diff options
575 files changed, 12578 insertions, 6951 deletions
diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX index 8de8a01a2474..f28a24e0279b 100644 --- a/Documentation/00-INDEX +++ b/Documentation/00-INDEX | |||
@@ -138,6 +138,8 @@ java.txt | |||
138 | - info on the in-kernel binary support for Java(tm). | 138 | - info on the in-kernel binary support for Java(tm). |
139 | kbuild/ | 139 | kbuild/ |
140 | - directory with info about the kernel build process. | 140 | - directory with info about the kernel build process. |
141 | kdumpt.txt | ||
142 | - mini HowTo on getting the crash dump code to work. | ||
141 | kernel-doc-nano-HOWTO.txt | 143 | kernel-doc-nano-HOWTO.txt |
142 | - mini HowTo on generation and location of kernel documentation files. | 144 | - mini HowTo on generation and location of kernel documentation files. |
143 | kernel-docs.txt | 145 | kernel-docs.txt |
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index 4d35562b1cf9..bcdeee146ff1 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches | |||
@@ -299,7 +299,7 @@ can certify the below: | |||
299 | 299 | ||
300 | then you just add a line saying | 300 | then you just add a line saying |
301 | 301 | ||
302 | Signed-off-by: Random J Developer <random@developer.org> | 302 | Signed-off-by: Random J Developer <random@developer.example.org> |
303 | 303 | ||
304 | Some people also put extra tags at the end. They'll just be ignored for | 304 | Some people also put extra tags at the end. They'll just be ignored for |
305 | now, but you can do this to mark internal company procedures or just | 305 | now, but you can do this to mark internal company procedures or just |
diff --git a/Documentation/cdrom/sbpcd b/Documentation/cdrom/sbpcd index d1825dffca34..b3ba63f4ce3e 100644 --- a/Documentation/cdrom/sbpcd +++ b/Documentation/cdrom/sbpcd | |||
@@ -419,6 +419,7 @@ into the file "track01": | |||
419 | */ | 419 | */ |
420 | #include <stdio.h> | 420 | #include <stdio.h> |
421 | #include <sys/ioctl.h> | 421 | #include <sys/ioctl.h> |
422 | #include <sys/types.h> | ||
422 | #include <linux/cdrom.h> | 423 | #include <linux/cdrom.h> |
423 | 424 | ||
424 | static struct cdrom_tochdr hdr; | 425 | static struct cdrom_tochdr hdr; |
@@ -429,7 +430,7 @@ static int datafile, drive; | |||
429 | static int i, j, limit, track, err; | 430 | static int i, j, limit, track, err; |
430 | static char filename[32]; | 431 | static char filename[32]; |
431 | 432 | ||
432 | main(int argc, char *argv[]) | 433 | int main(int argc, char *argv[]) |
433 | { | 434 | { |
434 | /* | 435 | /* |
435 | * open /dev/cdrom | 436 | * open /dev/cdrom |
@@ -516,6 +517,7 @@ entry[track+1].cdte_addr.lba=entry[track].cdte_addr.lba+300; | |||
516 | } | 517 | } |
517 | arg.addr.lba++; | 518 | arg.addr.lba++; |
518 | } | 519 | } |
520 | return 0; | ||
519 | } | 521 | } |
520 | /*===================== end program ========================================*/ | 522 | /*===================== end program ========================================*/ |
521 | 523 | ||
@@ -564,15 +566,16 @@ Appendix -- the "cdtester" utility: | |||
564 | #include <stdio.h> | 566 | #include <stdio.h> |
565 | #include <malloc.h> | 567 | #include <malloc.h> |
566 | #include <sys/ioctl.h> | 568 | #include <sys/ioctl.h> |
569 | #include <sys/types.h> | ||
567 | #include <linux/cdrom.h> | 570 | #include <linux/cdrom.h> |
568 | 571 | ||
569 | #ifdef AZT_PRIVATE_IOCTLS | 572 | #ifdef AZT_PRIVATE_IOCTLS |
570 | #include <linux/../../drivers/cdrom/aztcd.h> | 573 | #include <linux/../../drivers/cdrom/aztcd.h> |
571 | #endif AZT_PRIVATE_IOCTLS | 574 | #endif /* AZT_PRIVATE_IOCTLS */ |
572 | #ifdef SBP_PRIVATE_IOCTLS | 575 | #ifdef SBP_PRIVATE_IOCTLS |
573 | #include <linux/../../drivers/cdrom/sbpcd.h> | 576 | #include <linux/../../drivers/cdrom/sbpcd.h> |
574 | #include <linux/fs.h> | 577 | #include <linux/fs.h> |
575 | #endif SBP_PRIVATE_IOCTLS | 578 | #endif /* SBP_PRIVATE_IOCTLS */ |
576 | 579 | ||
577 | struct cdrom_tochdr hdr; | 580 | struct cdrom_tochdr hdr; |
578 | struct cdrom_tochdr tocHdr; | 581 | struct cdrom_tochdr tocHdr; |
@@ -590,7 +593,7 @@ union | |||
590 | struct cdrom_msf msf; | 593 | struct cdrom_msf msf; |
591 | unsigned char buf[CD_FRAMESIZE_RAW]; | 594 | unsigned char buf[CD_FRAMESIZE_RAW]; |
592 | } azt; | 595 | } azt; |
593 | #endif AZT_PRIVATE_IOCTLS | 596 | #endif /* AZT_PRIVATE_IOCTLS */ |
594 | int i, i1, i2, i3, j, k; | 597 | int i, i1, i2, i3, j, k; |
595 | unsigned char sequence=0; | 598 | unsigned char sequence=0; |
596 | unsigned char command[80]; | 599 | unsigned char command[80]; |
@@ -738,7 +741,7 @@ void display(int size,unsigned char *buffer) | |||
738 | } | 741 | } |
739 | } | 742 | } |
740 | 743 | ||
741 | main(int argc, char *argv[]) | 744 | int main(int argc, char *argv[]) |
742 | { | 745 | { |
743 | printf("\nTesting tool for a CDROM driver's audio functions V0.1\n"); | 746 | printf("\nTesting tool for a CDROM driver's audio functions V0.1\n"); |
744 | printf("(C) 1995 Eberhard Moenkeberg <emoenke@gwdg.de>\n"); | 747 | printf("(C) 1995 Eberhard Moenkeberg <emoenke@gwdg.de>\n"); |
@@ -1046,12 +1049,13 @@ main(int argc, char *argv[]) | |||
1046 | rc=ioctl(drive,CDROMAUDIOBUFSIZ,j); | 1049 | rc=ioctl(drive,CDROMAUDIOBUFSIZ,j); |
1047 | printf("%d frames granted.\n",rc); | 1050 | printf("%d frames granted.\n",rc); |
1048 | break; | 1051 | break; |
1049 | #endif SBP_PRIVATE_IOCTLS | 1052 | #endif /* SBP_PRIVATE_IOCTLS */ |
1050 | default: | 1053 | default: |
1051 | printf("unknown command: \"%s\".\n",command); | 1054 | printf("unknown command: \"%s\".\n",command); |
1052 | break; | 1055 | break; |
1053 | } | 1056 | } |
1054 | } | 1057 | } |
1058 | return 0; | ||
1055 | } | 1059 | } |
1056 | /*==========================================================================*/ | 1060 | /*==========================================================================*/ |
1057 | 1061 | ||
diff --git a/Documentation/cpu-freq/governors.txt b/Documentation/cpu-freq/governors.txt index b85481acd0ca..933fae74c337 100644 --- a/Documentation/cpu-freq/governors.txt +++ b/Documentation/cpu-freq/governors.txt | |||
@@ -9,6 +9,7 @@ | |||
9 | 9 | ||
10 | 10 | ||
11 | Dominik Brodowski <linux@brodo.de> | 11 | Dominik Brodowski <linux@brodo.de> |
12 | some additions and corrections by Nico Golde <nico@ngolde.de> | ||
12 | 13 | ||
13 | 14 | ||
14 | 15 | ||
@@ -25,6 +26,7 @@ Contents: | |||
25 | 2.1 Performance | 26 | 2.1 Performance |
26 | 2.2 Powersave | 27 | 2.2 Powersave |
27 | 2.3 Userspace | 28 | 2.3 Userspace |
29 | 2.4 Ondemand | ||
28 | 30 | ||
29 | 3. The Governor Interface in the CPUfreq Core | 31 | 3. The Governor Interface in the CPUfreq Core |
30 | 32 | ||
@@ -86,7 +88,7 @@ highest frequency within the borders of scaling_min_freq and | |||
86 | scaling_max_freq. | 88 | scaling_max_freq. |
87 | 89 | ||
88 | 90 | ||
89 | 2.1 Powersave | 91 | 2.2 Powersave |
90 | ------------- | 92 | ------------- |
91 | 93 | ||
92 | The CPUfreq governor "powersave" sets the CPU statically to the | 94 | The CPUfreq governor "powersave" sets the CPU statically to the |
@@ -94,7 +96,7 @@ lowest frequency within the borders of scaling_min_freq and | |||
94 | scaling_max_freq. | 96 | scaling_max_freq. |
95 | 97 | ||
96 | 98 | ||
97 | 2.2 Userspace | 99 | 2.3 Userspace |
98 | ------------- | 100 | ------------- |
99 | 101 | ||
100 | The CPUfreq governor "userspace" allows the user, or any userspace | 102 | The CPUfreq governor "userspace" allows the user, or any userspace |
@@ -103,6 +105,14 @@ by making a sysfs file "scaling_setspeed" available in the CPU-device | |||
103 | directory. | 105 | directory. |
104 | 106 | ||
105 | 107 | ||
108 | 2.4 Ondemand | ||
109 | ------------ | ||
110 | |||
111 | The CPUfreq govenor "ondemand" sets the CPU depending on the | ||
112 | current usage. To do this the CPU must have the capability to | ||
113 | switch the frequency very fast. | ||
114 | |||
115 | |||
106 | 116 | ||
107 | 3. The Governor Interface in the CPUfreq Core | 117 | 3. The Governor Interface in the CPUfreq Core |
108 | ============================================= | 118 | ============================================= |
diff --git a/Documentation/cpusets.txt b/Documentation/cpusets.txt index 2f8f24eaefd9..ad944c060312 100644 --- a/Documentation/cpusets.txt +++ b/Documentation/cpusets.txt | |||
@@ -51,6 +51,14 @@ mems_allowed vector. | |||
51 | 51 | ||
52 | If a cpuset is cpu or mem exclusive, no other cpuset, other than a direct | 52 | If a cpuset is cpu or mem exclusive, no other cpuset, other than a direct |
53 | ancestor or descendent, may share any of the same CPUs or Memory Nodes. | 53 | ancestor or descendent, may share any of the same CPUs or Memory Nodes. |
54 | A cpuset that is cpu exclusive has a sched domain associated with it. | ||
55 | The sched domain consists of all cpus in the current cpuset that are not | ||
56 | part of any exclusive child cpusets. | ||
57 | This ensures that the scheduler load balacing code only balances | ||
58 | against the cpus that are in the sched domain as defined above and not | ||
59 | all of the cpus in the system. This removes any overhead due to | ||
60 | load balancing code trying to pull tasks outside of the cpu exclusive | ||
61 | cpuset only to be prevented by the tasks' cpus_allowed mask. | ||
54 | 62 | ||
55 | User level code may create and destroy cpusets by name in the cpuset | 63 | User level code may create and destroy cpusets by name in the cpuset |
56 | virtual file system, manage the attributes and permissions of these | 64 | virtual file system, manage the attributes and permissions of these |
@@ -84,6 +92,9 @@ This can be especially valuable on: | |||
84 | and a database), or | 92 | and a database), or |
85 | * NUMA systems running large HPC applications with demanding | 93 | * NUMA systems running large HPC applications with demanding |
86 | performance characteristics. | 94 | performance characteristics. |
95 | * Also cpu_exclusive cpusets are useful for servers running orthogonal | ||
96 | workloads such as RT applications requiring low latency and HPC | ||
97 | applications that are throughput sensitive | ||
87 | 98 | ||
88 | These subsets, or "soft partitions" must be able to be dynamically | 99 | These subsets, or "soft partitions" must be able to be dynamically |
89 | adjusted, as the job mix changes, without impacting other concurrently | 100 | adjusted, as the job mix changes, without impacting other concurrently |
@@ -125,6 +136,8 @@ Cpusets extends these two mechanisms as follows: | |||
125 | - A cpuset may be marked exclusive, which ensures that no other | 136 | - A cpuset may be marked exclusive, which ensures that no other |
126 | cpuset (except direct ancestors and descendents) may contain | 137 | cpuset (except direct ancestors and descendents) may contain |
127 | any overlapping CPUs or Memory Nodes. | 138 | any overlapping CPUs or Memory Nodes. |
139 | Also a cpu_exclusive cpuset would be associated with a sched | ||
140 | domain. | ||
128 | - You can list all the tasks (by pid) attached to any cpuset. | 141 | - You can list all the tasks (by pid) attached to any cpuset. |
129 | 142 | ||
130 | The implementation of cpusets requires a few, simple hooks | 143 | The implementation of cpusets requires a few, simple hooks |
@@ -136,6 +149,9 @@ into the rest of the kernel, none in performance critical paths: | |||
136 | allowed in that tasks cpuset. | 149 | allowed in that tasks cpuset. |
137 | - in sched.c migrate_all_tasks(), to keep migrating tasks within | 150 | - in sched.c migrate_all_tasks(), to keep migrating tasks within |
138 | the CPUs allowed by their cpuset, if possible. | 151 | the CPUs allowed by their cpuset, if possible. |
152 | - in sched.c, a new API partition_sched_domains for handling | ||
153 | sched domain changes associated with cpu_exclusive cpusets | ||
154 | and related changes in both sched.c and arch/ia64/kernel/domain.c | ||
139 | - in the mbind and set_mempolicy system calls, to mask the requested | 155 | - in the mbind and set_mempolicy system calls, to mask the requested |
140 | Memory Nodes by what's allowed in that tasks cpuset. | 156 | Memory Nodes by what's allowed in that tasks cpuset. |
141 | - in page_alloc, to restrict memory to allowed nodes. | 157 | - in page_alloc, to restrict memory to allowed nodes. |
diff --git a/Documentation/devices.txt b/Documentation/devices.txt index bb67cf25010e..0f515175c72a 100644 --- a/Documentation/devices.txt +++ b/Documentation/devices.txt | |||
@@ -94,6 +94,7 @@ Your cooperation is appreciated. | |||
94 | 9 = /dev/urandom Faster, less secure random number gen. | 94 | 9 = /dev/urandom Faster, less secure random number gen. |
95 | 10 = /dev/aio Asyncronous I/O notification interface | 95 | 10 = /dev/aio Asyncronous I/O notification interface |
96 | 11 = /dev/kmsg Writes to this come out as printk's | 96 | 11 = /dev/kmsg Writes to this come out as printk's |
97 | 12 = /dev/oldmem Access to crash dump from kexec kernel | ||
97 | 1 block RAM disk | 98 | 1 block RAM disk |
98 | 0 = /dev/ram0 First RAM disk | 99 | 0 = /dev/ram0 First RAM disk |
99 | 1 = /dev/ram1 Second RAM disk | 100 | 1 = /dev/ram1 Second RAM disk |
diff --git a/Documentation/dvb/bt8xx.txt b/Documentation/dvb/bt8xx.txt index d64430bf4bb6..3a3260794758 100644 --- a/Documentation/dvb/bt8xx.txt +++ b/Documentation/dvb/bt8xx.txt | |||
@@ -44,26 +44,23 @@ TwinHan (dst) are loaded automatically by the dvb-bt8xx device driver. | |||
44 | $ modprobe dst | 44 | $ modprobe dst |
45 | 45 | ||
46 | The value 0x71 will override the PCI type detection for dvb-bt8xx, | 46 | The value 0x71 will override the PCI type detection for dvb-bt8xx, |
47 | which is necessary for TwinHan cards. | 47 | which is necessary for TwinHan cards. |
48 | 48 | ||
49 | If you're having an older card (blue color circuit) and card=0x71 locks | 49 | If you're having an older card (blue color circuit) and card=0x71 locks |
50 | your machine, try using 0x68, too. If that does not work, ask on the | 50 | your machine, try using 0x68, too. If that does not work, ask on the |
51 | mailing list. | 51 | mailing list. |
52 | 52 | ||
53 | The DST module takes a couple of useful parameters. | 53 | The DST module takes a couple of useful parameters: |
54 | 54 | ||
55 | verbose takes values 0 to 5. These values control the verbosity level. | 55 | a. verbose takes values 0 to 5. These values control the verbosity level. |
56 | 56 | b. debug takes values 0 and 1. You can either disable or enable debugging. | |
57 | debug takes values 0 and 1. You can either disable or enable debugging. | 57 | c. dst_addons takes values 0 and 0x20: |
58 | 58 | - A value of 0 means it is a FTA card. | |
59 | dst_addons takes values 0 and 0x20. A value of 0 means it is a FTA card. | 59 | - A value of 0x20 means it has a Conditional Access slot. |
60 | 0x20 means it has a Conditional Access slot. | ||
61 | |||
62 | The autodected values are determined bythe cards 'response | ||
63 | string' which you can see in your logs e.g. | ||
64 | |||
65 | dst_get_device_id: Recognise [DSTMCI] | ||
66 | 60 | ||
61 | The autodetected values are determined by the "response string" | ||
62 | of the card, which you can see in your logs: | ||
63 | e.g.: dst_get_device_id: Recognize [DSTMCI] | ||
67 | 64 | ||
68 | -- | 65 | -- |
69 | Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham | 66 | Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham, Uwe Bugla |
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 77511af45362..1d227ee3792a 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -43,6 +43,14 @@ Who: Randy Dunlap <rddunlap@osdl.org> | |||
43 | 43 | ||
44 | --------------------------- | 44 | --------------------------- |
45 | 45 | ||
46 | What: RAW driver (CONFIG_RAW_DRIVER) | ||
47 | When: December 2005 | ||
48 | Why: declared obsolete since kernel 2.6.3 | ||
49 | O_DIRECT can be used instead | ||
50 | Who: Adrian Bunk <bunk@stusta.de> | ||
51 | |||
52 | --------------------------- | ||
53 | |||
46 | What: register_ioctl32_conversion() / unregister_ioctl32_conversion() | 54 | What: register_ioctl32_conversion() / unregister_ioctl32_conversion() |
47 | When: April 2005 | 55 | When: April 2005 |
48 | Why: Replaced by ->compat_ioctl in file_operations and other method | 56 | Why: Replaced by ->compat_ioctl in file_operations and other method |
diff --git a/Documentation/kdump/gdbmacros.txt b/Documentation/kdump/gdbmacros.txt new file mode 100644 index 000000000000..bc1b9eb92ae1 --- /dev/null +++ b/Documentation/kdump/gdbmacros.txt | |||
@@ -0,0 +1,179 @@ | |||
1 | # | ||
2 | # This file contains a few gdb macros (user defined commands) to extract | ||
3 | # useful information from kernel crashdump (kdump) like stack traces of | ||
4 | # all the processes or a particular process and trapinfo. | ||
5 | # | ||
6 | # These macros can be used by copying this file in .gdbinit (put in home | ||
7 | # directory or current directory) or by invoking gdb command with | ||
8 | # --command=<command-file-name> option | ||
9 | # | ||
10 | # Credits: | ||
11 | # Alexander Nyberg <alexn@telia.com> | ||
12 | # V Srivatsa <vatsa@in.ibm.com> | ||
13 | # Maneesh Soni <maneesh@in.ibm.com> | ||
14 | # | ||
15 | |||
16 | define bttnobp | ||
17 | set $tasks_off=((size_t)&((struct task_struct *)0)->tasks) | ||
18 | set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next) | ||
19 | set $init_t=&init_task | ||
20 | set $next_t=(((char *)($init_t->tasks).next) - $tasks_off) | ||
21 | while ($next_t != $init_t) | ||
22 | set $next_t=(struct task_struct *)$next_t | ||
23 | printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm | ||
24 | printf "===================\n" | ||
25 | set var $stackp = $next_t.thread.esp | ||
26 | set var $stack_top = ($stackp & ~4095) + 4096 | ||
27 | |||
28 | while ($stackp < $stack_top) | ||
29 | if (*($stackp) > _stext && *($stackp) < _sinittext) | ||
30 | info symbol *($stackp) | ||
31 | end | ||
32 | set $stackp += 4 | ||
33 | end | ||
34 | set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off) | ||
35 | while ($next_th != $next_t) | ||
36 | set $next_th=(struct task_struct *)$next_th | ||
37 | printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm | ||
38 | printf "===================\n" | ||
39 | set var $stackp = $next_t.thread.esp | ||
40 | set var $stack_top = ($stackp & ~4095) + 4096 | ||
41 | |||
42 | while ($stackp < $stack_top) | ||
43 | if (*($stackp) > _stext && *($stackp) < _sinittext) | ||
44 | info symbol *($stackp) | ||
45 | end | ||
46 | set $stackp += 4 | ||
47 | end | ||
48 | set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off) | ||
49 | end | ||
50 | set $next_t=(char *)($next_t->tasks.next) - $tasks_off | ||
51 | end | ||
52 | end | ||
53 | document bttnobp | ||
54 | dump all thread stack traces on a kernel compiled with !CONFIG_FRAME_POINTER | ||
55 | end | ||
56 | |||
57 | define btt | ||
58 | set $tasks_off=((size_t)&((struct task_struct *)0)->tasks) | ||
59 | set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next) | ||
60 | set $init_t=&init_task | ||
61 | set $next_t=(((char *)($init_t->tasks).next) - $tasks_off) | ||
62 | while ($next_t != $init_t) | ||
63 | set $next_t=(struct task_struct *)$next_t | ||
64 | printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm | ||
65 | printf "===================\n" | ||
66 | set var $stackp = $next_t.thread.esp | ||
67 | set var $stack_top = ($stackp & ~4095) + 4096 | ||
68 | set var $stack_bot = ($stackp & ~4095) | ||
69 | |||
70 | set $stackp = *($stackp) | ||
71 | while (($stackp < $stack_top) && ($stackp > $stack_bot)) | ||
72 | set var $addr = *($stackp + 4) | ||
73 | info symbol $addr | ||
74 | set $stackp = *($stackp) | ||
75 | end | ||
76 | |||
77 | set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off) | ||
78 | while ($next_th != $next_t) | ||
79 | set $next_th=(struct task_struct *)$next_th | ||
80 | printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm | ||
81 | printf "===================\n" | ||
82 | set var $stackp = $next_t.thread.esp | ||
83 | set var $stack_top = ($stackp & ~4095) + 4096 | ||
84 | set var $stack_bot = ($stackp & ~4095) | ||
85 | |||
86 | set $stackp = *($stackp) | ||
87 | while (($stackp < $stack_top) && ($stackp > $stack_bot)) | ||
88 | set var $addr = *($stackp + 4) | ||
89 | info symbol $addr | ||
90 | set $stackp = *($stackp) | ||
91 | end | ||
92 | set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off) | ||
93 | end | ||
94 | set $next_t=(char *)($next_t->tasks.next) - $tasks_off | ||
95 | end | ||
96 | end | ||
97 | document btt | ||
98 | dump all thread stack traces on a kernel compiled with CONFIG_FRAME_POINTER | ||
99 | end | ||
100 | |||
101 | define btpid | ||
102 | set var $pid = $arg0 | ||
103 | set $tasks_off=((size_t)&((struct task_struct *)0)->tasks) | ||
104 | set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next) | ||
105 | set $init_t=&init_task | ||
106 | set $next_t=(((char *)($init_t->tasks).next) - $tasks_off) | ||
107 | set var $pid_task = 0 | ||
108 | |||
109 | while ($next_t != $init_t) | ||
110 | set $next_t=(struct task_struct *)$next_t | ||
111 | |||
112 | if ($next_t.pid == $pid) | ||
113 | set $pid_task = $next_t | ||
114 | end | ||
115 | |||
116 | set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off) | ||
117 | while ($next_th != $next_t) | ||
118 | set $next_th=(struct task_struct *)$next_th | ||
119 | if ($next_th.pid == $pid) | ||
120 | set $pid_task = $next_th | ||
121 | end | ||
122 | set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off) | ||
123 | end | ||
124 | set $next_t=(char *)($next_t->tasks.next) - $tasks_off | ||
125 | end | ||
126 | |||
127 | printf "\npid %d; comm %s:\n", $pid_task.pid, $pid_task.comm | ||
128 | printf "===================\n" | ||
129 | set var $stackp = $pid_task.thread.esp | ||
130 | set var $stack_top = ($stackp & ~4095) + 4096 | ||
131 | set var $stack_bot = ($stackp & ~4095) | ||
132 | |||
133 | set $stackp = *($stackp) | ||
134 | while (($stackp < $stack_top) && ($stackp > $stack_bot)) | ||
135 | set var $addr = *($stackp + 4) | ||
136 | info symbol $addr | ||
137 | set $stackp = *($stackp) | ||
138 | end | ||
139 | end | ||
140 | document btpid | ||
141 | backtrace of pid | ||
142 | end | ||
143 | |||
144 | |||
145 | define trapinfo | ||
146 | set var $pid = $arg0 | ||
147 | set $tasks_off=((size_t)&((struct task_struct *)0)->tasks) | ||
148 | set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next) | ||
149 | set $init_t=&init_task | ||
150 | set $next_t=(((char *)($init_t->tasks).next) - $tasks_off) | ||
151 | set var $pid_task = 0 | ||
152 | |||
153 | while ($next_t != $init_t) | ||
154 | set $next_t=(struct task_struct *)$next_t | ||
155 | |||
156 | if ($next_t.pid == $pid) | ||
157 | set $pid_task = $next_t | ||
158 | end | ||
159 | |||
160 | set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off) | ||
161 | while ($next_th != $next_t) | ||
162 | set $next_th=(struct task_struct *)$next_th | ||
163 | if ($next_th.pid == $pid) | ||
164 | set $pid_task = $next_th | ||
165 | end | ||
166 | set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off) | ||
167 | end | ||
168 | set $next_t=(char *)($next_t->tasks.next) - $tasks_off | ||
169 | end | ||
170 | |||
171 | printf "Trapno %ld, cr2 0x%lx, error_code %ld\n", $pid_task.thread.trap_no, \ | ||
172 | $pid_task.thread.cr2, $pid_task.thread.error_code | ||
173 | |||
174 | end | ||
175 | document trapinfo | ||
176 | Run info threads and lookup pid of thread #1 | ||
177 | 'trapinfo <pid>' will tell you by which trap & possibly | ||
178 | addresthe kernel paniced. | ||
179 | end | ||
diff --git a/Documentation/kdump/kdump.txt b/Documentation/kdump/kdump.txt new file mode 100644 index 000000000000..7ff213f4becd --- /dev/null +++ b/Documentation/kdump/kdump.txt | |||
@@ -0,0 +1,141 @@ | |||
1 | Documentation for kdump - the kexec-based crash dumping solution | ||
2 | ================================================================ | ||
3 | |||
4 | DESIGN | ||
5 | ====== | ||
6 | |||
7 | Kdump uses kexec to reboot to a second kernel whenever a dump needs to be taken. | ||
8 | This second kernel is booted with very little memory. The first kernel reserves | ||
9 | the section of memory that the second kernel uses. This ensures that on-going | ||
10 | DMA from the first kernel does not corrupt the second kernel. | ||
11 | |||
12 | All the necessary information about Core image is encoded in ELF format and | ||
13 | stored in reserved area of memory before crash. Physical address of start of | ||
14 | ELF header is passed to new kernel through command line parameter elfcorehdr=. | ||
15 | |||
16 | On i386, the first 640 KB of physical memory is needed to boot, irrespective | ||
17 | of where the kernel loads. Hence, this region is backed up by kexec just before | ||
18 | rebooting into the new kernel. | ||
19 | |||
20 | In the second kernel, "old memory" can be accessed in two ways. | ||
21 | |||
22 | - The first one is through a /dev/oldmem device interface. A capture utility | ||
23 | can read the device file and write out the memory in raw format. This is raw | ||
24 | dump of memory and analysis/capture tool should be intelligent enough to | ||
25 | determine where to look for the right information. ELF headers (elfcorehdr=) | ||
26 | can become handy here. | ||
27 | |||
28 | - The second interface is through /proc/vmcore. This exports the dump as an ELF | ||
29 | format file which can be written out using any file copy command | ||
30 | (cp, scp, etc). Further, gdb can be used to perform limited debugging on | ||
31 | the dump file. This method ensures methods ensure that there is correct | ||
32 | ordering of the dump pages (corresponding to the first 640 KB that has been | ||
33 | relocated). | ||
34 | |||
35 | SETUP | ||
36 | ===== | ||
37 | |||
38 | 1) Download http://www.xmission.com/~ebiederm/files/kexec/kexec-tools-1.101.tar.gz | ||
39 | and apply http://lse.sourceforge.net/kdump/patches/kexec-tools-1.101-kdump.patch | ||
40 | and after that build the source. | ||
41 | |||
42 | 2) Download and build the appropriate (latest) kexec/kdump (-mm) kernel | ||
43 | patchset and apply it to the vanilla kernel tree. | ||
44 | |||
45 | Two kernels need to be built in order to get this feature working. | ||
46 | |||
47 | A) First kernel: | ||
48 | a) Enable "kexec system call" feature (in Processor type and features). | ||
49 | CONFIG_KEXEC=y | ||
50 | b) This kernel's physical load address should be the default value of | ||
51 | 0x100000 (0x100000, 1 MB) (in Processor type and features). | ||
52 | CONFIG_PHYSICAL_START=0x100000 | ||
53 | c) Enable "sysfs file system support" (in Pseudo filesystems). | ||
54 | CONFIG_SYSFS=y | ||
55 | d) Boot into first kernel with the command line parameter "crashkernel=Y@X". | ||
56 | Use appropriate values for X and Y. Y denotes how much memory to reserve | ||
57 | for the second kernel, and X denotes at what physical address the reserved | ||
58 | memory section starts. For example: "crashkernel=64M@16M". | ||
59 | |||
60 | B) Second kernel: | ||
61 | a) Enable "kernel crash dumps" feature (in Processor type and features). | ||
62 | CONFIG_CRASH_DUMP=y | ||
63 | b) Specify a suitable value for "Physical address where the kernel is | ||
64 | loaded" (in Processor type and features). Typically this value | ||
65 | should be same as X (See option d) above, e.g., 16 MB or 0x1000000. | ||
66 | CONFIG_PHYSICAL_START=0x1000000 | ||
67 | c) Enable "/proc/vmcore support" (Optional, in Pseudo filesystems). | ||
68 | CONFIG_PROC_VMCORE=y | ||
69 | d) Disable SMP support and build a UP kernel (Until it is fixed). | ||
70 | CONFIG_SMP=n | ||
71 | e) Enable "Local APIC support on uniprocessors". | ||
72 | CONFIG_X86_UP_APIC=y | ||
73 | f) Enable "IO-APIC support on uniprocessors" | ||
74 | CONFIG_X86_UP_IOAPIC=y | ||
75 | |||
76 | Note: i) Options a) and b) depend upon "Configure standard kernel features | ||
77 | (for small systems)" (under General setup). | ||
78 | ii) Option a) also depends on CONFIG_HIGHMEM (under Processor | ||
79 | type and features). | ||
80 | iii) Both option a) and b) are under "Processor type and features". | ||
81 | |||
82 | 3) Boot into the first kernel. You are now ready to try out kexec-based crash | ||
83 | dumps. | ||
84 | |||
85 | 4) Load the second kernel to be booted using: | ||
86 | |||
87 | kexec -p <second-kernel> --crash-dump --args-linux --append="root=<root-dev> | ||
88 | init 1 irqpoll" | ||
89 | |||
90 | Note: i) <second-kernel> has to be a vmlinux image. bzImage will not work, | ||
91 | as of now. | ||
92 | ii) By default ELF headers are stored in ELF32 format (for i386). This | ||
93 | is sufficient to represent the physical memory up to 4GB. To store | ||
94 | headers in ELF64 format, specifiy "--elf64-core-headers" on the | ||
95 | kexec command line additionally. | ||
96 | iii) Specify "irqpoll" as command line parameter. This reduces driver | ||
97 | initialization failures in second kernel due to shared interrupts. | ||
98 | |||
99 | 5) System reboots into the second kernel when a panic occurs. A module can be | ||
100 | written to force the panic or "ALT-SysRq-c" can be used initiate a crash | ||
101 | dump for testing purposes. | ||
102 | |||
103 | 6) Write out the dump file using | ||
104 | |||
105 | cp /proc/vmcore <dump-file> | ||
106 | |||
107 | Dump memory can also be accessed as a /dev/oldmem device for a linear/raw | ||
108 | view. To create the device, type: | ||
109 | |||
110 | mknod /dev/oldmem c 1 12 | ||
111 | |||
112 | Use "dd" with suitable options for count, bs and skip to access specific | ||
113 | portions of the dump. | ||
114 | |||
115 | Entire memory: dd if=/dev/oldmem of=oldmem.001 | ||
116 | |||
117 | ANALYSIS | ||
118 | ======== | ||
119 | |||
120 | Limited analysis can be done using gdb on the dump file copied out of | ||
121 | /proc/vmcore. Use vmlinux built with -g and run | ||
122 | |||
123 | gdb vmlinux <dump-file> | ||
124 | |||
125 | Stack trace for the task on processor 0, register display, memory display | ||
126 | work fine. | ||
127 | |||
128 | Note: gdb cannot analyse core files generated in ELF64 format for i386. | ||
129 | |||
130 | TODO | ||
131 | ==== | ||
132 | |||
133 | 1) Provide a kernel pages filtering mechanism so that core file size is not | ||
134 | insane on systems having huge memory banks. | ||
135 | 2) Modify "crash" tool to make it recognize this dump. | ||
136 | |||
137 | CONTACT | ||
138 | ======= | ||
139 | |||
140 | Vivek Goyal (vgoyal@in.ibm.com) | ||
141 | Maneesh Soni (maneesh@in.ibm.com) | ||
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 4924d387a657..f44bb5567c5b 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -358,6 +358,10 @@ running once the system is up. | |||
358 | cpia_pp= [HW,PPT] | 358 | cpia_pp= [HW,PPT] |
359 | Format: { parport<nr> | auto | none } | 359 | Format: { parport<nr> | auto | none } |
360 | 360 | ||
361 | crashkernel=nn[KMG]@ss[KMG] | ||
362 | [KNL] Reserve a chunk of physical memory to | ||
363 | hold a kernel to switch to with kexec on panic. | ||
364 | |||
361 | cs4232= [HW,OSS] | 365 | cs4232= [HW,OSS] |
362 | Format: <io>,<irq>,<dma>,<dma2>,<mpuio>,<mpuirq> | 366 | Format: <io>,<irq>,<dma>,<dma2>,<mpuio>,<mpuirq> |
363 | 367 | ||
@@ -447,6 +451,10 @@ running once the system is up. | |||
447 | Format: {"as"|"cfq"|"deadline"|"noop"} | 451 | Format: {"as"|"cfq"|"deadline"|"noop"} |
448 | See Documentation/block/as-iosched.txt | 452 | See Documentation/block/as-iosched.txt |
449 | and Documentation/block/deadline-iosched.txt for details. | 453 | and Documentation/block/deadline-iosched.txt for details. |
454 | elfcorehdr= [IA-32] | ||
455 | Specifies physical address of start of kernel core image | ||
456 | elf header. | ||
457 | See Documentation/kdump.txt for details. | ||
450 | 458 | ||
451 | enforcing [SELINUX] Set initial enforcing status. | 459 | enforcing [SELINUX] Set initial enforcing status. |
452 | Format: {"0" | "1"} | 460 | Format: {"0" | "1"} |
@@ -548,6 +556,9 @@ running once the system is up. | |||
548 | 556 | ||
549 | i810= [HW,DRM] | 557 | i810= [HW,DRM] |
550 | 558 | ||
559 | i8k.ignore_dmi [HW] Continue probing hardware even if DMI data | ||
560 | indicates that the driver is running on unsupported | ||
561 | hardware. | ||
551 | i8k.force [HW] Activate i8k driver even if SMM BIOS signature | 562 | i8k.force [HW] Activate i8k driver even if SMM BIOS signature |
552 | does not match list of supported models. | 563 | does not match list of supported models. |
553 | i8k.power_status | 564 | i8k.power_status |
diff --git a/Documentation/networking/00-INDEX b/Documentation/networking/00-INDEX index 834993d26730..5b01d5cc4e95 100644 --- a/Documentation/networking/00-INDEX +++ b/Documentation/networking/00-INDEX | |||
@@ -114,9 +114,7 @@ tuntap.txt | |||
114 | vortex.txt | 114 | vortex.txt |
115 | - info on using 3Com Vortex (3c590, 3c592, 3c595, 3c597) Ethernet cards. | 115 | - info on using 3Com Vortex (3c590, 3c592, 3c595, 3c597) Ethernet cards. |
116 | wan-router.txt | 116 | wan-router.txt |
117 | - Wan router documentation | 117 | - WAN router documentation |
118 | wanpipe.txt | ||
119 | - WANPIPE(tm) Multiprotocol WAN Driver for Linux WAN Router | ||
120 | wavelan.txt | 118 | wavelan.txt |
121 | - AT&T GIS (nee NCR) WaveLAN card: An Ethernet-like radio transceiver | 119 | - AT&T GIS (nee NCR) WaveLAN card: An Ethernet-like radio transceiver |
122 | x25.txt | 120 | x25.txt |
diff --git a/Documentation/networking/wanpipe.txt b/Documentation/networking/wanpipe.txt deleted file mode 100644 index aea20cd2a56e..000000000000 --- a/Documentation/networking/wanpipe.txt +++ /dev/null | |||
@@ -1,622 +0,0 @@ | |||
1 | ------------------------------------------------------------------------------ | ||
2 | Linux WAN Router Utilities Package | ||
3 | ------------------------------------------------------------------------------ | ||
4 | Version 2.2.1 | ||
5 | Mar 28, 2001 | ||
6 | Author: Nenad Corbic <ncorbic@sangoma.com> | ||
7 | Copyright (c) 1995-2001 Sangoma Technologies Inc. | ||
8 | ------------------------------------------------------------------------------ | ||
9 | |||
10 | INTRODUCTION | ||
11 | |||
12 | Wide Area Networks (WANs) are used to interconnect Local Area Networks (LANs) | ||
13 | and/or stand-alone hosts over vast distances with data transfer rates | ||
14 | significantly higher than those achievable with commonly used dial-up | ||
15 | connections. | ||
16 | |||
17 | Usually an external device called `WAN router' sitting on your local network | ||
18 | or connected to your machine's serial port provides physical connection to | ||
19 | WAN. Although router's job may be as simple as taking your local network | ||
20 | traffic, converting it to WAN format and piping it through the WAN link, these | ||
21 | devices are notoriously expensive, with prices as much as 2 - 5 times higher | ||
22 | then the price of a typical PC box. | ||
23 | |||
24 | Alternatively, considering robustness and multitasking capabilities of Linux, | ||
25 | an internal router can be built (most routers use some sort of stripped down | ||
26 | Unix-like operating system anyway). With a number of relatively inexpensive WAN | ||
27 | interface cards available on the market, a perfectly usable router can be | ||
28 | built for less than half a price of an external router. Yet a Linux box | ||
29 | acting as a router can still be used for other purposes, such as fire-walling, | ||
30 | running FTP, WWW or DNS server, etc. | ||
31 | |||
32 | This kernel module introduces the notion of a WAN Link Driver (WLD) to Linux | ||
33 | operating system and provides generic hardware-independent services for such | ||
34 | drivers. Why can existing Linux network device interface not be used for | ||
35 | this purpose? Well, it can. However, there are a few key differences between | ||
36 | a typical network interface (e.g. Ethernet) and a WAN link. | ||
37 | |||
38 | Many WAN protocols, such as X.25 and frame relay, allow for multiple logical | ||
39 | connections (known as `virtual circuits' in X.25 terminology) over a single | ||
40 | physical link. Each such virtual circuit may (and almost always does) lead | ||
41 | to a different geographical location and, therefore, different network. As a | ||
42 | result, it is the virtual circuit, not the physical link, that represents a | ||
43 | route and, therefore, a network interface in Linux terms. | ||
44 | |||
45 | To further complicate things, virtual circuits are usually volatile in nature | ||
46 | (excluding so called `permanent' virtual circuits or PVCs). With almost no | ||
47 | time required to set up and tear down a virtual circuit, it is highly desirable | ||
48 | to implement on-demand connections in order to minimize network charges. So | ||
49 | unlike a typical network driver, the WAN driver must be able to handle multiple | ||
50 | network interfaces and cope as multiple virtual circuits come into existence | ||
51 | and go away dynamically. | ||
52 | |||
53 | Last, but not least, WAN configuration is much more complex than that of say | ||
54 | Ethernet and may well amount to several dozens of parameters. Some of them | ||
55 | are "link-wide" while others are virtual circuit-specific. The same holds | ||
56 | true for WAN statistics which is by far more extensive and extremely useful | ||
57 | when troubleshooting WAN connections. Extending the ifconfig utility to suit | ||
58 | these needs may be possible, but does not seem quite reasonable. Therefore, a | ||
59 | WAN configuration utility and corresponding application programmer's interface | ||
60 | is needed for this purpose. | ||
61 | |||
62 | Most of these problems are taken care of by this module. Its goal is to | ||
63 | provide a user with more-or-less standard look and feel for all WAN devices and | ||
64 | assist a WAN device driver writer by providing common services, such as: | ||
65 | |||
66 | o User-level interface via /proc file system | ||
67 | o Centralized configuration | ||
68 | o Device management (setup, shutdown, etc.) | ||
69 | o Network interface management (dynamic creation/destruction) | ||
70 | o Protocol encapsulation/decapsulation | ||
71 | |||
72 | To ba able to use the Linux WAN Router you will also need a WAN Tools package | ||
73 | available from | ||
74 | |||
75 | ftp.sangoma.com/pub/linux/current_wanpipe/wanpipe-X.Y.Z.tgz | ||
76 | |||
77 | where vX.Y.Z represent the wanpipe version number. | ||
78 | |||
79 | For technical questions and/or comments please e-mail to ncorbic@sangoma.com. | ||
80 | For general inquiries please contact Sangoma Technologies Inc. by | ||
81 | |||
82 | Hotline: 1-800-388-2475 (USA and Canada, toll free) | ||
83 | Phone: (905) 474-1990 ext: 106 | ||
84 | Fax: (905) 474-9223 | ||
85 | E-mail: dm@sangoma.com (David Mandelstam) | ||
86 | WWW: http://www.sangoma.com | ||
87 | |||
88 | |||
89 | INSTALLATION | ||
90 | |||
91 | Please read the WanpipeForLinux.pdf manual on how to | ||
92 | install the WANPIPE tools and drivers properly. | ||
93 | |||
94 | |||
95 | After installing wanpipe package: /usr/local/wanrouter/doc. | ||
96 | On the ftp.sangoma.com : /linux/current_wanpipe/doc | ||
97 | |||
98 | |||
99 | COPYRIGHT AND LICENSING INFORMATION | ||
100 | |||
101 | This program is free software; you can redistribute it and/or modify it under | ||
102 | the terms of the GNU General Public License as published by the Free Software | ||
103 | Foundation; either version 2, or (at your option) any later version. | ||
104 | |||
105 | This program is distributed in the hope that it will be useful, but WITHOUT | ||
106 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | ||
107 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||
108 | |||
109 | You should have received a copy of the GNU General Public License along with | ||
110 | this program; if not, write to the Free Software Foundation, Inc., 675 Mass | ||
111 | Ave, Cambridge, MA 02139, USA. | ||
112 | |||
113 | |||
114 | |||
115 | ACKNOWLEDGEMENTS | ||
116 | |||
117 | This product is based on the WANPIPE(tm) Multiprotocol WAN Router developed | ||
118 | by Sangoma Technologies Inc. for Linux 2.0.x and 2.2.x. Success of the WANPIPE | ||
119 | together with the next major release of Linux kernel in summer 1996 commanded | ||
120 | adequate changes to the WANPIPE code to take full advantage of new Linux | ||
121 | features. | ||
122 | |||
123 | Instead of continuing developing proprietary interface tied to Sangoma WAN | ||
124 | cards, we decided to separate all hardware-independent code into a separate | ||
125 | module and defined two levels of interfaces - one for user-level applications | ||
126 | and another for kernel-level WAN drivers. WANPIPE is now implemented as a | ||
127 | WAN driver compliant with the WAN Link Driver interface. Also a general | ||
128 | purpose WAN configuration utility and a set of shell scripts was developed to | ||
129 | support WAN router at the user level. | ||
130 | |||
131 | Many useful ideas concerning hardware-independent interface implementation | ||
132 | were given by Mike McLagan <mike.mclagan@linux.org> and his implementation | ||
133 | of the Frame Relay router and drivers for Sangoma cards (dlci/sdla). | ||
134 | |||
135 | With the new implementation of the APIs being incorporated into the WANPIPE, | ||
136 | a special thank goes to Alan Cox in providing insight into BSD sockets. | ||
137 | |||
138 | Special thanks to all the WANPIPE users who performed field-testing, reported | ||
139 | bugs and made valuable comments and suggestions that help us to improve this | ||
140 | product. | ||
141 | |||
142 | |||
143 | |||
144 | NEW IN THIS RELEASE | ||
145 | |||
146 | o Updated the WANCFG utility | ||
147 | Calls the pppconfig to configure the PPPD | ||
148 | for async connections. | ||
149 | |||
150 | o Added the PPPCONFIG utility | ||
151 | Used to configure the PPPD dameon for the | ||
152 | WANPIPE Async PPP and standard serial port. | ||
153 | The wancfg calls the pppconfig to configure | ||
154 | the pppd. | ||
155 | |||
156 | o Fixed the PCI autodetect feature. | ||
157 | The SLOT 0 was used as an autodetect option | ||
158 | however, some high end PC's slot numbers start | ||
159 | from 0. | ||
160 | |||
161 | o This release has been tested with the new backupd | ||
162 | daemon release. | ||
163 | |||
164 | |||
165 | PRODUCT COMPONENTS AND RELATED FILES | ||
166 | |||
167 | /etc: (or user defined) | ||
168 | wanpipe1.conf default router configuration file | ||
169 | |||
170 | /lib/modules/X.Y.Z/misc: | ||
171 | wanrouter.o router kernel loadable module | ||
172 | af_wanpipe.o wanpipe api socket module | ||
173 | |||
174 | /lib/modules/X.Y.Z/net: | ||
175 | sdladrv.o Sangoma SDLA support module | ||
176 | wanpipe.o Sangoma WANPIPE(tm) driver module | ||
177 | |||
178 | /proc/net/wanrouter | ||
179 | Config reads current router configuration | ||
180 | Status reads current router status | ||
181 | {name} reads WAN driver statistics | ||
182 | |||
183 | /usr/sbin: | ||
184 | wanrouter wanrouter start-up script | ||
185 | wanconfig wanrouter configuration utility | ||
186 | sdladump WANPIPE adapter memory dump utility | ||
187 | fpipemon Monitor for Frame Relay | ||
188 | cpipemon Monitor for Cisco HDLC | ||
189 | ppipemon Monitor for PPP | ||
190 | xpipemon Monitor for X25 | ||
191 | wpkbdmon WANPIPE keyboard led monitor/debugger | ||
192 | |||
193 | /usr/local/wanrouter: | ||
194 | README this file | ||
195 | COPYING GNU General Public License | ||
196 | Setup installation script | ||
197 | Filelist distribution definition file | ||
198 | wanrouter.rc meta-configuration file | ||
199 | (used by the Setup and wanrouter script) | ||
200 | |||
201 | /usr/local/wanrouter/doc: | ||
202 | wanpipeForLinux.pdf WAN Router User's Manual | ||
203 | |||
204 | /usr/local/wanrouter/patches: | ||
205 | wanrouter-v2213.gz patch for Linux kernels 2.2.11 up to 2.2.13. | ||
206 | wanrouter-v2214.gz patch for Linux kernel 2.2.14. | ||
207 | wanrouter-v2215.gz patch for Linux kernels 2.2.15 to 2.2.17. | ||
208 | wanrouter-v2218.gz patch for Linux kernels 2.2.18 and up. | ||
209 | wanrouter-v240.gz patch for Linux kernel 2.4.0. | ||
210 | wanrouter-v242.gz patch for Linux kernel 2.4.2 and up. | ||
211 | wanrouter-v2034.gz patch for Linux kernel 2.0.34 | ||
212 | wanrouter-v2036.gz patch for Linux kernel 2.0.36 and up. | ||
213 | |||
214 | /usr/local/wanrouter/patches/kdrivers: | ||
215 | Sources of the latest WANPIPE device drivers. | ||
216 | These are used to UPGRADE the linux kernel to the newest | ||
217 | version if the kernel source has already been pathced with | ||
218 | WANPIPE drivers. | ||
219 | |||
220 | /usr/local/wanrouter/samples: | ||
221 | interface sample interface configuration file | ||
222 | wanpipe1.cpri CHDLC primary port | ||
223 | wanpipe2.csec CHDLC secondary port | ||
224 | wanpipe1.fr Frame Relay protocol | ||
225 | wanpipe1.ppp PPP protocol ) | ||
226 | wanpipe1.asy CHDLC ASYNC protocol | ||
227 | wanpipe1.x25 X25 protocol | ||
228 | wanpipe1.stty Sync TTY driver (Used by Kernel PPPD daemon) | ||
229 | wanpipe1.atty Async TTY driver (Used by Kernel PPPD daemon) | ||
230 | wanrouter.rc sample meta-configuration file | ||
231 | |||
232 | /usr/local/wanrouter/util: | ||
233 | * wan-tools utilities source code | ||
234 | |||
235 | /usr/local/wanrouter/api/x25: | ||
236 | * x25 api sample programs. | ||
237 | /usr/local/wanrouter/api/chdlc: | ||
238 | * chdlc api sample programs. | ||
239 | /usr/local/wanrouter/api/fr: | ||
240 | * fr api sample programs. | ||
241 | /usr/local/wanrouter/config/wancfg: | ||
242 | wancfg WANPIPE GUI configuration program. | ||
243 | Creates wanpipe#.conf files. | ||
244 | /usr/local/wanrouter/config/cfgft1: | ||
245 | cfgft1 GUI CSU/DSU configuration program. | ||
246 | |||
247 | /usr/include/linux: | ||
248 | wanrouter.h router API definitions | ||
249 | wanpipe.h WANPIPE API definitions | ||
250 | sdladrv.h SDLA support module API definitions | ||
251 | sdlasfm.h SDLA firmware module definitions | ||
252 | if_wanpipe.h WANPIPE Socket definitions | ||
253 | if_wanpipe_common.h WANPIPE Socket/Driver common definitions. | ||
254 | sdlapci.h WANPIPE PCI definitions | ||
255 | |||
256 | |||
257 | /usr/src/linux/net/wanrouter: | ||
258 | * wanrouter source code | ||
259 | |||
260 | /var/log: | ||
261 | wanrouter wanrouter start-up log (created by the Setup script) | ||
262 | |||
263 | /var/lock: (or /var/lock/subsys for RedHat) | ||
264 | wanrouter wanrouter lock file (created by the Setup script) | ||
265 | |||
266 | /usr/local/wanrouter/firmware: | ||
267 | fr514.sfm Frame relay firmware for Sangoma S508/S514 card | ||
268 | cdual514.sfm Dual Port Cisco HDLC firmware for Sangoma S508/S514 card | ||
269 | ppp514.sfm PPP Firmware for Sangoma S508 and S514 cards | ||
270 | x25_508.sfm X25 Firmware for Sangoma S508 card. | ||
271 | |||
272 | |||
273 | REVISION HISTORY | ||
274 | |||
275 | 1.0.0 December 31, 1996 Initial version | ||
276 | |||
277 | 1.0.1 January 30, 1997 Status and statistics can be read via /proc | ||
278 | filesystem entries. | ||
279 | |||
280 | 1.0.2 April 30, 1997 Added UDP management via monitors. | ||
281 | |||
282 | 1.0.3 June 3, 1997 UDP management for multiple boards using Frame | ||
283 | Relay and PPP | ||
284 | Enabled continuous transmission of Configure | ||
285 | Request Packet for PPP (for 508 only) | ||
286 | Connection Timeout for PPP changed from 900 to 0 | ||
287 | Flow Control Problem fixed for Frame Relay | ||
288 | |||
289 | 1.0.4 July 10, 1997 S508/FT1 monitoring capability in fpipemon and | ||
290 | ppipemon utilities. | ||
291 | Configurable TTL for UDP packets. | ||
292 | Multicast and Broadcast IP source addresses are | ||
293 | silently discarded. | ||
294 | |||
295 | 1.0.5 July 28, 1997 Configurable T391,T392,N391,N392,N393 for Frame | ||
296 | Relay in router.conf. | ||
297 | Configurable Memory Address through router.conf | ||
298 | for Frame Relay, PPP and X.25. (commenting this | ||
299 | out enables auto-detection). | ||
300 | Fixed freeing up received buffers using kfree() | ||
301 | for Frame Relay and X.25. | ||
302 | Protect sdla_peek() by calling save_flags(), | ||
303 | cli() and restore_flags(). | ||
304 | Changed number of Trace elements from 32 to 20 | ||
305 | Added DLCI specific data monitoring in FPIPEMON. | ||
306 | 2.0.0 Nov 07, 1997 Implemented protection of RACE conditions by | ||
307 | critical flags for FRAME RELAY and PPP. | ||
308 | DLCI List interrupt mode implemented. | ||
309 | IPX support in FRAME RELAY and PPP. | ||
310 | IPX Server Support (MARS) | ||
311 | More driver specific stats included in FPIPEMON | ||
312 | and PIPEMON. | ||
313 | |||
314 | 2.0.1 Nov 28, 1997 Bug Fixes for version 2.0.0. | ||
315 | Protection of "enable_irq()" while | ||
316 | "disable_irq()" has been enabled from any other | ||
317 | routine (for Frame Relay, PPP and X25). | ||
318 | Added additional Stats for Fpipemon and Ppipemon | ||
319 | Improved Load Sharing for multiple boards | ||
320 | |||
321 | 2.0.2 Dec 09, 1997 Support for PAP and CHAP for ppp has been | ||
322 | implemented. | ||
323 | |||
324 | 2.0.3 Aug 15, 1998 New release supporting Cisco HDLC, CIR for Frame | ||
325 | relay, Dynamic IP assignment for PPP and Inverse | ||
326 | Arp support for Frame-relay. Man Pages are | ||
327 | included for better support and a new utility | ||
328 | for configuring FT1 cards. | ||
329 | |||
330 | 2.0.4 Dec 09, 1998 Dual Port support for Cisco HDLC. | ||
331 | Support for HDLC (LAPB) API. | ||
332 | Supports BiSync Streaming code for S502E | ||
333 | and S503 cards. | ||
334 | Support for Streaming HDLC API. | ||
335 | Provides a BSD socket interface for | ||
336 | creating applications using BiSync | ||
337 | streaming. | ||
338 | |||
339 | 2.0.5 Aug 04, 1999 CHDLC initializatin bug fix. | ||
340 | PPP interrupt driven driver: | ||
341 | Fix to the PPP line hangup problem. | ||
342 | New PPP firmware | ||
343 | Added comments to the startup SYSTEM ERROR messages | ||
344 | Xpipemon debugging application for the X25 protocol | ||
345 | New USER_MANUAL.txt | ||
346 | Fixed the odd boundary 4byte writes to the board. | ||
347 | BiSync Streaming code has been taken out. | ||
348 | Available as a patch. | ||
349 | Streaming HDLC API has been taken out. | ||
350 | Available as a patch. | ||
351 | |||
352 | 2.0.6 Aug 17, 1999 Increased debugging in statup scripts | ||
353 | Fixed insallation bugs from 2.0.5 | ||
354 | Kernel patch works for both 2.2.10 and 2.2.11 kernels. | ||
355 | There is no functional difference between the two packages | ||
356 | |||
357 | 2.0.7 Aug 26, 1999 o Merged X25API code into WANPIPE. | ||
358 | o Fixed a memeory leak for X25API | ||
359 | o Updated the X25API code for 2.2.X kernels. | ||
360 | o Improved NEM handling. | ||
361 | |||
362 | 2.1.0 Oct 25, 1999 o New code for S514 PCI Card | ||
363 | o New CHDLC and Frame Relay drivers | ||
364 | o PPP and X25 are not supported in this release | ||
365 | |||
366 | 2.1.1 Nov 30, 1999 o PPP support for S514 PCI Cards | ||
367 | |||
368 | 2.1.3 Apr 06, 2000 o Socket based x25api | ||
369 | o Socket based chdlc api | ||
370 | o Socket based fr api | ||
371 | o Dual Port Receive only CHDLC support. | ||
372 | o Asynchronous CHDLC support (Secondary Port) | ||
373 | o cfgft1 GUI csu/dsu configurator | ||
374 | o wancfg GUI configuration file | ||
375 | configurator. | ||
376 | o Architectual directory changes. | ||
377 | |||
378 | beta-2.1.4 Jul 2000 o Dynamic interface configuration: | ||
379 | Network interfaces reflect the state | ||
380 | of protocol layer. If the protocol becomes | ||
381 | disconnected, driver will bring down | ||
382 | the interface. Once the protocol reconnects | ||
383 | the interface will be brought up. | ||
384 | |||
385 | Note: This option is turned off by default. | ||
386 | |||
387 | o Dynamic wanrouter setup using 'wanconfig': | ||
388 | wanconfig utility can be used to | ||
389 | shutdown,restart,start or reconfigure | ||
390 | a virtual circuit dynamically. | ||
391 | |||
392 | Frame Relay: Each DLCI can be: | ||
393 | created,stopped,restarted and reconfigured | ||
394 | dynamically using wanconfig. | ||
395 | |||
396 | ex: wanconfig card wanpipe1 dev wp1_fr16 up | ||
397 | |||
398 | o Wanrouter startup via command line arguments: | ||
399 | wanconfig also supports wanrouter startup via command line | ||
400 | arguments. Thus, there is no need to create a wanpipe#.conf | ||
401 | configuration file. | ||
402 | |||
403 | o Socket based x25api update/bug fixes. | ||
404 | Added support for LCN numbers greater than 255. | ||
405 | Option to pass up modem messages. | ||
406 | Provided a PCI IRQ check, so a single S514 | ||
407 | card is guaranteed to have a non-sharing interrupt. | ||
408 | |||
409 | o Fixes to the wancfg utility. | ||
410 | o New FT1 debugging support via *pipemon utilities. | ||
411 | o Frame Relay ARP support Enabled. | ||
412 | |||
413 | beta3-2.1.4 Jul 2000 o X25 M_BIT Problem fix. | ||
414 | o Added the Multi-Port PPP | ||
415 | Updated utilites for the Multi-Port PPP. | ||
416 | |||
417 | 2.1.4 Aut 2000 | ||
418 | o In X25API: | ||
419 | Maximum packet an application can send | ||
420 | to the driver has been extended to 4096 bytes. | ||
421 | |||
422 | Fixed the x25 startup bug. Enable | ||
423 | communications only after all interfaces | ||
424 | come up. HIGH SVC/PVC is used to calculate | ||
425 | the number of channels. | ||
426 | Enable protocol only after all interfaces | ||
427 | are enabled. | ||
428 | |||
429 | o Added an extra state to the FT1 config, kernel module. | ||
430 | o Updated the pipemon debuggers. | ||
431 | |||
432 | o Blocked the Multi-Port PPP from running on kernels | ||
433 | 2.2.16 or greater, due to syncppp kernel module | ||
434 | change. | ||
435 | |||
436 | beta1-2.1.5 Nov 15 2000 | ||
437 | o Fixed the MulitPort PPP Support for kernels 2.2.16 and above. | ||
438 | 2.2.X kernels only | ||
439 | |||
440 | o Secured the driver UDP debugging calls | ||
441 | - All illegal netowrk debugging calls are reported to | ||
442 | the log. | ||
443 | - Defined a set of allowed commands, all other denied. | ||
444 | |||
445 | o Cpipemon | ||
446 | - Added set FT1 commands to the cpipemon. Thus CSU/DSU | ||
447 | configuraiton can be performed using cpipemon. | ||
448 | All systems that cannot run cfgft1 GUI utility should | ||
449 | use cpipemon to configure the on board CSU/DSU. | ||
450 | |||
451 | |||
452 | o Keyboard Led Monitor/Debugger | ||
453 | - A new utilty /usr/sbin/wpkbdmon uses keyboard leds | ||
454 | to convey operatinal statistic information of the | ||
455 | Sangoma WANPIPE cards. | ||
456 | NUM_LOCK = Line State (On=connected, Off=disconnected) | ||
457 | CAPS_LOCK = Tx data (On=transmitting, Off=no tx data) | ||
458 | SCROLL_LOCK = Rx data (On=receiving, Off=no rx data | ||
459 | |||
460 | o Hardware probe on module load and dynamic device allocation | ||
461 | - During WANPIPE module load, all Sangoma cards are probed | ||
462 | and found information is printed in the /var/log/messages. | ||
463 | - If no cards are found, the module load fails. | ||
464 | - Appropriate number of devices are dynamically loaded | ||
465 | based on the number of Sangoma cards found. | ||
466 | |||
467 | Note: The kernel configuraiton option | ||
468 | CONFIG_WANPIPE_CARDS has been taken out. | ||
469 | |||
470 | o Fixed the Frame Relay and Chdlc network interfaces so they are | ||
471 | compatible with libpcap libraries. Meaning, tcpdump, snort, | ||
472 | ethereal, and all other packet sniffers and debuggers work on | ||
473 | all WANPIPE netowrk interfaces. | ||
474 | - Set the network interface encoding type to ARPHRD_PPP. | ||
475 | This tell the sniffers that data obtained from the | ||
476 | network interface is in pure IP format. | ||
477 | Fix for 2.2.X kernels only. | ||
478 | |||
479 | o True interface encoding option for Frame Relay and CHDLC | ||
480 | - The above fix sets the network interface encoding | ||
481 | type to ARPHRD_PPP, however some customers use | ||
482 | the encoding interface type to determine the | ||
483 | protocol running. Therefore, the TURE ENCODING | ||
484 | option will set the interface type back to the | ||
485 | original value. | ||
486 | |||
487 | NOTE: If this option is used with Frame Relay and CHDLC | ||
488 | libpcap library support will be broken. | ||
489 | i.e. tcpdump will not work. | ||
490 | Fix for 2.2.x Kernels only. | ||
491 | |||
492 | o Ethernet Bridgind over Frame Relay | ||
493 | - The Frame Relay bridging has been developed by | ||
494 | Kristian Hoffmann and Mark Wells. | ||
495 | - The Linux kernel bridge is used to send ethernet | ||
496 | data over the frame relay links. | ||
497 | For 2.2.X Kernels only. | ||
498 | |||
499 | o Added extensive 2.0.X support. Most new features of | ||
500 | 2.1.5 for protocols Frame Relay, PPP and CHDLC are | ||
501 | supported under 2.0.X kernels. | ||
502 | |||
503 | beta1-2.2.0 Dec 30 2000 | ||
504 | o Updated drivers for 2.4.X kernels. | ||
505 | o Updated drivers for SMP support. | ||
506 | o X25API is now able to share PCI interrupts. | ||
507 | o Took out a general polling routine that was used | ||
508 | only by X25API. | ||
509 | o Added appropriate locks to the dynamic reconfiguration | ||
510 | code. | ||
511 | o Fixed a bug in the keyboard debug monitor. | ||
512 | |||
513 | beta2-2.2.0 Jan 8 2001 | ||
514 | o Patches for 2.4.0 kernel | ||
515 | o Patches for 2.2.18 kernel | ||
516 | o Minor updates to PPP and CHLDC drivers. | ||
517 | Note: No functinal difference. | ||
518 | |||
519 | beta3-2.2.9 Jan 10 2001 | ||
520 | o I missed the 2.2.18 kernel patches in beta2-2.2.0 | ||
521 | release. They are included in this release. | ||
522 | |||
523 | Stable Release | ||
524 | 2.2.0 Feb 01 2001 | ||
525 | o Bug fix in wancfg GUI configurator. | ||
526 | The edit function didn't work properly. | ||
527 | |||
528 | |||
529 | bata1-2.2.1 Feb 09 2001 | ||
530 | o WANPIPE TTY Driver emulation. | ||
531 | Two modes of operation Sync and Async. | ||
532 | Sync: Using the PPPD daemon, kernel SyncPPP layer | ||
533 | and the Wanpipe sync TTY driver: a PPP protocol | ||
534 | connection can be established via Sangoma adapter, over | ||
535 | a T1 leased line. | ||
536 | |||
537 | The 2.4.0 kernel PPP layer supports MULTILINK | ||
538 | protocol, that can be used to bundle any number of Sangoma | ||
539 | adapters (T1 lines) into one, under a single IP address. | ||
540 | Thus, efficiently obtaining multiple T1 throughput. | ||
541 | |||
542 | NOTE: The remote side must also implement MULTILINK PPP | ||
543 | protocol. | ||
544 | |||
545 | Async:Using the PPPD daemon, kernel AsyncPPP layer | ||
546 | and the WANPIPE async TTY driver: a PPP protocol | ||
547 | connection can be established via Sangoma adapter and | ||
548 | a modem, over a telephone line. | ||
549 | |||
550 | Thus, the WANPIPE async TTY driver simulates a serial | ||
551 | TTY driver that would normally be used to interface the | ||
552 | MODEM to the linux kernel. | ||
553 | |||
554 | o WANPIPE PPP Backup Utility | ||
555 | This utility will monitor the state of the PPP T1 line. | ||
556 | In case of failure, a dial up connection will be established | ||
557 | via pppd daemon, ether via a serial tty driver (serial port), | ||
558 | or a WANPIPE async TTY driver (in case serial port is unavailable). | ||
559 | |||
560 | Furthermore, while in dial up mode, the primary PPP T1 link | ||
561 | will be monitored for signs of life. | ||
562 | |||
563 | If the PPP T1 link comes back to life, the dial up connection | ||
564 | will be shutdown and T1 line re-established. | ||
565 | |||
566 | |||
567 | o New Setup installation script. | ||
568 | Option to UPGRADE device drivers if the kernel source has | ||
569 | already been patched with WANPIPE. | ||
570 | |||
571 | Option to COMPILE WANPIPE modules against the currently | ||
572 | running kernel, thus no need for manual kernel and module | ||
573 | re-compilatin. | ||
574 | |||
575 | o Updates and Bug Fixes to wancfg utility. | ||
576 | |||
577 | bata2-2.2.1 Feb 20 2001 | ||
578 | |||
579 | o Bug fixes to the CHDLC device drivers. | ||
580 | The driver had compilation problems under kernels | ||
581 | 2.2.14 or lower. | ||
582 | |||
583 | o Bug fixes to the Setup installation script. | ||
584 | The device drivers compilation options didn't work | ||
585 | properly. | ||
586 | |||
587 | o Update to the wpbackupd daemon. | ||
588 | Optimized the cross-over times, between the primary | ||
589 | link and the backup dialup. | ||
590 | |||
591 | beta3-2.2.1 Mar 02 2001 | ||
592 | o Patches for 2.4.2 kernel. | ||
593 | |||
594 | o Bug fixes to util/ make files. | ||
595 | o Bug fixes to the Setup installation script. | ||
596 | |||
597 | o Took out the backupd support and made it into | ||
598 | as separate package. | ||
599 | |||
600 | beta4-2.2.1 Mar 12 2001 | ||
601 | |||
602 | o Fix to the Frame Relay Device driver. | ||
603 | IPSAC sends a packet of zero length | ||
604 | header to the frame relay driver. The | ||
605 | driver tries to push its own 2 byte header | ||
606 | into the packet, which causes the driver to | ||
607 | crash. | ||
608 | |||
609 | o Fix the WANPIPE re-configuration code. | ||
610 | Bug was found by trying to run the cfgft1 while the | ||
611 | interface was already running. | ||
612 | |||
613 | o Updates to cfgft1. | ||
614 | Writes a wanpipe#.cfgft1 configuration file | ||
615 | once the CSU/DSU is configured. This file can | ||
616 | holds the current CSU/DSU configuration. | ||
617 | |||
618 | |||
619 | |||
620 | >>>>>> END OF README <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< | ||
621 | |||
622 | |||
diff --git a/Documentation/power/pci.txt b/Documentation/power/pci.txt index 35b1a7dae342..6fc9d511fc39 100644 --- a/Documentation/power/pci.txt +++ b/Documentation/power/pci.txt | |||
@@ -291,6 +291,44 @@ a request to enable wake events from D3, two calls should be made to | |||
291 | pci_enable_wake (one for both D3hot and D3cold). | 291 | pci_enable_wake (one for both D3hot and D3cold). |
292 | 292 | ||
293 | 293 | ||
294 | A reference implementation | ||
295 | ------------------------- | ||
296 | .suspend() | ||
297 | { | ||
298 | /* driver specific operations */ | ||
299 | |||
300 | /* Disable IRQ */ | ||
301 | free_irq(); | ||
302 | /* If using MSI */ | ||
303 | pci_disable_msi(); | ||
304 | |||
305 | pci_save_state(); | ||
306 | pci_enable_wake(); | ||
307 | /* Disable IO/bus master/irq router */ | ||
308 | pci_disable_device(); | ||
309 | pci_set_power_state(pci_choose_state()); | ||
310 | } | ||
311 | |||
312 | .resume() | ||
313 | { | ||
314 | pci_set_power_state(PCI_D0); | ||
315 | pci_restore_state(); | ||
316 | /* device's irq possibly is changed, driver should take care */ | ||
317 | pci_enable_device(); | ||
318 | pci_set_master(); | ||
319 | |||
320 | /* if using MSI, device's vector possibly is changed */ | ||
321 | pci_enable_msi(); | ||
322 | |||
323 | request_irq(); | ||
324 | /* driver specific operations; */ | ||
325 | } | ||
326 | |||
327 | This is a typical implementation. Drivers can slightly change the order | ||
328 | of the operations in the implementation, ignore some operations or add | ||
329 | more deriver specific operations in it, but drivers should do something like | ||
330 | this on the whole. | ||
331 | |||
294 | 5. Resources | 332 | 5. Resources |
295 | ~~~~~~~~~~~~ | 333 | ~~~~~~~~~~~~ |
296 | 334 | ||
diff --git a/Documentation/power/swsusp.txt b/Documentation/power/swsusp.txt index 4e1627cc5b51..7a6b78966459 100644 --- a/Documentation/power/swsusp.txt +++ b/Documentation/power/swsusp.txt | |||
@@ -164,10 +164,11 @@ place where the thread is safe to be frozen (no kernel semaphores | |||
164 | should be held at that point and it must be safe to sleep there), and | 164 | should be held at that point and it must be safe to sleep there), and |
165 | add: | 165 | add: |
166 | 166 | ||
167 | try_to_freeze(); | 167 | try_to_freeze(); |
168 | 168 | ||
169 | If the thread is needed for writing the image to storage, you should | 169 | If the thread is needed for writing the image to storage, you should |
170 | instead set the PF_NOFREEZE process flag when creating the thread. | 170 | instead set the PF_NOFREEZE process flag when creating the thread (and |
171 | be very carefull). | ||
171 | 172 | ||
172 | 173 | ||
173 | Q: What is the difference between between "platform", "shutdown" and | 174 | Q: What is the difference between between "platform", "shutdown" and |
@@ -232,3 +233,81 @@ A: Try running | |||
232 | cat `cat /proc/[0-9]*/maps | grep / | sed 's:.* /:/:' | sort -u` > /dev/null | 233 | cat `cat /proc/[0-9]*/maps | grep / | sed 's:.* /:/:' | sort -u` > /dev/null |
233 | 234 | ||
234 | after resume. swapoff -a; swapon -a may also be usefull. | 235 | after resume. swapoff -a; swapon -a may also be usefull. |
236 | |||
237 | Q: What happens to devices during swsusp? They seem to be resumed | ||
238 | during system suspend? | ||
239 | |||
240 | A: That's correct. We need to resume them if we want to write image to | ||
241 | disk. Whole sequence goes like | ||
242 | |||
243 | Suspend part | ||
244 | ~~~~~~~~~~~~ | ||
245 | running system, user asks for suspend-to-disk | ||
246 | |||
247 | user processes are stopped | ||
248 | |||
249 | suspend(PMSG_FREEZE): devices are frozen so that they don't interfere | ||
250 | with state snapshot | ||
251 | |||
252 | state snapshot: copy of whole used memory is taken with interrupts disabled | ||
253 | |||
254 | resume(): devices are woken up so that we can write image to swap | ||
255 | |||
256 | write image to swap | ||
257 | |||
258 | suspend(PMSG_SUSPEND): suspend devices so that we can power off | ||
259 | |||
260 | turn the power off | ||
261 | |||
262 | Resume part | ||
263 | ~~~~~~~~~~~ | ||
264 | (is actually pretty similar) | ||
265 | |||
266 | running system, user asks for suspend-to-disk | ||
267 | |||
268 | user processes are stopped (in common case there are none, but with resume-from-initrd, noone knows) | ||
269 | |||
270 | read image from disk | ||
271 | |||
272 | suspend(PMSG_FREEZE): devices are frozen so that they don't interfere | ||
273 | with image restoration | ||
274 | |||
275 | image restoration: rewrite memory with image | ||
276 | |||
277 | resume(): devices are woken up so that system can continue | ||
278 | |||
279 | thaw all user processes | ||
280 | |||
281 | Q: What is this 'Encrypt suspend image' for? | ||
282 | |||
283 | A: First of all: it is not a replacement for dm-crypt encrypted swap. | ||
284 | It cannot protect your computer while it is suspended. Instead it does | ||
285 | protect from leaking sensitive data after resume from suspend. | ||
286 | |||
287 | Think of the following: you suspend while an application is running | ||
288 | that keeps sensitive data in memory. The application itself prevents | ||
289 | the data from being swapped out. Suspend, however, must write these | ||
290 | data to swap to be able to resume later on. Without suspend encryption | ||
291 | your sensitive data are then stored in plaintext on disk. This means | ||
292 | that after resume your sensitive data are accessible to all | ||
293 | applications having direct access to the swap device which was used | ||
294 | for suspend. If you don't need swap after resume these data can remain | ||
295 | on disk virtually forever. Thus it can happen that your system gets | ||
296 | broken in weeks later and sensitive data which you thought were | ||
297 | encrypted and protected are retrieved and stolen from the swap device. | ||
298 | To prevent this situation you should use 'Encrypt suspend image'. | ||
299 | |||
300 | During suspend a temporary key is created and this key is used to | ||
301 | encrypt the data written to disk. When, during resume, the data was | ||
302 | read back into memory the temporary key is destroyed which simply | ||
303 | means that all data written to disk during suspend are then | ||
304 | inaccessible so they can't be stolen later on. The only thing that | ||
305 | you must then take care of is that you call 'mkswap' for the swap | ||
306 | partition used for suspend as early as possible during regular | ||
307 | boot. This asserts that any temporary key from an oopsed suspend or | ||
308 | from a failed or aborted resume is erased from the swap device. | ||
309 | |||
310 | As a rule of thumb use encrypted swap to protect your data while your | ||
311 | system is shut down or suspended. Additionally use the encrypted | ||
312 | suspend image to prevent sensitive data from being stolen after | ||
313 | resume. | ||
diff --git a/Documentation/power/video.txt b/Documentation/power/video.txt index 68734355d7cf..881a37e3eeb0 100644 --- a/Documentation/power/video.txt +++ b/Documentation/power/video.txt | |||
@@ -83,8 +83,10 @@ Compaq Armada E500 - P3-700 none (1) (S1 also works OK) | |||
83 | Compaq Evo N620c vga=normal, s3_bios (2) | 83 | Compaq Evo N620c vga=normal, s3_bios (2) |
84 | Dell 600m, ATI R250 Lf none (1), but needs xorg-x11-6.8.1.902-1 | 84 | Dell 600m, ATI R250 Lf none (1), but needs xorg-x11-6.8.1.902-1 |
85 | Dell D600, ATI RV250 vga=normal and X, or try vbestate (6) | 85 | Dell D600, ATI RV250 vga=normal and X, or try vbestate (6) |
86 | Dell D610 vga=normal and X (possibly vbestate (6) too, but not tested) | ||
86 | Dell Inspiron 4000 ??? (*) | 87 | Dell Inspiron 4000 ??? (*) |
87 | Dell Inspiron 500m ??? (*) | 88 | Dell Inspiron 500m ??? (*) |
89 | Dell Inspiron 510m ??? | ||
88 | Dell Inspiron 600m ??? (*) | 90 | Dell Inspiron 600m ??? (*) |
89 | Dell Inspiron 8200 ??? (*) | 91 | Dell Inspiron 8200 ??? (*) |
90 | Dell Inspiron 8500 ??? (*) | 92 | Dell Inspiron 8500 ??? (*) |
@@ -123,6 +125,7 @@ Toshiba Satellite 4030CDT s3_mode (3) | |||
123 | Toshiba Satellite 4080XCDT s3_mode (3) | 125 | Toshiba Satellite 4080XCDT s3_mode (3) |
124 | Toshiba Satellite 4090XCDT ??? (*) | 126 | Toshiba Satellite 4090XCDT ??? (*) |
125 | Toshiba Satellite P10-554 s3_bios,s3_mode (4)(****) | 127 | Toshiba Satellite P10-554 s3_bios,s3_mode (4)(****) |
128 | Toshiba M30 (2) xor X with nvidia driver using internal AGP | ||
126 | Uniwill 244IIO ??? (*) | 129 | Uniwill 244IIO ??? (*) |
127 | 130 | ||
128 | 131 | ||
diff --git a/Documentation/power/video_extension.txt b/Documentation/power/video_extension.txt index 8e33d7c82c49..b2f9b1598ac2 100644 --- a/Documentation/power/video_extension.txt +++ b/Documentation/power/video_extension.txt | |||
@@ -1,13 +1,16 @@ | |||
1 | This driver implement the ACPI Extensions For Display Adapters | 1 | ACPI video extensions |
2 | for integrated graphics devices on motherboard, as specified in | 2 | ~~~~~~~~~~~~~~~~~~~~~ |
3 | ACPI 2.0 Specification, Appendix B, allowing to perform some basic | 3 | |
4 | control like defining the video POST device, retrieving EDID information | 4 | This driver implement the ACPI Extensions For Display Adapters for |
5 | or to setup a video output, etc. Note that this is an ref. implementation only. | 5 | integrated graphics devices on motherboard, as specified in ACPI 2.0 |
6 | It may or may not work for your integrated video device. | 6 | Specification, Appendix B, allowing to perform some basic control like |
7 | defining the video POST device, retrieving EDID information or to | ||
8 | setup a video output, etc. Note that this is an ref. implementation | ||
9 | only. It may or may not work for your integrated video device. | ||
7 | 10 | ||
8 | Interfaces exposed to userland through /proc/acpi/video: | 11 | Interfaces exposed to userland through /proc/acpi/video: |
9 | 12 | ||
10 | VGA/info : display the supported video bus device capability like ,Video ROM, CRT/LCD/TV. | 13 | VGA/info : display the supported video bus device capability like Video ROM, CRT/LCD/TV. |
11 | VGA/ROM : Used to get a copy of the display devices' ROM data (up to 4k). | 14 | VGA/ROM : Used to get a copy of the display devices' ROM data (up to 4k). |
12 | VGA/POST_info : Used to determine what options are implemented. | 15 | VGA/POST_info : Used to determine what options are implemented. |
13 | VGA/POST : Used to get/set POST device. | 16 | VGA/POST : Used to get/set POST device. |
@@ -15,7 +18,7 @@ VGA/DOS : Used to get/set ownership of output switching: | |||
15 | Please refer ACPI spec B.4.1 _DOS | 18 | Please refer ACPI spec B.4.1 _DOS |
16 | VGA/CRT : CRT output | 19 | VGA/CRT : CRT output |
17 | VGA/LCD : LCD output | 20 | VGA/LCD : LCD output |
18 | VGA/TV : TV output | 21 | VGA/TVO : TV output |
19 | VGA/*/brightness : Used to get/set brightness of output device | 22 | VGA/*/brightness : Used to get/set brightness of output device |
20 | 23 | ||
21 | Notify event through /proc/acpi/event: | 24 | Notify event through /proc/acpi/event: |
diff --git a/Documentation/s390/s390dbf.txt b/Documentation/s390/s390dbf.txt index 2d1cd939b4df..e24fdeada970 100644 --- a/Documentation/s390/s390dbf.txt +++ b/Documentation/s390/s390dbf.txt | |||
@@ -12,8 +12,8 @@ where log records can be stored efficiently in memory, where each component | |||
12 | One purpose of this is to inspect the debug logs after a production system crash | 12 | One purpose of this is to inspect the debug logs after a production system crash |
13 | in order to analyze the reason for the crash. | 13 | in order to analyze the reason for the crash. |
14 | If the system still runs but only a subcomponent which uses dbf failes, | 14 | If the system still runs but only a subcomponent which uses dbf failes, |
15 | it is possible to look at the debug logs on a live system via the Linux proc | 15 | it is possible to look at the debug logs on a live system via the Linux |
16 | filesystem. | 16 | debugfs filesystem. |
17 | The debug feature may also very useful for kernel and driver development. | 17 | The debug feature may also very useful for kernel and driver development. |
18 | 18 | ||
19 | Design: | 19 | Design: |
@@ -52,16 +52,18 @@ Each debug entry contains the following data: | |||
52 | - Flag, if entry is an exception or not | 52 | - Flag, if entry is an exception or not |
53 | 53 | ||
54 | The debug logs can be inspected in a live system through entries in | 54 | The debug logs can be inspected in a live system through entries in |
55 | the proc-filesystem. Under the path /proc/s390dbf there is | 55 | the debugfs-filesystem. Under the toplevel directory "s390dbf" there is |
56 | a directory for each registered component, which is named like the | 56 | a directory for each registered component, which is named like the |
57 | corresponding component. | 57 | corresponding component. The debugfs normally should be mounted to |
58 | /sys/kernel/debug therefore the debug feature can be accessed unter | ||
59 | /sys/kernel/debug/s390dbf. | ||
58 | 60 | ||
59 | The content of the directories are files which represent different views | 61 | The content of the directories are files which represent different views |
60 | to the debug log. Each component can decide which views should be | 62 | to the debug log. Each component can decide which views should be |
61 | used through registering them with the function debug_register_view(). | 63 | used through registering them with the function debug_register_view(). |
62 | Predefined views for hex/ascii, sprintf and raw binary data are provided. | 64 | Predefined views for hex/ascii, sprintf and raw binary data are provided. |
63 | It is also possible to define other views. The content of | 65 | It is also possible to define other views. The content of |
64 | a view can be inspected simply by reading the corresponding proc file. | 66 | a view can be inspected simply by reading the corresponding debugfs file. |
65 | 67 | ||
66 | All debug logs have an an actual debug level (range from 0 to 6). | 68 | All debug logs have an an actual debug level (range from 0 to 6). |
67 | The default level is 3. Event and Exception functions have a 'level' | 69 | The default level is 3. Event and Exception functions have a 'level' |
@@ -69,14 +71,14 @@ parameter. Only debug entries with a level that is lower or equal | |||
69 | than the actual level are written to the log. This means, when | 71 | than the actual level are written to the log. This means, when |
70 | writing events, high priority log entries should have a low level | 72 | writing events, high priority log entries should have a low level |
71 | value whereas low priority entries should have a high one. | 73 | value whereas low priority entries should have a high one. |
72 | The actual debug level can be changed with the help of the proc-filesystem | 74 | The actual debug level can be changed with the help of the debugfs-filesystem |
73 | through writing a number string "x" to the 'level' proc file which is | 75 | through writing a number string "x" to the 'level' debugfs file which is |
74 | provided for every debug log. Debugging can be switched off completely | 76 | provided for every debug log. Debugging can be switched off completely |
75 | by using "-" on the 'level' proc file. | 77 | by using "-" on the 'level' debugfs file. |
76 | 78 | ||
77 | Example: | 79 | Example: |
78 | 80 | ||
79 | > echo "-" > /proc/s390dbf/dasd/level | 81 | > echo "-" > /sys/kernel/debug/s390dbf/dasd/level |
80 | 82 | ||
81 | It is also possible to deactivate the debug feature globally for every | 83 | It is also possible to deactivate the debug feature globally for every |
82 | debug log. You can change the behavior using 2 sysctl parameters in | 84 | debug log. You can change the behavior using 2 sysctl parameters in |
@@ -99,11 +101,11 @@ Kernel Interfaces: | |||
99 | ------------------ | 101 | ------------------ |
100 | 102 | ||
101 | ---------------------------------------------------------------------------- | 103 | ---------------------------------------------------------------------------- |
102 | debug_info_t *debug_register(char *name, int pages_index, int nr_areas, | 104 | debug_info_t *debug_register(char *name, int pages, int nr_areas, |
103 | int buf_size); | 105 | int buf_size); |
104 | 106 | ||
105 | Parameter: name: Name of debug log (e.g. used for proc entry) | 107 | Parameter: name: Name of debug log (e.g. used for debugfs entry) |
106 | pages_index: 2^pages_index pages will be allocated per area | 108 | pages: number of pages, which will be allocated per area |
107 | nr_areas: number of debug areas | 109 | nr_areas: number of debug areas |
108 | buf_size: size of data area in each debug entry | 110 | buf_size: size of data area in each debug entry |
109 | 111 | ||
@@ -134,7 +136,7 @@ Return Value: none | |||
134 | Description: Sets new actual debug level if new_level is valid. | 136 | Description: Sets new actual debug level if new_level is valid. |
135 | 137 | ||
136 | --------------------------------------------------------------------------- | 138 | --------------------------------------------------------------------------- |
137 | +void debug_stop_all(void); | 139 | void debug_stop_all(void); |
138 | 140 | ||
139 | Parameter: none | 141 | Parameter: none |
140 | 142 | ||
@@ -270,7 +272,7 @@ Parameter: id: handle for debug log | |||
270 | Return Value: 0 : ok | 272 | Return Value: 0 : ok |
271 | < 0: Error | 273 | < 0: Error |
272 | 274 | ||
273 | Description: registers new debug view and creates proc dir entry | 275 | Description: registers new debug view and creates debugfs dir entry |
274 | 276 | ||
275 | --------------------------------------------------------------------------- | 277 | --------------------------------------------------------------------------- |
276 | int debug_unregister_view (debug_info_t * id, struct debug_view *view); | 278 | int debug_unregister_view (debug_info_t * id, struct debug_view *view); |
@@ -281,7 +283,7 @@ Parameter: id: handle for debug log | |||
281 | Return Value: 0 : ok | 283 | Return Value: 0 : ok |
282 | < 0: Error | 284 | < 0: Error |
283 | 285 | ||
284 | Description: unregisters debug view and removes proc dir entry | 286 | Description: unregisters debug view and removes debugfs dir entry |
285 | 287 | ||
286 | 288 | ||
287 | 289 | ||
@@ -308,7 +310,7 @@ static int init(void) | |||
308 | { | 310 | { |
309 | /* register 4 debug areas with one page each and 4 byte data field */ | 311 | /* register 4 debug areas with one page each and 4 byte data field */ |
310 | 312 | ||
311 | debug_info = debug_register ("test", 0, 4, 4 ); | 313 | debug_info = debug_register ("test", 1, 4, 4 ); |
312 | debug_register_view(debug_info,&debug_hex_ascii_view); | 314 | debug_register_view(debug_info,&debug_hex_ascii_view); |
313 | debug_register_view(debug_info,&debug_raw_view); | 315 | debug_register_view(debug_info,&debug_raw_view); |
314 | 316 | ||
@@ -343,7 +345,7 @@ static int init(void) | |||
343 | /* register 4 debug areas with one page each and data field for */ | 345 | /* register 4 debug areas with one page each and data field for */ |
344 | /* format string pointer + 2 varargs (= 3 * sizeof(long)) */ | 346 | /* format string pointer + 2 varargs (= 3 * sizeof(long)) */ |
345 | 347 | ||
346 | debug_info = debug_register ("test", 0, 4, sizeof(long) * 3); | 348 | debug_info = debug_register ("test", 1, 4, sizeof(long) * 3); |
347 | debug_register_view(debug_info,&debug_sprintf_view); | 349 | debug_register_view(debug_info,&debug_sprintf_view); |
348 | 350 | ||
349 | debug_sprintf_event(debug_info, 2 , "first event in %s:%i\n",__FILE__,__LINE__); | 351 | debug_sprintf_event(debug_info, 2 , "first event in %s:%i\n",__FILE__,__LINE__); |
@@ -362,16 +364,16 @@ module_exit(cleanup); | |||
362 | 364 | ||
363 | 365 | ||
364 | 366 | ||
365 | ProcFS Interface | 367 | Debugfs Interface |
366 | ---------------- | 368 | ---------------- |
367 | Views to the debug logs can be investigated through reading the corresponding | 369 | Views to the debug logs can be investigated through reading the corresponding |
368 | proc-files: | 370 | debugfs-files: |
369 | 371 | ||
370 | Example: | 372 | Example: |
371 | 373 | ||
372 | > ls /proc/s390dbf/dasd | 374 | > ls /sys/kernel/debug/s390dbf/dasd |
373 | flush hex_ascii level raw | 375 | flush hex_ascii level pages raw |
374 | > cat /proc/s390dbf/dasd/hex_ascii | sort +1 | 376 | > cat /sys/kernel/debug/s390dbf/dasd/hex_ascii | sort +1 |
375 | 00 00974733272:680099 2 - 02 0006ad7e 07 ea 4a 90 | .... | 377 | 00 00974733272:680099 2 - 02 0006ad7e 07 ea 4a 90 | .... |
376 | 00 00974733272:682210 2 - 02 0006ade6 46 52 45 45 | FREE | 378 | 00 00974733272:682210 2 - 02 0006ade6 46 52 45 45 | FREE |
377 | 00 00974733272:682213 2 - 02 0006adf6 07 ea 4a 90 | .... | 379 | 00 00974733272:682213 2 - 02 0006adf6 07 ea 4a 90 | .... |
@@ -391,25 +393,36 @@ Changing the debug level | |||
391 | Example: | 393 | Example: |
392 | 394 | ||
393 | 395 | ||
394 | > cat /proc/s390dbf/dasd/level | 396 | > cat /sys/kernel/debug/s390dbf/dasd/level |
395 | 3 | 397 | 3 |
396 | > echo "5" > /proc/s390dbf/dasd/level | 398 | > echo "5" > /sys/kernel/debug/s390dbf/dasd/level |
397 | > cat /proc/s390dbf/dasd/level | 399 | > cat /sys/kernel/debug/s390dbf/dasd/level |
398 | 5 | 400 | 5 |
399 | 401 | ||
400 | Flushing debug areas | 402 | Flushing debug areas |
401 | -------------------- | 403 | -------------------- |
402 | Debug areas can be flushed with piping the number of the desired | 404 | Debug areas can be flushed with piping the number of the desired |
403 | area (0...n) to the proc file "flush". When using "-" all debug areas | 405 | area (0...n) to the debugfs file "flush". When using "-" all debug areas |
404 | are flushed. | 406 | are flushed. |
405 | 407 | ||
406 | Examples: | 408 | Examples: |
407 | 409 | ||
408 | 1. Flush debug area 0: | 410 | 1. Flush debug area 0: |
409 | > echo "0" > /proc/s390dbf/dasd/flush | 411 | > echo "0" > /sys/kernel/debug/s390dbf/dasd/flush |
410 | 412 | ||
411 | 2. Flush all debug areas: | 413 | 2. Flush all debug areas: |
412 | > echo "-" > /proc/s390dbf/dasd/flush | 414 | > echo "-" > /sys/kernel/debug/s390dbf/dasd/flush |
415 | |||
416 | Changing the size of debug areas | ||
417 | ------------------------------------ | ||
418 | It is possible the change the size of debug areas through piping | ||
419 | the number of pages to the debugfs file "pages". The resize request will | ||
420 | also flush the debug areas. | ||
421 | |||
422 | Example: | ||
423 | |||
424 | Define 4 pages for the debug areas of debug feature "dasd": | ||
425 | > echo "4" > /sys/kernel/debug/s390dbf/dasd/pages | ||
413 | 426 | ||
414 | Stooping the debug feature | 427 | Stooping the debug feature |
415 | -------------------------- | 428 | -------------------------- |
@@ -491,7 +504,7 @@ Defining views | |||
491 | -------------- | 504 | -------------- |
492 | 505 | ||
493 | Views are specified with the 'debug_view' structure. There are defined | 506 | Views are specified with the 'debug_view' structure. There are defined |
494 | callback functions which are used for reading and writing the proc files: | 507 | callback functions which are used for reading and writing the debugfs files: |
495 | 508 | ||
496 | struct debug_view { | 509 | struct debug_view { |
497 | char name[DEBUG_MAX_PROCF_LEN]; | 510 | char name[DEBUG_MAX_PROCF_LEN]; |
@@ -525,7 +538,7 @@ typedef int (debug_input_proc_t) (debug_info_t* id, | |||
525 | The "private_data" member can be used as pointer to view specific data. | 538 | The "private_data" member can be used as pointer to view specific data. |
526 | It is not used by the debug feature itself. | 539 | It is not used by the debug feature itself. |
527 | 540 | ||
528 | The output when reading a debug-proc file is structured like this: | 541 | The output when reading a debugfs file is structured like this: |
529 | 542 | ||
530 | "prolog_proc output" | 543 | "prolog_proc output" |
531 | 544 | ||
@@ -534,13 +547,13 @@ The output when reading a debug-proc file is structured like this: | |||
534 | "header_proc output 3" "format_proc output 3" | 547 | "header_proc output 3" "format_proc output 3" |
535 | ... | 548 | ... |
536 | 549 | ||
537 | When a view is read from the proc fs, the Debug Feature calls the | 550 | When a view is read from the debugfs, the Debug Feature calls the |
538 | 'prolog_proc' once for writing the prolog. | 551 | 'prolog_proc' once for writing the prolog. |
539 | Then 'header_proc' and 'format_proc' are called for each | 552 | Then 'header_proc' and 'format_proc' are called for each |
540 | existing debug entry. | 553 | existing debug entry. |
541 | 554 | ||
542 | The input_proc can be used to implement functionality when it is written to | 555 | The input_proc can be used to implement functionality when it is written to |
543 | the view (e.g. like with 'echo "0" > /proc/s390dbf/dasd/level). | 556 | the view (e.g. like with 'echo "0" > /sys/kernel/debug/s390dbf/dasd/level). |
544 | 557 | ||
545 | For header_proc there can be used the default function | 558 | For header_proc there can be used the default function |
546 | debug_dflt_header_fn() which is defined in in debug.h. | 559 | debug_dflt_header_fn() which is defined in in debug.h. |
@@ -602,7 +615,7 @@ debug_info = debug_register ("test", 0, 4, 4 )); | |||
602 | debug_register_view(debug_info, &debug_test_view); | 615 | debug_register_view(debug_info, &debug_test_view); |
603 | for(i = 0; i < 10; i ++) debug_int_event(debug_info, 1, i); | 616 | for(i = 0; i < 10; i ++) debug_int_event(debug_info, 1, i); |
604 | 617 | ||
605 | > cat /proc/s390dbf/test/myview | 618 | > cat /sys/kernel/debug/s390dbf/test/myview |
606 | 00 00964419734:611402 1 - 00 88042ca This error........... | 619 | 00 00964419734:611402 1 - 00 88042ca This error........... |
607 | 00 00964419734:611405 1 - 00 88042ca That error........... | 620 | 00 00964419734:611405 1 - 00 88042ca That error........... |
608 | 00 00964419734:611408 1 - 00 88042ca Problem.............. | 621 | 00 00964419734:611408 1 - 00 88042ca Problem.............. |
diff --git a/Documentation/sysrq.txt b/Documentation/sysrq.txt index f98c2e31c143..136d817c01ba 100644 --- a/Documentation/sysrq.txt +++ b/Documentation/sysrq.txt | |||
@@ -72,6 +72,8 @@ On all - write a character to /proc/sysrq-trigger. eg: | |||
72 | 'b' - Will immediately reboot the system without syncing or unmounting | 72 | 'b' - Will immediately reboot the system without syncing or unmounting |
73 | your disks. | 73 | your disks. |
74 | 74 | ||
75 | 'c' - Will perform a kexec reboot in order to take a crashdump. | ||
76 | |||
75 | 'o' - Will shut your system off (if configured and supported). | 77 | 'o' - Will shut your system off (if configured and supported). |
76 | 78 | ||
77 | 's' - Will attempt to sync all mounted filesystems. | 79 | 's' - Will attempt to sync all mounted filesystems. |
@@ -122,6 +124,9 @@ useful when you want to exit a program that will not let you switch consoles. | |||
122 | re'B'oot is good when you're unable to shut down. But you should also 'S'ync | 124 | re'B'oot is good when you're unable to shut down. But you should also 'S'ync |
123 | and 'U'mount first. | 125 | and 'U'mount first. |
124 | 126 | ||
127 | 'C'rashdump can be used to manually trigger a crashdump when the system is hung. | ||
128 | The kernel needs to have been built with CONFIG_KEXEC enabled. | ||
129 | |||
125 | 'S'ync is great when your system is locked up, it allows you to sync your | 130 | 'S'ync is great when your system is locked up, it allows you to sync your |
126 | disks and will certainly lessen the chance of data loss and fscking. Note | 131 | disks and will certainly lessen the chance of data loss and fscking. Note |
127 | that the sync hasn't taken place until you see the "OK" and "Done" appear | 132 | that the sync hasn't taken place until you see the "OK" and "Done" appear |
diff --git a/MAINTAINERS b/MAINTAINERS index a07eeb411370..a0b0d595d17c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -576,10 +576,9 @@ S: Supported | |||
576 | 576 | ||
577 | COMPUTONE INTELLIPORT MULTIPORT CARD | 577 | COMPUTONE INTELLIPORT MULTIPORT CARD |
578 | P: Michael H. Warfield | 578 | P: Michael H. Warfield |
579 | M: Michael H. Warfield <mhw@wittsend.com> | 579 | M: mhw@wittsend.com |
580 | W: http://www.wittsend.com/computone.html | 580 | W: http://www.wittsend.com/computone.html |
581 | L: linux-computone@lazuli.wittsend.com | 581 | S: Maintained |
582 | S: Orphaned | ||
583 | 582 | ||
584 | COSA/SRP SYNC SERIAL DRIVER | 583 | COSA/SRP SYNC SERIAL DRIVER |
585 | P: Jan "Yenya" Kasprzak | 584 | P: Jan "Yenya" Kasprzak |
@@ -1330,6 +1329,16 @@ M: rml@novell.com | |||
1330 | L: linux-kernel@vger.kernel.org | 1329 | L: linux-kernel@vger.kernel.org |
1331 | S: Maintained | 1330 | S: Maintained |
1332 | 1331 | ||
1332 | KEXEC | ||
1333 | P: Eric Biederman | ||
1334 | P: Randy Dunlap | ||
1335 | M: ebiederm@xmission.com | ||
1336 | M: rddunlap@osdl.org | ||
1337 | W: http://www.xmission.com/~ebiederm/files/kexec/ | ||
1338 | L: linux-kernel@vger.kernel.org | ||
1339 | L: fastboot@osdl.org | ||
1340 | S: Maintained | ||
1341 | |||
1333 | LANMEDIA WAN CARD DRIVER | 1342 | LANMEDIA WAN CARD DRIVER |
1334 | P: Andrew Stanley-Jones | 1343 | P: Andrew Stanley-Jones |
1335 | M: asj@lanmedia.com | 1344 | M: asj@lanmedia.com |
@@ -2115,9 +2124,7 @@ S: Maintained | |||
2115 | SOFTWARE SUSPEND: | 2124 | SOFTWARE SUSPEND: |
2116 | P: Pavel Machek | 2125 | P: Pavel Machek |
2117 | M: pavel@suse.cz | 2126 | M: pavel@suse.cz |
2118 | M: pavel@ucw.cz | 2127 | L: linux-pm@osdl.org |
2119 | L: http://lister.fornax.hu/mailman/listinfo/swsusp | ||
2120 | W: http://swsusp.sf.net/ | ||
2121 | S: Maintained | 2128 | S: Maintained |
2122 | 2129 | ||
2123 | SONIC NETWORK DRIVER | 2130 | SONIC NETWORK DRIVER |
@@ -2594,7 +2601,7 @@ M: davidm@snapgear.com | |||
2594 | P: D. Jeff Dionne (created first uClinux port) | 2601 | P: D. Jeff Dionne (created first uClinux port) |
2595 | M: jeff@uclinux.org | 2602 | M: jeff@uclinux.org |
2596 | W: http://www.uclinux.org/ | 2603 | W: http://www.uclinux.org/ |
2597 | L: uclinux-dev@uclinux.org | 2604 | L: uclinux-dev@uclinux.org (subscribers-only) |
2598 | S: Maintained | 2605 | S: Maintained |
2599 | 2606 | ||
2600 | UCLINUX FOR NEC V850 | 2607 | UCLINUX FOR NEC V850 |
@@ -281,7 +281,7 @@ export quiet Q KBUILD_VERBOSE | |||
281 | # See documentation in Documentation/kbuild/makefiles.txt | 281 | # See documentation in Documentation/kbuild/makefiles.txt |
282 | 282 | ||
283 | # cc-option | 283 | # cc-option |
284 | # Usage: cflags-y += $(call gcc-option, -march=winchip-c6, -march=i586) | 284 | # Usage: cflags-y += $(call cc-option, -march=winchip-c6, -march=i586) |
285 | 285 | ||
286 | cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \ | 286 | cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \ |
287 | > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;) | 287 | > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;) |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 07ba77c19f6c..c8d94dcd8ef7 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -157,7 +157,7 @@ config ARCH_RPC | |||
157 | config ARCH_SA1100 | 157 | config ARCH_SA1100 |
158 | bool "SA1100-based" | 158 | bool "SA1100-based" |
159 | select ISA | 159 | select ISA |
160 | select DISCONTIGMEM | 160 | select ARCH_DISCONTIGMEM_ENABLE |
161 | 161 | ||
162 | config ARCH_S3C2410 | 162 | config ARCH_S3C2410 |
163 | bool "Samsung S3C2410" | 163 | bool "Samsung S3C2410" |
@@ -346,6 +346,21 @@ config PREEMPT | |||
346 | Say Y here if you are building a kernel for a desktop, embedded | 346 | Say Y here if you are building a kernel for a desktop, embedded |
347 | or real-time system. Say N if you are unsure. | 347 | or real-time system. Say N if you are unsure. |
348 | 348 | ||
349 | config NO_IDLE_HZ | ||
350 | bool "Dynamic tick timer" | ||
351 | help | ||
352 | Select this option if you want to disable continuous timer ticks | ||
353 | and have them programmed to occur as required. This option saves | ||
354 | power as the system can remain in idle state for longer. | ||
355 | |||
356 | By default dynamic tick is disabled during the boot, and can be | ||
357 | manually enabled with: | ||
358 | |||
359 | echo 1 > /sys/devices/system/timer/timer0/dyn_tick | ||
360 | |||
361 | Alternatively, if you want dynamic tick automatically enabled | ||
362 | during boot, pass "dyntick=enable" via the kernel command string. | ||
363 | |||
349 | config ARCH_DISCONTIGMEM_ENABLE | 364 | config ARCH_DISCONTIGMEM_ENABLE |
350 | bool | 365 | bool |
351 | default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM) | 366 | default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM) |
diff --git a/arch/arm/configs/enp2611_defconfig b/arch/arm/configs/enp2611_defconfig index 06fae4b62774..b8c51ee7f1bb 100644 --- a/arch/arm/configs/enp2611_defconfig +++ b/arch/arm/configs/enp2611_defconfig | |||
@@ -1,14 +1,13 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.12-rc1-bk2 | 3 | # Linux kernel version: 2.6.12-git6 |
4 | # Sun Mar 27 22:08:24 2005 | 4 | # Sat Jun 25 00:57:29 2005 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
8 | CONFIG_UID16=y | 8 | CONFIG_UID16=y |
9 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | 9 | CONFIG_RWSEM_GENERIC_SPINLOCK=y |
10 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 10 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
11 | CONFIG_GENERIC_IOMAP=y | ||
12 | 11 | ||
13 | # | 12 | # |
14 | # Code maturity level options | 13 | # Code maturity level options |
@@ -16,6 +15,7 @@ CONFIG_GENERIC_IOMAP=y | |||
16 | CONFIG_EXPERIMENTAL=y | 15 | CONFIG_EXPERIMENTAL=y |
17 | CONFIG_CLEAN_COMPILE=y | 16 | CONFIG_CLEAN_COMPILE=y |
18 | CONFIG_BROKEN_ON_SMP=y | 17 | CONFIG_BROKEN_ON_SMP=y |
18 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
19 | 19 | ||
20 | # | 20 | # |
21 | # General setup | 21 | # General setup |
@@ -35,6 +35,8 @@ CONFIG_EMBEDDED=y | |||
35 | CONFIG_KALLSYMS=y | 35 | CONFIG_KALLSYMS=y |
36 | # CONFIG_KALLSYMS_ALL is not set | 36 | # CONFIG_KALLSYMS_ALL is not set |
37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
38 | CONFIG_PRINTK=y | ||
39 | CONFIG_BUG=y | ||
38 | CONFIG_BASE_FULL=y | 40 | CONFIG_BASE_FULL=y |
39 | CONFIG_FUTEX=y | 41 | CONFIG_FUTEX=y |
40 | CONFIG_EPOLL=y | 42 | CONFIG_EPOLL=y |
@@ -82,6 +84,7 @@ CONFIG_ARCH_IXP2000=y | |||
82 | # CONFIG_ARCH_VERSATILE is not set | 84 | # CONFIG_ARCH_VERSATILE is not set |
83 | # CONFIG_ARCH_IMX is not set | 85 | # CONFIG_ARCH_IMX is not set |
84 | # CONFIG_ARCH_H720X is not set | 86 | # CONFIG_ARCH_H720X is not set |
87 | # CONFIG_ARCH_AAEC2000 is not set | ||
85 | CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y | 88 | CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y |
86 | 89 | ||
87 | # | 90 | # |
@@ -96,6 +99,7 @@ CONFIG_ARCH_ENP2611=y | |||
96 | # CONFIG_ARCH_IXDP2800 is not set | 99 | # CONFIG_ARCH_IXDP2800 is not set |
97 | # CONFIG_ARCH_IXDP2401 is not set | 100 | # CONFIG_ARCH_IXDP2401 is not set |
98 | # CONFIG_ARCH_IXDP2801 is not set | 101 | # CONFIG_ARCH_IXDP2801 is not set |
102 | # CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set | ||
99 | 103 | ||
100 | # | 104 | # |
101 | # Processor Type | 105 | # Processor Type |
@@ -106,7 +110,6 @@ CONFIG_CPU_32v5=y | |||
106 | CONFIG_CPU_ABRT_EV5T=y | 110 | CONFIG_CPU_ABRT_EV5T=y |
107 | CONFIG_CPU_CACHE_VIVT=y | 111 | CONFIG_CPU_CACHE_VIVT=y |
108 | CONFIG_CPU_TLB_V4WBI=y | 112 | CONFIG_CPU_TLB_V4WBI=y |
109 | CONFIG_CPU_MINICACHE=y | ||
110 | 113 | ||
111 | # | 114 | # |
112 | # Processor Features | 115 | # Processor Features |
@@ -118,9 +121,11 @@ CONFIG_XSCALE_PMU=y | |||
118 | # | 121 | # |
119 | # Bus support | 122 | # Bus support |
120 | # | 123 | # |
124 | CONFIG_ISA_DMA_API=y | ||
121 | CONFIG_PCI=y | 125 | CONFIG_PCI=y |
122 | CONFIG_PCI_LEGACY_PROC=y | 126 | CONFIG_PCI_LEGACY_PROC=y |
123 | CONFIG_PCI_NAMES=y | 127 | CONFIG_PCI_NAMES=y |
128 | # CONFIG_PCI_DEBUG is not set | ||
124 | 129 | ||
125 | # | 130 | # |
126 | # PCCARD (PCMCIA/CardBus) support | 131 | # PCCARD (PCMCIA/CardBus) support |
@@ -130,7 +135,15 @@ CONFIG_PCI_NAMES=y | |||
130 | # | 135 | # |
131 | # Kernel Features | 136 | # Kernel Features |
132 | # | 137 | # |
138 | # CONFIG_SMP is not set | ||
133 | # CONFIG_PREEMPT is not set | 139 | # CONFIG_PREEMPT is not set |
140 | # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set | ||
141 | CONFIG_SELECT_MEMORY_MODEL=y | ||
142 | CONFIG_FLATMEM_MANUAL=y | ||
143 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
144 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
145 | CONFIG_FLATMEM=y | ||
146 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
134 | CONFIG_ALIGNMENT_TRAP=y | 147 | CONFIG_ALIGNMENT_TRAP=y |
135 | 148 | ||
136 | # | 149 | # |
@@ -269,7 +282,6 @@ CONFIG_MTD_IXP2000=y | |||
269 | # | 282 | # |
270 | # Block devices | 283 | # Block devices |
271 | # | 284 | # |
272 | # CONFIG_BLK_DEV_FD is not set | ||
273 | # CONFIG_BLK_CPQ_DA is not set | 285 | # CONFIG_BLK_CPQ_DA is not set |
274 | # CONFIG_BLK_CPQ_CISS_DA is not set | 286 | # CONFIG_BLK_CPQ_CISS_DA is not set |
275 | # CONFIG_BLK_DEV_DAC960 is not set | 287 | # CONFIG_BLK_DEV_DAC960 is not set |
@@ -308,6 +320,7 @@ CONFIG_IOSCHED_CFQ=y | |||
308 | # | 320 | # |
309 | # Fusion MPT device support | 321 | # Fusion MPT device support |
310 | # | 322 | # |
323 | # CONFIG_FUSION is not set | ||
311 | 324 | ||
312 | # | 325 | # |
313 | # IEEE 1394 (FireWire) support | 326 | # IEEE 1394 (FireWire) support |
@@ -329,10 +342,11 @@ CONFIG_NET=y | |||
329 | # | 342 | # |
330 | CONFIG_PACKET=y | 343 | CONFIG_PACKET=y |
331 | CONFIG_PACKET_MMAP=y | 344 | CONFIG_PACKET_MMAP=y |
332 | # CONFIG_NETLINK_DEV is not set | ||
333 | CONFIG_UNIX=y | 345 | CONFIG_UNIX=y |
334 | # CONFIG_NET_KEY is not set | 346 | # CONFIG_NET_KEY is not set |
335 | CONFIG_INET=y | 347 | CONFIG_INET=y |
348 | CONFIG_IP_FIB_HASH=y | ||
349 | # CONFIG_IP_FIB_TRIE is not set | ||
336 | # CONFIG_IP_MULTICAST is not set | 350 | # CONFIG_IP_MULTICAST is not set |
337 | # CONFIG_IP_ADVANCED_ROUTER is not set | 351 | # CONFIG_IP_ADVANCED_ROUTER is not set |
338 | CONFIG_IP_PNP=y | 352 | CONFIG_IP_PNP=y |
@@ -349,6 +363,17 @@ CONFIG_SYN_COOKIES=y | |||
349 | # CONFIG_INET_TUNNEL is not set | 363 | # CONFIG_INET_TUNNEL is not set |
350 | # CONFIG_IP_TCPDIAG is not set | 364 | # CONFIG_IP_TCPDIAG is not set |
351 | # CONFIG_IP_TCPDIAG_IPV6 is not set | 365 | # CONFIG_IP_TCPDIAG_IPV6 is not set |
366 | |||
367 | # | ||
368 | # TCP congestion control | ||
369 | # | ||
370 | CONFIG_TCP_CONG_BIC=y | ||
371 | CONFIG_TCP_CONG_WESTWOOD=m | ||
372 | CONFIG_TCP_CONG_HTCP=m | ||
373 | # CONFIG_TCP_CONG_HSTCP is not set | ||
374 | # CONFIG_TCP_CONG_HYBLA is not set | ||
375 | # CONFIG_TCP_CONG_VEGAS is not set | ||
376 | # CONFIG_TCP_CONG_SCALABLE is not set | ||
352 | # CONFIG_IPV6 is not set | 377 | # CONFIG_IPV6 is not set |
353 | # CONFIG_NETFILTER is not set | 378 | # CONFIG_NETFILTER is not set |
354 | 379 | ||
@@ -404,6 +429,7 @@ CONFIG_MII=y | |||
404 | # CONFIG_SUNGEM is not set | 429 | # CONFIG_SUNGEM is not set |
405 | # CONFIG_NET_VENDOR_3COM is not set | 430 | # CONFIG_NET_VENDOR_3COM is not set |
406 | # CONFIG_SMC91X is not set | 431 | # CONFIG_SMC91X is not set |
432 | # CONFIG_DM9000 is not set | ||
407 | 433 | ||
408 | # | 434 | # |
409 | # Tulip family network device support | 435 | # Tulip family network device support |
@@ -440,9 +466,11 @@ CONFIG_EEPRO100=y | |||
440 | # CONFIG_HAMACHI is not set | 466 | # CONFIG_HAMACHI is not set |
441 | # CONFIG_YELLOWFIN is not set | 467 | # CONFIG_YELLOWFIN is not set |
442 | # CONFIG_R8169 is not set | 468 | # CONFIG_R8169 is not set |
469 | # CONFIG_SKGE is not set | ||
443 | # CONFIG_SK98LIN is not set | 470 | # CONFIG_SK98LIN is not set |
444 | # CONFIG_VIA_VELOCITY is not set | 471 | # CONFIG_VIA_VELOCITY is not set |
445 | # CONFIG_TIGON3 is not set | 472 | # CONFIG_TIGON3 is not set |
473 | # CONFIG_BNX2 is not set | ||
446 | 474 | ||
447 | # | 475 | # |
448 | # Ethernet (10000 Mbit) | 476 | # Ethernet (10000 Mbit) |
@@ -464,6 +492,7 @@ CONFIG_EEPRO100=y | |||
464 | # Wan interfaces | 492 | # Wan interfaces |
465 | # | 493 | # |
466 | CONFIG_WAN=y | 494 | CONFIG_WAN=y |
495 | # CONFIG_DSCC4 is not set | ||
467 | # CONFIG_LANMEDIA is not set | 496 | # CONFIG_LANMEDIA is not set |
468 | # CONFIG_SYNCLINK_SYNCPPP is not set | 497 | # CONFIG_SYNCLINK_SYNCPPP is not set |
469 | CONFIG_HDLC=y | 498 | CONFIG_HDLC=y |
@@ -526,7 +555,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | |||
526 | # | 555 | # |
527 | # CONFIG_SERIO is not set | 556 | # CONFIG_SERIO is not set |
528 | # CONFIG_GAMEPORT is not set | 557 | # CONFIG_GAMEPORT is not set |
529 | CONFIG_SOUND_GAMEPORT=y | ||
530 | 558 | ||
531 | # | 559 | # |
532 | # Character devices | 560 | # Character devices |
@@ -547,6 +575,7 @@ CONFIG_SERIAL_8250_NR_UARTS=2 | |||
547 | # | 575 | # |
548 | CONFIG_SERIAL_CORE=y | 576 | CONFIG_SERIAL_CORE=y |
549 | CONFIG_SERIAL_CORE_CONSOLE=y | 577 | CONFIG_SERIAL_CORE_CONSOLE=y |
578 | # CONFIG_SERIAL_JSM is not set | ||
550 | CONFIG_UNIX98_PTYS=y | 579 | CONFIG_UNIX98_PTYS=y |
551 | CONFIG_LEGACY_PTYS=y | 580 | CONFIG_LEGACY_PTYS=y |
552 | CONFIG_LEGACY_PTY_COUNT=256 | 581 | CONFIG_LEGACY_PTY_COUNT=256 |
@@ -613,17 +642,18 @@ CONFIG_I2C_ALGOBIT=y | |||
613 | # CONFIG_I2C_AMD8111 is not set | 642 | # CONFIG_I2C_AMD8111 is not set |
614 | # CONFIG_I2C_I801 is not set | 643 | # CONFIG_I2C_I801 is not set |
615 | # CONFIG_I2C_I810 is not set | 644 | # CONFIG_I2C_I810 is not set |
645 | # CONFIG_I2C_PIIX4 is not set | ||
616 | # CONFIG_I2C_ISA is not set | 646 | # CONFIG_I2C_ISA is not set |
617 | # CONFIG_I2C_IXP2000 is not set | 647 | # CONFIG_I2C_IXP2000 is not set |
618 | # CONFIG_I2C_NFORCE2 is not set | 648 | # CONFIG_I2C_NFORCE2 is not set |
619 | # CONFIG_I2C_PARPORT_LIGHT is not set | 649 | # CONFIG_I2C_PARPORT_LIGHT is not set |
620 | # CONFIG_I2C_PIIX4 is not set | ||
621 | # CONFIG_I2C_PROSAVAGE is not set | 650 | # CONFIG_I2C_PROSAVAGE is not set |
622 | # CONFIG_I2C_SAVAGE4 is not set | 651 | # CONFIG_I2C_SAVAGE4 is not set |
623 | # CONFIG_SCx200_ACB is not set | 652 | # CONFIG_SCx200_ACB is not set |
624 | # CONFIG_I2C_SIS5595 is not set | 653 | # CONFIG_I2C_SIS5595 is not set |
625 | # CONFIG_I2C_SIS630 is not set | 654 | # CONFIG_I2C_SIS630 is not set |
626 | # CONFIG_I2C_SIS96X is not set | 655 | # CONFIG_I2C_SIS96X is not set |
656 | # CONFIG_I2C_STUB is not set | ||
627 | # CONFIG_I2C_VIA is not set | 657 | # CONFIG_I2C_VIA is not set |
628 | # CONFIG_I2C_VIAPRO is not set | 658 | # CONFIG_I2C_VIAPRO is not set |
629 | # CONFIG_I2C_VOODOO3 is not set | 659 | # CONFIG_I2C_VOODOO3 is not set |
@@ -637,7 +667,9 @@ CONFIG_I2C_SENSOR=y | |||
637 | # CONFIG_SENSORS_ADM1025 is not set | 667 | # CONFIG_SENSORS_ADM1025 is not set |
638 | # CONFIG_SENSORS_ADM1026 is not set | 668 | # CONFIG_SENSORS_ADM1026 is not set |
639 | # CONFIG_SENSORS_ADM1031 is not set | 669 | # CONFIG_SENSORS_ADM1031 is not set |
670 | # CONFIG_SENSORS_ADM9240 is not set | ||
640 | # CONFIG_SENSORS_ASB100 is not set | 671 | # CONFIG_SENSORS_ASB100 is not set |
672 | # CONFIG_SENSORS_ATXP1 is not set | ||
641 | # CONFIG_SENSORS_DS1621 is not set | 673 | # CONFIG_SENSORS_DS1621 is not set |
642 | # CONFIG_SENSORS_FSCHER is not set | 674 | # CONFIG_SENSORS_FSCHER is not set |
643 | # CONFIG_SENSORS_FSCPOS is not set | 675 | # CONFIG_SENSORS_FSCPOS is not set |
@@ -653,6 +685,7 @@ CONFIG_I2C_SENSOR=y | |||
653 | # CONFIG_SENSORS_LM85 is not set | 685 | # CONFIG_SENSORS_LM85 is not set |
654 | # CONFIG_SENSORS_LM87 is not set | 686 | # CONFIG_SENSORS_LM87 is not set |
655 | # CONFIG_SENSORS_LM90 is not set | 687 | # CONFIG_SENSORS_LM90 is not set |
688 | # CONFIG_SENSORS_LM92 is not set | ||
656 | # CONFIG_SENSORS_MAX1619 is not set | 689 | # CONFIG_SENSORS_MAX1619 is not set |
657 | # CONFIG_SENSORS_PC87360 is not set | 690 | # CONFIG_SENSORS_PC87360 is not set |
658 | # CONFIG_SENSORS_SMSC47B397 is not set | 691 | # CONFIG_SENSORS_SMSC47B397 is not set |
@@ -662,14 +695,19 @@ CONFIG_I2C_SENSOR=y | |||
662 | # CONFIG_SENSORS_W83781D is not set | 695 | # CONFIG_SENSORS_W83781D is not set |
663 | # CONFIG_SENSORS_W83L785TS is not set | 696 | # CONFIG_SENSORS_W83L785TS is not set |
664 | # CONFIG_SENSORS_W83627HF is not set | 697 | # CONFIG_SENSORS_W83627HF is not set |
698 | # CONFIG_SENSORS_W83627EHF is not set | ||
665 | 699 | ||
666 | # | 700 | # |
667 | # Other I2C Chip support | 701 | # Other I2C Chip support |
668 | # | 702 | # |
703 | # CONFIG_SENSORS_DS1337 is not set | ||
704 | # CONFIG_SENSORS_DS1374 is not set | ||
669 | CONFIG_SENSORS_EEPROM=y | 705 | CONFIG_SENSORS_EEPROM=y |
670 | # CONFIG_SENSORS_PCF8574 is not set | 706 | # CONFIG_SENSORS_PCF8574 is not set |
707 | # CONFIG_SENSORS_PCA9539 is not set | ||
671 | # CONFIG_SENSORS_PCF8591 is not set | 708 | # CONFIG_SENSORS_PCF8591 is not set |
672 | # CONFIG_SENSORS_RTC8564 is not set | 709 | # CONFIG_SENSORS_RTC8564 is not set |
710 | # CONFIG_SENSORS_MAX6875 is not set | ||
673 | # CONFIG_I2C_DEBUG_CORE is not set | 711 | # CONFIG_I2C_DEBUG_CORE is not set |
674 | # CONFIG_I2C_DEBUG_ALGO is not set | 712 | # CONFIG_I2C_DEBUG_ALGO is not set |
675 | # CONFIG_I2C_DEBUG_BUS is not set | 713 | # CONFIG_I2C_DEBUG_BUS is not set |
@@ -723,6 +761,7 @@ CONFIG_EXT2_FS=y | |||
723 | CONFIG_EXT2_FS_XATTR=y | 761 | CONFIG_EXT2_FS_XATTR=y |
724 | CONFIG_EXT2_FS_POSIX_ACL=y | 762 | CONFIG_EXT2_FS_POSIX_ACL=y |
725 | # CONFIG_EXT2_FS_SECURITY is not set | 763 | # CONFIG_EXT2_FS_SECURITY is not set |
764 | # CONFIG_EXT2_FS_XIP is not set | ||
726 | CONFIG_EXT3_FS=y | 765 | CONFIG_EXT3_FS=y |
727 | CONFIG_EXT3_FS_XATTR=y | 766 | CONFIG_EXT3_FS_XATTR=y |
728 | CONFIG_EXT3_FS_POSIX_ACL=y | 767 | CONFIG_EXT3_FS_POSIX_ACL=y |
@@ -763,7 +802,6 @@ CONFIG_DNOTIFY=y | |||
763 | # | 802 | # |
764 | CONFIG_PROC_FS=y | 803 | CONFIG_PROC_FS=y |
765 | CONFIG_SYSFS=y | 804 | CONFIG_SYSFS=y |
766 | # CONFIG_DEVFS_FS is not set | ||
767 | # CONFIG_DEVPTS_FS_XATTR is not set | 805 | # CONFIG_DEVPTS_FS_XATTR is not set |
768 | CONFIG_TMPFS=y | 806 | CONFIG_TMPFS=y |
769 | # CONFIG_TMPFS_XATTR is not set | 807 | # CONFIG_TMPFS_XATTR is not set |
@@ -801,12 +839,14 @@ CONFIG_JFFS2_RTIME=y | |||
801 | # | 839 | # |
802 | CONFIG_NFS_FS=y | 840 | CONFIG_NFS_FS=y |
803 | CONFIG_NFS_V3=y | 841 | CONFIG_NFS_V3=y |
842 | # CONFIG_NFS_V3_ACL is not set | ||
804 | # CONFIG_NFS_V4 is not set | 843 | # CONFIG_NFS_V4 is not set |
805 | # CONFIG_NFS_DIRECTIO is not set | 844 | # CONFIG_NFS_DIRECTIO is not set |
806 | # CONFIG_NFSD is not set | 845 | # CONFIG_NFSD is not set |
807 | CONFIG_ROOT_NFS=y | 846 | CONFIG_ROOT_NFS=y |
808 | CONFIG_LOCKD=y | 847 | CONFIG_LOCKD=y |
809 | CONFIG_LOCKD_V4=y | 848 | CONFIG_LOCKD_V4=y |
849 | CONFIG_NFS_COMMON=y | ||
810 | CONFIG_SUNRPC=y | 850 | CONFIG_SUNRPC=y |
811 | # CONFIG_RPCSEC_GSS_KRB5 is not set | 851 | # CONFIG_RPCSEC_GSS_KRB5 is not set |
812 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | 852 | # CONFIG_RPCSEC_GSS_SPKM3 is not set |
@@ -891,3 +931,4 @@ CONFIG_CRC32=y | |||
891 | # CONFIG_LIBCRC32C is not set | 931 | # CONFIG_LIBCRC32C is not set |
892 | CONFIG_ZLIB_INFLATE=y | 932 | CONFIG_ZLIB_INFLATE=y |
893 | CONFIG_ZLIB_DEFLATE=y | 933 | CONFIG_ZLIB_DEFLATE=y |
934 | # CONFIG_TEXTSEARCH is not set | ||
diff --git a/arch/arm/configs/ixdp2400_defconfig b/arch/arm/configs/ixdp2400_defconfig index 810a450a55d2..3cfbe2ec29ca 100644 --- a/arch/arm/configs/ixdp2400_defconfig +++ b/arch/arm/configs/ixdp2400_defconfig | |||
@@ -1,14 +1,13 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.12-rc1-bk2 | 3 | # Linux kernel version: 2.6.12-git6 |
4 | # Sun Mar 27 21:13:38 2005 | 4 | # Sat Jun 25 00:58:38 2005 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
8 | CONFIG_UID16=y | 8 | CONFIG_UID16=y |
9 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | 9 | CONFIG_RWSEM_GENERIC_SPINLOCK=y |
10 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 10 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
11 | CONFIG_GENERIC_IOMAP=y | ||
12 | 11 | ||
13 | # | 12 | # |
14 | # Code maturity level options | 13 | # Code maturity level options |
@@ -16,6 +15,7 @@ CONFIG_GENERIC_IOMAP=y | |||
16 | CONFIG_EXPERIMENTAL=y | 15 | CONFIG_EXPERIMENTAL=y |
17 | CONFIG_CLEAN_COMPILE=y | 16 | CONFIG_CLEAN_COMPILE=y |
18 | CONFIG_BROKEN_ON_SMP=y | 17 | CONFIG_BROKEN_ON_SMP=y |
18 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
19 | 19 | ||
20 | # | 20 | # |
21 | # General setup | 21 | # General setup |
@@ -35,6 +35,8 @@ CONFIG_EMBEDDED=y | |||
35 | CONFIG_KALLSYMS=y | 35 | CONFIG_KALLSYMS=y |
36 | # CONFIG_KALLSYMS_ALL is not set | 36 | # CONFIG_KALLSYMS_ALL is not set |
37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
38 | CONFIG_PRINTK=y | ||
39 | CONFIG_BUG=y | ||
38 | CONFIG_BASE_FULL=y | 40 | CONFIG_BASE_FULL=y |
39 | CONFIG_FUTEX=y | 41 | CONFIG_FUTEX=y |
40 | CONFIG_EPOLL=y | 42 | CONFIG_EPOLL=y |
@@ -82,6 +84,7 @@ CONFIG_ARCH_IXP2000=y | |||
82 | # CONFIG_ARCH_VERSATILE is not set | 84 | # CONFIG_ARCH_VERSATILE is not set |
83 | # CONFIG_ARCH_IMX is not set | 85 | # CONFIG_ARCH_IMX is not set |
84 | # CONFIG_ARCH_H720X is not set | 86 | # CONFIG_ARCH_H720X is not set |
87 | # CONFIG_ARCH_AAEC2000 is not set | ||
85 | CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y | 88 | CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y |
86 | 89 | ||
87 | # | 90 | # |
@@ -97,6 +100,7 @@ CONFIG_ARCH_IXDP2400=y | |||
97 | CONFIG_ARCH_IXDP2X00=y | 100 | CONFIG_ARCH_IXDP2X00=y |
98 | # CONFIG_ARCH_IXDP2401 is not set | 101 | # CONFIG_ARCH_IXDP2401 is not set |
99 | # CONFIG_ARCH_IXDP2801 is not set | 102 | # CONFIG_ARCH_IXDP2801 is not set |
103 | # CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set | ||
100 | 104 | ||
101 | # | 105 | # |
102 | # Processor Type | 106 | # Processor Type |
@@ -107,7 +111,6 @@ CONFIG_CPU_32v5=y | |||
107 | CONFIG_CPU_ABRT_EV5T=y | 111 | CONFIG_CPU_ABRT_EV5T=y |
108 | CONFIG_CPU_CACHE_VIVT=y | 112 | CONFIG_CPU_CACHE_VIVT=y |
109 | CONFIG_CPU_TLB_V4WBI=y | 113 | CONFIG_CPU_TLB_V4WBI=y |
110 | CONFIG_CPU_MINICACHE=y | ||
111 | 114 | ||
112 | # | 115 | # |
113 | # Processor Features | 116 | # Processor Features |
@@ -119,9 +122,11 @@ CONFIG_XSCALE_PMU=y | |||
119 | # | 122 | # |
120 | # Bus support | 123 | # Bus support |
121 | # | 124 | # |
125 | CONFIG_ISA_DMA_API=y | ||
122 | CONFIG_PCI=y | 126 | CONFIG_PCI=y |
123 | CONFIG_PCI_LEGACY_PROC=y | 127 | CONFIG_PCI_LEGACY_PROC=y |
124 | CONFIG_PCI_NAMES=y | 128 | CONFIG_PCI_NAMES=y |
129 | # CONFIG_PCI_DEBUG is not set | ||
125 | 130 | ||
126 | # | 131 | # |
127 | # PCCARD (PCMCIA/CardBus) support | 132 | # PCCARD (PCMCIA/CardBus) support |
@@ -131,7 +136,15 @@ CONFIG_PCI_NAMES=y | |||
131 | # | 136 | # |
132 | # Kernel Features | 137 | # Kernel Features |
133 | # | 138 | # |
139 | # CONFIG_SMP is not set | ||
134 | # CONFIG_PREEMPT is not set | 140 | # CONFIG_PREEMPT is not set |
141 | # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set | ||
142 | CONFIG_SELECT_MEMORY_MODEL=y | ||
143 | CONFIG_FLATMEM_MANUAL=y | ||
144 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
145 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
146 | CONFIG_FLATMEM=y | ||
147 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
135 | CONFIG_ALIGNMENT_TRAP=y | 148 | CONFIG_ALIGNMENT_TRAP=y |
136 | 149 | ||
137 | # | 150 | # |
@@ -270,7 +283,6 @@ CONFIG_MTD_IXP2000=y | |||
270 | # | 283 | # |
271 | # Block devices | 284 | # Block devices |
272 | # | 285 | # |
273 | # CONFIG_BLK_DEV_FD is not set | ||
274 | # CONFIG_BLK_CPQ_DA is not set | 286 | # CONFIG_BLK_CPQ_DA is not set |
275 | # CONFIG_BLK_CPQ_CISS_DA is not set | 287 | # CONFIG_BLK_CPQ_CISS_DA is not set |
276 | # CONFIG_BLK_DEV_DAC960 is not set | 288 | # CONFIG_BLK_DEV_DAC960 is not set |
@@ -309,6 +321,7 @@ CONFIG_IOSCHED_CFQ=y | |||
309 | # | 321 | # |
310 | # Fusion MPT device support | 322 | # Fusion MPT device support |
311 | # | 323 | # |
324 | # CONFIG_FUSION is not set | ||
312 | 325 | ||
313 | # | 326 | # |
314 | # IEEE 1394 (FireWire) support | 327 | # IEEE 1394 (FireWire) support |
@@ -330,10 +343,11 @@ CONFIG_NET=y | |||
330 | # | 343 | # |
331 | CONFIG_PACKET=y | 344 | CONFIG_PACKET=y |
332 | CONFIG_PACKET_MMAP=y | 345 | CONFIG_PACKET_MMAP=y |
333 | # CONFIG_NETLINK_DEV is not set | ||
334 | CONFIG_UNIX=y | 346 | CONFIG_UNIX=y |
335 | # CONFIG_NET_KEY is not set | 347 | # CONFIG_NET_KEY is not set |
336 | CONFIG_INET=y | 348 | CONFIG_INET=y |
349 | CONFIG_IP_FIB_HASH=y | ||
350 | # CONFIG_IP_FIB_TRIE is not set | ||
337 | # CONFIG_IP_MULTICAST is not set | 351 | # CONFIG_IP_MULTICAST is not set |
338 | # CONFIG_IP_ADVANCED_ROUTER is not set | 352 | # CONFIG_IP_ADVANCED_ROUTER is not set |
339 | CONFIG_IP_PNP=y | 353 | CONFIG_IP_PNP=y |
@@ -350,6 +364,17 @@ CONFIG_SYN_COOKIES=y | |||
350 | # CONFIG_INET_TUNNEL is not set | 364 | # CONFIG_INET_TUNNEL is not set |
351 | # CONFIG_IP_TCPDIAG is not set | 365 | # CONFIG_IP_TCPDIAG is not set |
352 | # CONFIG_IP_TCPDIAG_IPV6 is not set | 366 | # CONFIG_IP_TCPDIAG_IPV6 is not set |
367 | |||
368 | # | ||
369 | # TCP congestion control | ||
370 | # | ||
371 | CONFIG_TCP_CONG_BIC=y | ||
372 | CONFIG_TCP_CONG_WESTWOOD=m | ||
373 | CONFIG_TCP_CONG_HTCP=m | ||
374 | # CONFIG_TCP_CONG_HSTCP is not set | ||
375 | # CONFIG_TCP_CONG_HYBLA is not set | ||
376 | # CONFIG_TCP_CONG_VEGAS is not set | ||
377 | # CONFIG_TCP_CONG_SCALABLE is not set | ||
353 | # CONFIG_IPV6 is not set | 378 | # CONFIG_IPV6 is not set |
354 | # CONFIG_NETFILTER is not set | 379 | # CONFIG_NETFILTER is not set |
355 | 380 | ||
@@ -405,6 +430,7 @@ CONFIG_MII=y | |||
405 | # CONFIG_SUNGEM is not set | 430 | # CONFIG_SUNGEM is not set |
406 | # CONFIG_NET_VENDOR_3COM is not set | 431 | # CONFIG_NET_VENDOR_3COM is not set |
407 | # CONFIG_SMC91X is not set | 432 | # CONFIG_SMC91X is not set |
433 | # CONFIG_DM9000 is not set | ||
408 | 434 | ||
409 | # | 435 | # |
410 | # Tulip family network device support | 436 | # Tulip family network device support |
@@ -441,9 +467,11 @@ CONFIG_EEPRO100=y | |||
441 | # CONFIG_HAMACHI is not set | 467 | # CONFIG_HAMACHI is not set |
442 | # CONFIG_YELLOWFIN is not set | 468 | # CONFIG_YELLOWFIN is not set |
443 | # CONFIG_R8169 is not set | 469 | # CONFIG_R8169 is not set |
470 | # CONFIG_SKGE is not set | ||
444 | # CONFIG_SK98LIN is not set | 471 | # CONFIG_SK98LIN is not set |
445 | # CONFIG_VIA_VELOCITY is not set | 472 | # CONFIG_VIA_VELOCITY is not set |
446 | # CONFIG_TIGON3 is not set | 473 | # CONFIG_TIGON3 is not set |
474 | # CONFIG_BNX2 is not set | ||
447 | 475 | ||
448 | # | 476 | # |
449 | # Ethernet (10000 Mbit) | 477 | # Ethernet (10000 Mbit) |
@@ -465,6 +493,7 @@ CONFIG_EEPRO100=y | |||
465 | # Wan interfaces | 493 | # Wan interfaces |
466 | # | 494 | # |
467 | CONFIG_WAN=y | 495 | CONFIG_WAN=y |
496 | # CONFIG_DSCC4 is not set | ||
468 | # CONFIG_LANMEDIA is not set | 497 | # CONFIG_LANMEDIA is not set |
469 | # CONFIG_SYNCLINK_SYNCPPP is not set | 498 | # CONFIG_SYNCLINK_SYNCPPP is not set |
470 | CONFIG_HDLC=y | 499 | CONFIG_HDLC=y |
@@ -527,7 +556,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | |||
527 | # | 556 | # |
528 | # CONFIG_SERIO is not set | 557 | # CONFIG_SERIO is not set |
529 | # CONFIG_GAMEPORT is not set | 558 | # CONFIG_GAMEPORT is not set |
530 | CONFIG_SOUND_GAMEPORT=y | ||
531 | 559 | ||
532 | # | 560 | # |
533 | # Character devices | 561 | # Character devices |
@@ -548,6 +576,7 @@ CONFIG_SERIAL_8250_NR_UARTS=2 | |||
548 | # | 576 | # |
549 | CONFIG_SERIAL_CORE=y | 577 | CONFIG_SERIAL_CORE=y |
550 | CONFIG_SERIAL_CORE_CONSOLE=y | 578 | CONFIG_SERIAL_CORE_CONSOLE=y |
579 | # CONFIG_SERIAL_JSM is not set | ||
551 | CONFIG_UNIX98_PTYS=y | 580 | CONFIG_UNIX98_PTYS=y |
552 | CONFIG_LEGACY_PTYS=y | 581 | CONFIG_LEGACY_PTYS=y |
553 | CONFIG_LEGACY_PTY_COUNT=256 | 582 | CONFIG_LEGACY_PTY_COUNT=256 |
@@ -614,17 +643,18 @@ CONFIG_I2C_ALGOBIT=y | |||
614 | # CONFIG_I2C_AMD8111 is not set | 643 | # CONFIG_I2C_AMD8111 is not set |
615 | # CONFIG_I2C_I801 is not set | 644 | # CONFIG_I2C_I801 is not set |
616 | # CONFIG_I2C_I810 is not set | 645 | # CONFIG_I2C_I810 is not set |
646 | # CONFIG_I2C_PIIX4 is not set | ||
617 | # CONFIG_I2C_ISA is not set | 647 | # CONFIG_I2C_ISA is not set |
618 | # CONFIG_I2C_IXP2000 is not set | 648 | # CONFIG_I2C_IXP2000 is not set |
619 | # CONFIG_I2C_NFORCE2 is not set | 649 | # CONFIG_I2C_NFORCE2 is not set |
620 | # CONFIG_I2C_PARPORT_LIGHT is not set | 650 | # CONFIG_I2C_PARPORT_LIGHT is not set |
621 | # CONFIG_I2C_PIIX4 is not set | ||
622 | # CONFIG_I2C_PROSAVAGE is not set | 651 | # CONFIG_I2C_PROSAVAGE is not set |
623 | # CONFIG_I2C_SAVAGE4 is not set | 652 | # CONFIG_I2C_SAVAGE4 is not set |
624 | # CONFIG_SCx200_ACB is not set | 653 | # CONFIG_SCx200_ACB is not set |
625 | # CONFIG_I2C_SIS5595 is not set | 654 | # CONFIG_I2C_SIS5595 is not set |
626 | # CONFIG_I2C_SIS630 is not set | 655 | # CONFIG_I2C_SIS630 is not set |
627 | # CONFIG_I2C_SIS96X is not set | 656 | # CONFIG_I2C_SIS96X is not set |
657 | # CONFIG_I2C_STUB is not set | ||
628 | # CONFIG_I2C_VIA is not set | 658 | # CONFIG_I2C_VIA is not set |
629 | # CONFIG_I2C_VIAPRO is not set | 659 | # CONFIG_I2C_VIAPRO is not set |
630 | # CONFIG_I2C_VOODOO3 is not set | 660 | # CONFIG_I2C_VOODOO3 is not set |
@@ -638,7 +668,9 @@ CONFIG_I2C_SENSOR=y | |||
638 | # CONFIG_SENSORS_ADM1025 is not set | 668 | # CONFIG_SENSORS_ADM1025 is not set |
639 | # CONFIG_SENSORS_ADM1026 is not set | 669 | # CONFIG_SENSORS_ADM1026 is not set |
640 | # CONFIG_SENSORS_ADM1031 is not set | 670 | # CONFIG_SENSORS_ADM1031 is not set |
671 | # CONFIG_SENSORS_ADM9240 is not set | ||
641 | # CONFIG_SENSORS_ASB100 is not set | 672 | # CONFIG_SENSORS_ASB100 is not set |
673 | # CONFIG_SENSORS_ATXP1 is not set | ||
642 | # CONFIG_SENSORS_DS1621 is not set | 674 | # CONFIG_SENSORS_DS1621 is not set |
643 | # CONFIG_SENSORS_FSCHER is not set | 675 | # CONFIG_SENSORS_FSCHER is not set |
644 | # CONFIG_SENSORS_FSCPOS is not set | 676 | # CONFIG_SENSORS_FSCPOS is not set |
@@ -654,6 +686,7 @@ CONFIG_I2C_SENSOR=y | |||
654 | # CONFIG_SENSORS_LM85 is not set | 686 | # CONFIG_SENSORS_LM85 is not set |
655 | # CONFIG_SENSORS_LM87 is not set | 687 | # CONFIG_SENSORS_LM87 is not set |
656 | # CONFIG_SENSORS_LM90 is not set | 688 | # CONFIG_SENSORS_LM90 is not set |
689 | # CONFIG_SENSORS_LM92 is not set | ||
657 | # CONFIG_SENSORS_MAX1619 is not set | 690 | # CONFIG_SENSORS_MAX1619 is not set |
658 | # CONFIG_SENSORS_PC87360 is not set | 691 | # CONFIG_SENSORS_PC87360 is not set |
659 | # CONFIG_SENSORS_SMSC47B397 is not set | 692 | # CONFIG_SENSORS_SMSC47B397 is not set |
@@ -663,14 +696,19 @@ CONFIG_I2C_SENSOR=y | |||
663 | # CONFIG_SENSORS_W83781D is not set | 696 | # CONFIG_SENSORS_W83781D is not set |
664 | # CONFIG_SENSORS_W83L785TS is not set | 697 | # CONFIG_SENSORS_W83L785TS is not set |
665 | # CONFIG_SENSORS_W83627HF is not set | 698 | # CONFIG_SENSORS_W83627HF is not set |
699 | # CONFIG_SENSORS_W83627EHF is not set | ||
666 | 700 | ||
667 | # | 701 | # |
668 | # Other I2C Chip support | 702 | # Other I2C Chip support |
669 | # | 703 | # |
704 | # CONFIG_SENSORS_DS1337 is not set | ||
705 | # CONFIG_SENSORS_DS1374 is not set | ||
670 | CONFIG_SENSORS_EEPROM=y | 706 | CONFIG_SENSORS_EEPROM=y |
671 | # CONFIG_SENSORS_PCF8574 is not set | 707 | # CONFIG_SENSORS_PCF8574 is not set |
708 | # CONFIG_SENSORS_PCA9539 is not set | ||
672 | # CONFIG_SENSORS_PCF8591 is not set | 709 | # CONFIG_SENSORS_PCF8591 is not set |
673 | # CONFIG_SENSORS_RTC8564 is not set | 710 | # CONFIG_SENSORS_RTC8564 is not set |
711 | # CONFIG_SENSORS_MAX6875 is not set | ||
674 | # CONFIG_I2C_DEBUG_CORE is not set | 712 | # CONFIG_I2C_DEBUG_CORE is not set |
675 | # CONFIG_I2C_DEBUG_ALGO is not set | 713 | # CONFIG_I2C_DEBUG_ALGO is not set |
676 | # CONFIG_I2C_DEBUG_BUS is not set | 714 | # CONFIG_I2C_DEBUG_BUS is not set |
@@ -724,6 +762,7 @@ CONFIG_EXT2_FS=y | |||
724 | CONFIG_EXT2_FS_XATTR=y | 762 | CONFIG_EXT2_FS_XATTR=y |
725 | CONFIG_EXT2_FS_POSIX_ACL=y | 763 | CONFIG_EXT2_FS_POSIX_ACL=y |
726 | # CONFIG_EXT2_FS_SECURITY is not set | 764 | # CONFIG_EXT2_FS_SECURITY is not set |
765 | # CONFIG_EXT2_FS_XIP is not set | ||
727 | CONFIG_EXT3_FS=y | 766 | CONFIG_EXT3_FS=y |
728 | CONFIG_EXT3_FS_XATTR=y | 767 | CONFIG_EXT3_FS_XATTR=y |
729 | CONFIG_EXT3_FS_POSIX_ACL=y | 768 | CONFIG_EXT3_FS_POSIX_ACL=y |
@@ -764,7 +803,6 @@ CONFIG_DNOTIFY=y | |||
764 | # | 803 | # |
765 | CONFIG_PROC_FS=y | 804 | CONFIG_PROC_FS=y |
766 | CONFIG_SYSFS=y | 805 | CONFIG_SYSFS=y |
767 | # CONFIG_DEVFS_FS is not set | ||
768 | # CONFIG_DEVPTS_FS_XATTR is not set | 806 | # CONFIG_DEVPTS_FS_XATTR is not set |
769 | CONFIG_TMPFS=y | 807 | CONFIG_TMPFS=y |
770 | # CONFIG_TMPFS_XATTR is not set | 808 | # CONFIG_TMPFS_XATTR is not set |
@@ -802,12 +840,14 @@ CONFIG_JFFS2_RTIME=y | |||
802 | # | 840 | # |
803 | CONFIG_NFS_FS=y | 841 | CONFIG_NFS_FS=y |
804 | CONFIG_NFS_V3=y | 842 | CONFIG_NFS_V3=y |
843 | # CONFIG_NFS_V3_ACL is not set | ||
805 | # CONFIG_NFS_V4 is not set | 844 | # CONFIG_NFS_V4 is not set |
806 | # CONFIG_NFS_DIRECTIO is not set | 845 | # CONFIG_NFS_DIRECTIO is not set |
807 | # CONFIG_NFSD is not set | 846 | # CONFIG_NFSD is not set |
808 | CONFIG_ROOT_NFS=y | 847 | CONFIG_ROOT_NFS=y |
809 | CONFIG_LOCKD=y | 848 | CONFIG_LOCKD=y |
810 | CONFIG_LOCKD_V4=y | 849 | CONFIG_LOCKD_V4=y |
850 | CONFIG_NFS_COMMON=y | ||
811 | CONFIG_SUNRPC=y | 851 | CONFIG_SUNRPC=y |
812 | # CONFIG_RPCSEC_GSS_KRB5 is not set | 852 | # CONFIG_RPCSEC_GSS_KRB5 is not set |
813 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | 853 | # CONFIG_RPCSEC_GSS_SPKM3 is not set |
@@ -892,3 +932,4 @@ CONFIG_CRC32=y | |||
892 | # CONFIG_LIBCRC32C is not set | 932 | # CONFIG_LIBCRC32C is not set |
893 | CONFIG_ZLIB_INFLATE=y | 933 | CONFIG_ZLIB_INFLATE=y |
894 | CONFIG_ZLIB_DEFLATE=y | 934 | CONFIG_ZLIB_DEFLATE=y |
935 | # CONFIG_TEXTSEARCH is not set | ||
diff --git a/arch/arm/configs/ixdp2401_defconfig b/arch/arm/configs/ixdp2401_defconfig index 72e1b940e975..5c87e8e6969b 100644 --- a/arch/arm/configs/ixdp2401_defconfig +++ b/arch/arm/configs/ixdp2401_defconfig | |||
@@ -1,14 +1,13 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.12-rc1-bk2 | 3 | # Linux kernel version: 2.6.12-git6 |
4 | # Sun Mar 27 21:53:55 2005 | 4 | # Sat Jun 25 00:59:35 2005 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
8 | CONFIG_UID16=y | 8 | CONFIG_UID16=y |
9 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | 9 | CONFIG_RWSEM_GENERIC_SPINLOCK=y |
10 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 10 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
11 | CONFIG_GENERIC_IOMAP=y | ||
12 | 11 | ||
13 | # | 12 | # |
14 | # Code maturity level options | 13 | # Code maturity level options |
@@ -16,6 +15,7 @@ CONFIG_GENERIC_IOMAP=y | |||
16 | CONFIG_EXPERIMENTAL=y | 15 | CONFIG_EXPERIMENTAL=y |
17 | CONFIG_CLEAN_COMPILE=y | 16 | CONFIG_CLEAN_COMPILE=y |
18 | CONFIG_BROKEN_ON_SMP=y | 17 | CONFIG_BROKEN_ON_SMP=y |
18 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
19 | 19 | ||
20 | # | 20 | # |
21 | # General setup | 21 | # General setup |
@@ -35,6 +35,8 @@ CONFIG_EMBEDDED=y | |||
35 | CONFIG_KALLSYMS=y | 35 | CONFIG_KALLSYMS=y |
36 | # CONFIG_KALLSYMS_ALL is not set | 36 | # CONFIG_KALLSYMS_ALL is not set |
37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
38 | CONFIG_PRINTK=y | ||
39 | CONFIG_BUG=y | ||
38 | CONFIG_BASE_FULL=y | 40 | CONFIG_BASE_FULL=y |
39 | CONFIG_FUTEX=y | 41 | CONFIG_FUTEX=y |
40 | CONFIG_EPOLL=y | 42 | CONFIG_EPOLL=y |
@@ -82,6 +84,7 @@ CONFIG_ARCH_IXP2000=y | |||
82 | # CONFIG_ARCH_VERSATILE is not set | 84 | # CONFIG_ARCH_VERSATILE is not set |
83 | # CONFIG_ARCH_IMX is not set | 85 | # CONFIG_ARCH_IMX is not set |
84 | # CONFIG_ARCH_H720X is not set | 86 | # CONFIG_ARCH_H720X is not set |
87 | # CONFIG_ARCH_AAEC2000 is not set | ||
85 | CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y | 88 | CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y |
86 | 89 | ||
87 | # | 90 | # |
@@ -97,6 +100,7 @@ CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y | |||
97 | CONFIG_ARCH_IXDP2401=y | 100 | CONFIG_ARCH_IXDP2401=y |
98 | # CONFIG_ARCH_IXDP2801 is not set | 101 | # CONFIG_ARCH_IXDP2801 is not set |
99 | CONFIG_ARCH_IXDP2X01=y | 102 | CONFIG_ARCH_IXDP2X01=y |
103 | # CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set | ||
100 | 104 | ||
101 | # | 105 | # |
102 | # Processor Type | 106 | # Processor Type |
@@ -107,7 +111,6 @@ CONFIG_CPU_32v5=y | |||
107 | CONFIG_CPU_ABRT_EV5T=y | 111 | CONFIG_CPU_ABRT_EV5T=y |
108 | CONFIG_CPU_CACHE_VIVT=y | 112 | CONFIG_CPU_CACHE_VIVT=y |
109 | CONFIG_CPU_TLB_V4WBI=y | 113 | CONFIG_CPU_TLB_V4WBI=y |
110 | CONFIG_CPU_MINICACHE=y | ||
111 | 114 | ||
112 | # | 115 | # |
113 | # Processor Features | 116 | # Processor Features |
@@ -119,9 +122,11 @@ CONFIG_XSCALE_PMU=y | |||
119 | # | 122 | # |
120 | # Bus support | 123 | # Bus support |
121 | # | 124 | # |
125 | CONFIG_ISA_DMA_API=y | ||
122 | CONFIG_PCI=y | 126 | CONFIG_PCI=y |
123 | CONFIG_PCI_LEGACY_PROC=y | 127 | CONFIG_PCI_LEGACY_PROC=y |
124 | CONFIG_PCI_NAMES=y | 128 | CONFIG_PCI_NAMES=y |
129 | # CONFIG_PCI_DEBUG is not set | ||
125 | 130 | ||
126 | # | 131 | # |
127 | # PCCARD (PCMCIA/CardBus) support | 132 | # PCCARD (PCMCIA/CardBus) support |
@@ -131,7 +136,15 @@ CONFIG_PCI_NAMES=y | |||
131 | # | 136 | # |
132 | # Kernel Features | 137 | # Kernel Features |
133 | # | 138 | # |
139 | # CONFIG_SMP is not set | ||
134 | # CONFIG_PREEMPT is not set | 140 | # CONFIG_PREEMPT is not set |
141 | # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set | ||
142 | CONFIG_SELECT_MEMORY_MODEL=y | ||
143 | CONFIG_FLATMEM_MANUAL=y | ||
144 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
145 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
146 | CONFIG_FLATMEM=y | ||
147 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
135 | CONFIG_ALIGNMENT_TRAP=y | 148 | CONFIG_ALIGNMENT_TRAP=y |
136 | 149 | ||
137 | # | 150 | # |
@@ -270,7 +283,6 @@ CONFIG_MTD_IXP2000=y | |||
270 | # | 283 | # |
271 | # Block devices | 284 | # Block devices |
272 | # | 285 | # |
273 | # CONFIG_BLK_DEV_FD is not set | ||
274 | # CONFIG_BLK_CPQ_DA is not set | 286 | # CONFIG_BLK_CPQ_DA is not set |
275 | # CONFIG_BLK_CPQ_CISS_DA is not set | 287 | # CONFIG_BLK_CPQ_CISS_DA is not set |
276 | # CONFIG_BLK_DEV_DAC960 is not set | 288 | # CONFIG_BLK_DEV_DAC960 is not set |
@@ -309,6 +321,7 @@ CONFIG_IOSCHED_CFQ=y | |||
309 | # | 321 | # |
310 | # Fusion MPT device support | 322 | # Fusion MPT device support |
311 | # | 323 | # |
324 | # CONFIG_FUSION is not set | ||
312 | 325 | ||
313 | # | 326 | # |
314 | # IEEE 1394 (FireWire) support | 327 | # IEEE 1394 (FireWire) support |
@@ -330,10 +343,11 @@ CONFIG_NET=y | |||
330 | # | 343 | # |
331 | CONFIG_PACKET=y | 344 | CONFIG_PACKET=y |
332 | CONFIG_PACKET_MMAP=y | 345 | CONFIG_PACKET_MMAP=y |
333 | # CONFIG_NETLINK_DEV is not set | ||
334 | CONFIG_UNIX=y | 346 | CONFIG_UNIX=y |
335 | # CONFIG_NET_KEY is not set | 347 | # CONFIG_NET_KEY is not set |
336 | CONFIG_INET=y | 348 | CONFIG_INET=y |
349 | CONFIG_IP_FIB_HASH=y | ||
350 | # CONFIG_IP_FIB_TRIE is not set | ||
337 | # CONFIG_IP_MULTICAST is not set | 351 | # CONFIG_IP_MULTICAST is not set |
338 | # CONFIG_IP_ADVANCED_ROUTER is not set | 352 | # CONFIG_IP_ADVANCED_ROUTER is not set |
339 | CONFIG_IP_PNP=y | 353 | CONFIG_IP_PNP=y |
@@ -350,6 +364,17 @@ CONFIG_SYN_COOKIES=y | |||
350 | # CONFIG_INET_TUNNEL is not set | 364 | # CONFIG_INET_TUNNEL is not set |
351 | CONFIG_IP_TCPDIAG=y | 365 | CONFIG_IP_TCPDIAG=y |
352 | # CONFIG_IP_TCPDIAG_IPV6 is not set | 366 | # CONFIG_IP_TCPDIAG_IPV6 is not set |
367 | |||
368 | # | ||
369 | # TCP congestion control | ||
370 | # | ||
371 | CONFIG_TCP_CONG_BIC=y | ||
372 | CONFIG_TCP_CONG_WESTWOOD=m | ||
373 | CONFIG_TCP_CONG_HTCP=m | ||
374 | # CONFIG_TCP_CONG_HSTCP is not set | ||
375 | # CONFIG_TCP_CONG_HYBLA is not set | ||
376 | # CONFIG_TCP_CONG_VEGAS is not set | ||
377 | # CONFIG_TCP_CONG_SCALABLE is not set | ||
353 | # CONFIG_IPV6 is not set | 378 | # CONFIG_IPV6 is not set |
354 | # CONFIG_NETFILTER is not set | 379 | # CONFIG_NETFILTER is not set |
355 | 380 | ||
@@ -405,6 +430,7 @@ CONFIG_MII=y | |||
405 | # CONFIG_SUNGEM is not set | 430 | # CONFIG_SUNGEM is not set |
406 | # CONFIG_NET_VENDOR_3COM is not set | 431 | # CONFIG_NET_VENDOR_3COM is not set |
407 | # CONFIG_SMC91X is not set | 432 | # CONFIG_SMC91X is not set |
433 | # CONFIG_DM9000 is not set | ||
408 | 434 | ||
409 | # | 435 | # |
410 | # Tulip family network device support | 436 | # Tulip family network device support |
@@ -442,9 +468,11 @@ CONFIG_EEPRO100=y | |||
442 | # CONFIG_HAMACHI is not set | 468 | # CONFIG_HAMACHI is not set |
443 | # CONFIG_YELLOWFIN is not set | 469 | # CONFIG_YELLOWFIN is not set |
444 | # CONFIG_R8169 is not set | 470 | # CONFIG_R8169 is not set |
471 | # CONFIG_SKGE is not set | ||
445 | # CONFIG_SK98LIN is not set | 472 | # CONFIG_SK98LIN is not set |
446 | # CONFIG_VIA_VELOCITY is not set | 473 | # CONFIG_VIA_VELOCITY is not set |
447 | # CONFIG_TIGON3 is not set | 474 | # CONFIG_TIGON3 is not set |
475 | # CONFIG_BNX2 is not set | ||
448 | 476 | ||
449 | # | 477 | # |
450 | # Ethernet (10000 Mbit) | 478 | # Ethernet (10000 Mbit) |
@@ -466,6 +494,7 @@ CONFIG_EEPRO100=y | |||
466 | # Wan interfaces | 494 | # Wan interfaces |
467 | # | 495 | # |
468 | CONFIG_WAN=y | 496 | CONFIG_WAN=y |
497 | # CONFIG_DSCC4 is not set | ||
469 | # CONFIG_LANMEDIA is not set | 498 | # CONFIG_LANMEDIA is not set |
470 | # CONFIG_SYNCLINK_SYNCPPP is not set | 499 | # CONFIG_SYNCLINK_SYNCPPP is not set |
471 | CONFIG_HDLC=y | 500 | CONFIG_HDLC=y |
@@ -528,7 +557,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | |||
528 | # | 557 | # |
529 | # CONFIG_SERIO is not set | 558 | # CONFIG_SERIO is not set |
530 | # CONFIG_GAMEPORT is not set | 559 | # CONFIG_GAMEPORT is not set |
531 | CONFIG_SOUND_GAMEPORT=y | ||
532 | 560 | ||
533 | # | 561 | # |
534 | # Character devices | 562 | # Character devices |
@@ -549,6 +577,7 @@ CONFIG_SERIAL_8250_NR_UARTS=2 | |||
549 | # | 577 | # |
550 | CONFIG_SERIAL_CORE=y | 578 | CONFIG_SERIAL_CORE=y |
551 | CONFIG_SERIAL_CORE_CONSOLE=y | 579 | CONFIG_SERIAL_CORE_CONSOLE=y |
580 | # CONFIG_SERIAL_JSM is not set | ||
552 | CONFIG_UNIX98_PTYS=y | 581 | CONFIG_UNIX98_PTYS=y |
553 | CONFIG_LEGACY_PTYS=y | 582 | CONFIG_LEGACY_PTYS=y |
554 | CONFIG_LEGACY_PTY_COUNT=256 | 583 | CONFIG_LEGACY_PTY_COUNT=256 |
@@ -615,17 +644,18 @@ CONFIG_I2C_ALGOBIT=y | |||
615 | # CONFIG_I2C_AMD8111 is not set | 644 | # CONFIG_I2C_AMD8111 is not set |
616 | # CONFIG_I2C_I801 is not set | 645 | # CONFIG_I2C_I801 is not set |
617 | # CONFIG_I2C_I810 is not set | 646 | # CONFIG_I2C_I810 is not set |
647 | # CONFIG_I2C_PIIX4 is not set | ||
618 | # CONFIG_I2C_ISA is not set | 648 | # CONFIG_I2C_ISA is not set |
619 | # CONFIG_I2C_IXP2000 is not set | 649 | # CONFIG_I2C_IXP2000 is not set |
620 | # CONFIG_I2C_NFORCE2 is not set | 650 | # CONFIG_I2C_NFORCE2 is not set |
621 | # CONFIG_I2C_PARPORT_LIGHT is not set | 651 | # CONFIG_I2C_PARPORT_LIGHT is not set |
622 | # CONFIG_I2C_PIIX4 is not set | ||
623 | # CONFIG_I2C_PROSAVAGE is not set | 652 | # CONFIG_I2C_PROSAVAGE is not set |
624 | # CONFIG_I2C_SAVAGE4 is not set | 653 | # CONFIG_I2C_SAVAGE4 is not set |
625 | # CONFIG_SCx200_ACB is not set | 654 | # CONFIG_SCx200_ACB is not set |
626 | # CONFIG_I2C_SIS5595 is not set | 655 | # CONFIG_I2C_SIS5595 is not set |
627 | # CONFIG_I2C_SIS630 is not set | 656 | # CONFIG_I2C_SIS630 is not set |
628 | # CONFIG_I2C_SIS96X is not set | 657 | # CONFIG_I2C_SIS96X is not set |
658 | # CONFIG_I2C_STUB is not set | ||
629 | # CONFIG_I2C_VIA is not set | 659 | # CONFIG_I2C_VIA is not set |
630 | # CONFIG_I2C_VIAPRO is not set | 660 | # CONFIG_I2C_VIAPRO is not set |
631 | # CONFIG_I2C_VOODOO3 is not set | 661 | # CONFIG_I2C_VOODOO3 is not set |
@@ -639,7 +669,9 @@ CONFIG_I2C_SENSOR=y | |||
639 | # CONFIG_SENSORS_ADM1025 is not set | 669 | # CONFIG_SENSORS_ADM1025 is not set |
640 | # CONFIG_SENSORS_ADM1026 is not set | 670 | # CONFIG_SENSORS_ADM1026 is not set |
641 | # CONFIG_SENSORS_ADM1031 is not set | 671 | # CONFIG_SENSORS_ADM1031 is not set |
672 | # CONFIG_SENSORS_ADM9240 is not set | ||
642 | # CONFIG_SENSORS_ASB100 is not set | 673 | # CONFIG_SENSORS_ASB100 is not set |
674 | # CONFIG_SENSORS_ATXP1 is not set | ||
643 | # CONFIG_SENSORS_DS1621 is not set | 675 | # CONFIG_SENSORS_DS1621 is not set |
644 | # CONFIG_SENSORS_FSCHER is not set | 676 | # CONFIG_SENSORS_FSCHER is not set |
645 | # CONFIG_SENSORS_FSCPOS is not set | 677 | # CONFIG_SENSORS_FSCPOS is not set |
@@ -655,6 +687,7 @@ CONFIG_I2C_SENSOR=y | |||
655 | # CONFIG_SENSORS_LM85 is not set | 687 | # CONFIG_SENSORS_LM85 is not set |
656 | # CONFIG_SENSORS_LM87 is not set | 688 | # CONFIG_SENSORS_LM87 is not set |
657 | # CONFIG_SENSORS_LM90 is not set | 689 | # CONFIG_SENSORS_LM90 is not set |
690 | # CONFIG_SENSORS_LM92 is not set | ||
658 | # CONFIG_SENSORS_MAX1619 is not set | 691 | # CONFIG_SENSORS_MAX1619 is not set |
659 | # CONFIG_SENSORS_PC87360 is not set | 692 | # CONFIG_SENSORS_PC87360 is not set |
660 | # CONFIG_SENSORS_SMSC47B397 is not set | 693 | # CONFIG_SENSORS_SMSC47B397 is not set |
@@ -664,14 +697,19 @@ CONFIG_I2C_SENSOR=y | |||
664 | # CONFIG_SENSORS_W83781D is not set | 697 | # CONFIG_SENSORS_W83781D is not set |
665 | # CONFIG_SENSORS_W83L785TS is not set | 698 | # CONFIG_SENSORS_W83L785TS is not set |
666 | # CONFIG_SENSORS_W83627HF is not set | 699 | # CONFIG_SENSORS_W83627HF is not set |
700 | # CONFIG_SENSORS_W83627EHF is not set | ||
667 | 701 | ||
668 | # | 702 | # |
669 | # Other I2C Chip support | 703 | # Other I2C Chip support |
670 | # | 704 | # |
705 | # CONFIG_SENSORS_DS1337 is not set | ||
706 | # CONFIG_SENSORS_DS1374 is not set | ||
671 | CONFIG_SENSORS_EEPROM=y | 707 | CONFIG_SENSORS_EEPROM=y |
672 | # CONFIG_SENSORS_PCF8574 is not set | 708 | # CONFIG_SENSORS_PCF8574 is not set |
709 | # CONFIG_SENSORS_PCA9539 is not set | ||
673 | # CONFIG_SENSORS_PCF8591 is not set | 710 | # CONFIG_SENSORS_PCF8591 is not set |
674 | # CONFIG_SENSORS_RTC8564 is not set | 711 | # CONFIG_SENSORS_RTC8564 is not set |
712 | # CONFIG_SENSORS_MAX6875 is not set | ||
675 | # CONFIG_I2C_DEBUG_CORE is not set | 713 | # CONFIG_I2C_DEBUG_CORE is not set |
676 | # CONFIG_I2C_DEBUG_ALGO is not set | 714 | # CONFIG_I2C_DEBUG_ALGO is not set |
677 | # CONFIG_I2C_DEBUG_BUS is not set | 715 | # CONFIG_I2C_DEBUG_BUS is not set |
@@ -725,6 +763,7 @@ CONFIG_EXT2_FS=y | |||
725 | CONFIG_EXT2_FS_XATTR=y | 763 | CONFIG_EXT2_FS_XATTR=y |
726 | CONFIG_EXT2_FS_POSIX_ACL=y | 764 | CONFIG_EXT2_FS_POSIX_ACL=y |
727 | # CONFIG_EXT2_FS_SECURITY is not set | 765 | # CONFIG_EXT2_FS_SECURITY is not set |
766 | # CONFIG_EXT2_FS_XIP is not set | ||
728 | CONFIG_EXT3_FS=y | 767 | CONFIG_EXT3_FS=y |
729 | CONFIG_EXT3_FS_XATTR=y | 768 | CONFIG_EXT3_FS_XATTR=y |
730 | CONFIG_EXT3_FS_POSIX_ACL=y | 769 | CONFIG_EXT3_FS_POSIX_ACL=y |
@@ -765,7 +804,6 @@ CONFIG_DNOTIFY=y | |||
765 | # | 804 | # |
766 | CONFIG_PROC_FS=y | 805 | CONFIG_PROC_FS=y |
767 | CONFIG_SYSFS=y | 806 | CONFIG_SYSFS=y |
768 | # CONFIG_DEVFS_FS is not set | ||
769 | # CONFIG_DEVPTS_FS_XATTR is not set | 807 | # CONFIG_DEVPTS_FS_XATTR is not set |
770 | CONFIG_TMPFS=y | 808 | CONFIG_TMPFS=y |
771 | # CONFIG_TMPFS_XATTR is not set | 809 | # CONFIG_TMPFS_XATTR is not set |
@@ -803,12 +841,14 @@ CONFIG_JFFS2_RTIME=y | |||
803 | # | 841 | # |
804 | CONFIG_NFS_FS=y | 842 | CONFIG_NFS_FS=y |
805 | CONFIG_NFS_V3=y | 843 | CONFIG_NFS_V3=y |
844 | # CONFIG_NFS_V3_ACL is not set | ||
806 | # CONFIG_NFS_V4 is not set | 845 | # CONFIG_NFS_V4 is not set |
807 | # CONFIG_NFS_DIRECTIO is not set | 846 | # CONFIG_NFS_DIRECTIO is not set |
808 | # CONFIG_NFSD is not set | 847 | # CONFIG_NFSD is not set |
809 | CONFIG_ROOT_NFS=y | 848 | CONFIG_ROOT_NFS=y |
810 | CONFIG_LOCKD=y | 849 | CONFIG_LOCKD=y |
811 | CONFIG_LOCKD_V4=y | 850 | CONFIG_LOCKD_V4=y |
851 | CONFIG_NFS_COMMON=y | ||
812 | CONFIG_SUNRPC=y | 852 | CONFIG_SUNRPC=y |
813 | # CONFIG_RPCSEC_GSS_KRB5 is not set | 853 | # CONFIG_RPCSEC_GSS_KRB5 is not set |
814 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | 854 | # CONFIG_RPCSEC_GSS_SPKM3 is not set |
@@ -893,3 +933,4 @@ CONFIG_CRC32=y | |||
893 | # CONFIG_LIBCRC32C is not set | 933 | # CONFIG_LIBCRC32C is not set |
894 | CONFIG_ZLIB_INFLATE=y | 934 | CONFIG_ZLIB_INFLATE=y |
895 | CONFIG_ZLIB_DEFLATE=y | 935 | CONFIG_ZLIB_DEFLATE=y |
936 | # CONFIG_TEXTSEARCH is not set | ||
diff --git a/arch/arm/configs/ixdp2800_defconfig b/arch/arm/configs/ixdp2800_defconfig index 1592e45f0278..3cb561a551cb 100644 --- a/arch/arm/configs/ixdp2800_defconfig +++ b/arch/arm/configs/ixdp2800_defconfig | |||
@@ -1,14 +1,13 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.12-rc1-bk2 | 3 | # Linux kernel version: 2.6.12-git6 |
4 | # Sun Mar 27 22:15:23 2005 | 4 | # Sat Jun 25 01:00:27 2005 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
8 | CONFIG_UID16=y | 8 | CONFIG_UID16=y |
9 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | 9 | CONFIG_RWSEM_GENERIC_SPINLOCK=y |
10 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 10 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
11 | CONFIG_GENERIC_IOMAP=y | ||
12 | 11 | ||
13 | # | 12 | # |
14 | # Code maturity level options | 13 | # Code maturity level options |
@@ -16,6 +15,7 @@ CONFIG_GENERIC_IOMAP=y | |||
16 | CONFIG_EXPERIMENTAL=y | 15 | CONFIG_EXPERIMENTAL=y |
17 | CONFIG_CLEAN_COMPILE=y | 16 | CONFIG_CLEAN_COMPILE=y |
18 | CONFIG_BROKEN_ON_SMP=y | 17 | CONFIG_BROKEN_ON_SMP=y |
18 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
19 | 19 | ||
20 | # | 20 | # |
21 | # General setup | 21 | # General setup |
@@ -35,6 +35,8 @@ CONFIG_EMBEDDED=y | |||
35 | CONFIG_KALLSYMS=y | 35 | CONFIG_KALLSYMS=y |
36 | # CONFIG_KALLSYMS_ALL is not set | 36 | # CONFIG_KALLSYMS_ALL is not set |
37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
38 | CONFIG_PRINTK=y | ||
39 | CONFIG_BUG=y | ||
38 | CONFIG_BASE_FULL=y | 40 | CONFIG_BASE_FULL=y |
39 | CONFIG_FUTEX=y | 41 | CONFIG_FUTEX=y |
40 | CONFIG_EPOLL=y | 42 | CONFIG_EPOLL=y |
@@ -82,6 +84,7 @@ CONFIG_ARCH_IXP2000=y | |||
82 | # CONFIG_ARCH_VERSATILE is not set | 84 | # CONFIG_ARCH_VERSATILE is not set |
83 | # CONFIG_ARCH_IMX is not set | 85 | # CONFIG_ARCH_IMX is not set |
84 | # CONFIG_ARCH_H720X is not set | 86 | # CONFIG_ARCH_H720X is not set |
87 | # CONFIG_ARCH_AAEC2000 is not set | ||
85 | CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y | 88 | CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y |
86 | 89 | ||
87 | # | 90 | # |
@@ -97,6 +100,7 @@ CONFIG_ARCH_IXDP2800=y | |||
97 | CONFIG_ARCH_IXDP2X00=y | 100 | CONFIG_ARCH_IXDP2X00=y |
98 | # CONFIG_ARCH_IXDP2401 is not set | 101 | # CONFIG_ARCH_IXDP2401 is not set |
99 | # CONFIG_ARCH_IXDP2801 is not set | 102 | # CONFIG_ARCH_IXDP2801 is not set |
103 | # CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set | ||
100 | 104 | ||
101 | # | 105 | # |
102 | # Processor Type | 106 | # Processor Type |
@@ -107,7 +111,6 @@ CONFIG_CPU_32v5=y | |||
107 | CONFIG_CPU_ABRT_EV5T=y | 111 | CONFIG_CPU_ABRT_EV5T=y |
108 | CONFIG_CPU_CACHE_VIVT=y | 112 | CONFIG_CPU_CACHE_VIVT=y |
109 | CONFIG_CPU_TLB_V4WBI=y | 113 | CONFIG_CPU_TLB_V4WBI=y |
110 | CONFIG_CPU_MINICACHE=y | ||
111 | 114 | ||
112 | # | 115 | # |
113 | # Processor Features | 116 | # Processor Features |
@@ -119,9 +122,11 @@ CONFIG_XSCALE_PMU=y | |||
119 | # | 122 | # |
120 | # Bus support | 123 | # Bus support |
121 | # | 124 | # |
125 | CONFIG_ISA_DMA_API=y | ||
122 | CONFIG_PCI=y | 126 | CONFIG_PCI=y |
123 | CONFIG_PCI_LEGACY_PROC=y | 127 | CONFIG_PCI_LEGACY_PROC=y |
124 | CONFIG_PCI_NAMES=y | 128 | CONFIG_PCI_NAMES=y |
129 | # CONFIG_PCI_DEBUG is not set | ||
125 | 130 | ||
126 | # | 131 | # |
127 | # PCCARD (PCMCIA/CardBus) support | 132 | # PCCARD (PCMCIA/CardBus) support |
@@ -131,7 +136,15 @@ CONFIG_PCI_NAMES=y | |||
131 | # | 136 | # |
132 | # Kernel Features | 137 | # Kernel Features |
133 | # | 138 | # |
139 | # CONFIG_SMP is not set | ||
134 | # CONFIG_PREEMPT is not set | 140 | # CONFIG_PREEMPT is not set |
141 | # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set | ||
142 | CONFIG_SELECT_MEMORY_MODEL=y | ||
143 | CONFIG_FLATMEM_MANUAL=y | ||
144 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
145 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
146 | CONFIG_FLATMEM=y | ||
147 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
135 | CONFIG_ALIGNMENT_TRAP=y | 148 | CONFIG_ALIGNMENT_TRAP=y |
136 | 149 | ||
137 | # | 150 | # |
@@ -270,7 +283,6 @@ CONFIG_MTD_IXP2000=y | |||
270 | # | 283 | # |
271 | # Block devices | 284 | # Block devices |
272 | # | 285 | # |
273 | # CONFIG_BLK_DEV_FD is not set | ||
274 | # CONFIG_BLK_CPQ_DA is not set | 286 | # CONFIG_BLK_CPQ_DA is not set |
275 | # CONFIG_BLK_CPQ_CISS_DA is not set | 287 | # CONFIG_BLK_CPQ_CISS_DA is not set |
276 | # CONFIG_BLK_DEV_DAC960 is not set | 288 | # CONFIG_BLK_DEV_DAC960 is not set |
@@ -309,6 +321,7 @@ CONFIG_IOSCHED_CFQ=y | |||
309 | # | 321 | # |
310 | # Fusion MPT device support | 322 | # Fusion MPT device support |
311 | # | 323 | # |
324 | # CONFIG_FUSION is not set | ||
312 | 325 | ||
313 | # | 326 | # |
314 | # IEEE 1394 (FireWire) support | 327 | # IEEE 1394 (FireWire) support |
@@ -330,10 +343,11 @@ CONFIG_NET=y | |||
330 | # | 343 | # |
331 | CONFIG_PACKET=y | 344 | CONFIG_PACKET=y |
332 | CONFIG_PACKET_MMAP=y | 345 | CONFIG_PACKET_MMAP=y |
333 | # CONFIG_NETLINK_DEV is not set | ||
334 | CONFIG_UNIX=y | 346 | CONFIG_UNIX=y |
335 | # CONFIG_NET_KEY is not set | 347 | # CONFIG_NET_KEY is not set |
336 | CONFIG_INET=y | 348 | CONFIG_INET=y |
349 | CONFIG_IP_FIB_HASH=y | ||
350 | # CONFIG_IP_FIB_TRIE is not set | ||
337 | # CONFIG_IP_MULTICAST is not set | 351 | # CONFIG_IP_MULTICAST is not set |
338 | # CONFIG_IP_ADVANCED_ROUTER is not set | 352 | # CONFIG_IP_ADVANCED_ROUTER is not set |
339 | CONFIG_IP_PNP=y | 353 | CONFIG_IP_PNP=y |
@@ -350,6 +364,17 @@ CONFIG_SYN_COOKIES=y | |||
350 | # CONFIG_INET_TUNNEL is not set | 364 | # CONFIG_INET_TUNNEL is not set |
351 | # CONFIG_IP_TCPDIAG is not set | 365 | # CONFIG_IP_TCPDIAG is not set |
352 | # CONFIG_IP_TCPDIAG_IPV6 is not set | 366 | # CONFIG_IP_TCPDIAG_IPV6 is not set |
367 | |||
368 | # | ||
369 | # TCP congestion control | ||
370 | # | ||
371 | CONFIG_TCP_CONG_BIC=y | ||
372 | CONFIG_TCP_CONG_WESTWOOD=m | ||
373 | CONFIG_TCP_CONG_HTCP=m | ||
374 | # CONFIG_TCP_CONG_HSTCP is not set | ||
375 | # CONFIG_TCP_CONG_HYBLA is not set | ||
376 | # CONFIG_TCP_CONG_VEGAS is not set | ||
377 | # CONFIG_TCP_CONG_SCALABLE is not set | ||
353 | # CONFIG_IPV6 is not set | 378 | # CONFIG_IPV6 is not set |
354 | # CONFIG_NETFILTER is not set | 379 | # CONFIG_NETFILTER is not set |
355 | 380 | ||
@@ -405,6 +430,7 @@ CONFIG_MII=y | |||
405 | # CONFIG_SUNGEM is not set | 430 | # CONFIG_SUNGEM is not set |
406 | # CONFIG_NET_VENDOR_3COM is not set | 431 | # CONFIG_NET_VENDOR_3COM is not set |
407 | # CONFIG_SMC91X is not set | 432 | # CONFIG_SMC91X is not set |
433 | # CONFIG_DM9000 is not set | ||
408 | 434 | ||
409 | # | 435 | # |
410 | # Tulip family network device support | 436 | # Tulip family network device support |
@@ -441,9 +467,11 @@ CONFIG_EEPRO100=y | |||
441 | # CONFIG_HAMACHI is not set | 467 | # CONFIG_HAMACHI is not set |
442 | # CONFIG_YELLOWFIN is not set | 468 | # CONFIG_YELLOWFIN is not set |
443 | # CONFIG_R8169 is not set | 469 | # CONFIG_R8169 is not set |
470 | # CONFIG_SKGE is not set | ||
444 | # CONFIG_SK98LIN is not set | 471 | # CONFIG_SK98LIN is not set |
445 | # CONFIG_VIA_VELOCITY is not set | 472 | # CONFIG_VIA_VELOCITY is not set |
446 | # CONFIG_TIGON3 is not set | 473 | # CONFIG_TIGON3 is not set |
474 | # CONFIG_BNX2 is not set | ||
447 | 475 | ||
448 | # | 476 | # |
449 | # Ethernet (10000 Mbit) | 477 | # Ethernet (10000 Mbit) |
@@ -465,6 +493,7 @@ CONFIG_EEPRO100=y | |||
465 | # Wan interfaces | 493 | # Wan interfaces |
466 | # | 494 | # |
467 | CONFIG_WAN=y | 495 | CONFIG_WAN=y |
496 | # CONFIG_DSCC4 is not set | ||
468 | # CONFIG_LANMEDIA is not set | 497 | # CONFIG_LANMEDIA is not set |
469 | # CONFIG_SYNCLINK_SYNCPPP is not set | 498 | # CONFIG_SYNCLINK_SYNCPPP is not set |
470 | CONFIG_HDLC=y | 499 | CONFIG_HDLC=y |
@@ -527,7 +556,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | |||
527 | # | 556 | # |
528 | # CONFIG_SERIO is not set | 557 | # CONFIG_SERIO is not set |
529 | # CONFIG_GAMEPORT is not set | 558 | # CONFIG_GAMEPORT is not set |
530 | CONFIG_SOUND_GAMEPORT=y | ||
531 | 559 | ||
532 | # | 560 | # |
533 | # Character devices | 561 | # Character devices |
@@ -548,6 +576,7 @@ CONFIG_SERIAL_8250_NR_UARTS=2 | |||
548 | # | 576 | # |
549 | CONFIG_SERIAL_CORE=y | 577 | CONFIG_SERIAL_CORE=y |
550 | CONFIG_SERIAL_CORE_CONSOLE=y | 578 | CONFIG_SERIAL_CORE_CONSOLE=y |
579 | # CONFIG_SERIAL_JSM is not set | ||
551 | CONFIG_UNIX98_PTYS=y | 580 | CONFIG_UNIX98_PTYS=y |
552 | CONFIG_LEGACY_PTYS=y | 581 | CONFIG_LEGACY_PTYS=y |
553 | CONFIG_LEGACY_PTY_COUNT=256 | 582 | CONFIG_LEGACY_PTY_COUNT=256 |
@@ -614,17 +643,18 @@ CONFIG_I2C_ALGOBIT=y | |||
614 | # CONFIG_I2C_AMD8111 is not set | 643 | # CONFIG_I2C_AMD8111 is not set |
615 | # CONFIG_I2C_I801 is not set | 644 | # CONFIG_I2C_I801 is not set |
616 | # CONFIG_I2C_I810 is not set | 645 | # CONFIG_I2C_I810 is not set |
646 | # CONFIG_I2C_PIIX4 is not set | ||
617 | # CONFIG_I2C_ISA is not set | 647 | # CONFIG_I2C_ISA is not set |
618 | # CONFIG_I2C_IXP2000 is not set | 648 | # CONFIG_I2C_IXP2000 is not set |
619 | # CONFIG_I2C_NFORCE2 is not set | 649 | # CONFIG_I2C_NFORCE2 is not set |
620 | # CONFIG_I2C_PARPORT_LIGHT is not set | 650 | # CONFIG_I2C_PARPORT_LIGHT is not set |
621 | # CONFIG_I2C_PIIX4 is not set | ||
622 | # CONFIG_I2C_PROSAVAGE is not set | 651 | # CONFIG_I2C_PROSAVAGE is not set |
623 | # CONFIG_I2C_SAVAGE4 is not set | 652 | # CONFIG_I2C_SAVAGE4 is not set |
624 | # CONFIG_SCx200_ACB is not set | 653 | # CONFIG_SCx200_ACB is not set |
625 | # CONFIG_I2C_SIS5595 is not set | 654 | # CONFIG_I2C_SIS5595 is not set |
626 | # CONFIG_I2C_SIS630 is not set | 655 | # CONFIG_I2C_SIS630 is not set |
627 | # CONFIG_I2C_SIS96X is not set | 656 | # CONFIG_I2C_SIS96X is not set |
657 | # CONFIG_I2C_STUB is not set | ||
628 | # CONFIG_I2C_VIA is not set | 658 | # CONFIG_I2C_VIA is not set |
629 | # CONFIG_I2C_VIAPRO is not set | 659 | # CONFIG_I2C_VIAPRO is not set |
630 | # CONFIG_I2C_VOODOO3 is not set | 660 | # CONFIG_I2C_VOODOO3 is not set |
@@ -638,7 +668,9 @@ CONFIG_I2C_SENSOR=y | |||
638 | # CONFIG_SENSORS_ADM1025 is not set | 668 | # CONFIG_SENSORS_ADM1025 is not set |
639 | # CONFIG_SENSORS_ADM1026 is not set | 669 | # CONFIG_SENSORS_ADM1026 is not set |
640 | # CONFIG_SENSORS_ADM1031 is not set | 670 | # CONFIG_SENSORS_ADM1031 is not set |
671 | # CONFIG_SENSORS_ADM9240 is not set | ||
641 | # CONFIG_SENSORS_ASB100 is not set | 672 | # CONFIG_SENSORS_ASB100 is not set |
673 | # CONFIG_SENSORS_ATXP1 is not set | ||
642 | # CONFIG_SENSORS_DS1621 is not set | 674 | # CONFIG_SENSORS_DS1621 is not set |
643 | # CONFIG_SENSORS_FSCHER is not set | 675 | # CONFIG_SENSORS_FSCHER is not set |
644 | # CONFIG_SENSORS_FSCPOS is not set | 676 | # CONFIG_SENSORS_FSCPOS is not set |
@@ -654,6 +686,7 @@ CONFIG_I2C_SENSOR=y | |||
654 | # CONFIG_SENSORS_LM85 is not set | 686 | # CONFIG_SENSORS_LM85 is not set |
655 | # CONFIG_SENSORS_LM87 is not set | 687 | # CONFIG_SENSORS_LM87 is not set |
656 | # CONFIG_SENSORS_LM90 is not set | 688 | # CONFIG_SENSORS_LM90 is not set |
689 | # CONFIG_SENSORS_LM92 is not set | ||
657 | # CONFIG_SENSORS_MAX1619 is not set | 690 | # CONFIG_SENSORS_MAX1619 is not set |
658 | # CONFIG_SENSORS_PC87360 is not set | 691 | # CONFIG_SENSORS_PC87360 is not set |
659 | # CONFIG_SENSORS_SMSC47B397 is not set | 692 | # CONFIG_SENSORS_SMSC47B397 is not set |
@@ -663,14 +696,19 @@ CONFIG_I2C_SENSOR=y | |||
663 | # CONFIG_SENSORS_W83781D is not set | 696 | # CONFIG_SENSORS_W83781D is not set |
664 | # CONFIG_SENSORS_W83L785TS is not set | 697 | # CONFIG_SENSORS_W83L785TS is not set |
665 | # CONFIG_SENSORS_W83627HF is not set | 698 | # CONFIG_SENSORS_W83627HF is not set |
699 | # CONFIG_SENSORS_W83627EHF is not set | ||
666 | 700 | ||
667 | # | 701 | # |
668 | # Other I2C Chip support | 702 | # Other I2C Chip support |
669 | # | 703 | # |
704 | # CONFIG_SENSORS_DS1337 is not set | ||
705 | # CONFIG_SENSORS_DS1374 is not set | ||
670 | CONFIG_SENSORS_EEPROM=y | 706 | CONFIG_SENSORS_EEPROM=y |
671 | # CONFIG_SENSORS_PCF8574 is not set | 707 | # CONFIG_SENSORS_PCF8574 is not set |
708 | # CONFIG_SENSORS_PCA9539 is not set | ||
672 | # CONFIG_SENSORS_PCF8591 is not set | 709 | # CONFIG_SENSORS_PCF8591 is not set |
673 | # CONFIG_SENSORS_RTC8564 is not set | 710 | # CONFIG_SENSORS_RTC8564 is not set |
711 | # CONFIG_SENSORS_MAX6875 is not set | ||
674 | # CONFIG_I2C_DEBUG_CORE is not set | 712 | # CONFIG_I2C_DEBUG_CORE is not set |
675 | # CONFIG_I2C_DEBUG_ALGO is not set | 713 | # CONFIG_I2C_DEBUG_ALGO is not set |
676 | # CONFIG_I2C_DEBUG_BUS is not set | 714 | # CONFIG_I2C_DEBUG_BUS is not set |
@@ -724,6 +762,7 @@ CONFIG_EXT2_FS=y | |||
724 | CONFIG_EXT2_FS_XATTR=y | 762 | CONFIG_EXT2_FS_XATTR=y |
725 | CONFIG_EXT2_FS_POSIX_ACL=y | 763 | CONFIG_EXT2_FS_POSIX_ACL=y |
726 | # CONFIG_EXT2_FS_SECURITY is not set | 764 | # CONFIG_EXT2_FS_SECURITY is not set |
765 | # CONFIG_EXT2_FS_XIP is not set | ||
727 | CONFIG_EXT3_FS=y | 766 | CONFIG_EXT3_FS=y |
728 | CONFIG_EXT3_FS_XATTR=y | 767 | CONFIG_EXT3_FS_XATTR=y |
729 | CONFIG_EXT3_FS_POSIX_ACL=y | 768 | CONFIG_EXT3_FS_POSIX_ACL=y |
@@ -764,7 +803,6 @@ CONFIG_DNOTIFY=y | |||
764 | # | 803 | # |
765 | CONFIG_PROC_FS=y | 804 | CONFIG_PROC_FS=y |
766 | CONFIG_SYSFS=y | 805 | CONFIG_SYSFS=y |
767 | # CONFIG_DEVFS_FS is not set | ||
768 | # CONFIG_DEVPTS_FS_XATTR is not set | 806 | # CONFIG_DEVPTS_FS_XATTR is not set |
769 | CONFIG_TMPFS=y | 807 | CONFIG_TMPFS=y |
770 | # CONFIG_TMPFS_XATTR is not set | 808 | # CONFIG_TMPFS_XATTR is not set |
@@ -802,12 +840,14 @@ CONFIG_JFFS2_RTIME=y | |||
802 | # | 840 | # |
803 | CONFIG_NFS_FS=y | 841 | CONFIG_NFS_FS=y |
804 | CONFIG_NFS_V3=y | 842 | CONFIG_NFS_V3=y |
843 | # CONFIG_NFS_V3_ACL is not set | ||
805 | # CONFIG_NFS_V4 is not set | 844 | # CONFIG_NFS_V4 is not set |
806 | # CONFIG_NFS_DIRECTIO is not set | 845 | # CONFIG_NFS_DIRECTIO is not set |
807 | # CONFIG_NFSD is not set | 846 | # CONFIG_NFSD is not set |
808 | CONFIG_ROOT_NFS=y | 847 | CONFIG_ROOT_NFS=y |
809 | CONFIG_LOCKD=y | 848 | CONFIG_LOCKD=y |
810 | CONFIG_LOCKD_V4=y | 849 | CONFIG_LOCKD_V4=y |
850 | CONFIG_NFS_COMMON=y | ||
811 | CONFIG_SUNRPC=y | 851 | CONFIG_SUNRPC=y |
812 | # CONFIG_RPCSEC_GSS_KRB5 is not set | 852 | # CONFIG_RPCSEC_GSS_KRB5 is not set |
813 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | 853 | # CONFIG_RPCSEC_GSS_SPKM3 is not set |
@@ -892,3 +932,4 @@ CONFIG_CRC32=y | |||
892 | # CONFIG_LIBCRC32C is not set | 932 | # CONFIG_LIBCRC32C is not set |
893 | CONFIG_ZLIB_INFLATE=y | 933 | CONFIG_ZLIB_INFLATE=y |
894 | CONFIG_ZLIB_DEFLATE=y | 934 | CONFIG_ZLIB_DEFLATE=y |
935 | # CONFIG_TEXTSEARCH is not set | ||
diff --git a/arch/arm/configs/ixdp2801_defconfig b/arch/arm/configs/ixdp2801_defconfig index f1afe3d09ec6..b1e162f29cb9 100644 --- a/arch/arm/configs/ixdp2801_defconfig +++ b/arch/arm/configs/ixdp2801_defconfig | |||
@@ -1,14 +1,13 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.12-rc1-bk2 | 3 | # Linux kernel version: 2.6.12-git6 |
4 | # Sun Mar 27 22:39:19 2005 | 4 | # Sat Jun 25 01:01:18 2005 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
8 | CONFIG_UID16=y | 8 | CONFIG_UID16=y |
9 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | 9 | CONFIG_RWSEM_GENERIC_SPINLOCK=y |
10 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 10 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
11 | CONFIG_GENERIC_IOMAP=y | ||
12 | 11 | ||
13 | # | 12 | # |
14 | # Code maturity level options | 13 | # Code maturity level options |
@@ -16,6 +15,7 @@ CONFIG_GENERIC_IOMAP=y | |||
16 | CONFIG_EXPERIMENTAL=y | 15 | CONFIG_EXPERIMENTAL=y |
17 | CONFIG_CLEAN_COMPILE=y | 16 | CONFIG_CLEAN_COMPILE=y |
18 | CONFIG_BROKEN_ON_SMP=y | 17 | CONFIG_BROKEN_ON_SMP=y |
18 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
19 | 19 | ||
20 | # | 20 | # |
21 | # General setup | 21 | # General setup |
@@ -35,6 +35,8 @@ CONFIG_EMBEDDED=y | |||
35 | CONFIG_KALLSYMS=y | 35 | CONFIG_KALLSYMS=y |
36 | # CONFIG_KALLSYMS_ALL is not set | 36 | # CONFIG_KALLSYMS_ALL is not set |
37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
38 | CONFIG_PRINTK=y | ||
39 | CONFIG_BUG=y | ||
38 | CONFIG_BASE_FULL=y | 40 | CONFIG_BASE_FULL=y |
39 | CONFIG_FUTEX=y | 41 | CONFIG_FUTEX=y |
40 | CONFIG_EPOLL=y | 42 | CONFIG_EPOLL=y |
@@ -82,6 +84,7 @@ CONFIG_ARCH_IXP2000=y | |||
82 | # CONFIG_ARCH_VERSATILE is not set | 84 | # CONFIG_ARCH_VERSATILE is not set |
83 | # CONFIG_ARCH_IMX is not set | 85 | # CONFIG_ARCH_IMX is not set |
84 | # CONFIG_ARCH_H720X is not set | 86 | # CONFIG_ARCH_H720X is not set |
87 | # CONFIG_ARCH_AAEC2000 is not set | ||
85 | CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y | 88 | CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y |
86 | 89 | ||
87 | # | 90 | # |
@@ -97,6 +100,7 @@ CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y | |||
97 | # CONFIG_ARCH_IXDP2401 is not set | 100 | # CONFIG_ARCH_IXDP2401 is not set |
98 | CONFIG_ARCH_IXDP2801=y | 101 | CONFIG_ARCH_IXDP2801=y |
99 | CONFIG_ARCH_IXDP2X01=y | 102 | CONFIG_ARCH_IXDP2X01=y |
103 | # CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set | ||
100 | 104 | ||
101 | # | 105 | # |
102 | # Processor Type | 106 | # Processor Type |
@@ -107,7 +111,6 @@ CONFIG_CPU_32v5=y | |||
107 | CONFIG_CPU_ABRT_EV5T=y | 111 | CONFIG_CPU_ABRT_EV5T=y |
108 | CONFIG_CPU_CACHE_VIVT=y | 112 | CONFIG_CPU_CACHE_VIVT=y |
109 | CONFIG_CPU_TLB_V4WBI=y | 113 | CONFIG_CPU_TLB_V4WBI=y |
110 | CONFIG_CPU_MINICACHE=y | ||
111 | 114 | ||
112 | # | 115 | # |
113 | # Processor Features | 116 | # Processor Features |
@@ -119,9 +122,11 @@ CONFIG_XSCALE_PMU=y | |||
119 | # | 122 | # |
120 | # Bus support | 123 | # Bus support |
121 | # | 124 | # |
125 | CONFIG_ISA_DMA_API=y | ||
122 | CONFIG_PCI=y | 126 | CONFIG_PCI=y |
123 | CONFIG_PCI_LEGACY_PROC=y | 127 | CONFIG_PCI_LEGACY_PROC=y |
124 | CONFIG_PCI_NAMES=y | 128 | CONFIG_PCI_NAMES=y |
129 | # CONFIG_PCI_DEBUG is not set | ||
125 | 130 | ||
126 | # | 131 | # |
127 | # PCCARD (PCMCIA/CardBus) support | 132 | # PCCARD (PCMCIA/CardBus) support |
@@ -131,7 +136,15 @@ CONFIG_PCI_NAMES=y | |||
131 | # | 136 | # |
132 | # Kernel Features | 137 | # Kernel Features |
133 | # | 138 | # |
139 | # CONFIG_SMP is not set | ||
134 | # CONFIG_PREEMPT is not set | 140 | # CONFIG_PREEMPT is not set |
141 | # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set | ||
142 | CONFIG_SELECT_MEMORY_MODEL=y | ||
143 | CONFIG_FLATMEM_MANUAL=y | ||
144 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
145 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
146 | CONFIG_FLATMEM=y | ||
147 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
135 | CONFIG_ALIGNMENT_TRAP=y | 148 | CONFIG_ALIGNMENT_TRAP=y |
136 | 149 | ||
137 | # | 150 | # |
@@ -270,7 +283,6 @@ CONFIG_MTD_IXP2000=y | |||
270 | # | 283 | # |
271 | # Block devices | 284 | # Block devices |
272 | # | 285 | # |
273 | # CONFIG_BLK_DEV_FD is not set | ||
274 | # CONFIG_BLK_CPQ_DA is not set | 286 | # CONFIG_BLK_CPQ_DA is not set |
275 | # CONFIG_BLK_CPQ_CISS_DA is not set | 287 | # CONFIG_BLK_CPQ_CISS_DA is not set |
276 | # CONFIG_BLK_DEV_DAC960 is not set | 288 | # CONFIG_BLK_DEV_DAC960 is not set |
@@ -309,6 +321,7 @@ CONFIG_IOSCHED_CFQ=y | |||
309 | # | 321 | # |
310 | # Fusion MPT device support | 322 | # Fusion MPT device support |
311 | # | 323 | # |
324 | # CONFIG_FUSION is not set | ||
312 | 325 | ||
313 | # | 326 | # |
314 | # IEEE 1394 (FireWire) support | 327 | # IEEE 1394 (FireWire) support |
@@ -330,10 +343,11 @@ CONFIG_NET=y | |||
330 | # | 343 | # |
331 | CONFIG_PACKET=y | 344 | CONFIG_PACKET=y |
332 | CONFIG_PACKET_MMAP=y | 345 | CONFIG_PACKET_MMAP=y |
333 | # CONFIG_NETLINK_DEV is not set | ||
334 | CONFIG_UNIX=y | 346 | CONFIG_UNIX=y |
335 | # CONFIG_NET_KEY is not set | 347 | # CONFIG_NET_KEY is not set |
336 | CONFIG_INET=y | 348 | CONFIG_INET=y |
349 | CONFIG_IP_FIB_HASH=y | ||
350 | # CONFIG_IP_FIB_TRIE is not set | ||
337 | # CONFIG_IP_MULTICAST is not set | 351 | # CONFIG_IP_MULTICAST is not set |
338 | # CONFIG_IP_ADVANCED_ROUTER is not set | 352 | # CONFIG_IP_ADVANCED_ROUTER is not set |
339 | CONFIG_IP_PNP=y | 353 | CONFIG_IP_PNP=y |
@@ -350,6 +364,17 @@ CONFIG_SYN_COOKIES=y | |||
350 | # CONFIG_INET_TUNNEL is not set | 364 | # CONFIG_INET_TUNNEL is not set |
351 | # CONFIG_IP_TCPDIAG is not set | 365 | # CONFIG_IP_TCPDIAG is not set |
352 | # CONFIG_IP_TCPDIAG_IPV6 is not set | 366 | # CONFIG_IP_TCPDIAG_IPV6 is not set |
367 | |||
368 | # | ||
369 | # TCP congestion control | ||
370 | # | ||
371 | CONFIG_TCP_CONG_BIC=y | ||
372 | CONFIG_TCP_CONG_WESTWOOD=m | ||
373 | CONFIG_TCP_CONG_HTCP=m | ||
374 | # CONFIG_TCP_CONG_HSTCP is not set | ||
375 | # CONFIG_TCP_CONG_HYBLA is not set | ||
376 | # CONFIG_TCP_CONG_VEGAS is not set | ||
377 | # CONFIG_TCP_CONG_SCALABLE is not set | ||
353 | # CONFIG_IPV6 is not set | 378 | # CONFIG_IPV6 is not set |
354 | # CONFIG_NETFILTER is not set | 379 | # CONFIG_NETFILTER is not set |
355 | 380 | ||
@@ -405,6 +430,7 @@ CONFIG_MII=y | |||
405 | # CONFIG_SUNGEM is not set | 430 | # CONFIG_SUNGEM is not set |
406 | # CONFIG_NET_VENDOR_3COM is not set | 431 | # CONFIG_NET_VENDOR_3COM is not set |
407 | # CONFIG_SMC91X is not set | 432 | # CONFIG_SMC91X is not set |
433 | # CONFIG_DM9000 is not set | ||
408 | 434 | ||
409 | # | 435 | # |
410 | # Tulip family network device support | 436 | # Tulip family network device support |
@@ -442,9 +468,11 @@ CONFIG_EEPRO100=y | |||
442 | # CONFIG_HAMACHI is not set | 468 | # CONFIG_HAMACHI is not set |
443 | # CONFIG_YELLOWFIN is not set | 469 | # CONFIG_YELLOWFIN is not set |
444 | # CONFIG_R8169 is not set | 470 | # CONFIG_R8169 is not set |
471 | # CONFIG_SKGE is not set | ||
445 | # CONFIG_SK98LIN is not set | 472 | # CONFIG_SK98LIN is not set |
446 | # CONFIG_VIA_VELOCITY is not set | 473 | # CONFIG_VIA_VELOCITY is not set |
447 | # CONFIG_TIGON3 is not set | 474 | # CONFIG_TIGON3 is not set |
475 | # CONFIG_BNX2 is not set | ||
448 | 476 | ||
449 | # | 477 | # |
450 | # Ethernet (10000 Mbit) | 478 | # Ethernet (10000 Mbit) |
@@ -466,6 +494,7 @@ CONFIG_EEPRO100=y | |||
466 | # Wan interfaces | 494 | # Wan interfaces |
467 | # | 495 | # |
468 | CONFIG_WAN=y | 496 | CONFIG_WAN=y |
497 | # CONFIG_DSCC4 is not set | ||
469 | # CONFIG_LANMEDIA is not set | 498 | # CONFIG_LANMEDIA is not set |
470 | # CONFIG_SYNCLINK_SYNCPPP is not set | 499 | # CONFIG_SYNCLINK_SYNCPPP is not set |
471 | CONFIG_HDLC=y | 500 | CONFIG_HDLC=y |
@@ -528,7 +557,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | |||
528 | # | 557 | # |
529 | # CONFIG_SERIO is not set | 558 | # CONFIG_SERIO is not set |
530 | # CONFIG_GAMEPORT is not set | 559 | # CONFIG_GAMEPORT is not set |
531 | CONFIG_SOUND_GAMEPORT=y | ||
532 | 560 | ||
533 | # | 561 | # |
534 | # Character devices | 562 | # Character devices |
@@ -549,6 +577,7 @@ CONFIG_SERIAL_8250_NR_UARTS=2 | |||
549 | # | 577 | # |
550 | CONFIG_SERIAL_CORE=y | 578 | CONFIG_SERIAL_CORE=y |
551 | CONFIG_SERIAL_CORE_CONSOLE=y | 579 | CONFIG_SERIAL_CORE_CONSOLE=y |
580 | # CONFIG_SERIAL_JSM is not set | ||
552 | CONFIG_UNIX98_PTYS=y | 581 | CONFIG_UNIX98_PTYS=y |
553 | CONFIG_LEGACY_PTYS=y | 582 | CONFIG_LEGACY_PTYS=y |
554 | CONFIG_LEGACY_PTY_COUNT=256 | 583 | CONFIG_LEGACY_PTY_COUNT=256 |
@@ -615,17 +644,18 @@ CONFIG_I2C_ALGOBIT=y | |||
615 | # CONFIG_I2C_AMD8111 is not set | 644 | # CONFIG_I2C_AMD8111 is not set |
616 | # CONFIG_I2C_I801 is not set | 645 | # CONFIG_I2C_I801 is not set |
617 | # CONFIG_I2C_I810 is not set | 646 | # CONFIG_I2C_I810 is not set |
647 | # CONFIG_I2C_PIIX4 is not set | ||
618 | # CONFIG_I2C_ISA is not set | 648 | # CONFIG_I2C_ISA is not set |
619 | # CONFIG_I2C_IXP2000 is not set | 649 | # CONFIG_I2C_IXP2000 is not set |
620 | # CONFIG_I2C_NFORCE2 is not set | 650 | # CONFIG_I2C_NFORCE2 is not set |
621 | # CONFIG_I2C_PARPORT_LIGHT is not set | 651 | # CONFIG_I2C_PARPORT_LIGHT is not set |
622 | # CONFIG_I2C_PIIX4 is not set | ||
623 | # CONFIG_I2C_PROSAVAGE is not set | 652 | # CONFIG_I2C_PROSAVAGE is not set |
624 | # CONFIG_I2C_SAVAGE4 is not set | 653 | # CONFIG_I2C_SAVAGE4 is not set |
625 | # CONFIG_SCx200_ACB is not set | 654 | # CONFIG_SCx200_ACB is not set |
626 | # CONFIG_I2C_SIS5595 is not set | 655 | # CONFIG_I2C_SIS5595 is not set |
627 | # CONFIG_I2C_SIS630 is not set | 656 | # CONFIG_I2C_SIS630 is not set |
628 | # CONFIG_I2C_SIS96X is not set | 657 | # CONFIG_I2C_SIS96X is not set |
658 | # CONFIG_I2C_STUB is not set | ||
629 | # CONFIG_I2C_VIA is not set | 659 | # CONFIG_I2C_VIA is not set |
630 | # CONFIG_I2C_VIAPRO is not set | 660 | # CONFIG_I2C_VIAPRO is not set |
631 | # CONFIG_I2C_VOODOO3 is not set | 661 | # CONFIG_I2C_VOODOO3 is not set |
@@ -639,7 +669,9 @@ CONFIG_I2C_SENSOR=y | |||
639 | # CONFIG_SENSORS_ADM1025 is not set | 669 | # CONFIG_SENSORS_ADM1025 is not set |
640 | # CONFIG_SENSORS_ADM1026 is not set | 670 | # CONFIG_SENSORS_ADM1026 is not set |
641 | # CONFIG_SENSORS_ADM1031 is not set | 671 | # CONFIG_SENSORS_ADM1031 is not set |
672 | # CONFIG_SENSORS_ADM9240 is not set | ||
642 | # CONFIG_SENSORS_ASB100 is not set | 673 | # CONFIG_SENSORS_ASB100 is not set |
674 | # CONFIG_SENSORS_ATXP1 is not set | ||
643 | # CONFIG_SENSORS_DS1621 is not set | 675 | # CONFIG_SENSORS_DS1621 is not set |
644 | # CONFIG_SENSORS_FSCHER is not set | 676 | # CONFIG_SENSORS_FSCHER is not set |
645 | # CONFIG_SENSORS_FSCPOS is not set | 677 | # CONFIG_SENSORS_FSCPOS is not set |
@@ -655,6 +687,7 @@ CONFIG_I2C_SENSOR=y | |||
655 | # CONFIG_SENSORS_LM85 is not set | 687 | # CONFIG_SENSORS_LM85 is not set |
656 | # CONFIG_SENSORS_LM87 is not set | 688 | # CONFIG_SENSORS_LM87 is not set |
657 | # CONFIG_SENSORS_LM90 is not set | 689 | # CONFIG_SENSORS_LM90 is not set |
690 | # CONFIG_SENSORS_LM92 is not set | ||
658 | # CONFIG_SENSORS_MAX1619 is not set | 691 | # CONFIG_SENSORS_MAX1619 is not set |
659 | # CONFIG_SENSORS_PC87360 is not set | 692 | # CONFIG_SENSORS_PC87360 is not set |
660 | # CONFIG_SENSORS_SMSC47B397 is not set | 693 | # CONFIG_SENSORS_SMSC47B397 is not set |
@@ -664,14 +697,19 @@ CONFIG_I2C_SENSOR=y | |||
664 | # CONFIG_SENSORS_W83781D is not set | 697 | # CONFIG_SENSORS_W83781D is not set |
665 | # CONFIG_SENSORS_W83L785TS is not set | 698 | # CONFIG_SENSORS_W83L785TS is not set |
666 | # CONFIG_SENSORS_W83627HF is not set | 699 | # CONFIG_SENSORS_W83627HF is not set |
700 | # CONFIG_SENSORS_W83627EHF is not set | ||
667 | 701 | ||
668 | # | 702 | # |
669 | # Other I2C Chip support | 703 | # Other I2C Chip support |
670 | # | 704 | # |
705 | # CONFIG_SENSORS_DS1337 is not set | ||
706 | # CONFIG_SENSORS_DS1374 is not set | ||
671 | CONFIG_SENSORS_EEPROM=y | 707 | CONFIG_SENSORS_EEPROM=y |
672 | # CONFIG_SENSORS_PCF8574 is not set | 708 | # CONFIG_SENSORS_PCF8574 is not set |
709 | # CONFIG_SENSORS_PCA9539 is not set | ||
673 | # CONFIG_SENSORS_PCF8591 is not set | 710 | # CONFIG_SENSORS_PCF8591 is not set |
674 | # CONFIG_SENSORS_RTC8564 is not set | 711 | # CONFIG_SENSORS_RTC8564 is not set |
712 | # CONFIG_SENSORS_MAX6875 is not set | ||
675 | # CONFIG_I2C_DEBUG_CORE is not set | 713 | # CONFIG_I2C_DEBUG_CORE is not set |
676 | # CONFIG_I2C_DEBUG_ALGO is not set | 714 | # CONFIG_I2C_DEBUG_ALGO is not set |
677 | # CONFIG_I2C_DEBUG_BUS is not set | 715 | # CONFIG_I2C_DEBUG_BUS is not set |
@@ -725,6 +763,7 @@ CONFIG_EXT2_FS=y | |||
725 | CONFIG_EXT2_FS_XATTR=y | 763 | CONFIG_EXT2_FS_XATTR=y |
726 | CONFIG_EXT2_FS_POSIX_ACL=y | 764 | CONFIG_EXT2_FS_POSIX_ACL=y |
727 | # CONFIG_EXT2_FS_SECURITY is not set | 765 | # CONFIG_EXT2_FS_SECURITY is not set |
766 | # CONFIG_EXT2_FS_XIP is not set | ||
728 | CONFIG_EXT3_FS=y | 767 | CONFIG_EXT3_FS=y |
729 | CONFIG_EXT3_FS_XATTR=y | 768 | CONFIG_EXT3_FS_XATTR=y |
730 | CONFIG_EXT3_FS_POSIX_ACL=y | 769 | CONFIG_EXT3_FS_POSIX_ACL=y |
@@ -765,7 +804,6 @@ CONFIG_DNOTIFY=y | |||
765 | # | 804 | # |
766 | CONFIG_PROC_FS=y | 805 | CONFIG_PROC_FS=y |
767 | CONFIG_SYSFS=y | 806 | CONFIG_SYSFS=y |
768 | # CONFIG_DEVFS_FS is not set | ||
769 | # CONFIG_DEVPTS_FS_XATTR is not set | 807 | # CONFIG_DEVPTS_FS_XATTR is not set |
770 | CONFIG_TMPFS=y | 808 | CONFIG_TMPFS=y |
771 | # CONFIG_TMPFS_XATTR is not set | 809 | # CONFIG_TMPFS_XATTR is not set |
@@ -803,12 +841,14 @@ CONFIG_JFFS2_RTIME=y | |||
803 | # | 841 | # |
804 | CONFIG_NFS_FS=y | 842 | CONFIG_NFS_FS=y |
805 | CONFIG_NFS_V3=y | 843 | CONFIG_NFS_V3=y |
844 | # CONFIG_NFS_V3_ACL is not set | ||
806 | # CONFIG_NFS_V4 is not set | 845 | # CONFIG_NFS_V4 is not set |
807 | # CONFIG_NFS_DIRECTIO is not set | 846 | # CONFIG_NFS_DIRECTIO is not set |
808 | # CONFIG_NFSD is not set | 847 | # CONFIG_NFSD is not set |
809 | CONFIG_ROOT_NFS=y | 848 | CONFIG_ROOT_NFS=y |
810 | CONFIG_LOCKD=y | 849 | CONFIG_LOCKD=y |
811 | CONFIG_LOCKD_V4=y | 850 | CONFIG_LOCKD_V4=y |
851 | CONFIG_NFS_COMMON=y | ||
812 | CONFIG_SUNRPC=y | 852 | CONFIG_SUNRPC=y |
813 | # CONFIG_RPCSEC_GSS_KRB5 is not set | 853 | # CONFIG_RPCSEC_GSS_KRB5 is not set |
814 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | 854 | # CONFIG_RPCSEC_GSS_SPKM3 is not set |
@@ -893,3 +933,4 @@ CONFIG_CRC32=y | |||
893 | # CONFIG_LIBCRC32C is not set | 933 | # CONFIG_LIBCRC32C is not set |
894 | CONFIG_ZLIB_INFLATE=y | 934 | CONFIG_ZLIB_INFLATE=y |
895 | CONFIG_ZLIB_DEFLATE=y | 935 | CONFIG_ZLIB_DEFLATE=y |
936 | # CONFIG_TEXTSEARCH is not set | ||
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index ff187f4308f0..395137a8fad2 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c | |||
@@ -4,6 +4,10 @@ | |||
4 | * Copyright (C) 1992 Linus Torvalds | 4 | * Copyright (C) 1992 Linus Torvalds |
5 | * Modifications for ARM processor Copyright (C) 1995-2000 Russell King. | 5 | * Modifications for ARM processor Copyright (C) 1995-2000 Russell King. |
6 | * | 6 | * |
7 | * Support for Dynamic Tick Timer Copyright (C) 2004-2005 Nokia Corporation. | ||
8 | * Dynamic Tick Timer written by Tony Lindgren <tony@atomide.com> and | ||
9 | * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>. | ||
10 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 12 | * it under the terms of the GNU General Public License version 2 as |
9 | * published by the Free Software Foundation. | 13 | * published by the Free Software Foundation. |
@@ -37,6 +41,7 @@ | |||
37 | #include <asm/irq.h> | 41 | #include <asm/irq.h> |
38 | #include <asm/system.h> | 42 | #include <asm/system.h> |
39 | #include <asm/mach/irq.h> | 43 | #include <asm/mach/irq.h> |
44 | #include <asm/mach/time.h> | ||
40 | 45 | ||
41 | /* | 46 | /* |
42 | * Maximum IRQ count. Currently, this is arbitary. However, it should | 47 | * Maximum IRQ count. Currently, this is arbitary. However, it should |
@@ -329,6 +334,15 @@ __do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs) | |||
329 | 334 | ||
330 | spin_unlock(&irq_controller_lock); | 335 | spin_unlock(&irq_controller_lock); |
331 | 336 | ||
337 | #ifdef CONFIG_NO_IDLE_HZ | ||
338 | if (!(action->flags & SA_TIMER) && system_timer->dyn_tick != NULL) { | ||
339 | write_seqlock(&xtime_lock); | ||
340 | if (system_timer->dyn_tick->state & DYN_TICK_ENABLED) | ||
341 | system_timer->dyn_tick->handler(irq, 0, regs); | ||
342 | write_sequnlock(&xtime_lock); | ||
343 | } | ||
344 | #endif | ||
345 | |||
332 | if (!(action->flags & SA_INTERRUPT)) | 346 | if (!(action->flags & SA_INTERRUPT)) |
333 | local_irq_enable(); | 347 | local_irq_enable(); |
334 | 348 | ||
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index c232f24f4a60..06054c9ba074 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c | |||
@@ -381,6 +381,95 @@ static struct sysdev_class timer_sysclass = { | |||
381 | .resume = timer_resume, | 381 | .resume = timer_resume, |
382 | }; | 382 | }; |
383 | 383 | ||
384 | #ifdef CONFIG_NO_IDLE_HZ | ||
385 | static int timer_dyn_tick_enable(void) | ||
386 | { | ||
387 | struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick; | ||
388 | unsigned long flags; | ||
389 | int ret = -ENODEV; | ||
390 | |||
391 | if (dyn_tick) { | ||
392 | write_seqlock_irqsave(&xtime_lock, flags); | ||
393 | ret = 0; | ||
394 | if (!(dyn_tick->state & DYN_TICK_ENABLED)) { | ||
395 | ret = dyn_tick->enable(); | ||
396 | |||
397 | if (ret == 0) | ||
398 | dyn_tick->state |= DYN_TICK_ENABLED; | ||
399 | } | ||
400 | write_sequnlock_irqrestore(&xtime_lock, flags); | ||
401 | } | ||
402 | |||
403 | return ret; | ||
404 | } | ||
405 | |||
406 | static int timer_dyn_tick_disable(void) | ||
407 | { | ||
408 | struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick; | ||
409 | unsigned long flags; | ||
410 | int ret = -ENODEV; | ||
411 | |||
412 | if (dyn_tick) { | ||
413 | write_seqlock_irqsave(&xtime_lock, flags); | ||
414 | ret = 0; | ||
415 | if (dyn_tick->state & DYN_TICK_ENABLED) { | ||
416 | ret = dyn_tick->disable(); | ||
417 | |||
418 | if (ret == 0) | ||
419 | dyn_tick->state &= ~DYN_TICK_ENABLED; | ||
420 | } | ||
421 | write_sequnlock_irqrestore(&xtime_lock, flags); | ||
422 | } | ||
423 | |||
424 | return ret; | ||
425 | } | ||
426 | |||
427 | void timer_dyn_reprogram(void) | ||
428 | { | ||
429 | struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick; | ||
430 | unsigned long flags; | ||
431 | |||
432 | write_seqlock_irqsave(&xtime_lock, flags); | ||
433 | if (dyn_tick->state & DYN_TICK_ENABLED) | ||
434 | dyn_tick->reprogram(next_timer_interrupt() - jiffies); | ||
435 | write_sequnlock_irqrestore(&xtime_lock, flags); | ||
436 | } | ||
437 | |||
438 | static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf) | ||
439 | { | ||
440 | return sprintf(buf, "%i\n", | ||
441 | (system_timer->dyn_tick->state & DYN_TICK_ENABLED) >> 1); | ||
442 | } | ||
443 | |||
444 | static ssize_t timer_set_dyn_tick(struct sys_device *dev, const char *buf, | ||
445 | size_t count) | ||
446 | { | ||
447 | unsigned int enable = simple_strtoul(buf, NULL, 2); | ||
448 | |||
449 | if (enable) | ||
450 | timer_dyn_tick_enable(); | ||
451 | else | ||
452 | timer_dyn_tick_disable(); | ||
453 | |||
454 | return count; | ||
455 | } | ||
456 | static SYSDEV_ATTR(dyn_tick, 0644, timer_show_dyn_tick, timer_set_dyn_tick); | ||
457 | |||
458 | /* | ||
459 | * dyntick=enable|disable | ||
460 | */ | ||
461 | static char dyntick_str[4] __initdata = ""; | ||
462 | |||
463 | static int __init dyntick_setup(char *str) | ||
464 | { | ||
465 | if (str) | ||
466 | strlcpy(dyntick_str, str, sizeof(dyntick_str)); | ||
467 | return 1; | ||
468 | } | ||
469 | |||
470 | __setup("dyntick=", dyntick_setup); | ||
471 | #endif | ||
472 | |||
384 | static int __init timer_init_sysfs(void) | 473 | static int __init timer_init_sysfs(void) |
385 | { | 474 | { |
386 | int ret = sysdev_class_register(&timer_sysclass); | 475 | int ret = sysdev_class_register(&timer_sysclass); |
@@ -388,6 +477,20 @@ static int __init timer_init_sysfs(void) | |||
388 | system_timer->dev.cls = &timer_sysclass; | 477 | system_timer->dev.cls = &timer_sysclass; |
389 | ret = sysdev_register(&system_timer->dev); | 478 | ret = sysdev_register(&system_timer->dev); |
390 | } | 479 | } |
480 | |||
481 | #ifdef CONFIG_NO_IDLE_HZ | ||
482 | if (ret == 0 && system_timer->dyn_tick) { | ||
483 | ret = sysdev_create_file(&system_timer->dev, &attr_dyn_tick); | ||
484 | |||
485 | /* | ||
486 | * Turn on dynamic tick after calibrate delay | ||
487 | * for correct bogomips | ||
488 | */ | ||
489 | if (ret == 0 && dyntick_str[0] == 'e') | ||
490 | ret = timer_dyn_tick_enable(); | ||
491 | } | ||
492 | #endif | ||
493 | |||
391 | return ret; | 494 | return ret; |
392 | } | 495 | } |
393 | 496 | ||
diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig index 45c930ccd064..0793dcf54f2e 100644 --- a/arch/arm/mach-clps711x/Kconfig +++ b/arch/arm/mach-clps711x/Kconfig | |||
@@ -28,7 +28,7 @@ config ARCH_CLEP7312 | |||
28 | config ARCH_EDB7211 | 28 | config ARCH_EDB7211 |
29 | bool "EDB7211" | 29 | bool "EDB7211" |
30 | select ISA | 30 | select ISA |
31 | select DISCONTIGMEM | 31 | select ARCH_DISCONTIGMEM_ENABLE |
32 | help | 32 | help |
33 | Say Y here if you intend to run this kernel on a Cirrus Logic EDB-7211 | 33 | Say Y here if you intend to run this kernel on a Cirrus Logic EDB-7211 |
34 | evaluation board. | 34 | evaluation board. |
diff --git a/arch/arm/mach-ixp2000/Kconfig b/arch/arm/mach-ixp2000/Kconfig index 9361e05f6fa3..ecb58d83478e 100644 --- a/arch/arm/mach-ixp2000/Kconfig +++ b/arch/arm/mach-ixp2000/Kconfig | |||
@@ -54,6 +54,14 @@ config ARCH_IXDP2X01 | |||
54 | depends on ARCH_IXDP2401 || ARCH_IXDP2801 | 54 | depends on ARCH_IXDP2401 || ARCH_IXDP2801 |
55 | default y | 55 | default y |
56 | 56 | ||
57 | config IXP2000_SUPPORT_BROKEN_PCI_IO | ||
58 | bool "Support broken PCI I/O on older IXP2000s" | ||
59 | default y | ||
60 | help | ||
61 | Say 'N' here if you only intend to run your kernel on an | ||
62 | IXP2000 B0 or later model and do not need the PCI I/O | ||
63 | byteswap workaround. Say 'Y' otherwise. | ||
64 | |||
57 | endmenu | 65 | endmenu |
58 | 66 | ||
59 | endif | 67 | endif |
diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c index 04b38bcf9aac..f3a291b6a9fb 100644 --- a/arch/arm/mach-ixp2000/enp2611.c +++ b/arch/arm/mach-ixp2000/enp2611.c | |||
@@ -197,8 +197,23 @@ static struct platform_device enp2611_flash = { | |||
197 | .resource = &enp2611_flash_resource, | 197 | .resource = &enp2611_flash_resource, |
198 | }; | 198 | }; |
199 | 199 | ||
200 | static struct ixp2000_i2c_pins enp2611_i2c_gpio_pins = { | ||
201 | .sda_pin = ENP2611_GPIO_SDA, | ||
202 | .scl_pin = ENP2611_GPIO_SCL, | ||
203 | }; | ||
204 | |||
205 | static struct platform_device enp2611_i2c_controller = { | ||
206 | .name = "IXP2000-I2C", | ||
207 | .id = 0, | ||
208 | .dev = { | ||
209 | .platform_data = &enp2611_i2c_gpio_pins | ||
210 | }, | ||
211 | .num_resources = 0 | ||
212 | }; | ||
213 | |||
200 | static struct platform_device *enp2611_devices[] __initdata = { | 214 | static struct platform_device *enp2611_devices[] __initdata = { |
201 | &enp2611_flash | 215 | &enp2611_flash, |
216 | &enp2611_i2c_controller | ||
202 | }; | 217 | }; |
203 | 218 | ||
204 | static void __init enp2611_init_machine(void) | 219 | static void __init enp2611_init_machine(void) |
diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c index 21c41fe15b99..5e4380747b53 100644 --- a/arch/arm/mach-ixp2000/ixdp2x00.c +++ b/arch/arm/mach-ixp2000/ixdp2x00.c | |||
@@ -42,6 +42,9 @@ | |||
42 | #include <asm/mach/flash.h> | 42 | #include <asm/mach/flash.h> |
43 | #include <asm/mach/arch.h> | 43 | #include <asm/mach/arch.h> |
44 | 44 | ||
45 | #include <asm/arch/gpio.h> | ||
46 | |||
47 | |||
45 | /************************************************************************* | 48 | /************************************************************************* |
46 | * IXDP2x00 IRQ Initialization | 49 | * IXDP2x00 IRQ Initialization |
47 | *************************************************************************/ | 50 | *************************************************************************/ |
diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c index 5ff2f2718c58..0788fb2b5c10 100644 --- a/arch/arm/mach-ixp2000/pci.c +++ b/arch/arm/mach-ixp2000/pci.c | |||
@@ -198,6 +198,19 @@ clear_master_aborts(void) | |||
198 | void __init | 198 | void __init |
199 | ixp2000_pci_preinit(void) | 199 | ixp2000_pci_preinit(void) |
200 | { | 200 | { |
201 | #ifndef CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO | ||
202 | /* | ||
203 | * Configure the PCI unit to properly byteswap I/O transactions, | ||
204 | * and verify that it worked. | ||
205 | */ | ||
206 | ixp2000_reg_write(IXP2000_PCI_CONTROL, | ||
207 | (*IXP2000_PCI_CONTROL | PCI_CONTROL_IEE)); | ||
208 | |||
209 | if ((*IXP2000_PCI_CONTROL & PCI_CONTROL_IEE) == 0) | ||
210 | panic("IXP2000: PCI I/O is broken on this ixp model, and " | ||
211 | "the needed workaround has not been configured in"); | ||
212 | #endif | ||
213 | |||
201 | hook_fault_code(16+6, ixp2000_pci_abort_handler, SIGBUS, | 214 | hook_fault_code(16+6, ixp2000_pci_abort_handler, SIGBUS, |
202 | "PCI config cycle to non-existent device"); | 215 | "PCI config cycle to non-existent device"); |
203 | } | 216 | } |
diff --git a/arch/frv/kernel/setup.c b/arch/frv/kernel/setup.c index ef6865f0b979..767ebb55bd83 100644 --- a/arch/frv/kernel/setup.c +++ b/arch/frv/kernel/setup.c | |||
@@ -790,12 +790,10 @@ void __init setup_arch(char **cmdline_p) | |||
790 | #ifndef CONFIG_GDBSTUB_UART0 | 790 | #ifndef CONFIG_GDBSTUB_UART0 |
791 | __reg(UART0_BASE + UART_IER * 8) = 0; | 791 | __reg(UART0_BASE + UART_IER * 8) = 0; |
792 | early_serial_setup(&__frv_uart0); | 792 | early_serial_setup(&__frv_uart0); |
793 | // register_serial(&__frv_uart0); | ||
794 | #endif | 793 | #endif |
795 | #ifndef CONFIG_GDBSTUB_UART1 | 794 | #ifndef CONFIG_GDBSTUB_UART1 |
796 | __reg(UART1_BASE + UART_IER * 8) = 0; | 795 | __reg(UART1_BASE + UART_IER * 8) = 0; |
797 | early_serial_setup(&__frv_uart1); | 796 | early_serial_setup(&__frv_uart1); |
798 | // register_serial(&__frv_uart1); | ||
799 | #endif | 797 | #endif |
800 | 798 | ||
801 | #if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH) | 799 | #if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH) |
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index d4ae5f9ceae6..6c02336fe2e4 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig | |||
@@ -510,28 +510,7 @@ config SCHED_SMT | |||
510 | cost of slightly increased overhead in some places. If unsure say | 510 | cost of slightly increased overhead in some places. If unsure say |
511 | N here. | 511 | N here. |
512 | 512 | ||
513 | config PREEMPT | 513 | source "kernel/Kconfig.preempt" |
514 | bool "Preemptible Kernel" | ||
515 | help | ||
516 | This option reduces the latency of the kernel when reacting to | ||
517 | real-time or interactive events by allowing a low priority process to | ||
518 | be preempted even if it is in kernel mode executing a system call. | ||
519 | This allows applications to run more reliably even when the system is | ||
520 | under load. | ||
521 | |||
522 | Say Y here if you are building a kernel for a desktop, embedded | ||
523 | or real-time system. Say N if you are unsure. | ||
524 | |||
525 | config PREEMPT_BKL | ||
526 | bool "Preempt The Big Kernel Lock" | ||
527 | depends on PREEMPT | ||
528 | default y | ||
529 | help | ||
530 | This option reduces the latency of the kernel by making the | ||
531 | big kernel lock preemptible. | ||
532 | |||
533 | Say Y here if you are building a kernel for a desktop system. | ||
534 | Say N if you are unsure. | ||
535 | 514 | ||
536 | config X86_UP_APIC | 515 | config X86_UP_APIC |
537 | bool "Local APIC support on uniprocessors" | 516 | bool "Local APIC support on uniprocessors" |
@@ -963,6 +942,41 @@ config SECCOMP | |||
963 | 942 | ||
964 | source kernel/Kconfig.hz | 943 | source kernel/Kconfig.hz |
965 | 944 | ||
945 | config PHYSICAL_START | ||
946 | hex "Physical address where the kernel is loaded" if EMBEDDED | ||
947 | default "0x100000" | ||
948 | help | ||
949 | This gives the physical address where the kernel is loaded. | ||
950 | Primarily used in the case of kexec on panic where the | ||
951 | fail safe kernel needs to run at a different address than | ||
952 | the panic-ed kernel. | ||
953 | |||
954 | Don't change this unless you know what you are doing. | ||
955 | |||
956 | config KEXEC | ||
957 | bool "kexec system call (EXPERIMENTAL)" | ||
958 | depends on EXPERIMENTAL | ||
959 | help | ||
960 | kexec is a system call that implements the ability to shutdown your | ||
961 | current kernel, and to start another kernel. It is like a reboot | ||
962 | but it is indepedent of the system firmware. And like a reboot | ||
963 | you can start any kernel with it, not just Linux. | ||
964 | |||
965 | The name comes from the similiarity to the exec system call. | ||
966 | |||
967 | It is an ongoing process to be certain the hardware in a machine | ||
968 | is properly shutdown, so do not be surprised if this code does not | ||
969 | initially work for you. It may help to enable device hotplugging | ||
970 | support. As of this writing the exact hardware interface is | ||
971 | strongly in flux, so no good recommendation can be made. | ||
972 | |||
973 | config CRASH_DUMP | ||
974 | bool "kernel crash dumps (EXPERIMENTAL)" | ||
975 | depends on EMBEDDED | ||
976 | depends on EXPERIMENTAL | ||
977 | depends on HIGHMEM | ||
978 | help | ||
979 | Generate crash dump after being started by kexec. | ||
966 | endmenu | 980 | endmenu |
967 | 981 | ||
968 | 982 | ||
@@ -1250,6 +1264,15 @@ config SCx200 | |||
1250 | This support is also available as a module. If compiled as a | 1264 | This support is also available as a module. If compiled as a |
1251 | module, it will be called scx200. | 1265 | module, it will be called scx200. |
1252 | 1266 | ||
1267 | config HOTPLUG_CPU | ||
1268 | bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" | ||
1269 | depends on SMP && HOTPLUG && EXPERIMENTAL | ||
1270 | ---help--- | ||
1271 | Say Y here to experiment with turning CPUs off and on. CPUs | ||
1272 | can be controlled through /sys/devices/system/cpu. | ||
1273 | |||
1274 | Say N. | ||
1275 | |||
1253 | source "drivers/pcmcia/Kconfig" | 1276 | source "drivers/pcmcia/Kconfig" |
1254 | 1277 | ||
1255 | source "drivers/pci/hotplug/Kconfig" | 1278 | source "drivers/pci/hotplug/Kconfig" |
diff --git a/arch/i386/boot/Makefile b/arch/i386/boot/Makefile index 43cd6220ee49..1e71382d413a 100644 --- a/arch/i386/boot/Makefile +++ b/arch/i386/boot/Makefile | |||
@@ -25,8 +25,8 @@ SVGA_MODE := -DSVGA_MODE=NORMAL_VGA | |||
25 | 25 | ||
26 | #RAMDISK := -DRAMDISK=512 | 26 | #RAMDISK := -DRAMDISK=512 |
27 | 27 | ||
28 | targets := vmlinux.bin bootsect bootsect.o setup setup.o \ | 28 | targets := vmlinux.bin bootsect bootsect.o \ |
29 | zImage bzImage | 29 | setup setup.o zImage bzImage |
30 | subdir- := compressed | 30 | subdir- := compressed |
31 | 31 | ||
32 | hostprogs-y := tools/build | 32 | hostprogs-y := tools/build |
diff --git a/arch/i386/boot/compressed/head.S b/arch/i386/boot/compressed/head.S index c5e80b69e7d4..b5893e4ecd37 100644 --- a/arch/i386/boot/compressed/head.S +++ b/arch/i386/boot/compressed/head.S | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #include <linux/linkage.h> | 26 | #include <linux/linkage.h> |
27 | #include <asm/segment.h> | 27 | #include <asm/segment.h> |
28 | #include <asm/page.h> | ||
28 | 29 | ||
29 | .globl startup_32 | 30 | .globl startup_32 |
30 | 31 | ||
@@ -74,7 +75,7 @@ startup_32: | |||
74 | popl %esi # discard address | 75 | popl %esi # discard address |
75 | popl %esi # real mode pointer | 76 | popl %esi # real mode pointer |
76 | xorl %ebx,%ebx | 77 | xorl %ebx,%ebx |
77 | ljmp $(__BOOT_CS), $0x100000 | 78 | ljmp $(__BOOT_CS), $__PHYSICAL_START |
78 | 79 | ||
79 | /* | 80 | /* |
80 | * We come here, if we were loaded high. | 81 | * We come here, if we were loaded high. |
@@ -99,7 +100,7 @@ startup_32: | |||
99 | popl %ecx # lcount | 100 | popl %ecx # lcount |
100 | popl %edx # high_buffer_start | 101 | popl %edx # high_buffer_start |
101 | popl %eax # hcount | 102 | popl %eax # hcount |
102 | movl $0x100000,%edi | 103 | movl $__PHYSICAL_START,%edi |
103 | cli # make sure we don't get interrupted | 104 | cli # make sure we don't get interrupted |
104 | ljmp $(__BOOT_CS), $0x1000 # and jump to the move routine | 105 | ljmp $(__BOOT_CS), $0x1000 # and jump to the move routine |
105 | 106 | ||
@@ -124,5 +125,5 @@ move_routine_start: | |||
124 | movsl | 125 | movsl |
125 | movl %ebx,%esi # Restore setup pointer | 126 | movl %ebx,%esi # Restore setup pointer |
126 | xorl %ebx,%ebx | 127 | xorl %ebx,%ebx |
127 | ljmp $(__BOOT_CS), $0x100000 | 128 | ljmp $(__BOOT_CS), $__PHYSICAL_START |
128 | move_routine_end: | 129 | move_routine_end: |
diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c index cedc55cc47de..82a807f9f5e6 100644 --- a/arch/i386/boot/compressed/misc.c +++ b/arch/i386/boot/compressed/misc.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/vmalloc.h> | 13 | #include <linux/vmalloc.h> |
14 | #include <linux/tty.h> | 14 | #include <linux/tty.h> |
15 | #include <asm/io.h> | 15 | #include <asm/io.h> |
16 | #include <asm/page.h> | ||
16 | 17 | ||
17 | /* | 18 | /* |
18 | * gzip declarations | 19 | * gzip declarations |
@@ -308,7 +309,7 @@ static void setup_normal_output_buffer(void) | |||
308 | #else | 309 | #else |
309 | if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < 1024) error("Less than 2MB of memory"); | 310 | if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < 1024) error("Less than 2MB of memory"); |
310 | #endif | 311 | #endif |
311 | output_data = (char *)0x100000; /* Points to 1M */ | 312 | output_data = (char *)__PHYSICAL_START; /* Normally Points to 1M */ |
312 | free_mem_end_ptr = (long)real_mode; | 313 | free_mem_end_ptr = (long)real_mode; |
313 | } | 314 | } |
314 | 315 | ||
@@ -333,8 +334,8 @@ static void setup_output_buffer_if_we_run_high(struct moveparams *mv) | |||
333 | low_buffer_size = low_buffer_end - LOW_BUFFER_START; | 334 | low_buffer_size = low_buffer_end - LOW_BUFFER_START; |
334 | high_loaded = 1; | 335 | high_loaded = 1; |
335 | free_mem_end_ptr = (long)high_buffer_start; | 336 | free_mem_end_ptr = (long)high_buffer_start; |
336 | if ( (0x100000 + low_buffer_size) > ((ulg)high_buffer_start)) { | 337 | if ( (__PHYSICAL_START + low_buffer_size) > ((ulg)high_buffer_start)) { |
337 | high_buffer_start = (uch *)(0x100000 + low_buffer_size); | 338 | high_buffer_start = (uch *)(__PHYSICAL_START + low_buffer_size); |
338 | mv->hcount = 0; /* say: we need not to move high_buffer */ | 339 | mv->hcount = 0; /* say: we need not to move high_buffer */ |
339 | } | 340 | } |
340 | else mv->hcount = -1; | 341 | else mv->hcount = -1; |
@@ -353,7 +354,6 @@ static void close_output_buffer_if_we_run_high(struct moveparams *mv) | |||
353 | } | 354 | } |
354 | } | 355 | } |
355 | 356 | ||
356 | |||
357 | asmlinkage int decompress_kernel(struct moveparams *mv, void *rmode) | 357 | asmlinkage int decompress_kernel(struct moveparams *mv, void *rmode) |
358 | { | 358 | { |
359 | real_mode = rmode; | 359 | real_mode = rmode; |
diff --git a/arch/i386/boot/edd.S b/arch/i386/boot/edd.S index 027d6b354ffb..d8d69f2b911d 100644 --- a/arch/i386/boot/edd.S +++ b/arch/i386/boot/edd.S | |||
@@ -6,7 +6,7 @@ | |||
6 | * projects 1572D, 1484D, 1386D, 1226DT | 6 | * projects 1572D, 1484D, 1386D, 1226DT |
7 | * disk signature read by Matt Domsch <Matt_Domsch@dell.com> | 7 | * disk signature read by Matt Domsch <Matt_Domsch@dell.com> |
8 | * and Andrew Wilks <Andrew_Wilks@dell.com> September 2003, June 2004 | 8 | * and Andrew Wilks <Andrew_Wilks@dell.com> September 2003, June 2004 |
9 | * legacy CHS retreival by Patrick J. LoPresti <patl@users.sourceforge.net> | 9 | * legacy CHS retrieval by Patrick J. LoPresti <patl@users.sourceforge.net> |
10 | * March 2004 | 10 | * March 2004 |
11 | * Command line option parsing, Matt Domsch, November 2004 | 11 | * Command line option parsing, Matt Domsch, November 2004 |
12 | */ | 12 | */ |
diff --git a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S index caa1fde6904e..8cb420f40c58 100644 --- a/arch/i386/boot/setup.S +++ b/arch/i386/boot/setup.S | |||
@@ -33,7 +33,7 @@ | |||
33 | * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999. | 33 | * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999. |
34 | * <stiker@northlink.com> | 34 | * <stiker@northlink.com> |
35 | * | 35 | * |
36 | * Fix to work around buggy BIOSes which dont use carry bit correctly | 36 | * Fix to work around buggy BIOSes which don't use carry bit correctly |
37 | * and/or report extended memory in CX/DX for e801h memory size detection | 37 | * and/or report extended memory in CX/DX for e801h memory size detection |
38 | * call. As a result the kernel got wrong figures. The int15/e801h docs | 38 | * call. As a result the kernel got wrong figures. The int15/e801h docs |
39 | * from Ralf Brown interrupt list seem to indicate AX/BX should be used | 39 | * from Ralf Brown interrupt list seem to indicate AX/BX should be used |
@@ -357,7 +357,7 @@ bail820: | |||
357 | 357 | ||
358 | meme801: | 358 | meme801: |
359 | stc # fix to work around buggy | 359 | stc # fix to work around buggy |
360 | xorw %cx,%cx # BIOSes which dont clear/set | 360 | xorw %cx,%cx # BIOSes which don't clear/set |
361 | xorw %dx,%dx # carry on pass/error of | 361 | xorw %dx,%dx # carry on pass/error of |
362 | # e801h memory size call | 362 | # e801h memory size call |
363 | # or merely pass cx,dx though | 363 | # or merely pass cx,dx though |
@@ -847,7 +847,7 @@ flush_instr: | |||
847 | # | 847 | # |
848 | # but we yet haven't reloaded the CS register, so the default size | 848 | # but we yet haven't reloaded the CS register, so the default size |
849 | # of the target offset still is 16 bit. | 849 | # of the target offset still is 16 bit. |
850 | # However, using an operand prefix (0x66), the CPU will properly | 850 | # However, using an operand prefix (0x66), the CPU will properly |
851 | # take our 48 bit far pointer. (INTeL 80386 Programmer's Reference | 851 | # take our 48 bit far pointer. (INTeL 80386 Programmer's Reference |
852 | # Manual, Mixing 16-bit and 32-bit code, page 16-6) | 852 | # Manual, Mixing 16-bit and 32-bit code, page 16-6) |
853 | 853 | ||
diff --git a/arch/i386/boot/tools/build.c b/arch/i386/boot/tools/build.c index 26509b826aed..4a17956512e1 100644 --- a/arch/i386/boot/tools/build.c +++ b/arch/i386/boot/tools/build.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: build.c,v 1.5 1997/05/19 12:29:58 mj Exp $ | ||
3 | * | ||
4 | * Copyright (C) 1991, 1992 Linus Torvalds | 2 | * Copyright (C) 1991, 1992 Linus Torvalds |
5 | * Copyright (C) 1997 Martin Mares | 3 | * Copyright (C) 1997 Martin Mares |
6 | */ | 4 | */ |
@@ -8,7 +6,8 @@ | |||
8 | /* | 6 | /* |
9 | * This file builds a disk-image from three different files: | 7 | * This file builds a disk-image from three different files: |
10 | * | 8 | * |
11 | * - bootsect: exactly 512 bytes of 8086 machine code, loads the rest | 9 | * - bootsect: compatibility mbr which prints an error message if |
10 | * someone tries to boot the kernel directly. | ||
12 | * - setup: 8086 machine code, sets up system parm | 11 | * - setup: 8086 machine code, sets up system parm |
13 | * - system: 80386 code for actual system | 12 | * - system: 80386 code for actual system |
14 | * | 13 | * |
diff --git a/arch/i386/crypto/aes.c b/arch/i386/crypto/aes.c index 1019430fc1f1..88ee85c3b43b 100644 --- a/arch/i386/crypto/aes.c +++ b/arch/i386/crypto/aes.c | |||
@@ -59,7 +59,7 @@ struct aes_ctx { | |||
59 | }; | 59 | }; |
60 | 60 | ||
61 | #define WPOLY 0x011b | 61 | #define WPOLY 0x011b |
62 | #define u32_in(x) le32_to_cpu(*(const u32 *)(x)) | 62 | #define u32_in(x) le32_to_cpup((const __le32 *)(x)) |
63 | #define bytes2word(b0, b1, b2, b3) \ | 63 | #define bytes2word(b0, b1, b2, b3) \ |
64 | (((u32)(b3) << 24) | ((u32)(b2) << 16) | ((u32)(b1) << 8) | (b0)) | 64 | (((u32)(b3) << 24) | ((u32)(b2) << 16) | ((u32)(b1) << 8) | (b0)) |
65 | 65 | ||
diff --git a/arch/i386/defconfig b/arch/i386/defconfig index 28e620383799..ca07b95c06b8 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig | |||
@@ -126,7 +126,6 @@ CONFIG_HAVE_DEC_LOCK=y | |||
126 | # | 126 | # |
127 | CONFIG_PM=y | 127 | CONFIG_PM=y |
128 | CONFIG_SOFTWARE_SUSPEND=y | 128 | CONFIG_SOFTWARE_SUSPEND=y |
129 | # CONFIG_PM_DISK is not set | ||
130 | 129 | ||
131 | # | 130 | # |
132 | # ACPI (Advanced Configuration and Power Interface) Support | 131 | # ACPI (Advanced Configuration and Power Interface) Support |
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile index 51ecd512603d..4cc83b322b36 100644 --- a/arch/i386/kernel/Makefile +++ b/arch/i386/kernel/Makefile | |||
@@ -24,6 +24,7 @@ obj-$(CONFIG_X86_MPPARSE) += mpparse.o | |||
24 | obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o | 24 | obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o |
25 | obj-$(CONFIG_X86_IO_APIC) += io_apic.o | 25 | obj-$(CONFIG_X86_IO_APIC) += io_apic.o |
26 | obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups.o | 26 | obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups.o |
27 | obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o | ||
27 | obj-$(CONFIG_X86_NUMAQ) += numaq.o | 28 | obj-$(CONFIG_X86_NUMAQ) += numaq.o |
28 | obj-$(CONFIG_X86_SUMMIT_NUMA) += summit.o | 29 | obj-$(CONFIG_X86_SUMMIT_NUMA) += summit.o |
29 | obj-$(CONFIG_KPROBES) += kprobes.o | 30 | obj-$(CONFIG_KPROBES) += kprobes.o |
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 848bb97af7ca..9f63ae0f404b 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/efi.h> | 29 | #include <linux/efi.h> |
30 | #include <linux/irq.h> | 30 | #include <linux/irq.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/dmi.h> | ||
32 | 33 | ||
33 | #include <asm/pgtable.h> | 34 | #include <asm/pgtable.h> |
34 | #include <asm/io_apic.h> | 35 | #include <asm/io_apic.h> |
@@ -815,6 +816,219 @@ acpi_process_madt(void) | |||
815 | return; | 816 | return; |
816 | } | 817 | } |
817 | 818 | ||
819 | extern int acpi_force; | ||
820 | |||
821 | #ifdef __i386__ | ||
822 | |||
823 | #ifdef CONFIG_ACPI_PCI | ||
824 | static int __init disable_acpi_irq(struct dmi_system_id *d) | ||
825 | { | ||
826 | if (!acpi_force) { | ||
827 | printk(KERN_NOTICE "%s detected: force use of acpi=noirq\n", | ||
828 | d->ident); | ||
829 | acpi_noirq_set(); | ||
830 | } | ||
831 | return 0; | ||
832 | } | ||
833 | |||
834 | static int __init disable_acpi_pci(struct dmi_system_id *d) | ||
835 | { | ||
836 | if (!acpi_force) { | ||
837 | printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n", | ||
838 | d->ident); | ||
839 | acpi_disable_pci(); | ||
840 | } | ||
841 | return 0; | ||
842 | } | ||
843 | #endif | ||
844 | |||
845 | static int __init dmi_disable_acpi(struct dmi_system_id *d) | ||
846 | { | ||
847 | if (!acpi_force) { | ||
848 | printk(KERN_NOTICE "%s detected: acpi off\n",d->ident); | ||
849 | disable_acpi(); | ||
850 | } else { | ||
851 | printk(KERN_NOTICE | ||
852 | "Warning: DMI blacklist says broken, but acpi forced\n"); | ||
853 | } | ||
854 | return 0; | ||
855 | } | ||
856 | |||
857 | /* | ||
858 | * Limit ACPI to CPU enumeration for HT | ||
859 | */ | ||
860 | static int __init force_acpi_ht(struct dmi_system_id *d) | ||
861 | { | ||
862 | if (!acpi_force) { | ||
863 | printk(KERN_NOTICE "%s detected: force use of acpi=ht\n", d->ident); | ||
864 | disable_acpi(); | ||
865 | acpi_ht = 1; | ||
866 | } else { | ||
867 | printk(KERN_NOTICE | ||
868 | "Warning: acpi=force overrules DMI blacklist: acpi=ht\n"); | ||
869 | } | ||
870 | return 0; | ||
871 | } | ||
872 | |||
873 | /* | ||
874 | * If your system is blacklisted here, but you find that acpi=force | ||
875 | * works for you, please contact acpi-devel@sourceforge.net | ||
876 | */ | ||
877 | static struct dmi_system_id __initdata acpi_dmi_table[] = { | ||
878 | /* | ||
879 | * Boxes that need ACPI disabled | ||
880 | */ | ||
881 | { | ||
882 | .callback = dmi_disable_acpi, | ||
883 | .ident = "IBM Thinkpad", | ||
884 | .matches = { | ||
885 | DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), | ||
886 | DMI_MATCH(DMI_BOARD_NAME, "2629H1G"), | ||
887 | }, | ||
888 | }, | ||
889 | |||
890 | /* | ||
891 | * Boxes that need acpi=ht | ||
892 | */ | ||
893 | { | ||
894 | .callback = force_acpi_ht, | ||
895 | .ident = "FSC Primergy T850", | ||
896 | .matches = { | ||
897 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
898 | DMI_MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"), | ||
899 | }, | ||
900 | }, | ||
901 | { | ||
902 | .callback = force_acpi_ht, | ||
903 | .ident = "DELL GX240", | ||
904 | .matches = { | ||
905 | DMI_MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"), | ||
906 | DMI_MATCH(DMI_BOARD_NAME, "OptiPlex GX240"), | ||
907 | }, | ||
908 | }, | ||
909 | { | ||
910 | .callback = force_acpi_ht, | ||
911 | .ident = "HP VISUALIZE NT Workstation", | ||
912 | .matches = { | ||
913 | DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), | ||
914 | DMI_MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"), | ||
915 | }, | ||
916 | }, | ||
917 | { | ||
918 | .callback = force_acpi_ht, | ||
919 | .ident = "Compaq Workstation W8000", | ||
920 | .matches = { | ||
921 | DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), | ||
922 | DMI_MATCH(DMI_PRODUCT_NAME, "Workstation W8000"), | ||
923 | }, | ||
924 | }, | ||
925 | { | ||
926 | .callback = force_acpi_ht, | ||
927 | .ident = "ASUS P4B266", | ||
928 | .matches = { | ||
929 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), | ||
930 | DMI_MATCH(DMI_BOARD_NAME, "P4B266"), | ||
931 | }, | ||
932 | }, | ||
933 | { | ||
934 | .callback = force_acpi_ht, | ||
935 | .ident = "ASUS P2B-DS", | ||
936 | .matches = { | ||
937 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), | ||
938 | DMI_MATCH(DMI_BOARD_NAME, "P2B-DS"), | ||
939 | }, | ||
940 | }, | ||
941 | { | ||
942 | .callback = force_acpi_ht, | ||
943 | .ident = "ASUS CUR-DLS", | ||
944 | .matches = { | ||
945 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), | ||
946 | DMI_MATCH(DMI_BOARD_NAME, "CUR-DLS"), | ||
947 | }, | ||
948 | }, | ||
949 | { | ||
950 | .callback = force_acpi_ht, | ||
951 | .ident = "ABIT i440BX-W83977", | ||
952 | .matches = { | ||
953 | DMI_MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"), | ||
954 | DMI_MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"), | ||
955 | }, | ||
956 | }, | ||
957 | { | ||
958 | .callback = force_acpi_ht, | ||
959 | .ident = "IBM Bladecenter", | ||
960 | .matches = { | ||
961 | DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), | ||
962 | DMI_MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"), | ||
963 | }, | ||
964 | }, | ||
965 | { | ||
966 | .callback = force_acpi_ht, | ||
967 | .ident = "IBM eServer xSeries 360", | ||
968 | .matches = { | ||
969 | DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), | ||
970 | DMI_MATCH(DMI_BOARD_NAME, "eServer xSeries 360"), | ||
971 | }, | ||
972 | }, | ||
973 | { | ||
974 | .callback = force_acpi_ht, | ||
975 | .ident = "IBM eserver xSeries 330", | ||
976 | .matches = { | ||
977 | DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), | ||
978 | DMI_MATCH(DMI_BOARD_NAME, "eserver xSeries 330"), | ||
979 | }, | ||
980 | }, | ||
981 | { | ||
982 | .callback = force_acpi_ht, | ||
983 | .ident = "IBM eserver xSeries 440", | ||
984 | .matches = { | ||
985 | DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), | ||
986 | DMI_MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"), | ||
987 | }, | ||
988 | }, | ||
989 | |||
990 | #ifdef CONFIG_ACPI_PCI | ||
991 | /* | ||
992 | * Boxes that need ACPI PCI IRQ routing disabled | ||
993 | */ | ||
994 | { | ||
995 | .callback = disable_acpi_irq, | ||
996 | .ident = "ASUS A7V", | ||
997 | .matches = { | ||
998 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"), | ||
999 | DMI_MATCH(DMI_BOARD_NAME, "<A7V>"), | ||
1000 | /* newer BIOS, Revision 1011, does work */ | ||
1001 | DMI_MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1007"), | ||
1002 | }, | ||
1003 | }, | ||
1004 | |||
1005 | /* | ||
1006 | * Boxes that need ACPI PCI IRQ routing and PCI scan disabled | ||
1007 | */ | ||
1008 | { /* _BBN 0 bug */ | ||
1009 | .callback = disable_acpi_pci, | ||
1010 | .ident = "ASUS PR-DLS", | ||
1011 | .matches = { | ||
1012 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), | ||
1013 | DMI_MATCH(DMI_BOARD_NAME, "PR-DLS"), | ||
1014 | DMI_MATCH(DMI_BIOS_VERSION, "ASUS PR-DLS ACPI BIOS Revision 1010"), | ||
1015 | DMI_MATCH(DMI_BIOS_DATE, "03/21/2003") | ||
1016 | }, | ||
1017 | }, | ||
1018 | { | ||
1019 | .callback = disable_acpi_pci, | ||
1020 | .ident = "Acer TravelMate 36x Laptop", | ||
1021 | .matches = { | ||
1022 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
1023 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), | ||
1024 | }, | ||
1025 | }, | ||
1026 | #endif | ||
1027 | { } | ||
1028 | }; | ||
1029 | |||
1030 | #endif /* __i386__ */ | ||
1031 | |||
818 | /* | 1032 | /* |
819 | * acpi_boot_table_init() and acpi_boot_init() | 1033 | * acpi_boot_table_init() and acpi_boot_init() |
820 | * called from setup_arch(), always. | 1034 | * called from setup_arch(), always. |
@@ -843,6 +1057,10 @@ acpi_boot_table_init(void) | |||
843 | { | 1057 | { |
844 | int error; | 1058 | int error; |
845 | 1059 | ||
1060 | #ifdef __i386__ | ||
1061 | dmi_check_system(acpi_dmi_table); | ||
1062 | #endif | ||
1063 | |||
846 | /* | 1064 | /* |
847 | * If acpi_disabled, bail out | 1065 | * If acpi_disabled, bail out |
848 | * One exception: acpi=ht continues far enough to enumerate LAPICs | 1066 | * One exception: acpi=ht continues far enough to enumerate LAPICs |
@@ -870,8 +1088,6 @@ acpi_boot_table_init(void) | |||
870 | */ | 1088 | */ |
871 | error = acpi_blacklisted(); | 1089 | error = acpi_blacklisted(); |
872 | if (error) { | 1090 | if (error) { |
873 | extern int acpi_force; | ||
874 | |||
875 | if (acpi_force) { | 1091 | if (acpi_force) { |
876 | printk(KERN_WARNING PREFIX "acpi=force override\n"); | 1092 | printk(KERN_WARNING PREFIX "acpi=force override\n"); |
877 | } else { | 1093 | } else { |
diff --git a/arch/i386/kernel/acpi/sleep.c b/arch/i386/kernel/acpi/sleep.c index 28bb0514bb6e..c1af93032ff3 100644 --- a/arch/i386/kernel/acpi/sleep.c +++ b/arch/i386/kernel/acpi/sleep.c | |||
@@ -7,6 +7,7 @@ | |||
7 | 7 | ||
8 | #include <linux/acpi.h> | 8 | #include <linux/acpi.h> |
9 | #include <linux/bootmem.h> | 9 | #include <linux/bootmem.h> |
10 | #include <linux/dmi.h> | ||
10 | #include <asm/smp.h> | 11 | #include <asm/smp.h> |
11 | #include <asm/tlbflush.h> | 12 | #include <asm/tlbflush.h> |
12 | 13 | ||
@@ -91,3 +92,29 @@ static int __init acpi_sleep_setup(char *str) | |||
91 | 92 | ||
92 | 93 | ||
93 | __setup("acpi_sleep=", acpi_sleep_setup); | 94 | __setup("acpi_sleep=", acpi_sleep_setup); |
95 | |||
96 | |||
97 | static __init int reset_videomode_after_s3(struct dmi_system_id *d) | ||
98 | { | ||
99 | acpi_video_flags |= 2; | ||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | static __initdata struct dmi_system_id acpisleep_dmi_table[] = { | ||
104 | { /* Reset video mode after returning from ACPI S3 sleep */ | ||
105 | .callback = reset_videomode_after_s3, | ||
106 | .ident = "Toshiba Satellite 4030cdt", | ||
107 | .matches = { | ||
108 | DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"), | ||
109 | }, | ||
110 | }, | ||
111 | { } | ||
112 | }; | ||
113 | |||
114 | static int __init acpisleep_dmi_init(void) | ||
115 | { | ||
116 | dmi_check_system(acpisleep_dmi_table); | ||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | core_initcall(acpisleep_dmi_init); | ||
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index 8d993fa71754..93df90bbb87e 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/mc146818rtc.h> | 26 | #include <linux/mc146818rtc.h> |
27 | #include <linux/kernel_stat.h> | 27 | #include <linux/kernel_stat.h> |
28 | #include <linux/sysdev.h> | 28 | #include <linux/sysdev.h> |
29 | #include <linux/cpu.h> | ||
29 | 30 | ||
30 | #include <asm/atomic.h> | 31 | #include <asm/atomic.h> |
31 | #include <asm/smp.h> | 32 | #include <asm/smp.h> |
@@ -40,6 +41,11 @@ | |||
40 | #include "io_ports.h" | 41 | #include "io_ports.h" |
41 | 42 | ||
42 | /* | 43 | /* |
44 | * Knob to control our willingness to enable the local APIC. | ||
45 | */ | ||
46 | int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */ | ||
47 | |||
48 | /* | ||
43 | * Debug level | 49 | * Debug level |
44 | */ | 50 | */ |
45 | int apic_verbosity; | 51 | int apic_verbosity; |
@@ -205,7 +211,7 @@ void __init connect_bsp_APIC(void) | |||
205 | enable_apic_mode(); | 211 | enable_apic_mode(); |
206 | } | 212 | } |
207 | 213 | ||
208 | void disconnect_bsp_APIC(void) | 214 | void disconnect_bsp_APIC(int virt_wire_setup) |
209 | { | 215 | { |
210 | if (pic_mode) { | 216 | if (pic_mode) { |
211 | /* | 217 | /* |
@@ -219,6 +225,42 @@ void disconnect_bsp_APIC(void) | |||
219 | outb(0x70, 0x22); | 225 | outb(0x70, 0x22); |
220 | outb(0x00, 0x23); | 226 | outb(0x00, 0x23); |
221 | } | 227 | } |
228 | else { | ||
229 | /* Go back to Virtual Wire compatibility mode */ | ||
230 | unsigned long value; | ||
231 | |||
232 | /* For the spurious interrupt use vector F, and enable it */ | ||
233 | value = apic_read(APIC_SPIV); | ||
234 | value &= ~APIC_VECTOR_MASK; | ||
235 | value |= APIC_SPIV_APIC_ENABLED; | ||
236 | value |= 0xf; | ||
237 | apic_write_around(APIC_SPIV, value); | ||
238 | |||
239 | if (!virt_wire_setup) { | ||
240 | /* For LVT0 make it edge triggered, active high, external and enabled */ | ||
241 | value = apic_read(APIC_LVT0); | ||
242 | value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING | | ||
243 | APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | | ||
244 | APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED ); | ||
245 | value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; | ||
246 | value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT); | ||
247 | apic_write_around(APIC_LVT0, value); | ||
248 | } | ||
249 | else { | ||
250 | /* Disable LVT0 */ | ||
251 | apic_write_around(APIC_LVT0, APIC_LVT_MASKED); | ||
252 | } | ||
253 | |||
254 | /* For LVT1 make it edge triggered, active high, nmi and enabled */ | ||
255 | value = apic_read(APIC_LVT1); | ||
256 | value &= ~( | ||
257 | APIC_MODE_MASK | APIC_SEND_PENDING | | ||
258 | APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | | ||
259 | APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED); | ||
260 | value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; | ||
261 | value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI); | ||
262 | apic_write_around(APIC_LVT1, value); | ||
263 | } | ||
222 | } | 264 | } |
223 | 265 | ||
224 | void disable_local_APIC(void) | 266 | void disable_local_APIC(void) |
@@ -363,7 +405,7 @@ void __init init_bsp_APIC(void) | |||
363 | apic_write_around(APIC_LVT1, value); | 405 | apic_write_around(APIC_LVT1, value); |
364 | } | 406 | } |
365 | 407 | ||
366 | void __init setup_local_APIC (void) | 408 | void __devinit setup_local_APIC(void) |
367 | { | 409 | { |
368 | unsigned long oldvalue, value, ver, maxlvt; | 410 | unsigned long oldvalue, value, ver, maxlvt; |
369 | 411 | ||
@@ -634,7 +676,7 @@ static struct sys_device device_lapic = { | |||
634 | .cls = &lapic_sysclass, | 676 | .cls = &lapic_sysclass, |
635 | }; | 677 | }; |
636 | 678 | ||
637 | static void __init apic_pm_activate(void) | 679 | static void __devinit apic_pm_activate(void) |
638 | { | 680 | { |
639 | apic_pm_state.active = 1; | 681 | apic_pm_state.active = 1; |
640 | } | 682 | } |
@@ -665,26 +707,6 @@ static void apic_pm_activate(void) { } | |||
665 | * Original code written by Keir Fraser. | 707 | * Original code written by Keir Fraser. |
666 | */ | 708 | */ |
667 | 709 | ||
668 | /* | ||
669 | * Knob to control our willingness to enable the local APIC. | ||
670 | */ | ||
671 | int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */ | ||
672 | |||
673 | static int __init lapic_disable(char *str) | ||
674 | { | ||
675 | enable_local_apic = -1; | ||
676 | clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); | ||
677 | return 0; | ||
678 | } | ||
679 | __setup("nolapic", lapic_disable); | ||
680 | |||
681 | static int __init lapic_enable(char *str) | ||
682 | { | ||
683 | enable_local_apic = 1; | ||
684 | return 0; | ||
685 | } | ||
686 | __setup("lapic", lapic_enable); | ||
687 | |||
688 | static int __init apic_set_verbosity(char *str) | 710 | static int __init apic_set_verbosity(char *str) |
689 | { | 711 | { |
690 | if (strcmp("debug", str) == 0) | 712 | if (strcmp("debug", str) == 0) |
@@ -855,7 +877,7 @@ fake_ioapic_page: | |||
855 | * but we do not accept timer interrupts yet. We only allow the BP | 877 | * but we do not accept timer interrupts yet. We only allow the BP |
856 | * to calibrate. | 878 | * to calibrate. |
857 | */ | 879 | */ |
858 | static unsigned int __init get_8254_timer_count(void) | 880 | static unsigned int __devinit get_8254_timer_count(void) |
859 | { | 881 | { |
860 | extern spinlock_t i8253_lock; | 882 | extern spinlock_t i8253_lock; |
861 | unsigned long flags; | 883 | unsigned long flags; |
@@ -874,7 +896,7 @@ static unsigned int __init get_8254_timer_count(void) | |||
874 | } | 896 | } |
875 | 897 | ||
876 | /* next tick in 8254 can be caught by catching timer wraparound */ | 898 | /* next tick in 8254 can be caught by catching timer wraparound */ |
877 | static void __init wait_8254_wraparound(void) | 899 | static void __devinit wait_8254_wraparound(void) |
878 | { | 900 | { |
879 | unsigned int curr_count, prev_count; | 901 | unsigned int curr_count, prev_count; |
880 | 902 | ||
@@ -894,7 +916,7 @@ static void __init wait_8254_wraparound(void) | |||
894 | * Default initialization for 8254 timers. If we use other timers like HPET, | 916 | * Default initialization for 8254 timers. If we use other timers like HPET, |
895 | * we override this later | 917 | * we override this later |
896 | */ | 918 | */ |
897 | void (*wait_timer_tick)(void) __initdata = wait_8254_wraparound; | 919 | void (*wait_timer_tick)(void) __devinitdata = wait_8254_wraparound; |
898 | 920 | ||
899 | /* | 921 | /* |
900 | * This function sets up the local APIC timer, with a timeout of | 922 | * This function sets up the local APIC timer, with a timeout of |
@@ -930,7 +952,7 @@ static void __setup_APIC_LVTT(unsigned int clocks) | |||
930 | apic_write_around(APIC_TMICT, clocks/APIC_DIVISOR); | 952 | apic_write_around(APIC_TMICT, clocks/APIC_DIVISOR); |
931 | } | 953 | } |
932 | 954 | ||
933 | static void __init setup_APIC_timer(unsigned int clocks) | 955 | static void __devinit setup_APIC_timer(unsigned int clocks) |
934 | { | 956 | { |
935 | unsigned long flags; | 957 | unsigned long flags; |
936 | 958 | ||
@@ -1043,12 +1065,12 @@ void __init setup_boot_APIC_clock(void) | |||
1043 | local_irq_enable(); | 1065 | local_irq_enable(); |
1044 | } | 1066 | } |
1045 | 1067 | ||
1046 | void __init setup_secondary_APIC_clock(void) | 1068 | void __devinit setup_secondary_APIC_clock(void) |
1047 | { | 1069 | { |
1048 | setup_APIC_timer(calibration_result); | 1070 | setup_APIC_timer(calibration_result); |
1049 | } | 1071 | } |
1050 | 1072 | ||
1051 | void __init disable_APIC_timer(void) | 1073 | void __devinit disable_APIC_timer(void) |
1052 | { | 1074 | { |
1053 | if (using_apic_timer) { | 1075 | if (using_apic_timer) { |
1054 | unsigned long v; | 1076 | unsigned long v; |
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index 0ff65abcd56c..d48ce9290963 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c | |||
@@ -346,10 +346,10 @@ extern int (*console_blank_hook)(int); | |||
346 | struct apm_user { | 346 | struct apm_user { |
347 | int magic; | 347 | int magic; |
348 | struct apm_user * next; | 348 | struct apm_user * next; |
349 | int suser: 1; | 349 | unsigned int suser: 1; |
350 | int writer: 1; | 350 | unsigned int writer: 1; |
351 | int reader: 1; | 351 | unsigned int reader: 1; |
352 | int suspend_wait: 1; | 352 | unsigned int suspend_wait: 1; |
353 | int suspend_result; | 353 | int suspend_result; |
354 | int suspends_pending; | 354 | int suspends_pending; |
355 | int standbys_pending; | 355 | int standbys_pending; |
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index b9954248d0aa..2203a9d20212 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c | |||
@@ -24,9 +24,9 @@ EXPORT_PER_CPU_SYMBOL(cpu_gdt_table); | |||
24 | DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); | 24 | DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); |
25 | EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack); | 25 | EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack); |
26 | 26 | ||
27 | static int cachesize_override __initdata = -1; | 27 | static int cachesize_override __devinitdata = -1; |
28 | static int disable_x86_fxsr __initdata = 0; | 28 | static int disable_x86_fxsr __devinitdata = 0; |
29 | static int disable_x86_serial_nr __initdata = 1; | 29 | static int disable_x86_serial_nr __devinitdata = 1; |
30 | 30 | ||
31 | struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {}; | 31 | struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {}; |
32 | 32 | ||
@@ -59,7 +59,7 @@ static int __init cachesize_setup(char *str) | |||
59 | } | 59 | } |
60 | __setup("cachesize=", cachesize_setup); | 60 | __setup("cachesize=", cachesize_setup); |
61 | 61 | ||
62 | int __init get_model_name(struct cpuinfo_x86 *c) | 62 | int __devinit get_model_name(struct cpuinfo_x86 *c) |
63 | { | 63 | { |
64 | unsigned int *v; | 64 | unsigned int *v; |
65 | char *p, *q; | 65 | char *p, *q; |
@@ -89,7 +89,7 @@ int __init get_model_name(struct cpuinfo_x86 *c) | |||
89 | } | 89 | } |
90 | 90 | ||
91 | 91 | ||
92 | void __init display_cacheinfo(struct cpuinfo_x86 *c) | 92 | void __devinit display_cacheinfo(struct cpuinfo_x86 *c) |
93 | { | 93 | { |
94 | unsigned int n, dummy, ecx, edx, l2size; | 94 | unsigned int n, dummy, ecx, edx, l2size; |
95 | 95 | ||
@@ -130,7 +130,7 @@ void __init display_cacheinfo(struct cpuinfo_x86 *c) | |||
130 | /* in particular, if CPUID levels 0x80000002..4 are supported, this isn't used */ | 130 | /* in particular, if CPUID levels 0x80000002..4 are supported, this isn't used */ |
131 | 131 | ||
132 | /* Look up CPU names by table lookup. */ | 132 | /* Look up CPU names by table lookup. */ |
133 | static char __init *table_lookup_model(struct cpuinfo_x86 *c) | 133 | static char __devinit *table_lookup_model(struct cpuinfo_x86 *c) |
134 | { | 134 | { |
135 | struct cpu_model_info *info; | 135 | struct cpu_model_info *info; |
136 | 136 | ||
@@ -151,7 +151,7 @@ static char __init *table_lookup_model(struct cpuinfo_x86 *c) | |||
151 | } | 151 | } |
152 | 152 | ||
153 | 153 | ||
154 | void __init get_cpu_vendor(struct cpuinfo_x86 *c, int early) | 154 | void __devinit get_cpu_vendor(struct cpuinfo_x86 *c, int early) |
155 | { | 155 | { |
156 | char *v = c->x86_vendor_id; | 156 | char *v = c->x86_vendor_id; |
157 | int i; | 157 | int i; |
@@ -202,7 +202,7 @@ static inline int flag_is_changeable_p(u32 flag) | |||
202 | 202 | ||
203 | 203 | ||
204 | /* Probe for the CPUID instruction */ | 204 | /* Probe for the CPUID instruction */ |
205 | static int __init have_cpuid_p(void) | 205 | static int __devinit have_cpuid_p(void) |
206 | { | 206 | { |
207 | return flag_is_changeable_p(X86_EFLAGS_ID); | 207 | return flag_is_changeable_p(X86_EFLAGS_ID); |
208 | } | 208 | } |
@@ -249,7 +249,7 @@ static void __init early_cpu_detect(void) | |||
249 | #endif | 249 | #endif |
250 | } | 250 | } |
251 | 251 | ||
252 | void __init generic_identify(struct cpuinfo_x86 * c) | 252 | void __devinit generic_identify(struct cpuinfo_x86 * c) |
253 | { | 253 | { |
254 | u32 tfms, xlvl; | 254 | u32 tfms, xlvl; |
255 | int junk; | 255 | int junk; |
@@ -296,7 +296,7 @@ void __init generic_identify(struct cpuinfo_x86 * c) | |||
296 | } | 296 | } |
297 | } | 297 | } |
298 | 298 | ||
299 | static void __init squash_the_stupid_serial_number(struct cpuinfo_x86 *c) | 299 | static void __devinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c) |
300 | { | 300 | { |
301 | if (cpu_has(c, X86_FEATURE_PN) && disable_x86_serial_nr ) { | 301 | if (cpu_has(c, X86_FEATURE_PN) && disable_x86_serial_nr ) { |
302 | /* Disable processor serial number */ | 302 | /* Disable processor serial number */ |
@@ -324,7 +324,7 @@ __setup("serialnumber", x86_serial_nr_setup); | |||
324 | /* | 324 | /* |
325 | * This does the hard work of actually picking apart the CPU stuff... | 325 | * This does the hard work of actually picking apart the CPU stuff... |
326 | */ | 326 | */ |
327 | void __init identify_cpu(struct cpuinfo_x86 *c) | 327 | void __devinit identify_cpu(struct cpuinfo_x86 *c) |
328 | { | 328 | { |
329 | int i; | 329 | int i; |
330 | 330 | ||
@@ -432,10 +432,13 @@ void __init identify_cpu(struct cpuinfo_x86 *c) | |||
432 | #ifdef CONFIG_X86_MCE | 432 | #ifdef CONFIG_X86_MCE |
433 | mcheck_init(c); | 433 | mcheck_init(c); |
434 | #endif | 434 | #endif |
435 | if (c == &boot_cpu_data) | ||
436 | sysenter_setup(); | ||
437 | enable_sep_cpu(); | ||
435 | } | 438 | } |
436 | 439 | ||
437 | #ifdef CONFIG_X86_HT | 440 | #ifdef CONFIG_X86_HT |
438 | void __init detect_ht(struct cpuinfo_x86 *c) | 441 | void __devinit detect_ht(struct cpuinfo_x86 *c) |
439 | { | 442 | { |
440 | u32 eax, ebx, ecx, edx; | 443 | u32 eax, ebx, ecx, edx; |
441 | int index_msb, tmp; | 444 | int index_msb, tmp; |
@@ -490,7 +493,7 @@ void __init detect_ht(struct cpuinfo_x86 *c) | |||
490 | } | 493 | } |
491 | #endif | 494 | #endif |
492 | 495 | ||
493 | void __init print_cpu_info(struct cpuinfo_x86 *c) | 496 | void __devinit print_cpu_info(struct cpuinfo_x86 *c) |
494 | { | 497 | { |
495 | char *vendor = NULL; | 498 | char *vendor = NULL; |
496 | 499 | ||
@@ -513,7 +516,7 @@ void __init print_cpu_info(struct cpuinfo_x86 *c) | |||
513 | printk("\n"); | 516 | printk("\n"); |
514 | } | 517 | } |
515 | 518 | ||
516 | cpumask_t cpu_initialized __initdata = CPU_MASK_NONE; | 519 | cpumask_t cpu_initialized __devinitdata = CPU_MASK_NONE; |
517 | 520 | ||
518 | /* This is hacky. :) | 521 | /* This is hacky. :) |
519 | * We're emulating future behavior. | 522 | * We're emulating future behavior. |
@@ -560,7 +563,7 @@ void __init early_cpu_init(void) | |||
560 | * and IDT. We reload them nevertheless, this function acts as a | 563 | * and IDT. We reload them nevertheless, this function acts as a |
561 | * 'CPU state barrier', nothing should get across. | 564 | * 'CPU state barrier', nothing should get across. |
562 | */ | 565 | */ |
563 | void __init cpu_init (void) | 566 | void __devinit cpu_init(void) |
564 | { | 567 | { |
565 | int cpu = smp_processor_id(); | 568 | int cpu = smp_processor_id(); |
566 | struct tss_struct * t = &per_cpu(init_tss, cpu); | 569 | struct tss_struct * t = &per_cpu(init_tss, cpu); |
@@ -648,3 +651,15 @@ void __init cpu_init (void) | |||
648 | clear_used_math(); | 651 | clear_used_math(); |
649 | mxcsr_feature_mask_init(); | 652 | mxcsr_feature_mask_init(); |
650 | } | 653 | } |
654 | |||
655 | #ifdef CONFIG_HOTPLUG_CPU | ||
656 | void __devinit cpu_uninit(void) | ||
657 | { | ||
658 | int cpu = raw_smp_processor_id(); | ||
659 | cpu_clear(cpu, cpu_initialized); | ||
660 | |||
661 | /* lazy TLB state */ | ||
662 | per_cpu(cpu_tlbstate, cpu).state = 0; | ||
663 | per_cpu(cpu_tlbstate, cpu).active_mm = &init_mm; | ||
664 | } | ||
665 | #endif | ||
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c index 5c530064eb74..73a5dc5b26b8 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c | |||
@@ -648,9 +648,7 @@ static int powernow_cpu_exit (struct cpufreq_policy *policy) { | |||
648 | } | 648 | } |
649 | #endif | 649 | #endif |
650 | 650 | ||
651 | if (powernow_table) | 651 | kfree(powernow_table); |
652 | kfree(powernow_table); | ||
653 | |||
654 | return 0; | 652 | return 0; |
655 | } | 653 | } |
656 | 654 | ||
diff --git a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c index 121aa2176e69..96a75d045835 100644 --- a/arch/i386/kernel/cpu/intel.c +++ b/arch/i386/kernel/cpu/intel.c | |||
@@ -28,7 +28,7 @@ extern int trap_init_f00f_bug(void); | |||
28 | struct movsl_mask movsl_mask; | 28 | struct movsl_mask movsl_mask; |
29 | #endif | 29 | #endif |
30 | 30 | ||
31 | void __init early_intel_workaround(struct cpuinfo_x86 *c) | 31 | void __devinit early_intel_workaround(struct cpuinfo_x86 *c) |
32 | { | 32 | { |
33 | if (c->x86_vendor != X86_VENDOR_INTEL) | 33 | if (c->x86_vendor != X86_VENDOR_INTEL) |
34 | return; | 34 | return; |
@@ -43,7 +43,7 @@ void __init early_intel_workaround(struct cpuinfo_x86 *c) | |||
43 | * This is called before we do cpu ident work | 43 | * This is called before we do cpu ident work |
44 | */ | 44 | */ |
45 | 45 | ||
46 | int __init ppro_with_ram_bug(void) | 46 | int __devinit ppro_with_ram_bug(void) |
47 | { | 47 | { |
48 | /* Uses data from early_cpu_detect now */ | 48 | /* Uses data from early_cpu_detect now */ |
49 | if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && | 49 | if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && |
@@ -61,7 +61,7 @@ int __init ppro_with_ram_bug(void) | |||
61 | * P4 Xeon errata 037 workaround. | 61 | * P4 Xeon errata 037 workaround. |
62 | * Hardware prefetcher may cause stale data to be loaded into the cache. | 62 | * Hardware prefetcher may cause stale data to be loaded into the cache. |
63 | */ | 63 | */ |
64 | static void __init Intel_errata_workarounds(struct cpuinfo_x86 *c) | 64 | static void __devinit Intel_errata_workarounds(struct cpuinfo_x86 *c) |
65 | { | 65 | { |
66 | unsigned long lo, hi; | 66 | unsigned long lo, hi; |
67 | 67 | ||
@@ -80,7 +80,7 @@ static void __init Intel_errata_workarounds(struct cpuinfo_x86 *c) | |||
80 | /* | 80 | /* |
81 | * find out the number of processor cores on the die | 81 | * find out the number of processor cores on the die |
82 | */ | 82 | */ |
83 | static int __init num_cpu_cores(struct cpuinfo_x86 *c) | 83 | static int __devinit num_cpu_cores(struct cpuinfo_x86 *c) |
84 | { | 84 | { |
85 | unsigned int eax; | 85 | unsigned int eax; |
86 | 86 | ||
@@ -98,7 +98,7 @@ static int __init num_cpu_cores(struct cpuinfo_x86 *c) | |||
98 | return 1; | 98 | return 1; |
99 | } | 99 | } |
100 | 100 | ||
101 | static void __init init_intel(struct cpuinfo_x86 *c) | 101 | static void __devinit init_intel(struct cpuinfo_x86 *c) |
102 | { | 102 | { |
103 | unsigned int l2 = 0; | 103 | unsigned int l2 = 0; |
104 | char *p = NULL; | 104 | char *p = NULL; |
@@ -204,7 +204,7 @@ static unsigned int intel_size_cache(struct cpuinfo_x86 * c, unsigned int size) | |||
204 | return size; | 204 | return size; |
205 | } | 205 | } |
206 | 206 | ||
207 | static struct cpu_dev intel_cpu_dev __initdata = { | 207 | static struct cpu_dev intel_cpu_dev __devinitdata = { |
208 | .c_vendor = "Intel", | 208 | .c_vendor = "Intel", |
209 | .c_ident = { "GenuineIntel" }, | 209 | .c_ident = { "GenuineIntel" }, |
210 | .c_models = { | 210 | .c_models = { |
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c index a710dc4eb20e..1d768b263269 100644 --- a/arch/i386/kernel/cpu/intel_cacheinfo.c +++ b/arch/i386/kernel/cpu/intel_cacheinfo.c | |||
@@ -28,7 +28,7 @@ struct _cache_table | |||
28 | }; | 28 | }; |
29 | 29 | ||
30 | /* all the cache descriptor types we care about (no TLB or trace cache entries) */ | 30 | /* all the cache descriptor types we care about (no TLB or trace cache entries) */ |
31 | static struct _cache_table cache_table[] __initdata = | 31 | static struct _cache_table cache_table[] __devinitdata = |
32 | { | 32 | { |
33 | { 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */ | 33 | { 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */ |
34 | { 0x08, LVL_1_INST, 16 }, /* 4-way set assoc, 32 byte line size */ | 34 | { 0x08, LVL_1_INST, 16 }, /* 4-way set assoc, 32 byte line size */ |
@@ -160,7 +160,7 @@ static int __init find_num_cache_leaves(void) | |||
160 | return retval; | 160 | return retval; |
161 | } | 161 | } |
162 | 162 | ||
163 | unsigned int __init init_intel_cacheinfo(struct cpuinfo_x86 *c) | 163 | unsigned int __devinit init_intel_cacheinfo(struct cpuinfo_x86 *c) |
164 | { | 164 | { |
165 | unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */ | 165 | unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */ |
166 | unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */ | 166 | unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */ |
diff --git a/arch/i386/kernel/cpu/mcheck/k7.c b/arch/i386/kernel/cpu/mcheck/k7.c index 8df52e86c4d2..c4abe7657397 100644 --- a/arch/i386/kernel/cpu/mcheck/k7.c +++ b/arch/i386/kernel/cpu/mcheck/k7.c | |||
@@ -69,7 +69,7 @@ static fastcall void k7_machine_check(struct pt_regs * regs, long error_code) | |||
69 | 69 | ||
70 | 70 | ||
71 | /* AMD K7 machine check is Intel like */ | 71 | /* AMD K7 machine check is Intel like */ |
72 | void __init amd_mcheck_init(struct cpuinfo_x86 *c) | 72 | void __devinit amd_mcheck_init(struct cpuinfo_x86 *c) |
73 | { | 73 | { |
74 | u32 l, h; | 74 | u32 l, h; |
75 | int i; | 75 | int i; |
diff --git a/arch/i386/kernel/cpu/mcheck/mce.c b/arch/i386/kernel/cpu/mcheck/mce.c index bf6d1aefafc0..2cf25d2ba0f1 100644 --- a/arch/i386/kernel/cpu/mcheck/mce.c +++ b/arch/i386/kernel/cpu/mcheck/mce.c | |||
@@ -16,7 +16,7 @@ | |||
16 | 16 | ||
17 | #include "mce.h" | 17 | #include "mce.h" |
18 | 18 | ||
19 | int mce_disabled __initdata = 0; | 19 | int mce_disabled __devinitdata = 0; |
20 | int nr_mce_banks; | 20 | int nr_mce_banks; |
21 | 21 | ||
22 | EXPORT_SYMBOL_GPL(nr_mce_banks); /* non-fatal.o */ | 22 | EXPORT_SYMBOL_GPL(nr_mce_banks); /* non-fatal.o */ |
@@ -31,7 +31,7 @@ static fastcall void unexpected_machine_check(struct pt_regs * regs, long error_ | |||
31 | void fastcall (*machine_check_vector)(struct pt_regs *, long error_code) = unexpected_machine_check; | 31 | void fastcall (*machine_check_vector)(struct pt_regs *, long error_code) = unexpected_machine_check; |
32 | 32 | ||
33 | /* This has to be run for each processor */ | 33 | /* This has to be run for each processor */ |
34 | void __init mcheck_init(struct cpuinfo_x86 *c) | 34 | void __devinit mcheck_init(struct cpuinfo_x86 *c) |
35 | { | 35 | { |
36 | if (mce_disabled==1) | 36 | if (mce_disabled==1) |
37 | return; | 37 | return; |
diff --git a/arch/i386/kernel/cpu/mcheck/p4.c b/arch/i386/kernel/cpu/mcheck/p4.c index 8b16ceb929b4..0abccb6fdf9e 100644 --- a/arch/i386/kernel/cpu/mcheck/p4.c +++ b/arch/i386/kernel/cpu/mcheck/p4.c | |||
@@ -78,7 +78,7 @@ fastcall void smp_thermal_interrupt(struct pt_regs *regs) | |||
78 | } | 78 | } |
79 | 79 | ||
80 | /* P4/Xeon Thermal regulation detect and init */ | 80 | /* P4/Xeon Thermal regulation detect and init */ |
81 | static void __init intel_init_thermal(struct cpuinfo_x86 *c) | 81 | static void __devinit intel_init_thermal(struct cpuinfo_x86 *c) |
82 | { | 82 | { |
83 | u32 l, h; | 83 | u32 l, h; |
84 | unsigned int cpu = smp_processor_id(); | 84 | unsigned int cpu = smp_processor_id(); |
@@ -232,7 +232,7 @@ static fastcall void intel_machine_check(struct pt_regs * regs, long error_code) | |||
232 | } | 232 | } |
233 | 233 | ||
234 | 234 | ||
235 | void __init intel_p4_mcheck_init(struct cpuinfo_x86 *c) | 235 | void __devinit intel_p4_mcheck_init(struct cpuinfo_x86 *c) |
236 | { | 236 | { |
237 | u32 l, h; | 237 | u32 l, h; |
238 | int i; | 238 | int i; |
diff --git a/arch/i386/kernel/cpu/mcheck/p5.c b/arch/i386/kernel/cpu/mcheck/p5.c index c45a1b485c80..ec0614cd2925 100644 --- a/arch/i386/kernel/cpu/mcheck/p5.c +++ b/arch/i386/kernel/cpu/mcheck/p5.c | |||
@@ -29,7 +29,7 @@ static fastcall void pentium_machine_check(struct pt_regs * regs, long error_cod | |||
29 | } | 29 | } |
30 | 30 | ||
31 | /* Set up machine check reporting for processors with Intel style MCE */ | 31 | /* Set up machine check reporting for processors with Intel style MCE */ |
32 | void __init intel_p5_mcheck_init(struct cpuinfo_x86 *c) | 32 | void __devinit intel_p5_mcheck_init(struct cpuinfo_x86 *c) |
33 | { | 33 | { |
34 | u32 l, h; | 34 | u32 l, h; |
35 | 35 | ||
diff --git a/arch/i386/kernel/cpu/mcheck/p6.c b/arch/i386/kernel/cpu/mcheck/p6.c index 46640f8c2494..f01b73f947e1 100644 --- a/arch/i386/kernel/cpu/mcheck/p6.c +++ b/arch/i386/kernel/cpu/mcheck/p6.c | |||
@@ -80,7 +80,7 @@ static fastcall void intel_machine_check(struct pt_regs * regs, long error_code) | |||
80 | } | 80 | } |
81 | 81 | ||
82 | /* Set up machine check reporting for processors with Intel style MCE */ | 82 | /* Set up machine check reporting for processors with Intel style MCE */ |
83 | void __init intel_p6_mcheck_init(struct cpuinfo_x86 *c) | 83 | void __devinit intel_p6_mcheck_init(struct cpuinfo_x86 *c) |
84 | { | 84 | { |
85 | u32 l, h; | 85 | u32 l, h; |
86 | int i; | 86 | int i; |
diff --git a/arch/i386/kernel/cpu/mcheck/winchip.c b/arch/i386/kernel/cpu/mcheck/winchip.c index 753fa7acb984..7bae68fa168f 100644 --- a/arch/i386/kernel/cpu/mcheck/winchip.c +++ b/arch/i386/kernel/cpu/mcheck/winchip.c | |||
@@ -23,7 +23,7 @@ static fastcall void winchip_machine_check(struct pt_regs * regs, long error_cod | |||
23 | } | 23 | } |
24 | 24 | ||
25 | /* Set up machine check reporting on the Winchip C6 series */ | 25 | /* Set up machine check reporting on the Winchip C6 series */ |
26 | void __init winchip_mcheck_init(struct cpuinfo_x86 *c) | 26 | void __devinit winchip_mcheck_init(struct cpuinfo_x86 *c) |
27 | { | 27 | { |
28 | u32 lo, hi; | 28 | u32 lo, hi; |
29 | machine_check_vector = winchip_machine_check; | 29 | machine_check_vector = winchip_machine_check; |
diff --git a/arch/i386/kernel/cpu/mtrr/generic.c b/arch/i386/kernel/cpu/mtrr/generic.c index f468a979e9aa..64d91f73a0a4 100644 --- a/arch/i386/kernel/cpu/mtrr/generic.c +++ b/arch/i386/kernel/cpu/mtrr/generic.c | |||
@@ -70,8 +70,7 @@ void __init get_mtrr_state(void) | |||
70 | /* Free resources associated with a struct mtrr_state */ | 70 | /* Free resources associated with a struct mtrr_state */ |
71 | void __init finalize_mtrr_state(void) | 71 | void __init finalize_mtrr_state(void) |
72 | { | 72 | { |
73 | if (mtrr_state.var_ranges) | 73 | kfree(mtrr_state.var_ranges); |
74 | kfree(mtrr_state.var_ranges); | ||
75 | mtrr_state.var_ranges = NULL; | 74 | mtrr_state.var_ranges = NULL; |
76 | } | 75 | } |
77 | 76 | ||
diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c new file mode 100644 index 000000000000..e5fab12f7926 --- /dev/null +++ b/arch/i386/kernel/crash.c | |||
@@ -0,0 +1,223 @@ | |||
1 | /* | ||
2 | * Architecture specific (i386) functions for kexec based crash dumps. | ||
3 | * | ||
4 | * Created by: Hariprasad Nellitheertha (hari@in.ibm.com) | ||
5 | * | ||
6 | * Copyright (C) IBM Corporation, 2004. All rights reserved. | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #include <linux/init.h> | ||
11 | #include <linux/types.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/smp.h> | ||
14 | #include <linux/irq.h> | ||
15 | #include <linux/reboot.h> | ||
16 | #include <linux/kexec.h> | ||
17 | #include <linux/irq.h> | ||
18 | #include <linux/delay.h> | ||
19 | #include <linux/elf.h> | ||
20 | #include <linux/elfcore.h> | ||
21 | |||
22 | #include <asm/processor.h> | ||
23 | #include <asm/hardirq.h> | ||
24 | #include <asm/nmi.h> | ||
25 | #include <asm/hw_irq.h> | ||
26 | #include <asm/apic.h> | ||
27 | #include <mach_ipi.h> | ||
28 | |||
29 | |||
30 | note_buf_t crash_notes[NR_CPUS]; | ||
31 | /* This keeps a track of which one is crashing cpu. */ | ||
32 | static int crashing_cpu; | ||
33 | |||
34 | static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data, | ||
35 | size_t data_len) | ||
36 | { | ||
37 | struct elf_note note; | ||
38 | |||
39 | note.n_namesz = strlen(name) + 1; | ||
40 | note.n_descsz = data_len; | ||
41 | note.n_type = type; | ||
42 | memcpy(buf, ¬e, sizeof(note)); | ||
43 | buf += (sizeof(note) +3)/4; | ||
44 | memcpy(buf, name, note.n_namesz); | ||
45 | buf += (note.n_namesz + 3)/4; | ||
46 | memcpy(buf, data, note.n_descsz); | ||
47 | buf += (note.n_descsz + 3)/4; | ||
48 | |||
49 | return buf; | ||
50 | } | ||
51 | |||
52 | static void final_note(u32 *buf) | ||
53 | { | ||
54 | struct elf_note note; | ||
55 | |||
56 | note.n_namesz = 0; | ||
57 | note.n_descsz = 0; | ||
58 | note.n_type = 0; | ||
59 | memcpy(buf, ¬e, sizeof(note)); | ||
60 | } | ||
61 | |||
62 | static void crash_save_this_cpu(struct pt_regs *regs, int cpu) | ||
63 | { | ||
64 | struct elf_prstatus prstatus; | ||
65 | u32 *buf; | ||
66 | |||
67 | if ((cpu < 0) || (cpu >= NR_CPUS)) | ||
68 | return; | ||
69 | |||
70 | /* Using ELF notes here is opportunistic. | ||
71 | * I need a well defined structure format | ||
72 | * for the data I pass, and I need tags | ||
73 | * on the data to indicate what information I have | ||
74 | * squirrelled away. ELF notes happen to provide | ||
75 | * all of that that no need to invent something new. | ||
76 | */ | ||
77 | buf = &crash_notes[cpu][0]; | ||
78 | memset(&prstatus, 0, sizeof(prstatus)); | ||
79 | prstatus.pr_pid = current->pid; | ||
80 | elf_core_copy_regs(&prstatus.pr_reg, regs); | ||
81 | buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus, | ||
82 | sizeof(prstatus)); | ||
83 | final_note(buf); | ||
84 | } | ||
85 | |||
86 | static void crash_get_current_regs(struct pt_regs *regs) | ||
87 | { | ||
88 | __asm__ __volatile__("movl %%ebx,%0" : "=m"(regs->ebx)); | ||
89 | __asm__ __volatile__("movl %%ecx,%0" : "=m"(regs->ecx)); | ||
90 | __asm__ __volatile__("movl %%edx,%0" : "=m"(regs->edx)); | ||
91 | __asm__ __volatile__("movl %%esi,%0" : "=m"(regs->esi)); | ||
92 | __asm__ __volatile__("movl %%edi,%0" : "=m"(regs->edi)); | ||
93 | __asm__ __volatile__("movl %%ebp,%0" : "=m"(regs->ebp)); | ||
94 | __asm__ __volatile__("movl %%eax,%0" : "=m"(regs->eax)); | ||
95 | __asm__ __volatile__("movl %%esp,%0" : "=m"(regs->esp)); | ||
96 | __asm__ __volatile__("movw %%ss, %%ax;" :"=a"(regs->xss)); | ||
97 | __asm__ __volatile__("movw %%cs, %%ax;" :"=a"(regs->xcs)); | ||
98 | __asm__ __volatile__("movw %%ds, %%ax;" :"=a"(regs->xds)); | ||
99 | __asm__ __volatile__("movw %%es, %%ax;" :"=a"(regs->xes)); | ||
100 | __asm__ __volatile__("pushfl; popl %0" :"=m"(regs->eflags)); | ||
101 | |||
102 | regs->eip = (unsigned long)current_text_addr(); | ||
103 | } | ||
104 | |||
105 | /* CPU does not save ss and esp on stack if execution is already | ||
106 | * running in kernel mode at the time of NMI occurrence. This code | ||
107 | * fixes it. | ||
108 | */ | ||
109 | static void crash_setup_regs(struct pt_regs *newregs, struct pt_regs *oldregs) | ||
110 | { | ||
111 | memcpy(newregs, oldregs, sizeof(*newregs)); | ||
112 | newregs->esp = (unsigned long)&(oldregs->esp); | ||
113 | __asm__ __volatile__("xorl %eax, %eax;"); | ||
114 | __asm__ __volatile__ ("movw %%ss, %%ax;" :"=a"(newregs->xss)); | ||
115 | } | ||
116 | |||
117 | /* We may have saved_regs from where the error came from | ||
118 | * or it is NULL if via a direct panic(). | ||
119 | */ | ||
120 | static void crash_save_self(struct pt_regs *saved_regs) | ||
121 | { | ||
122 | struct pt_regs regs; | ||
123 | int cpu; | ||
124 | |||
125 | cpu = smp_processor_id(); | ||
126 | if (saved_regs) | ||
127 | crash_setup_regs(®s, saved_regs); | ||
128 | else | ||
129 | crash_get_current_regs(®s); | ||
130 | crash_save_this_cpu(®s, cpu); | ||
131 | } | ||
132 | |||
133 | #ifdef CONFIG_SMP | ||
134 | static atomic_t waiting_for_crash_ipi; | ||
135 | |||
136 | static int crash_nmi_callback(struct pt_regs *regs, int cpu) | ||
137 | { | ||
138 | struct pt_regs fixed_regs; | ||
139 | |||
140 | /* Don't do anything if this handler is invoked on crashing cpu. | ||
141 | * Otherwise, system will completely hang. Crashing cpu can get | ||
142 | * an NMI if system was initially booted with nmi_watchdog parameter. | ||
143 | */ | ||
144 | if (cpu == crashing_cpu) | ||
145 | return 1; | ||
146 | local_irq_disable(); | ||
147 | |||
148 | if (!user_mode(regs)) { | ||
149 | crash_setup_regs(&fixed_regs, regs); | ||
150 | regs = &fixed_regs; | ||
151 | } | ||
152 | crash_save_this_cpu(regs, cpu); | ||
153 | disable_local_APIC(); | ||
154 | atomic_dec(&waiting_for_crash_ipi); | ||
155 | /* Assume hlt works */ | ||
156 | __asm__("hlt"); | ||
157 | for(;;); | ||
158 | |||
159 | return 1; | ||
160 | } | ||
161 | |||
162 | /* | ||
163 | * By using the NMI code instead of a vector we just sneak thru the | ||
164 | * word generator coming out with just what we want. AND it does | ||
165 | * not matter if clustered_apic_mode is set or not. | ||
166 | */ | ||
167 | static void smp_send_nmi_allbutself(void) | ||
168 | { | ||
169 | send_IPI_allbutself(APIC_DM_NMI); | ||
170 | } | ||
171 | |||
172 | static void nmi_shootdown_cpus(void) | ||
173 | { | ||
174 | unsigned long msecs; | ||
175 | |||
176 | atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); | ||
177 | /* Would it be better to replace the trap vector here? */ | ||
178 | set_nmi_callback(crash_nmi_callback); | ||
179 | /* Ensure the new callback function is set before sending | ||
180 | * out the NMI | ||
181 | */ | ||
182 | wmb(); | ||
183 | |||
184 | smp_send_nmi_allbutself(); | ||
185 | |||
186 | msecs = 1000; /* Wait at most a second for the other cpus to stop */ | ||
187 | while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) { | ||
188 | mdelay(1); | ||
189 | msecs--; | ||
190 | } | ||
191 | |||
192 | /* Leave the nmi callback set */ | ||
193 | disable_local_APIC(); | ||
194 | } | ||
195 | #else | ||
196 | static void nmi_shootdown_cpus(void) | ||
197 | { | ||
198 | /* There are no cpus to shootdown */ | ||
199 | } | ||
200 | #endif | ||
201 | |||
202 | void machine_crash_shutdown(struct pt_regs *regs) | ||
203 | { | ||
204 | /* This function is only called after the system | ||
205 | * has paniced or is otherwise in a critical state. | ||
206 | * The minimum amount of code to allow a kexec'd kernel | ||
207 | * to run successfully needs to happen here. | ||
208 | * | ||
209 | * In practice this means shooting down the other cpus in | ||
210 | * an SMP system. | ||
211 | */ | ||
212 | /* The kernel is broken so disable interrupts */ | ||
213 | local_irq_disable(); | ||
214 | |||
215 | /* Make a note of crashing cpu. Will be used in NMI callback.*/ | ||
216 | crashing_cpu = smp_processor_id(); | ||
217 | nmi_shootdown_cpus(); | ||
218 | lapic_shutdown(); | ||
219 | #if defined(CONFIG_X86_IO_APIC) | ||
220 | disable_IO_APIC(); | ||
221 | #endif | ||
222 | crash_save_self(regs); | ||
223 | } | ||
diff --git a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c index 6ed7e28f306c..a3cdf894302b 100644 --- a/arch/i386/kernel/dmi_scan.c +++ b/arch/i386/kernel/dmi_scan.c | |||
@@ -1,22 +1,15 @@ | |||
1 | #include <linux/types.h> | 1 | #include <linux/types.h> |
2 | #include <linux/kernel.h> | ||
3 | #include <linux/string.h> | 2 | #include <linux/string.h> |
4 | #include <linux/init.h> | 3 | #include <linux/init.h> |
5 | #include <linux/module.h> | 4 | #include <linux/module.h> |
6 | #include <linux/slab.h> | ||
7 | #include <linux/acpi.h> | ||
8 | #include <asm/io.h> | ||
9 | #include <linux/pm.h> | ||
10 | #include <asm/system.h> | ||
11 | #include <linux/dmi.h> | 5 | #include <linux/dmi.h> |
12 | #include <linux/bootmem.h> | 6 | #include <linux/bootmem.h> |
13 | 7 | ||
14 | 8 | ||
15 | struct dmi_header | 9 | struct dmi_header { |
16 | { | 10 | u8 type; |
17 | u8 type; | 11 | u8 length; |
18 | u8 length; | 12 | u16 handle; |
19 | u16 handle; | ||
20 | }; | 13 | }; |
21 | 14 | ||
22 | #undef DMI_DEBUG | 15 | #undef DMI_DEBUG |
@@ -29,15 +22,13 @@ struct dmi_header | |||
29 | 22 | ||
30 | static char * __init dmi_string(struct dmi_header *dm, u8 s) | 23 | static char * __init dmi_string(struct dmi_header *dm, u8 s) |
31 | { | 24 | { |
32 | u8 *bp=(u8 *)dm; | 25 | u8 *bp = ((u8 *) dm) + dm->length; |
33 | bp+=dm->length; | 26 | |
34 | if(!s) | 27 | if (!s) |
35 | return ""; | 28 | return ""; |
36 | s--; | 29 | s--; |
37 | while(s>0 && *bp) | 30 | while (s > 0 && *bp) { |
38 | { | 31 | bp += strlen(bp) + 1; |
39 | bp+=strlen(bp); | ||
40 | bp++; | ||
41 | s--; | 32 | s--; |
42 | } | 33 | } |
43 | return bp; | 34 | return bp; |
@@ -47,16 +38,14 @@ static char * __init dmi_string(struct dmi_header *dm, u8 s) | |||
47 | * We have to be cautious here. We have seen BIOSes with DMI pointers | 38 | * We have to be cautious here. We have seen BIOSes with DMI pointers |
48 | * pointing to completely the wrong place for example | 39 | * pointing to completely the wrong place for example |
49 | */ | 40 | */ |
50 | 41 | static int __init dmi_table(u32 base, int len, int num, | |
51 | static int __init dmi_table(u32 base, int len, int num, void (*decode)(struct dmi_header *)) | 42 | void (*decode)(struct dmi_header *)) |
52 | { | 43 | { |
53 | u8 *buf; | 44 | u8 *buf, *data; |
54 | struct dmi_header *dm; | 45 | int i = 0; |
55 | u8 *data; | ||
56 | int i=0; | ||
57 | 46 | ||
58 | buf = bt_ioremap(base, len); | 47 | buf = bt_ioremap(base, len); |
59 | if(buf==NULL) | 48 | if (buf == NULL) |
60 | return -1; | 49 | return -1; |
61 | 50 | ||
62 | data = buf; | 51 | data = buf; |
@@ -65,36 +54,34 @@ static int __init dmi_table(u32 base, int len, int num, void (*decode)(struct dm | |||
65 | * Stop when we see all the items the table claimed to have | 54 | * Stop when we see all the items the table claimed to have |
66 | * OR we run off the end of the table (also happens) | 55 | * OR we run off the end of the table (also happens) |
67 | */ | 56 | */ |
68 | 57 | while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) { | |
69 | while(i<num && data-buf+sizeof(struct dmi_header)<=len) | 58 | struct dmi_header *dm = (struct dmi_header *)data; |
70 | { | ||
71 | dm=(struct dmi_header *)data; | ||
72 | /* | 59 | /* |
73 | * We want to know the total length (formated area and strings) | 60 | * We want to know the total length (formated area and strings) |
74 | * before decoding to make sure we won't run off the table in | 61 | * before decoding to make sure we won't run off the table in |
75 | * dmi_decode or dmi_string | 62 | * dmi_decode or dmi_string |
76 | */ | 63 | */ |
77 | data+=dm->length; | 64 | data += dm->length; |
78 | while(data-buf<len-1 && (data[0] || data[1])) | 65 | while ((data - buf < len - 1) && (data[0] || data[1])) |
79 | data++; | 66 | data++; |
80 | if(data-buf<len-1) | 67 | if (data - buf < len - 1) |
81 | decode(dm); | 68 | decode(dm); |
82 | data+=2; | 69 | data += 2; |
83 | i++; | 70 | i++; |
84 | } | 71 | } |
85 | bt_iounmap(buf, len); | 72 | bt_iounmap(buf, len); |
86 | return 0; | 73 | return 0; |
87 | } | 74 | } |
88 | 75 | ||
89 | 76 | static int __init dmi_checksum(u8 *buf) | |
90 | inline static int __init dmi_checksum(u8 *buf) | ||
91 | { | 77 | { |
92 | u8 sum=0; | 78 | u8 sum = 0; |
93 | int a; | 79 | int a; |
94 | 80 | ||
95 | for(a=0; a<15; a++) | 81 | for (a = 0; a < 15; a++) |
96 | sum+=buf[a]; | 82 | sum += buf[a]; |
97 | return (sum==0); | 83 | |
84 | return sum == 0; | ||
98 | } | 85 | } |
99 | 86 | ||
100 | static int __init dmi_iterate(void (*decode)(struct dmi_header *)) | 87 | static int __init dmi_iterate(void (*decode)(struct dmi_header *)) |
@@ -110,28 +97,30 @@ static int __init dmi_iterate(void (*decode)(struct dmi_header *)) | |||
110 | p = ioremap(0xF0000, 0x10000); | 97 | p = ioremap(0xF0000, 0x10000); |
111 | if (p == NULL) | 98 | if (p == NULL) |
112 | return -1; | 99 | return -1; |
100 | |||
113 | for (q = p; q < p + 0x10000; q += 16) { | 101 | for (q = p; q < p + 0x10000; q += 16) { |
114 | memcpy_fromio(buf, q, 15); | 102 | memcpy_fromio(buf, q, 15); |
115 | if(memcmp(buf, "_DMI_", 5)==0 && dmi_checksum(buf)) | 103 | if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) { |
116 | { | 104 | u16 num = (buf[13] << 8) | buf[12]; |
117 | u16 num=buf[13]<<8|buf[12]; | 105 | u16 len = (buf[7] << 8) | buf[6]; |
118 | u16 len=buf[7]<<8|buf[6]; | 106 | u32 base = (buf[11] << 24) | (buf[10] << 16) | |
119 | u32 base=buf[11]<<24|buf[10]<<16|buf[9]<<8|buf[8]; | 107 | (buf[9] << 8) | buf[8]; |
120 | 108 | ||
121 | /* | 109 | /* |
122 | * DMI version 0.0 means that the real version is taken from | 110 | * DMI version 0.0 means that the real version is taken from |
123 | * the SMBIOS version, which we don't know at this point. | 111 | * the SMBIOS version, which we don't know at this point. |
124 | */ | 112 | */ |
125 | if(buf[14]!=0) | 113 | if (buf[14] != 0) |
126 | printk(KERN_INFO "DMI %d.%d present.\n", | 114 | printk(KERN_INFO "DMI %d.%d present.\n", |
127 | buf[14]>>4, buf[14]&0x0F); | 115 | buf[14] >> 4, buf[14] & 0xF); |
128 | else | 116 | else |
129 | printk(KERN_INFO "DMI present.\n"); | 117 | printk(KERN_INFO "DMI present.\n"); |
118 | |||
130 | dmi_printk((KERN_INFO "%d structures occupying %d bytes.\n", | 119 | dmi_printk((KERN_INFO "%d structures occupying %d bytes.\n", |
131 | num, len)); | 120 | num, len)); |
132 | dmi_printk((KERN_INFO "DMI table at 0x%08X.\n", | 121 | dmi_printk((KERN_INFO "DMI table at 0x%08X.\n", base)); |
133 | base)); | 122 | |
134 | if(dmi_table(base,len, num, decode)==0) | 123 | if (dmi_table(base,len, num, decode) == 0) |
135 | return 0; | 124 | return 0; |
136 | } | 125 | } |
137 | } | 126 | } |
@@ -143,16 +132,17 @@ static char *dmi_ident[DMI_STRING_MAX]; | |||
143 | /* | 132 | /* |
144 | * Save a DMI string | 133 | * Save a DMI string |
145 | */ | 134 | */ |
146 | |||
147 | static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string) | 135 | static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string) |
148 | { | 136 | { |
149 | char *d = (char*)dm; | 137 | char *d = (char*)dm; |
150 | char *p = dmi_string(dm, d[string]); | 138 | char *p = dmi_string(dm, d[string]); |
151 | if(p==NULL || *p == 0) | 139 | |
140 | if (p == NULL || *p == 0) | ||
152 | return; | 141 | return; |
153 | if (dmi_ident[slot]) | 142 | if (dmi_ident[slot]) |
154 | return; | 143 | return; |
155 | dmi_ident[slot] = alloc_bootmem(strlen(p)+1); | 144 | |
145 | dmi_ident[slot] = alloc_bootmem(strlen(p) + 1); | ||
156 | if(dmi_ident[slot]) | 146 | if(dmi_ident[slot]) |
157 | strcpy(dmi_ident[slot], p); | 147 | strcpy(dmi_ident[slot], p); |
158 | else | 148 | else |
@@ -160,281 +150,47 @@ static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string) | |||
160 | } | 150 | } |
161 | 151 | ||
162 | /* | 152 | /* |
163 | * Ugly compatibility crap. | ||
164 | */ | ||
165 | #define dmi_blacklist dmi_system_id | ||
166 | #define NO_MATCH { DMI_NONE, NULL} | ||
167 | #define MATCH DMI_MATCH | ||
168 | |||
169 | /* | ||
170 | * Toshiba keyboard likes to repeat keys when they are not repeated. | ||
171 | */ | ||
172 | |||
173 | static __init int broken_toshiba_keyboard(struct dmi_blacklist *d) | ||
174 | { | ||
175 | printk(KERN_WARNING "Toshiba with broken keyboard detected. If your keyboard sometimes generates 3 keypresses instead of one, see http://davyd.ucc.asn.au/projects/toshiba/README\n"); | ||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | |||
180 | #ifdef CONFIG_ACPI_SLEEP | ||
181 | static __init int reset_videomode_after_s3(struct dmi_blacklist *d) | ||
182 | { | ||
183 | /* See acpi_wakeup.S */ | ||
184 | extern long acpi_video_flags; | ||
185 | acpi_video_flags |= 2; | ||
186 | return 0; | ||
187 | } | ||
188 | #endif | ||
189 | |||
190 | |||
191 | #ifdef CONFIG_ACPI_BOOT | ||
192 | extern int acpi_force; | ||
193 | |||
194 | static __init __attribute__((unused)) int dmi_disable_acpi(struct dmi_blacklist *d) | ||
195 | { | ||
196 | if (!acpi_force) { | ||
197 | printk(KERN_NOTICE "%s detected: acpi off\n",d->ident); | ||
198 | disable_acpi(); | ||
199 | } else { | ||
200 | printk(KERN_NOTICE | ||
201 | "Warning: DMI blacklist says broken, but acpi forced\n"); | ||
202 | } | ||
203 | return 0; | ||
204 | } | ||
205 | |||
206 | /* | ||
207 | * Limit ACPI to CPU enumeration for HT | ||
208 | */ | ||
209 | static __init __attribute__((unused)) int force_acpi_ht(struct dmi_blacklist *d) | ||
210 | { | ||
211 | if (!acpi_force) { | ||
212 | printk(KERN_NOTICE "%s detected: force use of acpi=ht\n", d->ident); | ||
213 | disable_acpi(); | ||
214 | acpi_ht = 1; | ||
215 | } else { | ||
216 | printk(KERN_NOTICE | ||
217 | "Warning: acpi=force overrules DMI blacklist: acpi=ht\n"); | ||
218 | } | ||
219 | return 0; | ||
220 | } | ||
221 | #endif | ||
222 | |||
223 | #ifdef CONFIG_ACPI_PCI | ||
224 | static __init int disable_acpi_irq(struct dmi_blacklist *d) | ||
225 | { | ||
226 | if (!acpi_force) { | ||
227 | printk(KERN_NOTICE "%s detected: force use of acpi=noirq\n", | ||
228 | d->ident); | ||
229 | acpi_noirq_set(); | ||
230 | } | ||
231 | return 0; | ||
232 | } | ||
233 | static __init int disable_acpi_pci(struct dmi_blacklist *d) | ||
234 | { | ||
235 | if (!acpi_force) { | ||
236 | printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n", | ||
237 | d->ident); | ||
238 | acpi_disable_pci(); | ||
239 | } | ||
240 | return 0; | ||
241 | } | ||
242 | #endif | ||
243 | |||
244 | /* | ||
245 | * Process the DMI blacklists | ||
246 | */ | ||
247 | |||
248 | |||
249 | /* | ||
250 | * This will be expanded over time to force things like the APM | ||
251 | * interrupt mask settings according to the laptop | ||
252 | */ | ||
253 | |||
254 | static __initdata struct dmi_blacklist dmi_blacklist[]={ | ||
255 | |||
256 | { broken_toshiba_keyboard, "Toshiba Satellite 4030cdt", { /* Keyboard generates spurious repeats */ | ||
257 | MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"), | ||
258 | NO_MATCH, NO_MATCH, NO_MATCH | ||
259 | } }, | ||
260 | #ifdef CONFIG_ACPI_SLEEP | ||
261 | { reset_videomode_after_s3, "Toshiba Satellite 4030cdt", { /* Reset video mode after returning from ACPI S3 sleep */ | ||
262 | MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"), | ||
263 | NO_MATCH, NO_MATCH, NO_MATCH | ||
264 | } }, | ||
265 | #endif | ||
266 | |||
267 | #ifdef CONFIG_ACPI_BOOT | ||
268 | /* | ||
269 | * If your system is blacklisted here, but you find that acpi=force | ||
270 | * works for you, please contact acpi-devel@sourceforge.net | ||
271 | */ | ||
272 | |||
273 | /* | ||
274 | * Boxes that need ACPI disabled | ||
275 | */ | ||
276 | |||
277 | { dmi_disable_acpi, "IBM Thinkpad", { | ||
278 | MATCH(DMI_BOARD_VENDOR, "IBM"), | ||
279 | MATCH(DMI_BOARD_NAME, "2629H1G"), | ||
280 | NO_MATCH, NO_MATCH }}, | ||
281 | |||
282 | /* | ||
283 | * Boxes that need acpi=ht | ||
284 | */ | ||
285 | |||
286 | { force_acpi_ht, "FSC Primergy T850", { | ||
287 | MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
288 | MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"), | ||
289 | NO_MATCH, NO_MATCH }}, | ||
290 | |||
291 | { force_acpi_ht, "DELL GX240", { | ||
292 | MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"), | ||
293 | MATCH(DMI_BOARD_NAME, "OptiPlex GX240"), | ||
294 | NO_MATCH, NO_MATCH }}, | ||
295 | |||
296 | { force_acpi_ht, "HP VISUALIZE NT Workstation", { | ||
297 | MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), | ||
298 | MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"), | ||
299 | NO_MATCH, NO_MATCH }}, | ||
300 | |||
301 | { force_acpi_ht, "Compaq Workstation W8000", { | ||
302 | MATCH(DMI_SYS_VENDOR, "Compaq"), | ||
303 | MATCH(DMI_PRODUCT_NAME, "Workstation W8000"), | ||
304 | NO_MATCH, NO_MATCH }}, | ||
305 | |||
306 | { force_acpi_ht, "ASUS P4B266", { | ||
307 | MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), | ||
308 | MATCH(DMI_BOARD_NAME, "P4B266"), | ||
309 | NO_MATCH, NO_MATCH }}, | ||
310 | |||
311 | { force_acpi_ht, "ASUS P2B-DS", { | ||
312 | MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), | ||
313 | MATCH(DMI_BOARD_NAME, "P2B-DS"), | ||
314 | NO_MATCH, NO_MATCH }}, | ||
315 | |||
316 | { force_acpi_ht, "ASUS CUR-DLS", { | ||
317 | MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), | ||
318 | MATCH(DMI_BOARD_NAME, "CUR-DLS"), | ||
319 | NO_MATCH, NO_MATCH }}, | ||
320 | |||
321 | { force_acpi_ht, "ABIT i440BX-W83977", { | ||
322 | MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"), | ||
323 | MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"), | ||
324 | NO_MATCH, NO_MATCH }}, | ||
325 | |||
326 | { force_acpi_ht, "IBM Bladecenter", { | ||
327 | MATCH(DMI_BOARD_VENDOR, "IBM"), | ||
328 | MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"), | ||
329 | NO_MATCH, NO_MATCH }}, | ||
330 | |||
331 | { force_acpi_ht, "IBM eServer xSeries 360", { | ||
332 | MATCH(DMI_BOARD_VENDOR, "IBM"), | ||
333 | MATCH(DMI_BOARD_NAME, "eServer xSeries 360"), | ||
334 | NO_MATCH, NO_MATCH }}, | ||
335 | |||
336 | { force_acpi_ht, "IBM eserver xSeries 330", { | ||
337 | MATCH(DMI_BOARD_VENDOR, "IBM"), | ||
338 | MATCH(DMI_BOARD_NAME, "eserver xSeries 330"), | ||
339 | NO_MATCH, NO_MATCH }}, | ||
340 | |||
341 | { force_acpi_ht, "IBM eserver xSeries 440", { | ||
342 | MATCH(DMI_BOARD_VENDOR, "IBM"), | ||
343 | MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"), | ||
344 | NO_MATCH, NO_MATCH }}, | ||
345 | |||
346 | #endif // CONFIG_ACPI_BOOT | ||
347 | |||
348 | #ifdef CONFIG_ACPI_PCI | ||
349 | /* | ||
350 | * Boxes that need ACPI PCI IRQ routing disabled | ||
351 | */ | ||
352 | |||
353 | { disable_acpi_irq, "ASUS A7V", { | ||
354 | MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"), | ||
355 | MATCH(DMI_BOARD_NAME, "<A7V>"), | ||
356 | /* newer BIOS, Revision 1011, does work */ | ||
357 | MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1007"), | ||
358 | NO_MATCH }}, | ||
359 | |||
360 | /* | ||
361 | * Boxes that need ACPI PCI IRQ routing and PCI scan disabled | ||
362 | */ | ||
363 | { disable_acpi_pci, "ASUS PR-DLS", { /* _BBN 0 bug */ | ||
364 | MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), | ||
365 | MATCH(DMI_BOARD_NAME, "PR-DLS"), | ||
366 | MATCH(DMI_BIOS_VERSION, "ASUS PR-DLS ACPI BIOS Revision 1010"), | ||
367 | MATCH(DMI_BIOS_DATE, "03/21/2003") }}, | ||
368 | |||
369 | { disable_acpi_pci, "Acer TravelMate 36x Laptop", { | ||
370 | MATCH(DMI_SYS_VENDOR, "Acer"), | ||
371 | MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), | ||
372 | NO_MATCH, NO_MATCH | ||
373 | } }, | ||
374 | |||
375 | #endif | ||
376 | |||
377 | { NULL, } | ||
378 | }; | ||
379 | |||
380 | /* | ||
381 | * Process a DMI table entry. Right now all we care about are the BIOS | 153 | * Process a DMI table entry. Right now all we care about are the BIOS |
382 | * and machine entries. For 2.5 we should pull the smbus controller info | 154 | * and machine entries. For 2.5 we should pull the smbus controller info |
383 | * out of here. | 155 | * out of here. |
384 | */ | 156 | */ |
385 | |||
386 | static void __init dmi_decode(struct dmi_header *dm) | 157 | static void __init dmi_decode(struct dmi_header *dm) |
387 | { | 158 | { |
388 | #ifdef DMI_DEBUG | 159 | u8 *data __attribute__((__unused__)) = (u8 *)dm; |
389 | u8 *data = (u8 *)dm; | ||
390 | #endif | ||
391 | 160 | ||
392 | switch(dm->type) | 161 | switch(dm->type) { |
393 | { | 162 | case 0: |
394 | case 0: | 163 | dmi_printk(("BIOS Vendor: %s\n", dmi_string(dm, data[4]))); |
395 | dmi_printk(("BIOS Vendor: %s\n", | 164 | dmi_save_ident(dm, DMI_BIOS_VENDOR, 4); |
396 | dmi_string(dm, data[4]))); | 165 | dmi_printk(("BIOS Version: %s\n", dmi_string(dm, data[5]))); |
397 | dmi_save_ident(dm, DMI_BIOS_VENDOR, 4); | 166 | dmi_save_ident(dm, DMI_BIOS_VERSION, 5); |
398 | dmi_printk(("BIOS Version: %s\n", | 167 | dmi_printk(("BIOS Release: %s\n", dmi_string(dm, data[8]))); |
399 | dmi_string(dm, data[5]))); | 168 | dmi_save_ident(dm, DMI_BIOS_DATE, 8); |
400 | dmi_save_ident(dm, DMI_BIOS_VERSION, 5); | 169 | break; |
401 | dmi_printk(("BIOS Release: %s\n", | 170 | case 1: |
402 | dmi_string(dm, data[8]))); | 171 | dmi_printk(("System Vendor: %s\n", dmi_string(dm, data[4]))); |
403 | dmi_save_ident(dm, DMI_BIOS_DATE, 8); | 172 | dmi_save_ident(dm, DMI_SYS_VENDOR, 4); |
404 | break; | 173 | dmi_printk(("Product Name: %s\n", dmi_string(dm, data[5]))); |
405 | case 1: | 174 | dmi_save_ident(dm, DMI_PRODUCT_NAME, 5); |
406 | dmi_printk(("System Vendor: %s\n", | 175 | dmi_printk(("Version: %s\n", dmi_string(dm, data[6]))); |
407 | dmi_string(dm, data[4]))); | 176 | dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6); |
408 | dmi_save_ident(dm, DMI_SYS_VENDOR, 4); | 177 | dmi_printk(("Serial Number: %s\n", dmi_string(dm, data[7]))); |
409 | dmi_printk(("Product Name: %s\n", | 178 | dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7); |
410 | dmi_string(dm, data[5]))); | 179 | break; |
411 | dmi_save_ident(dm, DMI_PRODUCT_NAME, 5); | 180 | case 2: |
412 | dmi_printk(("Version: %s\n", | 181 | dmi_printk(("Board Vendor: %s\n", dmi_string(dm, data[4]))); |
413 | dmi_string(dm, data[6]))); | 182 | dmi_save_ident(dm, DMI_BOARD_VENDOR, 4); |
414 | dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6); | 183 | dmi_printk(("Board Name: %s\n", dmi_string(dm, data[5]))); |
415 | dmi_printk(("Serial Number: %s\n", | 184 | dmi_save_ident(dm, DMI_BOARD_NAME, 5); |
416 | dmi_string(dm, data[7]))); | 185 | dmi_printk(("Board Version: %s\n", dmi_string(dm, data[6]))); |
417 | break; | 186 | dmi_save_ident(dm, DMI_BOARD_VERSION, 6); |
418 | case 2: | 187 | break; |
419 | dmi_printk(("Board Vendor: %s\n", | ||
420 | dmi_string(dm, data[4]))); | ||
421 | dmi_save_ident(dm, DMI_BOARD_VENDOR, 4); | ||
422 | dmi_printk(("Board Name: %s\n", | ||
423 | dmi_string(dm, data[5]))); | ||
424 | dmi_save_ident(dm, DMI_BOARD_NAME, 5); | ||
425 | dmi_printk(("Board Version: %s\n", | ||
426 | dmi_string(dm, data[6]))); | ||
427 | dmi_save_ident(dm, DMI_BOARD_VERSION, 6); | ||
428 | break; | ||
429 | } | 188 | } |
430 | } | 189 | } |
431 | 190 | ||
432 | void __init dmi_scan_machine(void) | 191 | void __init dmi_scan_machine(void) |
433 | { | 192 | { |
434 | int err = dmi_iterate(dmi_decode); | 193 | if (dmi_iterate(dmi_decode)) |
435 | if(err == 0) | ||
436 | dmi_check_system(dmi_blacklist); | ||
437 | else | ||
438 | printk(KERN_INFO "DMI not present.\n"); | 194 | printk(KERN_INFO "DMI not present.\n"); |
439 | } | 195 | } |
440 | 196 | ||
@@ -470,7 +226,6 @@ fail: d++; | |||
470 | 226 | ||
471 | return count; | 227 | return count; |
472 | } | 228 | } |
473 | |||
474 | EXPORT_SYMBOL(dmi_check_system); | 229 | EXPORT_SYMBOL(dmi_check_system); |
475 | 230 | ||
476 | /** | 231 | /** |
@@ -480,8 +235,8 @@ EXPORT_SYMBOL(dmi_check_system); | |||
480 | * Returns one DMI data value, can be used to perform | 235 | * Returns one DMI data value, can be used to perform |
481 | * complex DMI data checks. | 236 | * complex DMI data checks. |
482 | */ | 237 | */ |
483 | char * dmi_get_system_info(int field) | 238 | char *dmi_get_system_info(int field) |
484 | { | 239 | { |
485 | return dmi_ident[field]; | 240 | return dmi_ident[field]; |
486 | } | 241 | } |
487 | 242 | EXPORT_SYMBOL(dmi_get_system_info); | |
diff --git a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c index f732f427b418..385883ea8c19 100644 --- a/arch/i386/kernel/efi.c +++ b/arch/i386/kernel/efi.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/ioport.h> | 30 | #include <linux/ioport.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/efi.h> | 32 | #include <linux/efi.h> |
33 | #include <linux/kexec.h> | ||
33 | 34 | ||
34 | #include <asm/setup.h> | 35 | #include <asm/setup.h> |
35 | #include <asm/io.h> | 36 | #include <asm/io.h> |
@@ -598,6 +599,9 @@ efi_initialize_iomem_resources(struct resource *code_resource, | |||
598 | if (md->type == EFI_CONVENTIONAL_MEMORY) { | 599 | if (md->type == EFI_CONVENTIONAL_MEMORY) { |
599 | request_resource(res, code_resource); | 600 | request_resource(res, code_resource); |
600 | request_resource(res, data_resource); | 601 | request_resource(res, data_resource); |
602 | #ifdef CONFIG_KEXEC | ||
603 | request_resource(res, &crashk_res); | ||
604 | #endif | ||
601 | } | 605 | } |
602 | } | 606 | } |
603 | } | 607 | } |
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index e966fc8c44c4..4477bb107098 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S | |||
@@ -299,7 +299,6 @@ is386: movl $2,%ecx # set MP | |||
299 | movl %eax,%cr0 | 299 | movl %eax,%cr0 |
300 | 300 | ||
301 | call check_x87 | 301 | call check_x87 |
302 | incb ready | ||
303 | lgdt cpu_gdt_descr | 302 | lgdt cpu_gdt_descr |
304 | lidt idt_descr | 303 | lidt idt_descr |
305 | ljmp $(__KERNEL_CS),$1f | 304 | ljmp $(__KERNEL_CS),$1f |
@@ -316,8 +315,9 @@ is386: movl $2,%ecx # set MP | |||
316 | lldt %ax | 315 | lldt %ax |
317 | cld # gcc2 wants the direction flag cleared at all times | 316 | cld # gcc2 wants the direction flag cleared at all times |
318 | #ifdef CONFIG_SMP | 317 | #ifdef CONFIG_SMP |
319 | movb ready, %cl | 318 | movb ready, %cl |
320 | cmpb $1,%cl | 319 | movb $1, ready |
320 | cmpb $0,%cl | ||
321 | je 1f # the first CPU calls start_kernel | 321 | je 1f # the first CPU calls start_kernel |
322 | # all other CPUs call initialize_secondary | 322 | # all other CPUs call initialize_secondary |
323 | call initialize_secondary | 323 | call initialize_secondary |
diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c index 2c4813b47e57..178f4e9bac9d 100644 --- a/arch/i386/kernel/i8259.c +++ b/arch/i386/kernel/i8259.c | |||
@@ -268,10 +268,22 @@ static int i8259A_suspend(struct sys_device *dev, pm_message_t state) | |||
268 | return 0; | 268 | return 0; |
269 | } | 269 | } |
270 | 270 | ||
271 | static int i8259A_shutdown(struct sys_device *dev) | ||
272 | { | ||
273 | /* Put the i8259A into a quiescent state that | ||
274 | * the kernel initialization code can get it | ||
275 | * out of. | ||
276 | */ | ||
277 | outb(0xff, 0x21); /* mask all of 8259A-1 */ | ||
278 | outb(0xff, 0xA1); /* mask all of 8259A-1 */ | ||
279 | return 0; | ||
280 | } | ||
281 | |||
271 | static struct sysdev_class i8259_sysdev_class = { | 282 | static struct sysdev_class i8259_sysdev_class = { |
272 | set_kset_name("i8259"), | 283 | set_kset_name("i8259"), |
273 | .suspend = i8259A_suspend, | 284 | .suspend = i8259A_suspend, |
274 | .resume = i8259A_resume, | 285 | .resume = i8259A_resume, |
286 | .shutdown = i8259A_shutdown, | ||
275 | }; | 287 | }; |
276 | 288 | ||
277 | static struct sys_device device_i8259A = { | 289 | static struct sys_device device_i8259A = { |
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 2451a3a99440..35eb8e29c485 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c | |||
@@ -576,9 +576,11 @@ static int balanced_irq(void *unused) | |||
576 | try_to_freeze(); | 576 | try_to_freeze(); |
577 | if (time_after(jiffies, | 577 | if (time_after(jiffies, |
578 | prev_balance_time+balanced_irq_interval)) { | 578 | prev_balance_time+balanced_irq_interval)) { |
579 | preempt_disable(); | ||
579 | do_irq_balance(); | 580 | do_irq_balance(); |
580 | prev_balance_time = jiffies; | 581 | prev_balance_time = jiffies; |
581 | time_remaining = balanced_irq_interval; | 582 | time_remaining = balanced_irq_interval; |
583 | preempt_enable(); | ||
582 | } | 584 | } |
583 | } | 585 | } |
584 | return 0; | 586 | return 0; |
@@ -630,10 +632,8 @@ static int __init balanced_irq_init(void) | |||
630 | printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq"); | 632 | printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq"); |
631 | failed: | 633 | failed: |
632 | for (i = 0; i < NR_CPUS; i++) { | 634 | for (i = 0; i < NR_CPUS; i++) { |
633 | if(irq_cpu_data[i].irq_delta) | 635 | kfree(irq_cpu_data[i].irq_delta); |
634 | kfree(irq_cpu_data[i].irq_delta); | 636 | kfree(irq_cpu_data[i].last_irq); |
635 | if(irq_cpu_data[i].last_irq) | ||
636 | kfree(irq_cpu_data[i].last_irq); | ||
637 | } | 637 | } |
638 | return 0; | 638 | return 0; |
639 | } | 639 | } |
@@ -1634,12 +1634,43 @@ static void __init enable_IO_APIC(void) | |||
1634 | */ | 1634 | */ |
1635 | void disable_IO_APIC(void) | 1635 | void disable_IO_APIC(void) |
1636 | { | 1636 | { |
1637 | int pin; | ||
1637 | /* | 1638 | /* |
1638 | * Clear the IO-APIC before rebooting: | 1639 | * Clear the IO-APIC before rebooting: |
1639 | */ | 1640 | */ |
1640 | clear_IO_APIC(); | 1641 | clear_IO_APIC(); |
1641 | 1642 | ||
1642 | disconnect_bsp_APIC(); | 1643 | /* |
1644 | * If the i82559 is routed through an IOAPIC | ||
1645 | * Put that IOAPIC in virtual wire mode | ||
1646 | * so legacy interrups can be delivered. | ||
1647 | */ | ||
1648 | pin = find_isa_irq_pin(0, mp_ExtINT); | ||
1649 | if (pin != -1) { | ||
1650 | struct IO_APIC_route_entry entry; | ||
1651 | unsigned long flags; | ||
1652 | |||
1653 | memset(&entry, 0, sizeof(entry)); | ||
1654 | entry.mask = 0; /* Enabled */ | ||
1655 | entry.trigger = 0; /* Edge */ | ||
1656 | entry.irr = 0; | ||
1657 | entry.polarity = 0; /* High */ | ||
1658 | entry.delivery_status = 0; | ||
1659 | entry.dest_mode = 0; /* Physical */ | ||
1660 | entry.delivery_mode = 7; /* ExtInt */ | ||
1661 | entry.vector = 0; | ||
1662 | entry.dest.physical.physical_dest = 0; | ||
1663 | |||
1664 | |||
1665 | /* | ||
1666 | * Add it to the IO-APIC irq-routing table: | ||
1667 | */ | ||
1668 | spin_lock_irqsave(&ioapic_lock, flags); | ||
1669 | io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1)); | ||
1670 | io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0)); | ||
1671 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
1672 | } | ||
1673 | disconnect_bsp_APIC(pin != -1); | ||
1643 | } | 1674 | } |
1644 | 1675 | ||
1645 | /* | 1676 | /* |
diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c index 73945a3c53c4..ce66dcc26d90 100644 --- a/arch/i386/kernel/irq.c +++ b/arch/i386/kernel/irq.c | |||
@@ -15,6 +15,9 @@ | |||
15 | #include <linux/seq_file.h> | 15 | #include <linux/seq_file.h> |
16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
17 | #include <linux/kernel_stat.h> | 17 | #include <linux/kernel_stat.h> |
18 | #include <linux/notifier.h> | ||
19 | #include <linux/cpu.h> | ||
20 | #include <linux/delay.h> | ||
18 | 21 | ||
19 | DEFINE_PER_CPU(irq_cpustat_t, irq_stat) ____cacheline_maxaligned_in_smp; | 22 | DEFINE_PER_CPU(irq_cpustat_t, irq_stat) ____cacheline_maxaligned_in_smp; |
20 | EXPORT_PER_CPU_SYMBOL(irq_stat); | 23 | EXPORT_PER_CPU_SYMBOL(irq_stat); |
@@ -153,6 +156,11 @@ void irq_ctx_init(int cpu) | |||
153 | cpu,hardirq_ctx[cpu],softirq_ctx[cpu]); | 156 | cpu,hardirq_ctx[cpu],softirq_ctx[cpu]); |
154 | } | 157 | } |
155 | 158 | ||
159 | void irq_ctx_exit(int cpu) | ||
160 | { | ||
161 | hardirq_ctx[cpu] = NULL; | ||
162 | } | ||
163 | |||
156 | extern asmlinkage void __do_softirq(void); | 164 | extern asmlinkage void __do_softirq(void); |
157 | 165 | ||
158 | asmlinkage void do_softirq(void) | 166 | asmlinkage void do_softirq(void) |
@@ -210,9 +218,8 @@ int show_interrupts(struct seq_file *p, void *v) | |||
210 | 218 | ||
211 | if (i == 0) { | 219 | if (i == 0) { |
212 | seq_printf(p, " "); | 220 | seq_printf(p, " "); |
213 | for (j=0; j<NR_CPUS; j++) | 221 | for_each_cpu(j) |
214 | if (cpu_online(j)) | 222 | seq_printf(p, "CPU%d ",j); |
215 | seq_printf(p, "CPU%d ",j); | ||
216 | seq_putc(p, '\n'); | 223 | seq_putc(p, '\n'); |
217 | } | 224 | } |
218 | 225 | ||
@@ -225,9 +232,8 @@ int show_interrupts(struct seq_file *p, void *v) | |||
225 | #ifndef CONFIG_SMP | 232 | #ifndef CONFIG_SMP |
226 | seq_printf(p, "%10u ", kstat_irqs(i)); | 233 | seq_printf(p, "%10u ", kstat_irqs(i)); |
227 | #else | 234 | #else |
228 | for (j = 0; j < NR_CPUS; j++) | 235 | for_each_cpu(j) |
229 | if (cpu_online(j)) | 236 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); |
230 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); | ||
231 | #endif | 237 | #endif |
232 | seq_printf(p, " %14s", irq_desc[i].handler->typename); | 238 | seq_printf(p, " %14s", irq_desc[i].handler->typename); |
233 | seq_printf(p, " %s", action->name); | 239 | seq_printf(p, " %s", action->name); |
@@ -240,16 +246,14 @@ skip: | |||
240 | spin_unlock_irqrestore(&irq_desc[i].lock, flags); | 246 | spin_unlock_irqrestore(&irq_desc[i].lock, flags); |
241 | } else if (i == NR_IRQS) { | 247 | } else if (i == NR_IRQS) { |
242 | seq_printf(p, "NMI: "); | 248 | seq_printf(p, "NMI: "); |
243 | for (j = 0; j < NR_CPUS; j++) | 249 | for_each_cpu(j) |
244 | if (cpu_online(j)) | 250 | seq_printf(p, "%10u ", nmi_count(j)); |
245 | seq_printf(p, "%10u ", nmi_count(j)); | ||
246 | seq_putc(p, '\n'); | 251 | seq_putc(p, '\n'); |
247 | #ifdef CONFIG_X86_LOCAL_APIC | 252 | #ifdef CONFIG_X86_LOCAL_APIC |
248 | seq_printf(p, "LOC: "); | 253 | seq_printf(p, "LOC: "); |
249 | for (j = 0; j < NR_CPUS; j++) | 254 | for_each_cpu(j) |
250 | if (cpu_online(j)) | 255 | seq_printf(p, "%10u ", |
251 | seq_printf(p, "%10u ", | 256 | per_cpu(irq_stat,j).apic_timer_irqs); |
252 | per_cpu(irq_stat,j).apic_timer_irqs); | ||
253 | seq_putc(p, '\n'); | 257 | seq_putc(p, '\n'); |
254 | #endif | 258 | #endif |
255 | seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); | 259 | seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); |
@@ -259,3 +263,45 @@ skip: | |||
259 | } | 263 | } |
260 | return 0; | 264 | return 0; |
261 | } | 265 | } |
266 | |||
267 | #ifdef CONFIG_HOTPLUG_CPU | ||
268 | #include <mach_apic.h> | ||
269 | |||
270 | void fixup_irqs(cpumask_t map) | ||
271 | { | ||
272 | unsigned int irq; | ||
273 | static int warned; | ||
274 | |||
275 | for (irq = 0; irq < NR_IRQS; irq++) { | ||
276 | cpumask_t mask; | ||
277 | if (irq == 2) | ||
278 | continue; | ||
279 | |||
280 | cpus_and(mask, irq_affinity[irq], map); | ||
281 | if (any_online_cpu(mask) == NR_CPUS) { | ||
282 | printk("Breaking affinity for irq %i\n", irq); | ||
283 | mask = map; | ||
284 | } | ||
285 | if (irq_desc[irq].handler->set_affinity) | ||
286 | irq_desc[irq].handler->set_affinity(irq, mask); | ||
287 | else if (irq_desc[irq].action && !(warned++)) | ||
288 | printk("Cannot set affinity for irq %i\n", irq); | ||
289 | } | ||
290 | |||
291 | #if 0 | ||
292 | barrier(); | ||
293 | /* Ingo Molnar says: "after the IO-APIC masks have been redirected | ||
294 | [note the nop - the interrupt-enable boundary on x86 is two | ||
295 | instructions from sti] - to flush out pending hardirqs and | ||
296 | IPIs. After this point nothing is supposed to reach this CPU." */ | ||
297 | __asm__ __volatile__("sti; nop; cli"); | ||
298 | barrier(); | ||
299 | #else | ||
300 | /* That doesn't seem sufficient. Give it 1ms. */ | ||
301 | local_irq_enable(); | ||
302 | mdelay(1); | ||
303 | local_irq_disable(); | ||
304 | #endif | ||
305 | } | ||
306 | #endif | ||
307 | |||
diff --git a/arch/i386/kernel/machine_kexec.c b/arch/i386/kernel/machine_kexec.c new file mode 100644 index 000000000000..52ed18d8b511 --- /dev/null +++ b/arch/i386/kernel/machine_kexec.c | |||
@@ -0,0 +1,226 @@ | |||
1 | /* | ||
2 | * machine_kexec.c - handle transition of Linux booting another kernel | ||
3 | * Copyright (C) 2002-2005 Eric Biederman <ebiederm@xmission.com> | ||
4 | * | ||
5 | * This source code is licensed under the GNU General Public License, | ||
6 | * Version 2. See the file COPYING for more details. | ||
7 | */ | ||
8 | |||
9 | #include <linux/mm.h> | ||
10 | #include <linux/kexec.h> | ||
11 | #include <linux/delay.h> | ||
12 | #include <asm/pgtable.h> | ||
13 | #include <asm/pgalloc.h> | ||
14 | #include <asm/tlbflush.h> | ||
15 | #include <asm/mmu_context.h> | ||
16 | #include <asm/io.h> | ||
17 | #include <asm/apic.h> | ||
18 | #include <asm/cpufeature.h> | ||
19 | |||
20 | static inline unsigned long read_cr3(void) | ||
21 | { | ||
22 | unsigned long cr3; | ||
23 | asm volatile("movl %%cr3,%0": "=r"(cr3)); | ||
24 | return cr3; | ||
25 | } | ||
26 | |||
27 | #define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE))) | ||
28 | |||
29 | #define L0_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) | ||
30 | #define L1_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) | ||
31 | #define L2_ATTR (_PAGE_PRESENT) | ||
32 | |||
33 | #define LEVEL0_SIZE (1UL << 12UL) | ||
34 | |||
35 | #ifndef CONFIG_X86_PAE | ||
36 | #define LEVEL1_SIZE (1UL << 22UL) | ||
37 | static u32 pgtable_level1[1024] PAGE_ALIGNED; | ||
38 | |||
39 | static void identity_map_page(unsigned long address) | ||
40 | { | ||
41 | unsigned long level1_index, level2_index; | ||
42 | u32 *pgtable_level2; | ||
43 | |||
44 | /* Find the current page table */ | ||
45 | pgtable_level2 = __va(read_cr3()); | ||
46 | |||
47 | /* Find the indexes of the physical address to identity map */ | ||
48 | level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE; | ||
49 | level2_index = address / LEVEL1_SIZE; | ||
50 | |||
51 | /* Identity map the page table entry */ | ||
52 | pgtable_level1[level1_index] = address | L0_ATTR; | ||
53 | pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR; | ||
54 | |||
55 | /* Flush the tlb so the new mapping takes effect. | ||
56 | * Global tlb entries are not flushed but that is not an issue. | ||
57 | */ | ||
58 | load_cr3(pgtable_level2); | ||
59 | } | ||
60 | |||
61 | #else | ||
62 | #define LEVEL1_SIZE (1UL << 21UL) | ||
63 | #define LEVEL2_SIZE (1UL << 30UL) | ||
64 | static u64 pgtable_level1[512] PAGE_ALIGNED; | ||
65 | static u64 pgtable_level2[512] PAGE_ALIGNED; | ||
66 | |||
67 | static void identity_map_page(unsigned long address) | ||
68 | { | ||
69 | unsigned long level1_index, level2_index, level3_index; | ||
70 | u64 *pgtable_level3; | ||
71 | |||
72 | /* Find the current page table */ | ||
73 | pgtable_level3 = __va(read_cr3()); | ||
74 | |||
75 | /* Find the indexes of the physical address to identity map */ | ||
76 | level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE; | ||
77 | level2_index = (address % LEVEL2_SIZE)/LEVEL1_SIZE; | ||
78 | level3_index = address / LEVEL2_SIZE; | ||
79 | |||
80 | /* Identity map the page table entry */ | ||
81 | pgtable_level1[level1_index] = address | L0_ATTR; | ||
82 | pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR; | ||
83 | set_64bit(&pgtable_level3[level3_index], | ||
84 | __pa(pgtable_level2) | L2_ATTR); | ||
85 | |||
86 | /* Flush the tlb so the new mapping takes effect. | ||
87 | * Global tlb entries are not flushed but that is not an issue. | ||
88 | */ | ||
89 | load_cr3(pgtable_level3); | ||
90 | } | ||
91 | #endif | ||
92 | |||
93 | |||
94 | static void set_idt(void *newidt, __u16 limit) | ||
95 | { | ||
96 | unsigned char curidt[6]; | ||
97 | |||
98 | /* ia32 supports unaliged loads & stores */ | ||
99 | (*(__u16 *)(curidt)) = limit; | ||
100 | (*(__u32 *)(curidt +2)) = (unsigned long)(newidt); | ||
101 | |||
102 | __asm__ __volatile__ ( | ||
103 | "lidt %0\n" | ||
104 | : "=m" (curidt) | ||
105 | ); | ||
106 | }; | ||
107 | |||
108 | |||
109 | static void set_gdt(void *newgdt, __u16 limit) | ||
110 | { | ||
111 | unsigned char curgdt[6]; | ||
112 | |||
113 | /* ia32 supports unaligned loads & stores */ | ||
114 | (*(__u16 *)(curgdt)) = limit; | ||
115 | (*(__u32 *)(curgdt +2)) = (unsigned long)(newgdt); | ||
116 | |||
117 | __asm__ __volatile__ ( | ||
118 | "lgdt %0\n" | ||
119 | : "=m" (curgdt) | ||
120 | ); | ||
121 | }; | ||
122 | |||
123 | static void load_segments(void) | ||
124 | { | ||
125 | #define __STR(X) #X | ||
126 | #define STR(X) __STR(X) | ||
127 | |||
128 | __asm__ __volatile__ ( | ||
129 | "\tljmp $"STR(__KERNEL_CS)",$1f\n" | ||
130 | "\t1:\n" | ||
131 | "\tmovl $"STR(__KERNEL_DS)",%eax\n" | ||
132 | "\tmovl %eax,%ds\n" | ||
133 | "\tmovl %eax,%es\n" | ||
134 | "\tmovl %eax,%fs\n" | ||
135 | "\tmovl %eax,%gs\n" | ||
136 | "\tmovl %eax,%ss\n" | ||
137 | ); | ||
138 | #undef STR | ||
139 | #undef __STR | ||
140 | } | ||
141 | |||
142 | typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)( | ||
143 | unsigned long indirection_page, | ||
144 | unsigned long reboot_code_buffer, | ||
145 | unsigned long start_address, | ||
146 | unsigned int has_pae) ATTRIB_NORET; | ||
147 | |||
148 | const extern unsigned char relocate_new_kernel[]; | ||
149 | extern void relocate_new_kernel_end(void); | ||
150 | const extern unsigned int relocate_new_kernel_size; | ||
151 | |||
152 | /* | ||
153 | * A architecture hook called to validate the | ||
154 | * proposed image and prepare the control pages | ||
155 | * as needed. The pages for KEXEC_CONTROL_CODE_SIZE | ||
156 | * have been allocated, but the segments have yet | ||
157 | * been copied into the kernel. | ||
158 | * | ||
159 | * Do what every setup is needed on image and the | ||
160 | * reboot code buffer to allow us to avoid allocations | ||
161 | * later. | ||
162 | * | ||
163 | * Currently nothing. | ||
164 | */ | ||
165 | int machine_kexec_prepare(struct kimage *image) | ||
166 | { | ||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | /* | ||
171 | * Undo anything leftover by machine_kexec_prepare | ||
172 | * when an image is freed. | ||
173 | */ | ||
174 | void machine_kexec_cleanup(struct kimage *image) | ||
175 | { | ||
176 | } | ||
177 | |||
178 | /* | ||
179 | * Do not allocate memory (or fail in any way) in machine_kexec(). | ||
180 | * We are past the point of no return, committed to rebooting now. | ||
181 | */ | ||
182 | NORET_TYPE void machine_kexec(struct kimage *image) | ||
183 | { | ||
184 | unsigned long page_list; | ||
185 | unsigned long reboot_code_buffer; | ||
186 | |||
187 | relocate_new_kernel_t rnk; | ||
188 | |||
189 | /* Interrupts aren't acceptable while we reboot */ | ||
190 | local_irq_disable(); | ||
191 | |||
192 | /* Compute some offsets */ | ||
193 | reboot_code_buffer = page_to_pfn(image->control_code_page) | ||
194 | << PAGE_SHIFT; | ||
195 | page_list = image->head; | ||
196 | |||
197 | /* Set up an identity mapping for the reboot_code_buffer */ | ||
198 | identity_map_page(reboot_code_buffer); | ||
199 | |||
200 | /* copy it out */ | ||
201 | memcpy((void *)reboot_code_buffer, relocate_new_kernel, | ||
202 | relocate_new_kernel_size); | ||
203 | |||
204 | /* The segment registers are funny things, they are | ||
205 | * automatically loaded from a table, in memory wherever you | ||
206 | * set them to a specific selector, but this table is never | ||
207 | * accessed again you set the segment to a different selector. | ||
208 | * | ||
209 | * The more common model is are caches where the behide | ||
210 | * the scenes work is done, but is also dropped at arbitrary | ||
211 | * times. | ||
212 | * | ||
213 | * I take advantage of this here by force loading the | ||
214 | * segments, before I zap the gdt with an invalid value. | ||
215 | */ | ||
216 | load_segments(); | ||
217 | /* The gdt & idt are now invalid. | ||
218 | * If you want to load them you must set up your own idt & gdt. | ||
219 | */ | ||
220 | set_gdt(phys_to_virt(0),0); | ||
221 | set_idt(phys_to_virt(0),0); | ||
222 | |||
223 | /* now call it */ | ||
224 | rnk = (relocate_new_kernel_t) reboot_code_buffer; | ||
225 | (*rnk)(page_list, reboot_code_buffer, image->start, cpu_has_pae); | ||
226 | } | ||
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c index 383a11600d2c..af917f609c7d 100644 --- a/arch/i386/kernel/mpparse.c +++ b/arch/i386/kernel/mpparse.c | |||
@@ -67,7 +67,6 @@ unsigned long mp_lapic_addr; | |||
67 | 67 | ||
68 | /* Processor that is doing the boot up */ | 68 | /* Processor that is doing the boot up */ |
69 | unsigned int boot_cpu_physical_apicid = -1U; | 69 | unsigned int boot_cpu_physical_apicid = -1U; |
70 | unsigned int boot_cpu_logical_apicid = -1U; | ||
71 | /* Internal processor count */ | 70 | /* Internal processor count */ |
72 | static unsigned int __initdata num_processors; | 71 | static unsigned int __initdata num_processors; |
73 | 72 | ||
@@ -180,7 +179,6 @@ static void __init MP_processor_info (struct mpc_config_processor *m) | |||
180 | if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) { | 179 | if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) { |
181 | Dprintk(" Bootup CPU\n"); | 180 | Dprintk(" Bootup CPU\n"); |
182 | boot_cpu_physical_apicid = m->mpc_apicid; | 181 | boot_cpu_physical_apicid = m->mpc_apicid; |
183 | boot_cpu_logical_apicid = apicid; | ||
184 | } | 182 | } |
185 | 183 | ||
186 | if (num_processors >= NR_CPUS) { | 184 | if (num_processors >= NR_CPUS) { |
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index aea2ce1145df..5f8cfa6b7940 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <stdarg.h> | 14 | #include <stdarg.h> |
15 | 15 | ||
16 | #include <linux/cpu.h> | ||
16 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
17 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
18 | #include <linux/fs.h> | 19 | #include <linux/fs.h> |
@@ -55,6 +56,9 @@ | |||
55 | #include <linux/irq.h> | 56 | #include <linux/irq.h> |
56 | #include <linux/err.h> | 57 | #include <linux/err.h> |
57 | 58 | ||
59 | #include <asm/tlbflush.h> | ||
60 | #include <asm/cpu.h> | ||
61 | |||
58 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); | 62 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); |
59 | 63 | ||
60 | static int hlt_counter; | 64 | static int hlt_counter; |
@@ -143,14 +147,42 @@ static void poll_idle (void) | |||
143 | } | 147 | } |
144 | } | 148 | } |
145 | 149 | ||
150 | #ifdef CONFIG_HOTPLUG_CPU | ||
151 | #include <asm/nmi.h> | ||
152 | /* We don't actually take CPU down, just spin without interrupts. */ | ||
153 | static inline void play_dead(void) | ||
154 | { | ||
155 | /* This must be done before dead CPU ack */ | ||
156 | cpu_exit_clear(); | ||
157 | wbinvd(); | ||
158 | mb(); | ||
159 | /* Ack it */ | ||
160 | __get_cpu_var(cpu_state) = CPU_DEAD; | ||
161 | |||
162 | /* | ||
163 | * With physical CPU hotplug, we should halt the cpu | ||
164 | */ | ||
165 | local_irq_disable(); | ||
166 | while (1) | ||
167 | __asm__ __volatile__("hlt":::"memory"); | ||
168 | } | ||
169 | #else | ||
170 | static inline void play_dead(void) | ||
171 | { | ||
172 | BUG(); | ||
173 | } | ||
174 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
175 | |||
146 | /* | 176 | /* |
147 | * The idle thread. There's no useful work to be | 177 | * The idle thread. There's no useful work to be |
148 | * done, so just try to conserve power and have a | 178 | * done, so just try to conserve power and have a |
149 | * low exit latency (ie sit in a loop waiting for | 179 | * low exit latency (ie sit in a loop waiting for |
150 | * somebody to say that they'd like to reschedule) | 180 | * somebody to say that they'd like to reschedule) |
151 | */ | 181 | */ |
152 | void cpu_idle (void) | 182 | void cpu_idle(void) |
153 | { | 183 | { |
184 | int cpu = raw_smp_processor_id(); | ||
185 | |||
154 | /* endless idle loop with no priority at all */ | 186 | /* endless idle loop with no priority at all */ |
155 | while (1) { | 187 | while (1) { |
156 | while (!need_resched()) { | 188 | while (!need_resched()) { |
@@ -165,6 +197,9 @@ void cpu_idle (void) | |||
165 | if (!idle) | 197 | if (!idle) |
166 | idle = default_idle; | 198 | idle = default_idle; |
167 | 199 | ||
200 | if (cpu_is_offline(cpu)) | ||
201 | play_dead(); | ||
202 | |||
168 | __get_cpu_var(irq_stat).idle_timestamp = jiffies; | 203 | __get_cpu_var(irq_stat).idle_timestamp = jiffies; |
169 | idle(); | 204 | idle(); |
170 | } | 205 | } |
@@ -223,7 +258,7 @@ static void mwait_idle(void) | |||
223 | } | 258 | } |
224 | } | 259 | } |
225 | 260 | ||
226 | void __init select_idle_routine(const struct cpuinfo_x86 *c) | 261 | void __devinit select_idle_routine(const struct cpuinfo_x86 *c) |
227 | { | 262 | { |
228 | if (cpu_has(c, X86_FEATURE_MWAIT)) { | 263 | if (cpu_has(c, X86_FEATURE_MWAIT)) { |
229 | printk("monitor/mwait feature present.\n"); | 264 | printk("monitor/mwait feature present.\n"); |
diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c index db912209a8d3..b3e584849961 100644 --- a/arch/i386/kernel/reboot.c +++ b/arch/i386/kernel/reboot.c | |||
@@ -26,7 +26,6 @@ static int reboot_mode; | |||
26 | static int reboot_thru_bios; | 26 | static int reboot_thru_bios; |
27 | 27 | ||
28 | #ifdef CONFIG_SMP | 28 | #ifdef CONFIG_SMP |
29 | int reboot_smp = 0; | ||
30 | static int reboot_cpu = -1; | 29 | static int reboot_cpu = -1; |
31 | /* shamelessly grabbed from lib/vsprintf.c for readability */ | 30 | /* shamelessly grabbed from lib/vsprintf.c for readability */ |
32 | #define is_digit(c) ((c) >= '0' && (c) <= '9') | 31 | #define is_digit(c) ((c) >= '0' && (c) <= '9') |
@@ -49,7 +48,6 @@ static int __init reboot_setup(char *str) | |||
49 | break; | 48 | break; |
50 | #ifdef CONFIG_SMP | 49 | #ifdef CONFIG_SMP |
51 | case 's': /* "smp" reboot by executing reset on BSP or other CPU*/ | 50 | case 's': /* "smp" reboot by executing reset on BSP or other CPU*/ |
52 | reboot_smp = 1; | ||
53 | if (is_digit(*(str+1))) { | 51 | if (is_digit(*(str+1))) { |
54 | reboot_cpu = (int) (*(str+1) - '0'); | 52 | reboot_cpu = (int) (*(str+1) - '0'); |
55 | if (is_digit(*(str+2))) | 53 | if (is_digit(*(str+2))) |
@@ -88,33 +86,9 @@ static int __init set_bios_reboot(struct dmi_system_id *d) | |||
88 | return 0; | 86 | return 0; |
89 | } | 87 | } |
90 | 88 | ||
91 | /* | ||
92 | * Some machines require the "reboot=s" commandline option, this quirk makes that automatic. | ||
93 | */ | ||
94 | static int __init set_smp_reboot(struct dmi_system_id *d) | ||
95 | { | ||
96 | #ifdef CONFIG_SMP | ||
97 | if (!reboot_smp) { | ||
98 | reboot_smp = 1; | ||
99 | printk(KERN_INFO "%s series board detected. Selecting SMP-method for reboots.\n", d->ident); | ||
100 | } | ||
101 | #endif | ||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | /* | ||
106 | * Some machines require the "reboot=b,s" commandline option, this quirk makes that automatic. | ||
107 | */ | ||
108 | static int __init set_smp_bios_reboot(struct dmi_system_id *d) | ||
109 | { | ||
110 | set_smp_reboot(d); | ||
111 | set_bios_reboot(d); | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static struct dmi_system_id __initdata reboot_dmi_table[] = { | 89 | static struct dmi_system_id __initdata reboot_dmi_table[] = { |
116 | { /* Handle problems with rebooting on Dell 1300's */ | 90 | { /* Handle problems with rebooting on Dell 1300's */ |
117 | .callback = set_smp_bios_reboot, | 91 | .callback = set_bios_reboot, |
118 | .ident = "Dell PowerEdge 1300", | 92 | .ident = "Dell PowerEdge 1300", |
119 | .matches = { | 93 | .matches = { |
120 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), | 94 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), |
@@ -301,41 +275,32 @@ void machine_real_restart(unsigned char *code, int length) | |||
301 | EXPORT_SYMBOL(machine_real_restart); | 275 | EXPORT_SYMBOL(machine_real_restart); |
302 | #endif | 276 | #endif |
303 | 277 | ||
304 | void machine_restart(char * __unused) | 278 | void machine_shutdown(void) |
305 | { | 279 | { |
306 | #ifdef CONFIG_SMP | 280 | #ifdef CONFIG_SMP |
307 | int cpuid; | 281 | int reboot_cpu_id; |
308 | 282 | ||
309 | cpuid = GET_APIC_ID(apic_read(APIC_ID)); | 283 | /* The boot cpu is always logical cpu 0 */ |
310 | 284 | reboot_cpu_id = 0; | |
311 | if (reboot_smp) { | 285 | |
312 | 286 | /* See if there has been given a command line override */ | |
313 | /* check to see if reboot_cpu is valid | 287 | if ((reboot_cpu_id != -1) && (reboot_cpu < NR_CPUS) && |
314 | if its not, default to the BSP */ | 288 | cpu_isset(reboot_cpu, cpu_online_map)) { |
315 | if ((reboot_cpu == -1) || | 289 | reboot_cpu_id = reboot_cpu; |
316 | (reboot_cpu > (NR_CPUS -1)) || | ||
317 | !physid_isset(cpuid, phys_cpu_present_map)) | ||
318 | reboot_cpu = boot_cpu_physical_apicid; | ||
319 | |||
320 | reboot_smp = 0; /* use this as a flag to only go through this once*/ | ||
321 | /* re-run this function on the other CPUs | ||
322 | it will fall though this section since we have | ||
323 | cleared reboot_smp, and do the reboot if it is the | ||
324 | correct CPU, otherwise it halts. */ | ||
325 | if (reboot_cpu != cpuid) | ||
326 | smp_call_function((void *)machine_restart , NULL, 1, 0); | ||
327 | } | 290 | } |
328 | 291 | ||
329 | /* if reboot_cpu is still -1, then we want a tradional reboot, | 292 | /* Make certain the cpu I'm rebooting on is online */ |
330 | and if we are not running on the reboot_cpu,, halt */ | 293 | if (!cpu_isset(reboot_cpu_id, cpu_online_map)) { |
331 | if ((reboot_cpu != -1) && (cpuid != reboot_cpu)) { | 294 | reboot_cpu_id = smp_processor_id(); |
332 | for (;;) | ||
333 | __asm__ __volatile__ ("hlt"); | ||
334 | } | 295 | } |
335 | /* | 296 | |
336 | * Stop all CPUs and turn off local APICs and the IO-APIC, so | 297 | /* Make certain I only run on the appropriate processor */ |
337 | * other OSs see a clean IRQ state. | 298 | set_cpus_allowed(current, cpumask_of_cpu(reboot_cpu_id)); |
299 | |||
300 | /* O.K. Now that I'm on the appropriate processor, stop | ||
301 | * all of the others, and disable their local APICs. | ||
338 | */ | 302 | */ |
303 | |||
339 | smp_send_stop(); | 304 | smp_send_stop(); |
340 | #endif /* CONFIG_SMP */ | 305 | #endif /* CONFIG_SMP */ |
341 | 306 | ||
@@ -344,6 +309,11 @@ void machine_restart(char * __unused) | |||
344 | #ifdef CONFIG_X86_IO_APIC | 309 | #ifdef CONFIG_X86_IO_APIC |
345 | disable_IO_APIC(); | 310 | disable_IO_APIC(); |
346 | #endif | 311 | #endif |
312 | } | ||
313 | |||
314 | void machine_restart(char * __unused) | ||
315 | { | ||
316 | machine_shutdown(); | ||
347 | 317 | ||
348 | if (!reboot_thru_bios) { | 318 | if (!reboot_thru_bios) { |
349 | if (efi_enabled) { | 319 | if (efi_enabled) { |
diff --git a/arch/i386/kernel/relocate_kernel.S b/arch/i386/kernel/relocate_kernel.S new file mode 100644 index 000000000000..d312616effa1 --- /dev/null +++ b/arch/i386/kernel/relocate_kernel.S | |||
@@ -0,0 +1,120 @@ | |||
1 | /* | ||
2 | * relocate_kernel.S - put the kernel image in place to boot | ||
3 | * Copyright (C) 2002-2004 Eric Biederman <ebiederm@xmission.com> | ||
4 | * | ||
5 | * This source code is licensed under the GNU General Public License, | ||
6 | * Version 2. See the file COPYING for more details. | ||
7 | */ | ||
8 | |||
9 | #include <linux/linkage.h> | ||
10 | |||
11 | /* | ||
12 | * Must be relocatable PIC code callable as a C function, that once | ||
13 | * it starts can not use the previous processes stack. | ||
14 | */ | ||
15 | .globl relocate_new_kernel | ||
16 | relocate_new_kernel: | ||
17 | /* read the arguments and say goodbye to the stack */ | ||
18 | movl 4(%esp), %ebx /* page_list */ | ||
19 | movl 8(%esp), %ebp /* reboot_code_buffer */ | ||
20 | movl 12(%esp), %edx /* start address */ | ||
21 | movl 16(%esp), %ecx /* cpu_has_pae */ | ||
22 | |||
23 | /* zero out flags, and disable interrupts */ | ||
24 | pushl $0 | ||
25 | popfl | ||
26 | |||
27 | /* set a new stack at the bottom of our page... */ | ||
28 | lea 4096(%ebp), %esp | ||
29 | |||
30 | /* store the parameters back on the stack */ | ||
31 | pushl %edx /* store the start address */ | ||
32 | |||
33 | /* Set cr0 to a known state: | ||
34 | * 31 0 == Paging disabled | ||
35 | * 18 0 == Alignment check disabled | ||
36 | * 16 0 == Write protect disabled | ||
37 | * 3 0 == No task switch | ||
38 | * 2 0 == Don't do FP software emulation. | ||
39 | * 0 1 == Proctected mode enabled | ||
40 | */ | ||
41 | movl %cr0, %eax | ||
42 | andl $~((1<<31)|(1<<18)|(1<<16)|(1<<3)|(1<<2)), %eax | ||
43 | orl $(1<<0), %eax | ||
44 | movl %eax, %cr0 | ||
45 | |||
46 | /* clear cr4 if applicable */ | ||
47 | testl %ecx, %ecx | ||
48 | jz 1f | ||
49 | /* Set cr4 to a known state: | ||
50 | * Setting everything to zero seems safe. | ||
51 | */ | ||
52 | movl %cr4, %eax | ||
53 | andl $0, %eax | ||
54 | movl %eax, %cr4 | ||
55 | |||
56 | jmp 1f | ||
57 | 1: | ||
58 | |||
59 | /* Flush the TLB (needed?) */ | ||
60 | xorl %eax, %eax | ||
61 | movl %eax, %cr3 | ||
62 | |||
63 | /* Do the copies */ | ||
64 | movl %ebx, %ecx | ||
65 | jmp 1f | ||
66 | |||
67 | 0: /* top, read another word from the indirection page */ | ||
68 | movl (%ebx), %ecx | ||
69 | addl $4, %ebx | ||
70 | 1: | ||
71 | testl $0x1, %ecx /* is it a destination page */ | ||
72 | jz 2f | ||
73 | movl %ecx, %edi | ||
74 | andl $0xfffff000, %edi | ||
75 | jmp 0b | ||
76 | 2: | ||
77 | testl $0x2, %ecx /* is it an indirection page */ | ||
78 | jz 2f | ||
79 | movl %ecx, %ebx | ||
80 | andl $0xfffff000, %ebx | ||
81 | jmp 0b | ||
82 | 2: | ||
83 | testl $0x4, %ecx /* is it the done indicator */ | ||
84 | jz 2f | ||
85 | jmp 3f | ||
86 | 2: | ||
87 | testl $0x8, %ecx /* is it the source indicator */ | ||
88 | jz 0b /* Ignore it otherwise */ | ||
89 | movl %ecx, %esi /* For every source page do a copy */ | ||
90 | andl $0xfffff000, %esi | ||
91 | |||
92 | movl $1024, %ecx | ||
93 | rep ; movsl | ||
94 | jmp 0b | ||
95 | |||
96 | 3: | ||
97 | |||
98 | /* To be certain of avoiding problems with self-modifying code | ||
99 | * I need to execute a serializing instruction here. | ||
100 | * So I flush the TLB, it's handy, and not processor dependent. | ||
101 | */ | ||
102 | xorl %eax, %eax | ||
103 | movl %eax, %cr3 | ||
104 | |||
105 | /* set all of the registers to known values */ | ||
106 | /* leave %esp alone */ | ||
107 | |||
108 | xorl %eax, %eax | ||
109 | xorl %ebx, %ebx | ||
110 | xorl %ecx, %ecx | ||
111 | xorl %edx, %edx | ||
112 | xorl %esi, %esi | ||
113 | xorl %edi, %edi | ||
114 | xorl %ebp, %ebp | ||
115 | ret | ||
116 | relocate_new_kernel_end: | ||
117 | |||
118 | .globl relocate_new_kernel_size | ||
119 | relocate_new_kernel_size: | ||
120 | .long relocate_new_kernel_end - relocate_new_kernel | ||
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 30406fd0b64c..7306353c520e 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c | |||
@@ -43,7 +43,12 @@ | |||
43 | #include <linux/init.h> | 43 | #include <linux/init.h> |
44 | #include <linux/edd.h> | 44 | #include <linux/edd.h> |
45 | #include <linux/nodemask.h> | 45 | #include <linux/nodemask.h> |
46 | #include <linux/kexec.h> | ||
47 | #include <linux/crash_dump.h> | ||
48 | |||
46 | #include <video/edid.h> | 49 | #include <video/edid.h> |
50 | |||
51 | #include <asm/apic.h> | ||
47 | #include <asm/e820.h> | 52 | #include <asm/e820.h> |
48 | #include <asm/mpspec.h> | 53 | #include <asm/mpspec.h> |
49 | #include <asm/setup.h> | 54 | #include <asm/setup.h> |
@@ -55,12 +60,15 @@ | |||
55 | #include "setup_arch_pre.h" | 60 | #include "setup_arch_pre.h" |
56 | #include <bios_ebda.h> | 61 | #include <bios_ebda.h> |
57 | 62 | ||
63 | /* Forward Declaration. */ | ||
64 | void __init find_max_pfn(void); | ||
65 | |||
58 | /* This value is set up by the early boot code to point to the value | 66 | /* This value is set up by the early boot code to point to the value |
59 | immediately after the boot time page tables. It contains a *physical* | 67 | immediately after the boot time page tables. It contains a *physical* |
60 | address, and must not be in the .bss segment! */ | 68 | address, and must not be in the .bss segment! */ |
61 | unsigned long init_pg_tables_end __initdata = ~0UL; | 69 | unsigned long init_pg_tables_end __initdata = ~0UL; |
62 | 70 | ||
63 | int disable_pse __initdata = 0; | 71 | int disable_pse __devinitdata = 0; |
64 | 72 | ||
65 | /* | 73 | /* |
66 | * Machine setup.. | 74 | * Machine setup.. |
@@ -732,6 +740,15 @@ static void __init parse_cmdline_early (char ** cmdline_p) | |||
732 | if (to != command_line) | 740 | if (to != command_line) |
733 | to--; | 741 | to--; |
734 | if (!memcmp(from+7, "exactmap", 8)) { | 742 | if (!memcmp(from+7, "exactmap", 8)) { |
743 | #ifdef CONFIG_CRASH_DUMP | ||
744 | /* If we are doing a crash dump, we | ||
745 | * still need to know the real mem | ||
746 | * size before original memory map is | ||
747 | * reset. | ||
748 | */ | ||
749 | find_max_pfn(); | ||
750 | saved_max_pfn = max_pfn; | ||
751 | #endif | ||
735 | from += 8+7; | 752 | from += 8+7; |
736 | e820.nr_map = 0; | 753 | e820.nr_map = 0; |
737 | userdef = 1; | 754 | userdef = 1; |
@@ -835,6 +852,44 @@ static void __init parse_cmdline_early (char ** cmdline_p) | |||
835 | #endif /* CONFIG_X86_LOCAL_APIC */ | 852 | #endif /* CONFIG_X86_LOCAL_APIC */ |
836 | #endif /* CONFIG_ACPI_BOOT */ | 853 | #endif /* CONFIG_ACPI_BOOT */ |
837 | 854 | ||
855 | #ifdef CONFIG_X86_LOCAL_APIC | ||
856 | /* enable local APIC */ | ||
857 | else if (!memcmp(from, "lapic", 5)) | ||
858 | lapic_enable(); | ||
859 | |||
860 | /* disable local APIC */ | ||
861 | else if (!memcmp(from, "nolapic", 6)) | ||
862 | lapic_disable(); | ||
863 | #endif /* CONFIG_X86_LOCAL_APIC */ | ||
864 | |||
865 | #ifdef CONFIG_KEXEC | ||
866 | /* crashkernel=size@addr specifies the location to reserve for | ||
867 | * a crash kernel. By reserving this memory we guarantee | ||
868 | * that linux never set's it up as a DMA target. | ||
869 | * Useful for holding code to do something appropriate | ||
870 | * after a kernel panic. | ||
871 | */ | ||
872 | else if (!memcmp(from, "crashkernel=", 12)) { | ||
873 | unsigned long size, base; | ||
874 | size = memparse(from+12, &from); | ||
875 | if (*from == '@') { | ||
876 | base = memparse(from+1, &from); | ||
877 | /* FIXME: Do I want a sanity check | ||
878 | * to validate the memory range? | ||
879 | */ | ||
880 | crashk_res.start = base; | ||
881 | crashk_res.end = base + size - 1; | ||
882 | } | ||
883 | } | ||
884 | #endif | ||
885 | #ifdef CONFIG_CRASH_DUMP | ||
886 | /* elfcorehdr= specifies the location of elf core header | ||
887 | * stored by the crashed kernel. | ||
888 | */ | ||
889 | else if (!memcmp(from, "elfcorehdr=", 11)) | ||
890 | elfcorehdr_addr = memparse(from+11, &from); | ||
891 | #endif | ||
892 | |||
838 | /* | 893 | /* |
839 | * highmem=size forces highmem to be exactly 'size' bytes. | 894 | * highmem=size forces highmem to be exactly 'size' bytes. |
840 | * This works even on boxes that have no highmem otherwise. | 895 | * This works even on boxes that have no highmem otherwise. |
@@ -1113,8 +1168,8 @@ void __init setup_bootmem_allocator(void) | |||
1113 | * the (very unlikely) case of us accidentally initializing the | 1168 | * the (very unlikely) case of us accidentally initializing the |
1114 | * bootmem allocator with an invalid RAM area. | 1169 | * bootmem allocator with an invalid RAM area. |
1115 | */ | 1170 | */ |
1116 | reserve_bootmem(HIGH_MEMORY, (PFN_PHYS(min_low_pfn) + | 1171 | reserve_bootmem(__PHYSICAL_START, (PFN_PHYS(min_low_pfn) + |
1117 | bootmap_size + PAGE_SIZE-1) - (HIGH_MEMORY)); | 1172 | bootmap_size + PAGE_SIZE-1) - (__PHYSICAL_START)); |
1118 | 1173 | ||
1119 | /* | 1174 | /* |
1120 | * reserve physical page 0 - it's a special BIOS page on many boxes, | 1175 | * reserve physical page 0 - it's a special BIOS page on many boxes, |
@@ -1170,6 +1225,11 @@ void __init setup_bootmem_allocator(void) | |||
1170 | } | 1225 | } |
1171 | } | 1226 | } |
1172 | #endif | 1227 | #endif |
1228 | #ifdef CONFIG_KEXEC | ||
1229 | if (crashk_res.start != crashk_res.end) | ||
1230 | reserve_bootmem(crashk_res.start, | ||
1231 | crashk_res.end - crashk_res.start + 1); | ||
1232 | #endif | ||
1173 | } | 1233 | } |
1174 | 1234 | ||
1175 | /* | 1235 | /* |
@@ -1223,6 +1283,9 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat | |||
1223 | */ | 1283 | */ |
1224 | request_resource(res, code_resource); | 1284 | request_resource(res, code_resource); |
1225 | request_resource(res, data_resource); | 1285 | request_resource(res, data_resource); |
1286 | #ifdef CONFIG_KEXEC | ||
1287 | request_resource(res, &crashk_res); | ||
1288 | #endif | ||
1226 | } | 1289 | } |
1227 | } | 1290 | } |
1228 | } | 1291 | } |
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index 68be7d0c7238..cec4bde67161 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/mc146818rtc.h> | 19 | #include <linux/mc146818rtc.h> |
20 | #include <linux/cache.h> | 20 | #include <linux/cache.h> |
21 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
22 | #include <linux/cpu.h> | ||
22 | #include <linux/module.h> | 23 | #include <linux/module.h> |
23 | 24 | ||
24 | #include <asm/mtrr.h> | 25 | #include <asm/mtrr.h> |
@@ -164,7 +165,7 @@ void send_IPI_mask_bitmask(cpumask_t cpumask, int vector) | |||
164 | unsigned long flags; | 165 | unsigned long flags; |
165 | 166 | ||
166 | local_irq_save(flags); | 167 | local_irq_save(flags); |
167 | 168 | WARN_ON(mask & ~cpus_addr(cpu_online_map)[0]); | |
168 | /* | 169 | /* |
169 | * Wait for idle. | 170 | * Wait for idle. |
170 | */ | 171 | */ |
@@ -346,21 +347,21 @@ out: | |||
346 | static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm, | 347 | static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm, |
347 | unsigned long va) | 348 | unsigned long va) |
348 | { | 349 | { |
349 | cpumask_t tmp; | ||
350 | /* | 350 | /* |
351 | * A couple of (to be removed) sanity checks: | 351 | * A couple of (to be removed) sanity checks: |
352 | * | 352 | * |
353 | * - we do not send IPIs to not-yet booted CPUs. | ||
354 | * - current CPU must not be in mask | 353 | * - current CPU must not be in mask |
355 | * - mask must exist :) | 354 | * - mask must exist :) |
356 | */ | 355 | */ |
357 | BUG_ON(cpus_empty(cpumask)); | 356 | BUG_ON(cpus_empty(cpumask)); |
358 | |||
359 | cpus_and(tmp, cpumask, cpu_online_map); | ||
360 | BUG_ON(!cpus_equal(cpumask, tmp)); | ||
361 | BUG_ON(cpu_isset(smp_processor_id(), cpumask)); | 357 | BUG_ON(cpu_isset(smp_processor_id(), cpumask)); |
362 | BUG_ON(!mm); | 358 | BUG_ON(!mm); |
363 | 359 | ||
360 | /* If a CPU which we ran on has gone down, OK. */ | ||
361 | cpus_and(cpumask, cpumask, cpu_online_map); | ||
362 | if (cpus_empty(cpumask)) | ||
363 | return; | ||
364 | |||
364 | /* | 365 | /* |
365 | * i'm not happy about this global shared spinlock in the | 366 | * i'm not happy about this global shared spinlock in the |
366 | * MM hot path, but we'll see how contended it is. | 367 | * MM hot path, but we'll see how contended it is. |
@@ -476,6 +477,7 @@ void flush_tlb_all(void) | |||
476 | */ | 477 | */ |
477 | void smp_send_reschedule(int cpu) | 478 | void smp_send_reschedule(int cpu) |
478 | { | 479 | { |
480 | WARN_ON(cpu_is_offline(cpu)); | ||
479 | send_IPI_mask(cpumask_of_cpu(cpu), RESCHEDULE_VECTOR); | 481 | send_IPI_mask(cpumask_of_cpu(cpu), RESCHEDULE_VECTOR); |
480 | } | 482 | } |
481 | 483 | ||
@@ -493,6 +495,16 @@ struct call_data_struct { | |||
493 | int wait; | 495 | int wait; |
494 | }; | 496 | }; |
495 | 497 | ||
498 | void lock_ipi_call_lock(void) | ||
499 | { | ||
500 | spin_lock_irq(&call_lock); | ||
501 | } | ||
502 | |||
503 | void unlock_ipi_call_lock(void) | ||
504 | { | ||
505 | spin_unlock_irq(&call_lock); | ||
506 | } | ||
507 | |||
496 | static struct call_data_struct * call_data; | 508 | static struct call_data_struct * call_data; |
497 | 509 | ||
498 | /* | 510 | /* |
@@ -516,10 +528,15 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, | |||
516 | */ | 528 | */ |
517 | { | 529 | { |
518 | struct call_data_struct data; | 530 | struct call_data_struct data; |
519 | int cpus = num_online_cpus()-1; | 531 | int cpus; |
520 | 532 | ||
521 | if (!cpus) | 533 | /* Holding any lock stops cpus from going down. */ |
534 | spin_lock(&call_lock); | ||
535 | cpus = num_online_cpus() - 1; | ||
536 | if (!cpus) { | ||
537 | spin_unlock(&call_lock); | ||
522 | return 0; | 538 | return 0; |
539 | } | ||
523 | 540 | ||
524 | /* Can deadlock when called with interrupts disabled */ | 541 | /* Can deadlock when called with interrupts disabled */ |
525 | WARN_ON(irqs_disabled()); | 542 | WARN_ON(irqs_disabled()); |
@@ -531,7 +548,6 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, | |||
531 | if (wait) | 548 | if (wait) |
532 | atomic_set(&data.finished, 0); | 549 | atomic_set(&data.finished, 0); |
533 | 550 | ||
534 | spin_lock(&call_lock); | ||
535 | call_data = &data; | 551 | call_data = &data; |
536 | mb(); | 552 | mb(); |
537 | 553 | ||
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index c20d96d5c15c..d66bf489a2e9 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c | |||
@@ -44,6 +44,9 @@ | |||
44 | #include <linux/smp_lock.h> | 44 | #include <linux/smp_lock.h> |
45 | #include <linux/irq.h> | 45 | #include <linux/irq.h> |
46 | #include <linux/bootmem.h> | 46 | #include <linux/bootmem.h> |
47 | #include <linux/notifier.h> | ||
48 | #include <linux/cpu.h> | ||
49 | #include <linux/percpu.h> | ||
47 | 50 | ||
48 | #include <linux/delay.h> | 51 | #include <linux/delay.h> |
49 | #include <linux/mc146818rtc.h> | 52 | #include <linux/mc146818rtc.h> |
@@ -56,18 +59,28 @@ | |||
56 | #include <smpboot_hooks.h> | 59 | #include <smpboot_hooks.h> |
57 | 60 | ||
58 | /* Set if we find a B stepping CPU */ | 61 | /* Set if we find a B stepping CPU */ |
59 | static int __initdata smp_b_stepping; | 62 | static int __devinitdata smp_b_stepping; |
60 | 63 | ||
61 | /* Number of siblings per CPU package */ | 64 | /* Number of siblings per CPU package */ |
62 | int smp_num_siblings = 1; | 65 | int smp_num_siblings = 1; |
63 | #ifdef CONFIG_X86_HT | 66 | #ifdef CONFIG_X86_HT |
64 | EXPORT_SYMBOL(smp_num_siblings); | 67 | EXPORT_SYMBOL(smp_num_siblings); |
65 | #endif | 68 | #endif |
66 | int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */ | 69 | |
70 | /* Package ID of each logical CPU */ | ||
71 | int phys_proc_id[NR_CPUS] = {[0 ... NR_CPUS-1] = BAD_APICID}; | ||
67 | EXPORT_SYMBOL(phys_proc_id); | 72 | EXPORT_SYMBOL(phys_proc_id); |
68 | int cpu_core_id[NR_CPUS]; /* Core ID of each logical CPU */ | 73 | |
74 | /* Core ID of each logical CPU */ | ||
75 | int cpu_core_id[NR_CPUS] = {[0 ... NR_CPUS-1] = BAD_APICID}; | ||
69 | EXPORT_SYMBOL(cpu_core_id); | 76 | EXPORT_SYMBOL(cpu_core_id); |
70 | 77 | ||
78 | cpumask_t cpu_sibling_map[NR_CPUS]; | ||
79 | EXPORT_SYMBOL(cpu_sibling_map); | ||
80 | |||
81 | cpumask_t cpu_core_map[NR_CPUS]; | ||
82 | EXPORT_SYMBOL(cpu_core_map); | ||
83 | |||
71 | /* bitmap of online cpus */ | 84 | /* bitmap of online cpus */ |
72 | cpumask_t cpu_online_map; | 85 | cpumask_t cpu_online_map; |
73 | EXPORT_SYMBOL(cpu_online_map); | 86 | EXPORT_SYMBOL(cpu_online_map); |
@@ -77,6 +90,12 @@ cpumask_t cpu_callout_map; | |||
77 | EXPORT_SYMBOL(cpu_callout_map); | 90 | EXPORT_SYMBOL(cpu_callout_map); |
78 | static cpumask_t smp_commenced_mask; | 91 | static cpumask_t smp_commenced_mask; |
79 | 92 | ||
93 | /* TSC's upper 32 bits can't be written in eariler CPU (before prescott), there | ||
94 | * is no way to resync one AP against BP. TBD: for prescott and above, we | ||
95 | * should use IA64's algorithm | ||
96 | */ | ||
97 | static int __devinitdata tsc_sync_disabled; | ||
98 | |||
80 | /* Per CPU bogomips and other parameters */ | 99 | /* Per CPU bogomips and other parameters */ |
81 | struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; | 100 | struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; |
82 | EXPORT_SYMBOL(cpu_data); | 101 | EXPORT_SYMBOL(cpu_data); |
@@ -96,13 +115,16 @@ static int trampoline_exec; | |||
96 | 115 | ||
97 | static void map_cpu_to_logical_apicid(void); | 116 | static void map_cpu_to_logical_apicid(void); |
98 | 117 | ||
118 | /* State of each CPU. */ | ||
119 | DEFINE_PER_CPU(int, cpu_state) = { 0 }; | ||
120 | |||
99 | /* | 121 | /* |
100 | * Currently trivial. Write the real->protected mode | 122 | * Currently trivial. Write the real->protected mode |
101 | * bootstrap into the page concerned. The caller | 123 | * bootstrap into the page concerned. The caller |
102 | * has made sure it's suitably aligned. | 124 | * has made sure it's suitably aligned. |
103 | */ | 125 | */ |
104 | 126 | ||
105 | static unsigned long __init setup_trampoline(void) | 127 | static unsigned long __devinit setup_trampoline(void) |
106 | { | 128 | { |
107 | memcpy(trampoline_base, trampoline_data, trampoline_end - trampoline_data); | 129 | memcpy(trampoline_base, trampoline_data, trampoline_end - trampoline_data); |
108 | return virt_to_phys(trampoline_base); | 130 | return virt_to_phys(trampoline_base); |
@@ -132,7 +154,7 @@ void __init smp_alloc_memory(void) | |||
132 | * a given CPU | 154 | * a given CPU |
133 | */ | 155 | */ |
134 | 156 | ||
135 | static void __init smp_store_cpu_info(int id) | 157 | static void __devinit smp_store_cpu_info(int id) |
136 | { | 158 | { |
137 | struct cpuinfo_x86 *c = cpu_data + id; | 159 | struct cpuinfo_x86 *c = cpu_data + id; |
138 | 160 | ||
@@ -326,7 +348,7 @@ extern void calibrate_delay(void); | |||
326 | 348 | ||
327 | static atomic_t init_deasserted; | 349 | static atomic_t init_deasserted; |
328 | 350 | ||
329 | static void __init smp_callin(void) | 351 | static void __devinit smp_callin(void) |
330 | { | 352 | { |
331 | int cpuid, phys_id; | 353 | int cpuid, phys_id; |
332 | unsigned long timeout; | 354 | unsigned long timeout; |
@@ -411,16 +433,48 @@ static void __init smp_callin(void) | |||
411 | /* | 433 | /* |
412 | * Synchronize the TSC with the BP | 434 | * Synchronize the TSC with the BP |
413 | */ | 435 | */ |
414 | if (cpu_has_tsc && cpu_khz) | 436 | if (cpu_has_tsc && cpu_khz && !tsc_sync_disabled) |
415 | synchronize_tsc_ap(); | 437 | synchronize_tsc_ap(); |
416 | } | 438 | } |
417 | 439 | ||
418 | static int cpucount; | 440 | static int cpucount; |
419 | 441 | ||
442 | static inline void | ||
443 | set_cpu_sibling_map(int cpu) | ||
444 | { | ||
445 | int i; | ||
446 | |||
447 | if (smp_num_siblings > 1) { | ||
448 | for (i = 0; i < NR_CPUS; i++) { | ||
449 | if (!cpu_isset(i, cpu_callout_map)) | ||
450 | continue; | ||
451 | if (cpu_core_id[cpu] == cpu_core_id[i]) { | ||
452 | cpu_set(i, cpu_sibling_map[cpu]); | ||
453 | cpu_set(cpu, cpu_sibling_map[i]); | ||
454 | } | ||
455 | } | ||
456 | } else { | ||
457 | cpu_set(cpu, cpu_sibling_map[cpu]); | ||
458 | } | ||
459 | |||
460 | if (current_cpu_data.x86_num_cores > 1) { | ||
461 | for (i = 0; i < NR_CPUS; i++) { | ||
462 | if (!cpu_isset(i, cpu_callout_map)) | ||
463 | continue; | ||
464 | if (phys_proc_id[cpu] == phys_proc_id[i]) { | ||
465 | cpu_set(i, cpu_core_map[cpu]); | ||
466 | cpu_set(cpu, cpu_core_map[i]); | ||
467 | } | ||
468 | } | ||
469 | } else { | ||
470 | cpu_core_map[cpu] = cpu_sibling_map[cpu]; | ||
471 | } | ||
472 | } | ||
473 | |||
420 | /* | 474 | /* |
421 | * Activate a secondary processor. | 475 | * Activate a secondary processor. |
422 | */ | 476 | */ |
423 | static void __init start_secondary(void *unused) | 477 | static void __devinit start_secondary(void *unused) |
424 | { | 478 | { |
425 | /* | 479 | /* |
426 | * Dont put anything before smp_callin(), SMP | 480 | * Dont put anything before smp_callin(), SMP |
@@ -443,7 +497,23 @@ static void __init start_secondary(void *unused) | |||
443 | * the local TLBs too. | 497 | * the local TLBs too. |
444 | */ | 498 | */ |
445 | local_flush_tlb(); | 499 | local_flush_tlb(); |
500 | |||
501 | /* This must be done before setting cpu_online_map */ | ||
502 | set_cpu_sibling_map(raw_smp_processor_id()); | ||
503 | wmb(); | ||
504 | |||
505 | /* | ||
506 | * We need to hold call_lock, so there is no inconsistency | ||
507 | * between the time smp_call_function() determines number of | ||
508 | * IPI receipients, and the time when the determination is made | ||
509 | * for which cpus receive the IPI. Holding this | ||
510 | * lock helps us to not include this cpu in a currently in progress | ||
511 | * smp_call_function(). | ||
512 | */ | ||
513 | lock_ipi_call_lock(); | ||
446 | cpu_set(smp_processor_id(), cpu_online_map); | 514 | cpu_set(smp_processor_id(), cpu_online_map); |
515 | unlock_ipi_call_lock(); | ||
516 | per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; | ||
447 | 517 | ||
448 | /* We can take interrupts now: we're officially "up". */ | 518 | /* We can take interrupts now: we're officially "up". */ |
449 | local_irq_enable(); | 519 | local_irq_enable(); |
@@ -458,7 +528,7 @@ static void __init start_secondary(void *unused) | |||
458 | * from the task structure | 528 | * from the task structure |
459 | * This function must not return. | 529 | * This function must not return. |
460 | */ | 530 | */ |
461 | void __init initialize_secondary(void) | 531 | void __devinit initialize_secondary(void) |
462 | { | 532 | { |
463 | /* | 533 | /* |
464 | * We don't actually need to load the full TSS, | 534 | * We don't actually need to load the full TSS, |
@@ -572,7 +642,7 @@ static inline void __inquire_remote_apic(int apicid) | |||
572 | * INIT, INIT, STARTUP sequence will reset the chip hard for us, and this | 642 | * INIT, INIT, STARTUP sequence will reset the chip hard for us, and this |
573 | * won't ... remember to clear down the APIC, etc later. | 643 | * won't ... remember to clear down the APIC, etc later. |
574 | */ | 644 | */ |
575 | static int __init | 645 | static int __devinit |
576 | wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip) | 646 | wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip) |
577 | { | 647 | { |
578 | unsigned long send_status = 0, accept_status = 0; | 648 | unsigned long send_status = 0, accept_status = 0; |
@@ -618,7 +688,7 @@ wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip) | |||
618 | #endif /* WAKE_SECONDARY_VIA_NMI */ | 688 | #endif /* WAKE_SECONDARY_VIA_NMI */ |
619 | 689 | ||
620 | #ifdef WAKE_SECONDARY_VIA_INIT | 690 | #ifdef WAKE_SECONDARY_VIA_INIT |
621 | static int __init | 691 | static int __devinit |
622 | wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) | 692 | wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) |
623 | { | 693 | { |
624 | unsigned long send_status = 0, accept_status = 0; | 694 | unsigned long send_status = 0, accept_status = 0; |
@@ -753,8 +823,43 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) | |||
753 | #endif /* WAKE_SECONDARY_VIA_INIT */ | 823 | #endif /* WAKE_SECONDARY_VIA_INIT */ |
754 | 824 | ||
755 | extern cpumask_t cpu_initialized; | 825 | extern cpumask_t cpu_initialized; |
826 | static inline int alloc_cpu_id(void) | ||
827 | { | ||
828 | cpumask_t tmp_map; | ||
829 | int cpu; | ||
830 | cpus_complement(tmp_map, cpu_present_map); | ||
831 | cpu = first_cpu(tmp_map); | ||
832 | if (cpu >= NR_CPUS) | ||
833 | return -ENODEV; | ||
834 | return cpu; | ||
835 | } | ||
836 | |||
837 | #ifdef CONFIG_HOTPLUG_CPU | ||
838 | static struct task_struct * __devinitdata cpu_idle_tasks[NR_CPUS]; | ||
839 | static inline struct task_struct * alloc_idle_task(int cpu) | ||
840 | { | ||
841 | struct task_struct *idle; | ||
842 | |||
843 | if ((idle = cpu_idle_tasks[cpu]) != NULL) { | ||
844 | /* initialize thread_struct. we really want to avoid destroy | ||
845 | * idle tread | ||
846 | */ | ||
847 | idle->thread.esp = (unsigned long)(((struct pt_regs *) | ||
848 | (THREAD_SIZE + (unsigned long) idle->thread_info)) - 1); | ||
849 | init_idle(idle, cpu); | ||
850 | return idle; | ||
851 | } | ||
852 | idle = fork_idle(cpu); | ||
853 | |||
854 | if (!IS_ERR(idle)) | ||
855 | cpu_idle_tasks[cpu] = idle; | ||
856 | return idle; | ||
857 | } | ||
858 | #else | ||
859 | #define alloc_idle_task(cpu) fork_idle(cpu) | ||
860 | #endif | ||
756 | 861 | ||
757 | static int __init do_boot_cpu(int apicid) | 862 | static int __devinit do_boot_cpu(int apicid, int cpu) |
758 | /* | 863 | /* |
759 | * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad | 864 | * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad |
760 | * (ie clustered apic addressing mode), this is a LOGICAL apic ID. | 865 | * (ie clustered apic addressing mode), this is a LOGICAL apic ID. |
@@ -763,16 +868,17 @@ static int __init do_boot_cpu(int apicid) | |||
763 | { | 868 | { |
764 | struct task_struct *idle; | 869 | struct task_struct *idle; |
765 | unsigned long boot_error; | 870 | unsigned long boot_error; |
766 | int timeout, cpu; | 871 | int timeout; |
767 | unsigned long start_eip; | 872 | unsigned long start_eip; |
768 | unsigned short nmi_high = 0, nmi_low = 0; | 873 | unsigned short nmi_high = 0, nmi_low = 0; |
769 | 874 | ||
770 | cpu = ++cpucount; | 875 | ++cpucount; |
876 | |||
771 | /* | 877 | /* |
772 | * We can't use kernel_thread since we must avoid to | 878 | * We can't use kernel_thread since we must avoid to |
773 | * reschedule the child. | 879 | * reschedule the child. |
774 | */ | 880 | */ |
775 | idle = fork_idle(cpu); | 881 | idle = alloc_idle_task(cpu); |
776 | if (IS_ERR(idle)) | 882 | if (IS_ERR(idle)) |
777 | panic("failed fork for CPU %d", cpu); | 883 | panic("failed fork for CPU %d", cpu); |
778 | idle->thread.eip = (unsigned long) start_secondary; | 884 | idle->thread.eip = (unsigned long) start_secondary; |
@@ -839,13 +945,16 @@ static int __init do_boot_cpu(int apicid) | |||
839 | inquire_remote_apic(apicid); | 945 | inquire_remote_apic(apicid); |
840 | } | 946 | } |
841 | } | 947 | } |
842 | x86_cpu_to_apicid[cpu] = apicid; | 948 | |
843 | if (boot_error) { | 949 | if (boot_error) { |
844 | /* Try to put things back the way they were before ... */ | 950 | /* Try to put things back the way they were before ... */ |
845 | unmap_cpu_to_logical_apicid(cpu); | 951 | unmap_cpu_to_logical_apicid(cpu); |
846 | cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */ | 952 | cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */ |
847 | cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */ | 953 | cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */ |
848 | cpucount--; | 954 | cpucount--; |
955 | } else { | ||
956 | x86_cpu_to_apicid[cpu] = apicid; | ||
957 | cpu_set(cpu, cpu_present_map); | ||
849 | } | 958 | } |
850 | 959 | ||
851 | /* mark "stuck" area as not stuck */ | 960 | /* mark "stuck" area as not stuck */ |
@@ -854,6 +963,75 @@ static int __init do_boot_cpu(int apicid) | |||
854 | return boot_error; | 963 | return boot_error; |
855 | } | 964 | } |
856 | 965 | ||
966 | #ifdef CONFIG_HOTPLUG_CPU | ||
967 | void cpu_exit_clear(void) | ||
968 | { | ||
969 | int cpu = raw_smp_processor_id(); | ||
970 | |||
971 | idle_task_exit(); | ||
972 | |||
973 | cpucount --; | ||
974 | cpu_uninit(); | ||
975 | irq_ctx_exit(cpu); | ||
976 | |||
977 | cpu_clear(cpu, cpu_callout_map); | ||
978 | cpu_clear(cpu, cpu_callin_map); | ||
979 | cpu_clear(cpu, cpu_present_map); | ||
980 | |||
981 | cpu_clear(cpu, smp_commenced_mask); | ||
982 | unmap_cpu_to_logical_apicid(cpu); | ||
983 | } | ||
984 | |||
985 | struct warm_boot_cpu_info { | ||
986 | struct completion *complete; | ||
987 | int apicid; | ||
988 | int cpu; | ||
989 | }; | ||
990 | |||
991 | static void __devinit do_warm_boot_cpu(void *p) | ||
992 | { | ||
993 | struct warm_boot_cpu_info *info = p; | ||
994 | do_boot_cpu(info->apicid, info->cpu); | ||
995 | complete(info->complete); | ||
996 | } | ||
997 | |||
998 | int __devinit smp_prepare_cpu(int cpu) | ||
999 | { | ||
1000 | DECLARE_COMPLETION(done); | ||
1001 | struct warm_boot_cpu_info info; | ||
1002 | struct work_struct task; | ||
1003 | int apicid, ret; | ||
1004 | |||
1005 | lock_cpu_hotplug(); | ||
1006 | apicid = x86_cpu_to_apicid[cpu]; | ||
1007 | if (apicid == BAD_APICID) { | ||
1008 | ret = -ENODEV; | ||
1009 | goto exit; | ||
1010 | } | ||
1011 | |||
1012 | info.complete = &done; | ||
1013 | info.apicid = apicid; | ||
1014 | info.cpu = cpu; | ||
1015 | INIT_WORK(&task, do_warm_boot_cpu, &info); | ||
1016 | |||
1017 | tsc_sync_disabled = 1; | ||
1018 | |||
1019 | /* init low mem mapping */ | ||
1020 | memcpy(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS, | ||
1021 | sizeof(swapper_pg_dir[0]) * KERNEL_PGD_PTRS); | ||
1022 | flush_tlb_all(); | ||
1023 | schedule_work(&task); | ||
1024 | wait_for_completion(&done); | ||
1025 | |||
1026 | tsc_sync_disabled = 0; | ||
1027 | zap_low_mappings(); | ||
1028 | ret = 0; | ||
1029 | exit: | ||
1030 | unlock_cpu_hotplug(); | ||
1031 | return ret; | ||
1032 | } | ||
1033 | #endif | ||
1034 | |||
857 | static void smp_tune_scheduling (void) | 1035 | static void smp_tune_scheduling (void) |
858 | { | 1036 | { |
859 | unsigned long cachesize; /* kB */ | 1037 | unsigned long cachesize; /* kB */ |
@@ -895,13 +1073,6 @@ void *xquad_portio; | |||
895 | EXPORT_SYMBOL(xquad_portio); | 1073 | EXPORT_SYMBOL(xquad_portio); |
896 | #endif | 1074 | #endif |
897 | 1075 | ||
898 | cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; | ||
899 | #ifdef CONFIG_X86_HT | ||
900 | EXPORT_SYMBOL(cpu_sibling_map); | ||
901 | #endif | ||
902 | cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; | ||
903 | EXPORT_SYMBOL(cpu_core_map); | ||
904 | |||
905 | static void __init smp_boot_cpus(unsigned int max_cpus) | 1076 | static void __init smp_boot_cpus(unsigned int max_cpus) |
906 | { | 1077 | { |
907 | int apicid, cpu, bit, kicked; | 1078 | int apicid, cpu, bit, kicked; |
@@ -1013,7 +1184,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) | |||
1013 | if (max_cpus <= cpucount+1) | 1184 | if (max_cpus <= cpucount+1) |
1014 | continue; | 1185 | continue; |
1015 | 1186 | ||
1016 | if (do_boot_cpu(apicid)) | 1187 | if (((cpu = alloc_cpu_id()) <= 0) || do_boot_cpu(apicid, cpu)) |
1017 | printk("CPU #%d not responding - cannot use it.\n", | 1188 | printk("CPU #%d not responding - cannot use it.\n", |
1018 | apicid); | 1189 | apicid); |
1019 | else | 1190 | else |
@@ -1065,44 +1236,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus) | |||
1065 | cpus_clear(cpu_core_map[cpu]); | 1236 | cpus_clear(cpu_core_map[cpu]); |
1066 | } | 1237 | } |
1067 | 1238 | ||
1068 | for (cpu = 0; cpu < NR_CPUS; cpu++) { | 1239 | cpu_set(0, cpu_sibling_map[0]); |
1069 | struct cpuinfo_x86 *c = cpu_data + cpu; | 1240 | cpu_set(0, cpu_core_map[0]); |
1070 | int siblings = 0; | ||
1071 | int i; | ||
1072 | if (!cpu_isset(cpu, cpu_callout_map)) | ||
1073 | continue; | ||
1074 | |||
1075 | if (smp_num_siblings > 1) { | ||
1076 | for (i = 0; i < NR_CPUS; i++) { | ||
1077 | if (!cpu_isset(i, cpu_callout_map)) | ||
1078 | continue; | ||
1079 | if (cpu_core_id[cpu] == cpu_core_id[i]) { | ||
1080 | siblings++; | ||
1081 | cpu_set(i, cpu_sibling_map[cpu]); | ||
1082 | } | ||
1083 | } | ||
1084 | } else { | ||
1085 | siblings++; | ||
1086 | cpu_set(cpu, cpu_sibling_map[cpu]); | ||
1087 | } | ||
1088 | |||
1089 | if (siblings != smp_num_siblings) { | ||
1090 | printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings); | ||
1091 | smp_num_siblings = siblings; | ||
1092 | } | ||
1093 | |||
1094 | if (c->x86_num_cores > 1) { | ||
1095 | for (i = 0; i < NR_CPUS; i++) { | ||
1096 | if (!cpu_isset(i, cpu_callout_map)) | ||
1097 | continue; | ||
1098 | if (phys_proc_id[cpu] == phys_proc_id[i]) { | ||
1099 | cpu_set(i, cpu_core_map[cpu]); | ||
1100 | } | ||
1101 | } | ||
1102 | } else { | ||
1103 | cpu_core_map[cpu] = cpu_sibling_map[cpu]; | ||
1104 | } | ||
1105 | } | ||
1106 | 1241 | ||
1107 | smpboot_setup_io_apic(); | 1242 | smpboot_setup_io_apic(); |
1108 | 1243 | ||
@@ -1119,6 +1254,9 @@ static void __init smp_boot_cpus(unsigned int max_cpus) | |||
1119 | who understands all this stuff should rewrite it properly. --RR 15/Jul/02 */ | 1254 | who understands all this stuff should rewrite it properly. --RR 15/Jul/02 */ |
1120 | void __init smp_prepare_cpus(unsigned int max_cpus) | 1255 | void __init smp_prepare_cpus(unsigned int max_cpus) |
1121 | { | 1256 | { |
1257 | smp_commenced_mask = cpumask_of_cpu(0); | ||
1258 | cpu_callin_map = cpumask_of_cpu(0); | ||
1259 | mb(); | ||
1122 | smp_boot_cpus(max_cpus); | 1260 | smp_boot_cpus(max_cpus); |
1123 | } | 1261 | } |
1124 | 1262 | ||
@@ -1126,23 +1264,98 @@ void __devinit smp_prepare_boot_cpu(void) | |||
1126 | { | 1264 | { |
1127 | cpu_set(smp_processor_id(), cpu_online_map); | 1265 | cpu_set(smp_processor_id(), cpu_online_map); |
1128 | cpu_set(smp_processor_id(), cpu_callout_map); | 1266 | cpu_set(smp_processor_id(), cpu_callout_map); |
1267 | cpu_set(smp_processor_id(), cpu_present_map); | ||
1268 | per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; | ||
1129 | } | 1269 | } |
1130 | 1270 | ||
1131 | int __devinit __cpu_up(unsigned int cpu) | 1271 | #ifdef CONFIG_HOTPLUG_CPU |
1272 | static void | ||
1273 | remove_siblinginfo(int cpu) | ||
1132 | { | 1274 | { |
1133 | /* This only works at boot for x86. See "rewrite" above. */ | 1275 | int sibling; |
1134 | if (cpu_isset(cpu, smp_commenced_mask)) { | 1276 | |
1135 | local_irq_enable(); | 1277 | for_each_cpu_mask(sibling, cpu_sibling_map[cpu]) |
1136 | return -ENOSYS; | 1278 | cpu_clear(cpu, cpu_sibling_map[sibling]); |
1279 | for_each_cpu_mask(sibling, cpu_core_map[cpu]) | ||
1280 | cpu_clear(cpu, cpu_core_map[sibling]); | ||
1281 | cpus_clear(cpu_sibling_map[cpu]); | ||
1282 | cpus_clear(cpu_core_map[cpu]); | ||
1283 | phys_proc_id[cpu] = BAD_APICID; | ||
1284 | cpu_core_id[cpu] = BAD_APICID; | ||
1285 | } | ||
1286 | |||
1287 | int __cpu_disable(void) | ||
1288 | { | ||
1289 | cpumask_t map = cpu_online_map; | ||
1290 | int cpu = smp_processor_id(); | ||
1291 | |||
1292 | /* | ||
1293 | * Perhaps use cpufreq to drop frequency, but that could go | ||
1294 | * into generic code. | ||
1295 | * | ||
1296 | * We won't take down the boot processor on i386 due to some | ||
1297 | * interrupts only being able to be serviced by the BSP. | ||
1298 | * Especially so if we're not using an IOAPIC -zwane | ||
1299 | */ | ||
1300 | if (cpu == 0) | ||
1301 | return -EBUSY; | ||
1302 | |||
1303 | /* We enable the timer again on the exit path of the death loop */ | ||
1304 | disable_APIC_timer(); | ||
1305 | /* Allow any queued timer interrupts to get serviced */ | ||
1306 | local_irq_enable(); | ||
1307 | mdelay(1); | ||
1308 | local_irq_disable(); | ||
1309 | |||
1310 | remove_siblinginfo(cpu); | ||
1311 | |||
1312 | cpu_clear(cpu, map); | ||
1313 | fixup_irqs(map); | ||
1314 | /* It's now safe to remove this processor from the online map */ | ||
1315 | cpu_clear(cpu, cpu_online_map); | ||
1316 | return 0; | ||
1317 | } | ||
1318 | |||
1319 | void __cpu_die(unsigned int cpu) | ||
1320 | { | ||
1321 | /* We don't do anything here: idle task is faking death itself. */ | ||
1322 | unsigned int i; | ||
1323 | |||
1324 | for (i = 0; i < 10; i++) { | ||
1325 | /* They ack this in play_dead by setting CPU_DEAD */ | ||
1326 | if (per_cpu(cpu_state, cpu) == CPU_DEAD) { | ||
1327 | printk ("CPU %d is now offline\n", cpu); | ||
1328 | return; | ||
1329 | } | ||
1330 | current->state = TASK_UNINTERRUPTIBLE; | ||
1331 | schedule_timeout(HZ/10); | ||
1137 | } | 1332 | } |
1333 | printk(KERN_ERR "CPU %u didn't die...\n", cpu); | ||
1334 | } | ||
1335 | #else /* ... !CONFIG_HOTPLUG_CPU */ | ||
1336 | int __cpu_disable(void) | ||
1337 | { | ||
1338 | return -ENOSYS; | ||
1339 | } | ||
1340 | |||
1341 | void __cpu_die(unsigned int cpu) | ||
1342 | { | ||
1343 | /* We said "no" in __cpu_disable */ | ||
1344 | BUG(); | ||
1345 | } | ||
1346 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
1138 | 1347 | ||
1348 | int __devinit __cpu_up(unsigned int cpu) | ||
1349 | { | ||
1139 | /* In case one didn't come up */ | 1350 | /* In case one didn't come up */ |
1140 | if (!cpu_isset(cpu, cpu_callin_map)) { | 1351 | if (!cpu_isset(cpu, cpu_callin_map)) { |
1352 | printk(KERN_DEBUG "skipping cpu%d, didn't come online\n", cpu); | ||
1141 | local_irq_enable(); | 1353 | local_irq_enable(); |
1142 | return -EIO; | 1354 | return -EIO; |
1143 | } | 1355 | } |
1144 | 1356 | ||
1145 | local_irq_enable(); | 1357 | local_irq_enable(); |
1358 | per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; | ||
1146 | /* Unleash the CPU! */ | 1359 | /* Unleash the CPU! */ |
1147 | cpu_set(cpu, smp_commenced_mask); | 1360 | cpu_set(cpu, smp_commenced_mask); |
1148 | while (!cpu_isset(cpu, cpu_online_map)) | 1361 | while (!cpu_isset(cpu, cpu_online_map)) |
@@ -1156,10 +1369,12 @@ void __init smp_cpus_done(unsigned int max_cpus) | |||
1156 | setup_ioapic_dest(); | 1369 | setup_ioapic_dest(); |
1157 | #endif | 1370 | #endif |
1158 | zap_low_mappings(); | 1371 | zap_low_mappings(); |
1372 | #ifndef CONFIG_HOTPLUG_CPU | ||
1159 | /* | 1373 | /* |
1160 | * Disable executability of the SMP trampoline: | 1374 | * Disable executability of the SMP trampoline: |
1161 | */ | 1375 | */ |
1162 | set_kernel_exec((unsigned long)trampoline_base, trampoline_exec); | 1376 | set_kernel_exec((unsigned long)trampoline_base, trampoline_exec); |
1377 | #endif | ||
1163 | } | 1378 | } |
1164 | 1379 | ||
1165 | void __init smp_intr_init(void) | 1380 | void __init smp_intr_init(void) |
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S index d408afaf6495..442a6e937b19 100644 --- a/arch/i386/kernel/syscall_table.S +++ b/arch/i386/kernel/syscall_table.S | |||
@@ -283,7 +283,7 @@ ENTRY(sys_call_table) | |||
283 | .long sys_mq_timedreceive /* 280 */ | 283 | .long sys_mq_timedreceive /* 280 */ |
284 | .long sys_mq_notify | 284 | .long sys_mq_notify |
285 | .long sys_mq_getsetattr | 285 | .long sys_mq_getsetattr |
286 | .long sys_ni_syscall /* reserved for kexec */ | 286 | .long sys_kexec_load |
287 | .long sys_waitid | 287 | .long sys_waitid |
288 | .long sys_ni_syscall /* 285 */ /* available */ | 288 | .long sys_ni_syscall /* 285 */ /* available */ |
289 | .long sys_add_key | 289 | .long sys_add_key |
diff --git a/arch/i386/kernel/sysenter.c b/arch/i386/kernel/sysenter.c index 960d8bd137d0..0bada1870bdf 100644 --- a/arch/i386/kernel/sysenter.c +++ b/arch/i386/kernel/sysenter.c | |||
@@ -21,11 +21,16 @@ | |||
21 | 21 | ||
22 | extern asmlinkage void sysenter_entry(void); | 22 | extern asmlinkage void sysenter_entry(void); |
23 | 23 | ||
24 | void enable_sep_cpu(void *info) | 24 | void enable_sep_cpu(void) |
25 | { | 25 | { |
26 | int cpu = get_cpu(); | 26 | int cpu = get_cpu(); |
27 | struct tss_struct *tss = &per_cpu(init_tss, cpu); | 27 | struct tss_struct *tss = &per_cpu(init_tss, cpu); |
28 | 28 | ||
29 | if (!boot_cpu_has(X86_FEATURE_SEP)) { | ||
30 | put_cpu(); | ||
31 | return; | ||
32 | } | ||
33 | |||
29 | tss->ss1 = __KERNEL_CS; | 34 | tss->ss1 = __KERNEL_CS; |
30 | tss->esp1 = sizeof(struct tss_struct) + (unsigned long) tss; | 35 | tss->esp1 = sizeof(struct tss_struct) + (unsigned long) tss; |
31 | wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0); | 36 | wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0); |
@@ -41,7 +46,7 @@ void enable_sep_cpu(void *info) | |||
41 | extern const char vsyscall_int80_start, vsyscall_int80_end; | 46 | extern const char vsyscall_int80_start, vsyscall_int80_end; |
42 | extern const char vsyscall_sysenter_start, vsyscall_sysenter_end; | 47 | extern const char vsyscall_sysenter_start, vsyscall_sysenter_end; |
43 | 48 | ||
44 | static int __init sysenter_setup(void) | 49 | int __init sysenter_setup(void) |
45 | { | 50 | { |
46 | void *page = (void *)get_zeroed_page(GFP_ATOMIC); | 51 | void *page = (void *)get_zeroed_page(GFP_ATOMIC); |
47 | 52 | ||
@@ -58,8 +63,5 @@ static int __init sysenter_setup(void) | |||
58 | &vsyscall_sysenter_start, | 63 | &vsyscall_sysenter_start, |
59 | &vsyscall_sysenter_end - &vsyscall_sysenter_start); | 64 | &vsyscall_sysenter_end - &vsyscall_sysenter_start); |
60 | 65 | ||
61 | on_each_cpu(enable_sep_cpu, NULL, 1, 1); | ||
62 | return 0; | 66 | return 0; |
63 | } | 67 | } |
64 | |||
65 | __initcall(sysenter_setup); | ||
diff --git a/arch/i386/kernel/time_hpet.c b/arch/i386/kernel/time_hpet.c index 10a0cbb88e75..658c0629ba6a 100644 --- a/arch/i386/kernel/time_hpet.c +++ b/arch/i386/kernel/time_hpet.c | |||
@@ -50,7 +50,7 @@ static void hpet_writel(unsigned long d, unsigned long a) | |||
50 | * comparator value and continue. Next tick can be caught by checking | 50 | * comparator value and continue. Next tick can be caught by checking |
51 | * for a change in the comparator value. Used in apic.c. | 51 | * for a change in the comparator value. Used in apic.c. |
52 | */ | 52 | */ |
53 | static void __init wait_hpet_tick(void) | 53 | static void __devinit wait_hpet_tick(void) |
54 | { | 54 | { |
55 | unsigned int start_cmp_val, end_cmp_val; | 55 | unsigned int start_cmp_val, end_cmp_val; |
56 | 56 | ||
diff --git a/arch/i386/kernel/timers/common.c b/arch/i386/kernel/timers/common.c index 37353bd31803..8163fe0cf1f0 100644 --- a/arch/i386/kernel/timers/common.c +++ b/arch/i386/kernel/timers/common.c | |||
@@ -86,7 +86,7 @@ bad_ctc: | |||
86 | #define CALIBRATE_CNT_HPET (5 * hpet_tick) | 86 | #define CALIBRATE_CNT_HPET (5 * hpet_tick) |
87 | #define CALIBRATE_TIME_HPET (5 * KERNEL_TICK_USEC) | 87 | #define CALIBRATE_TIME_HPET (5 * KERNEL_TICK_USEC) |
88 | 88 | ||
89 | unsigned long __init calibrate_tsc_hpet(unsigned long *tsc_hpet_quotient_ptr) | 89 | unsigned long __devinit calibrate_tsc_hpet(unsigned long *tsc_hpet_quotient_ptr) |
90 | { | 90 | { |
91 | unsigned long tsc_startlow, tsc_starthigh; | 91 | unsigned long tsc_startlow, tsc_starthigh; |
92 | unsigned long tsc_endlow, tsc_endhigh; | 92 | unsigned long tsc_endlow, tsc_endhigh; |
diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c index 54c36b182021..f46e625bab67 100644 --- a/arch/i386/kernel/timers/timer_tsc.c +++ b/arch/i386/kernel/timers/timer_tsc.c | |||
@@ -33,7 +33,7 @@ static struct timer_opts timer_tsc; | |||
33 | 33 | ||
34 | static inline void cpufreq_delayed_get(void); | 34 | static inline void cpufreq_delayed_get(void); |
35 | 35 | ||
36 | int tsc_disable __initdata = 0; | 36 | int tsc_disable __devinitdata = 0; |
37 | 37 | ||
38 | extern spinlock_t i8253_lock; | 38 | extern spinlock_t i8253_lock; |
39 | 39 | ||
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index e4d4e2162c7a..a61f33d06ea3 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/ptrace.h> | 27 | #include <linux/ptrace.h> |
28 | #include <linux/utsname.h> | 28 | #include <linux/utsname.h> |
29 | #include <linux/kprobes.h> | 29 | #include <linux/kprobes.h> |
30 | #include <linux/kexec.h> | ||
30 | 31 | ||
31 | #ifdef CONFIG_EISA | 32 | #ifdef CONFIG_EISA |
32 | #include <linux/ioport.h> | 33 | #include <linux/ioport.h> |
@@ -234,22 +235,22 @@ void show_registers(struct pt_regs *regs) | |||
234 | * time of the fault.. | 235 | * time of the fault.. |
235 | */ | 236 | */ |
236 | if (in_kernel) { | 237 | if (in_kernel) { |
237 | u8 *eip; | 238 | u8 __user *eip; |
238 | 239 | ||
239 | printk("\nStack: "); | 240 | printk("\nStack: "); |
240 | show_stack(NULL, (unsigned long*)esp); | 241 | show_stack(NULL, (unsigned long*)esp); |
241 | 242 | ||
242 | printk("Code: "); | 243 | printk("Code: "); |
243 | 244 | ||
244 | eip = (u8 *)regs->eip - 43; | 245 | eip = (u8 __user *)regs->eip - 43; |
245 | for (i = 0; i < 64; i++, eip++) { | 246 | for (i = 0; i < 64; i++, eip++) { |
246 | unsigned char c; | 247 | unsigned char c; |
247 | 248 | ||
248 | if (eip < (u8 *)PAGE_OFFSET || __get_user(c, eip)) { | 249 | if (eip < (u8 __user *)PAGE_OFFSET || __get_user(c, eip)) { |
249 | printk(" Bad EIP value."); | 250 | printk(" Bad EIP value."); |
250 | break; | 251 | break; |
251 | } | 252 | } |
252 | if (eip == (u8 *)regs->eip) | 253 | if (eip == (u8 __user *)regs->eip) |
253 | printk("<%02x> ", c); | 254 | printk("<%02x> ", c); |
254 | else | 255 | else |
255 | printk("%02x ", c); | 256 | printk("%02x ", c); |
@@ -273,13 +274,13 @@ static void handle_BUG(struct pt_regs *regs) | |||
273 | 274 | ||
274 | if (eip < PAGE_OFFSET) | 275 | if (eip < PAGE_OFFSET) |
275 | goto no_bug; | 276 | goto no_bug; |
276 | if (__get_user(ud2, (unsigned short *)eip)) | 277 | if (__get_user(ud2, (unsigned short __user *)eip)) |
277 | goto no_bug; | 278 | goto no_bug; |
278 | if (ud2 != 0x0b0f) | 279 | if (ud2 != 0x0b0f) |
279 | goto no_bug; | 280 | goto no_bug; |
280 | if (__get_user(line, (unsigned short *)(eip + 2))) | 281 | if (__get_user(line, (unsigned short __user *)(eip + 2))) |
281 | goto bug; | 282 | goto bug; |
282 | if (__get_user(file, (char **)(eip + 4)) || | 283 | if (__get_user(file, (char * __user *)(eip + 4)) || |
283 | (unsigned long)file < PAGE_OFFSET || __get_user(c, file)) | 284 | (unsigned long)file < PAGE_OFFSET || __get_user(c, file)) |
284 | file = "<bad filename>"; | 285 | file = "<bad filename>"; |
285 | 286 | ||
@@ -294,6 +295,9 @@ bug: | |||
294 | printk("Kernel BUG\n"); | 295 | printk("Kernel BUG\n"); |
295 | } | 296 | } |
296 | 297 | ||
298 | /* This is gone through when something in the kernel | ||
299 | * has done something bad and is about to be terminated. | ||
300 | */ | ||
297 | void die(const char * str, struct pt_regs * regs, long err) | 301 | void die(const char * str, struct pt_regs * regs, long err) |
298 | { | 302 | { |
299 | static struct { | 303 | static struct { |
@@ -341,6 +345,10 @@ void die(const char * str, struct pt_regs * regs, long err) | |||
341 | bust_spinlocks(0); | 345 | bust_spinlocks(0); |
342 | die.lock_owner = -1; | 346 | die.lock_owner = -1; |
343 | spin_unlock_irq(&die.lock); | 347 | spin_unlock_irq(&die.lock); |
348 | |||
349 | if (kexec_should_crash(current)) | ||
350 | crash_kexec(regs); | ||
351 | |||
344 | if (in_interrupt()) | 352 | if (in_interrupt()) |
345 | panic("Fatal exception in interrupt"); | 353 | panic("Fatal exception in interrupt"); |
346 | 354 | ||
@@ -361,6 +369,10 @@ static inline void die_if_kernel(const char * str, struct pt_regs * regs, long e | |||
361 | static void do_trap(int trapnr, int signr, char *str, int vm86, | 369 | static void do_trap(int trapnr, int signr, char *str, int vm86, |
362 | struct pt_regs * regs, long error_code, siginfo_t *info) | 370 | struct pt_regs * regs, long error_code, siginfo_t *info) |
363 | { | 371 | { |
372 | struct task_struct *tsk = current; | ||
373 | tsk->thread.error_code = error_code; | ||
374 | tsk->thread.trap_no = trapnr; | ||
375 | |||
364 | if (regs->eflags & VM_MASK) { | 376 | if (regs->eflags & VM_MASK) { |
365 | if (vm86) | 377 | if (vm86) |
366 | goto vm86_trap; | 378 | goto vm86_trap; |
@@ -371,9 +383,6 @@ static void do_trap(int trapnr, int signr, char *str, int vm86, | |||
371 | goto kernel_trap; | 383 | goto kernel_trap; |
372 | 384 | ||
373 | trap_signal: { | 385 | trap_signal: { |
374 | struct task_struct *tsk = current; | ||
375 | tsk->thread.error_code = error_code; | ||
376 | tsk->thread.trap_no = trapnr; | ||
377 | if (info) | 386 | if (info) |
378 | force_sig_info(signr, info, tsk); | 387 | force_sig_info(signr, info, tsk); |
379 | else | 388 | else |
@@ -486,6 +495,9 @@ fastcall void do_general_protection(struct pt_regs * regs, long error_code) | |||
486 | } | 495 | } |
487 | put_cpu(); | 496 | put_cpu(); |
488 | 497 | ||
498 | current->thread.error_code = error_code; | ||
499 | current->thread.trap_no = 13; | ||
500 | |||
489 | if (regs->eflags & VM_MASK) | 501 | if (regs->eflags & VM_MASK) |
490 | goto gp_in_vm86; | 502 | goto gp_in_vm86; |
491 | 503 | ||
@@ -570,6 +582,15 @@ void die_nmi (struct pt_regs *regs, const char *msg) | |||
570 | console_silent(); | 582 | console_silent(); |
571 | spin_unlock(&nmi_print_lock); | 583 | spin_unlock(&nmi_print_lock); |
572 | bust_spinlocks(0); | 584 | bust_spinlocks(0); |
585 | |||
586 | /* If we are in kernel we are probably nested up pretty bad | ||
587 | * and might aswell get out now while we still can. | ||
588 | */ | ||
589 | if (!user_mode(regs)) { | ||
590 | current->thread.trap_no = 2; | ||
591 | crash_kexec(regs); | ||
592 | } | ||
593 | |||
573 | do_exit(SIGSEGV); | 594 | do_exit(SIGSEGV); |
574 | } | 595 | } |
575 | 596 | ||
@@ -625,6 +646,14 @@ fastcall void do_nmi(struct pt_regs * regs, long error_code) | |||
625 | nmi_enter(); | 646 | nmi_enter(); |
626 | 647 | ||
627 | cpu = smp_processor_id(); | 648 | cpu = smp_processor_id(); |
649 | |||
650 | #ifdef CONFIG_HOTPLUG_CPU | ||
651 | if (!cpu_online(cpu)) { | ||
652 | nmi_exit(); | ||
653 | return; | ||
654 | } | ||
655 | #endif | ||
656 | |||
628 | ++nmi_count(cpu); | 657 | ++nmi_count(cpu); |
629 | 658 | ||
630 | if (!nmi_callback(regs, cpu)) | 659 | if (!nmi_callback(regs, cpu)) |
@@ -872,9 +901,9 @@ fastcall void do_simd_coprocessor_error(struct pt_regs * regs, | |||
872 | error_code); | 901 | error_code); |
873 | return; | 902 | return; |
874 | } | 903 | } |
875 | die_if_kernel("cache flush denied", regs, error_code); | ||
876 | current->thread.trap_no = 19; | 904 | current->thread.trap_no = 19; |
877 | current->thread.error_code = error_code; | 905 | current->thread.error_code = error_code; |
906 | die_if_kernel("cache flush denied", regs, error_code); | ||
878 | force_sig(SIGSEGV, current); | 907 | force_sig(SIGSEGV, current); |
879 | } | 908 | } |
880 | } | 909 | } |
diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S index e0512cc8bea7..7e01a528a83a 100644 --- a/arch/i386/kernel/vmlinux.lds.S +++ b/arch/i386/kernel/vmlinux.lds.S | |||
@@ -2,20 +2,23 @@ | |||
2 | * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>; | 2 | * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>; |
3 | */ | 3 | */ |
4 | 4 | ||
5 | #define LOAD_OFFSET __PAGE_OFFSET | ||
6 | |||
5 | #include <asm-generic/vmlinux.lds.h> | 7 | #include <asm-generic/vmlinux.lds.h> |
6 | #include <asm/thread_info.h> | 8 | #include <asm/thread_info.h> |
7 | #include <asm/page.h> | 9 | #include <asm/page.h> |
8 | 10 | ||
9 | OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") | 11 | OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") |
10 | OUTPUT_ARCH(i386) | 12 | OUTPUT_ARCH(i386) |
11 | ENTRY(startup_32) | 13 | ENTRY(phys_startup_32) |
12 | jiffies = jiffies_64; | 14 | jiffies = jiffies_64; |
13 | SECTIONS | 15 | SECTIONS |
14 | { | 16 | { |
15 | . = __PAGE_OFFSET + 0x100000; | 17 | . = __KERNEL_START; |
18 | phys_startup_32 = startup_32 - LOAD_OFFSET; | ||
16 | /* read-only */ | 19 | /* read-only */ |
17 | _text = .; /* Text and read-only data */ | 20 | _text = .; /* Text and read-only data */ |
18 | .text : { | 21 | .text : AT(ADDR(.text) - LOAD_OFFSET) { |
19 | *(.text) | 22 | *(.text) |
20 | SCHED_TEXT | 23 | SCHED_TEXT |
21 | LOCK_TEXT | 24 | LOCK_TEXT |
@@ -27,49 +30,55 @@ SECTIONS | |||
27 | 30 | ||
28 | . = ALIGN(16); /* Exception table */ | 31 | . = ALIGN(16); /* Exception table */ |
29 | __start___ex_table = .; | 32 | __start___ex_table = .; |
30 | __ex_table : { *(__ex_table) } | 33 | __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) } |
31 | __stop___ex_table = .; | 34 | __stop___ex_table = .; |
32 | 35 | ||
33 | RODATA | 36 | RODATA |
34 | 37 | ||
35 | /* writeable */ | 38 | /* writeable */ |
36 | .data : { /* Data */ | 39 | .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */ |
37 | *(.data) | 40 | *(.data) |
38 | CONSTRUCTORS | 41 | CONSTRUCTORS |
39 | } | 42 | } |
40 | 43 | ||
41 | . = ALIGN(4096); | 44 | . = ALIGN(4096); |
42 | __nosave_begin = .; | 45 | __nosave_begin = .; |
43 | .data_nosave : { *(.data.nosave) } | 46 | .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) } |
44 | . = ALIGN(4096); | 47 | . = ALIGN(4096); |
45 | __nosave_end = .; | 48 | __nosave_end = .; |
46 | 49 | ||
47 | . = ALIGN(4096); | 50 | . = ALIGN(4096); |
48 | .data.page_aligned : { *(.data.idt) } | 51 | .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { |
52 | *(.data.idt) | ||
53 | } | ||
49 | 54 | ||
50 | . = ALIGN(32); | 55 | . = ALIGN(32); |
51 | .data.cacheline_aligned : { *(.data.cacheline_aligned) } | 56 | .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) { |
57 | *(.data.cacheline_aligned) | ||
58 | } | ||
52 | 59 | ||
53 | _edata = .; /* End of data section */ | 60 | _edata = .; /* End of data section */ |
54 | 61 | ||
55 | . = ALIGN(THREAD_SIZE); /* init_task */ | 62 | . = ALIGN(THREAD_SIZE); /* init_task */ |
56 | .data.init_task : { *(.data.init_task) } | 63 | .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) { |
64 | *(.data.init_task) | ||
65 | } | ||
57 | 66 | ||
58 | /* will be freed after init */ | 67 | /* will be freed after init */ |
59 | . = ALIGN(4096); /* Init code and data */ | 68 | . = ALIGN(4096); /* Init code and data */ |
60 | __init_begin = .; | 69 | __init_begin = .; |
61 | .init.text : { | 70 | .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { |
62 | _sinittext = .; | 71 | _sinittext = .; |
63 | *(.init.text) | 72 | *(.init.text) |
64 | _einittext = .; | 73 | _einittext = .; |
65 | } | 74 | } |
66 | .init.data : { *(.init.data) } | 75 | .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) } |
67 | . = ALIGN(16); | 76 | . = ALIGN(16); |
68 | __setup_start = .; | 77 | __setup_start = .; |
69 | .init.setup : { *(.init.setup) } | 78 | .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) } |
70 | __setup_end = .; | 79 | __setup_end = .; |
71 | __initcall_start = .; | 80 | __initcall_start = .; |
72 | .initcall.init : { | 81 | .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { |
73 | *(.initcall1.init) | 82 | *(.initcall1.init) |
74 | *(.initcall2.init) | 83 | *(.initcall2.init) |
75 | *(.initcall3.init) | 84 | *(.initcall3.init) |
@@ -80,33 +89,41 @@ SECTIONS | |||
80 | } | 89 | } |
81 | __initcall_end = .; | 90 | __initcall_end = .; |
82 | __con_initcall_start = .; | 91 | __con_initcall_start = .; |
83 | .con_initcall.init : { *(.con_initcall.init) } | 92 | .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) { |
93 | *(.con_initcall.init) | ||
94 | } | ||
84 | __con_initcall_end = .; | 95 | __con_initcall_end = .; |
85 | SECURITY_INIT | 96 | SECURITY_INIT |
86 | . = ALIGN(4); | 97 | . = ALIGN(4); |
87 | __alt_instructions = .; | 98 | __alt_instructions = .; |
88 | .altinstructions : { *(.altinstructions) } | 99 | .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) { |
100 | *(.altinstructions) | ||
101 | } | ||
89 | __alt_instructions_end = .; | 102 | __alt_instructions_end = .; |
90 | .altinstr_replacement : { *(.altinstr_replacement) } | 103 | .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) { |
104 | *(.altinstr_replacement) | ||
105 | } | ||
91 | /* .exit.text is discard at runtime, not link time, to deal with references | 106 | /* .exit.text is discard at runtime, not link time, to deal with references |
92 | from .altinstructions and .eh_frame */ | 107 | from .altinstructions and .eh_frame */ |
93 | .exit.text : { *(.exit.text) } | 108 | .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) } |
94 | .exit.data : { *(.exit.data) } | 109 | .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) } |
95 | . = ALIGN(4096); | 110 | . = ALIGN(4096); |
96 | __initramfs_start = .; | 111 | __initramfs_start = .; |
97 | .init.ramfs : { *(.init.ramfs) } | 112 | .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) } |
98 | __initramfs_end = .; | 113 | __initramfs_end = .; |
99 | . = ALIGN(32); | 114 | . = ALIGN(32); |
100 | __per_cpu_start = .; | 115 | __per_cpu_start = .; |
101 | .data.percpu : { *(.data.percpu) } | 116 | .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) } |
102 | __per_cpu_end = .; | 117 | __per_cpu_end = .; |
103 | . = ALIGN(4096); | 118 | . = ALIGN(4096); |
104 | __init_end = .; | 119 | __init_end = .; |
105 | /* freed after init ends here */ | 120 | /* freed after init ends here */ |
106 | 121 | ||
107 | __bss_start = .; /* BSS */ | 122 | __bss_start = .; /* BSS */ |
108 | .bss : { | 123 | .bss.page_aligned : AT(ADDR(.bss.page_aligned) - LOAD_OFFSET) { |
109 | *(.bss.page_aligned) | 124 | *(.bss.page_aligned) |
125 | } | ||
126 | .bss : AT(ADDR(.bss) - LOAD_OFFSET) { | ||
110 | *(.bss) | 127 | *(.bss) |
111 | } | 128 | } |
112 | . = ALIGN(4); | 129 | . = ALIGN(4); |
diff --git a/arch/i386/mach-default/setup.c b/arch/i386/mach-default/setup.c index 0aa08eaa8932..e5a1a83d09ef 100644 --- a/arch/i386/mach-default/setup.c +++ b/arch/i386/mach-default/setup.c | |||
@@ -10,6 +10,14 @@ | |||
10 | #include <asm/acpi.h> | 10 | #include <asm/acpi.h> |
11 | #include <asm/arch_hooks.h> | 11 | #include <asm/arch_hooks.h> |
12 | 12 | ||
13 | #ifdef CONFIG_HOTPLUG_CPU | ||
14 | #define DEFAULT_SEND_IPI (1) | ||
15 | #else | ||
16 | #define DEFAULT_SEND_IPI (0) | ||
17 | #endif | ||
18 | |||
19 | int no_broadcast=DEFAULT_SEND_IPI; | ||
20 | |||
13 | /** | 21 | /** |
14 | * pre_intr_init_hook - initialisation prior to setting up interrupt vectors | 22 | * pre_intr_init_hook - initialisation prior to setting up interrupt vectors |
15 | * | 23 | * |
@@ -104,3 +112,22 @@ void __init mca_nmi_hook(void) | |||
104 | printk("NMI generated from unknown source!\n"); | 112 | printk("NMI generated from unknown source!\n"); |
105 | } | 113 | } |
106 | #endif | 114 | #endif |
115 | |||
116 | static __init int no_ipi_broadcast(char *str) | ||
117 | { | ||
118 | get_option(&str, &no_broadcast); | ||
119 | printk ("Using %s mode\n", no_broadcast ? "No IPI Broadcast" : | ||
120 | "IPI Broadcast"); | ||
121 | return 1; | ||
122 | } | ||
123 | |||
124 | __setup("no_ipi_broadcast", no_ipi_broadcast); | ||
125 | |||
126 | static int __init print_ipi_mode(void) | ||
127 | { | ||
128 | printk ("Using IPI %s mode\n", no_broadcast ? "No-Shortcut" : | ||
129 | "Shortcut"); | ||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | late_initcall(print_ipi_mode); | ||
diff --git a/arch/i386/mach-default/topology.c b/arch/i386/mach-default/topology.c index 5b3e8817dae8..23395fff35d1 100644 --- a/arch/i386/mach-default/topology.c +++ b/arch/i386/mach-default/topology.c | |||
@@ -73,12 +73,11 @@ static int __init topology_init(void) | |||
73 | { | 73 | { |
74 | int i; | 74 | int i; |
75 | 75 | ||
76 | for (i = 0; i < MAX_NUMNODES; i++) { | 76 | for_each_online_node(i) |
77 | if (node_online(i)) | 77 | arch_register_node(i); |
78 | arch_register_node(i); | 78 | |
79 | } | 79 | for_each_cpu(i) |
80 | for (i = 0; i < NR_CPUS; i++) | 80 | arch_register_cpu(i); |
81 | if (cpu_possible(i)) arch_register_cpu(i); | ||
82 | return 0; | 81 | return 0; |
83 | } | 82 | } |
84 | 83 | ||
@@ -88,8 +87,8 @@ static int __init topology_init(void) | |||
88 | { | 87 | { |
89 | int i; | 88 | int i; |
90 | 89 | ||
91 | for (i = 0; i < NR_CPUS; i++) | 90 | for_each_cpu(i) |
92 | if (cpu_possible(i)) arch_register_cpu(i); | 91 | arch_register_cpu(i); |
93 | return 0; | 92 | return 0; |
94 | } | 93 | } |
95 | 94 | ||
diff --git a/arch/i386/mach-visws/mpparse.c b/arch/i386/mach-visws/mpparse.c index 5a22082147f4..5f3d7e6de37b 100644 --- a/arch/i386/mach-visws/mpparse.c +++ b/arch/i386/mach-visws/mpparse.c | |||
@@ -23,7 +23,6 @@ unsigned long mp_lapic_addr; | |||
23 | 23 | ||
24 | /* Processor that is doing the boot up */ | 24 | /* Processor that is doing the boot up */ |
25 | unsigned int boot_cpu_physical_apicid = -1U; | 25 | unsigned int boot_cpu_physical_apicid = -1U; |
26 | unsigned int boot_cpu_logical_apicid = -1U; | ||
27 | 26 | ||
28 | /* Bitmask of physically existing CPUs */ | 27 | /* Bitmask of physically existing CPUs */ |
29 | physid_mask_t phys_cpu_present_map; | 28 | physid_mask_t phys_cpu_present_map; |
@@ -52,10 +51,8 @@ static void __init MP_processor_info (struct mpc_config_processor *m) | |||
52 | (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, | 51 | (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, |
53 | m->mpc_apicver); | 52 | m->mpc_apicver); |
54 | 53 | ||
55 | if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) { | 54 | if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) |
56 | boot_cpu_physical_apicid = m->mpc_apicid; | 55 | boot_cpu_physical_apicid = m->mpc_apicid; |
57 | boot_cpu_logical_apicid = logical_apicid; | ||
58 | } | ||
59 | 56 | ||
60 | ver = m->mpc_apicver; | 57 | ver = m->mpc_apicver; |
61 | if ((ver >= 0x14 && m->mpc_apicid >= 0xff) || m->mpc_apicid >= 0xf) { | 58 | if ((ver >= 0x14 && m->mpc_apicid >= 0xff) || m->mpc_apicid >= 0xf) { |
diff --git a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c index f429c871e845..b358f0702a44 100644 --- a/arch/i386/mm/discontig.c +++ b/arch/i386/mm/discontig.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #include <linux/initrd.h> | 30 | #include <linux/initrd.h> |
31 | #include <linux/nodemask.h> | 31 | #include <linux/nodemask.h> |
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <linux/kexec.h> | ||
34 | |||
33 | #include <asm/e820.h> | 35 | #include <asm/e820.h> |
34 | #include <asm/setup.h> | 36 | #include <asm/setup.h> |
35 | #include <asm/mmzone.h> | 37 | #include <asm/mmzone.h> |
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c index a509237c4815..8e90339d6eaa 100644 --- a/arch/i386/mm/fault.c +++ b/arch/i386/mm/fault.c | |||
@@ -146,7 +146,7 @@ static int __is_prefetch(struct pt_regs *regs, unsigned long addr) | |||
146 | 146 | ||
147 | if (instr > limit) | 147 | if (instr > limit) |
148 | break; | 148 | break; |
149 | if (__get_user(opcode, (unsigned char *) instr)) | 149 | if (__get_user(opcode, (unsigned char __user *) instr)) |
150 | break; | 150 | break; |
151 | 151 | ||
152 | instr_hi = opcode & 0xf0; | 152 | instr_hi = opcode & 0xf0; |
@@ -173,7 +173,7 @@ static int __is_prefetch(struct pt_regs *regs, unsigned long addr) | |||
173 | scan_more = 0; | 173 | scan_more = 0; |
174 | if (instr > limit) | 174 | if (instr > limit) |
175 | break; | 175 | break; |
176 | if (__get_user(opcode, (unsigned char *) instr)) | 176 | if (__get_user(opcode, (unsigned char __user *) instr)) |
177 | break; | 177 | break; |
178 | prefetch = (instr_lo == 0xF) && | 178 | prefetch = (instr_lo == 0xF) && |
179 | (opcode == 0x0D || opcode == 0x18); | 179 | (opcode == 0x0D || opcode == 0x18); |
@@ -463,6 +463,9 @@ no_context: | |||
463 | printk(KERN_ALERT "*pte = %08lx\n", page); | 463 | printk(KERN_ALERT "*pte = %08lx\n", page); |
464 | } | 464 | } |
465 | #endif | 465 | #endif |
466 | tsk->thread.cr2 = address; | ||
467 | tsk->thread.trap_no = 14; | ||
468 | tsk->thread.error_code = error_code; | ||
466 | die("Oops", regs, error_code); | 469 | die("Oops", regs, error_code); |
467 | bust_spinlocks(0); | 470 | bust_spinlocks(0); |
468 | do_exit(SIGKILL); | 471 | do_exit(SIGKILL); |
diff --git a/arch/i386/mm/highmem.c b/arch/i386/mm/highmem.c index 4b7aaf99d7ea..b6eb4dcb8777 100644 --- a/arch/i386/mm/highmem.c +++ b/arch/i386/mm/highmem.c | |||
@@ -75,6 +75,24 @@ void kunmap_atomic(void *kvaddr, enum km_type type) | |||
75 | preempt_check_resched(); | 75 | preempt_check_resched(); |
76 | } | 76 | } |
77 | 77 | ||
78 | /* This is the same as kmap_atomic() but can map memory that doesn't | ||
79 | * have a struct page associated with it. | ||
80 | */ | ||
81 | void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) | ||
82 | { | ||
83 | enum fixed_addresses idx; | ||
84 | unsigned long vaddr; | ||
85 | |||
86 | inc_preempt_count(); | ||
87 | |||
88 | idx = type + KM_TYPE_NR*smp_processor_id(); | ||
89 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | ||
90 | set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot)); | ||
91 | __flush_tlb_one(vaddr); | ||
92 | |||
93 | return (void*) vaddr; | ||
94 | } | ||
95 | |||
78 | struct page *kmap_atomic_to_page(void *ptr) | 96 | struct page *kmap_atomic_to_page(void *ptr) |
79 | { | 97 | { |
80 | unsigned long idx, vaddr = (unsigned long)ptr; | 98 | unsigned long idx, vaddr = (unsigned long)ptr; |
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 3672e2ef51ae..12216b52e28b 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c | |||
@@ -352,7 +352,7 @@ static void __init pagetable_init (void) | |||
352 | #endif | 352 | #endif |
353 | } | 353 | } |
354 | 354 | ||
355 | #if defined(CONFIG_PM_DISK) || defined(CONFIG_SOFTWARE_SUSPEND) | 355 | #ifdef CONFIG_SOFTWARE_SUSPEND |
356 | /* | 356 | /* |
357 | * Swap suspend & friends need this for resume because things like the intel-agp | 357 | * Swap suspend & friends need this for resume because things like the intel-agp |
358 | * driver might have split up a kernel 4MB mapping. | 358 | * driver might have split up a kernel 4MB mapping. |
diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c index d393eefc7052..6b25afc933b6 100644 --- a/arch/i386/mm/ioremap.c +++ b/arch/i386/mm/ioremap.c | |||
@@ -243,7 +243,7 @@ void iounmap(volatile void __iomem *addr) | |||
243 | write_lock(&vmlist_lock); | 243 | write_lock(&vmlist_lock); |
244 | p = __remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr)); | 244 | p = __remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr)); |
245 | if (!p) { | 245 | if (!p) { |
246 | printk("iounmap: bad address %p\n", addr); | 246 | printk(KERN_WARNING "iounmap: bad address %p\n", addr); |
247 | goto out_unlock; | 247 | goto out_unlock; |
248 | } | 248 | } |
249 | 249 | ||
diff --git a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c index 270c59f099a4..bd2f7afc7a2a 100644 --- a/arch/i386/mm/pgtable.c +++ b/arch/i386/mm/pgtable.c | |||
@@ -32,9 +32,9 @@ void show_mem(void) | |||
32 | unsigned long i; | 32 | unsigned long i; |
33 | struct page_state ps; | 33 | struct page_state ps; |
34 | 34 | ||
35 | printk("Mem-info:\n"); | 35 | printk(KERN_INFO "Mem-info:\n"); |
36 | show_free_areas(); | 36 | show_free_areas(); |
37 | printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); | 37 | printk(KERN_INFO "Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); |
38 | for_each_pgdat(pgdat) { | 38 | for_each_pgdat(pgdat) { |
39 | for (i = 0; i < pgdat->node_spanned_pages; ++i) { | 39 | for (i = 0; i < pgdat->node_spanned_pages; ++i) { |
40 | page = pgdat_page_nr(pgdat, i); | 40 | page = pgdat_page_nr(pgdat, i); |
@@ -49,18 +49,18 @@ void show_mem(void) | |||
49 | shared += page_count(page) - 1; | 49 | shared += page_count(page) - 1; |
50 | } | 50 | } |
51 | } | 51 | } |
52 | printk("%d pages of RAM\n", total); | 52 | printk(KERN_INFO "%d pages of RAM\n", total); |
53 | printk("%d pages of HIGHMEM\n",highmem); | 53 | printk(KERN_INFO "%d pages of HIGHMEM\n", highmem); |
54 | printk("%d reserved pages\n",reserved); | 54 | printk(KERN_INFO "%d reserved pages\n", reserved); |
55 | printk("%d pages shared\n",shared); | 55 | printk(KERN_INFO "%d pages shared\n", shared); |
56 | printk("%d pages swap cached\n",cached); | 56 | printk(KERN_INFO "%d pages swap cached\n", cached); |
57 | 57 | ||
58 | get_page_state(&ps); | 58 | get_page_state(&ps); |
59 | printk("%lu pages dirty\n", ps.nr_dirty); | 59 | printk(KERN_INFO "%lu pages dirty\n", ps.nr_dirty); |
60 | printk("%lu pages writeback\n", ps.nr_writeback); | 60 | printk(KERN_INFO "%lu pages writeback\n", ps.nr_writeback); |
61 | printk("%lu pages mapped\n", ps.nr_mapped); | 61 | printk(KERN_INFO "%lu pages mapped\n", ps.nr_mapped); |
62 | printk("%lu pages slab\n", ps.nr_slab); | 62 | printk(KERN_INFO "%lu pages slab\n", ps.nr_slab); |
63 | printk("%lu pages pagetables\n", ps.nr_page_table_pages); | 63 | printk(KERN_INFO "%lu pages pagetables\n", ps.nr_page_table_pages); |
64 | } | 64 | } |
65 | 65 | ||
66 | /* | 66 | /* |
@@ -113,16 +113,16 @@ void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags) | |||
113 | pmd_t *pmd; | 113 | pmd_t *pmd; |
114 | 114 | ||
115 | if (vaddr & (PMD_SIZE-1)) { /* vaddr is misaligned */ | 115 | if (vaddr & (PMD_SIZE-1)) { /* vaddr is misaligned */ |
116 | printk ("set_pmd_pfn: vaddr misaligned\n"); | 116 | printk(KERN_WARNING "set_pmd_pfn: vaddr misaligned\n"); |
117 | return; /* BUG(); */ | 117 | return; /* BUG(); */ |
118 | } | 118 | } |
119 | if (pfn & (PTRS_PER_PTE-1)) { /* pfn is misaligned */ | 119 | if (pfn & (PTRS_PER_PTE-1)) { /* pfn is misaligned */ |
120 | printk ("set_pmd_pfn: pfn misaligned\n"); | 120 | printk(KERN_WARNING "set_pmd_pfn: pfn misaligned\n"); |
121 | return; /* BUG(); */ | 121 | return; /* BUG(); */ |
122 | } | 122 | } |
123 | pgd = swapper_pg_dir + pgd_index(vaddr); | 123 | pgd = swapper_pg_dir + pgd_index(vaddr); |
124 | if (pgd_none(*pgd)) { | 124 | if (pgd_none(*pgd)) { |
125 | printk ("set_pmd_pfn: pgd_none\n"); | 125 | printk(KERN_WARNING "set_pmd_pfn: pgd_none\n"); |
126 | return; /* BUG(); */ | 126 | return; /* BUG(); */ |
127 | } | 127 | } |
128 | pud = pud_offset(pgd, vaddr); | 128 | pud = pud_offset(pgd, vaddr); |
diff --git a/arch/i386/power/cpu.c b/arch/i386/power/cpu.c index 6f521cf19a13..0e6b45b61251 100644 --- a/arch/i386/power/cpu.c +++ b/arch/i386/power/cpu.c | |||
@@ -22,9 +22,11 @@ | |||
22 | #include <linux/device.h> | 22 | #include <linux/device.h> |
23 | #include <linux/suspend.h> | 23 | #include <linux/suspend.h> |
24 | #include <linux/acpi.h> | 24 | #include <linux/acpi.h> |
25 | |||
25 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
26 | #include <asm/acpi.h> | 27 | #include <asm/acpi.h> |
27 | #include <asm/tlbflush.h> | 28 | #include <asm/tlbflush.h> |
29 | #include <asm/processor.h> | ||
28 | 30 | ||
29 | static struct saved_context saved_context; | 31 | static struct saved_context saved_context; |
30 | 32 | ||
@@ -33,8 +35,6 @@ unsigned long saved_context_esp, saved_context_ebp; | |||
33 | unsigned long saved_context_esi, saved_context_edi; | 35 | unsigned long saved_context_esi, saved_context_edi; |
34 | unsigned long saved_context_eflags; | 36 | unsigned long saved_context_eflags; |
35 | 37 | ||
36 | extern void enable_sep_cpu(void *); | ||
37 | |||
38 | void __save_processor_state(struct saved_context *ctxt) | 38 | void __save_processor_state(struct saved_context *ctxt) |
39 | { | 39 | { |
40 | kernel_fpu_begin(); | 40 | kernel_fpu_begin(); |
@@ -44,7 +44,6 @@ void __save_processor_state(struct saved_context *ctxt) | |||
44 | */ | 44 | */ |
45 | asm volatile ("sgdt %0" : "=m" (ctxt->gdt_limit)); | 45 | asm volatile ("sgdt %0" : "=m" (ctxt->gdt_limit)); |
46 | asm volatile ("sidt %0" : "=m" (ctxt->idt_limit)); | 46 | asm volatile ("sidt %0" : "=m" (ctxt->idt_limit)); |
47 | asm volatile ("sldt %0" : "=m" (ctxt->ldt)); | ||
48 | asm volatile ("str %0" : "=m" (ctxt->tr)); | 47 | asm volatile ("str %0" : "=m" (ctxt->tr)); |
49 | 48 | ||
50 | /* | 49 | /* |
@@ -107,7 +106,6 @@ static void fix_processor_context(void) | |||
107 | 106 | ||
108 | void __restore_processor_state(struct saved_context *ctxt) | 107 | void __restore_processor_state(struct saved_context *ctxt) |
109 | { | 108 | { |
110 | |||
111 | /* | 109 | /* |
112 | * control registers | 110 | * control registers |
113 | */ | 111 | */ |
@@ -117,6 +115,13 @@ void __restore_processor_state(struct saved_context *ctxt) | |||
117 | asm volatile ("movl %0, %%cr0" :: "r" (ctxt->cr0)); | 115 | asm volatile ("movl %0, %%cr0" :: "r" (ctxt->cr0)); |
118 | 116 | ||
119 | /* | 117 | /* |
118 | * now restore the descriptor tables to their proper values | ||
119 | * ltr is done i fix_processor_context(). | ||
120 | */ | ||
121 | asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit)); | ||
122 | asm volatile ("lidt %0" :: "m" (ctxt->idt_limit)); | ||
123 | |||
124 | /* | ||
120 | * segment registers | 125 | * segment registers |
121 | */ | 126 | */ |
122 | asm volatile ("movw %0, %%es" :: "r" (ctxt->es)); | 127 | asm volatile ("movw %0, %%es" :: "r" (ctxt->es)); |
@@ -125,18 +130,10 @@ void __restore_processor_state(struct saved_context *ctxt) | |||
125 | asm volatile ("movw %0, %%ss" :: "r" (ctxt->ss)); | 130 | asm volatile ("movw %0, %%ss" :: "r" (ctxt->ss)); |
126 | 131 | ||
127 | /* | 132 | /* |
128 | * now restore the descriptor tables to their proper values | ||
129 | * ltr is done i fix_processor_context(). | ||
130 | */ | ||
131 | asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit)); | ||
132 | asm volatile ("lidt %0" :: "m" (ctxt->idt_limit)); | ||
133 | asm volatile ("lldt %0" :: "m" (ctxt->ldt)); | ||
134 | |||
135 | /* | ||
136 | * sysenter MSRs | 133 | * sysenter MSRs |
137 | */ | 134 | */ |
138 | if (boot_cpu_has(X86_FEATURE_SEP)) | 135 | if (boot_cpu_has(X86_FEATURE_SEP)) |
139 | enable_sep_cpu(NULL); | 136 | enable_sep_cpu(); |
140 | 137 | ||
141 | fix_processor_context(); | 138 | fix_processor_context(); |
142 | do_fpu_end(); | 139 | do_fpu_end(); |
diff --git a/arch/ia64/kernel/domain.c b/arch/ia64/kernel/domain.c index fe532c970438..d65e87b6394f 100644 --- a/arch/ia64/kernel/domain.c +++ b/arch/ia64/kernel/domain.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/topology.h> | 14 | #include <linux/topology.h> |
15 | #include <linux/nodemask.h> | 15 | #include <linux/nodemask.h> |
16 | 16 | ||
17 | #define SD_NODES_PER_DOMAIN 6 | 17 | #define SD_NODES_PER_DOMAIN 16 |
18 | 18 | ||
19 | #ifdef CONFIG_NUMA | 19 | #ifdef CONFIG_NUMA |
20 | /** | 20 | /** |
@@ -27,7 +27,7 @@ | |||
27 | * | 27 | * |
28 | * Should use nodemask_t. | 28 | * Should use nodemask_t. |
29 | */ | 29 | */ |
30 | static int __devinit find_next_best_node(int node, unsigned long *used_nodes) | 30 | static int find_next_best_node(int node, unsigned long *used_nodes) |
31 | { | 31 | { |
32 | int i, n, val, min_val, best_node = 0; | 32 | int i, n, val, min_val, best_node = 0; |
33 | 33 | ||
@@ -66,7 +66,7 @@ static int __devinit find_next_best_node(int node, unsigned long *used_nodes) | |||
66 | * should be one that prevents unnecessary balancing, but also spreads tasks | 66 | * should be one that prevents unnecessary balancing, but also spreads tasks |
67 | * out optimally. | 67 | * out optimally. |
68 | */ | 68 | */ |
69 | static cpumask_t __devinit sched_domain_node_span(int node) | 69 | static cpumask_t sched_domain_node_span(int node) |
70 | { | 70 | { |
71 | int i; | 71 | int i; |
72 | cpumask_t span, nodemask; | 72 | cpumask_t span, nodemask; |
@@ -96,7 +96,7 @@ static cpumask_t __devinit sched_domain_node_span(int node) | |||
96 | #ifdef CONFIG_SCHED_SMT | 96 | #ifdef CONFIG_SCHED_SMT |
97 | static DEFINE_PER_CPU(struct sched_domain, cpu_domains); | 97 | static DEFINE_PER_CPU(struct sched_domain, cpu_domains); |
98 | static struct sched_group sched_group_cpus[NR_CPUS]; | 98 | static struct sched_group sched_group_cpus[NR_CPUS]; |
99 | static int __devinit cpu_to_cpu_group(int cpu) | 99 | static int cpu_to_cpu_group(int cpu) |
100 | { | 100 | { |
101 | return cpu; | 101 | return cpu; |
102 | } | 102 | } |
@@ -104,7 +104,7 @@ static int __devinit cpu_to_cpu_group(int cpu) | |||
104 | 104 | ||
105 | static DEFINE_PER_CPU(struct sched_domain, phys_domains); | 105 | static DEFINE_PER_CPU(struct sched_domain, phys_domains); |
106 | static struct sched_group sched_group_phys[NR_CPUS]; | 106 | static struct sched_group sched_group_phys[NR_CPUS]; |
107 | static int __devinit cpu_to_phys_group(int cpu) | 107 | static int cpu_to_phys_group(int cpu) |
108 | { | 108 | { |
109 | #ifdef CONFIG_SCHED_SMT | 109 | #ifdef CONFIG_SCHED_SMT |
110 | return first_cpu(cpu_sibling_map[cpu]); | 110 | return first_cpu(cpu_sibling_map[cpu]); |
@@ -125,44 +125,36 @@ static struct sched_group *sched_group_nodes[MAX_NUMNODES]; | |||
125 | static DEFINE_PER_CPU(struct sched_domain, allnodes_domains); | 125 | static DEFINE_PER_CPU(struct sched_domain, allnodes_domains); |
126 | static struct sched_group sched_group_allnodes[MAX_NUMNODES]; | 126 | static struct sched_group sched_group_allnodes[MAX_NUMNODES]; |
127 | 127 | ||
128 | static int __devinit cpu_to_allnodes_group(int cpu) | 128 | static int cpu_to_allnodes_group(int cpu) |
129 | { | 129 | { |
130 | return cpu_to_node(cpu); | 130 | return cpu_to_node(cpu); |
131 | } | 131 | } |
132 | #endif | 132 | #endif |
133 | 133 | ||
134 | /* | 134 | /* |
135 | * Set up scheduler domains and groups. Callers must hold the hotplug lock. | 135 | * Build sched domains for a given set of cpus and attach the sched domains |
136 | * to the individual cpus | ||
136 | */ | 137 | */ |
137 | void __devinit arch_init_sched_domains(void) | 138 | void build_sched_domains(const cpumask_t *cpu_map) |
138 | { | 139 | { |
139 | int i; | 140 | int i; |
140 | cpumask_t cpu_default_map; | ||
141 | 141 | ||
142 | /* | 142 | /* |
143 | * Setup mask for cpus without special case scheduling requirements. | 143 | * Set up domains for cpus specified by the cpu_map. |
144 | * For now this just excludes isolated cpus, but could be used to | ||
145 | * exclude other special cases in the future. | ||
146 | */ | 144 | */ |
147 | cpus_complement(cpu_default_map, cpu_isolated_map); | 145 | for_each_cpu_mask(i, *cpu_map) { |
148 | cpus_and(cpu_default_map, cpu_default_map, cpu_online_map); | ||
149 | |||
150 | /* | ||
151 | * Set up domains. Isolated domains just stay on the dummy domain. | ||
152 | */ | ||
153 | for_each_cpu_mask(i, cpu_default_map) { | ||
154 | int group; | 146 | int group; |
155 | struct sched_domain *sd = NULL, *p; | 147 | struct sched_domain *sd = NULL, *p; |
156 | cpumask_t nodemask = node_to_cpumask(cpu_to_node(i)); | 148 | cpumask_t nodemask = node_to_cpumask(cpu_to_node(i)); |
157 | 149 | ||
158 | cpus_and(nodemask, nodemask, cpu_default_map); | 150 | cpus_and(nodemask, nodemask, *cpu_map); |
159 | 151 | ||
160 | #ifdef CONFIG_NUMA | 152 | #ifdef CONFIG_NUMA |
161 | if (num_online_cpus() | 153 | if (num_online_cpus() |
162 | > SD_NODES_PER_DOMAIN*cpus_weight(nodemask)) { | 154 | > SD_NODES_PER_DOMAIN*cpus_weight(nodemask)) { |
163 | sd = &per_cpu(allnodes_domains, i); | 155 | sd = &per_cpu(allnodes_domains, i); |
164 | *sd = SD_ALLNODES_INIT; | 156 | *sd = SD_ALLNODES_INIT; |
165 | sd->span = cpu_default_map; | 157 | sd->span = *cpu_map; |
166 | group = cpu_to_allnodes_group(i); | 158 | group = cpu_to_allnodes_group(i); |
167 | sd->groups = &sched_group_allnodes[group]; | 159 | sd->groups = &sched_group_allnodes[group]; |
168 | p = sd; | 160 | p = sd; |
@@ -173,7 +165,7 @@ void __devinit arch_init_sched_domains(void) | |||
173 | *sd = SD_NODE_INIT; | 165 | *sd = SD_NODE_INIT; |
174 | sd->span = sched_domain_node_span(cpu_to_node(i)); | 166 | sd->span = sched_domain_node_span(cpu_to_node(i)); |
175 | sd->parent = p; | 167 | sd->parent = p; |
176 | cpus_and(sd->span, sd->span, cpu_default_map); | 168 | cpus_and(sd->span, sd->span, *cpu_map); |
177 | #endif | 169 | #endif |
178 | 170 | ||
179 | p = sd; | 171 | p = sd; |
@@ -190,7 +182,7 @@ void __devinit arch_init_sched_domains(void) | |||
190 | group = cpu_to_cpu_group(i); | 182 | group = cpu_to_cpu_group(i); |
191 | *sd = SD_SIBLING_INIT; | 183 | *sd = SD_SIBLING_INIT; |
192 | sd->span = cpu_sibling_map[i]; | 184 | sd->span = cpu_sibling_map[i]; |
193 | cpus_and(sd->span, sd->span, cpu_default_map); | 185 | cpus_and(sd->span, sd->span, *cpu_map); |
194 | sd->parent = p; | 186 | sd->parent = p; |
195 | sd->groups = &sched_group_cpus[group]; | 187 | sd->groups = &sched_group_cpus[group]; |
196 | #endif | 188 | #endif |
@@ -198,9 +190,9 @@ void __devinit arch_init_sched_domains(void) | |||
198 | 190 | ||
199 | #ifdef CONFIG_SCHED_SMT | 191 | #ifdef CONFIG_SCHED_SMT |
200 | /* Set up CPU (sibling) groups */ | 192 | /* Set up CPU (sibling) groups */ |
201 | for_each_cpu_mask(i, cpu_default_map) { | 193 | for_each_cpu_mask(i, *cpu_map) { |
202 | cpumask_t this_sibling_map = cpu_sibling_map[i]; | 194 | cpumask_t this_sibling_map = cpu_sibling_map[i]; |
203 | cpus_and(this_sibling_map, this_sibling_map, cpu_default_map); | 195 | cpus_and(this_sibling_map, this_sibling_map, *cpu_map); |
204 | if (i != first_cpu(this_sibling_map)) | 196 | if (i != first_cpu(this_sibling_map)) |
205 | continue; | 197 | continue; |
206 | 198 | ||
@@ -213,7 +205,7 @@ void __devinit arch_init_sched_domains(void) | |||
213 | for (i = 0; i < MAX_NUMNODES; i++) { | 205 | for (i = 0; i < MAX_NUMNODES; i++) { |
214 | cpumask_t nodemask = node_to_cpumask(i); | 206 | cpumask_t nodemask = node_to_cpumask(i); |
215 | 207 | ||
216 | cpus_and(nodemask, nodemask, cpu_default_map); | 208 | cpus_and(nodemask, nodemask, *cpu_map); |
217 | if (cpus_empty(nodemask)) | 209 | if (cpus_empty(nodemask)) |
218 | continue; | 210 | continue; |
219 | 211 | ||
@@ -222,7 +214,7 @@ void __devinit arch_init_sched_domains(void) | |||
222 | } | 214 | } |
223 | 215 | ||
224 | #ifdef CONFIG_NUMA | 216 | #ifdef CONFIG_NUMA |
225 | init_sched_build_groups(sched_group_allnodes, cpu_default_map, | 217 | init_sched_build_groups(sched_group_allnodes, *cpu_map, |
226 | &cpu_to_allnodes_group); | 218 | &cpu_to_allnodes_group); |
227 | 219 | ||
228 | for (i = 0; i < MAX_NUMNODES; i++) { | 220 | for (i = 0; i < MAX_NUMNODES; i++) { |
@@ -233,12 +225,12 @@ void __devinit arch_init_sched_domains(void) | |||
233 | cpumask_t covered = CPU_MASK_NONE; | 225 | cpumask_t covered = CPU_MASK_NONE; |
234 | int j; | 226 | int j; |
235 | 227 | ||
236 | cpus_and(nodemask, nodemask, cpu_default_map); | 228 | cpus_and(nodemask, nodemask, *cpu_map); |
237 | if (cpus_empty(nodemask)) | 229 | if (cpus_empty(nodemask)) |
238 | continue; | 230 | continue; |
239 | 231 | ||
240 | domainspan = sched_domain_node_span(i); | 232 | domainspan = sched_domain_node_span(i); |
241 | cpus_and(domainspan, domainspan, cpu_default_map); | 233 | cpus_and(domainspan, domainspan, *cpu_map); |
242 | 234 | ||
243 | sg = kmalloc(sizeof(struct sched_group), GFP_KERNEL); | 235 | sg = kmalloc(sizeof(struct sched_group), GFP_KERNEL); |
244 | sched_group_nodes[i] = sg; | 236 | sched_group_nodes[i] = sg; |
@@ -266,7 +258,7 @@ void __devinit arch_init_sched_domains(void) | |||
266 | int n = (i + j) % MAX_NUMNODES; | 258 | int n = (i + j) % MAX_NUMNODES; |
267 | 259 | ||
268 | cpus_complement(notcovered, covered); | 260 | cpus_complement(notcovered, covered); |
269 | cpus_and(tmp, notcovered, cpu_default_map); | 261 | cpus_and(tmp, notcovered, *cpu_map); |
270 | cpus_and(tmp, tmp, domainspan); | 262 | cpus_and(tmp, tmp, domainspan); |
271 | if (cpus_empty(tmp)) | 263 | if (cpus_empty(tmp)) |
272 | break; | 264 | break; |
@@ -293,7 +285,7 @@ void __devinit arch_init_sched_domains(void) | |||
293 | #endif | 285 | #endif |
294 | 286 | ||
295 | /* Calculate CPU power for physical packages and nodes */ | 287 | /* Calculate CPU power for physical packages and nodes */ |
296 | for_each_cpu_mask(i, cpu_default_map) { | 288 | for_each_cpu_mask(i, *cpu_map) { |
297 | int power; | 289 | int power; |
298 | struct sched_domain *sd; | 290 | struct sched_domain *sd; |
299 | #ifdef CONFIG_SCHED_SMT | 291 | #ifdef CONFIG_SCHED_SMT |
@@ -359,13 +351,35 @@ next_sg: | |||
359 | cpu_attach_domain(sd, i); | 351 | cpu_attach_domain(sd, i); |
360 | } | 352 | } |
361 | } | 353 | } |
354 | /* | ||
355 | * Set up scheduler domains and groups. Callers must hold the hotplug lock. | ||
356 | */ | ||
357 | void arch_init_sched_domains(const cpumask_t *cpu_map) | ||
358 | { | ||
359 | cpumask_t cpu_default_map; | ||
360 | |||
361 | /* | ||
362 | * Setup mask for cpus without special case scheduling requirements. | ||
363 | * For now this just excludes isolated cpus, but could be used to | ||
364 | * exclude other special cases in the future. | ||
365 | */ | ||
366 | cpus_andnot(cpu_default_map, *cpu_map, cpu_isolated_map); | ||
367 | |||
368 | build_sched_domains(&cpu_default_map); | ||
369 | } | ||
362 | 370 | ||
363 | void __devinit arch_destroy_sched_domains(void) | 371 | void arch_destroy_sched_domains(const cpumask_t *cpu_map) |
364 | { | 372 | { |
365 | #ifdef CONFIG_NUMA | 373 | #ifdef CONFIG_NUMA |
366 | int i; | 374 | int i; |
367 | for (i = 0; i < MAX_NUMNODES; i++) { | 375 | for (i = 0; i < MAX_NUMNODES; i++) { |
376 | cpumask_t nodemask = node_to_cpumask(i); | ||
368 | struct sched_group *oldsg, *sg = sched_group_nodes[i]; | 377 | struct sched_group *oldsg, *sg = sched_group_nodes[i]; |
378 | |||
379 | cpus_and(nodemask, nodemask, *cpu_map); | ||
380 | if (cpus_empty(nodemask)) | ||
381 | continue; | ||
382 | |||
369 | if (sg == NULL) | 383 | if (sg == NULL) |
370 | continue; | 384 | continue; |
371 | sg = sg->next; | 385 | sg = sg->next; |
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 3865f088ffa2..623b0a546709 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c | |||
@@ -346,6 +346,7 @@ smp_callin (void) | |||
346 | lock_ipi_calllock(); | 346 | lock_ipi_calllock(); |
347 | cpu_set(cpuid, cpu_online_map); | 347 | cpu_set(cpuid, cpu_online_map); |
348 | unlock_ipi_calllock(); | 348 | unlock_ipi_calllock(); |
349 | per_cpu(cpu_state, cpuid) = CPU_ONLINE; | ||
349 | 350 | ||
350 | smp_setup_percpu_timer(); | 351 | smp_setup_percpu_timer(); |
351 | 352 | ||
@@ -611,6 +612,7 @@ void __devinit smp_prepare_boot_cpu(void) | |||
611 | { | 612 | { |
612 | cpu_set(smp_processor_id(), cpu_online_map); | 613 | cpu_set(smp_processor_id(), cpu_online_map); |
613 | cpu_set(smp_processor_id(), cpu_callin_map); | 614 | cpu_set(smp_processor_id(), cpu_callin_map); |
615 | per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; | ||
614 | } | 616 | } |
615 | 617 | ||
616 | /* | 618 | /* |
@@ -688,6 +690,7 @@ int __cpu_disable(void) | |||
688 | return -EBUSY; | 690 | return -EBUSY; |
689 | 691 | ||
690 | remove_siblinginfo(cpu); | 692 | remove_siblinginfo(cpu); |
693 | cpu_clear(cpu, cpu_online_map); | ||
691 | fixup_irqs(); | 694 | fixup_irqs(); |
692 | local_flush_tlb_all(); | 695 | local_flush_tlb_all(); |
693 | cpu_clear(cpu, cpu_callin_map); | 696 | cpu_clear(cpu, cpu_callin_map); |
@@ -774,6 +777,7 @@ __cpu_up (unsigned int cpu) | |||
774 | if (cpu_isset(cpu, cpu_callin_map)) | 777 | if (cpu_isset(cpu, cpu_callin_map)) |
775 | return -EINVAL; | 778 | return -EINVAL; |
776 | 779 | ||
780 | per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; | ||
777 | /* Processor goes to start_secondary(), sets online flag */ | 781 | /* Processor goes to start_secondary(), sets online flag */ |
778 | ret = do_boot_cpu(sapicid, cpu); | 782 | ret = do_boot_cpu(sapicid, cpu); |
779 | if (ret < 0) | 783 | if (ret < 0) |
diff --git a/arch/ia64/sn/kernel/xpc.h b/arch/ia64/sn/kernel/xpc.h index 1a0aed8490d1..d0ee635daf2e 100644 --- a/arch/ia64/sn/kernel/xpc.h +++ b/arch/ia64/sn/kernel/xpc.h | |||
@@ -87,7 +87,7 @@ struct xpc_rsvd_page { | |||
87 | u8 partid; /* partition ID from SAL */ | 87 | u8 partid; /* partition ID from SAL */ |
88 | u8 version; | 88 | u8 version; |
89 | u8 pad[6]; /* pad to u64 align */ | 89 | u8 pad[6]; /* pad to u64 align */ |
90 | u64 vars_pa; | 90 | volatile u64 vars_pa; |
91 | u64 part_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned; | 91 | u64 part_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned; |
92 | u64 mach_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned; | 92 | u64 mach_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned; |
93 | }; | 93 | }; |
@@ -138,7 +138,7 @@ struct xpc_vars { | |||
138 | * occupies half a cacheline. | 138 | * occupies half a cacheline. |
139 | */ | 139 | */ |
140 | struct xpc_vars_part { | 140 | struct xpc_vars_part { |
141 | u64 magic; | 141 | volatile u64 magic; |
142 | 142 | ||
143 | u64 openclose_args_pa; /* physical address of open and close args */ | 143 | u64 openclose_args_pa; /* physical address of open and close args */ |
144 | u64 GPs_pa; /* physical address of Get/Put values */ | 144 | u64 GPs_pa; /* physical address of Get/Put values */ |
@@ -185,8 +185,8 @@ struct xpc_vars_part { | |||
185 | * Define a Get/Put value pair (pointers) used with a message queue. | 185 | * Define a Get/Put value pair (pointers) used with a message queue. |
186 | */ | 186 | */ |
187 | struct xpc_gp { | 187 | struct xpc_gp { |
188 | s64 get; /* Get value */ | 188 | volatile s64 get; /* Get value */ |
189 | s64 put; /* Put value */ | 189 | volatile s64 put; /* Put value */ |
190 | }; | 190 | }; |
191 | 191 | ||
192 | #define XPC_GP_SIZE \ | 192 | #define XPC_GP_SIZE \ |
@@ -231,7 +231,7 @@ struct xpc_openclose_args { | |||
231 | */ | 231 | */ |
232 | struct xpc_notify { | 232 | struct xpc_notify { |
233 | struct semaphore sema; /* notify semaphore */ | 233 | struct semaphore sema; /* notify semaphore */ |
234 | u8 type; /* type of notification */ | 234 | volatile u8 type; /* type of notification */ |
235 | 235 | ||
236 | /* the following two fields are only used if type == XPC_N_CALL */ | 236 | /* the following two fields are only used if type == XPC_N_CALL */ |
237 | xpc_notify_func func; /* user's notify function */ | 237 | xpc_notify_func func; /* user's notify function */ |
@@ -439,7 +439,7 @@ struct xpc_partition { | |||
439 | 439 | ||
440 | /* XPC infrastructure referencing and teardown control */ | 440 | /* XPC infrastructure referencing and teardown control */ |
441 | 441 | ||
442 | u8 setup_state; /* infrastructure setup state */ | 442 | volatile u8 setup_state; /* infrastructure setup state */ |
443 | wait_queue_head_t teardown_wq; /* kthread waiting to teardown infra */ | 443 | wait_queue_head_t teardown_wq; /* kthread waiting to teardown infra */ |
444 | atomic_t references; /* #of references to infrastructure */ | 444 | atomic_t references; /* #of references to infrastructure */ |
445 | 445 | ||
diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c index 0bf6fbcc46d2..6d02dac8056f 100644 --- a/arch/ia64/sn/kernel/xpc_channel.c +++ b/arch/ia64/sn/kernel/xpc_channel.c | |||
@@ -209,7 +209,7 @@ xpc_setup_infrastructure(struct xpc_partition *part) | |||
209 | * With the setting of the partition setup_state to XPC_P_SETUP, we're | 209 | * With the setting of the partition setup_state to XPC_P_SETUP, we're |
210 | * declaring that this partition is ready to go. | 210 | * declaring that this partition is ready to go. |
211 | */ | 211 | */ |
212 | (volatile u8) part->setup_state = XPC_P_SETUP; | 212 | part->setup_state = XPC_P_SETUP; |
213 | 213 | ||
214 | 214 | ||
215 | /* | 215 | /* |
@@ -227,7 +227,7 @@ xpc_setup_infrastructure(struct xpc_partition *part) | |||
227 | xpc_vars_part[partid].IPI_phys_cpuid = | 227 | xpc_vars_part[partid].IPI_phys_cpuid = |
228 | cpu_physical_id(smp_processor_id()); | 228 | cpu_physical_id(smp_processor_id()); |
229 | xpc_vars_part[partid].nchannels = part->nchannels; | 229 | xpc_vars_part[partid].nchannels = part->nchannels; |
230 | (volatile u64) xpc_vars_part[partid].magic = XPC_VP_MAGIC1; | 230 | xpc_vars_part[partid].magic = XPC_VP_MAGIC1; |
231 | 231 | ||
232 | return xpcSuccess; | 232 | return xpcSuccess; |
233 | } | 233 | } |
@@ -355,7 +355,7 @@ xpc_pull_remote_vars_part(struct xpc_partition *part) | |||
355 | 355 | ||
356 | /* let the other side know that we've pulled their variables */ | 356 | /* let the other side know that we've pulled their variables */ |
357 | 357 | ||
358 | (volatile u64) xpc_vars_part[partid].magic = XPC_VP_MAGIC2; | 358 | xpc_vars_part[partid].magic = XPC_VP_MAGIC2; |
359 | } | 359 | } |
360 | 360 | ||
361 | if (pulled_entry->magic == XPC_VP_MAGIC1) { | 361 | if (pulled_entry->magic == XPC_VP_MAGIC1) { |
@@ -1183,7 +1183,7 @@ xpc_process_msg_IPI(struct xpc_partition *part, int ch_number) | |||
1183 | */ | 1183 | */ |
1184 | xpc_clear_local_msgqueue_flags(ch); | 1184 | xpc_clear_local_msgqueue_flags(ch); |
1185 | 1185 | ||
1186 | (volatile s64) ch->w_remote_GP.get = ch->remote_GP.get; | 1186 | ch->w_remote_GP.get = ch->remote_GP.get; |
1187 | 1187 | ||
1188 | dev_dbg(xpc_chan, "w_remote_GP.get changed to %ld, partid=%d, " | 1188 | dev_dbg(xpc_chan, "w_remote_GP.get changed to %ld, partid=%d, " |
1189 | "channel=%d\n", ch->w_remote_GP.get, ch->partid, | 1189 | "channel=%d\n", ch->w_remote_GP.get, ch->partid, |
@@ -1211,7 +1211,7 @@ xpc_process_msg_IPI(struct xpc_partition *part, int ch_number) | |||
1211 | */ | 1211 | */ |
1212 | xpc_clear_remote_msgqueue_flags(ch); | 1212 | xpc_clear_remote_msgqueue_flags(ch); |
1213 | 1213 | ||
1214 | (volatile s64) ch->w_remote_GP.put = ch->remote_GP.put; | 1214 | ch->w_remote_GP.put = ch->remote_GP.put; |
1215 | 1215 | ||
1216 | dev_dbg(xpc_chan, "w_remote_GP.put changed to %ld, partid=%d, " | 1216 | dev_dbg(xpc_chan, "w_remote_GP.put changed to %ld, partid=%d, " |
1217 | "channel=%d\n", ch->w_remote_GP.put, ch->partid, | 1217 | "channel=%d\n", ch->w_remote_GP.put, ch->partid, |
@@ -1875,7 +1875,7 @@ xpc_send_msg(struct xpc_channel *ch, struct xpc_msg *msg, u8 notify_type, | |||
1875 | notify = &ch->notify_queue[msg_number % ch->local_nentries]; | 1875 | notify = &ch->notify_queue[msg_number % ch->local_nentries]; |
1876 | notify->func = func; | 1876 | notify->func = func; |
1877 | notify->key = key; | 1877 | notify->key = key; |
1878 | (volatile u8) notify->type = notify_type; | 1878 | notify->type = notify_type; |
1879 | 1879 | ||
1880 | // >>> is a mb() needed here? | 1880 | // >>> is a mb() needed here? |
1881 | 1881 | ||
diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c index cd7ed73f0e7a..578265ea9e67 100644 --- a/arch/ia64/sn/kernel/xpc_partition.c +++ b/arch/ia64/sn/kernel/xpc_partition.c | |||
@@ -253,7 +253,7 @@ xpc_rsvd_page_init(void) | |||
253 | * This signifies to the remote partition that our reserved | 253 | * This signifies to the remote partition that our reserved |
254 | * page is initialized. | 254 | * page is initialized. |
255 | */ | 255 | */ |
256 | (volatile u64) rp->vars_pa = __pa(xpc_vars); | 256 | rp->vars_pa = __pa(xpc_vars); |
257 | 257 | ||
258 | return rp; | 258 | return rp; |
259 | } | 259 | } |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 94f5a8eb2c22..bd9de7b00c0a 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -1416,6 +1416,12 @@ config HIGHMEM | |||
1416 | bool "High Memory Support" | 1416 | bool "High Memory Support" |
1417 | depends on MIPS32 && (CPU_R3000 || CPU_SB1 || CPU_R7000 || CPU_RM9000 || CPU_R10000) && !(MACH_DECSTATION || MOMENCO_JAGUAR_ATX) | 1417 | depends on MIPS32 && (CPU_R3000 || CPU_SB1 || CPU_R7000 || CPU_RM9000 || CPU_R10000) && !(MACH_DECSTATION || MOMENCO_JAGUAR_ATX) |
1418 | 1418 | ||
1419 | config ARCH_FLATMEM_ENABLE | ||
1420 | def_bool y | ||
1421 | depends on !NUMA | ||
1422 | |||
1423 | source "mm/Kconfig" | ||
1424 | |||
1419 | config SMP | 1425 | config SMP |
1420 | bool "Multi-Processing support" | 1426 | bool "Multi-Processing support" |
1421 | depends on CPU_RM9000 || (SIBYTE_SB1250 && !SIBYTE_STANDALONE) || SGI_IP27 | 1427 | depends on CPU_RM9000 || (SIBYTE_SB1250 && !SIBYTE_STANDALONE) || SGI_IP27 |
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 6018ca25aceb..3a240e3e004c 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/root_dev.h> | 33 | #include <linux/root_dev.h> |
34 | #include <linux/highmem.h> | 34 | #include <linux/highmem.h> |
35 | #include <linux/console.h> | 35 | #include <linux/console.h> |
36 | #include <linux/mmzone.h> | ||
36 | 37 | ||
37 | #include <asm/addrspace.h> | 38 | #include <asm/addrspace.h> |
38 | #include <asm/bootinfo.h> | 39 | #include <asm/bootinfo.h> |
@@ -356,6 +357,8 @@ static inline void bootmem_init(void) | |||
356 | } | 357 | } |
357 | #endif | 358 | #endif |
358 | 359 | ||
360 | memory_present(0, first_usable_pfn, max_low_pfn); | ||
361 | |||
359 | /* Initialize the boot-time allocator with low memory only. */ | 362 | /* Initialize the boot-time allocator with low memory only. */ |
360 | bootmap_size = init_bootmem(first_usable_pfn, max_low_pfn); | 363 | bootmap_size = init_bootmem(first_usable_pfn, max_low_pfn); |
361 | 364 | ||
@@ -557,6 +560,7 @@ void __init setup_arch(char **cmdline_p) | |||
557 | 560 | ||
558 | parse_cmdline_early(); | 561 | parse_cmdline_early(); |
559 | bootmem_init(); | 562 | bootmem_init(); |
563 | sparse_init(); | ||
560 | paging_init(); | 564 | paging_init(); |
561 | resource_init(); | 565 | resource_init(); |
562 | } | 566 | } |
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 73843c528778..9c9a271c8a3a 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c | |||
@@ -128,7 +128,7 @@ static void __init fixrange_init(unsigned long start, unsigned long end, | |||
128 | #endif /* CONFIG_MIPS64 */ | 128 | #endif /* CONFIG_MIPS64 */ |
129 | #endif /* CONFIG_HIGHMEM */ | 129 | #endif /* CONFIG_HIGHMEM */ |
130 | 130 | ||
131 | #ifndef CONFIG_DISCONTIGMEM | 131 | #ifndef CONFIG_NEED_MULTIPLE_NODES |
132 | extern void pagetable_init(void); | 132 | extern void pagetable_init(void); |
133 | 133 | ||
134 | void __init paging_init(void) | 134 | void __init paging_init(void) |
@@ -253,7 +253,7 @@ void __init mem_init(void) | |||
253 | initsize >> 10, | 253 | initsize >> 10, |
254 | (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))); | 254 | (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))); |
255 | } | 255 | } |
256 | #endif /* !CONFIG_DISCONTIGMEM */ | 256 | #endif /* !CONFIG_NEED_MULTIPLE_NODES */ |
257 | 257 | ||
258 | #ifdef CONFIG_BLK_DEV_INITRD | 258 | #ifdef CONFIG_BLK_DEV_INITRD |
259 | void free_initrd_mem(unsigned long start, unsigned long end) | 259 | void free_initrd_mem(unsigned long start, unsigned long end) |
diff --git a/arch/mips/mm/pgtable.c b/arch/mips/mm/pgtable.c index 3b88fdeef329..3fe94202da8c 100644 --- a/arch/mips/mm/pgtable.c +++ b/arch/mips/mm/pgtable.c | |||
@@ -5,7 +5,7 @@ | |||
5 | 5 | ||
6 | void show_mem(void) | 6 | void show_mem(void) |
7 | { | 7 | { |
8 | #ifndef CONFIG_DISCONTIGMEM /* XXX(hch): later.. */ | 8 | #ifndef CONFIG_NEED_MULTIPLE_NODES /* XXX(hch): later.. */ |
9 | int pfn, total = 0, reserved = 0; | 9 | int pfn, total = 0, reserved = 0; |
10 | int shared = 0, cached = 0; | 10 | int shared = 0, cached = 0; |
11 | int highmem = 0; | 11 | int highmem = 0; |
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index 848f43970a4b..a7835cd3f51f 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig | |||
@@ -88,6 +88,9 @@ config 8xx | |||
88 | depends on BROKEN | 88 | depends on BROKEN |
89 | bool "8xx" | 89 | bool "8xx" |
90 | 90 | ||
91 | config E200 | ||
92 | bool "e200" | ||
93 | |||
91 | config E500 | 94 | config E500 |
92 | bool "e500" | 95 | bool "e500" |
93 | 96 | ||
@@ -98,12 +101,12 @@ config PPC_FPU | |||
98 | 101 | ||
99 | config BOOKE | 102 | config BOOKE |
100 | bool | 103 | bool |
101 | depends on E500 | 104 | depends on E200 || E500 |
102 | default y | 105 | default y |
103 | 106 | ||
104 | config FSL_BOOKE | 107 | config FSL_BOOKE |
105 | bool | 108 | bool |
106 | depends on E500 | 109 | depends on E200 || E500 |
107 | default y | 110 | default y |
108 | 111 | ||
109 | config PTE_64BIT | 112 | config PTE_64BIT |
@@ -141,16 +144,16 @@ config ALTIVEC | |||
141 | 144 | ||
142 | config SPE | 145 | config SPE |
143 | bool "SPE Support" | 146 | bool "SPE Support" |
144 | depends on E500 | 147 | depends on E200 || E500 |
145 | ---help--- | 148 | ---help--- |
146 | This option enables kernel support for the Signal Processing | 149 | This option enables kernel support for the Signal Processing |
147 | Extensions (SPE) to the PowerPC processor. The kernel currently | 150 | Extensions (SPE) to the PowerPC processor. The kernel currently |
148 | supports saving and restoring SPE registers, and turning on the | 151 | supports saving and restoring SPE registers, and turning on the |
149 | 'spe enable' bit so user processes can execute SPE instructions. | 152 | 'spe enable' bit so user processes can execute SPE instructions. |
150 | 153 | ||
151 | This option is only usefully if you have a processor that supports | 154 | This option is only useful if you have a processor that supports |
152 | SPE (e500, otherwise known as 85xx series), but does not have any | 155 | SPE (e500, otherwise known as 85xx series), but does not have any |
153 | affect on a non-spe cpu (it does, however add code to the kernel). | 156 | effect on a non-spe cpu (it does, however add code to the kernel). |
154 | 157 | ||
155 | If in doubt, say Y here. | 158 | If in doubt, say Y here. |
156 | 159 | ||
@@ -200,7 +203,7 @@ config TAU_AVERAGE | |||
200 | 203 | ||
201 | config MATH_EMULATION | 204 | config MATH_EMULATION |
202 | bool "Math emulation" | 205 | bool "Math emulation" |
203 | depends on 4xx || 8xx || E500 | 206 | depends on 4xx || 8xx || E200 || E500 |
204 | ---help--- | 207 | ---help--- |
205 | Some PowerPC chips designed for embedded applications do not have | 208 | Some PowerPC chips designed for embedded applications do not have |
206 | a floating-point unit and therefore do not implement the | 209 | a floating-point unit and therefore do not implement the |
@@ -214,6 +217,26 @@ config MATH_EMULATION | |||
214 | here. Saying Y here will not hurt performance (on any machine) but | 217 | here. Saying Y here will not hurt performance (on any machine) but |
215 | will increase the size of the kernel. | 218 | will increase the size of the kernel. |
216 | 219 | ||
220 | config KEXEC | ||
221 | bool "kexec system call (EXPERIMENTAL)" | ||
222 | depends on EXPERIMENTAL | ||
223 | help | ||
224 | kexec is a system call that implements the ability to shutdown your | ||
225 | current kernel, and to start another kernel. It is like a reboot | ||
226 | but it is indepedent of the system firmware. And like a reboot | ||
227 | you can start any kernel with it, not just Linux. | ||
228 | |||
229 | The name comes from the similiarity to the exec system call. | ||
230 | |||
231 | It is an ongoing process to be certain the hardware in a machine | ||
232 | is properly shutdown, so do not be surprised if this code does not | ||
233 | initially work for you. It may help to enable device hotplugging | ||
234 | support. As of this writing the exact hardware interface is | ||
235 | strongly in flux, so no good recommendation can be made. | ||
236 | |||
237 | In the GameCube implementation, kexec allows you to load and | ||
238 | run DOL files, including kernel and homebrew DOLs. | ||
239 | |||
217 | source "drivers/cpufreq/Kconfig" | 240 | source "drivers/cpufreq/Kconfig" |
218 | 241 | ||
219 | config CPU_FREQ_PMAC | 242 | config CPU_FREQ_PMAC |
@@ -254,7 +277,7 @@ config PPC_STD_MMU | |||
254 | 277 | ||
255 | config NOT_COHERENT_CACHE | 278 | config NOT_COHERENT_CACHE |
256 | bool | 279 | bool |
257 | depends on 4xx || 8xx | 280 | depends on 4xx || 8xx || E200 |
258 | default y | 281 | default y |
259 | 282 | ||
260 | endmenu | 283 | endmenu |
diff --git a/arch/ppc/Kconfig.debug b/arch/ppc/Kconfig.debug index d2e1eea8e8e4..e16c7710d4be 100644 --- a/arch/ppc/Kconfig.debug +++ b/arch/ppc/Kconfig.debug | |||
@@ -66,7 +66,7 @@ config SERIAL_TEXT_DEBUG | |||
66 | 66 | ||
67 | config PPC_OCP | 67 | config PPC_OCP |
68 | bool | 68 | bool |
69 | depends on IBM_OCP || FSL_OCP || XILINX_OCP | 69 | depends on IBM_OCP || XILINX_OCP |
70 | default y | 70 | default y |
71 | 71 | ||
72 | endmenu | 72 | endmenu |
diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile index 0432a25b4735..f9b0d778dd82 100644 --- a/arch/ppc/Makefile +++ b/arch/ppc/Makefile | |||
@@ -29,7 +29,7 @@ CPP = $(CC) -E $(CFLAGS) | |||
29 | 29 | ||
30 | CHECKFLAGS += -D__powerpc__ | 30 | CHECKFLAGS += -D__powerpc__ |
31 | 31 | ||
32 | ifndef CONFIG_E500 | 32 | ifndef CONFIG_FSL_BOOKE |
33 | CFLAGS += -mstring | 33 | CFLAGS += -mstring |
34 | endif | 34 | endif |
35 | 35 | ||
@@ -38,6 +38,7 @@ cpu-as-$(CONFIG_4xx) += -Wa,-m405 | |||
38 | cpu-as-$(CONFIG_6xx) += -Wa,-maltivec | 38 | cpu-as-$(CONFIG_6xx) += -Wa,-maltivec |
39 | cpu-as-$(CONFIG_POWER4) += -Wa,-maltivec | 39 | cpu-as-$(CONFIG_POWER4) += -Wa,-maltivec |
40 | cpu-as-$(CONFIG_E500) += -Wa,-me500 | 40 | cpu-as-$(CONFIG_E500) += -Wa,-me500 |
41 | cpu-as-$(CONFIG_E200) += -Wa,-me200 | ||
41 | 42 | ||
42 | AFLAGS += $(cpu-as-y) | 43 | AFLAGS += $(cpu-as-y) |
43 | CFLAGS += $(cpu-as-y) | 44 | CFLAGS += $(cpu-as-y) |
diff --git a/arch/ppc/boot/openfirmware/chrpmain.c b/arch/ppc/boot/openfirmware/chrpmain.c index 6fb4f738728c..effe4a0624b0 100644 --- a/arch/ppc/boot/openfirmware/chrpmain.c +++ b/arch/ppc/boot/openfirmware/chrpmain.c | |||
@@ -39,7 +39,7 @@ char *avail_high; | |||
39 | 39 | ||
40 | #define SCRATCH_SIZE (128 << 10) | 40 | #define SCRATCH_SIZE (128 << 10) |
41 | 41 | ||
42 | static char scratch[SCRATCH_SIZE]; /* 1MB of scratch space for gunzip */ | 42 | static char scratch[SCRATCH_SIZE]; /* 128k of scratch space for gunzip */ |
43 | 43 | ||
44 | typedef void (*kernel_start_t)(int, int, void *, unsigned int, unsigned int); | 44 | typedef void (*kernel_start_t)(int, int, void *, unsigned int, unsigned int); |
45 | 45 | ||
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index b284451802c9..b1457a8a9c0f 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile | |||
@@ -26,7 +26,10 @@ obj-$(CONFIG_KGDB) += ppc-stub.o | |||
26 | obj-$(CONFIG_SMP) += smp.o smp-tbsync.o | 26 | obj-$(CONFIG_SMP) += smp.o smp-tbsync.o |
27 | obj-$(CONFIG_TAU) += temp.o | 27 | obj-$(CONFIG_TAU) += temp.o |
28 | obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o | 28 | obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o |
29 | ifndef CONFIG_E200 | ||
29 | obj-$(CONFIG_FSL_BOOKE) += perfmon_fsl_booke.o | 30 | obj-$(CONFIG_FSL_BOOKE) += perfmon_fsl_booke.o |
31 | endif | ||
32 | obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o | ||
30 | 33 | ||
31 | ifndef CONFIG_MATH_EMULATION | 34 | ifndef CONFIG_MATH_EMULATION |
32 | obj-$(CONFIG_8xx) += softemu8xx.o | 35 | obj-$(CONFIG_8xx) += softemu8xx.o |
diff --git a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c index 01c226008dbf..50936cda0af9 100644 --- a/arch/ppc/kernel/cputable.c +++ b/arch/ppc/kernel/cputable.c | |||
@@ -903,7 +903,30 @@ struct cpu_spec cpu_specs[] = { | |||
903 | .dcache_bsize = 32, | 903 | .dcache_bsize = 32, |
904 | }, | 904 | }, |
905 | #endif /* CONFIG_44x */ | 905 | #endif /* CONFIG_44x */ |
906 | #ifdef CONFIG_E500 | 906 | #ifdef CONFIG_FSL_BOOKE |
907 | { /* e200z5 */ | ||
908 | .pvr_mask = 0xfff00000, | ||
909 | .pvr_value = 0x81000000, | ||
910 | .cpu_name = "e200z5", | ||
911 | /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ | ||
912 | .cpu_features = CPU_FTR_USE_TB, | ||
913 | .cpu_user_features = PPC_FEATURE_32 | | ||
914 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_EFP_SINGLE | | ||
915 | PPC_FEATURE_UNIFIED_CACHE, | ||
916 | .dcache_bsize = 32, | ||
917 | }, | ||
918 | { /* e200z6 */ | ||
919 | .pvr_mask = 0xfff00000, | ||
920 | .pvr_value = 0x81100000, | ||
921 | .cpu_name = "e200z6", | ||
922 | /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ | ||
923 | .cpu_features = CPU_FTR_USE_TB, | ||
924 | .cpu_user_features = PPC_FEATURE_32 | | ||
925 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP | | ||
926 | PPC_FEATURE_HAS_EFP_SINGLE | | ||
927 | PPC_FEATURE_UNIFIED_CACHE, | ||
928 | .dcache_bsize = 32, | ||
929 | }, | ||
907 | { /* e500 */ | 930 | { /* e500 */ |
908 | .pvr_mask = 0xffff0000, | 931 | .pvr_mask = 0xffff0000, |
909 | .pvr_value = 0x80200000, | 932 | .pvr_value = 0x80200000, |
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S index 8377b6ca26da..d4df68629cc6 100644 --- a/arch/ppc/kernel/entry.S +++ b/arch/ppc/kernel/entry.S | |||
@@ -60,6 +60,11 @@ mcheck_transfer_to_handler: | |||
60 | TRANSFER_TO_HANDLER_EXC_LEVEL(MCHECK) | 60 | TRANSFER_TO_HANDLER_EXC_LEVEL(MCHECK) |
61 | b transfer_to_handler_full | 61 | b transfer_to_handler_full |
62 | 62 | ||
63 | .globl debug_transfer_to_handler | ||
64 | debug_transfer_to_handler: | ||
65 | TRANSFER_TO_HANDLER_EXC_LEVEL(DEBUG) | ||
66 | b transfer_to_handler_full | ||
67 | |||
63 | .globl crit_transfer_to_handler | 68 | .globl crit_transfer_to_handler |
64 | crit_transfer_to_handler: | 69 | crit_transfer_to_handler: |
65 | TRANSFER_TO_HANDLER_EXC_LEVEL(CRIT) | 70 | TRANSFER_TO_HANDLER_EXC_LEVEL(CRIT) |
@@ -835,6 +840,10 @@ ret_from_crit_exc: | |||
835 | RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI) | 840 | RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI) |
836 | 841 | ||
837 | #ifdef CONFIG_BOOKE | 842 | #ifdef CONFIG_BOOKE |
843 | .globl ret_from_debug_exc | ||
844 | ret_from_debug_exc: | ||
845 | RET_FROM_EXC_LEVEL(SPRN_DSRR0, SPRN_DSRR1, RFDI) | ||
846 | |||
838 | .globl ret_from_mcheck_exc | 847 | .globl ret_from_mcheck_exc |
839 | ret_from_mcheck_exc: | 848 | ret_from_mcheck_exc: |
840 | RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, RFMCI) | 849 | RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, RFMCI) |
diff --git a/arch/ppc/kernel/head_booke.h b/arch/ppc/kernel/head_booke.h index 9c50f9d2657c..9342acf12e72 100644 --- a/arch/ppc/kernel/head_booke.h +++ b/arch/ppc/kernel/head_booke.h | |||
@@ -49,6 +49,7 @@ | |||
49 | * | 49 | * |
50 | * On 40x critical is the only additional level | 50 | * On 40x critical is the only additional level |
51 | * On 44x/e500 we have critical and machine check | 51 | * On 44x/e500 we have critical and machine check |
52 | * On e200 we have critical and debug (machine check occurs via critical) | ||
52 | * | 53 | * |
53 | * Additionally we reserve a SPRG for each priority level so we can free up a | 54 | * Additionally we reserve a SPRG for each priority level so we can free up a |
54 | * GPR to use as the base for indirect access to the exception stacks. This | 55 | * GPR to use as the base for indirect access to the exception stacks. This |
@@ -60,12 +61,16 @@ | |||
60 | 61 | ||
61 | /* CRIT_SPRG only used in critical exception handling */ | 62 | /* CRIT_SPRG only used in critical exception handling */ |
62 | #define CRIT_SPRG SPRN_SPRG2 | 63 | #define CRIT_SPRG SPRN_SPRG2 |
63 | /* MCHECK_SPRG only used in critical exception handling */ | 64 | /* MCHECK_SPRG only used in machine check exception handling */ |
64 | #define MCHECK_SPRG SPRN_SPRG6W | 65 | #define MCHECK_SPRG SPRN_SPRG6W |
65 | 66 | ||
66 | #define MCHECK_STACK_TOP (exception_stack_top - 4096) | 67 | #define MCHECK_STACK_TOP (exception_stack_top - 4096) |
67 | #define CRIT_STACK_TOP (exception_stack_top) | 68 | #define CRIT_STACK_TOP (exception_stack_top) |
68 | 69 | ||
70 | /* only on e200 for now */ | ||
71 | #define DEBUG_STACK_TOP (exception_stack_top - 4096) | ||
72 | #define DEBUG_SPRG SPRN_SPRG6W | ||
73 | |||
69 | #ifdef CONFIG_SMP | 74 | #ifdef CONFIG_SMP |
70 | #define BOOKE_LOAD_EXC_LEVEL_STACK(level) \ | 75 | #define BOOKE_LOAD_EXC_LEVEL_STACK(level) \ |
71 | mfspr r8,SPRN_PIR; \ | 76 | mfspr r8,SPRN_PIR; \ |
@@ -124,6 +129,8 @@ | |||
124 | 129 | ||
125 | #define CRITICAL_EXCEPTION_PROLOG \ | 130 | #define CRITICAL_EXCEPTION_PROLOG \ |
126 | EXC_LEVEL_EXCEPTION_PROLOG(CRIT, SPRN_CSRR0, SPRN_CSRR1) | 131 | EXC_LEVEL_EXCEPTION_PROLOG(CRIT, SPRN_CSRR0, SPRN_CSRR1) |
132 | #define DEBUG_EXCEPTION_PROLOG \ | ||
133 | EXC_LEVEL_EXCEPTION_PROLOG(DEBUG, SPRN_DSRR0, SPRN_DSRR1) | ||
127 | #define MCHECK_EXCEPTION_PROLOG \ | 134 | #define MCHECK_EXCEPTION_PROLOG \ |
128 | EXC_LEVEL_EXCEPTION_PROLOG(MCHECK, SPRN_MCSRR0, SPRN_MCSRR1) | 135 | EXC_LEVEL_EXCEPTION_PROLOG(MCHECK, SPRN_MCSRR0, SPRN_MCSRR1) |
129 | 136 | ||
@@ -205,6 +212,60 @@ label: | |||
205 | * save (and later restore) the MSR via SPRN_CSRR1, which will still have | 212 | * save (and later restore) the MSR via SPRN_CSRR1, which will still have |
206 | * the MSR_DE bit set. | 213 | * the MSR_DE bit set. |
207 | */ | 214 | */ |
215 | #ifdef CONFIG_E200 | ||
216 | #define DEBUG_EXCEPTION \ | ||
217 | START_EXCEPTION(Debug); \ | ||
218 | DEBUG_EXCEPTION_PROLOG; \ | ||
219 | \ | ||
220 | /* \ | ||
221 | * If there is a single step or branch-taken exception in an \ | ||
222 | * exception entry sequence, it was probably meant to apply to \ | ||
223 | * the code where the exception occurred (since exception entry \ | ||
224 | * doesn't turn off DE automatically). We simulate the effect \ | ||
225 | * of turning off DE on entry to an exception handler by turning \ | ||
226 | * off DE in the CSRR1 value and clearing the debug status. \ | ||
227 | */ \ | ||
228 | mfspr r10,SPRN_DBSR; /* check single-step/branch taken */ \ | ||
229 | andis. r10,r10,DBSR_IC@h; \ | ||
230 | beq+ 2f; \ | ||
231 | \ | ||
232 | lis r10,KERNELBASE@h; /* check if exception in vectors */ \ | ||
233 | ori r10,r10,KERNELBASE@l; \ | ||
234 | cmplw r12,r10; \ | ||
235 | blt+ 2f; /* addr below exception vectors */ \ | ||
236 | \ | ||
237 | lis r10,Debug@h; \ | ||
238 | ori r10,r10,Debug@l; \ | ||
239 | cmplw r12,r10; \ | ||
240 | bgt+ 2f; /* addr above exception vectors */ \ | ||
241 | \ | ||
242 | /* here it looks like we got an inappropriate debug exception. */ \ | ||
243 | 1: rlwinm r9,r9,0,~MSR_DE; /* clear DE in the CDRR1 value */ \ | ||
244 | lis r10,DBSR_IC@h; /* clear the IC event */ \ | ||
245 | mtspr SPRN_DBSR,r10; \ | ||
246 | /* restore state and get out */ \ | ||
247 | lwz r10,_CCR(r11); \ | ||
248 | lwz r0,GPR0(r11); \ | ||
249 | lwz r1,GPR1(r11); \ | ||
250 | mtcrf 0x80,r10; \ | ||
251 | mtspr SPRN_DSRR0,r12; \ | ||
252 | mtspr SPRN_DSRR1,r9; \ | ||
253 | lwz r9,GPR9(r11); \ | ||
254 | lwz r12,GPR12(r11); \ | ||
255 | mtspr DEBUG_SPRG,r8; \ | ||
256 | BOOKE_LOAD_EXC_LEVEL_STACK(DEBUG); /* r8 points to the debug stack */ \ | ||
257 | lwz r10,GPR10-INT_FRAME_SIZE(r8); \ | ||
258 | lwz r11,GPR11-INT_FRAME_SIZE(r8); \ | ||
259 | mfspr r8,DEBUG_SPRG; \ | ||
260 | \ | ||
261 | RFDI; \ | ||
262 | b .; \ | ||
263 | \ | ||
264 | /* continue normal handling for a critical exception... */ \ | ||
265 | 2: mfspr r4,SPRN_DBSR; \ | ||
266 | addi r3,r1,STACK_FRAME_OVERHEAD; \ | ||
267 | EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, debug_transfer_to_handler, ret_from_debug_exc) | ||
268 | #else | ||
208 | #define DEBUG_EXCEPTION \ | 269 | #define DEBUG_EXCEPTION \ |
209 | START_EXCEPTION(Debug); \ | 270 | START_EXCEPTION(Debug); \ |
210 | CRITICAL_EXCEPTION_PROLOG; \ | 271 | CRITICAL_EXCEPTION_PROLOG; \ |
@@ -257,6 +318,7 @@ label: | |||
257 | 2: mfspr r4,SPRN_DBSR; \ | 318 | 2: mfspr r4,SPRN_DBSR; \ |
258 | addi r3,r1,STACK_FRAME_OVERHEAD; \ | 319 | addi r3,r1,STACK_FRAME_OVERHEAD; \ |
259 | EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, crit_transfer_to_handler, ret_from_crit_exc) | 320 | EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, crit_transfer_to_handler, ret_from_crit_exc) |
321 | #endif | ||
260 | 322 | ||
261 | #define INSTRUCTION_STORAGE_EXCEPTION \ | 323 | #define INSTRUCTION_STORAGE_EXCEPTION \ |
262 | START_EXCEPTION(InstructionStorage) \ | 324 | START_EXCEPTION(InstructionStorage) \ |
diff --git a/arch/ppc/kernel/head_fsl_booke.S b/arch/ppc/kernel/head_fsl_booke.S index ce36e88ba627..eb804b7a3cb2 100644 --- a/arch/ppc/kernel/head_fsl_booke.S +++ b/arch/ppc/kernel/head_fsl_booke.S | |||
@@ -102,6 +102,7 @@ invstr: mflr r6 /* Make it accessible */ | |||
102 | or r7,r7,r4 | 102 | or r7,r7,r4 |
103 | mtspr SPRN_MAS6,r7 | 103 | mtspr SPRN_MAS6,r7 |
104 | tlbsx 0,r6 /* search MSR[IS], SPID=PID0 */ | 104 | tlbsx 0,r6 /* search MSR[IS], SPID=PID0 */ |
105 | #ifndef CONFIG_E200 | ||
105 | mfspr r7,SPRN_MAS1 | 106 | mfspr r7,SPRN_MAS1 |
106 | andis. r7,r7,MAS1_VALID@h | 107 | andis. r7,r7,MAS1_VALID@h |
107 | bne match_TLB | 108 | bne match_TLB |
@@ -118,6 +119,7 @@ invstr: mflr r6 /* Make it accessible */ | |||
118 | or r7,r7,r4 | 119 | or r7,r7,r4 |
119 | mtspr SPRN_MAS6,r7 | 120 | mtspr SPRN_MAS6,r7 |
120 | tlbsx 0,r6 /* Fall through, we had to match */ | 121 | tlbsx 0,r6 /* Fall through, we had to match */ |
122 | #endif | ||
121 | match_TLB: | 123 | match_TLB: |
122 | mfspr r7,SPRN_MAS0 | 124 | mfspr r7,SPRN_MAS0 |
123 | rlwinm r3,r7,16,20,31 /* Extract MAS0(Entry) */ | 125 | rlwinm r3,r7,16,20,31 /* Extract MAS0(Entry) */ |
@@ -196,8 +198,10 @@ skpinv: addi r6,r6,1 /* Increment */ | |||
196 | /* 4. Clear out PIDs & Search info */ | 198 | /* 4. Clear out PIDs & Search info */ |
197 | li r6,0 | 199 | li r6,0 |
198 | mtspr SPRN_PID0,r6 | 200 | mtspr SPRN_PID0,r6 |
201 | #ifndef CONFIG_E200 | ||
199 | mtspr SPRN_PID1,r6 | 202 | mtspr SPRN_PID1,r6 |
200 | mtspr SPRN_PID2,r6 | 203 | mtspr SPRN_PID2,r6 |
204 | #endif | ||
201 | mtspr SPRN_MAS6,r6 | 205 | mtspr SPRN_MAS6,r6 |
202 | 206 | ||
203 | /* 5. Invalidate mapping we started in */ | 207 | /* 5. Invalidate mapping we started in */ |
@@ -277,7 +281,9 @@ skpinv: addi r6,r6,1 /* Increment */ | |||
277 | SET_IVOR(32, SPEUnavailable); | 281 | SET_IVOR(32, SPEUnavailable); |
278 | SET_IVOR(33, SPEFloatingPointData); | 282 | SET_IVOR(33, SPEFloatingPointData); |
279 | SET_IVOR(34, SPEFloatingPointRound); | 283 | SET_IVOR(34, SPEFloatingPointRound); |
284 | #ifndef CONFIG_E200 | ||
280 | SET_IVOR(35, PerformanceMonitor); | 285 | SET_IVOR(35, PerformanceMonitor); |
286 | #endif | ||
281 | 287 | ||
282 | /* Establish the interrupt vector base */ | 288 | /* Establish the interrupt vector base */ |
283 | lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */ | 289 | lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */ |
@@ -285,6 +291,9 @@ skpinv: addi r6,r6,1 /* Increment */ | |||
285 | 291 | ||
286 | /* Setup the defaults for TLB entries */ | 292 | /* Setup the defaults for TLB entries */ |
287 | li r2,(MAS4_TSIZED(BOOKE_PAGESZ_4K))@l | 293 | li r2,(MAS4_TSIZED(BOOKE_PAGESZ_4K))@l |
294 | #ifdef CONFIG_E200 | ||
295 | oris r2,r2,MAS4_TLBSELD(1)@h | ||
296 | #endif | ||
288 | mtspr SPRN_MAS4, r2 | 297 | mtspr SPRN_MAS4, r2 |
289 | 298 | ||
290 | #if 0 | 299 | #if 0 |
@@ -293,6 +302,12 @@ skpinv: addi r6,r6,1 /* Increment */ | |||
293 | oris r2,r2,HID0_DOZE@h | 302 | oris r2,r2,HID0_DOZE@h |
294 | mtspr SPRN_HID0, r2 | 303 | mtspr SPRN_HID0, r2 |
295 | #endif | 304 | #endif |
305 | #ifdef CONFIG_E200 | ||
306 | /* enable dedicated debug exception handling resources (Debug APU) */ | ||
307 | mfspr r2,SPRN_HID0 | ||
308 | ori r2,r2,HID0_DAPUEN@l | ||
309 | mtspr SPRN_HID0,r2 | ||
310 | #endif | ||
296 | 311 | ||
297 | #if !defined(CONFIG_BDI_SWITCH) | 312 | #if !defined(CONFIG_BDI_SWITCH) |
298 | /* | 313 | /* |
@@ -414,7 +429,12 @@ interrupt_base: | |||
414 | CRITICAL_EXCEPTION(0x0100, CriticalInput, UnknownException) | 429 | CRITICAL_EXCEPTION(0x0100, CriticalInput, UnknownException) |
415 | 430 | ||
416 | /* Machine Check Interrupt */ | 431 | /* Machine Check Interrupt */ |
432 | #ifdef CONFIG_E200 | ||
433 | /* no RFMCI, MCSRRs on E200 */ | ||
434 | CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException) | ||
435 | #else | ||
417 | MCHECK_EXCEPTION(0x0200, MachineCheck, MachineCheckException) | 436 | MCHECK_EXCEPTION(0x0200, MachineCheck, MachineCheckException) |
437 | #endif | ||
418 | 438 | ||
419 | /* Data Storage Interrupt */ | 439 | /* Data Storage Interrupt */ |
420 | START_EXCEPTION(DataStorage) | 440 | START_EXCEPTION(DataStorage) |
@@ -520,8 +540,13 @@ interrupt_base: | |||
520 | #ifdef CONFIG_PPC_FPU | 540 | #ifdef CONFIG_PPC_FPU |
521 | FP_UNAVAILABLE_EXCEPTION | 541 | FP_UNAVAILABLE_EXCEPTION |
522 | #else | 542 | #else |
543 | #ifdef CONFIG_E200 | ||
544 | /* E200 treats 'normal' floating point instructions as FP Unavail exception */ | ||
545 | EXCEPTION(0x0800, FloatingPointUnavailable, ProgramCheckException, EXC_XFER_EE) | ||
546 | #else | ||
523 | EXCEPTION(0x0800, FloatingPointUnavailable, UnknownException, EXC_XFER_EE) | 547 | EXCEPTION(0x0800, FloatingPointUnavailable, UnknownException, EXC_XFER_EE) |
524 | #endif | 548 | #endif |
549 | #endif | ||
525 | 550 | ||
526 | /* System Call Interrupt */ | 551 | /* System Call Interrupt */ |
527 | START_EXCEPTION(SystemCall) | 552 | START_EXCEPTION(SystemCall) |
@@ -691,6 +716,7 @@ interrupt_base: | |||
691 | /* | 716 | /* |
692 | * Local functions | 717 | * Local functions |
693 | */ | 718 | */ |
719 | |||
694 | /* | 720 | /* |
695 | * Data TLB exceptions will bail out to this point | 721 | * Data TLB exceptions will bail out to this point |
696 | * if they can't resolve the lightweight TLB fault. | 722 | * if they can't resolve the lightweight TLB fault. |
@@ -761,6 +787,31 @@ END_FTR_SECTION_IFSET(CPU_FTR_BIG_PHYS) | |||
761 | 2: rlwimi r11, r12, 0, 20, 31 /* Extract RPN from PTE and merge with perms */ | 787 | 2: rlwimi r11, r12, 0, 20, 31 /* Extract RPN from PTE and merge with perms */ |
762 | mtspr SPRN_MAS3, r11 | 788 | mtspr SPRN_MAS3, r11 |
763 | #endif | 789 | #endif |
790 | #ifdef CONFIG_E200 | ||
791 | /* Round robin TLB1 entries assignment */ | ||
792 | mfspr r12, SPRN_MAS0 | ||
793 | |||
794 | /* Extract TLB1CFG(NENTRY) */ | ||
795 | mfspr r11, SPRN_TLB1CFG | ||
796 | andi. r11, r11, 0xfff | ||
797 | |||
798 | /* Extract MAS0(NV) */ | ||
799 | andi. r13, r12, 0xfff | ||
800 | addi r13, r13, 1 | ||
801 | cmpw 0, r13, r11 | ||
802 | addi r12, r12, 1 | ||
803 | |||
804 | /* check if we need to wrap */ | ||
805 | blt 7f | ||
806 | |||
807 | /* wrap back to first free tlbcam entry */ | ||
808 | lis r13, tlbcam_index@ha | ||
809 | lwz r13, tlbcam_index@l(r13) | ||
810 | rlwimi r12, r13, 0, 20, 31 | ||
811 | 7: | ||
812 | mtspr SPRN_MAS0,r12 | ||
813 | #endif /* CONFIG_E200 */ | ||
814 | |||
764 | tlbwe | 815 | tlbwe |
765 | 816 | ||
766 | /* Done...restore registers and get out of here. */ | 817 | /* Done...restore registers and get out of here. */ |
diff --git a/arch/ppc/kernel/machine_kexec.c b/arch/ppc/kernel/machine_kexec.c new file mode 100644 index 000000000000..84d65a87191e --- /dev/null +++ b/arch/ppc/kernel/machine_kexec.c | |||
@@ -0,0 +1,118 @@ | |||
1 | /* | ||
2 | * machine_kexec.c - handle transition of Linux booting another kernel | ||
3 | * Copyright (C) 2002-2003 Eric Biederman <ebiederm@xmission.com> | ||
4 | * | ||
5 | * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz | ||
6 | * | ||
7 | * This source code is licensed under the GNU General Public License, | ||
8 | * Version 2. See the file COPYING for more details. | ||
9 | */ | ||
10 | |||
11 | #include <linux/mm.h> | ||
12 | #include <linux/kexec.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <linux/reboot.h> | ||
15 | #include <asm/pgtable.h> | ||
16 | #include <asm/pgalloc.h> | ||
17 | #include <asm/mmu_context.h> | ||
18 | #include <asm/io.h> | ||
19 | #include <asm/hw_irq.h> | ||
20 | #include <asm/cacheflush.h> | ||
21 | #include <asm/machdep.h> | ||
22 | |||
23 | typedef NORET_TYPE void (*relocate_new_kernel_t)( | ||
24 | unsigned long indirection_page, | ||
25 | unsigned long reboot_code_buffer, | ||
26 | unsigned long start_address) ATTRIB_NORET; | ||
27 | |||
28 | const extern unsigned char relocate_new_kernel[]; | ||
29 | const extern unsigned int relocate_new_kernel_size; | ||
30 | |||
31 | void machine_shutdown(void) | ||
32 | { | ||
33 | if (ppc_md.machine_shutdown) | ||
34 | ppc_md.machine_shutdown(); | ||
35 | } | ||
36 | |||
37 | void machine_crash_shutdown(struct pt_regs *regs) | ||
38 | { | ||
39 | if (ppc_md.machine_crash_shutdown) | ||
40 | ppc_md.machine_crash_shutdown(); | ||
41 | } | ||
42 | |||
43 | /* | ||
44 | * Do what every setup is needed on image and the | ||
45 | * reboot code buffer to allow us to avoid allocations | ||
46 | * later. | ||
47 | */ | ||
48 | int machine_kexec_prepare(struct kimage *image) | ||
49 | { | ||
50 | if (ppc_md.machine_kexec_prepare) | ||
51 | return ppc_md.machine_kexec_prepare(image); | ||
52 | /* | ||
53 | * Fail if platform doesn't provide its own machine_kexec_prepare | ||
54 | * implementation. | ||
55 | */ | ||
56 | return -ENOSYS; | ||
57 | } | ||
58 | |||
59 | void machine_kexec_cleanup(struct kimage *image) | ||
60 | { | ||
61 | if (ppc_md.machine_kexec_cleanup) | ||
62 | ppc_md.machine_kexec_cleanup(image); | ||
63 | } | ||
64 | |||
65 | /* | ||
66 | * Do not allocate memory (or fail in any way) in machine_kexec(). | ||
67 | * We are past the point of no return, committed to rebooting now. | ||
68 | */ | ||
69 | NORET_TYPE void machine_kexec(struct kimage *image) | ||
70 | { | ||
71 | if (ppc_md.machine_kexec) | ||
72 | ppc_md.machine_kexec(image); | ||
73 | else { | ||
74 | /* | ||
75 | * Fall back to normal restart if platform doesn't provide | ||
76 | * its own kexec function, and user insist to kexec... | ||
77 | */ | ||
78 | machine_restart(NULL); | ||
79 | } | ||
80 | for(;;); | ||
81 | } | ||
82 | |||
83 | /* | ||
84 | * This is a generic machine_kexec function suitable at least for | ||
85 | * non-OpenFirmware embedded platforms. | ||
86 | * It merely copies the image relocation code to the control page and | ||
87 | * jumps to it. | ||
88 | * A platform specific function may just call this one. | ||
89 | */ | ||
90 | void machine_kexec_simple(struct kimage *image) | ||
91 | { | ||
92 | unsigned long page_list; | ||
93 | unsigned long reboot_code_buffer, reboot_code_buffer_phys; | ||
94 | relocate_new_kernel_t rnk; | ||
95 | |||
96 | /* Interrupts aren't acceptable while we reboot */ | ||
97 | local_irq_disable(); | ||
98 | |||
99 | page_list = image->head; | ||
100 | |||
101 | /* we need both effective and real address here */ | ||
102 | reboot_code_buffer = | ||
103 | (unsigned long)page_address(image->control_code_page); | ||
104 | reboot_code_buffer_phys = virt_to_phys((void *)reboot_code_buffer); | ||
105 | |||
106 | /* copy our kernel relocation code to the control code page */ | ||
107 | memcpy((void *)reboot_code_buffer, relocate_new_kernel, | ||
108 | relocate_new_kernel_size); | ||
109 | |||
110 | flush_icache_range(reboot_code_buffer, | ||
111 | reboot_code_buffer + KEXEC_CONTROL_CODE_SIZE); | ||
112 | printk(KERN_INFO "Bye!\n"); | ||
113 | |||
114 | /* now call it */ | ||
115 | rnk = (relocate_new_kernel_t) reboot_code_buffer; | ||
116 | (*rnk)(page_list, reboot_code_buffer_phys, image->start); | ||
117 | } | ||
118 | |||
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 7329ef177a18..b6a63a49a232 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S | |||
@@ -593,6 +593,14 @@ _GLOBAL(flush_instruction_cache) | |||
593 | iccci 0,r3 | 593 | iccci 0,r3 |
594 | #endif | 594 | #endif |
595 | #elif CONFIG_FSL_BOOKE | 595 | #elif CONFIG_FSL_BOOKE |
596 | BEGIN_FTR_SECTION | ||
597 | mfspr r3,SPRN_L1CSR0 | ||
598 | ori r3,r3,L1CSR0_CFI|L1CSR0_CLFC | ||
599 | /* msync; isync recommended here */ | ||
600 | mtspr SPRN_L1CSR0,r3 | ||
601 | isync | ||
602 | blr | ||
603 | END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) | ||
596 | mfspr r3,SPRN_L1CSR1 | 604 | mfspr r3,SPRN_L1CSR1 |
597 | ori r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR | 605 | ori r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR |
598 | mtspr SPRN_L1CSR1,r3 | 606 | mtspr SPRN_L1CSR1,r3 |
@@ -1436,7 +1444,7 @@ _GLOBAL(sys_call_table) | |||
1436 | .long sys_mq_timedreceive /* 265 */ | 1444 | .long sys_mq_timedreceive /* 265 */ |
1437 | .long sys_mq_notify | 1445 | .long sys_mq_notify |
1438 | .long sys_mq_getsetattr | 1446 | .long sys_mq_getsetattr |
1439 | .long sys_ni_syscall /* 268 reserved for sys_kexec_load */ | 1447 | .long sys_kexec_load |
1440 | .long sys_add_key | 1448 | .long sys_add_key |
1441 | .long sys_request_key /* 270 */ | 1449 | .long sys_request_key /* 270 */ |
1442 | .long sys_keyctl | 1450 | .long sys_keyctl |
diff --git a/arch/ppc/kernel/perfmon.c b/arch/ppc/kernel/perfmon.c index 918f6b252e45..fa1dad96b830 100644 --- a/arch/ppc/kernel/perfmon.c +++ b/arch/ppc/kernel/perfmon.c | |||
@@ -36,7 +36,7 @@ | |||
36 | /* A lock to regulate grabbing the interrupt */ | 36 | /* A lock to regulate grabbing the interrupt */ |
37 | DEFINE_SPINLOCK(perfmon_lock); | 37 | DEFINE_SPINLOCK(perfmon_lock); |
38 | 38 | ||
39 | #ifdef CONFIG_FSL_BOOKE | 39 | #if defined (CONFIG_FSL_BOOKE) && !defined (CONFIG_E200) |
40 | static void dummy_perf(struct pt_regs *regs) | 40 | static void dummy_perf(struct pt_regs *regs) |
41 | { | 41 | { |
42 | unsigned int pmgc0 = mfpmr(PMRN_PMGC0); | 42 | unsigned int pmgc0 = mfpmr(PMRN_PMGC0); |
diff --git a/arch/ppc/kernel/relocate_kernel.S b/arch/ppc/kernel/relocate_kernel.S new file mode 100644 index 000000000000..7ff69c4af920 --- /dev/null +++ b/arch/ppc/kernel/relocate_kernel.S | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | * relocate_kernel.S - put the kernel image in place to boot | ||
3 | * Copyright (C) 2002-2003 Eric Biederman <ebiederm@xmission.com> | ||
4 | * | ||
5 | * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz | ||
6 | * | ||
7 | * This source code is licensed under the GNU General Public License, | ||
8 | * Version 2. See the file COPYING for more details. | ||
9 | */ | ||
10 | |||
11 | #include <asm/reg.h> | ||
12 | #include <asm/ppc_asm.h> | ||
13 | #include <asm/processor.h> | ||
14 | |||
15 | #include <asm/kexec.h> | ||
16 | |||
17 | #define PAGE_SIZE 4096 /* must be same value as in <asm/page.h> */ | ||
18 | |||
19 | /* | ||
20 | * Must be relocatable PIC code callable as a C function. | ||
21 | */ | ||
22 | .globl relocate_new_kernel | ||
23 | relocate_new_kernel: | ||
24 | /* r3 = page_list */ | ||
25 | /* r4 = reboot_code_buffer */ | ||
26 | /* r5 = start_address */ | ||
27 | |||
28 | li r0, 0 | ||
29 | |||
30 | /* | ||
31 | * Set Machine Status Register to a known status, | ||
32 | * switch the MMU off and jump to 1: in a single step. | ||
33 | */ | ||
34 | |||
35 | mr r8, r0 | ||
36 | ori r8, r8, MSR_RI|MSR_ME | ||
37 | mtspr SRR1, r8 | ||
38 | addi r8, r4, 1f - relocate_new_kernel | ||
39 | mtspr SRR0, r8 | ||
40 | sync | ||
41 | rfi | ||
42 | |||
43 | 1: | ||
44 | /* from this point address translation is turned off */ | ||
45 | /* and interrupts are disabled */ | ||
46 | |||
47 | /* set a new stack at the bottom of our page... */ | ||
48 | /* (not really needed now) */ | ||
49 | addi r1, r4, KEXEC_CONTROL_CODE_SIZE - 8 /* for LR Save+Back Chain */ | ||
50 | stw r0, 0(r1) | ||
51 | |||
52 | /* Do the copies */ | ||
53 | li r6, 0 /* checksum */ | ||
54 | mr r0, r3 | ||
55 | b 1f | ||
56 | |||
57 | 0: /* top, read another word for the indirection page */ | ||
58 | lwzu r0, 4(r3) | ||
59 | |||
60 | 1: | ||
61 | /* is it a destination page? (r8) */ | ||
62 | rlwinm. r7, r0, 0, 31, 31 /* IND_DESTINATION (1<<0) */ | ||
63 | beq 2f | ||
64 | |||
65 | rlwinm r8, r0, 0, 0, 19 /* clear kexec flags, page align */ | ||
66 | b 0b | ||
67 | |||
68 | 2: /* is it an indirection page? (r3) */ | ||
69 | rlwinm. r7, r0, 0, 30, 30 /* IND_INDIRECTION (1<<1) */ | ||
70 | beq 2f | ||
71 | |||
72 | rlwinm r3, r0, 0, 0, 19 /* clear kexec flags, page align */ | ||
73 | subi r3, r3, 4 | ||
74 | b 0b | ||
75 | |||
76 | 2: /* are we done? */ | ||
77 | rlwinm. r7, r0, 0, 29, 29 /* IND_DONE (1<<2) */ | ||
78 | beq 2f | ||
79 | b 3f | ||
80 | |||
81 | 2: /* is it a source page? (r9) */ | ||
82 | rlwinm. r7, r0, 0, 28, 28 /* IND_SOURCE (1<<3) */ | ||
83 | beq 0b | ||
84 | |||
85 | rlwinm r9, r0, 0, 0, 19 /* clear kexec flags, page align */ | ||
86 | |||
87 | li r7, PAGE_SIZE / 4 | ||
88 | mtctr r7 | ||
89 | subi r9, r9, 4 | ||
90 | subi r8, r8, 4 | ||
91 | 9: | ||
92 | lwzu r0, 4(r9) /* do the copy */ | ||
93 | xor r6, r6, r0 | ||
94 | stwu r0, 4(r8) | ||
95 | dcbst 0, r8 | ||
96 | sync | ||
97 | icbi 0, r8 | ||
98 | bdnz 9b | ||
99 | |||
100 | addi r9, r9, 4 | ||
101 | addi r8, r8, 4 | ||
102 | b 0b | ||
103 | |||
104 | 3: | ||
105 | |||
106 | /* To be certain of avoiding problems with self-modifying code | ||
107 | * execute a serializing instruction here. | ||
108 | */ | ||
109 | isync | ||
110 | sync | ||
111 | |||
112 | /* jump to the entry point, usually the setup routine */ | ||
113 | mtlr r5 | ||
114 | blrl | ||
115 | |||
116 | 1: b 1b | ||
117 | |||
118 | relocate_new_kernel_end: | ||
119 | |||
120 | .globl relocate_new_kernel_size | ||
121 | relocate_new_kernel_size: | ||
122 | .long relocate_new_kernel_end - relocate_new_kernel | ||
123 | |||
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index 2ca8ecfeefd9..9e6ae5696650 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c | |||
@@ -173,13 +173,13 @@ static inline int check_io_access(struct pt_regs *regs) | |||
173 | /* On 4xx, the reason for the machine check or program exception | 173 | /* On 4xx, the reason for the machine check or program exception |
174 | is in the ESR. */ | 174 | is in the ESR. */ |
175 | #define get_reason(regs) ((regs)->dsisr) | 175 | #define get_reason(regs) ((regs)->dsisr) |
176 | #ifndef CONFIG_E500 | 176 | #ifndef CONFIG_FSL_BOOKE |
177 | #define get_mc_reason(regs) ((regs)->dsisr) | 177 | #define get_mc_reason(regs) ((regs)->dsisr) |
178 | #else | 178 | #else |
179 | #define get_mc_reason(regs) (mfspr(SPRN_MCSR)) | 179 | #define get_mc_reason(regs) (mfspr(SPRN_MCSR)) |
180 | #endif | 180 | #endif |
181 | #define REASON_FP ESR_FP | 181 | #define REASON_FP ESR_FP |
182 | #define REASON_ILLEGAL ESR_PIL | 182 | #define REASON_ILLEGAL (ESR_PIL | ESR_PUO) |
183 | #define REASON_PRIVILEGED ESR_PPR | 183 | #define REASON_PRIVILEGED ESR_PPR |
184 | #define REASON_TRAP ESR_PTR | 184 | #define REASON_TRAP ESR_PTR |
185 | 185 | ||
@@ -302,7 +302,25 @@ void MachineCheckException(struct pt_regs *regs) | |||
302 | printk("Bus - Instruction Parity Error\n"); | 302 | printk("Bus - Instruction Parity Error\n"); |
303 | if (reason & MCSR_BUS_RPERR) | 303 | if (reason & MCSR_BUS_RPERR) |
304 | printk("Bus - Read Parity Error\n"); | 304 | printk("Bus - Read Parity Error\n"); |
305 | #else /* !CONFIG_4xx && !CONFIG_E500 */ | 305 | #elif defined (CONFIG_E200) |
306 | printk("Machine check in kernel mode.\n"); | ||
307 | printk("Caused by (from MCSR=%lx): ", reason); | ||
308 | |||
309 | if (reason & MCSR_MCP) | ||
310 | printk("Machine Check Signal\n"); | ||
311 | if (reason & MCSR_CP_PERR) | ||
312 | printk("Cache Push Parity Error\n"); | ||
313 | if (reason & MCSR_CPERR) | ||
314 | printk("Cache Parity Error\n"); | ||
315 | if (reason & MCSR_EXCP_ERR) | ||
316 | printk("ISI, ITLB, or Bus Error on first instruction fetch for an exception handler\n"); | ||
317 | if (reason & MCSR_BUS_IRERR) | ||
318 | printk("Bus - Read Bus Error on instruction fetch\n"); | ||
319 | if (reason & MCSR_BUS_DRERR) | ||
320 | printk("Bus - Read Bus Error on data load\n"); | ||
321 | if (reason & MCSR_BUS_WRERR) | ||
322 | printk("Bus - Write Bus Error on buffered store or cache line push\n"); | ||
323 | #else /* !CONFIG_4xx && !CONFIG_E500 && !CONFIG_E200 */ | ||
306 | printk("Machine check in kernel mode.\n"); | 324 | printk("Machine check in kernel mode.\n"); |
307 | printk("Caused by (from SRR1=%lx): ", reason); | 325 | printk("Caused by (from SRR1=%lx): ", reason); |
308 | switch (reason & 0x601F0000) { | 326 | switch (reason & 0x601F0000) { |
diff --git a/arch/ppc/mm/44x_mmu.c b/arch/ppc/mm/44x_mmu.c index 72f7c0d1c0ed..3d79ce281b67 100644 --- a/arch/ppc/mm/44x_mmu.c +++ b/arch/ppc/mm/44x_mmu.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include <linux/vmalloc.h> | 39 | #include <linux/vmalloc.h> |
40 | #include <linux/init.h> | 40 | #include <linux/init.h> |
41 | #include <linux/delay.h> | 41 | #include <linux/delay.h> |
42 | #include <linux/bootmem.h> | ||
43 | #include <linux/highmem.h> | 42 | #include <linux/highmem.h> |
44 | 43 | ||
45 | #include <asm/pgalloc.h> | 44 | #include <asm/pgalloc.h> |
diff --git a/arch/ppc/mm/4xx_mmu.c b/arch/ppc/mm/4xx_mmu.c index a7f616140381..b7bcbc232f39 100644 --- a/arch/ppc/mm/4xx_mmu.c +++ b/arch/ppc/mm/4xx_mmu.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/vmalloc.h> | 36 | #include <linux/vmalloc.h> |
37 | #include <linux/init.h> | 37 | #include <linux/init.h> |
38 | #include <linux/delay.h> | 38 | #include <linux/delay.h> |
39 | #include <linux/bootmem.h> | ||
40 | #include <linux/highmem.h> | 39 | #include <linux/highmem.h> |
41 | 40 | ||
42 | #include <asm/pgalloc.h> | 41 | #include <asm/pgalloc.h> |
diff --git a/arch/ppc/mm/fsl_booke_mmu.c b/arch/ppc/mm/fsl_booke_mmu.c index e07990efa046..af9ca0eb6d55 100644 --- a/arch/ppc/mm/fsl_booke_mmu.c +++ b/arch/ppc/mm/fsl_booke_mmu.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #include <linux/vmalloc.h> | 41 | #include <linux/vmalloc.h> |
42 | #include <linux/init.h> | 42 | #include <linux/init.h> |
43 | #include <linux/delay.h> | 43 | #include <linux/delay.h> |
44 | #include <linux/bootmem.h> | ||
45 | #include <linux/highmem.h> | 44 | #include <linux/highmem.h> |
46 | 45 | ||
47 | #include <asm/pgalloc.h> | 46 | #include <asm/pgalloc.h> |
@@ -126,7 +125,7 @@ void settlbcam(int index, unsigned long virt, phys_addr_t phys, | |||
126 | flags |= _PAGE_COHERENT; | 125 | flags |= _PAGE_COHERENT; |
127 | #endif | 126 | #endif |
128 | 127 | ||
129 | TLBCAM[index].MAS0 = MAS0_TLBSEL(1) | MAS0_ESEL(index); | 128 | TLBCAM[index].MAS0 = MAS0_TLBSEL(1) | MAS0_ESEL(index) | MAS0_NV(index+1); |
130 | TLBCAM[index].MAS1 = MAS1_VALID | MAS1_IPROT | MAS1_TSIZE(tsize) | MAS1_TID(pid); | 129 | TLBCAM[index].MAS1 = MAS1_VALID | MAS1_IPROT | MAS1_TSIZE(tsize) | MAS1_TID(pid); |
131 | TLBCAM[index].MAS2 = virt & PAGE_MASK; | 130 | TLBCAM[index].MAS2 = virt & PAGE_MASK; |
132 | 131 | ||
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c index 37ece1542799..ddd04d4c1ea9 100644 --- a/arch/ppc/platforms/83xx/mpc834x_sys.c +++ b/arch/ppc/platforms/83xx/mpc834x_sys.c | |||
@@ -94,20 +94,24 @@ mpc834x_sys_setup_arch(void) | |||
94 | 94 | ||
95 | /* setup the board related information for the enet controllers */ | 95 | /* setup the board related information for the enet controllers */ |
96 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC1); | 96 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC1); |
97 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 97 | if (pdata) { |
98 | pdata->interruptPHY = MPC83xx_IRQ_EXT1; | 98 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
99 | pdata->phyid = 0; | 99 | pdata->interruptPHY = MPC83xx_IRQ_EXT1; |
100 | /* fixup phy address */ | 100 | pdata->phyid = 0; |
101 | pdata->phy_reg_addr += binfo->bi_immr_base; | 101 | /* fixup phy address */ |
102 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | 102 | pdata->phy_reg_addr += binfo->bi_immr_base; |
103 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | ||
104 | } | ||
103 | 105 | ||
104 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC2); | 106 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC2); |
105 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 107 | if (pdata) { |
106 | pdata->interruptPHY = MPC83xx_IRQ_EXT2; | 108 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
107 | pdata->phyid = 1; | 109 | pdata->interruptPHY = MPC83xx_IRQ_EXT2; |
108 | /* fixup phy address */ | 110 | pdata->phyid = 1; |
109 | pdata->phy_reg_addr += binfo->bi_immr_base; | 111 | /* fixup phy address */ |
110 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | 112 | pdata->phy_reg_addr += binfo->bi_immr_base; |
113 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | ||
114 | } | ||
111 | 115 | ||
112 | #ifdef CONFIG_BLK_DEV_INITRD | 116 | #ifdef CONFIG_BLK_DEV_INITRD |
113 | if (initrd_start) | 117 | if (initrd_start) |
diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c index a2ed611cd936..ddd2e9a5bb12 100644 --- a/arch/ppc/platforms/85xx/mpc8540_ads.c +++ b/arch/ppc/platforms/85xx/mpc8540_ads.c | |||
@@ -92,28 +92,34 @@ mpc8540ads_setup_arch(void) | |||
92 | 92 | ||
93 | /* setup the board related information for the enet controllers */ | 93 | /* setup the board related information for the enet controllers */ |
94 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); | 94 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); |
95 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 95 | if (pdata) { |
96 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; | 96 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
97 | pdata->phyid = 0; | 97 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; |
98 | /* fixup phy address */ | 98 | pdata->phyid = 0; |
99 | pdata->phy_reg_addr += binfo->bi_immr_base; | 99 | /* fixup phy address */ |
100 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | 100 | pdata->phy_reg_addr += binfo->bi_immr_base; |
101 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | ||
102 | } | ||
101 | 103 | ||
102 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); | 104 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); |
103 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 105 | if (pdata) { |
104 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; | 106 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
105 | pdata->phyid = 1; | 107 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; |
106 | /* fixup phy address */ | 108 | pdata->phyid = 1; |
107 | pdata->phy_reg_addr += binfo->bi_immr_base; | 109 | /* fixup phy address */ |
108 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | 110 | pdata->phy_reg_addr += binfo->bi_immr_base; |
109 | 111 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | |
110 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC); | 112 | } |
111 | pdata->board_flags = 0; | 113 | |
112 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; | 114 | if (pdata) { |
113 | pdata->phyid = 3; | 115 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC); |
114 | /* fixup phy address */ | 116 | pdata->board_flags = 0; |
115 | pdata->phy_reg_addr += binfo->bi_immr_base; | 117 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; |
116 | memcpy(pdata->mac_addr, binfo->bi_enet2addr, 6); | 118 | pdata->phyid = 3; |
119 | /* fixup phy address */ | ||
120 | pdata->phy_reg_addr += binfo->bi_immr_base; | ||
121 | memcpy(pdata->mac_addr, binfo->bi_enet2addr, 6); | ||
122 | } | ||
117 | 123 | ||
118 | #ifdef CONFIG_BLK_DEV_INITRD | 124 | #ifdef CONFIG_BLK_DEV_INITRD |
119 | if (initrd_start) | 125 | if (initrd_start) |
diff --git a/arch/ppc/platforms/85xx/mpc8560_ads.c b/arch/ppc/platforms/85xx/mpc8560_ads.c index d87dfd5ce0a2..e18380258b68 100644 --- a/arch/ppc/platforms/85xx/mpc8560_ads.c +++ b/arch/ppc/platforms/85xx/mpc8560_ads.c | |||
@@ -90,20 +90,24 @@ mpc8560ads_setup_arch(void) | |||
90 | 90 | ||
91 | /* setup the board related information for the enet controllers */ | 91 | /* setup the board related information for the enet controllers */ |
92 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); | 92 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); |
93 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 93 | if (pdata) { |
94 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; | 94 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
95 | pdata->phyid = 0; | 95 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; |
96 | /* fixup phy address */ | 96 | pdata->phyid = 0; |
97 | pdata->phy_reg_addr += binfo->bi_immr_base; | 97 | /* fixup phy address */ |
98 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | 98 | pdata->phy_reg_addr += binfo->bi_immr_base; |
99 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | ||
100 | } | ||
99 | 101 | ||
100 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); | 102 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); |
101 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 103 | if (pdata) { |
102 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; | 104 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
103 | pdata->phyid = 1; | 105 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; |
104 | /* fixup phy address */ | 106 | pdata->phyid = 1; |
105 | pdata->phy_reg_addr += binfo->bi_immr_base; | 107 | /* fixup phy address */ |
106 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | 108 | pdata->phy_reg_addr += binfo->bi_immr_base; |
109 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | ||
110 | } | ||
107 | 111 | ||
108 | #ifdef CONFIG_BLK_DEV_INITRD | 112 | #ifdef CONFIG_BLK_DEV_INITRD |
109 | if (initrd_start) | 113 | if (initrd_start) |
diff --git a/arch/ppc/platforms/85xx/sbc8560.c b/arch/ppc/platforms/85xx/sbc8560.c index 3dbdd73618eb..165df94d4aa6 100644 --- a/arch/ppc/platforms/85xx/sbc8560.c +++ b/arch/ppc/platforms/85xx/sbc8560.c | |||
@@ -129,20 +129,24 @@ sbc8560_setup_arch(void) | |||
129 | 129 | ||
130 | /* setup the board related information for the enet controllers */ | 130 | /* setup the board related information for the enet controllers */ |
131 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); | 131 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); |
132 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 132 | if (pdata) { |
133 | pdata->interruptPHY = MPC85xx_IRQ_EXT6; | 133 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
134 | pdata->phyid = 25; | 134 | pdata->interruptPHY = MPC85xx_IRQ_EXT6; |
135 | /* fixup phy address */ | 135 | pdata->phyid = 25; |
136 | pdata->phy_reg_addr += binfo->bi_immr_base; | 136 | /* fixup phy address */ |
137 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | 137 | pdata->phy_reg_addr += binfo->bi_immr_base; |
138 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | ||
139 | } | ||
138 | 140 | ||
139 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); | 141 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); |
140 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 142 | if (pdata) { |
141 | pdata->interruptPHY = MPC85xx_IRQ_EXT7; | 143 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
142 | pdata->phyid = 26; | 144 | pdata->interruptPHY = MPC85xx_IRQ_EXT7; |
143 | /* fixup phy address */ | 145 | pdata->phyid = 26; |
144 | pdata->phy_reg_addr += binfo->bi_immr_base; | 146 | /* fixup phy address */ |
145 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | 147 | pdata->phy_reg_addr += binfo->bi_immr_base; |
148 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | ||
149 | } | ||
146 | 150 | ||
147 | #ifdef CONFIG_BLK_DEV_INITRD | 151 | #ifdef CONFIG_BLK_DEV_INITRD |
148 | if (initrd_start) | 152 | if (initrd_start) |
diff --git a/arch/ppc/platforms/85xx/stx_gp3.c b/arch/ppc/platforms/85xx/stx_gp3.c index 9455bb6b45e9..bb41265cfc85 100644 --- a/arch/ppc/platforms/85xx/stx_gp3.c +++ b/arch/ppc/platforms/85xx/stx_gp3.c | |||
@@ -122,19 +122,23 @@ gp3_setup_arch(void) | |||
122 | 122 | ||
123 | /* setup the board related information for the enet controllers */ | 123 | /* setup the board related information for the enet controllers */ |
124 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); | 124 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); |
125 | /* pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */ | 125 | if (pdata) { |
126 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; | 126 | /* pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */ |
127 | pdata->phyid = 2; | 127 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; |
128 | pdata->phy_reg_addr += binfo->bi_immr_base; | 128 | pdata->phyid = 2; |
129 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | 129 | pdata->phy_reg_addr += binfo->bi_immr_base; |
130 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | ||
131 | } | ||
130 | 132 | ||
131 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); | 133 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); |
132 | /* pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */ | 134 | if (pdata) { |
133 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; | 135 | /* pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */ |
134 | pdata->phyid = 4; | 136 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; |
135 | /* fixup phy address */ | 137 | pdata->phyid = 4; |
136 | pdata->phy_reg_addr += binfo->bi_immr_base; | 138 | /* fixup phy address */ |
137 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | 139 | pdata->phy_reg_addr += binfo->bi_immr_base; |
140 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | ||
141 | } | ||
138 | 142 | ||
139 | #ifdef CONFIG_BLK_DEV_INITRD | 143 | #ifdef CONFIG_BLK_DEV_INITRD |
140 | if (initrd_start) | 144 | if (initrd_start) |
diff --git a/arch/ppc/platforms/chrp_pci.c b/arch/ppc/platforms/chrp_pci.c index 7d0ee308f662..7d3fbb5c5db2 100644 --- a/arch/ppc/platforms/chrp_pci.c +++ b/arch/ppc/platforms/chrp_pci.c | |||
@@ -9,7 +9,6 @@ | |||
9 | #include <linux/string.h> | 9 | #include <linux/string.h> |
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | #include <linux/ide.h> | 11 | #include <linux/ide.h> |
12 | #include <linux/bootmem.h> | ||
13 | 12 | ||
14 | #include <asm/io.h> | 13 | #include <asm/io.h> |
15 | #include <asm/pgtable.h> | 14 | #include <asm/pgtable.h> |
diff --git a/arch/ppc/platforms/katana.c b/arch/ppc/platforms/katana.c index eda922ac3167..169dbf6534b9 100644 --- a/arch/ppc/platforms/katana.c +++ b/arch/ppc/platforms/katana.c | |||
@@ -27,12 +27,12 @@ | |||
27 | #include <linux/root_dev.h> | 27 | #include <linux/root_dev.h> |
28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
29 | #include <linux/seq_file.h> | 29 | #include <linux/seq_file.h> |
30 | #include <linux/bootmem.h> | ||
31 | #include <linux/mtd/physmap.h> | 30 | #include <linux/mtd/physmap.h> |
32 | #include <linux/mv643xx.h> | 31 | #include <linux/mv643xx.h> |
33 | #ifdef CONFIG_BOOTIMG | 32 | #ifdef CONFIG_BOOTIMG |
34 | #include <linux/bootimg.h> | 33 | #include <linux/bootimg.h> |
35 | #endif | 34 | #endif |
35 | #include <asm/io.h> | ||
36 | #include <asm/page.h> | 36 | #include <asm/page.h> |
37 | #include <asm/time.h> | 37 | #include <asm/time.h> |
38 | #include <asm/smp.h> | 38 | #include <asm/smp.h> |
diff --git a/arch/ppc/platforms/pmac_pci.c b/arch/ppc/platforms/pmac_pci.c index f6ff51924061..719fb49fe2bc 100644 --- a/arch/ppc/platforms/pmac_pci.c +++ b/arch/ppc/platforms/pmac_pci.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/string.h> | 18 | #include <linux/string.h> |
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/bootmem.h> | ||
21 | 20 | ||
22 | #include <asm/sections.h> | 21 | #include <asm/sections.h> |
23 | #include <asm/io.h> | 22 | #include <asm/io.h> |
diff --git a/arch/ppc/syslib/cpm2_common.c b/arch/ppc/syslib/cpm2_common.c index ea5e77080e8d..4c19a4ac7163 100644 --- a/arch/ppc/syslib/cpm2_common.c +++ b/arch/ppc/syslib/cpm2_common.c | |||
@@ -21,8 +21,8 @@ | |||
21 | #include <linux/string.h> | 21 | #include <linux/string.h> |
22 | #include <linux/mm.h> | 22 | #include <linux/mm.h> |
23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
24 | #include <linux/bootmem.h> | ||
25 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <asm/io.h> | ||
26 | #include <asm/irq.h> | 26 | #include <asm/irq.h> |
27 | #include <asm/mpc8260.h> | 27 | #include <asm/mpc8260.h> |
28 | #include <asm/page.h> | 28 | #include <asm/page.h> |
diff --git a/arch/ppc/syslib/indirect_pci.c b/arch/ppc/syslib/indirect_pci.c index a5a752609e2c..e71488469704 100644 --- a/arch/ppc/syslib/indirect_pci.c +++ b/arch/ppc/syslib/indirect_pci.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
15 | #include <linux/string.h> | 15 | #include <linux/string.h> |
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/bootmem.h> | ||
18 | 17 | ||
19 | #include <asm/io.h> | 18 | #include <asm/io.h> |
20 | #include <asm/prom.h> | 19 | #include <asm/prom.h> |
diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c index 7b241e7876bd..cc77177fa1c6 100644 --- a/arch/ppc/syslib/mv64x60.c +++ b/arch/ppc/syslib/mv64x60.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/string.h> | 19 | #include <linux/string.h> |
20 | #include <linux/bootmem.h> | ||
21 | #include <linux/spinlock.h> | 20 | #include <linux/spinlock.h> |
22 | #include <linux/mv643xx.h> | 21 | #include <linux/mv643xx.h> |
23 | 22 | ||
diff --git a/arch/ppc/syslib/mv64x60_win.c b/arch/ppc/syslib/mv64x60_win.c index b6f0f5dcf6ee..5b827e2bbe22 100644 --- a/arch/ppc/syslib/mv64x60_win.c +++ b/arch/ppc/syslib/mv64x60_win.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/string.h> | 19 | #include <linux/string.h> |
20 | #include <linux/bootmem.h> | ||
21 | #include <linux/mv643xx.h> | 20 | #include <linux/mv643xx.h> |
22 | 21 | ||
23 | #include <asm/byteorder.h> | 22 | #include <asm/byteorder.h> |
diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig index cb27068bfcd4..f804f25232ac 100644 --- a/arch/ppc64/Kconfig +++ b/arch/ppc64/Kconfig | |||
@@ -142,6 +142,23 @@ config PPC_SPLPAR | |||
142 | processors, that is, which share physical processors between | 142 | processors, that is, which share physical processors between |
143 | two or more partitions. | 143 | two or more partitions. |
144 | 144 | ||
145 | config KEXEC | ||
146 | bool "kexec system call (EXPERIMENTAL)" | ||
147 | depends on PPC_MULTIPLATFORM && EXPERIMENTAL | ||
148 | help | ||
149 | kexec is a system call that implements the ability to shutdown your | ||
150 | current kernel, and to start another kernel. It is like a reboot | ||
151 | but it is indepedent of the system firmware. And like a reboot | ||
152 | you can start any kernel with it, not just Linux. | ||
153 | |||
154 | The name comes from the similiarity to the exec system call. | ||
155 | |||
156 | It is an ongoing process to be certain the hardware in a machine | ||
157 | is properly shutdown, so do not be surprised if this code does not | ||
158 | initially work for you. It may help to enable device hotplugging | ||
159 | support. As of this writing the exact hardware interface is | ||
160 | strongly in flux, so no good recommendation can be made. | ||
161 | |||
145 | config IBMVIO | 162 | config IBMVIO |
146 | depends on PPC_PSERIES || PPC_ISERIES | 163 | depends on PPC_PSERIES || PPC_ISERIES |
147 | bool | 164 | bool |
@@ -270,26 +287,7 @@ config SCHED_SMT | |||
270 | when dealing with POWER5 cpus at a cost of slightly increased | 287 | when dealing with POWER5 cpus at a cost of slightly increased |
271 | overhead in some places. If unsure say N here. | 288 | overhead in some places. If unsure say N here. |
272 | 289 | ||
273 | config PREEMPT | 290 | source "kernel/Kconfig.preempt" |
274 | bool "Preemptible Kernel" | ||
275 | help | ||
276 | This option reduces the latency of the kernel when reacting to | ||
277 | real-time or interactive events by allowing a low priority process to | ||
278 | be preempted even if it is in kernel mode executing a system call. | ||
279 | |||
280 | Say Y here if you are building a kernel for a desktop, embedded | ||
281 | or real-time system. Say N if you are unsure. | ||
282 | |||
283 | config PREEMPT_BKL | ||
284 | bool "Preempt The Big Kernel Lock" | ||
285 | depends on PREEMPT | ||
286 | default y | ||
287 | help | ||
288 | This option reduces the latency of the kernel by making the | ||
289 | big kernel lock preemptible. | ||
290 | |||
291 | Say Y here if you are building a kernel for a desktop system. | ||
292 | Say N if you are unsure. | ||
293 | 291 | ||
294 | config EEH | 292 | config EEH |
295 | bool "PCI Extended Error Handling (EEH)" if EMBEDDED | 293 | bool "PCI Extended Error Handling (EEH)" if EMBEDDED |
diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index dffbfb7ac8d5..d9b2660ef221 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile | |||
@@ -36,6 +36,7 @@ obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \ | |||
36 | obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_iommu.o bpa_nvram.o \ | 36 | obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_iommu.o bpa_nvram.o \ |
37 | bpa_iic.o spider-pic.o | 37 | bpa_iic.o spider-pic.o |
38 | 38 | ||
39 | obj-$(CONFIG_KEXEC) += machine_kexec.o | ||
39 | obj-$(CONFIG_EEH) += eeh.o | 40 | obj-$(CONFIG_EEH) += eeh.o |
40 | obj-$(CONFIG_PROC_FS) += proc_ppc64.o | 41 | obj-$(CONFIG_PROC_FS) += proc_ppc64.o |
41 | obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o | 42 | obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o |
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index 02c8f4e3e4bc..675c2708588f 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S | |||
@@ -1194,7 +1194,7 @@ _GLOBAL(pSeries_secondary_smp_init) | |||
1194 | bl .__restore_cpu_setup | 1194 | bl .__restore_cpu_setup |
1195 | 1195 | ||
1196 | /* Set up a paca value for this processor. Since we have the | 1196 | /* Set up a paca value for this processor. Since we have the |
1197 | * physical cpu id in r3, we need to search the pacas to find | 1197 | * physical cpu id in r24, we need to search the pacas to find |
1198 | * which logical id maps to our physical one. | 1198 | * which logical id maps to our physical one. |
1199 | */ | 1199 | */ |
1200 | LOADADDR(r13, paca) /* Get base vaddr of paca array */ | 1200 | LOADADDR(r13, paca) /* Get base vaddr of paca array */ |
@@ -1207,8 +1207,8 @@ _GLOBAL(pSeries_secondary_smp_init) | |||
1207 | cmpwi r5,NR_CPUS | 1207 | cmpwi r5,NR_CPUS |
1208 | blt 1b | 1208 | blt 1b |
1209 | 1209 | ||
1210 | 99: HMT_LOW /* Couldn't find our CPU id */ | 1210 | mr r3,r24 /* not found, copy phys to r3 */ |
1211 | b 99b | 1211 | b .kexec_wait /* next kernel might do better */ |
1212 | 1212 | ||
1213 | 2: mtspr SPRG3,r13 /* Save vaddr of paca in SPRG3 */ | 1213 | 2: mtspr SPRG3,r13 /* Save vaddr of paca in SPRG3 */ |
1214 | /* From now on, r24 is expected to be logica cpuid */ | 1214 | /* From now on, r24 is expected to be logica cpuid */ |
diff --git a/arch/ppc64/kernel/lparcfg.c b/arch/ppc64/kernel/lparcfg.c index 387923fcf9b0..02e96627fa66 100644 --- a/arch/ppc64/kernel/lparcfg.c +++ b/arch/ppc64/kernel/lparcfg.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <asm/system.h> | 34 | #include <asm/system.h> |
35 | #include <asm/time.h> | 35 | #include <asm/time.h> |
36 | #include <asm/iSeries/ItExtVpdPanel.h> | 36 | #include <asm/iSeries/ItExtVpdPanel.h> |
37 | #include <asm/prom.h> | ||
37 | 38 | ||
38 | #define MODULE_VERS "1.6" | 39 | #define MODULE_VERS "1.6" |
39 | #define MODULE_NAME "lparcfg" | 40 | #define MODULE_NAME "lparcfg" |
diff --git a/arch/ppc64/kernel/machine_kexec.c b/arch/ppc64/kernel/machine_kexec.c new file mode 100644 index 000000000000..fdb2fc649d72 --- /dev/null +++ b/arch/ppc64/kernel/machine_kexec.c | |||
@@ -0,0 +1,302 @@ | |||
1 | /* | ||
2 | * machine_kexec.c - handle transition of Linux booting another kernel | ||
3 | * | ||
4 | * Copyright (C) 2004-2005, IBM Corp. | ||
5 | * | ||
6 | * Created by: Milton D Miller II | ||
7 | * | ||
8 | * This source code is licensed under the GNU General Public License, | ||
9 | * Version 2. See the file COPYING for more details. | ||
10 | */ | ||
11 | |||
12 | |||
13 | #include <linux/cpumask.h> | ||
14 | #include <linux/kexec.h> | ||
15 | #include <linux/smp.h> | ||
16 | #include <linux/thread_info.h> | ||
17 | #include <linux/errno.h> | ||
18 | |||
19 | #include <asm/page.h> | ||
20 | #include <asm/current.h> | ||
21 | #include <asm/machdep.h> | ||
22 | #include <asm/cacheflush.h> | ||
23 | #include <asm/paca.h> | ||
24 | #include <asm/mmu.h> | ||
25 | #include <asm/sections.h> /* _end */ | ||
26 | #include <asm/prom.h> | ||
27 | |||
28 | #define HASH_GROUP_SIZE 0x80 /* size of each hash group, asm/mmu.h */ | ||
29 | |||
30 | /* Have this around till we move it into crash specific file */ | ||
31 | note_buf_t crash_notes[NR_CPUS]; | ||
32 | |||
33 | /* Dummy for now. Not sure if we need to have a crash shutdown in here | ||
34 | * and if what it will achieve. Letting it be now to compile the code | ||
35 | * in generic kexec environment | ||
36 | */ | ||
37 | void machine_crash_shutdown(struct pt_regs *regs) | ||
38 | { | ||
39 | /* do nothing right now */ | ||
40 | /* smp_relase_cpus() if we want smp on panic kernel */ | ||
41 | /* cpu_irq_down to isolate us until we are ready */ | ||
42 | } | ||
43 | |||
44 | int machine_kexec_prepare(struct kimage *image) | ||
45 | { | ||
46 | int i; | ||
47 | unsigned long begin, end; /* limits of segment */ | ||
48 | unsigned long low, high; /* limits of blocked memory range */ | ||
49 | struct device_node *node; | ||
50 | unsigned long *basep; | ||
51 | unsigned int *sizep; | ||
52 | |||
53 | if (!ppc_md.hpte_clear_all) | ||
54 | return -ENOENT; | ||
55 | |||
56 | /* | ||
57 | * Since we use the kernel fault handlers and paging code to | ||
58 | * handle the virtual mode, we must make sure no destination | ||
59 | * overlaps kernel static data or bss. | ||
60 | */ | ||
61 | for (i = 0; i < image->nr_segments; i++) | ||
62 | if (image->segment[i].mem < __pa(_end)) | ||
63 | return -ETXTBSY; | ||
64 | |||
65 | /* | ||
66 | * For non-LPAR, we absolutely can not overwrite the mmu hash | ||
67 | * table, since we are still using the bolted entries in it to | ||
68 | * do the copy. Check that here. | ||
69 | * | ||
70 | * It is safe if the end is below the start of the blocked | ||
71 | * region (end <= low), or if the beginning is after the | ||
72 | * end of the blocked region (begin >= high). Use the | ||
73 | * boolean identity !(a || b) === (!a && !b). | ||
74 | */ | ||
75 | if (htab_address) { | ||
76 | low = __pa(htab_address); | ||
77 | high = low + (htab_hash_mask + 1) * HASH_GROUP_SIZE; | ||
78 | |||
79 | for (i = 0; i < image->nr_segments; i++) { | ||
80 | begin = image->segment[i].mem; | ||
81 | end = begin + image->segment[i].memsz; | ||
82 | |||
83 | if ((begin < high) && (end > low)) | ||
84 | return -ETXTBSY; | ||
85 | } | ||
86 | } | ||
87 | |||
88 | /* We also should not overwrite the tce tables */ | ||
89 | for (node = of_find_node_by_type(NULL, "pci"); node != NULL; | ||
90 | node = of_find_node_by_type(node, "pci")) { | ||
91 | basep = (unsigned long *)get_property(node, "linux,tce-base", | ||
92 | NULL); | ||
93 | sizep = (unsigned int *)get_property(node, "linux,tce-size", | ||
94 | NULL); | ||
95 | if (basep == NULL || sizep == NULL) | ||
96 | continue; | ||
97 | |||
98 | low = *basep; | ||
99 | high = low + (*sizep); | ||
100 | |||
101 | for (i = 0; i < image->nr_segments; i++) { | ||
102 | begin = image->segment[i].mem; | ||
103 | end = begin + image->segment[i].memsz; | ||
104 | |||
105 | if ((begin < high) && (end > low)) | ||
106 | return -ETXTBSY; | ||
107 | } | ||
108 | } | ||
109 | |||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | void machine_kexec_cleanup(struct kimage *image) | ||
114 | { | ||
115 | /* we do nothing in prepare that needs to be undone */ | ||
116 | } | ||
117 | |||
118 | #define IND_FLAGS (IND_DESTINATION | IND_INDIRECTION | IND_DONE | IND_SOURCE) | ||
119 | |||
120 | static void copy_segments(unsigned long ind) | ||
121 | { | ||
122 | unsigned long entry; | ||
123 | unsigned long *ptr; | ||
124 | void *dest; | ||
125 | void *addr; | ||
126 | |||
127 | /* | ||
128 | * We rely on kexec_load to create a lists that properly | ||
129 | * initializes these pointers before they are used. | ||
130 | * We will still crash if the list is wrong, but at least | ||
131 | * the compiler will be quiet. | ||
132 | */ | ||
133 | ptr = NULL; | ||
134 | dest = NULL; | ||
135 | |||
136 | for (entry = ind; !(entry & IND_DONE); entry = *ptr++) { | ||
137 | addr = __va(entry & PAGE_MASK); | ||
138 | |||
139 | switch (entry & IND_FLAGS) { | ||
140 | case IND_DESTINATION: | ||
141 | dest = addr; | ||
142 | break; | ||
143 | case IND_INDIRECTION: | ||
144 | ptr = addr; | ||
145 | break; | ||
146 | case IND_SOURCE: | ||
147 | copy_page(dest, addr); | ||
148 | dest += PAGE_SIZE; | ||
149 | } | ||
150 | } | ||
151 | } | ||
152 | |||
153 | void kexec_copy_flush(struct kimage *image) | ||
154 | { | ||
155 | long i, nr_segments = image->nr_segments; | ||
156 | struct kexec_segment ranges[KEXEC_SEGMENT_MAX]; | ||
157 | |||
158 | /* save the ranges on the stack to efficiently flush the icache */ | ||
159 | memcpy(ranges, image->segment, sizeof(ranges)); | ||
160 | |||
161 | /* | ||
162 | * After this call we may not use anything allocated in dynamic | ||
163 | * memory, including *image. | ||
164 | * | ||
165 | * Only globals and the stack are allowed. | ||
166 | */ | ||
167 | copy_segments(image->head); | ||
168 | |||
169 | /* | ||
170 | * we need to clear the icache for all dest pages sometime, | ||
171 | * including ones that were in place on the original copy | ||
172 | */ | ||
173 | for (i = 0; i < nr_segments; i++) | ||
174 | flush_icache_range(ranges[i].mem + KERNELBASE, | ||
175 | ranges[i].mem + KERNELBASE + | ||
176 | ranges[i].memsz); | ||
177 | } | ||
178 | |||
179 | #ifdef CONFIG_SMP | ||
180 | |||
181 | /* FIXME: we should schedule this function to be called on all cpus based | ||
182 | * on calling the interrupts, but we would like to call it off irq level | ||
183 | * so that the interrupt controller is clean. | ||
184 | */ | ||
185 | void kexec_smp_down(void *arg) | ||
186 | { | ||
187 | if (ppc_md.cpu_irq_down) | ||
188 | ppc_md.cpu_irq_down(); | ||
189 | |||
190 | local_irq_disable(); | ||
191 | kexec_smp_wait(); | ||
192 | /* NOTREACHED */ | ||
193 | } | ||
194 | |||
195 | static void kexec_prepare_cpus(void) | ||
196 | { | ||
197 | int my_cpu, i, notified=-1; | ||
198 | |||
199 | smp_call_function(kexec_smp_down, NULL, 0, /* wait */0); | ||
200 | my_cpu = get_cpu(); | ||
201 | |||
202 | /* check the others cpus are now down (via paca hw cpu id == -1) */ | ||
203 | for (i=0; i < NR_CPUS; i++) { | ||
204 | if (i == my_cpu) | ||
205 | continue; | ||
206 | |||
207 | while (paca[i].hw_cpu_id != -1) { | ||
208 | if (!cpu_possible(i)) { | ||
209 | printk("kexec: cpu %d hw_cpu_id %d is not" | ||
210 | " possible, ignoring\n", | ||
211 | i, paca[i].hw_cpu_id); | ||
212 | break; | ||
213 | } | ||
214 | if (!cpu_online(i)) { | ||
215 | /* Fixme: this can be spinning in | ||
216 | * pSeries_secondary_wait with a paca | ||
217 | * waiting for it to go online. | ||
218 | */ | ||
219 | printk("kexec: cpu %d hw_cpu_id %d is not" | ||
220 | " online, ignoring\n", | ||
221 | i, paca[i].hw_cpu_id); | ||
222 | break; | ||
223 | } | ||
224 | if (i != notified) { | ||
225 | printk( "kexec: waiting for cpu %d (physical" | ||
226 | " %d) to go down\n", | ||
227 | i, paca[i].hw_cpu_id); | ||
228 | notified = i; | ||
229 | } | ||
230 | } | ||
231 | } | ||
232 | |||
233 | /* after we tell the others to go down */ | ||
234 | if (ppc_md.cpu_irq_down) | ||
235 | ppc_md.cpu_irq_down(); | ||
236 | |||
237 | put_cpu(); | ||
238 | |||
239 | local_irq_disable(); | ||
240 | } | ||
241 | |||
242 | #else /* ! SMP */ | ||
243 | |||
244 | static void kexec_prepare_cpus(void) | ||
245 | { | ||
246 | /* | ||
247 | * move the secondarys to us so that we can copy | ||
248 | * the new kernel 0-0x100 safely | ||
249 | * | ||
250 | * do this if kexec in setup.c ? | ||
251 | */ | ||
252 | smp_relase_cpus(); | ||
253 | if (ppc_md.cpu_irq_down) | ||
254 | ppc_md.cpu_irq_down(); | ||
255 | local_irq_disable(); | ||
256 | } | ||
257 | |||
258 | #endif /* SMP */ | ||
259 | |||
260 | /* | ||
261 | * kexec thread structure and stack. | ||
262 | * | ||
263 | * We need to make sure that this is 16384-byte aligned due to the | ||
264 | * way process stacks are handled. It also must be statically allocated | ||
265 | * or allocated as part of the kimage, because everything else may be | ||
266 | * overwritten when we copy the kexec image. We piggyback on the | ||
267 | * "init_task" linker section here to statically allocate a stack. | ||
268 | * | ||
269 | * We could use a smaller stack if we don't care about anything using | ||
270 | * current, but that audit has not been performed. | ||
271 | */ | ||
272 | union thread_union kexec_stack | ||
273 | __attribute__((__section__(".data.init_task"))) = { }; | ||
274 | |||
275 | /* Our assembly helper, in kexec_stub.S */ | ||
276 | extern NORET_TYPE void kexec_sequence(void *newstack, unsigned long start, | ||
277 | void *image, void *control, | ||
278 | void (*clear_all)(void)) ATTRIB_NORET; | ||
279 | |||
280 | /* too late to fail here */ | ||
281 | void machine_kexec(struct kimage *image) | ||
282 | { | ||
283 | |||
284 | /* prepare control code if any */ | ||
285 | |||
286 | /* shutdown other cpus into our wait loop and quiesce interrupts */ | ||
287 | kexec_prepare_cpus(); | ||
288 | |||
289 | /* switch to a staticly allocated stack. Based on irq stack code. | ||
290 | * XXX: the task struct will likely be invalid once we do the copy! | ||
291 | */ | ||
292 | kexec_stack.thread_info.task = current_thread_info()->task; | ||
293 | kexec_stack.thread_info.flags = 0; | ||
294 | |||
295 | /* Some things are best done in assembly. Finding globals with | ||
296 | * a toc is easier in C, so pass in what we can. | ||
297 | */ | ||
298 | kexec_sequence(&kexec_stack, image->start, image, | ||
299 | page_address(image->control_code_page), | ||
300 | ppc_md.hpte_clear_all); | ||
301 | /* NOTREACHED */ | ||
302 | } | ||
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index e3c73b3425dc..f3dea0c5a88c 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S | |||
@@ -680,6 +680,177 @@ _GLOBAL(kernel_thread) | |||
680 | ld r30,-16(r1) | 680 | ld r30,-16(r1) |
681 | blr | 681 | blr |
682 | 682 | ||
683 | /* kexec_wait(phys_cpu) | ||
684 | * | ||
685 | * wait for the flag to change, indicating this kernel is going away but | ||
686 | * the slave code for the next one is at addresses 0 to 100. | ||
687 | * | ||
688 | * This is used by all slaves. | ||
689 | * | ||
690 | * Physical (hardware) cpu id should be in r3. | ||
691 | */ | ||
692 | _GLOBAL(kexec_wait) | ||
693 | bl 1f | ||
694 | 1: mflr r5 | ||
695 | addi r5,r5,kexec_flag-1b | ||
696 | |||
697 | 99: HMT_LOW | ||
698 | #ifdef CONFIG_KEXEC /* use no memory without kexec */ | ||
699 | lwz r4,0(r5) | ||
700 | cmpwi 0,r4,0 | ||
701 | bnea 0x60 | ||
702 | #endif | ||
703 | b 99b | ||
704 | |||
705 | /* this can be in text because we won't change it until we are | ||
706 | * running in real anyways | ||
707 | */ | ||
708 | kexec_flag: | ||
709 | .long 0 | ||
710 | |||
711 | |||
712 | #ifdef CONFIG_KEXEC | ||
713 | |||
714 | /* kexec_smp_wait(void) | ||
715 | * | ||
716 | * call with interrupts off | ||
717 | * note: this is a terminal routine, it does not save lr | ||
718 | * | ||
719 | * get phys id from paca | ||
720 | * set paca id to -1 to say we got here | ||
721 | * switch to real mode | ||
722 | * join other cpus in kexec_wait(phys_id) | ||
723 | */ | ||
724 | _GLOBAL(kexec_smp_wait) | ||
725 | lhz r3,PACAHWCPUID(r13) | ||
726 | li r4,-1 | ||
727 | sth r4,PACAHWCPUID(r13) /* let others know we left */ | ||
728 | bl real_mode | ||
729 | b .kexec_wait | ||
730 | |||
731 | /* | ||
732 | * switch to real mode (turn mmu off) | ||
733 | * we use the early kernel trick that the hardware ignores bits | ||
734 | * 0 and 1 (big endian) of the effective address in real mode | ||
735 | * | ||
736 | * don't overwrite r3 here, it is live for kexec_wait above. | ||
737 | */ | ||
738 | real_mode: /* assume normal blr return */ | ||
739 | 1: li r9,MSR_RI | ||
740 | li r10,MSR_DR|MSR_IR | ||
741 | mflr r11 /* return address to SRR0 */ | ||
742 | mfmsr r12 | ||
743 | andc r9,r12,r9 | ||
744 | andc r10,r12,r10 | ||
745 | |||
746 | mtmsrd r9,1 | ||
747 | mtspr SPRN_SRR1,r10 | ||
748 | mtspr SPRN_SRR0,r11 | ||
749 | rfid | ||
750 | |||
751 | |||
752 | /* | ||
753 | * kexec_sequence(newstack, start, image, control, clear_all()) | ||
754 | * | ||
755 | * does the grungy work with stack switching and real mode switches | ||
756 | * also does simple calls to other code | ||
757 | */ | ||
758 | |||
759 | _GLOBAL(kexec_sequence) | ||
760 | mflr r0 | ||
761 | std r0,16(r1) | ||
762 | |||
763 | /* switch stacks to newstack -- &kexec_stack.stack */ | ||
764 | stdu r1,THREAD_SIZE-112(r3) | ||
765 | mr r1,r3 | ||
766 | |||
767 | li r0,0 | ||
768 | std r0,16(r1) | ||
769 | |||
770 | /* save regs for local vars on new stack. | ||
771 | * yes, we won't go back, but ... | ||
772 | */ | ||
773 | std r31,-8(r1) | ||
774 | std r30,-16(r1) | ||
775 | std r29,-24(r1) | ||
776 | std r28,-32(r1) | ||
777 | std r27,-40(r1) | ||
778 | std r26,-48(r1) | ||
779 | std r25,-56(r1) | ||
780 | |||
781 | stdu r1,-112-64(r1) | ||
782 | |||
783 | /* save args into preserved regs */ | ||
784 | mr r31,r3 /* newstack (both) */ | ||
785 | mr r30,r4 /* start (real) */ | ||
786 | mr r29,r5 /* image (virt) */ | ||
787 | mr r28,r6 /* control, unused */ | ||
788 | mr r27,r7 /* clear_all() fn desc */ | ||
789 | mr r26,r8 /* spare */ | ||
790 | lhz r25,PACAHWCPUID(r13) /* get our phys cpu from paca */ | ||
791 | |||
792 | /* disable interrupts, we are overwriting kernel data next */ | ||
793 | mfmsr r3 | ||
794 | rlwinm r3,r3,0,17,15 | ||
795 | mtmsrd r3,1 | ||
796 | |||
797 | /* copy dest pages, flush whole dest image */ | ||
798 | mr r3,r29 | ||
799 | bl .kexec_copy_flush /* (image) */ | ||
800 | |||
801 | /* turn off mmu */ | ||
802 | bl real_mode | ||
803 | |||
804 | /* clear out hardware hash page table and tlb */ | ||
805 | ld r5,0(r27) /* deref function descriptor */ | ||
806 | mtctr r5 | ||
807 | bctrl /* ppc_md.hash_clear_all(void); */ | ||
808 | |||
809 | /* | ||
810 | * kexec image calling is: | ||
811 | * the first 0x100 bytes of the entry point are copied to 0 | ||
812 | * | ||
813 | * all slaves branch to slave = 0x60 (absolute) | ||
814 | * slave(phys_cpu_id); | ||
815 | * | ||
816 | * master goes to start = entry point | ||
817 | * start(phys_cpu_id, start, 0); | ||
818 | * | ||
819 | * | ||
820 | * a wrapper is needed to call existing kernels, here is an approximate | ||
821 | * description of one method: | ||
822 | * | ||
823 | * v2: (2.6.10) | ||
824 | * start will be near the boot_block (maybe 0x100 bytes before it?) | ||
825 | * it will have a 0x60, which will b to boot_block, where it will wait | ||
826 | * and 0 will store phys into struct boot-block and load r3 from there, | ||
827 | * copy kernel 0-0x100 and tell slaves to back down to 0x60 again | ||
828 | * | ||
829 | * v1: (2.6.9) | ||
830 | * boot block will have all cpus scanning device tree to see if they | ||
831 | * are the boot cpu ????? | ||
832 | * other device tree differences (prop sizes, va vs pa, etc)... | ||
833 | */ | ||
834 | |||
835 | /* copy 0x100 bytes starting at start to 0 */ | ||
836 | li r3,0 | ||
837 | mr r4,r30 | ||
838 | li r5,0x100 | ||
839 | li r6,0 | ||
840 | bl .copy_and_flush /* (dest, src, copy limit, start offset) */ | ||
841 | 1: /* assume normal blr return */ | ||
842 | |||
843 | /* release other cpus to the new kernel secondary start at 0x60 */ | ||
844 | mflr r5 | ||
845 | li r6,1 | ||
846 | stw r6,kexec_flag-1b(5) | ||
847 | mr r3,r25 # my phys cpu | ||
848 | mr r4,r30 # start, aka phys mem offset | ||
849 | mtlr 4 | ||
850 | li r5,0 | ||
851 | blr /* image->start(physid, image->start, 0); */ | ||
852 | #endif /* CONFIG_KEXEC */ | ||
853 | |||
683 | /* Why isn't this a) automatic, b) written in 'C'? */ | 854 | /* Why isn't this a) automatic, b) written in 'C'? */ |
684 | .balign 8 | 855 | .balign 8 |
685 | _GLOBAL(sys_call_table32) | 856 | _GLOBAL(sys_call_table32) |
@@ -951,7 +1122,7 @@ _GLOBAL(sys_call_table32) | |||
951 | .llong .compat_sys_mq_timedreceive /* 265 */ | 1122 | .llong .compat_sys_mq_timedreceive /* 265 */ |
952 | .llong .compat_sys_mq_notify | 1123 | .llong .compat_sys_mq_notify |
953 | .llong .compat_sys_mq_getsetattr | 1124 | .llong .compat_sys_mq_getsetattr |
954 | .llong .sys_ni_syscall /* 268 reserved for sys_kexec_load */ | 1125 | .llong .compat_sys_kexec_load |
955 | .llong .sys32_add_key | 1126 | .llong .sys32_add_key |
956 | .llong .sys32_request_key | 1127 | .llong .sys32_request_key |
957 | .llong .compat_sys_keyctl | 1128 | .llong .compat_sys_keyctl |
@@ -1227,7 +1398,7 @@ _GLOBAL(sys_call_table) | |||
1227 | .llong .sys_mq_timedreceive /* 265 */ | 1398 | .llong .sys_mq_timedreceive /* 265 */ |
1228 | .llong .sys_mq_notify | 1399 | .llong .sys_mq_notify |
1229 | .llong .sys_mq_getsetattr | 1400 | .llong .sys_mq_getsetattr |
1230 | .llong .sys_ni_syscall /* 268 reserved for sys_kexec_load */ | 1401 | .llong .sys_kexec_load |
1231 | .llong .sys_add_key | 1402 | .llong .sys_add_key |
1232 | .llong .sys_request_key /* 270 */ | 1403 | .llong .sys_request_key /* 270 */ |
1233 | .llong .sys_keyctl | 1404 | .llong .sys_keyctl |
diff --git a/arch/ppc64/kernel/mpic.c b/arch/ppc64/kernel/mpic.c index 593ea5b82afa..e8fbab1df37f 100644 --- a/arch/ppc64/kernel/mpic.c +++ b/arch/ppc64/kernel/mpic.c | |||
@@ -792,6 +792,35 @@ void mpic_setup_this_cpu(void) | |||
792 | #endif /* CONFIG_SMP */ | 792 | #endif /* CONFIG_SMP */ |
793 | } | 793 | } |
794 | 794 | ||
795 | /* | ||
796 | * XXX: someone who knows mpic should check this. | ||
797 | * do we need to eoi the ipi here (see xics comments)? | ||
798 | * or can we reset the mpic in the new kernel? | ||
799 | */ | ||
800 | void mpic_teardown_this_cpu(void) | ||
801 | { | ||
802 | struct mpic *mpic = mpic_primary; | ||
803 | unsigned long flags; | ||
804 | u32 msk = 1 << hard_smp_processor_id(); | ||
805 | unsigned int i; | ||
806 | |||
807 | BUG_ON(mpic == NULL); | ||
808 | |||
809 | DBG("%s: teardown_this_cpu(%d)\n", mpic->name, hard_smp_processor_id()); | ||
810 | spin_lock_irqsave(&mpic_lock, flags); | ||
811 | |||
812 | /* let the mpic know we don't want intrs. */ | ||
813 | for (i = 0; i < mpic->num_sources ; i++) | ||
814 | mpic_irq_write(i, MPIC_IRQ_DESTINATION, | ||
815 | mpic_irq_read(i, MPIC_IRQ_DESTINATION) & ~msk); | ||
816 | |||
817 | /* Set current processor priority to max */ | ||
818 | mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf); | ||
819 | |||
820 | spin_unlock_irqrestore(&mpic_lock, flags); | ||
821 | } | ||
822 | |||
823 | |||
795 | void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask) | 824 | void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask) |
796 | { | 825 | { |
797 | struct mpic *mpic = mpic_primary; | 826 | struct mpic *mpic = mpic_primary; |
diff --git a/arch/ppc64/kernel/mpic.h b/arch/ppc64/kernel/mpic.h index 63e177143eac..99fbbc9a084c 100644 --- a/arch/ppc64/kernel/mpic.h +++ b/arch/ppc64/kernel/mpic.h | |||
@@ -255,6 +255,9 @@ extern unsigned int mpic_irq_get_priority(unsigned int irq); | |||
255 | /* Setup a non-boot CPU */ | 255 | /* Setup a non-boot CPU */ |
256 | extern void mpic_setup_this_cpu(void); | 256 | extern void mpic_setup_this_cpu(void); |
257 | 257 | ||
258 | /* Clean up for kexec (or cpu offline or ...) */ | ||
259 | extern void mpic_teardown_this_cpu(void); | ||
260 | |||
258 | /* Request IPIs on primary mpic */ | 261 | /* Request IPIs on primary mpic */ |
259 | extern void mpic_request_ipis(void); | 262 | extern void mpic_request_ipis(void); |
260 | 263 | ||
diff --git a/arch/ppc64/kernel/pSeries_setup.c b/arch/ppc64/kernel/pSeries_setup.c index f2b41243342c..44d9af72d225 100644 --- a/arch/ppc64/kernel/pSeries_setup.c +++ b/arch/ppc64/kernel/pSeries_setup.c | |||
@@ -187,14 +187,16 @@ static void __init pSeries_setup_arch(void) | |||
187 | { | 187 | { |
188 | /* Fixup ppc_md depending on the type of interrupt controller */ | 188 | /* Fixup ppc_md depending on the type of interrupt controller */ |
189 | if (ppc64_interrupt_controller == IC_OPEN_PIC) { | 189 | if (ppc64_interrupt_controller == IC_OPEN_PIC) { |
190 | ppc_md.init_IRQ = pSeries_init_mpic; | 190 | ppc_md.init_IRQ = pSeries_init_mpic; |
191 | ppc_md.get_irq = mpic_get_irq; | 191 | ppc_md.get_irq = mpic_get_irq; |
192 | ppc_md.cpu_irq_down = mpic_teardown_this_cpu; | ||
192 | /* Allocate the mpic now, so that find_and_init_phbs() can | 193 | /* Allocate the mpic now, so that find_and_init_phbs() can |
193 | * fill the ISUs */ | 194 | * fill the ISUs */ |
194 | pSeries_setup_mpic(); | 195 | pSeries_setup_mpic(); |
195 | } else { | 196 | } else { |
196 | ppc_md.init_IRQ = xics_init_IRQ; | 197 | ppc_md.init_IRQ = xics_init_IRQ; |
197 | ppc_md.get_irq = xics_get_irq; | 198 | ppc_md.get_irq = xics_get_irq; |
199 | ppc_md.cpu_irq_down = xics_teardown_cpu; | ||
198 | } | 200 | } |
199 | 201 | ||
200 | #ifdef CONFIG_SMP | 202 | #ifdef CONFIG_SMP |
diff --git a/arch/ppc64/kernel/pSeries_smp.c b/arch/ppc64/kernel/pSeries_smp.c index 30154140f7e2..62c55a123560 100644 --- a/arch/ppc64/kernel/pSeries_smp.c +++ b/arch/ppc64/kernel/pSeries_smp.c | |||
@@ -93,10 +93,13 @@ static int query_cpu_stopped(unsigned int pcpu) | |||
93 | 93 | ||
94 | int pSeries_cpu_disable(void) | 94 | int pSeries_cpu_disable(void) |
95 | { | 95 | { |
96 | int cpu = smp_processor_id(); | ||
97 | |||
98 | cpu_clear(cpu, cpu_online_map); | ||
96 | systemcfg->processorCount--; | 99 | systemcfg->processorCount--; |
97 | 100 | ||
98 | /*fix boot_cpuid here*/ | 101 | /*fix boot_cpuid here*/ |
99 | if (smp_processor_id() == boot_cpuid) | 102 | if (cpu == boot_cpuid) |
100 | boot_cpuid = any_online_cpu(cpu_online_map); | 103 | boot_cpuid = any_online_cpu(cpu_online_map); |
101 | 104 | ||
102 | /* FIXME: abstract this to not be platform specific later on */ | 105 | /* FIXME: abstract this to not be platform specific later on */ |
diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index 0a47a5ef428d..d5e4866e9ac2 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c | |||
@@ -677,11 +677,16 @@ void __init setup_system(void) | |||
677 | DBG(" <- setup_system()\n"); | 677 | DBG(" <- setup_system()\n"); |
678 | } | 678 | } |
679 | 679 | ||
680 | 680 | /* also used by kexec */ | |
681 | void machine_restart(char *cmd) | 681 | void machine_shutdown(void) |
682 | { | 682 | { |
683 | if (ppc_md.nvram_sync) | 683 | if (ppc_md.nvram_sync) |
684 | ppc_md.nvram_sync(); | 684 | ppc_md.nvram_sync(); |
685 | } | ||
686 | |||
687 | void machine_restart(char *cmd) | ||
688 | { | ||
689 | machine_shutdown(); | ||
685 | ppc_md.restart(cmd); | 690 | ppc_md.restart(cmd); |
686 | #ifdef CONFIG_SMP | 691 | #ifdef CONFIG_SMP |
687 | smp_send_stop(); | 692 | smp_send_stop(); |
@@ -690,13 +695,11 @@ void machine_restart(char *cmd) | |||
690 | local_irq_disable(); | 695 | local_irq_disable(); |
691 | while (1) ; | 696 | while (1) ; |
692 | } | 697 | } |
693 | |||
694 | EXPORT_SYMBOL(machine_restart); | 698 | EXPORT_SYMBOL(machine_restart); |
695 | 699 | ||
696 | void machine_power_off(void) | 700 | void machine_power_off(void) |
697 | { | 701 | { |
698 | if (ppc_md.nvram_sync) | 702 | machine_shutdown(); |
699 | ppc_md.nvram_sync(); | ||
700 | ppc_md.power_off(); | 703 | ppc_md.power_off(); |
701 | #ifdef CONFIG_SMP | 704 | #ifdef CONFIG_SMP |
702 | smp_send_stop(); | 705 | smp_send_stop(); |
@@ -705,13 +708,11 @@ void machine_power_off(void) | |||
705 | local_irq_disable(); | 708 | local_irq_disable(); |
706 | while (1) ; | 709 | while (1) ; |
707 | } | 710 | } |
708 | |||
709 | EXPORT_SYMBOL(machine_power_off); | 711 | EXPORT_SYMBOL(machine_power_off); |
710 | 712 | ||
711 | void machine_halt(void) | 713 | void machine_halt(void) |
712 | { | 714 | { |
713 | if (ppc_md.nvram_sync) | 715 | machine_shutdown(); |
714 | ppc_md.nvram_sync(); | ||
715 | ppc_md.halt(); | 716 | ppc_md.halt(); |
716 | #ifdef CONFIG_SMP | 717 | #ifdef CONFIG_SMP |
717 | smp_send_stop(); | 718 | smp_send_stop(); |
@@ -720,7 +721,6 @@ void machine_halt(void) | |||
720 | local_irq_disable(); | 721 | local_irq_disable(); |
721 | while (1) ; | 722 | while (1) ; |
722 | } | 723 | } |
723 | |||
724 | EXPORT_SYMBOL(machine_halt); | 724 | EXPORT_SYMBOL(machine_halt); |
725 | 725 | ||
726 | static int ppc64_panic_event(struct notifier_block *this, | 726 | static int ppc64_panic_event(struct notifier_block *this, |
diff --git a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c index 879f39b90a33..677c4450984a 100644 --- a/arch/ppc64/kernel/xics.c +++ b/arch/ppc64/kernel/xics.c | |||
@@ -647,6 +647,31 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask) | |||
647 | } | 647 | } |
648 | } | 648 | } |
649 | 649 | ||
650 | void xics_teardown_cpu(void) | ||
651 | { | ||
652 | int cpu = smp_processor_id(); | ||
653 | int status; | ||
654 | |||
655 | ops->cppr_info(cpu, 0x00); | ||
656 | iosync(); | ||
657 | |||
658 | /* | ||
659 | * we need to EOI the IPI if we got here from kexec down IPI | ||
660 | * | ||
661 | * xics doesn't care if we duplicate an EOI as long as we | ||
662 | * don't EOI and raise priority. | ||
663 | * | ||
664 | * probably need to check all the other interrupts too | ||
665 | * should we be flagging idle loop instead? | ||
666 | * or creating some task to be scheduled? | ||
667 | */ | ||
668 | ops->xirr_info_set(cpu, XICS_IPI); | ||
669 | |||
670 | status = rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE, | ||
671 | (1UL << interrupt_server_size) - 1 - default_distrib_server, 0); | ||
672 | WARN_ON(status != 0); | ||
673 | } | ||
674 | |||
650 | #ifdef CONFIG_HOTPLUG_CPU | 675 | #ifdef CONFIG_HOTPLUG_CPU |
651 | 676 | ||
652 | /* Interrupts are disabled. */ | 677 | /* Interrupts are disabled. */ |
diff --git a/arch/ppc64/mm/hash_native.c b/arch/ppc64/mm/hash_native.c index 52b6b9305341..4fec05817d66 100644 --- a/arch/ppc64/mm/hash_native.c +++ b/arch/ppc64/mm/hash_native.c | |||
@@ -304,6 +304,50 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long va, | |||
304 | local_irq_restore(flags); | 304 | local_irq_restore(flags); |
305 | } | 305 | } |
306 | 306 | ||
307 | /* | ||
308 | * clear all mappings on kexec. All cpus are in real mode (or they will | ||
309 | * be when they isi), and we are the only one left. We rely on our kernel | ||
310 | * mapping being 0xC0's and the hardware ignoring those two real bits. | ||
311 | * | ||
312 | * TODO: add batching support when enabled. remember, no dynamic memory here, | ||
313 | * athough there is the control page available... | ||
314 | */ | ||
315 | static void native_hpte_clear(void) | ||
316 | { | ||
317 | unsigned long slot, slots, flags; | ||
318 | HPTE *hptep = htab_address; | ||
319 | Hpte_dword0 dw0; | ||
320 | unsigned long pteg_count; | ||
321 | |||
322 | pteg_count = htab_hash_mask + 1; | ||
323 | |||
324 | local_irq_save(flags); | ||
325 | |||
326 | /* we take the tlbie lock and hold it. Some hardware will | ||
327 | * deadlock if we try to tlbie from two processors at once. | ||
328 | */ | ||
329 | spin_lock(&native_tlbie_lock); | ||
330 | |||
331 | slots = pteg_count * HPTES_PER_GROUP; | ||
332 | |||
333 | for (slot = 0; slot < slots; slot++, hptep++) { | ||
334 | /* | ||
335 | * we could lock the pte here, but we are the only cpu | ||
336 | * running, right? and for crash dump, we probably | ||
337 | * don't want to wait for a maybe bad cpu. | ||
338 | */ | ||
339 | dw0 = hptep->dw0.dw0; | ||
340 | |||
341 | if (dw0.v) { | ||
342 | hptep->dw0.dword0 = 0; | ||
343 | tlbie(slot2va(dw0.avpn, dw0.l, dw0.h, slot), dw0.l); | ||
344 | } | ||
345 | } | ||
346 | |||
347 | spin_unlock(&native_tlbie_lock); | ||
348 | local_irq_restore(flags); | ||
349 | } | ||
350 | |||
307 | static void native_flush_hash_range(unsigned long context, | 351 | static void native_flush_hash_range(unsigned long context, |
308 | unsigned long number, int local) | 352 | unsigned long number, int local) |
309 | { | 353 | { |
@@ -415,7 +459,8 @@ void hpte_init_native(void) | |||
415 | ppc_md.hpte_updatepp = native_hpte_updatepp; | 459 | ppc_md.hpte_updatepp = native_hpte_updatepp; |
416 | ppc_md.hpte_updateboltedpp = native_hpte_updateboltedpp; | 460 | ppc_md.hpte_updateboltedpp = native_hpte_updateboltedpp; |
417 | ppc_md.hpte_insert = native_hpte_insert; | 461 | ppc_md.hpte_insert = native_hpte_insert; |
418 | ppc_md.hpte_remove = native_hpte_remove; | 462 | ppc_md.hpte_remove = native_hpte_remove; |
463 | ppc_md.hpte_clear_all = native_hpte_clear; | ||
419 | if (tlb_batching_enabled()) | 464 | if (tlb_batching_enabled()) |
420 | ppc_md.flush_hash_range = native_flush_hash_range; | 465 | ppc_md.flush_hash_range = native_flush_hash_range; |
421 | htab_finish_init(); | 466 | htab_finish_init(); |
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 32696c1d9280..6600ee87f896 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
@@ -455,6 +455,14 @@ config NO_IDLE_HZ_INIT | |||
455 | The HZ timer is switched off in idle by default. That means the | 455 | The HZ timer is switched off in idle by default. That means the |
456 | HZ timer is already disabled at boot time. | 456 | HZ timer is already disabled at boot time. |
457 | 457 | ||
458 | config KEXEC | ||
459 | bool "kexec system call (EXPERIMENTAL)" | ||
460 | depends on EXPERIMENTAL | ||
461 | help | ||
462 | kexec is a system call that implements the ability to shutdown your | ||
463 | current kernel, and to start another kernel. It is like a reboot | ||
464 | but is independent of hardware/microcode support. | ||
465 | |||
458 | endmenu | 466 | endmenu |
459 | 467 | ||
460 | config PCMCIA | 468 | config PCMCIA |
diff --git a/arch/s390/defconfig b/arch/s390/defconfig index 07fd0414a4bf..89850b2c27ea 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig | |||
@@ -245,6 +245,7 @@ CONFIG_S390_TAPE_BLOCK=y | |||
245 | # | 245 | # |
246 | CONFIG_S390_TAPE_34XX=m | 246 | CONFIG_S390_TAPE_34XX=m |
247 | # CONFIG_VMLOGRDR is not set | 247 | # CONFIG_VMLOGRDR is not set |
248 | # CONFIG_VMCP is not set | ||
248 | # CONFIG_MONREADER is not set | 249 | # CONFIG_MONREADER is not set |
249 | # CONFIG_DCSS_SHM is not set | 250 | # CONFIG_DCSS_SHM is not set |
250 | 251 | ||
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index b41e0e199a7c..ab1e49d2e518 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile | |||
@@ -25,6 +25,16 @@ obj-$(CONFIG_ARCH_S390X) += entry64.o reipl64.o | |||
25 | 25 | ||
26 | obj-$(CONFIG_VIRT_TIMER) += vtime.o | 26 | obj-$(CONFIG_VIRT_TIMER) += vtime.o |
27 | 27 | ||
28 | # Kexec part | ||
29 | S390_KEXEC_OBJS := machine_kexec.o crash.o | ||
30 | ifeq ($(CONFIG_ARCH_S390X),y) | ||
31 | S390_KEXEC_OBJS += relocate_kernel64.o | ||
32 | else | ||
33 | S390_KEXEC_OBJS += relocate_kernel.o | ||
34 | endif | ||
35 | obj-$(CONFIG_KEXEC) += $(S390_KEXEC_OBJS) | ||
36 | |||
37 | |||
28 | # | 38 | # |
29 | # This is just to get the dependencies... | 39 | # This is just to get the dependencies... |
30 | # | 40 | # |
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 7a607b1d0380..bf529739c8ab 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S | |||
@@ -1441,3 +1441,11 @@ compat_sys_waitid_wrapper: | |||
1441 | lgfr %r5,%r5 # int | 1441 | lgfr %r5,%r5 # int |
1442 | llgtr %r6,%r6 # struct rusage_emu31 * | 1442 | llgtr %r6,%r6 # struct rusage_emu31 * |
1443 | jg compat_sys_waitid | 1443 | jg compat_sys_waitid |
1444 | |||
1445 | .globl compat_sys_kexec_load_wrapper | ||
1446 | compat_sys_kexec_load_wrapper: | ||
1447 | llgfr %r2,%r2 # unsigned long | ||
1448 | llgfr %r3,%r3 # unsigned long | ||
1449 | llgtr %r4,%r4 # struct kexec_segment * | ||
1450 | llgfr %r5,%r5 # unsigned long | ||
1451 | jg compat_sys_kexec_load | ||
diff --git a/arch/s390/kernel/cpcmd.c b/arch/s390/kernel/cpcmd.c index 44df8dc07c59..20062145e84e 100644 --- a/arch/s390/kernel/cpcmd.c +++ b/arch/s390/kernel/cpcmd.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * arch/s390/kernel/cpcmd.c | 2 | * arch/s390/kernel/cpcmd.c |
3 | * | 3 | * |
4 | * S390 version | 4 | * S390 version |
5 | * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation | 5 | * Copyright (C) 1999,2005 IBM Deutschland Entwicklung GmbH, IBM Corporation |
6 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), | 6 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), |
7 | * Christian Borntraeger (cborntra@de.ibm.com), | 7 | * Christian Borntraeger (cborntra@de.ibm.com), |
8 | */ | 8 | */ |
@@ -18,93 +18,114 @@ | |||
18 | #include <asm/system.h> | 18 | #include <asm/system.h> |
19 | 19 | ||
20 | static DEFINE_SPINLOCK(cpcmd_lock); | 20 | static DEFINE_SPINLOCK(cpcmd_lock); |
21 | static char cpcmd_buf[240]; | 21 | static char cpcmd_buf[241]; |
22 | 22 | ||
23 | /* | 23 | /* |
24 | * the caller of __cpcmd has to ensure that the response buffer is below 2 GB | 24 | * the caller of __cpcmd has to ensure that the response buffer is below 2 GB |
25 | */ | 25 | */ |
26 | void __cpcmd(char *cmd, char *response, int rlen) | 26 | int __cpcmd(const char *cmd, char *response, int rlen, int *response_code) |
27 | { | 27 | { |
28 | const int mask = 0x40000000L; | 28 | const int mask = 0x40000000L; |
29 | unsigned long flags; | 29 | unsigned long flags; |
30 | int return_code; | ||
31 | int return_len; | ||
30 | int cmdlen; | 32 | int cmdlen; |
31 | 33 | ||
32 | spin_lock_irqsave(&cpcmd_lock, flags); | 34 | spin_lock_irqsave(&cpcmd_lock, flags); |
33 | cmdlen = strlen(cmd); | 35 | cmdlen = strlen(cmd); |
34 | BUG_ON(cmdlen > 240); | 36 | BUG_ON(cmdlen > 240); |
35 | strcpy(cpcmd_buf, cmd); | 37 | memcpy(cpcmd_buf, cmd, cmdlen); |
36 | ASCEBC(cpcmd_buf, cmdlen); | 38 | ASCEBC(cpcmd_buf, cmdlen); |
37 | 39 | ||
38 | if (response != NULL && rlen > 0) { | 40 | if (response != NULL && rlen > 0) { |
39 | memset(response, 0, rlen); | 41 | memset(response, 0, rlen); |
40 | #ifndef CONFIG_ARCH_S390X | 42 | #ifndef CONFIG_ARCH_S390X |
41 | asm volatile ("LRA 2,0(%0)\n\t" | 43 | asm volatile ( "lra 2,0(%2)\n" |
42 | "LR 4,%1\n\t" | 44 | "lr 4,%3\n" |
43 | "O 4,%4\n\t" | 45 | "o 4,%6\n" |
44 | "LRA 3,0(%2)\n\t" | 46 | "lra 3,0(%4)\n" |
45 | "LR 5,%3\n\t" | 47 | "lr 5,%5\n" |
46 | ".long 0x83240008 # Diagnose X'08'\n\t" | 48 | "diag 2,4,0x8\n" |
47 | : /* no output */ | 49 | "brc 8, .Litfits\n" |
48 | : "a" (cpcmd_buf), "d" (cmdlen), | 50 | "ar 5, %5\n" |
49 | "a" (response), "d" (rlen), "m" (mask) | 51 | ".Litfits: \n" |
50 | : "cc", "2", "3", "4", "5" ); | 52 | "lr %0,4\n" |
53 | "lr %1,5\n" | ||
54 | : "=d" (return_code), "=d" (return_len) | ||
55 | : "a" (cpcmd_buf), "d" (cmdlen), | ||
56 | "a" (response), "d" (rlen), "m" (mask) | ||
57 | : "cc", "2", "3", "4", "5" ); | ||
51 | #else /* CONFIG_ARCH_S390X */ | 58 | #else /* CONFIG_ARCH_S390X */ |
52 | asm volatile (" lrag 2,0(%0)\n" | 59 | asm volatile ( "lrag 2,0(%2)\n" |
53 | " lgr 4,%1\n" | 60 | "lgr 4,%3\n" |
54 | " o 4,%4\n" | 61 | "o 4,%6\n" |
55 | " lrag 3,0(%2)\n" | 62 | "lrag 3,0(%4)\n" |
56 | " lgr 5,%3\n" | 63 | "lgr 5,%5\n" |
57 | " sam31\n" | 64 | "sam31\n" |
58 | " .long 0x83240008 # Diagnose X'08'\n" | 65 | "diag 2,4,0x8\n" |
59 | " sam64" | 66 | "sam64\n" |
60 | : /* no output */ | 67 | "brc 8, .Litfits\n" |
61 | : "a" (cpcmd_buf), "d" (cmdlen), | 68 | "agr 5, %5\n" |
62 | "a" (response), "d" (rlen), "m" (mask) | 69 | ".Litfits: \n" |
63 | : "cc", "2", "3", "4", "5" ); | 70 | "lgr %0,4\n" |
71 | "lgr %1,5\n" | ||
72 | : "=d" (return_code), "=d" (return_len) | ||
73 | : "a" (cpcmd_buf), "d" (cmdlen), | ||
74 | "a" (response), "d" (rlen), "m" (mask) | ||
75 | : "cc", "2", "3", "4", "5" ); | ||
64 | #endif /* CONFIG_ARCH_S390X */ | 76 | #endif /* CONFIG_ARCH_S390X */ |
65 | EBCASC(response, rlen); | 77 | EBCASC(response, rlen); |
66 | } else { | 78 | } else { |
79 | return_len = 0; | ||
67 | #ifndef CONFIG_ARCH_S390X | 80 | #ifndef CONFIG_ARCH_S390X |
68 | asm volatile ("LRA 2,0(%0)\n\t" | 81 | asm volatile ( "lra 2,0(%1)\n" |
69 | "LR 3,%1\n\t" | 82 | "lr 3,%2\n" |
70 | ".long 0x83230008 # Diagnose X'08'\n\t" | 83 | "diag 2,3,0x8\n" |
71 | : /* no output */ | 84 | "lr %0,3\n" |
72 | : "a" (cpcmd_buf), "d" (cmdlen) | 85 | : "=d" (return_code) |
73 | : "2", "3" ); | 86 | : "a" (cpcmd_buf), "d" (cmdlen) |
87 | : "2", "3" ); | ||
74 | #else /* CONFIG_ARCH_S390X */ | 88 | #else /* CONFIG_ARCH_S390X */ |
75 | asm volatile (" lrag 2,0(%0)\n" | 89 | asm volatile ( "lrag 2,0(%1)\n" |
76 | " lgr 3,%1\n" | 90 | "lgr 3,%2\n" |
77 | " sam31\n" | 91 | "sam31\n" |
78 | " .long 0x83230008 # Diagnose X'08'\n" | 92 | "diag 2,3,0x8\n" |
79 | " sam64" | 93 | "sam64\n" |
80 | : /* no output */ | 94 | "lgr %0,3\n" |
81 | : "a" (cpcmd_buf), "d" (cmdlen) | 95 | : "=d" (return_code) |
82 | : "2", "3" ); | 96 | : "a" (cpcmd_buf), "d" (cmdlen) |
97 | : "2", "3" ); | ||
83 | #endif /* CONFIG_ARCH_S390X */ | 98 | #endif /* CONFIG_ARCH_S390X */ |
84 | } | 99 | } |
85 | spin_unlock_irqrestore(&cpcmd_lock, flags); | 100 | spin_unlock_irqrestore(&cpcmd_lock, flags); |
101 | if (response_code != NULL) | ||
102 | *response_code = return_code; | ||
103 | return return_len; | ||
86 | } | 104 | } |
87 | 105 | ||
88 | EXPORT_SYMBOL(__cpcmd); | 106 | EXPORT_SYMBOL(__cpcmd); |
89 | 107 | ||
90 | #ifdef CONFIG_ARCH_S390X | 108 | #ifdef CONFIG_ARCH_S390X |
91 | void cpcmd(char *cmd, char *response, int rlen) | 109 | int cpcmd(const char *cmd, char *response, int rlen, int *response_code) |
92 | { | 110 | { |
93 | char *lowbuf; | 111 | char *lowbuf; |
112 | int len; | ||
113 | |||
94 | if ((rlen == 0) || (response == NULL) | 114 | if ((rlen == 0) || (response == NULL) |
95 | || !((unsigned long)response >> 31)) | 115 | || !((unsigned long)response >> 31)) |
96 | __cpcmd(cmd, response, rlen); | 116 | len = __cpcmd(cmd, response, rlen, response_code); |
97 | else { | 117 | else { |
98 | lowbuf = kmalloc(rlen, GFP_KERNEL | GFP_DMA); | 118 | lowbuf = kmalloc(rlen, GFP_KERNEL | GFP_DMA); |
99 | if (!lowbuf) { | 119 | if (!lowbuf) { |
100 | printk(KERN_WARNING | 120 | printk(KERN_WARNING |
101 | "cpcmd: could not allocate response buffer\n"); | 121 | "cpcmd: could not allocate response buffer\n"); |
102 | return; | 122 | return -ENOMEM; |
103 | } | 123 | } |
104 | __cpcmd(cmd, lowbuf, rlen); | 124 | len = __cpcmd(cmd, lowbuf, rlen, response_code); |
105 | memcpy(response, lowbuf, rlen); | 125 | memcpy(response, lowbuf, rlen); |
106 | kfree(lowbuf); | 126 | kfree(lowbuf); |
107 | } | 127 | } |
128 | return len; | ||
108 | } | 129 | } |
109 | 130 | ||
110 | EXPORT_SYMBOL(cpcmd); | 131 | EXPORT_SYMBOL(cpcmd); |
diff --git a/arch/s390/kernel/crash.c b/arch/s390/kernel/crash.c new file mode 100644 index 000000000000..7bd169c58b0c --- /dev/null +++ b/arch/s390/kernel/crash.c | |||
@@ -0,0 +1,17 @@ | |||
1 | /* | ||
2 | * arch/s390/kernel/crash.c | ||
3 | * | ||
4 | * (C) Copyright IBM Corp. 2005 | ||
5 | * | ||
6 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #include <linux/threads.h> | ||
11 | #include <linux/kexec.h> | ||
12 | |||
13 | note_buf_t crash_notes[NR_CPUS]; | ||
14 | |||
15 | void machine_crash_shutdown(struct pt_regs *regs) | ||
16 | { | ||
17 | } | ||
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index 91f8ce5543d3..960ba6029c3a 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c | |||
@@ -19,22 +19,27 @@ | |||
19 | #include <linux/sysctl.h> | 19 | #include <linux/sysctl.h> |
20 | #include <asm/uaccess.h> | 20 | #include <asm/uaccess.h> |
21 | #include <asm/semaphore.h> | 21 | #include <asm/semaphore.h> |
22 | |||
23 | #include <linux/module.h> | 22 | #include <linux/module.h> |
24 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/fs.h> | ||
25 | #include <linux/debugfs.h> | ||
25 | 26 | ||
26 | #include <asm/debug.h> | 27 | #include <asm/debug.h> |
27 | 28 | ||
28 | #define DEBUG_PROLOG_ENTRY -1 | 29 | #define DEBUG_PROLOG_ENTRY -1 |
29 | 30 | ||
31 | #define ALL_AREAS 0 /* copy all debug areas */ | ||
32 | #define NO_AREAS 1 /* copy no debug areas */ | ||
33 | |||
30 | /* typedefs */ | 34 | /* typedefs */ |
31 | 35 | ||
32 | typedef struct file_private_info { | 36 | typedef struct file_private_info { |
33 | loff_t offset; /* offset of last read in file */ | 37 | loff_t offset; /* offset of last read in file */ |
34 | int act_area; /* number of last formated area */ | 38 | int act_area; /* number of last formated area */ |
39 | int act_page; /* act page in given area */ | ||
35 | int act_entry; /* last formated entry (offset */ | 40 | int act_entry; /* last formated entry (offset */ |
36 | /* relative to beginning of last */ | 41 | /* relative to beginning of last */ |
37 | /* formated area) */ | 42 | /* formated page) */ |
38 | size_t act_entry_offset; /* up to this offset we copied */ | 43 | size_t act_entry_offset; /* up to this offset we copied */ |
39 | /* in last read the last formated */ | 44 | /* in last read the last formated */ |
40 | /* entry to userland */ | 45 | /* entry to userland */ |
@@ -51,8 +56,8 @@ typedef struct | |||
51 | * This assumes that all args are converted into longs | 56 | * This assumes that all args are converted into longs |
52 | * on L/390 this is the case for all types of parameter | 57 | * on L/390 this is the case for all types of parameter |
53 | * except of floats, and long long (32 bit) | 58 | * except of floats, and long long (32 bit) |
54 | * | 59 | * |
55 | */ | 60 | */ |
56 | long args[0]; | 61 | long args[0]; |
57 | } debug_sprintf_entry_t; | 62 | } debug_sprintf_entry_t; |
58 | 63 | ||
@@ -63,32 +68,38 @@ extern void tod_to_timeval(uint64_t todval, struct timeval *xtime); | |||
63 | 68 | ||
64 | static int debug_init(void); | 69 | static int debug_init(void); |
65 | static ssize_t debug_output(struct file *file, char __user *user_buf, | 70 | static ssize_t debug_output(struct file *file, char __user *user_buf, |
66 | size_t user_len, loff_t * offset); | 71 | size_t user_len, loff_t * offset); |
67 | static ssize_t debug_input(struct file *file, const char __user *user_buf, | 72 | static ssize_t debug_input(struct file *file, const char __user *user_buf, |
68 | size_t user_len, loff_t * offset); | 73 | size_t user_len, loff_t * offset); |
69 | static int debug_open(struct inode *inode, struct file *file); | 74 | static int debug_open(struct inode *inode, struct file *file); |
70 | static int debug_close(struct inode *inode, struct file *file); | 75 | static int debug_close(struct inode *inode, struct file *file); |
71 | static debug_info_t* debug_info_create(char *name, int page_order, int nr_areas, int buf_size); | 76 | static debug_info_t* debug_info_create(char *name, int pages_per_area, |
77 | int nr_areas, int buf_size); | ||
72 | static void debug_info_get(debug_info_t *); | 78 | static void debug_info_get(debug_info_t *); |
73 | static void debug_info_put(debug_info_t *); | 79 | static void debug_info_put(debug_info_t *); |
74 | static int debug_prolog_level_fn(debug_info_t * id, | 80 | static int debug_prolog_level_fn(debug_info_t * id, |
75 | struct debug_view *view, char *out_buf); | 81 | struct debug_view *view, char *out_buf); |
76 | static int debug_input_level_fn(debug_info_t * id, struct debug_view *view, | 82 | static int debug_input_level_fn(debug_info_t * id, struct debug_view *view, |
77 | struct file *file, const char __user *user_buf, | 83 | struct file *file, const char __user *user_buf, |
78 | size_t user_buf_size, loff_t * offset); | 84 | size_t user_buf_size, loff_t * offset); |
85 | static int debug_prolog_pages_fn(debug_info_t * id, | ||
86 | struct debug_view *view, char *out_buf); | ||
87 | static int debug_input_pages_fn(debug_info_t * id, struct debug_view *view, | ||
88 | struct file *file, const char __user *user_buf, | ||
89 | size_t user_buf_size, loff_t * offset); | ||
79 | static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view, | 90 | static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view, |
80 | struct file *file, const char __user *user_buf, | 91 | struct file *file, const char __user *user_buf, |
81 | size_t user_buf_size, loff_t * offset); | 92 | size_t user_buf_size, loff_t * offset); |
82 | static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view, | 93 | static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view, |
83 | char *out_buf, const char *in_buf); | 94 | char *out_buf, const char *in_buf); |
84 | static int debug_raw_format_fn(debug_info_t * id, | 95 | static int debug_raw_format_fn(debug_info_t * id, |
85 | struct debug_view *view, char *out_buf, | 96 | struct debug_view *view, char *out_buf, |
86 | const char *in_buf); | 97 | const char *in_buf); |
87 | static int debug_raw_header_fn(debug_info_t * id, struct debug_view *view, | 98 | static int debug_raw_header_fn(debug_info_t * id, struct debug_view *view, |
88 | int area, debug_entry_t * entry, char *out_buf); | 99 | int area, debug_entry_t * entry, char *out_buf); |
89 | 100 | ||
90 | static int debug_sprintf_format_fn(debug_info_t * id, struct debug_view *view, | 101 | static int debug_sprintf_format_fn(debug_info_t * id, struct debug_view *view, |
91 | char *out_buf, debug_sprintf_entry_t *curr_event); | 102 | char *out_buf, debug_sprintf_entry_t *curr_event); |
92 | 103 | ||
93 | /* globals */ | 104 | /* globals */ |
94 | 105 | ||
@@ -119,6 +130,15 @@ struct debug_view debug_level_view = { | |||
119 | NULL | 130 | NULL |
120 | }; | 131 | }; |
121 | 132 | ||
133 | struct debug_view debug_pages_view = { | ||
134 | "pages", | ||
135 | &debug_prolog_pages_fn, | ||
136 | NULL, | ||
137 | NULL, | ||
138 | &debug_input_pages_fn, | ||
139 | NULL | ||
140 | }; | ||
141 | |||
122 | struct debug_view debug_flush_view = { | 142 | struct debug_view debug_flush_view = { |
123 | "flush", | 143 | "flush", |
124 | NULL, | 144 | NULL, |
@@ -149,98 +169,161 @@ DECLARE_MUTEX(debug_lock); | |||
149 | static int initialized; | 169 | static int initialized; |
150 | 170 | ||
151 | static struct file_operations debug_file_ops = { | 171 | static struct file_operations debug_file_ops = { |
152 | .owner = THIS_MODULE, | 172 | .owner = THIS_MODULE, |
153 | .read = debug_output, | 173 | .read = debug_output, |
154 | .write = debug_input, | 174 | .write = debug_input, |
155 | .open = debug_open, | 175 | .open = debug_open, |
156 | .release = debug_close, | 176 | .release = debug_close, |
157 | }; | 177 | }; |
158 | 178 | ||
159 | static struct proc_dir_entry *debug_proc_root_entry; | 179 | static struct dentry *debug_debugfs_root_entry; |
160 | 180 | ||
161 | /* functions */ | 181 | /* functions */ |
162 | 182 | ||
163 | /* | 183 | /* |
184 | * debug_areas_alloc | ||
185 | * - Debug areas are implemented as a threedimensonal array: | ||
186 | * areas[areanumber][pagenumber][pageoffset] | ||
187 | */ | ||
188 | |||
189 | static debug_entry_t*** | ||
190 | debug_areas_alloc(int pages_per_area, int nr_areas) | ||
191 | { | ||
192 | debug_entry_t*** areas; | ||
193 | int i,j; | ||
194 | |||
195 | areas = (debug_entry_t ***) kmalloc(nr_areas * | ||
196 | sizeof(debug_entry_t**), | ||
197 | GFP_KERNEL); | ||
198 | if (!areas) | ||
199 | goto fail_malloc_areas; | ||
200 | for (i = 0; i < nr_areas; i++) { | ||
201 | areas[i] = (debug_entry_t**) kmalloc(pages_per_area * | ||
202 | sizeof(debug_entry_t*),GFP_KERNEL); | ||
203 | if (!areas[i]) { | ||
204 | goto fail_malloc_areas2; | ||
205 | } | ||
206 | for(j = 0; j < pages_per_area; j++) { | ||
207 | areas[i][j] = (debug_entry_t*)kmalloc(PAGE_SIZE, | ||
208 | GFP_KERNEL); | ||
209 | if(!areas[i][j]) { | ||
210 | for(j--; j >=0 ; j--) { | ||
211 | kfree(areas[i][j]); | ||
212 | } | ||
213 | kfree(areas[i]); | ||
214 | goto fail_malloc_areas2; | ||
215 | } else { | ||
216 | memset(areas[i][j],0,PAGE_SIZE); | ||
217 | } | ||
218 | } | ||
219 | } | ||
220 | return areas; | ||
221 | |||
222 | fail_malloc_areas2: | ||
223 | for(i--; i >= 0; i--){ | ||
224 | for(j=0; j < pages_per_area;j++){ | ||
225 | kfree(areas[i][j]); | ||
226 | } | ||
227 | kfree(areas[i]); | ||
228 | } | ||
229 | kfree(areas); | ||
230 | fail_malloc_areas: | ||
231 | return NULL; | ||
232 | |||
233 | } | ||
234 | |||
235 | |||
236 | /* | ||
164 | * debug_info_alloc | 237 | * debug_info_alloc |
165 | * - alloc new debug-info | 238 | * - alloc new debug-info |
166 | */ | 239 | */ |
167 | 240 | ||
168 | static debug_info_t* debug_info_alloc(char *name, int page_order, | 241 | static debug_info_t* |
169 | int nr_areas, int buf_size) | 242 | debug_info_alloc(char *name, int pages_per_area, int nr_areas, int buf_size, |
243 | int level, int mode) | ||
170 | { | 244 | { |
171 | debug_info_t* rc; | 245 | debug_info_t* rc; |
172 | int i; | ||
173 | 246 | ||
174 | /* alloc everything */ | 247 | /* alloc everything */ |
175 | 248 | ||
176 | rc = (debug_info_t*) kmalloc(sizeof(debug_info_t), GFP_ATOMIC); | 249 | rc = (debug_info_t*) kmalloc(sizeof(debug_info_t), GFP_KERNEL); |
177 | if(!rc) | 250 | if(!rc) |
178 | goto fail_malloc_rc; | 251 | goto fail_malloc_rc; |
179 | rc->active_entry = (int*)kmalloc(nr_areas * sizeof(int), GFP_ATOMIC); | 252 | rc->active_entries = (int*)kmalloc(nr_areas * sizeof(int), GFP_KERNEL); |
180 | if(!rc->active_entry) | 253 | if(!rc->active_entries) |
181 | goto fail_malloc_active_entry; | 254 | goto fail_malloc_active_entries; |
182 | memset(rc->active_entry, 0, nr_areas * sizeof(int)); | 255 | memset(rc->active_entries, 0, nr_areas * sizeof(int)); |
183 | rc->areas = (debug_entry_t **) kmalloc(nr_areas * | 256 | rc->active_pages = (int*)kmalloc(nr_areas * sizeof(int), GFP_KERNEL); |
184 | sizeof(debug_entry_t *), | 257 | if(!rc->active_pages) |
185 | GFP_ATOMIC); | 258 | goto fail_malloc_active_pages; |
186 | if (!rc->areas) | 259 | memset(rc->active_pages, 0, nr_areas * sizeof(int)); |
187 | goto fail_malloc_areas; | 260 | if((mode == ALL_AREAS) && (pages_per_area != 0)){ |
188 | for (i = 0; i < nr_areas; i++) { | 261 | rc->areas = debug_areas_alloc(pages_per_area, nr_areas); |
189 | rc->areas[i] = (debug_entry_t *) __get_free_pages(GFP_ATOMIC, | 262 | if(!rc->areas) |
190 | page_order); | 263 | goto fail_malloc_areas; |
191 | if (!rc->areas[i]) { | 264 | } else { |
192 | for (i--; i >= 0; i--) { | 265 | rc->areas = NULL; |
193 | free_pages((unsigned long) rc->areas[i], | ||
194 | page_order); | ||
195 | } | ||
196 | goto fail_malloc_areas2; | ||
197 | } else { | ||
198 | memset(rc->areas[i], 0, PAGE_SIZE << page_order); | ||
199 | } | ||
200 | } | 266 | } |
201 | 267 | ||
202 | /* initialize members */ | 268 | /* initialize members */ |
203 | 269 | ||
204 | spin_lock_init(&rc->lock); | 270 | spin_lock_init(&rc->lock); |
205 | rc->page_order = page_order; | 271 | rc->pages_per_area = pages_per_area; |
206 | rc->nr_areas = nr_areas; | 272 | rc->nr_areas = nr_areas; |
207 | rc->active_area = 0; | 273 | rc->active_area = 0; |
208 | rc->level = DEBUG_DEFAULT_LEVEL; | 274 | rc->level = level; |
209 | rc->buf_size = buf_size; | 275 | rc->buf_size = buf_size; |
210 | rc->entry_size = sizeof(debug_entry_t) + buf_size; | 276 | rc->entry_size = sizeof(debug_entry_t) + buf_size; |
211 | strlcpy(rc->name, name, sizeof(rc->name)); | 277 | strlcpy(rc->name, name, sizeof(rc->name)-1); |
212 | memset(rc->views, 0, DEBUG_MAX_VIEWS * sizeof(struct debug_view *)); | 278 | memset(rc->views, 0, DEBUG_MAX_VIEWS * sizeof(struct debug_view *)); |
213 | #ifdef CONFIG_PROC_FS | 279 | memset(rc->debugfs_entries, 0 ,DEBUG_MAX_VIEWS * |
214 | memset(rc->proc_entries, 0 ,DEBUG_MAX_VIEWS * | 280 | sizeof(struct dentry*)); |
215 | sizeof(struct proc_dir_entry*)); | ||
216 | #endif /* CONFIG_PROC_FS */ | ||
217 | atomic_set(&(rc->ref_count), 0); | 281 | atomic_set(&(rc->ref_count), 0); |
218 | 282 | ||
219 | return rc; | 283 | return rc; |
220 | 284 | ||
221 | fail_malloc_areas2: | ||
222 | kfree(rc->areas); | ||
223 | fail_malloc_areas: | 285 | fail_malloc_areas: |
224 | kfree(rc->active_entry); | 286 | kfree(rc->active_pages); |
225 | fail_malloc_active_entry: | 287 | fail_malloc_active_pages: |
288 | kfree(rc->active_entries); | ||
289 | fail_malloc_active_entries: | ||
226 | kfree(rc); | 290 | kfree(rc); |
227 | fail_malloc_rc: | 291 | fail_malloc_rc: |
228 | return NULL; | 292 | return NULL; |
229 | } | 293 | } |
230 | 294 | ||
231 | /* | 295 | /* |
232 | * debug_info_free | 296 | * debug_areas_free |
233 | * - free memory debug-info | 297 | * - free all debug areas |
234 | */ | 298 | */ |
235 | 299 | ||
236 | static void debug_info_free(debug_info_t* db_info){ | 300 | static void |
237 | int i; | 301 | debug_areas_free(debug_info_t* db_info) |
302 | { | ||
303 | int i,j; | ||
304 | |||
305 | if(!db_info->areas) | ||
306 | return; | ||
238 | for (i = 0; i < db_info->nr_areas; i++) { | 307 | for (i = 0; i < db_info->nr_areas; i++) { |
239 | free_pages((unsigned long) db_info->areas[i], | 308 | for(j = 0; j < db_info->pages_per_area; j++) { |
240 | db_info->page_order); | 309 | kfree(db_info->areas[i][j]); |
310 | } | ||
311 | kfree(db_info->areas[i]); | ||
241 | } | 312 | } |
242 | kfree(db_info->areas); | 313 | kfree(db_info->areas); |
243 | kfree(db_info->active_entry); | 314 | db_info->areas = NULL; |
315 | } | ||
316 | |||
317 | /* | ||
318 | * debug_info_free | ||
319 | * - free memory debug-info | ||
320 | */ | ||
321 | |||
322 | static void | ||
323 | debug_info_free(debug_info_t* db_info){ | ||
324 | debug_areas_free(db_info); | ||
325 | kfree(db_info->active_entries); | ||
326 | kfree(db_info->active_pages); | ||
244 | kfree(db_info); | 327 | kfree(db_info); |
245 | } | 328 | } |
246 | 329 | ||
@@ -249,21 +332,22 @@ static void debug_info_free(debug_info_t* db_info){ | |||
249 | * - create new debug-info | 332 | * - create new debug-info |
250 | */ | 333 | */ |
251 | 334 | ||
252 | static debug_info_t* debug_info_create(char *name, int page_order, | 335 | static debug_info_t* |
253 | int nr_areas, int buf_size) | 336 | debug_info_create(char *name, int pages_per_area, int nr_areas, int buf_size) |
254 | { | 337 | { |
255 | debug_info_t* rc; | 338 | debug_info_t* rc; |
256 | 339 | ||
257 | rc = debug_info_alloc(name, page_order, nr_areas, buf_size); | 340 | rc = debug_info_alloc(name, pages_per_area, nr_areas, buf_size, |
341 | DEBUG_DEFAULT_LEVEL, ALL_AREAS); | ||
258 | if(!rc) | 342 | if(!rc) |
259 | goto out; | 343 | goto out; |
260 | 344 | ||
261 | 345 | /* create root directory */ | |
262 | /* create proc rood directory */ | 346 | rc->debugfs_root_entry = debugfs_create_dir(rc->name, |
263 | rc->proc_root_entry = proc_mkdir(rc->name, debug_proc_root_entry); | 347 | debug_debugfs_root_entry); |
264 | 348 | ||
265 | /* append new element to linked list */ | 349 | /* append new element to linked list */ |
266 | if (debug_area_first == NULL) { | 350 | if (!debug_area_first) { |
267 | /* first element in list */ | 351 | /* first element in list */ |
268 | debug_area_first = rc; | 352 | debug_area_first = rc; |
269 | rc->prev = NULL; | 353 | rc->prev = NULL; |
@@ -285,17 +369,21 @@ out: | |||
285 | * - copy debug-info | 369 | * - copy debug-info |
286 | */ | 370 | */ |
287 | 371 | ||
288 | static debug_info_t* debug_info_copy(debug_info_t* in) | 372 | static debug_info_t* |
373 | debug_info_copy(debug_info_t* in, int mode) | ||
289 | { | 374 | { |
290 | int i; | 375 | int i,j; |
291 | debug_info_t* rc; | 376 | debug_info_t* rc; |
292 | rc = debug_info_alloc(in->name, in->page_order, | 377 | |
293 | in->nr_areas, in->buf_size); | 378 | rc = debug_info_alloc(in->name, in->pages_per_area, in->nr_areas, |
294 | if(!rc) | 379 | in->buf_size, in->level, mode); |
380 | if(!rc || (mode == NO_AREAS)) | ||
295 | goto out; | 381 | goto out; |
296 | 382 | ||
297 | for(i = 0; i < in->nr_areas; i++){ | 383 | for(i = 0; i < in->nr_areas; i++){ |
298 | memcpy(rc->areas[i],in->areas[i], PAGE_SIZE << in->page_order); | 384 | for(j = 0; j < in->pages_per_area; j++) { |
385 | memcpy(rc->areas[i][j], in->areas[i][j],PAGE_SIZE); | ||
386 | } | ||
299 | } | 387 | } |
300 | out: | 388 | out: |
301 | return rc; | 389 | return rc; |
@@ -306,7 +394,8 @@ out: | |||
306 | * - increments reference count for debug-info | 394 | * - increments reference count for debug-info |
307 | */ | 395 | */ |
308 | 396 | ||
309 | static void debug_info_get(debug_info_t * db_info) | 397 | static void |
398 | debug_info_get(debug_info_t * db_info) | ||
310 | { | 399 | { |
311 | if (db_info) | 400 | if (db_info) |
312 | atomic_inc(&db_info->ref_count); | 401 | atomic_inc(&db_info->ref_count); |
@@ -317,29 +406,20 @@ static void debug_info_get(debug_info_t * db_info) | |||
317 | * - decreases reference count for debug-info and frees it if necessary | 406 | * - decreases reference count for debug-info and frees it if necessary |
318 | */ | 407 | */ |
319 | 408 | ||
320 | static void debug_info_put(debug_info_t *db_info) | 409 | static void |
410 | debug_info_put(debug_info_t *db_info) | ||
321 | { | 411 | { |
322 | int i; | 412 | int i; |
323 | 413 | ||
324 | if (!db_info) | 414 | if (!db_info) |
325 | return; | 415 | return; |
326 | if (atomic_dec_and_test(&db_info->ref_count)) { | 416 | if (atomic_dec_and_test(&db_info->ref_count)) { |
327 | #ifdef DEBUG | ||
328 | printk(KERN_INFO "debug: freeing debug area %p (%s)\n", | ||
329 | db_info, db_info->name); | ||
330 | #endif | ||
331 | for (i = 0; i < DEBUG_MAX_VIEWS; i++) { | 417 | for (i = 0; i < DEBUG_MAX_VIEWS; i++) { |
332 | if (db_info->views[i] == NULL) | 418 | if (!db_info->views[i]) |
333 | continue; | 419 | continue; |
334 | #ifdef CONFIG_PROC_FS | 420 | debugfs_remove(db_info->debugfs_entries[i]); |
335 | remove_proc_entry(db_info->proc_entries[i]->name, | ||
336 | db_info->proc_root_entry); | ||
337 | #endif | ||
338 | } | 421 | } |
339 | #ifdef CONFIG_PROC_FS | 422 | debugfs_remove(db_info->debugfs_root_entry); |
340 | remove_proc_entry(db_info->proc_root_entry->name, | ||
341 | debug_proc_root_entry); | ||
342 | #endif | ||
343 | if(db_info == debug_area_first) | 423 | if(db_info == debug_area_first) |
344 | debug_area_first = db_info->next; | 424 | debug_area_first = db_info->next; |
345 | if(db_info == debug_area_last) | 425 | if(db_info == debug_area_last) |
@@ -355,9 +435,9 @@ static void debug_info_put(debug_info_t *db_info) | |||
355 | * - format one debug entry and return size of formated data | 435 | * - format one debug entry and return size of formated data |
356 | */ | 436 | */ |
357 | 437 | ||
358 | static int debug_format_entry(file_private_info_t *p_info) | 438 | static int |
439 | debug_format_entry(file_private_info_t *p_info) | ||
359 | { | 440 | { |
360 | debug_info_t *id_org = p_info->debug_info_org; | ||
361 | debug_info_t *id_snap = p_info->debug_info_snap; | 441 | debug_info_t *id_snap = p_info->debug_info_snap; |
362 | struct debug_view *view = p_info->view; | 442 | struct debug_view *view = p_info->view; |
363 | debug_entry_t *act_entry; | 443 | debug_entry_t *act_entry; |
@@ -365,22 +445,23 @@ static int debug_format_entry(file_private_info_t *p_info) | |||
365 | if(p_info->act_entry == DEBUG_PROLOG_ENTRY){ | 445 | if(p_info->act_entry == DEBUG_PROLOG_ENTRY){ |
366 | /* print prolog */ | 446 | /* print prolog */ |
367 | if (view->prolog_proc) | 447 | if (view->prolog_proc) |
368 | len += view->prolog_proc(id_org, view,p_info->temp_buf); | 448 | len += view->prolog_proc(id_snap,view,p_info->temp_buf); |
369 | goto out; | 449 | goto out; |
370 | } | 450 | } |
371 | 451 | if (!id_snap->areas) /* this is true, if we have a prolog only view */ | |
372 | act_entry = (debug_entry_t *) ((char*)id_snap->areas[p_info->act_area] + | 452 | goto out; /* or if 'pages_per_area' is 0 */ |
373 | p_info->act_entry); | 453 | act_entry = (debug_entry_t *) ((char*)id_snap->areas[p_info->act_area] |
454 | [p_info->act_page] + p_info->act_entry); | ||
374 | 455 | ||
375 | if (act_entry->id.stck == 0LL) | 456 | if (act_entry->id.stck == 0LL) |
376 | goto out; /* empty entry */ | 457 | goto out; /* empty entry */ |
377 | if (view->header_proc) | 458 | if (view->header_proc) |
378 | len += view->header_proc(id_org, view, p_info->act_area, | 459 | len += view->header_proc(id_snap, view, p_info->act_area, |
379 | act_entry, p_info->temp_buf + len); | 460 | act_entry, p_info->temp_buf + len); |
380 | if (view->format_proc) | 461 | if (view->format_proc) |
381 | len += view->format_proc(id_org, view, p_info->temp_buf + len, | 462 | len += view->format_proc(id_snap, view, p_info->temp_buf + len, |
382 | DEBUG_DATA(act_entry)); | 463 | DEBUG_DATA(act_entry)); |
383 | out: | 464 | out: |
384 | return len; | 465 | return len; |
385 | } | 466 | } |
386 | 467 | ||
@@ -389,20 +470,30 @@ static int debug_format_entry(file_private_info_t *p_info) | |||
389 | * - goto next entry in p_info | 470 | * - goto next entry in p_info |
390 | */ | 471 | */ |
391 | 472 | ||
392 | extern inline int debug_next_entry(file_private_info_t *p_info) | 473 | extern inline int |
474 | debug_next_entry(file_private_info_t *p_info) | ||
393 | { | 475 | { |
394 | debug_info_t *id = p_info->debug_info_snap; | 476 | debug_info_t *id; |
477 | |||
478 | id = p_info->debug_info_snap; | ||
395 | if(p_info->act_entry == DEBUG_PROLOG_ENTRY){ | 479 | if(p_info->act_entry == DEBUG_PROLOG_ENTRY){ |
396 | p_info->act_entry = 0; | 480 | p_info->act_entry = 0; |
481 | p_info->act_page = 0; | ||
397 | goto out; | 482 | goto out; |
398 | } | 483 | } |
399 | if ((p_info->act_entry += id->entry_size) | 484 | if(!id->areas) |
400 | > ((PAGE_SIZE << (id->page_order)) | 485 | return 1; |
401 | - id->entry_size)){ | 486 | p_info->act_entry += id->entry_size; |
402 | 487 | /* switch to next page, if we reached the end of the page */ | |
403 | /* next area */ | 488 | if (p_info->act_entry > (PAGE_SIZE - id->entry_size)){ |
489 | /* next page */ | ||
404 | p_info->act_entry = 0; | 490 | p_info->act_entry = 0; |
405 | p_info->act_area++; | 491 | p_info->act_page += 1; |
492 | if((p_info->act_page % id->pages_per_area) == 0) { | ||
493 | /* next area */ | ||
494 | p_info->act_area++; | ||
495 | p_info->act_page=0; | ||
496 | } | ||
406 | if(p_info->act_area >= id->nr_areas) | 497 | if(p_info->act_area >= id->nr_areas) |
407 | return 1; | 498 | return 1; |
408 | } | 499 | } |
@@ -416,13 +507,14 @@ out: | |||
416 | * - copies formated debug entries to the user buffer | 507 | * - copies formated debug entries to the user buffer |
417 | */ | 508 | */ |
418 | 509 | ||
419 | static ssize_t debug_output(struct file *file, /* file descriptor */ | 510 | static ssize_t |
420 | char __user *user_buf, /* user buffer */ | 511 | debug_output(struct file *file, /* file descriptor */ |
421 | size_t len, /* length of buffer */ | 512 | char __user *user_buf, /* user buffer */ |
422 | loff_t *offset) /* offset in the file */ | 513 | size_t len, /* length of buffer */ |
514 | loff_t *offset) /* offset in the file */ | ||
423 | { | 515 | { |
424 | size_t count = 0; | 516 | size_t count = 0; |
425 | size_t entry_offset, size = 0; | 517 | size_t entry_offset; |
426 | file_private_info_t *p_info; | 518 | file_private_info_t *p_info; |
427 | 519 | ||
428 | p_info = ((file_private_info_t *) file->private_data); | 520 | p_info = ((file_private_info_t *) file->private_data); |
@@ -430,27 +522,33 @@ static ssize_t debug_output(struct file *file, /* file descriptor */ | |||
430 | return -EPIPE; | 522 | return -EPIPE; |
431 | if(p_info->act_area >= p_info->debug_info_snap->nr_areas) | 523 | if(p_info->act_area >= p_info->debug_info_snap->nr_areas) |
432 | return 0; | 524 | return 0; |
433 | |||
434 | entry_offset = p_info->act_entry_offset; | 525 | entry_offset = p_info->act_entry_offset; |
435 | |||
436 | while(count < len){ | 526 | while(count < len){ |
437 | size = debug_format_entry(p_info); | 527 | int formatted_line_size; |
438 | size = min((len - count), (size - entry_offset)); | 528 | int formatted_line_residue; |
439 | 529 | int user_buf_residue; | |
440 | if(size){ | 530 | size_t copy_size; |
441 | if (copy_to_user(user_buf + count, | 531 | |
442 | p_info->temp_buf + entry_offset, size)) | 532 | formatted_line_size = debug_format_entry(p_info); |
443 | return -EFAULT; | 533 | formatted_line_residue = formatted_line_size - entry_offset; |
534 | user_buf_residue = len-count; | ||
535 | copy_size = min(user_buf_residue, formatted_line_residue); | ||
536 | if(copy_size){ | ||
537 | if (copy_to_user(user_buf + count, p_info->temp_buf | ||
538 | + entry_offset, copy_size)) | ||
539 | return -EFAULT; | ||
540 | count += copy_size; | ||
541 | entry_offset += copy_size; | ||
444 | } | 542 | } |
445 | count += size; | 543 | if(copy_size == formatted_line_residue){ |
446 | entry_offset = 0; | 544 | entry_offset = 0; |
447 | if(count != len) | 545 | if(debug_next_entry(p_info)) |
448 | if(debug_next_entry(p_info)) | ||
449 | goto out; | 546 | goto out; |
547 | } | ||
450 | } | 548 | } |
451 | out: | 549 | out: |
452 | p_info->offset = *offset + count; | 550 | p_info->offset = *offset + count; |
453 | p_info->act_entry_offset = size; | 551 | p_info->act_entry_offset = entry_offset; |
454 | *offset = p_info->offset; | 552 | *offset = p_info->offset; |
455 | return count; | 553 | return count; |
456 | } | 554 | } |
@@ -461,9 +559,9 @@ out: | |||
461 | * - calls input function of view | 559 | * - calls input function of view |
462 | */ | 560 | */ |
463 | 561 | ||
464 | static ssize_t debug_input(struct file *file, | 562 | static ssize_t |
465 | const char __user *user_buf, size_t length, | 563 | debug_input(struct file *file, const char __user *user_buf, size_t length, |
466 | loff_t *offset) | 564 | loff_t *offset) |
467 | { | 565 | { |
468 | int rc = 0; | 566 | int rc = 0; |
469 | file_private_info_t *p_info; | 567 | file_private_info_t *p_info; |
@@ -487,26 +585,23 @@ static ssize_t debug_input(struct file *file, | |||
487 | * handle | 585 | * handle |
488 | */ | 586 | */ |
489 | 587 | ||
490 | static int debug_open(struct inode *inode, struct file *file) | 588 | static int |
589 | debug_open(struct inode *inode, struct file *file) | ||
491 | { | 590 | { |
492 | int i = 0, rc = 0; | 591 | int i = 0, rc = 0; |
493 | file_private_info_t *p_info; | 592 | file_private_info_t *p_info; |
494 | debug_info_t *debug_info, *debug_info_snapshot; | 593 | debug_info_t *debug_info, *debug_info_snapshot; |
495 | 594 | ||
496 | #ifdef DEBUG | ||
497 | printk("debug_open\n"); | ||
498 | #endif | ||
499 | down(&debug_lock); | 595 | down(&debug_lock); |
500 | 596 | ||
501 | /* find debug log and view */ | 597 | /* find debug log and view */ |
502 | |||
503 | debug_info = debug_area_first; | 598 | debug_info = debug_area_first; |
504 | while(debug_info != NULL){ | 599 | while(debug_info != NULL){ |
505 | for (i = 0; i < DEBUG_MAX_VIEWS; i++) { | 600 | for (i = 0; i < DEBUG_MAX_VIEWS; i++) { |
506 | if (debug_info->views[i] == NULL) | 601 | if (!debug_info->views[i]) |
507 | continue; | 602 | continue; |
508 | else if (debug_info->proc_entries[i] == | 603 | else if (debug_info->debugfs_entries[i] == |
509 | PDE(file->f_dentry->d_inode)) { | 604 | file->f_dentry) { |
510 | goto found; /* found view ! */ | 605 | goto found; /* found view ! */ |
511 | } | 606 | } |
512 | } | 607 | } |
@@ -516,41 +611,42 @@ static int debug_open(struct inode *inode, struct file *file) | |||
516 | rc = -EINVAL; | 611 | rc = -EINVAL; |
517 | goto out; | 612 | goto out; |
518 | 613 | ||
519 | found: | 614 | found: |
520 | 615 | ||
521 | /* make snapshot of current debug areas to get it consistent */ | 616 | /* Make snapshot of current debug areas to get it consistent. */ |
617 | /* To copy all the areas is only needed, if we have a view which */ | ||
618 | /* formats the debug areas. */ | ||
522 | 619 | ||
523 | debug_info_snapshot = debug_info_copy(debug_info); | 620 | if(!debug_info->views[i]->format_proc && |
621 | !debug_info->views[i]->header_proc){ | ||
622 | debug_info_snapshot = debug_info_copy(debug_info, NO_AREAS); | ||
623 | } else { | ||
624 | debug_info_snapshot = debug_info_copy(debug_info, ALL_AREAS); | ||
625 | } | ||
524 | 626 | ||
525 | if(!debug_info_snapshot){ | 627 | if(!debug_info_snapshot){ |
526 | #ifdef DEBUG | ||
527 | printk(KERN_ERR "debug_open: debug_info_copy failed (out of mem)\n"); | ||
528 | #endif | ||
529 | rc = -ENOMEM; | 628 | rc = -ENOMEM; |
530 | goto out; | 629 | goto out; |
531 | } | 630 | } |
532 | 631 | p_info = (file_private_info_t *) kmalloc(sizeof(file_private_info_t), | |
533 | if ((file->private_data = | 632 | GFP_KERNEL); |
534 | kmalloc(sizeof(file_private_info_t), GFP_ATOMIC)) == 0) { | 633 | if(!p_info){ |
535 | #ifdef DEBUG | 634 | if(debug_info_snapshot) |
536 | printk(KERN_ERR "debug_open: kmalloc failed\n"); | 635 | debug_info_free(debug_info_snapshot); |
537 | #endif | ||
538 | debug_info_free(debug_info_snapshot); | ||
539 | rc = -ENOMEM; | 636 | rc = -ENOMEM; |
540 | goto out; | 637 | goto out; |
541 | } | 638 | } |
542 | p_info = (file_private_info_t *) file->private_data; | ||
543 | p_info->offset = 0; | 639 | p_info->offset = 0; |
544 | p_info->debug_info_snap = debug_info_snapshot; | 640 | p_info->debug_info_snap = debug_info_snapshot; |
545 | p_info->debug_info_org = debug_info; | 641 | p_info->debug_info_org = debug_info; |
546 | p_info->view = debug_info->views[i]; | 642 | p_info->view = debug_info->views[i]; |
547 | p_info->act_area = 0; | 643 | p_info->act_area = 0; |
644 | p_info->act_page = 0; | ||
548 | p_info->act_entry = DEBUG_PROLOG_ENTRY; | 645 | p_info->act_entry = DEBUG_PROLOG_ENTRY; |
549 | p_info->act_entry_offset = 0; | 646 | p_info->act_entry_offset = 0; |
550 | 647 | file->private_data = p_info; | |
551 | debug_info_get(debug_info); | 648 | debug_info_get(debug_info); |
552 | 649 | out: | |
553 | out: | ||
554 | up(&debug_lock); | 650 | up(&debug_lock); |
555 | return rc; | 651 | return rc; |
556 | } | 652 | } |
@@ -561,14 +657,13 @@ static int debug_open(struct inode *inode, struct file *file) | |||
561 | * - deletes private_data area of the file handle | 657 | * - deletes private_data area of the file handle |
562 | */ | 658 | */ |
563 | 659 | ||
564 | static int debug_close(struct inode *inode, struct file *file) | 660 | static int |
661 | debug_close(struct inode *inode, struct file *file) | ||
565 | { | 662 | { |
566 | file_private_info_t *p_info; | 663 | file_private_info_t *p_info; |
567 | #ifdef DEBUG | ||
568 | printk("debug_close\n"); | ||
569 | #endif | ||
570 | p_info = (file_private_info_t *) file->private_data; | 664 | p_info = (file_private_info_t *) file->private_data; |
571 | debug_info_free(p_info->debug_info_snap); | 665 | if(p_info->debug_info_snap) |
666 | debug_info_free(p_info->debug_info_snap); | ||
572 | debug_info_put(p_info->debug_info_org); | 667 | debug_info_put(p_info->debug_info_org); |
573 | kfree(file->private_data); | 668 | kfree(file->private_data); |
574 | return 0; /* success */ | 669 | return 0; /* success */ |
@@ -580,8 +675,8 @@ static int debug_close(struct inode *inode, struct file *file) | |||
580 | * - returns handle for debug area | 675 | * - returns handle for debug area |
581 | */ | 676 | */ |
582 | 677 | ||
583 | debug_info_t *debug_register | 678 | debug_info_t* |
584 | (char *name, int page_order, int nr_areas, int buf_size) | 679 | debug_register (char *name, int pages_per_area, int nr_areas, int buf_size) |
585 | { | 680 | { |
586 | debug_info_t *rc = NULL; | 681 | debug_info_t *rc = NULL; |
587 | 682 | ||
@@ -591,18 +686,14 @@ debug_info_t *debug_register | |||
591 | 686 | ||
592 | /* create new debug_info */ | 687 | /* create new debug_info */ |
593 | 688 | ||
594 | rc = debug_info_create(name, page_order, nr_areas, buf_size); | 689 | rc = debug_info_create(name, pages_per_area, nr_areas, buf_size); |
595 | if(!rc) | 690 | if(!rc) |
596 | goto out; | 691 | goto out; |
597 | debug_register_view(rc, &debug_level_view); | 692 | debug_register_view(rc, &debug_level_view); |
598 | debug_register_view(rc, &debug_flush_view); | 693 | debug_register_view(rc, &debug_flush_view); |
599 | #ifdef DEBUG | 694 | debug_register_view(rc, &debug_pages_view); |
600 | printk(KERN_INFO | 695 | out: |
601 | "debug: reserved %d areas of %d pages for debugging %s\n", | 696 | if (!rc){ |
602 | nr_areas, 1 << page_order, rc->name); | ||
603 | #endif | ||
604 | out: | ||
605 | if (rc == NULL){ | ||
606 | printk(KERN_ERR "debug: debug_register failed for %s\n",name); | 697 | printk(KERN_ERR "debug: debug_register failed for %s\n",name); |
607 | } | 698 | } |
608 | up(&debug_lock); | 699 | up(&debug_lock); |
@@ -614,27 +705,65 @@ debug_info_t *debug_register | |||
614 | * - give back debug area | 705 | * - give back debug area |
615 | */ | 706 | */ |
616 | 707 | ||
617 | void debug_unregister(debug_info_t * id) | 708 | void |
709 | debug_unregister(debug_info_t * id) | ||
618 | { | 710 | { |
619 | if (!id) | 711 | if (!id) |
620 | goto out; | 712 | goto out; |
621 | down(&debug_lock); | 713 | down(&debug_lock); |
622 | #ifdef DEBUG | ||
623 | printk(KERN_INFO "debug: unregistering %s\n", id->name); | ||
624 | #endif | ||
625 | debug_info_put(id); | 714 | debug_info_put(id); |
626 | up(&debug_lock); | 715 | up(&debug_lock); |
627 | 716 | ||
628 | out: | 717 | out: |
629 | return; | 718 | return; |
630 | } | 719 | } |
631 | 720 | ||
632 | /* | 721 | /* |
722 | * debug_set_size: | ||
723 | * - set area size (number of pages) and number of areas | ||
724 | */ | ||
725 | static int | ||
726 | debug_set_size(debug_info_t* id, int nr_areas, int pages_per_area) | ||
727 | { | ||
728 | unsigned long flags; | ||
729 | debug_entry_t *** new_areas; | ||
730 | int rc=0; | ||
731 | |||
732 | if(!id || (nr_areas <= 0) || (pages_per_area < 0)) | ||
733 | return -EINVAL; | ||
734 | if(pages_per_area > 0){ | ||
735 | new_areas = debug_areas_alloc(pages_per_area, nr_areas); | ||
736 | if(!new_areas) { | ||
737 | printk(KERN_WARNING "debug: could not allocate memory "\ | ||
738 | "for pagenumber: %i\n",pages_per_area); | ||
739 | rc = -ENOMEM; | ||
740 | goto out; | ||
741 | } | ||
742 | } else { | ||
743 | new_areas = NULL; | ||
744 | } | ||
745 | spin_lock_irqsave(&id->lock,flags); | ||
746 | debug_areas_free(id); | ||
747 | id->areas = new_areas; | ||
748 | id->nr_areas = nr_areas; | ||
749 | id->pages_per_area = pages_per_area; | ||
750 | id->active_area = 0; | ||
751 | memset(id->active_entries,0,sizeof(int)*id->nr_areas); | ||
752 | memset(id->active_pages, 0, sizeof(int)*id->nr_areas); | ||
753 | spin_unlock_irqrestore(&id->lock,flags); | ||
754 | printk(KERN_INFO "debug: %s: set new size (%i pages)\n"\ | ||
755 | ,id->name, pages_per_area); | ||
756 | out: | ||
757 | return rc; | ||
758 | } | ||
759 | |||
760 | /* | ||
633 | * debug_set_level: | 761 | * debug_set_level: |
634 | * - set actual debug level | 762 | * - set actual debug level |
635 | */ | 763 | */ |
636 | 764 | ||
637 | void debug_set_level(debug_info_t* id, int new_level) | 765 | void |
766 | debug_set_level(debug_info_t* id, int new_level) | ||
638 | { | 767 | { |
639 | unsigned long flags; | 768 | unsigned long flags; |
640 | if(!id) | 769 | if(!id) |
@@ -649,10 +778,6 @@ void debug_set_level(debug_info_t* id, int new_level) | |||
649 | id->name, new_level, 0, DEBUG_MAX_LEVEL); | 778 | id->name, new_level, 0, DEBUG_MAX_LEVEL); |
650 | } else { | 779 | } else { |
651 | id->level = new_level; | 780 | id->level = new_level; |
652 | #ifdef DEBUG | ||
653 | printk(KERN_INFO | ||
654 | "debug: %s: new level %i\n",id->name,id->level); | ||
655 | #endif | ||
656 | } | 781 | } |
657 | spin_unlock_irqrestore(&id->lock,flags); | 782 | spin_unlock_irqrestore(&id->lock,flags); |
658 | } | 783 | } |
@@ -663,11 +788,16 @@ void debug_set_level(debug_info_t* id, int new_level) | |||
663 | * - set active entry to next in the ring buffer | 788 | * - set active entry to next in the ring buffer |
664 | */ | 789 | */ |
665 | 790 | ||
666 | extern inline void proceed_active_entry(debug_info_t * id) | 791 | extern inline void |
792 | proceed_active_entry(debug_info_t * id) | ||
667 | { | 793 | { |
668 | if ((id->active_entry[id->active_area] += id->entry_size) | 794 | if ((id->active_entries[id->active_area] += id->entry_size) |
669 | > ((PAGE_SIZE << (id->page_order)) - id->entry_size)) | 795 | > (PAGE_SIZE - id->entry_size)){ |
670 | id->active_entry[id->active_area] = 0; | 796 | id->active_entries[id->active_area] = 0; |
797 | id->active_pages[id->active_area] = | ||
798 | (id->active_pages[id->active_area] + 1) % | ||
799 | id->pages_per_area; | ||
800 | } | ||
671 | } | 801 | } |
672 | 802 | ||
673 | /* | 803 | /* |
@@ -675,7 +805,8 @@ extern inline void proceed_active_entry(debug_info_t * id) | |||
675 | * - set active area to next in the ring buffer | 805 | * - set active area to next in the ring buffer |
676 | */ | 806 | */ |
677 | 807 | ||
678 | extern inline void proceed_active_area(debug_info_t * id) | 808 | extern inline void |
809 | proceed_active_area(debug_info_t * id) | ||
679 | { | 810 | { |
680 | id->active_area++; | 811 | id->active_area++; |
681 | id->active_area = id->active_area % id->nr_areas; | 812 | id->active_area = id->active_area % id->nr_areas; |
@@ -685,10 +816,12 @@ extern inline void proceed_active_area(debug_info_t * id) | |||
685 | * get_active_entry: | 816 | * get_active_entry: |
686 | */ | 817 | */ |
687 | 818 | ||
688 | extern inline debug_entry_t *get_active_entry(debug_info_t * id) | 819 | extern inline debug_entry_t* |
820 | get_active_entry(debug_info_t * id) | ||
689 | { | 821 | { |
690 | return (debug_entry_t *) ((char *) id->areas[id->active_area] + | 822 | return (debug_entry_t *) (((char *) id->areas[id->active_area] |
691 | id->active_entry[id->active_area]); | 823 | [id->active_pages[id->active_area]]) + |
824 | id->active_entries[id->active_area]); | ||
692 | } | 825 | } |
693 | 826 | ||
694 | /* | 827 | /* |
@@ -696,8 +829,9 @@ extern inline debug_entry_t *get_active_entry(debug_info_t * id) | |||
696 | * - set timestamp, caller address, cpu number etc. | 829 | * - set timestamp, caller address, cpu number etc. |
697 | */ | 830 | */ |
698 | 831 | ||
699 | extern inline void debug_finish_entry(debug_info_t * id, debug_entry_t* active, | 832 | extern inline void |
700 | int level, int exception) | 833 | debug_finish_entry(debug_info_t * id, debug_entry_t* active, int level, |
834 | int exception) | ||
701 | { | 835 | { |
702 | STCK(active->id.stck); | 836 | STCK(active->id.stck); |
703 | active->id.fields.cpuid = smp_processor_id(); | 837 | active->id.fields.cpuid = smp_processor_id(); |
@@ -721,7 +855,8 @@ static int debug_active=1; | |||
721 | * always allow read, allow write only if debug_stoppable is set or | 855 | * always allow read, allow write only if debug_stoppable is set or |
722 | * if debug_active is already off | 856 | * if debug_active is already off |
723 | */ | 857 | */ |
724 | static int s390dbf_procactive(ctl_table *table, int write, struct file *filp, | 858 | static int |
859 | s390dbf_procactive(ctl_table *table, int write, struct file *filp, | ||
725 | void __user *buffer, size_t *lenp, loff_t *ppos) | 860 | void __user *buffer, size_t *lenp, loff_t *ppos) |
726 | { | 861 | { |
727 | if (!write || debug_stoppable || !debug_active) | 862 | if (!write || debug_stoppable || !debug_active) |
@@ -766,7 +901,8 @@ static struct ctl_table s390dbf_dir_table[] = { | |||
766 | 901 | ||
767 | struct ctl_table_header *s390dbf_sysctl_header; | 902 | struct ctl_table_header *s390dbf_sysctl_header; |
768 | 903 | ||
769 | void debug_stop_all(void) | 904 | void |
905 | debug_stop_all(void) | ||
770 | { | 906 | { |
771 | if (debug_stoppable) | 907 | if (debug_stoppable) |
772 | debug_active = 0; | 908 | debug_active = 0; |
@@ -778,13 +914,13 @@ void debug_stop_all(void) | |||
778 | * - write debug entry with given size | 914 | * - write debug entry with given size |
779 | */ | 915 | */ |
780 | 916 | ||
781 | debug_entry_t *debug_event_common(debug_info_t * id, int level, const void *buf, | 917 | debug_entry_t* |
782 | int len) | 918 | debug_event_common(debug_info_t * id, int level, const void *buf, int len) |
783 | { | 919 | { |
784 | unsigned long flags; | 920 | unsigned long flags; |
785 | debug_entry_t *active; | 921 | debug_entry_t *active; |
786 | 922 | ||
787 | if (!debug_active) | 923 | if (!debug_active || !id->areas) |
788 | return NULL; | 924 | return NULL; |
789 | spin_lock_irqsave(&id->lock, flags); | 925 | spin_lock_irqsave(&id->lock, flags); |
790 | active = get_active_entry(id); | 926 | active = get_active_entry(id); |
@@ -801,13 +937,13 @@ debug_entry_t *debug_event_common(debug_info_t * id, int level, const void *buf, | |||
801 | * - write debug entry with given size and switch to next debug area | 937 | * - write debug entry with given size and switch to next debug area |
802 | */ | 938 | */ |
803 | 939 | ||
804 | debug_entry_t *debug_exception_common(debug_info_t * id, int level, | 940 | debug_entry_t |
805 | const void *buf, int len) | 941 | *debug_exception_common(debug_info_t * id, int level, const void *buf, int len) |
806 | { | 942 | { |
807 | unsigned long flags; | 943 | unsigned long flags; |
808 | debug_entry_t *active; | 944 | debug_entry_t *active; |
809 | 945 | ||
810 | if (!debug_active) | 946 | if (!debug_active || !id->areas) |
811 | return NULL; | 947 | return NULL; |
812 | spin_lock_irqsave(&id->lock, flags); | 948 | spin_lock_irqsave(&id->lock, flags); |
813 | active = get_active_entry(id); | 949 | active = get_active_entry(id); |
@@ -823,7 +959,8 @@ debug_entry_t *debug_exception_common(debug_info_t * id, int level, | |||
823 | * counts arguments in format string for sprintf view | 959 | * counts arguments in format string for sprintf view |
824 | */ | 960 | */ |
825 | 961 | ||
826 | extern inline int debug_count_numargs(char *string) | 962 | extern inline int |
963 | debug_count_numargs(char *string) | ||
827 | { | 964 | { |
828 | int numargs=0; | 965 | int numargs=0; |
829 | 966 | ||
@@ -838,8 +975,8 @@ extern inline int debug_count_numargs(char *string) | |||
838 | * debug_sprintf_event: | 975 | * debug_sprintf_event: |
839 | */ | 976 | */ |
840 | 977 | ||
841 | debug_entry_t *debug_sprintf_event(debug_info_t* id, | 978 | debug_entry_t* |
842 | int level,char *string,...) | 979 | debug_sprintf_event(debug_info_t* id, int level,char *string,...) |
843 | { | 980 | { |
844 | va_list ap; | 981 | va_list ap; |
845 | int numargs,idx; | 982 | int numargs,idx; |
@@ -849,7 +986,7 @@ debug_entry_t *debug_sprintf_event(debug_info_t* id, | |||
849 | 986 | ||
850 | if((!id) || (level > id->level)) | 987 | if((!id) || (level > id->level)) |
851 | return NULL; | 988 | return NULL; |
852 | if (!debug_active) | 989 | if (!debug_active || !id->areas) |
853 | return NULL; | 990 | return NULL; |
854 | numargs=debug_count_numargs(string); | 991 | numargs=debug_count_numargs(string); |
855 | 992 | ||
@@ -871,8 +1008,8 @@ debug_entry_t *debug_sprintf_event(debug_info_t* id, | |||
871 | * debug_sprintf_exception: | 1008 | * debug_sprintf_exception: |
872 | */ | 1009 | */ |
873 | 1010 | ||
874 | debug_entry_t *debug_sprintf_exception(debug_info_t* id, | 1011 | debug_entry_t* |
875 | int level,char *string,...) | 1012 | debug_sprintf_exception(debug_info_t* id, int level,char *string,...) |
876 | { | 1013 | { |
877 | va_list ap; | 1014 | va_list ap; |
878 | int numargs,idx; | 1015 | int numargs,idx; |
@@ -882,7 +1019,7 @@ debug_entry_t *debug_sprintf_exception(debug_info_t* id, | |||
882 | 1019 | ||
883 | if((!id) || (level > id->level)) | 1020 | if((!id) || (level > id->level)) |
884 | return NULL; | 1021 | return NULL; |
885 | if (!debug_active) | 1022 | if (!debug_active || !id->areas) |
886 | return NULL; | 1023 | return NULL; |
887 | 1024 | ||
888 | numargs=debug_count_numargs(string); | 1025 | numargs=debug_count_numargs(string); |
@@ -906,15 +1043,14 @@ debug_entry_t *debug_sprintf_exception(debug_info_t* id, | |||
906 | * - is called exactly once to initialize the debug feature | 1043 | * - is called exactly once to initialize the debug feature |
907 | */ | 1044 | */ |
908 | 1045 | ||
909 | static int __init debug_init(void) | 1046 | static int |
1047 | __init debug_init(void) | ||
910 | { | 1048 | { |
911 | int rc = 0; | 1049 | int rc = 0; |
912 | 1050 | ||
913 | s390dbf_sysctl_header = register_sysctl_table(s390dbf_dir_table, 1); | 1051 | s390dbf_sysctl_header = register_sysctl_table(s390dbf_dir_table, 1); |
914 | down(&debug_lock); | 1052 | down(&debug_lock); |
915 | #ifdef CONFIG_PROC_FS | 1053 | debug_debugfs_root_entry = debugfs_create_dir(DEBUG_DIR_ROOT,NULL); |
916 | debug_proc_root_entry = proc_mkdir(DEBUG_DIR_ROOT, NULL); | ||
917 | #endif /* CONFIG_PROC_FS */ | ||
918 | printk(KERN_INFO "debug: Initialization complete\n"); | 1054 | printk(KERN_INFO "debug: Initialization complete\n"); |
919 | initialized = 1; | 1055 | initialized = 1; |
920 | up(&debug_lock); | 1056 | up(&debug_lock); |
@@ -926,13 +1062,14 @@ static int __init debug_init(void) | |||
926 | * debug_register_view: | 1062 | * debug_register_view: |
927 | */ | 1063 | */ |
928 | 1064 | ||
929 | int debug_register_view(debug_info_t * id, struct debug_view *view) | 1065 | int |
1066 | debug_register_view(debug_info_t * id, struct debug_view *view) | ||
930 | { | 1067 | { |
931 | int rc = 0; | 1068 | int rc = 0; |
932 | int i; | 1069 | int i; |
933 | unsigned long flags; | 1070 | unsigned long flags; |
934 | mode_t mode = S_IFREG; | 1071 | mode_t mode = S_IFREG; |
935 | struct proc_dir_entry *pde; | 1072 | struct dentry *pde; |
936 | 1073 | ||
937 | if (!id) | 1074 | if (!id) |
938 | goto out; | 1075 | goto out; |
@@ -940,16 +1077,17 @@ int debug_register_view(debug_info_t * id, struct debug_view *view) | |||
940 | mode |= S_IRUSR; | 1077 | mode |= S_IRUSR; |
941 | if (view->input_proc) | 1078 | if (view->input_proc) |
942 | mode |= S_IWUSR; | 1079 | mode |= S_IWUSR; |
943 | pde = create_proc_entry(view->name, mode, id->proc_root_entry); | 1080 | pde = debugfs_create_file(view->name, mode, id->debugfs_root_entry, |
1081 | NULL, &debug_file_ops); | ||
944 | if (!pde){ | 1082 | if (!pde){ |
945 | printk(KERN_WARNING "debug: create_proc_entry() failed! Cannot register view %s/%s\n", id->name,view->name); | 1083 | printk(KERN_WARNING "debug: debugfs_create_file() failed!"\ |
1084 | " Cannot register view %s/%s\n", id->name,view->name); | ||
946 | rc = -1; | 1085 | rc = -1; |
947 | goto out; | 1086 | goto out; |
948 | } | 1087 | } |
949 | |||
950 | spin_lock_irqsave(&id->lock, flags); | 1088 | spin_lock_irqsave(&id->lock, flags); |
951 | for (i = 0; i < DEBUG_MAX_VIEWS; i++) { | 1089 | for (i = 0; i < DEBUG_MAX_VIEWS; i++) { |
952 | if (id->views[i] == NULL) | 1090 | if (!id->views[i]) |
953 | break; | 1091 | break; |
954 | } | 1092 | } |
955 | if (i == DEBUG_MAX_VIEWS) { | 1093 | if (i == DEBUG_MAX_VIEWS) { |
@@ -957,16 +1095,14 @@ int debug_register_view(debug_info_t * id, struct debug_view *view) | |||
957 | id->name,view->name); | 1095 | id->name,view->name); |
958 | printk(KERN_WARNING | 1096 | printk(KERN_WARNING |
959 | "debug: maximum number of views reached (%i)!\n", i); | 1097 | "debug: maximum number of views reached (%i)!\n", i); |
960 | remove_proc_entry(pde->name, id->proc_root_entry); | 1098 | debugfs_remove(pde); |
961 | rc = -1; | 1099 | rc = -1; |
962 | } | 1100 | } else { |
963 | else { | ||
964 | id->views[i] = view; | 1101 | id->views[i] = view; |
965 | pde->proc_fops = &debug_file_ops; | 1102 | id->debugfs_entries[i] = pde; |
966 | id->proc_entries[i] = pde; | ||
967 | } | 1103 | } |
968 | spin_unlock_irqrestore(&id->lock, flags); | 1104 | spin_unlock_irqrestore(&id->lock, flags); |
969 | out: | 1105 | out: |
970 | return rc; | 1106 | return rc; |
971 | } | 1107 | } |
972 | 1108 | ||
@@ -974,7 +1110,8 @@ int debug_register_view(debug_info_t * id, struct debug_view *view) | |||
974 | * debug_unregister_view: | 1110 | * debug_unregister_view: |
975 | */ | 1111 | */ |
976 | 1112 | ||
977 | int debug_unregister_view(debug_info_t * id, struct debug_view *view) | 1113 | int |
1114 | debug_unregister_view(debug_info_t * id, struct debug_view *view) | ||
978 | { | 1115 | { |
979 | int rc = 0; | 1116 | int rc = 0; |
980 | int i; | 1117 | int i; |
@@ -990,15 +1127,46 @@ int debug_unregister_view(debug_info_t * id, struct debug_view *view) | |||
990 | if (i == DEBUG_MAX_VIEWS) | 1127 | if (i == DEBUG_MAX_VIEWS) |
991 | rc = -1; | 1128 | rc = -1; |
992 | else { | 1129 | else { |
993 | #ifdef CONFIG_PROC_FS | 1130 | debugfs_remove(id->debugfs_entries[i]); |
994 | remove_proc_entry(id->proc_entries[i]->name, | ||
995 | id->proc_root_entry); | ||
996 | #endif | ||
997 | id->views[i] = NULL; | 1131 | id->views[i] = NULL; |
998 | rc = 0; | 1132 | rc = 0; |
999 | } | 1133 | } |
1000 | spin_unlock_irqrestore(&id->lock, flags); | 1134 | spin_unlock_irqrestore(&id->lock, flags); |
1001 | out: | 1135 | out: |
1136 | return rc; | ||
1137 | } | ||
1138 | |||
1139 | static inline char * | ||
1140 | debug_get_user_string(const char __user *user_buf, size_t user_len) | ||
1141 | { | ||
1142 | char* buffer; | ||
1143 | |||
1144 | buffer = kmalloc(user_len + 1, GFP_KERNEL); | ||
1145 | if (!buffer) | ||
1146 | return ERR_PTR(-ENOMEM); | ||
1147 | if (copy_from_user(buffer, user_buf, user_len) != 0) { | ||
1148 | kfree(buffer); | ||
1149 | return ERR_PTR(-EFAULT); | ||
1150 | } | ||
1151 | /* got the string, now strip linefeed. */ | ||
1152 | if (buffer[user_len - 1] == '\n') | ||
1153 | buffer[user_len - 1] = 0; | ||
1154 | else | ||
1155 | buffer[user_len] = 0; | ||
1156 | return buffer; | ||
1157 | } | ||
1158 | |||
1159 | static inline int | ||
1160 | debug_get_uint(char *buf) | ||
1161 | { | ||
1162 | int rc; | ||
1163 | |||
1164 | for(; isspace(*buf); buf++); | ||
1165 | rc = simple_strtoul(buf, &buf, 10); | ||
1166 | if(*buf){ | ||
1167 | printk("debug: no integer specified!\n"); | ||
1168 | rc = -EINVAL; | ||
1169 | } | ||
1002 | return rc; | 1170 | return rc; |
1003 | } | 1171 | } |
1004 | 1172 | ||
@@ -1011,13 +1179,69 @@ int debug_unregister_view(debug_info_t * id, struct debug_view *view) | |||
1011 | * prints out actual debug level | 1179 | * prints out actual debug level |
1012 | */ | 1180 | */ |
1013 | 1181 | ||
1014 | static int debug_prolog_level_fn(debug_info_t * id, | 1182 | static int |
1183 | debug_prolog_pages_fn(debug_info_t * id, | ||
1015 | struct debug_view *view, char *out_buf) | 1184 | struct debug_view *view, char *out_buf) |
1016 | { | 1185 | { |
1186 | return sprintf(out_buf, "%i\n", id->pages_per_area); | ||
1187 | } | ||
1188 | |||
1189 | /* | ||
1190 | * reads new size (number of pages per debug area) | ||
1191 | */ | ||
1192 | |||
1193 | static int | ||
1194 | debug_input_pages_fn(debug_info_t * id, struct debug_view *view, | ||
1195 | struct file *file, const char __user *user_buf, | ||
1196 | size_t user_len, loff_t * offset) | ||
1197 | { | ||
1198 | char *str; | ||
1199 | int rc,new_pages; | ||
1200 | |||
1201 | if (user_len > 0x10000) | ||
1202 | user_len = 0x10000; | ||
1203 | if (*offset != 0){ | ||
1204 | rc = -EPIPE; | ||
1205 | goto out; | ||
1206 | } | ||
1207 | str = debug_get_user_string(user_buf,user_len); | ||
1208 | if(IS_ERR(str)){ | ||
1209 | rc = PTR_ERR(str); | ||
1210 | goto out; | ||
1211 | } | ||
1212 | new_pages = debug_get_uint(str); | ||
1213 | if(new_pages < 0){ | ||
1214 | rc = -EINVAL; | ||
1215 | goto free_str; | ||
1216 | } | ||
1217 | rc = debug_set_size(id,id->nr_areas, new_pages); | ||
1218 | if(rc != 0){ | ||
1219 | rc = -EINVAL; | ||
1220 | goto free_str; | ||
1221 | } | ||
1222 | rc = user_len; | ||
1223 | free_str: | ||
1224 | kfree(str); | ||
1225 | out: | ||
1226 | *offset += user_len; | ||
1227 | return rc; /* number of input characters */ | ||
1228 | } | ||
1229 | |||
1230 | /* | ||
1231 | * prints out actual debug level | ||
1232 | */ | ||
1233 | |||
1234 | static int | ||
1235 | debug_prolog_level_fn(debug_info_t * id, struct debug_view *view, char *out_buf) | ||
1236 | { | ||
1017 | int rc = 0; | 1237 | int rc = 0; |
1018 | 1238 | ||
1019 | if(id->level == -1) rc = sprintf(out_buf,"-\n"); | 1239 | if(id->level == DEBUG_OFF_LEVEL) { |
1020 | else rc = sprintf(out_buf, "%i\n", id->level); | 1240 | rc = sprintf(out_buf,"-\n"); |
1241 | } | ||
1242 | else { | ||
1243 | rc = sprintf(out_buf, "%i\n", id->level); | ||
1244 | } | ||
1021 | return rc; | 1245 | return rc; |
1022 | } | 1246 | } |
1023 | 1247 | ||
@@ -1025,30 +1249,43 @@ static int debug_prolog_level_fn(debug_info_t * id, | |||
1025 | * reads new debug level | 1249 | * reads new debug level |
1026 | */ | 1250 | */ |
1027 | 1251 | ||
1028 | static int debug_input_level_fn(debug_info_t * id, struct debug_view *view, | 1252 | static int |
1029 | struct file *file, const char __user *user_buf, | 1253 | debug_input_level_fn(debug_info_t * id, struct debug_view *view, |
1030 | size_t in_buf_size, loff_t * offset) | 1254 | struct file *file, const char __user *user_buf, |
1255 | size_t user_len, loff_t * offset) | ||
1031 | { | 1256 | { |
1032 | char input_buf[1]; | 1257 | char *str; |
1033 | int rc = in_buf_size; | 1258 | int rc,new_level; |
1034 | 1259 | ||
1035 | if (*offset != 0) | 1260 | if (user_len > 0x10000) |
1261 | user_len = 0x10000; | ||
1262 | if (*offset != 0){ | ||
1263 | rc = -EPIPE; | ||
1036 | goto out; | 1264 | goto out; |
1037 | if (copy_from_user(input_buf, user_buf, 1)){ | 1265 | } |
1038 | rc = -EFAULT; | 1266 | str = debug_get_user_string(user_buf,user_len); |
1267 | if(IS_ERR(str)){ | ||
1268 | rc = PTR_ERR(str); | ||
1039 | goto out; | 1269 | goto out; |
1040 | } | 1270 | } |
1041 | if (isdigit(input_buf[0])) { | 1271 | if(str[0] == '-'){ |
1042 | int new_level = ((int) input_buf[0] - (int) '0'); | ||
1043 | debug_set_level(id, new_level); | ||
1044 | } else if(input_buf[0] == '-') { | ||
1045 | debug_set_level(id, DEBUG_OFF_LEVEL); | 1272 | debug_set_level(id, DEBUG_OFF_LEVEL); |
1273 | rc = user_len; | ||
1274 | goto free_str; | ||
1046 | } else { | 1275 | } else { |
1047 | printk(KERN_INFO "debug: level `%c` is not valid\n", | 1276 | new_level = debug_get_uint(str); |
1048 | input_buf[0]); | ||
1049 | } | 1277 | } |
1050 | out: | 1278 | if(new_level < 0) { |
1051 | *offset += in_buf_size; | 1279 | printk(KERN_INFO "debug: level `%s` is not valid\n", str); |
1280 | rc = -EINVAL; | ||
1281 | } else { | ||
1282 | debug_set_level(id, new_level); | ||
1283 | rc = user_len; | ||
1284 | } | ||
1285 | free_str: | ||
1286 | kfree(str); | ||
1287 | out: | ||
1288 | *offset += user_len; | ||
1052 | return rc; /* number of input characters */ | 1289 | return rc; /* number of input characters */ |
1053 | } | 1290 | } |
1054 | 1291 | ||
@@ -1057,29 +1294,36 @@ static int debug_input_level_fn(debug_info_t * id, struct debug_view *view, | |||
1057 | * flushes debug areas | 1294 | * flushes debug areas |
1058 | */ | 1295 | */ |
1059 | 1296 | ||
1060 | void debug_flush(debug_info_t* id, int area) | 1297 | void |
1298 | debug_flush(debug_info_t* id, int area) | ||
1061 | { | 1299 | { |
1062 | unsigned long flags; | 1300 | unsigned long flags; |
1063 | int i; | 1301 | int i,j; |
1064 | 1302 | ||
1065 | if(!id) | 1303 | if(!id || !id->areas) |
1066 | return; | 1304 | return; |
1067 | spin_lock_irqsave(&id->lock,flags); | 1305 | spin_lock_irqsave(&id->lock,flags); |
1068 | if(area == DEBUG_FLUSH_ALL){ | 1306 | if(area == DEBUG_FLUSH_ALL){ |
1069 | id->active_area = 0; | 1307 | id->active_area = 0; |
1070 | memset(id->active_entry, 0, id->nr_areas * sizeof(int)); | 1308 | memset(id->active_entries, 0, id->nr_areas * sizeof(int)); |
1071 | for (i = 0; i < id->nr_areas; i++) | 1309 | for (i = 0; i < id->nr_areas; i++) { |
1072 | memset(id->areas[i], 0, PAGE_SIZE << id->page_order); | 1310 | id->active_pages[i] = 0; |
1311 | for(j = 0; j < id->pages_per_area; j++) { | ||
1312 | memset(id->areas[i][j], 0, PAGE_SIZE); | ||
1313 | } | ||
1314 | } | ||
1073 | printk(KERN_INFO "debug: %s: all areas flushed\n",id->name); | 1315 | printk(KERN_INFO "debug: %s: all areas flushed\n",id->name); |
1074 | } else if(area >= 0 && area < id->nr_areas) { | 1316 | } else if(area >= 0 && area < id->nr_areas) { |
1075 | id->active_entry[area] = 0; | 1317 | id->active_entries[area] = 0; |
1076 | memset(id->areas[area], 0, PAGE_SIZE << id->page_order); | 1318 | id->active_pages[area] = 0; |
1077 | printk(KERN_INFO | 1319 | for(i = 0; i < id->pages_per_area; i++) { |
1078 | "debug: %s: area %i has been flushed\n", | 1320 | memset(id->areas[area][i],0,PAGE_SIZE); |
1321 | } | ||
1322 | printk(KERN_INFO "debug: %s: area %i has been flushed\n", | ||
1079 | id->name, area); | 1323 | id->name, area); |
1080 | } else { | 1324 | } else { |
1081 | printk(KERN_INFO | 1325 | printk(KERN_INFO |
1082 | "debug: %s: area %i cannot be flushed (range: %i - %i)\n", | 1326 | "debug: %s: area %i cannot be flushed (range: %i - %i)\n", |
1083 | id->name, area, 0, id->nr_areas-1); | 1327 | id->name, area, 0, id->nr_areas-1); |
1084 | } | 1328 | } |
1085 | spin_unlock_irqrestore(&id->lock,flags); | 1329 | spin_unlock_irqrestore(&id->lock,flags); |
@@ -1089,15 +1333,20 @@ void debug_flush(debug_info_t* id, int area) | |||
1089 | * view function: flushes debug areas | 1333 | * view function: flushes debug areas |
1090 | */ | 1334 | */ |
1091 | 1335 | ||
1092 | static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view, | 1336 | static int |
1093 | struct file *file, const char __user *user_buf, | 1337 | debug_input_flush_fn(debug_info_t * id, struct debug_view *view, |
1094 | size_t in_buf_size, loff_t * offset) | 1338 | struct file *file, const char __user *user_buf, |
1339 | size_t user_len, loff_t * offset) | ||
1095 | { | 1340 | { |
1096 | char input_buf[1]; | 1341 | char input_buf[1]; |
1097 | int rc = in_buf_size; | 1342 | int rc = user_len; |
1098 | 1343 | ||
1099 | if (*offset != 0) | 1344 | if (user_len > 0x10000) |
1345 | user_len = 0x10000; | ||
1346 | if (*offset != 0){ | ||
1347 | rc = -EPIPE; | ||
1100 | goto out; | 1348 | goto out; |
1349 | } | ||
1101 | if (copy_from_user(input_buf, user_buf, 1)){ | 1350 | if (copy_from_user(input_buf, user_buf, 1)){ |
1102 | rc = -EFAULT; | 1351 | rc = -EFAULT; |
1103 | goto out; | 1352 | goto out; |
@@ -1114,8 +1363,8 @@ static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view, | |||
1114 | 1363 | ||
1115 | printk(KERN_INFO "debug: area `%c` is not valid\n", input_buf[0]); | 1364 | printk(KERN_INFO "debug: area `%c` is not valid\n", input_buf[0]); |
1116 | 1365 | ||
1117 | out: | 1366 | out: |
1118 | *offset += in_buf_size; | 1367 | *offset += user_len; |
1119 | return rc; /* number of input characters */ | 1368 | return rc; /* number of input characters */ |
1120 | } | 1369 | } |
1121 | 1370 | ||
@@ -1123,8 +1372,9 @@ static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view, | |||
1123 | * prints debug header in raw format | 1372 | * prints debug header in raw format |
1124 | */ | 1373 | */ |
1125 | 1374 | ||
1126 | int debug_raw_header_fn(debug_info_t * id, struct debug_view *view, | 1375 | static int |
1127 | int area, debug_entry_t * entry, char *out_buf) | 1376 | debug_raw_header_fn(debug_info_t * id, struct debug_view *view, |
1377 | int area, debug_entry_t * entry, char *out_buf) | ||
1128 | { | 1378 | { |
1129 | int rc; | 1379 | int rc; |
1130 | 1380 | ||
@@ -1137,7 +1387,8 @@ int debug_raw_header_fn(debug_info_t * id, struct debug_view *view, | |||
1137 | * prints debug data in raw format | 1387 | * prints debug data in raw format |
1138 | */ | 1388 | */ |
1139 | 1389 | ||
1140 | static int debug_raw_format_fn(debug_info_t * id, struct debug_view *view, | 1390 | static int |
1391 | debug_raw_format_fn(debug_info_t * id, struct debug_view *view, | ||
1141 | char *out_buf, const char *in_buf) | 1392 | char *out_buf, const char *in_buf) |
1142 | { | 1393 | { |
1143 | int rc; | 1394 | int rc; |
@@ -1151,8 +1402,9 @@ static int debug_raw_format_fn(debug_info_t * id, struct debug_view *view, | |||
1151 | * prints debug data in hex/ascii format | 1402 | * prints debug data in hex/ascii format |
1152 | */ | 1403 | */ |
1153 | 1404 | ||
1154 | static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view, | 1405 | static int |
1155 | char *out_buf, const char *in_buf) | 1406 | debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view, |
1407 | char *out_buf, const char *in_buf) | ||
1156 | { | 1408 | { |
1157 | int i, rc = 0; | 1409 | int i, rc = 0; |
1158 | 1410 | ||
@@ -1176,7 +1428,8 @@ static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view, | |||
1176 | * prints header for debug entry | 1428 | * prints header for debug entry |
1177 | */ | 1429 | */ |
1178 | 1430 | ||
1179 | int debug_dflt_header_fn(debug_info_t * id, struct debug_view *view, | 1431 | int |
1432 | debug_dflt_header_fn(debug_info_t * id, struct debug_view *view, | ||
1180 | int area, debug_entry_t * entry, char *out_buf) | 1433 | int area, debug_entry_t * entry, char *out_buf) |
1181 | { | 1434 | { |
1182 | struct timeval time_val; | 1435 | struct timeval time_val; |
@@ -1210,8 +1463,9 @@ int debug_dflt_header_fn(debug_info_t * id, struct debug_view *view, | |||
1210 | 1463 | ||
1211 | #define DEBUG_SPRINTF_MAX_ARGS 10 | 1464 | #define DEBUG_SPRINTF_MAX_ARGS 10 |
1212 | 1465 | ||
1213 | int debug_sprintf_format_fn(debug_info_t * id, struct debug_view *view, | 1466 | static int |
1214 | char *out_buf, debug_sprintf_entry_t *curr_event) | 1467 | debug_sprintf_format_fn(debug_info_t * id, struct debug_view *view, |
1468 | char *out_buf, debug_sprintf_entry_t *curr_event) | ||
1215 | { | 1469 | { |
1216 | int num_longs, num_used_args = 0,i, rc = 0; | 1470 | int num_longs, num_used_args = 0,i, rc = 0; |
1217 | int index[DEBUG_SPRINTF_MAX_ARGS]; | 1471 | int index[DEBUG_SPRINTF_MAX_ARGS]; |
@@ -1251,14 +1505,10 @@ out: | |||
1251 | /* | 1505 | /* |
1252 | * clean up module | 1506 | * clean up module |
1253 | */ | 1507 | */ |
1254 | void __exit debug_exit(void) | 1508 | void |
1509 | __exit debug_exit(void) | ||
1255 | { | 1510 | { |
1256 | #ifdef DEBUG | 1511 | debugfs_remove(debug_debugfs_root_entry); |
1257 | printk("debug_cleanup_module: \n"); | ||
1258 | #endif | ||
1259 | #ifdef CONFIG_PROC_FS | ||
1260 | remove_proc_entry(debug_proc_root_entry->name, NULL); | ||
1261 | #endif /* CONFIG_PROC_FS */ | ||
1262 | unregister_sysctl_table(s390dbf_sysctl_header); | 1512 | unregister_sysctl_table(s390dbf_sysctl_header); |
1263 | return; | 1513 | return; |
1264 | } | 1514 | } |
@@ -1266,7 +1516,7 @@ void __exit debug_exit(void) | |||
1266 | /* | 1516 | /* |
1267 | * module definitions | 1517 | * module definitions |
1268 | */ | 1518 | */ |
1269 | core_initcall(debug_init); | 1519 | postcore_initcall(debug_init); |
1270 | module_exit(debug_exit); | 1520 | module_exit(debug_exit); |
1271 | MODULE_LICENSE("GPL"); | 1521 | MODULE_LICENSE("GPL"); |
1272 | 1522 | ||
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index c0e09b33febe..5b262b5d869f 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
@@ -7,6 +7,7 @@ | |||
7 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), | 7 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), |
8 | * Hartmut Penner (hp@de.ibm.com), | 8 | * Hartmut Penner (hp@de.ibm.com), |
9 | * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), | 9 | * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), |
10 | * Heiko Carstens <heiko.carstens@de.ibm.com> | ||
10 | */ | 11 | */ |
11 | 12 | ||
12 | #include <linux/sys.h> | 13 | #include <linux/sys.h> |
@@ -49,9 +50,9 @@ SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC | |||
49 | SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP | 50 | SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP |
50 | SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE | 51 | SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE |
51 | 52 | ||
52 | _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ | 53 | _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING | \ |
53 | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) | 54 | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) |
54 | _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED) | 55 | _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING) |
55 | 56 | ||
56 | STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER | 57 | STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER |
57 | STACK_SIZE = 1 << STACK_SHIFT | 58 | STACK_SIZE = 1 << STACK_SHIFT |
@@ -121,7 +122,11 @@ STACK_SIZE = 1 << STACK_SHIFT | |||
121 | bz BASED(stack_overflow) | 122 | bz BASED(stack_overflow) |
122 | 3: | 123 | 3: |
123 | #endif | 124 | #endif |
124 | 2: s %r15,BASED(.Lc_spsize) # make room for registers & psw | 125 | 2: |
126 | .endm | ||
127 | |||
128 | .macro CREATE_STACK_FRAME psworg,savearea | ||
129 | s %r15,BASED(.Lc_spsize) # make room for registers & psw | ||
125 | mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack | 130 | mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack |
126 | la %r12,\psworg | 131 | la %r12,\psworg |
127 | st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 | 132 | st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 |
@@ -161,6 +166,13 @@ __switch_to_base: | |||
161 | be __switch_to_noper-__switch_to_base(%r1) # we got away w/o bashing TLB's | 166 | be __switch_to_noper-__switch_to_base(%r1) # we got away w/o bashing TLB's |
162 | lctl %c9,%c11,__THREAD_per(%r3) # Nope we didn't | 167 | lctl %c9,%c11,__THREAD_per(%r3) # Nope we didn't |
163 | __switch_to_noper: | 168 | __switch_to_noper: |
169 | l %r4,__THREAD_info(%r2) # get thread_info of prev | ||
170 | tm __TI_flags+3(%r4),_TIF_MCCK_PENDING # machine check pending? | ||
171 | bz __switch_to_no_mcck-__switch_to_base(%r1) | ||
172 | ni __TI_flags+3(%r4),255-_TIF_MCCK_PENDING # clear flag in prev | ||
173 | l %r4,__THREAD_info(%r3) # get thread_info of next | ||
174 | oi __TI_flags+3(%r4),_TIF_MCCK_PENDING # set it in next | ||
175 | __switch_to_no_mcck: | ||
164 | stm %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task | 176 | stm %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task |
165 | st %r15,__THREAD_ksp(%r2) # store kernel stack to prev->tss.ksp | 177 | st %r15,__THREAD_ksp(%r2) # store kernel stack to prev->tss.ksp |
166 | l %r15,__THREAD_ksp(%r3) # load kernel stack from next->tss.ksp | 178 | l %r15,__THREAD_ksp(%r3) # load kernel stack from next->tss.ksp |
@@ -185,6 +197,7 @@ system_call: | |||
185 | sysc_saveall: | 197 | sysc_saveall: |
186 | SAVE_ALL_BASE __LC_SAVE_AREA | 198 | SAVE_ALL_BASE __LC_SAVE_AREA |
187 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 | 199 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 |
200 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA | ||
188 | lh %r7,0x8a # get svc number from lowcore | 201 | lh %r7,0x8a # get svc number from lowcore |
189 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 202 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
190 | sysc_vtime: | 203 | sysc_vtime: |
@@ -234,6 +247,8 @@ sysc_work_loop: | |||
234 | # One of the work bits is on. Find out which one. | 247 | # One of the work bits is on. Find out which one. |
235 | # | 248 | # |
236 | sysc_work: | 249 | sysc_work: |
250 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING | ||
251 | bo BASED(sysc_mcck_pending) | ||
237 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED | 252 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED |
238 | bo BASED(sysc_reschedule) | 253 | bo BASED(sysc_reschedule) |
239 | tm __TI_flags+3(%r9),_TIF_SIGPENDING | 254 | tm __TI_flags+3(%r9),_TIF_SIGPENDING |
@@ -253,6 +268,14 @@ sysc_reschedule: | |||
253 | br %r1 # call scheduler | 268 | br %r1 # call scheduler |
254 | 269 | ||
255 | # | 270 | # |
271 | # _TIF_MCCK_PENDING is set, call handler | ||
272 | # | ||
273 | sysc_mcck_pending: | ||
274 | l %r1,BASED(.Ls390_handle_mcck) | ||
275 | la %r14,BASED(sysc_work_loop) | ||
276 | br %r1 # TIF bit will be cleared by handler | ||
277 | |||
278 | # | ||
256 | # _TIF_SIGPENDING is set, call do_signal | 279 | # _TIF_SIGPENDING is set, call do_signal |
257 | # | 280 | # |
258 | sysc_sigpending: | 281 | sysc_sigpending: |
@@ -430,6 +453,7 @@ pgm_check_handler: | |||
430 | tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception | 453 | tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception |
431 | bnz BASED(pgm_per) # got per exception -> special case | 454 | bnz BASED(pgm_per) # got per exception -> special case |
432 | SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 | 455 | SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 |
456 | CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA | ||
433 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 457 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
434 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 458 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
435 | bz BASED(pgm_no_vtime) | 459 | bz BASED(pgm_no_vtime) |
@@ -468,6 +492,7 @@ pgm_per: | |||
468 | # | 492 | # |
469 | pgm_per_std: | 493 | pgm_per_std: |
470 | SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 | 494 | SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 |
495 | CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA | ||
471 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 496 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
472 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 497 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
473 | bz BASED(pgm_no_vtime2) | 498 | bz BASED(pgm_no_vtime2) |
@@ -493,6 +518,7 @@ pgm_no_vtime2: | |||
493 | # | 518 | # |
494 | pgm_svcper: | 519 | pgm_svcper: |
495 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 | 520 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 |
521 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA | ||
496 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 522 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
497 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 523 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
498 | bz BASED(pgm_no_vtime3) | 524 | bz BASED(pgm_no_vtime3) |
@@ -521,6 +547,7 @@ io_int_handler: | |||
521 | stck __LC_INT_CLOCK | 547 | stck __LC_INT_CLOCK |
522 | SAVE_ALL_BASE __LC_SAVE_AREA+16 | 548 | SAVE_ALL_BASE __LC_SAVE_AREA+16 |
523 | SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+16,0 | 549 | SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+16,0 |
550 | CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 | ||
524 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 551 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
525 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 552 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
526 | bz BASED(io_no_vtime) | 553 | bz BASED(io_no_vtime) |
@@ -578,9 +605,11 @@ io_work: | |||
578 | lr %r15,%r1 | 605 | lr %r15,%r1 |
579 | # | 606 | # |
580 | # One of the work bits is on. Find out which one. | 607 | # One of the work bits is on. Find out which one. |
581 | # Checked are: _TIF_SIGPENDING and _TIF_NEED_RESCHED | 608 | # Checked are: _TIF_SIGPENDING, _TIF_NEED_RESCHED and _TIF_MCCK_PENDING |
582 | # | 609 | # |
583 | io_work_loop: | 610 | io_work_loop: |
611 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING | ||
612 | bo BASED(io_mcck_pending) | ||
584 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED | 613 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED |
585 | bo BASED(io_reschedule) | 614 | bo BASED(io_reschedule) |
586 | tm __TI_flags+3(%r9),_TIF_SIGPENDING | 615 | tm __TI_flags+3(%r9),_TIF_SIGPENDING |
@@ -588,6 +617,14 @@ io_work_loop: | |||
588 | b BASED(io_leave) | 617 | b BASED(io_leave) |
589 | 618 | ||
590 | # | 619 | # |
620 | # _TIF_MCCK_PENDING is set, call handler | ||
621 | # | ||
622 | io_mcck_pending: | ||
623 | l %r1,BASED(.Ls390_handle_mcck) | ||
624 | l %r14,BASED(io_work_loop) | ||
625 | br %r1 # TIF bit will be cleared by handler | ||
626 | |||
627 | # | ||
591 | # _TIF_NEED_RESCHED is set, call schedule | 628 | # _TIF_NEED_RESCHED is set, call schedule |
592 | # | 629 | # |
593 | io_reschedule: | 630 | io_reschedule: |
@@ -621,6 +658,7 @@ ext_int_handler: | |||
621 | stck __LC_INT_CLOCK | 658 | stck __LC_INT_CLOCK |
622 | SAVE_ALL_BASE __LC_SAVE_AREA+16 | 659 | SAVE_ALL_BASE __LC_SAVE_AREA+16 |
623 | SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16,0 | 660 | SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16,0 |
661 | CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 | ||
624 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 662 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
625 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 663 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
626 | bz BASED(ext_no_vtime) | 664 | bz BASED(ext_no_vtime) |
@@ -642,19 +680,62 @@ ext_no_vtime: | |||
642 | 680 | ||
643 | .globl mcck_int_handler | 681 | .globl mcck_int_handler |
644 | mcck_int_handler: | 682 | mcck_int_handler: |
645 | STORE_TIMER __LC_ASYNC_ENTER_TIMER | 683 | spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer |
684 | lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs | ||
646 | SAVE_ALL_BASE __LC_SAVE_AREA+32 | 685 | SAVE_ALL_BASE __LC_SAVE_AREA+32 |
647 | SAVE_ALL __LC_MCK_OLD_PSW,__LC_SAVE_AREA+32,0 | 686 | la %r12,__LC_MCK_OLD_PSW |
687 | tm __LC_MCCK_CODE,0x80 # system damage? | ||
688 | bo BASED(mcck_int_main) # yes -> rest of mcck code invalid | ||
689 | tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? | ||
690 | bo BASED(0f) | ||
691 | spt __LC_LAST_UPDATE_TIMER # revalidate cpu timer | ||
648 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 692 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
649 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 693 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER |
694 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | ||
695 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_EXIT_TIMER | ||
696 | 0: tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? | ||
697 | bno BASED(mcck_no_vtime) # no -> skip cleanup critical | ||
698 | tm __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ? | ||
650 | bz BASED(mcck_no_vtime) | 699 | bz BASED(mcck_no_vtime) |
651 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER | 700 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER |
652 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 701 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
653 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER | 702 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER |
654 | mcck_no_vtime: | 703 | mcck_no_vtime: |
655 | #endif | 704 | #endif |
705 | 0: | ||
706 | tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? | ||
707 | bno BASED(mcck_int_main) # no -> skip cleanup critical | ||
708 | tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit | ||
709 | bnz BASED(mcck_int_main) # from user -> load async stack | ||
710 | clc __LC_MCK_OLD_PSW+4(4),BASED(.Lcritical_end) | ||
711 | bhe BASED(mcck_int_main) | ||
712 | clc __LC_MCK_OLD_PSW+4(4),BASED(.Lcritical_start) | ||
713 | bl BASED(mcck_int_main) | ||
714 | l %r14,BASED(.Lcleanup_critical) | ||
715 | basr %r14,%r14 | ||
716 | mcck_int_main: | ||
717 | l %r14,__LC_PANIC_STACK # are we already on the panic stack? | ||
718 | slr %r14,%r15 | ||
719 | sra %r14,PAGE_SHIFT | ||
720 | be BASED(0f) | ||
721 | l %r15,__LC_PANIC_STACK # load panic stack | ||
722 | 0: CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+32 | ||
723 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | ||
724 | la %r2,SP_PTREGS(%r15) # load pt_regs | ||
656 | l %r1,BASED(.Ls390_mcck) | 725 | l %r1,BASED(.Ls390_mcck) |
657 | basr %r14,%r1 # call machine check handler | 726 | basr %r14,%r1 # call machine check handler |
727 | tm SP_PSW+1(%r15),0x01 # returning to user ? | ||
728 | bno BASED(mcck_return) | ||
729 | l %r1,__LC_KERNEL_STACK # switch to kernel stack | ||
730 | s %r1,BASED(.Lc_spsize) | ||
731 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) | ||
732 | xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain | ||
733 | lr %r15,%r1 | ||
734 | stosm __SF_EMPTY(%r15),0x04 # turn dat on | ||
735 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING | ||
736 | bno BASED(mcck_return) | ||
737 | l %r1,BASED(.Ls390_handle_mcck) | ||
738 | basr %r14,%r1 # call machine check handler | ||
658 | mcck_return: | 739 | mcck_return: |
659 | RESTORE_ALL 0 | 740 | RESTORE_ALL 0 |
660 | 741 | ||
@@ -742,7 +823,7 @@ cleanup_critical: | |||
742 | clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop) | 823 | clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop) |
743 | bl BASED(0f) | 824 | bl BASED(0f) |
744 | clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop+4) | 825 | clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop+4) |
745 | bl BASED(cleanup_sysc_leave) | 826 | bl BASED(cleanup_sysc_return) |
746 | 0: | 827 | 0: |
747 | br %r14 | 828 | br %r14 |
748 | 829 | ||
@@ -760,6 +841,7 @@ cleanup_system_call: | |||
760 | mvc __LC_SAVE_AREA(16),__LC_SAVE_AREA+16 | 841 | mvc __LC_SAVE_AREA(16),__LC_SAVE_AREA+16 |
761 | 0: st %r13,__LC_SAVE_AREA+20 | 842 | 0: st %r13,__LC_SAVE_AREA+20 |
762 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 | 843 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 |
844 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA | ||
763 | st %r15,__LC_SAVE_AREA+28 | 845 | st %r15,__LC_SAVE_AREA+28 |
764 | lh %r7,0x8a | 846 | lh %r7,0x8a |
765 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 847 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
@@ -834,6 +916,8 @@ cleanup_sysc_leave_insn: | |||
834 | * Symbol constants | 916 | * Symbol constants |
835 | */ | 917 | */ |
836 | .Ls390_mcck: .long s390_do_machine_check | 918 | .Ls390_mcck: .long s390_do_machine_check |
919 | .Ls390_handle_mcck: | ||
920 | .long s390_handle_mcck | ||
837 | .Ldo_IRQ: .long do_IRQ | 921 | .Ldo_IRQ: .long do_IRQ |
838 | .Ldo_extint: .long do_extint | 922 | .Ldo_extint: .long do_extint |
839 | .Ldo_signal: .long do_signal | 923 | .Ldo_signal: .long do_signal |
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 51527ab8c8f9..57ca75d0ad7f 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
@@ -7,6 +7,7 @@ | |||
7 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), | 7 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), |
8 | * Hartmut Penner (hp@de.ibm.com), | 8 | * Hartmut Penner (hp@de.ibm.com), |
9 | * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), | 9 | * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), |
10 | * Heiko Carstens <heiko.carstens@de.ibm.com> | ||
10 | */ | 11 | */ |
11 | 12 | ||
12 | #include <linux/sys.h> | 13 | #include <linux/sys.h> |
@@ -52,9 +53,9 @@ SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE | |||
52 | STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER | 53 | STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER |
53 | STACK_SIZE = 1 << STACK_SHIFT | 54 | STACK_SIZE = 1 << STACK_SHIFT |
54 | 55 | ||
55 | _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ | 56 | _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING | \ |
56 | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) | 57 | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) |
57 | _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED) | 58 | _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING) |
58 | 59 | ||
59 | #define BASED(name) name-system_call(%r13) | 60 | #define BASED(name) name-system_call(%r13) |
60 | 61 | ||
@@ -114,7 +115,11 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED) | |||
114 | jz stack_overflow | 115 | jz stack_overflow |
115 | 3: | 116 | 3: |
116 | #endif | 117 | #endif |
117 | 2: aghi %r15,-SP_SIZE # make room for registers & psw | 118 | 2: |
119 | .endm | ||
120 | |||
121 | .macro CREATE_STACK_FRAME psworg,savearea | ||
122 | aghi %r15,-SP_SIZE # make room for registers & psw | ||
118 | mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack | 123 | mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack |
119 | la %r12,\psworg | 124 | la %r12,\psworg |
120 | stg %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 | 125 | stg %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 |
@@ -152,6 +157,13 @@ __switch_to: | |||
152 | je __switch_to_noper # we got away without bashing TLB's | 157 | je __switch_to_noper # we got away without bashing TLB's |
153 | lctlg %c9,%c11,__THREAD_per(%r3) # Nope we didn't | 158 | lctlg %c9,%c11,__THREAD_per(%r3) # Nope we didn't |
154 | __switch_to_noper: | 159 | __switch_to_noper: |
160 | lg %r4,__THREAD_info(%r2) # get thread_info of prev | ||
161 | tm __TI_flags+7(%r4),_TIF_MCCK_PENDING # machine check pending? | ||
162 | jz __switch_to_no_mcck | ||
163 | ni __TI_flags+7(%r4),255-_TIF_MCCK_PENDING # clear flag in prev | ||
164 | lg %r4,__THREAD_info(%r3) # get thread_info of next | ||
165 | oi __TI_flags+7(%r4),_TIF_MCCK_PENDING # set it in next | ||
166 | __switch_to_no_mcck: | ||
155 | stmg %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task | 167 | stmg %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task |
156 | stg %r15,__THREAD_ksp(%r2) # store kernel stack to prev->tss.ksp | 168 | stg %r15,__THREAD_ksp(%r2) # store kernel stack to prev->tss.ksp |
157 | lg %r15,__THREAD_ksp(%r3) # load kernel stack from next->tss.ksp | 169 | lg %r15,__THREAD_ksp(%r3) # load kernel stack from next->tss.ksp |
@@ -176,6 +188,7 @@ system_call: | |||
176 | sysc_saveall: | 188 | sysc_saveall: |
177 | SAVE_ALL_BASE __LC_SAVE_AREA | 189 | SAVE_ALL_BASE __LC_SAVE_AREA |
178 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 | 190 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 |
191 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA | ||
179 | llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore | 192 | llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore |
180 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 193 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
181 | sysc_vtime: | 194 | sysc_vtime: |
@@ -232,6 +245,8 @@ sysc_work_loop: | |||
232 | # One of the work bits is on. Find out which one. | 245 | # One of the work bits is on. Find out which one. |
233 | # | 246 | # |
234 | sysc_work: | 247 | sysc_work: |
248 | tm __TI_flags+7(%r9),_TIF_MCCK_PENDING | ||
249 | jo sysc_mcck_pending | ||
235 | tm __TI_flags+7(%r9),_TIF_NEED_RESCHED | 250 | tm __TI_flags+7(%r9),_TIF_NEED_RESCHED |
236 | jo sysc_reschedule | 251 | jo sysc_reschedule |
237 | tm __TI_flags+7(%r9),_TIF_SIGPENDING | 252 | tm __TI_flags+7(%r9),_TIF_SIGPENDING |
@@ -250,6 +265,13 @@ sysc_reschedule: | |||
250 | jg schedule # return point is sysc_return | 265 | jg schedule # return point is sysc_return |
251 | 266 | ||
252 | # | 267 | # |
268 | # _TIF_MCCK_PENDING is set, call handler | ||
269 | # | ||
270 | sysc_mcck_pending: | ||
271 | larl %r14,sysc_work_loop | ||
272 | jg s390_handle_mcck # TIF bit will be cleared by handler | ||
273 | |||
274 | # | ||
253 | # _TIF_SIGPENDING is set, call do_signal | 275 | # _TIF_SIGPENDING is set, call do_signal |
254 | # | 276 | # |
255 | sysc_sigpending: | 277 | sysc_sigpending: |
@@ -474,6 +496,7 @@ pgm_check_handler: | |||
474 | tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception | 496 | tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception |
475 | jnz pgm_per # got per exception -> special case | 497 | jnz pgm_per # got per exception -> special case |
476 | SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 | 498 | SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 |
499 | CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA | ||
477 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 500 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
478 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 501 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
479 | jz pgm_no_vtime | 502 | jz pgm_no_vtime |
@@ -512,6 +535,7 @@ pgm_per: | |||
512 | # | 535 | # |
513 | pgm_per_std: | 536 | pgm_per_std: |
514 | SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 | 537 | SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 |
538 | CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA | ||
515 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 539 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
516 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 540 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
517 | jz pgm_no_vtime2 | 541 | jz pgm_no_vtime2 |
@@ -537,6 +561,7 @@ pgm_no_vtime2: | |||
537 | # | 561 | # |
538 | pgm_svcper: | 562 | pgm_svcper: |
539 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 | 563 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 |
564 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA | ||
540 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 565 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
541 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 566 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
542 | jz pgm_no_vtime3 | 567 | jz pgm_no_vtime3 |
@@ -564,6 +589,7 @@ io_int_handler: | |||
564 | stck __LC_INT_CLOCK | 589 | stck __LC_INT_CLOCK |
565 | SAVE_ALL_BASE __LC_SAVE_AREA+32 | 590 | SAVE_ALL_BASE __LC_SAVE_AREA+32 |
566 | SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+32,0 | 591 | SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+32,0 |
592 | CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+32 | ||
567 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 593 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
568 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 594 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
569 | jz io_no_vtime | 595 | jz io_no_vtime |
@@ -621,9 +647,11 @@ io_work: | |||
621 | lgr %r15,%r1 | 647 | lgr %r15,%r1 |
622 | # | 648 | # |
623 | # One of the work bits is on. Find out which one. | 649 | # One of the work bits is on. Find out which one. |
624 | # Checked are: _TIF_SIGPENDING and _TIF_NEED_RESCHED | 650 | # Checked are: _TIF_SIGPENDING, _TIF_NEED_RESCHED and _TIF_MCCK_PENDING |
625 | # | 651 | # |
626 | io_work_loop: | 652 | io_work_loop: |
653 | tm __TI_flags+7(%r9),_TIF_MCCK_PENDING | ||
654 | jo io_mcck_pending | ||
627 | tm __TI_flags+7(%r9),_TIF_NEED_RESCHED | 655 | tm __TI_flags+7(%r9),_TIF_NEED_RESCHED |
628 | jo io_reschedule | 656 | jo io_reschedule |
629 | tm __TI_flags+7(%r9),_TIF_SIGPENDING | 657 | tm __TI_flags+7(%r9),_TIF_SIGPENDING |
@@ -631,6 +659,13 @@ io_work_loop: | |||
631 | j io_leave | 659 | j io_leave |
632 | 660 | ||
633 | # | 661 | # |
662 | # _TIF_MCCK_PENDING is set, call handler | ||
663 | # | ||
664 | io_mcck_pending: | ||
665 | larl %r14,io_work_loop | ||
666 | jg s390_handle_mcck # TIF bit will be cleared by handler | ||
667 | |||
668 | # | ||
634 | # _TIF_NEED_RESCHED is set, call schedule | 669 | # _TIF_NEED_RESCHED is set, call schedule |
635 | # | 670 | # |
636 | io_reschedule: | 671 | io_reschedule: |
@@ -661,6 +696,7 @@ ext_int_handler: | |||
661 | stck __LC_INT_CLOCK | 696 | stck __LC_INT_CLOCK |
662 | SAVE_ALL_BASE __LC_SAVE_AREA+32 | 697 | SAVE_ALL_BASE __LC_SAVE_AREA+32 |
663 | SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32,0 | 698 | SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32,0 |
699 | CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32 | ||
664 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 700 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
665 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 701 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
666 | jz ext_no_vtime | 702 | jz ext_no_vtime |
@@ -680,18 +716,60 @@ ext_no_vtime: | |||
680 | */ | 716 | */ |
681 | .globl mcck_int_handler | 717 | .globl mcck_int_handler |
682 | mcck_int_handler: | 718 | mcck_int_handler: |
683 | STORE_TIMER __LC_ASYNC_ENTER_TIMER | 719 | la %r1,4095 # revalidate r1 |
720 | spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer | ||
721 | lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs | ||
684 | SAVE_ALL_BASE __LC_SAVE_AREA+64 | 722 | SAVE_ALL_BASE __LC_SAVE_AREA+64 |
685 | SAVE_ALL __LC_MCK_OLD_PSW,__LC_SAVE_AREA+64,0 | 723 | la %r12,__LC_MCK_OLD_PSW |
724 | tm __LC_MCCK_CODE,0x80 # system damage? | ||
725 | jo mcck_int_main # yes -> rest of mcck code invalid | ||
726 | tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? | ||
727 | jo 0f | ||
728 | spt __LC_LAST_UPDATE_TIMER | ||
686 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 729 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
687 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 730 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER |
731 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | ||
732 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_EXIT_TIMER | ||
733 | 0: tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? | ||
734 | jno mcck_no_vtime # no -> no timer update | ||
735 | tm __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ? | ||
688 | jz mcck_no_vtime | 736 | jz mcck_no_vtime |
689 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER | 737 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER |
690 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 738 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
691 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER | 739 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER |
692 | mcck_no_vtime: | 740 | mcck_no_vtime: |
693 | #endif | 741 | #endif |
694 | brasl %r14,s390_do_machine_check | 742 | 0: |
743 | tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? | ||
744 | jno mcck_int_main # no -> skip cleanup critical | ||
745 | tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit | ||
746 | jnz mcck_int_main # from user -> load kernel stack | ||
747 | clc __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_end) | ||
748 | jhe mcck_int_main | ||
749 | clc __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_start) | ||
750 | jl mcck_int_main | ||
751 | brasl %r14,cleanup_critical | ||
752 | mcck_int_main: | ||
753 | lg %r14,__LC_PANIC_STACK # are we already on the panic stack? | ||
754 | slgr %r14,%r15 | ||
755 | srag %r14,%r14,PAGE_SHIFT | ||
756 | jz 0f | ||
757 | lg %r15,__LC_PANIC_STACK # load panic stack | ||
758 | 0: CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+64 | ||
759 | lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct | ||
760 | la %r2,SP_PTREGS(%r15) # load pt_regs | ||
761 | brasl %r14,s390_do_machine_check | ||
762 | tm SP_PSW+1(%r15),0x01 # returning to user ? | ||
763 | jno mcck_return | ||
764 | lg %r1,__LC_KERNEL_STACK # switch to kernel stack | ||
765 | aghi %r1,-SP_SIZE | ||
766 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) | ||
767 | xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain | ||
768 | lgr %r15,%r1 | ||
769 | stosm __SF_EMPTY(%r15),0x04 # turn dat on | ||
770 | tm __TI_flags+7(%r9),_TIF_MCCK_PENDING | ||
771 | jno mcck_return | ||
772 | brasl %r14,s390_handle_mcck | ||
695 | mcck_return: | 773 | mcck_return: |
696 | RESTORE_ALL 0 | 774 | RESTORE_ALL 0 |
697 | 775 | ||
@@ -775,7 +853,7 @@ cleanup_critical: | |||
775 | clc 8(8,%r12),BASED(cleanup_table_sysc_work_loop) | 853 | clc 8(8,%r12),BASED(cleanup_table_sysc_work_loop) |
776 | jl 0f | 854 | jl 0f |
777 | clc 8(8,%r12),BASED(cleanup_table_sysc_work_loop+8) | 855 | clc 8(8,%r12),BASED(cleanup_table_sysc_work_loop+8) |
778 | jl cleanup_sysc_leave | 856 | jl cleanup_sysc_return |
779 | 0: | 857 | 0: |
780 | br %r14 | 858 | br %r14 |
781 | 859 | ||
@@ -793,6 +871,7 @@ cleanup_system_call: | |||
793 | mvc __LC_SAVE_AREA(32),__LC_SAVE_AREA+32 | 871 | mvc __LC_SAVE_AREA(32),__LC_SAVE_AREA+32 |
794 | 0: stg %r13,__LC_SAVE_AREA+40 | 872 | 0: stg %r13,__LC_SAVE_AREA+40 |
795 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 | 873 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 |
874 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA | ||
796 | stg %r15,__LC_SAVE_AREA+56 | 875 | stg %r15,__LC_SAVE_AREA+56 |
797 | llgh %r7,__LC_SVC_INT_CODE | 876 | llgh %r7,__LC_SVC_INT_CODE |
798 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 877 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c new file mode 100644 index 000000000000..2721c3a32b84 --- /dev/null +++ b/arch/s390/kernel/machine_kexec.c | |||
@@ -0,0 +1,98 @@ | |||
1 | /* | ||
2 | * arch/s390/kernel/machine_kexec.c | ||
3 | * | ||
4 | * (C) Copyright IBM Corp. 2005 | ||
5 | * | ||
6 | * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com> | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | /* | ||
11 | * s390_machine_kexec.c - handle the transition of Linux booting another kernel | ||
12 | * on the S390 architecture. | ||
13 | */ | ||
14 | |||
15 | #include <asm/cio.h> | ||
16 | #include <asm/setup.h> | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/mm.h> | ||
19 | #include <linux/kexec.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <asm/pgtable.h> | ||
22 | #include <asm/pgalloc.h> | ||
23 | #include <asm/system.h> | ||
24 | |||
25 | static void kexec_halt_all_cpus(void *); | ||
26 | |||
27 | typedef void (*relocate_kernel_t) (kimage_entry_t *, unsigned long); | ||
28 | |||
29 | const extern unsigned char relocate_kernel[]; | ||
30 | const extern unsigned long long relocate_kernel_len; | ||
31 | |||
32 | int | ||
33 | machine_kexec_prepare(struct kimage *image) | ||
34 | { | ||
35 | unsigned long reboot_code_buffer; | ||
36 | |||
37 | /* We don't support anything but the default image type for now. */ | ||
38 | if (image->type != KEXEC_TYPE_DEFAULT) | ||
39 | return -EINVAL; | ||
40 | |||
41 | /* Get the destination where the assembler code should be copied to.*/ | ||
42 | reboot_code_buffer = page_to_pfn(image->control_code_page)<<PAGE_SHIFT; | ||
43 | |||
44 | /* Then copy it */ | ||
45 | memcpy((void *) reboot_code_buffer, relocate_kernel, | ||
46 | relocate_kernel_len); | ||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | void | ||
51 | machine_kexec_cleanup(struct kimage *image) | ||
52 | { | ||
53 | } | ||
54 | |||
55 | void | ||
56 | machine_shutdown(void) | ||
57 | { | ||
58 | printk(KERN_INFO "kexec: machine_shutdown called\n"); | ||
59 | } | ||
60 | |||
61 | NORET_TYPE void | ||
62 | machine_kexec(struct kimage *image) | ||
63 | { | ||
64 | clear_all_subchannels(); | ||
65 | |||
66 | /* Disable lowcore protection */ | ||
67 | ctl_clear_bit(0,28); | ||
68 | |||
69 | on_each_cpu(kexec_halt_all_cpus, image, 0, 0); | ||
70 | for (;;); | ||
71 | } | ||
72 | |||
73 | static void | ||
74 | kexec_halt_all_cpus(void *kernel_image) | ||
75 | { | ||
76 | static atomic_t cpuid = ATOMIC_INIT(-1); | ||
77 | int cpu; | ||
78 | struct kimage *image; | ||
79 | relocate_kernel_t data_mover; | ||
80 | |||
81 | if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid)) | ||
82 | signal_processor(smp_processor_id(), sigp_stop); | ||
83 | |||
84 | /* Wait for all other cpus to enter stopped state */ | ||
85 | for_each_online_cpu(cpu) { | ||
86 | if (cpu == smp_processor_id()) | ||
87 | continue; | ||
88 | while (!smp_cpu_not_running(cpu)) | ||
89 | cpu_relax(); | ||
90 | } | ||
91 | |||
92 | image = (struct kimage *) kernel_image; | ||
93 | data_mover = (relocate_kernel_t) | ||
94 | (page_to_pfn(image->control_code_page) << PAGE_SHIFT); | ||
95 | |||
96 | /* Call the moving routine */ | ||
97 | (*data_mover) (&image->head, image->start); | ||
98 | } | ||
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 7aea25d6e300..9f3dff6c0b72 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c | |||
@@ -91,13 +91,12 @@ void do_monitor_call(struct pt_regs *regs, long interruption_code) | |||
91 | (void *)(long) smp_processor_id()); | 91 | (void *)(long) smp_processor_id()); |
92 | } | 92 | } |
93 | 93 | ||
94 | extern void s390_handle_mcck(void); | ||
94 | /* | 95 | /* |
95 | * The idle loop on a S390... | 96 | * The idle loop on a S390... |
96 | */ | 97 | */ |
97 | void default_idle(void) | 98 | void default_idle(void) |
98 | { | 99 | { |
99 | psw_t wait_psw; | ||
100 | unsigned long reg; | ||
101 | int cpu, rc; | 100 | int cpu, rc; |
102 | 101 | ||
103 | local_irq_disable(); | 102 | local_irq_disable(); |
@@ -125,38 +124,17 @@ void default_idle(void) | |||
125 | cpu_die(); | 124 | cpu_die(); |
126 | #endif | 125 | #endif |
127 | 126 | ||
128 | /* | 127 | local_mcck_disable(); |
129 | * Wait for external, I/O or machine check interrupt and | 128 | if (test_thread_flag(TIF_MCCK_PENDING)) { |
130 | * switch off machine check bit after the wait has ended. | 129 | local_mcck_enable(); |
131 | */ | 130 | local_irq_enable(); |
132 | wait_psw.mask = PSW_KERNEL_BITS | PSW_MASK_MCHECK | PSW_MASK_WAIT | | 131 | s390_handle_mcck(); |
133 | PSW_MASK_IO | PSW_MASK_EXT; | 132 | return; |
134 | #ifndef CONFIG_ARCH_S390X | 133 | } |
135 | asm volatile ( | 134 | |
136 | " basr %0,0\n" | 135 | /* Wait for external, I/O or machine check interrupt. */ |
137 | "0: la %0,1f-0b(%0)\n" | 136 | __load_psw_mask(PSW_KERNEL_BITS | PSW_MASK_WAIT | |
138 | " st %0,4(%1)\n" | 137 | PSW_MASK_IO | PSW_MASK_EXT); |
139 | " oi 4(%1),0x80\n" | ||
140 | " lpsw 0(%1)\n" | ||
141 | "1: la %0,2f-1b(%0)\n" | ||
142 | " st %0,4(%1)\n" | ||
143 | " oi 4(%1),0x80\n" | ||
144 | " ni 1(%1),0xf9\n" | ||
145 | " lpsw 0(%1)\n" | ||
146 | "2:" | ||
147 | : "=&a" (reg) : "a" (&wait_psw) : "memory", "cc" ); | ||
148 | #else /* CONFIG_ARCH_S390X */ | ||
149 | asm volatile ( | ||
150 | " larl %0,0f\n" | ||
151 | " stg %0,8(%1)\n" | ||
152 | " lpswe 0(%1)\n" | ||
153 | "0: larl %0,1f\n" | ||
154 | " stg %0,8(%1)\n" | ||
155 | " ni 1(%1),0xf9\n" | ||
156 | " lpswe 0(%1)\n" | ||
157 | "1:" | ||
158 | : "=&a" (reg) : "a" (&wait_psw) : "memory", "cc" ); | ||
159 | #endif /* CONFIG_ARCH_S390X */ | ||
160 | } | 138 | } |
161 | 139 | ||
162 | void cpu_idle(void) | 140 | void cpu_idle(void) |
diff --git a/arch/s390/kernel/relocate_kernel.S b/arch/s390/kernel/relocate_kernel.S new file mode 100644 index 000000000000..d5e4a62fbb79 --- /dev/null +++ b/arch/s390/kernel/relocate_kernel.S | |||
@@ -0,0 +1,81 @@ | |||
1 | /* | ||
2 | * arch/s390/kernel/relocate_kernel.S | ||
3 | * | ||
4 | * (C) Copyright IBM Corp. 2005 | ||
5 | * | ||
6 | * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com> | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | /* | ||
11 | * moves the new kernel to its destination... | ||
12 | * %r2 = pointer to first kimage_entry_t | ||
13 | * %r3 = start address - where to jump to after the job is done... | ||
14 | * | ||
15 | * %r5 will be used as temp. storage | ||
16 | * %r6 holds the destination address | ||
17 | * %r7 = PAGE_SIZE | ||
18 | * %r8 holds the source address | ||
19 | * %r9 = PAGE_SIZE | ||
20 | * %r10 is a page mask | ||
21 | */ | ||
22 | |||
23 | .text | ||
24 | .globl relocate_kernel | ||
25 | relocate_kernel: | ||
26 | basr %r13,0 #base address | ||
27 | .base: | ||
28 | spx zero64-.base(%r13) #absolute addressing mode | ||
29 | stnsm sys_msk-.base(%r13),0xf8 #disable DAT and IRQ (external) | ||
30 | lhi %r10,-1 #preparing the mask | ||
31 | sll %r10,12 #shift it such that it becomes 0xf000 | ||
32 | .top: | ||
33 | lhi %r7,4096 #load PAGE_SIZE in r7 | ||
34 | lhi %r9,4096 #load PAGE_SIZE in r9 | ||
35 | l %r5,0(%r2) #read another word for indirection page | ||
36 | ahi %r2,4 #increment pointer | ||
37 | tml %r5,0x1 #is it a destination page? | ||
38 | je .indir_check #NO, goto "indir_check" | ||
39 | lr %r6,%r5 #r6 = r5 | ||
40 | nr %r6,%r10 #mask it out and... | ||
41 | j .top #...next iteration | ||
42 | .indir_check: | ||
43 | tml %r5,0x2 #is it a indirection page? | ||
44 | je .done_test #NO, goto "done_test" | ||
45 | nr %r5,%r10 #YES, mask out, | ||
46 | lr %r2,%r5 #move it into the right register, | ||
47 | j .top #and read next... | ||
48 | .done_test: | ||
49 | tml %r5,0x4 #is it the done indicator? | ||
50 | je .source_test #NO! Well, then it should be the source indicator... | ||
51 | j .done #ok, lets finish it here... | ||
52 | .source_test: | ||
53 | tml %r5,0x8 #it should be a source indicator... | ||
54 | je .top #NO, ignore it... | ||
55 | lr %r8,%r5 #r8 = r5 | ||
56 | nr %r8,%r10 #masking | ||
57 | 0: mvcle %r6,%r8,0x0 #copy PAGE_SIZE bytes from r8 to r6 - pad with 0 | ||
58 | jo 0b | ||
59 | j .top | ||
60 | .done: | ||
61 | sr %r0,%r0 #clear register r0 | ||
62 | la %r4,load_psw-.base(%r13) #load psw-address into the register | ||
63 | o %r3,4(%r4) #or load address into psw | ||
64 | st %r3,4(%r4) | ||
65 | mvc 0(8,%r0),0(%r4) #copy psw to absolute address 0 | ||
66 | sr %r1,%r1 #clear %r1 | ||
67 | sr %r2,%r2 #clear %r2 | ||
68 | sigp %r1,%r2,0x12 #set cpuid to zero | ||
69 | lpsw 0 #hopefully start new kernel... | ||
70 | |||
71 | .align 8 | ||
72 | zero64: | ||
73 | .quad 0 | ||
74 | load_psw: | ||
75 | .long 0x00080000,0x80000000 | ||
76 | sys_msk: | ||
77 | .quad 0 | ||
78 | relocate_kernel_end: | ||
79 | .globl relocate_kernel_len | ||
80 | relocate_kernel_len: | ||
81 | .quad relocate_kernel_end - relocate_kernel | ||
diff --git a/arch/s390/kernel/relocate_kernel64.S b/arch/s390/kernel/relocate_kernel64.S new file mode 100644 index 000000000000..96290cc4eb3c --- /dev/null +++ b/arch/s390/kernel/relocate_kernel64.S | |||
@@ -0,0 +1,82 @@ | |||
1 | /* | ||
2 | * arch/s390/kernel/relocate_kernel64.S | ||
3 | * | ||
4 | * (C) Copyright IBM Corp. 2005 | ||
5 | * | ||
6 | * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com> | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | /* | ||
11 | * moves the new kernel to its destination... | ||
12 | * %r2 = pointer to first kimage_entry_t | ||
13 | * %r3 = start address - where to jump to after the job is done... | ||
14 | * | ||
15 | * %r5 will be used as temp. storage | ||
16 | * %r6 holds the destination address | ||
17 | * %r7 = PAGE_SIZE | ||
18 | * %r8 holds the source address | ||
19 | * %r9 = PAGE_SIZE | ||
20 | * | ||
21 | * 0xf000 is a page_mask | ||
22 | */ | ||
23 | |||
24 | .text | ||
25 | .globl relocate_kernel | ||
26 | relocate_kernel: | ||
27 | basr %r13,0 #base address | ||
28 | .base: | ||
29 | spx zero64-.base(%r13) #absolute addressing mode | ||
30 | stnsm sys_msk-.base(%r13),0xf8 #disable DAT and IRQ (external) | ||
31 | .top: | ||
32 | lghi %r7,4096 #load PAGE_SIZE in r7 | ||
33 | lghi %r9,4096 #load PAGE_SIZE in r9 | ||
34 | lg %r5,0(%r2) #read another word for indirection page | ||
35 | aghi %r2,8 #increment pointer | ||
36 | tml %r5,0x1 #is it a destination page? | ||
37 | je .indir_check #NO, goto "indir_check" | ||
38 | lgr %r6,%r5 #r6 = r5 | ||
39 | nill %r6,0xf000 #mask it out and... | ||
40 | j .top #...next iteration | ||
41 | .indir_check: | ||
42 | tml %r5,0x2 #is it a indirection page? | ||
43 | je .done_test #NO, goto "done_test" | ||
44 | nill %r5,0xf000 #YES, mask out, | ||
45 | lgr %r2,%r5 #move it into the right register, | ||
46 | j .top #and read next... | ||
47 | .done_test: | ||
48 | tml %r5,0x4 #is it the done indicator? | ||
49 | je .source_test #NO! Well, then it should be the source indicator... | ||
50 | j .done #ok, lets finish it here... | ||
51 | .source_test: | ||
52 | tml %r5,0x8 #it should be a source indicator... | ||
53 | je .top #NO, ignore it... | ||
54 | lgr %r8,%r5 #r8 = r5 | ||
55 | nill %r8,0xf000 #masking | ||
56 | 0: mvcle %r6,%r8,0x0 #copy PAGE_SIZE bytes from r8 to r6 - pad with 0 | ||
57 | jo 0b | ||
58 | j .top | ||
59 | .done: | ||
60 | sgr %r0,%r0 #clear register r0 | ||
61 | la %r4,load_psw-.base(%r13) #load psw-address into the register | ||
62 | o %r3,4(%r4) #or load address into psw | ||
63 | st %r3,4(%r4) | ||
64 | mvc 0(8,%r0),0(%r4) #copy psw to absolute address 0 | ||
65 | sam31 #31 bit mode | ||
66 | sr %r1,%r1 #erase register r1 | ||
67 | sr %r2,%r2 #erase register r2 | ||
68 | sigp %r1,%r2,0x12 #set cpuid to zero | ||
69 | lpsw 0 #hopefully start new kernel... | ||
70 | |||
71 | .align 8 | ||
72 | zero64: | ||
73 | .quad 0 | ||
74 | load_psw: | ||
75 | .long 0x00080000,0x80000000 | ||
76 | sys_msk: | ||
77 | .quad 0 | ||
78 | relocate_kernel_end: | ||
79 | .globl relocate_kernel_len | ||
80 | relocate_kernel_len: | ||
81 | .quad relocate_kernel_end - relocate_kernel | ||
82 | |||
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index df83215beac3..b6d740ac0e6e 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -198,11 +198,11 @@ static void __init conmode_default(void) | |||
198 | char *ptr; | 198 | char *ptr; |
199 | 199 | ||
200 | if (MACHINE_IS_VM) { | 200 | if (MACHINE_IS_VM) { |
201 | __cpcmd("QUERY CONSOLE", query_buffer, 1024); | 201 | __cpcmd("QUERY CONSOLE", query_buffer, 1024, NULL); |
202 | console_devno = simple_strtoul(query_buffer + 5, NULL, 16); | 202 | console_devno = simple_strtoul(query_buffer + 5, NULL, 16); |
203 | ptr = strstr(query_buffer, "SUBCHANNEL ="); | 203 | ptr = strstr(query_buffer, "SUBCHANNEL ="); |
204 | console_irq = simple_strtoul(ptr + 13, NULL, 16); | 204 | console_irq = simple_strtoul(ptr + 13, NULL, 16); |
205 | __cpcmd("QUERY TERM", query_buffer, 1024); | 205 | __cpcmd("QUERY TERM", query_buffer, 1024, NULL); |
206 | ptr = strstr(query_buffer, "CONMODE"); | 206 | ptr = strstr(query_buffer, "CONMODE"); |
207 | /* | 207 | /* |
208 | * Set the conmode to 3215 so that the device recognition | 208 | * Set the conmode to 3215 so that the device recognition |
@@ -211,7 +211,7 @@ static void __init conmode_default(void) | |||
211 | * 3215 and the 3270 driver will try to access the console | 211 | * 3215 and the 3270 driver will try to access the console |
212 | * device (3215 as console and 3270 as normal tty). | 212 | * device (3215 as console and 3270 as normal tty). |
213 | */ | 213 | */ |
214 | __cpcmd("TERM CONMODE 3215", NULL, 0); | 214 | __cpcmd("TERM CONMODE 3215", NULL, 0, NULL); |
215 | if (ptr == NULL) { | 215 | if (ptr == NULL) { |
216 | #if defined(CONFIG_SCLP_CONSOLE) | 216 | #if defined(CONFIG_SCLP_CONSOLE) |
217 | SET_CONSOLE_SCLP; | 217 | SET_CONSOLE_SCLP; |
@@ -414,7 +414,8 @@ setup_lowcore(void) | |||
414 | lc->program_new_psw.mask = PSW_KERNEL_BITS; | 414 | lc->program_new_psw.mask = PSW_KERNEL_BITS; |
415 | lc->program_new_psw.addr = | 415 | lc->program_new_psw.addr = |
416 | PSW_ADDR_AMODE | (unsigned long)pgm_check_handler; | 416 | PSW_ADDR_AMODE | (unsigned long)pgm_check_handler; |
417 | lc->mcck_new_psw.mask = PSW_KERNEL_BITS; | 417 | lc->mcck_new_psw.mask = |
418 | PSW_KERNEL_BITS & ~PSW_MASK_MCHECK & ~PSW_MASK_DAT; | ||
418 | lc->mcck_new_psw.addr = | 419 | lc->mcck_new_psw.addr = |
419 | PSW_ADDR_AMODE | (unsigned long) mcck_int_handler; | 420 | PSW_ADDR_AMODE | (unsigned long) mcck_int_handler; |
420 | lc->io_new_psw.mask = PSW_KERNEL_BITS; | 421 | lc->io_new_psw.mask = PSW_KERNEL_BITS; |
@@ -424,12 +425,18 @@ setup_lowcore(void) | |||
424 | lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE; | 425 | lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE; |
425 | lc->async_stack = (unsigned long) | 426 | lc->async_stack = (unsigned long) |
426 | __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) + ASYNC_SIZE; | 427 | __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) + ASYNC_SIZE; |
427 | #ifdef CONFIG_CHECK_STACK | ||
428 | lc->panic_stack = (unsigned long) | 428 | lc->panic_stack = (unsigned long) |
429 | __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0) + PAGE_SIZE; | 429 | __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0) + PAGE_SIZE; |
430 | #endif | ||
431 | lc->current_task = (unsigned long) init_thread_union.thread_info.task; | 430 | lc->current_task = (unsigned long) init_thread_union.thread_info.task; |
432 | lc->thread_info = (unsigned long) &init_thread_union; | 431 | lc->thread_info = (unsigned long) &init_thread_union; |
432 | #ifndef CONFIG_ARCH_S390X | ||
433 | if (MACHINE_HAS_IEEE) { | ||
434 | lc->extended_save_area_addr = (__u32) | ||
435 | __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0); | ||
436 | /* enable extended save area */ | ||
437 | ctl_set_bit(14, 29); | ||
438 | } | ||
439 | #endif | ||
433 | #ifdef CONFIG_ARCH_S390X | 440 | #ifdef CONFIG_ARCH_S390X |
434 | if (MACHINE_HAS_DIAG44) | 441 | if (MACHINE_HAS_DIAG44) |
435 | lc->diag44_opcode = 0x83000044; | 442 | lc->diag44_opcode = 0x83000044; |
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index fdfcf0488b49..642572a8e334 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -284,7 +284,7 @@ static void do_machine_restart(void * __unused) | |||
284 | * locks are always held disabled). | 284 | * locks are always held disabled). |
285 | */ | 285 | */ |
286 | if (MACHINE_IS_VM) | 286 | if (MACHINE_IS_VM) |
287 | cpcmd ("IPL", NULL, 0); | 287 | cpcmd ("IPL", NULL, 0, NULL); |
288 | else | 288 | else |
289 | reipl (0x10000 | S390_lowcore.ipl_device); | 289 | reipl (0x10000 | S390_lowcore.ipl_device); |
290 | } | 290 | } |
@@ -313,7 +313,7 @@ static void do_machine_halt(void * __unused) | |||
313 | if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid) == 0) { | 313 | if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid) == 0) { |
314 | smp_send_stop(); | 314 | smp_send_stop(); |
315 | if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0) | 315 | if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0) |
316 | cpcmd(vmhalt_cmd, NULL, 0); | 316 | cpcmd(vmhalt_cmd, NULL, 0, NULL); |
317 | signal_processor(smp_processor_id(), | 317 | signal_processor(smp_processor_id(), |
318 | sigp_stop_and_store_status); | 318 | sigp_stop_and_store_status); |
319 | } | 319 | } |
@@ -332,7 +332,7 @@ static void do_machine_power_off(void * __unused) | |||
332 | if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid) == 0) { | 332 | if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid) == 0) { |
333 | smp_send_stop(); | 333 | smp_send_stop(); |
334 | if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0) | 334 | if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0) |
335 | cpcmd(vmpoff_cmd, NULL, 0); | 335 | cpcmd(vmpoff_cmd, NULL, 0, NULL); |
336 | signal_processor(smp_processor_id(), | 336 | signal_processor(smp_processor_id(), |
337 | sigp_stop_and_store_status); | 337 | sigp_stop_and_store_status); |
338 | } | 338 | } |
@@ -679,12 +679,14 @@ __cpu_disable(void) | |||
679 | { | 679 | { |
680 | unsigned long flags; | 680 | unsigned long flags; |
681 | ec_creg_mask_parms cr_parms; | 681 | ec_creg_mask_parms cr_parms; |
682 | int cpu = smp_processor_id(); | ||
682 | 683 | ||
683 | spin_lock_irqsave(&smp_reserve_lock, flags); | 684 | spin_lock_irqsave(&smp_reserve_lock, flags); |
684 | if (smp_cpu_reserved[smp_processor_id()] != 0) { | 685 | if (smp_cpu_reserved[cpu] != 0) { |
685 | spin_unlock_irqrestore(&smp_reserve_lock, flags); | 686 | spin_unlock_irqrestore(&smp_reserve_lock, flags); |
686 | return -EBUSY; | 687 | return -EBUSY; |
687 | } | 688 | } |
689 | cpu_clear(cpu, cpu_online_map); | ||
688 | 690 | ||
689 | #ifdef CONFIG_PFAULT | 691 | #ifdef CONFIG_PFAULT |
690 | /* Disable pfault pseudo page faults on this cpu. */ | 692 | /* Disable pfault pseudo page faults on this cpu. */ |
@@ -771,13 +773,24 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
771 | 773 | ||
772 | *(lowcore_ptr[i]) = S390_lowcore; | 774 | *(lowcore_ptr[i]) = S390_lowcore; |
773 | lowcore_ptr[i]->async_stack = stack + (ASYNC_SIZE); | 775 | lowcore_ptr[i]->async_stack = stack + (ASYNC_SIZE); |
774 | #ifdef CONFIG_CHECK_STACK | ||
775 | stack = __get_free_pages(GFP_KERNEL,0); | 776 | stack = __get_free_pages(GFP_KERNEL,0); |
776 | if (stack == 0ULL) | 777 | if (stack == 0ULL) |
777 | panic("smp_boot_cpus failed to allocate memory\n"); | 778 | panic("smp_boot_cpus failed to allocate memory\n"); |
778 | lowcore_ptr[i]->panic_stack = stack + (PAGE_SIZE); | 779 | lowcore_ptr[i]->panic_stack = stack + (PAGE_SIZE); |
780 | #ifndef __s390x__ | ||
781 | if (MACHINE_HAS_IEEE) { | ||
782 | lowcore_ptr[i]->extended_save_area_addr = | ||
783 | (__u32) __get_free_pages(GFP_KERNEL,0); | ||
784 | if (lowcore_ptr[i]->extended_save_area_addr == 0) | ||
785 | panic("smp_boot_cpus failed to " | ||
786 | "allocate memory\n"); | ||
787 | } | ||
779 | #endif | 788 | #endif |
780 | } | 789 | } |
790 | #ifndef __s390x__ | ||
791 | if (MACHINE_HAS_IEEE) | ||
792 | ctl_set_bit(14, 29); /* enable extended save area */ | ||
793 | #endif | ||
781 | set_prefix((u32)(unsigned long) lowcore_ptr[smp_processor_id()]); | 794 | set_prefix((u32)(unsigned long) lowcore_ptr[smp_processor_id()]); |
782 | 795 | ||
783 | for_each_cpu(cpu) | 796 | for_each_cpu(cpu) |
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 515938628f82..a8668afb5f87 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S | |||
@@ -285,7 +285,7 @@ SYSCALL(sys_mq_timedsend,sys_mq_timedsend,compat_sys_mq_timedsend_wrapper) | |||
285 | SYSCALL(sys_mq_timedreceive,sys_mq_timedreceive,compat_sys_mq_timedreceive_wrapper) | 285 | SYSCALL(sys_mq_timedreceive,sys_mq_timedreceive,compat_sys_mq_timedreceive_wrapper) |
286 | SYSCALL(sys_mq_notify,sys_mq_notify,compat_sys_mq_notify_wrapper) /* 275 */ | 286 | SYSCALL(sys_mq_notify,sys_mq_notify,compat_sys_mq_notify_wrapper) /* 275 */ |
287 | SYSCALL(sys_mq_getsetattr,sys_mq_getsetattr,compat_sys_mq_getsetattr_wrapper) | 287 | SYSCALL(sys_mq_getsetattr,sys_mq_getsetattr,compat_sys_mq_getsetattr_wrapper) |
288 | NI_SYSCALL /* reserved for kexec */ | 288 | SYSCALL(sys_kexec_load,sys_kexec_load,compat_sys_kexec_load_wrapper) |
289 | SYSCALL(sys_add_key,sys_add_key,compat_sys_add_key_wrapper) | 289 | SYSCALL(sys_add_key,sys_add_key,compat_sys_add_key_wrapper) |
290 | SYSCALL(sys_request_key,sys_request_key,compat_sys_request_key_wrapper) | 290 | SYSCALL(sys_request_key,sys_request_key,compat_sys_request_key_wrapper) |
291 | SYSCALL(sys_keyctl,sys_keyctl,compat_sys_keyctl) /* 280 */ | 291 | SYSCALL(sys_keyctl,sys_keyctl,compat_sys_keyctl) /* 280 */ |
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index ca34b6f34b38..bc7b7be7acbe 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c | |||
@@ -735,7 +735,7 @@ void __init trap_init(void) | |||
735 | &ext_int_pfault); | 735 | &ext_int_pfault); |
736 | #endif | 736 | #endif |
737 | #ifndef CONFIG_ARCH_S390X | 737 | #ifndef CONFIG_ARCH_S390X |
738 | cpcmd("SET PAGEX ON", NULL, 0); | 738 | cpcmd("SET PAGEX ON", NULL, 0, NULL); |
739 | #endif | 739 | #endif |
740 | } | 740 | } |
741 | } | 741 | } |
diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c index 648deed17e25..c5348108ca3c 100644 --- a/arch/s390/mm/extmem.c +++ b/arch/s390/mm/extmem.c | |||
@@ -576,8 +576,8 @@ segment_save(char *name) | |||
576 | segtype_string[seg->range[i].start & 0xff]); | 576 | segtype_string[seg->range[i].start & 0xff]); |
577 | } | 577 | } |
578 | sprintf(cmd2, "SAVESEG %s", name); | 578 | sprintf(cmd2, "SAVESEG %s", name); |
579 | cpcmd(cmd1, NULL, 0); | 579 | cpcmd(cmd1, NULL, 0, NULL); |
580 | cpcmd(cmd2, NULL, 0); | 580 | cpcmd(cmd2, NULL, 0, NULL); |
581 | spin_unlock(&dcss_lock); | 581 | spin_unlock(&dcss_lock); |
582 | } | 582 | } |
583 | 583 | ||
diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c index cf15b4a8b517..c1b03f7c1daa 100644 --- a/arch/um/drivers/daemon_user.c +++ b/arch/um/drivers/daemon_user.c | |||
@@ -157,9 +157,9 @@ static void daemon_remove(void *data) | |||
157 | 157 | ||
158 | os_close_file(pri->fd); | 158 | os_close_file(pri->fd); |
159 | os_close_file(pri->control); | 159 | os_close_file(pri->control); |
160 | if(pri->data_addr != NULL) kfree(pri->data_addr); | 160 | kfree(pri->data_addr); |
161 | if(pri->ctl_addr != NULL) kfree(pri->ctl_addr); | 161 | kfree(pri->ctl_addr); |
162 | if(pri->local_addr != NULL) kfree(pri->local_addr); | 162 | kfree(pri->local_addr); |
163 | } | 163 | } |
164 | 164 | ||
165 | int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri) | 165 | int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri) |
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 0f59736db329..2bb4c4f5dec4 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c | |||
@@ -602,11 +602,26 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str, | |||
602 | return n; | 602 | return n; |
603 | } | 603 | } |
604 | 604 | ||
605 | int line_remove(struct line *lines, unsigned int num, char *str) | 605 | int line_id(char **str, int *start_out, int *end_out) |
606 | { | ||
607 | char *end; | ||
608 | int n; | ||
609 | |||
610 | n = simple_strtoul(*str, &end, 0); | ||
611 | if((*end != '\0') || (end == *str)) | ||
612 | return -1; | ||
613 | |||
614 | *str = end; | ||
615 | *start_out = n; | ||
616 | *end_out = n; | ||
617 | return n; | ||
618 | } | ||
619 | |||
620 | int line_remove(struct line *lines, unsigned int num, int n) | ||
606 | { | 621 | { |
607 | char config[sizeof("conxxxx=none\0")]; | 622 | char config[sizeof("conxxxx=none\0")]; |
608 | 623 | ||
609 | sprintf(config, "%s=none", str); | 624 | sprintf(config, "%d=none", n); |
610 | return !line_setup(lines, num, config, 0); | 625 | return !line_setup(lines, num, config, 0); |
611 | } | 626 | } |
612 | 627 | ||
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index d7c7adcc0a67..404de41a4f67 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c | |||
@@ -419,8 +419,9 @@ void mconsole_config(struct mc_request *req) | |||
419 | void mconsole_remove(struct mc_request *req) | 419 | void mconsole_remove(struct mc_request *req) |
420 | { | 420 | { |
421 | struct mc_device *dev; | 421 | struct mc_device *dev; |
422 | char *ptr = req->request.data; | 422 | char *ptr = req->request.data, *err_msg = ""; |
423 | int err; | 423 | char error[256]; |
424 | int err, start, end, n; | ||
424 | 425 | ||
425 | ptr += strlen("remove"); | 426 | ptr += strlen("remove"); |
426 | while(isspace(*ptr)) ptr++; | 427 | while(isspace(*ptr)) ptr++; |
@@ -429,8 +430,35 @@ void mconsole_remove(struct mc_request *req) | |||
429 | mconsole_reply(req, "Bad remove option", 1, 0); | 430 | mconsole_reply(req, "Bad remove option", 1, 0); |
430 | return; | 431 | return; |
431 | } | 432 | } |
432 | err = (*dev->remove)(&ptr[strlen(dev->name)]); | 433 | |
433 | mconsole_reply(req, "", err, 0); | 434 | ptr = &ptr[strlen(dev->name)]; |
435 | |||
436 | err = 1; | ||
437 | n = (*dev->id)(&ptr, &start, &end); | ||
438 | if(n < 0){ | ||
439 | err_msg = "Couldn't parse device number"; | ||
440 | goto out; | ||
441 | } | ||
442 | else if((n < start) || (n > end)){ | ||
443 | sprintf(error, "Invalid device number - must be between " | ||
444 | "%d and %d", start, end); | ||
445 | err_msg = error; | ||
446 | goto out; | ||
447 | } | ||
448 | |||
449 | err = (*dev->remove)(n); | ||
450 | switch(err){ | ||
451 | case -ENODEV: | ||
452 | err_msg = "Device doesn't exist"; | ||
453 | break; | ||
454 | case -EBUSY: | ||
455 | err_msg = "Device is currently open"; | ||
456 | break; | ||
457 | default: | ||
458 | break; | ||
459 | } | ||
460 | out: | ||
461 | mconsole_reply(req, err_msg, err, 0); | ||
434 | } | 462 | } |
435 | 463 | ||
436 | #ifdef CONFIG_MAGIC_SYSRQ | 464 | #ifdef CONFIG_MAGIC_SYSRQ |
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 5388a7428691..1495007bf6c0 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c | |||
@@ -612,25 +612,35 @@ static int net_config(char *str) | |||
612 | return(err); | 612 | return(err); |
613 | } | 613 | } |
614 | 614 | ||
615 | static int net_remove(char *str) | 615 | static int net_id(char **str, int *start_out, int *end_out) |
616 | { | ||
617 | char *end; | ||
618 | int n; | ||
619 | |||
620 | n = simple_strtoul(*str, &end, 0); | ||
621 | if((*end != '\0') || (end == *str)) | ||
622 | return -1; | ||
623 | |||
624 | *start_out = n; | ||
625 | *end_out = n; | ||
626 | *str = end; | ||
627 | return n; | ||
628 | } | ||
629 | |||
630 | static int net_remove(int n) | ||
616 | { | 631 | { |
617 | struct uml_net *device; | 632 | struct uml_net *device; |
618 | struct net_device *dev; | 633 | struct net_device *dev; |
619 | struct uml_net_private *lp; | 634 | struct uml_net_private *lp; |
620 | char *end; | ||
621 | int n; | ||
622 | |||
623 | n = simple_strtoul(str, &end, 0); | ||
624 | if((*end != '\0') || (end == str)) | ||
625 | return(-1); | ||
626 | 635 | ||
627 | device = find_device(n); | 636 | device = find_device(n); |
628 | if(device == NULL) | 637 | if(device == NULL) |
629 | return(0); | 638 | return -ENODEV; |
630 | 639 | ||
631 | dev = device->dev; | 640 | dev = device->dev; |
632 | lp = dev->priv; | 641 | lp = dev->priv; |
633 | if(lp->fd > 0) return(-1); | 642 | if(lp->fd > 0) |
643 | return -EBUSY; | ||
634 | if(lp->remove != NULL) (*lp->remove)(&lp->user); | 644 | if(lp->remove != NULL) (*lp->remove)(&lp->user); |
635 | unregister_netdev(dev); | 645 | unregister_netdev(dev); |
636 | platform_device_unregister(&device->pdev); | 646 | platform_device_unregister(&device->pdev); |
@@ -638,13 +648,14 @@ static int net_remove(char *str) | |||
638 | list_del(&device->list); | 648 | list_del(&device->list); |
639 | kfree(device); | 649 | kfree(device); |
640 | free_netdev(dev); | 650 | free_netdev(dev); |
641 | return(0); | 651 | return 0; |
642 | } | 652 | } |
643 | 653 | ||
644 | static struct mc_device net_mc = { | 654 | static struct mc_device net_mc = { |
645 | .name = "eth", | 655 | .name = "eth", |
646 | .config = net_config, | 656 | .config = net_config, |
647 | .get_config = NULL, | 657 | .get_config = NULL, |
658 | .id = net_id, | ||
648 | .remove = net_remove, | 659 | .remove = net_remove, |
649 | }; | 660 | }; |
650 | 661 | ||
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c index b32a77010fbe..62e04ecfada8 100644 --- a/arch/um/drivers/ssl.c +++ b/arch/um/drivers/ssl.c | |||
@@ -49,7 +49,7 @@ static struct chan_opts opts = { | |||
49 | 49 | ||
50 | static int ssl_config(char *str); | 50 | static int ssl_config(char *str); |
51 | static int ssl_get_config(char *dev, char *str, int size, char **error_out); | 51 | static int ssl_get_config(char *dev, char *str, int size, char **error_out); |
52 | static int ssl_remove(char *str); | 52 | static int ssl_remove(int n); |
53 | 53 | ||
54 | static struct line_driver driver = { | 54 | static struct line_driver driver = { |
55 | .name = "UML serial line", | 55 | .name = "UML serial line", |
@@ -69,6 +69,7 @@ static struct line_driver driver = { | |||
69 | .name = "ssl", | 69 | .name = "ssl", |
70 | .config = ssl_config, | 70 | .config = ssl_config, |
71 | .get_config = ssl_get_config, | 71 | .get_config = ssl_get_config, |
72 | .id = line_id, | ||
72 | .remove = ssl_remove, | 73 | .remove = ssl_remove, |
73 | }, | 74 | }, |
74 | }; | 75 | }; |
@@ -94,10 +95,10 @@ static int ssl_get_config(char *dev, char *str, int size, char **error_out) | |||
94 | str, size, error_out)); | 95 | str, size, error_out)); |
95 | } | 96 | } |
96 | 97 | ||
97 | static int ssl_remove(char *str) | 98 | static int ssl_remove(int n) |
98 | { | 99 | { |
99 | return(line_remove(serial_lines, | 100 | return line_remove(serial_lines, |
100 | sizeof(serial_lines)/sizeof(serial_lines[0]), str)); | 101 | sizeof(serial_lines)/sizeof(serial_lines[0]), n); |
101 | } | 102 | } |
102 | 103 | ||
103 | int ssl_open(struct tty_struct *tty, struct file *filp) | 104 | int ssl_open(struct tty_struct *tty, struct file *filp) |
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c index afbe1e71ed83..005aa6333b6e 100644 --- a/arch/um/drivers/stdio_console.c +++ b/arch/um/drivers/stdio_console.c | |||
@@ -55,7 +55,7 @@ static struct chan_opts opts = { | |||
55 | 55 | ||
56 | static int con_config(char *str); | 56 | static int con_config(char *str); |
57 | static int con_get_config(char *dev, char *str, int size, char **error_out); | 57 | static int con_get_config(char *dev, char *str, int size, char **error_out); |
58 | static int con_remove(char *str); | 58 | static int con_remove(int n); |
59 | 59 | ||
60 | static struct line_driver driver = { | 60 | static struct line_driver driver = { |
61 | .name = "UML console", | 61 | .name = "UML console", |
@@ -75,6 +75,7 @@ static struct line_driver driver = { | |||
75 | .name = "con", | 75 | .name = "con", |
76 | .config = con_config, | 76 | .config = con_config, |
77 | .get_config = con_get_config, | 77 | .get_config = con_get_config, |
78 | .id = line_id, | ||
78 | .remove = con_remove, | 79 | .remove = con_remove, |
79 | }, | 80 | }, |
80 | }; | 81 | }; |
@@ -99,9 +100,9 @@ static int con_get_config(char *dev, char *str, int size, char **error_out) | |||
99 | size, error_out)); | 100 | size, error_out)); |
100 | } | 101 | } |
101 | 102 | ||
102 | static int con_remove(char *str) | 103 | static int con_remove(int n) |
103 | { | 104 | { |
104 | return(line_remove(vts, sizeof(vts)/sizeof(vts[0]), str)); | 105 | return line_remove(vts, sizeof(vts)/sizeof(vts[0]), n); |
105 | } | 106 | } |
106 | 107 | ||
107 | static int con_open(struct tty_struct *tty, struct file *filp) | 108 | static int con_open(struct tty_struct *tty, struct file *filp) |
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 2a7f6892c55c..344b24d09a7c 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c | |||
@@ -754,24 +754,34 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out) | |||
754 | return(len); | 754 | return(len); |
755 | } | 755 | } |
756 | 756 | ||
757 | static int ubd_remove(char *str) | 757 | static int ubd_id(char **str, int *start_out, int *end_out) |
758 | { | ||
759 | int n; | ||
760 | |||
761 | n = parse_unit(str); | ||
762 | *start_out = 0; | ||
763 | *end_out = MAX_DEV - 1; | ||
764 | return n; | ||
765 | } | ||
766 | |||
767 | static int ubd_remove(int n) | ||
758 | { | 768 | { |
759 | struct ubd *dev; | 769 | struct ubd *dev; |
760 | int n, err = -ENODEV; | 770 | int err = -ENODEV; |
761 | 771 | ||
762 | n = parse_unit(&str); | 772 | spin_lock(&ubd_lock); |
763 | 773 | ||
764 | if((n < 0) || (n >= MAX_DEV)) | 774 | if(ubd_gendisk[n] == NULL) |
765 | return(err); | 775 | goto out; |
766 | 776 | ||
767 | dev = &ubd_dev[n]; | 777 | dev = &ubd_dev[n]; |
768 | if(dev->count > 0) | ||
769 | return(-EBUSY); /* you cannot remove a open disk */ | ||
770 | 778 | ||
771 | err = 0; | 779 | if(dev->file == NULL) |
772 | spin_lock(&ubd_lock); | 780 | goto out; |
773 | 781 | ||
774 | if(ubd_gendisk[n] == NULL) | 782 | /* you cannot remove a open disk */ |
783 | err = -EBUSY; | ||
784 | if(dev->count > 0) | ||
775 | goto out; | 785 | goto out; |
776 | 786 | ||
777 | del_gendisk(ubd_gendisk[n]); | 787 | del_gendisk(ubd_gendisk[n]); |
@@ -787,15 +797,16 @@ static int ubd_remove(char *str) | |||
787 | platform_device_unregister(&dev->pdev); | 797 | platform_device_unregister(&dev->pdev); |
788 | *dev = ((struct ubd) DEFAULT_UBD); | 798 | *dev = ((struct ubd) DEFAULT_UBD); |
789 | err = 0; | 799 | err = 0; |
790 | out: | 800 | out: |
791 | spin_unlock(&ubd_lock); | 801 | spin_unlock(&ubd_lock); |
792 | return(err); | 802 | return err; |
793 | } | 803 | } |
794 | 804 | ||
795 | static struct mc_device ubd_mc = { | 805 | static struct mc_device ubd_mc = { |
796 | .name = "ubd", | 806 | .name = "ubd", |
797 | .config = ubd_config, | 807 | .config = ubd_config, |
798 | .get_config = ubd_get_config, | 808 | .get_config = ubd_get_config, |
809 | .id = ubd_id, | ||
799 | .remove = ubd_remove, | 810 | .remove = ubd_remove, |
800 | }; | 811 | }; |
801 | 812 | ||
diff --git a/arch/um/include/line.h b/arch/um/include/line.h index 4c5e92c04ccb..5323d22a6ca7 100644 --- a/arch/um/include/line.h +++ b/arch/um/include/line.h | |||
@@ -101,7 +101,8 @@ extern void lines_init(struct line *lines, int nlines); | |||
101 | extern void close_lines(struct line *lines, int nlines); | 101 | extern void close_lines(struct line *lines, int nlines); |
102 | 102 | ||
103 | extern int line_config(struct line *lines, unsigned int sizeof_lines, char *str); | 103 | extern int line_config(struct line *lines, unsigned int sizeof_lines, char *str); |
104 | extern int line_remove(struct line *lines, unsigned int sizeof_lines, char *str); | 104 | extern int line_id(char **str, int *start_out, int *end_out); |
105 | extern int line_remove(struct line *lines, unsigned int sizeof_lines, int n); | ||
105 | extern int line_get_config(char *dev, struct line *lines, unsigned int sizeof_lines, char *str, | 106 | extern int line_get_config(char *dev, struct line *lines, unsigned int sizeof_lines, char *str, |
106 | int size, char **error_out); | 107 | int size, char **error_out); |
107 | 108 | ||
diff --git a/arch/um/include/mconsole_kern.h b/arch/um/include/mconsole_kern.h index 61c274fcee5d..d86ee14260ce 100644 --- a/arch/um/include/mconsole_kern.h +++ b/arch/um/include/mconsole_kern.h | |||
@@ -20,7 +20,8 @@ struct mc_device { | |||
20 | char *name; | 20 | char *name; |
21 | int (*config)(char *); | 21 | int (*config)(char *); |
22 | int (*get_config)(char *, char *, int, char **); | 22 | int (*get_config)(char *, char *, int, char **); |
23 | int (*remove)(char *); | 23 | int (*id)(char **, int *, int *); |
24 | int (*remove)(int); | ||
24 | }; | 25 | }; |
25 | 26 | ||
26 | #define CONFIG_CHUNK(str, size, current, chunk, end) \ | 27 | #define CONFIG_CHUNK(str, size, current, chunk, end) \ |
diff --git a/arch/um/include/time_user.h b/arch/um/include/time_user.h index 6793a2fcd0ae..f64ef77019a3 100644 --- a/arch/um/include/time_user.h +++ b/arch/um/include/time_user.h | |||
@@ -8,11 +8,11 @@ | |||
8 | 8 | ||
9 | extern void timer(void); | 9 | extern void timer(void); |
10 | extern void switch_timers(int to_real); | 10 | extern void switch_timers(int to_real); |
11 | extern void set_interval(int timer_type); | ||
12 | extern void idle_sleep(int secs); | 11 | extern void idle_sleep(int secs); |
13 | extern void enable_timer(void); | 12 | extern void enable_timer(void); |
14 | extern void disable_timer(void); | 13 | extern void disable_timer(void); |
15 | extern unsigned long time_lock(void); | 14 | extern unsigned long time_lock(void); |
16 | extern void time_unlock(unsigned long); | 15 | extern void time_unlock(unsigned long); |
16 | extern void user_time_init(void); | ||
17 | 17 | ||
18 | #endif | 18 | #endif |
diff --git a/arch/um/kernel/main.c b/arch/um/kernel/main.c index e59f58152678..1e1a87f1c510 100644 --- a/arch/um/kernel/main.c +++ b/arch/um/kernel/main.c | |||
@@ -69,7 +69,6 @@ static __init void do_uml_initcalls(void) | |||
69 | 69 | ||
70 | static void last_ditch_exit(int sig) | 70 | static void last_ditch_exit(int sig) |
71 | { | 71 | { |
72 | kmalloc_ok = 0; | ||
73 | signal(SIGINT, SIG_DFL); | 72 | signal(SIGINT, SIG_DFL); |
74 | signal(SIGTERM, SIG_DFL); | 73 | signal(SIGTERM, SIG_DFL); |
75 | signal(SIGHUP, SIG_DFL); | 74 | signal(SIGHUP, SIG_DFL); |
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c index 157584ae4792..d4036ed680bc 100644 --- a/arch/um/kernel/process_kern.c +++ b/arch/um/kernel/process_kern.c | |||
@@ -96,8 +96,8 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) | |||
96 | 96 | ||
97 | current->thread.request.u.thread.proc = fn; | 97 | current->thread.request.u.thread.proc = fn; |
98 | current->thread.request.u.thread.arg = arg; | 98 | current->thread.request.u.thread.arg = arg; |
99 | pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0, NULL, 0, NULL, | 99 | pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0, |
100 | NULL); | 100 | ¤t->thread.regs, 0, NULL, NULL); |
101 | if(pid < 0) | 101 | if(pid < 0) |
102 | panic("do_fork failed in kernel_thread, errno = %d", pid); | 102 | panic("do_fork failed in kernel_thread, errno = %d", pid); |
103 | return(pid); | 103 | return(pid); |
@@ -169,7 +169,7 @@ int current_pid(void) | |||
169 | 169 | ||
170 | void default_idle(void) | 170 | void default_idle(void) |
171 | { | 171 | { |
172 | uml_idle_timer(); | 172 | CHOOSE_MODE(uml_idle_timer(), (void) 0); |
173 | 173 | ||
174 | atomic_inc(&init_mm.mm_count); | 174 | atomic_inc(&init_mm.mm_count); |
175 | current->mm = &init_mm; | 175 | current->mm = &init_mm; |
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c index 207f89d74908..fcec51da1d37 100644 --- a/arch/um/kernel/reboot.c +++ b/arch/um/kernel/reboot.c | |||
@@ -38,14 +38,14 @@ static void kill_off_processes(void) | |||
38 | 38 | ||
39 | void uml_cleanup(void) | 39 | void uml_cleanup(void) |
40 | { | 40 | { |
41 | kill_off_processes(); | 41 | kmalloc_ok = 0; |
42 | do_uml_exitcalls(); | 42 | do_uml_exitcalls(); |
43 | kill_off_processes(); | ||
43 | } | 44 | } |
44 | 45 | ||
45 | void machine_restart(char * __unused) | 46 | void machine_restart(char * __unused) |
46 | { | 47 | { |
47 | do_uml_exitcalls(); | 48 | uml_cleanup(); |
48 | kill_off_processes(); | ||
49 | CHOOSE_MODE(reboot_tt(), reboot_skas()); | 49 | CHOOSE_MODE(reboot_tt(), reboot_skas()); |
50 | } | 50 | } |
51 | 51 | ||
@@ -53,8 +53,7 @@ EXPORT_SYMBOL(machine_restart); | |||
53 | 53 | ||
54 | void machine_power_off(void) | 54 | void machine_power_off(void) |
55 | { | 55 | { |
56 | do_uml_exitcalls(); | 56 | uml_cleanup(); |
57 | kill_off_processes(); | ||
58 | CHOOSE_MODE(halt_tt(), halt_skas()); | 57 | CHOOSE_MODE(halt_tt(), halt_skas()); |
59 | } | 58 | } |
60 | 59 | ||
diff --git a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile index d37d1bfcd6f7..ff69c4b312c0 100644 --- a/arch/um/kernel/skas/Makefile +++ b/arch/um/kernel/skas/Makefile | |||
@@ -4,10 +4,10 @@ | |||
4 | # | 4 | # |
5 | 5 | ||
6 | obj-y := exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \ | 6 | obj-y := exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \ |
7 | syscall_kern.o syscall_user.o time.o tlb.o trap_user.o uaccess.o \ | 7 | syscall_kern.o syscall_user.o tlb.o trap_user.o uaccess.o \ |
8 | 8 | ||
9 | subdir- := util | 9 | subdir- := util |
10 | 10 | ||
11 | USER_OBJS := process.o time.o | 11 | USER_OBJS := process.o |
12 | 12 | ||
13 | include arch/um/scripts/Makefile.rules | 13 | include arch/um/scripts/Makefile.rules |
diff --git a/arch/um/kernel/skas/include/mode-skas.h b/arch/um/kernel/skas/include/mode-skas.h index c1e33bd788db..bcd26a6a3888 100644 --- a/arch/um/kernel/skas/include/mode-skas.h +++ b/arch/um/kernel/skas/include/mode-skas.h | |||
@@ -13,7 +13,6 @@ extern unsigned long exec_fp_regs[]; | |||
13 | extern unsigned long exec_fpx_regs[]; | 13 | extern unsigned long exec_fpx_regs[]; |
14 | extern int have_fpx_regs; | 14 | extern int have_fpx_regs; |
15 | 15 | ||
16 | extern void user_time_init_skas(void); | ||
17 | extern void sig_handler_common_skas(int sig, void *sc_ptr); | 16 | extern void sig_handler_common_skas(int sig, void *sc_ptr); |
18 | extern void halt_skas(void); | 17 | extern void halt_skas(void); |
19 | extern void reboot_skas(void); | 18 | extern void reboot_skas(void); |
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c index fc71ef295782..0a7b8aa55db8 100644 --- a/arch/um/kernel/skas/process_kern.c +++ b/arch/um/kernel/skas/process_kern.c | |||
@@ -111,8 +111,7 @@ int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp, | |||
111 | void (*handler)(int); | 111 | void (*handler)(int); |
112 | 112 | ||
113 | if(current->thread.forking){ | 113 | if(current->thread.forking){ |
114 | memcpy(&p->thread.regs.regs.skas, | 114 | memcpy(&p->thread.regs.regs.skas, ®s->regs.skas, |
115 | ¤t->thread.regs.regs.skas, | ||
116 | sizeof(p->thread.regs.regs.skas)); | 115 | sizeof(p->thread.regs.regs.skas)); |
117 | REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.skas.regs, 0); | 116 | REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.skas.regs, 0); |
118 | if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp; | 117 | if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp; |
@@ -181,7 +180,6 @@ int start_uml_skas(void) | |||
181 | start_userspace(0); | 180 | start_userspace(0); |
182 | 181 | ||
183 | init_new_thread_signals(1); | 182 | init_new_thread_signals(1); |
184 | uml_idle_timer(); | ||
185 | 183 | ||
186 | init_task.thread.request.u.thread.proc = start_kernel_proc; | 184 | init_task.thread.request.u.thread.proc = start_kernel_proc; |
187 | init_task.thread.request.u.thread.arg = NULL; | 185 | init_task.thread.request.u.thread.arg = NULL; |
@@ -201,14 +199,3 @@ int thread_pid_skas(struct task_struct *task) | |||
201 | #warning Need to look up userspace_pid by cpu | 199 | #warning Need to look up userspace_pid by cpu |
202 | return(userspace_pid[0]); | 200 | return(userspace_pid[0]); |
203 | } | 201 | } |
204 | |||
205 | /* | ||
206 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
207 | * Emacs will notice this stuff at the end of the file and automatically | ||
208 | * adjust the settings for this buffer only. This must remain at the end | ||
209 | * of the file. | ||
210 | * --------------------------------------------------------------------------- | ||
211 | * Local variables: | ||
212 | * c-file-style: "linux" | ||
213 | * End: | ||
214 | */ | ||
diff --git a/arch/um/kernel/skas/time.c b/arch/um/kernel/skas/time.c deleted file mode 100644 index 98091494b897..000000000000 --- a/arch/um/kernel/skas/time.c +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | |||
6 | #include <sys/signal.h> | ||
7 | #include <sys/time.h> | ||
8 | #include "time_user.h" | ||
9 | #include "process.h" | ||
10 | #include "user.h" | ||
11 | |||
12 | void user_time_init_skas(void) | ||
13 | { | ||
14 | if(signal(SIGALRM, (__sighandler_t) alarm_handler) == SIG_ERR) | ||
15 | panic("Couldn't set SIGALRM handler"); | ||
16 | if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR) | ||
17 | panic("Couldn't set SIGVTALRM handler"); | ||
18 | set_interval(ITIMER_VIRTUAL); | ||
19 | } | ||
20 | |||
21 | /* | ||
22 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
23 | * Emacs will notice this stuff at the end of the file and automatically | ||
24 | * adjust the settings for this buffer only. This must remain at the end | ||
25 | * of the file. | ||
26 | * --------------------------------------------------------------------------- | ||
27 | * Local variables: | ||
28 | * c-file-style: "linux" | ||
29 | * End: | ||
30 | */ | ||
diff --git a/arch/um/kernel/syscall_kern.c b/arch/um/kernel/syscall_kern.c index b7a55251e897..8e1a3501ff46 100644 --- a/arch/um/kernel/syscall_kern.c +++ b/arch/um/kernel/syscall_kern.c | |||
@@ -31,7 +31,8 @@ long sys_fork(void) | |||
31 | long ret; | 31 | long ret; |
32 | 32 | ||
33 | current->thread.forking = 1; | 33 | current->thread.forking = 1; |
34 | ret = do_fork(SIGCHLD, 0, NULL, 0, NULL, NULL); | 34 | ret = do_fork(SIGCHLD, UPT_SP(¤t->thread.regs.regs), |
35 | ¤t->thread.regs, 0, NULL, NULL); | ||
35 | current->thread.forking = 0; | 36 | current->thread.forking = 0; |
36 | return(ret); | 37 | return(ret); |
37 | } | 38 | } |
@@ -41,8 +42,9 @@ long sys_vfork(void) | |||
41 | long ret; | 42 | long ret; |
42 | 43 | ||
43 | current->thread.forking = 1; | 44 | current->thread.forking = 1; |
44 | ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0, NULL, | 45 | ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, |
45 | NULL); | 46 | UPT_SP(¤t->thread.regs.regs), |
47 | ¤t->thread.regs, 0, NULL, NULL); | ||
46 | current->thread.forking = 0; | 48 | current->thread.forking = 0; |
47 | return(ret); | 49 | return(ret); |
48 | } | 50 | } |
@@ -162,14 +164,3 @@ int next_syscall_index(int limit) | |||
162 | spin_unlock(&syscall_lock); | 164 | spin_unlock(&syscall_lock); |
163 | return(ret); | 165 | return(ret); |
164 | } | 166 | } |
165 | |||
166 | /* | ||
167 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
168 | * Emacs will notice this stuff at the end of the file and automatically | ||
169 | * adjust the settings for this buffer only. This must remain at the end | ||
170 | * of the file. | ||
171 | * --------------------------------------------------------------------------- | ||
172 | * Local variables: | ||
173 | * c-file-style: "linux" | ||
174 | * End: | ||
175 | */ | ||
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index c40c86a3f918..f829b309b63c 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c | |||
@@ -33,7 +33,7 @@ void timer(void) | |||
33 | timeradd(&xtime, &local_offset, &xtime); | 33 | timeradd(&xtime, &local_offset, &xtime); |
34 | } | 34 | } |
35 | 35 | ||
36 | void set_interval(int timer_type) | 36 | static void set_interval(int timer_type) |
37 | { | 37 | { |
38 | int usec = 1000000/hz(); | 38 | int usec = 1000000/hz(); |
39 | struct itimerval interval = ((struct itimerval) { { 0, usec }, | 39 | struct itimerval interval = ((struct itimerval) { { 0, usec }, |
@@ -45,12 +45,7 @@ void set_interval(int timer_type) | |||
45 | 45 | ||
46 | void enable_timer(void) | 46 | void enable_timer(void) |
47 | { | 47 | { |
48 | int usec = 1000000/hz(); | 48 | set_interval(ITIMER_VIRTUAL); |
49 | struct itimerval enable = ((struct itimerval) { { 0, usec }, | ||
50 | { 0, usec }}); | ||
51 | if(setitimer(ITIMER_VIRTUAL, &enable, NULL)) | ||
52 | printk("enable_timer - setitimer failed, errno = %d\n", | ||
53 | errno); | ||
54 | } | 49 | } |
55 | 50 | ||
56 | void disable_timer(void) | 51 | void disable_timer(void) |
@@ -155,13 +150,15 @@ void idle_sleep(int secs) | |||
155 | nanosleep(&ts, NULL); | 150 | nanosleep(&ts, NULL); |
156 | } | 151 | } |
157 | 152 | ||
158 | /* | 153 | /* XXX This partly duplicates init_irq_signals */ |
159 | * Overrides for Emacs so that we follow Linus's tabbing style. | 154 | |
160 | * Emacs will notice this stuff at the end of the file and automatically | 155 | void user_time_init(void) |
161 | * adjust the settings for this buffer only. This must remain at the end | 156 | { |
162 | * of the file. | 157 | set_handler(SIGVTALRM, (__sighandler_t) alarm_handler, |
163 | * --------------------------------------------------------------------------- | 158 | SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, |
164 | * Local variables: | 159 | SIGALRM, SIGUSR2, -1); |
165 | * c-file-style: "linux" | 160 | set_handler(SIGALRM, (__sighandler_t) alarm_handler, |
166 | * End: | 161 | SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, |
167 | */ | 162 | SIGVTALRM, SIGUSR2, -1); |
163 | set_interval(ITIMER_VIRTUAL); | ||
164 | } | ||
diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c index 6516fc52afe0..a8b4ef601f59 100644 --- a/arch/um/kernel/time_kern.c +++ b/arch/um/kernel/time_kern.c | |||
@@ -162,7 +162,7 @@ int __init timer_init(void) | |||
162 | { | 162 | { |
163 | int err; | 163 | int err; |
164 | 164 | ||
165 | CHOOSE_MODE(user_time_init_tt(), user_time_init_skas()); | 165 | user_time_init(); |
166 | err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", NULL); | 166 | err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", NULL); |
167 | if(err != 0) | 167 | if(err != 0) |
168 | printk(KERN_ERR "timer_init : request_irq failed - " | 168 | printk(KERN_ERR "timer_init : request_irq failed - " |
diff --git a/arch/um/kernel/tt/Makefile b/arch/um/kernel/tt/Makefile index 3fd2554e60b6..6939e5af8472 100644 --- a/arch/um/kernel/tt/Makefile +++ b/arch/um/kernel/tt/Makefile | |||
@@ -4,11 +4,11 @@ | |||
4 | # | 4 | # |
5 | 5 | ||
6 | obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \ | 6 | obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \ |
7 | syscall_kern.o syscall_user.o time.o tlb.o tracer.o trap_user.o \ | 7 | syscall_kern.o syscall_user.o tlb.o tracer.o trap_user.o \ |
8 | uaccess.o uaccess_user.o | 8 | uaccess.o uaccess_user.o |
9 | 9 | ||
10 | obj-$(CONFIG_PT_PROXY) += gdb_kern.o ptproxy/ | 10 | obj-$(CONFIG_PT_PROXY) += gdb_kern.o ptproxy/ |
11 | 11 | ||
12 | USER_OBJS := gdb.o time.o tracer.o | 12 | USER_OBJS := gdb.o tracer.o |
13 | 13 | ||
14 | include arch/um/scripts/Makefile.rules | 14 | include arch/um/scripts/Makefile.rules |
diff --git a/arch/um/kernel/tt/gdb.c b/arch/um/kernel/tt/gdb.c index 19a0ad7b35b3..37e22d71a0d9 100644 --- a/arch/um/kernel/tt/gdb.c +++ b/arch/um/kernel/tt/gdb.c | |||
@@ -153,10 +153,10 @@ void remove_gdb_cb(void *unused) | |||
153 | exit_debugger_cb(NULL); | 153 | exit_debugger_cb(NULL); |
154 | } | 154 | } |
155 | 155 | ||
156 | int gdb_remove(char *unused) | 156 | int gdb_remove(int unused) |
157 | { | 157 | { |
158 | initial_thread_cb(remove_gdb_cb, NULL); | 158 | initial_thread_cb(remove_gdb_cb, NULL); |
159 | return(0); | 159 | return 0; |
160 | } | 160 | } |
161 | 161 | ||
162 | void signal_usr1(int sig) | 162 | void signal_usr1(int sig) |
diff --git a/arch/um/kernel/tt/gdb_kern.c b/arch/um/kernel/tt/gdb_kern.c index 93fb121f86af..26506388a6aa 100644 --- a/arch/um/kernel/tt/gdb_kern.c +++ b/arch/um/kernel/tt/gdb_kern.c | |||
@@ -10,7 +10,7 @@ | |||
10 | #ifdef CONFIG_MCONSOLE | 10 | #ifdef CONFIG_MCONSOLE |
11 | 11 | ||
12 | extern int gdb_config(char *str); | 12 | extern int gdb_config(char *str); |
13 | extern int gdb_remove(char *unused); | 13 | extern int gdb_remove(int n); |
14 | 14 | ||
15 | static struct mc_device gdb_mc = { | 15 | static struct mc_device gdb_mc = { |
16 | .name = "gdb", | 16 | .name = "gdb", |
diff --git a/arch/um/kernel/tt/include/debug.h b/arch/um/kernel/tt/include/debug.h index 8eff674107ca..738435461e13 100644 --- a/arch/um/kernel/tt/include/debug.h +++ b/arch/um/kernel/tt/include/debug.h | |||
@@ -4,8 +4,8 @@ | |||
4 | * Licensed under the GPL | 4 | * Licensed under the GPL |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #ifndef __DEBUG_H | 7 | #ifndef __UML_TT_DEBUG_H |
8 | #define __DEBUG_H | 8 | #define __UML_TT_DEBUG_H |
9 | 9 | ||
10 | extern int debugger_proxy(int status, pid_t pid); | 10 | extern int debugger_proxy(int status, pid_t pid); |
11 | extern void child_proxy(pid_t pid, int status); | 11 | extern void child_proxy(pid_t pid, int status); |
@@ -13,17 +13,6 @@ extern void init_proxy (pid_t pid, int waiting, int status); | |||
13 | extern int start_debugger(char *prog, int startup, int stop, int *debugger_fd); | 13 | extern int start_debugger(char *prog, int startup, int stop, int *debugger_fd); |
14 | extern void fake_child_exit(void); | 14 | extern void fake_child_exit(void); |
15 | extern int gdb_config(char *str); | 15 | extern int gdb_config(char *str); |
16 | extern int gdb_remove(char *unused); | 16 | extern int gdb_remove(int unused); |
17 | 17 | ||
18 | #endif | 18 | #endif |
19 | |||
20 | /* | ||
21 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
22 | * Emacs will notice this stuff at the end of the file and automatically | ||
23 | * adjust the settings for this buffer only. This must remain at the end | ||
24 | * of the file. | ||
25 | * --------------------------------------------------------------------------- | ||
26 | * Local variables: | ||
27 | * c-file-style: "linux" | ||
28 | * End: | ||
29 | */ | ||
diff --git a/arch/um/kernel/tt/include/mode-tt.h b/arch/um/kernel/tt/include/mode-tt.h index efe462019069..e171e15fead5 100644 --- a/arch/um/kernel/tt/include/mode-tt.h +++ b/arch/um/kernel/tt/include/mode-tt.h | |||
@@ -13,7 +13,6 @@ enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB }; | |||
13 | extern int tracing_pid; | 13 | extern int tracing_pid; |
14 | 14 | ||
15 | extern int tracer(int (*init_proc)(void *), void *sp); | 15 | extern int tracer(int (*init_proc)(void *), void *sp); |
16 | extern void user_time_init_tt(void); | ||
17 | extern void sig_handler_common_tt(int sig, void *sc); | 16 | extern void sig_handler_common_tt(int sig, void *sc); |
18 | extern void syscall_handler_tt(int sig, union uml_pt_regs *regs); | 17 | extern void syscall_handler_tt(int sig, union uml_pt_regs *regs); |
19 | extern void reboot_tt(void); | 18 | extern void reboot_tt(void); |
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c index 776310fd5b8b..a189a2b92935 100644 --- a/arch/um/kernel/tt/process_kern.c +++ b/arch/um/kernel/tt/process_kern.c | |||
@@ -266,10 +266,10 @@ int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp, | |||
266 | } | 266 | } |
267 | 267 | ||
268 | if(current->thread.forking){ | 268 | if(current->thread.forking){ |
269 | sc_to_sc(UPT_SC(&p->thread.regs.regs), | 269 | sc_to_sc(UPT_SC(&p->thread.regs.regs), UPT_SC(®s->regs)); |
270 | UPT_SC(¤t->thread.regs.regs)); | ||
271 | SC_SET_SYSCALL_RETURN(UPT_SC(&p->thread.regs.regs), 0); | 270 | SC_SET_SYSCALL_RETURN(UPT_SC(&p->thread.regs.regs), 0); |
272 | if(sp != 0) SC_SP(UPT_SC(&p->thread.regs.regs)) = sp; | 271 | if(sp != 0) |
272 | SC_SP(UPT_SC(&p->thread.regs.regs)) = sp; | ||
273 | } | 273 | } |
274 | p->thread.mode.tt.extern_pid = new_pid; | 274 | p->thread.mode.tt.extern_pid = new_pid; |
275 | 275 | ||
@@ -459,14 +459,3 @@ int is_valid_pid(int pid) | |||
459 | read_unlock(&tasklist_lock); | 459 | read_unlock(&tasklist_lock); |
460 | return(0); | 460 | return(0); |
461 | } | 461 | } |
462 | |||
463 | /* | ||
464 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
465 | * Emacs will notice this stuff at the end of the file and automatically | ||
466 | * adjust the settings for this buffer only. This must remain at the end | ||
467 | * of the file. | ||
468 | * --------------------------------------------------------------------------- | ||
469 | * Local variables: | ||
470 | * c-file-style: "linux" | ||
471 | * End: | ||
472 | */ | ||
diff --git a/arch/um/kernel/tt/time.c b/arch/um/kernel/tt/time.c deleted file mode 100644 index 8565b71b07cd..000000000000 --- a/arch/um/kernel/tt/time.c +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | |||
6 | #include <signal.h> | ||
7 | #include <sys/time.h> | ||
8 | #include <time_user.h> | ||
9 | #include "process.h" | ||
10 | #include "user.h" | ||
11 | |||
12 | void user_time_init_tt(void) | ||
13 | { | ||
14 | if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR) | ||
15 | panic("Couldn't set SIGVTALRM handler"); | ||
16 | set_interval(ITIMER_VIRTUAL); | ||
17 | } | ||
18 | |||
19 | /* | ||
20 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
21 | * Emacs will notice this stuff at the end of the file and automatically | ||
22 | * adjust the settings for this buffer only. This must remain at the end | ||
23 | * of the file. | ||
24 | * --------------------------------------------------------------------------- | ||
25 | * Local variables: | ||
26 | * c-file-style: "linux" | ||
27 | * End: | ||
28 | */ | ||
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c index 03913ca5d256..4efc69a039d7 100644 --- a/arch/um/sys-i386/signal.c +++ b/arch/um/sys-i386/signal.c | |||
@@ -312,7 +312,7 @@ long sys_sigreturn(struct pt_regs regs) | |||
312 | unsigned long __user *extramask = frame->extramask; | 312 | unsigned long __user *extramask = frame->extramask; |
313 | int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long); | 313 | int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long); |
314 | 314 | ||
315 | if(copy_from_user(&set.sig[0], oldmask, sizeof(&set.sig[0])) || | 315 | if(copy_from_user(&set.sig[0], oldmask, sizeof(set.sig[0])) || |
316 | copy_from_user(&set.sig[1], extramask, sig_size)) | 316 | copy_from_user(&set.sig[1], extramask, sig_size)) |
317 | goto segfault; | 317 | goto segfault; |
318 | 318 | ||
diff --git a/arch/um/sys-i386/syscalls.c b/arch/um/sys-i386/syscalls.c index 335e2d89504d..83e9be820a86 100644 --- a/arch/um/sys-i386/syscalls.c +++ b/arch/um/sys-i386/syscalls.c | |||
@@ -69,15 +69,11 @@ long sys_clone(unsigned long clone_flags, unsigned long newsp, | |||
69 | { | 69 | { |
70 | long ret; | 70 | long ret; |
71 | 71 | ||
72 | /* XXX: normal arch do here this pass, and also pass the regs to | 72 | if (!newsp) |
73 | * do_fork, instead of NULL. Currently the arch-independent code | 73 | newsp = UPT_SP(¤t->thread.regs.regs); |
74 | * ignores these values, while the UML code (actually it's | ||
75 | * copy_thread) does the right thing. But this should change, | ||
76 | probably. */ | ||
77 | /*if (!newsp) | ||
78 | newsp = UPT_SP(current->thread.regs);*/ | ||
79 | current->thread.forking = 1; | 74 | current->thread.forking = 1; |
80 | ret = do_fork(clone_flags, newsp, NULL, 0, parent_tid, child_tid); | 75 | ret = do_fork(clone_flags, newsp, ¤t->thread.regs, 0, parent_tid, |
76 | child_tid); | ||
81 | current->thread.forking = 0; | 77 | current->thread.forking = 0; |
82 | return(ret); | 78 | return(ret); |
83 | } | 79 | } |
@@ -197,14 +193,3 @@ long sys_sigaction(int sig, const struct old_sigaction __user *act, | |||
197 | 193 | ||
198 | return ret; | 194 | return ret; |
199 | } | 195 | } |
200 | |||
201 | /* | ||
202 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
203 | * Emacs will notice this stuff at the end of the file and automatically | ||
204 | * adjust the settings for this buffer only. This must remain at the end | ||
205 | * of the file. | ||
206 | * --------------------------------------------------------------------------- | ||
207 | * Local variables: | ||
208 | * c-file-style: "linux" | ||
209 | * End: | ||
210 | */ | ||
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c index 6f44f40204ed..3259a4db4534 100644 --- a/arch/um/sys-x86_64/syscalls.c +++ b/arch/um/sys-x86_64/syscalls.c | |||
@@ -174,26 +174,11 @@ long sys_clone(unsigned long clone_flags, unsigned long newsp, | |||
174 | { | 174 | { |
175 | long ret; | 175 | long ret; |
176 | 176 | ||
177 | /* XXX: normal arch do here this pass, and also pass the regs to | 177 | if (!newsp) |
178 | * do_fork, instead of NULL. Currently the arch-independent code | 178 | newsp = UPT_SP(¤t->thread.regs.regs); |
179 | * ignores these values, while the UML code (actually it's | ||
180 | * copy_thread) does the right thing. But this should change, | ||
181 | probably. */ | ||
182 | /*if (!newsp) | ||
183 | newsp = UPT_SP(current->thread.regs);*/ | ||
184 | current->thread.forking = 1; | 179 | current->thread.forking = 1; |
185 | ret = do_fork(clone_flags, newsp, NULL, 0, parent_tid, child_tid); | 180 | ret = do_fork(clone_flags, newsp, ¤t->thread.regs, 0, parent_tid, |
181 | child_tid); | ||
186 | current->thread.forking = 0; | 182 | current->thread.forking = 0; |
187 | return(ret); | 183 | return(ret); |
188 | } | 184 | } |
189 | |||
190 | /* | ||
191 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
192 | * Emacs will notice this stuff at the end of the file and automatically | ||
193 | * adjust the settings for this buffer only. This must remain at the end | ||
194 | * of the file. | ||
195 | * --------------------------------------------------------------------------- | ||
196 | * Local variables: | ||
197 | * c-file-style: "linux" | ||
198 | * End: | ||
199 | */ | ||
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index db259757dc8a..d09437b5c48f 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig | |||
@@ -207,33 +207,6 @@ config SMP | |||
207 | 207 | ||
208 | If you don't know what to do here, say N. | 208 | If you don't know what to do here, say N. |
209 | 209 | ||
210 | config PREEMPT | ||
211 | bool "Preemptible Kernel" | ||
212 | ---help--- | ||
213 | This option reduces the latency of the kernel when reacting to | ||
214 | real-time or interactive events by allowing a low priority process to | ||
215 | be preempted even if it is in kernel mode executing a system call. | ||
216 | This allows applications to run more reliably even when the system is | ||
217 | under load. On contrary it may also break your drivers and add | ||
218 | priority inheritance problems to your system. Don't select it if | ||
219 | you rely on a stable system or have slightly obscure hardware. | ||
220 | It's also not very well tested on x86-64 currently. | ||
221 | You have been warned. | ||
222 | |||
223 | Say Y here if you are feeling brave and building a kernel for a | ||
224 | desktop, embedded or real-time system. Say N if you are unsure. | ||
225 | |||
226 | config PREEMPT_BKL | ||
227 | bool "Preempt The Big Kernel Lock" | ||
228 | depends on PREEMPT | ||
229 | default y | ||
230 | help | ||
231 | This option reduces the latency of the kernel by making the | ||
232 | big kernel lock preemptible. | ||
233 | |||
234 | Say Y here if you are building a kernel for a desktop system. | ||
235 | Say N if you are unsure. | ||
236 | |||
237 | config SCHED_SMT | 210 | config SCHED_SMT |
238 | bool "SMT (Hyperthreading) scheduler support" | 211 | bool "SMT (Hyperthreading) scheduler support" |
239 | depends on SMP | 212 | depends on SMP |
@@ -244,6 +217,8 @@ config SCHED_SMT | |||
244 | cost of slightly increased overhead in some places. If unsure say | 217 | cost of slightly increased overhead in some places. If unsure say |
245 | N here. | 218 | N here. |
246 | 219 | ||
220 | source "kernel/Kconfig.preempt" | ||
221 | |||
247 | config K8_NUMA | 222 | config K8_NUMA |
248 | bool "K8 NUMA support" | 223 | bool "K8 NUMA support" |
249 | select NUMA | 224 | select NUMA |
@@ -313,6 +288,15 @@ config NR_CPUS | |||
313 | This is purely to save memory - each supported CPU requires | 288 | This is purely to save memory - each supported CPU requires |
314 | memory in the static kernel configuration. | 289 | memory in the static kernel configuration. |
315 | 290 | ||
291 | config HOTPLUG_CPU | ||
292 | bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" | ||
293 | depends on SMP && HOTPLUG && EXPERIMENTAL | ||
294 | help | ||
295 | Say Y here to experiment with turning CPUs off and on. CPUs | ||
296 | can be controlled through /sys/devices/system/cpu/cpu#. | ||
297 | Say N if you want to disable CPU hotplug. | ||
298 | |||
299 | |||
316 | config HPET_TIMER | 300 | config HPET_TIMER |
317 | bool | 301 | bool |
318 | default y | 302 | default y |
@@ -385,6 +369,34 @@ config X86_MCE_INTEL | |||
385 | Additional support for intel specific MCE features such as | 369 | Additional support for intel specific MCE features such as |
386 | the thermal monitor. | 370 | the thermal monitor. |
387 | 371 | ||
372 | config PHYSICAL_START | ||
373 | hex "Physical address where the kernel is loaded" if EMBEDDED | ||
374 | default "0x100000" | ||
375 | help | ||
376 | This gives the physical address where the kernel is loaded. | ||
377 | Primarily used in the case of kexec on panic where the | ||
378 | fail safe kernel needs to run at a different address than | ||
379 | the panic-ed kernel. | ||
380 | |||
381 | Don't change this unless you know what you are doing. | ||
382 | |||
383 | config KEXEC | ||
384 | bool "kexec system call (EXPERIMENTAL)" | ||
385 | depends on EXPERIMENTAL | ||
386 | help | ||
387 | kexec is a system call that implements the ability to shutdown your | ||
388 | current kernel, and to start another kernel. It is like a reboot | ||
389 | but it is indepedent of the system firmware. And like a reboot | ||
390 | you can start any kernel with it, not just Linux. | ||
391 | |||
392 | The name comes from the similiarity to the exec system call. | ||
393 | |||
394 | It is an ongoing process to be certain the hardware in a machine | ||
395 | is properly shutdown, so do not be surprised if this code does not | ||
396 | initially work for you. It may help to enable device hotplugging | ||
397 | support. As of this writing the exact hardware interface is | ||
398 | strongly in flux, so no good recommendation can be made. | ||
399 | |||
388 | config SECCOMP | 400 | config SECCOMP |
389 | bool "Enable seccomp to safely compute untrusted bytecode" | 401 | bool "Enable seccomp to safely compute untrusted bytecode" |
390 | depends on PROC_FS | 402 | depends on PROC_FS |
diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile index 6f90c246c418..8a73794f9b90 100644 --- a/arch/x86_64/Makefile +++ b/arch/x86_64/Makefile | |||
@@ -35,7 +35,7 @@ export IA32_CC IA32_LD IA32_AS IA32_OBJCOPY IA32_CPP | |||
35 | 35 | ||
36 | LDFLAGS := -m elf_x86_64 | 36 | LDFLAGS := -m elf_x86_64 |
37 | OBJCOPYFLAGS := -O binary -R .note -R .comment -S | 37 | OBJCOPYFLAGS := -O binary -R .note -R .comment -S |
38 | LDFLAGS_vmlinux := -e stext | 38 | LDFLAGS_vmlinux := |
39 | 39 | ||
40 | CHECKFLAGS += -D__x86_64__ -m64 | 40 | CHECKFLAGS += -D__x86_64__ -m64 |
41 | 41 | ||
diff --git a/arch/x86_64/boot/compressed/head.S b/arch/x86_64/boot/compressed/head.S index 27264dbd575c..6f55565e4d42 100644 --- a/arch/x86_64/boot/compressed/head.S +++ b/arch/x86_64/boot/compressed/head.S | |||
@@ -2,8 +2,6 @@ | |||
2 | * linux/boot/head.S | 2 | * linux/boot/head.S |
3 | * | 3 | * |
4 | * Copyright (C) 1991, 1992, 1993 Linus Torvalds | 4 | * Copyright (C) 1991, 1992, 1993 Linus Torvalds |
5 | * | ||
6 | * $Id: head.S,v 1.3 2001/04/20 00:59:28 ak Exp $ | ||
7 | */ | 5 | */ |
8 | 6 | ||
9 | /* | 7 | /* |
@@ -21,13 +19,14 @@ | |||
21 | */ | 19 | */ |
22 | 20 | ||
23 | /* | 21 | /* |
24 | * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 | 22 | * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 |
25 | */ | 23 | */ |
26 | .code32 | 24 | .code32 |
27 | .text | 25 | .text |
28 | 26 | ||
29 | #include <linux/linkage.h> | 27 | #include <linux/linkage.h> |
30 | #include <asm/segment.h> | 28 | #include <asm/segment.h> |
29 | #include <asm/page.h> | ||
31 | 30 | ||
32 | .code32 | 31 | .code32 |
33 | .globl startup_32 | 32 | .globl startup_32 |
@@ -77,7 +76,7 @@ startup_32: | |||
77 | jnz 3f | 76 | jnz 3f |
78 | addl $8,%esp | 77 | addl $8,%esp |
79 | xorl %ebx,%ebx | 78 | xorl %ebx,%ebx |
80 | ljmp $(__KERNEL_CS), $0x100000 | 79 | ljmp $(__KERNEL_CS), $__PHYSICAL_START |
81 | 80 | ||
82 | /* | 81 | /* |
83 | * We come here, if we were loaded high. | 82 | * We come here, if we were loaded high. |
@@ -103,7 +102,7 @@ startup_32: | |||
103 | popl %ecx # lcount | 102 | popl %ecx # lcount |
104 | popl %edx # high_buffer_start | 103 | popl %edx # high_buffer_start |
105 | popl %eax # hcount | 104 | popl %eax # hcount |
106 | movl $0x100000,%edi | 105 | movl $__PHYSICAL_START,%edi |
107 | cli # make sure we don't get interrupted | 106 | cli # make sure we don't get interrupted |
108 | ljmp $(__KERNEL_CS), $0x1000 # and jump to the move routine | 107 | ljmp $(__KERNEL_CS), $0x1000 # and jump to the move routine |
109 | 108 | ||
@@ -128,7 +127,7 @@ move_routine_start: | |||
128 | movsl | 127 | movsl |
129 | movl %ebx,%esi # Restore setup pointer | 128 | movl %ebx,%esi # Restore setup pointer |
130 | xorl %ebx,%ebx | 129 | xorl %ebx,%ebx |
131 | ljmp $(__KERNEL_CS), $0x100000 | 130 | ljmp $(__KERNEL_CS), $__PHYSICAL_START |
132 | move_routine_end: | 131 | move_routine_end: |
133 | 132 | ||
134 | 133 | ||
diff --git a/arch/x86_64/boot/compressed/misc.c b/arch/x86_64/boot/compressed/misc.c index c8b9216f9e63..b38d5b8b5fb8 100644 --- a/arch/x86_64/boot/compressed/misc.c +++ b/arch/x86_64/boot/compressed/misc.c | |||
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | #include "miscsetup.h" | 12 | #include "miscsetup.h" |
13 | #include <asm/io.h> | 13 | #include <asm/io.h> |
14 | #include <asm/page.h> | ||
14 | 15 | ||
15 | /* | 16 | /* |
16 | * gzip declarations | 17 | * gzip declarations |
@@ -92,8 +93,11 @@ static unsigned long output_ptr = 0; | |||
92 | static void *malloc(int size); | 93 | static void *malloc(int size); |
93 | static void free(void *where); | 94 | static void free(void *where); |
94 | 95 | ||
96 | void* memset(void* s, int c, unsigned n); | ||
97 | void* memcpy(void* dest, const void* src, unsigned n); | ||
98 | |||
95 | static void putstr(const char *); | 99 | static void putstr(const char *); |
96 | 100 | ||
97 | extern int end; | 101 | extern int end; |
98 | static long free_mem_ptr = (long)&end; | 102 | static long free_mem_ptr = (long)&end; |
99 | static long free_mem_end_ptr; | 103 | static long free_mem_end_ptr; |
@@ -284,7 +288,7 @@ void setup_normal_output_buffer(void) | |||
284 | #else | 288 | #else |
285 | if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory"); | 289 | if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory"); |
286 | #endif | 290 | #endif |
287 | output_data = (char *)0x100000; /* Points to 1M */ | 291 | output_data = (char *)__PHYSICAL_START; /* Normally Points to 1M */ |
288 | free_mem_end_ptr = (long)real_mode; | 292 | free_mem_end_ptr = (long)real_mode; |
289 | } | 293 | } |
290 | 294 | ||
@@ -307,8 +311,8 @@ void setup_output_buffer_if_we_run_high(struct moveparams *mv) | |||
307 | low_buffer_size = low_buffer_end - LOW_BUFFER_START; | 311 | low_buffer_size = low_buffer_end - LOW_BUFFER_START; |
308 | high_loaded = 1; | 312 | high_loaded = 1; |
309 | free_mem_end_ptr = (long)high_buffer_start; | 313 | free_mem_end_ptr = (long)high_buffer_start; |
310 | if ( (0x100000 + low_buffer_size) > ((ulg)high_buffer_start)) { | 314 | if ( (__PHYSICAL_START + low_buffer_size) > ((ulg)high_buffer_start)) { |
311 | high_buffer_start = (uch *)(0x100000 + low_buffer_size); | 315 | high_buffer_start = (uch *)(__PHYSICAL_START + low_buffer_size); |
312 | mv->hcount = 0; /* say: we need not to move high_buffer */ | 316 | mv->hcount = 0; /* say: we need not to move high_buffer */ |
313 | } | 317 | } |
314 | else mv->hcount = -1; | 318 | else mv->hcount = -1; |
diff --git a/arch/x86_64/boot/install.sh b/arch/x86_64/boot/install.sh index f17b40dfc0f4..198af15a7758 100644 --- a/arch/x86_64/boot/install.sh +++ b/arch/x86_64/boot/install.sh | |||
@@ -1,6 +1,6 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | # | 2 | # |
3 | # arch/i386/boot/install.sh | 3 | # arch/x86_64/boot/install.sh |
4 | # | 4 | # |
5 | # This file is subject to the terms and conditions of the GNU General Public | 5 | # This file is subject to the terms and conditions of the GNU General Public |
6 | # License. See the file "COPYING" in the main directory of this archive | 6 | # License. See the file "COPYING" in the main directory of this archive |
diff --git a/arch/x86_64/boot/setup.S b/arch/x86_64/boot/setup.S index 75d4d2ad93b3..ff58b2832b75 100644 --- a/arch/x86_64/boot/setup.S +++ b/arch/x86_64/boot/setup.S | |||
@@ -33,7 +33,7 @@ | |||
33 | * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999. | 33 | * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999. |
34 | * <stiker@northlink.com> | 34 | * <stiker@northlink.com> |
35 | * | 35 | * |
36 | * Fix to work around buggy BIOSes which dont use carry bit correctly | 36 | * Fix to work around buggy BIOSes which don't use carry bit correctly |
37 | * and/or report extended memory in CX/DX for e801h memory size detection | 37 | * and/or report extended memory in CX/DX for e801h memory size detection |
38 | * call. As a result the kernel got wrong figures. The int15/e801h docs | 38 | * call. As a result the kernel got wrong figures. The int15/e801h docs |
39 | * from Ralf Brown interrupt list seem to indicate AX/BX should be used | 39 | * from Ralf Brown interrupt list seem to indicate AX/BX should be used |
@@ -383,7 +383,7 @@ sse_ok: | |||
383 | # a whole bunch of different types, and allows memory holes and | 383 | # a whole bunch of different types, and allows memory holes and |
384 | # everything. We scan through this memory map and build a list | 384 | # everything. We scan through this memory map and build a list |
385 | # of the first 32 memory areas, which we return at [E820MAP]. | 385 | # of the first 32 memory areas, which we return at [E820MAP]. |
386 | # This is documented at http://www.teleport.com/~acpi/acpihtml/topic245.htm | 386 | # This is documented at http://www.acpi.info/, in the ACPI 2.0 specification. |
387 | 387 | ||
388 | #define SMAP 0x534d4150 | 388 | #define SMAP 0x534d4150 |
389 | 389 | ||
@@ -436,7 +436,7 @@ bail820: | |||
436 | 436 | ||
437 | meme801: | 437 | meme801: |
438 | stc # fix to work around buggy | 438 | stc # fix to work around buggy |
439 | xorw %cx,%cx # BIOSes which dont clear/set | 439 | xorw %cx,%cx # BIOSes which don't clear/set |
440 | xorw %dx,%dx # carry on pass/error of | 440 | xorw %dx,%dx # carry on pass/error of |
441 | # e801h memory size call | 441 | # e801h memory size call |
442 | # or merely pass cx,dx though | 442 | # or merely pass cx,dx though |
@@ -733,7 +733,7 @@ flush_instr: | |||
733 | # | 733 | # |
734 | # but we yet haven't reloaded the CS register, so the default size | 734 | # but we yet haven't reloaded the CS register, so the default size |
735 | # of the target offset still is 16 bit. | 735 | # of the target offset still is 16 bit. |
736 | # However, using an operant prefix (0x66), the CPU will properly | 736 | # However, using an operand prefix (0x66), the CPU will properly |
737 | # take our 48 bit far pointer. (INTeL 80386 Programmer's Reference | 737 | # take our 48 bit far pointer. (INTeL 80386 Programmer's Reference |
738 | # Manual, Mixing 16-bit and 32-bit code, page 16-6) | 738 | # Manual, Mixing 16-bit and 32-bit code, page 16-6) |
739 | 739 | ||
diff --git a/arch/x86_64/boot/tools/build.c b/arch/x86_64/boot/tools/build.c index c2fa66313170..18b5bac1c428 100644 --- a/arch/x86_64/boot/tools/build.c +++ b/arch/x86_64/boot/tools/build.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: build.c,v 1.3 2001/06/26 15:14:50 pavel Exp $ | ||
3 | * | ||
4 | * Copyright (C) 1991, 1992 Linus Torvalds | 2 | * Copyright (C) 1991, 1992 Linus Torvalds |
5 | * Copyright (C) 1997 Martin Mares | 3 | * Copyright (C) 1997 Martin Mares |
6 | */ | 4 | */ |
@@ -8,7 +6,8 @@ | |||
8 | /* | 6 | /* |
9 | * This file builds a disk-image from three different files: | 7 | * This file builds a disk-image from three different files: |
10 | * | 8 | * |
11 | * - bootsect: exactly 512 bytes of 8086 machine code, loads the rest | 9 | * - bootsect: compatibility mbr which prints an error message if |
10 | * someone tries to boot the kernel directly. | ||
12 | * - setup: 8086 machine code, sets up system parm | 11 | * - setup: 8086 machine code, sets up system parm |
13 | * - system: 80386 code for actual system | 12 | * - system: 80386 code for actual system |
14 | * | 13 | * |
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S index f3ca0db85b5b..cc935427d532 100644 --- a/arch/x86_64/ia32/ia32entry.S +++ b/arch/x86_64/ia32/ia32entry.S | |||
@@ -589,7 +589,7 @@ ia32_sys_call_table: | |||
589 | .quad compat_sys_mq_timedreceive /* 280 */ | 589 | .quad compat_sys_mq_timedreceive /* 280 */ |
590 | .quad compat_sys_mq_notify | 590 | .quad compat_sys_mq_notify |
591 | .quad compat_sys_mq_getsetattr | 591 | .quad compat_sys_mq_getsetattr |
592 | .quad quiet_ni_syscall /* reserved for kexec */ | 592 | .quad compat_sys_kexec_load /* reserved for kexec */ |
593 | .quad compat_sys_waitid | 593 | .quad compat_sys_waitid |
594 | .quad quiet_ni_syscall /* sys_altroot */ | 594 | .quad quiet_ni_syscall /* sys_altroot */ |
595 | .quad sys_add_key | 595 | .quad sys_add_key |
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile index 5ca4a4598fda..48f9e2c19cd6 100644 --- a/arch/x86_64/kernel/Makefile +++ b/arch/x86_64/kernel/Makefile | |||
@@ -20,6 +20,7 @@ obj-$(CONFIG_SMP) += smp.o smpboot.o trampoline.o | |||
20 | obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o | 20 | obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o |
21 | obj-$(CONFIG_X86_IO_APIC) += io_apic.o mpparse.o \ | 21 | obj-$(CONFIG_X86_IO_APIC) += io_apic.o mpparse.o \ |
22 | genapic.o genapic_cluster.o genapic_flat.o | 22 | genapic.o genapic_cluster.o genapic_flat.o |
23 | obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o | ||
23 | obj-$(CONFIG_PM) += suspend.o | 24 | obj-$(CONFIG_PM) += suspend.o |
24 | obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend_asm.o | 25 | obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend_asm.o |
25 | obj-$(CONFIG_CPU_FREQ) += cpufreq/ | 26 | obj-$(CONFIG_CPU_FREQ) += cpufreq/ |
diff --git a/arch/x86_64/kernel/acpi/wakeup.S b/arch/x86_64/kernel/acpi/wakeup.S index a4c630034cd4..185faa911db5 100644 --- a/arch/x86_64/kernel/acpi/wakeup.S +++ b/arch/x86_64/kernel/acpi/wakeup.S | |||
@@ -67,7 +67,7 @@ wakeup_code: | |||
67 | shll $4, %eax | 67 | shll $4, %eax |
68 | addl $(gdta - wakeup_code), %eax | 68 | addl $(gdta - wakeup_code), %eax |
69 | movl %eax, gdt_48a +2 - wakeup_code | 69 | movl %eax, gdt_48a +2 - wakeup_code |
70 | lgdt %ds:gdt_48a - wakeup_code # load gdt with whatever is | 70 | lgdtl %ds:gdt_48a - wakeup_code # load gdt with whatever is |
71 | # appropriate | 71 | # appropriate |
72 | 72 | ||
73 | movl $1, %eax # protected mode (PE) bit | 73 | movl $1, %eax # protected mode (PE) bit |
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c index f8e6cc4fecd4..375d369570ca 100644 --- a/arch/x86_64/kernel/apic.c +++ b/arch/x86_64/kernel/apic.c | |||
@@ -133,7 +133,7 @@ void __init connect_bsp_APIC(void) | |||
133 | } | 133 | } |
134 | } | 134 | } |
135 | 135 | ||
136 | void disconnect_bsp_APIC(void) | 136 | void disconnect_bsp_APIC(int virt_wire_setup) |
137 | { | 137 | { |
138 | if (pic_mode) { | 138 | if (pic_mode) { |
139 | /* | 139 | /* |
@@ -146,6 +146,42 @@ void disconnect_bsp_APIC(void) | |||
146 | outb(0x70, 0x22); | 146 | outb(0x70, 0x22); |
147 | outb(0x00, 0x23); | 147 | outb(0x00, 0x23); |
148 | } | 148 | } |
149 | else { | ||
150 | /* Go back to Virtual Wire compatibility mode */ | ||
151 | unsigned long value; | ||
152 | |||
153 | /* For the spurious interrupt use vector F, and enable it */ | ||
154 | value = apic_read(APIC_SPIV); | ||
155 | value &= ~APIC_VECTOR_MASK; | ||
156 | value |= APIC_SPIV_APIC_ENABLED; | ||
157 | value |= 0xf; | ||
158 | apic_write_around(APIC_SPIV, value); | ||
159 | |||
160 | if (!virt_wire_setup) { | ||
161 | /* For LVT0 make it edge triggered, active high, external and enabled */ | ||
162 | value = apic_read(APIC_LVT0); | ||
163 | value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING | | ||
164 | APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | | ||
165 | APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED ); | ||
166 | value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; | ||
167 | value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT); | ||
168 | apic_write_around(APIC_LVT0, value); | ||
169 | } | ||
170 | else { | ||
171 | /* Disable LVT0 */ | ||
172 | apic_write_around(APIC_LVT0, APIC_LVT_MASKED); | ||
173 | } | ||
174 | |||
175 | /* For LVT1 make it edge triggered, active high, nmi and enabled */ | ||
176 | value = apic_read(APIC_LVT1); | ||
177 | value &= ~( | ||
178 | APIC_MODE_MASK | APIC_SEND_PENDING | | ||
179 | APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | | ||
180 | APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED); | ||
181 | value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; | ||
182 | value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI); | ||
183 | apic_write_around(APIC_LVT1, value); | ||
184 | } | ||
149 | } | 185 | } |
150 | 186 | ||
151 | void disable_local_APIC(void) | 187 | void disable_local_APIC(void) |
@@ -285,7 +321,7 @@ void __init init_bsp_APIC(void) | |||
285 | apic_write_around(APIC_LVT1, value); | 321 | apic_write_around(APIC_LVT1, value); |
286 | } | 322 | } |
287 | 323 | ||
288 | void __init setup_local_APIC (void) | 324 | void __cpuinit setup_local_APIC (void) |
289 | { | 325 | { |
290 | unsigned int value, ver, maxlvt; | 326 | unsigned int value, ver, maxlvt; |
291 | 327 | ||
@@ -534,7 +570,7 @@ static struct sys_device device_lapic = { | |||
534 | .cls = &lapic_sysclass, | 570 | .cls = &lapic_sysclass, |
535 | }; | 571 | }; |
536 | 572 | ||
537 | static void __init apic_pm_activate(void) | 573 | static void __cpuinit apic_pm_activate(void) |
538 | { | 574 | { |
539 | apic_pm_state.active = 1; | 575 | apic_pm_state.active = 1; |
540 | } | 576 | } |
@@ -774,14 +810,14 @@ void __init setup_boot_APIC_clock (void) | |||
774 | local_irq_enable(); | 810 | local_irq_enable(); |
775 | } | 811 | } |
776 | 812 | ||
777 | void __init setup_secondary_APIC_clock(void) | 813 | void __cpuinit setup_secondary_APIC_clock(void) |
778 | { | 814 | { |
779 | local_irq_disable(); /* FIXME: Do we need this? --RR */ | 815 | local_irq_disable(); /* FIXME: Do we need this? --RR */ |
780 | setup_APIC_timer(calibration_result); | 816 | setup_APIC_timer(calibration_result); |
781 | local_irq_enable(); | 817 | local_irq_enable(); |
782 | } | 818 | } |
783 | 819 | ||
784 | void __init disable_APIC_timer(void) | 820 | void __cpuinit disable_APIC_timer(void) |
785 | { | 821 | { |
786 | if (using_apic_timer) { | 822 | if (using_apic_timer) { |
787 | unsigned long v; | 823 | unsigned long v; |
diff --git a/arch/x86_64/kernel/crash.c b/arch/x86_64/kernel/crash.c new file mode 100644 index 000000000000..d7fa4248501c --- /dev/null +++ b/arch/x86_64/kernel/crash.c | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * Architecture specific (x86_64) functions for kexec based crash dumps. | ||
3 | * | ||
4 | * Created by: Hariprasad Nellitheertha (hari@in.ibm.com) | ||
5 | * | ||
6 | * Copyright (C) IBM Corporation, 2004. All rights reserved. | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #include <linux/init.h> | ||
11 | #include <linux/types.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/smp.h> | ||
14 | #include <linux/irq.h> | ||
15 | #include <linux/reboot.h> | ||
16 | #include <linux/kexec.h> | ||
17 | |||
18 | #include <asm/processor.h> | ||
19 | #include <asm/hardirq.h> | ||
20 | #include <asm/nmi.h> | ||
21 | #include <asm/hw_irq.h> | ||
22 | |||
23 | note_buf_t crash_notes[NR_CPUS]; | ||
24 | |||
25 | void machine_crash_shutdown(struct pt_regs *regs) | ||
26 | { | ||
27 | /* This function is only called after the system | ||
28 | * has paniced or is otherwise in a critical state. | ||
29 | * The minimum amount of code to allow a kexec'd kernel | ||
30 | * to run successfully needs to happen here. | ||
31 | * | ||
32 | * In practice this means shooting down the other cpus in | ||
33 | * an SMP system. | ||
34 | */ | ||
35 | } | ||
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c index 7c154dfff64a..6ded3a50dfe6 100644 --- a/arch/x86_64/kernel/e820.c +++ b/arch/x86_64/kernel/e820.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/bootmem.h> | 16 | #include <linux/bootmem.h> |
17 | #include <linux/ioport.h> | 17 | #include <linux/ioport.h> |
18 | #include <linux/string.h> | 18 | #include <linux/string.h> |
19 | #include <linux/kexec.h> | ||
19 | #include <asm/page.h> | 20 | #include <asm/page.h> |
20 | #include <asm/e820.h> | 21 | #include <asm/e820.h> |
21 | #include <asm/proto.h> | 22 | #include <asm/proto.h> |
@@ -191,8 +192,6 @@ void __init e820_reserve_resources(void) | |||
191 | int i; | 192 | int i; |
192 | for (i = 0; i < e820.nr_map; i++) { | 193 | for (i = 0; i < e820.nr_map; i++) { |
193 | struct resource *res; | 194 | struct resource *res; |
194 | if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL) | ||
195 | continue; | ||
196 | res = alloc_bootmem_low(sizeof(struct resource)); | 195 | res = alloc_bootmem_low(sizeof(struct resource)); |
197 | switch (e820.map[i].type) { | 196 | switch (e820.map[i].type) { |
198 | case E820_RAM: res->name = "System RAM"; break; | 197 | case E820_RAM: res->name = "System RAM"; break; |
@@ -212,6 +211,9 @@ void __init e820_reserve_resources(void) | |||
212 | */ | 211 | */ |
213 | request_resource(res, &code_resource); | 212 | request_resource(res, &code_resource); |
214 | request_resource(res, &data_resource); | 213 | request_resource(res, &data_resource); |
214 | #ifdef CONFIG_KEXEC | ||
215 | request_resource(res, &crashk_res); | ||
216 | #endif | ||
215 | } | 217 | } |
216 | } | 218 | } |
217 | } | 219 | } |
diff --git a/arch/x86_64/kernel/genapic_flat.c b/arch/x86_64/kernel/genapic_flat.c index b4cbbad04226..282846965080 100644 --- a/arch/x86_64/kernel/genapic_flat.c +++ b/arch/x86_64/kernel/genapic_flat.c | |||
@@ -7,6 +7,8 @@ | |||
7 | * Hacked for x86-64 by James Cleverdon from i386 architecture code by | 7 | * Hacked for x86-64 by James Cleverdon from i386 architecture code by |
8 | * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and | 8 | * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and |
9 | * James Cleverdon. | 9 | * James Cleverdon. |
10 | * Ashok Raj <ashok.raj@intel.com> | ||
11 | * Removed IPI broadcast shortcut to support CPU hotplug | ||
10 | */ | 12 | */ |
11 | #include <linux/config.h> | 13 | #include <linux/config.h> |
12 | #include <linux/threads.h> | 14 | #include <linux/threads.h> |
@@ -18,6 +20,46 @@ | |||
18 | #include <asm/smp.h> | 20 | #include <asm/smp.h> |
19 | #include <asm/ipi.h> | 21 | #include <asm/ipi.h> |
20 | 22 | ||
23 | /* | ||
24 | * The following permit choosing broadcast IPI shortcut v.s sending IPI only | ||
25 | * to online cpus via the send_IPI_mask varient. | ||
26 | * The mask version is my preferred option, since it eliminates a lot of | ||
27 | * other extra code that would need to be written to cleanup intrs sent | ||
28 | * to a CPU while offline. | ||
29 | * | ||
30 | * Sending broadcast introduces lots of trouble in CPU hotplug situations. | ||
31 | * These IPI's are delivered to cpu's irrespective of their offline status | ||
32 | * and could pickup stale intr data when these CPUS are turned online. | ||
33 | * | ||
34 | * Not using broadcast is a cleaner approach IMO, but Andi Kleen disagrees with | ||
35 | * the idea of not using broadcast IPI's anymore. Hence the run time check | ||
36 | * is introduced, on his request so we can choose an alternate mechanism. | ||
37 | * | ||
38 | * Initial wacky performance tests that collect cycle counts show | ||
39 | * no increase in using mask v.s broadcast version. In fact they seem | ||
40 | * identical in terms of cycle counts. | ||
41 | * | ||
42 | * if we need to use broadcast, we need to do the following. | ||
43 | * | ||
44 | * cli; | ||
45 | * hold call_lock; | ||
46 | * clear any pending IPI, just ack and clear all pending intr | ||
47 | * set cpu_online_map; | ||
48 | * release call_lock; | ||
49 | * sti; | ||
50 | * | ||
51 | * The complicated dummy irq processing shown above is not required if | ||
52 | * we didnt sent IPI's to wrong CPU's in the first place. | ||
53 | * | ||
54 | * - Ashok Raj <ashok.raj@intel.com> | ||
55 | */ | ||
56 | #ifdef CONFIG_HOTPLUG_CPU | ||
57 | #define DEFAULT_SEND_IPI (1) | ||
58 | #else | ||
59 | #define DEFAULT_SEND_IPI (0) | ||
60 | #endif | ||
61 | |||
62 | static int no_broadcast=DEFAULT_SEND_IPI; | ||
21 | 63 | ||
22 | static cpumask_t flat_target_cpus(void) | 64 | static cpumask_t flat_target_cpus(void) |
23 | { | 65 | { |
@@ -45,22 +87,6 @@ static void flat_init_apic_ldr(void) | |||
45 | apic_write_around(APIC_LDR, val); | 87 | apic_write_around(APIC_LDR, val); |
46 | } | 88 | } |
47 | 89 | ||
48 | static void flat_send_IPI_allbutself(int vector) | ||
49 | { | ||
50 | /* | ||
51 | * if there are no other CPUs in the system then | ||
52 | * we get an APIC send error if we try to broadcast. | ||
53 | * thus we have to avoid sending IPIs in this case. | ||
54 | */ | ||
55 | if (num_online_cpus() > 1) | ||
56 | __send_IPI_shortcut(APIC_DEST_ALLBUT, vector, APIC_DEST_LOGICAL); | ||
57 | } | ||
58 | |||
59 | static void flat_send_IPI_all(int vector) | ||
60 | { | ||
61 | __send_IPI_shortcut(APIC_DEST_ALLINC, vector, APIC_DEST_LOGICAL); | ||
62 | } | ||
63 | |||
64 | static void flat_send_IPI_mask(cpumask_t cpumask, int vector) | 90 | static void flat_send_IPI_mask(cpumask_t cpumask, int vector) |
65 | { | 91 | { |
66 | unsigned long mask = cpus_addr(cpumask)[0]; | 92 | unsigned long mask = cpus_addr(cpumask)[0]; |
@@ -93,6 +119,39 @@ static void flat_send_IPI_mask(cpumask_t cpumask, int vector) | |||
93 | local_irq_restore(flags); | 119 | local_irq_restore(flags); |
94 | } | 120 | } |
95 | 121 | ||
122 | static inline void __local_flat_send_IPI_allbutself(int vector) | ||
123 | { | ||
124 | if (no_broadcast) { | ||
125 | cpumask_t mask = cpu_online_map; | ||
126 | int this_cpu = get_cpu(); | ||
127 | |||
128 | cpu_clear(this_cpu, mask); | ||
129 | flat_send_IPI_mask(mask, vector); | ||
130 | put_cpu(); | ||
131 | } | ||
132 | else | ||
133 | __send_IPI_shortcut(APIC_DEST_ALLBUT, vector, APIC_DEST_LOGICAL); | ||
134 | } | ||
135 | |||
136 | static inline void __local_flat_send_IPI_all(int vector) | ||
137 | { | ||
138 | if (no_broadcast) | ||
139 | flat_send_IPI_mask(cpu_online_map, vector); | ||
140 | else | ||
141 | __send_IPI_shortcut(APIC_DEST_ALLINC, vector, APIC_DEST_LOGICAL); | ||
142 | } | ||
143 | |||
144 | static void flat_send_IPI_allbutself(int vector) | ||
145 | { | ||
146 | if (((num_online_cpus()) - 1) >= 1) | ||
147 | __local_flat_send_IPI_allbutself(vector); | ||
148 | } | ||
149 | |||
150 | static void flat_send_IPI_all(int vector) | ||
151 | { | ||
152 | __local_flat_send_IPI_all(vector); | ||
153 | } | ||
154 | |||
96 | static int flat_apic_id_registered(void) | 155 | static int flat_apic_id_registered(void) |
97 | { | 156 | { |
98 | return physid_isset(GET_APIC_ID(apic_read(APIC_ID)), phys_cpu_present_map); | 157 | return physid_isset(GET_APIC_ID(apic_read(APIC_ID)), phys_cpu_present_map); |
@@ -111,6 +170,16 @@ static unsigned int phys_pkg_id(int index_msb) | |||
111 | return ((ebx >> 24) & 0xFF) >> index_msb; | 170 | return ((ebx >> 24) & 0xFF) >> index_msb; |
112 | } | 171 | } |
113 | 172 | ||
173 | static __init int no_ipi_broadcast(char *str) | ||
174 | { | ||
175 | get_option(&str, &no_broadcast); | ||
176 | printk ("Using %s mode\n", no_broadcast ? "No IPI Broadcast" : | ||
177 | "IPI Broadcast"); | ||
178 | return 1; | ||
179 | } | ||
180 | |||
181 | __setup("no_ipi_broadcast", no_ipi_broadcast); | ||
182 | |||
114 | struct genapic apic_flat = { | 183 | struct genapic apic_flat = { |
115 | .name = "flat", | 184 | .name = "flat", |
116 | .int_delivery_mode = dest_LowestPrio, | 185 | .int_delivery_mode = dest_LowestPrio, |
@@ -125,3 +194,12 @@ struct genapic apic_flat = { | |||
125 | .cpu_mask_to_apicid = flat_cpu_mask_to_apicid, | 194 | .cpu_mask_to_apicid = flat_cpu_mask_to_apicid, |
126 | .phys_pkg_id = phys_pkg_id, | 195 | .phys_pkg_id = phys_pkg_id, |
127 | }; | 196 | }; |
197 | |||
198 | static int __init print_ipi_mode(void) | ||
199 | { | ||
200 | printk ("Using IPI %s mode\n", no_broadcast ? "No-Shortcut" : | ||
201 | "Shortcut"); | ||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | late_initcall(print_ipi_mode); | ||
diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S index 9bd2e7a4b81e..8d765aa77a26 100644 --- a/arch/x86_64/kernel/head.S +++ b/arch/x86_64/kernel/head.S | |||
@@ -248,23 +248,23 @@ ENTRY(_stext) | |||
248 | */ | 248 | */ |
249 | .org 0x1000 | 249 | .org 0x1000 |
250 | ENTRY(init_level4_pgt) | 250 | ENTRY(init_level4_pgt) |
251 | .quad 0x0000000000102007 /* -> level3_ident_pgt */ | 251 | .quad 0x0000000000002007 + __PHYSICAL_START /* -> level3_ident_pgt */ |
252 | .fill 255,8,0 | 252 | .fill 255,8,0 |
253 | .quad 0x000000000010a007 | 253 | .quad 0x000000000000a007 + __PHYSICAL_START |
254 | .fill 254,8,0 | 254 | .fill 254,8,0 |
255 | /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ | 255 | /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ |
256 | .quad 0x0000000000103007 /* -> level3_kernel_pgt */ | 256 | .quad 0x0000000000003007 + __PHYSICAL_START /* -> level3_kernel_pgt */ |
257 | 257 | ||
258 | .org 0x2000 | 258 | .org 0x2000 |
259 | ENTRY(level3_ident_pgt) | 259 | ENTRY(level3_ident_pgt) |
260 | .quad 0x0000000000104007 | 260 | .quad 0x0000000000004007 + __PHYSICAL_START |
261 | .fill 511,8,0 | 261 | .fill 511,8,0 |
262 | 262 | ||
263 | .org 0x3000 | 263 | .org 0x3000 |
264 | ENTRY(level3_kernel_pgt) | 264 | ENTRY(level3_kernel_pgt) |
265 | .fill 510,8,0 | 265 | .fill 510,8,0 |
266 | /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */ | 266 | /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */ |
267 | .quad 0x0000000000105007 /* -> level2_kernel_pgt */ | 267 | .quad 0x0000000000005007 + __PHYSICAL_START /* -> level2_kernel_pgt */ |
268 | .fill 1,8,0 | 268 | .fill 1,8,0 |
269 | 269 | ||
270 | .org 0x4000 | 270 | .org 0x4000 |
@@ -337,17 +337,17 @@ ENTRY(empty_bad_pmd_table) | |||
337 | 337 | ||
338 | .org 0xa000 | 338 | .org 0xa000 |
339 | ENTRY(level3_physmem_pgt) | 339 | ENTRY(level3_physmem_pgt) |
340 | .quad 0x0000000000105007 /* -> level2_kernel_pgt (so that __va works even before pagetable_init) */ | 340 | .quad 0x0000000000005007 + __PHYSICAL_START /* -> level2_kernel_pgt (so that __va works even before pagetable_init) */ |
341 | 341 | ||
342 | .org 0xb000 | 342 | .org 0xb000 |
343 | #ifdef CONFIG_ACPI_SLEEP | 343 | #ifdef CONFIG_ACPI_SLEEP |
344 | ENTRY(wakeup_level4_pgt) | 344 | ENTRY(wakeup_level4_pgt) |
345 | .quad 0x0000000000102007 /* -> level3_ident_pgt */ | 345 | .quad 0x0000000000002007 + __PHYSICAL_START /* -> level3_ident_pgt */ |
346 | .fill 255,8,0 | 346 | .fill 255,8,0 |
347 | .quad 0x000000000010a007 | 347 | .quad 0x000000000000a007 + __PHYSICAL_START |
348 | .fill 254,8,0 | 348 | .fill 254,8,0 |
349 | /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ | 349 | /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ |
350 | .quad 0x0000000000103007 /* -> level3_kernel_pgt */ | 350 | .quad 0x0000000000003007 + __PHYSICAL_START /* -> level3_kernel_pgt */ |
351 | #endif | 351 | #endif |
352 | 352 | ||
353 | .data | 353 | .data |
diff --git a/arch/x86_64/kernel/i387.c b/arch/x86_64/kernel/i387.c index ba139cac57ce..d9b22b633e39 100644 --- a/arch/x86_64/kernel/i387.c +++ b/arch/x86_64/kernel/i387.c | |||
@@ -42,7 +42,7 @@ void mxcsr_feature_mask_init(void) | |||
42 | * Called at bootup to set up the initial FPU state that is later cloned | 42 | * Called at bootup to set up the initial FPU state that is later cloned |
43 | * into all processes. | 43 | * into all processes. |
44 | */ | 44 | */ |
45 | void __init fpu_init(void) | 45 | void __cpuinit fpu_init(void) |
46 | { | 46 | { |
47 | unsigned long oldcr0 = read_cr0(); | 47 | unsigned long oldcr0 = read_cr0(); |
48 | extern void __bad_fxsave_alignment(void); | 48 | extern void __bad_fxsave_alignment(void); |
diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c index 19eafa0aa95c..a89169095129 100644 --- a/arch/x86_64/kernel/i8259.c +++ b/arch/x86_64/kernel/i8259.c | |||
@@ -414,10 +414,22 @@ static int i8259A_suspend(struct sys_device *dev, pm_message_t state) | |||
414 | return 0; | 414 | return 0; |
415 | } | 415 | } |
416 | 416 | ||
417 | static int i8259A_shutdown(struct sys_device *dev) | ||
418 | { | ||
419 | /* Put the i8259A into a quiescent state that | ||
420 | * the kernel initialization code can get it | ||
421 | * out of. | ||
422 | */ | ||
423 | outb(0xff, 0x21); /* mask all of 8259A-1 */ | ||
424 | outb(0xff, 0xA1); /* mask all of 8259A-1 */ | ||
425 | return 0; | ||
426 | } | ||
427 | |||
417 | static struct sysdev_class i8259_sysdev_class = { | 428 | static struct sysdev_class i8259_sysdev_class = { |
418 | set_kset_name("i8259"), | 429 | set_kset_name("i8259"), |
419 | .suspend = i8259A_suspend, | 430 | .suspend = i8259A_suspend, |
420 | .resume = i8259A_resume, | 431 | .resume = i8259A_resume, |
432 | .shutdown = i8259A_shutdown, | ||
421 | }; | 433 | }; |
422 | 434 | ||
423 | static struct sys_device device_i8259A = { | 435 | static struct sys_device device_i8259A = { |
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index afd87e64d0a8..157190d986bb 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c | |||
@@ -330,7 +330,7 @@ static int find_irq_entry(int apic, int pin, int type) | |||
330 | /* | 330 | /* |
331 | * Find the pin to which IRQ[irq] (ISA) is connected | 331 | * Find the pin to which IRQ[irq] (ISA) is connected |
332 | */ | 332 | */ |
333 | static int __init find_isa_irq_pin(int irq, int type) | 333 | static int find_isa_irq_pin(int irq, int type) |
334 | { | 334 | { |
335 | int i; | 335 | int i; |
336 | 336 | ||
@@ -1132,12 +1132,44 @@ static void __init enable_IO_APIC(void) | |||
1132 | */ | 1132 | */ |
1133 | void disable_IO_APIC(void) | 1133 | void disable_IO_APIC(void) |
1134 | { | 1134 | { |
1135 | int pin; | ||
1135 | /* | 1136 | /* |
1136 | * Clear the IO-APIC before rebooting: | 1137 | * Clear the IO-APIC before rebooting: |
1137 | */ | 1138 | */ |
1138 | clear_IO_APIC(); | 1139 | clear_IO_APIC(); |
1139 | 1140 | ||
1140 | disconnect_bsp_APIC(); | 1141 | /* |
1142 | * If the i82559 is routed through an IOAPIC | ||
1143 | * Put that IOAPIC in virtual wire mode | ||
1144 | * so legacy interrups can be delivered. | ||
1145 | */ | ||
1146 | pin = find_isa_irq_pin(0, mp_ExtINT); | ||
1147 | if (pin != -1) { | ||
1148 | struct IO_APIC_route_entry entry; | ||
1149 | unsigned long flags; | ||
1150 | |||
1151 | memset(&entry, 0, sizeof(entry)); | ||
1152 | entry.mask = 0; /* Enabled */ | ||
1153 | entry.trigger = 0; /* Edge */ | ||
1154 | entry.irr = 0; | ||
1155 | entry.polarity = 0; /* High */ | ||
1156 | entry.delivery_status = 0; | ||
1157 | entry.dest_mode = 0; /* Physical */ | ||
1158 | entry.delivery_mode = 7; /* ExtInt */ | ||
1159 | entry.vector = 0; | ||
1160 | entry.dest.physical.physical_dest = 0; | ||
1161 | |||
1162 | |||
1163 | /* | ||
1164 | * Add it to the IO-APIC irq-routing table: | ||
1165 | */ | ||
1166 | spin_lock_irqsave(&ioapic_lock, flags); | ||
1167 | io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1)); | ||
1168 | io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0)); | ||
1169 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
1170 | } | ||
1171 | |||
1172 | disconnect_bsp_APIC(pin != -1); | ||
1141 | } | 1173 | } |
1142 | 1174 | ||
1143 | /* | 1175 | /* |
diff --git a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c index 62b112e4deb4..cc3fb85f5145 100644 --- a/arch/x86_64/kernel/irq.c +++ b/arch/x86_64/kernel/irq.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
15 | #include <linux/seq_file.h> | 15 | #include <linux/seq_file.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/delay.h> | ||
17 | #include <asm/uaccess.h> | 18 | #include <asm/uaccess.h> |
18 | #include <asm/io_apic.h> | 19 | #include <asm/io_apic.h> |
19 | 20 | ||
@@ -106,3 +107,31 @@ asmlinkage unsigned int do_IRQ(struct pt_regs *regs) | |||
106 | return 1; | 107 | return 1; |
107 | } | 108 | } |
108 | 109 | ||
110 | #ifdef CONFIG_HOTPLUG_CPU | ||
111 | void fixup_irqs(cpumask_t map) | ||
112 | { | ||
113 | unsigned int irq; | ||
114 | static int warned; | ||
115 | |||
116 | for (irq = 0; irq < NR_IRQS; irq++) { | ||
117 | cpumask_t mask; | ||
118 | if (irq == 2) | ||
119 | continue; | ||
120 | |||
121 | cpus_and(mask, irq_affinity[irq], map); | ||
122 | if (any_online_cpu(mask) == NR_CPUS) { | ||
123 | printk("Breaking affinity for irq %i\n", irq); | ||
124 | mask = map; | ||
125 | } | ||
126 | if (irq_desc[irq].handler->set_affinity) | ||
127 | irq_desc[irq].handler->set_affinity(irq, mask); | ||
128 | else if (irq_desc[irq].action && !(warned++)) | ||
129 | printk("Cannot set affinity for irq %i\n", irq); | ||
130 | } | ||
131 | |||
132 | /* That doesn't seem sufficient. Give it 1ms. */ | ||
133 | local_irq_enable(); | ||
134 | mdelay(1); | ||
135 | local_irq_disable(); | ||
136 | } | ||
137 | #endif | ||
diff --git a/arch/x86_64/kernel/machine_kexec.c b/arch/x86_64/kernel/machine_kexec.c new file mode 100644 index 000000000000..60d1eff41567 --- /dev/null +++ b/arch/x86_64/kernel/machine_kexec.c | |||
@@ -0,0 +1,250 @@ | |||
1 | /* | ||
2 | * machine_kexec.c - handle transition of Linux booting another kernel | ||
3 | * Copyright (C) 2002-2005 Eric Biederman <ebiederm@xmission.com> | ||
4 | * | ||
5 | * This source code is licensed under the GNU General Public License, | ||
6 | * Version 2. See the file COPYING for more details. | ||
7 | */ | ||
8 | |||
9 | #include <linux/mm.h> | ||
10 | #include <linux/kexec.h> | ||
11 | #include <linux/delay.h> | ||
12 | #include <linux/string.h> | ||
13 | #include <linux/reboot.h> | ||
14 | #include <asm/pda.h> | ||
15 | #include <asm/pgtable.h> | ||
16 | #include <asm/pgalloc.h> | ||
17 | #include <asm/tlbflush.h> | ||
18 | #include <asm/mmu_context.h> | ||
19 | #include <asm/io.h> | ||
20 | #include <asm/apic.h> | ||
21 | #include <asm/cpufeature.h> | ||
22 | #include <asm/hw_irq.h> | ||
23 | |||
24 | #define LEVEL0_SIZE (1UL << 12UL) | ||
25 | #define LEVEL1_SIZE (1UL << 21UL) | ||
26 | #define LEVEL2_SIZE (1UL << 30UL) | ||
27 | #define LEVEL3_SIZE (1UL << 39UL) | ||
28 | #define LEVEL4_SIZE (1UL << 48UL) | ||
29 | |||
30 | #define L0_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) | ||
31 | #define L1_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_PSE) | ||
32 | #define L2_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) | ||
33 | #define L3_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) | ||
34 | |||
35 | static void init_level2_page(u64 *level2p, unsigned long addr) | ||
36 | { | ||
37 | unsigned long end_addr; | ||
38 | |||
39 | addr &= PAGE_MASK; | ||
40 | end_addr = addr + LEVEL2_SIZE; | ||
41 | while (addr < end_addr) { | ||
42 | *(level2p++) = addr | L1_ATTR; | ||
43 | addr += LEVEL1_SIZE; | ||
44 | } | ||
45 | } | ||
46 | |||
47 | static int init_level3_page(struct kimage *image, u64 *level3p, | ||
48 | unsigned long addr, unsigned long last_addr) | ||
49 | { | ||
50 | unsigned long end_addr; | ||
51 | int result; | ||
52 | |||
53 | result = 0; | ||
54 | addr &= PAGE_MASK; | ||
55 | end_addr = addr + LEVEL3_SIZE; | ||
56 | while ((addr < last_addr) && (addr < end_addr)) { | ||
57 | struct page *page; | ||
58 | u64 *level2p; | ||
59 | |||
60 | page = kimage_alloc_control_pages(image, 0); | ||
61 | if (!page) { | ||
62 | result = -ENOMEM; | ||
63 | goto out; | ||
64 | } | ||
65 | level2p = (u64 *)page_address(page); | ||
66 | init_level2_page(level2p, addr); | ||
67 | *(level3p++) = __pa(level2p) | L2_ATTR; | ||
68 | addr += LEVEL2_SIZE; | ||
69 | } | ||
70 | /* clear the unused entries */ | ||
71 | while (addr < end_addr) { | ||
72 | *(level3p++) = 0; | ||
73 | addr += LEVEL2_SIZE; | ||
74 | } | ||
75 | out: | ||
76 | return result; | ||
77 | } | ||
78 | |||
79 | |||
80 | static int init_level4_page(struct kimage *image, u64 *level4p, | ||
81 | unsigned long addr, unsigned long last_addr) | ||
82 | { | ||
83 | unsigned long end_addr; | ||
84 | int result; | ||
85 | |||
86 | result = 0; | ||
87 | addr &= PAGE_MASK; | ||
88 | end_addr = addr + LEVEL4_SIZE; | ||
89 | while ((addr < last_addr) && (addr < end_addr)) { | ||
90 | struct page *page; | ||
91 | u64 *level3p; | ||
92 | |||
93 | page = kimage_alloc_control_pages(image, 0); | ||
94 | if (!page) { | ||
95 | result = -ENOMEM; | ||
96 | goto out; | ||
97 | } | ||
98 | level3p = (u64 *)page_address(page); | ||
99 | result = init_level3_page(image, level3p, addr, last_addr); | ||
100 | if (result) { | ||
101 | goto out; | ||
102 | } | ||
103 | *(level4p++) = __pa(level3p) | L3_ATTR; | ||
104 | addr += LEVEL3_SIZE; | ||
105 | } | ||
106 | /* clear the unused entries */ | ||
107 | while (addr < end_addr) { | ||
108 | *(level4p++) = 0; | ||
109 | addr += LEVEL3_SIZE; | ||
110 | } | ||
111 | out: | ||
112 | return result; | ||
113 | } | ||
114 | |||
115 | |||
116 | static int init_pgtable(struct kimage *image, unsigned long start_pgtable) | ||
117 | { | ||
118 | u64 *level4p; | ||
119 | level4p = (u64 *)__va(start_pgtable); | ||
120 | return init_level4_page(image, level4p, 0, end_pfn << PAGE_SHIFT); | ||
121 | } | ||
122 | |||
123 | static void set_idt(void *newidt, u16 limit) | ||
124 | { | ||
125 | unsigned char curidt[10]; | ||
126 | |||
127 | /* x86-64 supports unaliged loads & stores */ | ||
128 | (*(u16 *)(curidt)) = limit; | ||
129 | (*(u64 *)(curidt +2)) = (unsigned long)(newidt); | ||
130 | |||
131 | __asm__ __volatile__ ( | ||
132 | "lidt %0\n" | ||
133 | : "=m" (curidt) | ||
134 | ); | ||
135 | }; | ||
136 | |||
137 | |||
138 | static void set_gdt(void *newgdt, u16 limit) | ||
139 | { | ||
140 | unsigned char curgdt[10]; | ||
141 | |||
142 | /* x86-64 supports unaligned loads & stores */ | ||
143 | (*(u16 *)(curgdt)) = limit; | ||
144 | (*(u64 *)(curgdt +2)) = (unsigned long)(newgdt); | ||
145 | |||
146 | __asm__ __volatile__ ( | ||
147 | "lgdt %0\n" | ||
148 | : "=m" (curgdt) | ||
149 | ); | ||
150 | }; | ||
151 | |||
152 | static void load_segments(void) | ||
153 | { | ||
154 | __asm__ __volatile__ ( | ||
155 | "\tmovl $"STR(__KERNEL_DS)",%eax\n" | ||
156 | "\tmovl %eax,%ds\n" | ||
157 | "\tmovl %eax,%es\n" | ||
158 | "\tmovl %eax,%ss\n" | ||
159 | "\tmovl %eax,%fs\n" | ||
160 | "\tmovl %eax,%gs\n" | ||
161 | ); | ||
162 | #undef STR | ||
163 | #undef __STR | ||
164 | } | ||
165 | |||
166 | typedef NORET_TYPE void (*relocate_new_kernel_t)(unsigned long indirection_page, | ||
167 | unsigned long control_code_buffer, | ||
168 | unsigned long start_address, | ||
169 | unsigned long pgtable) ATTRIB_NORET; | ||
170 | |||
171 | const extern unsigned char relocate_new_kernel[]; | ||
172 | const extern unsigned long relocate_new_kernel_size; | ||
173 | |||
174 | int machine_kexec_prepare(struct kimage *image) | ||
175 | { | ||
176 | unsigned long start_pgtable, control_code_buffer; | ||
177 | int result; | ||
178 | |||
179 | /* Calculate the offsets */ | ||
180 | start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT; | ||
181 | control_code_buffer = start_pgtable + 4096UL; | ||
182 | |||
183 | /* Setup the identity mapped 64bit page table */ | ||
184 | result = init_pgtable(image, start_pgtable); | ||
185 | if (result) | ||
186 | return result; | ||
187 | |||
188 | /* Place the code in the reboot code buffer */ | ||
189 | memcpy(__va(control_code_buffer), relocate_new_kernel, | ||
190 | relocate_new_kernel_size); | ||
191 | |||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | void machine_kexec_cleanup(struct kimage *image) | ||
196 | { | ||
197 | return; | ||
198 | } | ||
199 | |||
200 | /* | ||
201 | * Do not allocate memory (or fail in any way) in machine_kexec(). | ||
202 | * We are past the point of no return, committed to rebooting now. | ||
203 | */ | ||
204 | NORET_TYPE void machine_kexec(struct kimage *image) | ||
205 | { | ||
206 | unsigned long page_list; | ||
207 | unsigned long control_code_buffer; | ||
208 | unsigned long start_pgtable; | ||
209 | relocate_new_kernel_t rnk; | ||
210 | |||
211 | /* Interrupts aren't acceptable while we reboot */ | ||
212 | local_irq_disable(); | ||
213 | |||
214 | /* Calculate the offsets */ | ||
215 | page_list = image->head; | ||
216 | start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT; | ||
217 | control_code_buffer = start_pgtable + 4096UL; | ||
218 | |||
219 | /* Set the low half of the page table to my identity mapped | ||
220 | * page table for kexec. Leave the high half pointing at the | ||
221 | * kernel pages. Don't bother to flush the global pages | ||
222 | * as that will happen when I fully switch to my identity mapped | ||
223 | * page table anyway. | ||
224 | */ | ||
225 | memcpy(__va(read_cr3()), __va(start_pgtable), PAGE_SIZE/2); | ||
226 | __flush_tlb(); | ||
227 | |||
228 | |||
229 | /* The segment registers are funny things, they are | ||
230 | * automatically loaded from a table, in memory wherever you | ||
231 | * set them to a specific selector, but this table is never | ||
232 | * accessed again unless you set the segment to a different selector. | ||
233 | * | ||
234 | * The more common model are caches where the behide | ||
235 | * the scenes work is done, but is also dropped at arbitrary | ||
236 | * times. | ||
237 | * | ||
238 | * I take advantage of this here by force loading the | ||
239 | * segments, before I zap the gdt with an invalid value. | ||
240 | */ | ||
241 | load_segments(); | ||
242 | /* The gdt & idt are now invalid. | ||
243 | * If you want to load them you must set up your own idt & gdt. | ||
244 | */ | ||
245 | set_gdt(phys_to_virt(0),0); | ||
246 | set_idt(phys_to_virt(0),0); | ||
247 | /* now call it */ | ||
248 | rnk = (relocate_new_kernel_t) control_code_buffer; | ||
249 | (*rnk)(page_list, control_code_buffer, image->start, start_pgtable); | ||
250 | } | ||
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c index 3a89d735a4f6..21e70625a495 100644 --- a/arch/x86_64/kernel/mce.c +++ b/arch/x86_64/kernel/mce.c | |||
@@ -327,7 +327,7 @@ static void mce_init(void *dummy) | |||
327 | } | 327 | } |
328 | 328 | ||
329 | /* Add per CPU specific workarounds here */ | 329 | /* Add per CPU specific workarounds here */ |
330 | static void __init mce_cpu_quirks(struct cpuinfo_x86 *c) | 330 | static void __cpuinit mce_cpu_quirks(struct cpuinfo_x86 *c) |
331 | { | 331 | { |
332 | /* This should be disabled by the BIOS, but isn't always */ | 332 | /* This should be disabled by the BIOS, but isn't always */ |
333 | if (c->x86_vendor == X86_VENDOR_AMD && c->x86 == 15) { | 333 | if (c->x86_vendor == X86_VENDOR_AMD && c->x86 == 15) { |
@@ -337,7 +337,7 @@ static void __init mce_cpu_quirks(struct cpuinfo_x86 *c) | |||
337 | } | 337 | } |
338 | } | 338 | } |
339 | 339 | ||
340 | static void __init mce_cpu_features(struct cpuinfo_x86 *c) | 340 | static void __cpuinit mce_cpu_features(struct cpuinfo_x86 *c) |
341 | { | 341 | { |
342 | switch (c->x86_vendor) { | 342 | switch (c->x86_vendor) { |
343 | case X86_VENDOR_INTEL: | 343 | case X86_VENDOR_INTEL: |
@@ -352,7 +352,7 @@ static void __init mce_cpu_features(struct cpuinfo_x86 *c) | |||
352 | * Called for each booted CPU to set up machine checks. | 352 | * Called for each booted CPU to set up machine checks. |
353 | * Must be called with preempt off. | 353 | * Must be called with preempt off. |
354 | */ | 354 | */ |
355 | void __init mcheck_init(struct cpuinfo_x86 *c) | 355 | void __cpuinit mcheck_init(struct cpuinfo_x86 *c) |
356 | { | 356 | { |
357 | static cpumask_t mce_cpus __initdata = CPU_MASK_NONE; | 357 | static cpumask_t mce_cpus __initdata = CPU_MASK_NONE; |
358 | 358 | ||
@@ -411,7 +411,7 @@ static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, loff | |||
411 | memset(mcelog.entry, 0, next * sizeof(struct mce)); | 411 | memset(mcelog.entry, 0, next * sizeof(struct mce)); |
412 | mcelog.next = 0; | 412 | mcelog.next = 0; |
413 | 413 | ||
414 | synchronize_kernel(); | 414 | synchronize_sched(); |
415 | 415 | ||
416 | /* Collect entries that were still getting written before the synchronize. */ | 416 | /* Collect entries that were still getting written before the synchronize. */ |
417 | 417 | ||
@@ -542,7 +542,7 @@ ACCESSOR(bank4ctl,bank[4],mce_restart()) | |||
542 | ACCESSOR(tolerant,tolerant,) | 542 | ACCESSOR(tolerant,tolerant,) |
543 | ACCESSOR(check_interval,check_interval,mce_restart()) | 543 | ACCESSOR(check_interval,check_interval,mce_restart()) |
544 | 544 | ||
545 | static __init int mce_init_device(void) | 545 | static __cpuinit int mce_init_device(void) |
546 | { | 546 | { |
547 | int err; | 547 | int err; |
548 | if (!mce_available(&boot_cpu_data)) | 548 | if (!mce_available(&boot_cpu_data)) |
diff --git a/arch/x86_64/kernel/mce_intel.c b/arch/x86_64/kernel/mce_intel.c index 4db9a640069f..0be0a7959814 100644 --- a/arch/x86_64/kernel/mce_intel.c +++ b/arch/x86_64/kernel/mce_intel.c | |||
@@ -42,7 +42,7 @@ done: | |||
42 | irq_exit(); | 42 | irq_exit(); |
43 | } | 43 | } |
44 | 44 | ||
45 | static void __init intel_init_thermal(struct cpuinfo_x86 *c) | 45 | static void __cpuinit intel_init_thermal(struct cpuinfo_x86 *c) |
46 | { | 46 | { |
47 | u32 l, h; | 47 | u32 l, h; |
48 | int tm2 = 0; | 48 | int tm2 = 0; |
@@ -93,7 +93,7 @@ static void __init intel_init_thermal(struct cpuinfo_x86 *c) | |||
93 | return; | 93 | return; |
94 | } | 94 | } |
95 | 95 | ||
96 | void __init mce_intel_feature_init(struct cpuinfo_x86 *c) | 96 | void __cpuinit mce_intel_feature_init(struct cpuinfo_x86 *c) |
97 | { | 97 | { |
98 | intel_init_thermal(c); | 98 | intel_init_thermal(c); |
99 | } | 99 | } |
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c index 31c0f2e6ac91..4e44d6e6b7e5 100644 --- a/arch/x86_64/kernel/nmi.c +++ b/arch/x86_64/kernel/nmi.c | |||
@@ -98,7 +98,7 @@ static unsigned int nmi_p4_cccr_val; | |||
98 | (P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \ | 98 | (P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \ |
99 | P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE) | 99 | P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE) |
100 | 100 | ||
101 | static __init inline int nmi_known_cpu(void) | 101 | static __cpuinit inline int nmi_known_cpu(void) |
102 | { | 102 | { |
103 | switch (boot_cpu_data.x86_vendor) { | 103 | switch (boot_cpu_data.x86_vendor) { |
104 | case X86_VENDOR_AMD: | 104 | case X86_VENDOR_AMD: |
@@ -110,7 +110,7 @@ static __init inline int nmi_known_cpu(void) | |||
110 | } | 110 | } |
111 | 111 | ||
112 | /* Run after command line and cpu_init init, but before all other checks */ | 112 | /* Run after command line and cpu_init init, but before all other checks */ |
113 | void __init nmi_watchdog_default(void) | 113 | void __cpuinit nmi_watchdog_default(void) |
114 | { | 114 | { |
115 | if (nmi_watchdog != NMI_DEFAULT) | 115 | if (nmi_watchdog != NMI_DEFAULT) |
116 | return; | 116 | return; |
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index e59d1f9d6163..1d91271796e5 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c | |||
@@ -8,7 +8,8 @@ | |||
8 | * | 8 | * |
9 | * X86-64 port | 9 | * X86-64 port |
10 | * Andi Kleen. | 10 | * Andi Kleen. |
11 | * | 11 | * |
12 | * CPU hotplug support - ashok.raj@intel.com | ||
12 | * $Id: process.c,v 1.38 2002/01/15 10:08:03 ak Exp $ | 13 | * $Id: process.c,v 1.38 2002/01/15 10:08:03 ak Exp $ |
13 | */ | 14 | */ |
14 | 15 | ||
@@ -18,6 +19,7 @@ | |||
18 | 19 | ||
19 | #include <stdarg.h> | 20 | #include <stdarg.h> |
20 | 21 | ||
22 | #include <linux/cpu.h> | ||
21 | #include <linux/errno.h> | 23 | #include <linux/errno.h> |
22 | #include <linux/sched.h> | 24 | #include <linux/sched.h> |
23 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
@@ -154,6 +156,29 @@ void cpu_idle_wait(void) | |||
154 | } | 156 | } |
155 | EXPORT_SYMBOL_GPL(cpu_idle_wait); | 157 | EXPORT_SYMBOL_GPL(cpu_idle_wait); |
156 | 158 | ||
159 | #ifdef CONFIG_HOTPLUG_CPU | ||
160 | DECLARE_PER_CPU(int, cpu_state); | ||
161 | |||
162 | #include <asm/nmi.h> | ||
163 | /* We don't actually take CPU down, just spin without interrupts. */ | ||
164 | static inline void play_dead(void) | ||
165 | { | ||
166 | idle_task_exit(); | ||
167 | wbinvd(); | ||
168 | mb(); | ||
169 | /* Ack it */ | ||
170 | __get_cpu_var(cpu_state) = CPU_DEAD; | ||
171 | |||
172 | while (1) | ||
173 | safe_halt(); | ||
174 | } | ||
175 | #else | ||
176 | static inline void play_dead(void) | ||
177 | { | ||
178 | BUG(); | ||
179 | } | ||
180 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
181 | |||
157 | /* | 182 | /* |
158 | * The idle thread. There's no useful work to be | 183 | * The idle thread. There's no useful work to be |
159 | * done, so just try to conserve power and have a | 184 | * done, so just try to conserve power and have a |
@@ -174,6 +199,8 @@ void cpu_idle (void) | |||
174 | idle = pm_idle; | 199 | idle = pm_idle; |
175 | if (!idle) | 200 | if (!idle) |
176 | idle = default_idle; | 201 | idle = default_idle; |
202 | if (cpu_is_offline(smp_processor_id())) | ||
203 | play_dead(); | ||
177 | idle(); | 204 | idle(); |
178 | } | 205 | } |
179 | 206 | ||
@@ -204,7 +231,7 @@ static void mwait_idle(void) | |||
204 | } | 231 | } |
205 | } | 232 | } |
206 | 233 | ||
207 | void __init select_idle_routine(const struct cpuinfo_x86 *c) | 234 | void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) |
208 | { | 235 | { |
209 | static int printed; | 236 | static int printed; |
210 | if (cpu_has(c, X86_FEATURE_MWAIT)) { | 237 | if (cpu_has(c, X86_FEATURE_MWAIT)) { |
diff --git a/arch/x86_64/kernel/reboot.c b/arch/x86_64/kernel/reboot.c index be4b36f762cf..57e71dbdfd69 100644 --- a/arch/x86_64/kernel/reboot.c +++ b/arch/x86_64/kernel/reboot.c | |||
@@ -66,41 +66,47 @@ static int __init reboot_setup(char *str) | |||
66 | 66 | ||
67 | __setup("reboot=", reboot_setup); | 67 | __setup("reboot=", reboot_setup); |
68 | 68 | ||
69 | #ifdef CONFIG_SMP | 69 | static inline void kb_wait(void) |
70 | static void smp_halt(void) | ||
71 | { | 70 | { |
72 | int cpuid = safe_smp_processor_id(); | 71 | int i; |
73 | static int first_entry = 1; | ||
74 | 72 | ||
75 | if (reboot_force) | 73 | for (i=0; i<0x10000; i++) |
76 | return; | 74 | if ((inb_p(0x64) & 0x02) == 0) |
75 | break; | ||
76 | } | ||
77 | 77 | ||
78 | if (first_entry) { | 78 | void machine_shutdown(void) |
79 | first_entry = 0; | 79 | { |
80 | smp_call_function((void *)machine_restart, NULL, 1, 0); | 80 | /* Stop the cpus and apics */ |
81 | } | 81 | #ifdef CONFIG_SMP |
82 | 82 | int reboot_cpu_id; | |
83 | smp_stop_cpu(); | ||
84 | 83 | ||
85 | /* AP calling this. Just halt */ | 84 | /* The boot cpu is always logical cpu 0 */ |
86 | if (cpuid != boot_cpu_id) { | 85 | reboot_cpu_id = 0; |
87 | for (;;) | 86 | |
88 | asm("hlt"); | 87 | /* Make certain the cpu I'm about to reboot on is online */ |
88 | if (!cpu_isset(reboot_cpu_id, cpu_online_map)) { | ||
89 | reboot_cpu_id = smp_processor_id(); | ||
89 | } | 90 | } |
90 | 91 | ||
91 | /* Wait for all other CPUs to have run smp_stop_cpu */ | 92 | /* Make certain I only run on the appropriate processor */ |
92 | while (!cpus_empty(cpu_online_map)) | 93 | set_cpus_allowed(current, cpumask_of_cpu(reboot_cpu_id)); |
93 | rep_nop(); | 94 | |
94 | } | 95 | /* O.K Now that I'm on the appropriate processor, |
96 | * stop all of the others. | ||
97 | */ | ||
98 | smp_send_stop(); | ||
95 | #endif | 99 | #endif |
96 | 100 | ||
97 | static inline void kb_wait(void) | 101 | local_irq_disable(); |
98 | { | ||
99 | int i; | ||
100 | 102 | ||
101 | for (i=0; i<0x10000; i++) | 103 | #ifndef CONFIG_SMP |
102 | if ((inb_p(0x64) & 0x02) == 0) | 104 | disable_local_APIC(); |
103 | break; | 105 | #endif |
106 | |||
107 | disable_IO_APIC(); | ||
108 | |||
109 | local_irq_enable(); | ||
104 | } | 110 | } |
105 | 111 | ||
106 | void machine_restart(char * __unused) | 112 | void machine_restart(char * __unused) |
@@ -109,9 +115,7 @@ void machine_restart(char * __unused) | |||
109 | 115 | ||
110 | printk("machine restart\n"); | 116 | printk("machine restart\n"); |
111 | 117 | ||
112 | #ifdef CONFIG_SMP | 118 | machine_shutdown(); |
113 | smp_halt(); | ||
114 | #endif | ||
115 | 119 | ||
116 | if (!reboot_force) { | 120 | if (!reboot_force) { |
117 | local_irq_disable(); | 121 | local_irq_disable(); |
diff --git a/arch/x86_64/kernel/relocate_kernel.S b/arch/x86_64/kernel/relocate_kernel.S new file mode 100644 index 000000000000..d24fa9b72a2b --- /dev/null +++ b/arch/x86_64/kernel/relocate_kernel.S | |||
@@ -0,0 +1,143 @@ | |||
1 | /* | ||
2 | * relocate_kernel.S - put the kernel image in place to boot | ||
3 | * Copyright (C) 2002-2005 Eric Biederman <ebiederm@xmission.com> | ||
4 | * | ||
5 | * This source code is licensed under the GNU General Public License, | ||
6 | * Version 2. See the file COPYING for more details. | ||
7 | */ | ||
8 | |||
9 | #include <linux/linkage.h> | ||
10 | |||
11 | /* | ||
12 | * Must be relocatable PIC code callable as a C function, that once | ||
13 | * it starts can not use the previous processes stack. | ||
14 | */ | ||
15 | .globl relocate_new_kernel | ||
16 | .code64 | ||
17 | relocate_new_kernel: | ||
18 | /* %rdi page_list | ||
19 | * %rsi reboot_code_buffer | ||
20 | * %rdx start address | ||
21 | * %rcx page_table | ||
22 | * %r8 arg5 | ||
23 | * %r9 arg6 | ||
24 | */ | ||
25 | |||
26 | /* zero out flags, and disable interrupts */ | ||
27 | pushq $0 | ||
28 | popfq | ||
29 | |||
30 | /* set a new stack at the bottom of our page... */ | ||
31 | lea 4096(%rsi), %rsp | ||
32 | |||
33 | /* store the parameters back on the stack */ | ||
34 | pushq %rdx /* store the start address */ | ||
35 | |||
36 | /* Set cr0 to a known state: | ||
37 | * 31 1 == Paging enabled | ||
38 | * 18 0 == Alignment check disabled | ||
39 | * 16 0 == Write protect disabled | ||
40 | * 3 0 == No task switch | ||
41 | * 2 0 == Don't do FP software emulation. | ||
42 | * 0 1 == Proctected mode enabled | ||
43 | */ | ||
44 | movq %cr0, %rax | ||
45 | andq $~((1<<18)|(1<<16)|(1<<3)|(1<<2)), %rax | ||
46 | orl $((1<<31)|(1<<0)), %eax | ||
47 | movq %rax, %cr0 | ||
48 | |||
49 | /* Set cr4 to a known state: | ||
50 | * 10 0 == xmm exceptions disabled | ||
51 | * 9 0 == xmm registers instructions disabled | ||
52 | * 8 0 == performance monitoring counter disabled | ||
53 | * 7 0 == page global disabled | ||
54 | * 6 0 == machine check exceptions disabled | ||
55 | * 5 1 == physical address extension enabled | ||
56 | * 4 0 == page size extensions disabled | ||
57 | * 3 0 == Debug extensions disabled | ||
58 | * 2 0 == Time stamp disable (disabled) | ||
59 | * 1 0 == Protected mode virtual interrupts disabled | ||
60 | * 0 0 == VME disabled | ||
61 | */ | ||
62 | |||
63 | movq $((1<<5)), %rax | ||
64 | movq %rax, %cr4 | ||
65 | |||
66 | jmp 1f | ||
67 | 1: | ||
68 | |||
69 | /* Switch to the identity mapped page tables, | ||
70 | * and flush the TLB. | ||
71 | */ | ||
72 | movq %rcx, %cr3 | ||
73 | |||
74 | /* Do the copies */ | ||
75 | movq %rdi, %rcx /* Put the page_list in %rcx */ | ||
76 | xorq %rdi, %rdi | ||
77 | xorq %rsi, %rsi | ||
78 | jmp 1f | ||
79 | |||
80 | 0: /* top, read another word for the indirection page */ | ||
81 | |||
82 | movq (%rbx), %rcx | ||
83 | addq $8, %rbx | ||
84 | 1: | ||
85 | testq $0x1, %rcx /* is it a destination page? */ | ||
86 | jz 2f | ||
87 | movq %rcx, %rdi | ||
88 | andq $0xfffffffffffff000, %rdi | ||
89 | jmp 0b | ||
90 | 2: | ||
91 | testq $0x2, %rcx /* is it an indirection page? */ | ||
92 | jz 2f | ||
93 | movq %rcx, %rbx | ||
94 | andq $0xfffffffffffff000, %rbx | ||
95 | jmp 0b | ||
96 | 2: | ||
97 | testq $0x4, %rcx /* is it the done indicator? */ | ||
98 | jz 2f | ||
99 | jmp 3f | ||
100 | 2: | ||
101 | testq $0x8, %rcx /* is it the source indicator? */ | ||
102 | jz 0b /* Ignore it otherwise */ | ||
103 | movq %rcx, %rsi /* For ever source page do a copy */ | ||
104 | andq $0xfffffffffffff000, %rsi | ||
105 | |||
106 | movq $512, %rcx | ||
107 | rep ; movsq | ||
108 | jmp 0b | ||
109 | 3: | ||
110 | |||
111 | /* To be certain of avoiding problems with self-modifying code | ||
112 | * I need to execute a serializing instruction here. | ||
113 | * So I flush the TLB by reloading %cr3 here, it's handy, | ||
114 | * and not processor dependent. | ||
115 | */ | ||
116 | movq %cr3, %rax | ||
117 | movq %rax, %cr3 | ||
118 | |||
119 | /* set all of the registers to known values */ | ||
120 | /* leave %rsp alone */ | ||
121 | |||
122 | xorq %rax, %rax | ||
123 | xorq %rbx, %rbx | ||
124 | xorq %rcx, %rcx | ||
125 | xorq %rdx, %rdx | ||
126 | xorq %rsi, %rsi | ||
127 | xorq %rdi, %rdi | ||
128 | xorq %rbp, %rbp | ||
129 | xorq %r8, %r8 | ||
130 | xorq %r9, %r9 | ||
131 | xorq %r10, %r9 | ||
132 | xorq %r11, %r11 | ||
133 | xorq %r12, %r12 | ||
134 | xorq %r13, %r13 | ||
135 | xorq %r14, %r14 | ||
136 | xorq %r15, %r15 | ||
137 | |||
138 | ret | ||
139 | relocate_new_kernel_end: | ||
140 | |||
141 | .globl relocate_new_kernel_size | ||
142 | relocate_new_kernel_size: | ||
143 | .quad relocate_new_kernel_end - relocate_new_kernel | ||
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 000015dd5a8b..b02d921da4f7 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/kallsyms.h> | 41 | #include <linux/kallsyms.h> |
42 | #include <linux/edd.h> | 42 | #include <linux/edd.h> |
43 | #include <linux/mmzone.h> | 43 | #include <linux/mmzone.h> |
44 | #include <linux/kexec.h> | ||
44 | 45 | ||
45 | #include <asm/mtrr.h> | 46 | #include <asm/mtrr.h> |
46 | #include <asm/uaccess.h> | 47 | #include <asm/uaccess.h> |
@@ -367,6 +368,27 @@ static __init void parse_cmdline_early (char ** cmdline_p) | |||
367 | if (!memcmp(from, "noexec=", 7)) | 368 | if (!memcmp(from, "noexec=", 7)) |
368 | nonx_setup(from + 7); | 369 | nonx_setup(from + 7); |
369 | 370 | ||
371 | #ifdef CONFIG_KEXEC | ||
372 | /* crashkernel=size@addr specifies the location to reserve for | ||
373 | * a crash kernel. By reserving this memory we guarantee | ||
374 | * that linux never set's it up as a DMA target. | ||
375 | * Useful for holding code to do something appropriate | ||
376 | * after a kernel panic. | ||
377 | */ | ||
378 | else if (!memcmp(from, "crashkernel=", 12)) { | ||
379 | unsigned long size, base; | ||
380 | size = memparse(from+12, &from); | ||
381 | if (*from == '@') { | ||
382 | base = memparse(from+1, &from); | ||
383 | /* FIXME: Do I want a sanity check | ||
384 | * to validate the memory range? | ||
385 | */ | ||
386 | crashk_res.start = base; | ||
387 | crashk_res.end = base + size - 1; | ||
388 | } | ||
389 | } | ||
390 | #endif | ||
391 | |||
370 | next_char: | 392 | next_char: |
371 | c = *(from++); | 393 | c = *(from++); |
372 | if (!c) | 394 | if (!c) |
@@ -625,6 +647,13 @@ void __init setup_arch(char **cmdline_p) | |||
625 | #endif | 647 | #endif |
626 | 648 | ||
627 | sparse_init(); | 649 | sparse_init(); |
650 | |||
651 | #ifdef CONFIG_KEXEC | ||
652 | if (crashk_res.start != crashk_res.end) { | ||
653 | reserve_bootmem(crashk_res.start, | ||
654 | crashk_res.end - crashk_res.start + 1); | ||
655 | } | ||
656 | #endif | ||
628 | paging_init(); | 657 | paging_init(); |
629 | 658 | ||
630 | check_ioapic(); | 659 | check_ioapic(); |
@@ -676,7 +705,7 @@ void __init setup_arch(char **cmdline_p) | |||
676 | #endif | 705 | #endif |
677 | } | 706 | } |
678 | 707 | ||
679 | static int __init get_model_name(struct cpuinfo_x86 *c) | 708 | static int __cpuinit get_model_name(struct cpuinfo_x86 *c) |
680 | { | 709 | { |
681 | unsigned int *v; | 710 | unsigned int *v; |
682 | 711 | ||
@@ -692,7 +721,7 @@ static int __init get_model_name(struct cpuinfo_x86 *c) | |||
692 | } | 721 | } |
693 | 722 | ||
694 | 723 | ||
695 | static void __init display_cacheinfo(struct cpuinfo_x86 *c) | 724 | static void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c) |
696 | { | 725 | { |
697 | unsigned int n, dummy, eax, ebx, ecx, edx; | 726 | unsigned int n, dummy, eax, ebx, ecx, edx; |
698 | 727 | ||
@@ -803,7 +832,7 @@ static int __init init_amd(struct cpuinfo_x86 *c) | |||
803 | return r; | 832 | return r; |
804 | } | 833 | } |
805 | 834 | ||
806 | static void __init detect_ht(struct cpuinfo_x86 *c) | 835 | static void __cpuinit detect_ht(struct cpuinfo_x86 *c) |
807 | { | 836 | { |
808 | #ifdef CONFIG_SMP | 837 | #ifdef CONFIG_SMP |
809 | u32 eax, ebx, ecx, edx; | 838 | u32 eax, ebx, ecx, edx; |
@@ -864,7 +893,7 @@ static void __init detect_ht(struct cpuinfo_x86 *c) | |||
864 | /* | 893 | /* |
865 | * find out the number of processor cores on the die | 894 | * find out the number of processor cores on the die |
866 | */ | 895 | */ |
867 | static int __init intel_num_cpu_cores(struct cpuinfo_x86 *c) | 896 | static int __cpuinit intel_num_cpu_cores(struct cpuinfo_x86 *c) |
868 | { | 897 | { |
869 | unsigned int eax; | 898 | unsigned int eax; |
870 | 899 | ||
@@ -882,7 +911,7 @@ static int __init intel_num_cpu_cores(struct cpuinfo_x86 *c) | |||
882 | return 1; | 911 | return 1; |
883 | } | 912 | } |
884 | 913 | ||
885 | static void __init init_intel(struct cpuinfo_x86 *c) | 914 | static void __cpuinit init_intel(struct cpuinfo_x86 *c) |
886 | { | 915 | { |
887 | /* Cache sizes */ | 916 | /* Cache sizes */ |
888 | unsigned n; | 917 | unsigned n; |
@@ -902,7 +931,7 @@ static void __init init_intel(struct cpuinfo_x86 *c) | |||
902 | c->x86_num_cores = intel_num_cpu_cores(c); | 931 | c->x86_num_cores = intel_num_cpu_cores(c); |
903 | } | 932 | } |
904 | 933 | ||
905 | void __init get_cpu_vendor(struct cpuinfo_x86 *c) | 934 | void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c) |
906 | { | 935 | { |
907 | char *v = c->x86_vendor_id; | 936 | char *v = c->x86_vendor_id; |
908 | 937 | ||
@@ -923,7 +952,7 @@ struct cpu_model_info { | |||
923 | /* Do some early cpuid on the boot CPU to get some parameter that are | 952 | /* Do some early cpuid on the boot CPU to get some parameter that are |
924 | needed before check_bugs. Everything advanced is in identify_cpu | 953 | needed before check_bugs. Everything advanced is in identify_cpu |
925 | below. */ | 954 | below. */ |
926 | void __init early_identify_cpu(struct cpuinfo_x86 *c) | 955 | void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c) |
927 | { | 956 | { |
928 | u32 tfms; | 957 | u32 tfms; |
929 | 958 | ||
@@ -977,7 +1006,7 @@ void __init early_identify_cpu(struct cpuinfo_x86 *c) | |||
977 | /* | 1006 | /* |
978 | * This does the hard work of actually picking apart the CPU stuff... | 1007 | * This does the hard work of actually picking apart the CPU stuff... |
979 | */ | 1008 | */ |
980 | void __init identify_cpu(struct cpuinfo_x86 *c) | 1009 | void __cpuinit identify_cpu(struct cpuinfo_x86 *c) |
981 | { | 1010 | { |
982 | int i; | 1011 | int i; |
983 | u32 xlvl; | 1012 | u32 xlvl; |
@@ -1054,7 +1083,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c) | |||
1054 | } | 1083 | } |
1055 | 1084 | ||
1056 | 1085 | ||
1057 | void __init print_cpu_info(struct cpuinfo_x86 *c) | 1086 | void __cpuinit print_cpu_info(struct cpuinfo_x86 *c) |
1058 | { | 1087 | { |
1059 | if (c->x86_model_id[0]) | 1088 | if (c->x86_model_id[0]) |
1060 | printk("%s", c->x86_model_id); | 1089 | printk("%s", c->x86_model_id); |
diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c index 678b7ac33b8b..f2b9c6bc999a 100644 --- a/arch/x86_64/kernel/setup64.c +++ b/arch/x86_64/kernel/setup64.c | |||
@@ -29,7 +29,7 @@ | |||
29 | 29 | ||
30 | char x86_boot_params[BOOT_PARAM_SIZE] __initdata = {0,}; | 30 | char x86_boot_params[BOOT_PARAM_SIZE] __initdata = {0,}; |
31 | 31 | ||
32 | cpumask_t cpu_initialized __initdata = CPU_MASK_NONE; | 32 | cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE; |
33 | 33 | ||
34 | struct x8664_pda cpu_pda[NR_CPUS] __cacheline_aligned; | 34 | struct x8664_pda cpu_pda[NR_CPUS] __cacheline_aligned; |
35 | 35 | ||
@@ -171,7 +171,7 @@ void syscall_init(void) | |||
171 | wrmsrl(MSR_SYSCALL_MASK, EF_TF|EF_DF|EF_IE|0x3000); | 171 | wrmsrl(MSR_SYSCALL_MASK, EF_TF|EF_DF|EF_IE|0x3000); |
172 | } | 172 | } |
173 | 173 | ||
174 | void __init check_efer(void) | 174 | void __cpuinit check_efer(void) |
175 | { | 175 | { |
176 | unsigned long efer; | 176 | unsigned long efer; |
177 | 177 | ||
@@ -188,7 +188,7 @@ void __init check_efer(void) | |||
188 | * 'CPU state barrier', nothing should get across. | 188 | * 'CPU state barrier', nothing should get across. |
189 | * A lot of state is already set up in PDA init. | 189 | * A lot of state is already set up in PDA init. |
190 | */ | 190 | */ |
191 | void __init cpu_init (void) | 191 | void __cpuinit cpu_init (void) |
192 | { | 192 | { |
193 | #ifdef CONFIG_SMP | 193 | #ifdef CONFIG_SMP |
194 | int cpu = stack_smp_processor_id(); | 194 | int cpu = stack_smp_processor_id(); |
diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c index 1e379ed17b1d..ccae392886af 100644 --- a/arch/x86_64/kernel/smp.c +++ b/arch/x86_64/kernel/smp.c | |||
@@ -283,6 +283,16 @@ struct call_data_struct { | |||
283 | 283 | ||
284 | static struct call_data_struct * call_data; | 284 | static struct call_data_struct * call_data; |
285 | 285 | ||
286 | void lock_ipi_call_lock(void) | ||
287 | { | ||
288 | spin_lock_irq(&call_lock); | ||
289 | } | ||
290 | |||
291 | void unlock_ipi_call_lock(void) | ||
292 | { | ||
293 | spin_unlock_irq(&call_lock); | ||
294 | } | ||
295 | |||
286 | /* | 296 | /* |
287 | * this function sends a 'generic call function' IPI to all other CPUs | 297 | * this function sends a 'generic call function' IPI to all other CPUs |
288 | * in the system. | 298 | * in the system. |
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index f1ec0f345941..b969ee128728 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c | |||
@@ -34,6 +34,7 @@ | |||
34 | * Andi Kleen : Converted to new state machine. | 34 | * Andi Kleen : Converted to new state machine. |
35 | * Various cleanups. | 35 | * Various cleanups. |
36 | * Probably mostly hotplug CPU ready now. | 36 | * Probably mostly hotplug CPU ready now. |
37 | * Ashok Raj : CPU hotplug support | ||
37 | */ | 38 | */ |
38 | 39 | ||
39 | 40 | ||
@@ -58,11 +59,6 @@ | |||
58 | #include <asm/proto.h> | 59 | #include <asm/proto.h> |
59 | #include <asm/nmi.h> | 60 | #include <asm/nmi.h> |
60 | 61 | ||
61 | /* Change for real CPU hotplug. Note other files need to be fixed | ||
62 | first too. */ | ||
63 | #define __cpuinit __init | ||
64 | #define __cpuinitdata __initdata | ||
65 | |||
66 | /* Number of siblings per CPU package */ | 62 | /* Number of siblings per CPU package */ |
67 | int smp_num_siblings = 1; | 63 | int smp_num_siblings = 1; |
68 | /* Package ID of each logical CPU */ | 64 | /* Package ID of each logical CPU */ |
@@ -103,6 +99,37 @@ EXPORT_SYMBOL(cpu_core_map); | |||
103 | extern unsigned char trampoline_data[]; | 99 | extern unsigned char trampoline_data[]; |
104 | extern unsigned char trampoline_end[]; | 100 | extern unsigned char trampoline_end[]; |
105 | 101 | ||
102 | /* State of each CPU */ | ||
103 | DEFINE_PER_CPU(int, cpu_state) = { 0 }; | ||
104 | |||
105 | /* | ||
106 | * Store all idle threads, this can be reused instead of creating | ||
107 | * a new thread. Also avoids complicated thread destroy functionality | ||
108 | * for idle threads. | ||
109 | */ | ||
110 | struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ; | ||
111 | |||
112 | #define get_idle_for_cpu(x) (idle_thread_array[(x)]) | ||
113 | #define set_idle_for_cpu(x,p) (idle_thread_array[(x)] = (p)) | ||
114 | |||
115 | /* | ||
116 | * cpu_possible_map should be static, it cannot change as cpu's | ||
117 | * are onlined, or offlined. The reason is per-cpu data-structures | ||
118 | * are allocated by some modules at init time, and dont expect to | ||
119 | * do this dynamically on cpu arrival/departure. | ||
120 | * cpu_present_map on the other hand can change dynamically. | ||
121 | * In case when cpu_hotplug is not compiled, then we resort to current | ||
122 | * behaviour, which is cpu_possible == cpu_present. | ||
123 | * If cpu-hotplug is supported, then we need to preallocate for all | ||
124 | * those NR_CPUS, hence cpu_possible_map represents entire NR_CPUS range. | ||
125 | * - Ashok Raj | ||
126 | */ | ||
127 | #ifdef CONFIG_HOTPLUG_CPU | ||
128 | #define fixup_cpu_possible_map(x) cpu_set((x), cpu_possible_map) | ||
129 | #else | ||
130 | #define fixup_cpu_possible_map(x) | ||
131 | #endif | ||
132 | |||
106 | /* | 133 | /* |
107 | * Currently trivial. Write the real->protected mode | 134 | * Currently trivial. Write the real->protected mode |
108 | * bootstrap into the page concerned. The caller | 135 | * bootstrap into the page concerned. The caller |
@@ -418,6 +445,33 @@ void __cpuinit smp_callin(void) | |||
418 | cpu_set(cpuid, cpu_callin_map); | 445 | cpu_set(cpuid, cpu_callin_map); |
419 | } | 446 | } |
420 | 447 | ||
448 | static inline void set_cpu_sibling_map(int cpu) | ||
449 | { | ||
450 | int i; | ||
451 | |||
452 | if (smp_num_siblings > 1) { | ||
453 | for_each_cpu(i) { | ||
454 | if (cpu_core_id[cpu] == cpu_core_id[i]) { | ||
455 | cpu_set(i, cpu_sibling_map[cpu]); | ||
456 | cpu_set(cpu, cpu_sibling_map[i]); | ||
457 | } | ||
458 | } | ||
459 | } else { | ||
460 | cpu_set(cpu, cpu_sibling_map[cpu]); | ||
461 | } | ||
462 | |||
463 | if (current_cpu_data.x86_num_cores > 1) { | ||
464 | for_each_cpu(i) { | ||
465 | if (phys_proc_id[cpu] == phys_proc_id[i]) { | ||
466 | cpu_set(i, cpu_core_map[cpu]); | ||
467 | cpu_set(cpu, cpu_core_map[i]); | ||
468 | } | ||
469 | } | ||
470 | } else { | ||
471 | cpu_core_map[cpu] = cpu_sibling_map[cpu]; | ||
472 | } | ||
473 | } | ||
474 | |||
421 | /* | 475 | /* |
422 | * Setup code on secondary processor (after comming out of the trampoline) | 476 | * Setup code on secondary processor (after comming out of the trampoline) |
423 | */ | 477 | */ |
@@ -448,9 +502,28 @@ void __cpuinit start_secondary(void) | |||
448 | enable_APIC_timer(); | 502 | enable_APIC_timer(); |
449 | 503 | ||
450 | /* | 504 | /* |
505 | * The sibling maps must be set before turing the online map on for | ||
506 | * this cpu | ||
507 | */ | ||
508 | set_cpu_sibling_map(smp_processor_id()); | ||
509 | |||
510 | /* | ||
511 | * We need to hold call_lock, so there is no inconsistency | ||
512 | * between the time smp_call_function() determines number of | ||
513 | * IPI receipients, and the time when the determination is made | ||
514 | * for which cpus receive the IPI in genapic_flat.c. Holding this | ||
515 | * lock helps us to not include this cpu in a currently in progress | ||
516 | * smp_call_function(). | ||
517 | */ | ||
518 | lock_ipi_call_lock(); | ||
519 | |||
520 | /* | ||
451 | * Allow the master to continue. | 521 | * Allow the master to continue. |
452 | */ | 522 | */ |
453 | cpu_set(smp_processor_id(), cpu_online_map); | 523 | cpu_set(smp_processor_id(), cpu_online_map); |
524 | per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; | ||
525 | unlock_ipi_call_lock(); | ||
526 | |||
454 | mb(); | 527 | mb(); |
455 | 528 | ||
456 | /* Wait for TSC sync to not schedule things before. | 529 | /* Wait for TSC sync to not schedule things before. |
@@ -628,33 +701,77 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta | |||
628 | return (send_status | accept_status); | 701 | return (send_status | accept_status); |
629 | } | 702 | } |
630 | 703 | ||
704 | struct create_idle { | ||
705 | struct task_struct *idle; | ||
706 | struct completion done; | ||
707 | int cpu; | ||
708 | }; | ||
709 | |||
710 | void do_fork_idle(void *_c_idle) | ||
711 | { | ||
712 | struct create_idle *c_idle = _c_idle; | ||
713 | |||
714 | c_idle->idle = fork_idle(c_idle->cpu); | ||
715 | complete(&c_idle->done); | ||
716 | } | ||
717 | |||
631 | /* | 718 | /* |
632 | * Boot one CPU. | 719 | * Boot one CPU. |
633 | */ | 720 | */ |
634 | static int __cpuinit do_boot_cpu(int cpu, int apicid) | 721 | static int __cpuinit do_boot_cpu(int cpu, int apicid) |
635 | { | 722 | { |
636 | struct task_struct *idle; | ||
637 | unsigned long boot_error; | 723 | unsigned long boot_error; |
638 | int timeout; | 724 | int timeout; |
639 | unsigned long start_rip; | 725 | unsigned long start_rip; |
726 | struct create_idle c_idle = { | ||
727 | .cpu = cpu, | ||
728 | .done = COMPLETION_INITIALIZER(c_idle.done), | ||
729 | }; | ||
730 | DECLARE_WORK(work, do_fork_idle, &c_idle); | ||
731 | |||
732 | c_idle.idle = get_idle_for_cpu(cpu); | ||
733 | |||
734 | if (c_idle.idle) { | ||
735 | c_idle.idle->thread.rsp = (unsigned long) (((struct pt_regs *) | ||
736 | (THREAD_SIZE + (unsigned long) c_idle.idle->thread_info)) - 1); | ||
737 | init_idle(c_idle.idle, cpu); | ||
738 | goto do_rest; | ||
739 | } | ||
740 | |||
640 | /* | 741 | /* |
641 | * We can't use kernel_thread since we must avoid to | 742 | * During cold boot process, keventd thread is not spun up yet. |
642 | * reschedule the child. | 743 | * When we do cpu hot-add, we create idle threads on the fly, we should |
744 | * not acquire any attributes from the calling context. Hence the clean | ||
745 | * way to create kernel_threads() is to do that from keventd(). | ||
746 | * We do the current_is_keventd() due to the fact that ACPI notifier | ||
747 | * was also queuing to keventd() and when the caller is already running | ||
748 | * in context of keventd(), we would end up with locking up the keventd | ||
749 | * thread. | ||
643 | */ | 750 | */ |
644 | idle = fork_idle(cpu); | 751 | if (!keventd_up() || current_is_keventd()) |
645 | if (IS_ERR(idle)) { | 752 | work.func(work.data); |
753 | else { | ||
754 | schedule_work(&work); | ||
755 | wait_for_completion(&c_idle.done); | ||
756 | } | ||
757 | |||
758 | if (IS_ERR(c_idle.idle)) { | ||
646 | printk("failed fork for CPU %d\n", cpu); | 759 | printk("failed fork for CPU %d\n", cpu); |
647 | return PTR_ERR(idle); | 760 | return PTR_ERR(c_idle.idle); |
648 | } | 761 | } |
649 | 762 | ||
650 | cpu_pda[cpu].pcurrent = idle; | 763 | set_idle_for_cpu(cpu, c_idle.idle); |
764 | |||
765 | do_rest: | ||
766 | |||
767 | cpu_pda[cpu].pcurrent = c_idle.idle; | ||
651 | 768 | ||
652 | start_rip = setup_trampoline(); | 769 | start_rip = setup_trampoline(); |
653 | 770 | ||
654 | init_rsp = idle->thread.rsp; | 771 | init_rsp = c_idle.idle->thread.rsp; |
655 | per_cpu(init_tss,cpu).rsp0 = init_rsp; | 772 | per_cpu(init_tss,cpu).rsp0 = init_rsp; |
656 | initial_code = start_secondary; | 773 | initial_code = start_secondary; |
657 | clear_ti_thread_flag(idle->thread_info, TIF_FORK); | 774 | clear_ti_thread_flag(c_idle.idle->thread_info, TIF_FORK); |
658 | 775 | ||
659 | printk(KERN_INFO "Booting processor %d/%d rip %lx rsp %lx\n", cpu, apicid, | 776 | printk(KERN_INFO "Booting processor %d/%d rip %lx rsp %lx\n", cpu, apicid, |
660 | start_rip, init_rsp); | 777 | start_rip, init_rsp); |
@@ -746,51 +863,6 @@ cycles_t cacheflush_time; | |||
746 | unsigned long cache_decay_ticks; | 863 | unsigned long cache_decay_ticks; |
747 | 864 | ||
748 | /* | 865 | /* |
749 | * Construct cpu_sibling_map[], so that we can tell the sibling CPU | ||
750 | * on SMT systems efficiently. | ||
751 | */ | ||
752 | static __cpuinit void detect_siblings(void) | ||
753 | { | ||
754 | int cpu; | ||
755 | |||
756 | for (cpu = 0; cpu < NR_CPUS; cpu++) { | ||
757 | cpus_clear(cpu_sibling_map[cpu]); | ||
758 | cpus_clear(cpu_core_map[cpu]); | ||
759 | } | ||
760 | |||
761 | for_each_online_cpu (cpu) { | ||
762 | struct cpuinfo_x86 *c = cpu_data + cpu; | ||
763 | int siblings = 0; | ||
764 | int i; | ||
765 | if (smp_num_siblings > 1) { | ||
766 | for_each_online_cpu (i) { | ||
767 | if (cpu_core_id[cpu] == cpu_core_id[i]) { | ||
768 | siblings++; | ||
769 | cpu_set(i, cpu_sibling_map[cpu]); | ||
770 | } | ||
771 | } | ||
772 | } else { | ||
773 | siblings++; | ||
774 | cpu_set(cpu, cpu_sibling_map[cpu]); | ||
775 | } | ||
776 | |||
777 | if (siblings != smp_num_siblings) { | ||
778 | printk(KERN_WARNING | ||
779 | "WARNING: %d siblings found for CPU%d, should be %d\n", | ||
780 | siblings, cpu, smp_num_siblings); | ||
781 | smp_num_siblings = siblings; | ||
782 | } | ||
783 | if (c->x86_num_cores > 1) { | ||
784 | for_each_online_cpu(i) { | ||
785 | if (phys_proc_id[cpu] == phys_proc_id[i]) | ||
786 | cpu_set(i, cpu_core_map[cpu]); | ||
787 | } | ||
788 | } else | ||
789 | cpu_core_map[cpu] = cpu_sibling_map[cpu]; | ||
790 | } | ||
791 | } | ||
792 | |||
793 | /* | ||
794 | * Cleanup possible dangling ends... | 866 | * Cleanup possible dangling ends... |
795 | */ | 867 | */ |
796 | static __cpuinit void smp_cleanup_boot(void) | 868 | static __cpuinit void smp_cleanup_boot(void) |
@@ -823,7 +895,7 @@ static __cpuinit void smp_cleanup_boot(void) | |||
823 | * | 895 | * |
824 | * RED-PEN audit/test this more. I bet there is more state messed up here. | 896 | * RED-PEN audit/test this more. I bet there is more state messed up here. |
825 | */ | 897 | */ |
826 | static __cpuinit void disable_smp(void) | 898 | static __init void disable_smp(void) |
827 | { | 899 | { |
828 | cpu_present_map = cpumask_of_cpu(0); | 900 | cpu_present_map = cpumask_of_cpu(0); |
829 | cpu_possible_map = cpumask_of_cpu(0); | 901 | cpu_possible_map = cpumask_of_cpu(0); |
@@ -838,7 +910,7 @@ static __cpuinit void disable_smp(void) | |||
838 | /* | 910 | /* |
839 | * Handle user cpus=... parameter. | 911 | * Handle user cpus=... parameter. |
840 | */ | 912 | */ |
841 | static __cpuinit void enforce_max_cpus(unsigned max_cpus) | 913 | static __init void enforce_max_cpus(unsigned max_cpus) |
842 | { | 914 | { |
843 | int i, k; | 915 | int i, k; |
844 | k = 0; | 916 | k = 0; |
@@ -855,7 +927,7 @@ static __cpuinit void enforce_max_cpus(unsigned max_cpus) | |||
855 | /* | 927 | /* |
856 | * Various sanity checks. | 928 | * Various sanity checks. |
857 | */ | 929 | */ |
858 | static int __cpuinit smp_sanity_check(unsigned max_cpus) | 930 | static int __init smp_sanity_check(unsigned max_cpus) |
859 | { | 931 | { |
860 | if (!physid_isset(hard_smp_processor_id(), phys_cpu_present_map)) { | 932 | if (!physid_isset(hard_smp_processor_id(), phys_cpu_present_map)) { |
861 | printk("weird, boot CPU (#%d) not listed by the BIOS.\n", | 933 | printk("weird, boot CPU (#%d) not listed by the BIOS.\n", |
@@ -913,7 +985,7 @@ static int __cpuinit smp_sanity_check(unsigned max_cpus) | |||
913 | * Prepare for SMP bootup. The MP table or ACPI has been read | 985 | * Prepare for SMP bootup. The MP table or ACPI has been read |
914 | * earlier. Just do some sanity checking here and enable APIC mode. | 986 | * earlier. Just do some sanity checking here and enable APIC mode. |
915 | */ | 987 | */ |
916 | void __cpuinit smp_prepare_cpus(unsigned int max_cpus) | 988 | void __init smp_prepare_cpus(unsigned int max_cpus) |
917 | { | 989 | { |
918 | int i; | 990 | int i; |
919 | 991 | ||
@@ -930,10 +1002,9 @@ void __cpuinit smp_prepare_cpus(unsigned int max_cpus) | |||
930 | int apicid = cpu_present_to_apicid(i); | 1002 | int apicid = cpu_present_to_apicid(i); |
931 | if (physid_isset(apicid, phys_cpu_present_map)) { | 1003 | if (physid_isset(apicid, phys_cpu_present_map)) { |
932 | cpu_set(i, cpu_present_map); | 1004 | cpu_set(i, cpu_present_map); |
933 | /* possible map would be different if we supported real | ||
934 | CPU hotplug. */ | ||
935 | cpu_set(i, cpu_possible_map); | 1005 | cpu_set(i, cpu_possible_map); |
936 | } | 1006 | } |
1007 | fixup_cpu_possible_map(i); | ||
937 | } | 1008 | } |
938 | 1009 | ||
939 | if (smp_sanity_check(max_cpus) < 0) { | 1010 | if (smp_sanity_check(max_cpus) < 0) { |
@@ -978,13 +1049,13 @@ void __init smp_prepare_boot_cpu(void) | |||
978 | int me = smp_processor_id(); | 1049 | int me = smp_processor_id(); |
979 | cpu_set(me, cpu_online_map); | 1050 | cpu_set(me, cpu_online_map); |
980 | cpu_set(me, cpu_callout_map); | 1051 | cpu_set(me, cpu_callout_map); |
1052 | cpu_set(0, cpu_sibling_map[0]); | ||
1053 | cpu_set(0, cpu_core_map[0]); | ||
1054 | per_cpu(cpu_state, me) = CPU_ONLINE; | ||
981 | } | 1055 | } |
982 | 1056 | ||
983 | /* | 1057 | /* |
984 | * Entry point to boot a CPU. | 1058 | * Entry point to boot a CPU. |
985 | * | ||
986 | * This is all __cpuinit, not __devinit for now because we don't support | ||
987 | * CPU hotplug (yet). | ||
988 | */ | 1059 | */ |
989 | int __cpuinit __cpu_up(unsigned int cpu) | 1060 | int __cpuinit __cpu_up(unsigned int cpu) |
990 | { | 1061 | { |
@@ -1001,6 +1072,15 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
1001 | return -EINVAL; | 1072 | return -EINVAL; |
1002 | } | 1073 | } |
1003 | 1074 | ||
1075 | /* | ||
1076 | * Already booted CPU? | ||
1077 | */ | ||
1078 | if (cpu_isset(cpu, cpu_callin_map)) { | ||
1079 | Dprintk("do_boot_cpu %d Already started\n", cpu); | ||
1080 | return -ENOSYS; | ||
1081 | } | ||
1082 | |||
1083 | per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; | ||
1004 | /* Boot it! */ | 1084 | /* Boot it! */ |
1005 | err = do_boot_cpu(cpu, apicid); | 1085 | err = do_boot_cpu(cpu, apicid); |
1006 | if (err < 0) { | 1086 | if (err < 0) { |
@@ -1013,23 +1093,118 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
1013 | 1093 | ||
1014 | while (!cpu_isset(cpu, cpu_online_map)) | 1094 | while (!cpu_isset(cpu, cpu_online_map)) |
1015 | cpu_relax(); | 1095 | cpu_relax(); |
1016 | return 0; | 1096 | err = 0; |
1097 | |||
1098 | return err; | ||
1017 | } | 1099 | } |
1018 | 1100 | ||
1019 | /* | 1101 | /* |
1020 | * Finish the SMP boot. | 1102 | * Finish the SMP boot. |
1021 | */ | 1103 | */ |
1022 | void __cpuinit smp_cpus_done(unsigned int max_cpus) | 1104 | void __init smp_cpus_done(unsigned int max_cpus) |
1023 | { | 1105 | { |
1106 | #ifndef CONFIG_HOTPLUG_CPU | ||
1024 | zap_low_mappings(); | 1107 | zap_low_mappings(); |
1108 | #endif | ||
1025 | smp_cleanup_boot(); | 1109 | smp_cleanup_boot(); |
1026 | 1110 | ||
1027 | #ifdef CONFIG_X86_IO_APIC | 1111 | #ifdef CONFIG_X86_IO_APIC |
1028 | setup_ioapic_dest(); | 1112 | setup_ioapic_dest(); |
1029 | #endif | 1113 | #endif |
1030 | 1114 | ||
1031 | detect_siblings(); | ||
1032 | time_init_gtod(); | 1115 | time_init_gtod(); |
1033 | 1116 | ||
1034 | check_nmi_watchdog(); | 1117 | check_nmi_watchdog(); |
1035 | } | 1118 | } |
1119 | |||
1120 | #ifdef CONFIG_HOTPLUG_CPU | ||
1121 | |||
1122 | static void remove_siblinginfo(int cpu) | ||
1123 | { | ||
1124 | int sibling; | ||
1125 | |||
1126 | for_each_cpu_mask(sibling, cpu_sibling_map[cpu]) | ||
1127 | cpu_clear(cpu, cpu_sibling_map[sibling]); | ||
1128 | for_each_cpu_mask(sibling, cpu_core_map[cpu]) | ||
1129 | cpu_clear(cpu, cpu_core_map[sibling]); | ||
1130 | cpus_clear(cpu_sibling_map[cpu]); | ||
1131 | cpus_clear(cpu_core_map[cpu]); | ||
1132 | phys_proc_id[cpu] = BAD_APICID; | ||
1133 | cpu_core_id[cpu] = BAD_APICID; | ||
1134 | } | ||
1135 | |||
1136 | void remove_cpu_from_maps(void) | ||
1137 | { | ||
1138 | int cpu = smp_processor_id(); | ||
1139 | |||
1140 | cpu_clear(cpu, cpu_callout_map); | ||
1141 | cpu_clear(cpu, cpu_callin_map); | ||
1142 | clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */ | ||
1143 | } | ||
1144 | |||
1145 | int __cpu_disable(void) | ||
1146 | { | ||
1147 | int cpu = smp_processor_id(); | ||
1148 | |||
1149 | /* | ||
1150 | * Perhaps use cpufreq to drop frequency, but that could go | ||
1151 | * into generic code. | ||
1152 | * | ||
1153 | * We won't take down the boot processor on i386 due to some | ||
1154 | * interrupts only being able to be serviced by the BSP. | ||
1155 | * Especially so if we're not using an IOAPIC -zwane | ||
1156 | */ | ||
1157 | if (cpu == 0) | ||
1158 | return -EBUSY; | ||
1159 | |||
1160 | disable_APIC_timer(); | ||
1161 | |||
1162 | /* | ||
1163 | * HACK: | ||
1164 | * Allow any queued timer interrupts to get serviced | ||
1165 | * This is only a temporary solution until we cleanup | ||
1166 | * fixup_irqs as we do for IA64. | ||
1167 | */ | ||
1168 | local_irq_enable(); | ||
1169 | mdelay(1); | ||
1170 | |||
1171 | local_irq_disable(); | ||
1172 | remove_siblinginfo(cpu); | ||
1173 | |||
1174 | /* It's now safe to remove this processor from the online map */ | ||
1175 | cpu_clear(cpu, cpu_online_map); | ||
1176 | remove_cpu_from_maps(); | ||
1177 | fixup_irqs(cpu_online_map); | ||
1178 | return 0; | ||
1179 | } | ||
1180 | |||
1181 | void __cpu_die(unsigned int cpu) | ||
1182 | { | ||
1183 | /* We don't do anything here: idle task is faking death itself. */ | ||
1184 | unsigned int i; | ||
1185 | |||
1186 | for (i = 0; i < 10; i++) { | ||
1187 | /* They ack this in play_dead by setting CPU_DEAD */ | ||
1188 | if (per_cpu(cpu_state, cpu) == CPU_DEAD) { | ||
1189 | printk ("CPU %d is now offline\n", cpu); | ||
1190 | return; | ||
1191 | } | ||
1192 | current->state = TASK_UNINTERRUPTIBLE; | ||
1193 | schedule_timeout(HZ/10); | ||
1194 | } | ||
1195 | printk(KERN_ERR "CPU %u didn't die...\n", cpu); | ||
1196 | } | ||
1197 | |||
1198 | #else /* ... !CONFIG_HOTPLUG_CPU */ | ||
1199 | |||
1200 | int __cpu_disable(void) | ||
1201 | { | ||
1202 | return -ENOSYS; | ||
1203 | } | ||
1204 | |||
1205 | void __cpu_die(unsigned int cpu) | ||
1206 | { | ||
1207 | /* We said "no" in __cpu_disable */ | ||
1208 | BUG(); | ||
1209 | } | ||
1210 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
diff --git a/arch/x86_64/kernel/suspend.c b/arch/x86_64/kernel/suspend.c index ebaa1e37d657..6c0f402e3a88 100644 --- a/arch/x86_64/kernel/suspend.c +++ b/arch/x86_64/kernel/suspend.c | |||
@@ -44,7 +44,6 @@ void __save_processor_state(struct saved_context *ctxt) | |||
44 | */ | 44 | */ |
45 | asm volatile ("sgdt %0" : "=m" (ctxt->gdt_limit)); | 45 | asm volatile ("sgdt %0" : "=m" (ctxt->gdt_limit)); |
46 | asm volatile ("sidt %0" : "=m" (ctxt->idt_limit)); | 46 | asm volatile ("sidt %0" : "=m" (ctxt->idt_limit)); |
47 | asm volatile ("sldt %0" : "=m" (ctxt->ldt)); | ||
48 | asm volatile ("str %0" : "=m" (ctxt->tr)); | 47 | asm volatile ("str %0" : "=m" (ctxt->tr)); |
49 | 48 | ||
50 | /* XMM0..XMM15 should be handled by kernel_fpu_begin(). */ | 49 | /* XMM0..XMM15 should be handled by kernel_fpu_begin(). */ |
@@ -69,6 +68,7 @@ void __save_processor_state(struct saved_context *ctxt) | |||
69 | asm volatile ("movq %%cr2, %0" : "=r" (ctxt->cr2)); | 68 | asm volatile ("movq %%cr2, %0" : "=r" (ctxt->cr2)); |
70 | asm volatile ("movq %%cr3, %0" : "=r" (ctxt->cr3)); | 69 | asm volatile ("movq %%cr3, %0" : "=r" (ctxt->cr3)); |
71 | asm volatile ("movq %%cr4, %0" : "=r" (ctxt->cr4)); | 70 | asm volatile ("movq %%cr4, %0" : "=r" (ctxt->cr4)); |
71 | asm volatile ("movq %%cr8, %0" : "=r" (ctxt->cr8)); | ||
72 | } | 72 | } |
73 | 73 | ||
74 | void save_processor_state(void) | 74 | void save_processor_state(void) |
@@ -90,12 +90,20 @@ void __restore_processor_state(struct saved_context *ctxt) | |||
90 | /* | 90 | /* |
91 | * control registers | 91 | * control registers |
92 | */ | 92 | */ |
93 | asm volatile ("movq %0, %%cr8" :: "r" (ctxt->cr8)); | ||
93 | asm volatile ("movq %0, %%cr4" :: "r" (ctxt->cr4)); | 94 | asm volatile ("movq %0, %%cr4" :: "r" (ctxt->cr4)); |
94 | asm volatile ("movq %0, %%cr3" :: "r" (ctxt->cr3)); | 95 | asm volatile ("movq %0, %%cr3" :: "r" (ctxt->cr3)); |
95 | asm volatile ("movq %0, %%cr2" :: "r" (ctxt->cr2)); | 96 | asm volatile ("movq %0, %%cr2" :: "r" (ctxt->cr2)); |
96 | asm volatile ("movq %0, %%cr0" :: "r" (ctxt->cr0)); | 97 | asm volatile ("movq %0, %%cr0" :: "r" (ctxt->cr0)); |
97 | 98 | ||
98 | /* | 99 | /* |
100 | * now restore the descriptor tables to their proper values | ||
101 | * ltr is done i fix_processor_context(). | ||
102 | */ | ||
103 | asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit)); | ||
104 | asm volatile ("lidt %0" :: "m" (ctxt->idt_limit)); | ||
105 | |||
106 | /* | ||
99 | * segment registers | 107 | * segment registers |
100 | */ | 108 | */ |
101 | asm volatile ("movw %0, %%ds" :: "r" (ctxt->ds)); | 109 | asm volatile ("movw %0, %%ds" :: "r" (ctxt->ds)); |
@@ -108,14 +116,6 @@ void __restore_processor_state(struct saved_context *ctxt) | |||
108 | wrmsrl(MSR_GS_BASE, ctxt->gs_base); | 116 | wrmsrl(MSR_GS_BASE, ctxt->gs_base); |
109 | wrmsrl(MSR_KERNEL_GS_BASE, ctxt->gs_kernel_base); | 117 | wrmsrl(MSR_KERNEL_GS_BASE, ctxt->gs_kernel_base); |
110 | 118 | ||
111 | /* | ||
112 | * now restore the descriptor tables to their proper values | ||
113 | * ltr is done i fix_processor_context(). | ||
114 | */ | ||
115 | asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit)); | ||
116 | asm volatile ("lidt %0" :: "m" (ctxt->idt_limit)); | ||
117 | asm volatile ("lldt %0" :: "m" (ctxt->ldt)); | ||
118 | |||
119 | fix_processor_context(); | 119 | fix_processor_context(); |
120 | 120 | ||
121 | do_fpu_end(); | 121 | do_fpu_end(); |
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 121646fc43f6..102736630002 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c | |||
@@ -586,11 +586,17 @@ static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs) | |||
586 | asmlinkage void default_do_nmi(struct pt_regs *regs) | 586 | asmlinkage void default_do_nmi(struct pt_regs *regs) |
587 | { | 587 | { |
588 | unsigned char reason = 0; | 588 | unsigned char reason = 0; |
589 | int cpu; | ||
590 | |||
591 | cpu = smp_processor_id(); | ||
589 | 592 | ||
590 | /* Only the BSP gets external NMIs from the system. */ | 593 | /* Only the BSP gets external NMIs from the system. */ |
591 | if (!smp_processor_id()) | 594 | if (!cpu) |
592 | reason = get_nmi_reason(); | 595 | reason = get_nmi_reason(); |
593 | 596 | ||
597 | if (!cpu_online(cpu)) | ||
598 | return; | ||
599 | |||
594 | if (!(reason & 0xc0)) { | 600 | if (!(reason & 0xc0)) { |
595 | if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT) | 601 | if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT) |
596 | == NOTIFY_STOP) | 602 | == NOTIFY_STOP) |
diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S index 59ebd5beda87..73389f51c4e5 100644 --- a/arch/x86_64/kernel/vmlinux.lds.S +++ b/arch/x86_64/kernel/vmlinux.lds.S | |||
@@ -2,7 +2,10 @@ | |||
2 | * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>; | 2 | * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>; |
3 | */ | 3 | */ |
4 | 4 | ||
5 | #define LOAD_OFFSET __START_KERNEL_map | ||
6 | |||
5 | #include <asm-generic/vmlinux.lds.h> | 7 | #include <asm-generic/vmlinux.lds.h> |
8 | #include <asm/page.h> | ||
6 | #include <linux/config.h> | 9 | #include <linux/config.h> |
7 | 10 | ||
8 | OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") | 11 | OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") |
@@ -11,28 +14,30 @@ ENTRY(phys_startup_64) | |||
11 | jiffies_64 = jiffies; | 14 | jiffies_64 = jiffies; |
12 | SECTIONS | 15 | SECTIONS |
13 | { | 16 | { |
14 | . = 0xffffffff80100000; | 17 | . = __START_KERNEL; |
15 | phys_startup_64 = startup_64 - LOAD_OFFSET; | 18 | phys_startup_64 = startup_64 - LOAD_OFFSET; |
16 | _text = .; /* Text and read-only data */ | 19 | _text = .; /* Text and read-only data */ |
17 | .text : { | 20 | .text : AT(ADDR(.text) - LOAD_OFFSET) { |
18 | *(.text) | 21 | *(.text) |
19 | SCHED_TEXT | 22 | SCHED_TEXT |
20 | LOCK_TEXT | 23 | LOCK_TEXT |
21 | *(.fixup) | 24 | *(.fixup) |
22 | *(.gnu.warning) | 25 | *(.gnu.warning) |
23 | } = 0x9090 | 26 | } = 0x9090 |
24 | .text.lock : { *(.text.lock) } /* out-of-line lock text */ | 27 | /* out-of-line lock text */ |
28 | .text.lock : AT(ADDR(.text.lock) - LOAD_OFFSET) { *(.text.lock) } | ||
25 | 29 | ||
26 | _etext = .; /* End of text section */ | 30 | _etext = .; /* End of text section */ |
27 | 31 | ||
28 | . = ALIGN(16); /* Exception table */ | 32 | . = ALIGN(16); /* Exception table */ |
29 | __start___ex_table = .; | 33 | __start___ex_table = .; |
30 | __ex_table : { *(__ex_table) } | 34 | __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) } |
31 | __stop___ex_table = .; | 35 | __stop___ex_table = .; |
32 | 36 | ||
33 | RODATA | 37 | RODATA |
34 | 38 | ||
35 | .data : { /* Data */ | 39 | /* Data */ |
40 | .data : AT(ADDR(.data) - LOAD_OFFSET) { | ||
36 | *(.data) | 41 | *(.data) |
37 | CONSTRUCTORS | 42 | CONSTRUCTORS |
38 | } | 43 | } |
@@ -40,62 +45,95 @@ SECTIONS | |||
40 | _edata = .; /* End of data section */ | 45 | _edata = .; /* End of data section */ |
41 | 46 | ||
42 | __bss_start = .; /* BSS */ | 47 | __bss_start = .; /* BSS */ |
43 | .bss : { | 48 | .bss : AT(ADDR(.bss) - LOAD_OFFSET) { |
44 | *(.bss.page_aligned) | 49 | *(.bss.page_aligned) |
45 | *(.bss) | 50 | *(.bss) |
46 | } | 51 | } |
47 | __bss_end = .; | 52 | __bss_end = .; |
48 | 53 | ||
54 | . = ALIGN(PAGE_SIZE); | ||
49 | . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); | 55 | . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); |
50 | .data.cacheline_aligned : { *(.data.cacheline_aligned) } | 56 | .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) { |
57 | *(.data.cacheline_aligned) | ||
58 | } | ||
59 | |||
60 | #define VSYSCALL_ADDR (-10*1024*1024) | ||
61 | #define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.cacheline_aligned) + SIZEOF(.data.cacheline_aligned) + 4095) & ~(4095)) | ||
62 | #define VSYSCALL_VIRT_ADDR ((ADDR(.data.cacheline_aligned) + SIZEOF(.data.cacheline_aligned) + 4095) & ~(4095)) | ||
63 | |||
64 | #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR) | ||
65 | #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET) | ||
66 | |||
67 | #define VVIRT_OFFSET (VSYSCALL_ADDR - VSYSCALL_VIRT_ADDR) | ||
68 | #define VVIRT(x) (ADDR(x) - VVIRT_OFFSET) | ||
51 | 69 | ||
52 | #define AFTER(x) BINALIGN(LOADADDR(x) + SIZEOF(x), 16) | 70 | . = VSYSCALL_ADDR; |
53 | #define BINALIGN(x,y) (((x) + (y) - 1) & ~((y) - 1)) | 71 | .vsyscall_0 : AT(VSYSCALL_PHYS_ADDR) { *(.vsyscall_0) } |
54 | #define CACHE_ALIGN(x) BINALIGN(x, CONFIG_X86_L1_CACHE_BYTES) | 72 | __vsyscall_0 = VSYSCALL_VIRT_ADDR; |
55 | 73 | ||
56 | .vsyscall_0 -10*1024*1024: AT ((LOADADDR(.data.cacheline_aligned) + SIZEOF(.data.cacheline_aligned) + 4095) & ~(4095)) { *(.vsyscall_0) } | ||
57 | __vsyscall_0 = LOADADDR(.vsyscall_0); | ||
58 | . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); | 74 | . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); |
59 | .xtime_lock : AT CACHE_ALIGN(AFTER(.vsyscall_0)) { *(.xtime_lock) } | 75 | .xtime_lock : AT(VLOAD(.xtime_lock)) { *(.xtime_lock) } |
60 | xtime_lock = LOADADDR(.xtime_lock); | 76 | xtime_lock = VVIRT(.xtime_lock); |
61 | .vxtime : AT AFTER(.xtime_lock) { *(.vxtime) } | 77 | |
62 | vxtime = LOADADDR(.vxtime); | 78 | .vxtime : AT(VLOAD(.vxtime)) { *(.vxtime) } |
63 | .wall_jiffies : AT AFTER(.vxtime) { *(.wall_jiffies) } | 79 | vxtime = VVIRT(.vxtime); |
64 | wall_jiffies = LOADADDR(.wall_jiffies); | 80 | |
65 | .sys_tz : AT AFTER(.wall_jiffies) { *(.sys_tz) } | 81 | .wall_jiffies : AT(VLOAD(.wall_jiffies)) { *(.wall_jiffies) } |
66 | sys_tz = LOADADDR(.sys_tz); | 82 | wall_jiffies = VVIRT(.wall_jiffies); |
67 | .sysctl_vsyscall : AT AFTER(.sys_tz) { *(.sysctl_vsyscall) } | 83 | |
68 | sysctl_vsyscall = LOADADDR(.sysctl_vsyscall); | 84 | .sys_tz : AT(VLOAD(.sys_tz)) { *(.sys_tz) } |
69 | .xtime : AT AFTER(.sysctl_vsyscall) { *(.xtime) } | 85 | sys_tz = VVIRT(.sys_tz); |
70 | xtime = LOADADDR(.xtime); | 86 | |
87 | .sysctl_vsyscall : AT(VLOAD(.sysctl_vsyscall)) { *(.sysctl_vsyscall) } | ||
88 | sysctl_vsyscall = VVIRT(.sysctl_vsyscall); | ||
89 | |||
90 | .xtime : AT(VLOAD(.xtime)) { *(.xtime) } | ||
91 | xtime = VVIRT(.xtime); | ||
92 | |||
71 | . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); | 93 | . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); |
72 | .jiffies : AT CACHE_ALIGN(AFTER(.xtime)) { *(.jiffies) } | 94 | .jiffies : AT(VLOAD(.jiffies)) { *(.jiffies) } |
73 | jiffies = LOADADDR(.jiffies); | 95 | jiffies = VVIRT(.jiffies); |
74 | .vsyscall_1 ADDR(.vsyscall_0) + 1024: AT (LOADADDR(.vsyscall_0) + 1024) { *(.vsyscall_1) } | 96 | |
75 | . = LOADADDR(.vsyscall_0) + 4096; | 97 | .vsyscall_1 ADDR(.vsyscall_0) + 1024: AT(VLOAD(.vsyscall_1)) { *(.vsyscall_1) } |
98 | .vsyscall_2 ADDR(.vsyscall_0) + 2048: AT(VLOAD(.vsyscall_2)) { *(.vsyscall_2) } | ||
99 | .vsyscall_3 ADDR(.vsyscall_0) + 3072: AT(VLOAD(.vsyscall_3)) { *(.vsyscall_3) } | ||
100 | |||
101 | . = VSYSCALL_VIRT_ADDR + 4096; | ||
102 | |||
103 | #undef VSYSCALL_ADDR | ||
104 | #undef VSYSCALL_PHYS_ADDR | ||
105 | #undef VSYSCALL_VIRT_ADDR | ||
106 | #undef VLOAD_OFFSET | ||
107 | #undef VLOAD | ||
108 | #undef VVIRT_OFFSET | ||
109 | #undef VVIRT | ||
76 | 110 | ||
77 | . = ALIGN(8192); /* init_task */ | 111 | . = ALIGN(8192); /* init_task */ |
78 | .data.init_task : { *(.data.init_task) } | 112 | .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) { |
113 | *(.data.init_task) | ||
114 | } | ||
79 | 115 | ||
80 | . = ALIGN(4096); | 116 | . = ALIGN(4096); |
81 | .data.page_aligned : { *(.data.page_aligned) } | 117 | .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { |
118 | *(.data.page_aligned) | ||
119 | } | ||
82 | 120 | ||
83 | . = ALIGN(4096); /* Init code and data */ | 121 | . = ALIGN(4096); /* Init code and data */ |
84 | __init_begin = .; | 122 | __init_begin = .; |
85 | .init.text : { | 123 | .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { |
86 | _sinittext = .; | 124 | _sinittext = .; |
87 | *(.init.text) | 125 | *(.init.text) |
88 | _einittext = .; | 126 | _einittext = .; |
89 | } | 127 | } |
90 | __initdata_begin = .; | 128 | __initdata_begin = .; |
91 | .init.data : { *(.init.data) } | 129 | .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) } |
92 | __initdata_end = .; | 130 | __initdata_end = .; |
93 | . = ALIGN(16); | 131 | . = ALIGN(16); |
94 | __setup_start = .; | 132 | __setup_start = .; |
95 | .init.setup : { *(.init.setup) } | 133 | .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) } |
96 | __setup_end = .; | 134 | __setup_end = .; |
97 | __initcall_start = .; | 135 | __initcall_start = .; |
98 | .initcall.init : { | 136 | .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { |
99 | *(.initcall1.init) | 137 | *(.initcall1.init) |
100 | *(.initcall2.init) | 138 | *(.initcall2.init) |
101 | *(.initcall3.init) | 139 | *(.initcall3.init) |
@@ -106,32 +144,38 @@ SECTIONS | |||
106 | } | 144 | } |
107 | __initcall_end = .; | 145 | __initcall_end = .; |
108 | __con_initcall_start = .; | 146 | __con_initcall_start = .; |
109 | .con_initcall.init : { *(.con_initcall.init) } | 147 | .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) { |
148 | *(.con_initcall.init) | ||
149 | } | ||
110 | __con_initcall_end = .; | 150 | __con_initcall_end = .; |
111 | SECURITY_INIT | 151 | SECURITY_INIT |
112 | . = ALIGN(8); | 152 | . = ALIGN(8); |
113 | __alt_instructions = .; | 153 | __alt_instructions = .; |
114 | .altinstructions : { *(.altinstructions) } | 154 | .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) { |
155 | *(.altinstructions) | ||
156 | } | ||
115 | __alt_instructions_end = .; | 157 | __alt_instructions_end = .; |
116 | .altinstr_replacement : { *(.altinstr_replacement) } | 158 | .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) { |
159 | *(.altinstr_replacement) | ||
160 | } | ||
117 | /* .exit.text is discard at runtime, not link time, to deal with references | 161 | /* .exit.text is discard at runtime, not link time, to deal with references |
118 | from .altinstructions and .eh_frame */ | 162 | from .altinstructions and .eh_frame */ |
119 | .exit.text : { *(.exit.text) } | 163 | .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) } |
120 | .exit.data : { *(.exit.data) } | 164 | .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) } |
121 | . = ALIGN(4096); | 165 | . = ALIGN(4096); |
122 | __initramfs_start = .; | 166 | __initramfs_start = .; |
123 | .init.ramfs : { *(.init.ramfs) } | 167 | .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) } |
124 | __initramfs_end = .; | 168 | __initramfs_end = .; |
125 | . = ALIGN(32); | 169 | . = ALIGN(32); |
126 | __per_cpu_start = .; | 170 | __per_cpu_start = .; |
127 | .data.percpu : { *(.data.percpu) } | 171 | .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) } |
128 | __per_cpu_end = .; | 172 | __per_cpu_end = .; |
129 | . = ALIGN(4096); | 173 | . = ALIGN(4096); |
130 | __init_end = .; | 174 | __init_end = .; |
131 | 175 | ||
132 | . = ALIGN(4096); | 176 | . = ALIGN(4096); |
133 | __nosave_begin = .; | 177 | __nosave_begin = .; |
134 | .data_nosave : { *(.data.nosave) } | 178 | .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) } |
135 | . = ALIGN(4096); | 179 | . = ALIGN(4096); |
136 | __nosave_end = .; | 180 | __nosave_end = .; |
137 | 181 | ||
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c index 84cde796ecb1..ac61c186eb02 100644 --- a/arch/x86_64/mm/numa.c +++ b/arch/x86_64/mm/numa.c | |||
@@ -251,7 +251,7 @@ void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn) | |||
251 | setup_node_bootmem(0, start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT); | 251 | setup_node_bootmem(0, start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT); |
252 | } | 252 | } |
253 | 253 | ||
254 | __init void numa_add_cpu(int cpu) | 254 | __cpuinit void numa_add_cpu(int cpu) |
255 | { | 255 | { |
256 | /* BP is initialized elsewhere */ | 256 | /* BP is initialized elsewhere */ |
257 | if (cpu) | 257 | if (cpu) |
diff --git a/arch/xtensa/platform-iss/console.c b/arch/xtensa/platform-iss/console.c index 9e2b53f6a907..4fbddf92a921 100644 --- a/arch/xtensa/platform-iss/console.c +++ b/arch/xtensa/platform-iss/console.c | |||
@@ -198,9 +198,6 @@ static int rs_read_proc(char *page, char **start, off_t off, int count, | |||
198 | } | 198 | } |
199 | 199 | ||
200 | 200 | ||
201 | int register_serial(struct serial_struct*); | ||
202 | void unregister_serial(int); | ||
203 | |||
204 | static struct tty_operations serial_ops = { | 201 | static struct tty_operations serial_ops = { |
205 | .open = rs_open, | 202 | .open = rs_open, |
206 | .close = rs_close, | 203 | .close = rs_close, |
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 670fdb5142d1..86c52520ed34 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -55,7 +55,7 @@ if ACPI_INTERPRETER | |||
55 | 55 | ||
56 | config ACPI_SLEEP | 56 | config ACPI_SLEEP |
57 | bool "Sleep States (EXPERIMENTAL)" | 57 | bool "Sleep States (EXPERIMENTAL)" |
58 | depends on X86 | 58 | depends on X86 && (!SMP || SUSPEND_SMP) |
59 | depends on EXPERIMENTAL && PM | 59 | depends on EXPERIMENTAL && PM |
60 | default y | 60 | default y |
61 | ---help--- | 61 | ---help--- |
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 8093f2e00321..8dbf802ee7f8 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c | |||
@@ -435,6 +435,7 @@ acpi_pci_irq_enable ( | |||
435 | /* Interrupt Line values above 0xF are forbidden */ | 435 | /* Interrupt Line values above 0xF are forbidden */ |
436 | if (dev->irq >= 0 && (dev->irq <= 0xF)) { | 436 | if (dev->irq >= 0 && (dev->irq <= 0xF)) { |
437 | printk(" - using IRQ %d\n", dev->irq); | 437 | printk(" - using IRQ %d\n", dev->irq); |
438 | acpi_register_gsi(dev->irq, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW); | ||
438 | return_VALUE(0); | 439 | return_VALUE(0); |
439 | } | 440 | } |
440 | else { | 441 | else { |
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 6ef3069b5710..b79badd0f158 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
@@ -16,6 +16,11 @@ struct sysdev_class cpu_sysdev_class = { | |||
16 | EXPORT_SYMBOL(cpu_sysdev_class); | 16 | EXPORT_SYMBOL(cpu_sysdev_class); |
17 | 17 | ||
18 | #ifdef CONFIG_HOTPLUG_CPU | 18 | #ifdef CONFIG_HOTPLUG_CPU |
19 | int __attribute__((weak)) smp_prepare_cpu (int cpu) | ||
20 | { | ||
21 | return 0; | ||
22 | } | ||
23 | |||
19 | static ssize_t show_online(struct sys_device *dev, char *buf) | 24 | static ssize_t show_online(struct sys_device *dev, char *buf) |
20 | { | 25 | { |
21 | struct cpu *cpu = container_of(dev, struct cpu, sysdev); | 26 | struct cpu *cpu = container_of(dev, struct cpu, sysdev); |
@@ -36,7 +41,11 @@ static ssize_t store_online(struct sys_device *dev, const char *buf, | |||
36 | kobject_hotplug(&dev->kobj, KOBJ_OFFLINE); | 41 | kobject_hotplug(&dev->kobj, KOBJ_OFFLINE); |
37 | break; | 42 | break; |
38 | case '1': | 43 | case '1': |
39 | ret = cpu_up(cpu->sysdev.id); | 44 | ret = smp_prepare_cpu(cpu->sysdev.id); |
45 | if (!ret) | ||
46 | ret = cpu_up(cpu->sysdev.id); | ||
47 | if (!ret) | ||
48 | kobject_hotplug(&dev->kobj, KOBJ_ONLINE); | ||
40 | break; | 49 | break; |
41 | default: | 50 | default: |
42 | ret = -EINVAL; | 51 | ret = -EINVAL; |
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index fd94ea27d594..60e64091de1b 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c | |||
@@ -37,6 +37,7 @@ | |||
37 | 37 | ||
38 | static void blk_unplug_work(void *data); | 38 | static void blk_unplug_work(void *data); |
39 | static void blk_unplug_timeout(unsigned long data); | 39 | static void blk_unplug_timeout(unsigned long data); |
40 | static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io); | ||
40 | 41 | ||
41 | /* | 42 | /* |
42 | * For the allocated request tables | 43 | * For the allocated request tables |
@@ -1137,7 +1138,7 @@ new_hw_segment: | |||
1137 | } | 1138 | } |
1138 | 1139 | ||
1139 | 1140 | ||
1140 | int blk_phys_contig_segment(request_queue_t *q, struct bio *bio, | 1141 | static int blk_phys_contig_segment(request_queue_t *q, struct bio *bio, |
1141 | struct bio *nxt) | 1142 | struct bio *nxt) |
1142 | { | 1143 | { |
1143 | if (!(q->queue_flags & (1 << QUEUE_FLAG_CLUSTER))) | 1144 | if (!(q->queue_flags & (1 << QUEUE_FLAG_CLUSTER))) |
@@ -1158,9 +1159,7 @@ int blk_phys_contig_segment(request_queue_t *q, struct bio *bio, | |||
1158 | return 0; | 1159 | return 0; |
1159 | } | 1160 | } |
1160 | 1161 | ||
1161 | EXPORT_SYMBOL(blk_phys_contig_segment); | 1162 | static int blk_hw_contig_segment(request_queue_t *q, struct bio *bio, |
1162 | |||
1163 | int blk_hw_contig_segment(request_queue_t *q, struct bio *bio, | ||
1164 | struct bio *nxt) | 1163 | struct bio *nxt) |
1165 | { | 1164 | { |
1166 | if (unlikely(!bio_flagged(bio, BIO_SEG_VALID))) | 1165 | if (unlikely(!bio_flagged(bio, BIO_SEG_VALID))) |
@@ -1176,8 +1175,6 @@ int blk_hw_contig_segment(request_queue_t *q, struct bio *bio, | |||
1176 | return 1; | 1175 | return 1; |
1177 | } | 1176 | } |
1178 | 1177 | ||
1179 | EXPORT_SYMBOL(blk_hw_contig_segment); | ||
1180 | |||
1181 | /* | 1178 | /* |
1182 | * map a request to scatterlist, return number of sg entries setup. Caller | 1179 | * map a request to scatterlist, return number of sg entries setup. Caller |
1183 | * must make sure sg can hold rq->nr_phys_segments entries | 1180 | * must make sure sg can hold rq->nr_phys_segments entries |
@@ -1347,8 +1344,8 @@ static int ll_front_merge_fn(request_queue_t *q, struct request *req, | |||
1347 | static int ll_merge_requests_fn(request_queue_t *q, struct request *req, | 1344 | static int ll_merge_requests_fn(request_queue_t *q, struct request *req, |
1348 | struct request *next) | 1345 | struct request *next) |
1349 | { | 1346 | { |
1350 | int total_phys_segments = req->nr_phys_segments +next->nr_phys_segments; | 1347 | int total_phys_segments; |
1351 | int total_hw_segments = req->nr_hw_segments + next->nr_hw_segments; | 1348 | int total_hw_segments; |
1352 | 1349 | ||
1353 | /* | 1350 | /* |
1354 | * First check if the either of the requests are re-queued | 1351 | * First check if the either of the requests are re-queued |
@@ -1358,7 +1355,7 @@ static int ll_merge_requests_fn(request_queue_t *q, struct request *req, | |||
1358 | return 0; | 1355 | return 0; |
1359 | 1356 | ||
1360 | /* | 1357 | /* |
1361 | * Will it become to large? | 1358 | * Will it become too large? |
1362 | */ | 1359 | */ |
1363 | if ((req->nr_sectors + next->nr_sectors) > q->max_sectors) | 1360 | if ((req->nr_sectors + next->nr_sectors) > q->max_sectors) |
1364 | return 0; | 1361 | return 0; |
@@ -1825,7 +1822,7 @@ static inline int ioc_batching(request_queue_t *q, struct io_context *ioc) | |||
1825 | * is the behaviour we want though - once it gets a wakeup it should be given | 1822 | * is the behaviour we want though - once it gets a wakeup it should be given |
1826 | * a nice run. | 1823 | * a nice run. |
1827 | */ | 1824 | */ |
1828 | void ioc_set_batching(request_queue_t *q, struct io_context *ioc) | 1825 | static void ioc_set_batching(request_queue_t *q, struct io_context *ioc) |
1829 | { | 1826 | { |
1830 | if (!ioc || ioc_batching(q, ioc)) | 1827 | if (!ioc || ioc_batching(q, ioc)) |
1831 | return; | 1828 | return; |
@@ -2254,45 +2251,7 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector) | |||
2254 | 2251 | ||
2255 | EXPORT_SYMBOL(blkdev_issue_flush); | 2252 | EXPORT_SYMBOL(blkdev_issue_flush); |
2256 | 2253 | ||
2257 | /** | 2254 | static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io) |
2258 | * blkdev_scsi_issue_flush_fn - issue flush for SCSI devices | ||
2259 | * @q: device queue | ||
2260 | * @disk: gendisk | ||
2261 | * @error_sector: error offset | ||
2262 | * | ||
2263 | * Description: | ||
2264 | * Devices understanding the SCSI command set, can use this function as | ||
2265 | * a helper for issuing a cache flush. Note: driver is required to store | ||
2266 | * the error offset (in case of error flushing) in ->sector of struct | ||
2267 | * request. | ||
2268 | */ | ||
2269 | int blkdev_scsi_issue_flush_fn(request_queue_t *q, struct gendisk *disk, | ||
2270 | sector_t *error_sector) | ||
2271 | { | ||
2272 | struct request *rq = blk_get_request(q, WRITE, __GFP_WAIT); | ||
2273 | int ret; | ||
2274 | |||
2275 | rq->flags |= REQ_BLOCK_PC | REQ_SOFTBARRIER; | ||
2276 | rq->sector = 0; | ||
2277 | memset(rq->cmd, 0, sizeof(rq->cmd)); | ||
2278 | rq->cmd[0] = 0x35; | ||
2279 | rq->cmd_len = 12; | ||
2280 | rq->data = NULL; | ||
2281 | rq->data_len = 0; | ||
2282 | rq->timeout = 60 * HZ; | ||
2283 | |||
2284 | ret = blk_execute_rq(q, disk, rq); | ||
2285 | |||
2286 | if (ret && error_sector) | ||
2287 | *error_sector = rq->sector; | ||
2288 | |||
2289 | blk_put_request(rq); | ||
2290 | return ret; | ||
2291 | } | ||
2292 | |||
2293 | EXPORT_SYMBOL(blkdev_scsi_issue_flush_fn); | ||
2294 | |||
2295 | void drive_stat_acct(struct request *rq, int nr_sectors, int new_io) | ||
2296 | { | 2255 | { |
2297 | int rw = rq_data_dir(rq); | 2256 | int rw = rq_data_dir(rq); |
2298 | 2257 | ||
@@ -2551,16 +2510,6 @@ void blk_attempt_remerge(request_queue_t *q, struct request *rq) | |||
2551 | 2510 | ||
2552 | EXPORT_SYMBOL(blk_attempt_remerge); | 2511 | EXPORT_SYMBOL(blk_attempt_remerge); |
2553 | 2512 | ||
2554 | /* | ||
2555 | * Non-locking blk_attempt_remerge variant. | ||
2556 | */ | ||
2557 | void __blk_attempt_remerge(request_queue_t *q, struct request *rq) | ||
2558 | { | ||
2559 | attempt_back_merge(q, rq); | ||
2560 | } | ||
2561 | |||
2562 | EXPORT_SYMBOL(__blk_attempt_remerge); | ||
2563 | |||
2564 | static int __make_request(request_queue_t *q, struct bio *bio) | 2513 | static int __make_request(request_queue_t *q, struct bio *bio) |
2565 | { | 2514 | { |
2566 | struct request *req, *freereq = NULL; | 2515 | struct request *req, *freereq = NULL; |
@@ -2971,7 +2920,7 @@ void submit_bio(int rw, struct bio *bio) | |||
2971 | 2920 | ||
2972 | EXPORT_SYMBOL(submit_bio); | 2921 | EXPORT_SYMBOL(submit_bio); |
2973 | 2922 | ||
2974 | void blk_recalc_rq_segments(struct request *rq) | 2923 | static void blk_recalc_rq_segments(struct request *rq) |
2975 | { | 2924 | { |
2976 | struct bio *bio, *prevbio = NULL; | 2925 | struct bio *bio, *prevbio = NULL; |
2977 | int nr_phys_segs, nr_hw_segs; | 2926 | int nr_phys_segs, nr_hw_segs; |
@@ -3013,7 +2962,7 @@ void blk_recalc_rq_segments(struct request *rq) | |||
3013 | rq->nr_hw_segments = nr_hw_segs; | 2962 | rq->nr_hw_segments = nr_hw_segs; |
3014 | } | 2963 | } |
3015 | 2964 | ||
3016 | void blk_recalc_rq_sectors(struct request *rq, int nsect) | 2965 | static void blk_recalc_rq_sectors(struct request *rq, int nsect) |
3017 | { | 2966 | { |
3018 | if (blk_fs_request(rq)) { | 2967 | if (blk_fs_request(rq)) { |
3019 | rq->hard_sector += nsect; | 2968 | rq->hard_sector += nsect; |
@@ -3601,7 +3550,7 @@ static struct sysfs_ops queue_sysfs_ops = { | |||
3601 | .store = queue_attr_store, | 3550 | .store = queue_attr_store, |
3602 | }; | 3551 | }; |
3603 | 3552 | ||
3604 | struct kobj_type queue_ktype = { | 3553 | static struct kobj_type queue_ktype = { |
3605 | .sysfs_ops = &queue_sysfs_ops, | 3554 | .sysfs_ops = &queue_sysfs_ops, |
3606 | .default_attrs = default_attrs, | 3555 | .default_attrs = default_attrs, |
3607 | }; | 3556 | }; |
diff --git a/drivers/cdrom/cm206.c b/drivers/cdrom/cm206.c index da80b14335a5..01f035173328 100644 --- a/drivers/cdrom/cm206.c +++ b/drivers/cdrom/cm206.c | |||
@@ -307,7 +307,7 @@ static DEFINE_SPINLOCK(cm206_lock); | |||
307 | /* First, we define some polling functions. These are actually | 307 | /* First, we define some polling functions. These are actually |
308 | only being used in the initialization. */ | 308 | only being used in the initialization. */ |
309 | 309 | ||
310 | void send_command_polled(int command) | 310 | static void send_command_polled(int command) |
311 | { | 311 | { |
312 | int loop = POLLOOP; | 312 | int loop = POLLOOP; |
313 | while (!(inw(r_line_status) & ls_transmitter_buffer_empty) | 313 | while (!(inw(r_line_status) & ls_transmitter_buffer_empty) |
@@ -318,7 +318,7 @@ void send_command_polled(int command) | |||
318 | outw(command, r_uart_transmit); | 318 | outw(command, r_uart_transmit); |
319 | } | 319 | } |
320 | 320 | ||
321 | uch receive_echo_polled(void) | 321 | static uch receive_echo_polled(void) |
322 | { | 322 | { |
323 | int loop = POLLOOP; | 323 | int loop = POLLOOP; |
324 | while (!(inw(r_line_status) & ls_receive_buffer_full) && loop > 0) { | 324 | while (!(inw(r_line_status) & ls_receive_buffer_full) && loop > 0) { |
@@ -328,13 +328,13 @@ uch receive_echo_polled(void) | |||
328 | return ((uch) inw(r_uart_receive)); | 328 | return ((uch) inw(r_uart_receive)); |
329 | } | 329 | } |
330 | 330 | ||
331 | uch send_receive_polled(int command) | 331 | static uch send_receive_polled(int command) |
332 | { | 332 | { |
333 | send_command_polled(command); | 333 | send_command_polled(command); |
334 | return receive_echo_polled(); | 334 | return receive_echo_polled(); |
335 | } | 335 | } |
336 | 336 | ||
337 | inline void clear_ur(void) | 337 | static inline void clear_ur(void) |
338 | { | 338 | { |
339 | if (cd->ur_r != cd->ur_w) { | 339 | if (cd->ur_r != cd->ur_w) { |
340 | debug(("Deleting bytes from fifo:")); | 340 | debug(("Deleting bytes from fifo:")); |
@@ -439,7 +439,7 @@ static irqreturn_t cm206_interrupt(int sig, void *dev_id, struct pt_regs *regs) | |||
439 | } | 439 | } |
440 | 440 | ||
441 | /* we have put the address of the wait queue in who */ | 441 | /* we have put the address of the wait queue in who */ |
442 | void cm206_timeout(unsigned long who) | 442 | static void cm206_timeout(unsigned long who) |
443 | { | 443 | { |
444 | cd->timed_out = 1; | 444 | cd->timed_out = 1; |
445 | debug(("Timing out\n")); | 445 | debug(("Timing out\n")); |
@@ -448,7 +448,7 @@ void cm206_timeout(unsigned long who) | |||
448 | 448 | ||
449 | /* This function returns 1 if a timeout occurred, 0 if an interrupt | 449 | /* This function returns 1 if a timeout occurred, 0 if an interrupt |
450 | happened */ | 450 | happened */ |
451 | int sleep_or_timeout(wait_queue_head_t * wait, int timeout) | 451 | static int sleep_or_timeout(wait_queue_head_t * wait, int timeout) |
452 | { | 452 | { |
453 | cd->timed_out = 0; | 453 | cd->timed_out = 0; |
454 | init_timer(&cd->timer); | 454 | init_timer(&cd->timer); |
@@ -465,13 +465,7 @@ int sleep_or_timeout(wait_queue_head_t * wait, int timeout) | |||
465 | return 0; | 465 | return 0; |
466 | } | 466 | } |
467 | 467 | ||
468 | void cm206_delay(int nr_jiffies) | 468 | static void send_command(int command) |
469 | { | ||
470 | DECLARE_WAIT_QUEUE_HEAD(wait); | ||
471 | sleep_or_timeout(&wait, nr_jiffies); | ||
472 | } | ||
473 | |||
474 | void send_command(int command) | ||
475 | { | 469 | { |
476 | debug(("Sending 0x%x\n", command)); | 470 | debug(("Sending 0x%x\n", command)); |
477 | if (!(inw(r_line_status) & ls_transmitter_buffer_empty)) { | 471 | if (!(inw(r_line_status) & ls_transmitter_buffer_empty)) { |
@@ -490,7 +484,7 @@ void send_command(int command) | |||
490 | outw(command, r_uart_transmit); | 484 | outw(command, r_uart_transmit); |
491 | } | 485 | } |
492 | 486 | ||
493 | uch receive_byte(int timeout) | 487 | static uch receive_byte(int timeout) |
494 | { | 488 | { |
495 | uch ret; | 489 | uch ret; |
496 | cli(); | 490 | cli(); |
@@ -521,23 +515,23 @@ uch receive_byte(int timeout) | |||
521 | return ret; | 515 | return ret; |
522 | } | 516 | } |
523 | 517 | ||
524 | inline uch receive_echo(void) | 518 | static inline uch receive_echo(void) |
525 | { | 519 | { |
526 | return receive_byte(UART_TIMEOUT); | 520 | return receive_byte(UART_TIMEOUT); |
527 | } | 521 | } |
528 | 522 | ||
529 | inline uch send_receive(int command) | 523 | static inline uch send_receive(int command) |
530 | { | 524 | { |
531 | send_command(command); | 525 | send_command(command); |
532 | return receive_echo(); | 526 | return receive_echo(); |
533 | } | 527 | } |
534 | 528 | ||
535 | inline uch wait_dsb(void) | 529 | static inline uch wait_dsb(void) |
536 | { | 530 | { |
537 | return receive_byte(DSB_TIMEOUT); | 531 | return receive_byte(DSB_TIMEOUT); |
538 | } | 532 | } |
539 | 533 | ||
540 | int type_0_command(int command, int expect_dsb) | 534 | static int type_0_command(int command, int expect_dsb) |
541 | { | 535 | { |
542 | int e; | 536 | int e; |
543 | clear_ur(); | 537 | clear_ur(); |
@@ -552,7 +546,7 @@ int type_0_command(int command, int expect_dsb) | |||
552 | return 0; | 546 | return 0; |
553 | } | 547 | } |
554 | 548 | ||
555 | int type_1_command(int command, int bytes, uch * status) | 549 | static int type_1_command(int command, int bytes, uch * status) |
556 | { /* returns info */ | 550 | { /* returns info */ |
557 | int i; | 551 | int i; |
558 | if (type_0_command(command, 0)) | 552 | if (type_0_command(command, 0)) |
@@ -564,7 +558,7 @@ int type_1_command(int command, int bytes, uch * status) | |||
564 | 558 | ||
565 | /* This function resets the adapter card. We'd better not do this too | 559 | /* This function resets the adapter card. We'd better not do this too |
566 | * often, because it tends to generate `lost interrupts.' */ | 560 | * often, because it tends to generate `lost interrupts.' */ |
567 | void reset_cm260(void) | 561 | static void reset_cm260(void) |
568 | { | 562 | { |
569 | outw(dc_normal | dc_initialize | READ_AHEAD, r_data_control); | 563 | outw(dc_normal | dc_initialize | READ_AHEAD, r_data_control); |
570 | udelay(10); /* 3.3 mu sec minimum */ | 564 | udelay(10); /* 3.3 mu sec minimum */ |
@@ -572,7 +566,7 @@ void reset_cm260(void) | |||
572 | } | 566 | } |
573 | 567 | ||
574 | /* fsm: frame-sec-min from linear address; one of many */ | 568 | /* fsm: frame-sec-min from linear address; one of many */ |
575 | void fsm(int lba, uch * fsm) | 569 | static void fsm(int lba, uch * fsm) |
576 | { | 570 | { |
577 | fsm[0] = lba % 75; | 571 | fsm[0] = lba % 75; |
578 | lba /= 75; | 572 | lba /= 75; |
@@ -581,17 +575,17 @@ void fsm(int lba, uch * fsm) | |||
581 | fsm[2] = lba / 60; | 575 | fsm[2] = lba / 60; |
582 | } | 576 | } |
583 | 577 | ||
584 | inline int fsm2lba(uch * fsm) | 578 | static inline int fsm2lba(uch * fsm) |
585 | { | 579 | { |
586 | return fsm[0] + 75 * (fsm[1] - 2 + 60 * fsm[2]); | 580 | return fsm[0] + 75 * (fsm[1] - 2 + 60 * fsm[2]); |
587 | } | 581 | } |
588 | 582 | ||
589 | inline int f_s_m2lba(uch f, uch s, uch m) | 583 | static inline int f_s_m2lba(uch f, uch s, uch m) |
590 | { | 584 | { |
591 | return f + 75 * (s - 2 + 60 * m); | 585 | return f + 75 * (s - 2 + 60 * m); |
592 | } | 586 | } |
593 | 587 | ||
594 | int start_read(int start) | 588 | static int start_read(int start) |
595 | { | 589 | { |
596 | uch read_sector[4] = { c_read_data, }; | 590 | uch read_sector[4] = { c_read_data, }; |
597 | int i, e; | 591 | int i, e; |
@@ -613,7 +607,7 @@ int start_read(int start) | |||
613 | return 0; | 607 | return 0; |
614 | } | 608 | } |
615 | 609 | ||
616 | int stop_read(void) | 610 | static int stop_read(void) |
617 | { | 611 | { |
618 | int e; | 612 | int e; |
619 | type_0_command(c_stop, 0); | 613 | type_0_command(c_stop, 0); |
@@ -630,7 +624,7 @@ int stop_read(void) | |||
630 | routine takes care of this. Set a flag `background' in the cd | 624 | routine takes care of this. Set a flag `background' in the cd |
631 | struct to indicate the process. */ | 625 | struct to indicate the process. */ |
632 | 626 | ||
633 | int read_background(int start, int reading) | 627 | static int read_background(int start, int reading) |
634 | { | 628 | { |
635 | if (cd->background) | 629 | if (cd->background) |
636 | return -1; /* can't do twice */ | 630 | return -1; /* can't do twice */ |
@@ -658,7 +652,7 @@ void transport_data(int port, ush * dest, int count) | |||
658 | 652 | ||
659 | 653 | ||
660 | #define MAX_TRIES 100 | 654 | #define MAX_TRIES 100 |
661 | int read_sector(int start) | 655 | static int read_sector(int start) |
662 | { | 656 | { |
663 | int tries = 0; | 657 | int tries = 0; |
664 | if (cd->background) { | 658 | if (cd->background) { |
@@ -753,7 +747,7 @@ static DECLARE_TASKLET(cm206_tasklet, cm206_tasklet_func, 0); | |||
753 | /* This command clears the dsb_possible_media_change flag, so we must | 747 | /* This command clears the dsb_possible_media_change flag, so we must |
754 | * retain it. | 748 | * retain it. |
755 | */ | 749 | */ |
756 | void get_drive_status(void) | 750 | static void get_drive_status(void) |
757 | { | 751 | { |
758 | uch status[2]; | 752 | uch status[2]; |
759 | type_1_command(c_drive_status, 2, status); /* this might be done faster */ | 753 | type_1_command(c_drive_status, 2, status); /* this might be done faster */ |
@@ -764,7 +758,7 @@ void get_drive_status(void) | |||
764 | dsb_drive_not_ready | dsb_tray_not_closed)); | 758 | dsb_drive_not_ready | dsb_tray_not_closed)); |
765 | } | 759 | } |
766 | 760 | ||
767 | void get_disc_status(void) | 761 | static void get_disc_status(void) |
768 | { | 762 | { |
769 | if (type_1_command(c_disc_status, 7, cd->disc_status)) { | 763 | if (type_1_command(c_disc_status, 7, cd->disc_status)) { |
770 | debug(("get_disc_status: error\n")); | 764 | debug(("get_disc_status: error\n")); |
@@ -801,7 +795,7 @@ static void cm206_release(struct cdrom_device_info *cdi) | |||
801 | 795 | ||
802 | /* Empty buffer empties $sectors$ sectors of the adapter card buffer, | 796 | /* Empty buffer empties $sectors$ sectors of the adapter card buffer, |
803 | * and then reads a sector in kernel memory. */ | 797 | * and then reads a sector in kernel memory. */ |
804 | void empty_buffer(int sectors) | 798 | static void empty_buffer(int sectors) |
805 | { | 799 | { |
806 | while (sectors >= 0) { | 800 | while (sectors >= 0) { |
807 | transport_data(r_fifo_output_buffer, | 801 | transport_data(r_fifo_output_buffer, |
@@ -819,7 +813,7 @@ void empty_buffer(int sectors) | |||
819 | /* try_adapter. This function determines if the requested sector is | 813 | /* try_adapter. This function determines if the requested sector is |
820 | in adapter memory, or will appear there soon. Returns 0 upon | 814 | in adapter memory, or will appear there soon. Returns 0 upon |
821 | success */ | 815 | success */ |
822 | int try_adapter(int sector) | 816 | static int try_adapter(int sector) |
823 | { | 817 | { |
824 | if (cd->adapter_first <= sector && sector < cd->adapter_last) { | 818 | if (cd->adapter_first <= sector && sector < cd->adapter_last) { |
825 | /* sector is in adapter memory */ | 819 | /* sector is in adapter memory */ |
@@ -910,7 +904,7 @@ static void do_cm206_request(request_queue_t * q) | |||
910 | */ | 904 | */ |
911 | 905 | ||
912 | /* seek seeks to address lba. It does wait to arrive there. */ | 906 | /* seek seeks to address lba. It does wait to arrive there. */ |
913 | void seek(int lba) | 907 | static void seek(int lba) |
914 | { | 908 | { |
915 | int i; | 909 | int i; |
916 | uch seek_command[4] = { c_seek, }; | 910 | uch seek_command[4] = { c_seek, }; |
@@ -926,7 +920,7 @@ uch bcdbin(unsigned char bcd) | |||
926 | return (bcd >> 4) * 10 + (bcd & 0xf); | 920 | return (bcd >> 4) * 10 + (bcd & 0xf); |
927 | } | 921 | } |
928 | 922 | ||
929 | inline uch normalize_track(uch track) | 923 | static inline uch normalize_track(uch track) |
930 | { | 924 | { |
931 | if (track < 1) | 925 | if (track < 1) |
932 | return 1; | 926 | return 1; |
@@ -939,7 +933,7 @@ inline uch normalize_track(uch track) | |||
939 | * tracks seen in the process. Input $track$ must be between 1 and | 933 | * tracks seen in the process. Input $track$ must be between 1 and |
940 | * #-of-tracks+1. Note that the start of the disc must be in toc[1].fsm. | 934 | * #-of-tracks+1. Note that the start of the disc must be in toc[1].fsm. |
941 | */ | 935 | */ |
942 | int get_toc_lba(uch track) | 936 | static int get_toc_lba(uch track) |
943 | { | 937 | { |
944 | int max = 74 * 60 * 75 - 150, min = fsm2lba(cd->toc[1].fsm); | 938 | int max = 74 * 60 * 75 - 150, min = fsm2lba(cd->toc[1].fsm); |
945 | int i, lba, l, old_lba = 0; | 939 | int i, lba, l, old_lba = 0; |
@@ -991,7 +985,7 @@ int get_toc_lba(uch track) | |||
991 | return lba; | 985 | return lba; |
992 | } | 986 | } |
993 | 987 | ||
994 | void update_toc_entry(uch track) | 988 | static void update_toc_entry(uch track) |
995 | { | 989 | { |
996 | track = normalize_track(track); | 990 | track = normalize_track(track); |
997 | if (!cd->toc[track].track) | 991 | if (!cd->toc[track].track) |
@@ -999,7 +993,7 @@ void update_toc_entry(uch track) | |||
999 | } | 993 | } |
1000 | 994 | ||
1001 | /* return 0 upon success */ | 995 | /* return 0 upon success */ |
1002 | int read_toc_header(struct cdrom_tochdr *hp) | 996 | static int read_toc_header(struct cdrom_tochdr *hp) |
1003 | { | 997 | { |
1004 | if (!FIRST_TRACK) | 998 | if (!FIRST_TRACK) |
1005 | get_disc_status(); | 999 | get_disc_status(); |
@@ -1016,7 +1010,7 @@ int read_toc_header(struct cdrom_tochdr *hp) | |||
1016 | return -1; | 1010 | return -1; |
1017 | } | 1011 | } |
1018 | 1012 | ||
1019 | void play_from_to_msf(struct cdrom_msf *msfp) | 1013 | static void play_from_to_msf(struct cdrom_msf *msfp) |
1020 | { | 1014 | { |
1021 | uch play_command[] = { c_play, | 1015 | uch play_command[] = { c_play, |
1022 | msfp->cdmsf_frame0, msfp->cdmsf_sec0, msfp->cdmsf_min0, | 1016 | msfp->cdmsf_frame0, msfp->cdmsf_sec0, msfp->cdmsf_min0, |
@@ -1032,7 +1026,7 @@ void play_from_to_msf(struct cdrom_msf *msfp) | |||
1032 | cd->dsb = wait_dsb(); | 1026 | cd->dsb = wait_dsb(); |
1033 | } | 1027 | } |
1034 | 1028 | ||
1035 | void play_from_to_track(int from, int to) | 1029 | static void play_from_to_track(int from, int to) |
1036 | { | 1030 | { |
1037 | uch play_command[8] = { c_play, }; | 1031 | uch play_command[8] = { c_play, }; |
1038 | int i; | 1032 | int i; |
@@ -1059,7 +1053,7 @@ void play_from_to_track(int from, int to) | |||
1059 | cd->dsb = wait_dsb(); | 1053 | cd->dsb = wait_dsb(); |
1060 | } | 1054 | } |
1061 | 1055 | ||
1062 | int get_current_q(struct cdrom_subchnl *qp) | 1056 | static int get_current_q(struct cdrom_subchnl *qp) |
1063 | { | 1057 | { |
1064 | int i; | 1058 | int i; |
1065 | uch *q = cd->q; | 1059 | uch *q = cd->q; |
@@ -1093,14 +1087,14 @@ int get_current_q(struct cdrom_subchnl *qp) | |||
1093 | return 0; | 1087 | return 0; |
1094 | } | 1088 | } |
1095 | 1089 | ||
1096 | void invalidate_toc(void) | 1090 | static void invalidate_toc(void) |
1097 | { | 1091 | { |
1098 | memset(cd->toc, 0, sizeof(cd->toc)); | 1092 | memset(cd->toc, 0, sizeof(cd->toc)); |
1099 | memset(cd->disc_status, 0, sizeof(cd->disc_status)); | 1093 | memset(cd->disc_status, 0, sizeof(cd->disc_status)); |
1100 | } | 1094 | } |
1101 | 1095 | ||
1102 | /* cdrom.c guarantees that cdte_format == CDROM_MSF */ | 1096 | /* cdrom.c guarantees that cdte_format == CDROM_MSF */ |
1103 | void get_toc_entry(struct cdrom_tocentry *ep) | 1097 | static void get_toc_entry(struct cdrom_tocentry *ep) |
1104 | { | 1098 | { |
1105 | uch track = normalize_track(ep->cdte_track); | 1099 | uch track = normalize_track(ep->cdte_track); |
1106 | update_toc_entry(track); | 1100 | update_toc_entry(track); |
@@ -1117,8 +1111,8 @@ void get_toc_entry(struct cdrom_tocentry *ep) | |||
1117 | * upon success. Memory checking has been done by cdrom_ioctl(), the | 1111 | * upon success. Memory checking has been done by cdrom_ioctl(), the |
1118 | * calling function, as well as LBA/MSF sanitization. | 1112 | * calling function, as well as LBA/MSF sanitization. |
1119 | */ | 1113 | */ |
1120 | int cm206_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, | 1114 | static int cm206_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, |
1121 | void *arg) | 1115 | void *arg) |
1122 | { | 1116 | { |
1123 | switch (cmd) { | 1117 | switch (cmd) { |
1124 | case CDROMREADTOCHDR: | 1118 | case CDROMREADTOCHDR: |
@@ -1189,7 +1183,7 @@ static int cm206_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, | |||
1189 | } | 1183 | } |
1190 | } | 1184 | } |
1191 | 1185 | ||
1192 | int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr) | 1186 | static int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr) |
1193 | { | 1187 | { |
1194 | if (cd != NULL) { | 1188 | if (cd != NULL) { |
1195 | int r; | 1189 | int r; |
@@ -1204,16 +1198,9 @@ int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr) | |||
1204 | /* The new generic cdrom support. Routines should be concise, most of | 1198 | /* The new generic cdrom support. Routines should be concise, most of |
1205 | the logic should be in cdrom.c */ | 1199 | the logic should be in cdrom.c */ |
1206 | 1200 | ||
1207 | /* returns number of times device is in use */ | ||
1208 | int cm206_open_files(struct cdrom_device_info *cdi) | ||
1209 | { | ||
1210 | if (cd) | ||
1211 | return cd->openfiles; | ||
1212 | return -1; | ||
1213 | } | ||
1214 | 1201 | ||
1215 | /* controls tray movement */ | 1202 | /* controls tray movement */ |
1216 | int cm206_tray_move(struct cdrom_device_info *cdi, int position) | 1203 | static int cm206_tray_move(struct cdrom_device_info *cdi, int position) |
1217 | { | 1204 | { |
1218 | if (position) { /* 1: eject */ | 1205 | if (position) { /* 1: eject */ |
1219 | type_0_command(c_open_tray, 1); | 1206 | type_0_command(c_open_tray, 1); |
@@ -1224,7 +1211,7 @@ int cm206_tray_move(struct cdrom_device_info *cdi, int position) | |||
1224 | } | 1211 | } |
1225 | 1212 | ||
1226 | /* gives current state of the drive */ | 1213 | /* gives current state of the drive */ |
1227 | int cm206_drive_status(struct cdrom_device_info *cdi, int slot_nr) | 1214 | static int cm206_drive_status(struct cdrom_device_info *cdi, int slot_nr) |
1228 | { | 1215 | { |
1229 | get_drive_status(); | 1216 | get_drive_status(); |
1230 | if (cd->dsb & dsb_tray_not_closed) | 1217 | if (cd->dsb & dsb_tray_not_closed) |
@@ -1237,7 +1224,7 @@ int cm206_drive_status(struct cdrom_device_info *cdi, int slot_nr) | |||
1237 | } | 1224 | } |
1238 | 1225 | ||
1239 | /* locks or unlocks door lock==1: lock; return 0 upon success */ | 1226 | /* locks or unlocks door lock==1: lock; return 0 upon success */ |
1240 | int cm206_lock_door(struct cdrom_device_info *cdi, int lock) | 1227 | static int cm206_lock_door(struct cdrom_device_info *cdi, int lock) |
1241 | { | 1228 | { |
1242 | uch command = (lock) ? c_lock_tray : c_unlock_tray; | 1229 | uch command = (lock) ? c_lock_tray : c_unlock_tray; |
1243 | type_0_command(command, 1); /* wait and get dsb */ | 1230 | type_0_command(command, 1); /* wait and get dsb */ |
@@ -1248,8 +1235,8 @@ int cm206_lock_door(struct cdrom_device_info *cdi, int lock) | |||
1248 | /* Although a session start should be in LBA format, we return it in | 1235 | /* Although a session start should be in LBA format, we return it in |
1249 | MSF format because it is slightly easier, and the new generic ioctl | 1236 | MSF format because it is slightly easier, and the new generic ioctl |
1250 | will take care of the necessary conversion. */ | 1237 | will take care of the necessary conversion. */ |
1251 | int cm206_get_last_session(struct cdrom_device_info *cdi, | 1238 | static int cm206_get_last_session(struct cdrom_device_info *cdi, |
1252 | struct cdrom_multisession *mssp) | 1239 | struct cdrom_multisession *mssp) |
1253 | { | 1240 | { |
1254 | if (!FIRST_TRACK) | 1241 | if (!FIRST_TRACK) |
1255 | get_disc_status(); | 1242 | get_disc_status(); |
@@ -1268,7 +1255,7 @@ int cm206_get_last_session(struct cdrom_device_info *cdi, | |||
1268 | return 0; | 1255 | return 0; |
1269 | } | 1256 | } |
1270 | 1257 | ||
1271 | int cm206_get_upc(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn) | 1258 | static int cm206_get_upc(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn) |
1272 | { | 1259 | { |
1273 | uch upc[10]; | 1260 | uch upc[10]; |
1274 | char *ret = mcn->medium_catalog_number; | 1261 | char *ret = mcn->medium_catalog_number; |
@@ -1287,7 +1274,7 @@ int cm206_get_upc(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn) | |||
1287 | return 0; | 1274 | return 0; |
1288 | } | 1275 | } |
1289 | 1276 | ||
1290 | int cm206_reset(struct cdrom_device_info *cdi) | 1277 | static int cm206_reset(struct cdrom_device_info *cdi) |
1291 | { | 1278 | { |
1292 | stop_read(); | 1279 | stop_read(); |
1293 | reset_cm260(); | 1280 | reset_cm260(); |
@@ -1300,7 +1287,7 @@ int cm206_reset(struct cdrom_device_info *cdi) | |||
1300 | return 0; | 1287 | return 0; |
1301 | } | 1288 | } |
1302 | 1289 | ||
1303 | int cm206_select_speed(struct cdrom_device_info *cdi, int speed) | 1290 | static int cm206_select_speed(struct cdrom_device_info *cdi, int speed) |
1304 | { | 1291 | { |
1305 | int r; | 1292 | int r; |
1306 | switch (speed) { | 1293 | switch (speed) { |
@@ -1392,7 +1379,7 @@ static struct gendisk *cm206_gendisk; | |||
1392 | request_region, 15 bits of one port and 6 of another make things | 1379 | request_region, 15 bits of one port and 6 of another make things |
1393 | likely enough to accept the region on the first hit... | 1380 | likely enough to accept the region on the first hit... |
1394 | */ | 1381 | */ |
1395 | int __init probe_base_port(int base) | 1382 | static int __init probe_base_port(int base) |
1396 | { | 1383 | { |
1397 | int b = 0x300, e = 0x370; /* this is the range of start addresses */ | 1384 | int b = 0x300, e = 0x370; /* this is the range of start addresses */ |
1398 | volatile int fool, i; | 1385 | volatile int fool, i; |
@@ -1416,7 +1403,7 @@ int __init probe_base_port(int base) | |||
1416 | 1403 | ||
1417 | #if !defined(MODULE) || defined(AUTO_PROBE_MODULE) | 1404 | #if !defined(MODULE) || defined(AUTO_PROBE_MODULE) |
1418 | /* Probe for irq# nr. If nr==0, probe for all possible irq's. */ | 1405 | /* Probe for irq# nr. If nr==0, probe for all possible irq's. */ |
1419 | int __init probe_irq(int nr) | 1406 | static int __init probe_irq(int nr) |
1420 | { | 1407 | { |
1421 | int irqs, irq; | 1408 | int irqs, irq; |
1422 | outw(dc_normal | READ_AHEAD, r_data_control); /* disable irq-generation */ | 1409 | outw(dc_normal | READ_AHEAD, r_data_control); /* disable irq-generation */ |
@@ -1558,7 +1545,7 @@ static void __init parse_options(void) | |||
1558 | } | 1545 | } |
1559 | } | 1546 | } |
1560 | 1547 | ||
1561 | int __cm206_init(void) | 1548 | static int __cm206_init(void) |
1562 | { | 1549 | { |
1563 | parse_options(); | 1550 | parse_options(); |
1564 | #if !defined(AUTO_PROBE_MODULE) | 1551 | #if !defined(AUTO_PROBE_MODULE) |
@@ -1567,7 +1554,7 @@ int __cm206_init(void) | |||
1567 | return cm206_init(); | 1554 | return cm206_init(); |
1568 | } | 1555 | } |
1569 | 1556 | ||
1570 | void __exit cm206_exit(void) | 1557 | static void __exit cm206_exit(void) |
1571 | { | 1558 | { |
1572 | del_gendisk(cm206_gendisk); | 1559 | del_gendisk(cm206_gendisk); |
1573 | put_disk(cm206_gendisk); | 1560 | put_disk(cm206_gendisk); |
diff --git a/drivers/cdrom/sonycd535.c b/drivers/cdrom/sonycd535.c index f4be7bfd6675..9f22e8f1f6c0 100644 --- a/drivers/cdrom/sonycd535.c +++ b/drivers/cdrom/sonycd535.c | |||
@@ -1605,8 +1605,7 @@ out7: | |||
1605 | put_disk(cdu_disk); | 1605 | put_disk(cdu_disk); |
1606 | out6: | 1606 | out6: |
1607 | for (i = 0; i < sony_buffer_sectors; i++) | 1607 | for (i = 0; i < sony_buffer_sectors; i++) |
1608 | if (sony_buffer[i]) | 1608 | kfree(sony_buffer[i]); |
1609 | kfree(sony_buffer[i]); | ||
1610 | out5: | 1609 | out5: |
1611 | kfree(sony_buffer); | 1610 | kfree(sony_buffer); |
1612 | out4: | 1611 | out4: |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 7ccf871d3c9d..43d0cb19ef6a 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -940,8 +940,8 @@ config RAW_DRIVER | |||
940 | Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O. | 940 | Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O. |
941 | See the raw(8) manpage for more details. | 941 | See the raw(8) manpage for more details. |
942 | 942 | ||
943 | The raw driver is deprecated and may be removed from 2.7 | 943 | The raw driver is deprecated and will be removed soon. |
944 | kernels. Applications should simply open the device (eg /dev/hda1) | 944 | Applications should simply open the device (eg /dev/hda1) |
945 | with the O_DIRECT flag. | 945 | with the O_DIRECT flag. |
946 | 946 | ||
947 | config HPET | 947 | config HPET |
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index 777bc499bbbd..2a36561eec68 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c | |||
@@ -1973,10 +1973,6 @@ static _INLINE_ void show_serial_version(void) | |||
1973 | } | 1973 | } |
1974 | 1974 | ||
1975 | 1975 | ||
1976 | int register_serial(struct serial_struct *req); | ||
1977 | void unregister_serial(int line); | ||
1978 | |||
1979 | |||
1980 | static struct tty_operations serial_ops = { | 1976 | static struct tty_operations serial_ops = { |
1981 | .open = rs_open, | 1977 | .open = rs_open, |
1982 | .close = rs_close, | 1978 | .close = rs_close, |
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c index 6bf2e27dc23a..11f9ee581124 100644 --- a/drivers/char/applicom.c +++ b/drivers/char/applicom.c | |||
@@ -599,7 +599,7 @@ static ssize_t ac_read (struct file *filp, char __user *buf, size_t count, loff_ | |||
599 | 599 | ||
600 | #ifdef DEBUG | 600 | #ifdef DEBUG |
601 | if (loopcount++ > 2) { | 601 | if (loopcount++ > 2) { |
602 | printk("Looping in ac_read. loopcount %d\n", loopcount); | 602 | printk(KERN_DEBUG "Looping in ac_read. loopcount %d\n", loopcount); |
603 | } | 603 | } |
604 | #endif | 604 | #endif |
605 | } | 605 | } |
diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c index 7def6ad51798..62cda25724e3 100644 --- a/drivers/char/ds1620.c +++ b/drivers/char/ds1620.c | |||
@@ -163,8 +163,7 @@ static void ds1620_out(int cmd, int bits, int value) | |||
163 | netwinder_ds1620_reset(); | 163 | netwinder_ds1620_reset(); |
164 | netwinder_unlock(&flags); | 164 | netwinder_unlock(&flags); |
165 | 165 | ||
166 | set_current_state(TASK_INTERRUPTIBLE); | 166 | msleep(20); |
167 | schedule_timeout(2); | ||
168 | } | 167 | } |
169 | 168 | ||
170 | static unsigned int ds1620_in(int cmd, int bits) | 169 | static unsigned int ds1620_in(int cmd, int bits) |
diff --git a/drivers/char/ftape/compressor/zftape-compress.c b/drivers/char/ftape/compressor/zftape-compress.c index 220a227e6061..65ffc0be3df9 100644 --- a/drivers/char/ftape/compressor/zftape-compress.c +++ b/drivers/char/ftape/compressor/zftape-compress.c | |||
@@ -1176,8 +1176,8 @@ KERN_INFO "Compressor for zftape (lzrw3 algorithm)\n"); | |||
1176 | } | 1176 | } |
1177 | #else /* !MODULE */ | 1177 | #else /* !MODULE */ |
1178 | /* print a short no-nonsense boot message */ | 1178 | /* print a short no-nonsense boot message */ |
1179 | printk("zftape compressor v1.00a 970514\n"); | 1179 | printk(KERN_INFO "zftape compressor v1.00a 970514\n"); |
1180 | printk("For use with " FTAPE_VERSION "\n"); | 1180 | printk(KERN_INFO "For use with " FTAPE_VERSION "\n"); |
1181 | #endif /* MODULE */ | 1181 | #endif /* MODULE */ |
1182 | TRACE(ft_t_info, "zft_compressor_init @ 0x%p", zft_compressor_init); | 1182 | TRACE(ft_t_info, "zft_compressor_init @ 0x%p", zft_compressor_init); |
1183 | TRACE(ft_t_info, "installing compressor for zftape ..."); | 1183 | TRACE(ft_t_info, "installing compressor for zftape ..."); |
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 5ec732e6ca92..762fa430fb5b 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
@@ -834,7 +834,7 @@ int hpet_alloc(struct hpet_data *hdp) | |||
834 | printk("\n"); | 834 | printk("\n"); |
835 | 835 | ||
836 | ns = hpetp->hp_period; /* femptoseconds, 10^-15 */ | 836 | ns = hpetp->hp_period; /* femptoseconds, 10^-15 */ |
837 | do_div(ns, 1000000); /* convert to nanoseconds, 10^-9 */ | 837 | ns /= 1000000; /* convert to nanoseconds, 10^-9 */ |
838 | printk(KERN_INFO "hpet%d: %ldns tick, %d %d-bit timers\n", | 838 | printk(KERN_INFO "hpet%d: %ldns tick, %d %d-bit timers\n", |
839 | hpetp->hp_which, ns, hpetp->hp_ntimer, | 839 | hpetp->hp_which, ns, hpetp->hp_ntimer, |
840 | cap & HPET_COUNTER_SIZE_MASK ? 64 : 32); | 840 | cap & HPET_COUNTER_SIZE_MASK ? 64 : 32); |
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c index a81197640283..6c4b3f986d0c 100644 --- a/drivers/char/i8k.c +++ b/drivers/char/i8k.c | |||
@@ -20,13 +20,14 @@ | |||
20 | #include <linux/types.h> | 20 | #include <linux/types.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/proc_fs.h> | 22 | #include <linux/proc_fs.h> |
23 | #include <linux/apm_bios.h> | 23 | #include <linux/seq_file.h> |
24 | #include <linux/dmi.h> | ||
24 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
25 | #include <asm/io.h> | 26 | #include <asm/io.h> |
26 | 27 | ||
27 | #include <linux/i8k.h> | 28 | #include <linux/i8k.h> |
28 | 29 | ||
29 | #define I8K_VERSION "1.13 14/05/2002" | 30 | #define I8K_VERSION "1.14 21/02/2005" |
30 | 31 | ||
31 | #define I8K_SMM_FN_STATUS 0x0025 | 32 | #define I8K_SMM_FN_STATUS 0x0025 |
32 | #define I8K_SMM_POWER_STATUS 0x0069 | 33 | #define I8K_SMM_POWER_STATUS 0x0069 |
@@ -34,7 +35,8 @@ | |||
34 | #define I8K_SMM_GET_FAN 0x00a3 | 35 | #define I8K_SMM_GET_FAN 0x00a3 |
35 | #define I8K_SMM_GET_SPEED 0x02a3 | 36 | #define I8K_SMM_GET_SPEED 0x02a3 |
36 | #define I8K_SMM_GET_TEMP 0x10a3 | 37 | #define I8K_SMM_GET_TEMP 0x10a3 |
37 | #define I8K_SMM_GET_DELL_SIG 0xffa3 | 38 | #define I8K_SMM_GET_DELL_SIG1 0xfea3 |
39 | #define I8K_SMM_GET_DELL_SIG2 0xffa3 | ||
38 | #define I8K_SMM_BIOS_VERSION 0x00a6 | 40 | #define I8K_SMM_BIOS_VERSION 0x00a6 |
39 | 41 | ||
40 | #define I8K_FAN_MULT 30 | 42 | #define I8K_FAN_MULT 30 |
@@ -52,18 +54,7 @@ | |||
52 | 54 | ||
53 | #define I8K_TEMPERATURE_BUG 1 | 55 | #define I8K_TEMPERATURE_BUG 1 |
54 | 56 | ||
55 | #define DELL_SIGNATURE "Dell Computer" | 57 | static char bios_version[4]; |
56 | |||
57 | static char *supported_models[] = { | ||
58 | "Inspiron", | ||
59 | "Latitude", | ||
60 | NULL | ||
61 | }; | ||
62 | |||
63 | static char system_vendor[48] = "?"; | ||
64 | static char product_name [48] = "?"; | ||
65 | static char bios_version [4] = "?"; | ||
66 | static char serial_number[16] = "?"; | ||
67 | 58 | ||
68 | MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)"); | 59 | MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)"); |
69 | MODULE_DESCRIPTION("Driver for accessing SMM BIOS on Dell laptops"); | 60 | MODULE_DESCRIPTION("Driver for accessing SMM BIOS on Dell laptops"); |
@@ -73,6 +64,10 @@ static int force; | |||
73 | module_param(force, bool, 0); | 64 | module_param(force, bool, 0); |
74 | MODULE_PARM_DESC(force, "Force loading without checking for supported models"); | 65 | MODULE_PARM_DESC(force, "Force loading without checking for supported models"); |
75 | 66 | ||
67 | static int ignore_dmi; | ||
68 | module_param(ignore_dmi, bool, 0); | ||
69 | MODULE_PARM_DESC(ignore_dmi, "Continue probing hardware even if DMI data does not match"); | ||
70 | |||
76 | static int restricted; | 71 | static int restricted; |
77 | module_param(restricted, bool, 0); | 72 | module_param(restricted, bool, 0); |
78 | MODULE_PARM_DESC(restricted, "Allow fan control if SYS_ADMIN capability set"); | 73 | MODULE_PARM_DESC(restricted, "Allow fan control if SYS_ADMIN capability set"); |
@@ -81,69 +76,69 @@ static int power_status; | |||
81 | module_param(power_status, bool, 0600); | 76 | module_param(power_status, bool, 0600); |
82 | MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k"); | 77 | MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k"); |
83 | 78 | ||
84 | static ssize_t i8k_read(struct file *, char __user *, size_t, loff_t *); | 79 | static int i8k_open_fs(struct inode *inode, struct file *file); |
85 | static int i8k_ioctl(struct inode *, struct file *, unsigned int, | 80 | static int i8k_ioctl(struct inode *, struct file *, unsigned int, |
86 | unsigned long); | 81 | unsigned long); |
87 | 82 | ||
88 | static struct file_operations i8k_fops = { | 83 | static struct file_operations i8k_fops = { |
89 | .read = i8k_read, | 84 | .open = i8k_open_fs, |
90 | .ioctl = i8k_ioctl, | 85 | .read = seq_read, |
86 | .llseek = seq_lseek, | ||
87 | .release = single_release, | ||
88 | .ioctl = i8k_ioctl, | ||
89 | }; | ||
90 | |||
91 | struct smm_regs { | ||
92 | unsigned int eax; | ||
93 | unsigned int ebx __attribute__ ((packed)); | ||
94 | unsigned int ecx __attribute__ ((packed)); | ||
95 | unsigned int edx __attribute__ ((packed)); | ||
96 | unsigned int esi __attribute__ ((packed)); | ||
97 | unsigned int edi __attribute__ ((packed)); | ||
91 | }; | 98 | }; |
92 | 99 | ||
93 | typedef struct { | 100 | static inline char *i8k_get_dmi_data(int field) |
94 | unsigned int eax; | 101 | { |
95 | unsigned int ebx __attribute__ ((packed)); | 102 | return dmi_get_system_info(field) ? : "N/A"; |
96 | unsigned int ecx __attribute__ ((packed)); | 103 | } |
97 | unsigned int edx __attribute__ ((packed)); | ||
98 | unsigned int esi __attribute__ ((packed)); | ||
99 | unsigned int edi __attribute__ ((packed)); | ||
100 | } SMMRegisters; | ||
101 | |||
102 | typedef struct { | ||
103 | u8 type; | ||
104 | u8 length; | ||
105 | u16 handle; | ||
106 | } DMIHeader; | ||
107 | 104 | ||
108 | /* | 105 | /* |
109 | * Call the System Management Mode BIOS. Code provided by Jonathan Buzzard. | 106 | * Call the System Management Mode BIOS. Code provided by Jonathan Buzzard. |
110 | */ | 107 | */ |
111 | static int i8k_smm(SMMRegisters *regs) | 108 | static int i8k_smm(struct smm_regs *regs) |
112 | { | 109 | { |
113 | int rc; | 110 | int rc; |
114 | int eax = regs->eax; | 111 | int eax = regs->eax; |
115 | 112 | ||
116 | asm("pushl %%eax\n\t" \ | 113 | asm("pushl %%eax\n\t" |
117 | "movl 0(%%eax),%%edx\n\t" \ | 114 | "movl 0(%%eax),%%edx\n\t" |
118 | "push %%edx\n\t" \ | 115 | "push %%edx\n\t" |
119 | "movl 4(%%eax),%%ebx\n\t" \ | 116 | "movl 4(%%eax),%%ebx\n\t" |
120 | "movl 8(%%eax),%%ecx\n\t" \ | 117 | "movl 8(%%eax),%%ecx\n\t" |
121 | "movl 12(%%eax),%%edx\n\t" \ | 118 | "movl 12(%%eax),%%edx\n\t" |
122 | "movl 16(%%eax),%%esi\n\t" \ | 119 | "movl 16(%%eax),%%esi\n\t" |
123 | "movl 20(%%eax),%%edi\n\t" \ | 120 | "movl 20(%%eax),%%edi\n\t" |
124 | "popl %%eax\n\t" \ | 121 | "popl %%eax\n\t" |
125 | "out %%al,$0xb2\n\t" \ | 122 | "out %%al,$0xb2\n\t" |
126 | "out %%al,$0x84\n\t" \ | 123 | "out %%al,$0x84\n\t" |
127 | "xchgl %%eax,(%%esp)\n\t" | 124 | "xchgl %%eax,(%%esp)\n\t" |
128 | "movl %%ebx,4(%%eax)\n\t" \ | 125 | "movl %%ebx,4(%%eax)\n\t" |
129 | "movl %%ecx,8(%%eax)\n\t" \ | 126 | "movl %%ecx,8(%%eax)\n\t" |
130 | "movl %%edx,12(%%eax)\n\t" \ | 127 | "movl %%edx,12(%%eax)\n\t" |
131 | "movl %%esi,16(%%eax)\n\t" \ | 128 | "movl %%esi,16(%%eax)\n\t" |
132 | "movl %%edi,20(%%eax)\n\t" \ | 129 | "movl %%edi,20(%%eax)\n\t" |
133 | "popl %%edx\n\t" \ | 130 | "popl %%edx\n\t" |
134 | "movl %%edx,0(%%eax)\n\t" \ | 131 | "movl %%edx,0(%%eax)\n\t" |
135 | "lahf\n\t" \ | 132 | "lahf\n\t" |
136 | "shrl $8,%%eax\n\t" \ | 133 | "shrl $8,%%eax\n\t" |
137 | "andl $1,%%eax\n" \ | 134 | "andl $1,%%eax\n":"=a"(rc) |
138 | : "=a" (rc) | 135 | : "a"(regs) |
139 | : "a" (regs) | 136 | : "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory"); |
140 | : "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory"); | 137 | |
141 | 138 | if (rc != 0 || (regs->eax & 0xffff) == 0xffff || regs->eax == eax) | |
142 | if ((rc != 0) || ((regs->eax & 0xffff) == 0xffff) || (regs->eax == eax)) { | 139 | return -EINVAL; |
143 | return -EINVAL; | 140 | |
144 | } | 141 | return 0; |
145 | |||
146 | return 0; | ||
147 | } | 142 | } |
148 | 143 | ||
149 | /* | 144 | /* |
@@ -152,24 +147,9 @@ static int i8k_smm(SMMRegisters *regs) | |||
152 | */ | 147 | */ |
153 | static int i8k_get_bios_version(void) | 148 | static int i8k_get_bios_version(void) |
154 | { | 149 | { |
155 | SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; | 150 | struct smm_regs regs = { .eax = I8K_SMM_BIOS_VERSION, }; |
156 | int rc; | ||
157 | |||
158 | regs.eax = I8K_SMM_BIOS_VERSION; | ||
159 | if ((rc=i8k_smm(®s)) < 0) { | ||
160 | return rc; | ||
161 | } | ||
162 | |||
163 | return regs.eax; | ||
164 | } | ||
165 | 151 | ||
166 | /* | 152 | return i8k_smm(®s) ? : regs.eax; |
167 | * Read the machine id. | ||
168 | */ | ||
169 | static int i8k_get_serial_number(unsigned char *buff) | ||
170 | { | ||
171 | strlcpy(buff, serial_number, sizeof(serial_number)); | ||
172 | return 0; | ||
173 | } | 153 | } |
174 | 154 | ||
175 | /* | 155 | /* |
@@ -177,24 +157,22 @@ static int i8k_get_serial_number(unsigned char *buff) | |||
177 | */ | 157 | */ |
178 | static int i8k_get_fn_status(void) | 158 | static int i8k_get_fn_status(void) |
179 | { | 159 | { |
180 | SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; | 160 | struct smm_regs regs = { .eax = I8K_SMM_FN_STATUS, }; |
181 | int rc; | 161 | int rc; |
182 | 162 | ||
183 | regs.eax = I8K_SMM_FN_STATUS; | 163 | if ((rc = i8k_smm(®s)) < 0) |
184 | if ((rc=i8k_smm(®s)) < 0) { | 164 | return rc; |
185 | return rc; | 165 | |
186 | } | 166 | switch ((regs.eax >> I8K_FN_SHIFT) & I8K_FN_MASK) { |
187 | 167 | case I8K_FN_UP: | |
188 | switch ((regs.eax >> I8K_FN_SHIFT) & I8K_FN_MASK) { | 168 | return I8K_VOL_UP; |
189 | case I8K_FN_UP: | 169 | case I8K_FN_DOWN: |
190 | return I8K_VOL_UP; | 170 | return I8K_VOL_DOWN; |
191 | case I8K_FN_DOWN: | 171 | case I8K_FN_MUTE: |
192 | return I8K_VOL_DOWN; | 172 | return I8K_VOL_MUTE; |
193 | case I8K_FN_MUTE: | 173 | default: |
194 | return I8K_VOL_MUTE; | 174 | return 0; |
195 | default: | 175 | } |
196 | return 0; | ||
197 | } | ||
198 | } | 176 | } |
199 | 177 | ||
200 | /* | 178 | /* |
@@ -202,20 +180,13 @@ static int i8k_get_fn_status(void) | |||
202 | */ | 180 | */ |
203 | static int i8k_get_power_status(void) | 181 | static int i8k_get_power_status(void) |
204 | { | 182 | { |
205 | SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; | 183 | struct smm_regs regs = { .eax = I8K_SMM_POWER_STATUS, }; |
206 | int rc; | 184 | int rc; |
207 | 185 | ||
208 | regs.eax = I8K_SMM_POWER_STATUS; | 186 | if ((rc = i8k_smm(®s)) < 0) |
209 | if ((rc=i8k_smm(®s)) < 0) { | 187 | return rc; |
210 | return rc; | 188 | |
211 | } | 189 | return (regs.eax & 0xff) == I8K_POWER_AC ? I8K_AC : I8K_BATTERY; |
212 | |||
213 | switch (regs.eax & 0xff) { | ||
214 | case I8K_POWER_AC: | ||
215 | return I8K_AC; | ||
216 | default: | ||
217 | return I8K_BATTERY; | ||
218 | } | ||
219 | } | 190 | } |
220 | 191 | ||
221 | /* | 192 | /* |
@@ -223,16 +194,10 @@ static int i8k_get_power_status(void) | |||
223 | */ | 194 | */ |
224 | static int i8k_get_fan_status(int fan) | 195 | static int i8k_get_fan_status(int fan) |
225 | { | 196 | { |
226 | SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; | 197 | struct smm_regs regs = { .eax = I8K_SMM_GET_FAN, }; |
227 | int rc; | ||
228 | |||
229 | regs.eax = I8K_SMM_GET_FAN; | ||
230 | regs.ebx = fan & 0xff; | ||
231 | if ((rc=i8k_smm(®s)) < 0) { | ||
232 | return rc; | ||
233 | } | ||
234 | 198 | ||
235 | return (regs.eax & 0xff); | 199 | regs.ebx = fan & 0xff; |
200 | return i8k_smm(®s) ? : regs.eax & 0xff; | ||
236 | } | 201 | } |
237 | 202 | ||
238 | /* | 203 | /* |
@@ -240,16 +205,10 @@ static int i8k_get_fan_status(int fan) | |||
240 | */ | 205 | */ |
241 | static int i8k_get_fan_speed(int fan) | 206 | static int i8k_get_fan_speed(int fan) |
242 | { | 207 | { |
243 | SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; | 208 | struct smm_regs regs = { .eax = I8K_SMM_GET_SPEED, }; |
244 | int rc; | ||
245 | 209 | ||
246 | regs.eax = I8K_SMM_GET_SPEED; | 210 | regs.ebx = fan & 0xff; |
247 | regs.ebx = fan & 0xff; | 211 | return i8k_smm(®s) ? : (regs.eax & 0xffff) * I8K_FAN_MULT; |
248 | if ((rc=i8k_smm(®s)) < 0) { | ||
249 | return rc; | ||
250 | } | ||
251 | |||
252 | return (regs.eax & 0xffff) * I8K_FAN_MULT; | ||
253 | } | 212 | } |
254 | 213 | ||
255 | /* | 214 | /* |
@@ -257,532 +216,318 @@ static int i8k_get_fan_speed(int fan) | |||
257 | */ | 216 | */ |
258 | static int i8k_set_fan(int fan, int speed) | 217 | static int i8k_set_fan(int fan, int speed) |
259 | { | 218 | { |
260 | SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; | 219 | struct smm_regs regs = { .eax = I8K_SMM_SET_FAN, }; |
261 | int rc; | ||
262 | |||
263 | speed = (speed < 0) ? 0 : ((speed > I8K_FAN_MAX) ? I8K_FAN_MAX : speed); | ||
264 | 220 | ||
265 | regs.eax = I8K_SMM_SET_FAN; | 221 | speed = (speed < 0) ? 0 : ((speed > I8K_FAN_MAX) ? I8K_FAN_MAX : speed); |
266 | regs.ebx = (fan & 0xff) | (speed << 8); | 222 | regs.ebx = (fan & 0xff) | (speed << 8); |
267 | if ((rc=i8k_smm(®s)) < 0) { | ||
268 | return rc; | ||
269 | } | ||
270 | 223 | ||
271 | return (i8k_get_fan_status(fan)); | 224 | return i8k_smm(®s) ? : i8k_get_fan_status(fan); |
272 | } | 225 | } |
273 | 226 | ||
274 | /* | 227 | /* |
275 | * Read the cpu temperature. | 228 | * Read the cpu temperature. |
276 | */ | 229 | */ |
277 | static int i8k_get_cpu_temp(void) | 230 | static int i8k_get_temp(int sensor) |
278 | { | 231 | { |
279 | SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; | 232 | struct smm_regs regs = { .eax = I8K_SMM_GET_TEMP, }; |
280 | int rc; | 233 | int rc; |
281 | int temp; | 234 | int temp; |
282 | 235 | ||
283 | #ifdef I8K_TEMPERATURE_BUG | 236 | #ifdef I8K_TEMPERATURE_BUG |
284 | static int prev = 0; | 237 | static int prev; |
285 | #endif | 238 | #endif |
239 | regs.ebx = sensor & 0xff; | ||
240 | if ((rc = i8k_smm(®s)) < 0) | ||
241 | return rc; | ||
286 | 242 | ||
287 | regs.eax = I8K_SMM_GET_TEMP; | 243 | temp = regs.eax & 0xff; |
288 | if ((rc=i8k_smm(®s)) < 0) { | ||
289 | return rc; | ||
290 | } | ||
291 | temp = regs.eax & 0xff; | ||
292 | 244 | ||
293 | #ifdef I8K_TEMPERATURE_BUG | 245 | #ifdef I8K_TEMPERATURE_BUG |
294 | /* | 246 | /* |
295 | * Sometimes the temperature sensor returns 0x99, which is out of range. | 247 | * Sometimes the temperature sensor returns 0x99, which is out of range. |
296 | * In this case we return (once) the previous cached value. For example: | 248 | * In this case we return (once) the previous cached value. For example: |
297 | # 1003655137 00000058 00005a4b | 249 | # 1003655137 00000058 00005a4b |
298 | # 1003655138 00000099 00003a80 <--- 0x99 = 153 degrees | 250 | # 1003655138 00000099 00003a80 <--- 0x99 = 153 degrees |
299 | # 1003655139 00000054 00005c52 | 251 | # 1003655139 00000054 00005c52 |
300 | */ | 252 | */ |
301 | if (temp > I8K_MAX_TEMP) { | 253 | if (temp > I8K_MAX_TEMP) { |
302 | temp = prev; | 254 | temp = prev; |
303 | prev = I8K_MAX_TEMP; | 255 | prev = I8K_MAX_TEMP; |
304 | } else { | 256 | } else { |
305 | prev = temp; | 257 | prev = temp; |
306 | } | 258 | } |
307 | #endif | 259 | #endif |
308 | 260 | ||
309 | return temp; | 261 | return temp; |
310 | } | 262 | } |
311 | 263 | ||
312 | static int i8k_get_dell_signature(void) | 264 | static int i8k_get_dell_signature(int req_fn) |
313 | { | 265 | { |
314 | SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; | 266 | struct smm_regs regs = { .eax = req_fn, }; |
315 | int rc; | 267 | int rc; |
316 | 268 | ||
317 | regs.eax = I8K_SMM_GET_DELL_SIG; | 269 | if ((rc = i8k_smm(®s)) < 0) |
318 | if ((rc=i8k_smm(®s)) < 0) { | 270 | return rc; |
319 | return rc; | ||
320 | } | ||
321 | 271 | ||
322 | if ((regs.eax == 1145651527) && (regs.edx == 1145392204)) { | 272 | return regs.eax == 1145651527 && regs.edx == 1145392204 ? 0 : -1; |
323 | return 0; | ||
324 | } else { | ||
325 | return -1; | ||
326 | } | ||
327 | } | 273 | } |
328 | 274 | ||
329 | static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, | 275 | static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, |
330 | unsigned long arg) | 276 | unsigned long arg) |
331 | { | 277 | { |
332 | int val; | 278 | int val = 0; |
333 | int speed; | 279 | int speed; |
334 | unsigned char buff[16]; | 280 | unsigned char buff[16]; |
335 | int __user *argp = (int __user *)arg; | 281 | int __user *argp = (int __user *)arg; |
336 | |||
337 | if (!argp) | ||
338 | return -EINVAL; | ||
339 | |||
340 | switch (cmd) { | ||
341 | case I8K_BIOS_VERSION: | ||
342 | val = i8k_get_bios_version(); | ||
343 | break; | ||
344 | |||
345 | case I8K_MACHINE_ID: | ||
346 | memset(buff, 0, 16); | ||
347 | val = i8k_get_serial_number(buff); | ||
348 | break; | ||
349 | |||
350 | case I8K_FN_STATUS: | ||
351 | val = i8k_get_fn_status(); | ||
352 | break; | ||
353 | |||
354 | case I8K_POWER_STATUS: | ||
355 | val = i8k_get_power_status(); | ||
356 | break; | ||
357 | |||
358 | case I8K_GET_TEMP: | ||
359 | val = i8k_get_cpu_temp(); | ||
360 | break; | ||
361 | |||
362 | case I8K_GET_SPEED: | ||
363 | if (copy_from_user(&val, argp, sizeof(int))) { | ||
364 | return -EFAULT; | ||
365 | } | ||
366 | val = i8k_get_fan_speed(val); | ||
367 | break; | ||
368 | |||
369 | case I8K_GET_FAN: | ||
370 | if (copy_from_user(&val, argp, sizeof(int))) { | ||
371 | return -EFAULT; | ||
372 | } | ||
373 | val = i8k_get_fan_status(val); | ||
374 | break; | ||
375 | 282 | ||
376 | case I8K_SET_FAN: | 283 | if (!argp) |
377 | if (restricted && !capable(CAP_SYS_ADMIN)) { | 284 | return -EINVAL; |
378 | return -EPERM; | ||
379 | } | ||
380 | if (copy_from_user(&val, argp, sizeof(int))) { | ||
381 | return -EFAULT; | ||
382 | } | ||
383 | if (copy_from_user(&speed, argp+1, sizeof(int))) { | ||
384 | return -EFAULT; | ||
385 | } | ||
386 | val = i8k_set_fan(val, speed); | ||
387 | break; | ||
388 | 285 | ||
389 | default: | 286 | switch (cmd) { |
390 | return -EINVAL; | 287 | case I8K_BIOS_VERSION: |
391 | } | 288 | val = i8k_get_bios_version(); |
289 | break; | ||
392 | 290 | ||
393 | if (val < 0) { | 291 | case I8K_MACHINE_ID: |
394 | return val; | 292 | memset(buff, 0, 16); |
395 | } | 293 | strlcpy(buff, i8k_get_dmi_data(DMI_PRODUCT_SERIAL), sizeof(buff)); |
294 | break; | ||
396 | 295 | ||
397 | switch (cmd) { | 296 | case I8K_FN_STATUS: |
398 | case I8K_BIOS_VERSION: | 297 | val = i8k_get_fn_status(); |
399 | if (copy_to_user(argp, &val, 4)) { | 298 | break; |
400 | return -EFAULT; | ||
401 | } | ||
402 | break; | ||
403 | case I8K_MACHINE_ID: | ||
404 | if (copy_to_user(argp, buff, 16)) { | ||
405 | return -EFAULT; | ||
406 | } | ||
407 | break; | ||
408 | default: | ||
409 | if (copy_to_user(argp, &val, sizeof(int))) { | ||
410 | return -EFAULT; | ||
411 | } | ||
412 | break; | ||
413 | } | ||
414 | 299 | ||
415 | return 0; | 300 | case I8K_POWER_STATUS: |
416 | } | 301 | val = i8k_get_power_status(); |
302 | break; | ||
417 | 303 | ||
418 | /* | 304 | case I8K_GET_TEMP: |
419 | * Print the information for /proc/i8k. | 305 | val = i8k_get_temp(0); |
420 | */ | 306 | break; |
421 | static int i8k_get_info(char *buffer, char **start, off_t fpos, int length) | ||
422 | { | ||
423 | int n, fn_key, cpu_temp, ac_power; | ||
424 | int left_fan, right_fan, left_speed, right_speed; | ||
425 | |||
426 | cpu_temp = i8k_get_cpu_temp(); /* 11100 µs */ | ||
427 | left_fan = i8k_get_fan_status(I8K_FAN_LEFT); /* 580 µs */ | ||
428 | right_fan = i8k_get_fan_status(I8K_FAN_RIGHT); /* 580 µs */ | ||
429 | left_speed = i8k_get_fan_speed(I8K_FAN_LEFT); /* 580 µs */ | ||
430 | right_speed = i8k_get_fan_speed(I8K_FAN_RIGHT); /* 580 µs */ | ||
431 | fn_key = i8k_get_fn_status(); /* 750 µs */ | ||
432 | if (power_status) { | ||
433 | ac_power = i8k_get_power_status(); /* 14700 µs */ | ||
434 | } else { | ||
435 | ac_power = -1; | ||
436 | } | ||
437 | |||
438 | /* | ||
439 | * Info: | ||
440 | * | ||
441 | * 1) Format version (this will change if format changes) | ||
442 | * 2) BIOS version | ||
443 | * 3) BIOS machine ID | ||
444 | * 4) Cpu temperature | ||
445 | * 5) Left fan status | ||
446 | * 6) Right fan status | ||
447 | * 7) Left fan speed | ||
448 | * 8) Right fan speed | ||
449 | * 9) AC power | ||
450 | * 10) Fn Key status | ||
451 | */ | ||
452 | n = sprintf(buffer, "%s %s %s %d %d %d %d %d %d %d\n", | ||
453 | I8K_PROC_FMT, | ||
454 | bios_version, | ||
455 | serial_number, | ||
456 | cpu_temp, | ||
457 | left_fan, | ||
458 | right_fan, | ||
459 | left_speed, | ||
460 | right_speed, | ||
461 | ac_power, | ||
462 | fn_key); | ||
463 | |||
464 | return n; | ||
465 | } | ||
466 | 307 | ||
467 | static ssize_t i8k_read(struct file *f, char __user *buffer, size_t len, loff_t *fpos) | 308 | case I8K_GET_SPEED: |
468 | { | 309 | if (copy_from_user(&val, argp, sizeof(int))) |
469 | int n; | 310 | return -EFAULT; |
470 | char info[128]; | ||
471 | 311 | ||
472 | n = i8k_get_info(info, NULL, 0, 128); | 312 | val = i8k_get_fan_speed(val); |
473 | if (n <= 0) { | 313 | break; |
474 | return n; | ||
475 | } | ||
476 | 314 | ||
477 | if (*fpos >= n) { | 315 | case I8K_GET_FAN: |
478 | return 0; | 316 | if (copy_from_user(&val, argp, sizeof(int))) |
479 | } | 317 | return -EFAULT; |
480 | 318 | ||
481 | if ((*fpos + len) >= n) { | 319 | val = i8k_get_fan_status(val); |
482 | len = n - *fpos; | 320 | break; |
483 | } | ||
484 | 321 | ||
485 | if (copy_to_user(buffer, info, len) != 0) { | 322 | case I8K_SET_FAN: |
486 | return -EFAULT; | 323 | if (restricted && !capable(CAP_SYS_ADMIN)) |
487 | } | 324 | return -EPERM; |
488 | 325 | ||
489 | *fpos += len; | 326 | if (copy_from_user(&val, argp, sizeof(int))) |
490 | return len; | 327 | return -EFAULT; |
491 | } | ||
492 | 328 | ||
493 | static char* __init string_trim(char *s, int size) | 329 | if (copy_from_user(&speed, argp + 1, sizeof(int))) |
494 | { | 330 | return -EFAULT; |
495 | int len; | ||
496 | char *p; | ||
497 | 331 | ||
498 | if ((len = strlen(s)) > size) { | 332 | val = i8k_set_fan(val, speed); |
499 | len = size; | 333 | break; |
500 | } | ||
501 | 334 | ||
502 | for (p=s+len-1; len && (*p==' '); len--,p--) { | 335 | default: |
503 | *p = '\0'; | 336 | return -EINVAL; |
504 | } | 337 | } |
505 | 338 | ||
506 | return s; | 339 | if (val < 0) |
507 | } | 340 | return val; |
508 | 341 | ||
509 | /* DMI code, stolen from arch/i386/kernel/dmi_scan.c */ | 342 | switch (cmd) { |
343 | case I8K_BIOS_VERSION: | ||
344 | if (copy_to_user(argp, &val, 4)) | ||
345 | return -EFAULT; | ||
510 | 346 | ||
511 | /* | 347 | break; |
512 | * |<-- dmi->length -->| | 348 | case I8K_MACHINE_ID: |
513 | * | | | 349 | if (copy_to_user(argp, buff, 16)) |
514 | * |dmi header s=N | string1,\0, ..., stringN,\0, ..., \0 | 350 | return -EFAULT; |
515 | * | | | ||
516 | * +-----------------------+ | ||
517 | */ | ||
518 | static char* __init dmi_string(DMIHeader *dmi, u8 s) | ||
519 | { | ||
520 | u8 *p; | ||
521 | 351 | ||
522 | if (!s) { | 352 | break; |
523 | return ""; | 353 | default: |
524 | } | 354 | if (copy_to_user(argp, &val, sizeof(int))) |
525 | s--; | 355 | return -EFAULT; |
526 | 356 | ||
527 | p = (u8 *)dmi + dmi->length; | 357 | break; |
528 | while (s > 0) { | 358 | } |
529 | p += strlen(p); | ||
530 | p++; | ||
531 | s--; | ||
532 | } | ||
533 | 359 | ||
534 | return p; | 360 | return 0; |
535 | } | 361 | } |
536 | 362 | ||
537 | static void __init dmi_decode(DMIHeader *dmi) | 363 | /* |
364 | * Print the information for /proc/i8k. | ||
365 | */ | ||
366 | static int i8k_proc_show(struct seq_file *seq, void *offset) | ||
538 | { | 367 | { |
539 | u8 *data = (u8 *) dmi; | 368 | int fn_key, cpu_temp, ac_power; |
540 | char *p; | 369 | int left_fan, right_fan, left_speed, right_speed; |
541 | 370 | ||
542 | #ifdef I8K_DEBUG | 371 | cpu_temp = i8k_get_temp(0); /* 11100 µs */ |
543 | int i; | 372 | left_fan = i8k_get_fan_status(I8K_FAN_LEFT); /* 580 µs */ |
544 | printk("%08x ", (int)data); | 373 | right_fan = i8k_get_fan_status(I8K_FAN_RIGHT); /* 580 µs */ |
545 | for (i=0; i<data[1] && i<64; i++) { | 374 | left_speed = i8k_get_fan_speed(I8K_FAN_LEFT); /* 580 µs */ |
546 | printk("%02x ", data[i]); | 375 | right_speed = i8k_get_fan_speed(I8K_FAN_RIGHT); /* 580 µs */ |
547 | } | 376 | fn_key = i8k_get_fn_status(); /* 750 µs */ |
548 | printk("\n"); | 377 | if (power_status) |
549 | #endif | 378 | ac_power = i8k_get_power_status(); /* 14700 µs */ |
550 | 379 | else | |
551 | switch (dmi->type) { | 380 | ac_power = -1; |
552 | case 0: /* BIOS Information */ | ||
553 | p = dmi_string(dmi,data[5]); | ||
554 | if (*p) { | ||
555 | strlcpy(bios_version, p, sizeof(bios_version)); | ||
556 | string_trim(bios_version, sizeof(bios_version)); | ||
557 | } | ||
558 | break; | ||
559 | case 1: /* System Information */ | ||
560 | p = dmi_string(dmi,data[4]); | ||
561 | if (*p) { | ||
562 | strlcpy(system_vendor, p, sizeof(system_vendor)); | ||
563 | string_trim(system_vendor, sizeof(system_vendor)); | ||
564 | } | ||
565 | p = dmi_string(dmi,data[5]); | ||
566 | if (*p) { | ||
567 | strlcpy(product_name, p, sizeof(product_name)); | ||
568 | string_trim(product_name, sizeof(product_name)); | ||
569 | } | ||
570 | p = dmi_string(dmi,data[7]); | ||
571 | if (*p) { | ||
572 | strlcpy(serial_number, p, sizeof(serial_number)); | ||
573 | string_trim(serial_number, sizeof(serial_number)); | ||
574 | } | ||
575 | break; | ||
576 | } | ||
577 | } | ||
578 | 381 | ||
579 | static int __init dmi_table(u32 base, int len, int num, void (*fn)(DMIHeader*)) | ||
580 | { | ||
581 | u8 *buf; | ||
582 | u8 *data; | ||
583 | DMIHeader *dmi; | ||
584 | int i = 1; | ||
585 | |||
586 | buf = ioremap(base, len); | ||
587 | if (buf == NULL) { | ||
588 | return -1; | ||
589 | } | ||
590 | data = buf; | ||
591 | |||
592 | /* | ||
593 | * Stop when we see al the items the table claimed to have | ||
594 | * or we run off the end of the table (also happens) | ||
595 | */ | ||
596 | while ((i<num) && ((data-buf) < len)) { | ||
597 | dmi = (DMIHeader *)data; | ||
598 | /* | ||
599 | * Avoid misparsing crud if the length of the last | ||
600 | * record is crap | ||
601 | */ | ||
602 | if ((data-buf+dmi->length) >= len) { | ||
603 | break; | ||
604 | } | ||
605 | fn(dmi); | ||
606 | data += dmi->length; | ||
607 | /* | 382 | /* |
608 | * Don't go off the end of the data if there is | 383 | * Info: |
609 | * stuff looking like string fill past the end | 384 | * |
385 | * 1) Format version (this will change if format changes) | ||
386 | * 2) BIOS version | ||
387 | * 3) BIOS machine ID | ||
388 | * 4) Cpu temperature | ||
389 | * 5) Left fan status | ||
390 | * 6) Right fan status | ||
391 | * 7) Left fan speed | ||
392 | * 8) Right fan speed | ||
393 | * 9) AC power | ||
394 | * 10) Fn Key status | ||
610 | */ | 395 | */ |
611 | while (((data-buf) < len) && (*data || data[1])) { | 396 | return seq_printf(seq, "%s %s %s %d %d %d %d %d %d %d\n", |
612 | data++; | 397 | I8K_PROC_FMT, |
613 | } | 398 | bios_version, |
614 | data += 2; | 399 | dmi_get_system_info(DMI_PRODUCT_SERIAL) ? : "N/A", |
615 | i++; | 400 | cpu_temp, |
616 | } | 401 | left_fan, right_fan, left_speed, right_speed, |
617 | iounmap(buf); | 402 | ac_power, fn_key); |
618 | |||
619 | return 0; | ||
620 | } | 403 | } |
621 | 404 | ||
622 | static int __init dmi_iterate(void (*decode)(DMIHeader *)) | 405 | static int i8k_open_fs(struct inode *inode, struct file *file) |
623 | { | 406 | { |
624 | unsigned char buf[20]; | 407 | return single_open(file, i8k_proc_show, NULL); |
625 | void __iomem *p = ioremap(0xe0000, 0x20000), *q; | ||
626 | |||
627 | if (!p) | ||
628 | return -1; | ||
629 | |||
630 | for (q = p; q < p + 0x20000; q += 16) { | ||
631 | memcpy_fromio(buf, q, 20); | ||
632 | if (memcmp(buf, "_DMI_", 5)==0) { | ||
633 | u16 num = buf[13]<<8 | buf[12]; | ||
634 | u16 len = buf [7]<<8 | buf [6]; | ||
635 | u32 base = buf[11]<<24 | buf[10]<<16 | buf[9]<<8 | buf[8]; | ||
636 | #ifdef I8K_DEBUG | ||
637 | printk(KERN_INFO "DMI %d.%d present.\n", | ||
638 | buf[14]>>4, buf[14]&0x0F); | ||
639 | printk(KERN_INFO "%d structures occupying %d bytes.\n", | ||
640 | buf[13]<<8 | buf[12], | ||
641 | buf [7]<<8 | buf[6]); | ||
642 | printk(KERN_INFO "DMI table at 0x%08X.\n", | ||
643 | buf[11]<<24 | buf[10]<<16 | buf[9]<<8 | buf[8]); | ||
644 | #endif | ||
645 | if (dmi_table(base, len, num, decode)==0) { | ||
646 | iounmap(p); | ||
647 | return 0; | ||
648 | } | ||
649 | } | ||
650 | } | ||
651 | iounmap(p); | ||
652 | return -1; | ||
653 | } | 408 | } |
654 | /* end of DMI code */ | ||
655 | |||
656 | /* | ||
657 | * Get DMI information. | ||
658 | */ | ||
659 | static int __init i8k_dmi_probe(void) | ||
660 | { | ||
661 | char **p; | ||
662 | |||
663 | if (dmi_iterate(dmi_decode) != 0) { | ||
664 | printk(KERN_INFO "i8k: unable to get DMI information\n"); | ||
665 | return -ENODEV; | ||
666 | } | ||
667 | |||
668 | if (strncmp(system_vendor,DELL_SIGNATURE,strlen(DELL_SIGNATURE)) != 0) { | ||
669 | printk(KERN_INFO "i8k: not running on a Dell system\n"); | ||
670 | return -ENODEV; | ||
671 | } | ||
672 | |||
673 | for (p=supported_models; ; p++) { | ||
674 | if (!*p) { | ||
675 | printk(KERN_INFO "i8k: unsupported model: %s\n", product_name); | ||
676 | return -ENODEV; | ||
677 | } | ||
678 | if (strncmp(product_name,*p,strlen(*p)) == 0) { | ||
679 | break; | ||
680 | } | ||
681 | } | ||
682 | 409 | ||
683 | return 0; | 410 | static struct dmi_system_id __initdata i8k_dmi_table[] = { |
684 | } | 411 | { |
412 | .ident = "Dell Inspiron", | ||
413 | .matches = { | ||
414 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer"), | ||
415 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron"), | ||
416 | }, | ||
417 | }, | ||
418 | { | ||
419 | .ident = "Dell Latitude", | ||
420 | .matches = { | ||
421 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer"), | ||
422 | DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"), | ||
423 | }, | ||
424 | }, | ||
425 | { | ||
426 | .ident = "Dell Inspiron 2", | ||
427 | .matches = { | ||
428 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
429 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron"), | ||
430 | }, | ||
431 | }, | ||
432 | { | ||
433 | .ident = "Dell Latitude 2", | ||
434 | .matches = { | ||
435 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
436 | DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"), | ||
437 | }, | ||
438 | }, | ||
439 | { } | ||
440 | }; | ||
685 | 441 | ||
686 | /* | 442 | /* |
687 | * Probe for the presence of a supported laptop. | 443 | * Probe for the presence of a supported laptop. |
688 | */ | 444 | */ |
689 | static int __init i8k_probe(void) | 445 | static int __init i8k_probe(void) |
690 | { | 446 | { |
691 | char buff[4]; | 447 | char buff[4]; |
692 | int version; | 448 | int version; |
693 | int smm_found = 0; | 449 | |
694 | |||
695 | /* | ||
696 | * Get DMI information | ||
697 | */ | ||
698 | if (i8k_dmi_probe() != 0) { | ||
699 | printk(KERN_INFO "i8k: vendor=%s, model=%s, version=%s\n", | ||
700 | system_vendor, product_name, bios_version); | ||
701 | } | ||
702 | |||
703 | /* | ||
704 | * Get SMM Dell signature | ||
705 | */ | ||
706 | if (i8k_get_dell_signature() != 0) { | ||
707 | printk(KERN_INFO "i8k: unable to get SMM Dell signature\n"); | ||
708 | } else { | ||
709 | smm_found = 1; | ||
710 | } | ||
711 | |||
712 | /* | ||
713 | * Get SMM BIOS version. | ||
714 | */ | ||
715 | version = i8k_get_bios_version(); | ||
716 | if (version <= 0) { | ||
717 | printk(KERN_INFO "i8k: unable to get SMM BIOS version\n"); | ||
718 | } else { | ||
719 | smm_found = 1; | ||
720 | buff[0] = (version >> 16) & 0xff; | ||
721 | buff[1] = (version >> 8) & 0xff; | ||
722 | buff[2] = (version) & 0xff; | ||
723 | buff[3] = '\0'; | ||
724 | /* | 450 | /* |
725 | * If DMI BIOS version is unknown use SMM BIOS version. | 451 | * Get DMI information |
726 | */ | 452 | */ |
727 | if (bios_version[0] == '?') { | 453 | if (!dmi_check_system(i8k_dmi_table)) { |
728 | strcpy(bios_version, buff); | 454 | if (!ignore_dmi && !force) |
455 | return -ENODEV; | ||
456 | |||
457 | printk(KERN_INFO "i8k: not running on a supported Dell system.\n"); | ||
458 | printk(KERN_INFO "i8k: vendor=%s, model=%s, version=%s\n", | ||
459 | i8k_get_dmi_data(DMI_SYS_VENDOR), | ||
460 | i8k_get_dmi_data(DMI_PRODUCT_NAME), | ||
461 | i8k_get_dmi_data(DMI_BIOS_VERSION)); | ||
729 | } | 462 | } |
463 | |||
464 | strlcpy(bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION), sizeof(bios_version)); | ||
465 | |||
730 | /* | 466 | /* |
731 | * Check if the two versions match. | 467 | * Get SMM Dell signature |
732 | */ | 468 | */ |
733 | if (strncmp(buff,bios_version,sizeof(bios_version)) != 0) { | 469 | if (i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG1) && |
734 | printk(KERN_INFO "i8k: BIOS version mismatch: %s != %s\n", | 470 | i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG2)) { |
735 | buff, bios_version); | 471 | printk(KERN_ERR "i8k: unable to get SMM Dell signature\n"); |
472 | if (!force) | ||
473 | return -ENODEV; | ||
736 | } | 474 | } |
737 | } | ||
738 | 475 | ||
739 | if (!smm_found && !force) { | 476 | /* |
740 | return -ENODEV; | 477 | * Get SMM BIOS version. |
741 | } | 478 | */ |
479 | version = i8k_get_bios_version(); | ||
480 | if (version <= 0) { | ||
481 | printk(KERN_WARNING "i8k: unable to get SMM BIOS version\n"); | ||
482 | } else { | ||
483 | buff[0] = (version >> 16) & 0xff; | ||
484 | buff[1] = (version >> 8) & 0xff; | ||
485 | buff[2] = (version) & 0xff; | ||
486 | buff[3] = '\0'; | ||
487 | /* | ||
488 | * If DMI BIOS version is unknown use SMM BIOS version. | ||
489 | */ | ||
490 | if (!dmi_get_system_info(DMI_BIOS_VERSION)) | ||
491 | strlcpy(bios_version, buff, sizeof(bios_version)); | ||
492 | |||
493 | /* | ||
494 | * Check if the two versions match. | ||
495 | */ | ||
496 | if (strncmp(buff, bios_version, sizeof(bios_version)) != 0) | ||
497 | printk(KERN_WARNING "i8k: BIOS version mismatch: %s != %s\n", | ||
498 | buff, bios_version); | ||
499 | } | ||
742 | 500 | ||
743 | return 0; | 501 | return 0; |
744 | } | 502 | } |
745 | 503 | ||
746 | #ifdef MODULE | 504 | static int __init i8k_init(void) |
747 | static | ||
748 | #endif | ||
749 | int __init i8k_init(void) | ||
750 | { | 505 | { |
751 | struct proc_dir_entry *proc_i8k; | 506 | struct proc_dir_entry *proc_i8k; |
752 | |||
753 | /* Are we running on an supported laptop? */ | ||
754 | if (i8k_probe() != 0) { | ||
755 | return -ENODEV; | ||
756 | } | ||
757 | |||
758 | /* Register the proc entry */ | ||
759 | proc_i8k = create_proc_info_entry("i8k", 0, NULL, i8k_get_info); | ||
760 | if (!proc_i8k) { | ||
761 | return -ENOENT; | ||
762 | } | ||
763 | proc_i8k->proc_fops = &i8k_fops; | ||
764 | proc_i8k->owner = THIS_MODULE; | ||
765 | |||
766 | printk(KERN_INFO | ||
767 | "Dell laptop SMM driver v%s Massimo Dal Zotto (dz@debian.org)\n", | ||
768 | I8K_VERSION); | ||
769 | |||
770 | return 0; | ||
771 | } | ||
772 | 507 | ||
773 | #ifdef MODULE | 508 | /* Are we running on an supported laptop? */ |
774 | int init_module(void) | 509 | if (i8k_probe()) |
775 | { | 510 | return -ENODEV; |
776 | return i8k_init(); | 511 | |
512 | /* Register the proc entry */ | ||
513 | proc_i8k = create_proc_entry("i8k", 0, NULL); | ||
514 | if (!proc_i8k) | ||
515 | return -ENOENT; | ||
516 | |||
517 | proc_i8k->proc_fops = &i8k_fops; | ||
518 | proc_i8k->owner = THIS_MODULE; | ||
519 | |||
520 | printk(KERN_INFO | ||
521 | "Dell laptop SMM driver v%s Massimo Dal Zotto (dz@debian.org)\n", | ||
522 | I8K_VERSION); | ||
523 | |||
524 | return 0; | ||
777 | } | 525 | } |
778 | 526 | ||
779 | void cleanup_module(void) | 527 | static void __exit i8k_exit(void) |
780 | { | 528 | { |
781 | /* Remove the proc entry */ | 529 | remove_proc_entry("i8k", NULL); |
782 | remove_proc_entry("i8k", NULL); | ||
783 | |||
784 | printk(KERN_INFO "i8k: module unloaded\n"); | ||
785 | } | 530 | } |
786 | #endif | ||
787 | 531 | ||
788 | /* end of file */ | 532 | module_init(i8k_init); |
533 | module_exit(i8k_exit); | ||
diff --git a/drivers/char/ip2/i2cmd.c b/drivers/char/ip2/i2cmd.c index fd299d6c42ac..cb8f4198e9a3 100644 --- a/drivers/char/ip2/i2cmd.c +++ b/drivers/char/ip2/i2cmd.c | |||
@@ -97,7 +97,7 @@ static UCHAR ct41[] = { 1, BYP, 0x29 }; // RESUME | |||
97 | //static UCHAR ct44[]={ 2, BTH, 0x2C,0 }; // MS PING | 97 | //static UCHAR ct44[]={ 2, BTH, 0x2C,0 }; // MS PING |
98 | //static UCHAR ct45[]={ 1, BTH, 0x2D }; // HOTENAB | 98 | //static UCHAR ct45[]={ 1, BTH, 0x2D }; // HOTENAB |
99 | //static UCHAR ct46[]={ 1, BTH, 0x2E }; // HOTDSAB | 99 | //static UCHAR ct46[]={ 1, BTH, 0x2E }; // HOTDSAB |
100 | static UCHAR ct47[] = { 7, BTH, 0x2F,0,0,0,0,0,0 }; // UNIX FLAGS | 100 | //static UCHAR ct47[]={ 7, BTH, 0x2F,0,0,0,0,0,0 }; // UNIX FLAGS |
101 | //static UCHAR ct48[]={ 1, BTH, 0x30 }; // DSRFLOWENAB | 101 | //static UCHAR ct48[]={ 1, BTH, 0x30 }; // DSRFLOWENAB |
102 | //static UCHAR ct49[]={ 1, BTH, 0x31 }; // DSRFLOWDSAB | 102 | //static UCHAR ct49[]={ 1, BTH, 0x31 }; // DSRFLOWDSAB |
103 | //static UCHAR ct50[]={ 1, BTH, 0x32 }; // DTRFLOWENAB | 103 | //static UCHAR ct50[]={ 1, BTH, 0x32 }; // DTRFLOWENAB |
@@ -162,6 +162,7 @@ static UCHAR ct89[]={ 1, BYP, 0x59 }; // DSS_NOW | |||
162 | // This routine sets the parameters of command 47 and returns a pointer to the | 162 | // This routine sets the parameters of command 47 and returns a pointer to the |
163 | // appropriate structure. | 163 | // appropriate structure. |
164 | //****************************************************************************** | 164 | //****************************************************************************** |
165 | #if 0 | ||
165 | cmdSyntaxPtr | 166 | cmdSyntaxPtr |
166 | i2cmdUnixFlags(unsigned short iflag,unsigned short cflag,unsigned short lflag) | 167 | i2cmdUnixFlags(unsigned short iflag,unsigned short cflag,unsigned short lflag) |
167 | { | 168 | { |
@@ -175,6 +176,7 @@ i2cmdUnixFlags(unsigned short iflag,unsigned short cflag,unsigned short lflag) | |||
175 | pCM->cmd[6] = (unsigned char) (lflag >> 8); | 176 | pCM->cmd[6] = (unsigned char) (lflag >> 8); |
176 | return pCM; | 177 | return pCM; |
177 | } | 178 | } |
179 | #endif /* 0 */ | ||
178 | 180 | ||
179 | //****************************************************************************** | 181 | //****************************************************************************** |
180 | // Function: i2cmdBaudDef(which, rate) | 182 | // Function: i2cmdBaudDef(which, rate) |
@@ -187,7 +189,7 @@ i2cmdUnixFlags(unsigned short iflag,unsigned short cflag,unsigned short lflag) | |||
187 | // This routine sets the parameters of commands 54 or 55 (according to the | 189 | // This routine sets the parameters of commands 54 or 55 (according to the |
188 | // argument which), and returns a pointer to the appropriate structure. | 190 | // argument which), and returns a pointer to the appropriate structure. |
189 | //****************************************************************************** | 191 | //****************************************************************************** |
190 | cmdSyntaxPtr | 192 | static cmdSyntaxPtr |
191 | i2cmdBaudDef(int which, unsigned short rate) | 193 | i2cmdBaudDef(int which, unsigned short rate) |
192 | { | 194 | { |
193 | cmdSyntaxPtr pCM; | 195 | cmdSyntaxPtr pCM; |
diff --git a/drivers/char/ip2/i2cmd.h b/drivers/char/ip2/i2cmd.h index c41728a85710..baa4e721b758 100644 --- a/drivers/char/ip2/i2cmd.h +++ b/drivers/char/ip2/i2cmd.h | |||
@@ -64,16 +64,6 @@ typedef struct _cmdSyntax | |||
64 | // directly from user-level | 64 | // directly from user-level |
65 | #define VAR 0x10 // This command is of variable length! | 65 | #define VAR 0x10 // This command is of variable length! |
66 | 66 | ||
67 | //----------------------------------- | ||
68 | // External declarations for i2cmd.c | ||
69 | //----------------------------------- | ||
70 | // Routine to set up parameters for the "define hot-key sequence" command. Since | ||
71 | // there is more than one parameter to assign, we must use a function rather | ||
72 | // than a macro (used usually). | ||
73 | // | ||
74 | extern cmdSyntaxPtr i2cmdUnixFlags(USHORT iflag,USHORT cflag,USHORT lflag); | ||
75 | extern cmdSyntaxPtr i2cmdBaudDef(int which, USHORT rate); | ||
76 | |||
77 | // Declarations for the global arrays used to bear the commands and their | 67 | // Declarations for the global arrays used to bear the commands and their |
78 | // arguments. | 68 | // arguments. |
79 | // | 69 | // |
@@ -433,6 +423,7 @@ static UCHAR cc02[]; | |||
433 | #define CMD_HOT_ENAB (cmdSyntaxPtr)(ct45) // Enable Hot-key checking | 423 | #define CMD_HOT_ENAB (cmdSyntaxPtr)(ct45) // Enable Hot-key checking |
434 | #define CMD_HOT_DSAB (cmdSyntaxPtr)(ct46) // Disable Hot-key checking | 424 | #define CMD_HOT_DSAB (cmdSyntaxPtr)(ct46) // Disable Hot-key checking |
435 | 425 | ||
426 | #if 0 | ||
436 | // COMMAND 47: Send Protocol info via Unix flags: | 427 | // COMMAND 47: Send Protocol info via Unix flags: |
437 | // iflag = Unix tty t_iflag | 428 | // iflag = Unix tty t_iflag |
438 | // cflag = Unix tty t_cflag | 429 | // cflag = Unix tty t_cflag |
@@ -441,6 +432,7 @@ static UCHAR cc02[]; | |||
441 | // within these flags | 432 | // within these flags |
442 | // | 433 | // |
443 | #define CMD_UNIX_FLAGS(iflag,cflag,lflag) i2cmdUnixFlags(iflag,cflag,lflag) | 434 | #define CMD_UNIX_FLAGS(iflag,cflag,lflag) i2cmdUnixFlags(iflag,cflag,lflag) |
435 | #endif /* 0 */ | ||
444 | 436 | ||
445 | #define CMD_DSRFL_ENAB (cmdSyntaxPtr)(ct48) // Enable DSR receiver ctrl | 437 | #define CMD_DSRFL_ENAB (cmdSyntaxPtr)(ct48) // Enable DSR receiver ctrl |
446 | #define CMD_DSRFL_DSAB (cmdSyntaxPtr)(ct49) // Disable DSR receiver ctrl | 438 | #define CMD_DSRFL_DSAB (cmdSyntaxPtr)(ct49) // Disable DSR receiver ctrl |
diff --git a/drivers/char/ip2main.c b/drivers/char/ip2main.c index 3b8314b4249a..cf0cd58d6305 100644 --- a/drivers/char/ip2main.c +++ b/drivers/char/ip2main.c | |||
@@ -2691,16 +2691,6 @@ no_xon: | |||
2691 | pCh->flags |= ASYNC_CHECK_CD; | 2691 | pCh->flags |= ASYNC_CHECK_CD; |
2692 | } | 2692 | } |
2693 | 2693 | ||
2694 | #ifdef XXX | ||
2695 | do_flags_thing: // This is a test, we don't do the flags thing | ||
2696 | |||
2697 | if ( (cflag & CRTSCTS) ) { | ||
2698 | cflag |= 014000000000; | ||
2699 | } | ||
2700 | i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, | ||
2701 | CMD_UNIX_FLAGS(iflag,cflag,lflag)); | ||
2702 | #endif | ||
2703 | |||
2704 | service_it: | 2694 | service_it: |
2705 | i2DrainOutput( pCh, 100 ); | 2695 | i2DrainOutput( pCh, 100 ); |
2706 | } | 2696 | } |
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 601c7fccb4cf..1bbf507adda5 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -1756,7 +1756,7 @@ static void isicom_flush_buffer(struct tty_struct * tty) | |||
1756 | } | 1756 | } |
1757 | 1757 | ||
1758 | 1758 | ||
1759 | static int __init register_ioregion(void) | 1759 | static int __devinit register_ioregion(void) |
1760 | { | 1760 | { |
1761 | int count, done=0; | 1761 | int count, done=0; |
1762 | for (count=0; count < BOARD_COUNT; count++ ) { | 1762 | for (count=0; count < BOARD_COUNT; count++ ) { |
@@ -1771,7 +1771,7 @@ static int __init register_ioregion(void) | |||
1771 | return done; | 1771 | return done; |
1772 | } | 1772 | } |
1773 | 1773 | ||
1774 | static void __exit unregister_ioregion(void) | 1774 | static void unregister_ioregion(void) |
1775 | { | 1775 | { |
1776 | int count; | 1776 | int count; |
1777 | for (count=0; count < BOARD_COUNT; count++ ) | 1777 | for (count=0; count < BOARD_COUNT; count++ ) |
@@ -1803,7 +1803,7 @@ static struct tty_operations isicom_ops = { | |||
1803 | .tiocmset = isicom_tiocmset, | 1803 | .tiocmset = isicom_tiocmset, |
1804 | }; | 1804 | }; |
1805 | 1805 | ||
1806 | static int __init register_drivers(void) | 1806 | static int __devinit register_drivers(void) |
1807 | { | 1807 | { |
1808 | int error; | 1808 | int error; |
1809 | 1809 | ||
@@ -1834,7 +1834,7 @@ static int __init register_drivers(void) | |||
1834 | return 0; | 1834 | return 0; |
1835 | } | 1835 | } |
1836 | 1836 | ||
1837 | static void __exit unregister_drivers(void) | 1837 | static void unregister_drivers(void) |
1838 | { | 1838 | { |
1839 | int error = tty_unregister_driver(isicom_normal); | 1839 | int error = tty_unregister_driver(isicom_normal); |
1840 | if (error) | 1840 | if (error) |
@@ -1842,7 +1842,7 @@ static void __exit unregister_drivers(void) | |||
1842 | put_tty_driver(isicom_normal); | 1842 | put_tty_driver(isicom_normal); |
1843 | } | 1843 | } |
1844 | 1844 | ||
1845 | static int __init register_isr(void) | 1845 | static int __devinit register_isr(void) |
1846 | { | 1846 | { |
1847 | int count, done=0; | 1847 | int count, done=0; |
1848 | unsigned long irqflags; | 1848 | unsigned long irqflags; |
@@ -1883,7 +1883,7 @@ static void __exit unregister_isr(void) | |||
1883 | } | 1883 | } |
1884 | } | 1884 | } |
1885 | 1885 | ||
1886 | static int __init isicom_init(void) | 1886 | static int __devinit isicom_init(void) |
1887 | { | 1887 | { |
1888 | int card, channel, base; | 1888 | int card, channel, base; |
1889 | struct isi_port * port; | 1889 | struct isi_port * port; |
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index c02a21dbad5d..52a073eee201 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c | |||
@@ -407,7 +407,6 @@ static unsigned long stli_eisamemprobeaddrs[] = { | |||
407 | }; | 407 | }; |
408 | 408 | ||
409 | static int stli_eisamempsize = sizeof(stli_eisamemprobeaddrs) / sizeof(unsigned long); | 409 | static int stli_eisamempsize = sizeof(stli_eisamemprobeaddrs) / sizeof(unsigned long); |
410 | int stli_eisaprobe = STLI_EISAPROBE; | ||
411 | 410 | ||
412 | /* | 411 | /* |
413 | * Define the Stallion PCI vendor and device IDs. | 412 | * Define the Stallion PCI vendor and device IDs. |
@@ -4685,7 +4684,7 @@ static int stli_initbrds(void) | |||
4685 | #ifdef MODULE | 4684 | #ifdef MODULE |
4686 | stli_argbrds(); | 4685 | stli_argbrds(); |
4687 | #endif | 4686 | #endif |
4688 | if (stli_eisaprobe) | 4687 | if (STLI_EISAPROBE) |
4689 | stli_findeisabrds(); | 4688 | stli_findeisabrds(); |
4690 | #ifdef CONFIG_PCI | 4689 | #ifdef CONFIG_PCI |
4691 | stli_findpcibrds(); | 4690 | stli_findpcibrds(); |
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index e3085b22a365..42187381506b 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -23,7 +23,10 @@ | |||
23 | #include <linux/devfs_fs_kernel.h> | 23 | #include <linux/devfs_fs_kernel.h> |
24 | #include <linux/ptrace.h> | 24 | #include <linux/ptrace.h> |
25 | #include <linux/device.h> | 25 | #include <linux/device.h> |
26 | #include <linux/highmem.h> | ||
27 | #include <linux/crash_dump.h> | ||
26 | #include <linux/backing-dev.h> | 28 | #include <linux/backing-dev.h> |
29 | #include <linux/bootmem.h> | ||
27 | 30 | ||
28 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
29 | #include <asm/io.h> | 32 | #include <asm/io.h> |
@@ -273,6 +276,40 @@ static int mmap_kmem(struct file * file, struct vm_area_struct * vma) | |||
273 | return mmap_mem(file, vma); | 276 | return mmap_mem(file, vma); |
274 | } | 277 | } |
275 | 278 | ||
279 | #ifdef CONFIG_CRASH_DUMP | ||
280 | /* | ||
281 | * Read memory corresponding to the old kernel. | ||
282 | */ | ||
283 | static ssize_t read_oldmem(struct file *file, char __user *buf, | ||
284 | size_t count, loff_t *ppos) | ||
285 | { | ||
286 | unsigned long pfn, offset; | ||
287 | size_t read = 0, csize; | ||
288 | int rc = 0; | ||
289 | |||
290 | while (count) { | ||
291 | pfn = *ppos / PAGE_SIZE; | ||
292 | if (pfn > saved_max_pfn) | ||
293 | return read; | ||
294 | |||
295 | offset = (unsigned long)(*ppos % PAGE_SIZE); | ||
296 | if (count > PAGE_SIZE - offset) | ||
297 | csize = PAGE_SIZE - offset; | ||
298 | else | ||
299 | csize = count; | ||
300 | |||
301 | rc = copy_oldmem_page(pfn, buf, csize, offset, 1); | ||
302 | if (rc < 0) | ||
303 | return rc; | ||
304 | buf += csize; | ||
305 | *ppos += csize; | ||
306 | read += csize; | ||
307 | count -= csize; | ||
308 | } | ||
309 | return read; | ||
310 | } | ||
311 | #endif | ||
312 | |||
276 | extern long vread(char *buf, char *addr, unsigned long count); | 313 | extern long vread(char *buf, char *addr, unsigned long count); |
277 | extern long vwrite(char *buf, char *addr, unsigned long count); | 314 | extern long vwrite(char *buf, char *addr, unsigned long count); |
278 | 315 | ||
@@ -721,6 +758,7 @@ static int open_port(struct inode * inode, struct file * filp) | |||
721 | #define read_full read_zero | 758 | #define read_full read_zero |
722 | #define open_mem open_port | 759 | #define open_mem open_port |
723 | #define open_kmem open_mem | 760 | #define open_kmem open_mem |
761 | #define open_oldmem open_mem | ||
724 | 762 | ||
725 | static struct file_operations mem_fops = { | 763 | static struct file_operations mem_fops = { |
726 | .llseek = memory_lseek, | 764 | .llseek = memory_lseek, |
@@ -770,6 +808,13 @@ static struct file_operations full_fops = { | |||
770 | .write = write_full, | 808 | .write = write_full, |
771 | }; | 809 | }; |
772 | 810 | ||
811 | #ifdef CONFIG_CRASH_DUMP | ||
812 | static struct file_operations oldmem_fops = { | ||
813 | .read = read_oldmem, | ||
814 | .open = open_oldmem, | ||
815 | }; | ||
816 | #endif | ||
817 | |||
773 | static ssize_t kmsg_write(struct file * file, const char __user * buf, | 818 | static ssize_t kmsg_write(struct file * file, const char __user * buf, |
774 | size_t count, loff_t *ppos) | 819 | size_t count, loff_t *ppos) |
775 | { | 820 | { |
@@ -825,6 +870,11 @@ static int memory_open(struct inode * inode, struct file * filp) | |||
825 | case 11: | 870 | case 11: |
826 | filp->f_op = &kmsg_fops; | 871 | filp->f_op = &kmsg_fops; |
827 | break; | 872 | break; |
873 | #ifdef CONFIG_CRASH_DUMP | ||
874 | case 12: | ||
875 | filp->f_op = &oldmem_fops; | ||
876 | break; | ||
877 | #endif | ||
828 | default: | 878 | default: |
829 | return -ENXIO; | 879 | return -ENXIO; |
830 | } | 880 | } |
@@ -854,6 +904,9 @@ static const struct { | |||
854 | {8, "random", S_IRUGO | S_IWUSR, &random_fops}, | 904 | {8, "random", S_IRUGO | S_IWUSR, &random_fops}, |
855 | {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops}, | 905 | {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops}, |
856 | {11,"kmsg", S_IRUGO | S_IWUSR, &kmsg_fops}, | 906 | {11,"kmsg", S_IRUGO | S_IWUSR, &kmsg_fops}, |
907 | #ifdef CONFIG_CRASH_DUMP | ||
908 | {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops}, | ||
909 | #endif | ||
857 | }; | 910 | }; |
858 | 911 | ||
859 | static struct class *mem_class; | 912 | static struct class *mem_class; |
diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 3115d318b997..31cf84d69026 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c | |||
@@ -66,8 +66,6 @@ static unsigned char misc_minors[DYNAMIC_MINORS / 8]; | |||
66 | extern int rtc_DP8570A_init(void); | 66 | extern int rtc_DP8570A_init(void); |
67 | extern int rtc_MK48T08_init(void); | 67 | extern int rtc_MK48T08_init(void); |
68 | extern int pmu_device_init(void); | 68 | extern int pmu_device_init(void); |
69 | extern int tosh_init(void); | ||
70 | extern int i8k_init(void); | ||
71 | 69 | ||
72 | #ifdef CONFIG_PROC_FS | 70 | #ifdef CONFIG_PROC_FS |
73 | static void *misc_seq_start(struct seq_file *seq, loff_t *pos) | 71 | static void *misc_seq_start(struct seq_file *seq, loff_t *pos) |
@@ -314,12 +312,6 @@ static int __init misc_init(void) | |||
314 | #ifdef CONFIG_PMAC_PBOOK | 312 | #ifdef CONFIG_PMAC_PBOOK |
315 | pmu_device_init(); | 313 | pmu_device_init(); |
316 | #endif | 314 | #endif |
317 | #ifdef CONFIG_TOSHIBA | ||
318 | tosh_init(); | ||
319 | #endif | ||
320 | #ifdef CONFIG_I8K | ||
321 | i8k_init(); | ||
322 | #endif | ||
323 | if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) { | 315 | if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) { |
324 | printk("unable to get major %d for misc devices\n", | 316 | printk("unable to get major %d for misc devices\n", |
325 | MISC_MAJOR); | 317 | MISC_MAJOR); |
diff --git a/drivers/char/mwave/3780i.c b/drivers/char/mwave/3780i.c index ab00f51475df..613aed9e1840 100644 --- a/drivers/char/mwave/3780i.c +++ b/drivers/char/mwave/3780i.c | |||
@@ -107,8 +107,8 @@ void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO, | |||
107 | spin_unlock_irqrestore(&dsp_lock, flags); | 107 | spin_unlock_irqrestore(&dsp_lock, flags); |
108 | } | 108 | } |
109 | 109 | ||
110 | void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex, | 110 | static void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex, |
111 | unsigned char ucValue) | 111 | unsigned char ucValue) |
112 | { | 112 | { |
113 | DSP_ISA_SLAVE_CONTROL rSlaveControl; | 113 | DSP_ISA_SLAVE_CONTROL rSlaveControl; |
114 | DSP_ISA_SLAVE_CONTROL rSlaveControl_Save; | 114 | DSP_ISA_SLAVE_CONTROL rSlaveControl_Save; |
@@ -141,6 +141,7 @@ void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex, | |||
141 | 141 | ||
142 | } | 142 | } |
143 | 143 | ||
144 | #if 0 | ||
144 | unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO, | 145 | unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO, |
145 | unsigned uIndex) | 146 | unsigned uIndex) |
146 | { | 147 | { |
@@ -167,6 +168,7 @@ unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO, | |||
167 | 168 | ||
168 | return ucValue; | 169 | return ucValue; |
169 | } | 170 | } |
171 | #endif /* 0 */ | ||
170 | 172 | ||
171 | int dsp3780I_EnableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings, | 173 | int dsp3780I_EnableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings, |
172 | unsigned short *pIrqMap, | 174 | unsigned short *pIrqMap, |
diff --git a/drivers/char/mwave/3780i.h b/drivers/char/mwave/3780i.h index 3e7d020d1bf4..270431ca7dae 100644 --- a/drivers/char/mwave/3780i.h +++ b/drivers/char/mwave/3780i.h | |||
@@ -338,10 +338,6 @@ unsigned short dsp3780I_ReadMsaCfg(unsigned short usDspBaseIO, | |||
338 | unsigned long ulMsaAddr); | 338 | unsigned long ulMsaAddr); |
339 | void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO, | 339 | void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO, |
340 | unsigned long ulMsaAddr, unsigned short usValue); | 340 | unsigned long ulMsaAddr, unsigned short usValue); |
341 | void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex, | ||
342 | unsigned char ucValue); | ||
343 | unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO, | ||
344 | unsigned uIndex); | ||
345 | int dsp3780I_GetIPCSource(unsigned short usDspBaseIO, | 341 | int dsp3780I_GetIPCSource(unsigned short usDspBaseIO, |
346 | unsigned short *pusIPCSource); | 342 | unsigned short *pusIPCSource); |
347 | 343 | ||
diff --git a/drivers/char/mwave/tp3780i.c b/drivers/char/mwave/tp3780i.c index ab650cd6efc0..d6c72e0934e2 100644 --- a/drivers/char/mwave/tp3780i.c +++ b/drivers/char/mwave/tp3780i.c | |||
@@ -242,20 +242,14 @@ int tp3780I_ClaimResources(THINKPAD_BD_DATA * pBDData) | |||
242 | { | 242 | { |
243 | int retval = 0; | 243 | int retval = 0; |
244 | DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; | 244 | DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; |
245 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) | ||
246 | struct resource *pres; | 245 | struct resource *pres; |
247 | #endif | ||
248 | 246 | ||
249 | PRINTK_2(TRACE_TP3780I, | 247 | PRINTK_2(TRACE_TP3780I, |
250 | "tp3780i::tp3780I_ClaimResources entry pBDData %p\n", pBDData); | 248 | "tp3780i::tp3780I_ClaimResources entry pBDData %p\n", pBDData); |
251 | 249 | ||
252 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) | ||
253 | pres = request_region(pSettings->usDspBaseIO, 16, "mwave_3780i"); | 250 | pres = request_region(pSettings->usDspBaseIO, 16, "mwave_3780i"); |
254 | if ( pres == NULL ) retval = -EIO; | 251 | if ( pres == NULL ) retval = -EIO; |
255 | #else | 252 | |
256 | retval = check_region(pSettings->usDspBaseIO, 16); | ||
257 | if (!retval) request_region(pSettings->usDspBaseIO, 16, "mwave_3780i"); | ||
258 | #endif | ||
259 | if (retval) { | 253 | if (retval) { |
260 | PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_ClaimResources: Error: Could not claim I/O region starting at %x\n", pSettings->usDspBaseIO); | 254 | PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_ClaimResources: Error: Could not claim I/O region starting at %x\n", pSettings->usDspBaseIO); |
261 | retval = -EIO; | 255 | retval = -EIO; |
@@ -292,7 +286,7 @@ int tp3780I_ReleaseResources(THINKPAD_BD_DATA * pBDData) | |||
292 | int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData) | 286 | int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData) |
293 | { | 287 | { |
294 | DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; | 288 | DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; |
295 | BOOLEAN bDSPPoweredUp = FALSE, bDSPEnabled = FALSE, bInterruptAllocated = FALSE; | 289 | BOOLEAN bDSPPoweredUp = FALSE, bInterruptAllocated = FALSE; |
296 | 290 | ||
297 | PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_EnableDSP entry pBDData %p\n", pBDData); | 291 | PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_EnableDSP entry pBDData %p\n", pBDData); |
298 | 292 | ||
@@ -397,8 +391,6 @@ int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData) | |||
397 | if (dsp3780I_EnableDSP(pSettings, s_ausThinkpadIrqToField, s_ausThinkpadDmaToField)) { | 391 | if (dsp3780I_EnableDSP(pSettings, s_ausThinkpadIrqToField, s_ausThinkpadDmaToField)) { |
398 | PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Error: dsp7880I_EnableDSP() failed\n"); | 392 | PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Error: dsp7880I_EnableDSP() failed\n"); |
399 | goto exit_cleanup; | 393 | goto exit_cleanup; |
400 | } else { | ||
401 | bDSPEnabled = TRUE; | ||
402 | } | 394 | } |
403 | 395 | ||
404 | EnableSRAM(pBDData); | 396 | EnableSRAM(pBDData); |
@@ -411,8 +403,6 @@ int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData) | |||
411 | 403 | ||
412 | exit_cleanup: | 404 | exit_cleanup: |
413 | PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Cleaning up\n"); | 405 | PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Cleaning up\n"); |
414 | if (bDSPEnabled) | ||
415 | dsp3780I_DisableDSP(pSettings); | ||
416 | if (bDSPPoweredUp) | 406 | if (bDSPPoweredUp) |
417 | smapi_set_DSP_power_state(FALSE); | 407 | smapi_set_DSP_power_state(FALSE); |
418 | if (bInterruptAllocated) { | 408 | if (bInterruptAllocated) { |
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c index f63a3fd7ca6f..1af733d07321 100644 --- a/drivers/char/nvram.c +++ b/drivers/char/nvram.c | |||
@@ -211,12 +211,13 @@ nvram_check_checksum(void) | |||
211 | return rv; | 211 | return rv; |
212 | } | 212 | } |
213 | 213 | ||
214 | void | 214 | static void |
215 | __nvram_set_checksum(void) | 215 | __nvram_set_checksum(void) |
216 | { | 216 | { |
217 | mach_set_checksum(); | 217 | mach_set_checksum(); |
218 | } | 218 | } |
219 | 219 | ||
220 | #if 0 | ||
220 | void | 221 | void |
221 | nvram_set_checksum(void) | 222 | nvram_set_checksum(void) |
222 | { | 223 | { |
@@ -226,6 +227,7 @@ nvram_set_checksum(void) | |||
226 | __nvram_set_checksum(); | 227 | __nvram_set_checksum(); |
227 | spin_unlock_irqrestore(&rtc_lock, flags); | 228 | spin_unlock_irqrestore(&rtc_lock, flags); |
228 | } | 229 | } |
230 | #endif /* 0 */ | ||
229 | 231 | ||
230 | /* | 232 | /* |
231 | * The are the file operation function for user access to /dev/nvram | 233 | * The are the file operation function for user access to /dev/nvram |
@@ -921,6 +923,4 @@ EXPORT_SYMBOL(__nvram_write_byte); | |||
921 | EXPORT_SYMBOL(nvram_write_byte); | 923 | EXPORT_SYMBOL(nvram_write_byte); |
922 | EXPORT_SYMBOL(__nvram_check_checksum); | 924 | EXPORT_SYMBOL(__nvram_check_checksum); |
923 | EXPORT_SYMBOL(nvram_check_checksum); | 925 | EXPORT_SYMBOL(nvram_check_checksum); |
924 | EXPORT_SYMBOL(__nvram_set_checksum); | ||
925 | EXPORT_SYMBOL(nvram_set_checksum); | ||
926 | MODULE_ALIAS_MISCDEV(NVRAM_MINOR); | 926 | MODULE_ALIAS_MISCDEV(NVRAM_MINOR); |
diff --git a/drivers/char/rio/func.h b/drivers/char/rio/func.h index e8f3860f4726..01987c6dc398 100644 --- a/drivers/char/rio/func.h +++ b/drivers/char/rio/func.h | |||
@@ -147,7 +147,6 @@ struct rio_info * rio_info_store( int cmd, struct rio_info * p); | |||
147 | extern int rio_pcicopy(char *src, char *dst, int n); | 147 | extern int rio_pcicopy(char *src, char *dst, int n); |
148 | extern int rio_minor (struct tty_struct *tty); | 148 | extern int rio_minor (struct tty_struct *tty); |
149 | extern int rio_ismodem (struct tty_struct *tty); | 149 | extern int rio_ismodem (struct tty_struct *tty); |
150 | extern void rio_udelay (int usecs); | ||
151 | 150 | ||
152 | extern void rio_start_card_running (struct Host * HostP); | 151 | extern void rio_start_card_running (struct Host * HostP); |
153 | 152 | ||
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c index 763893e289b3..7db3370f4972 100644 --- a/drivers/char/rio/rio_linux.c +++ b/drivers/char/rio/rio_linux.c | |||
@@ -354,11 +354,6 @@ int rio_ismodem(struct tty_struct *tty) | |||
354 | } | 354 | } |
355 | 355 | ||
356 | 356 | ||
357 | void rio_udelay (int usecs) | ||
358 | { | ||
359 | udelay (usecs); | ||
360 | } | ||
361 | |||
362 | static int rio_set_real_termios (void *ptr) | 357 | static int rio_set_real_termios (void *ptr) |
363 | { | 358 | { |
364 | int rv, modem; | 359 | int rv, modem; |
diff --git a/drivers/char/rio/rioinit.c b/drivers/char/rio/rioinit.c index dca941ed10cf..898a126ae3e6 100644 --- a/drivers/char/rio/rioinit.c +++ b/drivers/char/rio/rioinit.c | |||
@@ -37,6 +37,7 @@ static char *_rioinit_c_sccs_ = "@(#)rioinit.c 1.3"; | |||
37 | #include <linux/module.h> | 37 | #include <linux/module.h> |
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/errno.h> | 39 | #include <linux/errno.h> |
40 | #include <linux/delay.h> | ||
40 | #include <asm/io.h> | 41 | #include <asm/io.h> |
41 | #include <asm/system.h> | 42 | #include <asm/system.h> |
42 | #include <asm/string.h> | 43 | #include <asm/string.h> |
@@ -1560,14 +1561,14 @@ uint Slot; | |||
1560 | INTERRUPT_DISABLE | BYTE_OPERATION | | 1561 | INTERRUPT_DISABLE | BYTE_OPERATION | |
1561 | SLOW_LINKS | SLOW_AT_BUS); | 1562 | SLOW_LINKS | SLOW_AT_BUS); |
1562 | WBYTE(DpRamP->DpResetTpu, 0xFF); | 1563 | WBYTE(DpRamP->DpResetTpu, 0xFF); |
1563 | rio_udelay (3); | 1564 | udelay(3); |
1564 | 1565 | ||
1565 | rio_dprintk (RIO_DEBUG_INIT, "RIOHostReset: Don't know if it worked. Try reset again\n"); | 1566 | rio_dprintk (RIO_DEBUG_INIT, "RIOHostReset: Don't know if it worked. Try reset again\n"); |
1566 | WBYTE(DpRamP->DpControl, BOOT_FROM_RAM | EXTERNAL_BUS_OFF | | 1567 | WBYTE(DpRamP->DpControl, BOOT_FROM_RAM | EXTERNAL_BUS_OFF | |
1567 | INTERRUPT_DISABLE | BYTE_OPERATION | | 1568 | INTERRUPT_DISABLE | BYTE_OPERATION | |
1568 | SLOW_LINKS | SLOW_AT_BUS); | 1569 | SLOW_LINKS | SLOW_AT_BUS); |
1569 | WBYTE(DpRamP->DpResetTpu, 0xFF); | 1570 | WBYTE(DpRamP->DpResetTpu, 0xFF); |
1570 | rio_udelay (3); | 1571 | udelay(3); |
1571 | break; | 1572 | break; |
1572 | #ifdef FUTURE_RELEASE | 1573 | #ifdef FUTURE_RELEASE |
1573 | case RIO_EISA: | 1574 | case RIO_EISA: |
@@ -1599,7 +1600,7 @@ uint Slot; | |||
1599 | DpRamP->DpControl = RIO_PCI_BOOT_FROM_RAM; | 1600 | DpRamP->DpControl = RIO_PCI_BOOT_FROM_RAM; |
1600 | DpRamP->DpResetInt = 0xFF; | 1601 | DpRamP->DpResetInt = 0xFF; |
1601 | DpRamP->DpResetTpu = 0xFF; | 1602 | DpRamP->DpResetTpu = 0xFF; |
1602 | rio_udelay (100); | 1603 | udelay(100); |
1603 | /* for (i=0; i<6000; i++); */ | 1604 | /* for (i=0; i<6000; i++); */ |
1604 | /* suspend( 3 ); */ | 1605 | /* suspend( 3 ); */ |
1605 | break; | 1606 | break; |
diff --git a/drivers/char/rio/riotty.c b/drivers/char/rio/riotty.c index db655002671f..78a321afdf4f 100644 --- a/drivers/char/rio/riotty.c +++ b/drivers/char/rio/riotty.c | |||
@@ -524,16 +524,16 @@ riotclose(void *ptr) | |||
524 | register uint SysPort = dev; | 524 | register uint SysPort = dev; |
525 | struct ttystatics *tp; /* pointer to our ttystruct */ | 525 | struct ttystatics *tp; /* pointer to our ttystruct */ |
526 | #endif | 526 | #endif |
527 | struct Port *PortP =ptr; /* pointer to the port structure */ | 527 | struct Port *PortP = ptr; /* pointer to the port structure */ |
528 | int deleted = 0; | 528 | int deleted = 0; |
529 | int try = -1; /* Disable the timeouts by setting them to -1 */ | 529 | int try = -1; /* Disable the timeouts by setting them to -1 */ |
530 | int repeat_this = -1; /* Congrats to those having 15 years of | 530 | int repeat_this = -1; /* Congrats to those having 15 years of |
531 | uptime! (You get to break the driver.) */ | 531 | uptime! (You get to break the driver.) */ |
532 | long end_time; | 532 | unsigned long end_time; |
533 | struct tty_struct * tty; | 533 | struct tty_struct * tty; |
534 | unsigned long flags; | 534 | unsigned long flags; |
535 | int Modem; | 535 | int Modem; |
536 | int rv =0; | 536 | int rv = 0; |
537 | 537 | ||
538 | rio_dprintk (RIO_DEBUG_TTY, "port close SysPort %d\n",PortP->PortNum); | 538 | rio_dprintk (RIO_DEBUG_TTY, "port close SysPort %d\n",PortP->PortNum); |
539 | 539 | ||
@@ -620,7 +620,7 @@ riotclose(void *ptr) | |||
620 | if (repeat_this -- <= 0) { | 620 | if (repeat_this -- <= 0) { |
621 | rv = -EINTR; | 621 | rv = -EINTR; |
622 | rio_dprintk (RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n"); | 622 | rio_dprintk (RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n"); |
623 | RIOPreemptiveCmd(p, PortP, FCLOSE ); | 623 | RIOPreemptiveCmd(p, PortP, FCLOSE); |
624 | goto close_end; | 624 | goto close_end; |
625 | } | 625 | } |
626 | rio_dprintk (RIO_DEBUG_TTY, "Calling timeout to flush in closing\n"); | 626 | rio_dprintk (RIO_DEBUG_TTY, "Calling timeout to flush in closing\n"); |
@@ -656,14 +656,12 @@ riotclose(void *ptr) | |||
656 | goto close_end; | 656 | goto close_end; |
657 | } | 657 | } |
658 | 658 | ||
659 | |||
660 | |||
661 | /* Can't call RIOShortCommand with the port locked. */ | 659 | /* Can't call RIOShortCommand with the port locked. */ |
662 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | 660 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); |
663 | 661 | ||
664 | if (RIOShortCommand(p, PortP, CLOSE, 1, 0) == RIO_FAIL) { | 662 | if (RIOShortCommand(p, PortP, CLOSE, 1, 0) == RIO_FAIL) { |
665 | RIOPreemptiveCmd(p, PortP,FCLOSE); | 663 | RIOPreemptiveCmd(p, PortP, FCLOSE); |
666 | goto close_end; | 664 | goto close_end; |
667 | } | 665 | } |
668 | 666 | ||
669 | if (!deleted) | 667 | if (!deleted) |
@@ -698,7 +696,6 @@ riotclose(void *ptr) | |||
698 | */ | 696 | */ |
699 | PortP->Config &= ~(RIO_CTSFLOW|RIO_RTSFLOW); | 697 | PortP->Config &= ~(RIO_CTSFLOW|RIO_RTSFLOW); |
700 | 698 | ||
701 | |||
702 | #ifdef STATS | 699 | #ifdef STATS |
703 | PortP->Stat.CloseCnt++; | 700 | PortP->Stat.CloseCnt++; |
704 | #endif | 701 | #endif |
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index 5bcbeb0cb9ae..f463d6baa685 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c | |||
@@ -161,6 +161,64 @@ static Word_t upci_aiop_intr_bits[AIOP_CTL_SIZE] = { | |||
161 | UPCI_AIOP_INTR_BIT_3 | 161 | UPCI_AIOP_INTR_BIT_3 |
162 | }; | 162 | }; |
163 | 163 | ||
164 | static Byte_t RData[RDATASIZE] = { | ||
165 | 0x00, 0x09, 0xf6, 0x82, | ||
166 | 0x02, 0x09, 0x86, 0xfb, | ||
167 | 0x04, 0x09, 0x00, 0x0a, | ||
168 | 0x06, 0x09, 0x01, 0x0a, | ||
169 | 0x08, 0x09, 0x8a, 0x13, | ||
170 | 0x0a, 0x09, 0xc5, 0x11, | ||
171 | 0x0c, 0x09, 0x86, 0x85, | ||
172 | 0x0e, 0x09, 0x20, 0x0a, | ||
173 | 0x10, 0x09, 0x21, 0x0a, | ||
174 | 0x12, 0x09, 0x41, 0xff, | ||
175 | 0x14, 0x09, 0x82, 0x00, | ||
176 | 0x16, 0x09, 0x82, 0x7b, | ||
177 | 0x18, 0x09, 0x8a, 0x7d, | ||
178 | 0x1a, 0x09, 0x88, 0x81, | ||
179 | 0x1c, 0x09, 0x86, 0x7a, | ||
180 | 0x1e, 0x09, 0x84, 0x81, | ||
181 | 0x20, 0x09, 0x82, 0x7c, | ||
182 | 0x22, 0x09, 0x0a, 0x0a | ||
183 | }; | ||
184 | |||
185 | static Byte_t RRegData[RREGDATASIZE] = { | ||
186 | 0x00, 0x09, 0xf6, 0x82, /* 00: Stop Rx processor */ | ||
187 | 0x08, 0x09, 0x8a, 0x13, /* 04: Tx software flow control */ | ||
188 | 0x0a, 0x09, 0xc5, 0x11, /* 08: XON char */ | ||
189 | 0x0c, 0x09, 0x86, 0x85, /* 0c: XANY */ | ||
190 | 0x12, 0x09, 0x41, 0xff, /* 10: Rx mask char */ | ||
191 | 0x14, 0x09, 0x82, 0x00, /* 14: Compare/Ignore #0 */ | ||
192 | 0x16, 0x09, 0x82, 0x7b, /* 18: Compare #1 */ | ||
193 | 0x18, 0x09, 0x8a, 0x7d, /* 1c: Compare #2 */ | ||
194 | 0x1a, 0x09, 0x88, 0x81, /* 20: Interrupt #1 */ | ||
195 | 0x1c, 0x09, 0x86, 0x7a, /* 24: Ignore/Replace #1 */ | ||
196 | 0x1e, 0x09, 0x84, 0x81, /* 28: Interrupt #2 */ | ||
197 | 0x20, 0x09, 0x82, 0x7c, /* 2c: Ignore/Replace #2 */ | ||
198 | 0x22, 0x09, 0x0a, 0x0a /* 30: Rx FIFO Enable */ | ||
199 | }; | ||
200 | |||
201 | static CONTROLLER_T sController[CTL_SIZE] = { | ||
202 | {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, | ||
203 | {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}, | ||
204 | {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, | ||
205 | {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}, | ||
206 | {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, | ||
207 | {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}, | ||
208 | {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, | ||
209 | {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}} | ||
210 | }; | ||
211 | |||
212 | static Byte_t sBitMapClrTbl[8] = { | ||
213 | 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f | ||
214 | }; | ||
215 | |||
216 | static Byte_t sBitMapSetTbl[8] = { | ||
217 | 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 | ||
218 | }; | ||
219 | |||
220 | static int sClockPrescale = 0x14; | ||
221 | |||
164 | /* | 222 | /* |
165 | * Line number is the ttySIx number (x), the Minor number. We | 223 | * Line number is the ttySIx number (x), the Minor number. We |
166 | * assign them sequentially, starting at zero. The following | 224 | * assign them sequentially, starting at zero. The following |
@@ -177,6 +235,26 @@ static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model); | |||
177 | static unsigned char GetLineNumber(int ctrl, int aiop, int ch); | 235 | static unsigned char GetLineNumber(int ctrl, int aiop, int ch); |
178 | static unsigned char SetLineNumber(int ctrl, int aiop, int ch); | 236 | static unsigned char SetLineNumber(int ctrl, int aiop, int ch); |
179 | static void rp_start(struct tty_struct *tty); | 237 | static void rp_start(struct tty_struct *tty); |
238 | static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum, | ||
239 | int ChanNum); | ||
240 | static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode); | ||
241 | static void sFlushRxFIFO(CHANNEL_T * ChP); | ||
242 | static void sFlushTxFIFO(CHANNEL_T * ChP); | ||
243 | static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags); | ||
244 | static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags); | ||
245 | static void sModemReset(CONTROLLER_T * CtlP, int chan, int on); | ||
246 | static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on); | ||
247 | static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data); | ||
248 | static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum, | ||
249 | ByteIO_t * AiopIOList, int AiopIOListSize, | ||
250 | WordIO_t ConfigIO, int IRQNum, Byte_t Frequency, | ||
251 | int PeriodicOnly, int altChanRingIndicator, | ||
252 | int UPCIRingInd); | ||
253 | static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO, | ||
254 | ByteIO_t * AiopIOList, int AiopIOListSize, | ||
255 | int IRQNum, Byte_t Frequency, int PeriodicOnly); | ||
256 | static int sReadAiopID(ByteIO_t io); | ||
257 | static int sReadAiopNumChan(WordIO_t io); | ||
180 | 258 | ||
181 | #ifdef MODULE | 259 | #ifdef MODULE |
182 | MODULE_AUTHOR("Theodore Ts'o"); | 260 | MODULE_AUTHOR("Theodore Ts'o"); |
@@ -1798,7 +1876,7 @@ static void rp_flush_buffer(struct tty_struct *tty) | |||
1798 | * init's aiopic and serial port hardware. | 1876 | * init's aiopic and serial port hardware. |
1799 | * Inputs: i is the board number (0-n) | 1877 | * Inputs: i is the board number (0-n) |
1800 | */ | 1878 | */ |
1801 | __init int register_PCI(int i, struct pci_dev *dev) | 1879 | static __init int register_PCI(int i, struct pci_dev *dev) |
1802 | { | 1880 | { |
1803 | int num_aiops, aiop, max_num_aiops, num_chan, chan; | 1881 | int num_aiops, aiop, max_num_aiops, num_chan, chan; |
1804 | unsigned int aiopio[MAX_AIOPS_PER_BOARD]; | 1882 | unsigned int aiopio[MAX_AIOPS_PER_BOARD]; |
@@ -2453,72 +2531,6 @@ static void rp_cleanup_module(void) | |||
2453 | } | 2531 | } |
2454 | #endif | 2532 | #endif |
2455 | 2533 | ||
2456 | #ifndef TRUE | ||
2457 | #define TRUE 1 | ||
2458 | #endif | ||
2459 | |||
2460 | #ifndef FALSE | ||
2461 | #define FALSE 0 | ||
2462 | #endif | ||
2463 | |||
2464 | static Byte_t RData[RDATASIZE] = { | ||
2465 | 0x00, 0x09, 0xf6, 0x82, | ||
2466 | 0x02, 0x09, 0x86, 0xfb, | ||
2467 | 0x04, 0x09, 0x00, 0x0a, | ||
2468 | 0x06, 0x09, 0x01, 0x0a, | ||
2469 | 0x08, 0x09, 0x8a, 0x13, | ||
2470 | 0x0a, 0x09, 0xc5, 0x11, | ||
2471 | 0x0c, 0x09, 0x86, 0x85, | ||
2472 | 0x0e, 0x09, 0x20, 0x0a, | ||
2473 | 0x10, 0x09, 0x21, 0x0a, | ||
2474 | 0x12, 0x09, 0x41, 0xff, | ||
2475 | 0x14, 0x09, 0x82, 0x00, | ||
2476 | 0x16, 0x09, 0x82, 0x7b, | ||
2477 | 0x18, 0x09, 0x8a, 0x7d, | ||
2478 | 0x1a, 0x09, 0x88, 0x81, | ||
2479 | 0x1c, 0x09, 0x86, 0x7a, | ||
2480 | 0x1e, 0x09, 0x84, 0x81, | ||
2481 | 0x20, 0x09, 0x82, 0x7c, | ||
2482 | 0x22, 0x09, 0x0a, 0x0a | ||
2483 | }; | ||
2484 | |||
2485 | static Byte_t RRegData[RREGDATASIZE] = { | ||
2486 | 0x00, 0x09, 0xf6, 0x82, /* 00: Stop Rx processor */ | ||
2487 | 0x08, 0x09, 0x8a, 0x13, /* 04: Tx software flow control */ | ||
2488 | 0x0a, 0x09, 0xc5, 0x11, /* 08: XON char */ | ||
2489 | 0x0c, 0x09, 0x86, 0x85, /* 0c: XANY */ | ||
2490 | 0x12, 0x09, 0x41, 0xff, /* 10: Rx mask char */ | ||
2491 | 0x14, 0x09, 0x82, 0x00, /* 14: Compare/Ignore #0 */ | ||
2492 | 0x16, 0x09, 0x82, 0x7b, /* 18: Compare #1 */ | ||
2493 | 0x18, 0x09, 0x8a, 0x7d, /* 1c: Compare #2 */ | ||
2494 | 0x1a, 0x09, 0x88, 0x81, /* 20: Interrupt #1 */ | ||
2495 | 0x1c, 0x09, 0x86, 0x7a, /* 24: Ignore/Replace #1 */ | ||
2496 | 0x1e, 0x09, 0x84, 0x81, /* 28: Interrupt #2 */ | ||
2497 | 0x20, 0x09, 0x82, 0x7c, /* 2c: Ignore/Replace #2 */ | ||
2498 | 0x22, 0x09, 0x0a, 0x0a /* 30: Rx FIFO Enable */ | ||
2499 | }; | ||
2500 | |||
2501 | CONTROLLER_T sController[CTL_SIZE] = { | ||
2502 | {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, | ||
2503 | {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}, | ||
2504 | {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, | ||
2505 | {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}, | ||
2506 | {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, | ||
2507 | {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}, | ||
2508 | {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, | ||
2509 | {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}} | ||
2510 | }; | ||
2511 | |||
2512 | Byte_t sBitMapClrTbl[8] = { | ||
2513 | 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f | ||
2514 | }; | ||
2515 | |||
2516 | Byte_t sBitMapSetTbl[8] = { | ||
2517 | 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 | ||
2518 | }; | ||
2519 | |||
2520 | int sClockPrescale = 0x14; | ||
2521 | |||
2522 | /*************************************************************************** | 2534 | /*************************************************************************** |
2523 | Function: sInitController | 2535 | Function: sInitController |
2524 | Purpose: Initialization of controller global registers and controller | 2536 | Purpose: Initialization of controller global registers and controller |
@@ -2554,22 +2566,22 @@ Call: sInitController(CtlP,CtlNum,MudbacIO,AiopIOList,AiopIOListSize, | |||
2554 | FREQ_4HZ - 4 Hertz | 2566 | FREQ_4HZ - 4 Hertz |
2555 | If IRQNum is set to 0 the Frequency parameter is | 2567 | If IRQNum is set to 0 the Frequency parameter is |
2556 | overidden, it is forced to a value of FREQ_DIS. | 2568 | overidden, it is forced to a value of FREQ_DIS. |
2557 | int PeriodicOnly: TRUE if all interrupts except the periodic | 2569 | int PeriodicOnly: 1 if all interrupts except the periodic |
2558 | interrupt are to be blocked. | 2570 | interrupt are to be blocked. |
2559 | FALSE is both the periodic interrupt and | 2571 | 0 is both the periodic interrupt and |
2560 | other channel interrupts are allowed. | 2572 | other channel interrupts are allowed. |
2561 | If IRQNum is set to 0 the PeriodicOnly parameter is | 2573 | If IRQNum is set to 0 the PeriodicOnly parameter is |
2562 | overidden, it is forced to a value of FALSE. | 2574 | overidden, it is forced to a value of 0. |
2563 | Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller | 2575 | Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller |
2564 | initialization failed. | 2576 | initialization failed. |
2565 | 2577 | ||
2566 | Comments: | 2578 | Comments: |
2567 | If periodic interrupts are to be disabled but AIOP interrupts | 2579 | If periodic interrupts are to be disabled but AIOP interrupts |
2568 | are allowed, set Frequency to FREQ_DIS and PeriodicOnly to FALSE. | 2580 | are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0. |
2569 | 2581 | ||
2570 | If interrupts are to be completely disabled set IRQNum to 0. | 2582 | If interrupts are to be completely disabled set IRQNum to 0. |
2571 | 2583 | ||
2572 | Setting Frequency to FREQ_DIS and PeriodicOnly to TRUE is an | 2584 | Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an |
2573 | invalid combination. | 2585 | invalid combination. |
2574 | 2586 | ||
2575 | This function performs initialization of global interrupt modes, | 2587 | This function performs initialization of global interrupt modes, |
@@ -2589,9 +2601,9 @@ Warnings: No range checking on any of the parameters is done. | |||
2589 | After this function all AIOPs on the controller are disabled, | 2601 | After this function all AIOPs on the controller are disabled, |
2590 | they can be enabled with sEnAiop(). | 2602 | they can be enabled with sEnAiop(). |
2591 | */ | 2603 | */ |
2592 | int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO, | 2604 | static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO, |
2593 | ByteIO_t * AiopIOList, int AiopIOListSize, int IRQNum, | 2605 | ByteIO_t * AiopIOList, int AiopIOListSize, |
2594 | Byte_t Frequency, int PeriodicOnly) | 2606 | int IRQNum, Byte_t Frequency, int PeriodicOnly) |
2595 | { | 2607 | { |
2596 | int i; | 2608 | int i; |
2597 | ByteIO_t io; | 2609 | ByteIO_t io; |
@@ -2687,22 +2699,22 @@ Call: sPCIInitController(CtlP,CtlNum,AiopIOList,AiopIOListSize, | |||
2687 | FREQ_4HZ - 4 Hertz | 2699 | FREQ_4HZ - 4 Hertz |
2688 | If IRQNum is set to 0 the Frequency parameter is | 2700 | If IRQNum is set to 0 the Frequency parameter is |
2689 | overidden, it is forced to a value of FREQ_DIS. | 2701 | overidden, it is forced to a value of FREQ_DIS. |
2690 | int PeriodicOnly: TRUE if all interrupts except the periodic | 2702 | int PeriodicOnly: 1 if all interrupts except the periodic |
2691 | interrupt are to be blocked. | 2703 | interrupt are to be blocked. |
2692 | FALSE is both the periodic interrupt and | 2704 | 0 is both the periodic interrupt and |
2693 | other channel interrupts are allowed. | 2705 | other channel interrupts are allowed. |
2694 | If IRQNum is set to 0 the PeriodicOnly parameter is | 2706 | If IRQNum is set to 0 the PeriodicOnly parameter is |
2695 | overidden, it is forced to a value of FALSE. | 2707 | overidden, it is forced to a value of 0. |
2696 | Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller | 2708 | Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller |
2697 | initialization failed. | 2709 | initialization failed. |
2698 | 2710 | ||
2699 | Comments: | 2711 | Comments: |
2700 | If periodic interrupts are to be disabled but AIOP interrupts | 2712 | If periodic interrupts are to be disabled but AIOP interrupts |
2701 | are allowed, set Frequency to FREQ_DIS and PeriodicOnly to FALSE. | 2713 | are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0. |
2702 | 2714 | ||
2703 | If interrupts are to be completely disabled set IRQNum to 0. | 2715 | If interrupts are to be completely disabled set IRQNum to 0. |
2704 | 2716 | ||
2705 | Setting Frequency to FREQ_DIS and PeriodicOnly to TRUE is an | 2717 | Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an |
2706 | invalid combination. | 2718 | invalid combination. |
2707 | 2719 | ||
2708 | This function performs initialization of global interrupt modes, | 2720 | This function performs initialization of global interrupt modes, |
@@ -2722,11 +2734,11 @@ Warnings: No range checking on any of the parameters is done. | |||
2722 | After this function all AIOPs on the controller are disabled, | 2734 | After this function all AIOPs on the controller are disabled, |
2723 | they can be enabled with sEnAiop(). | 2735 | they can be enabled with sEnAiop(). |
2724 | */ | 2736 | */ |
2725 | int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum, | 2737 | static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum, |
2726 | ByteIO_t * AiopIOList, int AiopIOListSize, | 2738 | ByteIO_t * AiopIOList, int AiopIOListSize, |
2727 | WordIO_t ConfigIO, int IRQNum, Byte_t Frequency, | 2739 | WordIO_t ConfigIO, int IRQNum, Byte_t Frequency, |
2728 | int PeriodicOnly, int altChanRingIndicator, | 2740 | int PeriodicOnly, int altChanRingIndicator, |
2729 | int UPCIRingInd) | 2741 | int UPCIRingInd) |
2730 | { | 2742 | { |
2731 | int i; | 2743 | int i; |
2732 | ByteIO_t io; | 2744 | ByteIO_t io; |
@@ -2784,7 +2796,7 @@ Return: int: Flag AIOPID_XXXX if a valid AIOP is found, where X | |||
2784 | Warnings: No context switches are allowed while executing this function. | 2796 | Warnings: No context switches are allowed while executing this function. |
2785 | 2797 | ||
2786 | */ | 2798 | */ |
2787 | int sReadAiopID(ByteIO_t io) | 2799 | static int sReadAiopID(ByteIO_t io) |
2788 | { | 2800 | { |
2789 | Byte_t AiopID; /* ID byte from AIOP */ | 2801 | Byte_t AiopID; /* ID byte from AIOP */ |
2790 | 2802 | ||
@@ -2810,7 +2822,7 @@ Comments: The number of channels is determined by write/reads from identical | |||
2810 | AIOP, otherwise it is an 8 channel. | 2822 | AIOP, otherwise it is an 8 channel. |
2811 | Warnings: No context switches are allowed while executing this function. | 2823 | Warnings: No context switches are allowed while executing this function. |
2812 | */ | 2824 | */ |
2813 | int sReadAiopNumChan(WordIO_t io) | 2825 | static int sReadAiopNumChan(WordIO_t io) |
2814 | { | 2826 | { |
2815 | Word_t x; | 2827 | Word_t x; |
2816 | static Byte_t R[4] = { 0x00, 0x00, 0x34, 0x12 }; | 2828 | static Byte_t R[4] = { 0x00, 0x00, 0x34, 0x12 }; |
@@ -2834,15 +2846,15 @@ Call: sInitChan(CtlP,ChP,AiopNum,ChanNum) | |||
2834 | CHANNEL_T *ChP; Ptr to channel structure | 2846 | CHANNEL_T *ChP; Ptr to channel structure |
2835 | int AiopNum; AIOP number within controller | 2847 | int AiopNum; AIOP number within controller |
2836 | int ChanNum; Channel number within AIOP | 2848 | int ChanNum; Channel number within AIOP |
2837 | Return: int: TRUE if initialization succeeded, FALSE if it fails because channel | 2849 | Return: int: 1 if initialization succeeded, 0 if it fails because channel |
2838 | number exceeds number of channels available in AIOP. | 2850 | number exceeds number of channels available in AIOP. |
2839 | Comments: This function must be called before a channel can be used. | 2851 | Comments: This function must be called before a channel can be used. |
2840 | Warnings: No range checking on any of the parameters is done. | 2852 | Warnings: No range checking on any of the parameters is done. |
2841 | 2853 | ||
2842 | No context switches are allowed while executing this function. | 2854 | No context switches are allowed while executing this function. |
2843 | */ | 2855 | */ |
2844 | int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum, | 2856 | static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum, |
2845 | int ChanNum) | 2857 | int ChanNum) |
2846 | { | 2858 | { |
2847 | int i; | 2859 | int i; |
2848 | WordIO_t AiopIO; | 2860 | WordIO_t AiopIO; |
@@ -2853,7 +2865,7 @@ int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum, | |||
2853 | int brd9600; | 2865 | int brd9600; |
2854 | 2866 | ||
2855 | if (ChanNum >= CtlP->AiopNumChan[AiopNum]) | 2867 | if (ChanNum >= CtlP->AiopNumChan[AiopNum]) |
2856 | return (FALSE); /* exceeds num chans in AIOP */ | 2868 | return 0; /* exceeds num chans in AIOP */ |
2857 | 2869 | ||
2858 | /* Channel, AIOP, and controller identifiers */ | 2870 | /* Channel, AIOP, and controller identifiers */ |
2859 | ChP->CtlP = CtlP; | 2871 | ChP->CtlP = CtlP; |
@@ -2968,7 +2980,7 @@ int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum, | |||
2968 | ChP->TxPrioBuf = ChOff + _TXP_BUF; | 2980 | ChP->TxPrioBuf = ChOff + _TXP_BUF; |
2969 | sEnRxProcessor(ChP); /* start the Rx processor */ | 2981 | sEnRxProcessor(ChP); /* start the Rx processor */ |
2970 | 2982 | ||
2971 | return (TRUE); | 2983 | return 1; |
2972 | } | 2984 | } |
2973 | 2985 | ||
2974 | /*************************************************************************** | 2986 | /*************************************************************************** |
@@ -2989,7 +3001,7 @@ Warnings: No context switches are allowed while executing this function. | |||
2989 | After calling this function a delay of 4 uS is required to ensure | 3001 | After calling this function a delay of 4 uS is required to ensure |
2990 | that the receive processor is no longer processing this channel. | 3002 | that the receive processor is no longer processing this channel. |
2991 | */ | 3003 | */ |
2992 | void sStopRxProcessor(CHANNEL_T * ChP) | 3004 | static void sStopRxProcessor(CHANNEL_T * ChP) |
2993 | { | 3005 | { |
2994 | Byte_t R[4]; | 3006 | Byte_t R[4]; |
2995 | 3007 | ||
@@ -3014,18 +3026,18 @@ Comments: To prevent data from being enqueued or dequeued in the Tx FIFO | |||
3014 | this function. | 3026 | this function. |
3015 | Warnings: No context switches are allowed while executing this function. | 3027 | Warnings: No context switches are allowed while executing this function. |
3016 | */ | 3028 | */ |
3017 | void sFlushRxFIFO(CHANNEL_T * ChP) | 3029 | static void sFlushRxFIFO(CHANNEL_T * ChP) |
3018 | { | 3030 | { |
3019 | int i; | 3031 | int i; |
3020 | Byte_t Ch; /* channel number within AIOP */ | 3032 | Byte_t Ch; /* channel number within AIOP */ |
3021 | int RxFIFOEnabled; /* TRUE if Rx FIFO enabled */ | 3033 | int RxFIFOEnabled; /* 1 if Rx FIFO enabled */ |
3022 | 3034 | ||
3023 | if (sGetRxCnt(ChP) == 0) /* Rx FIFO empty */ | 3035 | if (sGetRxCnt(ChP) == 0) /* Rx FIFO empty */ |
3024 | return; /* don't need to flush */ | 3036 | return; /* don't need to flush */ |
3025 | 3037 | ||
3026 | RxFIFOEnabled = FALSE; | 3038 | RxFIFOEnabled = 0; |
3027 | if (ChP->R[0x32] == 0x08) { /* Rx FIFO is enabled */ | 3039 | if (ChP->R[0x32] == 0x08) { /* Rx FIFO is enabled */ |
3028 | RxFIFOEnabled = TRUE; | 3040 | RxFIFOEnabled = 1; |
3029 | sDisRxFIFO(ChP); /* disable it */ | 3041 | sDisRxFIFO(ChP); /* disable it */ |
3030 | for (i = 0; i < 2000 / 200; i++) /* delay 2 uS to allow proc to disable FIFO */ | 3042 | for (i = 0; i < 2000 / 200; i++) /* delay 2 uS to allow proc to disable FIFO */ |
3031 | sInB(ChP->IntChan); /* depends on bus i/o timing */ | 3043 | sInB(ChP->IntChan); /* depends on bus i/o timing */ |
@@ -3056,18 +3068,18 @@ Comments: To prevent data from being enqueued or dequeued in the Tx FIFO | |||
3056 | this function. | 3068 | this function. |
3057 | Warnings: No context switches are allowed while executing this function. | 3069 | Warnings: No context switches are allowed while executing this function. |
3058 | */ | 3070 | */ |
3059 | void sFlushTxFIFO(CHANNEL_T * ChP) | 3071 | static void sFlushTxFIFO(CHANNEL_T * ChP) |
3060 | { | 3072 | { |
3061 | int i; | 3073 | int i; |
3062 | Byte_t Ch; /* channel number within AIOP */ | 3074 | Byte_t Ch; /* channel number within AIOP */ |
3063 | int TxEnabled; /* TRUE if transmitter enabled */ | 3075 | int TxEnabled; /* 1 if transmitter enabled */ |
3064 | 3076 | ||
3065 | if (sGetTxCnt(ChP) == 0) /* Tx FIFO empty */ | 3077 | if (sGetTxCnt(ChP) == 0) /* Tx FIFO empty */ |
3066 | return; /* don't need to flush */ | 3078 | return; /* don't need to flush */ |
3067 | 3079 | ||
3068 | TxEnabled = FALSE; | 3080 | TxEnabled = 0; |
3069 | if (ChP->TxControl[3] & TX_ENABLE) { | 3081 | if (ChP->TxControl[3] & TX_ENABLE) { |
3070 | TxEnabled = TRUE; | 3082 | TxEnabled = 1; |
3071 | sDisTransmit(ChP); /* disable transmitter */ | 3083 | sDisTransmit(ChP); /* disable transmitter */ |
3072 | } | 3084 | } |
3073 | sStopRxProcessor(ChP); /* stop Rx processor */ | 3085 | sStopRxProcessor(ChP); /* stop Rx processor */ |
@@ -3096,7 +3108,7 @@ Comments: The priority byte is transmitted before any data in the Tx FIFO. | |||
3096 | 3108 | ||
3097 | Warnings: No context switches are allowed while executing this function. | 3109 | Warnings: No context switches are allowed while executing this function. |
3098 | */ | 3110 | */ |
3099 | int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data) | 3111 | static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data) |
3100 | { | 3112 | { |
3101 | Byte_t DWBuf[4]; /* buffer for double word writes */ | 3113 | Byte_t DWBuf[4]; /* buffer for double word writes */ |
3102 | Word_t *WordPtr; /* must be far because Win SS != DS */ | 3114 | Word_t *WordPtr; /* must be far because Win SS != DS */ |
@@ -3158,7 +3170,7 @@ Comments: If an interrupt enable flag is set in Flags, that interrupt will be | |||
3158 | enable channel interrupts. This would allow the global interrupt | 3170 | enable channel interrupts. This would allow the global interrupt |
3159 | status register to be used to determine which AIOPs need service. | 3171 | status register to be used to determine which AIOPs need service. |
3160 | */ | 3172 | */ |
3161 | void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags) | 3173 | static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags) |
3162 | { | 3174 | { |
3163 | Byte_t Mask; /* Interrupt Mask Register */ | 3175 | Byte_t Mask; /* Interrupt Mask Register */ |
3164 | 3176 | ||
@@ -3202,7 +3214,7 @@ Comments: If an interrupt flag is set in Flags, that interrupt will be | |||
3202 | this channel's bit from being set in the AIOP's Interrupt Channel | 3214 | this channel's bit from being set in the AIOP's Interrupt Channel |
3203 | Register. | 3215 | Register. |
3204 | */ | 3216 | */ |
3205 | void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags) | 3217 | static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags) |
3206 | { | 3218 | { |
3207 | Byte_t Mask; /* Interrupt Mask Register */ | 3219 | Byte_t Mask; /* Interrupt Mask Register */ |
3208 | 3220 | ||
@@ -3218,7 +3230,7 @@ void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags) | |||
3218 | } | 3230 | } |
3219 | } | 3231 | } |
3220 | 3232 | ||
3221 | void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode) | 3233 | static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode) |
3222 | { | 3234 | { |
3223 | sOutB(ChP->CtlP->AiopIO[2], (mode & 0x18) | ChP->ChanNum); | 3235 | sOutB(ChP->CtlP->AiopIO[2], (mode & 0x18) | ChP->ChanNum); |
3224 | } | 3236 | } |
@@ -3227,7 +3239,7 @@ void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode) | |||
3227 | * Not an official SSCI function, but how to reset RocketModems. | 3239 | * Not an official SSCI function, but how to reset RocketModems. |
3228 | * ISA bus version | 3240 | * ISA bus version |
3229 | */ | 3241 | */ |
3230 | void sModemReset(CONTROLLER_T * CtlP, int chan, int on) | 3242 | static void sModemReset(CONTROLLER_T * CtlP, int chan, int on) |
3231 | { | 3243 | { |
3232 | ByteIO_t addr; | 3244 | ByteIO_t addr; |
3233 | Byte_t val; | 3245 | Byte_t val; |
@@ -3252,7 +3264,7 @@ void sModemReset(CONTROLLER_T * CtlP, int chan, int on) | |||
3252 | * Not an official SSCI function, but how to reset RocketModems. | 3264 | * Not an official SSCI function, but how to reset RocketModems. |
3253 | * PCI bus version | 3265 | * PCI bus version |
3254 | */ | 3266 | */ |
3255 | void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on) | 3267 | static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on) |
3256 | { | 3268 | { |
3257 | ByteIO_t addr; | 3269 | ByteIO_t addr; |
3258 | 3270 | ||
diff --git a/drivers/char/rocket_int.h b/drivers/char/rocket_int.h index 802687290ee1..3a8bcc85bc14 100644 --- a/drivers/char/rocket_int.h +++ b/drivers/char/rocket_int.h | |||
@@ -1130,46 +1130,6 @@ Warnings: This function writes the data byte without checking to see if | |||
1130 | */ | 1130 | */ |
1131 | #define sWriteTxByte(IO,DATA) sOutB(IO,DATA) | 1131 | #define sWriteTxByte(IO,DATA) sOutB(IO,DATA) |
1132 | 1132 | ||
1133 | int sInitController(CONTROLLER_T * CtlP, | ||
1134 | int CtlNum, | ||
1135 | ByteIO_t MudbacIO, | ||
1136 | ByteIO_t * AiopIOList, | ||
1137 | int AiopIOListSize, | ||
1138 | int IRQNum, Byte_t Frequency, int PeriodicOnly); | ||
1139 | |||
1140 | int sPCIInitController(CONTROLLER_T * CtlP, | ||
1141 | int CtlNum, | ||
1142 | ByteIO_t * AiopIOList, | ||
1143 | int AiopIOListSize, | ||
1144 | WordIO_t ConfigIO, | ||
1145 | int IRQNum, | ||
1146 | Byte_t Frequency, | ||
1147 | int PeriodicOnly, | ||
1148 | int altChanRingIndicator, int UPCIRingInd); | ||
1149 | |||
1150 | int sReadAiopID(ByteIO_t io); | ||
1151 | int sReadAiopNumChan(WordIO_t io); | ||
1152 | int sInitChan(CONTROLLER_T * CtlP, | ||
1153 | CHANNEL_T * ChP, int AiopNum, int ChanNum); | ||
1154 | Byte_t sGetRxErrStatus(CHANNEL_T * ChP); | ||
1155 | void sStopRxProcessor(CHANNEL_T * ChP); | ||
1156 | void sStopSWInFlowCtl(CHANNEL_T * ChP); | ||
1157 | void sFlushRxFIFO(CHANNEL_T * ChP); | ||
1158 | void sFlushTxFIFO(CHANNEL_T * ChP); | ||
1159 | int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data); | ||
1160 | void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags); | ||
1161 | void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags); | ||
1162 | void sModemReset(CONTROLLER_T * CtlP, int chan, int on); | ||
1163 | void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on); | ||
1164 | void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode); | ||
1165 | |||
1166 | extern Byte_t R[RDATASIZE]; | ||
1167 | extern CONTROLLER_T sController[CTL_SIZE]; | ||
1168 | extern Byte_t sIRQMap[16]; | ||
1169 | extern Byte_t sBitMapClrTbl[8]; | ||
1170 | extern Byte_t sBitMapSetTbl[8]; | ||
1171 | extern int sClockPrescale; | ||
1172 | |||
1173 | /* | 1133 | /* |
1174 | * Begin Linux specific definitions for the Rocketport driver | 1134 | * Begin Linux specific definitions for the Rocketport driver |
1175 | * | 1135 | * |
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index f59f7cbd525b..af79805b5576 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/spinlock.h> | 35 | #include <linux/spinlock.h> |
36 | #include <linux/vt_kern.h> | 36 | #include <linux/vt_kern.h> |
37 | #include <linux/workqueue.h> | 37 | #include <linux/workqueue.h> |
38 | #include <linux/kexec.h> | ||
38 | 39 | ||
39 | #include <asm/ptrace.h> | 40 | #include <asm/ptrace.h> |
40 | 41 | ||
@@ -94,6 +95,21 @@ static struct sysrq_key_op sysrq_unraw_op = { | |||
94 | }; | 95 | }; |
95 | #endif /* CONFIG_VT */ | 96 | #endif /* CONFIG_VT */ |
96 | 97 | ||
98 | #ifdef CONFIG_KEXEC | ||
99 | /* crashdump sysrq handler */ | ||
100 | static void sysrq_handle_crashdump(int key, struct pt_regs *pt_regs, | ||
101 | struct tty_struct *tty) | ||
102 | { | ||
103 | crash_kexec(pt_regs); | ||
104 | } | ||
105 | static struct sysrq_key_op sysrq_crashdump_op = { | ||
106 | .handler = sysrq_handle_crashdump, | ||
107 | .help_msg = "Crashdump", | ||
108 | .action_msg = "Trigger a crashdump", | ||
109 | .enable_mask = SYSRQ_ENABLE_DUMP, | ||
110 | }; | ||
111 | #endif | ||
112 | |||
97 | /* reboot sysrq handler */ | 113 | /* reboot sysrq handler */ |
98 | static void sysrq_handle_reboot(int key, struct pt_regs *pt_regs, | 114 | static void sysrq_handle_reboot(int key, struct pt_regs *pt_regs, |
99 | struct tty_struct *tty) | 115 | struct tty_struct *tty) |
@@ -273,8 +289,12 @@ static struct sysrq_key_op *sysrq_key_table[SYSRQ_KEY_TABLE_LENGTH] = { | |||
273 | it is handled specially on the sparc | 289 | it is handled specially on the sparc |
274 | and will never arrive */ | 290 | and will never arrive */ |
275 | /* b */ &sysrq_reboot_op, | 291 | /* b */ &sysrq_reboot_op, |
276 | /* c */ NULL, | 292 | #ifdef CONFIG_KEXEC |
277 | /* d */ NULL, | 293 | /* c */ &sysrq_crashdump_op, |
294 | #else | ||
295 | /* c */ NULL, | ||
296 | #endif | ||
297 | /* d */ NULL, | ||
278 | /* e */ &sysrq_term_op, | 298 | /* e */ &sysrq_term_op, |
279 | /* f */ &sysrq_moom_op, | 299 | /* f */ &sysrq_moom_op, |
280 | /* g */ NULL, | 300 | /* g */ NULL, |
diff --git a/drivers/char/toshiba.c b/drivers/char/toshiba.c index 58e21fe44262..0c6f521abd0e 100644 --- a/drivers/char/toshiba.c +++ b/drivers/char/toshiba.c | |||
@@ -73,16 +73,20 @@ | |||
73 | 73 | ||
74 | #define TOSH_MINOR_DEV 181 | 74 | #define TOSH_MINOR_DEV 181 |
75 | 75 | ||
76 | static int tosh_id = 0x0000; | 76 | MODULE_LICENSE("GPL"); |
77 | static int tosh_bios = 0x0000; | 77 | MODULE_AUTHOR("Jonathan Buzzard <jonathan@buzzard.org.uk>"); |
78 | static int tosh_date = 0x0000; | 78 | MODULE_DESCRIPTION("Toshiba laptop SMM driver"); |
79 | static int tosh_sci = 0x0000; | 79 | MODULE_SUPPORTED_DEVICE("toshiba"); |
80 | static int tosh_fan = 0; | ||
81 | |||
82 | static int tosh_fn = 0; | ||
83 | 80 | ||
84 | module_param(tosh_fn, int, 0); | 81 | static int tosh_fn; |
82 | module_param_named(fn, tosh_fn, int, 0); | ||
83 | MODULE_PARM_DESC(fn, "User specified Fn key detection port"); | ||
85 | 84 | ||
85 | static int tosh_id; | ||
86 | static int tosh_bios; | ||
87 | static int tosh_date; | ||
88 | static int tosh_sci; | ||
89 | static int tosh_fan; | ||
86 | 90 | ||
87 | static int tosh_ioctl(struct inode *, struct file *, unsigned int, | 91 | static int tosh_ioctl(struct inode *, struct file *, unsigned int, |
88 | unsigned long); | 92 | unsigned long); |
@@ -359,7 +363,7 @@ static int tosh_get_machine_id(void) | |||
359 | unsigned long address; | 363 | unsigned long address; |
360 | 364 | ||
361 | id = (0x100*(int) isa_readb(0xffffe))+((int) isa_readb(0xffffa)); | 365 | id = (0x100*(int) isa_readb(0xffffe))+((int) isa_readb(0xffffa)); |
362 | 366 | ||
363 | /* do we have a SCTTable machine identication number on our hands */ | 367 | /* do we have a SCTTable machine identication number on our hands */ |
364 | 368 | ||
365 | if (id==0xfc2f) { | 369 | if (id==0xfc2f) { |
@@ -424,7 +428,7 @@ static int tosh_probe(void) | |||
424 | } | 428 | } |
425 | 429 | ||
426 | /* call the Toshiba SCI support check routine */ | 430 | /* call the Toshiba SCI support check routine */ |
427 | 431 | ||
428 | regs.eax = 0xf0f0; | 432 | regs.eax = 0xf0f0; |
429 | regs.ebx = 0x0000; | 433 | regs.ebx = 0x0000; |
430 | regs.ecx = 0x0000; | 434 | regs.ecx = 0x0000; |
@@ -440,7 +444,7 @@ static int tosh_probe(void) | |||
440 | /* if we get this far then we are running on a Toshiba (probably)! */ | 444 | /* if we get this far then we are running on a Toshiba (probably)! */ |
441 | 445 | ||
442 | tosh_sci = regs.edx & 0xffff; | 446 | tosh_sci = regs.edx & 0xffff; |
443 | 447 | ||
444 | /* next get the machine ID of the current laptop */ | 448 | /* next get the machine ID of the current laptop */ |
445 | 449 | ||
446 | tosh_id = tosh_get_machine_id(); | 450 | tosh_id = tosh_get_machine_id(); |
@@ -475,16 +479,15 @@ static int tosh_probe(void) | |||
475 | return 0; | 479 | return 0; |
476 | } | 480 | } |
477 | 481 | ||
478 | int __init tosh_init(void) | 482 | static int __init toshiba_init(void) |
479 | { | 483 | { |
480 | int retval; | 484 | int retval; |
481 | /* are we running on a Toshiba laptop */ | 485 | /* are we running on a Toshiba laptop */ |
482 | 486 | ||
483 | if (tosh_probe()!=0) | 487 | if (tosh_probe()) |
484 | return -EIO; | 488 | return -ENODEV; |
485 | 489 | ||
486 | printk(KERN_INFO "Toshiba System Managment Mode driver v" | 490 | printk(KERN_INFO "Toshiba System Managment Mode driver v" TOSH_VERSION "\n"); |
487 | TOSH_VERSION"\n"); | ||
488 | 491 | ||
489 | /* set the port to use for Fn status if not specified as a parameter */ | 492 | /* set the port to use for Fn status if not specified as a parameter */ |
490 | if (tosh_fn==0x00) | 493 | if (tosh_fn==0x00) |
@@ -492,12 +495,12 @@ int __init tosh_init(void) | |||
492 | 495 | ||
493 | /* register the device file */ | 496 | /* register the device file */ |
494 | retval = misc_register(&tosh_device); | 497 | retval = misc_register(&tosh_device); |
495 | if(retval < 0) | 498 | if (retval < 0) |
496 | return retval; | 499 | return retval; |
497 | 500 | ||
498 | #ifdef CONFIG_PROC_FS | 501 | #ifdef CONFIG_PROC_FS |
499 | /* register the proc entry */ | 502 | /* register the proc entry */ |
500 | if(create_proc_info_entry("toshiba", 0, NULL, tosh_get_info) == NULL){ | 503 | if (create_proc_info_entry("toshiba", 0, NULL, tosh_get_info) == NULL) { |
501 | misc_deregister(&tosh_device); | 504 | misc_deregister(&tosh_device); |
502 | return -ENOMEM; | 505 | return -ENOMEM; |
503 | } | 506 | } |
@@ -506,27 +509,12 @@ int __init tosh_init(void) | |||
506 | return 0; | 509 | return 0; |
507 | } | 510 | } |
508 | 511 | ||
509 | #ifdef MODULE | 512 | static void __exit toshiba_exit(void) |
510 | int init_module(void) | ||
511 | { | ||
512 | return tosh_init(); | ||
513 | } | ||
514 | |||
515 | void cleanup_module(void) | ||
516 | { | 513 | { |
517 | /* remove the proc entry */ | ||
518 | |||
519 | remove_proc_entry("toshiba", NULL); | 514 | remove_proc_entry("toshiba", NULL); |
520 | |||
521 | /* unregister the device file */ | ||
522 | |||
523 | misc_deregister(&tosh_device); | 515 | misc_deregister(&tosh_device); |
524 | } | 516 | } |
525 | #endif | ||
526 | 517 | ||
527 | MODULE_LICENSE("GPL"); | 518 | module_init(toshiba_init); |
528 | MODULE_PARM_DESC(tosh_fn, "User specified Fn key detection port"); | 519 | module_exit(toshiba_exit); |
529 | MODULE_AUTHOR("Jonathan Buzzard <jonathan@buzzard.org.uk>"); | ||
530 | MODULE_DESCRIPTION("Toshiba laptop SMM driver"); | ||
531 | MODULE_SUPPORTED_DEVICE("toshiba"); | ||
532 | 520 | ||
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 5c843c9bf819..854475c54f0e 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -233,10 +233,10 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr, | |||
233 | data[15], data[16], data[17], data[22], data[23], | 233 | data[15], data[16], data[17], data[22], data[23], |
234 | data[24], data[25], data[26], data[27], data[28], | 234 | data[24], data[25], data[26], data[27], data[28], |
235 | data[29], data[30], data[31], data[32], data[33], | 235 | data[29], data[30], data[31], data[32], data[33], |
236 | be32_to_cpu(*((__be32 *) (data + 32)))); | 236 | be32_to_cpu(*((__be32 *) (data + 34)))); |
237 | 237 | ||
238 | for (i = 0; i < 256; i++) { | 238 | for (i = 0; i < 256; i++) { |
239 | str += sprintf(str, "%02X ", data[i + 39]); | 239 | str += sprintf(str, "%02X ", data[i + 38]); |
240 | if ((i + 1) % 16 == 0) | 240 | if ((i + 1) % 16 == 0) |
241 | str += sprintf(str, "\n"); | 241 | str += sprintf(str, "\n"); |
242 | } | 242 | } |
@@ -464,6 +464,7 @@ void __devexit tpm_remove(struct pci_dev *pci_dev) | |||
464 | 464 | ||
465 | pci_set_drvdata(pci_dev, NULL); | 465 | pci_set_drvdata(pci_dev, NULL); |
466 | misc_deregister(&chip->vendor->miscdev); | 466 | misc_deregister(&chip->vendor->miscdev); |
467 | kfree(&chip->vendor->miscdev.name); | ||
467 | 468 | ||
468 | sysfs_remove_group(&pci_dev->dev.kobj, chip->vendor->attr_group); | 469 | sysfs_remove_group(&pci_dev->dev.kobj, chip->vendor->attr_group); |
469 | 470 | ||
@@ -526,7 +527,9 @@ EXPORT_SYMBOL_GPL(tpm_pm_resume); | |||
526 | int tpm_register_hardware(struct pci_dev *pci_dev, | 527 | int tpm_register_hardware(struct pci_dev *pci_dev, |
527 | struct tpm_vendor_specific *entry) | 528 | struct tpm_vendor_specific *entry) |
528 | { | 529 | { |
529 | char devname[7]; | 530 | #define DEVNAME_SIZE 7 |
531 | |||
532 | char *devname; | ||
530 | struct tpm_chip *chip; | 533 | struct tpm_chip *chip; |
531 | int i, j; | 534 | int i, j; |
532 | 535 | ||
@@ -569,7 +572,8 @@ dev_num_search_complete: | |||
569 | else | 572 | else |
570 | chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR; | 573 | chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR; |
571 | 574 | ||
572 | snprintf(devname, sizeof(devname), "%s%d", "tpm", chip->dev_num); | 575 | devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL); |
576 | scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num); | ||
573 | chip->vendor->miscdev.name = devname; | 577 | chip->vendor->miscdev.name = devname; |
574 | 578 | ||
575 | chip->vendor->miscdev.dev = &(pci_dev->dev); | 579 | chip->vendor->miscdev.dev = &(pci_dev->dev); |
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 10cb450191a6..373b41f6b460 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h | |||
@@ -31,8 +31,8 @@ enum tpm_timeout { | |||
31 | 31 | ||
32 | /* TPM addresses */ | 32 | /* TPM addresses */ |
33 | enum tpm_addr { | 33 | enum tpm_addr { |
34 | TPM_SUPERIO_ADDR = 0x2E, | ||
34 | TPM_ADDR = 0x4E, | 35 | TPM_ADDR = 0x4E, |
35 | TPM_DATA = 0x4F | ||
36 | }; | 36 | }; |
37 | 37 | ||
38 | extern ssize_t tpm_show_pubek(struct device *, struct device_attribute *attr, | 38 | extern ssize_t tpm_show_pubek(struct device *, struct device_attribute *attr, |
@@ -79,16 +79,16 @@ struct tpm_chip { | |||
79 | struct list_head list; | 79 | struct list_head list; |
80 | }; | 80 | }; |
81 | 81 | ||
82 | static inline int tpm_read_index(int index) | 82 | static inline int tpm_read_index(int base, int index) |
83 | { | 83 | { |
84 | outb(index, TPM_ADDR); | 84 | outb(index, base); |
85 | return inb(TPM_DATA) & 0xFF; | 85 | return inb(base+1) & 0xFF; |
86 | } | 86 | } |
87 | 87 | ||
88 | static inline void tpm_write_index(int index, int value) | 88 | static inline void tpm_write_index(int base, int index, int value) |
89 | { | 89 | { |
90 | outb(index, TPM_ADDR); | 90 | outb(index, base); |
91 | outb(value & 0xFF, TPM_DATA); | 91 | outb(value & 0xFF, base+1); |
92 | } | 92 | } |
93 | 93 | ||
94 | extern int tpm_register_hardware(struct pci_dev *, | 94 | extern int tpm_register_hardware(struct pci_dev *, |
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c index 61fe14a77124..cc2cc77fd174 100644 --- a/drivers/char/tpm/tpm_atmel.c +++ b/drivers/char/tpm/tpm_atmel.c | |||
@@ -163,24 +163,24 @@ static int __devinit tpm_atml_init(struct pci_dev *pci_dev, | |||
163 | if (pci_enable_device(pci_dev)) | 163 | if (pci_enable_device(pci_dev)) |
164 | return -EIO; | 164 | return -EIO; |
165 | 165 | ||
166 | lo = tpm_read_index( TPM_ATMEL_BASE_ADDR_LO ); | 166 | lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO); |
167 | hi = tpm_read_index( TPM_ATMEL_BASE_ADDR_HI ); | 167 | hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI); |
168 | 168 | ||
169 | tpm_atmel.base = (hi<<8)|lo; | 169 | tpm_atmel.base = (hi<<8)|lo; |
170 | dev_dbg( &pci_dev->dev, "Operating with base: 0x%x\n", tpm_atmel.base); | 170 | dev_dbg( &pci_dev->dev, "Operating with base: 0x%x\n", tpm_atmel.base); |
171 | 171 | ||
172 | /* verify that it is an Atmel part */ | 172 | /* verify that it is an Atmel part */ |
173 | if (tpm_read_index(4) != 'A' || tpm_read_index(5) != 'T' | 173 | if (tpm_read_index(TPM_ADDR, 4) != 'A' || tpm_read_index(TPM_ADDR, 5) != 'T' |
174 | || tpm_read_index(6) != 'M' || tpm_read_index(7) != 'L') { | 174 | || tpm_read_index(TPM_ADDR, 6) != 'M' || tpm_read_index(TPM_ADDR, 7) != 'L') { |
175 | rc = -ENODEV; | 175 | rc = -ENODEV; |
176 | goto out_err; | 176 | goto out_err; |
177 | } | 177 | } |
178 | 178 | ||
179 | /* query chip for its version number */ | 179 | /* query chip for its version number */ |
180 | if ((version[0] = tpm_read_index(0x00)) != 0xFF) { | 180 | if ((version[0] = tpm_read_index(TPM_ADDR, 0x00)) != 0xFF) { |
181 | version[1] = tpm_read_index(0x01); | 181 | version[1] = tpm_read_index(TPM_ADDR, 0x01); |
182 | version[2] = tpm_read_index(0x02); | 182 | version[2] = tpm_read_index(TPM_ADDR, 0x02); |
183 | version[3] = tpm_read_index(0x03); | 183 | version[3] = tpm_read_index(TPM_ADDR, 0x03); |
184 | } else { | 184 | } else { |
185 | dev_info(&pci_dev->dev, "version query failed\n"); | 185 | dev_info(&pci_dev->dev, "version query failed\n"); |
186 | rc = -ENODEV; | 186 | rc = -ENODEV; |
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c index 1a45e7dfc13b..b4127348c063 100644 --- a/drivers/char/tpm/tpm_nsc.c +++ b/drivers/char/tpm/tpm_nsc.c | |||
@@ -23,7 +23,6 @@ | |||
23 | 23 | ||
24 | /* National definitions */ | 24 | /* National definitions */ |
25 | enum tpm_nsc_addr{ | 25 | enum tpm_nsc_addr{ |
26 | TPM_NSC_BASE = 0x360, | ||
27 | TPM_NSC_IRQ = 0x07, | 26 | TPM_NSC_IRQ = 0x07, |
28 | TPM_NSC_BASE0_HI = 0x60, | 27 | TPM_NSC_BASE0_HI = 0x60, |
29 | TPM_NSC_BASE0_LO = 0x61, | 28 | TPM_NSC_BASE0_LO = 0x61, |
@@ -56,6 +55,7 @@ enum tpm_nsc_status { | |||
56 | NSC_STATUS_RDY = 0x10, /* ready to receive command */ | 55 | NSC_STATUS_RDY = 0x10, /* ready to receive command */ |
57 | NSC_STATUS_IBR = 0x20 /* ready to receive data */ | 56 | NSC_STATUS_IBR = 0x20 /* ready to receive data */ |
58 | }; | 57 | }; |
58 | |||
59 | /* command bits */ | 59 | /* command bits */ |
60 | enum tpm_nsc_cmd_mode { | 60 | enum tpm_nsc_cmd_mode { |
61 | NSC_COMMAND_NORMAL = 0x01, /* normal mode */ | 61 | NSC_COMMAND_NORMAL = 0x01, /* normal mode */ |
@@ -150,7 +150,8 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count) | |||
150 | *p = inb(chip->vendor->base + NSC_DATA); | 150 | *p = inb(chip->vendor->base + NSC_DATA); |
151 | } | 151 | } |
152 | 152 | ||
153 | if ((data & NSC_STATUS_F0) == 0) { | 153 | if ((data & NSC_STATUS_F0) == 0 && |
154 | (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0)) { | ||
154 | dev_err(&chip->pci_dev->dev, "F0 not set\n"); | 155 | dev_err(&chip->pci_dev->dev, "F0 not set\n"); |
155 | return -EIO; | 156 | return -EIO; |
156 | } | 157 | } |
@@ -259,85 +260,64 @@ static int __devinit tpm_nsc_init(struct pci_dev *pci_dev, | |||
259 | { | 260 | { |
260 | int rc = 0; | 261 | int rc = 0; |
261 | int lo, hi; | 262 | int lo, hi; |
263 | int nscAddrBase = TPM_ADDR; | ||
262 | 264 | ||
263 | hi = tpm_read_index(TPM_NSC_BASE0_HI); | ||
264 | lo = tpm_read_index(TPM_NSC_BASE0_LO); | ||
265 | |||
266 | tpm_nsc.base = (hi<<8) | lo; | ||
267 | 265 | ||
268 | if (pci_enable_device(pci_dev)) | 266 | if (pci_enable_device(pci_dev)) |
269 | return -EIO; | 267 | return -EIO; |
270 | 268 | ||
269 | /* select PM channel 1 */ | ||
270 | tpm_write_index(nscAddrBase,NSC_LDN_INDEX, 0x12); | ||
271 | |||
271 | /* verify that it is a National part (SID) */ | 272 | /* verify that it is a National part (SID) */ |
272 | if (tpm_read_index(NSC_SID_INDEX) != 0xEF) { | 273 | if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) { |
273 | rc = -ENODEV; | 274 | nscAddrBase = (tpm_read_index(TPM_SUPERIO_ADDR, 0x2C)<<8)| |
274 | goto out_err; | 275 | (tpm_read_index(TPM_SUPERIO_ADDR, 0x2B)&0xFE); |
276 | if (tpm_read_index(nscAddrBase, NSC_SID_INDEX) != 0xF6) { | ||
277 | rc = -ENODEV; | ||
278 | goto out_err; | ||
279 | } | ||
275 | } | 280 | } |
276 | 281 | ||
282 | hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI); | ||
283 | lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO); | ||
284 | tpm_nsc.base = (hi<<8) | lo; | ||
285 | |||
277 | dev_dbg(&pci_dev->dev, "NSC TPM detected\n"); | 286 | dev_dbg(&pci_dev->dev, "NSC TPM detected\n"); |
278 | dev_dbg(&pci_dev->dev, | 287 | dev_dbg(&pci_dev->dev, |
279 | "NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n", | 288 | "NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n", |
280 | tpm_read_index(0x07), tpm_read_index(0x20), | 289 | tpm_read_index(nscAddrBase,0x07), tpm_read_index(nscAddrBase,0x20), |
281 | tpm_read_index(0x27)); | 290 | tpm_read_index(nscAddrBase,0x27)); |
282 | dev_dbg(&pci_dev->dev, | 291 | dev_dbg(&pci_dev->dev, |
283 | "NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n", | 292 | "NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n", |
284 | tpm_read_index(0x21), tpm_read_index(0x25), | 293 | tpm_read_index(nscAddrBase,0x21), tpm_read_index(nscAddrBase,0x25), |
285 | tpm_read_index(0x26), tpm_read_index(0x28)); | 294 | tpm_read_index(nscAddrBase,0x26), tpm_read_index(nscAddrBase,0x28)); |
286 | dev_dbg(&pci_dev->dev, "NSC IO Base0 0x%x\n", | 295 | dev_dbg(&pci_dev->dev, "NSC IO Base0 0x%x\n", |
287 | (tpm_read_index(0x60) << 8) | tpm_read_index(0x61)); | 296 | (tpm_read_index(nscAddrBase,0x60) << 8) | tpm_read_index(nscAddrBase,0x61)); |
288 | dev_dbg(&pci_dev->dev, "NSC IO Base1 0x%x\n", | 297 | dev_dbg(&pci_dev->dev, "NSC IO Base1 0x%x\n", |
289 | (tpm_read_index(0x62) << 8) | tpm_read_index(0x63)); | 298 | (tpm_read_index(nscAddrBase,0x62) << 8) | tpm_read_index(nscAddrBase,0x63)); |
290 | dev_dbg(&pci_dev->dev, "NSC Interrupt number and wakeup 0x%x\n", | 299 | dev_dbg(&pci_dev->dev, "NSC Interrupt number and wakeup 0x%x\n", |
291 | tpm_read_index(0x70)); | 300 | tpm_read_index(nscAddrBase,0x70)); |
292 | dev_dbg(&pci_dev->dev, "NSC IRQ type select 0x%x\n", | 301 | dev_dbg(&pci_dev->dev, "NSC IRQ type select 0x%x\n", |
293 | tpm_read_index(0x71)); | 302 | tpm_read_index(nscAddrBase,0x71)); |
294 | dev_dbg(&pci_dev->dev, | 303 | dev_dbg(&pci_dev->dev, |
295 | "NSC DMA channel select0 0x%x, select1 0x%x\n", | 304 | "NSC DMA channel select0 0x%x, select1 0x%x\n", |
296 | tpm_read_index(0x74), tpm_read_index(0x75)); | 305 | tpm_read_index(nscAddrBase,0x74), tpm_read_index(nscAddrBase,0x75)); |
297 | dev_dbg(&pci_dev->dev, | 306 | dev_dbg(&pci_dev->dev, |
298 | "NSC Config " | 307 | "NSC Config " |
299 | "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", | 308 | "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", |
300 | tpm_read_index(0xF0), tpm_read_index(0xF1), | 309 | tpm_read_index(nscAddrBase,0xF0), tpm_read_index(nscAddrBase,0xF1), |
301 | tpm_read_index(0xF2), tpm_read_index(0xF3), | 310 | tpm_read_index(nscAddrBase,0xF2), tpm_read_index(nscAddrBase,0xF3), |
302 | tpm_read_index(0xF4), tpm_read_index(0xF5), | 311 | tpm_read_index(nscAddrBase,0xF4), tpm_read_index(nscAddrBase,0xF5), |
303 | tpm_read_index(0xF6), tpm_read_index(0xF7), | 312 | tpm_read_index(nscAddrBase,0xF6), tpm_read_index(nscAddrBase,0xF7), |
304 | tpm_read_index(0xF8), tpm_read_index(0xF9)); | 313 | tpm_read_index(nscAddrBase,0xF8), tpm_read_index(nscAddrBase,0xF9)); |
305 | 314 | ||
306 | dev_info(&pci_dev->dev, | 315 | dev_info(&pci_dev->dev, |
307 | "NSC PC21100 TPM revision %d\n", | 316 | "NSC TPM revision %d\n", |
308 | tpm_read_index(0x27) & 0x1F); | 317 | tpm_read_index(nscAddrBase, 0x27) & 0x1F); |
309 | |||
310 | if (tpm_read_index(NSC_LDC_INDEX) == 0) | ||
311 | dev_info(&pci_dev->dev, ": NSC TPM not active\n"); | ||
312 | |||
313 | /* select PM channel 1 */ | ||
314 | tpm_write_index(NSC_LDN_INDEX, 0x12); | ||
315 | tpm_read_index(NSC_LDN_INDEX); | ||
316 | |||
317 | /* disable the DPM module */ | ||
318 | tpm_write_index(NSC_LDC_INDEX, 0); | ||
319 | tpm_read_index(NSC_LDC_INDEX); | ||
320 | |||
321 | /* set the data register base addresses */ | ||
322 | tpm_write_index(NSC_DIO_INDEX, TPM_NSC_BASE >> 8); | ||
323 | tpm_write_index(NSC_DIO_INDEX + 1, TPM_NSC_BASE); | ||
324 | tpm_read_index(NSC_DIO_INDEX); | ||
325 | tpm_read_index(NSC_DIO_INDEX + 1); | ||
326 | |||
327 | /* set the command register base addresses */ | ||
328 | tpm_write_index(NSC_CIO_INDEX, (TPM_NSC_BASE + 1) >> 8); | ||
329 | tpm_write_index(NSC_CIO_INDEX + 1, (TPM_NSC_BASE + 1)); | ||
330 | tpm_read_index(NSC_DIO_INDEX); | ||
331 | tpm_read_index(NSC_DIO_INDEX + 1); | ||
332 | |||
333 | /* set the interrupt number to be used for the host interface */ | ||
334 | tpm_write_index(NSC_IRQ_INDEX, TPM_NSC_IRQ); | ||
335 | tpm_write_index(NSC_ITS_INDEX, 0x00); | ||
336 | tpm_read_index(NSC_IRQ_INDEX); | ||
337 | 318 | ||
338 | /* enable the DPM module */ | 319 | /* enable the DPM module */ |
339 | tpm_write_index(NSC_LDC_INDEX, 0x01); | 320 | tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01); |
340 | tpm_read_index(NSC_LDC_INDEX); | ||
341 | 321 | ||
342 | if ((rc = tpm_register_hardware(pci_dev, &tpm_nsc)) < 0) | 322 | if ((rc = tpm_register_hardware(pci_dev, &tpm_nsc)) < 0) |
343 | goto out_err; | 323 | goto out_err; |
@@ -355,6 +335,9 @@ static struct pci_device_id tpm_pci_tbl[] __devinitdata = { | |||
355 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)}, | 335 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)}, |
356 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)}, | 336 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)}, |
357 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)}, | 337 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)}, |
338 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)}, | ||
339 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)}, | ||
340 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0)}, | ||
358 | {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)}, | 341 | {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)}, |
359 | {0,} | 342 | {0,} |
360 | }; | 343 | }; |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index cc4b43bad703..6e4be3bb2d89 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -94,6 +94,7 @@ | |||
94 | #include <linux/idr.h> | 94 | #include <linux/idr.h> |
95 | #include <linux/wait.h> | 95 | #include <linux/wait.h> |
96 | #include <linux/bitops.h> | 96 | #include <linux/bitops.h> |
97 | #include <linux/delay.h> | ||
97 | 98 | ||
98 | #include <asm/uaccess.h> | 99 | #include <asm/uaccess.h> |
99 | #include <asm/system.h> | 100 | #include <asm/system.h> |
@@ -2180,12 +2181,11 @@ static int tiocsetd(struct tty_struct *tty, int __user *p) | |||
2180 | return tty_set_ldisc(tty, ldisc); | 2181 | return tty_set_ldisc(tty, ldisc); |
2181 | } | 2182 | } |
2182 | 2183 | ||
2183 | static int send_break(struct tty_struct *tty, int duration) | 2184 | static int send_break(struct tty_struct *tty, unsigned int duration) |
2184 | { | 2185 | { |
2185 | tty->driver->break_ctl(tty, -1); | 2186 | tty->driver->break_ctl(tty, -1); |
2186 | if (!signal_pending(current)) { | 2187 | if (!signal_pending(current)) { |
2187 | set_current_state(TASK_INTERRUPTIBLE); | 2188 | msleep_interruptible(duration); |
2188 | schedule_timeout(duration); | ||
2189 | } | 2189 | } |
2190 | tty->driver->break_ctl(tty, 0); | 2190 | tty->driver->break_ctl(tty, 0); |
2191 | if (signal_pending(current)) | 2191 | if (signal_pending(current)) |
@@ -2366,10 +2366,10 @@ int tty_ioctl(struct inode * inode, struct file * file, | |||
2366 | * all by anyone? | 2366 | * all by anyone? |
2367 | */ | 2367 | */ |
2368 | if (!arg) | 2368 | if (!arg) |
2369 | return send_break(tty, HZ/4); | 2369 | return send_break(tty, 250); |
2370 | return 0; | 2370 | return 0; |
2371 | case TCSBRKP: /* support for POSIX tcsendbreak() */ | 2371 | case TCSBRKP: /* support for POSIX tcsendbreak() */ |
2372 | return send_break(tty, arg ? arg*(HZ/10) : HZ/4); | 2372 | return send_break(tty, arg ? arg*100 : 250); |
2373 | 2373 | ||
2374 | case TIOCMGET: | 2374 | case TIOCMGET: |
2375 | return tty_tiocmget(tty, file, p); | 2375 | return tty_tiocmget(tty, file, p); |
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index a3451cb94004..33b17c6a46fb 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c | |||
@@ -618,8 +618,8 @@ efivar_create_sysfs_entry(unsigned long variable_name_size, | |||
618 | new_efivar = kmalloc(sizeof(struct efivar_entry), GFP_KERNEL); | 618 | new_efivar = kmalloc(sizeof(struct efivar_entry), GFP_KERNEL); |
619 | 619 | ||
620 | if (!short_name || !new_efivar) { | 620 | if (!short_name || !new_efivar) { |
621 | if (short_name) kfree(short_name); | 621 | kfree(short_name); |
622 | if (new_efivar) kfree(new_efivar); | 622 | kfree(new_efivar); |
623 | return 1; | 623 | return 1; |
624 | } | 624 | } |
625 | memset(short_name, 0, short_name_size+1); | 625 | memset(short_name, 0, short_name_size+1); |
@@ -644,7 +644,8 @@ efivar_create_sysfs_entry(unsigned long variable_name_size, | |||
644 | kobj_set_kset_s(new_efivar, vars_subsys); | 644 | kobj_set_kset_s(new_efivar, vars_subsys); |
645 | kobject_register(&new_efivar->kobj); | 645 | kobject_register(&new_efivar->kobj); |
646 | 646 | ||
647 | kfree(short_name); short_name = NULL; | 647 | kfree(short_name); |
648 | short_name = NULL; | ||
648 | 649 | ||
649 | spin_lock(&efivars_lock); | 650 | spin_lock(&efivars_lock); |
650 | list_add(&new_efivar->list, &efivar_list); | 651 | list_add(&new_efivar->list, &efivar_list); |
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index d41ca31dbcb2..03c23ce98edb 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c | |||
@@ -20,13 +20,7 @@ | |||
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
22 | #include <asm/io.h> | 22 | #include <asm/io.h> |
23 | #ifdef CONFIG_FSL_OCP | ||
24 | #include <asm/ocp.h> | ||
25 | #define FSL_I2C_DEV_SEPARATE_DFSRR FS_I2C_SEPARATE_DFSRR | ||
26 | #define FSL_I2C_DEV_CLOCK_5200 FS_I2C_CLOCK_5200 | ||
27 | #else | ||
28 | #include <linux/fsl_devices.h> | 23 | #include <linux/fsl_devices.h> |
29 | #endif | ||
30 | #include <linux/i2c.h> | 24 | #include <linux/i2c.h> |
31 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
32 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
@@ -294,204 +288,6 @@ static struct i2c_adapter mpc_ops = { | |||
294 | .retries = 1 | 288 | .retries = 1 |
295 | }; | 289 | }; |
296 | 290 | ||
297 | #ifdef CONFIG_FSL_OCP | ||
298 | static int __devinit mpc_i2c_probe(struct ocp_device *ocp) | ||
299 | { | ||
300 | int result = 0; | ||
301 | struct mpc_i2c *i2c; | ||
302 | |||
303 | if (!(i2c = kmalloc(sizeof(*i2c), GFP_KERNEL))) { | ||
304 | return -ENOMEM; | ||
305 | } | ||
306 | memset(i2c, 0, sizeof(*i2c)); | ||
307 | |||
308 | i2c->irq = ocp->def->irq; | ||
309 | i2c->flags = ((struct ocp_fs_i2c_data *)ocp->def->additions)->flags; | ||
310 | init_waitqueue_head(&i2c->queue); | ||
311 | |||
312 | if (!request_mem_region(ocp->def->paddr, MPC_I2C_REGION, "i2c-mpc")) { | ||
313 | printk(KERN_ERR "i2c-mpc - resource unavailable\n"); | ||
314 | return -ENODEV; | ||
315 | } | ||
316 | |||
317 | i2c->base = ioremap(ocp->def->paddr, MPC_I2C_REGION); | ||
318 | |||
319 | if (!i2c->base) { | ||
320 | printk(KERN_ERR "i2c-mpc - failed to map controller\n"); | ||
321 | result = -ENOMEM; | ||
322 | goto fail_map; | ||
323 | } | ||
324 | |||
325 | if (i2c->irq != OCP_IRQ_NA) | ||
326 | { | ||
327 | if ((result = request_irq(ocp->def->irq, mpc_i2c_isr, | ||
328 | SA_SHIRQ, "i2c-mpc", i2c)) < 0) { | ||
329 | printk(KERN_ERR | ||
330 | "i2c-mpc - failed to attach interrupt\n"); | ||
331 | goto fail_irq; | ||
332 | } | ||
333 | } else | ||
334 | i2c->irq = 0; | ||
335 | |||
336 | mpc_i2c_setclock(i2c); | ||
337 | ocp_set_drvdata(ocp, i2c); | ||
338 | |||
339 | i2c->adap = mpc_ops; | ||
340 | i2c_set_adapdata(&i2c->adap, i2c); | ||
341 | |||
342 | if ((result = i2c_add_adapter(&i2c->adap)) < 0) { | ||
343 | printk(KERN_ERR "i2c-mpc - failed to add adapter\n"); | ||
344 | goto fail_add; | ||
345 | } | ||
346 | |||
347 | return result; | ||
348 | |||
349 | fail_add: | ||
350 | if (ocp->def->irq != OCP_IRQ_NA) | ||
351 | free_irq(ocp->def->irq, 0); | ||
352 | fail_irq: | ||
353 | iounmap(i2c->base); | ||
354 | fail_map: | ||
355 | release_mem_region(ocp->def->paddr, MPC_I2C_REGION); | ||
356 | kfree(i2c); | ||
357 | return result; | ||
358 | } | ||
359 | static void __devexit mpc_i2c_remove(struct ocp_device *ocp) | ||
360 | { | ||
361 | struct mpc_i2c *i2c = ocp_get_drvdata(ocp); | ||
362 | i2c_del_adapter(&i2c->adap); | ||
363 | ocp_set_drvdata(ocp, NULL); | ||
364 | |||
365 | if (ocp->def->irq != OCP_IRQ_NA) | ||
366 | free_irq(i2c->irq, i2c); | ||
367 | iounmap(i2c->base); | ||
368 | release_mem_region(ocp->def->paddr, MPC_I2C_REGION); | ||
369 | kfree(i2c); | ||
370 | } | ||
371 | |||
372 | static struct ocp_device_id mpc_iic_ids[] __devinitdata = { | ||
373 | {.vendor = OCP_VENDOR_FREESCALE,.function = OCP_FUNC_IIC}, | ||
374 | {.vendor = OCP_VENDOR_INVALID} | ||
375 | }; | ||
376 | |||
377 | MODULE_DEVICE_TABLE(ocp, mpc_iic_ids); | ||
378 | |||
379 | static struct ocp_driver mpc_iic_driver = { | ||
380 | .name = "iic", | ||
381 | .id_table = mpc_iic_ids, | ||
382 | .probe = mpc_i2c_probe, | ||
383 | .remove = __devexit_p(mpc_i2c_remove) | ||
384 | }; | ||
385 | |||
386 | static int __init iic_init(void) | ||
387 | { | ||
388 | return ocp_register_driver(&mpc_iic_driver); | ||
389 | } | ||
390 | |||
391 | static void __exit iic_exit(void) | ||
392 | { | ||
393 | ocp_unregister_driver(&mpc_iic_driver); | ||
394 | } | ||
395 | |||
396 | module_init(iic_init); | ||
397 | module_exit(iic_exit); | ||
398 | #else | ||
399 | static int fsl_i2c_probe(struct device *device) | ||
400 | { | ||
401 | int result = 0; | ||
402 | struct mpc_i2c *i2c; | ||
403 | struct platform_device *pdev = to_platform_device(device); | ||
404 | struct fsl_i2c_platform_data *pdata; | ||
405 | struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
406 | |||
407 | pdata = (struct fsl_i2c_platform_data *) pdev->dev.platform_data; | ||
408 | |||
409 | if (!(i2c = kmalloc(sizeof(*i2c), GFP_KERNEL))) { | ||
410 | return -ENOMEM; | ||
411 | } | ||
412 | memset(i2c, 0, sizeof(*i2c)); | ||
413 | |||
414 | i2c->irq = platform_get_irq(pdev, 0); | ||
415 | i2c->flags = pdata->device_flags; | ||
416 | init_waitqueue_head(&i2c->queue); | ||
417 | |||
418 | i2c->base = ioremap((phys_addr_t)r->start, MPC_I2C_REGION); | ||
419 | |||
420 | if (!i2c->base) { | ||
421 | printk(KERN_ERR "i2c-mpc - failed to map controller\n"); | ||
422 | result = -ENOMEM; | ||
423 | goto fail_map; | ||
424 | } | ||
425 | |||
426 | if (i2c->irq != 0) | ||
427 | if ((result = request_irq(i2c->irq, mpc_i2c_isr, | ||
428 | SA_SHIRQ, "i2c-mpc", i2c)) < 0) { | ||
429 | printk(KERN_ERR | ||
430 | "i2c-mpc - failed to attach interrupt\n"); | ||
431 | goto fail_irq; | ||
432 | } | ||
433 | |||
434 | mpc_i2c_setclock(i2c); | ||
435 | dev_set_drvdata(device, i2c); | ||
436 | |||
437 | i2c->adap = mpc_ops; | ||
438 | i2c_set_adapdata(&i2c->adap, i2c); | ||
439 | i2c->adap.dev.parent = &pdev->dev; | ||
440 | if ((result = i2c_add_adapter(&i2c->adap)) < 0) { | ||
441 | printk(KERN_ERR "i2c-mpc - failed to add adapter\n"); | ||
442 | goto fail_add; | ||
443 | } | ||
444 | |||
445 | return result; | ||
446 | |||
447 | fail_add: | ||
448 | if (i2c->irq != 0) | ||
449 | free_irq(i2c->irq, NULL); | ||
450 | fail_irq: | ||
451 | iounmap(i2c->base); | ||
452 | fail_map: | ||
453 | kfree(i2c); | ||
454 | return result; | ||
455 | }; | ||
456 | |||
457 | static int fsl_i2c_remove(struct device *device) | ||
458 | { | ||
459 | struct mpc_i2c *i2c = dev_get_drvdata(device); | ||
460 | |||
461 | i2c_del_adapter(&i2c->adap); | ||
462 | dev_set_drvdata(device, NULL); | ||
463 | |||
464 | if (i2c->irq != 0) | ||
465 | free_irq(i2c->irq, i2c); | ||
466 | |||
467 | iounmap(i2c->base); | ||
468 | kfree(i2c); | ||
469 | return 0; | ||
470 | }; | ||
471 | |||
472 | /* Structure for a device driver */ | ||
473 | static struct device_driver fsl_i2c_driver = { | ||
474 | .name = "fsl-i2c", | ||
475 | .bus = &platform_bus_type, | ||
476 | .probe = fsl_i2c_probe, | ||
477 | .remove = fsl_i2c_remove, | ||
478 | }; | ||
479 | |||
480 | static int __init fsl_i2c_init(void) | ||
481 | { | ||
482 | return driver_register(&fsl_i2c_driver); | ||
483 | } | ||
484 | |||
485 | static void __exit fsl_i2c_exit(void) | ||
486 | { | ||
487 | driver_unregister(&fsl_i2c_driver); | ||
488 | } | ||
489 | |||
490 | module_init(fsl_i2c_init); | ||
491 | module_exit(fsl_i2c_exit); | ||
492 | |||
493 | #endif /* CONFIG_FSL_OCP */ | ||
494 | |||
495 | MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>"); | 291 | MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>"); |
496 | MODULE_DESCRIPTION | 292 | MODULE_DESCRIPTION |
497 | ("I2C-Bus adapter for MPC107 bridge and MPC824x/85xx/52xx processors"); | 293 | ("I2C-Bus adapter for MPC107 bridge and MPC824x/85xx/52xx processors"); |
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 5900de3c3f4f..a9bf549c8dc5 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -396,7 +396,7 @@ static void i8042_stop(struct serio *serio) | |||
396 | struct i8042_port *port = serio->port_data; | 396 | struct i8042_port *port = serio->port_data; |
397 | 397 | ||
398 | port->exists = 0; | 398 | port->exists = 0; |
399 | synchronize_kernel(); | 399 | synchronize_sched(); |
400 | port->serio = NULL; | 400 | port->serio = NULL; |
401 | } | 401 | } |
402 | 402 | ||
diff --git a/drivers/isdn/act2000/capi.c b/drivers/isdn/act2000/capi.c index 40395f567231..afa46681f983 100644 --- a/drivers/isdn/act2000/capi.c +++ b/drivers/isdn/act2000/capi.c | |||
@@ -224,6 +224,7 @@ actcapi_manufacturer_req_net(act2000_card *card) | |||
224 | /* | 224 | /* |
225 | * Switch V.42 on or off | 225 | * Switch V.42 on or off |
226 | */ | 226 | */ |
227 | #if 0 | ||
227 | int | 228 | int |
228 | actcapi_manufacturer_req_v42(act2000_card *card, ulong arg) | 229 | actcapi_manufacturer_req_v42(act2000_card *card, ulong arg) |
229 | { | 230 | { |
@@ -242,6 +243,7 @@ actcapi_manufacturer_req_v42(act2000_card *card, ulong arg) | |||
242 | ACTCAPI_QUEUE_TX; | 243 | ACTCAPI_QUEUE_TX; |
243 | return 0; | 244 | return 0; |
244 | } | 245 | } |
246 | #endif /* 0 */ | ||
245 | 247 | ||
246 | /* | 248 | /* |
247 | * Set error-handler | 249 | * Set error-handler |
diff --git a/drivers/isdn/act2000/capi.h b/drivers/isdn/act2000/capi.h index 04d2bcdd37a7..f6d5f530b86b 100644 --- a/drivers/isdn/act2000/capi.h +++ b/drivers/isdn/act2000/capi.h | |||
@@ -350,7 +350,6 @@ actcapi_nextsmsg(act2000_card *card) | |||
350 | extern int actcapi_chkhdr(act2000_card *, actcapi_msghdr *); | 350 | extern int actcapi_chkhdr(act2000_card *, actcapi_msghdr *); |
351 | extern int actcapi_listen_req(act2000_card *); | 351 | extern int actcapi_listen_req(act2000_card *); |
352 | extern int actcapi_manufacturer_req_net(act2000_card *); | 352 | extern int actcapi_manufacturer_req_net(act2000_card *); |
353 | extern int actcapi_manufacturer_req_v42(act2000_card *, ulong); | ||
354 | extern int actcapi_manufacturer_req_errh(act2000_card *); | 353 | extern int actcapi_manufacturer_req_errh(act2000_card *); |
355 | extern int actcapi_manufacturer_req_msn(act2000_card *); | 354 | extern int actcapi_manufacturer_req_msn(act2000_card *); |
356 | extern int actcapi_connect_req(act2000_card *, act2000_chan *, char *, char, int, int); | 355 | extern int actcapi_connect_req(act2000_card *, act2000_chan *, char *, char, int, int); |
diff --git a/drivers/isdn/hardware/avm/b1dma.c b/drivers/isdn/hardware/avm/b1dma.c index 55bed00ca865..91dd0551fc7c 100644 --- a/drivers/isdn/hardware/avm/b1dma.c +++ b/drivers/isdn/hardware/avm/b1dma.c | |||
@@ -955,7 +955,7 @@ EXPORT_SYMBOL(b1dma_release_appl); | |||
955 | EXPORT_SYMBOL(b1dma_send_message); | 955 | EXPORT_SYMBOL(b1dma_send_message); |
956 | EXPORT_SYMBOL(b1dmactl_read_proc); | 956 | EXPORT_SYMBOL(b1dmactl_read_proc); |
957 | 957 | ||
958 | int b1dma_init(void) | 958 | static int __init b1dma_init(void) |
959 | { | 959 | { |
960 | char *p; | 960 | char *p; |
961 | char rev[32]; | 961 | char rev[32]; |
@@ -972,7 +972,7 @@ int b1dma_init(void) | |||
972 | return 0; | 972 | return 0; |
973 | } | 973 | } |
974 | 974 | ||
975 | void b1dma_exit(void) | 975 | static void __exit b1dma_exit(void) |
976 | { | 976 | { |
977 | } | 977 | } |
978 | 978 | ||
diff --git a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c index fa6b93b1a42d..724aac2c1cca 100644 --- a/drivers/isdn/hardware/avm/c4.c +++ b/drivers/isdn/hardware/avm/c4.c | |||
@@ -885,7 +885,7 @@ static int c4_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) | |||
885 | } | 885 | } |
886 | 886 | ||
887 | 887 | ||
888 | void c4_reset_ctr(struct capi_ctr *ctrl) | 888 | static void c4_reset_ctr(struct capi_ctr *ctrl) |
889 | { | 889 | { |
890 | avmcard *card = ((avmctrl_info *)(ctrl->driverdata))->card; | 890 | avmcard *card = ((avmctrl_info *)(ctrl->driverdata))->card; |
891 | avmctrl_info *cinfo; | 891 | avmctrl_info *cinfo; |
@@ -933,7 +933,7 @@ static void c4_remove(struct pci_dev *pdev) | |||
933 | /* ------------------------------------------------------------- */ | 933 | /* ------------------------------------------------------------- */ |
934 | 934 | ||
935 | 935 | ||
936 | void c4_register_appl(struct capi_ctr *ctrl, | 936 | static void c4_register_appl(struct capi_ctr *ctrl, |
937 | u16 appl, | 937 | u16 appl, |
938 | capi_register_params *rp) | 938 | capi_register_params *rp) |
939 | { | 939 | { |
@@ -978,7 +978,7 @@ void c4_register_appl(struct capi_ctr *ctrl, | |||
978 | 978 | ||
979 | /* ------------------------------------------------------------- */ | 979 | /* ------------------------------------------------------------- */ |
980 | 980 | ||
981 | void c4_release_appl(struct capi_ctr *ctrl, u16 appl) | 981 | static void c4_release_appl(struct capi_ctr *ctrl, u16 appl) |
982 | { | 982 | { |
983 | avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); | 983 | avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); |
984 | avmcard *card = cinfo->card; | 984 | avmcard *card = cinfo->card; |
diff --git a/drivers/isdn/hardware/avm/t1isa.c b/drivers/isdn/hardware/avm/t1isa.c index cb9d9cee2a64..3b701d97bdf1 100644 --- a/drivers/isdn/hardware/avm/t1isa.c +++ b/drivers/isdn/hardware/avm/t1isa.c | |||
@@ -328,7 +328,7 @@ static int t1isa_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) | |||
328 | return 0; | 328 | return 0; |
329 | } | 329 | } |
330 | 330 | ||
331 | void t1isa_reset_ctr(struct capi_ctr *ctrl) | 331 | static void t1isa_reset_ctr(struct capi_ctr *ctrl) |
332 | { | 332 | { |
333 | avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); | 333 | avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); |
334 | avmcard *card = cinfo->card; | 334 | avmcard *card = cinfo->card; |
diff --git a/drivers/isdn/hisax/Makefile b/drivers/isdn/hisax/Makefile index 8d6bb56754b8..293e27789d54 100644 --- a/drivers/isdn/hisax/Makefile +++ b/drivers/isdn/hisax/Makefile | |||
@@ -23,7 +23,7 @@ endif | |||
23 | # Multipart objects. | 23 | # Multipart objects. |
24 | 24 | ||
25 | hisax_st5481-y := st5481_init.o st5481_usb.o st5481_d.o \ | 25 | hisax_st5481-y := st5481_init.o st5481_usb.o st5481_d.o \ |
26 | st5481_b.o st5481_hdlc.o | 26 | st5481_b.o |
27 | 27 | ||
28 | hisax-y := config.o isdnl1.o tei.o isdnl2.o isdnl3.o \ | 28 | hisax-y := config.o isdnl1.o tei.o isdnl2.o isdnl3.o \ |
29 | lmgr.o q931.o callc.o fsm.o | 29 | lmgr.o q931.o callc.o fsm.o |
diff --git a/drivers/isdn/hisax/amd7930_fn.c b/drivers/isdn/hisax/amd7930_fn.c index c4f861a5db25..8ae08c41c853 100644 --- a/drivers/isdn/hisax/amd7930_fn.c +++ b/drivers/isdn/hisax/amd7930_fn.c | |||
@@ -97,7 +97,7 @@ static WORD initAMD[] = { | |||
97 | }; | 97 | }; |
98 | 98 | ||
99 | 99 | ||
100 | void /* macro wWordAMD */ | 100 | static void /* macro wWordAMD */ |
101 | WriteWordAmd7930(struct IsdnCardState *cs, BYTE reg, WORD val) | 101 | WriteWordAmd7930(struct IsdnCardState *cs, BYTE reg, WORD val) |
102 | { | 102 | { |
103 | wByteAMD(cs, 0x00, reg); | 103 | wByteAMD(cs, 0x00, reg); |
@@ -105,7 +105,7 @@ WriteWordAmd7930(struct IsdnCardState *cs, BYTE reg, WORD val) | |||
105 | wByteAMD(cs, 0x01, HIBYTE(val)); | 105 | wByteAMD(cs, 0x01, HIBYTE(val)); |
106 | } | 106 | } |
107 | 107 | ||
108 | WORD /* macro rWordAMD */ | 108 | static WORD /* macro rWordAMD */ |
109 | ReadWordAmd7930(struct IsdnCardState *cs, BYTE reg) | 109 | ReadWordAmd7930(struct IsdnCardState *cs, BYTE reg) |
110 | { | 110 | { |
111 | WORD res; | 111 | WORD res; |
@@ -665,7 +665,7 @@ Amd7930_l1hw(struct PStack *st, int pr, void *arg) | |||
665 | } | 665 | } |
666 | } | 666 | } |
667 | 667 | ||
668 | void | 668 | static void |
669 | setstack_Amd7930(struct PStack *st, struct IsdnCardState *cs) | 669 | setstack_Amd7930(struct PStack *st, struct IsdnCardState *cs) |
670 | { | 670 | { |
671 | 671 | ||
@@ -676,7 +676,7 @@ setstack_Amd7930(struct PStack *st, struct IsdnCardState *cs) | |||
676 | } | 676 | } |
677 | 677 | ||
678 | 678 | ||
679 | void | 679 | static void |
680 | DC_Close_Amd7930(struct IsdnCardState *cs) { | 680 | DC_Close_Amd7930(struct IsdnCardState *cs) { |
681 | if (cs->debug & L1_DEB_ISAC) | 681 | if (cs->debug & L1_DEB_ISAC) |
682 | debugl1(cs, "Amd7930: DC_Close called"); | 682 | debugl1(cs, "Amd7930: DC_Close called"); |
diff --git a/drivers/isdn/hisax/asuscom.c b/drivers/isdn/hisax/asuscom.c index 7546e2e4a94e..a98c5e38bbbc 100644 --- a/drivers/isdn/hisax/asuscom.c +++ b/drivers/isdn/hisax/asuscom.c | |||
@@ -22,7 +22,7 @@ | |||
22 | 22 | ||
23 | extern const char *CardType[]; | 23 | extern const char *CardType[]; |
24 | 24 | ||
25 | const char *Asuscom_revision = "$Revision: 1.14.2.4 $"; | 25 | static const char *Asuscom_revision = "$Revision: 1.14.2.4 $"; |
26 | 26 | ||
27 | #define byteout(addr,val) outb(val,addr) | 27 | #define byteout(addr,val) outb(val,addr) |
28 | #define bytein(addr) inb(addr) | 28 | #define bytein(addr) inb(addr) |
@@ -239,7 +239,7 @@ Start_IPAC: | |||
239 | return IRQ_HANDLED; | 239 | return IRQ_HANDLED; |
240 | } | 240 | } |
241 | 241 | ||
242 | void | 242 | static void |
243 | release_io_asuscom(struct IsdnCardState *cs) | 243 | release_io_asuscom(struct IsdnCardState *cs) |
244 | { | 244 | { |
245 | int bytecnt = 8; | 245 | int bytecnt = 8; |
diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c index 6fcb2cf7b0b6..625799ab0d14 100644 --- a/drivers/isdn/hisax/avm_pci.c +++ b/drivers/isdn/hisax/avm_pci.c | |||
@@ -172,7 +172,7 @@ struct BCState *Sel_BCS(struct IsdnCardState *cs, int channel) | |||
172 | return(NULL); | 172 | return(NULL); |
173 | } | 173 | } |
174 | 174 | ||
175 | void | 175 | static void |
176 | write_ctrl(struct BCState *bcs, int which) { | 176 | write_ctrl(struct BCState *bcs, int which) { |
177 | 177 | ||
178 | if (bcs->cs->debug & L1_DEB_HSCX) | 178 | if (bcs->cs->debug & L1_DEB_HSCX) |
@@ -193,7 +193,7 @@ write_ctrl(struct BCState *bcs, int which) { | |||
193 | } | 193 | } |
194 | } | 194 | } |
195 | 195 | ||
196 | void | 196 | static void |
197 | modehdlc(struct BCState *bcs, int mode, int bc) | 197 | modehdlc(struct BCState *bcs, int mode, int bc) |
198 | { | 198 | { |
199 | struct IsdnCardState *cs = bcs->cs; | 199 | struct IsdnCardState *cs = bcs->cs; |
@@ -451,7 +451,7 @@ HDLC_irq(struct BCState *bcs, u_int stat) { | |||
451 | } | 451 | } |
452 | } | 452 | } |
453 | 453 | ||
454 | inline void | 454 | static inline void |
455 | HDLC_irq_main(struct IsdnCardState *cs) | 455 | HDLC_irq_main(struct IsdnCardState *cs) |
456 | { | 456 | { |
457 | u_int stat; | 457 | u_int stat; |
@@ -487,7 +487,7 @@ HDLC_irq_main(struct IsdnCardState *cs) | |||
487 | } | 487 | } |
488 | } | 488 | } |
489 | 489 | ||
490 | void | 490 | static void |
491 | hdlc_l2l1(struct PStack *st, int pr, void *arg) | 491 | hdlc_l2l1(struct PStack *st, int pr, void *arg) |
492 | { | 492 | { |
493 | struct BCState *bcs = st->l1.bcs; | 493 | struct BCState *bcs = st->l1.bcs; |
@@ -547,7 +547,7 @@ hdlc_l2l1(struct PStack *st, int pr, void *arg) | |||
547 | } | 547 | } |
548 | } | 548 | } |
549 | 549 | ||
550 | void | 550 | static void |
551 | close_hdlcstate(struct BCState *bcs) | 551 | close_hdlcstate(struct BCState *bcs) |
552 | { | 552 | { |
553 | modehdlc(bcs, 0, 0); | 553 | modehdlc(bcs, 0, 0); |
@@ -570,7 +570,7 @@ close_hdlcstate(struct BCState *bcs) | |||
570 | } | 570 | } |
571 | } | 571 | } |
572 | 572 | ||
573 | int | 573 | static int |
574 | open_hdlcstate(struct IsdnCardState *cs, struct BCState *bcs) | 574 | open_hdlcstate(struct IsdnCardState *cs, struct BCState *bcs) |
575 | { | 575 | { |
576 | if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { | 576 | if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { |
@@ -598,7 +598,7 @@ open_hdlcstate(struct IsdnCardState *cs, struct BCState *bcs) | |||
598 | return (0); | 598 | return (0); |
599 | } | 599 | } |
600 | 600 | ||
601 | int | 601 | static int |
602 | setstack_hdlc(struct PStack *st, struct BCState *bcs) | 602 | setstack_hdlc(struct PStack *st, struct BCState *bcs) |
603 | { | 603 | { |
604 | bcs->channel = st->l1.bc; | 604 | bcs->channel = st->l1.bc; |
@@ -612,6 +612,7 @@ setstack_hdlc(struct PStack *st, struct BCState *bcs) | |||
612 | return (0); | 612 | return (0); |
613 | } | 613 | } |
614 | 614 | ||
615 | #if 0 | ||
615 | void __init | 616 | void __init |
616 | clear_pending_hdlc_ints(struct IsdnCardState *cs) | 617 | clear_pending_hdlc_ints(struct IsdnCardState *cs) |
617 | { | 618 | { |
@@ -641,8 +642,9 @@ clear_pending_hdlc_ints(struct IsdnCardState *cs) | |||
641 | debugl1(cs, "HDLC 2 VIN %x", val); | 642 | debugl1(cs, "HDLC 2 VIN %x", val); |
642 | } | 643 | } |
643 | } | 644 | } |
645 | #endif /* 0 */ | ||
644 | 646 | ||
645 | void __init | 647 | static void __init |
646 | inithdlc(struct IsdnCardState *cs) | 648 | inithdlc(struct IsdnCardState *cs) |
647 | { | 649 | { |
648 | cs->bcs[0].BC_SetStack = setstack_hdlc; | 650 | cs->bcs[0].BC_SetStack = setstack_hdlc; |
diff --git a/drivers/isdn/hisax/bkm_a4t.c b/drivers/isdn/hisax/bkm_a4t.c index f410f628a3e2..dcb308aeb50c 100644 --- a/drivers/isdn/hisax/bkm_a4t.c +++ b/drivers/isdn/hisax/bkm_a4t.c | |||
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | extern const char *CardType[]; | 24 | extern const char *CardType[]; |
25 | 25 | ||
26 | const char *bkm_a4t_revision = "$Revision: 1.22.2.4 $"; | 26 | static const char *bkm_a4t_revision = "$Revision: 1.22.2.4 $"; |
27 | 27 | ||
28 | 28 | ||
29 | static inline u_char | 29 | static inline u_char |
@@ -167,7 +167,7 @@ bkm_interrupt(int intno, void *dev_id, struct pt_regs *regs) | |||
167 | } | 167 | } |
168 | } | 168 | } |
169 | 169 | ||
170 | void | 170 | static void |
171 | release_io_bkm(struct IsdnCardState *cs) | 171 | release_io_bkm(struct IsdnCardState *cs) |
172 | { | 172 | { |
173 | if (cs->hw.ax.base) { | 173 | if (cs->hw.ax.base) { |
diff --git a/drivers/isdn/hisax/bkm_a8.c b/drivers/isdn/hisax/bkm_a8.c index 94bb83ce7fd8..5f21b82c8c8d 100644 --- a/drivers/isdn/hisax/bkm_a8.c +++ b/drivers/isdn/hisax/bkm_a8.c | |||
@@ -27,7 +27,7 @@ | |||
27 | 27 | ||
28 | extern const char *CardType[]; | 28 | extern const char *CardType[]; |
29 | 29 | ||
30 | const char sct_quadro_revision[] = "$Revision: 1.22.2.4 $"; | 30 | static const char sct_quadro_revision[] = "$Revision: 1.22.2.4 $"; |
31 | 31 | ||
32 | static const char *sct_quadro_subtypes[] = | 32 | static const char *sct_quadro_subtypes[] = |
33 | { | 33 | { |
@@ -193,7 +193,7 @@ bkm_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs) | |||
193 | return IRQ_HANDLED; | 193 | return IRQ_HANDLED; |
194 | } | 194 | } |
195 | 195 | ||
196 | void | 196 | static void |
197 | release_io_sct_quadro(struct IsdnCardState *cs) | 197 | release_io_sct_quadro(struct IsdnCardState *cs) |
198 | { | 198 | { |
199 | release_region(cs->hw.ax.base & 0xffffffc0, 128); | 199 | release_region(cs->hw.ax.base & 0xffffffc0, 128); |
@@ -261,7 +261,7 @@ BKM_card_msg(struct IsdnCardState *cs, int mt, void *arg) | |||
261 | return (0); | 261 | return (0); |
262 | } | 262 | } |
263 | 263 | ||
264 | int __init | 264 | static int __init |
265 | sct_alloc_io(u_int adr, u_int len) | 265 | sct_alloc_io(u_int adr, u_int len) |
266 | { | 266 | { |
267 | if (!request_region(adr, len, "scitel")) { | 267 | if (!request_region(adr, len, "scitel")) { |
diff --git a/drivers/isdn/hisax/callc.c b/drivers/isdn/hisax/callc.c index 04065ab2610f..7c56c44f0fd1 100644 --- a/drivers/isdn/hisax/callc.c +++ b/drivers/isdn/hisax/callc.c | |||
@@ -874,7 +874,7 @@ release_b_st(struct Channel *chanp) | |||
874 | } | 874 | } |
875 | } | 875 | } |
876 | 876 | ||
877 | struct Channel | 877 | static struct Channel |
878 | *selectfreechannel(struct PStack *st, int bch) | 878 | *selectfreechannel(struct PStack *st, int bch) |
879 | { | 879 | { |
880 | struct IsdnCardState *cs = st->l1.hardware; | 880 | struct IsdnCardState *cs = st->l1.hardware; |
@@ -1429,7 +1429,7 @@ capi_debug(struct Channel *chanp, capi_msg *cm) | |||
1429 | HiSax_putstatus(chanp->cs, "Ch", "%d CAPIMSG %s", chanp->chan, tmpbuf); | 1429 | HiSax_putstatus(chanp->cs, "Ch", "%d CAPIMSG %s", chanp->chan, tmpbuf); |
1430 | } | 1430 | } |
1431 | 1431 | ||
1432 | void | 1432 | static void |
1433 | lli_got_fac_req(struct Channel *chanp, capi_msg *cm) { | 1433 | lli_got_fac_req(struct Channel *chanp, capi_msg *cm) { |
1434 | if ((cm->para[0] != 3) || (cm->para[1] != 0)) | 1434 | if ((cm->para[0] != 3) || (cm->para[1] != 0)) |
1435 | return; | 1435 | return; |
@@ -1454,7 +1454,7 @@ lli_got_fac_req(struct Channel *chanp, capi_msg *cm) { | |||
1454 | } | 1454 | } |
1455 | } | 1455 | } |
1456 | 1456 | ||
1457 | void | 1457 | static void |
1458 | lli_got_manufacturer(struct Channel *chanp, struct IsdnCardState *cs, capi_msg *cm) { | 1458 | lli_got_manufacturer(struct Channel *chanp, struct IsdnCardState *cs, capi_msg *cm) { |
1459 | if ((cs->typ == ISDN_CTYPE_ELSA) || (cs->typ == ISDN_CTYPE_ELSA_PNP) || | 1459 | if ((cs->typ == ISDN_CTYPE_ELSA) || (cs->typ == ISDN_CTYPE_ELSA_PNP) || |
1460 | (cs->typ == ISDN_CTYPE_ELSA_PCI)) { | 1460 | (cs->typ == ISDN_CTYPE_ELSA_PCI)) { |
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index 1663ee69d41d..c542e6fb2bde 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c | |||
@@ -332,7 +332,7 @@ struct IsdnCard cards[HISAX_MAX_CARDS] = { | |||
332 | #define HISAX_IDSIZE (HISAX_MAX_CARDS*8) | 332 | #define HISAX_IDSIZE (HISAX_MAX_CARDS*8) |
333 | static char HiSaxID[HISAX_IDSIZE] = { 0, }; | 333 | static char HiSaxID[HISAX_IDSIZE] = { 0, }; |
334 | 334 | ||
335 | char *HiSax_id = HiSaxID; | 335 | static char *HiSax_id = HiSaxID; |
336 | #ifdef MODULE | 336 | #ifdef MODULE |
337 | /* Variables for insmod */ | 337 | /* Variables for insmod */ |
338 | static int type[HISAX_MAX_CARDS] = { 0, }; | 338 | static int type[HISAX_MAX_CARDS] = { 0, }; |
@@ -391,7 +391,7 @@ char *HiSax_getrev(const char *revision) | |||
391 | return rev; | 391 | return rev; |
392 | } | 392 | } |
393 | 393 | ||
394 | void __init HiSaxVersion(void) | 394 | static void __init HiSaxVersion(void) |
395 | { | 395 | { |
396 | char tmp[64]; | 396 | char tmp[64]; |
397 | 397 | ||
@@ -608,6 +608,7 @@ static inline struct IsdnCardState *hisax_findcard(int driverid) | |||
608 | /* | 608 | /* |
609 | * Find card with given card number | 609 | * Find card with given card number |
610 | */ | 610 | */ |
611 | #if 0 | ||
611 | struct IsdnCardState *hisax_get_card(int cardnr) | 612 | struct IsdnCardState *hisax_get_card(int cardnr) |
612 | { | 613 | { |
613 | if ((cardnr <= nrcards) && (cardnr > 0)) | 614 | if ((cardnr <= nrcards) && (cardnr > 0)) |
@@ -615,8 +616,9 @@ struct IsdnCardState *hisax_get_card(int cardnr) | |||
615 | return cards[cardnr - 1].cs; | 616 | return cards[cardnr - 1].cs; |
616 | return NULL; | 617 | return NULL; |
617 | } | 618 | } |
619 | #endif /* 0 */ | ||
618 | 620 | ||
619 | int HiSax_readstatus(u_char __user *buf, int len, int id, int channel) | 621 | static int HiSax_readstatus(u_char __user *buf, int len, int id, int channel) |
620 | { | 622 | { |
621 | int count, cnt; | 623 | int count, cnt; |
622 | u_char __user *p = buf; | 624 | u_char __user *p = buf; |
@@ -768,7 +770,7 @@ int ll_run(struct IsdnCardState *cs, int addfeatures) | |||
768 | return 0; | 770 | return 0; |
769 | } | 771 | } |
770 | 772 | ||
771 | void ll_stop(struct IsdnCardState *cs) | 773 | static void ll_stop(struct IsdnCardState *cs) |
772 | { | 774 | { |
773 | isdn_ctrl ic; | 775 | isdn_ctrl ic; |
774 | 776 | ||
@@ -1184,7 +1186,7 @@ static int checkcard(int cardnr, char *id, int *busy_flag, struct module *lockow | |||
1184 | return ret; | 1186 | return ret; |
1185 | } | 1187 | } |
1186 | 1188 | ||
1187 | void HiSax_shiftcards(int idx) | 1189 | static void HiSax_shiftcards(int idx) |
1188 | { | 1190 | { |
1189 | int i; | 1191 | int i; |
1190 | 1192 | ||
@@ -1192,7 +1194,7 @@ void HiSax_shiftcards(int idx) | |||
1192 | memcpy(&cards[i], &cards[i + 1], sizeof(cards[i])); | 1194 | memcpy(&cards[i], &cards[i + 1], sizeof(cards[i])); |
1193 | } | 1195 | } |
1194 | 1196 | ||
1195 | int HiSax_inithardware(int *busy_flag) | 1197 | static int HiSax_inithardware(int *busy_flag) |
1196 | { | 1198 | { |
1197 | int foundcards = 0; | 1199 | int foundcards = 0; |
1198 | int i = 0; | 1200 | int i = 0; |
diff --git a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c index 394d481e093f..b62d6b30b72b 100644 --- a/drivers/isdn/hisax/diva.c +++ b/drivers/isdn/hisax/diva.c | |||
@@ -28,7 +28,7 @@ | |||
28 | 28 | ||
29 | extern const char *CardType[]; | 29 | extern const char *CardType[]; |
30 | 30 | ||
31 | const char *Diva_revision = "$Revision: 1.33.2.6 $"; | 31 | static const char *Diva_revision = "$Revision: 1.33.2.6 $"; |
32 | 32 | ||
33 | #define byteout(addr,val) outb(val,addr) | 33 | #define byteout(addr,val) outb(val,addr) |
34 | #define bytein(addr) inb(addr) | 34 | #define bytein(addr) inb(addr) |
@@ -706,7 +706,7 @@ diva_irq_ipacx_pci(int intno, void *dev_id, struct pt_regs *regs) | |||
706 | return IRQ_HANDLED; | 706 | return IRQ_HANDLED; |
707 | } | 707 | } |
708 | 708 | ||
709 | void | 709 | static void |
710 | release_io_diva(struct IsdnCardState *cs) | 710 | release_io_diva(struct IsdnCardState *cs) |
711 | { | 711 | { |
712 | int bytecnt; | 712 | int bytecnt; |
diff --git a/drivers/isdn/hisax/elsa.c b/drivers/isdn/hisax/elsa.c index 4d7a0250d7e2..110e9fd669c5 100644 --- a/drivers/isdn/hisax/elsa.c +++ b/drivers/isdn/hisax/elsa.c | |||
@@ -33,13 +33,13 @@ | |||
33 | 33 | ||
34 | extern const char *CardType[]; | 34 | extern const char *CardType[]; |
35 | 35 | ||
36 | const char *Elsa_revision = "$Revision: 2.32.2.4 $"; | 36 | static const char *Elsa_revision = "$Revision: 2.32.2.4 $"; |
37 | const char *Elsa_Types[] = | 37 | static const char *Elsa_Types[] = |
38 | {"None", "PC", "PCC-8", "PCC-16", "PCF", "PCF-Pro", | 38 | {"None", "PC", "PCC-8", "PCC-16", "PCF", "PCF-Pro", |
39 | "PCMCIA", "QS 1000", "QS 3000", "Microlink PCI", "QS 3000 PCI", | 39 | "PCMCIA", "QS 1000", "QS 3000", "Microlink PCI", "QS 3000 PCI", |
40 | "PCMCIA-IPAC" }; | 40 | "PCMCIA-IPAC" }; |
41 | 41 | ||
42 | const char *ITACVer[] = | 42 | static const char *ITACVer[] = |
43 | {"?0?", "?1?", "?2?", "?3?", "?4?", "V2.2", | 43 | {"?0?", "?1?", "?2?", "?3?", "?4?", "V2.2", |
44 | "B1", "A1"}; | 44 | "B1", "A1"}; |
45 | 45 | ||
@@ -425,7 +425,7 @@ Start_IPAC: | |||
425 | return IRQ_HANDLED; | 425 | return IRQ_HANDLED; |
426 | } | 426 | } |
427 | 427 | ||
428 | void | 428 | static void |
429 | release_io_elsa(struct IsdnCardState *cs) | 429 | release_io_elsa(struct IsdnCardState *cs) |
430 | { | 430 | { |
431 | int bytecnt = 8; | 431 | int bytecnt = 8; |
diff --git a/drivers/isdn/hisax/elsa_ser.c b/drivers/isdn/hisax/elsa_ser.c index 689c83395693..898ec0916195 100644 --- a/drivers/isdn/hisax/elsa_ser.c +++ b/drivers/isdn/hisax/elsa_ser.c | |||
@@ -237,7 +237,7 @@ static void mshutdown(struct IsdnCardState *cs) | |||
237 | #endif | 237 | #endif |
238 | } | 238 | } |
239 | 239 | ||
240 | inline int | 240 | static inline int |
241 | write_modem(struct BCState *bcs) { | 241 | write_modem(struct BCState *bcs) { |
242 | int ret=0; | 242 | int ret=0; |
243 | struct IsdnCardState *cs = bcs->cs; | 243 | struct IsdnCardState *cs = bcs->cs; |
@@ -275,7 +275,7 @@ write_modem(struct BCState *bcs) { | |||
275 | return(ret); | 275 | return(ret); |
276 | } | 276 | } |
277 | 277 | ||
278 | inline void | 278 | static inline void |
279 | modem_fill(struct BCState *bcs) { | 279 | modem_fill(struct BCState *bcs) { |
280 | 280 | ||
281 | if (bcs->tx_skb) { | 281 | if (bcs->tx_skb) { |
@@ -422,7 +422,7 @@ extern int open_hscxstate(struct IsdnCardState *cs, struct BCState *bcs); | |||
422 | extern void modehscx(struct BCState *bcs, int mode, int bc); | 422 | extern void modehscx(struct BCState *bcs, int mode, int bc); |
423 | extern void hscx_l2l1(struct PStack *st, int pr, void *arg); | 423 | extern void hscx_l2l1(struct PStack *st, int pr, void *arg); |
424 | 424 | ||
425 | void | 425 | static void |
426 | close_elsastate(struct BCState *bcs) | 426 | close_elsastate(struct BCState *bcs) |
427 | { | 427 | { |
428 | modehscx(bcs, 0, bcs->channel); | 428 | modehscx(bcs, 0, bcs->channel); |
@@ -442,7 +442,7 @@ close_elsastate(struct BCState *bcs) | |||
442 | } | 442 | } |
443 | } | 443 | } |
444 | 444 | ||
445 | void | 445 | static void |
446 | modem_write_cmd(struct IsdnCardState *cs, u_char *buf, int len) { | 446 | modem_write_cmd(struct IsdnCardState *cs, u_char *buf, int len) { |
447 | int count, fp; | 447 | int count, fp; |
448 | u_char *msg = buf; | 448 | u_char *msg = buf; |
@@ -472,7 +472,7 @@ modem_write_cmd(struct IsdnCardState *cs, u_char *buf, int len) { | |||
472 | } | 472 | } |
473 | } | 473 | } |
474 | 474 | ||
475 | void | 475 | static void |
476 | modem_set_init(struct IsdnCardState *cs) { | 476 | modem_set_init(struct IsdnCardState *cs) { |
477 | int timeout; | 477 | int timeout; |
478 | 478 | ||
@@ -521,7 +521,7 @@ modem_set_init(struct IsdnCardState *cs) { | |||
521 | udelay(RCV_DELAY); | 521 | udelay(RCV_DELAY); |
522 | } | 522 | } |
523 | 523 | ||
524 | void | 524 | static void |
525 | modem_set_dial(struct IsdnCardState *cs, int outgoing) { | 525 | modem_set_dial(struct IsdnCardState *cs, int outgoing) { |
526 | int timeout; | 526 | int timeout; |
527 | #define RCV_DELAY 20000 | 527 | #define RCV_DELAY 20000 |
@@ -543,7 +543,7 @@ modem_set_dial(struct IsdnCardState *cs, int outgoing) { | |||
543 | udelay(RCV_DELAY); | 543 | udelay(RCV_DELAY); |
544 | } | 544 | } |
545 | 545 | ||
546 | void | 546 | static void |
547 | modem_l2l1(struct PStack *st, int pr, void *arg) | 547 | modem_l2l1(struct PStack *st, int pr, void *arg) |
548 | { | 548 | { |
549 | struct BCState *bcs = st->l1.bcs; | 549 | struct BCState *bcs = st->l1.bcs; |
@@ -579,7 +579,7 @@ modem_l2l1(struct PStack *st, int pr, void *arg) | |||
579 | } | 579 | } |
580 | } | 580 | } |
581 | 581 | ||
582 | int | 582 | static int |
583 | setstack_elsa(struct PStack *st, struct BCState *bcs) | 583 | setstack_elsa(struct PStack *st, struct BCState *bcs) |
584 | { | 584 | { |
585 | 585 | ||
@@ -614,7 +614,7 @@ setstack_elsa(struct PStack *st, struct BCState *bcs) | |||
614 | return (0); | 614 | return (0); |
615 | } | 615 | } |
616 | 616 | ||
617 | void | 617 | static void |
618 | init_modem(struct IsdnCardState *cs) { | 618 | init_modem(struct IsdnCardState *cs) { |
619 | 619 | ||
620 | cs->bcs[0].BC_SetStack = setstack_elsa; | 620 | cs->bcs[0].BC_SetStack = setstack_elsa; |
@@ -641,7 +641,7 @@ init_modem(struct IsdnCardState *cs) { | |||
641 | modem_set_init(cs); | 641 | modem_set_init(cs); |
642 | } | 642 | } |
643 | 643 | ||
644 | void | 644 | static void |
645 | release_modem(struct IsdnCardState *cs) { | 645 | release_modem(struct IsdnCardState *cs) { |
646 | 646 | ||
647 | cs->hw.elsa.MFlag = 0; | 647 | cs->hw.elsa.MFlag = 0; |
diff --git a/drivers/isdn/hisax/enternow.h b/drivers/isdn/hisax/enternow.h deleted file mode 100644 index ed2eec5874c5..000000000000 --- a/drivers/isdn/hisax/enternow.h +++ /dev/null | |||
@@ -1,51 +0,0 @@ | |||
1 | /* 2001/10/02 | ||
2 | * | ||
3 | * enternow.h Header-file included by | ||
4 | * enternow_pci.c | ||
5 | * | ||
6 | * Author Christoph Ersfeld <info@formula-n.de> | ||
7 | * Formula-n Europe AG (www.formula-n.com) | ||
8 | * previously Gerdes AG | ||
9 | * | ||
10 | * | ||
11 | * This file is (c) under GNU PUBLIC LICENSE | ||
12 | */ | ||
13 | |||
14 | |||
15 | /* ***************************************************************************************** * | ||
16 | * ****************************** datatypes and macros ************************************* * | ||
17 | * ***************************************************************************************** */ | ||
18 | |||
19 | #define BYTE unsigned char | ||
20 | #define WORD unsigned int | ||
21 | #define HIBYTE(w) ((unsigned char)((w & 0xff00) / 256)) | ||
22 | #define LOBYTE(w) ((unsigned char)(w & 0x00ff)) | ||
23 | #define InByte(addr) inb(addr) | ||
24 | #define OutByte(addr,val) outb(val,addr) | ||
25 | |||
26 | |||
27 | |||
28 | /* ***************************************************************************************** * | ||
29 | * *********************************** card-specific *************************************** * | ||
30 | * ***************************************************************************************** */ | ||
31 | |||
32 | /* für PowerISDN PCI */ | ||
33 | #define TJ_AMD_IRQ 0x20 | ||
34 | #define TJ_LED1 0x40 | ||
35 | #define TJ_LED2 0x80 | ||
36 | |||
37 | |||
38 | /* Das Fenster zum AMD... | ||
39 | * Ab Adresse hw.njet.base + TJ_AMD_PORT werden vom AMD jeweils 8 Bit in | ||
40 | * den TigerJet i/o-Raum gemappt | ||
41 | * -> 0x01 des AMD bei hw.njet.base + 0C4 */ | ||
42 | #define TJ_AMD_PORT 0xC0 | ||
43 | |||
44 | |||
45 | |||
46 | /* ***************************************************************************************** * | ||
47 | * *************************************** Prototypen ************************************** * | ||
48 | * ***************************************************************************************** */ | ||
49 | |||
50 | BYTE ReadByteAmd7930(struct IsdnCardState *cs, BYTE offset); | ||
51 | void WriteByteAmd7930(struct IsdnCardState *cs, BYTE offset, BYTE value); | ||
diff --git a/drivers/isdn/hisax/enternow_pci.c b/drivers/isdn/hisax/enternow_pci.c index 1cc4d11e007a..3341cf155531 100644 --- a/drivers/isdn/hisax/enternow_pci.c +++ b/drivers/isdn/hisax/enternow_pci.c | |||
@@ -65,7 +65,6 @@ | |||
65 | #include "isac.h" | 65 | #include "isac.h" |
66 | #include "isdnl1.h" | 66 | #include "isdnl1.h" |
67 | #include "amd7930_fn.h" | 67 | #include "amd7930_fn.h" |
68 | #include "enternow.h" | ||
69 | #include <linux/interrupt.h> | 68 | #include <linux/interrupt.h> |
70 | #include <linux/ppp_defs.h> | 69 | #include <linux/ppp_defs.h> |
71 | #include <linux/pci.h> | 70 | #include <linux/pci.h> |
@@ -74,58 +73,72 @@ | |||
74 | 73 | ||
75 | 74 | ||
76 | 75 | ||
77 | const char *enternow_pci_rev = "$Revision: 1.1.4.5 $"; | 76 | static const char *enternow_pci_rev = "$Revision: 1.1.4.5 $"; |
77 | |||
78 | |||
79 | /* für PowerISDN PCI */ | ||
80 | #define TJ_AMD_IRQ 0x20 | ||
81 | #define TJ_LED1 0x40 | ||
82 | #define TJ_LED2 0x80 | ||
83 | |||
84 | |||
85 | /* Das Fenster zum AMD... | ||
86 | * Ab Adresse hw.njet.base + TJ_AMD_PORT werden vom AMD jeweils 8 Bit in | ||
87 | * den TigerJet i/o-Raum gemappt | ||
88 | * -> 0x01 des AMD bei hw.njet.base + 0C4 */ | ||
89 | #define TJ_AMD_PORT 0xC0 | ||
90 | |||
78 | 91 | ||
79 | 92 | ||
80 | /* *************************** I/O-Interface functions ************************************* */ | 93 | /* *************************** I/O-Interface functions ************************************* */ |
81 | 94 | ||
82 | 95 | ||
83 | /* cs->readisac, macro rByteAMD */ | 96 | /* cs->readisac, macro rByteAMD */ |
84 | BYTE | 97 | static unsigned char |
85 | ReadByteAmd7930(struct IsdnCardState *cs, BYTE offset) | 98 | ReadByteAmd7930(struct IsdnCardState *cs, unsigned char offset) |
86 | { | 99 | { |
87 | /* direktes Register */ | 100 | /* direktes Register */ |
88 | if(offset < 8) | 101 | if(offset < 8) |
89 | return (InByte(cs->hw.njet.isac + 4*offset)); | 102 | return (inb(cs->hw.njet.isac + 4*offset)); |
90 | 103 | ||
91 | /* indirektes Register */ | 104 | /* indirektes Register */ |
92 | else { | 105 | else { |
93 | OutByte(cs->hw.njet.isac + 4*AMD_CR, offset); | 106 | outb(offset, cs->hw.njet.isac + 4*AMD_CR); |
94 | return(InByte(cs->hw.njet.isac + 4*AMD_DR)); | 107 | return(inb(cs->hw.njet.isac + 4*AMD_DR)); |
95 | } | 108 | } |
96 | } | 109 | } |
97 | 110 | ||
98 | /* cs->writeisac, macro wByteAMD */ | 111 | /* cs->writeisac, macro wByteAMD */ |
99 | void | 112 | static void |
100 | WriteByteAmd7930(struct IsdnCardState *cs, BYTE offset, BYTE value) | 113 | WriteByteAmd7930(struct IsdnCardState *cs, unsigned char offset, unsigned char value) |
101 | { | 114 | { |
102 | /* direktes Register */ | 115 | /* direktes Register */ |
103 | if(offset < 8) | 116 | if(offset < 8) |
104 | OutByte(cs->hw.njet.isac + 4*offset, value); | 117 | outb(value, cs->hw.njet.isac + 4*offset); |
105 | 118 | ||
106 | /* indirektes Register */ | 119 | /* indirektes Register */ |
107 | else { | 120 | else { |
108 | OutByte(cs->hw.njet.isac + 4*AMD_CR, offset); | 121 | outb(offset, cs->hw.njet.isac + 4*AMD_CR); |
109 | OutByte(cs->hw.njet.isac + 4*AMD_DR, value); | 122 | outb(value, cs->hw.njet.isac + 4*AMD_DR); |
110 | } | 123 | } |
111 | } | 124 | } |
112 | 125 | ||
113 | 126 | ||
114 | void | 127 | static void |
115 | enpci_setIrqMask(struct IsdnCardState *cs, BYTE val) { | 128 | enpci_setIrqMask(struct IsdnCardState *cs, unsigned char val) { |
116 | if (!val) | 129 | if (!val) |
117 | OutByte(cs->hw.njet.base+NETJET_IRQMASK1, 0x00); | 130 | outb(0x00, cs->hw.njet.base+NETJET_IRQMASK1); |
118 | else | 131 | else |
119 | OutByte(cs->hw.njet.base+NETJET_IRQMASK1, TJ_AMD_IRQ); | 132 | outb(TJ_AMD_IRQ, cs->hw.njet.base+NETJET_IRQMASK1); |
120 | } | 133 | } |
121 | 134 | ||
122 | 135 | ||
123 | static BYTE dummyrr(struct IsdnCardState *cs, int chan, BYTE off) | 136 | static unsigned char dummyrr(struct IsdnCardState *cs, int chan, unsigned char off) |
124 | { | 137 | { |
125 | return(5); | 138 | return(5); |
126 | } | 139 | } |
127 | 140 | ||
128 | static void dummywr(struct IsdnCardState *cs, int chan, BYTE off, BYTE value) | 141 | static void dummywr(struct IsdnCardState *cs, int chan, unsigned char off, unsigned char value) |
129 | { | 142 | { |
130 | 143 | ||
131 | } | 144 | } |
@@ -142,18 +155,18 @@ reset_enpci(struct IsdnCardState *cs) | |||
142 | 155 | ||
143 | /* Reset on, (also for AMD) */ | 156 | /* Reset on, (also for AMD) */ |
144 | cs->hw.njet.ctrl_reg = 0x07; | 157 | cs->hw.njet.ctrl_reg = 0x07; |
145 | OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); | 158 | outb(cs->hw.njet.ctrl_reg, cs->hw.njet.base + NETJET_CTRL); |
146 | mdelay(20); | 159 | mdelay(20); |
147 | /* Reset off */ | 160 | /* Reset off */ |
148 | cs->hw.njet.ctrl_reg = 0x30; | 161 | cs->hw.njet.ctrl_reg = 0x30; |
149 | OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); | 162 | outb(cs->hw.njet.ctrl_reg, cs->hw.njet.base + NETJET_CTRL); |
150 | /* 20ms delay */ | 163 | /* 20ms delay */ |
151 | mdelay(20); | 164 | mdelay(20); |
152 | cs->hw.njet.auxd = 0; // LED-status | 165 | cs->hw.njet.auxd = 0; // LED-status |
153 | cs->hw.njet.dmactrl = 0; | 166 | cs->hw.njet.dmactrl = 0; |
154 | OutByte(cs->hw.njet.base + NETJET_AUXCTRL, ~TJ_AMD_IRQ); | 167 | outb(~TJ_AMD_IRQ, cs->hw.njet.base + NETJET_AUXCTRL); |
155 | OutByte(cs->hw.njet.base + NETJET_IRQMASK1, TJ_AMD_IRQ); | 168 | outb(TJ_AMD_IRQ, cs->hw.njet.base + NETJET_IRQMASK1); |
156 | OutByte(cs->hw.njet.auxa, cs->hw.njet.auxd); // LED off | 169 | outb(cs->hw.njet.auxd, cs->hw.njet.auxa); // LED off |
157 | } | 170 | } |
158 | 171 | ||
159 | 172 | ||
@@ -161,7 +174,7 @@ static int | |||
161 | enpci_card_msg(struct IsdnCardState *cs, int mt, void *arg) | 174 | enpci_card_msg(struct IsdnCardState *cs, int mt, void *arg) |
162 | { | 175 | { |
163 | u_long flags; | 176 | u_long flags; |
164 | BYTE *chan; | 177 | unsigned char *chan; |
165 | 178 | ||
166 | if (cs->debug & L1_DEB_ISAC) | 179 | if (cs->debug & L1_DEB_ISAC) |
167 | debugl1(cs, "enter:now PCI: card_msg: 0x%04X", mt); | 180 | debugl1(cs, "enter:now PCI: card_msg: 0x%04X", mt); |
@@ -187,16 +200,16 @@ enpci_card_msg(struct IsdnCardState *cs, int mt, void *arg) | |||
187 | case MDL_ASSIGN: | 200 | case MDL_ASSIGN: |
188 | /* TEI assigned, LED1 on */ | 201 | /* TEI assigned, LED1 on */ |
189 | cs->hw.njet.auxd = TJ_AMD_IRQ << 1; | 202 | cs->hw.njet.auxd = TJ_AMD_IRQ << 1; |
190 | OutByte(cs->hw.njet.base + NETJET_AUXDATA, cs->hw.njet.auxd); | 203 | outb(cs->hw.njet.auxd, cs->hw.njet.base + NETJET_AUXDATA); |
191 | break; | 204 | break; |
192 | case MDL_REMOVE: | 205 | case MDL_REMOVE: |
193 | /* TEI removed, LEDs off */ | 206 | /* TEI removed, LEDs off */ |
194 | cs->hw.njet.auxd = 0; | 207 | cs->hw.njet.auxd = 0; |
195 | OutByte(cs->hw.njet.base + NETJET_AUXDATA, 0x00); | 208 | outb(0x00, cs->hw.njet.base + NETJET_AUXDATA); |
196 | break; | 209 | break; |
197 | case MDL_BC_ASSIGN: | 210 | case MDL_BC_ASSIGN: |
198 | /* activate B-channel */ | 211 | /* activate B-channel */ |
199 | chan = (BYTE *)arg; | 212 | chan = (unsigned char *)arg; |
200 | 213 | ||
201 | if (cs->debug & L1_DEB_ISAC) | 214 | if (cs->debug & L1_DEB_ISAC) |
202 | debugl1(cs, "enter:now PCI: assign phys. BC %d in AMD LMR1", *chan); | 215 | debugl1(cs, "enter:now PCI: assign phys. BC %d in AMD LMR1", *chan); |
@@ -204,11 +217,11 @@ enpci_card_msg(struct IsdnCardState *cs, int mt, void *arg) | |||
204 | cs->dc.amd7930.ph_command(cs, (cs->dc.amd7930.lmr1 | (*chan + 1)), "MDL_BC_ASSIGN"); | 217 | cs->dc.amd7930.ph_command(cs, (cs->dc.amd7930.lmr1 | (*chan + 1)), "MDL_BC_ASSIGN"); |
205 | /* at least one b-channel in use, LED 2 on */ | 218 | /* at least one b-channel in use, LED 2 on */ |
206 | cs->hw.njet.auxd |= TJ_AMD_IRQ << 2; | 219 | cs->hw.njet.auxd |= TJ_AMD_IRQ << 2; |
207 | OutByte(cs->hw.njet.base + NETJET_AUXDATA, cs->hw.njet.auxd); | 220 | outb(cs->hw.njet.auxd, cs->hw.njet.base + NETJET_AUXDATA); |
208 | break; | 221 | break; |
209 | case MDL_BC_RELEASE: | 222 | case MDL_BC_RELEASE: |
210 | /* deactivate B-channel */ | 223 | /* deactivate B-channel */ |
211 | chan = (BYTE *)arg; | 224 | chan = (unsigned char *)arg; |
212 | 225 | ||
213 | if (cs->debug & L1_DEB_ISAC) | 226 | if (cs->debug & L1_DEB_ISAC) |
214 | debugl1(cs, "enter:now PCI: release phys. BC %d in Amd LMR1", *chan); | 227 | debugl1(cs, "enter:now PCI: release phys. BC %d in Amd LMR1", *chan); |
@@ -217,7 +230,7 @@ enpci_card_msg(struct IsdnCardState *cs, int mt, void *arg) | |||
217 | /* no b-channel active -> LED2 off */ | 230 | /* no b-channel active -> LED2 off */ |
218 | if (!(cs->dc.amd7930.lmr1 & 3)) { | 231 | if (!(cs->dc.amd7930.lmr1 & 3)) { |
219 | cs->hw.njet.auxd &= ~(TJ_AMD_IRQ << 2); | 232 | cs->hw.njet.auxd &= ~(TJ_AMD_IRQ << 2); |
220 | OutByte(cs->hw.njet.base + NETJET_AUXDATA, cs->hw.njet.auxd); | 233 | outb(cs->hw.njet.auxd, cs->hw.njet.base + NETJET_AUXDATA); |
221 | } | 234 | } |
222 | break; | 235 | break; |
223 | default: | 236 | default: |
@@ -231,11 +244,11 @@ static irqreturn_t | |||
231 | enpci_interrupt(int intno, void *dev_id, struct pt_regs *regs) | 244 | enpci_interrupt(int intno, void *dev_id, struct pt_regs *regs) |
232 | { | 245 | { |
233 | struct IsdnCardState *cs = dev_id; | 246 | struct IsdnCardState *cs = dev_id; |
234 | BYTE s0val, s1val, ir; | 247 | unsigned char s0val, s1val, ir; |
235 | u_long flags; | 248 | u_long flags; |
236 | 249 | ||
237 | spin_lock_irqsave(&cs->lock, flags); | 250 | spin_lock_irqsave(&cs->lock, flags); |
238 | s1val = InByte(cs->hw.njet.base + NETJET_IRQSTAT1); | 251 | s1val = inb(cs->hw.njet.base + NETJET_IRQSTAT1); |
239 | 252 | ||
240 | /* AMD threw an interrupt */ | 253 | /* AMD threw an interrupt */ |
241 | if (!(s1val & TJ_AMD_IRQ)) { | 254 | if (!(s1val & TJ_AMD_IRQ)) { |
@@ -245,13 +258,13 @@ enpci_interrupt(int intno, void *dev_id, struct pt_regs *regs) | |||
245 | s1val = 1; | 258 | s1val = 1; |
246 | } else | 259 | } else |
247 | s1val = 0; | 260 | s1val = 0; |
248 | s0val = InByte(cs->hw.njet.base + NETJET_IRQSTAT0); | 261 | s0val = inb(cs->hw.njet.base + NETJET_IRQSTAT0); |
249 | if ((s0val | s1val)==0) { // shared IRQ | 262 | if ((s0val | s1val)==0) { // shared IRQ |
250 | spin_unlock_irqrestore(&cs->lock, flags); | 263 | spin_unlock_irqrestore(&cs->lock, flags); |
251 | return IRQ_NONE; | 264 | return IRQ_NONE; |
252 | } | 265 | } |
253 | if (s0val) | 266 | if (s0val) |
254 | OutByte(cs->hw.njet.base + NETJET_IRQSTAT0, s0val); | 267 | outb(s0val, cs->hw.njet.base + NETJET_IRQSTAT0); |
255 | 268 | ||
256 | /* DMA-Interrupt: B-channel-stuff */ | 269 | /* DMA-Interrupt: B-channel-stuff */ |
257 | /* set bits in sval to indicate which page is free */ | 270 | /* set bits in sval to indicate which page is free */ |
@@ -342,20 +355,20 @@ setup_enternow_pci(struct IsdnCard *card) | |||
342 | 355 | ||
343 | /* Reset an */ | 356 | /* Reset an */ |
344 | cs->hw.njet.ctrl_reg = 0x07; // geändert von 0xff | 357 | cs->hw.njet.ctrl_reg = 0x07; // geändert von 0xff |
345 | OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); | 358 | outb(cs->hw.njet.ctrl_reg, cs->hw.njet.base + NETJET_CTRL); |
346 | /* 20 ms Pause */ | 359 | /* 20 ms Pause */ |
347 | mdelay(20); | 360 | mdelay(20); |
348 | 361 | ||
349 | cs->hw.njet.ctrl_reg = 0x30; /* Reset Off and status read clear */ | 362 | cs->hw.njet.ctrl_reg = 0x30; /* Reset Off and status read clear */ |
350 | OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); | 363 | outb(cs->hw.njet.ctrl_reg, cs->hw.njet.base + NETJET_CTRL); |
351 | mdelay(10); | 364 | mdelay(10); |
352 | 365 | ||
353 | cs->hw.njet.auxd = 0x00; // war 0xc0 | 366 | cs->hw.njet.auxd = 0x00; // war 0xc0 |
354 | cs->hw.njet.dmactrl = 0; | 367 | cs->hw.njet.dmactrl = 0; |
355 | 368 | ||
356 | OutByte(cs->hw.njet.base + NETJET_AUXCTRL, ~TJ_AMD_IRQ); | 369 | outb(~TJ_AMD_IRQ, cs->hw.njet.base + NETJET_AUXCTRL); |
357 | OutByte(cs->hw.njet.base + NETJET_IRQMASK1, TJ_AMD_IRQ); | 370 | outb(TJ_AMD_IRQ, cs->hw.njet.base + NETJET_IRQMASK1); |
358 | OutByte(cs->hw.njet.auxa, cs->hw.njet.auxd); | 371 | outb(cs->hw.njet.auxd, cs->hw.njet.auxa); |
359 | 372 | ||
360 | break; | 373 | break; |
361 | } | 374 | } |
diff --git a/drivers/isdn/hisax/gazel.c b/drivers/isdn/hisax/gazel.c index 24a05a43f33e..352b45ac5347 100644 --- a/drivers/isdn/hisax/gazel.c +++ b/drivers/isdn/hisax/gazel.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
22 | 22 | ||
23 | extern const char *CardType[]; | 23 | extern const char *CardType[]; |
24 | const char *gazel_revision = "$Revision: 2.19.2.4 $"; | 24 | static const char *gazel_revision = "$Revision: 2.19.2.4 $"; |
25 | 25 | ||
26 | #define R647 1 | 26 | #define R647 1 |
27 | #define R685 2 | 27 | #define R685 2 |
@@ -317,7 +317,8 @@ gazel_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs) | |||
317 | spin_unlock_irqrestore(&cs->lock, flags); | 317 | spin_unlock_irqrestore(&cs->lock, flags); |
318 | return IRQ_HANDLED; | 318 | return IRQ_HANDLED; |
319 | } | 319 | } |
320 | void | 320 | |
321 | static void | ||
321 | release_io_gazel(struct IsdnCardState *cs) | 322 | release_io_gazel(struct IsdnCardState *cs) |
322 | { | 323 | { |
323 | unsigned int i; | 324 | unsigned int i; |
diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c index ba1d028343ec..6e7e060716b7 100644 --- a/drivers/isdn/hisax/hfc4s8s_l1.c +++ b/drivers/isdn/hisax/hfc4s8s_l1.c | |||
@@ -1358,7 +1358,7 @@ chipreset(hfc4s8s_hw * hw) | |||
1358 | /********************************************/ | 1358 | /********************************************/ |
1359 | /* disable/enable hardware in nt or te mode */ | 1359 | /* disable/enable hardware in nt or te mode */ |
1360 | /********************************************/ | 1360 | /********************************************/ |
1361 | void | 1361 | static void |
1362 | hfc_hardware_enable(hfc4s8s_hw * hw, int enable, int nt_mode) | 1362 | hfc_hardware_enable(hfc4s8s_hw * hw, int enable, int nt_mode) |
1363 | { | 1363 | { |
1364 | u_long flags; | 1364 | u_long flags; |
diff --git a/drivers/isdn/hisax/hfc_2bds0.c b/drivers/isdn/hisax/hfc_2bds0.c index ebea3feef003..7cf87793e790 100644 --- a/drivers/isdn/hisax/hfc_2bds0.c +++ b/drivers/isdn/hisax/hfc_2bds0.c | |||
@@ -345,7 +345,7 @@ hfc_send_data(struct BCState *bcs) | |||
345 | debugl1(cs,"send_data %d blocked", bcs->channel); | 345 | debugl1(cs,"send_data %d blocked", bcs->channel); |
346 | } | 346 | } |
347 | 347 | ||
348 | void | 348 | static void |
349 | main_rec_2bds0(struct BCState *bcs) | 349 | main_rec_2bds0(struct BCState *bcs) |
350 | { | 350 | { |
351 | struct IsdnCardState *cs = bcs->cs; | 351 | struct IsdnCardState *cs = bcs->cs; |
@@ -399,7 +399,7 @@ main_rec_2bds0(struct BCState *bcs) | |||
399 | return; | 399 | return; |
400 | } | 400 | } |
401 | 401 | ||
402 | void | 402 | static void |
403 | mode_2bs0(struct BCState *bcs, int mode, int bc) | 403 | mode_2bs0(struct BCState *bcs, int mode, int bc) |
404 | { | 404 | { |
405 | struct IsdnCardState *cs = bcs->cs; | 405 | struct IsdnCardState *cs = bcs->cs; |
@@ -505,7 +505,7 @@ hfc_l2l1(struct PStack *st, int pr, void *arg) | |||
505 | } | 505 | } |
506 | } | 506 | } |
507 | 507 | ||
508 | void | 508 | static void |
509 | close_2bs0(struct BCState *bcs) | 509 | close_2bs0(struct BCState *bcs) |
510 | { | 510 | { |
511 | mode_2bs0(bcs, 0, bcs->channel); | 511 | mode_2bs0(bcs, 0, bcs->channel); |
@@ -534,7 +534,7 @@ open_hfcstate(struct IsdnCardState *cs, struct BCState *bcs) | |||
534 | return (0); | 534 | return (0); |
535 | } | 535 | } |
536 | 536 | ||
537 | int | 537 | static int |
538 | setstack_2b(struct PStack *st, struct BCState *bcs) | 538 | setstack_2b(struct PStack *st, struct BCState *bcs) |
539 | { | 539 | { |
540 | bcs->channel = st->l1.bc; | 540 | bcs->channel = st->l1.bc; |
@@ -1004,7 +1004,7 @@ HFCD_l1hw(struct PStack *st, int pr, void *arg) | |||
1004 | } | 1004 | } |
1005 | } | 1005 | } |
1006 | 1006 | ||
1007 | void | 1007 | static void |
1008 | setstack_hfcd(struct PStack *st, struct IsdnCardState *cs) | 1008 | setstack_hfcd(struct PStack *st, struct IsdnCardState *cs) |
1009 | { | 1009 | { |
1010 | st->l1.l1hw = HFCD_l1hw; | 1010 | st->l1.l1hw = HFCD_l1hw; |
@@ -1015,7 +1015,7 @@ hfc_dbusy_timer(struct IsdnCardState *cs) | |||
1015 | { | 1015 | { |
1016 | } | 1016 | } |
1017 | 1017 | ||
1018 | unsigned int __init | 1018 | static unsigned int __init |
1019 | *init_send_hfcd(int cnt) | 1019 | *init_send_hfcd(int cnt) |
1020 | { | 1020 | { |
1021 | int i, *send; | 1021 | int i, *send; |
diff --git a/drivers/isdn/hisax/hfc_2bs0.c b/drivers/isdn/hisax/hfc_2bs0.c index bb376f39ac89..f978a5af8662 100644 --- a/drivers/isdn/hisax/hfc_2bs0.c +++ b/drivers/isdn/hisax/hfc_2bs0.c | |||
@@ -52,7 +52,7 @@ WaitNoBusy(struct IsdnCardState *cs) | |||
52 | return (to); | 52 | return (to); |
53 | } | 53 | } |
54 | 54 | ||
55 | int | 55 | static int |
56 | GetFreeFifoBytes(struct BCState *bcs) | 56 | GetFreeFifoBytes(struct BCState *bcs) |
57 | { | 57 | { |
58 | int s; | 58 | int s; |
@@ -66,7 +66,7 @@ GetFreeFifoBytes(struct BCState *bcs) | |||
66 | return (s); | 66 | return (s); |
67 | } | 67 | } |
68 | 68 | ||
69 | int | 69 | static int |
70 | ReadZReg(struct BCState *bcs, u_char reg) | 70 | ReadZReg(struct BCState *bcs, u_char reg) |
71 | { | 71 | { |
72 | int val; | 72 | int val; |
@@ -394,7 +394,7 @@ main_irq_hfc(struct BCState *bcs) | |||
394 | return; | 394 | return; |
395 | } | 395 | } |
396 | 396 | ||
397 | void | 397 | static void |
398 | mode_hfc(struct BCState *bcs, int mode, int bc) | 398 | mode_hfc(struct BCState *bcs, int mode, int bc) |
399 | { | 399 | { |
400 | struct IsdnCardState *cs = bcs->cs; | 400 | struct IsdnCardState *cs = bcs->cs; |
@@ -507,7 +507,7 @@ hfc_l2l1(struct PStack *st, int pr, void *arg) | |||
507 | } | 507 | } |
508 | 508 | ||
509 | 509 | ||
510 | void | 510 | static void |
511 | close_hfcstate(struct BCState *bcs) | 511 | close_hfcstate(struct BCState *bcs) |
512 | { | 512 | { |
513 | mode_hfc(bcs, 0, bcs->channel); | 513 | mode_hfc(bcs, 0, bcs->channel); |
@@ -537,7 +537,7 @@ open_hfcstate(struct IsdnCardState *cs, struct BCState *bcs) | |||
537 | return (0); | 537 | return (0); |
538 | } | 538 | } |
539 | 539 | ||
540 | int | 540 | static int |
541 | setstack_hfc(struct PStack *st, struct BCState *bcs) | 541 | setstack_hfc(struct PStack *st, struct BCState *bcs) |
542 | { | 542 | { |
543 | bcs->channel = st->l1.bc; | 543 | bcs->channel = st->l1.bc; |
@@ -551,7 +551,7 @@ setstack_hfc(struct PStack *st, struct BCState *bcs) | |||
551 | return (0); | 551 | return (0); |
552 | } | 552 | } |
553 | 553 | ||
554 | void __init | 554 | static void __init |
555 | init_send(struct BCState *bcs) | 555 | init_send(struct BCState *bcs) |
556 | { | 556 | { |
557 | int i; | 557 | int i; |
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c index c2db52696a86..8337b0f26cc4 100644 --- a/drivers/isdn/hisax/hfc_pci.c +++ b/drivers/isdn/hisax/hfc_pci.c | |||
@@ -70,7 +70,7 @@ static const PCI_ENTRY id_list[] = | |||
70 | /******************************************/ | 70 | /******************************************/ |
71 | /* free hardware resources used by driver */ | 71 | /* free hardware resources used by driver */ |
72 | /******************************************/ | 72 | /******************************************/ |
73 | void | 73 | static void |
74 | release_io_hfcpci(struct IsdnCardState *cs) | 74 | release_io_hfcpci(struct IsdnCardState *cs) |
75 | { | 75 | { |
76 | printk(KERN_INFO "HiSax: release hfcpci at %p\n", | 76 | printk(KERN_INFO "HiSax: release hfcpci at %p\n", |
@@ -394,7 +394,7 @@ receive_dmsg(struct IsdnCardState *cs) | |||
394 | /*******************************************************************************/ | 394 | /*******************************************************************************/ |
395 | /* check for transparent receive data and read max one threshold size if avail */ | 395 | /* check for transparent receive data and read max one threshold size if avail */ |
396 | /*******************************************************************************/ | 396 | /*******************************************************************************/ |
397 | int | 397 | static int |
398 | hfcpci_empty_fifo_trans(struct BCState *bcs, bzfifo_type * bz, u_char * bdata) | 398 | hfcpci_empty_fifo_trans(struct BCState *bcs, bzfifo_type * bz, u_char * bdata) |
399 | { | 399 | { |
400 | unsigned short *z1r, *z2r; | 400 | unsigned short *z1r, *z2r; |
@@ -446,7 +446,7 @@ hfcpci_empty_fifo_trans(struct BCState *bcs, bzfifo_type * bz, u_char * bdata) | |||
446 | /**********************************/ | 446 | /**********************************/ |
447 | /* B-channel main receive routine */ | 447 | /* B-channel main receive routine */ |
448 | /**********************************/ | 448 | /**********************************/ |
449 | void | 449 | static void |
450 | main_rec_hfcpci(struct BCState *bcs) | 450 | main_rec_hfcpci(struct BCState *bcs) |
451 | { | 451 | { |
452 | struct IsdnCardState *cs = bcs->cs; | 452 | struct IsdnCardState *cs = bcs->cs; |
@@ -1244,7 +1244,7 @@ HFCPCI_l1hw(struct PStack *st, int pr, void *arg) | |||
1244 | /***********************************************/ | 1244 | /***********************************************/ |
1245 | /* called during init setting l1 stack pointer */ | 1245 | /* called during init setting l1 stack pointer */ |
1246 | /***********************************************/ | 1246 | /***********************************************/ |
1247 | void | 1247 | static void |
1248 | setstack_hfcpci(struct PStack *st, struct IsdnCardState *cs) | 1248 | setstack_hfcpci(struct PStack *st, struct IsdnCardState *cs) |
1249 | { | 1249 | { |
1250 | st->l1.l1hw = HFCPCI_l1hw; | 1250 | st->l1.l1hw = HFCPCI_l1hw; |
@@ -1268,7 +1268,7 @@ hfcpci_send_data(struct BCState *bcs) | |||
1268 | /***************************************************************/ | 1268 | /***************************************************************/ |
1269 | /* activate/deactivate hardware for selected channels and mode */ | 1269 | /* activate/deactivate hardware for selected channels and mode */ |
1270 | /***************************************************************/ | 1270 | /***************************************************************/ |
1271 | void | 1271 | static void |
1272 | mode_hfcpci(struct BCState *bcs, int mode, int bc) | 1272 | mode_hfcpci(struct BCState *bcs, int mode, int bc) |
1273 | { | 1273 | { |
1274 | struct IsdnCardState *cs = bcs->cs; | 1274 | struct IsdnCardState *cs = bcs->cs; |
@@ -1579,7 +1579,7 @@ hfcpci_bh(struct IsdnCardState *cs) | |||
1579 | /********************************/ | 1579 | /********************************/ |
1580 | /* called for card init message */ | 1580 | /* called for card init message */ |
1581 | /********************************/ | 1581 | /********************************/ |
1582 | void __init | 1582 | static void __init |
1583 | inithfcpci(struct IsdnCardState *cs) | 1583 | inithfcpci(struct IsdnCardState *cs) |
1584 | { | 1584 | { |
1585 | cs->bcs[0].BC_SetStack = setstack_2b; | 1585 | cs->bcs[0].BC_SetStack = setstack_2b; |
diff --git a/drivers/isdn/hisax/hfc_pci.h b/drivers/isdn/hisax/hfc_pci.h index 4df036ed1af0..9ef2981e404e 100644 --- a/drivers/isdn/hisax/hfc_pci.h +++ b/drivers/isdn/hisax/hfc_pci.h | |||
@@ -232,5 +232,4 @@ typedef union { | |||
232 | #define Read_hfc(a,b) (*(((u_char *)a->hw.hfcpci.pci_io)+b)) | 232 | #define Read_hfc(a,b) (*(((u_char *)a->hw.hfcpci.pci_io)+b)) |
233 | 233 | ||
234 | extern void main_irq_hcpci(struct BCState *bcs); | 234 | extern void main_irq_hcpci(struct BCState *bcs); |
235 | extern void inithfcpci(struct IsdnCardState *cs); | ||
236 | extern void releasehfcpci(struct IsdnCardState *cs); | 235 | extern void releasehfcpci(struct IsdnCardState *cs); |
diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c index a307fcb6c634..f27c1608a3a7 100644 --- a/drivers/isdn/hisax/hfc_sx.c +++ b/drivers/isdn/hisax/hfc_sx.c | |||
@@ -308,7 +308,7 @@ read_fifo(struct IsdnCardState *cs, u_char fifo, int trans_max) | |||
308 | /******************************************/ | 308 | /******************************************/ |
309 | /* free hardware resources used by driver */ | 309 | /* free hardware resources used by driver */ |
310 | /******************************************/ | 310 | /******************************************/ |
311 | void | 311 | static void |
312 | release_io_hfcsx(struct IsdnCardState *cs) | 312 | release_io_hfcsx(struct IsdnCardState *cs) |
313 | { | 313 | { |
314 | cs->hw.hfcsx.int_m2 = 0; /* interrupt output off ! */ | 314 | cs->hw.hfcsx.int_m2 = 0; /* interrupt output off ! */ |
@@ -472,7 +472,7 @@ receive_dmsg(struct IsdnCardState *cs) | |||
472 | /**********************************/ | 472 | /**********************************/ |
473 | /* B-channel main receive routine */ | 473 | /* B-channel main receive routine */ |
474 | /**********************************/ | 474 | /**********************************/ |
475 | void | 475 | static void |
476 | main_rec_hfcsx(struct BCState *bcs) | 476 | main_rec_hfcsx(struct BCState *bcs) |
477 | { | 477 | { |
478 | struct IsdnCardState *cs = bcs->cs; | 478 | struct IsdnCardState *cs = bcs->cs; |
@@ -1003,7 +1003,7 @@ HFCSX_l1hw(struct PStack *st, int pr, void *arg) | |||
1003 | /***********************************************/ | 1003 | /***********************************************/ |
1004 | /* called during init setting l1 stack pointer */ | 1004 | /* called during init setting l1 stack pointer */ |
1005 | /***********************************************/ | 1005 | /***********************************************/ |
1006 | void | 1006 | static void |
1007 | setstack_hfcsx(struct PStack *st, struct IsdnCardState *cs) | 1007 | setstack_hfcsx(struct PStack *st, struct IsdnCardState *cs) |
1008 | { | 1008 | { |
1009 | st->l1.l1hw = HFCSX_l1hw; | 1009 | st->l1.l1hw = HFCSX_l1hw; |
@@ -1027,7 +1027,7 @@ hfcsx_send_data(struct BCState *bcs) | |||
1027 | /***************************************************************/ | 1027 | /***************************************************************/ |
1028 | /* activate/deactivate hardware for selected channels and mode */ | 1028 | /* activate/deactivate hardware for selected channels and mode */ |
1029 | /***************************************************************/ | 1029 | /***************************************************************/ |
1030 | void | 1030 | static void |
1031 | mode_hfcsx(struct BCState *bcs, int mode, int bc) | 1031 | mode_hfcsx(struct BCState *bcs, int mode, int bc) |
1032 | { | 1032 | { |
1033 | struct IsdnCardState *cs = bcs->cs; | 1033 | struct IsdnCardState *cs = bcs->cs; |
@@ -1328,7 +1328,7 @@ hfcsx_bh(struct IsdnCardState *cs) | |||
1328 | /********************************/ | 1328 | /********************************/ |
1329 | /* called for card init message */ | 1329 | /* called for card init message */ |
1330 | /********************************/ | 1330 | /********************************/ |
1331 | void __devinit | 1331 | static void __devinit |
1332 | inithfcsx(struct IsdnCardState *cs) | 1332 | inithfcsx(struct IsdnCardState *cs) |
1333 | { | 1333 | { |
1334 | cs->setstack_d = setstack_hfcsx; | 1334 | cs->setstack_d = setstack_hfcsx; |
diff --git a/drivers/isdn/hisax/hfc_sx.h b/drivers/isdn/hisax/hfc_sx.h index 12f54159344a..6792f13dc220 100644 --- a/drivers/isdn/hisax/hfc_sx.h +++ b/drivers/isdn/hisax/hfc_sx.h | |||
@@ -193,5 +193,4 @@ struct hfcsx_extra { | |||
193 | }; | 193 | }; |
194 | 194 | ||
195 | extern void main_irq_hfcsx(struct BCState *bcs); | 195 | extern void main_irq_hfcsx(struct BCState *bcs); |
196 | extern void inithfcsx(struct IsdnCardState *cs); | ||
197 | extern void releasehfcsx(struct IsdnCardState *cs); | 196 | extern void releasehfcsx(struct IsdnCardState *cs); |
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c index ffd74b84f502..e2c3af49d72b 100644 --- a/drivers/isdn/hisax/hfc_usb.c +++ b/drivers/isdn/hisax/hfc_usb.c | |||
@@ -60,7 +60,7 @@ static const char *hfcusb_revision = | |||
60 | #include "hisax_debug.h" | 60 | #include "hisax_debug.h" |
61 | static u_int debug; | 61 | static u_int debug; |
62 | module_param(debug, uint, 0); | 62 | module_param(debug, uint, 0); |
63 | int hfc_debug; | 63 | static int hfc_debug; |
64 | #endif | 64 | #endif |
65 | 65 | ||
66 | 66 | ||
@@ -85,7 +85,7 @@ static struct usb_device_id hfc_usb_idtab[] = { | |||
85 | * VendorID, ProductID, Devicename, LED_SCHEME, | 85 | * VendorID, ProductID, Devicename, LED_SCHEME, |
86 | * LED's BitMask in HFCUSB_P_DATA Register : LED_USB, LED_S0, LED_B1, LED_B2 | 86 | * LED's BitMask in HFCUSB_P_DATA Register : LED_USB, LED_S0, LED_B1, LED_B2 |
87 | */ | 87 | */ |
88 | vendor_data vdata[] = { | 88 | static vendor_data vdata[] = { |
89 | /* CologneChip Eval TA */ | 89 | /* CologneChip Eval TA */ |
90 | {0x0959, 0x2bd0, "ISDN USB TA (Cologne Chip HFC-S USB based)", | 90 | {0x0959, 0x2bd0, "ISDN USB TA (Cologne Chip HFC-S USB based)", |
91 | LED_OFF, {4, 0, 2, 1} | 91 | LED_OFF, {4, 0, 2, 1} |
@@ -1137,7 +1137,7 @@ set_hfcmode(hfcusb_data * hfc, int channel, int mode) | |||
1137 | } | 1137 | } |
1138 | } | 1138 | } |
1139 | 1139 | ||
1140 | void | 1140 | static void |
1141 | hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) | 1141 | hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) |
1142 | { | 1142 | { |
1143 | usb_fifo *fifo = my_hisax_if->priv; | 1143 | usb_fifo *fifo = my_hisax_if->priv; |
diff --git a/drivers/isdn/hisax/hfc_usb.h b/drivers/isdn/hisax/hfc_usb.h index b171600cf641..280dd29b30d6 100644 --- a/drivers/isdn/hisax/hfc_usb.h +++ b/drivers/isdn/hisax/hfc_usb.h | |||
@@ -168,7 +168,7 @@ static struct hfcusb_symbolic_list urb_errlist[] = { | |||
168 | * 3 entries are the configuration number, the minimum interval for | 168 | * 3 entries are the configuration number, the minimum interval for |
169 | * Interrupt endpoints & boolean if E-channel logging possible | 169 | * Interrupt endpoints & boolean if E-channel logging possible |
170 | */ | 170 | */ |
171 | int validconf[][19] = { | 171 | static int validconf[][19] = { |
172 | // INT in, ISO out config | 172 | // INT in, ISO out config |
173 | {EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NOP, EP_INT, | 173 | {EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NOP, EP_INT, |
174 | EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_NUL, EP_NUL, | 174 | EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_NUL, EP_NUL, |
@@ -187,7 +187,7 @@ int validconf[][19] = { | |||
187 | }; | 187 | }; |
188 | 188 | ||
189 | // string description of chosen config | 189 | // string description of chosen config |
190 | char *conf_str[] = { | 190 | static char *conf_str[] = { |
191 | "4 Interrupt IN + 3 Isochron OUT", | 191 | "4 Interrupt IN + 3 Isochron OUT", |
192 | "3 Interrupt IN + 3 Isochron OUT", | 192 | "3 Interrupt IN + 3 Isochron OUT", |
193 | "4 Isochron IN + 3 Isochron OUT", | 193 | "4 Isochron IN + 3 Isochron OUT", |
diff --git a/drivers/isdn/hisax/hfcscard.c b/drivers/isdn/hisax/hfcscard.c index 6fc55fea1702..86ab1c13f6b1 100644 --- a/drivers/isdn/hisax/hfcscard.c +++ b/drivers/isdn/hisax/hfcscard.c | |||
@@ -52,7 +52,7 @@ hfcs_Timer(struct IsdnCardState *cs) | |||
52 | */ | 52 | */ |
53 | } | 53 | } |
54 | 54 | ||
55 | void | 55 | static void |
56 | release_io_hfcs(struct IsdnCardState *cs) | 56 | release_io_hfcs(struct IsdnCardState *cs) |
57 | { | 57 | { |
58 | release2bds0(cs); | 58 | release2bds0(cs); |
diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h index dc5791728d53..17cf7663c582 100644 --- a/drivers/isdn/hisax/hisax.h +++ b/drivers/isdn/hisax/hisax.h | |||
@@ -1271,7 +1271,6 @@ extern void Logl2Frame(struct IsdnCardState *cs, struct sk_buff *skb, char *buf, | |||
1271 | void init_bcstate(struct IsdnCardState *cs, int bc); | 1271 | void init_bcstate(struct IsdnCardState *cs, int bc); |
1272 | 1272 | ||
1273 | void setstack_HiSax(struct PStack *st, struct IsdnCardState *cs); | 1273 | void setstack_HiSax(struct PStack *st, struct IsdnCardState *cs); |
1274 | unsigned int random_ri(void); | ||
1275 | void HiSax_addlist(struct IsdnCardState *sp, struct PStack *st); | 1274 | void HiSax_addlist(struct IsdnCardState *sp, struct PStack *st); |
1276 | void HiSax_rmlist(struct IsdnCardState *sp, struct PStack *st); | 1275 | void HiSax_rmlist(struct IsdnCardState *sp, struct PStack *st); |
1277 | 1276 | ||
@@ -1315,15 +1314,11 @@ int QuickHex(char *txt, u_char * p, int cnt); | |||
1315 | void LogFrame(struct IsdnCardState *cs, u_char * p, int size); | 1314 | void LogFrame(struct IsdnCardState *cs, u_char * p, int size); |
1316 | void dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir); | 1315 | void dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir); |
1317 | void iecpy(u_char * dest, u_char * iestart, int ieoffset); | 1316 | void iecpy(u_char * dest, u_char * iestart, int ieoffset); |
1318 | #ifdef ISDN_CHIP_ISAC | ||
1319 | void setstack_isac(struct PStack *st, struct IsdnCardState *cs); | ||
1320 | #endif /* ISDN_CHIP_ISAC */ | ||
1321 | #endif /* __KERNEL__ */ | 1317 | #endif /* __KERNEL__ */ |
1322 | 1318 | ||
1323 | #define HZDELAY(jiffs) {int tout = jiffs; while (tout--) udelay(1000000/HZ);} | 1319 | #define HZDELAY(jiffs) {int tout = jiffs; while (tout--) udelay(1000000/HZ);} |
1324 | 1320 | ||
1325 | int ll_run(struct IsdnCardState *cs, int addfeatures); | 1321 | int ll_run(struct IsdnCardState *cs, int addfeatures); |
1326 | void ll_stop(struct IsdnCardState *cs); | ||
1327 | int CallcNew(void); | 1322 | int CallcNew(void); |
1328 | void CallcFree(void); | 1323 | void CallcFree(void); |
1329 | int CallcNewChan(struct IsdnCardState *cs); | 1324 | int CallcNewChan(struct IsdnCardState *cs); |
diff --git a/drivers/isdn/hisax/hscx.c b/drivers/isdn/hisax/hscx.c index 5bbbe3e95125..66dbaee77bfb 100644 --- a/drivers/isdn/hisax/hscx.c +++ b/drivers/isdn/hisax/hscx.c | |||
@@ -151,7 +151,7 @@ hscx_l2l1(struct PStack *st, int pr, void *arg) | |||
151 | } | 151 | } |
152 | } | 152 | } |
153 | 153 | ||
154 | void | 154 | static void |
155 | close_hscxstate(struct BCState *bcs) | 155 | close_hscxstate(struct BCState *bcs) |
156 | { | 156 | { |
157 | modehscx(bcs, 0, bcs->channel); | 157 | modehscx(bcs, 0, bcs->channel); |
@@ -203,7 +203,7 @@ open_hscxstate(struct IsdnCardState *cs, struct BCState *bcs) | |||
203 | return (0); | 203 | return (0); |
204 | } | 204 | } |
205 | 205 | ||
206 | int | 206 | static int |
207 | setstack_hscx(struct PStack *st, struct BCState *bcs) | 207 | setstack_hscx(struct PStack *st, struct BCState *bcs) |
208 | { | 208 | { |
209 | bcs->channel = st->l1.bc; | 209 | bcs->channel = st->l1.bc; |
diff --git a/drivers/isdn/hisax/icc.c b/drivers/isdn/hisax/icc.c index dcf31f83c600..b4ca5859b177 100644 --- a/drivers/isdn/hisax/icc.c +++ b/drivers/isdn/hisax/icc.c | |||
@@ -108,7 +108,7 @@ icc_bh(struct IsdnCardState *cs) | |||
108 | #endif | 108 | #endif |
109 | } | 109 | } |
110 | 110 | ||
111 | void | 111 | static void |
112 | icc_empty_fifo(struct IsdnCardState *cs, int count) | 112 | icc_empty_fifo(struct IsdnCardState *cs, int count) |
113 | { | 113 | { |
114 | u_char *ptr; | 114 | u_char *ptr; |
@@ -563,13 +563,13 @@ ICC_l1hw(struct PStack *st, int pr, void *arg) | |||
563 | } | 563 | } |
564 | } | 564 | } |
565 | 565 | ||
566 | void | 566 | static void |
567 | setstack_icc(struct PStack *st, struct IsdnCardState *cs) | 567 | setstack_icc(struct PStack *st, struct IsdnCardState *cs) |
568 | { | 568 | { |
569 | st->l1.l1hw = ICC_l1hw; | 569 | st->l1.l1hw = ICC_l1hw; |
570 | } | 570 | } |
571 | 571 | ||
572 | void | 572 | static void |
573 | DC_Close_icc(struct IsdnCardState *cs) { | 573 | DC_Close_icc(struct IsdnCardState *cs) { |
574 | if (cs->dc.icc.mon_rx) { | 574 | if (cs->dc.icc.mon_rx) { |
575 | kfree(cs->dc.icc.mon_rx); | 575 | kfree(cs->dc.icc.mon_rx); |
diff --git a/drivers/isdn/hisax/ipacx.c b/drivers/isdn/hisax/ipacx.c index 6485e232d869..efba2f448017 100644 --- a/drivers/isdn/hisax/ipacx.c +++ b/drivers/isdn/hisax/ipacx.c | |||
@@ -36,8 +36,6 @@ static void ph_command(struct IsdnCardState *cs, unsigned int command); | |||
36 | static inline void cic_int(struct IsdnCardState *cs); | 36 | static inline void cic_int(struct IsdnCardState *cs); |
37 | static void dch_l2l1(struct PStack *st, int pr, void *arg); | 37 | static void dch_l2l1(struct PStack *st, int pr, void *arg); |
38 | static void dbusy_timer_handler(struct IsdnCardState *cs); | 38 | static void dbusy_timer_handler(struct IsdnCardState *cs); |
39 | static void ipacx_new_ph(struct IsdnCardState *cs); | ||
40 | static void dch_bh(struct IsdnCardState *cs); | ||
41 | static void dch_empty_fifo(struct IsdnCardState *cs, int count); | 39 | static void dch_empty_fifo(struct IsdnCardState *cs, int count); |
42 | static void dch_fill_fifo(struct IsdnCardState *cs); | 40 | static void dch_fill_fifo(struct IsdnCardState *cs); |
43 | static inline void dch_int(struct IsdnCardState *cs); | 41 | static inline void dch_int(struct IsdnCardState *cs); |
@@ -232,81 +230,6 @@ dbusy_timer_handler(struct IsdnCardState *cs) | |||
232 | } | 230 | } |
233 | 231 | ||
234 | //---------------------------------------------------------- | 232 | //---------------------------------------------------------- |
235 | // L1 state machine intermediate layer to isdnl1 module | ||
236 | //---------------------------------------------------------- | ||
237 | static void | ||
238 | ipacx_new_ph(struct IsdnCardState *cs) | ||
239 | { | ||
240 | switch (cs->dc.isac.ph_state) { | ||
241 | case (IPACX_IND_RES): | ||
242 | ph_command(cs, IPACX_CMD_DI); | ||
243 | l1_msg(cs, HW_RESET | INDICATION, NULL); | ||
244 | break; | ||
245 | |||
246 | case (IPACX_IND_DC): | ||
247 | l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL); | ||
248 | break; | ||
249 | |||
250 | case (IPACX_IND_DR): | ||
251 | l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL); | ||
252 | break; | ||
253 | |||
254 | case (IPACX_IND_PU): | ||
255 | l1_msg(cs, HW_POWERUP | CONFIRM, NULL); | ||
256 | break; | ||
257 | |||
258 | case (IPACX_IND_RSY): | ||
259 | l1_msg(cs, HW_RSYNC | INDICATION, NULL); | ||
260 | break; | ||
261 | |||
262 | case (IPACX_IND_AR): | ||
263 | l1_msg(cs, HW_INFO2 | INDICATION, NULL); | ||
264 | break; | ||
265 | |||
266 | case (IPACX_IND_AI8): | ||
267 | l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL); | ||
268 | break; | ||
269 | |||
270 | case (IPACX_IND_AI10): | ||
271 | l1_msg(cs, HW_INFO4_P10 | INDICATION, NULL); | ||
272 | break; | ||
273 | |||
274 | default: | ||
275 | break; | ||
276 | } | ||
277 | } | ||
278 | |||
279 | //---------------------------------------------------------- | ||
280 | // bottom half handler for D channel | ||
281 | //---------------------------------------------------------- | ||
282 | static void | ||
283 | dch_bh(struct IsdnCardState *cs) | ||
284 | { | ||
285 | struct PStack *st; | ||
286 | |||
287 | if (!cs) return; | ||
288 | |||
289 | if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) { | ||
290 | if (cs->debug) debugl1(cs, "D-Channel Busy cleared"); | ||
291 | for (st = cs->stlist; st; st = st->next) { | ||
292 | st->l1.l1l2(st, PH_PAUSE | CONFIRM, NULL); | ||
293 | } | ||
294 | } | ||
295 | |||
296 | if (test_and_clear_bit(D_RCVBUFREADY, &cs->event)) { | ||
297 | DChannel_proc_rcv(cs); | ||
298 | } | ||
299 | |||
300 | if (test_and_clear_bit(D_XMTBUFREADY, &cs->event)) { | ||
301 | DChannel_proc_xmt(cs); | ||
302 | } | ||
303 | |||
304 | if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) { | ||
305 | ipacx_new_ph(cs); | ||
306 | } | ||
307 | } | ||
308 | |||
309 | //---------------------------------------------------------- | ||
310 | // Fill buffer from receive FIFO | 233 | // Fill buffer from receive FIFO |
311 | //---------------------------------------------------------- | 234 | //---------------------------------------------------------- |
312 | static void | 235 | static void |
@@ -991,14 +914,5 @@ init_ipacx(struct IsdnCardState *cs, int part) | |||
991 | } | 914 | } |
992 | } | 915 | } |
993 | 916 | ||
994 | |||
995 | void __devinit | ||
996 | setup_ipacx(struct IsdnCardState *cs) | ||
997 | { | ||
998 | INIT_WORK(&cs->tqueue, (void *)(void *) dch_bh, cs); | ||
999 | cs->dbusytimer.function = (void *) dbusy_timer_handler; | ||
1000 | cs->dbusytimer.data = (long) cs; | ||
1001 | init_timer(&cs->dbusytimer); | ||
1002 | } | ||
1003 | //----------------- end of file ----------------------- | 917 | //----------------- end of file ----------------------- |
1004 | 918 | ||
diff --git a/drivers/isdn/hisax/isac.c b/drivers/isdn/hisax/isac.c index 20b949952952..85e063a08d23 100644 --- a/drivers/isdn/hisax/isac.c +++ b/drivers/isdn/hisax/isac.c | |||
@@ -112,7 +112,7 @@ isac_bh(struct IsdnCardState *cs) | |||
112 | #endif | 112 | #endif |
113 | } | 113 | } |
114 | 114 | ||
115 | void | 115 | static void |
116 | isac_empty_fifo(struct IsdnCardState *cs, int count) | 116 | isac_empty_fifo(struct IsdnCardState *cs, int count) |
117 | { | 117 | { |
118 | u_char *ptr; | 118 | u_char *ptr; |
@@ -563,13 +563,13 @@ ISAC_l1hw(struct PStack *st, int pr, void *arg) | |||
563 | } | 563 | } |
564 | } | 564 | } |
565 | 565 | ||
566 | void | 566 | static void |
567 | setstack_isac(struct PStack *st, struct IsdnCardState *cs) | 567 | setstack_isac(struct PStack *st, struct IsdnCardState *cs) |
568 | { | 568 | { |
569 | st->l1.l1hw = ISAC_l1hw; | 569 | st->l1.l1hw = ISAC_l1hw; |
570 | } | 570 | } |
571 | 571 | ||
572 | void | 572 | static void |
573 | DC_Close_isac(struct IsdnCardState *cs) { | 573 | DC_Close_isac(struct IsdnCardState *cs) { |
574 | if (cs->dc.isac.mon_rx) { | 574 | if (cs->dc.isac.mon_rx) { |
575 | kfree(cs->dc.isac.mon_rx); | 575 | kfree(cs->dc.isac.mon_rx); |
diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c index ee081321efb2..642a87c51295 100644 --- a/drivers/isdn/hisax/isar.c +++ b/drivers/isdn/hisax/isar.c | |||
@@ -21,13 +21,13 @@ | |||
21 | #define ETX 0x03 | 21 | #define ETX 0x03 |
22 | 22 | ||
23 | #define FAXMODCNT 13 | 23 | #define FAXMODCNT 13 |
24 | const u_char faxmodulation[] = {3,24,48,72,73,74,96,97,98,121,122,145,146}; | 24 | static const u_char faxmodulation[] = {3,24,48,72,73,74,96,97,98,121,122,145,146}; |
25 | static u_int modmask = 0x1fff; | 25 | static u_int modmask = 0x1fff; |
26 | static int frm_extra_delay = 2; | 26 | static int frm_extra_delay = 2; |
27 | static int para_TOA = 6; | 27 | static int para_TOA = 6; |
28 | const u_char *FC1_CMD[] = {"FAE", "FTS", "FRS", "FTM", "FRM", "FTH", "FRH", "CTRL" }; | 28 | static const u_char *FC1_CMD[] = {"FAE", "FTS", "FRS", "FTM", "FRM", "FTH", "FRH", "CTRL" }; |
29 | 29 | ||
30 | void isar_setup(struct IsdnCardState *cs); | 30 | static void isar_setup(struct IsdnCardState *cs); |
31 | static void isar_pump_cmd(struct BCState *bcs, u_char cmd, u_char para); | 31 | static void isar_pump_cmd(struct BCState *bcs, u_char cmd, u_char para); |
32 | static void ll_deliver_faxstat(struct BCState *bcs, u_char status); | 32 | static void ll_deliver_faxstat(struct BCState *bcs, u_char status); |
33 | 33 | ||
@@ -45,7 +45,7 @@ waitforHIA(struct IsdnCardState *cs, int timeout) | |||
45 | } | 45 | } |
46 | 46 | ||
47 | 47 | ||
48 | int | 48 | static int |
49 | sendmsg(struct IsdnCardState *cs, u_char his, u_char creg, u_char len, | 49 | sendmsg(struct IsdnCardState *cs, u_char his, u_char creg, u_char len, |
50 | u_char *msg) | 50 | u_char *msg) |
51 | { | 51 | { |
@@ -85,7 +85,7 @@ sendmsg(struct IsdnCardState *cs, u_char his, u_char creg, u_char len, | |||
85 | } | 85 | } |
86 | 86 | ||
87 | /* Call only with IRQ disabled !!! */ | 87 | /* Call only with IRQ disabled !!! */ |
88 | inline void | 88 | static inline void |
89 | rcv_mbox(struct IsdnCardState *cs, struct isar_reg *ireg, u_char *msg) | 89 | rcv_mbox(struct IsdnCardState *cs, struct isar_reg *ireg, u_char *msg) |
90 | { | 90 | { |
91 | int i; | 91 | int i; |
@@ -114,7 +114,7 @@ rcv_mbox(struct IsdnCardState *cs, struct isar_reg *ireg, u_char *msg) | |||
114 | } | 114 | } |
115 | 115 | ||
116 | /* Call only with IRQ disabled !!! */ | 116 | /* Call only with IRQ disabled !!! */ |
117 | inline void | 117 | static inline void |
118 | get_irq_infos(struct IsdnCardState *cs, struct isar_reg *ireg) | 118 | get_irq_infos(struct IsdnCardState *cs, struct isar_reg *ireg) |
119 | { | 119 | { |
120 | ireg->iis = cs->BC_Read_Reg(cs, 1, ISAR_IIS); | 120 | ireg->iis = cs->BC_Read_Reg(cs, 1, ISAR_IIS); |
@@ -127,7 +127,7 @@ get_irq_infos(struct IsdnCardState *cs, struct isar_reg *ireg) | |||
127 | #endif | 127 | #endif |
128 | } | 128 | } |
129 | 129 | ||
130 | int | 130 | static int |
131 | waitrecmsg(struct IsdnCardState *cs, u_char *len, | 131 | waitrecmsg(struct IsdnCardState *cs, u_char *len, |
132 | u_char *msg, int maxdelay) | 132 | u_char *msg, int maxdelay) |
133 | { | 133 | { |
@@ -185,7 +185,7 @@ ISARVersion(struct IsdnCardState *cs, char *s) | |||
185 | return(ver); | 185 | return(ver); |
186 | } | 186 | } |
187 | 187 | ||
188 | int | 188 | static int |
189 | isar_load_firmware(struct IsdnCardState *cs, u_char __user *buf) | 189 | isar_load_firmware(struct IsdnCardState *cs, u_char __user *buf) |
190 | { | 190 | { |
191 | int ret, size, cnt, debug; | 191 | int ret, size, cnt, debug; |
@@ -739,7 +739,7 @@ isar_fill_fifo(struct BCState *bcs) | |||
739 | } | 739 | } |
740 | } | 740 | } |
741 | 741 | ||
742 | inline | 742 | static inline |
743 | struct BCState *sel_bcs_isar(struct IsdnCardState *cs, u_char dpath) | 743 | struct BCState *sel_bcs_isar(struct IsdnCardState *cs, u_char dpath) |
744 | { | 744 | { |
745 | if ((!dpath) || (dpath == 3)) | 745 | if ((!dpath) || (dpath == 3)) |
@@ -751,7 +751,7 @@ struct BCState *sel_bcs_isar(struct IsdnCardState *cs, u_char dpath) | |||
751 | return(NULL); | 751 | return(NULL); |
752 | } | 752 | } |
753 | 753 | ||
754 | void | 754 | static void |
755 | send_frames(struct BCState *bcs) | 755 | send_frames(struct BCState *bcs) |
756 | { | 756 | { |
757 | if (bcs->tx_skb) { | 757 | if (bcs->tx_skb) { |
@@ -806,7 +806,7 @@ send_frames(struct BCState *bcs) | |||
806 | } | 806 | } |
807 | } | 807 | } |
808 | 808 | ||
809 | inline void | 809 | static inline void |
810 | check_send(struct IsdnCardState *cs, u_char rdm) | 810 | check_send(struct IsdnCardState *cs, u_char rdm) |
811 | { | 811 | { |
812 | struct BCState *bcs; | 812 | struct BCState *bcs; |
@@ -828,11 +828,13 @@ check_send(struct IsdnCardState *cs, u_char rdm) | |||
828 | 828 | ||
829 | } | 829 | } |
830 | 830 | ||
831 | const char *dmril[] = {"NO SPEED", "1200/75", "NODEF2", "75/1200", "NODEF4", | 831 | static const char *dmril[] = {"NO SPEED", "1200/75", "NODEF2", "75/1200", |
832 | "300", "600", "1200", "2400", "4800", "7200", | 832 | "NODEF4", "300", "600", "1200", "2400", |
833 | "9600nt", "9600t", "12000", "14400", "WRONG"}; | 833 | "4800", "7200", "9600nt", "9600t", "12000", |
834 | const char *dmrim[] = {"NO MOD", "NO DEF", "V32/V32b", "V22", "V21", | 834 | "14400", "WRONG"}; |
835 | "Bell103", "V23", "Bell202", "V17", "V29", "V27ter"}; | 835 | static const char *dmrim[] = {"NO MOD", "NO DEF", "V32/V32b", "V22", "V21", |
836 | "Bell103", "V23", "Bell202", "V17", "V29", | ||
837 | "V27ter"}; | ||
836 | 838 | ||
837 | static void | 839 | static void |
838 | isar_pump_status_rsp(struct BCState *bcs, struct isar_reg *ireg) { | 840 | isar_pump_status_rsp(struct BCState *bcs, struct isar_reg *ireg) { |
@@ -1388,7 +1390,7 @@ setup_iom2(struct BCState *bcs) { | |||
1388 | udelay(1000); | 1390 | udelay(1000); |
1389 | } | 1391 | } |
1390 | 1392 | ||
1391 | int | 1393 | static int |
1392 | modeisar(struct BCState *bcs, int mode, int bc) | 1394 | modeisar(struct BCState *bcs, int mode, int bc) |
1393 | { | 1395 | { |
1394 | struct IsdnCardState *cs = bcs->cs; | 1396 | struct IsdnCardState *cs = bcs->cs; |
@@ -1562,7 +1564,7 @@ isar_pump_cmd(struct BCState *bcs, u_char cmd, u_char para) | |||
1562 | sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, ctrl, nom, &p1); | 1564 | sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, ctrl, nom, &p1); |
1563 | } | 1565 | } |
1564 | 1566 | ||
1565 | void | 1567 | static void |
1566 | isar_setup(struct IsdnCardState *cs) | 1568 | isar_setup(struct IsdnCardState *cs) |
1567 | { | 1569 | { |
1568 | u_char msg; | 1570 | u_char msg; |
@@ -1582,7 +1584,7 @@ isar_setup(struct IsdnCardState *cs) | |||
1582 | } | 1584 | } |
1583 | } | 1585 | } |
1584 | 1586 | ||
1585 | void | 1587 | static void |
1586 | isar_l2l1(struct PStack *st, int pr, void *arg) | 1588 | isar_l2l1(struct PStack *st, int pr, void *arg) |
1587 | { | 1589 | { |
1588 | struct BCState *bcs = st->l1.bcs; | 1590 | struct BCState *bcs = st->l1.bcs; |
@@ -1681,7 +1683,7 @@ isar_l2l1(struct PStack *st, int pr, void *arg) | |||
1681 | } | 1683 | } |
1682 | } | 1684 | } |
1683 | 1685 | ||
1684 | void | 1686 | static void |
1685 | close_isarstate(struct BCState *bcs) | 1687 | close_isarstate(struct BCState *bcs) |
1686 | { | 1688 | { |
1687 | modeisar(bcs, 0, bcs->channel); | 1689 | modeisar(bcs, 0, bcs->channel); |
@@ -1703,7 +1705,7 @@ close_isarstate(struct BCState *bcs) | |||
1703 | del_timer(&bcs->hw.isar.ftimer); | 1705 | del_timer(&bcs->hw.isar.ftimer); |
1704 | } | 1706 | } |
1705 | 1707 | ||
1706 | int | 1708 | static int |
1707 | open_isarstate(struct IsdnCardState *cs, struct BCState *bcs) | 1709 | open_isarstate(struct IsdnCardState *cs, struct BCState *bcs) |
1708 | { | 1710 | { |
1709 | if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { | 1711 | if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { |
@@ -1725,7 +1727,7 @@ open_isarstate(struct IsdnCardState *cs, struct BCState *bcs) | |||
1725 | return (0); | 1727 | return (0); |
1726 | } | 1728 | } |
1727 | 1729 | ||
1728 | int | 1730 | static int |
1729 | setstack_isar(struct PStack *st, struct BCState *bcs) | 1731 | setstack_isar(struct PStack *st, struct BCState *bcs) |
1730 | { | 1732 | { |
1731 | bcs->channel = st->l1.bc; | 1733 | bcs->channel = st->l1.bc; |
diff --git a/drivers/isdn/hisax/isdnl1.c b/drivers/isdn/hisax/isdnl1.c index 4d08d27f1499..ac899503a74f 100644 --- a/drivers/isdn/hisax/isdnl1.c +++ b/drivers/isdn/hisax/isdnl1.c | |||
@@ -151,7 +151,7 @@ l1m_debug(struct FsmInst *fi, char *fmt, ...) | |||
151 | va_end(args); | 151 | va_end(args); |
152 | } | 152 | } |
153 | 153 | ||
154 | void | 154 | static void |
155 | L1activated(struct IsdnCardState *cs) | 155 | L1activated(struct IsdnCardState *cs) |
156 | { | 156 | { |
157 | struct PStack *st; | 157 | struct PStack *st; |
@@ -166,7 +166,7 @@ L1activated(struct IsdnCardState *cs) | |||
166 | } | 166 | } |
167 | } | 167 | } |
168 | 168 | ||
169 | void | 169 | static void |
170 | L1deactivated(struct IsdnCardState *cs) | 170 | L1deactivated(struct IsdnCardState *cs) |
171 | { | 171 | { |
172 | struct PStack *st; | 172 | struct PStack *st; |
@@ -370,7 +370,7 @@ init_bcstate(struct IsdnCardState *cs, int bc) | |||
370 | 370 | ||
371 | #ifdef L2FRAME_DEBUG /* psa */ | 371 | #ifdef L2FRAME_DEBUG /* psa */ |
372 | 372 | ||
373 | char * | 373 | static char * |
374 | l2cmd(u_char cmd) | 374 | l2cmd(u_char cmd) |
375 | { | 375 | { |
376 | switch (cmd & ~0x10) { | 376 | switch (cmd & ~0x10) { |
@@ -404,7 +404,7 @@ l2cmd(u_char cmd) | |||
404 | 404 | ||
405 | static char tmpdeb[32]; | 405 | static char tmpdeb[32]; |
406 | 406 | ||
407 | char * | 407 | static char * |
408 | l2frames(u_char * ptr) | 408 | l2frames(u_char * ptr) |
409 | { | 409 | { |
410 | switch (ptr[2] & ~0x10) { | 410 | switch (ptr[2] & ~0x10) { |
diff --git a/drivers/isdn/hisax/isdnl2.c b/drivers/isdn/hisax/isdnl2.c index d311b5fbf895..9022583fd6a0 100644 --- a/drivers/isdn/hisax/isdnl2.c +++ b/drivers/isdn/hisax/isdnl2.c | |||
@@ -142,7 +142,7 @@ freewin1(struct Layer2 *l2) | |||
142 | return cnt; | 142 | return cnt; |
143 | } | 143 | } |
144 | 144 | ||
145 | inline void | 145 | static inline void |
146 | freewin(struct PStack *st) | 146 | freewin(struct PStack *st) |
147 | { | 147 | { |
148 | freewin1(&st->l2); | 148 | freewin1(&st->l2); |
@@ -157,7 +157,7 @@ ReleaseWin(struct Layer2 *l2) | |||
157 | printk(KERN_WARNING "isdl2 freed %d skbuffs in release\n", cnt); | 157 | printk(KERN_WARNING "isdl2 freed %d skbuffs in release\n", cnt); |
158 | } | 158 | } |
159 | 159 | ||
160 | inline unsigned int | 160 | static inline unsigned int |
161 | cansend(struct PStack *st) | 161 | cansend(struct PStack *st) |
162 | { | 162 | { |
163 | unsigned int p1; | 163 | unsigned int p1; |
@@ -169,7 +169,7 @@ cansend(struct PStack *st) | |||
169 | return ((p1 < st->l2.window) && !test_bit(FLG_PEER_BUSY, &st->l2.flag)); | 169 | return ((p1 < st->l2.window) && !test_bit(FLG_PEER_BUSY, &st->l2.flag)); |
170 | } | 170 | } |
171 | 171 | ||
172 | inline void | 172 | static inline void |
173 | clear_exception(struct Layer2 *l2) | 173 | clear_exception(struct Layer2 *l2) |
174 | { | 174 | { |
175 | test_and_clear_bit(FLG_ACK_PEND, &l2->flag); | 175 | test_and_clear_bit(FLG_ACK_PEND, &l2->flag); |
@@ -178,7 +178,7 @@ clear_exception(struct Layer2 *l2) | |||
178 | clear_peer_busy(l2); | 178 | clear_peer_busy(l2); |
179 | } | 179 | } |
180 | 180 | ||
181 | inline int | 181 | static inline int |
182 | l2headersize(struct Layer2 *l2, int ui) | 182 | l2headersize(struct Layer2 *l2, int ui) |
183 | { | 183 | { |
184 | return (((test_bit(FLG_MOD128, &l2->flag) && (!ui)) ? 2 : 1) + | 184 | return (((test_bit(FLG_MOD128, &l2->flag) && (!ui)) ? 2 : 1) + |
@@ -223,40 +223,31 @@ enqueue_super(struct PStack *st, | |||
223 | 223 | ||
224 | #define enqueue_ui(a, b) enqueue_super(a, b) | 224 | #define enqueue_ui(a, b) enqueue_super(a, b) |
225 | 225 | ||
226 | inline int | 226 | static inline int |
227 | IsUI(u_char * data) | 227 | IsUI(u_char * data) |
228 | { | 228 | { |
229 | return ((data[0] & 0xef) == UI); | 229 | return ((data[0] & 0xef) == UI); |
230 | } | 230 | } |
231 | 231 | ||
232 | inline int | 232 | static inline int |
233 | IsUA(u_char * data) | 233 | IsUA(u_char * data) |
234 | { | 234 | { |
235 | return ((data[0] & 0xef) == UA); | 235 | return ((data[0] & 0xef) == UA); |
236 | } | 236 | } |
237 | 237 | ||
238 | inline int | 238 | static inline int |
239 | IsDM(u_char * data) | 239 | IsDM(u_char * data) |
240 | { | 240 | { |
241 | return ((data[0] & 0xef) == DM); | 241 | return ((data[0] & 0xef) == DM); |
242 | } | 242 | } |
243 | 243 | ||
244 | inline int | 244 | static inline int |
245 | IsDISC(u_char * data) | 245 | IsDISC(u_char * data) |
246 | { | 246 | { |
247 | return ((data[0] & 0xef) == DISC); | 247 | return ((data[0] & 0xef) == DISC); |
248 | } | 248 | } |
249 | 249 | ||
250 | inline int | 250 | static inline int |
251 | IsRR(u_char * data, struct PStack *st) | ||
252 | { | ||
253 | if (test_bit(FLG_MOD128, &st->l2.flag)) | ||
254 | return (data[0] == RR); | ||
255 | else | ||
256 | return ((data[0] & 0xf) == 1); | ||
257 | } | ||
258 | |||
259 | inline int | ||
260 | IsSFrame(u_char * data, struct PStack *st) | 251 | IsSFrame(u_char * data, struct PStack *st) |
261 | { | 252 | { |
262 | register u_char d = *data; | 253 | register u_char d = *data; |
@@ -266,7 +257,7 @@ IsSFrame(u_char * data, struct PStack *st) | |||
266 | return(((d & 0xf3) == 1) && ((d & 0x0c) != 0x0c)); | 257 | return(((d & 0xf3) == 1) && ((d & 0x0c) != 0x0c)); |
267 | } | 258 | } |
268 | 259 | ||
269 | inline int | 260 | static inline int |
270 | IsSABME(u_char * data, struct PStack *st) | 261 | IsSABME(u_char * data, struct PStack *st) |
271 | { | 262 | { |
272 | u_char d = data[0] & ~0x10; | 263 | u_char d = data[0] & ~0x10; |
@@ -274,25 +265,25 @@ IsSABME(u_char * data, struct PStack *st) | |||
274 | return (test_bit(FLG_MOD128, &st->l2.flag) ? d == SABME : d == SABM); | 265 | return (test_bit(FLG_MOD128, &st->l2.flag) ? d == SABME : d == SABM); |
275 | } | 266 | } |
276 | 267 | ||
277 | inline int | 268 | static inline int |
278 | IsREJ(u_char * data, struct PStack *st) | 269 | IsREJ(u_char * data, struct PStack *st) |
279 | { | 270 | { |
280 | return (test_bit(FLG_MOD128, &st->l2.flag) ? data[0] == REJ : (data[0] & 0xf) == REJ); | 271 | return (test_bit(FLG_MOD128, &st->l2.flag) ? data[0] == REJ : (data[0] & 0xf) == REJ); |
281 | } | 272 | } |
282 | 273 | ||
283 | inline int | 274 | static inline int |
284 | IsFRMR(u_char * data) | 275 | IsFRMR(u_char * data) |
285 | { | 276 | { |
286 | return ((data[0] & 0xef) == FRMR); | 277 | return ((data[0] & 0xef) == FRMR); |
287 | } | 278 | } |
288 | 279 | ||
289 | inline int | 280 | static inline int |
290 | IsRNR(u_char * data, struct PStack *st) | 281 | IsRNR(u_char * data, struct PStack *st) |
291 | { | 282 | { |
292 | return (test_bit(FLG_MOD128, &st->l2.flag) ? data[0] == RNR : (data[0] & 0xf) == RNR); | 283 | return (test_bit(FLG_MOD128, &st->l2.flag) ? data[0] == RNR : (data[0] & 0xf) == RNR); |
293 | } | 284 | } |
294 | 285 | ||
295 | int | 286 | static int |
296 | iframe_error(struct PStack *st, struct sk_buff *skb) | 287 | iframe_error(struct PStack *st, struct sk_buff *skb) |
297 | { | 288 | { |
298 | int i = l2addrsize(&st->l2) + (test_bit(FLG_MOD128, &st->l2.flag) ? 2 : 1); | 289 | int i = l2addrsize(&st->l2) + (test_bit(FLG_MOD128, &st->l2.flag) ? 2 : 1); |
@@ -315,7 +306,7 @@ iframe_error(struct PStack *st, struct sk_buff *skb) | |||
315 | return 0; | 306 | return 0; |
316 | } | 307 | } |
317 | 308 | ||
318 | int | 309 | static int |
319 | super_error(struct PStack *st, struct sk_buff *skb) | 310 | super_error(struct PStack *st, struct sk_buff *skb) |
320 | { | 311 | { |
321 | if (skb->len != l2addrsize(&st->l2) + | 312 | if (skb->len != l2addrsize(&st->l2) + |
@@ -325,7 +316,7 @@ super_error(struct PStack *st, struct sk_buff *skb) | |||
325 | return 0; | 316 | return 0; |
326 | } | 317 | } |
327 | 318 | ||
328 | int | 319 | static int |
329 | unnum_error(struct PStack *st, struct sk_buff *skb, int wantrsp) | 320 | unnum_error(struct PStack *st, struct sk_buff *skb, int wantrsp) |
330 | { | 321 | { |
331 | int rsp = (*skb->data & 0x2) >> 1; | 322 | int rsp = (*skb->data & 0x2) >> 1; |
@@ -341,7 +332,7 @@ unnum_error(struct PStack *st, struct sk_buff *skb, int wantrsp) | |||
341 | return 0; | 332 | return 0; |
342 | } | 333 | } |
343 | 334 | ||
344 | int | 335 | static int |
345 | UI_error(struct PStack *st, struct sk_buff *skb) | 336 | UI_error(struct PStack *st, struct sk_buff *skb) |
346 | { | 337 | { |
347 | int rsp = *skb->data & 0x2; | 338 | int rsp = *skb->data & 0x2; |
@@ -357,7 +348,7 @@ UI_error(struct PStack *st, struct sk_buff *skb) | |||
357 | return 0; | 348 | return 0; |
358 | } | 349 | } |
359 | 350 | ||
360 | int | 351 | static int |
361 | FRMR_error(struct PStack *st, struct sk_buff *skb) | 352 | FRMR_error(struct PStack *st, struct sk_buff *skb) |
362 | { | 353 | { |
363 | int headers = l2addrsize(&st->l2) + 1; | 354 | int headers = l2addrsize(&st->l2) + 1; |
@@ -444,51 +435,44 @@ send_uframe(struct PStack *st, u_char cmd, u_char cr) | |||
444 | enqueue_super(st, skb); | 435 | enqueue_super(st, skb); |
445 | } | 436 | } |
446 | 437 | ||
447 | inline u_char | 438 | static inline u_char |
448 | get_PollFlag(struct PStack * st, struct sk_buff * skb) | 439 | get_PollFlag(struct PStack * st, struct sk_buff * skb) |
449 | { | 440 | { |
450 | return (skb->data[l2addrsize(&(st->l2))] & 0x10); | 441 | return (skb->data[l2addrsize(&(st->l2))] & 0x10); |
451 | } | 442 | } |
452 | 443 | ||
453 | inline void | 444 | static inline u_char |
454 | FreeSkb(struct sk_buff *skb) | ||
455 | { | ||
456 | dev_kfree_skb(skb); | ||
457 | } | ||
458 | |||
459 | |||
460 | inline u_char | ||
461 | get_PollFlagFree(struct PStack *st, struct sk_buff *skb) | 445 | get_PollFlagFree(struct PStack *st, struct sk_buff *skb) |
462 | { | 446 | { |
463 | u_char PF; | 447 | u_char PF; |
464 | 448 | ||
465 | PF = get_PollFlag(st, skb); | 449 | PF = get_PollFlag(st, skb); |
466 | FreeSkb(skb); | 450 | dev_kfree_skb(skb); |
467 | return (PF); | 451 | return (PF); |
468 | } | 452 | } |
469 | 453 | ||
470 | inline void | 454 | static inline void |
471 | start_t200(struct PStack *st, int i) | 455 | start_t200(struct PStack *st, int i) |
472 | { | 456 | { |
473 | FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, i); | 457 | FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, i); |
474 | test_and_set_bit(FLG_T200_RUN, &st->l2.flag); | 458 | test_and_set_bit(FLG_T200_RUN, &st->l2.flag); |
475 | } | 459 | } |
476 | 460 | ||
477 | inline void | 461 | static inline void |
478 | restart_t200(struct PStack *st, int i) | 462 | restart_t200(struct PStack *st, int i) |
479 | { | 463 | { |
480 | FsmRestartTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, i); | 464 | FsmRestartTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, i); |
481 | test_and_set_bit(FLG_T200_RUN, &st->l2.flag); | 465 | test_and_set_bit(FLG_T200_RUN, &st->l2.flag); |
482 | } | 466 | } |
483 | 467 | ||
484 | inline void | 468 | static inline void |
485 | stop_t200(struct PStack *st, int i) | 469 | stop_t200(struct PStack *st, int i) |
486 | { | 470 | { |
487 | if(test_and_clear_bit(FLG_T200_RUN, &st->l2.flag)) | 471 | if(test_and_clear_bit(FLG_T200_RUN, &st->l2.flag)) |
488 | FsmDelTimer(&st->l2.t200, i); | 472 | FsmDelTimer(&st->l2.t200, i); |
489 | } | 473 | } |
490 | 474 | ||
491 | inline void | 475 | static inline void |
492 | st5_dl_release_l2l3(struct PStack *st) | 476 | st5_dl_release_l2l3(struct PStack *st) |
493 | { | 477 | { |
494 | int pr; | 478 | int pr; |
@@ -501,7 +485,7 @@ st5_dl_release_l2l3(struct PStack *st) | |||
501 | st->l2.l2l3(st, pr, NULL); | 485 | st->l2.l2l3(st, pr, NULL); |
502 | } | 486 | } |
503 | 487 | ||
504 | inline void | 488 | static inline void |
505 | lapb_dl_release_l2l3(struct PStack *st, int f) | 489 | lapb_dl_release_l2l3(struct PStack *st, int f) |
506 | { | 490 | { |
507 | if (test_bit(FLG_LAPB, &st->l2.flag)) | 491 | if (test_bit(FLG_LAPB, &st->l2.flag)) |
@@ -802,7 +786,7 @@ l2_connected(struct FsmInst *fi, int event, void *arg) | |||
802 | l2_mdl_error_ua(fi, event, arg); | 786 | l2_mdl_error_ua(fi, event, arg); |
803 | return; | 787 | return; |
804 | } | 788 | } |
805 | FreeSkb(skb); | 789 | dev_kfree_skb(skb); |
806 | 790 | ||
807 | if (test_and_clear_bit(FLG_PEND_REL, &st->l2.flag)) | 791 | if (test_and_clear_bit(FLG_PEND_REL, &st->l2.flag)) |
808 | l2_disconnect(fi, event, arg); | 792 | l2_disconnect(fi, event, arg); |
@@ -840,7 +824,7 @@ l2_released(struct FsmInst *fi, int event, void *arg) | |||
840 | l2_mdl_error_ua(fi, event, arg); | 824 | l2_mdl_error_ua(fi, event, arg); |
841 | return; | 825 | return; |
842 | } | 826 | } |
843 | FreeSkb(skb); | 827 | dev_kfree_skb(skb); |
844 | 828 | ||
845 | stop_t200(st, 6); | 829 | stop_t200(st, 6); |
846 | lapb_dl_release_l2l3(st, CONFIRM); | 830 | lapb_dl_release_l2l3(st, CONFIRM); |
@@ -889,7 +873,7 @@ l2_st6_dm_release(struct FsmInst *fi, int event, void *arg) | |||
889 | } | 873 | } |
890 | } | 874 | } |
891 | 875 | ||
892 | inline void | 876 | static inline void |
893 | enquiry_cr(struct PStack *st, u_char typ, u_char cr, u_char pf) | 877 | enquiry_cr(struct PStack *st, u_char typ, u_char cr, u_char pf) |
894 | { | 878 | { |
895 | struct sk_buff *skb; | 879 | struct sk_buff *skb; |
@@ -912,7 +896,7 @@ enquiry_cr(struct PStack *st, u_char typ, u_char cr, u_char pf) | |||
912 | enqueue_super(st, skb); | 896 | enqueue_super(st, skb); |
913 | } | 897 | } |
914 | 898 | ||
915 | inline void | 899 | static inline void |
916 | enquiry_response(struct PStack *st) | 900 | enquiry_response(struct PStack *st) |
917 | { | 901 | { |
918 | if (test_bit(FLG_OWN_BUSY, &st->l2.flag)) | 902 | if (test_bit(FLG_OWN_BUSY, &st->l2.flag)) |
@@ -922,7 +906,7 @@ enquiry_response(struct PStack *st) | |||
922 | test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); | 906 | test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); |
923 | } | 907 | } |
924 | 908 | ||
925 | inline void | 909 | static inline void |
926 | transmit_enquiry(struct PStack *st) | 910 | transmit_enquiry(struct PStack *st) |
927 | { | 911 | { |
928 | if (test_bit(FLG_OWN_BUSY, &st->l2.flag)) | 912 | if (test_bit(FLG_OWN_BUSY, &st->l2.flag)) |
@@ -1004,7 +988,7 @@ l2_st7_got_super(struct FsmInst *fi, int event, void *arg) | |||
1004 | PollFlag = (skb->data[0] & 0x10); | 988 | PollFlag = (skb->data[0] & 0x10); |
1005 | nr = (skb->data[0] >> 5) & 0x7; | 989 | nr = (skb->data[0] >> 5) & 0x7; |
1006 | } | 990 | } |
1007 | FreeSkb(skb); | 991 | dev_kfree_skb(skb); |
1008 | 992 | ||
1009 | if (PollFlag) { | 993 | if (PollFlag) { |
1010 | if (rsp) | 994 | if (rsp) |
@@ -1047,7 +1031,7 @@ l2_feed_i_if_reest(struct FsmInst *fi, int event, void *arg) | |||
1047 | if (!test_bit(FLG_L3_INIT, &st->l2.flag)) | 1031 | if (!test_bit(FLG_L3_INIT, &st->l2.flag)) |
1048 | skb_queue_tail(&st->l2.i_queue, skb); | 1032 | skb_queue_tail(&st->l2.i_queue, skb); |
1049 | else | 1033 | else |
1050 | FreeSkb(skb); | 1034 | dev_kfree_skb(skb); |
1051 | } | 1035 | } |
1052 | 1036 | ||
1053 | static void | 1037 | static void |
@@ -1093,7 +1077,7 @@ l2_got_iframe(struct FsmInst *fi, int event, void *arg) | |||
1093 | nr = (skb->data[i] >> 5) & 0x7; | 1077 | nr = (skb->data[i] >> 5) & 0x7; |
1094 | } | 1078 | } |
1095 | if (test_bit(FLG_OWN_BUSY, &l2->flag)) { | 1079 | if (test_bit(FLG_OWN_BUSY, &l2->flag)) { |
1096 | FreeSkb(skb); | 1080 | dev_kfree_skb(skb); |
1097 | if(PollFlag) enquiry_response(st); | 1081 | if(PollFlag) enquiry_response(st); |
1098 | } else if (l2->vr == ns) { | 1082 | } else if (l2->vr == ns) { |
1099 | (l2->vr)++; | 1083 | (l2->vr)++; |
@@ -1111,7 +1095,7 @@ l2_got_iframe(struct FsmInst *fi, int event, void *arg) | |||
1111 | st->l2.l2l3(st, DL_DATA | INDICATION, skb); | 1095 | st->l2.l2l3(st, DL_DATA | INDICATION, skb); |
1112 | } else { | 1096 | } else { |
1113 | /* n(s)!=v(r) */ | 1097 | /* n(s)!=v(r) */ |
1114 | FreeSkb(skb); | 1098 | dev_kfree_skb(skb); |
1115 | if (test_and_set_bit(FLG_REJEXC, &l2->flag)) { | 1099 | if (test_and_set_bit(FLG_REJEXC, &l2->flag)) { |
1116 | if (PollFlag) | 1100 | if (PollFlag) |
1117 | enquiry_response(st); | 1101 | enquiry_response(st); |
@@ -1309,7 +1293,7 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg) | |||
1309 | skb = alloc_skb(oskb->len + i, GFP_ATOMIC); | 1293 | skb = alloc_skb(oskb->len + i, GFP_ATOMIC); |
1310 | memcpy(skb_put(skb, i), header, i); | 1294 | memcpy(skb_put(skb, i), header, i); |
1311 | memcpy(skb_put(skb, oskb->len), oskb->data, oskb->len); | 1295 | memcpy(skb_put(skb, oskb->len), oskb->data, oskb->len); |
1312 | FreeSkb(oskb); | 1296 | dev_kfree_skb(oskb); |
1313 | } | 1297 | } |
1314 | st->l2.l2l1(st, PH_PULL | INDICATION, skb); | 1298 | st->l2.l2l1(st, PH_PULL | INDICATION, skb); |
1315 | test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); | 1299 | test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); |
@@ -1349,7 +1333,7 @@ l2_st8_got_super(struct FsmInst *fi, int event, void *arg) | |||
1349 | PollFlag = (skb->data[0] & 0x10); | 1333 | PollFlag = (skb->data[0] & 0x10); |
1350 | nr = (skb->data[0] >> 5) & 0x7; | 1334 | nr = (skb->data[0] >> 5) & 0x7; |
1351 | } | 1335 | } |
1352 | FreeSkb(skb); | 1336 | dev_kfree_skb(skb); |
1353 | 1337 | ||
1354 | if (rsp && PollFlag) { | 1338 | if (rsp && PollFlag) { |
1355 | if (legalnr(st, nr)) { | 1339 | if (legalnr(st, nr)) { |
@@ -1391,7 +1375,7 @@ l2_got_FRMR(struct FsmInst *fi, int event, void *arg) | |||
1391 | establishlink(fi); | 1375 | establishlink(fi); |
1392 | test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); | 1376 | test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); |
1393 | } | 1377 | } |
1394 | FreeSkb(skb); | 1378 | dev_kfree_skb(skb); |
1395 | } | 1379 | } |
1396 | 1380 | ||
1397 | static void | 1381 | static void |
@@ -1655,7 +1639,7 @@ isdnl2_l1l2(struct PStack *st, int pr, void *arg) | |||
1655 | datap += len; | 1639 | datap += len; |
1656 | else { | 1640 | else { |
1657 | FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *) 'N'); | 1641 | FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *) 'N'); |
1658 | FreeSkb(skb); | 1642 | dev_kfree_skb(skb); |
1659 | return; | 1643 | return; |
1660 | } | 1644 | } |
1661 | if (!(*datap & 1)) { /* I-Frame */ | 1645 | if (!(*datap & 1)) { /* I-Frame */ |
@@ -1684,16 +1668,16 @@ isdnl2_l1l2(struct PStack *st, int pr, void *arg) | |||
1684 | ret = FsmEvent(&st->l2.l2m, EV_L2_FRMR, skb); | 1668 | ret = FsmEvent(&st->l2.l2m, EV_L2_FRMR, skb); |
1685 | } else { | 1669 | } else { |
1686 | FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *) 'L'); | 1670 | FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *) 'L'); |
1687 | FreeSkb(skb); | 1671 | dev_kfree_skb(skb); |
1688 | ret = 0; | 1672 | ret = 0; |
1689 | } | 1673 | } |
1690 | if(c) { | 1674 | if(c) { |
1691 | FreeSkb(skb); | 1675 | dev_kfree_skb(skb); |
1692 | FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *)(long)c); | 1676 | FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *)(long)c); |
1693 | ret = 0; | 1677 | ret = 0; |
1694 | } | 1678 | } |
1695 | if (ret) | 1679 | if (ret) |
1696 | FreeSkb(skb); | 1680 | dev_kfree_skb(skb); |
1697 | break; | 1681 | break; |
1698 | case (PH_PULL | CONFIRM): | 1682 | case (PH_PULL | CONFIRM): |
1699 | FsmEvent(&st->l2.l2m, EV_L2_ACK_PULL, arg); | 1683 | FsmEvent(&st->l2.l2m, EV_L2_ACK_PULL, arg); |
diff --git a/drivers/isdn/hisax/isdnl3.c b/drivers/isdn/hisax/isdnl3.c index f571b5d18e91..abcc9530eb34 100644 --- a/drivers/isdn/hisax/isdnl3.c +++ b/drivers/isdn/hisax/isdnl3.c | |||
@@ -390,7 +390,7 @@ setstack_l3dc(struct PStack *st, struct Channel *chanp) | |||
390 | } | 390 | } |
391 | } | 391 | } |
392 | 392 | ||
393 | void | 393 | static void |
394 | isdnl3_trans(struct PStack *st, int pr, void *arg) { | 394 | isdnl3_trans(struct PStack *st, int pr, void *arg) { |
395 | st->l3.l3l2(st, pr, arg); | 395 | st->l3.l3l2(st, pr, arg); |
396 | } | 396 | } |
diff --git a/drivers/isdn/hisax/isurf.c b/drivers/isdn/hisax/isurf.c index af5171da7345..33747afc984d 100644 --- a/drivers/isdn/hisax/isurf.c +++ b/drivers/isdn/hisax/isurf.c | |||
@@ -122,7 +122,7 @@ isurf_interrupt(int intno, void *dev_id, struct pt_regs *regs) | |||
122 | return IRQ_HANDLED; | 122 | return IRQ_HANDLED; |
123 | } | 123 | } |
124 | 124 | ||
125 | void | 125 | static void |
126 | release_io_isurf(struct IsdnCardState *cs) | 126 | release_io_isurf(struct IsdnCardState *cs) |
127 | { | 127 | { |
128 | release_region(cs->hw.isurf.reset, 1); | 128 | release_region(cs->hw.isurf.reset, 1); |
diff --git a/drivers/isdn/hisax/ix1_micro.c b/drivers/isdn/hisax/ix1_micro.c index b843b7509ae2..908a7e144421 100644 --- a/drivers/isdn/hisax/ix1_micro.c +++ b/drivers/isdn/hisax/ix1_micro.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include "isdnl1.h" | 25 | #include "isdnl1.h" |
26 | 26 | ||
27 | extern const char *CardType[]; | 27 | extern const char *CardType[]; |
28 | const char *ix1_revision = "$Revision: 2.12.2.4 $"; | 28 | static const char *ix1_revision = "$Revision: 2.12.2.4 $"; |
29 | 29 | ||
30 | #define byteout(addr,val) outb(val,addr) | 30 | #define byteout(addr,val) outb(val,addr) |
31 | #define bytein(addr) inb(addr) | 31 | #define bytein(addr) inb(addr) |
@@ -162,7 +162,7 @@ ix1micro_interrupt(int intno, void *dev_id, struct pt_regs *regs) | |||
162 | return IRQ_HANDLED; | 162 | return IRQ_HANDLED; |
163 | } | 163 | } |
164 | 164 | ||
165 | void | 165 | static void |
166 | release_io_ix1micro(struct IsdnCardState *cs) | 166 | release_io_ix1micro(struct IsdnCardState *cs) |
167 | { | 167 | { |
168 | if (cs->hw.ix1.cfg_reg) | 168 | if (cs->hw.ix1.cfg_reg) |
diff --git a/drivers/isdn/hisax/jade.c b/drivers/isdn/hisax/jade.c index f05d52757557..363ae3179bbd 100644 --- a/drivers/isdn/hisax/jade.c +++ b/drivers/isdn/hisax/jade.c | |||
@@ -74,7 +74,7 @@ jade_write_indirect(struct IsdnCardState *cs, u_char reg, u_char value) | |||
74 | 74 | ||
75 | 75 | ||
76 | 76 | ||
77 | void | 77 | static void |
78 | modejade(struct BCState *bcs, int mode, int bc) | 78 | modejade(struct BCState *bcs, int mode, int bc) |
79 | { | 79 | { |
80 | struct IsdnCardState *cs = bcs->cs; | 80 | struct IsdnCardState *cs = bcs->cs; |
@@ -190,7 +190,7 @@ jade_l2l1(struct PStack *st, int pr, void *arg) | |||
190 | } | 190 | } |
191 | } | 191 | } |
192 | 192 | ||
193 | void | 193 | static void |
194 | close_jadestate(struct BCState *bcs) | 194 | close_jadestate(struct BCState *bcs) |
195 | { | 195 | { |
196 | modejade(bcs, 0, bcs->channel); | 196 | modejade(bcs, 0, bcs->channel); |
@@ -243,7 +243,7 @@ open_jadestate(struct IsdnCardState *cs, struct BCState *bcs) | |||
243 | } | 243 | } |
244 | 244 | ||
245 | 245 | ||
246 | int | 246 | static int |
247 | setstack_jade(struct PStack *st, struct BCState *bcs) | 247 | setstack_jade(struct PStack *st, struct BCState *bcs) |
248 | { | 248 | { |
249 | bcs->channel = st->l1.bc; | 249 | bcs->channel = st->l1.bc; |
diff --git a/drivers/isdn/hisax/jade.h b/drivers/isdn/hisax/jade.h index fa2944485994..29055e1ee381 100644 --- a/drivers/isdn/hisax/jade.h +++ b/drivers/isdn/hisax/jade.h | |||
@@ -128,7 +128,6 @@ | |||
128 | #define jade_TXAUDIOCH2CFG 0x1A | 128 | #define jade_TXAUDIOCH2CFG 0x1A |
129 | 129 | ||
130 | extern int JadeVersion(struct IsdnCardState *cs, char *s); | 130 | extern int JadeVersion(struct IsdnCardState *cs, char *s); |
131 | extern void modejade(struct BCState *bcs, int mode, int bc); | ||
132 | extern void clear_pending_jade_ints(struct IsdnCardState *cs); | 131 | extern void clear_pending_jade_ints(struct IsdnCardState *cs); |
133 | extern void initjade(struct IsdnCardState *cs); | 132 | extern void initjade(struct IsdnCardState *cs); |
134 | 133 | ||
diff --git a/drivers/isdn/hisax/l3_1tr6.c b/drivers/isdn/hisax/l3_1tr6.c index d6c1c8f8329d..c5c36eeff261 100644 --- a/drivers/isdn/hisax/l3_1tr6.c +++ b/drivers/isdn/hisax/l3_1tr6.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include <linux/ctype.h> | 19 | #include <linux/ctype.h> |
20 | 20 | ||
21 | extern char *HiSax_getrev(const char *revision); | 21 | extern char *HiSax_getrev(const char *revision); |
22 | const char *l3_1tr6_revision = "$Revision: 2.15.2.3 $"; | 22 | static const char *l3_1tr6_revision = "$Revision: 2.15.2.3 $"; |
23 | 23 | ||
24 | #define MsgHead(ptr, cref, mty, dis) \ | 24 | #define MsgHead(ptr, cref, mty, dis) \ |
25 | *ptr++ = dis; \ | 25 | *ptr++ = dis; \ |
diff --git a/drivers/isdn/hisax/l3dss1.c b/drivers/isdn/hisax/l3dss1.c index ec92308c1efc..a6d2abdb478a 100644 --- a/drivers/isdn/hisax/l3dss1.c +++ b/drivers/isdn/hisax/l3dss1.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <linux/config.h> | 26 | #include <linux/config.h> |
27 | 27 | ||
28 | extern char *HiSax_getrev(const char *revision); | 28 | extern char *HiSax_getrev(const char *revision); |
29 | const char *dss1_revision = "$Revision: 2.32.2.3 $"; | 29 | static const char *dss1_revision = "$Revision: 2.32.2.3 $"; |
30 | 30 | ||
31 | #define EXT_BEARER_CAPS 1 | 31 | #define EXT_BEARER_CAPS 1 |
32 | 32 | ||
diff --git a/drivers/isdn/hisax/l3ni1.c b/drivers/isdn/hisax/l3ni1.c index 3ab3a54daac1..f7041d5ba64e 100644 --- a/drivers/isdn/hisax/l3ni1.c +++ b/drivers/isdn/hisax/l3ni1.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/ctype.h> | 24 | #include <linux/ctype.h> |
25 | 25 | ||
26 | extern char *HiSax_getrev(const char *revision); | 26 | extern char *HiSax_getrev(const char *revision); |
27 | const char *ni1_revision = "$Revision: 2.8.2.3 $"; | 27 | static const char *ni1_revision = "$Revision: 2.8.2.3 $"; |
28 | 28 | ||
29 | #define EXT_BEARER_CAPS 1 | 29 | #define EXT_BEARER_CAPS 1 |
30 | 30 | ||
@@ -2665,7 +2665,7 @@ static void l3ni1_spid_send( struct l3_process *pc, u_char pr, void *arg ) | |||
2665 | l3ni1_SendSpid( pc, pr, arg, 20 ); | 2665 | l3ni1_SendSpid( pc, pr, arg, 20 ); |
2666 | } | 2666 | } |
2667 | 2667 | ||
2668 | void l3ni1_spid_epid( struct l3_process *pc, u_char pr, void *arg ) | 2668 | static void l3ni1_spid_epid( struct l3_process *pc, u_char pr, void *arg ) |
2669 | { | 2669 | { |
2670 | struct sk_buff *skb = arg; | 2670 | struct sk_buff *skb = arg; |
2671 | 2671 | ||
diff --git a/drivers/isdn/hisax/mic.c b/drivers/isdn/hisax/mic.c index 3ac4484a4886..fe11f226b285 100644 --- a/drivers/isdn/hisax/mic.c +++ b/drivers/isdn/hisax/mic.c | |||
@@ -18,7 +18,7 @@ | |||
18 | 18 | ||
19 | extern const char *CardType[]; | 19 | extern const char *CardType[]; |
20 | 20 | ||
21 | const char *mic_revision = "$Revision: 1.12.2.4 $"; | 21 | static const char *mic_revision = "$Revision: 1.12.2.4 $"; |
22 | 22 | ||
23 | #define byteout(addr,val) outb(val,addr) | 23 | #define byteout(addr,val) outb(val,addr) |
24 | #define bytein(addr) inb(addr) | 24 | #define bytein(addr) inb(addr) |
@@ -157,7 +157,7 @@ mic_interrupt(int intno, void *dev_id, struct pt_regs *regs) | |||
157 | return IRQ_HANDLED; | 157 | return IRQ_HANDLED; |
158 | } | 158 | } |
159 | 159 | ||
160 | void | 160 | static void |
161 | release_io_mic(struct IsdnCardState *cs) | 161 | release_io_mic(struct IsdnCardState *cs) |
162 | { | 162 | { |
163 | int bytecnt = 8; | 163 | int bytecnt = 8; |
diff --git a/drivers/isdn/hisax/netjet.c b/drivers/isdn/hisax/netjet.c index fe61d26365d3..94da03c30c51 100644 --- a/drivers/isdn/hisax/netjet.c +++ b/drivers/isdn/hisax/netjet.c | |||
@@ -25,8 +25,6 @@ | |||
25 | #include <asm/io.h> | 25 | #include <asm/io.h> |
26 | #include "netjet.h" | 26 | #include "netjet.h" |
27 | 27 | ||
28 | const char *NETjet_revision = "$Revision: 1.29.2.4 $"; | ||
29 | |||
30 | /* Interface functions */ | 28 | /* Interface functions */ |
31 | 29 | ||
32 | u_char | 30 | u_char |
@@ -66,7 +64,7 @@ NETjet_WriteICfifo(struct IsdnCardState *cs, u_char *data, int size) | |||
66 | outsb(cs->hw.njet.isac, data, size); | 64 | outsb(cs->hw.njet.isac, data, size); |
67 | } | 65 | } |
68 | 66 | ||
69 | void fill_mem(struct BCState *bcs, u_int *pos, u_int cnt, int chan, u_char fill) | 67 | static void fill_mem(struct BCState *bcs, u_int *pos, u_int cnt, int chan, u_char fill) |
70 | { | 68 | { |
71 | u_int mask=0x000000ff, val = 0, *p=pos; | 69 | u_int mask=0x000000ff, val = 0, *p=pos; |
72 | u_int i; | 70 | u_int i; |
@@ -85,7 +83,7 @@ void fill_mem(struct BCState *bcs, u_int *pos, u_int cnt, int chan, u_char fill) | |||
85 | } | 83 | } |
86 | } | 84 | } |
87 | 85 | ||
88 | void | 86 | static void |
89 | mode_tiger(struct BCState *bcs, int mode, int bc) | 87 | mode_tiger(struct BCState *bcs, int mode, int bc) |
90 | { | 88 | { |
91 | struct IsdnCardState *cs = bcs->cs; | 89 | struct IsdnCardState *cs = bcs->cs; |
@@ -852,7 +850,7 @@ tiger_l2l1(struct PStack *st, int pr, void *arg) | |||
852 | } | 850 | } |
853 | 851 | ||
854 | 852 | ||
855 | void | 853 | static void |
856 | close_tigerstate(struct BCState *bcs) | 854 | close_tigerstate(struct BCState *bcs) |
857 | { | 855 | { |
858 | mode_tiger(bcs, 0, bcs->channel); | 856 | mode_tiger(bcs, 0, bcs->channel); |
@@ -900,7 +898,7 @@ open_tigerstate(struct IsdnCardState *cs, struct BCState *bcs) | |||
900 | return (0); | 898 | return (0); |
901 | } | 899 | } |
902 | 900 | ||
903 | int | 901 | static int |
904 | setstack_tiger(struct PStack *st, struct BCState *bcs) | 902 | setstack_tiger(struct PStack *st, struct BCState *bcs) |
905 | { | 903 | { |
906 | bcs->channel = st->l1.bc; | 904 | bcs->channel = st->l1.bc; |
@@ -966,7 +964,7 @@ inittiger(struct IsdnCardState *cs) | |||
966 | cs->bcs[1].BC_Close = close_tigerstate; | 964 | cs->bcs[1].BC_Close = close_tigerstate; |
967 | } | 965 | } |
968 | 966 | ||
969 | void | 967 | static void |
970 | releasetiger(struct IsdnCardState *cs) | 968 | releasetiger(struct IsdnCardState *cs) |
971 | { | 969 | { |
972 | if (cs->bcs[0].hw.tiger.send) { | 970 | if (cs->bcs[0].hw.tiger.send) { |
diff --git a/drivers/isdn/hisax/niccy.c b/drivers/isdn/hisax/niccy.c index cf77d8360975..68a2159cbd11 100644 --- a/drivers/isdn/hisax/niccy.c +++ b/drivers/isdn/hisax/niccy.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/isapnp.h> | 24 | #include <linux/isapnp.h> |
25 | 25 | ||
26 | extern const char *CardType[]; | 26 | extern const char *CardType[]; |
27 | const char *niccy_revision = "$Revision: 1.21.2.4 $"; | 27 | static const char *niccy_revision = "$Revision: 1.21.2.4 $"; |
28 | 28 | ||
29 | #define byteout(addr,val) outb(val,addr) | 29 | #define byteout(addr,val) outb(val,addr) |
30 | #define bytein(addr) inb(addr) | 30 | #define bytein(addr) inb(addr) |
@@ -178,7 +178,7 @@ niccy_interrupt(int intno, void *dev_id, struct pt_regs *regs) | |||
178 | return IRQ_HANDLED; | 178 | return IRQ_HANDLED; |
179 | } | 179 | } |
180 | 180 | ||
181 | void | 181 | static void |
182 | release_io_niccy(struct IsdnCardState *cs) | 182 | release_io_niccy(struct IsdnCardState *cs) |
183 | { | 183 | { |
184 | if (cs->subtyp == NICCY_PCI) { | 184 | if (cs->subtyp == NICCY_PCI) { |
diff --git a/drivers/isdn/hisax/nj_s.c b/drivers/isdn/hisax/nj_s.c index fd664697f821..a7d3cd3f36fd 100644 --- a/drivers/isdn/hisax/nj_s.c +++ b/drivers/isdn/hisax/nj_s.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <linux/ppp_defs.h> | 15 | #include <linux/ppp_defs.h> |
16 | #include "netjet.h" | 16 | #include "netjet.h" |
17 | 17 | ||
18 | const char *NETjet_S_revision = "$Revision: 2.13.2.4 $"; | 18 | static const char *NETjet_S_revision = "$Revision: 2.13.2.4 $"; |
19 | 19 | ||
20 | static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off) | 20 | static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off) |
21 | { | 21 | { |
diff --git a/drivers/isdn/hisax/nj_u.c b/drivers/isdn/hisax/nj_u.c index 3d6441e9633c..1ae7cac98a87 100644 --- a/drivers/isdn/hisax/nj_u.c +++ b/drivers/isdn/hisax/nj_u.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <linux/ppp_defs.h> | 15 | #include <linux/ppp_defs.h> |
16 | #include "netjet.h" | 16 | #include "netjet.h" |
17 | 17 | ||
18 | const char *NETjet_U_revision = "$Revision: 2.14.2.3 $"; | 18 | static const char *NETjet_U_revision = "$Revision: 2.14.2.3 $"; |
19 | 19 | ||
20 | static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off) | 20 | static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off) |
21 | { | 21 | { |
diff --git a/drivers/isdn/hisax/q931.c b/drivers/isdn/hisax/q931.c index 170fcd4a3984..abecabf8c271 100644 --- a/drivers/isdn/hisax/q931.c +++ b/drivers/isdn/hisax/q931.c | |||
@@ -516,7 +516,7 @@ struct MessageType cause_1tr6[] = | |||
516 | {CAUSE_UserInfoDiscarded, "User Info Discarded"} | 516 | {CAUSE_UserInfoDiscarded, "User Info Discarded"} |
517 | }; | 517 | }; |
518 | 518 | ||
519 | int cause_1tr6_len = (sizeof(cause_1tr6) / sizeof(struct MessageType)); | 519 | static int cause_1tr6_len = (sizeof(cause_1tr6) / sizeof(struct MessageType)); |
520 | 520 | ||
521 | static int | 521 | static int |
522 | prcause_1tr6(char *dest, u_char * p) | 522 | prcause_1tr6(char *dest, u_char * p) |
@@ -935,7 +935,7 @@ display(char *dest, u_char * p) | |||
935 | return (dp - dest); | 935 | return (dp - dest); |
936 | } | 936 | } |
937 | 937 | ||
938 | int | 938 | static int |
939 | prfacility(char *dest, u_char * p) | 939 | prfacility(char *dest, u_char * p) |
940 | { | 940 | { |
941 | char *dp = dest; | 941 | char *dp = dest; |
diff --git a/drivers/isdn/hisax/s0box.c b/drivers/isdn/hisax/s0box.c index f3c481384a4e..7b63085ea6e5 100644 --- a/drivers/isdn/hisax/s0box.c +++ b/drivers/isdn/hisax/s0box.c | |||
@@ -17,7 +17,7 @@ | |||
17 | #include "isdnl1.h" | 17 | #include "isdnl1.h" |
18 | 18 | ||
19 | extern const char *CardType[]; | 19 | extern const char *CardType[]; |
20 | const char *s0box_revision = "$Revision: 2.6.2.4 $"; | 20 | static const char *s0box_revision = "$Revision: 2.6.2.4 $"; |
21 | 21 | ||
22 | static inline void | 22 | static inline void |
23 | writereg(unsigned int padr, signed int addr, u_char off, u_char val) { | 23 | writereg(unsigned int padr, signed int addr, u_char off, u_char val) { |
@@ -183,7 +183,7 @@ s0box_interrupt(int intno, void *dev_id, struct pt_regs *regs) | |||
183 | return IRQ_HANDLED; | 183 | return IRQ_HANDLED; |
184 | } | 184 | } |
185 | 185 | ||
186 | void | 186 | static void |
187 | release_io_s0box(struct IsdnCardState *cs) | 187 | release_io_s0box(struct IsdnCardState *cs) |
188 | { | 188 | { |
189 | release_region(cs->hw.teles3.cfg_reg, 8); | 189 | release_region(cs->hw.teles3.cfg_reg, 8); |
diff --git a/drivers/isdn/hisax/saphir.c b/drivers/isdn/hisax/saphir.c index 9e6d3d686cce..821776e1561a 100644 --- a/drivers/isdn/hisax/saphir.c +++ b/drivers/isdn/hisax/saphir.c | |||
@@ -171,7 +171,7 @@ SaphirWatchDog(struct IsdnCardState *cs) | |||
171 | mod_timer(&cs->hw.saphir.timer, jiffies+1*HZ); | 171 | mod_timer(&cs->hw.saphir.timer, jiffies+1*HZ); |
172 | } | 172 | } |
173 | 173 | ||
174 | void | 174 | static void |
175 | release_io_saphir(struct IsdnCardState *cs) | 175 | release_io_saphir(struct IsdnCardState *cs) |
176 | { | 176 | { |
177 | byteout(cs->hw.saphir.cfg_reg + IRQ_REG, 0xff); | 177 | byteout(cs->hw.saphir.cfg_reg + IRQ_REG, 0xff); |
diff --git a/drivers/isdn/hisax/sedlbauer.c b/drivers/isdn/hisax/sedlbauer.c index 8390f1606853..8c044a6a7fe3 100644 --- a/drivers/isdn/hisax/sedlbauer.c +++ b/drivers/isdn/hisax/sedlbauer.c | |||
@@ -51,9 +51,9 @@ | |||
51 | 51 | ||
52 | extern const char *CardType[]; | 52 | extern const char *CardType[]; |
53 | 53 | ||
54 | const char *Sedlbauer_revision = "$Revision: 1.34.2.6 $"; | 54 | static const char *Sedlbauer_revision = "$Revision: 1.34.2.6 $"; |
55 | 55 | ||
56 | const char *Sedlbauer_Types[] = | 56 | static const char *Sedlbauer_Types[] = |
57 | {"None", "speed card/win", "speed star", "speed fax+", | 57 | {"None", "speed card/win", "speed star", "speed fax+", |
58 | "speed win II / ISDN PC/104", "speed star II", "speed pci", | 58 | "speed win II / ISDN PC/104", "speed star II", "speed pci", |
59 | "speed fax+ pyramid", "speed fax+ pci", "HST Saphir III"}; | 59 | "speed fax+ pyramid", "speed fax+ pci", "HST Saphir III"}; |
@@ -394,7 +394,7 @@ sedlbauer_interrupt_isar(int intno, void *dev_id, struct pt_regs *regs) | |||
394 | return IRQ_HANDLED; | 394 | return IRQ_HANDLED; |
395 | } | 395 | } |
396 | 396 | ||
397 | void | 397 | static void |
398 | release_io_sedlbauer(struct IsdnCardState *cs) | 398 | release_io_sedlbauer(struct IsdnCardState *cs) |
399 | { | 399 | { |
400 | int bytecnt = 8; | 400 | int bytecnt = 8; |
diff --git a/drivers/isdn/hisax/sportster.c b/drivers/isdn/hisax/sportster.c index 132840b750ce..cdf35dc564c4 100644 --- a/drivers/isdn/hisax/sportster.c +++ b/drivers/isdn/hisax/sportster.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include "isdnl1.h" | 19 | #include "isdnl1.h" |
20 | 20 | ||
21 | extern const char *CardType[]; | 21 | extern const char *CardType[]; |
22 | const char *sportster_revision = "$Revision: 1.16.2.4 $"; | 22 | static const char *sportster_revision = "$Revision: 1.16.2.4 $"; |
23 | 23 | ||
24 | #define byteout(addr,val) outb(val,addr) | 24 | #define byteout(addr,val) outb(val,addr) |
25 | #define bytein(addr) inb(addr) | 25 | #define bytein(addr) inb(addr) |
@@ -132,7 +132,7 @@ sportster_interrupt(int intno, void *dev_id, struct pt_regs *regs) | |||
132 | return IRQ_HANDLED; | 132 | return IRQ_HANDLED; |
133 | } | 133 | } |
134 | 134 | ||
135 | void | 135 | static void |
136 | release_io_sportster(struct IsdnCardState *cs) | 136 | release_io_sportster(struct IsdnCardState *cs) |
137 | { | 137 | { |
138 | int i, adr; | 138 | int i, adr; |
@@ -144,7 +144,7 @@ release_io_sportster(struct IsdnCardState *cs) | |||
144 | } | 144 | } |
145 | } | 145 | } |
146 | 146 | ||
147 | void | 147 | static void |
148 | reset_sportster(struct IsdnCardState *cs) | 148 | reset_sportster(struct IsdnCardState *cs) |
149 | { | 149 | { |
150 | cs->hw.spt.res_irq |= SPORTSTER_RESET; /* Reset On */ | 150 | cs->hw.spt.res_irq |= SPORTSTER_RESET; /* Reset On */ |
diff --git a/drivers/isdn/hisax/st5481.h b/drivers/isdn/hisax/st5481.h index e8177b017b1d..0fda5c89429b 100644 --- a/drivers/isdn/hisax/st5481.h +++ b/drivers/isdn/hisax/st5481.h | |||
@@ -450,12 +450,8 @@ int st5481_setup_isocpipes(struct urb* urb[2], struct usb_device *dev, | |||
450 | usb_complete_t complete, void *context); | 450 | usb_complete_t complete, void *context); |
451 | void st5481_release_isocpipes(struct urb* urb[2]); | 451 | void st5481_release_isocpipes(struct urb* urb[2]); |
452 | 452 | ||
453 | int st5481_isoc_flatten(struct urb *urb); | ||
454 | void st5481_usb_pipe_reset(struct st5481_adapter *adapter, | 453 | void st5481_usb_pipe_reset(struct st5481_adapter *adapter, |
455 | u_char pipe, ctrl_complete_t complete, void *context); | 454 | u_char pipe, ctrl_complete_t complete, void *context); |
456 | void st5481_usb_ctrl_msg(struct st5481_adapter *adapter, | ||
457 | u8 request, u8 requesttype, u16 value, u16 index, | ||
458 | ctrl_complete_t complete, void *context); | ||
459 | void st5481_usb_device_ctrl_msg(struct st5481_adapter *adapter, | 455 | void st5481_usb_device_ctrl_msg(struct st5481_adapter *adapter, |
460 | u8 request, u16 value, | 456 | u8 request, u16 value, |
461 | ctrl_complete_t complete, void *context); | 457 | ctrl_complete_t complete, void *context); |
diff --git a/drivers/isdn/hisax/st5481_hdlc.c b/drivers/isdn/hisax/st5481_hdlc.c deleted file mode 100644 index 680f42e9a993..000000000000 --- a/drivers/isdn/hisax/st5481_hdlc.c +++ /dev/null | |||
@@ -1,580 +0,0 @@ | |||
1 | /* | ||
2 | * Driver for ST5481 USB ISDN modem | ||
3 | * | ||
4 | * Author Frode Isaksen | ||
5 | * Copyright 2001 by Frode Isaksen <fisaksen@bewan.com> | ||
6 | * 2001 by Kai Germaschewski <kai.germaschewski@gmx.de> | ||
7 | * | ||
8 | * This software may be used and distributed according to the terms | ||
9 | * of the GNU General Public License, incorporated herein by reference. | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <linux/crc-ccitt.h> | ||
14 | #include "st5481_hdlc.h" | ||
15 | |||
16 | |||
17 | enum { | ||
18 | HDLC_FAST_IDLE,HDLC_GET_FLAG_B0,HDLC_GETFLAG_B1A6,HDLC_GETFLAG_B7, | ||
19 | HDLC_GET_DATA,HDLC_FAST_FLAG | ||
20 | }; | ||
21 | |||
22 | enum { | ||
23 | HDLC_SEND_DATA,HDLC_SEND_CRC1,HDLC_SEND_FAST_FLAG, | ||
24 | HDLC_SEND_FIRST_FLAG,HDLC_SEND_CRC2,HDLC_SEND_CLOSING_FLAG, | ||
25 | HDLC_SEND_IDLE1,HDLC_SEND_FAST_IDLE,HDLC_SENDFLAG_B0, | ||
26 | HDLC_SENDFLAG_B1A6,HDLC_SENDFLAG_B7,STOPPED | ||
27 | }; | ||
28 | |||
29 | void | ||
30 | hdlc_rcv_init(struct hdlc_vars *hdlc, int do_adapt56) | ||
31 | { | ||
32 | hdlc->bit_shift = 0; | ||
33 | hdlc->hdlc_bits1 = 0; | ||
34 | hdlc->data_bits = 0; | ||
35 | hdlc->ffbit_shift = 0; | ||
36 | hdlc->data_received = 0; | ||
37 | hdlc->state = HDLC_GET_DATA; | ||
38 | hdlc->do_adapt56 = do_adapt56; | ||
39 | hdlc->dchannel = 0; | ||
40 | hdlc->crc = 0; | ||
41 | hdlc->cbin = 0; | ||
42 | hdlc->shift_reg = 0; | ||
43 | hdlc->ffvalue = 0; | ||
44 | hdlc->dstpos = 0; | ||
45 | } | ||
46 | |||
47 | void | ||
48 | hdlc_out_init(struct hdlc_vars *hdlc, int is_d_channel, int do_adapt56) | ||
49 | { | ||
50 | hdlc->bit_shift = 0; | ||
51 | hdlc->hdlc_bits1 = 0; | ||
52 | hdlc->data_bits = 0; | ||
53 | hdlc->ffbit_shift = 0; | ||
54 | hdlc->data_received = 0; | ||
55 | hdlc->do_closing = 0; | ||
56 | hdlc->ffvalue = 0; | ||
57 | if (is_d_channel) { | ||
58 | hdlc->dchannel = 1; | ||
59 | hdlc->state = HDLC_SEND_FIRST_FLAG; | ||
60 | } else { | ||
61 | hdlc->dchannel = 0; | ||
62 | hdlc->state = HDLC_SEND_FAST_FLAG; | ||
63 | hdlc->ffvalue = 0x7e; | ||
64 | } | ||
65 | hdlc->cbin = 0x7e; | ||
66 | hdlc->bit_shift = 0; | ||
67 | if(do_adapt56){ | ||
68 | hdlc->do_adapt56 = 1; | ||
69 | hdlc->data_bits = 0; | ||
70 | hdlc->state = HDLC_SENDFLAG_B0; | ||
71 | } else { | ||
72 | hdlc->do_adapt56 = 0; | ||
73 | hdlc->data_bits = 8; | ||
74 | } | ||
75 | hdlc->shift_reg = 0; | ||
76 | } | ||
77 | |||
78 | /* | ||
79 | hdlc_decode - decodes HDLC frames from a transparent bit stream. | ||
80 | |||
81 | The source buffer is scanned for valid HDLC frames looking for | ||
82 | flags (01111110) to indicate the start of a frame. If the start of | ||
83 | the frame is found, the bit stuffing is removed (0 after 5 1's). | ||
84 | When a new flag is found, the complete frame has been received | ||
85 | and the CRC is checked. | ||
86 | If a valid frame is found, the function returns the frame length | ||
87 | excluding the CRC with the bit HDLC_END_OF_FRAME set. | ||
88 | If the beginning of a valid frame is found, the function returns | ||
89 | the length. | ||
90 | If a framing error is found (too many 1s and not a flag) the function | ||
91 | returns the length with the bit HDLC_FRAMING_ERROR set. | ||
92 | If a CRC error is found the function returns the length with the | ||
93 | bit HDLC_CRC_ERROR set. | ||
94 | If the frame length exceeds the destination buffer size, the function | ||
95 | returns the length with the bit HDLC_LENGTH_ERROR set. | ||
96 | |||
97 | src - source buffer | ||
98 | slen - source buffer length | ||
99 | count - number of bytes removed (decoded) from the source buffer | ||
100 | dst _ destination buffer | ||
101 | dsize - destination buffer size | ||
102 | returns - number of decoded bytes in the destination buffer and status | ||
103 | flag. | ||
104 | */ | ||
105 | int hdlc_decode(struct hdlc_vars *hdlc, const unsigned char *src, | ||
106 | int slen, int *count, unsigned char *dst, int dsize) | ||
107 | { | ||
108 | int status=0; | ||
109 | |||
110 | static const unsigned char fast_flag[]={ | ||
111 | 0x00,0x00,0x00,0x20,0x30,0x38,0x3c,0x3e,0x3f | ||
112 | }; | ||
113 | |||
114 | static const unsigned char fast_flag_value[]={ | ||
115 | 0x00,0x7e,0xfc,0xf9,0xf3,0xe7,0xcf,0x9f,0x3f | ||
116 | }; | ||
117 | |||
118 | static const unsigned char fast_abort[]={ | ||
119 | 0x00,0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff | ||
120 | }; | ||
121 | |||
122 | *count = slen; | ||
123 | |||
124 | while(slen > 0){ | ||
125 | if(hdlc->bit_shift==0){ | ||
126 | hdlc->cbin = *src++; | ||
127 | slen--; | ||
128 | hdlc->bit_shift = 8; | ||
129 | if(hdlc->do_adapt56){ | ||
130 | hdlc->bit_shift --; | ||
131 | } | ||
132 | } | ||
133 | |||
134 | switch(hdlc->state){ | ||
135 | case STOPPED: | ||
136 | return 0; | ||
137 | case HDLC_FAST_IDLE: | ||
138 | if(hdlc->cbin == 0xff){ | ||
139 | hdlc->bit_shift = 0; | ||
140 | break; | ||
141 | } | ||
142 | hdlc->state = HDLC_GET_FLAG_B0; | ||
143 | hdlc->hdlc_bits1 = 0; | ||
144 | hdlc->bit_shift = 8; | ||
145 | break; | ||
146 | case HDLC_GET_FLAG_B0: | ||
147 | if(!(hdlc->cbin & 0x80)) { | ||
148 | hdlc->state = HDLC_GETFLAG_B1A6; | ||
149 | hdlc->hdlc_bits1 = 0; | ||
150 | } else { | ||
151 | if(!hdlc->do_adapt56){ | ||
152 | if(++hdlc->hdlc_bits1 >=8 ) if(hdlc->bit_shift==1) | ||
153 | hdlc->state = HDLC_FAST_IDLE; | ||
154 | } | ||
155 | } | ||
156 | hdlc->cbin<<=1; | ||
157 | hdlc->bit_shift --; | ||
158 | break; | ||
159 | case HDLC_GETFLAG_B1A6: | ||
160 | if(hdlc->cbin & 0x80){ | ||
161 | hdlc->hdlc_bits1++; | ||
162 | if(hdlc->hdlc_bits1==6){ | ||
163 | hdlc->state = HDLC_GETFLAG_B7; | ||
164 | } | ||
165 | } else { | ||
166 | hdlc->hdlc_bits1 = 0; | ||
167 | } | ||
168 | hdlc->cbin<<=1; | ||
169 | hdlc->bit_shift --; | ||
170 | break; | ||
171 | case HDLC_GETFLAG_B7: | ||
172 | if(hdlc->cbin & 0x80) { | ||
173 | hdlc->state = HDLC_GET_FLAG_B0; | ||
174 | } else { | ||
175 | hdlc->state = HDLC_GET_DATA; | ||
176 | hdlc->crc = 0xffff; | ||
177 | hdlc->shift_reg = 0; | ||
178 | hdlc->hdlc_bits1 = 0; | ||
179 | hdlc->data_bits = 0; | ||
180 | hdlc->data_received = 0; | ||
181 | } | ||
182 | hdlc->cbin<<=1; | ||
183 | hdlc->bit_shift --; | ||
184 | break; | ||
185 | case HDLC_GET_DATA: | ||
186 | if(hdlc->cbin & 0x80){ | ||
187 | hdlc->hdlc_bits1++; | ||
188 | switch(hdlc->hdlc_bits1){ | ||
189 | case 6: | ||
190 | break; | ||
191 | case 7: | ||
192 | if(hdlc->data_received) { | ||
193 | // bad frame | ||
194 | status = -HDLC_FRAMING_ERROR; | ||
195 | } | ||
196 | if(!hdlc->do_adapt56){ | ||
197 | if(hdlc->cbin==fast_abort[hdlc->bit_shift+1]){ | ||
198 | hdlc->state = HDLC_FAST_IDLE; | ||
199 | hdlc->bit_shift=1; | ||
200 | break; | ||
201 | } | ||
202 | } else { | ||
203 | hdlc->state = HDLC_GET_FLAG_B0; | ||
204 | } | ||
205 | break; | ||
206 | default: | ||
207 | hdlc->shift_reg>>=1; | ||
208 | hdlc->shift_reg |= 0x80; | ||
209 | hdlc->data_bits++; | ||
210 | break; | ||
211 | } | ||
212 | } else { | ||
213 | switch(hdlc->hdlc_bits1){ | ||
214 | case 5: | ||
215 | break; | ||
216 | case 6: | ||
217 | if(hdlc->data_received){ | ||
218 | if (hdlc->dstpos < 2) { | ||
219 | status = -HDLC_FRAMING_ERROR; | ||
220 | } else if (hdlc->crc != 0xf0b8){ | ||
221 | // crc error | ||
222 | status = -HDLC_CRC_ERROR; | ||
223 | } else { | ||
224 | // remove CRC | ||
225 | hdlc->dstpos -= 2; | ||
226 | // good frame | ||
227 | status = hdlc->dstpos; | ||
228 | } | ||
229 | } | ||
230 | hdlc->crc = 0xffff; | ||
231 | hdlc->shift_reg = 0; | ||
232 | hdlc->data_bits = 0; | ||
233 | if(!hdlc->do_adapt56){ | ||
234 | if(hdlc->cbin==fast_flag[hdlc->bit_shift]){ | ||
235 | hdlc->ffvalue = fast_flag_value[hdlc->bit_shift]; | ||
236 | hdlc->state = HDLC_FAST_FLAG; | ||
237 | hdlc->ffbit_shift = hdlc->bit_shift; | ||
238 | hdlc->bit_shift = 1; | ||
239 | } else { | ||
240 | hdlc->state = HDLC_GET_DATA; | ||
241 | hdlc->data_received = 0; | ||
242 | } | ||
243 | } else { | ||
244 | hdlc->state = HDLC_GET_DATA; | ||
245 | hdlc->data_received = 0; | ||
246 | } | ||
247 | break; | ||
248 | default: | ||
249 | hdlc->shift_reg>>=1; | ||
250 | hdlc->data_bits++; | ||
251 | break; | ||
252 | } | ||
253 | hdlc->hdlc_bits1 = 0; | ||
254 | } | ||
255 | if (status) { | ||
256 | hdlc->dstpos = 0; | ||
257 | *count -= slen; | ||
258 | hdlc->cbin <<= 1; | ||
259 | hdlc->bit_shift--; | ||
260 | return status; | ||
261 | } | ||
262 | if(hdlc->data_bits==8){ | ||
263 | hdlc->data_bits = 0; | ||
264 | hdlc->data_received = 1; | ||
265 | hdlc->crc = crc_ccitt_byte(hdlc->crc, hdlc->shift_reg); | ||
266 | |||
267 | // good byte received | ||
268 | if (dsize--) { | ||
269 | dst[hdlc->dstpos++] = hdlc->shift_reg; | ||
270 | } else { | ||
271 | // frame too long | ||
272 | status = -HDLC_LENGTH_ERROR; | ||
273 | hdlc->dstpos = 0; | ||
274 | } | ||
275 | } | ||
276 | hdlc->cbin <<= 1; | ||
277 | hdlc->bit_shift--; | ||
278 | break; | ||
279 | case HDLC_FAST_FLAG: | ||
280 | if(hdlc->cbin==hdlc->ffvalue){ | ||
281 | hdlc->bit_shift = 0; | ||
282 | break; | ||
283 | } else { | ||
284 | if(hdlc->cbin == 0xff){ | ||
285 | hdlc->state = HDLC_FAST_IDLE; | ||
286 | hdlc->bit_shift=0; | ||
287 | } else if(hdlc->ffbit_shift==8){ | ||
288 | hdlc->state = HDLC_GETFLAG_B7; | ||
289 | break; | ||
290 | } else { | ||
291 | hdlc->shift_reg = fast_abort[hdlc->ffbit_shift-1]; | ||
292 | hdlc->hdlc_bits1 = hdlc->ffbit_shift-2; | ||
293 | if(hdlc->hdlc_bits1<0)hdlc->hdlc_bits1 = 0; | ||
294 | hdlc->data_bits = hdlc->ffbit_shift-1; | ||
295 | hdlc->state = HDLC_GET_DATA; | ||
296 | hdlc->data_received = 0; | ||
297 | } | ||
298 | } | ||
299 | break; | ||
300 | default: | ||
301 | break; | ||
302 | } | ||
303 | } | ||
304 | *count -= slen; | ||
305 | return 0; | ||
306 | } | ||
307 | |||
308 | /* | ||
309 | hdlc_encode - encodes HDLC frames to a transparent bit stream. | ||
310 | |||
311 | The bit stream starts with a beginning flag (01111110). After | ||
312 | that each byte is added to the bit stream with bit stuffing added | ||
313 | (0 after 5 1's). | ||
314 | When the last byte has been removed from the source buffer, the | ||
315 | CRC (2 bytes is added) and the frame terminates with the ending flag. | ||
316 | For the dchannel, the idle character (all 1's) is also added at the end. | ||
317 | If this function is called with empty source buffer (slen=0), flags or | ||
318 | idle character will be generated. | ||
319 | |||
320 | src - source buffer | ||
321 | slen - source buffer length | ||
322 | count - number of bytes removed (encoded) from source buffer | ||
323 | dst _ destination buffer | ||
324 | dsize - destination buffer size | ||
325 | returns - number of encoded bytes in the destination buffer | ||
326 | */ | ||
327 | int hdlc_encode(struct hdlc_vars *hdlc, const unsigned char *src, | ||
328 | unsigned short slen, int *count, | ||
329 | unsigned char *dst, int dsize) | ||
330 | { | ||
331 | static const unsigned char xfast_flag_value[] = { | ||
332 | 0x7e,0x3f,0x9f,0xcf,0xe7,0xf3,0xf9,0xfc,0x7e | ||
333 | }; | ||
334 | |||
335 | int len = 0; | ||
336 | |||
337 | *count = slen; | ||
338 | |||
339 | while (dsize > 0) { | ||
340 | if(hdlc->bit_shift==0){ | ||
341 | if(slen && !hdlc->do_closing){ | ||
342 | hdlc->shift_reg = *src++; | ||
343 | slen--; | ||
344 | if (slen == 0) | ||
345 | hdlc->do_closing = 1; /* closing sequence, CRC + flag(s) */ | ||
346 | hdlc->bit_shift = 8; | ||
347 | } else { | ||
348 | if(hdlc->state == HDLC_SEND_DATA){ | ||
349 | if(hdlc->data_received){ | ||
350 | hdlc->state = HDLC_SEND_CRC1; | ||
351 | hdlc->crc ^= 0xffff; | ||
352 | hdlc->bit_shift = 8; | ||
353 | hdlc->shift_reg = hdlc->crc & 0xff; | ||
354 | } else if(!hdlc->do_adapt56){ | ||
355 | hdlc->state = HDLC_SEND_FAST_FLAG; | ||
356 | } else { | ||
357 | hdlc->state = HDLC_SENDFLAG_B0; | ||
358 | } | ||
359 | } | ||
360 | |||
361 | } | ||
362 | } | ||
363 | |||
364 | switch(hdlc->state){ | ||
365 | case STOPPED: | ||
366 | while (dsize--) | ||
367 | *dst++ = 0xff; | ||
368 | |||
369 | return dsize; | ||
370 | case HDLC_SEND_FAST_FLAG: | ||
371 | hdlc->do_closing = 0; | ||
372 | if(slen == 0){ | ||
373 | *dst++ = hdlc->ffvalue; | ||
374 | len++; | ||
375 | dsize--; | ||
376 | break; | ||
377 | } | ||
378 | if(hdlc->bit_shift==8){ | ||
379 | hdlc->cbin = hdlc->ffvalue>>(8-hdlc->data_bits); | ||
380 | hdlc->state = HDLC_SEND_DATA; | ||
381 | hdlc->crc = 0xffff; | ||
382 | hdlc->hdlc_bits1 = 0; | ||
383 | hdlc->data_received = 1; | ||
384 | } | ||
385 | break; | ||
386 | case HDLC_SENDFLAG_B0: | ||
387 | hdlc->do_closing = 0; | ||
388 | hdlc->cbin <<= 1; | ||
389 | hdlc->data_bits++; | ||
390 | hdlc->hdlc_bits1 = 0; | ||
391 | hdlc->state = HDLC_SENDFLAG_B1A6; | ||
392 | break; | ||
393 | case HDLC_SENDFLAG_B1A6: | ||
394 | hdlc->cbin <<= 1; | ||
395 | hdlc->data_bits++; | ||
396 | hdlc->cbin++; | ||
397 | if(++hdlc->hdlc_bits1 == 6) | ||
398 | hdlc->state = HDLC_SENDFLAG_B7; | ||
399 | break; | ||
400 | case HDLC_SENDFLAG_B7: | ||
401 | hdlc->cbin <<= 1; | ||
402 | hdlc->data_bits++; | ||
403 | if(slen == 0){ | ||
404 | hdlc->state = HDLC_SENDFLAG_B0; | ||
405 | break; | ||
406 | } | ||
407 | if(hdlc->bit_shift==8){ | ||
408 | hdlc->state = HDLC_SEND_DATA; | ||
409 | hdlc->crc = 0xffff; | ||
410 | hdlc->hdlc_bits1 = 0; | ||
411 | hdlc->data_received = 1; | ||
412 | } | ||
413 | break; | ||
414 | case HDLC_SEND_FIRST_FLAG: | ||
415 | hdlc->data_received = 1; | ||
416 | if(hdlc->data_bits==8){ | ||
417 | hdlc->state = HDLC_SEND_DATA; | ||
418 | hdlc->crc = 0xffff; | ||
419 | hdlc->hdlc_bits1 = 0; | ||
420 | break; | ||
421 | } | ||
422 | hdlc->cbin <<= 1; | ||
423 | hdlc->data_bits++; | ||
424 | if(hdlc->shift_reg & 0x01) | ||
425 | hdlc->cbin++; | ||
426 | hdlc->shift_reg >>= 1; | ||
427 | hdlc->bit_shift--; | ||
428 | if(hdlc->bit_shift==0){ | ||
429 | hdlc->state = HDLC_SEND_DATA; | ||
430 | hdlc->crc = 0xffff; | ||
431 | hdlc->hdlc_bits1 = 0; | ||
432 | } | ||
433 | break; | ||
434 | case HDLC_SEND_DATA: | ||
435 | hdlc->cbin <<= 1; | ||
436 | hdlc->data_bits++; | ||
437 | if(hdlc->hdlc_bits1 == 5){ | ||
438 | hdlc->hdlc_bits1 = 0; | ||
439 | break; | ||
440 | } | ||
441 | if(hdlc->bit_shift==8){ | ||
442 | hdlc->crc = crc_ccitt_byte(hdlc->crc, hdlc->shift_reg); | ||
443 | } | ||
444 | if(hdlc->shift_reg & 0x01){ | ||
445 | hdlc->hdlc_bits1++; | ||
446 | hdlc->cbin++; | ||
447 | hdlc->shift_reg >>= 1; | ||
448 | hdlc->bit_shift--; | ||
449 | } else { | ||
450 | hdlc->hdlc_bits1 = 0; | ||
451 | hdlc->shift_reg >>= 1; | ||
452 | hdlc->bit_shift--; | ||
453 | } | ||
454 | break; | ||
455 | case HDLC_SEND_CRC1: | ||
456 | hdlc->cbin <<= 1; | ||
457 | hdlc->data_bits++; | ||
458 | if(hdlc->hdlc_bits1 == 5){ | ||
459 | hdlc->hdlc_bits1 = 0; | ||
460 | break; | ||
461 | } | ||
462 | if(hdlc->shift_reg & 0x01){ | ||
463 | hdlc->hdlc_bits1++; | ||
464 | hdlc->cbin++; | ||
465 | hdlc->shift_reg >>= 1; | ||
466 | hdlc->bit_shift--; | ||
467 | } else { | ||
468 | hdlc->hdlc_bits1 = 0; | ||
469 | hdlc->shift_reg >>= 1; | ||
470 | hdlc->bit_shift--; | ||
471 | } | ||
472 | if(hdlc->bit_shift==0){ | ||
473 | hdlc->shift_reg = (hdlc->crc >> 8); | ||
474 | hdlc->state = HDLC_SEND_CRC2; | ||
475 | hdlc->bit_shift = 8; | ||
476 | } | ||
477 | break; | ||
478 | case HDLC_SEND_CRC2: | ||
479 | hdlc->cbin <<= 1; | ||
480 | hdlc->data_bits++; | ||
481 | if(hdlc->hdlc_bits1 == 5){ | ||
482 | hdlc->hdlc_bits1 = 0; | ||
483 | break; | ||
484 | } | ||
485 | if(hdlc->shift_reg & 0x01){ | ||
486 | hdlc->hdlc_bits1++; | ||
487 | hdlc->cbin++; | ||
488 | hdlc->shift_reg >>= 1; | ||
489 | hdlc->bit_shift--; | ||
490 | } else { | ||
491 | hdlc->hdlc_bits1 = 0; | ||
492 | hdlc->shift_reg >>= 1; | ||
493 | hdlc->bit_shift--; | ||
494 | } | ||
495 | if(hdlc->bit_shift==0){ | ||
496 | hdlc->shift_reg = 0x7e; | ||
497 | hdlc->state = HDLC_SEND_CLOSING_FLAG; | ||
498 | hdlc->bit_shift = 8; | ||
499 | } | ||
500 | break; | ||
501 | case HDLC_SEND_CLOSING_FLAG: | ||
502 | hdlc->cbin <<= 1; | ||
503 | hdlc->data_bits++; | ||
504 | if(hdlc->hdlc_bits1 == 5){ | ||
505 | hdlc->hdlc_bits1 = 0; | ||
506 | break; | ||
507 | } | ||
508 | if(hdlc->shift_reg & 0x01){ | ||
509 | hdlc->cbin++; | ||
510 | } | ||
511 | hdlc->shift_reg >>= 1; | ||
512 | hdlc->bit_shift--; | ||
513 | if(hdlc->bit_shift==0){ | ||
514 | hdlc->ffvalue = xfast_flag_value[hdlc->data_bits]; | ||
515 | if(hdlc->dchannel){ | ||
516 | hdlc->ffvalue = 0x7e; | ||
517 | hdlc->state = HDLC_SEND_IDLE1; | ||
518 | hdlc->bit_shift = 8-hdlc->data_bits; | ||
519 | if(hdlc->bit_shift==0) | ||
520 | hdlc->state = HDLC_SEND_FAST_IDLE; | ||
521 | } else { | ||
522 | if(!hdlc->do_adapt56){ | ||
523 | hdlc->state = HDLC_SEND_FAST_FLAG; | ||
524 | hdlc->data_received = 0; | ||
525 | } else { | ||
526 | hdlc->state = HDLC_SENDFLAG_B0; | ||
527 | hdlc->data_received = 0; | ||
528 | } | ||
529 | // Finished with this frame, send flags | ||
530 | if (dsize > 1) dsize = 1; | ||
531 | } | ||
532 | } | ||
533 | break; | ||
534 | case HDLC_SEND_IDLE1: | ||
535 | hdlc->do_closing = 0; | ||
536 | hdlc->cbin <<= 1; | ||
537 | hdlc->cbin++; | ||
538 | hdlc->data_bits++; | ||
539 | hdlc->bit_shift--; | ||
540 | if(hdlc->bit_shift==0){ | ||
541 | hdlc->state = HDLC_SEND_FAST_IDLE; | ||
542 | hdlc->bit_shift = 0; | ||
543 | } | ||
544 | break; | ||
545 | case HDLC_SEND_FAST_IDLE: | ||
546 | hdlc->do_closing = 0; | ||
547 | hdlc->cbin = 0xff; | ||
548 | hdlc->data_bits = 8; | ||
549 | if(hdlc->bit_shift == 8){ | ||
550 | hdlc->cbin = 0x7e; | ||
551 | hdlc->state = HDLC_SEND_FIRST_FLAG; | ||
552 | } else { | ||
553 | *dst++ = hdlc->cbin; | ||
554 | hdlc->bit_shift = hdlc->data_bits = 0; | ||
555 | len++; | ||
556 | dsize = 0; | ||
557 | } | ||
558 | break; | ||
559 | default: | ||
560 | break; | ||
561 | } | ||
562 | if(hdlc->do_adapt56){ | ||
563 | if(hdlc->data_bits==7){ | ||
564 | hdlc->cbin <<= 1; | ||
565 | hdlc->cbin++; | ||
566 | hdlc->data_bits++; | ||
567 | } | ||
568 | } | ||
569 | if(hdlc->data_bits==8){ | ||
570 | *dst++ = hdlc->cbin; | ||
571 | hdlc->data_bits = 0; | ||
572 | len++; | ||
573 | dsize--; | ||
574 | } | ||
575 | } | ||
576 | *count -= slen; | ||
577 | |||
578 | return len; | ||
579 | } | ||
580 | |||
diff --git a/drivers/isdn/hisax/st5481_hdlc.h b/drivers/isdn/hisax/st5481_hdlc.h deleted file mode 100644 index 495432f0f6ba..000000000000 --- a/drivers/isdn/hisax/st5481_hdlc.h +++ /dev/null | |||
@@ -1,62 +0,0 @@ | |||
1 | /* | ||
2 | * Driver for ST5481 USB ISDN modem | ||
3 | * | ||
4 | * Author Frode Isaksen | ||
5 | * Copyright 2001 by Frode Isaksen <fisaksen@bewan.com> | ||
6 | * 2001 by Kai Germaschewski <kai.germaschewski@gmx.de> | ||
7 | * | ||
8 | * This software may be used and distributed according to the terms | ||
9 | * of the GNU General Public License, incorporated herein by reference. | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #ifndef __ST5481_HDLC_H__ | ||
14 | #define __ST5481_HDLC_H__ | ||
15 | |||
16 | struct hdlc_vars { | ||
17 | int bit_shift; | ||
18 | int hdlc_bits1; | ||
19 | int data_bits; | ||
20 | int ffbit_shift; // encoding only | ||
21 | int state; | ||
22 | int dstpos; | ||
23 | |||
24 | int data_received:1; // set if transferring data | ||
25 | int dchannel:1; // set if D channel (send idle instead of flags) | ||
26 | int do_adapt56:1; // set if 56K adaptation | ||
27 | int do_closing:1; // set if in closing phase (need to send CRC + flag | ||
28 | |||
29 | unsigned short crc; | ||
30 | |||
31 | unsigned char cbin; | ||
32 | unsigned char shift_reg; | ||
33 | unsigned char ffvalue; | ||
34 | |||
35 | }; | ||
36 | |||
37 | |||
38 | /* | ||
39 | The return value from hdlc_decode is | ||
40 | the frame length, 0 if no complete frame was decoded, | ||
41 | or a negative error number | ||
42 | */ | ||
43 | |||
44 | #define HDLC_FRAMING_ERROR 1 | ||
45 | #define HDLC_CRC_ERROR 2 | ||
46 | #define HDLC_LENGTH_ERROR 3 | ||
47 | |||
48 | void | ||
49 | hdlc_rcv_init(struct hdlc_vars *hdlc, int do_adapt56); | ||
50 | |||
51 | int | ||
52 | hdlc_decode(struct hdlc_vars *hdlc, const unsigned char *src, int slen,int *count, | ||
53 | unsigned char *dst, int dsize); | ||
54 | |||
55 | void | ||
56 | hdlc_out_init(struct hdlc_vars *hdlc,int is_d_channel,int do_adapt56); | ||
57 | |||
58 | int | ||
59 | hdlc_encode(struct hdlc_vars *hdlc,const unsigned char *src,unsigned short slen,int *count, | ||
60 | unsigned char *dst,int dsize); | ||
61 | |||
62 | #endif | ||
diff --git a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c index 2369180b1cb1..ab62223297a5 100644 --- a/drivers/isdn/hisax/st5481_usb.c +++ b/drivers/isdn/hisax/st5481_usb.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include "st5481.h" | 16 | #include "st5481.h" |
17 | 17 | ||
18 | static int st5481_isoc_flatten(struct urb *urb); | ||
19 | |||
18 | /* ====================================================================== | 20 | /* ====================================================================== |
19 | * control pipe | 21 | * control pipe |
20 | */ | 22 | */ |
@@ -55,9 +57,9 @@ static void usb_next_ctrl_msg(struct urb *urb, | |||
55 | * Asynchronous endpoint 0 request (async version of usb_control_msg). | 57 | * Asynchronous endpoint 0 request (async version of usb_control_msg). |
56 | * The request will be queued up in a FIFO if the endpoint is busy. | 58 | * The request will be queued up in a FIFO if the endpoint is busy. |
57 | */ | 59 | */ |
58 | void usb_ctrl_msg(struct st5481_adapter *adapter, | 60 | static void usb_ctrl_msg(struct st5481_adapter *adapter, |
59 | u8 request, u8 requesttype, u16 value, u16 index, | 61 | u8 request, u8 requesttype, u16 value, u16 index, |
60 | ctrl_complete_t complete, void *context) | 62 | ctrl_complete_t complete, void *context) |
61 | { | 63 | { |
62 | struct st5481_ctrl *ctrl = &adapter->ctrl; | 64 | struct st5481_ctrl *ctrl = &adapter->ctrl; |
63 | int w_index; | 65 | int w_index; |
@@ -571,7 +573,7 @@ void st5481_release_in(struct st5481_in *in) | |||
571 | * Make the transfer_buffer contiguous by | 573 | * Make the transfer_buffer contiguous by |
572 | * copying from the iso descriptors if necessary. | 574 | * copying from the iso descriptors if necessary. |
573 | */ | 575 | */ |
574 | int st5481_isoc_flatten(struct urb *urb) | 576 | static int st5481_isoc_flatten(struct urb *urb) |
575 | { | 577 | { |
576 | struct usb_iso_packet_descriptor *pipd,*pend; | 578 | struct usb_iso_packet_descriptor *pipd,*pend; |
577 | unsigned char *src,*dst; | 579 | unsigned char *src,*dst; |
diff --git a/drivers/isdn/hisax/tei.c b/drivers/isdn/hisax/tei.c index 082726db3985..ceb0df92fd3e 100644 --- a/drivers/isdn/hisax/tei.c +++ b/drivers/isdn/hisax/tei.c | |||
@@ -74,7 +74,7 @@ static char *strTeiEvent[] = | |||
74 | "EV_T202", | 74 | "EV_T202", |
75 | }; | 75 | }; |
76 | 76 | ||
77 | unsigned int | 77 | static unsigned int |
78 | random_ri(void) | 78 | random_ri(void) |
79 | { | 79 | { |
80 | unsigned int x; | 80 | unsigned int x; |
diff --git a/drivers/isdn/hisax/teleint.c b/drivers/isdn/hisax/teleint.c index ef8984c5f1f7..a2b1816af37a 100644 --- a/drivers/isdn/hisax/teleint.c +++ b/drivers/isdn/hisax/teleint.c | |||
@@ -18,7 +18,7 @@ | |||
18 | 18 | ||
19 | extern const char *CardType[]; | 19 | extern const char *CardType[]; |
20 | 20 | ||
21 | const char *TeleInt_revision = "$Revision: 1.16.2.5 $"; | 21 | static const char *TeleInt_revision = "$Revision: 1.16.2.5 $"; |
22 | 22 | ||
23 | #define byteout(addr,val) outb(val,addr) | 23 | #define byteout(addr,val) outb(val,addr) |
24 | #define bytein(addr) inb(addr) | 24 | #define bytein(addr) inb(addr) |
@@ -203,7 +203,7 @@ TeleInt_Timer(struct IsdnCardState *cs) | |||
203 | add_timer(&cs->hw.hfc.timer); | 203 | add_timer(&cs->hw.hfc.timer); |
204 | } | 204 | } |
205 | 205 | ||
206 | void | 206 | static void |
207 | release_io_TeleInt(struct IsdnCardState *cs) | 207 | release_io_TeleInt(struct IsdnCardState *cs) |
208 | { | 208 | { |
209 | del_timer(&cs->hw.hfc.timer); | 209 | del_timer(&cs->hw.hfc.timer); |
diff --git a/drivers/isdn/hisax/teles0.c b/drivers/isdn/hisax/teles0.c index 5ec5ec3e1eab..2b7df8f98233 100644 --- a/drivers/isdn/hisax/teles0.c +++ b/drivers/isdn/hisax/teles0.c | |||
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | extern const char *CardType[]; | 24 | extern const char *CardType[]; |
25 | 25 | ||
26 | const char *teles0_revision = "$Revision: 2.15.2.4 $"; | 26 | static const char *teles0_revision = "$Revision: 2.15.2.4 $"; |
27 | 27 | ||
28 | #define TELES_IOMEM_SIZE 0x400 | 28 | #define TELES_IOMEM_SIZE 0x400 |
29 | #define byteout(addr,val) outb(val,addr) | 29 | #define byteout(addr,val) outb(val,addr) |
@@ -183,7 +183,7 @@ teles0_interrupt(int intno, void *dev_id, struct pt_regs *regs) | |||
183 | return IRQ_HANDLED; | 183 | return IRQ_HANDLED; |
184 | } | 184 | } |
185 | 185 | ||
186 | void | 186 | static void |
187 | release_io_teles0(struct IsdnCardState *cs) | 187 | release_io_teles0(struct IsdnCardState *cs) |
188 | { | 188 | { |
189 | if (cs->hw.teles0.cfg_reg) | 189 | if (cs->hw.teles0.cfg_reg) |
diff --git a/drivers/isdn/hisax/teles3.c b/drivers/isdn/hisax/teles3.c index c5b1f65f7275..adeaad62d35c 100644 --- a/drivers/isdn/hisax/teles3.c +++ b/drivers/isdn/hisax/teles3.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include "isdnl1.h" | 21 | #include "isdnl1.h" |
22 | 22 | ||
23 | extern const char *CardType[]; | 23 | extern const char *CardType[]; |
24 | const char *teles3_revision = "$Revision: 2.19.2.4 $"; | 24 | static const char *teles3_revision = "$Revision: 2.19.2.4 $"; |
25 | 25 | ||
26 | #define byteout(addr,val) outb(val,addr) | 26 | #define byteout(addr,val) outb(val,addr) |
27 | #define bytein(addr) inb(addr) | 27 | #define bytein(addr) inb(addr) |
@@ -154,7 +154,7 @@ release_ioregs(struct IsdnCardState *cs, int mask) | |||
154 | release_region(cs->hw.teles3.hscx[1] + 32, 32); | 154 | release_region(cs->hw.teles3.hscx[1] + 32, 32); |
155 | } | 155 | } |
156 | 156 | ||
157 | void | 157 | static void |
158 | release_io_teles3(struct IsdnCardState *cs) | 158 | release_io_teles3(struct IsdnCardState *cs) |
159 | { | 159 | { |
160 | if (cs->typ == ISDN_CTYPE_TELESPCMCIA) { | 160 | if (cs->typ == ISDN_CTYPE_TELESPCMCIA) { |
diff --git a/drivers/isdn/hisax/telespci.c b/drivers/isdn/hisax/telespci.c index 0661c6c31ad0..e2bb4fd8e25e 100644 --- a/drivers/isdn/hisax/telespci.c +++ b/drivers/isdn/hisax/telespci.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
22 | 22 | ||
23 | extern const char *CardType[]; | 23 | extern const char *CardType[]; |
24 | const char *telespci_revision = "$Revision: 2.23.2.3 $"; | 24 | static const char *telespci_revision = "$Revision: 2.23.2.3 $"; |
25 | 25 | ||
26 | #define ZORAN_PO_RQ_PEN 0x02000000 | 26 | #define ZORAN_PO_RQ_PEN 0x02000000 |
27 | #define ZORAN_PO_WR 0x00800000 | 27 | #define ZORAN_PO_WR 0x00800000 |
@@ -257,7 +257,7 @@ telespci_interrupt(int intno, void *dev_id, struct pt_regs *regs) | |||
257 | return IRQ_HANDLED; | 257 | return IRQ_HANDLED; |
258 | } | 258 | } |
259 | 259 | ||
260 | void | 260 | static void |
261 | release_io_telespci(struct IsdnCardState *cs) | 261 | release_io_telespci(struct IsdnCardState *cs) |
262 | { | 262 | { |
263 | iounmap(cs->hw.teles0.membase); | 263 | iounmap(cs->hw.teles0.membase); |
diff --git a/drivers/isdn/hisax/w6692.c b/drivers/isdn/hisax/w6692.c index d2b6b8e72980..7baf8e488471 100644 --- a/drivers/isdn/hisax/w6692.c +++ b/drivers/isdn/hisax/w6692.c | |||
@@ -41,7 +41,7 @@ static const PCI_ENTRY id_list[] = | |||
41 | 41 | ||
42 | extern const char *CardType[]; | 42 | extern const char *CardType[]; |
43 | 43 | ||
44 | const char *w6692_revision = "$Revision: 1.18.2.4 $"; | 44 | static const char *w6692_revision = "$Revision: 1.18.2.4 $"; |
45 | 45 | ||
46 | #define DBUSY_TIMER_VALUE 80 | 46 | #define DBUSY_TIMER_VALUE 80 |
47 | 47 | ||
@@ -880,7 +880,7 @@ setstack_w6692(struct PStack *st, struct BCState *bcs) | |||
880 | return (0); | 880 | return (0); |
881 | } | 881 | } |
882 | 882 | ||
883 | void resetW6692(struct IsdnCardState *cs) | 883 | static void resetW6692(struct IsdnCardState *cs) |
884 | { | 884 | { |
885 | cs->writeW6692(cs, W_D_CTL, W_D_CTL_SRST); | 885 | cs->writeW6692(cs, W_D_CTL, W_D_CTL_SRST); |
886 | mdelay(10); | 886 | mdelay(10); |
@@ -902,7 +902,7 @@ void resetW6692(struct IsdnCardState *cs) | |||
902 | } | 902 | } |
903 | } | 903 | } |
904 | 904 | ||
905 | void __init initW6692(struct IsdnCardState *cs, int part) | 905 | static void __init initW6692(struct IsdnCardState *cs, int part) |
906 | { | 906 | { |
907 | if (part & 1) { | 907 | if (part & 1) { |
908 | cs->setstack_d = setstack_W6692; | 908 | cs->setstack_d = setstack_W6692; |
diff --git a/drivers/isdn/i4l/isdn_audio.c b/drivers/isdn/i4l/isdn_audio.c index 5350836a4f98..2cc56d6a9fae 100644 --- a/drivers/isdn/i4l/isdn_audio.c +++ b/drivers/isdn/i4l/isdn_audio.c | |||
@@ -392,16 +392,6 @@ isdn_audio_adpcm2xlaw(adpcm_state * s, int fmt, unsigned char *in, | |||
392 | } | 392 | } |
393 | 393 | ||
394 | int | 394 | int |
395 | isdn_audio_2adpcm_flush(adpcm_state * s, unsigned char *out) | ||
396 | { | ||
397 | int olen = 0; | ||
398 | |||
399 | if (s->nleft) | ||
400 | isdn_audio_put_bits(0, 8 - s->nleft, s, &out, &olen); | ||
401 | return olen; | ||
402 | } | ||
403 | |||
404 | int | ||
405 | isdn_audio_xlaw2adpcm(adpcm_state * s, int fmt, unsigned char *in, | 395 | isdn_audio_xlaw2adpcm(adpcm_state * s, int fmt, unsigned char *in, |
406 | unsigned char *out, int len) | 396 | unsigned char *out, int len) |
407 | { | 397 | { |
diff --git a/drivers/isdn/i4l/isdn_audio.h b/drivers/isdn/i4l/isdn_audio.h index 5a977b21dcfa..013c3582e0d1 100644 --- a/drivers/isdn/i4l/isdn_audio.h +++ b/drivers/isdn/i4l/isdn_audio.h | |||
@@ -35,7 +35,6 @@ extern void isdn_audio_alaw2ulaw(unsigned char *, unsigned long); | |||
35 | extern adpcm_state *isdn_audio_adpcm_init(adpcm_state *, int); | 35 | extern adpcm_state *isdn_audio_adpcm_init(adpcm_state *, int); |
36 | extern int isdn_audio_adpcm2xlaw(adpcm_state *, int, unsigned char *, unsigned char *, int); | 36 | extern int isdn_audio_adpcm2xlaw(adpcm_state *, int, unsigned char *, unsigned char *, int); |
37 | extern int isdn_audio_xlaw2adpcm(adpcm_state *, int, unsigned char *, unsigned char *, int); | 37 | extern int isdn_audio_xlaw2adpcm(adpcm_state *, int, unsigned char *, unsigned char *, int); |
38 | extern int isdn_audio_2adpcm_flush(adpcm_state * s, unsigned char *out); | ||
39 | extern void isdn_audio_calc_dtmf(modem_info *, unsigned char *, int, int); | 38 | extern void isdn_audio_calc_dtmf(modem_info *, unsigned char *, int, int); |
40 | extern void isdn_audio_eval_dtmf(modem_info *); | 39 | extern void isdn_audio_eval_dtmf(modem_info *); |
41 | dtmf_state *isdn_audio_dtmf_init(dtmf_state *); | 40 | dtmf_state *isdn_audio_dtmf_init(dtmf_state *); |
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index c406df6f268a..eebcb0b97f0e 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c | |||
@@ -67,7 +67,7 @@ static isdn_divert_if *divert_if; /* = NULL */ | |||
67 | static int isdn_writebuf_stub(int, int, const u_char __user *, int); | 67 | static int isdn_writebuf_stub(int, int, const u_char __user *, int); |
68 | static void set_global_features(void); | 68 | static void set_global_features(void); |
69 | static int isdn_wildmat(char *s, char *p); | 69 | static int isdn_wildmat(char *s, char *p); |
70 | 70 | static int isdn_add_channels(isdn_driver_t *d, int drvidx, int n, int adding); | |
71 | 71 | ||
72 | static inline void | 72 | static inline void |
73 | isdn_lock_driver(isdn_driver_t *drv) | 73 | isdn_lock_driver(isdn_driver_t *drv) |
@@ -388,7 +388,7 @@ isdn_all_eaz(int di, int ch) | |||
388 | */ | 388 | */ |
389 | #include <linux/isdn/capicmd.h> | 389 | #include <linux/isdn/capicmd.h> |
390 | 390 | ||
391 | int | 391 | static int |
392 | isdn_capi_rec_hl_msg(capi_msg *cm) { | 392 | isdn_capi_rec_hl_msg(capi_msg *cm) { |
393 | 393 | ||
394 | int di; | 394 | int di; |
@@ -1923,7 +1923,7 @@ isdn_writebuf_skb_stub(int drvidx, int chan, int ack, struct sk_buff *skb) | |||
1923 | return ret; | 1923 | return ret; |
1924 | } | 1924 | } |
1925 | 1925 | ||
1926 | int | 1926 | static int |
1927 | isdn_add_channels(isdn_driver_t *d, int drvidx, int n, int adding) | 1927 | isdn_add_channels(isdn_driver_t *d, int drvidx, int n, int adding) |
1928 | { | 1928 | { |
1929 | int j, k, m; | 1929 | int j, k, m; |
diff --git a/drivers/isdn/i4l/isdn_common.h b/drivers/isdn/i4l/isdn_common.h index 808135c427ad..e27e9c3a81ed 100644 --- a/drivers/isdn/i4l/isdn_common.h +++ b/drivers/isdn/i4l/isdn_common.h | |||
@@ -41,7 +41,6 @@ extern int isdn_get_free_channel(int, int, int, int, int, char *); | |||
41 | extern int isdn_writebuf_skb_stub(int, int, int, struct sk_buff *); | 41 | extern int isdn_writebuf_skb_stub(int, int, int, struct sk_buff *); |
42 | extern int register_isdn(isdn_if * i); | 42 | extern int register_isdn(isdn_if * i); |
43 | extern int isdn_msncmp( const char *, const char *); | 43 | extern int isdn_msncmp( const char *, const char *); |
44 | extern int isdn_add_channels(isdn_driver_t *, int, int, int); | ||
45 | #if defined(ISDN_DEBUG_NET_DUMP) || defined(ISDN_DEBUG_MODEM_DUMP) | 44 | #if defined(ISDN_DEBUG_NET_DUMP) || defined(ISDN_DEBUG_MODEM_DUMP) |
46 | extern void isdn_dumppkt(char *, u_char *, int, int); | 45 | extern void isdn_dumppkt(char *, u_char *, int, int); |
47 | #endif | 46 | #endif |
diff --git a/drivers/isdn/i4l/isdn_concap.c b/drivers/isdn/i4l/isdn_concap.c index 83a4f5382bc2..0193b6f7c70c 100644 --- a/drivers/isdn/i4l/isdn_concap.c +++ b/drivers/isdn/i4l/isdn_concap.c | |||
@@ -39,7 +39,7 @@ | |||
39 | */ | 39 | */ |
40 | 40 | ||
41 | 41 | ||
42 | int isdn_concap_dl_data_req(struct concap_proto *concap, struct sk_buff *skb) | 42 | static int isdn_concap_dl_data_req(struct concap_proto *concap, struct sk_buff *skb) |
43 | { | 43 | { |
44 | struct net_device *ndev = concap -> net_dev; | 44 | struct net_device *ndev = concap -> net_dev; |
45 | isdn_net_dev *nd = ((isdn_net_local *) ndev->priv)->netdev; | 45 | isdn_net_dev *nd = ((isdn_net_local *) ndev->priv)->netdev; |
@@ -58,7 +58,7 @@ int isdn_concap_dl_data_req(struct concap_proto *concap, struct sk_buff *skb) | |||
58 | } | 58 | } |
59 | 59 | ||
60 | 60 | ||
61 | int isdn_concap_dl_connect_req(struct concap_proto *concap) | 61 | static int isdn_concap_dl_connect_req(struct concap_proto *concap) |
62 | { | 62 | { |
63 | struct net_device *ndev = concap -> net_dev; | 63 | struct net_device *ndev = concap -> net_dev; |
64 | isdn_net_local *lp = (isdn_net_local *) ndev->priv; | 64 | isdn_net_local *lp = (isdn_net_local *) ndev->priv; |
@@ -71,7 +71,7 @@ int isdn_concap_dl_connect_req(struct concap_proto *concap) | |||
71 | return ret; | 71 | return ret; |
72 | } | 72 | } |
73 | 73 | ||
74 | int isdn_concap_dl_disconn_req(struct concap_proto *concap) | 74 | static int isdn_concap_dl_disconn_req(struct concap_proto *concap) |
75 | { | 75 | { |
76 | IX25DEBUG( "isdn_concap_dl_disconn_req: %s \n", concap -> net_dev -> name); | 76 | IX25DEBUG( "isdn_concap_dl_disconn_req: %s \n", concap -> net_dev -> name); |
77 | 77 | ||
@@ -85,15 +85,6 @@ struct concap_device_ops isdn_concap_reliable_dl_dops = { | |||
85 | &isdn_concap_dl_disconn_req | 85 | &isdn_concap_dl_disconn_req |
86 | }; | 86 | }; |
87 | 87 | ||
88 | struct concap_device_ops isdn_concap_demand_dial_dops = { | ||
89 | NULL, /* set this first entry to something like &isdn_net_start_xmit, | ||
90 | but the entry part of the current isdn_net_start_xmit must be | ||
91 | separated first. */ | ||
92 | /* no connection control for demand dial semantics */ | ||
93 | NULL, | ||
94 | NULL, | ||
95 | }; | ||
96 | |||
97 | /* The following should better go into a dedicated source file such that | 88 | /* The following should better go into a dedicated source file such that |
98 | this sourcefile does not need to include any protocol specific header | 89 | this sourcefile does not need to include any protocol specific header |
99 | files. For now: | 90 | files. For now: |
diff --git a/drivers/isdn/i4l/isdn_concap.h b/drivers/isdn/i4l/isdn_concap.h index 306eb180438f..6ac7e0445ea5 100644 --- a/drivers/isdn/i4l/isdn_concap.h +++ b/drivers/isdn/i4l/isdn_concap.h | |||
@@ -8,7 +8,6 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | extern struct concap_device_ops isdn_concap_reliable_dl_dops; | 10 | extern struct concap_device_ops isdn_concap_reliable_dl_dops; |
11 | extern struct concap_device_ops isdn_concap_demand_dial_dops; | ||
12 | extern struct concap_proto * isdn_concap_new( int ); | 11 | extern struct concap_proto * isdn_concap_new( int ); |
13 | 12 | ||
14 | 13 | ||
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c index e2b790e34510..f30e8e63ae0d 100644 --- a/drivers/isdn/i4l/isdn_net.c +++ b/drivers/isdn/i4l/isdn_net.c | |||
@@ -176,7 +176,7 @@ static __inline__ void isdn_net_zero_frame_cnt(isdn_net_local *lp) | |||
176 | 176 | ||
177 | /* Prototypes */ | 177 | /* Prototypes */ |
178 | 178 | ||
179 | int isdn_net_force_dial_lp(isdn_net_local *); | 179 | static int isdn_net_force_dial_lp(isdn_net_local *); |
180 | static int isdn_net_start_xmit(struct sk_buff *, struct net_device *); | 180 | static int isdn_net_start_xmit(struct sk_buff *, struct net_device *); |
181 | 181 | ||
182 | static void isdn_net_ciscohdlck_connected(isdn_net_local *lp); | 182 | static void isdn_net_ciscohdlck_connected(isdn_net_local *lp); |
@@ -312,7 +312,7 @@ isdn_net_unbind_channel(isdn_net_local * lp) | |||
312 | * Since this function is called every second, simply reset the | 312 | * Since this function is called every second, simply reset the |
313 | * byte-counter of the interface after copying it to the cps-variable. | 313 | * byte-counter of the interface after copying it to the cps-variable. |
314 | */ | 314 | */ |
315 | unsigned long last_jiffies = -HZ; | 315 | static unsigned long last_jiffies = -HZ; |
316 | 316 | ||
317 | void | 317 | void |
318 | isdn_net_autohup(void) | 318 | isdn_net_autohup(void) |
@@ -1131,7 +1131,7 @@ isdn_net_adjust_hdr(struct sk_buff *skb, struct net_device *dev) | |||
1131 | } | 1131 | } |
1132 | 1132 | ||
1133 | 1133 | ||
1134 | void isdn_net_tx_timeout(struct net_device * ndev) | 1134 | static void isdn_net_tx_timeout(struct net_device * ndev) |
1135 | { | 1135 | { |
1136 | isdn_net_local *lp = (isdn_net_local *) ndev->priv; | 1136 | isdn_net_local *lp = (isdn_net_local *) ndev->priv; |
1137 | 1137 | ||
@@ -1424,7 +1424,7 @@ isdn_net_ciscohdlck_alloc_skb(isdn_net_local *lp, int len) | |||
1424 | } | 1424 | } |
1425 | 1425 | ||
1426 | /* cisco hdlck device private ioctls */ | 1426 | /* cisco hdlck device private ioctls */ |
1427 | int | 1427 | static int |
1428 | isdn_ciscohdlck_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | 1428 | isdn_ciscohdlck_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
1429 | { | 1429 | { |
1430 | isdn_net_local *lp = (isdn_net_local *) dev->priv; | 1430 | isdn_net_local *lp = (isdn_net_local *) dev->priv; |
@@ -2461,7 +2461,7 @@ isdn_net_findif(char *name) | |||
2461 | * This is called from the userlevel-routine below or | 2461 | * This is called from the userlevel-routine below or |
2462 | * from isdn_net_start_xmit(). | 2462 | * from isdn_net_start_xmit(). |
2463 | */ | 2463 | */ |
2464 | int | 2464 | static int |
2465 | isdn_net_force_dial_lp(isdn_net_local * lp) | 2465 | isdn_net_force_dial_lp(isdn_net_local * lp) |
2466 | { | 2466 | { |
2467 | if ((!(lp->flags & ISDN_NET_CONNECTED)) && !lp->dialstate) { | 2467 | if ((!(lp->flags & ISDN_NET_CONNECTED)) && !lp->dialstate) { |
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index e21007eca0f0..ad5aa38fb5a6 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c | |||
@@ -273,7 +273,7 @@ isdn_tty_rcv_skb(int i, int di, int channel, struct sk_buff *skb) | |||
273 | return 1; | 273 | return 1; |
274 | } | 274 | } |
275 | 275 | ||
276 | void | 276 | static void |
277 | isdn_tty_cleanup_xmit(modem_info * info) | 277 | isdn_tty_cleanup_xmit(modem_info * info) |
278 | { | 278 | { |
279 | skb_queue_purge(&info->xmit_queue); | 279 | skb_queue_purge(&info->xmit_queue); |
@@ -560,7 +560,7 @@ isdn_tty_modem_ncarrier(modem_info * info) | |||
560 | /* | 560 | /* |
561 | * return the usage calculated by si and layer 2 protocol | 561 | * return the usage calculated by si and layer 2 protocol |
562 | */ | 562 | */ |
563 | int | 563 | static int |
564 | isdn_calc_usage(int si, int l2) | 564 | isdn_calc_usage(int si, int l2) |
565 | { | 565 | { |
566 | int usg = ISDN_USAGE_MODEM; | 566 | int usg = ISDN_USAGE_MODEM; |
diff --git a/drivers/isdn/i4l/isdn_tty.h b/drivers/isdn/i4l/isdn_tty.h index 2423a7ff0cc3..9f0fa9501f4d 100644 --- a/drivers/isdn/i4l/isdn_tty.h +++ b/drivers/isdn/i4l/isdn_tty.h | |||
@@ -109,7 +109,6 @@ extern int isdn_tty_modem_init(void); | |||
109 | extern void isdn_tty_exit(void); | 109 | extern void isdn_tty_exit(void); |
110 | extern void isdn_tty_readmodem(void); | 110 | extern void isdn_tty_readmodem(void); |
111 | extern int isdn_tty_find_icall(int, int, setup_parm *); | 111 | extern int isdn_tty_find_icall(int, int, setup_parm *); |
112 | extern void isdn_tty_cleanup_xmit(modem_info *); | ||
113 | extern int isdn_tty_stat_callback(int, isdn_ctrl *); | 112 | extern int isdn_tty_stat_callback(int, isdn_ctrl *); |
114 | extern int isdn_tty_rcv_skb(int, int, int, struct sk_buff *); | 113 | extern int isdn_tty_rcv_skb(int, int, int, struct sk_buff *); |
115 | extern int isdn_tty_capi_facility(capi_msg *cm); | 114 | extern int isdn_tty_capi_facility(capi_msg *cm); |
diff --git a/drivers/isdn/i4l/isdn_ttyfax.c b/drivers/isdn/i4l/isdn_ttyfax.c index ce2c3ef92e46..a943d078bacc 100644 --- a/drivers/isdn/i4l/isdn_ttyfax.c +++ b/drivers/isdn/i4l/isdn_ttyfax.c | |||
@@ -148,7 +148,7 @@ isdn_tty_fax_modem_result(int code, modem_info * info) | |||
148 | } | 148 | } |
149 | } | 149 | } |
150 | 150 | ||
151 | int | 151 | static int |
152 | isdn_tty_fax_command1(modem_info * info, isdn_ctrl * c) | 152 | isdn_tty_fax_command1(modem_info * info, isdn_ctrl * c) |
153 | { | 153 | { |
154 | static char *msg[] = | 154 | static char *msg[] = |
@@ -316,7 +316,7 @@ isdn_tty_fax_bitorder(modem_info * info, struct sk_buff *skb) | |||
316 | * Parse AT+F.. FAX class 1 commands | 316 | * Parse AT+F.. FAX class 1 commands |
317 | */ | 317 | */ |
318 | 318 | ||
319 | int | 319 | static int |
320 | isdn_tty_cmd_FCLASS1(char **p, modem_info * info) | 320 | isdn_tty_cmd_FCLASS1(char **p, modem_info * info) |
321 | { | 321 | { |
322 | static char *cmd[] = | 322 | static char *cmd[] = |
@@ -408,7 +408,7 @@ isdn_tty_cmd_FCLASS1(char **p, modem_info * info) | |||
408 | * Parse AT+F.. FAX class 2 commands | 408 | * Parse AT+F.. FAX class 2 commands |
409 | */ | 409 | */ |
410 | 410 | ||
411 | int | 411 | static int |
412 | isdn_tty_cmd_FCLASS2(char **p, modem_info * info) | 412 | isdn_tty_cmd_FCLASS2(char **p, modem_info * info) |
413 | { | 413 | { |
414 | atemu *m = &info->emu; | 414 | atemu *m = &info->emu; |
diff --git a/drivers/isdn/i4l/isdn_x25iface.c b/drivers/isdn/i4l/isdn_x25iface.c index 4ab7600cf9c1..edf14a2aa3c8 100644 --- a/drivers/isdn/i4l/isdn_x25iface.c +++ b/drivers/isdn/i4l/isdn_x25iface.c | |||
@@ -40,15 +40,15 @@ typedef struct isdn_x25iface_proto_data { | |||
40 | 40 | ||
41 | 41 | ||
42 | /* is now in header file (extern): struct concap_proto * isdn_x25iface_proto_new(void); */ | 42 | /* is now in header file (extern): struct concap_proto * isdn_x25iface_proto_new(void); */ |
43 | void isdn_x25iface_proto_del( struct concap_proto * ); | 43 | static void isdn_x25iface_proto_del( struct concap_proto * ); |
44 | int isdn_x25iface_proto_close( struct concap_proto * ); | 44 | static int isdn_x25iface_proto_close( struct concap_proto * ); |
45 | int isdn_x25iface_proto_restart( struct concap_proto *, | 45 | static int isdn_x25iface_proto_restart( struct concap_proto *, |
46 | struct net_device *, | 46 | struct net_device *, |
47 | struct concap_device_ops *); | 47 | struct concap_device_ops *); |
48 | int isdn_x25iface_xmit( struct concap_proto *, struct sk_buff * ); | 48 | static int isdn_x25iface_xmit( struct concap_proto *, struct sk_buff * ); |
49 | int isdn_x25iface_receive( struct concap_proto *, struct sk_buff * ); | 49 | static int isdn_x25iface_receive( struct concap_proto *, struct sk_buff * ); |
50 | int isdn_x25iface_connect_ind( struct concap_proto * ); | 50 | static int isdn_x25iface_connect_ind( struct concap_proto * ); |
51 | int isdn_x25iface_disconn_ind( struct concap_proto * ); | 51 | static int isdn_x25iface_disconn_ind( struct concap_proto * ); |
52 | 52 | ||
53 | 53 | ||
54 | static struct concap_proto_ops ix25_pops = { | 54 | static struct concap_proto_ops ix25_pops = { |
@@ -102,7 +102,7 @@ struct concap_proto * isdn_x25iface_proto_new(void) | |||
102 | 102 | ||
103 | /* close the x25iface encapsulation protocol | 103 | /* close the x25iface encapsulation protocol |
104 | */ | 104 | */ |
105 | int isdn_x25iface_proto_close(struct concap_proto *cprot){ | 105 | static int isdn_x25iface_proto_close(struct concap_proto *cprot){ |
106 | 106 | ||
107 | ix25_pdata_t *tmp; | 107 | ix25_pdata_t *tmp; |
108 | int ret = 0; | 108 | int ret = 0; |
@@ -129,7 +129,7 @@ int isdn_x25iface_proto_close(struct concap_proto *cprot){ | |||
129 | 129 | ||
130 | /* Delete the x25iface encapsulation protocol instance | 130 | /* Delete the x25iface encapsulation protocol instance |
131 | */ | 131 | */ |
132 | void isdn_x25iface_proto_del(struct concap_proto *cprot){ | 132 | static void isdn_x25iface_proto_del(struct concap_proto *cprot){ |
133 | 133 | ||
134 | ix25_pdata_t * tmp; | 134 | ix25_pdata_t * tmp; |
135 | 135 | ||
@@ -158,9 +158,9 @@ void isdn_x25iface_proto_del(struct concap_proto *cprot){ | |||
158 | 158 | ||
159 | /* (re-)initialize the data structures for x25iface encapsulation | 159 | /* (re-)initialize the data structures for x25iface encapsulation |
160 | */ | 160 | */ |
161 | int isdn_x25iface_proto_restart(struct concap_proto *cprot, | 161 | static int isdn_x25iface_proto_restart(struct concap_proto *cprot, |
162 | struct net_device *ndev, | 162 | struct net_device *ndev, |
163 | struct concap_device_ops *dops) | 163 | struct concap_device_ops *dops) |
164 | { | 164 | { |
165 | ix25_pdata_t * pda = cprot -> proto_data ; | 165 | ix25_pdata_t * pda = cprot -> proto_data ; |
166 | ulong flags; | 166 | ulong flags; |
@@ -187,7 +187,7 @@ int isdn_x25iface_proto_restart(struct concap_proto *cprot, | |||
187 | 187 | ||
188 | /* deliver a dl_data frame received from i4l HL driver to the network layer | 188 | /* deliver a dl_data frame received from i4l HL driver to the network layer |
189 | */ | 189 | */ |
190 | int isdn_x25iface_receive(struct concap_proto *cprot, struct sk_buff *skb) | 190 | static int isdn_x25iface_receive(struct concap_proto *cprot, struct sk_buff *skb) |
191 | { | 191 | { |
192 | IX25DEBUG( "isdn_x25iface_receive %s \n", MY_DEVNAME(cprot->net_dev) ); | 192 | IX25DEBUG( "isdn_x25iface_receive %s \n", MY_DEVNAME(cprot->net_dev) ); |
193 | if ( ( (ix25_pdata_t*) (cprot->proto_data) ) | 193 | if ( ( (ix25_pdata_t*) (cprot->proto_data) ) |
@@ -206,7 +206,7 @@ int isdn_x25iface_receive(struct concap_proto *cprot, struct sk_buff *skb) | |||
206 | 206 | ||
207 | /* a connection set up is indicated by lower layer | 207 | /* a connection set up is indicated by lower layer |
208 | */ | 208 | */ |
209 | int isdn_x25iface_connect_ind(struct concap_proto *cprot) | 209 | static int isdn_x25iface_connect_ind(struct concap_proto *cprot) |
210 | { | 210 | { |
211 | struct sk_buff * skb = dev_alloc_skb(1); | 211 | struct sk_buff * skb = dev_alloc_skb(1); |
212 | enum wan_states *state_p | 212 | enum wan_states *state_p |
@@ -235,7 +235,7 @@ int isdn_x25iface_connect_ind(struct concap_proto *cprot) | |||
235 | 235 | ||
236 | /* a disconnect is indicated by lower layer | 236 | /* a disconnect is indicated by lower layer |
237 | */ | 237 | */ |
238 | int isdn_x25iface_disconn_ind(struct concap_proto *cprot) | 238 | static int isdn_x25iface_disconn_ind(struct concap_proto *cprot) |
239 | { | 239 | { |
240 | struct sk_buff *skb; | 240 | struct sk_buff *skb; |
241 | enum wan_states *state_p | 241 | enum wan_states *state_p |
@@ -264,7 +264,7 @@ int isdn_x25iface_disconn_ind(struct concap_proto *cprot) | |||
264 | /* process a frame handed over to us from linux network layer. First byte | 264 | /* process a frame handed over to us from linux network layer. First byte |
265 | semantics as defined in Documentation/networking/x25-iface.txt | 265 | semantics as defined in Documentation/networking/x25-iface.txt |
266 | */ | 266 | */ |
267 | int isdn_x25iface_xmit(struct concap_proto *cprot, struct sk_buff *skb) | 267 | static int isdn_x25iface_xmit(struct concap_proto *cprot, struct sk_buff *skb) |
268 | { | 268 | { |
269 | unsigned char firstbyte = skb->data[0]; | 269 | unsigned char firstbyte = skb->data[0]; |
270 | enum wan_states *state = &((ix25_pdata_t*)cprot->proto_data)->state; | 270 | enum wan_states *state = &((ix25_pdata_t*)cprot->proto_data)->state; |
diff --git a/drivers/isdn/pcbit/callbacks.c b/drivers/isdn/pcbit/callbacks.c index 692ec72d1ee8..f151f36c8255 100644 --- a/drivers/isdn/pcbit/callbacks.c +++ b/drivers/isdn/pcbit/callbacks.c | |||
@@ -125,23 +125,6 @@ void cb_out_2(struct pcbit_dev * dev, struct pcbit_chan* chan, | |||
125 | 125 | ||
126 | 126 | ||
127 | /* | 127 | /* |
128 | * Disconnect received (actually RELEASE COMPLETE) | ||
129 | * This means we were not able to establish connection with remote | ||
130 | * Inform the big boss above | ||
131 | */ | ||
132 | void cb_out_3(struct pcbit_dev * dev, struct pcbit_chan* chan, | ||
133 | struct callb_data *data) | ||
134 | { | ||
135 | isdn_ctrl ictl; | ||
136 | |||
137 | ictl.command = ISDN_STAT_DHUP; | ||
138 | ictl.driver=dev->id; | ||
139 | ictl.arg=chan->id; | ||
140 | dev->dev_if->statcallb(&ictl); | ||
141 | } | ||
142 | |||
143 | |||
144 | /* | ||
145 | * Incoming call received | 128 | * Incoming call received |
146 | * inform user | 129 | * inform user |
147 | */ | 130 | */ |
diff --git a/drivers/isdn/pcbit/callbacks.h b/drivers/isdn/pcbit/callbacks.h index f510dc56b57e..17aa0f54bfc3 100644 --- a/drivers/isdn/pcbit/callbacks.h +++ b/drivers/isdn/pcbit/callbacks.h | |||
@@ -19,9 +19,6 @@ extern void cb_out_1(struct pcbit_dev * dev, struct pcbit_chan* chan, | |||
19 | extern void cb_out_2(struct pcbit_dev * dev, struct pcbit_chan* chan, | 19 | extern void cb_out_2(struct pcbit_dev * dev, struct pcbit_chan* chan, |
20 | struct callb_data *data); | 20 | struct callb_data *data); |
21 | 21 | ||
22 | extern void cb_out_3(struct pcbit_dev * dev, struct pcbit_chan* chan, | ||
23 | struct callb_data *data); | ||
24 | |||
25 | extern void cb_in_1(struct pcbit_dev * dev, struct pcbit_chan* chan, | 22 | extern void cb_in_1(struct pcbit_dev * dev, struct pcbit_chan* chan, |
26 | struct callb_data *data); | 23 | struct callb_data *data); |
27 | extern void cb_in_2(struct pcbit_dev * dev, struct pcbit_chan* chan, | 24 | extern void cb_in_2(struct pcbit_dev * dev, struct pcbit_chan* chan, |
diff --git a/drivers/isdn/pcbit/capi.c b/drivers/isdn/pcbit/capi.c index 29eb03a8c29d..bef321d0e51d 100644 --- a/drivers/isdn/pcbit/capi.c +++ b/drivers/isdn/pcbit/capi.c | |||
@@ -627,16 +627,6 @@ int capi_decode_disc_ind(struct pcbit_chan *chan, struct sk_buff *skb) | |||
627 | return 0; | 627 | return 0; |
628 | } | 628 | } |
629 | 629 | ||
630 | int capi_decode_disc_conf(struct pcbit_chan *chan, struct sk_buff *skb) | ||
631 | { | ||
632 | ushort errcode; | ||
633 | |||
634 | errcode = *((ushort*) skb->data); | ||
635 | skb_pull(skb, 2); | ||
636 | |||
637 | return errcode; | ||
638 | } | ||
639 | |||
640 | #ifdef DEBUG | 630 | #ifdef DEBUG |
641 | int capi_decode_debug_188(u_char *hdr, ushort hdrlen) | 631 | int capi_decode_debug_188(u_char *hdr, ushort hdrlen) |
642 | { | 632 | { |
diff --git a/drivers/isdn/pcbit/capi.h b/drivers/isdn/pcbit/capi.h index 18e6aa360a8f..df8e73c04d7f 100644 --- a/drivers/isdn/pcbit/capi.h +++ b/drivers/isdn/pcbit/capi.h | |||
@@ -54,7 +54,6 @@ extern int capi_tdata_resp(struct pcbit_chan *chan, struct sk_buff ** skb); | |||
54 | 54 | ||
55 | /* Connection Termination */ | 55 | /* Connection Termination */ |
56 | extern int capi_disc_req(ushort callref, struct sk_buff **skb, u_char cause); | 56 | extern int capi_disc_req(ushort callref, struct sk_buff **skb, u_char cause); |
57 | extern int capi_decode_disc_conf(struct pcbit_chan *chan, struct sk_buff *skb); | ||
58 | 57 | ||
59 | extern int capi_decode_disc_ind(struct pcbit_chan *chan, struct sk_buff *skb); | 58 | extern int capi_decode_disc_ind(struct pcbit_chan *chan, struct sk_buff *skb); |
60 | extern int capi_disc_resp(struct pcbit_chan *chan, struct sk_buff **skb); | 59 | extern int capi_disc_resp(struct pcbit_chan *chan, struct sk_buff **skb); |
diff --git a/drivers/isdn/pcbit/drv.c b/drivers/isdn/pcbit/drv.c index e98f9c48c184..5de861f40816 100644 --- a/drivers/isdn/pcbit/drv.c +++ b/drivers/isdn/pcbit/drv.c | |||
@@ -56,10 +56,10 @@ static char* pcbit_devname[MAX_PCBIT_CARDS] = { | |||
56 | * prototypes | 56 | * prototypes |
57 | */ | 57 | */ |
58 | 58 | ||
59 | int pcbit_command(isdn_ctrl* ctl); | 59 | static int pcbit_command(isdn_ctrl* ctl); |
60 | int pcbit_stat(u_char __user * buf, int len, int, int); | 60 | static int pcbit_stat(u_char __user * buf, int len, int, int); |
61 | int pcbit_xmit(int driver, int chan, int ack, struct sk_buff *skb); | 61 | static int pcbit_xmit(int driver, int chan, int ack, struct sk_buff *skb); |
62 | int pcbit_writecmd(const u_char __user *, int, int, int); | 62 | static int pcbit_writecmd(const u_char __user *, int, int, int); |
63 | 63 | ||
64 | static int set_protocol_running(struct pcbit_dev * dev); | 64 | static int set_protocol_running(struct pcbit_dev * dev); |
65 | 65 | ||
@@ -238,7 +238,7 @@ void pcbit_terminate(int board) | |||
238 | } | 238 | } |
239 | #endif | 239 | #endif |
240 | 240 | ||
241 | int pcbit_command(isdn_ctrl* ctl) | 241 | static int pcbit_command(isdn_ctrl* ctl) |
242 | { | 242 | { |
243 | struct pcbit_dev *dev; | 243 | struct pcbit_dev *dev; |
244 | struct pcbit_chan *chan; | 244 | struct pcbit_chan *chan; |
@@ -330,7 +330,7 @@ static void pcbit_block_timer(unsigned long data) | |||
330 | } | 330 | } |
331 | #endif | 331 | #endif |
332 | 332 | ||
333 | int pcbit_xmit(int driver, int chnum, int ack, struct sk_buff *skb) | 333 | static int pcbit_xmit(int driver, int chnum, int ack, struct sk_buff *skb) |
334 | { | 334 | { |
335 | ushort hdrlen; | 335 | ushort hdrlen; |
336 | int refnum, len; | 336 | int refnum, len; |
@@ -389,7 +389,7 @@ int pcbit_xmit(int driver, int chnum, int ack, struct sk_buff *skb) | |||
389 | return len; | 389 | return len; |
390 | } | 390 | } |
391 | 391 | ||
392 | int pcbit_writecmd(const u_char __user *buf, int len, int driver, int channel) | 392 | static int pcbit_writecmd(const u_char __user *buf, int len, int driver, int channel) |
393 | { | 393 | { |
394 | struct pcbit_dev * dev; | 394 | struct pcbit_dev * dev; |
395 | int i, j; | 395 | int i, j; |
@@ -713,7 +713,7 @@ static char statbuf[STATBUF_LEN]; | |||
713 | static int stat_st = 0; | 713 | static int stat_st = 0; |
714 | static int stat_end = 0; | 714 | static int stat_end = 0; |
715 | 715 | ||
716 | int pcbit_stat(u_char __user *buf, int len, int driver, int channel) | 716 | static int pcbit_stat(u_char __user *buf, int len, int driver, int channel) |
717 | { | 717 | { |
718 | int stat_count; | 718 | int stat_count; |
719 | stat_count = stat_end - stat_st; | 719 | stat_count = stat_end - stat_st; |
diff --git a/drivers/isdn/sc/Makefile b/drivers/isdn/sc/Makefile index 9cc474cd0c44..0f2b7d602ac0 100644 --- a/drivers/isdn/sc/Makefile +++ b/drivers/isdn/sc/Makefile | |||
@@ -6,5 +6,5 @@ obj-$(CONFIG_ISDN_DRV_SC) += sc.o | |||
6 | 6 | ||
7 | # Multipart objects. | 7 | # Multipart objects. |
8 | 8 | ||
9 | sc-y := shmem.o init.o debug.o packet.o command.o event.o \ | 9 | sc-y := shmem.o init.o packet.o command.o event.o \ |
10 | ioctl.o interrupt.o message.o timer.o | 10 | ioctl.o interrupt.o message.o timer.o |
diff --git a/drivers/isdn/sc/command.c b/drivers/isdn/sc/command.c index b2c4eac7cef5..19f2fcf0ae4a 100644 --- a/drivers/isdn/sc/command.c +++ b/drivers/isdn/sc/command.c | |||
@@ -22,14 +22,14 @@ | |||
22 | #include "card.h" | 22 | #include "card.h" |
23 | #include "scioc.h" | 23 | #include "scioc.h" |
24 | 24 | ||
25 | int dial(int card, unsigned long channel, setup_parm setup); | 25 | static int dial(int card, unsigned long channel, setup_parm setup); |
26 | int hangup(int card, unsigned long channel); | 26 | static int hangup(int card, unsigned long channel); |
27 | int answer(int card, unsigned long channel); | 27 | static int answer(int card, unsigned long channel); |
28 | int clreaz(int card, unsigned long channel); | 28 | static int clreaz(int card, unsigned long channel); |
29 | int seteaz(int card, unsigned long channel, char *); | 29 | static int seteaz(int card, unsigned long channel, char *); |
30 | int setl2(int card, unsigned long arg); | 30 | static int setl2(int card, unsigned long arg); |
31 | int setl3(int card, unsigned long arg); | 31 | static int setl3(int card, unsigned long arg); |
32 | int acceptb(int card, unsigned long channel); | 32 | static int acceptb(int card, unsigned long channel); |
33 | 33 | ||
34 | extern int cinst; | 34 | extern int cinst; |
35 | extern board *sc_adapter[]; | 35 | extern board *sc_adapter[]; |
@@ -148,56 +148,6 @@ int command(isdn_ctrl *cmd) | |||
148 | } | 148 | } |
149 | 149 | ||
150 | /* | 150 | /* |
151 | * Confirm our ability to communicate with the board. This test assumes no | ||
152 | * other message activity is present | ||
153 | */ | ||
154 | int loopback(int card) | ||
155 | { | ||
156 | |||
157 | int status; | ||
158 | static char testmsg[] = "Test Message"; | ||
159 | RspMessage rspmsg; | ||
160 | |||
161 | if(!IS_VALID_CARD(card)) { | ||
162 | pr_debug("Invalid param: %d is not a valid card id\n", card); | ||
163 | return -ENODEV; | ||
164 | } | ||
165 | |||
166 | pr_debug("%s: Sending loopback message\n", | ||
167 | sc_adapter[card]->devicename); | ||
168 | |||
169 | /* | ||
170 | * Send the loopback message to confirm that memory transfer is | ||
171 | * operational | ||
172 | */ | ||
173 | status = send_and_receive(card, CMPID, cmReqType1, | ||
174 | cmReqClass0, | ||
175 | cmReqMsgLpbk, | ||
176 | 0, | ||
177 | (unsigned char) strlen(testmsg), | ||
178 | (unsigned char *)testmsg, | ||
179 | &rspmsg, SAR_TIMEOUT); | ||
180 | |||
181 | |||
182 | if (!status) { | ||
183 | pr_debug("%s: Loopback message successfully sent\n", | ||
184 | sc_adapter[card]->devicename); | ||
185 | if(strcmp(rspmsg.msg_data.byte_array, testmsg)) { | ||
186 | pr_debug("%s: Loopback return != sent\n", | ||
187 | sc_adapter[card]->devicename); | ||
188 | return -EIO; | ||
189 | } | ||
190 | return 0; | ||
191 | } | ||
192 | else { | ||
193 | pr_debug("%s: Send loopback message failed\n", | ||
194 | sc_adapter[card]->devicename); | ||
195 | return -EIO; | ||
196 | } | ||
197 | |||
198 | } | ||
199 | |||
200 | /* | ||
201 | * start the onboard firmware | 151 | * start the onboard firmware |
202 | */ | 152 | */ |
203 | int startproc(int card) | 153 | int startproc(int card) |
@@ -222,16 +172,10 @@ int startproc(int card) | |||
222 | } | 172 | } |
223 | 173 | ||
224 | 174 | ||
225 | int loadproc(int card, char *data) | ||
226 | { | ||
227 | return -1; | ||
228 | } | ||
229 | |||
230 | |||
231 | /* | 175 | /* |
232 | * Dials the number passed in | 176 | * Dials the number passed in |
233 | */ | 177 | */ |
234 | int dial(int card, unsigned long channel, setup_parm setup) | 178 | static int dial(int card, unsigned long channel, setup_parm setup) |
235 | { | 179 | { |
236 | int status; | 180 | int status; |
237 | char Phone[48]; | 181 | char Phone[48]; |
@@ -261,7 +205,7 @@ int dial(int card, unsigned long channel, setup_parm setup) | |||
261 | /* | 205 | /* |
262 | * Answer an incoming call | 206 | * Answer an incoming call |
263 | */ | 207 | */ |
264 | int answer(int card, unsigned long channel) | 208 | static int answer(int card, unsigned long channel) |
265 | { | 209 | { |
266 | if(!IS_VALID_CARD(card)) { | 210 | if(!IS_VALID_CARD(card)) { |
267 | pr_debug("Invalid param: %d is not a valid card id\n", card); | 211 | pr_debug("Invalid param: %d is not a valid card id\n", card); |
@@ -282,7 +226,7 @@ int answer(int card, unsigned long channel) | |||
282 | /* | 226 | /* |
283 | * Hangup up the call on specified channel | 227 | * Hangup up the call on specified channel |
284 | */ | 228 | */ |
285 | int hangup(int card, unsigned long channel) | 229 | static int hangup(int card, unsigned long channel) |
286 | { | 230 | { |
287 | int status; | 231 | int status; |
288 | 232 | ||
@@ -305,7 +249,7 @@ int hangup(int card, unsigned long channel) | |||
305 | /* | 249 | /* |
306 | * Set the layer 2 protocol (X.25, HDLC, Raw) | 250 | * Set the layer 2 protocol (X.25, HDLC, Raw) |
307 | */ | 251 | */ |
308 | int setl2(int card, unsigned long arg) | 252 | static int setl2(int card, unsigned long arg) |
309 | { | 253 | { |
310 | int status =0; | 254 | int status =0; |
311 | int protocol,channel; | 255 | int protocol,channel; |
@@ -340,7 +284,7 @@ int setl2(int card, unsigned long arg) | |||
340 | /* | 284 | /* |
341 | * Set the layer 3 protocol | 285 | * Set the layer 3 protocol |
342 | */ | 286 | */ |
343 | int setl3(int card, unsigned long channel) | 287 | static int setl3(int card, unsigned long channel) |
344 | { | 288 | { |
345 | int protocol = channel >> 8; | 289 | int protocol = channel >> 8; |
346 | 290 | ||
@@ -355,7 +299,7 @@ int setl3(int card, unsigned long channel) | |||
355 | return 0; | 299 | return 0; |
356 | } | 300 | } |
357 | 301 | ||
358 | int acceptb(int card, unsigned long channel) | 302 | static int acceptb(int card, unsigned long channel) |
359 | { | 303 | { |
360 | if(!IS_VALID_CARD(card)) { | 304 | if(!IS_VALID_CARD(card)) { |
361 | pr_debug("Invalid param: %d is not a valid card id\n", card); | 305 | pr_debug("Invalid param: %d is not a valid card id\n", card); |
@@ -374,7 +318,7 @@ int acceptb(int card, unsigned long channel) | |||
374 | return 0; | 318 | return 0; |
375 | } | 319 | } |
376 | 320 | ||
377 | int clreaz(int card, unsigned long arg) | 321 | static int clreaz(int card, unsigned long arg) |
378 | { | 322 | { |
379 | if(!IS_VALID_CARD(card)) { | 323 | if(!IS_VALID_CARD(card)) { |
380 | pr_debug("Invalid param: %d is not a valid card id\n", card); | 324 | pr_debug("Invalid param: %d is not a valid card id\n", card); |
@@ -388,7 +332,7 @@ int clreaz(int card, unsigned long arg) | |||
388 | return 0; | 332 | return 0; |
389 | } | 333 | } |
390 | 334 | ||
391 | int seteaz(int card, unsigned long arg, char *num) | 335 | static int seteaz(int card, unsigned long arg, char *num) |
392 | { | 336 | { |
393 | if(!IS_VALID_CARD(card)) { | 337 | if(!IS_VALID_CARD(card)) { |
394 | pr_debug("Invalid param: %d is not a valid card id\n", card); | 338 | pr_debug("Invalid param: %d is not a valid card id\n", card); |
diff --git a/drivers/isdn/sc/debug.c b/drivers/isdn/sc/debug.c deleted file mode 100644 index 1a992a75868b..000000000000 --- a/drivers/isdn/sc/debug.c +++ /dev/null | |||
@@ -1,46 +0,0 @@ | |||
1 | /* $Id: debug.c,v 1.5.6.1 2001/09/23 22:24:59 kai Exp $ | ||
2 | * | ||
3 | * Copyright (C) 1996 SpellCaster Telecommunications Inc. | ||
4 | * | ||
5 | * This software may be used and distributed according to the terms | ||
6 | * of the GNU General Public License, incorporated herein by reference. | ||
7 | * | ||
8 | * For more information, please contact gpl-info@spellcast.com or write: | ||
9 | * | ||
10 | * SpellCaster Telecommunications Inc. | ||
11 | * 5621 Finch Avenue East, Unit #3 | ||
12 | * Scarborough, Ontario Canada | ||
13 | * M1B 2T9 | ||
14 | * +1 (416) 297-8565 | ||
15 | * +1 (416) 297-6433 Facsimile | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/string.h> | ||
20 | |||
21 | int dbg_level = 0; | ||
22 | static char dbg_funcname[255]; | ||
23 | |||
24 | void dbg_endfunc(void) | ||
25 | { | ||
26 | if (dbg_level) { | ||
27 | printk("<-- Leaving function %s\n", dbg_funcname); | ||
28 | strcpy(dbg_funcname, ""); | ||
29 | } | ||
30 | } | ||
31 | |||
32 | void dbg_func(char *func) | ||
33 | { | ||
34 | strcpy(dbg_funcname, func); | ||
35 | if(dbg_level) | ||
36 | printk("--> Entering function %s\n", dbg_funcname); | ||
37 | } | ||
38 | |||
39 | inline void pullphone(char *dn, char *str) | ||
40 | { | ||
41 | int i = 0; | ||
42 | |||
43 | while(dn[i] != ',') | ||
44 | str[i] = dn[i], i++; | ||
45 | str[i] = 0x0; | ||
46 | } | ||
diff --git a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c index efefedea37b9..40b0df04ed9f 100644 --- a/drivers/isdn/sc/init.c +++ b/drivers/isdn/sc/init.c | |||
@@ -20,9 +20,9 @@ board *sc_adapter[MAX_CARDS]; | |||
20 | int cinst; | 20 | int cinst; |
21 | 21 | ||
22 | static char devname[] = "scX"; | 22 | static char devname[] = "scX"; |
23 | const char version[] = "2.0b1"; | 23 | static const char version[] = "2.0b1"; |
24 | 24 | ||
25 | const char *boardname[] = { "DataCommute/BRI", "DataCommute/PRI", "TeleCommute/BRI" }; | 25 | static const char *boardname[] = { "DataCommute/BRI", "DataCommute/PRI", "TeleCommute/BRI" }; |
26 | 26 | ||
27 | /* insmod set parameters */ | 27 | /* insmod set parameters */ |
28 | static unsigned int io[] = {0,0,0,0}; | 28 | static unsigned int io[] = {0,0,0,0}; |
@@ -35,26 +35,13 @@ module_param_array(irq, int, NULL, 0); | |||
35 | module_param_array(ram, int, NULL, 0); | 35 | module_param_array(ram, int, NULL, 0); |
36 | module_param(do_reset, bool, 0); | 36 | module_param(do_reset, bool, 0); |
37 | 37 | ||
38 | static int sup_irq[] = { 11, 10, 9, 5, 12, 14, 7, 3, 4, 6 }; | ||
39 | #define MAX_IRQS 10 | ||
40 | |||
41 | extern irqreturn_t interrupt_handler(int, void *, struct pt_regs *); | 38 | extern irqreturn_t interrupt_handler(int, void *, struct pt_regs *); |
42 | extern int sndpkt(int, int, int, struct sk_buff *); | 39 | extern int sndpkt(int, int, int, struct sk_buff *); |
43 | extern int command(isdn_ctrl *); | 40 | extern int command(isdn_ctrl *); |
44 | extern int indicate_status(int, int, ulong, char*); | 41 | extern int indicate_status(int, int, ulong, char*); |
45 | extern int reset(int); | 42 | extern int reset(int); |
46 | 43 | ||
47 | int identify_board(unsigned long, unsigned int); | 44 | static int identify_board(unsigned long, unsigned int); |
48 | |||
49 | int irq_supported(int irq_x) | ||
50 | { | ||
51 | int i; | ||
52 | for(i=0 ; i < MAX_IRQS ; i++) { | ||
53 | if(sup_irq[i] == irq_x) | ||
54 | return 1; | ||
55 | } | ||
56 | return 0; | ||
57 | } | ||
58 | 45 | ||
59 | static int __init sc_init(void) | 46 | static int __init sc_init(void) |
60 | { | 47 | { |
@@ -454,7 +441,7 @@ static void __exit sc_exit(void) | |||
454 | pr_info("SpellCaster ISA ISDN Adapter Driver Unloaded.\n"); | 441 | pr_info("SpellCaster ISA ISDN Adapter Driver Unloaded.\n"); |
455 | } | 442 | } |
456 | 443 | ||
457 | int identify_board(unsigned long rambase, unsigned int iobase) | 444 | static int identify_board(unsigned long rambase, unsigned int iobase) |
458 | { | 445 | { |
459 | unsigned int pgport; | 446 | unsigned int pgport; |
460 | unsigned long sig; | 447 | unsigned long sig; |
diff --git a/drivers/isdn/sc/interrupt.c b/drivers/isdn/sc/interrupt.c index e5e164aca7fa..8631d338d69a 100644 --- a/drivers/isdn/sc/interrupt.c +++ b/drivers/isdn/sc/interrupt.c | |||
@@ -31,7 +31,7 @@ extern void rcvpkt(int, RspMessage *); | |||
31 | extern int cinst; | 31 | extern int cinst; |
32 | extern board *sc_adapter[]; | 32 | extern board *sc_adapter[]; |
33 | 33 | ||
34 | int get_card_from_irq(int irq) | 34 | static int get_card_from_irq(int irq) |
35 | { | 35 | { |
36 | int i; | 36 | int i; |
37 | 37 | ||
diff --git a/drivers/isdn/sc/ioctl.c b/drivers/isdn/sc/ioctl.c index 1371a990416a..3314a5a19854 100644 --- a/drivers/isdn/sc/ioctl.c +++ b/drivers/isdn/sc/ioctl.c | |||
@@ -14,7 +14,6 @@ | |||
14 | 14 | ||
15 | extern int indicate_status(int, int, unsigned long, char *); | 15 | extern int indicate_status(int, int, unsigned long, char *); |
16 | extern int startproc(int); | 16 | extern int startproc(int); |
17 | extern int loadproc(int, char *record); | ||
18 | extern int reset(int); | 17 | extern int reset(int); |
19 | extern int send_and_receive(int, unsigned int, unsigned char,unsigned char, | 18 | extern int send_and_receive(int, unsigned int, unsigned char,unsigned char, |
20 | unsigned char,unsigned char, | 19 | unsigned char,unsigned char, |
@@ -23,7 +22,7 @@ extern int send_and_receive(int, unsigned int, unsigned char,unsigned char, | |||
23 | extern board *sc_adapter[]; | 22 | extern board *sc_adapter[]; |
24 | 23 | ||
25 | 24 | ||
26 | int GetStatus(int card, boardInfo *); | 25 | static int GetStatus(int card, boardInfo *); |
27 | 26 | ||
28 | /* | 27 | /* |
29 | * Process private IOCTL messages (typically from scctrl) | 28 | * Process private IOCTL messages (typically from scctrl) |
@@ -428,7 +427,7 @@ int sc_ioctl(int card, scs_ioctl *data) | |||
428 | return 0; | 427 | return 0; |
429 | } | 428 | } |
430 | 429 | ||
431 | int GetStatus(int card, boardInfo *bi) | 430 | static int GetStatus(int card, boardInfo *bi) |
432 | { | 431 | { |
433 | RspMessage rcvmsg; | 432 | RspMessage rcvmsg; |
434 | int i, status; | 433 | int i, status; |
diff --git a/drivers/isdn/sc/packet.c b/drivers/isdn/sc/packet.c index 8e3fac3ba1a1..f50defc38ae5 100644 --- a/drivers/isdn/sc/packet.c +++ b/drivers/isdn/sc/packet.c | |||
@@ -213,19 +213,3 @@ int setup_buffers(int card, int c) | |||
213 | return 0; | 213 | return 0; |
214 | } | 214 | } |
215 | 215 | ||
216 | int print_skb(int card,char *skb_p, int len){ | ||
217 | int i,data; | ||
218 | pr_debug("%s: data at 0x%x len: 0x%x\n", sc_adapter[card]->devicename, | ||
219 | skb_p,len); | ||
220 | for(i=1;i<=len;i++,skb_p++){ | ||
221 | data = (int) (0xff & (*skb_p)); | ||
222 | pr_debug("%s: data = 0x%x", sc_adapter[card]->devicename,data); | ||
223 | if(!(i%4)) | ||
224 | pr_debug(" "); | ||
225 | if(!(i%32)) | ||
226 | pr_debug("\n"); | ||
227 | } | ||
228 | pr_debug("\n"); | ||
229 | return 0; | ||
230 | } | ||
231 | |||
diff --git a/drivers/isdn/sc/shmem.c b/drivers/isdn/sc/shmem.c index 7bc2dfad0775..24854826ca45 100644 --- a/drivers/isdn/sc/shmem.c +++ b/drivers/isdn/sc/shmem.c | |||
@@ -108,6 +108,7 @@ void memcpy_fromshmem(int card, void *dest, const void *src, size_t n) | |||
108 | sc_adapter[card]->rambase + ((unsigned long) src %0x4000), (unsigned long) dest); */ | 108 | sc_adapter[card]->rambase + ((unsigned long) src %0x4000), (unsigned long) dest); */ |
109 | } | 109 | } |
110 | 110 | ||
111 | #if 0 | ||
111 | void memset_shmem(int card, void *dest, int c, size_t n) | 112 | void memset_shmem(int card, void *dest, int c, size_t n) |
112 | { | 113 | { |
113 | unsigned long flags; | 114 | unsigned long flags; |
@@ -141,3 +142,4 @@ void memset_shmem(int card, void *dest, int c, size_t n) | |||
141 | ((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80); | 142 | ((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80); |
142 | spin_unlock_irqrestore(&sc_adapter[card]->lock, flags); | 143 | spin_unlock_irqrestore(&sc_adapter[card]->lock, flags); |
143 | } | 144 | } |
145 | #endif /* 0 */ | ||
diff --git a/drivers/isdn/sc/timer.c b/drivers/isdn/sc/timer.c index 710d0f47ca35..aced19aac5a2 100644 --- a/drivers/isdn/sc/timer.c +++ b/drivers/isdn/sc/timer.c | |||
@@ -32,7 +32,7 @@ extern int sendmessage(int, unsigned int, unsigned int, unsigned int, | |||
32 | /* | 32 | /* |
33 | * Write the proper values into the I/O ports following a reset | 33 | * Write the proper values into the I/O ports following a reset |
34 | */ | 34 | */ |
35 | void setup_ports(int card) | 35 | static void setup_ports(int card) |
36 | { | 36 | { |
37 | 37 | ||
38 | outb((sc_adapter[card]->rambase >> 12), sc_adapter[card]->ioport[EXP_BASE]); | 38 | outb((sc_adapter[card]->rambase >> 12), sc_adapter[card]->ioport[EXP_BASE]); |
@@ -129,19 +129,3 @@ void check_phystat(unsigned long data) | |||
129 | ceReqPhyStatus,0,0,NULL); | 129 | ceReqPhyStatus,0,0,NULL); |
130 | } | 130 | } |
131 | 131 | ||
132 | /* | ||
133 | * When in trace mode, this callback is used to swap the working shared | ||
134 | * RAM page to the trace page(s) and process all received messages. It | ||
135 | * must be called often enough to get all of the messages out of RAM before | ||
136 | * it loops around. | ||
137 | * Trace messages are \n terminated strings. | ||
138 | * We output the messages in 64 byte chunks through readstat. Each chunk | ||
139 | * is scanned for a \n followed by a time stamp. If the timerstamp is older | ||
140 | * than the current time, scanning stops and the page and offset are recorded | ||
141 | * as the starting point the next time the trace timer is called. The final | ||
142 | * step is to restore the working page and reset the timer. | ||
143 | */ | ||
144 | void trace_timer(unsigned long data) | ||
145 | { | ||
146 | /* not implemented */ | ||
147 | } | ||
diff --git a/drivers/mca/mca-legacy.c b/drivers/mca/mca-legacy.c index af56313ba0af..0c7bfa74c8ef 100644 --- a/drivers/mca/mca-legacy.c +++ b/drivers/mca/mca-legacy.c | |||
@@ -180,7 +180,6 @@ struct mca_device *mca_find_device_by_slot(int slot) | |||
180 | 180 | ||
181 | return info.mca_dev; | 181 | return info.mca_dev; |
182 | } | 182 | } |
183 | EXPORT_SYMBOL(mca_find_device_by_slot); | ||
184 | 183 | ||
185 | /** | 184 | /** |
186 | * mca_read_stored_pos - read POS register from boot data | 185 | * mca_read_stored_pos - read POS register from boot data |
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index ac0dc27bb38f..867e988a5a93 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h | |||
@@ -435,7 +435,6 @@ struct cx8802_dev { | |||
435 | /* ----------------------------------------------------------- */ | 435 | /* ----------------------------------------------------------- */ |
436 | /* cx88-core.c */ | 436 | /* cx88-core.c */ |
437 | 437 | ||
438 | extern char *cx88_pci_irqs[32]; | ||
439 | extern char *cx88_vid_irqs[32]; | 438 | extern char *cx88_vid_irqs[32]; |
440 | extern char *cx88_mpeg_irqs[32]; | 439 | extern char *cx88_mpeg_irqs[32]; |
441 | extern void cx88_print_irqbits(char *name, char *tag, char **strings, | 440 | extern void cx88_print_irqbits(char *name, char *tag, char **strings, |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index a0b8848049c9..7e371b1209a1 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -66,8 +66,8 @@ | |||
66 | 66 | ||
67 | #define DRV_MODULE_NAME "tg3" | 67 | #define DRV_MODULE_NAME "tg3" |
68 | #define PFX DRV_MODULE_NAME ": " | 68 | #define PFX DRV_MODULE_NAME ": " |
69 | #define DRV_MODULE_VERSION "3.31" | 69 | #define DRV_MODULE_VERSION "3.32" |
70 | #define DRV_MODULE_RELDATE "June 8, 2005" | 70 | #define DRV_MODULE_RELDATE "June 24, 2005" |
71 | 71 | ||
72 | #define TG3_DEF_MAC_MODE 0 | 72 | #define TG3_DEF_MAC_MODE 0 |
73 | #define TG3_DEF_RX_MODE 0 | 73 | #define TG3_DEF_RX_MODE 0 |
@@ -337,12 +337,10 @@ static struct { | |||
337 | static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val) | 337 | static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val) |
338 | { | 338 | { |
339 | if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) { | 339 | if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) { |
340 | unsigned long flags; | 340 | spin_lock_bh(&tp->indirect_lock); |
341 | |||
342 | spin_lock_irqsave(&tp->indirect_lock, flags); | ||
343 | pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off); | 341 | pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off); |
344 | pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val); | 342 | pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val); |
345 | spin_unlock_irqrestore(&tp->indirect_lock, flags); | 343 | spin_unlock_bh(&tp->indirect_lock); |
346 | } else { | 344 | } else { |
347 | writel(val, tp->regs + off); | 345 | writel(val, tp->regs + off); |
348 | if ((tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) != 0) | 346 | if ((tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) != 0) |
@@ -353,12 +351,10 @@ static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val) | |||
353 | static void _tw32_flush(struct tg3 *tp, u32 off, u32 val) | 351 | static void _tw32_flush(struct tg3 *tp, u32 off, u32 val) |
354 | { | 352 | { |
355 | if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) { | 353 | if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) { |
356 | unsigned long flags; | 354 | spin_lock_bh(&tp->indirect_lock); |
357 | |||
358 | spin_lock_irqsave(&tp->indirect_lock, flags); | ||
359 | pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off); | 355 | pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off); |
360 | pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val); | 356 | pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val); |
361 | spin_unlock_irqrestore(&tp->indirect_lock, flags); | 357 | spin_unlock_bh(&tp->indirect_lock); |
362 | } else { | 358 | } else { |
363 | void __iomem *dest = tp->regs + off; | 359 | void __iomem *dest = tp->regs + off; |
364 | writel(val, dest); | 360 | writel(val, dest); |
@@ -398,28 +394,24 @@ static inline void _tw32_tx_mbox(struct tg3 *tp, u32 off, u32 val) | |||
398 | 394 | ||
399 | static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val) | 395 | static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val) |
400 | { | 396 | { |
401 | unsigned long flags; | 397 | spin_lock_bh(&tp->indirect_lock); |
402 | |||
403 | spin_lock_irqsave(&tp->indirect_lock, flags); | ||
404 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); | 398 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); |
405 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); | 399 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); |
406 | 400 | ||
407 | /* Always leave this as zero. */ | 401 | /* Always leave this as zero. */ |
408 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); | 402 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); |
409 | spin_unlock_irqrestore(&tp->indirect_lock, flags); | 403 | spin_unlock_bh(&tp->indirect_lock); |
410 | } | 404 | } |
411 | 405 | ||
412 | static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) | 406 | static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) |
413 | { | 407 | { |
414 | unsigned long flags; | 408 | spin_lock_bh(&tp->indirect_lock); |
415 | |||
416 | spin_lock_irqsave(&tp->indirect_lock, flags); | ||
417 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); | 409 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); |
418 | pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); | 410 | pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); |
419 | 411 | ||
420 | /* Always leave this as zero. */ | 412 | /* Always leave this as zero. */ |
421 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); | 413 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); |
422 | spin_unlock_irqrestore(&tp->indirect_lock, flags); | 414 | spin_unlock_bh(&tp->indirect_lock); |
423 | } | 415 | } |
424 | 416 | ||
425 | static void tg3_disable_ints(struct tg3 *tp) | 417 | static void tg3_disable_ints(struct tg3 *tp) |
@@ -438,12 +430,14 @@ static inline void tg3_cond_int(struct tg3 *tp) | |||
438 | 430 | ||
439 | static void tg3_enable_ints(struct tg3 *tp) | 431 | static void tg3_enable_ints(struct tg3 *tp) |
440 | { | 432 | { |
433 | tp->irq_sync = 0; | ||
434 | wmb(); | ||
435 | |||
441 | tw32(TG3PCI_MISC_HOST_CTRL, | 436 | tw32(TG3PCI_MISC_HOST_CTRL, |
442 | (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT)); | 437 | (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT)); |
443 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, | 438 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, |
444 | (tp->last_tag << 24)); | 439 | (tp->last_tag << 24)); |
445 | tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); | 440 | tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); |
446 | |||
447 | tg3_cond_int(tp); | 441 | tg3_cond_int(tp); |
448 | } | 442 | } |
449 | 443 | ||
@@ -492,6 +486,7 @@ static void tg3_restart_ints(struct tg3 *tp) | |||
492 | 486 | ||
493 | static inline void tg3_netif_stop(struct tg3 *tp) | 487 | static inline void tg3_netif_stop(struct tg3 *tp) |
494 | { | 488 | { |
489 | tp->dev->trans_start = jiffies; /* prevent tx timeout */ | ||
495 | netif_poll_disable(tp->dev); | 490 | netif_poll_disable(tp->dev); |
496 | netif_tx_disable(tp->dev); | 491 | netif_tx_disable(tp->dev); |
497 | } | 492 | } |
@@ -504,7 +499,8 @@ static inline void tg3_netif_start(struct tg3 *tp) | |||
504 | * (such as after tg3_init_hw) | 499 | * (such as after tg3_init_hw) |
505 | */ | 500 | */ |
506 | netif_poll_enable(tp->dev); | 501 | netif_poll_enable(tp->dev); |
507 | tg3_cond_int(tp); | 502 | tp->hw_status->status |= SD_STATUS_UPDATED; |
503 | tg3_enable_ints(tp); | ||
508 | } | 504 | } |
509 | 505 | ||
510 | static void tg3_switch_clocks(struct tg3 *tp) | 506 | static void tg3_switch_clocks(struct tg3 *tp) |
@@ -2578,7 +2574,7 @@ static void tg3_tx(struct tg3 *tp) | |||
2578 | sw_idx = NEXT_TX(sw_idx); | 2574 | sw_idx = NEXT_TX(sw_idx); |
2579 | } | 2575 | } |
2580 | 2576 | ||
2581 | dev_kfree_skb_irq(skb); | 2577 | dev_kfree_skb(skb); |
2582 | } | 2578 | } |
2583 | 2579 | ||
2584 | tp->tx_cons = sw_idx; | 2580 | tp->tx_cons = sw_idx; |
@@ -2884,11 +2880,8 @@ static int tg3_poll(struct net_device *netdev, int *budget) | |||
2884 | { | 2880 | { |
2885 | struct tg3 *tp = netdev_priv(netdev); | 2881 | struct tg3 *tp = netdev_priv(netdev); |
2886 | struct tg3_hw_status *sblk = tp->hw_status; | 2882 | struct tg3_hw_status *sblk = tp->hw_status; |
2887 | unsigned long flags; | ||
2888 | int done; | 2883 | int done; |
2889 | 2884 | ||
2890 | spin_lock_irqsave(&tp->lock, flags); | ||
2891 | |||
2892 | /* handle link change and other phy events */ | 2885 | /* handle link change and other phy events */ |
2893 | if (!(tp->tg3_flags & | 2886 | if (!(tp->tg3_flags & |
2894 | (TG3_FLAG_USE_LINKCHG_REG | | 2887 | (TG3_FLAG_USE_LINKCHG_REG | |
@@ -2896,7 +2889,9 @@ static int tg3_poll(struct net_device *netdev, int *budget) | |||
2896 | if (sblk->status & SD_STATUS_LINK_CHG) { | 2889 | if (sblk->status & SD_STATUS_LINK_CHG) { |
2897 | sblk->status = SD_STATUS_UPDATED | | 2890 | sblk->status = SD_STATUS_UPDATED | |
2898 | (sblk->status & ~SD_STATUS_LINK_CHG); | 2891 | (sblk->status & ~SD_STATUS_LINK_CHG); |
2892 | spin_lock(&tp->lock); | ||
2899 | tg3_setup_phy(tp, 0); | 2893 | tg3_setup_phy(tp, 0); |
2894 | spin_unlock(&tp->lock); | ||
2900 | } | 2895 | } |
2901 | } | 2896 | } |
2902 | 2897 | ||
@@ -2907,8 +2902,6 @@ static int tg3_poll(struct net_device *netdev, int *budget) | |||
2907 | spin_unlock(&tp->tx_lock); | 2902 | spin_unlock(&tp->tx_lock); |
2908 | } | 2903 | } |
2909 | 2904 | ||
2910 | spin_unlock_irqrestore(&tp->lock, flags); | ||
2911 | |||
2912 | /* run RX thread, within the bounds set by NAPI. | 2905 | /* run RX thread, within the bounds set by NAPI. |
2913 | * All RX "locking" is done by ensuring outside | 2906 | * All RX "locking" is done by ensuring outside |
2914 | * code synchronizes with dev->poll() | 2907 | * code synchronizes with dev->poll() |
@@ -2929,19 +2922,54 @@ static int tg3_poll(struct net_device *netdev, int *budget) | |||
2929 | if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) | 2922 | if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) |
2930 | tp->last_tag = sblk->status_tag; | 2923 | tp->last_tag = sblk->status_tag; |
2931 | rmb(); | 2924 | rmb(); |
2925 | sblk->status &= ~SD_STATUS_UPDATED; | ||
2932 | 2926 | ||
2933 | /* if no more work, tell net stack and NIC we're done */ | 2927 | /* if no more work, tell net stack and NIC we're done */ |
2934 | done = !tg3_has_work(tp); | 2928 | done = !tg3_has_work(tp); |
2935 | if (done) { | 2929 | if (done) { |
2936 | spin_lock_irqsave(&tp->lock, flags); | 2930 | spin_lock(&tp->lock); |
2937 | __netif_rx_complete(netdev); | 2931 | netif_rx_complete(netdev); |
2938 | tg3_restart_ints(tp); | 2932 | tg3_restart_ints(tp); |
2939 | spin_unlock_irqrestore(&tp->lock, flags); | 2933 | spin_unlock(&tp->lock); |
2940 | } | 2934 | } |
2941 | 2935 | ||
2942 | return (done ? 0 : 1); | 2936 | return (done ? 0 : 1); |
2943 | } | 2937 | } |
2944 | 2938 | ||
2939 | static void tg3_irq_quiesce(struct tg3 *tp) | ||
2940 | { | ||
2941 | BUG_ON(tp->irq_sync); | ||
2942 | |||
2943 | tp->irq_sync = 1; | ||
2944 | smp_mb(); | ||
2945 | |||
2946 | synchronize_irq(tp->pdev->irq); | ||
2947 | } | ||
2948 | |||
2949 | static inline int tg3_irq_sync(struct tg3 *tp) | ||
2950 | { | ||
2951 | return tp->irq_sync; | ||
2952 | } | ||
2953 | |||
2954 | /* Fully shutdown all tg3 driver activity elsewhere in the system. | ||
2955 | * If irq_sync is non-zero, then the IRQ handler must be synchronized | ||
2956 | * with as well. Most of the time, this is not necessary except when | ||
2957 | * shutting down the device. | ||
2958 | */ | ||
2959 | static inline void tg3_full_lock(struct tg3 *tp, int irq_sync) | ||
2960 | { | ||
2961 | if (irq_sync) | ||
2962 | tg3_irq_quiesce(tp); | ||
2963 | spin_lock_bh(&tp->lock); | ||
2964 | spin_lock(&tp->tx_lock); | ||
2965 | } | ||
2966 | |||
2967 | static inline void tg3_full_unlock(struct tg3 *tp) | ||
2968 | { | ||
2969 | spin_unlock(&tp->tx_lock); | ||
2970 | spin_unlock_bh(&tp->lock); | ||
2971 | } | ||
2972 | |||
2945 | /* MSI ISR - No need to check for interrupt sharing and no need to | 2973 | /* MSI ISR - No need to check for interrupt sharing and no need to |
2946 | * flush status block and interrupt mailbox. PCI ordering rules | 2974 | * flush status block and interrupt mailbox. PCI ordering rules |
2947 | * guarantee that MSI will arrive after the status block. | 2975 | * guarantee that MSI will arrive after the status block. |
@@ -2951,9 +2979,6 @@ static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs) | |||
2951 | struct net_device *dev = dev_id; | 2979 | struct net_device *dev = dev_id; |
2952 | struct tg3 *tp = netdev_priv(dev); | 2980 | struct tg3 *tp = netdev_priv(dev); |
2953 | struct tg3_hw_status *sblk = tp->hw_status; | 2981 | struct tg3_hw_status *sblk = tp->hw_status; |
2954 | unsigned long flags; | ||
2955 | |||
2956 | spin_lock_irqsave(&tp->lock, flags); | ||
2957 | 2982 | ||
2958 | /* | 2983 | /* |
2959 | * Writing any value to intr-mbox-0 clears PCI INTA# and | 2984 | * Writing any value to intr-mbox-0 clears PCI INTA# and |
@@ -2964,6 +2989,9 @@ static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs) | |||
2964 | */ | 2989 | */ |
2965 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); | 2990 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); |
2966 | tp->last_tag = sblk->status_tag; | 2991 | tp->last_tag = sblk->status_tag; |
2992 | rmb(); | ||
2993 | if (tg3_irq_sync(tp)) | ||
2994 | goto out; | ||
2967 | sblk->status &= ~SD_STATUS_UPDATED; | 2995 | sblk->status &= ~SD_STATUS_UPDATED; |
2968 | if (likely(tg3_has_work(tp))) | 2996 | if (likely(tg3_has_work(tp))) |
2969 | netif_rx_schedule(dev); /* schedule NAPI poll */ | 2997 | netif_rx_schedule(dev); /* schedule NAPI poll */ |
@@ -2972,9 +3000,7 @@ static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs) | |||
2972 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, | 3000 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, |
2973 | tp->last_tag << 24); | 3001 | tp->last_tag << 24); |
2974 | } | 3002 | } |
2975 | 3003 | out: | |
2976 | spin_unlock_irqrestore(&tp->lock, flags); | ||
2977 | |||
2978 | return IRQ_RETVAL(1); | 3004 | return IRQ_RETVAL(1); |
2979 | } | 3005 | } |
2980 | 3006 | ||
@@ -2983,11 +3009,8 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
2983 | struct net_device *dev = dev_id; | 3009 | struct net_device *dev = dev_id; |
2984 | struct tg3 *tp = netdev_priv(dev); | 3010 | struct tg3 *tp = netdev_priv(dev); |
2985 | struct tg3_hw_status *sblk = tp->hw_status; | 3011 | struct tg3_hw_status *sblk = tp->hw_status; |
2986 | unsigned long flags; | ||
2987 | unsigned int handled = 1; | 3012 | unsigned int handled = 1; |
2988 | 3013 | ||
2989 | spin_lock_irqsave(&tp->lock, flags); | ||
2990 | |||
2991 | /* In INTx mode, it is possible for the interrupt to arrive at | 3014 | /* In INTx mode, it is possible for the interrupt to arrive at |
2992 | * the CPU before the status block posted prior to the interrupt. | 3015 | * the CPU before the status block posted prior to the interrupt. |
2993 | * Reading the PCI State register will confirm whether the | 3016 | * Reading the PCI State register will confirm whether the |
@@ -3004,6 +3027,8 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
3004 | */ | 3027 | */ |
3005 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, | 3028 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, |
3006 | 0x00000001); | 3029 | 0x00000001); |
3030 | if (tg3_irq_sync(tp)) | ||
3031 | goto out; | ||
3007 | sblk->status &= ~SD_STATUS_UPDATED; | 3032 | sblk->status &= ~SD_STATUS_UPDATED; |
3008 | if (likely(tg3_has_work(tp))) | 3033 | if (likely(tg3_has_work(tp))) |
3009 | netif_rx_schedule(dev); /* schedule NAPI poll */ | 3034 | netif_rx_schedule(dev); /* schedule NAPI poll */ |
@@ -3018,9 +3043,7 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
3018 | } else { /* shared interrupt */ | 3043 | } else { /* shared interrupt */ |
3019 | handled = 0; | 3044 | handled = 0; |
3020 | } | 3045 | } |
3021 | 3046 | out: | |
3022 | spin_unlock_irqrestore(&tp->lock, flags); | ||
3023 | |||
3024 | return IRQ_RETVAL(handled); | 3047 | return IRQ_RETVAL(handled); |
3025 | } | 3048 | } |
3026 | 3049 | ||
@@ -3029,11 +3052,8 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *r | |||
3029 | struct net_device *dev = dev_id; | 3052 | struct net_device *dev = dev_id; |
3030 | struct tg3 *tp = netdev_priv(dev); | 3053 | struct tg3 *tp = netdev_priv(dev); |
3031 | struct tg3_hw_status *sblk = tp->hw_status; | 3054 | struct tg3_hw_status *sblk = tp->hw_status; |
3032 | unsigned long flags; | ||
3033 | unsigned int handled = 1; | 3055 | unsigned int handled = 1; |
3034 | 3056 | ||
3035 | spin_lock_irqsave(&tp->lock, flags); | ||
3036 | |||
3037 | /* In INTx mode, it is possible for the interrupt to arrive at | 3057 | /* In INTx mode, it is possible for the interrupt to arrive at |
3038 | * the CPU before the status block posted prior to the interrupt. | 3058 | * the CPU before the status block posted prior to the interrupt. |
3039 | * Reading the PCI State register will confirm whether the | 3059 | * Reading the PCI State register will confirm whether the |
@@ -3051,6 +3071,9 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *r | |||
3051 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, | 3071 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, |
3052 | 0x00000001); | 3072 | 0x00000001); |
3053 | tp->last_tag = sblk->status_tag; | 3073 | tp->last_tag = sblk->status_tag; |
3074 | rmb(); | ||
3075 | if (tg3_irq_sync(tp)) | ||
3076 | goto out; | ||
3054 | sblk->status &= ~SD_STATUS_UPDATED; | 3077 | sblk->status &= ~SD_STATUS_UPDATED; |
3055 | if (likely(tg3_has_work(tp))) | 3078 | if (likely(tg3_has_work(tp))) |
3056 | netif_rx_schedule(dev); /* schedule NAPI poll */ | 3079 | netif_rx_schedule(dev); /* schedule NAPI poll */ |
@@ -3065,9 +3088,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *r | |||
3065 | } else { /* shared interrupt */ | 3088 | } else { /* shared interrupt */ |
3066 | handled = 0; | 3089 | handled = 0; |
3067 | } | 3090 | } |
3068 | 3091 | out: | |
3069 | spin_unlock_irqrestore(&tp->lock, flags); | ||
3070 | |||
3071 | return IRQ_RETVAL(handled); | 3092 | return IRQ_RETVAL(handled); |
3072 | } | 3093 | } |
3073 | 3094 | ||
@@ -3106,8 +3127,7 @@ static void tg3_reset_task(void *_data) | |||
3106 | 3127 | ||
3107 | tg3_netif_stop(tp); | 3128 | tg3_netif_stop(tp); |
3108 | 3129 | ||
3109 | spin_lock_irq(&tp->lock); | 3130 | tg3_full_lock(tp, 1); |
3110 | spin_lock(&tp->tx_lock); | ||
3111 | 3131 | ||
3112 | restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER; | 3132 | restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER; |
3113 | tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER; | 3133 | tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER; |
@@ -3117,8 +3137,7 @@ static void tg3_reset_task(void *_data) | |||
3117 | 3137 | ||
3118 | tg3_netif_start(tp); | 3138 | tg3_netif_start(tp); |
3119 | 3139 | ||
3120 | spin_unlock(&tp->tx_lock); | 3140 | tg3_full_unlock(tp); |
3121 | spin_unlock_irq(&tp->lock); | ||
3122 | 3141 | ||
3123 | if (restart_timer) | 3142 | if (restart_timer) |
3124 | mod_timer(&tp->timer, jiffies + 1); | 3143 | mod_timer(&tp->timer, jiffies + 1); |
@@ -3224,39 +3243,21 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3224 | unsigned int i; | 3243 | unsigned int i; |
3225 | u32 len, entry, base_flags, mss; | 3244 | u32 len, entry, base_flags, mss; |
3226 | int would_hit_hwbug; | 3245 | int would_hit_hwbug; |
3227 | unsigned long flags; | ||
3228 | 3246 | ||
3229 | len = skb_headlen(skb); | 3247 | len = skb_headlen(skb); |
3230 | 3248 | ||
3231 | /* No BH disabling for tx_lock here. We are running in BH disabled | 3249 | /* No BH disabling for tx_lock here. We are running in BH disabled |
3232 | * context and TX reclaim runs via tp->poll inside of a software | 3250 | * context and TX reclaim runs via tp->poll inside of a software |
3233 | * interrupt. Rejoice! | 3251 | * interrupt. Furthermore, IRQ processing runs lockless so we have |
3234 | * | 3252 | * no IRQ context deadlocks to worry about either. Rejoice! |
3235 | * Actually, things are not so simple. If we are to take a hw | ||
3236 | * IRQ here, we can deadlock, consider: | ||
3237 | * | ||
3238 | * CPU1 CPU2 | ||
3239 | * tg3_start_xmit | ||
3240 | * take tp->tx_lock | ||
3241 | * tg3_timer | ||
3242 | * take tp->lock | ||
3243 | * tg3_interrupt | ||
3244 | * spin on tp->lock | ||
3245 | * spin on tp->tx_lock | ||
3246 | * | ||
3247 | * So we really do need to disable interrupts when taking | ||
3248 | * tx_lock here. | ||
3249 | */ | 3253 | */ |
3250 | local_irq_save(flags); | 3254 | if (!spin_trylock(&tp->tx_lock)) |
3251 | if (!spin_trylock(&tp->tx_lock)) { | ||
3252 | local_irq_restore(flags); | ||
3253 | return NETDEV_TX_LOCKED; | 3255 | return NETDEV_TX_LOCKED; |
3254 | } | ||
3255 | 3256 | ||
3256 | /* This is a hard error, log it. */ | 3257 | /* This is a hard error, log it. */ |
3257 | if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) { | 3258 | if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) { |
3258 | netif_stop_queue(dev); | 3259 | netif_stop_queue(dev); |
3259 | spin_unlock_irqrestore(&tp->tx_lock, flags); | 3260 | spin_unlock(&tp->tx_lock); |
3260 | printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n", | 3261 | printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n", |
3261 | dev->name); | 3262 | dev->name); |
3262 | return NETDEV_TX_BUSY; | 3263 | return NETDEV_TX_BUSY; |
@@ -3421,7 +3422,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3421 | 3422 | ||
3422 | out_unlock: | 3423 | out_unlock: |
3423 | mmiowb(); | 3424 | mmiowb(); |
3424 | spin_unlock_irqrestore(&tp->tx_lock, flags); | 3425 | spin_unlock(&tp->tx_lock); |
3425 | 3426 | ||
3426 | dev->trans_start = jiffies; | 3427 | dev->trans_start = jiffies; |
3427 | 3428 | ||
@@ -3455,8 +3456,8 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) | |||
3455 | } | 3456 | } |
3456 | 3457 | ||
3457 | tg3_netif_stop(tp); | 3458 | tg3_netif_stop(tp); |
3458 | spin_lock_irq(&tp->lock); | 3459 | |
3459 | spin_lock(&tp->tx_lock); | 3460 | tg3_full_lock(tp, 1); |
3460 | 3461 | ||
3461 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | 3462 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
3462 | 3463 | ||
@@ -3466,8 +3467,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) | |||
3466 | 3467 | ||
3467 | tg3_netif_start(tp); | 3468 | tg3_netif_start(tp); |
3468 | 3469 | ||
3469 | spin_unlock(&tp->tx_lock); | 3470 | tg3_full_unlock(tp); |
3470 | spin_unlock_irq(&tp->lock); | ||
3471 | 3471 | ||
3472 | return 0; | 3472 | return 0; |
3473 | } | 3473 | } |
@@ -5088,9 +5088,9 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p) | |||
5088 | 5088 | ||
5089 | memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); | 5089 | memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); |
5090 | 5090 | ||
5091 | spin_lock_irq(&tp->lock); | 5091 | spin_lock_bh(&tp->lock); |
5092 | __tg3_set_mac_addr(tp); | 5092 | __tg3_set_mac_addr(tp); |
5093 | spin_unlock_irq(&tp->lock); | 5093 | spin_unlock_bh(&tp->lock); |
5094 | 5094 | ||
5095 | return 0; | 5095 | return 0; |
5096 | } | 5096 | } |
@@ -5727,9 +5727,6 @@ static int tg3_reset_hw(struct tg3 *tp) | |||
5727 | 5727 | ||
5728 | tg3_write_sig_post_reset(tp, RESET_KIND_INIT); | 5728 | tg3_write_sig_post_reset(tp, RESET_KIND_INIT); |
5729 | 5729 | ||
5730 | if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) | ||
5731 | tg3_enable_ints(tp); | ||
5732 | |||
5733 | return 0; | 5730 | return 0; |
5734 | } | 5731 | } |
5735 | 5732 | ||
@@ -5802,10 +5799,8 @@ static void tg3_periodic_fetch_stats(struct tg3 *tp) | |||
5802 | static void tg3_timer(unsigned long __opaque) | 5799 | static void tg3_timer(unsigned long __opaque) |
5803 | { | 5800 | { |
5804 | struct tg3 *tp = (struct tg3 *) __opaque; | 5801 | struct tg3 *tp = (struct tg3 *) __opaque; |
5805 | unsigned long flags; | ||
5806 | 5802 | ||
5807 | spin_lock_irqsave(&tp->lock, flags); | 5803 | spin_lock(&tp->lock); |
5808 | spin_lock(&tp->tx_lock); | ||
5809 | 5804 | ||
5810 | if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) { | 5805 | if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) { |
5811 | /* All of this garbage is because when using non-tagged | 5806 | /* All of this garbage is because when using non-tagged |
@@ -5822,8 +5817,7 @@ static void tg3_timer(unsigned long __opaque) | |||
5822 | 5817 | ||
5823 | if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { | 5818 | if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { |
5824 | tp->tg3_flags2 |= TG3_FLG2_RESTART_TIMER; | 5819 | tp->tg3_flags2 |= TG3_FLG2_RESTART_TIMER; |
5825 | spin_unlock(&tp->tx_lock); | 5820 | spin_unlock(&tp->lock); |
5826 | spin_unlock_irqrestore(&tp->lock, flags); | ||
5827 | schedule_work(&tp->reset_task); | 5821 | schedule_work(&tp->reset_task); |
5828 | return; | 5822 | return; |
5829 | } | 5823 | } |
@@ -5891,8 +5885,7 @@ static void tg3_timer(unsigned long __opaque) | |||
5891 | tp->asf_counter = tp->asf_multiplier; | 5885 | tp->asf_counter = tp->asf_multiplier; |
5892 | } | 5886 | } |
5893 | 5887 | ||
5894 | spin_unlock(&tp->tx_lock); | 5888 | spin_unlock(&tp->lock); |
5895 | spin_unlock_irqrestore(&tp->lock, flags); | ||
5896 | 5889 | ||
5897 | tp->timer.expires = jiffies + tp->timer_offset; | 5890 | tp->timer.expires = jiffies + tp->timer_offset; |
5898 | add_timer(&tp->timer); | 5891 | add_timer(&tp->timer); |
@@ -6007,14 +6000,12 @@ static int tg3_test_msi(struct tg3 *tp) | |||
6007 | /* Need to reset the chip because the MSI cycle may have terminated | 6000 | /* Need to reset the chip because the MSI cycle may have terminated |
6008 | * with Master Abort. | 6001 | * with Master Abort. |
6009 | */ | 6002 | */ |
6010 | spin_lock_irq(&tp->lock); | 6003 | tg3_full_lock(tp, 1); |
6011 | spin_lock(&tp->tx_lock); | ||
6012 | 6004 | ||
6013 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | 6005 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
6014 | err = tg3_init_hw(tp); | 6006 | err = tg3_init_hw(tp); |
6015 | 6007 | ||
6016 | spin_unlock(&tp->tx_lock); | 6008 | tg3_full_unlock(tp); |
6017 | spin_unlock_irq(&tp->lock); | ||
6018 | 6009 | ||
6019 | if (err) | 6010 | if (err) |
6020 | free_irq(tp->pdev->irq, dev); | 6011 | free_irq(tp->pdev->irq, dev); |
@@ -6027,14 +6018,12 @@ static int tg3_open(struct net_device *dev) | |||
6027 | struct tg3 *tp = netdev_priv(dev); | 6018 | struct tg3 *tp = netdev_priv(dev); |
6028 | int err; | 6019 | int err; |
6029 | 6020 | ||
6030 | spin_lock_irq(&tp->lock); | 6021 | tg3_full_lock(tp, 0); |
6031 | spin_lock(&tp->tx_lock); | ||
6032 | 6022 | ||
6033 | tg3_disable_ints(tp); | 6023 | tg3_disable_ints(tp); |
6034 | tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE; | 6024 | tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE; |
6035 | 6025 | ||
6036 | spin_unlock(&tp->tx_lock); | 6026 | tg3_full_unlock(tp); |
6037 | spin_unlock_irq(&tp->lock); | ||
6038 | 6027 | ||
6039 | /* The placement of this call is tied | 6028 | /* The placement of this call is tied |
6040 | * to the setup and use of Host TX descriptors. | 6029 | * to the setup and use of Host TX descriptors. |
@@ -6081,8 +6070,7 @@ static int tg3_open(struct net_device *dev) | |||
6081 | return err; | 6070 | return err; |
6082 | } | 6071 | } |
6083 | 6072 | ||
6084 | spin_lock_irq(&tp->lock); | 6073 | tg3_full_lock(tp, 0); |
6085 | spin_lock(&tp->tx_lock); | ||
6086 | 6074 | ||
6087 | err = tg3_init_hw(tp); | 6075 | err = tg3_init_hw(tp); |
6088 | if (err) { | 6076 | if (err) { |
@@ -6106,8 +6094,7 @@ static int tg3_open(struct net_device *dev) | |||
6106 | tp->timer.function = tg3_timer; | 6094 | tp->timer.function = tg3_timer; |
6107 | } | 6095 | } |
6108 | 6096 | ||
6109 | spin_unlock(&tp->tx_lock); | 6097 | tg3_full_unlock(tp); |
6110 | spin_unlock_irq(&tp->lock); | ||
6111 | 6098 | ||
6112 | if (err) { | 6099 | if (err) { |
6113 | free_irq(tp->pdev->irq, dev); | 6100 | free_irq(tp->pdev->irq, dev); |
@@ -6123,8 +6110,7 @@ static int tg3_open(struct net_device *dev) | |||
6123 | err = tg3_test_msi(tp); | 6110 | err = tg3_test_msi(tp); |
6124 | 6111 | ||
6125 | if (err) { | 6112 | if (err) { |
6126 | spin_lock_irq(&tp->lock); | 6113 | tg3_full_lock(tp, 0); |
6127 | spin_lock(&tp->tx_lock); | ||
6128 | 6114 | ||
6129 | if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) { | 6115 | if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) { |
6130 | pci_disable_msi(tp->pdev); | 6116 | pci_disable_msi(tp->pdev); |
@@ -6134,22 +6120,19 @@ static int tg3_open(struct net_device *dev) | |||
6134 | tg3_free_rings(tp); | 6120 | tg3_free_rings(tp); |
6135 | tg3_free_consistent(tp); | 6121 | tg3_free_consistent(tp); |
6136 | 6122 | ||
6137 | spin_unlock(&tp->tx_lock); | 6123 | tg3_full_unlock(tp); |
6138 | spin_unlock_irq(&tp->lock); | ||
6139 | 6124 | ||
6140 | return err; | 6125 | return err; |
6141 | } | 6126 | } |
6142 | } | 6127 | } |
6143 | 6128 | ||
6144 | spin_lock_irq(&tp->lock); | 6129 | tg3_full_lock(tp, 0); |
6145 | spin_lock(&tp->tx_lock); | ||
6146 | 6130 | ||
6147 | add_timer(&tp->timer); | 6131 | add_timer(&tp->timer); |
6148 | tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; | 6132 | tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; |
6149 | tg3_enable_ints(tp); | 6133 | tg3_enable_ints(tp); |
6150 | 6134 | ||
6151 | spin_unlock(&tp->tx_lock); | 6135 | tg3_full_unlock(tp); |
6152 | spin_unlock_irq(&tp->lock); | ||
6153 | 6136 | ||
6154 | netif_start_queue(dev); | 6137 | netif_start_queue(dev); |
6155 | 6138 | ||
@@ -6395,8 +6378,7 @@ static int tg3_close(struct net_device *dev) | |||
6395 | 6378 | ||
6396 | del_timer_sync(&tp->timer); | 6379 | del_timer_sync(&tp->timer); |
6397 | 6380 | ||
6398 | spin_lock_irq(&tp->lock); | 6381 | tg3_full_lock(tp, 1); |
6399 | spin_lock(&tp->tx_lock); | ||
6400 | #if 0 | 6382 | #if 0 |
6401 | tg3_dump_state(tp); | 6383 | tg3_dump_state(tp); |
6402 | #endif | 6384 | #endif |
@@ -6410,8 +6392,7 @@ static int tg3_close(struct net_device *dev) | |||
6410 | TG3_FLAG_GOT_SERDES_FLOWCTL); | 6392 | TG3_FLAG_GOT_SERDES_FLOWCTL); |
6411 | netif_carrier_off(tp->dev); | 6393 | netif_carrier_off(tp->dev); |
6412 | 6394 | ||
6413 | spin_unlock(&tp->tx_lock); | 6395 | tg3_full_unlock(tp); |
6414 | spin_unlock_irq(&tp->lock); | ||
6415 | 6396 | ||
6416 | free_irq(tp->pdev->irq, dev); | 6397 | free_irq(tp->pdev->irq, dev); |
6417 | if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) { | 6398 | if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) { |
@@ -6448,16 +6429,15 @@ static unsigned long calc_crc_errors(struct tg3 *tp) | |||
6448 | if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) && | 6429 | if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) && |
6449 | (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || | 6430 | (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || |
6450 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) { | 6431 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) { |
6451 | unsigned long flags; | ||
6452 | u32 val; | 6432 | u32 val; |
6453 | 6433 | ||
6454 | spin_lock_irqsave(&tp->lock, flags); | 6434 | spin_lock_bh(&tp->lock); |
6455 | if (!tg3_readphy(tp, 0x1e, &val)) { | 6435 | if (!tg3_readphy(tp, 0x1e, &val)) { |
6456 | tg3_writephy(tp, 0x1e, val | 0x8000); | 6436 | tg3_writephy(tp, 0x1e, val | 0x8000); |
6457 | tg3_readphy(tp, 0x14, &val); | 6437 | tg3_readphy(tp, 0x14, &val); |
6458 | } else | 6438 | } else |
6459 | val = 0; | 6439 | val = 0; |
6460 | spin_unlock_irqrestore(&tp->lock, flags); | 6440 | spin_unlock_bh(&tp->lock); |
6461 | 6441 | ||
6462 | tp->phy_crc_errors += val; | 6442 | tp->phy_crc_errors += val; |
6463 | 6443 | ||
@@ -6719,11 +6699,9 @@ static void tg3_set_rx_mode(struct net_device *dev) | |||
6719 | { | 6699 | { |
6720 | struct tg3 *tp = netdev_priv(dev); | 6700 | struct tg3 *tp = netdev_priv(dev); |
6721 | 6701 | ||
6722 | spin_lock_irq(&tp->lock); | 6702 | tg3_full_lock(tp, 0); |
6723 | spin_lock(&tp->tx_lock); | ||
6724 | __tg3_set_rx_mode(dev); | 6703 | __tg3_set_rx_mode(dev); |
6725 | spin_unlock(&tp->tx_lock); | 6704 | tg3_full_unlock(tp); |
6726 | spin_unlock_irq(&tp->lock); | ||
6727 | } | 6705 | } |
6728 | 6706 | ||
6729 | #define TG3_REGDUMP_LEN (32 * 1024) | 6707 | #define TG3_REGDUMP_LEN (32 * 1024) |
@@ -6745,8 +6723,7 @@ static void tg3_get_regs(struct net_device *dev, | |||
6745 | 6723 | ||
6746 | memset(p, 0, TG3_REGDUMP_LEN); | 6724 | memset(p, 0, TG3_REGDUMP_LEN); |
6747 | 6725 | ||
6748 | spin_lock_irq(&tp->lock); | 6726 | tg3_full_lock(tp, 0); |
6749 | spin_lock(&tp->tx_lock); | ||
6750 | 6727 | ||
6751 | #define __GET_REG32(reg) (*(p)++ = tr32(reg)) | 6728 | #define __GET_REG32(reg) (*(p)++ = tr32(reg)) |
6752 | #define GET_REG32_LOOP(base,len) \ | 6729 | #define GET_REG32_LOOP(base,len) \ |
@@ -6796,8 +6773,7 @@ do { p = (u32 *)(orig_p + (reg)); \ | |||
6796 | #undef GET_REG32_LOOP | 6773 | #undef GET_REG32_LOOP |
6797 | #undef GET_REG32_1 | 6774 | #undef GET_REG32_1 |
6798 | 6775 | ||
6799 | spin_unlock(&tp->tx_lock); | 6776 | tg3_full_unlock(tp); |
6800 | spin_unlock_irq(&tp->lock); | ||
6801 | } | 6777 | } |
6802 | 6778 | ||
6803 | static int tg3_get_eeprom_len(struct net_device *dev) | 6779 | static int tg3_get_eeprom_len(struct net_device *dev) |
@@ -6973,8 +6949,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
6973 | return -EINVAL; | 6949 | return -EINVAL; |
6974 | } | 6950 | } |
6975 | 6951 | ||
6976 | spin_lock_irq(&tp->lock); | 6952 | tg3_full_lock(tp, 0); |
6977 | spin_lock(&tp->tx_lock); | ||
6978 | 6953 | ||
6979 | tp->link_config.autoneg = cmd->autoneg; | 6954 | tp->link_config.autoneg = cmd->autoneg; |
6980 | if (cmd->autoneg == AUTONEG_ENABLE) { | 6955 | if (cmd->autoneg == AUTONEG_ENABLE) { |
@@ -6990,8 +6965,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
6990 | if (netif_running(dev)) | 6965 | if (netif_running(dev)) |
6991 | tg3_setup_phy(tp, 1); | 6966 | tg3_setup_phy(tp, 1); |
6992 | 6967 | ||
6993 | spin_unlock(&tp->tx_lock); | 6968 | tg3_full_unlock(tp); |
6994 | spin_unlock_irq(&tp->lock); | ||
6995 | 6969 | ||
6996 | return 0; | 6970 | return 0; |
6997 | } | 6971 | } |
@@ -7027,12 +7001,12 @@ static int tg3_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | |||
7027 | !(tp->tg3_flags & TG3_FLAG_SERDES_WOL_CAP)) | 7001 | !(tp->tg3_flags & TG3_FLAG_SERDES_WOL_CAP)) |
7028 | return -EINVAL; | 7002 | return -EINVAL; |
7029 | 7003 | ||
7030 | spin_lock_irq(&tp->lock); | 7004 | spin_lock_bh(&tp->lock); |
7031 | if (wol->wolopts & WAKE_MAGIC) | 7005 | if (wol->wolopts & WAKE_MAGIC) |
7032 | tp->tg3_flags |= TG3_FLAG_WOL_ENABLE; | 7006 | tp->tg3_flags |= TG3_FLAG_WOL_ENABLE; |
7033 | else | 7007 | else |
7034 | tp->tg3_flags &= ~TG3_FLAG_WOL_ENABLE; | 7008 | tp->tg3_flags &= ~TG3_FLAG_WOL_ENABLE; |
7035 | spin_unlock_irq(&tp->lock); | 7009 | spin_unlock_bh(&tp->lock); |
7036 | 7010 | ||
7037 | return 0; | 7011 | return 0; |
7038 | } | 7012 | } |
@@ -7072,7 +7046,7 @@ static int tg3_nway_reset(struct net_device *dev) | |||
7072 | if (!netif_running(dev)) | 7046 | if (!netif_running(dev)) |
7073 | return -EAGAIN; | 7047 | return -EAGAIN; |
7074 | 7048 | ||
7075 | spin_lock_irq(&tp->lock); | 7049 | spin_lock_bh(&tp->lock); |
7076 | r = -EINVAL; | 7050 | r = -EINVAL; |
7077 | tg3_readphy(tp, MII_BMCR, &bmcr); | 7051 | tg3_readphy(tp, MII_BMCR, &bmcr); |
7078 | if (!tg3_readphy(tp, MII_BMCR, &bmcr) && | 7052 | if (!tg3_readphy(tp, MII_BMCR, &bmcr) && |
@@ -7080,7 +7054,7 @@ static int tg3_nway_reset(struct net_device *dev) | |||
7080 | tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART); | 7054 | tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART); |
7081 | r = 0; | 7055 | r = 0; |
7082 | } | 7056 | } |
7083 | spin_unlock_irq(&tp->lock); | 7057 | spin_unlock_bh(&tp->lock); |
7084 | 7058 | ||
7085 | return r; | 7059 | return r; |
7086 | } | 7060 | } |
@@ -7102,17 +7076,19 @@ static void tg3_get_ringparam(struct net_device *dev, struct ethtool_ringparam * | |||
7102 | static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) | 7076 | static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) |
7103 | { | 7077 | { |
7104 | struct tg3 *tp = netdev_priv(dev); | 7078 | struct tg3 *tp = netdev_priv(dev); |
7079 | int irq_sync = 0; | ||
7105 | 7080 | ||
7106 | if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) || | 7081 | if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) || |
7107 | (ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) || | 7082 | (ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) || |
7108 | (ering->tx_pending > TG3_TX_RING_SIZE - 1)) | 7083 | (ering->tx_pending > TG3_TX_RING_SIZE - 1)) |
7109 | return -EINVAL; | 7084 | return -EINVAL; |
7110 | 7085 | ||
7111 | if (netif_running(dev)) | 7086 | if (netif_running(dev)) { |
7112 | tg3_netif_stop(tp); | 7087 | tg3_netif_stop(tp); |
7088 | irq_sync = 1; | ||
7089 | } | ||
7113 | 7090 | ||
7114 | spin_lock_irq(&tp->lock); | 7091 | tg3_full_lock(tp, irq_sync); |
7115 | spin_lock(&tp->tx_lock); | ||
7116 | 7092 | ||
7117 | tp->rx_pending = ering->rx_pending; | 7093 | tp->rx_pending = ering->rx_pending; |
7118 | 7094 | ||
@@ -7128,8 +7104,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e | |||
7128 | tg3_netif_start(tp); | 7104 | tg3_netif_start(tp); |
7129 | } | 7105 | } |
7130 | 7106 | ||
7131 | spin_unlock(&tp->tx_lock); | 7107 | tg3_full_unlock(tp); |
7132 | spin_unlock_irq(&tp->lock); | ||
7133 | 7108 | ||
7134 | return 0; | 7109 | return 0; |
7135 | } | 7110 | } |
@@ -7146,12 +7121,15 @@ static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam | |||
7146 | static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) | 7121 | static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) |
7147 | { | 7122 | { |
7148 | struct tg3 *tp = netdev_priv(dev); | 7123 | struct tg3 *tp = netdev_priv(dev); |
7124 | int irq_sync = 0; | ||
7149 | 7125 | ||
7150 | if (netif_running(dev)) | 7126 | if (netif_running(dev)) { |
7151 | tg3_netif_stop(tp); | 7127 | tg3_netif_stop(tp); |
7128 | irq_sync = 1; | ||
7129 | } | ||
7130 | |||
7131 | tg3_full_lock(tp, irq_sync); | ||
7152 | 7132 | ||
7153 | spin_lock_irq(&tp->lock); | ||
7154 | spin_lock(&tp->tx_lock); | ||
7155 | if (epause->autoneg) | 7133 | if (epause->autoneg) |
7156 | tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG; | 7134 | tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG; |
7157 | else | 7135 | else |
@@ -7170,8 +7148,8 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam | |||
7170 | tg3_init_hw(tp); | 7148 | tg3_init_hw(tp); |
7171 | tg3_netif_start(tp); | 7149 | tg3_netif_start(tp); |
7172 | } | 7150 | } |
7173 | spin_unlock(&tp->tx_lock); | 7151 | |
7174 | spin_unlock_irq(&tp->lock); | 7152 | tg3_full_unlock(tp); |
7175 | 7153 | ||
7176 | return 0; | 7154 | return 0; |
7177 | } | 7155 | } |
@@ -7192,12 +7170,12 @@ static int tg3_set_rx_csum(struct net_device *dev, u32 data) | |||
7192 | return 0; | 7170 | return 0; |
7193 | } | 7171 | } |
7194 | 7172 | ||
7195 | spin_lock_irq(&tp->lock); | 7173 | spin_lock_bh(&tp->lock); |
7196 | if (data) | 7174 | if (data) |
7197 | tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS; | 7175 | tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS; |
7198 | else | 7176 | else |
7199 | tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS; | 7177 | tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS; |
7200 | spin_unlock_irq(&tp->lock); | 7178 | spin_unlock_bh(&tp->lock); |
7201 | 7179 | ||
7202 | return 0; | 7180 | return 0; |
7203 | } | 7181 | } |
@@ -7606,8 +7584,6 @@ static int tg3_test_loopback(struct tg3 *tp) | |||
7606 | 7584 | ||
7607 | tg3_abort_hw(tp, 1); | 7585 | tg3_abort_hw(tp, 1); |
7608 | 7586 | ||
7609 | /* Clearing this flag to keep interrupts disabled */ | ||
7610 | tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE; | ||
7611 | tg3_reset_hw(tp); | 7587 | tg3_reset_hw(tp); |
7612 | 7588 | ||
7613 | mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | | 7589 | mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | |
@@ -7716,11 +7692,14 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, | |||
7716 | data[1] = 1; | 7692 | data[1] = 1; |
7717 | } | 7693 | } |
7718 | if (etest->flags & ETH_TEST_FL_OFFLINE) { | 7694 | if (etest->flags & ETH_TEST_FL_OFFLINE) { |
7719 | if (netif_running(dev)) | 7695 | int irq_sync = 0; |
7696 | |||
7697 | if (netif_running(dev)) { | ||
7720 | tg3_netif_stop(tp); | 7698 | tg3_netif_stop(tp); |
7699 | irq_sync = 1; | ||
7700 | } | ||
7721 | 7701 | ||
7722 | spin_lock_irq(&tp->lock); | 7702 | tg3_full_lock(tp, irq_sync); |
7723 | spin_lock(&tp->tx_lock); | ||
7724 | 7703 | ||
7725 | tg3_halt(tp, RESET_KIND_SUSPEND, 1); | 7704 | tg3_halt(tp, RESET_KIND_SUSPEND, 1); |
7726 | tg3_nvram_lock(tp); | 7705 | tg3_nvram_lock(tp); |
@@ -7742,14 +7721,14 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, | |||
7742 | data[4] = 1; | 7721 | data[4] = 1; |
7743 | } | 7722 | } |
7744 | 7723 | ||
7745 | spin_unlock(&tp->tx_lock); | 7724 | tg3_full_unlock(tp); |
7746 | spin_unlock_irq(&tp->lock); | 7725 | |
7747 | if (tg3_test_interrupt(tp) != 0) { | 7726 | if (tg3_test_interrupt(tp) != 0) { |
7748 | etest->flags |= ETH_TEST_FL_FAILED; | 7727 | etest->flags |= ETH_TEST_FL_FAILED; |
7749 | data[5] = 1; | 7728 | data[5] = 1; |
7750 | } | 7729 | } |
7751 | spin_lock_irq(&tp->lock); | 7730 | |
7752 | spin_lock(&tp->tx_lock); | 7731 | tg3_full_lock(tp, 0); |
7753 | 7732 | ||
7754 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | 7733 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
7755 | if (netif_running(dev)) { | 7734 | if (netif_running(dev)) { |
@@ -7757,8 +7736,8 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, | |||
7757 | tg3_init_hw(tp); | 7736 | tg3_init_hw(tp); |
7758 | tg3_netif_start(tp); | 7737 | tg3_netif_start(tp); |
7759 | } | 7738 | } |
7760 | spin_unlock(&tp->tx_lock); | 7739 | |
7761 | spin_unlock_irq(&tp->lock); | 7740 | tg3_full_unlock(tp); |
7762 | } | 7741 | } |
7763 | } | 7742 | } |
7764 | 7743 | ||
@@ -7779,9 +7758,9 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
7779 | if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) | 7758 | if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) |
7780 | break; /* We have no PHY */ | 7759 | break; /* We have no PHY */ |
7781 | 7760 | ||
7782 | spin_lock_irq(&tp->lock); | 7761 | spin_lock_bh(&tp->lock); |
7783 | err = tg3_readphy(tp, data->reg_num & 0x1f, &mii_regval); | 7762 | err = tg3_readphy(tp, data->reg_num & 0x1f, &mii_regval); |
7784 | spin_unlock_irq(&tp->lock); | 7763 | spin_unlock_bh(&tp->lock); |
7785 | 7764 | ||
7786 | data->val_out = mii_regval; | 7765 | data->val_out = mii_regval; |
7787 | 7766 | ||
@@ -7795,9 +7774,9 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
7795 | if (!capable(CAP_NET_ADMIN)) | 7774 | if (!capable(CAP_NET_ADMIN)) |
7796 | return -EPERM; | 7775 | return -EPERM; |
7797 | 7776 | ||
7798 | spin_lock_irq(&tp->lock); | 7777 | spin_lock_bh(&tp->lock); |
7799 | err = tg3_writephy(tp, data->reg_num & 0x1f, data->val_in); | 7778 | err = tg3_writephy(tp, data->reg_num & 0x1f, data->val_in); |
7800 | spin_unlock_irq(&tp->lock); | 7779 | spin_unlock_bh(&tp->lock); |
7801 | 7780 | ||
7802 | return err; | 7781 | return err; |
7803 | 7782 | ||
@@ -7813,28 +7792,24 @@ static void tg3_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) | |||
7813 | { | 7792 | { |
7814 | struct tg3 *tp = netdev_priv(dev); | 7793 | struct tg3 *tp = netdev_priv(dev); |
7815 | 7794 | ||
7816 | spin_lock_irq(&tp->lock); | 7795 | tg3_full_lock(tp, 0); |
7817 | spin_lock(&tp->tx_lock); | ||
7818 | 7796 | ||
7819 | tp->vlgrp = grp; | 7797 | tp->vlgrp = grp; |
7820 | 7798 | ||
7821 | /* Update RX_MODE_KEEP_VLAN_TAG bit in RX_MODE register. */ | 7799 | /* Update RX_MODE_KEEP_VLAN_TAG bit in RX_MODE register. */ |
7822 | __tg3_set_rx_mode(dev); | 7800 | __tg3_set_rx_mode(dev); |
7823 | 7801 | ||
7824 | spin_unlock(&tp->tx_lock); | 7802 | tg3_full_unlock(tp); |
7825 | spin_unlock_irq(&tp->lock); | ||
7826 | } | 7803 | } |
7827 | 7804 | ||
7828 | static void tg3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) | 7805 | static void tg3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) |
7829 | { | 7806 | { |
7830 | struct tg3 *tp = netdev_priv(dev); | 7807 | struct tg3 *tp = netdev_priv(dev); |
7831 | 7808 | ||
7832 | spin_lock_irq(&tp->lock); | 7809 | tg3_full_lock(tp, 0); |
7833 | spin_lock(&tp->tx_lock); | ||
7834 | if (tp->vlgrp) | 7810 | if (tp->vlgrp) |
7835 | tp->vlgrp->vlan_devices[vid] = NULL; | 7811 | tp->vlgrp->vlan_devices[vid] = NULL; |
7836 | spin_unlock(&tp->tx_lock); | 7812 | tg3_full_unlock(tp); |
7837 | spin_unlock_irq(&tp->lock); | ||
7838 | } | 7813 | } |
7839 | #endif | 7814 | #endif |
7840 | 7815 | ||
@@ -10165,24 +10140,19 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) | |||
10165 | 10140 | ||
10166 | del_timer_sync(&tp->timer); | 10141 | del_timer_sync(&tp->timer); |
10167 | 10142 | ||
10168 | spin_lock_irq(&tp->lock); | 10143 | tg3_full_lock(tp, 1); |
10169 | spin_lock(&tp->tx_lock); | ||
10170 | tg3_disable_ints(tp); | 10144 | tg3_disable_ints(tp); |
10171 | spin_unlock(&tp->tx_lock); | 10145 | tg3_full_unlock(tp); |
10172 | spin_unlock_irq(&tp->lock); | ||
10173 | 10146 | ||
10174 | netif_device_detach(dev); | 10147 | netif_device_detach(dev); |
10175 | 10148 | ||
10176 | spin_lock_irq(&tp->lock); | 10149 | tg3_full_lock(tp, 0); |
10177 | spin_lock(&tp->tx_lock); | ||
10178 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | 10150 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
10179 | spin_unlock(&tp->tx_lock); | 10151 | tg3_full_unlock(tp); |
10180 | spin_unlock_irq(&tp->lock); | ||
10181 | 10152 | ||
10182 | err = tg3_set_power_state(tp, pci_choose_state(pdev, state)); | 10153 | err = tg3_set_power_state(tp, pci_choose_state(pdev, state)); |
10183 | if (err) { | 10154 | if (err) { |
10184 | spin_lock_irq(&tp->lock); | 10155 | tg3_full_lock(tp, 0); |
10185 | spin_lock(&tp->tx_lock); | ||
10186 | 10156 | ||
10187 | tg3_init_hw(tp); | 10157 | tg3_init_hw(tp); |
10188 | 10158 | ||
@@ -10192,8 +10162,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) | |||
10192 | netif_device_attach(dev); | 10162 | netif_device_attach(dev); |
10193 | tg3_netif_start(tp); | 10163 | tg3_netif_start(tp); |
10194 | 10164 | ||
10195 | spin_unlock(&tp->tx_lock); | 10165 | tg3_full_unlock(tp); |
10196 | spin_unlock_irq(&tp->lock); | ||
10197 | } | 10166 | } |
10198 | 10167 | ||
10199 | return err; | 10168 | return err; |
@@ -10216,20 +10185,16 @@ static int tg3_resume(struct pci_dev *pdev) | |||
10216 | 10185 | ||
10217 | netif_device_attach(dev); | 10186 | netif_device_attach(dev); |
10218 | 10187 | ||
10219 | spin_lock_irq(&tp->lock); | 10188 | tg3_full_lock(tp, 0); |
10220 | spin_lock(&tp->tx_lock); | ||
10221 | 10189 | ||
10222 | tg3_init_hw(tp); | 10190 | tg3_init_hw(tp); |
10223 | 10191 | ||
10224 | tp->timer.expires = jiffies + tp->timer_offset; | 10192 | tp->timer.expires = jiffies + tp->timer_offset; |
10225 | add_timer(&tp->timer); | 10193 | add_timer(&tp->timer); |
10226 | 10194 | ||
10227 | tg3_enable_ints(tp); | ||
10228 | |||
10229 | tg3_netif_start(tp); | 10195 | tg3_netif_start(tp); |
10230 | 10196 | ||
10231 | spin_unlock(&tp->tx_lock); | 10197 | tg3_full_unlock(tp); |
10232 | spin_unlock_irq(&tp->lock); | ||
10233 | 10198 | ||
10234 | return 0; | 10199 | return 0; |
10235 | } | 10200 | } |
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 993f84c93dc4..99c5f9675a56 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h | |||
@@ -2006,17 +2006,31 @@ struct tg3_ethtool_stats { | |||
2006 | struct tg3 { | 2006 | struct tg3 { |
2007 | /* begin "general, frequently-used members" cacheline section */ | 2007 | /* begin "general, frequently-used members" cacheline section */ |
2008 | 2008 | ||
2009 | /* If the IRQ handler (which runs lockless) needs to be | ||
2010 | * quiesced, the following bitmask state is used. The | ||
2011 | * SYNC flag is set by non-IRQ context code to initiate | ||
2012 | * the quiescence. | ||
2013 | * | ||
2014 | * When the IRQ handler notices that SYNC is set, it | ||
2015 | * disables interrupts and returns. | ||
2016 | * | ||
2017 | * When all outstanding IRQ handlers have returned after | ||
2018 | * the SYNC flag has been set, the setter can be assured | ||
2019 | * that interrupts will no longer get run. | ||
2020 | * | ||
2021 | * In this way all SMP driver locks are never acquired | ||
2022 | * in hw IRQ context, only sw IRQ context or lower. | ||
2023 | */ | ||
2024 | unsigned int irq_sync; | ||
2025 | |||
2009 | /* SMP locking strategy: | 2026 | /* SMP locking strategy: |
2010 | * | 2027 | * |
2011 | * lock: Held during all operations except TX packet | 2028 | * lock: Held during all operations except TX packet |
2012 | * processing. | 2029 | * processing. |
2013 | * | 2030 | * |
2014 | * tx_lock: Held during tg3_start_xmit{,_4gbug} and tg3_tx | 2031 | * tx_lock: Held during tg3_start_xmit and tg3_tx |
2015 | * | 2032 | * |
2016 | * If you want to shut up all asynchronous processing you must | 2033 | * Both of these locks are to be held with BH safety. |
2017 | * acquire both locks, 'lock' taken before 'tx_lock'. IRQs must | ||
2018 | * be disabled to take 'lock' but only softirq disabling is | ||
2019 | * necessary for acquisition of 'tx_lock'. | ||
2020 | */ | 2034 | */ |
2021 | spinlock_t lock; | 2035 | spinlock_t lock; |
2022 | spinlock_t indirect_lock; | 2036 | spinlock_t indirect_lock; |
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig index 66b94668ddd8..18c27e1e7884 100644 --- a/drivers/net/wan/Kconfig +++ b/drivers/net/wan/Kconfig | |||
@@ -435,7 +435,7 @@ config VENDOR_SANGOMA | |||
435 | the driver to support. | 435 | the driver to support. |
436 | 436 | ||
437 | If you have one or more of these cards, say M to this option; | 437 | If you have one or more of these cards, say M to this option; |
438 | and read <file:Documentation/networking/wanpipe.txt>. | 438 | and read <file:Documentation/networking/wan-router.txt>. |
439 | 439 | ||
440 | To compile this driver as a module, choose M here: the | 440 | To compile this driver as a module, choose M here: the |
441 | module will be called wanpipe. | 441 | module will be called wanpipe. |
diff --git a/drivers/s390/Kconfig b/drivers/s390/Kconfig index 96413c2cd1ad..a86a650f3d6d 100644 --- a/drivers/s390/Kconfig +++ b/drivers/s390/Kconfig | |||
@@ -187,6 +187,13 @@ config VMLOGRDR | |||
187 | *SYMPTOM. | 187 | *SYMPTOM. |
188 | This driver depends on the IUCV support driver. | 188 | This driver depends on the IUCV support driver. |
189 | 189 | ||
190 | config VMCP | ||
191 | tristate "Support for the z/VM CP interface (VM only)" | ||
192 | help | ||
193 | Select this option if you want to be able to interact with the control | ||
194 | program on z/VM | ||
195 | |||
196 | |||
190 | config MONREADER | 197 | config MONREADER |
191 | tristate "API for reading z/VM monitor service records" | 198 | tristate "API for reading z/VM monitor service records" |
192 | depends on IUCV | 199 | depends on IUCV |
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index ceeb3cf64a16..6527ff6f4706 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -176,7 +176,7 @@ dasd_state_known_to_basic(struct dasd_device * device) | |||
176 | return rc; | 176 | return rc; |
177 | 177 | ||
178 | /* register 'device' debug area, used for all DBF_DEV_XXX calls */ | 178 | /* register 'device' debug area, used for all DBF_DEV_XXX calls */ |
179 | device->debug_area = debug_register(device->cdev->dev.bus_id, 0, 2, | 179 | device->debug_area = debug_register(device->cdev->dev.bus_id, 1, 2, |
180 | 8 * sizeof (long)); | 180 | 8 * sizeof (long)); |
181 | debug_register_view(device->debug_area, &debug_sprintf_view); | 181 | debug_register_view(device->debug_area, &debug_sprintf_view); |
182 | debug_set_level(device->debug_area, DBF_EMERG); | 182 | debug_set_level(device->debug_area, DBF_EMERG); |
@@ -1952,26 +1952,24 @@ dasd_generic_notify(struct ccw_device *cdev, int event) | |||
1952 | * Automatically online either all dasd devices (dasd_autodetect) or | 1952 | * Automatically online either all dasd devices (dasd_autodetect) or |
1953 | * all devices specified with dasd= parameters. | 1953 | * all devices specified with dasd= parameters. |
1954 | */ | 1954 | */ |
1955 | static int | ||
1956 | __dasd_auto_online(struct device *dev, void *data) | ||
1957 | { | ||
1958 | struct ccw_device *cdev; | ||
1959 | |||
1960 | cdev = to_ccwdev(dev); | ||
1961 | if (dasd_autodetect || dasd_busid_known(cdev->dev.bus_id) == 0) | ||
1962 | ccw_device_set_online(cdev); | ||
1963 | return 0; | ||
1964 | } | ||
1965 | |||
1955 | void | 1966 | void |
1956 | dasd_generic_auto_online (struct ccw_driver *dasd_discipline_driver) | 1967 | dasd_generic_auto_online (struct ccw_driver *dasd_discipline_driver) |
1957 | { | 1968 | { |
1958 | struct device_driver *drv; | 1969 | struct device_driver *drv; |
1959 | struct device *d, *dev; | ||
1960 | struct ccw_device *cdev; | ||
1961 | 1970 | ||
1962 | drv = get_driver(&dasd_discipline_driver->driver); | 1971 | drv = get_driver(&dasd_discipline_driver->driver); |
1963 | down_read(&drv->bus->subsys.rwsem); | 1972 | driver_for_each_device(drv, NULL, NULL, __dasd_auto_online); |
1964 | dev = NULL; | ||
1965 | list_for_each_entry(d, &drv->devices, driver_list) { | ||
1966 | dev = get_device(d); | ||
1967 | if (!dev) | ||
1968 | continue; | ||
1969 | cdev = to_ccwdev(dev); | ||
1970 | if (dasd_autodetect || dasd_busid_known(cdev->dev.bus_id) == 0) | ||
1971 | ccw_device_set_online(cdev); | ||
1972 | put_device(dev); | ||
1973 | } | ||
1974 | up_read(&drv->bus->subsys.rwsem); | ||
1975 | put_driver(drv); | 1973 | put_driver(drv); |
1976 | } | 1974 | } |
1977 | 1975 | ||
@@ -1983,7 +1981,7 @@ dasd_init(void) | |||
1983 | init_waitqueue_head(&dasd_init_waitq); | 1981 | init_waitqueue_head(&dasd_init_waitq); |
1984 | 1982 | ||
1985 | /* register 'common' DASD debug area, used for all DBF_XXX calls */ | 1983 | /* register 'common' DASD debug area, used for all DBF_XXX calls */ |
1986 | dasd_debug_area = debug_register("dasd", 0, 2, 8 * sizeof (long)); | 1984 | dasd_debug_area = debug_register("dasd", 1, 2, 8 * sizeof (long)); |
1987 | if (dasd_debug_area == NULL) { | 1985 | if (dasd_debug_area == NULL) { |
1988 | rc = -ENOMEM; | 1986 | rc = -ENOMEM; |
1989 | goto failed; | 1987 | goto failed; |
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c index d7f19745911f..43c34f8c5e68 100644 --- a/drivers/s390/block/dasd_proc.c +++ b/drivers/s390/block/dasd_proc.c | |||
@@ -9,13 +9,14 @@ | |||
9 | * | 9 | * |
10 | * /proc interface for the dasd driver. | 10 | * /proc interface for the dasd driver. |
11 | * | 11 | * |
12 | * $Revision: 1.31 $ | 12 | * $Revision: 1.32 $ |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/config.h> | 15 | #include <linux/config.h> |
16 | #include <linux/ctype.h> | 16 | #include <linux/ctype.h> |
17 | #include <linux/seq_file.h> | 17 | #include <linux/seq_file.h> |
18 | #include <linux/vmalloc.h> | 18 | #include <linux/vmalloc.h> |
19 | #include <linux/proc_fs.h> | ||
19 | 20 | ||
20 | #include <asm/debug.h> | 21 | #include <asm/debug.h> |
21 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index 6bc27d52326f..4fde41188996 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c | |||
@@ -718,7 +718,7 @@ dcssblk_check_params(void) | |||
718 | buf[j-i] = dcssblk_segments[j]; | 718 | buf[j-i] = dcssblk_segments[j]; |
719 | } | 719 | } |
720 | buf[j-i] = '\0'; | 720 | buf[j-i] = '\0'; |
721 | rc = dcssblk_add_store(dcssblk_root_dev, buf, j-i); | 721 | rc = dcssblk_add_store(dcssblk_root_dev, NULL, buf, j-i); |
722 | if ((rc >= 0) && (dcssblk_segments[j] == '(')) { | 722 | if ((rc >= 0) && (dcssblk_segments[j] == '(')) { |
723 | for (k = 0; buf[k] != '\0'; k++) | 723 | for (k = 0; buf[k] != '\0'; k++) |
724 | buf[k] = toupper(buf[k]); | 724 | buf[k] = toupper(buf[k]); |
@@ -728,7 +728,7 @@ dcssblk_check_params(void) | |||
728 | up_read(&dcssblk_devices_sem); | 728 | up_read(&dcssblk_devices_sem); |
729 | if (dev_info) | 729 | if (dev_info) |
730 | dcssblk_shared_store(&dev_info->dev, | 730 | dcssblk_shared_store(&dev_info->dev, |
731 | "0\n", 2); | 731 | NULL, "0\n", 2); |
732 | } | 732 | } |
733 | } | 733 | } |
734 | while ((dcssblk_segments[j] != ',') && | 734 | while ((dcssblk_segments[j] != ',') && |
diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile index 14e8cce9f862..6377a96735df 100644 --- a/drivers/s390/char/Makefile +++ b/drivers/s390/char/Makefile | |||
@@ -19,6 +19,7 @@ obj-$(CONFIG_SCLP_CPI) += sclp_cpi.o | |||
19 | 19 | ||
20 | obj-$(CONFIG_ZVM_WATCHDOG) += vmwatchdog.o | 20 | obj-$(CONFIG_ZVM_WATCHDOG) += vmwatchdog.o |
21 | obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o | 21 | obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o |
22 | obj-$(CONFIG_VMCP) += vmcp.o | ||
22 | 23 | ||
23 | tape-$(CONFIG_S390_TAPE_BLOCK) += tape_block.o | 24 | tape-$(CONFIG_S390_TAPE_BLOCK) += tape_block.o |
24 | tape-$(CONFIG_PROC_FS) += tape_proc.o | 25 | tape-$(CONFIG_PROC_FS) += tape_proc.o |
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 022f17bff731..f11a67fda40e 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c | |||
@@ -860,8 +860,8 @@ con3215_init(void) | |||
860 | 860 | ||
861 | /* Set the console mode for VM */ | 861 | /* Set the console mode for VM */ |
862 | if (MACHINE_IS_VM) { | 862 | if (MACHINE_IS_VM) { |
863 | cpcmd("TERM CONMODE 3215", NULL, 0); | 863 | cpcmd("TERM CONMODE 3215", NULL, 0, NULL); |
864 | cpcmd("TERM AUTOCR OFF", NULL, 0); | 864 | cpcmd("TERM AUTOCR OFF", NULL, 0, NULL); |
865 | } | 865 | } |
866 | 866 | ||
867 | /* allocate 3215 request structures */ | 867 | /* allocate 3215 request structures */ |
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c index d52fb57a6b19..fc7a213e591f 100644 --- a/drivers/s390/char/con3270.c +++ b/drivers/s390/char/con3270.c | |||
@@ -591,8 +591,8 @@ con3270_init(void) | |||
591 | 591 | ||
592 | /* Set the console mode for VM */ | 592 | /* Set the console mode for VM */ |
593 | if (MACHINE_IS_VM) { | 593 | if (MACHINE_IS_VM) { |
594 | cpcmd("TERM CONMODE 3270", 0, 0); | 594 | cpcmd("TERM CONMODE 3270", NULL, 0, NULL); |
595 | cpcmd("TERM AUTOCR OFF", 0, 0); | 595 | cpcmd("TERM AUTOCR OFF", NULL, 0, NULL); |
596 | } | 596 | } |
597 | 597 | ||
598 | cdev = ccw_device_probe_console(); | 598 | cdev = ccw_device_probe_console(); |
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c index 480ec87976fb..20be88e91fa1 100644 --- a/drivers/s390/char/tape_34xx.c +++ b/drivers/s390/char/tape_34xx.c | |||
@@ -1351,13 +1351,13 @@ tape_34xx_init (void) | |||
1351 | { | 1351 | { |
1352 | int rc; | 1352 | int rc; |
1353 | 1353 | ||
1354 | TAPE_DBF_AREA = debug_register ( "tape_34xx", 1, 2, 4*sizeof(long)); | 1354 | TAPE_DBF_AREA = debug_register ( "tape_34xx", 2, 2, 4*sizeof(long)); |
1355 | debug_register_view(TAPE_DBF_AREA, &debug_sprintf_view); | 1355 | debug_register_view(TAPE_DBF_AREA, &debug_sprintf_view); |
1356 | #ifdef DBF_LIKE_HELL | 1356 | #ifdef DBF_LIKE_HELL |
1357 | debug_set_level(TAPE_DBF_AREA, 6); | 1357 | debug_set_level(TAPE_DBF_AREA, 6); |
1358 | #endif | 1358 | #endif |
1359 | 1359 | ||
1360 | DBF_EVENT(3, "34xx init: $Revision: 1.21 $\n"); | 1360 | DBF_EVENT(3, "34xx init: $Revision: 1.23 $\n"); |
1361 | /* Register driver for 3480/3490 tapes. */ | 1361 | /* Register driver for 3480/3490 tapes. */ |
1362 | rc = ccw_driver_register(&tape_34xx_driver); | 1362 | rc = ccw_driver_register(&tape_34xx_driver); |
1363 | if (rc) | 1363 | if (rc) |
@@ -1378,7 +1378,7 @@ tape_34xx_exit(void) | |||
1378 | MODULE_DEVICE_TABLE(ccw, tape_34xx_ids); | 1378 | MODULE_DEVICE_TABLE(ccw, tape_34xx_ids); |
1379 | MODULE_AUTHOR("(C) 2001-2002 IBM Deutschland Entwicklung GmbH"); | 1379 | MODULE_AUTHOR("(C) 2001-2002 IBM Deutschland Entwicklung GmbH"); |
1380 | MODULE_DESCRIPTION("Linux on zSeries channel attached 3480 tape " | 1380 | MODULE_DESCRIPTION("Linux on zSeries channel attached 3480 tape " |
1381 | "device driver ($Revision: 1.21 $)"); | 1381 | "device driver ($Revision: 1.23 $)"); |
1382 | MODULE_LICENSE("GPL"); | 1382 | MODULE_LICENSE("GPL"); |
1383 | 1383 | ||
1384 | module_init(tape_34xx_init); | 1384 | module_init(tape_34xx_init); |
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index b4df4a515b12..0597aa0e27ee 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c | |||
@@ -1186,7 +1186,7 @@ tape_mtop(struct tape_device *device, int mt_op, int mt_count) | |||
1186 | static int | 1186 | static int |
1187 | tape_init (void) | 1187 | tape_init (void) |
1188 | { | 1188 | { |
1189 | TAPE_DBF_AREA = debug_register ( "tape", 1, 2, 4*sizeof(long)); | 1189 | TAPE_DBF_AREA = debug_register ( "tape", 2, 2, 4*sizeof(long)); |
1190 | debug_register_view(TAPE_DBF_AREA, &debug_sprintf_view); | 1190 | debug_register_view(TAPE_DBF_AREA, &debug_sprintf_view); |
1191 | #ifdef DBF_LIKE_HELL | 1191 | #ifdef DBF_LIKE_HELL |
1192 | debug_set_level(TAPE_DBF_AREA, 6); | 1192 | debug_set_level(TAPE_DBF_AREA, 6); |
diff --git a/drivers/s390/char/tape_proc.c b/drivers/s390/char/tape_proc.c index 801d17cca34e..5fec0a10cc3d 100644 --- a/drivers/s390/char/tape_proc.c +++ b/drivers/s390/char/tape_proc.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/vmalloc.h> | 16 | #include <linux/vmalloc.h> |
17 | #include <linux/seq_file.h> | 17 | #include <linux/seq_file.h> |
18 | #include <linux/proc_fs.h> | ||
18 | 19 | ||
19 | #define TAPE_DBF_AREA tape_core_dbf | 20 | #define TAPE_DBF_AREA tape_core_dbf |
20 | 21 | ||
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c new file mode 100644 index 000000000000..7f11a608a633 --- /dev/null +++ b/drivers/s390/char/vmcp.c | |||
@@ -0,0 +1,219 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004,2005 IBM Corporation | ||
3 | * Interface implementation for communication with the v/VM control program | ||
4 | * Author(s): Christian Borntraeger <cborntra@de.ibm.com> | ||
5 | * | ||
6 | * | ||
7 | * z/VMs CP offers the possibility to issue commands via the diagnose code 8 | ||
8 | * this driver implements a character device that issues these commands and | ||
9 | * returns the answer of CP. | ||
10 | |||
11 | * The idea of this driver is based on cpint from Neale Ferguson and #CP in CMS | ||
12 | */ | ||
13 | |||
14 | #include <linux/fs.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/miscdevice.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <asm/cpcmd.h> | ||
20 | #include <asm/debug.h> | ||
21 | #include <asm/uaccess.h> | ||
22 | #include "vmcp.h" | ||
23 | |||
24 | MODULE_LICENSE("GPL"); | ||
25 | MODULE_AUTHOR("Christian Borntraeger <cborntra@de.ibm.com>"); | ||
26 | MODULE_DESCRIPTION("z/VM CP interface"); | ||
27 | |||
28 | static debug_info_t *vmcp_debug; | ||
29 | |||
30 | static int vmcp_open(struct inode *inode, struct file *file) | ||
31 | { | ||
32 | struct vmcp_session *session; | ||
33 | |||
34 | if (!capable(CAP_SYS_ADMIN)) | ||
35 | return -EPERM; | ||
36 | |||
37 | session = kmalloc(sizeof(*session), GFP_KERNEL); | ||
38 | if (!session) | ||
39 | return -ENOMEM; | ||
40 | session->bufsize = PAGE_SIZE; | ||
41 | session->response = NULL; | ||
42 | session->resp_size = 0; | ||
43 | init_MUTEX(&session->mutex); | ||
44 | file->private_data = session; | ||
45 | return nonseekable_open(inode, file); | ||
46 | } | ||
47 | |||
48 | static int vmcp_release(struct inode *inode, struct file *file) | ||
49 | { | ||
50 | struct vmcp_session *session; | ||
51 | |||
52 | session = (struct vmcp_session *)file->private_data; | ||
53 | file->private_data = NULL; | ||
54 | free_pages((unsigned long)session->response, get_order(session->bufsize)); | ||
55 | kfree(session); | ||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | static ssize_t | ||
60 | vmcp_read(struct file *file, char __user * buff, size_t count, loff_t * ppos) | ||
61 | { | ||
62 | size_t tocopy; | ||
63 | struct vmcp_session *session; | ||
64 | |||
65 | session = (struct vmcp_session *)file->private_data; | ||
66 | if (down_interruptible(&session->mutex)) | ||
67 | return -ERESTARTSYS; | ||
68 | if (!session->response) { | ||
69 | up(&session->mutex); | ||
70 | return 0; | ||
71 | } | ||
72 | if (*ppos > session->resp_size) { | ||
73 | up(&session->mutex); | ||
74 | return 0; | ||
75 | } | ||
76 | tocopy = min(session->resp_size - (size_t) (*ppos), count); | ||
77 | tocopy = min(tocopy,session->bufsize - (size_t) (*ppos)); | ||
78 | |||
79 | if (copy_to_user(buff, session->response + (*ppos), tocopy)) { | ||
80 | up(&session->mutex); | ||
81 | return -EFAULT; | ||
82 | } | ||
83 | up(&session->mutex); | ||
84 | *ppos += tocopy; | ||
85 | return tocopy; | ||
86 | } | ||
87 | |||
88 | static ssize_t | ||
89 | vmcp_write(struct file *file, const char __user * buff, size_t count, | ||
90 | loff_t * ppos) | ||
91 | { | ||
92 | char *cmd; | ||
93 | struct vmcp_session *session; | ||
94 | |||
95 | if (count > 240) | ||
96 | return -EINVAL; | ||
97 | cmd = kmalloc(count + 1, GFP_KERNEL); | ||
98 | if (!cmd) | ||
99 | return -ENOMEM; | ||
100 | if (copy_from_user(cmd, buff, count)) { | ||
101 | kfree(cmd); | ||
102 | return -EFAULT; | ||
103 | } | ||
104 | cmd[count] = '\0'; | ||
105 | session = (struct vmcp_session *)file->private_data; | ||
106 | if (down_interruptible(&session->mutex)) | ||
107 | return -ERESTARTSYS; | ||
108 | if (!session->response) | ||
109 | session->response = (char *)__get_free_pages(GFP_KERNEL | ||
110 | | __GFP_REPEAT | GFP_DMA, | ||
111 | get_order(session->bufsize)); | ||
112 | if (!session->response) { | ||
113 | up(&session->mutex); | ||
114 | kfree(cmd); | ||
115 | return -ENOMEM; | ||
116 | } | ||
117 | debug_text_event(vmcp_debug, 1, cmd); | ||
118 | session->resp_size = cpcmd(cmd, session->response, | ||
119 | session->bufsize, | ||
120 | &session->resp_code); | ||
121 | up(&session->mutex); | ||
122 | kfree(cmd); | ||
123 | *ppos = 0; /* reset the file pointer after a command */ | ||
124 | return count; | ||
125 | } | ||
126 | |||
127 | |||
128 | /* | ||
129 | * These ioctls are available, as the semantics of the diagnose 8 call | ||
130 | * does not fit very well into a Linux call. Diagnose X'08' is described in | ||
131 | * CP Programming Services SC24-6084-00 | ||
132 | * | ||
133 | * VMCP_GETCODE: gives the CP return code back to user space | ||
134 | * VMCP_SETBUF: sets the response buffer for the next write call. diagnose 8 | ||
135 | * expects adjacent pages in real storage and to make matters worse, we | ||
136 | * dont know the size of the response. Therefore we default to PAGESIZE and | ||
137 | * let userspace to change the response size, if userspace expects a bigger | ||
138 | * response | ||
139 | */ | ||
140 | static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
141 | { | ||
142 | struct vmcp_session *session; | ||
143 | int temp; | ||
144 | |||
145 | session = (struct vmcp_session *)file->private_data; | ||
146 | if (down_interruptible(&session->mutex)) | ||
147 | return -ERESTARTSYS; | ||
148 | switch (cmd) { | ||
149 | case VMCP_GETCODE: | ||
150 | temp = session->resp_code; | ||
151 | up(&session->mutex); | ||
152 | return put_user(temp, (int __user *)arg); | ||
153 | case VMCP_SETBUF: | ||
154 | free_pages((unsigned long)session->response, | ||
155 | get_order(session->bufsize)); | ||
156 | session->response=NULL; | ||
157 | temp = get_user(session->bufsize, (int __user *)arg); | ||
158 | if (get_order(session->bufsize) > 8) { | ||
159 | session->bufsize = PAGE_SIZE; | ||
160 | temp = -EINVAL; | ||
161 | } | ||
162 | up(&session->mutex); | ||
163 | return temp; | ||
164 | case VMCP_GETSIZE: | ||
165 | temp = session->resp_size; | ||
166 | up(&session->mutex); | ||
167 | return put_user(temp, (int __user *)arg); | ||
168 | default: | ||
169 | up(&session->mutex); | ||
170 | return -ENOIOCTLCMD; | ||
171 | } | ||
172 | } | ||
173 | |||
174 | static struct file_operations vmcp_fops = { | ||
175 | .owner = THIS_MODULE, | ||
176 | .open = &vmcp_open, | ||
177 | .release = &vmcp_release, | ||
178 | .read = &vmcp_read, | ||
179 | .llseek = &no_llseek, | ||
180 | .write = &vmcp_write, | ||
181 | .unlocked_ioctl = &vmcp_ioctl, | ||
182 | .compat_ioctl = &vmcp_ioctl | ||
183 | }; | ||
184 | |||
185 | static struct miscdevice vmcp_dev = { | ||
186 | .name = "vmcp", | ||
187 | .minor = MISC_DYNAMIC_MINOR, | ||
188 | .fops = &vmcp_fops, | ||
189 | }; | ||
190 | |||
191 | static int __init vmcp_init(void) | ||
192 | { | ||
193 | int ret; | ||
194 | |||
195 | if (!MACHINE_IS_VM) { | ||
196 | printk(KERN_WARNING | ||
197 | "z/VM CP interface is only available under z/VM\n"); | ||
198 | return -ENODEV; | ||
199 | } | ||
200 | ret = misc_register(&vmcp_dev); | ||
201 | if (!ret) | ||
202 | printk(KERN_INFO "z/VM CP interface loaded\n"); | ||
203 | else | ||
204 | printk(KERN_WARNING | ||
205 | "z/VM CP interface not loaded. Could not register misc device.\n"); | ||
206 | vmcp_debug = debug_register("vmcp", 1, 1, 240); | ||
207 | debug_register_view(vmcp_debug, &debug_hex_ascii_view); | ||
208 | return ret; | ||
209 | } | ||
210 | |||
211 | static void __exit vmcp_exit(void) | ||
212 | { | ||
213 | WARN_ON(misc_deregister(&vmcp_dev) != 0); | ||
214 | debug_unregister(vmcp_debug); | ||
215 | printk(KERN_INFO "z/VM CP interface unloaded.\n"); | ||
216 | } | ||
217 | |||
218 | module_init(vmcp_init); | ||
219 | module_exit(vmcp_exit); | ||
diff --git a/drivers/s390/char/vmcp.h b/drivers/s390/char/vmcp.h new file mode 100644 index 000000000000..87389e730465 --- /dev/null +++ b/drivers/s390/char/vmcp.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004, 2005 IBM Corporation | ||
3 | * Interface implementation for communication with the v/VM control program | ||
4 | * Version 1.0 | ||
5 | * Author(s): Christian Borntraeger <cborntra@de.ibm.com> | ||
6 | * | ||
7 | * | ||
8 | * z/VMs CP offers the possibility to issue commands via the diagnose code 8 | ||
9 | * this driver implements a character device that issues these commands and | ||
10 | * returns the answer of CP. | ||
11 | * | ||
12 | * The idea of this driver is based on cpint from Neale Ferguson | ||
13 | */ | ||
14 | |||
15 | #include <asm/semaphore.h> | ||
16 | #include <linux/ioctl.h> | ||
17 | |||
18 | #define VMCP_GETCODE _IOR(0x10, 1, int) | ||
19 | #define VMCP_SETBUF _IOW(0x10, 2, int) | ||
20 | #define VMCP_GETSIZE _IOR(0x10, 3, int) | ||
21 | |||
22 | struct vmcp_session { | ||
23 | unsigned int bufsize; | ||
24 | char *response; | ||
25 | int resp_size; | ||
26 | int resp_code; | ||
27 | /* As we use copy_from/to_user, which might * | ||
28 | * sleep and cannot use a spinlock */ | ||
29 | struct semaphore mutex; | ||
30 | }; | ||
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index f7717327d15e..491f00c032e8 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c | |||
@@ -236,7 +236,7 @@ vmlogrdr_get_recording_class_AB(void) { | |||
236 | int len,i; | 236 | int len,i; |
237 | 237 | ||
238 | printk (KERN_DEBUG "vmlogrdr: query command: %s\n", cp_command); | 238 | printk (KERN_DEBUG "vmlogrdr: query command: %s\n", cp_command); |
239 | cpcmd(cp_command, cp_response, sizeof(cp_response)); | 239 | cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); |
240 | printk (KERN_DEBUG "vmlogrdr: response: %s", cp_response); | 240 | printk (KERN_DEBUG "vmlogrdr: response: %s", cp_response); |
241 | len = strnlen(cp_response,sizeof(cp_response)); | 241 | len = strnlen(cp_response,sizeof(cp_response)); |
242 | // now the parsing | 242 | // now the parsing |
@@ -288,7 +288,7 @@ vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, int action, int purge) { | |||
288 | 288 | ||
289 | printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", | 289 | printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", |
290 | cp_command); | 290 | cp_command); |
291 | cpcmd(cp_command, cp_response, sizeof(cp_response)); | 291 | cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); |
292 | printk (KERN_DEBUG "vmlogrdr: recording response: %s", | 292 | printk (KERN_DEBUG "vmlogrdr: recording response: %s", |
293 | cp_response); | 293 | cp_response); |
294 | } | 294 | } |
@@ -301,7 +301,7 @@ vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, int action, int purge) { | |||
301 | qid_string); | 301 | qid_string); |
302 | 302 | ||
303 | printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", cp_command); | 303 | printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", cp_command); |
304 | cpcmd(cp_command, cp_response, sizeof(cp_response)); | 304 | cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); |
305 | printk (KERN_DEBUG "vmlogrdr: recording response: %s", | 305 | printk (KERN_DEBUG "vmlogrdr: recording response: %s", |
306 | cp_response); | 306 | cp_response); |
307 | /* The recording command will usually answer with 'Command complete' | 307 | /* The recording command will usually answer with 'Command complete' |
@@ -607,7 +607,7 @@ vmlogrdr_purge_store(struct device * dev, struct device_attribute *attr, const c | |||
607 | priv->recording_name); | 607 | priv->recording_name); |
608 | 608 | ||
609 | printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", cp_command); | 609 | printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", cp_command); |
610 | cpcmd(cp_command, cp_response, sizeof(cp_response)); | 610 | cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); |
611 | printk (KERN_DEBUG "vmlogrdr: recording response: %s", | 611 | printk (KERN_DEBUG "vmlogrdr: recording response: %s", |
612 | cp_response); | 612 | cp_response); |
613 | 613 | ||
@@ -682,7 +682,7 @@ vmlogrdr_recording_status_show(struct device_driver *driver, char *buf) { | |||
682 | char cp_command[] = "QUERY RECORDING "; | 682 | char cp_command[] = "QUERY RECORDING "; |
683 | int len; | 683 | int len; |
684 | 684 | ||
685 | cpcmd(cp_command, buf, 4096); | 685 | cpcmd(cp_command, buf, 4096, NULL); |
686 | len = strlen(buf); | 686 | len = strlen(buf); |
687 | return len; | 687 | return len; |
688 | } | 688 | } |
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index 306525acb9f8..91ea8e4777f3 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c | |||
@@ -403,34 +403,22 @@ ccwgroup_driver_register (struct ccwgroup_driver *cdriver) | |||
403 | return driver_register(&cdriver->driver); | 403 | return driver_register(&cdriver->driver); |
404 | } | 404 | } |
405 | 405 | ||
406 | static inline struct device * | 406 | static int |
407 | __get_next_ccwgroup_device(struct device_driver *drv) | 407 | __ccwgroup_driver_unregister_device(struct device *dev, void *data) |
408 | { | 408 | { |
409 | struct device *dev, *d; | 409 | __ccwgroup_remove_symlinks(to_ccwgroupdev(dev)); |
410 | 410 | device_unregister(dev); | |
411 | down_read(&drv->bus->subsys.rwsem); | 411 | put_device(dev); |
412 | dev = NULL; | 412 | return 0; |
413 | list_for_each_entry(d, &drv->devices, driver_list) { | ||
414 | dev = get_device(d); | ||
415 | if (dev) | ||
416 | break; | ||
417 | } | ||
418 | up_read(&drv->bus->subsys.rwsem); | ||
419 | return dev; | ||
420 | } | 413 | } |
421 | 414 | ||
422 | void | 415 | void |
423 | ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver) | 416 | ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver) |
424 | { | 417 | { |
425 | struct device *dev; | ||
426 | |||
427 | /* We don't want ccwgroup devices to live longer than their driver. */ | 418 | /* We don't want ccwgroup devices to live longer than their driver. */ |
428 | get_driver(&cdriver->driver); | 419 | get_driver(&cdriver->driver); |
429 | while ((dev = __get_next_ccwgroup_device(&cdriver->driver))) { | 420 | driver_for_each_device(&cdriver->driver, NULL, NULL, |
430 | __ccwgroup_remove_symlinks(to_ccwgroupdev(dev)); | 421 | __ccwgroup_driver_unregister_device); |
431 | device_unregister(dev); | ||
432 | put_device(dev); | ||
433 | }; | ||
434 | put_driver(&cdriver->driver); | 422 | put_driver(&cdriver->driver); |
435 | driver_unregister(&cdriver->driver); | 423 | driver_unregister(&cdriver->driver); |
436 | } | 424 | } |
@@ -449,7 +437,7 @@ __ccwgroup_get_gdev_by_cdev(struct ccw_device *cdev) | |||
449 | if (cdev->dev.driver_data) { | 437 | if (cdev->dev.driver_data) { |
450 | gdev = (struct ccwgroup_device *)cdev->dev.driver_data; | 438 | gdev = (struct ccwgroup_device *)cdev->dev.driver_data; |
451 | if (get_device(&gdev->dev)) { | 439 | if (get_device(&gdev->dev)) { |
452 | if (!list_empty(&gdev->dev.node)) | 440 | if (klist_node_attached(&gdev->dev.knode_bus)) |
453 | return gdev; | 441 | return gdev; |
454 | put_device(&gdev->dev); | 442 | put_device(&gdev->dev); |
455 | } | 443 | } |
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 1d9b3f18d8de..ea813bdce1d6 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/s390/cio/cio.c | 2 | * drivers/s390/cio/cio.c |
3 | * S/390 common I/O routines -- low level i/o calls | 3 | * S/390 common I/O routines -- low level i/o calls |
4 | * $Revision: 1.133 $ | 4 | * $Revision: 1.134 $ |
5 | * | 5 | * |
6 | * Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH, | 6 | * Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH, |
7 | * IBM Corporation | 7 | * IBM Corporation |
@@ -63,17 +63,17 @@ __setup ("cio_msg=", cio_setup); | |||
63 | static int __init | 63 | static int __init |
64 | cio_debug_init (void) | 64 | cio_debug_init (void) |
65 | { | 65 | { |
66 | cio_debug_msg_id = debug_register ("cio_msg", 4, 4, 16*sizeof (long)); | 66 | cio_debug_msg_id = debug_register ("cio_msg", 16, 4, 16*sizeof (long)); |
67 | if (!cio_debug_msg_id) | 67 | if (!cio_debug_msg_id) |
68 | goto out_unregister; | 68 | goto out_unregister; |
69 | debug_register_view (cio_debug_msg_id, &debug_sprintf_view); | 69 | debug_register_view (cio_debug_msg_id, &debug_sprintf_view); |
70 | debug_set_level (cio_debug_msg_id, 2); | 70 | debug_set_level (cio_debug_msg_id, 2); |
71 | cio_debug_trace_id = debug_register ("cio_trace", 4, 4, 8); | 71 | cio_debug_trace_id = debug_register ("cio_trace", 16, 4, 8); |
72 | if (!cio_debug_trace_id) | 72 | if (!cio_debug_trace_id) |
73 | goto out_unregister; | 73 | goto out_unregister; |
74 | debug_register_view (cio_debug_trace_id, &debug_hex_ascii_view); | 74 | debug_register_view (cio_debug_trace_id, &debug_hex_ascii_view); |
75 | debug_set_level (cio_debug_trace_id, 2); | 75 | debug_set_level (cio_debug_trace_id, 2); |
76 | cio_debug_crw_id = debug_register ("cio_crw", 2, 4, 16*sizeof (long)); | 76 | cio_debug_crw_id = debug_register ("cio_crw", 4, 4, 16*sizeof (long)); |
77 | if (!cio_debug_crw_id) | 77 | if (!cio_debug_crw_id) |
78 | goto out_unregister; | 78 | goto out_unregister; |
79 | debug_register_view (cio_debug_crw_id, &debug_sprintf_view); | 79 | debug_register_view (cio_debug_crw_id, &debug_sprintf_view); |
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 87bd70eeabed..555119cacc27 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c | |||
@@ -128,34 +128,28 @@ css_probe_device(int irq) | |||
128 | return ret; | 128 | return ret; |
129 | } | 129 | } |
130 | 130 | ||
131 | static int | ||
132 | check_subchannel(struct device * dev, void * data) | ||
133 | { | ||
134 | struct subchannel *sch; | ||
135 | int irq = (unsigned long)data; | ||
136 | |||
137 | sch = to_subchannel(dev); | ||
138 | return (sch->irq == irq); | ||
139 | } | ||
140 | |||
131 | struct subchannel * | 141 | struct subchannel * |
132 | get_subchannel_by_schid(int irq) | 142 | get_subchannel_by_schid(int irq) |
133 | { | 143 | { |
134 | struct subchannel *sch; | ||
135 | struct list_head *entry; | ||
136 | struct device *dev; | 144 | struct device *dev; |
137 | 145 | ||
138 | if (!get_bus(&css_bus_type)) | 146 | dev = bus_find_device(&css_bus_type, NULL, |
139 | return NULL; | 147 | (void *)(unsigned long)irq, check_subchannel); |
140 | down_read(&css_bus_type.subsys.rwsem); | ||
141 | sch = NULL; | ||
142 | list_for_each(entry, &css_bus_type.devices.list) { | ||
143 | dev = get_device(container_of(entry, | ||
144 | struct device, bus_list)); | ||
145 | if (!dev) | ||
146 | continue; | ||
147 | sch = to_subchannel(dev); | ||
148 | if (sch->irq == irq) | ||
149 | break; | ||
150 | put_device(dev); | ||
151 | sch = NULL; | ||
152 | } | ||
153 | up_read(&css_bus_type.subsys.rwsem); | ||
154 | put_bus(&css_bus_type); | ||
155 | 148 | ||
156 | return sch; | 149 | return dev ? to_subchannel(dev) : NULL; |
157 | } | 150 | } |
158 | 151 | ||
152 | |||
159 | static inline int | 153 | static inline int |
160 | css_get_subchannel_status(struct subchannel *sch, int schid) | 154 | css_get_subchannel_status(struct subchannel *sch, int schid) |
161 | { | 155 | { |
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 809e1108a06e..14c76f5e4177 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
@@ -514,36 +514,39 @@ ccw_device_register(struct ccw_device *cdev) | |||
514 | return ret; | 514 | return ret; |
515 | } | 515 | } |
516 | 516 | ||
517 | struct match_data { | ||
518 | unsigned int devno; | ||
519 | struct ccw_device * sibling; | ||
520 | }; | ||
521 | |||
522 | static int | ||
523 | match_devno(struct device * dev, void * data) | ||
524 | { | ||
525 | struct match_data * d = (struct match_data *)data; | ||
526 | struct ccw_device * cdev; | ||
527 | |||
528 | cdev = to_ccwdev(dev); | ||
529 | if ((cdev->private->state == DEV_STATE_DISCONNECTED) && | ||
530 | (cdev->private->devno == d->devno) && | ||
531 | (cdev != d->sibling)) { | ||
532 | cdev->private->state = DEV_STATE_NOT_OPER; | ||
533 | return 1; | ||
534 | } | ||
535 | return 0; | ||
536 | } | ||
537 | |||
517 | static struct ccw_device * | 538 | static struct ccw_device * |
518 | get_disc_ccwdev_by_devno(unsigned int devno, struct ccw_device *sibling) | 539 | get_disc_ccwdev_by_devno(unsigned int devno, struct ccw_device *sibling) |
519 | { | 540 | { |
520 | struct ccw_device *cdev; | ||
521 | struct list_head *entry; | ||
522 | struct device *dev; | 541 | struct device *dev; |
542 | struct match_data data = { | ||
543 | .devno = devno, | ||
544 | .sibling = sibling, | ||
545 | }; | ||
523 | 546 | ||
524 | if (!get_bus(&ccw_bus_type)) | 547 | dev = bus_find_device(&css_bus_type, NULL, &data, match_devno); |
525 | return NULL; | ||
526 | down_read(&ccw_bus_type.subsys.rwsem); | ||
527 | cdev = NULL; | ||
528 | list_for_each(entry, &ccw_bus_type.devices.list) { | ||
529 | dev = get_device(container_of(entry, | ||
530 | struct device, bus_list)); | ||
531 | if (!dev) | ||
532 | continue; | ||
533 | cdev = to_ccwdev(dev); | ||
534 | if ((cdev->private->state == DEV_STATE_DISCONNECTED) && | ||
535 | (cdev->private->devno == devno) && | ||
536 | (cdev != sibling)) { | ||
537 | cdev->private->state = DEV_STATE_NOT_OPER; | ||
538 | break; | ||
539 | } | ||
540 | put_device(dev); | ||
541 | cdev = NULL; | ||
542 | } | ||
543 | up_read(&ccw_bus_type.subsys.rwsem); | ||
544 | put_bus(&ccw_bus_type); | ||
545 | 548 | ||
546 | return cdev; | 549 | return dev ? to_ccwdev(dev) : NULL; |
547 | } | 550 | } |
548 | 551 | ||
549 | static void | 552 | static void |
@@ -647,7 +650,7 @@ io_subchannel_register(void *data) | |||
647 | cdev = (struct ccw_device *) data; | 650 | cdev = (struct ccw_device *) data; |
648 | sch = to_subchannel(cdev->dev.parent); | 651 | sch = to_subchannel(cdev->dev.parent); |
649 | 652 | ||
650 | if (!list_empty(&sch->dev.children)) { | 653 | if (klist_node_attached(&cdev->dev.knode_parent)) { |
651 | bus_rescan_devices(&ccw_bus_type); | 654 | bus_rescan_devices(&ccw_bus_type); |
652 | goto out; | 655 | goto out; |
653 | } | 656 | } |
@@ -1019,30 +1022,29 @@ ccw_device_probe_console(void) | |||
1019 | /* | 1022 | /* |
1020 | * get ccw_device matching the busid, but only if owned by cdrv | 1023 | * get ccw_device matching the busid, but only if owned by cdrv |
1021 | */ | 1024 | */ |
1025 | static int | ||
1026 | __ccwdev_check_busid(struct device *dev, void *id) | ||
1027 | { | ||
1028 | char *bus_id; | ||
1029 | |||
1030 | bus_id = (char *)id; | ||
1031 | |||
1032 | return (strncmp(bus_id, dev->bus_id, BUS_ID_SIZE) == 0); | ||
1033 | } | ||
1034 | |||
1035 | |||
1022 | struct ccw_device * | 1036 | struct ccw_device * |
1023 | get_ccwdev_by_busid(struct ccw_driver *cdrv, const char *bus_id) | 1037 | get_ccwdev_by_busid(struct ccw_driver *cdrv, const char *bus_id) |
1024 | { | 1038 | { |
1025 | struct device *d, *dev; | 1039 | struct device *dev; |
1026 | struct device_driver *drv; | 1040 | struct device_driver *drv; |
1027 | 1041 | ||
1028 | drv = get_driver(&cdrv->driver); | 1042 | drv = get_driver(&cdrv->driver); |
1029 | if (!drv) | 1043 | if (!drv) |
1030 | return 0; | 1044 | return NULL; |
1031 | |||
1032 | down_read(&drv->bus->subsys.rwsem); | ||
1033 | |||
1034 | dev = NULL; | ||
1035 | list_for_each_entry(d, &drv->devices, driver_list) { | ||
1036 | dev = get_device(d); | ||
1037 | 1045 | ||
1038 | if (dev && !strncmp(bus_id, dev->bus_id, BUS_ID_SIZE)) | 1046 | dev = driver_find_device(drv, NULL, (void *)bus_id, |
1039 | break; | 1047 | __ccwdev_check_busid); |
1040 | else if (dev) { | ||
1041 | put_device(dev); | ||
1042 | dev = NULL; | ||
1043 | } | ||
1044 | } | ||
1045 | up_read(&drv->bus->subsys.rwsem); | ||
1046 | put_driver(drv); | 1048 | put_driver(drv); |
1047 | 1049 | ||
1048 | return dev ? to_ccwdev(dev) : 0; | 1050 | return dev ? to_ccwdev(dev) : 0; |
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index bbe9f45d1438..82194c4eadfb 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c | |||
@@ -56,7 +56,7 @@ | |||
56 | #include "ioasm.h" | 56 | #include "ioasm.h" |
57 | #include "chsc.h" | 57 | #include "chsc.h" |
58 | 58 | ||
59 | #define VERSION_QDIO_C "$Revision: 1.98 $" | 59 | #define VERSION_QDIO_C "$Revision: 1.101 $" |
60 | 60 | ||
61 | /****************** MODULE PARAMETER VARIABLES ********************/ | 61 | /****************** MODULE PARAMETER VARIABLES ********************/ |
62 | MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>"); | 62 | MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>"); |
@@ -3342,7 +3342,7 @@ static int | |||
3342 | qdio_register_dbf_views(void) | 3342 | qdio_register_dbf_views(void) |
3343 | { | 3343 | { |
3344 | qdio_dbf_setup=debug_register(QDIO_DBF_SETUP_NAME, | 3344 | qdio_dbf_setup=debug_register(QDIO_DBF_SETUP_NAME, |
3345 | QDIO_DBF_SETUP_INDEX, | 3345 | QDIO_DBF_SETUP_PAGES, |
3346 | QDIO_DBF_SETUP_NR_AREAS, | 3346 | QDIO_DBF_SETUP_NR_AREAS, |
3347 | QDIO_DBF_SETUP_LEN); | 3347 | QDIO_DBF_SETUP_LEN); |
3348 | if (!qdio_dbf_setup) | 3348 | if (!qdio_dbf_setup) |
@@ -3351,7 +3351,7 @@ qdio_register_dbf_views(void) | |||
3351 | debug_set_level(qdio_dbf_setup,QDIO_DBF_SETUP_LEVEL); | 3351 | debug_set_level(qdio_dbf_setup,QDIO_DBF_SETUP_LEVEL); |
3352 | 3352 | ||
3353 | qdio_dbf_sbal=debug_register(QDIO_DBF_SBAL_NAME, | 3353 | qdio_dbf_sbal=debug_register(QDIO_DBF_SBAL_NAME, |
3354 | QDIO_DBF_SBAL_INDEX, | 3354 | QDIO_DBF_SBAL_PAGES, |
3355 | QDIO_DBF_SBAL_NR_AREAS, | 3355 | QDIO_DBF_SBAL_NR_AREAS, |
3356 | QDIO_DBF_SBAL_LEN); | 3356 | QDIO_DBF_SBAL_LEN); |
3357 | if (!qdio_dbf_sbal) | 3357 | if (!qdio_dbf_sbal) |
@@ -3361,7 +3361,7 @@ qdio_register_dbf_views(void) | |||
3361 | debug_set_level(qdio_dbf_sbal,QDIO_DBF_SBAL_LEVEL); | 3361 | debug_set_level(qdio_dbf_sbal,QDIO_DBF_SBAL_LEVEL); |
3362 | 3362 | ||
3363 | qdio_dbf_sense=debug_register(QDIO_DBF_SENSE_NAME, | 3363 | qdio_dbf_sense=debug_register(QDIO_DBF_SENSE_NAME, |
3364 | QDIO_DBF_SENSE_INDEX, | 3364 | QDIO_DBF_SENSE_PAGES, |
3365 | QDIO_DBF_SENSE_NR_AREAS, | 3365 | QDIO_DBF_SENSE_NR_AREAS, |
3366 | QDIO_DBF_SENSE_LEN); | 3366 | QDIO_DBF_SENSE_LEN); |
3367 | if (!qdio_dbf_sense) | 3367 | if (!qdio_dbf_sense) |
@@ -3371,7 +3371,7 @@ qdio_register_dbf_views(void) | |||
3371 | debug_set_level(qdio_dbf_sense,QDIO_DBF_SENSE_LEVEL); | 3371 | debug_set_level(qdio_dbf_sense,QDIO_DBF_SENSE_LEVEL); |
3372 | 3372 | ||
3373 | qdio_dbf_trace=debug_register(QDIO_DBF_TRACE_NAME, | 3373 | qdio_dbf_trace=debug_register(QDIO_DBF_TRACE_NAME, |
3374 | QDIO_DBF_TRACE_INDEX, | 3374 | QDIO_DBF_TRACE_PAGES, |
3375 | QDIO_DBF_TRACE_NR_AREAS, | 3375 | QDIO_DBF_TRACE_NR_AREAS, |
3376 | QDIO_DBF_TRACE_LEN); | 3376 | QDIO_DBF_TRACE_LEN); |
3377 | if (!qdio_dbf_trace) | 3377 | if (!qdio_dbf_trace) |
@@ -3382,7 +3382,7 @@ qdio_register_dbf_views(void) | |||
3382 | 3382 | ||
3383 | #ifdef CONFIG_QDIO_DEBUG | 3383 | #ifdef CONFIG_QDIO_DEBUG |
3384 | qdio_dbf_slsb_out=debug_register(QDIO_DBF_SLSB_OUT_NAME, | 3384 | qdio_dbf_slsb_out=debug_register(QDIO_DBF_SLSB_OUT_NAME, |
3385 | QDIO_DBF_SLSB_OUT_INDEX, | 3385 | QDIO_DBF_SLSB_OUT_PAGES, |
3386 | QDIO_DBF_SLSB_OUT_NR_AREAS, | 3386 | QDIO_DBF_SLSB_OUT_NR_AREAS, |
3387 | QDIO_DBF_SLSB_OUT_LEN); | 3387 | QDIO_DBF_SLSB_OUT_LEN); |
3388 | if (!qdio_dbf_slsb_out) | 3388 | if (!qdio_dbf_slsb_out) |
@@ -3391,7 +3391,7 @@ qdio_register_dbf_views(void) | |||
3391 | debug_set_level(qdio_dbf_slsb_out,QDIO_DBF_SLSB_OUT_LEVEL); | 3391 | debug_set_level(qdio_dbf_slsb_out,QDIO_DBF_SLSB_OUT_LEVEL); |
3392 | 3392 | ||
3393 | qdio_dbf_slsb_in=debug_register(QDIO_DBF_SLSB_IN_NAME, | 3393 | qdio_dbf_slsb_in=debug_register(QDIO_DBF_SLSB_IN_NAME, |
3394 | QDIO_DBF_SLSB_IN_INDEX, | 3394 | QDIO_DBF_SLSB_IN_PAGES, |
3395 | QDIO_DBF_SLSB_IN_NR_AREAS, | 3395 | QDIO_DBF_SLSB_IN_NR_AREAS, |
3396 | QDIO_DBF_SLSB_IN_LEN); | 3396 | QDIO_DBF_SLSB_IN_LEN); |
3397 | if (!qdio_dbf_slsb_in) | 3397 | if (!qdio_dbf_slsb_in) |
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index b6daadac4e8b..6b8aa6a852be 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | #include <asm/page.h> | 4 | #include <asm/page.h> |
5 | 5 | ||
6 | #define VERSION_CIO_QDIO_H "$Revision: 1.32 $" | 6 | #define VERSION_CIO_QDIO_H "$Revision: 1.33 $" |
7 | 7 | ||
8 | #ifdef CONFIG_QDIO_DEBUG | 8 | #ifdef CONFIG_QDIO_DEBUG |
9 | #define QDIO_VERBOSE_LEVEL 9 | 9 | #define QDIO_VERBOSE_LEVEL 9 |
@@ -132,7 +132,7 @@ enum qdio_irq_states { | |||
132 | 132 | ||
133 | #define QDIO_DBF_SETUP_NAME "qdio_setup" | 133 | #define QDIO_DBF_SETUP_NAME "qdio_setup" |
134 | #define QDIO_DBF_SETUP_LEN 8 | 134 | #define QDIO_DBF_SETUP_LEN 8 |
135 | #define QDIO_DBF_SETUP_INDEX 2 | 135 | #define QDIO_DBF_SETUP_PAGES 4 |
136 | #define QDIO_DBF_SETUP_NR_AREAS 1 | 136 | #define QDIO_DBF_SETUP_NR_AREAS 1 |
137 | #ifdef CONFIG_QDIO_DEBUG | 137 | #ifdef CONFIG_QDIO_DEBUG |
138 | #define QDIO_DBF_SETUP_LEVEL 6 | 138 | #define QDIO_DBF_SETUP_LEVEL 6 |
@@ -142,7 +142,7 @@ enum qdio_irq_states { | |||
142 | 142 | ||
143 | #define QDIO_DBF_SBAL_NAME "qdio_labs" /* sbal */ | 143 | #define QDIO_DBF_SBAL_NAME "qdio_labs" /* sbal */ |
144 | #define QDIO_DBF_SBAL_LEN 256 | 144 | #define QDIO_DBF_SBAL_LEN 256 |
145 | #define QDIO_DBF_SBAL_INDEX 2 | 145 | #define QDIO_DBF_SBAL_PAGES 4 |
146 | #define QDIO_DBF_SBAL_NR_AREAS 2 | 146 | #define QDIO_DBF_SBAL_NR_AREAS 2 |
147 | #ifdef CONFIG_QDIO_DEBUG | 147 | #ifdef CONFIG_QDIO_DEBUG |
148 | #define QDIO_DBF_SBAL_LEVEL 6 | 148 | #define QDIO_DBF_SBAL_LEVEL 6 |
@@ -154,16 +154,16 @@ enum qdio_irq_states { | |||
154 | #define QDIO_DBF_TRACE_LEN 8 | 154 | #define QDIO_DBF_TRACE_LEN 8 |
155 | #define QDIO_DBF_TRACE_NR_AREAS 2 | 155 | #define QDIO_DBF_TRACE_NR_AREAS 2 |
156 | #ifdef CONFIG_QDIO_DEBUG | 156 | #ifdef CONFIG_QDIO_DEBUG |
157 | #define QDIO_DBF_TRACE_INDEX 4 | 157 | #define QDIO_DBF_TRACE_PAGES 16 |
158 | #define QDIO_DBF_TRACE_LEVEL 4 /* -------- could be even more verbose here */ | 158 | #define QDIO_DBF_TRACE_LEVEL 4 /* -------- could be even more verbose here */ |
159 | #else /* CONFIG_QDIO_DEBUG */ | 159 | #else /* CONFIG_QDIO_DEBUG */ |
160 | #define QDIO_DBF_TRACE_INDEX 2 | 160 | #define QDIO_DBF_TRACE_PAGES 4 |
161 | #define QDIO_DBF_TRACE_LEVEL 2 | 161 | #define QDIO_DBF_TRACE_LEVEL 2 |
162 | #endif /* CONFIG_QDIO_DEBUG */ | 162 | #endif /* CONFIG_QDIO_DEBUG */ |
163 | 163 | ||
164 | #define QDIO_DBF_SENSE_NAME "qdio_sense" | 164 | #define QDIO_DBF_SENSE_NAME "qdio_sense" |
165 | #define QDIO_DBF_SENSE_LEN 64 | 165 | #define QDIO_DBF_SENSE_LEN 64 |
166 | #define QDIO_DBF_SENSE_INDEX 1 | 166 | #define QDIO_DBF_SENSE_PAGES 2 |
167 | #define QDIO_DBF_SENSE_NR_AREAS 1 | 167 | #define QDIO_DBF_SENSE_NR_AREAS 1 |
168 | #ifdef CONFIG_QDIO_DEBUG | 168 | #ifdef CONFIG_QDIO_DEBUG |
169 | #define QDIO_DBF_SENSE_LEVEL 6 | 169 | #define QDIO_DBF_SENSE_LEVEL 6 |
@@ -176,13 +176,13 @@ enum qdio_irq_states { | |||
176 | 176 | ||
177 | #define QDIO_DBF_SLSB_OUT_NAME "qdio_slsb_out" | 177 | #define QDIO_DBF_SLSB_OUT_NAME "qdio_slsb_out" |
178 | #define QDIO_DBF_SLSB_OUT_LEN QDIO_MAX_BUFFERS_PER_Q | 178 | #define QDIO_DBF_SLSB_OUT_LEN QDIO_MAX_BUFFERS_PER_Q |
179 | #define QDIO_DBF_SLSB_OUT_INDEX 8 | 179 | #define QDIO_DBF_SLSB_OUT_PAGES 256 |
180 | #define QDIO_DBF_SLSB_OUT_NR_AREAS 1 | 180 | #define QDIO_DBF_SLSB_OUT_NR_AREAS 1 |
181 | #define QDIO_DBF_SLSB_OUT_LEVEL 6 | 181 | #define QDIO_DBF_SLSB_OUT_LEVEL 6 |
182 | 182 | ||
183 | #define QDIO_DBF_SLSB_IN_NAME "qdio_slsb_in" | 183 | #define QDIO_DBF_SLSB_IN_NAME "qdio_slsb_in" |
184 | #define QDIO_DBF_SLSB_IN_LEN QDIO_MAX_BUFFERS_PER_Q | 184 | #define QDIO_DBF_SLSB_IN_LEN QDIO_MAX_BUFFERS_PER_Q |
185 | #define QDIO_DBF_SLSB_IN_INDEX 8 | 185 | #define QDIO_DBF_SLSB_IN_PAGES 256 |
186 | #define QDIO_DBF_SLSB_IN_NR_AREAS 1 | 186 | #define QDIO_DBF_SLSB_IN_NR_AREAS 1 |
187 | #define QDIO_DBF_SLSB_IN_LEVEL 6 | 187 | #define QDIO_DBF_SLSB_IN_LEVEL 6 |
188 | #endif /* CONFIG_QDIO_DEBUG */ | 188 | #endif /* CONFIG_QDIO_DEBUG */ |
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c index a99927d54ebb..60440dbe3a27 100644 --- a/drivers/s390/net/claw.c +++ b/drivers/s390/net/claw.c | |||
@@ -146,8 +146,8 @@ claw_unregister_debug_facility(void) | |||
146 | static int | 146 | static int |
147 | claw_register_debug_facility(void) | 147 | claw_register_debug_facility(void) |
148 | { | 148 | { |
149 | claw_dbf_setup = debug_register("claw_setup", 1, 1, 8); | 149 | claw_dbf_setup = debug_register("claw_setup", 2, 1, 8); |
150 | claw_dbf_trace = debug_register("claw_trace", 1, 2, 8); | 150 | claw_dbf_trace = debug_register("claw_trace", 2, 2, 8); |
151 | if (claw_dbf_setup == NULL || claw_dbf_trace == NULL) { | 151 | if (claw_dbf_setup == NULL || claw_dbf_trace == NULL) { |
152 | printk(KERN_WARNING "Not enough memory for debug facility.\n"); | 152 | printk(KERN_WARNING "Not enough memory for debug facility.\n"); |
153 | claw_unregister_debug_facility(); | 153 | claw_unregister_debug_facility(); |
diff --git a/drivers/s390/net/ctcdbug.c b/drivers/s390/net/ctcdbug.c index 2c86bfa11b2f..0e2a8bb93032 100644 --- a/drivers/s390/net/ctcdbug.c +++ b/drivers/s390/net/ctcdbug.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * | 2 | * |
3 | * linux/drivers/s390/net/ctcdbug.c ($Revision: 1.4 $) | 3 | * linux/drivers/s390/net/ctcdbug.c ($Revision: 1.6 $) |
4 | * | 4 | * |
5 | * CTC / ESCON network driver - s390 dbf exploit. | 5 | * CTC / ESCON network driver - s390 dbf exploit. |
6 | * | 6 | * |
@@ -9,7 +9,7 @@ | |||
9 | * Author(s): Original Code written by | 9 | * Author(s): Original Code written by |
10 | * Peter Tiedemann (ptiedem@de.ibm.com) | 10 | * Peter Tiedemann (ptiedem@de.ibm.com) |
11 | * | 11 | * |
12 | * $Revision: 1.4 $ $Date: 2004/08/04 10:11:59 $ | 12 | * $Revision: 1.6 $ $Date: 2005/05/11 08:10:17 $ |
13 | * | 13 | * |
14 | * This program is free software; you can redistribute it and/or modify | 14 | * This program is free software; you can redistribute it and/or modify |
15 | * it under the terms of the GNU General Public License as published by | 15 | * it under the terms of the GNU General Public License as published by |
@@ -51,15 +51,15 @@ int | |||
51 | ctc_register_dbf_views(void) | 51 | ctc_register_dbf_views(void) |
52 | { | 52 | { |
53 | ctc_dbf_setup = debug_register(CTC_DBF_SETUP_NAME, | 53 | ctc_dbf_setup = debug_register(CTC_DBF_SETUP_NAME, |
54 | CTC_DBF_SETUP_INDEX, | 54 | CTC_DBF_SETUP_PAGES, |
55 | CTC_DBF_SETUP_NR_AREAS, | 55 | CTC_DBF_SETUP_NR_AREAS, |
56 | CTC_DBF_SETUP_LEN); | 56 | CTC_DBF_SETUP_LEN); |
57 | ctc_dbf_data = debug_register(CTC_DBF_DATA_NAME, | 57 | ctc_dbf_data = debug_register(CTC_DBF_DATA_NAME, |
58 | CTC_DBF_DATA_INDEX, | 58 | CTC_DBF_DATA_PAGES, |
59 | CTC_DBF_DATA_NR_AREAS, | 59 | CTC_DBF_DATA_NR_AREAS, |
60 | CTC_DBF_DATA_LEN); | 60 | CTC_DBF_DATA_LEN); |
61 | ctc_dbf_trace = debug_register(CTC_DBF_TRACE_NAME, | 61 | ctc_dbf_trace = debug_register(CTC_DBF_TRACE_NAME, |
62 | CTC_DBF_TRACE_INDEX, | 62 | CTC_DBF_TRACE_PAGES, |
63 | CTC_DBF_TRACE_NR_AREAS, | 63 | CTC_DBF_TRACE_NR_AREAS, |
64 | CTC_DBF_TRACE_LEN); | 64 | CTC_DBF_TRACE_LEN); |
65 | 65 | ||
diff --git a/drivers/s390/net/ctcdbug.h b/drivers/s390/net/ctcdbug.h index 7fe2ebd1792d..7d6afa1627c3 100644 --- a/drivers/s390/net/ctcdbug.h +++ b/drivers/s390/net/ctcdbug.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * | 2 | * |
3 | * linux/drivers/s390/net/ctcdbug.h ($Revision: 1.5 $) | 3 | * linux/drivers/s390/net/ctcdbug.h ($Revision: 1.6 $) |
4 | * | 4 | * |
5 | * CTC / ESCON network driver - s390 dbf exploit. | 5 | * CTC / ESCON network driver - s390 dbf exploit. |
6 | * | 6 | * |
@@ -9,7 +9,7 @@ | |||
9 | * Author(s): Original Code written by | 9 | * Author(s): Original Code written by |
10 | * Peter Tiedemann (ptiedem@de.ibm.com) | 10 | * Peter Tiedemann (ptiedem@de.ibm.com) |
11 | * | 11 | * |
12 | * $Revision: 1.5 $ $Date: 2005/02/27 19:46:44 $ | 12 | * $Revision: 1.6 $ $Date: 2005/05/11 08:10:17 $ |
13 | * | 13 | * |
14 | * This program is free software; you can redistribute it and/or modify | 14 | * This program is free software; you can redistribute it and/or modify |
15 | * it under the terms of the GNU General Public License as published by | 15 | * it under the terms of the GNU General Public License as published by |
@@ -35,19 +35,19 @@ | |||
35 | */ | 35 | */ |
36 | #define CTC_DBF_SETUP_NAME "ctc_setup" | 36 | #define CTC_DBF_SETUP_NAME "ctc_setup" |
37 | #define CTC_DBF_SETUP_LEN 16 | 37 | #define CTC_DBF_SETUP_LEN 16 |
38 | #define CTC_DBF_SETUP_INDEX 3 | 38 | #define CTC_DBF_SETUP_PAGES 8 |
39 | #define CTC_DBF_SETUP_NR_AREAS 1 | 39 | #define CTC_DBF_SETUP_NR_AREAS 1 |
40 | #define CTC_DBF_SETUP_LEVEL 3 | 40 | #define CTC_DBF_SETUP_LEVEL 3 |
41 | 41 | ||
42 | #define CTC_DBF_DATA_NAME "ctc_data" | 42 | #define CTC_DBF_DATA_NAME "ctc_data" |
43 | #define CTC_DBF_DATA_LEN 128 | 43 | #define CTC_DBF_DATA_LEN 128 |
44 | #define CTC_DBF_DATA_INDEX 3 | 44 | #define CTC_DBF_DATA_PAGES 8 |
45 | #define CTC_DBF_DATA_NR_AREAS 1 | 45 | #define CTC_DBF_DATA_NR_AREAS 1 |
46 | #define CTC_DBF_DATA_LEVEL 3 | 46 | #define CTC_DBF_DATA_LEVEL 3 |
47 | 47 | ||
48 | #define CTC_DBF_TRACE_NAME "ctc_trace" | 48 | #define CTC_DBF_TRACE_NAME "ctc_trace" |
49 | #define CTC_DBF_TRACE_LEN 16 | 49 | #define CTC_DBF_TRACE_LEN 16 |
50 | #define CTC_DBF_TRACE_INDEX 2 | 50 | #define CTC_DBF_TRACE_PAGES 4 |
51 | #define CTC_DBF_TRACE_NR_AREAS 2 | 51 | #define CTC_DBF_TRACE_NR_AREAS 2 |
52 | #define CTC_DBF_TRACE_LEVEL 3 | 52 | #define CTC_DBF_TRACE_LEVEL 3 |
53 | 53 | ||
diff --git a/drivers/s390/net/iucv.h b/drivers/s390/net/iucv.h index 198330217eff..0c4644d3d2f3 100644 --- a/drivers/s390/net/iucv.h +++ b/drivers/s390/net/iucv.h | |||
@@ -37,19 +37,19 @@ | |||
37 | */ | 37 | */ |
38 | #define IUCV_DBF_SETUP_NAME "iucv_setup" | 38 | #define IUCV_DBF_SETUP_NAME "iucv_setup" |
39 | #define IUCV_DBF_SETUP_LEN 32 | 39 | #define IUCV_DBF_SETUP_LEN 32 |
40 | #define IUCV_DBF_SETUP_INDEX 1 | 40 | #define IUCV_DBF_SETUP_PAGES 2 |
41 | #define IUCV_DBF_SETUP_NR_AREAS 1 | 41 | #define IUCV_DBF_SETUP_NR_AREAS 1 |
42 | #define IUCV_DBF_SETUP_LEVEL 3 | 42 | #define IUCV_DBF_SETUP_LEVEL 3 |
43 | 43 | ||
44 | #define IUCV_DBF_DATA_NAME "iucv_data" | 44 | #define IUCV_DBF_DATA_NAME "iucv_data" |
45 | #define IUCV_DBF_DATA_LEN 128 | 45 | #define IUCV_DBF_DATA_LEN 128 |
46 | #define IUCV_DBF_DATA_INDEX 1 | 46 | #define IUCV_DBF_DATA_PAGES 2 |
47 | #define IUCV_DBF_DATA_NR_AREAS 1 | 47 | #define IUCV_DBF_DATA_NR_AREAS 1 |
48 | #define IUCV_DBF_DATA_LEVEL 2 | 48 | #define IUCV_DBF_DATA_LEVEL 2 |
49 | 49 | ||
50 | #define IUCV_DBF_TRACE_NAME "iucv_trace" | 50 | #define IUCV_DBF_TRACE_NAME "iucv_trace" |
51 | #define IUCV_DBF_TRACE_LEN 16 | 51 | #define IUCV_DBF_TRACE_LEN 16 |
52 | #define IUCV_DBF_TRACE_INDEX 2 | 52 | #define IUCV_DBF_TRACE_PAGES 4 |
53 | #define IUCV_DBF_TRACE_NR_AREAS 1 | 53 | #define IUCV_DBF_TRACE_NR_AREAS 1 |
54 | #define IUCV_DBF_TRACE_LEVEL 3 | 54 | #define IUCV_DBF_TRACE_LEVEL 3 |
55 | 55 | ||
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index ab086242d305..46f34ba93ac5 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c | |||
@@ -11,7 +11,7 @@ | |||
11 | * Frank Pavlic (pavlic@de.ibm.com) and | 11 | * Frank Pavlic (pavlic@de.ibm.com) and |
12 | * Martin Schwidefsky <schwidefsky@de.ibm.com> | 12 | * Martin Schwidefsky <schwidefsky@de.ibm.com> |
13 | * | 13 | * |
14 | * $Revision: 1.98 $ $Date: 2005/04/18 13:41:29 $ | 14 | * $Revision: 1.99 $ $Date: 2005/05/11 08:10:17 $ |
15 | * | 15 | * |
16 | * This program is free software; you can redistribute it and/or modify | 16 | * This program is free software; you can redistribute it and/or modify |
17 | * it under the terms of the GNU General Public License as published by | 17 | * it under the terms of the GNU General Public License as published by |
@@ -59,7 +59,7 @@ | |||
59 | /** | 59 | /** |
60 | * initialization string for output | 60 | * initialization string for output |
61 | */ | 61 | */ |
62 | #define VERSION_LCS_C "$Revision: 1.98 $" | 62 | #define VERSION_LCS_C "$Revision: 1.99 $" |
63 | 63 | ||
64 | static char version[] __initdata = "LCS driver ("VERSION_LCS_C "/" VERSION_LCS_H ")"; | 64 | static char version[] __initdata = "LCS driver ("VERSION_LCS_C "/" VERSION_LCS_H ")"; |
65 | static char debug_buffer[255]; | 65 | static char debug_buffer[255]; |
@@ -93,8 +93,8 @@ lcs_unregister_debug_facility(void) | |||
93 | static int | 93 | static int |
94 | lcs_register_debug_facility(void) | 94 | lcs_register_debug_facility(void) |
95 | { | 95 | { |
96 | lcs_dbf_setup = debug_register("lcs_setup", 1, 1, 8); | 96 | lcs_dbf_setup = debug_register("lcs_setup", 2, 1, 8); |
97 | lcs_dbf_trace = debug_register("lcs_trace", 1, 2, 8); | 97 | lcs_dbf_trace = debug_register("lcs_trace", 2, 2, 8); |
98 | if (lcs_dbf_setup == NULL || lcs_dbf_trace == NULL) { | 98 | if (lcs_dbf_setup == NULL || lcs_dbf_trace == NULL) { |
99 | PRINT_ERR("Not enough memory for debug facility.\n"); | 99 | PRINT_ERR("Not enough memory for debug facility.\n"); |
100 | lcs_unregister_debug_facility(); | 100 | lcs_unregister_debug_facility(); |
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index 3fd4fb754b2d..69425a7a6e98 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: netiucv.c,v 1.63 2004/07/27 13:36:05 mschwide Exp $ | 2 | * $Id: netiucv.c,v 1.66 2005/05/11 08:10:17 holzheu Exp $ |
3 | * | 3 | * |
4 | * IUCV network driver | 4 | * IUCV network driver |
5 | * | 5 | * |
@@ -30,7 +30,7 @@ | |||
30 | * along with this program; if not, write to the Free Software | 30 | * along with this program; if not, write to the Free Software |
31 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 31 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
32 | * | 32 | * |
33 | * RELEASE-TAG: IUCV network driver $Revision: 1.63 $ | 33 | * RELEASE-TAG: IUCV network driver $Revision: 1.66 $ |
34 | * | 34 | * |
35 | */ | 35 | */ |
36 | 36 | ||
@@ -391,15 +391,15 @@ static int | |||
391 | iucv_register_dbf_views(void) | 391 | iucv_register_dbf_views(void) |
392 | { | 392 | { |
393 | iucv_dbf_setup = debug_register(IUCV_DBF_SETUP_NAME, | 393 | iucv_dbf_setup = debug_register(IUCV_DBF_SETUP_NAME, |
394 | IUCV_DBF_SETUP_INDEX, | 394 | IUCV_DBF_SETUP_PAGES, |
395 | IUCV_DBF_SETUP_NR_AREAS, | 395 | IUCV_DBF_SETUP_NR_AREAS, |
396 | IUCV_DBF_SETUP_LEN); | 396 | IUCV_DBF_SETUP_LEN); |
397 | iucv_dbf_data = debug_register(IUCV_DBF_DATA_NAME, | 397 | iucv_dbf_data = debug_register(IUCV_DBF_DATA_NAME, |
398 | IUCV_DBF_DATA_INDEX, | 398 | IUCV_DBF_DATA_PAGES, |
399 | IUCV_DBF_DATA_NR_AREAS, | 399 | IUCV_DBF_DATA_NR_AREAS, |
400 | IUCV_DBF_DATA_LEN); | 400 | IUCV_DBF_DATA_LEN); |
401 | iucv_dbf_trace = debug_register(IUCV_DBF_TRACE_NAME, | 401 | iucv_dbf_trace = debug_register(IUCV_DBF_TRACE_NAME, |
402 | IUCV_DBF_TRACE_INDEX, | 402 | IUCV_DBF_TRACE_PAGES, |
403 | IUCV_DBF_TRACE_NR_AREAS, | 403 | IUCV_DBF_TRACE_NR_AREAS, |
404 | IUCV_DBF_TRACE_LEN); | 404 | IUCV_DBF_TRACE_LEN); |
405 | 405 | ||
@@ -2076,7 +2076,7 @@ DRIVER_ATTR(remove, 0200, NULL, remove_write); | |||
2076 | static void | 2076 | static void |
2077 | netiucv_banner(void) | 2077 | netiucv_banner(void) |
2078 | { | 2078 | { |
2079 | char vbuf[] = "$Revision: 1.63 $"; | 2079 | char vbuf[] = "$Revision: 1.66 $"; |
2080 | char *version = vbuf; | 2080 | char *version = vbuf; |
2081 | 2081 | ||
2082 | if ((version = strchr(version, ':'))) { | 2082 | if ((version = strchr(version, ':'))) { |
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h index a755b57db46b..008e0a5d2eb3 100644 --- a/drivers/s390/net/qeth.h +++ b/drivers/s390/net/qeth.h | |||
@@ -42,44 +42,44 @@ | |||
42 | */ | 42 | */ |
43 | #define QETH_DBF_SETUP_NAME "qeth_setup" | 43 | #define QETH_DBF_SETUP_NAME "qeth_setup" |
44 | #define QETH_DBF_SETUP_LEN 8 | 44 | #define QETH_DBF_SETUP_LEN 8 |
45 | #define QETH_DBF_SETUP_INDEX 3 | 45 | #define QETH_DBF_SETUP_PAGES 8 |
46 | #define QETH_DBF_SETUP_NR_AREAS 1 | 46 | #define QETH_DBF_SETUP_NR_AREAS 1 |
47 | #define QETH_DBF_SETUP_LEVEL 5 | 47 | #define QETH_DBF_SETUP_LEVEL 5 |
48 | 48 | ||
49 | #define QETH_DBF_MISC_NAME "qeth_misc" | 49 | #define QETH_DBF_MISC_NAME "qeth_misc" |
50 | #define QETH_DBF_MISC_LEN 128 | 50 | #define QETH_DBF_MISC_LEN 128 |
51 | #define QETH_DBF_MISC_INDEX 1 | 51 | #define QETH_DBF_MISC_PAGES 2 |
52 | #define QETH_DBF_MISC_NR_AREAS 1 | 52 | #define QETH_DBF_MISC_NR_AREAS 1 |
53 | #define QETH_DBF_MISC_LEVEL 2 | 53 | #define QETH_DBF_MISC_LEVEL 2 |
54 | 54 | ||
55 | #define QETH_DBF_DATA_NAME "qeth_data" | 55 | #define QETH_DBF_DATA_NAME "qeth_data" |
56 | #define QETH_DBF_DATA_LEN 96 | 56 | #define QETH_DBF_DATA_LEN 96 |
57 | #define QETH_DBF_DATA_INDEX 3 | 57 | #define QETH_DBF_DATA_PAGES 8 |
58 | #define QETH_DBF_DATA_NR_AREAS 1 | 58 | #define QETH_DBF_DATA_NR_AREAS 1 |
59 | #define QETH_DBF_DATA_LEVEL 2 | 59 | #define QETH_DBF_DATA_LEVEL 2 |
60 | 60 | ||
61 | #define QETH_DBF_CONTROL_NAME "qeth_control" | 61 | #define QETH_DBF_CONTROL_NAME "qeth_control" |
62 | #define QETH_DBF_CONTROL_LEN 256 | 62 | #define QETH_DBF_CONTROL_LEN 256 |
63 | #define QETH_DBF_CONTROL_INDEX 3 | 63 | #define QETH_DBF_CONTROL_PAGES 8 |
64 | #define QETH_DBF_CONTROL_NR_AREAS 2 | 64 | #define QETH_DBF_CONTROL_NR_AREAS 2 |
65 | #define QETH_DBF_CONTROL_LEVEL 5 | 65 | #define QETH_DBF_CONTROL_LEVEL 5 |
66 | 66 | ||
67 | #define QETH_DBF_TRACE_NAME "qeth_trace" | 67 | #define QETH_DBF_TRACE_NAME "qeth_trace" |
68 | #define QETH_DBF_TRACE_LEN 8 | 68 | #define QETH_DBF_TRACE_LEN 8 |
69 | #define QETH_DBF_TRACE_INDEX 2 | 69 | #define QETH_DBF_TRACE_PAGES 4 |
70 | #define QETH_DBF_TRACE_NR_AREAS 2 | 70 | #define QETH_DBF_TRACE_NR_AREAS 2 |
71 | #define QETH_DBF_TRACE_LEVEL 3 | 71 | #define QETH_DBF_TRACE_LEVEL 3 |
72 | extern debug_info_t *qeth_dbf_trace; | 72 | extern debug_info_t *qeth_dbf_trace; |
73 | 73 | ||
74 | #define QETH_DBF_SENSE_NAME "qeth_sense" | 74 | #define QETH_DBF_SENSE_NAME "qeth_sense" |
75 | #define QETH_DBF_SENSE_LEN 64 | 75 | #define QETH_DBF_SENSE_LEN 64 |
76 | #define QETH_DBF_SENSE_INDEX 1 | 76 | #define QETH_DBF_SENSE_PAGES 2 |
77 | #define QETH_DBF_SENSE_NR_AREAS 1 | 77 | #define QETH_DBF_SENSE_NR_AREAS 1 |
78 | #define QETH_DBF_SENSE_LEVEL 2 | 78 | #define QETH_DBF_SENSE_LEVEL 2 |
79 | 79 | ||
80 | #define QETH_DBF_QERR_NAME "qeth_qerr" | 80 | #define QETH_DBF_QERR_NAME "qeth_qerr" |
81 | #define QETH_DBF_QERR_LEN 8 | 81 | #define QETH_DBF_QERR_LEN 8 |
82 | #define QETH_DBF_QERR_INDEX 1 | 82 | #define QETH_DBF_QERR_PAGES 2 |
83 | #define QETH_DBF_QERR_NR_AREAS 2 | 83 | #define QETH_DBF_QERR_NR_AREAS 2 |
84 | #define QETH_DBF_QERR_LEVEL 2 | 84 | #define QETH_DBF_QERR_LEVEL 2 |
85 | 85 | ||
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 208127a5033a..3cb88c770037 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c | |||
@@ -7639,31 +7639,31 @@ static int | |||
7639 | qeth_register_dbf_views(void) | 7639 | qeth_register_dbf_views(void) |
7640 | { | 7640 | { |
7641 | qeth_dbf_setup = debug_register(QETH_DBF_SETUP_NAME, | 7641 | qeth_dbf_setup = debug_register(QETH_DBF_SETUP_NAME, |
7642 | QETH_DBF_SETUP_INDEX, | 7642 | QETH_DBF_SETUP_PAGES, |
7643 | QETH_DBF_SETUP_NR_AREAS, | 7643 | QETH_DBF_SETUP_NR_AREAS, |
7644 | QETH_DBF_SETUP_LEN); | 7644 | QETH_DBF_SETUP_LEN); |
7645 | qeth_dbf_misc = debug_register(QETH_DBF_MISC_NAME, | 7645 | qeth_dbf_misc = debug_register(QETH_DBF_MISC_NAME, |
7646 | QETH_DBF_MISC_INDEX, | 7646 | QETH_DBF_MISC_PAGES, |
7647 | QETH_DBF_MISC_NR_AREAS, | 7647 | QETH_DBF_MISC_NR_AREAS, |
7648 | QETH_DBF_MISC_LEN); | 7648 | QETH_DBF_MISC_LEN); |
7649 | qeth_dbf_data = debug_register(QETH_DBF_DATA_NAME, | 7649 | qeth_dbf_data = debug_register(QETH_DBF_DATA_NAME, |
7650 | QETH_DBF_DATA_INDEX, | 7650 | QETH_DBF_DATA_PAGES, |
7651 | QETH_DBF_DATA_NR_AREAS, | 7651 | QETH_DBF_DATA_NR_AREAS, |
7652 | QETH_DBF_DATA_LEN); | 7652 | QETH_DBF_DATA_LEN); |
7653 | qeth_dbf_control = debug_register(QETH_DBF_CONTROL_NAME, | 7653 | qeth_dbf_control = debug_register(QETH_DBF_CONTROL_NAME, |
7654 | QETH_DBF_CONTROL_INDEX, | 7654 | QETH_DBF_CONTROL_PAGES, |
7655 | QETH_DBF_CONTROL_NR_AREAS, | 7655 | QETH_DBF_CONTROL_NR_AREAS, |
7656 | QETH_DBF_CONTROL_LEN); | 7656 | QETH_DBF_CONTROL_LEN); |
7657 | qeth_dbf_sense = debug_register(QETH_DBF_SENSE_NAME, | 7657 | qeth_dbf_sense = debug_register(QETH_DBF_SENSE_NAME, |
7658 | QETH_DBF_SENSE_INDEX, | 7658 | QETH_DBF_SENSE_PAGES, |
7659 | QETH_DBF_SENSE_NR_AREAS, | 7659 | QETH_DBF_SENSE_NR_AREAS, |
7660 | QETH_DBF_SENSE_LEN); | 7660 | QETH_DBF_SENSE_LEN); |
7661 | qeth_dbf_qerr = debug_register(QETH_DBF_QERR_NAME, | 7661 | qeth_dbf_qerr = debug_register(QETH_DBF_QERR_NAME, |
7662 | QETH_DBF_QERR_INDEX, | 7662 | QETH_DBF_QERR_PAGES, |
7663 | QETH_DBF_QERR_NR_AREAS, | 7663 | QETH_DBF_QERR_NR_AREAS, |
7664 | QETH_DBF_QERR_LEN); | 7664 | QETH_DBF_QERR_LEN); |
7665 | qeth_dbf_trace = debug_register(QETH_DBF_TRACE_NAME, | 7665 | qeth_dbf_trace = debug_register(QETH_DBF_TRACE_NAME, |
7666 | QETH_DBF_TRACE_INDEX, | 7666 | QETH_DBF_TRACE_PAGES, |
7667 | QETH_DBF_TRACE_NR_AREAS, | 7667 | QETH_DBF_TRACE_NR_AREAS, |
7668 | QETH_DBF_TRACE_LEN); | 7668 | QETH_DBF_TRACE_LEN); |
7669 | 7669 | ||
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c index 1e3f7f3c662f..d6469baa7e16 100644 --- a/drivers/s390/net/smsgiucv.c +++ b/drivers/s390/net/smsgiucv.c | |||
@@ -138,7 +138,7 @@ static void __exit | |||
138 | smsg_exit(void) | 138 | smsg_exit(void) |
139 | { | 139 | { |
140 | if (smsg_handle > 0) { | 140 | if (smsg_handle > 0) { |
141 | cpcmd("SET SMSG OFF", 0, 0); | 141 | cpcmd("SET SMSG OFF", NULL, 0, NULL); |
142 | iucv_sever(smsg_pathid, 0); | 142 | iucv_sever(smsg_pathid, 0); |
143 | iucv_unregister_program(smsg_handle); | 143 | iucv_unregister_program(smsg_handle); |
144 | driver_unregister(&smsg_driver); | 144 | driver_unregister(&smsg_driver); |
@@ -177,7 +177,7 @@ smsg_init(void) | |||
177 | smsg_handle = 0; | 177 | smsg_handle = 0; |
178 | return -EIO; | 178 | return -EIO; |
179 | } | 179 | } |
180 | cpcmd("SET SMSG IUCV", 0, 0); | 180 | cpcmd("SET SMSG IUCV", NULL, 0, NULL); |
181 | return 0; | 181 | return 0; |
182 | } | 182 | } |
183 | 183 | ||
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c index ffa996c8a908..5bb255e02acc 100644 --- a/drivers/s390/s390mach.c +++ b/drivers/s390/s390mach.c | |||
@@ -31,14 +31,14 @@ extern void css_reiterate_subchannels(void); | |||
31 | extern struct workqueue_struct *slow_path_wq; | 31 | extern struct workqueue_struct *slow_path_wq; |
32 | extern struct work_struct slow_path_work; | 32 | extern struct work_struct slow_path_work; |
33 | 33 | ||
34 | static void | 34 | static NORET_TYPE void |
35 | s390_handle_damage(char *msg) | 35 | s390_handle_damage(char *msg) |
36 | { | 36 | { |
37 | printk(KERN_EMERG "%s\n", msg); | ||
38 | #ifdef CONFIG_SMP | 37 | #ifdef CONFIG_SMP |
39 | smp_send_stop(); | 38 | smp_send_stop(); |
40 | #endif | 39 | #endif |
41 | disabled_wait((unsigned long) __builtin_return_address(0)); | 40 | disabled_wait((unsigned long) __builtin_return_address(0)); |
41 | for(;;); | ||
42 | } | 42 | } |
43 | 43 | ||
44 | /* | 44 | /* |
@@ -122,40 +122,39 @@ repeat: | |||
122 | return 0; | 122 | return 0; |
123 | } | 123 | } |
124 | 124 | ||
125 | struct mcck_struct { | ||
126 | int kill_task; | ||
127 | int channel_report; | ||
128 | int warning; | ||
129 | unsigned long long mcck_code; | ||
130 | }; | ||
131 | |||
132 | static DEFINE_PER_CPU(struct mcck_struct, cpu_mcck); | ||
133 | |||
125 | /* | 134 | /* |
126 | * machine check handler. | 135 | * Main machine check handler function. Will be called with interrupts enabled |
136 | * or disabled and machine checks enabled or disabled. | ||
127 | */ | 137 | */ |
128 | void | 138 | void |
129 | s390_do_machine_check(void) | 139 | s390_handle_mcck(void) |
130 | { | 140 | { |
131 | struct mci *mci; | 141 | unsigned long flags; |
132 | 142 | struct mcck_struct mcck; | |
133 | mci = (struct mci *) &S390_lowcore.mcck_interruption_code; | ||
134 | 143 | ||
135 | if (mci->sd) /* system damage */ | 144 | /* |
136 | s390_handle_damage("received system damage machine check\n"); | 145 | * Disable machine checks and get the current state of accumulated |
146 | * machine checks. Afterwards delete the old state and enable machine | ||
147 | * checks again. | ||
148 | */ | ||
149 | local_irq_save(flags); | ||
150 | local_mcck_disable(); | ||
151 | mcck = __get_cpu_var(cpu_mcck); | ||
152 | memset(&__get_cpu_var(cpu_mcck), 0, sizeof(struct mcck_struct)); | ||
153 | clear_thread_flag(TIF_MCCK_PENDING); | ||
154 | local_mcck_enable(); | ||
155 | local_irq_restore(flags); | ||
137 | 156 | ||
138 | if (mci->pd) /* instruction processing damage */ | 157 | if (mcck.channel_report) |
139 | s390_handle_damage("received instruction processing " | ||
140 | "damage machine check\n"); | ||
141 | |||
142 | if (mci->se) /* storage error uncorrected */ | ||
143 | s390_handle_damage("received storage error uncorrected " | ||
144 | "machine check\n"); | ||
145 | |||
146 | if (mci->sc) /* storage error corrected */ | ||
147 | printk(KERN_WARNING | ||
148 | "received storage error corrected machine check\n"); | ||
149 | |||
150 | if (mci->ke) /* storage key-error uncorrected */ | ||
151 | s390_handle_damage("received storage key-error uncorrected " | ||
152 | "machine check\n"); | ||
153 | |||
154 | if (mci->ds && mci->fa) /* storage degradation */ | ||
155 | s390_handle_damage("received storage degradation machine " | ||
156 | "check\n"); | ||
157 | |||
158 | if (mci->cp) /* channel report word pending */ | ||
159 | up(&m_sem); | 158 | up(&m_sem); |
160 | 159 | ||
161 | #ifdef CONFIG_MACHCHK_WARNING | 160 | #ifdef CONFIG_MACHCHK_WARNING |
@@ -168,7 +167,7 @@ s390_do_machine_check(void) | |||
168 | * On VM we only get one interrupt per virtally presented machinecheck. | 167 | * On VM we only get one interrupt per virtally presented machinecheck. |
169 | * Though one suffices, we may get one interrupt per (virtual) processor. | 168 | * Though one suffices, we may get one interrupt per (virtual) processor. |
170 | */ | 169 | */ |
171 | if (mci->w) { /* WARNING pending ? */ | 170 | if (mcck.warning) { /* WARNING pending ? */ |
172 | static int mchchk_wng_posted = 0; | 171 | static int mchchk_wng_posted = 0; |
173 | /* | 172 | /* |
174 | * Use single machine clear, as we cannot handle smp right now | 173 | * Use single machine clear, as we cannot handle smp right now |
@@ -178,6 +177,261 @@ s390_do_machine_check(void) | |||
178 | kill_proc(1, SIGPWR, 1); | 177 | kill_proc(1, SIGPWR, 1); |
179 | } | 178 | } |
180 | #endif | 179 | #endif |
180 | |||
181 | if (mcck.kill_task) { | ||
182 | local_irq_enable(); | ||
183 | printk(KERN_EMERG "mcck: Terminating task because of machine " | ||
184 | "malfunction (code 0x%016llx).\n", mcck.mcck_code); | ||
185 | printk(KERN_EMERG "mcck: task: %s, pid: %d.\n", | ||
186 | current->comm, current->pid); | ||
187 | do_exit(SIGSEGV); | ||
188 | } | ||
189 | } | ||
190 | |||
191 | /* | ||
192 | * returns 0 if all registers could be validated | ||
193 | * returns 1 otherwise | ||
194 | */ | ||
195 | static int | ||
196 | s390_revalidate_registers(struct mci *mci) | ||
197 | { | ||
198 | int kill_task; | ||
199 | u64 tmpclock; | ||
200 | u64 zero; | ||
201 | void *fpt_save_area, *fpt_creg_save_area; | ||
202 | |||
203 | kill_task = 0; | ||
204 | zero = 0; | ||
205 | /* General purpose registers */ | ||
206 | if (!mci->gr) | ||
207 | /* | ||
208 | * General purpose registers couldn't be restored and have | ||
209 | * unknown contents. Process needs to be terminated. | ||
210 | */ | ||
211 | kill_task = 1; | ||
212 | |||
213 | /* Revalidate floating point registers */ | ||
214 | if (!mci->fp) | ||
215 | /* | ||
216 | * Floating point registers can't be restored and | ||
217 | * therefore the process needs to be terminated. | ||
218 | */ | ||
219 | kill_task = 1; | ||
220 | |||
221 | #ifndef __s390x__ | ||
222 | asm volatile("ld 0,0(%0)\n" | ||
223 | "ld 2,8(%0)\n" | ||
224 | "ld 4,16(%0)\n" | ||
225 | "ld 6,24(%0)" | ||
226 | : : "a" (&S390_lowcore.floating_pt_save_area)); | ||
227 | #endif | ||
228 | |||
229 | if (MACHINE_HAS_IEEE) { | ||
230 | #ifdef __s390x__ | ||
231 | fpt_save_area = &S390_lowcore.floating_pt_save_area; | ||
232 | fpt_creg_save_area = &S390_lowcore.fpt_creg_save_area; | ||
233 | #else | ||
234 | fpt_save_area = (void *) S390_lowcore.extended_save_area_addr; | ||
235 | fpt_creg_save_area = fpt_save_area+128; | ||
236 | #endif | ||
237 | /* Floating point control register */ | ||
238 | if (!mci->fc) { | ||
239 | /* | ||
240 | * Floating point control register can't be restored. | ||
241 | * Task will be terminated. | ||
242 | */ | ||
243 | asm volatile ("lfpc 0(%0)" : : "a" (&zero)); | ||
244 | kill_task = 1; | ||
245 | |||
246 | } | ||
247 | else | ||
248 | asm volatile ( | ||
249 | "lfpc 0(%0)" | ||
250 | : : "a" (fpt_creg_save_area)); | ||
251 | |||
252 | asm volatile("ld 0,0(%0)\n" | ||
253 | "ld 1,8(%0)\n" | ||
254 | "ld 2,16(%0)\n" | ||
255 | "ld 3,24(%0)\n" | ||
256 | "ld 4,32(%0)\n" | ||
257 | "ld 5,40(%0)\n" | ||
258 | "ld 6,48(%0)\n" | ||
259 | "ld 7,56(%0)\n" | ||
260 | "ld 8,64(%0)\n" | ||
261 | "ld 9,72(%0)\n" | ||
262 | "ld 10,80(%0)\n" | ||
263 | "ld 11,88(%0)\n" | ||
264 | "ld 12,96(%0)\n" | ||
265 | "ld 13,104(%0)\n" | ||
266 | "ld 14,112(%0)\n" | ||
267 | "ld 15,120(%0)\n" | ||
268 | : : "a" (fpt_save_area)); | ||
269 | } | ||
270 | |||
271 | /* Revalidate access registers */ | ||
272 | asm volatile("lam 0,15,0(%0)" | ||
273 | : : "a" (&S390_lowcore.access_regs_save_area)); | ||
274 | if (!mci->ar) | ||
275 | /* | ||
276 | * Access registers have unknown contents. | ||
277 | * Terminating task. | ||
278 | */ | ||
279 | kill_task = 1; | ||
280 | |||
281 | /* Revalidate control registers */ | ||
282 | if (!mci->cr) | ||
283 | /* | ||
284 | * Control registers have unknown contents. | ||
285 | * Can't recover and therefore stopping machine. | ||
286 | */ | ||
287 | s390_handle_damage("invalid control registers."); | ||
288 | else | ||
289 | #ifdef __s390x__ | ||
290 | asm volatile("lctlg 0,15,0(%0)" | ||
291 | : : "a" (&S390_lowcore.cregs_save_area)); | ||
292 | #else | ||
293 | asm volatile("lctl 0,15,0(%0)" | ||
294 | : : "a" (&S390_lowcore.cregs_save_area)); | ||
295 | #endif | ||
296 | |||
297 | /* | ||
298 | * We don't even try to revalidate the TOD register, since we simply | ||
299 | * can't write something sensible into that register. | ||
300 | */ | ||
301 | |||
302 | #ifdef __s390x__ | ||
303 | /* | ||
304 | * See if we can revalidate the TOD programmable register with its | ||
305 | * old contents (should be zero) otherwise set it to zero. | ||
306 | */ | ||
307 | if (!mci->pr) | ||
308 | asm volatile("sr 0,0\n" | ||
309 | "sckpf" | ||
310 | : : : "0", "cc"); | ||
311 | else | ||
312 | asm volatile( | ||
313 | "l 0,0(%0)\n" | ||
314 | "sckpf" | ||
315 | : : "a" (&S390_lowcore.tod_progreg_save_area) : "0", "cc"); | ||
316 | #endif | ||
317 | |||
318 | /* Revalidate clock comparator register */ | ||
319 | asm volatile ("stck 0(%1)\n" | ||
320 | "sckc 0(%1)" | ||
321 | : "=m" (tmpclock) : "a" (&(tmpclock)) : "cc", "memory"); | ||
322 | |||
323 | /* Check if old PSW is valid */ | ||
324 | if (!mci->wp) | ||
325 | /* | ||
326 | * Can't tell if we come from user or kernel mode | ||
327 | * -> stopping machine. | ||
328 | */ | ||
329 | s390_handle_damage("old psw invalid."); | ||
330 | |||
331 | if (!mci->ms || !mci->pm || !mci->ia) | ||
332 | kill_task = 1; | ||
333 | |||
334 | return kill_task; | ||
335 | } | ||
336 | |||
337 | /* | ||
338 | * machine check handler. | ||
339 | */ | ||
340 | void | ||
341 | s390_do_machine_check(struct pt_regs *regs) | ||
342 | { | ||
343 | struct mci *mci; | ||
344 | struct mcck_struct *mcck; | ||
345 | int umode; | ||
346 | |||
347 | mci = (struct mci *) &S390_lowcore.mcck_interruption_code; | ||
348 | mcck = &__get_cpu_var(cpu_mcck); | ||
349 | umode = user_mode(regs); | ||
350 | |||
351 | if (mci->sd) | ||
352 | /* System damage -> stopping machine */ | ||
353 | s390_handle_damage("received system damage machine check."); | ||
354 | |||
355 | if (mci->pd) { | ||
356 | if (mci->b) { | ||
357 | /* Processing backup -> verify if we can survive this */ | ||
358 | u64 z_mcic, o_mcic, t_mcic; | ||
359 | #ifdef __s390x__ | ||
360 | z_mcic = (1ULL<<63 | 1ULL<<59 | 1ULL<<29); | ||
361 | o_mcic = (1ULL<<43 | 1ULL<<42 | 1ULL<<41 | 1ULL<<40 | | ||
362 | 1ULL<<36 | 1ULL<<35 | 1ULL<<34 | 1ULL<<32 | | ||
363 | 1ULL<<30 | 1ULL<<21 | 1ULL<<20 | 1ULL<<17 | | ||
364 | 1ULL<<16); | ||
365 | #else | ||
366 | z_mcic = (1ULL<<63 | 1ULL<<59 | 1ULL<<57 | 1ULL<<50 | | ||
367 | 1ULL<<29); | ||
368 | o_mcic = (1ULL<<43 | 1ULL<<42 | 1ULL<<41 | 1ULL<<40 | | ||
369 | 1ULL<<36 | 1ULL<<35 | 1ULL<<34 | 1ULL<<32 | | ||
370 | 1ULL<<30 | 1ULL<<20 | 1ULL<<17 | 1ULL<<16); | ||
371 | #endif | ||
372 | t_mcic = *(u64 *)mci; | ||
373 | |||
374 | if (((t_mcic & z_mcic) != 0) || | ||
375 | ((t_mcic & o_mcic) != o_mcic)) { | ||
376 | s390_handle_damage("processing backup machine " | ||
377 | "check with damage."); | ||
378 | } | ||
379 | if (!umode) | ||
380 | s390_handle_damage("processing backup machine " | ||
381 | "check in kernel mode."); | ||
382 | mcck->kill_task = 1; | ||
383 | mcck->mcck_code = *(unsigned long long *) mci; | ||
384 | } | ||
385 | else { | ||
386 | /* Processing damage -> stopping machine */ | ||
387 | s390_handle_damage("received instruction processing " | ||
388 | "damage machine check."); | ||
389 | } | ||
390 | } | ||
391 | if (s390_revalidate_registers(mci)) { | ||
392 | if (umode) { | ||
393 | /* | ||
394 | * Couldn't restore all register contents while in | ||
395 | * user mode -> mark task for termination. | ||
396 | */ | ||
397 | mcck->kill_task = 1; | ||
398 | mcck->mcck_code = *(unsigned long long *) mci; | ||
399 | set_thread_flag(TIF_MCCK_PENDING); | ||
400 | } | ||
401 | else | ||
402 | /* | ||
403 | * Couldn't restore all register contents while in | ||
404 | * kernel mode -> stopping machine. | ||
405 | */ | ||
406 | s390_handle_damage("unable to revalidate registers."); | ||
407 | } | ||
408 | |||
409 | if (mci->se) | ||
410 | /* Storage error uncorrected */ | ||
411 | s390_handle_damage("received storage error uncorrected " | ||
412 | "machine check."); | ||
413 | |||
414 | if (mci->ke) | ||
415 | /* Storage key-error uncorrected */ | ||
416 | s390_handle_damage("received storage key-error uncorrected " | ||
417 | "machine check."); | ||
418 | |||
419 | if (mci->ds && mci->fa) | ||
420 | /* Storage degradation */ | ||
421 | s390_handle_damage("received storage degradation machine " | ||
422 | "check."); | ||
423 | |||
424 | if (mci->cp) { | ||
425 | /* Channel report word pending */ | ||
426 | mcck->channel_report = 1; | ||
427 | set_thread_flag(TIF_MCCK_PENDING); | ||
428 | } | ||
429 | |||
430 | if (mci->w) { | ||
431 | /* Warning pending */ | ||
432 | mcck->warning = 1; | ||
433 | set_thread_flag(TIF_MCCK_PENDING); | ||
434 | } | ||
181 | } | 435 | } |
182 | 436 | ||
183 | /* | 437 | /* |
@@ -189,9 +443,8 @@ static int | |||
189 | machine_check_init(void) | 443 | machine_check_init(void) |
190 | { | 444 | { |
191 | init_MUTEX_LOCKED(&m_sem); | 445 | init_MUTEX_LOCKED(&m_sem); |
192 | ctl_clear_bit(14, 25); /* disable damage MCH */ | 446 | ctl_clear_bit(14, 25); /* disable external damage MCH */ |
193 | ctl_set_bit(14, 26); /* enable degradation MCH */ | 447 | ctl_set_bit(14, 27); /* enable system recovery MCH */ |
194 | ctl_set_bit(14, 27); /* enable system recovery MCH */ | ||
195 | #ifdef CONFIG_MACHCHK_WARNING | 448 | #ifdef CONFIG_MACHCHK_WARNING |
196 | ctl_set_bit(14, 24); /* enable warning MCH */ | 449 | ctl_set_bit(14, 24); /* enable warning MCH */ |
197 | #endif | 450 | #endif |
diff --git a/drivers/s390/s390mach.h b/drivers/s390/s390mach.h index 7e26f0f1b0dc..4eaa70179182 100644 --- a/drivers/s390/s390mach.h +++ b/drivers/s390/s390mach.h | |||
@@ -16,20 +16,45 @@ struct mci { | |||
16 | __u32 sd : 1; /* 00 system damage */ | 16 | __u32 sd : 1; /* 00 system damage */ |
17 | __u32 pd : 1; /* 01 instruction-processing damage */ | 17 | __u32 pd : 1; /* 01 instruction-processing damage */ |
18 | __u32 sr : 1; /* 02 system recovery */ | 18 | __u32 sr : 1; /* 02 system recovery */ |
19 | __u32 to_be_defined_1 : 4; /* 03-06 */ | 19 | __u32 to_be_defined_1 : 1; /* 03 */ |
20 | __u32 cd : 1; /* 04 timing-facility damage */ | ||
21 | __u32 ed : 1; /* 05 external damage */ | ||
22 | __u32 to_be_defined_2 : 1; /* 06 */ | ||
20 | __u32 dg : 1; /* 07 degradation */ | 23 | __u32 dg : 1; /* 07 degradation */ |
21 | __u32 w : 1; /* 08 warning pending */ | 24 | __u32 w : 1; /* 08 warning pending */ |
22 | __u32 cp : 1; /* 09 channel-report pending */ | 25 | __u32 cp : 1; /* 09 channel-report pending */ |
23 | __u32 to_be_defined_2 : 6; /* 10-15 */ | 26 | __u32 sp : 1; /* 10 service-processor damage */ |
27 | __u32 ck : 1; /* 11 channel-subsystem damage */ | ||
28 | __u32 to_be_defined_3 : 2; /* 12-13 */ | ||
29 | __u32 b : 1; /* 14 backed up */ | ||
30 | __u32 to_be_defined_4 : 1; /* 15 */ | ||
24 | __u32 se : 1; /* 16 storage error uncorrected */ | 31 | __u32 se : 1; /* 16 storage error uncorrected */ |
25 | __u32 sc : 1; /* 17 storage error corrected */ | 32 | __u32 sc : 1; /* 17 storage error corrected */ |
26 | __u32 ke : 1; /* 18 storage-key error uncorrected */ | 33 | __u32 ke : 1; /* 18 storage-key error uncorrected */ |
27 | __u32 ds : 1; /* 19 storage degradation */ | 34 | __u32 ds : 1; /* 19 storage degradation */ |
28 | __u32 to_be_defined_3 : 4; /* 20-23 */ | 35 | __u32 wp : 1; /* 20 psw mwp validity */ |
36 | __u32 ms : 1; /* 21 psw mask and key validity */ | ||
37 | __u32 pm : 1; /* 22 psw program mask and cc validity */ | ||
38 | __u32 ia : 1; /* 23 psw instruction address validity */ | ||
29 | __u32 fa : 1; /* 24 failing storage address validity */ | 39 | __u32 fa : 1; /* 24 failing storage address validity */ |
30 | __u32 to_be_defined_4 : 7; /* 25-31 */ | 40 | __u32 to_be_defined_5 : 1; /* 25 */ |
41 | __u32 ec : 1; /* 26 external damage code validity */ | ||
42 | __u32 fp : 1; /* 27 floating point register validity */ | ||
43 | __u32 gr : 1; /* 28 general register validity */ | ||
44 | __u32 cr : 1; /* 29 control register validity */ | ||
45 | __u32 to_be_defined_6 : 1; /* 30 */ | ||
46 | __u32 st : 1; /* 31 storage logical validity */ | ||
31 | __u32 ie : 1; /* 32 indirect storage error */ | 47 | __u32 ie : 1; /* 32 indirect storage error */ |
32 | __u32 to_be_defined_5 : 31; /* 33-63 */ | 48 | __u32 ar : 1; /* 33 access register validity */ |
49 | __u32 da : 1; /* 34 delayed access exception */ | ||
50 | __u32 to_be_defined_7 : 7; /* 35-41 */ | ||
51 | __u32 pr : 1; /* 42 tod programmable register validity */ | ||
52 | __u32 fc : 1; /* 43 fp control register validity */ | ||
53 | __u32 ap : 1; /* 44 ancillary report */ | ||
54 | __u32 to_be_defined_8 : 1; /* 45 */ | ||
55 | __u32 ct : 1; /* 46 cpu timer validity */ | ||
56 | __u32 cc : 1; /* 47 clock comparator validity */ | ||
57 | __u32 to_be_defined_9 : 16; /* 47-63 */ | ||
33 | }; | 58 | }; |
34 | 59 | ||
35 | /* | 60 | /* |
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index a699c30b2662..bbe346bd3cb8 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c | |||
@@ -34,7 +34,6 @@ | |||
34 | 34 | ||
35 | #define ADDR32 (0) | 35 | #define ADDR32 (0) |
36 | 36 | ||
37 | #include <linux/version.h> | ||
38 | #include <linux/module.h> | 37 | #include <linux/module.h> |
39 | 38 | ||
40 | MODULE_AUTHOR("Deanna Bonds, with _lots_ of help from Mark Salyzyn"); | 39 | MODULE_AUTHOR("Deanna Bonds, with _lots_ of help from Mark Salyzyn"); |
@@ -1811,9 +1810,9 @@ static int adpt_system_info(void __user *buffer) | |||
1811 | memset(&si, 0, sizeof(si)); | 1810 | memset(&si, 0, sizeof(si)); |
1812 | 1811 | ||
1813 | si.osType = OS_LINUX; | 1812 | si.osType = OS_LINUX; |
1814 | si.osMajorVersion = (u8) (LINUX_VERSION_CODE >> 16); | 1813 | si.osMajorVersion = 0; |
1815 | si.osMinorVersion = (u8) (LINUX_VERSION_CODE >> 8 & 0x0ff); | 1814 | si.osMinorVersion = 0; |
1816 | si.osRevision = (u8) (LINUX_VERSION_CODE & 0x0ff); | 1815 | si.osRevision = 0; |
1817 | si.busType = SI_PCI_BUS; | 1816 | si.busType = SI_PCI_BUS; |
1818 | si.processorFamily = DPTI_sig.dsProcessorFamily; | 1817 | si.processorFamily = DPTI_sig.dsProcessorFamily; |
1819 | 1818 | ||
diff --git a/drivers/scsi/dpti.h b/drivers/scsi/dpti.h index 9821783c0164..489194af43d0 100644 --- a/drivers/scsi/dpti.h +++ b/drivers/scsi/dpti.h | |||
@@ -20,15 +20,7 @@ | |||
20 | #ifndef _DPT_H | 20 | #ifndef _DPT_H |
21 | #define _DPT_H | 21 | #define _DPT_H |
22 | 22 | ||
23 | #ifndef LINUX_VERSION_CODE | ||
24 | #include <linux/version.h> | ||
25 | #endif | ||
26 | |||
27 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,00) | ||
28 | #define MAX_TO_IOP_MESSAGES (210) | ||
29 | #else | ||
30 | #define MAX_TO_IOP_MESSAGES (255) | 23 | #define MAX_TO_IOP_MESSAGES (255) |
31 | #endif | ||
32 | #define MAX_FROM_IOP_MESSAGES (255) | 24 | #define MAX_FROM_IOP_MESSAGES (255) |
33 | 25 | ||
34 | 26 | ||
@@ -321,10 +313,6 @@ static int adpt_close(struct inode *inode, struct file *file); | |||
321 | static void adpt_delay(int millisec); | 313 | static void adpt_delay(int millisec); |
322 | #endif | 314 | #endif |
323 | 315 | ||
324 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) | ||
325 | static struct pci_dev* adpt_pci_find_device(uint vendor, struct pci_dev* from); | ||
326 | #endif | ||
327 | |||
328 | #if defined __ia64__ | 316 | #if defined __ia64__ |
329 | static void adpt_ia64_info(sysInfo_S* si); | 317 | static void adpt_ia64_info(sysInfo_S* si); |
330 | #endif | 318 | #endif |
diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c index f7ddc9f1ba41..2094d4811d61 100644 --- a/drivers/scsi/initio.c +++ b/drivers/scsi/initio.c | |||
@@ -223,7 +223,7 @@ static void tul_select_atn(HCS * pCurHcb, SCB * pCurScb); | |||
223 | static void tul_select_atn3(HCS * pCurHcb, SCB * pCurScb); | 223 | static void tul_select_atn3(HCS * pCurHcb, SCB * pCurScb); |
224 | static void tul_select_atn_stop(HCS * pCurHcb, SCB * pCurScb); | 224 | static void tul_select_atn_stop(HCS * pCurHcb, SCB * pCurScb); |
225 | static int int_tul_busfree(HCS * pCurHcb); | 225 | static int int_tul_busfree(HCS * pCurHcb); |
226 | int int_tul_scsi_rst(HCS * pCurHcb); | 226 | static int int_tul_scsi_rst(HCS * pCurHcb); |
227 | static int int_tul_bad_seq(HCS * pCurHcb); | 227 | static int int_tul_bad_seq(HCS * pCurHcb); |
228 | static int int_tul_resel(HCS * pCurHcb); | 228 | static int int_tul_resel(HCS * pCurHcb); |
229 | static int tul_sync_done(HCS * pCurHcb); | 229 | static int tul_sync_done(HCS * pCurHcb); |
@@ -240,9 +240,8 @@ static int tul_se2_rd_all(WORD CurBase); | |||
240 | static void tul_se2_update_all(WORD CurBase); /* setup default pattern */ | 240 | static void tul_se2_update_all(WORD CurBase); /* setup default pattern */ |
241 | static void tul_read_eeprom(WORD CurBase); | 241 | static void tul_read_eeprom(WORD CurBase); |
242 | 242 | ||
243 | /* ---- EXTERNAL VARIABLES ---- */ | ||
244 | HCS tul_hcs[MAX_SUPPORTED_ADAPTERS]; | ||
245 | /* ---- INTERNAL VARIABLES ---- */ | 243 | /* ---- INTERNAL VARIABLES ---- */ |
244 | static HCS tul_hcs[MAX_SUPPORTED_ADAPTERS]; | ||
246 | static INI_ADPT_STRUCT i91u_adpt[MAX_SUPPORTED_ADAPTERS]; | 245 | static INI_ADPT_STRUCT i91u_adpt[MAX_SUPPORTED_ADAPTERS]; |
247 | 246 | ||
248 | /*NVRAM nvram, *nvramp = &nvram; */ | 247 | /*NVRAM nvram, *nvramp = &nvram; */ |
@@ -381,7 +380,7 @@ void tul_se2_wait(void) | |||
381 | 380 | ||
382 | 381 | ||
383 | ******************************************************************/ | 382 | ******************************************************************/ |
384 | void tul_se2_instr(WORD CurBase, UCHAR instr) | 383 | static void tul_se2_instr(WORD CurBase, UCHAR instr) |
385 | { | 384 | { |
386 | int i; | 385 | int i; |
387 | UCHAR b; | 386 | UCHAR b; |
@@ -437,7 +436,7 @@ void tul_se2_ew_ds(WORD CurBase) | |||
437 | Input :address of Serial E2PROM | 436 | Input :address of Serial E2PROM |
438 | Output :value stored in Serial E2PROM | 437 | Output :value stored in Serial E2PROM |
439 | *******************************************************************/ | 438 | *******************************************************************/ |
440 | USHORT tul_se2_rd(WORD CurBase, ULONG adr) | 439 | static USHORT tul_se2_rd(WORD CurBase, ULONG adr) |
441 | { | 440 | { |
442 | UCHAR instr, readByte; | 441 | UCHAR instr, readByte; |
443 | USHORT readWord; | 442 | USHORT readWord; |
@@ -468,7 +467,7 @@ USHORT tul_se2_rd(WORD CurBase, ULONG adr) | |||
468 | /****************************************************************** | 467 | /****************************************************************** |
469 | Input: new value in Serial E2PROM, address of Serial E2PROM | 468 | Input: new value in Serial E2PROM, address of Serial E2PROM |
470 | *******************************************************************/ | 469 | *******************************************************************/ |
471 | void tul_se2_wr(WORD CurBase, UCHAR adr, USHORT writeWord) | 470 | static void tul_se2_wr(WORD CurBase, UCHAR adr, USHORT writeWord) |
472 | { | 471 | { |
473 | UCHAR readByte; | 472 | UCHAR readByte; |
474 | UCHAR instr; | 473 | UCHAR instr; |
@@ -584,8 +583,8 @@ void tul_read_eeprom(WORD CurBase) | |||
584 | TUL_WR(CurBase + TUL_GCTRL, gctrl & ~TUL_GCTRL_EEPROM_BIT); | 583 | TUL_WR(CurBase + TUL_GCTRL, gctrl & ~TUL_GCTRL_EEPROM_BIT); |
585 | } /* read_eeprom */ | 584 | } /* read_eeprom */ |
586 | 585 | ||
587 | int Addi91u_into_Adapter_table(WORD wBIOS, WORD wBASE, BYTE bInterrupt, | 586 | static int Addi91u_into_Adapter_table(WORD wBIOS, WORD wBASE, BYTE bInterrupt, |
588 | BYTE bBus, BYTE bDevice) | 587 | BYTE bBus, BYTE bDevice) |
589 | { | 588 | { |
590 | int i, j; | 589 | int i, j; |
591 | 590 | ||
@@ -616,7 +615,7 @@ int Addi91u_into_Adapter_table(WORD wBIOS, WORD wBASE, BYTE bInterrupt, | |||
616 | return 1; | 615 | return 1; |
617 | } | 616 | } |
618 | 617 | ||
619 | void init_i91uAdapter_table(void) | 618 | static void init_i91uAdapter_table(void) |
620 | { | 619 | { |
621 | int i; | 620 | int i; |
622 | 621 | ||
@@ -630,7 +629,7 @@ void init_i91uAdapter_table(void) | |||
630 | return; | 629 | return; |
631 | } | 630 | } |
632 | 631 | ||
633 | void tul_stop_bm(HCS * pCurHcb) | 632 | static void tul_stop_bm(HCS * pCurHcb) |
634 | { | 633 | { |
635 | 634 | ||
636 | if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND) { /* if DMA xfer is pending, abort DMA xfer */ | 635 | if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND) { /* if DMA xfer is pending, abort DMA xfer */ |
@@ -642,7 +641,7 @@ void tul_stop_bm(HCS * pCurHcb) | |||
642 | } | 641 | } |
643 | 642 | ||
644 | /***************************************************************************/ | 643 | /***************************************************************************/ |
645 | void get_tulipPCIConfig(HCS * pCurHcb, int ch_idx) | 644 | static void get_tulipPCIConfig(HCS * pCurHcb, int ch_idx) |
646 | { | 645 | { |
647 | pCurHcb->HCS_Base = i91u_adpt[ch_idx].ADPT_BASE; /* Supply base address */ | 646 | pCurHcb->HCS_Base = i91u_adpt[ch_idx].ADPT_BASE; /* Supply base address */ |
648 | pCurHcb->HCS_BIOS = i91u_adpt[ch_idx].ADPT_BIOS; /* Supply BIOS address */ | 647 | pCurHcb->HCS_BIOS = i91u_adpt[ch_idx].ADPT_BIOS; /* Supply BIOS address */ |
@@ -651,7 +650,7 @@ void get_tulipPCIConfig(HCS * pCurHcb, int ch_idx) | |||
651 | } | 650 | } |
652 | 651 | ||
653 | /***************************************************************************/ | 652 | /***************************************************************************/ |
654 | int tul_reset_scsi(HCS * pCurHcb, int seconds) | 653 | static int tul_reset_scsi(HCS * pCurHcb, int seconds) |
655 | { | 654 | { |
656 | TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_RST_BUS); | 655 | TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_RST_BUS); |
657 | 656 | ||
@@ -670,7 +669,8 @@ int tul_reset_scsi(HCS * pCurHcb, int seconds) | |||
670 | } | 669 | } |
671 | 670 | ||
672 | /***************************************************************************/ | 671 | /***************************************************************************/ |
673 | int init_tulip(HCS * pCurHcb, SCB * scbp, int tul_num_scb, BYTE * pbBiosAdr, int seconds) | 672 | static int init_tulip(HCS * pCurHcb, SCB * scbp, int tul_num_scb, |
673 | BYTE * pbBiosAdr, int seconds) | ||
674 | { | 674 | { |
675 | int i; | 675 | int i; |
676 | BYTE *pwFlags; | 676 | BYTE *pwFlags; |
@@ -788,7 +788,7 @@ int init_tulip(HCS * pCurHcb, SCB * scbp, int tul_num_scb, BYTE * pbBiosAdr, int | |||
788 | } | 788 | } |
789 | 789 | ||
790 | /***************************************************************************/ | 790 | /***************************************************************************/ |
791 | SCB *tul_alloc_scb(HCS * hcsp) | 791 | static SCB *tul_alloc_scb(HCS * hcsp) |
792 | { | 792 | { |
793 | SCB *pTmpScb; | 793 | SCB *pTmpScb; |
794 | ULONG flags; | 794 | ULONG flags; |
@@ -807,7 +807,7 @@ SCB *tul_alloc_scb(HCS * hcsp) | |||
807 | } | 807 | } |
808 | 808 | ||
809 | /***************************************************************************/ | 809 | /***************************************************************************/ |
810 | void tul_release_scb(HCS * hcsp, SCB * scbp) | 810 | static void tul_release_scb(HCS * hcsp, SCB * scbp) |
811 | { | 811 | { |
812 | ULONG flags; | 812 | ULONG flags; |
813 | 813 | ||
@@ -829,7 +829,7 @@ void tul_release_scb(HCS * hcsp, SCB * scbp) | |||
829 | } | 829 | } |
830 | 830 | ||
831 | /***************************************************************************/ | 831 | /***************************************************************************/ |
832 | void tul_append_pend_scb(HCS * pCurHcb, SCB * scbp) | 832 | static void tul_append_pend_scb(HCS * pCurHcb, SCB * scbp) |
833 | { | 833 | { |
834 | 834 | ||
835 | #if DEBUG_QUEUE | 835 | #if DEBUG_QUEUE |
@@ -847,7 +847,7 @@ void tul_append_pend_scb(HCS * pCurHcb, SCB * scbp) | |||
847 | } | 847 | } |
848 | 848 | ||
849 | /***************************************************************************/ | 849 | /***************************************************************************/ |
850 | void tul_push_pend_scb(HCS * pCurHcb, SCB * scbp) | 850 | static void tul_push_pend_scb(HCS * pCurHcb, SCB * scbp) |
851 | { | 851 | { |
852 | 852 | ||
853 | #if DEBUG_QUEUE | 853 | #if DEBUG_QUEUE |
@@ -863,7 +863,7 @@ void tul_push_pend_scb(HCS * pCurHcb, SCB * scbp) | |||
863 | } | 863 | } |
864 | 864 | ||
865 | /***************************************************************************/ | 865 | /***************************************************************************/ |
866 | SCB *tul_find_first_pend_scb(HCS * pCurHcb) | 866 | static SCB *tul_find_first_pend_scb(HCS * pCurHcb) |
867 | { | 867 | { |
868 | SCB *pFirstPend; | 868 | SCB *pFirstPend; |
869 | 869 | ||
@@ -894,24 +894,7 @@ SCB *tul_find_first_pend_scb(HCS * pCurHcb) | |||
894 | return (pFirstPend); | 894 | return (pFirstPend); |
895 | } | 895 | } |
896 | /***************************************************************************/ | 896 | /***************************************************************************/ |
897 | SCB *tul_pop_pend_scb(HCS * pCurHcb) | 897 | static void tul_unlink_pend_scb(HCS * pCurHcb, SCB * pCurScb) |
898 | { | ||
899 | SCB *pTmpScb; | ||
900 | |||
901 | if ((pTmpScb = pCurHcb->HCS_FirstPend) != NULL) { | ||
902 | if ((pCurHcb->HCS_FirstPend = pTmpScb->SCB_NxtScb) == NULL) | ||
903 | pCurHcb->HCS_LastPend = NULL; | ||
904 | pTmpScb->SCB_NxtScb = NULL; | ||
905 | } | ||
906 | #if DEBUG_QUEUE | ||
907 | printk("Pop pend SCB %lx; ", (ULONG) pTmpScb); | ||
908 | #endif | ||
909 | return (pTmpScb); | ||
910 | } | ||
911 | |||
912 | |||
913 | /***************************************************************************/ | ||
914 | void tul_unlink_pend_scb(HCS * pCurHcb, SCB * pCurScb) | ||
915 | { | 898 | { |
916 | SCB *pTmpScb, *pPrevScb; | 899 | SCB *pTmpScb, *pPrevScb; |
917 | 900 | ||
@@ -939,7 +922,7 @@ void tul_unlink_pend_scb(HCS * pCurHcb, SCB * pCurScb) | |||
939 | return; | 922 | return; |
940 | } | 923 | } |
941 | /***************************************************************************/ | 924 | /***************************************************************************/ |
942 | void tul_append_busy_scb(HCS * pCurHcb, SCB * scbp) | 925 | static void tul_append_busy_scb(HCS * pCurHcb, SCB * scbp) |
943 | { | 926 | { |
944 | 927 | ||
945 | #if DEBUG_QUEUE | 928 | #if DEBUG_QUEUE |
@@ -961,7 +944,7 @@ void tul_append_busy_scb(HCS * pCurHcb, SCB * scbp) | |||
961 | } | 944 | } |
962 | 945 | ||
963 | /***************************************************************************/ | 946 | /***************************************************************************/ |
964 | SCB *tul_pop_busy_scb(HCS * pCurHcb) | 947 | static SCB *tul_pop_busy_scb(HCS * pCurHcb) |
965 | { | 948 | { |
966 | SCB *pTmpScb; | 949 | SCB *pTmpScb; |
967 | 950 | ||
@@ -982,7 +965,7 @@ SCB *tul_pop_busy_scb(HCS * pCurHcb) | |||
982 | } | 965 | } |
983 | 966 | ||
984 | /***************************************************************************/ | 967 | /***************************************************************************/ |
985 | void tul_unlink_busy_scb(HCS * pCurHcb, SCB * pCurScb) | 968 | static void tul_unlink_busy_scb(HCS * pCurHcb, SCB * pCurScb) |
986 | { | 969 | { |
987 | SCB *pTmpScb, *pPrevScb; | 970 | SCB *pTmpScb, *pPrevScb; |
988 | 971 | ||
@@ -1037,7 +1020,7 @@ SCB *tul_find_busy_scb(HCS * pCurHcb, WORD tarlun) | |||
1037 | } | 1020 | } |
1038 | 1021 | ||
1039 | /***************************************************************************/ | 1022 | /***************************************************************************/ |
1040 | void tul_append_done_scb(HCS * pCurHcb, SCB * scbp) | 1023 | static void tul_append_done_scb(HCS * pCurHcb, SCB * scbp) |
1041 | { | 1024 | { |
1042 | 1025 | ||
1043 | #if DEBUG_QUEUE | 1026 | #if DEBUG_QUEUE |
@@ -1073,7 +1056,7 @@ SCB *tul_find_done_scb(HCS * pCurHcb) | |||
1073 | } | 1056 | } |
1074 | 1057 | ||
1075 | /***************************************************************************/ | 1058 | /***************************************************************************/ |
1076 | int tul_abort_srb(HCS * pCurHcb, struct scsi_cmnd *srbp) | 1059 | static int tul_abort_srb(HCS * pCurHcb, struct scsi_cmnd *srbp) |
1077 | { | 1060 | { |
1078 | ULONG flags; | 1061 | ULONG flags; |
1079 | SCB *pTmpScb, *pPrevScb; | 1062 | SCB *pTmpScb, *pPrevScb; |
@@ -1163,7 +1146,7 @@ int tul_abort_srb(HCS * pCurHcb, struct scsi_cmnd *srbp) | |||
1163 | } | 1146 | } |
1164 | 1147 | ||
1165 | /***************************************************************************/ | 1148 | /***************************************************************************/ |
1166 | int tul_bad_seq(HCS * pCurHcb) | 1149 | static int tul_bad_seq(HCS * pCurHcb) |
1167 | { | 1150 | { |
1168 | SCB *pCurScb; | 1151 | SCB *pCurScb; |
1169 | 1152 | ||
@@ -1182,9 +1165,11 @@ int tul_bad_seq(HCS * pCurHcb) | |||
1182 | return (tul_post_scsi_rst(pCurHcb)); | 1165 | return (tul_post_scsi_rst(pCurHcb)); |
1183 | } | 1166 | } |
1184 | 1167 | ||
1168 | #if 0 | ||
1169 | |||
1185 | /************************************************************************/ | 1170 | /************************************************************************/ |
1186 | int tul_device_reset(HCS * pCurHcb, struct scsi_cmnd *pSrb, | 1171 | static int tul_device_reset(HCS * pCurHcb, struct scsi_cmnd *pSrb, |
1187 | unsigned int target, unsigned int ResetFlags) | 1172 | unsigned int target, unsigned int ResetFlags) |
1188 | { | 1173 | { |
1189 | ULONG flags; | 1174 | ULONG flags; |
1190 | SCB *pScb; | 1175 | SCB *pScb; |
@@ -1255,7 +1240,7 @@ int tul_device_reset(HCS * pCurHcb, struct scsi_cmnd *pSrb, | |||
1255 | return SCSI_RESET_PENDING; | 1240 | return SCSI_RESET_PENDING; |
1256 | } | 1241 | } |
1257 | 1242 | ||
1258 | int tul_reset_scsi_bus(HCS * pCurHcb) | 1243 | static int tul_reset_scsi_bus(HCS * pCurHcb) |
1259 | { | 1244 | { |
1260 | ULONG flags; | 1245 | ULONG flags; |
1261 | 1246 | ||
@@ -1284,8 +1269,10 @@ int tul_reset_scsi_bus(HCS * pCurHcb) | |||
1284 | return (SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET); | 1269 | return (SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET); |
1285 | } | 1270 | } |
1286 | 1271 | ||
1272 | #endif /* 0 */ | ||
1273 | |||
1287 | /************************************************************************/ | 1274 | /************************************************************************/ |
1288 | void tul_exec_scb(HCS * pCurHcb, SCB * pCurScb) | 1275 | static void tul_exec_scb(HCS * pCurHcb, SCB * pCurScb) |
1289 | { | 1276 | { |
1290 | ULONG flags; | 1277 | ULONG flags; |
1291 | 1278 | ||
@@ -1318,7 +1305,7 @@ void tul_exec_scb(HCS * pCurHcb, SCB * pCurScb) | |||
1318 | } | 1305 | } |
1319 | 1306 | ||
1320 | /***************************************************************************/ | 1307 | /***************************************************************************/ |
1321 | int tul_isr(HCS * pCurHcb) | 1308 | static int tul_isr(HCS * pCurHcb) |
1322 | { | 1309 | { |
1323 | /* Enter critical section */ | 1310 | /* Enter critical section */ |
1324 | 1311 | ||
@@ -2108,7 +2095,7 @@ int int_tul_busfree(HCS * pCurHcb) | |||
2108 | 2095 | ||
2109 | /***************************************************************************/ | 2096 | /***************************************************************************/ |
2110 | /* scsi bus reset */ | 2097 | /* scsi bus reset */ |
2111 | int int_tul_scsi_rst(HCS * pCurHcb) | 2098 | static int int_tul_scsi_rst(HCS * pCurHcb) |
2112 | { | 2099 | { |
2113 | SCB *pCurScb; | 2100 | SCB *pCurScb; |
2114 | int i; | 2101 | int i; |
@@ -2214,7 +2201,7 @@ int int_tul_resel(HCS * pCurHcb) | |||
2214 | 2201 | ||
2215 | 2202 | ||
2216 | /***************************************************************************/ | 2203 | /***************************************************************************/ |
2217 | int int_tul_bad_seq(HCS * pCurHcb) | 2204 | static int int_tul_bad_seq(HCS * pCurHcb) |
2218 | { /* target wrong phase */ | 2205 | { /* target wrong phase */ |
2219 | SCB *pCurScb; | 2206 | SCB *pCurScb; |
2220 | int i; | 2207 | int i; |
diff --git a/drivers/scsi/initio.h b/drivers/scsi/initio.h index df3ed7c1cee3..3efb1184fc39 100644 --- a/drivers/scsi/initio.h +++ b/drivers/scsi/initio.h | |||
@@ -719,21 +719,3 @@ typedef struct _HCSinfo { | |||
719 | #define SCSI_RESET_HOST_RESET 0x200 | 719 | #define SCSI_RESET_HOST_RESET 0x200 |
720 | #define SCSI_RESET_ACTION 0xff | 720 | #define SCSI_RESET_ACTION 0xff |
721 | 721 | ||
722 | extern void init_i91uAdapter_table(void); | ||
723 | extern int Addi91u_into_Adapter_table(WORD, WORD, BYTE, BYTE, BYTE); | ||
724 | extern int tul_ReturnNumberOfAdapters(void); | ||
725 | extern void get_tulipPCIConfig(HCS * pHCB, int iChannel_index); | ||
726 | extern int init_tulip(HCS * pHCB, SCB * pSCB, int tul_num_scb, BYTE * pbBiosAdr, int reset_time); | ||
727 | extern SCB *tul_alloc_scb(HCS * pHCB); | ||
728 | extern int tul_abort_srb(HCS * pHCB, struct scsi_cmnd * pSRB); | ||
729 | extern void tul_exec_scb(HCS * pHCB, SCB * pSCB); | ||
730 | extern void tul_release_scb(HCS * pHCB, SCB * pSCB); | ||
731 | extern void tul_stop_bm(HCS * pHCB); | ||
732 | extern int tul_reset_scsi(HCS * pCurHcb, int seconds); | ||
733 | extern int tul_isr(HCS * pHCB); | ||
734 | extern int tul_reset(HCS * pHCB, struct scsi_cmnd * pSRB, unsigned char target); | ||
735 | extern int tul_reset_scsi_bus(HCS * pCurHcb); | ||
736 | extern int tul_device_reset(HCS * pCurHcb, struct scsi_cmnd *pSrb, | ||
737 | unsigned int target, unsigned int ResetFlags); | ||
738 | /* ---- EXTERNAL VARIABLES ---- */ | ||
739 | extern HCS tul_hcs[]; | ||
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index db92a0ceda79..feb8e73fc1c9 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c | |||
@@ -992,18 +992,17 @@ static int get_lsr_info(struct m68k_serial * info, unsigned int *value) | |||
992 | /* | 992 | /* |
993 | * This routine sends a break character out the serial port. | 993 | * This routine sends a break character out the serial port. |
994 | */ | 994 | */ |
995 | static void send_break( struct m68k_serial * info, int duration) | 995 | static void send_break(struct m68k_serial * info, unsigned int duration) |
996 | { | 996 | { |
997 | m68328_uart *uart = &uart_addr[info->line]; | 997 | m68328_uart *uart = &uart_addr[info->line]; |
998 | unsigned long flags; | 998 | unsigned long flags; |
999 | if (!info->port) | 999 | if (!info->port) |
1000 | return; | 1000 | return; |
1001 | set_current_state(TASK_INTERRUPTIBLE); | ||
1002 | save_flags(flags); | 1001 | save_flags(flags); |
1003 | cli(); | 1002 | cli(); |
1004 | #ifdef USE_INTS | 1003 | #ifdef USE_INTS |
1005 | uart->utx.w |= UTX_SEND_BREAK; | 1004 | uart->utx.w |= UTX_SEND_BREAK; |
1006 | schedule_timeout(duration); | 1005 | msleep_interruptible(duration); |
1007 | uart->utx.w &= ~UTX_SEND_BREAK; | 1006 | uart->utx.w &= ~UTX_SEND_BREAK; |
1008 | #endif | 1007 | #endif |
1009 | restore_flags(flags); | 1008 | restore_flags(flags); |
@@ -1033,14 +1032,14 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, | |||
1033 | return retval; | 1032 | return retval; |
1034 | tty_wait_until_sent(tty, 0); | 1033 | tty_wait_until_sent(tty, 0); |
1035 | if (!arg) | 1034 | if (!arg) |
1036 | send_break(info, HZ/4); /* 1/4 second */ | 1035 | send_break(info, 250); /* 1/4 second */ |
1037 | return 0; | 1036 | return 0; |
1038 | case TCSBRKP: /* support for POSIX tcsendbreak() */ | 1037 | case TCSBRKP: /* support for POSIX tcsendbreak() */ |
1039 | retval = tty_check_change(tty); | 1038 | retval = tty_check_change(tty); |
1040 | if (retval) | 1039 | if (retval) |
1041 | return retval; | 1040 | return retval; |
1042 | tty_wait_until_sent(tty, 0); | 1041 | tty_wait_until_sent(tty, 0); |
1043 | send_break(info, arg ? arg*(HZ/10) : HZ/4); | 1042 | send_break(info, arg ? arg*(100) : 250); |
1044 | return 0; | 1043 | return 0; |
1045 | case TIOCGSOFTCAR: | 1044 | case TIOCGSOFTCAR: |
1046 | error = put_user(C_CLOCAL(tty) ? 1 : 0, | 1045 | error = put_user(C_CLOCAL(tty) ? 1 : 0, |
diff --git a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c index f148022b6b4e..b116122e569a 100644 --- a/drivers/serial/68360serial.c +++ b/drivers/serial/68360serial.c | |||
@@ -1394,14 +1394,13 @@ static void end_break(ser_info_t *info) | |||
1394 | /* | 1394 | /* |
1395 | * This routine sends a break character out the serial port. | 1395 | * This routine sends a break character out the serial port. |
1396 | */ | 1396 | */ |
1397 | static void send_break(ser_info_t *info, int duration) | 1397 | static void send_break(ser_info_t *info, unsigned int duration) |
1398 | { | 1398 | { |
1399 | set_current_state(TASK_INTERRUPTIBLE); | ||
1400 | #ifdef SERIAL_DEBUG_SEND_BREAK | 1399 | #ifdef SERIAL_DEBUG_SEND_BREAK |
1401 | printk("rs_send_break(%d) jiff=%lu...", duration, jiffies); | 1400 | printk("rs_send_break(%d) jiff=%lu...", duration, jiffies); |
1402 | #endif | 1401 | #endif |
1403 | begin_break(info); | 1402 | begin_break(info); |
1404 | schedule_timeout(duration); | 1403 | msleep_interruptible(duration); |
1405 | end_break(info); | 1404 | end_break(info); |
1406 | #ifdef SERIAL_DEBUG_SEND_BREAK | 1405 | #ifdef SERIAL_DEBUG_SEND_BREAK |
1407 | printk("done jiffies=%lu\n", jiffies); | 1406 | printk("done jiffies=%lu\n", jiffies); |
@@ -1436,7 +1435,7 @@ static int rs_360_ioctl(struct tty_struct *tty, struct file * file, | |||
1436 | if (signal_pending(current)) | 1435 | if (signal_pending(current)) |
1437 | return -EINTR; | 1436 | return -EINTR; |
1438 | if (!arg) { | 1437 | if (!arg) { |
1439 | send_break(info, HZ/4); /* 1/4 second */ | 1438 | send_break(info, 250); /* 1/4 second */ |
1440 | if (signal_pending(current)) | 1439 | if (signal_pending(current)) |
1441 | return -EINTR; | 1440 | return -EINTR; |
1442 | } | 1441 | } |
@@ -1448,7 +1447,7 @@ static int rs_360_ioctl(struct tty_struct *tty, struct file * file, | |||
1448 | tty_wait_until_sent(tty, 0); | 1447 | tty_wait_until_sent(tty, 0); |
1449 | if (signal_pending(current)) | 1448 | if (signal_pending(current)) |
1450 | return -EINTR; | 1449 | return -EINTR; |
1451 | send_break(info, arg ? arg*(HZ/10) : HZ/4); | 1450 | send_break(info, arg ? arg*100 : 250); |
1452 | if (signal_pending(current)) | 1451 | if (signal_pending(current)) |
1453 | return -EINTR; | 1452 | return -EINTR; |
1454 | return 0; | 1453 | return 0; |
diff --git a/drivers/serial/icom.h b/drivers/serial/icom.h index 23dc0f7ddf8b..798f1ef23712 100644 --- a/drivers/serial/icom.h +++ b/drivers/serial/icom.h | |||
@@ -286,5 +286,3 @@ struct lookup_int_table { | |||
286 | u32 __iomem *global_int_mask; | 286 | u32 __iomem *global_int_mask; |
287 | unsigned long processor_id; | 287 | unsigned long processor_id; |
288 | }; | 288 | }; |
289 | |||
290 | #define MSECS_TO_JIFFIES(ms) (((ms)*HZ+999)/1000) | ||
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c index a8314aee2ab8..a2a643318002 100644 --- a/drivers/serial/mpsc.c +++ b/drivers/serial/mpsc.c | |||
@@ -67,7 +67,11 @@ | |||
67 | 67 | ||
68 | static struct mpsc_port_info mpsc_ports[MPSC_NUM_CTLRS]; | 68 | static struct mpsc_port_info mpsc_ports[MPSC_NUM_CTLRS]; |
69 | static struct mpsc_shared_regs mpsc_shared_regs; | 69 | static struct mpsc_shared_regs mpsc_shared_regs; |
70 | static struct uart_driver mpsc_reg; | ||
70 | 71 | ||
72 | static void mpsc_start_rx(struct mpsc_port_info *pi); | ||
73 | static void mpsc_free_ring_mem(struct mpsc_port_info *pi); | ||
74 | static void mpsc_release_port(struct uart_port *port); | ||
71 | /* | 75 | /* |
72 | ****************************************************************************** | 76 | ****************************************************************************** |
73 | * | 77 | * |
@@ -546,7 +550,6 @@ static int | |||
546 | mpsc_alloc_ring_mem(struct mpsc_port_info *pi) | 550 | mpsc_alloc_ring_mem(struct mpsc_port_info *pi) |
547 | { | 551 | { |
548 | int rc = 0; | 552 | int rc = 0; |
549 | static void mpsc_free_ring_mem(struct mpsc_port_info *pi); | ||
550 | 553 | ||
551 | pr_debug("mpsc_alloc_ring_mem[%d]: Allocating ring mem\n", | 554 | pr_debug("mpsc_alloc_ring_mem[%d]: Allocating ring mem\n", |
552 | pi->port.line); | 555 | pi->port.line); |
@@ -745,7 +748,6 @@ mpsc_rx_intr(struct mpsc_port_info *pi, struct pt_regs *regs) | |||
745 | int rc = 0; | 748 | int rc = 0; |
746 | u8 *bp; | 749 | u8 *bp; |
747 | char flag = TTY_NORMAL; | 750 | char flag = TTY_NORMAL; |
748 | static void mpsc_start_rx(struct mpsc_port_info *pi); | ||
749 | 751 | ||
750 | pr_debug("mpsc_rx_intr[%d]: Handling Rx intr\n", pi->port.line); | 752 | pr_debug("mpsc_rx_intr[%d]: Handling Rx intr\n", pi->port.line); |
751 | 753 | ||
@@ -1178,7 +1180,6 @@ static void | |||
1178 | mpsc_shutdown(struct uart_port *port) | 1180 | mpsc_shutdown(struct uart_port *port) |
1179 | { | 1181 | { |
1180 | struct mpsc_port_info *pi = (struct mpsc_port_info *)port; | 1182 | struct mpsc_port_info *pi = (struct mpsc_port_info *)port; |
1181 | static void mpsc_release_port(struct uart_port *port); | ||
1182 | 1183 | ||
1183 | pr_debug("mpsc_shutdown[%d]: Shutting down MPSC\n", port->line); | 1184 | pr_debug("mpsc_shutdown[%d]: Shutting down MPSC\n", port->line); |
1184 | 1185 | ||
@@ -1448,7 +1449,6 @@ mpsc_console_setup(struct console *co, char *options) | |||
1448 | return uart_set_options(&pi->port, co, baud, parity, bits, flow); | 1449 | return uart_set_options(&pi->port, co, baud, parity, bits, flow); |
1449 | } | 1450 | } |
1450 | 1451 | ||
1451 | extern struct uart_driver mpsc_reg; | ||
1452 | static struct console mpsc_console = { | 1452 | static struct console mpsc_console = { |
1453 | .name = MPSC_DEV_NAME, | 1453 | .name = MPSC_DEV_NAME, |
1454 | .write = mpsc_console_write, | 1454 | .write = mpsc_console_write, |
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 5c4231ae295b..8e65206d3d76 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c | |||
@@ -1071,7 +1071,7 @@ static void __init sunzilog_alloc_tables(void) | |||
1071 | */ | 1071 | */ |
1072 | static struct zilog_layout __iomem * __init get_zs_sun4u(int chip, int zsnode) | 1072 | static struct zilog_layout __iomem * __init get_zs_sun4u(int chip, int zsnode) |
1073 | { | 1073 | { |
1074 | unsigned long mapped_addr; | 1074 | void __iomem *mapped_addr; |
1075 | unsigned int sun4u_ino; | 1075 | unsigned int sun4u_ino; |
1076 | struct sbus_bus *sbus = NULL; | 1076 | struct sbus_bus *sbus = NULL; |
1077 | struct sbus_dev *sdev = NULL; | 1077 | struct sbus_dev *sdev = NULL; |
@@ -1111,9 +1111,9 @@ static struct zilog_layout __iomem * __init get_zs_sun4u(int chip, int zsnode) | |||
1111 | apply_fhc_ranges(central_bus->child, | 1111 | apply_fhc_ranges(central_bus->child, |
1112 | &zsregs[0], 1); | 1112 | &zsregs[0], 1); |
1113 | apply_central_ranges(central_bus, &zsregs[0], 1); | 1113 | apply_central_ranges(central_bus, &zsregs[0], 1); |
1114 | mapped_addr = | 1114 | mapped_addr = (void __iomem *) |
1115 | (((u64)zsregs[0].which_io)<<32UL) | | 1115 | ((((u64)zsregs[0].which_io)<<32UL) | |
1116 | ((u64)zsregs[0].phys_addr); | 1116 | ((u64)zsregs[0].phys_addr)); |
1117 | } | 1117 | } |
1118 | 1118 | ||
1119 | if (zilog_irq == -1) { | 1119 | if (zilog_irq == -1) { |
diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c index d5863b8b56ee..f2c9fa423d40 100644 --- a/drivers/telephony/ixj.c +++ b/drivers/telephony/ixj.c | |||
@@ -329,10 +329,8 @@ static IXJ *ixj_alloc() | |||
329 | 329 | ||
330 | static void ixj_fsk_free(IXJ *j) | 330 | static void ixj_fsk_free(IXJ *j) |
331 | { | 331 | { |
332 | if(j->fskdata != NULL) { | 332 | kfree(j->fskdata); |
333 | kfree(j->fskdata); | 333 | j->fskdata = NULL; |
334 | j->fskdata = NULL; | ||
335 | } | ||
336 | } | 334 | } |
337 | 335 | ||
338 | static void ixj_fsk_alloc(IXJ *j) | 336 | static void ixj_fsk_alloc(IXJ *j) |
@@ -3867,13 +3865,11 @@ static int set_rec_codec(IXJ *j, int rate) | |||
3867 | j->rec_mode = 7; | 3865 | j->rec_mode = 7; |
3868 | break; | 3866 | break; |
3869 | default: | 3867 | default: |
3868 | kfree(j->read_buffer); | ||
3870 | j->rec_frame_size = 0; | 3869 | j->rec_frame_size = 0; |
3871 | j->rec_mode = -1; | 3870 | j->rec_mode = -1; |
3872 | if (j->read_buffer) { | 3871 | j->read_buffer = NULL; |
3873 | kfree(j->read_buffer); | 3872 | j->read_buffer_size = 0; |
3874 | j->read_buffer = NULL; | ||
3875 | j->read_buffer_size = 0; | ||
3876 | } | ||
3877 | retval = 1; | 3873 | retval = 1; |
3878 | break; | 3874 | break; |
3879 | } | 3875 | } |
@@ -3991,14 +3987,12 @@ static int ixj_record_start(IXJ *j) | |||
3991 | 3987 | ||
3992 | static void ixj_record_stop(IXJ *j) | 3988 | static void ixj_record_stop(IXJ *j) |
3993 | { | 3989 | { |
3994 | if(ixjdebug & 0x0002) | 3990 | if (ixjdebug & 0x0002) |
3995 | printk("IXJ %d Stopping Record Codec %d at %ld\n", j->board, j->rec_codec, jiffies); | 3991 | printk("IXJ %d Stopping Record Codec %d at %ld\n", j->board, j->rec_codec, jiffies); |
3996 | 3992 | ||
3997 | if (j->read_buffer) { | 3993 | kfree(j->read_buffer); |
3998 | kfree(j->read_buffer); | 3994 | j->read_buffer = NULL; |
3999 | j->read_buffer = NULL; | 3995 | j->read_buffer_size = 0; |
4000 | j->read_buffer_size = 0; | ||
4001 | } | ||
4002 | if (j->rec_mode > -1) { | 3996 | if (j->rec_mode > -1) { |
4003 | ixj_WriteDSPCommand(0x5120, j); | 3997 | ixj_WriteDSPCommand(0x5120, j); |
4004 | j->rec_mode = -1; | 3998 | j->rec_mode = -1; |
@@ -4449,13 +4443,11 @@ static int set_play_codec(IXJ *j, int rate) | |||
4449 | j->play_mode = 5; | 4443 | j->play_mode = 5; |
4450 | break; | 4444 | break; |
4451 | default: | 4445 | default: |
4446 | kfree(j->write_buffer); | ||
4452 | j->play_frame_size = 0; | 4447 | j->play_frame_size = 0; |
4453 | j->play_mode = -1; | 4448 | j->play_mode = -1; |
4454 | if (j->write_buffer) { | 4449 | j->write_buffer = NULL; |
4455 | kfree(j->write_buffer); | 4450 | j->write_buffer_size = 0; |
4456 | j->write_buffer = NULL; | ||
4457 | j->write_buffer_size = 0; | ||
4458 | } | ||
4459 | retval = 1; | 4451 | retval = 1; |
4460 | break; | 4452 | break; |
4461 | } | 4453 | } |
@@ -4578,14 +4570,12 @@ static int ixj_play_start(IXJ *j) | |||
4578 | 4570 | ||
4579 | static void ixj_play_stop(IXJ *j) | 4571 | static void ixj_play_stop(IXJ *j) |
4580 | { | 4572 | { |
4581 | if(ixjdebug & 0x0002) | 4573 | if (ixjdebug & 0x0002) |
4582 | printk("IXJ %d Stopping Play Codec %d at %ld\n", j->board, j->play_codec, jiffies); | 4574 | printk("IXJ %d Stopping Play Codec %d at %ld\n", j->board, j->play_codec, jiffies); |
4583 | 4575 | ||
4584 | if (j->write_buffer) { | 4576 | kfree(j->write_buffer); |
4585 | kfree(j->write_buffer); | 4577 | j->write_buffer = NULL; |
4586 | j->write_buffer = NULL; | 4578 | j->write_buffer_size = 0; |
4587 | j->write_buffer_size = 0; | ||
4588 | } | ||
4589 | if (j->play_mode > -1) { | 4579 | if (j->play_mode > -1) { |
4590 | ixj_WriteDSPCommand(0x5221, j); /* Stop playback and flush buffers. 8022 reference page 9-40 */ | 4580 | ixj_WriteDSPCommand(0x5221, j); /* Stop playback and flush buffers. 8022 reference page 9-40 */ |
4591 | 4581 | ||
@@ -5810,9 +5800,7 @@ static void ixj_cpt_stop(IXJ *j) | |||
5810 | ixj_play_tone(j, 0); | 5800 | ixj_play_tone(j, 0); |
5811 | j->tone_state = j->tone_cadence_state = 0; | 5801 | j->tone_state = j->tone_cadence_state = 0; |
5812 | if (j->cadence_t) { | 5802 | if (j->cadence_t) { |
5813 | if (j->cadence_t->ce) { | 5803 | kfree(j->cadence_t->ce); |
5814 | kfree(j->cadence_t->ce); | ||
5815 | } | ||
5816 | kfree(j->cadence_t); | 5804 | kfree(j->cadence_t); |
5817 | j->cadence_t = NULL; | 5805 | j->cadence_t = NULL; |
5818 | } | 5806 | } |
@@ -7497,10 +7485,8 @@ static void cleanup(void) | |||
7497 | printk(KERN_INFO "IXJ: Releasing XILINX address for /dev/phone%d\n", cnt); | 7485 | printk(KERN_INFO "IXJ: Releasing XILINX address for /dev/phone%d\n", cnt); |
7498 | release_region(j->XILINXbase, 4); | 7486 | release_region(j->XILINXbase, 4); |
7499 | } | 7487 | } |
7500 | if (j->read_buffer) | 7488 | kfree(j->read_buffer); |
7501 | kfree(j->read_buffer); | 7489 | kfree(j->write_buffer); |
7502 | if (j->write_buffer) | ||
7503 | kfree(j->write_buffer); | ||
7504 | if (j->dev) | 7490 | if (j->dev) |
7505 | pnp_device_detach(j->dev); | 7491 | pnp_device_detach(j->dev); |
7506 | if (ixjdebug & 0x0002) | 7492 | if (ixjdebug & 0x0002) |
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c index cacd88cc84ab..b6fe30c3ad62 100644 --- a/drivers/video/au1100fb.c +++ b/drivers/video/au1100fb.c | |||
@@ -111,15 +111,15 @@ static int au1100fb_ioctl(struct inode *inode, struct file *file, u_int cmd, | |||
111 | void au1100_nocursor(struct display *p, int mode, int xx, int yy){}; | 111 | void au1100_nocursor(struct display *p, int mode, int xx, int yy){}; |
112 | 112 | ||
113 | static struct fb_ops au1100fb_ops = { | 113 | static struct fb_ops au1100fb_ops = { |
114 | owner: THIS_MODULE, | 114 | .owner = THIS_MODULE, |
115 | fb_get_fix: fbgen_get_fix, | 115 | .fb_get_fix = fbgen_get_fix, |
116 | fb_get_var: fbgen_get_var, | 116 | .fb_get_var = fbgen_get_var, |
117 | fb_set_var: fbgen_set_var, | 117 | .fb_set_var = fbgen_set_var, |
118 | fb_get_cmap: fbgen_get_cmap, | 118 | .fb_get_cmap = fbgen_get_cmap, |
119 | fb_set_cmap: fbgen_set_cmap, | 119 | .fb_set_cmap = fbgen_set_cmap, |
120 | fb_pan_display: fbgen_pan_display, | 120 | .fb_pan_display = fbgen_pan_display, |
121 | fb_ioctl: au1100fb_ioctl, | 121 | .fb_ioctl = au1100fb_ioctl, |
122 | fb_mmap: au1100fb_mmap, | 122 | .fb_mmap = au1100fb_mmap, |
123 | }; | 123 | }; |
124 | 124 | ||
125 | static void au1100_detect(void) | 125 | static void au1100_detect(void) |
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index e4b91a4b936c..cbff98337aa6 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig | |||
@@ -156,7 +156,6 @@ config FONT_6x11 | |||
156 | config FONT_7x14 | 156 | config FONT_7x14 |
157 | bool "console 7x14 font (not supported by all drivers)" if FONTS | 157 | bool "console 7x14 font (not supported by all drivers)" if FONTS |
158 | depends on FRAMEBUFFER_CONSOLE | 158 | depends on FRAMEBUFFER_CONSOLE |
159 | default y if !SPARC32 && !SPARC64 && !FONTS | ||
160 | help | 159 | help |
161 | Console font with characters just a bit smaller than the default. | 160 | Console font with characters just a bit smaller than the default. |
162 | If the standard 8x16 font is a little too big for you, say Y. | 161 | If the standard 8x16 font is a little too big for you, say Y. |
@@ -197,8 +196,8 @@ config FONT_SUN12x22 | |||
197 | standard font is unreadable for you, say Y, otherwise say N. | 196 | standard font is unreadable for you, say Y, otherwise say N. |
198 | 197 | ||
199 | config FONT_10x18 | 198 | config FONT_10x18 |
200 | bool "console 10x18 font (not supported by all drivers)" | 199 | bool "console 10x18 font (not supported by all drivers)" if FONTS |
201 | depends on FONTS | 200 | depends on FRAMEBUFFER_CONSOLE |
202 | help | 201 | help |
203 | This is a high resolution console font for machines with very | 202 | This is a high resolution console font for machines with very |
204 | big letters. It fits between the sun 12x22 and the normal 8x16 font. | 203 | big letters. It fits between the sun 12x22 and the normal 8x16 font. |
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c index 277d733c6d00..7dfbf39b4ed3 100644 --- a/drivers/video/fbsysfs.c +++ b/drivers/video/fbsysfs.c | |||
@@ -228,8 +228,6 @@ static ssize_t store_virtual(struct class_device *class_device, | |||
228 | if (last - buf >= count) | 228 | if (last - buf >= count) |
229 | return -EINVAL; | 229 | return -EINVAL; |
230 | var.yres_virtual = simple_strtoul(last, &last, 0); | 230 | var.yres_virtual = simple_strtoul(last, &last, 0); |
231 | printk(KERN_ERR "fb: xres %d yres %d\n", var.xres_virtual, | ||
232 | var.yres_virtual); | ||
233 | 231 | ||
234 | if ((err = activate(fb_info, &var))) | 232 | if ((err = activate(fb_info, &var))) |
235 | return err; | 233 | return err; |
diff --git a/drivers/video/matrox/matroxfb_misc.c b/drivers/video/matrox/matroxfb_misc.c index 76fd3a519b8a..a18dd024fc86 100644 --- a/drivers/video/matrox/matroxfb_misc.c +++ b/drivers/video/matrox/matroxfb_misc.c | |||
@@ -197,10 +197,7 @@ int matroxfb_vgaHWinit(WPMINFO struct my_timming* m) { | |||
197 | DBG(__FUNCTION__) | 197 | DBG(__FUNCTION__) |
198 | 198 | ||
199 | hw->SEQ[0] = 0x00; | 199 | hw->SEQ[0] = 0x00; |
200 | if (fwidth == 9) | 200 | hw->SEQ[1] = 0x01; /* or 0x09 */ |
201 | hw->SEQ[1] = 0x00; | ||
202 | else | ||
203 | hw->SEQ[1] = 0x01; /* or 0x09 */ | ||
204 | hw->SEQ[2] = 0x0F; /* bitplanes */ | 201 | hw->SEQ[2] = 0x0F; /* bitplanes */ |
205 | hw->SEQ[3] = 0x00; | 202 | hw->SEQ[3] = 0x00; |
206 | hw->SEQ[4] = 0x0E; | 203 | hw->SEQ[4] = 0x0E; |
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index f3069b01e248..9ed1a931dd31 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c | |||
@@ -389,10 +389,11 @@ static int __init vesafb_probe(struct device *device) | |||
389 | unsigned int temp_size = size_total; | 389 | unsigned int temp_size = size_total; |
390 | /* Find the largest power-of-two */ | 390 | /* Find the largest power-of-two */ |
391 | while (temp_size & (temp_size - 1)) | 391 | while (temp_size & (temp_size - 1)) |
392 | temp_size &= (temp_size - 1); | 392 | temp_size &= (temp_size - 1); |
393 | 393 | ||
394 | /* Try and find a power of two to add */ | 394 | /* Try and find a power of two to add */ |
395 | while (temp_size && mtrr_add(vesafb_fix.smem_start, temp_size, MTRR_TYPE_WRCOMB, 1)==-EINVAL) { | 395 | while (temp_size > PAGE_SIZE && |
396 | mtrr_add(vesafb_fix.smem_start, temp_size, MTRR_TYPE_WRCOMB, 1)==-EINVAL) { | ||
396 | temp_size >>= 1; | 397 | temp_size >>= 1; |
397 | } | 398 | } |
398 | } | 399 | } |
diff --git a/fs/Kconfig b/fs/Kconfig index 8157f2e2d515..062177956239 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -734,6 +734,12 @@ config PROC_KCORE | |||
734 | bool "/proc/kcore support" if !ARM | 734 | bool "/proc/kcore support" if !ARM |
735 | depends on PROC_FS && MMU | 735 | depends on PROC_FS && MMU |
736 | 736 | ||
737 | config PROC_VMCORE | ||
738 | bool "/proc/vmcore support (EXPERIMENTAL)" | ||
739 | depends on PROC_FS && EMBEDDED && EXPERIMENTAL && CRASH_DUMP | ||
740 | help | ||
741 | Exports the dump image of crashed kernel in ELF format. | ||
742 | |||
737 | config SYSFS | 743 | config SYSFS |
738 | bool "sysfs file system support" if EMBEDDED | 744 | bool "sysfs file system support" if EMBEDDED |
739 | default y | 745 | default y |
diff --git a/fs/dquot.c b/fs/dquot.c index 37212b039a4a..b9732335bcdc 100644 --- a/fs/dquot.c +++ b/fs/dquot.c | |||
@@ -409,13 +409,10 @@ out_dqlock: | |||
409 | * for this sb+type at all. */ | 409 | * for this sb+type at all. */ |
410 | static void invalidate_dquots(struct super_block *sb, int type) | 410 | static void invalidate_dquots(struct super_block *sb, int type) |
411 | { | 411 | { |
412 | struct dquot *dquot; | 412 | struct dquot *dquot, *tmp; |
413 | struct list_head *head; | ||
414 | 413 | ||
415 | spin_lock(&dq_list_lock); | 414 | spin_lock(&dq_list_lock); |
416 | for (head = inuse_list.next; head != &inuse_list;) { | 415 | list_for_each_entry_safe(dquot, tmp, &inuse_list, dq_inuse) { |
417 | dquot = list_entry(head, struct dquot, dq_inuse); | ||
418 | head = head->next; | ||
419 | if (dquot->dq_sb != sb) | 416 | if (dquot->dq_sb != sb) |
420 | continue; | 417 | continue; |
421 | if (dquot->dq_type != type) | 418 | if (dquot->dq_type != type) |
diff --git a/fs/jffs/intrep.c b/fs/jffs/intrep.c index 8cc6893fc56c..fc589ddd0762 100644 --- a/fs/jffs/intrep.c +++ b/fs/jffs/intrep.c | |||
@@ -175,8 +175,64 @@ jffs_hexdump(struct mtd_info *mtd, loff_t pos, int size) | |||
175 | } | 175 | } |
176 | } | 176 | } |
177 | 177 | ||
178 | /* Print the contents of a node. */ | ||
179 | static void | ||
180 | jffs_print_node(struct jffs_node *n) | ||
181 | { | ||
182 | D(printk("jffs_node: 0x%p\n", n)); | ||
183 | D(printk("{\n")); | ||
184 | D(printk(" 0x%08x, /* version */\n", n->version)); | ||
185 | D(printk(" 0x%08x, /* data_offset */\n", n->data_offset)); | ||
186 | D(printk(" 0x%08x, /* data_size */\n", n->data_size)); | ||
187 | D(printk(" 0x%08x, /* removed_size */\n", n->removed_size)); | ||
188 | D(printk(" 0x%08x, /* fm_offset */\n", n->fm_offset)); | ||
189 | D(printk(" 0x%02x, /* name_size */\n", n->name_size)); | ||
190 | D(printk(" 0x%p, /* fm, fm->offset: %u */\n", | ||
191 | n->fm, (n->fm ? n->fm->offset : 0))); | ||
192 | D(printk(" 0x%p, /* version_prev */\n", n->version_prev)); | ||
193 | D(printk(" 0x%p, /* version_next */\n", n->version_next)); | ||
194 | D(printk(" 0x%p, /* range_prev */\n", n->range_prev)); | ||
195 | D(printk(" 0x%p, /* range_next */\n", n->range_next)); | ||
196 | D(printk("}\n")); | ||
197 | } | ||
198 | |||
178 | #endif | 199 | #endif |
179 | 200 | ||
201 | /* Print the contents of a raw inode. */ | ||
202 | static void | ||
203 | jffs_print_raw_inode(struct jffs_raw_inode *raw_inode) | ||
204 | { | ||
205 | D(printk("jffs_raw_inode: inode number: %u\n", raw_inode->ino)); | ||
206 | D(printk("{\n")); | ||
207 | D(printk(" 0x%08x, /* magic */\n", raw_inode->magic)); | ||
208 | D(printk(" 0x%08x, /* ino */\n", raw_inode->ino)); | ||
209 | D(printk(" 0x%08x, /* pino */\n", raw_inode->pino)); | ||
210 | D(printk(" 0x%08x, /* version */\n", raw_inode->version)); | ||
211 | D(printk(" 0x%08x, /* mode */\n", raw_inode->mode)); | ||
212 | D(printk(" 0x%04x, /* uid */\n", raw_inode->uid)); | ||
213 | D(printk(" 0x%04x, /* gid */\n", raw_inode->gid)); | ||
214 | D(printk(" 0x%08x, /* atime */\n", raw_inode->atime)); | ||
215 | D(printk(" 0x%08x, /* mtime */\n", raw_inode->mtime)); | ||
216 | D(printk(" 0x%08x, /* ctime */\n", raw_inode->ctime)); | ||
217 | D(printk(" 0x%08x, /* offset */\n", raw_inode->offset)); | ||
218 | D(printk(" 0x%08x, /* dsize */\n", raw_inode->dsize)); | ||
219 | D(printk(" 0x%08x, /* rsize */\n", raw_inode->rsize)); | ||
220 | D(printk(" 0x%02x, /* nsize */\n", raw_inode->nsize)); | ||
221 | D(printk(" 0x%02x, /* nlink */\n", raw_inode->nlink)); | ||
222 | D(printk(" 0x%02x, /* spare */\n", | ||
223 | raw_inode->spare)); | ||
224 | D(printk(" %u, /* rename */\n", | ||
225 | raw_inode->rename)); | ||
226 | D(printk(" %u, /* deleted */\n", | ||
227 | raw_inode->deleted)); | ||
228 | D(printk(" 0x%02x, /* accurate */\n", | ||
229 | raw_inode->accurate)); | ||
230 | D(printk(" 0x%08x, /* dchksum */\n", raw_inode->dchksum)); | ||
231 | D(printk(" 0x%04x, /* nchksum */\n", raw_inode->nchksum)); | ||
232 | D(printk(" 0x%04x, /* chksum */\n", raw_inode->chksum)); | ||
233 | D(printk("}\n")); | ||
234 | } | ||
235 | |||
180 | #define flash_safe_acquire(arg) | 236 | #define flash_safe_acquire(arg) |
181 | #define flash_safe_release(arg) | 237 | #define flash_safe_release(arg) |
182 | 238 | ||
@@ -2507,64 +2563,6 @@ jffs_update_file(struct jffs_file *f, struct jffs_node *node) | |||
2507 | return 0; | 2563 | return 0; |
2508 | } | 2564 | } |
2509 | 2565 | ||
2510 | /* Print the contents of a node. */ | ||
2511 | void | ||
2512 | jffs_print_node(struct jffs_node *n) | ||
2513 | { | ||
2514 | D(printk("jffs_node: 0x%p\n", n)); | ||
2515 | D(printk("{\n")); | ||
2516 | D(printk(" 0x%08x, /* version */\n", n->version)); | ||
2517 | D(printk(" 0x%08x, /* data_offset */\n", n->data_offset)); | ||
2518 | D(printk(" 0x%08x, /* data_size */\n", n->data_size)); | ||
2519 | D(printk(" 0x%08x, /* removed_size */\n", n->removed_size)); | ||
2520 | D(printk(" 0x%08x, /* fm_offset */\n", n->fm_offset)); | ||
2521 | D(printk(" 0x%02x, /* name_size */\n", n->name_size)); | ||
2522 | D(printk(" 0x%p, /* fm, fm->offset: %u */\n", | ||
2523 | n->fm, (n->fm ? n->fm->offset : 0))); | ||
2524 | D(printk(" 0x%p, /* version_prev */\n", n->version_prev)); | ||
2525 | D(printk(" 0x%p, /* version_next */\n", n->version_next)); | ||
2526 | D(printk(" 0x%p, /* range_prev */\n", n->range_prev)); | ||
2527 | D(printk(" 0x%p, /* range_next */\n", n->range_next)); | ||
2528 | D(printk("}\n")); | ||
2529 | } | ||
2530 | |||
2531 | |||
2532 | /* Print the contents of a raw inode. */ | ||
2533 | void | ||
2534 | jffs_print_raw_inode(struct jffs_raw_inode *raw_inode) | ||
2535 | { | ||
2536 | D(printk("jffs_raw_inode: inode number: %u\n", raw_inode->ino)); | ||
2537 | D(printk("{\n")); | ||
2538 | D(printk(" 0x%08x, /* magic */\n", raw_inode->magic)); | ||
2539 | D(printk(" 0x%08x, /* ino */\n", raw_inode->ino)); | ||
2540 | D(printk(" 0x%08x, /* pino */\n", raw_inode->pino)); | ||
2541 | D(printk(" 0x%08x, /* version */\n", raw_inode->version)); | ||
2542 | D(printk(" 0x%08x, /* mode */\n", raw_inode->mode)); | ||
2543 | D(printk(" 0x%04x, /* uid */\n", raw_inode->uid)); | ||
2544 | D(printk(" 0x%04x, /* gid */\n", raw_inode->gid)); | ||
2545 | D(printk(" 0x%08x, /* atime */\n", raw_inode->atime)); | ||
2546 | D(printk(" 0x%08x, /* mtime */\n", raw_inode->mtime)); | ||
2547 | D(printk(" 0x%08x, /* ctime */\n", raw_inode->ctime)); | ||
2548 | D(printk(" 0x%08x, /* offset */\n", raw_inode->offset)); | ||
2549 | D(printk(" 0x%08x, /* dsize */\n", raw_inode->dsize)); | ||
2550 | D(printk(" 0x%08x, /* rsize */\n", raw_inode->rsize)); | ||
2551 | D(printk(" 0x%02x, /* nsize */\n", raw_inode->nsize)); | ||
2552 | D(printk(" 0x%02x, /* nlink */\n", raw_inode->nlink)); | ||
2553 | D(printk(" 0x%02x, /* spare */\n", | ||
2554 | raw_inode->spare)); | ||
2555 | D(printk(" %u, /* rename */\n", | ||
2556 | raw_inode->rename)); | ||
2557 | D(printk(" %u, /* deleted */\n", | ||
2558 | raw_inode->deleted)); | ||
2559 | D(printk(" 0x%02x, /* accurate */\n", | ||
2560 | raw_inode->accurate)); | ||
2561 | D(printk(" 0x%08x, /* dchksum */\n", raw_inode->dchksum)); | ||
2562 | D(printk(" 0x%04x, /* nchksum */\n", raw_inode->nchksum)); | ||
2563 | D(printk(" 0x%04x, /* chksum */\n", raw_inode->chksum)); | ||
2564 | D(printk("}\n")); | ||
2565 | } | ||
2566 | |||
2567 | |||
2568 | /* Print the contents of a file. */ | 2566 | /* Print the contents of a file. */ |
2569 | #if 0 | 2567 | #if 0 |
2570 | int | 2568 | int |
diff --git a/fs/jffs/intrep.h b/fs/jffs/intrep.h index 4ae97b17911c..5c7abe0e2695 100644 --- a/fs/jffs/intrep.h +++ b/fs/jffs/intrep.h | |||
@@ -49,8 +49,6 @@ int jffs_garbage_collect_thread(void *c); | |||
49 | void jffs_garbage_collect_trigger(struct jffs_control *c); | 49 | void jffs_garbage_collect_trigger(struct jffs_control *c); |
50 | 50 | ||
51 | /* For debugging purposes. */ | 51 | /* For debugging purposes. */ |
52 | void jffs_print_node(struct jffs_node *n); | ||
53 | void jffs_print_raw_inode(struct jffs_raw_inode *raw_inode); | ||
54 | #if 0 | 52 | #if 0 |
55 | int jffs_print_file(struct jffs_file *f); | 53 | int jffs_print_file(struct jffs_file *f); |
56 | #endif /* 0 */ | 54 | #endif /* 0 */ |
diff --git a/fs/jffs/jffs_fm.c b/fs/jffs/jffs_fm.c index 0cab8da49d3c..053e3a98a276 100644 --- a/fs/jffs/jffs_fm.c +++ b/fs/jffs/jffs_fm.c | |||
@@ -31,6 +31,60 @@ static void jffs_free_fm(struct jffs_fm *n); | |||
31 | extern kmem_cache_t *fm_cache; | 31 | extern kmem_cache_t *fm_cache; |
32 | extern kmem_cache_t *node_cache; | 32 | extern kmem_cache_t *node_cache; |
33 | 33 | ||
34 | #if CONFIG_JFFS_FS_VERBOSE > 0 | ||
35 | void | ||
36 | jffs_print_fmcontrol(struct jffs_fmcontrol *fmc) | ||
37 | { | ||
38 | D(printk("struct jffs_fmcontrol: 0x%p\n", fmc)); | ||
39 | D(printk("{\n")); | ||
40 | D(printk(" %u, /* flash_size */\n", fmc->flash_size)); | ||
41 | D(printk(" %u, /* used_size */\n", fmc->used_size)); | ||
42 | D(printk(" %u, /* dirty_size */\n", fmc->dirty_size)); | ||
43 | D(printk(" %u, /* free_size */\n", fmc->free_size)); | ||
44 | D(printk(" %u, /* sector_size */\n", fmc->sector_size)); | ||
45 | D(printk(" %u, /* min_free_size */\n", fmc->min_free_size)); | ||
46 | D(printk(" %u, /* max_chunk_size */\n", fmc->max_chunk_size)); | ||
47 | D(printk(" 0x%p, /* mtd */\n", fmc->mtd)); | ||
48 | D(printk(" 0x%p, /* head */ " | ||
49 | "(head->offset = 0x%08x)\n", | ||
50 | fmc->head, (fmc->head ? fmc->head->offset : 0))); | ||
51 | D(printk(" 0x%p, /* tail */ " | ||
52 | "(tail->offset + tail->size = 0x%08x)\n", | ||
53 | fmc->tail, | ||
54 | (fmc->tail ? fmc->tail->offset + fmc->tail->size : 0))); | ||
55 | D(printk(" 0x%p, /* head_extra */\n", fmc->head_extra)); | ||
56 | D(printk(" 0x%p, /* tail_extra */\n", fmc->tail_extra)); | ||
57 | D(printk("}\n")); | ||
58 | } | ||
59 | #endif /* CONFIG_JFFS_FS_VERBOSE > 0 */ | ||
60 | |||
61 | #if CONFIG_JFFS_FS_VERBOSE > 2 | ||
62 | static void | ||
63 | jffs_print_fm(struct jffs_fm *fm) | ||
64 | { | ||
65 | D(printk("struct jffs_fm: 0x%p\n", fm)); | ||
66 | D(printk("{\n")); | ||
67 | D(printk(" 0x%08x, /* offset */\n", fm->offset)); | ||
68 | D(printk(" %u, /* size */\n", fm->size)); | ||
69 | D(printk(" 0x%p, /* prev */\n", fm->prev)); | ||
70 | D(printk(" 0x%p, /* next */\n", fm->next)); | ||
71 | D(printk(" 0x%p, /* nodes */\n", fm->nodes)); | ||
72 | D(printk("}\n")); | ||
73 | } | ||
74 | #endif /* CONFIG_JFFS_FS_VERBOSE > 2 */ | ||
75 | |||
76 | #if 0 | ||
77 | void | ||
78 | jffs_print_node_ref(struct jffs_node_ref *ref) | ||
79 | { | ||
80 | D(printk("struct jffs_node_ref: 0x%p\n", ref)); | ||
81 | D(printk("{\n")); | ||
82 | D(printk(" 0x%p, /* node */\n", ref->node)); | ||
83 | D(printk(" 0x%p, /* next */\n", ref->next)); | ||
84 | D(printk("}\n")); | ||
85 | } | ||
86 | #endif /* 0 */ | ||
87 | |||
34 | /* This function creates a new shiny flash memory control structure. */ | 88 | /* This function creates a new shiny flash memory control structure. */ |
35 | struct jffs_fmcontrol * | 89 | struct jffs_fmcontrol * |
36 | jffs_build_begin(struct jffs_control *c, int unit) | 90 | jffs_build_begin(struct jffs_control *c, int unit) |
@@ -742,54 +796,3 @@ int jffs_get_node_inuse(void) | |||
742 | { | 796 | { |
743 | return no_jffs_node; | 797 | return no_jffs_node; |
744 | } | 798 | } |
745 | |||
746 | void | ||
747 | jffs_print_fmcontrol(struct jffs_fmcontrol *fmc) | ||
748 | { | ||
749 | D(printk("struct jffs_fmcontrol: 0x%p\n", fmc)); | ||
750 | D(printk("{\n")); | ||
751 | D(printk(" %u, /* flash_size */\n", fmc->flash_size)); | ||
752 | D(printk(" %u, /* used_size */\n", fmc->used_size)); | ||
753 | D(printk(" %u, /* dirty_size */\n", fmc->dirty_size)); | ||
754 | D(printk(" %u, /* free_size */\n", fmc->free_size)); | ||
755 | D(printk(" %u, /* sector_size */\n", fmc->sector_size)); | ||
756 | D(printk(" %u, /* min_free_size */\n", fmc->min_free_size)); | ||
757 | D(printk(" %u, /* max_chunk_size */\n", fmc->max_chunk_size)); | ||
758 | D(printk(" 0x%p, /* mtd */\n", fmc->mtd)); | ||
759 | D(printk(" 0x%p, /* head */ " | ||
760 | "(head->offset = 0x%08x)\n", | ||
761 | fmc->head, (fmc->head ? fmc->head->offset : 0))); | ||
762 | D(printk(" 0x%p, /* tail */ " | ||
763 | "(tail->offset + tail->size = 0x%08x)\n", | ||
764 | fmc->tail, | ||
765 | (fmc->tail ? fmc->tail->offset + fmc->tail->size : 0))); | ||
766 | D(printk(" 0x%p, /* head_extra */\n", fmc->head_extra)); | ||
767 | D(printk(" 0x%p, /* tail_extra */\n", fmc->tail_extra)); | ||
768 | D(printk("}\n")); | ||
769 | } | ||
770 | |||
771 | void | ||
772 | jffs_print_fm(struct jffs_fm *fm) | ||
773 | { | ||
774 | D(printk("struct jffs_fm: 0x%p\n", fm)); | ||
775 | D(printk("{\n")); | ||
776 | D(printk(" 0x%08x, /* offset */\n", fm->offset)); | ||
777 | D(printk(" %u, /* size */\n", fm->size)); | ||
778 | D(printk(" 0x%p, /* prev */\n", fm->prev)); | ||
779 | D(printk(" 0x%p, /* next */\n", fm->next)); | ||
780 | D(printk(" 0x%p, /* nodes */\n", fm->nodes)); | ||
781 | D(printk("}\n")); | ||
782 | } | ||
783 | |||
784 | #if 0 | ||
785 | void | ||
786 | jffs_print_node_ref(struct jffs_node_ref *ref) | ||
787 | { | ||
788 | D(printk("struct jffs_node_ref: 0x%p\n", ref)); | ||
789 | D(printk("{\n")); | ||
790 | D(printk(" 0x%p, /* node */\n", ref->node)); | ||
791 | D(printk(" 0x%p, /* next */\n", ref->next)); | ||
792 | D(printk("}\n")); | ||
793 | } | ||
794 | #endif /* 0 */ | ||
795 | |||
diff --git a/fs/jffs/jffs_fm.h b/fs/jffs/jffs_fm.h index bc291c431822..f64151e74122 100644 --- a/fs/jffs/jffs_fm.h +++ b/fs/jffs/jffs_fm.h | |||
@@ -139,8 +139,9 @@ int jffs_add_node(struct jffs_node *node); | |||
139 | void jffs_fmfree_partly(struct jffs_fmcontrol *fmc, struct jffs_fm *fm, | 139 | void jffs_fmfree_partly(struct jffs_fmcontrol *fmc, struct jffs_fm *fm, |
140 | __u32 size); | 140 | __u32 size); |
141 | 141 | ||
142 | #if CONFIG_JFFS_FS_VERBOSE > 0 | ||
142 | void jffs_print_fmcontrol(struct jffs_fmcontrol *fmc); | 143 | void jffs_print_fmcontrol(struct jffs_fmcontrol *fmc); |
143 | void jffs_print_fm(struct jffs_fm *fm); | 144 | #endif |
144 | #if 0 | 145 | #if 0 |
145 | void jffs_print_node_ref(struct jffs_node_ref *ref); | 146 | void jffs_print_node_ref(struct jffs_node_ref *ref); |
146 | #endif /* 0 */ | 147 | #endif /* 0 */ |
diff --git a/fs/libfs.c b/fs/libfs.c index 5025563e7379..58101dff2c66 100644 --- a/fs/libfs.c +++ b/fs/libfs.c | |||
@@ -183,6 +183,7 @@ struct file_operations simple_dir_operations = { | |||
183 | .llseek = dcache_dir_lseek, | 183 | .llseek = dcache_dir_lseek, |
184 | .read = generic_read_dir, | 184 | .read = generic_read_dir, |
185 | .readdir = dcache_readdir, | 185 | .readdir = dcache_readdir, |
186 | .fsync = simple_sync_file, | ||
186 | }; | 187 | }; |
187 | 188 | ||
188 | struct inode_operations simple_dir_inode_operations = { | 189 | struct inode_operations simple_dir_inode_operations = { |
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index 2dc2d8693968..a9f7a8ab1d59 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c | |||
@@ -705,18 +705,6 @@ ncp_do_readdir(struct file *filp, void *dirent, filldir_t filldir, | |||
705 | DPRINTK("ncp_do_readdir: init failed, err=%d\n", err); | 705 | DPRINTK("ncp_do_readdir: init failed, err=%d\n", err); |
706 | return; | 706 | return; |
707 | } | 707 | } |
708 | #ifdef USE_OLD_SLOW_DIRECTORY_LISTING | ||
709 | for (;;) { | ||
710 | err = ncp_search_for_file_or_subdir(server, &seq, &entry.i); | ||
711 | if (err) { | ||
712 | DPRINTK("ncp_do_readdir: search failed, err=%d\n", err); | ||
713 | break; | ||
714 | } | ||
715 | entry.volume = entry.i.volNumber; | ||
716 | if (!ncp_fill_cache(filp, dirent, filldir, ctl, &entry)) | ||
717 | break; | ||
718 | } | ||
719 | #else | ||
720 | /* We MUST NOT use server->buffer_size handshaked with server if we are | 708 | /* We MUST NOT use server->buffer_size handshaked with server if we are |
721 | using UDP, as for UDP server uses max. buffer size determined by | 709 | using UDP, as for UDP server uses max. buffer size determined by |
722 | MTU, and for TCP server uses hardwired value 65KB (== 66560 bytes). | 710 | MTU, and for TCP server uses hardwired value 65KB (== 66560 bytes). |
@@ -754,7 +742,6 @@ ncp_do_readdir(struct file *filp, void *dirent, filldir_t filldir, | |||
754 | } | 742 | } |
755 | } while (more); | 743 | } while (more); |
756 | vfree(buf); | 744 | vfree(buf); |
757 | #endif | ||
758 | return; | 745 | return; |
759 | } | 746 | } |
760 | 747 | ||
diff --git a/fs/ncpfs/ncplib_kernel.c b/fs/ncpfs/ncplib_kernel.c index e4eb5ed4bee4..c755e1848a42 100644 --- a/fs/ncpfs/ncplib_kernel.c +++ b/fs/ncpfs/ncplib_kernel.c | |||
@@ -845,46 +845,6 @@ out: | |||
845 | return result; | 845 | return result; |
846 | } | 846 | } |
847 | 847 | ||
848 | /* Search for everything */ | ||
849 | int ncp_search_for_file_or_subdir(struct ncp_server *server, | ||
850 | struct nw_search_sequence *seq, | ||
851 | struct nw_info_struct *target) | ||
852 | { | ||
853 | int result; | ||
854 | |||
855 | ncp_init_request(server); | ||
856 | ncp_add_byte(server, 3); /* subfunction */ | ||
857 | ncp_add_byte(server, server->name_space[seq->volNumber]); | ||
858 | ncp_add_byte(server, 0); /* data stream (???) */ | ||
859 | ncp_add_word(server, cpu_to_le16(0x8006)); /* Search attribs */ | ||
860 | ncp_add_dword(server, RIM_ALL); /* return info mask */ | ||
861 | ncp_add_mem(server, seq, 9); | ||
862 | #ifdef CONFIG_NCPFS_NFS_NS | ||
863 | if (server->name_space[seq->volNumber] == NW_NS_NFS) { | ||
864 | ncp_add_byte(server, 0); /* 0 byte pattern */ | ||
865 | } else | ||
866 | #endif | ||
867 | { | ||
868 | ncp_add_byte(server, 2); /* 2 byte pattern */ | ||
869 | ncp_add_byte(server, 0xff); /* following is a wildcard */ | ||
870 | ncp_add_byte(server, '*'); | ||
871 | } | ||
872 | |||
873 | if ((result = ncp_request(server, 87)) != 0) | ||
874 | goto out; | ||
875 | memcpy(seq, ncp_reply_data(server, 0), sizeof(*seq)); | ||
876 | ncp_extract_file_info(ncp_reply_data(server, 10), target); | ||
877 | |||
878 | ncp_unlock_server(server); | ||
879 | |||
880 | result = ncp_obtain_nfs_info(server, target); | ||
881 | return result; | ||
882 | |||
883 | out: | ||
884 | ncp_unlock_server(server); | ||
885 | return result; | ||
886 | } | ||
887 | |||
888 | int ncp_search_for_fileset(struct ncp_server *server, | 848 | int ncp_search_for_fileset(struct ncp_server *server, |
889 | struct nw_search_sequence *seq, | 849 | struct nw_search_sequence *seq, |
890 | int* more, | 850 | int* more, |
diff --git a/fs/ncpfs/ncplib_kernel.h b/fs/ncpfs/ncplib_kernel.h index 05ec2e9d90c6..9e4dc30c2435 100644 --- a/fs/ncpfs/ncplib_kernel.h +++ b/fs/ncpfs/ncplib_kernel.h | |||
@@ -87,9 +87,6 @@ int ncp_open_create_file_or_subdir(struct ncp_server *, struct inode *, char *, | |||
87 | 87 | ||
88 | int ncp_initialize_search(struct ncp_server *, struct inode *, | 88 | int ncp_initialize_search(struct ncp_server *, struct inode *, |
89 | struct nw_search_sequence *target); | 89 | struct nw_search_sequence *target); |
90 | int ncp_search_for_file_or_subdir(struct ncp_server *server, | ||
91 | struct nw_search_sequence *seq, | ||
92 | struct nw_info_struct *target); | ||
93 | int ncp_search_for_fileset(struct ncp_server *server, | 90 | int ncp_search_for_fileset(struct ncp_server *server, |
94 | struct nw_search_sequence *seq, | 91 | struct nw_search_sequence *seq, |
95 | int* more, int* cnt, | 92 | int* more, int* cnt, |
diff --git a/fs/partitions/Makefile b/fs/partitions/Makefile index 4c83c17969e1..66d5cc26fafb 100644 --- a/fs/partitions/Makefile +++ b/fs/partitions/Makefile | |||
@@ -17,4 +17,3 @@ obj-$(CONFIG_SUN_PARTITION) += sun.o | |||
17 | obj-$(CONFIG_ULTRIX_PARTITION) += ultrix.o | 17 | obj-$(CONFIG_ULTRIX_PARTITION) += ultrix.o |
18 | obj-$(CONFIG_IBM_PARTITION) += ibm.o | 18 | obj-$(CONFIG_IBM_PARTITION) += ibm.o |
19 | obj-$(CONFIG_EFI_PARTITION) += efi.o | 19 | obj-$(CONFIG_EFI_PARTITION) += efi.o |
20 | obj-$(CONFIG_NEC98_PARTITION) += nec98.o msdos.o | ||
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 2cab98a9a621..77e178f13162 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -79,9 +79,6 @@ static int (*check_part[])(struct parsed_partitions *, struct block_device *) = | |||
79 | #ifdef CONFIG_LDM_PARTITION | 79 | #ifdef CONFIG_LDM_PARTITION |
80 | ldm_partition, /* this must come before msdos */ | 80 | ldm_partition, /* this must come before msdos */ |
81 | #endif | 81 | #endif |
82 | #ifdef CONFIG_NEC98_PARTITION | ||
83 | nec98_partition, /* must be come before `msdos_partition' */ | ||
84 | #endif | ||
85 | #ifdef CONFIG_MSDOS_PARTITION | 82 | #ifdef CONFIG_MSDOS_PARTITION |
86 | msdos_partition, | 83 | msdos_partition, |
87 | #endif | 84 | #endif |
diff --git a/fs/partitions/check.h b/fs/partitions/check.h index 43adcc68e471..17ae8ecd9e8b 100644 --- a/fs/partitions/check.h +++ b/fs/partitions/check.h | |||
@@ -30,7 +30,3 @@ put_partition(struct parsed_partitions *p, int n, sector_t from, sector_t size) | |||
30 | 30 | ||
31 | extern int warn_no_part; | 31 | extern int warn_no_part; |
32 | 32 | ||
33 | extern void parse_bsd(struct parsed_partitions *state, | ||
34 | struct block_device *bdev, u32 offset, u32 size, | ||
35 | int origin, char *flavour, int max_partitions); | ||
36 | |||
diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c index 584a27b2bbd5..9935d254186e 100644 --- a/fs/partitions/msdos.c +++ b/fs/partitions/msdos.c | |||
@@ -202,12 +202,12 @@ parse_solaris_x86(struct parsed_partitions *state, struct block_device *bdev, | |||
202 | #endif | 202 | #endif |
203 | } | 203 | } |
204 | 204 | ||
205 | #if defined(CONFIG_BSD_DISKLABEL) || defined(CONFIG_NEC98_PARTITION) | 205 | #if defined(CONFIG_BSD_DISKLABEL) |
206 | /* | 206 | /* |
207 | * Create devices for BSD partitions listed in a disklabel, under a | 207 | * Create devices for BSD partitions listed in a disklabel, under a |
208 | * dos-like partition. See parse_extended() for more information. | 208 | * dos-like partition. See parse_extended() for more information. |
209 | */ | 209 | */ |
210 | void | 210 | static void |
211 | parse_bsd(struct parsed_partitions *state, struct block_device *bdev, | 211 | parse_bsd(struct parsed_partitions *state, struct block_device *bdev, |
212 | u32 offset, u32 size, int origin, char *flavour, | 212 | u32 offset, u32 size, int origin, char *flavour, |
213 | int max_partitions) | 213 | int max_partitions) |
diff --git a/fs/proc/Makefile b/fs/proc/Makefile index 738b9b602932..7431d7ba2d09 100644 --- a/fs/proc/Makefile +++ b/fs/proc/Makefile | |||
@@ -11,4 +11,5 @@ proc-y += inode.o root.o base.o generic.o array.o \ | |||
11 | kmsg.o proc_tty.o proc_misc.o | 11 | kmsg.o proc_tty.o proc_misc.o |
12 | 12 | ||
13 | proc-$(CONFIG_PROC_KCORE) += kcore.o | 13 | proc-$(CONFIG_PROC_KCORE) += kcore.o |
14 | proc-$(CONFIG_PROC_VMCORE) += vmcore.o | ||
14 | proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o | 15 | proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o |
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index 94b570ad037d..a3453555a94e 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <linux/jiffies.h> | 44 | #include <linux/jiffies.h> |
45 | #include <linux/sysrq.h> | 45 | #include <linux/sysrq.h> |
46 | #include <linux/vmalloc.h> | 46 | #include <linux/vmalloc.h> |
47 | #include <linux/crash_dump.h> | ||
47 | #include <asm/uaccess.h> | 48 | #include <asm/uaccess.h> |
48 | #include <asm/pgtable.h> | 49 | #include <asm/pgtable.h> |
49 | #include <asm/io.h> | 50 | #include <asm/io.h> |
@@ -618,6 +619,11 @@ void __init proc_misc_init(void) | |||
618 | (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE; | 619 | (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE; |
619 | } | 620 | } |
620 | #endif | 621 | #endif |
622 | #ifdef CONFIG_PROC_VMCORE | ||
623 | proc_vmcore = create_proc_entry("vmcore", S_IRUSR, NULL); | ||
624 | if (proc_vmcore) | ||
625 | proc_vmcore->proc_fops = &proc_vmcore_operations; | ||
626 | #endif | ||
621 | #ifdef CONFIG_MAGIC_SYSRQ | 627 | #ifdef CONFIG_MAGIC_SYSRQ |
622 | entry = create_proc_entry("sysrq-trigger", S_IWUSR, NULL); | 628 | entry = create_proc_entry("sysrq-trigger", S_IWUSR, NULL); |
623 | if (entry) | 629 | if (entry) |
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c new file mode 100644 index 000000000000..3b2e7b69e63a --- /dev/null +++ b/fs/proc/vmcore.c | |||
@@ -0,0 +1,669 @@ | |||
1 | /* | ||
2 | * fs/proc/vmcore.c Interface for accessing the crash | ||
3 | * dump from the system's previous life. | ||
4 | * Heavily borrowed from fs/proc/kcore.c | ||
5 | * Created by: Hariprasad Nellitheertha (hari@in.ibm.com) | ||
6 | * Copyright (C) IBM Corporation, 2004. All rights reserved | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #include <linux/config.h> | ||
11 | #include <linux/mm.h> | ||
12 | #include <linux/proc_fs.h> | ||
13 | #include <linux/user.h> | ||
14 | #include <linux/a.out.h> | ||
15 | #include <linux/elf.h> | ||
16 | #include <linux/elfcore.h> | ||
17 | #include <linux/proc_fs.h> | ||
18 | #include <linux/highmem.h> | ||
19 | #include <linux/bootmem.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/crash_dump.h> | ||
22 | #include <linux/list.h> | ||
23 | #include <asm/uaccess.h> | ||
24 | #include <asm/io.h> | ||
25 | |||
26 | /* List representing chunks of contiguous memory areas and their offsets in | ||
27 | * vmcore file. | ||
28 | */ | ||
29 | static LIST_HEAD(vmcore_list); | ||
30 | |||
31 | /* Stores the pointer to the buffer containing kernel elf core headers. */ | ||
32 | static char *elfcorebuf; | ||
33 | static size_t elfcorebuf_sz; | ||
34 | |||
35 | /* Total size of vmcore file. */ | ||
36 | static u64 vmcore_size; | ||
37 | |||
38 | struct proc_dir_entry *proc_vmcore = NULL; | ||
39 | |||
40 | /* Reads a page from the oldmem device from given offset. */ | ||
41 | static ssize_t read_from_oldmem(char *buf, size_t count, | ||
42 | loff_t *ppos, int userbuf) | ||
43 | { | ||
44 | unsigned long pfn, offset; | ||
45 | size_t nr_bytes; | ||
46 | ssize_t read = 0, tmp; | ||
47 | |||
48 | if (!count) | ||
49 | return 0; | ||
50 | |||
51 | offset = (unsigned long)(*ppos % PAGE_SIZE); | ||
52 | pfn = (unsigned long)(*ppos / PAGE_SIZE); | ||
53 | if (pfn > saved_max_pfn) | ||
54 | return -EINVAL; | ||
55 | |||
56 | do { | ||
57 | if (count > (PAGE_SIZE - offset)) | ||
58 | nr_bytes = PAGE_SIZE - offset; | ||
59 | else | ||
60 | nr_bytes = count; | ||
61 | |||
62 | tmp = copy_oldmem_page(pfn, buf, nr_bytes, offset, userbuf); | ||
63 | if (tmp < 0) | ||
64 | return tmp; | ||
65 | *ppos += nr_bytes; | ||
66 | count -= nr_bytes; | ||
67 | buf += nr_bytes; | ||
68 | read += nr_bytes; | ||
69 | ++pfn; | ||
70 | offset = 0; | ||
71 | } while (count); | ||
72 | |||
73 | return read; | ||
74 | } | ||
75 | |||
76 | /* Maps vmcore file offset to respective physical address in memroy. */ | ||
77 | static u64 map_offset_to_paddr(loff_t offset, struct list_head *vc_list, | ||
78 | struct vmcore **m_ptr) | ||
79 | { | ||
80 | struct vmcore *m; | ||
81 | u64 paddr; | ||
82 | |||
83 | list_for_each_entry(m, vc_list, list) { | ||
84 | u64 start, end; | ||
85 | start = m->offset; | ||
86 | end = m->offset + m->size - 1; | ||
87 | if (offset >= start && offset <= end) { | ||
88 | paddr = m->paddr + offset - start; | ||
89 | *m_ptr = m; | ||
90 | return paddr; | ||
91 | } | ||
92 | } | ||
93 | *m_ptr = NULL; | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | /* Read from the ELF header and then the crash dump. On error, negative value is | ||
98 | * returned otherwise number of bytes read are returned. | ||
99 | */ | ||
100 | static ssize_t read_vmcore(struct file *file, char __user *buffer, | ||
101 | size_t buflen, loff_t *fpos) | ||
102 | { | ||
103 | ssize_t acc = 0, tmp; | ||
104 | size_t tsz, nr_bytes; | ||
105 | u64 start; | ||
106 | struct vmcore *curr_m = NULL; | ||
107 | |||
108 | if (buflen == 0 || *fpos >= vmcore_size) | ||
109 | return 0; | ||
110 | |||
111 | /* trim buflen to not go beyond EOF */ | ||
112 | if (buflen > vmcore_size - *fpos) | ||
113 | buflen = vmcore_size - *fpos; | ||
114 | |||
115 | /* Read ELF core header */ | ||
116 | if (*fpos < elfcorebuf_sz) { | ||
117 | tsz = elfcorebuf_sz - *fpos; | ||
118 | if (buflen < tsz) | ||
119 | tsz = buflen; | ||
120 | if (copy_to_user(buffer, elfcorebuf + *fpos, tsz)) | ||
121 | return -EFAULT; | ||
122 | buflen -= tsz; | ||
123 | *fpos += tsz; | ||
124 | buffer += tsz; | ||
125 | acc += tsz; | ||
126 | |||
127 | /* leave now if filled buffer already */ | ||
128 | if (buflen == 0) | ||
129 | return acc; | ||
130 | } | ||
131 | |||
132 | start = map_offset_to_paddr(*fpos, &vmcore_list, &curr_m); | ||
133 | if (!curr_m) | ||
134 | return -EINVAL; | ||
135 | if ((tsz = (PAGE_SIZE - (start & ~PAGE_MASK))) > buflen) | ||
136 | tsz = buflen; | ||
137 | |||
138 | /* Calculate left bytes in current memory segment. */ | ||
139 | nr_bytes = (curr_m->size - (start - curr_m->paddr)); | ||
140 | if (tsz > nr_bytes) | ||
141 | tsz = nr_bytes; | ||
142 | |||
143 | while (buflen) { | ||
144 | tmp = read_from_oldmem(buffer, tsz, &start, 1); | ||
145 | if (tmp < 0) | ||
146 | return tmp; | ||
147 | buflen -= tsz; | ||
148 | *fpos += tsz; | ||
149 | buffer += tsz; | ||
150 | acc += tsz; | ||
151 | if (start >= (curr_m->paddr + curr_m->size)) { | ||
152 | if (curr_m->list.next == &vmcore_list) | ||
153 | return acc; /*EOF*/ | ||
154 | curr_m = list_entry(curr_m->list.next, | ||
155 | struct vmcore, list); | ||
156 | start = curr_m->paddr; | ||
157 | } | ||
158 | if ((tsz = (PAGE_SIZE - (start & ~PAGE_MASK))) > buflen) | ||
159 | tsz = buflen; | ||
160 | /* Calculate left bytes in current memory segment. */ | ||
161 | nr_bytes = (curr_m->size - (start - curr_m->paddr)); | ||
162 | if (tsz > nr_bytes) | ||
163 | tsz = nr_bytes; | ||
164 | } | ||
165 | return acc; | ||
166 | } | ||
167 | |||
168 | static int open_vmcore(struct inode *inode, struct file *filp) | ||
169 | { | ||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | struct file_operations proc_vmcore_operations = { | ||
174 | .read = read_vmcore, | ||
175 | .open = open_vmcore, | ||
176 | }; | ||
177 | |||
178 | static struct vmcore* __init get_new_element(void) | ||
179 | { | ||
180 | struct vmcore *p; | ||
181 | |||
182 | p = kmalloc(sizeof(*p), GFP_KERNEL); | ||
183 | if (p) | ||
184 | memset(p, 0, sizeof(*p)); | ||
185 | return p; | ||
186 | } | ||
187 | |||
188 | static u64 __init get_vmcore_size_elf64(char *elfptr) | ||
189 | { | ||
190 | int i; | ||
191 | u64 size; | ||
192 | Elf64_Ehdr *ehdr_ptr; | ||
193 | Elf64_Phdr *phdr_ptr; | ||
194 | |||
195 | ehdr_ptr = (Elf64_Ehdr *)elfptr; | ||
196 | phdr_ptr = (Elf64_Phdr*)(elfptr + sizeof(Elf64_Ehdr)); | ||
197 | size = sizeof(Elf64_Ehdr) + ((ehdr_ptr->e_phnum) * sizeof(Elf64_Phdr)); | ||
198 | for (i = 0; i < ehdr_ptr->e_phnum; i++) { | ||
199 | size += phdr_ptr->p_memsz; | ||
200 | phdr_ptr++; | ||
201 | } | ||
202 | return size; | ||
203 | } | ||
204 | |||
205 | static u64 __init get_vmcore_size_elf32(char *elfptr) | ||
206 | { | ||
207 | int i; | ||
208 | u64 size; | ||
209 | Elf32_Ehdr *ehdr_ptr; | ||
210 | Elf32_Phdr *phdr_ptr; | ||
211 | |||
212 | ehdr_ptr = (Elf32_Ehdr *)elfptr; | ||
213 | phdr_ptr = (Elf32_Phdr*)(elfptr + sizeof(Elf32_Ehdr)); | ||
214 | size = sizeof(Elf32_Ehdr) + ((ehdr_ptr->e_phnum) * sizeof(Elf32_Phdr)); | ||
215 | for (i = 0; i < ehdr_ptr->e_phnum; i++) { | ||
216 | size += phdr_ptr->p_memsz; | ||
217 | phdr_ptr++; | ||
218 | } | ||
219 | return size; | ||
220 | } | ||
221 | |||
222 | /* Merges all the PT_NOTE headers into one. */ | ||
223 | static int __init merge_note_headers_elf64(char *elfptr, size_t *elfsz, | ||
224 | struct list_head *vc_list) | ||
225 | { | ||
226 | int i, nr_ptnote=0, rc=0; | ||
227 | char *tmp; | ||
228 | Elf64_Ehdr *ehdr_ptr; | ||
229 | Elf64_Phdr phdr, *phdr_ptr; | ||
230 | Elf64_Nhdr *nhdr_ptr; | ||
231 | u64 phdr_sz = 0, note_off; | ||
232 | |||
233 | ehdr_ptr = (Elf64_Ehdr *)elfptr; | ||
234 | phdr_ptr = (Elf64_Phdr*)(elfptr + sizeof(Elf64_Ehdr)); | ||
235 | for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) { | ||
236 | int j; | ||
237 | void *notes_section; | ||
238 | struct vmcore *new; | ||
239 | u64 offset, max_sz, sz, real_sz = 0; | ||
240 | if (phdr_ptr->p_type != PT_NOTE) | ||
241 | continue; | ||
242 | nr_ptnote++; | ||
243 | max_sz = phdr_ptr->p_memsz; | ||
244 | offset = phdr_ptr->p_offset; | ||
245 | notes_section = kmalloc(max_sz, GFP_KERNEL); | ||
246 | if (!notes_section) | ||
247 | return -ENOMEM; | ||
248 | rc = read_from_oldmem(notes_section, max_sz, &offset, 0); | ||
249 | if (rc < 0) { | ||
250 | kfree(notes_section); | ||
251 | return rc; | ||
252 | } | ||
253 | nhdr_ptr = notes_section; | ||
254 | for (j = 0; j < max_sz; j += sz) { | ||
255 | if (nhdr_ptr->n_namesz == 0) | ||
256 | break; | ||
257 | sz = sizeof(Elf64_Nhdr) + | ||
258 | ((nhdr_ptr->n_namesz + 3) & ~3) + | ||
259 | ((nhdr_ptr->n_descsz + 3) & ~3); | ||
260 | real_sz += sz; | ||
261 | nhdr_ptr = (Elf64_Nhdr*)((char*)nhdr_ptr + sz); | ||
262 | } | ||
263 | |||
264 | /* Add this contiguous chunk of notes section to vmcore list.*/ | ||
265 | new = get_new_element(); | ||
266 | if (!new) { | ||
267 | kfree(notes_section); | ||
268 | return -ENOMEM; | ||
269 | } | ||
270 | new->paddr = phdr_ptr->p_offset; | ||
271 | new->size = real_sz; | ||
272 | list_add_tail(&new->list, vc_list); | ||
273 | phdr_sz += real_sz; | ||
274 | kfree(notes_section); | ||
275 | } | ||
276 | |||
277 | /* Prepare merged PT_NOTE program header. */ | ||
278 | phdr.p_type = PT_NOTE; | ||
279 | phdr.p_flags = 0; | ||
280 | note_off = sizeof(Elf64_Ehdr) + | ||
281 | (ehdr_ptr->e_phnum - nr_ptnote +1) * sizeof(Elf64_Phdr); | ||
282 | phdr.p_offset = note_off; | ||
283 | phdr.p_vaddr = phdr.p_paddr = 0; | ||
284 | phdr.p_filesz = phdr.p_memsz = phdr_sz; | ||
285 | phdr.p_align = 0; | ||
286 | |||
287 | /* Add merged PT_NOTE program header*/ | ||
288 | tmp = elfptr + sizeof(Elf64_Ehdr); | ||
289 | memcpy(tmp, &phdr, sizeof(phdr)); | ||
290 | tmp += sizeof(phdr); | ||
291 | |||
292 | /* Remove unwanted PT_NOTE program headers. */ | ||
293 | i = (nr_ptnote - 1) * sizeof(Elf64_Phdr); | ||
294 | *elfsz = *elfsz - i; | ||
295 | memmove(tmp, tmp+i, ((*elfsz)-sizeof(Elf64_Ehdr)-sizeof(Elf64_Phdr))); | ||
296 | |||
297 | /* Modify e_phnum to reflect merged headers. */ | ||
298 | ehdr_ptr->e_phnum = ehdr_ptr->e_phnum - nr_ptnote + 1; | ||
299 | |||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | /* Merges all the PT_NOTE headers into one. */ | ||
304 | static int __init merge_note_headers_elf32(char *elfptr, size_t *elfsz, | ||
305 | struct list_head *vc_list) | ||
306 | { | ||
307 | int i, nr_ptnote=0, rc=0; | ||
308 | char *tmp; | ||
309 | Elf32_Ehdr *ehdr_ptr; | ||
310 | Elf32_Phdr phdr, *phdr_ptr; | ||
311 | Elf32_Nhdr *nhdr_ptr; | ||
312 | u64 phdr_sz = 0, note_off; | ||
313 | |||
314 | ehdr_ptr = (Elf32_Ehdr *)elfptr; | ||
315 | phdr_ptr = (Elf32_Phdr*)(elfptr + sizeof(Elf32_Ehdr)); | ||
316 | for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) { | ||
317 | int j; | ||
318 | void *notes_section; | ||
319 | struct vmcore *new; | ||
320 | u64 offset, max_sz, sz, real_sz = 0; | ||
321 | if (phdr_ptr->p_type != PT_NOTE) | ||
322 | continue; | ||
323 | nr_ptnote++; | ||
324 | max_sz = phdr_ptr->p_memsz; | ||
325 | offset = phdr_ptr->p_offset; | ||
326 | notes_section = kmalloc(max_sz, GFP_KERNEL); | ||
327 | if (!notes_section) | ||
328 | return -ENOMEM; | ||
329 | rc = read_from_oldmem(notes_section, max_sz, &offset, 0); | ||
330 | if (rc < 0) { | ||
331 | kfree(notes_section); | ||
332 | return rc; | ||
333 | } | ||
334 | nhdr_ptr = notes_section; | ||
335 | for (j = 0; j < max_sz; j += sz) { | ||
336 | if (nhdr_ptr->n_namesz == 0) | ||
337 | break; | ||
338 | sz = sizeof(Elf32_Nhdr) + | ||
339 | ((nhdr_ptr->n_namesz + 3) & ~3) + | ||
340 | ((nhdr_ptr->n_descsz + 3) & ~3); | ||
341 | real_sz += sz; | ||
342 | nhdr_ptr = (Elf32_Nhdr*)((char*)nhdr_ptr + sz); | ||
343 | } | ||
344 | |||
345 | /* Add this contiguous chunk of notes section to vmcore list.*/ | ||
346 | new = get_new_element(); | ||
347 | if (!new) { | ||
348 | kfree(notes_section); | ||
349 | return -ENOMEM; | ||
350 | } | ||
351 | new->paddr = phdr_ptr->p_offset; | ||
352 | new->size = real_sz; | ||
353 | list_add_tail(&new->list, vc_list); | ||
354 | phdr_sz += real_sz; | ||
355 | kfree(notes_section); | ||
356 | } | ||
357 | |||
358 | /* Prepare merged PT_NOTE program header. */ | ||
359 | phdr.p_type = PT_NOTE; | ||
360 | phdr.p_flags = 0; | ||
361 | note_off = sizeof(Elf32_Ehdr) + | ||
362 | (ehdr_ptr->e_phnum - nr_ptnote +1) * sizeof(Elf32_Phdr); | ||
363 | phdr.p_offset = note_off; | ||
364 | phdr.p_vaddr = phdr.p_paddr = 0; | ||
365 | phdr.p_filesz = phdr.p_memsz = phdr_sz; | ||
366 | phdr.p_align = 0; | ||
367 | |||
368 | /* Add merged PT_NOTE program header*/ | ||
369 | tmp = elfptr + sizeof(Elf32_Ehdr); | ||
370 | memcpy(tmp, &phdr, sizeof(phdr)); | ||
371 | tmp += sizeof(phdr); | ||
372 | |||
373 | /* Remove unwanted PT_NOTE program headers. */ | ||
374 | i = (nr_ptnote - 1) * sizeof(Elf32_Phdr); | ||
375 | *elfsz = *elfsz - i; | ||
376 | memmove(tmp, tmp+i, ((*elfsz)-sizeof(Elf32_Ehdr)-sizeof(Elf32_Phdr))); | ||
377 | |||
378 | /* Modify e_phnum to reflect merged headers. */ | ||
379 | ehdr_ptr->e_phnum = ehdr_ptr->e_phnum - nr_ptnote + 1; | ||
380 | |||
381 | return 0; | ||
382 | } | ||
383 | |||
384 | /* Add memory chunks represented by program headers to vmcore list. Also update | ||
385 | * the new offset fields of exported program headers. */ | ||
386 | static int __init process_ptload_program_headers_elf64(char *elfptr, | ||
387 | size_t elfsz, | ||
388 | struct list_head *vc_list) | ||
389 | { | ||
390 | int i; | ||
391 | Elf64_Ehdr *ehdr_ptr; | ||
392 | Elf64_Phdr *phdr_ptr; | ||
393 | loff_t vmcore_off; | ||
394 | struct vmcore *new; | ||
395 | |||
396 | ehdr_ptr = (Elf64_Ehdr *)elfptr; | ||
397 | phdr_ptr = (Elf64_Phdr*)(elfptr + sizeof(Elf64_Ehdr)); /* PT_NOTE hdr */ | ||
398 | |||
399 | /* First program header is PT_NOTE header. */ | ||
400 | vmcore_off = sizeof(Elf64_Ehdr) + | ||
401 | (ehdr_ptr->e_phnum) * sizeof(Elf64_Phdr) + | ||
402 | phdr_ptr->p_memsz; /* Note sections */ | ||
403 | |||
404 | for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) { | ||
405 | if (phdr_ptr->p_type != PT_LOAD) | ||
406 | continue; | ||
407 | |||
408 | /* Add this contiguous chunk of memory to vmcore list.*/ | ||
409 | new = get_new_element(); | ||
410 | if (!new) | ||
411 | return -ENOMEM; | ||
412 | new->paddr = phdr_ptr->p_offset; | ||
413 | new->size = phdr_ptr->p_memsz; | ||
414 | list_add_tail(&new->list, vc_list); | ||
415 | |||
416 | /* Update the program header offset. */ | ||
417 | phdr_ptr->p_offset = vmcore_off; | ||
418 | vmcore_off = vmcore_off + phdr_ptr->p_memsz; | ||
419 | } | ||
420 | return 0; | ||
421 | } | ||
422 | |||
423 | static int __init process_ptload_program_headers_elf32(char *elfptr, | ||
424 | size_t elfsz, | ||
425 | struct list_head *vc_list) | ||
426 | { | ||
427 | int i; | ||
428 | Elf32_Ehdr *ehdr_ptr; | ||
429 | Elf32_Phdr *phdr_ptr; | ||
430 | loff_t vmcore_off; | ||
431 | struct vmcore *new; | ||
432 | |||
433 | ehdr_ptr = (Elf32_Ehdr *)elfptr; | ||
434 | phdr_ptr = (Elf32_Phdr*)(elfptr + sizeof(Elf32_Ehdr)); /* PT_NOTE hdr */ | ||
435 | |||
436 | /* First program header is PT_NOTE header. */ | ||
437 | vmcore_off = sizeof(Elf32_Ehdr) + | ||
438 | (ehdr_ptr->e_phnum) * sizeof(Elf32_Phdr) + | ||
439 | phdr_ptr->p_memsz; /* Note sections */ | ||
440 | |||
441 | for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) { | ||
442 | if (phdr_ptr->p_type != PT_LOAD) | ||
443 | continue; | ||
444 | |||
445 | /* Add this contiguous chunk of memory to vmcore list.*/ | ||
446 | new = get_new_element(); | ||
447 | if (!new) | ||
448 | return -ENOMEM; | ||
449 | new->paddr = phdr_ptr->p_offset; | ||
450 | new->size = phdr_ptr->p_memsz; | ||
451 | list_add_tail(&new->list, vc_list); | ||
452 | |||
453 | /* Update the program header offset */ | ||
454 | phdr_ptr->p_offset = vmcore_off; | ||
455 | vmcore_off = vmcore_off + phdr_ptr->p_memsz; | ||
456 | } | ||
457 | return 0; | ||
458 | } | ||
459 | |||
460 | /* Sets offset fields of vmcore elements. */ | ||
461 | static void __init set_vmcore_list_offsets_elf64(char *elfptr, | ||
462 | struct list_head *vc_list) | ||
463 | { | ||
464 | loff_t vmcore_off; | ||
465 | Elf64_Ehdr *ehdr_ptr; | ||
466 | struct vmcore *m; | ||
467 | |||
468 | ehdr_ptr = (Elf64_Ehdr *)elfptr; | ||
469 | |||
470 | /* Skip Elf header and program headers. */ | ||
471 | vmcore_off = sizeof(Elf64_Ehdr) + | ||
472 | (ehdr_ptr->e_phnum) * sizeof(Elf64_Phdr); | ||
473 | |||
474 | list_for_each_entry(m, vc_list, list) { | ||
475 | m->offset = vmcore_off; | ||
476 | vmcore_off += m->size; | ||
477 | } | ||
478 | } | ||
479 | |||
480 | /* Sets offset fields of vmcore elements. */ | ||
481 | static void __init set_vmcore_list_offsets_elf32(char *elfptr, | ||
482 | struct list_head *vc_list) | ||
483 | { | ||
484 | loff_t vmcore_off; | ||
485 | Elf32_Ehdr *ehdr_ptr; | ||
486 | struct vmcore *m; | ||
487 | |||
488 | ehdr_ptr = (Elf32_Ehdr *)elfptr; | ||
489 | |||
490 | /* Skip Elf header and program headers. */ | ||
491 | vmcore_off = sizeof(Elf32_Ehdr) + | ||
492 | (ehdr_ptr->e_phnum) * sizeof(Elf32_Phdr); | ||
493 | |||
494 | list_for_each_entry(m, vc_list, list) { | ||
495 | m->offset = vmcore_off; | ||
496 | vmcore_off += m->size; | ||
497 | } | ||
498 | } | ||
499 | |||
500 | static int __init parse_crash_elf64_headers(void) | ||
501 | { | ||
502 | int rc=0; | ||
503 | Elf64_Ehdr ehdr; | ||
504 | u64 addr; | ||
505 | |||
506 | addr = elfcorehdr_addr; | ||
507 | |||
508 | /* Read Elf header */ | ||
509 | rc = read_from_oldmem((char*)&ehdr, sizeof(Elf64_Ehdr), &addr, 0); | ||
510 | if (rc < 0) | ||
511 | return rc; | ||
512 | |||
513 | /* Do some basic Verification. */ | ||
514 | if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 || | ||
515 | (ehdr.e_type != ET_CORE) || | ||
516 | !elf_check_arch(&ehdr) || | ||
517 | ehdr.e_ident[EI_CLASS] != ELFCLASS64 || | ||
518 | ehdr.e_ident[EI_VERSION] != EV_CURRENT || | ||
519 | ehdr.e_version != EV_CURRENT || | ||
520 | ehdr.e_ehsize != sizeof(Elf64_Ehdr) || | ||
521 | ehdr.e_phentsize != sizeof(Elf64_Phdr) || | ||
522 | ehdr.e_phnum == 0) { | ||
523 | printk(KERN_WARNING "Warning: Core image elf header is not" | ||
524 | "sane\n"); | ||
525 | return -EINVAL; | ||
526 | } | ||
527 | |||
528 | /* Read in all elf headers. */ | ||
529 | elfcorebuf_sz = sizeof(Elf64_Ehdr) + ehdr.e_phnum * sizeof(Elf64_Phdr); | ||
530 | elfcorebuf = kmalloc(elfcorebuf_sz, GFP_KERNEL); | ||
531 | if (!elfcorebuf) | ||
532 | return -ENOMEM; | ||
533 | addr = elfcorehdr_addr; | ||
534 | rc = read_from_oldmem(elfcorebuf, elfcorebuf_sz, &addr, 0); | ||
535 | if (rc < 0) { | ||
536 | kfree(elfcorebuf); | ||
537 | return rc; | ||
538 | } | ||
539 | |||
540 | /* Merge all PT_NOTE headers into one. */ | ||
541 | rc = merge_note_headers_elf64(elfcorebuf, &elfcorebuf_sz, &vmcore_list); | ||
542 | if (rc) { | ||
543 | kfree(elfcorebuf); | ||
544 | return rc; | ||
545 | } | ||
546 | rc = process_ptload_program_headers_elf64(elfcorebuf, elfcorebuf_sz, | ||
547 | &vmcore_list); | ||
548 | if (rc) { | ||
549 | kfree(elfcorebuf); | ||
550 | return rc; | ||
551 | } | ||
552 | set_vmcore_list_offsets_elf64(elfcorebuf, &vmcore_list); | ||
553 | return 0; | ||
554 | } | ||
555 | |||
556 | static int __init parse_crash_elf32_headers(void) | ||
557 | { | ||
558 | int rc=0; | ||
559 | Elf32_Ehdr ehdr; | ||
560 | u64 addr; | ||
561 | |||
562 | addr = elfcorehdr_addr; | ||
563 | |||
564 | /* Read Elf header */ | ||
565 | rc = read_from_oldmem((char*)&ehdr, sizeof(Elf32_Ehdr), &addr, 0); | ||
566 | if (rc < 0) | ||
567 | return rc; | ||
568 | |||
569 | /* Do some basic Verification. */ | ||
570 | if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 || | ||
571 | (ehdr.e_type != ET_CORE) || | ||
572 | !elf_check_arch(&ehdr) || | ||
573 | ehdr.e_ident[EI_CLASS] != ELFCLASS32|| | ||
574 | ehdr.e_ident[EI_VERSION] != EV_CURRENT || | ||
575 | ehdr.e_version != EV_CURRENT || | ||
576 | ehdr.e_ehsize != sizeof(Elf32_Ehdr) || | ||
577 | ehdr.e_phentsize != sizeof(Elf32_Phdr) || | ||
578 | ehdr.e_phnum == 0) { | ||
579 | printk(KERN_WARNING "Warning: Core image elf header is not" | ||
580 | "sane\n"); | ||
581 | return -EINVAL; | ||
582 | } | ||
583 | |||
584 | /* Read in all elf headers. */ | ||
585 | elfcorebuf_sz = sizeof(Elf32_Ehdr) + ehdr.e_phnum * sizeof(Elf32_Phdr); | ||
586 | elfcorebuf = kmalloc(elfcorebuf_sz, GFP_KERNEL); | ||
587 | if (!elfcorebuf) | ||
588 | return -ENOMEM; | ||
589 | addr = elfcorehdr_addr; | ||
590 | rc = read_from_oldmem(elfcorebuf, elfcorebuf_sz, &addr, 0); | ||
591 | if (rc < 0) { | ||
592 | kfree(elfcorebuf); | ||
593 | return rc; | ||
594 | } | ||
595 | |||
596 | /* Merge all PT_NOTE headers into one. */ | ||
597 | rc = merge_note_headers_elf32(elfcorebuf, &elfcorebuf_sz, &vmcore_list); | ||
598 | if (rc) { | ||
599 | kfree(elfcorebuf); | ||
600 | return rc; | ||
601 | } | ||
602 | rc = process_ptload_program_headers_elf32(elfcorebuf, elfcorebuf_sz, | ||
603 | &vmcore_list); | ||
604 | if (rc) { | ||
605 | kfree(elfcorebuf); | ||
606 | return rc; | ||
607 | } | ||
608 | set_vmcore_list_offsets_elf32(elfcorebuf, &vmcore_list); | ||
609 | return 0; | ||
610 | } | ||
611 | |||
612 | static int __init parse_crash_elf_headers(void) | ||
613 | { | ||
614 | unsigned char e_ident[EI_NIDENT]; | ||
615 | u64 addr; | ||
616 | int rc=0; | ||
617 | |||
618 | addr = elfcorehdr_addr; | ||
619 | rc = read_from_oldmem(e_ident, EI_NIDENT, &addr, 0); | ||
620 | if (rc < 0) | ||
621 | return rc; | ||
622 | if (memcmp(e_ident, ELFMAG, SELFMAG) != 0) { | ||
623 | printk(KERN_WARNING "Warning: Core image elf header" | ||
624 | " not found\n"); | ||
625 | return -EINVAL; | ||
626 | } | ||
627 | |||
628 | if (e_ident[EI_CLASS] == ELFCLASS64) { | ||
629 | rc = parse_crash_elf64_headers(); | ||
630 | if (rc) | ||
631 | return rc; | ||
632 | |||
633 | /* Determine vmcore size. */ | ||
634 | vmcore_size = get_vmcore_size_elf64(elfcorebuf); | ||
635 | } else if (e_ident[EI_CLASS] == ELFCLASS32) { | ||
636 | rc = parse_crash_elf32_headers(); | ||
637 | if (rc) | ||
638 | return rc; | ||
639 | |||
640 | /* Determine vmcore size. */ | ||
641 | vmcore_size = get_vmcore_size_elf32(elfcorebuf); | ||
642 | } else { | ||
643 | printk(KERN_WARNING "Warning: Core image elf header is not" | ||
644 | " sane\n"); | ||
645 | return -EINVAL; | ||
646 | } | ||
647 | return 0; | ||
648 | } | ||
649 | |||
650 | /* Init function for vmcore module. */ | ||
651 | static int __init vmcore_init(void) | ||
652 | { | ||
653 | int rc = 0; | ||
654 | |||
655 | /* If elfcorehdr= has been passed in cmdline, then capture the dump.*/ | ||
656 | if (!(elfcorehdr_addr < ELFCORE_ADDR_MAX)) | ||
657 | return rc; | ||
658 | rc = parse_crash_elf_headers(); | ||
659 | if (rc) { | ||
660 | printk(KERN_WARNING "Kdump: vmcore not initialized\n"); | ||
661 | return rc; | ||
662 | } | ||
663 | |||
664 | /* Initialize /proc/vmcore size if proc is already up. */ | ||
665 | if (proc_vmcore) | ||
666 | proc_vmcore->size = vmcore_size; | ||
667 | return 0; | ||
668 | } | ||
669 | module_init(vmcore_init) | ||
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 0d5817f81972..289d864fe731 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -254,6 +254,7 @@ static int _get_block_create_0 (struct inode * inode, long block, | |||
254 | char * p = NULL; | 254 | char * p = NULL; |
255 | int chars; | 255 | int chars; |
256 | int ret ; | 256 | int ret ; |
257 | int result ; | ||
257 | int done = 0 ; | 258 | int done = 0 ; |
258 | unsigned long offset ; | 259 | unsigned long offset ; |
259 | 260 | ||
@@ -262,10 +263,13 @@ static int _get_block_create_0 (struct inode * inode, long block, | |||
262 | (loff_t)block * inode->i_sb->s_blocksize + 1, TYPE_ANY, 3); | 263 | (loff_t)block * inode->i_sb->s_blocksize + 1, TYPE_ANY, 3); |
263 | 264 | ||
264 | research: | 265 | research: |
265 | if (search_for_position_by_key (inode->i_sb, &key, &path) != POSITION_FOUND) { | 266 | result = search_for_position_by_key (inode->i_sb, &key, &path) ; |
267 | if (result != POSITION_FOUND) { | ||
266 | pathrelse (&path); | 268 | pathrelse (&path); |
267 | if (p) | 269 | if (p) |
268 | kunmap(bh_result->b_page) ; | 270 | kunmap(bh_result->b_page) ; |
271 | if (result == IO_ERROR) | ||
272 | return -EIO; | ||
269 | // We do not return -ENOENT if there is a hole but page is uptodate, because it means | 273 | // We do not return -ENOENT if there is a hole but page is uptodate, because it means |
270 | // That there is some MMAPED data associated with it that is yet to be written to disk. | 274 | // That there is some MMAPED data associated with it that is yet to be written to disk. |
271 | if ((args & GET_BLOCK_NO_HOLE) && !PageUptodate(bh_result->b_page) ) { | 275 | if ((args & GET_BLOCK_NO_HOLE) && !PageUptodate(bh_result->b_page) ) { |
@@ -382,8 +386,9 @@ research: | |||
382 | 386 | ||
383 | // update key to look for the next piece | 387 | // update key to look for the next piece |
384 | set_cpu_key_k_offset (&key, cpu_key_k_offset (&key) + chars); | 388 | set_cpu_key_k_offset (&key, cpu_key_k_offset (&key) + chars); |
385 | if (search_for_position_by_key (inode->i_sb, &key, &path) != POSITION_FOUND) | 389 | result = search_for_position_by_key (inode->i_sb, &key, &path); |
386 | // we read something from tail, even if now we got IO_ERROR | 390 | if (result != POSITION_FOUND) |
391 | // i/o error most likely | ||
387 | break; | 392 | break; |
388 | bh = get_last_bh (&path); | 393 | bh = get_last_bh (&path); |
389 | ih = get_ih (&path); | 394 | ih = get_ih (&path); |
@@ -394,6 +399,10 @@ research: | |||
394 | 399 | ||
395 | finished: | 400 | finished: |
396 | pathrelse (&path); | 401 | pathrelse (&path); |
402 | |||
403 | if (result == IO_ERROR) | ||
404 | return -EIO; | ||
405 | |||
397 | /* this buffer has valid data, but isn't valid for io. mapping it to | 406 | /* this buffer has valid data, but isn't valid for io. mapping it to |
398 | * block #0 tells the rest of reiserfs it just has a tail in it | 407 | * block #0 tells the rest of reiserfs it just has a tail in it |
399 | */ | 408 | */ |
diff --git a/include/asm-arm/arch-ixp2000/io.h b/include/asm-arm/arch-ixp2000/io.h index 5e56b47446e0..3241cd6f0778 100644 --- a/include/asm-arm/arch-ixp2000/io.h +++ b/include/asm-arm/arch-ixp2000/io.h | |||
@@ -17,16 +17,21 @@ | |||
17 | 17 | ||
18 | #define IO_SPACE_LIMIT 0xffffffff | 18 | #define IO_SPACE_LIMIT 0xffffffff |
19 | #define __mem_pci(a) (a) | 19 | #define __mem_pci(a) (a) |
20 | #define ___io(p) ((void __iomem *)((p)+IXP2000_PCI_IO_VIRT_BASE)) | ||
21 | 20 | ||
22 | /* | 21 | /* |
23 | * The IXP2400 before revision B0 asserts byte lanes for PCI I/O | 22 | * The A? revisions of the IXP2000s assert byte lanes for PCI I/O |
24 | * transactions the other way round (MEM transactions don't have this | 23 | * transactions the other way round (MEM transactions don't have this |
25 | * issue), so we need to override the standard functions. B0 and later | 24 | * issue), so if we want to support those models, we need to override |
26 | * have a bit that can be set to 1 to get the 'proper' behavior, but | 25 | * the standard I/O functions. |
27 | * since that isn't available on the A? revisions we just keep doing | 26 | * |
28 | * things manually. | 27 | * B0 and later have a bit that can be set to 1 to get the proper |
28 | * behavior for I/O transactions, which then allows us to use the | ||
29 | * standard I/O functions. This is what we do if the user does not | ||
30 | * explicitly ask for support for pre-B0. | ||
29 | */ | 31 | */ |
32 | #ifdef CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO | ||
33 | #define ___io(p) ((void __iomem *)((p)+IXP2000_PCI_IO_VIRT_BASE)) | ||
34 | |||
30 | #define alignb(addr) (void __iomem *)((unsigned long)(addr) ^ 3) | 35 | #define alignb(addr) (void __iomem *)((unsigned long)(addr) ^ 3) |
31 | #define alignw(addr) (void __iomem *)((unsigned long)(addr) ^ 2) | 36 | #define alignw(addr) (void __iomem *)((unsigned long)(addr) ^ 2) |
32 | 37 | ||
@@ -119,6 +124,9 @@ | |||
119 | #define ioport_map(port, nr) ___io(port) | 124 | #define ioport_map(port, nr) ___io(port) |
120 | 125 | ||
121 | #define ioport_unmap(addr) | 126 | #define ioport_unmap(addr) |
127 | #else | ||
128 | #define __io(p) ((void __iomem *)((p)+IXP2000_PCI_IO_VIRT_BASE)) | ||
129 | #endif | ||
122 | 130 | ||
123 | 131 | ||
124 | #ifdef CONFIG_ARCH_IXDP2X01 | 132 | #ifdef CONFIG_ARCH_IXDP2X01 |
diff --git a/include/asm-arm/arch-ixp2000/ixp2000-regs.h b/include/asm-arm/arch-ixp2000/ixp2000-regs.h index a1d9e181b10f..5eb47d4bfbf6 100644 --- a/include/asm-arm/arch-ixp2000/ixp2000-regs.h +++ b/include/asm-arm/arch-ixp2000/ixp2000-regs.h | |||
@@ -241,7 +241,7 @@ | |||
241 | #define PCI_CONTROL_BE_DEI (1 << 21) /* Big Endian Data Enable In */ | 241 | #define PCI_CONTROL_BE_DEI (1 << 21) /* Big Endian Data Enable In */ |
242 | #define PCI_CONTROL_BE_BEO (1 << 20) /* Big Endian Byte Enable Out */ | 242 | #define PCI_CONTROL_BE_BEO (1 << 20) /* Big Endian Byte Enable Out */ |
243 | #define PCI_CONTROL_BE_BEI (1 << 19) /* Big Endian Byte Enable In */ | 243 | #define PCI_CONTROL_BE_BEI (1 << 19) /* Big Endian Byte Enable In */ |
244 | #define PCI_CONTROL_PNR (1 << 17) /* PCI Not Reset bit */ | 244 | #define PCI_CONTROL_IEE (1 << 17) /* I/O cycle Endian swap Enable */ |
245 | 245 | ||
246 | #define IXP2000_PCI_RST_REL (1 << 2) | 246 | #define IXP2000_PCI_RST_REL (1 << 2) |
247 | #define CFG_RST_DIR (*IXP2000_PCI_CONTROL & IXP2000_PCICNTL_PCF) | 247 | #define CFG_RST_DIR (*IXP2000_PCI_CONTROL & IXP2000_PCICNTL_PCF) |
diff --git a/include/asm-arm/mach/time.h b/include/asm-arm/mach/time.h index 5cf4fd659fd5..047980ad18d1 100644 --- a/include/asm-arm/mach/time.h +++ b/include/asm-arm/mach/time.h | |||
@@ -39,8 +39,29 @@ struct sys_timer { | |||
39 | void (*suspend)(void); | 39 | void (*suspend)(void); |
40 | void (*resume)(void); | 40 | void (*resume)(void); |
41 | unsigned long (*offset)(void); | 41 | unsigned long (*offset)(void); |
42 | |||
43 | #ifdef CONFIG_NO_IDLE_HZ | ||
44 | struct dyn_tick_timer *dyn_tick; | ||
45 | #endif | ||
46 | }; | ||
47 | |||
48 | #ifdef CONFIG_NO_IDLE_HZ | ||
49 | |||
50 | #define DYN_TICK_SKIPPING (1 << 2) | ||
51 | #define DYN_TICK_ENABLED (1 << 1) | ||
52 | #define DYN_TICK_SUITABLE (1 << 0) | ||
53 | |||
54 | struct dyn_tick_timer { | ||
55 | unsigned int state; /* Current state */ | ||
56 | int (*enable)(void); /* Enables dynamic tick */ | ||
57 | int (*disable)(void); /* Disables dynamic tick */ | ||
58 | void (*reprogram)(unsigned long); /* Reprograms the timer */ | ||
59 | int (*handler)(int, void *, struct pt_regs *); | ||
42 | }; | 60 | }; |
43 | 61 | ||
62 | void timer_dyn_reprogram(void); | ||
63 | #endif | ||
64 | |||
44 | extern struct sys_timer *system_timer; | 65 | extern struct sys_timer *system_timer; |
45 | extern void timer_tick(struct pt_regs *); | 66 | extern void timer_tick(struct pt_regs *); |
46 | 67 | ||
diff --git a/include/asm-arm/signal.h b/include/asm-arm/signal.h index 46e69ae395af..760f6e65af05 100644 --- a/include/asm-arm/signal.h +++ b/include/asm-arm/signal.h | |||
@@ -114,6 +114,7 @@ typedef unsigned long sigset_t; | |||
114 | #define SIGSTKSZ 8192 | 114 | #define SIGSTKSZ 8192 |
115 | 115 | ||
116 | #ifdef __KERNEL__ | 116 | #ifdef __KERNEL__ |
117 | #define SA_TIMER 0x40000000 | ||
117 | #define SA_IRQNOMASK 0x08000000 | 118 | #define SA_IRQNOMASK 0x08000000 |
118 | #endif | 119 | #endif |
119 | 120 | ||
diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h index 39dd7008013c..3d0d2860b6db 100644 --- a/include/asm-arm/system.h +++ b/include/asm-arm/system.h | |||
@@ -145,34 +145,12 @@ extern unsigned int user_debug; | |||
145 | #define set_wmb(var, value) do { var = value; wmb(); } while (0) | 145 | #define set_wmb(var, value) do { var = value; wmb(); } while (0) |
146 | #define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t"); | 146 | #define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t"); |
147 | 147 | ||
148 | #ifdef CONFIG_SMP | ||
149 | /* | 148 | /* |
150 | * Define our own context switch locking. This allows us to enable | 149 | * switch_mm() may do a full cache flush over the context switch, |
151 | * interrupts over the context switch, otherwise we end up with high | 150 | * so enable interrupts over the context switch to avoid high |
152 | * interrupt latency. The real problem area is switch_mm() which may | 151 | * latency. |
153 | * do a full cache flush. | ||
154 | */ | 152 | */ |
155 | #define prepare_arch_switch(rq,next) \ | 153 | #define __ARCH_WANT_INTERRUPTS_ON_CTXSW |
156 | do { \ | ||
157 | spin_lock(&(next)->switch_lock); \ | ||
158 | spin_unlock_irq(&(rq)->lock); \ | ||
159 | } while (0) | ||
160 | |||
161 | #define finish_arch_switch(rq,prev) \ | ||
162 | spin_unlock(&(prev)->switch_lock) | ||
163 | |||
164 | #define task_running(rq,p) \ | ||
165 | ((rq)->curr == (p) || spin_is_locked(&(p)->switch_lock)) | ||
166 | #else | ||
167 | /* | ||
168 | * Our UP-case is more simple, but we assume knowledge of how | ||
169 | * spin_unlock_irq() and friends are implemented. This avoids | ||
170 | * us needlessly decrementing and incrementing the preempt count. | ||
171 | */ | ||
172 | #define prepare_arch_switch(rq,next) local_irq_enable() | ||
173 | #define finish_arch_switch(rq,prev) spin_unlock(&(rq)->lock) | ||
174 | #define task_running(rq,p) ((rq)->curr == (p)) | ||
175 | #endif | ||
176 | 154 | ||
177 | /* | 155 | /* |
178 | * switch_to(prev, next) should switch from task `prev' to `next' | 156 | * switch_to(prev, next) should switch from task `prev' to `next' |
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 99cef06a364a..b3bb326ae5b6 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h | |||
@@ -73,7 +73,7 @@ | |||
73 | } | 73 | } |
74 | 74 | ||
75 | #define SECURITY_INIT \ | 75 | #define SECURITY_INIT \ |
76 | .security_initcall.init : { \ | 76 | .security_initcall.init : AT(ADDR(.security_initcall.init) - LOAD_OFFSET) { \ |
77 | VMLINUX_SYMBOL(__security_initcall_start) = .; \ | 77 | VMLINUX_SYMBOL(__security_initcall_start) = .; \ |
78 | *(.security_initcall.init) \ | 78 | *(.security_initcall.init) \ |
79 | VMLINUX_SYMBOL(__security_initcall_end) = .; \ | 79 | VMLINUX_SYMBOL(__security_initcall_end) = .; \ |
diff --git a/include/asm-i386/apic.h b/include/asm-i386/apic.h index a5810cf7b578..6a1b1882285c 100644 --- a/include/asm-i386/apic.h +++ b/include/asm-i386/apic.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/pm.h> | 5 | #include <linux/pm.h> |
6 | #include <asm/fixmap.h> | 6 | #include <asm/fixmap.h> |
7 | #include <asm/apicdef.h> | 7 | #include <asm/apicdef.h> |
8 | #include <asm/processor.h> | ||
8 | #include <asm/system.h> | 9 | #include <asm/system.h> |
9 | 10 | ||
10 | #define Dprintk(x...) | 11 | #define Dprintk(x...) |
@@ -16,8 +17,20 @@ | |||
16 | #define APIC_VERBOSE 1 | 17 | #define APIC_VERBOSE 1 |
17 | #define APIC_DEBUG 2 | 18 | #define APIC_DEBUG 2 |
18 | 19 | ||
20 | extern int enable_local_apic; | ||
19 | extern int apic_verbosity; | 21 | extern int apic_verbosity; |
20 | 22 | ||
23 | static inline void lapic_disable(void) | ||
24 | { | ||
25 | enable_local_apic = -1; | ||
26 | clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); | ||
27 | } | ||
28 | |||
29 | static inline void lapic_enable(void) | ||
30 | { | ||
31 | enable_local_apic = 1; | ||
32 | } | ||
33 | |||
21 | /* | 34 | /* |
22 | * Define the default level of output to be very little | 35 | * Define the default level of output to be very little |
23 | * This can be turned up by using apic=verbose for more | 36 | * This can be turned up by using apic=verbose for more |
@@ -87,7 +100,7 @@ extern void (*wait_timer_tick)(void); | |||
87 | extern int get_maxlvt(void); | 100 | extern int get_maxlvt(void); |
88 | extern void clear_local_APIC(void); | 101 | extern void clear_local_APIC(void); |
89 | extern void connect_bsp_APIC (void); | 102 | extern void connect_bsp_APIC (void); |
90 | extern void disconnect_bsp_APIC (void); | 103 | extern void disconnect_bsp_APIC (int virt_wire_setup); |
91 | extern void disable_local_APIC (void); | 104 | extern void disable_local_APIC (void); |
92 | extern void lapic_shutdown (void); | 105 | extern void lapic_shutdown (void); |
93 | extern int verify_local_APIC (void); | 106 | extern int verify_local_APIC (void); |
diff --git a/include/asm-i386/apicdef.h b/include/asm-i386/apicdef.h index c689554ad5b9..0fed5e3c699c 100644 --- a/include/asm-i386/apicdef.h +++ b/include/asm-i386/apicdef.h | |||
@@ -86,11 +86,12 @@ | |||
86 | #define APIC_LVT_REMOTE_IRR (1<<14) | 86 | #define APIC_LVT_REMOTE_IRR (1<<14) |
87 | #define APIC_INPUT_POLARITY (1<<13) | 87 | #define APIC_INPUT_POLARITY (1<<13) |
88 | #define APIC_SEND_PENDING (1<<12) | 88 | #define APIC_SEND_PENDING (1<<12) |
89 | #define APIC_MODE_MASK 0x700 | ||
89 | #define GET_APIC_DELIVERY_MODE(x) (((x)>>8)&0x7) | 90 | #define GET_APIC_DELIVERY_MODE(x) (((x)>>8)&0x7) |
90 | #define SET_APIC_DELIVERY_MODE(x,y) (((x)&~0x700)|((y)<<8)) | 91 | #define SET_APIC_DELIVERY_MODE(x,y) (((x)&~0x700)|((y)<<8)) |
91 | #define APIC_MODE_FIXED 0x0 | 92 | #define APIC_MODE_FIXED 0x0 |
92 | #define APIC_MODE_NMI 0x4 | 93 | #define APIC_MODE_NMI 0x4 |
93 | #define APIC_MODE_EXINT 0x7 | 94 | #define APIC_MODE_EXTINT 0x7 |
94 | #define APIC_LVT1 0x360 | 95 | #define APIC_LVT1 0x360 |
95 | #define APIC_LVTERR 0x370 | 96 | #define APIC_LVTERR 0x370 |
96 | #define APIC_TMICT 0x380 | 97 | #define APIC_TMICT 0x380 |
diff --git a/include/asm-i386/cpu.h b/include/asm-i386/cpu.h index 002740b21951..e7252c216ca8 100644 --- a/include/asm-i386/cpu.h +++ b/include/asm-i386/cpu.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/cpu.h> | 5 | #include <linux/cpu.h> |
6 | #include <linux/topology.h> | 6 | #include <linux/topology.h> |
7 | #include <linux/nodemask.h> | 7 | #include <linux/nodemask.h> |
8 | #include <linux/percpu.h> | ||
8 | 9 | ||
9 | #include <asm/node.h> | 10 | #include <asm/node.h> |
10 | 11 | ||
@@ -16,4 +17,5 @@ extern int arch_register_cpu(int num); | |||
16 | extern void arch_unregister_cpu(int); | 17 | extern void arch_unregister_cpu(int); |
17 | #endif | 18 | #endif |
18 | 19 | ||
20 | DECLARE_PER_CPU(int, cpu_state); | ||
19 | #endif /* _ASM_I386_CPU_H_ */ | 21 | #endif /* _ASM_I386_CPU_H_ */ |
diff --git a/include/asm-i386/highmem.h b/include/asm-i386/highmem.h index 1df42bf347df..0fd331306b60 100644 --- a/include/asm-i386/highmem.h +++ b/include/asm-i386/highmem.h | |||
@@ -70,6 +70,7 @@ void *kmap(struct page *page); | |||
70 | void kunmap(struct page *page); | 70 | void kunmap(struct page *page); |
71 | void *kmap_atomic(struct page *page, enum km_type type); | 71 | void *kmap_atomic(struct page *page, enum km_type type); |
72 | void kunmap_atomic(void *kvaddr, enum km_type type); | 72 | void kunmap_atomic(void *kvaddr, enum km_type type); |
73 | void *kmap_atomic_pfn(unsigned long pfn, enum km_type type); | ||
73 | struct page *kmap_atomic_to_page(void *ptr); | 74 | struct page *kmap_atomic_to_page(void *ptr); |
74 | 75 | ||
75 | #define flush_cache_kmaps() do { } while (0) | 76 | #define flush_cache_kmaps() do { } while (0) |
diff --git a/include/asm-i386/irq.h b/include/asm-i386/irq.h index 05b9e61b0a72..270f1986b19f 100644 --- a/include/asm-i386/irq.h +++ b/include/asm-i386/irq.h | |||
@@ -29,13 +29,19 @@ extern void release_vm86_irqs(struct task_struct *); | |||
29 | 29 | ||
30 | #ifdef CONFIG_4KSTACKS | 30 | #ifdef CONFIG_4KSTACKS |
31 | extern void irq_ctx_init(int cpu); | 31 | extern void irq_ctx_init(int cpu); |
32 | extern void irq_ctx_exit(int cpu); | ||
32 | # define __ARCH_HAS_DO_SOFTIRQ | 33 | # define __ARCH_HAS_DO_SOFTIRQ |
33 | #else | 34 | #else |
34 | # define irq_ctx_init(cpu) do { } while (0) | 35 | # define irq_ctx_init(cpu) do { } while (0) |
36 | # define irq_ctx_exit(cpu) do { } while (0) | ||
35 | #endif | 37 | #endif |
36 | 38 | ||
37 | #ifdef CONFIG_IRQBALANCE | 39 | #ifdef CONFIG_IRQBALANCE |
38 | extern int irqbalance_disable(char *str); | 40 | extern int irqbalance_disable(char *str); |
39 | #endif | 41 | #endif |
40 | 42 | ||
43 | #ifdef CONFIG_HOTPLUG_CPU | ||
44 | extern void fixup_irqs(cpumask_t map); | ||
45 | #endif | ||
46 | |||
41 | #endif /* _ASM_IRQ_H */ | 47 | #endif /* _ASM_IRQ_H */ |
diff --git a/include/asm-i386/kdebug.h b/include/asm-i386/kdebug.h index de6498b0d493..b3f8d5f59d5d 100644 --- a/include/asm-i386/kdebug.h +++ b/include/asm-i386/kdebug.h | |||
@@ -18,7 +18,7 @@ struct die_args { | |||
18 | }; | 18 | }; |
19 | 19 | ||
20 | /* Note - you should never unregister because that can race with NMIs. | 20 | /* Note - you should never unregister because that can race with NMIs. |
21 | If you really want to do it first unregister - then synchronize_kernel - then free. | 21 | If you really want to do it first unregister - then synchronize_sched - then free. |
22 | */ | 22 | */ |
23 | int register_die_notifier(struct notifier_block *nb); | 23 | int register_die_notifier(struct notifier_block *nb); |
24 | extern struct notifier_block *i386die_chain; | 24 | extern struct notifier_block *i386die_chain; |
diff --git a/include/asm-i386/kexec.h b/include/asm-i386/kexec.h new file mode 100644 index 000000000000..6ed2a03e37b3 --- /dev/null +++ b/include/asm-i386/kexec.h | |||
@@ -0,0 +1,33 @@ | |||
1 | #ifndef _I386_KEXEC_H | ||
2 | #define _I386_KEXEC_H | ||
3 | |||
4 | #include <asm/fixmap.h> | ||
5 | |||
6 | /* | ||
7 | * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return. | ||
8 | * I.e. Maximum page that is mapped directly into kernel memory, | ||
9 | * and kmap is not required. | ||
10 | * | ||
11 | * Someone correct me if FIXADDR_START - PAGEOFFSET is not the correct | ||
12 | * calculation for the amount of memory directly mappable into the | ||
13 | * kernel memory space. | ||
14 | */ | ||
15 | |||
16 | /* Maximum physical address we can use pages from */ | ||
17 | #define KEXEC_SOURCE_MEMORY_LIMIT (-1UL) | ||
18 | /* Maximum address we can reach in physical address mode */ | ||
19 | #define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL) | ||
20 | /* Maximum address we can use for the control code buffer */ | ||
21 | #define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE | ||
22 | |||
23 | #define KEXEC_CONTROL_CODE_SIZE 4096 | ||
24 | |||
25 | /* The native architecture */ | ||
26 | #define KEXEC_ARCH KEXEC_ARCH_386 | ||
27 | |||
28 | #define MAX_NOTE_BYTES 1024 | ||
29 | typedef u32 note_buf_t[MAX_NOTE_BYTES/4]; | ||
30 | |||
31 | extern note_buf_t crash_notes[]; | ||
32 | |||
33 | #endif /* _I386_KEXEC_H */ | ||
diff --git a/include/asm-i386/mach-default/mach_ipi.h b/include/asm-i386/mach-default/mach_ipi.h index 6f2b17a20089..cc756a67cd63 100644 --- a/include/asm-i386/mach-default/mach_ipi.h +++ b/include/asm-i386/mach-default/mach_ipi.h | |||
@@ -4,11 +4,34 @@ | |||
4 | void send_IPI_mask_bitmask(cpumask_t mask, int vector); | 4 | void send_IPI_mask_bitmask(cpumask_t mask, int vector); |
5 | void __send_IPI_shortcut(unsigned int shortcut, int vector); | 5 | void __send_IPI_shortcut(unsigned int shortcut, int vector); |
6 | 6 | ||
7 | extern int no_broadcast; | ||
8 | |||
7 | static inline void send_IPI_mask(cpumask_t mask, int vector) | 9 | static inline void send_IPI_mask(cpumask_t mask, int vector) |
8 | { | 10 | { |
9 | send_IPI_mask_bitmask(mask, vector); | 11 | send_IPI_mask_bitmask(mask, vector); |
10 | } | 12 | } |
11 | 13 | ||
14 | static inline void __local_send_IPI_allbutself(int vector) | ||
15 | { | ||
16 | if (no_broadcast) { | ||
17 | cpumask_t mask = cpu_online_map; | ||
18 | int this_cpu = get_cpu(); | ||
19 | |||
20 | cpu_clear(this_cpu, mask); | ||
21 | send_IPI_mask(mask, vector); | ||
22 | put_cpu(); | ||
23 | } else | ||
24 | __send_IPI_shortcut(APIC_DEST_ALLBUT, vector); | ||
25 | } | ||
26 | |||
27 | static inline void __local_send_IPI_all(int vector) | ||
28 | { | ||
29 | if (no_broadcast) | ||
30 | send_IPI_mask(cpu_online_map, vector); | ||
31 | else | ||
32 | __send_IPI_shortcut(APIC_DEST_ALLINC, vector); | ||
33 | } | ||
34 | |||
12 | static inline void send_IPI_allbutself(int vector) | 35 | static inline void send_IPI_allbutself(int vector) |
13 | { | 36 | { |
14 | /* | 37 | /* |
@@ -18,13 +41,13 @@ static inline void send_IPI_allbutself(int vector) | |||
18 | if (!(num_online_cpus() > 1)) | 41 | if (!(num_online_cpus() > 1)) |
19 | return; | 42 | return; |
20 | 43 | ||
21 | __send_IPI_shortcut(APIC_DEST_ALLBUT, vector); | 44 | __local_send_IPI_allbutself(vector); |
22 | return; | 45 | return; |
23 | } | 46 | } |
24 | 47 | ||
25 | static inline void send_IPI_all(int vector) | 48 | static inline void send_IPI_all(int vector) |
26 | { | 49 | { |
27 | __send_IPI_shortcut(APIC_DEST_ALLINC, vector); | 50 | __local_send_IPI_all(vector); |
28 | } | 51 | } |
29 | 52 | ||
30 | #endif /* __ASM_MACH_IPI_H */ | 53 | #endif /* __ASM_MACH_IPI_H */ |
diff --git a/include/asm-i386/page.h b/include/asm-i386/page.h index dea8f8e6d86e..8d93f732d72d 100644 --- a/include/asm-i386/page.h +++ b/include/asm-i386/page.h | |||
@@ -126,9 +126,12 @@ extern int page_is_ram(unsigned long pagenr); | |||
126 | 126 | ||
127 | #ifdef __ASSEMBLY__ | 127 | #ifdef __ASSEMBLY__ |
128 | #define __PAGE_OFFSET (0xC0000000) | 128 | #define __PAGE_OFFSET (0xC0000000) |
129 | #define __PHYSICAL_START CONFIG_PHYSICAL_START | ||
129 | #else | 130 | #else |
130 | #define __PAGE_OFFSET (0xC0000000UL) | 131 | #define __PAGE_OFFSET (0xC0000000UL) |
132 | #define __PHYSICAL_START ((unsigned long)CONFIG_PHYSICAL_START) | ||
131 | #endif | 133 | #endif |
134 | #define __KERNEL_START (__PAGE_OFFSET + __PHYSICAL_START) | ||
132 | 135 | ||
133 | 136 | ||
134 | #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET) | 137 | #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET) |
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index c76c50e96225..6f0f93d0d417 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h | |||
@@ -691,5 +691,7 @@ extern void select_idle_routine(const struct cpuinfo_x86 *c); | |||
691 | #define cache_line_size() (boot_cpu_data.x86_cache_alignment) | 691 | #define cache_line_size() (boot_cpu_data.x86_cache_alignment) |
692 | 692 | ||
693 | extern unsigned long boot_option_idle_override; | 693 | extern unsigned long boot_option_idle_override; |
694 | extern void enable_sep_cpu(void); | ||
695 | extern int sysenter_setup(void); | ||
694 | 696 | ||
695 | #endif /* __ASM_I386_PROCESSOR_H */ | 697 | #endif /* __ASM_I386_PROCESSOR_H */ |
diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h index 55ef31f66bbe..edad9b4712fa 100644 --- a/include/asm-i386/smp.h +++ b/include/asm-i386/smp.h | |||
@@ -42,10 +42,17 @@ extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs); | |||
42 | extern void smp_invalidate_rcv(void); /* Process an NMI */ | 42 | extern void smp_invalidate_rcv(void); /* Process an NMI */ |
43 | extern void (*mtrr_hook) (void); | 43 | extern void (*mtrr_hook) (void); |
44 | extern void zap_low_mappings (void); | 44 | extern void zap_low_mappings (void); |
45 | extern void lock_ipi_call_lock(void); | ||
46 | extern void unlock_ipi_call_lock(void); | ||
45 | 47 | ||
46 | #define MAX_APICID 256 | 48 | #define MAX_APICID 256 |
47 | extern u8 x86_cpu_to_apicid[]; | 49 | extern u8 x86_cpu_to_apicid[]; |
48 | 50 | ||
51 | #ifdef CONFIG_HOTPLUG_CPU | ||
52 | extern void cpu_exit_clear(void); | ||
53 | extern void cpu_uninit(void); | ||
54 | #endif | ||
55 | |||
49 | /* | 56 | /* |
50 | * This function is needed by all SMP systems. It must _always_ be valid | 57 | * This function is needed by all SMP systems. It must _always_ be valid |
51 | * from the initial startup. We map APIC_BASE very early in page_setup(), | 58 | * from the initial startup. We map APIC_BASE very early in page_setup(), |
@@ -83,6 +90,9 @@ static __inline int logical_smp_processor_id(void) | |||
83 | } | 90 | } |
84 | 91 | ||
85 | #endif | 92 | #endif |
93 | |||
94 | extern int __cpu_disable(void); | ||
95 | extern void __cpu_die(unsigned int cpu); | ||
86 | #endif /* !__ASSEMBLY__ */ | 96 | #endif /* !__ASSEMBLY__ */ |
87 | 97 | ||
88 | #define NO_PROC_ID 0xFF /* No processor magic marker */ | 98 | #define NO_PROC_ID 0xFF /* No processor magic marker */ |
diff --git a/include/asm-i386/topology.h b/include/asm-i386/topology.h index 6d0f67507b21..2461b731781e 100644 --- a/include/asm-i386/topology.h +++ b/include/asm-i386/topology.h | |||
@@ -74,11 +74,14 @@ static inline int node_to_first_cpu(int node) | |||
74 | .imbalance_pct = 125, \ | 74 | .imbalance_pct = 125, \ |
75 | .cache_hot_time = (10*1000000), \ | 75 | .cache_hot_time = (10*1000000), \ |
76 | .cache_nice_tries = 1, \ | 76 | .cache_nice_tries = 1, \ |
77 | .busy_idx = 3, \ | ||
78 | .idle_idx = 1, \ | ||
79 | .newidle_idx = 2, \ | ||
80 | .wake_idx = 1, \ | ||
77 | .per_cpu_gain = 100, \ | 81 | .per_cpu_gain = 100, \ |
78 | .flags = SD_LOAD_BALANCE \ | 82 | .flags = SD_LOAD_BALANCE \ |
79 | | SD_BALANCE_EXEC \ | 83 | | SD_BALANCE_EXEC \ |
80 | | SD_BALANCE_NEWIDLE \ | 84 | | SD_BALANCE_FORK \ |
81 | | SD_WAKE_IDLE \ | ||
82 | | SD_WAKE_BALANCE, \ | 85 | | SD_WAKE_BALANCE, \ |
83 | .last_balance = jiffies, \ | 86 | .last_balance = jiffies, \ |
84 | .balance_interval = 1, \ | 87 | .balance_interval = 1, \ |
diff --git a/include/asm-ia64/system.h b/include/asm-ia64/system.h index 6f516e76d1f0..cd2cf76b2db1 100644 --- a/include/asm-ia64/system.h +++ b/include/asm-ia64/system.h | |||
@@ -183,8 +183,6 @@ do { \ | |||
183 | 183 | ||
184 | #ifdef __KERNEL__ | 184 | #ifdef __KERNEL__ |
185 | 185 | ||
186 | #define prepare_to_switch() do { } while(0) | ||
187 | |||
188 | #ifdef CONFIG_IA32_SUPPORT | 186 | #ifdef CONFIG_IA32_SUPPORT |
189 | # define IS_IA32_PROCESS(regs) (ia64_psr(regs)->is != 0) | 187 | # define IS_IA32_PROCESS(regs) (ia64_psr(regs)->is != 0) |
190 | #else | 188 | #else |
@@ -274,13 +272,7 @@ extern void ia64_load_extra (struct task_struct *task); | |||
274 | * of that CPU which will not be released, because there we wait for the | 272 | * of that CPU which will not be released, because there we wait for the |
275 | * tasklist_lock to become available. | 273 | * tasklist_lock to become available. |
276 | */ | 274 | */ |
277 | #define prepare_arch_switch(rq, next) \ | 275 | #define __ARCH_WANT_UNLOCKED_CTXSW |
278 | do { \ | ||
279 | spin_lock(&(next)->switch_lock); \ | ||
280 | spin_unlock(&(rq)->lock); \ | ||
281 | } while (0) | ||
282 | #define finish_arch_switch(rq, prev) spin_unlock_irq(&(prev)->switch_lock) | ||
283 | #define task_running(rq, p) ((rq)->curr == (p) || spin_is_locked(&(p)->switch_lock)) | ||
284 | 276 | ||
285 | #define ia64_platform_is(x) (strcmp(x, platform_name) == 0) | 277 | #define ia64_platform_is(x) (strcmp(x, platform_name) == 0) |
286 | 278 | ||
diff --git a/include/asm-ia64/topology.h b/include/asm-ia64/topology.h index 21cf351fd05c..4e64c2a6b369 100644 --- a/include/asm-ia64/topology.h +++ b/include/asm-ia64/topology.h | |||
@@ -42,25 +42,54 @@ | |||
42 | 42 | ||
43 | void build_cpu_to_node_map(void); | 43 | void build_cpu_to_node_map(void); |
44 | 44 | ||
45 | #define SD_CPU_INIT (struct sched_domain) { \ | ||
46 | .span = CPU_MASK_NONE, \ | ||
47 | .parent = NULL, \ | ||
48 | .groups = NULL, \ | ||
49 | .min_interval = 1, \ | ||
50 | .max_interval = 4, \ | ||
51 | .busy_factor = 64, \ | ||
52 | .imbalance_pct = 125, \ | ||
53 | .cache_hot_time = (10*1000000), \ | ||
54 | .per_cpu_gain = 100, \ | ||
55 | .cache_nice_tries = 2, \ | ||
56 | .busy_idx = 2, \ | ||
57 | .idle_idx = 1, \ | ||
58 | .newidle_idx = 2, \ | ||
59 | .wake_idx = 1, \ | ||
60 | .forkexec_idx = 1, \ | ||
61 | .flags = SD_LOAD_BALANCE \ | ||
62 | | SD_BALANCE_NEWIDLE \ | ||
63 | | SD_BALANCE_EXEC \ | ||
64 | | SD_WAKE_AFFINE, \ | ||
65 | .last_balance = jiffies, \ | ||
66 | .balance_interval = 1, \ | ||
67 | .nr_balance_failed = 0, \ | ||
68 | } | ||
69 | |||
45 | /* sched_domains SD_NODE_INIT for IA64 NUMA machines */ | 70 | /* sched_domains SD_NODE_INIT for IA64 NUMA machines */ |
46 | #define SD_NODE_INIT (struct sched_domain) { \ | 71 | #define SD_NODE_INIT (struct sched_domain) { \ |
47 | .span = CPU_MASK_NONE, \ | 72 | .span = CPU_MASK_NONE, \ |
48 | .parent = NULL, \ | 73 | .parent = NULL, \ |
49 | .groups = NULL, \ | 74 | .groups = NULL, \ |
50 | .min_interval = 80, \ | 75 | .min_interval = 8, \ |
51 | .max_interval = 320, \ | 76 | .max_interval = 8*(min(num_online_cpus(), 32)), \ |
52 | .busy_factor = 320, \ | 77 | .busy_factor = 64, \ |
53 | .imbalance_pct = 125, \ | 78 | .imbalance_pct = 125, \ |
54 | .cache_hot_time = (10*1000000), \ | 79 | .cache_hot_time = (10*1000000), \ |
55 | .cache_nice_tries = 1, \ | 80 | .cache_nice_tries = 2, \ |
81 | .busy_idx = 3, \ | ||
82 | .idle_idx = 2, \ | ||
83 | .newidle_idx = 0, /* unused */ \ | ||
84 | .wake_idx = 1, \ | ||
85 | .forkexec_idx = 1, \ | ||
56 | .per_cpu_gain = 100, \ | 86 | .per_cpu_gain = 100, \ |
57 | .flags = SD_LOAD_BALANCE \ | 87 | .flags = SD_LOAD_BALANCE \ |
58 | | SD_BALANCE_EXEC \ | 88 | | SD_BALANCE_EXEC \ |
59 | | SD_BALANCE_NEWIDLE \ | 89 | | SD_BALANCE_FORK \ |
60 | | SD_WAKE_IDLE \ | ||
61 | | SD_WAKE_BALANCE, \ | 90 | | SD_WAKE_BALANCE, \ |
62 | .last_balance = jiffies, \ | 91 | .last_balance = jiffies, \ |
63 | .balance_interval = 1, \ | 92 | .balance_interval = 64, \ |
64 | .nr_balance_failed = 0, \ | 93 | .nr_balance_failed = 0, \ |
65 | } | 94 | } |
66 | 95 | ||
@@ -69,17 +98,21 @@ void build_cpu_to_node_map(void); | |||
69 | .span = CPU_MASK_NONE, \ | 98 | .span = CPU_MASK_NONE, \ |
70 | .parent = NULL, \ | 99 | .parent = NULL, \ |
71 | .groups = NULL, \ | 100 | .groups = NULL, \ |
72 | .min_interval = 80, \ | 101 | .min_interval = 64, \ |
73 | .max_interval = 320, \ | 102 | .max_interval = 64*num_online_cpus(), \ |
74 | .busy_factor = 320, \ | 103 | .busy_factor = 128, \ |
75 | .imbalance_pct = 125, \ | 104 | .imbalance_pct = 133, \ |
76 | .cache_hot_time = (10*1000000), \ | 105 | .cache_hot_time = (10*1000000), \ |
77 | .cache_nice_tries = 1, \ | 106 | .cache_nice_tries = 1, \ |
107 | .busy_idx = 3, \ | ||
108 | .idle_idx = 3, \ | ||
109 | .newidle_idx = 0, /* unused */ \ | ||
110 | .wake_idx = 0, /* unused */ \ | ||
111 | .forkexec_idx = 0, /* unused */ \ | ||
78 | .per_cpu_gain = 100, \ | 112 | .per_cpu_gain = 100, \ |
79 | .flags = SD_LOAD_BALANCE \ | 113 | .flags = SD_LOAD_BALANCE, \ |
80 | | SD_BALANCE_EXEC, \ | ||
81 | .last_balance = jiffies, \ | 114 | .last_balance = jiffies, \ |
82 | .balance_interval = 100*(63+num_online_cpus())/64, \ | 115 | .balance_interval = 64, \ |
83 | .nr_balance_failed = 0, \ | 116 | .nr_balance_failed = 0, \ |
84 | } | 117 | } |
85 | 118 | ||
diff --git a/include/asm-mips/mmzone.h b/include/asm-mips/mmzone.h index 29ee13be0b2a..d721143dbd47 100644 --- a/include/asm-mips/mmzone.h +++ b/include/asm-mips/mmzone.h | |||
@@ -8,6 +8,8 @@ | |||
8 | #include <asm/page.h> | 8 | #include <asm/page.h> |
9 | #include <mmzone.h> | 9 | #include <mmzone.h> |
10 | 10 | ||
11 | #ifdef CONFIG_DISCONTIGMEM | ||
12 | |||
11 | #define kvaddr_to_nid(kvaddr) pa_to_nid(__pa(kvaddr)) | 13 | #define kvaddr_to_nid(kvaddr) pa_to_nid(__pa(kvaddr)) |
12 | #define pfn_to_nid(pfn) pa_to_nid((pfn) << PAGE_SHIFT) | 14 | #define pfn_to_nid(pfn) pa_to_nid((pfn) << PAGE_SHIFT) |
13 | 15 | ||
@@ -36,4 +38,6 @@ | |||
36 | /* XXX: FIXME -- wli */ | 38 | /* XXX: FIXME -- wli */ |
37 | #define kern_addr_valid(addr) (0) | 39 | #define kern_addr_valid(addr) (0) |
38 | 40 | ||
41 | #endif /* CONFIG_DISCONTIGMEM */ | ||
42 | |||
39 | #endif /* _ASM_MMZONE_H_ */ | 43 | #endif /* _ASM_MMZONE_H_ */ |
diff --git a/include/asm-mips/page.h b/include/asm-mips/page.h index d1bf8240e73b..5cae35cd9ba9 100644 --- a/include/asm-mips/page.h +++ b/include/asm-mips/page.h | |||
@@ -127,7 +127,7 @@ static __inline__ int get_order(unsigned long size) | |||
127 | 127 | ||
128 | #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) | 128 | #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) |
129 | 129 | ||
130 | #ifndef CONFIG_DISCONTIGMEM | 130 | #ifndef CONFIG_NEED_MULTIPLE_NODES |
131 | #define pfn_to_page(pfn) (mem_map + (pfn)) | 131 | #define pfn_to_page(pfn) (mem_map + (pfn)) |
132 | #define page_to_pfn(page) ((unsigned long)((page) - mem_map)) | 132 | #define page_to_pfn(page) ((unsigned long)((page) - mem_map)) |
133 | #define pfn_valid(pfn) ((pfn) < max_mapnr) | 133 | #define pfn_valid(pfn) ((pfn) < max_mapnr) |
diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h index 878843203d67..e76ccd6e3a5d 100644 --- a/include/asm-mips/pgtable.h +++ b/include/asm-mips/pgtable.h | |||
@@ -350,7 +350,7 @@ static inline void update_mmu_cache(struct vm_area_struct *vma, | |||
350 | __update_cache(vma, address, pte); | 350 | __update_cache(vma, address, pte); |
351 | } | 351 | } |
352 | 352 | ||
353 | #ifndef CONFIG_DISCONTIGMEM | 353 | #ifndef CONFIG_NEED_MULTIPLE_NODES |
354 | #define kern_addr_valid(addr) (1) | 354 | #define kern_addr_valid(addr) (1) |
355 | #endif | 355 | #endif |
356 | 356 | ||
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h index 888fd8908467..169f3d4265b1 100644 --- a/include/asm-mips/system.h +++ b/include/asm-mips/system.h | |||
@@ -422,16 +422,10 @@ extern void __die_if_kernel(const char *, struct pt_regs *, const char *file, | |||
422 | extern int stop_a_enabled; | 422 | extern int stop_a_enabled; |
423 | 423 | ||
424 | /* | 424 | /* |
425 | * Taken from include/asm-ia64/system.h; prevents deadlock on SMP | 425 | * See include/asm-ia64/system.h; prevents deadlock on SMP |
426 | * systems. | 426 | * systems. |
427 | */ | 427 | */ |
428 | #define prepare_arch_switch(rq, next) \ | 428 | #define __ARCH_WANT_UNLOCKED_CTXSW |
429 | do { \ | ||
430 | spin_lock(&(next)->switch_lock); \ | ||
431 | spin_unlock(&(rq)->lock); \ | ||
432 | } while (0) | ||
433 | #define finish_arch_switch(rq, prev) spin_unlock_irq(&(prev)->switch_lock) | ||
434 | #define task_running(rq, p) ((rq)->curr == (p) || spin_is_locked(&(p)->switch_lock)) | ||
435 | 429 | ||
436 | #define arch_align_stack(x) (x) | 430 | #define arch_align_stack(x) (x) |
437 | 431 | ||
diff --git a/include/asm-ppc/fsl_ocp.h b/include/asm-ppc/fsl_ocp.h deleted file mode 100644 index 050fbba8d049..000000000000 --- a/include/asm-ppc/fsl_ocp.h +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
1 | /* | ||
2 | * include/asm-ppc/fsl_ocp.h | ||
3 | * | ||
4 | * Definitions for the on-chip peripherals on Freescale PPC processors | ||
5 | * | ||
6 | * Maintainer: Kumar Gala (kumar.gala@freescale.com) | ||
7 | * | ||
8 | * Copyright 2004 Freescale Semiconductor, Inc | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | */ | ||
15 | |||
16 | #ifdef __KERNEL__ | ||
17 | #ifndef __ASM_FS_OCP_H__ | ||
18 | #define __ASM_FS_OCP_H__ | ||
19 | |||
20 | /* A table of information for supporting the Gianfar Ethernet Controller | ||
21 | * This helps identify which enet controller we are dealing with, | ||
22 | * and what type of enet controller it is | ||
23 | */ | ||
24 | struct ocp_gfar_data { | ||
25 | uint interruptTransmit; | ||
26 | uint interruptError; | ||
27 | uint interruptReceive; | ||
28 | uint interruptPHY; | ||
29 | uint flags; | ||
30 | uint phyid; | ||
31 | uint phyregidx; | ||
32 | unsigned char mac_addr[6]; | ||
33 | }; | ||
34 | |||
35 | /* Flags in the flags field */ | ||
36 | #define GFAR_HAS_COALESCE 0x20 | ||
37 | #define GFAR_HAS_RMON 0x10 | ||
38 | #define GFAR_HAS_MULTI_INTR 0x08 | ||
39 | #define GFAR_FIRM_SET_MACADDR 0x04 | ||
40 | #define GFAR_HAS_PHY_INTR 0x02 /* if not set use a timer */ | ||
41 | #define GFAR_HAS_GIGABIT 0x01 | ||
42 | |||
43 | /* Data structure for I2C support. Just contains a couple flags | ||
44 | * to distinguish various I2C implementations*/ | ||
45 | struct ocp_fs_i2c_data { | ||
46 | uint flags; | ||
47 | }; | ||
48 | |||
49 | /* Flags for I2C */ | ||
50 | #define FS_I2C_SEPARATE_DFSRR 0x02 | ||
51 | #define FS_I2C_CLOCK_5200 0x01 | ||
52 | |||
53 | #endif /* __ASM_FS_OCP_H__ */ | ||
54 | #endif /* __KERNEL__ */ | ||
diff --git a/include/asm-ppc/kexec.h b/include/asm-ppc/kexec.h new file mode 100644 index 000000000000..73191310d8db --- /dev/null +++ b/include/asm-ppc/kexec.h | |||
@@ -0,0 +1,38 @@ | |||
1 | #ifndef _PPC_KEXEC_H | ||
2 | #define _PPC_KEXEC_H | ||
3 | |||
4 | #ifdef CONFIG_KEXEC | ||
5 | |||
6 | /* | ||
7 | * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return. | ||
8 | * I.e. Maximum page that is mapped directly into kernel memory, | ||
9 | * and kmap is not required. | ||
10 | * | ||
11 | * Someone correct me if FIXADDR_START - PAGEOFFSET is not the correct | ||
12 | * calculation for the amount of memory directly mappable into the | ||
13 | * kernel memory space. | ||
14 | */ | ||
15 | |||
16 | /* Maximum physical address we can use pages from */ | ||
17 | #define KEXEC_SOURCE_MEMORY_LIMIT (-1UL) | ||
18 | /* Maximum address we can reach in physical address mode */ | ||
19 | #define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL) | ||
20 | /* Maximum address we can use for the control code buffer */ | ||
21 | #define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE | ||
22 | |||
23 | #define KEXEC_CONTROL_CODE_SIZE 4096 | ||
24 | |||
25 | /* The native architecture */ | ||
26 | #define KEXEC_ARCH KEXEC_ARCH_PPC | ||
27 | |||
28 | #ifndef __ASSEMBLY__ | ||
29 | |||
30 | struct kimage; | ||
31 | |||
32 | extern void machine_kexec_simple(struct kimage *image); | ||
33 | |||
34 | #endif /* __ASSEMBLY__ */ | ||
35 | |||
36 | #endif /* CONFIG_KEXEC */ | ||
37 | |||
38 | #endif /* _PPC_KEXEC_H */ | ||
diff --git a/include/asm-ppc/machdep.h b/include/asm-ppc/machdep.h index b78d40870c95..1d4ab70a56f3 100644 --- a/include/asm-ppc/machdep.h +++ b/include/asm-ppc/machdep.h | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | #include <linux/config.h> | 5 | #include <linux/config.h> |
6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
7 | #include <linux/kexec.h> | ||
7 | 8 | ||
8 | #include <asm/setup.h> | 9 | #include <asm/setup.h> |
9 | #include <asm/page.h> | 10 | #include <asm/page.h> |
@@ -114,6 +115,36 @@ struct machdep_calls { | |||
114 | /* functions for dealing with other cpus */ | 115 | /* functions for dealing with other cpus */ |
115 | struct smp_ops_t *smp_ops; | 116 | struct smp_ops_t *smp_ops; |
116 | #endif /* CONFIG_SMP */ | 117 | #endif /* CONFIG_SMP */ |
118 | |||
119 | #ifdef CONFIG_KEXEC | ||
120 | /* Called to shutdown machine specific hardware not already controlled | ||
121 | * by other drivers. | ||
122 | * XXX Should we move this one out of kexec scope? | ||
123 | */ | ||
124 | void (*machine_shutdown)(void); | ||
125 | |||
126 | /* Called to do the minimal shutdown needed to run a kexec'd kernel | ||
127 | * to run successfully. | ||
128 | * XXX Should we move this one out of kexec scope? | ||
129 | */ | ||
130 | void (*machine_crash_shutdown)(void); | ||
131 | |||
132 | /* Called to do what every setup is needed on image and the | ||
133 | * reboot code buffer. Returns 0 on success. | ||
134 | * Provide your own (maybe dummy) implementation if your platform | ||
135 | * claims to support kexec. | ||
136 | */ | ||
137 | int (*machine_kexec_prepare)(struct kimage *image); | ||
138 | |||
139 | /* Called to handle any machine specific cleanup on image */ | ||
140 | void (*machine_kexec_cleanup)(struct kimage *image); | ||
141 | |||
142 | /* Called to perform the _real_ kexec. | ||
143 | * Do NOT allocate memory or fail here. We are past the point of | ||
144 | * no return. | ||
145 | */ | ||
146 | void (*machine_kexec)(struct kimage *image); | ||
147 | #endif /* CONFIG_KEXEC */ | ||
117 | }; | 148 | }; |
118 | 149 | ||
119 | extern struct machdep_calls ppc_md; | 150 | extern struct machdep_calls ppc_md; |
diff --git a/include/asm-ppc/mmu.h b/include/asm-ppc/mmu.h index d465aee1c82e..9205db404c7a 100644 --- a/include/asm-ppc/mmu.h +++ b/include/asm-ppc/mmu.h | |||
@@ -405,7 +405,7 @@ typedef struct _P601_BAT { | |||
405 | 405 | ||
406 | #define MAS0_TLBSEL(x) ((x << 28) & 0x30000000) | 406 | #define MAS0_TLBSEL(x) ((x << 28) & 0x30000000) |
407 | #define MAS0_ESEL(x) ((x << 16) & 0x0FFF0000) | 407 | #define MAS0_ESEL(x) ((x << 16) & 0x0FFF0000) |
408 | #define MAS0_NV 0x00000FFF | 408 | #define MAS0_NV(x) ((x) & 0x00000FFF) |
409 | 409 | ||
410 | #define MAS1_VALID 0x80000000 | 410 | #define MAS1_VALID 0x80000000 |
411 | #define MAS1_IPROT 0x40000000 | 411 | #define MAS1_IPROT 0x40000000 |
diff --git a/include/asm-ppc/mmu_context.h b/include/asm-ppc/mmu_context.h index 9222fa6ca172..ccabbce39d85 100644 --- a/include/asm-ppc/mmu_context.h +++ b/include/asm-ppc/mmu_context.h | |||
@@ -63,7 +63,7 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) | |||
63 | #define LAST_CONTEXT 255 | 63 | #define LAST_CONTEXT 255 |
64 | #define FIRST_CONTEXT 1 | 64 | #define FIRST_CONTEXT 1 |
65 | 65 | ||
66 | #elif defined(CONFIG_E500) | 66 | #elif defined(CONFIG_E200) || defined(CONFIG_E500) |
67 | #define NO_CONTEXT 256 | 67 | #define NO_CONTEXT 256 |
68 | #define LAST_CONTEXT 255 | 68 | #define LAST_CONTEXT 255 |
69 | #define FIRST_CONTEXT 1 | 69 | #define FIRST_CONTEXT 1 |
diff --git a/include/asm-ppc/ocp.h b/include/asm-ppc/ocp.h index c726f1845190..983116f59d90 100644 --- a/include/asm-ppc/ocp.h +++ b/include/asm-ppc/ocp.h | |||
@@ -202,10 +202,6 @@ static DEVICE_ATTR(name##_##field, S_IRUGO, show_##name##_##field, NULL); | |||
202 | #include <asm/ibm_ocp.h> | 202 | #include <asm/ibm_ocp.h> |
203 | #endif | 203 | #endif |
204 | 204 | ||
205 | #ifdef CONFIG_FSL_OCP | ||
206 | #include <asm/fsl_ocp.h> | ||
207 | #endif | ||
208 | |||
209 | #endif /* CONFIG_PPC_OCP */ | 205 | #endif /* CONFIG_PPC_OCP */ |
210 | #endif /* __OCP_H__ */ | 206 | #endif /* __OCP_H__ */ |
211 | #endif /* __KERNEL__ */ | 207 | #endif /* __KERNEL__ */ |
diff --git a/include/asm-ppc/ppc_asm.h b/include/asm-ppc/ppc_asm.h index 13fa8e7483c1..f76221def484 100644 --- a/include/asm-ppc/ppc_asm.h +++ b/include/asm-ppc/ppc_asm.h | |||
@@ -174,6 +174,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) | |||
174 | #define CLR_TOP32(r) | 174 | #define CLR_TOP32(r) |
175 | #endif /* CONFIG_PPC64BRIDGE */ | 175 | #endif /* CONFIG_PPC64BRIDGE */ |
176 | 176 | ||
177 | #define RFCI .long 0x4c000066 /* rfci instruction */ | ||
178 | #define RFDI .long 0x4c00004e /* rfdi instruction */ | ||
177 | #define RFMCI .long 0x4c00004c /* rfmci instruction */ | 179 | #define RFMCI .long 0x4c00004c /* rfmci instruction */ |
178 | 180 | ||
179 | #ifdef CONFIG_IBM405_ERR77 | 181 | #ifdef CONFIG_IBM405_ERR77 |
diff --git a/include/asm-ppc/reg.h b/include/asm-ppc/reg.h index c418aab7cd34..88b4222154d4 100644 --- a/include/asm-ppc/reg.h +++ b/include/asm-ppc/reg.h | |||
@@ -160,6 +160,7 @@ | |||
160 | #define HID0_ICFI (1<<11) /* Instr. Cache Flash Invalidate */ | 160 | #define HID0_ICFI (1<<11) /* Instr. Cache Flash Invalidate */ |
161 | #define HID0_DCI (1<<10) /* Data Cache Invalidate */ | 161 | #define HID0_DCI (1<<10) /* Data Cache Invalidate */ |
162 | #define HID0_SPD (1<<9) /* Speculative disable */ | 162 | #define HID0_SPD (1<<9) /* Speculative disable */ |
163 | #define HID0_DAPUEN (1<<8) /* Debug APU enable */ | ||
163 | #define HID0_SGE (1<<7) /* Store Gathering Enable */ | 164 | #define HID0_SGE (1<<7) /* Store Gathering Enable */ |
164 | #define HID0_SIED (1<<7) /* Serial Instr. Execution [Disable] */ | 165 | #define HID0_SIED (1<<7) /* Serial Instr. Execution [Disable] */ |
165 | #define HID0_DFCA (1<<6) /* Data Cache Flush Assist */ | 166 | #define HID0_DFCA (1<<6) /* Data Cache Flush Assist */ |
diff --git a/include/asm-ppc/reg_booke.h b/include/asm-ppc/reg_booke.h index 45c5e6f2b7ab..00ad9c754c78 100644 --- a/include/asm-ppc/reg_booke.h +++ b/include/asm-ppc/reg_booke.h | |||
@@ -165,6 +165,8 @@ do { \ | |||
165 | #define SPRN_MCSRR1 0x23B /* Machine Check Save and Restore Register 1 */ | 165 | #define SPRN_MCSRR1 0x23B /* Machine Check Save and Restore Register 1 */ |
166 | #define SPRN_MCSR 0x23C /* Machine Check Status Register */ | 166 | #define SPRN_MCSR 0x23C /* Machine Check Status Register */ |
167 | #define SPRN_MCAR 0x23D /* Machine Check Address Register */ | 167 | #define SPRN_MCAR 0x23D /* Machine Check Address Register */ |
168 | #define SPRN_DSRR0 0x23E /* Debug Save and Restore Register 0 */ | ||
169 | #define SPRN_DSRR1 0x23F /* Debug Save and Restore Register 1 */ | ||
168 | #define SPRN_MAS0 0x270 /* MMU Assist Register 0 */ | 170 | #define SPRN_MAS0 0x270 /* MMU Assist Register 0 */ |
169 | #define SPRN_MAS1 0x271 /* MMU Assist Register 1 */ | 171 | #define SPRN_MAS1 0x271 /* MMU Assist Register 1 */ |
170 | #define SPRN_MAS2 0x272 /* MMU Assist Register 2 */ | 172 | #define SPRN_MAS2 0x272 /* MMU Assist Register 2 */ |
@@ -264,6 +266,17 @@ do { \ | |||
264 | #define MCSR_BUS_IPERR 0x00000002UL /* Instruction parity Error */ | 266 | #define MCSR_BUS_IPERR 0x00000002UL /* Instruction parity Error */ |
265 | #define MCSR_BUS_RPERR 0x00000001UL /* Read parity Error */ | 267 | #define MCSR_BUS_RPERR 0x00000001UL /* Read parity Error */ |
266 | #endif | 268 | #endif |
269 | #ifdef CONFIG_E200 | ||
270 | #define MCSR_MCP 0x80000000UL /* Machine Check Input Pin */ | ||
271 | #define MCSR_CP_PERR 0x20000000UL /* Cache Push Parity Error */ | ||
272 | #define MCSR_CPERR 0x10000000UL /* Cache Parity Error */ | ||
273 | #define MCSR_EXCP_ERR 0x08000000UL /* ISI, ITLB, or Bus Error on 1st insn | ||
274 | fetch for an exception handler */ | ||
275 | #define MCSR_BUS_IRERR 0x00000010UL /* Read Bus Error on instruction fetch*/ | ||
276 | #define MCSR_BUS_DRERR 0x00000008UL /* Read Bus Error on data load */ | ||
277 | #define MCSR_BUS_WRERR 0x00000004UL /* Write Bus Error on buffered | ||
278 | store or cache line push */ | ||
279 | #endif | ||
267 | 280 | ||
268 | /* Bit definitions for the DBSR. */ | 281 | /* Bit definitions for the DBSR. */ |
269 | /* | 282 | /* |
@@ -311,6 +324,7 @@ do { \ | |||
311 | #define ESR_ST 0x00800000 /* Store Operation */ | 324 | #define ESR_ST 0x00800000 /* Store Operation */ |
312 | #define ESR_DLK 0x00200000 /* Data Cache Locking */ | 325 | #define ESR_DLK 0x00200000 /* Data Cache Locking */ |
313 | #define ESR_ILK 0x00100000 /* Instr. Cache Locking */ | 326 | #define ESR_ILK 0x00100000 /* Instr. Cache Locking */ |
327 | #define ESR_PUO 0x00040000 /* Unimplemented Operation exception */ | ||
314 | #define ESR_BO 0x00020000 /* Byte Ordering */ | 328 | #define ESR_BO 0x00020000 /* Byte Ordering */ |
315 | 329 | ||
316 | /* Bit definitions related to the DBCR0. */ | 330 | /* Bit definitions related to the DBCR0. */ |
@@ -387,10 +401,12 @@ do { \ | |||
387 | #define ICCR_CACHE 1 /* Cacheable */ | 401 | #define ICCR_CACHE 1 /* Cacheable */ |
388 | 402 | ||
389 | /* Bit definitions for L1CSR0. */ | 403 | /* Bit definitions for L1CSR0. */ |
404 | #define L1CSR0_CLFC 0x00000100 /* Cache Lock Bits Flash Clear */ | ||
390 | #define L1CSR0_DCFI 0x00000002 /* Data Cache Flash Invalidate */ | 405 | #define L1CSR0_DCFI 0x00000002 /* Data Cache Flash Invalidate */ |
406 | #define L1CSR0_CFI 0x00000002 /* Cache Flash Invalidate */ | ||
391 | #define L1CSR0_DCE 0x00000001 /* Data Cache Enable */ | 407 | #define L1CSR0_DCE 0x00000001 /* Data Cache Enable */ |
392 | 408 | ||
393 | /* Bit definitions for L1CSR0. */ | 409 | /* Bit definitions for L1CSR1. */ |
394 | #define L1CSR1_ICLFR 0x00000100 /* Instr Cache Lock Bits Flash Reset */ | 410 | #define L1CSR1_ICLFR 0x00000100 /* Instr Cache Lock Bits Flash Reset */ |
395 | #define L1CSR1_ICFI 0x00000002 /* Instr Cache Flash Invalidate */ | 411 | #define L1CSR1_ICFI 0x00000002 /* Instr Cache Flash Invalidate */ |
396 | #define L1CSR1_ICE 0x00000001 /* Instr Cache Enable */ | 412 | #define L1CSR1_ICE 0x00000001 /* Instr Cache Enable */ |
diff --git a/include/asm-ppc64/kdebug.h b/include/asm-ppc64/kdebug.h index 488634258a72..d383d161cf8d 100644 --- a/include/asm-ppc64/kdebug.h +++ b/include/asm-ppc64/kdebug.h | |||
@@ -17,7 +17,7 @@ struct die_args { | |||
17 | 17 | ||
18 | /* | 18 | /* |
19 | Note - you should never unregister because that can race with NMIs. | 19 | Note - you should never unregister because that can race with NMIs. |
20 | If you really want to do it first unregister - then synchronize_kernel - | 20 | If you really want to do it first unregister - then synchronize_sched - |
21 | then free. | 21 | then free. |
22 | */ | 22 | */ |
23 | int register_die_notifier(struct notifier_block *nb); | 23 | int register_die_notifier(struct notifier_block *nb); |
diff --git a/include/asm-ppc64/kexec.h b/include/asm-ppc64/kexec.h new file mode 100644 index 000000000000..511908afaeeb --- /dev/null +++ b/include/asm-ppc64/kexec.h | |||
@@ -0,0 +1,41 @@ | |||
1 | #ifndef _PPC64_KEXEC_H | ||
2 | #define _PPC64_KEXEC_H | ||
3 | |||
4 | /* | ||
5 | * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return. | ||
6 | * I.e. Maximum page that is mapped directly into kernel memory, | ||
7 | * and kmap is not required. | ||
8 | */ | ||
9 | |||
10 | /* Maximum physical address we can use pages from */ | ||
11 | /* XXX: since we copy virt we can use any page we allocate */ | ||
12 | #define KEXEC_SOURCE_MEMORY_LIMIT (-1UL) | ||
13 | |||
14 | /* Maximum address we can reach in physical address mode */ | ||
15 | /* XXX: I want to allow initrd in highmem. otherwise set to rmo on lpar */ | ||
16 | #define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL) | ||
17 | |||
18 | /* Maximum address we can use for the control code buffer */ | ||
19 | /* XXX: unused today, ppc32 uses TASK_SIZE, probably left over from use_mm */ | ||
20 | #define KEXEC_CONTROL_MEMORY_LIMIT (-1UL) | ||
21 | |||
22 | /* XXX: today we don't use this at all, althogh we have a static stack */ | ||
23 | #define KEXEC_CONTROL_CODE_SIZE 4096 | ||
24 | |||
25 | /* The native architecture */ | ||
26 | #define KEXEC_ARCH KEXEC_ARCH_PPC64 | ||
27 | |||
28 | #define MAX_NOTE_BYTES 1024 | ||
29 | |||
30 | #ifndef __ASSEMBLY__ | ||
31 | |||
32 | typedef u32 note_buf_t[MAX_NOTE_BYTES/4]; | ||
33 | |||
34 | extern note_buf_t crash_notes[]; | ||
35 | |||
36 | extern void kexec_smp_wait(void); /* get and clear naca physid, wait for | ||
37 | master to copy new code to 0 */ | ||
38 | |||
39 | #endif /* __ASSEMBLY__ */ | ||
40 | #endif /* _PPC_KEXEC_H */ | ||
41 | |||
diff --git a/include/asm-ppc64/machdep.h b/include/asm-ppc64/machdep.h index 553b2ea23bed..9cdad3ed1526 100644 --- a/include/asm-ppc64/machdep.h +++ b/include/asm-ppc64/machdep.h | |||
@@ -86,6 +86,7 @@ struct machdep_calls { | |||
86 | 86 | ||
87 | void (*init_IRQ)(void); | 87 | void (*init_IRQ)(void); |
88 | int (*get_irq)(struct pt_regs *); | 88 | int (*get_irq)(struct pt_regs *); |
89 | void (*cpu_irq_down)(void); | ||
89 | 90 | ||
90 | /* PCI stuff */ | 91 | /* PCI stuff */ |
91 | void (*pcibios_fixup)(void); | 92 | void (*pcibios_fixup)(void); |
diff --git a/include/asm-ppc64/mmu.h b/include/asm-ppc64/mmu.h index 9d03a98a4fa3..f373de5e3dd9 100644 --- a/include/asm-ppc64/mmu.h +++ b/include/asm-ppc64/mmu.h | |||
@@ -181,6 +181,28 @@ static inline void tlbiel(unsigned long va) | |||
181 | asm volatile("ptesync": : :"memory"); | 181 | asm volatile("ptesync": : :"memory"); |
182 | } | 182 | } |
183 | 183 | ||
184 | static inline unsigned long slot2va(unsigned long avpn, unsigned long large, | ||
185 | unsigned long secondary, unsigned long slot) | ||
186 | { | ||
187 | unsigned long va; | ||
188 | |||
189 | va = avpn << 23; | ||
190 | |||
191 | if (!large) { | ||
192 | unsigned long vpi, pteg; | ||
193 | |||
194 | pteg = slot / HPTES_PER_GROUP; | ||
195 | if (secondary) | ||
196 | pteg = ~pteg; | ||
197 | |||
198 | vpi = ((va >> 28) ^ pteg) & htab_hash_mask; | ||
199 | |||
200 | va |= vpi << PAGE_SHIFT; | ||
201 | } | ||
202 | |||
203 | return va; | ||
204 | } | ||
205 | |||
184 | /* | 206 | /* |
185 | * Handle a fault by adding an HPTE. If the address can't be determined | 207 | * Handle a fault by adding an HPTE. If the address can't be determined |
186 | * to be valid via Linux page tables, return 1. If handled return 0 | 208 | * to be valid via Linux page tables, return 1. If handled return 0 |
diff --git a/include/asm-ppc64/xics.h b/include/asm-ppc64/xics.h index fdec5e7a7af6..0c45e14e26ca 100644 --- a/include/asm-ppc64/xics.h +++ b/include/asm-ppc64/xics.h | |||
@@ -17,6 +17,7 @@ | |||
17 | void xics_init_IRQ(void); | 17 | void xics_init_IRQ(void); |
18 | int xics_get_irq(struct pt_regs *); | 18 | int xics_get_irq(struct pt_regs *); |
19 | void xics_setup_cpu(void); | 19 | void xics_setup_cpu(void); |
20 | void xics_teardown_cpu(void); | ||
20 | void xics_cause_IPI(int cpu); | 21 | void xics_cause_IPI(int cpu); |
21 | void xics_request_IPIs(void); | 22 | void xics_request_IPIs(void); |
22 | void xics_migrate_irqs_away(void); | 23 | void xics_migrate_irqs_away(void); |
diff --git a/include/asm-s390/cpcmd.h b/include/asm-s390/cpcmd.h index 1d33c5da083e..1fcf65be7a23 100644 --- a/include/asm-s390/cpcmd.h +++ b/include/asm-s390/cpcmd.h | |||
@@ -11,14 +11,28 @@ | |||
11 | #define __CPCMD__ | 11 | #define __CPCMD__ |
12 | 12 | ||
13 | /* | 13 | /* |
14 | * the lowlevel function for cpcmd | ||
14 | * the caller of __cpcmd has to ensure that the response buffer is below 2 GB | 15 | * the caller of __cpcmd has to ensure that the response buffer is below 2 GB |
15 | */ | 16 | */ |
16 | extern void __cpcmd(char *cmd, char *response, int rlen); | 17 | extern int __cpcmd(const char *cmd, char *response, int rlen, int *response_code); |
17 | 18 | ||
18 | #ifndef __s390x__ | 19 | #ifndef __s390x__ |
19 | #define cpcmd __cpcmd | 20 | #define cpcmd __cpcmd |
20 | #else | 21 | #else |
21 | extern void cpcmd(char *cmd, char *response, int rlen); | 22 | /* |
23 | * cpcmd is the in-kernel interface for issuing CP commands | ||
24 | * | ||
25 | * cmd: null-terminated command string, max 240 characters | ||
26 | * response: response buffer for VM's textual response | ||
27 | * rlen: size of the response buffer, cpcmd will not exceed this size | ||
28 | * but will cap the output, if its too large. Everything that | ||
29 | * did not fit into the buffer will be silently dropped | ||
30 | * response_code: return pointer for VM's error code | ||
31 | * return value: the size of the response. The caller can check if the buffer | ||
32 | * was large enough by comparing the return value and rlen | ||
33 | * NOTE: If the response buffer is not below 2 GB, cpcmd can sleep | ||
34 | */ | ||
35 | extern int cpcmd(const char *cmd, char *response, int rlen, int *response_code); | ||
22 | #endif /*__s390x__*/ | 36 | #endif /*__s390x__*/ |
23 | 37 | ||
24 | #endif | 38 | #endif |
diff --git a/include/asm-s390/debug.h b/include/asm-s390/debug.h index 6bbcdea42a86..92360d90144b 100644 --- a/include/asm-s390/debug.h +++ b/include/asm-s390/debug.h | |||
@@ -9,6 +9,8 @@ | |||
9 | #ifndef DEBUG_H | 9 | #ifndef DEBUG_H |
10 | #define DEBUG_H | 10 | #define DEBUG_H |
11 | 11 | ||
12 | #include <linux/config.h> | ||
13 | #include <linux/fs.h> | ||
12 | #include <linux/string.h> | 14 | #include <linux/string.h> |
13 | 15 | ||
14 | /* Note: | 16 | /* Note: |
@@ -31,19 +33,18 @@ struct __debug_entry{ | |||
31 | } __attribute__((packed)); | 33 | } __attribute__((packed)); |
32 | 34 | ||
33 | 35 | ||
34 | #define __DEBUG_FEATURE_VERSION 1 /* version of debug feature */ | 36 | #define __DEBUG_FEATURE_VERSION 2 /* version of debug feature */ |
35 | 37 | ||
36 | #ifdef __KERNEL__ | 38 | #ifdef __KERNEL__ |
37 | #include <linux/spinlock.h> | 39 | #include <linux/spinlock.h> |
38 | #include <linux/kernel.h> | 40 | #include <linux/kernel.h> |
39 | #include <linux/time.h> | 41 | #include <linux/time.h> |
40 | #include <linux/proc_fs.h> | ||
41 | 42 | ||
42 | #define DEBUG_MAX_LEVEL 6 /* debug levels range from 0 to 6 */ | 43 | #define DEBUG_MAX_LEVEL 6 /* debug levels range from 0 to 6 */ |
43 | #define DEBUG_OFF_LEVEL -1 /* level where debug is switched off */ | 44 | #define DEBUG_OFF_LEVEL -1 /* level where debug is switched off */ |
44 | #define DEBUG_FLUSH_ALL -1 /* parameter to flush all areas */ | 45 | #define DEBUG_FLUSH_ALL -1 /* parameter to flush all areas */ |
45 | #define DEBUG_MAX_VIEWS 10 /* max number of views in proc fs */ | 46 | #define DEBUG_MAX_VIEWS 10 /* max number of views in proc fs */ |
46 | #define DEBUG_MAX_PROCF_LEN 64 /* max length for a proc file name */ | 47 | #define DEBUG_MAX_NAME_LEN 64 /* max length for a debugfs file name */ |
47 | #define DEBUG_DEFAULT_LEVEL 3 /* initial debug level */ | 48 | #define DEBUG_DEFAULT_LEVEL 3 /* initial debug level */ |
48 | 49 | ||
49 | #define DEBUG_DIR_ROOT "s390dbf" /* name of debug root directory in proc fs */ | 50 | #define DEBUG_DIR_ROOT "s390dbf" /* name of debug root directory in proc fs */ |
@@ -64,16 +65,17 @@ typedef struct debug_info { | |||
64 | spinlock_t lock; | 65 | spinlock_t lock; |
65 | int level; | 66 | int level; |
66 | int nr_areas; | 67 | int nr_areas; |
67 | int page_order; | 68 | int pages_per_area; |
68 | int buf_size; | 69 | int buf_size; |
69 | int entry_size; | 70 | int entry_size; |
70 | debug_entry_t** areas; | 71 | debug_entry_t*** areas; |
71 | int active_area; | 72 | int active_area; |
72 | int *active_entry; | 73 | int *active_pages; |
73 | struct proc_dir_entry* proc_root_entry; | 74 | int *active_entries; |
74 | struct proc_dir_entry* proc_entries[DEBUG_MAX_VIEWS]; | 75 | struct dentry* debugfs_root_entry; |
76 | struct dentry* debugfs_entries[DEBUG_MAX_VIEWS]; | ||
75 | struct debug_view* views[DEBUG_MAX_VIEWS]; | 77 | struct debug_view* views[DEBUG_MAX_VIEWS]; |
76 | char name[DEBUG_MAX_PROCF_LEN]; | 78 | char name[DEBUG_MAX_NAME_LEN]; |
77 | } debug_info_t; | 79 | } debug_info_t; |
78 | 80 | ||
79 | typedef int (debug_header_proc_t) (debug_info_t* id, | 81 | typedef int (debug_header_proc_t) (debug_info_t* id, |
@@ -98,7 +100,7 @@ int debug_dflt_header_fn(debug_info_t* id, struct debug_view* view, | |||
98 | int area, debug_entry_t* entry, char* out_buf); | 100 | int area, debug_entry_t* entry, char* out_buf); |
99 | 101 | ||
100 | struct debug_view { | 102 | struct debug_view { |
101 | char name[DEBUG_MAX_PROCF_LEN]; | 103 | char name[DEBUG_MAX_NAME_LEN]; |
102 | debug_prolog_proc_t* prolog_proc; | 104 | debug_prolog_proc_t* prolog_proc; |
103 | debug_header_proc_t* header_proc; | 105 | debug_header_proc_t* header_proc; |
104 | debug_format_proc_t* format_proc; | 106 | debug_format_proc_t* format_proc; |
@@ -120,7 +122,7 @@ debug_entry_t* debug_exception_common(debug_info_t* id, int level, | |||
120 | 122 | ||
121 | /* Debug Feature API: */ | 123 | /* Debug Feature API: */ |
122 | 124 | ||
123 | debug_info_t* debug_register(char* name, int pages_index, int nr_areas, | 125 | debug_info_t* debug_register(char* name, int pages, int nr_areas, |
124 | int buf_size); | 126 | int buf_size); |
125 | 127 | ||
126 | void debug_unregister(debug_info_t* id); | 128 | void debug_unregister(debug_info_t* id); |
@@ -132,7 +134,8 @@ void debug_stop_all(void); | |||
132 | extern inline debug_entry_t* | 134 | extern inline debug_entry_t* |
133 | debug_event(debug_info_t* id, int level, void* data, int length) | 135 | debug_event(debug_info_t* id, int level, void* data, int length) |
134 | { | 136 | { |
135 | if ((!id) || (level > id->level)) return NULL; | 137 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) |
138 | return NULL; | ||
136 | return debug_event_common(id,level,data,length); | 139 | return debug_event_common(id,level,data,length); |
137 | } | 140 | } |
138 | 141 | ||
@@ -140,7 +143,8 @@ extern inline debug_entry_t* | |||
140 | debug_int_event(debug_info_t* id, int level, unsigned int tag) | 143 | debug_int_event(debug_info_t* id, int level, unsigned int tag) |
141 | { | 144 | { |
142 | unsigned int t=tag; | 145 | unsigned int t=tag; |
143 | if ((!id) || (level > id->level)) return NULL; | 146 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) |
147 | return NULL; | ||
144 | return debug_event_common(id,level,&t,sizeof(unsigned int)); | 148 | return debug_event_common(id,level,&t,sizeof(unsigned int)); |
145 | } | 149 | } |
146 | 150 | ||
@@ -148,14 +152,16 @@ extern inline debug_entry_t * | |||
148 | debug_long_event (debug_info_t* id, int level, unsigned long tag) | 152 | debug_long_event (debug_info_t* id, int level, unsigned long tag) |
149 | { | 153 | { |
150 | unsigned long t=tag; | 154 | unsigned long t=tag; |
151 | if ((!id) || (level > id->level)) return NULL; | 155 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) |
156 | return NULL; | ||
152 | return debug_event_common(id,level,&t,sizeof(unsigned long)); | 157 | return debug_event_common(id,level,&t,sizeof(unsigned long)); |
153 | } | 158 | } |
154 | 159 | ||
155 | extern inline debug_entry_t* | 160 | extern inline debug_entry_t* |
156 | debug_text_event(debug_info_t* id, int level, const char* txt) | 161 | debug_text_event(debug_info_t* id, int level, const char* txt) |
157 | { | 162 | { |
158 | if ((!id) || (level > id->level)) return NULL; | 163 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) |
164 | return NULL; | ||
159 | return debug_event_common(id,level,txt,strlen(txt)); | 165 | return debug_event_common(id,level,txt,strlen(txt)); |
160 | } | 166 | } |
161 | 167 | ||
@@ -167,7 +173,8 @@ debug_sprintf_event(debug_info_t* id,int level,char *string,...) | |||
167 | extern inline debug_entry_t* | 173 | extern inline debug_entry_t* |
168 | debug_exception(debug_info_t* id, int level, void* data, int length) | 174 | debug_exception(debug_info_t* id, int level, void* data, int length) |
169 | { | 175 | { |
170 | if ((!id) || (level > id->level)) return NULL; | 176 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) |
177 | return NULL; | ||
171 | return debug_exception_common(id,level,data,length); | 178 | return debug_exception_common(id,level,data,length); |
172 | } | 179 | } |
173 | 180 | ||
@@ -175,7 +182,8 @@ extern inline debug_entry_t* | |||
175 | debug_int_exception(debug_info_t* id, int level, unsigned int tag) | 182 | debug_int_exception(debug_info_t* id, int level, unsigned int tag) |
176 | { | 183 | { |
177 | unsigned int t=tag; | 184 | unsigned int t=tag; |
178 | if ((!id) || (level > id->level)) return NULL; | 185 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) |
186 | return NULL; | ||
179 | return debug_exception_common(id,level,&t,sizeof(unsigned int)); | 187 | return debug_exception_common(id,level,&t,sizeof(unsigned int)); |
180 | } | 188 | } |
181 | 189 | ||
@@ -183,14 +191,16 @@ extern inline debug_entry_t * | |||
183 | debug_long_exception (debug_info_t* id, int level, unsigned long tag) | 191 | debug_long_exception (debug_info_t* id, int level, unsigned long tag) |
184 | { | 192 | { |
185 | unsigned long t=tag; | 193 | unsigned long t=tag; |
186 | if ((!id) || (level > id->level)) return NULL; | 194 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) |
195 | return NULL; | ||
187 | return debug_exception_common(id,level,&t,sizeof(unsigned long)); | 196 | return debug_exception_common(id,level,&t,sizeof(unsigned long)); |
188 | } | 197 | } |
189 | 198 | ||
190 | extern inline debug_entry_t* | 199 | extern inline debug_entry_t* |
191 | debug_text_exception(debug_info_t* id, int level, const char* txt) | 200 | debug_text_exception(debug_info_t* id, int level, const char* txt) |
192 | { | 201 | { |
193 | if ((!id) || (level > id->level)) return NULL; | 202 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) |
203 | return NULL; | ||
194 | return debug_exception_common(id,level,txt,strlen(txt)); | 204 | return debug_exception_common(id,level,txt,strlen(txt)); |
195 | } | 205 | } |
196 | 206 | ||
diff --git a/include/asm-s390/kexec.h b/include/asm-s390/kexec.h new file mode 100644 index 000000000000..54cf7d9f251c --- /dev/null +++ b/include/asm-s390/kexec.h | |||
@@ -0,0 +1,42 @@ | |||
1 | /* | ||
2 | * include/asm-s390/kexec.h | ||
3 | * | ||
4 | * (C) Copyright IBM Corp. 2005 | ||
5 | * | ||
6 | * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com> | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #ifndef _S390_KEXEC_H | ||
11 | #define _S390_KEXEC_H | ||
12 | |||
13 | #include <asm/page.h> | ||
14 | #include <asm/processor.h> | ||
15 | /* | ||
16 | * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return. | ||
17 | * I.e. Maximum page that is mapped directly into kernel memory, | ||
18 | * and kmap is not required. | ||
19 | */ | ||
20 | |||
21 | /* Maximum physical address we can use pages from */ | ||
22 | #define KEXEC_SOURCE_MEMORY_LIMIT (-1UL) | ||
23 | |||
24 | /* Maximum address we can reach in physical address mode */ | ||
25 | #define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL) | ||
26 | |||
27 | /* Maximum address we can use for the control pages */ | ||
28 | /* Not more than 2GB */ | ||
29 | #define KEXEC_CONTROL_MEMORY_LIMIT (1<<31) | ||
30 | |||
31 | /* Allocate one page for the pdp and the second for the code */ | ||
32 | #define KEXEC_CONTROL_CODE_SIZE 4096 | ||
33 | |||
34 | /* The native architecture */ | ||
35 | #define KEXEC_ARCH KEXEC_ARCH_S390 | ||
36 | |||
37 | #define MAX_NOTE_BYTES 1024 | ||
38 | typedef u32 note_buf_t[MAX_NOTE_BYTES/4]; | ||
39 | |||
40 | extern note_buf_t crash_notes[]; | ||
41 | |||
42 | #endif /*_S390_KEXEC_H */ | ||
diff --git a/include/asm-s390/lowcore.h b/include/asm-s390/lowcore.h index df5172fc589d..76b5b19c0ae2 100644 --- a/include/asm-s390/lowcore.h +++ b/include/asm-s390/lowcore.h | |||
@@ -109,10 +109,14 @@ | |||
109 | 109 | ||
110 | #ifndef __s390x__ | 110 | #ifndef __s390x__ |
111 | #define __LC_PFAULT_INTPARM 0x080 | 111 | #define __LC_PFAULT_INTPARM 0x080 |
112 | #define __LC_CPU_TIMER_SAVE_AREA 0x0D8 | ||
112 | #define __LC_AREGS_SAVE_AREA 0x120 | 113 | #define __LC_AREGS_SAVE_AREA 0x120 |
114 | #define __LC_GPREGS_SAVE_AREA 0x180 | ||
113 | #define __LC_CREGS_SAVE_AREA 0x1C0 | 115 | #define __LC_CREGS_SAVE_AREA 0x1C0 |
114 | #else /* __s390x__ */ | 116 | #else /* __s390x__ */ |
115 | #define __LC_PFAULT_INTPARM 0x11B8 | 117 | #define __LC_PFAULT_INTPARM 0x11B8 |
118 | #define __LC_GPREGS_SAVE_AREA 0x1280 | ||
119 | #define __LC_CPU_TIMER_SAVE_AREA 0x1328 | ||
116 | #define __LC_AREGS_SAVE_AREA 0x1340 | 120 | #define __LC_AREGS_SAVE_AREA 0x1340 |
117 | #define __LC_CREGS_SAVE_AREA 0x1380 | 121 | #define __LC_CREGS_SAVE_AREA 0x1380 |
118 | #endif /* __s390x__ */ | 122 | #endif /* __s390x__ */ |
@@ -167,7 +171,8 @@ struct _lowcore | |||
167 | __u16 subchannel_nr; /* 0x0ba */ | 171 | __u16 subchannel_nr; /* 0x0ba */ |
168 | __u32 io_int_parm; /* 0x0bc */ | 172 | __u32 io_int_parm; /* 0x0bc */ |
169 | __u32 io_int_word; /* 0x0c0 */ | 173 | __u32 io_int_word; /* 0x0c0 */ |
170 | __u8 pad3[0xD8-0xC4]; /* 0x0c4 */ | 174 | __u8 pad3[0xD4-0xC4]; /* 0x0c4 */ |
175 | __u32 extended_save_area_addr; /* 0x0d4 */ | ||
171 | __u32 cpu_timer_save_area[2]; /* 0x0d8 */ | 176 | __u32 cpu_timer_save_area[2]; /* 0x0d8 */ |
172 | __u32 clock_comp_save_area[2]; /* 0x0e0 */ | 177 | __u32 clock_comp_save_area[2]; /* 0x0e0 */ |
173 | __u32 mcck_interruption_code[2]; /* 0x0e8 */ | 178 | __u32 mcck_interruption_code[2]; /* 0x0e8 */ |
diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h index fb46e9090b50..8bd14de69e35 100644 --- a/include/asm-s390/processor.h +++ b/include/asm-s390/processor.h | |||
@@ -207,6 +207,18 @@ unsigned long get_wchan(struct task_struct *p); | |||
207 | #endif /* __s390x__ */ | 207 | #endif /* __s390x__ */ |
208 | 208 | ||
209 | /* | 209 | /* |
210 | * Set PSW to specified value. | ||
211 | */ | ||
212 | static inline void __load_psw(psw_t psw) | ||
213 | { | ||
214 | #ifndef __s390x__ | ||
215 | asm volatile ("lpsw 0(%0)" : : "a" (&psw), "m" (psw) : "cc" ); | ||
216 | #else | ||
217 | asm volatile ("lpswe 0(%0)" : : "a" (&psw), "m" (psw) : "cc" ); | ||
218 | #endif | ||
219 | } | ||
220 | |||
221 | /* | ||
210 | * Set PSW mask to specified value, while leaving the | 222 | * Set PSW mask to specified value, while leaving the |
211 | * PSW addr pointing to the next instruction. | 223 | * PSW addr pointing to the next instruction. |
212 | */ | 224 | */ |
@@ -214,8 +226,8 @@ unsigned long get_wchan(struct task_struct *p); | |||
214 | static inline void __load_psw_mask (unsigned long mask) | 226 | static inline void __load_psw_mask (unsigned long mask) |
215 | { | 227 | { |
216 | unsigned long addr; | 228 | unsigned long addr; |
217 | |||
218 | psw_t psw; | 229 | psw_t psw; |
230 | |||
219 | psw.mask = mask; | 231 | psw.mask = mask; |
220 | 232 | ||
221 | #ifndef __s390x__ | 233 | #ifndef __s390x__ |
@@ -241,30 +253,8 @@ static inline void __load_psw_mask (unsigned long mask) | |||
241 | */ | 253 | */ |
242 | static inline void enabled_wait(void) | 254 | static inline void enabled_wait(void) |
243 | { | 255 | { |
244 | unsigned long reg; | 256 | __load_psw_mask(PSW_BASE_BITS | PSW_MASK_IO | PSW_MASK_EXT | |
245 | psw_t wait_psw; | 257 | PSW_MASK_MCHECK | PSW_MASK_WAIT | PSW_DEFAULT_KEY); |
246 | |||
247 | wait_psw.mask = PSW_BASE_BITS | PSW_MASK_IO | PSW_MASK_EXT | | ||
248 | PSW_MASK_MCHECK | PSW_MASK_WAIT | PSW_DEFAULT_KEY; | ||
249 | #ifndef __s390x__ | ||
250 | asm volatile ( | ||
251 | " basr %0,0\n" | ||
252 | "0: la %0,1f-0b(%0)\n" | ||
253 | " st %0,4(%1)\n" | ||
254 | " oi 4(%1),0x80\n" | ||
255 | " lpsw 0(%1)\n" | ||
256 | "1:" | ||
257 | : "=&a" (reg) : "a" (&wait_psw), "m" (wait_psw) | ||
258 | : "memory", "cc" ); | ||
259 | #else /* __s390x__ */ | ||
260 | asm volatile ( | ||
261 | " larl %0,0f\n" | ||
262 | " stg %0,8(%1)\n" | ||
263 | " lpswe 0(%1)\n" | ||
264 | "0:" | ||
265 | : "=&a" (reg) : "a" (&wait_psw), "m" (wait_psw) | ||
266 | : "memory", "cc" ); | ||
267 | #endif /* __s390x__ */ | ||
268 | } | 258 | } |
269 | 259 | ||
270 | /* | 260 | /* |
@@ -273,13 +263,11 @@ static inline void enabled_wait(void) | |||
273 | 263 | ||
274 | static inline void disabled_wait(unsigned long code) | 264 | static inline void disabled_wait(unsigned long code) |
275 | { | 265 | { |
276 | char psw_buffer[2*sizeof(psw_t)]; | ||
277 | unsigned long ctl_buf; | 266 | unsigned long ctl_buf; |
278 | psw_t *dw_psw = (psw_t *)(((unsigned long) &psw_buffer+sizeof(psw_t)-1) | 267 | psw_t dw_psw; |
279 | & -sizeof(psw_t)); | ||
280 | 268 | ||
281 | dw_psw->mask = PSW_BASE_BITS | PSW_MASK_WAIT; | 269 | dw_psw.mask = PSW_BASE_BITS | PSW_MASK_WAIT; |
282 | dw_psw->addr = code; | 270 | dw_psw.addr = code; |
283 | /* | 271 | /* |
284 | * Store status and then load disabled wait psw, | 272 | * Store status and then load disabled wait psw, |
285 | * the processor is dead afterwards | 273 | * the processor is dead afterwards |
@@ -301,7 +289,7 @@ static inline void disabled_wait(unsigned long code) | |||
301 | " oi 0x1c0,0x10\n" /* fake protection bit */ | 289 | " oi 0x1c0,0x10\n" /* fake protection bit */ |
302 | " lpsw 0(%1)" | 290 | " lpsw 0(%1)" |
303 | : "=m" (ctl_buf) | 291 | : "=m" (ctl_buf) |
304 | : "a" (dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc" ); | 292 | : "a" (&dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc" ); |
305 | #else /* __s390x__ */ | 293 | #else /* __s390x__ */ |
306 | asm volatile (" stctg 0,0,0(%2)\n" | 294 | asm volatile (" stctg 0,0,0(%2)\n" |
307 | " ni 4(%2),0xef\n" /* switch off protection */ | 295 | " ni 4(%2),0xef\n" /* switch off protection */ |
@@ -333,7 +321,7 @@ static inline void disabled_wait(unsigned long code) | |||
333 | " oi 0x384(1),0x10\n" /* fake protection bit */ | 321 | " oi 0x384(1),0x10\n" /* fake protection bit */ |
334 | " lpswe 0(%1)" | 322 | " lpswe 0(%1)" |
335 | : "=m" (ctl_buf) | 323 | : "=m" (ctl_buf) |
336 | : "a" (dw_psw), "a" (&ctl_buf), | 324 | : "a" (&dw_psw), "a" (&ctl_buf), |
337 | "m" (dw_psw) : "cc", "0", "1"); | 325 | "m" (dw_psw) : "cc", "0", "1"); |
338 | #endif /* __s390x__ */ | 326 | #endif /* __s390x__ */ |
339 | } | 327 | } |
diff --git a/include/asm-s390/ptrace.h b/include/asm-s390/ptrace.h index 4eff8f2e3bf1..fc7c96edc697 100644 --- a/include/asm-s390/ptrace.h +++ b/include/asm-s390/ptrace.h | |||
@@ -276,7 +276,7 @@ typedef struct | |||
276 | #endif /* __s390x__ */ | 276 | #endif /* __s390x__ */ |
277 | 277 | ||
278 | #define PSW_KERNEL_BITS (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY | \ | 278 | #define PSW_KERNEL_BITS (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY | \ |
279 | PSW_DEFAULT_KEY) | 279 | PSW_MASK_MCHECK | PSW_DEFAULT_KEY) |
280 | #define PSW_USER_BITS (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_HOME | \ | 280 | #define PSW_USER_BITS (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_HOME | \ |
281 | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK | \ | 281 | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK | \ |
282 | PSW_MASK_PSTATE | PSW_DEFAULT_KEY) | 282 | PSW_MASK_PSTATE | PSW_DEFAULT_KEY) |
diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h index 81514d76edcf..b4a9f05a93d6 100644 --- a/include/asm-s390/system.h +++ b/include/asm-s390/system.h | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <asm/types.h> | 16 | #include <asm/types.h> |
17 | #include <asm/ptrace.h> | 17 | #include <asm/ptrace.h> |
18 | #include <asm/setup.h> | 18 | #include <asm/setup.h> |
19 | #include <asm/processor.h> | ||
19 | 20 | ||
20 | #ifdef __KERNEL__ | 21 | #ifdef __KERNEL__ |
21 | 22 | ||
@@ -103,29 +104,18 @@ static inline void restore_access_regs(unsigned int *acrs) | |||
103 | prev = __switch_to(prev,next); \ | 104 | prev = __switch_to(prev,next); \ |
104 | } while (0) | 105 | } while (0) |
105 | 106 | ||
106 | #define prepare_arch_switch(rq, next) do { } while(0) | ||
107 | #define task_running(rq, p) ((rq)->curr == (p)) | ||
108 | |||
109 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 107 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
110 | extern void account_user_vtime(struct task_struct *); | 108 | extern void account_user_vtime(struct task_struct *); |
111 | extern void account_system_vtime(struct task_struct *); | 109 | extern void account_system_vtime(struct task_struct *); |
112 | |||
113 | #define finish_arch_switch(rq, prev) do { \ | ||
114 | set_fs(current->thread.mm_segment); \ | ||
115 | spin_unlock(&(rq)->lock); \ | ||
116 | account_system_vtime(prev); \ | ||
117 | local_irq_enable(); \ | ||
118 | } while (0) | ||
119 | |||
120 | #else | 110 | #else |
111 | #define account_system_vtime(prev) do { } while (0) | ||
112 | #endif | ||
121 | 113 | ||
122 | #define finish_arch_switch(rq, prev) do { \ | 114 | #define finish_arch_switch(rq, prev) do { \ |
123 | set_fs(current->thread.mm_segment); \ | 115 | set_fs(current->thread.mm_segment); \ |
124 | spin_unlock_irq(&(rq)->lock); \ | 116 | account_system_vtime(prev); \ |
125 | } while (0) | 117 | } while (0) |
126 | 118 | ||
127 | #endif | ||
128 | |||
129 | #define nop() __asm__ __volatile__ ("nop") | 119 | #define nop() __asm__ __volatile__ ("nop") |
130 | 120 | ||
131 | #define xchg(ptr,x) \ | 121 | #define xchg(ptr,x) \ |
@@ -331,9 +321,6 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) | |||
331 | 321 | ||
332 | #ifdef __s390x__ | 322 | #ifdef __s390x__ |
333 | 323 | ||
334 | #define __load_psw(psw) \ | ||
335 | __asm__ __volatile__("lpswe 0(%0)" : : "a" (&psw), "m" (psw) : "cc" ); | ||
336 | |||
337 | #define __ctl_load(array, low, high) ({ \ | 324 | #define __ctl_load(array, low, high) ({ \ |
338 | typedef struct { char _[sizeof(array)]; } addrtype; \ | 325 | typedef struct { char _[sizeof(array)]; } addrtype; \ |
339 | __asm__ __volatile__ ( \ | 326 | __asm__ __volatile__ ( \ |
@@ -390,9 +377,6 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) | |||
390 | 377 | ||
391 | #else /* __s390x__ */ | 378 | #else /* __s390x__ */ |
392 | 379 | ||
393 | #define __load_psw(psw) \ | ||
394 | __asm__ __volatile__("lpsw 0(%0)" : : "a" (&psw) : "cc" ); | ||
395 | |||
396 | #define __ctl_load(array, low, high) ({ \ | 380 | #define __ctl_load(array, low, high) ({ \ |
397 | typedef struct { char _[sizeof(array)]; } addrtype; \ | 381 | typedef struct { char _[sizeof(array)]; } addrtype; \ |
398 | __asm__ __volatile__ ( \ | 382 | __asm__ __volatile__ ( \ |
@@ -451,6 +435,20 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) | |||
451 | /* For spinlocks etc */ | 435 | /* For spinlocks etc */ |
452 | #define local_irq_save(x) ((x) = local_irq_disable()) | 436 | #define local_irq_save(x) ((x) = local_irq_disable()) |
453 | 437 | ||
438 | /* | ||
439 | * Use to set psw mask except for the first byte which | ||
440 | * won't be changed by this function. | ||
441 | */ | ||
442 | static inline void | ||
443 | __set_psw_mask(unsigned long mask) | ||
444 | { | ||
445 | local_save_flags(mask); | ||
446 | __load_psw_mask(mask); | ||
447 | } | ||
448 | |||
449 | #define local_mcck_enable() __set_psw_mask(PSW_KERNEL_BITS) | ||
450 | #define local_mcck_disable() __set_psw_mask(PSW_KERNEL_BITS & ~PSW_MASK_MCHECK) | ||
451 | |||
454 | #ifdef CONFIG_SMP | 452 | #ifdef CONFIG_SMP |
455 | 453 | ||
456 | extern void smp_ctl_set_bit(int cr, int bit); | 454 | extern void smp_ctl_set_bit(int cr, int bit); |
diff --git a/include/asm-s390/thread_info.h b/include/asm-s390/thread_info.h index fe101d41e849..6c18a3f24316 100644 --- a/include/asm-s390/thread_info.h +++ b/include/asm-s390/thread_info.h | |||
@@ -96,6 +96,7 @@ static inline struct thread_info *current_thread_info(void) | |||
96 | #define TIF_RESTART_SVC 4 /* restart svc with new svc number */ | 96 | #define TIF_RESTART_SVC 4 /* restart svc with new svc number */ |
97 | #define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */ | 97 | #define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */ |
98 | #define TIF_SINGLE_STEP 6 /* deliver sigtrap on return to user */ | 98 | #define TIF_SINGLE_STEP 6 /* deliver sigtrap on return to user */ |
99 | #define TIF_MCCK_PENDING 7 /* machine check handling is pending */ | ||
99 | #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ | 100 | #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ |
100 | #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling | 101 | #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling |
101 | TIF_NEED_RESCHED */ | 102 | TIF_NEED_RESCHED */ |
@@ -109,6 +110,7 @@ static inline struct thread_info *current_thread_info(void) | |||
109 | #define _TIF_RESTART_SVC (1<<TIF_RESTART_SVC) | 110 | #define _TIF_RESTART_SVC (1<<TIF_RESTART_SVC) |
110 | #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) | 111 | #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) |
111 | #define _TIF_SINGLE_STEP (1<<TIF_SINGLE_STEP) | 112 | #define _TIF_SINGLE_STEP (1<<TIF_SINGLE_STEP) |
113 | #define _TIF_MCCK_PENDING (1<<TIF_MCCK_PENDING) | ||
112 | #define _TIF_USEDFPU (1<<TIF_USEDFPU) | 114 | #define _TIF_USEDFPU (1<<TIF_USEDFPU) |
113 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) | 115 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) |
114 | #define _TIF_31BIT (1<<TIF_31BIT) | 116 | #define _TIF_31BIT (1<<TIF_31BIT) |
diff --git a/include/asm-s390/unistd.h b/include/asm-s390/unistd.h index f1a204f7c0f0..363db45f8d07 100644 --- a/include/asm-s390/unistd.h +++ b/include/asm-s390/unistd.h | |||
@@ -269,7 +269,7 @@ | |||
269 | #define __NR_mq_timedreceive 274 | 269 | #define __NR_mq_timedreceive 274 |
270 | #define __NR_mq_notify 275 | 270 | #define __NR_mq_notify 275 |
271 | #define __NR_mq_getsetattr 276 | 271 | #define __NR_mq_getsetattr 276 |
272 | /* Number 277 is reserved for new sys_kexec_load */ | 272 | #define __NR_kexec_load 277 |
273 | #define __NR_add_key 278 | 273 | #define __NR_add_key 278 |
274 | #define __NR_request_key 279 | 274 | #define __NR_request_key 279 |
275 | #define __NR_keyctl 280 | 275 | #define __NR_keyctl 280 |
diff --git a/include/asm-sparc/system.h b/include/asm-sparc/system.h index 80cf20cfaee1..898562ebe94c 100644 --- a/include/asm-sparc/system.h +++ b/include/asm-sparc/system.h | |||
@@ -101,7 +101,7 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr, | |||
101 | * SWITCH_ENTER and SWITH_DO_LAZY_FPU do not work yet (e.g. SMP does not work) | 101 | * SWITCH_ENTER and SWITH_DO_LAZY_FPU do not work yet (e.g. SMP does not work) |
102 | * XXX WTF is the above comment? Found in late teen 2.4.x. | 102 | * XXX WTF is the above comment? Found in late teen 2.4.x. |
103 | */ | 103 | */ |
104 | #define prepare_arch_switch(rq, next) do { \ | 104 | #define prepare_arch_switch(next) do { \ |
105 | __asm__ __volatile__( \ | 105 | __asm__ __volatile__( \ |
106 | ".globl\tflush_patch_switch\nflush_patch_switch:\n\t" \ | 106 | ".globl\tflush_patch_switch\nflush_patch_switch:\n\t" \ |
107 | "save %sp, -0x40, %sp; save %sp, -0x40, %sp; save %sp, -0x40, %sp\n\t" \ | 107 | "save %sp, -0x40, %sp; save %sp, -0x40, %sp; save %sp, -0x40, %sp\n\t" \ |
@@ -109,8 +109,6 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr, | |||
109 | "save %sp, -0x40, %sp\n\t" \ | 109 | "save %sp, -0x40, %sp\n\t" \ |
110 | "restore; restore; restore; restore; restore; restore; restore"); \ | 110 | "restore; restore; restore; restore; restore; restore; restore"); \ |
111 | } while(0) | 111 | } while(0) |
112 | #define finish_arch_switch(rq, next) spin_unlock_irq(&(rq)->lock) | ||
113 | #define task_running(rq, p) ((rq)->curr == (p)) | ||
114 | 112 | ||
115 | /* Much care has gone into this code, do not touch it. | 113 | /* Much care has gone into this code, do not touch it. |
116 | * | 114 | * |
diff --git a/include/asm-sparc64/kdebug.h b/include/asm-sparc64/kdebug.h index f70d3dad01f9..6321f5a0198d 100644 --- a/include/asm-sparc64/kdebug.h +++ b/include/asm-sparc64/kdebug.h | |||
@@ -16,7 +16,7 @@ struct die_args { | |||
16 | }; | 16 | }; |
17 | 17 | ||
18 | /* Note - you should never unregister because that can race with NMIs. | 18 | /* Note - you should never unregister because that can race with NMIs. |
19 | * If you really want to do it first unregister - then synchronize_kernel | 19 | * If you really want to do it first unregister - then synchronize_sched |
20 | * - then free. | 20 | * - then free. |
21 | */ | 21 | */ |
22 | int register_die_notifier(struct notifier_block *nb); | 22 | int register_die_notifier(struct notifier_block *nb); |
diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h index fd12ca386f48..f9be2c5b4dc9 100644 --- a/include/asm-sparc64/system.h +++ b/include/asm-sparc64/system.h | |||
@@ -139,19 +139,13 @@ extern void __flushw_user(void); | |||
139 | #define flush_user_windows flushw_user | 139 | #define flush_user_windows flushw_user |
140 | #define flush_register_windows flushw_all | 140 | #define flush_register_windows flushw_all |
141 | 141 | ||
142 | #define prepare_arch_switch(rq, next) \ | 142 | /* Don't hold the runqueue lock over context switch */ |
143 | do { spin_lock(&(next)->switch_lock); \ | 143 | #define __ARCH_WANT_UNLOCKED_CTXSW |
144 | spin_unlock(&(rq)->lock); \ | 144 | #define prepare_arch_switch(next) \ |
145 | do { \ | ||
145 | flushw_all(); \ | 146 | flushw_all(); \ |
146 | } while (0) | 147 | } while (0) |
147 | 148 | ||
148 | #define finish_arch_switch(rq, prev) \ | ||
149 | do { spin_unlock_irq(&(prev)->switch_lock); \ | ||
150 | } while (0) | ||
151 | |||
152 | #define task_running(rq, p) \ | ||
153 | ((rq)->curr == (p) || spin_is_locked(&(p)->switch_lock)) | ||
154 | |||
155 | /* See what happens when you design the chip correctly? | 149 | /* See what happens when you design the chip correctly? |
156 | * | 150 | * |
157 | * We tell gcc we clobber all non-fixed-usage registers except | 151 | * We tell gcc we clobber all non-fixed-usage registers except |
diff --git a/include/asm-sparc64/termios.h b/include/asm-sparc64/termios.h index 8effce0da087..9777a9cca88a 100644 --- a/include/asm-sparc64/termios.h +++ b/include/asm-sparc64/termios.h | |||
@@ -100,16 +100,17 @@ struct winsize { | |||
100 | #define user_termio_to_kernel_termios(termios, termio) \ | 100 | #define user_termio_to_kernel_termios(termios, termio) \ |
101 | ({ \ | 101 | ({ \ |
102 | unsigned short tmp; \ | 102 | unsigned short tmp; \ |
103 | get_user(tmp, &(termio)->c_iflag); \ | 103 | int err; \ |
104 | err = get_user(tmp, &(termio)->c_iflag); \ | ||
104 | (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \ | 105 | (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \ |
105 | get_user(tmp, &(termio)->c_oflag); \ | 106 | err |= get_user(tmp, &(termio)->c_oflag); \ |
106 | (termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \ | 107 | (termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \ |
107 | get_user(tmp, &(termio)->c_cflag); \ | 108 | err |= get_user(tmp, &(termio)->c_cflag); \ |
108 | (termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \ | 109 | (termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \ |
109 | get_user(tmp, &(termio)->c_lflag); \ | 110 | err |= get_user(tmp, &(termio)->c_lflag); \ |
110 | (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \ | 111 | (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \ |
111 | copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ | 112 | err |= copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ |
112 | 0; \ | 113 | err; \ |
113 | }) | 114 | }) |
114 | 115 | ||
115 | /* | 116 | /* |
@@ -119,53 +120,56 @@ struct winsize { | |||
119 | */ | 120 | */ |
120 | #define kernel_termios_to_user_termio(termio, termios) \ | 121 | #define kernel_termios_to_user_termio(termio, termios) \ |
121 | ({ \ | 122 | ({ \ |
122 | put_user((termios)->c_iflag, &(termio)->c_iflag); \ | 123 | int err; \ |
123 | put_user((termios)->c_oflag, &(termio)->c_oflag); \ | 124 | err = put_user((termios)->c_iflag, &(termio)->c_iflag); \ |
124 | put_user((termios)->c_cflag, &(termio)->c_cflag); \ | 125 | err |= put_user((termios)->c_oflag, &(termio)->c_oflag); \ |
125 | put_user((termios)->c_lflag, &(termio)->c_lflag); \ | 126 | err |= put_user((termios)->c_cflag, &(termio)->c_cflag); \ |
126 | put_user((termios)->c_line, &(termio)->c_line); \ | 127 | err |= put_user((termios)->c_lflag, &(termio)->c_lflag); \ |
127 | copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ | 128 | err |= put_user((termios)->c_line, &(termio)->c_line); \ |
129 | err |= copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ | ||
128 | if (!((termios)->c_lflag & ICANON)) { \ | 130 | if (!((termios)->c_lflag & ICANON)) { \ |
129 | put_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \ | 131 | err |= put_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \ |
130 | put_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \ | 132 | err |= put_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \ |
131 | } \ | 133 | } \ |
132 | 0; \ | 134 | err; \ |
133 | }) | 135 | }) |
134 | 136 | ||
135 | #define user_termios_to_kernel_termios(k, u) \ | 137 | #define user_termios_to_kernel_termios(k, u) \ |
136 | ({ \ | 138 | ({ \ |
137 | get_user((k)->c_iflag, &(u)->c_iflag); \ | 139 | int err; \ |
138 | get_user((k)->c_oflag, &(u)->c_oflag); \ | 140 | err = get_user((k)->c_iflag, &(u)->c_iflag); \ |
139 | get_user((k)->c_cflag, &(u)->c_cflag); \ | 141 | err |= get_user((k)->c_oflag, &(u)->c_oflag); \ |
140 | get_user((k)->c_lflag, &(u)->c_lflag); \ | 142 | err |= get_user((k)->c_cflag, &(u)->c_cflag); \ |
141 | get_user((k)->c_line, &(u)->c_line); \ | 143 | err |= get_user((k)->c_lflag, &(u)->c_lflag); \ |
142 | copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \ | 144 | err |= get_user((k)->c_line, &(u)->c_line); \ |
145 | err |= copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \ | ||
143 | if((k)->c_lflag & ICANON) { \ | 146 | if((k)->c_lflag & ICANON) { \ |
144 | get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ | 147 | err |= get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ |
145 | get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ | 148 | err |= get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ |
146 | } else { \ | 149 | } else { \ |
147 | get_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ | 150 | err |= get_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ |
148 | get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ | 151 | err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ |
149 | } \ | 152 | } \ |
150 | 0; \ | 153 | err; \ |
151 | }) | 154 | }) |
152 | 155 | ||
153 | #define kernel_termios_to_user_termios(u, k) \ | 156 | #define kernel_termios_to_user_termios(u, k) \ |
154 | ({ \ | 157 | ({ \ |
155 | put_user((k)->c_iflag, &(u)->c_iflag); \ | 158 | int err; \ |
156 | put_user((k)->c_oflag, &(u)->c_oflag); \ | 159 | err = put_user((k)->c_iflag, &(u)->c_iflag); \ |
157 | put_user((k)->c_cflag, &(u)->c_cflag); \ | 160 | err |= put_user((k)->c_oflag, &(u)->c_oflag); \ |
158 | put_user((k)->c_lflag, &(u)->c_lflag); \ | 161 | err |= put_user((k)->c_cflag, &(u)->c_cflag); \ |
159 | put_user((k)->c_line, &(u)->c_line); \ | 162 | err |= put_user((k)->c_lflag, &(u)->c_lflag); \ |
160 | copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \ | 163 | err |= put_user((k)->c_line, &(u)->c_line); \ |
164 | err |= copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \ | ||
161 | if(!((k)->c_lflag & ICANON)) { \ | 165 | if(!((k)->c_lflag & ICANON)) { \ |
162 | put_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ | 166 | err |= put_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ |
163 | put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ | 167 | err |= put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ |
164 | } else { \ | 168 | } else { \ |
165 | put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ | 169 | err |= put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ |
166 | put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ | 170 | err |= put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ |
167 | } \ | 171 | } \ |
168 | 0; \ | 172 | err; \ |
169 | }) | 173 | }) |
170 | 174 | ||
171 | #endif /* __KERNEL__ */ | 175 | #endif /* __KERNEL__ */ |
diff --git a/include/asm-um/ptrace-i386.h b/include/asm-um/ptrace-i386.h index 04222f35c43e..fe882b9d917e 100644 --- a/include/asm-um/ptrace-i386.h +++ b/include/asm-um/ptrace-i386.h | |||
@@ -32,6 +32,10 @@ | |||
32 | #define PT_REGS_SYSCALL_RET(r) PT_REGS_EAX(r) | 32 | #define PT_REGS_SYSCALL_RET(r) PT_REGS_EAX(r) |
33 | #define PT_FIX_EXEC_STACK(sp) do ; while(0) | 33 | #define PT_FIX_EXEC_STACK(sp) do ; while(0) |
34 | 34 | ||
35 | /* Cope with a conditional i386 definition. */ | ||
36 | #undef profile_pc | ||
37 | #define profile_pc(regs) PT_REGS_IP(regs) | ||
38 | |||
35 | #define user_mode(r) UPT_IS_USER(&(r)->regs) | 39 | #define user_mode(r) UPT_IS_USER(&(r)->regs) |
36 | 40 | ||
37 | #endif | 41 | #endif |
diff --git a/include/asm-x86_64/apic.h b/include/asm-x86_64/apic.h index e4b1017b8b2b..16ec82e16b21 100644 --- a/include/asm-x86_64/apic.h +++ b/include/asm-x86_64/apic.h | |||
@@ -77,7 +77,7 @@ static inline void ack_APIC_irq(void) | |||
77 | extern int get_maxlvt (void); | 77 | extern int get_maxlvt (void); |
78 | extern void clear_local_APIC (void); | 78 | extern void clear_local_APIC (void); |
79 | extern void connect_bsp_APIC (void); | 79 | extern void connect_bsp_APIC (void); |
80 | extern void disconnect_bsp_APIC (void); | 80 | extern void disconnect_bsp_APIC (int virt_wire_setup); |
81 | extern void disable_local_APIC (void); | 81 | extern void disable_local_APIC (void); |
82 | extern int verify_local_APIC (void); | 82 | extern int verify_local_APIC (void); |
83 | extern void cache_APIC_registers (void); | 83 | extern void cache_APIC_registers (void); |
diff --git a/include/asm-x86_64/apicdef.h b/include/asm-x86_64/apicdef.h index bfebdb690654..9388062c4f6e 100644 --- a/include/asm-x86_64/apicdef.h +++ b/include/asm-x86_64/apicdef.h | |||
@@ -94,7 +94,7 @@ | |||
94 | #define SET_APIC_DELIVERY_MODE(x,y) (((x)&~0x700)|((y)<<8)) | 94 | #define SET_APIC_DELIVERY_MODE(x,y) (((x)&~0x700)|((y)<<8)) |
95 | #define APIC_MODE_FIXED 0x0 | 95 | #define APIC_MODE_FIXED 0x0 |
96 | #define APIC_MODE_NMI 0x4 | 96 | #define APIC_MODE_NMI 0x4 |
97 | #define APIC_MODE_EXINT 0x7 | 97 | #define APIC_MODE_EXTINT 0x7 |
98 | #define APIC_LVT1 0x360 | 98 | #define APIC_LVT1 0x360 |
99 | #define APIC_LVTERR 0x370 | 99 | #define APIC_LVTERR 0x370 |
100 | #define APIC_TMICT 0x380 | 100 | #define APIC_TMICT 0x380 |
diff --git a/include/asm-x86_64/irq.h b/include/asm-x86_64/irq.h index 3af50b3c3b05..eb3b7aa9eb9f 100644 --- a/include/asm-x86_64/irq.h +++ b/include/asm-x86_64/irq.h | |||
@@ -52,4 +52,9 @@ struct irqaction; | |||
52 | struct pt_regs; | 52 | struct pt_regs; |
53 | int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *); | 53 | int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *); |
54 | 54 | ||
55 | #ifdef CONFIG_HOTPLUG_CPU | ||
56 | #include <linux/cpumask.h> | ||
57 | extern void fixup_irqs(cpumask_t map); | ||
58 | #endif | ||
59 | |||
55 | #endif /* _ASM_IRQ_H */ | 60 | #endif /* _ASM_IRQ_H */ |
diff --git a/include/asm-x86_64/kdebug.h b/include/asm-x86_64/kdebug.h index 6277f75cbb4b..b90341994d80 100644 --- a/include/asm-x86_64/kdebug.h +++ b/include/asm-x86_64/kdebug.h | |||
@@ -14,7 +14,7 @@ struct die_args { | |||
14 | }; | 14 | }; |
15 | 15 | ||
16 | /* Note - you should never unregister because that can race with NMIs. | 16 | /* Note - you should never unregister because that can race with NMIs. |
17 | If you really want to do it first unregister - then synchronize_kernel - then free. | 17 | If you really want to do it first unregister - then synchronize_sched - then free. |
18 | */ | 18 | */ |
19 | int register_die_notifier(struct notifier_block *nb); | 19 | int register_die_notifier(struct notifier_block *nb); |
20 | extern struct notifier_block *die_chain; | 20 | extern struct notifier_block *die_chain; |
diff --git a/include/asm-x86_64/kexec.h b/include/asm-x86_64/kexec.h new file mode 100644 index 000000000000..42d2ff15c592 --- /dev/null +++ b/include/asm-x86_64/kexec.h | |||
@@ -0,0 +1,33 @@ | |||
1 | #ifndef _X86_64_KEXEC_H | ||
2 | #define _X86_64_KEXEC_H | ||
3 | |||
4 | #include <asm/page.h> | ||
5 | #include <asm/proto.h> | ||
6 | |||
7 | /* | ||
8 | * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return. | ||
9 | * I.e. Maximum page that is mapped directly into kernel memory, | ||
10 | * and kmap is not required. | ||
11 | * | ||
12 | * So far x86_64 is limited to 40 physical address bits. | ||
13 | */ | ||
14 | |||
15 | /* Maximum physical address we can use pages from */ | ||
16 | #define KEXEC_SOURCE_MEMORY_LIMIT (0xFFFFFFFFFFUL) | ||
17 | /* Maximum address we can reach in physical address mode */ | ||
18 | #define KEXEC_DESTINATION_MEMORY_LIMIT (0xFFFFFFFFFFUL) | ||
19 | /* Maximum address we can use for the control pages */ | ||
20 | #define KEXEC_CONTROL_MEMORY_LIMIT (0xFFFFFFFFFFUL) | ||
21 | |||
22 | /* Allocate one page for the pdp and the second for the code */ | ||
23 | #define KEXEC_CONTROL_CODE_SIZE (4096UL + 4096UL) | ||
24 | |||
25 | /* The native architecture */ | ||
26 | #define KEXEC_ARCH KEXEC_ARCH_X86_64 | ||
27 | |||
28 | #define MAX_NOTE_BYTES 1024 | ||
29 | typedef u32 note_buf_t[MAX_NOTE_BYTES/4]; | ||
30 | |||
31 | extern note_buf_t crash_notes[]; | ||
32 | |||
33 | #endif /* _X86_64_KEXEC_H */ | ||
diff --git a/include/asm-x86_64/page.h b/include/asm-x86_64/page.h index 60130f4ca986..431318764af6 100644 --- a/include/asm-x86_64/page.h +++ b/include/asm-x86_64/page.h | |||
@@ -64,12 +64,14 @@ typedef struct { unsigned long pgprot; } pgprot_t; | |||
64 | #define __pgd(x) ((pgd_t) { (x) } ) | 64 | #define __pgd(x) ((pgd_t) { (x) } ) |
65 | #define __pgprot(x) ((pgprot_t) { (x) } ) | 65 | #define __pgprot(x) ((pgprot_t) { (x) } ) |
66 | 66 | ||
67 | #define __START_KERNEL 0xffffffff80100000UL | 67 | #define __PHYSICAL_START ((unsigned long)CONFIG_PHYSICAL_START) |
68 | #define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START) | ||
68 | #define __START_KERNEL_map 0xffffffff80000000UL | 69 | #define __START_KERNEL_map 0xffffffff80000000UL |
69 | #define __PAGE_OFFSET 0xffff810000000000UL | 70 | #define __PAGE_OFFSET 0xffff810000000000UL |
70 | 71 | ||
71 | #else | 72 | #else |
72 | #define __START_KERNEL 0xffffffff80100000 | 73 | #define __PHYSICAL_START CONFIG_PHYSICAL_START |
74 | #define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START) | ||
73 | #define __START_KERNEL_map 0xffffffff80000000 | 75 | #define __START_KERNEL_map 0xffffffff80000000 |
74 | #define __PAGE_OFFSET 0xffff810000000000 | 76 | #define __PAGE_OFFSET 0xffff810000000000 |
75 | #endif /* !__ASSEMBLY__ */ | 77 | #endif /* !__ASSEMBLY__ */ |
diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h index a7425aa5a3b7..aeb1b73e21e1 100644 --- a/include/asm-x86_64/smp.h +++ b/include/asm-x86_64/smp.h | |||
@@ -43,6 +43,8 @@ extern cpumask_t cpu_callout_map; | |||
43 | extern void smp_alloc_memory(void); | 43 | extern void smp_alloc_memory(void); |
44 | extern volatile unsigned long smp_invalidate_needed; | 44 | extern volatile unsigned long smp_invalidate_needed; |
45 | extern int pic_mode; | 45 | extern int pic_mode; |
46 | extern void lock_ipi_call_lock(void); | ||
47 | extern void unlock_ipi_call_lock(void); | ||
46 | extern int smp_num_siblings; | 48 | extern int smp_num_siblings; |
47 | extern void smp_flush_tlb(void); | 49 | extern void smp_flush_tlb(void); |
48 | extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs); | 50 | extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs); |
@@ -77,6 +79,8 @@ extern __inline int hard_smp_processor_id(void) | |||
77 | } | 79 | } |
78 | 80 | ||
79 | extern int safe_smp_processor_id(void); | 81 | extern int safe_smp_processor_id(void); |
82 | extern int __cpu_disable(void); | ||
83 | extern void __cpu_die(unsigned int cpu); | ||
80 | 84 | ||
81 | #endif /* !ASSEMBLY */ | 85 | #endif /* !ASSEMBLY */ |
82 | 86 | ||
diff --git a/include/asm-x86_64/suspend.h b/include/asm-x86_64/suspend.h index ec745807feae..bb9f40597d09 100644 --- a/include/asm-x86_64/suspend.h +++ b/include/asm-x86_64/suspend.h | |||
@@ -16,7 +16,7 @@ arch_prepare_suspend(void) | |||
16 | struct saved_context { | 16 | struct saved_context { |
17 | u16 ds, es, fs, gs, ss; | 17 | u16 ds, es, fs, gs, ss; |
18 | unsigned long gs_base, gs_kernel_base, fs_base; | 18 | unsigned long gs_base, gs_kernel_base, fs_base; |
19 | unsigned long cr0, cr2, cr3, cr4; | 19 | unsigned long cr0, cr2, cr3, cr4, cr8; |
20 | u16 gdt_pad; | 20 | u16 gdt_pad; |
21 | u16 gdt_limit; | 21 | u16 gdt_limit; |
22 | unsigned long gdt_base; | 22 | unsigned long gdt_base; |
diff --git a/include/asm-x86_64/topology.h b/include/asm-x86_64/topology.h index 8f77e9f6bc23..c1bc3fad482e 100644 --- a/include/asm-x86_64/topology.h +++ b/include/asm-x86_64/topology.h | |||
@@ -39,12 +39,16 @@ extern int __node_distance(int, int); | |||
39 | .busy_factor = 32, \ | 39 | .busy_factor = 32, \ |
40 | .imbalance_pct = 125, \ | 40 | .imbalance_pct = 125, \ |
41 | .cache_hot_time = (10*1000000), \ | 41 | .cache_hot_time = (10*1000000), \ |
42 | .cache_nice_tries = 1, \ | 42 | .cache_nice_tries = 2, \ |
43 | .busy_idx = 3, \ | ||
44 | .idle_idx = 2, \ | ||
45 | .newidle_idx = 0, \ | ||
46 | .wake_idx = 1, \ | ||
47 | .forkexec_idx = 1, \ | ||
43 | .per_cpu_gain = 100, \ | 48 | .per_cpu_gain = 100, \ |
44 | .flags = SD_LOAD_BALANCE \ | 49 | .flags = SD_LOAD_BALANCE \ |
45 | | SD_BALANCE_NEWIDLE \ | 50 | | SD_BALANCE_FORK \ |
46 | | SD_BALANCE_EXEC \ | 51 | | SD_BALANCE_EXEC \ |
47 | | SD_WAKE_IDLE \ | ||
48 | | SD_WAKE_BALANCE, \ | 52 | | SD_WAKE_BALANCE, \ |
49 | .last_balance = jiffies, \ | 53 | .last_balance = jiffies, \ |
50 | .balance_interval = 1, \ | 54 | .balance_interval = 1, \ |
diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h index 3c9af6fd4332..d767adcbf0ff 100644 --- a/include/asm-x86_64/unistd.h +++ b/include/asm-x86_64/unistd.h | |||
@@ -552,7 +552,7 @@ __SYSCALL(__NR_mq_notify, sys_mq_notify) | |||
552 | #define __NR_mq_getsetattr 245 | 552 | #define __NR_mq_getsetattr 245 |
553 | __SYSCALL(__NR_mq_getsetattr, sys_mq_getsetattr) | 553 | __SYSCALL(__NR_mq_getsetattr, sys_mq_getsetattr) |
554 | #define __NR_kexec_load 246 | 554 | #define __NR_kexec_load 246 |
555 | __SYSCALL(__NR_kexec_load, sys_ni_syscall) | 555 | __SYSCALL(__NR_kexec_load, sys_kexec_load) |
556 | #define __NR_waitid 247 | 556 | #define __NR_waitid 247 |
557 | __SYSCALL(__NR_waitid, sys_waitid) | 557 | __SYSCALL(__NR_waitid, sys_waitid) |
558 | #define __NR_add_key 248 | 558 | #define __NR_add_key 248 |
diff --git a/include/linux/a.out.h b/include/linux/a.out.h index af8a1dfa5c32..f913cc3e1b0d 100644 --- a/include/linux/a.out.h +++ b/include/linux/a.out.h | |||
@@ -138,7 +138,7 @@ enum machine_type { | |||
138 | #endif | 138 | #endif |
139 | #endif | 139 | #endif |
140 | 140 | ||
141 | #define _N_SEGMENT_ROUND(x) (((x) + SEGMENT_SIZE - 1) & ~(SEGMENT_SIZE - 1)) | 141 | #define _N_SEGMENT_ROUND(x) ALIGN(x, SEGMENT_SIZE) |
142 | 142 | ||
143 | #define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text) | 143 | #define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text) |
144 | 144 | ||
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 60272141ff19..b54a0348a890 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -539,15 +539,12 @@ extern void generic_make_request(struct bio *bio); | |||
539 | extern void blk_put_request(struct request *); | 539 | extern void blk_put_request(struct request *); |
540 | extern void blk_end_sync_rq(struct request *rq); | 540 | extern void blk_end_sync_rq(struct request *rq); |
541 | extern void blk_attempt_remerge(request_queue_t *, struct request *); | 541 | extern void blk_attempt_remerge(request_queue_t *, struct request *); |
542 | extern void __blk_attempt_remerge(request_queue_t *, struct request *); | ||
543 | extern struct request *blk_get_request(request_queue_t *, int, int); | 542 | extern struct request *blk_get_request(request_queue_t *, int, int); |
544 | extern void blk_insert_request(request_queue_t *, struct request *, int, void *); | 543 | extern void blk_insert_request(request_queue_t *, struct request *, int, void *); |
545 | extern void blk_requeue_request(request_queue_t *, struct request *); | 544 | extern void blk_requeue_request(request_queue_t *, struct request *); |
546 | extern void blk_plug_device(request_queue_t *); | 545 | extern void blk_plug_device(request_queue_t *); |
547 | extern int blk_remove_plug(request_queue_t *); | 546 | extern int blk_remove_plug(request_queue_t *); |
548 | extern void blk_recount_segments(request_queue_t *, struct bio *); | 547 | extern void blk_recount_segments(request_queue_t *, struct bio *); |
549 | extern int blk_phys_contig_segment(request_queue_t *q, struct bio *, struct bio *); | ||
550 | extern int blk_hw_contig_segment(request_queue_t *q, struct bio *, struct bio *); | ||
551 | extern int scsi_cmd_ioctl(struct file *, struct gendisk *, unsigned int, void __user *); | 548 | extern int scsi_cmd_ioctl(struct file *, struct gendisk *, unsigned int, void __user *); |
552 | extern void blk_start_queue(request_queue_t *q); | 549 | extern void blk_start_queue(request_queue_t *q); |
553 | extern void blk_stop_queue(request_queue_t *q); | 550 | extern void blk_stop_queue(request_queue_t *q); |
@@ -631,7 +628,6 @@ extern void blk_queue_dma_alignment(request_queue_t *, int); | |||
631 | extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev); | 628 | extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev); |
632 | extern void blk_queue_ordered(request_queue_t *, int); | 629 | extern void blk_queue_ordered(request_queue_t *, int); |
633 | extern void blk_queue_issue_flush_fn(request_queue_t *, issue_flush_fn *); | 630 | extern void blk_queue_issue_flush_fn(request_queue_t *, issue_flush_fn *); |
634 | extern int blkdev_scsi_issue_flush_fn(request_queue_t *, struct gendisk *, sector_t *); | ||
635 | extern struct request *blk_start_pre_flush(request_queue_t *,struct request *); | 631 | extern struct request *blk_start_pre_flush(request_queue_t *,struct request *); |
636 | extern int blk_complete_barrier_rq(request_queue_t *, struct request *, int); | 632 | extern int blk_complete_barrier_rq(request_queue_t *, struct request *, int); |
637 | extern int blk_complete_barrier_rq_locked(request_queue_t *, struct request *, int); | 633 | extern int blk_complete_barrier_rq_locked(request_queue_t *, struct request *, int); |
@@ -675,8 +671,6 @@ extern int blkdev_issue_flush(struct block_device *, sector_t *); | |||
675 | 671 | ||
676 | #define blkdev_entry_to_request(entry) list_entry((entry), struct request, queuelist) | 672 | #define blkdev_entry_to_request(entry) list_entry((entry), struct request, queuelist) |
677 | 673 | ||
678 | extern void drive_stat_acct(struct request *, int, int); | ||
679 | |||
680 | static inline int queue_hardsect_size(request_queue_t *q) | 674 | static inline int queue_hardsect_size(request_queue_t *q) |
681 | { | 675 | { |
682 | int retval = 512; | 676 | int retval = 512; |
diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h index 500f451ce0c0..82bd8842d11c 100644 --- a/include/linux/bootmem.h +++ b/include/linux/bootmem.h | |||
@@ -22,6 +22,10 @@ extern unsigned long min_low_pfn; | |||
22 | */ | 22 | */ |
23 | extern unsigned long max_pfn; | 23 | extern unsigned long max_pfn; |
24 | 24 | ||
25 | #ifdef CONFIG_CRASH_DUMP | ||
26 | extern unsigned long saved_max_pfn; | ||
27 | #endif | ||
28 | |||
25 | /* | 29 | /* |
26 | * node_bootmem_map is a map pointer - the bits represent all physical | 30 | * node_bootmem_map is a map pointer - the bits represent all physical |
27 | * memory pages (including holes) on the node. | 31 | * memory pages (including holes) on the node. |
diff --git a/include/linux/cpu.h b/include/linux/cpu.h index fe0298e5dae1..e8904c0da686 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h | |||
@@ -69,6 +69,7 @@ extern struct semaphore cpucontrol; | |||
69 | register_cpu_notifier(&fn##_nb); \ | 69 | register_cpu_notifier(&fn##_nb); \ |
70 | } | 70 | } |
71 | int cpu_down(unsigned int cpu); | 71 | int cpu_down(unsigned int cpu); |
72 | extern int __attribute__((weak)) smp_prepare_cpu(int cpu); | ||
72 | #define cpu_is_offline(cpu) unlikely(!cpu_online(cpu)) | 73 | #define cpu_is_offline(cpu) unlikely(!cpu_online(cpu)) |
73 | #else | 74 | #else |
74 | #define lock_cpu_hotplug() do { } while (0) | 75 | #define lock_cpu_hotplug() do { } while (0) |
diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h new file mode 100644 index 000000000000..534d750d922d --- /dev/null +++ b/include/linux/crash_dump.h | |||
@@ -0,0 +1,18 @@ | |||
1 | #ifndef LINUX_CRASH_DUMP_H | ||
2 | #define LINUX_CRASH_DUMP_H | ||
3 | |||
4 | #ifdef CONFIG_CRASH_DUMP | ||
5 | #include <linux/kexec.h> | ||
6 | #include <linux/smp_lock.h> | ||
7 | #include <linux/device.h> | ||
8 | #include <linux/proc_fs.h> | ||
9 | |||
10 | #define ELFCORE_ADDR_MAX (-1ULL) | ||
11 | extern unsigned long long elfcorehdr_addr; | ||
12 | extern ssize_t copy_oldmem_page(unsigned long, char *, size_t, | ||
13 | unsigned long, int); | ||
14 | extern struct file_operations proc_vmcore_operations; | ||
15 | extern struct proc_dir_entry *proc_vmcore; | ||
16 | |||
17 | #endif /* CONFIG_CRASH_DUMP */ | ||
18 | #endif /* LINUX_CRASHDUMP_H */ | ||
diff --git a/include/linux/dmi.h b/include/linux/dmi.h index d2bcf556088b..5e93e6dce9a4 100644 --- a/include/linux/dmi.h +++ b/include/linux/dmi.h | |||
@@ -9,6 +9,7 @@ enum dmi_field { | |||
9 | DMI_SYS_VENDOR, | 9 | DMI_SYS_VENDOR, |
10 | DMI_PRODUCT_NAME, | 10 | DMI_PRODUCT_NAME, |
11 | DMI_PRODUCT_VERSION, | 11 | DMI_PRODUCT_VERSION, |
12 | DMI_PRODUCT_SERIAL, | ||
12 | DMI_BOARD_VENDOR, | 13 | DMI_BOARD_VENDOR, |
13 | DMI_BOARD_NAME, | 14 | DMI_BOARD_NAME, |
14 | DMI_BOARD_VERSION, | 15 | DMI_BOARD_VERSION, |
diff --git a/include/linux/highmem.h b/include/linux/highmem.h index 2a7e6c65c882..6bece9280eb7 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h | |||
@@ -28,6 +28,7 @@ static inline void *kmap(struct page *page) | |||
28 | 28 | ||
29 | #define kmap_atomic(page, idx) page_address(page) | 29 | #define kmap_atomic(page, idx) page_address(page) |
30 | #define kunmap_atomic(addr, idx) do { } while (0) | 30 | #define kunmap_atomic(addr, idx) do { } while (0) |
31 | #define kmap_atomic_pfn(pfn, idx) page_address(pfn_to_page(pfn)) | ||
31 | #define kmap_atomic_to_page(ptr) virt_to_page(ptr) | 32 | #define kmap_atomic_to_page(ptr) virt_to_page(ptr) |
32 | 33 | ||
33 | #endif /* CONFIG_HIGHMEM */ | 34 | #endif /* CONFIG_HIGHMEM */ |
diff --git a/include/linux/init.h b/include/linux/init.h index 05c83e0521ca..59008c3826cf 100644 --- a/include/linux/init.h +++ b/include/linux/init.h | |||
@@ -229,6 +229,18 @@ void __init parse_early_param(void); | |||
229 | #define __devexitdata __exitdata | 229 | #define __devexitdata __exitdata |
230 | #endif | 230 | #endif |
231 | 231 | ||
232 | #ifdef CONFIG_HOTPLUG_CPU | ||
233 | #define __cpuinit | ||
234 | #define __cpuinitdata | ||
235 | #define __cpuexit | ||
236 | #define __cpuexitdata | ||
237 | #else | ||
238 | #define __cpuinit __init | ||
239 | #define __cpuinitdata __initdata | ||
240 | #define __cpuexit __exit | ||
241 | #define __cpuexitdata __exitdata | ||
242 | #endif | ||
243 | |||
232 | /* Functions marked as __devexit may be discarded at kernel link time, depending | 244 | /* Functions marked as __devexit may be discarded at kernel link time, depending |
233 | on config options. Newer versions of binutils detect references from | 245 | on config options. Newer versions of binutils detect references from |
234 | retained sections to discarded sections and flag an error. Pointers to | 246 | retained sections to discarded sections and flag an error. Pointers to |
diff --git a/include/linux/init_task.h b/include/linux/init_task.h index a6a8c1a38d5e..03206a425d7a 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h | |||
@@ -108,7 +108,6 @@ extern struct group_info init_groups; | |||
108 | .blocked = {{0}}, \ | 108 | .blocked = {{0}}, \ |
109 | .alloc_lock = SPIN_LOCK_UNLOCKED, \ | 109 | .alloc_lock = SPIN_LOCK_UNLOCKED, \ |
110 | .proc_lock = SPIN_LOCK_UNLOCKED, \ | 110 | .proc_lock = SPIN_LOCK_UNLOCKED, \ |
111 | .switch_lock = SPIN_LOCK_UNLOCKED, \ | ||
112 | .journal_info = NULL, \ | 111 | .journal_info = NULL, \ |
113 | .cpu_timers = INIT_CPU_TIMERS(tsk.cpu_timers), \ | 112 | .cpu_timers = INIT_CPU_TIMERS(tsk.cpu_timers), \ |
114 | } | 113 | } |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index e25b97062ce1..687ba8c9973d 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -58,15 +58,23 @@ struct completion; | |||
58 | * be biten later when the calling function happens to sleep when it is not | 58 | * be biten later when the calling function happens to sleep when it is not |
59 | * supposed to. | 59 | * supposed to. |
60 | */ | 60 | */ |
61 | #ifdef CONFIG_PREEMPT_VOLUNTARY | ||
62 | extern int cond_resched(void); | ||
63 | # define might_resched() cond_resched() | ||
64 | #else | ||
65 | # define might_resched() do { } while (0) | ||
66 | #endif | ||
67 | |||
61 | #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP | 68 | #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP |
62 | #define might_sleep() __might_sleep(__FILE__, __LINE__) | 69 | void __might_sleep(char *file, int line); |
63 | #define might_sleep_if(cond) do { if (unlikely(cond)) might_sleep(); } while (0) | 70 | # define might_sleep() \ |
64 | void __might_sleep(char *file, int line); | 71 | do { __might_sleep(__FILE__, __LINE__); might_resched(); } while (0) |
65 | #else | 72 | #else |
66 | #define might_sleep() do {} while(0) | 73 | # define might_sleep() do { might_resched(); } while (0) |
67 | #define might_sleep_if(cond) do {} while (0) | ||
68 | #endif | 74 | #endif |
69 | 75 | ||
76 | #define might_sleep_if(cond) do { if (unlikely(cond)) might_sleep(); } while (0) | ||
77 | |||
70 | #define abs(x) ({ \ | 78 | #define abs(x) ({ \ |
71 | int __x = (x); \ | 79 | int __x = (x); \ |
72 | (__x < 0) ? -__x : __x; \ | 80 | (__x < 0) ? -__x : __x; \ |
diff --git a/include/linux/kexec.h b/include/linux/kexec.h new file mode 100644 index 000000000000..c8468472aec0 --- /dev/null +++ b/include/linux/kexec.h | |||
@@ -0,0 +1,135 @@ | |||
1 | #ifndef LINUX_KEXEC_H | ||
2 | #define LINUX_KEXEC_H | ||
3 | |||
4 | #ifdef CONFIG_KEXEC | ||
5 | #include <linux/types.h> | ||
6 | #include <linux/list.h> | ||
7 | #include <linux/linkage.h> | ||
8 | #include <linux/compat.h> | ||
9 | #include <asm/kexec.h> | ||
10 | |||
11 | /* Verify architecture specific macros are defined */ | ||
12 | |||
13 | #ifndef KEXEC_SOURCE_MEMORY_LIMIT | ||
14 | #error KEXEC_SOURCE_MEMORY_LIMIT not defined | ||
15 | #endif | ||
16 | |||
17 | #ifndef KEXEC_DESTINATION_MEMORY_LIMIT | ||
18 | #error KEXEC_DESTINATION_MEMORY_LIMIT not defined | ||
19 | #endif | ||
20 | |||
21 | #ifndef KEXEC_CONTROL_MEMORY_LIMIT | ||
22 | #error KEXEC_CONTROL_MEMORY_LIMIT not defined | ||
23 | #endif | ||
24 | |||
25 | #ifndef KEXEC_CONTROL_CODE_SIZE | ||
26 | #error KEXEC_CONTROL_CODE_SIZE not defined | ||
27 | #endif | ||
28 | |||
29 | #ifndef KEXEC_ARCH | ||
30 | #error KEXEC_ARCH not defined | ||
31 | #endif | ||
32 | |||
33 | /* | ||
34 | * This structure is used to hold the arguments that are used when loading | ||
35 | * kernel binaries. | ||
36 | */ | ||
37 | |||
38 | typedef unsigned long kimage_entry_t; | ||
39 | #define IND_DESTINATION 0x1 | ||
40 | #define IND_INDIRECTION 0x2 | ||
41 | #define IND_DONE 0x4 | ||
42 | #define IND_SOURCE 0x8 | ||
43 | |||
44 | #define KEXEC_SEGMENT_MAX 8 | ||
45 | struct kexec_segment { | ||
46 | void __user *buf; | ||
47 | size_t bufsz; | ||
48 | unsigned long mem; /* User space sees this as a (void *) ... */ | ||
49 | size_t memsz; | ||
50 | }; | ||
51 | |||
52 | #ifdef CONFIG_COMPAT | ||
53 | struct compat_kexec_segment { | ||
54 | compat_uptr_t buf; | ||
55 | compat_size_t bufsz; | ||
56 | compat_ulong_t mem; /* User space sees this as a (void *) ... */ | ||
57 | compat_size_t memsz; | ||
58 | }; | ||
59 | #endif | ||
60 | |||
61 | struct kimage { | ||
62 | kimage_entry_t head; | ||
63 | kimage_entry_t *entry; | ||
64 | kimage_entry_t *last_entry; | ||
65 | |||
66 | unsigned long destination; | ||
67 | |||
68 | unsigned long start; | ||
69 | struct page *control_code_page; | ||
70 | |||
71 | unsigned long nr_segments; | ||
72 | struct kexec_segment segment[KEXEC_SEGMENT_MAX]; | ||
73 | |||
74 | struct list_head control_pages; | ||
75 | struct list_head dest_pages; | ||
76 | struct list_head unuseable_pages; | ||
77 | |||
78 | /* Address of next control page to allocate for crash kernels. */ | ||
79 | unsigned long control_page; | ||
80 | |||
81 | /* Flags to indicate special processing */ | ||
82 | unsigned int type : 1; | ||
83 | #define KEXEC_TYPE_DEFAULT 0 | ||
84 | #define KEXEC_TYPE_CRASH 1 | ||
85 | }; | ||
86 | |||
87 | |||
88 | |||
89 | /* kexec interface functions */ | ||
90 | extern NORET_TYPE void machine_kexec(struct kimage *image) ATTRIB_NORET; | ||
91 | extern int machine_kexec_prepare(struct kimage *image); | ||
92 | extern void machine_kexec_cleanup(struct kimage *image); | ||
93 | extern asmlinkage long sys_kexec_load(unsigned long entry, | ||
94 | unsigned long nr_segments, | ||
95 | struct kexec_segment __user *segments, | ||
96 | unsigned long flags); | ||
97 | #ifdef CONFIG_COMPAT | ||
98 | extern asmlinkage long compat_sys_kexec_load(unsigned long entry, | ||
99 | unsigned long nr_segments, | ||
100 | struct compat_kexec_segment __user *segments, | ||
101 | unsigned long flags); | ||
102 | #endif | ||
103 | extern struct page *kimage_alloc_control_pages(struct kimage *image, | ||
104 | unsigned int order); | ||
105 | extern void crash_kexec(struct pt_regs *); | ||
106 | int kexec_should_crash(struct task_struct *); | ||
107 | extern struct kimage *kexec_image; | ||
108 | |||
109 | #define KEXEC_ON_CRASH 0x00000001 | ||
110 | #define KEXEC_ARCH_MASK 0xffff0000 | ||
111 | |||
112 | /* These values match the ELF architecture values. | ||
113 | * Unless there is a good reason that should continue to be the case. | ||
114 | */ | ||
115 | #define KEXEC_ARCH_DEFAULT ( 0 << 16) | ||
116 | #define KEXEC_ARCH_386 ( 3 << 16) | ||
117 | #define KEXEC_ARCH_X86_64 (62 << 16) | ||
118 | #define KEXEC_ARCH_PPC (20 << 16) | ||
119 | #define KEXEC_ARCH_PPC64 (21 << 16) | ||
120 | #define KEXEC_ARCH_IA_64 (50 << 16) | ||
121 | #define KEXEC_ARCH_S390 (22 << 16) | ||
122 | |||
123 | #define KEXEC_FLAGS (KEXEC_ON_CRASH) /* List of defined/legal kexec flags */ | ||
124 | |||
125 | /* Location of a reserved region to hold the crash kernel. | ||
126 | */ | ||
127 | extern struct resource crashk_res; | ||
128 | |||
129 | #else /* !CONFIG_KEXEC */ | ||
130 | struct pt_regs; | ||
131 | struct task_struct; | ||
132 | static inline void crash_kexec(struct pt_regs *regs) { } | ||
133 | static inline int kexec_should_crash(struct task_struct *p) { return 0; } | ||
134 | #endif /* CONFIG_KEXEC */ | ||
135 | #endif /* LINUX_KEXEC_H */ | ||
diff --git a/include/linux/list.h b/include/linux/list.h index 399b51d17218..aab2db21b013 100644 --- a/include/linux/list.h +++ b/include/linux/list.h | |||
@@ -185,7 +185,7 @@ static inline void list_del(struct list_head *entry) | |||
185 | * list_for_each_entry_rcu(). | 185 | * list_for_each_entry_rcu(). |
186 | * | 186 | * |
187 | * Note that the caller is not permitted to immediately free | 187 | * Note that the caller is not permitted to immediately free |
188 | * the newly deleted entry. Instead, either synchronize_kernel() | 188 | * the newly deleted entry. Instead, either synchronize_rcu() |
189 | * or call_rcu() must be used to defer freeing until an RCU | 189 | * or call_rcu() must be used to defer freeing until an RCU |
190 | * grace period has elapsed. | 190 | * grace period has elapsed. |
191 | */ | 191 | */ |
diff --git a/include/linux/nvram.h b/include/linux/nvram.h index b031e41b5e0d..9189829c131c 100644 --- a/include/linux/nvram.h +++ b/include/linux/nvram.h | |||
@@ -20,8 +20,6 @@ extern void __nvram_write_byte(unsigned char c, int i); | |||
20 | extern void nvram_write_byte(unsigned char c, int i); | 20 | extern void nvram_write_byte(unsigned char c, int i); |
21 | extern int __nvram_check_checksum(void); | 21 | extern int __nvram_check_checksum(void); |
22 | extern int nvram_check_checksum(void); | 22 | extern int nvram_check_checksum(void); |
23 | extern void __nvram_set_checksum(void); | ||
24 | extern void nvram_set_checksum(void); | ||
25 | #endif | 23 | #endif |
26 | 24 | ||
27 | #endif /* _LINUX_NVRAM_H */ | 25 | #endif /* _LINUX_NVRAM_H */ |
diff --git a/include/linux/pm.h b/include/linux/pm.h index ed2b76e75199..14479325e3f3 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h | |||
@@ -103,7 +103,8 @@ extern int pm_active; | |||
103 | /* | 103 | /* |
104 | * Register a device with power management | 104 | * Register a device with power management |
105 | */ | 105 | */ |
106 | struct pm_dev __deprecated *pm_register(pm_dev_t type, unsigned long id, pm_callback callback); | 106 | struct pm_dev __deprecated * |
107 | pm_register(pm_dev_t type, unsigned long id, pm_callback callback); | ||
107 | 108 | ||
108 | /* | 109 | /* |
109 | * Unregister a device with power management | 110 | * Unregister a device with power management |
@@ -190,17 +191,18 @@ typedef u32 __bitwise pm_message_t; | |||
190 | /* | 191 | /* |
191 | * There are 4 important states driver can be in: | 192 | * There are 4 important states driver can be in: |
192 | * ON -- driver is working | 193 | * ON -- driver is working |
193 | * FREEZE -- stop operations and apply whatever policy is applicable to a suspended driver | 194 | * FREEZE -- stop operations and apply whatever policy is applicable to a |
194 | * of that class, freeze queues for block like IDE does, drop packets for | 195 | * suspended driver of that class, freeze queues for block like IDE |
195 | * ethernet, etc... stop DMA engine too etc... so a consistent image can be | 196 | * does, drop packets for ethernet, etc... stop DMA engine too etc... |
196 | * saved; but do not power any hardware down. | 197 | * so a consistent image can be saved; but do not power any hardware |
197 | * SUSPEND - like FREEZE, but hardware is doing as much powersaving as possible. Roughly | 198 | * down. |
198 | * pci D3. | 199 | * SUSPEND - like FREEZE, but hardware is doing as much powersaving as |
200 | * possible. Roughly pci D3. | ||
199 | * | 201 | * |
200 | * Unfortunately, current drivers only recognize numeric values 0 (ON) and 3 (SUSPEND). | 202 | * Unfortunately, current drivers only recognize numeric values 0 (ON) and 3 |
201 | * We'll need to fix the drivers. So yes, putting 3 to all diferent defines is intentional, | 203 | * (SUSPEND). We'll need to fix the drivers. So yes, putting 3 to all different |
202 | * and will go away as soon as drivers are fixed. Also note that typedef is neccessary, | 204 | * defines is intentional, and will go away as soon as drivers are fixed. Also |
203 | * we'll probably want to switch to | 205 | * note that typedef is neccessary, we'll probably want to switch to |
204 | * typedef struct pm_message_t { int event; int flags; } pm_message_t | 206 | * typedef struct pm_message_t { int event; int flags; } pm_message_t |
205 | * or something similar soon. | 207 | * or something similar soon. |
206 | */ | 208 | */ |
@@ -222,11 +224,18 @@ struct dev_pm_info { | |||
222 | 224 | ||
223 | extern void device_pm_set_parent(struct device * dev, struct device * parent); | 225 | extern void device_pm_set_parent(struct device * dev, struct device * parent); |
224 | 226 | ||
225 | extern int device_suspend(pm_message_t state); | ||
226 | extern int device_power_down(pm_message_t state); | 227 | extern int device_power_down(pm_message_t state); |
227 | extern void device_power_up(void); | 228 | extern void device_power_up(void); |
228 | extern void device_resume(void); | 229 | extern void device_resume(void); |
229 | 230 | ||
231 | #ifdef CONFIG_PM | ||
232 | extern int device_suspend(pm_message_t state); | ||
233 | #else | ||
234 | static inline int device_suspend(pm_message_t state) | ||
235 | { | ||
236 | return 0; | ||
237 | } | ||
238 | #endif | ||
230 | 239 | ||
231 | #endif /* __KERNEL__ */ | 240 | #endif /* __KERNEL__ */ |
232 | 241 | ||
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 59e505261fd6..0563581e3a02 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h | |||
@@ -74,6 +74,13 @@ struct kcore_list { | |||
74 | size_t size; | 74 | size_t size; |
75 | }; | 75 | }; |
76 | 76 | ||
77 | struct vmcore { | ||
78 | struct list_head list; | ||
79 | unsigned long long paddr; | ||
80 | unsigned long size; | ||
81 | loff_t offset; | ||
82 | }; | ||
83 | |||
77 | #ifdef CONFIG_PROC_FS | 84 | #ifdef CONFIG_PROC_FS |
78 | 85 | ||
79 | extern struct proc_dir_entry proc_root; | 86 | extern struct proc_dir_entry proc_root; |
diff --git a/include/linux/reboot.h b/include/linux/reboot.h index d60fafc8bdc5..2d4dd23168dd 100644 --- a/include/linux/reboot.h +++ b/include/linux/reboot.h | |||
@@ -51,6 +51,10 @@ extern void machine_restart(char *cmd); | |||
51 | extern void machine_halt(void); | 51 | extern void machine_halt(void); |
52 | extern void machine_power_off(void); | 52 | extern void machine_power_off(void); |
53 | 53 | ||
54 | extern void machine_shutdown(void); | ||
55 | struct pt_regs; | ||
56 | extern void machine_crash_shutdown(struct pt_regs *); | ||
57 | |||
54 | #endif | 58 | #endif |
55 | 59 | ||
56 | #endif /* _LINUX_REBOOT_H */ | 60 | #endif /* _LINUX_REBOOT_H */ |
diff --git a/include/linux/sched.h b/include/linux/sched.h index e7fd09b0557f..9530b1903160 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -368,6 +368,11 @@ struct signal_struct { | |||
368 | #endif | 368 | #endif |
369 | }; | 369 | }; |
370 | 370 | ||
371 | /* Context switch must be unlocked if interrupts are to be enabled */ | ||
372 | #ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW | ||
373 | # define __ARCH_WANT_UNLOCKED_CTXSW | ||
374 | #endif | ||
375 | |||
371 | /* | 376 | /* |
372 | * Bits in flags field of signal_struct. | 377 | * Bits in flags field of signal_struct. |
373 | */ | 378 | */ |
@@ -460,10 +465,11 @@ enum idle_type | |||
460 | #define SD_LOAD_BALANCE 1 /* Do load balancing on this domain. */ | 465 | #define SD_LOAD_BALANCE 1 /* Do load balancing on this domain. */ |
461 | #define SD_BALANCE_NEWIDLE 2 /* Balance when about to become idle */ | 466 | #define SD_BALANCE_NEWIDLE 2 /* Balance when about to become idle */ |
462 | #define SD_BALANCE_EXEC 4 /* Balance on exec */ | 467 | #define SD_BALANCE_EXEC 4 /* Balance on exec */ |
463 | #define SD_WAKE_IDLE 8 /* Wake to idle CPU on task wakeup */ | 468 | #define SD_BALANCE_FORK 8 /* Balance on fork, clone */ |
464 | #define SD_WAKE_AFFINE 16 /* Wake task to waking CPU */ | 469 | #define SD_WAKE_IDLE 16 /* Wake to idle CPU on task wakeup */ |
465 | #define SD_WAKE_BALANCE 32 /* Perform balancing at task wakeup */ | 470 | #define SD_WAKE_AFFINE 32 /* Wake task to waking CPU */ |
466 | #define SD_SHARE_CPUPOWER 64 /* Domain members share cpu power */ | 471 | #define SD_WAKE_BALANCE 64 /* Perform balancing at task wakeup */ |
472 | #define SD_SHARE_CPUPOWER 128 /* Domain members share cpu power */ | ||
467 | 473 | ||
468 | struct sched_group { | 474 | struct sched_group { |
469 | struct sched_group *next; /* Must be a circular list */ | 475 | struct sched_group *next; /* Must be a circular list */ |
@@ -488,6 +494,11 @@ struct sched_domain { | |||
488 | unsigned long long cache_hot_time; /* Task considered cache hot (ns) */ | 494 | unsigned long long cache_hot_time; /* Task considered cache hot (ns) */ |
489 | unsigned int cache_nice_tries; /* Leave cache hot tasks for # tries */ | 495 | unsigned int cache_nice_tries; /* Leave cache hot tasks for # tries */ |
490 | unsigned int per_cpu_gain; /* CPU % gained by adding domain cpus */ | 496 | unsigned int per_cpu_gain; /* CPU % gained by adding domain cpus */ |
497 | unsigned int busy_idx; | ||
498 | unsigned int idle_idx; | ||
499 | unsigned int newidle_idx; | ||
500 | unsigned int wake_idx; | ||
501 | unsigned int forkexec_idx; | ||
491 | int flags; /* See SD_* */ | 502 | int flags; /* See SD_* */ |
492 | 503 | ||
493 | /* Runtime fields. */ | 504 | /* Runtime fields. */ |
@@ -511,10 +522,16 @@ struct sched_domain { | |||
511 | unsigned long alb_failed; | 522 | unsigned long alb_failed; |
512 | unsigned long alb_pushed; | 523 | unsigned long alb_pushed; |
513 | 524 | ||
514 | /* sched_balance_exec() stats */ | 525 | /* SD_BALANCE_EXEC stats */ |
515 | unsigned long sbe_attempts; | 526 | unsigned long sbe_cnt; |
527 | unsigned long sbe_balanced; | ||
516 | unsigned long sbe_pushed; | 528 | unsigned long sbe_pushed; |
517 | 529 | ||
530 | /* SD_BALANCE_FORK stats */ | ||
531 | unsigned long sbf_cnt; | ||
532 | unsigned long sbf_balanced; | ||
533 | unsigned long sbf_pushed; | ||
534 | |||
518 | /* try_to_wake_up() stats */ | 535 | /* try_to_wake_up() stats */ |
519 | unsigned long ttwu_wake_remote; | 536 | unsigned long ttwu_wake_remote; |
520 | unsigned long ttwu_move_affine; | 537 | unsigned long ttwu_move_affine; |
@@ -522,6 +539,8 @@ struct sched_domain { | |||
522 | #endif | 539 | #endif |
523 | }; | 540 | }; |
524 | 541 | ||
542 | extern void partition_sched_domains(cpumask_t *partition1, | ||
543 | cpumask_t *partition2); | ||
525 | #ifdef ARCH_HAS_SCHED_DOMAIN | 544 | #ifdef ARCH_HAS_SCHED_DOMAIN |
526 | /* Useful helpers that arch setup code may use. Defined in kernel/sched.c */ | 545 | /* Useful helpers that arch setup code may use. Defined in kernel/sched.c */ |
527 | extern cpumask_t cpu_isolated_map; | 546 | extern cpumask_t cpu_isolated_map; |
@@ -582,6 +601,9 @@ struct task_struct { | |||
582 | 601 | ||
583 | int lock_depth; /* BKL lock depth */ | 602 | int lock_depth; /* BKL lock depth */ |
584 | 603 | ||
604 | #if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW) | ||
605 | int oncpu; | ||
606 | #endif | ||
585 | int prio, static_prio; | 607 | int prio, static_prio; |
586 | struct list_head run_list; | 608 | struct list_head run_list; |
587 | prio_array_t *array; | 609 | prio_array_t *array; |
@@ -704,8 +726,6 @@ struct task_struct { | |||
704 | spinlock_t alloc_lock; | 726 | spinlock_t alloc_lock; |
705 | /* Protection of proc_dentry: nesting proc_lock, dcache_lock, write_lock_irq(&tasklist_lock); */ | 727 | /* Protection of proc_dentry: nesting proc_lock, dcache_lock, write_lock_irq(&tasklist_lock); */ |
706 | spinlock_t proc_lock; | 728 | spinlock_t proc_lock; |
707 | /* context-switch lock */ | ||
708 | spinlock_t switch_lock; | ||
709 | 729 | ||
710 | /* journalling filesystem info */ | 730 | /* journalling filesystem info */ |
711 | void *journal_info; | 731 | void *journal_info; |
@@ -912,7 +932,7 @@ extern void FASTCALL(wake_up_new_task(struct task_struct * tsk, | |||
912 | #else | 932 | #else |
913 | static inline void kick_process(struct task_struct *tsk) { } | 933 | static inline void kick_process(struct task_struct *tsk) { } |
914 | #endif | 934 | #endif |
915 | extern void FASTCALL(sched_fork(task_t * p)); | 935 | extern void FASTCALL(sched_fork(task_t * p, int clone_flags)); |
916 | extern void FASTCALL(sched_exit(task_t * p)); | 936 | extern void FASTCALL(sched_exit(task_t * p)); |
917 | 937 | ||
918 | extern int in_group_p(gid_t); | 938 | extern int in_group_p(gid_t); |
diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 2bf0d5fabcdb..f2e96fdfaae0 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h | |||
@@ -58,7 +58,7 @@ static inline int software_suspend(void) | |||
58 | } | 58 | } |
59 | #endif | 59 | #endif |
60 | 60 | ||
61 | #ifdef CONFIG_SMP | 61 | #ifdef CONFIG_SUSPEND_SMP |
62 | extern void disable_nonboot_cpus(void); | 62 | extern void disable_nonboot_cpus(void); |
63 | extern void enable_nonboot_cpus(void); | 63 | extern void enable_nonboot_cpus(void); |
64 | #else | 64 | #else |
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index c39f6f72cbbc..52830b6d94e5 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
@@ -159,8 +159,9 @@ asmlinkage long sys_shutdown(int, int); | |||
159 | asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, | 159 | asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, |
160 | void __user *arg); | 160 | void __user *arg); |
161 | asmlinkage long sys_restart_syscall(void); | 161 | asmlinkage long sys_restart_syscall(void); |
162 | asmlinkage long sys_kexec_load(void *entry, unsigned long nr_segments, | 162 | asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments, |
163 | struct kexec_segment *segments, unsigned long flags); | 163 | struct kexec_segment __user *segments, |
164 | unsigned long flags); | ||
164 | 165 | ||
165 | asmlinkage long sys_exit(int error_code); | 166 | asmlinkage long sys_exit(int error_code); |
166 | asmlinkage void sys_exit_group(int error_code); | 167 | asmlinkage void sys_exit_group(int error_code); |
diff --git a/include/linux/topology.h b/include/linux/topology.h index d70e8972c67f..0320225e96da 100644 --- a/include/linux/topology.h +++ b/include/linux/topology.h | |||
@@ -89,6 +89,11 @@ | |||
89 | .cache_hot_time = 0, \ | 89 | .cache_hot_time = 0, \ |
90 | .cache_nice_tries = 0, \ | 90 | .cache_nice_tries = 0, \ |
91 | .per_cpu_gain = 25, \ | 91 | .per_cpu_gain = 25, \ |
92 | .busy_idx = 0, \ | ||
93 | .idle_idx = 0, \ | ||
94 | .newidle_idx = 1, \ | ||
95 | .wake_idx = 0, \ | ||
96 | .forkexec_idx = 0, \ | ||
92 | .flags = SD_LOAD_BALANCE \ | 97 | .flags = SD_LOAD_BALANCE \ |
93 | | SD_BALANCE_NEWIDLE \ | 98 | | SD_BALANCE_NEWIDLE \ |
94 | | SD_BALANCE_EXEC \ | 99 | | SD_BALANCE_EXEC \ |
@@ -115,12 +120,15 @@ | |||
115 | .cache_hot_time = (5*1000000/2), \ | 120 | .cache_hot_time = (5*1000000/2), \ |
116 | .cache_nice_tries = 1, \ | 121 | .cache_nice_tries = 1, \ |
117 | .per_cpu_gain = 100, \ | 122 | .per_cpu_gain = 100, \ |
123 | .busy_idx = 2, \ | ||
124 | .idle_idx = 1, \ | ||
125 | .newidle_idx = 2, \ | ||
126 | .wake_idx = 1, \ | ||
127 | .forkexec_idx = 1, \ | ||
118 | .flags = SD_LOAD_BALANCE \ | 128 | .flags = SD_LOAD_BALANCE \ |
119 | | SD_BALANCE_NEWIDLE \ | 129 | | SD_BALANCE_NEWIDLE \ |
120 | | SD_BALANCE_EXEC \ | 130 | | SD_BALANCE_EXEC \ |
121 | | SD_WAKE_AFFINE \ | 131 | | SD_WAKE_AFFINE, \ |
122 | | SD_WAKE_IDLE \ | ||
123 | | SD_WAKE_BALANCE, \ | ||
124 | .last_balance = jiffies, \ | 132 | .last_balance = jiffies, \ |
125 | .balance_interval = 1, \ | 133 | .balance_interval = 1, \ |
126 | .nr_balance_failed = 0, \ | 134 | .nr_balance_failed = 0, \ |
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index 07e7d31f2d0b..4def882d0b31 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c | |||
@@ -41,7 +41,7 @@ static int __init do_linuxrc(void * shell) | |||
41 | static void __init handle_initrd(void) | 41 | static void __init handle_initrd(void) |
42 | { | 42 | { |
43 | int error; | 43 | int error; |
44 | int i, pid; | 44 | int pid; |
45 | 45 | ||
46 | real_root_dev = new_encode_dev(ROOT_DEV); | 46 | real_root_dev = new_encode_dev(ROOT_DEV); |
47 | create_dev("/dev/root.old", Root_RAM0, NULL); | 47 | create_dev("/dev/root.old", Root_RAM0, NULL); |
@@ -58,7 +58,7 @@ static void __init handle_initrd(void) | |||
58 | 58 | ||
59 | pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD); | 59 | pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD); |
60 | if (pid > 0) { | 60 | if (pid > 0) { |
61 | while (pid != sys_wait4(-1, &i, 0, NULL)) | 61 | while (pid != sys_wait4(-1, NULL, 0, NULL)) |
62 | yield(); | 62 | yield(); |
63 | } | 63 | } |
64 | 64 | ||
diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt new file mode 100644 index 000000000000..0b46a5dff4c0 --- /dev/null +++ b/kernel/Kconfig.preempt | |||
@@ -0,0 +1,65 @@ | |||
1 | |||
2 | choice | ||
3 | prompt "Preemption Model" | ||
4 | default PREEMPT_NONE | ||
5 | |||
6 | config PREEMPT_NONE | ||
7 | bool "No Forced Preemption (Server)" | ||
8 | help | ||
9 | This is the traditional Linux preemption model, geared towards | ||
10 | throughput. It will still provide good latencies most of the | ||
11 | time, but there are no guarantees and occasional longer delays | ||
12 | are possible. | ||
13 | |||
14 | Select this option if you are building a kernel for a server or | ||
15 | scientific/computation system, or if you want to maximize the | ||
16 | raw processing power of the kernel, irrespective of scheduling | ||
17 | latencies. | ||
18 | |||
19 | config PREEMPT_VOLUNTARY | ||
20 | bool "Voluntary Kernel Preemption (Desktop)" | ||
21 | help | ||
22 | This option reduces the latency of the kernel by adding more | ||
23 | "explicit preemption points" to the kernel code. These new | ||
24 | preemption points have been selected to reduce the maximum | ||
25 | latency of rescheduling, providing faster application reactions, | ||
26 | at the cost of slighly lower throughput. | ||
27 | |||
28 | This allows reaction to interactive events by allowing a | ||
29 | low priority process to voluntarily preempt itself even if it | ||
30 | is in kernel mode executing a system call. This allows | ||
31 | applications to run more 'smoothly' even when the system is | ||
32 | under load. | ||
33 | |||
34 | Select this if you are building a kernel for a desktop system. | ||
35 | |||
36 | config PREEMPT | ||
37 | bool "Preemptible Kernel (Low-Latency Desktop)" | ||
38 | help | ||
39 | This option reduces the latency of the kernel by making | ||
40 | all kernel code (that is not executing in a critical section) | ||
41 | preemptible. This allows reaction to interactive events by | ||
42 | permitting a low priority process to be preempted involuntarily | ||
43 | even if it is in kernel mode executing a system call and would | ||
44 | otherwise not be about to reach a natural preemption point. | ||
45 | This allows applications to run more 'smoothly' even when the | ||
46 | system is under load, at the cost of slighly lower throughput | ||
47 | and a slight runtime overhead to kernel code. | ||
48 | |||
49 | Select this if you are building a kernel for a desktop or | ||
50 | embedded system with latency requirements in the milliseconds | ||
51 | range. | ||
52 | |||
53 | endchoice | ||
54 | |||
55 | config PREEMPT_BKL | ||
56 | bool "Preempt The Big Kernel Lock" | ||
57 | depends on SMP || PREEMPT | ||
58 | default y | ||
59 | help | ||
60 | This option reduces the latency of the kernel by making the | ||
61 | big kernel lock preemptible. | ||
62 | |||
63 | Say Y here if you are building a kernel for a desktop system. | ||
64 | Say N if you are unsure. | ||
65 | |||
diff --git a/kernel/Makefile b/kernel/Makefile index b01d26fe8db7..cb05cd05d237 100644 --- a/kernel/Makefile +++ b/kernel/Makefile | |||
@@ -17,6 +17,7 @@ obj-$(CONFIG_MODULES) += module.o | |||
17 | obj-$(CONFIG_KALLSYMS) += kallsyms.o | 17 | obj-$(CONFIG_KALLSYMS) += kallsyms.o |
18 | obj-$(CONFIG_PM) += power/ | 18 | obj-$(CONFIG_PM) += power/ |
19 | obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o | 19 | obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o |
20 | obj-$(CONFIG_KEXEC) += kexec.o | ||
20 | obj-$(CONFIG_COMPAT) += compat.o | 21 | obj-$(CONFIG_COMPAT) += compat.o |
21 | obj-$(CONFIG_CPUSETS) += cpuset.o | 22 | obj-$(CONFIG_CPUSETS) += cpuset.o |
22 | obj-$(CONFIG_IKCONFIG) += configs.o | 23 | obj-$(CONFIG_IKCONFIG) += configs.o |
@@ -27,6 +28,7 @@ obj-$(CONFIG_AUDITSYSCALL) += auditsc.o | |||
27 | obj-$(CONFIG_KPROBES) += kprobes.o | 28 | obj-$(CONFIG_KPROBES) += kprobes.o |
28 | obj-$(CONFIG_SYSFS) += ksysfs.o | 29 | obj-$(CONFIG_SYSFS) += ksysfs.o |
29 | obj-$(CONFIG_GENERIC_HARDIRQS) += irq/ | 30 | obj-$(CONFIG_GENERIC_HARDIRQS) += irq/ |
31 | obj-$(CONFIG_CRASH_DUMP) += crash_dump.o | ||
30 | obj-$(CONFIG_SECCOMP) += seccomp.o | 32 | obj-$(CONFIG_SECCOMP) += seccomp.o |
31 | 33 | ||
32 | ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y) | 34 | ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y) |
diff --git a/kernel/cpu.c b/kernel/cpu.c index 628f4ccda127..53d8263ae12e 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
@@ -63,19 +63,15 @@ static int take_cpu_down(void *unused) | |||
63 | { | 63 | { |
64 | int err; | 64 | int err; |
65 | 65 | ||
66 | /* Take offline: makes arch_cpu_down somewhat easier. */ | ||
67 | cpu_clear(smp_processor_id(), cpu_online_map); | ||
68 | |||
69 | /* Ensure this CPU doesn't handle any more interrupts. */ | 66 | /* Ensure this CPU doesn't handle any more interrupts. */ |
70 | err = __cpu_disable(); | 67 | err = __cpu_disable(); |
71 | if (err < 0) | 68 | if (err < 0) |
72 | cpu_set(smp_processor_id(), cpu_online_map); | 69 | return err; |
73 | else | ||
74 | /* Force idle task to run as soon as we yield: it should | ||
75 | immediately notice cpu is offline and die quickly. */ | ||
76 | sched_idle_next(); | ||
77 | 70 | ||
78 | return err; | 71 | /* Force idle task to run as soon as we yield: it should |
72 | immediately notice cpu is offline and die quickly. */ | ||
73 | sched_idle_next(); | ||
74 | return 0; | ||
79 | } | 75 | } |
80 | 76 | ||
81 | int cpu_down(unsigned int cpu) | 77 | int cpu_down(unsigned int cpu) |
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 79dd929f4084..984c0bf3807f 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
@@ -595,10 +595,62 @@ static int validate_change(const struct cpuset *cur, const struct cpuset *trial) | |||
595 | return 0; | 595 | return 0; |
596 | } | 596 | } |
597 | 597 | ||
598 | /* | ||
599 | * For a given cpuset cur, partition the system as follows | ||
600 | * a. All cpus in the parent cpuset's cpus_allowed that are not part of any | ||
601 | * exclusive child cpusets | ||
602 | * b. All cpus in the current cpuset's cpus_allowed that are not part of any | ||
603 | * exclusive child cpusets | ||
604 | * Build these two partitions by calling partition_sched_domains | ||
605 | * | ||
606 | * Call with cpuset_sem held. May nest a call to the | ||
607 | * lock_cpu_hotplug()/unlock_cpu_hotplug() pair. | ||
608 | */ | ||
609 | static void update_cpu_domains(struct cpuset *cur) | ||
610 | { | ||
611 | struct cpuset *c, *par = cur->parent; | ||
612 | cpumask_t pspan, cspan; | ||
613 | |||
614 | if (par == NULL || cpus_empty(cur->cpus_allowed)) | ||
615 | return; | ||
616 | |||
617 | /* | ||
618 | * Get all cpus from parent's cpus_allowed not part of exclusive | ||
619 | * children | ||
620 | */ | ||
621 | pspan = par->cpus_allowed; | ||
622 | list_for_each_entry(c, &par->children, sibling) { | ||
623 | if (is_cpu_exclusive(c)) | ||
624 | cpus_andnot(pspan, pspan, c->cpus_allowed); | ||
625 | } | ||
626 | if (is_removed(cur) || !is_cpu_exclusive(cur)) { | ||
627 | cpus_or(pspan, pspan, cur->cpus_allowed); | ||
628 | if (cpus_equal(pspan, cur->cpus_allowed)) | ||
629 | return; | ||
630 | cspan = CPU_MASK_NONE; | ||
631 | } else { | ||
632 | if (cpus_empty(pspan)) | ||
633 | return; | ||
634 | cspan = cur->cpus_allowed; | ||
635 | /* | ||
636 | * Get all cpus from current cpuset's cpus_allowed not part | ||
637 | * of exclusive children | ||
638 | */ | ||
639 | list_for_each_entry(c, &cur->children, sibling) { | ||
640 | if (is_cpu_exclusive(c)) | ||
641 | cpus_andnot(cspan, cspan, c->cpus_allowed); | ||
642 | } | ||
643 | } | ||
644 | |||
645 | lock_cpu_hotplug(); | ||
646 | partition_sched_domains(&pspan, &cspan); | ||
647 | unlock_cpu_hotplug(); | ||
648 | } | ||
649 | |||
598 | static int update_cpumask(struct cpuset *cs, char *buf) | 650 | static int update_cpumask(struct cpuset *cs, char *buf) |
599 | { | 651 | { |
600 | struct cpuset trialcs; | 652 | struct cpuset trialcs; |
601 | int retval; | 653 | int retval, cpus_unchanged; |
602 | 654 | ||
603 | trialcs = *cs; | 655 | trialcs = *cs; |
604 | retval = cpulist_parse(buf, trialcs.cpus_allowed); | 656 | retval = cpulist_parse(buf, trialcs.cpus_allowed); |
@@ -608,9 +660,13 @@ static int update_cpumask(struct cpuset *cs, char *buf) | |||
608 | if (cpus_empty(trialcs.cpus_allowed)) | 660 | if (cpus_empty(trialcs.cpus_allowed)) |
609 | return -ENOSPC; | 661 | return -ENOSPC; |
610 | retval = validate_change(cs, &trialcs); | 662 | retval = validate_change(cs, &trialcs); |
611 | if (retval == 0) | 663 | if (retval < 0) |
612 | cs->cpus_allowed = trialcs.cpus_allowed; | 664 | return retval; |
613 | return retval; | 665 | cpus_unchanged = cpus_equal(cs->cpus_allowed, trialcs.cpus_allowed); |
666 | cs->cpus_allowed = trialcs.cpus_allowed; | ||
667 | if (is_cpu_exclusive(cs) && !cpus_unchanged) | ||
668 | update_cpu_domains(cs); | ||
669 | return 0; | ||
614 | } | 670 | } |
615 | 671 | ||
616 | static int update_nodemask(struct cpuset *cs, char *buf) | 672 | static int update_nodemask(struct cpuset *cs, char *buf) |
@@ -646,7 +702,7 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf) | |||
646 | { | 702 | { |
647 | int turning_on; | 703 | int turning_on; |
648 | struct cpuset trialcs; | 704 | struct cpuset trialcs; |
649 | int err; | 705 | int err, cpu_exclusive_changed; |
650 | 706 | ||
651 | turning_on = (simple_strtoul(buf, NULL, 10) != 0); | 707 | turning_on = (simple_strtoul(buf, NULL, 10) != 0); |
652 | 708 | ||
@@ -657,13 +713,18 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf) | |||
657 | clear_bit(bit, &trialcs.flags); | 713 | clear_bit(bit, &trialcs.flags); |
658 | 714 | ||
659 | err = validate_change(cs, &trialcs); | 715 | err = validate_change(cs, &trialcs); |
660 | if (err == 0) { | 716 | if (err < 0) |
661 | if (turning_on) | 717 | return err; |
662 | set_bit(bit, &cs->flags); | 718 | cpu_exclusive_changed = |
663 | else | 719 | (is_cpu_exclusive(cs) != is_cpu_exclusive(&trialcs)); |
664 | clear_bit(bit, &cs->flags); | 720 | if (turning_on) |
665 | } | 721 | set_bit(bit, &cs->flags); |
666 | return err; | 722 | else |
723 | clear_bit(bit, &cs->flags); | ||
724 | |||
725 | if (cpu_exclusive_changed) | ||
726 | update_cpu_domains(cs); | ||
727 | return 0; | ||
667 | } | 728 | } |
668 | 729 | ||
669 | static int attach_task(struct cpuset *cs, char *buf) | 730 | static int attach_task(struct cpuset *cs, char *buf) |
@@ -1309,12 +1370,14 @@ static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry) | |||
1309 | up(&cpuset_sem); | 1370 | up(&cpuset_sem); |
1310 | return -EBUSY; | 1371 | return -EBUSY; |
1311 | } | 1372 | } |
1312 | spin_lock(&cs->dentry->d_lock); | ||
1313 | parent = cs->parent; | 1373 | parent = cs->parent; |
1314 | set_bit(CS_REMOVED, &cs->flags); | 1374 | set_bit(CS_REMOVED, &cs->flags); |
1375 | if (is_cpu_exclusive(cs)) | ||
1376 | update_cpu_domains(cs); | ||
1315 | list_del(&cs->sibling); /* delete my sibling from parent->children */ | 1377 | list_del(&cs->sibling); /* delete my sibling from parent->children */ |
1316 | if (list_empty(&parent->children)) | 1378 | if (list_empty(&parent->children)) |
1317 | check_for_release(parent); | 1379 | check_for_release(parent); |
1380 | spin_lock(&cs->dentry->d_lock); | ||
1318 | d = dget(cs->dentry); | 1381 | d = dget(cs->dentry); |
1319 | cs->dentry = NULL; | 1382 | cs->dentry = NULL; |
1320 | spin_unlock(&d->d_lock); | 1383 | spin_unlock(&d->d_lock); |
diff --git a/kernel/crash_dump.c b/kernel/crash_dump.c new file mode 100644 index 000000000000..459ba49e376a --- /dev/null +++ b/kernel/crash_dump.c | |||
@@ -0,0 +1,52 @@ | |||
1 | /* | ||
2 | * kernel/crash_dump.c - Memory preserving reboot related code. | ||
3 | * | ||
4 | * Created by: Hariprasad Nellitheertha (hari@in.ibm.com) | ||
5 | * Copyright (C) IBM Corporation, 2004. All rights reserved | ||
6 | */ | ||
7 | |||
8 | #include <linux/smp_lock.h> | ||
9 | #include <linux/errno.h> | ||
10 | #include <linux/proc_fs.h> | ||
11 | #include <linux/bootmem.h> | ||
12 | #include <linux/highmem.h> | ||
13 | #include <linux/crash_dump.h> | ||
14 | |||
15 | #include <asm/io.h> | ||
16 | #include <asm/uaccess.h> | ||
17 | |||
18 | /* Stores the physical address of elf header of crash image. */ | ||
19 | unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX; | ||
20 | |||
21 | /* | ||
22 | * Copy a page from "oldmem". For this page, there is no pte mapped | ||
23 | * in the current kernel. We stitch up a pte, similar to kmap_atomic. | ||
24 | */ | ||
25 | ssize_t copy_oldmem_page(unsigned long pfn, char *buf, | ||
26 | size_t csize, unsigned long offset, int userbuf) | ||
27 | { | ||
28 | void *page, *vaddr; | ||
29 | |||
30 | if (!csize) | ||
31 | return 0; | ||
32 | |||
33 | page = kmalloc(PAGE_SIZE, GFP_KERNEL); | ||
34 | if (!page) | ||
35 | return -ENOMEM; | ||
36 | |||
37 | vaddr = kmap_atomic_pfn(pfn, KM_PTE0); | ||
38 | copy_page(page, vaddr); | ||
39 | kunmap_atomic(vaddr, KM_PTE0); | ||
40 | |||
41 | if (userbuf) { | ||
42 | if (copy_to_user(buf, (page + offset), csize)) { | ||
43 | kfree(page); | ||
44 | return -EFAULT; | ||
45 | } | ||
46 | } else { | ||
47 | memcpy(buf, (page + offset), csize); | ||
48 | } | ||
49 | |||
50 | kfree(page); | ||
51 | return csize; | ||
52 | } | ||
diff --git a/kernel/fork.c b/kernel/fork.c index a28d11e10877..2c7806873bfd 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -1003,9 +1003,6 @@ static task_t *copy_process(unsigned long clone_flags, | |||
1003 | p->pdeath_signal = 0; | 1003 | p->pdeath_signal = 0; |
1004 | p->exit_state = 0; | 1004 | p->exit_state = 0; |
1005 | 1005 | ||
1006 | /* Perform scheduler related setup */ | ||
1007 | sched_fork(p); | ||
1008 | |||
1009 | /* | 1006 | /* |
1010 | * Ok, make it visible to the rest of the system. | 1007 | * Ok, make it visible to the rest of the system. |
1011 | * We dont wake it up yet. | 1008 | * We dont wake it up yet. |
@@ -1014,18 +1011,24 @@ static task_t *copy_process(unsigned long clone_flags, | |||
1014 | INIT_LIST_HEAD(&p->ptrace_children); | 1011 | INIT_LIST_HEAD(&p->ptrace_children); |
1015 | INIT_LIST_HEAD(&p->ptrace_list); | 1012 | INIT_LIST_HEAD(&p->ptrace_list); |
1016 | 1013 | ||
1014 | /* Perform scheduler related setup. Assign this task to a CPU. */ | ||
1015 | sched_fork(p, clone_flags); | ||
1016 | |||
1017 | /* Need tasklist lock for parent etc handling! */ | 1017 | /* Need tasklist lock for parent etc handling! */ |
1018 | write_lock_irq(&tasklist_lock); | 1018 | write_lock_irq(&tasklist_lock); |
1019 | 1019 | ||
1020 | /* | 1020 | /* |
1021 | * The task hasn't been attached yet, so cpus_allowed mask cannot | 1021 | * The task hasn't been attached yet, so its cpus_allowed mask will |
1022 | * have changed. The cpus_allowed mask of the parent may have | 1022 | * not be changed, nor will its assigned CPU. |
1023 | * changed after it was copied first time, and it may then move to | 1023 | * |
1024 | * another CPU - so we re-copy it here and set the child's CPU to | 1024 | * The cpus_allowed mask of the parent may have changed after it was |
1025 | * the parent's CPU. This avoids alot of nasty races. | 1025 | * copied first time - so re-copy it here, then check the child's CPU |
1026 | * to ensure it is on a valid CPU (and if not, just force it back to | ||
1027 | * parent's CPU). This avoids alot of nasty races. | ||
1026 | */ | 1028 | */ |
1027 | p->cpus_allowed = current->cpus_allowed; | 1029 | p->cpus_allowed = current->cpus_allowed; |
1028 | set_task_cpu(p, smp_processor_id()); | 1030 | if (unlikely(!cpu_isset(task_cpu(p), p->cpus_allowed))) |
1031 | set_task_cpu(p, smp_processor_id()); | ||
1029 | 1032 | ||
1030 | /* | 1033 | /* |
1031 | * Check for pending SIGKILL! The new thread should not be allowed | 1034 | * Check for pending SIGKILL! The new thread should not be allowed |
diff --git a/kernel/kexec.c b/kernel/kexec.c new file mode 100644 index 000000000000..7843548cf2d9 --- /dev/null +++ b/kernel/kexec.c | |||
@@ -0,0 +1,1063 @@ | |||
1 | /* | ||
2 | * kexec.c - kexec system call | ||
3 | * Copyright (C) 2002-2004 Eric Biederman <ebiederm@xmission.com> | ||
4 | * | ||
5 | * This source code is licensed under the GNU General Public License, | ||
6 | * Version 2. See the file COPYING for more details. | ||
7 | */ | ||
8 | |||
9 | #include <linux/mm.h> | ||
10 | #include <linux/file.h> | ||
11 | #include <linux/slab.h> | ||
12 | #include <linux/fs.h> | ||
13 | #include <linux/kexec.h> | ||
14 | #include <linux/spinlock.h> | ||
15 | #include <linux/list.h> | ||
16 | #include <linux/highmem.h> | ||
17 | #include <linux/syscalls.h> | ||
18 | #include <linux/reboot.h> | ||
19 | #include <linux/syscalls.h> | ||
20 | #include <linux/ioport.h> | ||
21 | #include <linux/hardirq.h> | ||
22 | |||
23 | #include <asm/page.h> | ||
24 | #include <asm/uaccess.h> | ||
25 | #include <asm/io.h> | ||
26 | #include <asm/system.h> | ||
27 | #include <asm/semaphore.h> | ||
28 | |||
29 | /* Location of the reserved area for the crash kernel */ | ||
30 | struct resource crashk_res = { | ||
31 | .name = "Crash kernel", | ||
32 | .start = 0, | ||
33 | .end = 0, | ||
34 | .flags = IORESOURCE_BUSY | IORESOURCE_MEM | ||
35 | }; | ||
36 | |||
37 | int kexec_should_crash(struct task_struct *p) | ||
38 | { | ||
39 | if (in_interrupt() || !p->pid || p->pid == 1 || panic_on_oops) | ||
40 | return 1; | ||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | /* | ||
45 | * When kexec transitions to the new kernel there is a one-to-one | ||
46 | * mapping between physical and virtual addresses. On processors | ||
47 | * where you can disable the MMU this is trivial, and easy. For | ||
48 | * others it is still a simple predictable page table to setup. | ||
49 | * | ||
50 | * In that environment kexec copies the new kernel to its final | ||
51 | * resting place. This means I can only support memory whose | ||
52 | * physical address can fit in an unsigned long. In particular | ||
53 | * addresses where (pfn << PAGE_SHIFT) > ULONG_MAX cannot be handled. | ||
54 | * If the assembly stub has more restrictive requirements | ||
55 | * KEXEC_SOURCE_MEMORY_LIMIT and KEXEC_DEST_MEMORY_LIMIT can be | ||
56 | * defined more restrictively in <asm/kexec.h>. | ||
57 | * | ||
58 | * The code for the transition from the current kernel to the | ||
59 | * the new kernel is placed in the control_code_buffer, whose size | ||
60 | * is given by KEXEC_CONTROL_CODE_SIZE. In the best case only a single | ||
61 | * page of memory is necessary, but some architectures require more. | ||
62 | * Because this memory must be identity mapped in the transition from | ||
63 | * virtual to physical addresses it must live in the range | ||
64 | * 0 - TASK_SIZE, as only the user space mappings are arbitrarily | ||
65 | * modifiable. | ||
66 | * | ||
67 | * The assembly stub in the control code buffer is passed a linked list | ||
68 | * of descriptor pages detailing the source pages of the new kernel, | ||
69 | * and the destination addresses of those source pages. As this data | ||
70 | * structure is not used in the context of the current OS, it must | ||
71 | * be self-contained. | ||
72 | * | ||
73 | * The code has been made to work with highmem pages and will use a | ||
74 | * destination page in its final resting place (if it happens | ||
75 | * to allocate it). The end product of this is that most of the | ||
76 | * physical address space, and most of RAM can be used. | ||
77 | * | ||
78 | * Future directions include: | ||
79 | * - allocating a page table with the control code buffer identity | ||
80 | * mapped, to simplify machine_kexec and make kexec_on_panic more | ||
81 | * reliable. | ||
82 | */ | ||
83 | |||
84 | /* | ||
85 | * KIMAGE_NO_DEST is an impossible destination address..., for | ||
86 | * allocating pages whose destination address we do not care about. | ||
87 | */ | ||
88 | #define KIMAGE_NO_DEST (-1UL) | ||
89 | |||
90 | static int kimage_is_destination_range(struct kimage *image, | ||
91 | unsigned long start, unsigned long end); | ||
92 | static struct page *kimage_alloc_page(struct kimage *image, | ||
93 | unsigned int gfp_mask, | ||
94 | unsigned long dest); | ||
95 | |||
96 | static int do_kimage_alloc(struct kimage **rimage, unsigned long entry, | ||
97 | unsigned long nr_segments, | ||
98 | struct kexec_segment __user *segments) | ||
99 | { | ||
100 | size_t segment_bytes; | ||
101 | struct kimage *image; | ||
102 | unsigned long i; | ||
103 | int result; | ||
104 | |||
105 | /* Allocate a controlling structure */ | ||
106 | result = -ENOMEM; | ||
107 | image = kmalloc(sizeof(*image), GFP_KERNEL); | ||
108 | if (!image) | ||
109 | goto out; | ||
110 | |||
111 | memset(image, 0, sizeof(*image)); | ||
112 | image->head = 0; | ||
113 | image->entry = &image->head; | ||
114 | image->last_entry = &image->head; | ||
115 | image->control_page = ~0; /* By default this does not apply */ | ||
116 | image->start = entry; | ||
117 | image->type = KEXEC_TYPE_DEFAULT; | ||
118 | |||
119 | /* Initialize the list of control pages */ | ||
120 | INIT_LIST_HEAD(&image->control_pages); | ||
121 | |||
122 | /* Initialize the list of destination pages */ | ||
123 | INIT_LIST_HEAD(&image->dest_pages); | ||
124 | |||
125 | /* Initialize the list of unuseable pages */ | ||
126 | INIT_LIST_HEAD(&image->unuseable_pages); | ||
127 | |||
128 | /* Read in the segments */ | ||
129 | image->nr_segments = nr_segments; | ||
130 | segment_bytes = nr_segments * sizeof(*segments); | ||
131 | result = copy_from_user(image->segment, segments, segment_bytes); | ||
132 | if (result) | ||
133 | goto out; | ||
134 | |||
135 | /* | ||
136 | * Verify we have good destination addresses. The caller is | ||
137 | * responsible for making certain we don't attempt to load | ||
138 | * the new image into invalid or reserved areas of RAM. This | ||
139 | * just verifies it is an address we can use. | ||
140 | * | ||
141 | * Since the kernel does everything in page size chunks ensure | ||
142 | * the destination addreses are page aligned. Too many | ||
143 | * special cases crop of when we don't do this. The most | ||
144 | * insidious is getting overlapping destination addresses | ||
145 | * simply because addresses are changed to page size | ||
146 | * granularity. | ||
147 | */ | ||
148 | result = -EADDRNOTAVAIL; | ||
149 | for (i = 0; i < nr_segments; i++) { | ||
150 | unsigned long mstart, mend; | ||
151 | |||
152 | mstart = image->segment[i].mem; | ||
153 | mend = mstart + image->segment[i].memsz; | ||
154 | if ((mstart & ~PAGE_MASK) || (mend & ~PAGE_MASK)) | ||
155 | goto out; | ||
156 | if (mend >= KEXEC_DESTINATION_MEMORY_LIMIT) | ||
157 | goto out; | ||
158 | } | ||
159 | |||
160 | /* Verify our destination addresses do not overlap. | ||
161 | * If we alloed overlapping destination addresses | ||
162 | * through very weird things can happen with no | ||
163 | * easy explanation as one segment stops on another. | ||
164 | */ | ||
165 | result = -EINVAL; | ||
166 | for (i = 0; i < nr_segments; i++) { | ||
167 | unsigned long mstart, mend; | ||
168 | unsigned long j; | ||
169 | |||
170 | mstart = image->segment[i].mem; | ||
171 | mend = mstart + image->segment[i].memsz; | ||
172 | for (j = 0; j < i; j++) { | ||
173 | unsigned long pstart, pend; | ||
174 | pstart = image->segment[j].mem; | ||
175 | pend = pstart + image->segment[j].memsz; | ||
176 | /* Do the segments overlap ? */ | ||
177 | if ((mend > pstart) && (mstart < pend)) | ||
178 | goto out; | ||
179 | } | ||
180 | } | ||
181 | |||
182 | /* Ensure our buffer sizes are strictly less than | ||
183 | * our memory sizes. This should always be the case, | ||
184 | * and it is easier to check up front than to be surprised | ||
185 | * later on. | ||
186 | */ | ||
187 | result = -EINVAL; | ||
188 | for (i = 0; i < nr_segments; i++) { | ||
189 | if (image->segment[i].bufsz > image->segment[i].memsz) | ||
190 | goto out; | ||
191 | } | ||
192 | |||
193 | result = 0; | ||
194 | out: | ||
195 | if (result == 0) | ||
196 | *rimage = image; | ||
197 | else | ||
198 | kfree(image); | ||
199 | |||
200 | return result; | ||
201 | |||
202 | } | ||
203 | |||
204 | static int kimage_normal_alloc(struct kimage **rimage, unsigned long entry, | ||
205 | unsigned long nr_segments, | ||
206 | struct kexec_segment __user *segments) | ||
207 | { | ||
208 | int result; | ||
209 | struct kimage *image; | ||
210 | |||
211 | /* Allocate and initialize a controlling structure */ | ||
212 | image = NULL; | ||
213 | result = do_kimage_alloc(&image, entry, nr_segments, segments); | ||
214 | if (result) | ||
215 | goto out; | ||
216 | |||
217 | *rimage = image; | ||
218 | |||
219 | /* | ||
220 | * Find a location for the control code buffer, and add it | ||
221 | * the vector of segments so that it's pages will also be | ||
222 | * counted as destination pages. | ||
223 | */ | ||
224 | result = -ENOMEM; | ||
225 | image->control_code_page = kimage_alloc_control_pages(image, | ||
226 | get_order(KEXEC_CONTROL_CODE_SIZE)); | ||
227 | if (!image->control_code_page) { | ||
228 | printk(KERN_ERR "Could not allocate control_code_buffer\n"); | ||
229 | goto out; | ||
230 | } | ||
231 | |||
232 | result = 0; | ||
233 | out: | ||
234 | if (result == 0) | ||
235 | *rimage = image; | ||
236 | else | ||
237 | kfree(image); | ||
238 | |||
239 | return result; | ||
240 | } | ||
241 | |||
242 | static int kimage_crash_alloc(struct kimage **rimage, unsigned long entry, | ||
243 | unsigned long nr_segments, | ||
244 | struct kexec_segment *segments) | ||
245 | { | ||
246 | int result; | ||
247 | struct kimage *image; | ||
248 | unsigned long i; | ||
249 | |||
250 | image = NULL; | ||
251 | /* Verify we have a valid entry point */ | ||
252 | if ((entry < crashk_res.start) || (entry > crashk_res.end)) { | ||
253 | result = -EADDRNOTAVAIL; | ||
254 | goto out; | ||
255 | } | ||
256 | |||
257 | /* Allocate and initialize a controlling structure */ | ||
258 | result = do_kimage_alloc(&image, entry, nr_segments, segments); | ||
259 | if (result) | ||
260 | goto out; | ||
261 | |||
262 | /* Enable the special crash kernel control page | ||
263 | * allocation policy. | ||
264 | */ | ||
265 | image->control_page = crashk_res.start; | ||
266 | image->type = KEXEC_TYPE_CRASH; | ||
267 | |||
268 | /* | ||
269 | * Verify we have good destination addresses. Normally | ||
270 | * the caller is responsible for making certain we don't | ||
271 | * attempt to load the new image into invalid or reserved | ||
272 | * areas of RAM. But crash kernels are preloaded into a | ||
273 | * reserved area of ram. We must ensure the addresses | ||
274 | * are in the reserved area otherwise preloading the | ||
275 | * kernel could corrupt things. | ||
276 | */ | ||
277 | result = -EADDRNOTAVAIL; | ||
278 | for (i = 0; i < nr_segments; i++) { | ||
279 | unsigned long mstart, mend; | ||
280 | |||
281 | mstart = image->segment[i].mem; | ||
282 | mend = mstart + image->segment[i].memsz - 1; | ||
283 | /* Ensure we are within the crash kernel limits */ | ||
284 | if ((mstart < crashk_res.start) || (mend > crashk_res.end)) | ||
285 | goto out; | ||
286 | } | ||
287 | |||
288 | /* | ||
289 | * Find a location for the control code buffer, and add | ||
290 | * the vector of segments so that it's pages will also be | ||
291 | * counted as destination pages. | ||
292 | */ | ||
293 | result = -ENOMEM; | ||
294 | image->control_code_page = kimage_alloc_control_pages(image, | ||
295 | get_order(KEXEC_CONTROL_CODE_SIZE)); | ||
296 | if (!image->control_code_page) { | ||
297 | printk(KERN_ERR "Could not allocate control_code_buffer\n"); | ||
298 | goto out; | ||
299 | } | ||
300 | |||
301 | result = 0; | ||
302 | out: | ||
303 | if (result == 0) | ||
304 | *rimage = image; | ||
305 | else | ||
306 | kfree(image); | ||
307 | |||
308 | return result; | ||
309 | } | ||
310 | |||
311 | static int kimage_is_destination_range(struct kimage *image, | ||
312 | unsigned long start, | ||
313 | unsigned long end) | ||
314 | { | ||
315 | unsigned long i; | ||
316 | |||
317 | for (i = 0; i < image->nr_segments; i++) { | ||
318 | unsigned long mstart, mend; | ||
319 | |||
320 | mstart = image->segment[i].mem; | ||
321 | mend = mstart + image->segment[i].memsz; | ||
322 | if ((end > mstart) && (start < mend)) | ||
323 | return 1; | ||
324 | } | ||
325 | |||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | static struct page *kimage_alloc_pages(unsigned int gfp_mask, | ||
330 | unsigned int order) | ||
331 | { | ||
332 | struct page *pages; | ||
333 | |||
334 | pages = alloc_pages(gfp_mask, order); | ||
335 | if (pages) { | ||
336 | unsigned int count, i; | ||
337 | pages->mapping = NULL; | ||
338 | pages->private = order; | ||
339 | count = 1 << order; | ||
340 | for (i = 0; i < count; i++) | ||
341 | SetPageReserved(pages + i); | ||
342 | } | ||
343 | |||
344 | return pages; | ||
345 | } | ||
346 | |||
347 | static void kimage_free_pages(struct page *page) | ||
348 | { | ||
349 | unsigned int order, count, i; | ||
350 | |||
351 | order = page->private; | ||
352 | count = 1 << order; | ||
353 | for (i = 0; i < count; i++) | ||
354 | ClearPageReserved(page + i); | ||
355 | __free_pages(page, order); | ||
356 | } | ||
357 | |||
358 | static void kimage_free_page_list(struct list_head *list) | ||
359 | { | ||
360 | struct list_head *pos, *next; | ||
361 | |||
362 | list_for_each_safe(pos, next, list) { | ||
363 | struct page *page; | ||
364 | |||
365 | page = list_entry(pos, struct page, lru); | ||
366 | list_del(&page->lru); | ||
367 | kimage_free_pages(page); | ||
368 | } | ||
369 | } | ||
370 | |||
371 | static struct page *kimage_alloc_normal_control_pages(struct kimage *image, | ||
372 | unsigned int order) | ||
373 | { | ||
374 | /* Control pages are special, they are the intermediaries | ||
375 | * that are needed while we copy the rest of the pages | ||
376 | * to their final resting place. As such they must | ||
377 | * not conflict with either the destination addresses | ||
378 | * or memory the kernel is already using. | ||
379 | * | ||
380 | * The only case where we really need more than one of | ||
381 | * these are for architectures where we cannot disable | ||
382 | * the MMU and must instead generate an identity mapped | ||
383 | * page table for all of the memory. | ||
384 | * | ||
385 | * At worst this runs in O(N) of the image size. | ||
386 | */ | ||
387 | struct list_head extra_pages; | ||
388 | struct page *pages; | ||
389 | unsigned int count; | ||
390 | |||
391 | count = 1 << order; | ||
392 | INIT_LIST_HEAD(&extra_pages); | ||
393 | |||
394 | /* Loop while I can allocate a page and the page allocated | ||
395 | * is a destination page. | ||
396 | */ | ||
397 | do { | ||
398 | unsigned long pfn, epfn, addr, eaddr; | ||
399 | |||
400 | pages = kimage_alloc_pages(GFP_KERNEL, order); | ||
401 | if (!pages) | ||
402 | break; | ||
403 | pfn = page_to_pfn(pages); | ||
404 | epfn = pfn + count; | ||
405 | addr = pfn << PAGE_SHIFT; | ||
406 | eaddr = epfn << PAGE_SHIFT; | ||
407 | if ((epfn >= (KEXEC_CONTROL_MEMORY_LIMIT >> PAGE_SHIFT)) || | ||
408 | kimage_is_destination_range(image, addr, eaddr)) { | ||
409 | list_add(&pages->lru, &extra_pages); | ||
410 | pages = NULL; | ||
411 | } | ||
412 | } while (!pages); | ||
413 | |||
414 | if (pages) { | ||
415 | /* Remember the allocated page... */ | ||
416 | list_add(&pages->lru, &image->control_pages); | ||
417 | |||
418 | /* Because the page is already in it's destination | ||
419 | * location we will never allocate another page at | ||
420 | * that address. Therefore kimage_alloc_pages | ||
421 | * will not return it (again) and we don't need | ||
422 | * to give it an entry in image->segment[]. | ||
423 | */ | ||
424 | } | ||
425 | /* Deal with the destination pages I have inadvertently allocated. | ||
426 | * | ||
427 | * Ideally I would convert multi-page allocations into single | ||
428 | * page allocations, and add everyting to image->dest_pages. | ||
429 | * | ||
430 | * For now it is simpler to just free the pages. | ||
431 | */ | ||
432 | kimage_free_page_list(&extra_pages); | ||
433 | |||
434 | return pages; | ||
435 | } | ||
436 | |||
437 | static struct page *kimage_alloc_crash_control_pages(struct kimage *image, | ||
438 | unsigned int order) | ||
439 | { | ||
440 | /* Control pages are special, they are the intermediaries | ||
441 | * that are needed while we copy the rest of the pages | ||
442 | * to their final resting place. As such they must | ||
443 | * not conflict with either the destination addresses | ||
444 | * or memory the kernel is already using. | ||
445 | * | ||
446 | * Control pages are also the only pags we must allocate | ||
447 | * when loading a crash kernel. All of the other pages | ||
448 | * are specified by the segments and we just memcpy | ||
449 | * into them directly. | ||
450 | * | ||
451 | * The only case where we really need more than one of | ||
452 | * these are for architectures where we cannot disable | ||
453 | * the MMU and must instead generate an identity mapped | ||
454 | * page table for all of the memory. | ||
455 | * | ||
456 | * Given the low demand this implements a very simple | ||
457 | * allocator that finds the first hole of the appropriate | ||
458 | * size in the reserved memory region, and allocates all | ||
459 | * of the memory up to and including the hole. | ||
460 | */ | ||
461 | unsigned long hole_start, hole_end, size; | ||
462 | struct page *pages; | ||
463 | |||
464 | pages = NULL; | ||
465 | size = (1 << order) << PAGE_SHIFT; | ||
466 | hole_start = (image->control_page + (size - 1)) & ~(size - 1); | ||
467 | hole_end = hole_start + size - 1; | ||
468 | while (hole_end <= crashk_res.end) { | ||
469 | unsigned long i; | ||
470 | |||
471 | if (hole_end > KEXEC_CONTROL_MEMORY_LIMIT) | ||
472 | break; | ||
473 | if (hole_end > crashk_res.end) | ||
474 | break; | ||
475 | /* See if I overlap any of the segments */ | ||
476 | for (i = 0; i < image->nr_segments; i++) { | ||
477 | unsigned long mstart, mend; | ||
478 | |||
479 | mstart = image->segment[i].mem; | ||
480 | mend = mstart + image->segment[i].memsz - 1; | ||
481 | if ((hole_end >= mstart) && (hole_start <= mend)) { | ||
482 | /* Advance the hole to the end of the segment */ | ||
483 | hole_start = (mend + (size - 1)) & ~(size - 1); | ||
484 | hole_end = hole_start + size - 1; | ||
485 | break; | ||
486 | } | ||
487 | } | ||
488 | /* If I don't overlap any segments I have found my hole! */ | ||
489 | if (i == image->nr_segments) { | ||
490 | pages = pfn_to_page(hole_start >> PAGE_SHIFT); | ||
491 | break; | ||
492 | } | ||
493 | } | ||
494 | if (pages) | ||
495 | image->control_page = hole_end; | ||
496 | |||
497 | return pages; | ||
498 | } | ||
499 | |||
500 | |||
501 | struct page *kimage_alloc_control_pages(struct kimage *image, | ||
502 | unsigned int order) | ||
503 | { | ||
504 | struct page *pages = NULL; | ||
505 | |||
506 | switch (image->type) { | ||
507 | case KEXEC_TYPE_DEFAULT: | ||
508 | pages = kimage_alloc_normal_control_pages(image, order); | ||
509 | break; | ||
510 | case KEXEC_TYPE_CRASH: | ||
511 | pages = kimage_alloc_crash_control_pages(image, order); | ||
512 | break; | ||
513 | } | ||
514 | |||
515 | return pages; | ||
516 | } | ||
517 | |||
518 | static int kimage_add_entry(struct kimage *image, kimage_entry_t entry) | ||
519 | { | ||
520 | if (*image->entry != 0) | ||
521 | image->entry++; | ||
522 | |||
523 | if (image->entry == image->last_entry) { | ||
524 | kimage_entry_t *ind_page; | ||
525 | struct page *page; | ||
526 | |||
527 | page = kimage_alloc_page(image, GFP_KERNEL, KIMAGE_NO_DEST); | ||
528 | if (!page) | ||
529 | return -ENOMEM; | ||
530 | |||
531 | ind_page = page_address(page); | ||
532 | *image->entry = virt_to_phys(ind_page) | IND_INDIRECTION; | ||
533 | image->entry = ind_page; | ||
534 | image->last_entry = ind_page + | ||
535 | ((PAGE_SIZE/sizeof(kimage_entry_t)) - 1); | ||
536 | } | ||
537 | *image->entry = entry; | ||
538 | image->entry++; | ||
539 | *image->entry = 0; | ||
540 | |||
541 | return 0; | ||
542 | } | ||
543 | |||
544 | static int kimage_set_destination(struct kimage *image, | ||
545 | unsigned long destination) | ||
546 | { | ||
547 | int result; | ||
548 | |||
549 | destination &= PAGE_MASK; | ||
550 | result = kimage_add_entry(image, destination | IND_DESTINATION); | ||
551 | if (result == 0) | ||
552 | image->destination = destination; | ||
553 | |||
554 | return result; | ||
555 | } | ||
556 | |||
557 | |||
558 | static int kimage_add_page(struct kimage *image, unsigned long page) | ||
559 | { | ||
560 | int result; | ||
561 | |||
562 | page &= PAGE_MASK; | ||
563 | result = kimage_add_entry(image, page | IND_SOURCE); | ||
564 | if (result == 0) | ||
565 | image->destination += PAGE_SIZE; | ||
566 | |||
567 | return result; | ||
568 | } | ||
569 | |||
570 | |||
571 | static void kimage_free_extra_pages(struct kimage *image) | ||
572 | { | ||
573 | /* Walk through and free any extra destination pages I may have */ | ||
574 | kimage_free_page_list(&image->dest_pages); | ||
575 | |||
576 | /* Walk through and free any unuseable pages I have cached */ | ||
577 | kimage_free_page_list(&image->unuseable_pages); | ||
578 | |||
579 | } | ||
580 | static int kimage_terminate(struct kimage *image) | ||
581 | { | ||
582 | if (*image->entry != 0) | ||
583 | image->entry++; | ||
584 | |||
585 | *image->entry = IND_DONE; | ||
586 | |||
587 | return 0; | ||
588 | } | ||
589 | |||
590 | #define for_each_kimage_entry(image, ptr, entry) \ | ||
591 | for (ptr = &image->head; (entry = *ptr) && !(entry & IND_DONE); \ | ||
592 | ptr = (entry & IND_INDIRECTION)? \ | ||
593 | phys_to_virt((entry & PAGE_MASK)): ptr +1) | ||
594 | |||
595 | static void kimage_free_entry(kimage_entry_t entry) | ||
596 | { | ||
597 | struct page *page; | ||
598 | |||
599 | page = pfn_to_page(entry >> PAGE_SHIFT); | ||
600 | kimage_free_pages(page); | ||
601 | } | ||
602 | |||
603 | static void kimage_free(struct kimage *image) | ||
604 | { | ||
605 | kimage_entry_t *ptr, entry; | ||
606 | kimage_entry_t ind = 0; | ||
607 | |||
608 | if (!image) | ||
609 | return; | ||
610 | |||
611 | kimage_free_extra_pages(image); | ||
612 | for_each_kimage_entry(image, ptr, entry) { | ||
613 | if (entry & IND_INDIRECTION) { | ||
614 | /* Free the previous indirection page */ | ||
615 | if (ind & IND_INDIRECTION) | ||
616 | kimage_free_entry(ind); | ||
617 | /* Save this indirection page until we are | ||
618 | * done with it. | ||
619 | */ | ||
620 | ind = entry; | ||
621 | } | ||
622 | else if (entry & IND_SOURCE) | ||
623 | kimage_free_entry(entry); | ||
624 | } | ||
625 | /* Free the final indirection page */ | ||
626 | if (ind & IND_INDIRECTION) | ||
627 | kimage_free_entry(ind); | ||
628 | |||
629 | /* Handle any machine specific cleanup */ | ||
630 | machine_kexec_cleanup(image); | ||
631 | |||
632 | /* Free the kexec control pages... */ | ||
633 | kimage_free_page_list(&image->control_pages); | ||
634 | kfree(image); | ||
635 | } | ||
636 | |||
637 | static kimage_entry_t *kimage_dst_used(struct kimage *image, | ||
638 | unsigned long page) | ||
639 | { | ||
640 | kimage_entry_t *ptr, entry; | ||
641 | unsigned long destination = 0; | ||
642 | |||
643 | for_each_kimage_entry(image, ptr, entry) { | ||
644 | if (entry & IND_DESTINATION) | ||
645 | destination = entry & PAGE_MASK; | ||
646 | else if (entry & IND_SOURCE) { | ||
647 | if (page == destination) | ||
648 | return ptr; | ||
649 | destination += PAGE_SIZE; | ||
650 | } | ||
651 | } | ||
652 | |||
653 | return 0; | ||
654 | } | ||
655 | |||
656 | static struct page *kimage_alloc_page(struct kimage *image, | ||
657 | unsigned int gfp_mask, | ||
658 | unsigned long destination) | ||
659 | { | ||
660 | /* | ||
661 | * Here we implement safeguards to ensure that a source page | ||
662 | * is not copied to its destination page before the data on | ||
663 | * the destination page is no longer useful. | ||
664 | * | ||
665 | * To do this we maintain the invariant that a source page is | ||
666 | * either its own destination page, or it is not a | ||
667 | * destination page at all. | ||
668 | * | ||
669 | * That is slightly stronger than required, but the proof | ||
670 | * that no problems will not occur is trivial, and the | ||
671 | * implementation is simply to verify. | ||
672 | * | ||
673 | * When allocating all pages normally this algorithm will run | ||
674 | * in O(N) time, but in the worst case it will run in O(N^2) | ||
675 | * time. If the runtime is a problem the data structures can | ||
676 | * be fixed. | ||
677 | */ | ||
678 | struct page *page; | ||
679 | unsigned long addr; | ||
680 | |||
681 | /* | ||
682 | * Walk through the list of destination pages, and see if I | ||
683 | * have a match. | ||
684 | */ | ||
685 | list_for_each_entry(page, &image->dest_pages, lru) { | ||
686 | addr = page_to_pfn(page) << PAGE_SHIFT; | ||
687 | if (addr == destination) { | ||
688 | list_del(&page->lru); | ||
689 | return page; | ||
690 | } | ||
691 | } | ||
692 | page = NULL; | ||
693 | while (1) { | ||
694 | kimage_entry_t *old; | ||
695 | |||
696 | /* Allocate a page, if we run out of memory give up */ | ||
697 | page = kimage_alloc_pages(gfp_mask, 0); | ||
698 | if (!page) | ||
699 | return 0; | ||
700 | /* If the page cannot be used file it away */ | ||
701 | if (page_to_pfn(page) > | ||
702 | (KEXEC_SOURCE_MEMORY_LIMIT >> PAGE_SHIFT)) { | ||
703 | list_add(&page->lru, &image->unuseable_pages); | ||
704 | continue; | ||
705 | } | ||
706 | addr = page_to_pfn(page) << PAGE_SHIFT; | ||
707 | |||
708 | /* If it is the destination page we want use it */ | ||
709 | if (addr == destination) | ||
710 | break; | ||
711 | |||
712 | /* If the page is not a destination page use it */ | ||
713 | if (!kimage_is_destination_range(image, addr, | ||
714 | addr + PAGE_SIZE)) | ||
715 | break; | ||
716 | |||
717 | /* | ||
718 | * I know that the page is someones destination page. | ||
719 | * See if there is already a source page for this | ||
720 | * destination page. And if so swap the source pages. | ||
721 | */ | ||
722 | old = kimage_dst_used(image, addr); | ||
723 | if (old) { | ||
724 | /* If so move it */ | ||
725 | unsigned long old_addr; | ||
726 | struct page *old_page; | ||
727 | |||
728 | old_addr = *old & PAGE_MASK; | ||
729 | old_page = pfn_to_page(old_addr >> PAGE_SHIFT); | ||
730 | copy_highpage(page, old_page); | ||
731 | *old = addr | (*old & ~PAGE_MASK); | ||
732 | |||
733 | /* The old page I have found cannot be a | ||
734 | * destination page, so return it. | ||
735 | */ | ||
736 | addr = old_addr; | ||
737 | page = old_page; | ||
738 | break; | ||
739 | } | ||
740 | else { | ||
741 | /* Place the page on the destination list I | ||
742 | * will use it later. | ||
743 | */ | ||
744 | list_add(&page->lru, &image->dest_pages); | ||
745 | } | ||
746 | } | ||
747 | |||
748 | return page; | ||
749 | } | ||
750 | |||
751 | static int kimage_load_normal_segment(struct kimage *image, | ||
752 | struct kexec_segment *segment) | ||
753 | { | ||
754 | unsigned long maddr; | ||
755 | unsigned long ubytes, mbytes; | ||
756 | int result; | ||
757 | unsigned char *buf; | ||
758 | |||
759 | result = 0; | ||
760 | buf = segment->buf; | ||
761 | ubytes = segment->bufsz; | ||
762 | mbytes = segment->memsz; | ||
763 | maddr = segment->mem; | ||
764 | |||
765 | result = kimage_set_destination(image, maddr); | ||
766 | if (result < 0) | ||
767 | goto out; | ||
768 | |||
769 | while (mbytes) { | ||
770 | struct page *page; | ||
771 | char *ptr; | ||
772 | size_t uchunk, mchunk; | ||
773 | |||
774 | page = kimage_alloc_page(image, GFP_HIGHUSER, maddr); | ||
775 | if (page == 0) { | ||
776 | result = -ENOMEM; | ||
777 | goto out; | ||
778 | } | ||
779 | result = kimage_add_page(image, page_to_pfn(page) | ||
780 | << PAGE_SHIFT); | ||
781 | if (result < 0) | ||
782 | goto out; | ||
783 | |||
784 | ptr = kmap(page); | ||
785 | /* Start with a clear page */ | ||
786 | memset(ptr, 0, PAGE_SIZE); | ||
787 | ptr += maddr & ~PAGE_MASK; | ||
788 | mchunk = PAGE_SIZE - (maddr & ~PAGE_MASK); | ||
789 | if (mchunk > mbytes) | ||
790 | mchunk = mbytes; | ||
791 | |||
792 | uchunk = mchunk; | ||
793 | if (uchunk > ubytes) | ||
794 | uchunk = ubytes; | ||
795 | |||
796 | result = copy_from_user(ptr, buf, uchunk); | ||
797 | kunmap(page); | ||
798 | if (result) { | ||
799 | result = (result < 0) ? result : -EIO; | ||
800 | goto out; | ||
801 | } | ||
802 | ubytes -= uchunk; | ||
803 | maddr += mchunk; | ||
804 | buf += mchunk; | ||
805 | mbytes -= mchunk; | ||
806 | } | ||
807 | out: | ||
808 | return result; | ||
809 | } | ||
810 | |||
811 | static int kimage_load_crash_segment(struct kimage *image, | ||
812 | struct kexec_segment *segment) | ||
813 | { | ||
814 | /* For crash dumps kernels we simply copy the data from | ||
815 | * user space to it's destination. | ||
816 | * We do things a page at a time for the sake of kmap. | ||
817 | */ | ||
818 | unsigned long maddr; | ||
819 | unsigned long ubytes, mbytes; | ||
820 | int result; | ||
821 | unsigned char *buf; | ||
822 | |||
823 | result = 0; | ||
824 | buf = segment->buf; | ||
825 | ubytes = segment->bufsz; | ||
826 | mbytes = segment->memsz; | ||
827 | maddr = segment->mem; | ||
828 | while (mbytes) { | ||
829 | struct page *page; | ||
830 | char *ptr; | ||
831 | size_t uchunk, mchunk; | ||
832 | |||
833 | page = pfn_to_page(maddr >> PAGE_SHIFT); | ||
834 | if (page == 0) { | ||
835 | result = -ENOMEM; | ||
836 | goto out; | ||
837 | } | ||
838 | ptr = kmap(page); | ||
839 | ptr += maddr & ~PAGE_MASK; | ||
840 | mchunk = PAGE_SIZE - (maddr & ~PAGE_MASK); | ||
841 | if (mchunk > mbytes) | ||
842 | mchunk = mbytes; | ||
843 | |||
844 | uchunk = mchunk; | ||
845 | if (uchunk > ubytes) { | ||
846 | uchunk = ubytes; | ||
847 | /* Zero the trailing part of the page */ | ||
848 | memset(ptr + uchunk, 0, mchunk - uchunk); | ||
849 | } | ||
850 | result = copy_from_user(ptr, buf, uchunk); | ||
851 | kunmap(page); | ||
852 | if (result) { | ||
853 | result = (result < 0) ? result : -EIO; | ||
854 | goto out; | ||
855 | } | ||
856 | ubytes -= uchunk; | ||
857 | maddr += mchunk; | ||
858 | buf += mchunk; | ||
859 | mbytes -= mchunk; | ||
860 | } | ||
861 | out: | ||
862 | return result; | ||
863 | } | ||
864 | |||
865 | static int kimage_load_segment(struct kimage *image, | ||
866 | struct kexec_segment *segment) | ||
867 | { | ||
868 | int result = -ENOMEM; | ||
869 | |||
870 | switch (image->type) { | ||
871 | case KEXEC_TYPE_DEFAULT: | ||
872 | result = kimage_load_normal_segment(image, segment); | ||
873 | break; | ||
874 | case KEXEC_TYPE_CRASH: | ||
875 | result = kimage_load_crash_segment(image, segment); | ||
876 | break; | ||
877 | } | ||
878 | |||
879 | return result; | ||
880 | } | ||
881 | |||
882 | /* | ||
883 | * Exec Kernel system call: for obvious reasons only root may call it. | ||
884 | * | ||
885 | * This call breaks up into three pieces. | ||
886 | * - A generic part which loads the new kernel from the current | ||
887 | * address space, and very carefully places the data in the | ||
888 | * allocated pages. | ||
889 | * | ||
890 | * - A generic part that interacts with the kernel and tells all of | ||
891 | * the devices to shut down. Preventing on-going dmas, and placing | ||
892 | * the devices in a consistent state so a later kernel can | ||
893 | * reinitialize them. | ||
894 | * | ||
895 | * - A machine specific part that includes the syscall number | ||
896 | * and the copies the image to it's final destination. And | ||
897 | * jumps into the image at entry. | ||
898 | * | ||
899 | * kexec does not sync, or unmount filesystems so if you need | ||
900 | * that to happen you need to do that yourself. | ||
901 | */ | ||
902 | struct kimage *kexec_image = NULL; | ||
903 | static struct kimage *kexec_crash_image = NULL; | ||
904 | /* | ||
905 | * A home grown binary mutex. | ||
906 | * Nothing can wait so this mutex is safe to use | ||
907 | * in interrupt context :) | ||
908 | */ | ||
909 | static int kexec_lock = 0; | ||
910 | |||
911 | asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments, | ||
912 | struct kexec_segment __user *segments, | ||
913 | unsigned long flags) | ||
914 | { | ||
915 | struct kimage **dest_image, *image; | ||
916 | int locked; | ||
917 | int result; | ||
918 | |||
919 | /* We only trust the superuser with rebooting the system. */ | ||
920 | if (!capable(CAP_SYS_BOOT)) | ||
921 | return -EPERM; | ||
922 | |||
923 | /* | ||
924 | * Verify we have a legal set of flags | ||
925 | * This leaves us room for future extensions. | ||
926 | */ | ||
927 | if ((flags & KEXEC_FLAGS) != (flags & ~KEXEC_ARCH_MASK)) | ||
928 | return -EINVAL; | ||
929 | |||
930 | /* Verify we are on the appropriate architecture */ | ||
931 | if (((flags & KEXEC_ARCH_MASK) != KEXEC_ARCH) && | ||
932 | ((flags & KEXEC_ARCH_MASK) != KEXEC_ARCH_DEFAULT)) | ||
933 | return -EINVAL; | ||
934 | |||
935 | /* Put an artificial cap on the number | ||
936 | * of segments passed to kexec_load. | ||
937 | */ | ||
938 | if (nr_segments > KEXEC_SEGMENT_MAX) | ||
939 | return -EINVAL; | ||
940 | |||
941 | image = NULL; | ||
942 | result = 0; | ||
943 | |||
944 | /* Because we write directly to the reserved memory | ||
945 | * region when loading crash kernels we need a mutex here to | ||
946 | * prevent multiple crash kernels from attempting to load | ||
947 | * simultaneously, and to prevent a crash kernel from loading | ||
948 | * over the top of a in use crash kernel. | ||
949 | * | ||
950 | * KISS: always take the mutex. | ||
951 | */ | ||
952 | locked = xchg(&kexec_lock, 1); | ||
953 | if (locked) | ||
954 | return -EBUSY; | ||
955 | |||
956 | dest_image = &kexec_image; | ||
957 | if (flags & KEXEC_ON_CRASH) | ||
958 | dest_image = &kexec_crash_image; | ||
959 | if (nr_segments > 0) { | ||
960 | unsigned long i; | ||
961 | |||
962 | /* Loading another kernel to reboot into */ | ||
963 | if ((flags & KEXEC_ON_CRASH) == 0) | ||
964 | result = kimage_normal_alloc(&image, entry, | ||
965 | nr_segments, segments); | ||
966 | /* Loading another kernel to switch to if this one crashes */ | ||
967 | else if (flags & KEXEC_ON_CRASH) { | ||
968 | /* Free any current crash dump kernel before | ||
969 | * we corrupt it. | ||
970 | */ | ||
971 | kimage_free(xchg(&kexec_crash_image, NULL)); | ||
972 | result = kimage_crash_alloc(&image, entry, | ||
973 | nr_segments, segments); | ||
974 | } | ||
975 | if (result) | ||
976 | goto out; | ||
977 | |||
978 | result = machine_kexec_prepare(image); | ||
979 | if (result) | ||
980 | goto out; | ||
981 | |||
982 | for (i = 0; i < nr_segments; i++) { | ||
983 | result = kimage_load_segment(image, &image->segment[i]); | ||
984 | if (result) | ||
985 | goto out; | ||
986 | } | ||
987 | result = kimage_terminate(image); | ||
988 | if (result) | ||
989 | goto out; | ||
990 | } | ||
991 | /* Install the new kernel, and Uninstall the old */ | ||
992 | image = xchg(dest_image, image); | ||
993 | |||
994 | out: | ||
995 | xchg(&kexec_lock, 0); /* Release the mutex */ | ||
996 | kimage_free(image); | ||
997 | |||
998 | return result; | ||
999 | } | ||
1000 | |||
1001 | #ifdef CONFIG_COMPAT | ||
1002 | asmlinkage long compat_sys_kexec_load(unsigned long entry, | ||
1003 | unsigned long nr_segments, | ||
1004 | struct compat_kexec_segment __user *segments, | ||
1005 | unsigned long flags) | ||
1006 | { | ||
1007 | struct compat_kexec_segment in; | ||
1008 | struct kexec_segment out, __user *ksegments; | ||
1009 | unsigned long i, result; | ||
1010 | |||
1011 | /* Don't allow clients that don't understand the native | ||
1012 | * architecture to do anything. | ||
1013 | */ | ||
1014 | if ((flags & KEXEC_ARCH_MASK) == KEXEC_ARCH_DEFAULT) | ||
1015 | return -EINVAL; | ||
1016 | |||
1017 | if (nr_segments > KEXEC_SEGMENT_MAX) | ||
1018 | return -EINVAL; | ||
1019 | |||
1020 | ksegments = compat_alloc_user_space(nr_segments * sizeof(out)); | ||
1021 | for (i=0; i < nr_segments; i++) { | ||
1022 | result = copy_from_user(&in, &segments[i], sizeof(in)); | ||
1023 | if (result) | ||
1024 | return -EFAULT; | ||
1025 | |||
1026 | out.buf = compat_ptr(in.buf); | ||
1027 | out.bufsz = in.bufsz; | ||
1028 | out.mem = in.mem; | ||
1029 | out.memsz = in.memsz; | ||
1030 | |||
1031 | result = copy_to_user(&ksegments[i], &out, sizeof(out)); | ||
1032 | if (result) | ||
1033 | return -EFAULT; | ||
1034 | } | ||
1035 | |||
1036 | return sys_kexec_load(entry, nr_segments, ksegments, flags); | ||
1037 | } | ||
1038 | #endif | ||
1039 | |||
1040 | void crash_kexec(struct pt_regs *regs) | ||
1041 | { | ||
1042 | struct kimage *image; | ||
1043 | int locked; | ||
1044 | |||
1045 | |||
1046 | /* Take the kexec_lock here to prevent sys_kexec_load | ||
1047 | * running on one cpu from replacing the crash kernel | ||
1048 | * we are using after a panic on a different cpu. | ||
1049 | * | ||
1050 | * If the crash kernel was not located in a fixed area | ||
1051 | * of memory the xchg(&kexec_crash_image) would be | ||
1052 | * sufficient. But since I reuse the memory... | ||
1053 | */ | ||
1054 | locked = xchg(&kexec_lock, 1); | ||
1055 | if (!locked) { | ||
1056 | image = xchg(&kexec_crash_image, NULL); | ||
1057 | if (image) { | ||
1058 | machine_crash_shutdown(regs); | ||
1059 | machine_kexec(image); | ||
1060 | } | ||
1061 | xchg(&kexec_lock, 0); | ||
1062 | } | ||
1063 | } | ||
diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c index 1f064a63f8cf..015fb69ad94d 100644 --- a/kernel/ksysfs.c +++ b/kernel/ksysfs.c | |||
@@ -30,6 +30,16 @@ static ssize_t hotplug_seqnum_show(struct subsystem *subsys, char *page) | |||
30 | KERNEL_ATTR_RO(hotplug_seqnum); | 30 | KERNEL_ATTR_RO(hotplug_seqnum); |
31 | #endif | 31 | #endif |
32 | 32 | ||
33 | #ifdef CONFIG_KEXEC | ||
34 | #include <asm/kexec.h> | ||
35 | |||
36 | static ssize_t crash_notes_show(struct subsystem *subsys, char *page) | ||
37 | { | ||
38 | return sprintf(page, "%p\n", (void *)crash_notes); | ||
39 | } | ||
40 | KERNEL_ATTR_RO(crash_notes); | ||
41 | #endif | ||
42 | |||
33 | decl_subsys(kernel, NULL, NULL); | 43 | decl_subsys(kernel, NULL, NULL); |
34 | EXPORT_SYMBOL_GPL(kernel_subsys); | 44 | EXPORT_SYMBOL_GPL(kernel_subsys); |
35 | 45 | ||
@@ -37,6 +47,9 @@ static struct attribute * kernel_attrs[] = { | |||
37 | #ifdef CONFIG_HOTPLUG | 47 | #ifdef CONFIG_HOTPLUG |
38 | &hotplug_seqnum_attr.attr, | 48 | &hotplug_seqnum_attr.attr, |
39 | #endif | 49 | #endif |
50 | #ifdef CONFIG_KEXEC | ||
51 | &crash_notes_attr.attr, | ||
52 | #endif | ||
40 | NULL | 53 | NULL |
41 | }; | 54 | }; |
42 | 55 | ||
diff --git a/kernel/panic.c b/kernel/panic.c index 081f7465fc8d..74ba5f3e46c7 100644 --- a/kernel/panic.c +++ b/kernel/panic.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/sysrq.h> | 18 | #include <linux/sysrq.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/nmi.h> | 20 | #include <linux/nmi.h> |
21 | #include <linux/kexec.h> | ||
21 | 22 | ||
22 | int panic_timeout; | 23 | int panic_timeout; |
23 | int panic_on_oops; | 24 | int panic_on_oops; |
@@ -63,6 +64,13 @@ NORET_TYPE void panic(const char * fmt, ...) | |||
63 | unsigned long caller = (unsigned long) __builtin_return_address(0); | 64 | unsigned long caller = (unsigned long) __builtin_return_address(0); |
64 | #endif | 65 | #endif |
65 | 66 | ||
67 | /* | ||
68 | * It's possible to come here directly from a panic-assertion and not | ||
69 | * have preempt disabled. Some functions called from here want | ||
70 | * preempt to be disabled. No point enabling it later though... | ||
71 | */ | ||
72 | preempt_disable(); | ||
73 | |||
66 | bust_spinlocks(1); | 74 | bust_spinlocks(1); |
67 | va_start(args, fmt); | 75 | va_start(args, fmt); |
68 | vsnprintf(buf, sizeof(buf), fmt, args); | 76 | vsnprintf(buf, sizeof(buf), fmt, args); |
@@ -70,7 +78,19 @@ NORET_TYPE void panic(const char * fmt, ...) | |||
70 | printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf); | 78 | printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf); |
71 | bust_spinlocks(0); | 79 | bust_spinlocks(0); |
72 | 80 | ||
81 | /* | ||
82 | * If we have crashed and we have a crash kernel loaded let it handle | ||
83 | * everything else. | ||
84 | * Do we want to call this before we try to display a message? | ||
85 | */ | ||
86 | crash_kexec(NULL); | ||
87 | |||
73 | #ifdef CONFIG_SMP | 88 | #ifdef CONFIG_SMP |
89 | /* | ||
90 | * Note smp_send_stop is the usual smp shutdown function, which | ||
91 | * unfortunately means it may not be hardened to work in a panic | ||
92 | * situation. | ||
93 | */ | ||
74 | smp_send_stop(); | 94 | smp_send_stop(); |
75 | #endif | 95 | #endif |
76 | 96 | ||
@@ -79,8 +99,7 @@ NORET_TYPE void panic(const char * fmt, ...) | |||
79 | if (!panic_blink) | 99 | if (!panic_blink) |
80 | panic_blink = no_blink; | 100 | panic_blink = no_blink; |
81 | 101 | ||
82 | if (panic_timeout > 0) | 102 | if (panic_timeout > 0) { |
83 | { | ||
84 | /* | 103 | /* |
85 | * Delay timeout seconds before rebooting the machine. | 104 | * Delay timeout seconds before rebooting the machine. |
86 | * We can't use the "normal" timers since we just panicked.. | 105 | * We can't use the "normal" timers since we just panicked.. |
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 696387ffe49c..2c7121d9bff1 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig | |||
@@ -27,8 +27,8 @@ config PM_DEBUG | |||
27 | like suspend support. | 27 | like suspend support. |
28 | 28 | ||
29 | config SOFTWARE_SUSPEND | 29 | config SOFTWARE_SUSPEND |
30 | bool "Software Suspend (EXPERIMENTAL)" | 30 | bool "Software Suspend" |
31 | depends on EXPERIMENTAL && PM && SWAP | 31 | depends on EXPERIMENTAL && PM && SWAP && ((X86 && SMP) || ((FVR || PPC32 || X86) && !SMP)) |
32 | ---help--- | 32 | ---help--- |
33 | Enable the possibility of suspending the machine. | 33 | Enable the possibility of suspending the machine. |
34 | It doesn't need APM. | 34 | It doesn't need APM. |
@@ -72,3 +72,7 @@ config PM_STD_PARTITION | |||
72 | suspended image to. It will simply pick the first available swap | 72 | suspended image to. It will simply pick the first available swap |
73 | device. | 73 | device. |
74 | 74 | ||
75 | config SUSPEND_SMP | ||
76 | bool | ||
77 | depends on HOTPLUG_CPU && X86 && PM | ||
78 | default y | ||
diff --git a/kernel/power/Makefile b/kernel/power/Makefile index fbdc634135a7..2f438d0eaa13 100644 --- a/kernel/power/Makefile +++ b/kernel/power/Makefile | |||
@@ -3,9 +3,9 @@ ifeq ($(CONFIG_PM_DEBUG),y) | |||
3 | EXTRA_CFLAGS += -DDEBUG | 3 | EXTRA_CFLAGS += -DDEBUG |
4 | endif | 4 | endif |
5 | 5 | ||
6 | swsusp-smp-$(CONFIG_SMP) += smp.o | ||
7 | |||
8 | obj-y := main.o process.o console.o pm.o | 6 | obj-y := main.o process.o console.o pm.o |
9 | obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o $(swsusp-smp-y) disk.o | 7 | obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o disk.o |
8 | |||
9 | obj-$(CONFIG_SUSPEND_SMP) += smp.o | ||
10 | 10 | ||
11 | obj-$(CONFIG_MAGIC_SYSRQ) += poweroff.o | 11 | obj-$(CONFIG_MAGIC_SYSRQ) += poweroff.o |
diff --git a/kernel/power/disk.c b/kernel/power/disk.c index 02b6764034dc..fb8de63c2919 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c | |||
@@ -117,8 +117,8 @@ static void finish(void) | |||
117 | { | 117 | { |
118 | device_resume(); | 118 | device_resume(); |
119 | platform_finish(); | 119 | platform_finish(); |
120 | enable_nonboot_cpus(); | ||
121 | thaw_processes(); | 120 | thaw_processes(); |
121 | enable_nonboot_cpus(); | ||
122 | pm_restore_console(); | 122 | pm_restore_console(); |
123 | } | 123 | } |
124 | 124 | ||
@@ -131,28 +131,35 @@ static int prepare_processes(void) | |||
131 | 131 | ||
132 | sys_sync(); | 132 | sys_sync(); |
133 | 133 | ||
134 | disable_nonboot_cpus(); | ||
135 | |||
134 | if (freeze_processes()) { | 136 | if (freeze_processes()) { |
135 | error = -EBUSY; | 137 | error = -EBUSY; |
136 | return error; | 138 | goto thaw; |
137 | } | 139 | } |
138 | 140 | ||
139 | if (pm_disk_mode == PM_DISK_PLATFORM) { | 141 | if (pm_disk_mode == PM_DISK_PLATFORM) { |
140 | if (pm_ops && pm_ops->prepare) { | 142 | if (pm_ops && pm_ops->prepare) { |
141 | if ((error = pm_ops->prepare(PM_SUSPEND_DISK))) | 143 | if ((error = pm_ops->prepare(PM_SUSPEND_DISK))) |
142 | return error; | 144 | goto thaw; |
143 | } | 145 | } |
144 | } | 146 | } |
145 | 147 | ||
146 | /* Free memory before shutting down devices. */ | 148 | /* Free memory before shutting down devices. */ |
147 | free_some_memory(); | 149 | free_some_memory(); |
148 | |||
149 | return 0; | 150 | return 0; |
151 | thaw: | ||
152 | thaw_processes(); | ||
153 | enable_nonboot_cpus(); | ||
154 | pm_restore_console(); | ||
155 | return error; | ||
150 | } | 156 | } |
151 | 157 | ||
152 | static void unprepare_processes(void) | 158 | static void unprepare_processes(void) |
153 | { | 159 | { |
154 | enable_nonboot_cpus(); | 160 | platform_finish(); |
155 | thaw_processes(); | 161 | thaw_processes(); |
162 | enable_nonboot_cpus(); | ||
156 | pm_restore_console(); | 163 | pm_restore_console(); |
157 | } | 164 | } |
158 | 165 | ||
@@ -160,15 +167,9 @@ static int prepare_devices(void) | |||
160 | { | 167 | { |
161 | int error; | 168 | int error; |
162 | 169 | ||
163 | disable_nonboot_cpus(); | 170 | if ((error = device_suspend(PMSG_FREEZE))) |
164 | if ((error = device_suspend(PMSG_FREEZE))) { | ||
165 | printk("Some devices failed to suspend\n"); | 171 | printk("Some devices failed to suspend\n"); |
166 | platform_finish(); | 172 | return error; |
167 | enable_nonboot_cpus(); | ||
168 | return error; | ||
169 | } | ||
170 | |||
171 | return 0; | ||
172 | } | 173 | } |
173 | 174 | ||
174 | /** | 175 | /** |
@@ -185,9 +186,9 @@ int pm_suspend_disk(void) | |||
185 | int error; | 186 | int error; |
186 | 187 | ||
187 | error = prepare_processes(); | 188 | error = prepare_processes(); |
188 | if (!error) { | 189 | if (error) |
189 | error = prepare_devices(); | 190 | return error; |
190 | } | 191 | error = prepare_devices(); |
191 | 192 | ||
192 | if (error) { | 193 | if (error) { |
193 | unprepare_processes(); | 194 | unprepare_processes(); |
@@ -250,7 +251,7 @@ static int software_resume(void) | |||
250 | 251 | ||
251 | if ((error = prepare_processes())) { | 252 | if ((error = prepare_processes())) { |
252 | swsusp_close(); | 253 | swsusp_close(); |
253 | goto Cleanup; | 254 | goto Done; |
254 | } | 255 | } |
255 | 256 | ||
256 | pr_debug("PM: Reading swsusp image.\n"); | 257 | pr_debug("PM: Reading swsusp image.\n"); |
diff --git a/kernel/power/main.c b/kernel/power/main.c index 4cdebc972ff2..c94cb9e95090 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c | |||
@@ -55,6 +55,13 @@ static int suspend_prepare(suspend_state_t state) | |||
55 | 55 | ||
56 | pm_prepare_console(); | 56 | pm_prepare_console(); |
57 | 57 | ||
58 | disable_nonboot_cpus(); | ||
59 | |||
60 | if (num_online_cpus() != 1) { | ||
61 | error = -EPERM; | ||
62 | goto Enable_cpu; | ||
63 | } | ||
64 | |||
58 | if (freeze_processes()) { | 65 | if (freeze_processes()) { |
59 | error = -EAGAIN; | 66 | error = -EAGAIN; |
60 | goto Thaw; | 67 | goto Thaw; |
@@ -75,6 +82,8 @@ static int suspend_prepare(suspend_state_t state) | |||
75 | pm_ops->finish(state); | 82 | pm_ops->finish(state); |
76 | Thaw: | 83 | Thaw: |
77 | thaw_processes(); | 84 | thaw_processes(); |
85 | Enable_cpu: | ||
86 | enable_nonboot_cpus(); | ||
78 | pm_restore_console(); | 87 | pm_restore_console(); |
79 | return error; | 88 | return error; |
80 | } | 89 | } |
@@ -113,6 +122,7 @@ static void suspend_finish(suspend_state_t state) | |||
113 | if (pm_ops && pm_ops->finish) | 122 | if (pm_ops && pm_ops->finish) |
114 | pm_ops->finish(state); | 123 | pm_ops->finish(state); |
115 | thaw_processes(); | 124 | thaw_processes(); |
125 | enable_nonboot_cpus(); | ||
116 | pm_restore_console(); | 126 | pm_restore_console(); |
117 | } | 127 | } |
118 | 128 | ||
@@ -150,12 +160,6 @@ static int enter_state(suspend_state_t state) | |||
150 | goto Unlock; | 160 | goto Unlock; |
151 | } | 161 | } |
152 | 162 | ||
153 | /* Suspend is hard to get right on SMP. */ | ||
154 | if (num_online_cpus() != 1) { | ||
155 | error = -EPERM; | ||
156 | goto Unlock; | ||
157 | } | ||
158 | |||
159 | pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]); | 163 | pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]); |
160 | if ((error = suspend_prepare(state))) | 164 | if ((error = suspend_prepare(state))) |
161 | goto Unlock; | 165 | goto Unlock; |
diff --git a/kernel/power/smp.c b/kernel/power/smp.c index 457c2302ed42..bbe23079c62c 100644 --- a/kernel/power/smp.c +++ b/kernel/power/smp.c | |||
@@ -13,73 +13,52 @@ | |||
13 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
14 | #include <linux/suspend.h> | 14 | #include <linux/suspend.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/cpu.h> | ||
16 | #include <asm/atomic.h> | 17 | #include <asm/atomic.h> |
17 | #include <asm/tlbflush.h> | 18 | #include <asm/tlbflush.h> |
18 | 19 | ||
19 | static atomic_t cpu_counter, freeze; | 20 | /* This is protected by pm_sem semaphore */ |
20 | 21 | static cpumask_t frozen_cpus; | |
21 | |||
22 | static void smp_pause(void * data) | ||
23 | { | ||
24 | struct saved_context ctxt; | ||
25 | __save_processor_state(&ctxt); | ||
26 | printk("Sleeping in:\n"); | ||
27 | dump_stack(); | ||
28 | atomic_inc(&cpu_counter); | ||
29 | while (atomic_read(&freeze)) { | ||
30 | /* FIXME: restore takes place at random piece inside this. | ||
31 | This should probably be written in assembly, and | ||
32 | preserve general-purpose registers, too | ||
33 | |||
34 | What about stack? We may need to move to new stack here. | ||
35 | |||
36 | This should better be ran with interrupts disabled. | ||
37 | */ | ||
38 | cpu_relax(); | ||
39 | barrier(); | ||
40 | } | ||
41 | atomic_dec(&cpu_counter); | ||
42 | __restore_processor_state(&ctxt); | ||
43 | } | ||
44 | |||
45 | static cpumask_t oldmask; | ||
46 | 22 | ||
47 | void disable_nonboot_cpus(void) | 23 | void disable_nonboot_cpus(void) |
48 | { | 24 | { |
49 | oldmask = current->cpus_allowed; | 25 | int cpu, error; |
50 | set_cpus_allowed(current, cpumask_of_cpu(0)); | ||
51 | printk("Freezing CPUs (at %d)", raw_smp_processor_id()); | ||
52 | current->state = TASK_INTERRUPTIBLE; | ||
53 | schedule_timeout(HZ); | ||
54 | printk("..."); | ||
55 | BUG_ON(raw_smp_processor_id() != 0); | ||
56 | |||
57 | /* FIXME: for this to work, all the CPUs must be running | ||
58 | * "idle" thread (or we deadlock). Is that guaranteed? */ | ||
59 | 26 | ||
60 | atomic_set(&cpu_counter, 0); | 27 | error = 0; |
61 | atomic_set(&freeze, 1); | 28 | cpus_clear(frozen_cpus); |
62 | smp_call_function(smp_pause, NULL, 0, 0); | 29 | printk("Freezing cpus ...\n"); |
63 | while (atomic_read(&cpu_counter) < (num_online_cpus() - 1)) { | 30 | for_each_online_cpu(cpu) { |
64 | cpu_relax(); | 31 | if (cpu == 0) |
65 | barrier(); | 32 | continue; |
33 | error = cpu_down(cpu); | ||
34 | if (!error) { | ||
35 | cpu_set(cpu, frozen_cpus); | ||
36 | printk("CPU%d is down\n", cpu); | ||
37 | continue; | ||
38 | } | ||
39 | printk("Error taking cpu %d down: %d\n", cpu, error); | ||
66 | } | 40 | } |
67 | printk("ok\n"); | 41 | BUG_ON(smp_processor_id() != 0); |
42 | if (error) | ||
43 | panic("cpus not sleeping"); | ||
68 | } | 44 | } |
69 | 45 | ||
70 | void enable_nonboot_cpus(void) | 46 | void enable_nonboot_cpus(void) |
71 | { | 47 | { |
72 | printk("Restarting CPUs"); | 48 | int cpu, error; |
73 | atomic_set(&freeze, 0); | ||
74 | while (atomic_read(&cpu_counter)) { | ||
75 | cpu_relax(); | ||
76 | barrier(); | ||
77 | } | ||
78 | printk("..."); | ||
79 | set_cpus_allowed(current, oldmask); | ||
80 | schedule(); | ||
81 | printk("ok\n"); | ||
82 | 49 | ||
50 | printk("Thawing cpus ...\n"); | ||
51 | for_each_cpu_mask(cpu, frozen_cpus) { | ||
52 | error = smp_prepare_cpu(cpu); | ||
53 | if (!error) | ||
54 | error = cpu_up(cpu); | ||
55 | if (!error) { | ||
56 | printk("CPU%d is up\n", cpu); | ||
57 | continue; | ||
58 | } | ||
59 | printk("Error taking cpu %d up: %d\n", cpu, error); | ||
60 | panic("Not enough cpus"); | ||
61 | } | ||
62 | cpus_clear(frozen_cpus); | ||
83 | } | 63 | } |
84 | 64 | ||
85 | |||
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c index 53f9f8720ee4..c285fc5a2320 100644 --- a/kernel/power/swsusp.c +++ b/kernel/power/swsusp.c | |||
@@ -10,12 +10,12 @@ | |||
10 | * This file is released under the GPLv2. | 10 | * This file is released under the GPLv2. |
11 | * | 11 | * |
12 | * I'd like to thank the following people for their work: | 12 | * I'd like to thank the following people for their work: |
13 | * | 13 | * |
14 | * Pavel Machek <pavel@ucw.cz>: | 14 | * Pavel Machek <pavel@ucw.cz>: |
15 | * Modifications, defectiveness pointing, being with me at the very beginning, | 15 | * Modifications, defectiveness pointing, being with me at the very beginning, |
16 | * suspend to swap space, stop all tasks. Port to 2.4.18-ac and 2.5.17. | 16 | * suspend to swap space, stop all tasks. Port to 2.4.18-ac and 2.5.17. |
17 | * | 17 | * |
18 | * Steve Doddi <dirk@loth.demon.co.uk>: | 18 | * Steve Doddi <dirk@loth.demon.co.uk>: |
19 | * Support the possibility of hardware state restoring. | 19 | * Support the possibility of hardware state restoring. |
20 | * | 20 | * |
21 | * Raph <grey.havens@earthling.net>: | 21 | * Raph <grey.havens@earthling.net>: |
@@ -84,11 +84,11 @@ extern char resume_file[]; | |||
84 | static unsigned int nr_copy_pages __nosavedata = 0; | 84 | static unsigned int nr_copy_pages __nosavedata = 0; |
85 | 85 | ||
86 | /* Suspend pagedir is allocated before final copy, therefore it | 86 | /* Suspend pagedir is allocated before final copy, therefore it |
87 | must be freed after resume | 87 | must be freed after resume |
88 | 88 | ||
89 | Warning: this is evil. There are actually two pagedirs at time of | 89 | Warning: this is evil. There are actually two pagedirs at time of |
90 | resume. One is "pagedir_save", which is empty frame allocated at | 90 | resume. One is "pagedir_save", which is empty frame allocated at |
91 | time of suspend, that must be freed. Second is "pagedir_nosave", | 91 | time of suspend, that must be freed. Second is "pagedir_nosave", |
92 | allocated at time of resume, that travels through memory not to | 92 | allocated at time of resume, that travels through memory not to |
93 | collide with anything. | 93 | collide with anything. |
94 | 94 | ||
@@ -132,7 +132,7 @@ static int mark_swapfiles(swp_entry_t prev) | |||
132 | { | 132 | { |
133 | int error; | 133 | int error; |
134 | 134 | ||
135 | rw_swap_page_sync(READ, | 135 | rw_swap_page_sync(READ, |
136 | swp_entry(root_swap, 0), | 136 | swp_entry(root_swap, 0), |
137 | virt_to_page((unsigned long)&swsusp_header)); | 137 | virt_to_page((unsigned long)&swsusp_header)); |
138 | if (!memcmp("SWAP-SPACE",swsusp_header.sig, 10) || | 138 | if (!memcmp("SWAP-SPACE",swsusp_header.sig, 10) || |
@@ -140,7 +140,7 @@ static int mark_swapfiles(swp_entry_t prev) | |||
140 | memcpy(swsusp_header.orig_sig,swsusp_header.sig, 10); | 140 | memcpy(swsusp_header.orig_sig,swsusp_header.sig, 10); |
141 | memcpy(swsusp_header.sig,SWSUSP_SIG, 10); | 141 | memcpy(swsusp_header.sig,SWSUSP_SIG, 10); |
142 | swsusp_header.swsusp_info = prev; | 142 | swsusp_header.swsusp_info = prev; |
143 | error = rw_swap_page_sync(WRITE, | 143 | error = rw_swap_page_sync(WRITE, |
144 | swp_entry(root_swap, 0), | 144 | swp_entry(root_swap, 0), |
145 | virt_to_page((unsigned long) | 145 | virt_to_page((unsigned long) |
146 | &swsusp_header)); | 146 | &swsusp_header)); |
@@ -174,22 +174,22 @@ static int is_resume_device(const struct swap_info_struct *swap_info) | |||
174 | static int swsusp_swap_check(void) /* This is called before saving image */ | 174 | static int swsusp_swap_check(void) /* This is called before saving image */ |
175 | { | 175 | { |
176 | int i, len; | 176 | int i, len; |
177 | 177 | ||
178 | len=strlen(resume_file); | 178 | len=strlen(resume_file); |
179 | root_swap = 0xFFFF; | 179 | root_swap = 0xFFFF; |
180 | 180 | ||
181 | swap_list_lock(); | 181 | swap_list_lock(); |
182 | for(i=0; i<MAX_SWAPFILES; i++) { | 182 | for (i=0; i<MAX_SWAPFILES; i++) { |
183 | if (swap_info[i].flags == 0) { | 183 | if (swap_info[i].flags == 0) { |
184 | swapfile_used[i]=SWAPFILE_UNUSED; | 184 | swapfile_used[i]=SWAPFILE_UNUSED; |
185 | } else { | 185 | } else { |
186 | if(!len) { | 186 | if (!len) { |
187 | printk(KERN_WARNING "resume= option should be used to set suspend device" ); | 187 | printk(KERN_WARNING "resume= option should be used to set suspend device" ); |
188 | if(root_swap == 0xFFFF) { | 188 | if (root_swap == 0xFFFF) { |
189 | swapfile_used[i] = SWAPFILE_SUSPEND; | 189 | swapfile_used[i] = SWAPFILE_SUSPEND; |
190 | root_swap = i; | 190 | root_swap = i; |
191 | } else | 191 | } else |
192 | swapfile_used[i] = SWAPFILE_IGNORED; | 192 | swapfile_used[i] = SWAPFILE_IGNORED; |
193 | } else { | 193 | } else { |
194 | /* we ignore all swap devices that are not the resume_file */ | 194 | /* we ignore all swap devices that are not the resume_file */ |
195 | if (is_resume_device(&swap_info[i])) { | 195 | if (is_resume_device(&swap_info[i])) { |
@@ -209,15 +209,15 @@ static int swsusp_swap_check(void) /* This is called before saving image */ | |||
209 | * This is called after saving image so modification | 209 | * This is called after saving image so modification |
210 | * will be lost after resume... and that's what we want. | 210 | * will be lost after resume... and that's what we want. |
211 | * we make the device unusable. A new call to | 211 | * we make the device unusable. A new call to |
212 | * lock_swapdevices can unlock the devices. | 212 | * lock_swapdevices can unlock the devices. |
213 | */ | 213 | */ |
214 | static void lock_swapdevices(void) | 214 | static void lock_swapdevices(void) |
215 | { | 215 | { |
216 | int i; | 216 | int i; |
217 | 217 | ||
218 | swap_list_lock(); | 218 | swap_list_lock(); |
219 | for(i = 0; i< MAX_SWAPFILES; i++) | 219 | for (i = 0; i< MAX_SWAPFILES; i++) |
220 | if(swapfile_used[i] == SWAPFILE_IGNORED) { | 220 | if (swapfile_used[i] == SWAPFILE_IGNORED) { |
221 | swap_info[i].flags ^= 0xFF; | 221 | swap_info[i].flags ^= 0xFF; |
222 | } | 222 | } |
223 | swap_list_unlock(); | 223 | swap_list_unlock(); |
@@ -229,7 +229,7 @@ static void lock_swapdevices(void) | |||
229 | * @loc: Place to store the entry we used. | 229 | * @loc: Place to store the entry we used. |
230 | * | 230 | * |
231 | * Allocate a new swap entry and 'sync' it. Note we discard -EIO | 231 | * Allocate a new swap entry and 'sync' it. Note we discard -EIO |
232 | * errors. That is an artifact left over from swsusp. It did not | 232 | * errors. That is an artifact left over from swsusp. It did not |
233 | * check the return of rw_swap_page_sync() at all, since most pages | 233 | * check the return of rw_swap_page_sync() at all, since most pages |
234 | * written back to swap would return -EIO. | 234 | * written back to swap would return -EIO. |
235 | * This is a partial improvement, since we will at least return other | 235 | * This is a partial improvement, since we will at least return other |
@@ -241,7 +241,7 @@ static int write_page(unsigned long addr, swp_entry_t * loc) | |||
241 | int error = 0; | 241 | int error = 0; |
242 | 242 | ||
243 | entry = get_swap_page(); | 243 | entry = get_swap_page(); |
244 | if (swp_offset(entry) && | 244 | if (swp_offset(entry) && |
245 | swapfile_used[swp_type(entry)] == SWAPFILE_SUSPEND) { | 245 | swapfile_used[swp_type(entry)] == SWAPFILE_SUSPEND) { |
246 | error = rw_swap_page_sync(WRITE, entry, | 246 | error = rw_swap_page_sync(WRITE, entry, |
247 | virt_to_page(addr)); | 247 | virt_to_page(addr)); |
@@ -257,7 +257,7 @@ static int write_page(unsigned long addr, swp_entry_t * loc) | |||
257 | /** | 257 | /** |
258 | * data_free - Free the swap entries used by the saved image. | 258 | * data_free - Free the swap entries used by the saved image. |
259 | * | 259 | * |
260 | * Walk the list of used swap entries and free each one. | 260 | * Walk the list of used swap entries and free each one. |
261 | * This is only used for cleanup when suspend fails. | 261 | * This is only used for cleanup when suspend fails. |
262 | */ | 262 | */ |
263 | static void data_free(void) | 263 | static void data_free(void) |
@@ -290,7 +290,7 @@ static int data_write(void) | |||
290 | mod = 1; | 290 | mod = 1; |
291 | 291 | ||
292 | printk( "Writing data to swap (%d pages)... ", nr_copy_pages ); | 292 | printk( "Writing data to swap (%d pages)... ", nr_copy_pages ); |
293 | for_each_pbe(p, pagedir_nosave) { | 293 | for_each_pbe (p, pagedir_nosave) { |
294 | if (!(i%mod)) | 294 | if (!(i%mod)) |
295 | printk( "\b\b\b\b%3d%%", i / mod ); | 295 | printk( "\b\b\b\b%3d%%", i / mod ); |
296 | if ((error = write_page(p->address, &(p->swap_address)))) | 296 | if ((error = write_page(p->address, &(p->swap_address)))) |
@@ -335,7 +335,7 @@ static int close_swap(void) | |||
335 | 335 | ||
336 | dump_info(); | 336 | dump_info(); |
337 | error = write_page((unsigned long)&swsusp_info, &entry); | 337 | error = write_page((unsigned long)&swsusp_info, &entry); |
338 | if (!error) { | 338 | if (!error) { |
339 | printk( "S" ); | 339 | printk( "S" ); |
340 | error = mark_swapfiles(entry); | 340 | error = mark_swapfiles(entry); |
341 | printk( "|\n" ); | 341 | printk( "|\n" ); |
@@ -370,7 +370,7 @@ static int write_pagedir(void) | |||
370 | struct pbe * pbe; | 370 | struct pbe * pbe; |
371 | 371 | ||
372 | printk( "Writing pagedir..."); | 372 | printk( "Writing pagedir..."); |
373 | for_each_pb_page(pbe, pagedir_nosave) { | 373 | for_each_pb_page (pbe, pagedir_nosave) { |
374 | if ((error = write_page((unsigned long)pbe, &swsusp_info.pagedir[n++]))) | 374 | if ((error = write_page((unsigned long)pbe, &swsusp_info.pagedir[n++]))) |
375 | return error; | 375 | return error; |
376 | } | 376 | } |
@@ -472,7 +472,7 @@ static int save_highmem(void) | |||
472 | int res = 0; | 472 | int res = 0; |
473 | 473 | ||
474 | pr_debug("swsusp: Saving Highmem\n"); | 474 | pr_debug("swsusp: Saving Highmem\n"); |
475 | for_each_zone(zone) { | 475 | for_each_zone (zone) { |
476 | if (is_highmem(zone)) | 476 | if (is_highmem(zone)) |
477 | res = save_highmem_zone(zone); | 477 | res = save_highmem_zone(zone); |
478 | if (res) | 478 | if (res) |
@@ -547,7 +547,7 @@ static void count_data_pages(void) | |||
547 | 547 | ||
548 | nr_copy_pages = 0; | 548 | nr_copy_pages = 0; |
549 | 549 | ||
550 | for_each_zone(zone) { | 550 | for_each_zone (zone) { |
551 | if (is_highmem(zone)) | 551 | if (is_highmem(zone)) |
552 | continue; | 552 | continue; |
553 | mark_free_pages(zone); | 553 | mark_free_pages(zone); |
@@ -562,9 +562,9 @@ static void copy_data_pages(void) | |||
562 | struct zone *zone; | 562 | struct zone *zone; |
563 | unsigned long zone_pfn; | 563 | unsigned long zone_pfn; |
564 | struct pbe * pbe = pagedir_nosave; | 564 | struct pbe * pbe = pagedir_nosave; |
565 | 565 | ||
566 | pr_debug("copy_data_pages(): pages to copy: %d\n", nr_copy_pages); | 566 | pr_debug("copy_data_pages(): pages to copy: %d\n", nr_copy_pages); |
567 | for_each_zone(zone) { | 567 | for_each_zone (zone) { |
568 | if (is_highmem(zone)) | 568 | if (is_highmem(zone)) |
569 | continue; | 569 | continue; |
570 | mark_free_pages(zone); | 570 | mark_free_pages(zone); |
@@ -702,7 +702,7 @@ static void free_image_pages(void) | |||
702 | { | 702 | { |
703 | struct pbe * p; | 703 | struct pbe * p; |
704 | 704 | ||
705 | for_each_pbe(p, pagedir_save) { | 705 | for_each_pbe (p, pagedir_save) { |
706 | if (p->address) { | 706 | if (p->address) { |
707 | ClearPageNosave(virt_to_page(p->address)); | 707 | ClearPageNosave(virt_to_page(p->address)); |
708 | free_page(p->address); | 708 | free_page(p->address); |
@@ -719,7 +719,7 @@ static int alloc_image_pages(void) | |||
719 | { | 719 | { |
720 | struct pbe * p; | 720 | struct pbe * p; |
721 | 721 | ||
722 | for_each_pbe(p, pagedir_save) { | 722 | for_each_pbe (p, pagedir_save) { |
723 | p->address = get_zeroed_page(GFP_ATOMIC | __GFP_COLD); | 723 | p->address = get_zeroed_page(GFP_ATOMIC | __GFP_COLD); |
724 | if (!p->address) | 724 | if (!p->address) |
725 | return -ENOMEM; | 725 | return -ENOMEM; |
@@ -740,7 +740,7 @@ void swsusp_free(void) | |||
740 | /** | 740 | /** |
741 | * enough_free_mem - Make sure we enough free memory to snapshot. | 741 | * enough_free_mem - Make sure we enough free memory to snapshot. |
742 | * | 742 | * |
743 | * Returns TRUE or FALSE after checking the number of available | 743 | * Returns TRUE or FALSE after checking the number of available |
744 | * free pages. | 744 | * free pages. |
745 | */ | 745 | */ |
746 | 746 | ||
@@ -758,11 +758,11 @@ static int enough_free_mem(void) | |||
758 | /** | 758 | /** |
759 | * enough_swap - Make sure we have enough swap to save the image. | 759 | * enough_swap - Make sure we have enough swap to save the image. |
760 | * | 760 | * |
761 | * Returns TRUE or FALSE after checking the total amount of swap | 761 | * Returns TRUE or FALSE after checking the total amount of swap |
762 | * space avaiable. | 762 | * space avaiable. |
763 | * | 763 | * |
764 | * FIXME: si_swapinfo(&i) returns all swap devices information. | 764 | * FIXME: si_swapinfo(&i) returns all swap devices information. |
765 | * We should only consider resume_device. | 765 | * We should only consider resume_device. |
766 | */ | 766 | */ |
767 | 767 | ||
768 | static int enough_swap(void) | 768 | static int enough_swap(void) |
@@ -781,18 +781,18 @@ static int swsusp_alloc(void) | |||
781 | { | 781 | { |
782 | int error; | 782 | int error; |
783 | 783 | ||
784 | pagedir_nosave = NULL; | ||
785 | nr_copy_pages = calc_nr(nr_copy_pages); | ||
786 | |||
784 | pr_debug("suspend: (pages needed: %d + %d free: %d)\n", | 787 | pr_debug("suspend: (pages needed: %d + %d free: %d)\n", |
785 | nr_copy_pages, PAGES_FOR_IO, nr_free_pages()); | 788 | nr_copy_pages, PAGES_FOR_IO, nr_free_pages()); |
786 | 789 | ||
787 | pagedir_nosave = NULL; | ||
788 | if (!enough_free_mem()) | 790 | if (!enough_free_mem()) |
789 | return -ENOMEM; | 791 | return -ENOMEM; |
790 | 792 | ||
791 | if (!enough_swap()) | 793 | if (!enough_swap()) |
792 | return -ENOSPC; | 794 | return -ENOSPC; |
793 | 795 | ||
794 | nr_copy_pages = calc_nr(nr_copy_pages); | ||
795 | |||
796 | if (!(pagedir_save = alloc_pagedir(nr_copy_pages))) { | 796 | if (!(pagedir_save = alloc_pagedir(nr_copy_pages))) { |
797 | printk(KERN_ERR "suspend: Allocating pagedir failed.\n"); | 797 | printk(KERN_ERR "suspend: Allocating pagedir failed.\n"); |
798 | return -ENOMEM; | 798 | return -ENOMEM; |
@@ -827,8 +827,8 @@ static int suspend_prepare_image(void) | |||
827 | error = swsusp_alloc(); | 827 | error = swsusp_alloc(); |
828 | if (error) | 828 | if (error) |
829 | return error; | 829 | return error; |
830 | 830 | ||
831 | /* During allocating of suspend pagedir, new cold pages may appear. | 831 | /* During allocating of suspend pagedir, new cold pages may appear. |
832 | * Kill them. | 832 | * Kill them. |
833 | */ | 833 | */ |
834 | drain_local_pages(); | 834 | drain_local_pages(); |
@@ -929,21 +929,6 @@ int swsusp_resume(void) | |||
929 | return error; | 929 | return error; |
930 | } | 930 | } |
931 | 931 | ||
932 | /* More restore stuff */ | ||
933 | |||
934 | /* | ||
935 | * Returns true if given address/order collides with any orig_address | ||
936 | */ | ||
937 | static int does_collide_order(unsigned long addr, int order) | ||
938 | { | ||
939 | int i; | ||
940 | |||
941 | for (i=0; i < (1<<order); i++) | ||
942 | if (!PageNosaveFree(virt_to_page(addr + i * PAGE_SIZE))) | ||
943 | return 1; | ||
944 | return 0; | ||
945 | } | ||
946 | |||
947 | /** | 932 | /** |
948 | * On resume, for storing the PBE list and the image, | 933 | * On resume, for storing the PBE list and the image, |
949 | * we can only use memory pages that do not conflict with the pages | 934 | * we can only use memory pages that do not conflict with the pages |
@@ -973,7 +958,7 @@ static unsigned long get_usable_page(unsigned gfp_mask) | |||
973 | unsigned long m; | 958 | unsigned long m; |
974 | 959 | ||
975 | m = get_zeroed_page(gfp_mask); | 960 | m = get_zeroed_page(gfp_mask); |
976 | while (does_collide_order(m, 0)) { | 961 | while (!PageNosaveFree(virt_to_page(m))) { |
977 | eat_page((void *)m); | 962 | eat_page((void *)m); |
978 | m = get_zeroed_page(gfp_mask); | 963 | m = get_zeroed_page(gfp_mask); |
979 | if (!m) | 964 | if (!m) |
@@ -1045,7 +1030,7 @@ static struct pbe * swsusp_pagedir_relocate(struct pbe *pblist) | |||
1045 | 1030 | ||
1046 | /* Set page flags */ | 1031 | /* Set page flags */ |
1047 | 1032 | ||
1048 | for_each_zone(zone) { | 1033 | for_each_zone (zone) { |
1049 | for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) | 1034 | for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) |
1050 | SetPageNosaveFree(pfn_to_page(zone_pfn + | 1035 | SetPageNosaveFree(pfn_to_page(zone_pfn + |
1051 | zone->zone_start_pfn)); | 1036 | zone->zone_start_pfn)); |
@@ -1061,7 +1046,7 @@ static struct pbe * swsusp_pagedir_relocate(struct pbe *pblist) | |||
1061 | /* Relocate colliding pages */ | 1046 | /* Relocate colliding pages */ |
1062 | 1047 | ||
1063 | for_each_pb_page (pbpage, pblist) { | 1048 | for_each_pb_page (pbpage, pblist) { |
1064 | if (does_collide_order((unsigned long)pbpage, 0)) { | 1049 | if (!PageNosaveFree(virt_to_page((unsigned long)pbpage))) { |
1065 | m = (void *)get_usable_page(GFP_ATOMIC | __GFP_COLD); | 1050 | m = (void *)get_usable_page(GFP_ATOMIC | __GFP_COLD); |
1066 | if (!m) { | 1051 | if (!m) { |
1067 | error = -ENOMEM; | 1052 | error = -ENOMEM; |
@@ -1193,8 +1178,10 @@ static const char * sanity_check(void) | |||
1193 | return "version"; | 1178 | return "version"; |
1194 | if (strcmp(swsusp_info.uts.machine,system_utsname.machine)) | 1179 | if (strcmp(swsusp_info.uts.machine,system_utsname.machine)) |
1195 | return "machine"; | 1180 | return "machine"; |
1181 | #if 0 | ||
1196 | if(swsusp_info.cpus != num_online_cpus()) | 1182 | if(swsusp_info.cpus != num_online_cpus()) |
1197 | return "number of cpus"; | 1183 | return "number of cpus"; |
1184 | #endif | ||
1198 | return NULL; | 1185 | return NULL; |
1199 | } | 1186 | } |
1200 | 1187 | ||
diff --git a/kernel/printk.c b/kernel/printk.c index 3a442bfb8bee..5092397fac29 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -588,8 +588,7 @@ asmlinkage int vprintk(const char *fmt, va_list args) | |||
588 | log_level_unknown = 1; | 588 | log_level_unknown = 1; |
589 | } | 589 | } |
590 | 590 | ||
591 | if (!cpu_online(smp_processor_id()) && | 591 | if (!cpu_online(smp_processor_id())) { |
592 | system_state != SYSTEM_RUNNING) { | ||
593 | /* | 592 | /* |
594 | * Some console drivers may assume that per-cpu resources have | 593 | * Some console drivers may assume that per-cpu resources have |
595 | * been allocated. So don't allow them to be called by this | 594 | * been allocated. So don't allow them to be called by this |
diff --git a/kernel/resource.c b/kernel/resource.c index 52f696f11adf..26967e042201 100644 --- a/kernel/resource.c +++ b/kernel/resource.c | |||
@@ -263,7 +263,7 @@ static int find_resource(struct resource *root, struct resource *new, | |||
263 | new->start = min; | 263 | new->start = min; |
264 | if (new->end > max) | 264 | if (new->end > max) |
265 | new->end = max; | 265 | new->end = max; |
266 | new->start = (new->start + align - 1) & ~(align - 1); | 266 | new->start = ALIGN(new->start, align); |
267 | if (alignf) | 267 | if (alignf) |
268 | alignf(alignf_data, new, size, align); | 268 | alignf(alignf_data, new, size, align); |
269 | if (new->start < new->end && new->end - new->start >= size - 1) { | 269 | if (new->start < new->end && new->end - new->start >= size - 1) { |
diff --git a/kernel/sched.c b/kernel/sched.c index 6fa9ea4ae44c..a07cff90d849 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -166,7 +166,7 @@ | |||
166 | #define SCALE_PRIO(x, prio) \ | 166 | #define SCALE_PRIO(x, prio) \ |
167 | max(x * (MAX_PRIO - prio) / (MAX_USER_PRIO/2), MIN_TIMESLICE) | 167 | max(x * (MAX_PRIO - prio) / (MAX_USER_PRIO/2), MIN_TIMESLICE) |
168 | 168 | ||
169 | static inline unsigned int task_timeslice(task_t *p) | 169 | static unsigned int task_timeslice(task_t *p) |
170 | { | 170 | { |
171 | if (p->static_prio < NICE_TO_PRIO(0)) | 171 | if (p->static_prio < NICE_TO_PRIO(0)) |
172 | return SCALE_PRIO(DEF_TIMESLICE*4, p->static_prio); | 172 | return SCALE_PRIO(DEF_TIMESLICE*4, p->static_prio); |
@@ -206,7 +206,7 @@ struct runqueue { | |||
206 | */ | 206 | */ |
207 | unsigned long nr_running; | 207 | unsigned long nr_running; |
208 | #ifdef CONFIG_SMP | 208 | #ifdef CONFIG_SMP |
209 | unsigned long cpu_load; | 209 | unsigned long cpu_load[3]; |
210 | #endif | 210 | #endif |
211 | unsigned long long nr_switches; | 211 | unsigned long long nr_switches; |
212 | 212 | ||
@@ -260,22 +260,86 @@ struct runqueue { | |||
260 | 260 | ||
261 | static DEFINE_PER_CPU(struct runqueue, runqueues); | 261 | static DEFINE_PER_CPU(struct runqueue, runqueues); |
262 | 262 | ||
263 | /* | ||
264 | * The domain tree (rq->sd) is protected by RCU's quiescent state transition. | ||
265 | * See detach_destroy_domains: synchronize_sched for details. | ||
266 | * | ||
267 | * The domain tree of any CPU may only be accessed from within | ||
268 | * preempt-disabled sections. | ||
269 | */ | ||
263 | #define for_each_domain(cpu, domain) \ | 270 | #define for_each_domain(cpu, domain) \ |
264 | for (domain = cpu_rq(cpu)->sd; domain; domain = domain->parent) | 271 | for (domain = rcu_dereference(cpu_rq(cpu)->sd); domain; domain = domain->parent) |
265 | 272 | ||
266 | #define cpu_rq(cpu) (&per_cpu(runqueues, (cpu))) | 273 | #define cpu_rq(cpu) (&per_cpu(runqueues, (cpu))) |
267 | #define this_rq() (&__get_cpu_var(runqueues)) | 274 | #define this_rq() (&__get_cpu_var(runqueues)) |
268 | #define task_rq(p) cpu_rq(task_cpu(p)) | 275 | #define task_rq(p) cpu_rq(task_cpu(p)) |
269 | #define cpu_curr(cpu) (cpu_rq(cpu)->curr) | 276 | #define cpu_curr(cpu) (cpu_rq(cpu)->curr) |
270 | 277 | ||
271 | /* | ||
272 | * Default context-switch locking: | ||
273 | */ | ||
274 | #ifndef prepare_arch_switch | 278 | #ifndef prepare_arch_switch |
275 | # define prepare_arch_switch(rq, next) do { } while (0) | 279 | # define prepare_arch_switch(next) do { } while (0) |
276 | # define finish_arch_switch(rq, next) spin_unlock_irq(&(rq)->lock) | 280 | #endif |
277 | # define task_running(rq, p) ((rq)->curr == (p)) | 281 | #ifndef finish_arch_switch |
282 | # define finish_arch_switch(prev) do { } while (0) | ||
283 | #endif | ||
284 | |||
285 | #ifndef __ARCH_WANT_UNLOCKED_CTXSW | ||
286 | static inline int task_running(runqueue_t *rq, task_t *p) | ||
287 | { | ||
288 | return rq->curr == p; | ||
289 | } | ||
290 | |||
291 | static inline void prepare_lock_switch(runqueue_t *rq, task_t *next) | ||
292 | { | ||
293 | } | ||
294 | |||
295 | static inline void finish_lock_switch(runqueue_t *rq, task_t *prev) | ||
296 | { | ||
297 | spin_unlock_irq(&rq->lock); | ||
298 | } | ||
299 | |||
300 | #else /* __ARCH_WANT_UNLOCKED_CTXSW */ | ||
301 | static inline int task_running(runqueue_t *rq, task_t *p) | ||
302 | { | ||
303 | #ifdef CONFIG_SMP | ||
304 | return p->oncpu; | ||
305 | #else | ||
306 | return rq->curr == p; | ||
307 | #endif | ||
308 | } | ||
309 | |||
310 | static inline void prepare_lock_switch(runqueue_t *rq, task_t *next) | ||
311 | { | ||
312 | #ifdef CONFIG_SMP | ||
313 | /* | ||
314 | * We can optimise this out completely for !SMP, because the | ||
315 | * SMP rebalancing from interrupt is the only thing that cares | ||
316 | * here. | ||
317 | */ | ||
318 | next->oncpu = 1; | ||
319 | #endif | ||
320 | #ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW | ||
321 | spin_unlock_irq(&rq->lock); | ||
322 | #else | ||
323 | spin_unlock(&rq->lock); | ||
324 | #endif | ||
325 | } | ||
326 | |||
327 | static inline void finish_lock_switch(runqueue_t *rq, task_t *prev) | ||
328 | { | ||
329 | #ifdef CONFIG_SMP | ||
330 | /* | ||
331 | * After ->oncpu is cleared, the task can be moved to a different CPU. | ||
332 | * We must ensure this doesn't happen until the switch is completely | ||
333 | * finished. | ||
334 | */ | ||
335 | smp_wmb(); | ||
336 | prev->oncpu = 0; | ||
278 | #endif | 337 | #endif |
338 | #ifndef __ARCH_WANT_INTERRUPTS_ON_CTXSW | ||
339 | local_irq_enable(); | ||
340 | #endif | ||
341 | } | ||
342 | #endif /* __ARCH_WANT_UNLOCKED_CTXSW */ | ||
279 | 343 | ||
280 | /* | 344 | /* |
281 | * task_rq_lock - lock the runqueue a given task resides on and disable | 345 | * task_rq_lock - lock the runqueue a given task resides on and disable |
@@ -309,7 +373,7 @@ static inline void task_rq_unlock(runqueue_t *rq, unsigned long *flags) | |||
309 | * bump this up when changing the output format or the meaning of an existing | 373 | * bump this up when changing the output format or the meaning of an existing |
310 | * format, so that tools can adapt (or abort) | 374 | * format, so that tools can adapt (or abort) |
311 | */ | 375 | */ |
312 | #define SCHEDSTAT_VERSION 11 | 376 | #define SCHEDSTAT_VERSION 12 |
313 | 377 | ||
314 | static int show_schedstat(struct seq_file *seq, void *v) | 378 | static int show_schedstat(struct seq_file *seq, void *v) |
315 | { | 379 | { |
@@ -338,6 +402,7 @@ static int show_schedstat(struct seq_file *seq, void *v) | |||
338 | 402 | ||
339 | #ifdef CONFIG_SMP | 403 | #ifdef CONFIG_SMP |
340 | /* domain-specific stats */ | 404 | /* domain-specific stats */ |
405 | preempt_disable(); | ||
341 | for_each_domain(cpu, sd) { | 406 | for_each_domain(cpu, sd) { |
342 | enum idle_type itype; | 407 | enum idle_type itype; |
343 | char mask_str[NR_CPUS]; | 408 | char mask_str[NR_CPUS]; |
@@ -356,11 +421,13 @@ static int show_schedstat(struct seq_file *seq, void *v) | |||
356 | sd->lb_nobusyq[itype], | 421 | sd->lb_nobusyq[itype], |
357 | sd->lb_nobusyg[itype]); | 422 | sd->lb_nobusyg[itype]); |
358 | } | 423 | } |
359 | seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu %lu\n", | 424 | seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n", |
360 | sd->alb_cnt, sd->alb_failed, sd->alb_pushed, | 425 | sd->alb_cnt, sd->alb_failed, sd->alb_pushed, |
361 | sd->sbe_pushed, sd->sbe_attempts, | 426 | sd->sbe_cnt, sd->sbe_balanced, sd->sbe_pushed, |
427 | sd->sbf_cnt, sd->sbf_balanced, sd->sbf_pushed, | ||
362 | sd->ttwu_wake_remote, sd->ttwu_move_affine, sd->ttwu_move_balance); | 428 | sd->ttwu_wake_remote, sd->ttwu_move_affine, sd->ttwu_move_balance); |
363 | } | 429 | } |
430 | preempt_enable(); | ||
364 | #endif | 431 | #endif |
365 | } | 432 | } |
366 | return 0; | 433 | return 0; |
@@ -414,22 +481,6 @@ static inline runqueue_t *this_rq_lock(void) | |||
414 | return rq; | 481 | return rq; |
415 | } | 482 | } |
416 | 483 | ||
417 | #ifdef CONFIG_SCHED_SMT | ||
418 | static int cpu_and_siblings_are_idle(int cpu) | ||
419 | { | ||
420 | int sib; | ||
421 | for_each_cpu_mask(sib, cpu_sibling_map[cpu]) { | ||
422 | if (idle_cpu(sib)) | ||
423 | continue; | ||
424 | return 0; | ||
425 | } | ||
426 | |||
427 | return 1; | ||
428 | } | ||
429 | #else | ||
430 | #define cpu_and_siblings_are_idle(A) idle_cpu(A) | ||
431 | #endif | ||
432 | |||
433 | #ifdef CONFIG_SCHEDSTATS | 484 | #ifdef CONFIG_SCHEDSTATS |
434 | /* | 485 | /* |
435 | * Called when a process is dequeued from the active array and given | 486 | * Called when a process is dequeued from the active array and given |
@@ -622,7 +673,7 @@ static inline void __activate_idle_task(task_t *p, runqueue_t *rq) | |||
622 | rq->nr_running++; | 673 | rq->nr_running++; |
623 | } | 674 | } |
624 | 675 | ||
625 | static void recalc_task_prio(task_t *p, unsigned long long now) | 676 | static int recalc_task_prio(task_t *p, unsigned long long now) |
626 | { | 677 | { |
627 | /* Caller must always ensure 'now >= p->timestamp' */ | 678 | /* Caller must always ensure 'now >= p->timestamp' */ |
628 | unsigned long long __sleep_time = now - p->timestamp; | 679 | unsigned long long __sleep_time = now - p->timestamp; |
@@ -681,7 +732,7 @@ static void recalc_task_prio(task_t *p, unsigned long long now) | |||
681 | } | 732 | } |
682 | } | 733 | } |
683 | 734 | ||
684 | p->prio = effective_prio(p); | 735 | return effective_prio(p); |
685 | } | 736 | } |
686 | 737 | ||
687 | /* | 738 | /* |
@@ -704,7 +755,7 @@ static void activate_task(task_t *p, runqueue_t *rq, int local) | |||
704 | } | 755 | } |
705 | #endif | 756 | #endif |
706 | 757 | ||
707 | recalc_task_prio(p, now); | 758 | p->prio = recalc_task_prio(p, now); |
708 | 759 | ||
709 | /* | 760 | /* |
710 | * This checks to make sure it's not an uninterruptible task | 761 | * This checks to make sure it's not an uninterruptible task |
@@ -782,22 +833,12 @@ inline int task_curr(const task_t *p) | |||
782 | } | 833 | } |
783 | 834 | ||
784 | #ifdef CONFIG_SMP | 835 | #ifdef CONFIG_SMP |
785 | enum request_type { | ||
786 | REQ_MOVE_TASK, | ||
787 | REQ_SET_DOMAIN, | ||
788 | }; | ||
789 | |||
790 | typedef struct { | 836 | typedef struct { |
791 | struct list_head list; | 837 | struct list_head list; |
792 | enum request_type type; | ||
793 | 838 | ||
794 | /* For REQ_MOVE_TASK */ | ||
795 | task_t *task; | 839 | task_t *task; |
796 | int dest_cpu; | 840 | int dest_cpu; |
797 | 841 | ||
798 | /* For REQ_SET_DOMAIN */ | ||
799 | struct sched_domain *sd; | ||
800 | |||
801 | struct completion done; | 842 | struct completion done; |
802 | } migration_req_t; | 843 | } migration_req_t; |
803 | 844 | ||
@@ -819,7 +860,6 @@ static int migrate_task(task_t *p, int dest_cpu, migration_req_t *req) | |||
819 | } | 860 | } |
820 | 861 | ||
821 | init_completion(&req->done); | 862 | init_completion(&req->done); |
822 | req->type = REQ_MOVE_TASK; | ||
823 | req->task = p; | 863 | req->task = p; |
824 | req->dest_cpu = dest_cpu; | 864 | req->dest_cpu = dest_cpu; |
825 | list_add(&req->list, &rq->migration_queue); | 865 | list_add(&req->list, &rq->migration_queue); |
@@ -886,26 +926,154 @@ void kick_process(task_t *p) | |||
886 | * We want to under-estimate the load of migration sources, to | 926 | * We want to under-estimate the load of migration sources, to |
887 | * balance conservatively. | 927 | * balance conservatively. |
888 | */ | 928 | */ |
889 | static inline unsigned long source_load(int cpu) | 929 | static inline unsigned long source_load(int cpu, int type) |
890 | { | 930 | { |
891 | runqueue_t *rq = cpu_rq(cpu); | 931 | runqueue_t *rq = cpu_rq(cpu); |
892 | unsigned long load_now = rq->nr_running * SCHED_LOAD_SCALE; | 932 | unsigned long load_now = rq->nr_running * SCHED_LOAD_SCALE; |
933 | if (type == 0) | ||
934 | return load_now; | ||
893 | 935 | ||
894 | return min(rq->cpu_load, load_now); | 936 | return min(rq->cpu_load[type-1], load_now); |
895 | } | 937 | } |
896 | 938 | ||
897 | /* | 939 | /* |
898 | * Return a high guess at the load of a migration-target cpu | 940 | * Return a high guess at the load of a migration-target cpu |
899 | */ | 941 | */ |
900 | static inline unsigned long target_load(int cpu) | 942 | static inline unsigned long target_load(int cpu, int type) |
901 | { | 943 | { |
902 | runqueue_t *rq = cpu_rq(cpu); | 944 | runqueue_t *rq = cpu_rq(cpu); |
903 | unsigned long load_now = rq->nr_running * SCHED_LOAD_SCALE; | 945 | unsigned long load_now = rq->nr_running * SCHED_LOAD_SCALE; |
946 | if (type == 0) | ||
947 | return load_now; | ||
904 | 948 | ||
905 | return max(rq->cpu_load, load_now); | 949 | return max(rq->cpu_load[type-1], load_now); |
906 | } | 950 | } |
907 | 951 | ||
908 | #endif | 952 | /* |
953 | * find_idlest_group finds and returns the least busy CPU group within the | ||
954 | * domain. | ||
955 | */ | ||
956 | static struct sched_group * | ||
957 | find_idlest_group(struct sched_domain *sd, struct task_struct *p, int this_cpu) | ||
958 | { | ||
959 | struct sched_group *idlest = NULL, *this = NULL, *group = sd->groups; | ||
960 | unsigned long min_load = ULONG_MAX, this_load = 0; | ||
961 | int load_idx = sd->forkexec_idx; | ||
962 | int imbalance = 100 + (sd->imbalance_pct-100)/2; | ||
963 | |||
964 | do { | ||
965 | unsigned long load, avg_load; | ||
966 | int local_group; | ||
967 | int i; | ||
968 | |||
969 | local_group = cpu_isset(this_cpu, group->cpumask); | ||
970 | /* XXX: put a cpus allowed check */ | ||
971 | |||
972 | /* Tally up the load of all CPUs in the group */ | ||
973 | avg_load = 0; | ||
974 | |||
975 | for_each_cpu_mask(i, group->cpumask) { | ||
976 | /* Bias balancing toward cpus of our domain */ | ||
977 | if (local_group) | ||
978 | load = source_load(i, load_idx); | ||
979 | else | ||
980 | load = target_load(i, load_idx); | ||
981 | |||
982 | avg_load += load; | ||
983 | } | ||
984 | |||
985 | /* Adjust by relative CPU power of the group */ | ||
986 | avg_load = (avg_load * SCHED_LOAD_SCALE) / group->cpu_power; | ||
987 | |||
988 | if (local_group) { | ||
989 | this_load = avg_load; | ||
990 | this = group; | ||
991 | } else if (avg_load < min_load) { | ||
992 | min_load = avg_load; | ||
993 | idlest = group; | ||
994 | } | ||
995 | group = group->next; | ||
996 | } while (group != sd->groups); | ||
997 | |||
998 | if (!idlest || 100*this_load < imbalance*min_load) | ||
999 | return NULL; | ||
1000 | return idlest; | ||
1001 | } | ||
1002 | |||
1003 | /* | ||
1004 | * find_idlest_queue - find the idlest runqueue among the cpus in group. | ||
1005 | */ | ||
1006 | static int find_idlest_cpu(struct sched_group *group, int this_cpu) | ||
1007 | { | ||
1008 | unsigned long load, min_load = ULONG_MAX; | ||
1009 | int idlest = -1; | ||
1010 | int i; | ||
1011 | |||
1012 | for_each_cpu_mask(i, group->cpumask) { | ||
1013 | load = source_load(i, 0); | ||
1014 | |||
1015 | if (load < min_load || (load == min_load && i == this_cpu)) { | ||
1016 | min_load = load; | ||
1017 | idlest = i; | ||
1018 | } | ||
1019 | } | ||
1020 | |||
1021 | return idlest; | ||
1022 | } | ||
1023 | |||
1024 | /* | ||
1025 | * sched_balance_self: balance the current task (running on cpu) in domains | ||
1026 | * that have the 'flag' flag set. In practice, this is SD_BALANCE_FORK and | ||
1027 | * SD_BALANCE_EXEC. | ||
1028 | * | ||
1029 | * Balance, ie. select the least loaded group. | ||
1030 | * | ||
1031 | * Returns the target CPU number, or the same CPU if no balancing is needed. | ||
1032 | * | ||
1033 | * preempt must be disabled. | ||
1034 | */ | ||
1035 | static int sched_balance_self(int cpu, int flag) | ||
1036 | { | ||
1037 | struct task_struct *t = current; | ||
1038 | struct sched_domain *tmp, *sd = NULL; | ||
1039 | |||
1040 | for_each_domain(cpu, tmp) | ||
1041 | if (tmp->flags & flag) | ||
1042 | sd = tmp; | ||
1043 | |||
1044 | while (sd) { | ||
1045 | cpumask_t span; | ||
1046 | struct sched_group *group; | ||
1047 | int new_cpu; | ||
1048 | int weight; | ||
1049 | |||
1050 | span = sd->span; | ||
1051 | group = find_idlest_group(sd, t, cpu); | ||
1052 | if (!group) | ||
1053 | goto nextlevel; | ||
1054 | |||
1055 | new_cpu = find_idlest_cpu(group, cpu); | ||
1056 | if (new_cpu == -1 || new_cpu == cpu) | ||
1057 | goto nextlevel; | ||
1058 | |||
1059 | /* Now try balancing at a lower domain level */ | ||
1060 | cpu = new_cpu; | ||
1061 | nextlevel: | ||
1062 | sd = NULL; | ||
1063 | weight = cpus_weight(span); | ||
1064 | for_each_domain(cpu, tmp) { | ||
1065 | if (weight <= cpus_weight(tmp->span)) | ||
1066 | break; | ||
1067 | if (tmp->flags & flag) | ||
1068 | sd = tmp; | ||
1069 | } | ||
1070 | /* while loop will break here if sd == NULL */ | ||
1071 | } | ||
1072 | |||
1073 | return cpu; | ||
1074 | } | ||
1075 | |||
1076 | #endif /* CONFIG_SMP */ | ||
909 | 1077 | ||
910 | /* | 1078 | /* |
911 | * wake_idle() will wake a task on an idle cpu if task->cpu is | 1079 | * wake_idle() will wake a task on an idle cpu if task->cpu is |
@@ -927,14 +1095,14 @@ static int wake_idle(int cpu, task_t *p) | |||
927 | 1095 | ||
928 | for_each_domain(cpu, sd) { | 1096 | for_each_domain(cpu, sd) { |
929 | if (sd->flags & SD_WAKE_IDLE) { | 1097 | if (sd->flags & SD_WAKE_IDLE) { |
930 | cpus_and(tmp, sd->span, cpu_online_map); | 1098 | cpus_and(tmp, sd->span, p->cpus_allowed); |
931 | cpus_and(tmp, tmp, p->cpus_allowed); | ||
932 | for_each_cpu_mask(i, tmp) { | 1099 | for_each_cpu_mask(i, tmp) { |
933 | if (idle_cpu(i)) | 1100 | if (idle_cpu(i)) |
934 | return i; | 1101 | return i; |
935 | } | 1102 | } |
936 | } | 1103 | } |
937 | else break; | 1104 | else |
1105 | break; | ||
938 | } | 1106 | } |
939 | return cpu; | 1107 | return cpu; |
940 | } | 1108 | } |
@@ -967,7 +1135,7 @@ static int try_to_wake_up(task_t * p, unsigned int state, int sync) | |||
967 | runqueue_t *rq; | 1135 | runqueue_t *rq; |
968 | #ifdef CONFIG_SMP | 1136 | #ifdef CONFIG_SMP |
969 | unsigned long load, this_load; | 1137 | unsigned long load, this_load; |
970 | struct sched_domain *sd; | 1138 | struct sched_domain *sd, *this_sd = NULL; |
971 | int new_cpu; | 1139 | int new_cpu; |
972 | #endif | 1140 | #endif |
973 | 1141 | ||
@@ -986,70 +1154,69 @@ static int try_to_wake_up(task_t * p, unsigned int state, int sync) | |||
986 | if (unlikely(task_running(rq, p))) | 1154 | if (unlikely(task_running(rq, p))) |
987 | goto out_activate; | 1155 | goto out_activate; |
988 | 1156 | ||
989 | #ifdef CONFIG_SCHEDSTATS | 1157 | new_cpu = cpu; |
1158 | |||
990 | schedstat_inc(rq, ttwu_cnt); | 1159 | schedstat_inc(rq, ttwu_cnt); |
991 | if (cpu == this_cpu) { | 1160 | if (cpu == this_cpu) { |
992 | schedstat_inc(rq, ttwu_local); | 1161 | schedstat_inc(rq, ttwu_local); |
993 | } else { | 1162 | goto out_set_cpu; |
994 | for_each_domain(this_cpu, sd) { | 1163 | } |
995 | if (cpu_isset(cpu, sd->span)) { | 1164 | |
996 | schedstat_inc(sd, ttwu_wake_remote); | 1165 | for_each_domain(this_cpu, sd) { |
997 | break; | 1166 | if (cpu_isset(cpu, sd->span)) { |
998 | } | 1167 | schedstat_inc(sd, ttwu_wake_remote); |
1168 | this_sd = sd; | ||
1169 | break; | ||
999 | } | 1170 | } |
1000 | } | 1171 | } |
1001 | #endif | ||
1002 | 1172 | ||
1003 | new_cpu = cpu; | 1173 | if (unlikely(!cpu_isset(this_cpu, p->cpus_allowed))) |
1004 | if (cpu == this_cpu || unlikely(!cpu_isset(this_cpu, p->cpus_allowed))) | ||
1005 | goto out_set_cpu; | 1174 | goto out_set_cpu; |
1006 | 1175 | ||
1007 | load = source_load(cpu); | ||
1008 | this_load = target_load(this_cpu); | ||
1009 | |||
1010 | /* | 1176 | /* |
1011 | * If sync wakeup then subtract the (maximum possible) effect of | 1177 | * Check for affine wakeup and passive balancing possibilities. |
1012 | * the currently running task from the load of the current CPU: | ||
1013 | */ | 1178 | */ |
1014 | if (sync) | 1179 | if (this_sd) { |
1015 | this_load -= SCHED_LOAD_SCALE; | 1180 | int idx = this_sd->wake_idx; |
1181 | unsigned int imbalance; | ||
1016 | 1182 | ||
1017 | /* Don't pull the task off an idle CPU to a busy one */ | 1183 | imbalance = 100 + (this_sd->imbalance_pct - 100) / 2; |
1018 | if (load < SCHED_LOAD_SCALE/2 && this_load > SCHED_LOAD_SCALE/2) | ||
1019 | goto out_set_cpu; | ||
1020 | 1184 | ||
1021 | new_cpu = this_cpu; /* Wake to this CPU if we can */ | 1185 | load = source_load(cpu, idx); |
1186 | this_load = target_load(this_cpu, idx); | ||
1022 | 1187 | ||
1023 | /* | 1188 | new_cpu = this_cpu; /* Wake to this CPU if we can */ |
1024 | * Scan domains for affine wakeup and passive balancing | ||
1025 | * possibilities. | ||
1026 | */ | ||
1027 | for_each_domain(this_cpu, sd) { | ||
1028 | unsigned int imbalance; | ||
1029 | /* | ||
1030 | * Start passive balancing when half the imbalance_pct | ||
1031 | * limit is reached. | ||
1032 | */ | ||
1033 | imbalance = sd->imbalance_pct + (sd->imbalance_pct - 100) / 2; | ||
1034 | 1189 | ||
1035 | if ((sd->flags & SD_WAKE_AFFINE) && | 1190 | if (this_sd->flags & SD_WAKE_AFFINE) { |
1036 | !task_hot(p, rq->timestamp_last_tick, sd)) { | 1191 | unsigned long tl = this_load; |
1037 | /* | 1192 | /* |
1038 | * This domain has SD_WAKE_AFFINE and p is cache cold | 1193 | * If sync wakeup then subtract the (maximum possible) |
1039 | * in this domain. | 1194 | * effect of the currently running task from the load |
1195 | * of the current CPU: | ||
1040 | */ | 1196 | */ |
1041 | if (cpu_isset(cpu, sd->span)) { | 1197 | if (sync) |
1042 | schedstat_inc(sd, ttwu_move_affine); | 1198 | tl -= SCHED_LOAD_SCALE; |
1199 | |||
1200 | if ((tl <= load && | ||
1201 | tl + target_load(cpu, idx) <= SCHED_LOAD_SCALE) || | ||
1202 | 100*(tl + SCHED_LOAD_SCALE) <= imbalance*load) { | ||
1203 | /* | ||
1204 | * This domain has SD_WAKE_AFFINE and | ||
1205 | * p is cache cold in this domain, and | ||
1206 | * there is no bad imbalance. | ||
1207 | */ | ||
1208 | schedstat_inc(this_sd, ttwu_move_affine); | ||
1043 | goto out_set_cpu; | 1209 | goto out_set_cpu; |
1044 | } | 1210 | } |
1045 | } else if ((sd->flags & SD_WAKE_BALANCE) && | 1211 | } |
1046 | imbalance*this_load <= 100*load) { | 1212 | |
1047 | /* | 1213 | /* |
1048 | * This domain has SD_WAKE_BALANCE and there is | 1214 | * Start passive balancing when half the imbalance_pct |
1049 | * an imbalance. | 1215 | * limit is reached. |
1050 | */ | 1216 | */ |
1051 | if (cpu_isset(cpu, sd->span)) { | 1217 | if (this_sd->flags & SD_WAKE_BALANCE) { |
1052 | schedstat_inc(sd, ttwu_move_balance); | 1218 | if (imbalance*this_load <= 100*load) { |
1219 | schedstat_inc(this_sd, ttwu_move_balance); | ||
1053 | goto out_set_cpu; | 1220 | goto out_set_cpu; |
1054 | } | 1221 | } |
1055 | } | 1222 | } |
@@ -1120,17 +1287,19 @@ int fastcall wake_up_state(task_t *p, unsigned int state) | |||
1120 | return try_to_wake_up(p, state, 0); | 1287 | return try_to_wake_up(p, state, 0); |
1121 | } | 1288 | } |
1122 | 1289 | ||
1123 | #ifdef CONFIG_SMP | ||
1124 | static int find_idlest_cpu(struct task_struct *p, int this_cpu, | ||
1125 | struct sched_domain *sd); | ||
1126 | #endif | ||
1127 | |||
1128 | /* | 1290 | /* |
1129 | * Perform scheduler related setup for a newly forked process p. | 1291 | * Perform scheduler related setup for a newly forked process p. |
1130 | * p is forked by current. | 1292 | * p is forked by current. |
1131 | */ | 1293 | */ |
1132 | void fastcall sched_fork(task_t *p) | 1294 | void fastcall sched_fork(task_t *p, int clone_flags) |
1133 | { | 1295 | { |
1296 | int cpu = get_cpu(); | ||
1297 | |||
1298 | #ifdef CONFIG_SMP | ||
1299 | cpu = sched_balance_self(cpu, SD_BALANCE_FORK); | ||
1300 | #endif | ||
1301 | set_task_cpu(p, cpu); | ||
1302 | |||
1134 | /* | 1303 | /* |
1135 | * We mark the process as running here, but have not actually | 1304 | * We mark the process as running here, but have not actually |
1136 | * inserted it onto the runqueue yet. This guarantees that | 1305 | * inserted it onto the runqueue yet. This guarantees that |
@@ -1140,17 +1309,14 @@ void fastcall sched_fork(task_t *p) | |||
1140 | p->state = TASK_RUNNING; | 1309 | p->state = TASK_RUNNING; |
1141 | INIT_LIST_HEAD(&p->run_list); | 1310 | INIT_LIST_HEAD(&p->run_list); |
1142 | p->array = NULL; | 1311 | p->array = NULL; |
1143 | spin_lock_init(&p->switch_lock); | ||
1144 | #ifdef CONFIG_SCHEDSTATS | 1312 | #ifdef CONFIG_SCHEDSTATS |
1145 | memset(&p->sched_info, 0, sizeof(p->sched_info)); | 1313 | memset(&p->sched_info, 0, sizeof(p->sched_info)); |
1146 | #endif | 1314 | #endif |
1315 | #if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW) | ||
1316 | p->oncpu = 0; | ||
1317 | #endif | ||
1147 | #ifdef CONFIG_PREEMPT | 1318 | #ifdef CONFIG_PREEMPT |
1148 | /* | 1319 | /* Want to start with kernel preemption disabled. */ |
1149 | * During context-switch we hold precisely one spinlock, which | ||
1150 | * schedule_tail drops. (in the common case it's this_rq()->lock, | ||
1151 | * but it also can be p->switch_lock.) So we compensate with a count | ||
1152 | * of 1. Also, we want to start with kernel preemption disabled. | ||
1153 | */ | ||
1154 | p->thread_info->preempt_count = 1; | 1320 | p->thread_info->preempt_count = 1; |
1155 | #endif | 1321 | #endif |
1156 | /* | 1322 | /* |
@@ -1174,12 +1340,10 @@ void fastcall sched_fork(task_t *p) | |||
1174 | * runqueue lock is not a problem. | 1340 | * runqueue lock is not a problem. |
1175 | */ | 1341 | */ |
1176 | current->time_slice = 1; | 1342 | current->time_slice = 1; |
1177 | preempt_disable(); | ||
1178 | scheduler_tick(); | 1343 | scheduler_tick(); |
1179 | local_irq_enable(); | 1344 | } |
1180 | preempt_enable(); | 1345 | local_irq_enable(); |
1181 | } else | 1346 | put_cpu(); |
1182 | local_irq_enable(); | ||
1183 | } | 1347 | } |
1184 | 1348 | ||
1185 | /* | 1349 | /* |
@@ -1196,10 +1360,9 @@ void fastcall wake_up_new_task(task_t * p, unsigned long clone_flags) | |||
1196 | runqueue_t *rq, *this_rq; | 1360 | runqueue_t *rq, *this_rq; |
1197 | 1361 | ||
1198 | rq = task_rq_lock(p, &flags); | 1362 | rq = task_rq_lock(p, &flags); |
1199 | cpu = task_cpu(p); | ||
1200 | this_cpu = smp_processor_id(); | ||
1201 | |||
1202 | BUG_ON(p->state != TASK_RUNNING); | 1363 | BUG_ON(p->state != TASK_RUNNING); |
1364 | this_cpu = smp_processor_id(); | ||
1365 | cpu = task_cpu(p); | ||
1203 | 1366 | ||
1204 | /* | 1367 | /* |
1205 | * We decrease the sleep average of forking parents | 1368 | * We decrease the sleep average of forking parents |
@@ -1296,22 +1459,40 @@ void fastcall sched_exit(task_t * p) | |||
1296 | } | 1459 | } |
1297 | 1460 | ||
1298 | /** | 1461 | /** |
1462 | * prepare_task_switch - prepare to switch tasks | ||
1463 | * @rq: the runqueue preparing to switch | ||
1464 | * @next: the task we are going to switch to. | ||
1465 | * | ||
1466 | * This is called with the rq lock held and interrupts off. It must | ||
1467 | * be paired with a subsequent finish_task_switch after the context | ||
1468 | * switch. | ||
1469 | * | ||
1470 | * prepare_task_switch sets up locking and calls architecture specific | ||
1471 | * hooks. | ||
1472 | */ | ||
1473 | static inline void prepare_task_switch(runqueue_t *rq, task_t *next) | ||
1474 | { | ||
1475 | prepare_lock_switch(rq, next); | ||
1476 | prepare_arch_switch(next); | ||
1477 | } | ||
1478 | |||
1479 | /** | ||
1299 | * finish_task_switch - clean up after a task-switch | 1480 | * finish_task_switch - clean up after a task-switch |
1300 | * @prev: the thread we just switched away from. | 1481 | * @prev: the thread we just switched away from. |
1301 | * | 1482 | * |
1302 | * We enter this with the runqueue still locked, and finish_arch_switch() | 1483 | * finish_task_switch must be called after the context switch, paired |
1303 | * will unlock it along with doing any other architecture-specific cleanup | 1484 | * with a prepare_task_switch call before the context switch. |
1304 | * actions. | 1485 | * finish_task_switch will reconcile locking set up by prepare_task_switch, |
1486 | * and do any other architecture-specific cleanup actions. | ||
1305 | * | 1487 | * |
1306 | * Note that we may have delayed dropping an mm in context_switch(). If | 1488 | * Note that we may have delayed dropping an mm in context_switch(). If |
1307 | * so, we finish that here outside of the runqueue lock. (Doing it | 1489 | * so, we finish that here outside of the runqueue lock. (Doing it |
1308 | * with the lock held can cause deadlocks; see schedule() for | 1490 | * with the lock held can cause deadlocks; see schedule() for |
1309 | * details.) | 1491 | * details.) |
1310 | */ | 1492 | */ |
1311 | static inline void finish_task_switch(task_t *prev) | 1493 | static inline void finish_task_switch(runqueue_t *rq, task_t *prev) |
1312 | __releases(rq->lock) | 1494 | __releases(rq->lock) |
1313 | { | 1495 | { |
1314 | runqueue_t *rq = this_rq(); | ||
1315 | struct mm_struct *mm = rq->prev_mm; | 1496 | struct mm_struct *mm = rq->prev_mm; |
1316 | unsigned long prev_task_flags; | 1497 | unsigned long prev_task_flags; |
1317 | 1498 | ||
@@ -1329,7 +1510,8 @@ static inline void finish_task_switch(task_t *prev) | |||
1329 | * Manfred Spraul <manfred@colorfullife.com> | 1510 | * Manfred Spraul <manfred@colorfullife.com> |
1330 | */ | 1511 | */ |
1331 | prev_task_flags = prev->flags; | 1512 | prev_task_flags = prev->flags; |
1332 | finish_arch_switch(rq, prev); | 1513 | finish_arch_switch(prev); |
1514 | finish_lock_switch(rq, prev); | ||
1333 | if (mm) | 1515 | if (mm) |
1334 | mmdrop(mm); | 1516 | mmdrop(mm); |
1335 | if (unlikely(prev_task_flags & PF_DEAD)) | 1517 | if (unlikely(prev_task_flags & PF_DEAD)) |
@@ -1343,8 +1525,12 @@ static inline void finish_task_switch(task_t *prev) | |||
1343 | asmlinkage void schedule_tail(task_t *prev) | 1525 | asmlinkage void schedule_tail(task_t *prev) |
1344 | __releases(rq->lock) | 1526 | __releases(rq->lock) |
1345 | { | 1527 | { |
1346 | finish_task_switch(prev); | 1528 | runqueue_t *rq = this_rq(); |
1347 | 1529 | finish_task_switch(rq, prev); | |
1530 | #ifdef __ARCH_WANT_UNLOCKED_CTXSW | ||
1531 | /* In this case, finish_task_switch does not reenable preemption */ | ||
1532 | preempt_enable(); | ||
1533 | #endif | ||
1348 | if (current->set_child_tid) | 1534 | if (current->set_child_tid) |
1349 | put_user(current->pid, current->set_child_tid); | 1535 | put_user(current->pid, current->set_child_tid); |
1350 | } | 1536 | } |
@@ -1494,51 +1680,6 @@ static void double_lock_balance(runqueue_t *this_rq, runqueue_t *busiest) | |||
1494 | } | 1680 | } |
1495 | 1681 | ||
1496 | /* | 1682 | /* |
1497 | * find_idlest_cpu - find the least busy runqueue. | ||
1498 | */ | ||
1499 | static int find_idlest_cpu(struct task_struct *p, int this_cpu, | ||
1500 | struct sched_domain *sd) | ||
1501 | { | ||
1502 | unsigned long load, min_load, this_load; | ||
1503 | int i, min_cpu; | ||
1504 | cpumask_t mask; | ||
1505 | |||
1506 | min_cpu = UINT_MAX; | ||
1507 | min_load = ULONG_MAX; | ||
1508 | |||
1509 | cpus_and(mask, sd->span, p->cpus_allowed); | ||
1510 | |||
1511 | for_each_cpu_mask(i, mask) { | ||
1512 | load = target_load(i); | ||
1513 | |||
1514 | if (load < min_load) { | ||
1515 | min_cpu = i; | ||
1516 | min_load = load; | ||
1517 | |||
1518 | /* break out early on an idle CPU: */ | ||
1519 | if (!min_load) | ||
1520 | break; | ||
1521 | } | ||
1522 | } | ||
1523 | |||
1524 | /* add +1 to account for the new task */ | ||
1525 | this_load = source_load(this_cpu) + SCHED_LOAD_SCALE; | ||
1526 | |||
1527 | /* | ||
1528 | * Would with the addition of the new task to the | ||
1529 | * current CPU there be an imbalance between this | ||
1530 | * CPU and the idlest CPU? | ||
1531 | * | ||
1532 | * Use half of the balancing threshold - new-context is | ||
1533 | * a good opportunity to balance. | ||
1534 | */ | ||
1535 | if (min_load*(100 + (sd->imbalance_pct-100)/2) < this_load*100) | ||
1536 | return min_cpu; | ||
1537 | |||
1538 | return this_cpu; | ||
1539 | } | ||
1540 | |||
1541 | /* | ||
1542 | * If dest_cpu is allowed for this process, migrate the task to it. | 1683 | * If dest_cpu is allowed for this process, migrate the task to it. |
1543 | * This is accomplished by forcing the cpu_allowed mask to only | 1684 | * This is accomplished by forcing the cpu_allowed mask to only |
1544 | * allow dest_cpu, which will force the cpu onto dest_cpu. Then | 1685 | * allow dest_cpu, which will force the cpu onto dest_cpu. Then |
@@ -1571,37 +1712,16 @@ out: | |||
1571 | } | 1712 | } |
1572 | 1713 | ||
1573 | /* | 1714 | /* |
1574 | * sched_exec(): find the highest-level, exec-balance-capable | 1715 | * sched_exec - execve() is a valuable balancing opportunity, because at |
1575 | * domain and try to migrate the task to the least loaded CPU. | 1716 | * this point the task has the smallest effective memory and cache footprint. |
1576 | * | ||
1577 | * execve() is a valuable balancing opportunity, because at this point | ||
1578 | * the task has the smallest effective memory and cache footprint. | ||
1579 | */ | 1717 | */ |
1580 | void sched_exec(void) | 1718 | void sched_exec(void) |
1581 | { | 1719 | { |
1582 | struct sched_domain *tmp, *sd = NULL; | ||
1583 | int new_cpu, this_cpu = get_cpu(); | 1720 | int new_cpu, this_cpu = get_cpu(); |
1584 | 1721 | new_cpu = sched_balance_self(this_cpu, SD_BALANCE_EXEC); | |
1585 | /* Prefer the current CPU if there's only this task running */ | ||
1586 | if (this_rq()->nr_running <= 1) | ||
1587 | goto out; | ||
1588 | |||
1589 | for_each_domain(this_cpu, tmp) | ||
1590 | if (tmp->flags & SD_BALANCE_EXEC) | ||
1591 | sd = tmp; | ||
1592 | |||
1593 | if (sd) { | ||
1594 | schedstat_inc(sd, sbe_attempts); | ||
1595 | new_cpu = find_idlest_cpu(current, this_cpu, sd); | ||
1596 | if (new_cpu != this_cpu) { | ||
1597 | schedstat_inc(sd, sbe_pushed); | ||
1598 | put_cpu(); | ||
1599 | sched_migrate_task(current, new_cpu); | ||
1600 | return; | ||
1601 | } | ||
1602 | } | ||
1603 | out: | ||
1604 | put_cpu(); | 1722 | put_cpu(); |
1723 | if (new_cpu != this_cpu) | ||
1724 | sched_migrate_task(current, new_cpu); | ||
1605 | } | 1725 | } |
1606 | 1726 | ||
1607 | /* | 1727 | /* |
@@ -1632,7 +1752,7 @@ void pull_task(runqueue_t *src_rq, prio_array_t *src_array, task_t *p, | |||
1632 | */ | 1752 | */ |
1633 | static inline | 1753 | static inline |
1634 | int can_migrate_task(task_t *p, runqueue_t *rq, int this_cpu, | 1754 | int can_migrate_task(task_t *p, runqueue_t *rq, int this_cpu, |
1635 | struct sched_domain *sd, enum idle_type idle) | 1755 | struct sched_domain *sd, enum idle_type idle, int *all_pinned) |
1636 | { | 1756 | { |
1637 | /* | 1757 | /* |
1638 | * We do not migrate tasks that are: | 1758 | * We do not migrate tasks that are: |
@@ -1640,23 +1760,24 @@ int can_migrate_task(task_t *p, runqueue_t *rq, int this_cpu, | |||
1640 | * 2) cannot be migrated to this CPU due to cpus_allowed, or | 1760 | * 2) cannot be migrated to this CPU due to cpus_allowed, or |
1641 | * 3) are cache-hot on their current CPU. | 1761 | * 3) are cache-hot on their current CPU. |
1642 | */ | 1762 | */ |
1643 | if (task_running(rq, p)) | ||
1644 | return 0; | ||
1645 | if (!cpu_isset(this_cpu, p->cpus_allowed)) | 1763 | if (!cpu_isset(this_cpu, p->cpus_allowed)) |
1646 | return 0; | 1764 | return 0; |
1765 | *all_pinned = 0; | ||
1766 | |||
1767 | if (task_running(rq, p)) | ||
1768 | return 0; | ||
1647 | 1769 | ||
1648 | /* | 1770 | /* |
1649 | * Aggressive migration if: | 1771 | * Aggressive migration if: |
1650 | * 1) the [whole] cpu is idle, or | 1772 | * 1) task is cache cold, or |
1651 | * 2) too many balance attempts have failed. | 1773 | * 2) too many balance attempts have failed. |
1652 | */ | 1774 | */ |
1653 | 1775 | ||
1654 | if (cpu_and_siblings_are_idle(this_cpu) || \ | 1776 | if (sd->nr_balance_failed > sd->cache_nice_tries) |
1655 | sd->nr_balance_failed > sd->cache_nice_tries) | ||
1656 | return 1; | 1777 | return 1; |
1657 | 1778 | ||
1658 | if (task_hot(p, rq->timestamp_last_tick, sd)) | 1779 | if (task_hot(p, rq->timestamp_last_tick, sd)) |
1659 | return 0; | 1780 | return 0; |
1660 | return 1; | 1781 | return 1; |
1661 | } | 1782 | } |
1662 | 1783 | ||
@@ -1669,16 +1790,18 @@ int can_migrate_task(task_t *p, runqueue_t *rq, int this_cpu, | |||
1669 | */ | 1790 | */ |
1670 | static int move_tasks(runqueue_t *this_rq, int this_cpu, runqueue_t *busiest, | 1791 | static int move_tasks(runqueue_t *this_rq, int this_cpu, runqueue_t *busiest, |
1671 | unsigned long max_nr_move, struct sched_domain *sd, | 1792 | unsigned long max_nr_move, struct sched_domain *sd, |
1672 | enum idle_type idle) | 1793 | enum idle_type idle, int *all_pinned) |
1673 | { | 1794 | { |
1674 | prio_array_t *array, *dst_array; | 1795 | prio_array_t *array, *dst_array; |
1675 | struct list_head *head, *curr; | 1796 | struct list_head *head, *curr; |
1676 | int idx, pulled = 0; | 1797 | int idx, pulled = 0, pinned = 0; |
1677 | task_t *tmp; | 1798 | task_t *tmp; |
1678 | 1799 | ||
1679 | if (max_nr_move <= 0 || busiest->nr_running <= 1) | 1800 | if (max_nr_move == 0) |
1680 | goto out; | 1801 | goto out; |
1681 | 1802 | ||
1803 | pinned = 1; | ||
1804 | |||
1682 | /* | 1805 | /* |
1683 | * We first consider expired tasks. Those will likely not be | 1806 | * We first consider expired tasks. Those will likely not be |
1684 | * executed in the near future, and they are most likely to | 1807 | * executed in the near future, and they are most likely to |
@@ -1717,7 +1840,7 @@ skip_queue: | |||
1717 | 1840 | ||
1718 | curr = curr->prev; | 1841 | curr = curr->prev; |
1719 | 1842 | ||
1720 | if (!can_migrate_task(tmp, busiest, this_cpu, sd, idle)) { | 1843 | if (!can_migrate_task(tmp, busiest, this_cpu, sd, idle, &pinned)) { |
1721 | if (curr != head) | 1844 | if (curr != head) |
1722 | goto skip_queue; | 1845 | goto skip_queue; |
1723 | idx++; | 1846 | idx++; |
@@ -1746,6 +1869,9 @@ out: | |||
1746 | * inside pull_task(). | 1869 | * inside pull_task(). |
1747 | */ | 1870 | */ |
1748 | schedstat_add(sd, lb_gained[idle], pulled); | 1871 | schedstat_add(sd, lb_gained[idle], pulled); |
1872 | |||
1873 | if (all_pinned) | ||
1874 | *all_pinned = pinned; | ||
1749 | return pulled; | 1875 | return pulled; |
1750 | } | 1876 | } |
1751 | 1877 | ||
@@ -1760,8 +1886,15 @@ find_busiest_group(struct sched_domain *sd, int this_cpu, | |||
1760 | { | 1886 | { |
1761 | struct sched_group *busiest = NULL, *this = NULL, *group = sd->groups; | 1887 | struct sched_group *busiest = NULL, *this = NULL, *group = sd->groups; |
1762 | unsigned long max_load, avg_load, total_load, this_load, total_pwr; | 1888 | unsigned long max_load, avg_load, total_load, this_load, total_pwr; |
1889 | int load_idx; | ||
1763 | 1890 | ||
1764 | max_load = this_load = total_load = total_pwr = 0; | 1891 | max_load = this_load = total_load = total_pwr = 0; |
1892 | if (idle == NOT_IDLE) | ||
1893 | load_idx = sd->busy_idx; | ||
1894 | else if (idle == NEWLY_IDLE) | ||
1895 | load_idx = sd->newidle_idx; | ||
1896 | else | ||
1897 | load_idx = sd->idle_idx; | ||
1765 | 1898 | ||
1766 | do { | 1899 | do { |
1767 | unsigned long load; | 1900 | unsigned long load; |
@@ -1776,9 +1909,9 @@ find_busiest_group(struct sched_domain *sd, int this_cpu, | |||
1776 | for_each_cpu_mask(i, group->cpumask) { | 1909 | for_each_cpu_mask(i, group->cpumask) { |
1777 | /* Bias balancing toward cpus of our domain */ | 1910 | /* Bias balancing toward cpus of our domain */ |
1778 | if (local_group) | 1911 | if (local_group) |
1779 | load = target_load(i); | 1912 | load = target_load(i, load_idx); |
1780 | else | 1913 | else |
1781 | load = source_load(i); | 1914 | load = source_load(i, load_idx); |
1782 | 1915 | ||
1783 | avg_load += load; | 1916 | avg_load += load; |
1784 | } | 1917 | } |
@@ -1792,12 +1925,10 @@ find_busiest_group(struct sched_domain *sd, int this_cpu, | |||
1792 | if (local_group) { | 1925 | if (local_group) { |
1793 | this_load = avg_load; | 1926 | this_load = avg_load; |
1794 | this = group; | 1927 | this = group; |
1795 | goto nextgroup; | ||
1796 | } else if (avg_load > max_load) { | 1928 | } else if (avg_load > max_load) { |
1797 | max_load = avg_load; | 1929 | max_load = avg_load; |
1798 | busiest = group; | 1930 | busiest = group; |
1799 | } | 1931 | } |
1800 | nextgroup: | ||
1801 | group = group->next; | 1932 | group = group->next; |
1802 | } while (group != sd->groups); | 1933 | } while (group != sd->groups); |
1803 | 1934 | ||
@@ -1870,15 +2001,9 @@ nextgroup: | |||
1870 | 2001 | ||
1871 | /* Get rid of the scaling factor, rounding down as we divide */ | 2002 | /* Get rid of the scaling factor, rounding down as we divide */ |
1872 | *imbalance = *imbalance / SCHED_LOAD_SCALE; | 2003 | *imbalance = *imbalance / SCHED_LOAD_SCALE; |
1873 | |||
1874 | return busiest; | 2004 | return busiest; |
1875 | 2005 | ||
1876 | out_balanced: | 2006 | out_balanced: |
1877 | if (busiest && (idle == NEWLY_IDLE || | ||
1878 | (idle == SCHED_IDLE && max_load > SCHED_LOAD_SCALE)) ) { | ||
1879 | *imbalance = 1; | ||
1880 | return busiest; | ||
1881 | } | ||
1882 | 2007 | ||
1883 | *imbalance = 0; | 2008 | *imbalance = 0; |
1884 | return NULL; | 2009 | return NULL; |
@@ -1894,7 +2019,7 @@ static runqueue_t *find_busiest_queue(struct sched_group *group) | |||
1894 | int i; | 2019 | int i; |
1895 | 2020 | ||
1896 | for_each_cpu_mask(i, group->cpumask) { | 2021 | for_each_cpu_mask(i, group->cpumask) { |
1897 | load = source_load(i); | 2022 | load = source_load(i, 0); |
1898 | 2023 | ||
1899 | if (load > max_load) { | 2024 | if (load > max_load) { |
1900 | max_load = load; | 2025 | max_load = load; |
@@ -1906,6 +2031,12 @@ static runqueue_t *find_busiest_queue(struct sched_group *group) | |||
1906 | } | 2031 | } |
1907 | 2032 | ||
1908 | /* | 2033 | /* |
2034 | * Max backoff if we encounter pinned tasks. Pretty arbitrary value, but | ||
2035 | * so long as it is large enough. | ||
2036 | */ | ||
2037 | #define MAX_PINNED_INTERVAL 512 | ||
2038 | |||
2039 | /* | ||
1909 | * Check this_cpu to ensure it is balanced within domain. Attempt to move | 2040 | * Check this_cpu to ensure it is balanced within domain. Attempt to move |
1910 | * tasks if there is an imbalance. | 2041 | * tasks if there is an imbalance. |
1911 | * | 2042 | * |
@@ -1917,7 +2048,8 @@ static int load_balance(int this_cpu, runqueue_t *this_rq, | |||
1917 | struct sched_group *group; | 2048 | struct sched_group *group; |
1918 | runqueue_t *busiest; | 2049 | runqueue_t *busiest; |
1919 | unsigned long imbalance; | 2050 | unsigned long imbalance; |
1920 | int nr_moved; | 2051 | int nr_moved, all_pinned = 0; |
2052 | int active_balance = 0; | ||
1921 | 2053 | ||
1922 | spin_lock(&this_rq->lock); | 2054 | spin_lock(&this_rq->lock); |
1923 | schedstat_inc(sd, lb_cnt[idle]); | 2055 | schedstat_inc(sd, lb_cnt[idle]); |
@@ -1934,15 +2066,7 @@ static int load_balance(int this_cpu, runqueue_t *this_rq, | |||
1934 | goto out_balanced; | 2066 | goto out_balanced; |
1935 | } | 2067 | } |
1936 | 2068 | ||
1937 | /* | 2069 | BUG_ON(busiest == this_rq); |
1938 | * This should be "impossible", but since load | ||
1939 | * balancing is inherently racy and statistical, | ||
1940 | * it could happen in theory. | ||
1941 | */ | ||
1942 | if (unlikely(busiest == this_rq)) { | ||
1943 | WARN_ON(1); | ||
1944 | goto out_balanced; | ||
1945 | } | ||
1946 | 2070 | ||
1947 | schedstat_add(sd, lb_imbalance[idle], imbalance); | 2071 | schedstat_add(sd, lb_imbalance[idle], imbalance); |
1948 | 2072 | ||
@@ -1956,9 +2080,15 @@ static int load_balance(int this_cpu, runqueue_t *this_rq, | |||
1956 | */ | 2080 | */ |
1957 | double_lock_balance(this_rq, busiest); | 2081 | double_lock_balance(this_rq, busiest); |
1958 | nr_moved = move_tasks(this_rq, this_cpu, busiest, | 2082 | nr_moved = move_tasks(this_rq, this_cpu, busiest, |
1959 | imbalance, sd, idle); | 2083 | imbalance, sd, idle, |
2084 | &all_pinned); | ||
1960 | spin_unlock(&busiest->lock); | 2085 | spin_unlock(&busiest->lock); |
2086 | |||
2087 | /* All tasks on this runqueue were pinned by CPU affinity */ | ||
2088 | if (unlikely(all_pinned)) | ||
2089 | goto out_balanced; | ||
1961 | } | 2090 | } |
2091 | |||
1962 | spin_unlock(&this_rq->lock); | 2092 | spin_unlock(&this_rq->lock); |
1963 | 2093 | ||
1964 | if (!nr_moved) { | 2094 | if (!nr_moved) { |
@@ -1966,36 +2096,38 @@ static int load_balance(int this_cpu, runqueue_t *this_rq, | |||
1966 | sd->nr_balance_failed++; | 2096 | sd->nr_balance_failed++; |
1967 | 2097 | ||
1968 | if (unlikely(sd->nr_balance_failed > sd->cache_nice_tries+2)) { | 2098 | if (unlikely(sd->nr_balance_failed > sd->cache_nice_tries+2)) { |
1969 | int wake = 0; | ||
1970 | 2099 | ||
1971 | spin_lock(&busiest->lock); | 2100 | spin_lock(&busiest->lock); |
1972 | if (!busiest->active_balance) { | 2101 | if (!busiest->active_balance) { |
1973 | busiest->active_balance = 1; | 2102 | busiest->active_balance = 1; |
1974 | busiest->push_cpu = this_cpu; | 2103 | busiest->push_cpu = this_cpu; |
1975 | wake = 1; | 2104 | active_balance = 1; |
1976 | } | 2105 | } |
1977 | spin_unlock(&busiest->lock); | 2106 | spin_unlock(&busiest->lock); |
1978 | if (wake) | 2107 | if (active_balance) |
1979 | wake_up_process(busiest->migration_thread); | 2108 | wake_up_process(busiest->migration_thread); |
1980 | 2109 | ||
1981 | /* | 2110 | /* |
1982 | * We've kicked active balancing, reset the failure | 2111 | * We've kicked active balancing, reset the failure |
1983 | * counter. | 2112 | * counter. |
1984 | */ | 2113 | */ |
1985 | sd->nr_balance_failed = sd->cache_nice_tries; | 2114 | sd->nr_balance_failed = sd->cache_nice_tries+1; |
1986 | } | 2115 | } |
1987 | 2116 | } else | |
1988 | /* | ||
1989 | * We were unbalanced, but unsuccessful in move_tasks(), | ||
1990 | * so bump the balance_interval to lessen the lock contention. | ||
1991 | */ | ||
1992 | if (sd->balance_interval < sd->max_interval) | ||
1993 | sd->balance_interval++; | ||
1994 | } else { | ||
1995 | sd->nr_balance_failed = 0; | 2117 | sd->nr_balance_failed = 0; |
1996 | 2118 | ||
2119 | if (likely(!active_balance)) { | ||
1997 | /* We were unbalanced, so reset the balancing interval */ | 2120 | /* We were unbalanced, so reset the balancing interval */ |
1998 | sd->balance_interval = sd->min_interval; | 2121 | sd->balance_interval = sd->min_interval; |
2122 | } else { | ||
2123 | /* | ||
2124 | * If we've begun active balancing, start to back off. This | ||
2125 | * case may not be covered by the all_pinned logic if there | ||
2126 | * is only 1 task on the busy runqueue (because we don't call | ||
2127 | * move_tasks). | ||
2128 | */ | ||
2129 | if (sd->balance_interval < sd->max_interval) | ||
2130 | sd->balance_interval *= 2; | ||
1999 | } | 2131 | } |
2000 | 2132 | ||
2001 | return nr_moved; | 2133 | return nr_moved; |
@@ -2005,8 +2137,10 @@ out_balanced: | |||
2005 | 2137 | ||
2006 | schedstat_inc(sd, lb_balanced[idle]); | 2138 | schedstat_inc(sd, lb_balanced[idle]); |
2007 | 2139 | ||
2140 | sd->nr_balance_failed = 0; | ||
2008 | /* tune up the balancing interval */ | 2141 | /* tune up the balancing interval */ |
2009 | if (sd->balance_interval < sd->max_interval) | 2142 | if ((all_pinned && sd->balance_interval < MAX_PINNED_INTERVAL) || |
2143 | (sd->balance_interval < sd->max_interval)) | ||
2010 | sd->balance_interval *= 2; | 2144 | sd->balance_interval *= 2; |
2011 | 2145 | ||
2012 | return 0; | 2146 | return 0; |
@@ -2030,31 +2164,36 @@ static int load_balance_newidle(int this_cpu, runqueue_t *this_rq, | |||
2030 | schedstat_inc(sd, lb_cnt[NEWLY_IDLE]); | 2164 | schedstat_inc(sd, lb_cnt[NEWLY_IDLE]); |
2031 | group = find_busiest_group(sd, this_cpu, &imbalance, NEWLY_IDLE); | 2165 | group = find_busiest_group(sd, this_cpu, &imbalance, NEWLY_IDLE); |
2032 | if (!group) { | 2166 | if (!group) { |
2033 | schedstat_inc(sd, lb_balanced[NEWLY_IDLE]); | ||
2034 | schedstat_inc(sd, lb_nobusyg[NEWLY_IDLE]); | 2167 | schedstat_inc(sd, lb_nobusyg[NEWLY_IDLE]); |
2035 | goto out; | 2168 | goto out_balanced; |
2036 | } | 2169 | } |
2037 | 2170 | ||
2038 | busiest = find_busiest_queue(group); | 2171 | busiest = find_busiest_queue(group); |
2039 | if (!busiest || busiest == this_rq) { | 2172 | if (!busiest) { |
2040 | schedstat_inc(sd, lb_balanced[NEWLY_IDLE]); | ||
2041 | schedstat_inc(sd, lb_nobusyq[NEWLY_IDLE]); | 2173 | schedstat_inc(sd, lb_nobusyq[NEWLY_IDLE]); |
2042 | goto out; | 2174 | goto out_balanced; |
2043 | } | 2175 | } |
2044 | 2176 | ||
2177 | BUG_ON(busiest == this_rq); | ||
2178 | |||
2045 | /* Attempt to move tasks */ | 2179 | /* Attempt to move tasks */ |
2046 | double_lock_balance(this_rq, busiest); | 2180 | double_lock_balance(this_rq, busiest); |
2047 | 2181 | ||
2048 | schedstat_add(sd, lb_imbalance[NEWLY_IDLE], imbalance); | 2182 | schedstat_add(sd, lb_imbalance[NEWLY_IDLE], imbalance); |
2049 | nr_moved = move_tasks(this_rq, this_cpu, busiest, | 2183 | nr_moved = move_tasks(this_rq, this_cpu, busiest, |
2050 | imbalance, sd, NEWLY_IDLE); | 2184 | imbalance, sd, NEWLY_IDLE, NULL); |
2051 | if (!nr_moved) | 2185 | if (!nr_moved) |
2052 | schedstat_inc(sd, lb_failed[NEWLY_IDLE]); | 2186 | schedstat_inc(sd, lb_failed[NEWLY_IDLE]); |
2187 | else | ||
2188 | sd->nr_balance_failed = 0; | ||
2053 | 2189 | ||
2054 | spin_unlock(&busiest->lock); | 2190 | spin_unlock(&busiest->lock); |
2055 | |||
2056 | out: | ||
2057 | return nr_moved; | 2191 | return nr_moved; |
2192 | |||
2193 | out_balanced: | ||
2194 | schedstat_inc(sd, lb_balanced[NEWLY_IDLE]); | ||
2195 | sd->nr_balance_failed = 0; | ||
2196 | return 0; | ||
2058 | } | 2197 | } |
2059 | 2198 | ||
2060 | /* | 2199 | /* |
@@ -2086,56 +2225,42 @@ static inline void idle_balance(int this_cpu, runqueue_t *this_rq) | |||
2086 | static void active_load_balance(runqueue_t *busiest_rq, int busiest_cpu) | 2225 | static void active_load_balance(runqueue_t *busiest_rq, int busiest_cpu) |
2087 | { | 2226 | { |
2088 | struct sched_domain *sd; | 2227 | struct sched_domain *sd; |
2089 | struct sched_group *cpu_group; | ||
2090 | runqueue_t *target_rq; | 2228 | runqueue_t *target_rq; |
2091 | cpumask_t visited_cpus; | 2229 | int target_cpu = busiest_rq->push_cpu; |
2092 | int cpu; | 2230 | |
2231 | if (busiest_rq->nr_running <= 1) | ||
2232 | /* no task to move */ | ||
2233 | return; | ||
2234 | |||
2235 | target_rq = cpu_rq(target_cpu); | ||
2093 | 2236 | ||
2094 | /* | 2237 | /* |
2095 | * Search for suitable CPUs to push tasks to in successively higher | 2238 | * This condition is "impossible", if it occurs |
2096 | * domains with SD_LOAD_BALANCE set. | 2239 | * we need to fix it. Originally reported by |
2240 | * Bjorn Helgaas on a 128-cpu setup. | ||
2097 | */ | 2241 | */ |
2098 | visited_cpus = CPU_MASK_NONE; | 2242 | BUG_ON(busiest_rq == target_rq); |
2099 | for_each_domain(busiest_cpu, sd) { | ||
2100 | if (!(sd->flags & SD_LOAD_BALANCE)) | ||
2101 | /* no more domains to search */ | ||
2102 | break; | ||
2103 | 2243 | ||
2104 | schedstat_inc(sd, alb_cnt); | 2244 | /* move a task from busiest_rq to target_rq */ |
2245 | double_lock_balance(busiest_rq, target_rq); | ||
2105 | 2246 | ||
2106 | cpu_group = sd->groups; | 2247 | /* Search for an sd spanning us and the target CPU. */ |
2107 | do { | 2248 | for_each_domain(target_cpu, sd) |
2108 | for_each_cpu_mask(cpu, cpu_group->cpumask) { | 2249 | if ((sd->flags & SD_LOAD_BALANCE) && |
2109 | if (busiest_rq->nr_running <= 1) | 2250 | cpu_isset(busiest_cpu, sd->span)) |
2110 | /* no more tasks left to move */ | 2251 | break; |
2111 | return; | 2252 | |
2112 | if (cpu_isset(cpu, visited_cpus)) | 2253 | if (unlikely(sd == NULL)) |
2113 | continue; | 2254 | goto out; |
2114 | cpu_set(cpu, visited_cpus); | 2255 | |
2115 | if (!cpu_and_siblings_are_idle(cpu) || cpu == busiest_cpu) | 2256 | schedstat_inc(sd, alb_cnt); |
2116 | continue; | 2257 | |
2117 | 2258 | if (move_tasks(target_rq, target_cpu, busiest_rq, 1, sd, SCHED_IDLE, NULL)) | |
2118 | target_rq = cpu_rq(cpu); | 2259 | schedstat_inc(sd, alb_pushed); |
2119 | /* | 2260 | else |
2120 | * This condition is "impossible", if it occurs | 2261 | schedstat_inc(sd, alb_failed); |
2121 | * we need to fix it. Originally reported by | 2262 | out: |
2122 | * Bjorn Helgaas on a 128-cpu setup. | 2263 | spin_unlock(&target_rq->lock); |
2123 | */ | ||
2124 | BUG_ON(busiest_rq == target_rq); | ||
2125 | |||
2126 | /* move a task from busiest_rq to target_rq */ | ||
2127 | double_lock_balance(busiest_rq, target_rq); | ||
2128 | if (move_tasks(target_rq, cpu, busiest_rq, | ||
2129 | 1, sd, SCHED_IDLE)) { | ||
2130 | schedstat_inc(sd, alb_pushed); | ||
2131 | } else { | ||
2132 | schedstat_inc(sd, alb_failed); | ||
2133 | } | ||
2134 | spin_unlock(&target_rq->lock); | ||
2135 | } | ||
2136 | cpu_group = cpu_group->next; | ||
2137 | } while (cpu_group != sd->groups); | ||
2138 | } | ||
2139 | } | 2264 | } |
2140 | 2265 | ||
2141 | /* | 2266 | /* |
@@ -2156,18 +2281,23 @@ static void rebalance_tick(int this_cpu, runqueue_t *this_rq, | |||
2156 | unsigned long old_load, this_load; | 2281 | unsigned long old_load, this_load; |
2157 | unsigned long j = jiffies + CPU_OFFSET(this_cpu); | 2282 | unsigned long j = jiffies + CPU_OFFSET(this_cpu); |
2158 | struct sched_domain *sd; | 2283 | struct sched_domain *sd; |
2284 | int i; | ||
2159 | 2285 | ||
2160 | /* Update our load */ | ||
2161 | old_load = this_rq->cpu_load; | ||
2162 | this_load = this_rq->nr_running * SCHED_LOAD_SCALE; | 2286 | this_load = this_rq->nr_running * SCHED_LOAD_SCALE; |
2163 | /* | 2287 | /* Update our load */ |
2164 | * Round up the averaging division if load is increasing. This | 2288 | for (i = 0; i < 3; i++) { |
2165 | * prevents us from getting stuck on 9 if the load is 10, for | 2289 | unsigned long new_load = this_load; |
2166 | * example. | 2290 | int scale = 1 << i; |
2167 | */ | 2291 | old_load = this_rq->cpu_load[i]; |
2168 | if (this_load > old_load) | 2292 | /* |
2169 | old_load++; | 2293 | * Round up the averaging division if load is increasing. This |
2170 | this_rq->cpu_load = (old_load + this_load) / 2; | 2294 | * prevents us from getting stuck on 9 if the load is 10, for |
2295 | * example. | ||
2296 | */ | ||
2297 | if (new_load > old_load) | ||
2298 | new_load += scale-1; | ||
2299 | this_rq->cpu_load[i] = (old_load*(scale-1) + new_load) / scale; | ||
2300 | } | ||
2171 | 2301 | ||
2172 | for_each_domain(this_cpu, sd) { | 2302 | for_each_domain(this_cpu, sd) { |
2173 | unsigned long interval; | 2303 | unsigned long interval; |
@@ -2447,11 +2577,15 @@ out: | |||
2447 | #ifdef CONFIG_SCHED_SMT | 2577 | #ifdef CONFIG_SCHED_SMT |
2448 | static inline void wake_sleeping_dependent(int this_cpu, runqueue_t *this_rq) | 2578 | static inline void wake_sleeping_dependent(int this_cpu, runqueue_t *this_rq) |
2449 | { | 2579 | { |
2450 | struct sched_domain *sd = this_rq->sd; | 2580 | struct sched_domain *tmp, *sd = NULL; |
2451 | cpumask_t sibling_map; | 2581 | cpumask_t sibling_map; |
2452 | int i; | 2582 | int i; |
2453 | 2583 | ||
2454 | if (!(sd->flags & SD_SHARE_CPUPOWER)) | 2584 | for_each_domain(this_cpu, tmp) |
2585 | if (tmp->flags & SD_SHARE_CPUPOWER) | ||
2586 | sd = tmp; | ||
2587 | |||
2588 | if (!sd) | ||
2455 | return; | 2589 | return; |
2456 | 2590 | ||
2457 | /* | 2591 | /* |
@@ -2492,13 +2626,17 @@ static inline void wake_sleeping_dependent(int this_cpu, runqueue_t *this_rq) | |||
2492 | 2626 | ||
2493 | static inline int dependent_sleeper(int this_cpu, runqueue_t *this_rq) | 2627 | static inline int dependent_sleeper(int this_cpu, runqueue_t *this_rq) |
2494 | { | 2628 | { |
2495 | struct sched_domain *sd = this_rq->sd; | 2629 | struct sched_domain *tmp, *sd = NULL; |
2496 | cpumask_t sibling_map; | 2630 | cpumask_t sibling_map; |
2497 | prio_array_t *array; | 2631 | prio_array_t *array; |
2498 | int ret = 0, i; | 2632 | int ret = 0, i; |
2499 | task_t *p; | 2633 | task_t *p; |
2500 | 2634 | ||
2501 | if (!(sd->flags & SD_SHARE_CPUPOWER)) | 2635 | for_each_domain(this_cpu, tmp) |
2636 | if (tmp->flags & SD_SHARE_CPUPOWER) | ||
2637 | sd = tmp; | ||
2638 | |||
2639 | if (!sd) | ||
2502 | return 0; | 2640 | return 0; |
2503 | 2641 | ||
2504 | /* | 2642 | /* |
@@ -2613,7 +2751,7 @@ asmlinkage void __sched schedule(void) | |||
2613 | struct list_head *queue; | 2751 | struct list_head *queue; |
2614 | unsigned long long now; | 2752 | unsigned long long now; |
2615 | unsigned long run_time; | 2753 | unsigned long run_time; |
2616 | int cpu, idx; | 2754 | int cpu, idx, new_prio; |
2617 | 2755 | ||
2618 | /* | 2756 | /* |
2619 | * Test if we are atomic. Since do_exit() needs to call into | 2757 | * Test if we are atomic. Since do_exit() needs to call into |
@@ -2735,9 +2873,14 @@ go_idle: | |||
2735 | delta = delta * (ON_RUNQUEUE_WEIGHT * 128 / 100) / 128; | 2873 | delta = delta * (ON_RUNQUEUE_WEIGHT * 128 / 100) / 128; |
2736 | 2874 | ||
2737 | array = next->array; | 2875 | array = next->array; |
2738 | dequeue_task(next, array); | 2876 | new_prio = recalc_task_prio(next, next->timestamp + delta); |
2739 | recalc_task_prio(next, next->timestamp + delta); | 2877 | |
2740 | enqueue_task(next, array); | 2878 | if (unlikely(next->prio != new_prio)) { |
2879 | dequeue_task(next, array); | ||
2880 | next->prio = new_prio; | ||
2881 | enqueue_task(next, array); | ||
2882 | } else | ||
2883 | requeue_task(next, array); | ||
2741 | } | 2884 | } |
2742 | next->activated = 0; | 2885 | next->activated = 0; |
2743 | switch_tasks: | 2886 | switch_tasks: |
@@ -2761,11 +2904,15 @@ switch_tasks: | |||
2761 | rq->curr = next; | 2904 | rq->curr = next; |
2762 | ++*switch_count; | 2905 | ++*switch_count; |
2763 | 2906 | ||
2764 | prepare_arch_switch(rq, next); | 2907 | prepare_task_switch(rq, next); |
2765 | prev = context_switch(rq, prev, next); | 2908 | prev = context_switch(rq, prev, next); |
2766 | barrier(); | 2909 | barrier(); |
2767 | 2910 | /* | |
2768 | finish_task_switch(prev); | 2911 | * this_rq must be evaluated again because prev may have moved |
2912 | * CPUs since it called schedule(), thus the 'rq' on its stack | ||
2913 | * frame will be invalid. | ||
2914 | */ | ||
2915 | finish_task_switch(this_rq(), prev); | ||
2769 | } else | 2916 | } else |
2770 | spin_unlock_irq(&rq->lock); | 2917 | spin_unlock_irq(&rq->lock); |
2771 | 2918 | ||
@@ -3384,13 +3531,24 @@ recheck: | |||
3384 | if ((policy == SCHED_NORMAL) != (param->sched_priority == 0)) | 3531 | if ((policy == SCHED_NORMAL) != (param->sched_priority == 0)) |
3385 | return -EINVAL; | 3532 | return -EINVAL; |
3386 | 3533 | ||
3387 | if ((policy == SCHED_FIFO || policy == SCHED_RR) && | 3534 | /* |
3388 | param->sched_priority > p->signal->rlim[RLIMIT_RTPRIO].rlim_cur && | 3535 | * Allow unprivileged RT tasks to decrease priority: |
3389 | !capable(CAP_SYS_NICE)) | 3536 | */ |
3390 | return -EPERM; | 3537 | if (!capable(CAP_SYS_NICE)) { |
3391 | if ((current->euid != p->euid) && (current->euid != p->uid) && | 3538 | /* can't change policy */ |
3392 | !capable(CAP_SYS_NICE)) | 3539 | if (policy != p->policy) |
3393 | return -EPERM; | 3540 | return -EPERM; |
3541 | /* can't increase priority */ | ||
3542 | if (policy != SCHED_NORMAL && | ||
3543 | param->sched_priority > p->rt_priority && | ||
3544 | param->sched_priority > | ||
3545 | p->signal->rlim[RLIMIT_RTPRIO].rlim_cur) | ||
3546 | return -EPERM; | ||
3547 | /* can't change other user's priorities */ | ||
3548 | if ((current->euid != p->euid) && | ||
3549 | (current->euid != p->uid)) | ||
3550 | return -EPERM; | ||
3551 | } | ||
3394 | 3552 | ||
3395 | retval = security_task_setscheduler(p, policy, param); | 3553 | retval = security_task_setscheduler(p, policy, param); |
3396 | if (retval) | 3554 | if (retval) |
@@ -4030,6 +4188,9 @@ void __devinit init_idle(task_t *idle, int cpu) | |||
4030 | 4188 | ||
4031 | spin_lock_irqsave(&rq->lock, flags); | 4189 | spin_lock_irqsave(&rq->lock, flags); |
4032 | rq->curr = rq->idle = idle; | 4190 | rq->curr = rq->idle = idle; |
4191 | #if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW) | ||
4192 | idle->oncpu = 1; | ||
4193 | #endif | ||
4033 | set_tsk_need_resched(idle); | 4194 | set_tsk_need_resched(idle); |
4034 | spin_unlock_irqrestore(&rq->lock, flags); | 4195 | spin_unlock_irqrestore(&rq->lock, flags); |
4035 | 4196 | ||
@@ -4199,17 +4360,9 @@ static int migration_thread(void * data) | |||
4199 | req = list_entry(head->next, migration_req_t, list); | 4360 | req = list_entry(head->next, migration_req_t, list); |
4200 | list_del_init(head->next); | 4361 | list_del_init(head->next); |
4201 | 4362 | ||
4202 | if (req->type == REQ_MOVE_TASK) { | 4363 | spin_unlock(&rq->lock); |
4203 | spin_unlock(&rq->lock); | 4364 | __migrate_task(req->task, cpu, req->dest_cpu); |
4204 | __migrate_task(req->task, cpu, req->dest_cpu); | 4365 | local_irq_enable(); |
4205 | local_irq_enable(); | ||
4206 | } else if (req->type == REQ_SET_DOMAIN) { | ||
4207 | rq->sd = req->sd; | ||
4208 | spin_unlock_irq(&rq->lock); | ||
4209 | } else { | ||
4210 | spin_unlock_irq(&rq->lock); | ||
4211 | WARN_ON(1); | ||
4212 | } | ||
4213 | 4366 | ||
4214 | complete(&req->done); | 4367 | complete(&req->done); |
4215 | } | 4368 | } |
@@ -4440,7 +4593,6 @@ static int migration_call(struct notifier_block *nfb, unsigned long action, | |||
4440 | migration_req_t *req; | 4593 | migration_req_t *req; |
4441 | req = list_entry(rq->migration_queue.next, | 4594 | req = list_entry(rq->migration_queue.next, |
4442 | migration_req_t, list); | 4595 | migration_req_t, list); |
4443 | BUG_ON(req->type != REQ_MOVE_TASK); | ||
4444 | list_del_init(&req->list); | 4596 | list_del_init(&req->list); |
4445 | complete(&req->done); | 4597 | complete(&req->done); |
4446 | } | 4598 | } |
@@ -4471,12 +4623,17 @@ int __init migration_init(void) | |||
4471 | #endif | 4623 | #endif |
4472 | 4624 | ||
4473 | #ifdef CONFIG_SMP | 4625 | #ifdef CONFIG_SMP |
4474 | #define SCHED_DOMAIN_DEBUG | 4626 | #undef SCHED_DOMAIN_DEBUG |
4475 | #ifdef SCHED_DOMAIN_DEBUG | 4627 | #ifdef SCHED_DOMAIN_DEBUG |
4476 | static void sched_domain_debug(struct sched_domain *sd, int cpu) | 4628 | static void sched_domain_debug(struct sched_domain *sd, int cpu) |
4477 | { | 4629 | { |
4478 | int level = 0; | 4630 | int level = 0; |
4479 | 4631 | ||
4632 | if (!sd) { | ||
4633 | printk(KERN_DEBUG "CPU%d attaching NULL sched-domain.\n", cpu); | ||
4634 | return; | ||
4635 | } | ||
4636 | |||
4480 | printk(KERN_DEBUG "CPU%d attaching sched-domain:\n", cpu); | 4637 | printk(KERN_DEBUG "CPU%d attaching sched-domain:\n", cpu); |
4481 | 4638 | ||
4482 | do { | 4639 | do { |
@@ -4559,37 +4716,81 @@ static void sched_domain_debug(struct sched_domain *sd, int cpu) | |||
4559 | #define sched_domain_debug(sd, cpu) {} | 4716 | #define sched_domain_debug(sd, cpu) {} |
4560 | #endif | 4717 | #endif |
4561 | 4718 | ||
4719 | static int sd_degenerate(struct sched_domain *sd) | ||
4720 | { | ||
4721 | if (cpus_weight(sd->span) == 1) | ||
4722 | return 1; | ||
4723 | |||
4724 | /* Following flags need at least 2 groups */ | ||
4725 | if (sd->flags & (SD_LOAD_BALANCE | | ||
4726 | SD_BALANCE_NEWIDLE | | ||
4727 | SD_BALANCE_FORK | | ||
4728 | SD_BALANCE_EXEC)) { | ||
4729 | if (sd->groups != sd->groups->next) | ||
4730 | return 0; | ||
4731 | } | ||
4732 | |||
4733 | /* Following flags don't use groups */ | ||
4734 | if (sd->flags & (SD_WAKE_IDLE | | ||
4735 | SD_WAKE_AFFINE | | ||
4736 | SD_WAKE_BALANCE)) | ||
4737 | return 0; | ||
4738 | |||
4739 | return 1; | ||
4740 | } | ||
4741 | |||
4742 | static int sd_parent_degenerate(struct sched_domain *sd, | ||
4743 | struct sched_domain *parent) | ||
4744 | { | ||
4745 | unsigned long cflags = sd->flags, pflags = parent->flags; | ||
4746 | |||
4747 | if (sd_degenerate(parent)) | ||
4748 | return 1; | ||
4749 | |||
4750 | if (!cpus_equal(sd->span, parent->span)) | ||
4751 | return 0; | ||
4752 | |||
4753 | /* Does parent contain flags not in child? */ | ||
4754 | /* WAKE_BALANCE is a subset of WAKE_AFFINE */ | ||
4755 | if (cflags & SD_WAKE_AFFINE) | ||
4756 | pflags &= ~SD_WAKE_BALANCE; | ||
4757 | /* Flags needing groups don't count if only 1 group in parent */ | ||
4758 | if (parent->groups == parent->groups->next) { | ||
4759 | pflags &= ~(SD_LOAD_BALANCE | | ||
4760 | SD_BALANCE_NEWIDLE | | ||
4761 | SD_BALANCE_FORK | | ||
4762 | SD_BALANCE_EXEC); | ||
4763 | } | ||
4764 | if (~cflags & pflags) | ||
4765 | return 0; | ||
4766 | |||
4767 | return 1; | ||
4768 | } | ||
4769 | |||
4562 | /* | 4770 | /* |
4563 | * Attach the domain 'sd' to 'cpu' as its base domain. Callers must | 4771 | * Attach the domain 'sd' to 'cpu' as its base domain. Callers must |
4564 | * hold the hotplug lock. | 4772 | * hold the hotplug lock. |
4565 | */ | 4773 | */ |
4566 | void __devinit cpu_attach_domain(struct sched_domain *sd, int cpu) | 4774 | void cpu_attach_domain(struct sched_domain *sd, int cpu) |
4567 | { | 4775 | { |
4568 | migration_req_t req; | ||
4569 | unsigned long flags; | ||
4570 | runqueue_t *rq = cpu_rq(cpu); | 4776 | runqueue_t *rq = cpu_rq(cpu); |
4571 | int local = 1; | 4777 | struct sched_domain *tmp; |
4572 | |||
4573 | sched_domain_debug(sd, cpu); | ||
4574 | 4778 | ||
4575 | spin_lock_irqsave(&rq->lock, flags); | 4779 | /* Remove the sched domains which do not contribute to scheduling. */ |
4576 | 4780 | for (tmp = sd; tmp; tmp = tmp->parent) { | |
4577 | if (cpu == smp_processor_id() || !cpu_online(cpu)) { | 4781 | struct sched_domain *parent = tmp->parent; |
4578 | rq->sd = sd; | 4782 | if (!parent) |
4579 | } else { | 4783 | break; |
4580 | init_completion(&req.done); | 4784 | if (sd_parent_degenerate(tmp, parent)) |
4581 | req.type = REQ_SET_DOMAIN; | 4785 | tmp->parent = parent->parent; |
4582 | req.sd = sd; | ||
4583 | list_add(&req.list, &rq->migration_queue); | ||
4584 | local = 0; | ||
4585 | } | 4786 | } |
4586 | 4787 | ||
4587 | spin_unlock_irqrestore(&rq->lock, flags); | 4788 | if (sd && sd_degenerate(sd)) |
4789 | sd = sd->parent; | ||
4588 | 4790 | ||
4589 | if (!local) { | 4791 | sched_domain_debug(sd, cpu); |
4590 | wake_up_process(rq->migration_thread); | 4792 | |
4591 | wait_for_completion(&req.done); | 4793 | rcu_assign_pointer(rq->sd, sd); |
4592 | } | ||
4593 | } | 4794 | } |
4594 | 4795 | ||
4595 | /* cpus with isolated domains */ | 4796 | /* cpus with isolated domains */ |
@@ -4621,7 +4822,7 @@ __setup ("isolcpus=", isolated_cpu_setup); | |||
4621 | * covered by the given span, and will set each group's ->cpumask correctly, | 4822 | * covered by the given span, and will set each group's ->cpumask correctly, |
4622 | * and ->cpu_power to 0. | 4823 | * and ->cpu_power to 0. |
4623 | */ | 4824 | */ |
4624 | void __devinit init_sched_build_groups(struct sched_group groups[], | 4825 | void init_sched_build_groups(struct sched_group groups[], |
4625 | cpumask_t span, int (*group_fn)(int cpu)) | 4826 | cpumask_t span, int (*group_fn)(int cpu)) |
4626 | { | 4827 | { |
4627 | struct sched_group *first = NULL, *last = NULL; | 4828 | struct sched_group *first = NULL, *last = NULL; |
@@ -4657,13 +4858,14 @@ void __devinit init_sched_build_groups(struct sched_group groups[], | |||
4657 | 4858 | ||
4658 | 4859 | ||
4659 | #ifdef ARCH_HAS_SCHED_DOMAIN | 4860 | #ifdef ARCH_HAS_SCHED_DOMAIN |
4660 | extern void __devinit arch_init_sched_domains(void); | 4861 | extern void build_sched_domains(const cpumask_t *cpu_map); |
4661 | extern void __devinit arch_destroy_sched_domains(void); | 4862 | extern void arch_init_sched_domains(const cpumask_t *cpu_map); |
4863 | extern void arch_destroy_sched_domains(const cpumask_t *cpu_map); | ||
4662 | #else | 4864 | #else |
4663 | #ifdef CONFIG_SCHED_SMT | 4865 | #ifdef CONFIG_SCHED_SMT |
4664 | static DEFINE_PER_CPU(struct sched_domain, cpu_domains); | 4866 | static DEFINE_PER_CPU(struct sched_domain, cpu_domains); |
4665 | static struct sched_group sched_group_cpus[NR_CPUS]; | 4867 | static struct sched_group sched_group_cpus[NR_CPUS]; |
4666 | static int __devinit cpu_to_cpu_group(int cpu) | 4868 | static int cpu_to_cpu_group(int cpu) |
4667 | { | 4869 | { |
4668 | return cpu; | 4870 | return cpu; |
4669 | } | 4871 | } |
@@ -4671,7 +4873,7 @@ static int __devinit cpu_to_cpu_group(int cpu) | |||
4671 | 4873 | ||
4672 | static DEFINE_PER_CPU(struct sched_domain, phys_domains); | 4874 | static DEFINE_PER_CPU(struct sched_domain, phys_domains); |
4673 | static struct sched_group sched_group_phys[NR_CPUS]; | 4875 | static struct sched_group sched_group_phys[NR_CPUS]; |
4674 | static int __devinit cpu_to_phys_group(int cpu) | 4876 | static int cpu_to_phys_group(int cpu) |
4675 | { | 4877 | { |
4676 | #ifdef CONFIG_SCHED_SMT | 4878 | #ifdef CONFIG_SCHED_SMT |
4677 | return first_cpu(cpu_sibling_map[cpu]); | 4879 | return first_cpu(cpu_sibling_map[cpu]); |
@@ -4684,7 +4886,7 @@ static int __devinit cpu_to_phys_group(int cpu) | |||
4684 | 4886 | ||
4685 | static DEFINE_PER_CPU(struct sched_domain, node_domains); | 4887 | static DEFINE_PER_CPU(struct sched_domain, node_domains); |
4686 | static struct sched_group sched_group_nodes[MAX_NUMNODES]; | 4888 | static struct sched_group sched_group_nodes[MAX_NUMNODES]; |
4687 | static int __devinit cpu_to_node_group(int cpu) | 4889 | static int cpu_to_node_group(int cpu) |
4688 | { | 4890 | { |
4689 | return cpu_to_node(cpu); | 4891 | return cpu_to_node(cpu); |
4690 | } | 4892 | } |
@@ -4715,39 +4917,28 @@ static void check_sibling_maps(void) | |||
4715 | #endif | 4917 | #endif |
4716 | 4918 | ||
4717 | /* | 4919 | /* |
4718 | * Set up scheduler domains and groups. Callers must hold the hotplug lock. | 4920 | * Build sched domains for a given set of cpus and attach the sched domains |
4921 | * to the individual cpus | ||
4719 | */ | 4922 | */ |
4720 | static void __devinit arch_init_sched_domains(void) | 4923 | static void build_sched_domains(const cpumask_t *cpu_map) |
4721 | { | 4924 | { |
4722 | int i; | 4925 | int i; |
4723 | cpumask_t cpu_default_map; | ||
4724 | |||
4725 | #if defined(CONFIG_SCHED_SMT) && defined(CONFIG_NUMA) | ||
4726 | check_sibling_maps(); | ||
4727 | #endif | ||
4728 | /* | ||
4729 | * Setup mask for cpus without special case scheduling requirements. | ||
4730 | * For now this just excludes isolated cpus, but could be used to | ||
4731 | * exclude other special cases in the future. | ||
4732 | */ | ||
4733 | cpus_complement(cpu_default_map, cpu_isolated_map); | ||
4734 | cpus_and(cpu_default_map, cpu_default_map, cpu_online_map); | ||
4735 | 4926 | ||
4736 | /* | 4927 | /* |
4737 | * Set up domains. Isolated domains just stay on the dummy domain. | 4928 | * Set up domains for cpus specified by the cpu_map. |
4738 | */ | 4929 | */ |
4739 | for_each_cpu_mask(i, cpu_default_map) { | 4930 | for_each_cpu_mask(i, *cpu_map) { |
4740 | int group; | 4931 | int group; |
4741 | struct sched_domain *sd = NULL, *p; | 4932 | struct sched_domain *sd = NULL, *p; |
4742 | cpumask_t nodemask = node_to_cpumask(cpu_to_node(i)); | 4933 | cpumask_t nodemask = node_to_cpumask(cpu_to_node(i)); |
4743 | 4934 | ||
4744 | cpus_and(nodemask, nodemask, cpu_default_map); | 4935 | cpus_and(nodemask, nodemask, *cpu_map); |
4745 | 4936 | ||
4746 | #ifdef CONFIG_NUMA | 4937 | #ifdef CONFIG_NUMA |
4747 | sd = &per_cpu(node_domains, i); | 4938 | sd = &per_cpu(node_domains, i); |
4748 | group = cpu_to_node_group(i); | 4939 | group = cpu_to_node_group(i); |
4749 | *sd = SD_NODE_INIT; | 4940 | *sd = SD_NODE_INIT; |
4750 | sd->span = cpu_default_map; | 4941 | sd->span = *cpu_map; |
4751 | sd->groups = &sched_group_nodes[group]; | 4942 | sd->groups = &sched_group_nodes[group]; |
4752 | #endif | 4943 | #endif |
4753 | 4944 | ||
@@ -4765,7 +4956,7 @@ static void __devinit arch_init_sched_domains(void) | |||
4765 | group = cpu_to_cpu_group(i); | 4956 | group = cpu_to_cpu_group(i); |
4766 | *sd = SD_SIBLING_INIT; | 4957 | *sd = SD_SIBLING_INIT; |
4767 | sd->span = cpu_sibling_map[i]; | 4958 | sd->span = cpu_sibling_map[i]; |
4768 | cpus_and(sd->span, sd->span, cpu_default_map); | 4959 | cpus_and(sd->span, sd->span, *cpu_map); |
4769 | sd->parent = p; | 4960 | sd->parent = p; |
4770 | sd->groups = &sched_group_cpus[group]; | 4961 | sd->groups = &sched_group_cpus[group]; |
4771 | #endif | 4962 | #endif |
@@ -4775,7 +4966,7 @@ static void __devinit arch_init_sched_domains(void) | |||
4775 | /* Set up CPU (sibling) groups */ | 4966 | /* Set up CPU (sibling) groups */ |
4776 | for_each_online_cpu(i) { | 4967 | for_each_online_cpu(i) { |
4777 | cpumask_t this_sibling_map = cpu_sibling_map[i]; | 4968 | cpumask_t this_sibling_map = cpu_sibling_map[i]; |
4778 | cpus_and(this_sibling_map, this_sibling_map, cpu_default_map); | 4969 | cpus_and(this_sibling_map, this_sibling_map, *cpu_map); |
4779 | if (i != first_cpu(this_sibling_map)) | 4970 | if (i != first_cpu(this_sibling_map)) |
4780 | continue; | 4971 | continue; |
4781 | 4972 | ||
@@ -4788,7 +4979,7 @@ static void __devinit arch_init_sched_domains(void) | |||
4788 | for (i = 0; i < MAX_NUMNODES; i++) { | 4979 | for (i = 0; i < MAX_NUMNODES; i++) { |
4789 | cpumask_t nodemask = node_to_cpumask(i); | 4980 | cpumask_t nodemask = node_to_cpumask(i); |
4790 | 4981 | ||
4791 | cpus_and(nodemask, nodemask, cpu_default_map); | 4982 | cpus_and(nodemask, nodemask, *cpu_map); |
4792 | if (cpus_empty(nodemask)) | 4983 | if (cpus_empty(nodemask)) |
4793 | continue; | 4984 | continue; |
4794 | 4985 | ||
@@ -4798,12 +4989,12 @@ static void __devinit arch_init_sched_domains(void) | |||
4798 | 4989 | ||
4799 | #ifdef CONFIG_NUMA | 4990 | #ifdef CONFIG_NUMA |
4800 | /* Set up node groups */ | 4991 | /* Set up node groups */ |
4801 | init_sched_build_groups(sched_group_nodes, cpu_default_map, | 4992 | init_sched_build_groups(sched_group_nodes, *cpu_map, |
4802 | &cpu_to_node_group); | 4993 | &cpu_to_node_group); |
4803 | #endif | 4994 | #endif |
4804 | 4995 | ||
4805 | /* Calculate CPU power for physical packages and nodes */ | 4996 | /* Calculate CPU power for physical packages and nodes */ |
4806 | for_each_cpu_mask(i, cpu_default_map) { | 4997 | for_each_cpu_mask(i, *cpu_map) { |
4807 | int power; | 4998 | int power; |
4808 | struct sched_domain *sd; | 4999 | struct sched_domain *sd; |
4809 | #ifdef CONFIG_SCHED_SMT | 5000 | #ifdef CONFIG_SCHED_SMT |
@@ -4827,7 +5018,7 @@ static void __devinit arch_init_sched_domains(void) | |||
4827 | } | 5018 | } |
4828 | 5019 | ||
4829 | /* Attach the domains */ | 5020 | /* Attach the domains */ |
4830 | for_each_online_cpu(i) { | 5021 | for_each_cpu_mask(i, *cpu_map) { |
4831 | struct sched_domain *sd; | 5022 | struct sched_domain *sd; |
4832 | #ifdef CONFIG_SCHED_SMT | 5023 | #ifdef CONFIG_SCHED_SMT |
4833 | sd = &per_cpu(cpu_domains, i); | 5024 | sd = &per_cpu(cpu_domains, i); |
@@ -4837,41 +5028,85 @@ static void __devinit arch_init_sched_domains(void) | |||
4837 | cpu_attach_domain(sd, i); | 5028 | cpu_attach_domain(sd, i); |
4838 | } | 5029 | } |
4839 | } | 5030 | } |
5031 | /* | ||
5032 | * Set up scheduler domains and groups. Callers must hold the hotplug lock. | ||
5033 | */ | ||
5034 | static void arch_init_sched_domains(cpumask_t *cpu_map) | ||
5035 | { | ||
5036 | cpumask_t cpu_default_map; | ||
5037 | |||
5038 | #if defined(CONFIG_SCHED_SMT) && defined(CONFIG_NUMA) | ||
5039 | check_sibling_maps(); | ||
5040 | #endif | ||
5041 | /* | ||
5042 | * Setup mask for cpus without special case scheduling requirements. | ||
5043 | * For now this just excludes isolated cpus, but could be used to | ||
5044 | * exclude other special cases in the future. | ||
5045 | */ | ||
5046 | cpus_andnot(cpu_default_map, *cpu_map, cpu_isolated_map); | ||
5047 | |||
5048 | build_sched_domains(&cpu_default_map); | ||
5049 | } | ||
4840 | 5050 | ||
4841 | #ifdef CONFIG_HOTPLUG_CPU | 5051 | static void arch_destroy_sched_domains(const cpumask_t *cpu_map) |
4842 | static void __devinit arch_destroy_sched_domains(void) | ||
4843 | { | 5052 | { |
4844 | /* Do nothing: everything is statically allocated. */ | 5053 | /* Do nothing: everything is statically allocated. */ |
4845 | } | 5054 | } |
4846 | #endif | ||
4847 | 5055 | ||
4848 | #endif /* ARCH_HAS_SCHED_DOMAIN */ | 5056 | #endif /* ARCH_HAS_SCHED_DOMAIN */ |
4849 | 5057 | ||
4850 | /* | 5058 | /* |
4851 | * Initial dummy domain for early boot and for hotplug cpu. Being static, | 5059 | * Detach sched domains from a group of cpus specified in cpu_map |
4852 | * it is initialized to zero, so all balancing flags are cleared which is | 5060 | * These cpus will now be attached to the NULL domain |
4853 | * what we want. | ||
4854 | */ | 5061 | */ |
4855 | static struct sched_domain sched_domain_dummy; | 5062 | static inline void detach_destroy_domains(const cpumask_t *cpu_map) |
5063 | { | ||
5064 | int i; | ||
5065 | |||
5066 | for_each_cpu_mask(i, *cpu_map) | ||
5067 | cpu_attach_domain(NULL, i); | ||
5068 | synchronize_sched(); | ||
5069 | arch_destroy_sched_domains(cpu_map); | ||
5070 | } | ||
5071 | |||
5072 | /* | ||
5073 | * Partition sched domains as specified by the cpumasks below. | ||
5074 | * This attaches all cpus from the cpumasks to the NULL domain, | ||
5075 | * waits for a RCU quiescent period, recalculates sched | ||
5076 | * domain information and then attaches them back to the | ||
5077 | * correct sched domains | ||
5078 | * Call with hotplug lock held | ||
5079 | */ | ||
5080 | void partition_sched_domains(cpumask_t *partition1, cpumask_t *partition2) | ||
5081 | { | ||
5082 | cpumask_t change_map; | ||
5083 | |||
5084 | cpus_and(*partition1, *partition1, cpu_online_map); | ||
5085 | cpus_and(*partition2, *partition2, cpu_online_map); | ||
5086 | cpus_or(change_map, *partition1, *partition2); | ||
5087 | |||
5088 | /* Detach sched domains from all of the affected cpus */ | ||
5089 | detach_destroy_domains(&change_map); | ||
5090 | if (!cpus_empty(*partition1)) | ||
5091 | build_sched_domains(partition1); | ||
5092 | if (!cpus_empty(*partition2)) | ||
5093 | build_sched_domains(partition2); | ||
5094 | } | ||
4856 | 5095 | ||
4857 | #ifdef CONFIG_HOTPLUG_CPU | 5096 | #ifdef CONFIG_HOTPLUG_CPU |
4858 | /* | 5097 | /* |
4859 | * Force a reinitialization of the sched domains hierarchy. The domains | 5098 | * Force a reinitialization of the sched domains hierarchy. The domains |
4860 | * and groups cannot be updated in place without racing with the balancing | 5099 | * and groups cannot be updated in place without racing with the balancing |
4861 | * code, so we temporarily attach all running cpus to a "dummy" domain | 5100 | * code, so we temporarily attach all running cpus to the NULL domain |
4862 | * which will prevent rebalancing while the sched domains are recalculated. | 5101 | * which will prevent rebalancing while the sched domains are recalculated. |
4863 | */ | 5102 | */ |
4864 | static int update_sched_domains(struct notifier_block *nfb, | 5103 | static int update_sched_domains(struct notifier_block *nfb, |
4865 | unsigned long action, void *hcpu) | 5104 | unsigned long action, void *hcpu) |
4866 | { | 5105 | { |
4867 | int i; | ||
4868 | |||
4869 | switch (action) { | 5106 | switch (action) { |
4870 | case CPU_UP_PREPARE: | 5107 | case CPU_UP_PREPARE: |
4871 | case CPU_DOWN_PREPARE: | 5108 | case CPU_DOWN_PREPARE: |
4872 | for_each_online_cpu(i) | 5109 | detach_destroy_domains(&cpu_online_map); |
4873 | cpu_attach_domain(&sched_domain_dummy, i); | ||
4874 | arch_destroy_sched_domains(); | ||
4875 | return NOTIFY_OK; | 5110 | return NOTIFY_OK; |
4876 | 5111 | ||
4877 | case CPU_UP_CANCELED: | 5112 | case CPU_UP_CANCELED: |
@@ -4887,7 +5122,7 @@ static int update_sched_domains(struct notifier_block *nfb, | |||
4887 | } | 5122 | } |
4888 | 5123 | ||
4889 | /* The hotplug lock is already held by cpu_up/cpu_down */ | 5124 | /* The hotplug lock is already held by cpu_up/cpu_down */ |
4890 | arch_init_sched_domains(); | 5125 | arch_init_sched_domains(&cpu_online_map); |
4891 | 5126 | ||
4892 | return NOTIFY_OK; | 5127 | return NOTIFY_OK; |
4893 | } | 5128 | } |
@@ -4896,7 +5131,7 @@ static int update_sched_domains(struct notifier_block *nfb, | |||
4896 | void __init sched_init_smp(void) | 5131 | void __init sched_init_smp(void) |
4897 | { | 5132 | { |
4898 | lock_cpu_hotplug(); | 5133 | lock_cpu_hotplug(); |
4899 | arch_init_sched_domains(); | 5134 | arch_init_sched_domains(&cpu_online_map); |
4900 | unlock_cpu_hotplug(); | 5135 | unlock_cpu_hotplug(); |
4901 | /* XXX: Theoretical race here - CPU may be hotplugged now */ | 5136 | /* XXX: Theoretical race here - CPU may be hotplugged now */ |
4902 | hotcpu_notifier(update_sched_domains, 0); | 5137 | hotcpu_notifier(update_sched_domains, 0); |
@@ -4926,13 +5161,15 @@ void __init sched_init(void) | |||
4926 | 5161 | ||
4927 | rq = cpu_rq(i); | 5162 | rq = cpu_rq(i); |
4928 | spin_lock_init(&rq->lock); | 5163 | spin_lock_init(&rq->lock); |
5164 | rq->nr_running = 0; | ||
4929 | rq->active = rq->arrays; | 5165 | rq->active = rq->arrays; |
4930 | rq->expired = rq->arrays + 1; | 5166 | rq->expired = rq->arrays + 1; |
4931 | rq->best_expired_prio = MAX_PRIO; | 5167 | rq->best_expired_prio = MAX_PRIO; |
4932 | 5168 | ||
4933 | #ifdef CONFIG_SMP | 5169 | #ifdef CONFIG_SMP |
4934 | rq->sd = &sched_domain_dummy; | 5170 | rq->sd = NULL; |
4935 | rq->cpu_load = 0; | 5171 | for (j = 1; j < 3; j++) |
5172 | rq->cpu_load[j] = 0; | ||
4936 | rq->active_balance = 0; | 5173 | rq->active_balance = 0; |
4937 | rq->push_cpu = 0; | 5174 | rq->push_cpu = 0; |
4938 | rq->migration_thread = NULL; | 5175 | rq->migration_thread = NULL; |
diff --git a/kernel/sys.c b/kernel/sys.c index da24bc1292db..9a24374c23bc 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -16,6 +16,8 @@ | |||
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/highuid.h> | 17 | #include <linux/highuid.h> |
18 | #include <linux/fs.h> | 18 | #include <linux/fs.h> |
19 | #include <linux/kernel.h> | ||
20 | #include <linux/kexec.h> | ||
19 | #include <linux/workqueue.h> | 21 | #include <linux/workqueue.h> |
20 | #include <linux/device.h> | 22 | #include <linux/device.h> |
21 | #include <linux/key.h> | 23 | #include <linux/key.h> |
@@ -405,6 +407,7 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user | |||
405 | case LINUX_REBOOT_CMD_HALT: | 407 | case LINUX_REBOOT_CMD_HALT: |
406 | notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL); | 408 | notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL); |
407 | system_state = SYSTEM_HALT; | 409 | system_state = SYSTEM_HALT; |
410 | device_suspend(PMSG_SUSPEND); | ||
408 | device_shutdown(); | 411 | device_shutdown(); |
409 | printk(KERN_EMERG "System halted.\n"); | 412 | printk(KERN_EMERG "System halted.\n"); |
410 | machine_halt(); | 413 | machine_halt(); |
@@ -415,6 +418,7 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user | |||
415 | case LINUX_REBOOT_CMD_POWER_OFF: | 418 | case LINUX_REBOOT_CMD_POWER_OFF: |
416 | notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL); | 419 | notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL); |
417 | system_state = SYSTEM_POWER_OFF; | 420 | system_state = SYSTEM_POWER_OFF; |
421 | device_suspend(PMSG_SUSPEND); | ||
418 | device_shutdown(); | 422 | device_shutdown(); |
419 | printk(KERN_EMERG "Power down.\n"); | 423 | printk(KERN_EMERG "Power down.\n"); |
420 | machine_power_off(); | 424 | machine_power_off(); |
@@ -431,11 +435,30 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user | |||
431 | 435 | ||
432 | notifier_call_chain(&reboot_notifier_list, SYS_RESTART, buffer); | 436 | notifier_call_chain(&reboot_notifier_list, SYS_RESTART, buffer); |
433 | system_state = SYSTEM_RESTART; | 437 | system_state = SYSTEM_RESTART; |
438 | device_suspend(PMSG_FREEZE); | ||
434 | device_shutdown(); | 439 | device_shutdown(); |
435 | printk(KERN_EMERG "Restarting system with command '%s'.\n", buffer); | 440 | printk(KERN_EMERG "Restarting system with command '%s'.\n", buffer); |
436 | machine_restart(buffer); | 441 | machine_restart(buffer); |
437 | break; | 442 | break; |
438 | 443 | ||
444 | #ifdef CONFIG_KEXEC | ||
445 | case LINUX_REBOOT_CMD_KEXEC: | ||
446 | { | ||
447 | struct kimage *image; | ||
448 | image = xchg(&kexec_image, 0); | ||
449 | if (!image) { | ||
450 | unlock_kernel(); | ||
451 | return -EINVAL; | ||
452 | } | ||
453 | notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL); | ||
454 | system_state = SYSTEM_RESTART; | ||
455 | device_shutdown(); | ||
456 | printk(KERN_EMERG "Starting new kernel\n"); | ||
457 | machine_shutdown(); | ||
458 | machine_kexec(image); | ||
459 | break; | ||
460 | } | ||
461 | #endif | ||
439 | #ifdef CONFIG_SOFTWARE_SUSPEND | 462 | #ifdef CONFIG_SOFTWARE_SUSPEND |
440 | case LINUX_REBOOT_CMD_SW_SUSPEND: | 463 | case LINUX_REBOOT_CMD_SW_SUSPEND: |
441 | { | 464 | { |
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index 6f15bea7d1a8..29196ce9b40f 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c | |||
@@ -18,6 +18,8 @@ cond_syscall(sys_acct); | |||
18 | cond_syscall(sys_lookup_dcookie); | 18 | cond_syscall(sys_lookup_dcookie); |
19 | cond_syscall(sys_swapon); | 19 | cond_syscall(sys_swapon); |
20 | cond_syscall(sys_swapoff); | 20 | cond_syscall(sys_swapoff); |
21 | cond_syscall(sys_kexec_load); | ||
22 | cond_syscall(compat_sys_kexec_load); | ||
21 | cond_syscall(sys_init_module); | 23 | cond_syscall(sys_init_module); |
22 | cond_syscall(sys_delete_module); | 24 | cond_syscall(sys_delete_module); |
23 | cond_syscall(sys_socketpair); | 25 | cond_syscall(sys_socketpair); |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 24a4d12d5aa9..270ee7fadbd8 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -1000,8 +1000,7 @@ int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *ol | |||
1000 | int error = parse_table(name, nlen, oldval, oldlenp, | 1000 | int error = parse_table(name, nlen, oldval, oldlenp, |
1001 | newval, newlen, head->ctl_table, | 1001 | newval, newlen, head->ctl_table, |
1002 | &context); | 1002 | &context); |
1003 | if (context) | 1003 | kfree(context); |
1004 | kfree(context); | ||
1005 | if (error != -ENOTDIR) | 1004 | if (error != -ENOTDIR) |
1006 | return error; | 1005 | return error; |
1007 | tmp = tmp->next; | 1006 | tmp = tmp->next; |
diff --git a/kernel/timer.c b/kernel/timer.c index 51ff917c9590..f2a11887a726 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -1597,7 +1597,7 @@ void msleep(unsigned int msecs) | |||
1597 | EXPORT_SYMBOL(msleep); | 1597 | EXPORT_SYMBOL(msleep); |
1598 | 1598 | ||
1599 | /** | 1599 | /** |
1600 | * msleep_interruptible - sleep waiting for waitqueue interruptions | 1600 | * msleep_interruptible - sleep waiting for signals |
1601 | * @msecs: Time in milliseconds to sleep for | 1601 | * @msecs: Time in milliseconds to sleep for |
1602 | */ | 1602 | */ |
1603 | unsigned long msleep_interruptible(unsigned int msecs) | 1603 | unsigned long msleep_interruptible(unsigned int msecs) |
diff --git a/lib/Kconfig b/lib/Kconfig index 455833a9e31a..eeb429a52152 100644 --- a/lib/Kconfig +++ b/lib/Kconfig | |||
@@ -63,32 +63,16 @@ config REED_SOLOMON_ENC16 | |||
63 | config REED_SOLOMON_DEC16 | 63 | config REED_SOLOMON_DEC16 |
64 | boolean | 64 | boolean |
65 | 65 | ||
66 | # | ||
67 | # Textsearch support is select'ed if needed | ||
68 | # | ||
66 | config TEXTSEARCH | 69 | config TEXTSEARCH |
67 | boolean "Textsearch infrastructure" | 70 | boolean |
68 | default y | ||
69 | help | ||
70 | Say Y here if you want to provide a textsearch infrastructure | ||
71 | to other subsystems. | ||
72 | 71 | ||
73 | config TEXTSEARCH_KMP | 72 | config TEXTSEARCH_KMP |
74 | depends on TEXTSEARCH | 73 | tristate |
75 | tristate "Knuth-Morris-Pratt" | ||
76 | help | ||
77 | Say Y here if you want to be able to search text using the | ||
78 | Knuth-Morris-Pratt textsearch algorithm. | ||
79 | |||
80 | To compile this code as a module, choose M here: the | ||
81 | module will be called ts_kmp. | ||
82 | 74 | ||
83 | config TEXTSEARCH_FSM | 75 | config TEXTSEARCH_FSM |
84 | depends on TEXTSEARCH | 76 | tristate |
85 | tristate "Finite state machine" | ||
86 | help | ||
87 | Say Y here if you want to be able to search text using a | ||
88 | naive finite state machine approach implementing a subset | ||
89 | of regular expressions. | ||
90 | |||
91 | To compile this code as a module, choose M here: the | ||
92 | module will be called ts_fsm. | ||
93 | 77 | ||
94 | endmenu | 78 | endmenu |
diff --git a/lib/bitmap.c b/lib/bitmap.c index d1388a5ce89c..fb9371fdd44a 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c | |||
@@ -289,7 +289,6 @@ EXPORT_SYMBOL(__bitmap_weight); | |||
289 | 289 | ||
290 | #define CHUNKSZ 32 | 290 | #define CHUNKSZ 32 |
291 | #define nbits_to_hold_value(val) fls(val) | 291 | #define nbits_to_hold_value(val) fls(val) |
292 | #define roundup_power2(val,modulus) (((val) + (modulus) - 1) & ~((modulus) - 1)) | ||
293 | #define unhex(c) (isdigit(c) ? (c - '0') : (toupper(c) - 'A' + 10)) | 292 | #define unhex(c) (isdigit(c) ? (c - '0') : (toupper(c) - 'A' + 10)) |
294 | #define BASEDEC 10 /* fancier cpuset lists input in decimal */ | 293 | #define BASEDEC 10 /* fancier cpuset lists input in decimal */ |
295 | 294 | ||
@@ -316,7 +315,7 @@ int bitmap_scnprintf(char *buf, unsigned int buflen, | |||
316 | if (chunksz == 0) | 315 | if (chunksz == 0) |
317 | chunksz = CHUNKSZ; | 316 | chunksz = CHUNKSZ; |
318 | 317 | ||
319 | i = roundup_power2(nmaskbits, CHUNKSZ) - CHUNKSZ; | 318 | i = ALIGN(nmaskbits, CHUNKSZ) - CHUNKSZ; |
320 | for (; i >= 0; i -= CHUNKSZ) { | 319 | for (; i >= 0; i -= CHUNKSZ) { |
321 | chunkmask = ((1ULL << chunksz) - 1); | 320 | chunkmask = ((1ULL << chunksz) - 1); |
322 | word = i / BITS_PER_LONG; | 321 | word = i / BITS_PER_LONG; |
diff --git a/lib/sha1.c b/lib/sha1.c index 2f7f1148dfde..1cdabe3065f9 100644 --- a/lib/sha1.c +++ b/lib/sha1.c | |||
@@ -41,7 +41,7 @@ void sha_transform(__u32 *digest, const char *in, __u32 *W) | |||
41 | __u32 a, b, c, d, e, t, i; | 41 | __u32 a, b, c, d, e, t, i; |
42 | 42 | ||
43 | for (i = 0; i < 16; i++) | 43 | for (i = 0; i < 16; i++) |
44 | W[i] = be32_to_cpu(((const __u32 *)in)[i]); | 44 | W[i] = be32_to_cpu(((const __be32 *)in)[i]); |
45 | 45 | ||
46 | for (i = 0; i < 64; i++) | 46 | for (i = 0; i < 64; i++) |
47 | W[i+16] = rol32(W[i+13] ^ W[i+8] ^ W[i+2] ^ W[i], 1); | 47 | W[i+16] = rol32(W[i+13] ^ W[i+8] ^ W[i+2] ^ W[i], 1); |
diff --git a/mm/bootmem.c b/mm/bootmem.c index f82f7aebbee3..c1330cc19783 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c | |||
@@ -33,6 +33,14 @@ EXPORT_SYMBOL(max_pfn); /* This is exported so | |||
33 | * dma_get_required_mask(), which uses | 33 | * dma_get_required_mask(), which uses |
34 | * it, can be an inline function */ | 34 | * it, can be an inline function */ |
35 | 35 | ||
36 | #ifdef CONFIG_CRASH_DUMP | ||
37 | /* | ||
38 | * If we have booted due to a crash, max_pfn will be a very low value. We need | ||
39 | * to know the amount of memory that the previous kernel used. | ||
40 | */ | ||
41 | unsigned long saved_max_pfn; | ||
42 | #endif | ||
43 | |||
36 | /* return the number of _pages_ that will be allocated for the boot bitmap */ | 44 | /* return the number of _pages_ that will be allocated for the boot bitmap */ |
37 | unsigned long __init bootmem_bootmap_pages (unsigned long pages) | 45 | unsigned long __init bootmem_bootmap_pages (unsigned long pages) |
38 | { | 46 | { |
@@ -57,7 +65,7 @@ static unsigned long __init init_bootmem_core (pg_data_t *pgdat, | |||
57 | pgdat->pgdat_next = pgdat_list; | 65 | pgdat->pgdat_next = pgdat_list; |
58 | pgdat_list = pgdat; | 66 | pgdat_list = pgdat; |
59 | 67 | ||
60 | mapsize = (mapsize + (sizeof(long) - 1UL)) & ~(sizeof(long) - 1UL); | 68 | mapsize = ALIGN(mapsize, sizeof(long)); |
61 | bdata->node_bootmem_map = phys_to_virt(mapstart << PAGE_SHIFT); | 69 | bdata->node_bootmem_map = phys_to_virt(mapstart << PAGE_SHIFT); |
62 | bdata->node_boot_start = (start << PAGE_SHIFT); | 70 | bdata->node_boot_start = (start << PAGE_SHIFT); |
63 | bdata->node_low_pfn = end; | 71 | bdata->node_low_pfn = end; |
@@ -178,7 +186,7 @@ __alloc_bootmem_core(struct bootmem_data *bdata, unsigned long size, | |||
178 | } else | 186 | } else |
179 | preferred = 0; | 187 | preferred = 0; |
180 | 188 | ||
181 | preferred = ((preferred + align - 1) & ~(align - 1)) >> PAGE_SHIFT; | 189 | preferred = ALIGN(preferred, align) >> PAGE_SHIFT; |
182 | preferred += offset; | 190 | preferred += offset; |
183 | areasize = (size+PAGE_SIZE-1)/PAGE_SIZE; | 191 | areasize = (size+PAGE_SIZE-1)/PAGE_SIZE; |
184 | incr = align >> PAGE_SHIFT ? : 1; | 192 | incr = align >> PAGE_SHIFT ? : 1; |
@@ -219,7 +227,7 @@ found: | |||
219 | */ | 227 | */ |
220 | if (align < PAGE_SIZE && | 228 | if (align < PAGE_SIZE && |
221 | bdata->last_offset && bdata->last_pos+1 == start) { | 229 | bdata->last_offset && bdata->last_pos+1 == start) { |
222 | offset = (bdata->last_offset+align-1) & ~(align-1); | 230 | offset = ALIGN(bdata->last_offset, align); |
223 | BUG_ON(offset > PAGE_SIZE); | 231 | BUG_ON(offset > PAGE_SIZE); |
224 | remaining_size = PAGE_SIZE-offset; | 232 | remaining_size = PAGE_SIZE-offset; |
225 | if (size < remaining_size) { | 233 | if (size < remaining_size) { |
diff --git a/mm/filemap.c b/mm/filemap.c index 7332194d7afd..c11418dd94e8 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -1851,8 +1851,11 @@ generic_file_direct_write(struct kiocb *iocb, const struct iovec *iov, | |||
1851 | * i_sem is held, which protects generic_osync_inode() from | 1851 | * i_sem is held, which protects generic_osync_inode() from |
1852 | * livelocking. | 1852 | * livelocking. |
1853 | */ | 1853 | */ |
1854 | if (written >= 0 && file->f_flags & O_SYNC) | 1854 | if (written >= 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { |
1855 | generic_osync_inode(inode, mapping, OSYNC_METADATA); | 1855 | int err = generic_osync_inode(inode, mapping, OSYNC_METADATA); |
1856 | if (err < 0) | ||
1857 | written = err; | ||
1858 | } | ||
1856 | if (written == count && !is_sync_kiocb(iocb)) | 1859 | if (written == count && !is_sync_kiocb(iocb)) |
1857 | written = -EIOCBQUEUED; | 1860 | written = -EIOCBQUEUED; |
1858 | return written; | 1861 | return written; |
@@ -1951,7 +1954,9 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov, | |||
1951 | if (unlikely(nr_segs > 1)) { | 1954 | if (unlikely(nr_segs > 1)) { |
1952 | filemap_set_next_iovec(&cur_iov, | 1955 | filemap_set_next_iovec(&cur_iov, |
1953 | &iov_base, status); | 1956 | &iov_base, status); |
1954 | buf = cur_iov->iov_base + iov_base; | 1957 | if (count) |
1958 | buf = cur_iov->iov_base + | ||
1959 | iov_base; | ||
1955 | } else { | 1960 | } else { |
1956 | iov_base += status; | 1961 | iov_base += status; |
1957 | } | 1962 | } |
diff --git a/mm/memory.c b/mm/memory.c index c256175742ac..beabdefa6254 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -1139,7 +1139,7 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, | |||
1139 | { | 1139 | { |
1140 | pgd_t *pgd; | 1140 | pgd_t *pgd; |
1141 | unsigned long next; | 1141 | unsigned long next; |
1142 | unsigned long end = addr + size; | 1142 | unsigned long end = addr + PAGE_ALIGN(size); |
1143 | struct mm_struct *mm = vma->vm_mm; | 1143 | struct mm_struct *mm = vma->vm_mm; |
1144 | int err; | 1144 | int err; |
1145 | 1145 | ||
diff --git a/mm/page_io.c b/mm/page_io.c index 667c76df1ec2..2e605a19ce57 100644 --- a/mm/page_io.c +++ b/mm/page_io.c | |||
@@ -127,7 +127,7 @@ out: | |||
127 | return ret; | 127 | return ret; |
128 | } | 128 | } |
129 | 129 | ||
130 | #if defined(CONFIG_SOFTWARE_SUSPEND) || defined(CONFIG_PM_DISK) | 130 | #ifdef CONFIG_SOFTWARE_SUSPEND |
131 | /* | 131 | /* |
132 | * A scruffy utility function to read or write an arbitrary swap page | 132 | * A scruffy utility function to read or write an arbitrary swap page |
133 | * and wait on the I/O. The caller must have a ref on the page. | 133 | * and wait on the I/O. The caller must have a ref on the page. |
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 690e88ba2484..347083433120 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig | |||
@@ -1,32 +1,6 @@ | |||
1 | # | 1 | # |
2 | # IP configuration | 2 | # IP configuration |
3 | # | 3 | # |
4 | choice | ||
5 | prompt "Choose IP: FIB lookup" | ||
6 | depends on INET | ||
7 | default IP_FIB_HASH | ||
8 | |||
9 | config IP_FIB_HASH | ||
10 | bool "FIB_HASH" | ||
11 | ---help--- | ||
12 | Current FIB is very proven and good enough for most users. | ||
13 | |||
14 | config IP_FIB_TRIE | ||
15 | bool "FIB_TRIE" | ||
16 | ---help--- | ||
17 | Use new experimental LC-trie as FIB lookup algoritm. | ||
18 | This improves lookup performance | ||
19 | |||
20 | LC-trie is described in: | ||
21 | |||
22 | IP-address lookup using LC-tries. Stefan Nilsson and Gunnar Karlsson | ||
23 | IEEE Journal on Selected Areas in Communications, 17(6):1083-1092, June 1999 | ||
24 | An experimental study of compression methods for dynamic tries | ||
25 | Stefan Nilsson and Matti Tikkanen. Algorithmica, 33(1):19-33, 2002. | ||
26 | http://www.nada.kth.se/~snilsson/public/papers/dyntrie2/ | ||
27 | |||
28 | endchoice | ||
29 | |||
30 | config IP_MULTICAST | 4 | config IP_MULTICAST |
31 | bool "IP: multicasting" | 5 | bool "IP: multicasting" |
32 | depends on INET | 6 | depends on INET |
@@ -79,6 +53,44 @@ config IP_ADVANCED_ROUTER | |||
79 | 53 | ||
80 | If unsure, say N here. | 54 | If unsure, say N here. |
81 | 55 | ||
56 | choice | ||
57 | prompt "Choose IP: FIB lookup algorithm (choose FIB_HASH if unsure)" | ||
58 | depends on IP_ADVANCED_ROUTER | ||
59 | default IP_FIB_HASH | ||
60 | |||
61 | config IP_FIB_HASH | ||
62 | bool "FIB_HASH" | ||
63 | ---help--- | ||
64 | Current FIB is very proven and good enough for most users. | ||
65 | |||
66 | config IP_FIB_TRIE | ||
67 | bool "FIB_TRIE" | ||
68 | ---help--- | ||
69 | Use new experimental LC-trie as FIB lookup algoritm. | ||
70 | This improves lookup performance if you have a large | ||
71 | number of routes. | ||
72 | |||
73 | LC-trie is a longest matching prefix lookup algorithm which | ||
74 | performs better than FIB_HASH for large routing tables. | ||
75 | But, it consumes more memory and is more complex. | ||
76 | |||
77 | LC-trie is described in: | ||
78 | |||
79 | IP-address lookup using LC-tries. Stefan Nilsson and Gunnar Karlsson | ||
80 | IEEE Journal on Selected Areas in Communications, 17(6):1083-1092, June 1999 | ||
81 | An experimental study of compression methods for dynamic tries | ||
82 | Stefan Nilsson and Matti Tikkanen. Algorithmica, 33(1):19-33, 2002. | ||
83 | http://www.nada.kth.se/~snilsson/public/papers/dyntrie2/ | ||
84 | |||
85 | endchoice | ||
86 | |||
87 | # If the user does not enable advanced routing, he gets the safe | ||
88 | # default of the fib-hash algorithm. | ||
89 | config IP_FIB_HASH | ||
90 | bool | ||
91 | depends on !IP_ADVANCED_ROUTER | ||
92 | default y | ||
93 | |||
82 | config IP_MULTIPLE_TABLES | 94 | config IP_MULTIPLE_TABLES |
83 | bool "IP: policy routing" | 95 | bool "IP: policy routing" |
84 | depends on IP_ADVANCED_ROUTER | 96 | depends on IP_ADVANCED_ROUTER |
@@ -433,9 +445,22 @@ config IP_TCPDIAG | |||
433 | config IP_TCPDIAG_IPV6 | 445 | config IP_TCPDIAG_IPV6 |
434 | def_bool (IP_TCPDIAG=y && IPV6=y) || (IP_TCPDIAG=m && IPV6) | 446 | def_bool (IP_TCPDIAG=y && IPV6=y) || (IP_TCPDIAG=m && IPV6) |
435 | 447 | ||
448 | config TCP_CONG_ADVANCED | ||
449 | bool "TCP: advanced congestion control" | ||
450 | depends on INET | ||
451 | default y | ||
452 | ---help--- | ||
453 | Support for selection of various TCP congestion control | ||
454 | modules. | ||
455 | |||
456 | Nearly all users can safely say no here, and a safe default | ||
457 | selection will be made (BIC-TCP with new Reno as a fallback). | ||
458 | |||
459 | If unsure, say N. | ||
460 | |||
436 | # TCP Reno is builtin (required as fallback) | 461 | # TCP Reno is builtin (required as fallback) |
437 | menu "TCP congestion control" | 462 | menu "TCP congestion control" |
438 | depends on INET | 463 | depends on TCP_CONG_ADVANCED |
439 | 464 | ||
440 | config TCP_CONG_BIC | 465 | config TCP_CONG_BIC |
441 | tristate "Binary Increase Congestion (BIC) control" | 466 | tristate "Binary Increase Congestion (BIC) control" |
@@ -523,5 +548,10 @@ config TCP_CONG_SCALABLE | |||
523 | 548 | ||
524 | endmenu | 549 | endmenu |
525 | 550 | ||
551 | config TCP_CONG_BIC | ||
552 | boolean | ||
553 | depends on !TCP_CONG_ADVANCED | ||
554 | default y | ||
555 | |||
526 | source "net/ipv4/ipvs/Kconfig" | 556 | source "net/ipv4/ipvs/Kconfig" |
527 | 557 | ||
diff --git a/net/sched/Kconfig b/net/sched/Kconfig index 447b89e556b1..7bac249258e3 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig | |||
@@ -453,10 +453,11 @@ config NET_EMATCH_TEXT | |||
453 | tristate "Textsearch" | 453 | tristate "Textsearch" |
454 | depends on NET_EMATCH | 454 | depends on NET_EMATCH |
455 | select TEXTSEARCH | 455 | select TEXTSEARCH |
456 | select TEXTSEARCH_KMP | ||
457 | select TEXTSEARCH_FSM | ||
456 | ---help--- | 458 | ---help--- |
457 | Say Y here if you want to be ablt to classify packets based on | 459 | Say Y here if you want to be ablt to classify packets based on |
458 | textsearch comparisons. Please select the appropriate textsearch | 460 | textsearch comparisons. |
459 | algorithms in the Library section. | ||
460 | 461 | ||
461 | To compile this code as a module, choose M here: the | 462 | To compile this code as a module, choose M here: the |
462 | module will be called em_text. | 463 | module will be called em_text. |
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index eca92405948f..269f217918a3 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
@@ -970,7 +970,7 @@ tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc) | |||
970 | goto out; | 970 | goto out; |
971 | } | 971 | } |
972 | 972 | ||
973 | dprintk("RPC: XID %08x read %u bytes\n", | 973 | dprintk("RPC: XID %08x read %Zd bytes\n", |
974 | ntohl(xprt->tcp_xid), r); | 974 | ntohl(xprt->tcp_xid), r); |
975 | dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n", | 975 | dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n", |
976 | xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen); | 976 | xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen); |
@@ -1006,7 +1006,7 @@ tcp_read_discard(struct rpc_xprt *xprt, skb_reader_t *desc) | |||
1006 | desc->count -= len; | 1006 | desc->count -= len; |
1007 | desc->offset += len; | 1007 | desc->offset += len; |
1008 | xprt->tcp_offset += len; | 1008 | xprt->tcp_offset += len; |
1009 | dprintk("RPC: discarded %u bytes\n", len); | 1009 | dprintk("RPC: discarded %Zu bytes\n", len); |
1010 | tcp_check_recm(xprt); | 1010 | tcp_check_recm(xprt); |
1011 | } | 1011 | } |
1012 | 1012 | ||
diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c index 8ca7ecdb68fb..cb02baa63256 100644 --- a/scripts/basic/docproc.c +++ b/scripts/basic/docproc.c | |||
@@ -52,7 +52,7 @@ FILEONLY *internalfunctions; | |||
52 | FILEONLY *externalfunctions; | 52 | FILEONLY *externalfunctions; |
53 | FILEONLY *symbolsonly; | 53 | FILEONLY *symbolsonly; |
54 | 54 | ||
55 | typedef void FILELINE(char * file, signed char * line); | 55 | typedef void FILELINE(char * file, char * line); |
56 | FILELINE * singlefunctions; | 56 | FILELINE * singlefunctions; |
57 | FILELINE * entity_system; | 57 | FILELINE * entity_system; |
58 | 58 | ||
@@ -148,9 +148,9 @@ struct symfile * filename_exist(char * filename) | |||
148 | * Files are separated by tabs. | 148 | * Files are separated by tabs. |
149 | */ | 149 | */ |
150 | void adddep(char * file) { printf("\t%s", file); } | 150 | void adddep(char * file) { printf("\t%s", file); } |
151 | void adddep2(char * file, signed char * line) { line = line; adddep(file); } | 151 | void adddep2(char * file, char * line) { line = line; adddep(file); } |
152 | void noaction(char * line) { line = line; } | 152 | void noaction(char * line) { line = line; } |
153 | void noaction2(char * file, signed char * line) { file = file; line = line; } | 153 | void noaction2(char * file, char * line) { file = file; line = line; } |
154 | 154 | ||
155 | /* Echo the line without further action */ | 155 | /* Echo the line without further action */ |
156 | void printline(char * line) { printf("%s", line); } | 156 | void printline(char * line) { printf("%s", line); } |
@@ -179,8 +179,8 @@ void find_export_symbols(char * filename) | |||
179 | perror(real_filename); | 179 | perror(real_filename); |
180 | } | 180 | } |
181 | while(fgets(line, MAXLINESZ, fp)) { | 181 | while(fgets(line, MAXLINESZ, fp)) { |
182 | signed char *p; | 182 | char *p; |
183 | signed char *e; | 183 | char *e; |
184 | if (((p = strstr(line, "EXPORT_SYMBOL_GPL")) != 0) || | 184 | if (((p = strstr(line, "EXPORT_SYMBOL_GPL")) != 0) || |
185 | ((p = strstr(line, "EXPORT_SYMBOL")) != 0)) { | 185 | ((p = strstr(line, "EXPORT_SYMBOL")) != 0)) { |
186 | /* Skip EXPORT_SYMBOL{_GPL} */ | 186 | /* Skip EXPORT_SYMBOL{_GPL} */ |
@@ -253,7 +253,7 @@ void extfunc(char * filename) { docfunctions(filename, FUNCTION); } | |||
253 | * Call kernel-doc with the following parameters: | 253 | * Call kernel-doc with the following parameters: |
254 | * kernel-doc -docbook -function function1 [-function function2] | 254 | * kernel-doc -docbook -function function1 [-function function2] |
255 | */ | 255 | */ |
256 | void singfunc(char * filename, signed char * line) | 256 | void singfunc(char * filename, char * line) |
257 | { | 257 | { |
258 | char *vec[200]; /* Enough for specific functions */ | 258 | char *vec[200]; /* Enough for specific functions */ |
259 | int i, idx = 0; | 259 | int i, idx = 0; |
@@ -290,7 +290,7 @@ void singfunc(char * filename, signed char * line) | |||
290 | void parse_file(FILE *infile) | 290 | void parse_file(FILE *infile) |
291 | { | 291 | { |
292 | char line[MAXLINESZ]; | 292 | char line[MAXLINESZ]; |
293 | signed char * s; | 293 | char * s; |
294 | while(fgets(line, MAXLINESZ, infile)) { | 294 | while(fgets(line, MAXLINESZ, infile)) { |
295 | if (line[0] == '!') { | 295 | if (line[0] == '!') { |
296 | s = line + 2; | 296 | s = line + 2; |
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index 7f42c5d8a5a2..0b61bea869f7 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c | |||
@@ -212,23 +212,23 @@ void use_config(char *m, int slen) | |||
212 | if (*p == '_') | 212 | if (*p == '_') |
213 | *p = '/'; | 213 | *p = '/'; |
214 | else | 214 | else |
215 | *p = tolower((unsigned char)*p); | 215 | *p = tolower((int)*p); |
216 | } | 216 | } |
217 | printf(" $(wildcard include/config/%s.h) \\\n", s); | 217 | printf(" $(wildcard include/config/%s.h) \\\n", s); |
218 | } | 218 | } |
219 | 219 | ||
220 | void parse_config_file(signed char *map, size_t len) | 220 | void parse_config_file(char *map, size_t len) |
221 | { | 221 | { |
222 | int *end = (int *) (map + len); | 222 | int *end = (int *) (map + len); |
223 | /* start at +1, so that p can never be < map */ | 223 | /* start at +1, so that p can never be < map */ |
224 | int *m = (int *) map + 1; | 224 | int *m = (int *) map + 1; |
225 | signed char *p, *q; | 225 | char *p, *q; |
226 | 226 | ||
227 | for (; m < end; m++) { | 227 | for (; m < end; m++) { |
228 | if (*m == INT_CONF) { p = (signed char *) m ; goto conf; } | 228 | if (*m == INT_CONF) { p = (char *) m ; goto conf; } |
229 | if (*m == INT_ONFI) { p = (signed char *) m-1; goto conf; } | 229 | if (*m == INT_ONFI) { p = (char *) m-1; goto conf; } |
230 | if (*m == INT_NFIG) { p = (signed char *) m-2; goto conf; } | 230 | if (*m == INT_NFIG) { p = (char *) m-2; goto conf; } |
231 | if (*m == INT_FIG_) { p = (signed char *) m-3; goto conf; } | 231 | if (*m == INT_FIG_) { p = (char *) m-3; goto conf; } |
232 | continue; | 232 | continue; |
233 | conf: | 233 | conf: |
234 | if (p > map + len - 7) | 234 | if (p > map + len - 7) |
@@ -291,9 +291,9 @@ void do_config_file(char *filename) | |||
291 | 291 | ||
292 | void parse_dep_file(void *map, size_t len) | 292 | void parse_dep_file(void *map, size_t len) |
293 | { | 293 | { |
294 | signed char *m = map; | 294 | char *m = map; |
295 | signed char *end = m + len; | 295 | char *end = m + len; |
296 | signed char *p; | 296 | char *p; |
297 | char s[PATH_MAX]; | 297 | char s[PATH_MAX]; |
298 | 298 | ||
299 | p = strchr(m, ':'); | 299 | p = strchr(m, ':'); |
diff --git a/scripts/basic/split-include.c b/scripts/basic/split-include.c index 60fc4d8ebaa9..459c45276cb1 100644 --- a/scripts/basic/split-include.c +++ b/scripts/basic/split-include.c | |||
@@ -104,7 +104,7 @@ int main(int argc, const char * argv []) | |||
104 | /* Read config lines. */ | 104 | /* Read config lines. */ |
105 | while (fgets(line, buffer_size, fp_config)) | 105 | while (fgets(line, buffer_size, fp_config)) |
106 | { | 106 | { |
107 | const signed char * str_config; | 107 | const char * str_config; |
108 | int is_same; | 108 | int is_same; |
109 | int itarget; | 109 | int itarget; |
110 | 110 | ||
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 70e7264c6942..bc20cab9d0d6 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c | |||
@@ -31,14 +31,14 @@ char *defconfig_file; | |||
31 | static int indent = 1; | 31 | static int indent = 1; |
32 | static int valid_stdin = 1; | 32 | static int valid_stdin = 1; |
33 | static int conf_cnt; | 33 | static int conf_cnt; |
34 | static signed char line[128]; | 34 | static char line[128]; |
35 | static struct menu *rootEntry; | 35 | static struct menu *rootEntry; |
36 | 36 | ||
37 | static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n"); | 37 | static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n"); |
38 | 38 | ||
39 | static void strip(signed char *str) | 39 | static void strip(char *str) |
40 | { | 40 | { |
41 | signed char *p = str; | 41 | char *p = str; |
42 | int l; | 42 | int l; |
43 | 43 | ||
44 | while ((isspace(*p))) | 44 | while ((isspace(*p))) |
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 2755c459d780..02f670cc6bb9 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c | |||
@@ -27,10 +27,10 @@ const char *conf_confnames[] = { | |||
27 | NULL, | 27 | NULL, |
28 | }; | 28 | }; |
29 | 29 | ||
30 | static char *conf_expand_value(const signed char *in) | 30 | static char *conf_expand_value(const char *in) |
31 | { | 31 | { |
32 | struct symbol *sym; | 32 | struct symbol *sym; |
33 | const signed char *src; | 33 | const char *src; |
34 | static char res_value[SYMBOL_MAXLENGTH]; | 34 | static char res_value[SYMBOL_MAXLENGTH]; |
35 | char *dst, name[SYMBOL_MAXLENGTH]; | 35 | char *dst, name[SYMBOL_MAXLENGTH]; |
36 | 36 | ||
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index e5db10ca9564..457bec29511d 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <string.h> | 20 | #include <string.h> |
21 | #include <termios.h> | 21 | #include <termios.h> |
22 | #include <unistd.h> | 22 | #include <unistd.h> |
23 | #include <locale.h> | ||
23 | 24 | ||
24 | #define LKC_DIRECT_LINK | 25 | #define LKC_DIRECT_LINK |
25 | #include "lkc.h" | 26 | #include "lkc.h" |
@@ -254,8 +255,8 @@ search_help[] = N_( | |||
254 | " USB$ => find all CONFIG_ symbols ending with USB\n" | 255 | " USB$ => find all CONFIG_ symbols ending with USB\n" |
255 | "\n"); | 256 | "\n"); |
256 | 257 | ||
257 | static signed char buf[4096], *bufptr = buf; | 258 | static char buf[4096], *bufptr = buf; |
258 | static signed char input_buf[4096]; | 259 | static char input_buf[4096]; |
259 | static char filename[PATH_MAX+1] = ".config"; | 260 | static char filename[PATH_MAX+1] = ".config"; |
260 | static char *args[1024], **argptr = args; | 261 | static char *args[1024], **argptr = args; |
261 | static int indent; | 262 | static int indent; |
diff --git a/security/keys/key.c b/security/keys/key.c index 3304d37bb379..fb89f9844465 100644 --- a/security/keys/key.c +++ b/security/keys/key.c | |||
@@ -980,7 +980,7 @@ void unregister_key_type(struct key_type *ktype) | |||
980 | spin_unlock(&key_serial_lock); | 980 | spin_unlock(&key_serial_lock); |
981 | 981 | ||
982 | /* make sure everyone revalidates their keys */ | 982 | /* make sure everyone revalidates their keys */ |
983 | synchronize_kernel(); | 983 | synchronize_rcu(); |
984 | 984 | ||
985 | /* we should now be able to destroy the payloads of all the keys of | 985 | /* we should now be able to destroy the payloads of all the keys of |
986 | * this type with impunity */ | 986 | * this type with impunity */ |
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 34db087bbcc7..9b0369c5a223 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c | |||
@@ -234,7 +234,7 @@ static int install_session_keyring(struct task_struct *tsk, | |||
234 | ret = 0; | 234 | ret = 0; |
235 | 235 | ||
236 | /* we're using RCU on the pointer */ | 236 | /* we're using RCU on the pointer */ |
237 | synchronize_kernel(); | 237 | synchronize_rcu(); |
238 | key_put(old); | 238 | key_put(old); |
239 | error: | 239 | error: |
240 | return ret; | 240 | return ret; |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 87302a49067b..17a1189f1ff8 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -1658,9 +1658,8 @@ static int selinux_bprm_secureexec (struct linux_binprm *bprm) | |||
1658 | 1658 | ||
1659 | static void selinux_bprm_free_security(struct linux_binprm *bprm) | 1659 | static void selinux_bprm_free_security(struct linux_binprm *bprm) |
1660 | { | 1660 | { |
1661 | struct bprm_security_struct *bsec = bprm->security; | 1661 | kfree(bprm->security); |
1662 | bprm->security = NULL; | 1662 | bprm->security = NULL; |
1663 | kfree(bsec); | ||
1664 | } | 1663 | } |
1665 | 1664 | ||
1666 | extern struct vfsmount *selinuxfs_mount; | 1665 | extern struct vfsmount *selinuxfs_mount; |
@@ -2477,6 +2476,17 @@ static int selinux_file_mprotect(struct vm_area_struct *vma, | |||
2477 | prot = reqprot; | 2476 | prot = reqprot; |
2478 | 2477 | ||
2479 | #ifndef CONFIG_PPC32 | 2478 | #ifndef CONFIG_PPC32 |
2479 | if ((prot & PROT_EXEC) && !(vma->vm_flags & VM_EXECUTABLE) && | ||
2480 | (vma->vm_start >= vma->vm_mm->start_brk && | ||
2481 | vma->vm_end <= vma->vm_mm->brk)) { | ||
2482 | /* | ||
2483 | * We are making an executable mapping in the brk region. | ||
2484 | * This has an additional execheap check. | ||
2485 | */ | ||
2486 | rc = task_has_perm(current, current, PROCESS__EXECHEAP); | ||
2487 | if (rc) | ||
2488 | return rc; | ||
2489 | } | ||
2480 | if (vma->vm_file != NULL && vma->anon_vma != NULL && (prot & PROT_EXEC)) { | 2490 | if (vma->vm_file != NULL && vma->anon_vma != NULL && (prot & PROT_EXEC)) { |
2481 | /* | 2491 | /* |
2482 | * We are making executable a file mapping that has | 2492 | * We are making executable a file mapping that has |
@@ -2488,6 +2498,16 @@ static int selinux_file_mprotect(struct vm_area_struct *vma, | |||
2488 | if (rc) | 2498 | if (rc) |
2489 | return rc; | 2499 | return rc; |
2490 | } | 2500 | } |
2501 | if (!vma->vm_file && (prot & PROT_EXEC) && | ||
2502 | vma->vm_start <= vma->vm_mm->start_stack && | ||
2503 | vma->vm_end >= vma->vm_mm->start_stack) { | ||
2504 | /* Attempt to make the process stack executable. | ||
2505 | * This has an additional execstack check. | ||
2506 | */ | ||
2507 | rc = task_has_perm(current, current, PROCESS__EXECSTACK); | ||
2508 | if (rc) | ||
2509 | return rc; | ||
2510 | } | ||
2491 | #endif | 2511 | #endif |
2492 | 2512 | ||
2493 | return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED); | 2513 | return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED); |
diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h index 8928bb4d3c53..1deb59e1b762 100644 --- a/security/selinux/include/av_perm_to_string.h +++ b/security/selinux/include/av_perm_to_string.h | |||
@@ -70,6 +70,8 @@ | |||
70 | S_(SECCLASS_PROCESS, PROCESS__DYNTRANSITION, "dyntransition") | 70 | S_(SECCLASS_PROCESS, PROCESS__DYNTRANSITION, "dyntransition") |
71 | S_(SECCLASS_PROCESS, PROCESS__SETCURRENT, "setcurrent") | 71 | S_(SECCLASS_PROCESS, PROCESS__SETCURRENT, "setcurrent") |
72 | S_(SECCLASS_PROCESS, PROCESS__EXECMEM, "execmem") | 72 | S_(SECCLASS_PROCESS, PROCESS__EXECMEM, "execmem") |
73 | S_(SECCLASS_PROCESS, PROCESS__EXECSTACK, "execstack") | ||
74 | S_(SECCLASS_PROCESS, PROCESS__EXECHEAP, "execheap") | ||
73 | S_(SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue") | 75 | S_(SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue") |
74 | S_(SECCLASS_MSG, MSG__SEND, "send") | 76 | S_(SECCLASS_MSG, MSG__SEND, "send") |
75 | S_(SECCLASS_MSG, MSG__RECEIVE, "receive") | 77 | S_(SECCLASS_MSG, MSG__RECEIVE, "receive") |
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h index bdfce4ca8f8e..a78b5d59c9fc 100644 --- a/security/selinux/include/av_permissions.h +++ b/security/selinux/include/av_permissions.h | |||
@@ -465,6 +465,8 @@ | |||
465 | #define PROCESS__DYNTRANSITION 0x00800000UL | 465 | #define PROCESS__DYNTRANSITION 0x00800000UL |
466 | #define PROCESS__SETCURRENT 0x01000000UL | 466 | #define PROCESS__SETCURRENT 0x01000000UL |
467 | #define PROCESS__EXECMEM 0x02000000UL | 467 | #define PROCESS__EXECMEM 0x02000000UL |
468 | #define PROCESS__EXECSTACK 0x04000000UL | ||
469 | #define PROCESS__EXECHEAP 0x08000000UL | ||
468 | 470 | ||
469 | #define IPC__CREATE 0x00000001UL | 471 | #define IPC__CREATE 0x00000001UL |
470 | #define IPC__DESTROY 0x00000002UL | 472 | #define IPC__DESTROY 0x00000002UL |
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 07221568b505..8eb140dd2e4b 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c | |||
@@ -951,8 +951,7 @@ static int sel_make_bools(void) | |||
951 | u32 sid; | 951 | u32 sid; |
952 | 952 | ||
953 | /* remove any existing files */ | 953 | /* remove any existing files */ |
954 | if (bool_pending_values) | 954 | kfree(bool_pending_values); |
955 | kfree(bool_pending_values); | ||
956 | 955 | ||
957 | sel_remove_bools(dir); | 956 | sel_remove_bools(dir); |
958 | 957 | ||
@@ -997,10 +996,8 @@ static int sel_make_bools(void) | |||
997 | out: | 996 | out: |
998 | free_page((unsigned long)page); | 997 | free_page((unsigned long)page); |
999 | if (names) { | 998 | if (names) { |
1000 | for (i = 0; i < num; i++) { | 999 | for (i = 0; i < num; i++) |
1001 | if (names[i]) | 1000 | kfree(names[i]); |
1002 | kfree(names[i]); | ||
1003 | } | ||
1004 | kfree(names); | 1001 | kfree(names); |
1005 | } | 1002 | } |
1006 | return ret; | 1003 | return ret; |
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c index b53441184aca..e2057f5a411a 100644 --- a/security/selinux/ss/conditional.c +++ b/security/selinux/ss/conditional.c | |||
@@ -166,16 +166,14 @@ static void cond_list_destroy(struct cond_node *list) | |||
166 | 166 | ||
167 | void cond_policydb_destroy(struct policydb *p) | 167 | void cond_policydb_destroy(struct policydb *p) |
168 | { | 168 | { |
169 | if (p->bool_val_to_struct != NULL) | 169 | kfree(p->bool_val_to_struct); |
170 | kfree(p->bool_val_to_struct); | ||
171 | avtab_destroy(&p->te_cond_avtab); | 170 | avtab_destroy(&p->te_cond_avtab); |
172 | cond_list_destroy(p->cond_list); | 171 | cond_list_destroy(p->cond_list); |
173 | } | 172 | } |
174 | 173 | ||
175 | int cond_init_bool_indexes(struct policydb *p) | 174 | int cond_init_bool_indexes(struct policydb *p) |
176 | { | 175 | { |
177 | if (p->bool_val_to_struct) | 176 | kfree(p->bool_val_to_struct); |
178 | kfree(p->bool_val_to_struct); | ||
179 | p->bool_val_to_struct = (struct cond_bool_datum**) | 177 | p->bool_val_to_struct = (struct cond_bool_datum**) |
180 | kmalloc(p->p_bools.nprim * sizeof(struct cond_bool_datum*), GFP_KERNEL); | 178 | kmalloc(p->p_bools.nprim * sizeof(struct cond_bool_datum*), GFP_KERNEL); |
181 | if (!p->bool_val_to_struct) | 179 | if (!p->bool_val_to_struct) |
@@ -185,8 +183,7 @@ int cond_init_bool_indexes(struct policydb *p) | |||
185 | 183 | ||
186 | int cond_destroy_bool(void *key, void *datum, void *p) | 184 | int cond_destroy_bool(void *key, void *datum, void *p) |
187 | { | 185 | { |
188 | if (key) | 186 | kfree(key); |
189 | kfree(key); | ||
190 | kfree(datum); | 187 | kfree(datum); |
191 | return 0; | 188 | return 0; |
192 | } | 189 | } |
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index 14190efbf333..785c33cf4864 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c | |||
@@ -590,17 +590,12 @@ void policydb_destroy(struct policydb *p) | |||
590 | hashtab_destroy(p->symtab[i].table); | 590 | hashtab_destroy(p->symtab[i].table); |
591 | } | 591 | } |
592 | 592 | ||
593 | for (i = 0; i < SYM_NUM; i++) { | 593 | for (i = 0; i < SYM_NUM; i++) |
594 | if (p->sym_val_to_name[i]) | 594 | kfree(p->sym_val_to_name[i]); |
595 | kfree(p->sym_val_to_name[i]); | ||
596 | } | ||
597 | 595 | ||
598 | if (p->class_val_to_struct) | 596 | kfree(p->class_val_to_struct); |
599 | kfree(p->class_val_to_struct); | 597 | kfree(p->role_val_to_struct); |
600 | if (p->role_val_to_struct) | 598 | kfree(p->user_val_to_struct); |
601 | kfree(p->role_val_to_struct); | ||
602 | if (p->user_val_to_struct) | ||
603 | kfree(p->user_val_to_struct); | ||
604 | 599 | ||
605 | avtab_destroy(&p->te_avtab); | 600 | avtab_destroy(&p->te_avtab); |
606 | 601 | ||
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index b6149147d5cb..922bb45054aa 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -1705,11 +1705,9 @@ out: | |||
1705 | err: | 1705 | err: |
1706 | if (*names) { | 1706 | if (*names) { |
1707 | for (i = 0; i < *len; i++) | 1707 | for (i = 0; i < *len; i++) |
1708 | if ((*names)[i]) | 1708 | kfree((*names)[i]); |
1709 | kfree((*names)[i]); | ||
1710 | } | 1709 | } |
1711 | if (*values) | 1710 | kfree(*values); |
1712 | kfree(*values); | ||
1713 | goto out; | 1711 | goto out; |
1714 | } | 1712 | } |
1715 | 1713 | ||
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig index e537bd66a707..3b1fafc8f4f5 100644 --- a/sound/oss/Kconfig +++ b/sound/oss/Kconfig | |||
@@ -6,7 +6,7 @@ | |||
6 | # Prompt user for primary drivers. | 6 | # Prompt user for primary drivers. |
7 | config SOUND_BT878 | 7 | config SOUND_BT878 |
8 | tristate "BT878 audio dma" | 8 | tristate "BT878 audio dma" |
9 | depends on SOUND_PRIME!=n && SOUND | 9 | depends on SOUND_PRIME |
10 | ---help--- | 10 | ---help--- |
11 | Audio DMA support for bt878 based grabber boards. As you might have | 11 | Audio DMA support for bt878 based grabber boards. As you might have |
12 | already noticed, bt878 is listed with two functions in /proc/pci. | 12 | already noticed, bt878 is listed with two functions in /proc/pci. |
@@ -22,7 +22,7 @@ config SOUND_BT878 | |||
22 | 22 | ||
23 | config SOUND_CMPCI | 23 | config SOUND_CMPCI |
24 | tristate "C-Media PCI (CMI8338/8738)" | 24 | tristate "C-Media PCI (CMI8338/8738)" |
25 | depends on SOUND_PRIME!=n && SOUND && PCI | 25 | depends on SOUND_PRIME && PCI |
26 | help | 26 | help |
27 | Say Y or M if you have a PCI sound card using the CMI8338 | 27 | Say Y or M if you have a PCI sound card using the CMI8338 |
28 | or the CMI8738 chipset. Data on these chips are available at | 28 | or the CMI8738 chipset. Data on these chips are available at |
@@ -61,7 +61,7 @@ config SOUND_CMPCI_JOYSTICK | |||
61 | 61 | ||
62 | config SOUND_EMU10K1 | 62 | config SOUND_EMU10K1 |
63 | tristate "Creative SBLive! (EMU10K1)" | 63 | tristate "Creative SBLive! (EMU10K1)" |
64 | depends on SOUND_PRIME!=n && SOUND && PCI | 64 | depends on SOUND_PRIME && PCI |
65 | ---help--- | 65 | ---help--- |
66 | Say Y or M if you have a PCI sound card using the EMU10K1 chipset, | 66 | Say Y or M if you have a PCI sound card using the EMU10K1 chipset, |
67 | such as the Creative SBLive!, SB PCI512 or Emu-APS. | 67 | such as the Creative SBLive!, SB PCI512 or Emu-APS. |
@@ -87,7 +87,7 @@ config MIDI_EMU10K1 | |||
87 | 87 | ||
88 | config SOUND_FUSION | 88 | config SOUND_FUSION |
89 | tristate "Crystal SoundFusion (CS4280/461x)" | 89 | tristate "Crystal SoundFusion (CS4280/461x)" |
90 | depends on SOUND_PRIME!=n && SOUND | 90 | depends on SOUND_PRIME |
91 | help | 91 | help |
92 | This module drives the Crystal SoundFusion devices (CS4280/46xx | 92 | This module drives the Crystal SoundFusion devices (CS4280/46xx |
93 | series) when wired as native sound drivers with AC97 codecs. If | 93 | series) when wired as native sound drivers with AC97 codecs. If |
@@ -95,14 +95,14 @@ config SOUND_FUSION | |||
95 | 95 | ||
96 | config SOUND_CS4281 | 96 | config SOUND_CS4281 |
97 | tristate "Crystal Sound CS4281" | 97 | tristate "Crystal Sound CS4281" |
98 | depends on SOUND_PRIME!=n && SOUND | 98 | depends on SOUND_PRIME |
99 | help | 99 | help |
100 | Picture and feature list at | 100 | Picture and feature list at |
101 | <http://www.pcbroker.com/crystal4281.html>. | 101 | <http://www.pcbroker.com/crystal4281.html>. |
102 | 102 | ||
103 | config SOUND_BCM_CS4297A | 103 | config SOUND_BCM_CS4297A |
104 | tristate "Crystal Sound CS4297a (for Swarm)" | 104 | tristate "Crystal Sound CS4297a (for Swarm)" |
105 | depends on SOUND_PRIME!=n && SIBYTE_SWARM && SOUND | 105 | depends on SOUND_PRIME && SIBYTE_SWARM |
106 | help | 106 | help |
107 | The BCM91250A has a Crystal CS4297a on synchronous serial | 107 | The BCM91250A has a Crystal CS4297a on synchronous serial |
108 | port B (in addition to the DB-9 serial port). Say Y or M | 108 | port B (in addition to the DB-9 serial port). Say Y or M |
@@ -112,7 +112,7 @@ config SOUND_BCM_CS4297A | |||
112 | 112 | ||
113 | config SOUND_ES1370 | 113 | config SOUND_ES1370 |
114 | tristate "Ensoniq AudioPCI (ES1370)" | 114 | tristate "Ensoniq AudioPCI (ES1370)" |
115 | depends on SOUND_PRIME!=n && SOUND && PCI | 115 | depends on SOUND_PRIME && PCI |
116 | help | 116 | help |
117 | Say Y or M if you have a PCI sound card utilizing the Ensoniq | 117 | Say Y or M if you have a PCI sound card utilizing the Ensoniq |
118 | ES1370 chipset, such as Ensoniq's AudioPCI (non-97). To find | 118 | ES1370 chipset, such as Ensoniq's AudioPCI (non-97). To find |
@@ -125,7 +125,7 @@ config SOUND_ES1370 | |||
125 | 125 | ||
126 | config SOUND_ES1371 | 126 | config SOUND_ES1371 |
127 | tristate "Creative Ensoniq AudioPCI 97 (ES1371)" | 127 | tristate "Creative Ensoniq AudioPCI 97 (ES1371)" |
128 | depends on SOUND_PRIME!=n && SOUND && PCI | 128 | depends on SOUND_PRIME && PCI |
129 | help | 129 | help |
130 | Say Y or M if you have a PCI sound card utilizing the Ensoniq | 130 | Say Y or M if you have a PCI sound card utilizing the Ensoniq |
131 | ES1371 chipset, such as Ensoniq's AudioPCI97. To find out if | 131 | ES1371 chipset, such as Ensoniq's AudioPCI97. To find out if |
@@ -138,7 +138,7 @@ config SOUND_ES1371 | |||
138 | 138 | ||
139 | config SOUND_ESSSOLO1 | 139 | config SOUND_ESSSOLO1 |
140 | tristate "ESS Technology Solo1" | 140 | tristate "ESS Technology Solo1" |
141 | depends on SOUND_PRIME!=n && SOUND && PCI | 141 | depends on SOUND_PRIME && PCI |
142 | help | 142 | help |
143 | Say Y or M if you have a PCI sound card utilizing the ESS Technology | 143 | Say Y or M if you have a PCI sound card utilizing the ESS Technology |
144 | Solo1 chip. To find out if your sound card uses a | 144 | Solo1 chip. To find out if your sound card uses a |
@@ -149,7 +149,7 @@ config SOUND_ESSSOLO1 | |||
149 | 149 | ||
150 | config SOUND_MAESTRO | 150 | config SOUND_MAESTRO |
151 | tristate "ESS Maestro, Maestro2, Maestro2E driver" | 151 | tristate "ESS Maestro, Maestro2, Maestro2E driver" |
152 | depends on SOUND_PRIME!=n && SOUND && PCI | 152 | depends on SOUND_PRIME && PCI |
153 | help | 153 | help |
154 | Say Y or M if you have a sound system driven by ESS's Maestro line | 154 | Say Y or M if you have a sound system driven by ESS's Maestro line |
155 | of PCI sound chips. These include the Maestro 1, Maestro 2, and | 155 | of PCI sound chips. These include the Maestro 1, Maestro 2, and |
@@ -158,28 +158,28 @@ config SOUND_MAESTRO | |||
158 | 158 | ||
159 | config SOUND_MAESTRO3 | 159 | config SOUND_MAESTRO3 |
160 | tristate "ESS Maestro3/Allegro driver (EXPERIMENTAL)" | 160 | tristate "ESS Maestro3/Allegro driver (EXPERIMENTAL)" |
161 | depends on SOUND_PRIME!=n && SOUND && PCI && EXPERIMENTAL | 161 | depends on SOUND_PRIME && PCI && EXPERIMENTAL |
162 | help | 162 | help |
163 | Say Y or M if you have a sound system driven by ESS's Maestro 3 | 163 | Say Y or M if you have a sound system driven by ESS's Maestro 3 |
164 | PCI sound chip. | 164 | PCI sound chip. |
165 | 165 | ||
166 | config SOUND_ICH | 166 | config SOUND_ICH |
167 | tristate "Intel ICH (i8xx) audio support" | 167 | tristate "Intel ICH (i8xx) audio support" |
168 | depends on SOUND_PRIME!=n && PCI | 168 | depends on SOUND_PRIME && PCI |
169 | help | 169 | help |
170 | Support for integral audio in Intel's I/O Controller Hub (ICH) | 170 | Support for integral audio in Intel's I/O Controller Hub (ICH) |
171 | chipset, as used on the 810/820/840 motherboards. | 171 | chipset, as used on the 810/820/840 motherboards. |
172 | 172 | ||
173 | config SOUND_HARMONY | 173 | config SOUND_HARMONY |
174 | tristate "PA Harmony audio driver" | 174 | tristate "PA Harmony audio driver" |
175 | depends on GSC_LASI && SOUND_PRIME!=n | 175 | depends on GSC_LASI && SOUND_PRIME |
176 | help | 176 | help |
177 | Say 'Y' or 'M' to include support for Harmony soundchip | 177 | Say 'Y' or 'M' to include support for Harmony soundchip |
178 | on HP 712, 715/new and many other GSC based machines. | 178 | on HP 712, 715/new and many other GSC based machines. |
179 | 179 | ||
180 | config SOUND_SONICVIBES | 180 | config SOUND_SONICVIBES |
181 | tristate "S3 SonicVibes" | 181 | tristate "S3 SonicVibes" |
182 | depends on SOUND_PRIME!=n && SOUND | 182 | depends on SOUND_PRIME |
183 | help | 183 | help |
184 | Say Y or M if you have a PCI sound card utilizing the S3 | 184 | Say Y or M if you have a PCI sound card utilizing the S3 |
185 | SonicVibes chipset. To find out if your sound card uses a | 185 | SonicVibes chipset. To find out if your sound card uses a |
@@ -190,7 +190,7 @@ config SOUND_SONICVIBES | |||
190 | 190 | ||
191 | config SOUND_VWSND | 191 | config SOUND_VWSND |
192 | tristate "SGI Visual Workstation Sound" | 192 | tristate "SGI Visual Workstation Sound" |
193 | depends on SOUND_PRIME!=n && X86_VISWS && SOUND | 193 | depends on SOUND_PRIME && X86_VISWS |
194 | help | 194 | help |
195 | Say Y or M if you have an SGI Visual Workstation and you want to be | 195 | Say Y or M if you have an SGI Visual Workstation and you want to be |
196 | able to use its on-board audio. Read | 196 | able to use its on-board audio. Read |
@@ -199,18 +199,18 @@ config SOUND_VWSND | |||
199 | 199 | ||
200 | config SOUND_HAL2 | 200 | config SOUND_HAL2 |
201 | tristate "SGI HAL2 sound (EXPERIMENTAL)" | 201 | tristate "SGI HAL2 sound (EXPERIMENTAL)" |
202 | depends on SOUND_PRIME!=n && SOUND && SGI_IP22 && EXPERIMENTAL | 202 | depends on SOUND_PRIME && SGI_IP22 && EXPERIMENTAL |
203 | help | 203 | help |
204 | Say Y or M if you have an SGI Indy system and want to be able to | 204 | Say Y or M if you have an SGI Indy system and want to be able to |
205 | use it's on-board A2 audio system. | 205 | use it's on-board A2 audio system. |
206 | 206 | ||
207 | config SOUND_IT8172 | 207 | config SOUND_IT8172 |
208 | tristate "IT8172G Sound" | 208 | tristate "IT8172G Sound" |
209 | depends on SOUND_PRIME!=n && (MIPS_ITE8172 || MIPS_IVR) && SOUND | 209 | depends on SOUND_PRIME && (MIPS_ITE8172 || MIPS_IVR) |
210 | 210 | ||
211 | config SOUND_VRC5477 | 211 | config SOUND_VRC5477 |
212 | tristate "NEC Vrc5477 AC97 sound" | 212 | tristate "NEC Vrc5477 AC97 sound" |
213 | depends on SOUND_PRIME!=n && DDB5477 && SOUND | 213 | depends on SOUND_PRIME && DDB5477 |
214 | help | 214 | help |
215 | Say Y here to enable sound support for the NEC Vrc5477 chip, an | 215 | Say Y here to enable sound support for the NEC Vrc5477 chip, an |
216 | integrated, multi-function controller chip for MIPS CPUs. Works | 216 | integrated, multi-function controller chip for MIPS CPUs. Works |
@@ -218,15 +218,15 @@ config SOUND_VRC5477 | |||
218 | 218 | ||
219 | config SOUND_AU1000 | 219 | config SOUND_AU1000 |
220 | tristate "Au1000 Sound" | 220 | tristate "Au1000 Sound" |
221 | depends on SOUND_PRIME!=n && (SOC_AU1000 || SOC_AU1100 || SOC_AU1500) && SOUND | 221 | depends on SOUND_PRIME && (SOC_AU1000 || SOC_AU1100 || SOC_AU1500) |
222 | 222 | ||
223 | config SOUND_AU1550_AC97 | 223 | config SOUND_AU1550_AC97 |
224 | tristate "Au1550 AC97 Sound" | 224 | tristate "Au1550 AC97 Sound" |
225 | depends on SOUND_PRIME!=n && SOC_AU1550 && SOUND | 225 | depends on SOUND_PRIME && SOC_AU1550 |
226 | 226 | ||
227 | config SOUND_TRIDENT | 227 | config SOUND_TRIDENT |
228 | tristate "Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core" | 228 | tristate "Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core" |
229 | depends on SOUND_PRIME!=n && SOUND | 229 | depends on SOUND_PRIME |
230 | ---help--- | 230 | ---help--- |
231 | Say Y or M if you have a PCI sound card utilizing the Trident | 231 | Say Y or M if you have a PCI sound card utilizing the Trident |
232 | 4DWave-DX/NX chipset or your mother board chipset has SiS 7018 | 232 | 4DWave-DX/NX chipset or your mother board chipset has SiS 7018 |
@@ -267,7 +267,7 @@ config SOUND_TRIDENT | |||
267 | 267 | ||
268 | config SOUND_MSNDCLAS | 268 | config SOUND_MSNDCLAS |
269 | tristate "Support for Turtle Beach MultiSound Classic, Tahiti, Monterey" | 269 | tristate "Support for Turtle Beach MultiSound Classic, Tahiti, Monterey" |
270 | depends on SOUND_PRIME!=n && SOUND && (m || !STANDALONE) | 270 | depends on SOUND_PRIME && (m || !STANDALONE) |
271 | help | 271 | help |
272 | Say M here if you have a Turtle Beach MultiSound Classic, Tahiti or | 272 | Say M here if you have a Turtle Beach MultiSound Classic, Tahiti or |
273 | Monterey (not for the Pinnacle or Fiji). | 273 | Monterey (not for the Pinnacle or Fiji). |
@@ -331,7 +331,7 @@ config MSNDCLAS_IO | |||
331 | 331 | ||
332 | config SOUND_MSNDPIN | 332 | config SOUND_MSNDPIN |
333 | tristate "Support for Turtle Beach MultiSound Pinnacle, Fiji" | 333 | tristate "Support for Turtle Beach MultiSound Pinnacle, Fiji" |
334 | depends on SOUND_PRIME!=n && SOUND && (m || !STANDALONE) | 334 | depends on SOUND_PRIME && (m || !STANDALONE) |
335 | help | 335 | help |
336 | Say M here if you have a Turtle Beach MultiSound Pinnacle or Fiji. | 336 | Say M here if you have a Turtle Beach MultiSound Pinnacle or Fiji. |
337 | See <file:Documentation/sound/oss/MultiSound> for important information | 337 | See <file:Documentation/sound/oss/MultiSound> for important information |
@@ -492,7 +492,7 @@ config MSND_FIFOSIZE | |||
492 | 492 | ||
493 | config SOUND_VIA82CXXX | 493 | config SOUND_VIA82CXXX |
494 | tristate "VIA 82C686 Audio Codec" | 494 | tristate "VIA 82C686 Audio Codec" |
495 | depends on SOUND_PRIME!=n && PCI | 495 | depends on SOUND_PRIME && PCI |
496 | help | 496 | help |
497 | Say Y here to include support for the audio codec found on VIA | 497 | Say Y here to include support for the audio codec found on VIA |
498 | 82Cxxx-based chips. Typically these are built into a motherboard. | 498 | 82Cxxx-based chips. Typically these are built into a motherboard. |
@@ -512,7 +512,7 @@ config MIDI_VIA82CXXX | |||
512 | 512 | ||
513 | config SOUND_OSS | 513 | config SOUND_OSS |
514 | tristate "OSS sound modules" | 514 | tristate "OSS sound modules" |
515 | depends on SOUND_PRIME!=n && SOUND | 515 | depends on SOUND_PRIME |
516 | help | 516 | help |
517 | OSS is the Open Sound System suite of sound card drivers. They make | 517 | OSS is the Open Sound System suite of sound card drivers. They make |
518 | sound programming easier since they provide a common API. Say Y or | 518 | sound programming easier since they provide a common API. Say Y or |
@@ -1077,7 +1077,7 @@ config SOUND_WAVEARTIST | |||
1077 | 1077 | ||
1078 | config SOUND_TVMIXER | 1078 | config SOUND_TVMIXER |
1079 | tristate "TV card (bt848) mixer support" | 1079 | tristate "TV card (bt848) mixer support" |
1080 | depends on SOUND_PRIME!=n && SOUND && I2C | 1080 | depends on SOUND_PRIME && I2C |
1081 | help | 1081 | help |
1082 | Support for audio mixer facilities on the BT848 TV frame-grabber | 1082 | Support for audio mixer facilities on the BT848 TV frame-grabber |
1083 | card. | 1083 | card. |
@@ -1088,11 +1088,11 @@ config SOUND_KAHLUA | |||
1088 | 1088 | ||
1089 | config SOUND_ALI5455 | 1089 | config SOUND_ALI5455 |
1090 | tristate "ALi5455 audio support" | 1090 | tristate "ALi5455 audio support" |
1091 | depends on SOUND_PRIME!=n && PCI | 1091 | depends on SOUND_PRIME && PCI |
1092 | 1092 | ||
1093 | config SOUND_FORTE | 1093 | config SOUND_FORTE |
1094 | tristate "ForteMedia FM801 driver" | 1094 | tristate "ForteMedia FM801 driver" |
1095 | depends on SOUND_PRIME!=n && PCI | 1095 | depends on SOUND_PRIME && PCI |
1096 | help | 1096 | help |
1097 | Say Y or M if you want driver support for the ForteMedia FM801 PCI | 1097 | Say Y or M if you want driver support for the ForteMedia FM801 PCI |
1098 | audio controller (Abit AU10, Genius Sound Maker, HP Workstation | 1098 | audio controller (Abit AU10, Genius Sound Maker, HP Workstation |
@@ -1100,7 +1100,7 @@ config SOUND_FORTE | |||
1100 | 1100 | ||
1101 | config SOUND_RME96XX | 1101 | config SOUND_RME96XX |
1102 | tristate "RME Hammerfall (RME96XX) support" | 1102 | tristate "RME Hammerfall (RME96XX) support" |
1103 | depends on SOUND_PRIME!=n && PCI | 1103 | depends on SOUND_PRIME && PCI |
1104 | help | 1104 | help |
1105 | Say Y or M if you have a Hammerfall or Hammerfall light | 1105 | Say Y or M if you have a Hammerfall or Hammerfall light |
1106 | multichannel card from RME. If you want to access advanced | 1106 | multichannel card from RME. If you want to access advanced |
@@ -1108,11 +1108,11 @@ config SOUND_RME96XX | |||
1108 | 1108 | ||
1109 | config SOUND_AD1980 | 1109 | config SOUND_AD1980 |
1110 | tristate "AD1980 front/back switch plugin" | 1110 | tristate "AD1980 front/back switch plugin" |
1111 | depends on SOUND_PRIME!=n | 1111 | depends on SOUND_PRIME |
1112 | 1112 | ||
1113 | config SOUND_SH_DAC_AUDIO | 1113 | config SOUND_SH_DAC_AUDIO |
1114 | tristate "SuperH DAC audio support" | 1114 | tristate "SuperH DAC audio support" |
1115 | depends on SOUND_PRIME!=n && SOUND && CPU_SH3 | 1115 | depends on SOUND_PRIME && CPU_SH3 |
1116 | 1116 | ||
1117 | config SOUND_SH_DAC_AUDIO_CHANNEL | 1117 | config SOUND_SH_DAC_AUDIO_CHANNEL |
1118 | int " DAC channel" | 1118 | int " DAC channel" |
diff --git a/sound/oss/ad1816.c b/sound/oss/ad1816.c index 22dae5d0fda3..95586de02028 100644 --- a/sound/oss/ad1816.c +++ b/sound/oss/ad1816.c | |||
@@ -592,7 +592,7 @@ typedef struct mixer_def mixer_ent; | |||
592 | {{reg_l, pola_l, pos_l, len_l}, {reg_r, pola_r, pos_r, len_r}} | 592 | {{reg_l, pola_l, pos_l, len_l}, {reg_r, pola_r, pos_r, len_r}} |
593 | 593 | ||
594 | 594 | ||
595 | mixer_ent mix_devices[SOUND_MIXER_NRDEVICES][2] = { | 595 | static mixer_ent mix_devices[SOUND_MIXER_NRDEVICES][2] = { |
596 | MIX_ENT(SOUND_MIXER_VOLUME, 14, 1, 8, 5, 14, 1, 0, 5), | 596 | MIX_ENT(SOUND_MIXER_VOLUME, 14, 1, 8, 5, 14, 1, 0, 5), |
597 | MIX_ENT(SOUND_MIXER_BASS, 0, 0, 0, 0, 0, 0, 0, 0), | 597 | MIX_ENT(SOUND_MIXER_BASS, 0, 0, 0, 0, 0, 0, 0, 0), |
598 | MIX_ENT(SOUND_MIXER_TREBLE, 0, 0, 0, 0, 0, 0, 0, 0), | 598 | MIX_ENT(SOUND_MIXER_TREBLE, 0, 0, 0, 0, 0, 0, 0, 0), |
diff --git a/sound/oss/ad1848.c b/sound/oss/ad1848.c index 4384dac3f794..7c835abd99bc 100644 --- a/sound/oss/ad1848.c +++ b/sound/oss/ad1848.c | |||
@@ -2178,8 +2178,7 @@ void ad1848_unload(int io_base, int irq, int dma_playback, int dma_capture, int | |||
2178 | 2178 | ||
2179 | if (devc != NULL) | 2179 | if (devc != NULL) |
2180 | { | 2180 | { |
2181 | if(audio_devs[dev]->portc!=NULL) | 2181 | kfree(audio_devs[dev]->portc); |
2182 | kfree(audio_devs[dev]->portc); | ||
2183 | release_region(devc->base, 4); | 2182 | release_region(devc->base, 4); |
2184 | 2183 | ||
2185 | if (!share_dma) | 2184 | if (!share_dma) |
diff --git a/sound/oss/ad1889.c b/sound/oss/ad1889.c index b767c621fd09..2cfd214e4c2a 100644 --- a/sound/oss/ad1889.c +++ b/sound/oss/ad1889.c | |||
@@ -277,8 +277,7 @@ static void ad1889_free_dev(ad1889_dev_t *dev) | |||
277 | 277 | ||
278 | for (j = 0; j < AD_MAX_STATES; j++) { | 278 | for (j = 0; j < AD_MAX_STATES; j++) { |
279 | dmabuf = &dev->state[j].dmabuf; | 279 | dmabuf = &dev->state[j].dmabuf; |
280 | if (dmabuf->rawbuf != NULL) | 280 | kfree(dmabuf->rawbuf); |
281 | kfree(dmabuf->rawbuf); | ||
282 | } | 281 | } |
283 | 282 | ||
284 | kfree(dev); | 283 | kfree(dev); |
diff --git a/sound/oss/cmpci.c b/sound/oss/cmpci.c index 34720e66dae1..74dcca78c6c0 100644 --- a/sound/oss/cmpci.c +++ b/sound/oss/cmpci.c | |||
@@ -123,6 +123,7 @@ | |||
123 | #include <linux/smp_lock.h> | 123 | #include <linux/smp_lock.h> |
124 | #include <linux/bitops.h> | 124 | #include <linux/bitops.h> |
125 | #include <linux/wait.h> | 125 | #include <linux/wait.h> |
126 | #include <linux/dma-mapping.h> | ||
126 | 127 | ||
127 | #include <asm/io.h> | 128 | #include <asm/io.h> |
128 | #include <asm/page.h> | 129 | #include <asm/page.h> |
@@ -3058,7 +3059,7 @@ static int __devinit cm_probe(struct pci_dev *pcidev, const struct pci_device_id | |||
3058 | return -ENODEV; | 3059 | return -ENODEV; |
3059 | if (pcidev->irq == 0) | 3060 | if (pcidev->irq == 0) |
3060 | return -ENODEV; | 3061 | return -ENODEV; |
3061 | i = pci_set_dma_mask(pcidev, 0xffffffff); | 3062 | i = pci_set_dma_mask(pcidev, DMA_32BIT_MASK); |
3062 | if (i) { | 3063 | if (i) { |
3063 | printk(KERN_WARNING "cmpci: architecture does not support 32bit PCI busmaster DMA\n"); | 3064 | printk(KERN_WARNING "cmpci: architecture does not support 32bit PCI busmaster DMA\n"); |
3064 | return i; | 3065 | return i; |
diff --git a/sound/oss/dmasound/dmasound_awacs.c b/sound/oss/dmasound/dmasound_awacs.c index 5281b88987f3..33108661e671 100644 --- a/sound/oss/dmasound/dmasound_awacs.c +++ b/sound/oss/dmasound/dmasound_awacs.c | |||
@@ -671,14 +671,10 @@ static void PMacIrqCleanup(void) | |||
671 | release_OF_resource(awacs_node, 1); | 671 | release_OF_resource(awacs_node, 1); |
672 | release_OF_resource(awacs_node, 2); | 672 | release_OF_resource(awacs_node, 2); |
673 | 673 | ||
674 | if (awacs_tx_cmd_space) | 674 | kfree(awacs_tx_cmd_space); |
675 | kfree(awacs_tx_cmd_space); | 675 | kfree(awacs_rx_cmd_space); |
676 | if (awacs_rx_cmd_space) | 676 | kfree(beep_dbdma_cmd_space); |
677 | kfree(awacs_rx_cmd_space); | 677 | kfree(beep_buf); |
678 | if (beep_dbdma_cmd_space) | ||
679 | kfree(beep_dbdma_cmd_space); | ||
680 | if (beep_buf) | ||
681 | kfree(beep_buf); | ||
682 | #ifdef CONFIG_PMAC_PBOOK | 678 | #ifdef CONFIG_PMAC_PBOOK |
683 | pmu_unregister_sleep_notifier(&awacs_sleep_notifier); | 679 | pmu_unregister_sleep_notifier(&awacs_sleep_notifier); |
684 | #endif | 680 | #endif |
@@ -2301,8 +2297,7 @@ if (count <= 0) | |||
2301 | #endif | 2297 | #endif |
2302 | 2298 | ||
2303 | if ((write_sq.max_count + 1) > number_of_tx_cmd_buffers) { | 2299 | if ((write_sq.max_count + 1) > number_of_tx_cmd_buffers) { |
2304 | if (awacs_tx_cmd_space) | 2300 | kfree(awacs_tx_cmd_space); |
2305 | kfree(awacs_tx_cmd_space); | ||
2306 | number_of_tx_cmd_buffers = 0; | 2301 | number_of_tx_cmd_buffers = 0; |
2307 | 2302 | ||
2308 | /* we need nbufs + 1 (for the loop) and we should request + 1 | 2303 | /* we need nbufs + 1 (for the loop) and we should request + 1 |
@@ -2360,8 +2355,7 @@ if (count <= 0) | |||
2360 | #endif | 2355 | #endif |
2361 | 2356 | ||
2362 | if ((read_sq.max_count+1) > number_of_rx_cmd_buffers ) { | 2357 | if ((read_sq.max_count+1) > number_of_rx_cmd_buffers ) { |
2363 | if (awacs_rx_cmd_space) | 2358 | kfree(awacs_rx_cmd_space); |
2364 | kfree(awacs_rx_cmd_space); | ||
2365 | number_of_rx_cmd_buffers = 0; | 2359 | number_of_rx_cmd_buffers = 0; |
2366 | 2360 | ||
2367 | /* we need nbufs + 1 (for the loop) and we should request + 1 again | 2361 | /* we need nbufs + 1 (for the loop) and we should request + 1 again |
@@ -2805,7 +2799,7 @@ __init setup_beep(void) | |||
2805 | beep_buf = (short *) kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL); | 2799 | beep_buf = (short *) kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL); |
2806 | if (beep_buf == NULL) { | 2800 | if (beep_buf == NULL) { |
2807 | printk(KERN_ERR "dmasound_pmac: no memory for beep buffer\n"); | 2801 | printk(KERN_ERR "dmasound_pmac: no memory for beep buffer\n"); |
2808 | if( beep_dbdma_cmd_space ) kfree(beep_dbdma_cmd_space) ; | 2802 | kfree(beep_dbdma_cmd_space) ; |
2809 | return -ENOMEM ; | 2803 | return -ENOMEM ; |
2810 | } | 2804 | } |
2811 | return 0 ; | 2805 | return 0 ; |
diff --git a/sound/oss/emu10k1/midi.c b/sound/oss/emu10k1/midi.c index 33dea3d56c1e..b40b5f97aace 100644 --- a/sound/oss/emu10k1/midi.c +++ b/sound/oss/emu10k1/midi.c | |||
@@ -523,10 +523,8 @@ void emu10k1_seq_midi_close(int dev) | |||
523 | card = midi_devs[dev]->devc; | 523 | card = midi_devs[dev]->devc; |
524 | emu10k1_mpuout_close(card); | 524 | emu10k1_mpuout_close(card); |
525 | 525 | ||
526 | if (card->seq_mididev) { | 526 | kfree(card->seq_mididev); |
527 | kfree(card->seq_mididev); | 527 | card->seq_mididev = NULL; |
528 | card->seq_mididev = NULL; | ||
529 | } | ||
530 | } | 528 | } |
531 | 529 | ||
532 | int emu10k1_seq_midi_out(int dev, unsigned char midi_byte) | 530 | int emu10k1_seq_midi_out(int dev, unsigned char midi_byte) |
diff --git a/sound/oss/emu10k1/passthrough.c b/sound/oss/emu10k1/passthrough.c index 4094be55f3be..4e3baca7d41f 100644 --- a/sound/oss/emu10k1/passthrough.c +++ b/sound/oss/emu10k1/passthrough.c | |||
@@ -213,8 +213,7 @@ void emu10k1_pt_stop(struct emu10k1_card *card) | |||
213 | sblive_writeptr(card, SPCS0 + i, 0, pt->old_spcs[i]); | 213 | sblive_writeptr(card, SPCS0 + i, 0, pt->old_spcs[i]); |
214 | } | 214 | } |
215 | pt->state = PT_STATE_INACTIVE; | 215 | pt->state = PT_STATE_INACTIVE; |
216 | if(pt->buf) | 216 | kfree(pt->buf); |
217 | kfree(pt->buf); | ||
218 | } | 217 | } |
219 | } | 218 | } |
220 | 219 | ||
diff --git a/sound/oss/es1370.c b/sound/oss/es1370.c index 056091cff266..886f61c1c34a 100644 --- a/sound/oss/es1370.c +++ b/sound/oss/es1370.c | |||
@@ -156,6 +156,7 @@ | |||
156 | #include <linux/spinlock.h> | 156 | #include <linux/spinlock.h> |
157 | #include <linux/gameport.h> | 157 | #include <linux/gameport.h> |
158 | #include <linux/wait.h> | 158 | #include <linux/wait.h> |
159 | #include <linux/dma-mapping.h> | ||
159 | 160 | ||
160 | #include <asm/io.h> | 161 | #include <asm/io.h> |
161 | #include <asm/page.h> | 162 | #include <asm/page.h> |
@@ -2569,7 +2570,7 @@ static int __devinit es1370_probe(struct pci_dev *pcidev, const struct pci_devic | |||
2569 | return -ENODEV; | 2570 | return -ENODEV; |
2570 | if (pcidev->irq == 0) | 2571 | if (pcidev->irq == 0) |
2571 | return -ENODEV; | 2572 | return -ENODEV; |
2572 | i = pci_set_dma_mask(pcidev, 0xffffffff); | 2573 | i = pci_set_dma_mask(pcidev, DMA_32BIT_MASK); |
2573 | if (i) { | 2574 | if (i) { |
2574 | printk(KERN_WARNING "es1370: architecture does not support 32bit PCI busmaster DMA\n"); | 2575 | printk(KERN_WARNING "es1370: architecture does not support 32bit PCI busmaster DMA\n"); |
2575 | return i; | 2576 | return i; |
diff --git a/sound/oss/es1371.c b/sound/oss/es1371.c index a50fddaeea21..9266b777387b 100644 --- a/sound/oss/es1371.c +++ b/sound/oss/es1371.c | |||
@@ -128,6 +128,7 @@ | |||
128 | #include <linux/ac97_codec.h> | 128 | #include <linux/ac97_codec.h> |
129 | #include <linux/gameport.h> | 129 | #include <linux/gameport.h> |
130 | #include <linux/wait.h> | 130 | #include <linux/wait.h> |
131 | #include <linux/dma-mapping.h> | ||
131 | 132 | ||
132 | #include <asm/io.h> | 133 | #include <asm/io.h> |
133 | #include <asm/page.h> | 134 | #include <asm/page.h> |
@@ -2804,7 +2805,7 @@ static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_devic | |||
2804 | return -ENODEV; | 2805 | return -ENODEV; |
2805 | if (pcidev->irq == 0) | 2806 | if (pcidev->irq == 0) |
2806 | return -ENODEV; | 2807 | return -ENODEV; |
2807 | i = pci_set_dma_mask(pcidev, 0xffffffff); | 2808 | i = pci_set_dma_mask(pcidev, DMA_32BIT_MASK); |
2808 | if (i) { | 2809 | if (i) { |
2809 | printk(KERN_WARNING "es1371: architecture does not support 32bit PCI busmaster DMA\n"); | 2810 | printk(KERN_WARNING "es1371: architecture does not support 32bit PCI busmaster DMA\n"); |
2810 | return i; | 2811 | return i; |
diff --git a/sound/oss/esssolo1.c b/sound/oss/esssolo1.c index 6b3b9a99579d..fb09065d07c8 100644 --- a/sound/oss/esssolo1.c +++ b/sound/oss/esssolo1.c | |||
@@ -104,6 +104,7 @@ | |||
104 | #include <linux/smp_lock.h> | 104 | #include <linux/smp_lock.h> |
105 | #include <linux/gameport.h> | 105 | #include <linux/gameport.h> |
106 | #include <linux/wait.h> | 106 | #include <linux/wait.h> |
107 | #include <linux/dma-mapping.h> | ||
107 | 108 | ||
108 | #include <asm/io.h> | 109 | #include <asm/io.h> |
109 | #include <asm/page.h> | 110 | #include <asm/page.h> |
@@ -2326,7 +2327,7 @@ static int __devinit solo1_probe(struct pci_dev *pcidev, const struct pci_device | |||
2326 | * to 24 bits first, then 32 bits (playback only) if that fails. | 2327 | * to 24 bits first, then 32 bits (playback only) if that fails. |
2327 | */ | 2328 | */ |
2328 | if (pci_set_dma_mask(pcidev, 0x00ffffff) && | 2329 | if (pci_set_dma_mask(pcidev, 0x00ffffff) && |
2329 | pci_set_dma_mask(pcidev, 0xffffffff)) { | 2330 | pci_set_dma_mask(pcidev, DMA_32BIT_MASK)) { |
2330 | printk(KERN_WARNING "solo1: architecture does not support 24bit or 32bit PCI busmaster DMA\n"); | 2331 | printk(KERN_WARNING "solo1: architecture does not support 24bit or 32bit PCI busmaster DMA\n"); |
2331 | return -ENODEV; | 2332 | return -ENODEV; |
2332 | } | 2333 | } |
diff --git a/sound/oss/maestro.c b/sound/oss/maestro.c index 52d2db4bc312..3dce504e6d6d 100644 --- a/sound/oss/maestro.c +++ b/sound/oss/maestro.c | |||
@@ -2356,7 +2356,7 @@ ess_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | |||
2356 | } | 2356 | } |
2357 | 2357 | ||
2358 | rec_return_free: | 2358 | rec_return_free: |
2359 | if(combbuf) kfree(combbuf); | 2359 | kfree(combbuf); |
2360 | return ret; | 2360 | return ret; |
2361 | } | 2361 | } |
2362 | 2362 | ||
diff --git a/sound/oss/mpu401.c b/sound/oss/mpu401.c index b66f53fa8db0..0aac54c68f01 100644 --- a/sound/oss/mpu401.c +++ b/sound/oss/mpu401.c | |||
@@ -1240,8 +1240,7 @@ void unload_mpu401(struct address_info *hw_config) | |||
1240 | p=mpu401_synth_operations[n]; | 1240 | p=mpu401_synth_operations[n]; |
1241 | sound_unload_mididev(n); | 1241 | sound_unload_mididev(n); |
1242 | sound_unload_timerdev(hw_config->slots[2]); | 1242 | sound_unload_timerdev(hw_config->slots[2]); |
1243 | if(p) | 1243 | kfree(p); |
1244 | kfree(p); | ||
1245 | } | 1244 | } |
1246 | } | 1245 | } |
1247 | 1246 | ||
diff --git a/sound/oss/nm256.h b/sound/oss/nm256.h index eae7d99d6826..21e07b5081f2 100644 --- a/sound/oss/nm256.h +++ b/sound/oss/nm256.h | |||
@@ -128,9 +128,6 @@ struct nm256_info | |||
128 | struct nm256_info *next_card; | 128 | struct nm256_info *next_card; |
129 | }; | 129 | }; |
130 | 130 | ||
131 | /* Debug flag--bigger numbers mean more output. */ | ||
132 | extern int nm256_debug; | ||
133 | |||
134 | /* The BIOS signature. */ | 131 | /* The BIOS signature. */ |
135 | #define NM_SIGNATURE 0x4e4d0000 | 132 | #define NM_SIGNATURE 0x4e4d0000 |
136 | /* Signature mask. */ | 133 | /* Signature mask. */ |
@@ -284,7 +281,7 @@ nm256_readBuffer8 (struct nm256_info *card, u8 *dst, int port, int offset, | |||
284 | } | 281 | } |
285 | 282 | ||
286 | /* Returns a non-zero value if we should use the coefficient cache. */ | 283 | /* Returns a non-zero value if we should use the coefficient cache. */ |
287 | extern int nm256_cachedCoefficients (struct nm256_info *card); | 284 | static int nm256_cachedCoefficients (struct nm256_info *card); |
288 | 285 | ||
289 | #endif | 286 | #endif |
290 | 287 | ||
diff --git a/sound/oss/nm256_audio.c b/sound/oss/nm256_audio.c index f9166e135192..66970062eb36 100644 --- a/sound/oss/nm256_audio.c +++ b/sound/oss/nm256_audio.c | |||
@@ -28,12 +28,13 @@ | |||
28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
29 | #include <linux/spinlock.h> | 29 | #include <linux/spinlock.h> |
30 | #include "sound_config.h" | 30 | #include "sound_config.h" |
31 | #include "nm256.h" | ||
32 | #include "nm256_coeff.h" | ||
33 | 31 | ||
34 | int nm256_debug; | 32 | static int nm256_debug; |
35 | static int force_load; | 33 | static int force_load; |
36 | 34 | ||
35 | #include "nm256.h" | ||
36 | #include "nm256_coeff.h" | ||
37 | |||
37 | /* | 38 | /* |
38 | * The size of the playback reserve. When the playback buffer has less | 39 | * The size of the playback reserve. When the playback buffer has less |
39 | * than NM256_PLAY_WMARK_SIZE bytes to output, we request a new | 40 | * than NM256_PLAY_WMARK_SIZE bytes to output, we request a new |
@@ -138,7 +139,7 @@ static int usecache; | |||
138 | static int buffertop; | 139 | static int buffertop; |
139 | 140 | ||
140 | /* Check to see if we're using the bank of cached coefficients. */ | 141 | /* Check to see if we're using the bank of cached coefficients. */ |
141 | int | 142 | static int |
142 | nm256_cachedCoefficients (struct nm256_info *card) | 143 | nm256_cachedCoefficients (struct nm256_info *card) |
143 | { | 144 | { |
144 | return usecache; | 145 | return usecache; |
diff --git a/sound/oss/nm256_coeff.h b/sound/oss/nm256_coeff.h index 0ceecc20077b..6fc07f3cb33b 100644 --- a/sound/oss/nm256_coeff.h +++ b/sound/oss/nm256_coeff.h | |||
@@ -4650,7 +4650,7 @@ nm256_loadAllCoefficients (struct nm256_info *card) | |||
4650 | card->coeffsCurrent = 1; | 4650 | card->coeffsCurrent = 1; |
4651 | } | 4651 | } |
4652 | 4652 | ||
4653 | void | 4653 | static void |
4654 | nm256_loadCoefficient (struct nm256_info *card, int which, int number) | 4654 | nm256_loadCoefficient (struct nm256_info *card, int which, int number) |
4655 | { | 4655 | { |
4656 | static u16 addrs[3] = { 0x1c, 0x21c, 0x408 }; | 4656 | static u16 addrs[3] = { 0x1c, 0x21c, 0x408 }; |
diff --git a/sound/oss/rme96xx.c b/sound/oss/rme96xx.c index b4278eecc917..7609c68a89f4 100644 --- a/sound/oss/rme96xx.c +++ b/sound/oss/rme96xx.c | |||
@@ -1750,9 +1750,7 @@ static unsigned int rme96xx_poll(struct file *file, struct poll_table_struct *wa | |||
1750 | 1750 | ||
1751 | 1751 | ||
1752 | static struct file_operations rme96xx_audio_fops = { | 1752 | static struct file_operations rme96xx_audio_fops = { |
1753 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) | ||
1754 | .owner = THIS_MODULE, | 1753 | .owner = THIS_MODULE, |
1755 | #endif | ||
1756 | .read = rme96xx_read, | 1754 | .read = rme96xx_read, |
1757 | .write = rme96xx_write, | 1755 | .write = rme96xx_write, |
1758 | .poll = rme96xx_poll, | 1756 | .poll = rme96xx_poll, |
@@ -1852,9 +1850,7 @@ static int rme96xx_mixer_release(struct inode *inode, struct file *file) | |||
1852 | } | 1850 | } |
1853 | 1851 | ||
1854 | static /*const*/ struct file_operations rme96xx_mixer_fops = { | 1852 | static /*const*/ struct file_operations rme96xx_mixer_fops = { |
1855 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) | ||
1856 | .owner = THIS_MODULE, | 1853 | .owner = THIS_MODULE, |
1857 | #endif | ||
1858 | .ioctl = rme96xx_mixer_ioctl, | 1854 | .ioctl = rme96xx_mixer_ioctl, |
1859 | .open = rme96xx_mixer_open, | 1855 | .open = rme96xx_mixer_open, |
1860 | .release = rme96xx_mixer_release, | 1856 | .release = rme96xx_mixer_release, |
diff --git a/sound/oss/sb_common.c b/sound/oss/sb_common.c index ce359e6c933a..5f955e3d2e26 100644 --- a/sound/oss/sb_common.c +++ b/sound/oss/sb_common.c | |||
@@ -915,8 +915,8 @@ void sb_dsp_unload(struct address_info *hw_config, int sbmpu) | |||
915 | } | 915 | } |
916 | else | 916 | else |
917 | release_region(hw_config->io_base, 16); | 917 | release_region(hw_config->io_base, 16); |
918 | if(detected_devc) | 918 | |
919 | kfree(detected_devc); | 919 | kfree(detected_devc); |
920 | } | 920 | } |
921 | 921 | ||
922 | /* | 922 | /* |
diff --git a/sound/oss/sscape.c b/sound/oss/sscape.c index 50ca64629450..9ed5211c3168 100644 --- a/sound/oss/sscape.c +++ b/sound/oss/sscape.c | |||
@@ -991,7 +991,6 @@ static void __init sscape_pnp_init_hw(sscape_info* devc) | |||
991 | unsigned i; | 991 | unsigned i; |
992 | static char code_file_name[23] = "/sndscape/sndscape.cox"; | 992 | static char code_file_name[23] = "/sndscape/sndscape.cox"; |
993 | 993 | ||
994 | int sscape_sb_enable = 0; | ||
995 | int sscape_joystic_enable = 0x7f; | 994 | int sscape_joystic_enable = 0x7f; |
996 | int sscape_mic_enable = 0; | 995 | int sscape_mic_enable = 0; |
997 | int sscape_ext_midi = 0; | 996 | int sscape_ext_midi = 0; |
@@ -1015,14 +1014,9 @@ static void __init sscape_pnp_init_hw(sscape_info* devc) | |||
1015 | sscape_write( devc, 2, devc->ic_type == IC_ODIE ? 0x70 : 0x40); | 1014 | sscape_write( devc, 2, devc->ic_type == IC_ODIE ? 0x70 : 0x40); |
1016 | sscape_write( devc, 3, ( devc -> dma << 4) | 0x80); | 1015 | sscape_write( devc, 3, ( devc -> dma << 4) | 0x80); |
1017 | 1016 | ||
1018 | if ( sscape_sb_enable ) | 1017 | sscape_write (devc, 4, 0xF0 | (midi_irq<<2) | midi_irq); |
1019 | sscape_write (devc, 4, 0xF0 | (sb_irq << 2) | midi_irq); | ||
1020 | else | ||
1021 | sscape_write (devc, 4, 0xF0 | (midi_irq<<2) | midi_irq); | ||
1022 | 1018 | ||
1023 | i = 0x10; //sscape_read(devc, 9) & (devc->ic_type == IC_ODIE ? 0xf0 : 0xc0); | 1019 | i = 0x10; //sscape_read(devc, 9) & (devc->ic_type == IC_ODIE ? 0xf0 : 0xc0); |
1024 | if ( sscape_sb_enable ) | ||
1025 | i |= devc->ic_type == IC_ODIE ? 0x05 : 0x07; | ||
1026 | if (sscape_joystic_enable) i |= 8; | 1020 | if (sscape_joystic_enable) i |= 8; |
1027 | 1021 | ||
1028 | sscape_write (devc, 9, i); | 1022 | sscape_write (devc, 9, i); |
diff --git a/sound/oss/v_midi.c b/sound/oss/v_midi.c index 077b76797665..a7ef04fab075 100644 --- a/sound/oss/v_midi.c +++ b/sound/oss/v_midi.c | |||
@@ -39,8 +39,6 @@ static void *midi_mem = NULL; | |||
39 | */ | 39 | */ |
40 | 40 | ||
41 | 41 | ||
42 | void (*midi_input_intr) (int dev, unsigned char data); | ||
43 | |||
44 | static int v_midi_open (int dev, int mode, | 42 | static int v_midi_open (int dev, int mode, |
45 | void (*input) (int dev, unsigned char data), | 43 | void (*input) (int dev, unsigned char data), |
46 | void (*output) (int dev) | 44 | void (*output) (int dev) |
diff --git a/sound/oss/wavfront.c b/sound/oss/wavfront.c index cce1278dc487..b92ba8921638 100644 --- a/sound/oss/wavfront.c +++ b/sound/oss/wavfront.c | |||
@@ -151,11 +151,11 @@ static int (*midi_load_patch) (int devno, int format, const char __user *addr, | |||
151 | 151 | ||
152 | /*** Module-accessible parameters ***************************************/ | 152 | /*** Module-accessible parameters ***************************************/ |
153 | 153 | ||
154 | int wf_raw; /* we normally check for "raw state" to firmware | 154 | static int wf_raw; /* we normally check for "raw state" to firmware |
155 | loading. if set, then during driver loading, the | 155 | loading. if set, then during driver loading, the |
156 | state of the board is ignored, and we reset the | 156 | state of the board is ignored, and we reset the |
157 | board and load the firmware anyway. | 157 | board and load the firmware anyway. |
158 | */ | 158 | */ |
159 | 159 | ||
160 | static int fx_raw = 1; /* if this is zero, we'll leave the FX processor in | 160 | static int fx_raw = 1; /* if this is zero, we'll leave the FX processor in |
161 | whatever state it is when the driver is loaded. | 161 | whatever state it is when the driver is loaded. |
@@ -2911,7 +2911,7 @@ int __init detect_wffx (void) | |||
2911 | return 0; | 2911 | return 0; |
2912 | } | 2912 | } |
2913 | 2913 | ||
2914 | void | 2914 | static void |
2915 | wffx_mute (int onoff) | 2915 | wffx_mute (int onoff) |
2916 | 2916 | ||
2917 | { | 2917 | { |