diff options
162 files changed, 3099 insertions, 2045 deletions
| @@ -92,6 +92,7 @@ Rudolf Marek <R.Marek@sh.cvut.cz> | |||
| 92 | Rui Saraiva <rmps@joel.ist.utl.pt> | 92 | Rui Saraiva <rmps@joel.ist.utl.pt> |
| 93 | Sachin P Sant <ssant@in.ibm.com> | 93 | Sachin P Sant <ssant@in.ibm.com> |
| 94 | Sam Ravnborg <sam@mars.ravnborg.org> | 94 | Sam Ravnborg <sam@mars.ravnborg.org> |
| 95 | Sascha Hauer <s.hauer@pengutronix.de> | ||
| 95 | S.Çağlar Onur <caglar@pardus.org.tr> | 96 | S.Çağlar Onur <caglar@pardus.org.tr> |
| 96 | Simon Kelley <simon@thekelleys.org.uk> | 97 | Simon Kelley <simon@thekelleys.org.uk> |
| 97 | Stéphane Witzmann <stephane.witzmann@ubpmes.univ-bpclermont.fr> | 98 | Stéphane Witzmann <stephane.witzmann@ubpmes.univ-bpclermont.fr> |
| @@ -100,6 +101,7 @@ Tejun Heo <htejun@gmail.com> | |||
| 100 | Thomas Graf <tgraf@suug.ch> | 101 | Thomas Graf <tgraf@suug.ch> |
| 101 | Tony Luck <tony.luck@intel.com> | 102 | Tony Luck <tony.luck@intel.com> |
| 102 | Tsuneo Yoshioka <Tsuneo.Yoshioka@f-secure.com> | 103 | Tsuneo Yoshioka <Tsuneo.Yoshioka@f-secure.com> |
| 103 | Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com> | ||
| 104 | Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de> | 104 | Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de> |
| 105 | Uwe Kleine-König <ukl@pengutronix.de> | ||
| 106 | Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com> | ||
| 105 | Valdis Kletnieks <Valdis.Kletnieks@vt.edu> | 107 | Valdis Kletnieks <Valdis.Kletnieks@vt.edu> |
diff --git a/Documentation/cpu-freq/user-guide.txt b/Documentation/cpu-freq/user-guide.txt index e3443ddcfb89..917918f84fc7 100644 --- a/Documentation/cpu-freq/user-guide.txt +++ b/Documentation/cpu-freq/user-guide.txt | |||
| @@ -195,19 +195,3 @@ scaling_setspeed. By "echoing" a new frequency into this | |||
| 195 | you can change the speed of the CPU, | 195 | you can change the speed of the CPU, |
| 196 | but only within the limits of | 196 | but only within the limits of |
| 197 | scaling_min_freq and scaling_max_freq. | 197 | scaling_min_freq and scaling_max_freq. |
| 198 | |||
| 199 | |||
| 200 | 3.2 Deprecated Interfaces | ||
| 201 | ------------------------- | ||
| 202 | |||
| 203 | Depending on your kernel configuration, you might find the following | ||
| 204 | cpufreq-related files: | ||
| 205 | /proc/cpufreq | ||
| 206 | /proc/sys/cpu/*/speed | ||
| 207 | /proc/sys/cpu/*/speed-min | ||
| 208 | /proc/sys/cpu/*/speed-max | ||
| 209 | |||
| 210 | These are files for deprecated interfaces to cpufreq, which offer far | ||
| 211 | less functionality. Because of this, these interfaces aren't described | ||
| 212 | here. | ||
| 213 | |||
diff --git a/Documentation/filesystems/sysfs-pci.txt b/Documentation/filesystems/sysfs-pci.txt index 68ef48839c04..9f8740ca3f3b 100644 --- a/Documentation/filesystems/sysfs-pci.txt +++ b/Documentation/filesystems/sysfs-pci.txt | |||
| @@ -9,6 +9,7 @@ that support it. For example, a given bus might look like this: | |||
| 9 | | |-- class | 9 | | |-- class |
| 10 | | |-- config | 10 | | |-- config |
| 11 | | |-- device | 11 | | |-- device |
| 12 | | |-- enable | ||
| 12 | | |-- irq | 13 | | |-- irq |
| 13 | | |-- local_cpus | 14 | | |-- local_cpus |
| 14 | | |-- resource | 15 | | |-- resource |
| @@ -32,6 +33,7 @@ files, each with their own function. | |||
| 32 | class PCI class (ascii, ro) | 33 | class PCI class (ascii, ro) |
| 33 | config PCI config space (binary, rw) | 34 | config PCI config space (binary, rw) |
| 34 | device PCI device (ascii, ro) | 35 | device PCI device (ascii, ro) |
| 36 | enable Whether the device is enabled (ascii, rw) | ||
| 35 | irq IRQ number (ascii, ro) | 37 | irq IRQ number (ascii, ro) |
| 36 | local_cpus nearby CPU mask (cpumask, ro) | 38 | local_cpus nearby CPU mask (cpumask, ro) |
| 37 | resource PCI resource host addresses (ascii, ro) | 39 | resource PCI resource host addresses (ascii, ro) |
| @@ -57,10 +59,19 @@ used to do actual device programming from userspace. Note that some platforms | |||
| 57 | don't support mmapping of certain resources, so be sure to check the return | 59 | don't support mmapping of certain resources, so be sure to check the return |
| 58 | value from any attempted mmap. | 60 | value from any attempted mmap. |
| 59 | 61 | ||
| 62 | The 'enable' file provides a counter that indicates how many times the device | ||
| 63 | has been enabled. If the 'enable' file currently returns '4', and a '1' is | ||
| 64 | echoed into it, it will then return '5'. Echoing a '0' into it will decrease | ||
| 65 | the count. Even when it returns to 0, though, some of the initialisation | ||
| 66 | may not be reversed. | ||
| 67 | |||
| 60 | The 'rom' file is special in that it provides read-only access to the device's | 68 | The 'rom' file is special in that it provides read-only access to the device's |
| 61 | ROM file, if available. It's disabled by default, however, so applications | 69 | ROM file, if available. It's disabled by default, however, so applications |
| 62 | should write the string "1" to the file to enable it before attempting a read | 70 | should write the string "1" to the file to enable it before attempting a read |
| 63 | call, and disable it following the access by writing "0" to the file. | 71 | call, and disable it following the access by writing "0" to the file. Note |
| 72 | that the device must be enabled for a rom read to return data succesfully. | ||
| 73 | In the event a driver is not bound to the device, it can be enabled using the | ||
| 74 | 'enable' file, documented above. | ||
| 64 | 75 | ||
| 65 | Accessing legacy resources through sysfs | 76 | Accessing legacy resources through sysfs |
| 66 | ---------------------------------------- | 77 | ---------------------------------------- |
diff --git a/MAINTAINERS b/MAINTAINERS index 829a697f1235..4486ac1ccac5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -1021,6 +1021,14 @@ M: mb@bu3sch.de | |||
| 1021 | W: http://bu3sch.de/btgpio.php | 1021 | W: http://bu3sch.de/btgpio.php |
| 1022 | S: Maintained | 1022 | S: Maintained |
| 1023 | 1023 | ||
| 1024 | BTRFS FILE SYSTEM | ||
| 1025 | P: Chris Mason | ||
| 1026 | M: chris.mason@oracle.com | ||
| 1027 | L: linux-btrfs@vger.kernel.org | ||
| 1028 | W: http://btrfs.wiki.kernel.org/ | ||
| 1029 | T: git kernel.org:/pub/scm/linux/kernel/git/mason/btrfs-unstable.git | ||
| 1030 | S: Maintained | ||
| 1031 | |||
| 1024 | BTTV VIDEO4LINUX DRIVER | 1032 | BTTV VIDEO4LINUX DRIVER |
| 1025 | P: Mauro Carvalho Chehab | 1033 | P: Mauro Carvalho Chehab |
| 1026 | M: mchehab@infradead.org | 1034 | M: mchehab@infradead.org |
| @@ -2212,7 +2220,7 @@ P: Sean Hefty | |||
| 2212 | M: sean.hefty@intel.com | 2220 | M: sean.hefty@intel.com |
| 2213 | P: Hal Rosenstock | 2221 | P: Hal Rosenstock |
| 2214 | M: hal.rosenstock@gmail.com | 2222 | M: hal.rosenstock@gmail.com |
| 2215 | L: general@lists.openfabrics.org | 2223 | L: general@lists.openfabrics.org (moderated for non-subscribers) |
| 2216 | W: http://www.openib.org/ | 2224 | W: http://www.openib.org/ |
| 2217 | T: git kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git | 2225 | T: git kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git |
| 2218 | S: Supported | 2226 | S: Supported |
| @@ -4847,6 +4855,7 @@ P: Ingo Molnar | |||
| 4847 | M: mingo@redhat.com | 4855 | M: mingo@redhat.com |
| 4848 | P: H. Peter Anvin | 4856 | P: H. Peter Anvin |
| 4849 | M: hpa@zytor.com | 4857 | M: hpa@zytor.com |
| 4858 | M: x86@kernel.org | ||
| 4850 | L: linux-kernel@vger.kernel.org | 4859 | L: linux-kernel@vger.kernel.org |
| 4851 | T: git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git | 4860 | T: git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git |
| 4852 | S: Maintained | 4861 | S: Maintained |
| @@ -1,7 +1,7 @@ | |||
| 1 | VERSION = 2 | 1 | VERSION = 2 |
| 2 | PATCHLEVEL = 6 | 2 | PATCHLEVEL = 6 |
| 3 | SUBLEVEL = 29 | 3 | SUBLEVEL = 29 |
| 4 | EXTRAVERSION = -rc3 | 4 | EXTRAVERSION = -rc4 |
| 5 | NAME = Erotic Pickled Herring | 5 | NAME = Erotic Pickled Herring |
| 6 | 6 | ||
| 7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/alpha/include/asm/bug.h b/arch/alpha/include/asm/bug.h index 7b85b7c93709..1720c8ad86fe 100644 --- a/arch/alpha/include/asm/bug.h +++ b/arch/alpha/include/asm/bug.h | |||
| @@ -8,12 +8,12 @@ | |||
| 8 | 8 | ||
| 9 | /* ??? Would be nice to use .gprel32 here, but we can't be sure that the | 9 | /* ??? Would be nice to use .gprel32 here, but we can't be sure that the |
| 10 | function loaded the GP, so this could fail in modules. */ | 10 | function loaded the GP, so this could fail in modules. */ |
| 11 | #define BUG() { \ | 11 | #define BUG() do { \ |
| 12 | __asm__ __volatile__( \ | 12 | __asm__ __volatile__( \ |
| 13 | "call_pal %0 # bugchk\n\t" \ | 13 | "call_pal %0 # bugchk\n\t" \ |
| 14 | ".long %1\n\t.8byte %2" \ | 14 | ".long %1\n\t.8byte %2" \ |
| 15 | : : "i"(PAL_bugchk), "i"(__LINE__), "i"(__FILE__)); \ | 15 | : : "i"(PAL_bugchk), "i"(__LINE__), "i"(__FILE__)); \ |
| 16 | for ( ; ; ); } | 16 | for ( ; ; ); } while (0) |
| 17 | 17 | ||
| 18 | #define HAVE_ARCH_BUG | 18 | #define HAVE_ARCH_BUG |
| 19 | #endif | 19 | #endif |
diff --git a/arch/ia64/sn/kernel/io_acpi_init.c b/arch/ia64/sn/kernel/io_acpi_init.c index c5a214026a77..d0223abbbbd4 100644 --- a/arch/ia64/sn/kernel/io_acpi_init.c +++ b/arch/ia64/sn/kernel/io_acpi_init.c | |||
| @@ -443,7 +443,7 @@ sn_acpi_slot_fixup(struct pci_dev *dev) | |||
| 443 | size = pci_resource_len(dev, PCI_ROM_RESOURCE); | 443 | size = pci_resource_len(dev, PCI_ROM_RESOURCE); |
| 444 | addr = ioremap(pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE], | 444 | addr = ioremap(pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE], |
| 445 | size); | 445 | size); |
| 446 | image_size = pci_get_rom_size(addr, size); | 446 | image_size = pci_get_rom_size(dev, addr, size); |
| 447 | dev->resource[PCI_ROM_RESOURCE].start = (unsigned long) addr; | 447 | dev->resource[PCI_ROM_RESOURCE].start = (unsigned long) addr; |
| 448 | dev->resource[PCI_ROM_RESOURCE].end = | 448 | dev->resource[PCI_ROM_RESOURCE].end = |
| 449 | (unsigned long) addr + image_size - 1; | 449 | (unsigned long) addr + image_size - 1; |
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 4e1801bad83a..e2eb2da60f96 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c | |||
| @@ -269,7 +269,7 @@ sn_io_slot_fixup(struct pci_dev *dev) | |||
| 269 | 269 | ||
| 270 | rom = ioremap(pci_resource_start(dev, PCI_ROM_RESOURCE), | 270 | rom = ioremap(pci_resource_start(dev, PCI_ROM_RESOURCE), |
| 271 | size + 1); | 271 | size + 1); |
| 272 | image_size = pci_get_rom_size(rom, size + 1); | 272 | image_size = pci_get_rom_size(dev, rom, size + 1); |
| 273 | dev->resource[PCI_ROM_RESOURCE].end = | 273 | dev->resource[PCI_ROM_RESOURCE].end = |
| 274 | dev->resource[PCI_ROM_RESOURCE].start + | 274 | dev->resource[PCI_ROM_RESOURCE].start + |
| 275 | image_size - 1; | 275 | image_size - 1; |
diff --git a/arch/sh/boards/board-ap325rxa.c b/arch/sh/boards/board-ap325rxa.c index caf4c33f4e84..7c35787d29b4 100644 --- a/arch/sh/boards/board-ap325rxa.c +++ b/arch/sh/boards/board-ap325rxa.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/gpio.h> | 22 | #include <linux/gpio.h> |
| 23 | #include <linux/spi/spi.h> | 23 | #include <linux/spi/spi.h> |
| 24 | #include <linux/spi/spi_gpio.h> | 24 | #include <linux/spi/spi_gpio.h> |
| 25 | #include <media/ov772x.h> | ||
| 25 | #include <media/soc_camera_platform.h> | 26 | #include <media/soc_camera_platform.h> |
| 26 | #include <media/sh_mobile_ceu.h> | 27 | #include <media/sh_mobile_ceu.h> |
| 27 | #include <video/sh_mobile_lcdc.h> | 28 | #include <video/sh_mobile_lcdc.h> |
| @@ -216,7 +217,14 @@ static struct platform_device lcdc_device = { | |||
| 216 | }, | 217 | }, |
| 217 | }; | 218 | }; |
| 218 | 219 | ||
| 220 | static void camera_power(int val) | ||
| 221 | { | ||
| 222 | gpio_set_value(GPIO_PTZ5, val); /* RST_CAM/RSTB */ | ||
| 223 | mdelay(10); | ||
| 224 | } | ||
| 225 | |||
| 219 | #ifdef CONFIG_I2C | 226 | #ifdef CONFIG_I2C |
| 227 | /* support for the old ncm03j camera */ | ||
| 220 | static unsigned char camera_ncm03j_magic[] = | 228 | static unsigned char camera_ncm03j_magic[] = |
| 221 | { | 229 | { |
| 222 | 0x87, 0x00, 0x88, 0x08, 0x89, 0x01, 0x8A, 0xE8, | 230 | 0x87, 0x00, 0x88, 0x08, 0x89, 0x01, 0x8A, 0xE8, |
| @@ -237,6 +245,23 @@ static unsigned char camera_ncm03j_magic[] = | |||
| 237 | 0x63, 0xD4, 0x64, 0xEA, 0xD6, 0x0F, | 245 | 0x63, 0xD4, 0x64, 0xEA, 0xD6, 0x0F, |
| 238 | }; | 246 | }; |
| 239 | 247 | ||
| 248 | static int camera_probe(void) | ||
| 249 | { | ||
| 250 | struct i2c_adapter *a = i2c_get_adapter(0); | ||
| 251 | struct i2c_msg msg; | ||
| 252 | int ret; | ||
| 253 | |||
| 254 | camera_power(1); | ||
| 255 | msg.addr = 0x6e; | ||
| 256 | msg.buf = camera_ncm03j_magic; | ||
| 257 | msg.len = 2; | ||
| 258 | msg.flags = 0; | ||
| 259 | ret = i2c_transfer(a, &msg, 1); | ||
| 260 | camera_power(0); | ||
| 261 | |||
| 262 | return ret; | ||
| 263 | } | ||
| 264 | |||
| 240 | static int camera_set_capture(struct soc_camera_platform_info *info, | 265 | static int camera_set_capture(struct soc_camera_platform_info *info, |
| 241 | int enable) | 266 | int enable) |
| 242 | { | 267 | { |
| @@ -245,9 +270,11 @@ static int camera_set_capture(struct soc_camera_platform_info *info, | |||
| 245 | int ret = 0; | 270 | int ret = 0; |
| 246 | int i; | 271 | int i; |
| 247 | 272 | ||
| 273 | camera_power(0); | ||
| 248 | if (!enable) | 274 | if (!enable) |
| 249 | return 0; /* no disable for now */ | 275 | return 0; /* no disable for now */ |
| 250 | 276 | ||
| 277 | camera_power(1); | ||
| 251 | for (i = 0; i < ARRAY_SIZE(camera_ncm03j_magic); i += 2) { | 278 | for (i = 0; i < ARRAY_SIZE(camera_ncm03j_magic); i += 2) { |
| 252 | u_int8_t buf[8]; | 279 | u_int8_t buf[8]; |
| 253 | 280 | ||
| @@ -286,8 +313,35 @@ static struct platform_device camera_device = { | |||
| 286 | .platform_data = &camera_info, | 313 | .platform_data = &camera_info, |
| 287 | }, | 314 | }, |
| 288 | }; | 315 | }; |
| 316 | |||
| 317 | static int __init camera_setup(void) | ||
| 318 | { | ||
| 319 | if (camera_probe() > 0) | ||
| 320 | platform_device_register(&camera_device); | ||
| 321 | |||
| 322 | return 0; | ||
| 323 | } | ||
| 324 | late_initcall(camera_setup); | ||
| 325 | |||
| 289 | #endif /* CONFIG_I2C */ | 326 | #endif /* CONFIG_I2C */ |
| 290 | 327 | ||
| 328 | static int ov7725_power(struct device *dev, int mode) | ||
| 329 | { | ||
| 330 | camera_power(0); | ||
| 331 | if (mode) | ||
| 332 | camera_power(1); | ||
| 333 | |||
| 334 | return 0; | ||
| 335 | } | ||
| 336 | |||
| 337 | static struct ov772x_camera_info ov7725_info = { | ||
| 338 | .buswidth = SOCAM_DATAWIDTH_8, | ||
| 339 | .flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP, | ||
| 340 | .link = { | ||
| 341 | .power = ov7725_power, | ||
| 342 | }, | ||
| 343 | }; | ||
| 344 | |||
| 291 | static struct sh_mobile_ceu_info sh_mobile_ceu_info = { | 345 | static struct sh_mobile_ceu_info sh_mobile_ceu_info = { |
| 292 | .flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH | | 346 | .flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH | |
| 293 | SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8, | 347 | SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8, |
| @@ -338,9 +392,6 @@ static struct platform_device *ap325rxa_devices[] __initdata = { | |||
| 338 | &ap325rxa_nor_flash_device, | 392 | &ap325rxa_nor_flash_device, |
| 339 | &lcdc_device, | 393 | &lcdc_device, |
| 340 | &ceu_device, | 394 | &ceu_device, |
| 341 | #ifdef CONFIG_I2C | ||
| 342 | &camera_device, | ||
| 343 | #endif | ||
| 344 | &nand_flash_device, | 395 | &nand_flash_device, |
| 345 | &sdcard_cn3_device, | 396 | &sdcard_cn3_device, |
| 346 | }; | 397 | }; |
| @@ -349,6 +400,10 @@ static struct i2c_board_info __initdata ap325rxa_i2c_devices[] = { | |||
| 349 | { | 400 | { |
| 350 | I2C_BOARD_INFO("pcf8563", 0x51), | 401 | I2C_BOARD_INFO("pcf8563", 0x51), |
| 351 | }, | 402 | }, |
| 403 | { | ||
| 404 | I2C_BOARD_INFO("ov772x", 0x21), | ||
| 405 | .platform_data = &ov7725_info, | ||
| 406 | }, | ||
| 352 | }; | 407 | }; |
| 353 | 408 | ||
| 354 | static struct spi_board_info ap325rxa_spi_devices[] = { | 409 | static struct spi_board_info ap325rxa_spi_devices[] = { |
| @@ -426,7 +481,7 @@ static int __init ap325rxa_devices_setup(void) | |||
| 426 | gpio_request(GPIO_PTZ6, NULL); | 481 | gpio_request(GPIO_PTZ6, NULL); |
| 427 | gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */ | 482 | gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */ |
| 428 | gpio_request(GPIO_PTZ5, NULL); | 483 | gpio_request(GPIO_PTZ5, NULL); |
| 429 | gpio_direction_output(GPIO_PTZ5, 1); /* RST_CAM */ | 484 | gpio_direction_output(GPIO_PTZ5, 0); /* RST_CAM */ |
| 430 | gpio_request(GPIO_PTZ4, NULL); | 485 | gpio_request(GPIO_PTZ4, NULL); |
| 431 | gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */ | 486 | gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */ |
| 432 | 487 | ||
diff --git a/arch/sh/configs/ap325rxa_defconfig b/arch/sh/configs/ap325rxa_defconfig index 5c423fa8e6b8..352f87d50fdc 100644 --- a/arch/sh/configs/ap325rxa_defconfig +++ b/arch/sh/configs/ap325rxa_defconfig | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | # | 1 | # |
| 2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
| 3 | # Linux kernel version: 2.6.28 | 3 | # Linux kernel version: 2.6.29-rc2 |
| 4 | # Fri Jan 9 16:54:19 2009 | 4 | # Tue Jan 27 11:45:08 2009 |
| 5 | # | 5 | # |
| 6 | CONFIG_SUPERH=y | 6 | CONFIG_SUPERH=y |
| 7 | CONFIG_SUPERH32=y | 7 | CONFIG_SUPERH32=y |
| @@ -45,12 +45,12 @@ CONFIG_BSD_PROCESS_ACCT=y | |||
| 45 | # CONFIG_AUDIT is not set | 45 | # CONFIG_AUDIT is not set |
| 46 | # CONFIG_IKCONFIG is not set | 46 | # CONFIG_IKCONFIG is not set |
| 47 | CONFIG_LOG_BUF_SHIFT=14 | 47 | CONFIG_LOG_BUF_SHIFT=14 |
| 48 | # CONFIG_CGROUPS is not set | ||
| 49 | CONFIG_GROUP_SCHED=y | 48 | CONFIG_GROUP_SCHED=y |
| 50 | CONFIG_FAIR_GROUP_SCHED=y | 49 | CONFIG_FAIR_GROUP_SCHED=y |
| 51 | # CONFIG_RT_GROUP_SCHED is not set | 50 | # CONFIG_RT_GROUP_SCHED is not set |
| 52 | CONFIG_USER_SCHED=y | 51 | CONFIG_USER_SCHED=y |
| 53 | # CONFIG_CGROUP_SCHED is not set | 52 | # CONFIG_CGROUP_SCHED is not set |
| 53 | # CONFIG_CGROUPS is not set | ||
| 54 | CONFIG_SYSFS_DEPRECATED=y | 54 | CONFIG_SYSFS_DEPRECATED=y |
| 55 | CONFIG_SYSFS_DEPRECATED_V2=y | 55 | CONFIG_SYSFS_DEPRECATED_V2=y |
| 56 | # CONFIG_RELAY is not set | 56 | # CONFIG_RELAY is not set |
| @@ -378,6 +378,7 @@ CONFIG_WIRELESS=y | |||
| 378 | # CONFIG_WIRELESS_EXT is not set | 378 | # CONFIG_WIRELESS_EXT is not set |
| 379 | # CONFIG_LIB80211 is not set | 379 | # CONFIG_LIB80211 is not set |
| 380 | # CONFIG_MAC80211 is not set | 380 | # CONFIG_MAC80211 is not set |
| 381 | # CONFIG_WIMAX is not set | ||
| 381 | # CONFIG_RFKILL is not set | 382 | # CONFIG_RFKILL is not set |
| 382 | # CONFIG_NET_9P is not set | 383 | # CONFIG_NET_9P is not set |
| 383 | 384 | ||
| @@ -400,6 +401,7 @@ CONFIG_MTD=y | |||
| 400 | # CONFIG_MTD_DEBUG is not set | 401 | # CONFIG_MTD_DEBUG is not set |
| 401 | CONFIG_MTD_CONCAT=y | 402 | CONFIG_MTD_CONCAT=y |
| 402 | CONFIG_MTD_PARTITIONS=y | 403 | CONFIG_MTD_PARTITIONS=y |
| 404 | # CONFIG_MTD_TESTS is not set | ||
| 403 | # CONFIG_MTD_REDBOOT_PARTS is not set | 405 | # CONFIG_MTD_REDBOOT_PARTS is not set |
| 404 | CONFIG_MTD_CMDLINE_PARTS=y | 406 | CONFIG_MTD_CMDLINE_PARTS=y |
| 405 | # CONFIG_MTD_AR7_PARTS is not set | 407 | # CONFIG_MTD_AR7_PARTS is not set |
| @@ -447,9 +449,7 @@ CONFIG_MTD_CFI_UTIL=y | |||
| 447 | # | 449 | # |
| 448 | # CONFIG_MTD_COMPLEX_MAPPINGS is not set | 450 | # CONFIG_MTD_COMPLEX_MAPPINGS is not set |
| 449 | CONFIG_MTD_PHYSMAP=y | 451 | CONFIG_MTD_PHYSMAP=y |
| 450 | CONFIG_MTD_PHYSMAP_START=0xffffffff | 452 | # CONFIG_MTD_PHYSMAP_COMPAT is not set |
| 451 | CONFIG_MTD_PHYSMAP_LEN=0 | ||
| 452 | CONFIG_MTD_PHYSMAP_BANKWIDTH=0 | ||
| 453 | # CONFIG_MTD_PLATRAM is not set | 453 | # CONFIG_MTD_PLATRAM is not set |
| 454 | 454 | ||
| 455 | # | 455 | # |
| @@ -480,6 +480,12 @@ CONFIG_MTD_NAND_SH_FLCTL=y | |||
| 480 | # CONFIG_MTD_ONENAND is not set | 480 | # CONFIG_MTD_ONENAND is not set |
| 481 | 481 | ||
| 482 | # | 482 | # |
| 483 | # LPDDR flash memory drivers | ||
| 484 | # | ||
| 485 | # CONFIG_MTD_LPDDR is not set | ||
| 486 | # CONFIG_MTD_QINFO_PROBE is not set | ||
| 487 | |||
| 488 | # | ||
| 483 | # UBI - Unsorted block images | 489 | # UBI - Unsorted block images |
| 484 | # | 490 | # |
| 485 | CONFIG_MTD_UBI=y | 491 | CONFIG_MTD_UBI=y |
| @@ -607,6 +613,10 @@ CONFIG_SMSC911X=y | |||
| 607 | # CONFIG_WLAN_PRE80211 is not set | 613 | # CONFIG_WLAN_PRE80211 is not set |
| 608 | # CONFIG_WLAN_80211 is not set | 614 | # CONFIG_WLAN_80211 is not set |
| 609 | # CONFIG_IWLWIFI_LEDS is not set | 615 | # CONFIG_IWLWIFI_LEDS is not set |
| 616 | |||
| 617 | # | ||
| 618 | # Enable WiMAX (Networking options) to see the WiMAX drivers | ||
| 619 | # | ||
| 610 | # CONFIG_WAN is not set | 620 | # CONFIG_WAN is not set |
| 611 | # CONFIG_PPP is not set | 621 | # CONFIG_PPP is not set |
| 612 | # CONFIG_SLIP is not set | 622 | # CONFIG_SLIP is not set |
| @@ -790,6 +800,7 @@ CONFIG_SSB_POSSIBLE=y | |||
| 790 | # CONFIG_PMIC_DA903X is not set | 800 | # CONFIG_PMIC_DA903X is not set |
| 791 | # CONFIG_MFD_WM8400 is not set | 801 | # CONFIG_MFD_WM8400 is not set |
| 792 | # CONFIG_MFD_WM8350_I2C is not set | 802 | # CONFIG_MFD_WM8350_I2C is not set |
| 803 | # CONFIG_MFD_PCF50633 is not set | ||
| 793 | # CONFIG_REGULATOR is not set | 804 | # CONFIG_REGULATOR is not set |
| 794 | 805 | ||
| 795 | # | 806 | # |
| @@ -837,7 +848,7 @@ CONFIG_SOC_CAMERA=y | |||
| 837 | # CONFIG_SOC_CAMERA_MT9V022 is not set | 848 | # CONFIG_SOC_CAMERA_MT9V022 is not set |
| 838 | # CONFIG_SOC_CAMERA_TW9910 is not set | 849 | # CONFIG_SOC_CAMERA_TW9910 is not set |
| 839 | CONFIG_SOC_CAMERA_PLATFORM=y | 850 | CONFIG_SOC_CAMERA_PLATFORM=y |
| 840 | # CONFIG_SOC_CAMERA_OV772X is not set | 851 | CONFIG_SOC_CAMERA_OV772X=y |
| 841 | CONFIG_VIDEO_SH_MOBILE_CEU=y | 852 | CONFIG_VIDEO_SH_MOBILE_CEU=y |
| 842 | # CONFIG_RADIO_ADAPTERS is not set | 853 | # CONFIG_RADIO_ADAPTERS is not set |
| 843 | # CONFIG_DAB is not set | 854 | # CONFIG_DAB is not set |
| @@ -1012,6 +1023,7 @@ CONFIG_FS_POSIX_ACL=y | |||
| 1012 | CONFIG_FILE_LOCKING=y | 1023 | CONFIG_FILE_LOCKING=y |
| 1013 | # CONFIG_XFS_FS is not set | 1024 | # CONFIG_XFS_FS is not set |
| 1014 | # CONFIG_OCFS2_FS is not set | 1025 | # CONFIG_OCFS2_FS is not set |
| 1026 | # CONFIG_BTRFS_FS is not set | ||
| 1015 | CONFIG_DNOTIFY=y | 1027 | CONFIG_DNOTIFY=y |
| 1016 | CONFIG_INOTIFY=y | 1028 | CONFIG_INOTIFY=y |
| 1017 | CONFIG_INOTIFY_USER=y | 1029 | CONFIG_INOTIFY_USER=y |
| @@ -1060,6 +1072,7 @@ CONFIG_MISC_FILESYSTEMS=y | |||
| 1060 | # CONFIG_JFFS2_FS is not set | 1072 | # CONFIG_JFFS2_FS is not set |
| 1061 | # CONFIG_UBIFS_FS is not set | 1073 | # CONFIG_UBIFS_FS is not set |
| 1062 | # CONFIG_CRAMFS is not set | 1074 | # CONFIG_CRAMFS is not set |
| 1075 | # CONFIG_SQUASHFS is not set | ||
| 1063 | # CONFIG_VXFS_FS is not set | 1076 | # CONFIG_VXFS_FS is not set |
| 1064 | # CONFIG_MINIX_FS is not set | 1077 | # CONFIG_MINIX_FS is not set |
| 1065 | # CONFIG_OMFS_FS is not set | 1078 | # CONFIG_OMFS_FS is not set |
diff --git a/arch/sh/configs/migor_defconfig b/arch/sh/configs/migor_defconfig index 7758263514bc..678576796bdf 100644 --- a/arch/sh/configs/migor_defconfig +++ b/arch/sh/configs/migor_defconfig | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | # | 1 | # |
| 2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
| 3 | # Linux kernel version: 2.6.28 | 3 | # Linux kernel version: 2.6.29-rc1 |
| 4 | # Fri Jan 9 17:09:35 2009 | 4 | # Thu Jan 22 09:16:16 2009 |
| 5 | # | 5 | # |
| 6 | CONFIG_SUPERH=y | 6 | CONFIG_SUPERH=y |
| 7 | CONFIG_SUPERH32=y | 7 | CONFIG_SUPERH32=y |
| @@ -45,8 +45,12 @@ CONFIG_SYSVIPC_SYSCTL=y | |||
| 45 | CONFIG_IKCONFIG=y | 45 | CONFIG_IKCONFIG=y |
| 46 | CONFIG_IKCONFIG_PROC=y | 46 | CONFIG_IKCONFIG_PROC=y |
| 47 | CONFIG_LOG_BUF_SHIFT=14 | 47 | CONFIG_LOG_BUF_SHIFT=14 |
| 48 | # CONFIG_CGROUPS is not set | ||
| 49 | # CONFIG_GROUP_SCHED is not set | 48 | # CONFIG_GROUP_SCHED is not set |
| 49 | |||
| 50 | # | ||
| 51 | # Control Group support | ||
| 52 | # | ||
| 53 | # CONFIG_CGROUPS is not set | ||
| 50 | CONFIG_SYSFS_DEPRECATED=y | 54 | CONFIG_SYSFS_DEPRECATED=y |
| 51 | CONFIG_SYSFS_DEPRECATED_V2=y | 55 | CONFIG_SYSFS_DEPRECATED_V2=y |
| 52 | # CONFIG_RELAY is not set | 56 | # CONFIG_RELAY is not set |
| @@ -389,6 +393,7 @@ CONFIG_WIRELESS_EXT=y | |||
| 389 | CONFIG_WIRELESS_EXT_SYSFS=y | 393 | CONFIG_WIRELESS_EXT_SYSFS=y |
| 390 | # CONFIG_LIB80211 is not set | 394 | # CONFIG_LIB80211 is not set |
| 391 | # CONFIG_MAC80211 is not set | 395 | # CONFIG_MAC80211 is not set |
| 396 | # CONFIG_WIMAX is not set | ||
| 392 | # CONFIG_RFKILL is not set | 397 | # CONFIG_RFKILL is not set |
| 393 | # CONFIG_NET_9P is not set | 398 | # CONFIG_NET_9P is not set |
| 394 | 399 | ||
| @@ -411,6 +416,7 @@ CONFIG_MTD=y | |||
| 411 | # CONFIG_MTD_DEBUG is not set | 416 | # CONFIG_MTD_DEBUG is not set |
| 412 | CONFIG_MTD_CONCAT=y | 417 | CONFIG_MTD_CONCAT=y |
| 413 | CONFIG_MTD_PARTITIONS=y | 418 | CONFIG_MTD_PARTITIONS=y |
| 419 | # CONFIG_MTD_TESTS is not set | ||
| 414 | # CONFIG_MTD_REDBOOT_PARTS is not set | 420 | # CONFIG_MTD_REDBOOT_PARTS is not set |
| 415 | CONFIG_MTD_CMDLINE_PARTS=y | 421 | CONFIG_MTD_CMDLINE_PARTS=y |
| 416 | # CONFIG_MTD_AR7_PARTS is not set | 422 | # CONFIG_MTD_AR7_PARTS is not set |
| @@ -458,9 +464,7 @@ CONFIG_MTD_CFI_UTIL=y | |||
| 458 | # | 464 | # |
| 459 | # CONFIG_MTD_COMPLEX_MAPPINGS is not set | 465 | # CONFIG_MTD_COMPLEX_MAPPINGS is not set |
| 460 | CONFIG_MTD_PHYSMAP=y | 466 | CONFIG_MTD_PHYSMAP=y |
| 461 | CONFIG_MTD_PHYSMAP_START=0xffffffff | 467 | # CONFIG_MTD_PHYSMAP_COMPAT is not set |
| 462 | CONFIG_MTD_PHYSMAP_LEN=0 | ||
| 463 | CONFIG_MTD_PHYSMAP_BANKWIDTH=0 | ||
| 464 | # CONFIG_MTD_PLATRAM is not set | 468 | # CONFIG_MTD_PLATRAM is not set |
| 465 | 469 | ||
| 466 | # | 470 | # |
| @@ -488,6 +492,12 @@ CONFIG_MTD_NAND_PLATFORM=y | |||
| 488 | # CONFIG_MTD_ONENAND is not set | 492 | # CONFIG_MTD_ONENAND is not set |
| 489 | 493 | ||
| 490 | # | 494 | # |
| 495 | # LPDDR flash memory drivers | ||
| 496 | # | ||
| 497 | # CONFIG_MTD_LPDDR is not set | ||
| 498 | # CONFIG_MTD_QINFO_PROBE is not set | ||
| 499 | |||
| 500 | # | ||
| 491 | # UBI - Unsorted block images | 501 | # UBI - Unsorted block images |
| 492 | # | 502 | # |
| 493 | # CONFIG_MTD_UBI is not set | 503 | # CONFIG_MTD_UBI is not set |
| @@ -587,6 +597,10 @@ CONFIG_SMC91X=y | |||
| 587 | # CONFIG_WLAN_PRE80211 is not set | 597 | # CONFIG_WLAN_PRE80211 is not set |
| 588 | # CONFIG_WLAN_80211 is not set | 598 | # CONFIG_WLAN_80211 is not set |
| 589 | # CONFIG_IWLWIFI_LEDS is not set | 599 | # CONFIG_IWLWIFI_LEDS is not set |
| 600 | |||
| 601 | # | ||
| 602 | # Enable WiMAX (Networking options) to see the WiMAX drivers | ||
| 603 | # | ||
| 590 | # CONFIG_WAN is not set | 604 | # CONFIG_WAN is not set |
| 591 | # CONFIG_PPP is not set | 605 | # CONFIG_PPP is not set |
| 592 | # CONFIG_SLIP is not set | 606 | # CONFIG_SLIP is not set |
| @@ -761,6 +775,7 @@ CONFIG_SSB_POSSIBLE=y | |||
| 761 | # CONFIG_PMIC_DA903X is not set | 775 | # CONFIG_PMIC_DA903X is not set |
| 762 | # CONFIG_MFD_WM8400 is not set | 776 | # CONFIG_MFD_WM8400 is not set |
| 763 | # CONFIG_MFD_WM8350_I2C is not set | 777 | # CONFIG_MFD_WM8350_I2C is not set |
| 778 | # CONFIG_MFD_PCF50633 is not set | ||
| 764 | # CONFIG_REGULATOR is not set | 779 | # CONFIG_REGULATOR is not set |
| 765 | 780 | ||
| 766 | # | 781 | # |
| @@ -806,9 +821,9 @@ CONFIG_SOC_CAMERA=y | |||
| 806 | # CONFIG_SOC_CAMERA_MT9M111 is not set | 821 | # CONFIG_SOC_CAMERA_MT9M111 is not set |
| 807 | # CONFIG_SOC_CAMERA_MT9T031 is not set | 822 | # CONFIG_SOC_CAMERA_MT9T031 is not set |
| 808 | # CONFIG_SOC_CAMERA_MT9V022 is not set | 823 | # CONFIG_SOC_CAMERA_MT9V022 is not set |
| 809 | # CONFIG_SOC_CAMERA_TW9910 is not set | 824 | CONFIG_SOC_CAMERA_TW9910=y |
| 810 | CONFIG_SOC_CAMERA_PLATFORM=y | 825 | # CONFIG_SOC_CAMERA_PLATFORM is not set |
| 811 | # CONFIG_SOC_CAMERA_OV772X is not set | 826 | CONFIG_SOC_CAMERA_OV772X=y |
| 812 | CONFIG_VIDEO_SH_MOBILE_CEU=y | 827 | CONFIG_VIDEO_SH_MOBILE_CEU=y |
| 813 | # CONFIG_RADIO_ADAPTERS is not set | 828 | # CONFIG_RADIO_ADAPTERS is not set |
| 814 | # CONFIG_DAB is not set | 829 | # CONFIG_DAB is not set |
| @@ -866,11 +881,13 @@ CONFIG_USB_GADGET_SELECTED=y | |||
| 866 | # CONFIG_USB_GADGET_PXA25X is not set | 881 | # CONFIG_USB_GADGET_PXA25X is not set |
| 867 | # CONFIG_USB_GADGET_PXA27X is not set | 882 | # CONFIG_USB_GADGET_PXA27X is not set |
| 868 | # CONFIG_USB_GADGET_S3C2410 is not set | 883 | # CONFIG_USB_GADGET_S3C2410 is not set |
| 884 | # CONFIG_USB_GADGET_IMX is not set | ||
| 869 | CONFIG_USB_GADGET_M66592=y | 885 | CONFIG_USB_GADGET_M66592=y |
| 870 | CONFIG_USB_M66592=y | 886 | CONFIG_USB_M66592=y |
| 871 | CONFIG_SUPERH_BUILT_IN_M66592=y | 887 | CONFIG_SUPERH_BUILT_IN_M66592=y |
| 872 | # CONFIG_USB_GADGET_AMD5536UDC is not set | 888 | # CONFIG_USB_GADGET_AMD5536UDC is not set |
| 873 | # CONFIG_USB_GADGET_FSL_QE is not set | 889 | # CONFIG_USB_GADGET_FSL_QE is not set |
| 890 | # CONFIG_USB_GADGET_CI13XXX is not set | ||
| 874 | # CONFIG_USB_GADGET_NET2280 is not set | 891 | # CONFIG_USB_GADGET_NET2280 is not set |
| 875 | # CONFIG_USB_GADGET_GOKU is not set | 892 | # CONFIG_USB_GADGET_GOKU is not set |
| 876 | # CONFIG_USB_GADGET_DUMMY_HCD is not set | 893 | # CONFIG_USB_GADGET_DUMMY_HCD is not set |
| @@ -883,6 +900,11 @@ CONFIG_USB_G_SERIAL=y | |||
| 883 | # CONFIG_USB_MIDI_GADGET is not set | 900 | # CONFIG_USB_MIDI_GADGET is not set |
| 884 | # CONFIG_USB_G_PRINTER is not set | 901 | # CONFIG_USB_G_PRINTER is not set |
| 885 | # CONFIG_USB_CDC_COMPOSITE is not set | 902 | # CONFIG_USB_CDC_COMPOSITE is not set |
| 903 | |||
| 904 | # | ||
| 905 | # OTG and related infrastructure | ||
| 906 | # | ||
| 907 | # CONFIG_USB_GPIO_VBUS is not set | ||
| 886 | # CONFIG_MMC is not set | 908 | # CONFIG_MMC is not set |
| 887 | # CONFIG_MEMSTICK is not set | 909 | # CONFIG_MEMSTICK is not set |
| 888 | # CONFIG_NEW_LEDS is not set | 910 | # CONFIG_NEW_LEDS is not set |
| @@ -961,6 +983,7 @@ CONFIG_UIO_PDRV_GENIRQ=y | |||
| 961 | CONFIG_FILE_LOCKING=y | 983 | CONFIG_FILE_LOCKING=y |
| 962 | # CONFIG_XFS_FS is not set | 984 | # CONFIG_XFS_FS is not set |
| 963 | # CONFIG_OCFS2_FS is not set | 985 | # CONFIG_OCFS2_FS is not set |
| 986 | # CONFIG_BTRFS_FS is not set | ||
| 964 | # CONFIG_DNOTIFY is not set | 987 | # CONFIG_DNOTIFY is not set |
| 965 | # CONFIG_INOTIFY is not set | 988 | # CONFIG_INOTIFY is not set |
| 966 | # CONFIG_QUOTA is not set | 989 | # CONFIG_QUOTA is not set |
| @@ -1004,6 +1027,7 @@ CONFIG_MISC_FILESYSTEMS=y | |||
| 1004 | # CONFIG_EFS_FS is not set | 1027 | # CONFIG_EFS_FS is not set |
| 1005 | # CONFIG_JFFS2_FS is not set | 1028 | # CONFIG_JFFS2_FS is not set |
| 1006 | # CONFIG_CRAMFS is not set | 1029 | # CONFIG_CRAMFS is not set |
| 1030 | # CONFIG_SQUASHFS is not set | ||
| 1007 | # CONFIG_VXFS_FS is not set | 1031 | # CONFIG_VXFS_FS is not set |
| 1008 | # CONFIG_MINIX_FS is not set | 1032 | # CONFIG_MINIX_FS is not set |
| 1009 | # CONFIG_OMFS_FS is not set | 1033 | # CONFIG_OMFS_FS is not set |
diff --git a/arch/sh/include/asm/mutex-llsc.h b/arch/sh/include/asm/mutex-llsc.h index ee839ee58ac8..090358a7e1bb 100644 --- a/arch/sh/include/asm/mutex-llsc.h +++ b/arch/sh/include/asm/mutex-llsc.h | |||
| @@ -21,38 +21,36 @@ | |||
| 21 | static inline void | 21 | static inline void |
| 22 | __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *)) | 22 | __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *)) |
| 23 | { | 23 | { |
| 24 | int __ex_flag, __res; | 24 | int __done, __res; |
| 25 | 25 | ||
| 26 | __asm__ __volatile__ ( | 26 | __asm__ __volatile__ ( |
| 27 | "movli.l @%2, %0 \n" | 27 | "movli.l @%2, %0 \n" |
| 28 | "add #-1, %0 \n" | 28 | "add #-1, %0 \n" |
| 29 | "movco.l %0, @%2 \n" | 29 | "movco.l %0, @%2 \n" |
| 30 | "movt %1 \n" | 30 | "movt %1 \n" |
| 31 | : "=&z" (__res), "=&r" (__ex_flag) | 31 | : "=&z" (__res), "=&r" (__done) |
| 32 | : "r" (&(count)->counter) | 32 | : "r" (&(count)->counter) |
| 33 | : "t"); | 33 | : "t"); |
| 34 | 34 | ||
| 35 | __res |= !__ex_flag; | 35 | if (unlikely(!__done || __res != 0)) |
| 36 | if (unlikely(__res != 0)) | ||
| 37 | fail_fn(count); | 36 | fail_fn(count); |
| 38 | } | 37 | } |
| 39 | 38 | ||
| 40 | static inline int | 39 | static inline int |
| 41 | __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *)) | 40 | __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *)) |
| 42 | { | 41 | { |
| 43 | int __ex_flag, __res; | 42 | int __done, __res; |
| 44 | 43 | ||
| 45 | __asm__ __volatile__ ( | 44 | __asm__ __volatile__ ( |
| 46 | "movli.l @%2, %0 \n" | 45 | "movli.l @%2, %0 \n" |
| 47 | "add #-1, %0 \n" | 46 | "add #-1, %0 \n" |
| 48 | "movco.l %0, @%2 \n" | 47 | "movco.l %0, @%2 \n" |
| 49 | "movt %1 \n" | 48 | "movt %1 \n" |
| 50 | : "=&z" (__res), "=&r" (__ex_flag) | 49 | : "=&z" (__res), "=&r" (__done) |
| 51 | : "r" (&(count)->counter) | 50 | : "r" (&(count)->counter) |
| 52 | : "t"); | 51 | : "t"); |
| 53 | 52 | ||
| 54 | __res |= !__ex_flag; | 53 | if (unlikely(!__done || __res != 0)) |
| 55 | if (unlikely(__res != 0)) | ||
| 56 | __res = fail_fn(count); | 54 | __res = fail_fn(count); |
| 57 | 55 | ||
| 58 | return __res; | 56 | return __res; |
| @@ -61,19 +59,18 @@ __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *)) | |||
| 61 | static inline void | 59 | static inline void |
| 62 | __mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *)) | 60 | __mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *)) |
| 63 | { | 61 | { |
| 64 | int __ex_flag, __res; | 62 | int __done, __res; |
| 65 | 63 | ||
| 66 | __asm__ __volatile__ ( | 64 | __asm__ __volatile__ ( |
| 67 | "movli.l @%2, %0 \n\t" | 65 | "movli.l @%2, %0 \n\t" |
| 68 | "add #1, %0 \n\t" | 66 | "add #1, %0 \n\t" |
| 69 | "movco.l %0, @%2 \n\t" | 67 | "movco.l %0, @%2 \n\t" |
| 70 | "movt %1 \n\t" | 68 | "movt %1 \n\t" |
| 71 | : "=&z" (__res), "=&r" (__ex_flag) | 69 | : "=&z" (__res), "=&r" (__done) |
| 72 | : "r" (&(count)->counter) | 70 | : "r" (&(count)->counter) |
| 73 | : "t"); | 71 | : "t"); |
| 74 | 72 | ||
| 75 | __res |= !__ex_flag; | 73 | if (unlikely(!__done || __res <= 0)) |
| 76 | if (unlikely(__res <= 0)) | ||
| 77 | fail_fn(count); | 74 | fail_fn(count); |
| 78 | } | 75 | } |
| 79 | 76 | ||
diff --git a/arch/sh/include/asm/syscall_32.h b/arch/sh/include/asm/syscall_32.h index 05a868a71ef5..5bc34681d994 100644 --- a/arch/sh/include/asm/syscall_32.h +++ b/arch/sh/include/asm/syscall_32.h | |||
| @@ -21,23 +21,10 @@ static inline void syscall_rollback(struct task_struct *task, | |||
| 21 | */ | 21 | */ |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | static inline bool syscall_has_error(struct pt_regs *regs) | ||
| 25 | { | ||
| 26 | return (regs->sr & 0x1) ? true : false; | ||
| 27 | } | ||
| 28 | static inline void syscall_set_error(struct pt_regs *regs) | ||
| 29 | { | ||
| 30 | regs->sr |= 0x1; | ||
| 31 | } | ||
| 32 | static inline void syscall_clear_error(struct pt_regs *regs) | ||
| 33 | { | ||
| 34 | regs->sr &= ~0x1; | ||
| 35 | } | ||
| 36 | |||
| 37 | static inline long syscall_get_error(struct task_struct *task, | 24 | static inline long syscall_get_error(struct task_struct *task, |
| 38 | struct pt_regs *regs) | 25 | struct pt_regs *regs) |
| 39 | { | 26 | { |
| 40 | return syscall_has_error(regs) ? regs->regs[0] : 0; | 27 | return IS_ERR_VALUE(regs->regs[0]) ? regs->regs[0] : 0; |
| 41 | } | 28 | } |
| 42 | 29 | ||
| 43 | static inline long syscall_get_return_value(struct task_struct *task, | 30 | static inline long syscall_get_return_value(struct task_struct *task, |
| @@ -50,13 +37,10 @@ static inline void syscall_set_return_value(struct task_struct *task, | |||
| 50 | struct pt_regs *regs, | 37 | struct pt_regs *regs, |
| 51 | int error, long val) | 38 | int error, long val) |
| 52 | { | 39 | { |
| 53 | if (error) { | 40 | if (error) |
| 54 | syscall_set_error(regs); | ||
| 55 | regs->regs[0] = -error; | 41 | regs->regs[0] = -error; |
| 56 | } else { | 42 | else |
| 57 | syscall_clear_error(regs); | ||
| 58 | regs->regs[0] = val; | 43 | regs->regs[0] = val; |
| 59 | } | ||
| 60 | } | 44 | } |
| 61 | 45 | ||
| 62 | static inline void syscall_get_arguments(struct task_struct *task, | 46 | static inline void syscall_get_arguments(struct task_struct *task, |
diff --git a/arch/sh/include/asm/syscall_64.h b/arch/sh/include/asm/syscall_64.h index e1143b9784d6..c3561ca72bee 100644 --- a/arch/sh/include/asm/syscall_64.h +++ b/arch/sh/include/asm/syscall_64.h | |||
| @@ -21,23 +21,10 @@ static inline void syscall_rollback(struct task_struct *task, | |||
| 21 | */ | 21 | */ |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | static inline bool syscall_has_error(struct pt_regs *regs) | ||
| 25 | { | ||
| 26 | return (regs->sr & 0x1) ? true : false; | ||
| 27 | } | ||
| 28 | static inline void syscall_set_error(struct pt_regs *regs) | ||
| 29 | { | ||
| 30 | regs->sr |= 0x1; | ||
| 31 | } | ||
| 32 | static inline void syscall_clear_error(struct pt_regs *regs) | ||
| 33 | { | ||
| 34 | regs->sr &= ~0x1; | ||
| 35 | } | ||
| 36 | |||
| 37 | static inline long syscall_get_error(struct task_struct *task, | 24 | static inline long syscall_get_error(struct task_struct *task, |
| 38 | struct pt_regs *regs) | 25 | struct pt_regs *regs) |
| 39 | { | 26 | { |
| 40 | return syscall_has_error(regs) ? regs->regs[9] : 0; | 27 | return IS_ERR_VALUE(regs->regs[9]) ? regs->regs[9] : 0; |
| 41 | } | 28 | } |
| 42 | 29 | ||
| 43 | static inline long syscall_get_return_value(struct task_struct *task, | 30 | static inline long syscall_get_return_value(struct task_struct *task, |
| @@ -50,13 +37,10 @@ static inline void syscall_set_return_value(struct task_struct *task, | |||
| 50 | struct pt_regs *regs, | 37 | struct pt_regs *regs, |
| 51 | int error, long val) | 38 | int error, long val) |
| 52 | { | 39 | { |
| 53 | if (error) { | 40 | if (error) |
| 54 | syscall_set_error(regs); | ||
| 55 | regs->regs[9] = -error; | 41 | regs->regs[9] = -error; |
| 56 | } else { | 42 | else |
| 57 | syscall_clear_error(regs); | ||
| 58 | regs->regs[9] = val; | 43 | regs->regs[9] = val; |
| 59 | } | ||
| 60 | } | 44 | } |
| 61 | 45 | ||
| 62 | static inline void syscall_get_arguments(struct task_struct *task, | 46 | static inline void syscall_get_arguments(struct task_struct *task, |
diff --git a/arch/sh/kernel/cpu/sh4/fpu.c b/arch/sh/kernel/cpu/sh4/fpu.c index 2780917c0088..e3ea5411da6d 100644 --- a/arch/sh/kernel/cpu/sh4/fpu.c +++ b/arch/sh/kernel/cpu/sh4/fpu.c | |||
| @@ -423,7 +423,7 @@ static int ieee_fpe_handler(struct pt_regs *regs) | |||
| 423 | int m; | 423 | int m; |
| 424 | unsigned int hx; | 424 | unsigned int hx; |
| 425 | 425 | ||
| 426 | m = (finsn >> 9) & 0x7; | 426 | m = (finsn >> 8) & 0x7; |
| 427 | hx = tsk->thread.fpu.hard.fp_regs[m]; | 427 | hx = tsk->thread.fpu.hard.fp_regs[m]; |
| 428 | 428 | ||
| 429 | if ((tsk->thread.fpu.hard.fpscr & FPSCR_CAUSE_ERROR) | 429 | if ((tsk->thread.fpu.hard.fpscr & FPSCR_CAUSE_ERROR) |
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 534247508572..370d2cfa34eb 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c | |||
| @@ -262,11 +262,11 @@ void __init setup_bootmem_allocator(unsigned long free_pfn) | |||
| 262 | BOOTMEM_DEFAULT); | 262 | BOOTMEM_DEFAULT); |
| 263 | 263 | ||
| 264 | /* | 264 | /* |
| 265 | * reserve physical page 0 - it's a special BIOS page on many boxes, | 265 | * Reserve physical pages below CONFIG_ZERO_PAGE_OFFSET. |
| 266 | * enabling clean reboots, SMP operation, laptop functions. | ||
| 267 | */ | 266 | */ |
| 268 | reserve_bootmem(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET, | 267 | if (CONFIG_ZERO_PAGE_OFFSET != 0) |
| 269 | BOOTMEM_DEFAULT); | 268 | reserve_bootmem(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET, |
| 269 | BOOTMEM_DEFAULT); | ||
| 270 | 270 | ||
| 271 | sparse_memory_present_with_active_regions(0); | 271 | sparse_memory_present_with_active_regions(0); |
| 272 | 272 | ||
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c index 77c21bde376a..17784e19ae34 100644 --- a/arch/sh/kernel/signal_32.c +++ b/arch/sh/kernel/signal_32.c | |||
| @@ -510,7 +510,6 @@ handle_syscall_restart(unsigned long save_r0, struct pt_regs *regs, | |||
| 510 | case -ERESTARTNOHAND: | 510 | case -ERESTARTNOHAND: |
| 511 | no_system_call_restart: | 511 | no_system_call_restart: |
| 512 | regs->regs[0] = -EINTR; | 512 | regs->regs[0] = -EINTR; |
| 513 | regs->sr |= 1; | ||
| 514 | break; | 513 | break; |
| 515 | 514 | ||
| 516 | case -ERESTARTSYS: | 515 | case -ERESTARTSYS: |
| @@ -589,8 +588,7 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0) | |||
| 589 | 588 | ||
| 590 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 589 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
| 591 | if (signr > 0) { | 590 | if (signr > 0) { |
| 592 | if (regs->sr & 1) | 591 | handle_syscall_restart(save_r0, regs, &ka.sa); |
| 593 | handle_syscall_restart(save_r0, regs, &ka.sa); | ||
| 594 | 592 | ||
| 595 | /* Whee! Actually deliver the signal. */ | 593 | /* Whee! Actually deliver the signal. */ |
| 596 | if (handle_signal(signr, &ka, &info, oldset, | 594 | if (handle_signal(signr, &ka, &info, oldset, |
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c index b22fdfaaa191..0663a0ee6021 100644 --- a/arch/sh/kernel/signal_64.c +++ b/arch/sh/kernel/signal_64.c | |||
| @@ -60,7 +60,6 @@ handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa) | |||
| 60 | case -ERESTARTNOHAND: | 60 | case -ERESTARTNOHAND: |
| 61 | no_system_call_restart: | 61 | no_system_call_restart: |
| 62 | regs->regs[REG_RET] = -EINTR; | 62 | regs->regs[REG_RET] = -EINTR; |
| 63 | regs->sr |= 1; | ||
| 64 | break; | 63 | break; |
| 65 | 64 | ||
| 66 | case -ERESTARTSYS: | 65 | case -ERESTARTSYS: |
| @@ -109,8 +108,7 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
| 109 | 108 | ||
| 110 | signr = get_signal_to_deliver(&info, &ka, regs, 0); | 109 | signr = get_signal_to_deliver(&info, &ka, regs, 0); |
| 111 | if (signr > 0) { | 110 | if (signr > 0) { |
| 112 | if (regs->sr & 1) | 111 | handle_syscall_restart(regs, &ka.sa); |
| 113 | handle_syscall_restart(regs, &ka.sa); | ||
| 114 | 112 | ||
| 115 | /* Whee! Actually deliver the signal. */ | 113 | /* Whee! Actually deliver the signal. */ |
| 116 | if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { | 114 | if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { |
diff --git a/arch/sh/lib/checksum.S b/arch/sh/lib/checksum.S index cbdd0d40e545..356c8ec92893 100644 --- a/arch/sh/lib/checksum.S +++ b/arch/sh/lib/checksum.S | |||
| @@ -36,8 +36,7 @@ | |||
| 36 | */ | 36 | */ |
| 37 | 37 | ||
| 38 | /* | 38 | /* |
| 39 | * unsigned int csum_partial(const unsigned char *buf, int len, | 39 | * asmlinkage __wsum csum_partial(const void *buf, int len, __wsum sum); |
| 40 | * unsigned int sum); | ||
| 41 | */ | 40 | */ |
| 42 | 41 | ||
| 43 | .text | 42 | .text |
| @@ -49,11 +48,31 @@ ENTRY(csum_partial) | |||
| 49 | * Fortunately, it is easy to convert 2-byte alignment to 4-byte | 48 | * Fortunately, it is easy to convert 2-byte alignment to 4-byte |
| 50 | * alignment for the unrolled loop. | 49 | * alignment for the unrolled loop. |
| 51 | */ | 50 | */ |
| 52 | mov r5, r1 | ||
| 53 | mov r4, r0 | 51 | mov r4, r0 |
| 54 | tst #2, r0 ! Check alignment. | 52 | tst #3, r0 ! Check alignment. |
| 55 | bt 2f ! Jump if alignment is ok. | 53 | bt/s 2f ! Jump if alignment is ok. |
| 54 | mov r4, r7 ! Keep a copy to check for alignment | ||
| 56 | ! | 55 | ! |
| 56 | tst #1, r0 ! Check alignment. | ||
| 57 | bt 21f ! Jump if alignment is boundary of 2bytes. | ||
| 58 | |||
| 59 | ! buf is odd | ||
| 60 | tst r5, r5 | ||
| 61 | add #-1, r5 | ||
| 62 | bt 9f | ||
| 63 | mov.b @r4+, r0 | ||
| 64 | extu.b r0, r0 | ||
| 65 | addc r0, r6 ! t=0 from previous tst | ||
| 66 | mov r6, r0 | ||
| 67 | shll8 r6 | ||
| 68 | shlr16 r0 | ||
| 69 | shlr8 r0 | ||
| 70 | or r0, r6 | ||
| 71 | mov r4, r0 | ||
| 72 | tst #2, r0 | ||
| 73 | bt 2f | ||
| 74 | 21: | ||
| 75 | ! buf is 2 byte aligned (len could be 0) | ||
| 57 | add #-2, r5 ! Alignment uses up two bytes. | 76 | add #-2, r5 ! Alignment uses up two bytes. |
| 58 | cmp/pz r5 ! | 77 | cmp/pz r5 ! |
| 59 | bt/s 1f ! Jump if we had at least two bytes. | 78 | bt/s 1f ! Jump if we had at least two bytes. |
| @@ -61,16 +80,17 @@ ENTRY(csum_partial) | |||
| 61 | bra 6f | 80 | bra 6f |
| 62 | add #2, r5 ! r5 was < 2. Deal with it. | 81 | add #2, r5 ! r5 was < 2. Deal with it. |
| 63 | 1: | 82 | 1: |
| 64 | mov r5, r1 ! Save new len for later use. | ||
| 65 | mov.w @r4+, r0 | 83 | mov.w @r4+, r0 |
| 66 | extu.w r0, r0 | 84 | extu.w r0, r0 |
| 67 | addc r0, r6 | 85 | addc r0, r6 |
| 68 | bf 2f | 86 | bf 2f |
| 69 | add #1, r6 | 87 | add #1, r6 |
| 70 | 2: | 88 | 2: |
| 89 | ! buf is 4 byte aligned (len could be 0) | ||
| 90 | mov r5, r1 | ||
| 71 | mov #-5, r0 | 91 | mov #-5, r0 |
| 72 | shld r0, r5 | 92 | shld r0, r1 |
| 73 | tst r5, r5 | 93 | tst r1, r1 |
| 74 | bt/s 4f ! if it's =0, go to 4f | 94 | bt/s 4f ! if it's =0, go to 4f |
| 75 | clrt | 95 | clrt |
| 76 | .align 2 | 96 | .align 2 |
| @@ -92,30 +112,31 @@ ENTRY(csum_partial) | |||
| 92 | addc r0, r6 | 112 | addc r0, r6 |
| 93 | addc r2, r6 | 113 | addc r2, r6 |
| 94 | movt r0 | 114 | movt r0 |
| 95 | dt r5 | 115 | dt r1 |
| 96 | bf/s 3b | 116 | bf/s 3b |
| 97 | cmp/eq #1, r0 | 117 | cmp/eq #1, r0 |
| 98 | ! here, we know r5==0 | 118 | ! here, we know r1==0 |
| 99 | addc r5, r6 ! add carry to r6 | 119 | addc r1, r6 ! add carry to r6 |
| 100 | 4: | 120 | 4: |
| 101 | mov r1, r0 | 121 | mov r5, r0 |
| 102 | and #0x1c, r0 | 122 | and #0x1c, r0 |
| 103 | tst r0, r0 | 123 | tst r0, r0 |
| 104 | bt/s 6f | 124 | bt 6f |
| 105 | mov r0, r5 | 125 | ! 4 bytes or more remaining |
| 106 | shlr2 r5 | 126 | mov r0, r1 |
| 127 | shlr2 r1 | ||
| 107 | mov #0, r2 | 128 | mov #0, r2 |
| 108 | 5: | 129 | 5: |
| 109 | addc r2, r6 | 130 | addc r2, r6 |
| 110 | mov.l @r4+, r2 | 131 | mov.l @r4+, r2 |
| 111 | movt r0 | 132 | movt r0 |
| 112 | dt r5 | 133 | dt r1 |
| 113 | bf/s 5b | 134 | bf/s 5b |
| 114 | cmp/eq #1, r0 | 135 | cmp/eq #1, r0 |
| 115 | addc r2, r6 | 136 | addc r2, r6 |
| 116 | addc r5, r6 ! r5==0 here, so it means add carry-bit | 137 | addc r1, r6 ! r1==0 here, so it means add carry-bit |
| 117 | 6: | 138 | 6: |
| 118 | mov r1, r5 | 139 | ! 3 bytes or less remaining |
| 119 | mov #3, r0 | 140 | mov #3, r0 |
| 120 | and r0, r5 | 141 | and r0, r5 |
| 121 | tst r5, r5 | 142 | tst r5, r5 |
| @@ -139,8 +160,18 @@ ENTRY(csum_partial) | |||
| 139 | 8: | 160 | 8: |
| 140 | addc r0, r6 | 161 | addc r0, r6 |
| 141 | mov #0, r0 | 162 | mov #0, r0 |
| 142 | addc r0, r6 | 163 | addc r0, r6 |
| 143 | 9: | 164 | 9: |
| 165 | ! Check if the buffer was misaligned, if so realign sum | ||
| 166 | mov r7, r0 | ||
| 167 | tst #1, r0 | ||
| 168 | bt 10f | ||
| 169 | mov r6, r0 | ||
| 170 | shll8 r6 | ||
| 171 | shlr16 r0 | ||
| 172 | shlr8 r0 | ||
| 173 | or r0, r6 | ||
| 174 | 10: | ||
| 144 | rts | 175 | rts |
| 145 | mov r6, r0 | 176 | mov r6, r0 |
| 146 | 177 | ||
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index 256b00b61892..5a0d76dc56a4 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S | |||
| @@ -418,9 +418,9 @@ ENTRY(ia32_syscall) | |||
| 418 | orl $TS_COMPAT,TI_status(%r10) | 418 | orl $TS_COMPAT,TI_status(%r10) |
| 419 | testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) | 419 | testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) |
| 420 | jnz ia32_tracesys | 420 | jnz ia32_tracesys |
| 421 | ia32_do_syscall: | ||
| 422 | cmpl $(IA32_NR_syscalls-1),%eax | 421 | cmpl $(IA32_NR_syscalls-1),%eax |
| 423 | ja int_ret_from_sys_call /* ia32_tracesys has set RAX(%rsp) */ | 422 | ja ia32_badsys |
| 423 | ia32_do_call: | ||
| 424 | IA32_ARG_FIXUP | 424 | IA32_ARG_FIXUP |
| 425 | call *ia32_sys_call_table(,%rax,8) # xxx: rip relative | 425 | call *ia32_sys_call_table(,%rax,8) # xxx: rip relative |
| 426 | ia32_sysret: | 426 | ia32_sysret: |
| @@ -435,7 +435,9 @@ ia32_tracesys: | |||
| 435 | call syscall_trace_enter | 435 | call syscall_trace_enter |
| 436 | LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ | 436 | LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ |
| 437 | RESTORE_REST | 437 | RESTORE_REST |
| 438 | jmp ia32_do_syscall | 438 | cmpl $(IA32_NR_syscalls-1),%eax |
| 439 | ja int_ret_from_sys_call /* ia32_tracesys has set RAX(%rsp) */ | ||
| 440 | jmp ia32_do_call | ||
| 439 | END(ia32_syscall) | 441 | END(ia32_syscall) |
| 440 | 442 | ||
| 441 | ia32_badsys: | 443 | ia32_badsys: |
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index 707c1f6f95fa..a60c1f3bcb87 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c | |||
| @@ -156,11 +156,11 @@ static int __init acpi_sleep_setup(char *str) | |||
| 156 | #ifdef CONFIG_HIBERNATION | 156 | #ifdef CONFIG_HIBERNATION |
| 157 | if (strncmp(str, "s4_nohwsig", 10) == 0) | 157 | if (strncmp(str, "s4_nohwsig", 10) == 0) |
| 158 | acpi_no_s4_hw_signature(); | 158 | acpi_no_s4_hw_signature(); |
| 159 | if (strncmp(str, "s4_nonvs", 8) == 0) | ||
| 160 | acpi_s4_no_nvs(); | ||
| 159 | #endif | 161 | #endif |
| 160 | if (strncmp(str, "old_ordering", 12) == 0) | 162 | if (strncmp(str, "old_ordering", 12) == 0) |
| 161 | acpi_old_suspend_ordering(); | 163 | acpi_old_suspend_ordering(); |
| 162 | if (strncmp(str, "s4_nonvs", 8) == 0) | ||
| 163 | acpi_s4_no_nvs(); | ||
| 164 | str = strchr(str, ','); | 164 | str = strchr(str, ','); |
| 165 | if (str != NULL) | 165 | if (str != NULL) |
| 166 | str += strspn(str, ", \t"); | 166 | str += strspn(str, ", \t"); |
diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c index 4b6df2469fe3..115449f869ee 100644 --- a/arch/x86/kernel/apic.c +++ b/arch/x86/kernel/apic.c | |||
| @@ -1436,7 +1436,7 @@ static int __init detect_init_APIC(void) | |||
| 1436 | switch (boot_cpu_data.x86_vendor) { | 1436 | switch (boot_cpu_data.x86_vendor) { |
| 1437 | case X86_VENDOR_AMD: | 1437 | case X86_VENDOR_AMD: |
| 1438 | if ((boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model > 1) || | 1438 | if ((boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model > 1) || |
| 1439 | (boot_cpu_data.x86 == 15)) | 1439 | (boot_cpu_data.x86 >= 15)) |
| 1440 | break; | 1440 | break; |
| 1441 | goto no_apic; | 1441 | goto no_apic; |
| 1442 | case X86_VENDOR_INTEL: | 1442 | case X86_VENDOR_INTEL: |
diff --git a/arch/x86/kernel/cpu/cpufreq/Kconfig b/arch/x86/kernel/cpu/cpufreq/Kconfig index efae3b22a0ff..65792c2cc462 100644 --- a/arch/x86/kernel/cpu/cpufreq/Kconfig +++ b/arch/x86/kernel/cpu/cpufreq/Kconfig | |||
| @@ -245,17 +245,6 @@ config X86_E_POWERSAVER | |||
| 245 | 245 | ||
| 246 | comment "shared options" | 246 | comment "shared options" |
| 247 | 247 | ||
| 248 | config X86_ACPI_CPUFREQ_PROC_INTF | ||
| 249 | bool "/proc/acpi/processor/../performance interface (deprecated)" | ||
| 250 | depends on PROC_FS | ||
| 251 | depends on X86_ACPI_CPUFREQ || X86_POWERNOW_K7_ACPI || X86_POWERNOW_K8_ACPI | ||
| 252 | help | ||
| 253 | This enables the deprecated /proc/acpi/processor/../performance | ||
| 254 | interface. While it is helpful for debugging, the generic, | ||
| 255 | cross-architecture cpufreq interfaces should be used. | ||
| 256 | |||
| 257 | If in doubt, say N. | ||
| 258 | |||
| 259 | config X86_SPEEDSTEP_LIB | 248 | config X86_SPEEDSTEP_LIB |
| 260 | tristate | 249 | tristate |
| 261 | default (X86_SPEEDSTEP_ICH || X86_SPEEDSTEP_SMI || X86_P4_CLOCKMOD) | 250 | default (X86_SPEEDSTEP_ICH || X86_SPEEDSTEP_SMI || X86_P4_CLOCKMOD) |
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index 48533d77be78..da299eb85fc0 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c | |||
| @@ -36,8 +36,11 @@ static struct _cache_table cache_table[] __cpuinitdata = | |||
| 36 | { | 36 | { |
| 37 | { 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */ | 37 | { 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */ |
| 38 | { 0x08, LVL_1_INST, 16 }, /* 4-way set assoc, 32 byte line size */ | 38 | { 0x08, LVL_1_INST, 16 }, /* 4-way set assoc, 32 byte line size */ |
| 39 | { 0x09, LVL_1_INST, 32 }, /* 4-way set assoc, 64 byte line size */ | ||
| 39 | { 0x0a, LVL_1_DATA, 8 }, /* 2 way set assoc, 32 byte line size */ | 40 | { 0x0a, LVL_1_DATA, 8 }, /* 2 way set assoc, 32 byte line size */ |
| 40 | { 0x0c, LVL_1_DATA, 16 }, /* 4-way set assoc, 32 byte line size */ | 41 | { 0x0c, LVL_1_DATA, 16 }, /* 4-way set assoc, 32 byte line size */ |
| 42 | { 0x0d, LVL_1_DATA, 16 }, /* 4-way set assoc, 64 byte line size */ | ||
| 43 | { 0x21, LVL_2, 256 }, /* 8-way set assoc, 64 byte line size */ | ||
| 41 | { 0x22, LVL_3, 512 }, /* 4-way set assoc, sectored cache, 64 byte line size */ | 44 | { 0x22, LVL_3, 512 }, /* 4-way set assoc, sectored cache, 64 byte line size */ |
| 42 | { 0x23, LVL_3, 1024 }, /* 8-way set assoc, sectored cache, 64 byte line size */ | 45 | { 0x23, LVL_3, 1024 }, /* 8-way set assoc, sectored cache, 64 byte line size */ |
| 43 | { 0x25, LVL_3, 2048 }, /* 8-way set assoc, sectored cache, 64 byte line size */ | 46 | { 0x25, LVL_3, 2048 }, /* 8-way set assoc, sectored cache, 64 byte line size */ |
| @@ -85,6 +88,18 @@ static struct _cache_table cache_table[] __cpuinitdata = | |||
| 85 | { 0x85, LVL_2, 2048 }, /* 8-way set assoc, 32 byte line size */ | 88 | { 0x85, LVL_2, 2048 }, /* 8-way set assoc, 32 byte line size */ |
| 86 | { 0x86, LVL_2, 512 }, /* 4-way set assoc, 64 byte line size */ | 89 | { 0x86, LVL_2, 512 }, /* 4-way set assoc, 64 byte line size */ |
| 87 | { 0x87, LVL_2, 1024 }, /* 8-way set assoc, 64 byte line size */ | 90 | { 0x87, LVL_2, 1024 }, /* 8-way set assoc, 64 byte line size */ |
| 91 | { 0xd0, LVL_3, 512 }, /* 4-way set assoc, 64 byte line size */ | ||
| 92 | { 0xd1, LVL_3, 1024 }, /* 4-way set assoc, 64 byte line size */ | ||
| 93 | { 0xd2, LVL_3, 2048 }, /* 4-way set assoc, 64 byte line size */ | ||
| 94 | { 0xd6, LVL_3, 1024 }, /* 8-way set assoc, 64 byte line size */ | ||
| 95 | { 0xd7, LVL_3, 2038 }, /* 8-way set assoc, 64 byte line size */ | ||
| 96 | { 0xd8, LVL_3, 4096 }, /* 12-way set assoc, 64 byte line size */ | ||
| 97 | { 0xdc, LVL_3, 2048 }, /* 12-way set assoc, 64 byte line size */ | ||
| 98 | { 0xdd, LVL_3, 4096 }, /* 12-way set assoc, 64 byte line size */ | ||
| 99 | { 0xde, LVL_3, 8192 }, /* 12-way set assoc, 64 byte line size */ | ||
| 100 | { 0xe2, LVL_3, 2048 }, /* 16-way set assoc, 64 byte line size */ | ||
| 101 | { 0xe3, LVL_3, 4096 }, /* 16-way set assoc, 64 byte line size */ | ||
| 102 | { 0xe4, LVL_3, 8192 }, /* 16-way set assoc, 64 byte line size */ | ||
| 88 | { 0x00, 0, 0} | 103 | { 0x00, 0, 0} |
| 89 | }; | 104 | }; |
| 90 | 105 | ||
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index e28c7a987793..a1346217e43c 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
| @@ -346,6 +346,7 @@ ENTRY(save_args) | |||
| 346 | popq_cfi %rax /* move return address... */ | 346 | popq_cfi %rax /* move return address... */ |
| 347 | mov %gs:pda_irqstackptr,%rsp | 347 | mov %gs:pda_irqstackptr,%rsp |
| 348 | EMPTY_FRAME 0 | 348 | EMPTY_FRAME 0 |
| 349 | pushq_cfi %rbp /* backlink for unwinder */ | ||
| 349 | pushq_cfi %rax /* ... to the new stack */ | 350 | pushq_cfi %rax /* ... to the new stack */ |
| 350 | /* | 351 | /* |
| 351 | * We entered an interrupt context - irqs are off: | 352 | * We entered an interrupt context - irqs are off: |
diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c index 1c4a1302536c..9b0c480c383b 100644 --- a/arch/x86/kernel/io_apic.c +++ b/arch/x86/kernel/io_apic.c | |||
| @@ -2528,14 +2528,15 @@ static void irq_complete_move(struct irq_desc **descp) | |||
| 2528 | 2528 | ||
| 2529 | vector = ~get_irq_regs()->orig_ax; | 2529 | vector = ~get_irq_regs()->orig_ax; |
| 2530 | me = smp_processor_id(); | 2530 | me = smp_processor_id(); |
| 2531 | |||
| 2532 | if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) { | ||
| 2531 | #ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC | 2533 | #ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC |
| 2532 | *descp = desc = move_irq_desc(desc, me); | 2534 | *descp = desc = move_irq_desc(desc, me); |
| 2533 | /* get the new one */ | 2535 | /* get the new one */ |
| 2534 | cfg = desc->chip_data; | 2536 | cfg = desc->chip_data; |
| 2535 | #endif | 2537 | #endif |
| 2536 | |||
| 2537 | if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) | ||
| 2538 | send_cleanup_vector(cfg); | 2538 | send_cleanup_vector(cfg); |
| 2539 | } | ||
| 2539 | } | 2540 | } |
| 2540 | #else | 2541 | #else |
| 2541 | static inline void irq_complete_move(struct irq_desc **descp) {} | 2542 | static inline void irq_complete_move(struct irq_desc **descp) {} |
diff --git a/arch/x86/kernel/irqinit_32.c b/arch/x86/kernel/irqinit_32.c index 1507ad4e674d..10a09c2f1828 100644 --- a/arch/x86/kernel/irqinit_32.c +++ b/arch/x86/kernel/irqinit_32.c | |||
| @@ -78,15 +78,6 @@ void __init init_ISA_irqs(void) | |||
| 78 | } | 78 | } |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | /* | ||
| 82 | * IRQ2 is cascade interrupt to second interrupt controller | ||
| 83 | */ | ||
| 84 | static struct irqaction irq2 = { | ||
| 85 | .handler = no_action, | ||
| 86 | .mask = CPU_MASK_NONE, | ||
| 87 | .name = "cascade", | ||
| 88 | }; | ||
| 89 | |||
| 90 | DEFINE_PER_CPU(vector_irq_t, vector_irq) = { | 81 | DEFINE_PER_CPU(vector_irq_t, vector_irq) = { |
| 91 | [0 ... IRQ0_VECTOR - 1] = -1, | 82 | [0 ... IRQ0_VECTOR - 1] = -1, |
| 92 | [IRQ0_VECTOR] = 0, | 83 | [IRQ0_VECTOR] = 0, |
| @@ -178,9 +169,6 @@ void __init native_init_IRQ(void) | |||
| 178 | alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); | 169 | alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); |
| 179 | #endif | 170 | #endif |
| 180 | 171 | ||
| 181 | if (!acpi_ioapic) | ||
| 182 | setup_irq(2, &irq2); | ||
| 183 | |||
| 184 | /* setup after call gates are initialised (usually add in | 172 | /* setup after call gates are initialised (usually add in |
| 185 | * the architecture specific gates) | 173 | * the architecture specific gates) |
| 186 | */ | 174 | */ |
diff --git a/arch/x86/mach-default/setup.c b/arch/x86/mach-default/setup.c index df167f265622..a265a7c63190 100644 --- a/arch/x86/mach-default/setup.c +++ b/arch/x86/mach-default/setup.c | |||
| @@ -38,6 +38,15 @@ void __init pre_intr_init_hook(void) | |||
| 38 | init_ISA_irqs(); | 38 | init_ISA_irqs(); |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | /* | ||
| 42 | * IRQ2 is cascade interrupt to second interrupt controller | ||
| 43 | */ | ||
| 44 | static struct irqaction irq2 = { | ||
| 45 | .handler = no_action, | ||
| 46 | .mask = CPU_MASK_NONE, | ||
| 47 | .name = "cascade", | ||
| 48 | }; | ||
| 49 | |||
| 41 | /** | 50 | /** |
| 42 | * intr_init_hook - post gate setup interrupt initialisation | 51 | * intr_init_hook - post gate setup interrupt initialisation |
| 43 | * | 52 | * |
| @@ -53,6 +62,9 @@ void __init intr_init_hook(void) | |||
| 53 | if (x86_quirks->arch_intr_init()) | 62 | if (x86_quirks->arch_intr_init()) |
| 54 | return; | 63 | return; |
| 55 | } | 64 | } |
| 65 | if (!acpi_ioapic) | ||
| 66 | setup_irq(2, &irq2); | ||
| 67 | |||
| 56 | } | 68 | } |
| 57 | 69 | ||
| 58 | /** | 70 | /** |
diff --git a/arch/x86/mach-voyager/setup.c b/arch/x86/mach-voyager/setup.c index a580b9562e76..d914a7996a66 100644 --- a/arch/x86/mach-voyager/setup.c +++ b/arch/x86/mach-voyager/setup.c | |||
| @@ -33,13 +33,23 @@ void __init intr_init_hook(void) | |||
| 33 | setup_irq(2, &irq2); | 33 | setup_irq(2, &irq2); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | void __init pre_setup_arch_hook(void) | 36 | static void voyager_disable_tsc(void) |
| 37 | { | 37 | { |
| 38 | /* Voyagers run their CPUs from independent clocks, so disable | 38 | /* Voyagers run their CPUs from independent clocks, so disable |
| 39 | * the TSC code because we can't sync them */ | 39 | * the TSC code because we can't sync them */ |
| 40 | setup_clear_cpu_cap(X86_FEATURE_TSC); | 40 | setup_clear_cpu_cap(X86_FEATURE_TSC); |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | void __init pre_setup_arch_hook(void) | ||
| 44 | { | ||
| 45 | voyager_disable_tsc(); | ||
| 46 | } | ||
| 47 | |||
| 48 | void __init pre_time_init_hook(void) | ||
| 49 | { | ||
| 50 | voyager_disable_tsc(); | ||
| 51 | } | ||
| 52 | |||
| 43 | void __init trap_init_hook(void) | 53 | void __init trap_init_hook(void) |
| 44 | { | 54 | { |
| 45 | } | 55 | } |
diff --git a/arch/x86/mach-voyager/voyager_smp.c b/arch/x86/mach-voyager/voyager_smp.c index 9840b7ec749a..7ffcdeec4631 100644 --- a/arch/x86/mach-voyager/voyager_smp.c +++ b/arch/x86/mach-voyager/voyager_smp.c | |||
| @@ -81,7 +81,7 @@ static void enable_local_vic_irq(unsigned int irq); | |||
| 81 | static void disable_local_vic_irq(unsigned int irq); | 81 | static void disable_local_vic_irq(unsigned int irq); |
| 82 | static void before_handle_vic_irq(unsigned int irq); | 82 | static void before_handle_vic_irq(unsigned int irq); |
| 83 | static void after_handle_vic_irq(unsigned int irq); | 83 | static void after_handle_vic_irq(unsigned int irq); |
| 84 | static void set_vic_irq_affinity(unsigned int irq, cpumask_t mask); | 84 | static void set_vic_irq_affinity(unsigned int irq, const struct cpumask *mask); |
| 85 | static void ack_vic_irq(unsigned int irq); | 85 | static void ack_vic_irq(unsigned int irq); |
| 86 | static void vic_enable_cpi(void); | 86 | static void vic_enable_cpi(void); |
| 87 | static void do_boot_cpu(__u8 cpuid); | 87 | static void do_boot_cpu(__u8 cpuid); |
| @@ -211,8 +211,6 @@ static __u32 cpu_booted_map; | |||
| 211 | static cpumask_t smp_commenced_mask = CPU_MASK_NONE; | 211 | static cpumask_t smp_commenced_mask = CPU_MASK_NONE; |
| 212 | 212 | ||
| 213 | /* This is for the new dynamic CPU boot code */ | 213 | /* This is for the new dynamic CPU boot code */ |
| 214 | cpumask_t cpu_callin_map = CPU_MASK_NONE; | ||
| 215 | cpumask_t cpu_callout_map = CPU_MASK_NONE; | ||
| 216 | 214 | ||
| 217 | /* The per processor IRQ masks (these are usually kept in sync) */ | 215 | /* The per processor IRQ masks (these are usually kept in sync) */ |
| 218 | static __u16 vic_irq_mask[NR_CPUS] __cacheline_aligned; | 216 | static __u16 vic_irq_mask[NR_CPUS] __cacheline_aligned; |
| @@ -378,7 +376,7 @@ void __init find_smp_config(void) | |||
| 378 | cpus_addr(phys_cpu_present_map)[0] |= | 376 | cpus_addr(phys_cpu_present_map)[0] |= |
| 379 | voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + | 377 | voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + |
| 380 | 3) << 24; | 378 | 3) << 24; |
| 381 | cpu_possible_map = phys_cpu_present_map; | 379 | init_cpu_possible(&phys_cpu_present_map); |
| 382 | printk("VOYAGER SMP: phys_cpu_present_map = 0x%lx\n", | 380 | printk("VOYAGER SMP: phys_cpu_present_map = 0x%lx\n", |
| 383 | cpus_addr(phys_cpu_present_map)[0]); | 381 | cpus_addr(phys_cpu_present_map)[0]); |
| 384 | /* Here we set up the VIC to enable SMP */ | 382 | /* Here we set up the VIC to enable SMP */ |
| @@ -1599,16 +1597,16 @@ static void after_handle_vic_irq(unsigned int irq) | |||
| 1599 | * change the mask and then do an interrupt enable CPI to re-enable on | 1597 | * change the mask and then do an interrupt enable CPI to re-enable on |
| 1600 | * the selected processors */ | 1598 | * the selected processors */ |
| 1601 | 1599 | ||
| 1602 | void set_vic_irq_affinity(unsigned int irq, cpumask_t mask) | 1600 | void set_vic_irq_affinity(unsigned int irq, const struct cpumask *mask) |
| 1603 | { | 1601 | { |
| 1604 | /* Only extended processors handle interrupts */ | 1602 | /* Only extended processors handle interrupts */ |
| 1605 | unsigned long real_mask; | 1603 | unsigned long real_mask; |
| 1606 | unsigned long irq_mask = 1 << irq; | 1604 | unsigned long irq_mask = 1 << irq; |
| 1607 | int cpu; | 1605 | int cpu; |
| 1608 | 1606 | ||
| 1609 | real_mask = cpus_addr(mask)[0] & voyager_extended_vic_processors; | 1607 | real_mask = cpus_addr(*mask)[0] & voyager_extended_vic_processors; |
| 1610 | 1608 | ||
| 1611 | if (cpus_addr(mask)[0] == 0) | 1609 | if (cpus_addr(*mask)[0] == 0) |
| 1612 | /* can't have no CPUs to accept the interrupt -- extremely | 1610 | /* can't have no CPUs to accept the interrupt -- extremely |
| 1613 | * bad things will happen */ | 1611 | * bad things will happen */ |
| 1614 | return; | 1612 | return; |
| @@ -1750,10 +1748,11 @@ static void __cpuinit voyager_smp_prepare_boot_cpu(void) | |||
| 1750 | init_gdt(smp_processor_id()); | 1748 | init_gdt(smp_processor_id()); |
| 1751 | switch_to_new_gdt(); | 1749 | switch_to_new_gdt(); |
| 1752 | 1750 | ||
| 1753 | cpu_set(smp_processor_id(), cpu_online_map); | 1751 | cpu_online_map = cpumask_of_cpu(smp_processor_id()); |
| 1754 | cpu_set(smp_processor_id(), cpu_callout_map); | 1752 | cpu_callout_map = cpumask_of_cpu(smp_processor_id()); |
| 1755 | cpu_set(smp_processor_id(), cpu_possible_map); | 1753 | cpu_callin_map = CPU_MASK_NONE; |
| 1756 | cpu_set(smp_processor_id(), cpu_present_map); | 1754 | cpu_present_map = cpumask_of_cpu(smp_processor_id()); |
| 1755 | |||
| 1757 | } | 1756 | } |
| 1758 | 1757 | ||
| 1759 | static int __cpuinit voyager_cpu_up(unsigned int cpu) | 1758 | static int __cpuinit voyager_cpu_up(unsigned int cpu) |
| @@ -1783,9 +1782,9 @@ void __init smp_setup_processor_id(void) | |||
| 1783 | x86_write_percpu(cpu_number, hard_smp_processor_id()); | 1782 | x86_write_percpu(cpu_number, hard_smp_processor_id()); |
| 1784 | } | 1783 | } |
| 1785 | 1784 | ||
| 1786 | static void voyager_send_call_func(cpumask_t callmask) | 1785 | static void voyager_send_call_func(const struct cpumask *callmask) |
| 1787 | { | 1786 | { |
| 1788 | __u32 mask = cpus_addr(callmask)[0] & ~(1 << smp_processor_id()); | 1787 | __u32 mask = cpus_addr(*callmask)[0] & ~(1 << smp_processor_id()); |
| 1789 | send_CPI(mask, VIC_CALL_FUNCTION_CPI); | 1788 | send_CPI(mask, VIC_CALL_FUNCTION_CPI); |
| 1790 | } | 1789 | } |
| 1791 | 1790 | ||
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 90dfae511a41..c76ef1d701c9 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
| @@ -603,8 +603,6 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) | |||
| 603 | 603 | ||
| 604 | si_code = SEGV_MAPERR; | 604 | si_code = SEGV_MAPERR; |
| 605 | 605 | ||
| 606 | if (notify_page_fault(regs)) | ||
| 607 | return; | ||
| 608 | if (unlikely(kmmio_fault(regs, address))) | 606 | if (unlikely(kmmio_fault(regs, address))) |
| 609 | return; | 607 | return; |
| 610 | 608 | ||
| @@ -634,6 +632,9 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) | |||
| 634 | if (spurious_fault(address, error_code)) | 632 | if (spurious_fault(address, error_code)) |
| 635 | return; | 633 | return; |
| 636 | 634 | ||
| 635 | /* kprobes don't want to hook the spurious faults. */ | ||
| 636 | if (notify_page_fault(regs)) | ||
| 637 | return; | ||
| 637 | /* | 638 | /* |
| 638 | * Don't take the mm semaphore here. If we fixup a prefetch | 639 | * Don't take the mm semaphore here. If we fixup a prefetch |
| 639 | * fault we could otherwise deadlock. | 640 | * fault we could otherwise deadlock. |
| @@ -641,6 +642,9 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) | |||
| 641 | goto bad_area_nosemaphore; | 642 | goto bad_area_nosemaphore; |
| 642 | } | 643 | } |
| 643 | 644 | ||
| 645 | /* kprobes don't want to hook the spurious faults. */ | ||
| 646 | if (notify_page_fault(regs)) | ||
| 647 | return; | ||
| 644 | 648 | ||
| 645 | /* | 649 | /* |
| 646 | * It's safe to allow irq's after cr2 has been saved and the | 650 | * It's safe to allow irq's after cr2 has been saved and the |
diff --git a/arch/x86/xen/multicalls.h b/arch/x86/xen/multicalls.h index 858938241616..fa3e10725d98 100644 --- a/arch/x86/xen/multicalls.h +++ b/arch/x86/xen/multicalls.h | |||
| @@ -19,8 +19,10 @@ DECLARE_PER_CPU(unsigned long, xen_mc_irq_flags); | |||
| 19 | paired with xen_mc_issue() */ | 19 | paired with xen_mc_issue() */ |
| 20 | static inline void xen_mc_batch(void) | 20 | static inline void xen_mc_batch(void) |
| 21 | { | 21 | { |
| 22 | unsigned long flags; | ||
| 22 | /* need to disable interrupts until this entry is complete */ | 23 | /* need to disable interrupts until this entry is complete */ |
| 23 | local_irq_save(__get_cpu_var(xen_mc_irq_flags)); | 24 | local_irq_save(flags); |
| 25 | __get_cpu_var(xen_mc_irq_flags) = flags; | ||
| 24 | } | 26 | } |
| 25 | 27 | ||
| 26 | static inline struct multicall_space xen_mc_entry(size_t args) | 28 | static inline struct multicall_space xen_mc_entry(size_t args) |
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index d7f9839ba264..a7799a99f2d9 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
| @@ -9,6 +9,7 @@ menuconfig ACPI | |||
| 9 | depends on PCI | 9 | depends on PCI |
| 10 | depends on PM | 10 | depends on PM |
| 11 | select PNP | 11 | select PNP |
| 12 | select CPU_IDLE | ||
| 12 | default y | 13 | default y |
| 13 | ---help--- | 14 | ---help--- |
| 14 | Advanced Configuration and Power Interface (ACPI) support for | 15 | Advanced Configuration and Power Interface (ACPI) support for |
| @@ -287,7 +288,7 @@ config ACPI_CONTAINER | |||
| 287 | support physical cpu/memory hot-plug. | 288 | support physical cpu/memory hot-plug. |
| 288 | 289 | ||
| 289 | If one selects "m", this driver can be loaded with | 290 | If one selects "m", this driver can be loaded with |
| 290 | "modprobe acpi_container". | 291 | "modprobe container". |
| 291 | 292 | ||
| 292 | config ACPI_HOTPLUG_MEMORY | 293 | config ACPI_HOTPLUG_MEMORY |
| 293 | tristate "Memory Hotplug" | 294 | tristate "Memory Hotplug" |
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index 9684cc827930..22ce48985720 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c | |||
| @@ -538,10 +538,9 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) | |||
| 538 | if (ACPI_FAILURE(status)) { | 538 | if (ACPI_FAILURE(status)) { |
| 539 | ACPI_WARNING((AE_INFO, | 539 | ACPI_WARNING((AE_INFO, |
| 540 | "Truncating %u table entries!", | 540 | "Truncating %u table entries!", |
| 541 | (unsigned) | 541 | (unsigned) (table_count - |
| 542 | (acpi_gbl_root_table_list.size - | 542 | (acpi_gbl_root_table_list. |
| 543 | acpi_gbl_root_table_list. | 543 | count - 2)))); |
| 544 | count))); | ||
| 545 | break; | 544 | break; |
| 546 | } | 545 | } |
| 547 | } | 546 | } |
diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c index da9450bc60f7..9c9897dbe907 100644 --- a/drivers/acpi/acpica/uteval.c +++ b/drivers/acpi/acpica/uteval.c | |||
| @@ -116,9 +116,9 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) | |||
| 116 | return_ACPI_STATUS(AE_NO_MEMORY); | 116 | return_ACPI_STATUS(AE_NO_MEMORY); |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | /* Default return value is SUPPORTED */ | 119 | /* Default return value is 0, NOT-SUPPORTED */ |
| 120 | 120 | ||
| 121 | return_desc->integer.value = ACPI_UINT32_MAX; | 121 | return_desc->integer.value = 0; |
| 122 | walk_state->return_desc = return_desc; | 122 | walk_state->return_desc = return_desc; |
| 123 | 123 | ||
| 124 | /* Compare input string to static table of supported interfaces */ | 124 | /* Compare input string to static table of supported interfaces */ |
| @@ -127,10 +127,8 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) | |||
| 127 | if (!ACPI_STRCMP | 127 | if (!ACPI_STRCMP |
| 128 | (string_desc->string.pointer, | 128 | (string_desc->string.pointer, |
| 129 | acpi_interfaces_supported[i])) { | 129 | acpi_interfaces_supported[i])) { |
| 130 | 130 | return_desc->integer.value = ACPI_UINT32_MAX; | |
| 131 | /* The interface is supported */ | 131 | goto done; |
| 132 | |||
| 133 | return_ACPI_STATUS(AE_OK); | ||
| 134 | } | 132 | } |
| 135 | } | 133 | } |
| 136 | 134 | ||
| @@ -141,15 +139,14 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) | |||
| 141 | */ | 139 | */ |
| 142 | status = acpi_os_validate_interface(string_desc->string.pointer); | 140 | status = acpi_os_validate_interface(string_desc->string.pointer); |
| 143 | if (ACPI_SUCCESS(status)) { | 141 | if (ACPI_SUCCESS(status)) { |
| 144 | 142 | return_desc->integer.value = ACPI_UINT32_MAX; | |
| 145 | /* The interface is supported */ | ||
| 146 | |||
| 147 | return_ACPI_STATUS(AE_OK); | ||
| 148 | } | 143 | } |
| 149 | 144 | ||
| 150 | /* The interface is not supported */ | 145 | done: |
| 146 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, "ACPI: BIOS _OSI(%s) %ssupported\n", | ||
| 147 | string_desc->string.pointer, | ||
| 148 | return_desc->integer.value == 0 ? "not-" : "")); | ||
| 151 | 149 | ||
| 152 | return_desc->integer.value = 0; | ||
| 153 | return_ACPI_STATUS(AE_OK); | 150 | return_ACPI_STATUS(AE_OK); |
| 154 | } | 151 | } |
| 155 | 152 | ||
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index 17020c12623c..fe0cdf83641a 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c | |||
| @@ -163,7 +163,7 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context) | |||
| 163 | case ACPI_NOTIFY_BUS_CHECK: | 163 | case ACPI_NOTIFY_BUS_CHECK: |
| 164 | /* Fall through */ | 164 | /* Fall through */ |
| 165 | case ACPI_NOTIFY_DEVICE_CHECK: | 165 | case ACPI_NOTIFY_DEVICE_CHECK: |
| 166 | printk("Container driver received %s event\n", | 166 | printk(KERN_WARNING "Container driver received %s event\n", |
| 167 | (type == ACPI_NOTIFY_BUS_CHECK) ? | 167 | (type == ACPI_NOTIFY_BUS_CHECK) ? |
| 168 | "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK"); | 168 | "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK"); |
| 169 | status = acpi_bus_get_device(handle, &device); | 169 | status = acpi_bus_get_device(handle, &device); |
| @@ -174,7 +174,8 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context) | |||
| 174 | kobject_uevent(&device->dev.kobj, | 174 | kobject_uevent(&device->dev.kobj, |
| 175 | KOBJ_ONLINE); | 175 | KOBJ_ONLINE); |
| 176 | else | 176 | else |
| 177 | printk("Failed to add container\n"); | 177 | printk(KERN_WARNING |
| 178 | "Failed to add container\n"); | ||
| 178 | } | 179 | } |
| 179 | } else { | 180 | } else { |
| 180 | if (ACPI_SUCCESS(status)) { | 181 | if (ACPI_SUCCESS(status)) { |
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 5b30b8d91d71..35094f230b1e 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
| @@ -855,10 +855,14 @@ fdd_out: | |||
| 855 | static ssize_t show_docked(struct device *dev, | 855 | static ssize_t show_docked(struct device *dev, |
| 856 | struct device_attribute *attr, char *buf) | 856 | struct device_attribute *attr, char *buf) |
| 857 | { | 857 | { |
| 858 | struct acpi_device *tmp; | ||
| 859 | |||
| 858 | struct dock_station *dock_station = *((struct dock_station **) | 860 | struct dock_station *dock_station = *((struct dock_station **) |
| 859 | dev->platform_data); | 861 | dev->platform_data); |
| 860 | return snprintf(buf, PAGE_SIZE, "%d\n", dock_present(dock_station)); | ||
| 861 | 862 | ||
| 863 | if (ACPI_SUCCESS(acpi_bus_get_device(dock_station->handle, &tmp))) | ||
| 864 | return snprintf(buf, PAGE_SIZE, "1\n"); | ||
| 865 | return snprintf(buf, PAGE_SIZE, "0\n"); | ||
| 862 | } | 866 | } |
| 863 | static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); | 867 | static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); |
| 864 | 868 | ||
| @@ -984,7 +988,7 @@ static int dock_add(acpi_handle handle) | |||
| 984 | 988 | ||
| 985 | ret = device_create_file(&dock_device->dev, &dev_attr_docked); | 989 | ret = device_create_file(&dock_device->dev, &dev_attr_docked); |
| 986 | if (ret) { | 990 | if (ret) { |
| 987 | printk("Error %d adding sysfs file\n", ret); | 991 | printk(KERN_ERR "Error %d adding sysfs file\n", ret); |
| 988 | platform_device_unregister(dock_device); | 992 | platform_device_unregister(dock_device); |
| 989 | kfree(dock_station); | 993 | kfree(dock_station); |
| 990 | dock_station = NULL; | 994 | dock_station = NULL; |
| @@ -992,7 +996,7 @@ static int dock_add(acpi_handle handle) | |||
| 992 | } | 996 | } |
| 993 | ret = device_create_file(&dock_device->dev, &dev_attr_undock); | 997 | ret = device_create_file(&dock_device->dev, &dev_attr_undock); |
| 994 | if (ret) { | 998 | if (ret) { |
| 995 | printk("Error %d adding sysfs file\n", ret); | 999 | printk(KERN_ERR "Error %d adding sysfs file\n", ret); |
| 996 | device_remove_file(&dock_device->dev, &dev_attr_docked); | 1000 | device_remove_file(&dock_device->dev, &dev_attr_docked); |
| 997 | platform_device_unregister(dock_device); | 1001 | platform_device_unregister(dock_device); |
| 998 | kfree(dock_station); | 1002 | kfree(dock_station); |
| @@ -1001,7 +1005,7 @@ static int dock_add(acpi_handle handle) | |||
| 1001 | } | 1005 | } |
| 1002 | ret = device_create_file(&dock_device->dev, &dev_attr_uid); | 1006 | ret = device_create_file(&dock_device->dev, &dev_attr_uid); |
| 1003 | if (ret) { | 1007 | if (ret) { |
| 1004 | printk("Error %d adding sysfs file\n", ret); | 1008 | printk(KERN_ERR "Error %d adding sysfs file\n", ret); |
| 1005 | device_remove_file(&dock_device->dev, &dev_attr_docked); | 1009 | device_remove_file(&dock_device->dev, &dev_attr_docked); |
| 1006 | device_remove_file(&dock_device->dev, &dev_attr_undock); | 1010 | device_remove_file(&dock_device->dev, &dev_attr_undock); |
| 1007 | platform_device_unregister(dock_device); | 1011 | platform_device_unregister(dock_device); |
| @@ -1011,7 +1015,7 @@ static int dock_add(acpi_handle handle) | |||
| 1011 | } | 1015 | } |
| 1012 | ret = device_create_file(&dock_device->dev, &dev_attr_flags); | 1016 | ret = device_create_file(&dock_device->dev, &dev_attr_flags); |
| 1013 | if (ret) { | 1017 | if (ret) { |
| 1014 | printk("Error %d adding sysfs file\n", ret); | 1018 | printk(KERN_ERR "Error %d adding sysfs file\n", ret); |
| 1015 | device_remove_file(&dock_device->dev, &dev_attr_docked); | 1019 | device_remove_file(&dock_device->dev, &dev_attr_docked); |
| 1016 | device_remove_file(&dock_device->dev, &dev_attr_undock); | 1020 | device_remove_file(&dock_device->dev, &dev_attr_undock); |
| 1017 | device_remove_file(&dock_device->dev, &dev_attr_uid); | 1021 | device_remove_file(&dock_device->dev, &dev_attr_uid); |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index a2b82c90a683..5c2f5d343be6 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
| @@ -982,7 +982,7 @@ int __init acpi_ec_ecdt_probe(void) | |||
| 982 | saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); | 982 | saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); |
| 983 | if (!saved_ec) | 983 | if (!saved_ec) |
| 984 | return -ENOMEM; | 984 | return -ENOMEM; |
| 985 | memcpy(&saved_ec, boot_ec, sizeof(saved_ec)); | 985 | memcpy(saved_ec, boot_ec, sizeof(*saved_ec)); |
| 986 | /* fall through */ | 986 | /* fall through */ |
| 987 | } | 987 | } |
| 988 | /* This workaround is needed only on some broken machines, | 988 | /* This workaround is needed only on some broken machines, |
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index adec3d15810a..5479b9f42513 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
| @@ -255,12 +255,12 @@ static int acpi_platform_notify(struct device *dev) | |||
| 255 | } | 255 | } |
| 256 | type = acpi_get_bus_type(dev->bus); | 256 | type = acpi_get_bus_type(dev->bus); |
| 257 | if (!type) { | 257 | if (!type) { |
| 258 | DBG("No ACPI bus support for %s\n", dev->bus_id); | 258 | DBG("No ACPI bus support for %s\n", dev_name(dev)); |
| 259 | ret = -EINVAL; | 259 | ret = -EINVAL; |
| 260 | goto end; | 260 | goto end; |
| 261 | } | 261 | } |
| 262 | if ((ret = type->find_device(dev, &handle)) != 0) | 262 | if ((ret = type->find_device(dev, &handle)) != 0) |
| 263 | DBG("Can't get handler for %s\n", dev->bus_id); | 263 | DBG("Can't get handler for %s\n", dev_name(dev)); |
| 264 | end: | 264 | end: |
| 265 | if (!ret) | 265 | if (!ret) |
| 266 | acpi_bind_one(dev, handle); | 266 | acpi_bind_one(dev, handle); |
| @@ -271,10 +271,10 @@ static int acpi_platform_notify(struct device *dev) | |||
| 271 | 271 | ||
| 272 | acpi_get_name(dev->archdata.acpi_handle, | 272 | acpi_get_name(dev->archdata.acpi_handle, |
| 273 | ACPI_FULL_PATHNAME, &buffer); | 273 | ACPI_FULL_PATHNAME, &buffer); |
| 274 | DBG("Device %s -> %s\n", dev->bus_id, (char *)buffer.pointer); | 274 | DBG("Device %s -> %s\n", dev_name(dev), (char *)buffer.pointer); |
| 275 | kfree(buffer.pointer); | 275 | kfree(buffer.pointer); |
| 276 | } else | 276 | } else |
| 277 | DBG("Device %s -> No ACPI support\n", dev->bus_id); | 277 | DBG("Device %s -> No ACPI support\n", dev_name(dev)); |
| 278 | #endif | 278 | #endif |
| 279 | 279 | ||
| 280 | return ret; | 280 | return ret; |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 6729a4992f2b..b3193ec0a2ef 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
| @@ -228,10 +228,10 @@ void acpi_os_vprintf(const char *fmt, va_list args) | |||
| 228 | if (acpi_in_debugger) { | 228 | if (acpi_in_debugger) { |
| 229 | kdb_printf("%s", buffer); | 229 | kdb_printf("%s", buffer); |
| 230 | } else { | 230 | } else { |
| 231 | printk("%s", buffer); | 231 | printk(KERN_CONT "%s", buffer); |
| 232 | } | 232 | } |
| 233 | #else | 233 | #else |
| 234 | printk("%s", buffer); | 234 | printk(KERN_CONT "%s", buffer); |
| 235 | #endif | 235 | #endif |
| 236 | } | 236 | } |
| 237 | 237 | ||
| @@ -1317,6 +1317,54 @@ acpi_os_validate_interface (char *interface) | |||
| 1317 | return AE_SUPPORT; | 1317 | return AE_SUPPORT; |
| 1318 | } | 1318 | } |
| 1319 | 1319 | ||
| 1320 | #ifdef CONFIG_X86 | ||
| 1321 | |||
| 1322 | struct aml_port_desc { | ||
| 1323 | uint start; | ||
| 1324 | uint end; | ||
| 1325 | char* name; | ||
| 1326 | char warned; | ||
| 1327 | }; | ||
| 1328 | |||
| 1329 | static struct aml_port_desc aml_invalid_port_list[] = { | ||
| 1330 | {0x20, 0x21, "PIC0", 0}, | ||
| 1331 | {0xA0, 0xA1, "PIC1", 0}, | ||
| 1332 | {0x4D0, 0x4D1, "ELCR", 0} | ||
| 1333 | }; | ||
| 1334 | |||
| 1335 | /* | ||
| 1336 | * valid_aml_io_address() | ||
| 1337 | * | ||
| 1338 | * if valid, return true | ||
| 1339 | * else invalid, warn once, return false | ||
| 1340 | */ | ||
| 1341 | static bool valid_aml_io_address(uint address, uint length) | ||
| 1342 | { | ||
| 1343 | int i; | ||
| 1344 | int entries = sizeof(aml_invalid_port_list) / sizeof(struct aml_port_desc); | ||
| 1345 | |||
| 1346 | for (i = 0; i < entries; ++i) { | ||
| 1347 | if ((address >= aml_invalid_port_list[i].start && | ||
| 1348 | address <= aml_invalid_port_list[i].end) || | ||
| 1349 | (address + length >= aml_invalid_port_list[i].start && | ||
| 1350 | address + length <= aml_invalid_port_list[i].end)) | ||
| 1351 | { | ||
| 1352 | if (!aml_invalid_port_list[i].warned) | ||
| 1353 | { | ||
| 1354 | printk(KERN_ERR "ACPI: Denied BIOS AML access" | ||
| 1355 | " to invalid port 0x%x+0x%x (%s)\n", | ||
| 1356 | address, length, | ||
| 1357 | aml_invalid_port_list[i].name); | ||
| 1358 | aml_invalid_port_list[i].warned = 1; | ||
| 1359 | } | ||
| 1360 | return false; /* invalid */ | ||
| 1361 | } | ||
| 1362 | } | ||
| 1363 | return true; /* valid */ | ||
| 1364 | } | ||
| 1365 | #else | ||
| 1366 | static inline bool valid_aml_io_address(uint address, uint length) { return true; } | ||
| 1367 | #endif | ||
| 1320 | /****************************************************************************** | 1368 | /****************************************************************************** |
| 1321 | * | 1369 | * |
| 1322 | * FUNCTION: acpi_os_validate_address | 1370 | * FUNCTION: acpi_os_validate_address |
| @@ -1346,6 +1394,8 @@ acpi_os_validate_address ( | |||
| 1346 | 1394 | ||
| 1347 | switch (space_id) { | 1395 | switch (space_id) { |
| 1348 | case ACPI_ADR_SPACE_SYSTEM_IO: | 1396 | case ACPI_ADR_SPACE_SYSTEM_IO: |
| 1397 | if (!valid_aml_io_address(address, length)) | ||
| 1398 | return AE_AML_ILLEGAL_ADDRESS; | ||
| 1349 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | 1399 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: |
| 1350 | /* Only interference checks against SystemIO and SytemMemory | 1400 | /* Only interference checks against SystemIO and SytemMemory |
| 1351 | are needed */ | 1401 | are needed */ |
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index 1c6e73c7865e..6c772ca76bd1 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c | |||
| @@ -593,7 +593,7 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link) | |||
| 593 | return -ENODEV; | 593 | return -ENODEV; |
| 594 | } else { | 594 | } else { |
| 595 | acpi_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_USING; | 595 | acpi_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_USING; |
| 596 | printk(PREFIX "%s [%s] enabled at IRQ %d\n", | 596 | printk(KERN_WARNING PREFIX "%s [%s] enabled at IRQ %d\n", |
| 597 | acpi_device_name(link->device), | 597 | acpi_device_name(link->device), |
| 598 | acpi_device_bid(link->device), link->irq.active); | 598 | acpi_device_bid(link->device), link->irq.active); |
| 599 | } | 599 | } |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 66a9d8145562..7bc22a471fe3 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
| @@ -66,43 +66,17 @@ ACPI_MODULE_NAME("processor_idle"); | |||
| 66 | #define ACPI_PROCESSOR_FILE_POWER "power" | 66 | #define ACPI_PROCESSOR_FILE_POWER "power" |
| 67 | #define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000) | 67 | #define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000) |
| 68 | #define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY) | 68 | #define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY) |
| 69 | #ifndef CONFIG_CPU_IDLE | ||
| 70 | #define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */ | ||
| 71 | #define C3_OVERHEAD 4 /* 1us (3.579 ticks per us) */ | ||
| 72 | static void (*pm_idle_save) (void) __read_mostly; | ||
| 73 | #else | ||
| 74 | #define C2_OVERHEAD 1 /* 1us */ | 69 | #define C2_OVERHEAD 1 /* 1us */ |
| 75 | #define C3_OVERHEAD 1 /* 1us */ | 70 | #define C3_OVERHEAD 1 /* 1us */ |
| 76 | #endif | ||
| 77 | #define PM_TIMER_TICKS_TO_US(p) (((p) * 1000)/(PM_TIMER_FREQUENCY/1000)) | 71 | #define PM_TIMER_TICKS_TO_US(p) (((p) * 1000)/(PM_TIMER_FREQUENCY/1000)) |
| 78 | 72 | ||
| 79 | static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER; | 73 | static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER; |
| 80 | #ifdef CONFIG_CPU_IDLE | ||
| 81 | module_param(max_cstate, uint, 0000); | 74 | module_param(max_cstate, uint, 0000); |
| 82 | #else | ||
| 83 | module_param(max_cstate, uint, 0644); | ||
| 84 | #endif | ||
| 85 | static unsigned int nocst __read_mostly; | 75 | static unsigned int nocst __read_mostly; |
| 86 | module_param(nocst, uint, 0000); | 76 | module_param(nocst, uint, 0000); |
| 87 | 77 | ||
| 88 | #ifndef CONFIG_CPU_IDLE | ||
| 89 | /* | ||
| 90 | * bm_history -- bit-mask with a bit per jiffy of bus-master activity | ||
| 91 | * 1000 HZ: 0xFFFFFFFF: 32 jiffies = 32ms | ||
| 92 | * 800 HZ: 0xFFFFFFFF: 32 jiffies = 40ms | ||
| 93 | * 100 HZ: 0x0000000F: 4 jiffies = 40ms | ||
| 94 | * reduce history for more aggressive entry into C3 | ||
| 95 | */ | ||
| 96 | static unsigned int bm_history __read_mostly = | ||
| 97 | (HZ >= 800 ? 0xFFFFFFFF : ((1U << (HZ / 25)) - 1)); | ||
| 98 | module_param(bm_history, uint, 0644); | ||
| 99 | |||
| 100 | static int acpi_processor_set_power_policy(struct acpi_processor *pr); | ||
| 101 | |||
| 102 | #else /* CONFIG_CPU_IDLE */ | ||
| 103 | static unsigned int latency_factor __read_mostly = 2; | 78 | static unsigned int latency_factor __read_mostly = 2; |
| 104 | module_param(latency_factor, uint, 0644); | 79 | module_param(latency_factor, uint, 0644); |
| 105 | #endif | ||
| 106 | 80 | ||
| 107 | /* | 81 | /* |
| 108 | * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3. | 82 | * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3. |
| @@ -224,71 +198,6 @@ static void acpi_safe_halt(void) | |||
| 224 | current_thread_info()->status |= TS_POLLING; | 198 | current_thread_info()->status |= TS_POLLING; |
| 225 | } | 199 | } |
| 226 | 200 | ||
| 227 | #ifndef CONFIG_CPU_IDLE | ||
| 228 | |||
| 229 | static void | ||
| 230 | acpi_processor_power_activate(struct acpi_processor *pr, | ||
| 231 | struct acpi_processor_cx *new) | ||
| 232 | { | ||
| 233 | struct acpi_processor_cx *old; | ||
| 234 | |||
| 235 | if (!pr || !new) | ||
| 236 | return; | ||
| 237 | |||
| 238 | old = pr->power.state; | ||
| 239 | |||
| 240 | if (old) | ||
| 241 | old->promotion.count = 0; | ||
| 242 | new->demotion.count = 0; | ||
| 243 | |||
| 244 | /* Cleanup from old state. */ | ||
| 245 | if (old) { | ||
| 246 | switch (old->type) { | ||
| 247 | case ACPI_STATE_C3: | ||
| 248 | /* Disable bus master reload */ | ||
| 249 | if (new->type != ACPI_STATE_C3 && pr->flags.bm_check) | ||
| 250 | acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); | ||
| 251 | break; | ||
| 252 | } | ||
| 253 | } | ||
| 254 | |||
| 255 | /* Prepare to use new state. */ | ||
| 256 | switch (new->type) { | ||
| 257 | case ACPI_STATE_C3: | ||
| 258 | /* Enable bus master reload */ | ||
| 259 | if (old->type != ACPI_STATE_C3 && pr->flags.bm_check) | ||
| 260 | acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1); | ||
| 261 | break; | ||
| 262 | } | ||
| 263 | |||
| 264 | pr->power.state = new; | ||
| 265 | |||
| 266 | return; | ||
| 267 | } | ||
| 268 | |||
| 269 | static atomic_t c3_cpu_count; | ||
| 270 | |||
| 271 | /* Common C-state entry for C2, C3, .. */ | ||
| 272 | static void acpi_cstate_enter(struct acpi_processor_cx *cstate) | ||
| 273 | { | ||
| 274 | /* Don't trace irqs off for idle */ | ||
| 275 | stop_critical_timings(); | ||
| 276 | if (cstate->entry_method == ACPI_CSTATE_FFH) { | ||
| 277 | /* Call into architectural FFH based C-state */ | ||
| 278 | acpi_processor_ffh_cstate_enter(cstate); | ||
| 279 | } else { | ||
| 280 | int unused; | ||
| 281 | /* IO port based C-state */ | ||
| 282 | inb(cstate->address); | ||
| 283 | /* Dummy wait op - must do something useless after P_LVL2 read | ||
| 284 | because chipsets cannot guarantee that STPCLK# signal | ||
| 285 | gets asserted in time to freeze execution properly. */ | ||
| 286 | unused = inl(acpi_gbl_FADT.xpm_timer_block.address); | ||
| 287 | } | ||
| 288 | start_critical_timings(); | ||
| 289 | } | ||
| 290 | #endif /* !CONFIG_CPU_IDLE */ | ||
| 291 | |||
| 292 | #ifdef ARCH_APICTIMER_STOPS_ON_C3 | 201 | #ifdef ARCH_APICTIMER_STOPS_ON_C3 |
| 293 | 202 | ||
| 294 | /* | 203 | /* |
| @@ -390,421 +299,6 @@ static int tsc_halts_in_c(int state) | |||
| 390 | } | 299 | } |
| 391 | #endif | 300 | #endif |
| 392 | 301 | ||
| 393 | #ifndef CONFIG_CPU_IDLE | ||
| 394 | static void acpi_processor_idle(void) | ||
| 395 | { | ||
| 396 | struct acpi_processor *pr = NULL; | ||
| 397 | struct acpi_processor_cx *cx = NULL; | ||
| 398 | struct acpi_processor_cx *next_state = NULL; | ||
| 399 | int sleep_ticks = 0; | ||
| 400 | u32 t1, t2 = 0; | ||
| 401 | |||
| 402 | /* | ||
| 403 | * Interrupts must be disabled during bus mastering calculations and | ||
| 404 | * for C2/C3 transitions. | ||
| 405 | */ | ||
| 406 | local_irq_disable(); | ||
| 407 | |||
| 408 | pr = __get_cpu_var(processors); | ||
| 409 | if (!pr) { | ||
| 410 | local_irq_enable(); | ||
| 411 | return; | ||
| 412 | } | ||
| 413 | |||
| 414 | /* | ||
| 415 | * Check whether we truly need to go idle, or should | ||
| 416 | * reschedule: | ||
| 417 | */ | ||
| 418 | if (unlikely(need_resched())) { | ||
| 419 | local_irq_enable(); | ||
| 420 | return; | ||
| 421 | } | ||
| 422 | |||
| 423 | cx = pr->power.state; | ||
| 424 | if (!cx || acpi_idle_suspend) { | ||
| 425 | if (pm_idle_save) { | ||
| 426 | pm_idle_save(); /* enables IRQs */ | ||
| 427 | } else { | ||
| 428 | acpi_safe_halt(); | ||
| 429 | local_irq_enable(); | ||
| 430 | } | ||
| 431 | |||
| 432 | return; | ||
| 433 | } | ||
| 434 | |||
| 435 | /* | ||
| 436 | * Check BM Activity | ||
| 437 | * ----------------- | ||
| 438 | * Check for bus mastering activity (if required), record, and check | ||
| 439 | * for demotion. | ||
| 440 | */ | ||
| 441 | if (pr->flags.bm_check) { | ||
| 442 | u32 bm_status = 0; | ||
| 443 | unsigned long diff = jiffies - pr->power.bm_check_timestamp; | ||
| 444 | |||
| 445 | if (diff > 31) | ||
| 446 | diff = 31; | ||
| 447 | |||
| 448 | pr->power.bm_activity <<= diff; | ||
| 449 | |||
| 450 | acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status); | ||
| 451 | if (bm_status) { | ||
| 452 | pr->power.bm_activity |= 0x1; | ||
| 453 | acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1); | ||
| 454 | } | ||
| 455 | /* | ||
| 456 | * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect | ||
| 457 | * the true state of bus mastering activity; forcing us to | ||
| 458 | * manually check the BMIDEA bit of each IDE channel. | ||
| 459 | */ | ||
| 460 | else if (errata.piix4.bmisx) { | ||
| 461 | if ((inb_p(errata.piix4.bmisx + 0x02) & 0x01) | ||
| 462 | || (inb_p(errata.piix4.bmisx + 0x0A) & 0x01)) | ||
| 463 | pr->power.bm_activity |= 0x1; | ||
| 464 | } | ||
| 465 | |||
| 466 | pr->power.bm_check_timestamp = jiffies; | ||
| 467 | |||
| 468 | /* | ||
| 469 | * If bus mastering is or was active this jiffy, demote | ||
| 470 | * to avoid a faulty transition. Note that the processor | ||
| 471 | * won't enter a low-power state during this call (to this | ||
| 472 | * function) but should upon the next. | ||
| 473 | * | ||
| 474 | * TBD: A better policy might be to fallback to the demotion | ||
| 475 | * state (use it for this quantum only) istead of | ||
| 476 | * demoting -- and rely on duration as our sole demotion | ||
| 477 | * qualification. This may, however, introduce DMA | ||
| 478 | * issues (e.g. floppy DMA transfer overrun/underrun). | ||
| 479 | */ | ||
| 480 | if ((pr->power.bm_activity & 0x1) && | ||
| 481 | cx->demotion.threshold.bm) { | ||
| 482 | local_irq_enable(); | ||
| 483 | next_state = cx->demotion.state; | ||
| 484 | goto end; | ||
| 485 | } | ||
| 486 | } | ||
| 487 | |||
| 488 | #ifdef CONFIG_HOTPLUG_CPU | ||
| 489 | /* | ||
| 490 | * Check for P_LVL2_UP flag before entering C2 and above on | ||
| 491 | * an SMP system. We do it here instead of doing it at _CST/P_LVL | ||
| 492 | * detection phase, to work cleanly with logical CPU hotplug. | ||
| 493 | */ | ||
| 494 | if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && | ||
| 495 | !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) | ||
| 496 | cx = &pr->power.states[ACPI_STATE_C1]; | ||
| 497 | #endif | ||
| 498 | |||
| 499 | /* | ||
| 500 | * Sleep: | ||
| 501 | * ------ | ||
| 502 | * Invoke the current Cx state to put the processor to sleep. | ||
| 503 | */ | ||
| 504 | if (cx->type == ACPI_STATE_C2 || cx->type == ACPI_STATE_C3) { | ||
| 505 | current_thread_info()->status &= ~TS_POLLING; | ||
| 506 | /* | ||
| 507 | * TS_POLLING-cleared state must be visible before we | ||
| 508 | * test NEED_RESCHED: | ||
| 509 | */ | ||
| 510 | smp_mb(); | ||
| 511 | if (need_resched()) { | ||
| 512 | current_thread_info()->status |= TS_POLLING; | ||
| 513 | local_irq_enable(); | ||
| 514 | return; | ||
| 515 | } | ||
| 516 | } | ||
| 517 | |||
| 518 | switch (cx->type) { | ||
| 519 | |||
| 520 | case ACPI_STATE_C1: | ||
| 521 | /* | ||
| 522 | * Invoke C1. | ||
| 523 | * Use the appropriate idle routine, the one that would | ||
| 524 | * be used without acpi C-states. | ||
| 525 | */ | ||
| 526 | if (pm_idle_save) { | ||
| 527 | pm_idle_save(); /* enables IRQs */ | ||
| 528 | } else { | ||
| 529 | acpi_safe_halt(); | ||
| 530 | local_irq_enable(); | ||
| 531 | } | ||
| 532 | |||
| 533 | /* | ||
| 534 | * TBD: Can't get time duration while in C1, as resumes | ||
| 535 | * go to an ISR rather than here. Need to instrument | ||
| 536 | * base interrupt handler. | ||
| 537 | * | ||
| 538 | * Note: the TSC better not stop in C1, sched_clock() will | ||
| 539 | * skew otherwise. | ||
| 540 | */ | ||
| 541 | sleep_ticks = 0xFFFFFFFF; | ||
| 542 | |||
| 543 | break; | ||
| 544 | |||
| 545 | case ACPI_STATE_C2: | ||
| 546 | /* Get start time (ticks) */ | ||
| 547 | t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); | ||
| 548 | /* Tell the scheduler that we are going deep-idle: */ | ||
| 549 | sched_clock_idle_sleep_event(); | ||
| 550 | /* Invoke C2 */ | ||
| 551 | acpi_state_timer_broadcast(pr, cx, 1); | ||
| 552 | acpi_cstate_enter(cx); | ||
| 553 | /* Get end time (ticks) */ | ||
| 554 | t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); | ||
| 555 | |||
| 556 | #if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) | ||
| 557 | /* TSC halts in C2, so notify users */ | ||
| 558 | if (tsc_halts_in_c(ACPI_STATE_C2)) | ||
| 559 | mark_tsc_unstable("possible TSC halt in C2"); | ||
| 560 | #endif | ||
| 561 | /* Compute time (ticks) that we were actually asleep */ | ||
| 562 | sleep_ticks = ticks_elapsed(t1, t2); | ||
| 563 | |||
| 564 | /* Tell the scheduler how much we idled: */ | ||
| 565 | sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); | ||
| 566 | |||
| 567 | /* Re-enable interrupts */ | ||
| 568 | local_irq_enable(); | ||
| 569 | /* Do not account our idle-switching overhead: */ | ||
| 570 | sleep_ticks -= cx->latency_ticks + C2_OVERHEAD; | ||
| 571 | |||
| 572 | current_thread_info()->status |= TS_POLLING; | ||
| 573 | acpi_state_timer_broadcast(pr, cx, 0); | ||
| 574 | break; | ||
| 575 | |||
| 576 | case ACPI_STATE_C3: | ||
| 577 | acpi_unlazy_tlb(smp_processor_id()); | ||
| 578 | /* | ||
| 579 | * Must be done before busmaster disable as we might | ||
| 580 | * need to access HPET ! | ||
| 581 | */ | ||
| 582 | acpi_state_timer_broadcast(pr, cx, 1); | ||
| 583 | /* | ||
| 584 | * disable bus master | ||
| 585 | * bm_check implies we need ARB_DIS | ||
| 586 | * !bm_check implies we need cache flush | ||
| 587 | * bm_control implies whether we can do ARB_DIS | ||
| 588 | * | ||
| 589 | * That leaves a case where bm_check is set and bm_control is | ||
| 590 | * not set. In that case we cannot do much, we enter C3 | ||
| 591 | * without doing anything. | ||
| 592 | */ | ||
| 593 | if (pr->flags.bm_check && pr->flags.bm_control) { | ||
| 594 | if (atomic_inc_return(&c3_cpu_count) == | ||
| 595 | num_online_cpus()) { | ||
| 596 | /* | ||
| 597 | * All CPUs are trying to go to C3 | ||
| 598 | * Disable bus master arbitration | ||
| 599 | */ | ||
| 600 | acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); | ||
| 601 | } | ||
| 602 | } else if (!pr->flags.bm_check) { | ||
| 603 | /* SMP with no shared cache... Invalidate cache */ | ||
| 604 | ACPI_FLUSH_CPU_CACHE(); | ||
| 605 | } | ||
| 606 | |||
| 607 | /* Get start time (ticks) */ | ||
| 608 | t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); | ||
| 609 | /* Invoke C3 */ | ||
| 610 | /* Tell the scheduler that we are going deep-idle: */ | ||
| 611 | sched_clock_idle_sleep_event(); | ||
| 612 | acpi_cstate_enter(cx); | ||
| 613 | /* Get end time (ticks) */ | ||
| 614 | t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); | ||
| 615 | if (pr->flags.bm_check && pr->flags.bm_control) { | ||
| 616 | /* Enable bus master arbitration */ | ||
| 617 | atomic_dec(&c3_cpu_count); | ||
| 618 | acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); | ||
| 619 | } | ||
| 620 | |||
| 621 | #if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) | ||
| 622 | /* TSC halts in C3, so notify users */ | ||
| 623 | if (tsc_halts_in_c(ACPI_STATE_C3)) | ||
| 624 | mark_tsc_unstable("TSC halts in C3"); | ||
| 625 | #endif | ||
| 626 | /* Compute time (ticks) that we were actually asleep */ | ||
| 627 | sleep_ticks = ticks_elapsed(t1, t2); | ||
| 628 | /* Tell the scheduler how much we idled: */ | ||
| 629 | sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); | ||
| 630 | |||
| 631 | /* Re-enable interrupts */ | ||
| 632 | local_irq_enable(); | ||
| 633 | /* Do not account our idle-switching overhead: */ | ||
| 634 | sleep_ticks -= cx->latency_ticks + C3_OVERHEAD; | ||
| 635 | |||
| 636 | current_thread_info()->status |= TS_POLLING; | ||
| 637 | acpi_state_timer_broadcast(pr, cx, 0); | ||
| 638 | break; | ||
| 639 | |||
| 640 | default: | ||
| 641 | local_irq_enable(); | ||
| 642 | return; | ||
| 643 | } | ||
| 644 | cx->usage++; | ||
| 645 | if ((cx->type != ACPI_STATE_C1) && (sleep_ticks > 0)) | ||
| 646 | cx->time += sleep_ticks; | ||
| 647 | |||
| 648 | next_state = pr->power.state; | ||
| 649 | |||
| 650 | #ifdef CONFIG_HOTPLUG_CPU | ||
| 651 | /* Don't do promotion/demotion */ | ||
| 652 | if ((cx->type == ACPI_STATE_C1) && (num_online_cpus() > 1) && | ||
| 653 | !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) { | ||
| 654 | next_state = cx; | ||
| 655 | goto end; | ||
| 656 | } | ||
| 657 | #endif | ||
| 658 | |||
| 659 | /* | ||
| 660 | * Promotion? | ||
| 661 | * ---------- | ||
| 662 | * Track the number of longs (time asleep is greater than threshold) | ||
| 663 | * and promote when the count threshold is reached. Note that bus | ||
| 664 | * mastering activity may prevent promotions. | ||
| 665 | * Do not promote above max_cstate. | ||
| 666 | */ | ||
| 667 | if (cx->promotion.state && | ||
| 668 | ((cx->promotion.state - pr->power.states) <= max_cstate)) { | ||
| 669 | if (sleep_ticks > cx->promotion.threshold.ticks && | ||
| 670 | cx->promotion.state->latency <= | ||
| 671 | pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY)) { | ||
| 672 | cx->promotion.count++; | ||
| 673 | cx->demotion.count = 0; | ||
| 674 | if (cx->promotion.count >= | ||
| 675 | cx->promotion.threshold.count) { | ||
| 676 | if (pr->flags.bm_check) { | ||
| 677 | if (! | ||
| 678 | (pr->power.bm_activity & cx-> | ||
| 679 | promotion.threshold.bm)) { | ||
| 680 | next_state = | ||
| 681 | cx->promotion.state; | ||
| 682 | goto end; | ||
| 683 | } | ||
| 684 | } else { | ||
| 685 | next_state = cx->promotion.state; | ||
| 686 | goto end; | ||
| 687 | } | ||
| 688 | } | ||
| 689 | } | ||
| 690 | } | ||
| 691 | |||
| 692 | /* | ||
| 693 | * Demotion? | ||
| 694 | * --------- | ||
| 695 | * Track the number of shorts (time asleep is less than time threshold) | ||
| 696 | * and demote when the usage threshold is reached. | ||
| 697 | */ | ||
| 698 | if (cx->demotion.state) { | ||
| 699 | if (sleep_ticks < cx->demotion.threshold.ticks) { | ||
| 700 | cx->demotion.count++; | ||
| 701 | cx->promotion.count = 0; | ||
| 702 | if (cx->demotion.count >= cx->demotion.threshold.count) { | ||
| 703 | next_state = cx->demotion.state; | ||
| 704 | goto end; | ||
| 705 | } | ||
| 706 | } | ||
| 707 | } | ||
| 708 | |||
| 709 | end: | ||
| 710 | /* | ||
| 711 | * Demote if current state exceeds max_cstate | ||
| 712 | * or if the latency of the current state is unacceptable | ||
| 713 | */ | ||
| 714 | if ((pr->power.state - pr->power.states) > max_cstate || | ||
| 715 | pr->power.state->latency > | ||
| 716 | pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY)) { | ||
| 717 | if (cx->demotion.state) | ||
| 718 | next_state = cx->demotion.state; | ||
| 719 | } | ||
| 720 | |||
| 721 | /* | ||
| 722 | * New Cx State? | ||
| 723 | * ------------- | ||
| 724 | * If we're going to start using a new Cx state we must clean up | ||
| 725 | * from the previous and prepare to use the new. | ||
| 726 | */ | ||
| 727 | if (next_state != pr->power.state) | ||
| 728 | acpi_processor_power_activate(pr, next_state); | ||
| 729 | } | ||
| 730 | |||
| 731 | static int acpi_processor_set_power_policy(struct acpi_processor *pr) | ||
| 732 | { | ||
| 733 | unsigned int i; | ||
| 734 | unsigned int state_is_set = 0; | ||
| 735 | struct acpi_processor_cx *lower = NULL; | ||
| 736 | struct acpi_processor_cx *higher = NULL; | ||
| 737 | struct acpi_processor_cx *cx; | ||
| 738 | |||
| 739 | |||
| 740 | if (!pr) | ||
| 741 | return -EINVAL; | ||
| 742 | |||
| 743 | /* | ||
| 744 | * This function sets the default Cx state policy (OS idle handler). | ||
| 745 | * Our scheme is to promote quickly to C2 but more conservatively | ||
| 746 | * to C3. We're favoring C2 for its characteristics of low latency | ||
| 747 | * (quick response), good power savings, and ability to allow bus | ||
| 748 | * mastering activity. Note that the Cx state policy is completely | ||
| 749 | * customizable and can be altered dynamically. | ||
| 750 | */ | ||
| 751 | |||
| 752 | /* startup state */ | ||
| 753 | for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) { | ||
| 754 | cx = &pr->power.states[i]; | ||
| 755 | if (!cx->valid) | ||
| 756 | continue; | ||
| 757 | |||
| 758 | if (!state_is_set) | ||
| 759 | pr->power.state = cx; | ||
| 760 | state_is_set++; | ||
| 761 | break; | ||
| 762 | } | ||
| 763 | |||
| 764 | if (!state_is_set) | ||
| 765 | return -ENODEV; | ||
| 766 | |||
| 767 | /* demotion */ | ||
| 768 | for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) { | ||
| 769 | cx = &pr->power.states[i]; | ||
| 770 | if (!cx->valid) | ||
| 771 | continue; | ||
| 772 | |||
| 773 | if (lower) { | ||
| 774 | cx->demotion.state = lower; | ||
| 775 | cx->demotion.threshold.ticks = cx->latency_ticks; | ||
| 776 | cx->demotion.threshold.count = 1; | ||
| 777 | if (cx->type == ACPI_STATE_C3) | ||
| 778 | cx->demotion.threshold.bm = bm_history; | ||
| 779 | } | ||
| 780 | |||
| 781 | lower = cx; | ||
| 782 | } | ||
| 783 | |||
| 784 | /* promotion */ | ||
| 785 | for (i = (ACPI_PROCESSOR_MAX_POWER - 1); i > 0; i--) { | ||
| 786 | cx = &pr->power.states[i]; | ||
| 787 | if (!cx->valid) | ||
| 788 | continue; | ||
| 789 | |||
| 790 | if (higher) { | ||
| 791 | cx->promotion.state = higher; | ||
| 792 | cx->promotion.threshold.ticks = cx->latency_ticks; | ||
| 793 | if (cx->type >= ACPI_STATE_C2) | ||
| 794 | cx->promotion.threshold.count = 4; | ||
| 795 | else | ||
| 796 | cx->promotion.threshold.count = 10; | ||
| 797 | if (higher->type == ACPI_STATE_C3) | ||
| 798 | cx->promotion.threshold.bm = bm_history; | ||
| 799 | } | ||
| 800 | |||
| 801 | higher = cx; | ||
| 802 | } | ||
| 803 | |||
| 804 | return 0; | ||
| 805 | } | ||
| 806 | #endif /* !CONFIG_CPU_IDLE */ | ||
| 807 | |||
| 808 | static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) | 302 | static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) |
| 809 | { | 303 | { |
| 810 | 304 | ||
| @@ -1047,11 +541,7 @@ static void acpi_processor_power_verify_c2(struct acpi_processor_cx *cx) | |||
| 1047 | */ | 541 | */ |
| 1048 | cx->valid = 1; | 542 | cx->valid = 1; |
| 1049 | 543 | ||
| 1050 | #ifndef CONFIG_CPU_IDLE | ||
| 1051 | cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency); | ||
| 1052 | #else | ||
| 1053 | cx->latency_ticks = cx->latency; | 544 | cx->latency_ticks = cx->latency; |
| 1054 | #endif | ||
| 1055 | 545 | ||
| 1056 | return; | 546 | return; |
| 1057 | } | 547 | } |
| @@ -1121,7 +611,6 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr, | |||
| 1121 | " for C3 to be enabled on SMP systems\n")); | 611 | " for C3 to be enabled on SMP systems\n")); |
| 1122 | return; | 612 | return; |
| 1123 | } | 613 | } |
| 1124 | acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); | ||
| 1125 | } | 614 | } |
| 1126 | 615 | ||
| 1127 | /* | 616 | /* |
| @@ -1132,11 +621,16 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr, | |||
| 1132 | */ | 621 | */ |
| 1133 | cx->valid = 1; | 622 | cx->valid = 1; |
| 1134 | 623 | ||
| 1135 | #ifndef CONFIG_CPU_IDLE | ||
| 1136 | cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency); | ||
| 1137 | #else | ||
| 1138 | cx->latency_ticks = cx->latency; | 624 | cx->latency_ticks = cx->latency; |
| 1139 | #endif | 625 | /* |
| 626 | * On older chipsets, BM_RLD needs to be set | ||
| 627 | * in order for Bus Master activity to wake the | ||
| 628 | * system from C3. Newer chipsets handle DMA | ||
| 629 | * during C3 automatically and BM_RLD is a NOP. | ||
| 630 | * In either case, the proper way to | ||
| 631 | * handle BM_RLD is to set it and leave it set. | ||
| 632 | */ | ||
| 633 | acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1); | ||
| 1140 | 634 | ||
| 1141 | return; | 635 | return; |
| 1142 | } | 636 | } |
| @@ -1201,20 +695,6 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr) | |||
| 1201 | 695 | ||
| 1202 | pr->power.count = acpi_processor_power_verify(pr); | 696 | pr->power.count = acpi_processor_power_verify(pr); |
| 1203 | 697 | ||
| 1204 | #ifndef CONFIG_CPU_IDLE | ||
| 1205 | /* | ||
| 1206 | * Set Default Policy | ||
| 1207 | * ------------------ | ||
| 1208 | * Now that we know which states are supported, set the default | ||
| 1209 | * policy. Note that this policy can be changed dynamically | ||
| 1210 | * (e.g. encourage deeper sleeps to conserve battery life when | ||
| 1211 | * not on AC). | ||
| 1212 | */ | ||
| 1213 | result = acpi_processor_set_power_policy(pr); | ||
| 1214 | if (result) | ||
| 1215 | return result; | ||
| 1216 | #endif | ||
| 1217 | |||
| 1218 | /* | 698 | /* |
| 1219 | * if one state of type C2 or C3 is available, mark this | 699 | * if one state of type C2 or C3 is available, mark this |
| 1220 | * CPU as being "idle manageable" | 700 | * CPU as being "idle manageable" |
| @@ -1312,69 +792,6 @@ static const struct file_operations acpi_processor_power_fops = { | |||
| 1312 | .release = single_release, | 792 | .release = single_release, |
| 1313 | }; | 793 | }; |
| 1314 | 794 | ||
| 1315 | #ifndef CONFIG_CPU_IDLE | ||
| 1316 | |||
| 1317 | int acpi_processor_cst_has_changed(struct acpi_processor *pr) | ||
| 1318 | { | ||
| 1319 | int result = 0; | ||
| 1320 | |||
| 1321 | if (boot_option_idle_override) | ||
| 1322 | return 0; | ||
| 1323 | |||
| 1324 | if (!pr) | ||
| 1325 | return -EINVAL; | ||
| 1326 | |||
| 1327 | if (nocst) { | ||
| 1328 | return -ENODEV; | ||
| 1329 | } | ||
| 1330 | |||
| 1331 | if (!pr->flags.power_setup_done) | ||
| 1332 | return -ENODEV; | ||
| 1333 | |||
| 1334 | /* | ||
| 1335 | * Fall back to the default idle loop, when pm_idle_save had | ||
| 1336 | * been initialized. | ||
| 1337 | */ | ||
| 1338 | if (pm_idle_save) { | ||
| 1339 | pm_idle = pm_idle_save; | ||
| 1340 | /* Relies on interrupts forcing exit from idle. */ | ||
| 1341 | synchronize_sched(); | ||
| 1342 | } | ||
| 1343 | |||
| 1344 | pr->flags.power = 0; | ||
| 1345 | result = acpi_processor_get_power_info(pr); | ||
| 1346 | if ((pr->flags.power == 1) && (pr->flags.power_setup_done)) | ||
| 1347 | pm_idle = acpi_processor_idle; | ||
| 1348 | |||
| 1349 | return result; | ||
| 1350 | } | ||
| 1351 | |||
| 1352 | #ifdef CONFIG_SMP | ||
| 1353 | static void smp_callback(void *v) | ||
| 1354 | { | ||
| 1355 | /* we already woke the CPU up, nothing more to do */ | ||
| 1356 | } | ||
| 1357 | |||
| 1358 | /* | ||
| 1359 | * This function gets called when a part of the kernel has a new latency | ||
| 1360 | * requirement. This means we need to get all processors out of their C-state, | ||
| 1361 | * and then recalculate a new suitable C-state. Just do a cross-cpu IPI; that | ||
| 1362 | * wakes them all right up. | ||
| 1363 | */ | ||
| 1364 | static int acpi_processor_latency_notify(struct notifier_block *b, | ||
| 1365 | unsigned long l, void *v) | ||
| 1366 | { | ||
| 1367 | smp_call_function(smp_callback, NULL, 1); | ||
| 1368 | return NOTIFY_OK; | ||
| 1369 | } | ||
| 1370 | |||
| 1371 | static struct notifier_block acpi_processor_latency_notifier = { | ||
| 1372 | .notifier_call = acpi_processor_latency_notify, | ||
| 1373 | }; | ||
| 1374 | |||
| 1375 | #endif | ||
| 1376 | |||
| 1377 | #else /* CONFIG_CPU_IDLE */ | ||
| 1378 | 795 | ||
| 1379 | /** | 796 | /** |
| 1380 | * acpi_idle_bm_check - checks if bus master activity was detected | 797 | * acpi_idle_bm_check - checks if bus master activity was detected |
| @@ -1383,7 +800,7 @@ static int acpi_idle_bm_check(void) | |||
| 1383 | { | 800 | { |
| 1384 | u32 bm_status = 0; | 801 | u32 bm_status = 0; |
| 1385 | 802 | ||
| 1386 | acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status); | 803 | acpi_get_register_unlocked(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status); |
| 1387 | if (bm_status) | 804 | if (bm_status) |
| 1388 | acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1); | 805 | acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1); |
| 1389 | /* | 806 | /* |
| @@ -1400,25 +817,6 @@ static int acpi_idle_bm_check(void) | |||
| 1400 | } | 817 | } |
| 1401 | 818 | ||
| 1402 | /** | 819 | /** |
| 1403 | * acpi_idle_update_bm_rld - updates the BM_RLD bit depending on target state | ||
| 1404 | * @pr: the processor | ||
| 1405 | * @target: the new target state | ||
| 1406 | */ | ||
| 1407 | static inline void acpi_idle_update_bm_rld(struct acpi_processor *pr, | ||
| 1408 | struct acpi_processor_cx *target) | ||
| 1409 | { | ||
| 1410 | if (pr->flags.bm_rld_set && target->type != ACPI_STATE_C3) { | ||
| 1411 | acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); | ||
| 1412 | pr->flags.bm_rld_set = 0; | ||
| 1413 | } | ||
| 1414 | |||
| 1415 | if (!pr->flags.bm_rld_set && target->type == ACPI_STATE_C3) { | ||
| 1416 | acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1); | ||
| 1417 | pr->flags.bm_rld_set = 1; | ||
| 1418 | } | ||
| 1419 | } | ||
| 1420 | |||
| 1421 | /** | ||
| 1422 | * acpi_idle_do_entry - a helper function that does C2 and C3 type entry | 820 | * acpi_idle_do_entry - a helper function that does C2 and C3 type entry |
| 1423 | * @cx: cstate data | 821 | * @cx: cstate data |
| 1424 | * | 822 | * |
| @@ -1473,9 +871,6 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, | |||
| 1473 | return 0; | 871 | return 0; |
| 1474 | } | 872 | } |
| 1475 | 873 | ||
| 1476 | if (pr->flags.bm_check) | ||
| 1477 | acpi_idle_update_bm_rld(pr, cx); | ||
| 1478 | |||
| 1479 | t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); | 874 | t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); |
| 1480 | acpi_idle_do_entry(cx); | 875 | acpi_idle_do_entry(cx); |
| 1481 | t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); | 876 | t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); |
| @@ -1527,9 +922,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
| 1527 | */ | 922 | */ |
| 1528 | acpi_state_timer_broadcast(pr, cx, 1); | 923 | acpi_state_timer_broadcast(pr, cx, 1); |
| 1529 | 924 | ||
| 1530 | if (pr->flags.bm_check) | ||
| 1531 | acpi_idle_update_bm_rld(pr, cx); | ||
| 1532 | |||
| 1533 | if (cx->type == ACPI_STATE_C3) | 925 | if (cx->type == ACPI_STATE_C3) |
| 1534 | ACPI_FLUSH_CPU_CACHE(); | 926 | ACPI_FLUSH_CPU_CACHE(); |
| 1535 | 927 | ||
| @@ -1621,8 +1013,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
| 1621 | */ | 1013 | */ |
| 1622 | acpi_state_timer_broadcast(pr, cx, 1); | 1014 | acpi_state_timer_broadcast(pr, cx, 1); |
| 1623 | 1015 | ||
| 1624 | acpi_idle_update_bm_rld(pr, cx); | ||
| 1625 | |||
| 1626 | /* | 1016 | /* |
| 1627 | * disable bus master | 1017 | * disable bus master |
| 1628 | * bm_check implies we need ARB_DIS | 1018 | * bm_check implies we need ARB_DIS |
| @@ -1795,8 +1185,6 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr) | |||
| 1795 | return ret; | 1185 | return ret; |
| 1796 | } | 1186 | } |
| 1797 | 1187 | ||
| 1798 | #endif /* CONFIG_CPU_IDLE */ | ||
| 1799 | |||
| 1800 | int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, | 1188 | int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, |
| 1801 | struct acpi_device *device) | 1189 | struct acpi_device *device) |
| 1802 | { | 1190 | { |
| @@ -1825,10 +1213,6 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, | |||
| 1825 | "ACPI: processor limited to max C-state %d\n", | 1213 | "ACPI: processor limited to max C-state %d\n", |
| 1826 | max_cstate); | 1214 | max_cstate); |
| 1827 | first_run++; | 1215 | first_run++; |
| 1828 | #if !defined(CONFIG_CPU_IDLE) && defined(CONFIG_SMP) | ||
| 1829 | pm_qos_add_notifier(PM_QOS_CPU_DMA_LATENCY, | ||
| 1830 | &acpi_processor_latency_notifier); | ||
| 1831 | #endif | ||
| 1832 | } | 1216 | } |
| 1833 | 1217 | ||
| 1834 | if (!pr) | 1218 | if (!pr) |
| @@ -1852,11 +1236,9 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, | |||
| 1852 | * platforms that only support C1. | 1236 | * platforms that only support C1. |
| 1853 | */ | 1237 | */ |
| 1854 | if (pr->flags.power) { | 1238 | if (pr->flags.power) { |
| 1855 | #ifdef CONFIG_CPU_IDLE | ||
| 1856 | acpi_processor_setup_cpuidle(pr); | 1239 | acpi_processor_setup_cpuidle(pr); |
| 1857 | if (cpuidle_register_device(&pr->power.dev)) | 1240 | if (cpuidle_register_device(&pr->power.dev)) |
| 1858 | return -EIO; | 1241 | return -EIO; |
| 1859 | #endif | ||
| 1860 | 1242 | ||
| 1861 | printk(KERN_INFO PREFIX "CPU%d (power states:", pr->id); | 1243 | printk(KERN_INFO PREFIX "CPU%d (power states:", pr->id); |
| 1862 | for (i = 1; i <= pr->power.count; i++) | 1244 | for (i = 1; i <= pr->power.count; i++) |
| @@ -1864,13 +1246,6 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, | |||
| 1864 | printk(" C%d[C%d]", i, | 1246 | printk(" C%d[C%d]", i, |
| 1865 | pr->power.states[i].type); | 1247 | pr->power.states[i].type); |
| 1866 | printk(")\n"); | 1248 | printk(")\n"); |
| 1867 | |||
| 1868 | #ifndef CONFIG_CPU_IDLE | ||
| 1869 | if (pr->id == 0) { | ||
| 1870 | pm_idle_save = pm_idle; | ||
| 1871 | pm_idle = acpi_processor_idle; | ||
| 1872 | } | ||
| 1873 | #endif | ||
| 1874 | } | 1249 | } |
| 1875 | 1250 | ||
| 1876 | /* 'power' [R] */ | 1251 | /* 'power' [R] */ |
| @@ -1889,34 +1264,12 @@ int acpi_processor_power_exit(struct acpi_processor *pr, | |||
| 1889 | if (boot_option_idle_override) | 1264 | if (boot_option_idle_override) |
| 1890 | return 0; | 1265 | return 0; |
| 1891 | 1266 | ||
| 1892 | #ifdef CONFIG_CPU_IDLE | ||
| 1893 | cpuidle_unregister_device(&pr->power.dev); | 1267 | cpuidle_unregister_device(&pr->power.dev); |
| 1894 | #endif | ||
| 1895 | pr->flags.power_setup_done = 0; | 1268 | pr->flags.power_setup_done = 0; |
| 1896 | 1269 | ||
| 1897 | if (acpi_device_dir(device)) | 1270 | if (acpi_device_dir(device)) |
| 1898 | remove_proc_entry(ACPI_PROCESSOR_FILE_POWER, | 1271 | remove_proc_entry(ACPI_PROCESSOR_FILE_POWER, |
| 1899 | acpi_device_dir(device)); | 1272 | acpi_device_dir(device)); |
| 1900 | 1273 | ||
| 1901 | #ifndef CONFIG_CPU_IDLE | ||
| 1902 | |||
| 1903 | /* Unregister the idle handler when processor #0 is removed. */ | ||
| 1904 | if (pr->id == 0) { | ||
| 1905 | if (pm_idle_save) | ||
| 1906 | pm_idle = pm_idle_save; | ||
| 1907 | |||
| 1908 | /* | ||
| 1909 | * We are about to unload the current idle thread pm callback | ||
| 1910 | * (pm_idle), Wait for all processors to update cached/local | ||
| 1911 | * copies of pm_idle before proceeding. | ||
| 1912 | */ | ||
| 1913 | cpu_idle_wait(); | ||
| 1914 | #ifdef CONFIG_SMP | ||
| 1915 | pm_qos_remove_notifier(PM_QOS_CPU_DMA_LATENCY, | ||
| 1916 | &acpi_processor_latency_notifier); | ||
| 1917 | #endif | ||
| 1918 | } | ||
| 1919 | #endif | ||
| 1920 | |||
| 1921 | return 0; | 1274 | return 0; |
| 1922 | } | 1275 | } |
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 846e227592d4..9cc769b587ff 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
| @@ -31,14 +31,6 @@ | |||
| 31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
| 32 | #include <linux/cpufreq.h> | 32 | #include <linux/cpufreq.h> |
| 33 | 33 | ||
| 34 | #ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF | ||
| 35 | #include <linux/proc_fs.h> | ||
| 36 | #include <linux/seq_file.h> | ||
| 37 | #include <linux/mutex.h> | ||
| 38 | |||
| 39 | #include <asm/uaccess.h> | ||
| 40 | #endif | ||
| 41 | |||
| 42 | #ifdef CONFIG_X86 | 34 | #ifdef CONFIG_X86 |
| 43 | #include <asm/cpufeature.h> | 35 | #include <asm/cpufeature.h> |
| 44 | #endif | 36 | #endif |
| @@ -434,96 +426,6 @@ int acpi_processor_notify_smm(struct module *calling_module) | |||
| 434 | 426 | ||
| 435 | EXPORT_SYMBOL(acpi_processor_notify_smm); | 427 | EXPORT_SYMBOL(acpi_processor_notify_smm); |
| 436 | 428 | ||
| 437 | #ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF | ||
| 438 | /* /proc/acpi/processor/../performance interface (DEPRECATED) */ | ||
| 439 | |||
| 440 | static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file); | ||
| 441 | static struct file_operations acpi_processor_perf_fops = { | ||
| 442 | .owner = THIS_MODULE, | ||
| 443 | .open = acpi_processor_perf_open_fs, | ||
| 444 | .read = seq_read, | ||
| 445 | .llseek = seq_lseek, | ||
| 446 | .release = single_release, | ||
| 447 | }; | ||
| 448 | |||
| 449 | static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset) | ||
| 450 | { | ||
| 451 | struct acpi_processor *pr = seq->private; | ||
| 452 | int i; | ||
| 453 | |||
| 454 | |||
| 455 | if (!pr) | ||
| 456 | goto end; | ||
| 457 | |||
| 458 | if (!pr->performance) { | ||
| 459 | seq_puts(seq, "<not supported>\n"); | ||
| 460 | goto end; | ||
| 461 | } | ||
| 462 | |||
| 463 | seq_printf(seq, "state count: %d\n" | ||
| 464 | "active state: P%d\n", | ||
| 465 | pr->performance->state_count, pr->performance->state); | ||
| 466 | |||
| 467 | seq_puts(seq, "states:\n"); | ||
| 468 | for (i = 0; i < pr->performance->state_count; i++) | ||
| 469 | seq_printf(seq, | ||
| 470 | " %cP%d: %d MHz, %d mW, %d uS\n", | ||
| 471 | (i == pr->performance->state ? '*' : ' '), i, | ||
| 472 | (u32) pr->performance->states[i].core_frequency, | ||
| 473 | (u32) pr->performance->states[i].power, | ||
| 474 | (u32) pr->performance->states[i].transition_latency); | ||
| 475 | |||
| 476 | end: | ||
| 477 | return 0; | ||
| 478 | } | ||
| 479 | |||
| 480 | static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file) | ||
| 481 | { | ||
| 482 | return single_open(file, acpi_processor_perf_seq_show, | ||
| 483 | PDE(inode)->data); | ||
| 484 | } | ||
| 485 | |||
| 486 | static void acpi_cpufreq_add_file(struct acpi_processor *pr) | ||
| 487 | { | ||
| 488 | struct acpi_device *device = NULL; | ||
| 489 | |||
| 490 | |||
| 491 | if (acpi_bus_get_device(pr->handle, &device)) | ||
| 492 | return; | ||
| 493 | |||
| 494 | /* add file 'performance' [R/W] */ | ||
| 495 | proc_create_data(ACPI_PROCESSOR_FILE_PERFORMANCE, S_IFREG | S_IRUGO, | ||
| 496 | acpi_device_dir(device), | ||
| 497 | &acpi_processor_perf_fops, acpi_driver_data(device)); | ||
| 498 | return; | ||
| 499 | } | ||
| 500 | |||
| 501 | static void acpi_cpufreq_remove_file(struct acpi_processor *pr) | ||
| 502 | { | ||
| 503 | struct acpi_device *device = NULL; | ||
| 504 | |||
| 505 | |||
| 506 | if (acpi_bus_get_device(pr->handle, &device)) | ||
| 507 | return; | ||
| 508 | |||
| 509 | /* remove file 'performance' */ | ||
| 510 | remove_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE, | ||
| 511 | acpi_device_dir(device)); | ||
| 512 | |||
| 513 | return; | ||
| 514 | } | ||
| 515 | |||
| 516 | #else | ||
| 517 | static void acpi_cpufreq_add_file(struct acpi_processor *pr) | ||
| 518 | { | ||
| 519 | return; | ||
| 520 | } | ||
| 521 | static void acpi_cpufreq_remove_file(struct acpi_processor *pr) | ||
| 522 | { | ||
| 523 | return; | ||
| 524 | } | ||
| 525 | #endif /* CONFIG_X86_ACPI_CPUFREQ_PROC_INTF */ | ||
| 526 | |||
| 527 | static int acpi_processor_get_psd(struct acpi_processor *pr) | 429 | static int acpi_processor_get_psd(struct acpi_processor *pr) |
| 528 | { | 430 | { |
| 529 | int result = 0; | 431 | int result = 0; |
| @@ -747,14 +649,12 @@ err_ret: | |||
| 747 | } | 649 | } |
| 748 | EXPORT_SYMBOL(acpi_processor_preregister_performance); | 650 | EXPORT_SYMBOL(acpi_processor_preregister_performance); |
| 749 | 651 | ||
| 750 | |||
| 751 | int | 652 | int |
| 752 | acpi_processor_register_performance(struct acpi_processor_performance | 653 | acpi_processor_register_performance(struct acpi_processor_performance |
| 753 | *performance, unsigned int cpu) | 654 | *performance, unsigned int cpu) |
| 754 | { | 655 | { |
| 755 | struct acpi_processor *pr; | 656 | struct acpi_processor *pr; |
| 756 | 657 | ||
| 757 | |||
| 758 | if (!(acpi_processor_ppc_status & PPC_REGISTERED)) | 658 | if (!(acpi_processor_ppc_status & PPC_REGISTERED)) |
| 759 | return -EINVAL; | 659 | return -EINVAL; |
| 760 | 660 | ||
| @@ -781,8 +681,6 @@ acpi_processor_register_performance(struct acpi_processor_performance | |||
| 781 | return -EIO; | 681 | return -EIO; |
| 782 | } | 682 | } |
| 783 | 683 | ||
| 784 | acpi_cpufreq_add_file(pr); | ||
| 785 | |||
| 786 | mutex_unlock(&performance_mutex); | 684 | mutex_unlock(&performance_mutex); |
| 787 | return 0; | 685 | return 0; |
| 788 | } | 686 | } |
| @@ -795,7 +693,6 @@ acpi_processor_unregister_performance(struct acpi_processor_performance | |||
| 795 | { | 693 | { |
| 796 | struct acpi_processor *pr; | 694 | struct acpi_processor *pr; |
| 797 | 695 | ||
| 798 | |||
| 799 | mutex_lock(&performance_mutex); | 696 | mutex_lock(&performance_mutex); |
| 800 | 697 | ||
| 801 | pr = per_cpu(processors, cpu); | 698 | pr = per_cpu(processors, cpu); |
| @@ -808,8 +705,6 @@ acpi_processor_unregister_performance(struct acpi_processor_performance | |||
| 808 | kfree(pr->performance->states); | 705 | kfree(pr->performance->states); |
| 809 | pr->performance = NULL; | 706 | pr->performance = NULL; |
| 810 | 707 | ||
| 811 | acpi_cpufreq_remove_file(pr); | ||
| 812 | |||
| 813 | mutex_unlock(&performance_mutex); | 708 | mutex_unlock(&performance_mutex); |
| 814 | 709 | ||
| 815 | return; | 710 | return; |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 7e3c609cbef2..519266654f06 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
| @@ -90,31 +90,6 @@ void __init acpi_old_suspend_ordering(void) | |||
| 90 | old_suspend_ordering = true; | 90 | old_suspend_ordering = true; |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | /* | ||
| 94 | * According to the ACPI specification the BIOS should make sure that ACPI is | ||
| 95 | * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still, | ||
| 96 | * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI | ||
| 97 | * on such systems during resume. Unfortunately that doesn't help in | ||
| 98 | * particularly pathological cases in which SCI_EN has to be set directly on | ||
| 99 | * resume, although the specification states very clearly that this flag is | ||
| 100 | * owned by the hardware. The set_sci_en_on_resume variable will be set in such | ||
| 101 | * cases. | ||
| 102 | */ | ||
| 103 | static bool set_sci_en_on_resume; | ||
| 104 | /* | ||
| 105 | * The ACPI specification wants us to save NVS memory regions during hibernation | ||
| 106 | * and to restore them during the subsequent resume. However, it is not certain | ||
| 107 | * if this mechanism is going to work on all machines, so we allow the user to | ||
| 108 | * disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line | ||
| 109 | * option. | ||
| 110 | */ | ||
| 111 | static bool s4_no_nvs; | ||
| 112 | |||
| 113 | void __init acpi_s4_no_nvs(void) | ||
| 114 | { | ||
| 115 | s4_no_nvs = true; | ||
| 116 | } | ||
| 117 | |||
| 118 | /** | 93 | /** |
| 119 | * acpi_pm_disable_gpes - Disable the GPEs. | 94 | * acpi_pm_disable_gpes - Disable the GPEs. |
| 120 | */ | 95 | */ |
| @@ -193,6 +168,18 @@ static void acpi_pm_end(void) | |||
| 193 | #endif /* CONFIG_ACPI_SLEEP */ | 168 | #endif /* CONFIG_ACPI_SLEEP */ |
| 194 | 169 | ||
| 195 | #ifdef CONFIG_SUSPEND | 170 | #ifdef CONFIG_SUSPEND |
| 171 | /* | ||
| 172 | * According to the ACPI specification the BIOS should make sure that ACPI is | ||
| 173 | * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still, | ||
| 174 | * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI | ||
| 175 | * on such systems during resume. Unfortunately that doesn't help in | ||
| 176 | * particularly pathological cases in which SCI_EN has to be set directly on | ||
| 177 | * resume, although the specification states very clearly that this flag is | ||
| 178 | * owned by the hardware. The set_sci_en_on_resume variable will be set in such | ||
| 179 | * cases. | ||
| 180 | */ | ||
| 181 | static bool set_sci_en_on_resume; | ||
| 182 | |||
| 196 | extern void do_suspend_lowlevel(void); | 183 | extern void do_suspend_lowlevel(void); |
| 197 | 184 | ||
| 198 | static u32 acpi_suspend_states[] = { | 185 | static u32 acpi_suspend_states[] = { |
| @@ -396,6 +383,20 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
| 396 | #endif /* CONFIG_SUSPEND */ | 383 | #endif /* CONFIG_SUSPEND */ |
| 397 | 384 | ||
| 398 | #ifdef CONFIG_HIBERNATION | 385 | #ifdef CONFIG_HIBERNATION |
| 386 | /* | ||
| 387 | * The ACPI specification wants us to save NVS memory regions during hibernation | ||
| 388 | * and to restore them during the subsequent resume. However, it is not certain | ||
| 389 | * if this mechanism is going to work on all machines, so we allow the user to | ||
| 390 | * disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line | ||
| 391 | * option. | ||
| 392 | */ | ||
| 393 | static bool s4_no_nvs; | ||
| 394 | |||
| 395 | void __init acpi_s4_no_nvs(void) | ||
| 396 | { | ||
| 397 | s4_no_nvs = true; | ||
| 398 | } | ||
| 399 | |||
| 399 | static unsigned long s4_hardware_signature; | 400 | static unsigned long s4_hardware_signature; |
| 400 | static struct acpi_table_facs *facs; | 401 | static struct acpi_table_facs *facs; |
| 401 | static bool nosigcheck; | 402 | static bool nosigcheck; |
| @@ -679,7 +680,7 @@ static void acpi_power_off_prepare(void) | |||
| 679 | static void acpi_power_off(void) | 680 | static void acpi_power_off(void) |
| 680 | { | 681 | { |
| 681 | /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ | 682 | /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ |
| 682 | printk("%s called\n", __func__); | 683 | printk(KERN_DEBUG "%s called\n", __func__); |
| 683 | local_irq_disable(); | 684 | local_irq_disable(); |
| 684 | acpi_enable_wakeup_device(ACPI_STATE_S5); | 685 | acpi_enable_wakeup_device(ACPI_STATE_S5); |
| 685 | acpi_enter_sleep_state(ACPI_STATE_S5); | 686 | acpi_enter_sleep_state(ACPI_STATE_S5); |
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 775c97a282bd..a8852952fac4 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c | |||
| @@ -293,7 +293,12 @@ static void __init check_multiple_madt(void) | |||
| 293 | 293 | ||
| 294 | int __init acpi_table_init(void) | 294 | int __init acpi_table_init(void) |
| 295 | { | 295 | { |
| 296 | acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); | 296 | acpi_status status; |
| 297 | |||
| 298 | status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); | ||
| 299 | if (ACPI_FAILURE(status)) | ||
| 300 | return 1; | ||
| 301 | |||
| 297 | check_multiple_madt(); | 302 | check_multiple_madt(); |
| 298 | return 0; | 303 | return 0; |
| 299 | } | 304 | } |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index f261737636da..bb5ed059114a 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
| @@ -1020,7 +1020,7 @@ acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset) | |||
| 1020 | } | 1020 | } |
| 1021 | 1021 | ||
| 1022 | seq_printf(seq, "levels: "); | 1022 | seq_printf(seq, "levels: "); |
| 1023 | for (i = 0; i < dev->brightness->count; i++) | 1023 | for (i = 2; i < dev->brightness->count; i++) |
| 1024 | seq_printf(seq, " %d", dev->brightness->levels[i]); | 1024 | seq_printf(seq, " %d", dev->brightness->levels[i]); |
| 1025 | seq_printf(seq, "\ncurrent: %d\n", dev->brightness->curr); | 1025 | seq_printf(seq, "\ncurrent: %d\n", dev->brightness->curr); |
| 1026 | 1026 | ||
| @@ -1059,7 +1059,7 @@ acpi_video_device_write_brightness(struct file *file, | |||
| 1059 | return -EFAULT; | 1059 | return -EFAULT; |
| 1060 | 1060 | ||
| 1061 | /* validate through the list of available levels */ | 1061 | /* validate through the list of available levels */ |
| 1062 | for (i = 0; i < dev->brightness->count; i++) | 1062 | for (i = 2; i < dev->brightness->count; i++) |
| 1063 | if (level == dev->brightness->levels[i]) { | 1063 | if (level == dev->brightness->levels[i]) { |
| 1064 | if (ACPI_SUCCESS | 1064 | if (ACPI_SUCCESS |
| 1065 | (acpi_video_device_lcd_set_level(dev, level))) | 1065 | (acpi_video_device_lcd_set_level(dev, level))) |
| @@ -1260,7 +1260,7 @@ static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset) | |||
| 1260 | printk(KERN_WARNING PREFIX | 1260 | printk(KERN_WARNING PREFIX |
| 1261 | "This indicates a BIOS bug. Please contact the manufacturer.\n"); | 1261 | "This indicates a BIOS bug. Please contact the manufacturer.\n"); |
| 1262 | } | 1262 | } |
| 1263 | printk("%llx\n", options); | 1263 | printk(KERN_WARNING "%llx\n", options); |
| 1264 | seq_printf(seq, "can POST: <integrated video>"); | 1264 | seq_printf(seq, "can POST: <integrated video>"); |
| 1265 | if (options & 2) | 1265 | if (options & 2) |
| 1266 | seq_printf(seq, " <PCI video>"); | 1266 | seq_printf(seq, " <PCI video>"); |
| @@ -1712,7 +1712,7 @@ acpi_video_get_next_level(struct acpi_video_device *device, | |||
| 1712 | max = max_below = 0; | 1712 | max = max_below = 0; |
| 1713 | min = min_above = 255; | 1713 | min = min_above = 255; |
| 1714 | /* Find closest level to level_current */ | 1714 | /* Find closest level to level_current */ |
| 1715 | for (i = 0; i < device->brightness->count; i++) { | 1715 | for (i = 2; i < device->brightness->count; i++) { |
| 1716 | l = device->brightness->levels[i]; | 1716 | l = device->brightness->levels[i]; |
| 1717 | if (abs(l - level_current) < abs(delta)) { | 1717 | if (abs(l - level_current) < abs(delta)) { |
| 1718 | delta = l - level_current; | 1718 | delta = l - level_current; |
| @@ -1722,7 +1722,7 @@ acpi_video_get_next_level(struct acpi_video_device *device, | |||
| 1722 | } | 1722 | } |
| 1723 | /* Ajust level_current to closest available level */ | 1723 | /* Ajust level_current to closest available level */ |
| 1724 | level_current += delta; | 1724 | level_current += delta; |
| 1725 | for (i = 0; i < device->brightness->count; i++) { | 1725 | for (i = 2; i < device->brightness->count; i++) { |
| 1726 | l = device->brightness->levels[i]; | 1726 | l = device->brightness->levels[i]; |
| 1727 | if (l < min) | 1727 | if (l < min) |
| 1728 | min = l; | 1728 | min = l; |
| @@ -2006,6 +2006,12 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
| 2006 | device->pnp.bus_id[3] = '0' + instance; | 2006 | device->pnp.bus_id[3] = '0' + instance; |
| 2007 | instance ++; | 2007 | instance ++; |
| 2008 | } | 2008 | } |
| 2009 | /* a hack to fix the duplicate name "VGA" problem on Pa 3553 */ | ||
| 2010 | if (!strcmp(device->pnp.bus_id, "VGA")) { | ||
| 2011 | if (instance) | ||
| 2012 | device->pnp.bus_id[3] = '0' + instance; | ||
| 2013 | instance++; | ||
| 2014 | } | ||
| 2009 | 2015 | ||
| 2010 | video->device = device; | 2016 | video->device = device; |
| 2011 | strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); | 2017 | strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); |
diff --git a/drivers/char/sx.c b/drivers/char/sx.c index b60be7b0decf..f146e90404fa 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c | |||
| @@ -1713,8 +1713,8 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd, | |||
| 1713 | for (i = 0; i < SX_NBOARDS; i++) | 1713 | for (i = 0; i < SX_NBOARDS; i++) |
| 1714 | sx_dprintk(SX_DEBUG_FIRMWARE, "<%x> ", boards[i].flags); | 1714 | sx_dprintk(SX_DEBUG_FIRMWARE, "<%x> ", boards[i].flags); |
| 1715 | sx_dprintk(SX_DEBUG_FIRMWARE, "\n"); | 1715 | sx_dprintk(SX_DEBUG_FIRMWARE, "\n"); |
| 1716 | unlock_kernel(); | 1716 | rc = -EIO; |
| 1717 | return -EIO; | 1717 | goto out; |
| 1718 | } | 1718 | } |
| 1719 | 1719 | ||
| 1720 | switch (cmd) { | 1720 | switch (cmd) { |
| @@ -1747,7 +1747,8 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd, | |||
| 1747 | break; | 1747 | break; |
| 1748 | case SXIO_DO_RAMTEST: | 1748 | case SXIO_DO_RAMTEST: |
| 1749 | if (sx_initialized) /* Already initialized: better not ramtest the board. */ | 1749 | if (sx_initialized) /* Already initialized: better not ramtest the board. */ |
| 1750 | return -EPERM; | 1750 | rc = -EPERM; |
| 1751 | break; | ||
| 1751 | if (IS_SX_BOARD(board)) { | 1752 | if (IS_SX_BOARD(board)) { |
| 1752 | rc = do_memtest(board, 0, 0x7000); | 1753 | rc = do_memtest(board, 0, 0x7000); |
| 1753 | if (!rc) | 1754 | if (!rc) |
| @@ -1844,6 +1845,7 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd, | |||
| 1844 | rc = -ENOTTY; | 1845 | rc = -ENOTTY; |
| 1845 | break; | 1846 | break; |
| 1846 | } | 1847 | } |
| 1848 | out: | ||
| 1847 | unlock_kernel(); | 1849 | unlock_kernel(); |
| 1848 | func_exit(); | 1850 | func_exit(); |
| 1849 | return rc; | 1851 | return rc; |
diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c index 7be2cf3514e7..a5dd7a665aa8 100644 --- a/drivers/firewire/fw-card.c +++ b/drivers/firewire/fw-card.c | |||
| @@ -412,6 +412,7 @@ fw_card_add(struct fw_card *card, | |||
| 412 | { | 412 | { |
| 413 | u32 *config_rom; | 413 | u32 *config_rom; |
| 414 | size_t length; | 414 | size_t length; |
| 415 | int err; | ||
| 415 | 416 | ||
| 416 | card->max_receive = max_receive; | 417 | card->max_receive = max_receive; |
| 417 | card->link_speed = link_speed; | 418 | card->link_speed = link_speed; |
| @@ -422,7 +423,13 @@ fw_card_add(struct fw_card *card, | |||
| 422 | list_add_tail(&card->link, &card_list); | 423 | list_add_tail(&card->link, &card_list); |
| 423 | mutex_unlock(&card_mutex); | 424 | mutex_unlock(&card_mutex); |
| 424 | 425 | ||
| 425 | return card->driver->enable(card, config_rom, length); | 426 | err = card->driver->enable(card, config_rom, length); |
| 427 | if (err < 0) { | ||
| 428 | mutex_lock(&card_mutex); | ||
| 429 | list_del(&card->link); | ||
| 430 | mutex_unlock(&card_mutex); | ||
| 431 | } | ||
| 432 | return err; | ||
| 426 | } | 433 | } |
| 427 | EXPORT_SYMBOL(fw_card_add); | 434 | EXPORT_SYMBOL(fw_card_add); |
| 428 | 435 | ||
diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c index 03705240000f..abf4dfc8ec22 100644 --- a/drivers/hwmon/hp_accel.c +++ b/drivers/hwmon/hp_accel.c | |||
| @@ -153,7 +153,10 @@ static struct axis_conversion lis3lv02d_axis_y_inverted = {1, -2, 3}; | |||
| 153 | static struct axis_conversion lis3lv02d_axis_x_inverted = {-1, 2, 3}; | 153 | static struct axis_conversion lis3lv02d_axis_x_inverted = {-1, 2, 3}; |
| 154 | static struct axis_conversion lis3lv02d_axis_z_inverted = {1, 2, -3}; | 154 | static struct axis_conversion lis3lv02d_axis_z_inverted = {1, 2, -3}; |
| 155 | static struct axis_conversion lis3lv02d_axis_xy_rotated_left = {-2, 1, 3}; | 155 | static struct axis_conversion lis3lv02d_axis_xy_rotated_left = {-2, 1, 3}; |
| 156 | static struct axis_conversion lis3lv02d_axis_xy_rotated_left_usd = {-2, 1, -3}; | ||
| 156 | static struct axis_conversion lis3lv02d_axis_xy_swap_inverted = {-2, -1, 3}; | 157 | static struct axis_conversion lis3lv02d_axis_xy_swap_inverted = {-2, -1, 3}; |
| 158 | static struct axis_conversion lis3lv02d_axis_xy_rotated_right = {2, -1, 3}; | ||
| 159 | static struct axis_conversion lis3lv02d_axis_xy_swap_yz_inverted = {2, -1, -3}; | ||
| 157 | 160 | ||
| 158 | #define AXIS_DMI_MATCH(_ident, _name, _axis) { \ | 161 | #define AXIS_DMI_MATCH(_ident, _name, _axis) { \ |
| 159 | .ident = _ident, \ | 162 | .ident = _ident, \ |
| @@ -172,10 +175,12 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = { | |||
| 172 | AXIS_DMI_MATCH("NC2510", "HP Compaq 2510", y_inverted), | 175 | AXIS_DMI_MATCH("NC2510", "HP Compaq 2510", y_inverted), |
| 173 | AXIS_DMI_MATCH("NC8510", "HP Compaq 8510", xy_swap_inverted), | 176 | AXIS_DMI_MATCH("NC8510", "HP Compaq 8510", xy_swap_inverted), |
| 174 | AXIS_DMI_MATCH("HP2133", "HP 2133", xy_rotated_left), | 177 | AXIS_DMI_MATCH("HP2133", "HP 2133", xy_rotated_left), |
| 178 | AXIS_DMI_MATCH("NC653x", "HP Compaq 653", xy_rotated_left_usd), | ||
| 179 | AXIS_DMI_MATCH("NC673x", "HP Compaq 673", xy_rotated_left_usd), | ||
| 180 | AXIS_DMI_MATCH("NC651xx", "HP Compaq 651", xy_rotated_right), | ||
| 181 | AXIS_DMI_MATCH("NC671xx", "HP Compaq 671", xy_swap_yz_inverted), | ||
| 175 | { NULL, } | 182 | { NULL, } |
| 176 | /* Laptop models without axis info (yet): | 183 | /* Laptop models without axis info (yet): |
| 177 | * "NC651xx" "HP Compaq 651" | ||
| 178 | * "NC671xx" "HP Compaq 671" | ||
| 179 | * "NC6910" "HP Compaq 6910" | 184 | * "NC6910" "HP Compaq 6910" |
| 180 | * HP Compaq 8710x Notebook PC / Mobile Workstation | 185 | * HP Compaq 8710x Notebook PC / Mobile Workstation |
| 181 | * "NC2400" "HP Compaq nc2400" | 186 | * "NC2400" "HP Compaq nc2400" |
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c index a329e6bd5d2d..3838bc4acaba 100644 --- a/drivers/ieee1394/dv1394.c +++ b/drivers/ieee1394/dv1394.c | |||
| @@ -1823,6 +1823,10 @@ static int dv1394_open(struct inode *inode, struct file *file) | |||
| 1823 | 1823 | ||
| 1824 | #endif | 1824 | #endif |
| 1825 | 1825 | ||
| 1826 | printk(KERN_INFO "%s: NOTE, the dv1394 interface is unsupported " | ||
| 1827 | "and will not be available in the new firewire driver stack. " | ||
| 1828 | "Try libraw1394 based programs instead.\n", current->comm); | ||
| 1829 | |||
| 1826 | return 0; | 1830 | return 0; |
| 1827 | } | 1831 | } |
| 1828 | 1832 | ||
| @@ -2567,10 +2571,6 @@ static int __init dv1394_init_module(void) | |||
| 2567 | { | 2571 | { |
| 2568 | int ret; | 2572 | int ret; |
| 2569 | 2573 | ||
| 2570 | printk(KERN_WARNING | ||
| 2571 | "NOTE: The dv1394 driver is unsupported and may be removed in a " | ||
| 2572 | "future Linux release. Use raw1394 instead.\n"); | ||
| 2573 | |||
| 2574 | cdev_init(&dv1394_cdev, &dv1394_fops); | 2574 | cdev_init(&dv1394_cdev, &dv1394_fops); |
| 2575 | dv1394_cdev.owner = THIS_MODULE; | 2575 | dv1394_cdev.owner = THIS_MODULE; |
| 2576 | ret = cdev_add(&dv1394_cdev, IEEE1394_DV1394_DEV, 16); | 2576 | ret = cdev_add(&dv1394_cdev, IEEE1394_DV1394_DEV, 16); |
diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 1e3aea9eecf1..09658b218474 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c | |||
| @@ -25,13 +25,13 @@ static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector) | |||
| 25 | { | 25 | { |
| 26 | dev_info_t *hash; | 26 | dev_info_t *hash; |
| 27 | linear_conf_t *conf = mddev_to_conf(mddev); | 27 | linear_conf_t *conf = mddev_to_conf(mddev); |
| 28 | sector_t idx = sector >> conf->sector_shift; | ||
| 28 | 29 | ||
| 29 | /* | 30 | /* |
| 30 | * sector_div(a,b) returns the remainer and sets a to a/b | 31 | * sector_div(a,b) returns the remainer and sets a to a/b |
| 31 | */ | 32 | */ |
| 32 | sector >>= conf->sector_shift; | 33 | (void)sector_div(idx, conf->spacing); |
| 33 | (void)sector_div(sector, conf->spacing); | 34 | hash = conf->hash_table[idx]; |
| 34 | hash = conf->hash_table[sector]; | ||
| 35 | 35 | ||
| 36 | while (sector >= hash->num_sectors + hash->start_sector) | 36 | while (sector >= hash->num_sectors + hash->start_sector) |
| 37 | hash++; | 37 | hash++; |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 41e2509bf896..4495104f6c9f 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -1481,6 +1481,11 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) | |||
| 1481 | if (find_rdev_nr(mddev, rdev->desc_nr)) | 1481 | if (find_rdev_nr(mddev, rdev->desc_nr)) |
| 1482 | return -EBUSY; | 1482 | return -EBUSY; |
| 1483 | } | 1483 | } |
| 1484 | if (mddev->max_disks && rdev->desc_nr >= mddev->max_disks) { | ||
| 1485 | printk(KERN_WARNING "md: %s: array is limited to %d devices\n", | ||
| 1486 | mdname(mddev), mddev->max_disks); | ||
| 1487 | return -EBUSY; | ||
| 1488 | } | ||
| 1484 | bdevname(rdev->bdev,b); | 1489 | bdevname(rdev->bdev,b); |
| 1485 | while ( (s=strchr(b, '/')) != NULL) | 1490 | while ( (s=strchr(b, '/')) != NULL) |
| 1486 | *s = '!'; | 1491 | *s = '!'; |
| @@ -2441,6 +2446,15 @@ static void analyze_sbs(mddev_t * mddev) | |||
| 2441 | 2446 | ||
| 2442 | i = 0; | 2447 | i = 0; |
| 2443 | rdev_for_each(rdev, tmp, mddev) { | 2448 | rdev_for_each(rdev, tmp, mddev) { |
| 2449 | if (rdev->desc_nr >= mddev->max_disks || | ||
| 2450 | i > mddev->max_disks) { | ||
| 2451 | printk(KERN_WARNING | ||
| 2452 | "md: %s: %s: only %d devices permitted\n", | ||
| 2453 | mdname(mddev), bdevname(rdev->bdev, b), | ||
| 2454 | mddev->max_disks); | ||
| 2455 | kick_rdev_from_array(rdev); | ||
| 2456 | continue; | ||
| 2457 | } | ||
| 2444 | if (rdev != freshest) | 2458 | if (rdev != freshest) |
| 2445 | if (super_types[mddev->major_version]. | 2459 | if (super_types[mddev->major_version]. |
| 2446 | validate_super(mddev, rdev)) { | 2460 | validate_super(mddev, rdev)) { |
| @@ -4614,13 +4628,6 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev) | |||
| 4614 | * noticed in interrupt contexts ... | 4628 | * noticed in interrupt contexts ... |
| 4615 | */ | 4629 | */ |
| 4616 | 4630 | ||
| 4617 | if (rdev->desc_nr == mddev->max_disks) { | ||
| 4618 | printk(KERN_WARNING "%s: can not hot-add to full array!\n", | ||
| 4619 | mdname(mddev)); | ||
| 4620 | err = -EBUSY; | ||
| 4621 | goto abort_unbind_export; | ||
| 4622 | } | ||
| 4623 | |||
| 4624 | rdev->raid_disk = -1; | 4631 | rdev->raid_disk = -1; |
| 4625 | 4632 | ||
| 4626 | md_update_sb(mddev, 1); | 4633 | md_update_sb(mddev, 1); |
| @@ -4634,9 +4641,6 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev) | |||
| 4634 | md_new_event(mddev); | 4641 | md_new_event(mddev); |
| 4635 | return 0; | 4642 | return 0; |
| 4636 | 4643 | ||
| 4637 | abort_unbind_export: | ||
| 4638 | unbind_rdev_from_array(rdev); | ||
| 4639 | |||
| 4640 | abort_export: | 4644 | abort_export: |
| 4641 | export_rdev(rdev); | 4645 | export_rdev(rdev); |
| 4642 | return err; | 4646 | return err; |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 7b4f5f7155d8..01e3cffd03b8 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
| @@ -1640,7 +1640,8 @@ static void raid1d(mddev_t *mddev) | |||
| 1640 | } | 1640 | } |
| 1641 | 1641 | ||
| 1642 | bio = r1_bio->bios[r1_bio->read_disk]; | 1642 | bio = r1_bio->bios[r1_bio->read_disk]; |
| 1643 | if ((disk=read_balance(conf, r1_bio)) == -1) { | 1643 | if ((disk=read_balance(conf, r1_bio)) == -1 || |
| 1644 | disk == r1_bio->read_disk) { | ||
| 1644 | printk(KERN_ALERT "raid1: %s: unrecoverable I/O" | 1645 | printk(KERN_ALERT "raid1: %s: unrecoverable I/O" |
| 1645 | " read error for block %llu\n", | 1646 | " read error for block %llu\n", |
| 1646 | bdevname(bio->bi_bdev,b), | 1647 | bdevname(bio->bi_bdev,b), |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 56073199ceba..c64e6798878a 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
| @@ -217,6 +217,7 @@ config DELL_LAPTOP | |||
| 217 | depends on EXPERIMENTAL | 217 | depends on EXPERIMENTAL |
| 218 | depends on BACKLIGHT_CLASS_DEVICE | 218 | depends on BACKLIGHT_CLASS_DEVICE |
| 219 | depends on RFKILL | 219 | depends on RFKILL |
| 220 | depends on POWER_SUPPLY | ||
| 220 | default n | 221 | default n |
| 221 | ---help--- | 222 | ---help--- |
| 222 | This driver adds support for rfkill and backlight control to Dell | 223 | This driver adds support for rfkill and backlight control to Dell |
diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c index bf5e4d065436..558bf3f2c276 100644 --- a/drivers/misc/atmel-ssc.c +++ b/drivers/misc/atmel-ssc.c | |||
| @@ -35,7 +35,7 @@ struct ssc_device *ssc_request(unsigned int ssc_num) | |||
| 35 | 35 | ||
| 36 | if (!ssc_valid) { | 36 | if (!ssc_valid) { |
| 37 | spin_unlock(&user_lock); | 37 | spin_unlock(&user_lock); |
| 38 | dev_dbg(&ssc->pdev->dev, "could not find requested device\n"); | 38 | pr_err("ssc: ssc%d platform device is missing\n", ssc_num); |
| 39 | return ERR_PTR(-ENODEV); | 39 | return ERR_PTR(-ENODEV); |
| 40 | } | 40 | } |
| 41 | 41 | ||
diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c index 10c421b73eaf..f26667a7abf7 100644 --- a/drivers/misc/hpilo.c +++ b/drivers/misc/hpilo.c | |||
| @@ -207,7 +207,7 @@ static void ilo_ccb_close(struct pci_dev *pdev, struct ccb_data *data) | |||
| 207 | &device_ccb->recv_ctrl); | 207 | &device_ccb->recv_ctrl); |
| 208 | 208 | ||
| 209 | /* give iLO some time to process stop request */ | 209 | /* give iLO some time to process stop request */ |
| 210 | for (retries = 1000; retries > 0; retries--) { | 210 | for (retries = MAX_WAIT; retries > 0; retries--) { |
| 211 | doorbell_set(driver_ccb); | 211 | doorbell_set(driver_ccb); |
| 212 | udelay(1); | 212 | udelay(1); |
| 213 | if (!(ioread32(&device_ccb->send_ctrl) & (1 << CTRL_BITPOS_A)) | 213 | if (!(ioread32(&device_ccb->send_ctrl) & (1 << CTRL_BITPOS_A)) |
| @@ -309,7 +309,7 @@ static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot) | |||
| 309 | doorbell_clr(driver_ccb); | 309 | doorbell_clr(driver_ccb); |
| 310 | 310 | ||
| 311 | /* make sure iLO is really handling requests */ | 311 | /* make sure iLO is really handling requests */ |
| 312 | for (i = 1000; i > 0; i--) { | 312 | for (i = MAX_WAIT; i > 0; i--) { |
| 313 | if (ilo_pkt_dequeue(hw, driver_ccb, SENDQ, &pkt_id, NULL, NULL)) | 313 | if (ilo_pkt_dequeue(hw, driver_ccb, SENDQ, &pkt_id, NULL, NULL)) |
| 314 | break; | 314 | break; |
| 315 | udelay(1); | 315 | udelay(1); |
| @@ -326,7 +326,7 @@ static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot) | |||
| 326 | 326 | ||
| 327 | return 0; | 327 | return 0; |
| 328 | free: | 328 | free: |
| 329 | pci_free_consistent(pdev, data->dma_size, data->dma_va, data->dma_pa); | 329 | ilo_ccb_close(pdev, data); |
| 330 | out: | 330 | out: |
| 331 | return error; | 331 | return error; |
| 332 | } | 332 | } |
diff --git a/drivers/misc/hpilo.h b/drivers/misc/hpilo.h index a281207696c1..b64a20ef07e3 100644 --- a/drivers/misc/hpilo.h +++ b/drivers/misc/hpilo.h | |||
| @@ -19,6 +19,8 @@ | |||
| 19 | #define MAX_ILO_DEV 1 | 19 | #define MAX_ILO_DEV 1 |
| 20 | /* max number of files */ | 20 | /* max number of files */ |
| 21 | #define MAX_OPEN (MAX_CCB * MAX_ILO_DEV) | 21 | #define MAX_OPEN (MAX_CCB * MAX_ILO_DEV) |
| 22 | /* spin counter for open/close delay */ | ||
| 23 | #define MAX_WAIT 10000 | ||
| 22 | 24 | ||
| 23 | /* | 25 | /* |
| 24 | * Per device, used to track global memory allocations. | 26 | * Per device, used to track global memory allocations. |
diff --git a/drivers/misc/sgi-xp/xpc.h b/drivers/misc/sgi-xp/xpc.h index a5bd658c2e83..275b78896a73 100644 --- a/drivers/misc/sgi-xp/xpc.h +++ b/drivers/misc/sgi-xp/xpc.h | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
| 4 | * for more details. | 4 | * for more details. |
| 5 | * | 5 | * |
| 6 | * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved. | 6 | * Copyright (c) 2004-2009 Silicon Graphics, Inc. All Rights Reserved. |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | /* | 9 | /* |
| @@ -514,7 +514,8 @@ struct xpc_channel_uv { | |||
| 514 | /* partition's notify mq */ | 514 | /* partition's notify mq */ |
| 515 | 515 | ||
| 516 | struct xpc_send_msg_slot_uv *send_msg_slots; | 516 | struct xpc_send_msg_slot_uv *send_msg_slots; |
| 517 | struct xpc_notify_mq_msg_uv *recv_msg_slots; | 517 | void *recv_msg_slots; /* each slot will hold a xpc_notify_mq_msg_uv */ |
| 518 | /* structure plus the user's payload */ | ||
| 518 | 519 | ||
| 519 | struct xpc_fifo_head_uv msg_slot_free_list; | 520 | struct xpc_fifo_head_uv msg_slot_free_list; |
| 520 | struct xpc_fifo_head_uv recv_msg_list; /* deliverable payloads */ | 521 | struct xpc_fifo_head_uv recv_msg_list; /* deliverable payloads */ |
diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c index f17f7d40ea2c..29c0502a96b2 100644 --- a/drivers/misc/sgi-xp/xpc_uv.c +++ b/drivers/misc/sgi-xp/xpc_uv.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
| 4 | * for more details. | 4 | * for more details. |
| 5 | * | 5 | * |
| 6 | * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved. | 6 | * Copyright (c) 2008-2009 Silicon Graphics, Inc. All Rights Reserved. |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | /* | 9 | /* |
| @@ -1010,8 +1010,8 @@ xpc_allocate_recv_msg_slot_uv(struct xpc_channel *ch) | |||
| 1010 | continue; | 1010 | continue; |
| 1011 | 1011 | ||
| 1012 | for (entry = 0; entry < nentries; entry++) { | 1012 | for (entry = 0; entry < nentries; entry++) { |
| 1013 | msg_slot = ch_uv->recv_msg_slots + entry * | 1013 | msg_slot = ch_uv->recv_msg_slots + |
| 1014 | ch->entry_size; | 1014 | entry * ch->entry_size; |
| 1015 | 1015 | ||
| 1016 | msg_slot->hdr.msg_slot_number = entry; | 1016 | msg_slot->hdr.msg_slot_number = entry; |
| 1017 | } | 1017 | } |
| @@ -1308,9 +1308,8 @@ xpc_handle_notify_mq_msg_uv(struct xpc_partition *part, | |||
| 1308 | /* we're dealing with a normal message sent via the notify_mq */ | 1308 | /* we're dealing with a normal message sent via the notify_mq */ |
| 1309 | ch_uv = &ch->sn.uv; | 1309 | ch_uv = &ch->sn.uv; |
| 1310 | 1310 | ||
| 1311 | msg_slot = (struct xpc_notify_mq_msg_uv *)((u64)ch_uv->recv_msg_slots + | 1311 | msg_slot = ch_uv->recv_msg_slots + |
| 1312 | (msg->hdr.msg_slot_number % ch->remote_nentries) * | 1312 | (msg->hdr.msg_slot_number % ch->remote_nentries) * ch->entry_size; |
| 1313 | ch->entry_size); | ||
| 1314 | 1313 | ||
| 1315 | BUG_ON(msg->hdr.msg_slot_number != msg_slot->hdr.msg_slot_number); | 1314 | BUG_ON(msg->hdr.msg_slot_number != msg_slot->hdr.msg_slot_number); |
| 1316 | BUG_ON(msg_slot->hdr.size != 0); | 1315 | BUG_ON(msg_slot->hdr.size != 0); |
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index 379a1324db4e..d31791f60292 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c | |||
| @@ -2276,8 +2276,7 @@ no_mem: | |||
| 2276 | } else if ((len = ntohl(r->len_cq)) != 0) { | 2276 | } else if ((len = ntohl(r->len_cq)) != 0) { |
| 2277 | struct sge_fl *fl; | 2277 | struct sge_fl *fl; |
| 2278 | 2278 | ||
| 2279 | if (eth) | 2279 | lro &= eth && is_eth_tcp(rss_hi); |
| 2280 | lro = qs->lro_enabled && is_eth_tcp(rss_hi); | ||
| 2281 | 2280 | ||
| 2282 | fl = (len & F_RSPD_FLQ) ? &qs->fl[1] : &qs->fl[0]; | 2281 | fl = (len & F_RSPD_FLQ) ? &qs->fl[1] : &qs->fl[0]; |
| 2283 | if (fl->use_pages) { | 2282 | if (fl->use_pages) { |
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 3f7eab42aef1..acae2d8cd688 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
| @@ -351,6 +351,9 @@ static int gfar_probe(struct of_device *ofdev, | |||
| 351 | /* Reset MAC layer */ | 351 | /* Reset MAC layer */ |
| 352 | gfar_write(&priv->regs->maccfg1, MACCFG1_SOFT_RESET); | 352 | gfar_write(&priv->regs->maccfg1, MACCFG1_SOFT_RESET); |
| 353 | 353 | ||
| 354 | /* We need to delay at least 3 TX clocks */ | ||
| 355 | udelay(2); | ||
| 356 | |||
| 354 | tempval = (MACCFG1_TX_FLOW | MACCFG1_RX_FLOW); | 357 | tempval = (MACCFG1_TX_FLOW | MACCFG1_RX_FLOW); |
| 355 | gfar_write(&priv->regs->maccfg1, tempval); | 358 | gfar_write(&priv->regs->maccfg1, tempval); |
| 356 | 359 | ||
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index b1a83344acc7..eaa86897f5c3 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h | |||
| @@ -312,7 +312,7 @@ extern const char gfar_driver_version[]; | |||
| 312 | #define ATTRELI_EI(x) (x) | 312 | #define ATTRELI_EI(x) (x) |
| 313 | 313 | ||
| 314 | #define BD_LFLAG(flags) ((flags) << 16) | 314 | #define BD_LFLAG(flags) ((flags) << 16) |
| 315 | #define BD_LENGTH_MASK 0x00ff | 315 | #define BD_LENGTH_MASK 0x0000ffff |
| 316 | 316 | ||
| 317 | /* TxBD status field bits */ | 317 | /* TxBD status field bits */ |
| 318 | #define TXBD_READY 0x8000 | 318 | #define TXBD_READY 0x8000 |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b35c8813bef4..c01ea48da5fe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
| @@ -4042,6 +4042,7 @@ static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
| 4042 | priv->is_open = 1; | 4042 | priv->is_open = 1; |
| 4043 | } | 4043 | } |
| 4044 | 4044 | ||
| 4045 | pci_save_state(pdev); | ||
| 4045 | pci_set_power_state(pdev, PCI_D3hot); | 4046 | pci_set_power_state(pdev, PCI_D3hot); |
| 4046 | 4047 | ||
| 4047 | return 0; | 4048 | return 0; |
| @@ -4052,6 +4053,7 @@ static int iwl_pci_resume(struct pci_dev *pdev) | |||
| 4052 | struct iwl_priv *priv = pci_get_drvdata(pdev); | 4053 | struct iwl_priv *priv = pci_get_drvdata(pdev); |
| 4053 | 4054 | ||
| 4054 | pci_set_power_state(pdev, PCI_D0); | 4055 | pci_set_power_state(pdev, PCI_D0); |
| 4056 | pci_restore_state(pdev); | ||
| 4055 | 4057 | ||
| 4056 | if (priv->is_open) | 4058 | if (priv->is_open) |
| 4057 | iwl_mac_start(priv->hw); | 4059 | iwl_mac_start(priv->hw); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 412f66bac1af..70a8b21ca39b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c | |||
| @@ -480,6 +480,9 @@ void iwl_clear_stations_table(struct iwl_priv *priv) | |||
| 480 | priv->num_stations = 0; | 480 | priv->num_stations = 0; |
| 481 | memset(priv->stations, 0, sizeof(priv->stations)); | 481 | memset(priv->stations, 0, sizeof(priv->stations)); |
| 482 | 482 | ||
| 483 | /* clean ucode key table bit map */ | ||
| 484 | priv->ucode_key_table = 0; | ||
| 485 | |||
| 483 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 486 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
| 484 | } | 487 | } |
| 485 | EXPORT_SYMBOL(iwl_clear_stations_table); | 488 | EXPORT_SYMBOL(iwl_clear_stations_table); |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 95d01984c80e..5b44d322b99f 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
| @@ -8143,6 +8143,7 @@ static int iwl3945_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
| 8143 | priv->is_open = 1; | 8143 | priv->is_open = 1; |
| 8144 | } | 8144 | } |
| 8145 | 8145 | ||
| 8146 | pci_save_state(pdev); | ||
| 8146 | pci_set_power_state(pdev, PCI_D3hot); | 8147 | pci_set_power_state(pdev, PCI_D3hot); |
| 8147 | 8148 | ||
| 8148 | return 0; | 8149 | return 0; |
| @@ -8153,6 +8154,7 @@ static int iwl3945_pci_resume(struct pci_dev *pdev) | |||
| 8153 | struct iwl3945_priv *priv = pci_get_drvdata(pdev); | 8154 | struct iwl3945_priv *priv = pci_get_drvdata(pdev); |
| 8154 | 8155 | ||
| 8155 | pci_set_power_state(pdev, PCI_D0); | 8156 | pci_set_power_state(pdev, PCI_D0); |
| 8157 | pci_restore_state(pdev); | ||
| 8156 | 8158 | ||
| 8157 | if (priv->is_open) | 8159 | if (priv->is_open) |
| 8158 | iwl3945_mac_start(priv->hw); | 8160 | iwl3945_mac_start(priv->hw); |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index ab1d615425a8..93eac1423585 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
| @@ -355,6 +355,8 @@ static int pci_legacy_suspend(struct device *dev, pm_message_t state) | |||
| 355 | int i = 0; | 355 | int i = 0; |
| 356 | 356 | ||
| 357 | if (drv && drv->suspend) { | 357 | if (drv && drv->suspend) { |
| 358 | pci_power_t prev = pci_dev->current_state; | ||
| 359 | |||
| 358 | pci_dev->state_saved = false; | 360 | pci_dev->state_saved = false; |
| 359 | 361 | ||
| 360 | i = drv->suspend(pci_dev, state); | 362 | i = drv->suspend(pci_dev, state); |
| @@ -365,12 +367,16 @@ static int pci_legacy_suspend(struct device *dev, pm_message_t state) | |||
| 365 | if (pci_dev->state_saved) | 367 | if (pci_dev->state_saved) |
| 366 | goto Fixup; | 368 | goto Fixup; |
| 367 | 369 | ||
| 368 | if (WARN_ON_ONCE(pci_dev->current_state != PCI_D0)) | 370 | if (pci_dev->current_state != PCI_D0 |
| 371 | && pci_dev->current_state != PCI_UNKNOWN) { | ||
| 372 | WARN_ONCE(pci_dev->current_state != prev, | ||
| 373 | "PCI PM: Device state not saved by %pF\n", | ||
| 374 | drv->suspend); | ||
| 369 | goto Fixup; | 375 | goto Fixup; |
| 376 | } | ||
| 370 | } | 377 | } |
| 371 | 378 | ||
| 372 | pci_save_state(pci_dev); | 379 | pci_save_state(pci_dev); |
| 373 | pci_dev->state_saved = true; | ||
| 374 | /* | 380 | /* |
| 375 | * This is for compatibility with existing code with legacy PM support. | 381 | * This is for compatibility with existing code with legacy PM support. |
| 376 | */ | 382 | */ |
| @@ -424,35 +430,20 @@ static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev) | |||
| 424 | pci_fixup_device(pci_fixup_resume_early, pci_dev); | 430 | pci_fixup_device(pci_fixup_resume_early, pci_dev); |
| 425 | } | 431 | } |
| 426 | 432 | ||
| 427 | static int pci_pm_default_resume(struct pci_dev *pci_dev) | 433 | static void pci_pm_default_resume(struct pci_dev *pci_dev) |
| 428 | { | 434 | { |
| 429 | pci_fixup_device(pci_fixup_resume, pci_dev); | 435 | pci_fixup_device(pci_fixup_resume, pci_dev); |
| 430 | 436 | ||
| 431 | if (!pci_is_bridge(pci_dev)) | 437 | if (!pci_is_bridge(pci_dev)) |
| 432 | pci_enable_wake(pci_dev, PCI_D0, false); | 438 | pci_enable_wake(pci_dev, PCI_D0, false); |
| 433 | |||
| 434 | return pci_pm_reenable_device(pci_dev); | ||
| 435 | } | ||
| 436 | |||
| 437 | static void pci_pm_default_suspend_generic(struct pci_dev *pci_dev) | ||
| 438 | { | ||
| 439 | /* If device is enabled at this point, disable it */ | ||
| 440 | pci_disable_enabled_device(pci_dev); | ||
| 441 | /* | ||
| 442 | * Save state with interrupts enabled, because in principle the bus the | ||
| 443 | * device is on may be put into a low power state after this code runs. | ||
| 444 | */ | ||
| 445 | pci_save_state(pci_dev); | ||
| 446 | } | 439 | } |
| 447 | 440 | ||
| 448 | static void pci_pm_default_suspend(struct pci_dev *pci_dev) | 441 | static void pci_pm_default_suspend(struct pci_dev *pci_dev) |
| 449 | { | 442 | { |
| 450 | pci_pm_default_suspend_generic(pci_dev); | 443 | /* Disable non-bridge devices without PM support */ |
| 451 | |||
| 452 | if (!pci_is_bridge(pci_dev)) | 444 | if (!pci_is_bridge(pci_dev)) |
| 453 | pci_prepare_to_sleep(pci_dev); | 445 | pci_disable_enabled_device(pci_dev); |
| 454 | 446 | pci_save_state(pci_dev); | |
| 455 | pci_fixup_device(pci_fixup_suspend, pci_dev); | ||
| 456 | } | 447 | } |
| 457 | 448 | ||
| 458 | static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev) | 449 | static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev) |
| @@ -497,21 +488,49 @@ static void pci_pm_complete(struct device *dev) | |||
| 497 | static int pci_pm_suspend(struct device *dev) | 488 | static int pci_pm_suspend(struct device *dev) |
| 498 | { | 489 | { |
| 499 | struct pci_dev *pci_dev = to_pci_dev(dev); | 490 | struct pci_dev *pci_dev = to_pci_dev(dev); |
| 500 | struct device_driver *drv = dev->driver; | 491 | struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
| 501 | int error = 0; | ||
| 502 | 492 | ||
| 503 | if (pci_has_legacy_pm_support(pci_dev)) | 493 | if (pci_has_legacy_pm_support(pci_dev)) |
| 504 | return pci_legacy_suspend(dev, PMSG_SUSPEND); | 494 | return pci_legacy_suspend(dev, PMSG_SUSPEND); |
| 505 | 495 | ||
| 506 | if (drv && drv->pm && drv->pm->suspend) { | 496 | if (!pm) { |
| 507 | error = drv->pm->suspend(dev); | 497 | pci_pm_default_suspend(pci_dev); |
| 508 | suspend_report_result(drv->pm->suspend, error); | 498 | goto Fixup; |
| 509 | } | 499 | } |
| 510 | 500 | ||
| 511 | if (!error) | 501 | pci_dev->state_saved = false; |
| 512 | pci_pm_default_suspend(pci_dev); | ||
| 513 | 502 | ||
| 514 | return error; | 503 | if (pm->suspend) { |
| 504 | pci_power_t prev = pci_dev->current_state; | ||
| 505 | int error; | ||
| 506 | |||
| 507 | error = pm->suspend(dev); | ||
| 508 | suspend_report_result(pm->suspend, error); | ||
| 509 | if (error) | ||
| 510 | return error; | ||
| 511 | |||
| 512 | if (pci_dev->state_saved) | ||
| 513 | goto Fixup; | ||
| 514 | |||
| 515 | if (pci_dev->current_state != PCI_D0 | ||
| 516 | && pci_dev->current_state != PCI_UNKNOWN) { | ||
| 517 | WARN_ONCE(pci_dev->current_state != prev, | ||
| 518 | "PCI PM: State of device not saved by %pF\n", | ||
| 519 | pm->suspend); | ||
| 520 | goto Fixup; | ||
| 521 | } | ||
| 522 | } | ||
| 523 | |||
| 524 | if (!pci_dev->state_saved) { | ||
| 525 | pci_save_state(pci_dev); | ||
| 526 | if (!pci_is_bridge(pci_dev)) | ||
| 527 | pci_prepare_to_sleep(pci_dev); | ||
| 528 | } | ||
| 529 | |||
| 530 | Fixup: | ||
| 531 | pci_fixup_device(pci_fixup_suspend, pci_dev); | ||
| 532 | |||
| 533 | return 0; | ||
| 515 | } | 534 | } |
| 516 | 535 | ||
| 517 | static int pci_pm_suspend_noirq(struct device *dev) | 536 | static int pci_pm_suspend_noirq(struct device *dev) |
| @@ -554,7 +573,7 @@ static int pci_pm_resume_noirq(struct device *dev) | |||
| 554 | static int pci_pm_resume(struct device *dev) | 573 | static int pci_pm_resume(struct device *dev) |
| 555 | { | 574 | { |
| 556 | struct pci_dev *pci_dev = to_pci_dev(dev); | 575 | struct pci_dev *pci_dev = to_pci_dev(dev); |
| 557 | struct device_driver *drv = dev->driver; | 576 | struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
| 558 | int error = 0; | 577 | int error = 0; |
| 559 | 578 | ||
| 560 | /* | 579 | /* |
| @@ -567,12 +586,16 @@ static int pci_pm_resume(struct device *dev) | |||
| 567 | if (pci_has_legacy_pm_support(pci_dev)) | 586 | if (pci_has_legacy_pm_support(pci_dev)) |
| 568 | return pci_legacy_resume(dev); | 587 | return pci_legacy_resume(dev); |
| 569 | 588 | ||
| 570 | error = pci_pm_default_resume(pci_dev); | 589 | pci_pm_default_resume(pci_dev); |
| 571 | 590 | ||
| 572 | if (!error && drv && drv->pm && drv->pm->resume) | 591 | if (pm) { |
| 573 | error = drv->pm->resume(dev); | 592 | if (pm->resume) |
| 593 | error = pm->resume(dev); | ||
| 594 | } else { | ||
| 595 | pci_pm_reenable_device(pci_dev); | ||
| 596 | } | ||
| 574 | 597 | ||
| 575 | return error; | 598 | return 0; |
| 576 | } | 599 | } |
| 577 | 600 | ||
| 578 | #else /* !CONFIG_SUSPEND */ | 601 | #else /* !CONFIG_SUSPEND */ |
| @@ -589,21 +612,31 @@ static int pci_pm_resume(struct device *dev) | |||
| 589 | static int pci_pm_freeze(struct device *dev) | 612 | static int pci_pm_freeze(struct device *dev) |
| 590 | { | 613 | { |
| 591 | struct pci_dev *pci_dev = to_pci_dev(dev); | 614 | struct pci_dev *pci_dev = to_pci_dev(dev); |
| 592 | struct device_driver *drv = dev->driver; | 615 | struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
| 593 | int error = 0; | ||
| 594 | 616 | ||
| 595 | if (pci_has_legacy_pm_support(pci_dev)) | 617 | if (pci_has_legacy_pm_support(pci_dev)) |
| 596 | return pci_legacy_suspend(dev, PMSG_FREEZE); | 618 | return pci_legacy_suspend(dev, PMSG_FREEZE); |
| 597 | 619 | ||
| 598 | if (drv && drv->pm && drv->pm->freeze) { | 620 | if (!pm) { |
| 599 | error = drv->pm->freeze(dev); | 621 | pci_pm_default_suspend(pci_dev); |
| 600 | suspend_report_result(drv->pm->freeze, error); | 622 | return 0; |
| 601 | } | 623 | } |
| 602 | 624 | ||
| 603 | if (!error) | 625 | pci_dev->state_saved = false; |
| 604 | pci_pm_default_suspend_generic(pci_dev); | ||
| 605 | 626 | ||
| 606 | return error; | 627 | if (pm->freeze) { |
| 628 | int error; | ||
| 629 | |||
| 630 | error = pm->freeze(dev); | ||
| 631 | suspend_report_result(pm->freeze, error); | ||
| 632 | if (error) | ||
| 633 | return error; | ||
| 634 | } | ||
| 635 | |||
| 636 | if (!pci_dev->state_saved) | ||
| 637 | pci_save_state(pci_dev); | ||
| 638 | |||
| 639 | return 0; | ||
| 607 | } | 640 | } |
| 608 | 641 | ||
| 609 | static int pci_pm_freeze_noirq(struct device *dev) | 642 | static int pci_pm_freeze_noirq(struct device *dev) |
| @@ -646,16 +679,18 @@ static int pci_pm_thaw_noirq(struct device *dev) | |||
| 646 | static int pci_pm_thaw(struct device *dev) | 679 | static int pci_pm_thaw(struct device *dev) |
| 647 | { | 680 | { |
| 648 | struct pci_dev *pci_dev = to_pci_dev(dev); | 681 | struct pci_dev *pci_dev = to_pci_dev(dev); |
| 649 | struct device_driver *drv = dev->driver; | 682 | struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
| 650 | int error = 0; | 683 | int error = 0; |
| 651 | 684 | ||
| 652 | if (pci_has_legacy_pm_support(pci_dev)) | 685 | if (pci_has_legacy_pm_support(pci_dev)) |
| 653 | return pci_legacy_resume(dev); | 686 | return pci_legacy_resume(dev); |
| 654 | 687 | ||
| 655 | pci_pm_reenable_device(pci_dev); | 688 | if (pm) { |
| 656 | 689 | if (pm->thaw) | |
| 657 | if (drv && drv->pm && drv->pm->thaw) | 690 | error = pm->thaw(dev); |
| 658 | error = drv->pm->thaw(dev); | 691 | } else { |
| 692 | pci_pm_reenable_device(pci_dev); | ||
| 693 | } | ||
| 659 | 694 | ||
| 660 | return error; | 695 | return error; |
| 661 | } | 696 | } |
| @@ -663,22 +698,29 @@ static int pci_pm_thaw(struct device *dev) | |||
| 663 | static int pci_pm_poweroff(struct device *dev) | 698 | static int pci_pm_poweroff(struct device *dev) |
| 664 | { | 699 | { |
| 665 | struct pci_dev *pci_dev = to_pci_dev(dev); | 700 | struct pci_dev *pci_dev = to_pci_dev(dev); |
| 666 | struct device_driver *drv = dev->driver; | 701 | struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
| 667 | int error = 0; | 702 | int error = 0; |
| 668 | 703 | ||
| 669 | if (pci_has_legacy_pm_support(pci_dev)) | 704 | if (pci_has_legacy_pm_support(pci_dev)) |
| 670 | return pci_legacy_suspend(dev, PMSG_HIBERNATE); | 705 | return pci_legacy_suspend(dev, PMSG_HIBERNATE); |
| 671 | 706 | ||
| 672 | if (!drv || !drv->pm) | 707 | if (!pm) { |
| 673 | return 0; | 708 | pci_pm_default_suspend(pci_dev); |
| 709 | goto Fixup; | ||
| 710 | } | ||
| 711 | |||
| 712 | pci_dev->state_saved = false; | ||
| 674 | 713 | ||
| 675 | if (drv->pm->poweroff) { | 714 | if (pm->poweroff) { |
| 676 | error = drv->pm->poweroff(dev); | 715 | error = pm->poweroff(dev); |
| 677 | suspend_report_result(drv->pm->poweroff, error); | 716 | suspend_report_result(pm->poweroff, error); |
| 678 | } | 717 | } |
| 679 | 718 | ||
| 680 | if (!error) | 719 | if (!pci_dev->state_saved && !pci_is_bridge(pci_dev)) |
| 681 | pci_pm_default_suspend(pci_dev); | 720 | pci_prepare_to_sleep(pci_dev); |
| 721 | |||
| 722 | Fixup: | ||
| 723 | pci_fixup_device(pci_fixup_suspend, pci_dev); | ||
| 682 | 724 | ||
| 683 | return error; | 725 | return error; |
| 684 | } | 726 | } |
| @@ -719,7 +761,7 @@ static int pci_pm_restore_noirq(struct device *dev) | |||
| 719 | static int pci_pm_restore(struct device *dev) | 761 | static int pci_pm_restore(struct device *dev) |
| 720 | { | 762 | { |
| 721 | struct pci_dev *pci_dev = to_pci_dev(dev); | 763 | struct pci_dev *pci_dev = to_pci_dev(dev); |
| 722 | struct device_driver *drv = dev->driver; | 764 | struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
| 723 | int error = 0; | 765 | int error = 0; |
| 724 | 766 | ||
| 725 | /* | 767 | /* |
| @@ -732,10 +774,14 @@ static int pci_pm_restore(struct device *dev) | |||
| 732 | if (pci_has_legacy_pm_support(pci_dev)) | 774 | if (pci_has_legacy_pm_support(pci_dev)) |
| 733 | return pci_legacy_resume(dev); | 775 | return pci_legacy_resume(dev); |
| 734 | 776 | ||
| 735 | error = pci_pm_default_resume(pci_dev); | 777 | pci_pm_default_resume(pci_dev); |
| 736 | 778 | ||
| 737 | if (!error && drv && drv->pm && drv->pm->restore) | 779 | if (pm) { |
| 738 | error = drv->pm->restore(dev); | 780 | if (pm->restore) |
| 781 | error = pm->restore(dev); | ||
| 782 | } else { | ||
| 783 | pci_pm_reenable_device(pci_dev); | ||
| 784 | } | ||
| 739 | 785 | ||
| 740 | return error; | 786 | return error; |
| 741 | } | 787 | } |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index db7ec14fa719..dfc4e0ddf241 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
| @@ -768,8 +768,8 @@ pci_read_rom(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
| 768 | return -EINVAL; | 768 | return -EINVAL; |
| 769 | 769 | ||
| 770 | rom = pci_map_rom(pdev, &size); /* size starts out as PCI window size */ | 770 | rom = pci_map_rom(pdev, &size); /* size starts out as PCI window size */ |
| 771 | if (!rom) | 771 | if (!rom || !size) |
| 772 | return 0; | 772 | return -EIO; |
| 773 | 773 | ||
| 774 | if (off >= size) | 774 | if (off >= size) |
| 775 | count = 0; | 775 | count = 0; |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 48807556b47a..e3efe6b19ee7 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
| @@ -1418,10 +1418,10 @@ int pci_restore_standard_config(struct pci_dev *dev) | |||
| 1418 | break; | 1418 | break; |
| 1419 | } | 1419 | } |
| 1420 | 1420 | ||
| 1421 | dev->current_state = PCI_D0; | 1421 | pci_update_current_state(dev, PCI_D0); |
| 1422 | 1422 | ||
| 1423 | Restore: | 1423 | Restore: |
| 1424 | return pci_restore_state(dev); | 1424 | return dev->state_saved ? pci_restore_state(dev) : 0; |
| 1425 | } | 1425 | } |
| 1426 | 1426 | ||
| 1427 | /** | 1427 | /** |
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 586b6f75910d..b0367f168af4 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
| @@ -718,9 +718,9 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev) | |||
| 718 | 718 | ||
| 719 | /* | 719 | /* |
| 720 | * All PCIe functions are in one slot, remove one function will remove | 720 | * All PCIe functions are in one slot, remove one function will remove |
| 721 | * the the whole slot, so just wait | 721 | * the whole slot, so just wait until we are the last function left. |
| 722 | */ | 722 | */ |
| 723 | if (!list_empty(&parent->subordinate->devices)) | 723 | if (!list_is_last(&pdev->bus_list, &parent->subordinate->devices)) |
| 724 | goto out; | 724 | goto out; |
| 725 | 725 | ||
| 726 | /* All functions are removed, so just disable ASPM for the link */ | 726 | /* All functions are removed, so just disable ASPM for the link */ |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 99a914a027f8..f9b874eaeb9f 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
| @@ -55,25 +55,13 @@ static int pcie_portdrv_suspend(struct pci_dev *dev, pm_message_t state) | |||
| 55 | 55 | ||
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | static int pcie_portdrv_suspend_late(struct pci_dev *dev, pm_message_t state) | ||
| 59 | { | ||
| 60 | return pci_save_state(dev); | ||
| 61 | } | ||
| 62 | |||
| 63 | static int pcie_portdrv_resume_early(struct pci_dev *dev) | ||
| 64 | { | ||
| 65 | return pci_restore_state(dev); | ||
| 66 | } | ||
| 67 | |||
| 68 | static int pcie_portdrv_resume(struct pci_dev *dev) | 58 | static int pcie_portdrv_resume(struct pci_dev *dev) |
| 69 | { | 59 | { |
| 70 | pcie_portdrv_restore_config(dev); | 60 | pci_set_master(dev); |
| 71 | return pcie_port_device_resume(dev); | 61 | return pcie_port_device_resume(dev); |
| 72 | } | 62 | } |
| 73 | #else | 63 | #else |
| 74 | #define pcie_portdrv_suspend NULL | 64 | #define pcie_portdrv_suspend NULL |
| 75 | #define pcie_portdrv_suspend_late NULL | ||
| 76 | #define pcie_portdrv_resume_early NULL | ||
| 77 | #define pcie_portdrv_resume NULL | 65 | #define pcie_portdrv_resume NULL |
| 78 | #endif | 66 | #endif |
| 79 | 67 | ||
| @@ -292,8 +280,6 @@ static struct pci_driver pcie_portdriver = { | |||
| 292 | .remove = pcie_portdrv_remove, | 280 | .remove = pcie_portdrv_remove, |
| 293 | 281 | ||
| 294 | .suspend = pcie_portdrv_suspend, | 282 | .suspend = pcie_portdrv_suspend, |
| 295 | .suspend_late = pcie_portdrv_suspend_late, | ||
| 296 | .resume_early = pcie_portdrv_resume_early, | ||
| 297 | .resume = pcie_portdrv_resume, | 283 | .resume = pcie_portdrv_resume, |
| 298 | 284 | ||
| 299 | .err_handler = &pcie_portdrv_err_handler, | 285 | .err_handler = &pcie_portdrv_err_handler, |
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index 132a78159b60..29cbe47f219f 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c | |||
| @@ -63,7 +63,7 @@ void pci_disable_rom(struct pci_dev *pdev) | |||
| 63 | * The PCI window size could be much larger than the | 63 | * The PCI window size could be much larger than the |
| 64 | * actual image size. | 64 | * actual image size. |
| 65 | */ | 65 | */ |
| 66 | size_t pci_get_rom_size(void __iomem *rom, size_t size) | 66 | size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size) |
| 67 | { | 67 | { |
| 68 | void __iomem *image; | 68 | void __iomem *image; |
| 69 | int last_image; | 69 | int last_image; |
| @@ -72,8 +72,10 @@ size_t pci_get_rom_size(void __iomem *rom, size_t size) | |||
| 72 | do { | 72 | do { |
| 73 | void __iomem *pds; | 73 | void __iomem *pds; |
| 74 | /* Standard PCI ROMs start out with these bytes 55 AA */ | 74 | /* Standard PCI ROMs start out with these bytes 55 AA */ |
| 75 | if (readb(image) != 0x55) | 75 | if (readb(image) != 0x55) { |
| 76 | dev_err(&pdev->dev, "Invalid ROM contents\n"); | ||
| 76 | break; | 77 | break; |
| 78 | } | ||
| 77 | if (readb(image + 1) != 0xAA) | 79 | if (readb(image + 1) != 0xAA) |
| 78 | break; | 80 | break; |
| 79 | /* get the PCI data structure and check its signature */ | 81 | /* get the PCI data structure and check its signature */ |
| @@ -159,7 +161,7 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) | |||
| 159 | * size is much larger than the actual size of the ROM. | 161 | * size is much larger than the actual size of the ROM. |
| 160 | * True size is important if the ROM is going to be copied. | 162 | * True size is important if the ROM is going to be copied. |
| 161 | */ | 163 | */ |
| 162 | *size = pci_get_rom_size(rom, *size); | 164 | *size = pci_get_rom_size(pdev, rom, *size); |
| 163 | return rom; | 165 | return rom; |
| 164 | } | 166 | } |
| 165 | 167 | ||
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 1a266d4ab5f1..94363115a42a 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
| @@ -42,6 +42,7 @@ config ASUS_LAPTOP | |||
| 42 | depends on LEDS_CLASS | 42 | depends on LEDS_CLASS |
| 43 | depends on NEW_LEDS | 43 | depends on NEW_LEDS |
| 44 | depends on BACKLIGHT_CLASS_DEVICE | 44 | depends on BACKLIGHT_CLASS_DEVICE |
| 45 | depends on INPUT | ||
| 45 | ---help--- | 46 | ---help--- |
| 46 | This is the new Linux driver for Asus laptops. It may also support some | 47 | This is the new Linux driver for Asus laptops. It may also support some |
| 47 | MEDION, JVC or VICTOR laptops. It makes all the extra buttons generate | 48 | MEDION, JVC or VICTOR laptops. It makes all the extra buttons generate |
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index 8fb8b3591048..56af6cf385b0 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c | |||
| @@ -46,6 +46,7 @@ | |||
| 46 | #include <acpi/acpi_drivers.h> | 46 | #include <acpi/acpi_drivers.h> |
| 47 | #include <acpi/acpi_bus.h> | 47 | #include <acpi/acpi_bus.h> |
| 48 | #include <asm/uaccess.h> | 48 | #include <asm/uaccess.h> |
| 49 | #include <linux/input.h> | ||
| 49 | 50 | ||
| 50 | #define ASUS_LAPTOP_VERSION "0.42" | 51 | #define ASUS_LAPTOP_VERSION "0.42" |
| 51 | 52 | ||
| @@ -181,6 +182,8 @@ struct asus_hotk { | |||
| 181 | u8 light_level; //light sensor level | 182 | u8 light_level; //light sensor level |
| 182 | u8 light_switch; //light sensor switch value | 183 | u8 light_switch; //light sensor switch value |
| 183 | u16 event_count[128]; //count for each event TODO make this better | 184 | u16 event_count[128]; //count for each event TODO make this better |
| 185 | struct input_dev *inputdev; | ||
| 186 | u16 *keycode_map; | ||
| 184 | }; | 187 | }; |
| 185 | 188 | ||
| 186 | /* | 189 | /* |
| @@ -250,6 +253,37 @@ ASUS_LED(rled, "record"); | |||
| 250 | ASUS_LED(pled, "phone"); | 253 | ASUS_LED(pled, "phone"); |
| 251 | ASUS_LED(gled, "gaming"); | 254 | ASUS_LED(gled, "gaming"); |
| 252 | 255 | ||
| 256 | struct key_entry { | ||
| 257 | char type; | ||
| 258 | u8 code; | ||
| 259 | u16 keycode; | ||
| 260 | }; | ||
| 261 | |||
| 262 | enum { KE_KEY, KE_END }; | ||
| 263 | |||
| 264 | static struct key_entry asus_keymap[] = { | ||
| 265 | {KE_KEY, 0x30, KEY_VOLUMEUP}, | ||
| 266 | {KE_KEY, 0x31, KEY_VOLUMEDOWN}, | ||
| 267 | {KE_KEY, 0x32, KEY_MUTE}, | ||
| 268 | {KE_KEY, 0x33, KEY_SWITCHVIDEOMODE}, | ||
| 269 | {KE_KEY, 0x34, KEY_SWITCHVIDEOMODE}, | ||
| 270 | {KE_KEY, 0x40, KEY_PREVIOUSSONG}, | ||
| 271 | {KE_KEY, 0x41, KEY_NEXTSONG}, | ||
| 272 | {KE_KEY, 0x43, KEY_STOP}, | ||
| 273 | {KE_KEY, 0x45, KEY_PLAYPAUSE}, | ||
| 274 | {KE_KEY, 0x50, KEY_EMAIL}, | ||
| 275 | {KE_KEY, 0x51, KEY_WWW}, | ||
| 276 | {KE_KEY, 0x5C, BTN_EXTRA}, /* Performance */ | ||
| 277 | {KE_KEY, 0x5D, KEY_WLAN}, | ||
| 278 | {KE_KEY, 0x61, KEY_SWITCHVIDEOMODE}, | ||
| 279 | {KE_KEY, 0x6B, BTN_TOUCH}, /* Lock Mouse */ | ||
| 280 | {KE_KEY, 0x82, KEY_CAMERA}, | ||
| 281 | {KE_KEY, 0x8A, KEY_TV}, | ||
| 282 | {KE_KEY, 0x95, KEY_MEDIA}, | ||
| 283 | {KE_KEY, 0x99, KEY_PHONE}, | ||
| 284 | {KE_END, 0}, | ||
| 285 | }; | ||
| 286 | |||
| 253 | /* | 287 | /* |
| 254 | * This function evaluates an ACPI method, given an int as parameter, the | 288 | * This function evaluates an ACPI method, given an int as parameter, the |
| 255 | * method is searched within the scope of the handle, can be NULL. The output | 289 | * method is searched within the scope of the handle, can be NULL. The output |
| @@ -720,8 +754,68 @@ static ssize_t store_gps(struct device *dev, struct device_attribute *attr, | |||
| 720 | return store_status(buf, count, NULL, GPS_ON); | 754 | return store_status(buf, count, NULL, GPS_ON); |
| 721 | } | 755 | } |
| 722 | 756 | ||
| 757 | /* | ||
| 758 | * Hotkey functions | ||
| 759 | */ | ||
| 760 | static struct key_entry *asus_get_entry_by_scancode(int code) | ||
| 761 | { | ||
| 762 | struct key_entry *key; | ||
| 763 | |||
| 764 | for (key = asus_keymap; key->type != KE_END; key++) | ||
| 765 | if (code == key->code) | ||
| 766 | return key; | ||
| 767 | |||
| 768 | return NULL; | ||
| 769 | } | ||
| 770 | |||
| 771 | static struct key_entry *asus_get_entry_by_keycode(int code) | ||
| 772 | { | ||
| 773 | struct key_entry *key; | ||
| 774 | |||
| 775 | for (key = asus_keymap; key->type != KE_END; key++) | ||
| 776 | if (code == key->keycode && key->type == KE_KEY) | ||
| 777 | return key; | ||
| 778 | |||
| 779 | return NULL; | ||
| 780 | } | ||
| 781 | |||
| 782 | static int asus_getkeycode(struct input_dev *dev, int scancode, int *keycode) | ||
| 783 | { | ||
| 784 | struct key_entry *key = asus_get_entry_by_scancode(scancode); | ||
| 785 | |||
| 786 | if (key && key->type == KE_KEY) { | ||
| 787 | *keycode = key->keycode; | ||
| 788 | return 0; | ||
| 789 | } | ||
| 790 | |||
| 791 | return -EINVAL; | ||
| 792 | } | ||
| 793 | |||
| 794 | static int asus_setkeycode(struct input_dev *dev, int scancode, int keycode) | ||
| 795 | { | ||
| 796 | struct key_entry *key; | ||
| 797 | int old_keycode; | ||
| 798 | |||
| 799 | if (keycode < 0 || keycode > KEY_MAX) | ||
| 800 | return -EINVAL; | ||
| 801 | |||
| 802 | key = asus_get_entry_by_scancode(scancode); | ||
| 803 | if (key && key->type == KE_KEY) { | ||
| 804 | old_keycode = key->keycode; | ||
| 805 | key->keycode = keycode; | ||
| 806 | set_bit(keycode, dev->keybit); | ||
| 807 | if (!asus_get_entry_by_keycode(old_keycode)) | ||
| 808 | clear_bit(old_keycode, dev->keybit); | ||
| 809 | return 0; | ||
| 810 | } | ||
| 811 | |||
| 812 | return -EINVAL; | ||
| 813 | } | ||
| 814 | |||
| 723 | static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) | 815 | static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) |
| 724 | { | 816 | { |
| 817 | static struct key_entry *key; | ||
| 818 | |||
| 725 | /* TODO Find a better way to handle events count. */ | 819 | /* TODO Find a better way to handle events count. */ |
| 726 | if (!hotk) | 820 | if (!hotk) |
| 727 | return; | 821 | return; |
| @@ -738,10 +832,24 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) | |||
| 738 | lcd_blank(FB_BLANK_POWERDOWN); | 832 | lcd_blank(FB_BLANK_POWERDOWN); |
| 739 | } | 833 | } |
| 740 | 834 | ||
| 741 | acpi_bus_generate_proc_event(hotk->device, event, | 835 | acpi_bus_generate_netlink_event(hotk->device->pnp.device_class, |
| 742 | hotk->event_count[event % 128]++); | 836 | dev_name(&hotk->device->dev), event, |
| 743 | 837 | hotk->event_count[event % 128]++); | |
| 744 | return; | 838 | |
| 839 | if (hotk->inputdev) { | ||
| 840 | key = asus_get_entry_by_scancode(event); | ||
| 841 | if (!key) | ||
| 842 | return ; | ||
| 843 | |||
| 844 | switch (key->type) { | ||
| 845 | case KE_KEY: | ||
| 846 | input_report_key(hotk->inputdev, key->keycode, 1); | ||
| 847 | input_sync(hotk->inputdev); | ||
| 848 | input_report_key(hotk->inputdev, key->keycode, 0); | ||
| 849 | input_sync(hotk->inputdev); | ||
| 850 | break; | ||
| 851 | } | ||
| 852 | } | ||
| 745 | } | 853 | } |
| 746 | 854 | ||
| 747 | #define ASUS_CREATE_DEVICE_ATTR(_name) \ | 855 | #define ASUS_CREATE_DEVICE_ATTR(_name) \ |
| @@ -959,6 +1067,38 @@ static int asus_hotk_get_info(void) | |||
| 959 | return AE_OK; | 1067 | return AE_OK; |
| 960 | } | 1068 | } |
| 961 | 1069 | ||
| 1070 | static int asus_input_init(void) | ||
| 1071 | { | ||
| 1072 | const struct key_entry *key; | ||
| 1073 | int result; | ||
| 1074 | |||
| 1075 | hotk->inputdev = input_allocate_device(); | ||
| 1076 | if (!hotk->inputdev) { | ||
| 1077 | printk(ASUS_INFO "Unable to allocate input device\n"); | ||
| 1078 | return 0; | ||
| 1079 | } | ||
| 1080 | hotk->inputdev->name = "Asus Laptop extra buttons"; | ||
| 1081 | hotk->inputdev->phys = ASUS_HOTK_FILE "/input0"; | ||
| 1082 | hotk->inputdev->id.bustype = BUS_HOST; | ||
| 1083 | hotk->inputdev->getkeycode = asus_getkeycode; | ||
| 1084 | hotk->inputdev->setkeycode = asus_setkeycode; | ||
| 1085 | |||
| 1086 | for (key = asus_keymap; key->type != KE_END; key++) { | ||
| 1087 | switch (key->type) { | ||
| 1088 | case KE_KEY: | ||
| 1089 | set_bit(EV_KEY, hotk->inputdev->evbit); | ||
| 1090 | set_bit(key->keycode, hotk->inputdev->keybit); | ||
| 1091 | break; | ||
| 1092 | } | ||
| 1093 | } | ||
| 1094 | result = input_register_device(hotk->inputdev); | ||
| 1095 | if (result) { | ||
| 1096 | printk(ASUS_INFO "Unable to register input device\n"); | ||
| 1097 | input_free_device(hotk->inputdev); | ||
| 1098 | } | ||
| 1099 | return result; | ||
| 1100 | } | ||
| 1101 | |||
| 962 | static int asus_hotk_check(void) | 1102 | static int asus_hotk_check(void) |
| 963 | { | 1103 | { |
| 964 | int result = 0; | 1104 | int result = 0; |
| @@ -1044,7 +1184,7 @@ static int asus_hotk_add(struct acpi_device *device) | |||
| 1044 | /* GPS is on by default */ | 1184 | /* GPS is on by default */ |
| 1045 | write_status(NULL, 1, GPS_ON); | 1185 | write_status(NULL, 1, GPS_ON); |
| 1046 | 1186 | ||
| 1047 | end: | 1187 | end: |
| 1048 | if (result) { | 1188 | if (result) { |
| 1049 | kfree(hotk->name); | 1189 | kfree(hotk->name); |
| 1050 | kfree(hotk); | 1190 | kfree(hotk); |
| @@ -1091,10 +1231,17 @@ static void asus_led_exit(void) | |||
| 1091 | ASUS_LED_UNREGISTER(gled); | 1231 | ASUS_LED_UNREGISTER(gled); |
| 1092 | } | 1232 | } |
| 1093 | 1233 | ||
| 1234 | static void asus_input_exit(void) | ||
| 1235 | { | ||
| 1236 | if (hotk->inputdev) | ||
| 1237 | input_unregister_device(hotk->inputdev); | ||
| 1238 | } | ||
| 1239 | |||
| 1094 | static void __exit asus_laptop_exit(void) | 1240 | static void __exit asus_laptop_exit(void) |
| 1095 | { | 1241 | { |
| 1096 | asus_backlight_exit(); | 1242 | asus_backlight_exit(); |
| 1097 | asus_led_exit(); | 1243 | asus_led_exit(); |
| 1244 | asus_input_exit(); | ||
| 1098 | 1245 | ||
| 1099 | acpi_bus_unregister_driver(&asus_hotk_driver); | 1246 | acpi_bus_unregister_driver(&asus_hotk_driver); |
| 1100 | sysfs_remove_group(&asuspf_device->dev.kobj, &asuspf_attribute_group); | 1247 | sysfs_remove_group(&asuspf_device->dev.kobj, &asuspf_attribute_group); |
| @@ -1216,6 +1363,10 @@ static int __init asus_laptop_init(void) | |||
| 1216 | printk(ASUS_INFO "Brightness ignored, must be controlled by " | 1363 | printk(ASUS_INFO "Brightness ignored, must be controlled by " |
| 1217 | "ACPI video driver\n"); | 1364 | "ACPI video driver\n"); |
| 1218 | 1365 | ||
| 1366 | result = asus_input_init(); | ||
| 1367 | if (result) | ||
| 1368 | goto fail_input; | ||
| 1369 | |||
| 1219 | result = asus_led_init(dev); | 1370 | result = asus_led_init(dev); |
| 1220 | if (result) | 1371 | if (result) |
| 1221 | goto fail_led; | 1372 | goto fail_led; |
| @@ -1242,22 +1393,25 @@ static int __init asus_laptop_init(void) | |||
| 1242 | 1393 | ||
| 1243 | return 0; | 1394 | return 0; |
| 1244 | 1395 | ||
| 1245 | fail_sysfs: | 1396 | fail_sysfs: |
| 1246 | platform_device_del(asuspf_device); | 1397 | platform_device_del(asuspf_device); |
| 1247 | 1398 | ||
| 1248 | fail_platform_device2: | 1399 | fail_platform_device2: |
| 1249 | platform_device_put(asuspf_device); | 1400 | platform_device_put(asuspf_device); |
| 1250 | 1401 | ||
| 1251 | fail_platform_device1: | 1402 | fail_platform_device1: |
| 1252 | platform_driver_unregister(&asuspf_driver); | 1403 | platform_driver_unregister(&asuspf_driver); |
| 1253 | 1404 | ||
| 1254 | fail_platform_driver: | 1405 | fail_platform_driver: |
| 1255 | asus_led_exit(); | 1406 | asus_led_exit(); |
| 1256 | 1407 | ||
| 1257 | fail_led: | 1408 | fail_led: |
| 1409 | asus_input_exit(); | ||
| 1410 | |||
| 1411 | fail_input: | ||
| 1258 | asus_backlight_exit(); | 1412 | asus_backlight_exit(); |
| 1259 | 1413 | ||
| 1260 | fail_backlight: | 1414 | fail_backlight: |
| 1261 | 1415 | ||
| 1262 | return result; | 1416 | return result; |
| 1263 | } | 1417 | } |
diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c index 1e74988c7b2d..d63f26e666a4 100644 --- a/drivers/platform/x86/asus_acpi.c +++ b/drivers/platform/x86/asus_acpi.c | |||
| @@ -143,6 +143,7 @@ struct asus_hotk { | |||
| 143 | S1300N, S5200N*/ | 143 | S1300N, S5200N*/ |
| 144 | A4S, /* Z81sp */ | 144 | A4S, /* Z81sp */ |
| 145 | F3Sa, /* (Centrino) */ | 145 | F3Sa, /* (Centrino) */ |
| 146 | R1F, | ||
| 146 | END_MODEL | 147 | END_MODEL |
| 147 | } model; /* Models currently supported */ | 148 | } model; /* Models currently supported */ |
| 148 | u16 event_count[128]; /* Count for each event TODO make this better */ | 149 | u16 event_count[128]; /* Count for each event TODO make this better */ |
| @@ -420,7 +421,18 @@ static struct model_data model_conf[END_MODEL] = { | |||
| 420 | .display_get = "\\ADVG", | 421 | .display_get = "\\ADVG", |
| 421 | .display_set = "SDSP", | 422 | .display_set = "SDSP", |
| 422 | }, | 423 | }, |
| 423 | 424 | { | |
| 425 | .name = "R1F", | ||
| 426 | .mt_bt_switch = "BLED", | ||
| 427 | .mt_mled = "MLED", | ||
| 428 | .mt_wled = "WLED", | ||
| 429 | .mt_lcd_switch = "\\Q10", | ||
| 430 | .lcd_status = "\\GP06", | ||
| 431 | .brightness_set = "SPLV", | ||
| 432 | .brightness_get = "GPLV", | ||
| 433 | .display_set = "SDSP", | ||
| 434 | .display_get = "\\INFB" | ||
| 435 | } | ||
| 424 | }; | 436 | }; |
| 425 | 437 | ||
| 426 | /* procdir we use */ | 438 | /* procdir we use */ |
| @@ -1165,6 +1177,8 @@ static int asus_model_match(char *model) | |||
| 1165 | return W3V; | 1177 | return W3V; |
| 1166 | else if (strncmp(model, "W5A", 3) == 0) | 1178 | else if (strncmp(model, "W5A", 3) == 0) |
| 1167 | return W5A; | 1179 | return W5A; |
| 1180 | else if (strncmp(model, "R1F", 3) == 0) | ||
| 1181 | return R1F; | ||
| 1168 | else if (strncmp(model, "A4S", 3) == 0) | 1182 | else if (strncmp(model, "A4S", 3) == 0) |
| 1169 | return A4S; | 1183 | return A4S; |
| 1170 | else if (strncmp(model, "F3Sa", 4) == 0) | 1184 | else if (strncmp(model, "F3Sa", 4) == 0) |
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 9d93cb971e59..786ed8661cb0 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include <linux/uaccess.h> | 30 | #include <linux/uaccess.h> |
| 31 | #include <linux/input.h> | 31 | #include <linux/input.h> |
| 32 | #include <linux/rfkill.h> | 32 | #include <linux/rfkill.h> |
| 33 | #include <linux/pci.h> | ||
| 33 | 34 | ||
| 34 | #define EEEPC_LAPTOP_VERSION "0.1" | 35 | #define EEEPC_LAPTOP_VERSION "0.1" |
| 35 | 36 | ||
| @@ -161,6 +162,10 @@ static struct key_entry eeepc_keymap[] = { | |||
| 161 | {KE_KEY, 0x13, KEY_MUTE }, | 162 | {KE_KEY, 0x13, KEY_MUTE }, |
| 162 | {KE_KEY, 0x14, KEY_VOLUMEDOWN }, | 163 | {KE_KEY, 0x14, KEY_VOLUMEDOWN }, |
| 163 | {KE_KEY, 0x15, KEY_VOLUMEUP }, | 164 | {KE_KEY, 0x15, KEY_VOLUMEUP }, |
| 165 | {KE_KEY, 0x1a, KEY_COFFEE }, | ||
| 166 | {KE_KEY, 0x1b, KEY_ZOOM }, | ||
| 167 | {KE_KEY, 0x1c, KEY_PROG2 }, | ||
| 168 | {KE_KEY, 0x1d, KEY_PROG3 }, | ||
| 164 | {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE }, | 169 | {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE }, |
| 165 | {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE }, | 170 | {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE }, |
| 166 | {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE }, | 171 | {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE }, |
| @@ -510,7 +515,43 @@ static int eeepc_hotk_check(void) | |||
| 510 | static void notify_brn(void) | 515 | static void notify_brn(void) |
| 511 | { | 516 | { |
| 512 | struct backlight_device *bd = eeepc_backlight_device; | 517 | struct backlight_device *bd = eeepc_backlight_device; |
| 513 | bd->props.brightness = read_brightness(bd); | 518 | if (bd) |
| 519 | bd->props.brightness = read_brightness(bd); | ||
| 520 | } | ||
| 521 | |||
| 522 | static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) | ||
| 523 | { | ||
| 524 | struct pci_dev *dev; | ||
| 525 | struct pci_bus *bus = pci_find_bus(0, 1); | ||
| 526 | |||
| 527 | if (event != ACPI_NOTIFY_BUS_CHECK) | ||
| 528 | return; | ||
| 529 | |||
| 530 | if (!bus) { | ||
| 531 | printk(EEEPC_WARNING "Unable to find PCI bus 1?\n"); | ||
| 532 | return; | ||
| 533 | } | ||
| 534 | |||
| 535 | if (get_acpi(CM_ASL_WLAN) == 1) { | ||
| 536 | dev = pci_get_slot(bus, 0); | ||
| 537 | if (dev) { | ||
| 538 | /* Device already present */ | ||
| 539 | pci_dev_put(dev); | ||
| 540 | return; | ||
| 541 | } | ||
| 542 | dev = pci_scan_single_device(bus, 0); | ||
| 543 | if (dev) { | ||
| 544 | pci_bus_assign_resources(bus); | ||
| 545 | if (pci_bus_add_device(dev)) | ||
| 546 | printk(EEEPC_ERR "Unable to hotplug wifi\n"); | ||
| 547 | } | ||
| 548 | } else { | ||
| 549 | dev = pci_get_slot(bus, 0); | ||
| 550 | if (dev) { | ||
| 551 | pci_remove_bus_device(dev); | ||
| 552 | pci_dev_put(dev); | ||
| 553 | } | ||
| 554 | } | ||
| 514 | } | 555 | } |
| 515 | 556 | ||
| 516 | static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) | 557 | static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) |
| @@ -520,8 +561,9 @@ static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) | |||
| 520 | return; | 561 | return; |
| 521 | if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) | 562 | if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) |
| 522 | notify_brn(); | 563 | notify_brn(); |
| 523 | acpi_bus_generate_proc_event(ehotk->device, event, | 564 | acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class, |
| 524 | ehotk->event_count[event % 128]++); | 565 | dev_name(&ehotk->device->dev), event, |
| 566 | ehotk->event_count[event % 128]++); | ||
| 525 | if (ehotk->inputdev) { | 567 | if (ehotk->inputdev) { |
| 526 | key = eepc_get_entry_by_scancode(event); | 568 | key = eepc_get_entry_by_scancode(event); |
| 527 | if (key) { | 569 | if (key) { |
| @@ -539,6 +581,45 @@ static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) | |||
| 539 | } | 581 | } |
| 540 | } | 582 | } |
| 541 | 583 | ||
| 584 | static int eeepc_register_rfkill_notifier(char *node) | ||
| 585 | { | ||
| 586 | acpi_status status = AE_OK; | ||
| 587 | acpi_handle handle; | ||
| 588 | |||
| 589 | status = acpi_get_handle(NULL, node, &handle); | ||
| 590 | |||
| 591 | if (ACPI_SUCCESS(status)) { | ||
| 592 | status = acpi_install_notify_handler(handle, | ||
| 593 | ACPI_SYSTEM_NOTIFY, | ||
| 594 | eeepc_rfkill_notify, | ||
| 595 | NULL); | ||
| 596 | if (ACPI_FAILURE(status)) | ||
| 597 | printk(EEEPC_WARNING | ||
| 598 | "Failed to register notify on %s\n", node); | ||
| 599 | } else | ||
| 600 | return -ENODEV; | ||
| 601 | |||
| 602 | return 0; | ||
| 603 | } | ||
| 604 | |||
| 605 | static void eeepc_unregister_rfkill_notifier(char *node) | ||
| 606 | { | ||
| 607 | acpi_status status = AE_OK; | ||
| 608 | acpi_handle handle; | ||
| 609 | |||
| 610 | status = acpi_get_handle(NULL, node, &handle); | ||
| 611 | |||
| 612 | if (ACPI_SUCCESS(status)) { | ||
| 613 | status = acpi_remove_notify_handler(handle, | ||
| 614 | ACPI_SYSTEM_NOTIFY, | ||
| 615 | eeepc_rfkill_notify); | ||
| 616 | if (ACPI_FAILURE(status)) | ||
| 617 | printk(EEEPC_ERR | ||
| 618 | "Error removing rfkill notify handler %s\n", | ||
| 619 | node); | ||
| 620 | } | ||
| 621 | } | ||
| 622 | |||
| 542 | static int eeepc_hotk_add(struct acpi_device *device) | 623 | static int eeepc_hotk_add(struct acpi_device *device) |
| 543 | { | 624 | { |
| 544 | acpi_status status = AE_OK; | 625 | acpi_status status = AE_OK; |
| @@ -558,7 +639,7 @@ static int eeepc_hotk_add(struct acpi_device *device) | |||
| 558 | ehotk->device = device; | 639 | ehotk->device = device; |
| 559 | result = eeepc_hotk_check(); | 640 | result = eeepc_hotk_check(); |
| 560 | if (result) | 641 | if (result) |
| 561 | goto end; | 642 | goto ehotk_fail; |
| 562 | status = acpi_install_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY, | 643 | status = acpi_install_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY, |
| 563 | eeepc_hotk_notify, ehotk); | 644 | eeepc_hotk_notify, ehotk); |
| 564 | if (ACPI_FAILURE(status)) | 645 | if (ACPI_FAILURE(status)) |
| @@ -569,18 +650,25 @@ static int eeepc_hotk_add(struct acpi_device *device) | |||
| 569 | RFKILL_TYPE_WLAN); | 650 | RFKILL_TYPE_WLAN); |
| 570 | 651 | ||
| 571 | if (!ehotk->eeepc_wlan_rfkill) | 652 | if (!ehotk->eeepc_wlan_rfkill) |
| 572 | goto end; | 653 | goto wlan_fail; |
| 573 | 654 | ||
| 574 | ehotk->eeepc_wlan_rfkill->name = "eeepc-wlan"; | 655 | ehotk->eeepc_wlan_rfkill->name = "eeepc-wlan"; |
| 575 | ehotk->eeepc_wlan_rfkill->toggle_radio = eeepc_wlan_rfkill_set; | 656 | ehotk->eeepc_wlan_rfkill->toggle_radio = eeepc_wlan_rfkill_set; |
| 576 | ehotk->eeepc_wlan_rfkill->get_state = eeepc_wlan_rfkill_state; | 657 | ehotk->eeepc_wlan_rfkill->get_state = eeepc_wlan_rfkill_state; |
| 577 | if (get_acpi(CM_ASL_WLAN) == 1) | 658 | if (get_acpi(CM_ASL_WLAN) == 1) { |
| 578 | ehotk->eeepc_wlan_rfkill->state = | 659 | ehotk->eeepc_wlan_rfkill->state = |
| 579 | RFKILL_STATE_UNBLOCKED; | 660 | RFKILL_STATE_UNBLOCKED; |
| 580 | else | 661 | rfkill_set_default(RFKILL_TYPE_WLAN, |
| 662 | RFKILL_STATE_UNBLOCKED); | ||
| 663 | } else { | ||
| 581 | ehotk->eeepc_wlan_rfkill->state = | 664 | ehotk->eeepc_wlan_rfkill->state = |
| 582 | RFKILL_STATE_SOFT_BLOCKED; | 665 | RFKILL_STATE_SOFT_BLOCKED; |
| 583 | rfkill_register(ehotk->eeepc_wlan_rfkill); | 666 | rfkill_set_default(RFKILL_TYPE_WLAN, |
| 667 | RFKILL_STATE_SOFT_BLOCKED); | ||
| 668 | } | ||
| 669 | result = rfkill_register(ehotk->eeepc_wlan_rfkill); | ||
| 670 | if (result) | ||
| 671 | goto wlan_fail; | ||
| 584 | } | 672 | } |
| 585 | 673 | ||
| 586 | if (get_acpi(CM_ASL_BLUETOOTH) != -1) { | 674 | if (get_acpi(CM_ASL_BLUETOOTH) != -1) { |
| @@ -588,27 +676,47 @@ static int eeepc_hotk_add(struct acpi_device *device) | |||
| 588 | rfkill_allocate(&device->dev, RFKILL_TYPE_BLUETOOTH); | 676 | rfkill_allocate(&device->dev, RFKILL_TYPE_BLUETOOTH); |
| 589 | 677 | ||
| 590 | if (!ehotk->eeepc_bluetooth_rfkill) | 678 | if (!ehotk->eeepc_bluetooth_rfkill) |
| 591 | goto end; | 679 | goto bluetooth_fail; |
| 592 | 680 | ||
| 593 | ehotk->eeepc_bluetooth_rfkill->name = "eeepc-bluetooth"; | 681 | ehotk->eeepc_bluetooth_rfkill->name = "eeepc-bluetooth"; |
| 594 | ehotk->eeepc_bluetooth_rfkill->toggle_radio = | 682 | ehotk->eeepc_bluetooth_rfkill->toggle_radio = |
| 595 | eeepc_bluetooth_rfkill_set; | 683 | eeepc_bluetooth_rfkill_set; |
| 596 | ehotk->eeepc_bluetooth_rfkill->get_state = | 684 | ehotk->eeepc_bluetooth_rfkill->get_state = |
| 597 | eeepc_bluetooth_rfkill_state; | 685 | eeepc_bluetooth_rfkill_state; |
| 598 | if (get_acpi(CM_ASL_BLUETOOTH) == 1) | 686 | if (get_acpi(CM_ASL_BLUETOOTH) == 1) { |
| 599 | ehotk->eeepc_bluetooth_rfkill->state = | 687 | ehotk->eeepc_bluetooth_rfkill->state = |
| 600 | RFKILL_STATE_UNBLOCKED; | 688 | RFKILL_STATE_UNBLOCKED; |
| 601 | else | 689 | rfkill_set_default(RFKILL_TYPE_BLUETOOTH, |
| 690 | RFKILL_STATE_UNBLOCKED); | ||
| 691 | } else { | ||
| 602 | ehotk->eeepc_bluetooth_rfkill->state = | 692 | ehotk->eeepc_bluetooth_rfkill->state = |
| 603 | RFKILL_STATE_SOFT_BLOCKED; | 693 | RFKILL_STATE_SOFT_BLOCKED; |
| 604 | rfkill_register(ehotk->eeepc_bluetooth_rfkill); | 694 | rfkill_set_default(RFKILL_TYPE_BLUETOOTH, |
| 605 | } | 695 | RFKILL_STATE_SOFT_BLOCKED); |
| 696 | } | ||
| 606 | 697 | ||
| 607 | end: | 698 | result = rfkill_register(ehotk->eeepc_bluetooth_rfkill); |
| 608 | if (result) { | 699 | if (result) |
| 609 | kfree(ehotk); | 700 | goto bluetooth_fail; |
| 610 | ehotk = NULL; | ||
| 611 | } | 701 | } |
| 702 | |||
| 703 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); | ||
| 704 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); | ||
| 705 | |||
| 706 | return 0; | ||
| 707 | |||
| 708 | bluetooth_fail: | ||
| 709 | if (ehotk->eeepc_bluetooth_rfkill) | ||
| 710 | rfkill_free(ehotk->eeepc_bluetooth_rfkill); | ||
| 711 | rfkill_unregister(ehotk->eeepc_wlan_rfkill); | ||
| 712 | ehotk->eeepc_wlan_rfkill = NULL; | ||
| 713 | wlan_fail: | ||
| 714 | if (ehotk->eeepc_wlan_rfkill) | ||
| 715 | rfkill_free(ehotk->eeepc_wlan_rfkill); | ||
| 716 | ehotk_fail: | ||
| 717 | kfree(ehotk); | ||
| 718 | ehotk = NULL; | ||
| 719 | |||
| 612 | return result; | 720 | return result; |
| 613 | } | 721 | } |
| 614 | 722 | ||
| @@ -622,6 +730,10 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type) | |||
| 622 | eeepc_hotk_notify); | 730 | eeepc_hotk_notify); |
| 623 | if (ACPI_FAILURE(status)) | 731 | if (ACPI_FAILURE(status)) |
| 624 | printk(EEEPC_ERR "Error removing notify handler\n"); | 732 | printk(EEEPC_ERR "Error removing notify handler\n"); |
| 733 | |||
| 734 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); | ||
| 735 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); | ||
| 736 | |||
| 625 | kfree(ehotk); | 737 | kfree(ehotk); |
| 626 | return 0; | 738 | return 0; |
| 627 | } | 739 | } |
| @@ -737,13 +849,21 @@ static void eeepc_backlight_exit(void) | |||
| 737 | { | 849 | { |
| 738 | if (eeepc_backlight_device) | 850 | if (eeepc_backlight_device) |
| 739 | backlight_device_unregister(eeepc_backlight_device); | 851 | backlight_device_unregister(eeepc_backlight_device); |
| 740 | if (ehotk->inputdev) | 852 | eeepc_backlight_device = NULL; |
| 741 | input_unregister_device(ehotk->inputdev); | 853 | } |
| 854 | |||
| 855 | static void eeepc_rfkill_exit(void) | ||
| 856 | { | ||
| 742 | if (ehotk->eeepc_wlan_rfkill) | 857 | if (ehotk->eeepc_wlan_rfkill) |
| 743 | rfkill_unregister(ehotk->eeepc_wlan_rfkill); | 858 | rfkill_unregister(ehotk->eeepc_wlan_rfkill); |
| 744 | if (ehotk->eeepc_bluetooth_rfkill) | 859 | if (ehotk->eeepc_bluetooth_rfkill) |
| 745 | rfkill_unregister(ehotk->eeepc_bluetooth_rfkill); | 860 | rfkill_unregister(ehotk->eeepc_bluetooth_rfkill); |
| 746 | eeepc_backlight_device = NULL; | 861 | } |
| 862 | |||
| 863 | static void eeepc_input_exit(void) | ||
| 864 | { | ||
| 865 | if (ehotk->inputdev) | ||
| 866 | input_unregister_device(ehotk->inputdev); | ||
| 747 | } | 867 | } |
| 748 | 868 | ||
| 749 | static void eeepc_hwmon_exit(void) | 869 | static void eeepc_hwmon_exit(void) |
| @@ -762,6 +882,8 @@ static void eeepc_hwmon_exit(void) | |||
| 762 | static void __exit eeepc_laptop_exit(void) | 882 | static void __exit eeepc_laptop_exit(void) |
| 763 | { | 883 | { |
| 764 | eeepc_backlight_exit(); | 884 | eeepc_backlight_exit(); |
| 885 | eeepc_rfkill_exit(); | ||
| 886 | eeepc_input_exit(); | ||
| 765 | eeepc_hwmon_exit(); | 887 | eeepc_hwmon_exit(); |
| 766 | acpi_bus_unregister_driver(&eeepc_hotk_driver); | 888 | acpi_bus_unregister_driver(&eeepc_hotk_driver); |
| 767 | sysfs_remove_group(&platform_device->dev.kobj, | 889 | sysfs_remove_group(&platform_device->dev.kobj, |
| @@ -865,6 +987,8 @@ fail_platform_driver: | |||
| 865 | fail_hwmon: | 987 | fail_hwmon: |
| 866 | eeepc_backlight_exit(); | 988 | eeepc_backlight_exit(); |
| 867 | fail_backlight: | 989 | fail_backlight: |
| 990 | eeepc_input_exit(); | ||
| 991 | eeepc_rfkill_exit(); | ||
| 868 | return result; | 992 | return result; |
| 869 | } | 993 | } |
| 870 | 994 | ||
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index de91ddab0a86..f41135f2fb29 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c | |||
| @@ -463,9 +463,11 @@ static int __init hp_wmi_bios_setup(struct platform_device *device) | |||
| 463 | 463 | ||
| 464 | return 0; | 464 | return 0; |
| 465 | register_wwan_err: | 465 | register_wwan_err: |
| 466 | rfkill_unregister(bluetooth_rfkill); | 466 | if (bluetooth_rfkill) |
| 467 | rfkill_unregister(bluetooth_rfkill); | ||
| 467 | register_bluetooth_error: | 468 | register_bluetooth_error: |
| 468 | rfkill_unregister(wifi_rfkill); | 469 | if (wifi_rfkill) |
| 470 | rfkill_unregister(wifi_rfkill); | ||
| 469 | add_sysfs_error: | 471 | add_sysfs_error: |
| 470 | cleanup_sysfs(device); | 472 | cleanup_sysfs(device); |
| 471 | return err; | 473 | return err; |
diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c index f30db367c82e..c47a44dcb702 100644 --- a/drivers/platform/x86/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c | |||
| @@ -507,7 +507,7 @@ static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc) | |||
| 507 | 507 | ||
| 508 | hkey_num = result & 0xf; | 508 | hkey_num = result & 0xf; |
| 509 | 509 | ||
| 510 | if (hkey_num < 0 || hkey_num > ARRAY_SIZE(pcc->keymap)) { | 510 | if (hkey_num < 0 || hkey_num >= ARRAY_SIZE(pcc->keymap)) { |
| 511 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 511 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
| 512 | "hotkey number out of range: %d\n", | 512 | "hotkey number out of range: %d\n", |
| 513 | hkey_num)); | 513 | hkey_num)); |
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index cced4d108319..81450fbd8b12 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
| @@ -241,6 +241,12 @@ config RTC_DRV_M41T80_WDT | |||
| 241 | If you say Y here you will get support for the | 241 | If you say Y here you will get support for the |
| 242 | watchdog timer in the ST M41T60 and M41T80 RTC chips series. | 242 | watchdog timer in the ST M41T60 and M41T80 RTC chips series. |
| 243 | 243 | ||
| 244 | config RTC_DRV_DM355EVM | ||
| 245 | tristate "TI DaVinci DM355 EVM RTC" | ||
| 246 | depends on MFD_DM355EVM_MSP | ||
| 247 | help | ||
| 248 | Supports the RTC firmware in the MSP430 on the DM355 EVM. | ||
| 249 | |||
| 244 | config RTC_DRV_TWL92330 | 250 | config RTC_DRV_TWL92330 |
| 245 | boolean "TI TWL92330/Menelaus" | 251 | boolean "TI TWL92330/Menelaus" |
| 246 | depends on MENELAUS | 252 | depends on MENELAUS |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 6e28021abb9d..0e697aa51caa 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
| @@ -23,6 +23,7 @@ obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o | |||
| 23 | obj-$(CONFIG_RTC_DRV_AU1XXX) += rtc-au1xxx.o | 23 | obj-$(CONFIG_RTC_DRV_AU1XXX) += rtc-au1xxx.o |
| 24 | obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o | 24 | obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o |
| 25 | obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o | 25 | obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o |
| 26 | obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o | ||
| 26 | obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o | 27 | obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o |
| 27 | obj-$(CONFIG_RTC_DRV_DS1286) += rtc-ds1286.o | 28 | obj-$(CONFIG_RTC_DRV_DS1286) += rtc-ds1286.o |
| 28 | obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o | 29 | obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o |
diff --git a/drivers/rtc/rtc-dm355evm.c b/drivers/rtc/rtc-dm355evm.c new file mode 100644 index 000000000000..58d4e18530da --- /dev/null +++ b/drivers/rtc/rtc-dm355evm.c | |||
| @@ -0,0 +1,175 @@ | |||
| 1 | /* | ||
| 2 | * rtc-dm355evm.c - access battery-backed counter in MSP430 firmware | ||
| 3 | * | ||
| 4 | * Copyright (c) 2008 by David Brownell | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License | ||
| 8 | * as published by the Free Software Foundation; either version | ||
| 9 | * 2 of the License, or (at your option) any later version. | ||
| 10 | */ | ||
| 11 | #include <linux/kernel.h> | ||
| 12 | #include <linux/init.h> | ||
| 13 | #include <linux/rtc.h> | ||
| 14 | #include <linux/platform_device.h> | ||
| 15 | |||
| 16 | #include <linux/i2c/dm355evm_msp.h> | ||
| 17 | |||
| 18 | |||
| 19 | /* | ||
| 20 | * The MSP430 firmware on the DM355 EVM uses a watch crystal to feed | ||
| 21 | * a 1 Hz counter. When a backup battery is supplied, that makes a | ||
| 22 | * reasonable RTC for applications where alarms and non-NTP drift | ||
| 23 | * compensation aren't important. | ||
| 24 | * | ||
| 25 | * The only real glitch is the inability to read or write all four | ||
| 26 | * counter bytes atomically: the count may increment in the middle | ||
| 27 | * of an operation, causing trouble when the LSB rolls over. | ||
| 28 | * | ||
| 29 | * This driver was tested with firmware revision A4. | ||
| 30 | */ | ||
| 31 | union evm_time { | ||
| 32 | u8 bytes[4]; | ||
| 33 | u32 value; | ||
| 34 | }; | ||
| 35 | |||
| 36 | static int dm355evm_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
| 37 | { | ||
| 38 | union evm_time time; | ||
| 39 | int status; | ||
| 40 | int tries = 0; | ||
| 41 | |||
| 42 | do { | ||
| 43 | /* | ||
| 44 | * Read LSB(0) to MSB(3) bytes. Defend against the counter | ||
| 45 | * rolling over by re-reading until the value is stable, | ||
| 46 | * and assuming the four reads take at most a few seconds. | ||
| 47 | */ | ||
| 48 | status = dm355evm_msp_read(DM355EVM_MSP_RTC_0); | ||
| 49 | if (status < 0) | ||
| 50 | return status; | ||
| 51 | if (tries && time.bytes[0] == status) | ||
| 52 | break; | ||
| 53 | time.bytes[0] = status; | ||
| 54 | |||
| 55 | status = dm355evm_msp_read(DM355EVM_MSP_RTC_1); | ||
| 56 | if (status < 0) | ||
| 57 | return status; | ||
| 58 | if (tries && time.bytes[1] == status) | ||
| 59 | break; | ||
| 60 | time.bytes[1] = status; | ||
| 61 | |||
| 62 | status = dm355evm_msp_read(DM355EVM_MSP_RTC_2); | ||
| 63 | if (status < 0) | ||
| 64 | return status; | ||
| 65 | if (tries && time.bytes[2] == status) | ||
| 66 | break; | ||
| 67 | time.bytes[2] = status; | ||
| 68 | |||
| 69 | status = dm355evm_msp_read(DM355EVM_MSP_RTC_3); | ||
| 70 | if (status < 0) | ||
| 71 | return status; | ||
| 72 | if (tries && time.bytes[3] == status) | ||
| 73 | break; | ||
| 74 | time.bytes[3] = status; | ||
| 75 | |||
| 76 | } while (++tries < 5); | ||
| 77 | |||
| 78 | dev_dbg(dev, "read timestamp %08x\n", time.value); | ||
| 79 | |||
| 80 | rtc_time_to_tm(le32_to_cpu(time.value), tm); | ||
| 81 | return 0; | ||
| 82 | } | ||
| 83 | |||
| 84 | static int dm355evm_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
| 85 | { | ||
| 86 | union evm_time time; | ||
| 87 | unsigned long value; | ||
| 88 | int status; | ||
| 89 | |||
| 90 | rtc_tm_to_time(tm, &value); | ||
| 91 | time.value = cpu_to_le32(value); | ||
| 92 | |||
| 93 | dev_dbg(dev, "write timestamp %08x\n", time.value); | ||
| 94 | |||
| 95 | /* | ||
| 96 | * REVISIT handle non-atomic writes ... maybe just retry until | ||
| 97 | * byte[1] sticks (no rollover)? | ||
| 98 | */ | ||
| 99 | status = dm355evm_msp_write(time.bytes[0], DM355EVM_MSP_RTC_0); | ||
| 100 | if (status < 0) | ||
| 101 | return status; | ||
| 102 | |||
| 103 | status = dm355evm_msp_write(time.bytes[1], DM355EVM_MSP_RTC_1); | ||
| 104 | if (status < 0) | ||
| 105 | return status; | ||
| 106 | |||
| 107 | status = dm355evm_msp_write(time.bytes[2], DM355EVM_MSP_RTC_2); | ||
| 108 | if (status < 0) | ||
| 109 | return status; | ||
| 110 | |||
| 111 | status = dm355evm_msp_write(time.bytes[3], DM355EVM_MSP_RTC_3); | ||
| 112 | if (status < 0) | ||
| 113 | return status; | ||
| 114 | |||
| 115 | return 0; | ||
| 116 | } | ||
| 117 | |||
| 118 | static struct rtc_class_ops dm355evm_rtc_ops = { | ||
| 119 | .read_time = dm355evm_rtc_read_time, | ||
| 120 | .set_time = dm355evm_rtc_set_time, | ||
| 121 | }; | ||
| 122 | |||
| 123 | /*----------------------------------------------------------------------*/ | ||
| 124 | |||
| 125 | static int __devinit dm355evm_rtc_probe(struct platform_device *pdev) | ||
| 126 | { | ||
| 127 | struct rtc_device *rtc; | ||
| 128 | |||
| 129 | rtc = rtc_device_register(pdev->name, | ||
| 130 | &pdev->dev, &dm355evm_rtc_ops, THIS_MODULE); | ||
| 131 | if (IS_ERR(rtc)) { | ||
| 132 | dev_err(&pdev->dev, "can't register RTC device, err %ld\n", | ||
| 133 | PTR_ERR(rtc)); | ||
| 134 | return PTR_ERR(rtc); | ||
| 135 | } | ||
| 136 | platform_set_drvdata(pdev, rtc); | ||
| 137 | |||
| 138 | return 0; | ||
| 139 | } | ||
| 140 | |||
| 141 | static int __devexit dm355evm_rtc_remove(struct platform_device *pdev) | ||
| 142 | { | ||
| 143 | struct rtc_device *rtc = platform_get_drvdata(pdev); | ||
| 144 | |||
| 145 | rtc_device_unregister(rtc); | ||
| 146 | platform_set_drvdata(pdev, NULL); | ||
| 147 | return 0; | ||
| 148 | } | ||
| 149 | |||
| 150 | /* | ||
| 151 | * I2C is used to talk to the MSP430, but this platform device is | ||
| 152 | * exposed by an MFD driver that manages I2C communications. | ||
| 153 | */ | ||
| 154 | static struct platform_driver rtc_dm355evm_driver = { | ||
| 155 | .probe = dm355evm_rtc_probe, | ||
| 156 | .remove = __devexit_p(dm355evm_rtc_remove), | ||
| 157 | .driver = { | ||
| 158 | .owner = THIS_MODULE, | ||
| 159 | .name = "rtc-dm355evm", | ||
| 160 | }, | ||
| 161 | }; | ||
| 162 | |||
| 163 | static int __init dm355evm_rtc_init(void) | ||
| 164 | { | ||
| 165 | return platform_driver_register(&rtc_dm355evm_driver); | ||
| 166 | } | ||
| 167 | module_init(dm355evm_rtc_init); | ||
| 168 | |||
| 169 | static void __exit dm355evm_rtc_exit(void) | ||
| 170 | { | ||
| 171 | platform_driver_unregister(&rtc_dm355evm_driver); | ||
| 172 | } | ||
| 173 | module_exit(dm355evm_rtc_exit); | ||
| 174 | |||
| 175 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-ds1390.c b/drivers/rtc/rtc-ds1390.c index e54b5c619bdf..e01b955db077 100644 --- a/drivers/rtc/rtc-ds1390.c +++ b/drivers/rtc/rtc-ds1390.c | |||
| @@ -122,7 +122,6 @@ static const struct rtc_class_ops ds1390_rtc_ops = { | |||
| 122 | 122 | ||
| 123 | static int __devinit ds1390_probe(struct spi_device *spi) | 123 | static int __devinit ds1390_probe(struct spi_device *spi) |
| 124 | { | 124 | { |
| 125 | struct rtc_device *rtc; | ||
| 126 | unsigned char tmp; | 125 | unsigned char tmp; |
| 127 | struct ds1390 *chip; | 126 | struct ds1390 *chip; |
| 128 | int res; | 127 | int res; |
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index db16112cf197..e6e299feb51b 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c | |||
| @@ -1475,7 +1475,7 @@ static int aty128fb_set_par(struct fb_info *info) | |||
| 1475 | aty128_set_pll(&par->pll, par); | 1475 | aty128_set_pll(&par->pll, par); |
| 1476 | aty128_set_fifo(&par->fifo_reg, par); | 1476 | aty128_set_fifo(&par->fifo_reg, par); |
| 1477 | 1477 | ||
| 1478 | config = aty_ld_le32(CONFIG_CNTL) & ~3; | 1478 | config = aty_ld_le32(CNFG_CNTL) & ~3; |
| 1479 | 1479 | ||
| 1480 | #if defined(__BIG_ENDIAN) | 1480 | #if defined(__BIG_ENDIAN) |
| 1481 | if (par->crtc.bpp == 32) | 1481 | if (par->crtc.bpp == 32) |
| @@ -1484,7 +1484,7 @@ static int aty128fb_set_par(struct fb_info *info) | |||
| 1484 | config |= 1; /* make aperture do 16 bit swapping */ | 1484 | config |= 1; /* make aperture do 16 bit swapping */ |
| 1485 | #endif | 1485 | #endif |
| 1486 | 1486 | ||
| 1487 | aty_st_le32(CONFIG_CNTL, config); | 1487 | aty_st_le32(CNFG_CNTL, config); |
| 1488 | aty_st_8(CRTC_EXT_CNTL + 1, 0); /* turn the video back on */ | 1488 | aty_st_8(CRTC_EXT_CNTL + 1, 0); /* turn the video back on */ |
| 1489 | 1489 | ||
| 1490 | info->fix.line_length = (par->crtc.vxres * par->crtc.bpp) >> 3; | 1490 | info->fix.line_length = (par->crtc.vxres * par->crtc.bpp) >> 3; |
| @@ -1875,7 +1875,7 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i | |||
| 1875 | u32 dac; | 1875 | u32 dac; |
| 1876 | 1876 | ||
| 1877 | /* Get the chip revision */ | 1877 | /* Get the chip revision */ |
| 1878 | chip_rev = (aty_ld_le32(CONFIG_CNTL) >> 16) & 0x1F; | 1878 | chip_rev = (aty_ld_le32(CNFG_CNTL) >> 16) & 0x1F; |
| 1879 | 1879 | ||
| 1880 | strcpy(video_card, "Rage128 XX "); | 1880 | strcpy(video_card, "Rage128 XX "); |
| 1881 | video_card[8] = ent->device >> 8; | 1881 | video_card[8] = ent->device >> 8; |
| @@ -2057,7 +2057,7 @@ static int __devinit aty128_probe(struct pci_dev *pdev, const struct pci_device_ | |||
| 2057 | 2057 | ||
| 2058 | /* Grab memory size from the card */ | 2058 | /* Grab memory size from the card */ |
| 2059 | // How does this relate to the resource length from the PCI hardware? | 2059 | // How does this relate to the resource length from the PCI hardware? |
| 2060 | par->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF; | 2060 | par->vram_size = aty_ld_le32(CNFG_MEMSIZE) & 0x03FFFFFF; |
| 2061 | 2061 | ||
| 2062 | /* Virtualize the framebuffer */ | 2062 | /* Virtualize the framebuffer */ |
| 2063 | info->screen_base = ioremap(fb_addr, par->vram_size); | 2063 | info->screen_base = ioremap(fb_addr, par->vram_size); |
| @@ -2374,6 +2374,8 @@ static void aty128_set_suspend(struct aty128fb_par *par, int suspend) | |||
| 2374 | /* Set the chip into the appropriate suspend mode (we use D2, | 2374 | /* Set the chip into the appropriate suspend mode (we use D2, |
| 2375 | * D3 would require a complete re-initialisation of the chip, | 2375 | * D3 would require a complete re-initialisation of the chip, |
| 2376 | * including PCI config registers, clocks, AGP configuration, ...) | 2376 | * including PCI config registers, clocks, AGP configuration, ...) |
| 2377 | * | ||
| 2378 | * For resume, the core will have already brought us back to D0 | ||
| 2377 | */ | 2379 | */ |
| 2378 | if (suspend) { | 2380 | if (suspend) { |
| 2379 | /* Make sure CRTC2 is reset. Remove that the day we decide to | 2381 | /* Make sure CRTC2 is reset. Remove that the day we decide to |
| @@ -2391,17 +2393,9 @@ static void aty128_set_suspend(struct aty128fb_par *par, int suspend) | |||
| 2391 | aty_st_le32(BUS_CNTL1, 0x00000010); | 2393 | aty_st_le32(BUS_CNTL1, 0x00000010); |
| 2392 | aty_st_le32(MEM_POWER_MISC, 0x0c830000); | 2394 | aty_st_le32(MEM_POWER_MISC, 0x0c830000); |
| 2393 | mdelay(100); | 2395 | mdelay(100); |
| 2394 | pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command); | 2396 | |
| 2395 | /* Switch PCI power management to D2 */ | 2397 | /* Switch PCI power management to D2 */ |
| 2396 | pci_write_config_word(pdev, par->pm_reg+PCI_PM_CTRL, | 2398 | pci_set_power_state(pdev, PCI_D2); |
| 2397 | (pwr_command & ~PCI_PM_CTRL_STATE_MASK) | 2); | ||
| 2398 | pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command); | ||
| 2399 | } else { | ||
| 2400 | /* Switch back PCI power management to D0 */ | ||
| 2401 | mdelay(100); | ||
| 2402 | pci_write_config_word(pdev, par->pm_reg+PCI_PM_CTRL, 0); | ||
| 2403 | pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command); | ||
| 2404 | mdelay(100); | ||
| 2405 | } | 2399 | } |
| 2406 | } | 2400 | } |
| 2407 | 2401 | ||
| @@ -2410,6 +2404,12 @@ static int aty128_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
| 2410 | struct fb_info *info = pci_get_drvdata(pdev); | 2404 | struct fb_info *info = pci_get_drvdata(pdev); |
| 2411 | struct aty128fb_par *par = info->par; | 2405 | struct aty128fb_par *par = info->par; |
| 2412 | 2406 | ||
| 2407 | /* Because we may change PCI D state ourselves, we need to | ||
| 2408 | * first save the config space content so the core can | ||
| 2409 | * restore it properly on resume. | ||
| 2410 | */ | ||
| 2411 | pci_save_state(pdev); | ||
| 2412 | |||
| 2413 | /* We don't do anything but D2, for now we return 0, but | 2413 | /* We don't do anything but D2, for now we return 0, but |
| 2414 | * we may want to change that. How do we know if the BIOS | 2414 | * we may want to change that. How do we know if the BIOS |
| 2415 | * can properly take care of D3 ? Also, with swsusp, we | 2415 | * can properly take care of D3 ? Also, with swsusp, we |
| @@ -2476,6 +2476,11 @@ static int aty128_do_resume(struct pci_dev *pdev) | |||
| 2476 | if (pdev->dev.power.power_state.event == PM_EVENT_ON) | 2476 | if (pdev->dev.power.power_state.event == PM_EVENT_ON) |
| 2477 | return 0; | 2477 | return 0; |
| 2478 | 2478 | ||
| 2479 | /* PCI state will have been restored by the core, so | ||
| 2480 | * we should be in D0 now with our config space fully | ||
| 2481 | * restored | ||
| 2482 | */ | ||
| 2483 | |||
| 2479 | /* Wakeup chip */ | 2484 | /* Wakeup chip */ |
| 2480 | aty128_set_suspend(par, 0); | 2485 | aty128_set_suspend(par, 0); |
| 2481 | par->asleep = 0; | 2486 | par->asleep = 0; |
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index cc6b470073da..1207c208a30b 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c | |||
| @@ -135,7 +135,7 @@ | |||
| 135 | #if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || \ | 135 | #if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || \ |
| 136 | defined (CONFIG_FB_ATY_GENERIC_LCD) || defined(CONFIG_FB_ATY_BACKLIGHT) | 136 | defined (CONFIG_FB_ATY_GENERIC_LCD) || defined(CONFIG_FB_ATY_BACKLIGHT) |
| 137 | static const u32 lt_lcd_regs[] = { | 137 | static const u32 lt_lcd_regs[] = { |
| 138 | CONFIG_PANEL_LG, | 138 | CNFG_PANEL_LG, |
| 139 | LCD_GEN_CNTL_LG, | 139 | LCD_GEN_CNTL_LG, |
| 140 | DSTN_CONTROL_LG, | 140 | DSTN_CONTROL_LG, |
| 141 | HFB_PITCH_ADDR_LG, | 141 | HFB_PITCH_ADDR_LG, |
| @@ -446,7 +446,7 @@ static int __devinit correct_chipset(struct atyfb_par *par) | |||
| 446 | par->pll_limits.ecp_max = aty_chips[i].ecp_max; | 446 | par->pll_limits.ecp_max = aty_chips[i].ecp_max; |
| 447 | par->features = aty_chips[i].features; | 447 | par->features = aty_chips[i].features; |
| 448 | 448 | ||
| 449 | chip_id = aty_ld_le32(CONFIG_CHIP_ID, par); | 449 | chip_id = aty_ld_le32(CNFG_CHIP_ID, par); |
| 450 | type = chip_id & CFG_CHIP_TYPE; | 450 | type = chip_id & CFG_CHIP_TYPE; |
| 451 | rev = (chip_id & CFG_CHIP_REV) >> 24; | 451 | rev = (chip_id & CFG_CHIP_REV) >> 24; |
| 452 | 452 | ||
| @@ -629,7 +629,7 @@ static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc) | |||
| 629 | crtc->lcd_index = aty_ld_le32(LCD_INDEX, par); | 629 | crtc->lcd_index = aty_ld_le32(LCD_INDEX, par); |
| 630 | aty_st_le32(LCD_INDEX, crtc->lcd_index, par); | 630 | aty_st_le32(LCD_INDEX, crtc->lcd_index, par); |
| 631 | } | 631 | } |
| 632 | crtc->lcd_config_panel = aty_ld_lcd(CONFIG_PANEL, par); | 632 | crtc->lcd_config_panel = aty_ld_lcd(CNFG_PANEL, par); |
| 633 | crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par); | 633 | crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par); |
| 634 | 634 | ||
| 635 | 635 | ||
| @@ -676,7 +676,7 @@ static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc) | |||
| 676 | aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & ~(CRTC_EXT_DISP_EN | CRTC_EN), par); | 676 | aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & ~(CRTC_EXT_DISP_EN | CRTC_EN), par); |
| 677 | 677 | ||
| 678 | /* update non-shadow registers first */ | 678 | /* update non-shadow registers first */ |
| 679 | aty_st_lcd(CONFIG_PANEL, crtc->lcd_config_panel, par); | 679 | aty_st_lcd(CNFG_PANEL, crtc->lcd_config_panel, par); |
| 680 | aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl & | 680 | aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl & |
| 681 | ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par); | 681 | ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par); |
| 682 | 682 | ||
| @@ -858,7 +858,7 @@ static int aty_var_to_crtc(const struct fb_info *info, | |||
| 858 | if (!M64_HAS(MOBIL_BUS)) | 858 | if (!M64_HAS(MOBIL_BUS)) |
| 859 | crtc->lcd_index |= CRTC2_DISPLAY_DIS; | 859 | crtc->lcd_index |= CRTC2_DISPLAY_DIS; |
| 860 | 860 | ||
| 861 | crtc->lcd_config_panel = aty_ld_lcd(CONFIG_PANEL, par) | 0x4000; | 861 | crtc->lcd_config_panel = aty_ld_lcd(CNFG_PANEL, par) | 0x4000; |
| 862 | crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par) & ~CRTC_RW_SELECT; | 862 | crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par) & ~CRTC_RW_SELECT; |
| 863 | 863 | ||
| 864 | crtc->lcd_gen_cntl &= | 864 | crtc->lcd_gen_cntl &= |
| @@ -1978,7 +1978,7 @@ static int aty_power_mgmt(int sleep, struct atyfb_par *par) | |||
| 1978 | 1978 | ||
| 1979 | return timeout ? 0 : -EIO; | 1979 | return timeout ? 0 : -EIO; |
| 1980 | } | 1980 | } |
| 1981 | #endif | 1981 | #endif /* CONFIG_PPC_PMAC */ |
| 1982 | 1982 | ||
| 1983 | static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state) | 1983 | static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state) |
| 1984 | { | 1984 | { |
| @@ -2002,9 +2002,15 @@ static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
| 2002 | par->asleep = 1; | 2002 | par->asleep = 1; |
| 2003 | par->lock_blank = 1; | 2003 | par->lock_blank = 1; |
| 2004 | 2004 | ||
| 2005 | /* Because we may change PCI D state ourselves, we need to | ||
| 2006 | * first save the config space content so the core can | ||
| 2007 | * restore it properly on resume. | ||
| 2008 | */ | ||
| 2009 | pci_save_state(pdev); | ||
| 2010 | |||
| 2005 | #ifdef CONFIG_PPC_PMAC | 2011 | #ifdef CONFIG_PPC_PMAC |
| 2006 | /* Set chip to "suspend" mode */ | 2012 | /* Set chip to "suspend" mode */ |
| 2007 | if (aty_power_mgmt(1, par)) { | 2013 | if (machine_is(powermac) && aty_power_mgmt(1, par)) { |
| 2008 | par->asleep = 0; | 2014 | par->asleep = 0; |
| 2009 | par->lock_blank = 0; | 2015 | par->lock_blank = 0; |
| 2010 | atyfb_blank(FB_BLANK_UNBLANK, info); | 2016 | atyfb_blank(FB_BLANK_UNBLANK, info); |
| @@ -2047,11 +2053,15 @@ static int atyfb_pci_resume(struct pci_dev *pdev) | |||
| 2047 | 2053 | ||
| 2048 | acquire_console_sem(); | 2054 | acquire_console_sem(); |
| 2049 | 2055 | ||
| 2056 | /* PCI state will have been restored by the core, so | ||
| 2057 | * we should be in D0 now with our config space fully | ||
| 2058 | * restored | ||
| 2059 | */ | ||
| 2060 | |||
| 2050 | #ifdef CONFIG_PPC_PMAC | 2061 | #ifdef CONFIG_PPC_PMAC |
| 2051 | if (pdev->dev.power.power_state.event == 2) | 2062 | if (machine_is(powermac) && |
| 2063 | pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) | ||
| 2052 | aty_power_mgmt(0, par); | 2064 | aty_power_mgmt(0, par); |
| 2053 | #else | ||
| 2054 | pci_set_power_state(pdev, PCI_D0); | ||
| 2055 | #endif | 2065 | #endif |
| 2056 | 2066 | ||
| 2057 | aty_resume_chip(info); | 2067 | aty_resume_chip(info); |
| @@ -2254,7 +2264,7 @@ static int __devinit aty_init(struct fb_info *info) | |||
| 2254 | if (!M64_HAS(INTEGRATED)) { | 2264 | if (!M64_HAS(INTEGRATED)) { |
| 2255 | u32 stat0; | 2265 | u32 stat0; |
| 2256 | u8 dac_type, dac_subtype, clk_type; | 2266 | u8 dac_type, dac_subtype, clk_type; |
| 2257 | stat0 = aty_ld_le32(CONFIG_STAT0, par); | 2267 | stat0 = aty_ld_le32(CNFG_STAT0, par); |
| 2258 | par->bus_type = (stat0 >> 0) & 0x07; | 2268 | par->bus_type = (stat0 >> 0) & 0x07; |
| 2259 | par->ram_type = (stat0 >> 3) & 0x07; | 2269 | par->ram_type = (stat0 >> 3) & 0x07; |
| 2260 | ramname = aty_gx_ram[par->ram_type]; | 2270 | ramname = aty_gx_ram[par->ram_type]; |
| @@ -2324,7 +2334,7 @@ static int __devinit aty_init(struct fb_info *info) | |||
| 2324 | par->dac_ops = &aty_dac_ct; | 2334 | par->dac_ops = &aty_dac_ct; |
| 2325 | par->pll_ops = &aty_pll_ct; | 2335 | par->pll_ops = &aty_pll_ct; |
| 2326 | par->bus_type = PCI; | 2336 | par->bus_type = PCI; |
| 2327 | par->ram_type = (aty_ld_le32(CONFIG_STAT0, par) & 0x07); | 2337 | par->ram_type = (aty_ld_le32(CNFG_STAT0, par) & 0x07); |
| 2328 | ramname = aty_ct_ram[par->ram_type]; | 2338 | ramname = aty_ct_ram[par->ram_type]; |
| 2329 | /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */ | 2339 | /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */ |
| 2330 | if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM) | 2340 | if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM) |
| @@ -2433,7 +2443,7 @@ static int __devinit aty_init(struct fb_info *info) | |||
| 2433 | } | 2443 | } |
| 2434 | 2444 | ||
| 2435 | if (M64_HAS(MAGIC_VRAM_SIZE)) { | 2445 | if (M64_HAS(MAGIC_VRAM_SIZE)) { |
| 2436 | if (aty_ld_le32(CONFIG_STAT1, par) & 0x40000000) | 2446 | if (aty_ld_le32(CNFG_STAT1, par) & 0x40000000) |
| 2437 | info->fix.smem_len += 0x400000; | 2447 | info->fix.smem_len += 0x400000; |
| 2438 | } | 2448 | } |
| 2439 | 2449 | ||
| @@ -2946,7 +2956,7 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev, | |||
| 2946 | * Fix PROMs idea of MEM_CNTL settings... | 2956 | * Fix PROMs idea of MEM_CNTL settings... |
| 2947 | */ | 2957 | */ |
| 2948 | mem = aty_ld_le32(MEM_CNTL, par); | 2958 | mem = aty_ld_le32(MEM_CNTL, par); |
| 2949 | chip_id = aty_ld_le32(CONFIG_CHIP_ID, par); | 2959 | chip_id = aty_ld_le32(CNFG_CHIP_ID, par); |
| 2950 | if (((chip_id & CFG_CHIP_TYPE) == VT_CHIP_ID) && !((chip_id >> 24) & 1)) { | 2960 | if (((chip_id & CFG_CHIP_TYPE) == VT_CHIP_ID) && !((chip_id >> 24) & 1)) { |
| 2951 | switch (mem & 0x0f) { | 2961 | switch (mem & 0x0f) { |
| 2952 | case 3: | 2962 | case 3: |
| @@ -2964,7 +2974,7 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev, | |||
| 2964 | default: | 2974 | default: |
| 2965 | break; | 2975 | break; |
| 2966 | } | 2976 | } |
| 2967 | if ((aty_ld_le32(CONFIG_STAT0, par) & 7) >= SDRAM) | 2977 | if ((aty_ld_le32(CNFG_STAT0, par) & 7) >= SDRAM) |
| 2968 | mem &= ~(0x00700000); | 2978 | mem &= ~(0x00700000); |
| 2969 | } | 2979 | } |
| 2970 | mem &= ~(0xcf80e000); /* Turn off all undocumented bits. */ | 2980 | mem &= ~(0xcf80e000); /* Turn off all undocumented bits. */ |
| @@ -3572,7 +3582,7 @@ static int __init atyfb_atari_probe(void) | |||
| 3572 | } | 3582 | } |
| 3573 | 3583 | ||
| 3574 | /* Fake pci_id for correct_chipset() */ | 3584 | /* Fake pci_id for correct_chipset() */ |
| 3575 | switch (aty_ld_le32(CONFIG_CHIP_ID, par) & CFG_CHIP_TYPE) { | 3585 | switch (aty_ld_le32(CNFG_CHIP_ID, par) & CFG_CHIP_TYPE) { |
| 3576 | case 0x00d7: | 3586 | case 0x00d7: |
| 3577 | par->pci_id = PCI_CHIP_MACH64GX; | 3587 | par->pci_id = PCI_CHIP_MACH64GX; |
| 3578 | break; | 3588 | break; |
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index d0f1a7fc2c9d..16bb7e3c0310 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c | |||
| @@ -1936,8 +1936,8 @@ static void fixup_memory_mappings(struct radeonfb_info *rinfo) | |||
| 1936 | OUTREG(CRTC_GEN_CNTL, save_crtc_gen_cntl | CRTC_DISP_REQ_EN_B); | 1936 | OUTREG(CRTC_GEN_CNTL, save_crtc_gen_cntl | CRTC_DISP_REQ_EN_B); |
| 1937 | mdelay(100); | 1937 | mdelay(100); |
| 1938 | 1938 | ||
| 1939 | aper_base = INREG(CONFIG_APER_0_BASE); | 1939 | aper_base = INREG(CNFG_APER_0_BASE); |
| 1940 | aper_size = INREG(CONFIG_APER_SIZE); | 1940 | aper_size = INREG(CNFG_APER_SIZE); |
| 1941 | 1941 | ||
| 1942 | #ifdef SET_MC_FB_FROM_APERTURE | 1942 | #ifdef SET_MC_FB_FROM_APERTURE |
| 1943 | /* Set framebuffer to be at the same address as set in PCI BAR */ | 1943 | /* Set framebuffer to be at the same address as set in PCI BAR */ |
| @@ -2024,11 +2024,11 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo) | |||
| 2024 | ~CRTC_H_CUTOFF_ACTIVE_EN); | 2024 | ~CRTC_H_CUTOFF_ACTIVE_EN); |
| 2025 | } | 2025 | } |
| 2026 | } else { | 2026 | } else { |
| 2027 | tmp = INREG(CONFIG_MEMSIZE); | 2027 | tmp = INREG(CNFG_MEMSIZE); |
| 2028 | } | 2028 | } |
| 2029 | 2029 | ||
| 2030 | /* mem size is bits [28:0], mask off the rest */ | 2030 | /* mem size is bits [28:0], mask off the rest */ |
| 2031 | rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK; | 2031 | rinfo->video_ram = tmp & CNFG_MEMSIZE_MASK; |
| 2032 | 2032 | ||
| 2033 | /* | 2033 | /* |
| 2034 | * Hack to get around some busted production M6's | 2034 | * Hack to get around some busted production M6's |
| @@ -2228,7 +2228,7 @@ static int __devinit radeonfb_pci_register (struct pci_dev *pdev, | |||
| 2228 | */ | 2228 | */ |
| 2229 | rinfo->errata = 0; | 2229 | rinfo->errata = 0; |
| 2230 | if (rinfo->family == CHIP_FAMILY_R300 && | 2230 | if (rinfo->family == CHIP_FAMILY_R300 && |
| 2231 | (INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) | 2231 | (INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) |
| 2232 | == CFG_ATI_REV_A11) | 2232 | == CFG_ATI_REV_A11) |
| 2233 | rinfo->errata |= CHIP_ERRATA_R300_CG; | 2233 | rinfo->errata |= CHIP_ERRATA_R300_CG; |
| 2234 | 2234 | ||
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c index 675abdafc2d8..ca5f0dc28546 100644 --- a/drivers/video/aty/radeon_pm.c +++ b/drivers/video/aty/radeon_pm.c | |||
| @@ -333,7 +333,7 @@ static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo) | |||
| 333 | if (!rinfo->has_CRTC2) { | 333 | if (!rinfo->has_CRTC2) { |
| 334 | tmp = INPLL(pllSCLK_CNTL); | 334 | tmp = INPLL(pllSCLK_CNTL); |
| 335 | 335 | ||
| 336 | if ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) > CFG_ATI_REV_A13) | 336 | if ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) > CFG_ATI_REV_A13) |
| 337 | tmp &= ~(SCLK_CNTL__FORCE_CP | SCLK_CNTL__FORCE_RB); | 337 | tmp &= ~(SCLK_CNTL__FORCE_CP | SCLK_CNTL__FORCE_RB); |
| 338 | tmp &= ~(SCLK_CNTL__FORCE_HDP | SCLK_CNTL__FORCE_DISP1 | | 338 | tmp &= ~(SCLK_CNTL__FORCE_HDP | SCLK_CNTL__FORCE_DISP1 | |
| 339 | SCLK_CNTL__FORCE_TOP | SCLK_CNTL__FORCE_SE | | 339 | SCLK_CNTL__FORCE_TOP | SCLK_CNTL__FORCE_SE | |
| @@ -468,9 +468,9 @@ static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo) | |||
| 468 | 468 | ||
| 469 | /*RAGE_6::A11 A12 A12N1 A13, RV250::A11 A12, R300*/ | 469 | /*RAGE_6::A11 A12 A12N1 A13, RV250::A11 A12, R300*/ |
| 470 | if ((rinfo->family == CHIP_FAMILY_RV250 && | 470 | if ((rinfo->family == CHIP_FAMILY_RV250 && |
| 471 | ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) || | 471 | ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) || |
| 472 | ((rinfo->family == CHIP_FAMILY_RV100) && | 472 | ((rinfo->family == CHIP_FAMILY_RV100) && |
| 473 | ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) <= CFG_ATI_REV_A13))) { | 473 | ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) <= CFG_ATI_REV_A13))) { |
| 474 | tmp |= SCLK_CNTL__FORCE_CP; | 474 | tmp |= SCLK_CNTL__FORCE_CP; |
| 475 | tmp |= SCLK_CNTL__FORCE_VIP; | 475 | tmp |= SCLK_CNTL__FORCE_VIP; |
| 476 | } | 476 | } |
| @@ -486,7 +486,7 @@ static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo) | |||
| 486 | /* RV200::A11 A12 RV250::A11 A12 */ | 486 | /* RV200::A11 A12 RV250::A11 A12 */ |
| 487 | if (((rinfo->family == CHIP_FAMILY_RV200) || | 487 | if (((rinfo->family == CHIP_FAMILY_RV200) || |
| 488 | (rinfo->family == CHIP_FAMILY_RV250)) && | 488 | (rinfo->family == CHIP_FAMILY_RV250)) && |
| 489 | ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) | 489 | ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) |
| 490 | tmp |= SCLK_MORE_CNTL__FORCEON; | 490 | tmp |= SCLK_MORE_CNTL__FORCEON; |
| 491 | 491 | ||
| 492 | OUTPLL(pllSCLK_MORE_CNTL, tmp); | 492 | OUTPLL(pllSCLK_MORE_CNTL, tmp); |
| @@ -497,7 +497,7 @@ static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo) | |||
| 497 | /* RV200::A11 A12, RV250::A11 A12 */ | 497 | /* RV200::A11 A12, RV250::A11 A12 */ |
| 498 | if (((rinfo->family == CHIP_FAMILY_RV200) || | 498 | if (((rinfo->family == CHIP_FAMILY_RV200) || |
| 499 | (rinfo->family == CHIP_FAMILY_RV250)) && | 499 | (rinfo->family == CHIP_FAMILY_RV250)) && |
| 500 | ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) { | 500 | ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) { |
| 501 | tmp = INPLL(pllPLL_PWRMGT_CNTL); | 501 | tmp = INPLL(pllPLL_PWRMGT_CNTL); |
| 502 | tmp |= PLL_PWRMGT_CNTL__TCL_BYPASS_DISABLE; | 502 | tmp |= PLL_PWRMGT_CNTL__TCL_BYPASS_DISABLE; |
| 503 | OUTPLL(pllPLL_PWRMGT_CNTL, tmp); | 503 | OUTPLL(pllPLL_PWRMGT_CNTL, tmp); |
| @@ -702,7 +702,7 @@ static void radeon_pm_restore_regs(struct radeonfb_info *rinfo) | |||
| 702 | OUTREG(DISPLAY_BASE_ADDR, rinfo->save_regs[31]); | 702 | OUTREG(DISPLAY_BASE_ADDR, rinfo->save_regs[31]); |
| 703 | OUTREG(MC_AGP_LOCATION, rinfo->save_regs[32]); | 703 | OUTREG(MC_AGP_LOCATION, rinfo->save_regs[32]); |
| 704 | OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]); | 704 | OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]); |
| 705 | OUTREG(CONFIG_MEMSIZE, rinfo->video_ram); | 705 | OUTREG(CNFG_MEMSIZE, rinfo->video_ram); |
| 706 | 706 | ||
| 707 | OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]); | 707 | OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]); |
| 708 | OUTREG(DISP_PWR_MAN, rinfo->save_regs[10]); | 708 | OUTREG(DISP_PWR_MAN, rinfo->save_regs[10]); |
| @@ -1723,7 +1723,7 @@ static void radeon_reinitialize_M10(struct radeonfb_info *rinfo) | |||
| 1723 | OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]); | 1723 | OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]); |
| 1724 | OUTREG(MC_FB_LOCATION, rinfo->save_regs[30]); | 1724 | OUTREG(MC_FB_LOCATION, rinfo->save_regs[30]); |
| 1725 | OUTREG(OV0_BASE_ADDR, rinfo->save_regs[80]); | 1725 | OUTREG(OV0_BASE_ADDR, rinfo->save_regs[80]); |
| 1726 | OUTREG(CONFIG_MEMSIZE, rinfo->video_ram); | 1726 | OUTREG(CNFG_MEMSIZE, rinfo->video_ram); |
| 1727 | OUTREG(BUS_CNTL, rinfo->save_regs[36]); | 1727 | OUTREG(BUS_CNTL, rinfo->save_regs[36]); |
| 1728 | OUTREG(BUS_CNTL1, rinfo->save_regs[14]); | 1728 | OUTREG(BUS_CNTL1, rinfo->save_regs[14]); |
| 1729 | OUTREG(MPP_TB_CONFIG, rinfo->save_regs[37]); | 1729 | OUTREG(MPP_TB_CONFIG, rinfo->save_regs[37]); |
| @@ -1961,7 +1961,7 @@ static void radeon_pm_m9p_reconfigure_mc(struct radeonfb_info *rinfo) | |||
| 1961 | OUTMC(rinfo, ixMC_CHP_IO_CNTL_B1, rinfo->save_regs[68] /*0x141555ff*/); | 1961 | OUTMC(rinfo, ixMC_CHP_IO_CNTL_B1, rinfo->save_regs[68] /*0x141555ff*/); |
| 1962 | OUTMC(rinfo, ixMC_IMP_CNTL_0, rinfo->save_regs[71] /*0x00009249*/); | 1962 | OUTMC(rinfo, ixMC_IMP_CNTL_0, rinfo->save_regs[71] /*0x00009249*/); |
| 1963 | OUTREG(MC_IND_INDEX, 0); | 1963 | OUTREG(MC_IND_INDEX, 0); |
| 1964 | OUTREG(CONFIG_MEMSIZE, rinfo->video_ram); | 1964 | OUTREG(CNFG_MEMSIZE, rinfo->video_ram); |
| 1965 | 1965 | ||
| 1966 | mdelay(20); | 1966 | mdelay(20); |
| 1967 | } | 1967 | } |
| @@ -2361,7 +2361,7 @@ static void radeon_reinitialize_QW(struct radeonfb_info *rinfo) | |||
| 2361 | OUTMC(rinfo, ixMC_IMP_CNTL_0, 0x00009249); | 2361 | OUTMC(rinfo, ixMC_IMP_CNTL_0, 0x00009249); |
| 2362 | OUTREG(MC_IND_INDEX, 0); | 2362 | OUTREG(MC_IND_INDEX, 0); |
| 2363 | 2363 | ||
| 2364 | OUTREG(CONFIG_MEMSIZE, rinfo->video_ram); | 2364 | OUTREG(CNFG_MEMSIZE, rinfo->video_ram); |
| 2365 | 2365 | ||
| 2366 | radeon_pm_full_reset_sdram(rinfo); | 2366 | radeon_pm_full_reset_sdram(rinfo); |
| 2367 | 2367 | ||
| @@ -2509,9 +2509,7 @@ static void radeon_reinitialize_QW(struct radeonfb_info *rinfo) | |||
| 2509 | 2509 | ||
| 2510 | static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend) | 2510 | static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend) |
| 2511 | { | 2511 | { |
| 2512 | u16 pwr_cmd; | ||
| 2513 | u32 tmp; | 2512 | u32 tmp; |
| 2514 | int i; | ||
| 2515 | 2513 | ||
| 2516 | if (!rinfo->pm_reg) | 2514 | if (!rinfo->pm_reg) |
| 2517 | return; | 2515 | return; |
| @@ -2557,32 +2555,14 @@ static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend) | |||
| 2557 | } | 2555 | } |
| 2558 | } | 2556 | } |
| 2559 | 2557 | ||
| 2560 | for (i = 0; i < 64; ++i) | ||
| 2561 | pci_read_config_dword(rinfo->pdev, i * 4, | ||
| 2562 | &rinfo->cfg_save[i]); | ||
| 2563 | |||
| 2564 | /* Switch PCI power management to D2. */ | 2558 | /* Switch PCI power management to D2. */ |
| 2565 | pci_disable_device(rinfo->pdev); | 2559 | pci_disable_device(rinfo->pdev); |
| 2566 | for (;;) { | 2560 | pci_save_state(rinfo->pdev); |
| 2567 | pci_read_config_word( | 2561 | pci_set_power_state(rinfo->pdev, PCI_D2); |
| 2568 | rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, | ||
| 2569 | &pwr_cmd); | ||
| 2570 | if (pwr_cmd & 2) | ||
| 2571 | break; | ||
| 2572 | pci_write_config_word( | ||
| 2573 | rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, | ||
| 2574 | (pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | 2); | ||
| 2575 | mdelay(500); | ||
| 2576 | } | ||
| 2577 | } else { | 2562 | } else { |
| 2578 | printk(KERN_DEBUG "radeonfb (%s): switching to D0 state...\n", | 2563 | printk(KERN_DEBUG "radeonfb (%s): switching to D0 state...\n", |
| 2579 | pci_name(rinfo->pdev)); | 2564 | pci_name(rinfo->pdev)); |
| 2580 | 2565 | ||
| 2581 | /* Switch back PCI powermanagment to D0 */ | ||
| 2582 | mdelay(200); | ||
| 2583 | pci_write_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, 0); | ||
| 2584 | mdelay(500); | ||
| 2585 | |||
| 2586 | if (rinfo->family <= CHIP_FAMILY_RV250) { | 2566 | if (rinfo->family <= CHIP_FAMILY_RV250) { |
| 2587 | /* Reset the SDRAM controller */ | 2567 | /* Reset the SDRAM controller */ |
| 2588 | radeon_pm_full_reset_sdram(rinfo); | 2568 | radeon_pm_full_reset_sdram(rinfo); |
| @@ -2598,37 +2578,10 @@ static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend) | |||
| 2598 | } | 2578 | } |
| 2599 | } | 2579 | } |
| 2600 | 2580 | ||
| 2601 | static int radeon_restore_pci_cfg(struct radeonfb_info *rinfo) | ||
| 2602 | { | ||
| 2603 | int i; | ||
| 2604 | static u32 radeon_cfg_after_resume[64]; | ||
| 2605 | |||
| 2606 | for (i = 0; i < 64; ++i) | ||
| 2607 | pci_read_config_dword(rinfo->pdev, i * 4, | ||
| 2608 | &radeon_cfg_after_resume[i]); | ||
| 2609 | |||
| 2610 | if (radeon_cfg_after_resume[PCI_BASE_ADDRESS_0/4] | ||
| 2611 | == rinfo->cfg_save[PCI_BASE_ADDRESS_0/4]) | ||
| 2612 | return 0; /* assume everything is ok */ | ||
| 2613 | |||
| 2614 | for (i = PCI_BASE_ADDRESS_0/4; i < 64; ++i) { | ||
| 2615 | if (radeon_cfg_after_resume[i] != rinfo->cfg_save[i]) | ||
| 2616 | pci_write_config_dword(rinfo->pdev, i * 4, | ||
| 2617 | rinfo->cfg_save[i]); | ||
| 2618 | } | ||
| 2619 | pci_write_config_word(rinfo->pdev, PCI_CACHE_LINE_SIZE, | ||
| 2620 | rinfo->cfg_save[PCI_CACHE_LINE_SIZE/4]); | ||
| 2621 | pci_write_config_word(rinfo->pdev, PCI_COMMAND, | ||
| 2622 | rinfo->cfg_save[PCI_COMMAND/4]); | ||
| 2623 | return 1; | ||
| 2624 | } | ||
| 2625 | |||
| 2626 | |||
| 2627 | int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg) | 2581 | int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg) |
| 2628 | { | 2582 | { |
| 2629 | struct fb_info *info = pci_get_drvdata(pdev); | 2583 | struct fb_info *info = pci_get_drvdata(pdev); |
| 2630 | struct radeonfb_info *rinfo = info->par; | 2584 | struct radeonfb_info *rinfo = info->par; |
| 2631 | int i; | ||
| 2632 | 2585 | ||
| 2633 | if (mesg.event == pdev->dev.power.power_state.event) | 2586 | if (mesg.event == pdev->dev.power.power_state.event) |
| 2634 | return 0; | 2587 | return 0; |
| @@ -2674,6 +2627,11 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg) | |||
| 2674 | pmac_suspend_agp_for_card(pdev); | 2627 | pmac_suspend_agp_for_card(pdev); |
| 2675 | #endif /* CONFIG_PPC_PMAC */ | 2628 | #endif /* CONFIG_PPC_PMAC */ |
| 2676 | 2629 | ||
| 2630 | /* It's unclear whether or when the generic code will do that, so let's | ||
| 2631 | * do it ourselves. We save state before we do any power management | ||
| 2632 | */ | ||
| 2633 | pci_save_state(pdev); | ||
| 2634 | |||
| 2677 | /* If we support wakeup from poweroff, we save all regs we can including cfg | 2635 | /* If we support wakeup from poweroff, we save all regs we can including cfg |
| 2678 | * space | 2636 | * space |
| 2679 | */ | 2637 | */ |
| @@ -2698,9 +2656,6 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg) | |||
| 2698 | mdelay(20); | 2656 | mdelay(20); |
| 2699 | OUTREG(LVDS_GEN_CNTL, INREG(LVDS_GEN_CNTL) & ~(LVDS_DIGON)); | 2657 | OUTREG(LVDS_GEN_CNTL, INREG(LVDS_GEN_CNTL) & ~(LVDS_DIGON)); |
| 2700 | } | 2658 | } |
| 2701 | // FIXME: Use PCI layer | ||
| 2702 | for (i = 0; i < 64; ++i) | ||
| 2703 | pci_read_config_dword(pdev, i * 4, &rinfo->cfg_save[i]); | ||
| 2704 | pci_disable_device(pdev); | 2659 | pci_disable_device(pdev); |
| 2705 | } | 2660 | } |
| 2706 | /* If we support D2, we go to it (should be fixed later with a flag forcing | 2661 | /* If we support D2, we go to it (should be fixed later with a flag forcing |
| @@ -2717,6 +2672,13 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg) | |||
| 2717 | return 0; | 2672 | return 0; |
| 2718 | } | 2673 | } |
| 2719 | 2674 | ||
| 2675 | static int radeon_check_power_loss(struct radeonfb_info *rinfo) | ||
| 2676 | { | ||
| 2677 | return rinfo->save_regs[4] != INPLL(CLK_PIN_CNTL) || | ||
| 2678 | rinfo->save_regs[2] != INPLL(MCLK_CNTL) || | ||
| 2679 | rinfo->save_regs[3] != INPLL(SCLK_CNTL); | ||
| 2680 | } | ||
| 2681 | |||
| 2720 | int radeonfb_pci_resume(struct pci_dev *pdev) | 2682 | int radeonfb_pci_resume(struct pci_dev *pdev) |
| 2721 | { | 2683 | { |
| 2722 | struct fb_info *info = pci_get_drvdata(pdev); | 2684 | struct fb_info *info = pci_get_drvdata(pdev); |
| @@ -2735,20 +2697,13 @@ int radeonfb_pci_resume(struct pci_dev *pdev) | |||
| 2735 | printk(KERN_DEBUG "radeonfb (%s): resuming from state: %d...\n", | 2697 | printk(KERN_DEBUG "radeonfb (%s): resuming from state: %d...\n", |
| 2736 | pci_name(pdev), pdev->dev.power.power_state.event); | 2698 | pci_name(pdev), pdev->dev.power.power_state.event); |
| 2737 | 2699 | ||
| 2738 | 2700 | /* PCI state will have been restored by the core, so | |
| 2739 | if (pci_enable_device(pdev)) { | 2701 | * we should be in D0 now with our config space fully |
| 2740 | rc = -ENODEV; | 2702 | * restored |
| 2741 | printk(KERN_ERR "radeonfb (%s): can't enable PCI device !\n", | 2703 | */ |
| 2742 | pci_name(pdev)); | ||
| 2743 | goto bail; | ||
| 2744 | } | ||
| 2745 | pci_set_master(pdev); | ||
| 2746 | |||
| 2747 | if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) { | 2704 | if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) { |
| 2748 | /* Wakeup chip. Check from config space if we were powered off | 2705 | /* Wakeup chip */ |
| 2749 | * (todo: additionally, check CLK_PIN_CNTL too) | 2706 | if ((rinfo->pm_mode & radeon_pm_off) && radeon_check_power_loss(rinfo)) { |
| 2750 | */ | ||
| 2751 | if ((rinfo->pm_mode & radeon_pm_off) && radeon_restore_pci_cfg(rinfo)) { | ||
| 2752 | if (rinfo->reinit_func != NULL) | 2707 | if (rinfo->reinit_func != NULL) |
| 2753 | rinfo->reinit_func(rinfo); | 2708 | rinfo->reinit_func(rinfo); |
| 2754 | else { | 2709 | else { |
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h index 3ea1b00fdd22..7351e66c7f54 100644 --- a/drivers/video/aty/radeonfb.h +++ b/drivers/video/aty/radeonfb.h | |||
| @@ -361,8 +361,6 @@ struct radeonfb_info { | |||
| 361 | #ifdef CONFIG_FB_RADEON_I2C | 361 | #ifdef CONFIG_FB_RADEON_I2C |
| 362 | struct radeon_i2c_chan i2c[4]; | 362 | struct radeon_i2c_chan i2c[4]; |
| 363 | #endif | 363 | #endif |
| 364 | |||
| 365 | u32 cfg_save[64]; | ||
| 366 | }; | 364 | }; |
| 367 | 365 | ||
| 368 | 366 | ||
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 363b3cb2f01b..63d759498165 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile | |||
| @@ -18,7 +18,7 @@ obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o | |||
| 18 | obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o | 18 | obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o |
| 19 | obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o | 19 | obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o |
| 20 | obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o | 20 | obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o |
| 21 | obj-$(CONFIG_BACKLIGHT_DA903X) += da903x.o | 21 | obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o |
| 22 | obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o | 22 | obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o |
| 23 | obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o | 23 | obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o |
| 24 | obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o | 24 | obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o |
diff --git a/drivers/video/backlight/da903x.c b/drivers/video/backlight/da903x_bl.c index 93bb4340cc64..93bb4340cc64 100644 --- a/drivers/video/backlight/da903x.c +++ b/drivers/video/backlight/da903x_bl.c | |||
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c index 91b78e691505..f53b9f1d6aba 100644 --- a/drivers/video/fbcmap.c +++ b/drivers/video/fbcmap.c | |||
| @@ -250,10 +250,6 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info) | |||
| 250 | int rc, size = cmap->len * sizeof(u16); | 250 | int rc, size = cmap->len * sizeof(u16); |
| 251 | struct fb_cmap umap; | 251 | struct fb_cmap umap; |
| 252 | 252 | ||
| 253 | if (cmap->start < 0 || (!info->fbops->fb_setcolreg && | ||
| 254 | !info->fbops->fb_setcmap)) | ||
| 255 | return -EINVAL; | ||
| 256 | |||
| 257 | memset(&umap, 0, sizeof(struct fb_cmap)); | 253 | memset(&umap, 0, sizeof(struct fb_cmap)); |
| 258 | rc = fb_alloc_cmap(&umap, cmap->len, cmap->transp != NULL); | 254 | rc = fb_alloc_cmap(&umap, cmap->len, cmap->transp != NULL); |
| 259 | if (rc) | 255 | if (rc) |
| @@ -262,11 +258,23 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info) | |||
| 262 | copy_from_user(umap.green, cmap->green, size) || | 258 | copy_from_user(umap.green, cmap->green, size) || |
| 263 | copy_from_user(umap.blue, cmap->blue, size) || | 259 | copy_from_user(umap.blue, cmap->blue, size) || |
| 264 | (cmap->transp && copy_from_user(umap.transp, cmap->transp, size))) { | 260 | (cmap->transp && copy_from_user(umap.transp, cmap->transp, size))) { |
| 265 | fb_dealloc_cmap(&umap); | 261 | rc = -EFAULT; |
| 266 | return -EFAULT; | 262 | goto out; |
| 267 | } | 263 | } |
| 268 | umap.start = cmap->start; | 264 | umap.start = cmap->start; |
| 265 | if (!lock_fb_info(info)) { | ||
| 266 | rc = -ENODEV; | ||
| 267 | goto out; | ||
| 268 | } | ||
| 269 | if (cmap->start < 0 || (!info->fbops->fb_setcolreg && | ||
| 270 | !info->fbops->fb_setcmap)) { | ||
| 271 | rc = -EINVAL; | ||
| 272 | goto out1; | ||
| 273 | } | ||
| 269 | rc = fb_set_cmap(&umap, info); | 274 | rc = fb_set_cmap(&umap, info); |
| 275 | out1: | ||
| 276 | unlock_fb_info(info); | ||
| 277 | out: | ||
| 270 | fb_dealloc_cmap(&umap); | 278 | fb_dealloc_cmap(&umap); |
| 271 | return rc; | 279 | return rc; |
| 272 | } | 280 | } |
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 756efeb91abc..cfd9dce1ce0b 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
| @@ -1013,132 +1013,139 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, | |||
| 1013 | struct fb_var_screeninfo var; | 1013 | struct fb_var_screeninfo var; |
| 1014 | struct fb_fix_screeninfo fix; | 1014 | struct fb_fix_screeninfo fix; |
| 1015 | struct fb_con2fbmap con2fb; | 1015 | struct fb_con2fbmap con2fb; |
| 1016 | struct fb_cmap cmap_from; | ||
| 1016 | struct fb_cmap_user cmap; | 1017 | struct fb_cmap_user cmap; |
| 1017 | struct fb_event event; | 1018 | struct fb_event event; |
| 1018 | void __user *argp = (void __user *)arg; | 1019 | void __user *argp = (void __user *)arg; |
| 1019 | long ret = 0; | 1020 | long ret = 0; |
| 1020 | 1021 | ||
| 1021 | fb = info->fbops; | ||
| 1022 | if (!fb) | ||
| 1023 | return -ENODEV; | ||
| 1024 | |||
| 1025 | switch (cmd) { | 1022 | switch (cmd) { |
| 1026 | case FBIOGET_VSCREENINFO: | 1023 | case FBIOGET_VSCREENINFO: |
| 1027 | ret = copy_to_user(argp, &info->var, | 1024 | if (!lock_fb_info(info)) |
| 1028 | sizeof(var)) ? -EFAULT : 0; | 1025 | return -ENODEV; |
| 1026 | var = info->var; | ||
| 1027 | unlock_fb_info(info); | ||
| 1028 | |||
| 1029 | ret = copy_to_user(argp, &var, sizeof(var)) ? -EFAULT : 0; | ||
| 1029 | break; | 1030 | break; |
| 1030 | case FBIOPUT_VSCREENINFO: | 1031 | case FBIOPUT_VSCREENINFO: |
| 1031 | if (copy_from_user(&var, argp, sizeof(var))) { | 1032 | if (copy_from_user(&var, argp, sizeof(var))) |
| 1032 | ret = -EFAULT; | 1033 | return -EFAULT; |
| 1033 | break; | 1034 | if (!lock_fb_info(info)) |
| 1034 | } | 1035 | return -ENODEV; |
| 1035 | acquire_console_sem(); | 1036 | acquire_console_sem(); |
| 1036 | info->flags |= FBINFO_MISC_USEREVENT; | 1037 | info->flags |= FBINFO_MISC_USEREVENT; |
| 1037 | ret = fb_set_var(info, &var); | 1038 | ret = fb_set_var(info, &var); |
| 1038 | info->flags &= ~FBINFO_MISC_USEREVENT; | 1039 | info->flags &= ~FBINFO_MISC_USEREVENT; |
| 1039 | release_console_sem(); | 1040 | release_console_sem(); |
| 1040 | if (ret == 0 && copy_to_user(argp, &var, sizeof(var))) | 1041 | unlock_fb_info(info); |
| 1042 | if (!ret && copy_to_user(argp, &var, sizeof(var))) | ||
| 1041 | ret = -EFAULT; | 1043 | ret = -EFAULT; |
| 1042 | break; | 1044 | break; |
| 1043 | case FBIOGET_FSCREENINFO: | 1045 | case FBIOGET_FSCREENINFO: |
| 1044 | ret = copy_to_user(argp, &info->fix, | 1046 | if (!lock_fb_info(info)) |
| 1045 | sizeof(fix)) ? -EFAULT : 0; | 1047 | return -ENODEV; |
| 1048 | fix = info->fix; | ||
| 1049 | unlock_fb_info(info); | ||
| 1050 | |||
| 1051 | ret = copy_to_user(argp, &fix, sizeof(fix)) ? -EFAULT : 0; | ||
| 1046 | break; | 1052 | break; |
| 1047 | case FBIOPUTCMAP: | 1053 | case FBIOPUTCMAP: |
| 1048 | if (copy_from_user(&cmap, argp, sizeof(cmap))) | 1054 | if (copy_from_user(&cmap, argp, sizeof(cmap))) |
| 1049 | ret = -EFAULT; | 1055 | return -EFAULT; |
| 1050 | else | 1056 | ret = fb_set_user_cmap(&cmap, info); |
| 1051 | ret = fb_set_user_cmap(&cmap, info); | ||
| 1052 | break; | 1057 | break; |
| 1053 | case FBIOGETCMAP: | 1058 | case FBIOGETCMAP: |
| 1054 | if (copy_from_user(&cmap, argp, sizeof(cmap))) | 1059 | if (copy_from_user(&cmap, argp, sizeof(cmap))) |
| 1055 | ret = -EFAULT; | 1060 | return -EFAULT; |
| 1056 | else | 1061 | if (!lock_fb_info(info)) |
| 1057 | ret = fb_cmap_to_user(&info->cmap, &cmap); | 1062 | return -ENODEV; |
| 1063 | cmap_from = info->cmap; | ||
| 1064 | unlock_fb_info(info); | ||
| 1065 | ret = fb_cmap_to_user(&cmap_from, &cmap); | ||
| 1058 | break; | 1066 | break; |
| 1059 | case FBIOPAN_DISPLAY: | 1067 | case FBIOPAN_DISPLAY: |
| 1060 | if (copy_from_user(&var, argp, sizeof(var))) { | 1068 | if (copy_from_user(&var, argp, sizeof(var))) |
| 1061 | ret = -EFAULT; | 1069 | return -EFAULT; |
| 1062 | break; | 1070 | if (!lock_fb_info(info)) |
| 1063 | } | 1071 | return -ENODEV; |
| 1064 | acquire_console_sem(); | 1072 | acquire_console_sem(); |
| 1065 | ret = fb_pan_display(info, &var); | 1073 | ret = fb_pan_display(info, &var); |
| 1066 | release_console_sem(); | 1074 | release_console_sem(); |
| 1075 | unlock_fb_info(info); | ||
| 1067 | if (ret == 0 && copy_to_user(argp, &var, sizeof(var))) | 1076 | if (ret == 0 && copy_to_user(argp, &var, sizeof(var))) |
| 1068 | ret = -EFAULT; | 1077 | return -EFAULT; |
| 1069 | break; | 1078 | break; |
| 1070 | case FBIO_CURSOR: | 1079 | case FBIO_CURSOR: |
| 1071 | ret = -EINVAL; | 1080 | ret = -EINVAL; |
| 1072 | break; | 1081 | break; |
| 1073 | case FBIOGET_CON2FBMAP: | 1082 | case FBIOGET_CON2FBMAP: |
| 1074 | if (copy_from_user(&con2fb, argp, sizeof(con2fb))) | 1083 | if (copy_from_user(&con2fb, argp, sizeof(con2fb))) |
| 1075 | ret = -EFAULT; | 1084 | return -EFAULT; |
| 1076 | else if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) | 1085 | if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) |
| 1077 | ret = -EINVAL; | 1086 | return -EINVAL; |
| 1078 | else { | 1087 | con2fb.framebuffer = -1; |
| 1079 | con2fb.framebuffer = -1; | 1088 | event.data = &con2fb; |
| 1080 | event.info = info; | 1089 | |
| 1081 | event.data = &con2fb; | 1090 | if (!lock_fb_info(info)) |
| 1082 | fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, | 1091 | return -ENODEV; |
| 1083 | &event); | 1092 | event.info = info; |
| 1084 | ret = copy_to_user(argp, &con2fb, | 1093 | fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event); |
| 1085 | sizeof(con2fb)) ? -EFAULT : 0; | 1094 | unlock_fb_info(info); |
| 1086 | } | 1095 | |
| 1096 | ret = copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0; | ||
| 1087 | break; | 1097 | break; |
| 1088 | case FBIOPUT_CON2FBMAP: | 1098 | case FBIOPUT_CON2FBMAP: |
| 1089 | if (copy_from_user(&con2fb, argp, sizeof(con2fb))) { | 1099 | if (copy_from_user(&con2fb, argp, sizeof(con2fb))) |
| 1090 | ret = -EFAULT; | 1100 | return -EFAULT; |
| 1091 | break; | 1101 | if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) |
| 1092 | } | 1102 | return -EINVAL; |
| 1093 | if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) { | 1103 | if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX) |
| 1094 | ret = -EINVAL; | 1104 | return -EINVAL; |
| 1095 | break; | ||
| 1096 | } | ||
| 1097 | if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX) { | ||
| 1098 | ret = -EINVAL; | ||
| 1099 | break; | ||
| 1100 | } | ||
| 1101 | if (!registered_fb[con2fb.framebuffer]) | 1105 | if (!registered_fb[con2fb.framebuffer]) |
| 1102 | request_module("fb%d", con2fb.framebuffer); | 1106 | request_module("fb%d", con2fb.framebuffer); |
| 1103 | if (!registered_fb[con2fb.framebuffer]) { | 1107 | if (!registered_fb[con2fb.framebuffer]) { |
| 1104 | ret = -EINVAL; | 1108 | ret = -EINVAL; |
| 1105 | break; | 1109 | break; |
| 1106 | } | 1110 | } |
| 1107 | event.info = info; | ||
| 1108 | event.data = &con2fb; | 1111 | event.data = &con2fb; |
| 1112 | if (!lock_fb_info(info)) | ||
| 1113 | return -ENODEV; | ||
| 1114 | event.info = info; | ||
| 1109 | ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, | 1115 | ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, |
| 1110 | &event); | 1116 | &event); |
| 1117 | unlock_fb_info(info); | ||
| 1111 | break; | 1118 | break; |
| 1112 | case FBIOBLANK: | 1119 | case FBIOBLANK: |
| 1120 | if (!lock_fb_info(info)) | ||
| 1121 | return -ENODEV; | ||
| 1113 | acquire_console_sem(); | 1122 | acquire_console_sem(); |
| 1114 | info->flags |= FBINFO_MISC_USEREVENT; | 1123 | info->flags |= FBINFO_MISC_USEREVENT; |
| 1115 | ret = fb_blank(info, arg); | 1124 | ret = fb_blank(info, arg); |
| 1116 | info->flags &= ~FBINFO_MISC_USEREVENT; | 1125 | info->flags &= ~FBINFO_MISC_USEREVENT; |
| 1117 | release_console_sem(); | 1126 | release_console_sem(); |
| 1118 | break;; | 1127 | unlock_fb_info(info); |
| 1128 | break; | ||
| 1119 | default: | 1129 | default: |
| 1120 | if (fb->fb_ioctl == NULL) | 1130 | if (!lock_fb_info(info)) |
| 1121 | ret = -ENOTTY; | 1131 | return -ENODEV; |
| 1122 | else | 1132 | fb = info->fbops; |
| 1133 | if (fb->fb_ioctl) | ||
| 1123 | ret = fb->fb_ioctl(info, cmd, arg); | 1134 | ret = fb->fb_ioctl(info, cmd, arg); |
| 1135 | else | ||
| 1136 | ret = -ENOTTY; | ||
| 1137 | unlock_fb_info(info); | ||
| 1124 | } | 1138 | } |
| 1125 | return ret; | 1139 | return ret; |
| 1126 | } | 1140 | } |
| 1127 | 1141 | ||
| 1128 | static long fb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 1142 | static long fb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
| 1129 | __acquires(&info->lock) | ||
| 1130 | __releases(&info->lock) | ||
| 1131 | { | 1143 | { |
| 1132 | struct inode *inode = file->f_path.dentry->d_inode; | 1144 | struct inode *inode = file->f_path.dentry->d_inode; |
| 1133 | int fbidx = iminor(inode); | 1145 | int fbidx = iminor(inode); |
| 1134 | struct fb_info *info; | 1146 | struct fb_info *info = registered_fb[fbidx]; |
| 1135 | long ret; | ||
| 1136 | 1147 | ||
| 1137 | info = registered_fb[fbidx]; | 1148 | return do_fb_ioctl(info, cmd, arg); |
| 1138 | mutex_lock(&info->lock); | ||
| 1139 | ret = do_fb_ioctl(info, cmd, arg); | ||
| 1140 | mutex_unlock(&info->lock); | ||
| 1141 | return ret; | ||
| 1142 | } | 1149 | } |
| 1143 | 1150 | ||
| 1144 | #ifdef CONFIG_COMPAT | 1151 | #ifdef CONFIG_COMPAT |
| @@ -1257,8 +1264,6 @@ static int fb_get_fscreeninfo(struct fb_info *info, unsigned int cmd, | |||
| 1257 | 1264 | ||
| 1258 | static long fb_compat_ioctl(struct file *file, unsigned int cmd, | 1265 | static long fb_compat_ioctl(struct file *file, unsigned int cmd, |
| 1259 | unsigned long arg) | 1266 | unsigned long arg) |
| 1260 | __acquires(&info->lock) | ||
| 1261 | __releases(&info->lock) | ||
| 1262 | { | 1267 | { |
| 1263 | struct inode *inode = file->f_path.dentry->d_inode; | 1268 | struct inode *inode = file->f_path.dentry->d_inode; |
| 1264 | int fbidx = iminor(inode); | 1269 | int fbidx = iminor(inode); |
| @@ -1266,7 +1271,6 @@ __releases(&info->lock) | |||
| 1266 | struct fb_ops *fb = info->fbops; | 1271 | struct fb_ops *fb = info->fbops; |
| 1267 | long ret = -ENOIOCTLCMD; | 1272 | long ret = -ENOIOCTLCMD; |
| 1268 | 1273 | ||
| 1269 | mutex_lock(&info->lock); | ||
| 1270 | switch(cmd) { | 1274 | switch(cmd) { |
| 1271 | case FBIOGET_VSCREENINFO: | 1275 | case FBIOGET_VSCREENINFO: |
| 1272 | case FBIOPUT_VSCREENINFO: | 1276 | case FBIOPUT_VSCREENINFO: |
| @@ -1292,7 +1296,6 @@ __releases(&info->lock) | |||
| 1292 | ret = fb->fb_compat_ioctl(info, cmd, arg); | 1296 | ret = fb->fb_compat_ioctl(info, cmd, arg); |
| 1293 | break; | 1297 | break; |
| 1294 | } | 1298 | } |
| 1295 | mutex_unlock(&info->lock); | ||
| 1296 | return ret; | 1299 | return ret; |
| 1297 | } | 1300 | } |
| 1298 | #endif | 1301 | #endif |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index e3ff2b9e602f..33b7235f853b 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
| @@ -1208,9 +1208,11 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma, | |||
| 1208 | * check for an ELF header. If we find one, dump the first page to | 1208 | * check for an ELF header. If we find one, dump the first page to |
| 1209 | * aid in determining what was mapped here. | 1209 | * aid in determining what was mapped here. |
| 1210 | */ | 1210 | */ |
| 1211 | if (FILTER(ELF_HEADERS) && vma->vm_file != NULL && vma->vm_pgoff == 0) { | 1211 | if (FILTER(ELF_HEADERS) && |
| 1212 | vma->vm_pgoff == 0 && (vma->vm_flags & VM_READ)) { | ||
| 1212 | u32 __user *header = (u32 __user *) vma->vm_start; | 1213 | u32 __user *header = (u32 __user *) vma->vm_start; |
| 1213 | u32 word; | 1214 | u32 word; |
| 1215 | mm_segment_t fs = get_fs(); | ||
| 1214 | /* | 1216 | /* |
| 1215 | * Doing it this way gets the constant folded by GCC. | 1217 | * Doing it this way gets the constant folded by GCC. |
| 1216 | */ | 1218 | */ |
| @@ -1223,7 +1225,15 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma, | |||
| 1223 | magic.elfmag[EI_MAG1] = ELFMAG1; | 1225 | magic.elfmag[EI_MAG1] = ELFMAG1; |
| 1224 | magic.elfmag[EI_MAG2] = ELFMAG2; | 1226 | magic.elfmag[EI_MAG2] = ELFMAG2; |
| 1225 | magic.elfmag[EI_MAG3] = ELFMAG3; | 1227 | magic.elfmag[EI_MAG3] = ELFMAG3; |
| 1226 | if (get_user(word, header) == 0 && word == magic.cmp) | 1228 | /* |
| 1229 | * Switch to the user "segment" for get_user(), | ||
| 1230 | * then put back what elf_core_dump() had in place. | ||
| 1231 | */ | ||
| 1232 | set_fs(USER_DS); | ||
| 1233 | if (unlikely(get_user(word, header))) | ||
| 1234 | word = 0; | ||
| 1235 | set_fs(fs); | ||
| 1236 | if (word == magic.cmp) | ||
| 1227 | return PAGE_SIZE; | 1237 | return PAGE_SIZE; |
| 1228 | } | 1238 | } |
| 1229 | 1239 | ||
diff --git a/fs/btrfs/Kconfig b/fs/btrfs/Kconfig index f8fcf999ea1b..7bb3c020e570 100644 --- a/fs/btrfs/Kconfig +++ b/fs/btrfs/Kconfig | |||
| @@ -16,3 +16,16 @@ config BTRFS_FS | |||
| 16 | module will be called btrfs. | 16 | module will be called btrfs. |
| 17 | 17 | ||
| 18 | If unsure, say N. | 18 | If unsure, say N. |
| 19 | |||
| 20 | config BTRFS_FS_POSIX_ACL | ||
| 21 | bool "Btrfs POSIX Access Control Lists" | ||
| 22 | depends on BTRFS_FS | ||
| 23 | select FS_POSIX_ACL | ||
| 24 | help | ||
| 25 | POSIX Access Control Lists (ACLs) support permissions for users and | ||
| 26 | groups beyond the owner/group/world scheme. | ||
| 27 | |||
| 28 | To learn more about Access Control Lists, visit the POSIX ACLs for | ||
| 29 | Linux website <http://acl.bestbits.at/>. | ||
| 30 | |||
| 31 | If you don't know what Access Control Lists are, say N | ||
diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c index 8e2fec05dbe0..c84ca1f5259a 100644 --- a/fs/btrfs/async-thread.c +++ b/fs/btrfs/async-thread.c | |||
| @@ -16,11 +16,11 @@ | |||
| 16 | * Boston, MA 021110-1307, USA. | 16 | * Boston, MA 021110-1307, USA. |
| 17 | */ | 17 | */ |
| 18 | 18 | ||
| 19 | #include <linux/version.h> | ||
| 20 | #include <linux/kthread.h> | 19 | #include <linux/kthread.h> |
| 21 | #include <linux/list.h> | 20 | #include <linux/list.h> |
| 22 | #include <linux/spinlock.h> | 21 | #include <linux/spinlock.h> |
| 23 | # include <linux/freezer.h> | 22 | #include <linux/freezer.h> |
| 23 | #include <linux/ftrace.h> | ||
| 24 | #include "async-thread.h" | 24 | #include "async-thread.h" |
| 25 | 25 | ||
| 26 | #define WORK_QUEUED_BIT 0 | 26 | #define WORK_QUEUED_BIT 0 |
| @@ -143,6 +143,7 @@ static int worker_loop(void *arg) | |||
| 143 | struct btrfs_work *work; | 143 | struct btrfs_work *work; |
| 144 | do { | 144 | do { |
| 145 | spin_lock_irq(&worker->lock); | 145 | spin_lock_irq(&worker->lock); |
| 146 | again_locked: | ||
| 146 | while (!list_empty(&worker->pending)) { | 147 | while (!list_empty(&worker->pending)) { |
| 147 | cur = worker->pending.next; | 148 | cur = worker->pending.next; |
| 148 | work = list_entry(cur, struct btrfs_work, list); | 149 | work = list_entry(cur, struct btrfs_work, list); |
| @@ -165,14 +166,50 @@ static int worker_loop(void *arg) | |||
| 165 | check_idle_worker(worker); | 166 | check_idle_worker(worker); |
| 166 | 167 | ||
| 167 | } | 168 | } |
| 168 | worker->working = 0; | ||
| 169 | if (freezing(current)) { | 169 | if (freezing(current)) { |
| 170 | worker->working = 0; | ||
| 171 | spin_unlock_irq(&worker->lock); | ||
| 170 | refrigerator(); | 172 | refrigerator(); |
| 171 | } else { | 173 | } else { |
| 172 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 173 | spin_unlock_irq(&worker->lock); | 174 | spin_unlock_irq(&worker->lock); |
| 174 | if (!kthread_should_stop()) | 175 | if (!kthread_should_stop()) { |
| 176 | cpu_relax(); | ||
| 177 | /* | ||
| 178 | * we've dropped the lock, did someone else | ||
| 179 | * jump_in? | ||
| 180 | */ | ||
| 181 | smp_mb(); | ||
| 182 | if (!list_empty(&worker->pending)) | ||
| 183 | continue; | ||
| 184 | |||
| 185 | /* | ||
| 186 | * this short schedule allows more work to | ||
| 187 | * come in without the queue functions | ||
| 188 | * needing to go through wake_up_process() | ||
| 189 | * | ||
| 190 | * worker->working is still 1, so nobody | ||
| 191 | * is going to try and wake us up | ||
| 192 | */ | ||
| 193 | schedule_timeout(1); | ||
| 194 | smp_mb(); | ||
| 195 | if (!list_empty(&worker->pending)) | ||
| 196 | continue; | ||
| 197 | |||
| 198 | /* still no more work?, sleep for real */ | ||
| 199 | spin_lock_irq(&worker->lock); | ||
| 200 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 201 | if (!list_empty(&worker->pending)) | ||
| 202 | goto again_locked; | ||
| 203 | |||
| 204 | /* | ||
| 205 | * this makes sure we get a wakeup when someone | ||
| 206 | * adds something new to the queue | ||
| 207 | */ | ||
| 208 | worker->working = 0; | ||
| 209 | spin_unlock_irq(&worker->lock); | ||
| 210 | |||
| 175 | schedule(); | 211 | schedule(); |
| 212 | } | ||
| 176 | __set_current_state(TASK_RUNNING); | 213 | __set_current_state(TASK_RUNNING); |
| 177 | } | 214 | } |
| 178 | } while (!kthread_should_stop()); | 215 | } while (!kthread_should_stop()); |
| @@ -350,13 +387,14 @@ int btrfs_requeue_work(struct btrfs_work *work) | |||
| 350 | { | 387 | { |
| 351 | struct btrfs_worker_thread *worker = work->worker; | 388 | struct btrfs_worker_thread *worker = work->worker; |
| 352 | unsigned long flags; | 389 | unsigned long flags; |
| 390 | int wake = 0; | ||
| 353 | 391 | ||
| 354 | if (test_and_set_bit(WORK_QUEUED_BIT, &work->flags)) | 392 | if (test_and_set_bit(WORK_QUEUED_BIT, &work->flags)) |
| 355 | goto out; | 393 | goto out; |
| 356 | 394 | ||
| 357 | spin_lock_irqsave(&worker->lock, flags); | 395 | spin_lock_irqsave(&worker->lock, flags); |
| 358 | atomic_inc(&worker->num_pending); | ||
| 359 | list_add_tail(&work->list, &worker->pending); | 396 | list_add_tail(&work->list, &worker->pending); |
| 397 | atomic_inc(&worker->num_pending); | ||
| 360 | 398 | ||
| 361 | /* by definition we're busy, take ourselves off the idle | 399 | /* by definition we're busy, take ourselves off the idle |
| 362 | * list | 400 | * list |
| @@ -368,10 +406,16 @@ int btrfs_requeue_work(struct btrfs_work *work) | |||
| 368 | &worker->workers->worker_list); | 406 | &worker->workers->worker_list); |
| 369 | spin_unlock_irqrestore(&worker->workers->lock, flags); | 407 | spin_unlock_irqrestore(&worker->workers->lock, flags); |
| 370 | } | 408 | } |
| 409 | if (!worker->working) { | ||
| 410 | wake = 1; | ||
| 411 | worker->working = 1; | ||
| 412 | } | ||
| 371 | 413 | ||
| 372 | spin_unlock_irqrestore(&worker->lock, flags); | 414 | spin_unlock_irqrestore(&worker->lock, flags); |
| 373 | 415 | if (wake) | |
| 416 | wake_up_process(worker->task); | ||
| 374 | out: | 417 | out: |
| 418 | |||
| 375 | return 0; | 419 | return 0; |
| 376 | } | 420 | } |
| 377 | 421 | ||
| @@ -398,9 +442,10 @@ int btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work) | |||
| 398 | } | 442 | } |
| 399 | 443 | ||
| 400 | spin_lock_irqsave(&worker->lock, flags); | 444 | spin_lock_irqsave(&worker->lock, flags); |
| 445 | |||
| 446 | list_add_tail(&work->list, &worker->pending); | ||
| 401 | atomic_inc(&worker->num_pending); | 447 | atomic_inc(&worker->num_pending); |
| 402 | check_busy_worker(worker); | 448 | check_busy_worker(worker); |
| 403 | list_add_tail(&work->list, &worker->pending); | ||
| 404 | 449 | ||
| 405 | /* | 450 | /* |
| 406 | * avoid calling into wake_up_process if this thread has already | 451 | * avoid calling into wake_up_process if this thread has already |
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index ee848d8585d9..ab07627084f1 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c | |||
| @@ -32,7 +32,6 @@ | |||
| 32 | #include <linux/swap.h> | 32 | #include <linux/swap.h> |
| 33 | #include <linux/writeback.h> | 33 | #include <linux/writeback.h> |
| 34 | #include <linux/bit_spinlock.h> | 34 | #include <linux/bit_spinlock.h> |
| 35 | #include <linux/version.h> | ||
| 36 | #include <linux/pagevec.h> | 35 | #include <linux/pagevec.h> |
| 37 | #include "compat.h" | 36 | #include "compat.h" |
| 38 | #include "ctree.h" | 37 | #include "ctree.h" |
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 9e46c0776816..551177c0011a 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
| @@ -54,6 +54,31 @@ struct btrfs_path *btrfs_alloc_path(void) | |||
| 54 | return path; | 54 | return path; |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | /* | ||
| 58 | * set all locked nodes in the path to blocking locks. This should | ||
| 59 | * be done before scheduling | ||
| 60 | */ | ||
| 61 | noinline void btrfs_set_path_blocking(struct btrfs_path *p) | ||
| 62 | { | ||
| 63 | int i; | ||
| 64 | for (i = 0; i < BTRFS_MAX_LEVEL; i++) { | ||
| 65 | if (p->nodes[i] && p->locks[i]) | ||
| 66 | btrfs_set_lock_blocking(p->nodes[i]); | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | /* | ||
| 71 | * reset all the locked nodes in the patch to spinning locks. | ||
| 72 | */ | ||
| 73 | noinline void btrfs_clear_path_blocking(struct btrfs_path *p) | ||
| 74 | { | ||
| 75 | int i; | ||
| 76 | for (i = 0; i < BTRFS_MAX_LEVEL; i++) { | ||
| 77 | if (p->nodes[i] && p->locks[i]) | ||
| 78 | btrfs_clear_lock_blocking(p->nodes[i]); | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 57 | /* this also releases the path */ | 82 | /* this also releases the path */ |
| 58 | void btrfs_free_path(struct btrfs_path *p) | 83 | void btrfs_free_path(struct btrfs_path *p) |
| 59 | { | 84 | { |
| @@ -272,6 +297,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
| 272 | if (IS_ERR(cow)) | 297 | if (IS_ERR(cow)) |
| 273 | return PTR_ERR(cow); | 298 | return PTR_ERR(cow); |
| 274 | 299 | ||
| 300 | /* cow is set to blocking by btrfs_init_new_buffer */ | ||
| 301 | |||
| 275 | copy_extent_buffer(cow, buf, 0, 0, cow->len); | 302 | copy_extent_buffer(cow, buf, 0, 0, cow->len); |
| 276 | btrfs_set_header_bytenr(cow, cow->start); | 303 | btrfs_set_header_bytenr(cow, cow->start); |
| 277 | btrfs_set_header_generation(cow, trans->transid); | 304 | btrfs_set_header_generation(cow, trans->transid); |
| @@ -388,17 +415,20 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
| 388 | WARN_ON(1); | 415 | WARN_ON(1); |
| 389 | } | 416 | } |
| 390 | 417 | ||
| 391 | spin_lock(&root->fs_info->hash_lock); | ||
| 392 | if (btrfs_header_generation(buf) == trans->transid && | 418 | if (btrfs_header_generation(buf) == trans->transid && |
| 393 | btrfs_header_owner(buf) == root->root_key.objectid && | 419 | btrfs_header_owner(buf) == root->root_key.objectid && |
| 394 | !btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN)) { | 420 | !btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN)) { |
| 395 | *cow_ret = buf; | 421 | *cow_ret = buf; |
| 396 | spin_unlock(&root->fs_info->hash_lock); | ||
| 397 | WARN_ON(prealloc_dest); | 422 | WARN_ON(prealloc_dest); |
| 398 | return 0; | 423 | return 0; |
| 399 | } | 424 | } |
| 400 | spin_unlock(&root->fs_info->hash_lock); | 425 | |
| 401 | search_start = buf->start & ~((u64)(1024 * 1024 * 1024) - 1); | 426 | search_start = buf->start & ~((u64)(1024 * 1024 * 1024) - 1); |
| 427 | |||
| 428 | if (parent) | ||
| 429 | btrfs_set_lock_blocking(parent); | ||
| 430 | btrfs_set_lock_blocking(buf); | ||
| 431 | |||
| 402 | ret = __btrfs_cow_block(trans, root, buf, parent, | 432 | ret = __btrfs_cow_block(trans, root, buf, parent, |
| 403 | parent_slot, cow_ret, search_start, 0, | 433 | parent_slot, cow_ret, search_start, 0, |
| 404 | prealloc_dest); | 434 | prealloc_dest); |
| @@ -504,6 +534,8 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, | |||
| 504 | if (parent_nritems == 1) | 534 | if (parent_nritems == 1) |
| 505 | return 0; | 535 | return 0; |
| 506 | 536 | ||
| 537 | btrfs_set_lock_blocking(parent); | ||
| 538 | |||
| 507 | for (i = start_slot; i < end_slot; i++) { | 539 | for (i = start_slot; i < end_slot; i++) { |
| 508 | int close = 1; | 540 | int close = 1; |
| 509 | 541 | ||
| @@ -564,6 +596,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, | |||
| 564 | search_start = last_block; | 596 | search_start = last_block; |
| 565 | 597 | ||
| 566 | btrfs_tree_lock(cur); | 598 | btrfs_tree_lock(cur); |
| 599 | btrfs_set_lock_blocking(cur); | ||
| 567 | err = __btrfs_cow_block(trans, root, cur, parent, i, | 600 | err = __btrfs_cow_block(trans, root, cur, parent, i, |
| 568 | &cur, search_start, | 601 | &cur, search_start, |
| 569 | min(16 * blocksize, | 602 | min(16 * blocksize, |
| @@ -862,6 +895,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
| 862 | return 0; | 895 | return 0; |
| 863 | 896 | ||
| 864 | mid = path->nodes[level]; | 897 | mid = path->nodes[level]; |
| 898 | |||
| 865 | WARN_ON(!path->locks[level]); | 899 | WARN_ON(!path->locks[level]); |
| 866 | WARN_ON(btrfs_header_generation(mid) != trans->transid); | 900 | WARN_ON(btrfs_header_generation(mid) != trans->transid); |
| 867 | 901 | ||
| @@ -884,6 +918,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
| 884 | /* promote the child to a root */ | 918 | /* promote the child to a root */ |
| 885 | child = read_node_slot(root, mid, 0); | 919 | child = read_node_slot(root, mid, 0); |
| 886 | btrfs_tree_lock(child); | 920 | btrfs_tree_lock(child); |
| 921 | btrfs_set_lock_blocking(child); | ||
| 887 | BUG_ON(!child); | 922 | BUG_ON(!child); |
| 888 | ret = btrfs_cow_block(trans, root, child, mid, 0, &child, 0); | 923 | ret = btrfs_cow_block(trans, root, child, mid, 0, &child, 0); |
| 889 | BUG_ON(ret); | 924 | BUG_ON(ret); |
| @@ -900,6 +935,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
| 900 | 935 | ||
| 901 | add_root_to_dirty_list(root); | 936 | add_root_to_dirty_list(root); |
| 902 | btrfs_tree_unlock(child); | 937 | btrfs_tree_unlock(child); |
| 938 | |||
| 903 | path->locks[level] = 0; | 939 | path->locks[level] = 0; |
| 904 | path->nodes[level] = NULL; | 940 | path->nodes[level] = NULL; |
| 905 | clean_tree_block(trans, root, mid); | 941 | clean_tree_block(trans, root, mid); |
| @@ -924,6 +960,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
| 924 | left = read_node_slot(root, parent, pslot - 1); | 960 | left = read_node_slot(root, parent, pslot - 1); |
| 925 | if (left) { | 961 | if (left) { |
| 926 | btrfs_tree_lock(left); | 962 | btrfs_tree_lock(left); |
| 963 | btrfs_set_lock_blocking(left); | ||
| 927 | wret = btrfs_cow_block(trans, root, left, | 964 | wret = btrfs_cow_block(trans, root, left, |
| 928 | parent, pslot - 1, &left, 0); | 965 | parent, pslot - 1, &left, 0); |
| 929 | if (wret) { | 966 | if (wret) { |
| @@ -934,6 +971,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
| 934 | right = read_node_slot(root, parent, pslot + 1); | 971 | right = read_node_slot(root, parent, pslot + 1); |
| 935 | if (right) { | 972 | if (right) { |
| 936 | btrfs_tree_lock(right); | 973 | btrfs_tree_lock(right); |
| 974 | btrfs_set_lock_blocking(right); | ||
| 937 | wret = btrfs_cow_block(trans, root, right, | 975 | wret = btrfs_cow_block(trans, root, right, |
| 938 | parent, pslot + 1, &right, 0); | 976 | parent, pslot + 1, &right, 0); |
| 939 | if (wret) { | 977 | if (wret) { |
| @@ -1109,6 +1147,8 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, | |||
| 1109 | u32 left_nr; | 1147 | u32 left_nr; |
| 1110 | 1148 | ||
| 1111 | btrfs_tree_lock(left); | 1149 | btrfs_tree_lock(left); |
| 1150 | btrfs_set_lock_blocking(left); | ||
| 1151 | |||
| 1112 | left_nr = btrfs_header_nritems(left); | 1152 | left_nr = btrfs_header_nritems(left); |
| 1113 | if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { | 1153 | if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { |
| 1114 | wret = 1; | 1154 | wret = 1; |
| @@ -1155,7 +1195,10 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, | |||
| 1155 | */ | 1195 | */ |
| 1156 | if (right) { | 1196 | if (right) { |
| 1157 | u32 right_nr; | 1197 | u32 right_nr; |
| 1198 | |||
| 1158 | btrfs_tree_lock(right); | 1199 | btrfs_tree_lock(right); |
| 1200 | btrfs_set_lock_blocking(right); | ||
| 1201 | |||
| 1159 | right_nr = btrfs_header_nritems(right); | 1202 | right_nr = btrfs_header_nritems(right); |
| 1160 | if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { | 1203 | if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { |
| 1161 | wret = 1; | 1204 | wret = 1; |
| @@ -1210,8 +1253,7 @@ static noinline void reada_for_search(struct btrfs_root *root, | |||
| 1210 | struct btrfs_disk_key disk_key; | 1253 | struct btrfs_disk_key disk_key; |
| 1211 | u32 nritems; | 1254 | u32 nritems; |
| 1212 | u64 search; | 1255 | u64 search; |
| 1213 | u64 lowest_read; | 1256 | u64 target; |
| 1214 | u64 highest_read; | ||
| 1215 | u64 nread = 0; | 1257 | u64 nread = 0; |
| 1216 | int direction = path->reada; | 1258 | int direction = path->reada; |
| 1217 | struct extent_buffer *eb; | 1259 | struct extent_buffer *eb; |
| @@ -1235,8 +1277,7 @@ static noinline void reada_for_search(struct btrfs_root *root, | |||
| 1235 | return; | 1277 | return; |
| 1236 | } | 1278 | } |
| 1237 | 1279 | ||
| 1238 | highest_read = search; | 1280 | target = search; |
| 1239 | lowest_read = search; | ||
| 1240 | 1281 | ||
| 1241 | nritems = btrfs_header_nritems(node); | 1282 | nritems = btrfs_header_nritems(node); |
| 1242 | nr = slot; | 1283 | nr = slot; |
| @@ -1256,27 +1297,80 @@ static noinline void reada_for_search(struct btrfs_root *root, | |||
| 1256 | break; | 1297 | break; |
| 1257 | } | 1298 | } |
| 1258 | search = btrfs_node_blockptr(node, nr); | 1299 | search = btrfs_node_blockptr(node, nr); |
| 1259 | if ((search >= lowest_read && search <= highest_read) || | 1300 | if ((search <= target && target - search <= 65536) || |
| 1260 | (search < lowest_read && lowest_read - search <= 16384) || | 1301 | (search > target && search - target <= 65536)) { |
| 1261 | (search > highest_read && search - highest_read <= 16384)) { | ||
| 1262 | readahead_tree_block(root, search, blocksize, | 1302 | readahead_tree_block(root, search, blocksize, |
| 1263 | btrfs_node_ptr_generation(node, nr)); | 1303 | btrfs_node_ptr_generation(node, nr)); |
| 1264 | nread += blocksize; | 1304 | nread += blocksize; |
| 1265 | } | 1305 | } |
| 1266 | nscan++; | 1306 | nscan++; |
| 1267 | if (path->reada < 2 && (nread > (64 * 1024) || nscan > 32)) | 1307 | if ((nread > 65536 || nscan > 32)) |
| 1268 | break; | 1308 | break; |
| 1309 | } | ||
| 1310 | } | ||
| 1269 | 1311 | ||
| 1270 | if (nread > (256 * 1024) || nscan > 128) | 1312 | /* |
| 1271 | break; | 1313 | * returns -EAGAIN if it had to drop the path, or zero if everything was in |
| 1314 | * cache | ||
| 1315 | */ | ||
| 1316 | static noinline int reada_for_balance(struct btrfs_root *root, | ||
| 1317 | struct btrfs_path *path, int level) | ||
| 1318 | { | ||
| 1319 | int slot; | ||
| 1320 | int nritems; | ||
| 1321 | struct extent_buffer *parent; | ||
| 1322 | struct extent_buffer *eb; | ||
| 1323 | u64 gen; | ||
| 1324 | u64 block1 = 0; | ||
| 1325 | u64 block2 = 0; | ||
| 1326 | int ret = 0; | ||
| 1327 | int blocksize; | ||
| 1272 | 1328 | ||
| 1273 | if (search < lowest_read) | 1329 | parent = path->nodes[level - 1]; |
| 1274 | lowest_read = search; | 1330 | if (!parent) |
| 1275 | if (search > highest_read) | 1331 | return 0; |
| 1276 | highest_read = search; | 1332 | |
| 1333 | nritems = btrfs_header_nritems(parent); | ||
| 1334 | slot = path->slots[level]; | ||
| 1335 | blocksize = btrfs_level_size(root, level); | ||
| 1336 | |||
| 1337 | if (slot > 0) { | ||
| 1338 | block1 = btrfs_node_blockptr(parent, slot - 1); | ||
| 1339 | gen = btrfs_node_ptr_generation(parent, slot - 1); | ||
| 1340 | eb = btrfs_find_tree_block(root, block1, blocksize); | ||
| 1341 | if (eb && btrfs_buffer_uptodate(eb, gen)) | ||
| 1342 | block1 = 0; | ||
| 1343 | free_extent_buffer(eb); | ||
| 1344 | } | ||
| 1345 | if (slot < nritems) { | ||
| 1346 | block2 = btrfs_node_blockptr(parent, slot + 1); | ||
| 1347 | gen = btrfs_node_ptr_generation(parent, slot + 1); | ||
| 1348 | eb = btrfs_find_tree_block(root, block2, blocksize); | ||
| 1349 | if (eb && btrfs_buffer_uptodate(eb, gen)) | ||
| 1350 | block2 = 0; | ||
| 1351 | free_extent_buffer(eb); | ||
| 1352 | } | ||
| 1353 | if (block1 || block2) { | ||
| 1354 | ret = -EAGAIN; | ||
| 1355 | btrfs_release_path(root, path); | ||
| 1356 | if (block1) | ||
| 1357 | readahead_tree_block(root, block1, blocksize, 0); | ||
| 1358 | if (block2) | ||
| 1359 | readahead_tree_block(root, block2, blocksize, 0); | ||
| 1360 | |||
| 1361 | if (block1) { | ||
| 1362 | eb = read_tree_block(root, block1, blocksize, 0); | ||
| 1363 | free_extent_buffer(eb); | ||
| 1364 | } | ||
| 1365 | if (block1) { | ||
| 1366 | eb = read_tree_block(root, block2, blocksize, 0); | ||
| 1367 | free_extent_buffer(eb); | ||
| 1368 | } | ||
| 1277 | } | 1369 | } |
| 1370 | return ret; | ||
| 1278 | } | 1371 | } |
| 1279 | 1372 | ||
| 1373 | |||
| 1280 | /* | 1374 | /* |
| 1281 | * when we walk down the tree, it is usually safe to unlock the higher layers | 1375 | * when we walk down the tree, it is usually safe to unlock the higher layers |
| 1282 | * in the tree. The exceptions are when our path goes through slot 0, because | 1376 | * in the tree. The exceptions are when our path goes through slot 0, because |
| @@ -1328,6 +1422,32 @@ static noinline void unlock_up(struct btrfs_path *path, int level, | |||
| 1328 | } | 1422 | } |
| 1329 | 1423 | ||
| 1330 | /* | 1424 | /* |
| 1425 | * This releases any locks held in the path starting at level and | ||
| 1426 | * going all the way up to the root. | ||
| 1427 | * | ||
| 1428 | * btrfs_search_slot will keep the lock held on higher nodes in a few | ||
| 1429 | * corner cases, such as COW of the block at slot zero in the node. This | ||
| 1430 | * ignores those rules, and it should only be called when there are no | ||
| 1431 | * more updates to be done higher up in the tree. | ||
| 1432 | */ | ||
| 1433 | noinline void btrfs_unlock_up_safe(struct btrfs_path *path, int level) | ||
| 1434 | { | ||
| 1435 | int i; | ||
| 1436 | |||
| 1437 | if (path->keep_locks || path->lowest_level) | ||
| 1438 | return; | ||
| 1439 | |||
| 1440 | for (i = level; i < BTRFS_MAX_LEVEL; i++) { | ||
| 1441 | if (!path->nodes[i]) | ||
| 1442 | continue; | ||
| 1443 | if (!path->locks[i]) | ||
| 1444 | continue; | ||
| 1445 | btrfs_tree_unlock(path->nodes[i]); | ||
| 1446 | path->locks[i] = 0; | ||
| 1447 | } | ||
| 1448 | } | ||
| 1449 | |||
| 1450 | /* | ||
| 1331 | * look for key in the tree. path is filled in with nodes along the way | 1451 | * look for key in the tree. path is filled in with nodes along the way |
| 1332 | * if key is found, we return zero and you can find the item in the leaf | 1452 | * if key is found, we return zero and you can find the item in the leaf |
| 1333 | * level of the path (level 0) | 1453 | * level of the path (level 0) |
| @@ -1387,31 +1507,30 @@ again: | |||
| 1387 | int wret; | 1507 | int wret; |
| 1388 | 1508 | ||
| 1389 | /* is a cow on this block not required */ | 1509 | /* is a cow on this block not required */ |
| 1390 | spin_lock(&root->fs_info->hash_lock); | ||
| 1391 | if (btrfs_header_generation(b) == trans->transid && | 1510 | if (btrfs_header_generation(b) == trans->transid && |
| 1392 | btrfs_header_owner(b) == root->root_key.objectid && | 1511 | btrfs_header_owner(b) == root->root_key.objectid && |
| 1393 | !btrfs_header_flag(b, BTRFS_HEADER_FLAG_WRITTEN)) { | 1512 | !btrfs_header_flag(b, BTRFS_HEADER_FLAG_WRITTEN)) { |
| 1394 | spin_unlock(&root->fs_info->hash_lock); | ||
| 1395 | goto cow_done; | 1513 | goto cow_done; |
| 1396 | } | 1514 | } |
| 1397 | spin_unlock(&root->fs_info->hash_lock); | ||
| 1398 | 1515 | ||
| 1399 | /* ok, we have to cow, is our old prealloc the right | 1516 | /* ok, we have to cow, is our old prealloc the right |
| 1400 | * size? | 1517 | * size? |
| 1401 | */ | 1518 | */ |
| 1402 | if (prealloc_block.objectid && | 1519 | if (prealloc_block.objectid && |
| 1403 | prealloc_block.offset != b->len) { | 1520 | prealloc_block.offset != b->len) { |
| 1521 | btrfs_release_path(root, p); | ||
| 1404 | btrfs_free_reserved_extent(root, | 1522 | btrfs_free_reserved_extent(root, |
| 1405 | prealloc_block.objectid, | 1523 | prealloc_block.objectid, |
| 1406 | prealloc_block.offset); | 1524 | prealloc_block.offset); |
| 1407 | prealloc_block.objectid = 0; | 1525 | prealloc_block.objectid = 0; |
| 1526 | goto again; | ||
| 1408 | } | 1527 | } |
| 1409 | 1528 | ||
| 1410 | /* | 1529 | /* |
| 1411 | * for higher level blocks, try not to allocate blocks | 1530 | * for higher level blocks, try not to allocate blocks |
| 1412 | * with the block and the parent locks held. | 1531 | * with the block and the parent locks held. |
| 1413 | */ | 1532 | */ |
| 1414 | if (level > 1 && !prealloc_block.objectid && | 1533 | if (level > 0 && !prealloc_block.objectid && |
| 1415 | btrfs_path_lock_waiting(p, level)) { | 1534 | btrfs_path_lock_waiting(p, level)) { |
| 1416 | u32 size = b->len; | 1535 | u32 size = b->len; |
| 1417 | u64 hint = b->start; | 1536 | u64 hint = b->start; |
| @@ -1425,6 +1544,8 @@ again: | |||
| 1425 | goto again; | 1544 | goto again; |
| 1426 | } | 1545 | } |
| 1427 | 1546 | ||
| 1547 | btrfs_set_path_blocking(p); | ||
| 1548 | |||
| 1428 | wret = btrfs_cow_block(trans, root, b, | 1549 | wret = btrfs_cow_block(trans, root, b, |
| 1429 | p->nodes[level + 1], | 1550 | p->nodes[level + 1], |
| 1430 | p->slots[level + 1], | 1551 | p->slots[level + 1], |
| @@ -1446,6 +1567,22 @@ cow_done: | |||
| 1446 | if (!p->skip_locking) | 1567 | if (!p->skip_locking) |
| 1447 | p->locks[level] = 1; | 1568 | p->locks[level] = 1; |
| 1448 | 1569 | ||
| 1570 | btrfs_clear_path_blocking(p); | ||
| 1571 | |||
| 1572 | /* | ||
| 1573 | * we have a lock on b and as long as we aren't changing | ||
| 1574 | * the tree, there is no way to for the items in b to change. | ||
| 1575 | * It is safe to drop the lock on our parent before we | ||
| 1576 | * go through the expensive btree search on b. | ||
| 1577 | * | ||
| 1578 | * If cow is true, then we might be changing slot zero, | ||
| 1579 | * which may require changing the parent. So, we can't | ||
| 1580 | * drop the lock until after we know which slot we're | ||
| 1581 | * operating on. | ||
| 1582 | */ | ||
| 1583 | if (!cow) | ||
| 1584 | btrfs_unlock_up_safe(p, level + 1); | ||
| 1585 | |||
| 1449 | ret = check_block(root, p, level); | 1586 | ret = check_block(root, p, level); |
| 1450 | if (ret) { | 1587 | if (ret) { |
| 1451 | ret = -1; | 1588 | ret = -1; |
| @@ -1453,6 +1590,7 @@ cow_done: | |||
| 1453 | } | 1590 | } |
| 1454 | 1591 | ||
| 1455 | ret = bin_search(b, key, level, &slot); | 1592 | ret = bin_search(b, key, level, &slot); |
| 1593 | |||
| 1456 | if (level != 0) { | 1594 | if (level != 0) { |
| 1457 | if (ret && slot > 0) | 1595 | if (ret && slot > 0) |
| 1458 | slot -= 1; | 1596 | slot -= 1; |
| @@ -1460,7 +1598,16 @@ cow_done: | |||
| 1460 | if ((p->search_for_split || ins_len > 0) && | 1598 | if ((p->search_for_split || ins_len > 0) && |
| 1461 | btrfs_header_nritems(b) >= | 1599 | btrfs_header_nritems(b) >= |
| 1462 | BTRFS_NODEPTRS_PER_BLOCK(root) - 3) { | 1600 | BTRFS_NODEPTRS_PER_BLOCK(root) - 3) { |
| 1463 | int sret = split_node(trans, root, p, level); | 1601 | int sret; |
| 1602 | |||
| 1603 | sret = reada_for_balance(root, p, level); | ||
| 1604 | if (sret) | ||
| 1605 | goto again; | ||
| 1606 | |||
| 1607 | btrfs_set_path_blocking(p); | ||
| 1608 | sret = split_node(trans, root, p, level); | ||
| 1609 | btrfs_clear_path_blocking(p); | ||
| 1610 | |||
| 1464 | BUG_ON(sret > 0); | 1611 | BUG_ON(sret > 0); |
| 1465 | if (sret) { | 1612 | if (sret) { |
| 1466 | ret = sret; | 1613 | ret = sret; |
| @@ -1468,9 +1615,19 @@ cow_done: | |||
| 1468 | } | 1615 | } |
| 1469 | b = p->nodes[level]; | 1616 | b = p->nodes[level]; |
| 1470 | slot = p->slots[level]; | 1617 | slot = p->slots[level]; |
| 1471 | } else if (ins_len < 0) { | 1618 | } else if (ins_len < 0 && |
| 1472 | int sret = balance_level(trans, root, p, | 1619 | btrfs_header_nritems(b) < |
| 1473 | level); | 1620 | BTRFS_NODEPTRS_PER_BLOCK(root) / 4) { |
| 1621 | int sret; | ||
| 1622 | |||
| 1623 | sret = reada_for_balance(root, p, level); | ||
| 1624 | if (sret) | ||
| 1625 | goto again; | ||
| 1626 | |||
| 1627 | btrfs_set_path_blocking(p); | ||
| 1628 | sret = balance_level(trans, root, p, level); | ||
| 1629 | btrfs_clear_path_blocking(p); | ||
| 1630 | |||
| 1474 | if (sret) { | 1631 | if (sret) { |
| 1475 | ret = sret; | 1632 | ret = sret; |
| 1476 | goto done; | 1633 | goto done; |
| @@ -1504,7 +1661,7 @@ cow_done: | |||
| 1504 | * of the btree by dropping locks before | 1661 | * of the btree by dropping locks before |
| 1505 | * we read. | 1662 | * we read. |
| 1506 | */ | 1663 | */ |
| 1507 | if (level > 1) { | 1664 | if (level > 0) { |
| 1508 | btrfs_release_path(NULL, p); | 1665 | btrfs_release_path(NULL, p); |
| 1509 | if (tmp) | 1666 | if (tmp) |
| 1510 | free_extent_buffer(tmp); | 1667 | free_extent_buffer(tmp); |
| @@ -1519,6 +1676,7 @@ cow_done: | |||
| 1519 | free_extent_buffer(tmp); | 1676 | free_extent_buffer(tmp); |
| 1520 | goto again; | 1677 | goto again; |
| 1521 | } else { | 1678 | } else { |
| 1679 | btrfs_set_path_blocking(p); | ||
| 1522 | if (tmp) | 1680 | if (tmp) |
| 1523 | free_extent_buffer(tmp); | 1681 | free_extent_buffer(tmp); |
| 1524 | if (should_reada) | 1682 | if (should_reada) |
| @@ -1528,14 +1686,29 @@ cow_done: | |||
| 1528 | b = read_node_slot(root, b, slot); | 1686 | b = read_node_slot(root, b, slot); |
| 1529 | } | 1687 | } |
| 1530 | } | 1688 | } |
| 1531 | if (!p->skip_locking) | 1689 | if (!p->skip_locking) { |
| 1532 | btrfs_tree_lock(b); | 1690 | int lret; |
| 1691 | |||
| 1692 | btrfs_clear_path_blocking(p); | ||
| 1693 | lret = btrfs_try_spin_lock(b); | ||
| 1694 | |||
| 1695 | if (!lret) { | ||
| 1696 | btrfs_set_path_blocking(p); | ||
| 1697 | btrfs_tree_lock(b); | ||
| 1698 | btrfs_clear_path_blocking(p); | ||
| 1699 | } | ||
| 1700 | } | ||
| 1533 | } else { | 1701 | } else { |
| 1534 | p->slots[level] = slot; | 1702 | p->slots[level] = slot; |
| 1535 | if (ins_len > 0 && | 1703 | if (ins_len > 0 && |
| 1536 | btrfs_leaf_free_space(root, b) < ins_len) { | 1704 | btrfs_leaf_free_space(root, b) < ins_len) { |
| 1537 | int sret = split_leaf(trans, root, key, | 1705 | int sret; |
| 1706 | |||
| 1707 | btrfs_set_path_blocking(p); | ||
| 1708 | sret = split_leaf(trans, root, key, | ||
| 1538 | p, ins_len, ret == 0); | 1709 | p, ins_len, ret == 0); |
| 1710 | btrfs_clear_path_blocking(p); | ||
| 1711 | |||
| 1539 | BUG_ON(sret > 0); | 1712 | BUG_ON(sret > 0); |
| 1540 | if (sret) { | 1713 | if (sret) { |
| 1541 | ret = sret; | 1714 | ret = sret; |
| @@ -1549,12 +1722,16 @@ cow_done: | |||
| 1549 | } | 1722 | } |
| 1550 | ret = 1; | 1723 | ret = 1; |
| 1551 | done: | 1724 | done: |
| 1725 | /* | ||
| 1726 | * we don't really know what they plan on doing with the path | ||
| 1727 | * from here on, so for now just mark it as blocking | ||
| 1728 | */ | ||
| 1729 | btrfs_set_path_blocking(p); | ||
| 1552 | if (prealloc_block.objectid) { | 1730 | if (prealloc_block.objectid) { |
| 1553 | btrfs_free_reserved_extent(root, | 1731 | btrfs_free_reserved_extent(root, |
| 1554 | prealloc_block.objectid, | 1732 | prealloc_block.objectid, |
| 1555 | prealloc_block.offset); | 1733 | prealloc_block.offset); |
| 1556 | } | 1734 | } |
| 1557 | |||
| 1558 | return ret; | 1735 | return ret; |
| 1559 | } | 1736 | } |
| 1560 | 1737 | ||
| @@ -1578,6 +1755,8 @@ int btrfs_merge_path(struct btrfs_trans_handle *trans, | |||
| 1578 | ret = btrfs_cow_block(trans, root, eb, NULL, 0, &eb, 0); | 1755 | ret = btrfs_cow_block(trans, root, eb, NULL, 0, &eb, 0); |
| 1579 | BUG_ON(ret); | 1756 | BUG_ON(ret); |
| 1580 | 1757 | ||
| 1758 | btrfs_set_lock_blocking(eb); | ||
| 1759 | |||
| 1581 | parent = eb; | 1760 | parent = eb; |
| 1582 | while (1) { | 1761 | while (1) { |
| 1583 | level = btrfs_header_level(parent); | 1762 | level = btrfs_header_level(parent); |
| @@ -1602,6 +1781,7 @@ int btrfs_merge_path(struct btrfs_trans_handle *trans, | |||
| 1602 | eb = read_tree_block(root, bytenr, blocksize, | 1781 | eb = read_tree_block(root, bytenr, blocksize, |
| 1603 | generation); | 1782 | generation); |
| 1604 | btrfs_tree_lock(eb); | 1783 | btrfs_tree_lock(eb); |
| 1784 | btrfs_set_lock_blocking(eb); | ||
| 1605 | } | 1785 | } |
| 1606 | 1786 | ||
| 1607 | /* | 1787 | /* |
| @@ -1626,6 +1806,7 @@ int btrfs_merge_path(struct btrfs_trans_handle *trans, | |||
| 1626 | eb = read_tree_block(root, bytenr, blocksize, | 1806 | eb = read_tree_block(root, bytenr, blocksize, |
| 1627 | generation); | 1807 | generation); |
| 1628 | btrfs_tree_lock(eb); | 1808 | btrfs_tree_lock(eb); |
| 1809 | btrfs_set_lock_blocking(eb); | ||
| 1629 | } | 1810 | } |
| 1630 | 1811 | ||
| 1631 | ret = btrfs_cow_block(trans, root, eb, parent, slot, | 1812 | ret = btrfs_cow_block(trans, root, eb, parent, slot, |
| @@ -2172,6 +2353,8 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root | |||
| 2172 | 2353 | ||
| 2173 | right = read_node_slot(root, upper, slot + 1); | 2354 | right = read_node_slot(root, upper, slot + 1); |
| 2174 | btrfs_tree_lock(right); | 2355 | btrfs_tree_lock(right); |
| 2356 | btrfs_set_lock_blocking(right); | ||
| 2357 | |||
| 2175 | free_space = btrfs_leaf_free_space(root, right); | 2358 | free_space = btrfs_leaf_free_space(root, right); |
| 2176 | if (free_space < data_size) | 2359 | if (free_space < data_size) |
| 2177 | goto out_unlock; | 2360 | goto out_unlock; |
| @@ -2367,6 +2550,8 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
| 2367 | 2550 | ||
| 2368 | left = read_node_slot(root, path->nodes[1], slot - 1); | 2551 | left = read_node_slot(root, path->nodes[1], slot - 1); |
| 2369 | btrfs_tree_lock(left); | 2552 | btrfs_tree_lock(left); |
| 2553 | btrfs_set_lock_blocking(left); | ||
| 2554 | |||
| 2370 | free_space = btrfs_leaf_free_space(root, left); | 2555 | free_space = btrfs_leaf_free_space(root, left); |
| 2371 | if (free_space < data_size) { | 2556 | if (free_space < data_size) { |
| 2372 | ret = 1; | 2557 | ret = 1; |
| @@ -2825,6 +3010,12 @@ int btrfs_split_item(struct btrfs_trans_handle *trans, | |||
| 2825 | path->keep_locks = 0; | 3010 | path->keep_locks = 0; |
| 2826 | BUG_ON(ret); | 3011 | BUG_ON(ret); |
| 2827 | 3012 | ||
| 3013 | /* | ||
| 3014 | * make sure any changes to the path from split_leaf leave it | ||
| 3015 | * in a blocking state | ||
| 3016 | */ | ||
| 3017 | btrfs_set_path_blocking(path); | ||
| 3018 | |||
| 2828 | leaf = path->nodes[0]; | 3019 | leaf = path->nodes[0]; |
| 2829 | BUG_ON(btrfs_leaf_free_space(root, leaf) < sizeof(struct btrfs_item)); | 3020 | BUG_ON(btrfs_leaf_free_space(root, leaf) < sizeof(struct btrfs_item)); |
| 2830 | 3021 | ||
| @@ -3354,6 +3545,7 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, | |||
| 3354 | BUG(); | 3545 | BUG(); |
| 3355 | } | 3546 | } |
| 3356 | out: | 3547 | out: |
| 3548 | btrfs_unlock_up_safe(path, 1); | ||
| 3357 | return ret; | 3549 | return ret; |
| 3358 | } | 3550 | } |
| 3359 | 3551 | ||
| @@ -3441,15 +3633,22 @@ noinline int btrfs_del_leaf(struct btrfs_trans_handle *trans, | |||
| 3441 | { | 3633 | { |
| 3442 | int ret; | 3634 | int ret; |
| 3443 | u64 root_gen = btrfs_header_generation(path->nodes[1]); | 3635 | u64 root_gen = btrfs_header_generation(path->nodes[1]); |
| 3636 | u64 parent_start = path->nodes[1]->start; | ||
| 3637 | u64 parent_owner = btrfs_header_owner(path->nodes[1]); | ||
| 3444 | 3638 | ||
| 3445 | ret = del_ptr(trans, root, path, 1, path->slots[1]); | 3639 | ret = del_ptr(trans, root, path, 1, path->slots[1]); |
| 3446 | if (ret) | 3640 | if (ret) |
| 3447 | return ret; | 3641 | return ret; |
| 3448 | 3642 | ||
| 3643 | /* | ||
| 3644 | * btrfs_free_extent is expensive, we want to make sure we | ||
| 3645 | * aren't holding any locks when we call it | ||
| 3646 | */ | ||
| 3647 | btrfs_unlock_up_safe(path, 0); | ||
| 3648 | |||
| 3449 | ret = btrfs_free_extent(trans, root, bytenr, | 3649 | ret = btrfs_free_extent(trans, root, bytenr, |
| 3450 | btrfs_level_size(root, 0), | 3650 | btrfs_level_size(root, 0), |
| 3451 | path->nodes[1]->start, | 3651 | parent_start, parent_owner, |
| 3452 | btrfs_header_owner(path->nodes[1]), | ||
| 3453 | root_gen, 0, 1); | 3652 | root_gen, 0, 1); |
| 3454 | return ret; | 3653 | return ret; |
| 3455 | } | 3654 | } |
| @@ -3721,12 +3920,14 @@ find_next_key: | |||
| 3721 | */ | 3920 | */ |
| 3722 | if (slot >= nritems) { | 3921 | if (slot >= nritems) { |
| 3723 | path->slots[level] = slot; | 3922 | path->slots[level] = slot; |
| 3923 | btrfs_set_path_blocking(path); | ||
| 3724 | sret = btrfs_find_next_key(root, path, min_key, level, | 3924 | sret = btrfs_find_next_key(root, path, min_key, level, |
| 3725 | cache_only, min_trans); | 3925 | cache_only, min_trans); |
| 3726 | if (sret == 0) { | 3926 | if (sret == 0) { |
| 3727 | btrfs_release_path(root, path); | 3927 | btrfs_release_path(root, path); |
| 3728 | goto again; | 3928 | goto again; |
| 3729 | } else { | 3929 | } else { |
| 3930 | btrfs_clear_path_blocking(path); | ||
| 3730 | goto out; | 3931 | goto out; |
| 3731 | } | 3932 | } |
| 3732 | } | 3933 | } |
| @@ -3738,16 +3939,20 @@ find_next_key: | |||
| 3738 | unlock_up(path, level, 1); | 3939 | unlock_up(path, level, 1); |
| 3739 | goto out; | 3940 | goto out; |
| 3740 | } | 3941 | } |
| 3942 | btrfs_set_path_blocking(path); | ||
| 3741 | cur = read_node_slot(root, cur, slot); | 3943 | cur = read_node_slot(root, cur, slot); |
| 3742 | 3944 | ||
| 3743 | btrfs_tree_lock(cur); | 3945 | btrfs_tree_lock(cur); |
| 3946 | |||
| 3744 | path->locks[level - 1] = 1; | 3947 | path->locks[level - 1] = 1; |
| 3745 | path->nodes[level - 1] = cur; | 3948 | path->nodes[level - 1] = cur; |
| 3746 | unlock_up(path, level, 1); | 3949 | unlock_up(path, level, 1); |
| 3950 | btrfs_clear_path_blocking(path); | ||
| 3747 | } | 3951 | } |
| 3748 | out: | 3952 | out: |
| 3749 | if (ret == 0) | 3953 | if (ret == 0) |
| 3750 | memcpy(min_key, &found_key, sizeof(found_key)); | 3954 | memcpy(min_key, &found_key, sizeof(found_key)); |
| 3955 | btrfs_set_path_blocking(path); | ||
| 3751 | return ret; | 3956 | return ret; |
| 3752 | } | 3957 | } |
| 3753 | 3958 | ||
| @@ -3843,6 +4048,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
| 3843 | if (ret < 0) | 4048 | if (ret < 0) |
| 3844 | return ret; | 4049 | return ret; |
| 3845 | 4050 | ||
| 4051 | btrfs_set_path_blocking(path); | ||
| 3846 | nritems = btrfs_header_nritems(path->nodes[0]); | 4052 | nritems = btrfs_header_nritems(path->nodes[0]); |
| 3847 | /* | 4053 | /* |
| 3848 | * by releasing the path above we dropped all our locks. A balance | 4054 | * by releasing the path above we dropped all our locks. A balance |
| @@ -3873,6 +4079,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
| 3873 | free_extent_buffer(next); | 4079 | free_extent_buffer(next); |
| 3874 | } | 4080 | } |
| 3875 | 4081 | ||
| 4082 | /* the path was set to blocking above */ | ||
| 3876 | if (level == 1 && (path->locks[1] || path->skip_locking) && | 4083 | if (level == 1 && (path->locks[1] || path->skip_locking) && |
| 3877 | path->reada) | 4084 | path->reada) |
| 3878 | reada_for_search(root, path, level, slot, 0); | 4085 | reada_for_search(root, path, level, slot, 0); |
| @@ -3881,6 +4088,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
| 3881 | if (!path->skip_locking) { | 4088 | if (!path->skip_locking) { |
| 3882 | WARN_ON(!btrfs_tree_locked(c)); | 4089 | WARN_ON(!btrfs_tree_locked(c)); |
| 3883 | btrfs_tree_lock(next); | 4090 | btrfs_tree_lock(next); |
| 4091 | btrfs_set_lock_blocking(next); | ||
| 3884 | } | 4092 | } |
| 3885 | break; | 4093 | break; |
| 3886 | } | 4094 | } |
| @@ -3897,12 +4105,15 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
| 3897 | path->locks[level] = 1; | 4105 | path->locks[level] = 1; |
| 3898 | if (!level) | 4106 | if (!level) |
| 3899 | break; | 4107 | break; |
| 4108 | |||
| 4109 | btrfs_set_path_blocking(path); | ||
| 3900 | if (level == 1 && path->locks[1] && path->reada) | 4110 | if (level == 1 && path->locks[1] && path->reada) |
| 3901 | reada_for_search(root, path, level, slot, 0); | 4111 | reada_for_search(root, path, level, slot, 0); |
| 3902 | next = read_node_slot(root, next, 0); | 4112 | next = read_node_slot(root, next, 0); |
| 3903 | if (!path->skip_locking) { | 4113 | if (!path->skip_locking) { |
| 3904 | WARN_ON(!btrfs_tree_locked(path->nodes[level])); | 4114 | WARN_ON(!btrfs_tree_locked(path->nodes[level])); |
| 3905 | btrfs_tree_lock(next); | 4115 | btrfs_tree_lock(next); |
| 4116 | btrfs_set_lock_blocking(next); | ||
| 3906 | } | 4117 | } |
| 3907 | } | 4118 | } |
| 3908 | done: | 4119 | done: |
| @@ -3927,6 +4138,7 @@ int btrfs_previous_item(struct btrfs_root *root, | |||
| 3927 | 4138 | ||
| 3928 | while (1) { | 4139 | while (1) { |
| 3929 | if (path->slots[0] == 0) { | 4140 | if (path->slots[0] == 0) { |
| 4141 | btrfs_set_path_blocking(path); | ||
| 3930 | ret = btrfs_prev_leaf(root, path); | 4142 | ret = btrfs_prev_leaf(root, path); |
| 3931 | if (ret != 0) | 4143 | if (ret != 0) |
| 3932 | return ret; | 4144 | return ret; |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index eee060f88113..531db112c8bd 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
| @@ -454,17 +454,11 @@ struct btrfs_timespec { | |||
| 454 | __le32 nsec; | 454 | __le32 nsec; |
| 455 | } __attribute__ ((__packed__)); | 455 | } __attribute__ ((__packed__)); |
| 456 | 456 | ||
| 457 | typedef enum { | 457 | enum btrfs_compression_type { |
| 458 | BTRFS_COMPRESS_NONE = 0, | 458 | BTRFS_COMPRESS_NONE = 0, |
| 459 | BTRFS_COMPRESS_ZLIB = 1, | 459 | BTRFS_COMPRESS_ZLIB = 1, |
| 460 | BTRFS_COMPRESS_LAST = 2, | 460 | BTRFS_COMPRESS_LAST = 2, |
| 461 | } btrfs_compression_type; | 461 | }; |
| 462 | |||
| 463 | /* we don't understand any encryption methods right now */ | ||
| 464 | typedef enum { | ||
| 465 | BTRFS_ENCRYPTION_NONE = 0, | ||
| 466 | BTRFS_ENCRYPTION_LAST = 1, | ||
| 467 | } btrfs_encryption_type; | ||
| 468 | 462 | ||
| 469 | struct btrfs_inode_item { | 463 | struct btrfs_inode_item { |
| 470 | /* nfs style generation number */ | 464 | /* nfs style generation number */ |
| @@ -701,9 +695,7 @@ struct btrfs_fs_info { | |||
| 701 | struct btrfs_transaction *running_transaction; | 695 | struct btrfs_transaction *running_transaction; |
| 702 | wait_queue_head_t transaction_throttle; | 696 | wait_queue_head_t transaction_throttle; |
| 703 | wait_queue_head_t transaction_wait; | 697 | wait_queue_head_t transaction_wait; |
| 704 | |||
| 705 | wait_queue_head_t async_submit_wait; | 698 | wait_queue_head_t async_submit_wait; |
| 706 | wait_queue_head_t tree_log_wait; | ||
| 707 | 699 | ||
| 708 | struct btrfs_super_block super_copy; | 700 | struct btrfs_super_block super_copy; |
| 709 | struct btrfs_super_block super_for_commit; | 701 | struct btrfs_super_block super_for_commit; |
| @@ -711,7 +703,6 @@ struct btrfs_fs_info { | |||
| 711 | struct super_block *sb; | 703 | struct super_block *sb; |
| 712 | struct inode *btree_inode; | 704 | struct inode *btree_inode; |
| 713 | struct backing_dev_info bdi; | 705 | struct backing_dev_info bdi; |
| 714 | spinlock_t hash_lock; | ||
| 715 | struct mutex trans_mutex; | 706 | struct mutex trans_mutex; |
| 716 | struct mutex tree_log_mutex; | 707 | struct mutex tree_log_mutex; |
| 717 | struct mutex transaction_kthread_mutex; | 708 | struct mutex transaction_kthread_mutex; |
| @@ -730,10 +721,6 @@ struct btrfs_fs_info { | |||
| 730 | atomic_t async_submit_draining; | 721 | atomic_t async_submit_draining; |
| 731 | atomic_t nr_async_bios; | 722 | atomic_t nr_async_bios; |
| 732 | atomic_t async_delalloc_pages; | 723 | atomic_t async_delalloc_pages; |
| 733 | atomic_t tree_log_writers; | ||
| 734 | atomic_t tree_log_commit; | ||
| 735 | unsigned long tree_log_batch; | ||
| 736 | u64 tree_log_transid; | ||
| 737 | 724 | ||
| 738 | /* | 725 | /* |
| 739 | * this is used by the balancing code to wait for all the pending | 726 | * this is used by the balancing code to wait for all the pending |
| @@ -833,7 +820,14 @@ struct btrfs_root { | |||
| 833 | struct kobject root_kobj; | 820 | struct kobject root_kobj; |
| 834 | struct completion kobj_unregister; | 821 | struct completion kobj_unregister; |
| 835 | struct mutex objectid_mutex; | 822 | struct mutex objectid_mutex; |
| 823 | |||
| 836 | struct mutex log_mutex; | 824 | struct mutex log_mutex; |
| 825 | wait_queue_head_t log_writer_wait; | ||
| 826 | wait_queue_head_t log_commit_wait[2]; | ||
| 827 | atomic_t log_writers; | ||
| 828 | atomic_t log_commit[2]; | ||
| 829 | unsigned long log_transid; | ||
| 830 | unsigned long log_batch; | ||
| 837 | 831 | ||
| 838 | u64 objectid; | 832 | u64 objectid; |
| 839 | u64 last_trans; | 833 | u64 last_trans; |
| @@ -1841,6 +1835,10 @@ void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p); | |||
| 1841 | struct btrfs_path *btrfs_alloc_path(void); | 1835 | struct btrfs_path *btrfs_alloc_path(void); |
| 1842 | void btrfs_free_path(struct btrfs_path *p); | 1836 | void btrfs_free_path(struct btrfs_path *p); |
| 1843 | void btrfs_init_path(struct btrfs_path *p); | 1837 | void btrfs_init_path(struct btrfs_path *p); |
| 1838 | void btrfs_set_path_blocking(struct btrfs_path *p); | ||
| 1839 | void btrfs_clear_path_blocking(struct btrfs_path *p); | ||
| 1840 | void btrfs_unlock_up_safe(struct btrfs_path *p, int level); | ||
| 1841 | |||
| 1844 | int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 1842 | int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
| 1845 | struct btrfs_path *path, int slot, int nr); | 1843 | struct btrfs_path *path, int slot, int nr); |
| 1846 | int btrfs_del_leaf(struct btrfs_trans_handle *trans, | 1844 | int btrfs_del_leaf(struct btrfs_trans_handle *trans, |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 81a313874ae5..5aebddd71193 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -16,7 +16,6 @@ | |||
| 16 | * Boston, MA 021110-1307, USA. | 16 | * Boston, MA 021110-1307, USA. |
| 17 | */ | 17 | */ |
| 18 | 18 | ||
| 19 | #include <linux/version.h> | ||
| 20 | #include <linux/fs.h> | 19 | #include <linux/fs.h> |
| 21 | #include <linux/blkdev.h> | 20 | #include <linux/blkdev.h> |
| 22 | #include <linux/scatterlist.h> | 21 | #include <linux/scatterlist.h> |
| @@ -800,7 +799,7 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr, | |||
| 800 | ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid); | 799 | ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid); |
| 801 | 800 | ||
| 802 | if (ret == 0) | 801 | if (ret == 0) |
| 803 | buf->flags |= EXTENT_UPTODATE; | 802 | set_bit(EXTENT_BUFFER_UPTODATE, &buf->bflags); |
| 804 | else | 803 | else |
| 805 | WARN_ON(1); | 804 | WARN_ON(1); |
| 806 | return buf; | 805 | return buf; |
| @@ -814,6 +813,10 @@ int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
| 814 | if (btrfs_header_generation(buf) == | 813 | if (btrfs_header_generation(buf) == |
| 815 | root->fs_info->running_transaction->transid) { | 814 | root->fs_info->running_transaction->transid) { |
| 816 | WARN_ON(!btrfs_tree_locked(buf)); | 815 | WARN_ON(!btrfs_tree_locked(buf)); |
| 816 | |||
| 817 | /* ugh, clear_extent_buffer_dirty can be expensive */ | ||
| 818 | btrfs_set_lock_blocking(buf); | ||
| 819 | |||
| 817 | clear_extent_buffer_dirty(&BTRFS_I(btree_inode)->io_tree, | 820 | clear_extent_buffer_dirty(&BTRFS_I(btree_inode)->io_tree, |
| 818 | buf); | 821 | buf); |
| 819 | } | 822 | } |
| @@ -850,6 +853,14 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, | |||
| 850 | spin_lock_init(&root->list_lock); | 853 | spin_lock_init(&root->list_lock); |
| 851 | mutex_init(&root->objectid_mutex); | 854 | mutex_init(&root->objectid_mutex); |
| 852 | mutex_init(&root->log_mutex); | 855 | mutex_init(&root->log_mutex); |
| 856 | init_waitqueue_head(&root->log_writer_wait); | ||
| 857 | init_waitqueue_head(&root->log_commit_wait[0]); | ||
| 858 | init_waitqueue_head(&root->log_commit_wait[1]); | ||
| 859 | atomic_set(&root->log_commit[0], 0); | ||
| 860 | atomic_set(&root->log_commit[1], 0); | ||
| 861 | atomic_set(&root->log_writers, 0); | ||
| 862 | root->log_batch = 0; | ||
| 863 | root->log_transid = 0; | ||
| 853 | extent_io_tree_init(&root->dirty_log_pages, | 864 | extent_io_tree_init(&root->dirty_log_pages, |
| 854 | fs_info->btree_inode->i_mapping, GFP_NOFS); | 865 | fs_info->btree_inode->i_mapping, GFP_NOFS); |
| 855 | 866 | ||
| @@ -934,15 +945,16 @@ int btrfs_free_log_root_tree(struct btrfs_trans_handle *trans, | |||
| 934 | return 0; | 945 | return 0; |
| 935 | } | 946 | } |
| 936 | 947 | ||
| 937 | int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, | 948 | static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans, |
| 938 | struct btrfs_fs_info *fs_info) | 949 | struct btrfs_fs_info *fs_info) |
| 939 | { | 950 | { |
| 940 | struct btrfs_root *root; | 951 | struct btrfs_root *root; |
| 941 | struct btrfs_root *tree_root = fs_info->tree_root; | 952 | struct btrfs_root *tree_root = fs_info->tree_root; |
| 953 | struct extent_buffer *leaf; | ||
| 942 | 954 | ||
| 943 | root = kzalloc(sizeof(*root), GFP_NOFS); | 955 | root = kzalloc(sizeof(*root), GFP_NOFS); |
| 944 | if (!root) | 956 | if (!root) |
| 945 | return -ENOMEM; | 957 | return ERR_PTR(-ENOMEM); |
| 946 | 958 | ||
| 947 | __setup_root(tree_root->nodesize, tree_root->leafsize, | 959 | __setup_root(tree_root->nodesize, tree_root->leafsize, |
| 948 | tree_root->sectorsize, tree_root->stripesize, | 960 | tree_root->sectorsize, tree_root->stripesize, |
| @@ -951,12 +963,23 @@ int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, | |||
| 951 | root->root_key.objectid = BTRFS_TREE_LOG_OBJECTID; | 963 | root->root_key.objectid = BTRFS_TREE_LOG_OBJECTID; |
| 952 | root->root_key.type = BTRFS_ROOT_ITEM_KEY; | 964 | root->root_key.type = BTRFS_ROOT_ITEM_KEY; |
| 953 | root->root_key.offset = BTRFS_TREE_LOG_OBJECTID; | 965 | root->root_key.offset = BTRFS_TREE_LOG_OBJECTID; |
| 966 | /* | ||
| 967 | * log trees do not get reference counted because they go away | ||
| 968 | * before a real commit is actually done. They do store pointers | ||
| 969 | * to file data extents, and those reference counts still get | ||
| 970 | * updated (along with back refs to the log tree). | ||
| 971 | */ | ||
| 954 | root->ref_cows = 0; | 972 | root->ref_cows = 0; |
| 955 | 973 | ||
| 956 | root->node = btrfs_alloc_free_block(trans, root, root->leafsize, | 974 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, |
| 957 | 0, BTRFS_TREE_LOG_OBJECTID, | 975 | 0, BTRFS_TREE_LOG_OBJECTID, |
| 958 | trans->transid, 0, 0, 0); | 976 | trans->transid, 0, 0, 0); |
| 977 | if (IS_ERR(leaf)) { | ||
| 978 | kfree(root); | ||
| 979 | return ERR_CAST(leaf); | ||
| 980 | } | ||
| 959 | 981 | ||
| 982 | root->node = leaf; | ||
| 960 | btrfs_set_header_nritems(root->node, 0); | 983 | btrfs_set_header_nritems(root->node, 0); |
| 961 | btrfs_set_header_level(root->node, 0); | 984 | btrfs_set_header_level(root->node, 0); |
| 962 | btrfs_set_header_bytenr(root->node, root->node->start); | 985 | btrfs_set_header_bytenr(root->node, root->node->start); |
| @@ -968,7 +991,48 @@ int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, | |||
| 968 | BTRFS_FSID_SIZE); | 991 | BTRFS_FSID_SIZE); |
| 969 | btrfs_mark_buffer_dirty(root->node); | 992 | btrfs_mark_buffer_dirty(root->node); |
| 970 | btrfs_tree_unlock(root->node); | 993 | btrfs_tree_unlock(root->node); |
| 971 | fs_info->log_root_tree = root; | 994 | return root; |
| 995 | } | ||
| 996 | |||
| 997 | int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, | ||
| 998 | struct btrfs_fs_info *fs_info) | ||
| 999 | { | ||
| 1000 | struct btrfs_root *log_root; | ||
| 1001 | |||
| 1002 | log_root = alloc_log_tree(trans, fs_info); | ||
| 1003 | if (IS_ERR(log_root)) | ||
| 1004 | return PTR_ERR(log_root); | ||
| 1005 | WARN_ON(fs_info->log_root_tree); | ||
| 1006 | fs_info->log_root_tree = log_root; | ||
| 1007 | return 0; | ||
| 1008 | } | ||
| 1009 | |||
| 1010 | int btrfs_add_log_tree(struct btrfs_trans_handle *trans, | ||
| 1011 | struct btrfs_root *root) | ||
| 1012 | { | ||
| 1013 | struct btrfs_root *log_root; | ||
| 1014 | struct btrfs_inode_item *inode_item; | ||
| 1015 | |||
| 1016 | log_root = alloc_log_tree(trans, root->fs_info); | ||
| 1017 | if (IS_ERR(log_root)) | ||
| 1018 | return PTR_ERR(log_root); | ||
| 1019 | |||
| 1020 | log_root->last_trans = trans->transid; | ||
| 1021 | log_root->root_key.offset = root->root_key.objectid; | ||
| 1022 | |||
| 1023 | inode_item = &log_root->root_item.inode; | ||
| 1024 | inode_item->generation = cpu_to_le64(1); | ||
| 1025 | inode_item->size = cpu_to_le64(3); | ||
| 1026 | inode_item->nlink = cpu_to_le32(1); | ||
| 1027 | inode_item->nbytes = cpu_to_le64(root->leafsize); | ||
| 1028 | inode_item->mode = cpu_to_le32(S_IFDIR | 0755); | ||
| 1029 | |||
| 1030 | btrfs_set_root_bytenr(&log_root->root_item, log_root->node->start); | ||
| 1031 | btrfs_set_root_generation(&log_root->root_item, trans->transid); | ||
| 1032 | |||
| 1033 | WARN_ON(root->log_root); | ||
| 1034 | root->log_root = log_root; | ||
| 1035 | root->log_transid = 0; | ||
| 972 | return 0; | 1036 | return 0; |
| 973 | } | 1037 | } |
| 974 | 1038 | ||
| @@ -1136,7 +1200,6 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits) | |||
| 1136 | { | 1200 | { |
| 1137 | struct btrfs_fs_info *info = (struct btrfs_fs_info *)congested_data; | 1201 | struct btrfs_fs_info *info = (struct btrfs_fs_info *)congested_data; |
| 1138 | int ret = 0; | 1202 | int ret = 0; |
| 1139 | struct list_head *cur; | ||
| 1140 | struct btrfs_device *device; | 1203 | struct btrfs_device *device; |
| 1141 | struct backing_dev_info *bdi; | 1204 | struct backing_dev_info *bdi; |
| 1142 | #if 0 | 1205 | #if 0 |
| @@ -1144,8 +1207,7 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits) | |||
| 1144 | btrfs_congested_async(info, 0)) | 1207 | btrfs_congested_async(info, 0)) |
| 1145 | return 1; | 1208 | return 1; |
| 1146 | #endif | 1209 | #endif |
| 1147 | list_for_each(cur, &info->fs_devices->devices) { | 1210 | list_for_each_entry(device, &info->fs_devices->devices, dev_list) { |
| 1148 | device = list_entry(cur, struct btrfs_device, dev_list); | ||
| 1149 | if (!device->bdev) | 1211 | if (!device->bdev) |
| 1150 | continue; | 1212 | continue; |
| 1151 | bdi = blk_get_backing_dev_info(device->bdev); | 1213 | bdi = blk_get_backing_dev_info(device->bdev); |
| @@ -1163,13 +1225,11 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits) | |||
| 1163 | */ | 1225 | */ |
| 1164 | static void __unplug_io_fn(struct backing_dev_info *bdi, struct page *page) | 1226 | static void __unplug_io_fn(struct backing_dev_info *bdi, struct page *page) |
| 1165 | { | 1227 | { |
| 1166 | struct list_head *cur; | ||
| 1167 | struct btrfs_device *device; | 1228 | struct btrfs_device *device; |
| 1168 | struct btrfs_fs_info *info; | 1229 | struct btrfs_fs_info *info; |
| 1169 | 1230 | ||
| 1170 | info = (struct btrfs_fs_info *)bdi->unplug_io_data; | 1231 | info = (struct btrfs_fs_info *)bdi->unplug_io_data; |
| 1171 | list_for_each(cur, &info->fs_devices->devices) { | 1232 | list_for_each_entry(device, &info->fs_devices->devices, dev_list) { |
| 1172 | device = list_entry(cur, struct btrfs_device, dev_list); | ||
| 1173 | if (!device->bdev) | 1233 | if (!device->bdev) |
| 1174 | continue; | 1234 | continue; |
| 1175 | 1235 | ||
| @@ -1447,7 +1507,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1447 | INIT_LIST_HEAD(&fs_info->dead_roots); | 1507 | INIT_LIST_HEAD(&fs_info->dead_roots); |
| 1448 | INIT_LIST_HEAD(&fs_info->hashers); | 1508 | INIT_LIST_HEAD(&fs_info->hashers); |
| 1449 | INIT_LIST_HEAD(&fs_info->delalloc_inodes); | 1509 | INIT_LIST_HEAD(&fs_info->delalloc_inodes); |
| 1450 | spin_lock_init(&fs_info->hash_lock); | ||
| 1451 | spin_lock_init(&fs_info->delalloc_lock); | 1510 | spin_lock_init(&fs_info->delalloc_lock); |
| 1452 | spin_lock_init(&fs_info->new_trans_lock); | 1511 | spin_lock_init(&fs_info->new_trans_lock); |
| 1453 | spin_lock_init(&fs_info->ref_cache_lock); | 1512 | spin_lock_init(&fs_info->ref_cache_lock); |
| @@ -1535,10 +1594,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1535 | init_waitqueue_head(&fs_info->transaction_throttle); | 1594 | init_waitqueue_head(&fs_info->transaction_throttle); |
| 1536 | init_waitqueue_head(&fs_info->transaction_wait); | 1595 | init_waitqueue_head(&fs_info->transaction_wait); |
| 1537 | init_waitqueue_head(&fs_info->async_submit_wait); | 1596 | init_waitqueue_head(&fs_info->async_submit_wait); |
| 1538 | init_waitqueue_head(&fs_info->tree_log_wait); | ||
| 1539 | atomic_set(&fs_info->tree_log_commit, 0); | ||
| 1540 | atomic_set(&fs_info->tree_log_writers, 0); | ||
| 1541 | fs_info->tree_log_transid = 0; | ||
| 1542 | 1597 | ||
| 1543 | __setup_root(4096, 4096, 4096, 4096, tree_root, | 1598 | __setup_root(4096, 4096, 4096, 4096, tree_root, |
| 1544 | fs_info, BTRFS_ROOT_TREE_OBJECTID); | 1599 | fs_info, BTRFS_ROOT_TREE_OBJECTID); |
| @@ -1627,6 +1682,8 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1627 | * low idle thresh | 1682 | * low idle thresh |
| 1628 | */ | 1683 | */ |
| 1629 | fs_info->endio_workers.idle_thresh = 4; | 1684 | fs_info->endio_workers.idle_thresh = 4; |
| 1685 | fs_info->endio_meta_workers.idle_thresh = 4; | ||
| 1686 | |||
| 1630 | fs_info->endio_write_workers.idle_thresh = 64; | 1687 | fs_info->endio_write_workers.idle_thresh = 64; |
| 1631 | fs_info->endio_meta_write_workers.idle_thresh = 64; | 1688 | fs_info->endio_meta_write_workers.idle_thresh = 64; |
| 1632 | 1689 | ||
| @@ -1740,13 +1797,13 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1740 | fs_info->system_alloc_profile = fs_info->metadata_alloc_profile; | 1797 | fs_info->system_alloc_profile = fs_info->metadata_alloc_profile; |
| 1741 | fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root, | 1798 | fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root, |
| 1742 | "btrfs-cleaner"); | 1799 | "btrfs-cleaner"); |
| 1743 | if (!fs_info->cleaner_kthread) | 1800 | if (IS_ERR(fs_info->cleaner_kthread)) |
| 1744 | goto fail_csum_root; | 1801 | goto fail_csum_root; |
| 1745 | 1802 | ||
| 1746 | fs_info->transaction_kthread = kthread_run(transaction_kthread, | 1803 | fs_info->transaction_kthread = kthread_run(transaction_kthread, |
| 1747 | tree_root, | 1804 | tree_root, |
| 1748 | "btrfs-transaction"); | 1805 | "btrfs-transaction"); |
| 1749 | if (!fs_info->transaction_kthread) | 1806 | if (IS_ERR(fs_info->transaction_kthread)) |
| 1750 | goto fail_cleaner; | 1807 | goto fail_cleaner; |
| 1751 | 1808 | ||
| 1752 | if (btrfs_super_log_root(disk_super) != 0) { | 1809 | if (btrfs_super_log_root(disk_super) != 0) { |
| @@ -1828,13 +1885,14 @@ fail_sb_buffer: | |||
| 1828 | fail_iput: | 1885 | fail_iput: |
| 1829 | invalidate_inode_pages2(fs_info->btree_inode->i_mapping); | 1886 | invalidate_inode_pages2(fs_info->btree_inode->i_mapping); |
| 1830 | iput(fs_info->btree_inode); | 1887 | iput(fs_info->btree_inode); |
| 1831 | fail: | 1888 | |
| 1832 | btrfs_close_devices(fs_info->fs_devices); | 1889 | btrfs_close_devices(fs_info->fs_devices); |
| 1833 | btrfs_mapping_tree_free(&fs_info->mapping_tree); | 1890 | btrfs_mapping_tree_free(&fs_info->mapping_tree); |
| 1891 | bdi_destroy(&fs_info->bdi); | ||
| 1834 | 1892 | ||
| 1893 | fail: | ||
| 1835 | kfree(extent_root); | 1894 | kfree(extent_root); |
| 1836 | kfree(tree_root); | 1895 | kfree(tree_root); |
| 1837 | bdi_destroy(&fs_info->bdi); | ||
| 1838 | kfree(fs_info); | 1896 | kfree(fs_info); |
| 1839 | kfree(chunk_root); | 1897 | kfree(chunk_root); |
| 1840 | kfree(dev_root); | 1898 | kfree(dev_root); |
| @@ -1995,7 +2053,6 @@ static int write_dev_supers(struct btrfs_device *device, | |||
| 1995 | 2053 | ||
| 1996 | int write_all_supers(struct btrfs_root *root, int max_mirrors) | 2054 | int write_all_supers(struct btrfs_root *root, int max_mirrors) |
| 1997 | { | 2055 | { |
| 1998 | struct list_head *cur; | ||
| 1999 | struct list_head *head = &root->fs_info->fs_devices->devices; | 2056 | struct list_head *head = &root->fs_info->fs_devices->devices; |
| 2000 | struct btrfs_device *dev; | 2057 | struct btrfs_device *dev; |
| 2001 | struct btrfs_super_block *sb; | 2058 | struct btrfs_super_block *sb; |
| @@ -2011,8 +2068,7 @@ int write_all_supers(struct btrfs_root *root, int max_mirrors) | |||
| 2011 | 2068 | ||
| 2012 | sb = &root->fs_info->super_for_commit; | 2069 | sb = &root->fs_info->super_for_commit; |
| 2013 | dev_item = &sb->dev_item; | 2070 | dev_item = &sb->dev_item; |
| 2014 | list_for_each(cur, head) { | 2071 | list_for_each_entry(dev, head, dev_list) { |
| 2015 | dev = list_entry(cur, struct btrfs_device, dev_list); | ||
| 2016 | if (!dev->bdev) { | 2072 | if (!dev->bdev) { |
| 2017 | total_errors++; | 2073 | total_errors++; |
| 2018 | continue; | 2074 | continue; |
| @@ -2045,8 +2101,7 @@ int write_all_supers(struct btrfs_root *root, int max_mirrors) | |||
| 2045 | } | 2101 | } |
| 2046 | 2102 | ||
| 2047 | total_errors = 0; | 2103 | total_errors = 0; |
| 2048 | list_for_each(cur, head) { | 2104 | list_for_each_entry(dev, head, dev_list) { |
| 2049 | dev = list_entry(cur, struct btrfs_device, dev_list); | ||
| 2050 | if (!dev->bdev) | 2105 | if (!dev->bdev) |
| 2051 | continue; | 2106 | continue; |
| 2052 | if (!dev->in_fs_metadata || !dev->writeable) | 2107 | if (!dev->in_fs_metadata || !dev->writeable) |
| @@ -2260,6 +2315,8 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf) | |||
| 2260 | u64 transid = btrfs_header_generation(buf); | 2315 | u64 transid = btrfs_header_generation(buf); |
| 2261 | struct inode *btree_inode = root->fs_info->btree_inode; | 2316 | struct inode *btree_inode = root->fs_info->btree_inode; |
| 2262 | 2317 | ||
| 2318 | btrfs_set_lock_blocking(buf); | ||
| 2319 | |||
| 2263 | WARN_ON(!btrfs_tree_locked(buf)); | 2320 | WARN_ON(!btrfs_tree_locked(buf)); |
| 2264 | if (transid != root->fs_info->generation) { | 2321 | if (transid != root->fs_info->generation) { |
| 2265 | printk(KERN_CRIT "btrfs transid mismatch buffer %llu, " | 2322 | printk(KERN_CRIT "btrfs transid mismatch buffer %llu, " |
| @@ -2302,14 +2359,13 @@ int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid) | |||
| 2302 | int ret; | 2359 | int ret; |
| 2303 | ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid); | 2360 | ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid); |
| 2304 | if (ret == 0) | 2361 | if (ret == 0) |
| 2305 | buf->flags |= EXTENT_UPTODATE; | 2362 | set_bit(EXTENT_BUFFER_UPTODATE, &buf->bflags); |
| 2306 | return ret; | 2363 | return ret; |
| 2307 | } | 2364 | } |
| 2308 | 2365 | ||
| 2309 | int btree_lock_page_hook(struct page *page) | 2366 | int btree_lock_page_hook(struct page *page) |
| 2310 | { | 2367 | { |
| 2311 | struct inode *inode = page->mapping->host; | 2368 | struct inode *inode = page->mapping->host; |
| 2312 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
| 2313 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | 2369 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
| 2314 | struct extent_buffer *eb; | 2370 | struct extent_buffer *eb; |
| 2315 | unsigned long len; | 2371 | unsigned long len; |
| @@ -2324,9 +2380,7 @@ int btree_lock_page_hook(struct page *page) | |||
| 2324 | goto out; | 2380 | goto out; |
| 2325 | 2381 | ||
| 2326 | btrfs_tree_lock(eb); | 2382 | btrfs_tree_lock(eb); |
| 2327 | spin_lock(&root->fs_info->hash_lock); | ||
| 2328 | btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN); | 2383 | btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN); |
| 2329 | spin_unlock(&root->fs_info->hash_lock); | ||
| 2330 | btrfs_tree_unlock(eb); | 2384 | btrfs_tree_unlock(eb); |
| 2331 | free_extent_buffer(eb); | 2385 | free_extent_buffer(eb); |
| 2332 | out: | 2386 | out: |
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h index c0ff404c31b7..494a56eb2986 100644 --- a/fs/btrfs/disk-io.h +++ b/fs/btrfs/disk-io.h | |||
| @@ -98,5 +98,7 @@ int btrfs_free_log_root_tree(struct btrfs_trans_handle *trans, | |||
| 98 | struct btrfs_fs_info *fs_info); | 98 | struct btrfs_fs_info *fs_info); |
| 99 | int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, | 99 | int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, |
| 100 | struct btrfs_fs_info *fs_info); | 100 | struct btrfs_fs_info *fs_info); |
| 101 | int btrfs_add_log_tree(struct btrfs_trans_handle *trans, | ||
| 102 | struct btrfs_root *root); | ||
| 101 | int btree_lock_page_hook(struct page *page); | 103 | int btree_lock_page_hook(struct page *page); |
| 102 | #endif | 104 | #endif |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 293da650873f..7527523c2d2d 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -19,7 +19,7 @@ | |||
| 19 | #include <linux/pagemap.h> | 19 | #include <linux/pagemap.h> |
| 20 | #include <linux/writeback.h> | 20 | #include <linux/writeback.h> |
| 21 | #include <linux/blkdev.h> | 21 | #include <linux/blkdev.h> |
| 22 | #include <linux/version.h> | 22 | #include <linux/sort.h> |
| 23 | #include "compat.h" | 23 | #include "compat.h" |
| 24 | #include "hash.h" | 24 | #include "hash.h" |
| 25 | #include "crc32c.h" | 25 | #include "crc32c.h" |
| @@ -30,7 +30,6 @@ | |||
| 30 | #include "volumes.h" | 30 | #include "volumes.h" |
| 31 | #include "locking.h" | 31 | #include "locking.h" |
| 32 | #include "ref-cache.h" | 32 | #include "ref-cache.h" |
| 33 | #include "compat.h" | ||
| 34 | 33 | ||
| 35 | #define PENDING_EXTENT_INSERT 0 | 34 | #define PENDING_EXTENT_INSERT 0 |
| 36 | #define PENDING_EXTENT_DELETE 1 | 35 | #define PENDING_EXTENT_DELETE 1 |
| @@ -326,10 +325,8 @@ static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info, | |||
| 326 | u64 flags) | 325 | u64 flags) |
| 327 | { | 326 | { |
| 328 | struct list_head *head = &info->space_info; | 327 | struct list_head *head = &info->space_info; |
| 329 | struct list_head *cur; | ||
| 330 | struct btrfs_space_info *found; | 328 | struct btrfs_space_info *found; |
| 331 | list_for_each(cur, head) { | 329 | list_for_each_entry(found, head, list) { |
| 332 | found = list_entry(cur, struct btrfs_space_info, list); | ||
| 333 | if (found->flags == flags) | 330 | if (found->flags == flags) |
| 334 | return found; | 331 | return found; |
| 335 | } | 332 | } |
| @@ -1525,15 +1522,55 @@ out: | |||
| 1525 | return ret; | 1522 | return ret; |
| 1526 | } | 1523 | } |
| 1527 | 1524 | ||
| 1528 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 1525 | /* when a block goes through cow, we update the reference counts of |
| 1529 | struct extent_buffer *orig_buf, struct extent_buffer *buf, | 1526 | * everything that block points to. The internal pointers of the block |
| 1530 | u32 *nr_extents) | 1527 | * can be in just about any order, and it is likely to have clusters of |
| 1528 | * things that are close together and clusters of things that are not. | ||
| 1529 | * | ||
| 1530 | * To help reduce the seeks that come with updating all of these reference | ||
| 1531 | * counts, sort them by byte number before actual updates are done. | ||
| 1532 | * | ||
| 1533 | * struct refsort is used to match byte number to slot in the btree block. | ||
| 1534 | * we sort based on the byte number and then use the slot to actually | ||
| 1535 | * find the item. | ||
| 1536 | * | ||
| 1537 | * struct refsort is smaller than strcut btrfs_item and smaller than | ||
| 1538 | * struct btrfs_key_ptr. Since we're currently limited to the page size | ||
| 1539 | * for a btree block, there's no way for a kmalloc of refsorts for a | ||
| 1540 | * single node to be bigger than a page. | ||
| 1541 | */ | ||
| 1542 | struct refsort { | ||
| 1543 | u64 bytenr; | ||
| 1544 | u32 slot; | ||
| 1545 | }; | ||
| 1546 | |||
| 1547 | /* | ||
| 1548 | * for passing into sort() | ||
| 1549 | */ | ||
| 1550 | static int refsort_cmp(const void *a_void, const void *b_void) | ||
| 1551 | { | ||
| 1552 | const struct refsort *a = a_void; | ||
| 1553 | const struct refsort *b = b_void; | ||
| 1554 | |||
| 1555 | if (a->bytenr < b->bytenr) | ||
| 1556 | return -1; | ||
| 1557 | if (a->bytenr > b->bytenr) | ||
| 1558 | return 1; | ||
| 1559 | return 0; | ||
| 1560 | } | ||
| 1561 | |||
| 1562 | |||
| 1563 | noinline int btrfs_inc_ref(struct btrfs_trans_handle *trans, | ||
| 1564 | struct btrfs_root *root, | ||
| 1565 | struct extent_buffer *orig_buf, | ||
| 1566 | struct extent_buffer *buf, u32 *nr_extents) | ||
| 1531 | { | 1567 | { |
| 1532 | u64 bytenr; | 1568 | u64 bytenr; |
| 1533 | u64 ref_root; | 1569 | u64 ref_root; |
| 1534 | u64 orig_root; | 1570 | u64 orig_root; |
| 1535 | u64 ref_generation; | 1571 | u64 ref_generation; |
| 1536 | u64 orig_generation; | 1572 | u64 orig_generation; |
| 1573 | struct refsort *sorted; | ||
| 1537 | u32 nritems; | 1574 | u32 nritems; |
| 1538 | u32 nr_file_extents = 0; | 1575 | u32 nr_file_extents = 0; |
| 1539 | struct btrfs_key key; | 1576 | struct btrfs_key key; |
| @@ -1542,6 +1579,8 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
| 1542 | int level; | 1579 | int level; |
| 1543 | int ret = 0; | 1580 | int ret = 0; |
| 1544 | int faili = 0; | 1581 | int faili = 0; |
| 1582 | int refi = 0; | ||
| 1583 | int slot; | ||
| 1545 | int (*process_func)(struct btrfs_trans_handle *, struct btrfs_root *, | 1584 | int (*process_func)(struct btrfs_trans_handle *, struct btrfs_root *, |
| 1546 | u64, u64, u64, u64, u64, u64, u64, u64); | 1585 | u64, u64, u64, u64, u64, u64, u64, u64); |
| 1547 | 1586 | ||
| @@ -1553,6 +1592,9 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
| 1553 | nritems = btrfs_header_nritems(buf); | 1592 | nritems = btrfs_header_nritems(buf); |
| 1554 | level = btrfs_header_level(buf); | 1593 | level = btrfs_header_level(buf); |
| 1555 | 1594 | ||
| 1595 | sorted = kmalloc(sizeof(struct refsort) * nritems, GFP_NOFS); | ||
| 1596 | BUG_ON(!sorted); | ||
| 1597 | |||
| 1556 | if (root->ref_cows) { | 1598 | if (root->ref_cows) { |
| 1557 | process_func = __btrfs_inc_extent_ref; | 1599 | process_func = __btrfs_inc_extent_ref; |
| 1558 | } else { | 1600 | } else { |
| @@ -1565,6 +1607,11 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
| 1565 | process_func = __btrfs_update_extent_ref; | 1607 | process_func = __btrfs_update_extent_ref; |
| 1566 | } | 1608 | } |
| 1567 | 1609 | ||
| 1610 | /* | ||
| 1611 | * we make two passes through the items. In the first pass we | ||
| 1612 | * only record the byte number and slot. Then we sort based on | ||
| 1613 | * byte number and do the actual work based on the sorted results | ||
| 1614 | */ | ||
| 1568 | for (i = 0; i < nritems; i++) { | 1615 | for (i = 0; i < nritems; i++) { |
| 1569 | cond_resched(); | 1616 | cond_resched(); |
| 1570 | if (level == 0) { | 1617 | if (level == 0) { |
| @@ -1581,6 +1628,32 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
| 1581 | continue; | 1628 | continue; |
| 1582 | 1629 | ||
| 1583 | nr_file_extents++; | 1630 | nr_file_extents++; |
| 1631 | sorted[refi].bytenr = bytenr; | ||
| 1632 | sorted[refi].slot = i; | ||
| 1633 | refi++; | ||
| 1634 | } else { | ||
| 1635 | bytenr = btrfs_node_blockptr(buf, i); | ||
| 1636 | sorted[refi].bytenr = bytenr; | ||
| 1637 | sorted[refi].slot = i; | ||
| 1638 | refi++; | ||
| 1639 | } | ||
| 1640 | } | ||
| 1641 | /* | ||
| 1642 | * if refi == 0, we didn't actually put anything into the sorted | ||
| 1643 | * array and we're done | ||
| 1644 | */ | ||
| 1645 | if (refi == 0) | ||
| 1646 | goto out; | ||
| 1647 | |||
| 1648 | sort(sorted, refi, sizeof(struct refsort), refsort_cmp, NULL); | ||
| 1649 | |||
| 1650 | for (i = 0; i < refi; i++) { | ||
| 1651 | cond_resched(); | ||
| 1652 | slot = sorted[i].slot; | ||
| 1653 | bytenr = sorted[i].bytenr; | ||
| 1654 | |||
| 1655 | if (level == 0) { | ||
| 1656 | btrfs_item_key_to_cpu(buf, &key, slot); | ||
| 1584 | 1657 | ||
| 1585 | ret = process_func(trans, root, bytenr, | 1658 | ret = process_func(trans, root, bytenr, |
| 1586 | orig_buf->start, buf->start, | 1659 | orig_buf->start, buf->start, |
| @@ -1589,25 +1662,25 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
| 1589 | key.objectid); | 1662 | key.objectid); |
| 1590 | 1663 | ||
| 1591 | if (ret) { | 1664 | if (ret) { |
| 1592 | faili = i; | 1665 | faili = slot; |
| 1593 | WARN_ON(1); | 1666 | WARN_ON(1); |
| 1594 | goto fail; | 1667 | goto fail; |
| 1595 | } | 1668 | } |
| 1596 | } else { | 1669 | } else { |
| 1597 | bytenr = btrfs_node_blockptr(buf, i); | ||
| 1598 | ret = process_func(trans, root, bytenr, | 1670 | ret = process_func(trans, root, bytenr, |
| 1599 | orig_buf->start, buf->start, | 1671 | orig_buf->start, buf->start, |
| 1600 | orig_root, ref_root, | 1672 | orig_root, ref_root, |
| 1601 | orig_generation, ref_generation, | 1673 | orig_generation, ref_generation, |
| 1602 | level - 1); | 1674 | level - 1); |
| 1603 | if (ret) { | 1675 | if (ret) { |
| 1604 | faili = i; | 1676 | faili = slot; |
| 1605 | WARN_ON(1); | 1677 | WARN_ON(1); |
| 1606 | goto fail; | 1678 | goto fail; |
| 1607 | } | 1679 | } |
| 1608 | } | 1680 | } |
| 1609 | } | 1681 | } |
| 1610 | out: | 1682 | out: |
| 1683 | kfree(sorted); | ||
| 1611 | if (nr_extents) { | 1684 | if (nr_extents) { |
| 1612 | if (level == 0) | 1685 | if (level == 0) |
| 1613 | *nr_extents = nr_file_extents; | 1686 | *nr_extents = nr_file_extents; |
| @@ -1616,6 +1689,7 @@ out: | |||
| 1616 | } | 1689 | } |
| 1617 | return 0; | 1690 | return 0; |
| 1618 | fail: | 1691 | fail: |
| 1692 | kfree(sorted); | ||
| 1619 | WARN_ON(1); | 1693 | WARN_ON(1); |
| 1620 | return ret; | 1694 | return ret; |
| 1621 | } | 1695 | } |
| @@ -2159,7 +2233,8 @@ again: | |||
| 2159 | ret = find_first_extent_bit(&info->extent_ins, search, &start, | 2233 | ret = find_first_extent_bit(&info->extent_ins, search, &start, |
| 2160 | &end, EXTENT_WRITEBACK); | 2234 | &end, EXTENT_WRITEBACK); |
| 2161 | if (ret) { | 2235 | if (ret) { |
| 2162 | if (skipped && all && !num_inserts) { | 2236 | if (skipped && all && !num_inserts && |
| 2237 | list_empty(&update_list)) { | ||
| 2163 | skipped = 0; | 2238 | skipped = 0; |
| 2164 | search = 0; | 2239 | search = 0; |
| 2165 | continue; | 2240 | continue; |
| @@ -2547,6 +2622,7 @@ again: | |||
| 2547 | if (ret) { | 2622 | if (ret) { |
| 2548 | if (all && skipped && !nr) { | 2623 | if (all && skipped && !nr) { |
| 2549 | search = 0; | 2624 | search = 0; |
| 2625 | skipped = 0; | ||
| 2550 | continue; | 2626 | continue; |
| 2551 | } | 2627 | } |
| 2552 | mutex_unlock(&info->extent_ins_mutex); | 2628 | mutex_unlock(&info->extent_ins_mutex); |
| @@ -2700,13 +2776,9 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
| 2700 | /* if metadata always pin */ | 2776 | /* if metadata always pin */ |
| 2701 | if (owner_objectid < BTRFS_FIRST_FREE_OBJECTID) { | 2777 | if (owner_objectid < BTRFS_FIRST_FREE_OBJECTID) { |
| 2702 | if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID) { | 2778 | if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID) { |
| 2703 | struct btrfs_block_group_cache *cache; | 2779 | mutex_lock(&root->fs_info->pinned_mutex); |
| 2704 | 2780 | btrfs_update_pinned_extents(root, bytenr, num_bytes, 1); | |
| 2705 | /* btrfs_free_reserved_extent */ | 2781 | mutex_unlock(&root->fs_info->pinned_mutex); |
| 2706 | cache = btrfs_lookup_block_group(root->fs_info, bytenr); | ||
| 2707 | BUG_ON(!cache); | ||
| 2708 | btrfs_add_free_space(cache, bytenr, num_bytes); | ||
| 2709 | put_block_group(cache); | ||
| 2710 | update_reserved_extents(root, bytenr, num_bytes, 0); | 2782 | update_reserved_extents(root, bytenr, num_bytes, 0); |
| 2711 | return 0; | 2783 | return 0; |
| 2712 | } | 2784 | } |
| @@ -3014,7 +3086,6 @@ loop_check: | |||
| 3014 | static void dump_space_info(struct btrfs_space_info *info, u64 bytes) | 3086 | static void dump_space_info(struct btrfs_space_info *info, u64 bytes) |
| 3015 | { | 3087 | { |
| 3016 | struct btrfs_block_group_cache *cache; | 3088 | struct btrfs_block_group_cache *cache; |
| 3017 | struct list_head *l; | ||
| 3018 | 3089 | ||
| 3019 | printk(KERN_INFO "space_info has %llu free, is %sfull\n", | 3090 | printk(KERN_INFO "space_info has %llu free, is %sfull\n", |
| 3020 | (unsigned long long)(info->total_bytes - info->bytes_used - | 3091 | (unsigned long long)(info->total_bytes - info->bytes_used - |
| @@ -3022,8 +3093,7 @@ static void dump_space_info(struct btrfs_space_info *info, u64 bytes) | |||
| 3022 | (info->full) ? "" : "not "); | 3093 | (info->full) ? "" : "not "); |
| 3023 | 3094 | ||
| 3024 | down_read(&info->groups_sem); | 3095 | down_read(&info->groups_sem); |
| 3025 | list_for_each(l, &info->block_groups) { | 3096 | list_for_each_entry(cache, &info->block_groups, list) { |
| 3026 | cache = list_entry(l, struct btrfs_block_group_cache, list); | ||
| 3027 | spin_lock(&cache->lock); | 3097 | spin_lock(&cache->lock); |
| 3028 | printk(KERN_INFO "block group %llu has %llu bytes, %llu used " | 3098 | printk(KERN_INFO "block group %llu has %llu bytes, %llu used " |
| 3029 | "%llu pinned %llu reserved\n", | 3099 | "%llu pinned %llu reserved\n", |
| @@ -3342,7 +3412,10 @@ struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, | |||
| 3342 | btrfs_set_header_generation(buf, trans->transid); | 3412 | btrfs_set_header_generation(buf, trans->transid); |
| 3343 | btrfs_tree_lock(buf); | 3413 | btrfs_tree_lock(buf); |
| 3344 | clean_tree_block(trans, root, buf); | 3414 | clean_tree_block(trans, root, buf); |
| 3415 | |||
| 3416 | btrfs_set_lock_blocking(buf); | ||
| 3345 | btrfs_set_buffer_uptodate(buf); | 3417 | btrfs_set_buffer_uptodate(buf); |
| 3418 | |||
| 3346 | if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID) { | 3419 | if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID) { |
| 3347 | set_extent_dirty(&root->dirty_log_pages, buf->start, | 3420 | set_extent_dirty(&root->dirty_log_pages, buf->start, |
| 3348 | buf->start + buf->len - 1, GFP_NOFS); | 3421 | buf->start + buf->len - 1, GFP_NOFS); |
| @@ -3351,6 +3424,7 @@ struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, | |||
| 3351 | buf->start + buf->len - 1, GFP_NOFS); | 3424 | buf->start + buf->len - 1, GFP_NOFS); |
| 3352 | } | 3425 | } |
| 3353 | trans->blocks_used++; | 3426 | trans->blocks_used++; |
| 3427 | /* this returns a buffer locked for blocking */ | ||
| 3354 | return buf; | 3428 | return buf; |
| 3355 | } | 3429 | } |
| 3356 | 3430 | ||
| @@ -3388,36 +3462,73 @@ int btrfs_drop_leaf_ref(struct btrfs_trans_handle *trans, | |||
| 3388 | { | 3462 | { |
| 3389 | u64 leaf_owner; | 3463 | u64 leaf_owner; |
| 3390 | u64 leaf_generation; | 3464 | u64 leaf_generation; |
| 3465 | struct refsort *sorted; | ||
| 3391 | struct btrfs_key key; | 3466 | struct btrfs_key key; |
| 3392 | struct btrfs_file_extent_item *fi; | 3467 | struct btrfs_file_extent_item *fi; |
| 3393 | int i; | 3468 | int i; |
| 3394 | int nritems; | 3469 | int nritems; |
| 3395 | int ret; | 3470 | int ret; |
| 3471 | int refi = 0; | ||
| 3472 | int slot; | ||
| 3396 | 3473 | ||
| 3397 | BUG_ON(!btrfs_is_leaf(leaf)); | 3474 | BUG_ON(!btrfs_is_leaf(leaf)); |
| 3398 | nritems = btrfs_header_nritems(leaf); | 3475 | nritems = btrfs_header_nritems(leaf); |
| 3399 | leaf_owner = btrfs_header_owner(leaf); | 3476 | leaf_owner = btrfs_header_owner(leaf); |
| 3400 | leaf_generation = btrfs_header_generation(leaf); | 3477 | leaf_generation = btrfs_header_generation(leaf); |
| 3401 | 3478 | ||
| 3479 | sorted = kmalloc(sizeof(*sorted) * nritems, GFP_NOFS); | ||
| 3480 | /* we do this loop twice. The first time we build a list | ||
| 3481 | * of the extents we have a reference on, then we sort the list | ||
| 3482 | * by bytenr. The second time around we actually do the | ||
| 3483 | * extent freeing. | ||
| 3484 | */ | ||
| 3402 | for (i = 0; i < nritems; i++) { | 3485 | for (i = 0; i < nritems; i++) { |
| 3403 | u64 disk_bytenr; | 3486 | u64 disk_bytenr; |
| 3404 | cond_resched(); | 3487 | cond_resched(); |
| 3405 | 3488 | ||
| 3406 | btrfs_item_key_to_cpu(leaf, &key, i); | 3489 | btrfs_item_key_to_cpu(leaf, &key, i); |
| 3490 | |||
| 3491 | /* only extents have references, skip everything else */ | ||
| 3407 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) | 3492 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) |
| 3408 | continue; | 3493 | continue; |
| 3494 | |||
| 3409 | fi = btrfs_item_ptr(leaf, i, struct btrfs_file_extent_item); | 3495 | fi = btrfs_item_ptr(leaf, i, struct btrfs_file_extent_item); |
| 3496 | |||
| 3497 | /* inline extents live in the btree, they don't have refs */ | ||
| 3410 | if (btrfs_file_extent_type(leaf, fi) == | 3498 | if (btrfs_file_extent_type(leaf, fi) == |
| 3411 | BTRFS_FILE_EXTENT_INLINE) | 3499 | BTRFS_FILE_EXTENT_INLINE) |
| 3412 | continue; | 3500 | continue; |
| 3413 | /* | 3501 | |
| 3414 | * FIXME make sure to insert a trans record that | ||
| 3415 | * repeats the snapshot del on crash | ||
| 3416 | */ | ||
| 3417 | disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi); | 3502 | disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi); |
| 3503 | |||
| 3504 | /* holes don't have refs */ | ||
| 3418 | if (disk_bytenr == 0) | 3505 | if (disk_bytenr == 0) |
| 3419 | continue; | 3506 | continue; |
| 3420 | 3507 | ||
| 3508 | sorted[refi].bytenr = disk_bytenr; | ||
| 3509 | sorted[refi].slot = i; | ||
| 3510 | refi++; | ||
| 3511 | } | ||
| 3512 | |||
| 3513 | if (refi == 0) | ||
| 3514 | goto out; | ||
| 3515 | |||
| 3516 | sort(sorted, refi, sizeof(struct refsort), refsort_cmp, NULL); | ||
| 3517 | |||
| 3518 | for (i = 0; i < refi; i++) { | ||
| 3519 | u64 disk_bytenr; | ||
| 3520 | |||
| 3521 | disk_bytenr = sorted[i].bytenr; | ||
| 3522 | slot = sorted[i].slot; | ||
| 3523 | |||
| 3524 | cond_resched(); | ||
| 3525 | |||
| 3526 | btrfs_item_key_to_cpu(leaf, &key, slot); | ||
| 3527 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) | ||
| 3528 | continue; | ||
| 3529 | |||
| 3530 | fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); | ||
| 3531 | |||
| 3421 | ret = __btrfs_free_extent(trans, root, disk_bytenr, | 3532 | ret = __btrfs_free_extent(trans, root, disk_bytenr, |
| 3422 | btrfs_file_extent_disk_num_bytes(leaf, fi), | 3533 | btrfs_file_extent_disk_num_bytes(leaf, fi), |
| 3423 | leaf->start, leaf_owner, leaf_generation, | 3534 | leaf->start, leaf_owner, leaf_generation, |
| @@ -3428,6 +3539,8 @@ int btrfs_drop_leaf_ref(struct btrfs_trans_handle *trans, | |||
| 3428 | wake_up(&root->fs_info->transaction_throttle); | 3539 | wake_up(&root->fs_info->transaction_throttle); |
| 3429 | cond_resched(); | 3540 | cond_resched(); |
| 3430 | } | 3541 | } |
| 3542 | out: | ||
| 3543 | kfree(sorted); | ||
| 3431 | return 0; | 3544 | return 0; |
| 3432 | } | 3545 | } |
| 3433 | 3546 | ||
| @@ -3437,9 +3550,25 @@ static noinline int cache_drop_leaf_ref(struct btrfs_trans_handle *trans, | |||
| 3437 | { | 3550 | { |
| 3438 | int i; | 3551 | int i; |
| 3439 | int ret; | 3552 | int ret; |
| 3440 | struct btrfs_extent_info *info = ref->extents; | 3553 | struct btrfs_extent_info *info; |
| 3554 | struct refsort *sorted; | ||
| 3555 | |||
| 3556 | if (ref->nritems == 0) | ||
| 3557 | return 0; | ||
| 3441 | 3558 | ||
| 3559 | sorted = kmalloc(sizeof(*sorted) * ref->nritems, GFP_NOFS); | ||
| 3442 | for (i = 0; i < ref->nritems; i++) { | 3560 | for (i = 0; i < ref->nritems; i++) { |
| 3561 | sorted[i].bytenr = ref->extents[i].bytenr; | ||
| 3562 | sorted[i].slot = i; | ||
| 3563 | } | ||
| 3564 | sort(sorted, ref->nritems, sizeof(struct refsort), refsort_cmp, NULL); | ||
| 3565 | |||
| 3566 | /* | ||
| 3567 | * the items in the ref were sorted when the ref was inserted | ||
| 3568 | * into the ref cache, so this is already in order | ||
| 3569 | */ | ||
| 3570 | for (i = 0; i < ref->nritems; i++) { | ||
| 3571 | info = ref->extents + sorted[i].slot; | ||
| 3443 | ret = __btrfs_free_extent(trans, root, info->bytenr, | 3572 | ret = __btrfs_free_extent(trans, root, info->bytenr, |
| 3444 | info->num_bytes, ref->bytenr, | 3573 | info->num_bytes, ref->bytenr, |
| 3445 | ref->owner, ref->generation, | 3574 | ref->owner, ref->generation, |
| @@ -3453,6 +3582,7 @@ static noinline int cache_drop_leaf_ref(struct btrfs_trans_handle *trans, | |||
| 3453 | info++; | 3582 | info++; |
| 3454 | } | 3583 | } |
| 3455 | 3584 | ||
| 3585 | kfree(sorted); | ||
| 3456 | return 0; | 3586 | return 0; |
| 3457 | } | 3587 | } |
| 3458 | 3588 | ||
| @@ -3497,6 +3627,152 @@ static int drop_snap_lookup_refcount(struct btrfs_root *root, u64 start, | |||
| 3497 | } | 3627 | } |
| 3498 | 3628 | ||
| 3499 | /* | 3629 | /* |
| 3630 | * this is used while deleting old snapshots, and it drops the refs | ||
| 3631 | * on a whole subtree starting from a level 1 node. | ||
| 3632 | * | ||
| 3633 | * The idea is to sort all the leaf pointers, and then drop the | ||
| 3634 | * ref on all the leaves in order. Most of the time the leaves | ||
| 3635 | * will have ref cache entries, so no leaf IOs will be required to | ||
| 3636 | * find the extents they have references on. | ||
| 3637 | * | ||
| 3638 | * For each leaf, any references it has are also dropped in order | ||
| 3639 | * | ||
| 3640 | * This ends up dropping the references in something close to optimal | ||
| 3641 | * order for reading and modifying the extent allocation tree. | ||
| 3642 | */ | ||
| 3643 | static noinline int drop_level_one_refs(struct btrfs_trans_handle *trans, | ||
| 3644 | struct btrfs_root *root, | ||
| 3645 | struct btrfs_path *path) | ||
| 3646 | { | ||
| 3647 | u64 bytenr; | ||
| 3648 | u64 root_owner; | ||
| 3649 | u64 root_gen; | ||
| 3650 | struct extent_buffer *eb = path->nodes[1]; | ||
| 3651 | struct extent_buffer *leaf; | ||
| 3652 | struct btrfs_leaf_ref *ref; | ||
| 3653 | struct refsort *sorted = NULL; | ||
| 3654 | int nritems = btrfs_header_nritems(eb); | ||
| 3655 | int ret; | ||
| 3656 | int i; | ||
| 3657 | int refi = 0; | ||
| 3658 | int slot = path->slots[1]; | ||
| 3659 | u32 blocksize = btrfs_level_size(root, 0); | ||
| 3660 | u32 refs; | ||
| 3661 | |||
| 3662 | if (nritems == 0) | ||
| 3663 | goto out; | ||
| 3664 | |||
| 3665 | root_owner = btrfs_header_owner(eb); | ||
| 3666 | root_gen = btrfs_header_generation(eb); | ||
| 3667 | sorted = kmalloc(sizeof(*sorted) * nritems, GFP_NOFS); | ||
| 3668 | |||
| 3669 | /* | ||
| 3670 | * step one, sort all the leaf pointers so we don't scribble | ||
| 3671 | * randomly into the extent allocation tree | ||
| 3672 | */ | ||
| 3673 | for (i = slot; i < nritems; i++) { | ||
| 3674 | sorted[refi].bytenr = btrfs_node_blockptr(eb, i); | ||
| 3675 | sorted[refi].slot = i; | ||
| 3676 | refi++; | ||
| 3677 | } | ||
| 3678 | |||
| 3679 | /* | ||
| 3680 | * nritems won't be zero, but if we're picking up drop_snapshot | ||
| 3681 | * after a crash, slot might be > 0, so double check things | ||
| 3682 | * just in case. | ||
| 3683 | */ | ||
| 3684 | if (refi == 0) | ||
| 3685 | goto out; | ||
| 3686 | |||
| 3687 | sort(sorted, refi, sizeof(struct refsort), refsort_cmp, NULL); | ||
| 3688 | |||
| 3689 | /* | ||
| 3690 | * the first loop frees everything the leaves point to | ||
| 3691 | */ | ||
| 3692 | for (i = 0; i < refi; i++) { | ||
| 3693 | u64 ptr_gen; | ||
| 3694 | |||
| 3695 | bytenr = sorted[i].bytenr; | ||
| 3696 | |||
| 3697 | /* | ||
| 3698 | * check the reference count on this leaf. If it is > 1 | ||
| 3699 | * we just decrement it below and don't update any | ||
| 3700 | * of the refs the leaf points to. | ||
| 3701 | */ | ||
| 3702 | ret = drop_snap_lookup_refcount(root, bytenr, blocksize, &refs); | ||
| 3703 | BUG_ON(ret); | ||
| 3704 | if (refs != 1) | ||
| 3705 | continue; | ||
| 3706 | |||
| 3707 | ptr_gen = btrfs_node_ptr_generation(eb, sorted[i].slot); | ||
| 3708 | |||
| 3709 | /* | ||
| 3710 | * the leaf only had one reference, which means the | ||
| 3711 | * only thing pointing to this leaf is the snapshot | ||
| 3712 | * we're deleting. It isn't possible for the reference | ||
| 3713 | * count to increase again later | ||
| 3714 | * | ||
| 3715 | * The reference cache is checked for the leaf, | ||
| 3716 | * and if found we'll be able to drop any refs held by | ||
| 3717 | * the leaf without needing to read it in. | ||
| 3718 | */ | ||
| 3719 | ref = btrfs_lookup_leaf_ref(root, bytenr); | ||
| 3720 | if (ref && ref->generation != ptr_gen) { | ||
| 3721 | btrfs_free_leaf_ref(root, ref); | ||
| 3722 | ref = NULL; | ||
| 3723 | } | ||
| 3724 | if (ref) { | ||
| 3725 | ret = cache_drop_leaf_ref(trans, root, ref); | ||
| 3726 | BUG_ON(ret); | ||
| 3727 | btrfs_remove_leaf_ref(root, ref); | ||
| 3728 | btrfs_free_leaf_ref(root, ref); | ||
| 3729 | } else { | ||
| 3730 | /* | ||
| 3731 | * the leaf wasn't in the reference cache, so | ||
| 3732 | * we have to read it. | ||
| 3733 | */ | ||
| 3734 | leaf = read_tree_block(root, bytenr, blocksize, | ||
| 3735 | ptr_gen); | ||
| 3736 | ret = btrfs_drop_leaf_ref(trans, root, leaf); | ||
| 3737 | BUG_ON(ret); | ||
| 3738 | free_extent_buffer(leaf); | ||
| 3739 | } | ||
| 3740 | atomic_inc(&root->fs_info->throttle_gen); | ||
| 3741 | wake_up(&root->fs_info->transaction_throttle); | ||
| 3742 | cond_resched(); | ||
| 3743 | } | ||
| 3744 | |||
| 3745 | /* | ||
| 3746 | * run through the loop again to free the refs on the leaves. | ||
| 3747 | * This is faster than doing it in the loop above because | ||
| 3748 | * the leaves are likely to be clustered together. We end up | ||
| 3749 | * working in nice chunks on the extent allocation tree. | ||
| 3750 | */ | ||
| 3751 | for (i = 0; i < refi; i++) { | ||
| 3752 | bytenr = sorted[i].bytenr; | ||
| 3753 | ret = __btrfs_free_extent(trans, root, bytenr, | ||
| 3754 | blocksize, eb->start, | ||
| 3755 | root_owner, root_gen, 0, 1); | ||
| 3756 | BUG_ON(ret); | ||
| 3757 | |||
| 3758 | atomic_inc(&root->fs_info->throttle_gen); | ||
| 3759 | wake_up(&root->fs_info->transaction_throttle); | ||
| 3760 | cond_resched(); | ||
| 3761 | } | ||
| 3762 | out: | ||
| 3763 | kfree(sorted); | ||
| 3764 | |||
| 3765 | /* | ||
| 3766 | * update the path to show we've processed the entire level 1 | ||
| 3767 | * node. This will get saved into the root's drop_snapshot_progress | ||
| 3768 | * field so these drops are not repeated again if this transaction | ||
| 3769 | * commits. | ||
| 3770 | */ | ||
| 3771 | path->slots[1] = nritems; | ||
| 3772 | return 0; | ||
| 3773 | } | ||
| 3774 | |||
| 3775 | /* | ||
| 3500 | * helper function for drop_snapshot, this walks down the tree dropping ref | 3776 | * helper function for drop_snapshot, this walks down the tree dropping ref |
| 3501 | * counts as it goes. | 3777 | * counts as it goes. |
| 3502 | */ | 3778 | */ |
| @@ -3511,7 +3787,6 @@ static noinline int walk_down_tree(struct btrfs_trans_handle *trans, | |||
| 3511 | struct extent_buffer *next; | 3787 | struct extent_buffer *next; |
| 3512 | struct extent_buffer *cur; | 3788 | struct extent_buffer *cur; |
| 3513 | struct extent_buffer *parent; | 3789 | struct extent_buffer *parent; |
| 3514 | struct btrfs_leaf_ref *ref; | ||
| 3515 | u32 blocksize; | 3790 | u32 blocksize; |
| 3516 | int ret; | 3791 | int ret; |
| 3517 | u32 refs; | 3792 | u32 refs; |
| @@ -3538,17 +3813,46 @@ static noinline int walk_down_tree(struct btrfs_trans_handle *trans, | |||
| 3538 | if (path->slots[*level] >= | 3813 | if (path->slots[*level] >= |
| 3539 | btrfs_header_nritems(cur)) | 3814 | btrfs_header_nritems(cur)) |
| 3540 | break; | 3815 | break; |
| 3816 | |||
| 3817 | /* the new code goes down to level 1 and does all the | ||
| 3818 | * leaves pointed to that node in bulk. So, this check | ||
| 3819 | * for level 0 will always be false. | ||
| 3820 | * | ||
| 3821 | * But, the disk format allows the drop_snapshot_progress | ||
| 3822 | * field in the root to leave things in a state where | ||
| 3823 | * a leaf will need cleaning up here. If someone crashes | ||
| 3824 | * with the old code and then boots with the new code, | ||
| 3825 | * we might find a leaf here. | ||
| 3826 | */ | ||
| 3541 | if (*level == 0) { | 3827 | if (*level == 0) { |
| 3542 | ret = btrfs_drop_leaf_ref(trans, root, cur); | 3828 | ret = btrfs_drop_leaf_ref(trans, root, cur); |
| 3543 | BUG_ON(ret); | 3829 | BUG_ON(ret); |
| 3544 | break; | 3830 | break; |
| 3545 | } | 3831 | } |
| 3832 | |||
| 3833 | /* | ||
| 3834 | * once we get to level one, process the whole node | ||
| 3835 | * at once, including everything below it. | ||
| 3836 | */ | ||
| 3837 | if (*level == 1) { | ||
| 3838 | ret = drop_level_one_refs(trans, root, path); | ||
| 3839 | BUG_ON(ret); | ||
| 3840 | break; | ||
| 3841 | } | ||
| 3842 | |||
| 3546 | bytenr = btrfs_node_blockptr(cur, path->slots[*level]); | 3843 | bytenr = btrfs_node_blockptr(cur, path->slots[*level]); |
| 3547 | ptr_gen = btrfs_node_ptr_generation(cur, path->slots[*level]); | 3844 | ptr_gen = btrfs_node_ptr_generation(cur, path->slots[*level]); |
| 3548 | blocksize = btrfs_level_size(root, *level - 1); | 3845 | blocksize = btrfs_level_size(root, *level - 1); |
| 3549 | 3846 | ||
| 3550 | ret = drop_snap_lookup_refcount(root, bytenr, blocksize, &refs); | 3847 | ret = drop_snap_lookup_refcount(root, bytenr, blocksize, &refs); |
| 3551 | BUG_ON(ret); | 3848 | BUG_ON(ret); |
| 3849 | |||
| 3850 | /* | ||
| 3851 | * if there is more than one reference, we don't need | ||
| 3852 | * to read that node to drop any references it has. We | ||
| 3853 | * just drop the ref we hold on that node and move on to the | ||
| 3854 | * next slot in this level. | ||
| 3855 | */ | ||
| 3552 | if (refs != 1) { | 3856 | if (refs != 1) { |
| 3553 | parent = path->nodes[*level]; | 3857 | parent = path->nodes[*level]; |
| 3554 | root_owner = btrfs_header_owner(parent); | 3858 | root_owner = btrfs_header_owner(parent); |
| @@ -3567,46 +3871,12 @@ static noinline int walk_down_tree(struct btrfs_trans_handle *trans, | |||
| 3567 | 3871 | ||
| 3568 | continue; | 3872 | continue; |
| 3569 | } | 3873 | } |
| 3874 | |||
| 3570 | /* | 3875 | /* |
| 3571 | * at this point, we have a single ref, and since the | 3876 | * we need to keep freeing things in the next level down. |
| 3572 | * only place referencing this extent is a dead root | 3877 | * read the block and loop around to process it |
| 3573 | * the reference count should never go higher. | ||
| 3574 | * So, we don't need to check it again | ||
| 3575 | */ | 3878 | */ |
| 3576 | if (*level == 1) { | 3879 | next = read_tree_block(root, bytenr, blocksize, ptr_gen); |
| 3577 | ref = btrfs_lookup_leaf_ref(root, bytenr); | ||
| 3578 | if (ref && ref->generation != ptr_gen) { | ||
| 3579 | btrfs_free_leaf_ref(root, ref); | ||
| 3580 | ref = NULL; | ||
| 3581 | } | ||
| 3582 | if (ref) { | ||
| 3583 | ret = cache_drop_leaf_ref(trans, root, ref); | ||
| 3584 | BUG_ON(ret); | ||
| 3585 | btrfs_remove_leaf_ref(root, ref); | ||
| 3586 | btrfs_free_leaf_ref(root, ref); | ||
| 3587 | *level = 0; | ||
| 3588 | break; | ||
| 3589 | } | ||
| 3590 | } | ||
| 3591 | next = btrfs_find_tree_block(root, bytenr, blocksize); | ||
| 3592 | if (!next || !btrfs_buffer_uptodate(next, ptr_gen)) { | ||
| 3593 | free_extent_buffer(next); | ||
| 3594 | |||
| 3595 | next = read_tree_block(root, bytenr, blocksize, | ||
| 3596 | ptr_gen); | ||
| 3597 | cond_resched(); | ||
| 3598 | #if 0 | ||
| 3599 | /* | ||
| 3600 | * this is a debugging check and can go away | ||
| 3601 | * the ref should never go all the way down to 1 | ||
| 3602 | * at this point | ||
| 3603 | */ | ||
| 3604 | ret = lookup_extent_ref(NULL, root, bytenr, blocksize, | ||
| 3605 | &refs); | ||
| 3606 | BUG_ON(ret); | ||
| 3607 | WARN_ON(refs != 1); | ||
| 3608 | #endif | ||
| 3609 | } | ||
| 3610 | WARN_ON(*level <= 0); | 3880 | WARN_ON(*level <= 0); |
| 3611 | if (path->nodes[*level-1]) | 3881 | if (path->nodes[*level-1]) |
| 3612 | free_extent_buffer(path->nodes[*level-1]); | 3882 | free_extent_buffer(path->nodes[*level-1]); |
| @@ -3631,11 +3901,16 @@ out: | |||
| 3631 | root_owner = btrfs_header_owner(parent); | 3901 | root_owner = btrfs_header_owner(parent); |
| 3632 | root_gen = btrfs_header_generation(parent); | 3902 | root_gen = btrfs_header_generation(parent); |
| 3633 | 3903 | ||
| 3904 | /* | ||
| 3905 | * cleanup and free the reference on the last node | ||
| 3906 | * we processed | ||
| 3907 | */ | ||
| 3634 | ret = __btrfs_free_extent(trans, root, bytenr, blocksize, | 3908 | ret = __btrfs_free_extent(trans, root, bytenr, blocksize, |
| 3635 | parent->start, root_owner, root_gen, | 3909 | parent->start, root_owner, root_gen, |
| 3636 | *level, 1); | 3910 | *level, 1); |
| 3637 | free_extent_buffer(path->nodes[*level]); | 3911 | free_extent_buffer(path->nodes[*level]); |
| 3638 | path->nodes[*level] = NULL; | 3912 | path->nodes[*level] = NULL; |
| 3913 | |||
| 3639 | *level += 1; | 3914 | *level += 1; |
| 3640 | BUG_ON(ret); | 3915 | BUG_ON(ret); |
| 3641 | 3916 | ||
| @@ -3687,6 +3962,7 @@ static noinline int walk_down_subtree(struct btrfs_trans_handle *trans, | |||
| 3687 | 3962 | ||
| 3688 | next = read_tree_block(root, bytenr, blocksize, ptr_gen); | 3963 | next = read_tree_block(root, bytenr, blocksize, ptr_gen); |
| 3689 | btrfs_tree_lock(next); | 3964 | btrfs_tree_lock(next); |
| 3965 | btrfs_set_lock_blocking(next); | ||
| 3690 | 3966 | ||
| 3691 | ret = btrfs_lookup_extent_ref(trans, root, bytenr, blocksize, | 3967 | ret = btrfs_lookup_extent_ref(trans, root, bytenr, blocksize, |
| 3692 | &refs); | 3968 | &refs); |
| @@ -3754,6 +4030,13 @@ static noinline int walk_up_tree(struct btrfs_trans_handle *trans, | |||
| 3754 | if (slot < btrfs_header_nritems(path->nodes[i]) - 1) { | 4030 | if (slot < btrfs_header_nritems(path->nodes[i]) - 1) { |
| 3755 | struct extent_buffer *node; | 4031 | struct extent_buffer *node; |
| 3756 | struct btrfs_disk_key disk_key; | 4032 | struct btrfs_disk_key disk_key; |
| 4033 | |||
| 4034 | /* | ||
| 4035 | * there is more work to do in this level. | ||
| 4036 | * Update the drop_progress marker to reflect | ||
| 4037 | * the work we've done so far, and then bump | ||
| 4038 | * the slot number | ||
| 4039 | */ | ||
| 3757 | node = path->nodes[i]; | 4040 | node = path->nodes[i]; |
| 3758 | path->slots[i]++; | 4041 | path->slots[i]++; |
| 3759 | *level = i; | 4042 | *level = i; |
| @@ -3765,6 +4048,11 @@ static noinline int walk_up_tree(struct btrfs_trans_handle *trans, | |||
| 3765 | return 0; | 4048 | return 0; |
| 3766 | } else { | 4049 | } else { |
| 3767 | struct extent_buffer *parent; | 4050 | struct extent_buffer *parent; |
| 4051 | |||
| 4052 | /* | ||
| 4053 | * this whole node is done, free our reference | ||
| 4054 | * on it and go up one level | ||
| 4055 | */ | ||
| 3768 | if (path->nodes[*level] == root->node) | 4056 | if (path->nodes[*level] == root->node) |
| 3769 | parent = path->nodes[*level]; | 4057 | parent = path->nodes[*level]; |
| 3770 | else | 4058 | else |
| @@ -4444,7 +4732,7 @@ static noinline int replace_one_extent(struct btrfs_trans_handle *trans, | |||
| 4444 | u64 lock_end = 0; | 4732 | u64 lock_end = 0; |
| 4445 | u64 num_bytes; | 4733 | u64 num_bytes; |
| 4446 | u64 ext_offset; | 4734 | u64 ext_offset; |
| 4447 | u64 first_pos; | 4735 | u64 search_end = (u64)-1; |
| 4448 | u32 nritems; | 4736 | u32 nritems; |
| 4449 | int nr_scaned = 0; | 4737 | int nr_scaned = 0; |
| 4450 | int extent_locked = 0; | 4738 | int extent_locked = 0; |
| @@ -4452,7 +4740,6 @@ static noinline int replace_one_extent(struct btrfs_trans_handle *trans, | |||
| 4452 | int ret; | 4740 | int ret; |
| 4453 | 4741 | ||
| 4454 | memcpy(&key, leaf_key, sizeof(key)); | 4742 | memcpy(&key, leaf_key, sizeof(key)); |
| 4455 | first_pos = INT_LIMIT(loff_t) - extent_key->offset; | ||
| 4456 | if (ref_path->owner_objectid != BTRFS_MULTIPLE_OBJECTIDS) { | 4743 | if (ref_path->owner_objectid != BTRFS_MULTIPLE_OBJECTIDS) { |
| 4457 | if (key.objectid < ref_path->owner_objectid || | 4744 | if (key.objectid < ref_path->owner_objectid || |
| 4458 | (key.objectid == ref_path->owner_objectid && | 4745 | (key.objectid == ref_path->owner_objectid && |
| @@ -4501,7 +4788,7 @@ next: | |||
| 4501 | if ((key.objectid > ref_path->owner_objectid) || | 4788 | if ((key.objectid > ref_path->owner_objectid) || |
| 4502 | (key.objectid == ref_path->owner_objectid && | 4789 | (key.objectid == ref_path->owner_objectid && |
| 4503 | key.type > BTRFS_EXTENT_DATA_KEY) || | 4790 | key.type > BTRFS_EXTENT_DATA_KEY) || |
| 4504 | (key.offset >= first_pos + extent_key->offset)) | 4791 | key.offset >= search_end) |
| 4505 | break; | 4792 | break; |
| 4506 | } | 4793 | } |
| 4507 | 4794 | ||
| @@ -4534,8 +4821,10 @@ next: | |||
| 4534 | num_bytes = btrfs_file_extent_num_bytes(leaf, fi); | 4821 | num_bytes = btrfs_file_extent_num_bytes(leaf, fi); |
| 4535 | ext_offset = btrfs_file_extent_offset(leaf, fi); | 4822 | ext_offset = btrfs_file_extent_offset(leaf, fi); |
| 4536 | 4823 | ||
| 4537 | if (first_pos > key.offset - ext_offset) | 4824 | if (search_end == (u64)-1) { |
| 4538 | first_pos = key.offset - ext_offset; | 4825 | search_end = key.offset - ext_offset + |
| 4826 | btrfs_file_extent_ram_bytes(leaf, fi); | ||
| 4827 | } | ||
| 4539 | 4828 | ||
| 4540 | if (!extent_locked) { | 4829 | if (!extent_locked) { |
| 4541 | lock_start = key.offset; | 4830 | lock_start = key.offset; |
| @@ -4724,7 +5013,7 @@ next: | |||
| 4724 | } | 5013 | } |
| 4725 | skip: | 5014 | skip: |
| 4726 | if (ref_path->owner_objectid != BTRFS_MULTIPLE_OBJECTIDS && | 5015 | if (ref_path->owner_objectid != BTRFS_MULTIPLE_OBJECTIDS && |
| 4727 | key.offset >= first_pos + extent_key->offset) | 5016 | key.offset >= search_end) |
| 4728 | break; | 5017 | break; |
| 4729 | 5018 | ||
| 4730 | cond_resched(); | 5019 | cond_resched(); |
| @@ -4778,6 +5067,7 @@ int btrfs_reloc_tree_cache_ref(struct btrfs_trans_handle *trans, | |||
| 4778 | ref->bytenr = buf->start; | 5067 | ref->bytenr = buf->start; |
| 4779 | ref->owner = btrfs_header_owner(buf); | 5068 | ref->owner = btrfs_header_owner(buf); |
| 4780 | ref->generation = btrfs_header_generation(buf); | 5069 | ref->generation = btrfs_header_generation(buf); |
| 5070 | |||
| 4781 | ret = btrfs_add_leaf_ref(root, ref, 0); | 5071 | ret = btrfs_add_leaf_ref(root, ref, 0); |
| 4782 | WARN_ON(ret); | 5072 | WARN_ON(ret); |
| 4783 | btrfs_free_leaf_ref(root, ref); | 5073 | btrfs_free_leaf_ref(root, ref); |
| @@ -5957,9 +6247,11 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, | |||
| 5957 | path = btrfs_alloc_path(); | 6247 | path = btrfs_alloc_path(); |
| 5958 | BUG_ON(!path); | 6248 | BUG_ON(!path); |
| 5959 | 6249 | ||
| 5960 | btrfs_remove_free_space_cache(block_group); | 6250 | spin_lock(&root->fs_info->block_group_cache_lock); |
| 5961 | rb_erase(&block_group->cache_node, | 6251 | rb_erase(&block_group->cache_node, |
| 5962 | &root->fs_info->block_group_cache_tree); | 6252 | &root->fs_info->block_group_cache_tree); |
| 6253 | spin_unlock(&root->fs_info->block_group_cache_lock); | ||
| 6254 | btrfs_remove_free_space_cache(block_group); | ||
| 5963 | down_write(&block_group->space_info->groups_sem); | 6255 | down_write(&block_group->space_info->groups_sem); |
| 5964 | list_del(&block_group->list); | 6256 | list_del(&block_group->list); |
| 5965 | up_write(&block_group->space_info->groups_sem); | 6257 | up_write(&block_group->space_info->groups_sem); |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index e086d407f1fa..37d43b516b79 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
| @@ -9,7 +9,6 @@ | |||
| 9 | #include <linux/spinlock.h> | 9 | #include <linux/spinlock.h> |
| 10 | #include <linux/blkdev.h> | 10 | #include <linux/blkdev.h> |
| 11 | #include <linux/swap.h> | 11 | #include <linux/swap.h> |
| 12 | #include <linux/version.h> | ||
| 13 | #include <linux/writeback.h> | 12 | #include <linux/writeback.h> |
| 14 | #include <linux/pagevec.h> | 13 | #include <linux/pagevec.h> |
| 15 | #include "extent_io.h" | 14 | #include "extent_io.h" |
| @@ -31,7 +30,7 @@ static LIST_HEAD(buffers); | |||
| 31 | static LIST_HEAD(states); | 30 | static LIST_HEAD(states); |
| 32 | 31 | ||
| 33 | #define LEAK_DEBUG 0 | 32 | #define LEAK_DEBUG 0 |
| 34 | #ifdef LEAK_DEBUG | 33 | #if LEAK_DEBUG |
| 35 | static DEFINE_SPINLOCK(leak_lock); | 34 | static DEFINE_SPINLOCK(leak_lock); |
| 36 | #endif | 35 | #endif |
| 37 | 36 | ||
| @@ -120,7 +119,7 @@ void extent_io_tree_init(struct extent_io_tree *tree, | |||
| 120 | static struct extent_state *alloc_extent_state(gfp_t mask) | 119 | static struct extent_state *alloc_extent_state(gfp_t mask) |
| 121 | { | 120 | { |
| 122 | struct extent_state *state; | 121 | struct extent_state *state; |
| 123 | #ifdef LEAK_DEBUG | 122 | #if LEAK_DEBUG |
| 124 | unsigned long flags; | 123 | unsigned long flags; |
| 125 | #endif | 124 | #endif |
| 126 | 125 | ||
| @@ -130,7 +129,7 @@ static struct extent_state *alloc_extent_state(gfp_t mask) | |||
| 130 | state->state = 0; | 129 | state->state = 0; |
| 131 | state->private = 0; | 130 | state->private = 0; |
| 132 | state->tree = NULL; | 131 | state->tree = NULL; |
| 133 | #ifdef LEAK_DEBUG | 132 | #if LEAK_DEBUG |
| 134 | spin_lock_irqsave(&leak_lock, flags); | 133 | spin_lock_irqsave(&leak_lock, flags); |
| 135 | list_add(&state->leak_list, &states); | 134 | list_add(&state->leak_list, &states); |
| 136 | spin_unlock_irqrestore(&leak_lock, flags); | 135 | spin_unlock_irqrestore(&leak_lock, flags); |
| @@ -145,11 +144,11 @@ static void free_extent_state(struct extent_state *state) | |||
| 145 | if (!state) | 144 | if (!state) |
| 146 | return; | 145 | return; |
| 147 | if (atomic_dec_and_test(&state->refs)) { | 146 | if (atomic_dec_and_test(&state->refs)) { |
| 148 | #ifdef LEAK_DEBUG | 147 | #if LEAK_DEBUG |
| 149 | unsigned long flags; | 148 | unsigned long flags; |
| 150 | #endif | 149 | #endif |
| 151 | WARN_ON(state->tree); | 150 | WARN_ON(state->tree); |
| 152 | #ifdef LEAK_DEBUG | 151 | #if LEAK_DEBUG |
| 153 | spin_lock_irqsave(&leak_lock, flags); | 152 | spin_lock_irqsave(&leak_lock, flags); |
| 154 | list_del(&state->leak_list); | 153 | list_del(&state->leak_list); |
| 155 | spin_unlock_irqrestore(&leak_lock, flags); | 154 | spin_unlock_irqrestore(&leak_lock, flags); |
| @@ -2378,11 +2377,6 @@ static int extent_write_cache_pages(struct extent_io_tree *tree, | |||
| 2378 | int scanned = 0; | 2377 | int scanned = 0; |
| 2379 | int range_whole = 0; | 2378 | int range_whole = 0; |
| 2380 | 2379 | ||
| 2381 | if (wbc->nonblocking && bdi_write_congested(bdi)) { | ||
| 2382 | wbc->encountered_congestion = 1; | ||
| 2383 | return 0; | ||
| 2384 | } | ||
| 2385 | |||
| 2386 | pagevec_init(&pvec, 0); | 2380 | pagevec_init(&pvec, 0); |
| 2387 | if (wbc->range_cyclic) { | 2381 | if (wbc->range_cyclic) { |
| 2388 | index = mapping->writeback_index; /* Start from prev offset */ | 2382 | index = mapping->writeback_index; /* Start from prev offset */ |
| @@ -2855,6 +2849,98 @@ out: | |||
| 2855 | return sector; | 2849 | return sector; |
| 2856 | } | 2850 | } |
| 2857 | 2851 | ||
| 2852 | int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | ||
| 2853 | __u64 start, __u64 len, get_extent_t *get_extent) | ||
| 2854 | { | ||
| 2855 | int ret; | ||
| 2856 | u64 off = start; | ||
| 2857 | u64 max = start + len; | ||
| 2858 | u32 flags = 0; | ||
| 2859 | u64 disko = 0; | ||
| 2860 | struct extent_map *em = NULL; | ||
| 2861 | int end = 0; | ||
| 2862 | u64 em_start = 0, em_len = 0; | ||
| 2863 | unsigned long emflags; | ||
| 2864 | ret = 0; | ||
| 2865 | |||
| 2866 | if (len == 0) | ||
| 2867 | return -EINVAL; | ||
| 2868 | |||
| 2869 | lock_extent(&BTRFS_I(inode)->io_tree, start, start + len, | ||
| 2870 | GFP_NOFS); | ||
| 2871 | em = get_extent(inode, NULL, 0, off, max - off, 0); | ||
| 2872 | if (!em) | ||
| 2873 | goto out; | ||
| 2874 | if (IS_ERR(em)) { | ||
| 2875 | ret = PTR_ERR(em); | ||
| 2876 | goto out; | ||
| 2877 | } | ||
| 2878 | while (!end) { | ||
| 2879 | off = em->start + em->len; | ||
| 2880 | if (off >= max) | ||
| 2881 | end = 1; | ||
| 2882 | |||
| 2883 | em_start = em->start; | ||
| 2884 | em_len = em->len; | ||
| 2885 | |||
| 2886 | disko = 0; | ||
| 2887 | flags = 0; | ||
| 2888 | |||
| 2889 | switch (em->block_start) { | ||
| 2890 | case EXTENT_MAP_LAST_BYTE: | ||
| 2891 | end = 1; | ||
| 2892 | flags |= FIEMAP_EXTENT_LAST; | ||
| 2893 | break; | ||
| 2894 | case EXTENT_MAP_HOLE: | ||
| 2895 | flags |= FIEMAP_EXTENT_UNWRITTEN; | ||
| 2896 | break; | ||
| 2897 | case EXTENT_MAP_INLINE: | ||
| 2898 | flags |= (FIEMAP_EXTENT_DATA_INLINE | | ||
| 2899 | FIEMAP_EXTENT_NOT_ALIGNED); | ||
| 2900 | break; | ||
| 2901 | case EXTENT_MAP_DELALLOC: | ||
| 2902 | flags |= (FIEMAP_EXTENT_DELALLOC | | ||
| 2903 | FIEMAP_EXTENT_UNKNOWN); | ||
| 2904 | break; | ||
| 2905 | default: | ||
| 2906 | disko = em->block_start; | ||
| 2907 | break; | ||
| 2908 | } | ||
| 2909 | if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) | ||
| 2910 | flags |= FIEMAP_EXTENT_ENCODED; | ||
| 2911 | |||
| 2912 | emflags = em->flags; | ||
| 2913 | free_extent_map(em); | ||
| 2914 | em = NULL; | ||
| 2915 | |||
| 2916 | if (!end) { | ||
| 2917 | em = get_extent(inode, NULL, 0, off, max - off, 0); | ||
| 2918 | if (!em) | ||
| 2919 | goto out; | ||
| 2920 | if (IS_ERR(em)) { | ||
| 2921 | ret = PTR_ERR(em); | ||
| 2922 | goto out; | ||
| 2923 | } | ||
| 2924 | emflags = em->flags; | ||
| 2925 | } | ||
| 2926 | if (test_bit(EXTENT_FLAG_VACANCY, &emflags)) { | ||
| 2927 | flags |= FIEMAP_EXTENT_LAST; | ||
| 2928 | end = 1; | ||
| 2929 | } | ||
| 2930 | |||
| 2931 | ret = fiemap_fill_next_extent(fieinfo, em_start, disko, | ||
| 2932 | em_len, flags); | ||
| 2933 | if (ret) | ||
| 2934 | goto out_free; | ||
| 2935 | } | ||
| 2936 | out_free: | ||
| 2937 | free_extent_map(em); | ||
| 2938 | out: | ||
| 2939 | unlock_extent(&BTRFS_I(inode)->io_tree, start, start + len, | ||
| 2940 | GFP_NOFS); | ||
| 2941 | return ret; | ||
| 2942 | } | ||
| 2943 | |||
| 2858 | static inline struct page *extent_buffer_page(struct extent_buffer *eb, | 2944 | static inline struct page *extent_buffer_page(struct extent_buffer *eb, |
| 2859 | unsigned long i) | 2945 | unsigned long i) |
| 2860 | { | 2946 | { |
| @@ -2892,15 +2978,17 @@ static struct extent_buffer *__alloc_extent_buffer(struct extent_io_tree *tree, | |||
| 2892 | gfp_t mask) | 2978 | gfp_t mask) |
| 2893 | { | 2979 | { |
| 2894 | struct extent_buffer *eb = NULL; | 2980 | struct extent_buffer *eb = NULL; |
| 2895 | #ifdef LEAK_DEBUG | 2981 | #if LEAK_DEBUG |
| 2896 | unsigned long flags; | 2982 | unsigned long flags; |
| 2897 | #endif | 2983 | #endif |
| 2898 | 2984 | ||
| 2899 | eb = kmem_cache_zalloc(extent_buffer_cache, mask); | 2985 | eb = kmem_cache_zalloc(extent_buffer_cache, mask); |
| 2900 | eb->start = start; | 2986 | eb->start = start; |
| 2901 | eb->len = len; | 2987 | eb->len = len; |
| 2902 | mutex_init(&eb->mutex); | 2988 | spin_lock_init(&eb->lock); |
| 2903 | #ifdef LEAK_DEBUG | 2989 | init_waitqueue_head(&eb->lock_wq); |
| 2990 | |||
| 2991 | #if LEAK_DEBUG | ||
| 2904 | spin_lock_irqsave(&leak_lock, flags); | 2992 | spin_lock_irqsave(&leak_lock, flags); |
| 2905 | list_add(&eb->leak_list, &buffers); | 2993 | list_add(&eb->leak_list, &buffers); |
| 2906 | spin_unlock_irqrestore(&leak_lock, flags); | 2994 | spin_unlock_irqrestore(&leak_lock, flags); |
| @@ -2912,7 +3000,7 @@ static struct extent_buffer *__alloc_extent_buffer(struct extent_io_tree *tree, | |||
| 2912 | 3000 | ||
| 2913 | static void __free_extent_buffer(struct extent_buffer *eb) | 3001 | static void __free_extent_buffer(struct extent_buffer *eb) |
| 2914 | { | 3002 | { |
| 2915 | #ifdef LEAK_DEBUG | 3003 | #if LEAK_DEBUG |
| 2916 | unsigned long flags; | 3004 | unsigned long flags; |
| 2917 | spin_lock_irqsave(&leak_lock, flags); | 3005 | spin_lock_irqsave(&leak_lock, flags); |
| 2918 | list_del(&eb->leak_list); | 3006 | list_del(&eb->leak_list); |
| @@ -2980,8 +3068,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, | |||
| 2980 | unlock_page(p); | 3068 | unlock_page(p); |
| 2981 | } | 3069 | } |
| 2982 | if (uptodate) | 3070 | if (uptodate) |
| 2983 | eb->flags |= EXTENT_UPTODATE; | 3071 | set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); |
| 2984 | eb->flags |= EXTENT_BUFFER_FILLED; | ||
| 2985 | 3072 | ||
| 2986 | spin_lock(&tree->buffer_lock); | 3073 | spin_lock(&tree->buffer_lock); |
| 2987 | exists = buffer_tree_insert(tree, start, &eb->rb_node); | 3074 | exists = buffer_tree_insert(tree, start, &eb->rb_node); |
| @@ -3135,7 +3222,7 @@ int clear_extent_buffer_uptodate(struct extent_io_tree *tree, | |||
| 3135 | unsigned long num_pages; | 3222 | unsigned long num_pages; |
| 3136 | 3223 | ||
| 3137 | num_pages = num_extent_pages(eb->start, eb->len); | 3224 | num_pages = num_extent_pages(eb->start, eb->len); |
| 3138 | eb->flags &= ~EXTENT_UPTODATE; | 3225 | clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); |
| 3139 | 3226 | ||
| 3140 | clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1, | 3227 | clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1, |
| 3141 | GFP_NOFS); | 3228 | GFP_NOFS); |
| @@ -3206,7 +3293,7 @@ int extent_buffer_uptodate(struct extent_io_tree *tree, | |||
| 3206 | struct page *page; | 3293 | struct page *page; |
| 3207 | int pg_uptodate = 1; | 3294 | int pg_uptodate = 1; |
| 3208 | 3295 | ||
| 3209 | if (eb->flags & EXTENT_UPTODATE) | 3296 | if (test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags)) |
| 3210 | return 1; | 3297 | return 1; |
| 3211 | 3298 | ||
| 3212 | ret = test_range_bit(tree, eb->start, eb->start + eb->len - 1, | 3299 | ret = test_range_bit(tree, eb->start, eb->start + eb->len - 1, |
| @@ -3242,7 +3329,7 @@ int read_extent_buffer_pages(struct extent_io_tree *tree, | |||
| 3242 | struct bio *bio = NULL; | 3329 | struct bio *bio = NULL; |
| 3243 | unsigned long bio_flags = 0; | 3330 | unsigned long bio_flags = 0; |
| 3244 | 3331 | ||
| 3245 | if (eb->flags & EXTENT_UPTODATE) | 3332 | if (test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags)) |
| 3246 | return 0; | 3333 | return 0; |
| 3247 | 3334 | ||
| 3248 | if (test_range_bit(tree, eb->start, eb->start + eb->len - 1, | 3335 | if (test_range_bit(tree, eb->start, eb->start + eb->len - 1, |
| @@ -3273,7 +3360,7 @@ int read_extent_buffer_pages(struct extent_io_tree *tree, | |||
| 3273 | } | 3360 | } |
| 3274 | if (all_uptodate) { | 3361 | if (all_uptodate) { |
| 3275 | if (start_i == 0) | 3362 | if (start_i == 0) |
| 3276 | eb->flags |= EXTENT_UPTODATE; | 3363 | set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); |
| 3277 | goto unlock_exit; | 3364 | goto unlock_exit; |
| 3278 | } | 3365 | } |
| 3279 | 3366 | ||
| @@ -3309,7 +3396,7 @@ int read_extent_buffer_pages(struct extent_io_tree *tree, | |||
| 3309 | } | 3396 | } |
| 3310 | 3397 | ||
| 3311 | if (!ret) | 3398 | if (!ret) |
| 3312 | eb->flags |= EXTENT_UPTODATE; | 3399 | set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); |
| 3313 | return ret; | 3400 | return ret; |
| 3314 | 3401 | ||
| 3315 | unlock_exit: | 3402 | unlock_exit: |
| @@ -3406,7 +3493,6 @@ int map_extent_buffer(struct extent_buffer *eb, unsigned long start, | |||
| 3406 | unmap_extent_buffer(eb, eb->map_token, km); | 3493 | unmap_extent_buffer(eb, eb->map_token, km); |
| 3407 | eb->map_token = NULL; | 3494 | eb->map_token = NULL; |
| 3408 | save = 1; | 3495 | save = 1; |
| 3409 | WARN_ON(!mutex_is_locked(&eb->mutex)); | ||
| 3410 | } | 3496 | } |
| 3411 | err = map_private_extent_buffer(eb, start, min_len, token, map, | 3497 | err = map_private_extent_buffer(eb, start, min_len, token, map, |
| 3412 | map_start, map_len, km); | 3498 | map_start, map_len, km); |
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index c5b483a79137..1f9df88afbf6 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h | |||
| @@ -22,6 +22,10 @@ | |||
| 22 | /* flags for bio submission */ | 22 | /* flags for bio submission */ |
| 23 | #define EXTENT_BIO_COMPRESSED 1 | 23 | #define EXTENT_BIO_COMPRESSED 1 |
| 24 | 24 | ||
| 25 | /* these are bit numbers for test/set bit */ | ||
| 26 | #define EXTENT_BUFFER_UPTODATE 0 | ||
| 27 | #define EXTENT_BUFFER_BLOCKING 1 | ||
| 28 | |||
| 25 | /* | 29 | /* |
| 26 | * page->private values. Every page that is controlled by the extent | 30 | * page->private values. Every page that is controlled by the extent |
| 27 | * map has page->private set to one. | 31 | * map has page->private set to one. |
| @@ -95,11 +99,19 @@ struct extent_buffer { | |||
| 95 | unsigned long map_start; | 99 | unsigned long map_start; |
| 96 | unsigned long map_len; | 100 | unsigned long map_len; |
| 97 | struct page *first_page; | 101 | struct page *first_page; |
| 102 | unsigned long bflags; | ||
| 98 | atomic_t refs; | 103 | atomic_t refs; |
| 99 | int flags; | ||
| 100 | struct list_head leak_list; | 104 | struct list_head leak_list; |
| 101 | struct rb_node rb_node; | 105 | struct rb_node rb_node; |
| 102 | struct mutex mutex; | 106 | |
| 107 | /* the spinlock is used to protect most operations */ | ||
| 108 | spinlock_t lock; | ||
| 109 | |||
| 110 | /* | ||
| 111 | * when we keep the lock held while blocking, waiters go onto | ||
| 112 | * the wq | ||
| 113 | */ | ||
| 114 | wait_queue_head_t lock_wq; | ||
| 103 | }; | 115 | }; |
| 104 | 116 | ||
| 105 | struct extent_map_tree; | 117 | struct extent_map_tree; |
| @@ -193,6 +205,8 @@ int extent_commit_write(struct extent_io_tree *tree, | |||
| 193 | unsigned from, unsigned to); | 205 | unsigned from, unsigned to); |
| 194 | sector_t extent_bmap(struct address_space *mapping, sector_t iblock, | 206 | sector_t extent_bmap(struct address_space *mapping, sector_t iblock, |
| 195 | get_extent_t *get_extent); | 207 | get_extent_t *get_extent); |
| 208 | int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | ||
| 209 | __u64 start, __u64 len, get_extent_t *get_extent); | ||
| 196 | int set_range_dirty(struct extent_io_tree *tree, u64 start, u64 end); | 210 | int set_range_dirty(struct extent_io_tree *tree, u64 start, u64 end); |
| 197 | int set_state_private(struct extent_io_tree *tree, u64 start, u64 private); | 211 | int set_state_private(struct extent_io_tree *tree, u64 start, u64 private); |
| 198 | int get_state_private(struct extent_io_tree *tree, u64 start, u64 *private); | 212 | int get_state_private(struct extent_io_tree *tree, u64 start, u64 *private); |
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 4a83e33ada32..50da69da20ce 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | #include <linux/slab.h> | 3 | #include <linux/slab.h> |
| 4 | #include <linux/module.h> | 4 | #include <linux/module.h> |
| 5 | #include <linux/spinlock.h> | 5 | #include <linux/spinlock.h> |
| 6 | #include <linux/version.h> | ||
| 7 | #include <linux/hardirq.h> | 6 | #include <linux/hardirq.h> |
| 8 | #include "extent_map.h" | 7 | #include "extent_map.h" |
| 9 | 8 | ||
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 90268334145e..3e8023efaff7 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
| @@ -29,7 +29,6 @@ | |||
| 29 | #include <linux/writeback.h> | 29 | #include <linux/writeback.h> |
| 30 | #include <linux/statfs.h> | 30 | #include <linux/statfs.h> |
| 31 | #include <linux/compat.h> | 31 | #include <linux/compat.h> |
| 32 | #include <linux/version.h> | ||
| 33 | #include "ctree.h" | 32 | #include "ctree.h" |
| 34 | #include "disk-io.h" | 33 | #include "disk-io.h" |
| 35 | #include "transaction.h" | 34 | #include "transaction.h" |
| @@ -1215,10 +1214,10 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
| 1215 | } | 1214 | } |
| 1216 | mutex_unlock(&root->fs_info->trans_mutex); | 1215 | mutex_unlock(&root->fs_info->trans_mutex); |
| 1217 | 1216 | ||
| 1218 | root->fs_info->tree_log_batch++; | 1217 | root->log_batch++; |
| 1219 | filemap_fdatawrite(inode->i_mapping); | 1218 | filemap_fdatawrite(inode->i_mapping); |
| 1220 | btrfs_wait_ordered_range(inode, 0, (u64)-1); | 1219 | btrfs_wait_ordered_range(inode, 0, (u64)-1); |
| 1221 | root->fs_info->tree_log_batch++; | 1220 | root->log_batch++; |
| 1222 | 1221 | ||
| 1223 | /* | 1222 | /* |
| 1224 | * ok we haven't committed the transaction yet, lets do a commit | 1223 | * ok we haven't committed the transaction yet, lets do a commit |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 8adfe059ab41..8f0706210a47 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -34,7 +34,6 @@ | |||
| 34 | #include <linux/statfs.h> | 34 | #include <linux/statfs.h> |
| 35 | #include <linux/compat.h> | 35 | #include <linux/compat.h> |
| 36 | #include <linux/bit_spinlock.h> | 36 | #include <linux/bit_spinlock.h> |
| 37 | #include <linux/version.h> | ||
| 38 | #include <linux/xattr.h> | 37 | #include <linux/xattr.h> |
| 39 | #include <linux/posix_acl.h> | 38 | #include <linux/posix_acl.h> |
| 40 | #include <linux/falloc.h> | 39 | #include <linux/falloc.h> |
| @@ -51,6 +50,7 @@ | |||
| 51 | #include "tree-log.h" | 50 | #include "tree-log.h" |
| 52 | #include "ref-cache.h" | 51 | #include "ref-cache.h" |
| 53 | #include "compression.h" | 52 | #include "compression.h" |
| 53 | #include "locking.h" | ||
| 54 | 54 | ||
| 55 | struct btrfs_iget_args { | 55 | struct btrfs_iget_args { |
| 56 | u64 ino; | 56 | u64 ino; |
| @@ -91,6 +91,16 @@ static noinline int cow_file_range(struct inode *inode, | |||
| 91 | u64 start, u64 end, int *page_started, | 91 | u64 start, u64 end, int *page_started, |
| 92 | unsigned long *nr_written, int unlock); | 92 | unsigned long *nr_written, int unlock); |
| 93 | 93 | ||
| 94 | static int btrfs_init_inode_security(struct inode *inode, struct inode *dir) | ||
| 95 | { | ||
| 96 | int err; | ||
| 97 | |||
| 98 | err = btrfs_init_acl(inode, dir); | ||
| 99 | if (!err) | ||
| 100 | err = btrfs_xattr_security_init(inode, dir); | ||
| 101 | return err; | ||
| 102 | } | ||
| 103 | |||
| 94 | /* | 104 | /* |
| 95 | * a very lame attempt at stopping writes when the FS is 85% full. There | 105 | * a very lame attempt at stopping writes when the FS is 85% full. There |
| 96 | * are countless ways this is incorrect, but it is better than nothing. | 106 | * are countless ways this is incorrect, but it is better than nothing. |
| @@ -350,6 +360,19 @@ again: | |||
| 350 | nr_pages = (end >> PAGE_CACHE_SHIFT) - (start >> PAGE_CACHE_SHIFT) + 1; | 360 | nr_pages = (end >> PAGE_CACHE_SHIFT) - (start >> PAGE_CACHE_SHIFT) + 1; |
| 351 | nr_pages = min(nr_pages, (128 * 1024UL) / PAGE_CACHE_SIZE); | 361 | nr_pages = min(nr_pages, (128 * 1024UL) / PAGE_CACHE_SIZE); |
| 352 | 362 | ||
| 363 | /* | ||
| 364 | * we don't want to send crud past the end of i_size through | ||
| 365 | * compression, that's just a waste of CPU time. So, if the | ||
| 366 | * end of the file is before the start of our current | ||
| 367 | * requested range of bytes, we bail out to the uncompressed | ||
| 368 | * cleanup code that can deal with all of this. | ||
| 369 | * | ||
| 370 | * It isn't really the fastest way to fix things, but this is a | ||
| 371 | * very uncommon corner. | ||
| 372 | */ | ||
| 373 | if (actual_end <= start) | ||
| 374 | goto cleanup_and_bail_uncompressed; | ||
| 375 | |||
| 353 | total_compressed = actual_end - start; | 376 | total_compressed = actual_end - start; |
| 354 | 377 | ||
| 355 | /* we want to make sure that amount of ram required to uncompress | 378 | /* we want to make sure that amount of ram required to uncompress |
| @@ -494,6 +517,7 @@ again: | |||
| 494 | goto again; | 517 | goto again; |
| 495 | } | 518 | } |
| 496 | } else { | 519 | } else { |
| 520 | cleanup_and_bail_uncompressed: | ||
| 497 | /* | 521 | /* |
| 498 | * No compression, but we still need to write the pages in | 522 | * No compression, but we still need to write the pages in |
| 499 | * the file we've been given so far. redirty the locked | 523 | * the file we've been given so far. redirty the locked |
| @@ -1324,12 +1348,11 @@ static noinline int add_pending_csums(struct btrfs_trans_handle *trans, | |||
| 1324 | struct inode *inode, u64 file_offset, | 1348 | struct inode *inode, u64 file_offset, |
| 1325 | struct list_head *list) | 1349 | struct list_head *list) |
| 1326 | { | 1350 | { |
| 1327 | struct list_head *cur; | ||
| 1328 | struct btrfs_ordered_sum *sum; | 1351 | struct btrfs_ordered_sum *sum; |
| 1329 | 1352 | ||
| 1330 | btrfs_set_trans_block_group(trans, inode); | 1353 | btrfs_set_trans_block_group(trans, inode); |
| 1331 | list_for_each(cur, list) { | 1354 | |
| 1332 | sum = list_entry(cur, struct btrfs_ordered_sum, list); | 1355 | list_for_each_entry(sum, list, list) { |
| 1333 | btrfs_csum_file_blocks(trans, | 1356 | btrfs_csum_file_blocks(trans, |
| 1334 | BTRFS_I(inode)->root->fs_info->csum_root, sum); | 1357 | BTRFS_I(inode)->root->fs_info->csum_root, sum); |
| 1335 | } | 1358 | } |
| @@ -2013,6 +2036,7 @@ void btrfs_read_locked_inode(struct inode *inode) | |||
| 2013 | BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item); | 2036 | BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item); |
| 2014 | 2037 | ||
| 2015 | alloc_group_block = btrfs_inode_block_group(leaf, inode_item); | 2038 | alloc_group_block = btrfs_inode_block_group(leaf, inode_item); |
| 2039 | |||
| 2016 | BTRFS_I(inode)->block_group = btrfs_find_block_group(root, 0, | 2040 | BTRFS_I(inode)->block_group = btrfs_find_block_group(root, 0, |
| 2017 | alloc_group_block, 0); | 2041 | alloc_group_block, 0); |
| 2018 | btrfs_free_path(path); | 2042 | btrfs_free_path(path); |
| @@ -2039,6 +2063,7 @@ void btrfs_read_locked_inode(struct inode *inode) | |||
| 2039 | inode->i_mapping->backing_dev_info = &root->fs_info->bdi; | 2063 | inode->i_mapping->backing_dev_info = &root->fs_info->bdi; |
| 2040 | break; | 2064 | break; |
| 2041 | default: | 2065 | default: |
| 2066 | inode->i_op = &btrfs_special_inode_operations; | ||
| 2042 | init_special_inode(inode, inode->i_mode, rdev); | 2067 | init_special_inode(inode, inode->i_mode, rdev); |
| 2043 | break; | 2068 | break; |
| 2044 | } | 2069 | } |
| @@ -2108,6 +2133,7 @@ noinline int btrfs_update_inode(struct btrfs_trans_handle *trans, | |||
| 2108 | goto failed; | 2133 | goto failed; |
| 2109 | } | 2134 | } |
| 2110 | 2135 | ||
| 2136 | btrfs_unlock_up_safe(path, 1); | ||
| 2111 | leaf = path->nodes[0]; | 2137 | leaf = path->nodes[0]; |
| 2112 | inode_item = btrfs_item_ptr(leaf, path->slots[0], | 2138 | inode_item = btrfs_item_ptr(leaf, path->slots[0], |
| 2113 | struct btrfs_inode_item); | 2139 | struct btrfs_inode_item); |
| @@ -2429,6 +2455,8 @@ next_node: | |||
| 2429 | ref->generation = leaf_gen; | 2455 | ref->generation = leaf_gen; |
| 2430 | ref->nritems = 0; | 2456 | ref->nritems = 0; |
| 2431 | 2457 | ||
| 2458 | btrfs_sort_leaf_ref(ref); | ||
| 2459 | |||
| 2432 | ret = btrfs_add_leaf_ref(root, ref, 0); | 2460 | ret = btrfs_add_leaf_ref(root, ref, 0); |
| 2433 | WARN_ON(ret); | 2461 | WARN_ON(ret); |
| 2434 | btrfs_free_leaf_ref(root, ref); | 2462 | btrfs_free_leaf_ref(root, ref); |
| @@ -2476,7 +2504,7 @@ noinline int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, | |||
| 2476 | struct btrfs_path *path; | 2504 | struct btrfs_path *path; |
| 2477 | struct btrfs_key key; | 2505 | struct btrfs_key key; |
| 2478 | struct btrfs_key found_key; | 2506 | struct btrfs_key found_key; |
| 2479 | u32 found_type; | 2507 | u32 found_type = (u8)-1; |
| 2480 | struct extent_buffer *leaf; | 2508 | struct extent_buffer *leaf; |
| 2481 | struct btrfs_file_extent_item *fi; | 2509 | struct btrfs_file_extent_item *fi; |
| 2482 | u64 extent_start = 0; | 2510 | u64 extent_start = 0; |
| @@ -2663,6 +2691,8 @@ next: | |||
| 2663 | if (pending_del_nr) | 2691 | if (pending_del_nr) |
| 2664 | goto del_pending; | 2692 | goto del_pending; |
| 2665 | btrfs_release_path(root, path); | 2693 | btrfs_release_path(root, path); |
| 2694 | if (found_type == BTRFS_INODE_ITEM_KEY) | ||
| 2695 | break; | ||
| 2666 | goto search_again; | 2696 | goto search_again; |
| 2667 | } | 2697 | } |
| 2668 | 2698 | ||
| @@ -2679,6 +2709,8 @@ del_pending: | |||
| 2679 | BUG_ON(ret); | 2709 | BUG_ON(ret); |
| 2680 | pending_del_nr = 0; | 2710 | pending_del_nr = 0; |
| 2681 | btrfs_release_path(root, path); | 2711 | btrfs_release_path(root, path); |
| 2712 | if (found_type == BTRFS_INODE_ITEM_KEY) | ||
| 2713 | break; | ||
| 2682 | goto search_again; | 2714 | goto search_again; |
| 2683 | } | 2715 | } |
| 2684 | } | 2716 | } |
| @@ -3265,7 +3297,7 @@ skip: | |||
| 3265 | 3297 | ||
| 3266 | /* Reached end of directory/root. Bump pos past the last item. */ | 3298 | /* Reached end of directory/root. Bump pos past the last item. */ |
| 3267 | if (key_type == BTRFS_DIR_INDEX_KEY) | 3299 | if (key_type == BTRFS_DIR_INDEX_KEY) |
| 3268 | filp->f_pos = INT_LIMIT(typeof(filp->f_pos)); | 3300 | filp->f_pos = INT_LIMIT(off_t); |
| 3269 | else | 3301 | else |
| 3270 | filp->f_pos++; | 3302 | filp->f_pos++; |
| 3271 | nopos: | 3303 | nopos: |
| @@ -3458,7 +3490,14 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
| 3458 | root->highest_inode = objectid; | 3490 | root->highest_inode = objectid; |
| 3459 | 3491 | ||
| 3460 | inode->i_uid = current_fsuid(); | 3492 | inode->i_uid = current_fsuid(); |
| 3461 | inode->i_gid = current_fsgid(); | 3493 | |
| 3494 | if (dir && (dir->i_mode & S_ISGID)) { | ||
| 3495 | inode->i_gid = dir->i_gid; | ||
| 3496 | if (S_ISDIR(mode)) | ||
| 3497 | mode |= S_ISGID; | ||
| 3498 | } else | ||
| 3499 | inode->i_gid = current_fsgid(); | ||
| 3500 | |||
| 3462 | inode->i_mode = mode; | 3501 | inode->i_mode = mode; |
| 3463 | inode->i_ino = objectid; | 3502 | inode->i_ino = objectid; |
| 3464 | inode_set_bytes(inode, 0); | 3503 | inode_set_bytes(inode, 0); |
| @@ -3586,7 +3625,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, | |||
| 3586 | if (IS_ERR(inode)) | 3625 | if (IS_ERR(inode)) |
| 3587 | goto out_unlock; | 3626 | goto out_unlock; |
| 3588 | 3627 | ||
| 3589 | err = btrfs_init_acl(inode, dir); | 3628 | err = btrfs_init_inode_security(inode, dir); |
| 3590 | if (err) { | 3629 | if (err) { |
| 3591 | drop_inode = 1; | 3630 | drop_inode = 1; |
| 3592 | goto out_unlock; | 3631 | goto out_unlock; |
| @@ -3649,7 +3688,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
| 3649 | if (IS_ERR(inode)) | 3688 | if (IS_ERR(inode)) |
| 3650 | goto out_unlock; | 3689 | goto out_unlock; |
| 3651 | 3690 | ||
| 3652 | err = btrfs_init_acl(inode, dir); | 3691 | err = btrfs_init_inode_security(inode, dir); |
| 3653 | if (err) { | 3692 | if (err) { |
| 3654 | drop_inode = 1; | 3693 | drop_inode = 1; |
| 3655 | goto out_unlock; | 3694 | goto out_unlock; |
| @@ -3772,7 +3811,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
| 3772 | 3811 | ||
| 3773 | drop_on_err = 1; | 3812 | drop_on_err = 1; |
| 3774 | 3813 | ||
| 3775 | err = btrfs_init_acl(inode, dir); | 3814 | err = btrfs_init_inode_security(inode, dir); |
| 3776 | if (err) | 3815 | if (err) |
| 3777 | goto out_fail; | 3816 | goto out_fail; |
| 3778 | 3817 | ||
| @@ -4158,9 +4197,10 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, | |||
| 4158 | return -EINVAL; | 4197 | return -EINVAL; |
| 4159 | } | 4198 | } |
| 4160 | 4199 | ||
| 4161 | static sector_t btrfs_bmap(struct address_space *mapping, sector_t iblock) | 4200 | static int btrfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, |
| 4201 | __u64 start, __u64 len) | ||
| 4162 | { | 4202 | { |
| 4163 | return extent_bmap(mapping, iblock, btrfs_get_extent); | 4203 | return extent_fiemap(inode, fieinfo, start, len, btrfs_get_extent); |
| 4164 | } | 4204 | } |
| 4165 | 4205 | ||
| 4166 | int btrfs_readpage(struct file *file, struct page *page) | 4206 | int btrfs_readpage(struct file *file, struct page *page) |
| @@ -4733,7 +4773,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
| 4733 | if (IS_ERR(inode)) | 4773 | if (IS_ERR(inode)) |
| 4734 | goto out_unlock; | 4774 | goto out_unlock; |
| 4735 | 4775 | ||
| 4736 | err = btrfs_init_acl(inode, dir); | 4776 | err = btrfs_init_inode_security(inode, dir); |
| 4737 | if (err) { | 4777 | if (err) { |
| 4738 | drop_inode = 1; | 4778 | drop_inode = 1; |
| 4739 | goto out_unlock; | 4779 | goto out_unlock; |
| @@ -4987,13 +5027,24 @@ static struct extent_io_ops btrfs_extent_io_ops = { | |||
| 4987 | .clear_bit_hook = btrfs_clear_bit_hook, | 5027 | .clear_bit_hook = btrfs_clear_bit_hook, |
| 4988 | }; | 5028 | }; |
| 4989 | 5029 | ||
| 5030 | /* | ||
| 5031 | * btrfs doesn't support the bmap operation because swapfiles | ||
| 5032 | * use bmap to make a mapping of extents in the file. They assume | ||
| 5033 | * these extents won't change over the life of the file and they | ||
| 5034 | * use the bmap result to do IO directly to the drive. | ||
| 5035 | * | ||
| 5036 | * the btrfs bmap call would return logical addresses that aren't | ||
| 5037 | * suitable for IO and they also will change frequently as COW | ||
| 5038 | * operations happen. So, swapfile + btrfs == corruption. | ||
| 5039 | * | ||
| 5040 | * For now we're avoiding this by dropping bmap. | ||
| 5041 | */ | ||
| 4990 | static struct address_space_operations btrfs_aops = { | 5042 | static struct address_space_operations btrfs_aops = { |
| 4991 | .readpage = btrfs_readpage, | 5043 | .readpage = btrfs_readpage, |
| 4992 | .writepage = btrfs_writepage, | 5044 | .writepage = btrfs_writepage, |
| 4993 | .writepages = btrfs_writepages, | 5045 | .writepages = btrfs_writepages, |
| 4994 | .readpages = btrfs_readpages, | 5046 | .readpages = btrfs_readpages, |
| 4995 | .sync_page = block_sync_page, | 5047 | .sync_page = block_sync_page, |
| 4996 | .bmap = btrfs_bmap, | ||
| 4997 | .direct_IO = btrfs_direct_IO, | 5048 | .direct_IO = btrfs_direct_IO, |
| 4998 | .invalidatepage = btrfs_invalidatepage, | 5049 | .invalidatepage = btrfs_invalidatepage, |
| 4999 | .releasepage = btrfs_releasepage, | 5050 | .releasepage = btrfs_releasepage, |
| @@ -5017,6 +5068,7 @@ static struct inode_operations btrfs_file_inode_operations = { | |||
| 5017 | .removexattr = btrfs_removexattr, | 5068 | .removexattr = btrfs_removexattr, |
| 5018 | .permission = btrfs_permission, | 5069 | .permission = btrfs_permission, |
| 5019 | .fallocate = btrfs_fallocate, | 5070 | .fallocate = btrfs_fallocate, |
| 5071 | .fiemap = btrfs_fiemap, | ||
| 5020 | }; | 5072 | }; |
| 5021 | static struct inode_operations btrfs_special_inode_operations = { | 5073 | static struct inode_operations btrfs_special_inode_operations = { |
| 5022 | .getattr = btrfs_getattr, | 5074 | .getattr = btrfs_getattr, |
| @@ -5032,4 +5084,8 @@ static struct inode_operations btrfs_symlink_inode_operations = { | |||
| 5032 | .follow_link = page_follow_link_light, | 5084 | .follow_link = page_follow_link_light, |
| 5033 | .put_link = page_put_link, | 5085 | .put_link = page_put_link, |
| 5034 | .permission = btrfs_permission, | 5086 | .permission = btrfs_permission, |
| 5087 | .setxattr = btrfs_setxattr, | ||
| 5088 | .getxattr = btrfs_getxattr, | ||
| 5089 | .listxattr = btrfs_listxattr, | ||
| 5090 | .removexattr = btrfs_removexattr, | ||
| 5035 | }; | 5091 | }; |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index c2aa33e3feb5..988fdc8b49eb 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
| @@ -38,7 +38,6 @@ | |||
| 38 | #include <linux/compat.h> | 38 | #include <linux/compat.h> |
| 39 | #include <linux/bit_spinlock.h> | 39 | #include <linux/bit_spinlock.h> |
| 40 | #include <linux/security.h> | 40 | #include <linux/security.h> |
| 41 | #include <linux/version.h> | ||
| 42 | #include <linux/xattr.h> | 41 | #include <linux/xattr.h> |
| 43 | #include <linux/vmalloc.h> | 42 | #include <linux/vmalloc.h> |
| 44 | #include "compat.h" | 43 | #include "compat.h" |
diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c index 39bae7761db6..68fd9ccf1805 100644 --- a/fs/btrfs/locking.c +++ b/fs/btrfs/locking.c | |||
| @@ -26,45 +26,215 @@ | |||
| 26 | #include "locking.h" | 26 | #include "locking.h" |
| 27 | 27 | ||
| 28 | /* | 28 | /* |
| 29 | * locks the per buffer mutex in an extent buffer. This uses adaptive locks | 29 | * btrfs_header_level() isn't free, so don't call it when lockdep isn't |
| 30 | * and the spin is not tuned very extensively. The spinning does make a big | 30 | * on |
| 31 | * difference in almost every workload, but spinning for the right amount of | ||
| 32 | * time needs some help. | ||
| 33 | * | ||
| 34 | * In general, we want to spin as long as the lock holder is doing btree | ||
| 35 | * searches, and we should give up if they are in more expensive code. | ||
| 36 | */ | 31 | */ |
| 32 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
| 33 | static inline void spin_nested(struct extent_buffer *eb) | ||
| 34 | { | ||
| 35 | spin_lock_nested(&eb->lock, BTRFS_MAX_LEVEL - btrfs_header_level(eb)); | ||
| 36 | } | ||
| 37 | #else | ||
| 38 | static inline void spin_nested(struct extent_buffer *eb) | ||
| 39 | { | ||
| 40 | spin_lock(&eb->lock); | ||
| 41 | } | ||
| 42 | #endif | ||
| 37 | 43 | ||
| 38 | int btrfs_tree_lock(struct extent_buffer *eb) | 44 | /* |
| 45 | * Setting a lock to blocking will drop the spinlock and set the | ||
| 46 | * flag that forces other procs who want the lock to wait. After | ||
| 47 | * this you can safely schedule with the lock held. | ||
| 48 | */ | ||
| 49 | void btrfs_set_lock_blocking(struct extent_buffer *eb) | ||
| 39 | { | 50 | { |
| 40 | int i; | 51 | if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) { |
| 52 | set_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags); | ||
| 53 | spin_unlock(&eb->lock); | ||
| 54 | } | ||
| 55 | /* exit with the spin lock released and the bit set */ | ||
| 56 | } | ||
| 41 | 57 | ||
| 42 | if (mutex_trylock(&eb->mutex)) | 58 | /* |
| 43 | return 0; | 59 | * clearing the blocking flag will take the spinlock again. |
| 60 | * After this you can't safely schedule | ||
| 61 | */ | ||
| 62 | void btrfs_clear_lock_blocking(struct extent_buffer *eb) | ||
| 63 | { | ||
| 64 | if (test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) { | ||
| 65 | spin_nested(eb); | ||
| 66 | clear_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags); | ||
| 67 | smp_mb__after_clear_bit(); | ||
| 68 | } | ||
| 69 | /* exit with the spin lock held */ | ||
| 70 | } | ||
| 71 | |||
| 72 | /* | ||
| 73 | * unfortunately, many of the places that currently set a lock to blocking | ||
| 74 | * don't end up blocking for every long, and often they don't block | ||
| 75 | * at all. For a dbench 50 run, if we don't spin one the blocking bit | ||
| 76 | * at all, the context switch rate can jump up to 400,000/sec or more. | ||
| 77 | * | ||
| 78 | * So, we're still stuck with this crummy spin on the blocking bit, | ||
| 79 | * at least until the most common causes of the short blocks | ||
| 80 | * can be dealt with. | ||
| 81 | */ | ||
| 82 | static int btrfs_spin_on_block(struct extent_buffer *eb) | ||
| 83 | { | ||
| 84 | int i; | ||
| 44 | for (i = 0; i < 512; i++) { | 85 | for (i = 0; i < 512; i++) { |
| 45 | cpu_relax(); | 86 | cpu_relax(); |
| 46 | if (mutex_trylock(&eb->mutex)) | 87 | if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) |
| 88 | return 1; | ||
| 89 | if (need_resched()) | ||
| 90 | break; | ||
| 91 | } | ||
| 92 | return 0; | ||
| 93 | } | ||
| 94 | |||
| 95 | /* | ||
| 96 | * This is somewhat different from trylock. It will take the | ||
| 97 | * spinlock but if it finds the lock is set to blocking, it will | ||
| 98 | * return without the lock held. | ||
| 99 | * | ||
| 100 | * returns 1 if it was able to take the lock and zero otherwise | ||
| 101 | * | ||
| 102 | * After this call, scheduling is not safe without first calling | ||
| 103 | * btrfs_set_lock_blocking() | ||
| 104 | */ | ||
| 105 | int btrfs_try_spin_lock(struct extent_buffer *eb) | ||
| 106 | { | ||
| 107 | int i; | ||
| 108 | |||
| 109 | spin_nested(eb); | ||
| 110 | if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) | ||
| 111 | return 1; | ||
| 112 | spin_unlock(&eb->lock); | ||
| 113 | |||
| 114 | /* spin for a bit on the BLOCKING flag */ | ||
| 115 | for (i = 0; i < 2; i++) { | ||
| 116 | if (!btrfs_spin_on_block(eb)) | ||
| 117 | break; | ||
| 118 | |||
| 119 | spin_nested(eb); | ||
| 120 | if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) | ||
| 121 | return 1; | ||
| 122 | spin_unlock(&eb->lock); | ||
| 123 | } | ||
| 124 | return 0; | ||
| 125 | } | ||
| 126 | |||
| 127 | /* | ||
| 128 | * the autoremove wake function will return 0 if it tried to wake up | ||
| 129 | * a process that was already awake, which means that process won't | ||
| 130 | * count as an exclusive wakeup. The waitq code will continue waking | ||
| 131 | * procs until it finds one that was actually sleeping. | ||
| 132 | * | ||
| 133 | * For btrfs, this isn't quite what we want. We want a single proc | ||
| 134 | * to be notified that the lock is ready for taking. If that proc | ||
| 135 | * already happen to be awake, great, it will loop around and try for | ||
| 136 | * the lock. | ||
| 137 | * | ||
| 138 | * So, btrfs_wake_function always returns 1, even when the proc that we | ||
| 139 | * tried to wake up was already awake. | ||
| 140 | */ | ||
| 141 | static int btrfs_wake_function(wait_queue_t *wait, unsigned mode, | ||
| 142 | int sync, void *key) | ||
| 143 | { | ||
| 144 | autoremove_wake_function(wait, mode, sync, key); | ||
| 145 | return 1; | ||
| 146 | } | ||
| 147 | |||
| 148 | /* | ||
| 149 | * returns with the extent buffer spinlocked. | ||
| 150 | * | ||
| 151 | * This will spin and/or wait as required to take the lock, and then | ||
| 152 | * return with the spinlock held. | ||
| 153 | * | ||
| 154 | * After this call, scheduling is not safe without first calling | ||
| 155 | * btrfs_set_lock_blocking() | ||
| 156 | */ | ||
| 157 | int btrfs_tree_lock(struct extent_buffer *eb) | ||
| 158 | { | ||
| 159 | DEFINE_WAIT(wait); | ||
| 160 | wait.func = btrfs_wake_function; | ||
| 161 | |||
| 162 | while(1) { | ||
| 163 | spin_nested(eb); | ||
| 164 | |||
| 165 | /* nobody is blocking, exit with the spinlock held */ | ||
| 166 | if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) | ||
| 47 | return 0; | 167 | return 0; |
| 168 | |||
| 169 | /* | ||
| 170 | * we have the spinlock, but the real owner is blocking. | ||
| 171 | * wait for them | ||
| 172 | */ | ||
| 173 | spin_unlock(&eb->lock); | ||
| 174 | |||
| 175 | /* | ||
| 176 | * spin for a bit, and if the blocking flag goes away, | ||
| 177 | * loop around | ||
| 178 | */ | ||
| 179 | if (btrfs_spin_on_block(eb)) | ||
| 180 | continue; | ||
| 181 | |||
| 182 | prepare_to_wait_exclusive(&eb->lock_wq, &wait, | ||
| 183 | TASK_UNINTERRUPTIBLE); | ||
| 184 | |||
| 185 | if (test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) | ||
| 186 | schedule(); | ||
| 187 | |||
| 188 | finish_wait(&eb->lock_wq, &wait); | ||
| 48 | } | 189 | } |
| 49 | cpu_relax(); | ||
| 50 | mutex_lock_nested(&eb->mutex, BTRFS_MAX_LEVEL - btrfs_header_level(eb)); | ||
| 51 | return 0; | 190 | return 0; |
| 52 | } | 191 | } |
| 53 | 192 | ||
| 193 | /* | ||
| 194 | * Very quick trylock, this does not spin or schedule. It returns | ||
| 195 | * 1 with the spinlock held if it was able to take the lock, or it | ||
| 196 | * returns zero if it was unable to take the lock. | ||
| 197 | * | ||
| 198 | * After this call, scheduling is not safe without first calling | ||
| 199 | * btrfs_set_lock_blocking() | ||
| 200 | */ | ||
| 54 | int btrfs_try_tree_lock(struct extent_buffer *eb) | 201 | int btrfs_try_tree_lock(struct extent_buffer *eb) |
| 55 | { | 202 | { |
| 56 | return mutex_trylock(&eb->mutex); | 203 | if (spin_trylock(&eb->lock)) { |
| 204 | if (test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) { | ||
| 205 | /* | ||
| 206 | * we've got the spinlock, but the real owner is | ||
| 207 | * blocking. Drop the spinlock and return failure | ||
| 208 | */ | ||
| 209 | spin_unlock(&eb->lock); | ||
| 210 | return 0; | ||
| 211 | } | ||
| 212 | return 1; | ||
| 213 | } | ||
| 214 | /* someone else has the spinlock giveup */ | ||
| 215 | return 0; | ||
| 57 | } | 216 | } |
| 58 | 217 | ||
| 59 | int btrfs_tree_unlock(struct extent_buffer *eb) | 218 | int btrfs_tree_unlock(struct extent_buffer *eb) |
| 60 | { | 219 | { |
| 61 | mutex_unlock(&eb->mutex); | 220 | /* |
| 221 | * if we were a blocking owner, we don't have the spinlock held | ||
| 222 | * just clear the bit and look for waiters | ||
| 223 | */ | ||
| 224 | if (test_and_clear_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) | ||
| 225 | smp_mb__after_clear_bit(); | ||
| 226 | else | ||
| 227 | spin_unlock(&eb->lock); | ||
| 228 | |||
| 229 | if (waitqueue_active(&eb->lock_wq)) | ||
| 230 | wake_up(&eb->lock_wq); | ||
| 62 | return 0; | 231 | return 0; |
| 63 | } | 232 | } |
| 64 | 233 | ||
| 65 | int btrfs_tree_locked(struct extent_buffer *eb) | 234 | int btrfs_tree_locked(struct extent_buffer *eb) |
| 66 | { | 235 | { |
| 67 | return mutex_is_locked(&eb->mutex); | 236 | return test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags) || |
| 237 | spin_is_locked(&eb->lock); | ||
| 68 | } | 238 | } |
| 69 | 239 | ||
| 70 | /* | 240 | /* |
| @@ -75,12 +245,14 @@ int btrfs_path_lock_waiting(struct btrfs_path *path, int level) | |||
| 75 | { | 245 | { |
| 76 | int i; | 246 | int i; |
| 77 | struct extent_buffer *eb; | 247 | struct extent_buffer *eb; |
| 248 | |||
| 78 | for (i = level; i <= level + 1 && i < BTRFS_MAX_LEVEL; i++) { | 249 | for (i = level; i <= level + 1 && i < BTRFS_MAX_LEVEL; i++) { |
| 79 | eb = path->nodes[i]; | 250 | eb = path->nodes[i]; |
| 80 | if (!eb) | 251 | if (!eb) |
| 81 | break; | 252 | break; |
| 82 | smp_mb(); | 253 | smp_mb(); |
| 83 | if (!list_empty(&eb->mutex.wait_list)) | 254 | if (spin_is_contended(&eb->lock) || |
| 255 | waitqueue_active(&eb->lock_wq)) | ||
| 84 | return 1; | 256 | return 1; |
| 85 | } | 257 | } |
| 86 | return 0; | 258 | return 0; |
diff --git a/fs/btrfs/locking.h b/fs/btrfs/locking.h index bc1faef12519..d92e707f5870 100644 --- a/fs/btrfs/locking.h +++ b/fs/btrfs/locking.h | |||
| @@ -22,6 +22,12 @@ | |||
| 22 | int btrfs_tree_lock(struct extent_buffer *eb); | 22 | int btrfs_tree_lock(struct extent_buffer *eb); |
| 23 | int btrfs_tree_unlock(struct extent_buffer *eb); | 23 | int btrfs_tree_unlock(struct extent_buffer *eb); |
| 24 | int btrfs_tree_locked(struct extent_buffer *eb); | 24 | int btrfs_tree_locked(struct extent_buffer *eb); |
| 25 | |||
| 25 | int btrfs_try_tree_lock(struct extent_buffer *eb); | 26 | int btrfs_try_tree_lock(struct extent_buffer *eb); |
| 27 | int btrfs_try_spin_lock(struct extent_buffer *eb); | ||
| 28 | |||
| 26 | int btrfs_path_lock_waiting(struct btrfs_path *path, int level); | 29 | int btrfs_path_lock_waiting(struct btrfs_path *path, int level); |
| 30 | |||
| 31 | void btrfs_set_lock_blocking(struct extent_buffer *eb); | ||
| 32 | void btrfs_clear_lock_blocking(struct extent_buffer *eb); | ||
| 27 | #endif | 33 | #endif |
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index a20940170274..77c2411a5f0f 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c | |||
| @@ -613,7 +613,6 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr, | |||
| 613 | struct btrfs_sector_sum *sector_sums; | 613 | struct btrfs_sector_sum *sector_sums; |
| 614 | struct btrfs_ordered_extent *ordered; | 614 | struct btrfs_ordered_extent *ordered; |
| 615 | struct btrfs_ordered_inode_tree *tree = &BTRFS_I(inode)->ordered_tree; | 615 | struct btrfs_ordered_inode_tree *tree = &BTRFS_I(inode)->ordered_tree; |
| 616 | struct list_head *cur; | ||
| 617 | unsigned long num_sectors; | 616 | unsigned long num_sectors; |
| 618 | unsigned long i; | 617 | unsigned long i; |
| 619 | u32 sectorsize = BTRFS_I(inode)->root->sectorsize; | 618 | u32 sectorsize = BTRFS_I(inode)->root->sectorsize; |
| @@ -624,8 +623,7 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr, | |||
| 624 | return 1; | 623 | return 1; |
| 625 | 624 | ||
| 626 | mutex_lock(&tree->mutex); | 625 | mutex_lock(&tree->mutex); |
| 627 | list_for_each_prev(cur, &ordered->list) { | 626 | list_for_each_entry_reverse(ordered_sum, &ordered->list, list) { |
| 628 | ordered_sum = list_entry(cur, struct btrfs_ordered_sum, list); | ||
| 629 | if (disk_bytenr >= ordered_sum->bytenr) { | 627 | if (disk_bytenr >= ordered_sum->bytenr) { |
| 630 | num_sectors = ordered_sum->len / sectorsize; | 628 | num_sectors = ordered_sum->len / sectorsize; |
| 631 | sector_sums = ordered_sum->sums; | 629 | sector_sums = ordered_sum->sums; |
diff --git a/fs/btrfs/ref-cache.c b/fs/btrfs/ref-cache.c index 6f0acc4c9eab..d0cc62bccb94 100644 --- a/fs/btrfs/ref-cache.c +++ b/fs/btrfs/ref-cache.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | */ | 17 | */ |
| 18 | 18 | ||
| 19 | #include <linux/sched.h> | 19 | #include <linux/sched.h> |
| 20 | #include <linux/sort.h> | ||
| 20 | #include "ctree.h" | 21 | #include "ctree.h" |
| 21 | #include "ref-cache.h" | 22 | #include "ref-cache.h" |
| 22 | #include "transaction.h" | 23 | #include "transaction.h" |
diff --git a/fs/btrfs/ref-cache.h b/fs/btrfs/ref-cache.h index 16f3183d7c59..bc283ad2db73 100644 --- a/fs/btrfs/ref-cache.h +++ b/fs/btrfs/ref-cache.h | |||
| @@ -73,5 +73,4 @@ int btrfs_add_leaf_ref(struct btrfs_root *root, struct btrfs_leaf_ref *ref, | |||
| 73 | int btrfs_remove_leaf_refs(struct btrfs_root *root, u64 max_root_gen, | 73 | int btrfs_remove_leaf_refs(struct btrfs_root *root, u64 max_root_gen, |
| 74 | int shared); | 74 | int shared); |
| 75 | int btrfs_remove_leaf_ref(struct btrfs_root *root, struct btrfs_leaf_ref *ref); | 75 | int btrfs_remove_leaf_ref(struct btrfs_root *root, struct btrfs_leaf_ref *ref); |
| 76 | |||
| 77 | #endif | 76 | #endif |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index db9fb3bc1e33..f3fd7e2cbc38 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
| @@ -37,7 +37,6 @@ | |||
| 37 | #include <linux/ctype.h> | 37 | #include <linux/ctype.h> |
| 38 | #include <linux/namei.h> | 38 | #include <linux/namei.h> |
| 39 | #include <linux/miscdevice.h> | 39 | #include <linux/miscdevice.h> |
| 40 | #include <linux/version.h> | ||
| 41 | #include <linux/magic.h> | 40 | #include <linux/magic.h> |
| 42 | #include "compat.h" | 41 | #include "compat.h" |
| 43 | #include "ctree.h" | 42 | #include "ctree.h" |
| @@ -583,17 +582,18 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd, | |||
| 583 | struct btrfs_ioctl_vol_args *vol; | 582 | struct btrfs_ioctl_vol_args *vol; |
| 584 | struct btrfs_fs_devices *fs_devices; | 583 | struct btrfs_fs_devices *fs_devices; |
| 585 | int ret = -ENOTTY; | 584 | int ret = -ENOTTY; |
| 586 | int len; | ||
| 587 | 585 | ||
| 588 | if (!capable(CAP_SYS_ADMIN)) | 586 | if (!capable(CAP_SYS_ADMIN)) |
| 589 | return -EPERM; | 587 | return -EPERM; |
| 590 | 588 | ||
| 591 | vol = kmalloc(sizeof(*vol), GFP_KERNEL); | 589 | vol = kmalloc(sizeof(*vol), GFP_KERNEL); |
| 590 | if (!vol) | ||
| 591 | return -ENOMEM; | ||
| 592 | |||
| 592 | if (copy_from_user(vol, (void __user *)arg, sizeof(*vol))) { | 593 | if (copy_from_user(vol, (void __user *)arg, sizeof(*vol))) { |
| 593 | ret = -EFAULT; | 594 | ret = -EFAULT; |
| 594 | goto out; | 595 | goto out; |
| 595 | } | 596 | } |
| 596 | len = strnlen(vol->name, BTRFS_PATH_NAME_MAX); | ||
| 597 | 597 | ||
| 598 | switch (cmd) { | 598 | switch (cmd) { |
| 599 | case BTRFS_IOC_SCAN_DEV: | 599 | case BTRFS_IOC_SCAN_DEV: |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 8a08f9443340..919172de5c9a 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
| @@ -852,11 +852,9 @@ static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans, | |||
| 852 | { | 852 | { |
| 853 | struct btrfs_pending_snapshot *pending; | 853 | struct btrfs_pending_snapshot *pending; |
| 854 | struct list_head *head = &trans->transaction->pending_snapshots; | 854 | struct list_head *head = &trans->transaction->pending_snapshots; |
| 855 | struct list_head *cur; | ||
| 856 | int ret; | 855 | int ret; |
| 857 | 856 | ||
| 858 | list_for_each(cur, head) { | 857 | list_for_each_entry(pending, head, list) { |
| 859 | pending = list_entry(cur, struct btrfs_pending_snapshot, list); | ||
| 860 | ret = create_pending_snapshot(trans, fs_info, pending); | 858 | ret = create_pending_snapshot(trans, fs_info, pending); |
| 861 | BUG_ON(ret); | 859 | BUG_ON(ret); |
| 862 | } | 860 | } |
diff --git a/fs/btrfs/tree-defrag.c b/fs/btrfs/tree-defrag.c index 3e8358c36165..98d25fa4570e 100644 --- a/fs/btrfs/tree-defrag.c +++ b/fs/btrfs/tree-defrag.c | |||
| @@ -74,6 +74,7 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, | |||
| 74 | u32 nritems; | 74 | u32 nritems; |
| 75 | 75 | ||
| 76 | root_node = btrfs_lock_root_node(root); | 76 | root_node = btrfs_lock_root_node(root); |
| 77 | btrfs_set_lock_blocking(root_node); | ||
| 77 | nritems = btrfs_header_nritems(root_node); | 78 | nritems = btrfs_header_nritems(root_node); |
| 78 | root->defrag_max.objectid = 0; | 79 | root->defrag_max.objectid = 0; |
| 79 | /* from above we know this is not a leaf */ | 80 | /* from above we know this is not a leaf */ |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index d81cda2e077c..20794290256b 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
| @@ -78,104 +78,6 @@ static int link_to_fixup_dir(struct btrfs_trans_handle *trans, | |||
| 78 | */ | 78 | */ |
| 79 | 79 | ||
| 80 | /* | 80 | /* |
| 81 | * btrfs_add_log_tree adds a new per-subvolume log tree into the | ||
| 82 | * tree of log tree roots. This must be called with a tree log transaction | ||
| 83 | * running (see start_log_trans). | ||
| 84 | */ | ||
| 85 | static int btrfs_add_log_tree(struct btrfs_trans_handle *trans, | ||
| 86 | struct btrfs_root *root) | ||
| 87 | { | ||
| 88 | struct btrfs_key key; | ||
| 89 | struct btrfs_root_item root_item; | ||
| 90 | struct btrfs_inode_item *inode_item; | ||
| 91 | struct extent_buffer *leaf; | ||
| 92 | struct btrfs_root *new_root = root; | ||
| 93 | int ret; | ||
| 94 | u64 objectid = root->root_key.objectid; | ||
| 95 | |||
| 96 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, 0, | ||
| 97 | BTRFS_TREE_LOG_OBJECTID, | ||
| 98 | trans->transid, 0, 0, 0); | ||
| 99 | if (IS_ERR(leaf)) { | ||
| 100 | ret = PTR_ERR(leaf); | ||
| 101 | return ret; | ||
| 102 | } | ||
| 103 | |||
| 104 | btrfs_set_header_nritems(leaf, 0); | ||
| 105 | btrfs_set_header_level(leaf, 0); | ||
| 106 | btrfs_set_header_bytenr(leaf, leaf->start); | ||
| 107 | btrfs_set_header_generation(leaf, trans->transid); | ||
| 108 | btrfs_set_header_owner(leaf, BTRFS_TREE_LOG_OBJECTID); | ||
| 109 | |||
| 110 | write_extent_buffer(leaf, root->fs_info->fsid, | ||
| 111 | (unsigned long)btrfs_header_fsid(leaf), | ||
| 112 | BTRFS_FSID_SIZE); | ||
| 113 | btrfs_mark_buffer_dirty(leaf); | ||
| 114 | |||
| 115 | inode_item = &root_item.inode; | ||
| 116 | memset(inode_item, 0, sizeof(*inode_item)); | ||
| 117 | inode_item->generation = cpu_to_le64(1); | ||
| 118 | inode_item->size = cpu_to_le64(3); | ||
| 119 | inode_item->nlink = cpu_to_le32(1); | ||
| 120 | inode_item->nbytes = cpu_to_le64(root->leafsize); | ||
| 121 | inode_item->mode = cpu_to_le32(S_IFDIR | 0755); | ||
| 122 | |||
| 123 | btrfs_set_root_bytenr(&root_item, leaf->start); | ||
| 124 | btrfs_set_root_generation(&root_item, trans->transid); | ||
| 125 | btrfs_set_root_level(&root_item, 0); | ||
| 126 | btrfs_set_root_refs(&root_item, 0); | ||
| 127 | btrfs_set_root_used(&root_item, 0); | ||
| 128 | |||
| 129 | memset(&root_item.drop_progress, 0, sizeof(root_item.drop_progress)); | ||
| 130 | root_item.drop_level = 0; | ||
| 131 | |||
| 132 | btrfs_tree_unlock(leaf); | ||
| 133 | free_extent_buffer(leaf); | ||
| 134 | leaf = NULL; | ||
| 135 | |||
| 136 | btrfs_set_root_dirid(&root_item, 0); | ||
| 137 | |||
| 138 | key.objectid = BTRFS_TREE_LOG_OBJECTID; | ||
| 139 | key.offset = objectid; | ||
| 140 | btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); | ||
| 141 | ret = btrfs_insert_root(trans, root->fs_info->log_root_tree, &key, | ||
| 142 | &root_item); | ||
| 143 | if (ret) | ||
| 144 | goto fail; | ||
| 145 | |||
| 146 | new_root = btrfs_read_fs_root_no_radix(root->fs_info->log_root_tree, | ||
| 147 | &key); | ||
| 148 | BUG_ON(!new_root); | ||
| 149 | |||
| 150 | WARN_ON(root->log_root); | ||
| 151 | root->log_root = new_root; | ||
| 152 | |||
| 153 | /* | ||
| 154 | * log trees do not get reference counted because they go away | ||
| 155 | * before a real commit is actually done. They do store pointers | ||
| 156 | * to file data extents, and those reference counts still get | ||
| 157 | * updated (along with back refs to the log tree). | ||
| 158 | */ | ||
| 159 | new_root->ref_cows = 0; | ||
| 160 | new_root->last_trans = trans->transid; | ||
| 161 | |||
| 162 | /* | ||
| 163 | * we need to make sure the root block for this new tree | ||
| 164 | * is marked as dirty in the dirty_log_pages tree. This | ||
| 165 | * is how it gets flushed down to disk at tree log commit time. | ||
| 166 | * | ||
| 167 | * the tree logging mutex keeps others from coming in and changing | ||
| 168 | * the new_root->node, so we can safely access it here | ||
| 169 | */ | ||
| 170 | set_extent_dirty(&new_root->dirty_log_pages, new_root->node->start, | ||
| 171 | new_root->node->start + new_root->node->len - 1, | ||
| 172 | GFP_NOFS); | ||
| 173 | |||
| 174 | fail: | ||
| 175 | return ret; | ||
| 176 | } | ||
| 177 | |||
| 178 | /* | ||
| 179 | * start a sub transaction and setup the log tree | 81 | * start a sub transaction and setup the log tree |
| 180 | * this increments the log tree writer count to make the people | 82 | * this increments the log tree writer count to make the people |
| 181 | * syncing the tree wait for us to finish | 83 | * syncing the tree wait for us to finish |
| @@ -184,6 +86,14 @@ static int start_log_trans(struct btrfs_trans_handle *trans, | |||
| 184 | struct btrfs_root *root) | 86 | struct btrfs_root *root) |
| 185 | { | 87 | { |
| 186 | int ret; | 88 | int ret; |
| 89 | |||
| 90 | mutex_lock(&root->log_mutex); | ||
| 91 | if (root->log_root) { | ||
| 92 | root->log_batch++; | ||
| 93 | atomic_inc(&root->log_writers); | ||
| 94 | mutex_unlock(&root->log_mutex); | ||
| 95 | return 0; | ||
| 96 | } | ||
| 187 | mutex_lock(&root->fs_info->tree_log_mutex); | 97 | mutex_lock(&root->fs_info->tree_log_mutex); |
| 188 | if (!root->fs_info->log_root_tree) { | 98 | if (!root->fs_info->log_root_tree) { |
| 189 | ret = btrfs_init_log_root_tree(trans, root->fs_info); | 99 | ret = btrfs_init_log_root_tree(trans, root->fs_info); |
| @@ -193,9 +103,10 @@ static int start_log_trans(struct btrfs_trans_handle *trans, | |||
| 193 | ret = btrfs_add_log_tree(trans, root); | 103 | ret = btrfs_add_log_tree(trans, root); |
| 194 | BUG_ON(ret); | 104 | BUG_ON(ret); |
| 195 | } | 105 | } |
| 196 | atomic_inc(&root->fs_info->tree_log_writers); | ||
| 197 | root->fs_info->tree_log_batch++; | ||
| 198 | mutex_unlock(&root->fs_info->tree_log_mutex); | 106 | mutex_unlock(&root->fs_info->tree_log_mutex); |
| 107 | root->log_batch++; | ||
| 108 | atomic_inc(&root->log_writers); | ||
| 109 | mutex_unlock(&root->log_mutex); | ||
| 199 | return 0; | 110 | return 0; |
| 200 | } | 111 | } |
| 201 | 112 | ||
| @@ -212,13 +123,12 @@ static int join_running_log_trans(struct btrfs_root *root) | |||
| 212 | if (!root->log_root) | 123 | if (!root->log_root) |
| 213 | return -ENOENT; | 124 | return -ENOENT; |
| 214 | 125 | ||
| 215 | mutex_lock(&root->fs_info->tree_log_mutex); | 126 | mutex_lock(&root->log_mutex); |
| 216 | if (root->log_root) { | 127 | if (root->log_root) { |
| 217 | ret = 0; | 128 | ret = 0; |
| 218 | atomic_inc(&root->fs_info->tree_log_writers); | 129 | atomic_inc(&root->log_writers); |
| 219 | root->fs_info->tree_log_batch++; | ||
| 220 | } | 130 | } |
| 221 | mutex_unlock(&root->fs_info->tree_log_mutex); | 131 | mutex_unlock(&root->log_mutex); |
| 222 | return ret; | 132 | return ret; |
| 223 | } | 133 | } |
| 224 | 134 | ||
| @@ -228,10 +138,11 @@ static int join_running_log_trans(struct btrfs_root *root) | |||
| 228 | */ | 138 | */ |
| 229 | static int end_log_trans(struct btrfs_root *root) | 139 | static int end_log_trans(struct btrfs_root *root) |
| 230 | { | 140 | { |
| 231 | atomic_dec(&root->fs_info->tree_log_writers); | 141 | if (atomic_dec_and_test(&root->log_writers)) { |
| 232 | smp_mb(); | 142 | smp_mb(); |
| 233 | if (waitqueue_active(&root->fs_info->tree_log_wait)) | 143 | if (waitqueue_active(&root->log_writer_wait)) |
| 234 | wake_up(&root->fs_info->tree_log_wait); | 144 | wake_up(&root->log_writer_wait); |
| 145 | } | ||
| 235 | return 0; | 146 | return 0; |
| 236 | } | 147 | } |
| 237 | 148 | ||
| @@ -1704,6 +1615,7 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans, | |||
| 1704 | 1615 | ||
| 1705 | btrfs_tree_lock(next); | 1616 | btrfs_tree_lock(next); |
| 1706 | clean_tree_block(trans, root, next); | 1617 | clean_tree_block(trans, root, next); |
| 1618 | btrfs_set_lock_blocking(next); | ||
| 1707 | btrfs_wait_tree_block_writeback(next); | 1619 | btrfs_wait_tree_block_writeback(next); |
| 1708 | btrfs_tree_unlock(next); | 1620 | btrfs_tree_unlock(next); |
| 1709 | 1621 | ||
| @@ -1750,6 +1662,7 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans, | |||
| 1750 | next = path->nodes[*level]; | 1662 | next = path->nodes[*level]; |
| 1751 | btrfs_tree_lock(next); | 1663 | btrfs_tree_lock(next); |
| 1752 | clean_tree_block(trans, root, next); | 1664 | clean_tree_block(trans, root, next); |
| 1665 | btrfs_set_lock_blocking(next); | ||
| 1753 | btrfs_wait_tree_block_writeback(next); | 1666 | btrfs_wait_tree_block_writeback(next); |
| 1754 | btrfs_tree_unlock(next); | 1667 | btrfs_tree_unlock(next); |
| 1755 | 1668 | ||
| @@ -1807,6 +1720,7 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans, | |||
| 1807 | 1720 | ||
| 1808 | btrfs_tree_lock(next); | 1721 | btrfs_tree_lock(next); |
| 1809 | clean_tree_block(trans, root, next); | 1722 | clean_tree_block(trans, root, next); |
| 1723 | btrfs_set_lock_blocking(next); | ||
| 1810 | btrfs_wait_tree_block_writeback(next); | 1724 | btrfs_wait_tree_block_writeback(next); |
| 1811 | btrfs_tree_unlock(next); | 1725 | btrfs_tree_unlock(next); |
| 1812 | 1726 | ||
| @@ -1879,6 +1793,7 @@ static int walk_log_tree(struct btrfs_trans_handle *trans, | |||
| 1879 | 1793 | ||
| 1880 | btrfs_tree_lock(next); | 1794 | btrfs_tree_lock(next); |
| 1881 | clean_tree_block(trans, log, next); | 1795 | clean_tree_block(trans, log, next); |
| 1796 | btrfs_set_lock_blocking(next); | ||
| 1882 | btrfs_wait_tree_block_writeback(next); | 1797 | btrfs_wait_tree_block_writeback(next); |
| 1883 | btrfs_tree_unlock(next); | 1798 | btrfs_tree_unlock(next); |
| 1884 | 1799 | ||
| @@ -1902,26 +1817,65 @@ static int walk_log_tree(struct btrfs_trans_handle *trans, | |||
| 1902 | } | 1817 | } |
| 1903 | } | 1818 | } |
| 1904 | btrfs_free_path(path); | 1819 | btrfs_free_path(path); |
| 1905 | if (wc->free) | ||
| 1906 | free_extent_buffer(log->node); | ||
| 1907 | return ret; | 1820 | return ret; |
| 1908 | } | 1821 | } |
| 1909 | 1822 | ||
| 1910 | static int wait_log_commit(struct btrfs_root *log) | 1823 | /* |
| 1824 | * helper function to update the item for a given subvolumes log root | ||
| 1825 | * in the tree of log roots | ||
| 1826 | */ | ||
| 1827 | static int update_log_root(struct btrfs_trans_handle *trans, | ||
| 1828 | struct btrfs_root *log) | ||
| 1829 | { | ||
| 1830 | int ret; | ||
| 1831 | |||
| 1832 | if (log->log_transid == 1) { | ||
| 1833 | /* insert root item on the first sync */ | ||
| 1834 | ret = btrfs_insert_root(trans, log->fs_info->log_root_tree, | ||
| 1835 | &log->root_key, &log->root_item); | ||
| 1836 | } else { | ||
| 1837 | ret = btrfs_update_root(trans, log->fs_info->log_root_tree, | ||
| 1838 | &log->root_key, &log->root_item); | ||
| 1839 | } | ||
| 1840 | return ret; | ||
| 1841 | } | ||
| 1842 | |||
| 1843 | static int wait_log_commit(struct btrfs_root *root, unsigned long transid) | ||
| 1911 | { | 1844 | { |
| 1912 | DEFINE_WAIT(wait); | 1845 | DEFINE_WAIT(wait); |
| 1913 | u64 transid = log->fs_info->tree_log_transid; | 1846 | int index = transid % 2; |
| 1914 | 1847 | ||
| 1848 | /* | ||
| 1849 | * we only allow two pending log transactions at a time, | ||
| 1850 | * so we know that if ours is more than 2 older than the | ||
| 1851 | * current transaction, we're done | ||
| 1852 | */ | ||
| 1915 | do { | 1853 | do { |
| 1916 | prepare_to_wait(&log->fs_info->tree_log_wait, &wait, | 1854 | prepare_to_wait(&root->log_commit_wait[index], |
| 1917 | TASK_UNINTERRUPTIBLE); | 1855 | &wait, TASK_UNINTERRUPTIBLE); |
| 1918 | mutex_unlock(&log->fs_info->tree_log_mutex); | 1856 | mutex_unlock(&root->log_mutex); |
| 1919 | if (atomic_read(&log->fs_info->tree_log_commit)) | 1857 | if (root->log_transid < transid + 2 && |
| 1858 | atomic_read(&root->log_commit[index])) | ||
| 1920 | schedule(); | 1859 | schedule(); |
| 1921 | finish_wait(&log->fs_info->tree_log_wait, &wait); | 1860 | finish_wait(&root->log_commit_wait[index], &wait); |
| 1922 | mutex_lock(&log->fs_info->tree_log_mutex); | 1861 | mutex_lock(&root->log_mutex); |
| 1923 | } while (transid == log->fs_info->tree_log_transid && | 1862 | } while (root->log_transid < transid + 2 && |
| 1924 | atomic_read(&log->fs_info->tree_log_commit)); | 1863 | atomic_read(&root->log_commit[index])); |
| 1864 | return 0; | ||
| 1865 | } | ||
| 1866 | |||
| 1867 | static int wait_for_writer(struct btrfs_root *root) | ||
| 1868 | { | ||
| 1869 | DEFINE_WAIT(wait); | ||
| 1870 | while (atomic_read(&root->log_writers)) { | ||
| 1871 | prepare_to_wait(&root->log_writer_wait, | ||
| 1872 | &wait, TASK_UNINTERRUPTIBLE); | ||
| 1873 | mutex_unlock(&root->log_mutex); | ||
| 1874 | if (atomic_read(&root->log_writers)) | ||
| 1875 | schedule(); | ||
| 1876 | mutex_lock(&root->log_mutex); | ||
| 1877 | finish_wait(&root->log_writer_wait, &wait); | ||
| 1878 | } | ||
| 1925 | return 0; | 1879 | return 0; |
| 1926 | } | 1880 | } |
| 1927 | 1881 | ||
| @@ -1933,57 +1887,114 @@ static int wait_log_commit(struct btrfs_root *log) | |||
| 1933 | int btrfs_sync_log(struct btrfs_trans_handle *trans, | 1887 | int btrfs_sync_log(struct btrfs_trans_handle *trans, |
| 1934 | struct btrfs_root *root) | 1888 | struct btrfs_root *root) |
| 1935 | { | 1889 | { |
| 1890 | int index1; | ||
| 1891 | int index2; | ||
| 1936 | int ret; | 1892 | int ret; |
| 1937 | unsigned long batch; | ||
| 1938 | struct btrfs_root *log = root->log_root; | 1893 | struct btrfs_root *log = root->log_root; |
| 1894 | struct btrfs_root *log_root_tree = root->fs_info->log_root_tree; | ||
| 1939 | 1895 | ||
| 1940 | mutex_lock(&log->fs_info->tree_log_mutex); | 1896 | mutex_lock(&root->log_mutex); |
| 1941 | if (atomic_read(&log->fs_info->tree_log_commit)) { | 1897 | index1 = root->log_transid % 2; |
| 1942 | wait_log_commit(log); | 1898 | if (atomic_read(&root->log_commit[index1])) { |
| 1943 | goto out; | 1899 | wait_log_commit(root, root->log_transid); |
| 1900 | mutex_unlock(&root->log_mutex); | ||
| 1901 | return 0; | ||
| 1944 | } | 1902 | } |
| 1945 | atomic_set(&log->fs_info->tree_log_commit, 1); | 1903 | atomic_set(&root->log_commit[index1], 1); |
| 1904 | |||
| 1905 | /* wait for previous tree log sync to complete */ | ||
| 1906 | if (atomic_read(&root->log_commit[(index1 + 1) % 2])) | ||
| 1907 | wait_log_commit(root, root->log_transid - 1); | ||
| 1946 | 1908 | ||
| 1947 | while (1) { | 1909 | while (1) { |
| 1948 | batch = log->fs_info->tree_log_batch; | 1910 | unsigned long batch = root->log_batch; |
| 1949 | mutex_unlock(&log->fs_info->tree_log_mutex); | 1911 | mutex_unlock(&root->log_mutex); |
| 1950 | schedule_timeout_uninterruptible(1); | 1912 | schedule_timeout_uninterruptible(1); |
| 1951 | mutex_lock(&log->fs_info->tree_log_mutex); | 1913 | mutex_lock(&root->log_mutex); |
| 1952 | 1914 | wait_for_writer(root); | |
| 1953 | while (atomic_read(&log->fs_info->tree_log_writers)) { | 1915 | if (batch == root->log_batch) |
| 1954 | DEFINE_WAIT(wait); | ||
| 1955 | prepare_to_wait(&log->fs_info->tree_log_wait, &wait, | ||
| 1956 | TASK_UNINTERRUPTIBLE); | ||
| 1957 | mutex_unlock(&log->fs_info->tree_log_mutex); | ||
| 1958 | if (atomic_read(&log->fs_info->tree_log_writers)) | ||
| 1959 | schedule(); | ||
| 1960 | mutex_lock(&log->fs_info->tree_log_mutex); | ||
| 1961 | finish_wait(&log->fs_info->tree_log_wait, &wait); | ||
| 1962 | } | ||
| 1963 | if (batch == log->fs_info->tree_log_batch) | ||
| 1964 | break; | 1916 | break; |
| 1965 | } | 1917 | } |
| 1966 | 1918 | ||
| 1967 | ret = btrfs_write_and_wait_marked_extents(log, &log->dirty_log_pages); | 1919 | ret = btrfs_write_and_wait_marked_extents(log, &log->dirty_log_pages); |
| 1968 | BUG_ON(ret); | 1920 | BUG_ON(ret); |
| 1969 | ret = btrfs_write_and_wait_marked_extents(root->fs_info->log_root_tree, | 1921 | |
| 1970 | &root->fs_info->log_root_tree->dirty_log_pages); | 1922 | btrfs_set_root_bytenr(&log->root_item, log->node->start); |
| 1923 | btrfs_set_root_generation(&log->root_item, trans->transid); | ||
| 1924 | btrfs_set_root_level(&log->root_item, btrfs_header_level(log->node)); | ||
| 1925 | |||
| 1926 | root->log_batch = 0; | ||
| 1927 | root->log_transid++; | ||
| 1928 | log->log_transid = root->log_transid; | ||
| 1929 | smp_mb(); | ||
| 1930 | /* | ||
| 1931 | * log tree has been flushed to disk, new modifications of | ||
| 1932 | * the log will be written to new positions. so it's safe to | ||
| 1933 | * allow log writers to go in. | ||
| 1934 | */ | ||
| 1935 | mutex_unlock(&root->log_mutex); | ||
| 1936 | |||
| 1937 | mutex_lock(&log_root_tree->log_mutex); | ||
| 1938 | log_root_tree->log_batch++; | ||
| 1939 | atomic_inc(&log_root_tree->log_writers); | ||
| 1940 | mutex_unlock(&log_root_tree->log_mutex); | ||
| 1941 | |||
| 1942 | ret = update_log_root(trans, log); | ||
| 1943 | BUG_ON(ret); | ||
| 1944 | |||
| 1945 | mutex_lock(&log_root_tree->log_mutex); | ||
| 1946 | if (atomic_dec_and_test(&log_root_tree->log_writers)) { | ||
| 1947 | smp_mb(); | ||
| 1948 | if (waitqueue_active(&log_root_tree->log_writer_wait)) | ||
| 1949 | wake_up(&log_root_tree->log_writer_wait); | ||
| 1950 | } | ||
| 1951 | |||
| 1952 | index2 = log_root_tree->log_transid % 2; | ||
| 1953 | if (atomic_read(&log_root_tree->log_commit[index2])) { | ||
| 1954 | wait_log_commit(log_root_tree, log_root_tree->log_transid); | ||
| 1955 | mutex_unlock(&log_root_tree->log_mutex); | ||
| 1956 | goto out; | ||
| 1957 | } | ||
| 1958 | atomic_set(&log_root_tree->log_commit[index2], 1); | ||
| 1959 | |||
| 1960 | if (atomic_read(&log_root_tree->log_commit[(index2 + 1) % 2])) | ||
| 1961 | wait_log_commit(log_root_tree, log_root_tree->log_transid - 1); | ||
| 1962 | |||
| 1963 | wait_for_writer(log_root_tree); | ||
| 1964 | |||
| 1965 | ret = btrfs_write_and_wait_marked_extents(log_root_tree, | ||
| 1966 | &log_root_tree->dirty_log_pages); | ||
| 1971 | BUG_ON(ret); | 1967 | BUG_ON(ret); |
| 1972 | 1968 | ||
| 1973 | btrfs_set_super_log_root(&root->fs_info->super_for_commit, | 1969 | btrfs_set_super_log_root(&root->fs_info->super_for_commit, |
| 1974 | log->fs_info->log_root_tree->node->start); | 1970 | log_root_tree->node->start); |
| 1975 | btrfs_set_super_log_root_level(&root->fs_info->super_for_commit, | 1971 | btrfs_set_super_log_root_level(&root->fs_info->super_for_commit, |
| 1976 | btrfs_header_level(log->fs_info->log_root_tree->node)); | 1972 | btrfs_header_level(log_root_tree->node)); |
| 1973 | |||
| 1974 | log_root_tree->log_batch = 0; | ||
| 1975 | log_root_tree->log_transid++; | ||
| 1976 | smp_mb(); | ||
| 1977 | |||
| 1978 | mutex_unlock(&log_root_tree->log_mutex); | ||
| 1979 | |||
| 1980 | /* | ||
| 1981 | * nobody else is going to jump in and write the the ctree | ||
| 1982 | * super here because the log_commit atomic below is protecting | ||
| 1983 | * us. We must be called with a transaction handle pinning | ||
| 1984 | * the running transaction open, so a full commit can't hop | ||
| 1985 | * in and cause problems either. | ||
| 1986 | */ | ||
| 1987 | write_ctree_super(trans, root->fs_info->tree_root, 2); | ||
| 1977 | 1988 | ||
| 1978 | write_ctree_super(trans, log->fs_info->tree_root, 2); | 1989 | atomic_set(&log_root_tree->log_commit[index2], 0); |
| 1979 | log->fs_info->tree_log_transid++; | ||
| 1980 | log->fs_info->tree_log_batch = 0; | ||
| 1981 | atomic_set(&log->fs_info->tree_log_commit, 0); | ||
| 1982 | smp_mb(); | 1990 | smp_mb(); |
| 1983 | if (waitqueue_active(&log->fs_info->tree_log_wait)) | 1991 | if (waitqueue_active(&log_root_tree->log_commit_wait[index2])) |
| 1984 | wake_up(&log->fs_info->tree_log_wait); | 1992 | wake_up(&log_root_tree->log_commit_wait[index2]); |
| 1985 | out: | 1993 | out: |
| 1986 | mutex_unlock(&log->fs_info->tree_log_mutex); | 1994 | atomic_set(&root->log_commit[index1], 0); |
| 1995 | smp_mb(); | ||
| 1996 | if (waitqueue_active(&root->log_commit_wait[index1])) | ||
| 1997 | wake_up(&root->log_commit_wait[index1]); | ||
| 1987 | return 0; | 1998 | return 0; |
| 1988 | } | 1999 | } |
| 1989 | 2000 | ||
| @@ -2019,38 +2030,18 @@ int btrfs_free_log(struct btrfs_trans_handle *trans, struct btrfs_root *root) | |||
| 2019 | start, end, GFP_NOFS); | 2030 | start, end, GFP_NOFS); |
| 2020 | } | 2031 | } |
| 2021 | 2032 | ||
| 2022 | log = root->log_root; | 2033 | if (log->log_transid > 0) { |
| 2023 | ret = btrfs_del_root(trans, root->fs_info->log_root_tree, | 2034 | ret = btrfs_del_root(trans, root->fs_info->log_root_tree, |
| 2024 | &log->root_key); | 2035 | &log->root_key); |
| 2025 | BUG_ON(ret); | 2036 | BUG_ON(ret); |
| 2037 | } | ||
| 2026 | root->log_root = NULL; | 2038 | root->log_root = NULL; |
| 2027 | kfree(root->log_root); | 2039 | free_extent_buffer(log->node); |
| 2040 | kfree(log); | ||
| 2028 | return 0; | 2041 | return 0; |
| 2029 | } | 2042 | } |
| 2030 | 2043 | ||
| 2031 | /* | 2044 | /* |
| 2032 | * helper function to update the item for a given subvolumes log root | ||
| 2033 | * in the tree of log roots | ||
| 2034 | */ | ||
| 2035 | static int update_log_root(struct btrfs_trans_handle *trans, | ||
| 2036 | struct btrfs_root *log) | ||
| 2037 | { | ||
| 2038 | u64 bytenr = btrfs_root_bytenr(&log->root_item); | ||
| 2039 | int ret; | ||
| 2040 | |||
| 2041 | if (log->node->start == bytenr) | ||
| 2042 | return 0; | ||
| 2043 | |||
| 2044 | btrfs_set_root_bytenr(&log->root_item, log->node->start); | ||
| 2045 | btrfs_set_root_generation(&log->root_item, trans->transid); | ||
| 2046 | btrfs_set_root_level(&log->root_item, btrfs_header_level(log->node)); | ||
| 2047 | ret = btrfs_update_root(trans, log->fs_info->log_root_tree, | ||
| 2048 | &log->root_key, &log->root_item); | ||
| 2049 | BUG_ON(ret); | ||
| 2050 | return ret; | ||
| 2051 | } | ||
| 2052 | |||
| 2053 | /* | ||
| 2054 | * If both a file and directory are logged, and unlinks or renames are | 2045 | * If both a file and directory are logged, and unlinks or renames are |
| 2055 | * mixed in, we have a few interesting corners: | 2046 | * mixed in, we have a few interesting corners: |
| 2056 | * | 2047 | * |
| @@ -2711,11 +2702,6 @@ next_slot: | |||
| 2711 | 2702 | ||
| 2712 | btrfs_free_path(path); | 2703 | btrfs_free_path(path); |
| 2713 | btrfs_free_path(dst_path); | 2704 | btrfs_free_path(dst_path); |
| 2714 | |||
| 2715 | mutex_lock(&root->fs_info->tree_log_mutex); | ||
| 2716 | ret = update_log_root(trans, log); | ||
| 2717 | BUG_ON(ret); | ||
| 2718 | mutex_unlock(&root->fs_info->tree_log_mutex); | ||
| 2719 | out: | 2705 | out: |
| 2720 | return 0; | 2706 | return 0; |
| 2721 | } | 2707 | } |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 3451e1cca2b5..bcd14ebccae1 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
| @@ -20,7 +20,6 @@ | |||
| 20 | #include <linux/buffer_head.h> | 20 | #include <linux/buffer_head.h> |
| 21 | #include <linux/blkdev.h> | 21 | #include <linux/blkdev.h> |
| 22 | #include <linux/random.h> | 22 | #include <linux/random.h> |
| 23 | #include <linux/version.h> | ||
| 24 | #include <asm/div64.h> | 23 | #include <asm/div64.h> |
| 25 | #include "compat.h" | 24 | #include "compat.h" |
| 26 | #include "ctree.h" | 25 | #include "ctree.h" |
| @@ -104,10 +103,8 @@ static noinline struct btrfs_device *__find_device(struct list_head *head, | |||
| 104 | u64 devid, u8 *uuid) | 103 | u64 devid, u8 *uuid) |
| 105 | { | 104 | { |
| 106 | struct btrfs_device *dev; | 105 | struct btrfs_device *dev; |
| 107 | struct list_head *cur; | ||
| 108 | 106 | ||
| 109 | list_for_each(cur, head) { | 107 | list_for_each_entry(dev, head, dev_list) { |
| 110 | dev = list_entry(cur, struct btrfs_device, dev_list); | ||
| 111 | if (dev->devid == devid && | 108 | if (dev->devid == devid && |
| 112 | (!uuid || !memcmp(dev->uuid, uuid, BTRFS_UUID_SIZE))) { | 109 | (!uuid || !memcmp(dev->uuid, uuid, BTRFS_UUID_SIZE))) { |
| 113 | return dev; | 110 | return dev; |
| @@ -118,11 +115,9 @@ static noinline struct btrfs_device *__find_device(struct list_head *head, | |||
| 118 | 115 | ||
| 119 | static noinline struct btrfs_fs_devices *find_fsid(u8 *fsid) | 116 | static noinline struct btrfs_fs_devices *find_fsid(u8 *fsid) |
| 120 | { | 117 | { |
| 121 | struct list_head *cur; | ||
| 122 | struct btrfs_fs_devices *fs_devices; | 118 | struct btrfs_fs_devices *fs_devices; |
| 123 | 119 | ||
| 124 | list_for_each(cur, &fs_uuids) { | 120 | list_for_each_entry(fs_devices, &fs_uuids, list) { |
| 125 | fs_devices = list_entry(cur, struct btrfs_fs_devices, list); | ||
| 126 | if (memcmp(fsid, fs_devices->fsid, BTRFS_FSID_SIZE) == 0) | 121 | if (memcmp(fsid, fs_devices->fsid, BTRFS_FSID_SIZE) == 0) |
| 127 | return fs_devices; | 122 | return fs_devices; |
| 128 | } | 123 | } |
| @@ -159,6 +154,7 @@ static noinline int run_scheduled_bios(struct btrfs_device *device) | |||
| 159 | loop: | 154 | loop: |
| 160 | spin_lock(&device->io_lock); | 155 | spin_lock(&device->io_lock); |
| 161 | 156 | ||
| 157 | loop_lock: | ||
| 162 | /* take all the bios off the list at once and process them | 158 | /* take all the bios off the list at once and process them |
| 163 | * later on (without the lock held). But, remember the | 159 | * later on (without the lock held). But, remember the |
| 164 | * tail and other pointers so the bios can be properly reinserted | 160 | * tail and other pointers so the bios can be properly reinserted |
| @@ -208,7 +204,7 @@ loop: | |||
| 208 | * is now congested. Back off and let other work structs | 204 | * is now congested. Back off and let other work structs |
| 209 | * run instead | 205 | * run instead |
| 210 | */ | 206 | */ |
| 211 | if (pending && bdi_write_congested(bdi) && | 207 | if (pending && bdi_write_congested(bdi) && num_run > 16 && |
| 212 | fs_info->fs_devices->open_devices > 1) { | 208 | fs_info->fs_devices->open_devices > 1) { |
| 213 | struct bio *old_head; | 209 | struct bio *old_head; |
| 214 | 210 | ||
| @@ -220,7 +216,8 @@ loop: | |||
| 220 | tail->bi_next = old_head; | 216 | tail->bi_next = old_head; |
| 221 | else | 217 | else |
| 222 | device->pending_bio_tail = tail; | 218 | device->pending_bio_tail = tail; |
| 223 | device->running_pending = 0; | 219 | |
| 220 | device->running_pending = 1; | ||
| 224 | 221 | ||
| 225 | spin_unlock(&device->io_lock); | 222 | spin_unlock(&device->io_lock); |
| 226 | btrfs_requeue_work(&device->work); | 223 | btrfs_requeue_work(&device->work); |
| @@ -229,6 +226,11 @@ loop: | |||
| 229 | } | 226 | } |
| 230 | if (again) | 227 | if (again) |
| 231 | goto loop; | 228 | goto loop; |
| 229 | |||
| 230 | spin_lock(&device->io_lock); | ||
| 231 | if (device->pending_bios) | ||
| 232 | goto loop_lock; | ||
| 233 | spin_unlock(&device->io_lock); | ||
| 232 | done: | 234 | done: |
| 233 | return 0; | 235 | return 0; |
| 234 | } | 236 | } |
| @@ -345,14 +347,11 @@ error: | |||
| 345 | 347 | ||
| 346 | int btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices) | 348 | int btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices) |
| 347 | { | 349 | { |
| 348 | struct list_head *tmp; | 350 | struct btrfs_device *device, *next; |
| 349 | struct list_head *cur; | ||
| 350 | struct btrfs_device *device; | ||
| 351 | 351 | ||
| 352 | mutex_lock(&uuid_mutex); | 352 | mutex_lock(&uuid_mutex); |
| 353 | again: | 353 | again: |
| 354 | list_for_each_safe(cur, tmp, &fs_devices->devices) { | 354 | list_for_each_entry_safe(device, next, &fs_devices->devices, dev_list) { |
| 355 | device = list_entry(cur, struct btrfs_device, dev_list); | ||
| 356 | if (device->in_fs_metadata) | 355 | if (device->in_fs_metadata) |
| 357 | continue; | 356 | continue; |
| 358 | 357 | ||
| @@ -383,14 +382,12 @@ again: | |||
| 383 | 382 | ||
| 384 | static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) | 383 | static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) |
| 385 | { | 384 | { |
| 386 | struct list_head *cur; | ||
| 387 | struct btrfs_device *device; | 385 | struct btrfs_device *device; |
| 388 | 386 | ||
| 389 | if (--fs_devices->opened > 0) | 387 | if (--fs_devices->opened > 0) |
| 390 | return 0; | 388 | return 0; |
| 391 | 389 | ||
| 392 | list_for_each(cur, &fs_devices->devices) { | 390 | list_for_each_entry(device, &fs_devices->devices, dev_list) { |
| 393 | device = list_entry(cur, struct btrfs_device, dev_list); | ||
| 394 | if (device->bdev) { | 391 | if (device->bdev) { |
| 395 | close_bdev_exclusive(device->bdev, device->mode); | 392 | close_bdev_exclusive(device->bdev, device->mode); |
| 396 | fs_devices->open_devices--; | 393 | fs_devices->open_devices--; |
| @@ -439,7 +436,6 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, | |||
| 439 | { | 436 | { |
| 440 | struct block_device *bdev; | 437 | struct block_device *bdev; |
| 441 | struct list_head *head = &fs_devices->devices; | 438 | struct list_head *head = &fs_devices->devices; |
| 442 | struct list_head *cur; | ||
| 443 | struct btrfs_device *device; | 439 | struct btrfs_device *device; |
| 444 | struct block_device *latest_bdev = NULL; | 440 | struct block_device *latest_bdev = NULL; |
| 445 | struct buffer_head *bh; | 441 | struct buffer_head *bh; |
| @@ -450,8 +446,7 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, | |||
| 450 | int seeding = 1; | 446 | int seeding = 1; |
| 451 | int ret = 0; | 447 | int ret = 0; |
| 452 | 448 | ||
| 453 | list_for_each(cur, head) { | 449 | list_for_each_entry(device, head, dev_list) { |
| 454 | device = list_entry(cur, struct btrfs_device, dev_list); | ||
| 455 | if (device->bdev) | 450 | if (device->bdev) |
| 456 | continue; | 451 | continue; |
| 457 | if (!device->name) | 452 | if (!device->name) |
| @@ -578,7 +573,7 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder, | |||
| 578 | *(unsigned long long *)disk_super->fsid, | 573 | *(unsigned long long *)disk_super->fsid, |
| 579 | *(unsigned long long *)(disk_super->fsid + 8)); | 574 | *(unsigned long long *)(disk_super->fsid + 8)); |
| 580 | } | 575 | } |
| 581 | printk(KERN_INFO "devid %llu transid %llu %s\n", | 576 | printk(KERN_CONT "devid %llu transid %llu %s\n", |
| 582 | (unsigned long long)devid, (unsigned long long)transid, path); | 577 | (unsigned long long)devid, (unsigned long long)transid, path); |
| 583 | ret = device_list_add(path, disk_super, devid, fs_devices_ret); | 578 | ret = device_list_add(path, disk_super, devid, fs_devices_ret); |
| 584 | 579 | ||
| @@ -1017,14 +1012,12 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) | |||
| 1017 | } | 1012 | } |
| 1018 | 1013 | ||
| 1019 | if (strcmp(device_path, "missing") == 0) { | 1014 | if (strcmp(device_path, "missing") == 0) { |
| 1020 | struct list_head *cur; | ||
| 1021 | struct list_head *devices; | 1015 | struct list_head *devices; |
| 1022 | struct btrfs_device *tmp; | 1016 | struct btrfs_device *tmp; |
| 1023 | 1017 | ||
| 1024 | device = NULL; | 1018 | device = NULL; |
| 1025 | devices = &root->fs_info->fs_devices->devices; | 1019 | devices = &root->fs_info->fs_devices->devices; |
| 1026 | list_for_each(cur, devices) { | 1020 | list_for_each_entry(tmp, devices, dev_list) { |
| 1027 | tmp = list_entry(cur, struct btrfs_device, dev_list); | ||
| 1028 | if (tmp->in_fs_metadata && !tmp->bdev) { | 1021 | if (tmp->in_fs_metadata && !tmp->bdev) { |
| 1029 | device = tmp; | 1022 | device = tmp; |
| 1030 | break; | 1023 | break; |
| @@ -1280,7 +1273,6 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
| 1280 | struct btrfs_trans_handle *trans; | 1273 | struct btrfs_trans_handle *trans; |
| 1281 | struct btrfs_device *device; | 1274 | struct btrfs_device *device; |
| 1282 | struct block_device *bdev; | 1275 | struct block_device *bdev; |
| 1283 | struct list_head *cur; | ||
| 1284 | struct list_head *devices; | 1276 | struct list_head *devices; |
| 1285 | struct super_block *sb = root->fs_info->sb; | 1277 | struct super_block *sb = root->fs_info->sb; |
| 1286 | u64 total_bytes; | 1278 | u64 total_bytes; |
| @@ -1304,8 +1296,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
| 1304 | mutex_lock(&root->fs_info->volume_mutex); | 1296 | mutex_lock(&root->fs_info->volume_mutex); |
| 1305 | 1297 | ||
| 1306 | devices = &root->fs_info->fs_devices->devices; | 1298 | devices = &root->fs_info->fs_devices->devices; |
| 1307 | list_for_each(cur, devices) { | 1299 | list_for_each_entry(device, devices, dev_list) { |
| 1308 | device = list_entry(cur, struct btrfs_device, dev_list); | ||
| 1309 | if (device->bdev == bdev) { | 1300 | if (device->bdev == bdev) { |
| 1310 | ret = -EEXIST; | 1301 | ret = -EEXIST; |
| 1311 | goto error; | 1302 | goto error; |
| @@ -1704,7 +1695,6 @@ static u64 div_factor(u64 num, int factor) | |||
| 1704 | int btrfs_balance(struct btrfs_root *dev_root) | 1695 | int btrfs_balance(struct btrfs_root *dev_root) |
| 1705 | { | 1696 | { |
| 1706 | int ret; | 1697 | int ret; |
| 1707 | struct list_head *cur; | ||
| 1708 | struct list_head *devices = &dev_root->fs_info->fs_devices->devices; | 1698 | struct list_head *devices = &dev_root->fs_info->fs_devices->devices; |
| 1709 | struct btrfs_device *device; | 1699 | struct btrfs_device *device; |
| 1710 | u64 old_size; | 1700 | u64 old_size; |
| @@ -1723,8 +1713,7 @@ int btrfs_balance(struct btrfs_root *dev_root) | |||
| 1723 | dev_root = dev_root->fs_info->dev_root; | 1713 | dev_root = dev_root->fs_info->dev_root; |
| 1724 | 1714 | ||
| 1725 | /* step one make some room on all the devices */ | 1715 | /* step one make some room on all the devices */ |
| 1726 | list_for_each(cur, devices) { | 1716 | list_for_each_entry(device, devices, dev_list) { |
| 1727 | device = list_entry(cur, struct btrfs_device, dev_list); | ||
| 1728 | old_size = device->total_bytes; | 1717 | old_size = device->total_bytes; |
| 1729 | size_to_free = div_factor(old_size, 1); | 1718 | size_to_free = div_factor(old_size, 1); |
| 1730 | size_to_free = min(size_to_free, (u64)1 * 1024 * 1024); | 1719 | size_to_free = min(size_to_free, (u64)1 * 1024 * 1024); |
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c index 7f332e270894..a9d3bf4d2689 100644 --- a/fs/btrfs/xattr.c +++ b/fs/btrfs/xattr.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
| 22 | #include <linux/rwsem.h> | 22 | #include <linux/rwsem.h> |
| 23 | #include <linux/xattr.h> | 23 | #include <linux/xattr.h> |
| 24 | #include <linux/security.h> | ||
| 24 | #include "ctree.h" | 25 | #include "ctree.h" |
| 25 | #include "btrfs_inode.h" | 26 | #include "btrfs_inode.h" |
| 26 | #include "transaction.h" | 27 | #include "transaction.h" |
| @@ -45,9 +46,12 @@ ssize_t __btrfs_getxattr(struct inode *inode, const char *name, | |||
| 45 | /* lookup the xattr by name */ | 46 | /* lookup the xattr by name */ |
| 46 | di = btrfs_lookup_xattr(NULL, root, path, inode->i_ino, name, | 47 | di = btrfs_lookup_xattr(NULL, root, path, inode->i_ino, name, |
| 47 | strlen(name), 0); | 48 | strlen(name), 0); |
| 48 | if (!di || IS_ERR(di)) { | 49 | if (!di) { |
| 49 | ret = -ENODATA; | 50 | ret = -ENODATA; |
| 50 | goto out; | 51 | goto out; |
| 52 | } else if (IS_ERR(di)) { | ||
| 53 | ret = PTR_ERR(di); | ||
| 54 | goto out; | ||
| 51 | } | 55 | } |
| 52 | 56 | ||
| 53 | leaf = path->nodes[0]; | 57 | leaf = path->nodes[0]; |
| @@ -62,6 +66,14 @@ ssize_t __btrfs_getxattr(struct inode *inode, const char *name, | |||
| 62 | ret = -ERANGE; | 66 | ret = -ERANGE; |
| 63 | goto out; | 67 | goto out; |
| 64 | } | 68 | } |
| 69 | |||
| 70 | /* | ||
| 71 | * The way things are packed into the leaf is like this | ||
| 72 | * |struct btrfs_dir_item|name|data| | ||
| 73 | * where name is the xattr name, so security.foo, and data is the | ||
| 74 | * content of the xattr. data_ptr points to the location in memory | ||
| 75 | * where the data starts in the in memory leaf | ||
| 76 | */ | ||
| 65 | data_ptr = (unsigned long)((char *)(di + 1) + | 77 | data_ptr = (unsigned long)((char *)(di + 1) + |
| 66 | btrfs_dir_name_len(leaf, di)); | 78 | btrfs_dir_name_len(leaf, di)); |
| 67 | read_extent_buffer(leaf, buffer, data_ptr, | 79 | read_extent_buffer(leaf, buffer, data_ptr, |
| @@ -86,7 +98,7 @@ int __btrfs_setxattr(struct inode *inode, const char *name, | |||
| 86 | if (!path) | 98 | if (!path) |
| 87 | return -ENOMEM; | 99 | return -ENOMEM; |
| 88 | 100 | ||
| 89 | trans = btrfs_start_transaction(root, 1); | 101 | trans = btrfs_join_transaction(root, 1); |
| 90 | btrfs_set_trans_block_group(trans, inode); | 102 | btrfs_set_trans_block_group(trans, inode); |
| 91 | 103 | ||
| 92 | /* first lets see if we already have this xattr */ | 104 | /* first lets see if we already have this xattr */ |
| @@ -176,7 +188,6 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
| 176 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 188 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
| 177 | if (ret < 0) | 189 | if (ret < 0) |
| 178 | goto err; | 190 | goto err; |
| 179 | ret = 0; | ||
| 180 | advance = 0; | 191 | advance = 0; |
| 181 | while (1) { | 192 | while (1) { |
| 182 | leaf = path->nodes[0]; | 193 | leaf = path->nodes[0]; |
| @@ -320,3 +331,34 @@ int btrfs_removexattr(struct dentry *dentry, const char *name) | |||
| 320 | return -EOPNOTSUPP; | 331 | return -EOPNOTSUPP; |
| 321 | return __btrfs_setxattr(dentry->d_inode, name, NULL, 0, XATTR_REPLACE); | 332 | return __btrfs_setxattr(dentry->d_inode, name, NULL, 0, XATTR_REPLACE); |
| 322 | } | 333 | } |
| 334 | |||
| 335 | int btrfs_xattr_security_init(struct inode *inode, struct inode *dir) | ||
| 336 | { | ||
| 337 | int err; | ||
| 338 | size_t len; | ||
| 339 | void *value; | ||
| 340 | char *suffix; | ||
| 341 | char *name; | ||
| 342 | |||
| 343 | err = security_inode_init_security(inode, dir, &suffix, &value, &len); | ||
| 344 | if (err) { | ||
| 345 | if (err == -EOPNOTSUPP) | ||
| 346 | return 0; | ||
| 347 | return err; | ||
| 348 | } | ||
| 349 | |||
| 350 | name = kmalloc(XATTR_SECURITY_PREFIX_LEN + strlen(suffix) + 1, | ||
| 351 | GFP_NOFS); | ||
| 352 | if (!name) { | ||
| 353 | err = -ENOMEM; | ||
| 354 | } else { | ||
| 355 | strcpy(name, XATTR_SECURITY_PREFIX); | ||
| 356 | strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix); | ||
| 357 | err = __btrfs_setxattr(inode, name, value, len, 0); | ||
| 358 | kfree(name); | ||
| 359 | } | ||
| 360 | |||
| 361 | kfree(suffix); | ||
| 362 | kfree(value); | ||
| 363 | return err; | ||
| 364 | } | ||
diff --git a/fs/btrfs/xattr.h b/fs/btrfs/xattr.h index 5b1d08f8e68d..c71e9c3cf3f7 100644 --- a/fs/btrfs/xattr.h +++ b/fs/btrfs/xattr.h | |||
| @@ -36,4 +36,6 @@ extern int btrfs_setxattr(struct dentry *dentry, const char *name, | |||
| 36 | const void *value, size_t size, int flags); | 36 | const void *value, size_t size, int flags); |
| 37 | extern int btrfs_removexattr(struct dentry *dentry, const char *name); | 37 | extern int btrfs_removexattr(struct dentry *dentry, const char *name); |
| 38 | 38 | ||
| 39 | extern int btrfs_xattr_security_init(struct inode *inode, struct inode *dir); | ||
| 40 | |||
| 39 | #endif /* __XATTR__ */ | 41 | #endif /* __XATTR__ */ |
diff --git a/fs/buffer.c b/fs/buffer.c index b58208f1640a..665d446b25bc 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
| @@ -2688,7 +2688,7 @@ int nobh_write_end(struct file *file, struct address_space *mapping, | |||
| 2688 | struct buffer_head *bh; | 2688 | struct buffer_head *bh; |
| 2689 | BUG_ON(fsdata != NULL && page_has_buffers(page)); | 2689 | BUG_ON(fsdata != NULL && page_has_buffers(page)); |
| 2690 | 2690 | ||
| 2691 | if (unlikely(copied < len) && !page_has_buffers(page)) | 2691 | if (unlikely(copied < len) && head) |
| 2692 | attach_nobh_buffers(page, head); | 2692 | attach_nobh_buffers(page, head); |
| 2693 | if (page_has_buffers(page)) | 2693 | if (page_has_buffers(page)) |
| 2694 | return generic_write_end(file, mapping, pos, len, | 2694 | return generic_write_end(file, mapping, pos, len, |
diff --git a/fs/compat.c b/fs/compat.c index 65a070e705ab..d0145ca27572 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
| @@ -1407,7 +1407,7 @@ int compat_do_execve(char * filename, | |||
| 1407 | bprm->cred = prepare_exec_creds(); | 1407 | bprm->cred = prepare_exec_creds(); |
| 1408 | if (!bprm->cred) | 1408 | if (!bprm->cred) |
| 1409 | goto out_unlock; | 1409 | goto out_unlock; |
| 1410 | check_unsafe_exec(bprm); | 1410 | check_unsafe_exec(bprm, current->files); |
| 1411 | 1411 | ||
| 1412 | file = open_exec(filename); | 1412 | file = open_exec(filename); |
| 1413 | retval = PTR_ERR(file); | 1413 | retval = PTR_ERR(file); |
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index c8f8d5904f5e..9c6d815dd191 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
| @@ -785,7 +785,7 @@ static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) | |||
| 785 | 785 | ||
| 786 | if (copy_in_user(&sgio->status, &sgio32->status, | 786 | if (copy_in_user(&sgio->status, &sgio32->status, |
| 787 | (4 * sizeof(unsigned char)) + | 787 | (4 * sizeof(unsigned char)) + |
| 788 | (2 * sizeof(unsigned (short))) + | 788 | (2 * sizeof(unsigned short)) + |
| 789 | (3 * sizeof(int)))) | 789 | (3 * sizeof(int)))) |
| 790 | return -EFAULT; | 790 | return -EFAULT; |
| 791 | 791 | ||
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 9c2358391147..8e93341f3e82 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c | |||
| @@ -553,24 +553,12 @@ static void detach_groups(struct config_group *group) | |||
| 553 | 553 | ||
| 554 | child = sd->s_dentry; | 554 | child = sd->s_dentry; |
| 555 | 555 | ||
| 556 | /* | ||
| 557 | * Note: we hide this from lockdep since we have no way | ||
| 558 | * to teach lockdep about recursive | ||
| 559 | * I_MUTEX_PARENT -> I_MUTEX_CHILD patterns along a path | ||
| 560 | * in an inode tree, which are valid as soon as | ||
| 561 | * I_MUTEX_PARENT -> I_MUTEX_CHILD is valid from a | ||
| 562 | * parent inode to one of its children. | ||
| 563 | */ | ||
| 564 | lockdep_off(); | ||
| 565 | mutex_lock(&child->d_inode->i_mutex); | 556 | mutex_lock(&child->d_inode->i_mutex); |
| 566 | lockdep_on(); | ||
| 567 | 557 | ||
| 568 | configfs_detach_group(sd->s_element); | 558 | configfs_detach_group(sd->s_element); |
| 569 | child->d_inode->i_flags |= S_DEAD; | 559 | child->d_inode->i_flags |= S_DEAD; |
| 570 | 560 | ||
| 571 | lockdep_off(); | ||
| 572 | mutex_unlock(&child->d_inode->i_mutex); | 561 | mutex_unlock(&child->d_inode->i_mutex); |
| 573 | lockdep_on(); | ||
| 574 | 562 | ||
| 575 | d_delete(child); | 563 | d_delete(child); |
| 576 | dput(child); | 564 | dput(child); |
| @@ -760,22 +748,11 @@ static int configfs_attach_item(struct config_item *parent_item, | |||
| 760 | * We are going to remove an inode and its dentry but | 748 | * We are going to remove an inode and its dentry but |
| 761 | * the VFS may already have hit and used them. Thus, | 749 | * the VFS may already have hit and used them. Thus, |
| 762 | * we must lock them as rmdir() would. | 750 | * we must lock them as rmdir() would. |
| 763 | * | ||
| 764 | * Note: we hide this from lockdep since we have no way | ||
| 765 | * to teach lockdep about recursive | ||
| 766 | * I_MUTEX_PARENT -> I_MUTEX_CHILD patterns along a path | ||
| 767 | * in an inode tree, which are valid as soon as | ||
| 768 | * I_MUTEX_PARENT -> I_MUTEX_CHILD is valid from a | ||
| 769 | * parent inode to one of its children. | ||
| 770 | */ | 751 | */ |
| 771 | lockdep_off(); | ||
| 772 | mutex_lock(&dentry->d_inode->i_mutex); | 752 | mutex_lock(&dentry->d_inode->i_mutex); |
| 773 | lockdep_on(); | ||
| 774 | configfs_remove_dir(item); | 753 | configfs_remove_dir(item); |
| 775 | dentry->d_inode->i_flags |= S_DEAD; | 754 | dentry->d_inode->i_flags |= S_DEAD; |
| 776 | lockdep_off(); | ||
| 777 | mutex_unlock(&dentry->d_inode->i_mutex); | 755 | mutex_unlock(&dentry->d_inode->i_mutex); |
| 778 | lockdep_on(); | ||
| 779 | d_delete(dentry); | 756 | d_delete(dentry); |
| 780 | } | 757 | } |
| 781 | } | 758 | } |
| @@ -810,25 +787,14 @@ static int configfs_attach_group(struct config_item *parent_item, | |||
| 810 | * | 787 | * |
| 811 | * We must also lock the inode to remove it safely in case of | 788 | * We must also lock the inode to remove it safely in case of |
| 812 | * error, as rmdir() would. | 789 | * error, as rmdir() would. |
| 813 | * | ||
| 814 | * Note: we hide this from lockdep since we have no way | ||
| 815 | * to teach lockdep about recursive | ||
| 816 | * I_MUTEX_PARENT -> I_MUTEX_CHILD patterns along a path | ||
| 817 | * in an inode tree, which are valid as soon as | ||
| 818 | * I_MUTEX_PARENT -> I_MUTEX_CHILD is valid from a | ||
| 819 | * parent inode to one of its children. | ||
| 820 | */ | 790 | */ |
| 821 | lockdep_off(); | ||
| 822 | mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); | 791 | mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); |
| 823 | lockdep_on(); | ||
| 824 | ret = populate_groups(to_config_group(item)); | 792 | ret = populate_groups(to_config_group(item)); |
| 825 | if (ret) { | 793 | if (ret) { |
| 826 | configfs_detach_item(item); | 794 | configfs_detach_item(item); |
| 827 | dentry->d_inode->i_flags |= S_DEAD; | 795 | dentry->d_inode->i_flags |= S_DEAD; |
| 828 | } | 796 | } |
| 829 | lockdep_off(); | ||
| 830 | mutex_unlock(&dentry->d_inode->i_mutex); | 797 | mutex_unlock(&dentry->d_inode->i_mutex); |
| 831 | lockdep_on(); | ||
| 832 | if (ret) | 798 | if (ret) |
| 833 | d_delete(dentry); | 799 | d_delete(dentry); |
| 834 | } | 800 | } |
| @@ -990,17 +956,7 @@ static int configfs_depend_prep(struct dentry *origin, | |||
| 990 | BUG_ON(!origin || !sd); | 956 | BUG_ON(!origin || !sd); |
| 991 | 957 | ||
| 992 | /* Lock this guy on the way down */ | 958 | /* Lock this guy on the way down */ |
| 993 | /* | ||
| 994 | * Note: we hide this from lockdep since we have no way | ||
| 995 | * to teach lockdep about recursive | ||
| 996 | * I_MUTEX_PARENT -> I_MUTEX_CHILD patterns along a path | ||
| 997 | * in an inode tree, which are valid as soon as | ||
| 998 | * I_MUTEX_PARENT -> I_MUTEX_CHILD is valid from a | ||
| 999 | * parent inode to one of its children. | ||
| 1000 | */ | ||
| 1001 | lockdep_off(); | ||
| 1002 | mutex_lock(&sd->s_dentry->d_inode->i_mutex); | 959 | mutex_lock(&sd->s_dentry->d_inode->i_mutex); |
| 1003 | lockdep_on(); | ||
| 1004 | if (sd->s_element == target) /* Boo-yah */ | 960 | if (sd->s_element == target) /* Boo-yah */ |
| 1005 | goto out; | 961 | goto out; |
| 1006 | 962 | ||
| @@ -1014,9 +970,7 @@ static int configfs_depend_prep(struct dentry *origin, | |||
| 1014 | } | 970 | } |
| 1015 | 971 | ||
| 1016 | /* We looped all our children and didn't find target */ | 972 | /* We looped all our children and didn't find target */ |
| 1017 | lockdep_off(); | ||
| 1018 | mutex_unlock(&sd->s_dentry->d_inode->i_mutex); | 973 | mutex_unlock(&sd->s_dentry->d_inode->i_mutex); |
| 1019 | lockdep_on(); | ||
| 1020 | ret = -ENOENT; | 974 | ret = -ENOENT; |
| 1021 | 975 | ||
| 1022 | out: | 976 | out: |
| @@ -1036,16 +990,11 @@ static void configfs_depend_rollback(struct dentry *origin, | |||
| 1036 | struct dentry *dentry = item->ci_dentry; | 990 | struct dentry *dentry = item->ci_dentry; |
| 1037 | 991 | ||
| 1038 | while (dentry != origin) { | 992 | while (dentry != origin) { |
| 1039 | /* See comments in configfs_depend_prep() */ | ||
| 1040 | lockdep_off(); | ||
| 1041 | mutex_unlock(&dentry->d_inode->i_mutex); | 993 | mutex_unlock(&dentry->d_inode->i_mutex); |
| 1042 | lockdep_on(); | ||
| 1043 | dentry = dentry->d_parent; | 994 | dentry = dentry->d_parent; |
| 1044 | } | 995 | } |
| 1045 | 996 | ||
| 1046 | lockdep_off(); | ||
| 1047 | mutex_unlock(&origin->d_inode->i_mutex); | 997 | mutex_unlock(&origin->d_inode->i_mutex); |
| 1048 | lockdep_on(); | ||
| 1049 | } | 998 | } |
| 1050 | 999 | ||
| 1051 | int configfs_depend_item(struct configfs_subsystem *subsys, | 1000 | int configfs_depend_item(struct configfs_subsystem *subsys, |
| @@ -1380,16 +1329,8 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 1380 | } | 1329 | } |
| 1381 | 1330 | ||
| 1382 | /* Wait until the racing operation terminates */ | 1331 | /* Wait until the racing operation terminates */ |
| 1383 | /* | ||
| 1384 | * Note: we hide this from lockdep since we are locked | ||
| 1385 | * with subclass I_MUTEX_NORMAL from vfs_rmdir() (why | ||
| 1386 | * not I_MUTEX_CHILD?), and I_MUTEX_XATTR or | ||
| 1387 | * I_MUTEX_QUOTA are not relevant for the locked inode. | ||
| 1388 | */ | ||
| 1389 | lockdep_off(); | ||
| 1390 | mutex_lock(wait_mutex); | 1332 | mutex_lock(wait_mutex); |
| 1391 | mutex_unlock(wait_mutex); | 1333 | mutex_unlock(wait_mutex); |
| 1392 | lockdep_on(); | ||
| 1393 | } | 1334 | } |
| 1394 | } while (ret == -EAGAIN); | 1335 | } while (ret == -EAGAIN); |
| 1395 | 1336 | ||
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index c01e043670e2..f6caeb1d1106 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
| @@ -1716,7 +1716,7 @@ static int ecryptfs_copy_filename(char **copied_name, size_t *copied_name_size, | |||
| 1716 | { | 1716 | { |
| 1717 | int rc = 0; | 1717 | int rc = 0; |
| 1718 | 1718 | ||
| 1719 | (*copied_name) = kmalloc((name_size + 2), GFP_KERNEL); | 1719 | (*copied_name) = kmalloc((name_size + 1), GFP_KERNEL); |
| 1720 | if (!(*copied_name)) { | 1720 | if (!(*copied_name)) { |
| 1721 | rc = -ENOMEM; | 1721 | rc = -ENOMEM; |
| 1722 | goto out; | 1722 | goto out; |
| @@ -1726,7 +1726,7 @@ static int ecryptfs_copy_filename(char **copied_name, size_t *copied_name_size, | |||
| 1726 | * in printing out the | 1726 | * in printing out the |
| 1727 | * string in debug | 1727 | * string in debug |
| 1728 | * messages */ | 1728 | * messages */ |
| 1729 | (*copied_name_size) = (name_size + 1); | 1729 | (*copied_name_size) = name_size; |
| 1730 | out: | 1730 | out: |
| 1731 | return rc; | 1731 | return rc; |
| 1732 | } | 1732 | } |
| @@ -1049,16 +1049,32 @@ EXPORT_SYMBOL(install_exec_creds); | |||
| 1049 | * - the caller must hold current->cred_exec_mutex to protect against | 1049 | * - the caller must hold current->cred_exec_mutex to protect against |
| 1050 | * PTRACE_ATTACH | 1050 | * PTRACE_ATTACH |
| 1051 | */ | 1051 | */ |
| 1052 | void check_unsafe_exec(struct linux_binprm *bprm) | 1052 | void check_unsafe_exec(struct linux_binprm *bprm, struct files_struct *files) |
| 1053 | { | 1053 | { |
| 1054 | struct task_struct *p = current; | 1054 | struct task_struct *p = current, *t; |
| 1055 | unsigned long flags; | ||
| 1056 | unsigned n_fs, n_files, n_sighand; | ||
| 1055 | 1057 | ||
| 1056 | bprm->unsafe = tracehook_unsafe_exec(p); | 1058 | bprm->unsafe = tracehook_unsafe_exec(p); |
| 1057 | 1059 | ||
| 1058 | if (atomic_read(&p->fs->count) > 1 || | 1060 | n_fs = 1; |
| 1059 | atomic_read(&p->files->count) > 1 || | 1061 | n_files = 1; |
| 1060 | atomic_read(&p->sighand->count) > 1) | 1062 | n_sighand = 1; |
| 1063 | lock_task_sighand(p, &flags); | ||
| 1064 | for (t = next_thread(p); t != p; t = next_thread(t)) { | ||
| 1065 | if (t->fs == p->fs) | ||
| 1066 | n_fs++; | ||
| 1067 | if (t->files == files) | ||
| 1068 | n_files++; | ||
| 1069 | n_sighand++; | ||
| 1070 | } | ||
| 1071 | |||
| 1072 | if (atomic_read(&p->fs->count) > n_fs || | ||
| 1073 | atomic_read(&p->files->count) > n_files || | ||
| 1074 | atomic_read(&p->sighand->count) > n_sighand) | ||
| 1061 | bprm->unsafe |= LSM_UNSAFE_SHARE; | 1075 | bprm->unsafe |= LSM_UNSAFE_SHARE; |
| 1076 | |||
| 1077 | unlock_task_sighand(p, &flags); | ||
| 1062 | } | 1078 | } |
| 1063 | 1079 | ||
| 1064 | /* | 1080 | /* |
| @@ -1273,7 +1289,7 @@ int do_execve(char * filename, | |||
| 1273 | bprm->cred = prepare_exec_creds(); | 1289 | bprm->cred = prepare_exec_creds(); |
| 1274 | if (!bprm->cred) | 1290 | if (!bprm->cred) |
| 1275 | goto out_unlock; | 1291 | goto out_unlock; |
| 1276 | check_unsafe_exec(bprm); | 1292 | check_unsafe_exec(bprm, displaced); |
| 1277 | 1293 | ||
| 1278 | file = open_exec(filename); | 1294 | file = open_exec(filename); |
| 1279 | retval = PTR_ERR(file); | 1295 | retval = PTR_ERR(file); |
diff --git a/fs/internal.h b/fs/internal.h index 53af885f1732..0d8ac497b3d5 100644 --- a/fs/internal.h +++ b/fs/internal.h | |||
| @@ -43,7 +43,7 @@ extern void __init chrdev_init(void); | |||
| 43 | /* | 43 | /* |
| 44 | * exec.c | 44 | * exec.c |
| 45 | */ | 45 | */ |
| 46 | extern void check_unsafe_exec(struct linux_binprm *); | 46 | extern void check_unsafe_exec(struct linux_binprm *, struct files_struct *); |
| 47 | 47 | ||
| 48 | /* | 48 | /* |
| 49 | * namespace.c | 49 | * namespace.c |
diff --git a/fs/seq_file.c b/fs/seq_file.c index b569ff1c4dc8..5267098532bf 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c | |||
| @@ -54,6 +54,64 @@ int seq_open(struct file *file, const struct seq_operations *op) | |||
| 54 | } | 54 | } |
| 55 | EXPORT_SYMBOL(seq_open); | 55 | EXPORT_SYMBOL(seq_open); |
| 56 | 56 | ||
| 57 | static int traverse(struct seq_file *m, loff_t offset) | ||
| 58 | { | ||
| 59 | loff_t pos = 0, index; | ||
| 60 | int error = 0; | ||
| 61 | void *p; | ||
| 62 | |||
| 63 | m->version = 0; | ||
| 64 | index = 0; | ||
| 65 | m->count = m->from = 0; | ||
| 66 | if (!offset) { | ||
| 67 | m->index = index; | ||
| 68 | return 0; | ||
| 69 | } | ||
| 70 | if (!m->buf) { | ||
| 71 | m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL); | ||
| 72 | if (!m->buf) | ||
| 73 | return -ENOMEM; | ||
| 74 | } | ||
| 75 | p = m->op->start(m, &index); | ||
| 76 | while (p) { | ||
| 77 | error = PTR_ERR(p); | ||
| 78 | if (IS_ERR(p)) | ||
| 79 | break; | ||
| 80 | error = m->op->show(m, p); | ||
| 81 | if (error < 0) | ||
| 82 | break; | ||
| 83 | if (unlikely(error)) { | ||
| 84 | error = 0; | ||
| 85 | m->count = 0; | ||
| 86 | } | ||
| 87 | if (m->count == m->size) | ||
| 88 | goto Eoverflow; | ||
| 89 | if (pos + m->count > offset) { | ||
| 90 | m->from = offset - pos; | ||
| 91 | m->count -= m->from; | ||
| 92 | m->index = index; | ||
| 93 | break; | ||
| 94 | } | ||
| 95 | pos += m->count; | ||
| 96 | m->count = 0; | ||
| 97 | if (pos == offset) { | ||
| 98 | index++; | ||
| 99 | m->index = index; | ||
| 100 | break; | ||
| 101 | } | ||
| 102 | p = m->op->next(m, p, &index); | ||
| 103 | } | ||
| 104 | m->op->stop(m, p); | ||
| 105 | m->index = index; | ||
| 106 | return error; | ||
| 107 | |||
| 108 | Eoverflow: | ||
| 109 | m->op->stop(m, p); | ||
| 110 | kfree(m->buf); | ||
| 111 | m->buf = kmalloc(m->size <<= 1, GFP_KERNEL); | ||
| 112 | return !m->buf ? -ENOMEM : -EAGAIN; | ||
| 113 | } | ||
| 114 | |||
| 57 | /** | 115 | /** |
| 58 | * seq_read - ->read() method for sequential files. | 116 | * seq_read - ->read() method for sequential files. |
| 59 | * @file: the file to read from | 117 | * @file: the file to read from |
| @@ -186,63 +244,6 @@ Efault: | |||
| 186 | } | 244 | } |
| 187 | EXPORT_SYMBOL(seq_read); | 245 | EXPORT_SYMBOL(seq_read); |
| 188 | 246 | ||
| 189 | static int traverse(struct seq_file *m, loff_t offset) | ||
| 190 | { | ||
| 191 | loff_t pos = 0, index; | ||
| 192 | int error = 0; | ||
| 193 | void *p; | ||
| 194 | |||
| 195 | m->version = 0; | ||
| 196 | index = 0; | ||
| 197 | m->count = m->from = 0; | ||
| 198 | if (!offset) { | ||
| 199 | m->index = index; | ||
| 200 | return 0; | ||
| 201 | } | ||
| 202 | if (!m->buf) { | ||
| 203 | m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL); | ||
| 204 | if (!m->buf) | ||
| 205 | return -ENOMEM; | ||
| 206 | } | ||
| 207 | p = m->op->start(m, &index); | ||
| 208 | while (p) { | ||
| 209 | error = PTR_ERR(p); | ||
| 210 | if (IS_ERR(p)) | ||
| 211 | break; | ||
| 212 | error = m->op->show(m, p); | ||
| 213 | if (error < 0) | ||
| 214 | break; | ||
| 215 | if (unlikely(error)) { | ||
| 216 | error = 0; | ||
| 217 | m->count = 0; | ||
| 218 | } | ||
| 219 | if (m->count == m->size) | ||
| 220 | goto Eoverflow; | ||
| 221 | if (pos + m->count > offset) { | ||
| 222 | m->from = offset - pos; | ||
| 223 | m->count -= m->from; | ||
| 224 | m->index = index; | ||
| 225 | break; | ||
| 226 | } | ||
| 227 | pos += m->count; | ||
| 228 | m->count = 0; | ||
| 229 | if (pos == offset) { | ||
| 230 | index++; | ||
| 231 | m->index = index; | ||
| 232 | break; | ||
| 233 | } | ||
| 234 | p = m->op->next(m, p, &index); | ||
| 235 | } | ||
| 236 | m->op->stop(m, p); | ||
| 237 | return error; | ||
| 238 | |||
| 239 | Eoverflow: | ||
| 240 | m->op->stop(m, p); | ||
| 241 | kfree(m->buf); | ||
| 242 | m->buf = kmalloc(m->size <<= 1, GFP_KERNEL); | ||
| 243 | return !m->buf ? -ENOMEM : -EAGAIN; | ||
| 244 | } | ||
| 245 | |||
| 246 | /** | 247 | /** |
| 247 | * seq_lseek - ->llseek() method for sequential files. | 248 | * seq_lseek - ->llseek() method for sequential files. |
| 248 | * @file: the file in question | 249 | * @file: the file in question |
diff --git a/fs/super.c b/fs/super.c index 645e5403f2a0..61dce001dd57 100644 --- a/fs/super.c +++ b/fs/super.c | |||
| @@ -301,7 +301,7 @@ void generic_shutdown_super(struct super_block *sb) | |||
| 301 | /* | 301 | /* |
| 302 | * wait for asynchronous fs operations to finish before going further | 302 | * wait for asynchronous fs operations to finish before going further |
| 303 | */ | 303 | */ |
| 304 | async_synchronize_full_special(&sb->s_async_list); | 304 | async_synchronize_full_domain(&sb->s_async_list); |
| 305 | 305 | ||
| 306 | /* bad name - it should be evict_inodes() */ | 306 | /* bad name - it should be evict_inodes() */ |
| 307 | invalidate_inodes(sb); | 307 | invalidate_inodes(sb); |
| @@ -470,7 +470,7 @@ restart: | |||
| 470 | sb->s_count++; | 470 | sb->s_count++; |
| 471 | spin_unlock(&sb_lock); | 471 | spin_unlock(&sb_lock); |
| 472 | down_read(&sb->s_umount); | 472 | down_read(&sb->s_umount); |
| 473 | async_synchronize_full_special(&sb->s_async_list); | 473 | async_synchronize_full_domain(&sb->s_async_list); |
| 474 | if (sb->s_root && (wait || sb->s_dirt)) | 474 | if (sb->s_root && (wait || sb->s_dirt)) |
| 475 | sb->s_op->sync_fs(sb, wait); | 475 | sb->s_op->sync_fs(sb, wait); |
| 476 | up_read(&sb->s_umount); | 476 | up_read(&sb->s_umount); |
diff --git a/include/acpi/pdc_intel.h b/include/acpi/pdc_intel.h index e72bfdd887f9..552637b0d051 100644 --- a/include/acpi/pdc_intel.h +++ b/include/acpi/pdc_intel.h | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #define ACPI_PDC_SMP_T_SWCOORD (0x0080) | 14 | #define ACPI_PDC_SMP_T_SWCOORD (0x0080) |
| 15 | #define ACPI_PDC_C_C1_FFH (0x0100) | 15 | #define ACPI_PDC_C_C1_FFH (0x0100) |
| 16 | #define ACPI_PDC_C_C2C3_FFH (0x0200) | 16 | #define ACPI_PDC_C_C2C3_FFH (0x0200) |
| 17 | #define ACPI_PDC_SMP_P_HWCOORD (0x0800) | ||
| 17 | 18 | ||
| 18 | #define ACPI_PDC_EST_CAPABILITY_SMP (ACPI_PDC_SMP_C1PT | \ | 19 | #define ACPI_PDC_EST_CAPABILITY_SMP (ACPI_PDC_SMP_C1PT | \ |
| 19 | ACPI_PDC_C_C1_HALT | \ | 20 | ACPI_PDC_C_C1_HALT | \ |
| @@ -22,6 +23,7 @@ | |||
| 22 | #define ACPI_PDC_EST_CAPABILITY_SWSMP (ACPI_PDC_SMP_C1PT | \ | 23 | #define ACPI_PDC_EST_CAPABILITY_SWSMP (ACPI_PDC_SMP_C1PT | \ |
| 23 | ACPI_PDC_C_C1_HALT | \ | 24 | ACPI_PDC_C_C1_HALT | \ |
| 24 | ACPI_PDC_SMP_P_SWCOORD | \ | 25 | ACPI_PDC_SMP_P_SWCOORD | \ |
| 26 | ACPI_PDC_SMP_P_HWCOORD | \ | ||
| 25 | ACPI_PDC_P_FFH) | 27 | ACPI_PDC_P_FFH) |
| 26 | 28 | ||
| 27 | #define ACPI_PDC_C_CAPABILITY_SMP (ACPI_PDC_SMP_C2C3 | \ | 29 | #define ACPI_PDC_C_CAPABILITY_SMP (ACPI_PDC_SMP_C2C3 | \ |
diff --git a/include/linux/async.h b/include/linux/async.h index c4ecacd0b327..68a9530196f2 100644 --- a/include/linux/async.h +++ b/include/linux/async.h | |||
| @@ -17,9 +17,11 @@ typedef u64 async_cookie_t; | |||
| 17 | typedef void (async_func_ptr) (void *data, async_cookie_t cookie); | 17 | typedef void (async_func_ptr) (void *data, async_cookie_t cookie); |
| 18 | 18 | ||
| 19 | extern async_cookie_t async_schedule(async_func_ptr *ptr, void *data); | 19 | extern async_cookie_t async_schedule(async_func_ptr *ptr, void *data); |
| 20 | extern async_cookie_t async_schedule_special(async_func_ptr *ptr, void *data, struct list_head *list); | 20 | extern async_cookie_t async_schedule_domain(async_func_ptr *ptr, void *data, |
| 21 | struct list_head *list); | ||
| 21 | extern void async_synchronize_full(void); | 22 | extern void async_synchronize_full(void); |
| 22 | extern void async_synchronize_full_special(struct list_head *list); | 23 | extern void async_synchronize_full_domain(struct list_head *list); |
| 23 | extern void async_synchronize_cookie(async_cookie_t cookie); | 24 | extern void async_synchronize_cookie(async_cookie_t cookie); |
| 24 | extern void async_synchronize_cookie_special(async_cookie_t cookie, struct list_head *list); | 25 | extern void async_synchronize_cookie_domain(async_cookie_t cookie, |
| 26 | struct list_head *list); | ||
| 25 | 27 | ||
diff --git a/include/linux/fb.h b/include/linux/fb.h index 818fe21257e8..31527e17076b 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h | |||
| @@ -960,6 +960,21 @@ extern struct fb_info *registered_fb[FB_MAX]; | |||
| 960 | extern int num_registered_fb; | 960 | extern int num_registered_fb; |
| 961 | extern struct class *fb_class; | 961 | extern struct class *fb_class; |
| 962 | 962 | ||
| 963 | static inline int lock_fb_info(struct fb_info *info) | ||
| 964 | { | ||
| 965 | mutex_lock(&info->lock); | ||
| 966 | if (!info->fbops) { | ||
| 967 | mutex_unlock(&info->lock); | ||
| 968 | return 0; | ||
| 969 | } | ||
| 970 | return 1; | ||
| 971 | } | ||
| 972 | |||
| 973 | static inline void unlock_fb_info(struct fb_info *info) | ||
| 974 | { | ||
| 975 | mutex_unlock(&info->lock); | ||
| 976 | } | ||
| 977 | |||
| 963 | static inline void __fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, | 978 | static inline void __fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, |
| 964 | u8 *src, u32 s_pitch, u32 height) | 979 | u8 *src, u32 s_pitch, u32 height) |
| 965 | { | 980 | { |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 343df9ef2412..7fa371898e3e 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
| @@ -480,7 +480,8 @@ static inline char *pack_hex_byte(char *buf, u8 byte) | |||
| 480 | /* | 480 | /* |
| 481 | * swap - swap value of @a and @b | 481 | * swap - swap value of @a and @b |
| 482 | */ | 482 | */ |
| 483 | #define swap(a, b) ({ typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; }) | 483 | #define swap(a, b) \ |
| 484 | do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0) | ||
| 484 | 485 | ||
| 485 | /** | 486 | /** |
| 486 | * container_of - cast a member of a structure out to the containing structure | 487 | * container_of - cast a member of a structure out to the containing structure |
diff --git a/include/linux/module.h b/include/linux/module.h index f3b8329eb5b8..145a75528cc1 100644 --- a/include/linux/module.h +++ b/include/linux/module.h | |||
| @@ -407,7 +407,6 @@ static inline local_t *__module_ref_addr(struct module *mod, int cpu) | |||
| 407 | static inline void __module_get(struct module *module) | 407 | static inline void __module_get(struct module *module) |
| 408 | { | 408 | { |
| 409 | if (module) { | 409 | if (module) { |
| 410 | BUG_ON(module_refcount(module) == 0); | ||
| 411 | local_inc(__module_ref_addr(module, get_cpu())); | 410 | local_inc(__module_ref_addr(module, get_cpu())); |
| 412 | put_cpu(); | 411 | put_cpu(); |
| 413 | } | 412 | } |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 48890cf3f96e..7bd624bfdcfd 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
| @@ -684,7 +684,7 @@ int pci_enable_rom(struct pci_dev *pdev); | |||
| 684 | void pci_disable_rom(struct pci_dev *pdev); | 684 | void pci_disable_rom(struct pci_dev *pdev); |
| 685 | void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size); | 685 | void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size); |
| 686 | void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom); | 686 | void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom); |
| 687 | size_t pci_get_rom_size(void __iomem *rom, size_t size); | 687 | size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size); |
| 688 | 688 | ||
| 689 | /* Power management related routines */ | 689 | /* Power management related routines */ |
| 690 | int pci_save_state(struct pci_dev *dev); | 690 | int pci_save_state(struct pci_dev *dev); |
diff --git a/include/linux/sched.h b/include/linux/sched.h index f3c23cf11abc..699edb8e1853 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
| @@ -445,6 +445,7 @@ struct pacct_struct { | |||
| 445 | * @utime: time spent in user mode, in &cputime_t units | 445 | * @utime: time spent in user mode, in &cputime_t units |
| 446 | * @stime: time spent in kernel mode, in &cputime_t units | 446 | * @stime: time spent in kernel mode, in &cputime_t units |
| 447 | * @sum_exec_runtime: total time spent on the CPU, in nanoseconds | 447 | * @sum_exec_runtime: total time spent on the CPU, in nanoseconds |
| 448 | * @lock: lock for fields in this struct | ||
| 448 | * | 449 | * |
| 449 | * This structure groups together three kinds of CPU time that are | 450 | * This structure groups together three kinds of CPU time that are |
| 450 | * tracked for threads and thread groups. Most things considering | 451 | * tracked for threads and thread groups. Most things considering |
diff --git a/include/linux/wait.h b/include/linux/wait.h index ef609f842fac..a210ede73b56 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h | |||
| @@ -132,6 +132,8 @@ static inline void __remove_wait_queue(wait_queue_head_t *head, | |||
| 132 | list_del(&old->task_list); | 132 | list_del(&old->task_list); |
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | void __wake_up_common(wait_queue_head_t *q, unsigned int mode, | ||
| 136 | int nr_exclusive, int sync, void *key); | ||
| 135 | void __wake_up(wait_queue_head_t *q, unsigned int mode, int nr, void *key); | 137 | void __wake_up(wait_queue_head_t *q, unsigned int mode, int nr, void *key); |
| 136 | extern void __wake_up_locked(wait_queue_head_t *q, unsigned int mode); | 138 | extern void __wake_up_locked(wait_queue_head_t *q, unsigned int mode); |
| 137 | extern void __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr); | 139 | extern void __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr); |
| @@ -333,16 +335,19 @@ do { \ | |||
| 333 | for (;;) { \ | 335 | for (;;) { \ |
| 334 | prepare_to_wait_exclusive(&wq, &__wait, \ | 336 | prepare_to_wait_exclusive(&wq, &__wait, \ |
| 335 | TASK_INTERRUPTIBLE); \ | 337 | TASK_INTERRUPTIBLE); \ |
| 336 | if (condition) \ | 338 | if (condition) { \ |
| 339 | finish_wait(&wq, &__wait); \ | ||
| 337 | break; \ | 340 | break; \ |
| 341 | } \ | ||
| 338 | if (!signal_pending(current)) { \ | 342 | if (!signal_pending(current)) { \ |
| 339 | schedule(); \ | 343 | schedule(); \ |
| 340 | continue; \ | 344 | continue; \ |
| 341 | } \ | 345 | } \ |
| 342 | ret = -ERESTARTSYS; \ | 346 | ret = -ERESTARTSYS; \ |
| 347 | abort_exclusive_wait(&wq, &__wait, \ | ||
| 348 | TASK_INTERRUPTIBLE, NULL); \ | ||
| 343 | break; \ | 349 | break; \ |
| 344 | } \ | 350 | } \ |
| 345 | finish_wait(&wq, &__wait); \ | ||
| 346 | } while (0) | 351 | } while (0) |
| 347 | 352 | ||
| 348 | #define wait_event_interruptible_exclusive(wq, condition) \ | 353 | #define wait_event_interruptible_exclusive(wq, condition) \ |
| @@ -431,6 +436,8 @@ extern long interruptible_sleep_on_timeout(wait_queue_head_t *q, | |||
| 431 | void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state); | 436 | void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state); |
| 432 | void prepare_to_wait_exclusive(wait_queue_head_t *q, wait_queue_t *wait, int state); | 437 | void prepare_to_wait_exclusive(wait_queue_head_t *q, wait_queue_t *wait, int state); |
| 433 | void finish_wait(wait_queue_head_t *q, wait_queue_t *wait); | 438 | void finish_wait(wait_queue_head_t *q, wait_queue_t *wait); |
| 439 | void abort_exclusive_wait(wait_queue_head_t *q, wait_queue_t *wait, | ||
| 440 | unsigned int mode, void *key); | ||
| 434 | int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key); | 441 | int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key); |
| 435 | int wake_bit_function(wait_queue_t *wait, unsigned mode, int sync, void *key); | 442 | int wake_bit_function(wait_queue_t *wait, unsigned mode, int sync, void *key); |
| 436 | 443 | ||
diff --git a/include/video/aty128.h b/include/video/aty128.h index 7079beb005e8..51ac69f05bdc 100644 --- a/include/video/aty128.h +++ b/include/video/aty128.h | |||
| @@ -21,9 +21,9 @@ | |||
| 21 | #define I2C_CNTL_1 0x0094 | 21 | #define I2C_CNTL_1 0x0094 |
| 22 | #define PALETTE_INDEX 0x00b0 | 22 | #define PALETTE_INDEX 0x00b0 |
| 23 | #define PALETTE_DATA 0x00b4 | 23 | #define PALETTE_DATA 0x00b4 |
| 24 | #define CONFIG_CNTL 0x00e0 | 24 | #define CNFG_CNTL 0x00e0 |
| 25 | #define GEN_RESET_CNTL 0x00f0 | 25 | #define GEN_RESET_CNTL 0x00f0 |
| 26 | #define CONFIG_MEMSIZE 0x00f8 | 26 | #define CNFG_MEMSIZE 0x00f8 |
| 27 | #define MEM_CNTL 0x0140 | 27 | #define MEM_CNTL 0x0140 |
| 28 | #define MEM_POWER_MISC 0x015c | 28 | #define MEM_POWER_MISC 0x015c |
| 29 | #define AGP_BASE 0x0170 | 29 | #define AGP_BASE 0x0170 |
diff --git a/include/video/mach64.h b/include/video/mach64.h index a8332e528ec1..89e91c0cb737 100644 --- a/include/video/mach64.h +++ b/include/video/mach64.h | |||
| @@ -103,7 +103,7 @@ | |||
| 103 | #define CUR_HORZ_VERT_OFF 0x0070 /* Dword offset 0_1C */ | 103 | #define CUR_HORZ_VERT_OFF 0x0070 /* Dword offset 0_1C */ |
| 104 | #define CUR2_HORZ_VERT_OFF 0x0070 /* Dword offset 0_1C */ | 104 | #define CUR2_HORZ_VERT_OFF 0x0070 /* Dword offset 0_1C */ |
| 105 | 105 | ||
| 106 | #define CONFIG_PANEL_LG 0x0074 /* Dword offset 0_1D (LG) */ | 106 | #define CNFG_PANEL_LG 0x0074 /* Dword offset 0_1D (LG) */ |
| 107 | 107 | ||
| 108 | /* General I/O Control */ | 108 | /* General I/O Control */ |
| 109 | #define GP_IO 0x0078 /* Dword offset 0_1E */ | 109 | #define GP_IO 0x0078 /* Dword offset 0_1E */ |
| @@ -146,8 +146,8 @@ | |||
| 146 | #define CLOCK_SEL_CNTL 0x0090 /* Dword offset 0_24 */ | 146 | #define CLOCK_SEL_CNTL 0x0090 /* Dword offset 0_24 */ |
| 147 | 147 | ||
| 148 | /* Configuration */ | 148 | /* Configuration */ |
| 149 | #define CONFIG_STAT1 0x0094 /* Dword offset 0_25 */ | 149 | #define CNFG_STAT1 0x0094 /* Dword offset 0_25 */ |
| 150 | #define CONFIG_STAT2 0x0098 /* Dword offset 0_26 */ | 150 | #define CNFG_STAT2 0x0098 /* Dword offset 0_26 */ |
| 151 | 151 | ||
| 152 | /* Bus Control */ | 152 | /* Bus Control */ |
| 153 | #define BUS_CNTL 0x00A0 /* Dword offset 0_28 */ | 153 | #define BUS_CNTL 0x00A0 /* Dword offset 0_28 */ |
| @@ -190,9 +190,9 @@ | |||
| 190 | #define POWER_MANAGEMENT_LG 0x00D8 /* Dword offset 0_36 (LG) */ | 190 | #define POWER_MANAGEMENT_LG 0x00D8 /* Dword offset 0_36 (LG) */ |
| 191 | 191 | ||
| 192 | /* Configuration */ | 192 | /* Configuration */ |
| 193 | #define CONFIG_CNTL 0x00DC /* Dword offset 0_37 (CT, ET, VT) */ | 193 | #define CNFG_CNTL 0x00DC /* Dword offset 0_37 (CT, ET, VT) */ |
| 194 | #define CONFIG_CHIP_ID 0x00E0 /* Dword offset 0_38 */ | 194 | #define CNFG_CHIP_ID 0x00E0 /* Dword offset 0_38 */ |
| 195 | #define CONFIG_STAT0 0x00E4 /* Dword offset 0_39 */ | 195 | #define CNFG_STAT0 0x00E4 /* Dword offset 0_39 */ |
| 196 | 196 | ||
| 197 | /* Test and Debug */ | 197 | /* Test and Debug */ |
| 198 | #define CRC_SIG 0x00E8 /* Dword offset 0_3A */ | 198 | #define CRC_SIG 0x00E8 /* Dword offset 0_3A */ |
| @@ -851,17 +851,17 @@ | |||
| 851 | #define PLL_YCLK_CNTL 0x29 | 851 | #define PLL_YCLK_CNTL 0x29 |
| 852 | #define PM_DYN_CLK_CNTL 0x2A | 852 | #define PM_DYN_CLK_CNTL 0x2A |
| 853 | 853 | ||
| 854 | /* CONFIG_CNTL register constants */ | 854 | /* CNFG_CNTL register constants */ |
| 855 | #define APERTURE_4M_ENABLE 1 | 855 | #define APERTURE_4M_ENABLE 1 |
| 856 | #define APERTURE_8M_ENABLE 2 | 856 | #define APERTURE_8M_ENABLE 2 |
| 857 | #define VGA_APERTURE_ENABLE 4 | 857 | #define VGA_APERTURE_ENABLE 4 |
| 858 | 858 | ||
| 859 | /* CONFIG_STAT0 register constants (GX, CX) */ | 859 | /* CNFG_STAT0 register constants (GX, CX) */ |
| 860 | #define CFG_BUS_TYPE 0x00000007 | 860 | #define CFG_BUS_TYPE 0x00000007 |
| 861 | #define CFG_MEM_TYPE 0x00000038 | 861 | #define CFG_MEM_TYPE 0x00000038 |
| 862 | #define CFG_INIT_DAC_TYPE 0x00000e00 | 862 | #define CFG_INIT_DAC_TYPE 0x00000e00 |
| 863 | 863 | ||
| 864 | /* CONFIG_STAT0 register constants (CT, ET, VT) */ | 864 | /* CNFG_STAT0 register constants (CT, ET, VT) */ |
| 865 | #define CFG_MEM_TYPE_xT 0x00000007 | 865 | #define CFG_MEM_TYPE_xT 0x00000007 |
| 866 | 866 | ||
| 867 | #define ISA 0 | 867 | #define ISA 0 |
| @@ -942,7 +942,7 @@ | |||
| 942 | #define PCI_ATI_VENDOR_ID 0x1002 | 942 | #define PCI_ATI_VENDOR_ID 0x1002 |
| 943 | 943 | ||
| 944 | 944 | ||
| 945 | /* CONFIG_CHIP_ID register constants */ | 945 | /* CNFG_CHIP_ID register constants */ |
| 946 | #define CFG_CHIP_TYPE 0x0000FFFF | 946 | #define CFG_CHIP_TYPE 0x0000FFFF |
| 947 | #define CFG_CHIP_CLASS 0x00FF0000 | 947 | #define CFG_CHIP_CLASS 0x00FF0000 |
| 948 | #define CFG_CHIP_REV 0xFF000000 | 948 | #define CFG_CHIP_REV 0xFF000000 |
| @@ -951,7 +951,7 @@ | |||
| 951 | #define CFG_CHIP_MINOR 0xC0000000 | 951 | #define CFG_CHIP_MINOR 0xC0000000 |
| 952 | 952 | ||
| 953 | 953 | ||
| 954 | /* Chip IDs read from CONFIG_CHIP_ID */ | 954 | /* Chip IDs read from CNFG_CHIP_ID */ |
| 955 | 955 | ||
| 956 | /* mach64GX family */ | 956 | /* mach64GX family */ |
| 957 | #define GX_CHIP_ID 0xD7 /* mach64GX (ATI888GX00) */ | 957 | #define GX_CHIP_ID 0xD7 /* mach64GX (ATI888GX00) */ |
| @@ -1254,7 +1254,7 @@ | |||
| 1254 | #define CRTC2_DISPLAY_DIS 0x00000400 | 1254 | #define CRTC2_DISPLAY_DIS 0x00000400 |
| 1255 | 1255 | ||
| 1256 | /* LCD register indices */ | 1256 | /* LCD register indices */ |
| 1257 | #define CONFIG_PANEL 0x00 | 1257 | #define CNFG_PANEL 0x00 |
| 1258 | #define LCD_GEN_CNTL 0x01 | 1258 | #define LCD_GEN_CNTL 0x01 |
| 1259 | #define DSTN_CONTROL 0x02 | 1259 | #define DSTN_CONTROL 0x02 |
| 1260 | #define HFB_PITCH_ADDR 0x03 | 1260 | #define HFB_PITCH_ADDR 0x03 |
diff --git a/include/video/radeon.h b/include/video/radeon.h index 1cd09cc5b169..e072b16b39ab 100644 --- a/include/video/radeon.h +++ b/include/video/radeon.h | |||
| @@ -11,13 +11,13 @@ | |||
| 11 | #define HI_STAT 0x004C | 11 | #define HI_STAT 0x004C |
| 12 | #define BUS_CNTL1 0x0034 | 12 | #define BUS_CNTL1 0x0034 |
| 13 | #define I2C_CNTL_1 0x0094 | 13 | #define I2C_CNTL_1 0x0094 |
| 14 | #define CONFIG_CNTL 0x00E0 | 14 | #define CNFG_CNTL 0x00E0 |
| 15 | #define CONFIG_MEMSIZE 0x00F8 | 15 | #define CNFG_MEMSIZE 0x00F8 |
| 16 | #define CONFIG_APER_0_BASE 0x0100 | 16 | #define CNFG_APER_0_BASE 0x0100 |
| 17 | #define CONFIG_APER_1_BASE 0x0104 | 17 | #define CNFG_APER_1_BASE 0x0104 |
| 18 | #define CONFIG_APER_SIZE 0x0108 | 18 | #define CNFG_APER_SIZE 0x0108 |
| 19 | #define CONFIG_REG_1_BASE 0x010C | 19 | #define CNFG_REG_1_BASE 0x010C |
| 20 | #define CONFIG_REG_APER_SIZE 0x0110 | 20 | #define CNFG_REG_APER_SIZE 0x0110 |
| 21 | #define PAD_AGPINPUT_DELAY 0x0164 | 21 | #define PAD_AGPINPUT_DELAY 0x0164 |
| 22 | #define PAD_CTLR_STRENGTH 0x0168 | 22 | #define PAD_CTLR_STRENGTH 0x0168 |
| 23 | #define PAD_CTLR_UPDATE 0x016C | 23 | #define PAD_CTLR_UPDATE 0x016C |
| @@ -509,7 +509,7 @@ | |||
| 509 | /* CLOCK_CNTL_INDEX bit constants */ | 509 | /* CLOCK_CNTL_INDEX bit constants */ |
| 510 | #define PLL_WR_EN 0x00000080 | 510 | #define PLL_WR_EN 0x00000080 |
| 511 | 511 | ||
| 512 | /* CONFIG_CNTL bit constants */ | 512 | /* CNFG_CNTL bit constants */ |
| 513 | #define CFG_VGA_RAM_EN 0x00000100 | 513 | #define CFG_VGA_RAM_EN 0x00000100 |
| 514 | #define CFG_ATI_REV_ID_MASK (0xf << 16) | 514 | #define CFG_ATI_REV_ID_MASK (0xf << 16) |
| 515 | #define CFG_ATI_REV_A11 (0 << 16) | 515 | #define CFG_ATI_REV_A11 (0 << 16) |
| @@ -980,7 +980,7 @@ | |||
| 980 | 980 | ||
| 981 | /* masks */ | 981 | /* masks */ |
| 982 | 982 | ||
| 983 | #define CONFIG_MEMSIZE_MASK 0x1f000000 | 983 | #define CNFG_MEMSIZE_MASK 0x1f000000 |
| 984 | #define MEM_CFG_TYPE 0x40000000 | 984 | #define MEM_CFG_TYPE 0x40000000 |
| 985 | #define DST_OFFSET_MASK 0x003fffff | 985 | #define DST_OFFSET_MASK 0x003fffff |
| 986 | #define DST_PITCH_MASK 0x3fc00000 | 986 | #define DST_PITCH_MASK 0x3fc00000 |
| @@ -565,11 +565,15 @@ static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss, | |||
| 565 | struct hstate *h = hstate_file(shp->shm_file); | 565 | struct hstate *h = hstate_file(shp->shm_file); |
| 566 | *rss += pages_per_huge_page(h) * mapping->nrpages; | 566 | *rss += pages_per_huge_page(h) * mapping->nrpages; |
| 567 | } else { | 567 | } else { |
| 568 | #ifdef CONFIG_SHMEM | ||
| 568 | struct shmem_inode_info *info = SHMEM_I(inode); | 569 | struct shmem_inode_info *info = SHMEM_I(inode); |
| 569 | spin_lock(&info->lock); | 570 | spin_lock(&info->lock); |
| 570 | *rss += inode->i_mapping->nrpages; | 571 | *rss += inode->i_mapping->nrpages; |
| 571 | *swp += info->swapped; | 572 | *swp += info->swapped; |
| 572 | spin_unlock(&info->lock); | 573 | spin_unlock(&info->lock); |
| 574 | #else | ||
| 575 | *rss += inode->i_mapping->nrpages; | ||
| 576 | #endif | ||
| 573 | } | 577 | } |
| 574 | 578 | ||
| 575 | total++; | 579 | total++; |
diff --git a/kernel/async.c b/kernel/async.c index 608b32b42812..f565891f2c9b 100644 --- a/kernel/async.c +++ b/kernel/async.c | |||
| @@ -54,6 +54,7 @@ asynchronous and synchronous parts of the kernel. | |||
| 54 | #include <linux/sched.h> | 54 | #include <linux/sched.h> |
| 55 | #include <linux/init.h> | 55 | #include <linux/init.h> |
| 56 | #include <linux/kthread.h> | 56 | #include <linux/kthread.h> |
| 57 | #include <linux/delay.h> | ||
| 57 | #include <asm/atomic.h> | 58 | #include <asm/atomic.h> |
| 58 | 59 | ||
| 59 | static async_cookie_t next_cookie = 1; | 60 | static async_cookie_t next_cookie = 1; |
| @@ -132,21 +133,23 @@ static void run_one_entry(void) | |||
| 132 | entry = list_first_entry(&async_pending, struct async_entry, list); | 133 | entry = list_first_entry(&async_pending, struct async_entry, list); |
| 133 | 134 | ||
| 134 | /* 2) move it to the running queue */ | 135 | /* 2) move it to the running queue */ |
| 135 | list_del(&entry->list); | 136 | list_move_tail(&entry->list, entry->running); |
| 136 | list_add_tail(&entry->list, &async_running); | ||
| 137 | spin_unlock_irqrestore(&async_lock, flags); | 137 | spin_unlock_irqrestore(&async_lock, flags); |
| 138 | 138 | ||
| 139 | /* 3) run it (and print duration)*/ | 139 | /* 3) run it (and print duration)*/ |
| 140 | if (initcall_debug && system_state == SYSTEM_BOOTING) { | 140 | if (initcall_debug && system_state == SYSTEM_BOOTING) { |
| 141 | printk("calling %lli_%pF @ %i\n", entry->cookie, entry->func, task_pid_nr(current)); | 141 | printk("calling %lli_%pF @ %i\n", (long long)entry->cookie, |
| 142 | entry->func, task_pid_nr(current)); | ||
| 142 | calltime = ktime_get(); | 143 | calltime = ktime_get(); |
| 143 | } | 144 | } |
| 144 | entry->func(entry->data, entry->cookie); | 145 | entry->func(entry->data, entry->cookie); |
| 145 | if (initcall_debug && system_state == SYSTEM_BOOTING) { | 146 | if (initcall_debug && system_state == SYSTEM_BOOTING) { |
| 146 | rettime = ktime_get(); | 147 | rettime = ktime_get(); |
| 147 | delta = ktime_sub(rettime, calltime); | 148 | delta = ktime_sub(rettime, calltime); |
| 148 | printk("initcall %lli_%pF returned 0 after %lld usecs\n", entry->cookie, | 149 | printk("initcall %lli_%pF returned 0 after %lld usecs\n", |
| 149 | entry->func, ktime_to_ns(delta) >> 10); | 150 | (long long)entry->cookie, |
| 151 | entry->func, | ||
| 152 | (long long)ktime_to_ns(delta) >> 10); | ||
| 150 | } | 153 | } |
| 151 | 154 | ||
| 152 | /* 4) remove it from the running queue */ | 155 | /* 4) remove it from the running queue */ |
| @@ -205,18 +208,44 @@ static async_cookie_t __async_schedule(async_func_ptr *ptr, void *data, struct l | |||
| 205 | return newcookie; | 208 | return newcookie; |
| 206 | } | 209 | } |
| 207 | 210 | ||
| 211 | /** | ||
| 212 | * async_schedule - schedule a function for asynchronous execution | ||
| 213 | * @ptr: function to execute asynchronously | ||
| 214 | * @data: data pointer to pass to the function | ||
| 215 | * | ||
| 216 | * Returns an async_cookie_t that may be used for checkpointing later. | ||
| 217 | * Note: This function may be called from atomic or non-atomic contexts. | ||
| 218 | */ | ||
| 208 | async_cookie_t async_schedule(async_func_ptr *ptr, void *data) | 219 | async_cookie_t async_schedule(async_func_ptr *ptr, void *data) |
| 209 | { | 220 | { |
| 210 | return __async_schedule(ptr, data, &async_pending); | 221 | return __async_schedule(ptr, data, &async_running); |
| 211 | } | 222 | } |
| 212 | EXPORT_SYMBOL_GPL(async_schedule); | 223 | EXPORT_SYMBOL_GPL(async_schedule); |
| 213 | 224 | ||
| 214 | async_cookie_t async_schedule_special(async_func_ptr *ptr, void *data, struct list_head *running) | 225 | /** |
| 226 | * async_schedule_domain - schedule a function for asynchronous execution within a certain domain | ||
| 227 | * @ptr: function to execute asynchronously | ||
| 228 | * @data: data pointer to pass to the function | ||
| 229 | * @running: running list for the domain | ||
| 230 | * | ||
| 231 | * Returns an async_cookie_t that may be used for checkpointing later. | ||
| 232 | * @running may be used in the async_synchronize_*_domain() functions | ||
| 233 | * to wait within a certain synchronization domain rather than globally. | ||
| 234 | * A synchronization domain is specified via the running queue @running to use. | ||
| 235 | * Note: This function may be called from atomic or non-atomic contexts. | ||
| 236 | */ | ||
| 237 | async_cookie_t async_schedule_domain(async_func_ptr *ptr, void *data, | ||
| 238 | struct list_head *running) | ||
| 215 | { | 239 | { |
| 216 | return __async_schedule(ptr, data, running); | 240 | return __async_schedule(ptr, data, running); |
| 217 | } | 241 | } |
| 218 | EXPORT_SYMBOL_GPL(async_schedule_special); | 242 | EXPORT_SYMBOL_GPL(async_schedule_domain); |
| 219 | 243 | ||
| 244 | /** | ||
| 245 | * async_synchronize_full - synchronize all asynchronous function calls | ||
| 246 | * | ||
| 247 | * This function waits until all asynchronous function calls have been done. | ||
| 248 | */ | ||
| 220 | void async_synchronize_full(void) | 249 | void async_synchronize_full(void) |
| 221 | { | 250 | { |
| 222 | do { | 251 | do { |
| @@ -225,13 +254,30 @@ void async_synchronize_full(void) | |||
| 225 | } | 254 | } |
| 226 | EXPORT_SYMBOL_GPL(async_synchronize_full); | 255 | EXPORT_SYMBOL_GPL(async_synchronize_full); |
| 227 | 256 | ||
| 228 | void async_synchronize_full_special(struct list_head *list) | 257 | /** |
| 258 | * async_synchronize_full_domain - synchronize all asynchronous function within a certain domain | ||
| 259 | * @list: running list to synchronize on | ||
| 260 | * | ||
| 261 | * This function waits until all asynchronous function calls for the | ||
| 262 | * synchronization domain specified by the running list @list have been done. | ||
| 263 | */ | ||
| 264 | void async_synchronize_full_domain(struct list_head *list) | ||
| 229 | { | 265 | { |
| 230 | async_synchronize_cookie_special(next_cookie, list); | 266 | async_synchronize_cookie_domain(next_cookie, list); |
| 231 | } | 267 | } |
| 232 | EXPORT_SYMBOL_GPL(async_synchronize_full_special); | 268 | EXPORT_SYMBOL_GPL(async_synchronize_full_domain); |
| 233 | 269 | ||
| 234 | void async_synchronize_cookie_special(async_cookie_t cookie, struct list_head *running) | 270 | /** |
| 271 | * async_synchronize_cookie_domain - synchronize asynchronous function calls within a certain domain with cookie checkpointing | ||
| 272 | * @cookie: async_cookie_t to use as checkpoint | ||
| 273 | * @running: running list to synchronize on | ||
| 274 | * | ||
| 275 | * This function waits until all asynchronous function calls for the | ||
| 276 | * synchronization domain specified by the running list @list submitted | ||
| 277 | * prior to @cookie have been done. | ||
| 278 | */ | ||
| 279 | void async_synchronize_cookie_domain(async_cookie_t cookie, | ||
| 280 | struct list_head *running) | ||
| 235 | { | 281 | { |
| 236 | ktime_t starttime, delta, endtime; | 282 | ktime_t starttime, delta, endtime; |
| 237 | 283 | ||
| @@ -247,14 +293,22 @@ void async_synchronize_cookie_special(async_cookie_t cookie, struct list_head *r | |||
| 247 | delta = ktime_sub(endtime, starttime); | 293 | delta = ktime_sub(endtime, starttime); |
| 248 | 294 | ||
| 249 | printk("async_continuing @ %i after %lli usec\n", | 295 | printk("async_continuing @ %i after %lli usec\n", |
| 250 | task_pid_nr(current), ktime_to_ns(delta) >> 10); | 296 | task_pid_nr(current), |
| 297 | (long long)ktime_to_ns(delta) >> 10); | ||
| 251 | } | 298 | } |
| 252 | } | 299 | } |
| 253 | EXPORT_SYMBOL_GPL(async_synchronize_cookie_special); | 300 | EXPORT_SYMBOL_GPL(async_synchronize_cookie_domain); |
| 254 | 301 | ||
| 302 | /** | ||
| 303 | * async_synchronize_cookie - synchronize asynchronous function calls with cookie checkpointing | ||
| 304 | * @cookie: async_cookie_t to use as checkpoint | ||
| 305 | * | ||
| 306 | * This function waits until all asynchronous function calls prior to @cookie | ||
| 307 | * have been done. | ||
| 308 | */ | ||
| 255 | void async_synchronize_cookie(async_cookie_t cookie) | 309 | void async_synchronize_cookie(async_cookie_t cookie) |
| 256 | { | 310 | { |
| 257 | async_synchronize_cookie_special(cookie, &async_running); | 311 | async_synchronize_cookie_domain(cookie, &async_running); |
| 258 | } | 312 | } |
| 259 | EXPORT_SYMBOL_GPL(async_synchronize_cookie); | 313 | EXPORT_SYMBOL_GPL(async_synchronize_cookie); |
| 260 | 314 | ||
| @@ -315,7 +369,11 @@ static int async_manager_thread(void *unused) | |||
| 315 | ec = atomic_read(&entry_count); | 369 | ec = atomic_read(&entry_count); |
| 316 | 370 | ||
| 317 | while (tc < ec && tc < MAX_THREADS) { | 371 | while (tc < ec && tc < MAX_THREADS) { |
| 318 | kthread_run(async_thread, NULL, "async/%i", tc); | 372 | if (IS_ERR(kthread_run(async_thread, NULL, "async/%i", |
| 373 | tc))) { | ||
| 374 | msleep(100); | ||
| 375 | continue; | ||
| 376 | } | ||
| 319 | atomic_inc(&thread_count); | 377 | atomic_inc(&thread_count); |
| 320 | tc++; | 378 | tc++; |
| 321 | } | 379 | } |
| @@ -330,7 +388,9 @@ static int async_manager_thread(void *unused) | |||
| 330 | static int __init async_init(void) | 388 | static int __init async_init(void) |
| 331 | { | 389 | { |
| 332 | if (async_enabled) | 390 | if (async_enabled) |
| 333 | kthread_run(async_manager_thread, NULL, "async/mgr"); | 391 | if (IS_ERR(kthread_run(async_manager_thread, NULL, |
| 392 | "async/mgr"))) | ||
| 393 | async_enabled = 0; | ||
| 334 | return 0; | 394 | return 0; |
| 335 | } | 395 | } |
| 336 | 396 | ||
diff --git a/kernel/fork.c b/kernel/fork.c index 242a706e7721..6d5dbb7a13e2 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
| @@ -1005,6 +1005,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
| 1005 | * triggers too late. This doesn't hurt, the check is only there | 1005 | * triggers too late. This doesn't hurt, the check is only there |
| 1006 | * to stop root fork bombs. | 1006 | * to stop root fork bombs. |
| 1007 | */ | 1007 | */ |
| 1008 | retval = -EAGAIN; | ||
| 1008 | if (nr_threads >= max_threads) | 1009 | if (nr_threads >= max_threads) |
| 1009 | goto bad_fork_cleanup_count; | 1010 | goto bad_fork_cleanup_count; |
| 1010 | 1011 | ||
diff --git a/kernel/irq/numa_migrate.c b/kernel/irq/numa_migrate.c index ecf765c6a77a..acd88356ac76 100644 --- a/kernel/irq/numa_migrate.c +++ b/kernel/irq/numa_migrate.c | |||
| @@ -71,7 +71,7 @@ static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc, | |||
| 71 | desc = irq_desc_ptrs[irq]; | 71 | desc = irq_desc_ptrs[irq]; |
| 72 | 72 | ||
| 73 | if (desc && old_desc != desc) | 73 | if (desc && old_desc != desc) |
| 74 | goto out_unlock; | 74 | goto out_unlock; |
| 75 | 75 | ||
| 76 | node = cpu_to_node(cpu); | 76 | node = cpu_to_node(cpu); |
| 77 | desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node); | 77 | desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node); |
| @@ -84,10 +84,15 @@ static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc, | |||
| 84 | init_copy_one_irq_desc(irq, old_desc, desc, cpu); | 84 | init_copy_one_irq_desc(irq, old_desc, desc, cpu); |
| 85 | 85 | ||
| 86 | irq_desc_ptrs[irq] = desc; | 86 | irq_desc_ptrs[irq] = desc; |
| 87 | spin_unlock_irqrestore(&sparse_irq_lock, flags); | ||
| 87 | 88 | ||
| 88 | /* free the old one */ | 89 | /* free the old one */ |
| 89 | free_one_irq_desc(old_desc, desc); | 90 | free_one_irq_desc(old_desc, desc); |
| 91 | spin_unlock(&old_desc->lock); | ||
| 90 | kfree(old_desc); | 92 | kfree(old_desc); |
| 93 | spin_lock(&desc->lock); | ||
| 94 | |||
| 95 | return desc; | ||
| 91 | 96 | ||
| 92 | out_unlock: | 97 | out_unlock: |
| 93 | spin_unlock_irqrestore(&sparse_irq_lock, flags); | 98 | spin_unlock_irqrestore(&sparse_irq_lock, flags); |
diff --git a/kernel/power/main.c b/kernel/power/main.c index 239988873971..b4d219016b6c 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c | |||
| @@ -57,16 +57,6 @@ int pm_notifier_call_chain(unsigned long val) | |||
| 57 | #ifdef CONFIG_PM_DEBUG | 57 | #ifdef CONFIG_PM_DEBUG |
| 58 | int pm_test_level = TEST_NONE; | 58 | int pm_test_level = TEST_NONE; |
| 59 | 59 | ||
| 60 | static int suspend_test(int level) | ||
| 61 | { | ||
| 62 | if (pm_test_level == level) { | ||
| 63 | printk(KERN_INFO "suspend debug: Waiting for 5 seconds.\n"); | ||
| 64 | mdelay(5000); | ||
| 65 | return 1; | ||
| 66 | } | ||
| 67 | return 0; | ||
| 68 | } | ||
| 69 | |||
| 70 | static const char * const pm_tests[__TEST_AFTER_LAST] = { | 60 | static const char * const pm_tests[__TEST_AFTER_LAST] = { |
| 71 | [TEST_NONE] = "none", | 61 | [TEST_NONE] = "none", |
| 72 | [TEST_CORE] = "core", | 62 | [TEST_CORE] = "core", |
| @@ -125,14 +115,24 @@ static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr, | |||
| 125 | } | 115 | } |
| 126 | 116 | ||
| 127 | power_attr(pm_test); | 117 | power_attr(pm_test); |
| 128 | #else /* !CONFIG_PM_DEBUG */ | 118 | #endif /* CONFIG_PM_DEBUG */ |
| 129 | static inline int suspend_test(int level) { return 0; } | ||
| 130 | #endif /* !CONFIG_PM_DEBUG */ | ||
| 131 | 119 | ||
| 132 | #endif /* CONFIG_PM_SLEEP */ | 120 | #endif /* CONFIG_PM_SLEEP */ |
| 133 | 121 | ||
| 134 | #ifdef CONFIG_SUSPEND | 122 | #ifdef CONFIG_SUSPEND |
| 135 | 123 | ||
| 124 | static int suspend_test(int level) | ||
| 125 | { | ||
| 126 | #ifdef CONFIG_PM_DEBUG | ||
| 127 | if (pm_test_level == level) { | ||
| 128 | printk(KERN_INFO "suspend debug: Waiting for 5 seconds.\n"); | ||
| 129 | mdelay(5000); | ||
| 130 | return 1; | ||
| 131 | } | ||
| 132 | #endif /* !CONFIG_PM_DEBUG */ | ||
| 133 | return 0; | ||
| 134 | } | ||
| 135 | |||
| 136 | #ifdef CONFIG_PM_TEST_SUSPEND | 136 | #ifdef CONFIG_PM_TEST_SUSPEND |
| 137 | 137 | ||
| 138 | /* | 138 | /* |
diff --git a/kernel/sched.c b/kernel/sched.c index 566c8c9e3a6d..1ffb89514871 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
| @@ -4697,8 +4697,8 @@ EXPORT_SYMBOL(default_wake_function); | |||
| 4697 | * started to run but is not in state TASK_RUNNING. try_to_wake_up() returns | 4697 | * started to run but is not in state TASK_RUNNING. try_to_wake_up() returns |
| 4698 | * zero in this (rare) case, and we handle it by continuing to scan the queue. | 4698 | * zero in this (rare) case, and we handle it by continuing to scan the queue. |
| 4699 | */ | 4699 | */ |
| 4700 | static void __wake_up_common(wait_queue_head_t *q, unsigned int mode, | 4700 | void __wake_up_common(wait_queue_head_t *q, unsigned int mode, |
| 4701 | int nr_exclusive, int sync, void *key) | 4701 | int nr_exclusive, int sync, void *key) |
| 4702 | { | 4702 | { |
| 4703 | wait_queue_t *curr, *next; | 4703 | wait_queue_t *curr, *next; |
| 4704 | 4704 | ||
diff --git a/kernel/sys.c b/kernel/sys.c index e7dc0e10a485..f145c415bc16 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
| @@ -1525,22 +1525,14 @@ SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim) | |||
| 1525 | return -EINVAL; | 1525 | return -EINVAL; |
| 1526 | if (copy_from_user(&new_rlim, rlim, sizeof(*rlim))) | 1526 | if (copy_from_user(&new_rlim, rlim, sizeof(*rlim))) |
| 1527 | return -EFAULT; | 1527 | return -EFAULT; |
| 1528 | if (new_rlim.rlim_cur > new_rlim.rlim_max) | ||
| 1529 | return -EINVAL; | ||
| 1528 | old_rlim = current->signal->rlim + resource; | 1530 | old_rlim = current->signal->rlim + resource; |
| 1529 | if ((new_rlim.rlim_max > old_rlim->rlim_max) && | 1531 | if ((new_rlim.rlim_max > old_rlim->rlim_max) && |
| 1530 | !capable(CAP_SYS_RESOURCE)) | 1532 | !capable(CAP_SYS_RESOURCE)) |
| 1531 | return -EPERM; | 1533 | return -EPERM; |
| 1532 | 1534 | if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open) | |
| 1533 | if (resource == RLIMIT_NOFILE) { | 1535 | return -EPERM; |
| 1534 | if (new_rlim.rlim_max == RLIM_INFINITY) | ||
| 1535 | new_rlim.rlim_max = sysctl_nr_open; | ||
| 1536 | if (new_rlim.rlim_cur == RLIM_INFINITY) | ||
| 1537 | new_rlim.rlim_cur = sysctl_nr_open; | ||
| 1538 | if (new_rlim.rlim_max > sysctl_nr_open) | ||
| 1539 | return -EPERM; | ||
| 1540 | } | ||
| 1541 | |||
| 1542 | if (new_rlim.rlim_cur > new_rlim.rlim_max) | ||
| 1543 | return -EINVAL; | ||
| 1544 | 1536 | ||
| 1545 | retval = security_task_setrlimit(resource, &new_rlim); | 1537 | retval = security_task_setrlimit(resource, &new_rlim); |
| 1546 | if (retval) | 1538 | if (retval) |
diff --git a/kernel/wait.c b/kernel/wait.c index cd87131f2fc2..42a2dbc181c8 100644 --- a/kernel/wait.c +++ b/kernel/wait.c | |||
| @@ -91,6 +91,15 @@ prepare_to_wait_exclusive(wait_queue_head_t *q, wait_queue_t *wait, int state) | |||
| 91 | } | 91 | } |
| 92 | EXPORT_SYMBOL(prepare_to_wait_exclusive); | 92 | EXPORT_SYMBOL(prepare_to_wait_exclusive); |
| 93 | 93 | ||
| 94 | /* | ||
| 95 | * finish_wait - clean up after waiting in a queue | ||
| 96 | * @q: waitqueue waited on | ||
| 97 | * @wait: wait descriptor | ||
| 98 | * | ||
| 99 | * Sets current thread back to running state and removes | ||
| 100 | * the wait descriptor from the given waitqueue if still | ||
| 101 | * queued. | ||
| 102 | */ | ||
| 94 | void finish_wait(wait_queue_head_t *q, wait_queue_t *wait) | 103 | void finish_wait(wait_queue_head_t *q, wait_queue_t *wait) |
| 95 | { | 104 | { |
| 96 | unsigned long flags; | 105 | unsigned long flags; |
| @@ -117,6 +126,39 @@ void finish_wait(wait_queue_head_t *q, wait_queue_t *wait) | |||
| 117 | } | 126 | } |
| 118 | EXPORT_SYMBOL(finish_wait); | 127 | EXPORT_SYMBOL(finish_wait); |
| 119 | 128 | ||
| 129 | /* | ||
| 130 | * abort_exclusive_wait - abort exclusive waiting in a queue | ||
| 131 | * @q: waitqueue waited on | ||
| 132 | * @wait: wait descriptor | ||
| 133 | * @state: runstate of the waiter to be woken | ||
| 134 | * @key: key to identify a wait bit queue or %NULL | ||
| 135 | * | ||
| 136 | * Sets current thread back to running state and removes | ||
| 137 | * the wait descriptor from the given waitqueue if still | ||
| 138 | * queued. | ||
| 139 | * | ||
| 140 | * Wakes up the next waiter if the caller is concurrently | ||
| 141 | * woken up through the queue. | ||
| 142 | * | ||
| 143 | * This prevents waiter starvation where an exclusive waiter | ||
| 144 | * aborts and is woken up concurrently and noone wakes up | ||
| 145 | * the next waiter. | ||
| 146 | */ | ||
| 147 | void abort_exclusive_wait(wait_queue_head_t *q, wait_queue_t *wait, | ||
| 148 | unsigned int mode, void *key) | ||
| 149 | { | ||
| 150 | unsigned long flags; | ||
| 151 | |||
| 152 | __set_current_state(TASK_RUNNING); | ||
| 153 | spin_lock_irqsave(&q->lock, flags); | ||
| 154 | if (!list_empty(&wait->task_list)) | ||
| 155 | list_del_init(&wait->task_list); | ||
| 156 | else if (waitqueue_active(q)) | ||
| 157 | __wake_up_common(q, mode, 1, 0, key); | ||
| 158 | spin_unlock_irqrestore(&q->lock, flags); | ||
| 159 | } | ||
| 160 | EXPORT_SYMBOL(abort_exclusive_wait); | ||
| 161 | |||
| 120 | int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key) | 162 | int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key) |
| 121 | { | 163 | { |
| 122 | int ret = default_wake_function(wait, mode, sync, key); | 164 | int ret = default_wake_function(wait, mode, sync, key); |
| @@ -177,17 +219,20 @@ int __sched | |||
| 177 | __wait_on_bit_lock(wait_queue_head_t *wq, struct wait_bit_queue *q, | 219 | __wait_on_bit_lock(wait_queue_head_t *wq, struct wait_bit_queue *q, |
| 178 | int (*action)(void *), unsigned mode) | 220 | int (*action)(void *), unsigned mode) |
| 179 | { | 221 | { |
| 180 | int ret = 0; | ||
| 181 | |||
| 182 | do { | 222 | do { |
| 223 | int ret; | ||
| 224 | |||
| 183 | prepare_to_wait_exclusive(wq, &q->wait, mode); | 225 | prepare_to_wait_exclusive(wq, &q->wait, mode); |
| 184 | if (test_bit(q->key.bit_nr, q->key.flags)) { | 226 | if (!test_bit(q->key.bit_nr, q->key.flags)) |
| 185 | if ((ret = (*action)(q->key.flags))) | 227 | continue; |
| 186 | break; | 228 | ret = action(q->key.flags); |
| 187 | } | 229 | if (!ret) |
| 230 | continue; | ||
| 231 | abort_exclusive_wait(wq, &q->wait, mode, &q->key); | ||
| 232 | return ret; | ||
| 188 | } while (test_and_set_bit(q->key.bit_nr, q->key.flags)); | 233 | } while (test_and_set_bit(q->key.bit_nr, q->key.flags)); |
| 189 | finish_wait(wq, &q->wait); | 234 | finish_wait(wq, &q->wait); |
| 190 | return ret; | 235 | return 0; |
| 191 | } | 236 | } |
| 192 | EXPORT_SYMBOL(__wait_on_bit_lock); | 237 | EXPORT_SYMBOL(__wait_on_bit_lock); |
| 193 | 238 | ||
diff --git a/mm/memory.c b/mm/memory.c index 22bfa7a47a0b..baa999e87cd2 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
| @@ -1999,7 +1999,7 @@ gotten: | |||
| 1999 | * Don't let another task, with possibly unlocked vma, | 1999 | * Don't let another task, with possibly unlocked vma, |
| 2000 | * keep the mlocked page. | 2000 | * keep the mlocked page. |
| 2001 | */ | 2001 | */ |
| 2002 | if (vma->vm_flags & VM_LOCKED) { | 2002 | if ((vma->vm_flags & VM_LOCKED) && old_page) { |
| 2003 | lock_page(old_page); /* for LRU manipulation */ | 2003 | lock_page(old_page); /* for LRU manipulation */ |
| 2004 | clear_page_mlock(old_page); | 2004 | clear_page_mlock(old_page); |
| 2005 | unlock_page(old_page); | 2005 | unlock_page(old_page); |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 557fe16cbfb0..dda42f0bd7a3 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
| @@ -663,14 +663,10 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
| 663 | th->urg_ptr = 0; | 663 | th->urg_ptr = 0; |
| 664 | 664 | ||
| 665 | /* The urg_mode check is necessary during a below snd_una win probe */ | 665 | /* The urg_mode check is necessary during a below snd_una win probe */ |
| 666 | if (unlikely(tcp_urg_mode(tp))) { | 666 | if (unlikely(tcp_urg_mode(tp) && |
| 667 | if (between(tp->snd_up, tcb->seq + 1, tcb->seq + 0xFFFF)) { | 667 | between(tp->snd_up, tcb->seq + 1, tcb->seq + 0xFFFF))) { |
| 668 | th->urg_ptr = htons(tp->snd_up - tcb->seq); | 668 | th->urg_ptr = htons(tp->snd_up - tcb->seq); |
| 669 | th->urg = 1; | 669 | th->urg = 1; |
| 670 | } else if (after(tcb->seq + 0xFFFF, tp->snd_nxt)) { | ||
| 671 | th->urg_ptr = 0xFFFF; | ||
| 672 | th->urg = 1; | ||
| 673 | } | ||
| 674 | } | 670 | } |
| 675 | 671 | ||
| 676 | tcp_options_write((__be32 *)(th + 1), tp, &opts, &md5_hash_location); | 672 | tcp_options_write((__be32 *)(th + 1), tp, &opts, &md5_hash_location); |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 1ab180bad72a..cc3a0a06c004 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
| @@ -1231,7 +1231,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, | |||
| 1231 | int proto) | 1231 | int proto) |
| 1232 | { | 1232 | { |
| 1233 | struct sock *sk; | 1233 | struct sock *sk; |
| 1234 | struct udphdr *uh = udp_hdr(skb); | 1234 | struct udphdr *uh; |
| 1235 | unsigned short ulen; | 1235 | unsigned short ulen; |
| 1236 | struct rtable *rt = (struct rtable*)skb->dst; | 1236 | struct rtable *rt = (struct rtable*)skb->dst; |
| 1237 | __be32 saddr = ip_hdr(skb)->saddr; | 1237 | __be32 saddr = ip_hdr(skb)->saddr; |
| @@ -1244,6 +1244,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, | |||
| 1244 | if (!pskb_may_pull(skb, sizeof(struct udphdr))) | 1244 | if (!pskb_may_pull(skb, sizeof(struct udphdr))) |
| 1245 | goto drop; /* No space for header. */ | 1245 | goto drop; /* No space for header. */ |
| 1246 | 1246 | ||
| 1247 | uh = udp_hdr(skb); | ||
| 1247 | ulen = ntohs(uh->len); | 1248 | ulen = ntohs(uh->len); |
| 1248 | if (ulen > skb->len) | 1249 | if (ulen > skb->len) |
| 1249 | goto short_packet; | 1250 | goto short_packet; |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 4b15938bef4d..9fb49c3b518a 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
| @@ -1105,6 +1105,18 @@ static inline int ip6_ufo_append_data(struct sock *sk, | |||
| 1105 | return err; | 1105 | return err; |
| 1106 | } | 1106 | } |
| 1107 | 1107 | ||
| 1108 | static inline struct ipv6_opt_hdr *ip6_opt_dup(struct ipv6_opt_hdr *src, | ||
| 1109 | gfp_t gfp) | ||
| 1110 | { | ||
| 1111 | return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL; | ||
| 1112 | } | ||
| 1113 | |||
| 1114 | static inline struct ipv6_rt_hdr *ip6_rthdr_dup(struct ipv6_rt_hdr *src, | ||
| 1115 | gfp_t gfp) | ||
| 1116 | { | ||
| 1117 | return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL; | ||
| 1118 | } | ||
| 1119 | |||
| 1108 | int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | 1120 | int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, |
| 1109 | int offset, int len, int odd, struct sk_buff *skb), | 1121 | int offset, int len, int odd, struct sk_buff *skb), |
| 1110 | void *from, int length, int transhdrlen, | 1122 | void *from, int length, int transhdrlen, |
| @@ -1130,17 +1142,37 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
| 1130 | * setup for corking | 1142 | * setup for corking |
| 1131 | */ | 1143 | */ |
| 1132 | if (opt) { | 1144 | if (opt) { |
| 1133 | if (np->cork.opt == NULL) { | 1145 | if (WARN_ON(np->cork.opt)) |
| 1134 | np->cork.opt = kmalloc(opt->tot_len, | ||
| 1135 | sk->sk_allocation); | ||
| 1136 | if (unlikely(np->cork.opt == NULL)) | ||
| 1137 | return -ENOBUFS; | ||
| 1138 | } else if (np->cork.opt->tot_len < opt->tot_len) { | ||
| 1139 | printk(KERN_DEBUG "ip6_append_data: invalid option length\n"); | ||
| 1140 | return -EINVAL; | 1146 | return -EINVAL; |
| 1141 | } | 1147 | |
| 1142 | memcpy(np->cork.opt, opt, opt->tot_len); | 1148 | np->cork.opt = kmalloc(opt->tot_len, sk->sk_allocation); |
| 1143 | inet->cork.flags |= IPCORK_OPT; | 1149 | if (unlikely(np->cork.opt == NULL)) |
| 1150 | return -ENOBUFS; | ||
| 1151 | |||
| 1152 | np->cork.opt->tot_len = opt->tot_len; | ||
| 1153 | np->cork.opt->opt_flen = opt->opt_flen; | ||
| 1154 | np->cork.opt->opt_nflen = opt->opt_nflen; | ||
| 1155 | |||
| 1156 | np->cork.opt->dst0opt = ip6_opt_dup(opt->dst0opt, | ||
| 1157 | sk->sk_allocation); | ||
| 1158 | if (opt->dst0opt && !np->cork.opt->dst0opt) | ||
| 1159 | return -ENOBUFS; | ||
| 1160 | |||
| 1161 | np->cork.opt->dst1opt = ip6_opt_dup(opt->dst1opt, | ||
| 1162 | sk->sk_allocation); | ||
| 1163 | if (opt->dst1opt && !np->cork.opt->dst1opt) | ||
| 1164 | return -ENOBUFS; | ||
| 1165 | |||
| 1166 | np->cork.opt->hopopt = ip6_opt_dup(opt->hopopt, | ||
| 1167 | sk->sk_allocation); | ||
| 1168 | if (opt->hopopt && !np->cork.opt->hopopt) | ||
| 1169 | return -ENOBUFS; | ||
| 1170 | |||
| 1171 | np->cork.opt->srcrt = ip6_rthdr_dup(opt->srcrt, | ||
| 1172 | sk->sk_allocation); | ||
| 1173 | if (opt->srcrt && !np->cork.opt->srcrt) | ||
| 1174 | return -ENOBUFS; | ||
| 1175 | |||
| 1144 | /* need source address above miyazawa*/ | 1176 | /* need source address above miyazawa*/ |
| 1145 | } | 1177 | } |
| 1146 | dst_hold(&rt->u.dst); | 1178 | dst_hold(&rt->u.dst); |
| @@ -1167,8 +1199,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
| 1167 | } else { | 1199 | } else { |
| 1168 | rt = (struct rt6_info *)inet->cork.dst; | 1200 | rt = (struct rt6_info *)inet->cork.dst; |
| 1169 | fl = &inet->cork.fl; | 1201 | fl = &inet->cork.fl; |
| 1170 | if (inet->cork.flags & IPCORK_OPT) | 1202 | opt = np->cork.opt; |
| 1171 | opt = np->cork.opt; | ||
| 1172 | transhdrlen = 0; | 1203 | transhdrlen = 0; |
| 1173 | exthdrlen = 0; | 1204 | exthdrlen = 0; |
| 1174 | mtu = inet->cork.fragsize; | 1205 | mtu = inet->cork.fragsize; |
| @@ -1407,9 +1438,15 @@ error: | |||
| 1407 | 1438 | ||
| 1408 | static void ip6_cork_release(struct inet_sock *inet, struct ipv6_pinfo *np) | 1439 | static void ip6_cork_release(struct inet_sock *inet, struct ipv6_pinfo *np) |
| 1409 | { | 1440 | { |
| 1410 | inet->cork.flags &= ~IPCORK_OPT; | 1441 | if (np->cork.opt) { |
| 1411 | kfree(np->cork.opt); | 1442 | kfree(np->cork.opt->dst0opt); |
| 1412 | np->cork.opt = NULL; | 1443 | kfree(np->cork.opt->dst1opt); |
| 1444 | kfree(np->cork.opt->hopopt); | ||
| 1445 | kfree(np->cork.opt->srcrt); | ||
| 1446 | kfree(np->cork.opt); | ||
| 1447 | np->cork.opt = NULL; | ||
| 1448 | } | ||
| 1449 | |||
| 1413 | if (inet->cork.dst) { | 1450 | if (inet->cork.dst) { |
| 1414 | dst_release(inet->cork.dst); | 1451 | dst_release(inet->cork.dst); |
| 1415 | inet->cork.dst = NULL; | 1452 | inet->cork.dst = NULL; |
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index e17836680f49..0a1798eafb0b 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c | |||
| @@ -1767,7 +1767,7 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file) | |||
| 1767 | AFMT_S8 | AFMT_U16_LE | | 1767 | AFMT_S8 | AFMT_U16_LE | |
| 1768 | AFMT_U16_BE | | 1768 | AFMT_U16_BE | |
| 1769 | AFMT_S32_LE | AFMT_S32_BE | | 1769 | AFMT_S32_LE | AFMT_S32_BE | |
| 1770 | AFMT_S24_LE | AFMT_S24_LE | | 1770 | AFMT_S24_LE | AFMT_S24_BE | |
| 1771 | AFMT_S24_PACKED; | 1771 | AFMT_S24_PACKED; |
| 1772 | params = kmalloc(sizeof(*params), GFP_KERNEL); | 1772 | params = kmalloc(sizeof(*params), GFP_KERNEL); |
| 1773 | if (!params) | 1773 | if (!params) |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index b7bba7dc7cf1..0b708134d12f 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
| @@ -487,7 +487,6 @@ int /*__devinit*/ snd_hda_bus_new(struct snd_card *card, | |||
| 487 | { | 487 | { |
| 488 | struct hda_bus *bus; | 488 | struct hda_bus *bus; |
| 489 | int err; | 489 | int err; |
| 490 | char qname[8]; | ||
| 491 | static struct snd_device_ops dev_ops = { | 490 | static struct snd_device_ops dev_ops = { |
| 492 | .dev_register = snd_hda_bus_dev_register, | 491 | .dev_register = snd_hda_bus_dev_register, |
| 493 | .dev_free = snd_hda_bus_dev_free, | 492 | .dev_free = snd_hda_bus_dev_free, |
| @@ -517,10 +516,12 @@ int /*__devinit*/ snd_hda_bus_new(struct snd_card *card, | |||
| 517 | mutex_init(&bus->cmd_mutex); | 516 | mutex_init(&bus->cmd_mutex); |
| 518 | INIT_LIST_HEAD(&bus->codec_list); | 517 | INIT_LIST_HEAD(&bus->codec_list); |
| 519 | 518 | ||
| 520 | snprintf(qname, sizeof(qname), "hda%d", card->number); | 519 | snprintf(bus->workq_name, sizeof(bus->workq_name), |
| 521 | bus->workq = create_workqueue(qname); | 520 | "hd-audio%d", card->number); |
| 521 | bus->workq = create_singlethread_workqueue(bus->workq_name); | ||
| 522 | if (!bus->workq) { | 522 | if (!bus->workq) { |
| 523 | snd_printk(KERN_ERR "cannot create workqueue %s\n", qname); | 523 | snd_printk(KERN_ERR "cannot create workqueue %s\n", |
| 524 | bus->workq_name); | ||
| 524 | kfree(bus); | 525 | kfree(bus); |
| 525 | return -ENOMEM; | 526 | return -ENOMEM; |
| 526 | } | 527 | } |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 5810ef588402..09a332ada0c6 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
| @@ -614,6 +614,7 @@ struct hda_bus { | |||
| 614 | 614 | ||
| 615 | /* unsolicited event queue */ | 615 | /* unsolicited event queue */ |
| 616 | struct hda_bus_unsolicited *unsol; | 616 | struct hda_bus_unsolicited *unsol; |
| 617 | char workq_name[16]; | ||
| 617 | struct workqueue_struct *workq; /* common workqueue for codecs */ | 618 | struct workqueue_struct *workq; /* common workqueue for codecs */ |
| 618 | 619 | ||
| 619 | /* assigned PCMs */ | 620 | /* assigned PCMs */ |
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index 7ca66d654148..144b85276d5a 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c | |||
| @@ -399,7 +399,8 @@ static void print_conn_list(struct snd_info_buffer *buffer, | |||
| 399 | { | 399 | { |
| 400 | int c, curr = -1; | 400 | int c, curr = -1; |
| 401 | 401 | ||
| 402 | if (conn_len > 1 && wid_type != AC_WID_AUD_MIX) | 402 | if (conn_len > 1 && wid_type != AC_WID_AUD_MIX && |
| 403 | wid_type != AC_WID_VOL_KNB) | ||
| 403 | curr = snd_hda_codec_read(codec, nid, 0, | 404 | curr = snd_hda_codec_read(codec, nid, 0, |
| 404 | AC_VERB_GET_CONNECT_SEL, 0); | 405 | AC_VERB_GET_CONNECT_SEL, 0); |
| 405 | snd_iprintf(buffer, " Connection: %d\n", conn_len); | 406 | snd_iprintf(buffer, " Connection: %d\n", conn_len); |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 7884a4e07061..ae5c8a0d1479 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
| @@ -1037,6 +1037,7 @@ do_sku: | |||
| 1037 | case 0x10ec0267: | 1037 | case 0x10ec0267: |
| 1038 | case 0x10ec0268: | 1038 | case 0x10ec0268: |
| 1039 | case 0x10ec0269: | 1039 | case 0x10ec0269: |
| 1040 | case 0x10ec0272: | ||
| 1040 | case 0x10ec0660: | 1041 | case 0x10ec0660: |
| 1041 | case 0x10ec0662: | 1042 | case 0x10ec0662: |
| 1042 | case 0x10ec0663: | 1043 | case 0x10ec0663: |
| @@ -1065,6 +1066,7 @@ do_sku: | |||
| 1065 | case 0x10ec0882: | 1066 | case 0x10ec0882: |
| 1066 | case 0x10ec0883: | 1067 | case 0x10ec0883: |
| 1067 | case 0x10ec0885: | 1068 | case 0x10ec0885: |
| 1069 | case 0x10ec0887: | ||
| 1068 | case 0x10ec0889: | 1070 | case 0x10ec0889: |
| 1069 | snd_hda_codec_write(codec, 0x20, 0, | 1071 | snd_hda_codec_write(codec, 0x20, 0, |
| 1070 | AC_VERB_SET_COEF_INDEX, 7); | 1072 | AC_VERB_SET_COEF_INDEX, 7); |
| @@ -7012,6 +7014,7 @@ static int patch_alc882(struct hda_codec *codec) | |||
| 7012 | break; | 7014 | break; |
| 7013 | case 0x106b1000: /* iMac 24 */ | 7015 | case 0x106b1000: /* iMac 24 */ |
| 7014 | case 0x106b2800: /* AppleTV */ | 7016 | case 0x106b2800: /* AppleTV */ |
| 7017 | case 0x106b3e00: /* iMac 24 Aluminium */ | ||
| 7015 | board_config = ALC885_IMAC24; | 7018 | board_config = ALC885_IMAC24; |
| 7016 | break; | 7019 | break; |
| 7017 | case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */ | 7020 | case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */ |
| @@ -8514,6 +8517,8 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
| 8514 | SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD), | 8517 | SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD), |
| 8515 | SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), | 8518 | SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), |
| 8516 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), | 8519 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), |
| 8520 | SND_PCI_QUIRK(0x1734, 0x1107, "FSC AMILO Xi2550", | ||
| 8521 | ALC883_FUJITSU_PI2515), | ||
| 8517 | SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515), | 8522 | SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515), |
| 8518 | SND_PCI_QUIRK(0x1734, 0x113d, "Fujitsu AMILO Xa3530", | 8523 | SND_PCI_QUIRK(0x1734, 0x113d, "Fujitsu AMILO Xa3530", |
| 8519 | ALC888_FUJITSU_XA3530), | 8524 | ALC888_FUJITSU_XA3530), |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index b787b3cc096f..38428e22428f 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
| @@ -1804,6 +1804,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { | |||
| 1804 | "HP dv4", STAC_HP_DV5), | 1804 | "HP dv4", STAC_HP_DV5), |
| 1805 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fc, | 1805 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fc, |
| 1806 | "HP dv7", STAC_HP_M4), | 1806 | "HP dv7", STAC_HP_M4), |
| 1807 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3600, | ||
| 1808 | "HP dv5", STAC_HP_DV5), | ||
| 1807 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3603, | 1809 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3603, |
| 1808 | "HP dv5", STAC_HP_DV5), | 1810 | "HP dv5", STAC_HP_DV5), |
| 1809 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a, | 1811 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a, |
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 19d3391e229f..e900cdc84849 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
| @@ -617,7 +617,7 @@ static int snd_intel8x0_ali_codec_semaphore(struct intel8x0 *chip) | |||
| 617 | int time = 100; | 617 | int time = 100; |
| 618 | if (chip->buggy_semaphore) | 618 | if (chip->buggy_semaphore) |
| 619 | return 0; /* just ignore ... */ | 619 | return 0; /* just ignore ... */ |
| 620 | while (time-- && (igetdword(chip, ICHREG(ALI_CAS)) & ALI_CAS_SEM_BUSY)) | 620 | while (--time && (igetdword(chip, ICHREG(ALI_CAS)) & ALI_CAS_SEM_BUSY)) |
| 621 | udelay(1); | 621 | udelay(1); |
| 622 | if (! time && ! chip->in_ac97_init) | 622 | if (! time && ! chip->in_ac97_init) |
| 623 | snd_printk(KERN_WARNING "ali_codec_semaphore timeout\n"); | 623 | snd_printk(KERN_WARNING "ali_codec_semaphore timeout\n"); |
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c index c5d67900d666..ff0054b76502 100644 --- a/sound/soc/atmel/atmel_ssc_dai.c +++ b/sound/soc/atmel/atmel_ssc_dai.c | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | * Based on at91-ssc.c by | 10 | * Based on at91-ssc.c by |
| 11 | * Frank Mandarino <fmandarino@endrelia.com> | 11 | * Frank Mandarino <fmandarino@endrelia.com> |
| 12 | * Based on pxa2xx Platform drivers by | 12 | * Based on pxa2xx Platform drivers by |
| 13 | * Liam Girdwood <liam.girdwood@wolfsonmicro.com> | 13 | * Liam Girdwood <lrg@slimlogic.co.uk> |
| 14 | * | 14 | * |
| 15 | * This program is free software; you can redistribute it and/or modify | 15 | * This program is free software; you can redistribute it and/or modify |
| 16 | * it under the terms of the GNU General Public License as published by | 16 | * it under the terms of the GNU General Public License as published by |
diff --git a/sound/soc/atmel/atmel_ssc_dai.h b/sound/soc/atmel/atmel_ssc_dai.h index a828746e8a2f..391135f9c6c1 100644 --- a/sound/soc/atmel/atmel_ssc_dai.h +++ b/sound/soc/atmel/atmel_ssc_dai.h | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | * Based on at91-ssc.c by | 10 | * Based on at91-ssc.c by |
| 11 | * Frank Mandarino <fmandarino@endrelia.com> | 11 | * Frank Mandarino <fmandarino@endrelia.com> |
| 12 | * Based on pxa2xx Platform drivers by | 12 | * Based on pxa2xx Platform drivers by |
| 13 | * Liam Girdwood <liam.girdwood@wolfsonmicro.com> | 13 | * Liam Girdwood <lrg@slimlogic.co.uk> |
| 14 | * | 14 | * |
| 15 | * This program is free software; you can redistribute it and/or modify | 15 | * This program is free software; you can redistribute it and/or modify |
| 16 | * it under the terms of the GNU General Public License as published by | 16 | * it under the terms of the GNU General Public License as published by |
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index e3989d406f54..35d99750c383 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC. | 4 | * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC. |
| 5 | * | 5 | * |
| 6 | * Author: Liam Girdwood <lg@opensource.wolfsonmicro.com> | 6 | * Author: Liam Girdwood <lrg@slimlogic.co.uk> |
| 7 | * | 7 | * |
| 8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
| 9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index 5b5afc144478..1cbb7b9b51ce 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c | |||
| @@ -2,8 +2,7 @@ | |||
| 2 | * wm8990.c -- WM8990 ALSA Soc Audio driver | 2 | * wm8990.c -- WM8990 ALSA Soc Audio driver |
| 3 | * | 3 | * |
| 4 | * Copyright 2008 Wolfson Microelectronics PLC. | 4 | * Copyright 2008 Wolfson Microelectronics PLC. |
| 5 | * Author: Liam Girdwood | 5 | * Author: Liam Girdwood <lrg@slimlogic.co.uk> |
| 6 | * lg@opensource.wolfsonmicro.com or linux@wolfsonmicro.com | ||
| 7 | * | 6 | * |
| 8 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
| 9 | * under the terms of the GNU General Public License as published by the | 8 | * under the terms of the GNU General Public License as published by the |
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index b0362dfd5b71..dd3bb2933762 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c | |||
| @@ -175,9 +175,10 @@ static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
| 175 | { | 175 | { |
| 176 | struct snd_pcm_runtime *runtime = substream->runtime; | 176 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 177 | struct omap_runtime_data *prtd = runtime->private_data; | 177 | struct omap_runtime_data *prtd = runtime->private_data; |
| 178 | unsigned long flags; | ||
| 178 | int ret = 0; | 179 | int ret = 0; |
| 179 | 180 | ||
| 180 | spin_lock_irq(&prtd->lock); | 181 | spin_lock_irqsave(&prtd->lock, flags); |
| 181 | switch (cmd) { | 182 | switch (cmd) { |
| 182 | case SNDRV_PCM_TRIGGER_START: | 183 | case SNDRV_PCM_TRIGGER_START: |
| 183 | case SNDRV_PCM_TRIGGER_RESUME: | 184 | case SNDRV_PCM_TRIGGER_RESUME: |
| @@ -195,7 +196,7 @@ static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
| 195 | default: | 196 | default: |
| 196 | ret = -EINVAL; | 197 | ret = -EINVAL; |
| 197 | } | 198 | } |
| 198 | spin_unlock_irq(&prtd->lock); | 199 | spin_unlock_irqrestore(&prtd->lock, flags); |
| 199 | 200 | ||
| 200 | return ret; | 201 | return ret; |
| 201 | } | 202 | } |
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index c709b9563226..2ab83129d9b0 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c | |||
| @@ -2966,6 +2966,7 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip, | |||
| 2966 | return -EINVAL; | 2966 | return -EINVAL; |
| 2967 | } | 2967 | } |
| 2968 | alts = &iface->altsetting[fp->altset_idx]; | 2968 | alts = &iface->altsetting[fp->altset_idx]; |
| 2969 | fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); | ||
| 2969 | usb_set_interface(chip->dev, fp->iface, 0); | 2970 | usb_set_interface(chip->dev, fp->iface, 0); |
| 2970 | init_usb_pitch(chip->dev, fp->iface, alts, fp); | 2971 | init_usb_pitch(chip->dev, fp->iface, alts, fp); |
| 2971 | init_usb_sample_rate(chip->dev, fp->iface, alts, fp, fp->rate_max); | 2972 | init_usb_sample_rate(chip->dev, fp->iface, alts, fp, fp->rate_max); |
