diff options
124 files changed, 2491 insertions, 1488 deletions
diff --git a/.gitignore b/.gitignore index 8363e48cdcdc..fdcce40226d7 100644 --- a/.gitignore +++ b/.gitignore | |||
| @@ -53,3 +53,5 @@ cscope.* | |||
| 53 | 53 | ||
| 54 | *.orig | 54 | *.orig |
| 55 | *.rej | 55 | *.rej |
| 56 | *~ | ||
| 57 | \#*# | ||
diff --git a/Documentation/controllers/memory.txt b/Documentation/controllers/memory.txt index 6015347b41e2..866b9cd9a959 100644 --- a/Documentation/controllers/memory.txt +++ b/Documentation/controllers/memory.txt | |||
| @@ -1,4 +1,8 @@ | |||
| 1 | Memory Controller | 1 | Memory Resource Controller |
| 2 | |||
| 3 | NOTE: The Memory Resource Controller has been generically been referred | ||
| 4 | to as the memory controller in this document. Do not confuse memory controller | ||
| 5 | used here with the memory controller that is used in hardware. | ||
| 2 | 6 | ||
| 3 | Salient features | 7 | Salient features |
| 4 | 8 | ||
| @@ -152,7 +156,7 @@ The memory controller uses the following hierarchy | |||
| 152 | 156 | ||
| 153 | a. Enable CONFIG_CGROUPS | 157 | a. Enable CONFIG_CGROUPS |
| 154 | b. Enable CONFIG_RESOURCE_COUNTERS | 158 | b. Enable CONFIG_RESOURCE_COUNTERS |
| 155 | c. Enable CONFIG_CGROUP_MEM_CONT | 159 | c. Enable CONFIG_CGROUP_MEM_RES_CTLR |
| 156 | 160 | ||
| 157 | 1. Prepare the cgroups | 161 | 1. Prepare the cgroups |
| 158 | # mkdir -p /cgroups | 162 | # mkdir -p /cgroups |
| @@ -164,7 +168,7 @@ c. Enable CONFIG_CGROUP_MEM_CONT | |||
| 164 | 168 | ||
| 165 | Since now we're in the 0 cgroup, | 169 | Since now we're in the 0 cgroup, |
| 166 | We can alter the memory limit: | 170 | We can alter the memory limit: |
| 167 | # echo -n 4M > /cgroups/0/memory.limit_in_bytes | 171 | # echo 4M > /cgroups/0/memory.limit_in_bytes |
| 168 | 172 | ||
| 169 | NOTE: We can use a suffix (k, K, m, M, g or G) to indicate values in kilo, | 173 | NOTE: We can use a suffix (k, K, m, M, g or G) to indicate values in kilo, |
| 170 | mega or gigabytes. | 174 | mega or gigabytes. |
| @@ -185,7 +189,7 @@ number of factors, such as rounding up to page boundaries or the total | |||
| 185 | availability of memory on the system. The user is required to re-read | 189 | availability of memory on the system. The user is required to re-read |
| 186 | this file after a write to guarantee the value committed by the kernel. | 190 | this file after a write to guarantee the value committed by the kernel. |
| 187 | 191 | ||
| 188 | # echo -n 1 > memory.limit_in_bytes | 192 | # echo 1 > memory.limit_in_bytes |
| 189 | # cat memory.limit_in_bytes | 193 | # cat memory.limit_in_bytes |
| 190 | 4096 | 194 | 4096 |
| 191 | 195 | ||
| @@ -197,7 +201,7 @@ caches, RSS and Active pages/Inactive pages are shown. | |||
| 197 | 201 | ||
| 198 | The memory.force_empty gives an interface to drop *all* charges by force. | 202 | The memory.force_empty gives an interface to drop *all* charges by force. |
| 199 | 203 | ||
| 200 | # echo -n 1 > memory.force_empty | 204 | # echo 1 > memory.force_empty |
| 201 | 205 | ||
| 202 | will drop all charges in cgroup. Currently, this is maintained for test. | 206 | will drop all charges in cgroup. Currently, this is maintained for test. |
| 203 | 207 | ||
diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt index 8da724e2a0ff..54630095aa3c 100644 --- a/Documentation/gpio.txt +++ b/Documentation/gpio.txt | |||
| @@ -2,6 +2,9 @@ GPIO Interfaces | |||
| 2 | 2 | ||
| 3 | This provides an overview of GPIO access conventions on Linux. | 3 | This provides an overview of GPIO access conventions on Linux. |
| 4 | 4 | ||
| 5 | These calls use the gpio_* naming prefix. No other calls should use that | ||
| 6 | prefix, or the related __gpio_* prefix. | ||
| 7 | |||
| 5 | 8 | ||
| 6 | What is a GPIO? | 9 | What is a GPIO? |
| 7 | =============== | 10 | =============== |
| @@ -69,11 +72,13 @@ in this document, but drivers acting as clients to the GPIO interface must | |||
| 69 | not care how it's implemented.) | 72 | not care how it's implemented.) |
| 70 | 73 | ||
| 71 | That said, if the convention is supported on their platform, drivers should | 74 | That said, if the convention is supported on their platform, drivers should |
| 72 | use it when possible. Platforms should declare GENERIC_GPIO support in | 75 | use it when possible. Platforms must declare GENERIC_GPIO support in their |
| 73 | Kconfig (boolean true), which multi-platform drivers can depend on when | 76 | Kconfig (boolean true), and provide an <asm/gpio.h> file. Drivers that can't |
| 74 | using the include file: | 77 | work without standard GPIO calls should have Kconfig entries which depend |
| 78 | on GENERIC_GPIO. The GPIO calls are available, either as "real code" or as | ||
| 79 | optimized-away stubs, when drivers use the include file: | ||
| 75 | 80 | ||
| 76 | #include <asm/gpio.h> | 81 | #include <linux/gpio.h> |
| 77 | 82 | ||
| 78 | If you stick to this convention then it'll be easier for other developers to | 83 | If you stick to this convention then it'll be easier for other developers to |
| 79 | see what your code is doing, and help maintain it. | 84 | see what your code is doing, and help maintain it. |
| @@ -316,6 +321,9 @@ pulldowns integrated on some platforms. Not all platforms support them, | |||
| 316 | or support them in the same way; and any given board might use external | 321 | or support them in the same way; and any given board might use external |
| 317 | pullups (or pulldowns) so that the on-chip ones should not be used. | 322 | pullups (or pulldowns) so that the on-chip ones should not be used. |
| 318 | (When a circuit needs 5 kOhm, on-chip 100 kOhm resistors won't do.) | 323 | (When a circuit needs 5 kOhm, on-chip 100 kOhm resistors won't do.) |
| 324 | Likewise drive strength (2 mA vs 20 mA) and voltage (1.8V vs 3.3V) is a | ||
| 325 | platform-specific issue, as are models like (not) having a one-to-one | ||
| 326 | correspondence between configurable pins and GPIOs. | ||
| 319 | 327 | ||
| 320 | There are other system-specific mechanisms that are not specified here, | 328 | There are other system-specific mechanisms that are not specified here, |
| 321 | like the aforementioned options for input de-glitching and wire-OR output. | 329 | like the aforementioned options for input de-glitching and wire-OR output. |
diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt index 83f515c2905a..be89f393274f 100644 --- a/Documentation/kprobes.txt +++ b/Documentation/kprobes.txt | |||
| @@ -192,7 +192,8 @@ code mapping. | |||
| 192 | The Kprobes API includes a "register" function and an "unregister" | 192 | The Kprobes API includes a "register" function and an "unregister" |
| 193 | function for each type of probe. Here are terse, mini-man-page | 193 | function for each type of probe. Here are terse, mini-man-page |
| 194 | specifications for these functions and the associated probe handlers | 194 | specifications for these functions and the associated probe handlers |
| 195 | that you'll write. See the latter half of this document for examples. | 195 | that you'll write. See the files in the samples/kprobes/ sub-directory |
| 196 | for examples. | ||
| 196 | 197 | ||
| 197 | 4.1 register_kprobe | 198 | 4.1 register_kprobe |
| 198 | 199 | ||
| @@ -420,249 +421,15 @@ e. Watchpoint probes (which fire on data references). | |||
| 420 | 421 | ||
| 421 | 8. Kprobes Example | 422 | 8. Kprobes Example |
| 422 | 423 | ||
| 423 | Here's a sample kernel module showing the use of kprobes to dump a | 424 | See samples/kprobes/kprobe_example.c |
| 424 | stack trace and selected i386 registers when do_fork() is called. | ||
| 425 | ----- cut here ----- | ||
| 426 | /*kprobe_example.c*/ | ||
| 427 | #include <linux/kernel.h> | ||
| 428 | #include <linux/module.h> | ||
| 429 | #include <linux/kprobes.h> | ||
| 430 | #include <linux/sched.h> | ||
| 431 | |||
| 432 | /*For each probe you need to allocate a kprobe structure*/ | ||
| 433 | static struct kprobe kp; | ||
| 434 | |||
| 435 | /*kprobe pre_handler: called just before the probed instruction is executed*/ | ||
| 436 | int handler_pre(struct kprobe *p, struct pt_regs *regs) | ||
| 437 | { | ||
| 438 | printk("pre_handler: p->addr=0x%p, eip=%lx, eflags=0x%lx\n", | ||
| 439 | p->addr, regs->eip, regs->eflags); | ||
| 440 | dump_stack(); | ||
| 441 | return 0; | ||
| 442 | } | ||
| 443 | |||
| 444 | /*kprobe post_handler: called after the probed instruction is executed*/ | ||
| 445 | void handler_post(struct kprobe *p, struct pt_regs *regs, unsigned long flags) | ||
| 446 | { | ||
| 447 | printk("post_handler: p->addr=0x%p, eflags=0x%lx\n", | ||
| 448 | p->addr, regs->eflags); | ||
| 449 | } | ||
| 450 | |||
| 451 | /* fault_handler: this is called if an exception is generated for any | ||
| 452 | * instruction within the pre- or post-handler, or when Kprobes | ||
| 453 | * single-steps the probed instruction. | ||
| 454 | */ | ||
| 455 | int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr) | ||
| 456 | { | ||
| 457 | printk("fault_handler: p->addr=0x%p, trap #%dn", | ||
| 458 | p->addr, trapnr); | ||
| 459 | /* Return 0 because we don't handle the fault. */ | ||
| 460 | return 0; | ||
| 461 | } | ||
| 462 | |||
| 463 | static int __init kprobe_init(void) | ||
| 464 | { | ||
| 465 | int ret; | ||
| 466 | kp.pre_handler = handler_pre; | ||
| 467 | kp.post_handler = handler_post; | ||
| 468 | kp.fault_handler = handler_fault; | ||
| 469 | kp.symbol_name = "do_fork"; | ||
| 470 | |||
| 471 | ret = register_kprobe(&kp); | ||
| 472 | if (ret < 0) { | ||
| 473 | printk("register_kprobe failed, returned %d\n", ret); | ||
| 474 | return ret; | ||
| 475 | } | ||
| 476 | printk("kprobe registered\n"); | ||
| 477 | return 0; | ||
| 478 | } | ||
| 479 | |||
| 480 | static void __exit kprobe_exit(void) | ||
| 481 | { | ||
| 482 | unregister_kprobe(&kp); | ||
| 483 | printk("kprobe unregistered\n"); | ||
| 484 | } | ||
| 485 | |||
| 486 | module_init(kprobe_init) | ||
| 487 | module_exit(kprobe_exit) | ||
| 488 | MODULE_LICENSE("GPL"); | ||
| 489 | ----- cut here ----- | ||
| 490 | |||
| 491 | You can build the kernel module, kprobe-example.ko, using the following | ||
| 492 | Makefile: | ||
| 493 | ----- cut here ----- | ||
| 494 | obj-m := kprobe-example.o | ||
| 495 | KDIR := /lib/modules/$(shell uname -r)/build | ||
| 496 | PWD := $(shell pwd) | ||
| 497 | default: | ||
| 498 | $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules | ||
| 499 | clean: | ||
| 500 | rm -f *.mod.c *.ko *.o | ||
| 501 | ----- cut here ----- | ||
| 502 | |||
| 503 | $ make | ||
| 504 | $ su - | ||
| 505 | ... | ||
| 506 | # insmod kprobe-example.ko | ||
| 507 | |||
| 508 | You will see the trace data in /var/log/messages and on the console | ||
| 509 | whenever do_fork() is invoked to create a new process. | ||
| 510 | 425 | ||
| 511 | 9. Jprobes Example | 426 | 9. Jprobes Example |
| 512 | 427 | ||
| 513 | Here's a sample kernel module showing the use of jprobes to dump | 428 | See samples/kprobes/jprobe_example.c |
| 514 | the arguments of do_fork(). | ||
| 515 | ----- cut here ----- | ||
| 516 | /*jprobe-example.c */ | ||
| 517 | #include <linux/kernel.h> | ||
| 518 | #include <linux/module.h> | ||
| 519 | #include <linux/fs.h> | ||
| 520 | #include <linux/uio.h> | ||
| 521 | #include <linux/kprobes.h> | ||
| 522 | |||
| 523 | /* | ||
| 524 | * Jumper probe for do_fork. | ||
| 525 | * Mirror principle enables access to arguments of the probed routine | ||
| 526 | * from the probe handler. | ||
| 527 | */ | ||
| 528 | |||
| 529 | /* Proxy routine having the same arguments as actual do_fork() routine */ | ||
| 530 | long jdo_fork(unsigned long clone_flags, unsigned long stack_start, | ||
| 531 | struct pt_regs *regs, unsigned long stack_size, | ||
| 532 | int __user * parent_tidptr, int __user * child_tidptr) | ||
| 533 | { | ||
| 534 | printk("jprobe: clone_flags=0x%lx, stack_size=0x%lx, regs=0x%p\n", | ||
| 535 | clone_flags, stack_size, regs); | ||
| 536 | /* Always end with a call to jprobe_return(). */ | ||
| 537 | jprobe_return(); | ||
| 538 | /*NOTREACHED*/ | ||
| 539 | return 0; | ||
| 540 | } | ||
| 541 | |||
| 542 | static struct jprobe my_jprobe = { | ||
| 543 | .entry = jdo_fork | ||
| 544 | }; | ||
| 545 | |||
| 546 | static int __init jprobe_init(void) | ||
| 547 | { | ||
| 548 | int ret; | ||
| 549 | my_jprobe.kp.symbol_name = "do_fork"; | ||
| 550 | |||
| 551 | if ((ret = register_jprobe(&my_jprobe)) <0) { | ||
| 552 | printk("register_jprobe failed, returned %d\n", ret); | ||
| 553 | return -1; | ||
| 554 | } | ||
| 555 | printk("Planted jprobe at %p, handler addr %p\n", | ||
| 556 | my_jprobe.kp.addr, my_jprobe.entry); | ||
| 557 | return 0; | ||
| 558 | } | ||
| 559 | |||
| 560 | static void __exit jprobe_exit(void) | ||
| 561 | { | ||
| 562 | unregister_jprobe(&my_jprobe); | ||
| 563 | printk("jprobe unregistered\n"); | ||
| 564 | } | ||
| 565 | |||
| 566 | module_init(jprobe_init) | ||
| 567 | module_exit(jprobe_exit) | ||
| 568 | MODULE_LICENSE("GPL"); | ||
| 569 | ----- cut here ----- | ||
| 570 | |||
| 571 | Build and insert the kernel module as shown in the above kprobe | ||
| 572 | example. You will see the trace data in /var/log/messages and on | ||
| 573 | the console whenever do_fork() is invoked to create a new process. | ||
| 574 | (Some messages may be suppressed if syslogd is configured to | ||
| 575 | eliminate duplicate messages.) | ||
| 576 | 429 | ||
| 577 | 10. Kretprobes Example | 430 | 10. Kretprobes Example |
| 578 | 431 | ||
| 579 | Here's a sample kernel module showing the use of return probes to | 432 | See samples/kprobes/kretprobe_example.c |
| 580 | report failed calls to sys_open(). | ||
| 581 | ----- cut here ----- | ||
| 582 | /*kretprobe-example.c*/ | ||
| 583 | #include <linux/kernel.h> | ||
| 584 | #include <linux/module.h> | ||
| 585 | #include <linux/kprobes.h> | ||
| 586 | #include <linux/ktime.h> | ||
| 587 | |||
| 588 | /* per-instance private data */ | ||
| 589 | struct my_data { | ||
| 590 | ktime_t entry_stamp; | ||
| 591 | }; | ||
| 592 | |||
| 593 | static const char *probed_func = "sys_open"; | ||
| 594 | |||
| 595 | /* Timestamp function entry. */ | ||
| 596 | static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs) | ||
| 597 | { | ||
| 598 | struct my_data *data; | ||
| 599 | |||
| 600 | if(!current->mm) | ||
| 601 | return 1; /* skip kernel threads */ | ||
| 602 | |||
| 603 | data = (struct my_data *)ri->data; | ||
| 604 | data->entry_stamp = ktime_get(); | ||
| 605 | return 0; | ||
| 606 | } | ||
| 607 | |||
| 608 | /* If the probed function failed, log the return value and duration. | ||
| 609 | * Duration may turn out to be zero consistently, depending upon the | ||
| 610 | * granularity of time accounting on the platform. */ | ||
| 611 | static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs) | ||
| 612 | { | ||
| 613 | int retval = regs_return_value(regs); | ||
| 614 | struct my_data *data = (struct my_data *)ri->data; | ||
| 615 | s64 delta; | ||
| 616 | ktime_t now; | ||
| 617 | |||
| 618 | if (retval < 0) { | ||
| 619 | now = ktime_get(); | ||
| 620 | delta = ktime_to_ns(ktime_sub(now, data->entry_stamp)); | ||
| 621 | printk("%s: return val = %d (duration = %lld ns)\n", | ||
| 622 | probed_func, retval, delta); | ||
| 623 | } | ||
| 624 | return 0; | ||
| 625 | } | ||
| 626 | |||
| 627 | static struct kretprobe my_kretprobe = { | ||
| 628 | .handler = return_handler, | ||
| 629 | .entry_handler = entry_handler, | ||
| 630 | .data_size = sizeof(struct my_data), | ||
| 631 | .maxactive = 20, /* probe up to 20 instances concurrently */ | ||
| 632 | }; | ||
| 633 | |||
| 634 | static int __init kretprobe_init(void) | ||
| 635 | { | ||
| 636 | int ret; | ||
| 637 | my_kretprobe.kp.symbol_name = (char *)probed_func; | ||
| 638 | |||
| 639 | if ((ret = register_kretprobe(&my_kretprobe)) < 0) { | ||
| 640 | printk("register_kretprobe failed, returned %d\n", ret); | ||
| 641 | return -1; | ||
| 642 | } | ||
| 643 | printk("Kretprobe active on %s\n", my_kretprobe.kp.symbol_name); | ||
| 644 | return 0; | ||
| 645 | } | ||
| 646 | |||
| 647 | static void __exit kretprobe_exit(void) | ||
| 648 | { | ||
| 649 | unregister_kretprobe(&my_kretprobe); | ||
| 650 | printk("kretprobe unregistered\n"); | ||
| 651 | /* nmissed > 0 suggests that maxactive was set too low. */ | ||
| 652 | printk("Missed probing %d instances of %s\n", | ||
| 653 | my_kretprobe.nmissed, probed_func); | ||
| 654 | } | ||
| 655 | |||
| 656 | module_init(kretprobe_init) | ||
| 657 | module_exit(kretprobe_exit) | ||
| 658 | MODULE_LICENSE("GPL"); | ||
| 659 | ----- cut here ----- | ||
| 660 | |||
| 661 | Build and insert the kernel module as shown in the above kprobe | ||
| 662 | example. You will see the trace data in /var/log/messages and on the | ||
| 663 | console whenever sys_open() returns a negative value. (Some messages | ||
| 664 | may be suppressed if syslogd is configured to eliminate duplicate | ||
| 665 | messages.) | ||
| 666 | 433 | ||
| 667 | For additional information on Kprobes, refer to the following URLs: | 434 | For additional information on Kprobes, refer to the following URLs: |
| 668 | http://www-106.ibm.com/developerworks/library/l-kprobes.html?ca=dgr-lnxw42Kprobe | 435 | http://www-106.ibm.com/developerworks/library/l-kprobes.html?ca=dgr-lnxw42Kprobe |
diff --git a/Documentation/pci.txt b/Documentation/pci.txt index 72b20c639596..bb7bd27d4682 100644 --- a/Documentation/pci.txt +++ b/Documentation/pci.txt | |||
| @@ -123,7 +123,8 @@ initialization with a pointer to a structure describing the driver | |||
| 123 | 123 | ||
| 124 | 124 | ||
| 125 | The ID table is an array of struct pci_device_id entries ending with an | 125 | The ID table is an array of struct pci_device_id entries ending with an |
| 126 | all-zero entry. Each entry consists of: | 126 | all-zero entry; use of the macro DECLARE_PCI_DEVICE_TABLE is the preferred |
| 127 | method of declaring the table. Each entry consists of: | ||
| 127 | 128 | ||
| 128 | vendor,device Vendor and device ID to match (or PCI_ANY_ID) | 129 | vendor,device Vendor and device ID to match (or PCI_ANY_ID) |
| 129 | 130 | ||
| @@ -191,7 +192,8 @@ Tips on when/where to use the above attributes: | |||
| 191 | 192 | ||
| 192 | o Do not mark the struct pci_driver. | 193 | o Do not mark the struct pci_driver. |
| 193 | 194 | ||
| 194 | o The ID table array should be marked __devinitdata. | 195 | o The ID table array should be marked __devinitconst; this is done |
| 196 | automatically if the table is declared with DECLARE_PCI_DEVICE_TABLE(). | ||
| 195 | 197 | ||
| 196 | o The probe() and remove() functions should be marked __devinit | 198 | o The probe() and remove() functions should be marked __devinit |
| 197 | and __devexit respectively. All initialization functions | 199 | and __devexit respectively. All initialization functions |
diff --git a/MAINTAINERS b/MAINTAINERS index a0f78e764329..558636e3a954 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -1138,6 +1138,12 @@ L: accessrunner-general@lists.sourceforge.net | |||
| 1138 | W: http://accessrunner.sourceforge.net/ | 1138 | W: http://accessrunner.sourceforge.net/ |
| 1139 | S: Maintained | 1139 | S: Maintained |
| 1140 | 1140 | ||
| 1141 | CONTROL GROUPS (CGROUPS) | ||
| 1142 | P: Paul Menage | ||
| 1143 | M: menage@google.com | ||
| 1144 | L: containers@lists.linux-foundation.org | ||
| 1145 | S: Maintained | ||
| 1146 | |||
| 1141 | CORETEMP HARDWARE MONITORING DRIVER | 1147 | CORETEMP HARDWARE MONITORING DRIVER |
| 1142 | P: Rudolf Marek | 1148 | P: Rudolf Marek |
| 1143 | M: r.marek@assembler.cz | 1149 | M: r.marek@assembler.cz |
| @@ -2633,6 +2639,17 @@ L: linux-kernel@vger.kernel.org | |||
| 2633 | W: http://www.linux-mm.org | 2639 | W: http://www.linux-mm.org |
| 2634 | S: Maintained | 2640 | S: Maintained |
| 2635 | 2641 | ||
| 2642 | MEMORY RESOURCE CONTROLLER | ||
| 2643 | P: Balbir Singh | ||
| 2644 | M: balbir@linux.vnet.ibm.com | ||
| 2645 | P: Pavel Emelyanov | ||
| 2646 | M: xemul@openvz.org | ||
| 2647 | P: KAMEZAWA Hiroyuki | ||
| 2648 | M: kamezawa.hiroyu@jp.fujitsu.com | ||
| 2649 | L: linux-mm@kvack.org | ||
| 2650 | L: linux-kernel@vger.kernel.org | ||
| 2651 | S: Maintained | ||
| 2652 | |||
| 2636 | MEI MN10300/AM33 PORT | 2653 | MEI MN10300/AM33 PORT |
| 2637 | P: David Howells | 2654 | P: David Howells |
| 2638 | M: dhowells@redhat.com | 2655 | M: dhowells@redhat.com |
diff --git a/arch/Kconfig b/arch/Kconfig index 3d72dc3fc8f5..694c9af520bb 100644 --- a/arch/Kconfig +++ b/arch/Kconfig | |||
| @@ -27,5 +27,12 @@ config KPROBES | |||
| 27 | for kernel debugging, non-intrusive instrumentation and testing. | 27 | for kernel debugging, non-intrusive instrumentation and testing. |
| 28 | If in doubt, say "N". | 28 | If in doubt, say "N". |
| 29 | 29 | ||
| 30 | config KRETPROBES | ||
| 31 | def_bool y | ||
| 32 | depends on KPROBES && HAVE_KRETPROBES | ||
| 33 | |||
| 30 | config HAVE_KPROBES | 34 | config HAVE_KPROBES |
| 31 | def_bool n | 35 | def_bool n |
| 36 | |||
| 37 | config HAVE_KRETPROBES | ||
| 38 | def_bool n | ||
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c index 26d3789dfdd0..be6fa105cd34 100644 --- a/arch/alpha/kernel/pci_iommu.c +++ b/arch/alpha/kernel/pci_iommu.c | |||
| @@ -31,7 +31,6 @@ | |||
| 31 | #endif | 31 | #endif |
| 32 | 32 | ||
| 33 | #define DEBUG_NODIRECT 0 | 33 | #define DEBUG_NODIRECT 0 |
| 34 | #define DEBUG_FORCEDAC 0 | ||
| 35 | 34 | ||
| 36 | #define ISA_DMA_MASK 0x00ffffff | 35 | #define ISA_DMA_MASK 0x00ffffff |
| 37 | 36 | ||
| @@ -126,39 +125,67 @@ iommu_arena_new(struct pci_controller *hose, dma_addr_t base, | |||
| 126 | return iommu_arena_new_node(0, hose, base, window_size, align); | 125 | return iommu_arena_new_node(0, hose, base, window_size, align); |
| 127 | } | 126 | } |
| 128 | 127 | ||
| 128 | static inline int is_span_boundary(unsigned int index, unsigned int nr, | ||
| 129 | unsigned long shift, | ||
| 130 | unsigned long boundary_size) | ||
| 131 | { | ||
| 132 | shift = (shift + index) & (boundary_size - 1); | ||
| 133 | return shift + nr > boundary_size; | ||
| 134 | } | ||
| 135 | |||
| 129 | /* Must be called with the arena lock held */ | 136 | /* Must be called with the arena lock held */ |
| 130 | static long | 137 | static long |
| 131 | iommu_arena_find_pages(struct pci_iommu_arena *arena, long n, long mask) | 138 | iommu_arena_find_pages(struct device *dev, struct pci_iommu_arena *arena, |
| 139 | long n, long mask) | ||
| 132 | { | 140 | { |
| 133 | unsigned long *ptes; | 141 | unsigned long *ptes; |
| 134 | long i, p, nent; | 142 | long i, p, nent; |
| 143 | int pass = 0; | ||
| 144 | unsigned long base; | ||
| 145 | unsigned long boundary_size; | ||
| 146 | |||
| 147 | BUG_ON(arena->dma_base & ~PAGE_MASK); | ||
| 148 | base = arena->dma_base >> PAGE_SHIFT; | ||
| 149 | if (dev) | ||
| 150 | boundary_size = ALIGN(dma_get_max_seg_size(dev) + 1, PAGE_SIZE) | ||
| 151 | >> PAGE_SHIFT; | ||
| 152 | else | ||
| 153 | boundary_size = ALIGN(1UL << 32, PAGE_SIZE) >> PAGE_SHIFT; | ||
| 154 | |||
| 155 | BUG_ON(!is_power_of_2(boundary_size)); | ||
| 135 | 156 | ||
| 136 | /* Search forward for the first mask-aligned sequence of N free ptes */ | 157 | /* Search forward for the first mask-aligned sequence of N free ptes */ |
| 137 | ptes = arena->ptes; | 158 | ptes = arena->ptes; |
| 138 | nent = arena->size >> PAGE_SHIFT; | 159 | nent = arena->size >> PAGE_SHIFT; |
| 139 | p = (arena->next_entry + mask) & ~mask; | 160 | p = ALIGN(arena->next_entry, mask + 1); |
| 140 | i = 0; | 161 | i = 0; |
| 162 | |||
| 163 | again: | ||
| 141 | while (i < n && p+i < nent) { | 164 | while (i < n && p+i < nent) { |
| 165 | if (!i && is_span_boundary(p, n, base, boundary_size)) { | ||
| 166 | p = ALIGN(p + 1, mask + 1); | ||
| 167 | goto again; | ||
| 168 | } | ||
| 169 | |||
| 142 | if (ptes[p+i]) | 170 | if (ptes[p+i]) |
| 143 | p = (p + i + 1 + mask) & ~mask, i = 0; | 171 | p = ALIGN(p + i + 1, mask + 1), i = 0; |
| 144 | else | 172 | else |
| 145 | i = i + 1; | 173 | i = i + 1; |
| 146 | } | 174 | } |
| 147 | 175 | ||
| 148 | if (i < n) { | 176 | if (i < n) { |
| 149 | /* Reached the end. Flush the TLB and restart the | 177 | if (pass < 1) { |
| 150 | search from the beginning. */ | 178 | /* |
| 151 | alpha_mv.mv_pci_tbi(arena->hose, 0, -1); | 179 | * Reached the end. Flush the TLB and restart |
| 152 | 180 | * the search from the beginning. | |
| 153 | p = 0, i = 0; | 181 | */ |
| 154 | while (i < n && p+i < nent) { | 182 | alpha_mv.mv_pci_tbi(arena->hose, 0, -1); |
| 155 | if (ptes[p+i]) | 183 | |
| 156 | p = (p + i + 1 + mask) & ~mask, i = 0; | 184 | pass++; |
| 157 | else | 185 | p = 0; |
| 158 | i = i + 1; | 186 | i = 0; |
| 159 | } | 187 | goto again; |
| 160 | 188 | } else | |
| 161 | if (i < n) | ||
| 162 | return -1; | 189 | return -1; |
| 163 | } | 190 | } |
| 164 | 191 | ||
| @@ -168,7 +195,8 @@ iommu_arena_find_pages(struct pci_iommu_arena *arena, long n, long mask) | |||
| 168 | } | 195 | } |
| 169 | 196 | ||
| 170 | static long | 197 | static long |
| 171 | iommu_arena_alloc(struct pci_iommu_arena *arena, long n, unsigned int align) | 198 | iommu_arena_alloc(struct device *dev, struct pci_iommu_arena *arena, long n, |
| 199 | unsigned int align) | ||
| 172 | { | 200 | { |
| 173 | unsigned long flags; | 201 | unsigned long flags; |
| 174 | unsigned long *ptes; | 202 | unsigned long *ptes; |
| @@ -179,7 +207,7 @@ iommu_arena_alloc(struct pci_iommu_arena *arena, long n, unsigned int align) | |||
| 179 | /* Search for N empty ptes */ | 207 | /* Search for N empty ptes */ |
| 180 | ptes = arena->ptes; | 208 | ptes = arena->ptes; |
| 181 | mask = max(align, arena->align_entry) - 1; | 209 | mask = max(align, arena->align_entry) - 1; |
| 182 | p = iommu_arena_find_pages(arena, n, mask); | 210 | p = iommu_arena_find_pages(dev, arena, n, mask); |
| 183 | if (p < 0) { | 211 | if (p < 0) { |
| 184 | spin_unlock_irqrestore(&arena->lock, flags); | 212 | spin_unlock_irqrestore(&arena->lock, flags); |
| 185 | return -1; | 213 | return -1; |
| @@ -229,6 +257,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size, | |||
| 229 | unsigned long paddr; | 257 | unsigned long paddr; |
| 230 | dma_addr_t ret; | 258 | dma_addr_t ret; |
| 231 | unsigned int align = 0; | 259 | unsigned int align = 0; |
| 260 | struct device *dev = pdev ? &pdev->dev : NULL; | ||
| 232 | 261 | ||
| 233 | paddr = __pa(cpu_addr); | 262 | paddr = __pa(cpu_addr); |
| 234 | 263 | ||
| @@ -276,7 +305,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size, | |||
| 276 | /* Force allocation to 64KB boundary for ISA bridges. */ | 305 | /* Force allocation to 64KB boundary for ISA bridges. */ |
| 277 | if (pdev && pdev == isa_bridge) | 306 | if (pdev && pdev == isa_bridge) |
| 278 | align = 8; | 307 | align = 8; |
| 279 | dma_ofs = iommu_arena_alloc(arena, npages, align); | 308 | dma_ofs = iommu_arena_alloc(dev, arena, npages, align); |
| 280 | if (dma_ofs < 0) { | 309 | if (dma_ofs < 0) { |
| 281 | printk(KERN_WARNING "pci_map_single failed: " | 310 | printk(KERN_WARNING "pci_map_single failed: " |
| 282 | "could not allocate dma page tables\n"); | 311 | "could not allocate dma page tables\n"); |
| @@ -563,7 +592,7 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end, | |||
| 563 | 592 | ||
| 564 | paddr &= ~PAGE_MASK; | 593 | paddr &= ~PAGE_MASK; |
| 565 | npages = calc_npages(paddr + size); | 594 | npages = calc_npages(paddr + size); |
| 566 | dma_ofs = iommu_arena_alloc(arena, npages, 0); | 595 | dma_ofs = iommu_arena_alloc(dev, arena, npages, 0); |
| 567 | if (dma_ofs < 0) { | 596 | if (dma_ofs < 0) { |
| 568 | /* If we attempted a direct map above but failed, die. */ | 597 | /* If we attempted a direct map above but failed, die. */ |
| 569 | if (leader->dma_address == 0) | 598 | if (leader->dma_address == 0) |
| @@ -830,7 +859,7 @@ iommu_reserve(struct pci_iommu_arena *arena, long pg_count, long align_mask) | |||
| 830 | 859 | ||
| 831 | /* Search for N empty ptes. */ | 860 | /* Search for N empty ptes. */ |
| 832 | ptes = arena->ptes; | 861 | ptes = arena->ptes; |
| 833 | p = iommu_arena_find_pages(arena, pg_count, align_mask); | 862 | p = iommu_arena_find_pages(NULL, arena, pg_count, align_mask); |
| 834 | if (p < 0) { | 863 | if (p < 0) { |
| 835 | spin_unlock_irqrestore(&arena->lock, flags); | 864 | spin_unlock_irqrestore(&arena->lock, flags); |
| 836 | return -1; | 865 | return -1; |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 16b82e1272b0..955fc53c1c01 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
| @@ -12,6 +12,7 @@ config ARM | |||
| 12 | select SYS_SUPPORTS_APM_EMULATION | 12 | select SYS_SUPPORTS_APM_EMULATION |
| 13 | select HAVE_OPROFILE | 13 | select HAVE_OPROFILE |
| 14 | select HAVE_KPROBES if (!XIP_KERNEL) | 14 | select HAVE_KPROBES if (!XIP_KERNEL) |
| 15 | select HAVE_KRETPROBES if (HAVE_KPROBES) | ||
| 15 | help | 16 | help |
| 16 | The ARM series is a line of low-power-consumption RISC chip designs | 17 | The ARM series is a line of low-power-consumption RISC chip designs |
| 17 | licensed by ARM Ltd and targeted at embedded applications and | 18 | licensed by ARM Ltd and targeted at embedded applications and |
diff --git a/arch/cris/arch-v10/kernel/time.c b/arch/cris/arch-v10/kernel/time.c index 9310a7b476e9..525483f0ddf8 100644 --- a/arch/cris/arch-v10/kernel/time.c +++ b/arch/cris/arch-v10/kernel/time.c | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | #include <linux/swap.h> | 13 | #include <linux/swap.h> |
| 14 | #include <linux/sched.h> | 14 | #include <linux/sched.h> |
| 15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
| 16 | #include <linux/vmstat.h> | 16 | #include <linux/mm.h> |
| 17 | #include <asm/arch/svinto.h> | 17 | #include <asm/arch/svinto.h> |
| 18 | #include <asm/types.h> | 18 | #include <asm/types.h> |
| 19 | #include <asm/signal.h> | 19 | #include <asm/signal.h> |
diff --git a/arch/cris/arch-v10/lib/string.c b/arch/cris/arch-v10/lib/string.c index 7161a2bef4fe..c7bd6ebdc93c 100644 --- a/arch/cris/arch-v10/lib/string.c +++ b/arch/cris/arch-v10/lib/string.c | |||
| @@ -1,55 +1,59 @@ | |||
| 1 | /*#************************************************************************#*/ | 1 | /* A memcpy for CRIS. |
| 2 | /*#-------------------------------------------------------------------------*/ | 2 | Copyright (C) 1994-2005 Axis Communications. |
| 3 | /*# */ | 3 | All rights reserved. |
| 4 | /*# FUNCTION NAME: memcpy() */ | 4 | |
| 5 | /*# */ | 5 | Redistribution and use in source and binary forms, with or without |
| 6 | /*# PARAMETERS: void* dst; Destination address. */ | 6 | modification, are permitted provided that the following conditions |
| 7 | /*# void* src; Source address. */ | 7 | are met: |
| 8 | /*# int len; Number of bytes to copy. */ | 8 | |
| 9 | /*# */ | 9 | 1. Redistributions of source code must retain the above copyright |
| 10 | /*# RETURNS: dst. */ | 10 | notice, this list of conditions and the following disclaimer. |
| 11 | /*# */ | 11 | |
| 12 | /*# DESCRIPTION: Copies len bytes of memory from src to dst. No guarantees */ | 12 | 2. Neither the name of Axis Communications nor the names of its |
| 13 | /*# about copying of overlapping memory areas. This routine is */ | 13 | contributors may be used to endorse or promote products derived |
| 14 | /*# very sensitive to compiler changes in register allocation. */ | 14 | from this software without specific prior written permission. |
| 15 | /*# Should really be rewritten to avoid this problem. */ | 15 | |
| 16 | /*# */ | 16 | THIS SOFTWARE IS PROVIDED BY AXIS COMMUNICATIONS AND ITS CONTRIBUTORS |
| 17 | /*#-------------------------------------------------------------------------*/ | 17 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 18 | /*# */ | 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 19 | /*# HISTORY */ | 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AXIS |
| 20 | /*# */ | 20 | COMMUNICATIONS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| 21 | /*# DATE NAME CHANGES */ | 21 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 22 | /*# ---- ---- ------- */ | 22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| 23 | /*# 941007 Kenny R Creation */ | 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 24 | /*# 941011 Kenny R Lots of optimizations and inlining. */ | 24 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
| 25 | /*# 941129 Ulf A Adapted for use in libc. */ | 25 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
| 26 | /*# 950216 HP N==0 forgotten if non-aligned src/dst. */ | 26 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 27 | /*# Added some optimizations. */ | 27 | POSSIBILITY OF SUCH DAMAGE. */ |
| 28 | /*# 001025 HP Make src and dst char *. Align dst to */ | 28 | |
| 29 | /*# dword, not just word-if-both-src-and-dst- */ | 29 | /* FIXME: This file should really only be used for reference, as the |
| 30 | /*# are-misaligned. */ | 30 | result is somewhat depending on gcc generating what we expect rather |
| 31 | /*# */ | 31 | than what we describe. An assembly file should be used instead. */ |
| 32 | /*#-------------------------------------------------------------------------*/ | 32 | |
| 33 | 33 | #include <stddef.h> | |
| 34 | #include <linux/types.h> | 34 | |
| 35 | 35 | /* Break even between movem and move16 is really at 38.7 * 2, but | |
| 36 | void *memcpy(void *pdst, | 36 | modulo 44, so up to the next multiple of 44, we use ordinary code. */ |
| 37 | const void *psrc, | 37 | #define MEMCPY_BY_BLOCK_THRESHOLD (44 * 2) |
| 38 | size_t pn) | 38 | |
| 39 | /* No name ambiguities in this file. */ | ||
| 40 | __asm__ (".syntax no_register_prefix"); | ||
| 41 | |||
| 42 | void * | ||
| 43 | memcpy(void *pdst, const void *psrc, size_t pn) | ||
| 39 | { | 44 | { |
| 40 | /* Ok. Now we want the parameters put in special registers. | 45 | /* Now we want the parameters put in special registers. |
| 41 | Make sure the compiler is able to make something useful of this. | 46 | Make sure the compiler is able to make something useful of this. |
| 42 | As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop). | 47 | As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop). |
| 43 | 48 | ||
| 44 | If gcc was alright, it really would need no temporaries, and no | 49 | If gcc was allright, it really would need no temporaries, and no |
| 45 | stack space to save stuff on. */ | 50 | stack space to save stuff on. */ |
| 46 | 51 | ||
| 47 | register void *return_dst __asm__ ("r10") = pdst; | 52 | register void *return_dst __asm__ ("r10") = pdst; |
| 48 | register char *dst __asm__ ("r13") = pdst; | 53 | register unsigned char *dst __asm__ ("r13") = pdst; |
| 49 | register const char *src __asm__ ("r11") = psrc; | 54 | register unsigned const char *src __asm__ ("r11") = psrc; |
| 50 | register int n __asm__ ("r12") = pn; | 55 | register int n __asm__ ("r12") = pn; |
| 51 | 56 | ||
| 52 | |||
| 53 | /* When src is aligned but not dst, this makes a few extra needless | 57 | /* When src is aligned but not dst, this makes a few extra needless |
| 54 | cycles. I believe it would take as many to check that the | 58 | cycles. I believe it would take as many to check that the |
| 55 | re-alignment was unnecessary. */ | 59 | re-alignment was unnecessary. */ |
| @@ -59,167 +63,174 @@ void *memcpy(void *pdst, | |||
| 59 | && n >= 3) | 63 | && n >= 3) |
| 60 | { | 64 | { |
| 61 | if ((unsigned long) dst & 1) | 65 | if ((unsigned long) dst & 1) |
| 62 | { | 66 | { |
| 63 | n--; | 67 | n--; |
| 64 | *(char*)dst = *(char*)src; | 68 | *dst = *src; |
| 65 | src++; | 69 | src++; |
| 66 | dst++; | 70 | dst++; |
| 67 | } | 71 | } |
| 68 | 72 | ||
| 69 | if ((unsigned long) dst & 2) | 73 | if ((unsigned long) dst & 2) |
| 70 | { | 74 | { |
| 71 | n -= 2; | 75 | n -= 2; |
| 72 | *(short*)dst = *(short*)src; | 76 | *(short *) dst = *(short *) src; |
| 73 | src += 2; | 77 | src += 2; |
| 74 | dst += 2; | 78 | dst += 2; |
| 75 | } | 79 | } |
| 76 | } | 80 | } |
| 77 | 81 | ||
| 78 | /* Decide which copying method to use. */ | 82 | /* Decide which copying method to use. */ |
| 79 | if (n >= 44*2) /* Break even between movem and | 83 | if (n >= MEMCPY_BY_BLOCK_THRESHOLD) |
| 80 | move16 is at 38.7*2, but modulo 44. */ | 84 | { |
| 81 | { | 85 | /* It is not optimal to tell the compiler about clobbering any |
| 82 | /* For large copies we use 'movem' */ | 86 | registers; that will move the saving/restoring of those registers |
| 83 | 87 | to the function prologue/epilogue, and make non-movem sizes | |
| 84 | /* It is not optimal to tell the compiler about clobbering any | 88 | suboptimal. */ |
| 85 | registers; that will move the saving/restoring of those registers | 89 | __asm__ volatile |
| 86 | to the function prologue/epilogue, and make non-movem sizes | 90 | ("\ |
| 87 | suboptimal. | 91 | ;; GCC does promise correct register allocations, but let's \n\ |
| 88 | 92 | ;; make sure it keeps its promises. \n\ | |
| 89 | This method is not foolproof; it assumes that the "asm reg" | 93 | .ifnc %0-%1-%2,$r13-$r11-$r12 \n\ |
| 90 | declarations at the beginning of the function really are used | 94 | .error \"GCC reg alloc bug: %0-%1-%4 != $r13-$r12-$r11\" \n\ |
| 91 | here (beware: they may be moved to temporary registers). | 95 | .endif \n\ |
| 92 | This way, we do not have to save/move the registers around into | 96 | \n\ |
| 93 | temporaries; we can safely use them straight away. | 97 | ;; Save the registers we'll use in the movem process \n\ |
| 94 | 98 | ;; on the stack. \n\ | |
| 95 | If you want to check that the allocation was right; then | 99 | subq 11*4,sp \n\ |
| 96 | check the equalities in the first comment. It should say | 100 | movem r10,[sp] \n\ |
| 97 | "r13=r13, r11=r11, r12=r12" */ | ||
| 98 | __asm__ volatile ("\n\ | ||
| 99 | ;; Check that the following is true (same register names on \n\ | ||
| 100 | ;; both sides of equal sign, as in r8=r8): \n\ | ||
| 101 | ;; %0=r13, %1=r11, %2=r12 \n\ | ||
| 102 | ;; \n\ | ||
| 103 | ;; Save the registers we'll use in the movem process \n\ | ||
| 104 | ;; on the stack. \n\ | ||
| 105 | subq 11*4,$sp \n\ | ||
| 106 | movem $r10,[$sp] \n\ | ||
| 107 | \n\ | 101 | \n\ |
| 108 | ;; Now we've got this: \n\ | 102 | ;; Now we've got this: \n\ |
| 109 | ;; r11 - src \n\ | 103 | ;; r11 - src \n\ |
| 110 | ;; r13 - dst \n\ | 104 | ;; r13 - dst \n\ |
| 111 | ;; r12 - n \n\ | 105 | ;; r12 - n \n\ |
| 112 | \n\ | 106 | \n\ |
| 113 | ;; Update n for the first loop \n\ | 107 | ;; Update n for the first loop. \n\ |
| 114 | subq 44,$r12 \n\ | 108 | subq 44,r12 \n\ |
| 115 | 0: \n\ | 109 | 0: \n\ |
| 116 | movem [$r11+],$r10 \n\ | 110 | " |
| 117 | subq 44,$r12 \n\ | 111 | #ifdef __arch_common_v10_v32 |
| 118 | bge 0b \n\ | 112 | /* Cater to branch offset difference between v32 and v10. We |
| 119 | movem $r10,[$r13+] \n\ | 113 | assume the branch below has an 8-bit offset. */ |
| 114 | " setf\n" | ||
| 115 | #endif | ||
| 116 | " movem [r11+],r10 \n\ | ||
| 117 | subq 44,r12 \n\ | ||
| 118 | bge 0b \n\ | ||
| 119 | movem r10,[r13+] \n\ | ||
| 120 | \n\ | 120 | \n\ |
| 121 | addq 44,$r12 ;; compensate for last loop underflowing n \n\ | 121 | ;; Compensate for last loop underflowing n. \n\ |
| 122 | addq 44,r12 \n\ | ||
| 122 | \n\ | 123 | \n\ |
| 123 | ;; Restore registers from stack \n\ | 124 | ;; Restore registers from stack. \n\ |
| 124 | movem [$sp+],$r10" | 125 | movem [sp+],r10" |
| 125 | 126 | ||
| 126 | /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n) | 127 | /* Outputs. */ |
| 127 | /* Inputs */ : "0" (dst), "1" (src), "2" (n)); | 128 | : "=r" (dst), "=r" (src), "=r" (n) |
| 128 | |||
| 129 | } | ||
| 130 | 129 | ||
| 131 | /* Either we directly starts copying, using dword copying | 130 | /* Inputs. */ |
| 132 | in a loop, or we copy as much as possible with 'movem' | 131 | : "0" (dst), "1" (src), "2" (n)); |
| 133 | and then the last block (<44 bytes) is copied here. | 132 | } |
| 134 | This will work since 'movem' will have updated src,dst,n. */ | ||
| 135 | 133 | ||
| 136 | while ( n >= 16 ) | 134 | while (n >= 16) |
| 137 | { | 135 | { |
| 138 | *((long*)dst)++ = *((long*)src)++; | 136 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 139 | *((long*)dst)++ = *((long*)src)++; | 137 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 140 | *((long*)dst)++ = *((long*)src)++; | 138 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 141 | *((long*)dst)++ = *((long*)src)++; | 139 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 142 | n -= 16; | 140 | |
| 143 | } | 141 | n -= 16; |
| 142 | } | ||
| 144 | 143 | ||
| 145 | /* A switch() is definitely the fastest although it takes a LOT of code. | ||
| 146 | * Particularly if you inline code this. | ||
| 147 | */ | ||
| 148 | switch (n) | 144 | switch (n) |
| 149 | { | 145 | { |
| 150 | case 0: | 146 | case 0: |
| 151 | break; | 147 | break; |
| 148 | |||
| 152 | case 1: | 149 | case 1: |
| 153 | *(char*)dst = *(char*)src; | 150 | *dst = *src; |
| 154 | break; | 151 | break; |
| 152 | |||
| 155 | case 2: | 153 | case 2: |
| 156 | *(short*)dst = *(short*)src; | 154 | *(short *) dst = *(short *) src; |
| 157 | break; | 155 | break; |
| 156 | |||
| 158 | case 3: | 157 | case 3: |
| 159 | *((short*)dst)++ = *((short*)src)++; | 158 | *(short *) dst = *(short *) src; dst += 2; src += 2; |
| 160 | *(char*)dst = *(char*)src; | 159 | *dst = *src; |
| 161 | break; | 160 | break; |
| 161 | |||
| 162 | case 4: | 162 | case 4: |
| 163 | *((long*)dst)++ = *((long*)src)++; | 163 | *(long *) dst = *(long *) src; |
| 164 | break; | 164 | break; |
| 165 | |||
| 165 | case 5: | 166 | case 5: |
| 166 | *((long*)dst)++ = *((long*)src)++; | 167 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 167 | *(char*)dst = *(char*)src; | 168 | *dst = *src; |
| 168 | break; | 169 | break; |
| 170 | |||
| 169 | case 6: | 171 | case 6: |
| 170 | *((long*)dst)++ = *((long*)src)++; | 172 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 171 | *(short*)dst = *(short*)src; | 173 | *(short *) dst = *(short *) src; |
| 172 | break; | 174 | break; |
| 175 | |||
| 173 | case 7: | 176 | case 7: |
| 174 | *((long*)dst)++ = *((long*)src)++; | 177 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 175 | *((short*)dst)++ = *((short*)src)++; | 178 | *(short *) dst = *(short *) src; dst += 2; src += 2; |
| 176 | *(char*)dst = *(char*)src; | 179 | *dst = *src; |
| 177 | break; | 180 | break; |
| 181 | |||
| 178 | case 8: | 182 | case 8: |
| 179 | *((long*)dst)++ = *((long*)src)++; | 183 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 180 | *((long*)dst)++ = *((long*)src)++; | 184 | *(long *) dst = *(long *) src; |
| 181 | break; | 185 | break; |
| 186 | |||
| 182 | case 9: | 187 | case 9: |
| 183 | *((long*)dst)++ = *((long*)src)++; | 188 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 184 | *((long*)dst)++ = *((long*)src)++; | 189 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 185 | *(char*)dst = *(char*)src; | 190 | *dst = *src; |
| 186 | break; | 191 | break; |
| 192 | |||
| 187 | case 10: | 193 | case 10: |
| 188 | *((long*)dst)++ = *((long*)src)++; | 194 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 189 | *((long*)dst)++ = *((long*)src)++; | 195 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 190 | *(short*)dst = *(short*)src; | 196 | *(short *) dst = *(short *) src; |
| 191 | break; | 197 | break; |
| 198 | |||
| 192 | case 11: | 199 | case 11: |
| 193 | *((long*)dst)++ = *((long*)src)++; | 200 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 194 | *((long*)dst)++ = *((long*)src)++; | 201 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 195 | *((short*)dst)++ = *((short*)src)++; | 202 | *(short *) dst = *(short *) src; dst += 2; src += 2; |
| 196 | *(char*)dst = *(char*)src; | 203 | *dst = *src; |
| 197 | break; | 204 | break; |
| 205 | |||
| 198 | case 12: | 206 | case 12: |
| 199 | *((long*)dst)++ = *((long*)src)++; | 207 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 200 | *((long*)dst)++ = *((long*)src)++; | 208 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 201 | *((long*)dst)++ = *((long*)src)++; | 209 | *(long *) dst = *(long *) src; |
| 202 | break; | 210 | break; |
| 211 | |||
| 203 | case 13: | 212 | case 13: |
| 204 | *((long*)dst)++ = *((long*)src)++; | 213 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 205 | *((long*)dst)++ = *((long*)src)++; | 214 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 206 | *((long*)dst)++ = *((long*)src)++; | 215 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 207 | *(char*)dst = *(char*)src; | 216 | *dst = *src; |
| 208 | break; | 217 | break; |
| 218 | |||
| 209 | case 14: | 219 | case 14: |
| 210 | *((long*)dst)++ = *((long*)src)++; | 220 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 211 | *((long*)dst)++ = *((long*)src)++; | 221 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 212 | *((long*)dst)++ = *((long*)src)++; | 222 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 213 | *(short*)dst = *(short*)src; | 223 | *(short *) dst = *(short *) src; |
| 214 | break; | 224 | break; |
| 225 | |||
| 215 | case 15: | 226 | case 15: |
| 216 | *((long*)dst)++ = *((long*)src)++; | 227 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 217 | *((long*)dst)++ = *((long*)src)++; | 228 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 218 | *((long*)dst)++ = *((long*)src)++; | 229 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 219 | *((short*)dst)++ = *((short*)src)++; | 230 | *(short *) dst = *(short *) src; dst += 2; src += 2; |
| 220 | *(char*)dst = *(char*)src; | 231 | *dst = *src; |
| 221 | break; | 232 | break; |
| 222 | } | 233 | } |
| 223 | 234 | ||
| 224 | return return_dst; /* destination pointer. */ | 235 | return return_dst; |
| 225 | } /* memcpy() */ | 236 | } |
diff --git a/arch/cris/arch-v10/lib/usercopy.c b/arch/cris/arch-v10/lib/usercopy.c index b8e6c0430e5b..b0a608da7bd1 100644 --- a/arch/cris/arch-v10/lib/usercopy.c +++ b/arch/cris/arch-v10/lib/usercopy.c | |||
| @@ -193,7 +193,7 @@ __copy_user (void __user *pdst, const void *psrc, unsigned long pn) | |||
| 193 | inaccessible. */ | 193 | inaccessible. */ |
| 194 | 194 | ||
| 195 | unsigned long | 195 | unsigned long |
| 196 | __copy_user_zeroing (void __user *pdst, const void *psrc, unsigned long pn) | 196 | __copy_user_zeroing(void *pdst, const void __user *psrc, unsigned long pn) |
| 197 | { | 197 | { |
| 198 | /* We want the parameters put in special registers. | 198 | /* We want the parameters put in special registers. |
| 199 | Make sure the compiler is able to make something useful of this. | 199 | Make sure the compiler is able to make something useful of this. |
diff --git a/arch/cris/arch-v32/lib/string.c b/arch/cris/arch-v32/lib/string.c index 6740b2cebae5..c7bd6ebdc93c 100644 --- a/arch/cris/arch-v32/lib/string.c +++ b/arch/cris/arch-v32/lib/string.c | |||
| @@ -1,55 +1,59 @@ | |||
| 1 | /*#************************************************************************#*/ | 1 | /* A memcpy for CRIS. |
| 2 | /*#-------------------------------------------------------------------------*/ | 2 | Copyright (C) 1994-2005 Axis Communications. |
| 3 | /*# */ | 3 | All rights reserved. |
| 4 | /*# FUNCTION NAME: memcpy() */ | 4 | |
| 5 | /*# */ | 5 | Redistribution and use in source and binary forms, with or without |
| 6 | /*# PARAMETERS: void* dst; Destination address. */ | 6 | modification, are permitted provided that the following conditions |
| 7 | /*# void* src; Source address. */ | 7 | are met: |
| 8 | /*# int len; Number of bytes to copy. */ | 8 | |
| 9 | /*# */ | 9 | 1. Redistributions of source code must retain the above copyright |
| 10 | /*# RETURNS: dst. */ | 10 | notice, this list of conditions and the following disclaimer. |
| 11 | /*# */ | 11 | |
| 12 | /*# DESCRIPTION: Copies len bytes of memory from src to dst. No guarantees */ | 12 | 2. Neither the name of Axis Communications nor the names of its |
| 13 | /*# about copying of overlapping memory areas. This routine is */ | 13 | contributors may be used to endorse or promote products derived |
| 14 | /*# very sensitive to compiler changes in register allocation. */ | 14 | from this software without specific prior written permission. |
| 15 | /*# Should really be rewritten to avoid this problem. */ | 15 | |
| 16 | /*# */ | 16 | THIS SOFTWARE IS PROVIDED BY AXIS COMMUNICATIONS AND ITS CONTRIBUTORS |
| 17 | /*#-------------------------------------------------------------------------*/ | 17 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 18 | /*# */ | 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 19 | /*# HISTORY */ | 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AXIS |
| 20 | /*# */ | 20 | COMMUNICATIONS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| 21 | /*# DATE NAME CHANGES */ | 21 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 22 | /*# ---- ---- ------- */ | 22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| 23 | /*# 941007 Kenny R Creation */ | 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 24 | /*# 941011 Kenny R Lots of optimizations and inlining. */ | 24 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
| 25 | /*# 941129 Ulf A Adapted for use in libc. */ | 25 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
| 26 | /*# 950216 HP N==0 forgotten if non-aligned src/dst. */ | 26 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 27 | /*# Added some optimizations. */ | 27 | POSSIBILITY OF SUCH DAMAGE. */ |
| 28 | /*# 001025 HP Make src and dst char *. Align dst to */ | 28 | |
| 29 | /*# dword, not just word-if-both-src-and-dst- */ | 29 | /* FIXME: This file should really only be used for reference, as the |
| 30 | /*# are-misaligned. */ | 30 | result is somewhat depending on gcc generating what we expect rather |
| 31 | /*# */ | 31 | than what we describe. An assembly file should be used instead. */ |
| 32 | /*#-------------------------------------------------------------------------*/ | 32 | |
| 33 | 33 | #include <stddef.h> | |
| 34 | #include <linux/types.h> | 34 | |
| 35 | 35 | /* Break even between movem and move16 is really at 38.7 * 2, but | |
| 36 | void *memcpy(void *pdst, | 36 | modulo 44, so up to the next multiple of 44, we use ordinary code. */ |
| 37 | const void *psrc, | 37 | #define MEMCPY_BY_BLOCK_THRESHOLD (44 * 2) |
| 38 | size_t pn) | 38 | |
| 39 | /* No name ambiguities in this file. */ | ||
| 40 | __asm__ (".syntax no_register_prefix"); | ||
| 41 | |||
| 42 | void * | ||
| 43 | memcpy(void *pdst, const void *psrc, size_t pn) | ||
| 39 | { | 44 | { |
| 40 | /* Ok. Now we want the parameters put in special registers. | 45 | /* Now we want the parameters put in special registers. |
| 41 | Make sure the compiler is able to make something useful of this. | 46 | Make sure the compiler is able to make something useful of this. |
| 42 | As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop). | 47 | As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop). |
| 43 | 48 | ||
| 44 | If gcc was alright, it really would need no temporaries, and no | 49 | If gcc was allright, it really would need no temporaries, and no |
| 45 | stack space to save stuff on. */ | 50 | stack space to save stuff on. */ |
| 46 | 51 | ||
| 47 | register void *return_dst __asm__ ("r10") = pdst; | 52 | register void *return_dst __asm__ ("r10") = pdst; |
| 48 | register char *dst __asm__ ("r13") = pdst; | 53 | register unsigned char *dst __asm__ ("r13") = pdst; |
| 49 | register const char *src __asm__ ("r11") = psrc; | 54 | register unsigned const char *src __asm__ ("r11") = psrc; |
| 50 | register int n __asm__ ("r12") = pn; | 55 | register int n __asm__ ("r12") = pn; |
| 51 | 56 | ||
| 52 | |||
| 53 | /* When src is aligned but not dst, this makes a few extra needless | 57 | /* When src is aligned but not dst, this makes a few extra needless |
| 54 | cycles. I believe it would take as many to check that the | 58 | cycles. I believe it would take as many to check that the |
| 55 | re-alignment was unnecessary. */ | 59 | re-alignment was unnecessary. */ |
| @@ -59,161 +63,174 @@ void *memcpy(void *pdst, | |||
| 59 | && n >= 3) | 63 | && n >= 3) |
| 60 | { | 64 | { |
| 61 | if ((unsigned long) dst & 1) | 65 | if ((unsigned long) dst & 1) |
| 62 | { | 66 | { |
| 63 | n--; | 67 | n--; |
| 64 | *(char*)dst = *(char*)src; | 68 | *dst = *src; |
| 65 | src++; | 69 | src++; |
| 66 | dst++; | 70 | dst++; |
| 67 | } | 71 | } |
| 68 | 72 | ||
| 69 | if ((unsigned long) dst & 2) | 73 | if ((unsigned long) dst & 2) |
| 70 | { | 74 | { |
| 71 | n -= 2; | 75 | n -= 2; |
| 72 | *(short*)dst = *(short*)src; | 76 | *(short *) dst = *(short *) src; |
| 73 | src += 2; | 77 | src += 2; |
| 74 | dst += 2; | 78 | dst += 2; |
| 75 | } | 79 | } |
| 76 | } | 80 | } |
| 77 | 81 | ||
| 78 | /* Decide which copying method to use. Movem is dirt cheap, so the | 82 | /* Decide which copying method to use. */ |
| 79 | overheap is low enough to always use the minimum block size as the | 83 | if (n >= MEMCPY_BY_BLOCK_THRESHOLD) |
| 80 | threshold. */ | 84 | { |
| 81 | if (n >= 44) | 85 | /* It is not optimal to tell the compiler about clobbering any |
| 82 | { | 86 | registers; that will move the saving/restoring of those registers |
| 83 | /* For large copies we use 'movem' */ | 87 | to the function prologue/epilogue, and make non-movem sizes |
| 84 | 88 | suboptimal. */ | |
| 85 | /* It is not optimal to tell the compiler about clobbering any | 89 | __asm__ volatile |
| 86 | registers; that will move the saving/restoring of those registers | 90 | ("\ |
| 87 | to the function prologue/epilogue, and make non-movem sizes | 91 | ;; GCC does promise correct register allocations, but let's \n\ |
| 88 | suboptimal. */ | 92 | ;; make sure it keeps its promises. \n\ |
| 89 | __asm__ volatile (" \n\ | 93 | .ifnc %0-%1-%2,$r13-$r11-$r12 \n\ |
| 90 | ;; Check that the register asm declaration got right. \n\ | 94 | .error \"GCC reg alloc bug: %0-%1-%4 != $r13-$r12-$r11\" \n\ |
| 91 | ;; The GCC manual explicitly says TRT will happen. \n\ | 95 | .endif \n\ |
| 92 | .ifnc %0-%1-%2,$r13-$r11-$r12 \n\ | ||
| 93 | .err \n\ | ||
| 94 | .endif \n\ | ||
| 95 | \n\ | ||
| 96 | ;; Save the registers we'll use in the movem process \n\ | ||
| 97 | \n\ | 96 | \n\ |
| 98 | ;; on the stack. \n\ | 97 | ;; Save the registers we'll use in the movem process \n\ |
| 99 | subq 11*4,$sp \n\ | 98 | ;; on the stack. \n\ |
| 100 | movem $r10,[$sp] \n\ | 99 | subq 11*4,sp \n\ |
| 100 | movem r10,[sp] \n\ | ||
| 101 | \n\ | 101 | \n\ |
| 102 | ;; Now we've got this: \n\ | 102 | ;; Now we've got this: \n\ |
| 103 | ;; r11 - src \n\ | 103 | ;; r11 - src \n\ |
| 104 | ;; r13 - dst \n\ | 104 | ;; r13 - dst \n\ |
| 105 | ;; r12 - n \n\ | 105 | ;; r12 - n \n\ |
| 106 | \n\ | 106 | \n\ |
| 107 | ;; Update n for the first loop \n\ | 107 | ;; Update n for the first loop. \n\ |
| 108 | subq 44,$r12 \n\ | 108 | subq 44,r12 \n\ |
| 109 | 0: \n\ | 109 | 0: \n\ |
| 110 | movem [$r11+],$r10 \n\ | 110 | " |
| 111 | subq 44,$r12 \n\ | 111 | #ifdef __arch_common_v10_v32 |
| 112 | bge 0b \n\ | 112 | /* Cater to branch offset difference between v32 and v10. We |
| 113 | movem $r10,[$r13+] \n\ | 113 | assume the branch below has an 8-bit offset. */ |
| 114 | " setf\n" | ||
| 115 | #endif | ||
| 116 | " movem [r11+],r10 \n\ | ||
| 117 | subq 44,r12 \n\ | ||
| 118 | bge 0b \n\ | ||
| 119 | movem r10,[r13+] \n\ | ||
| 114 | \n\ | 120 | \n\ |
| 115 | addq 44,$r12 ;; compensate for last loop underflowing n \n\ | 121 | ;; Compensate for last loop underflowing n. \n\ |
| 122 | addq 44,r12 \n\ | ||
| 116 | \n\ | 123 | \n\ |
| 117 | ;; Restore registers from stack \n\ | 124 | ;; Restore registers from stack. \n\ |
| 118 | movem [$sp+],$r10" | 125 | movem [sp+],r10" |
| 119 | 126 | ||
| 120 | /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n) | 127 | /* Outputs. */ |
| 121 | /* Inputs */ : "0" (dst), "1" (src), "2" (n)); | 128 | : "=r" (dst), "=r" (src), "=r" (n) |
| 122 | 129 | ||
| 123 | } | 130 | /* Inputs. */ |
| 131 | : "0" (dst), "1" (src), "2" (n)); | ||
| 132 | } | ||
| 124 | 133 | ||
| 125 | /* Either we directly starts copying, using dword copying | 134 | while (n >= 16) |
| 126 | in a loop, or we copy as much as possible with 'movem' | 135 | { |
| 127 | and then the last block (<44 bytes) is copied here. | 136 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 128 | This will work since 'movem' will have updated src,dst,n. */ | 137 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 138 | *(long *) dst = *(long *) src; dst += 4; src += 4; | ||
| 139 | *(long *) dst = *(long *) src; dst += 4; src += 4; | ||
| 129 | 140 | ||
| 130 | while ( n >= 16 ) | 141 | n -= 16; |
| 131 | { | 142 | } |
| 132 | *((long*)dst)++ = *((long*)src)++; | ||
| 133 | *((long*)dst)++ = *((long*)src)++; | ||
| 134 | *((long*)dst)++ = *((long*)src)++; | ||
| 135 | *((long*)dst)++ = *((long*)src)++; | ||
| 136 | n -= 16; | ||
| 137 | } | ||
| 138 | 143 | ||
| 139 | /* A switch() is definitely the fastest although it takes a LOT of code. | ||
| 140 | * Particularly if you inline code this. | ||
| 141 | */ | ||
| 142 | switch (n) | 144 | switch (n) |
| 143 | { | 145 | { |
| 144 | case 0: | 146 | case 0: |
| 145 | break; | 147 | break; |
| 148 | |||
| 146 | case 1: | 149 | case 1: |
| 147 | *(char*)dst = *(char*)src; | 150 | *dst = *src; |
| 148 | break; | 151 | break; |
| 152 | |||
| 149 | case 2: | 153 | case 2: |
| 150 | *(short*)dst = *(short*)src; | 154 | *(short *) dst = *(short *) src; |
| 151 | break; | 155 | break; |
| 156 | |||
| 152 | case 3: | 157 | case 3: |
| 153 | *((short*)dst)++ = *((short*)src)++; | 158 | *(short *) dst = *(short *) src; dst += 2; src += 2; |
| 154 | *(char*)dst = *(char*)src; | 159 | *dst = *src; |
| 155 | break; | 160 | break; |
| 161 | |||
| 156 | case 4: | 162 | case 4: |
| 157 | *((long*)dst)++ = *((long*)src)++; | 163 | *(long *) dst = *(long *) src; |
| 158 | break; | 164 | break; |
| 165 | |||
| 159 | case 5: | 166 | case 5: |
| 160 | *((long*)dst)++ = *((long*)src)++; | 167 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 161 | *(char*)dst = *(char*)src; | 168 | *dst = *src; |
| 162 | break; | 169 | break; |
| 170 | |||
| 163 | case 6: | 171 | case 6: |
| 164 | *((long*)dst)++ = *((long*)src)++; | 172 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 165 | *(short*)dst = *(short*)src; | 173 | *(short *) dst = *(short *) src; |
| 166 | break; | 174 | break; |
| 175 | |||
| 167 | case 7: | 176 | case 7: |
| 168 | *((long*)dst)++ = *((long*)src)++; | 177 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 169 | *((short*)dst)++ = *((short*)src)++; | 178 | *(short *) dst = *(short *) src; dst += 2; src += 2; |
| 170 | *(char*)dst = *(char*)src; | 179 | *dst = *src; |
| 171 | break; | 180 | break; |
| 181 | |||
| 172 | case 8: | 182 | case 8: |
| 173 | *((long*)dst)++ = *((long*)src)++; | 183 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 174 | *((long*)dst)++ = *((long*)src)++; | 184 | *(long *) dst = *(long *) src; |
| 175 | break; | 185 | break; |
| 186 | |||
| 176 | case 9: | 187 | case 9: |
| 177 | *((long*)dst)++ = *((long*)src)++; | 188 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 178 | *((long*)dst)++ = *((long*)src)++; | 189 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 179 | *(char*)dst = *(char*)src; | 190 | *dst = *src; |
| 180 | break; | 191 | break; |
| 192 | |||
| 181 | case 10: | 193 | case 10: |
| 182 | *((long*)dst)++ = *((long*)src)++; | 194 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 183 | *((long*)dst)++ = *((long*)src)++; | 195 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 184 | *(short*)dst = *(short*)src; | 196 | *(short *) dst = *(short *) src; |
| 185 | break; | 197 | break; |
| 198 | |||
| 186 | case 11: | 199 | case 11: |
| 187 | *((long*)dst)++ = *((long*)src)++; | 200 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 188 | *((long*)dst)++ = *((long*)src)++; | 201 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 189 | *((short*)dst)++ = *((short*)src)++; | 202 | *(short *) dst = *(short *) src; dst += 2; src += 2; |
| 190 | *(char*)dst = *(char*)src; | 203 | *dst = *src; |
| 191 | break; | 204 | break; |
| 205 | |||
| 192 | case 12: | 206 | case 12: |
| 193 | *((long*)dst)++ = *((long*)src)++; | 207 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 194 | *((long*)dst)++ = *((long*)src)++; | 208 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 195 | *((long*)dst)++ = *((long*)src)++; | 209 | *(long *) dst = *(long *) src; |
| 196 | break; | 210 | break; |
| 211 | |||
| 197 | case 13: | 212 | case 13: |
| 198 | *((long*)dst)++ = *((long*)src)++; | 213 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 199 | *((long*)dst)++ = *((long*)src)++; | 214 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 200 | *((long*)dst)++ = *((long*)src)++; | 215 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 201 | *(char*)dst = *(char*)src; | 216 | *dst = *src; |
| 202 | break; | 217 | break; |
| 218 | |||
| 203 | case 14: | 219 | case 14: |
| 204 | *((long*)dst)++ = *((long*)src)++; | 220 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 205 | *((long*)dst)++ = *((long*)src)++; | 221 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 206 | *((long*)dst)++ = *((long*)src)++; | 222 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 207 | *(short*)dst = *(short*)src; | 223 | *(short *) dst = *(short *) src; |
| 208 | break; | 224 | break; |
| 225 | |||
| 209 | case 15: | 226 | case 15: |
| 210 | *((long*)dst)++ = *((long*)src)++; | 227 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 211 | *((long*)dst)++ = *((long*)src)++; | 228 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 212 | *((long*)dst)++ = *((long*)src)++; | 229 | *(long *) dst = *(long *) src; dst += 4; src += 4; |
| 213 | *((short*)dst)++ = *((short*)src)++; | 230 | *(short *) dst = *(short *) src; dst += 2; src += 2; |
| 214 | *(char*)dst = *(char*)src; | 231 | *dst = *src; |
| 215 | break; | 232 | break; |
| 216 | } | 233 | } |
| 217 | 234 | ||
| 218 | return return_dst; /* destination pointer. */ | 235 | return return_dst; |
| 219 | } /* memcpy() */ | 236 | } |
diff --git a/arch/cris/arch-v32/lib/usercopy.c b/arch/cris/arch-v32/lib/usercopy.c index 04d0cf35a276..0b5b70d5f58a 100644 --- a/arch/cris/arch-v32/lib/usercopy.c +++ b/arch/cris/arch-v32/lib/usercopy.c | |||
| @@ -161,7 +161,7 @@ __copy_user (void __user *pdst, const void *psrc, unsigned long pn) | |||
| 161 | inaccessible. */ | 161 | inaccessible. */ |
| 162 | 162 | ||
| 163 | unsigned long | 163 | unsigned long |
| 164 | __copy_user_zeroing (void __user *pdst, const void *psrc, unsigned long pn) | 164 | __copy_user_zeroing(void *pdst, const void __user *psrc, unsigned long pn) |
| 165 | { | 165 | { |
| 166 | /* We want the parameters put in special registers. | 166 | /* We want the parameters put in special registers. |
| 167 | Make sure the compiler is able to make something useful of this. | 167 | Make sure the compiler is able to make something useful of this. |
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index dff9edfc7465..56762d3c2a6a 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig | |||
| @@ -18,6 +18,7 @@ config IA64 | |||
| 18 | select HAVE_IDE | 18 | select HAVE_IDE |
| 19 | select HAVE_OPROFILE | 19 | select HAVE_OPROFILE |
| 20 | select HAVE_KPROBES | 20 | select HAVE_KPROBES |
| 21 | select HAVE_KRETPROBES | ||
| 21 | default y | 22 | default y |
| 22 | help | 23 | help |
| 23 | The Itanium Processor Family is Intel's 64-bit successor to | 24 | The Itanium Processor Family is Intel's 64-bit successor to |
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 5b8d8382b762..1189d8d6170d 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
| @@ -90,6 +90,7 @@ config PPC | |||
| 90 | select HAVE_IDE | 90 | select HAVE_IDE |
| 91 | select HAVE_OPROFILE | 91 | select HAVE_OPROFILE |
| 92 | select HAVE_KPROBES | 92 | select HAVE_KPROBES |
| 93 | select HAVE_KRETPROBES | ||
| 93 | 94 | ||
| 94 | config EARLY_PRINTK | 95 | config EARLY_PRINTK |
| 95 | bool | 96 | bool |
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index b21444b681b6..9892827b6176 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
| @@ -61,6 +61,7 @@ config S390 | |||
| 61 | def_bool y | 61 | def_bool y |
| 62 | select HAVE_OPROFILE | 62 | select HAVE_OPROFILE |
| 63 | select HAVE_KPROBES | 63 | select HAVE_KPROBES |
| 64 | select HAVE_KRETPROBES | ||
| 64 | 65 | ||
| 65 | source "init/Kconfig" | 66 | source "init/Kconfig" |
| 66 | 67 | ||
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index 3af378ddb6ae..463d1be32c98 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig | |||
| @@ -10,6 +10,7 @@ config SPARC | |||
| 10 | default y | 10 | default y |
| 11 | select HAVE_OPROFILE | 11 | select HAVE_OPROFILE |
| 12 | select HAVE_KPROBES | 12 | select HAVE_KPROBES |
| 13 | select HAVE_KRETPROBES | ||
| 13 | 14 | ||
| 14 | config SPARC64 | 15 | config SPARC64 |
| 15 | bool | 16 | bool |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 53800b80a204..f41c9538ca30 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
| @@ -21,6 +21,7 @@ config X86 | |||
| 21 | select HAVE_IDE | 21 | select HAVE_IDE |
| 22 | select HAVE_OPROFILE | 22 | select HAVE_OPROFILE |
| 23 | select HAVE_KPROBES | 23 | select HAVE_KPROBES |
| 24 | select HAVE_KRETPROBES | ||
| 24 | select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64) | 25 | select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64) |
| 25 | 26 | ||
| 26 | 27 | ||
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 674cd66dcaba..18feb1c7c33b 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
| @@ -849,7 +849,8 @@ static int pkt_flush_cache(struct pktcdvd_device *pd) | |||
| 849 | /* | 849 | /* |
| 850 | * speed is given as the normal factor, e.g. 4 for 4x | 850 | * speed is given as the normal factor, e.g. 4 for 4x |
| 851 | */ | 851 | */ |
| 852 | static int pkt_set_speed(struct pktcdvd_device *pd, unsigned write_speed, unsigned read_speed) | 852 | static noinline_for_stack int pkt_set_speed(struct pktcdvd_device *pd, |
| 853 | unsigned write_speed, unsigned read_speed) | ||
| 853 | { | 854 | { |
| 854 | struct packet_command cgc; | 855 | struct packet_command cgc; |
| 855 | struct request_sense sense; | 856 | struct request_sense sense; |
| @@ -1776,7 +1777,8 @@ static int pkt_get_track_info(struct pktcdvd_device *pd, __u16 track, __u8 type, | |||
| 1776 | return pkt_generic_packet(pd, &cgc); | 1777 | return pkt_generic_packet(pd, &cgc); |
| 1777 | } | 1778 | } |
| 1778 | 1779 | ||
| 1779 | static int pkt_get_last_written(struct pktcdvd_device *pd, long *last_written) | 1780 | static noinline_for_stack int pkt_get_last_written(struct pktcdvd_device *pd, |
| 1781 | long *last_written) | ||
| 1780 | { | 1782 | { |
| 1781 | disc_information di; | 1783 | disc_information di; |
| 1782 | track_information ti; | 1784 | track_information ti; |
| @@ -1813,7 +1815,7 @@ static int pkt_get_last_written(struct pktcdvd_device *pd, long *last_written) | |||
| 1813 | /* | 1815 | /* |
| 1814 | * write mode select package based on pd->settings | 1816 | * write mode select package based on pd->settings |
| 1815 | */ | 1817 | */ |
| 1816 | static int pkt_set_write_settings(struct pktcdvd_device *pd) | 1818 | static noinline_for_stack int pkt_set_write_settings(struct pktcdvd_device *pd) |
| 1817 | { | 1819 | { |
| 1818 | struct packet_command cgc; | 1820 | struct packet_command cgc; |
| 1819 | struct request_sense sense; | 1821 | struct request_sense sense; |
| @@ -1972,7 +1974,7 @@ static int pkt_writable_disc(struct pktcdvd_device *pd, disc_information *di) | |||
| 1972 | return 1; | 1974 | return 1; |
| 1973 | } | 1975 | } |
| 1974 | 1976 | ||
| 1975 | static int pkt_probe_settings(struct pktcdvd_device *pd) | 1977 | static noinline_for_stack int pkt_probe_settings(struct pktcdvd_device *pd) |
| 1976 | { | 1978 | { |
| 1977 | struct packet_command cgc; | 1979 | struct packet_command cgc; |
| 1978 | unsigned char buf[12]; | 1980 | unsigned char buf[12]; |
| @@ -2071,7 +2073,8 @@ static int pkt_probe_settings(struct pktcdvd_device *pd) | |||
| 2071 | /* | 2073 | /* |
| 2072 | * enable/disable write caching on drive | 2074 | * enable/disable write caching on drive |
| 2073 | */ | 2075 | */ |
| 2074 | static int pkt_write_caching(struct pktcdvd_device *pd, int set) | 2076 | static noinline_for_stack int pkt_write_caching(struct pktcdvd_device *pd, |
| 2077 | int set) | ||
| 2075 | { | 2078 | { |
| 2076 | struct packet_command cgc; | 2079 | struct packet_command cgc; |
| 2077 | struct request_sense sense; | 2080 | struct request_sense sense; |
| @@ -2116,7 +2119,8 @@ static int pkt_lock_door(struct pktcdvd_device *pd, int lockflag) | |||
| 2116 | /* | 2119 | /* |
| 2117 | * Returns drive maximum write speed | 2120 | * Returns drive maximum write speed |
| 2118 | */ | 2121 | */ |
| 2119 | static int pkt_get_max_speed(struct pktcdvd_device *pd, unsigned *write_speed) | 2122 | static noinline_for_stack int pkt_get_max_speed(struct pktcdvd_device *pd, |
| 2123 | unsigned *write_speed) | ||
| 2120 | { | 2124 | { |
| 2121 | struct packet_command cgc; | 2125 | struct packet_command cgc; |
| 2122 | struct request_sense sense; | 2126 | struct request_sense sense; |
| @@ -2177,7 +2181,8 @@ static char us_clv_to_speed[16] = { | |||
| 2177 | /* | 2181 | /* |
| 2178 | * reads the maximum media speed from ATIP | 2182 | * reads the maximum media speed from ATIP |
| 2179 | */ | 2183 | */ |
| 2180 | static int pkt_media_speed(struct pktcdvd_device *pd, unsigned *speed) | 2184 | static noinline_for_stack int pkt_media_speed(struct pktcdvd_device *pd, |
| 2185 | unsigned *speed) | ||
| 2181 | { | 2186 | { |
| 2182 | struct packet_command cgc; | 2187 | struct packet_command cgc; |
| 2183 | struct request_sense sense; | 2188 | struct request_sense sense; |
| @@ -2249,7 +2254,7 @@ static int pkt_media_speed(struct pktcdvd_device *pd, unsigned *speed) | |||
| 2249 | } | 2254 | } |
| 2250 | } | 2255 | } |
| 2251 | 2256 | ||
| 2252 | static int pkt_perform_opc(struct pktcdvd_device *pd) | 2257 | static noinline_for_stack int pkt_perform_opc(struct pktcdvd_device *pd) |
| 2253 | { | 2258 | { |
| 2254 | struct packet_command cgc; | 2259 | struct packet_command cgc; |
| 2255 | struct request_sense sense; | 2260 | struct request_sense sense; |
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 85d596a3c18c..eba2883b630e 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
| @@ -1527,7 +1527,7 @@ static int __devinit reset_card(struct pci_dev *pdev, | |||
| 1527 | msleep(10); | 1527 | msleep(10); |
| 1528 | 1528 | ||
| 1529 | portcount = inw(base + 0x2); | 1529 | portcount = inw(base + 0x2); |
| 1530 | if (!inw(base + 0xe) & 0x1 || (portcount != 0 && portcount != 4 && | 1530 | if (!(inw(base + 0xe) & 0x1) || (portcount != 0 && portcount != 4 && |
| 1531 | portcount != 8 && portcount != 16)) { | 1531 | portcount != 8 && portcount != 16)) { |
| 1532 | dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.\n", | 1532 | dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.\n", |
| 1533 | card + 1); | 1533 | card + 1); |
diff --git a/drivers/char/pcmcia/ipwireless/network.c b/drivers/char/pcmcia/ipwireless/network.c index ff35230058d3..d793e68b3e0d 100644 --- a/drivers/char/pcmcia/ipwireless/network.c +++ b/drivers/char/pcmcia/ipwireless/network.c | |||
| @@ -377,13 +377,16 @@ void ipwireless_network_packet_received(struct ipw_network *network, | |||
| 377 | for (i = 0; i < MAX_ASSOCIATED_TTYS; i++) { | 377 | for (i = 0; i < MAX_ASSOCIATED_TTYS; i++) { |
| 378 | struct ipw_tty *tty = network->associated_ttys[channel_idx][i]; | 378 | struct ipw_tty *tty = network->associated_ttys[channel_idx][i]; |
| 379 | 379 | ||
| 380 | if (!tty) | ||
| 381 | continue; | ||
| 382 | |||
| 380 | /* | 383 | /* |
| 381 | * If it's associated with a tty (other than the RAS channel | 384 | * If it's associated with a tty (other than the RAS channel |
| 382 | * when we're online), then send the data to that tty. The RAS | 385 | * when we're online), then send the data to that tty. The RAS |
| 383 | * channel's data is handled above - it always goes through | 386 | * channel's data is handled above - it always goes through |
| 384 | * ppp_generic. | 387 | * ppp_generic. |
| 385 | */ | 388 | */ |
| 386 | if (tty && channel_idx == IPW_CHANNEL_RAS | 389 | if (channel_idx == IPW_CHANNEL_RAS |
| 387 | && (network->ras_control_lines & | 390 | && (network->ras_control_lines & |
| 388 | IPW_CONTROL_LINE_DCD) != 0 | 391 | IPW_CONTROL_LINE_DCD) != 0 |
| 389 | && ipwireless_tty_is_modem(tty)) { | 392 | && ipwireless_tty_is_modem(tty)) { |
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index c0e08c7bca2f..5ff83df67b44 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c | |||
| @@ -2109,7 +2109,6 @@ static void sx_throttle(struct tty_struct * tty) | |||
| 2109 | sx_out(bp, CD186x_CAR, port_No(port)); | 2109 | sx_out(bp, CD186x_CAR, port_No(port)); |
| 2110 | spin_unlock_irqrestore(&bp->lock, flags); | 2110 | spin_unlock_irqrestore(&bp->lock, flags); |
| 2111 | if (I_IXOFF(tty)) { | 2111 | if (I_IXOFF(tty)) { |
| 2112 | spin_unlock_irqrestore(&bp->lock, flags); | ||
| 2113 | sx_wait_CCR(bp); | 2112 | sx_wait_CCR(bp); |
| 2114 | spin_lock_irqsave(&bp->lock, flags); | 2113 | spin_lock_irqsave(&bp->lock, flags); |
| 2115 | sx_out(bp, CD186x_CCR, CCR_SSCH2); | 2114 | sx_out(bp, CD186x_CCR, CCR_SSCH2); |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 367be9175061..9b58b894f823 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
| @@ -702,6 +702,7 @@ void redraw_screen(struct vc_data *vc, int is_switch) | |||
| 702 | if (is_switch) { | 702 | if (is_switch) { |
| 703 | set_leds(); | 703 | set_leds(); |
| 704 | compute_shiftstate(); | 704 | compute_shiftstate(); |
| 705 | notify_update(vc); | ||
| 705 | } | 706 | } |
| 706 | } | 707 | } |
| 707 | 708 | ||
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 8b10d9f23bef..c5263d63aca3 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
| @@ -42,14 +42,14 @@ config INPUT_M68K_BEEP | |||
| 42 | 42 | ||
| 43 | config INPUT_APANEL | 43 | config INPUT_APANEL |
| 44 | tristate "Fujitsu Lifebook Application Panel buttons" | 44 | tristate "Fujitsu Lifebook Application Panel buttons" |
| 45 | depends on X86 | 45 | depends on X86 && I2C && LEDS_CLASS |
| 46 | select I2C_I801 | ||
| 47 | select INPUT_POLLDEV | 46 | select INPUT_POLLDEV |
| 48 | select CHECK_SIGNATURE | 47 | select CHECK_SIGNATURE |
| 49 | help | 48 | help |
| 50 | Say Y here for support of the Application Panel buttons, used on | 49 | Say Y here for support of the Application Panel buttons, used on |
| 51 | Fujitsu Lifebook. These are attached to the mainboard through | 50 | Fujitsu Lifebook. These are attached to the mainboard through |
| 52 | an SMBus interface managed by the I2C Intel ICH (i801) driver. | 51 | an SMBus interface managed by the I2C Intel ICH (i801) driver, |
| 52 | which you should also build for this kernel. | ||
| 53 | 53 | ||
| 54 | To compile this driver as a module, choose M here: the module will | 54 | To compile this driver as a module, choose M here: the module will |
| 55 | be called apanel. | 55 | be called apanel. |
diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c index 7993e01f9fc5..76043dedba5b 100644 --- a/drivers/isdn/hisax/hisax_fcpcipnp.c +++ b/drivers/isdn/hisax/hisax_fcpcipnp.c | |||
| @@ -725,23 +725,6 @@ static int __devinit fcpcipnp_setup(struct fritz_adapter *adapter) | |||
| 725 | 725 | ||
| 726 | switch (adapter->type) { | 726 | switch (adapter->type) { |
| 727 | case AVM_FRITZ_PCIV2: | 727 | case AVM_FRITZ_PCIV2: |
| 728 | retval = request_irq(adapter->irq, fcpci2_irq, IRQF_SHARED, | ||
| 729 | "fcpcipnp", adapter); | ||
| 730 | break; | ||
| 731 | case AVM_FRITZ_PCI: | ||
| 732 | retval = request_irq(adapter->irq, fcpci_irq, IRQF_SHARED, | ||
| 733 | "fcpcipnp", adapter); | ||
| 734 | break; | ||
| 735 | case AVM_FRITZ_PNP: | ||
| 736 | retval = request_irq(adapter->irq, fcpci_irq, 0, | ||
| 737 | "fcpcipnp", adapter); | ||
| 738 | break; | ||
| 739 | } | ||
| 740 | if (retval) | ||
| 741 | goto err_region; | ||
| 742 | |||
| 743 | switch (adapter->type) { | ||
| 744 | case AVM_FRITZ_PCIV2: | ||
| 745 | case AVM_FRITZ_PCI: | 728 | case AVM_FRITZ_PCI: |
| 746 | val = inl(adapter->io); | 729 | val = inl(adapter->io); |
| 747 | break; | 730 | break; |
| @@ -796,6 +779,23 @@ static int __devinit fcpcipnp_setup(struct fritz_adapter *adapter) | |||
| 796 | 779 | ||
| 797 | switch (adapter->type) { | 780 | switch (adapter->type) { |
| 798 | case AVM_FRITZ_PCIV2: | 781 | case AVM_FRITZ_PCIV2: |
| 782 | retval = request_irq(adapter->irq, fcpci2_irq, IRQF_SHARED, | ||
| 783 | "fcpcipnp", adapter); | ||
| 784 | break; | ||
| 785 | case AVM_FRITZ_PCI: | ||
| 786 | retval = request_irq(adapter->irq, fcpci_irq, IRQF_SHARED, | ||
| 787 | "fcpcipnp", adapter); | ||
| 788 | break; | ||
| 789 | case AVM_FRITZ_PNP: | ||
| 790 | retval = request_irq(adapter->irq, fcpci_irq, 0, | ||
| 791 | "fcpcipnp", adapter); | ||
| 792 | break; | ||
| 793 | } | ||
| 794 | if (retval) | ||
| 795 | goto err_region; | ||
| 796 | |||
| 797 | switch (adapter->type) { | ||
| 798 | case AVM_FRITZ_PCIV2: | ||
| 799 | fcpci2_init(adapter); | 799 | fcpci2_init(adapter); |
| 800 | isacsx_setup(&adapter->isac); | 800 | isacsx_setup(&adapter->isac); |
| 801 | break; | 801 | break; |
diff --git a/drivers/isdn/i4l/isdn_ttyfax.c b/drivers/isdn/i4l/isdn_ttyfax.c index f93de4a30355..78f7660c1d0e 100644 --- a/drivers/isdn/i4l/isdn_ttyfax.c +++ b/drivers/isdn/i4l/isdn_ttyfax.c | |||
| @@ -906,7 +906,8 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info) | |||
| 906 | sprintf(rs, "\r\n0-2"); | 906 | sprintf(rs, "\r\n0-2"); |
| 907 | isdn_tty_at_cout(rs, info); | 907 | isdn_tty_at_cout(rs, info); |
| 908 | } else { | 908 | } else { |
| 909 | if ((f->phase != ISDN_FAX_PHASE_D) || (!info->faxonline & 1)) | 909 | if ((f->phase != ISDN_FAX_PHASE_D) || |
| 910 | (!(info->faxonline & 1))) | ||
| 910 | PARSE_ERROR1; | 911 | PARSE_ERROR1; |
| 911 | par = isdn_getnum(p); | 912 | par = isdn_getnum(p); |
| 912 | if ((par < 0) || (par > 2)) | 913 | if ((par < 0) || (par > 2)) |
diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c index 655ef9a3f4df..a335c85a736e 100644 --- a/drivers/isdn/isdnloop/isdnloop.c +++ b/drivers/isdn/isdnloop/isdnloop.c | |||
| @@ -1289,7 +1289,7 @@ isdnloop_command(isdn_ctrl * c, isdnloop_card * card) | |||
| 1289 | } | 1289 | } |
| 1290 | break; | 1290 | break; |
| 1291 | case ISDN_CMD_CLREAZ: | 1291 | case ISDN_CMD_CLREAZ: |
| 1292 | if (!card->flags & ISDNLOOP_FLAGS_RUNNING) | 1292 | if (!(card->flags & ISDNLOOP_FLAGS_RUNNING)) |
| 1293 | return -ENODEV; | 1293 | return -ENODEV; |
| 1294 | if (card->leased) | 1294 | if (card->leased) |
| 1295 | break; | 1295 | break; |
| @@ -1333,7 +1333,7 @@ isdnloop_command(isdn_ctrl * c, isdnloop_card * card) | |||
| 1333 | } | 1333 | } |
| 1334 | break; | 1334 | break; |
| 1335 | case ISDN_CMD_SETL3: | 1335 | case ISDN_CMD_SETL3: |
| 1336 | if (!card->flags & ISDNLOOP_FLAGS_RUNNING) | 1336 | if (!(card->flags & ISDNLOOP_FLAGS_RUNNING)) |
| 1337 | return -ENODEV; | 1337 | return -ENODEV; |
| 1338 | return 0; | 1338 | return 0; |
| 1339 | default: | 1339 | default: |
| @@ -1380,7 +1380,7 @@ if_writecmd(const u_char __user *buf, int len, int id, int channel) | |||
| 1380 | isdnloop_card *card = isdnloop_findcard(id); | 1380 | isdnloop_card *card = isdnloop_findcard(id); |
| 1381 | 1381 | ||
| 1382 | if (card) { | 1382 | if (card) { |
| 1383 | if (!card->flags & ISDNLOOP_FLAGS_RUNNING) | 1383 | if (!(card->flags & ISDNLOOP_FLAGS_RUNNING)) |
| 1384 | return -ENODEV; | 1384 | return -ENODEV; |
| 1385 | return (isdnloop_writecmd(buf, len, 1, card)); | 1385 | return (isdnloop_writecmd(buf, len, 1, card)); |
| 1386 | } | 1386 | } |
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 7aeceedcf7d4..831aed9c56ff 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
| @@ -1047,6 +1047,11 @@ void bitmap_daemon_work(struct bitmap *bitmap) | |||
| 1047 | if (time_before(jiffies, bitmap->daemon_lastrun + bitmap->daemon_sleep*HZ)) | 1047 | if (time_before(jiffies, bitmap->daemon_lastrun + bitmap->daemon_sleep*HZ)) |
| 1048 | return; | 1048 | return; |
| 1049 | bitmap->daemon_lastrun = jiffies; | 1049 | bitmap->daemon_lastrun = jiffies; |
| 1050 | if (bitmap->allclean) { | ||
| 1051 | bitmap->mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT; | ||
| 1052 | return; | ||
| 1053 | } | ||
| 1054 | bitmap->allclean = 1; | ||
| 1050 | 1055 | ||
| 1051 | for (j = 0; j < bitmap->chunks; j++) { | 1056 | for (j = 0; j < bitmap->chunks; j++) { |
| 1052 | bitmap_counter_t *bmc; | 1057 | bitmap_counter_t *bmc; |
| @@ -1068,8 +1073,10 @@ void bitmap_daemon_work(struct bitmap *bitmap) | |||
| 1068 | clear_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE); | 1073 | clear_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE); |
| 1069 | 1074 | ||
| 1070 | spin_unlock_irqrestore(&bitmap->lock, flags); | 1075 | spin_unlock_irqrestore(&bitmap->lock, flags); |
| 1071 | if (need_write) | 1076 | if (need_write) { |
| 1072 | write_page(bitmap, page, 0); | 1077 | write_page(bitmap, page, 0); |
| 1078 | bitmap->allclean = 0; | ||
| 1079 | } | ||
| 1073 | continue; | 1080 | continue; |
| 1074 | } | 1081 | } |
| 1075 | 1082 | ||
| @@ -1098,6 +1105,9 @@ void bitmap_daemon_work(struct bitmap *bitmap) | |||
| 1098 | /* | 1105 | /* |
| 1099 | if (j < 100) printk("bitmap: j=%lu, *bmc = 0x%x\n", j, *bmc); | 1106 | if (j < 100) printk("bitmap: j=%lu, *bmc = 0x%x\n", j, *bmc); |
| 1100 | */ | 1107 | */ |
| 1108 | if (*bmc) | ||
| 1109 | bitmap->allclean = 0; | ||
| 1110 | |||
| 1101 | if (*bmc == 2) { | 1111 | if (*bmc == 2) { |
| 1102 | *bmc=1; /* maybe clear the bit next time */ | 1112 | *bmc=1; /* maybe clear the bit next time */ |
| 1103 | set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); | 1113 | set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); |
| @@ -1132,6 +1142,8 @@ void bitmap_daemon_work(struct bitmap *bitmap) | |||
| 1132 | } | 1142 | } |
| 1133 | } | 1143 | } |
| 1134 | 1144 | ||
| 1145 | if (bitmap->allclean == 0) | ||
| 1146 | bitmap->mddev->thread->timeout = bitmap->daemon_sleep * HZ; | ||
| 1135 | } | 1147 | } |
| 1136 | 1148 | ||
| 1137 | static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap, | 1149 | static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap, |
| @@ -1226,6 +1238,7 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect | |||
| 1226 | sectors -= blocks; | 1238 | sectors -= blocks; |
| 1227 | else sectors = 0; | 1239 | else sectors = 0; |
| 1228 | } | 1240 | } |
| 1241 | bitmap->allclean = 0; | ||
| 1229 | return 0; | 1242 | return 0; |
| 1230 | } | 1243 | } |
| 1231 | 1244 | ||
| @@ -1296,6 +1309,7 @@ int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks, | |||
| 1296 | } | 1309 | } |
| 1297 | } | 1310 | } |
| 1298 | spin_unlock_irq(&bitmap->lock); | 1311 | spin_unlock_irq(&bitmap->lock); |
| 1312 | bitmap->allclean = 0; | ||
| 1299 | return rv; | 1313 | return rv; |
| 1300 | } | 1314 | } |
| 1301 | 1315 | ||
| @@ -1332,6 +1346,7 @@ void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int ab | |||
| 1332 | } | 1346 | } |
| 1333 | unlock: | 1347 | unlock: |
| 1334 | spin_unlock_irqrestore(&bitmap->lock, flags); | 1348 | spin_unlock_irqrestore(&bitmap->lock, flags); |
| 1349 | bitmap->allclean = 0; | ||
| 1335 | } | 1350 | } |
| 1336 | 1351 | ||
| 1337 | void bitmap_close_sync(struct bitmap *bitmap) | 1352 | void bitmap_close_sync(struct bitmap *bitmap) |
| @@ -1399,7 +1414,7 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int n | |||
| 1399 | set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); | 1414 | set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); |
| 1400 | } | 1415 | } |
| 1401 | spin_unlock_irq(&bitmap->lock); | 1416 | spin_unlock_irq(&bitmap->lock); |
| 1402 | 1417 | bitmap->allclean = 0; | |
| 1403 | } | 1418 | } |
| 1404 | 1419 | ||
| 1405 | /* dirty the memory and file bits for bitmap chunks "s" to "e" */ | 1420 | /* dirty the memory and file bits for bitmap chunks "s" to "e" */ |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 7da6ec244e15..827824a9f3e9 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -1105,7 +1105,11 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) | |||
| 1105 | rdev->sb_size = le32_to_cpu(sb->max_dev) * 2 + 256; | 1105 | rdev->sb_size = le32_to_cpu(sb->max_dev) * 2 + 256; |
| 1106 | bmask = queue_hardsect_size(rdev->bdev->bd_disk->queue)-1; | 1106 | bmask = queue_hardsect_size(rdev->bdev->bd_disk->queue)-1; |
| 1107 | if (rdev->sb_size & bmask) | 1107 | if (rdev->sb_size & bmask) |
| 1108 | rdev-> sb_size = (rdev->sb_size | bmask)+1; | 1108 | rdev->sb_size = (rdev->sb_size | bmask) + 1; |
| 1109 | |||
| 1110 | if (minor_version | ||
| 1111 | && rdev->data_offset < sb_offset + (rdev->sb_size/512)) | ||
| 1112 | return -EINVAL; | ||
| 1109 | 1113 | ||
| 1110 | if (sb->level == cpu_to_le32(LEVEL_MULTIPATH)) | 1114 | if (sb->level == cpu_to_le32(LEVEL_MULTIPATH)) |
| 1111 | rdev->desc_nr = -1; | 1115 | rdev->desc_nr = -1; |
| @@ -1137,7 +1141,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) | |||
| 1137 | else | 1141 | else |
| 1138 | ret = 0; | 1142 | ret = 0; |
| 1139 | } | 1143 | } |
| 1140 | if (minor_version) | 1144 | if (minor_version) |
| 1141 | rdev->size = ((rdev->bdev->bd_inode->i_size>>9) - le64_to_cpu(sb->data_offset)) / 2; | 1145 | rdev->size = ((rdev->bdev->bd_inode->i_size>>9) - le64_to_cpu(sb->data_offset)) / 2; |
| 1142 | else | 1146 | else |
| 1143 | rdev->size = rdev->sb_offset; | 1147 | rdev->size = rdev->sb_offset; |
| @@ -1499,7 +1503,8 @@ static void export_rdev(mdk_rdev_t * rdev) | |||
| 1499 | free_disk_sb(rdev); | 1503 | free_disk_sb(rdev); |
| 1500 | list_del_init(&rdev->same_set); | 1504 | list_del_init(&rdev->same_set); |
| 1501 | #ifndef MODULE | 1505 | #ifndef MODULE |
| 1502 | md_autodetect_dev(rdev->bdev->bd_dev); | 1506 | if (test_bit(AutoDetected, &rdev->flags)) |
| 1507 | md_autodetect_dev(rdev->bdev->bd_dev); | ||
| 1503 | #endif | 1508 | #endif |
| 1504 | unlock_rdev(rdev); | 1509 | unlock_rdev(rdev); |
| 1505 | kobject_put(&rdev->kobj); | 1510 | kobject_put(&rdev->kobj); |
| @@ -1996,9 +2001,11 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
| 1996 | char *e; | 2001 | char *e; |
| 1997 | unsigned long long size = simple_strtoull(buf, &e, 10); | 2002 | unsigned long long size = simple_strtoull(buf, &e, 10); |
| 1998 | unsigned long long oldsize = rdev->size; | 2003 | unsigned long long oldsize = rdev->size; |
| 2004 | mddev_t *my_mddev = rdev->mddev; | ||
| 2005 | |||
| 1999 | if (e==buf || (*e && *e != '\n')) | 2006 | if (e==buf || (*e && *e != '\n')) |
| 2000 | return -EINVAL; | 2007 | return -EINVAL; |
| 2001 | if (rdev->mddev->pers) | 2008 | if (my_mddev->pers) |
| 2002 | return -EBUSY; | 2009 | return -EBUSY; |
| 2003 | rdev->size = size; | 2010 | rdev->size = size; |
| 2004 | if (size > oldsize && rdev->mddev->external) { | 2011 | if (size > oldsize && rdev->mddev->external) { |
| @@ -2011,7 +2018,7 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
| 2011 | int overlap = 0; | 2018 | int overlap = 0; |
| 2012 | struct list_head *tmp, *tmp2; | 2019 | struct list_head *tmp, *tmp2; |
| 2013 | 2020 | ||
| 2014 | mddev_unlock(rdev->mddev); | 2021 | mddev_unlock(my_mddev); |
| 2015 | for_each_mddev(mddev, tmp) { | 2022 | for_each_mddev(mddev, tmp) { |
| 2016 | mdk_rdev_t *rdev2; | 2023 | mdk_rdev_t *rdev2; |
| 2017 | 2024 | ||
| @@ -2031,7 +2038,7 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
| 2031 | break; | 2038 | break; |
| 2032 | } | 2039 | } |
| 2033 | } | 2040 | } |
| 2034 | mddev_lock(rdev->mddev); | 2041 | mddev_lock(my_mddev); |
| 2035 | if (overlap) { | 2042 | if (overlap) { |
| 2036 | /* Someone else could have slipped in a size | 2043 | /* Someone else could have slipped in a size |
| 2037 | * change here, but doing so is just silly. | 2044 | * change here, but doing so is just silly. |
| @@ -2043,8 +2050,8 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
| 2043 | return -EBUSY; | 2050 | return -EBUSY; |
| 2044 | } | 2051 | } |
| 2045 | } | 2052 | } |
| 2046 | if (size < rdev->mddev->size || rdev->mddev->size == 0) | 2053 | if (size < my_mddev->size || my_mddev->size == 0) |
| 2047 | rdev->mddev->size = size; | 2054 | my_mddev->size = size; |
| 2048 | return len; | 2055 | return len; |
| 2049 | } | 2056 | } |
| 2050 | 2057 | ||
| @@ -2065,10 +2072,21 @@ rdev_attr_show(struct kobject *kobj, struct attribute *attr, char *page) | |||
| 2065 | { | 2072 | { |
| 2066 | struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr); | 2073 | struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr); |
| 2067 | mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj); | 2074 | mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj); |
| 2075 | mddev_t *mddev = rdev->mddev; | ||
| 2076 | ssize_t rv; | ||
| 2068 | 2077 | ||
| 2069 | if (!entry->show) | 2078 | if (!entry->show) |
| 2070 | return -EIO; | 2079 | return -EIO; |
| 2071 | return entry->show(rdev, page); | 2080 | |
| 2081 | rv = mddev ? mddev_lock(mddev) : -EBUSY; | ||
| 2082 | if (!rv) { | ||
| 2083 | if (rdev->mddev == NULL) | ||
| 2084 | rv = -EBUSY; | ||
| 2085 | else | ||
| 2086 | rv = entry->show(rdev, page); | ||
| 2087 | mddev_unlock(mddev); | ||
| 2088 | } | ||
| 2089 | return rv; | ||
| 2072 | } | 2090 | } |
| 2073 | 2091 | ||
| 2074 | static ssize_t | 2092 | static ssize_t |
| @@ -2077,15 +2095,19 @@ rdev_attr_store(struct kobject *kobj, struct attribute *attr, | |||
| 2077 | { | 2095 | { |
| 2078 | struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr); | 2096 | struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr); |
| 2079 | mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj); | 2097 | mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj); |
| 2080 | int rv; | 2098 | ssize_t rv; |
| 2099 | mddev_t *mddev = rdev->mddev; | ||
| 2081 | 2100 | ||
| 2082 | if (!entry->store) | 2101 | if (!entry->store) |
| 2083 | return -EIO; | 2102 | return -EIO; |
| 2084 | if (!capable(CAP_SYS_ADMIN)) | 2103 | if (!capable(CAP_SYS_ADMIN)) |
| 2085 | return -EACCES; | 2104 | return -EACCES; |
| 2086 | rv = mddev_lock(rdev->mddev); | 2105 | rv = mddev ? mddev_lock(mddev): -EBUSY; |
| 2087 | if (!rv) { | 2106 | if (!rv) { |
| 2088 | rv = entry->store(rdev, page, length); | 2107 | if (rdev->mddev == NULL) |
| 2108 | rv = -EBUSY; | ||
| 2109 | else | ||
| 2110 | rv = entry->store(rdev, page, length); | ||
| 2089 | mddev_unlock(rdev->mddev); | 2111 | mddev_unlock(rdev->mddev); |
| 2090 | } | 2112 | } |
| 2091 | return rv; | 2113 | return rv; |
| @@ -5351,6 +5373,7 @@ void md_write_start(mddev_t *mddev, struct bio *bi) | |||
| 5351 | mddev->ro = 0; | 5373 | mddev->ro = 0; |
| 5352 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 5374 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
| 5353 | md_wakeup_thread(mddev->thread); | 5375 | md_wakeup_thread(mddev->thread); |
| 5376 | md_wakeup_thread(mddev->sync_thread); | ||
| 5354 | } | 5377 | } |
| 5355 | atomic_inc(&mddev->writes_pending); | 5378 | atomic_inc(&mddev->writes_pending); |
| 5356 | if (mddev->in_sync) { | 5379 | if (mddev->in_sync) { |
| @@ -6021,6 +6044,7 @@ static void autostart_arrays(int part) | |||
| 6021 | MD_BUG(); | 6044 | MD_BUG(); |
| 6022 | continue; | 6045 | continue; |
| 6023 | } | 6046 | } |
| 6047 | set_bit(AutoDetected, &rdev->flags); | ||
| 6024 | list_add(&rdev->same_set, &pending_raid_disks); | 6048 | list_add(&rdev->same_set, &pending_raid_disks); |
| 6025 | i_passed++; | 6049 | i_passed++; |
| 6026 | } | 6050 | } |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 5c7fef091cec..ff61b309129a 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
| @@ -592,6 +592,37 @@ static int raid1_congested(void *data, int bits) | |||
| 592 | } | 592 | } |
| 593 | 593 | ||
| 594 | 594 | ||
| 595 | static int flush_pending_writes(conf_t *conf) | ||
| 596 | { | ||
| 597 | /* Any writes that have been queued but are awaiting | ||
| 598 | * bitmap updates get flushed here. | ||
| 599 | * We return 1 if any requests were actually submitted. | ||
| 600 | */ | ||
| 601 | int rv = 0; | ||
| 602 | |||
| 603 | spin_lock_irq(&conf->device_lock); | ||
| 604 | |||
| 605 | if (conf->pending_bio_list.head) { | ||
| 606 | struct bio *bio; | ||
| 607 | bio = bio_list_get(&conf->pending_bio_list); | ||
| 608 | blk_remove_plug(conf->mddev->queue); | ||
| 609 | spin_unlock_irq(&conf->device_lock); | ||
| 610 | /* flush any pending bitmap writes to | ||
| 611 | * disk before proceeding w/ I/O */ | ||
| 612 | bitmap_unplug(conf->mddev->bitmap); | ||
| 613 | |||
| 614 | while (bio) { /* submit pending writes */ | ||
| 615 | struct bio *next = bio->bi_next; | ||
| 616 | bio->bi_next = NULL; | ||
| 617 | generic_make_request(bio); | ||
| 618 | bio = next; | ||
| 619 | } | ||
| 620 | rv = 1; | ||
| 621 | } else | ||
| 622 | spin_unlock_irq(&conf->device_lock); | ||
| 623 | return rv; | ||
| 624 | } | ||
| 625 | |||
| 595 | /* Barriers.... | 626 | /* Barriers.... |
| 596 | * Sometimes we need to suspend IO while we do something else, | 627 | * Sometimes we need to suspend IO while we do something else, |
| 597 | * either some resync/recovery, or reconfigure the array. | 628 | * either some resync/recovery, or reconfigure the array. |
| @@ -673,15 +704,23 @@ static void freeze_array(conf_t *conf) | |||
| 673 | /* stop syncio and normal IO and wait for everything to | 704 | /* stop syncio and normal IO and wait for everything to |
| 674 | * go quite. | 705 | * go quite. |
| 675 | * We increment barrier and nr_waiting, and then | 706 | * We increment barrier and nr_waiting, and then |
| 676 | * wait until barrier+nr_pending match nr_queued+2 | 707 | * wait until nr_pending match nr_queued+1 |
| 708 | * This is called in the context of one normal IO request | ||
| 709 | * that has failed. Thus any sync request that might be pending | ||
| 710 | * will be blocked by nr_pending, and we need to wait for | ||
| 711 | * pending IO requests to complete or be queued for re-try. | ||
| 712 | * Thus the number queued (nr_queued) plus this request (1) | ||
| 713 | * must match the number of pending IOs (nr_pending) before | ||
| 714 | * we continue. | ||
| 677 | */ | 715 | */ |
| 678 | spin_lock_irq(&conf->resync_lock); | 716 | spin_lock_irq(&conf->resync_lock); |
| 679 | conf->barrier++; | 717 | conf->barrier++; |
| 680 | conf->nr_waiting++; | 718 | conf->nr_waiting++; |
| 681 | wait_event_lock_irq(conf->wait_barrier, | 719 | wait_event_lock_irq(conf->wait_barrier, |
| 682 | conf->barrier+conf->nr_pending == conf->nr_queued+2, | 720 | conf->nr_pending == conf->nr_queued+1, |
| 683 | conf->resync_lock, | 721 | conf->resync_lock, |
| 684 | raid1_unplug(conf->mddev->queue)); | 722 | ({ flush_pending_writes(conf); |
| 723 | raid1_unplug(conf->mddev->queue); })); | ||
| 685 | spin_unlock_irq(&conf->resync_lock); | 724 | spin_unlock_irq(&conf->resync_lock); |
| 686 | } | 725 | } |
| 687 | static void unfreeze_array(conf_t *conf) | 726 | static void unfreeze_array(conf_t *conf) |
| @@ -907,6 +946,9 @@ static int make_request(struct request_queue *q, struct bio * bio) | |||
| 907 | blk_plug_device(mddev->queue); | 946 | blk_plug_device(mddev->queue); |
| 908 | spin_unlock_irqrestore(&conf->device_lock, flags); | 947 | spin_unlock_irqrestore(&conf->device_lock, flags); |
| 909 | 948 | ||
| 949 | /* In case raid1d snuck into freeze_array */ | ||
| 950 | wake_up(&conf->wait_barrier); | ||
| 951 | |||
| 910 | if (do_sync) | 952 | if (do_sync) |
| 911 | md_wakeup_thread(mddev->thread); | 953 | md_wakeup_thread(mddev->thread); |
| 912 | #if 0 | 954 | #if 0 |
| @@ -1473,28 +1515,14 @@ static void raid1d(mddev_t *mddev) | |||
| 1473 | 1515 | ||
| 1474 | for (;;) { | 1516 | for (;;) { |
| 1475 | char b[BDEVNAME_SIZE]; | 1517 | char b[BDEVNAME_SIZE]; |
| 1476 | spin_lock_irqsave(&conf->device_lock, flags); | ||
| 1477 | |||
| 1478 | if (conf->pending_bio_list.head) { | ||
| 1479 | bio = bio_list_get(&conf->pending_bio_list); | ||
| 1480 | blk_remove_plug(mddev->queue); | ||
| 1481 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
| 1482 | /* flush any pending bitmap writes to disk before proceeding w/ I/O */ | ||
| 1483 | bitmap_unplug(mddev->bitmap); | ||
| 1484 | 1518 | ||
| 1485 | while (bio) { /* submit pending writes */ | 1519 | unplug += flush_pending_writes(conf); |
| 1486 | struct bio *next = bio->bi_next; | ||
| 1487 | bio->bi_next = NULL; | ||
| 1488 | generic_make_request(bio); | ||
| 1489 | bio = next; | ||
| 1490 | } | ||
| 1491 | unplug = 1; | ||
| 1492 | 1520 | ||
| 1493 | continue; | 1521 | spin_lock_irqsave(&conf->device_lock, flags); |
| 1494 | } | 1522 | if (list_empty(head)) { |
| 1495 | 1523 | spin_unlock_irqrestore(&conf->device_lock, flags); | |
| 1496 | if (list_empty(head)) | ||
| 1497 | break; | 1524 | break; |
| 1525 | } | ||
| 1498 | r1_bio = list_entry(head->prev, r1bio_t, retry_list); | 1526 | r1_bio = list_entry(head->prev, r1bio_t, retry_list); |
| 1499 | list_del(head->prev); | 1527 | list_del(head->prev); |
| 1500 | conf->nr_queued--; | 1528 | conf->nr_queued--; |
| @@ -1590,7 +1618,6 @@ static void raid1d(mddev_t *mddev) | |||
| 1590 | } | 1618 | } |
| 1591 | } | 1619 | } |
| 1592 | } | 1620 | } |
| 1593 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
| 1594 | if (unplug) | 1621 | if (unplug) |
| 1595 | unplug_slaves(mddev); | 1622 | unplug_slaves(mddev); |
| 1596 | } | 1623 | } |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 017f58113c33..32389d2f18fc 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
| @@ -537,7 +537,8 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio) | |||
| 537 | current_distance = abs(r10_bio->devs[slot].addr - | 537 | current_distance = abs(r10_bio->devs[slot].addr - |
| 538 | conf->mirrors[disk].head_position); | 538 | conf->mirrors[disk].head_position); |
| 539 | 539 | ||
| 540 | /* Find the disk whose head is closest */ | 540 | /* Find the disk whose head is closest, |
| 541 | * or - for far > 1 - find the closest to partition beginning */ | ||
| 541 | 542 | ||
| 542 | for (nslot = slot; nslot < conf->copies; nslot++) { | 543 | for (nslot = slot; nslot < conf->copies; nslot++) { |
| 543 | int ndisk = r10_bio->devs[nslot].devnum; | 544 | int ndisk = r10_bio->devs[nslot].devnum; |
| @@ -557,8 +558,13 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio) | |||
| 557 | slot = nslot; | 558 | slot = nslot; |
| 558 | break; | 559 | break; |
| 559 | } | 560 | } |
| 560 | new_distance = abs(r10_bio->devs[nslot].addr - | 561 | |
| 561 | conf->mirrors[ndisk].head_position); | 562 | /* for far > 1 always use the lowest address */ |
| 563 | if (conf->far_copies > 1) | ||
| 564 | new_distance = r10_bio->devs[nslot].addr; | ||
| 565 | else | ||
| 566 | new_distance = abs(r10_bio->devs[nslot].addr - | ||
| 567 | conf->mirrors[ndisk].head_position); | ||
| 562 | if (new_distance < current_distance) { | 568 | if (new_distance < current_distance) { |
| 563 | current_distance = new_distance; | 569 | current_distance = new_distance; |
| 564 | disk = ndisk; | 570 | disk = ndisk; |
| @@ -629,7 +635,36 @@ static int raid10_congested(void *data, int bits) | |||
| 629 | return ret; | 635 | return ret; |
| 630 | } | 636 | } |
| 631 | 637 | ||
| 632 | 638 | static int flush_pending_writes(conf_t *conf) | |
| 639 | { | ||
| 640 | /* Any writes that have been queued but are awaiting | ||
| 641 | * bitmap updates get flushed here. | ||
| 642 | * We return 1 if any requests were actually submitted. | ||
| 643 | */ | ||
| 644 | int rv = 0; | ||
| 645 | |||
| 646 | spin_lock_irq(&conf->device_lock); | ||
| 647 | |||
| 648 | if (conf->pending_bio_list.head) { | ||
| 649 | struct bio *bio; | ||
| 650 | bio = bio_list_get(&conf->pending_bio_list); | ||
| 651 | blk_remove_plug(conf->mddev->queue); | ||
| 652 | spin_unlock_irq(&conf->device_lock); | ||
| 653 | /* flush any pending bitmap writes to disk | ||
| 654 | * before proceeding w/ I/O */ | ||
| 655 | bitmap_unplug(conf->mddev->bitmap); | ||
| 656 | |||
| 657 | while (bio) { /* submit pending writes */ | ||
| 658 | struct bio *next = bio->bi_next; | ||
| 659 | bio->bi_next = NULL; | ||
| 660 | generic_make_request(bio); | ||
| 661 | bio = next; | ||
| 662 | } | ||
| 663 | rv = 1; | ||
| 664 | } else | ||
| 665 | spin_unlock_irq(&conf->device_lock); | ||
| 666 | return rv; | ||
| 667 | } | ||
| 633 | /* Barriers.... | 668 | /* Barriers.... |
| 634 | * Sometimes we need to suspend IO while we do something else, | 669 | * Sometimes we need to suspend IO while we do something else, |
| 635 | * either some resync/recovery, or reconfigure the array. | 670 | * either some resync/recovery, or reconfigure the array. |
| @@ -712,15 +747,23 @@ static void freeze_array(conf_t *conf) | |||
| 712 | /* stop syncio and normal IO and wait for everything to | 747 | /* stop syncio and normal IO and wait for everything to |
| 713 | * go quiet. | 748 | * go quiet. |
| 714 | * We increment barrier and nr_waiting, and then | 749 | * We increment barrier and nr_waiting, and then |
| 715 | * wait until barrier+nr_pending match nr_queued+2 | 750 | * wait until nr_pending match nr_queued+1 |
| 751 | * This is called in the context of one normal IO request | ||
| 752 | * that has failed. Thus any sync request that might be pending | ||
| 753 | * will be blocked by nr_pending, and we need to wait for | ||
| 754 | * pending IO requests to complete or be queued for re-try. | ||
| 755 | * Thus the number queued (nr_queued) plus this request (1) | ||
| 756 | * must match the number of pending IOs (nr_pending) before | ||
| 757 | * we continue. | ||
| 716 | */ | 758 | */ |
| 717 | spin_lock_irq(&conf->resync_lock); | 759 | spin_lock_irq(&conf->resync_lock); |
| 718 | conf->barrier++; | 760 | conf->barrier++; |
| 719 | conf->nr_waiting++; | 761 | conf->nr_waiting++; |
| 720 | wait_event_lock_irq(conf->wait_barrier, | 762 | wait_event_lock_irq(conf->wait_barrier, |
| 721 | conf->barrier+conf->nr_pending == conf->nr_queued+2, | 763 | conf->nr_pending == conf->nr_queued+1, |
| 722 | conf->resync_lock, | 764 | conf->resync_lock, |
| 723 | raid10_unplug(conf->mddev->queue)); | 765 | ({ flush_pending_writes(conf); |
| 766 | raid10_unplug(conf->mddev->queue); })); | ||
| 724 | spin_unlock_irq(&conf->resync_lock); | 767 | spin_unlock_irq(&conf->resync_lock); |
| 725 | } | 768 | } |
| 726 | 769 | ||
| @@ -892,6 +935,9 @@ static int make_request(struct request_queue *q, struct bio * bio) | |||
| 892 | blk_plug_device(mddev->queue); | 935 | blk_plug_device(mddev->queue); |
| 893 | spin_unlock_irqrestore(&conf->device_lock, flags); | 936 | spin_unlock_irqrestore(&conf->device_lock, flags); |
| 894 | 937 | ||
| 938 | /* In case raid10d snuck in to freeze_array */ | ||
| 939 | wake_up(&conf->wait_barrier); | ||
| 940 | |||
| 895 | if (do_sync) | 941 | if (do_sync) |
| 896 | md_wakeup_thread(mddev->thread); | 942 | md_wakeup_thread(mddev->thread); |
| 897 | 943 | ||
| @@ -1464,28 +1510,14 @@ static void raid10d(mddev_t *mddev) | |||
| 1464 | 1510 | ||
| 1465 | for (;;) { | 1511 | for (;;) { |
| 1466 | char b[BDEVNAME_SIZE]; | 1512 | char b[BDEVNAME_SIZE]; |
| 1467 | spin_lock_irqsave(&conf->device_lock, flags); | ||
| 1468 | 1513 | ||
| 1469 | if (conf->pending_bio_list.head) { | 1514 | unplug += flush_pending_writes(conf); |
| 1470 | bio = bio_list_get(&conf->pending_bio_list); | ||
| 1471 | blk_remove_plug(mddev->queue); | ||
| 1472 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
| 1473 | /* flush any pending bitmap writes to disk before proceeding w/ I/O */ | ||
| 1474 | bitmap_unplug(mddev->bitmap); | ||
| 1475 | |||
| 1476 | while (bio) { /* submit pending writes */ | ||
| 1477 | struct bio *next = bio->bi_next; | ||
| 1478 | bio->bi_next = NULL; | ||
| 1479 | generic_make_request(bio); | ||
| 1480 | bio = next; | ||
| 1481 | } | ||
| 1482 | unplug = 1; | ||
| 1483 | |||
| 1484 | continue; | ||
| 1485 | } | ||
| 1486 | 1515 | ||
| 1487 | if (list_empty(head)) | 1516 | spin_lock_irqsave(&conf->device_lock, flags); |
| 1517 | if (list_empty(head)) { | ||
| 1518 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
| 1488 | break; | 1519 | break; |
| 1520 | } | ||
| 1489 | r10_bio = list_entry(head->prev, r10bio_t, retry_list); | 1521 | r10_bio = list_entry(head->prev, r10bio_t, retry_list); |
| 1490 | list_del(head->prev); | 1522 | list_del(head->prev); |
| 1491 | conf->nr_queued--; | 1523 | conf->nr_queued--; |
| @@ -1548,7 +1580,6 @@ static void raid10d(mddev_t *mddev) | |||
| 1548 | } | 1580 | } |
| 1549 | } | 1581 | } |
| 1550 | } | 1582 | } |
| 1551 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
| 1552 | if (unplug) | 1583 | if (unplug) |
| 1553 | unplug_slaves(mddev); | 1584 | unplug_slaves(mddev); |
| 1554 | } | 1585 | } |
| @@ -1787,6 +1818,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
| 1787 | if (j == conf->copies) { | 1818 | if (j == conf->copies) { |
| 1788 | /* Cannot recover, so abort the recovery */ | 1819 | /* Cannot recover, so abort the recovery */ |
| 1789 | put_buf(r10_bio); | 1820 | put_buf(r10_bio); |
| 1821 | if (rb2) | ||
| 1822 | atomic_dec(&rb2->remaining); | ||
| 1790 | r10_bio = rb2; | 1823 | r10_bio = rb2; |
| 1791 | if (!test_and_set_bit(MD_RECOVERY_ERR, &mddev->recovery)) | 1824 | if (!test_and_set_bit(MD_RECOVERY_ERR, &mddev->recovery)) |
| 1792 | printk(KERN_INFO "raid10: %s: insufficient working devices for recovery.\n", | 1825 | printk(KERN_INFO "raid10: %s: insufficient working devices for recovery.\n", |
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index afd82966f9a0..13bac53db69a 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c | |||
| @@ -48,31 +48,13 @@ struct sm501_devdata { | |||
| 48 | unsigned int pdev_id; | 48 | unsigned int pdev_id; |
| 49 | unsigned int irq; | 49 | unsigned int irq; |
| 50 | void __iomem *regs; | 50 | void __iomem *regs; |
| 51 | unsigned int rev; | ||
| 51 | }; | 52 | }; |
| 52 | 53 | ||
| 53 | #define MHZ (1000 * 1000) | 54 | #define MHZ (1000 * 1000) |
| 54 | 55 | ||
| 55 | #ifdef DEBUG | 56 | #ifdef DEBUG |
| 56 | static const unsigned int misc_div[] = { | 57 | static const unsigned int div_tab[] = { |
| 57 | [0] = 1, | ||
| 58 | [1] = 2, | ||
| 59 | [2] = 4, | ||
| 60 | [3] = 8, | ||
| 61 | [4] = 16, | ||
| 62 | [5] = 32, | ||
| 63 | [6] = 64, | ||
| 64 | [7] = 128, | ||
| 65 | [8] = 3, | ||
| 66 | [9] = 6, | ||
| 67 | [10] = 12, | ||
| 68 | [11] = 24, | ||
| 69 | [12] = 48, | ||
| 70 | [13] = 96, | ||
| 71 | [14] = 192, | ||
| 72 | [15] = 384, | ||
| 73 | }; | ||
| 74 | |||
| 75 | static const unsigned int px_div[] = { | ||
| 76 | [0] = 1, | 58 | [0] = 1, |
| 77 | [1] = 2, | 59 | [1] = 2, |
| 78 | [2] = 4, | 60 | [2] = 4, |
| @@ -101,12 +83,12 @@ static const unsigned int px_div[] = { | |||
| 101 | 83 | ||
| 102 | static unsigned long decode_div(unsigned long pll2, unsigned long val, | 84 | static unsigned long decode_div(unsigned long pll2, unsigned long val, |
| 103 | unsigned int lshft, unsigned int selbit, | 85 | unsigned int lshft, unsigned int selbit, |
| 104 | unsigned long mask, const unsigned int *dtab) | 86 | unsigned long mask) |
| 105 | { | 87 | { |
| 106 | if (val & selbit) | 88 | if (val & selbit) |
| 107 | pll2 = 288 * MHZ; | 89 | pll2 = 288 * MHZ; |
| 108 | 90 | ||
| 109 | return pll2 / dtab[(val >> lshft) & mask]; | 91 | return pll2 / div_tab[(val >> lshft) & mask]; |
| 110 | } | 92 | } |
| 111 | 93 | ||
| 112 | #define fmt_freq(x) ((x) / MHZ), ((x) % MHZ), (x) | 94 | #define fmt_freq(x) ((x) / MHZ), ((x) % MHZ), (x) |
| @@ -141,10 +123,10 @@ static void sm501_dump_clk(struct sm501_devdata *sm) | |||
| 141 | } | 123 | } |
| 142 | 124 | ||
| 143 | sdclk0 = (misct & (1<<12)) ? pll2 : 288 * MHZ; | 125 | sdclk0 = (misct & (1<<12)) ? pll2 : 288 * MHZ; |
| 144 | sdclk0 /= misc_div[((misct >> 8) & 0xf)]; | 126 | sdclk0 /= div_tab[((misct >> 8) & 0xf)]; |
| 145 | 127 | ||
| 146 | sdclk1 = (misct & (1<<20)) ? pll2 : 288 * MHZ; | 128 | sdclk1 = (misct & (1<<20)) ? pll2 : 288 * MHZ; |
| 147 | sdclk1 /= misc_div[((misct >> 16) & 0xf)]; | 129 | sdclk1 /= div_tab[((misct >> 16) & 0xf)]; |
| 148 | 130 | ||
| 149 | dev_dbg(sm->dev, "MISCT=%08lx, PM0=%08lx, PM1=%08lx\n", | 131 | dev_dbg(sm->dev, "MISCT=%08lx, PM0=%08lx, PM1=%08lx\n", |
| 150 | misct, pm0, pm1); | 132 | misct, pm0, pm1); |
| @@ -158,19 +140,19 @@ static void sm501_dump_clk(struct sm501_devdata *sm) | |||
| 158 | "P2 %ld.%ld MHz (%ld), V2 %ld.%ld (%ld), " | 140 | "P2 %ld.%ld MHz (%ld), V2 %ld.%ld (%ld), " |
| 159 | "M %ld.%ld (%ld), MX1 %ld.%ld (%ld)\n", | 141 | "M %ld.%ld (%ld), MX1 %ld.%ld (%ld)\n", |
| 160 | (pmc & 3 ) == 0 ? '*' : '-', | 142 | (pmc & 3 ) == 0 ? '*' : '-', |
| 161 | fmt_freq(decode_div(pll2, pm0, 24, 1<<29, 31, px_div)), | 143 | fmt_freq(decode_div(pll2, pm0, 24, 1<<29, 31)), |
| 162 | fmt_freq(decode_div(pll2, pm0, 16, 1<<20, 15, misc_div)), | 144 | fmt_freq(decode_div(pll2, pm0, 16, 1<<20, 15)), |
| 163 | fmt_freq(decode_div(pll2, pm0, 8, 1<<12, 15, misc_div)), | 145 | fmt_freq(decode_div(pll2, pm0, 8, 1<<12, 15)), |
| 164 | fmt_freq(decode_div(pll2, pm0, 0, 1<<4, 15, misc_div))); | 146 | fmt_freq(decode_div(pll2, pm0, 0, 1<<4, 15))); |
| 165 | 147 | ||
| 166 | dev_dbg(sm->dev, "PM1[%c]: " | 148 | dev_dbg(sm->dev, "PM1[%c]: " |
| 167 | "P2 %ld.%ld MHz (%ld), V2 %ld.%ld (%ld), " | 149 | "P2 %ld.%ld MHz (%ld), V2 %ld.%ld (%ld), " |
| 168 | "M %ld.%ld (%ld), MX1 %ld.%ld (%ld)\n", | 150 | "M %ld.%ld (%ld), MX1 %ld.%ld (%ld)\n", |
| 169 | (pmc & 3 ) == 1 ? '*' : '-', | 151 | (pmc & 3 ) == 1 ? '*' : '-', |
| 170 | fmt_freq(decode_div(pll2, pm1, 24, 1<<29, 31, px_div)), | 152 | fmt_freq(decode_div(pll2, pm1, 24, 1<<29, 31)), |
| 171 | fmt_freq(decode_div(pll2, pm1, 16, 1<<20, 15, misc_div)), | 153 | fmt_freq(decode_div(pll2, pm1, 16, 1<<20, 15)), |
| 172 | fmt_freq(decode_div(pll2, pm1, 8, 1<<12, 15, misc_div)), | 154 | fmt_freq(decode_div(pll2, pm1, 8, 1<<12, 15)), |
| 173 | fmt_freq(decode_div(pll2, pm1, 0, 1<<4, 15, misc_div))); | 155 | fmt_freq(decode_div(pll2, pm1, 0, 1<<4, 15))); |
| 174 | } | 156 | } |
| 175 | 157 | ||
| 176 | static void sm501_dump_regs(struct sm501_devdata *sm) | 158 | static void sm501_dump_regs(struct sm501_devdata *sm) |
| @@ -436,46 +418,108 @@ struct sm501_clock { | |||
| 436 | unsigned long mclk; | 418 | unsigned long mclk; |
| 437 | int divider; | 419 | int divider; |
| 438 | int shift; | 420 | int shift; |
| 421 | unsigned int m, n, k; | ||
| 439 | }; | 422 | }; |
| 440 | 423 | ||
| 424 | /* sm501_calc_clock | ||
| 425 | * | ||
| 426 | * Calculates the nearest discrete clock frequency that | ||
| 427 | * can be achieved with the specified input clock. | ||
| 428 | * the maximum divisor is 3 or 5 | ||
| 429 | */ | ||
| 430 | |||
| 431 | static int sm501_calc_clock(unsigned long freq, | ||
| 432 | struct sm501_clock *clock, | ||
| 433 | int max_div, | ||
| 434 | unsigned long mclk, | ||
| 435 | long *best_diff) | ||
| 436 | { | ||
| 437 | int ret = 0; | ||
| 438 | int divider; | ||
| 439 | int shift; | ||
| 440 | long diff; | ||
| 441 | |||
| 442 | /* try dividers 1 and 3 for CRT and for panel, | ||
| 443 | try divider 5 for panel only.*/ | ||
| 444 | |||
| 445 | for (divider = 1; divider <= max_div; divider += 2) { | ||
| 446 | /* try all 8 shift values.*/ | ||
| 447 | for (shift = 0; shift < 8; shift++) { | ||
| 448 | /* Calculate difference to requested clock */ | ||
| 449 | diff = sm501fb_round_div(mclk, divider << shift) - freq; | ||
| 450 | if (diff < 0) | ||
| 451 | diff = -diff; | ||
| 452 | |||
| 453 | /* If it is less than the current, use it */ | ||
| 454 | if (diff < *best_diff) { | ||
| 455 | *best_diff = diff; | ||
| 456 | |||
| 457 | clock->mclk = mclk; | ||
| 458 | clock->divider = divider; | ||
| 459 | clock->shift = shift; | ||
| 460 | ret = 1; | ||
| 461 | } | ||
| 462 | } | ||
| 463 | } | ||
| 464 | |||
| 465 | return ret; | ||
| 466 | } | ||
| 467 | |||
| 468 | /* sm501_calc_pll | ||
| 469 | * | ||
| 470 | * Calculates the nearest discrete clock frequency that can be | ||
| 471 | * achieved using the programmable PLL. | ||
| 472 | * the maximum divisor is 3 or 5 | ||
| 473 | */ | ||
| 474 | |||
| 475 | static unsigned long sm501_calc_pll(unsigned long freq, | ||
| 476 | struct sm501_clock *clock, | ||
| 477 | int max_div) | ||
| 478 | { | ||
| 479 | unsigned long mclk; | ||
| 480 | unsigned int m, n, k; | ||
| 481 | long best_diff = 999999999; | ||
| 482 | |||
| 483 | /* | ||
| 484 | * The SM502 datasheet doesn't specify the min/max values for M and N. | ||
| 485 | * N = 1 at least doesn't work in practice. | ||
| 486 | */ | ||
| 487 | for (m = 2; m <= 255; m++) { | ||
| 488 | for (n = 2; n <= 127; n++) { | ||
| 489 | for (k = 0; k <= 1; k++) { | ||
| 490 | mclk = (24000000UL * m / n) >> k; | ||
| 491 | |||
| 492 | if (sm501_calc_clock(freq, clock, max_div, | ||
| 493 | mclk, &best_diff)) { | ||
| 494 | clock->m = m; | ||
| 495 | clock->n = n; | ||
| 496 | clock->k = k; | ||
| 497 | } | ||
| 498 | } | ||
| 499 | } | ||
| 500 | } | ||
| 501 | |||
| 502 | /* Return best clock. */ | ||
| 503 | return clock->mclk / (clock->divider << clock->shift); | ||
| 504 | } | ||
| 505 | |||
| 441 | /* sm501_select_clock | 506 | /* sm501_select_clock |
| 442 | * | 507 | * |
| 443 | * selects nearest discrete clock frequency the SM501 can achive | 508 | * Calculates the nearest discrete clock frequency that can be |
| 509 | * achieved using the 288MHz and 336MHz PLLs. | ||
| 444 | * the maximum divisor is 3 or 5 | 510 | * the maximum divisor is 3 or 5 |
| 445 | */ | 511 | */ |
| 512 | |||
| 446 | static unsigned long sm501_select_clock(unsigned long freq, | 513 | static unsigned long sm501_select_clock(unsigned long freq, |
| 447 | struct sm501_clock *clock, | 514 | struct sm501_clock *clock, |
| 448 | int max_div) | 515 | int max_div) |
| 449 | { | 516 | { |
| 450 | unsigned long mclk; | 517 | unsigned long mclk; |
| 451 | int divider; | ||
| 452 | int shift; | ||
| 453 | long diff; | ||
| 454 | long best_diff = 999999999; | 518 | long best_diff = 999999999; |
| 455 | 519 | ||
| 456 | /* Try 288MHz and 336MHz clocks. */ | 520 | /* Try 288MHz and 336MHz clocks. */ |
| 457 | for (mclk = 288000000; mclk <= 336000000; mclk += 48000000) { | 521 | for (mclk = 288000000; mclk <= 336000000; mclk += 48000000) { |
| 458 | /* try dividers 1 and 3 for CRT and for panel, | 522 | sm501_calc_clock(freq, clock, max_div, mclk, &best_diff); |
| 459 | try divider 5 for panel only.*/ | ||
| 460 | |||
| 461 | for (divider = 1; divider <= max_div; divider += 2) { | ||
| 462 | /* try all 8 shift values.*/ | ||
| 463 | for (shift = 0; shift < 8; shift++) { | ||
| 464 | /* Calculate difference to requested clock */ | ||
| 465 | diff = sm501fb_round_div(mclk, divider << shift) - freq; | ||
| 466 | if (diff < 0) | ||
| 467 | diff = -diff; | ||
| 468 | |||
| 469 | /* If it is less than the current, use it */ | ||
| 470 | if (diff < best_diff) { | ||
| 471 | best_diff = diff; | ||
| 472 | |||
| 473 | clock->mclk = mclk; | ||
| 474 | clock->divider = divider; | ||
| 475 | clock->shift = shift; | ||
| 476 | } | ||
| 477 | } | ||
| 478 | } | ||
| 479 | } | 523 | } |
| 480 | 524 | ||
| 481 | /* Return best clock. */ | 525 | /* Return best clock. */ |
| @@ -497,6 +541,7 @@ unsigned long sm501_set_clock(struct device *dev, | |||
| 497 | unsigned long gate = readl(sm->regs + SM501_CURRENT_GATE); | 541 | unsigned long gate = readl(sm->regs + SM501_CURRENT_GATE); |
| 498 | unsigned long clock = readl(sm->regs + SM501_CURRENT_CLOCK); | 542 | unsigned long clock = readl(sm->regs + SM501_CURRENT_CLOCK); |
| 499 | unsigned char reg; | 543 | unsigned char reg; |
| 544 | unsigned int pll_reg = 0; | ||
| 500 | unsigned long sm501_freq; /* the actual frequency acheived */ | 545 | unsigned long sm501_freq; /* the actual frequency acheived */ |
| 501 | 546 | ||
| 502 | struct sm501_clock to; | 547 | struct sm501_clock to; |
| @@ -511,14 +556,28 @@ unsigned long sm501_set_clock(struct device *dev, | |||
| 511 | * requested frequency the value must be multiplied by | 556 | * requested frequency the value must be multiplied by |
| 512 | * 2. This clock also has an additional pre divisor */ | 557 | * 2. This clock also has an additional pre divisor */ |
| 513 | 558 | ||
| 514 | sm501_freq = (sm501_select_clock(2 * req_freq, &to, 5) / 2); | 559 | if (sm->rev >= 0xC0) { |
| 515 | reg=to.shift & 0x07;/* bottom 3 bits are shift */ | 560 | /* SM502 -> use the programmable PLL */ |
| 516 | if (to.divider == 3) | 561 | sm501_freq = (sm501_calc_pll(2 * req_freq, |
| 517 | reg |= 0x08; /* /3 divider required */ | 562 | &to, 5) / 2); |
| 518 | else if (to.divider == 5) | 563 | reg = to.shift & 0x07;/* bottom 3 bits are shift */ |
| 519 | reg |= 0x10; /* /5 divider required */ | 564 | if (to.divider == 3) |
| 520 | if (to.mclk != 288000000) | 565 | reg |= 0x08; /* /3 divider required */ |
| 521 | reg |= 0x20; /* which mclk pll is source */ | 566 | else if (to.divider == 5) |
| 567 | reg |= 0x10; /* /5 divider required */ | ||
| 568 | reg |= 0x40; /* select the programmable PLL */ | ||
| 569 | pll_reg = 0x20000 | (to.k << 15) | (to.n << 8) | to.m; | ||
| 570 | } else { | ||
| 571 | sm501_freq = (sm501_select_clock(2 * req_freq, | ||
| 572 | &to, 5) / 2); | ||
| 573 | reg = to.shift & 0x07;/* bottom 3 bits are shift */ | ||
| 574 | if (to.divider == 3) | ||
| 575 | reg |= 0x08; /* /3 divider required */ | ||
| 576 | else if (to.divider == 5) | ||
| 577 | reg |= 0x10; /* /5 divider required */ | ||
| 578 | if (to.mclk != 288000000) | ||
| 579 | reg |= 0x20; /* which mclk pll is source */ | ||
| 580 | } | ||
| 522 | break; | 581 | break; |
| 523 | 582 | ||
| 524 | case SM501_CLOCK_V2XCLK: | 583 | case SM501_CLOCK_V2XCLK: |
| @@ -579,6 +638,10 @@ unsigned long sm501_set_clock(struct device *dev, | |||
| 579 | } | 638 | } |
| 580 | 639 | ||
| 581 | writel(mode, sm->regs + SM501_POWER_MODE_CONTROL); | 640 | writel(mode, sm->regs + SM501_POWER_MODE_CONTROL); |
| 641 | |||
| 642 | if (pll_reg) | ||
| 643 | writel(pll_reg, sm->regs + SM501_PROGRAMMABLE_PLL_CONTROL); | ||
| 644 | |||
| 582 | sm501_sync_regs(sm); | 645 | sm501_sync_regs(sm); |
| 583 | 646 | ||
| 584 | dev_info(sm->dev, "gate %08lx, clock %08lx, mode %08lx\n", | 647 | dev_info(sm->dev, "gate %08lx, clock %08lx, mode %08lx\n", |
| @@ -599,15 +662,24 @@ EXPORT_SYMBOL_GPL(sm501_set_clock); | |||
| 599 | * finds the closest available frequency for a given clock | 662 | * finds the closest available frequency for a given clock |
| 600 | */ | 663 | */ |
| 601 | 664 | ||
| 602 | unsigned long sm501_find_clock(int clksrc, | 665 | unsigned long sm501_find_clock(struct device *dev, |
| 666 | int clksrc, | ||
| 603 | unsigned long req_freq) | 667 | unsigned long req_freq) |
| 604 | { | 668 | { |
| 669 | struct sm501_devdata *sm = dev_get_drvdata(dev); | ||
| 605 | unsigned long sm501_freq; /* the frequency achiveable by the 501 */ | 670 | unsigned long sm501_freq; /* the frequency achiveable by the 501 */ |
| 606 | struct sm501_clock to; | 671 | struct sm501_clock to; |
| 607 | 672 | ||
| 608 | switch (clksrc) { | 673 | switch (clksrc) { |
| 609 | case SM501_CLOCK_P2XCLK: | 674 | case SM501_CLOCK_P2XCLK: |
| 610 | sm501_freq = (sm501_select_clock(2 * req_freq, &to, 5) / 2); | 675 | if (sm->rev >= 0xC0) { |
| 676 | /* SM502 -> use the programmable PLL */ | ||
| 677 | sm501_freq = (sm501_calc_pll(2 * req_freq, | ||
| 678 | &to, 5) / 2); | ||
| 679 | } else { | ||
| 680 | sm501_freq = (sm501_select_clock(2 * req_freq, | ||
| 681 | &to, 5) / 2); | ||
| 682 | } | ||
| 611 | break; | 683 | break; |
| 612 | 684 | ||
| 613 | case SM501_CLOCK_V2XCLK: | 685 | case SM501_CLOCK_V2XCLK: |
| @@ -914,6 +986,8 @@ static int sm501_init_dev(struct sm501_devdata *sm) | |||
| 914 | dev_info(sm->dev, "SM501 At %p: Version %08lx, %ld Mb, IRQ %d\n", | 986 | dev_info(sm->dev, "SM501 At %p: Version %08lx, %ld Mb, IRQ %d\n", |
| 915 | sm->regs, devid, (unsigned long)mem_avail >> 20, sm->irq); | 987 | sm->regs, devid, (unsigned long)mem_avail >> 20, sm->irq); |
| 916 | 988 | ||
| 989 | sm->rev = devid & SM501_DEVICEID_REVMASK; | ||
| 990 | |||
| 917 | sm501_dump_gate(sm); | 991 | sm501_dump_gate(sm); |
| 918 | 992 | ||
| 919 | ret = device_create_file(sm->dev, &dev_attr_dbg_regs); | 993 | ret = device_create_file(sm->dev, &dev_attr_dbg_regs); |
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index bb269d0c677e..6cb781262f94 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c | |||
| @@ -1078,7 +1078,8 @@ static int hotkey_get_tablet_mode(int *status) | |||
| 1078 | if (!acpi_evalf(hkey_handle, &s, "MHKG", "d")) | 1078 | if (!acpi_evalf(hkey_handle, &s, "MHKG", "d")) |
| 1079 | return -EIO; | 1079 | return -EIO; |
| 1080 | 1080 | ||
| 1081 | return ((s & TP_HOTKEY_TABLET_MASK) != 0); | 1081 | *status = ((s & TP_HOTKEY_TABLET_MASK) != 0); |
| 1082 | return 0; | ||
| 1082 | } | 1083 | } |
| 1083 | 1084 | ||
| 1084 | /* | 1085 | /* |
diff --git a/drivers/parisc/Kconfig b/drivers/parisc/Kconfig index 1d3b84b4af3f..553a9905299a 100644 --- a/drivers/parisc/Kconfig +++ b/drivers/parisc/Kconfig | |||
| @@ -103,6 +103,11 @@ config IOMMU_SBA | |||
| 103 | depends on PCI_LBA | 103 | depends on PCI_LBA |
| 104 | default PCI_LBA | 104 | default PCI_LBA |
| 105 | 105 | ||
| 106 | config IOMMU_HELPER | ||
| 107 | bool | ||
| 108 | depends on IOMMU_SBA || IOMMU_CCIO | ||
| 109 | default y | ||
| 110 | |||
| 106 | #config PCI_EPIC | 111 | #config PCI_EPIC |
| 107 | # bool "EPIC/SAGA PCI support" | 112 | # bool "EPIC/SAGA PCI support" |
| 108 | # depends on PCI | 113 | # depends on PCI |
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index d08b284de196..60d338cd8009 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c | |||
| @@ -43,6 +43,7 @@ | |||
| 43 | #include <linux/proc_fs.h> | 43 | #include <linux/proc_fs.h> |
| 44 | #include <linux/seq_file.h> | 44 | #include <linux/seq_file.h> |
| 45 | #include <linux/scatterlist.h> | 45 | #include <linux/scatterlist.h> |
| 46 | #include <linux/iommu-helper.h> | ||
| 46 | 47 | ||
| 47 | #include <asm/byteorder.h> | 48 | #include <asm/byteorder.h> |
| 48 | #include <asm/cache.h> /* for L1_CACHE_BYTES */ | 49 | #include <asm/cache.h> /* for L1_CACHE_BYTES */ |
| @@ -302,13 +303,17 @@ static int ioc_count; | |||
| 302 | */ | 303 | */ |
| 303 | #define CCIO_SEARCH_LOOP(ioc, res_idx, mask, size) \ | 304 | #define CCIO_SEARCH_LOOP(ioc, res_idx, mask, size) \ |
| 304 | for(; res_ptr < res_end; ++res_ptr) { \ | 305 | for(; res_ptr < res_end; ++res_ptr) { \ |
| 305 | if(0 == (*res_ptr & mask)) { \ | 306 | int ret;\ |
| 306 | *res_ptr |= mask; \ | 307 | unsigned int idx;\ |
| 307 | res_idx = (unsigned int)((unsigned long)res_ptr - (unsigned long)ioc->res_map); \ | 308 | idx = (unsigned int)((unsigned long)res_ptr - (unsigned long)ioc->res_map); \ |
| 308 | ioc->res_hint = res_idx + (size >> 3); \ | 309 | ret = iommu_is_span_boundary(idx << 3, pages_needed, 0, boundary_size);\ |
| 309 | goto resource_found; \ | 310 | if ((0 == (*res_ptr & mask)) && !ret) { \ |
| 310 | } \ | 311 | *res_ptr |= mask; \ |
| 311 | } | 312 | res_idx = idx;\ |
| 313 | ioc->res_hint = res_idx + (size >> 3); \ | ||
| 314 | goto resource_found; \ | ||
| 315 | } \ | ||
| 316 | } | ||
| 312 | 317 | ||
| 313 | #define CCIO_FIND_FREE_MAPPING(ioa, res_idx, mask, size) \ | 318 | #define CCIO_FIND_FREE_MAPPING(ioa, res_idx, mask, size) \ |
| 314 | u##size *res_ptr = (u##size *)&((ioc)->res_map[ioa->res_hint & ~((size >> 3) - 1)]); \ | 319 | u##size *res_ptr = (u##size *)&((ioc)->res_map[ioa->res_hint & ~((size >> 3) - 1)]); \ |
| @@ -341,10 +346,11 @@ static int ioc_count; | |||
| 341 | * of available pages for the requested size. | 346 | * of available pages for the requested size. |
| 342 | */ | 347 | */ |
| 343 | static int | 348 | static int |
| 344 | ccio_alloc_range(struct ioc *ioc, size_t size) | 349 | ccio_alloc_range(struct ioc *ioc, struct device *dev, size_t size) |
| 345 | { | 350 | { |
| 346 | unsigned int pages_needed = size >> IOVP_SHIFT; | 351 | unsigned int pages_needed = size >> IOVP_SHIFT; |
| 347 | unsigned int res_idx; | 352 | unsigned int res_idx; |
| 353 | unsigned long boundary_size; | ||
| 348 | #ifdef CCIO_SEARCH_TIME | 354 | #ifdef CCIO_SEARCH_TIME |
| 349 | unsigned long cr_start = mfctl(16); | 355 | unsigned long cr_start = mfctl(16); |
| 350 | #endif | 356 | #endif |
| @@ -360,6 +366,9 @@ ccio_alloc_range(struct ioc *ioc, size_t size) | |||
| 360 | ** ggg sacrifices another 710 to the computer gods. | 366 | ** ggg sacrifices another 710 to the computer gods. |
| 361 | */ | 367 | */ |
| 362 | 368 | ||
| 369 | boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1, 1 << IOVP_SHIFT); | ||
| 370 | boundary_size >>= IOVP_SHIFT; | ||
| 371 | |||
| 363 | if (pages_needed <= 8) { | 372 | if (pages_needed <= 8) { |
| 364 | /* | 373 | /* |
| 365 | * LAN traffic will not thrash the TLB IFF the same NIC | 374 | * LAN traffic will not thrash the TLB IFF the same NIC |
| @@ -760,7 +769,7 @@ ccio_map_single(struct device *dev, void *addr, size_t size, | |||
| 760 | ioc->msingle_pages += size >> IOVP_SHIFT; | 769 | ioc->msingle_pages += size >> IOVP_SHIFT; |
| 761 | #endif | 770 | #endif |
| 762 | 771 | ||
| 763 | idx = ccio_alloc_range(ioc, size); | 772 | idx = ccio_alloc_range(ioc, dev, size); |
| 764 | iovp = (dma_addr_t)MKIOVP(idx); | 773 | iovp = (dma_addr_t)MKIOVP(idx); |
| 765 | 774 | ||
| 766 | pdir_start = &(ioc->pdir_base[idx]); | 775 | pdir_start = &(ioc->pdir_base[idx]); |
diff --git a/drivers/parisc/iommu-helpers.h b/drivers/parisc/iommu-helpers.h index 97ba8286c596..a9c46cc2db37 100644 --- a/drivers/parisc/iommu-helpers.h +++ b/drivers/parisc/iommu-helpers.h | |||
| @@ -96,8 +96,8 @@ iommu_fill_pdir(struct ioc *ioc, struct scatterlist *startsg, int nents, | |||
| 96 | 96 | ||
| 97 | static inline unsigned int | 97 | static inline unsigned int |
| 98 | iommu_coalesce_chunks(struct ioc *ioc, struct device *dev, | 98 | iommu_coalesce_chunks(struct ioc *ioc, struct device *dev, |
| 99 | struct scatterlist *startsg, int nents, | 99 | struct scatterlist *startsg, int nents, |
| 100 | int (*iommu_alloc_range)(struct ioc *, size_t)) | 100 | int (*iommu_alloc_range)(struct ioc *, struct device *, size_t)) |
| 101 | { | 101 | { |
| 102 | struct scatterlist *contig_sg; /* contig chunk head */ | 102 | struct scatterlist *contig_sg; /* contig chunk head */ |
| 103 | unsigned long dma_offset, dma_len; /* start/len of DMA stream */ | 103 | unsigned long dma_offset, dma_len; /* start/len of DMA stream */ |
| @@ -166,7 +166,7 @@ iommu_coalesce_chunks(struct ioc *ioc, struct device *dev, | |||
| 166 | dma_len = ALIGN(dma_len + dma_offset, IOVP_SIZE); | 166 | dma_len = ALIGN(dma_len + dma_offset, IOVP_SIZE); |
| 167 | sg_dma_address(contig_sg) = | 167 | sg_dma_address(contig_sg) = |
| 168 | PIDE_FLAG | 168 | PIDE_FLAG |
| 169 | | (iommu_alloc_range(ioc, dma_len) << IOVP_SHIFT) | 169 | | (iommu_alloc_range(ioc, dev, dma_len) << IOVP_SHIFT) |
| 170 | | dma_offset; | 170 | | dma_offset; |
| 171 | n_mappings++; | 171 | n_mappings++; |
| 172 | } | 172 | } |
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index d06627c3f353..e834127a8505 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/string.h> | 29 | #include <linux/string.h> |
| 30 | #include <linux/pci.h> | 30 | #include <linux/pci.h> |
| 31 | #include <linux/scatterlist.h> | 31 | #include <linux/scatterlist.h> |
| 32 | #include <linux/iommu-helper.h> | ||
| 32 | 33 | ||
| 33 | #include <asm/byteorder.h> | 34 | #include <asm/byteorder.h> |
| 34 | #include <asm/io.h> | 35 | #include <asm/io.h> |
| @@ -313,6 +314,12 @@ sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents) | |||
| 313 | #define RESMAP_MASK(n) (~0UL << (BITS_PER_LONG - (n))) | 314 | #define RESMAP_MASK(n) (~0UL << (BITS_PER_LONG - (n))) |
| 314 | #define RESMAP_IDX_MASK (sizeof(unsigned long) - 1) | 315 | #define RESMAP_IDX_MASK (sizeof(unsigned long) - 1) |
| 315 | 316 | ||
| 317 | unsigned long ptr_to_pide(struct ioc *ioc, unsigned long *res_ptr, | ||
| 318 | unsigned int bitshiftcnt) | ||
| 319 | { | ||
| 320 | return (((unsigned long)res_ptr - (unsigned long)ioc->res_map) << 3) | ||
| 321 | + bitshiftcnt; | ||
| 322 | } | ||
| 316 | 323 | ||
| 317 | /** | 324 | /** |
| 318 | * sba_search_bitmap - find free space in IO PDIR resource bitmap | 325 | * sba_search_bitmap - find free space in IO PDIR resource bitmap |
| @@ -324,19 +331,36 @@ sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents) | |||
| 324 | * Cool perf optimization: search for log2(size) bits at a time. | 331 | * Cool perf optimization: search for log2(size) bits at a time. |
| 325 | */ | 332 | */ |
| 326 | static SBA_INLINE unsigned long | 333 | static SBA_INLINE unsigned long |
| 327 | sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted) | 334 | sba_search_bitmap(struct ioc *ioc, struct device *dev, |
| 335 | unsigned long bits_wanted) | ||
| 328 | { | 336 | { |
| 329 | unsigned long *res_ptr = ioc->res_hint; | 337 | unsigned long *res_ptr = ioc->res_hint; |
| 330 | unsigned long *res_end = (unsigned long *) &(ioc->res_map[ioc->res_size]); | 338 | unsigned long *res_end = (unsigned long *) &(ioc->res_map[ioc->res_size]); |
| 331 | unsigned long pide = ~0UL; | 339 | unsigned long pide = ~0UL, tpide; |
| 340 | unsigned long boundary_size; | ||
| 341 | unsigned long shift; | ||
| 342 | int ret; | ||
| 343 | |||
| 344 | boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1, 1 << IOVP_SHIFT); | ||
| 345 | boundary_size >>= IOVP_SHIFT; | ||
| 346 | |||
| 347 | #if defined(ZX1_SUPPORT) | ||
| 348 | BUG_ON(ioc->ibase & ~IOVP_MASK); | ||
| 349 | shift = ioc->ibase >> IOVP_SHIFT; | ||
| 350 | #else | ||
| 351 | shift = 0; | ||
| 352 | #endif | ||
| 332 | 353 | ||
| 333 | if (bits_wanted > (BITS_PER_LONG/2)) { | 354 | if (bits_wanted > (BITS_PER_LONG/2)) { |
| 334 | /* Search word at a time - no mask needed */ | 355 | /* Search word at a time - no mask needed */ |
| 335 | for(; res_ptr < res_end; ++res_ptr) { | 356 | for(; res_ptr < res_end; ++res_ptr) { |
| 336 | if (*res_ptr == 0) { | 357 | tpide = ptr_to_pide(ioc, res_ptr, 0); |
| 358 | ret = iommu_is_span_boundary(tpide, bits_wanted, | ||
| 359 | shift, | ||
| 360 | boundary_size); | ||
| 361 | if ((*res_ptr == 0) && !ret) { | ||
| 337 | *res_ptr = RESMAP_MASK(bits_wanted); | 362 | *res_ptr = RESMAP_MASK(bits_wanted); |
| 338 | pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map); | 363 | pide = tpide; |
| 339 | pide <<= 3; /* convert to bit address */ | ||
| 340 | break; | 364 | break; |
| 341 | } | 365 | } |
| 342 | } | 366 | } |
| @@ -365,11 +389,13 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted) | |||
| 365 | { | 389 | { |
| 366 | DBG_RES(" %p %lx %lx\n", res_ptr, mask, *res_ptr); | 390 | DBG_RES(" %p %lx %lx\n", res_ptr, mask, *res_ptr); |
| 367 | WARN_ON(mask == 0); | 391 | WARN_ON(mask == 0); |
| 368 | if(((*res_ptr) & mask) == 0) { | 392 | tpide = ptr_to_pide(ioc, res_ptr, bitshiftcnt); |
| 393 | ret = iommu_is_span_boundary(tpide, bits_wanted, | ||
| 394 | shift, | ||
| 395 | boundary_size); | ||
| 396 | if ((((*res_ptr) & mask) == 0) && !ret) { | ||
| 369 | *res_ptr |= mask; /* mark resources busy! */ | 397 | *res_ptr |= mask; /* mark resources busy! */ |
| 370 | pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map); | 398 | pide = tpide; |
| 371 | pide <<= 3; /* convert to bit address */ | ||
| 372 | pide += bitshiftcnt; | ||
| 373 | break; | 399 | break; |
| 374 | } | 400 | } |
| 375 | mask >>= o; | 401 | mask >>= o; |
| @@ -404,7 +430,7 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted) | |||
| 404 | * resource bit map. | 430 | * resource bit map. |
| 405 | */ | 431 | */ |
| 406 | static int | 432 | static int |
| 407 | sba_alloc_range(struct ioc *ioc, size_t size) | 433 | sba_alloc_range(struct ioc *ioc, struct device *dev, size_t size) |
| 408 | { | 434 | { |
| 409 | unsigned int pages_needed = size >> IOVP_SHIFT; | 435 | unsigned int pages_needed = size >> IOVP_SHIFT; |
| 410 | #ifdef SBA_COLLECT_STATS | 436 | #ifdef SBA_COLLECT_STATS |
| @@ -412,9 +438,9 @@ sba_alloc_range(struct ioc *ioc, size_t size) | |||
| 412 | #endif | 438 | #endif |
| 413 | unsigned long pide; | 439 | unsigned long pide; |
| 414 | 440 | ||
| 415 | pide = sba_search_bitmap(ioc, pages_needed); | 441 | pide = sba_search_bitmap(ioc, dev, pages_needed); |
| 416 | if (pide >= (ioc->res_size << 3)) { | 442 | if (pide >= (ioc->res_size << 3)) { |
| 417 | pide = sba_search_bitmap(ioc, pages_needed); | 443 | pide = sba_search_bitmap(ioc, dev, pages_needed); |
| 418 | if (pide >= (ioc->res_size << 3)) | 444 | if (pide >= (ioc->res_size << 3)) |
| 419 | panic("%s: I/O MMU @ %p is out of mapping resources\n", | 445 | panic("%s: I/O MMU @ %p is out of mapping resources\n", |
| 420 | __FILE__, ioc->ioc_hpa); | 446 | __FILE__, ioc->ioc_hpa); |
| @@ -710,7 +736,7 @@ sba_map_single(struct device *dev, void *addr, size_t size, | |||
| 710 | ioc->msingle_calls++; | 736 | ioc->msingle_calls++; |
| 711 | ioc->msingle_pages += size >> IOVP_SHIFT; | 737 | ioc->msingle_pages += size >> IOVP_SHIFT; |
| 712 | #endif | 738 | #endif |
| 713 | pide = sba_alloc_range(ioc, size); | 739 | pide = sba_alloc_range(ioc, dev, size); |
| 714 | iovp = (dma_addr_t) pide << IOVP_SHIFT; | 740 | iovp = (dma_addr_t) pide << IOVP_SHIFT; |
| 715 | 741 | ||
| 716 | DBG_RUN("%s() 0x%p -> 0x%lx\n", | 742 | DBG_RUN("%s() 0x%p -> 0x%lx\n", |
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index ef5a6a245f5f..6a9403d79e0c 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
| @@ -145,13 +145,15 @@ void pci_bus_add_devices(struct pci_bus *bus) | |||
| 145 | child_bus = dev->subordinate; | 145 | child_bus = dev->subordinate; |
| 146 | child_bus->dev.parent = child_bus->bridge; | 146 | child_bus->dev.parent = child_bus->bridge; |
| 147 | retval = device_register(&child_bus->dev); | 147 | retval = device_register(&child_bus->dev); |
| 148 | if (!retval) | 148 | if (retval) |
| 149 | dev_err(&dev->dev, "Error registering pci_bus," | ||
| 150 | " continuing...\n"); | ||
| 151 | else | ||
| 149 | retval = device_create_file(&child_bus->dev, | 152 | retval = device_create_file(&child_bus->dev, |
| 150 | &dev_attr_cpuaffinity); | 153 | &dev_attr_cpuaffinity); |
| 151 | if (retval) | 154 | if (retval) |
| 152 | dev_err(&dev->dev, "Error registering pci_bus" | 155 | dev_err(&dev->dev, "Error creating cpuaffinity" |
| 153 | " device bridge symlink," | 156 | " file, continuing...\n"); |
| 154 | " continuing...\n"); | ||
| 155 | } | 157 | } |
| 156 | } | 158 | } |
| 157 | } | 159 | } |
diff --git a/drivers/pci/hotplug-pci.c b/drivers/pci/hotplug-pci.c index a590ef682153..4d4a64478404 100644 --- a/drivers/pci/hotplug-pci.c +++ b/drivers/pci/hotplug-pci.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | #include "pci.h" | 4 | #include "pci.h" |
| 5 | 5 | ||
| 6 | 6 | ||
| 7 | unsigned int pci_do_scan_bus(struct pci_bus *bus) | 7 | unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus) |
| 8 | { | 8 | { |
| 9 | unsigned int max; | 9 | unsigned int max; |
| 10 | 10 | ||
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index cf22f9e01e00..5e50008d1181 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
| @@ -1085,7 +1085,7 @@ static int acpiphp_bus_trim(acpi_handle handle) | |||
| 1085 | * This function should be called per *physical slot*, | 1085 | * This function should be called per *physical slot*, |
| 1086 | * not per each slot object in ACPI namespace. | 1086 | * not per each slot object in ACPI namespace. |
| 1087 | */ | 1087 | */ |
| 1088 | static int enable_device(struct acpiphp_slot *slot) | 1088 | static int __ref enable_device(struct acpiphp_slot *slot) |
| 1089 | { | 1089 | { |
| 1090 | struct pci_dev *dev; | 1090 | struct pci_dev *dev; |
| 1091 | struct pci_bus *bus = slot->bridge->pci_bus; | 1091 | struct pci_bus *bus = slot->bridge->pci_bus; |
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index 5e9be44817cb..b3515fc4cd38 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c | |||
| @@ -250,7 +250,7 @@ int cpci_led_off(struct slot* slot) | |||
| 250 | * Device configuration functions | 250 | * Device configuration functions |
| 251 | */ | 251 | */ |
| 252 | 252 | ||
| 253 | int cpci_configure_slot(struct slot* slot) | 253 | int __ref cpci_configure_slot(struct slot *slot) |
| 254 | { | 254 | { |
| 255 | struct pci_bus *parent; | 255 | struct pci_bus *parent; |
| 256 | int fn; | 256 | int fn; |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 6eba9b2cfb90..698975a6a21c 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
| @@ -711,7 +711,8 @@ static int hpc_power_off_slot(struct slot * slot) | |||
| 711 | retval = pcie_write_cmd(slot, slot_cmd, cmd_mask); | 711 | retval = pcie_write_cmd(slot, slot_cmd, cmd_mask); |
| 712 | if (retval) { | 712 | if (retval) { |
| 713 | err("%s: Write command failed!\n", __FUNCTION__); | 713 | err("%s: Write command failed!\n", __FUNCTION__); |
| 714 | return -1; | 714 | retval = -1; |
| 715 | goto out; | ||
| 715 | } | 716 | } |
| 716 | dbg("%s: SLOTCTRL %x write cmd %x\n", | 717 | dbg("%s: SLOTCTRL %x write cmd %x\n", |
| 717 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); | 718 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); |
| @@ -722,7 +723,7 @@ static int hpc_power_off_slot(struct slot * slot) | |||
| 722 | * removed from the slot/adapter. | 723 | * removed from the slot/adapter. |
| 723 | */ | 724 | */ |
| 724 | msleep(1000); | 725 | msleep(1000); |
| 725 | 726 | out: | |
| 726 | if (changed) | 727 | if (changed) |
| 727 | pcie_unmask_bad_dllp(ctrl); | 728 | pcie_unmask_bad_dllp(ctrl); |
| 728 | 729 | ||
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index dd50713966d1..9372a840b63d 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c | |||
| @@ -167,7 +167,7 @@ static void program_fw_provided_values(struct pci_dev *dev) | |||
| 167 | } | 167 | } |
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | static int pciehp_add_bridge(struct pci_dev *dev) | 170 | static int __ref pciehp_add_bridge(struct pci_dev *dev) |
| 171 | { | 171 | { |
| 172 | struct pci_bus *parent = dev->bus; | 172 | struct pci_bus *parent = dev->bus; |
| 173 | int pass, busnr, start = parent->secondary; | 173 | int pass, busnr, start = parent->secondary; |
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c index 0a6b25ef194c..a69a21520895 100644 --- a/drivers/pci/hotplug/shpchp_pci.c +++ b/drivers/pci/hotplug/shpchp_pci.c | |||
| @@ -96,7 +96,7 @@ static void program_fw_provided_values(struct pci_dev *dev) | |||
| 96 | } | 96 | } |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | int shpchp_configure_device(struct slot *p_slot) | 99 | int __ref shpchp_configure_device(struct slot *p_slot) |
| 100 | { | 100 | { |
| 101 | struct pci_dev *dev; | 101 | struct pci_dev *dev; |
| 102 | struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; | 102 | struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 4d23b9fb551b..2db2e4bb0d1e 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
| @@ -286,7 +286,7 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) | |||
| 286 | } | 286 | } |
| 287 | } | 287 | } |
| 288 | 288 | ||
| 289 | void pci_read_bridge_bases(struct pci_bus *child) | 289 | void __devinit pci_read_bridge_bases(struct pci_bus *child) |
| 290 | { | 290 | { |
| 291 | struct pci_dev *dev = child->self; | 291 | struct pci_dev *dev = child->self; |
| 292 | u8 io_base_lo, io_limit_lo; | 292 | u8 io_base_lo, io_limit_lo; |
| @@ -472,7 +472,7 @@ static void pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max) | |||
| 472 | * them, we proceed to assigning numbers to the remaining buses in | 472 | * them, we proceed to assigning numbers to the remaining buses in |
| 473 | * order to avoid overlaps between old and new bus numbers. | 473 | * order to avoid overlaps between old and new bus numbers. |
| 474 | */ | 474 | */ |
| 475 | int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass) | 475 | int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass) |
| 476 | { | 476 | { |
| 477 | struct pci_bus *child; | 477 | struct pci_bus *child; |
| 478 | int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); | 478 | int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); |
| @@ -1008,7 +1008,7 @@ int pci_scan_slot(struct pci_bus *bus, int devfn) | |||
| 1008 | return nr; | 1008 | return nr; |
| 1009 | } | 1009 | } |
| 1010 | 1010 | ||
| 1011 | unsigned int pci_scan_child_bus(struct pci_bus *bus) | 1011 | unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) |
| 1012 | { | 1012 | { |
| 1013 | unsigned int devfn, pass, max = bus->secondary; | 1013 | unsigned int devfn, pass, max = bus->secondary; |
| 1014 | struct pci_dev *dev; | 1014 | struct pci_dev *dev; |
| @@ -1116,7 +1116,7 @@ err_out: | |||
| 1116 | return NULL; | 1116 | return NULL; |
| 1117 | } | 1117 | } |
| 1118 | 1118 | ||
| 1119 | struct pci_bus *pci_scan_bus_parented(struct device *parent, | 1119 | struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, |
| 1120 | int bus, struct pci_ops *ops, void *sysdata) | 1120 | int bus, struct pci_ops *ops, void *sysdata) |
| 1121 | { | 1121 | { |
| 1122 | struct pci_bus *b; | 1122 | struct pci_bus *b; |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index bbad4a9f264f..e9a333d98552 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
| @@ -1652,9 +1652,8 @@ static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev) | |||
| 1652 | pci_write_config_byte(dev, 0x75, 0x1); | 1652 | pci_write_config_byte(dev, 0x75, 0x1); |
| 1653 | pci_write_config_byte(dev, 0x77, 0x0); | 1653 | pci_write_config_byte(dev, 0x77, 0x0); |
| 1654 | 1654 | ||
| 1655 | printk(KERN_INFO | 1655 | dev_info(&dev->dev, |
| 1656 | "PCI: VIA CX700 PCI parking/caching fixup on %s\n", | 1656 | "Disabling VIA CX700 PCI parking/caching\n"); |
| 1657 | pci_name(dev)); | ||
| 1658 | } | 1657 | } |
| 1659 | } | 1658 | } |
| 1660 | } | 1659 | } |
| @@ -1726,32 +1725,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2 | |||
| 1726 | quirk_msi_ht_cap); | 1725 | quirk_msi_ht_cap); |
| 1727 | 1726 | ||
| 1728 | 1727 | ||
| 1729 | /* | ||
| 1730 | * Force enable MSI mapping capability on HT bridges | ||
| 1731 | */ | ||
| 1732 | static void __devinit quirk_msi_ht_cap_enable(struct pci_dev *dev) | ||
| 1733 | { | ||
| 1734 | int pos, ttl = 48; | ||
| 1735 | |||
| 1736 | pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); | ||
| 1737 | while (pos && ttl--) { | ||
| 1738 | u8 flags; | ||
| 1739 | |||
| 1740 | if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, &flags) == 0) { | ||
| 1741 | printk(KERN_INFO "PCI: Enabling HT MSI Mapping on %s\n", | ||
| 1742 | pci_name(dev)); | ||
| 1743 | |||
| 1744 | pci_write_config_byte(dev, pos + HT_MSI_FLAGS, | ||
| 1745 | flags | HT_MSI_FLAGS_ENABLE); | ||
| 1746 | } | ||
| 1747 | pos = pci_find_next_ht_capability(dev, pos, | ||
| 1748 | HT_CAPTYPE_MSI_MAPPING); | ||
| 1749 | } | ||
| 1750 | } | ||
| 1751 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, | ||
| 1752 | PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB, | ||
| 1753 | quirk_msi_ht_cap_enable); | ||
| 1754 | |||
| 1755 | /* The nVidia CK804 chipset may have 2 HT MSI mappings. | 1728 | /* The nVidia CK804 chipset may have 2 HT MSI mappings. |
| 1756 | * MSI are supported if the MSI capability set in any of these mappings. | 1729 | * MSI are supported if the MSI capability set in any of these mappings. |
| 1757 | */ | 1730 | */ |
| @@ -1778,9 +1751,8 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev) | |||
| 1778 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, | 1751 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, |
| 1779 | quirk_nvidia_ck804_msi_ht_cap); | 1752 | quirk_nvidia_ck804_msi_ht_cap); |
| 1780 | 1753 | ||
| 1781 | /* | 1754 | /* Force enable MSI mapping capability on HT bridges */ |
| 1782 | * Force enable MSI mapping capability on HT bridges */ | 1755 | static void __devinit ht_enable_msi_mapping(struct pci_dev *dev) |
| 1783 | static inline void ht_enable_msi_mapping(struct pci_dev *dev) | ||
| 1784 | { | 1756 | { |
| 1785 | int pos, ttl = 48; | 1757 | int pos, ttl = 48; |
| 1786 | 1758 | ||
| @@ -1799,6 +1771,9 @@ static inline void ht_enable_msi_mapping(struct pci_dev *dev) | |||
| 1799 | HT_CAPTYPE_MSI_MAPPING); | 1771 | HT_CAPTYPE_MSI_MAPPING); |
| 1800 | } | 1772 | } |
| 1801 | } | 1773 | } |
| 1774 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, | ||
| 1775 | PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB, | ||
| 1776 | ht_enable_msi_mapping); | ||
| 1802 | 1777 | ||
| 1803 | static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) | 1778 | static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) |
| 1804 | { | 1779 | { |
| @@ -1830,7 +1805,7 @@ static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) | |||
| 1830 | 1805 | ||
| 1831 | if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, | 1806 | if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, |
| 1832 | &flags) == 0) { | 1807 | &flags) == 0) { |
| 1833 | dev_info(&dev->dev, "Quirk disabling HT MSI mapping"); | 1808 | dev_info(&dev->dev, "Disabling HT MSI mapping"); |
| 1834 | pci_write_config_byte(dev, pos + HT_MSI_FLAGS, | 1809 | pci_write_config_byte(dev, pos + HT_MSI_FLAGS, |
| 1835 | flags & ~HT_MSI_FLAGS_ENABLE); | 1810 | flags & ~HT_MSI_FLAGS_ENABLE); |
| 1836 | } | 1811 | } |
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 6402d699072b..82f5ad9c3af4 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
| @@ -250,6 +250,15 @@ config RTC_DRV_TWL92330 | |||
| 250 | platforms. The support is integrated with the rest of | 250 | platforms. The support is integrated with the rest of |
| 251 | the Menelaus driver; it's not separate module. | 251 | the Menelaus driver; it's not separate module. |
| 252 | 252 | ||
| 253 | config RTC_DRV_S35390A | ||
| 254 | tristate "Seiko Instruments S-35390A" | ||
| 255 | help | ||
| 256 | If you say yes here you will get support for the Seiko | ||
| 257 | Instruments S-35390A. | ||
| 258 | |||
| 259 | This driver can also be built as a module. If so the module | ||
| 260 | will be called rtc-s35390a. | ||
| 261 | |||
| 253 | endif # I2C | 262 | endif # I2C |
| 254 | 263 | ||
| 255 | comment "SPI RTC drivers" | 264 | comment "SPI RTC drivers" |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index ec703f34ab86..872f1218ff9f 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
| @@ -45,6 +45,7 @@ obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o | |||
| 45 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o | 45 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o |
| 46 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o | 46 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o |
| 47 | obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o | 47 | obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o |
| 48 | obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o | ||
| 48 | obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o | 49 | obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o |
| 49 | obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o | 50 | obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o |
| 50 | obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o | 51 | obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o |
diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c new file mode 100644 index 000000000000..e8abc90c32c5 --- /dev/null +++ b/drivers/rtc/rtc-s35390a.c | |||
| @@ -0,0 +1,316 @@ | |||
| 1 | /* | ||
| 2 | * Seiko Instruments S-35390A RTC Driver | ||
| 3 | * | ||
| 4 | * Copyright (c) 2007 Byron Bradley | ||
| 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 | |||
| 12 | #include <linux/module.h> | ||
| 13 | #include <linux/rtc.h> | ||
| 14 | #include <linux/i2c.h> | ||
| 15 | #include <linux/bitrev.h> | ||
| 16 | #include <linux/bcd.h> | ||
| 17 | #include <linux/slab.h> | ||
| 18 | |||
| 19 | #define S35390A_CMD_STATUS1 0 | ||
| 20 | #define S35390A_CMD_STATUS2 1 | ||
| 21 | #define S35390A_CMD_TIME1 2 | ||
| 22 | |||
| 23 | #define S35390A_BYTE_YEAR 0 | ||
| 24 | #define S35390A_BYTE_MONTH 1 | ||
| 25 | #define S35390A_BYTE_DAY 2 | ||
| 26 | #define S35390A_BYTE_WDAY 3 | ||
| 27 | #define S35390A_BYTE_HOURS 4 | ||
| 28 | #define S35390A_BYTE_MINS 5 | ||
| 29 | #define S35390A_BYTE_SECS 6 | ||
| 30 | |||
| 31 | #define S35390A_FLAG_POC 0x01 | ||
| 32 | #define S35390A_FLAG_BLD 0x02 | ||
| 33 | #define S35390A_FLAG_24H 0x40 | ||
| 34 | #define S35390A_FLAG_RESET 0x80 | ||
| 35 | #define S35390A_FLAG_TEST 0x01 | ||
| 36 | |||
| 37 | struct s35390a { | ||
| 38 | struct i2c_client *client[8]; | ||
| 39 | struct rtc_device *rtc; | ||
| 40 | int twentyfourhour; | ||
| 41 | }; | ||
| 42 | |||
| 43 | static int s35390a_set_reg(struct s35390a *s35390a, int reg, char *buf, int len) | ||
| 44 | { | ||
| 45 | struct i2c_client *client = s35390a->client[reg]; | ||
| 46 | struct i2c_msg msg[] = { | ||
| 47 | { client->addr, 0, len, buf }, | ||
| 48 | }; | ||
| 49 | |||
| 50 | if ((i2c_transfer(client->adapter, msg, 1)) != 1) | ||
| 51 | return -EIO; | ||
| 52 | |||
| 53 | return 0; | ||
| 54 | } | ||
| 55 | |||
| 56 | static int s35390a_get_reg(struct s35390a *s35390a, int reg, char *buf, int len) | ||
| 57 | { | ||
| 58 | struct i2c_client *client = s35390a->client[reg]; | ||
| 59 | struct i2c_msg msg[] = { | ||
| 60 | { client->addr, I2C_M_RD, len, buf }, | ||
| 61 | }; | ||
| 62 | |||
| 63 | if ((i2c_transfer(client->adapter, msg, 1)) != 1) | ||
| 64 | return -EIO; | ||
| 65 | |||
| 66 | return 0; | ||
| 67 | } | ||
| 68 | |||
| 69 | static int s35390a_reset(struct s35390a *s35390a) | ||
| 70 | { | ||
| 71 | char buf[1]; | ||
| 72 | |||
| 73 | if (s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf)) < 0) | ||
| 74 | return -EIO; | ||
| 75 | |||
| 76 | if (!(buf[0] & (S35390A_FLAG_POC | S35390A_FLAG_BLD))) | ||
| 77 | return 0; | ||
| 78 | |||
| 79 | buf[0] |= (S35390A_FLAG_RESET | S35390A_FLAG_24H); | ||
| 80 | buf[0] &= 0xf0; | ||
| 81 | return s35390a_set_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf)); | ||
| 82 | } | ||
| 83 | |||
| 84 | static int s35390a_disable_test_mode(struct s35390a *s35390a) | ||
| 85 | { | ||
| 86 | char buf[1]; | ||
| 87 | |||
| 88 | if (s35390a_get_reg(s35390a, S35390A_CMD_STATUS2, buf, sizeof(buf)) < 0) | ||
| 89 | return -EIO; | ||
| 90 | |||
| 91 | if (!(buf[0] & S35390A_FLAG_TEST)) | ||
| 92 | return 0; | ||
| 93 | |||
| 94 | buf[0] &= ~S35390A_FLAG_TEST; | ||
| 95 | return s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, buf, sizeof(buf)); | ||
| 96 | } | ||
| 97 | |||
| 98 | static char s35390a_hr2reg(struct s35390a *s35390a, int hour) | ||
| 99 | { | ||
| 100 | if (s35390a->twentyfourhour) | ||
| 101 | return BIN2BCD(hour); | ||
| 102 | |||
| 103 | if (hour < 12) | ||
| 104 | return BIN2BCD(hour); | ||
| 105 | |||
| 106 | return 0x40 | BIN2BCD(hour - 12); | ||
| 107 | } | ||
| 108 | |||
| 109 | static int s35390a_reg2hr(struct s35390a *s35390a, char reg) | ||
| 110 | { | ||
| 111 | unsigned hour; | ||
| 112 | |||
| 113 | if (s35390a->twentyfourhour) | ||
| 114 | return BCD2BIN(reg & 0x3f); | ||
| 115 | |||
| 116 | hour = BCD2BIN(reg & 0x3f); | ||
| 117 | if (reg & 0x40) | ||
| 118 | hour += 12; | ||
| 119 | |||
| 120 | return hour; | ||
| 121 | } | ||
| 122 | |||
| 123 | static int s35390a_set_datetime(struct i2c_client *client, struct rtc_time *tm) | ||
| 124 | { | ||
| 125 | struct s35390a *s35390a = i2c_get_clientdata(client); | ||
| 126 | int i, err; | ||
| 127 | char buf[7]; | ||
| 128 | |||
| 129 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d mday=%d, " | ||
| 130 | "mon=%d, year=%d, wday=%d\n", __func__, tm->tm_sec, | ||
| 131 | tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, | ||
| 132 | tm->tm_wday); | ||
| 133 | |||
| 134 | buf[S35390A_BYTE_YEAR] = BIN2BCD(tm->tm_year - 100); | ||
| 135 | buf[S35390A_BYTE_MONTH] = BIN2BCD(tm->tm_mon + 1); | ||
| 136 | buf[S35390A_BYTE_DAY] = BIN2BCD(tm->tm_mday); | ||
| 137 | buf[S35390A_BYTE_WDAY] = BIN2BCD(tm->tm_wday); | ||
| 138 | buf[S35390A_BYTE_HOURS] = s35390a_hr2reg(s35390a, tm->tm_hour); | ||
| 139 | buf[S35390A_BYTE_MINS] = BIN2BCD(tm->tm_min); | ||
| 140 | buf[S35390A_BYTE_SECS] = BIN2BCD(tm->tm_sec); | ||
| 141 | |||
| 142 | /* This chip expects the bits of each byte to be in reverse order */ | ||
| 143 | for (i = 0; i < 7; ++i) | ||
| 144 | buf[i] = bitrev8(buf[i]); | ||
| 145 | |||
| 146 | err = s35390a_set_reg(s35390a, S35390A_CMD_TIME1, buf, sizeof(buf)); | ||
| 147 | |||
| 148 | return err; | ||
| 149 | } | ||
| 150 | |||
| 151 | static int s35390a_get_datetime(struct i2c_client *client, struct rtc_time *tm) | ||
| 152 | { | ||
| 153 | struct s35390a *s35390a = i2c_get_clientdata(client); | ||
| 154 | char buf[7]; | ||
| 155 | int i, err; | ||
| 156 | |||
| 157 | err = s35390a_get_reg(s35390a, S35390A_CMD_TIME1, buf, sizeof(buf)); | ||
| 158 | if (err < 0) | ||
| 159 | return err; | ||
| 160 | |||
| 161 | /* This chip returns the bits of each byte in reverse order */ | ||
| 162 | for (i = 0; i < 7; ++i) | ||
| 163 | buf[i] = bitrev8(buf[i]); | ||
| 164 | |||
| 165 | tm->tm_sec = BCD2BIN(buf[S35390A_BYTE_SECS]); | ||
| 166 | tm->tm_min = BCD2BIN(buf[S35390A_BYTE_MINS]); | ||
| 167 | tm->tm_hour = s35390a_reg2hr(s35390a, buf[S35390A_BYTE_HOURS]); | ||
| 168 | tm->tm_wday = BCD2BIN(buf[S35390A_BYTE_WDAY]); | ||
| 169 | tm->tm_mday = BCD2BIN(buf[S35390A_BYTE_DAY]); | ||
| 170 | tm->tm_mon = BCD2BIN(buf[S35390A_BYTE_MONTH]) - 1; | ||
| 171 | tm->tm_year = BCD2BIN(buf[S35390A_BYTE_YEAR]) + 100; | ||
| 172 | |||
| 173 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, mday=%d, " | ||
| 174 | "mon=%d, year=%d, wday=%d\n", __func__, tm->tm_sec, | ||
| 175 | tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, | ||
| 176 | tm->tm_wday); | ||
| 177 | |||
| 178 | return rtc_valid_tm(tm); | ||
| 179 | } | ||
| 180 | |||
| 181 | static int s35390a_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
| 182 | { | ||
| 183 | return s35390a_get_datetime(to_i2c_client(dev), tm); | ||
| 184 | } | ||
| 185 | |||
| 186 | static int s35390a_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
| 187 | { | ||
| 188 | return s35390a_set_datetime(to_i2c_client(dev), tm); | ||
| 189 | } | ||
| 190 | |||
| 191 | static const struct rtc_class_ops s35390a_rtc_ops = { | ||
| 192 | .read_time = s35390a_rtc_read_time, | ||
| 193 | .set_time = s35390a_rtc_set_time, | ||
| 194 | }; | ||
| 195 | |||
| 196 | static struct i2c_driver s35390a_driver; | ||
| 197 | |||
| 198 | static int s35390a_probe(struct i2c_client *client) | ||
| 199 | { | ||
| 200 | int err; | ||
| 201 | unsigned int i; | ||
| 202 | struct s35390a *s35390a; | ||
| 203 | struct rtc_time tm; | ||
| 204 | char buf[1]; | ||
| 205 | |||
| 206 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | ||
| 207 | err = -ENODEV; | ||
| 208 | goto exit; | ||
| 209 | } | ||
| 210 | |||
| 211 | s35390a = kzalloc(sizeof(struct s35390a), GFP_KERNEL); | ||
| 212 | if (!s35390a) { | ||
| 213 | err = -ENOMEM; | ||
| 214 | goto exit; | ||
| 215 | } | ||
| 216 | |||
| 217 | s35390a->client[0] = client; | ||
| 218 | i2c_set_clientdata(client, s35390a); | ||
| 219 | |||
| 220 | /* This chip uses multiple addresses, use dummy devices for them */ | ||
| 221 | for (i = 1; i < 8; ++i) { | ||
| 222 | s35390a->client[i] = i2c_new_dummy(client->adapter, | ||
| 223 | client->addr + i, "rtc-s35390a"); | ||
| 224 | if (!s35390a->client[i]) { | ||
| 225 | dev_err(&client->dev, "Address %02x unavailable\n", | ||
| 226 | client->addr + i); | ||
| 227 | err = -EBUSY; | ||
| 228 | goto exit_dummy; | ||
| 229 | } | ||
| 230 | } | ||
| 231 | |||
| 232 | err = s35390a_reset(s35390a); | ||
| 233 | if (err < 0) { | ||
| 234 | dev_err(&client->dev, "error resetting chip\n"); | ||
| 235 | goto exit_dummy; | ||
| 236 | } | ||
| 237 | |||
| 238 | err = s35390a_disable_test_mode(s35390a); | ||
| 239 | if (err < 0) { | ||
| 240 | dev_err(&client->dev, "error disabling test mode\n"); | ||
| 241 | goto exit_dummy; | ||
| 242 | } | ||
| 243 | |||
| 244 | err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf)); | ||
| 245 | if (err < 0) { | ||
| 246 | dev_err(&client->dev, "error checking 12/24 hour mode\n"); | ||
| 247 | goto exit_dummy; | ||
| 248 | } | ||
| 249 | if (buf[0] & S35390A_FLAG_24H) | ||
| 250 | s35390a->twentyfourhour = 1; | ||
| 251 | else | ||
| 252 | s35390a->twentyfourhour = 0; | ||
| 253 | |||
| 254 | if (s35390a_get_datetime(client, &tm) < 0) | ||
| 255 | dev_warn(&client->dev, "clock needs to be set\n"); | ||
| 256 | |||
| 257 | s35390a->rtc = rtc_device_register(s35390a_driver.driver.name, | ||
| 258 | &client->dev, &s35390a_rtc_ops, THIS_MODULE); | ||
| 259 | |||
| 260 | if (IS_ERR(s35390a->rtc)) { | ||
| 261 | err = PTR_ERR(s35390a->rtc); | ||
| 262 | goto exit_dummy; | ||
| 263 | } | ||
| 264 | return 0; | ||
| 265 | |||
| 266 | exit_dummy: | ||
| 267 | for (i = 1; i < 8; ++i) | ||
| 268 | if (s35390a->client[i]) | ||
| 269 | i2c_unregister_device(s35390a->client[i]); | ||
| 270 | kfree(s35390a); | ||
| 271 | i2c_set_clientdata(client, NULL); | ||
| 272 | |||
| 273 | exit: | ||
| 274 | return err; | ||
| 275 | } | ||
| 276 | |||
| 277 | static int s35390a_remove(struct i2c_client *client) | ||
| 278 | { | ||
| 279 | unsigned int i; | ||
| 280 | |||
| 281 | struct s35390a *s35390a = i2c_get_clientdata(client); | ||
| 282 | for (i = 1; i < 8; ++i) | ||
| 283 | if (s35390a->client[i]) | ||
| 284 | i2c_unregister_device(s35390a->client[i]); | ||
| 285 | |||
| 286 | rtc_device_unregister(s35390a->rtc); | ||
| 287 | kfree(s35390a); | ||
| 288 | i2c_set_clientdata(client, NULL); | ||
| 289 | |||
| 290 | return 0; | ||
| 291 | } | ||
| 292 | |||
| 293 | static struct i2c_driver s35390a_driver = { | ||
| 294 | .driver = { | ||
| 295 | .name = "rtc-s35390a", | ||
| 296 | }, | ||
| 297 | .probe = s35390a_probe, | ||
| 298 | .remove = s35390a_remove, | ||
| 299 | }; | ||
| 300 | |||
| 301 | static int __init s35390a_rtc_init(void) | ||
| 302 | { | ||
| 303 | return i2c_add_driver(&s35390a_driver); | ||
| 304 | } | ||
| 305 | |||
| 306 | static void __exit s35390a_rtc_exit(void) | ||
| 307 | { | ||
| 308 | i2c_del_driver(&s35390a_driver); | ||
| 309 | } | ||
| 310 | |||
| 311 | MODULE_AUTHOR("Byron Bradley <byron.bbradley@gmail.com>"); | ||
| 312 | MODULE_DESCRIPTION("S35390A RTC driver"); | ||
| 313 | MODULE_LICENSE("GPL"); | ||
| 314 | |||
| 315 | module_init(s35390a_rtc_init); | ||
| 316 | module_exit(s35390a_rtc_exit); | ||
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c index 6f09cbd7fc48..97c68d021d28 100644 --- a/drivers/serial/8250_pnp.c +++ b/drivers/serial/8250_pnp.c | |||
| @@ -91,6 +91,8 @@ static const struct pnp_device_id pnp_dev_table[] = { | |||
| 91 | /* Archtek America Corp. */ | 91 | /* Archtek America Corp. */ |
| 92 | /* Archtek SmartLink Modem 3334BT Plug & Play */ | 92 | /* Archtek SmartLink Modem 3334BT Plug & Play */ |
| 93 | { "GVC000F", 0 }, | 93 | { "GVC000F", 0 }, |
| 94 | /* Archtek SmartLink Modem 3334BRV 33.6K Data Fax Voice */ | ||
| 95 | { "GVC0303", 0 }, | ||
| 94 | /* Hayes */ | 96 | /* Hayes */ |
| 95 | /* Hayes Optima 288 V.34-V.FC + FAX + Voice Plug & Play */ | 97 | /* Hayes Optima 288 V.34-V.FC + FAX + Voice Plug & Play */ |
| 96 | { "HAY0001", 0 }, | 98 | { "HAY0001", 0 }, |
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c index 348ee2c19b58..c2bb11c02bde 100644 --- a/drivers/serial/m32r_sio.c +++ b/drivers/serial/m32r_sio.c | |||
| @@ -421,7 +421,7 @@ static void transmit_chars(struct uart_sio_port *up) | |||
| 421 | up->port.icount.tx++; | 421 | up->port.icount.tx++; |
| 422 | if (uart_circ_empty(xmit)) | 422 | if (uart_circ_empty(xmit)) |
| 423 | break; | 423 | break; |
| 424 | while (!serial_in(up, UART_LSR) & UART_LSR_THRE); | 424 | while (!(serial_in(up, UART_LSR) & UART_LSR_THRE)); |
| 425 | 425 | ||
| 426 | } while (--count > 0); | 426 | } while (--count > 0); |
| 427 | 427 | ||
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c index 253ed5682a6d..a86315a0c5b8 100644 --- a/drivers/spi/mpc52xx_psc_spi.c +++ b/drivers/spi/mpc52xx_psc_spi.c | |||
| @@ -42,6 +42,7 @@ struct mpc52xx_psc_spi { | |||
| 42 | 42 | ||
| 43 | /* driver internal data */ | 43 | /* driver internal data */ |
| 44 | struct mpc52xx_psc __iomem *psc; | 44 | struct mpc52xx_psc __iomem *psc; |
| 45 | struct mpc52xx_psc_fifo __iomem *fifo; | ||
| 45 | unsigned int irq; | 46 | unsigned int irq; |
| 46 | u8 bits_per_word; | 47 | u8 bits_per_word; |
| 47 | u8 busy; | 48 | u8 busy; |
| @@ -139,6 +140,7 @@ static int mpc52xx_psc_spi_transfer_rxtx(struct spi_device *spi, | |||
| 139 | { | 140 | { |
| 140 | struct mpc52xx_psc_spi *mps = spi_master_get_devdata(spi->master); | 141 | struct mpc52xx_psc_spi *mps = spi_master_get_devdata(spi->master); |
| 141 | struct mpc52xx_psc __iomem *psc = mps->psc; | 142 | struct mpc52xx_psc __iomem *psc = mps->psc; |
| 143 | struct mpc52xx_psc_fifo __iomem *fifo = mps->fifo; | ||
| 142 | unsigned rb = 0; /* number of bytes receieved */ | 144 | unsigned rb = 0; /* number of bytes receieved */ |
| 143 | unsigned sb = 0; /* number of bytes sent */ | 145 | unsigned sb = 0; /* number of bytes sent */ |
| 144 | unsigned char *rx_buf = (unsigned char *)t->rx_buf; | 146 | unsigned char *rx_buf = (unsigned char *)t->rx_buf; |
| @@ -190,11 +192,11 @@ static int mpc52xx_psc_spi_transfer_rxtx(struct spi_device *spi, | |||
| 190 | out_8(&psc->mode, 0); | 192 | out_8(&psc->mode, 0); |
| 191 | } else { | 193 | } else { |
| 192 | out_8(&psc->mode, MPC52xx_PSC_MODE_FFULL); | 194 | out_8(&psc->mode, MPC52xx_PSC_MODE_FFULL); |
| 193 | out_be16(&psc->rfalarm, rfalarm); | 195 | out_be16(&fifo->rfalarm, rfalarm); |
| 194 | } | 196 | } |
| 195 | out_be16(&psc->mpc52xx_psc_imr, MPC52xx_PSC_IMR_RXRDY); | 197 | out_be16(&psc->mpc52xx_psc_imr, MPC52xx_PSC_IMR_RXRDY); |
| 196 | wait_for_completion(&mps->done); | 198 | wait_for_completion(&mps->done); |
| 197 | recv_at_once = in_be16(&psc->rfnum); | 199 | recv_at_once = in_be16(&fifo->rfnum); |
| 198 | dev_dbg(&spi->dev, "%d bytes received\n", recv_at_once); | 200 | dev_dbg(&spi->dev, "%d bytes received\n", recv_at_once); |
| 199 | 201 | ||
| 200 | send_at_once = recv_at_once; | 202 | send_at_once = recv_at_once; |
| @@ -331,6 +333,7 @@ static void mpc52xx_psc_spi_cleanup(struct spi_device *spi) | |||
| 331 | static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps) | 333 | static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps) |
| 332 | { | 334 | { |
| 333 | struct mpc52xx_psc __iomem *psc = mps->psc; | 335 | struct mpc52xx_psc __iomem *psc = mps->psc; |
| 336 | struct mpc52xx_psc_fifo __iomem *fifo = mps->fifo; | ||
| 334 | u32 mclken_div; | 337 | u32 mclken_div; |
| 335 | int ret = 0; | 338 | int ret = 0; |
| 336 | 339 | ||
| @@ -346,7 +349,7 @@ static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps) | |||
| 346 | /* Disable interrupts, interrupts are based on alarm level */ | 349 | /* Disable interrupts, interrupts are based on alarm level */ |
| 347 | out_be16(&psc->mpc52xx_psc_imr, 0); | 350 | out_be16(&psc->mpc52xx_psc_imr, 0); |
| 348 | out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1); | 351 | out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1); |
| 349 | out_8(&psc->rfcntl, 0); | 352 | out_8(&fifo->rfcntl, 0); |
| 350 | out_8(&psc->mode, MPC52xx_PSC_MODE_FFULL); | 353 | out_8(&psc->mode, MPC52xx_PSC_MODE_FFULL); |
| 351 | 354 | ||
| 352 | /* Configure 8bit codec mode as a SPI master and use EOF flags */ | 355 | /* Configure 8bit codec mode as a SPI master and use EOF flags */ |
| @@ -419,6 +422,8 @@ static int __init mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr, | |||
| 419 | ret = -EFAULT; | 422 | ret = -EFAULT; |
| 420 | goto free_master; | 423 | goto free_master; |
| 421 | } | 424 | } |
| 425 | /* On the 5200, fifo regs are immediately ajacent to the psc regs */ | ||
| 426 | mps->fifo = ((void __iomem *)mps->psc) + sizeof(struct mpc52xx_psc); | ||
| 422 | 427 | ||
| 423 | ret = request_irq(mps->irq, mpc52xx_psc_spi_isr, 0, "mpc52xx-psc-spi", | 428 | ret = request_irq(mps->irq, mpc52xx_psc_spi_isr, 0, "mpc52xx-psc-spi", |
| 424 | mps); | 429 | mps); |
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index 5c33cdb9cac7..a2b0aa48b8ea 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig | |||
| @@ -87,12 +87,13 @@ config USB_DYNAMIC_MINORS | |||
| 87 | If you are unsure about this, say N here. | 87 | If you are unsure about this, say N here. |
| 88 | 88 | ||
| 89 | config USB_SUSPEND | 89 | config USB_SUSPEND |
| 90 | bool "USB selective suspend/resume and wakeup (EXPERIMENTAL)" | 90 | bool "USB selective suspend/resume and wakeup" |
| 91 | depends on USB && PM && EXPERIMENTAL | 91 | depends on USB && PM |
| 92 | help | 92 | help |
| 93 | If you say Y here, you can use driver calls or the sysfs | 93 | If you say Y here, you can use driver calls or the sysfs |
| 94 | "power/state" file to suspend or resume individual USB | 94 | "power/level" file to suspend or resume individual USB |
| 95 | peripherals. | 95 | peripherals and to enable or disable autosuspend (see |
| 96 | Documentation/usb/power-management.txt for more details). | ||
| 96 | 97 | ||
| 97 | Also, USB "remote wakeup" signaling is supported, whereby some | 98 | Also, USB "remote wakeup" signaling is supported, whereby some |
| 98 | USB devices (like keyboards and network adapters) can wake up | 99 | USB devices (like keyboards and network adapters) can wake up |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index f90ab5e94c58..d9d1eb19f2a1 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
| @@ -28,35 +28,38 @@ | |||
| 28 | * devices is broken... | 28 | * devices is broken... |
| 29 | */ | 29 | */ |
| 30 | static const struct usb_device_id usb_quirk_list[] = { | 30 | static const struct usb_device_id usb_quirk_list[] = { |
| 31 | /* Action Semiconductor flash disk */ | ||
| 32 | { USB_DEVICE(0x10d6, 0x2200), .driver_info = USB_QUIRK_STRING_FETCH_255}, | ||
| 33 | |||
| 34 | /* CBM - Flash disk */ | 31 | /* CBM - Flash disk */ |
| 35 | { USB_DEVICE(0x0204, 0x6025), .driver_info = USB_QUIRK_RESET_RESUME }, | 32 | { USB_DEVICE(0x0204, 0x6025), .driver_info = USB_QUIRK_RESET_RESUME }, |
| 33 | |||
| 36 | /* HP 5300/5370C scanner */ | 34 | /* HP 5300/5370C scanner */ |
| 37 | { USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 }, | 35 | { USB_DEVICE(0x03f0, 0x0701), .driver_info = |
| 36 | USB_QUIRK_STRING_FETCH_255 }, | ||
| 38 | 37 | ||
| 39 | /* Creative SB Audigy 2 NX */ | 38 | /* Creative SB Audigy 2 NX */ |
| 40 | { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME }, | 39 | { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME }, |
| 41 | 40 | ||
| 41 | /* Philips PSC805 audio device */ | ||
| 42 | { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 43 | |||
| 42 | /* Roland SC-8820 */ | 44 | /* Roland SC-8820 */ |
| 43 | { USB_DEVICE(0x0582, 0x0007), .driver_info = USB_QUIRK_RESET_RESUME }, | 45 | { USB_DEVICE(0x0582, 0x0007), .driver_info = USB_QUIRK_RESET_RESUME }, |
| 44 | 46 | ||
| 45 | /* Edirol SD-20 */ | 47 | /* Edirol SD-20 */ |
| 46 | { USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME }, | 48 | { USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME }, |
| 47 | 49 | ||
| 48 | /* INTEL VALUE SSD */ | ||
| 49 | { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 50 | |||
| 51 | /* M-Systems Flash Disk Pioneers */ | 50 | /* M-Systems Flash Disk Pioneers */ |
| 52 | { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, | 51 | { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, |
| 53 | 52 | ||
| 54 | /* Philips PSC805 audio device */ | 53 | /* Action Semiconductor flash disk */ |
| 55 | { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME }, | 54 | { USB_DEVICE(0x10d6, 0x2200), .driver_info = |
| 55 | USB_QUIRK_STRING_FETCH_255 }, | ||
| 56 | 56 | ||
| 57 | /* SKYMEDI USB_DRIVE */ | 57 | /* SKYMEDI USB_DRIVE */ |
| 58 | { USB_DEVICE(0x1516, 0x8628), .driver_info = USB_QUIRK_RESET_RESUME }, | 58 | { USB_DEVICE(0x1516, 0x8628), .driver_info = USB_QUIRK_RESET_RESUME }, |
| 59 | 59 | ||
| 60 | /* INTEL VALUE SSD */ | ||
| 61 | { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
| 62 | |||
| 60 | { } /* terminating entry must be last */ | 63 | { } /* terminating entry must be last */ |
| 61 | }; | 64 | }; |
| 62 | 65 | ||
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 4f6bfa100f2a..2c32bd08ee7d 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c | |||
| @@ -92,7 +92,6 @@ struct printer_dev { | |||
| 92 | u8 *current_rx_buf; | 92 | u8 *current_rx_buf; |
| 93 | u8 printer_status; | 93 | u8 printer_status; |
| 94 | u8 reset_printer; | 94 | u8 reset_printer; |
| 95 | struct class_device *printer_class_dev; | ||
| 96 | struct cdev printer_cdev; | 95 | struct cdev printer_cdev; |
| 97 | struct device *pdev; | 96 | struct device *pdev; |
| 98 | u8 printer_cdev_open; | 97 | u8 printer_cdev_open; |
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 4402d6f042d9..096c41cc40d1 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c | |||
| @@ -103,6 +103,12 @@ static const char ep0name [] = "ep0"; | |||
| 103 | #error "Can't configure both IXP and PXA" | 103 | #error "Can't configure both IXP and PXA" |
| 104 | #endif | 104 | #endif |
| 105 | 105 | ||
| 106 | /* IXP doesn't yet support <linux/clk.h> */ | ||
| 107 | #define clk_get(dev,name) NULL | ||
| 108 | #define clk_enable(clk) do { } while (0) | ||
| 109 | #define clk_disable(clk) do { } while (0) | ||
| 110 | #define clk_put(clk) do { } while (0) | ||
| 111 | |||
| 106 | #endif | 112 | #endif |
| 107 | 113 | ||
| 108 | #include "pxa2xx_udc.h" | 114 | #include "pxa2xx_udc.h" |
| @@ -934,20 +940,31 @@ static void udc_disable(struct pxa2xx_udc *); | |||
| 934 | /* We disable the UDC -- and its 48 MHz clock -- whenever it's not | 940 | /* We disable the UDC -- and its 48 MHz clock -- whenever it's not |
| 935 | * in active use. | 941 | * in active use. |
| 936 | */ | 942 | */ |
| 937 | static int pullup(struct pxa2xx_udc *udc, int is_active) | 943 | static int pullup(struct pxa2xx_udc *udc) |
| 938 | { | 944 | { |
| 939 | is_active = is_active && udc->vbus && udc->pullup; | 945 | int is_active = udc->vbus && udc->pullup && !udc->suspended; |
| 940 | DMSG("%s\n", is_active ? "active" : "inactive"); | 946 | DMSG("%s\n", is_active ? "active" : "inactive"); |
| 941 | if (is_active) | 947 | if (is_active) { |
| 942 | udc_enable(udc); | 948 | if (!udc->active) { |
| 943 | else { | 949 | udc->active = 1; |
| 944 | if (udc->gadget.speed != USB_SPEED_UNKNOWN) { | 950 | /* Enable clock for USB device */ |
| 945 | DMSG("disconnect %s\n", udc->driver | 951 | clk_enable(udc->clk); |
| 946 | ? udc->driver->driver.name | 952 | udc_enable(udc); |
| 947 | : "(no driver)"); | ||
| 948 | stop_activity(udc, udc->driver); | ||
| 949 | } | 953 | } |
| 950 | udc_disable(udc); | 954 | } else { |
| 955 | if (udc->active) { | ||
| 956 | if (udc->gadget.speed != USB_SPEED_UNKNOWN) { | ||
| 957 | DMSG("disconnect %s\n", udc->driver | ||
| 958 | ? udc->driver->driver.name | ||
| 959 | : "(no driver)"); | ||
| 960 | stop_activity(udc, udc->driver); | ||
| 961 | } | ||
| 962 | udc_disable(udc); | ||
| 963 | /* Disable clock for USB device */ | ||
| 964 | clk_disable(udc->clk); | ||
| 965 | udc->active = 0; | ||
| 966 | } | ||
| 967 | |||
| 951 | } | 968 | } |
| 952 | return 0; | 969 | return 0; |
| 953 | } | 970 | } |
| @@ -958,9 +975,9 @@ static int pxa2xx_udc_vbus_session(struct usb_gadget *_gadget, int is_active) | |||
| 958 | struct pxa2xx_udc *udc; | 975 | struct pxa2xx_udc *udc; |
| 959 | 976 | ||
| 960 | udc = container_of(_gadget, struct pxa2xx_udc, gadget); | 977 | udc = container_of(_gadget, struct pxa2xx_udc, gadget); |
| 961 | udc->vbus = is_active = (is_active != 0); | 978 | udc->vbus = (is_active != 0); |
| 962 | DMSG("vbus %s\n", is_active ? "supplied" : "inactive"); | 979 | DMSG("vbus %s\n", is_active ? "supplied" : "inactive"); |
| 963 | pullup(udc, is_active); | 980 | pullup(udc); |
| 964 | return 0; | 981 | return 0; |
| 965 | } | 982 | } |
| 966 | 983 | ||
| @@ -975,9 +992,8 @@ static int pxa2xx_udc_pullup(struct usb_gadget *_gadget, int is_active) | |||
| 975 | if (!udc->mach->gpio_pullup && !udc->mach->udc_command) | 992 | if (!udc->mach->gpio_pullup && !udc->mach->udc_command) |
| 976 | return -EOPNOTSUPP; | 993 | return -EOPNOTSUPP; |
| 977 | 994 | ||
| 978 | is_active = (is_active != 0); | 995 | udc->pullup = (is_active != 0); |
| 979 | udc->pullup = is_active; | 996 | pullup(udc); |
| 980 | pullup(udc, is_active); | ||
| 981 | return 0; | 997 | return 0; |
| 982 | } | 998 | } |
| 983 | 999 | ||
| @@ -997,7 +1013,7 @@ static const struct usb_gadget_ops pxa2xx_udc_ops = { | |||
| 997 | #ifdef CONFIG_USB_GADGET_DEBUG_FS | 1013 | #ifdef CONFIG_USB_GADGET_DEBUG_FS |
| 998 | 1014 | ||
| 999 | static int | 1015 | static int |
| 1000 | udc_seq_show(struct seq_file *m, void *d) | 1016 | udc_seq_show(struct seq_file *m, void *_d) |
| 1001 | { | 1017 | { |
| 1002 | struct pxa2xx_udc *dev = m->private; | 1018 | struct pxa2xx_udc *dev = m->private; |
| 1003 | unsigned long flags; | 1019 | unsigned long flags; |
| @@ -1146,11 +1162,6 @@ static void udc_disable(struct pxa2xx_udc *dev) | |||
| 1146 | 1162 | ||
| 1147 | udc_clear_mask_UDCCR(UDCCR_UDE); | 1163 | udc_clear_mask_UDCCR(UDCCR_UDE); |
| 1148 | 1164 | ||
| 1149 | #ifdef CONFIG_ARCH_PXA | ||
| 1150 | /* Disable clock for USB device */ | ||
| 1151 | clk_disable(dev->clk); | ||
| 1152 | #endif | ||
| 1153 | |||
| 1154 | ep0_idle (dev); | 1165 | ep0_idle (dev); |
| 1155 | dev->gadget.speed = USB_SPEED_UNKNOWN; | 1166 | dev->gadget.speed = USB_SPEED_UNKNOWN; |
| 1156 | } | 1167 | } |
| @@ -1191,11 +1202,6 @@ static void udc_enable (struct pxa2xx_udc *dev) | |||
| 1191 | { | 1202 | { |
| 1192 | udc_clear_mask_UDCCR(UDCCR_UDE); | 1203 | udc_clear_mask_UDCCR(UDCCR_UDE); |
| 1193 | 1204 | ||
| 1194 | #ifdef CONFIG_ARCH_PXA | ||
| 1195 | /* Enable clock for USB device */ | ||
| 1196 | clk_enable(dev->clk); | ||
| 1197 | #endif | ||
| 1198 | |||
| 1199 | /* try to clear these bits before we enable the udc */ | 1205 | /* try to clear these bits before we enable the udc */ |
| 1200 | udc_ack_int_UDCCR(UDCCR_SUSIR|/*UDCCR_RSTIR|*/UDCCR_RESIR); | 1206 | udc_ack_int_UDCCR(UDCCR_SUSIR|/*UDCCR_RSTIR|*/UDCCR_RESIR); |
| 1201 | 1207 | ||
| @@ -1286,7 +1292,7 @@ fail: | |||
| 1286 | * for set_configuration as well as eventual disconnect. | 1292 | * for set_configuration as well as eventual disconnect. |
| 1287 | */ | 1293 | */ |
| 1288 | DMSG("registered gadget driver '%s'\n", driver->driver.name); | 1294 | DMSG("registered gadget driver '%s'\n", driver->driver.name); |
| 1289 | pullup(dev, 1); | 1295 | pullup(dev); |
| 1290 | dump_state(dev); | 1296 | dump_state(dev); |
| 1291 | return 0; | 1297 | return 0; |
| 1292 | } | 1298 | } |
| @@ -1329,7 +1335,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
| 1329 | return -EINVAL; | 1335 | return -EINVAL; |
| 1330 | 1336 | ||
| 1331 | local_irq_disable(); | 1337 | local_irq_disable(); |
| 1332 | pullup(dev, 0); | 1338 | dev->pullup = 0; |
| 1339 | pullup(dev); | ||
| 1333 | stop_activity(dev, driver); | 1340 | stop_activity(dev, driver); |
| 1334 | local_irq_enable(); | 1341 | local_irq_enable(); |
| 1335 | 1342 | ||
| @@ -2131,13 +2138,11 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev) | |||
| 2131 | if (irq < 0) | 2138 | if (irq < 0) |
| 2132 | return -ENODEV; | 2139 | return -ENODEV; |
| 2133 | 2140 | ||
| 2134 | #ifdef CONFIG_ARCH_PXA | ||
| 2135 | dev->clk = clk_get(&pdev->dev, "UDCCLK"); | 2141 | dev->clk = clk_get(&pdev->dev, "UDCCLK"); |
| 2136 | if (IS_ERR(dev->clk)) { | 2142 | if (IS_ERR(dev->clk)) { |
| 2137 | retval = PTR_ERR(dev->clk); | 2143 | retval = PTR_ERR(dev->clk); |
| 2138 | goto err_clk; | 2144 | goto err_clk; |
| 2139 | } | 2145 | } |
| 2140 | #endif | ||
| 2141 | 2146 | ||
| 2142 | pr_debug("%s: IRQ %d%s%s\n", driver_name, irq, | 2147 | pr_debug("%s: IRQ %d%s%s\n", driver_name, irq, |
| 2143 | dev->has_cfr ? "" : " (!cfr)", | 2148 | dev->has_cfr ? "" : " (!cfr)", |
| @@ -2250,10 +2255,8 @@ lubbock_fail0: | |||
| 2250 | if (dev->mach->gpio_vbus) | 2255 | if (dev->mach->gpio_vbus) |
| 2251 | gpio_free(dev->mach->gpio_vbus); | 2256 | gpio_free(dev->mach->gpio_vbus); |
| 2252 | err_gpio_vbus: | 2257 | err_gpio_vbus: |
| 2253 | #ifdef CONFIG_ARCH_PXA | ||
| 2254 | clk_put(dev->clk); | 2258 | clk_put(dev->clk); |
| 2255 | err_clk: | 2259 | err_clk: |
| 2256 | #endif | ||
| 2257 | return retval; | 2260 | return retval; |
| 2258 | } | 2261 | } |
| 2259 | 2262 | ||
| @@ -2269,7 +2272,9 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev) | |||
| 2269 | if (dev->driver) | 2272 | if (dev->driver) |
| 2270 | return -EBUSY; | 2273 | return -EBUSY; |
| 2271 | 2274 | ||
| 2272 | udc_disable(dev); | 2275 | dev->pullup = 0; |
| 2276 | pullup(dev); | ||
| 2277 | |||
| 2273 | remove_debug_files(dev); | 2278 | remove_debug_files(dev); |
| 2274 | 2279 | ||
| 2275 | if (dev->got_irq) { | 2280 | if (dev->got_irq) { |
| @@ -2289,9 +2294,7 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev) | |||
| 2289 | if (dev->mach->gpio_pullup) | 2294 | if (dev->mach->gpio_pullup) |
| 2290 | gpio_free(dev->mach->gpio_pullup); | 2295 | gpio_free(dev->mach->gpio_pullup); |
| 2291 | 2296 | ||
| 2292 | #ifdef CONFIG_ARCH_PXA | ||
| 2293 | clk_put(dev->clk); | 2297 | clk_put(dev->clk); |
| 2294 | #endif | ||
| 2295 | 2298 | ||
| 2296 | platform_set_drvdata(pdev, NULL); | 2299 | platform_set_drvdata(pdev, NULL); |
| 2297 | the_controller = NULL; | 2300 | the_controller = NULL; |
| @@ -2317,10 +2320,15 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev) | |||
| 2317 | static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state) | 2320 | static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state) |
| 2318 | { | 2321 | { |
| 2319 | struct pxa2xx_udc *udc = platform_get_drvdata(dev); | 2322 | struct pxa2xx_udc *udc = platform_get_drvdata(dev); |
| 2323 | unsigned long flags; | ||
| 2320 | 2324 | ||
| 2321 | if (!udc->mach->gpio_pullup && !udc->mach->udc_command) | 2325 | if (!udc->mach->gpio_pullup && !udc->mach->udc_command) |
| 2322 | WARN("USB host won't detect disconnect!\n"); | 2326 | WARN("USB host won't detect disconnect!\n"); |
| 2323 | pullup(udc, 0); | 2327 | udc->suspended = 1; |
| 2328 | |||
| 2329 | local_irq_save(flags); | ||
| 2330 | pullup(udc); | ||
| 2331 | local_irq_restore(flags); | ||
| 2324 | 2332 | ||
| 2325 | return 0; | 2333 | return 0; |
| 2326 | } | 2334 | } |
| @@ -2328,8 +2336,12 @@ static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state) | |||
| 2328 | static int pxa2xx_udc_resume(struct platform_device *dev) | 2336 | static int pxa2xx_udc_resume(struct platform_device *dev) |
| 2329 | { | 2337 | { |
| 2330 | struct pxa2xx_udc *udc = platform_get_drvdata(dev); | 2338 | struct pxa2xx_udc *udc = platform_get_drvdata(dev); |
| 2339 | unsigned long flags; | ||
| 2331 | 2340 | ||
| 2332 | pullup(udc, 1); | 2341 | udc->suspended = 0; |
| 2342 | local_irq_save(flags); | ||
| 2343 | pullup(udc); | ||
| 2344 | local_irq_restore(flags); | ||
| 2333 | 2345 | ||
| 2334 | return 0; | 2346 | return 0; |
| 2335 | } | 2347 | } |
diff --git a/drivers/usb/gadget/pxa2xx_udc.h b/drivers/usb/gadget/pxa2xx_udc.h index b67e3ff5e4eb..e2c19e88c875 100644 --- a/drivers/usb/gadget/pxa2xx_udc.h +++ b/drivers/usb/gadget/pxa2xx_udc.h | |||
| @@ -119,7 +119,9 @@ struct pxa2xx_udc { | |||
| 119 | has_cfr : 1, | 119 | has_cfr : 1, |
| 120 | req_pending : 1, | 120 | req_pending : 1, |
| 121 | req_std : 1, | 121 | req_std : 1, |
| 122 | req_config : 1; | 122 | req_config : 1, |
| 123 | suspended : 1, | ||
| 124 | active : 1; | ||
| 123 | 125 | ||
| 124 | #define start_watchdog(dev) mod_timer(&dev->timer, jiffies + (HZ/200)) | 126 | #define start_watchdog(dev) mod_timer(&dev->timer, jiffies + (HZ/200)) |
| 125 | struct timer_list timer; | 127 | struct timer_list timer; |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 776a97f33914..2e49de820b14 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
| @@ -319,10 +319,10 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
| 319 | if (likely (last->urb != urb)) { | 319 | if (likely (last->urb != urb)) { |
| 320 | ehci_urb_done(ehci, last->urb, last_status); | 320 | ehci_urb_done(ehci, last->urb, last_status); |
| 321 | count++; | 321 | count++; |
| 322 | last_status = -EINPROGRESS; | ||
| 322 | } | 323 | } |
| 323 | ehci_qtd_free (ehci, last); | 324 | ehci_qtd_free (ehci, last); |
| 324 | last = NULL; | 325 | last = NULL; |
| 325 | last_status = -EINPROGRESS; | ||
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | /* ignore urbs submitted during completions we reported */ | 328 | /* ignore urbs submitted during completions we reported */ |
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 0130fd8571e4..d7071c855758 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c | |||
| @@ -911,8 +911,7 @@ static int isp116x_hub_status_data(struct usb_hcd *hcd, char *buf) | |||
| 911 | buf[0] = 0; | 911 | buf[0] = 0; |
| 912 | 912 | ||
| 913 | for (i = 0; i < ports; i++) { | 913 | for (i = 0; i < ports; i++) { |
| 914 | u32 status = isp116x->rhport[i] = | 914 | u32 status = isp116x_read_reg32(isp116x, i ? HCRHPORT2 : HCRHPORT1); |
| 915 | isp116x_read_reg32(isp116x, i ? HCRHPORT2 : HCRHPORT1); | ||
| 916 | 915 | ||
| 917 | if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC | 916 | if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC |
| 918 | | RH_PS_OCIC | RH_PS_PRSC)) { | 917 | | RH_PS_OCIC | RH_PS_PRSC)) { |
| @@ -1031,7 +1030,9 @@ static int isp116x_hub_control(struct usb_hcd *hcd, | |||
| 1031 | DBG("GetPortStatus\n"); | 1030 | DBG("GetPortStatus\n"); |
| 1032 | if (!wIndex || wIndex > ports) | 1031 | if (!wIndex || wIndex > ports) |
| 1033 | goto error; | 1032 | goto error; |
| 1034 | tmp = isp116x->rhport[--wIndex]; | 1033 | spin_lock_irqsave(&isp116x->lock, flags); |
| 1034 | tmp = isp116x_read_reg32(isp116x, (--wIndex) ? HCRHPORT2 : HCRHPORT1); | ||
| 1035 | spin_unlock_irqrestore(&isp116x->lock, flags); | ||
| 1035 | *(__le32 *) buf = cpu_to_le32(tmp); | 1036 | *(__le32 *) buf = cpu_to_le32(tmp); |
| 1036 | DBG("GetPortStatus: port[%d] %08x\n", wIndex + 1, tmp); | 1037 | DBG("GetPortStatus: port[%d] %08x\n", wIndex + 1, tmp); |
| 1037 | break; | 1038 | break; |
| @@ -1080,8 +1081,6 @@ static int isp116x_hub_control(struct usb_hcd *hcd, | |||
| 1080 | spin_lock_irqsave(&isp116x->lock, flags); | 1081 | spin_lock_irqsave(&isp116x->lock, flags); |
| 1081 | isp116x_write_reg32(isp116x, wIndex | 1082 | isp116x_write_reg32(isp116x, wIndex |
| 1082 | ? HCRHPORT2 : HCRHPORT1, tmp); | 1083 | ? HCRHPORT2 : HCRHPORT1, tmp); |
| 1083 | isp116x->rhport[wIndex] = | ||
| 1084 | isp116x_read_reg32(isp116x, wIndex ? HCRHPORT2 : HCRHPORT1); | ||
| 1085 | spin_unlock_irqrestore(&isp116x->lock, flags); | 1084 | spin_unlock_irqrestore(&isp116x->lock, flags); |
| 1086 | break; | 1085 | break; |
| 1087 | case SetPortFeature: | 1086 | case SetPortFeature: |
| @@ -1095,24 +1094,22 @@ static int isp116x_hub_control(struct usb_hcd *hcd, | |||
| 1095 | spin_lock_irqsave(&isp116x->lock, flags); | 1094 | spin_lock_irqsave(&isp116x->lock, flags); |
| 1096 | isp116x_write_reg32(isp116x, wIndex | 1095 | isp116x_write_reg32(isp116x, wIndex |
| 1097 | ? HCRHPORT2 : HCRHPORT1, RH_PS_PSS); | 1096 | ? HCRHPORT2 : HCRHPORT1, RH_PS_PSS); |
| 1097 | spin_unlock_irqrestore(&isp116x->lock, flags); | ||
| 1098 | break; | 1098 | break; |
| 1099 | case USB_PORT_FEAT_POWER: | 1099 | case USB_PORT_FEAT_POWER: |
| 1100 | DBG("USB_PORT_FEAT_POWER\n"); | 1100 | DBG("USB_PORT_FEAT_POWER\n"); |
| 1101 | spin_lock_irqsave(&isp116x->lock, flags); | 1101 | spin_lock_irqsave(&isp116x->lock, flags); |
| 1102 | isp116x_write_reg32(isp116x, wIndex | 1102 | isp116x_write_reg32(isp116x, wIndex |
| 1103 | ? HCRHPORT2 : HCRHPORT1, RH_PS_PPS); | 1103 | ? HCRHPORT2 : HCRHPORT1, RH_PS_PPS); |
| 1104 | spin_unlock_irqrestore(&isp116x->lock, flags); | ||
| 1104 | break; | 1105 | break; |
| 1105 | case USB_PORT_FEAT_RESET: | 1106 | case USB_PORT_FEAT_RESET: |
| 1106 | DBG("USB_PORT_FEAT_RESET\n"); | 1107 | DBG("USB_PORT_FEAT_RESET\n"); |
| 1107 | root_port_reset(isp116x, wIndex); | 1108 | root_port_reset(isp116x, wIndex); |
| 1108 | spin_lock_irqsave(&isp116x->lock, flags); | ||
| 1109 | break; | 1109 | break; |
| 1110 | default: | 1110 | default: |
| 1111 | goto error; | 1111 | goto error; |
| 1112 | } | 1112 | } |
| 1113 | isp116x->rhport[wIndex] = | ||
| 1114 | isp116x_read_reg32(isp116x, wIndex ? HCRHPORT2 : HCRHPORT1); | ||
| 1115 | spin_unlock_irqrestore(&isp116x->lock, flags); | ||
| 1116 | break; | 1113 | break; |
| 1117 | 1114 | ||
| 1118 | default: | 1115 | default: |
diff --git a/drivers/usb/host/isp116x.h b/drivers/usb/host/isp116x.h index b91e2edd9c5c..595b90a99848 100644 --- a/drivers/usb/host/isp116x.h +++ b/drivers/usb/host/isp116x.h | |||
| @@ -270,7 +270,6 @@ struct isp116x { | |||
| 270 | u32 rhdesca; | 270 | u32 rhdesca; |
| 271 | u32 rhdescb; | 271 | u32 rhdescb; |
| 272 | u32 rhstatus; | 272 | u32 rhstatus; |
| 273 | u32 rhport[2]; | ||
| 274 | 273 | ||
| 275 | /* async schedule: control, bulk */ | 274 | /* async schedule: control, bulk */ |
| 276 | struct list_head async; | 275 | struct list_head async; |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 76db2fef4657..91dc433dbcf1 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
| @@ -92,6 +92,7 @@ struct ftdi_sio_quirk { | |||
| 92 | }; | 92 | }; |
| 93 | 93 | ||
| 94 | static int ftdi_jtag_probe (struct usb_serial *serial); | 94 | static int ftdi_jtag_probe (struct usb_serial *serial); |
| 95 | static int ftdi_mtxorb_hack_setup (struct usb_serial *serial); | ||
| 95 | static void ftdi_USB_UIRT_setup (struct ftdi_private *priv); | 96 | static void ftdi_USB_UIRT_setup (struct ftdi_private *priv); |
| 96 | static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv); | 97 | static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv); |
| 97 | 98 | ||
| @@ -99,6 +100,10 @@ static struct ftdi_sio_quirk ftdi_jtag_quirk = { | |||
| 99 | .probe = ftdi_jtag_probe, | 100 | .probe = ftdi_jtag_probe, |
| 100 | }; | 101 | }; |
| 101 | 102 | ||
| 103 | static struct ftdi_sio_quirk ftdi_mtxorb_hack_quirk = { | ||
| 104 | .probe = ftdi_mtxorb_hack_setup, | ||
| 105 | }; | ||
| 106 | |||
| 102 | static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { | 107 | static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { |
| 103 | .port_probe = ftdi_USB_UIRT_setup, | 108 | .port_probe = ftdi_USB_UIRT_setup, |
| 104 | }; | 109 | }; |
| @@ -161,6 +166,8 @@ static struct usb_device_id id_table_combined [] = { | |||
| 161 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) }, | 166 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) }, |
| 162 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) }, | 167 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) }, |
| 163 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, | 168 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, |
| 169 | { USB_DEVICE(MTXORB_VK_VID, MTXORB_VK_PID), | ||
| 170 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, | ||
| 164 | { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) }, | 171 | { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) }, |
| 165 | { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) }, | 172 | { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) }, |
| 166 | { USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) }, | 173 | { USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) }, |
| @@ -274,6 +281,7 @@ static struct usb_device_id id_table_combined [] = { | |||
| 274 | { USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) }, | 281 | { USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) }, |
| 275 | { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) }, | 282 | { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) }, |
| 276 | { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) }, | 283 | { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) }, |
| 284 | { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1010PC_PID) }, | ||
| 277 | { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) }, | 285 | { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) }, |
| 278 | { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) }, | 286 | { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) }, |
| 279 | { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) }, | 287 | { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) }, |
| @@ -1088,6 +1096,23 @@ static int ftdi_jtag_probe(struct usb_serial *serial) | |||
| 1088 | return 0; | 1096 | return 0; |
| 1089 | } | 1097 | } |
| 1090 | 1098 | ||
| 1099 | /* | ||
| 1100 | * The Matrix Orbital VK204-25-USB has an invalid IN endpoint. | ||
| 1101 | * We have to correct it if we want to read from it. | ||
| 1102 | */ | ||
| 1103 | static int ftdi_mtxorb_hack_setup(struct usb_serial *serial) | ||
| 1104 | { | ||
| 1105 | struct usb_host_endpoint *ep = serial->dev->ep_in[1]; | ||
| 1106 | struct usb_endpoint_descriptor *ep_desc = &ep->desc; | ||
| 1107 | |||
| 1108 | if (ep->enabled && ep_desc->wMaxPacketSize == 0) { | ||
| 1109 | ep_desc->wMaxPacketSize = 0x40; | ||
| 1110 | info("Fixing invalid wMaxPacketSize on read pipe"); | ||
| 1111 | } | ||
| 1112 | |||
| 1113 | return 0; | ||
| 1114 | } | ||
| 1115 | |||
| 1091 | /* ftdi_shutdown is called from usbserial:usb_serial_disconnect | 1116 | /* ftdi_shutdown is called from usbserial:usb_serial_disconnect |
| 1092 | * it is called when the usb device is disconnected | 1117 | * it is called when the usb device is disconnected |
| 1093 | * | 1118 | * |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 6eee2ab914ec..e1eb742abcd5 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
| @@ -102,6 +102,13 @@ | |||
| 102 | * (http://www.joernonline.de/dw/doku.php?id=start&idx=projects:oocdlink) */ | 102 | * (http://www.joernonline.de/dw/doku.php?id=start&idx=projects:oocdlink) */ |
| 103 | #define FTDI_OOCDLINK_PID 0xbaf8 /* Amontec JTAGkey */ | 103 | #define FTDI_OOCDLINK_PID 0xbaf8 /* Amontec JTAGkey */ |
| 104 | 104 | ||
| 105 | /* | ||
| 106 | * The following are the values for the Matrix Orbital VK204-25-USB | ||
| 107 | * display, which use the FT232RL. | ||
| 108 | */ | ||
| 109 | #define MTXORB_VK_VID 0x1b3d | ||
| 110 | #define MTXORB_VK_PID 0x0158 | ||
| 111 | |||
| 105 | /* Interbiometrics USB I/O Board */ | 112 | /* Interbiometrics USB I/O Board */ |
| 106 | /* Developed for Interbiometrics by Rudolf Gugler */ | 113 | /* Developed for Interbiometrics by Rudolf Gugler */ |
| 107 | #define INTERBIOMETRICS_VID 0x1209 | 114 | #define INTERBIOMETRICS_VID 0x1209 |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 869ecd374cb4..aeeb9cb20999 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
| @@ -110,11 +110,20 @@ | |||
| 110 | 110 | ||
| 111 | /* vendor id and device id defines */ | 111 | /* vendor id and device id defines */ |
| 112 | 112 | ||
| 113 | /* The native mos7840/7820 component */ | ||
| 113 | #define USB_VENDOR_ID_MOSCHIP 0x9710 | 114 | #define USB_VENDOR_ID_MOSCHIP 0x9710 |
| 114 | #define MOSCHIP_DEVICE_ID_7840 0x7840 | 115 | #define MOSCHIP_DEVICE_ID_7840 0x7840 |
| 115 | #define MOSCHIP_DEVICE_ID_7820 0x7820 | 116 | #define MOSCHIP_DEVICE_ID_7820 0x7820 |
| 117 | /* The native component can have its vendor/device id's overridden | ||
| 118 | * in vendor-specific implementations. Such devices can be handled | ||
| 119 | * by making a change here, in moschip_port_id_table, and in | ||
| 120 | * moschip_id_table_combined | ||
| 121 | */ | ||
| 122 | #define USB_VENDOR_ID_BANDB 0x0856 | ||
| 123 | #define BANDB_DEVICE_ID_USOPTL4_4 0xAC44 | ||
| 124 | #define BANDB_DEVICE_ID_USOPTL4_2 0xAC42 | ||
| 116 | 125 | ||
| 117 | /* Interrupt Rotinue Defines */ | 126 | /* Interrupt Routine Defines */ |
| 118 | 127 | ||
| 119 | #define SERIAL_IIR_RLS 0x06 | 128 | #define SERIAL_IIR_RLS 0x06 |
| 120 | #define SERIAL_IIR_MS 0x00 | 129 | #define SERIAL_IIR_MS 0x00 |
| @@ -159,12 +168,16 @@ | |||
| 159 | static struct usb_device_id moschip_port_id_table[] = { | 168 | static struct usb_device_id moschip_port_id_table[] = { |
| 160 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, | 169 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, |
| 161 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, | 170 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, |
| 171 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, | ||
| 172 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, | ||
| 162 | {} /* terminating entry */ | 173 | {} /* terminating entry */ |
| 163 | }; | 174 | }; |
| 164 | 175 | ||
| 165 | static __devinitdata struct usb_device_id moschip_id_table_combined[] = { | 176 | static __devinitdata struct usb_device_id moschip_id_table_combined[] = { |
| 166 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, | 177 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, |
| 167 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, | 178 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, |
| 179 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, | ||
| 180 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, | ||
| 168 | {} /* terminating entry */ | 181 | {} /* terminating entry */ |
| 169 | }; | 182 | }; |
| 170 | 183 | ||
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index af2674c57414..828a4377ec6a 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
| @@ -120,6 +120,9 @@ static int option_send_setup(struct usb_serial_port *port); | |||
| 120 | #define ANYDATA_PRODUCT_ADU_E100A 0x6501 | 120 | #define ANYDATA_PRODUCT_ADU_E100A 0x6501 |
| 121 | #define ANYDATA_PRODUCT_ADU_500A 0x6502 | 121 | #define ANYDATA_PRODUCT_ADU_500A 0x6502 |
| 122 | 122 | ||
| 123 | #define AXESSTEL_VENDOR_ID 0x1726 | ||
| 124 | #define AXESSTEL_PRODUCT_MV110H 0x1000 | ||
| 125 | |||
| 123 | #define BANDRICH_VENDOR_ID 0x1A8D | 126 | #define BANDRICH_VENDOR_ID 0x1A8D |
| 124 | #define BANDRICH_PRODUCT_C100_1 0x1002 | 127 | #define BANDRICH_PRODUCT_C100_1 0x1002 |
| 125 | #define BANDRICH_PRODUCT_C100_2 0x1003 | 128 | #define BANDRICH_PRODUCT_C100_2 0x1003 |
| @@ -192,6 +195,7 @@ static struct usb_device_id option_ids[] = { | |||
| 192 | { USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */ | 195 | { USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */ |
| 193 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, | 196 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, |
| 194 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, | 197 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, |
| 198 | { USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) }, | ||
| 195 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, | 199 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, |
| 196 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, | 200 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, |
| 197 | { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, | 201 | { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, |
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c index 958f5b17847c..b9b8ede61fb3 100644 --- a/drivers/usb/storage/protocol.c +++ b/drivers/usb/storage/protocol.c | |||
| @@ -170,7 +170,6 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer, | |||
| 170 | 170 | ||
| 171 | if (!sg) | 171 | if (!sg) |
| 172 | sg = scsi_sglist(srb); | 172 | sg = scsi_sglist(srb); |
| 173 | buflen = min(buflen, scsi_bufflen(srb)); | ||
| 174 | 173 | ||
| 175 | /* This loop handles a single s-g list entry, which may | 174 | /* This loop handles a single s-g list entry, which may |
| 176 | * include multiple pages. Find the initial page structure | 175 | * include multiple pages. Find the initial page structure |
| @@ -232,6 +231,7 @@ void usb_stor_set_xfer_buf(unsigned char *buffer, | |||
| 232 | unsigned int offset = 0; | 231 | unsigned int offset = 0; |
| 233 | struct scatterlist *sg = NULL; | 232 | struct scatterlist *sg = NULL; |
| 234 | 233 | ||
| 234 | buflen = min(buflen, scsi_bufflen(srb)); | ||
| 235 | buflen = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset, | 235 | buflen = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset, |
| 236 | TO_XFER_BUF); | 236 | TO_XFER_BUF); |
| 237 | if (buflen < scsi_bufflen(srb)) | 237 | if (buflen < scsi_bufflen(srb)) |
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c index e83dfba7e636..742b5c656d66 100644 --- a/drivers/video/sm501fb.c +++ b/drivers/video/sm501fb.c | |||
| @@ -237,12 +237,14 @@ static int sm501fb_check_var(struct fb_var_screeninfo *var, | |||
| 237 | 237 | ||
| 238 | /* check we can fit these values into the registers */ | 238 | /* check we can fit these values into the registers */ |
| 239 | 239 | ||
| 240 | if (var->hsync_len > 255 || var->vsync_len > 255) | 240 | if (var->hsync_len > 255 || var->vsync_len > 63) |
| 241 | return -EINVAL; | 241 | return -EINVAL; |
| 242 | 242 | ||
| 243 | if ((var->xres + var->right_margin) >= 4096) | 243 | /* hdisplay end and hsync start */ |
| 244 | if ((var->xres + var->right_margin) > 4096) | ||
| 244 | return -EINVAL; | 245 | return -EINVAL; |
| 245 | 246 | ||
| 247 | /* vdisplay end and vsync start */ | ||
| 246 | if ((var->yres + var->lower_margin) > 2048) | 248 | if ((var->yres + var->lower_margin) > 2048) |
| 247 | return -EINVAL; | 249 | return -EINVAL; |
| 248 | 250 | ||
| @@ -281,19 +283,21 @@ static int sm501fb_check_var(struct fb_var_screeninfo *var, | |||
| 281 | var->blue.length = var->bits_per_pixel; | 283 | var->blue.length = var->bits_per_pixel; |
| 282 | var->blue.offset = 0; | 284 | var->blue.offset = 0; |
| 283 | var->transp.length = 0; | 285 | var->transp.length = 0; |
| 286 | var->transp.offset = 0; | ||
| 284 | 287 | ||
| 285 | break; | 288 | break; |
| 286 | 289 | ||
| 287 | case 16: | 290 | case 16: |
| 288 | if (sm->pdata->flags & SM501_FBPD_SWAP_FB_ENDIAN) { | 291 | if (sm->pdata->flags & SM501_FBPD_SWAP_FB_ENDIAN) { |
| 289 | var->red.offset = 11; | ||
| 290 | var->green.offset = 5; | ||
| 291 | var->blue.offset = 0; | ||
| 292 | } else { | ||
| 293 | var->blue.offset = 11; | 292 | var->blue.offset = 11; |
| 294 | var->green.offset = 5; | 293 | var->green.offset = 5; |
| 295 | var->red.offset = 0; | 294 | var->red.offset = 0; |
| 295 | } else { | ||
| 296 | var->red.offset = 11; | ||
| 297 | var->green.offset = 5; | ||
| 298 | var->blue.offset = 0; | ||
| 296 | } | 299 | } |
| 300 | var->transp.offset = 0; | ||
| 297 | 301 | ||
| 298 | var->red.length = 5; | 302 | var->red.length = 5; |
| 299 | var->green.length = 6; | 303 | var->green.length = 6; |
| @@ -397,7 +401,7 @@ static int sm501fb_set_par_common(struct fb_info *info, | |||
| 397 | break; | 401 | break; |
| 398 | 402 | ||
| 399 | case 16: | 403 | case 16: |
| 400 | info->fix.visual = FB_VISUAL_DIRECTCOLOR; | 404 | info->fix.visual = FB_VISUAL_TRUECOLOR; |
| 401 | break; | 405 | break; |
| 402 | 406 | ||
| 403 | case 32: | 407 | case 32: |
| @@ -613,6 +617,7 @@ static int sm501fb_set_par_crt(struct fb_info *info) | |||
| 613 | 617 | ||
| 614 | case 16: | 618 | case 16: |
| 615 | control |= SM501_DC_CRT_CONTROL_16BPP; | 619 | control |= SM501_DC_CRT_CONTROL_16BPP; |
| 620 | sm501fb_setup_gamma(fbi, SM501_DC_CRT_PALETTE); | ||
| 616 | break; | 621 | break; |
| 617 | 622 | ||
| 618 | case 32: | 623 | case 32: |
| @@ -750,6 +755,7 @@ static int sm501fb_set_par_pnl(struct fb_info *info) | |||
| 750 | 755 | ||
| 751 | case 16: | 756 | case 16: |
| 752 | control |= SM501_DC_PANEL_CONTROL_16BPP; | 757 | control |= SM501_DC_PANEL_CONTROL_16BPP; |
| 758 | sm501fb_setup_gamma(fbi, SM501_DC_PANEL_PALETTE); | ||
| 753 | break; | 759 | break; |
| 754 | 760 | ||
| 755 | case 32: | 761 | case 32: |
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c index 70fb4ee2b421..919ce75db9e2 100644 --- a/drivers/video/tridentfb.c +++ b/drivers/video/tridentfb.c | |||
| @@ -564,19 +564,46 @@ static inline void write3CE(int reg, unsigned char val) | |||
| 564 | t_outb(val, 0x3CF); | 564 | t_outb(val, 0x3CF); |
| 565 | } | 565 | } |
| 566 | 566 | ||
| 567 | static inline void enable_mmio(void) | 567 | static void enable_mmio(void) |
| 568 | { | 568 | { |
| 569 | unsigned char tmp; | ||
| 570 | |||
| 569 | /* Goto New Mode */ | 571 | /* Goto New Mode */ |
| 570 | outb(0x0B, 0x3C4); | 572 | outb(0x0B, 0x3C4); |
| 571 | inb(0x3C5); | 573 | inb(0x3C5); |
| 572 | 574 | ||
| 573 | /* Unprotect registers */ | 575 | /* Unprotect registers */ |
| 574 | outb(NewMode1, 0x3C4); | 576 | outb(NewMode1, 0x3C4); |
| 577 | tmp = inb(0x3C5); | ||
| 575 | outb(0x80, 0x3C5); | 578 | outb(0x80, 0x3C5); |
| 576 | 579 | ||
| 577 | /* Enable MMIO */ | 580 | /* Enable MMIO */ |
| 578 | outb(PCIReg, 0x3D4); | 581 | outb(PCIReg, 0x3D4); |
| 579 | outb(inb(0x3D5) | 0x01, 0x3D5); | 582 | outb(inb(0x3D5) | 0x01, 0x3D5); |
| 583 | |||
| 584 | t_outb(NewMode1, 0x3C4); | ||
| 585 | t_outb(tmp, 0x3C5); | ||
| 586 | } | ||
| 587 | |||
| 588 | static void disable_mmio(void) | ||
| 589 | { | ||
| 590 | unsigned char tmp; | ||
| 591 | |||
| 592 | /* Goto New Mode */ | ||
| 593 | t_outb(0x0B, 0x3C4); | ||
| 594 | t_inb(0x3C5); | ||
| 595 | |||
| 596 | /* Unprotect registers */ | ||
| 597 | t_outb(NewMode1, 0x3C4); | ||
| 598 | tmp = t_inb(0x3C5); | ||
| 599 | t_outb(0x80, 0x3C5); | ||
| 600 | |||
| 601 | /* Disable MMIO */ | ||
| 602 | t_outb(PCIReg, 0x3D4); | ||
| 603 | t_outb(t_inb(0x3D5) & ~0x01, 0x3D5); | ||
| 604 | |||
| 605 | outb(NewMode1, 0x3C4); | ||
| 606 | outb(tmp, 0x3C5); | ||
| 580 | } | 607 | } |
| 581 | 608 | ||
| 582 | #define crtc_unlock() write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) & 0x7F) | 609 | #define crtc_unlock() write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) & 0x7F) |
| @@ -1239,9 +1266,9 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, | |||
| 1239 | default_par.io_virt = ioremap_nocache(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); | 1266 | default_par.io_virt = ioremap_nocache(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); |
| 1240 | 1267 | ||
| 1241 | if (!default_par.io_virt) { | 1268 | if (!default_par.io_virt) { |
| 1242 | release_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); | ||
| 1243 | debug("ioremap failed\n"); | 1269 | debug("ioremap failed\n"); |
| 1244 | return -1; | 1270 | err = -1; |
| 1271 | goto out_unmap1; | ||
| 1245 | } | 1272 | } |
| 1246 | 1273 | ||
| 1247 | enable_mmio(); | 1274 | enable_mmio(); |
| @@ -1252,25 +1279,21 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, | |||
| 1252 | 1279 | ||
| 1253 | if (!request_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len, "tridentfb")) { | 1280 | if (!request_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len, "tridentfb")) { |
| 1254 | debug("request_mem_region failed!\n"); | 1281 | debug("request_mem_region failed!\n"); |
| 1282 | disable_mmio(); | ||
| 1255 | err = -1; | 1283 | err = -1; |
| 1256 | goto out_unmap; | 1284 | goto out_unmap1; |
| 1257 | } | 1285 | } |
| 1258 | 1286 | ||
| 1259 | fb_info.screen_base = ioremap_nocache(tridentfb_fix.smem_start, | 1287 | fb_info.screen_base = ioremap_nocache(tridentfb_fix.smem_start, |
| 1260 | tridentfb_fix.smem_len); | 1288 | tridentfb_fix.smem_len); |
| 1261 | 1289 | ||
| 1262 | if (!fb_info.screen_base) { | 1290 | if (!fb_info.screen_base) { |
| 1263 | release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); | ||
| 1264 | debug("ioremap failed\n"); | 1291 | debug("ioremap failed\n"); |
| 1265 | err = -1; | 1292 | err = -1; |
| 1266 | goto out_unmap; | 1293 | goto out_unmap2; |
| 1267 | } | 1294 | } |
| 1268 | 1295 | ||
| 1269 | output("%s board found\n", pci_name(dev)); | 1296 | output("%s board found\n", pci_name(dev)); |
| 1270 | #if 0 | ||
| 1271 | output("Trident board found : mem = %X, io = %X, mem_v = %X, io_v = %X\n", | ||
| 1272 | tridentfb_fix.smem_start, tridentfb_fix.mmio_start, fb_info.screen_base, default_par.io_virt); | ||
| 1273 | #endif | ||
| 1274 | displaytype = get_displaytype(); | 1297 | displaytype = get_displaytype(); |
| 1275 | 1298 | ||
| 1276 | if (flatpanel) | 1299 | if (flatpanel) |
| @@ -1288,9 +1311,12 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, | |||
| 1288 | 1311 | ||
| 1289 | if (!fb_find_mode(&default_var, &fb_info, mode, NULL, 0, NULL, bpp)) { | 1312 | if (!fb_find_mode(&default_var, &fb_info, mode, NULL, 0, NULL, bpp)) { |
| 1290 | err = -EINVAL; | 1313 | err = -EINVAL; |
| 1291 | goto out_unmap; | 1314 | goto out_unmap2; |
| 1292 | } | 1315 | } |
| 1293 | fb_alloc_cmap(&fb_info.cmap, 256, 0); | 1316 | err = fb_alloc_cmap(&fb_info.cmap, 256, 0); |
| 1317 | if (err < 0) | ||
| 1318 | goto out_unmap2; | ||
| 1319 | |||
| 1294 | if (defaultaccel && acc) | 1320 | if (defaultaccel && acc) |
| 1295 | default_var.accel_flags |= FB_ACCELF_TEXT; | 1321 | default_var.accel_flags |= FB_ACCELF_TEXT; |
| 1296 | else | 1322 | else |
| @@ -1300,19 +1326,24 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, | |||
| 1300 | fb_info.device = &dev->dev; | 1326 | fb_info.device = &dev->dev; |
| 1301 | if (register_framebuffer(&fb_info) < 0) { | 1327 | if (register_framebuffer(&fb_info) < 0) { |
| 1302 | printk(KERN_ERR "tridentfb: could not register Trident framebuffer\n"); | 1328 | printk(KERN_ERR "tridentfb: could not register Trident framebuffer\n"); |
| 1329 | fb_dealloc_cmap(&fb_info.cmap); | ||
| 1303 | err = -EINVAL; | 1330 | err = -EINVAL; |
| 1304 | goto out_unmap; | 1331 | goto out_unmap2; |
| 1305 | } | 1332 | } |
| 1306 | output("fb%d: %s frame buffer device %dx%d-%dbpp\n", | 1333 | output("fb%d: %s frame buffer device %dx%d-%dbpp\n", |
| 1307 | fb_info.node, fb_info.fix.id, default_var.xres, | 1334 | fb_info.node, fb_info.fix.id, default_var.xres, |
| 1308 | default_var.yres, default_var.bits_per_pixel); | 1335 | default_var.yres, default_var.bits_per_pixel); |
| 1309 | return 0; | 1336 | return 0; |
| 1310 | 1337 | ||
| 1311 | out_unmap: | 1338 | out_unmap2: |
| 1312 | if (default_par.io_virt) | ||
| 1313 | iounmap(default_par.io_virt); | ||
| 1314 | if (fb_info.screen_base) | 1339 | if (fb_info.screen_base) |
| 1315 | iounmap(fb_info.screen_base); | 1340 | iounmap(fb_info.screen_base); |
| 1341 | release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); | ||
| 1342 | disable_mmio(); | ||
| 1343 | out_unmap1: | ||
| 1344 | if (default_par.io_virt) | ||
| 1345 | iounmap(default_par.io_virt); | ||
| 1346 | release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); | ||
| 1316 | return err; | 1347 | return err; |
| 1317 | } | 1348 | } |
| 1318 | 1349 | ||
| @@ -1323,7 +1354,7 @@ static void __devexit trident_pci_remove(struct pci_dev *dev) | |||
| 1323 | iounmap(par->io_virt); | 1354 | iounmap(par->io_virt); |
| 1324 | iounmap(fb_info.screen_base); | 1355 | iounmap(fb_info.screen_base); |
| 1325 | release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); | 1356 | release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); |
| 1326 | release_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); | 1357 | release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); |
| 1327 | } | 1358 | } |
| 1328 | 1359 | ||
| 1329 | /* List of boards that we are trying to support */ | 1360 | /* List of boards that we are trying to support */ |
diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c index 688e435b4d9a..10211e493001 100644 --- a/drivers/w1/masters/ds1wm.c +++ b/drivers/w1/masters/ds1wm.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include <linux/pm.h> | 17 | #include <linux/pm.h> |
| 18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
| 19 | #include <linux/clk.h> | 19 | #include <linux/clk.h> |
| 20 | #include <linux/err.h> | ||
| 20 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
| 21 | #include <linux/ds1wm.h> | 22 | #include <linux/ds1wm.h> |
| 22 | 23 | ||
| @@ -102,12 +103,12 @@ struct ds1wm_data { | |||
| 102 | static inline void ds1wm_write_register(struct ds1wm_data *ds1wm_data, u32 reg, | 103 | static inline void ds1wm_write_register(struct ds1wm_data *ds1wm_data, u32 reg, |
| 103 | u8 val) | 104 | u8 val) |
| 104 | { | 105 | { |
| 105 | __raw_writeb(val, ds1wm_data->map + (reg << ds1wm_data->bus_shift)); | 106 | __raw_writeb(val, ds1wm_data->map + (reg << ds1wm_data->bus_shift)); |
| 106 | } | 107 | } |
| 107 | 108 | ||
| 108 | static inline u8 ds1wm_read_register(struct ds1wm_data *ds1wm_data, u32 reg) | 109 | static inline u8 ds1wm_read_register(struct ds1wm_data *ds1wm_data, u32 reg) |
| 109 | { | 110 | { |
| 110 | return __raw_readb(ds1wm_data->map + (reg << ds1wm_data->bus_shift)); | 111 | return __raw_readb(ds1wm_data->map + (reg << ds1wm_data->bus_shift)); |
| 111 | } | 112 | } |
| 112 | 113 | ||
| 113 | 114 | ||
| @@ -149,8 +150,8 @@ static int ds1wm_reset(struct ds1wm_data *ds1wm_data) | |||
| 149 | timeleft = wait_for_completion_timeout(&reset_done, DS1WM_TIMEOUT); | 150 | timeleft = wait_for_completion_timeout(&reset_done, DS1WM_TIMEOUT); |
| 150 | ds1wm_data->reset_complete = NULL; | 151 | ds1wm_data->reset_complete = NULL; |
| 151 | if (!timeleft) { | 152 | if (!timeleft) { |
| 152 | dev_dbg(&ds1wm_data->pdev->dev, "reset failed\n"); | 153 | dev_err(&ds1wm_data->pdev->dev, "reset failed\n"); |
| 153 | return 1; | 154 | return 1; |
| 154 | } | 155 | } |
| 155 | 156 | ||
| 156 | /* Wait for the end of the reset. According to the specs, the time | 157 | /* Wait for the end of the reset. According to the specs, the time |
| @@ -167,11 +168,11 @@ static int ds1wm_reset(struct ds1wm_data *ds1wm_data) | |||
| 167 | (ds1wm_data->active_high ? DS1WM_INTEN_IAS : 0)); | 168 | (ds1wm_data->active_high ? DS1WM_INTEN_IAS : 0)); |
| 168 | 169 | ||
| 169 | if (!ds1wm_data->slave_present) { | 170 | if (!ds1wm_data->slave_present) { |
| 170 | dev_dbg(&ds1wm_data->pdev->dev, "reset: no devices found\n"); | 171 | dev_dbg(&ds1wm_data->pdev->dev, "reset: no devices found\n"); |
| 171 | return 1; | 172 | return 1; |
| 172 | } | 173 | } |
| 173 | 174 | ||
| 174 | return 0; | 175 | return 0; |
| 175 | } | 176 | } |
| 176 | 177 | ||
| 177 | static int ds1wm_write(struct ds1wm_data *ds1wm_data, u8 data) | 178 | static int ds1wm_write(struct ds1wm_data *ds1wm_data, u8 data) |
| @@ -334,7 +335,7 @@ static int ds1wm_probe(struct platform_device *pdev) | |||
| 334 | if (!pdev) | 335 | if (!pdev) |
| 335 | return -ENODEV; | 336 | return -ENODEV; |
| 336 | 337 | ||
| 337 | ds1wm_data = kzalloc(sizeof (*ds1wm_data), GFP_KERNEL); | 338 | ds1wm_data = kzalloc(sizeof(*ds1wm_data), GFP_KERNEL); |
| 338 | if (!ds1wm_data) | 339 | if (!ds1wm_data) |
| 339 | return -ENOMEM; | 340 | return -ENOMEM; |
| 340 | 341 | ||
| @@ -374,8 +375,8 @@ static int ds1wm_probe(struct platform_device *pdev) | |||
| 374 | goto err1; | 375 | goto err1; |
| 375 | 376 | ||
| 376 | ds1wm_data->clk = clk_get(&pdev->dev, "ds1wm"); | 377 | ds1wm_data->clk = clk_get(&pdev->dev, "ds1wm"); |
| 377 | if (!ds1wm_data->clk) { | 378 | if (IS_ERR(ds1wm_data->clk)) { |
| 378 | ret = -ENOENT; | 379 | ret = PTR_ERR(ds1wm_data->clk); |
| 379 | goto err2; | 380 | goto err2; |
| 380 | } | 381 | } |
| 381 | 382 | ||
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 41a958a7585e..5e1a4fb5cacb 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
| @@ -1424,6 +1424,18 @@ struct elf_note_info { | |||
| 1424 | int thread_notes; | 1424 | int thread_notes; |
| 1425 | }; | 1425 | }; |
| 1426 | 1426 | ||
| 1427 | /* | ||
| 1428 | * When a regset has a writeback hook, we call it on each thread before | ||
| 1429 | * dumping user memory. On register window machines, this makes sure the | ||
| 1430 | * user memory backing the register data is up to date before we read it. | ||
| 1431 | */ | ||
| 1432 | static void do_thread_regset_writeback(struct task_struct *task, | ||
| 1433 | const struct user_regset *regset) | ||
| 1434 | { | ||
| 1435 | if (regset->writeback) | ||
| 1436 | regset->writeback(task, regset, 1); | ||
| 1437 | } | ||
| 1438 | |||
| 1427 | static int fill_thread_core_info(struct elf_thread_core_info *t, | 1439 | static int fill_thread_core_info(struct elf_thread_core_info *t, |
| 1428 | const struct user_regset_view *view, | 1440 | const struct user_regset_view *view, |
| 1429 | long signr, size_t *total) | 1441 | long signr, size_t *total) |
| @@ -1445,6 +1457,8 @@ static int fill_thread_core_info(struct elf_thread_core_info *t, | |||
| 1445 | sizeof(t->prstatus), &t->prstatus); | 1457 | sizeof(t->prstatus), &t->prstatus); |
| 1446 | *total += notesize(&t->notes[0]); | 1458 | *total += notesize(&t->notes[0]); |
| 1447 | 1459 | ||
| 1460 | do_thread_regset_writeback(t->task, &view->regsets[0]); | ||
| 1461 | |||
| 1448 | /* | 1462 | /* |
| 1449 | * Each other regset might generate a note too. For each regset | 1463 | * Each other regset might generate a note too. For each regset |
| 1450 | * that has no core_note_type or is inactive, we leave t->notes[i] | 1464 | * that has no core_note_type or is inactive, we leave t->notes[i] |
| @@ -1452,6 +1466,7 @@ static int fill_thread_core_info(struct elf_thread_core_info *t, | |||
| 1452 | */ | 1466 | */ |
| 1453 | for (i = 1; i < view->n; ++i) { | 1467 | for (i = 1; i < view->n; ++i) { |
| 1454 | const struct user_regset *regset = &view->regsets[i]; | 1468 | const struct user_regset *regset = &view->regsets[i]; |
| 1469 | do_thread_regset_writeback(t->task, regset); | ||
| 1455 | if (regset->core_note_type && | 1470 | if (regset->core_note_type && |
| 1456 | (!regset->active || regset->active(t->task, regset))) { | 1471 | (!regset->active || regset->active(t->task, regset))) { |
| 1457 | int ret; | 1472 | int ret; |
diff --git a/fs/buffer.c b/fs/buffer.c index 897cd7477b34..ddfdd2c80bf9 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
| @@ -835,7 +835,7 @@ static int fsync_buffers_list(spinlock_t *lock, struct list_head *list) | |||
| 835 | smp_mb(); | 835 | smp_mb(); |
| 836 | if (buffer_dirty(bh)) { | 836 | if (buffer_dirty(bh)) { |
| 837 | list_add(&bh->b_assoc_buffers, | 837 | list_add(&bh->b_assoc_buffers, |
| 838 | &bh->b_assoc_map->private_list); | 838 | &mapping->private_list); |
| 839 | bh->b_assoc_map = mapping; | 839 | bh->b_assoc_map = mapping; |
| 840 | } | 840 | } |
| 841 | spin_unlock(lock); | 841 | spin_unlock(lock); |
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index dc74b186145d..6df1debdccce 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
| @@ -263,52 +263,102 @@ out: | |||
| 263 | return 0; | 263 | return 0; |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | /* This function must zero any hole we create */ | 266 | /** |
| 267 | * ecryptfs_prepare_write | ||
| 268 | * @file: The eCryptfs file | ||
| 269 | * @page: The eCryptfs page | ||
| 270 | * @from: The start byte from which we will write | ||
| 271 | * @to: The end byte to which we will write | ||
| 272 | * | ||
| 273 | * This function must zero any hole we create | ||
| 274 | * | ||
| 275 | * Returns zero on success; non-zero otherwise | ||
| 276 | */ | ||
| 267 | static int ecryptfs_prepare_write(struct file *file, struct page *page, | 277 | static int ecryptfs_prepare_write(struct file *file, struct page *page, |
| 268 | unsigned from, unsigned to) | 278 | unsigned from, unsigned to) |
| 269 | { | 279 | { |
| 270 | int rc = 0; | ||
| 271 | loff_t prev_page_end_size; | 280 | loff_t prev_page_end_size; |
| 281 | int rc = 0; | ||
| 272 | 282 | ||
| 273 | if (!PageUptodate(page)) { | 283 | if (!PageUptodate(page)) { |
| 274 | rc = ecryptfs_read_lower_page_segment(page, page->index, 0, | 284 | struct ecryptfs_crypt_stat *crypt_stat = |
| 275 | PAGE_CACHE_SIZE, | 285 | &ecryptfs_inode_to_private( |
| 276 | page->mapping->host); | 286 | file->f_path.dentry->d_inode)->crypt_stat; |
| 277 | if (rc) { | 287 | |
| 278 | printk(KERN_ERR "%s: Error attemping to read lower " | 288 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED) |
| 279 | "page segment; rc = [%d]\n", __FUNCTION__, rc); | 289 | || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) { |
| 280 | ClearPageUptodate(page); | 290 | rc = ecryptfs_read_lower_page_segment( |
| 281 | goto out; | 291 | page, page->index, 0, PAGE_CACHE_SIZE, |
| 282 | } else | 292 | page->mapping->host); |
| 293 | if (rc) { | ||
| 294 | printk(KERN_ERR "%s: Error attemping to read " | ||
| 295 | "lower page segment; rc = [%d]\n", | ||
| 296 | __FUNCTION__, rc); | ||
| 297 | ClearPageUptodate(page); | ||
| 298 | goto out; | ||
| 299 | } else | ||
| 300 | SetPageUptodate(page); | ||
| 301 | } else if (crypt_stat->flags & ECRYPTFS_VIEW_AS_ENCRYPTED) { | ||
| 302 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) { | ||
| 303 | rc = ecryptfs_copy_up_encrypted_with_header( | ||
| 304 | page, crypt_stat); | ||
| 305 | if (rc) { | ||
| 306 | printk(KERN_ERR "%s: Error attempting " | ||
| 307 | "to copy the encrypted content " | ||
| 308 | "from the lower file whilst " | ||
| 309 | "inserting the metadata from " | ||
| 310 | "the xattr into the header; rc " | ||
| 311 | "= [%d]\n", __FUNCTION__, rc); | ||
| 312 | ClearPageUptodate(page); | ||
| 313 | goto out; | ||
| 314 | } | ||
| 315 | SetPageUptodate(page); | ||
| 316 | } else { | ||
| 317 | rc = ecryptfs_read_lower_page_segment( | ||
| 318 | page, page->index, 0, PAGE_CACHE_SIZE, | ||
| 319 | page->mapping->host); | ||
| 320 | if (rc) { | ||
| 321 | printk(KERN_ERR "%s: Error reading " | ||
| 322 | "page; rc = [%d]\n", | ||
| 323 | __FUNCTION__, rc); | ||
| 324 | ClearPageUptodate(page); | ||
| 325 | goto out; | ||
| 326 | } | ||
| 327 | SetPageUptodate(page); | ||
| 328 | } | ||
| 329 | } else { | ||
| 330 | rc = ecryptfs_decrypt_page(page); | ||
| 331 | if (rc) { | ||
| 332 | printk(KERN_ERR "%s: Error decrypting page " | ||
| 333 | "at index [%ld]; rc = [%d]\n", | ||
| 334 | __FUNCTION__, page->index, rc); | ||
| 335 | ClearPageUptodate(page); | ||
| 336 | goto out; | ||
| 337 | } | ||
| 283 | SetPageUptodate(page); | 338 | SetPageUptodate(page); |
| 339 | } | ||
| 284 | } | 340 | } |
| 285 | |||
| 286 | prev_page_end_size = ((loff_t)page->index << PAGE_CACHE_SHIFT); | 341 | prev_page_end_size = ((loff_t)page->index << PAGE_CACHE_SHIFT); |
| 287 | 342 | /* If creating a page or more of holes, zero them out via truncate. | |
| 288 | /* | 343 | * Note, this will increase i_size. */ |
| 289 | * If creating a page or more of holes, zero them out via truncate. | ||
| 290 | * Note, this will increase i_size. | ||
| 291 | */ | ||
| 292 | if (page->index != 0) { | 344 | if (page->index != 0) { |
| 293 | if (prev_page_end_size > i_size_read(page->mapping->host)) { | 345 | if (prev_page_end_size > i_size_read(page->mapping->host)) { |
| 294 | rc = ecryptfs_truncate(file->f_path.dentry, | 346 | rc = ecryptfs_truncate(file->f_path.dentry, |
| 295 | prev_page_end_size); | 347 | prev_page_end_size); |
| 296 | if (rc) { | 348 | if (rc) { |
| 297 | printk(KERN_ERR "Error on attempt to " | 349 | printk(KERN_ERR "%s: Error on attempt to " |
| 298 | "truncate to (higher) offset [%lld];" | 350 | "truncate to (higher) offset [%lld];" |
| 299 | " rc = [%d]\n", prev_page_end_size, rc); | 351 | " rc = [%d]\n", __FUNCTION__, |
| 352 | prev_page_end_size, rc); | ||
| 300 | goto out; | 353 | goto out; |
| 301 | } | 354 | } |
| 302 | } | 355 | } |
| 303 | } | 356 | } |
| 304 | /* | 357 | /* Writing to a new page, and creating a small hole from start |
| 305 | * Writing to a new page, and creating a small hole from start of page? | 358 | * of page? Zero it out. */ |
| 306 | * Zero it out. | 359 | if ((i_size_read(page->mapping->host) == prev_page_end_size) |
| 307 | */ | 360 | && (from != 0)) |
| 308 | if ((i_size_read(page->mapping->host) == prev_page_end_size) && | ||
| 309 | (from != 0)) { | ||
| 310 | zero_user(page, 0, PAGE_CACHE_SIZE); | 361 | zero_user(page, 0, PAGE_CACHE_SIZE); |
| 311 | } | ||
| 312 | out: | 362 | out: |
| 313 | return rc; | 363 | return rc; |
| 314 | } | 364 | } |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 18769cc32377..ad5360664082 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
| @@ -806,8 +806,8 @@ static match_table_t tokens = { | |||
| 806 | {Opt_quota, "quota"}, | 806 | {Opt_quota, "quota"}, |
| 807 | {Opt_usrquota, "usrquota"}, | 807 | {Opt_usrquota, "usrquota"}, |
| 808 | {Opt_barrier, "barrier=%u"}, | 808 | {Opt_barrier, "barrier=%u"}, |
| 809 | {Opt_err, NULL}, | ||
| 810 | {Opt_resize, "resize"}, | 809 | {Opt_resize, "resize"}, |
| 810 | {Opt_err, NULL}, | ||
| 811 | }; | 811 | }; |
| 812 | 812 | ||
| 813 | static ext3_fsblk_t get_sb_block(void **data) | 813 | static ext3_fsblk_t get_sb_block(void **data) |
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 6841452e0dea..393cc22c1717 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
| @@ -2031,7 +2031,7 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, | |||
| 2031 | return -EXDEV; | 2031 | return -EXDEV; |
| 2032 | } | 2032 | } |
| 2033 | /* We must not pack tails for quota files on reiserfs for quota IO to work */ | 2033 | /* We must not pack tails for quota files on reiserfs for quota IO to work */ |
| 2034 | if (!REISERFS_I(nd.path.dentry->d_inode)->i_flags & i_nopack_mask) { | 2034 | if (!(REISERFS_I(nd.path.dentry->d_inode)->i_flags & i_nopack_mask)) { |
| 2035 | reiserfs_warning(sb, | 2035 | reiserfs_warning(sb, |
| 2036 | "reiserfs: Quota file must have tail packing disabled."); | 2036 | "reiserfs: Quota file must have tail packing disabled."); |
| 2037 | path_put(&nd.path); | 2037 | path_put(&nd.path); |
diff --git a/include/asm-arm/kprobes.h b/include/asm-arm/kprobes.h index 4e7bd32288ae..c042194d3ab5 100644 --- a/include/asm-arm/kprobes.h +++ b/include/asm-arm/kprobes.h | |||
| @@ -20,7 +20,6 @@ | |||
| 20 | #include <linux/ptrace.h> | 20 | #include <linux/ptrace.h> |
| 21 | #include <linux/percpu.h> | 21 | #include <linux/percpu.h> |
| 22 | 22 | ||
| 23 | #define ARCH_SUPPORTS_KRETPROBES | ||
| 24 | #define __ARCH_WANT_KPROBES_INSN_SLOT | 23 | #define __ARCH_WANT_KPROBES_INSN_SLOT |
| 25 | #define MAX_INSN_SIZE 2 | 24 | #define MAX_INSN_SIZE 2 |
| 26 | #define MAX_STACK_SIZE 64 /* 32 would probably be OK */ | 25 | #define MAX_STACK_SIZE 64 /* 32 would probably be OK */ |
diff --git a/include/asm-cris/uaccess.h b/include/asm-cris/uaccess.h index 69d48a2dc8e1..ea11eaf0e922 100644 --- a/include/asm-cris/uaccess.h +++ b/include/asm-cris/uaccess.h | |||
| @@ -1,43 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Authors: Bjorn Wesen (bjornw@axis.com) | 2 | * Authors: Bjorn Wesen (bjornw@axis.com) |
| 3 | * Hans-Peter Nilsson (hp@axis.com) | 3 | * Hans-Peter Nilsson (hp@axis.com) |
| 4 | * | ||
| 5 | * $Log: uaccess.h,v $ | ||
| 6 | * Revision 1.8 2001/10/29 13:01:48 bjornw | ||
| 7 | * Removed unused variable tmp2 in strnlen_user | ||
| 8 | * | ||
| 9 | * Revision 1.7 2001/10/02 12:44:52 hp | ||
| 10 | * Add support for 64-bit put_user/get_user | ||
| 11 | * | ||
| 12 | * Revision 1.6 2001/10/01 14:51:17 bjornw | ||
| 13 | * Added register prefixes and removed underscores | ||
| 14 | * | ||
| 15 | * Revision 1.5 2000/10/25 03:33:21 hp | ||
| 16 | * - Provide implementation for everything else but get_user and put_user; | ||
| 17 | * copying inline to/from user for constant length 0..16, 20, 24, and | ||
| 18 | * clearing for 0..4, 8, 12, 16, 20, 24, strncpy_from_user and strnlen_user | ||
| 19 | * always inline. | ||
| 20 | * - Constraints for destination addr in get_user cannot be memory, only reg. | ||
| 21 | * - Correct labels for PC at expected fault points. | ||
| 22 | * - Nits with assembly code. | ||
| 23 | * - Don't use statement expressions without value; use "do {} while (0)". | ||
| 24 | * - Return correct values from __generic_... functions. | ||
| 25 | * | ||
| 26 | * Revision 1.4 2000/09/12 16:28:25 bjornw | ||
| 27 | * * Removed comments from the get/put user asm code | ||
| 28 | * * Constrains for destination addr in put_user cannot be memory, only reg | ||
| 29 | * | ||
| 30 | * Revision 1.3 2000/09/12 14:30:20 bjornw | ||
| 31 | * MAX_ADDR_USER does not exist anymore | ||
| 32 | * | ||
| 33 | * Revision 1.2 2000/07/13 15:52:48 bjornw | ||
| 34 | * New user-access functions | ||
| 35 | * | ||
| 36 | * Revision 1.1.1.1 2000/07/10 16:32:31 bjornw | ||
| 37 | * CRIS architecture, working draft | ||
| 38 | * | ||
| 39 | * | ||
| 40 | * | ||
| 41 | */ | 4 | */ |
| 42 | 5 | ||
| 43 | /* Asm:s have been tweaked (within the domain of correctness) to give | 6 | /* Asm:s have been tweaked (within the domain of correctness) to give |
| @@ -209,9 +172,9 @@ extern long __get_user_bad(void); | |||
| 209 | /* More complex functions. Most are inline, but some call functions that | 172 | /* More complex functions. Most are inline, but some call functions that |
| 210 | live in lib/usercopy.c */ | 173 | live in lib/usercopy.c */ |
| 211 | 174 | ||
| 212 | extern unsigned long __copy_user(void *to, const void *from, unsigned long n); | 175 | extern unsigned long __copy_user(void __user *to, const void *from, unsigned long n); |
| 213 | extern unsigned long __copy_user_zeroing(void *to, const void *from, unsigned long n); | 176 | extern unsigned long __copy_user_zeroing(void *to, const void __user *from, unsigned long n); |
| 214 | extern unsigned long __do_clear_user(void *to, unsigned long n); | 177 | extern unsigned long __do_clear_user(void __user *to, unsigned long n); |
| 215 | 178 | ||
| 216 | static inline unsigned long | 179 | static inline unsigned long |
| 217 | __generic_copy_to_user(void __user *to, const void *from, unsigned long n) | 180 | __generic_copy_to_user(void __user *to, const void *from, unsigned long n) |
| @@ -253,7 +216,7 @@ strncpy_from_user(char *dst, const char __user *src, long count) | |||
| 253 | } | 216 | } |
| 254 | 217 | ||
| 255 | 218 | ||
| 256 | /* Note that if these expand awfully if made into switch constructs, so | 219 | /* Note that these expand awfully if made into switch constructs, so |
| 257 | don't do that. */ | 220 | don't do that. */ |
| 258 | 221 | ||
| 259 | static inline unsigned long | 222 | static inline unsigned long |
| @@ -407,19 +370,21 @@ __constant_clear_user(void __user *to, unsigned long n) | |||
| 407 | */ | 370 | */ |
| 408 | 371 | ||
| 409 | static inline unsigned long | 372 | static inline unsigned long |
| 410 | __generic_copy_from_user_nocheck(void *to, const void *from, unsigned long n) | 373 | __generic_copy_from_user_nocheck(void *to, const void __user *from, |
| 374 | unsigned long n) | ||
| 411 | { | 375 | { |
| 412 | return __copy_user_zeroing(to,from,n); | 376 | return __copy_user_zeroing(to,from,n); |
| 413 | } | 377 | } |
| 414 | 378 | ||
| 415 | static inline unsigned long | 379 | static inline unsigned long |
| 416 | __generic_copy_to_user_nocheck(void *to, const void *from, unsigned long n) | 380 | __generic_copy_to_user_nocheck(void __user *to, const void *from, |
| 381 | unsigned long n) | ||
| 417 | { | 382 | { |
| 418 | return __copy_user(to,from,n); | 383 | return __copy_user(to,from,n); |
| 419 | } | 384 | } |
| 420 | 385 | ||
| 421 | static inline unsigned long | 386 | static inline unsigned long |
| 422 | __generic_clear_user_nocheck(void *to, unsigned long n) | 387 | __generic_clear_user_nocheck(void __user *to, unsigned long n) |
| 423 | { | 388 | { |
| 424 | return __do_clear_user(to,n); | 389 | return __do_clear_user(to,n); |
| 425 | } | 390 | } |
diff --git a/include/asm-cris/unistd.h b/include/asm-cris/unistd.h index 007cb16a6b5b..76398ef87e9b 100644 --- a/include/asm-cris/unistd.h +++ b/include/asm-cris/unistd.h | |||
| @@ -329,12 +329,12 @@ | |||
| 329 | #define __NR_timerfd_create 322 | 329 | #define __NR_timerfd_create 322 |
| 330 | #define __NR_eventfd 323 | 330 | #define __NR_eventfd 323 |
| 331 | #define __NR_fallocate 324 | 331 | #define __NR_fallocate 324 |
| 332 | #define __NR_timerfd_settime 315 | 332 | #define __NR_timerfd_settime 325 |
| 333 | #define __NR_timerfd_gettime 316 | 333 | #define __NR_timerfd_gettime 326 |
| 334 | 334 | ||
| 335 | #ifdef __KERNEL__ | 335 | #ifdef __KERNEL__ |
| 336 | 336 | ||
| 337 | #define NR_syscalls 325 | 337 | #define NR_syscalls 327 |
| 338 | 338 | ||
| 339 | #include <asm/arch/unistd.h> | 339 | #include <asm/arch/unistd.h> |
| 340 | 340 | ||
diff --git a/include/asm-ia64/kprobes.h b/include/asm-ia64/kprobes.h index a93ce9ef07ff..adbaba14eb0a 100644 --- a/include/asm-ia64/kprobes.h +++ b/include/asm-ia64/kprobes.h | |||
| @@ -82,7 +82,6 @@ struct kprobe_ctlblk { | |||
| 82 | struct prev_kprobe prev_kprobe[ARCH_PREV_KPROBE_SZ]; | 82 | struct prev_kprobe prev_kprobe[ARCH_PREV_KPROBE_SZ]; |
| 83 | }; | 83 | }; |
| 84 | 84 | ||
| 85 | #define ARCH_SUPPORTS_KRETPROBES | ||
| 86 | #define kretprobe_blacklist_size 0 | 85 | #define kretprobe_blacklist_size 0 |
| 87 | 86 | ||
| 88 | #define SLOT0_OPCODE_SHIFT (37) | 87 | #define SLOT0_OPCODE_SHIFT (37) |
diff --git a/include/asm-powerpc/kprobes.h b/include/asm-powerpc/kprobes.h index afabad230dbb..d0e7701fa1f6 100644 --- a/include/asm-powerpc/kprobes.h +++ b/include/asm-powerpc/kprobes.h | |||
| @@ -80,7 +80,6 @@ typedef unsigned int kprobe_opcode_t; | |||
| 80 | #define is_trap(instr) (IS_TW(instr) || IS_TWI(instr)) | 80 | #define is_trap(instr) (IS_TW(instr) || IS_TWI(instr)) |
| 81 | #endif | 81 | #endif |
| 82 | 82 | ||
| 83 | #define ARCH_SUPPORTS_KRETPROBES | ||
| 84 | #define flush_insn_slot(p) do { } while (0) | 83 | #define flush_insn_slot(p) do { } while (0) |
| 85 | #define kretprobe_blacklist_size 0 | 84 | #define kretprobe_blacklist_size 0 |
| 86 | 85 | ||
diff --git a/include/asm-s390/kprobes.h b/include/asm-s390/kprobes.h index 948db3d0d05c..330f68caffe4 100644 --- a/include/asm-s390/kprobes.h +++ b/include/asm-s390/kprobes.h | |||
| @@ -46,7 +46,6 @@ typedef u16 kprobe_opcode_t; | |||
| 46 | ? (MAX_STACK_SIZE) \ | 46 | ? (MAX_STACK_SIZE) \ |
| 47 | : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) | 47 | : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) |
| 48 | 48 | ||
| 49 | #define ARCH_SUPPORTS_KRETPROBES | ||
| 50 | #define kretprobe_blacklist_size 0 | 49 | #define kretprobe_blacklist_size 0 |
| 51 | 50 | ||
| 52 | #define KPROBE_SWAP_INST 0x10 | 51 | #define KPROBE_SWAP_INST 0x10 |
diff --git a/include/asm-sparc64/kprobes.h b/include/asm-sparc64/kprobes.h index 7237dd87663e..5879d71afdaa 100644 --- a/include/asm-sparc64/kprobes.h +++ b/include/asm-sparc64/kprobes.h | |||
| @@ -14,8 +14,6 @@ typedef u32 kprobe_opcode_t; | |||
| 14 | 14 | ||
| 15 | #define arch_remove_kprobe(p) do {} while (0) | 15 | #define arch_remove_kprobe(p) do {} while (0) |
| 16 | 16 | ||
| 17 | #define ARCH_SUPPORTS_KRETPROBES | ||
| 18 | |||
| 19 | #define flush_insn_slot(p) \ | 17 | #define flush_insn_slot(p) \ |
| 20 | do { flushi(&(p)->ainsn.insn[0]); \ | 18 | do { flushi(&(p)->ainsn.insn[0]); \ |
| 21 | flushi(&(p)->ainsn.insn[1]); \ | 19 | flushi(&(p)->ainsn.insn[1]); \ |
diff --git a/include/asm-x86/kprobes.h b/include/asm-x86/kprobes.h index 143476a3cb52..61ad7b5d142e 100644 --- a/include/asm-x86/kprobes.h +++ b/include/asm-x86/kprobes.h | |||
| @@ -42,7 +42,6 @@ typedef u8 kprobe_opcode_t; | |||
| 42 | : (((unsigned long)current_thread_info()) + THREAD_SIZE \ | 42 | : (((unsigned long)current_thread_info()) + THREAD_SIZE \ |
| 43 | - (unsigned long)(ADDR))) | 43 | - (unsigned long)(ADDR))) |
| 44 | 44 | ||
| 45 | #define ARCH_SUPPORTS_KRETPROBES | ||
| 46 | #define flush_insn_slot(p) do { } while (0) | 45 | #define flush_insn_slot(p) do { } while (0) |
| 47 | 46 | ||
| 48 | extern const int kretprobe_blacklist_size; | 47 | extern const int kretprobe_blacklist_size; |
diff --git a/include/linux/Kbuild b/include/linux/Kbuild index aada32fffec2..994df3780007 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild | |||
| @@ -61,6 +61,7 @@ header-y += efs_fs_sb.h | |||
| 61 | header-y += elf-fdpic.h | 61 | header-y += elf-fdpic.h |
| 62 | header-y += elf-em.h | 62 | header-y += elf-em.h |
| 63 | header-y += fadvise.h | 63 | header-y += fadvise.h |
| 64 | header-y += falloc.h | ||
| 64 | header-y += fd.h | 65 | header-y += fd.h |
| 65 | header-y += fdreg.h | 66 | header-y += fdreg.h |
| 66 | header-y += fib_rules.h | 67 | header-y += fib_rules.h |
diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h index ac6aad98b607..1ddebfc52565 100644 --- a/include/linux/cgroup_subsys.h +++ b/include/linux/cgroup_subsys.h | |||
| @@ -37,7 +37,7 @@ SUBSYS(cpuacct) | |||
| 37 | 37 | ||
| 38 | /* */ | 38 | /* */ |
| 39 | 39 | ||
| 40 | #ifdef CONFIG_CGROUP_MEM_CONT | 40 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR |
| 41 | SUBSYS(mem_cgroup) | 41 | SUBSYS(mem_cgroup) |
| 42 | #endif | 42 | #endif |
| 43 | 43 | ||
diff --git a/include/linux/compiler.h b/include/linux/compiler.h index d0e17e1657dc..dcae0c8d97e6 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h | |||
| @@ -138,6 +138,12 @@ extern void __chk_io_ptr(const volatile void __iomem *); | |||
| 138 | #define noinline | 138 | #define noinline |
| 139 | #endif | 139 | #endif |
| 140 | 140 | ||
| 141 | /* | ||
| 142 | * Rather then using noinline to prevent stack consumption, use | ||
| 143 | * noinline_for_stack instead. For documentaiton reasons. | ||
| 144 | */ | ||
| 145 | #define noinline_for_stack noinline | ||
| 146 | |||
| 141 | #ifndef __always_inline | 147 | #ifndef __always_inline |
| 142 | #define __always_inline inline | 148 | #define __always_inline inline |
| 143 | #endif | 149 | #endif |
diff --git a/include/linux/delay.h b/include/linux/delay.h index 17ddb55430ae..54552d21296e 100644 --- a/include/linux/delay.h +++ b/include/linux/delay.h | |||
| @@ -7,6 +7,8 @@ | |||
| 7 | * Delay routines, using a pre-computed "loops_per_jiffy" value. | 7 | * Delay routines, using a pre-computed "loops_per_jiffy" value. |
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #include <linux/kernel.h> | ||
| 11 | |||
| 10 | extern unsigned long loops_per_jiffy; | 12 | extern unsigned long loops_per_jiffy; |
| 11 | 13 | ||
| 12 | #include <asm/delay.h> | 14 | #include <asm/delay.h> |
| @@ -32,7 +34,11 @@ extern unsigned long loops_per_jiffy; | |||
| 32 | #endif | 34 | #endif |
| 33 | 35 | ||
| 34 | #ifndef ndelay | 36 | #ifndef ndelay |
| 35 | #define ndelay(x) udelay(((x)+999)/1000) | 37 | static inline void ndelay(unsigned long x) |
| 38 | { | ||
| 39 | udelay(DIV_ROUND_UP(x, 1000)); | ||
| 40 | } | ||
| 41 | #define ndelay(x) ndelay(x) | ||
| 36 | #endif | 42 | #endif |
| 37 | 43 | ||
| 38 | void calibrate_delay(void); | 44 | void calibrate_delay(void); |
diff --git a/include/linux/gpio.h b/include/linux/gpio.h new file mode 100644 index 000000000000..4987a84078ef --- /dev/null +++ b/include/linux/gpio.h | |||
| @@ -0,0 +1,95 @@ | |||
| 1 | #ifndef __LINUX_GPIO_H | ||
| 2 | #define __LINUX_GPIO_H | ||
| 3 | |||
| 4 | /* see Documentation/gpio.txt */ | ||
| 5 | |||
| 6 | #ifdef CONFIG_GENERIC_GPIO | ||
| 7 | #include <asm/gpio.h> | ||
| 8 | |||
| 9 | #else | ||
| 10 | |||
| 11 | /* | ||
| 12 | * Some platforms don't support the GPIO programming interface. | ||
| 13 | * | ||
| 14 | * In case some driver uses it anyway (it should normally have | ||
| 15 | * depended on GENERIC_GPIO), these routines help the compiler | ||
| 16 | * optimize out much GPIO-related code ... or trigger a runtime | ||
| 17 | * warning when something is wrongly called. | ||
| 18 | */ | ||
| 19 | |||
| 20 | static inline int gpio_is_valid(int number) | ||
| 21 | { | ||
| 22 | return 0; | ||
| 23 | } | ||
| 24 | |||
| 25 | static inline int gpio_request(unsigned gpio, const char *label) | ||
| 26 | { | ||
| 27 | return -ENOSYS; | ||
| 28 | } | ||
| 29 | |||
| 30 | static inline void gpio_free(unsigned gpio) | ||
| 31 | { | ||
| 32 | /* GPIO can never have been requested */ | ||
| 33 | WARN_ON(1); | ||
| 34 | } | ||
| 35 | |||
| 36 | static inline int gpio_direction_input(unsigned gpio) | ||
| 37 | { | ||
| 38 | return -ENOSYS; | ||
| 39 | } | ||
| 40 | |||
| 41 | static inline int gpio_direction_output(unsigned gpio, int value) | ||
| 42 | { | ||
| 43 | return -ENOSYS; | ||
| 44 | } | ||
| 45 | |||
| 46 | static inline int gpio_get_value(unsigned gpio) | ||
| 47 | { | ||
| 48 | /* GPIO can never have been requested or set as {in,out}put */ | ||
| 49 | WARN_ON(1); | ||
| 50 | return 0; | ||
| 51 | } | ||
| 52 | |||
| 53 | static inline void gpio_set_value(unsigned gpio, int value) | ||
| 54 | { | ||
| 55 | /* GPIO can never have been requested or set as output */ | ||
| 56 | WARN_ON(1); | ||
| 57 | } | ||
| 58 | |||
| 59 | static inline int gpio_cansleep(unsigned gpio) | ||
| 60 | { | ||
| 61 | /* GPIO can never have been requested or set as {in,out}put */ | ||
| 62 | WARN_ON(1); | ||
| 63 | return 0; | ||
| 64 | } | ||
| 65 | |||
| 66 | static inline int gpio_get_value_cansleep(unsigned gpio) | ||
| 67 | { | ||
| 68 | /* GPIO can never have been requested or set as {in,out}put */ | ||
| 69 | WARN_ON(1); | ||
| 70 | return 0; | ||
| 71 | } | ||
| 72 | |||
| 73 | static inline void gpio_set_value_cansleep(unsigned gpio, int value) | ||
| 74 | { | ||
| 75 | /* GPIO can never have been requested or set as output */ | ||
| 76 | WARN_ON(1); | ||
| 77 | } | ||
| 78 | |||
| 79 | static inline int gpio_to_irq(unsigned gpio) | ||
| 80 | { | ||
| 81 | /* GPIO can never have been requested or set as input */ | ||
| 82 | WARN_ON(1); | ||
| 83 | return -EINVAL; | ||
| 84 | } | ||
| 85 | |||
| 86 | static inline int irq_to_gpio(unsigned irq) | ||
| 87 | { | ||
| 88 | /* irq can never have been returned from gpio_to_irq() */ | ||
| 89 | WARN_ON(1); | ||
| 90 | return -EINVAL; | ||
| 91 | } | ||
| 92 | |||
| 93 | #endif | ||
| 94 | |||
| 95 | #endif /* __LINUX_GPIO_H */ | ||
diff --git a/include/linux/iommu-helper.h b/include/linux/iommu-helper.h index 4dd4c04ff2f4..c975caf75385 100644 --- a/include/linux/iommu-helper.h +++ b/include/linux/iommu-helper.h | |||
| @@ -1,3 +1,6 @@ | |||
| 1 | extern int iommu_is_span_boundary(unsigned int index, unsigned int nr, | ||
| 2 | unsigned long shift, | ||
| 3 | unsigned long boundary_size); | ||
| 1 | extern unsigned long iommu_area_alloc(unsigned long *map, unsigned long size, | 4 | extern unsigned long iommu_area_alloc(unsigned long *map, unsigned long size, |
| 2 | unsigned long start, unsigned int nr, | 5 | unsigned long start, unsigned int nr, |
| 3 | unsigned long shift, | 6 | unsigned long shift, |
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h index 4a6ce82ba039..0f28486f6360 100644 --- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h | |||
| @@ -125,11 +125,11 @@ struct jprobe { | |||
| 125 | DECLARE_PER_CPU(struct kprobe *, current_kprobe); | 125 | DECLARE_PER_CPU(struct kprobe *, current_kprobe); |
| 126 | DECLARE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); | 126 | DECLARE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); |
| 127 | 127 | ||
| 128 | #ifdef ARCH_SUPPORTS_KRETPROBES | 128 | #ifdef CONFIG_KRETPROBES |
| 129 | extern void arch_prepare_kretprobe(struct kretprobe_instance *ri, | 129 | extern void arch_prepare_kretprobe(struct kretprobe_instance *ri, |
| 130 | struct pt_regs *regs); | 130 | struct pt_regs *regs); |
| 131 | extern int arch_trampoline_kprobe(struct kprobe *p); | 131 | extern int arch_trampoline_kprobe(struct kprobe *p); |
| 132 | #else /* ARCH_SUPPORTS_KRETPROBES */ | 132 | #else /* CONFIG_KRETPROBES */ |
| 133 | static inline void arch_prepare_kretprobe(struct kretprobe *rp, | 133 | static inline void arch_prepare_kretprobe(struct kretprobe *rp, |
| 134 | struct pt_regs *regs) | 134 | struct pt_regs *regs) |
| 135 | { | 135 | { |
| @@ -138,7 +138,7 @@ static inline int arch_trampoline_kprobe(struct kprobe *p) | |||
| 138 | { | 138 | { |
| 139 | return 0; | 139 | return 0; |
| 140 | } | 140 | } |
| 141 | #endif /* ARCH_SUPPORTS_KRETPROBES */ | 141 | #endif /* CONFIG_KRETPROBES */ |
| 142 | /* | 142 | /* |
| 143 | * Function-return probe - | 143 | * Function-return probe - |
| 144 | * Note: | 144 | * Note: |
diff --git a/include/linux/marker.h b/include/linux/marker.h index 5df879dc3776..430f6adf9762 100644 --- a/include/linux/marker.h +++ b/include/linux/marker.h | |||
| @@ -104,10 +104,16 @@ static inline void marker_update_probe_range(struct marker *begin, | |||
| 104 | #define MARK_NOARGS " " | 104 | #define MARK_NOARGS " " |
| 105 | 105 | ||
| 106 | /* To be used for string format validity checking with gcc */ | 106 | /* To be used for string format validity checking with gcc */ |
| 107 | static inline void __printf(1, 2) __mark_check_format(const char *fmt, ...) | 107 | static inline void __printf(1, 2) ___mark_check_format(const char *fmt, ...) |
| 108 | { | 108 | { |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | #define __mark_check_format(format, args...) \ | ||
| 112 | do { \ | ||
| 113 | if (0) \ | ||
| 114 | ___mark_check_format(format, ## args); \ | ||
| 115 | } while (0) | ||
| 116 | |||
| 111 | extern marker_probe_func __mark_empty_function; | 117 | extern marker_probe_func __mark_empty_function; |
| 112 | 118 | ||
| 113 | extern void marker_probe_cb(const struct marker *mdata, | 119 | extern void marker_probe_cb(const struct marker *mdata, |
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 04075628cb9a..8b1c4295848b 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h | |||
| @@ -25,18 +25,20 @@ struct page_cgroup; | |||
| 25 | struct page; | 25 | struct page; |
| 26 | struct mm_struct; | 26 | struct mm_struct; |
| 27 | 27 | ||
| 28 | #ifdef CONFIG_CGROUP_MEM_CONT | 28 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR |
| 29 | 29 | ||
| 30 | extern void mm_init_cgroup(struct mm_struct *mm, struct task_struct *p); | 30 | extern void mm_init_cgroup(struct mm_struct *mm, struct task_struct *p); |
| 31 | extern void mm_free_cgroup(struct mm_struct *mm); | 31 | extern void mm_free_cgroup(struct mm_struct *mm); |
| 32 | extern void page_assign_page_cgroup(struct page *page, | 32 | |
| 33 | struct page_cgroup *pc); | 33 | #define page_reset_bad_cgroup(page) ((page)->page_cgroup = 0) |
| 34 | |||
| 34 | extern struct page_cgroup *page_get_page_cgroup(struct page *page); | 35 | extern struct page_cgroup *page_get_page_cgroup(struct page *page); |
| 35 | extern int mem_cgroup_charge(struct page *page, struct mm_struct *mm, | 36 | extern int mem_cgroup_charge(struct page *page, struct mm_struct *mm, |
| 36 | gfp_t gfp_mask); | 37 | gfp_t gfp_mask); |
| 37 | extern void mem_cgroup_uncharge(struct page_cgroup *pc); | 38 | extern int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm, |
| 39 | gfp_t gfp_mask); | ||
| 38 | extern void mem_cgroup_uncharge_page(struct page *page); | 40 | extern void mem_cgroup_uncharge_page(struct page *page); |
| 39 | extern void mem_cgroup_move_lists(struct page_cgroup *pc, bool active); | 41 | extern void mem_cgroup_move_lists(struct page *page, bool active); |
| 40 | extern unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan, | 42 | extern unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan, |
| 41 | struct list_head *dst, | 43 | struct list_head *dst, |
| 42 | unsigned long *scanned, int order, | 44 | unsigned long *scanned, int order, |
| @@ -44,11 +46,9 @@ extern unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan, | |||
| 44 | struct mem_cgroup *mem_cont, | 46 | struct mem_cgroup *mem_cont, |
| 45 | int active); | 47 | int active); |
| 46 | extern void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask); | 48 | extern void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask); |
| 47 | extern int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm, | ||
| 48 | gfp_t gfp_mask); | ||
| 49 | int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *mem); | 49 | int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *mem); |
| 50 | 50 | ||
| 51 | #define vm_match_cgroup(mm, cgroup) \ | 51 | #define mm_match_cgroup(mm, cgroup) \ |
| 52 | ((cgroup) == rcu_dereference((mm)->mem_cgroup)) | 52 | ((cgroup) == rcu_dereference((mm)->mem_cgroup)) |
| 53 | 53 | ||
| 54 | extern int mem_cgroup_prepare_migration(struct page *page); | 54 | extern int mem_cgroup_prepare_migration(struct page *page); |
| @@ -72,7 +72,7 @@ extern long mem_cgroup_calc_reclaim_active(struct mem_cgroup *mem, | |||
| 72 | extern long mem_cgroup_calc_reclaim_inactive(struct mem_cgroup *mem, | 72 | extern long mem_cgroup_calc_reclaim_inactive(struct mem_cgroup *mem, |
| 73 | struct zone *zone, int priority); | 73 | struct zone *zone, int priority); |
| 74 | 74 | ||
| 75 | #else /* CONFIG_CGROUP_MEM_CONT */ | 75 | #else /* CONFIG_CGROUP_MEM_RES_CTLR */ |
| 76 | static inline void mm_init_cgroup(struct mm_struct *mm, | 76 | static inline void mm_init_cgroup(struct mm_struct *mm, |
| 77 | struct task_struct *p) | 77 | struct task_struct *p) |
| 78 | { | 78 | { |
| @@ -82,8 +82,7 @@ static inline void mm_free_cgroup(struct mm_struct *mm) | |||
| 82 | { | 82 | { |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | static inline void page_assign_page_cgroup(struct page *page, | 85 | static inline void page_reset_bad_cgroup(struct page *page) |
| 86 | struct page_cgroup *pc) | ||
| 87 | { | 86 | { |
| 88 | } | 87 | } |
| 89 | 88 | ||
| @@ -92,33 +91,27 @@ static inline struct page_cgroup *page_get_page_cgroup(struct page *page) | |||
| 92 | return NULL; | 91 | return NULL; |
| 93 | } | 92 | } |
| 94 | 93 | ||
| 95 | static inline int mem_cgroup_charge(struct page *page, struct mm_struct *mm, | 94 | static inline int mem_cgroup_charge(struct page *page, |
| 96 | gfp_t gfp_mask) | 95 | struct mm_struct *mm, gfp_t gfp_mask) |
| 97 | { | 96 | { |
| 98 | return 0; | 97 | return 0; |
| 99 | } | 98 | } |
| 100 | 99 | ||
| 101 | static inline void mem_cgroup_uncharge(struct page_cgroup *pc) | 100 | static inline int mem_cgroup_cache_charge(struct page *page, |
| 101 | struct mm_struct *mm, gfp_t gfp_mask) | ||
| 102 | { | 102 | { |
| 103 | return 0; | ||
| 103 | } | 104 | } |
| 104 | 105 | ||
| 105 | static inline void mem_cgroup_uncharge_page(struct page *page) | 106 | static inline void mem_cgroup_uncharge_page(struct page *page) |
| 106 | { | 107 | { |
| 107 | } | 108 | } |
| 108 | 109 | ||
| 109 | static inline void mem_cgroup_move_lists(struct page_cgroup *pc, | 110 | static inline void mem_cgroup_move_lists(struct page *page, bool active) |
| 110 | bool active) | ||
| 111 | { | ||
| 112 | } | ||
| 113 | |||
| 114 | static inline int mem_cgroup_cache_charge(struct page *page, | ||
| 115 | struct mm_struct *mm, | ||
| 116 | gfp_t gfp_mask) | ||
| 117 | { | 111 | { |
| 118 | return 0; | ||
| 119 | } | 112 | } |
| 120 | 113 | ||
| 121 | static inline int vm_match_cgroup(struct mm_struct *mm, struct mem_cgroup *mem) | 114 | static inline int mm_match_cgroup(struct mm_struct *mm, struct mem_cgroup *mem) |
| 122 | { | 115 | { |
| 123 | return 1; | 116 | return 1; |
| 124 | } | 117 | } |
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 34023c65d466..af190ceab971 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h | |||
| @@ -88,7 +88,7 @@ struct page { | |||
| 88 | void *virtual; /* Kernel virtual address (NULL if | 88 | void *virtual; /* Kernel virtual address (NULL if |
| 89 | not kmapped, ie. highmem) */ | 89 | not kmapped, ie. highmem) */ |
| 90 | #endif /* WANT_PAGE_VIRTUAL */ | 90 | #endif /* WANT_PAGE_VIRTUAL */ |
| 91 | #ifdef CONFIG_CGROUP_MEM_CONT | 91 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR |
| 92 | unsigned long page_cgroup; | 92 | unsigned long page_cgroup; |
| 93 | #endif | 93 | #endif |
| 94 | }; | 94 | }; |
| @@ -222,7 +222,7 @@ struct mm_struct { | |||
| 222 | /* aio bits */ | 222 | /* aio bits */ |
| 223 | rwlock_t ioctx_list_lock; | 223 | rwlock_t ioctx_list_lock; |
| 224 | struct kioctx *ioctx_list; | 224 | struct kioctx *ioctx_list; |
| 225 | #ifdef CONFIG_CGROUP_MEM_CONT | 225 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR |
| 226 | struct mem_cgroup *mem_cgroup; | 226 | struct mem_cgroup *mem_cgroup; |
| 227 | #endif | 227 | #endif |
| 228 | }; | 228 | }; |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 87195b62de52..f3165e7ac431 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
| @@ -389,6 +389,16 @@ struct pci_driver { | |||
| 389 | #define to_pci_driver(drv) container_of(drv, struct pci_driver, driver) | 389 | #define to_pci_driver(drv) container_of(drv, struct pci_driver, driver) |
| 390 | 390 | ||
| 391 | /** | 391 | /** |
| 392 | * DECLARE_PCI_DEVICE_TABLE - macro used to describe a pci device table | ||
| 393 | * @_table: device table name | ||
| 394 | * | ||
| 395 | * This macro is used to create a struct pci_device_id array (a device table) | ||
| 396 | * in a generic manner. | ||
| 397 | */ | ||
| 398 | #define DECLARE_PCI_DEVICE_TABLE(_table) \ | ||
| 399 | const struct pci_device_id _table[] __devinitconst | ||
| 400 | |||
| 401 | /** | ||
| 392 | * PCI_DEVICE - macro used to describe a specific pci device | 402 | * PCI_DEVICE - macro used to describe a specific pci device |
| 393 | * @vend: the 16 bit PCI Vendor ID | 403 | * @vend: the 16 bit PCI Vendor ID |
| 394 | * @dev: the 16 bit PCI Device ID | 404 | * @dev: the 16 bit PCI Device ID |
diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h index e51b531cd0b2..47fbcba11850 100644 --- a/include/linux/raid/bitmap.h +++ b/include/linux/raid/bitmap.h | |||
| @@ -235,6 +235,8 @@ struct bitmap { | |||
| 235 | 235 | ||
| 236 | unsigned long flags; | 236 | unsigned long flags; |
| 237 | 237 | ||
| 238 | int allclean; | ||
| 239 | |||
| 238 | unsigned long max_write_behind; /* write-behind mode */ | 240 | unsigned long max_write_behind; /* write-behind mode */ |
| 239 | atomic_t behind_writes; | 241 | atomic_t behind_writes; |
| 240 | 242 | ||
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index 85a068bab625..7bb6d1abf71e 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h | |||
| @@ -83,6 +83,7 @@ struct mdk_rdev_s | |||
| 83 | #define BarriersNotsupp 5 /* BIO_RW_BARRIER is not supported */ | 83 | #define BarriersNotsupp 5 /* BIO_RW_BARRIER is not supported */ |
| 84 | #define AllReserved 6 /* If whole device is reserved for | 84 | #define AllReserved 6 /* If whole device is reserved for |
| 85 | * one array */ | 85 | * one array */ |
| 86 | #define AutoDetected 7 /* added by auto-detect */ | ||
| 86 | 87 | ||
| 87 | int desc_nr; /* descriptor index in the superblock */ | 88 | int desc_nr; /* descriptor index in the superblock */ |
| 88 | int raid_disk; /* role of device in array */ | 89 | int raid_disk; /* role of device in array */ |
diff --git a/include/linux/sm501-regs.h b/include/linux/sm501-regs.h index 64236b73c724..d53642d2d899 100644 --- a/include/linux/sm501-regs.h +++ b/include/linux/sm501-regs.h | |||
| @@ -129,11 +129,14 @@ | |||
| 129 | 129 | ||
| 130 | #define SM501_DEVICEID_SM501 (0x05010000) | 130 | #define SM501_DEVICEID_SM501 (0x05010000) |
| 131 | #define SM501_DEVICEID_IDMASK (0xffff0000) | 131 | #define SM501_DEVICEID_IDMASK (0xffff0000) |
| 132 | #define SM501_DEVICEID_REVMASK (0x000000ff) | ||
| 132 | 133 | ||
| 133 | #define SM501_PLLCLOCK_COUNT (0x000064) | 134 | #define SM501_PLLCLOCK_COUNT (0x000064) |
| 134 | #define SM501_MISC_TIMING (0x000068) | 135 | #define SM501_MISC_TIMING (0x000068) |
| 135 | #define SM501_CURRENT_SDRAM_CLOCK (0x00006C) | 136 | #define SM501_CURRENT_SDRAM_CLOCK (0x00006C) |
| 136 | 137 | ||
| 138 | #define SM501_PROGRAMMABLE_PLL_CONTROL (0x000074) | ||
| 139 | |||
| 137 | /* GPIO base */ | 140 | /* GPIO base */ |
| 138 | #define SM501_GPIO (0x010000) | 141 | #define SM501_GPIO (0x010000) |
| 139 | #define SM501_GPIO_DATA_LOW (0x00) | 142 | #define SM501_GPIO_DATA_LOW (0x00) |
diff --git a/include/linux/sm501.h b/include/linux/sm501.h index 932a9efee8a5..bca134544700 100644 --- a/include/linux/sm501.h +++ b/include/linux/sm501.h | |||
| @@ -24,7 +24,8 @@ extern int sm501_unit_power(struct device *dev, | |||
| 24 | extern unsigned long sm501_set_clock(struct device *dev, | 24 | extern unsigned long sm501_set_clock(struct device *dev, |
| 25 | int clksrc, unsigned long freq); | 25 | int clksrc, unsigned long freq); |
| 26 | 26 | ||
| 27 | extern unsigned long sm501_find_clock(int clksrc, unsigned long req_freq); | 27 | extern unsigned long sm501_find_clock(struct device *dev, |
| 28 | int clksrc, unsigned long req_freq); | ||
| 28 | 29 | ||
| 29 | /* sm501_misc_control | 30 | /* sm501_misc_control |
| 30 | * | 31 | * |
diff --git a/include/linux/usb.h b/include/linux/usb.h index 5bd3ae8aaaf4..583e0481dfa0 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h | |||
| @@ -94,10 +94,9 @@ enum usb_interface_condition { | |||
| 94 | * @altsetting: array of interface structures, one for each alternate | 94 | * @altsetting: array of interface structures, one for each alternate |
| 95 | * setting that may be selected. Each one includes a set of | 95 | * setting that may be selected. Each one includes a set of |
| 96 | * endpoint configurations. They will be in no particular order. | 96 | * endpoint configurations. They will be in no particular order. |
| 97 | * @num_altsetting: number of altsettings defined. | ||
| 98 | * @cur_altsetting: the current altsetting. | 97 | * @cur_altsetting: the current altsetting. |
| 98 | * @num_altsetting: number of altsettings defined. | ||
| 99 | * @intf_assoc: interface association descriptor | 99 | * @intf_assoc: interface association descriptor |
| 100 | * @driver: the USB driver that is bound to this interface. | ||
| 101 | * @minor: the minor number assigned to this interface, if this | 100 | * @minor: the minor number assigned to this interface, if this |
| 102 | * interface is bound to a driver that uses the USB major number. | 101 | * interface is bound to a driver that uses the USB major number. |
| 103 | * If this interface does not use the USB major, this field should | 102 | * If this interface does not use the USB major, this field should |
diff --git a/init/Kconfig b/init/Kconfig index 98ebf3725412..074ac97f55e3 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
| @@ -366,6 +366,21 @@ config RESOURCE_COUNTERS | |||
| 366 | infrastructure that works with cgroups | 366 | infrastructure that works with cgroups |
| 367 | depends on CGROUPS | 367 | depends on CGROUPS |
| 368 | 368 | ||
| 369 | config CGROUP_MEM_RES_CTLR | ||
| 370 | bool "Memory Resource Controller for Control Groups" | ||
| 371 | depends on CGROUPS && RESOURCE_COUNTERS | ||
| 372 | help | ||
| 373 | Provides a memory resource controller that manages both page cache and | ||
| 374 | RSS memory. | ||
| 375 | |||
| 376 | Note that setting this option increases fixed memory overhead | ||
| 377 | associated with each page of memory in the system by 4/8 bytes | ||
| 378 | and also increases cache misses because struct page on many 64bit | ||
| 379 | systems will not fit into a single cache line anymore. | ||
| 380 | |||
| 381 | Only enable when you're ok with these trade offs and really | ||
| 382 | sure you need the memory resource controller. | ||
| 383 | |||
| 369 | config SYSFS_DEPRECATED | 384 | config SYSFS_DEPRECATED |
| 370 | bool | 385 | bool |
| 371 | 386 | ||
| @@ -392,21 +407,6 @@ config SYSFS_DEPRECATED_V2 | |||
| 392 | If you are using a distro with the most recent userspace | 407 | If you are using a distro with the most recent userspace |
| 393 | packages, it should be safe to say N here. | 408 | packages, it should be safe to say N here. |
| 394 | 409 | ||
| 395 | config CGROUP_MEM_CONT | ||
| 396 | bool "Memory controller for cgroups" | ||
| 397 | depends on CGROUPS && RESOURCE_COUNTERS | ||
| 398 | help | ||
| 399 | Provides a memory controller that manages both page cache and | ||
| 400 | RSS memory. | ||
| 401 | |||
| 402 | Note that setting this option increases fixed memory overhead | ||
| 403 | associated with each page of memory in the system by 4/8 bytes | ||
| 404 | and also increases cache misses because struct page on many 64bit | ||
| 405 | systems will not fit into a single cache line anymore. | ||
| 406 | |||
| 407 | Only enable when you're ok with these trade offs and really | ||
| 408 | sure you need the memory controller. | ||
| 409 | |||
| 410 | config PROC_PID_CPUSET | 410 | config PROC_PID_CPUSET |
| 411 | bool "Include legacy /proc/<pid>/cpuset file" | 411 | bool "Include legacy /proc/<pid>/cpuset file" |
| 412 | depends on CPUSETS | 412 | depends on CPUSETS |
diff --git a/init/main.c b/init/main.c index 8b1982082ad8..fbb0167c6b8a 100644 --- a/init/main.c +++ b/init/main.c | |||
| @@ -254,7 +254,7 @@ early_param("quiet", quiet_kernel); | |||
| 254 | static int __init loglevel(char *str) | 254 | static int __init loglevel(char *str) |
| 255 | { | 255 | { |
| 256 | get_option(&str, &console_loglevel); | 256 | get_option(&str, &console_loglevel); |
| 257 | return 1; | 257 | return 0; |
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | early_param("loglevel", loglevel); | 260 | early_param("loglevel", loglevel); |
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index d8abe996e009..e9c2fb01e89b 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
| @@ -2232,7 +2232,6 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | |||
| 2232 | 2232 | ||
| 2233 | mutex_lock(&cgroup_mutex); | 2233 | mutex_lock(&cgroup_mutex); |
| 2234 | 2234 | ||
| 2235 | cgrp->flags = 0; | ||
| 2236 | INIT_LIST_HEAD(&cgrp->sibling); | 2235 | INIT_LIST_HEAD(&cgrp->sibling); |
| 2237 | INIT_LIST_HEAD(&cgrp->children); | 2236 | INIT_LIST_HEAD(&cgrp->children); |
| 2238 | INIT_LIST_HEAD(&cgrp->css_sets); | 2237 | INIT_LIST_HEAD(&cgrp->css_sets); |
| @@ -2242,6 +2241,9 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | |||
| 2242 | cgrp->root = parent->root; | 2241 | cgrp->root = parent->root; |
| 2243 | cgrp->top_cgroup = parent->top_cgroup; | 2242 | cgrp->top_cgroup = parent->top_cgroup; |
| 2244 | 2243 | ||
| 2244 | if (notify_on_release(parent)) | ||
| 2245 | set_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags); | ||
| 2246 | |||
| 2245 | for_each_subsys(root, ss) { | 2247 | for_each_subsys(root, ss) { |
| 2246 | struct cgroup_subsys_state *css = ss->create(ss, cgrp); | 2248 | struct cgroup_subsys_state *css = ss->create(ss, cgrp); |
| 2247 | if (IS_ERR(css)) { | 2249 | if (IS_ERR(css)) { |
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 7a86e6432338..fcfb580c3afc 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c | |||
| @@ -498,27 +498,36 @@ static int __kprobes in_kprobes_functions(unsigned long addr) | |||
| 498 | return 0; | 498 | return 0; |
| 499 | } | 499 | } |
| 500 | 500 | ||
| 501 | /* | ||
| 502 | * If we have a symbol_name argument, look it up and add the offset field | ||
| 503 | * to it. This way, we can specify a relative address to a symbol. | ||
| 504 | */ | ||
| 505 | static kprobe_opcode_t __kprobes *kprobe_addr(struct kprobe *p) | ||
| 506 | { | ||
| 507 | kprobe_opcode_t *addr = p->addr; | ||
| 508 | if (p->symbol_name) { | ||
| 509 | if (addr) | ||
| 510 | return NULL; | ||
| 511 | kprobe_lookup_name(p->symbol_name, addr); | ||
| 512 | } | ||
| 513 | |||
| 514 | if (!addr) | ||
| 515 | return NULL; | ||
| 516 | return (kprobe_opcode_t *)(((char *)addr) + p->offset); | ||
| 517 | } | ||
| 518 | |||
| 501 | static int __kprobes __register_kprobe(struct kprobe *p, | 519 | static int __kprobes __register_kprobe(struct kprobe *p, |
| 502 | unsigned long called_from) | 520 | unsigned long called_from) |
| 503 | { | 521 | { |
| 504 | int ret = 0; | 522 | int ret = 0; |
| 505 | struct kprobe *old_p; | 523 | struct kprobe *old_p; |
| 506 | struct module *probed_mod; | 524 | struct module *probed_mod; |
| 525 | kprobe_opcode_t *addr; | ||
| 507 | 526 | ||
| 508 | /* | 527 | addr = kprobe_addr(p); |
| 509 | * If we have a symbol_name argument look it up, | 528 | if (!addr) |
| 510 | * and add it to the address. That way the addr | ||
| 511 | * field can either be global or relative to a symbol. | ||
| 512 | */ | ||
| 513 | if (p->symbol_name) { | ||
| 514 | if (p->addr) | ||
| 515 | return -EINVAL; | ||
| 516 | kprobe_lookup_name(p->symbol_name, p->addr); | ||
| 517 | } | ||
| 518 | |||
| 519 | if (!p->addr) | ||
| 520 | return -EINVAL; | 529 | return -EINVAL; |
| 521 | p->addr = (kprobe_opcode_t *)(((char *)p->addr)+ p->offset); | 530 | p->addr = addr; |
| 522 | 531 | ||
| 523 | if (!kernel_text_address((unsigned long) p->addr) || | 532 | if (!kernel_text_address((unsigned long) p->addr) || |
| 524 | in_kprobes_functions((unsigned long) p->addr)) | 533 | in_kprobes_functions((unsigned long) p->addr)) |
| @@ -678,8 +687,7 @@ void __kprobes unregister_jprobe(struct jprobe *jp) | |||
| 678 | unregister_kprobe(&jp->kp); | 687 | unregister_kprobe(&jp->kp); |
| 679 | } | 688 | } |
| 680 | 689 | ||
| 681 | #ifdef ARCH_SUPPORTS_KRETPROBES | 690 | #ifdef CONFIG_KRETPROBES |
| 682 | |||
| 683 | /* | 691 | /* |
| 684 | * This kprobe pre_handler is registered with every kretprobe. When probe | 692 | * This kprobe pre_handler is registered with every kretprobe. When probe |
| 685 | * hits it will set up the return probe. | 693 | * hits it will set up the return probe. |
| @@ -722,12 +730,12 @@ int __kprobes register_kretprobe(struct kretprobe *rp) | |||
| 722 | int ret = 0; | 730 | int ret = 0; |
| 723 | struct kretprobe_instance *inst; | 731 | struct kretprobe_instance *inst; |
| 724 | int i; | 732 | int i; |
| 725 | void *addr = rp->kp.addr; | 733 | void *addr; |
| 726 | 734 | ||
| 727 | if (kretprobe_blacklist_size) { | 735 | if (kretprobe_blacklist_size) { |
| 728 | if (addr == NULL) | 736 | addr = kprobe_addr(&rp->kp); |
| 729 | kprobe_lookup_name(rp->kp.symbol_name, addr); | 737 | if (!addr) |
| 730 | addr += rp->kp.offset; | 738 | return -EINVAL; |
| 731 | 739 | ||
| 732 | for (i = 0; kretprobe_blacklist[i].name != NULL; i++) { | 740 | for (i = 0; kretprobe_blacklist[i].name != NULL; i++) { |
| 733 | if (kretprobe_blacklist[i].addr == addr) | 741 | if (kretprobe_blacklist[i].addr == addr) |
| @@ -769,8 +777,7 @@ int __kprobes register_kretprobe(struct kretprobe *rp) | |||
| 769 | return ret; | 777 | return ret; |
| 770 | } | 778 | } |
| 771 | 779 | ||
| 772 | #else /* ARCH_SUPPORTS_KRETPROBES */ | 780 | #else /* CONFIG_KRETPROBES */ |
| 773 | |||
| 774 | int __kprobes register_kretprobe(struct kretprobe *rp) | 781 | int __kprobes register_kretprobe(struct kretprobe *rp) |
| 775 | { | 782 | { |
| 776 | return -ENOSYS; | 783 | return -ENOSYS; |
| @@ -781,8 +788,7 @@ static int __kprobes pre_handler_kretprobe(struct kprobe *p, | |||
| 781 | { | 788 | { |
| 782 | return 0; | 789 | return 0; |
| 783 | } | 790 | } |
| 784 | 791 | #endif /* CONFIG_KRETPROBES */ | |
| 785 | #endif /* ARCH_SUPPORTS_KRETPROBES */ | ||
| 786 | 792 | ||
| 787 | void __kprobes unregister_kretprobe(struct kretprobe *rp) | 793 | void __kprobes unregister_kretprobe(struct kretprobe *rp) |
| 788 | { | 794 | { |
diff --git a/kernel/marker.c b/kernel/marker.c index 50effc01d9a2..48a4ea5afffd 100644 --- a/kernel/marker.c +++ b/kernel/marker.c | |||
| @@ -698,14 +698,12 @@ int marker_probe_unregister(const char *name, | |||
| 698 | { | 698 | { |
| 699 | struct marker_entry *entry; | 699 | struct marker_entry *entry; |
| 700 | struct marker_probe_closure *old; | 700 | struct marker_probe_closure *old; |
| 701 | int ret = 0; | 701 | int ret = -ENOENT; |
| 702 | 702 | ||
| 703 | mutex_lock(&markers_mutex); | 703 | mutex_lock(&markers_mutex); |
| 704 | entry = get_marker(name); | 704 | entry = get_marker(name); |
| 705 | if (!entry) { | 705 | if (!entry) |
| 706 | ret = -ENOENT; | ||
| 707 | goto end; | 706 | goto end; |
| 708 | } | ||
| 709 | if (entry->rcu_pending) | 707 | if (entry->rcu_pending) |
| 710 | rcu_barrier(); | 708 | rcu_barrier(); |
| 711 | old = marker_entry_remove_probe(entry, probe, probe_private); | 709 | old = marker_entry_remove_probe(entry, probe, probe_private); |
| @@ -713,12 +711,15 @@ int marker_probe_unregister(const char *name, | |||
| 713 | marker_update_probes(); /* may update entry */ | 711 | marker_update_probes(); /* may update entry */ |
| 714 | mutex_lock(&markers_mutex); | 712 | mutex_lock(&markers_mutex); |
| 715 | entry = get_marker(name); | 713 | entry = get_marker(name); |
| 714 | if (!entry) | ||
| 715 | goto end; | ||
| 716 | entry->oldptr = old; | 716 | entry->oldptr = old; |
| 717 | entry->rcu_pending = 1; | 717 | entry->rcu_pending = 1; |
| 718 | /* write rcu_pending before calling the RCU callback */ | 718 | /* write rcu_pending before calling the RCU callback */ |
| 719 | smp_wmb(); | 719 | smp_wmb(); |
| 720 | call_rcu(&entry->rcu, free_old_closure); | 720 | call_rcu(&entry->rcu, free_old_closure); |
| 721 | remove_marker(name); /* Ignore busy error message */ | 721 | remove_marker(name); /* Ignore busy error message */ |
| 722 | ret = 0; | ||
| 722 | end: | 723 | end: |
| 723 | mutex_unlock(&markers_mutex); | 724 | mutex_unlock(&markers_mutex); |
| 724 | return ret; | 725 | return ret; |
diff --git a/kernel/res_counter.c b/kernel/res_counter.c index 16cbec2d5d60..efbfc0fc232f 100644 --- a/kernel/res_counter.c +++ b/kernel/res_counter.c | |||
| @@ -113,6 +113,7 @@ ssize_t res_counter_write(struct res_counter *counter, int member, | |||
| 113 | 113 | ||
| 114 | ret = -EINVAL; | 114 | ret = -EINVAL; |
| 115 | 115 | ||
| 116 | strstrip(buf); | ||
| 116 | if (write_strategy) { | 117 | if (write_strategy) { |
| 117 | if (write_strategy(buf, &tmp)) { | 118 | if (write_strategy(buf, &tmp)) { |
| 118 | goto out_free; | 119 | goto out_free; |
diff --git a/lib/iommu-helper.c b/lib/iommu-helper.c index 495575a59ca6..a3b8d4c3f77a 100644 --- a/lib/iommu-helper.c +++ b/lib/iommu-helper.c | |||
| @@ -40,10 +40,12 @@ static inline void set_bit_area(unsigned long *map, unsigned long i, | |||
| 40 | } | 40 | } |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | static inline int is_span_boundary(unsigned int index, unsigned int nr, | 43 | int iommu_is_span_boundary(unsigned int index, unsigned int nr, |
| 44 | unsigned long shift, | 44 | unsigned long shift, |
| 45 | unsigned long boundary_size) | 45 | unsigned long boundary_size) |
| 46 | { | 46 | { |
| 47 | BUG_ON(!is_power_of_2(boundary_size)); | ||
| 48 | |||
| 47 | shift = (shift + index) & (boundary_size - 1); | 49 | shift = (shift + index) & (boundary_size - 1); |
| 48 | return shift + nr > boundary_size; | 50 | return shift + nr > boundary_size; |
| 49 | } | 51 | } |
| @@ -57,7 +59,7 @@ unsigned long iommu_area_alloc(unsigned long *map, unsigned long size, | |||
| 57 | again: | 59 | again: |
| 58 | index = find_next_zero_area(map, size, start, nr, align_mask); | 60 | index = find_next_zero_area(map, size, start, nr, align_mask); |
| 59 | if (index != -1) { | 61 | if (index != -1) { |
| 60 | if (is_span_boundary(index, nr, shift, boundary_size)) { | 62 | if (iommu_is_span_boundary(index, nr, shift, boundary_size)) { |
| 61 | /* we could do more effectively */ | 63 | /* we could do more effectively */ |
| 62 | start = index + 1; | 64 | start = index + 1; |
| 63 | goto again; | 65 | goto again; |
diff --git a/mm/Makefile b/mm/Makefile index 9f117bab5322..a5b0dd93427a 100644 --- a/mm/Makefile +++ b/mm/Makefile | |||
| @@ -32,5 +32,5 @@ obj-$(CONFIG_FS_XIP) += filemap_xip.o | |||
| 32 | obj-$(CONFIG_MIGRATION) += migrate.o | 32 | obj-$(CONFIG_MIGRATION) += migrate.o |
| 33 | obj-$(CONFIG_SMP) += allocpercpu.o | 33 | obj-$(CONFIG_SMP) += allocpercpu.o |
| 34 | obj-$(CONFIG_QUICKLIST) += quicklist.o | 34 | obj-$(CONFIG_QUICKLIST) += quicklist.o |
| 35 | obj-$(CONFIG_CGROUP_MEM_CONT) += memcontrol.o | 35 | obj-$(CONFIG_CGROUP_MEM_RES_CTLR) += memcontrol.o |
| 36 | 36 | ||
diff --git a/mm/allocpercpu.c b/mm/allocpercpu.c index 7e58322b7134..b0012e27fea8 100644 --- a/mm/allocpercpu.c +++ b/mm/allocpercpu.c | |||
| @@ -6,6 +6,10 @@ | |||
| 6 | #include <linux/mm.h> | 6 | #include <linux/mm.h> |
| 7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
| 8 | 8 | ||
| 9 | #ifndef cache_line_size | ||
| 10 | #define cache_line_size() L1_CACHE_BYTES | ||
| 11 | #endif | ||
| 12 | |||
| 9 | /** | 13 | /** |
| 10 | * percpu_depopulate - depopulate per-cpu data for given cpu | 14 | * percpu_depopulate - depopulate per-cpu data for given cpu |
| 11 | * @__pdata: per-cpu data to depopulate | 15 | * @__pdata: per-cpu data to depopulate |
| @@ -52,6 +56,11 @@ void *percpu_populate(void *__pdata, size_t size, gfp_t gfp, int cpu) | |||
| 52 | struct percpu_data *pdata = __percpu_disguise(__pdata); | 56 | struct percpu_data *pdata = __percpu_disguise(__pdata); |
| 53 | int node = cpu_to_node(cpu); | 57 | int node = cpu_to_node(cpu); |
| 54 | 58 | ||
| 59 | /* | ||
| 60 | * We should make sure each CPU gets private memory. | ||
| 61 | */ | ||
| 62 | size = roundup(size, cache_line_size()); | ||
| 63 | |||
| 55 | BUG_ON(pdata->ptrs[cpu]); | 64 | BUG_ON(pdata->ptrs[cpu]); |
| 56 | if (node_online(node)) | 65 | if (node_online(node)) |
| 57 | pdata->ptrs[cpu] = kmalloc_node(size, gfp|__GFP_ZERO, node); | 66 | pdata->ptrs[cpu] = kmalloc_node(size, gfp|__GFP_ZERO, node); |
| @@ -98,7 +107,11 @@ EXPORT_SYMBOL_GPL(__percpu_populate_mask); | |||
| 98 | */ | 107 | */ |
| 99 | void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask) | 108 | void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask) |
| 100 | { | 109 | { |
| 101 | void *pdata = kzalloc(nr_cpu_ids * sizeof(void *), gfp); | 110 | /* |
| 111 | * We allocate whole cache lines to avoid false sharing | ||
| 112 | */ | ||
| 113 | size_t sz = roundup(nr_cpu_ids * sizeof(void *), cache_line_size()); | ||
| 114 | void *pdata = kzalloc(sz, gfp); | ||
| 102 | void *__pdata = __percpu_disguise(pdata); | 115 | void *__pdata = __percpu_disguise(pdata); |
| 103 | 116 | ||
| 104 | if (unlikely(!pdata)) | 117 | if (unlikely(!pdata)) |
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 89e6286a7f57..dcacc811e70e 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
| @@ -71,7 +71,25 @@ static void enqueue_huge_page(struct page *page) | |||
| 71 | free_huge_pages_node[nid]++; | 71 | free_huge_pages_node[nid]++; |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | static struct page *dequeue_huge_page(struct vm_area_struct *vma, | 74 | static struct page *dequeue_huge_page(void) |
| 75 | { | ||
| 76 | int nid; | ||
| 77 | struct page *page = NULL; | ||
| 78 | |||
| 79 | for (nid = 0; nid < MAX_NUMNODES; ++nid) { | ||
| 80 | if (!list_empty(&hugepage_freelists[nid])) { | ||
| 81 | page = list_entry(hugepage_freelists[nid].next, | ||
| 82 | struct page, lru); | ||
| 83 | list_del(&page->lru); | ||
| 84 | free_huge_pages--; | ||
| 85 | free_huge_pages_node[nid]--; | ||
| 86 | break; | ||
| 87 | } | ||
| 88 | } | ||
| 89 | return page; | ||
| 90 | } | ||
| 91 | |||
| 92 | static struct page *dequeue_huge_page_vma(struct vm_area_struct *vma, | ||
| 75 | unsigned long address) | 93 | unsigned long address) |
| 76 | { | 94 | { |
| 77 | int nid; | 95 | int nid; |
| @@ -296,8 +314,10 @@ static int gather_surplus_pages(int delta) | |||
| 296 | int needed, allocated; | 314 | int needed, allocated; |
| 297 | 315 | ||
| 298 | needed = (resv_huge_pages + delta) - free_huge_pages; | 316 | needed = (resv_huge_pages + delta) - free_huge_pages; |
| 299 | if (needed <= 0) | 317 | if (needed <= 0) { |
| 318 | resv_huge_pages += delta; | ||
| 300 | return 0; | 319 | return 0; |
| 320 | } | ||
| 301 | 321 | ||
| 302 | allocated = 0; | 322 | allocated = 0; |
| 303 | INIT_LIST_HEAD(&surplus_list); | 323 | INIT_LIST_HEAD(&surplus_list); |
| @@ -335,9 +355,12 @@ retry: | |||
| 335 | * The surplus_list now contains _at_least_ the number of extra pages | 355 | * The surplus_list now contains _at_least_ the number of extra pages |
| 336 | * needed to accomodate the reservation. Add the appropriate number | 356 | * needed to accomodate the reservation. Add the appropriate number |
| 337 | * of pages to the hugetlb pool and free the extras back to the buddy | 357 | * of pages to the hugetlb pool and free the extras back to the buddy |
| 338 | * allocator. | 358 | * allocator. Commit the entire reservation here to prevent another |
| 359 | * process from stealing the pages as they are added to the pool but | ||
| 360 | * before they are reserved. | ||
| 339 | */ | 361 | */ |
| 340 | needed += allocated; | 362 | needed += allocated; |
| 363 | resv_huge_pages += delta; | ||
| 341 | ret = 0; | 364 | ret = 0; |
| 342 | free: | 365 | free: |
| 343 | list_for_each_entry_safe(page, tmp, &surplus_list, lru) { | 366 | list_for_each_entry_safe(page, tmp, &surplus_list, lru) { |
| @@ -371,6 +394,9 @@ static void return_unused_surplus_pages(unsigned long unused_resv_pages) | |||
| 371 | struct page *page; | 394 | struct page *page; |
| 372 | unsigned long nr_pages; | 395 | unsigned long nr_pages; |
| 373 | 396 | ||
| 397 | /* Uncommit the reservation */ | ||
| 398 | resv_huge_pages -= unused_resv_pages; | ||
| 399 | |||
| 374 | nr_pages = min(unused_resv_pages, surplus_huge_pages); | 400 | nr_pages = min(unused_resv_pages, surplus_huge_pages); |
| 375 | 401 | ||
| 376 | while (nr_pages) { | 402 | while (nr_pages) { |
| @@ -402,7 +428,7 @@ static struct page *alloc_huge_page_shared(struct vm_area_struct *vma, | |||
| 402 | struct page *page; | 428 | struct page *page; |
| 403 | 429 | ||
| 404 | spin_lock(&hugetlb_lock); | 430 | spin_lock(&hugetlb_lock); |
| 405 | page = dequeue_huge_page(vma, addr); | 431 | page = dequeue_huge_page_vma(vma, addr); |
| 406 | spin_unlock(&hugetlb_lock); | 432 | spin_unlock(&hugetlb_lock); |
| 407 | return page ? page : ERR_PTR(-VM_FAULT_OOM); | 433 | return page ? page : ERR_PTR(-VM_FAULT_OOM); |
| 408 | } | 434 | } |
| @@ -417,7 +443,7 @@ static struct page *alloc_huge_page_private(struct vm_area_struct *vma, | |||
| 417 | 443 | ||
| 418 | spin_lock(&hugetlb_lock); | 444 | spin_lock(&hugetlb_lock); |
| 419 | if (free_huge_pages > resv_huge_pages) | 445 | if (free_huge_pages > resv_huge_pages) |
| 420 | page = dequeue_huge_page(vma, addr); | 446 | page = dequeue_huge_page_vma(vma, addr); |
| 421 | spin_unlock(&hugetlb_lock); | 447 | spin_unlock(&hugetlb_lock); |
| 422 | if (!page) { | 448 | if (!page) { |
| 423 | page = alloc_buddy_huge_page(vma, addr); | 449 | page = alloc_buddy_huge_page(vma, addr); |
| @@ -570,7 +596,7 @@ static unsigned long set_max_huge_pages(unsigned long count) | |||
| 570 | min_count = max(count, min_count); | 596 | min_count = max(count, min_count); |
| 571 | try_to_free_low(min_count); | 597 | try_to_free_low(min_count); |
| 572 | while (min_count < persistent_huge_pages) { | 598 | while (min_count < persistent_huge_pages) { |
| 573 | struct page *page = dequeue_huge_page(NULL, 0); | 599 | struct page *page = dequeue_huge_page(); |
| 574 | if (!page) | 600 | if (!page) |
| 575 | break; | 601 | break; |
| 576 | update_and_free_page(page); | 602 | update_and_free_page(page); |
| @@ -1205,12 +1231,13 @@ static int hugetlb_acct_memory(long delta) | |||
| 1205 | if (gather_surplus_pages(delta) < 0) | 1231 | if (gather_surplus_pages(delta) < 0) |
| 1206 | goto out; | 1232 | goto out; |
| 1207 | 1233 | ||
| 1208 | if (delta > cpuset_mems_nr(free_huge_pages_node)) | 1234 | if (delta > cpuset_mems_nr(free_huge_pages_node)) { |
| 1235 | return_unused_surplus_pages(delta); | ||
| 1209 | goto out; | 1236 | goto out; |
| 1237 | } | ||
| 1210 | } | 1238 | } |
| 1211 | 1239 | ||
| 1212 | ret = 0; | 1240 | ret = 0; |
| 1213 | resv_huge_pages += delta; | ||
| 1214 | if (delta < 0) | 1241 | if (delta < 0) |
| 1215 | return_unused_surplus_pages((unsigned long) -delta); | 1242 | return_unused_surplus_pages((unsigned long) -delta); |
| 1216 | 1243 | ||
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 631002d085d1..8b9f6cae938e 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
| @@ -137,14 +137,21 @@ struct mem_cgroup { | |||
| 137 | */ | 137 | */ |
| 138 | struct mem_cgroup_stat stat; | 138 | struct mem_cgroup_stat stat; |
| 139 | }; | 139 | }; |
| 140 | static struct mem_cgroup init_mem_cgroup; | ||
| 140 | 141 | ||
| 141 | /* | 142 | /* |
| 142 | * We use the lower bit of the page->page_cgroup pointer as a bit spin | 143 | * We use the lower bit of the page->page_cgroup pointer as a bit spin |
| 143 | * lock. We need to ensure that page->page_cgroup is atleast two | 144 | * lock. We need to ensure that page->page_cgroup is at least two |
| 144 | * byte aligned (based on comments from Nick Piggin) | 145 | * byte aligned (based on comments from Nick Piggin). But since |
| 146 | * bit_spin_lock doesn't actually set that lock bit in a non-debug | ||
| 147 | * uniprocessor kernel, we should avoid setting it here too. | ||
| 145 | */ | 148 | */ |
| 146 | #define PAGE_CGROUP_LOCK_BIT 0x0 | 149 | #define PAGE_CGROUP_LOCK_BIT 0x0 |
| 147 | #define PAGE_CGROUP_LOCK (1 << PAGE_CGROUP_LOCK_BIT) | 150 | #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) |
| 151 | #define PAGE_CGROUP_LOCK (1 << PAGE_CGROUP_LOCK_BIT) | ||
| 152 | #else | ||
| 153 | #define PAGE_CGROUP_LOCK 0x0 | ||
| 154 | #endif | ||
| 148 | 155 | ||
| 149 | /* | 156 | /* |
| 150 | * A page_cgroup page is associated with every page descriptor. The | 157 | * A page_cgroup page is associated with every page descriptor. The |
| @@ -154,37 +161,27 @@ struct page_cgroup { | |||
| 154 | struct list_head lru; /* per cgroup LRU list */ | 161 | struct list_head lru; /* per cgroup LRU list */ |
| 155 | struct page *page; | 162 | struct page *page; |
| 156 | struct mem_cgroup *mem_cgroup; | 163 | struct mem_cgroup *mem_cgroup; |
| 157 | atomic_t ref_cnt; /* Helpful when pages move b/w */ | 164 | int ref_cnt; /* cached, mapped, migrating */ |
| 158 | /* mapped and cached states */ | 165 | int flags; |
| 159 | int flags; | ||
| 160 | }; | 166 | }; |
| 161 | #define PAGE_CGROUP_FLAG_CACHE (0x1) /* charged as cache */ | 167 | #define PAGE_CGROUP_FLAG_CACHE (0x1) /* charged as cache */ |
| 162 | #define PAGE_CGROUP_FLAG_ACTIVE (0x2) /* page is active in this cgroup */ | 168 | #define PAGE_CGROUP_FLAG_ACTIVE (0x2) /* page is active in this cgroup */ |
| 163 | 169 | ||
| 164 | static inline int page_cgroup_nid(struct page_cgroup *pc) | 170 | static int page_cgroup_nid(struct page_cgroup *pc) |
| 165 | { | 171 | { |
| 166 | return page_to_nid(pc->page); | 172 | return page_to_nid(pc->page); |
| 167 | } | 173 | } |
| 168 | 174 | ||
| 169 | static inline enum zone_type page_cgroup_zid(struct page_cgroup *pc) | 175 | static enum zone_type page_cgroup_zid(struct page_cgroup *pc) |
| 170 | { | 176 | { |
| 171 | return page_zonenum(pc->page); | 177 | return page_zonenum(pc->page); |
| 172 | } | 178 | } |
| 173 | 179 | ||
| 174 | enum { | ||
| 175 | MEM_CGROUP_TYPE_UNSPEC = 0, | ||
| 176 | MEM_CGROUP_TYPE_MAPPED, | ||
| 177 | MEM_CGROUP_TYPE_CACHED, | ||
| 178 | MEM_CGROUP_TYPE_ALL, | ||
| 179 | MEM_CGROUP_TYPE_MAX, | ||
| 180 | }; | ||
| 181 | |||
| 182 | enum charge_type { | 180 | enum charge_type { |
| 183 | MEM_CGROUP_CHARGE_TYPE_CACHE = 0, | 181 | MEM_CGROUP_CHARGE_TYPE_CACHE = 0, |
| 184 | MEM_CGROUP_CHARGE_TYPE_MAPPED, | 182 | MEM_CGROUP_CHARGE_TYPE_MAPPED, |
| 185 | }; | 183 | }; |
| 186 | 184 | ||
| 187 | |||
| 188 | /* | 185 | /* |
| 189 | * Always modified under lru lock. Then, not necessary to preempt_disable() | 186 | * Always modified under lru lock. Then, not necessary to preempt_disable() |
| 190 | */ | 187 | */ |
| @@ -193,23 +190,21 @@ static void mem_cgroup_charge_statistics(struct mem_cgroup *mem, int flags, | |||
| 193 | { | 190 | { |
| 194 | int val = (charge)? 1 : -1; | 191 | int val = (charge)? 1 : -1; |
| 195 | struct mem_cgroup_stat *stat = &mem->stat; | 192 | struct mem_cgroup_stat *stat = &mem->stat; |
| 196 | VM_BUG_ON(!irqs_disabled()); | ||
| 197 | 193 | ||
| 194 | VM_BUG_ON(!irqs_disabled()); | ||
| 198 | if (flags & PAGE_CGROUP_FLAG_CACHE) | 195 | if (flags & PAGE_CGROUP_FLAG_CACHE) |
| 199 | __mem_cgroup_stat_add_safe(stat, | 196 | __mem_cgroup_stat_add_safe(stat, MEM_CGROUP_STAT_CACHE, val); |
| 200 | MEM_CGROUP_STAT_CACHE, val); | ||
| 201 | else | 197 | else |
| 202 | __mem_cgroup_stat_add_safe(stat, MEM_CGROUP_STAT_RSS, val); | 198 | __mem_cgroup_stat_add_safe(stat, MEM_CGROUP_STAT_RSS, val); |
| 203 | } | 199 | } |
| 204 | 200 | ||
| 205 | static inline struct mem_cgroup_per_zone * | 201 | static struct mem_cgroup_per_zone * |
| 206 | mem_cgroup_zoneinfo(struct mem_cgroup *mem, int nid, int zid) | 202 | mem_cgroup_zoneinfo(struct mem_cgroup *mem, int nid, int zid) |
| 207 | { | 203 | { |
| 208 | BUG_ON(!mem->info.nodeinfo[nid]); | ||
| 209 | return &mem->info.nodeinfo[nid]->zoneinfo[zid]; | 204 | return &mem->info.nodeinfo[nid]->zoneinfo[zid]; |
| 210 | } | 205 | } |
| 211 | 206 | ||
| 212 | static inline struct mem_cgroup_per_zone * | 207 | static struct mem_cgroup_per_zone * |
| 213 | page_cgroup_zoneinfo(struct page_cgroup *pc) | 208 | page_cgroup_zoneinfo(struct page_cgroup *pc) |
| 214 | { | 209 | { |
| 215 | struct mem_cgroup *mem = pc->mem_cgroup; | 210 | struct mem_cgroup *mem = pc->mem_cgroup; |
| @@ -234,18 +229,14 @@ static unsigned long mem_cgroup_get_all_zonestat(struct mem_cgroup *mem, | |||
| 234 | return total; | 229 | return total; |
| 235 | } | 230 | } |
| 236 | 231 | ||
| 237 | static struct mem_cgroup init_mem_cgroup; | 232 | static struct mem_cgroup *mem_cgroup_from_cont(struct cgroup *cont) |
| 238 | |||
| 239 | static inline | ||
| 240 | struct mem_cgroup *mem_cgroup_from_cont(struct cgroup *cont) | ||
| 241 | { | 233 | { |
| 242 | return container_of(cgroup_subsys_state(cont, | 234 | return container_of(cgroup_subsys_state(cont, |
| 243 | mem_cgroup_subsys_id), struct mem_cgroup, | 235 | mem_cgroup_subsys_id), struct mem_cgroup, |
| 244 | css); | 236 | css); |
| 245 | } | 237 | } |
| 246 | 238 | ||
| 247 | static inline | 239 | static struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p) |
| 248 | struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p) | ||
| 249 | { | 240 | { |
| 250 | return container_of(task_subsys_state(p, mem_cgroup_subsys_id), | 241 | return container_of(task_subsys_state(p, mem_cgroup_subsys_id), |
| 251 | struct mem_cgroup, css); | 242 | struct mem_cgroup, css); |
| @@ -267,81 +258,33 @@ void mm_free_cgroup(struct mm_struct *mm) | |||
| 267 | 258 | ||
| 268 | static inline int page_cgroup_locked(struct page *page) | 259 | static inline int page_cgroup_locked(struct page *page) |
| 269 | { | 260 | { |
| 270 | return bit_spin_is_locked(PAGE_CGROUP_LOCK_BIT, | 261 | return bit_spin_is_locked(PAGE_CGROUP_LOCK_BIT, &page->page_cgroup); |
| 271 | &page->page_cgroup); | ||
| 272 | } | 262 | } |
| 273 | 263 | ||
| 274 | void page_assign_page_cgroup(struct page *page, struct page_cgroup *pc) | 264 | static void page_assign_page_cgroup(struct page *page, struct page_cgroup *pc) |
| 275 | { | 265 | { |
| 276 | int locked; | 266 | VM_BUG_ON(!page_cgroup_locked(page)); |
| 277 | 267 | page->page_cgroup = ((unsigned long)pc | PAGE_CGROUP_LOCK); | |
| 278 | /* | ||
| 279 | * While resetting the page_cgroup we might not hold the | ||
| 280 | * page_cgroup lock. free_hot_cold_page() is an example | ||
| 281 | * of such a scenario | ||
| 282 | */ | ||
| 283 | if (pc) | ||
| 284 | VM_BUG_ON(!page_cgroup_locked(page)); | ||
| 285 | locked = (page->page_cgroup & PAGE_CGROUP_LOCK); | ||
| 286 | page->page_cgroup = ((unsigned long)pc | locked); | ||
| 287 | } | 268 | } |
| 288 | 269 | ||
| 289 | struct page_cgroup *page_get_page_cgroup(struct page *page) | 270 | struct page_cgroup *page_get_page_cgroup(struct page *page) |
| 290 | { | 271 | { |
| 291 | return (struct page_cgroup *) | 272 | return (struct page_cgroup *) (page->page_cgroup & ~PAGE_CGROUP_LOCK); |
| 292 | (page->page_cgroup & ~PAGE_CGROUP_LOCK); | ||
| 293 | } | 273 | } |
| 294 | 274 | ||
| 295 | static void __always_inline lock_page_cgroup(struct page *page) | 275 | static void lock_page_cgroup(struct page *page) |
| 296 | { | 276 | { |
| 297 | bit_spin_lock(PAGE_CGROUP_LOCK_BIT, &page->page_cgroup); | 277 | bit_spin_lock(PAGE_CGROUP_LOCK_BIT, &page->page_cgroup); |
| 298 | VM_BUG_ON(!page_cgroup_locked(page)); | ||
| 299 | } | ||
| 300 | |||
| 301 | static void __always_inline unlock_page_cgroup(struct page *page) | ||
| 302 | { | ||
| 303 | bit_spin_unlock(PAGE_CGROUP_LOCK_BIT, &page->page_cgroup); | ||
| 304 | } | 278 | } |
| 305 | 279 | ||
| 306 | /* | 280 | static int try_lock_page_cgroup(struct page *page) |
| 307 | * Tie new page_cgroup to struct page under lock_page_cgroup() | ||
| 308 | * This can fail if the page has been tied to a page_cgroup. | ||
| 309 | * If success, returns 0. | ||
| 310 | */ | ||
| 311 | static int page_cgroup_assign_new_page_cgroup(struct page *page, | ||
| 312 | struct page_cgroup *pc) | ||
| 313 | { | 281 | { |
| 314 | int ret = 0; | 282 | return bit_spin_trylock(PAGE_CGROUP_LOCK_BIT, &page->page_cgroup); |
| 315 | |||
| 316 | lock_page_cgroup(page); | ||
| 317 | if (!page_get_page_cgroup(page)) | ||
| 318 | page_assign_page_cgroup(page, pc); | ||
| 319 | else /* A page is tied to other pc. */ | ||
| 320 | ret = 1; | ||
| 321 | unlock_page_cgroup(page); | ||
| 322 | return ret; | ||
| 323 | } | 283 | } |
| 324 | 284 | ||
| 325 | /* | 285 | static void unlock_page_cgroup(struct page *page) |
| 326 | * Clear page->page_cgroup member under lock_page_cgroup(). | ||
| 327 | * If given "pc" value is different from one page->page_cgroup, | ||
| 328 | * page->cgroup is not cleared. | ||
| 329 | * Returns a value of page->page_cgroup at lock taken. | ||
| 330 | * A can can detect failure of clearing by following | ||
| 331 | * clear_page_cgroup(page, pc) == pc | ||
| 332 | */ | ||
| 333 | |||
| 334 | static struct page_cgroup *clear_page_cgroup(struct page *page, | ||
| 335 | struct page_cgroup *pc) | ||
| 336 | { | 286 | { |
| 337 | struct page_cgroup *ret; | 287 | bit_spin_unlock(PAGE_CGROUP_LOCK_BIT, &page->page_cgroup); |
| 338 | /* lock and clear */ | ||
| 339 | lock_page_cgroup(page); | ||
| 340 | ret = page_get_page_cgroup(page); | ||
| 341 | if (likely(ret == pc)) | ||
| 342 | page_assign_page_cgroup(page, NULL); | ||
| 343 | unlock_page_cgroup(page); | ||
| 344 | return ret; | ||
| 345 | } | 288 | } |
| 346 | 289 | ||
| 347 | static void __mem_cgroup_remove_list(struct page_cgroup *pc) | 290 | static void __mem_cgroup_remove_list(struct page_cgroup *pc) |
| @@ -399,7 +342,7 @@ int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *mem) | |||
| 399 | int ret; | 342 | int ret; |
| 400 | 343 | ||
| 401 | task_lock(task); | 344 | task_lock(task); |
| 402 | ret = task->mm && vm_match_cgroup(task->mm, mem); | 345 | ret = task->mm && mm_match_cgroup(task->mm, mem); |
| 403 | task_unlock(task); | 346 | task_unlock(task); |
| 404 | return ret; | 347 | return ret; |
| 405 | } | 348 | } |
| @@ -407,18 +350,30 @@ int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *mem) | |||
| 407 | /* | 350 | /* |
| 408 | * This routine assumes that the appropriate zone's lru lock is already held | 351 | * This routine assumes that the appropriate zone's lru lock is already held |
| 409 | */ | 352 | */ |
| 410 | void mem_cgroup_move_lists(struct page_cgroup *pc, bool active) | 353 | void mem_cgroup_move_lists(struct page *page, bool active) |
| 411 | { | 354 | { |
| 355 | struct page_cgroup *pc; | ||
| 412 | struct mem_cgroup_per_zone *mz; | 356 | struct mem_cgroup_per_zone *mz; |
| 413 | unsigned long flags; | 357 | unsigned long flags; |
| 414 | 358 | ||
| 415 | if (!pc) | 359 | /* |
| 360 | * We cannot lock_page_cgroup while holding zone's lru_lock, | ||
| 361 | * because other holders of lock_page_cgroup can be interrupted | ||
| 362 | * with an attempt to rotate_reclaimable_page. But we cannot | ||
| 363 | * safely get to page_cgroup without it, so just try_lock it: | ||
| 364 | * mem_cgroup_isolate_pages allows for page left on wrong list. | ||
| 365 | */ | ||
| 366 | if (!try_lock_page_cgroup(page)) | ||
| 416 | return; | 367 | return; |
| 417 | 368 | ||
| 418 | mz = page_cgroup_zoneinfo(pc); | 369 | pc = page_get_page_cgroup(page); |
| 419 | spin_lock_irqsave(&mz->lru_lock, flags); | 370 | if (pc) { |
| 420 | __mem_cgroup_move_lists(pc, active); | 371 | mz = page_cgroup_zoneinfo(pc); |
| 421 | spin_unlock_irqrestore(&mz->lru_lock, flags); | 372 | spin_lock_irqsave(&mz->lru_lock, flags); |
| 373 | __mem_cgroup_move_lists(pc, active); | ||
| 374 | spin_unlock_irqrestore(&mz->lru_lock, flags); | ||
| 375 | } | ||
| 376 | unlock_page_cgroup(page); | ||
| 422 | } | 377 | } |
| 423 | 378 | ||
| 424 | /* | 379 | /* |
| @@ -437,6 +392,7 @@ int mem_cgroup_calc_mapped_ratio(struct mem_cgroup *mem) | |||
| 437 | rss = (long)mem_cgroup_read_stat(&mem->stat, MEM_CGROUP_STAT_RSS); | 392 | rss = (long)mem_cgroup_read_stat(&mem->stat, MEM_CGROUP_STAT_RSS); |
| 438 | return (int)((rss * 100L) / total); | 393 | return (int)((rss * 100L) / total); |
| 439 | } | 394 | } |
| 395 | |||
| 440 | /* | 396 | /* |
| 441 | * This function is called from vmscan.c. In page reclaiming loop. balance | 397 | * This function is called from vmscan.c. In page reclaiming loop. balance |
| 442 | * between active and inactive list is calculated. For memory controller | 398 | * between active and inactive list is calculated. For memory controller |
| @@ -500,7 +456,6 @@ long mem_cgroup_calc_reclaim_inactive(struct mem_cgroup *mem, | |||
| 500 | struct mem_cgroup_per_zone *mz = mem_cgroup_zoneinfo(mem, nid, zid); | 456 | struct mem_cgroup_per_zone *mz = mem_cgroup_zoneinfo(mem, nid, zid); |
| 501 | 457 | ||
| 502 | nr_inactive = MEM_CGROUP_ZSTAT(mz, MEM_CGROUP_ZSTAT_INACTIVE); | 458 | nr_inactive = MEM_CGROUP_ZSTAT(mz, MEM_CGROUP_ZSTAT_INACTIVE); |
| 503 | |||
| 504 | return (nr_inactive >> priority); | 459 | return (nr_inactive >> priority); |
| 505 | } | 460 | } |
| 506 | 461 | ||
| @@ -586,26 +541,21 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm, | |||
| 586 | * with it | 541 | * with it |
| 587 | */ | 542 | */ |
| 588 | retry: | 543 | retry: |
| 589 | if (page) { | 544 | lock_page_cgroup(page); |
| 590 | lock_page_cgroup(page); | 545 | pc = page_get_page_cgroup(page); |
| 591 | pc = page_get_page_cgroup(page); | 546 | /* |
| 592 | /* | 547 | * The page_cgroup exists and |
| 593 | * The page_cgroup exists and | 548 | * the page has already been accounted. |
| 594 | * the page has already been accounted. | 549 | */ |
| 595 | */ | 550 | if (pc) { |
| 596 | if (pc) { | 551 | VM_BUG_ON(pc->page != page); |
| 597 | if (unlikely(!atomic_inc_not_zero(&pc->ref_cnt))) { | 552 | VM_BUG_ON(pc->ref_cnt <= 0); |
| 598 | /* this page is under being uncharged ? */ | 553 | |
| 599 | unlock_page_cgroup(page); | 554 | pc->ref_cnt++; |
| 600 | cpu_relax(); | ||
| 601 | goto retry; | ||
| 602 | } else { | ||
| 603 | unlock_page_cgroup(page); | ||
| 604 | goto done; | ||
| 605 | } | ||
| 606 | } | ||
| 607 | unlock_page_cgroup(page); | 555 | unlock_page_cgroup(page); |
| 556 | goto done; | ||
| 608 | } | 557 | } |
| 558 | unlock_page_cgroup(page); | ||
| 609 | 559 | ||
| 610 | pc = kzalloc(sizeof(struct page_cgroup), gfp_mask); | 560 | pc = kzalloc(sizeof(struct page_cgroup), gfp_mask); |
| 611 | if (pc == NULL) | 561 | if (pc == NULL) |
| @@ -623,16 +573,11 @@ retry: | |||
| 623 | rcu_read_lock(); | 573 | rcu_read_lock(); |
| 624 | mem = rcu_dereference(mm->mem_cgroup); | 574 | mem = rcu_dereference(mm->mem_cgroup); |
| 625 | /* | 575 | /* |
| 626 | * For every charge from the cgroup, increment reference | 576 | * For every charge from the cgroup, increment reference count |
| 627 | * count | ||
| 628 | */ | 577 | */ |
| 629 | css_get(&mem->css); | 578 | css_get(&mem->css); |
| 630 | rcu_read_unlock(); | 579 | rcu_read_unlock(); |
| 631 | 580 | ||
| 632 | /* | ||
| 633 | * If we created the page_cgroup, we should free it on exceeding | ||
| 634 | * the cgroup limit. | ||
| 635 | */ | ||
| 636 | while (res_counter_charge(&mem->res, PAGE_SIZE)) { | 581 | while (res_counter_charge(&mem->res, PAGE_SIZE)) { |
| 637 | if (!(gfp_mask & __GFP_WAIT)) | 582 | if (!(gfp_mask & __GFP_WAIT)) |
| 638 | goto out; | 583 | goto out; |
| @@ -641,12 +586,12 @@ retry: | |||
| 641 | continue; | 586 | continue; |
| 642 | 587 | ||
| 643 | /* | 588 | /* |
| 644 | * try_to_free_mem_cgroup_pages() might not give us a full | 589 | * try_to_free_mem_cgroup_pages() might not give us a full |
| 645 | * picture of reclaim. Some pages are reclaimed and might be | 590 | * picture of reclaim. Some pages are reclaimed and might be |
| 646 | * moved to swap cache or just unmapped from the cgroup. | 591 | * moved to swap cache or just unmapped from the cgroup. |
| 647 | * Check the limit again to see if the reclaim reduced the | 592 | * Check the limit again to see if the reclaim reduced the |
| 648 | * current usage of the cgroup before giving up | 593 | * current usage of the cgroup before giving up |
| 649 | */ | 594 | */ |
| 650 | if (res_counter_check_under_limit(&mem->res)) | 595 | if (res_counter_check_under_limit(&mem->res)) |
| 651 | continue; | 596 | continue; |
| 652 | 597 | ||
| @@ -657,14 +602,16 @@ retry: | |||
| 657 | congestion_wait(WRITE, HZ/10); | 602 | congestion_wait(WRITE, HZ/10); |
| 658 | } | 603 | } |
| 659 | 604 | ||
| 660 | atomic_set(&pc->ref_cnt, 1); | 605 | pc->ref_cnt = 1; |
| 661 | pc->mem_cgroup = mem; | 606 | pc->mem_cgroup = mem; |
| 662 | pc->page = page; | 607 | pc->page = page; |
| 663 | pc->flags = PAGE_CGROUP_FLAG_ACTIVE; | 608 | pc->flags = PAGE_CGROUP_FLAG_ACTIVE; |
| 664 | if (ctype == MEM_CGROUP_CHARGE_TYPE_CACHE) | 609 | if (ctype == MEM_CGROUP_CHARGE_TYPE_CACHE) |
| 665 | pc->flags |= PAGE_CGROUP_FLAG_CACHE; | 610 | pc->flags |= PAGE_CGROUP_FLAG_CACHE; |
| 666 | 611 | ||
| 667 | if (!page || page_cgroup_assign_new_page_cgroup(page, pc)) { | 612 | lock_page_cgroup(page); |
| 613 | if (page_get_page_cgroup(page)) { | ||
| 614 | unlock_page_cgroup(page); | ||
| 668 | /* | 615 | /* |
| 669 | * Another charge has been added to this page already. | 616 | * Another charge has been added to this page already. |
| 670 | * We take lock_page_cgroup(page) again and read | 617 | * We take lock_page_cgroup(page) again and read |
| @@ -673,17 +620,16 @@ retry: | |||
| 673 | res_counter_uncharge(&mem->res, PAGE_SIZE); | 620 | res_counter_uncharge(&mem->res, PAGE_SIZE); |
| 674 | css_put(&mem->css); | 621 | css_put(&mem->css); |
| 675 | kfree(pc); | 622 | kfree(pc); |
| 676 | if (!page) | ||
| 677 | goto done; | ||
| 678 | goto retry; | 623 | goto retry; |
| 679 | } | 624 | } |
| 625 | page_assign_page_cgroup(page, pc); | ||
| 680 | 626 | ||
| 681 | mz = page_cgroup_zoneinfo(pc); | 627 | mz = page_cgroup_zoneinfo(pc); |
| 682 | spin_lock_irqsave(&mz->lru_lock, flags); | 628 | spin_lock_irqsave(&mz->lru_lock, flags); |
| 683 | /* Update statistics vector */ | ||
| 684 | __mem_cgroup_add_list(pc); | 629 | __mem_cgroup_add_list(pc); |
| 685 | spin_unlock_irqrestore(&mz->lru_lock, flags); | 630 | spin_unlock_irqrestore(&mz->lru_lock, flags); |
| 686 | 631 | ||
| 632 | unlock_page_cgroup(page); | ||
| 687 | done: | 633 | done: |
| 688 | return 0; | 634 | return 0; |
| 689 | out: | 635 | out: |
| @@ -693,70 +639,61 @@ err: | |||
| 693 | return -ENOMEM; | 639 | return -ENOMEM; |
| 694 | } | 640 | } |
| 695 | 641 | ||
| 696 | int mem_cgroup_charge(struct page *page, struct mm_struct *mm, | 642 | int mem_cgroup_charge(struct page *page, struct mm_struct *mm, gfp_t gfp_mask) |
| 697 | gfp_t gfp_mask) | ||
| 698 | { | 643 | { |
| 699 | return mem_cgroup_charge_common(page, mm, gfp_mask, | 644 | return mem_cgroup_charge_common(page, mm, gfp_mask, |
| 700 | MEM_CGROUP_CHARGE_TYPE_MAPPED); | 645 | MEM_CGROUP_CHARGE_TYPE_MAPPED); |
| 701 | } | 646 | } |
| 702 | 647 | ||
| 703 | /* | ||
| 704 | * See if the cached pages should be charged at all? | ||
| 705 | */ | ||
| 706 | int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm, | 648 | int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm, |
| 707 | gfp_t gfp_mask) | 649 | gfp_t gfp_mask) |
| 708 | { | 650 | { |
| 709 | int ret = 0; | ||
| 710 | if (!mm) | 651 | if (!mm) |
| 711 | mm = &init_mm; | 652 | mm = &init_mm; |
| 712 | 653 | return mem_cgroup_charge_common(page, mm, gfp_mask, | |
| 713 | ret = mem_cgroup_charge_common(page, mm, gfp_mask, | ||
| 714 | MEM_CGROUP_CHARGE_TYPE_CACHE); | 654 | MEM_CGROUP_CHARGE_TYPE_CACHE); |
| 715 | return ret; | ||
| 716 | } | 655 | } |
| 717 | 656 | ||
| 718 | /* | 657 | /* |
| 719 | * Uncharging is always a welcome operation, we never complain, simply | 658 | * Uncharging is always a welcome operation, we never complain, simply |
| 720 | * uncharge. This routine should be called with lock_page_cgroup held | 659 | * uncharge. |
| 721 | */ | 660 | */ |
| 722 | void mem_cgroup_uncharge(struct page_cgroup *pc) | 661 | void mem_cgroup_uncharge_page(struct page *page) |
| 723 | { | 662 | { |
| 663 | struct page_cgroup *pc; | ||
| 724 | struct mem_cgroup *mem; | 664 | struct mem_cgroup *mem; |
| 725 | struct mem_cgroup_per_zone *mz; | 665 | struct mem_cgroup_per_zone *mz; |
| 726 | struct page *page; | ||
| 727 | unsigned long flags; | 666 | unsigned long flags; |
| 728 | 667 | ||
| 729 | /* | 668 | /* |
| 730 | * Check if our page_cgroup is valid | 669 | * Check if our page_cgroup is valid |
| 731 | */ | 670 | */ |
| 671 | lock_page_cgroup(page); | ||
| 672 | pc = page_get_page_cgroup(page); | ||
| 732 | if (!pc) | 673 | if (!pc) |
| 733 | return; | 674 | goto unlock; |
| 734 | 675 | ||
| 735 | if (atomic_dec_and_test(&pc->ref_cnt)) { | 676 | VM_BUG_ON(pc->page != page); |
| 736 | page = pc->page; | 677 | VM_BUG_ON(pc->ref_cnt <= 0); |
| 678 | |||
| 679 | if (--(pc->ref_cnt) == 0) { | ||
| 737 | mz = page_cgroup_zoneinfo(pc); | 680 | mz = page_cgroup_zoneinfo(pc); |
| 738 | /* | 681 | spin_lock_irqsave(&mz->lru_lock, flags); |
| 739 | * get page->cgroup and clear it under lock. | 682 | __mem_cgroup_remove_list(pc); |
| 740 | * force_empty can drop page->cgroup without checking refcnt. | 683 | spin_unlock_irqrestore(&mz->lru_lock, flags); |
| 741 | */ | 684 | |
| 685 | page_assign_page_cgroup(page, NULL); | ||
| 742 | unlock_page_cgroup(page); | 686 | unlock_page_cgroup(page); |
| 743 | if (clear_page_cgroup(page, pc) == pc) { | 687 | |
| 744 | mem = pc->mem_cgroup; | 688 | mem = pc->mem_cgroup; |
| 745 | css_put(&mem->css); | 689 | res_counter_uncharge(&mem->res, PAGE_SIZE); |
| 746 | res_counter_uncharge(&mem->res, PAGE_SIZE); | 690 | css_put(&mem->css); |
| 747 | spin_lock_irqsave(&mz->lru_lock, flags); | 691 | |
| 748 | __mem_cgroup_remove_list(pc); | 692 | kfree(pc); |
| 749 | spin_unlock_irqrestore(&mz->lru_lock, flags); | 693 | return; |
| 750 | kfree(pc); | ||
| 751 | } | ||
| 752 | lock_page_cgroup(page); | ||
| 753 | } | 694 | } |
| 754 | } | ||
| 755 | 695 | ||
| 756 | void mem_cgroup_uncharge_page(struct page *page) | 696 | unlock: |
| 757 | { | ||
| 758 | lock_page_cgroup(page); | ||
| 759 | mem_cgroup_uncharge(page_get_page_cgroup(page)); | ||
| 760 | unlock_page_cgroup(page); | 697 | unlock_page_cgroup(page); |
| 761 | } | 698 | } |
| 762 | 699 | ||
| @@ -764,63 +701,59 @@ void mem_cgroup_uncharge_page(struct page *page) | |||
| 764 | * Returns non-zero if a page (under migration) has valid page_cgroup member. | 701 | * Returns non-zero if a page (under migration) has valid page_cgroup member. |
| 765 | * Refcnt of page_cgroup is incremented. | 702 | * Refcnt of page_cgroup is incremented. |
| 766 | */ | 703 | */ |
| 767 | |||
| 768 | int mem_cgroup_prepare_migration(struct page *page) | 704 | int mem_cgroup_prepare_migration(struct page *page) |
| 769 | { | 705 | { |
| 770 | struct page_cgroup *pc; | 706 | struct page_cgroup *pc; |
| 771 | int ret = 0; | 707 | |
| 772 | lock_page_cgroup(page); | 708 | lock_page_cgroup(page); |
| 773 | pc = page_get_page_cgroup(page); | 709 | pc = page_get_page_cgroup(page); |
| 774 | if (pc && atomic_inc_not_zero(&pc->ref_cnt)) | 710 | if (pc) |
| 775 | ret = 1; | 711 | pc->ref_cnt++; |
| 776 | unlock_page_cgroup(page); | 712 | unlock_page_cgroup(page); |
| 777 | return ret; | 713 | return pc != NULL; |
| 778 | } | 714 | } |
| 779 | 715 | ||
| 780 | void mem_cgroup_end_migration(struct page *page) | 716 | void mem_cgroup_end_migration(struct page *page) |
| 781 | { | 717 | { |
| 782 | struct page_cgroup *pc; | 718 | mem_cgroup_uncharge_page(page); |
| 783 | |||
| 784 | lock_page_cgroup(page); | ||
| 785 | pc = page_get_page_cgroup(page); | ||
| 786 | mem_cgroup_uncharge(pc); | ||
| 787 | unlock_page_cgroup(page); | ||
| 788 | } | 719 | } |
| 720 | |||
| 789 | /* | 721 | /* |
| 790 | * We know both *page* and *newpage* are now not-on-LRU and Pg_locked. | 722 | * We know both *page* and *newpage* are now not-on-LRU and PG_locked. |
| 791 | * And no race with uncharge() routines because page_cgroup for *page* | 723 | * And no race with uncharge() routines because page_cgroup for *page* |
| 792 | * has extra one reference by mem_cgroup_prepare_migration. | 724 | * has extra one reference by mem_cgroup_prepare_migration. |
| 793 | */ | 725 | */ |
| 794 | |||
| 795 | void mem_cgroup_page_migration(struct page *page, struct page *newpage) | 726 | void mem_cgroup_page_migration(struct page *page, struct page *newpage) |
| 796 | { | 727 | { |
| 797 | struct page_cgroup *pc; | 728 | struct page_cgroup *pc; |
| 798 | struct mem_cgroup *mem; | ||
| 799 | unsigned long flags; | ||
| 800 | struct mem_cgroup_per_zone *mz; | 729 | struct mem_cgroup_per_zone *mz; |
| 801 | retry: | 730 | unsigned long flags; |
| 731 | |||
| 732 | lock_page_cgroup(page); | ||
| 802 | pc = page_get_page_cgroup(page); | 733 | pc = page_get_page_cgroup(page); |
| 803 | if (!pc) | 734 | if (!pc) { |
| 735 | unlock_page_cgroup(page); | ||
| 804 | return; | 736 | return; |
| 805 | mem = pc->mem_cgroup; | 737 | } |
| 738 | |||
| 806 | mz = page_cgroup_zoneinfo(pc); | 739 | mz = page_cgroup_zoneinfo(pc); |
| 807 | if (clear_page_cgroup(page, pc) != pc) | ||
| 808 | goto retry; | ||
| 809 | spin_lock_irqsave(&mz->lru_lock, flags); | 740 | spin_lock_irqsave(&mz->lru_lock, flags); |
| 810 | |||
| 811 | __mem_cgroup_remove_list(pc); | 741 | __mem_cgroup_remove_list(pc); |
| 812 | spin_unlock_irqrestore(&mz->lru_lock, flags); | 742 | spin_unlock_irqrestore(&mz->lru_lock, flags); |
| 813 | 743 | ||
| 744 | page_assign_page_cgroup(page, NULL); | ||
| 745 | unlock_page_cgroup(page); | ||
| 746 | |||
| 814 | pc->page = newpage; | 747 | pc->page = newpage; |
| 815 | lock_page_cgroup(newpage); | 748 | lock_page_cgroup(newpage); |
| 816 | page_assign_page_cgroup(newpage, pc); | 749 | page_assign_page_cgroup(newpage, pc); |
| 817 | unlock_page_cgroup(newpage); | ||
| 818 | 750 | ||
| 819 | mz = page_cgroup_zoneinfo(pc); | 751 | mz = page_cgroup_zoneinfo(pc); |
| 820 | spin_lock_irqsave(&mz->lru_lock, flags); | 752 | spin_lock_irqsave(&mz->lru_lock, flags); |
| 821 | __mem_cgroup_add_list(pc); | 753 | __mem_cgroup_add_list(pc); |
| 822 | spin_unlock_irqrestore(&mz->lru_lock, flags); | 754 | spin_unlock_irqrestore(&mz->lru_lock, flags); |
| 823 | return; | 755 | |
| 756 | unlock_page_cgroup(newpage); | ||
| 824 | } | 757 | } |
| 825 | 758 | ||
| 826 | /* | 759 | /* |
| @@ -829,14 +762,13 @@ retry: | |||
| 829 | * *And* this routine doesn't reclaim page itself, just removes page_cgroup. | 762 | * *And* this routine doesn't reclaim page itself, just removes page_cgroup. |
| 830 | */ | 763 | */ |
| 831 | #define FORCE_UNCHARGE_BATCH (128) | 764 | #define FORCE_UNCHARGE_BATCH (128) |
| 832 | static void | 765 | static void mem_cgroup_force_empty_list(struct mem_cgroup *mem, |
| 833 | mem_cgroup_force_empty_list(struct mem_cgroup *mem, | ||
| 834 | struct mem_cgroup_per_zone *mz, | 766 | struct mem_cgroup_per_zone *mz, |
| 835 | int active) | 767 | int active) |
| 836 | { | 768 | { |
| 837 | struct page_cgroup *pc; | 769 | struct page_cgroup *pc; |
| 838 | struct page *page; | 770 | struct page *page; |
| 839 | int count; | 771 | int count = FORCE_UNCHARGE_BATCH; |
| 840 | unsigned long flags; | 772 | unsigned long flags; |
| 841 | struct list_head *list; | 773 | struct list_head *list; |
| 842 | 774 | ||
| @@ -845,46 +777,36 @@ mem_cgroup_force_empty_list(struct mem_cgroup *mem, | |||
| 845 | else | 777 | else |
| 846 | list = &mz->inactive_list; | 778 | list = &mz->inactive_list; |
| 847 | 779 | ||
| 848 | if (list_empty(list)) | ||
| 849 | return; | ||
| 850 | retry: | ||
| 851 | count = FORCE_UNCHARGE_BATCH; | ||
| 852 | spin_lock_irqsave(&mz->lru_lock, flags); | 780 | spin_lock_irqsave(&mz->lru_lock, flags); |
| 853 | 781 | while (!list_empty(list)) { | |
| 854 | while (--count && !list_empty(list)) { | ||
| 855 | pc = list_entry(list->prev, struct page_cgroup, lru); | 782 | pc = list_entry(list->prev, struct page_cgroup, lru); |
| 856 | page = pc->page; | 783 | page = pc->page; |
| 857 | /* Avoid race with charge */ | 784 | get_page(page); |
| 858 | atomic_set(&pc->ref_cnt, 0); | 785 | spin_unlock_irqrestore(&mz->lru_lock, flags); |
| 859 | if (clear_page_cgroup(page, pc) == pc) { | 786 | mem_cgroup_uncharge_page(page); |
| 860 | css_put(&mem->css); | 787 | put_page(page); |
| 861 | res_counter_uncharge(&mem->res, PAGE_SIZE); | 788 | if (--count <= 0) { |
| 862 | __mem_cgroup_remove_list(pc); | 789 | count = FORCE_UNCHARGE_BATCH; |
| 863 | kfree(pc); | 790 | cond_resched(); |
| 864 | } else /* being uncharged ? ...do relax */ | 791 | } |
| 865 | break; | 792 | spin_lock_irqsave(&mz->lru_lock, flags); |
| 866 | } | 793 | } |
| 867 | spin_unlock_irqrestore(&mz->lru_lock, flags); | 794 | spin_unlock_irqrestore(&mz->lru_lock, flags); |
| 868 | if (!list_empty(list)) { | ||
| 869 | cond_resched(); | ||
| 870 | goto retry; | ||
| 871 | } | ||
| 872 | return; | ||
| 873 | } | 795 | } |
| 874 | 796 | ||
| 875 | /* | 797 | /* |
| 876 | * make mem_cgroup's charge to be 0 if there is no task. | 798 | * make mem_cgroup's charge to be 0 if there is no task. |
| 877 | * This enables deleting this mem_cgroup. | 799 | * This enables deleting this mem_cgroup. |
| 878 | */ | 800 | */ |
| 879 | 801 | static int mem_cgroup_force_empty(struct mem_cgroup *mem) | |
| 880 | int mem_cgroup_force_empty(struct mem_cgroup *mem) | ||
| 881 | { | 802 | { |
| 882 | int ret = -EBUSY; | 803 | int ret = -EBUSY; |
| 883 | int node, zid; | 804 | int node, zid; |
| 805 | |||
| 884 | css_get(&mem->css); | 806 | css_get(&mem->css); |
| 885 | /* | 807 | /* |
| 886 | * page reclaim code (kswapd etc..) will move pages between | 808 | * page reclaim code (kswapd etc..) will move pages between |
| 887 | ` * active_list <-> inactive_list while we don't take a lock. | 809 | * active_list <-> inactive_list while we don't take a lock. |
| 888 | * So, we have to do loop here until all lists are empty. | 810 | * So, we have to do loop here until all lists are empty. |
| 889 | */ | 811 | */ |
| 890 | while (mem->res.usage > 0) { | 812 | while (mem->res.usage > 0) { |
| @@ -906,9 +828,7 @@ out: | |||
| 906 | return ret; | 828 | return ret; |
| 907 | } | 829 | } |
| 908 | 830 | ||
| 909 | 831 | static int mem_cgroup_write_strategy(char *buf, unsigned long long *tmp) | |
| 910 | |||
| 911 | int mem_cgroup_write_strategy(char *buf, unsigned long long *tmp) | ||
| 912 | { | 832 | { |
| 913 | *tmp = memparse(buf, &buf); | 833 | *tmp = memparse(buf, &buf); |
| 914 | if (*buf != '\0') | 834 | if (*buf != '\0') |
| @@ -945,8 +865,7 @@ static ssize_t mem_force_empty_write(struct cgroup *cont, | |||
| 945 | size_t nbytes, loff_t *ppos) | 865 | size_t nbytes, loff_t *ppos) |
| 946 | { | 866 | { |
| 947 | struct mem_cgroup *mem = mem_cgroup_from_cont(cont); | 867 | struct mem_cgroup *mem = mem_cgroup_from_cont(cont); |
| 948 | int ret; | 868 | int ret = mem_cgroup_force_empty(mem); |
| 949 | ret = mem_cgroup_force_empty(mem); | ||
| 950 | if (!ret) | 869 | if (!ret) |
| 951 | ret = nbytes; | 870 | ret = nbytes; |
| 952 | return ret; | 871 | return ret; |
| @@ -955,7 +874,6 @@ static ssize_t mem_force_empty_write(struct cgroup *cont, | |||
| 955 | /* | 874 | /* |
| 956 | * Note: This should be removed if cgroup supports write-only file. | 875 | * Note: This should be removed if cgroup supports write-only file. |
| 957 | */ | 876 | */ |
| 958 | |||
| 959 | static ssize_t mem_force_empty_read(struct cgroup *cont, | 877 | static ssize_t mem_force_empty_read(struct cgroup *cont, |
| 960 | struct cftype *cft, | 878 | struct cftype *cft, |
| 961 | struct file *file, char __user *userbuf, | 879 | struct file *file, char __user *userbuf, |
| @@ -964,7 +882,6 @@ static ssize_t mem_force_empty_read(struct cgroup *cont, | |||
| 964 | return -EINVAL; | 882 | return -EINVAL; |
| 965 | } | 883 | } |
| 966 | 884 | ||
| 967 | |||
| 968 | static const struct mem_cgroup_stat_desc { | 885 | static const struct mem_cgroup_stat_desc { |
| 969 | const char *msg; | 886 | const char *msg; |
| 970 | u64 unit; | 887 | u64 unit; |
| @@ -1017,8 +934,6 @@ static int mem_control_stat_open(struct inode *unused, struct file *file) | |||
| 1017 | return single_open(file, mem_control_stat_show, cont); | 934 | return single_open(file, mem_control_stat_show, cont); |
| 1018 | } | 935 | } |
| 1019 | 936 | ||
| 1020 | |||
| 1021 | |||
| 1022 | static struct cftype mem_cgroup_files[] = { | 937 | static struct cftype mem_cgroup_files[] = { |
| 1023 | { | 938 | { |
| 1024 | .name = "usage_in_bytes", | 939 | .name = "usage_in_bytes", |
| @@ -1084,9 +999,6 @@ static void free_mem_cgroup_per_zone_info(struct mem_cgroup *mem, int node) | |||
| 1084 | kfree(mem->info.nodeinfo[node]); | 999 | kfree(mem->info.nodeinfo[node]); |
| 1085 | } | 1000 | } |
| 1086 | 1001 | ||
| 1087 | |||
| 1088 | static struct mem_cgroup init_mem_cgroup; | ||
| 1089 | |||
| 1090 | static struct cgroup_subsys_state * | 1002 | static struct cgroup_subsys_state * |
| 1091 | mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont) | 1003 | mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont) |
| 1092 | { | 1004 | { |
| @@ -1176,7 +1088,6 @@ static void mem_cgroup_move_task(struct cgroup_subsys *ss, | |||
| 1176 | 1088 | ||
| 1177 | out: | 1089 | out: |
| 1178 | mmput(mm); | 1090 | mmput(mm); |
| 1179 | return; | ||
| 1180 | } | 1091 | } |
| 1181 | 1092 | ||
| 1182 | struct cgroup_subsys mem_cgroup_subsys = { | 1093 | struct cgroup_subsys mem_cgroup_subsys = { |
diff --git a/mm/memory.c b/mm/memory.c index ce3c9e4492d8..0d14d1e58a5f 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
| @@ -1711,7 +1711,7 @@ unlock: | |||
| 1711 | } | 1711 | } |
| 1712 | return ret; | 1712 | return ret; |
| 1713 | oom_free_new: | 1713 | oom_free_new: |
| 1714 | __free_page(new_page); | 1714 | page_cache_release(new_page); |
| 1715 | oom: | 1715 | oom: |
| 1716 | if (old_page) | 1716 | if (old_page) |
| 1717 | page_cache_release(old_page); | 1717 | page_cache_release(old_page); |
| @@ -2093,12 +2093,9 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
| 2093 | unlock_page(page); | 2093 | unlock_page(page); |
| 2094 | 2094 | ||
| 2095 | if (write_access) { | 2095 | if (write_access) { |
| 2096 | /* XXX: We could OR the do_wp_page code with this one? */ | 2096 | ret |= do_wp_page(mm, vma, address, page_table, pmd, ptl, pte); |
| 2097 | if (do_wp_page(mm, vma, address, | 2097 | if (ret & VM_FAULT_ERROR) |
| 2098 | page_table, pmd, ptl, pte) & VM_FAULT_OOM) { | 2098 | ret &= VM_FAULT_ERROR; |
| 2099 | mem_cgroup_uncharge_page(page); | ||
| 2100 | ret = VM_FAULT_OOM; | ||
| 2101 | } | ||
| 2102 | goto out; | 2099 | goto out; |
| 2103 | } | 2100 | } |
| 2104 | 2101 | ||
| @@ -2163,7 +2160,7 @@ release: | |||
| 2163 | page_cache_release(page); | 2160 | page_cache_release(page); |
| 2164 | goto unlock; | 2161 | goto unlock; |
| 2165 | oom_free_page: | 2162 | oom_free_page: |
| 2166 | __free_page(page); | 2163 | page_cache_release(page); |
| 2167 | oom: | 2164 | oom: |
| 2168 | return VM_FAULT_OOM; | 2165 | return VM_FAULT_OOM; |
| 2169 | } | 2166 | } |
diff --git a/mm/migrate.c b/mm/migrate.c index a73504ff5ab9..4e0eccca5e26 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
| @@ -153,11 +153,6 @@ static void remove_migration_pte(struct vm_area_struct *vma, | |||
| 153 | return; | 153 | return; |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | if (mem_cgroup_charge(new, mm, GFP_KERNEL)) { | ||
| 157 | pte_unmap(ptep); | ||
| 158 | return; | ||
| 159 | } | ||
| 160 | |||
| 161 | ptl = pte_lockptr(mm, pmd); | 156 | ptl = pte_lockptr(mm, pmd); |
| 162 | spin_lock(ptl); | 157 | spin_lock(ptl); |
| 163 | pte = *ptep; | 158 | pte = *ptep; |
| @@ -169,6 +164,20 @@ static void remove_migration_pte(struct vm_area_struct *vma, | |||
| 169 | if (!is_migration_entry(entry) || migration_entry_to_page(entry) != old) | 164 | if (!is_migration_entry(entry) || migration_entry_to_page(entry) != old) |
| 170 | goto out; | 165 | goto out; |
| 171 | 166 | ||
| 167 | /* | ||
| 168 | * Yes, ignore the return value from a GFP_ATOMIC mem_cgroup_charge. | ||
| 169 | * Failure is not an option here: we're now expected to remove every | ||
| 170 | * migration pte, and will cause crashes otherwise. Normally this | ||
| 171 | * is not an issue: mem_cgroup_prepare_migration bumped up the old | ||
| 172 | * page_cgroup count for safety, that's now attached to the new page, | ||
| 173 | * so this charge should just be another incrementation of the count, | ||
| 174 | * to keep in balance with rmap.c's mem_cgroup_uncharging. But if | ||
| 175 | * there's been a force_empty, those reference counts may no longer | ||
| 176 | * be reliable, and this charge can actually fail: oh well, we don't | ||
| 177 | * make the situation any worse by proceeding as if it had succeeded. | ||
| 178 | */ | ||
| 179 | mem_cgroup_charge(new, mm, GFP_ATOMIC); | ||
| 180 | |||
| 172 | get_page(new); | 181 | get_page(new); |
| 173 | pte = pte_mkold(mk_pte(new, vma->vm_page_prot)); | 182 | pte = pte_mkold(mk_pte(new, vma->vm_page_prot)); |
| 174 | if (is_write_migration_entry(entry)) | 183 | if (is_write_migration_entry(entry)) |
diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 4194b9db0104..44b2da11bf43 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c | |||
| @@ -412,7 +412,7 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order, | |||
| 412 | return oom_kill_task(p); | 412 | return oom_kill_task(p); |
| 413 | } | 413 | } |
| 414 | 414 | ||
| 415 | #ifdef CONFIG_CGROUP_MEM_CONT | 415 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR |
| 416 | void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask) | 416 | void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask) |
| 417 | { | 417 | { |
| 418 | unsigned long points = 0; | 418 | unsigned long points = 0; |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 8896e874a67d..402a504f1228 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/swap.h> | 19 | #include <linux/swap.h> |
| 20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
| 21 | #include <linux/pagemap.h> | 21 | #include <linux/pagemap.h> |
| 22 | #include <linux/jiffies.h> | ||
| 22 | #include <linux/bootmem.h> | 23 | #include <linux/bootmem.h> |
| 23 | #include <linux/compiler.h> | 24 | #include <linux/compiler.h> |
| 24 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
| @@ -221,13 +222,19 @@ static inline int bad_range(struct zone *zone, struct page *page) | |||
| 221 | 222 | ||
| 222 | static void bad_page(struct page *page) | 223 | static void bad_page(struct page *page) |
| 223 | { | 224 | { |
| 224 | printk(KERN_EMERG "Bad page state in process '%s'\n" | 225 | void *pc = page_get_page_cgroup(page); |
| 225 | KERN_EMERG "page:%p flags:0x%0*lx mapping:%p mapcount:%d count:%d\n" | 226 | |
| 226 | KERN_EMERG "Trying to fix it up, but a reboot is needed\n" | 227 | printk(KERN_EMERG "Bad page state in process '%s'\n" KERN_EMERG |
| 227 | KERN_EMERG "Backtrace:\n", | 228 | "page:%p flags:0x%0*lx mapping:%p mapcount:%d count:%d\n", |
| 228 | current->comm, page, (int)(2*sizeof(unsigned long)), | 229 | current->comm, page, (int)(2*sizeof(unsigned long)), |
| 229 | (unsigned long)page->flags, page->mapping, | 230 | (unsigned long)page->flags, page->mapping, |
| 230 | page_mapcount(page), page_count(page)); | 231 | page_mapcount(page), page_count(page)); |
| 232 | if (pc) { | ||
| 233 | printk(KERN_EMERG "cgroup:%p\n", pc); | ||
| 234 | page_reset_bad_cgroup(page); | ||
| 235 | } | ||
| 236 | printk(KERN_EMERG "Trying to fix it up, but a reboot is needed\n" | ||
| 237 | KERN_EMERG "Backtrace:\n"); | ||
| 231 | dump_stack(); | 238 | dump_stack(); |
| 232 | page->flags &= ~(1 << PG_lru | | 239 | page->flags &= ~(1 << PG_lru | |
| 233 | 1 << PG_private | | 240 | 1 << PG_private | |
| @@ -453,6 +460,7 @@ static inline int free_pages_check(struct page *page) | |||
| 453 | { | 460 | { |
| 454 | if (unlikely(page_mapcount(page) | | 461 | if (unlikely(page_mapcount(page) | |
| 455 | (page->mapping != NULL) | | 462 | (page->mapping != NULL) | |
| 463 | (page_get_page_cgroup(page) != NULL) | | ||
| 456 | (page_count(page) != 0) | | 464 | (page_count(page) != 0) | |
| 457 | (page->flags & ( | 465 | (page->flags & ( |
| 458 | 1 << PG_lru | | 466 | 1 << PG_lru | |
| @@ -602,6 +610,7 @@ static int prep_new_page(struct page *page, int order, gfp_t gfp_flags) | |||
| 602 | { | 610 | { |
| 603 | if (unlikely(page_mapcount(page) | | 611 | if (unlikely(page_mapcount(page) | |
| 604 | (page->mapping != NULL) | | 612 | (page->mapping != NULL) | |
| 613 | (page_get_page_cgroup(page) != NULL) | | ||
| 605 | (page_count(page) != 0) | | 614 | (page_count(page) != 0) | |
| 606 | (page->flags & ( | 615 | (page->flags & ( |
| 607 | 1 << PG_lru | | 616 | 1 << PG_lru | |
| @@ -988,7 +997,6 @@ static void free_hot_cold_page(struct page *page, int cold) | |||
| 988 | 997 | ||
| 989 | if (!PageHighMem(page)) | 998 | if (!PageHighMem(page)) |
| 990 | debug_check_no_locks_freed(page_address(page), PAGE_SIZE); | 999 | debug_check_no_locks_freed(page_address(page), PAGE_SIZE); |
| 991 | VM_BUG_ON(page_get_page_cgroup(page)); | ||
| 992 | arch_free_page(page, 0); | 1000 | arch_free_page(page, 0); |
| 993 | kernel_map_pages(page, 1, 0); | 1001 | kernel_map_pages(page, 1, 0); |
| 994 | 1002 | ||
| @@ -1276,7 +1284,7 @@ static nodemask_t *zlc_setup(struct zonelist *zonelist, int alloc_flags) | |||
| 1276 | if (!zlc) | 1284 | if (!zlc) |
| 1277 | return NULL; | 1285 | return NULL; |
| 1278 | 1286 | ||
| 1279 | if (jiffies - zlc->last_full_zap > 1 * HZ) { | 1287 | if (time_after(jiffies, zlc->last_full_zap + HZ)) { |
| 1280 | bitmap_zero(zlc->fullzones, MAX_ZONES_PER_ZONELIST); | 1288 | bitmap_zero(zlc->fullzones, MAX_ZONES_PER_ZONELIST); |
| 1281 | zlc->last_full_zap = jiffies; | 1289 | zlc->last_full_zap = jiffies; |
| 1282 | } | 1290 | } |
| @@ -2527,7 +2535,6 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone, | |||
| 2527 | set_page_links(page, zone, nid, pfn); | 2535 | set_page_links(page, zone, nid, pfn); |
| 2528 | init_page_count(page); | 2536 | init_page_count(page); |
| 2529 | reset_page_mapcount(page); | 2537 | reset_page_mapcount(page); |
| 2530 | page_assign_page_cgroup(page, NULL); | ||
| 2531 | SetPageReserved(page); | 2538 | SetPageReserved(page); |
| 2532 | 2539 | ||
| 2533 | /* | 2540 | /* |
| @@ -321,7 +321,7 @@ static int page_referenced_anon(struct page *page, | |||
| 321 | * counting on behalf of references from different | 321 | * counting on behalf of references from different |
| 322 | * cgroups | 322 | * cgroups |
| 323 | */ | 323 | */ |
| 324 | if (mem_cont && !vm_match_cgroup(vma->vm_mm, mem_cont)) | 324 | if (mem_cont && !mm_match_cgroup(vma->vm_mm, mem_cont)) |
| 325 | continue; | 325 | continue; |
| 326 | referenced += page_referenced_one(page, vma, &mapcount); | 326 | referenced += page_referenced_one(page, vma, &mapcount); |
| 327 | if (!mapcount) | 327 | if (!mapcount) |
| @@ -382,7 +382,7 @@ static int page_referenced_file(struct page *page, | |||
| 382 | * counting on behalf of references from different | 382 | * counting on behalf of references from different |
| 383 | * cgroups | 383 | * cgroups |
| 384 | */ | 384 | */ |
| 385 | if (mem_cont && !vm_match_cgroup(vma->vm_mm, mem_cont)) | 385 | if (mem_cont && !mm_match_cgroup(vma->vm_mm, mem_cont)) |
| 386 | continue; | 386 | continue; |
| 387 | if ((vma->vm_flags & (VM_LOCKED|VM_MAYSHARE)) | 387 | if ((vma->vm_flags & (VM_LOCKED|VM_MAYSHARE)) |
| 388 | == (VM_LOCKED|VM_MAYSHARE)) { | 388 | == (VM_LOCKED|VM_MAYSHARE)) { |
diff --git a/mm/shmem.c b/mm/shmem.c index 90b576cbc06e..3372bc579e89 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
| @@ -1370,14 +1370,17 @@ repeat: | |||
| 1370 | shmem_swp_unmap(entry); | 1370 | shmem_swp_unmap(entry); |
| 1371 | spin_unlock(&info->lock); | 1371 | spin_unlock(&info->lock); |
| 1372 | unlock_page(swappage); | 1372 | unlock_page(swappage); |
| 1373 | page_cache_release(swappage); | ||
| 1374 | if (error == -ENOMEM) { | 1373 | if (error == -ENOMEM) { |
| 1375 | /* allow reclaim from this memory cgroup */ | 1374 | /* allow reclaim from this memory cgroup */ |
| 1376 | error = mem_cgroup_cache_charge(NULL, | 1375 | error = mem_cgroup_cache_charge(swappage, |
| 1377 | current->mm, gfp & ~__GFP_HIGHMEM); | 1376 | current->mm, gfp & ~__GFP_HIGHMEM); |
| 1378 | if (error) | 1377 | if (error) { |
| 1378 | page_cache_release(swappage); | ||
| 1379 | goto failed; | 1379 | goto failed; |
| 1380 | } | ||
| 1381 | mem_cgroup_uncharge_page(swappage); | ||
| 1380 | } | 1382 | } |
| 1383 | page_cache_release(swappage); | ||
| 1381 | goto repeat; | 1384 | goto repeat; |
| 1382 | } | 1385 | } |
| 1383 | } else if (sgp == SGP_READ && !filepage) { | 1386 | } else if (sgp == SGP_READ && !filepage) { |
| @@ -176,7 +176,7 @@ void activate_page(struct page *page) | |||
| 176 | SetPageActive(page); | 176 | SetPageActive(page); |
| 177 | add_page_to_active_list(zone, page); | 177 | add_page_to_active_list(zone, page); |
| 178 | __count_vm_event(PGACTIVATE); | 178 | __count_vm_event(PGACTIVATE); |
| 179 | mem_cgroup_move_lists(page_get_page_cgroup(page), true); | 179 | mem_cgroup_move_lists(page, true); |
| 180 | } | 180 | } |
| 181 | spin_unlock_irq(&zone->lru_lock); | 181 | spin_unlock_irq(&zone->lru_lock); |
| 182 | } | 182 | } |
diff --git a/mm/vmscan.c b/mm/vmscan.c index a26dabd62fed..45711585684e 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
| @@ -126,7 +126,7 @@ long vm_total_pages; /* The total number of pages which the VM controls */ | |||
| 126 | static LIST_HEAD(shrinker_list); | 126 | static LIST_HEAD(shrinker_list); |
| 127 | static DECLARE_RWSEM(shrinker_rwsem); | 127 | static DECLARE_RWSEM(shrinker_rwsem); |
| 128 | 128 | ||
| 129 | #ifdef CONFIG_CGROUP_MEM_CONT | 129 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR |
| 130 | #define scan_global_lru(sc) (!(sc)->mem_cgroup) | 130 | #define scan_global_lru(sc) (!(sc)->mem_cgroup) |
| 131 | #else | 131 | #else |
| 132 | #define scan_global_lru(sc) (1) | 132 | #define scan_global_lru(sc) (1) |
| @@ -1128,7 +1128,7 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone, | |||
| 1128 | ClearPageActive(page); | 1128 | ClearPageActive(page); |
| 1129 | 1129 | ||
| 1130 | list_move(&page->lru, &zone->inactive_list); | 1130 | list_move(&page->lru, &zone->inactive_list); |
| 1131 | mem_cgroup_move_lists(page_get_page_cgroup(page), false); | 1131 | mem_cgroup_move_lists(page, false); |
| 1132 | pgmoved++; | 1132 | pgmoved++; |
| 1133 | if (!pagevec_add(&pvec, page)) { | 1133 | if (!pagevec_add(&pvec, page)) { |
| 1134 | __mod_zone_page_state(zone, NR_INACTIVE, pgmoved); | 1134 | __mod_zone_page_state(zone, NR_INACTIVE, pgmoved); |
| @@ -1156,8 +1156,9 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone, | |||
| 1156 | VM_BUG_ON(PageLRU(page)); | 1156 | VM_BUG_ON(PageLRU(page)); |
| 1157 | SetPageLRU(page); | 1157 | SetPageLRU(page); |
| 1158 | VM_BUG_ON(!PageActive(page)); | 1158 | VM_BUG_ON(!PageActive(page)); |
| 1159 | |||
| 1159 | list_move(&page->lru, &zone->active_list); | 1160 | list_move(&page->lru, &zone->active_list); |
| 1160 | mem_cgroup_move_lists(page_get_page_cgroup(page), true); | 1161 | mem_cgroup_move_lists(page, true); |
| 1161 | pgmoved++; | 1162 | pgmoved++; |
| 1162 | if (!pagevec_add(&pvec, page)) { | 1163 | if (!pagevec_add(&pvec, page)) { |
| 1163 | __mod_zone_page_state(zone, NR_ACTIVE, pgmoved); | 1164 | __mod_zone_page_state(zone, NR_ACTIVE, pgmoved); |
| @@ -1427,7 +1428,7 @@ unsigned long try_to_free_pages(struct zone **zones, int order, gfp_t gfp_mask) | |||
| 1427 | return do_try_to_free_pages(zones, gfp_mask, &sc); | 1428 | return do_try_to_free_pages(zones, gfp_mask, &sc); |
| 1428 | } | 1429 | } |
| 1429 | 1430 | ||
| 1430 | #ifdef CONFIG_CGROUP_MEM_CONT | 1431 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR |
| 1431 | 1432 | ||
| 1432 | unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem_cont, | 1433 | unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem_cont, |
| 1433 | gfp_t gfp_mask) | 1434 | gfp_t gfp_mask) |
diff --git a/samples/Kconfig b/samples/Kconfig index 74d97cc24787..e1fb471cc501 100644 --- a/samples/Kconfig +++ b/samples/Kconfig | |||
| @@ -22,5 +22,16 @@ config SAMPLE_KOBJECT | |||
| 22 | 22 | ||
| 23 | If in doubt, say "N" here. | 23 | If in doubt, say "N" here. |
| 24 | 24 | ||
| 25 | config SAMPLE_KPROBES | ||
| 26 | tristate "Build kprobes examples -- loadable modules only" | ||
| 27 | depends on KPROBES && m | ||
| 28 | help | ||
| 29 | This build several kprobes example modules. | ||
| 30 | |||
| 31 | config SAMPLE_KRETPROBES | ||
| 32 | tristate "Build kretprobes example -- loadable modules only" | ||
| 33 | default m | ||
| 34 | depends on SAMPLE_KPROBES && KRETPROBES | ||
| 35 | |||
| 25 | endif # SAMPLES | 36 | endif # SAMPLES |
| 26 | 37 | ||
diff --git a/samples/Makefile b/samples/Makefile index 8652d0f268ad..2e02575f7794 100644 --- a/samples/Makefile +++ b/samples/Makefile | |||
| @@ -1,3 +1,3 @@ | |||
| 1 | # Makefile for Linux samples code | 1 | # Makefile for Linux samples code |
| 2 | 2 | ||
| 3 | obj-$(CONFIG_SAMPLES) += markers/ kobject/ | 3 | obj-$(CONFIG_SAMPLES) += markers/ kobject/ kprobes/ |
diff --git a/samples/kprobes/Makefile b/samples/kprobes/Makefile new file mode 100644 index 000000000000..68739bc4fc6a --- /dev/null +++ b/samples/kprobes/Makefile | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | # builds the kprobes example kernel modules; | ||
| 2 | # then to use one (as root): insmod <module_name.ko> | ||
| 3 | |||
| 4 | obj-$(CONFIG_SAMPLE_KPROBES) += kprobe_example.o jprobe_example.o | ||
| 5 | obj-$(CONFIG_SAMPLE_KRETPROBES) += kretprobe_example.o | ||
diff --git a/samples/kprobes/jprobe_example.c b/samples/kprobes/jprobe_example.c new file mode 100644 index 000000000000..b7541355b92b --- /dev/null +++ b/samples/kprobes/jprobe_example.c | |||
| @@ -0,0 +1,68 @@ | |||
| 1 | /* | ||
| 2 | * Here's a sample kernel module showing the use of jprobes to dump | ||
| 3 | * the arguments of do_fork(). | ||
| 4 | * | ||
| 5 | * For more information on theory of operation of jprobes, see | ||
| 6 | * Documentation/kprobes.txt | ||
| 7 | * | ||
| 8 | * Build and insert the kernel module as done in the kprobe example. | ||
| 9 | * You will see the trace data in /var/log/messages and on the | ||
| 10 | * console whenever do_fork() is invoked to create a new process. | ||
| 11 | * (Some messages may be suppressed if syslogd is configured to | ||
| 12 | * eliminate duplicate messages.) | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/kprobes.h> | ||
| 18 | |||
| 19 | /* | ||
| 20 | * Jumper probe for do_fork. | ||
| 21 | * Mirror principle enables access to arguments of the probed routine | ||
| 22 | * from the probe handler. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* Proxy routine having the same arguments as actual do_fork() routine */ | ||
| 26 | static long jdo_fork(unsigned long clone_flags, unsigned long stack_start, | ||
| 27 | struct pt_regs *regs, unsigned long stack_size, | ||
| 28 | int __user *parent_tidptr, int __user *child_tidptr) | ||
| 29 | { | ||
| 30 | printk(KERN_INFO "jprobe: clone_flags = 0x%lx, stack_size = 0x%lx," | ||
| 31 | " regs = 0x%p\n", | ||
| 32 | clone_flags, stack_size, regs); | ||
| 33 | |||
| 34 | /* Always end with a call to jprobe_return(). */ | ||
| 35 | jprobe_return(); | ||
| 36 | return 0; | ||
| 37 | } | ||
| 38 | |||
| 39 | static struct jprobe my_jprobe = { | ||
| 40 | .entry = jdo_fork, | ||
| 41 | .kp = { | ||
| 42 | .symbol_name = "do_fork", | ||
| 43 | }, | ||
| 44 | }; | ||
| 45 | |||
| 46 | static int __init jprobe_init(void) | ||
| 47 | { | ||
| 48 | int ret; | ||
| 49 | |||
| 50 | ret = register_jprobe(&my_jprobe); | ||
| 51 | if (ret < 0) { | ||
| 52 | printk(KERN_INFO "register_jprobe failed, returned %d\n", ret); | ||
| 53 | return -1; | ||
| 54 | } | ||
| 55 | printk(KERN_INFO "Planted jprobe at %p, handler addr %p\n", | ||
| 56 | my_jprobe.kp.addr, my_jprobe.entry); | ||
| 57 | return 0; | ||
| 58 | } | ||
| 59 | |||
| 60 | static void __exit jprobe_exit(void) | ||
| 61 | { | ||
| 62 | unregister_jprobe(&my_jprobe); | ||
| 63 | printk(KERN_INFO "jprobe at %p unregistered\n", my_jprobe.kp.addr); | ||
| 64 | } | ||
| 65 | |||
| 66 | module_init(jprobe_init) | ||
| 67 | module_exit(jprobe_exit) | ||
| 68 | MODULE_LICENSE("GPL"); | ||
diff --git a/samples/kprobes/kprobe_example.c b/samples/kprobes/kprobe_example.c new file mode 100644 index 000000000000..a681998a871c --- /dev/null +++ b/samples/kprobes/kprobe_example.c | |||
| @@ -0,0 +1,91 @@ | |||
| 1 | /* | ||
| 2 | * NOTE: This example is works on x86 and powerpc. | ||
| 3 | * Here's a sample kernel module showing the use of kprobes to dump a | ||
| 4 | * stack trace and selected registers when do_fork() is called. | ||
| 5 | * | ||
| 6 | * For more information on theory of operation of kprobes, see | ||
| 7 | * Documentation/kprobes.txt | ||
| 8 | * | ||
| 9 | * You will see the trace data in /var/log/messages and on the console | ||
| 10 | * whenever do_fork() is invoked to create a new process. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/kprobes.h> | ||
| 16 | |||
| 17 | /* For each probe you need to allocate a kprobe structure */ | ||
| 18 | static struct kprobe kp = { | ||
| 19 | .symbol_name = "do_fork", | ||
| 20 | }; | ||
| 21 | |||
| 22 | /* kprobe pre_handler: called just before the probed instruction is executed */ | ||
| 23 | static int handler_pre(struct kprobe *p, struct pt_regs *regs) | ||
| 24 | { | ||
| 25 | #ifdef CONFIG_X86 | ||
| 26 | printk(KERN_INFO "pre_handler: p->addr = 0x%p, ip = %lx," | ||
| 27 | " flags = 0x%lx\n", | ||
| 28 | p->addr, regs->ip, regs->flags); | ||
| 29 | #endif | ||
| 30 | #ifdef CONFIG_PPC | ||
| 31 | printk(KERN_INFO "pre_handler: p->addr = 0x%p, nip = 0x%lx," | ||
| 32 | " msr = 0x%lx\n", | ||
| 33 | p->addr, regs->nip, regs->msr); | ||
| 34 | #endif | ||
| 35 | |||
| 36 | /* A dump_stack() here will give a stack backtrace */ | ||
| 37 | return 0; | ||
| 38 | } | ||
| 39 | |||
| 40 | /* kprobe post_handler: called after the probed instruction is executed */ | ||
| 41 | static void handler_post(struct kprobe *p, struct pt_regs *regs, | ||
| 42 | unsigned long flags) | ||
| 43 | { | ||
| 44 | #ifdef CONFIG_X86 | ||
| 45 | printk(KERN_INFO "post_handler: p->addr = 0x%p, flags = 0x%lx\n", | ||
| 46 | p->addr, regs->flags); | ||
| 47 | #endif | ||
| 48 | #ifdef CONFIG_PPC | ||
| 49 | printk(KERN_INFO "post_handler: p->addr = 0x%p, msr = 0x%lx\n", | ||
| 50 | p->addr, regs->msr); | ||
| 51 | #endif | ||
| 52 | } | ||
| 53 | |||
| 54 | /* | ||
| 55 | * fault_handler: this is called if an exception is generated for any | ||
| 56 | * instruction within the pre- or post-handler, or when Kprobes | ||
| 57 | * single-steps the probed instruction. | ||
| 58 | */ | ||
| 59 | static int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr) | ||
| 60 | { | ||
| 61 | printk(KERN_INFO "fault_handler: p->addr = 0x%p, trap #%dn", | ||
| 62 | p->addr, trapnr); | ||
| 63 | /* Return 0 because we don't handle the fault. */ | ||
| 64 | return 0; | ||
| 65 | } | ||
| 66 | |||
| 67 | static int __init kprobe_init(void) | ||
| 68 | { | ||
| 69 | int ret; | ||
| 70 | kp.pre_handler = handler_pre; | ||
| 71 | kp.post_handler = handler_post; | ||
| 72 | kp.fault_handler = handler_fault; | ||
| 73 | |||
| 74 | ret = register_kprobe(&kp); | ||
| 75 | if (ret < 0) { | ||
| 76 | printk(KERN_INFO "register_kprobe failed, returned %d\n", ret); | ||
| 77 | return ret; | ||
| 78 | } | ||
| 79 | printk(KERN_INFO "Planted kprobe at %p\n", kp.addr); | ||
| 80 | return 0; | ||
| 81 | } | ||
| 82 | |||
| 83 | static void __exit kprobe_exit(void) | ||
| 84 | { | ||
| 85 | unregister_kprobe(&kp); | ||
| 86 | printk(KERN_INFO "kprobe at %p unregistered\n", kp.addr); | ||
| 87 | } | ||
| 88 | |||
| 89 | module_init(kprobe_init) | ||
| 90 | module_exit(kprobe_exit) | ||
| 91 | MODULE_LICENSE("GPL"); | ||
diff --git a/samples/kprobes/kretprobe_example.c b/samples/kprobes/kretprobe_example.c new file mode 100644 index 000000000000..4e764b317d61 --- /dev/null +++ b/samples/kprobes/kretprobe_example.c | |||
| @@ -0,0 +1,106 @@ | |||
| 1 | /* | ||
| 2 | * kretprobe_example.c | ||
| 3 | * | ||
| 4 | * Here's a sample kernel module showing the use of return probes to | ||
| 5 | * report the return value and total time taken for probed function | ||
| 6 | * to run. | ||
| 7 | * | ||
| 8 | * usage: insmod kretprobe_example.ko func=<func_name> | ||
| 9 | * | ||
| 10 | * If no func_name is specified, do_fork is instrumented | ||
| 11 | * | ||
| 12 | * For more information on theory of operation of kretprobes, see | ||
| 13 | * Documentation/kprobes.txt | ||
| 14 | * | ||
| 15 | * Build and insert the kernel module as done in the kprobe example. | ||
| 16 | * You will see the trace data in /var/log/messages and on the console | ||
| 17 | * whenever the probed function returns. (Some messages may be suppressed | ||
| 18 | * if syslogd is configured to eliminate duplicate messages.) | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/kernel.h> | ||
| 22 | #include <linux/module.h> | ||
| 23 | #include <linux/kprobes.h> | ||
| 24 | #include <linux/ktime.h> | ||
| 25 | #include <linux/limits.h> | ||
| 26 | |||
| 27 | static char func_name[NAME_MAX] = "do_fork"; | ||
| 28 | module_param_string(func, func_name, NAME_MAX, S_IRUGO); | ||
| 29 | MODULE_PARM_DESC(func, "Function to kretprobe; this module will report the" | ||
| 30 | " function's execution time"); | ||
| 31 | |||
| 32 | /* per-instance private data */ | ||
| 33 | struct my_data { | ||
| 34 | ktime_t entry_stamp; | ||
| 35 | }; | ||
| 36 | |||
| 37 | /* Here we use the entry_hanlder to timestamp function entry */ | ||
| 38 | static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs) | ||
| 39 | { | ||
| 40 | struct my_data *data; | ||
| 41 | |||
| 42 | if (!current->mm) | ||
| 43 | return 1; /* Skip kernel threads */ | ||
| 44 | |||
| 45 | data = (struct my_data *)ri->data; | ||
| 46 | data->entry_stamp = ktime_get(); | ||
| 47 | return 0; | ||
| 48 | } | ||
| 49 | |||
| 50 | /* | ||
| 51 | * Return-probe handler: Log the return value and duration. Duration may turn | ||
| 52 | * out to be zero consistently, depending upon the granularity of time | ||
| 53 | * accounting on the platform. | ||
| 54 | */ | ||
| 55 | static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs) | ||
| 56 | { | ||
| 57 | int retval = regs_return_value(regs); | ||
| 58 | struct my_data *data = (struct my_data *)ri->data; | ||
| 59 | s64 delta; | ||
| 60 | ktime_t now; | ||
| 61 | |||
| 62 | now = ktime_get(); | ||
| 63 | delta = ktime_to_ns(ktime_sub(now, data->entry_stamp)); | ||
| 64 | printk(KERN_INFO "%s returned %d and took %lld ns to execute\n", | ||
| 65 | func_name, retval, (long long)delta); | ||
| 66 | return 0; | ||
| 67 | } | ||
| 68 | |||
| 69 | static struct kretprobe my_kretprobe = { | ||
| 70 | .handler = ret_handler, | ||
| 71 | .entry_handler = entry_handler, | ||
| 72 | .data_size = sizeof(struct my_data), | ||
| 73 | /* Probe up to 20 instances concurrently. */ | ||
| 74 | .maxactive = 20, | ||
| 75 | }; | ||
| 76 | |||
| 77 | static int __init kretprobe_init(void) | ||
| 78 | { | ||
| 79 | int ret; | ||
| 80 | |||
| 81 | my_kretprobe.kp.symbol_name = func_name; | ||
| 82 | ret = register_kretprobe(&my_kretprobe); | ||
| 83 | if (ret < 0) { | ||
| 84 | printk(KERN_INFO "register_kretprobe failed, returned %d\n", | ||
| 85 | ret); | ||
| 86 | return -1; | ||
| 87 | } | ||
| 88 | printk(KERN_INFO "Planted return probe at %s: %p\n", | ||
| 89 | my_kretprobe.kp.symbol_name, my_kretprobe.kp.addr); | ||
| 90 | return 0; | ||
| 91 | } | ||
| 92 | |||
| 93 | static void __exit kretprobe_exit(void) | ||
| 94 | { | ||
| 95 | unregister_kretprobe(&my_kretprobe); | ||
| 96 | printk(KERN_INFO "kretprobe at %p unregistered\n", | ||
| 97 | my_kretprobe.kp.addr); | ||
| 98 | |||
| 99 | /* nmissed > 0 suggests that maxactive was set too low. */ | ||
| 100 | printk(KERN_INFO "Missed probing %d instances of %s\n", | ||
| 101 | my_kretprobe.nmissed, my_kretprobe.kp.symbol_name); | ||
| 102 | } | ||
| 103 | |||
| 104 | module_init(kretprobe_init) | ||
| 105 | module_exit(kretprobe_exit) | ||
| 106 | MODULE_LICENSE("GPL"); | ||
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 2086a856400a..2a7cef9726e4 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl | |||
| @@ -9,7 +9,7 @@ use strict; | |||
| 9 | my $P = $0; | 9 | my $P = $0; |
| 10 | $P =~ s@.*/@@g; | 10 | $P =~ s@.*/@@g; |
| 11 | 11 | ||
| 12 | my $V = '0.14'; | 12 | my $V = '0.15'; |
| 13 | 13 | ||
| 14 | use Getopt::Long qw(:config no_auto_abbrev); | 14 | use Getopt::Long qw(:config no_auto_abbrev); |
| 15 | 15 | ||
| @@ -105,8 +105,7 @@ our $Sparse = qr{ | |||
| 105 | __iomem| | 105 | __iomem| |
| 106 | __must_check| | 106 | __must_check| |
| 107 | __init_refok| | 107 | __init_refok| |
| 108 | __kprobes| | 108 | __kprobes |
| 109 | fastcall | ||
| 110 | }x; | 109 | }x; |
| 111 | our $Attribute = qr{ | 110 | our $Attribute = qr{ |
| 112 | const| | 111 | const| |
| @@ -158,7 +157,10 @@ sub build_types { | |||
| 158 | \b | 157 | \b |
| 159 | (?:const\s+)? | 158 | (?:const\s+)? |
| 160 | (?:unsigned\s+)? | 159 | (?:unsigned\s+)? |
| 161 | $all | 160 | (?: |
| 161 | $all| | ||
| 162 | (?:typeof|__typeof__)\s*\(\s*\**\s*$Ident\s*\) | ||
| 163 | ) | ||
| 162 | (?:\s+$Sparse|\s+const)* | 164 | (?:\s+$Sparse|\s+const)* |
| 163 | \b | 165 | \b |
| 164 | }x; | 166 | }x; |
| @@ -362,6 +364,7 @@ sub ctx_statement_block { | |||
| 362 | 364 | ||
| 363 | my $type = ''; | 365 | my $type = ''; |
| 364 | my $level = 0; | 366 | my $level = 0; |
| 367 | my $p; | ||
| 365 | my $c; | 368 | my $c; |
| 366 | my $len = 0; | 369 | my $len = 0; |
| 367 | 370 | ||
| @@ -386,6 +389,7 @@ sub ctx_statement_block { | |||
| 386 | last; | 389 | last; |
| 387 | } | 390 | } |
| 388 | } | 391 | } |
| 392 | $p = $c; | ||
| 389 | $c = substr($blk, $off, 1); | 393 | $c = substr($blk, $off, 1); |
| 390 | $remainder = substr($blk, $off); | 394 | $remainder = substr($blk, $off); |
| 391 | 395 | ||
| @@ -397,8 +401,9 @@ sub ctx_statement_block { | |||
| 397 | } | 401 | } |
| 398 | 402 | ||
| 399 | # An else is really a conditional as long as its not else if | 403 | # An else is really a conditional as long as its not else if |
| 400 | if ($level == 0 && $remainder =~ /(\s+else)(?:\s|{)/ && | 404 | if ($level == 0 && (!defined($p) || $p =~ /(?:\s|\})/) && |
| 401 | $remainder !~ /\s+else\s+if\b/) { | 405 | $remainder =~ /(else)(?:\s|{)/ && |
| 406 | $remainder !~ /else\s+if\b/) { | ||
| 402 | $coff = $off + length($1); | 407 | $coff = $off + length($1); |
| 403 | } | 408 | } |
| 404 | 409 | ||
| @@ -445,21 +450,73 @@ sub ctx_statement_block { | |||
| 445 | $line, $remain + 1, $off - $loff + 1, $level); | 450 | $line, $remain + 1, $off - $loff + 1, $level); |
| 446 | } | 451 | } |
| 447 | 452 | ||
| 453 | sub statement_lines { | ||
| 454 | my ($stmt) = @_; | ||
| 455 | |||
| 456 | # Strip the diff line prefixes and rip blank lines at start and end. | ||
| 457 | $stmt =~ s/(^|\n)./$1/g; | ||
| 458 | $stmt =~ s/^\s*//; | ||
| 459 | $stmt =~ s/\s*$//; | ||
| 460 | |||
| 461 | my @stmt_lines = ($stmt =~ /\n/g); | ||
| 462 | |||
| 463 | return $#stmt_lines + 2; | ||
| 464 | } | ||
| 465 | |||
| 466 | sub statement_rawlines { | ||
| 467 | my ($stmt) = @_; | ||
| 468 | |||
| 469 | my @stmt_lines = ($stmt =~ /\n/g); | ||
| 470 | |||
| 471 | return $#stmt_lines + 2; | ||
| 472 | } | ||
| 473 | |||
| 474 | sub statement_block_size { | ||
| 475 | my ($stmt) = @_; | ||
| 476 | |||
| 477 | $stmt =~ s/(^|\n)./$1/g; | ||
| 478 | $stmt =~ s/^\s*{//; | ||
| 479 | $stmt =~ s/}\s*$//; | ||
| 480 | $stmt =~ s/^\s*//; | ||
| 481 | $stmt =~ s/\s*$//; | ||
| 482 | |||
| 483 | my @stmt_lines = ($stmt =~ /\n/g); | ||
| 484 | my @stmt_statements = ($stmt =~ /;/g); | ||
| 485 | |||
| 486 | my $stmt_lines = $#stmt_lines + 2; | ||
| 487 | my $stmt_statements = $#stmt_statements + 1; | ||
| 488 | |||
| 489 | if ($stmt_lines > $stmt_statements) { | ||
| 490 | return $stmt_lines; | ||
| 491 | } else { | ||
| 492 | return $stmt_statements; | ||
| 493 | } | ||
| 494 | } | ||
| 495 | |||
| 448 | sub ctx_statement_full { | 496 | sub ctx_statement_full { |
| 449 | my ($linenr, $remain, $off) = @_; | 497 | my ($linenr, $remain, $off) = @_; |
| 450 | my ($statement, $condition, $level); | 498 | my ($statement, $condition, $level); |
| 451 | 499 | ||
| 452 | my (@chunks); | 500 | my (@chunks); |
| 453 | 501 | ||
| 502 | # Grab the first conditional/block pair. | ||
| 454 | ($statement, $condition, $linenr, $remain, $off, $level) = | 503 | ($statement, $condition, $linenr, $remain, $off, $level) = |
| 455 | ctx_statement_block($linenr, $remain, $off); | 504 | ctx_statement_block($linenr, $remain, $off); |
| 456 | #print "F: c<$condition> s<$statement>\n"; | 505 | #print "F: c<$condition> s<$statement>\n"; |
| 506 | push(@chunks, [ $condition, $statement ]); | ||
| 507 | if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { | ||
| 508 | return ($level, $linenr, @chunks); | ||
| 509 | } | ||
| 510 | |||
| 511 | # Pull in the following conditional/block pairs and see if they | ||
| 512 | # could continue the statement. | ||
| 457 | for (;;) { | 513 | for (;;) { |
| 458 | push(@chunks, [ $condition, $statement ]); | ||
| 459 | last if (!($remain > 0 && $condition =~ /^.\s*(?:if|else|do)/)); | ||
| 460 | ($statement, $condition, $linenr, $remain, $off, $level) = | 514 | ($statement, $condition, $linenr, $remain, $off, $level) = |
| 461 | ctx_statement_block($linenr, $remain, $off); | 515 | ctx_statement_block($linenr, $remain, $off); |
| 462 | #print "C: c<$condition> s<$statement>\n"; | 516 | #print "C: c<$condition> s<$statement> remain<$remain>\n"; |
| 517 | last if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:else|do)\b/s)); | ||
| 518 | #print "C: push\n"; | ||
| 519 | push(@chunks, [ $condition, $statement ]); | ||
| 463 | } | 520 | } |
| 464 | 521 | ||
| 465 | return ($level, $linenr, @chunks); | 522 | return ($level, $linenr, @chunks); |
| @@ -593,13 +650,13 @@ sub cat_vet { | |||
| 593 | } | 650 | } |
| 594 | 651 | ||
| 595 | my $av_preprocessor = 0; | 652 | my $av_preprocessor = 0; |
| 596 | my $av_paren = 0; | 653 | my $av_pending; |
| 597 | my @av_paren_type; | 654 | my @av_paren_type; |
| 598 | 655 | ||
| 599 | sub annotate_reset { | 656 | sub annotate_reset { |
| 600 | $av_preprocessor = 0; | 657 | $av_preprocessor = 0; |
| 601 | $av_paren = 0; | 658 | $av_pending = '_'; |
| 602 | @av_paren_type = (); | 659 | @av_paren_type = ('E'); |
| 603 | } | 660 | } |
| 604 | 661 | ||
| 605 | sub annotate_values { | 662 | sub annotate_values { |
| @@ -611,12 +668,13 @@ sub annotate_values { | |||
| 611 | print "$stream\n" if ($dbg_values > 1); | 668 | print "$stream\n" if ($dbg_values > 1); |
| 612 | 669 | ||
| 613 | while (length($cur)) { | 670 | while (length($cur)) { |
| 614 | print " <$type> " if ($dbg_values > 1); | 671 | print " <" . join('', @av_paren_type) . |
| 672 | "> <$type> " if ($dbg_values > 1); | ||
| 615 | if ($cur =~ /^(\s+)/o) { | 673 | if ($cur =~ /^(\s+)/o) { |
| 616 | print "WS($1)\n" if ($dbg_values > 1); | 674 | print "WS($1)\n" if ($dbg_values > 1); |
| 617 | if ($1 =~ /\n/ && $av_preprocessor) { | 675 | if ($1 =~ /\n/ && $av_preprocessor) { |
| 676 | $type = pop(@av_paren_type); | ||
| 618 | $av_preprocessor = 0; | 677 | $av_preprocessor = 0; |
| 619 | $type = 'N'; | ||
| 620 | } | 678 | } |
| 621 | 679 | ||
| 622 | } elsif ($cur =~ /^($Type)/) { | 680 | } elsif ($cur =~ /^($Type)/) { |
| @@ -626,11 +684,33 @@ sub annotate_values { | |||
| 626 | } elsif ($cur =~ /^(#\s*define\s*$Ident)(\(?)/o) { | 684 | } elsif ($cur =~ /^(#\s*define\s*$Ident)(\(?)/o) { |
| 627 | print "DEFINE($1)\n" if ($dbg_values > 1); | 685 | print "DEFINE($1)\n" if ($dbg_values > 1); |
| 628 | $av_preprocessor = 1; | 686 | $av_preprocessor = 1; |
| 629 | $av_paren_type[$av_paren] = 'N'; | 687 | $av_pending = 'N'; |
| 630 | 688 | ||
| 631 | } elsif ($cur =~ /^(#\s*(?:ifdef|ifndef|if|else|elif|endif))/o) { | 689 | } elsif ($cur =~ /^(#\s*(?:ifdef|ifndef|if))/o) { |
| 632 | print "PRE($1)\n" if ($dbg_values > 1); | 690 | print "PRE_START($1)\n" if ($dbg_values > 1); |
| 633 | $av_preprocessor = 1; | 691 | $av_preprocessor = 1; |
| 692 | |||
| 693 | push(@av_paren_type, $type); | ||
| 694 | push(@av_paren_type, $type); | ||
| 695 | $type = 'N'; | ||
| 696 | |||
| 697 | } elsif ($cur =~ /^(#\s*(?:else|elif))/o) { | ||
| 698 | print "PRE_RESTART($1)\n" if ($dbg_values > 1); | ||
| 699 | $av_preprocessor = 1; | ||
| 700 | |||
| 701 | push(@av_paren_type, $av_paren_type[$#av_paren_type]); | ||
| 702 | |||
| 703 | $type = 'N'; | ||
| 704 | |||
| 705 | } elsif ($cur =~ /^(#\s*(?:endif))/o) { | ||
| 706 | print "PRE_END($1)\n" if ($dbg_values > 1); | ||
| 707 | |||
| 708 | $av_preprocessor = 1; | ||
| 709 | |||
| 710 | # Assume all arms of the conditional end as this | ||
| 711 | # one does, and continue as if the #endif was not here. | ||
| 712 | pop(@av_paren_type); | ||
| 713 | push(@av_paren_type, $type); | ||
| 634 | $type = 'N'; | 714 | $type = 'N'; |
| 635 | 715 | ||
| 636 | } elsif ($cur =~ /^(\\\n)/o) { | 716 | } elsif ($cur =~ /^(\\\n)/o) { |
| @@ -639,13 +719,13 @@ sub annotate_values { | |||
| 639 | } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { | 719 | } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { |
| 640 | print "SIZEOF($1)\n" if ($dbg_values > 1); | 720 | print "SIZEOF($1)\n" if ($dbg_values > 1); |
| 641 | if (defined $2) { | 721 | if (defined $2) { |
| 642 | $av_paren_type[$av_paren] = 'V'; | 722 | $av_pending = 'V'; |
| 643 | } | 723 | } |
| 644 | $type = 'N'; | 724 | $type = 'N'; |
| 645 | 725 | ||
| 646 | } elsif ($cur =~ /^(if|while|typeof|__typeof__|for)\b/o) { | 726 | } elsif ($cur =~ /^(if|while|typeof|__typeof__|for)\b/o) { |
| 647 | print "COND($1)\n" if ($dbg_values > 1); | 727 | print "COND($1)\n" if ($dbg_values > 1); |
| 648 | $av_paren_type[$av_paren] = 'N'; | 728 | $av_pending = 'N'; |
| 649 | $type = 'N'; | 729 | $type = 'N'; |
| 650 | 730 | ||
| 651 | } elsif ($cur =~/^(return|case|else)/o) { | 731 | } elsif ($cur =~/^(return|case|else)/o) { |
| @@ -654,14 +734,14 @@ sub annotate_values { | |||
| 654 | 734 | ||
| 655 | } elsif ($cur =~ /^(\()/o) { | 735 | } elsif ($cur =~ /^(\()/o) { |
| 656 | print "PAREN('$1')\n" if ($dbg_values > 1); | 736 | print "PAREN('$1')\n" if ($dbg_values > 1); |
| 657 | $av_paren++; | 737 | push(@av_paren_type, $av_pending); |
| 738 | $av_pending = '_'; | ||
| 658 | $type = 'N'; | 739 | $type = 'N'; |
| 659 | 740 | ||
| 660 | } elsif ($cur =~ /^(\))/o) { | 741 | } elsif ($cur =~ /^(\))/o) { |
| 661 | $av_paren-- if ($av_paren > 0); | 742 | my $new_type = pop(@av_paren_type); |
| 662 | if (defined $av_paren_type[$av_paren]) { | 743 | if ($new_type ne '_') { |
| 663 | $type = $av_paren_type[$av_paren]; | 744 | $type = $new_type; |
| 664 | undef $av_paren_type[$av_paren]; | ||
| 665 | print "PAREN('$1') -> $type\n" | 745 | print "PAREN('$1') -> $type\n" |
| 666 | if ($dbg_values > 1); | 746 | if ($dbg_values > 1); |
| 667 | } else { | 747 | } else { |
| @@ -670,7 +750,7 @@ sub annotate_values { | |||
| 670 | 750 | ||
| 671 | } elsif ($cur =~ /^($Ident)\(/o) { | 751 | } elsif ($cur =~ /^($Ident)\(/o) { |
| 672 | print "FUNC($1)\n" if ($dbg_values > 1); | 752 | print "FUNC($1)\n" if ($dbg_values > 1); |
| 673 | $av_paren_type[$av_paren] = 'V'; | 753 | $av_pending = 'V'; |
| 674 | 754 | ||
| 675 | } elsif ($cur =~ /^($Ident|$Constant)/o) { | 755 | } elsif ($cur =~ /^($Ident|$Constant)/o) { |
| 676 | print "IDENT($1)\n" if ($dbg_values > 1); | 756 | print "IDENT($1)\n" if ($dbg_values > 1); |
| @@ -680,11 +760,11 @@ sub annotate_values { | |||
| 680 | print "ASSIGN($1)\n" if ($dbg_values > 1); | 760 | print "ASSIGN($1)\n" if ($dbg_values > 1); |
| 681 | $type = 'N'; | 761 | $type = 'N'; |
| 682 | 762 | ||
| 683 | } elsif ($cur =~/^(;)/) { | 763 | } elsif ($cur =~/^(;|{|})/) { |
| 684 | print "END($1)\n" if ($dbg_values > 1); | 764 | print "END($1)\n" if ($dbg_values > 1); |
| 685 | $type = 'E'; | 765 | $type = 'E'; |
| 686 | 766 | ||
| 687 | } elsif ($cur =~ /^(;|{|}|\?|:|\[)/o) { | 767 | } elsif ($cur =~ /^(;|\?|:|\[)/o) { |
| 688 | print "CLOSE($1)\n" if ($dbg_values > 1); | 768 | print "CLOSE($1)\n" if ($dbg_values > 1); |
| 689 | $type = 'N'; | 769 | $type = 'N'; |
| 690 | 770 | ||
| @@ -988,7 +1068,7 @@ sub process { | |||
| 988 | } | 1068 | } |
| 989 | 1069 | ||
| 990 | # check for RCS/CVS revision markers | 1070 | # check for RCS/CVS revision markers |
| 991 | if ($rawline =~ /\$(Revision|Log|Id)(?:\$|)/) { | 1071 | if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { |
| 992 | WARN("CVS style keyword markers, these will _not_ be updated\n". $herecurr); | 1072 | WARN("CVS style keyword markers, these will _not_ be updated\n". $herecurr); |
| 993 | } | 1073 | } |
| 994 | 1074 | ||
| @@ -999,41 +1079,44 @@ sub process { | |||
| 999 | 1079 | ||
| 1000 | # Check for potential 'bare' types | 1080 | # Check for potential 'bare' types |
| 1001 | if ($realcnt) { | 1081 | if ($realcnt) { |
| 1082 | my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); | ||
| 1083 | $s =~ s/\n./ /g; | ||
| 1084 | $s =~ s/{.*$//; | ||
| 1085 | |||
| 1002 | # Ignore goto labels. | 1086 | # Ignore goto labels. |
| 1003 | if ($line =~ /$Ident:\*$/) { | 1087 | if ($s =~ /$Ident:\*$/) { |
| 1004 | 1088 | ||
| 1005 | # Ignore functions being called | 1089 | # Ignore functions being called |
| 1006 | } elsif ($line =~ /^.\s*$Ident\s*\(/) { | 1090 | } elsif ($s =~ /^.\s*$Ident\s*\(/) { |
| 1007 | 1091 | ||
| 1008 | # definitions in global scope can only start with types | 1092 | # definitions in global scope can only start with types |
| 1009 | } elsif ($line =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b/) { | 1093 | } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b/) { |
| 1010 | possible($1, $line); | 1094 | possible($1, $s); |
| 1011 | 1095 | ||
| 1012 | # declarations always start with types | 1096 | # declarations always start with types |
| 1013 | } elsif ($prev_values eq 'E' && $line =~ /^.\s*(?:$Storage\s+)?(?:const\s+)?($Ident)\b(:?\s+$Sparse)?\s*\**\s*$Ident\s*(?:;|=|,)/) { | 1097 | } elsif ($prev_values eq 'E' && $s =~ /^.\s*(?:$Storage\s+)?(?:const\s+)?($Ident)\b(:?\s+$Sparse)?\s*\**\s*$Ident\s*(?:;|=|,)/) { |
| 1014 | possible($1); | 1098 | possible($1, $s); |
| 1015 | } | 1099 | } |
| 1016 | 1100 | ||
| 1017 | # any (foo ... *) is a pointer cast, and foo is a type | 1101 | # any (foo ... *) is a pointer cast, and foo is a type |
| 1018 | while ($line =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/g) { | 1102 | while ($s =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/g) { |
| 1019 | possible($1, $line); | 1103 | possible($1, $s); |
| 1020 | } | 1104 | } |
| 1021 | 1105 | ||
| 1022 | # Check for any sort of function declaration. | 1106 | # Check for any sort of function declaration. |
| 1023 | # int foo(something bar, other baz); | 1107 | # int foo(something bar, other baz); |
| 1024 | # void (*store_gdt)(x86_descr_ptr *); | 1108 | # void (*store_gdt)(x86_descr_ptr *); |
| 1025 | if ($prev_values eq 'E' && $line =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/) { | 1109 | if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/) { |
| 1026 | my ($name_len) = length($1); | 1110 | my ($name_len) = length($1); |
| 1027 | my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, $name_len); | ||
| 1028 | my $ctx = join("\n", @ctx); | ||
| 1029 | 1111 | ||
| 1030 | $ctx =~ s/\n.//; | 1112 | my $ctx = $s; |
| 1031 | substr($ctx, 0, $name_len + 1) = ''; | 1113 | substr($ctx, 0, $name_len + 1) = ''; |
| 1032 | $ctx =~ s/\)[^\)]*$//; | 1114 | $ctx =~ s/\)[^\)]*$//; |
| 1115 | |||
| 1033 | for my $arg (split(/\s*,\s*/, $ctx)) { | 1116 | for my $arg (split(/\s*,\s*/, $ctx)) { |
| 1034 | if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/ || $arg =~ /^($Ident)$/) { | 1117 | if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/ || $arg =~ /^($Ident)$/) { |
| 1035 | 1118 | ||
| 1036 | possible($1, $line); | 1119 | possible($1, $s); |
| 1037 | } | 1120 | } |
| 1038 | } | 1121 | } |
| 1039 | } | 1122 | } |
| @@ -1100,8 +1183,8 @@ sub process { | |||
| 1100 | $curr_values = $prev_values . $curr_values; | 1183 | $curr_values = $prev_values . $curr_values; |
| 1101 | if ($dbg_values) { | 1184 | if ($dbg_values) { |
| 1102 | my $outline = $opline; $outline =~ s/\t/ /g; | 1185 | my $outline = $opline; $outline =~ s/\t/ /g; |
| 1103 | warn "--> .$outline\n"; | 1186 | print "$linenr > .$outline\n"; |
| 1104 | warn "--> $curr_values\n"; | 1187 | print "$linenr > $curr_values\n"; |
| 1105 | } | 1188 | } |
| 1106 | $prev_values = substr($curr_values, -1); | 1189 | $prev_values = substr($curr_values, -1); |
| 1107 | 1190 | ||
| @@ -1148,7 +1231,9 @@ sub process { | |||
| 1148 | if (($prevline !~ /^}/) && | 1231 | if (($prevline !~ /^}/) && |
| 1149 | ($prevline !~ /^\+}/) && | 1232 | ($prevline !~ /^\+}/) && |
| 1150 | ($prevline !~ /^ }/) && | 1233 | ($prevline !~ /^ }/) && |
| 1151 | ($prevline !~ /\b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=)/)) { | 1234 | ($prevline !~ /^.DECLARE_$Ident\(\Q$name\E\)/) && |
| 1235 | ($prevline !~ /^.LIST_HEAD\(\Q$name\E\)/) && | ||
| 1236 | ($prevline !~ /\b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=|\[)/)) { | ||
| 1152 | WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); | 1237 | WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); |
| 1153 | } | 1238 | } |
| 1154 | } | 1239 | } |
| @@ -1266,7 +1351,7 @@ sub process { | |||
| 1266 | =>|->|<<|>>|<|>|=|!|~| | 1351 | =>|->|<<|>>|<|>|=|!|~| |
| 1267 | &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|% | 1352 | &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|% |
| 1268 | }x; | 1353 | }x; |
| 1269 | my @elements = split(/($;+|$ops|;)/, $opline); | 1354 | my @elements = split(/($ops|;)/, $opline); |
| 1270 | my $off = 0; | 1355 | my $off = 0; |
| 1271 | 1356 | ||
| 1272 | my $blank = copy_spacing($opline); | 1357 | my $blank = copy_spacing($opline); |
| @@ -1277,6 +1362,7 @@ sub process { | |||
| 1277 | my $a = ''; | 1362 | my $a = ''; |
| 1278 | $a = 'V' if ($elements[$n] ne ''); | 1363 | $a = 'V' if ($elements[$n] ne ''); |
| 1279 | $a = 'W' if ($elements[$n] =~ /\s$/); | 1364 | $a = 'W' if ($elements[$n] =~ /\s$/); |
| 1365 | $a = 'C' if ($elements[$n] =~ /$;$/); | ||
| 1280 | $a = 'B' if ($elements[$n] =~ /(\[|\()$/); | 1366 | $a = 'B' if ($elements[$n] =~ /(\[|\()$/); |
| 1281 | $a = 'O' if ($elements[$n] eq ''); | 1367 | $a = 'O' if ($elements[$n] eq ''); |
| 1282 | $a = 'E' if ($elements[$n] eq '' && $n == 0); | 1368 | $a = 'E' if ($elements[$n] eq '' && $n == 0); |
| @@ -1287,6 +1373,7 @@ sub process { | |||
| 1287 | if (defined $elements[$n + 2]) { | 1373 | if (defined $elements[$n + 2]) { |
| 1288 | $c = 'V' if ($elements[$n + 2] ne ''); | 1374 | $c = 'V' if ($elements[$n + 2] ne ''); |
| 1289 | $c = 'W' if ($elements[$n + 2] =~ /^\s/); | 1375 | $c = 'W' if ($elements[$n + 2] =~ /^\s/); |
| 1376 | $c = 'C' if ($elements[$n + 2] =~ /^$;/); | ||
| 1290 | $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); | 1377 | $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); |
| 1291 | $c = 'O' if ($elements[$n + 2] eq ''); | 1378 | $c = 'O' if ($elements[$n + 2] eq ''); |
| 1292 | $c = 'E' if ($elements[$n + 2] =~ /\s*\\$/); | 1379 | $c = 'E' if ($elements[$n + 2] =~ /\s*\\$/); |
| @@ -1330,13 +1417,13 @@ sub process { | |||
| 1330 | if ($op_type ne 'V' && | 1417 | if ($op_type ne 'V' && |
| 1331 | $ca =~ /\s$/ && $cc =~ /^\s*,/) { | 1418 | $ca =~ /\s$/ && $cc =~ /^\s*,/) { |
| 1332 | 1419 | ||
| 1333 | # Ignore comments | 1420 | # # Ignore comments |
| 1334 | } elsif ($op =~ /^$;+$/) { | 1421 | # } elsif ($op =~ /^$;+$/) { |
| 1335 | 1422 | ||
| 1336 | # ; should have either the end of line or a space or \ after it | 1423 | # ; should have either the end of line or a space or \ after it |
| 1337 | } elsif ($op eq ';') { | 1424 | } elsif ($op eq ';') { |
| 1338 | if ($ctx !~ /.x[WEB]/ && $cc !~ /^\\/ && | 1425 | if ($ctx !~ /.x[WEBC]/ && |
| 1339 | $cc !~ /^;/) { | 1426 | $cc !~ /^\\/ && $cc !~ /^;/) { |
| 1340 | ERROR("need space after that '$op' $at\n" . $hereptr); | 1427 | ERROR("need space after that '$op' $at\n" . $hereptr); |
| 1341 | } | 1428 | } |
| 1342 | 1429 | ||
| @@ -1351,7 +1438,7 @@ sub process { | |||
| 1351 | 1438 | ||
| 1352 | # , must have a space on the right. | 1439 | # , must have a space on the right. |
| 1353 | } elsif ($op eq ',') { | 1440 | } elsif ($op eq ',') { |
| 1354 | if ($ctx !~ /.xW|.xE/ && $cc !~ /^}/) { | 1441 | if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { |
| 1355 | ERROR("need space after that '$op' $at\n" . $hereptr); | 1442 | ERROR("need space after that '$op' $at\n" . $hereptr); |
| 1356 | } | 1443 | } |
| 1357 | 1444 | ||
| @@ -1364,7 +1451,7 @@ sub process { | |||
| 1364 | # unary operator, or a cast | 1451 | # unary operator, or a cast |
| 1365 | } elsif ($op eq '!' || $op eq '~' || | 1452 | } elsif ($op eq '!' || $op eq '~' || |
| 1366 | ($is_unary && ($op eq '*' || $op eq '-' || $op eq '&'))) { | 1453 | ($is_unary && ($op eq '*' || $op eq '-' || $op eq '&'))) { |
| 1367 | if ($ctx !~ /[WEB]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { | 1454 | if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { |
| 1368 | ERROR("need space before that '$op' $at\n" . $hereptr); | 1455 | ERROR("need space before that '$op' $at\n" . $hereptr); |
| 1369 | } | 1456 | } |
| 1370 | if ($ctx =~ /.xW/) { | 1457 | if ($ctx =~ /.xW/) { |
| @@ -1373,7 +1460,7 @@ sub process { | |||
| 1373 | 1460 | ||
| 1374 | # unary ++ and unary -- are allowed no space on one side. | 1461 | # unary ++ and unary -- are allowed no space on one side. |
| 1375 | } elsif ($op eq '++' or $op eq '--') { | 1462 | } elsif ($op eq '++' or $op eq '--') { |
| 1376 | if ($ctx !~ /[WOB]x[^W]/ && $ctx !~ /[^W]x[WOBE]/) { | 1463 | if ($ctx !~ /[WOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { |
| 1377 | ERROR("need space one side of that '$op' $at\n" . $hereptr); | 1464 | ERROR("need space one side of that '$op' $at\n" . $hereptr); |
| 1378 | } | 1465 | } |
| 1379 | if ($ctx =~ /WxB/ || ($ctx =~ /Wx./ && $cc =~ /^;/)) { | 1466 | if ($ctx =~ /WxB/ || ($ctx =~ /Wx./ && $cc =~ /^;/)) { |
| @@ -1387,13 +1474,13 @@ sub process { | |||
| 1387 | $op eq '*' or $op eq '/' or | 1474 | $op eq '*' or $op eq '/' or |
| 1388 | $op eq '%') | 1475 | $op eq '%') |
| 1389 | { | 1476 | { |
| 1390 | if ($ctx !~ /VxV|WxW|VxE|WxE|VxO/) { | 1477 | if ($ctx !~ /VxV|WxW|VxE|WxE|VxO|Cx.|.xC/) { |
| 1391 | ERROR("need consistent spacing around '$op' $at\n" . | 1478 | ERROR("need consistent spacing around '$op' $at\n" . |
| 1392 | $hereptr); | 1479 | $hereptr); |
| 1393 | } | 1480 | } |
| 1394 | 1481 | ||
| 1395 | # All the others need spaces both sides. | 1482 | # All the others need spaces both sides. |
| 1396 | } elsif ($ctx !~ /[EW]x[WE]/) { | 1483 | } elsif ($ctx !~ /[EWC]x[CWE]/) { |
| 1397 | # Ignore email addresses <foo@bar> | 1484 | # Ignore email addresses <foo@bar> |
| 1398 | if (!($op eq '<' && $cb =~ /$;\S+\@\S+>/) && | 1485 | if (!($op eq '<' && $cb =~ /$;\S+\@\S+>/) && |
| 1399 | !($op eq '>' && $cb =~ /<\S+\@\S+$;/)) { | 1486 | !($op eq '>' && $cb =~ /<\S+\@\S+$;/)) { |
| @@ -1551,7 +1638,7 @@ sub process { | |||
| 1551 | 1638 | ||
| 1552 | # multi-statement macros should be enclosed in a do while loop, grab the | 1639 | # multi-statement macros should be enclosed in a do while loop, grab the |
| 1553 | # first statement and ensure its the whole macro if its not enclosed | 1640 | # first statement and ensure its the whole macro if its not enclosed |
| 1554 | # in a known goot container | 1641 | # in a known good container |
| 1555 | if ($prevline =~ /\#define.*\\/ && | 1642 | if ($prevline =~ /\#define.*\\/ && |
| 1556 | $prevline !~/(?:do\s+{|\(\{|\{)/ && | 1643 | $prevline !~/(?:do\s+{|\(\{|\{)/ && |
| 1557 | $line !~ /(?:do\s+{|\(\{|\{)/ && | 1644 | $line !~ /(?:do\s+{|\(\{|\{)/ && |
| @@ -1599,84 +1686,95 @@ sub process { | |||
| 1599 | # check for redundant bracing round if etc | 1686 | # check for redundant bracing round if etc |
| 1600 | if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { | 1687 | if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { |
| 1601 | my ($level, $endln, @chunks) = | 1688 | my ($level, $endln, @chunks) = |
| 1602 | ctx_statement_full($linenr, $realcnt, 0); | 1689 | ctx_statement_full($linenr, $realcnt, 1); |
| 1603 | #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; | 1690 | #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; |
| 1604 | if ($#chunks > 1 && $level == 0) { | 1691 | #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; |
| 1692 | if ($#chunks > 0 && $level == 0) { | ||
| 1605 | my $allowed = 0; | 1693 | my $allowed = 0; |
| 1606 | my $seen = 0; | 1694 | my $seen = 0; |
| 1695 | my $herectx = $here . "\n";; | ||
| 1696 | my $ln = $linenr - 1; | ||
| 1607 | for my $chunk (@chunks) { | 1697 | for my $chunk (@chunks) { |
| 1608 | my ($cond, $block) = @{$chunk}; | 1698 | my ($cond, $block) = @{$chunk}; |
| 1609 | 1699 | ||
| 1700 | $herectx .= "$rawlines[$ln]\n[...]\n"; | ||
| 1701 | $ln += statement_rawlines($block) - 1; | ||
| 1702 | |||
| 1610 | substr($block, 0, length($cond)) = ''; | 1703 | substr($block, 0, length($cond)) = ''; |
| 1611 | 1704 | ||
| 1612 | $seen++ if ($block =~ /^\s*{/); | 1705 | $seen++ if ($block =~ /^\s*{/); |
| 1613 | 1706 | ||
| 1614 | $block =~ s/(^|\n)./$1/g; | 1707 | #print "cond<$cond> block<$block> allowed<$allowed>\n"; |
| 1615 | $block =~ s/^\s*{//; | 1708 | if (statement_lines($cond) > 1) { |
| 1616 | $block =~ s/}\s*$//; | 1709 | #print "APW: ALLOWED: cond<$cond>\n"; |
| 1617 | $block =~ s/^\s*//; | ||
| 1618 | $block =~ s/\s*$//; | ||
| 1619 | |||
| 1620 | my @lines = ($block =~ /\n/g); | ||
| 1621 | my @statements = ($block =~ /;/g); | ||
| 1622 | |||
| 1623 | #print "cond<$cond> block<$block> lines<" . scalar(@lines) . "> statements<" . scalar(@statements) . "> seen<$seen> allowed<$allowed>\n"; | ||
| 1624 | if (scalar(@lines) != 0) { | ||
| 1625 | $allowed = 1; | 1710 | $allowed = 1; |
| 1626 | } | 1711 | } |
| 1627 | if ($block =~/\b(?:if|for|while)\b/) { | 1712 | if ($block =~/\b(?:if|for|while)\b/) { |
| 1713 | #print "APW: ALLOWED: block<$block>\n"; | ||
| 1628 | $allowed = 1; | 1714 | $allowed = 1; |
| 1629 | } | 1715 | } |
| 1630 | if (scalar(@statements) > 1) { | 1716 | if (statement_block_size($block) > 1) { |
| 1717 | #print "APW: ALLOWED: lines block<$block>\n"; | ||
| 1631 | $allowed = 1; | 1718 | $allowed = 1; |
| 1632 | } | 1719 | } |
| 1633 | } | 1720 | } |
| 1634 | if ($seen && !$allowed) { | 1721 | if ($seen && !$allowed) { |
| 1635 | WARN("braces {} are not necessary for any arm of this statement\n" . $herecurr); | 1722 | WARN("braces {} are not necessary for any arm of this statement\n" . $herectx); |
| 1636 | $suppress_ifbraces = $endln; | ||
| 1637 | } | 1723 | } |
| 1724 | # Either way we have looked over this whole | ||
| 1725 | # statement and said what needs to be said. | ||
| 1726 | $suppress_ifbraces = $endln; | ||
| 1638 | } | 1727 | } |
| 1639 | } | 1728 | } |
| 1640 | if ($linenr > $suppress_ifbraces && | 1729 | if ($linenr > $suppress_ifbraces && |
| 1641 | $line =~ /\b(if|while|for|else)\b/) { | 1730 | $line =~ /\b(if|while|for|else)\b/) { |
| 1642 | # Locate the end of the opening statement. | 1731 | my ($level, $endln, @chunks) = |
| 1643 | my @control = ctx_statement($linenr, $realcnt, 0); | 1732 | ctx_statement_full($linenr, $realcnt, $-[0]); |
| 1644 | my $nr = $linenr + (scalar(@control) - 1); | 1733 | |
| 1645 | my $cnt = $realcnt - (scalar(@control) - 1); | 1734 | my $allowed = 0; |
| 1646 | 1735 | ||
| 1647 | my $off = $realcnt - $cnt; | 1736 | # Check the pre-context. |
| 1648 | #print "$off: line<$line>end<" . $lines[$nr - 1] . ">\n"; | 1737 | if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { |
| 1649 | 1738 | #print "APW: ALLOWED: pre<$1>\n"; | |
| 1650 | # If this is is a braced statement group check it | 1739 | $allowed = 1; |
| 1651 | if ($lines[$nr - 1] =~ /{\s*$/) { | 1740 | } |
| 1652 | my ($lvl, @block) = ctx_block_level($nr, $cnt); | 1741 | # Check the condition. |
| 1653 | 1742 | my ($cond, $block) = @{$chunks[0]}; | |
| 1654 | my $stmt = join("\n", @block); | 1743 | if (defined $cond) { |
| 1655 | # Drop the diff line leader. | 1744 | substr($block, 0, length($cond)) = ''; |
| 1656 | $stmt =~ s/\n./\n/g; | 1745 | } |
| 1657 | # Drop the code outside the block. | 1746 | if (statement_lines($cond) > 1) { |
| 1658 | $stmt =~ s/(^[^{]*){\s*//; | 1747 | #print "APW: ALLOWED: cond<$cond>\n"; |
| 1659 | my $before = $1; | 1748 | $allowed = 1; |
| 1660 | $stmt =~ s/\s*}([^}]*$)//; | 1749 | } |
| 1661 | my $after = $1; | 1750 | if ($block =~/\b(?:if|for|while)\b/) { |
| 1662 | 1751 | #print "APW: ALLOWED: block<$block>\n"; | |
| 1663 | #print "block<" . join(' ', @block) . "><" . scalar(@block) . ">\n"; | 1752 | $allowed = 1; |
| 1664 | #print "before<$before> stmt<$stmt> after<$after>\n\n"; | 1753 | } |
| 1665 | 1754 | if (statement_block_size($block) > 1) { | |
| 1666 | # Count the newlines, if there is only one | 1755 | #print "APW: ALLOWED: lines block<$block>\n"; |
| 1667 | # then the block should not have {}'s. | 1756 | $allowed = 1; |
| 1668 | my @lines = ($stmt =~ /\n/g); | 1757 | } |
| 1669 | my @statements = ($stmt =~ /;/g); | 1758 | # Check the post-context. |
| 1670 | #print "lines<" . scalar(@lines) . ">\n"; | 1759 | if (defined $chunks[1]) { |
| 1671 | #print "statements<" . scalar(@statements) . ">\n"; | 1760 | my ($cond, $block) = @{$chunks[1]}; |
| 1672 | if ($lvl == 0 && scalar(@lines) == 0 && | 1761 | if (defined $cond) { |
| 1673 | scalar(@statements) < 2 && | 1762 | substr($block, 0, length($cond)) = ''; |
| 1674 | $stmt !~ /{/ && $stmt !~ /\bif\b/ && | 1763 | } |
| 1675 | $before !~ /}/ && $after !~ /{/) { | 1764 | if ($block =~ /^\s*\{/) { |
| 1676 | my $herectx = "$here\n" . join("\n", @control, @block[1 .. $#block]) . "\n"; | 1765 | #print "APW: ALLOWED: chunk-1 block<$block>\n"; |
| 1677 | shift(@block); | 1766 | $allowed = 1; |
| 1678 | WARN("braces {} are not necessary for single statement blocks\n" . $herectx); | 1767 | } |
| 1768 | } | ||
| 1769 | if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { | ||
| 1770 | my $herectx = $here . "\n";; | ||
| 1771 | my $end = $linenr + statement_rawlines($block) - 1; | ||
| 1772 | |||
| 1773 | for (my $ln = $linenr - 1; $ln < $end; $ln++) { | ||
| 1774 | $herectx .= $rawlines[$ln] . "\n";; | ||
| 1679 | } | 1775 | } |
| 1776 | |||
| 1777 | WARN("braces {} are not necessary for single statement blocks\n" . $herectx); | ||
| 1680 | } | 1778 | } |
| 1681 | } | 1779 | } |
| 1682 | 1780 | ||
| @@ -1828,15 +1926,6 @@ sub process { | |||
| 1828 | print "are false positives report them to the maintainer, see\n"; | 1926 | print "are false positives report them to the maintainer, see\n"; |
| 1829 | print "CHECKPATCH in MAINTAINERS.\n"; | 1927 | print "CHECKPATCH in MAINTAINERS.\n"; |
| 1830 | } | 1928 | } |
| 1831 | print <<EOL if ($file == 1 && $quiet == 0); | ||
| 1832 | |||
| 1833 | WARNING: Using --file mode. Please do not send patches to linux-kernel | ||
| 1834 | that change whole existing files if you did not significantly change most | ||
| 1835 | of the the file for other reasons anyways or just wrote the file newly | ||
| 1836 | from scratch. Pure code style patches have a significant cost in a | ||
| 1837 | quickly changing code base like Linux because they cause rejects | ||
| 1838 | with other changes. | ||
| 1839 | EOL | ||
| 1840 | 1929 | ||
| 1841 | return $clean; | 1930 | return $clean; |
| 1842 | } | 1931 | } |
