diff options
303 files changed, 8190 insertions, 4837 deletions
@@ -951,6 +951,12 @@ S: Brevia 1043 | |||
951 | S: S-114 79 Stockholm | 951 | S: S-114 79 Stockholm |
952 | S: Sweden | 952 | S: Sweden |
953 | 953 | ||
954 | N: Pekka Enberg | ||
955 | E: penberg@cs.helsinki.fi | ||
956 | W: http://www.cs.helsinki.fi/u/penberg/ | ||
957 | D: Various kernel hacks, fixes, and cleanups. | ||
958 | S: Finland | ||
959 | |||
954 | N: David Engebretsen | 960 | N: David Engebretsen |
955 | E: engebret@us.ibm.com | 961 | E: engebret@us.ibm.com |
956 | D: Linux port to 64-bit PowerPC architecture | 962 | D: Linux port to 64-bit PowerPC architecture |
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl index 6d4b1ef5b6f1..49c745720f47 100644 --- a/Documentation/DocBook/kernel-api.tmpl +++ b/Documentation/DocBook/kernel-api.tmpl | |||
@@ -325,8 +325,13 @@ X!Ekernel/module.c | |||
325 | !Ekernel/irq/manage.c | 325 | !Ekernel/irq/manage.c |
326 | </sect1> | 326 | </sect1> |
327 | 327 | ||
328 | <sect1><title>DMA Channels</title> | ||
329 | !Ekernel/dma.c | ||
330 | </sect1> | ||
331 | |||
328 | <sect1><title>Resources Management</title> | 332 | <sect1><title>Resources Management</title> |
329 | !Ikernel/resource.c | 333 | !Ikernel/resource.c |
334 | !Ekernel/resource.c | ||
330 | </sect1> | 335 | </sect1> |
331 | 336 | ||
332 | <sect1><title>MTRR Handling</title> | 337 | <sect1><title>MTRR Handling</title> |
diff --git a/Documentation/IPMI.txt b/Documentation/IPMI.txt index 7756e09ea759..9f08d73d90bf 100644 --- a/Documentation/IPMI.txt +++ b/Documentation/IPMI.txt | |||
@@ -364,6 +364,7 @@ You can change this at module load time (for a module) with: | |||
364 | regspacings=<sp1>,<sp2>,... regsizes=<size1>,<size2>,... | 364 | regspacings=<sp1>,<sp2>,... regsizes=<size1>,<size2>,... |
365 | regshifts=<shift1>,<shift2>,... | 365 | regshifts=<shift1>,<shift2>,... |
366 | slave_addrs=<addr1>,<addr2>,... | 366 | slave_addrs=<addr1>,<addr2>,... |
367 | force_kipmid=<enable1>,<enable2>,... | ||
367 | 368 | ||
368 | Each of these except si_trydefaults is a list, the first item for the | 369 | Each of these except si_trydefaults is a list, the first item for the |
369 | first interface, second item for the second interface, etc. | 370 | first interface, second item for the second interface, etc. |
@@ -409,7 +410,13 @@ The slave_addrs specifies the IPMI address of the local BMC. This is | |||
409 | usually 0x20 and the driver defaults to that, but in case it's not, it | 410 | usually 0x20 and the driver defaults to that, but in case it's not, it |
410 | can be specified when the driver starts up. | 411 | can be specified when the driver starts up. |
411 | 412 | ||
412 | When compiled into the kernel, the addresses can be specified on the | 413 | The force_ipmid parameter forcefully enables (if set to 1) or disables |
414 | (if set to 0) the kernel IPMI daemon. Normally this is auto-detected | ||
415 | by the driver, but systems with broken interrupts might need an enable, | ||
416 | or users that don't want the daemon (don't need the performance, don't | ||
417 | want the CPU hit) can disable it. | ||
418 | |||
419 | When compiled into the kernel, the parameters can be specified on the | ||
413 | kernel command line as: | 420 | kernel command line as: |
414 | 421 | ||
415 | ipmi_si.type=<type1>,<type2>... | 422 | ipmi_si.type=<type1>,<type2>... |
@@ -419,6 +426,7 @@ kernel command line as: | |||
419 | ipmi_si.regsizes=<size1>,<size2>,... | 426 | ipmi_si.regsizes=<size1>,<size2>,... |
420 | ipmi_si.regshifts=<shift1>,<shift2>,... | 427 | ipmi_si.regshifts=<shift1>,<shift2>,... |
421 | ipmi_si.slave_addrs=<addr1>,<addr2>,... | 428 | ipmi_si.slave_addrs=<addr1>,<addr2>,... |
429 | ipmi_si.force_kipmid=<enable1>,<enable2>,... | ||
422 | 430 | ||
423 | It works the same as the module parameters of the same names. | 431 | It works the same as the module parameters of the same names. |
424 | 432 | ||
diff --git a/Documentation/fb/intel810.txt b/Documentation/fb/intel810.txt index 4f0d6bc789ef..be3e7836abef 100644 --- a/Documentation/fb/intel810.txt +++ b/Documentation/fb/intel810.txt | |||
@@ -9,8 +9,9 @@ Intel 810/815 Framebuffer driver | |||
9 | ================================================================ | 9 | ================================================================ |
10 | 10 | ||
11 | A. Introduction | 11 | A. Introduction |
12 | |||
12 | This is a framebuffer driver for various Intel 810/815 compatible | 13 | This is a framebuffer driver for various Intel 810/815 compatible |
13 | graphics devices. These would include: | 14 | graphics devices. These include: |
14 | 15 | ||
15 | Intel 810 | 16 | Intel 810 |
16 | Intel 810E | 17 | Intel 810E |
@@ -21,136 +22,136 @@ graphics devices. These would include: | |||
21 | 22 | ||
22 | B. Features | 23 | B. Features |
23 | 24 | ||
24 | - Choice of using Discrete Video Timings, VESA Generalized Timing | 25 | - Choice of using Discrete Video Timings, VESA Generalized Timing |
25 | Formula, or a framebuffer specific database to set the video mode | 26 | Formula, or a framebuffer specific database to set the video mode |
26 | 27 | ||
27 | - Supports a variable range of horizontal and vertical resolution, and | 28 | - Supports a variable range of horizontal and vertical resolution and |
28 | vertical refresh rates if the VESA Generalized Timing Formula is | 29 | vertical refresh rates if the VESA Generalized Timing Formula is |
29 | enabled. | 30 | enabled. |
30 | 31 | ||
31 | - Supports color depths of 8, 16, 24 and 32 bits per pixel | 32 | - Supports color depths of 8, 16, 24 and 32 bits per pixel |
32 | 33 | ||
33 | - Supports pseudocolor, directcolor, or truecolor visuals | 34 | - Supports pseudocolor, directcolor, or truecolor visuals |
34 | 35 | ||
35 | - Full and optimized hardware acceleration at 8, 16 and 24 bpp | 36 | - Full and optimized hardware acceleration at 8, 16 and 24 bpp |
36 | 37 | ||
37 | - Robust video state save and restore | 38 | - Robust video state save and restore |
38 | 39 | ||
39 | - MTRR support | 40 | - MTRR support |
40 | 41 | ||
41 | - Utilizes user-entered monitor specifications to automatically | 42 | - Utilizes user-entered monitor specifications to automatically |
42 | calculate required video mode parameters. | 43 | calculate required video mode parameters. |
43 | 44 | ||
44 | - Can concurrently run with xfree86 running with native i810 drivers | 45 | - Can concurrently run with xfree86 running with native i810 drivers |
45 | 46 | ||
46 | - Hardware Cursor Support | 47 | - Hardware Cursor Support |
47 | 48 | ||
48 | - Supports EDID probing either by DDC/I2C or through the BIOS | 49 | - Supports EDID probing either by DDC/I2C or through the BIOS |
49 | 50 | ||
50 | C. List of available options | 51 | C. List of available options |
51 | 52 | ||
52 | a. "video=i810fb" | 53 | a. "video=i810fb" |
53 | enables the i810 driver | 54 | enables the i810 driver |
54 | 55 | ||
55 | Recommendation: required | 56 | Recommendation: required |
56 | 57 | ||
57 | b. "xres:<value>" | 58 | b. "xres:<value>" |
58 | select horizontal resolution in pixels. (This parameter will be | 59 | select horizontal resolution in pixels. (This parameter will be |
59 | ignored if 'mode_option' is specified. See 'o' below). | 60 | ignored if 'mode_option' is specified. See 'o' below). |
60 | 61 | ||
61 | Recommendation: user preference | 62 | Recommendation: user preference |
62 | (default = 640) | 63 | (default = 640) |
63 | 64 | ||
64 | c. "yres:<value>" | 65 | c. "yres:<value>" |
65 | select vertical resolution in scanlines. If Discrete Video Timings | 66 | select vertical resolution in scanlines. If Discrete Video Timings |
66 | is enabled, this will be ignored and computed as 3*xres/4. (This | 67 | is enabled, this will be ignored and computed as 3*xres/4. (This |
67 | parameter will be ignored if 'mode_option' is specified. See 'o' | 68 | parameter will be ignored if 'mode_option' is specified. See 'o' |
68 | below) | 69 | below) |
69 | 70 | ||
70 | Recommendation: user preference | 71 | Recommendation: user preference |
71 | (default = 480) | 72 | (default = 480) |
72 | 73 | ||
73 | d. "vyres:<value>" | 74 | d. "vyres:<value>" |
74 | select virtual vertical resolution in scanlines. If (0) or none | 75 | select virtual vertical resolution in scanlines. If (0) or none |
75 | is specified, this will be computed against maximum available memory. | 76 | is specified, this will be computed against maximum available memory. |
76 | 77 | ||
77 | Recommendation: do not set | 78 | Recommendation: do not set |
78 | (default = 480) | 79 | (default = 480) |
79 | 80 | ||
80 | e. "vram:<value>" | 81 | e. "vram:<value>" |
81 | select amount of system RAM in MB to allocate for the video memory | 82 | select amount of system RAM in MB to allocate for the video memory |
82 | 83 | ||
83 | Recommendation: 1 - 4 MB. | 84 | Recommendation: 1 - 4 MB. |
84 | (default = 4) | 85 | (default = 4) |
85 | 86 | ||
86 | f. "bpp:<value>" | 87 | f. "bpp:<value>" |
87 | select desired pixel depth | 88 | select desired pixel depth |
88 | 89 | ||
89 | Recommendation: 8 | 90 | Recommendation: 8 |
90 | (default = 8) | 91 | (default = 8) |
91 | 92 | ||
92 | g. "hsync1/hsync2:<value>" | 93 | g. "hsync1/hsync2:<value>" |
93 | select the minimum and maximum Horizontal Sync Frequency of the | 94 | select the minimum and maximum Horizontal Sync Frequency of the |
94 | monitor in KHz. If a using a fixed frequency monitor, hsync1 must | 95 | monitor in kHz. If using a fixed frequency monitor, hsync1 must |
95 | be equal to hsync2. If EDID probing is successful, these will be | 96 | be equal to hsync2. If EDID probing is successful, these will be |
96 | ignored and values will be taken from the EDID block. | 97 | ignored and values will be taken from the EDID block. |
97 | 98 | ||
98 | Recommendation: check monitor manual for correct values | 99 | Recommendation: check monitor manual for correct values |
99 | default (29/30) | 100 | (default = 29/30) |
100 | 101 | ||
101 | h. "vsync1/vsync2:<value>" | 102 | h. "vsync1/vsync2:<value>" |
102 | select the minimum and maximum Vertical Sync Frequency of the monitor | 103 | select the minimum and maximum Vertical Sync Frequency of the monitor |
103 | in Hz. You can also use this option to lock your monitor's refresh | 104 | in Hz. You can also use this option to lock your monitor's refresh |
104 | rate. If EDID probing is successful, these will be ignored and values | 105 | rate. If EDID probing is successful, these will be ignored and values |
105 | will be taken from the EDID block. | 106 | will be taken from the EDID block. |
106 | 107 | ||
107 | Recommendation: check monitor manual for correct values | 108 | Recommendation: check monitor manual for correct values |
108 | (default = 60/60) | 109 | (default = 60/60) |
109 | 110 | ||
110 | IMPORTANT: If you need to clamp your timings, try to give some | 111 | IMPORTANT: If you need to clamp your timings, try to give some |
111 | leeway for computational errors (over/underflows). Example: if | 112 | leeway for computational errors (over/underflows). Example: if |
112 | using vsync1/vsync2 = 60/60, make sure hsync1/hsync2 has at least | 113 | using vsync1/vsync2 = 60/60, make sure hsync1/hsync2 has at least |
113 | a 1 unit difference, and vice versa. | 114 | a 1 unit difference, and vice versa. |
114 | 115 | ||
115 | i. "voffset:<value>" | 116 | i. "voffset:<value>" |
116 | select at what offset in MB of the logical memory to allocate the | 117 | select at what offset in MB of the logical memory to allocate the |
117 | framebuffer memory. The intent is to avoid the memory blocks | 118 | framebuffer memory. The intent is to avoid the memory blocks |
118 | used by standard graphics applications (XFree86). The default | 119 | used by standard graphics applications (XFree86). The default |
119 | offset (16 MB for a 64MB aperture, 8 MB for a 32MB aperture) will | 120 | offset (16 MB for a 64 MB aperture, 8 MB for a 32 MB aperture) will |
120 | avoid XFree86's usage and allows up to 7MB/15MB of framebuffer | 121 | avoid XFree86's usage and allows up to 7 MB/15 MB of framebuffer |
121 | memory. Depending on your usage, adjust the value up or down, | 122 | memory. Depending on your usage, adjust the value up or down |
122 | (0 for maximum usage, 31/63 MB for the least amount). Note, an | 123 | (0 for maximum usage, 31/63 MB for the least amount). Note, an |
123 | arbitrary setting may conflict with XFree86. | 124 | arbitrary setting may conflict with XFree86. |
124 | 125 | ||
125 | Recommendation: do not set | 126 | Recommendation: do not set |
126 | (default = 8 or 16 MB) | 127 | (default = 8 or 16 MB) |
127 | 128 | ||
128 | j. "accel" | 129 | j. "accel" |
129 | enable text acceleration. This can be enabled/reenabled anytime | 130 | enable text acceleration. This can be enabled/reenabled anytime |
130 | by using 'fbset -accel true/false'. | 131 | by using 'fbset -accel true/false'. |
131 | 132 | ||
132 | Recommendation: enable | 133 | Recommendation: enable |
133 | (default = not set) | 134 | (default = not set) |
134 | 135 | ||
135 | k. "mtrr" | 136 | k. "mtrr" |
136 | enable MTRR. This allows data transfers to the framebuffer memory | 137 | enable MTRR. This allows data transfers to the framebuffer memory |
137 | to occur in bursts which can significantly increase performance. | 138 | to occur in bursts which can significantly increase performance. |
138 | Not very helpful with the i810/i815 because of 'shared memory'. | 139 | Not very helpful with the i810/i815 because of 'shared memory'. |
139 | 140 | ||
140 | Recommendation: do not set | 141 | Recommendation: do not set |
141 | (default = not set) | 142 | (default = not set) |
142 | 143 | ||
143 | l. "extvga" | 144 | l. "extvga" |
144 | if specified, secondary/external VGA output will always be enabled. | 145 | if specified, secondary/external VGA output will always be enabled. |
145 | Useful if the BIOS turns off the VGA port when no monitor is attached. | 146 | Useful if the BIOS turns off the VGA port when no monitor is attached. |
146 | The external VGA monitor can then be attached without rebooting. | 147 | The external VGA monitor can then be attached without rebooting. |
147 | 148 | ||
148 | Recommendation: do not set | 149 | Recommendation: do not set |
149 | (default = not set) | 150 | (default = not set) |
150 | 151 | ||
151 | m. "sync" | 152 | m. "sync" |
152 | Forces the hardware engine to do a "sync" or wait for the hardware | 153 | Forces the hardware engine to do a "sync" or wait for the hardware |
153 | to finish before starting another instruction. This will produce a | 154 | to finish before starting another instruction. This will produce a |
154 | more stable setup, but will be slower. | 155 | more stable setup, but will be slower. |
155 | 156 | ||
156 | Recommendation: do not set | 157 | Recommendation: do not set |
@@ -162,6 +163,7 @@ C. List of available options | |||
162 | 163 | ||
163 | Recommendation: do not set | 164 | Recommendation: do not set |
164 | (default = not set) | 165 | (default = not set) |
166 | |||
165 | o. <xres>x<yres>[-<bpp>][@<refresh>] | 167 | o. <xres>x<yres>[-<bpp>][@<refresh>] |
166 | The driver will now accept specification of boot mode option. If this | 168 | The driver will now accept specification of boot mode option. If this |
167 | is specified, the options 'xres' and 'yres' will be ignored. See | 169 | is specified, the options 'xres' and 'yres' will be ignored. See |
@@ -183,8 +185,8 @@ append="video=i810fb:vram:2,xres:1024,yres:768,bpp:8,hsync1:30,hsync2:55, \ | |||
183 | vsync1:50,vsync2:85,accel,mtrr" | 185 | vsync1:50,vsync2:85,accel,mtrr" |
184 | 186 | ||
185 | This will initialize the framebuffer to 1024x768 at 8bpp. The framebuffer | 187 | This will initialize the framebuffer to 1024x768 at 8bpp. The framebuffer |
186 | will use 2 MB of System RAM. MTRR support will be enabled. The refresh rate | 188 | will use 2 MB of System RAM. MTRR support will be enabled. The refresh rate |
187 | will be computed based on the hsync1/hsync2 and vsync1/vsync2 values. | 189 | will be computed based on the hsync1/hsync2 and vsync1/vsync2 values. |
188 | 190 | ||
189 | IMPORTANT: | 191 | IMPORTANT: |
190 | You must include hsync1, hsync2, vsync1 and vsync2 to enable video modes | 192 | You must include hsync1, hsync2, vsync1 and vsync2 to enable video modes |
@@ -194,10 +196,10 @@ vsync1 and vsync2 parameters. These parameters will be taken from the EDID | |||
194 | block. | 196 | block. |
195 | 197 | ||
196 | E. Module options | 198 | E. Module options |
197 | 199 | ||
198 | The module parameters are essentially similar to the kernel | 200 | The module parameters are essentially similar to the kernel |
199 | parameters. The main difference is that you need to include a Boolean value | 201 | parameters. The main difference is that you need to include a Boolean value |
200 | (1 for TRUE, and 0 for FALSE) for those options which don't need a value. | 202 | (1 for TRUE, and 0 for FALSE) for those options which don't need a value. |
201 | 203 | ||
202 | Example, to enable MTRR, include "mtrr=1". | 204 | Example, to enable MTRR, include "mtrr=1". |
203 | 205 | ||
@@ -214,62 +216,62 @@ Or just add the following to /etc/modprobe.conf | |||
214 | options i810fb vram=2 xres=1024 bpp=16 hsync1=30 hsync2=55 vsync1=50 \ | 216 | options i810fb vram=2 xres=1024 bpp=16 hsync1=30 hsync2=55 vsync1=50 \ |
215 | vsync2=85 accel=1 mtrr=1 | 217 | vsync2=85 accel=1 mtrr=1 |
216 | 218 | ||
217 | and just do a | 219 | and just do a |
218 | 220 | ||
219 | modprobe i810fb | 221 | modprobe i810fb |
220 | 222 | ||
221 | 223 | ||
222 | F. Setup | 224 | F. Setup |
223 | 225 | ||
224 | a. Do your usual method of configuring the kernel. | 226 | a. Do your usual method of configuring the kernel. |
225 | 227 | ||
226 | make menuconfig/xconfig/config | 228 | make menuconfig/xconfig/config |
227 | 229 | ||
228 | b. Under "Code Maturity Options", enable "Prompt for experimental/ | 230 | b. Under "Code maturity level options" enable "Prompt for development |
229 | incomplete code/drivers". | 231 | and/or incomplete code/drivers". |
230 | 232 | ||
231 | c. Enable agpgart support for the Intel 810/815 on-board graphics. | 233 | c. Enable agpgart support for the Intel 810/815 on-board graphics. |
232 | This is required. The option is under "Character Devices" | 234 | This is required. The option is under "Character Devices". |
233 | 235 | ||
234 | d. Under "Graphics Support", select "Intel 810/815" either statically | 236 | d. Under "Graphics Support", select "Intel 810/815" either statically |
235 | or as a module. Choose "use VESA Generalized Timing Formula" if | 237 | or as a module. Choose "use VESA Generalized Timing Formula" if |
236 | you need to maximize the capability of your display. To be on the | 238 | you need to maximize the capability of your display. To be on the |
237 | safe side, you can leave this unselected. | 239 | safe side, you can leave this unselected. |
238 | 240 | ||
239 | e. If you want support for DDC/I2C probing (Plug and Play Displays), | 241 | e. If you want support for DDC/I2C probing (Plug and Play Displays), |
240 | set 'Enable DDC Support' to 'y'. To make this option appear, set | 242 | set 'Enable DDC Support' to 'y'. To make this option appear, set |
241 | 'use VESA Generalized Timing Formula' to 'y'. | 243 | 'use VESA Generalized Timing Formula' to 'y'. |
242 | 244 | ||
243 | f. If you want a framebuffer console, enable it under "Console | 245 | f. If you want a framebuffer console, enable it under "Console |
244 | Drivers" | 246 | Drivers". |
247 | |||
248 | g. Compile your kernel. | ||
249 | |||
250 | h. Load the driver as described in sections D and E. | ||
245 | 251 | ||
246 | g. Compile your kernel. | ||
247 | |||
248 | h. Load the driver as described in section D and E. | ||
249 | |||
250 | i. Try the DirectFB (http://www.directfb.org) + the i810 gfxdriver | 252 | i. Try the DirectFB (http://www.directfb.org) + the i810 gfxdriver |
251 | patch to see the chipset in action (or inaction :-). | 253 | patch to see the chipset in action (or inaction :-). |
252 | 254 | ||
253 | G. Acknowledgment: | 255 | G. Acknowledgment: |
254 | 256 | ||
255 | 1. Geert Uytterhoeven - his excellent howto and the virtual | 257 | 1. Geert Uytterhoeven - his excellent howto and the virtual |
256 | framebuffer driver code made this possible. | 258 | framebuffer driver code made this possible. |
257 | 259 | ||
258 | 2. Jeff Hartmann for his agpgart code. | 260 | 2. Jeff Hartmann for his agpgart code. |
259 | 261 | ||
260 | 3. The X developers. Insights were provided just by reading the | 262 | 3. The X developers. Insights were provided just by reading the |
261 | XFree86 source code. | 263 | XFree86 source code. |
262 | 264 | ||
263 | 4. Intel(c). For this value-oriented chipset driver and for | 265 | 4. Intel(c). For this value-oriented chipset driver and for |
264 | providing documentation. | 266 | providing documentation. |
265 | 267 | ||
266 | 5. Matt Sottek. His inputs and ideas helped in making some | 268 | 5. Matt Sottek. His inputs and ideas helped in making some |
267 | optimizations possible. | 269 | optimizations possible. |
268 | 270 | ||
269 | H. Home Page: | 271 | H. Home Page: |
270 | 272 | ||
271 | A more complete, and probably updated information is provided at | 273 | A more complete, and probably updated information is provided at |
272 | http://i810fb.sourceforge.net. | 274 | http://i810fb.sourceforge.net. |
273 | 275 | ||
274 | ########################### | 276 | ########################### |
275 | Tony | 277 | Tony |
diff --git a/Documentation/fb/intelfb.txt b/Documentation/fb/intelfb.txt index aa0d322db171..da5ee74219e8 100644 --- a/Documentation/fb/intelfb.txt +++ b/Documentation/fb/intelfb.txt | |||
@@ -88,12 +88,20 @@ Sample Usage | |||
88 | 88 | ||
89 | In /etc/lilo.conf, add the line: | 89 | In /etc/lilo.conf, add the line: |
90 | 90 | ||
91 | append="video=intelfb:800x600-32@75,accel,hwcursor,vram=8" | 91 | append="video=intelfb:mode=800x600-32@75,accel,hwcursor,vram=8" |
92 | 92 | ||
93 | This will initialize the framebuffer to 800x600 at 32bpp and 75Hz. The | 93 | This will initialize the framebuffer to 800x600 at 32bpp and 75Hz. The |
94 | framebuffer will use 8 MB of System RAM. hw acceleration of text and cursor | 94 | framebuffer will use 8 MB of System RAM. hw acceleration of text and cursor |
95 | will be enabled. | 95 | will be enabled. |
96 | 96 | ||
97 | Remarks | ||
98 | ------- | ||
99 | |||
100 | If setting this parameter doesn't work (you stay in a 80x25 text-mode), | ||
101 | you might need to set the "vga=<mode>" parameter too - see vesafb.txt | ||
102 | in this directory. | ||
103 | |||
104 | |||
97 | D. Module options | 105 | D. Module options |
98 | 106 | ||
99 | The module parameters are essentially similar to the kernel | 107 | The module parameters are essentially similar to the kernel |
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 9364f47c7116..b98f01fc14bf 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -122,15 +122,6 @@ Who: Arjan van de Ven | |||
122 | 122 | ||
123 | --------------------------- | 123 | --------------------------- |
124 | 124 | ||
125 | What: START_ARRAY ioctl for md | ||
126 | When: July 2006 | ||
127 | Files: drivers/md/md.c | ||
128 | Why: Not reliable by design - can fail when most needed. | ||
129 | Alternatives exist | ||
130 | Who: NeilBrown <neilb@suse.de> | ||
131 | |||
132 | --------------------------- | ||
133 | |||
134 | What: eepro100 network driver | 125 | What: eepro100 network driver |
135 | When: January 2007 | 126 | When: January 2007 |
136 | Why: replaced by the e100 driver | 127 | Why: replaced by the e100 driver |
@@ -325,3 +316,11 @@ Why: i2c-isa is a non-sense and doesn't fit in the device driver | |||
325 | Who: Jean Delvare <khali@linux-fr.org> | 316 | Who: Jean Delvare <khali@linux-fr.org> |
326 | 317 | ||
327 | --------------------------- | 318 | --------------------------- |
319 | |||
320 | What: ftape | ||
321 | When: 2.6.20 | ||
322 | Why: Orphaned for ages. SMP bugs long unfixed. Few users left | ||
323 | in the world. | ||
324 | Who: Jeff Garzik <jeff@garzik.org> | ||
325 | |||
326 | --------------------------- | ||
diff --git a/Documentation/ia64/serial.txt b/Documentation/ia64/serial.txt index f51eb4bc2ff1..040b9773209f 100644 --- a/Documentation/ia64/serial.txt +++ b/Documentation/ia64/serial.txt | |||
@@ -124,6 +124,13 @@ TROUBLESHOOTING SERIAL CONSOLE PROBLEMS | |||
124 | 124 | ||
125 | - Add entry to /etc/securetty for console tty. | 125 | - Add entry to /etc/securetty for console tty. |
126 | 126 | ||
127 | No ACPI serial devices found in 2.6.17 or later: | ||
128 | |||
129 | - Turn on CONFIG_PNP and CONFIG_PNPACPI. Prior to 2.6.17, ACPI | ||
130 | serial devices were discovered by 8250_acpi. In 2.6.17, | ||
131 | 8250_acpi was replaced by the combination of 8250_pnp and | ||
132 | CONFIG_PNPACPI. | ||
133 | |||
127 | 134 | ||
128 | 135 | ||
129 | [1] http://www.dig64.org/specifications/DIG64_PCDPv20.pdf | 136 | [1] http://www.dig64.org/specifications/DIG64_PCDPv20.pdf |
diff --git a/Documentation/kbuild/modules.txt b/Documentation/kbuild/modules.txt index 2e7702e94a78..769ee05ee4d1 100644 --- a/Documentation/kbuild/modules.txt +++ b/Documentation/kbuild/modules.txt | |||
@@ -43,7 +43,7 @@ are not planned to be included in the kernel tree. | |||
43 | What is covered within this file is mainly information to authors | 43 | What is covered within this file is mainly information to authors |
44 | of modules. The author of an external module should supply | 44 | of modules. The author of an external module should supply |
45 | a makefile that hides most of the complexity, so one only has to type | 45 | a makefile that hides most of the complexity, so one only has to type |
46 | 'make' to build the module. A complete example will be present in | 46 | 'make' to build the module. A complete example will be presented in |
47 | chapter 4, "Creating a kbuild file for an external module". | 47 | chapter 4, "Creating a kbuild file for an external module". |
48 | 48 | ||
49 | 49 | ||
@@ -61,6 +61,7 @@ when building an external module. | |||
61 | make -C <path-to-kernel> M=`pwd` | 61 | make -C <path-to-kernel> M=`pwd` |
62 | 62 | ||
63 | For the running kernel use: | 63 | For the running kernel use: |
64 | |||
64 | make -C /lib/modules/`uname -r`/build M=`pwd` | 65 | make -C /lib/modules/`uname -r`/build M=`pwd` |
65 | 66 | ||
66 | For the above command to succeed, the kernel must have been | 67 | For the above command to succeed, the kernel must have been |
@@ -130,10 +131,10 @@ when building an external module. | |||
130 | 131 | ||
131 | To make sure the kernel contains the information required to | 132 | To make sure the kernel contains the information required to |
132 | build external modules the target 'modules_prepare' must be used. | 133 | build external modules the target 'modules_prepare' must be used. |
133 | 'module_prepare' exists solely as a simple way to prepare | 134 | 'modules_prepare' exists solely as a simple way to prepare |
134 | a kernel source tree for building external modules. | 135 | a kernel source tree for building external modules. |
135 | Note: modules_prepare will not build Module.symvers even if | 136 | Note: modules_prepare will not build Module.symvers even if |
136 | CONFIG_MODULEVERSIONING is set. Therefore a full kernel build | 137 | CONFIG_MODVERSIONS is set. Therefore a full kernel build |
137 | needs to be executed to make module versioning work. | 138 | needs to be executed to make module versioning work. |
138 | 139 | ||
139 | --- 2.5 Building separate files for a module | 140 | --- 2.5 Building separate files for a module |
@@ -450,7 +451,7 @@ kernel refuses to load the module. | |||
450 | 451 | ||
451 | Module.symvers contains a list of all exported symbols from a kernel build. | 452 | Module.symvers contains a list of all exported symbols from a kernel build. |
452 | 453 | ||
453 | --- 7.1 Symbols fron the kernel (vmlinux + modules) | 454 | --- 7.1 Symbols from the kernel (vmlinux + modules) |
454 | 455 | ||
455 | During a kernel build, a file named Module.symvers will be generated. | 456 | During a kernel build, a file named Module.symvers will be generated. |
456 | Module.symvers contains all exported symbols from the kernel and | 457 | Module.symvers contains all exported symbols from the kernel and |
diff --git a/Documentation/md.txt b/Documentation/md.txt index 0668f9dc9d29..9ae9e4078985 100644 --- a/Documentation/md.txt +++ b/Documentation/md.txt | |||
@@ -154,11 +154,12 @@ contains further md-specific information about the device. | |||
154 | 154 | ||
155 | All md devices contain: | 155 | All md devices contain: |
156 | level | 156 | level |
157 | a text file indicating the 'raid level'. This may be a standard | 157 | a text file indicating the 'raid level'. e.g. raid0, raid1, |
158 | numerical level prefixed by "RAID-" - e.g. "RAID-5", or some | 158 | raid5, linear, multipath, faulty. |
159 | other name such as "linear" or "multipath". | ||
160 | If no raid level has been set yet (array is still being | 159 | If no raid level has been set yet (array is still being |
161 | assembled), this file will be empty. | 160 | assembled), the value will reflect whatever has been written |
161 | to it, which may be a name like the above, or may be a number | ||
162 | such as '0', '5', etc. | ||
162 | 163 | ||
163 | raid_disks | 164 | raid_disks |
164 | a text file with a simple number indicating the number of devices | 165 | a text file with a simple number indicating the number of devices |
@@ -192,14 +193,6 @@ All md devices contain: | |||
192 | 1.2 (newer format in varying locations) or "none" indicating that | 193 | 1.2 (newer format in varying locations) or "none" indicating that |
193 | the kernel isn't managing metadata at all. | 194 | the kernel isn't managing metadata at all. |
194 | 195 | ||
195 | level | ||
196 | The raid 'level' for this array. The name will often (but not | ||
197 | always) be the same as the name of the module that implements the | ||
198 | level. To be auto-loaded the module must have an alias | ||
199 | md-$LEVEL e.g. md-raid5 | ||
200 | This can be written only while the array is being assembled, not | ||
201 | after it is started. | ||
202 | |||
203 | layout | 196 | layout |
204 | The "layout" for the array for the particular level. This is | 197 | The "layout" for the array for the particular level. This is |
205 | simply a number that is interpretted differently by different | 198 | simply a number that is interpretted differently by different |
@@ -410,6 +403,15 @@ also have | |||
410 | than sectors, this my be larger than the number of actual errors | 403 | than sectors, this my be larger than the number of actual errors |
411 | by a factor of the number of sectors in a page. | 404 | by a factor of the number of sectors in a page. |
412 | 405 | ||
406 | bitmap_set_bits | ||
407 | If the array has a write-intent bitmap, then writing to this | ||
408 | attribute can set bits in the bitmap, indicating that a resync | ||
409 | would need to check the corresponding blocks. Either individual | ||
410 | numbers or start-end pairs can be written. Multiple numbers | ||
411 | can be separated by a space. | ||
412 | Note that the numbers are 'bit' numbers, not 'block' numbers. | ||
413 | They should be scaled by the bitmap_chunksize. | ||
414 | |||
413 | Each active md device may also have attributes specific to the | 415 | Each active md device may also have attributes specific to the |
414 | personality module that manages it. | 416 | personality module that manages it. |
415 | These are specific to the implementation of the module and could | 417 | These are specific to the implementation of the module and could |
diff --git a/MAINTAINERS b/MAINTAINERS index f0cd5a3f6de6..b62ab43c6094 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -2711,14 +2711,6 @@ M: chrisw@sous-sol.org | |||
2711 | L: stable@kernel.org | 2711 | L: stable@kernel.org |
2712 | S: Maintained | 2712 | S: Maintained |
2713 | 2713 | ||
2714 | STABLE BRANCH: | ||
2715 | P: Greg Kroah-Hartman | ||
2716 | M: greg@kroah.com | ||
2717 | P: Chris Wright | ||
2718 | M: chrisw@sous-sol.org | ||
2719 | L: stable@kernel.org | ||
2720 | S: Maintained | ||
2721 | |||
2722 | TPM DEVICE DRIVER | 2714 | TPM DEVICE DRIVER |
2723 | P: Kylene Hall | 2715 | P: Kylene Hall |
2724 | M: kjhall@us.ibm.com | 2716 | M: kjhall@us.ibm.com |
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 8a31fc1bfb15..ad6173651995 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c | |||
@@ -111,22 +111,26 @@ struct osf_dirent_callback { | |||
111 | 111 | ||
112 | static int | 112 | static int |
113 | osf_filldir(void *__buf, const char *name, int namlen, loff_t offset, | 113 | osf_filldir(void *__buf, const char *name, int namlen, loff_t offset, |
114 | ino_t ino, unsigned int d_type) | 114 | u64 ino, unsigned int d_type) |
115 | { | 115 | { |
116 | struct osf_dirent __user *dirent; | 116 | struct osf_dirent __user *dirent; |
117 | struct osf_dirent_callback *buf = (struct osf_dirent_callback *) __buf; | 117 | struct osf_dirent_callback *buf = (struct osf_dirent_callback *) __buf; |
118 | unsigned int reclen = ROUND_UP(NAME_OFFSET + namlen + 1); | 118 | unsigned int reclen = ROUND_UP(NAME_OFFSET + namlen + 1); |
119 | unsigned int d_ino; | ||
119 | 120 | ||
120 | buf->error = -EINVAL; /* only used if we fail */ | 121 | buf->error = -EINVAL; /* only used if we fail */ |
121 | if (reclen > buf->count) | 122 | if (reclen > buf->count) |
122 | return -EINVAL; | 123 | return -EINVAL; |
124 | d_ino = ino; | ||
125 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
126 | return -EOVERFLOW; | ||
123 | if (buf->basep) { | 127 | if (buf->basep) { |
124 | if (put_user(offset, buf->basep)) | 128 | if (put_user(offset, buf->basep)) |
125 | return -EFAULT; | 129 | return -EFAULT; |
126 | buf->basep = NULL; | 130 | buf->basep = NULL; |
127 | } | 131 | } |
128 | dirent = buf->dirent; | 132 | dirent = buf->dirent; |
129 | put_user(ino, &dirent->d_ino); | 133 | put_user(d_ino, &dirent->d_ino); |
130 | put_user(namlen, &dirent->d_namlen); | 134 | put_user(namlen, &dirent->d_namlen); |
131 | put_user(reclen, &dirent->d_reclen); | 135 | put_user(reclen, &dirent->d_reclen); |
132 | if (copy_to_user(dirent->d_name, name, namlen) || | 136 | if (copy_to_user(dirent->d_name, name, namlen) || |
diff --git a/arch/arm/mach-pnx4008/clock.c b/arch/arm/mach-pnx4008/clock.c index f582ed2ec43c..daa8d3d98eff 100644 --- a/arch/arm/mach-pnx4008/clock.c +++ b/arch/arm/mach-pnx4008/clock.c | |||
@@ -735,6 +735,16 @@ static struct clk uart6_ck = { | |||
735 | .enable_reg = UARTCLKCTRL_REG, | 735 | .enable_reg = UARTCLKCTRL_REG, |
736 | }; | 736 | }; |
737 | 737 | ||
738 | static struct clk wdt_ck = { | ||
739 | .name = "wdt_ck", | ||
740 | .parent = &per_ck, | ||
741 | .flags = NEEDS_INITIALIZATION, | ||
742 | .round_rate = &on_off_round_rate, | ||
743 | .set_rate = &on_off_set_rate, | ||
744 | .enable_shift = 0, | ||
745 | .enable_reg = TIMCLKCTRL_REG, | ||
746 | }; | ||
747 | |||
738 | /* These clocks are visible outside this module | 748 | /* These clocks are visible outside this module |
739 | * and can be initialized | 749 | * and can be initialized |
740 | */ | 750 | */ |
@@ -765,6 +775,7 @@ static struct clk *onchip_clks[] = { | |||
765 | &uart4_ck, | 775 | &uart4_ck, |
766 | &uart5_ck, | 776 | &uart5_ck, |
767 | &uart6_ck, | 777 | &uart6_ck, |
778 | &wdt_ck, | ||
768 | }; | 779 | }; |
769 | 780 | ||
770 | static int local_clk_enable(struct clk *clk) | 781 | static int local_clk_enable(struct clk *clk) |
diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c index ab5e9503bae5..0221ba3bc799 100644 --- a/arch/arm/vfp/vfpsingle.c +++ b/arch/arm/vfp/vfpsingle.c | |||
@@ -198,8 +198,10 @@ u32 vfp_single_normaliseround(int sd, struct vfp_single *vs, u32 fpscr, u32 exce | |||
198 | vfp_single_dump("pack: final", vs); | 198 | vfp_single_dump("pack: final", vs); |
199 | { | 199 | { |
200 | s32 d = vfp_single_pack(vs); | 200 | s32 d = vfp_single_pack(vs); |
201 | #ifdef DEBUG | ||
201 | pr_debug("VFP: %s: d(s%d)=%08x exceptions=%08x\n", func, | 202 | pr_debug("VFP: %s: d(s%d)=%08x exceptions=%08x\n", func, |
202 | sd, d, exceptions); | 203 | sd, d, exceptions); |
204 | #endif | ||
203 | vfp_put_float(d, sd); | 205 | vfp_put_float(d, sd); |
204 | } | 206 | } |
205 | 207 | ||
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig index f7b171b92ea2..cf1c446e003a 100644 --- a/arch/frv/Kconfig +++ b/arch/frv/Kconfig | |||
@@ -86,6 +86,14 @@ config HIGHPTE | |||
86 | with a lot of RAM, this can be wasteful of precious low memory. | 86 | with a lot of RAM, this can be wasteful of precious low memory. |
87 | Setting this option will put user-space page tables in high memory. | 87 | Setting this option will put user-space page tables in high memory. |
88 | 88 | ||
89 | config LARGE_ALLOCS | ||
90 | bool "Allow allocating large blocks (> 1MB) of memory" | ||
91 | help | ||
92 | Allow the slab memory allocator to keep chains for very large memory | ||
93 | sizes - up to 32MB. You may need this if your system has a lot of | ||
94 | RAM, and you need to able to allocate very large contiguous chunks. | ||
95 | If unsure, say N. | ||
96 | |||
89 | source "mm/Kconfig" | 97 | source "mm/Kconfig" |
90 | 98 | ||
91 | choice | 99 | choice |
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c index bddbd22706ed..9d6a3f210148 100644 --- a/arch/ia64/ia32/sys_ia32.c +++ b/arch/ia64/ia32/sys_ia32.c | |||
@@ -125,6 +125,7 @@ sys32_execve (char __user *name, compat_uptr_t __user *argv, compat_uptr_t __use | |||
125 | 125 | ||
126 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf) | 126 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf) |
127 | { | 127 | { |
128 | compat_ino_t ino; | ||
128 | int err; | 129 | int err; |
129 | 130 | ||
130 | if ((u64) stat->size > MAX_NON_LFS || | 131 | if ((u64) stat->size > MAX_NON_LFS || |
@@ -132,11 +133,15 @@ int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf) | |||
132 | !old_valid_dev(stat->rdev)) | 133 | !old_valid_dev(stat->rdev)) |
133 | return -EOVERFLOW; | 134 | return -EOVERFLOW; |
134 | 135 | ||
136 | ino = stat->ino; | ||
137 | if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino) | ||
138 | return -EOVERFLOW; | ||
139 | |||
135 | if (clear_user(ubuf, sizeof(*ubuf))) | 140 | if (clear_user(ubuf, sizeof(*ubuf))) |
136 | return -EFAULT; | 141 | return -EFAULT; |
137 | 142 | ||
138 | err = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev); | 143 | err = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev); |
139 | err |= __put_user(stat->ino, &ubuf->st_ino); | 144 | err |= __put_user(ino, &ubuf->st_ino); |
140 | err |= __put_user(stat->mode, &ubuf->st_mode); | 145 | err |= __put_user(stat->mode, &ubuf->st_mode); |
141 | err |= __put_user(stat->nlink, &ubuf->st_nlink); | 146 | err |= __put_user(stat->nlink, &ubuf->st_nlink); |
142 | err |= __put_user(high2lowuid(stat->uid), &ubuf->st_uid); | 147 | err |= __put_user(high2lowuid(stat->uid), &ubuf->st_uid); |
@@ -1222,16 +1227,20 @@ struct readdir32_callback { | |||
1222 | }; | 1227 | }; |
1223 | 1228 | ||
1224 | static int | 1229 | static int |
1225 | filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino, | 1230 | filldir32 (void *__buf, const char *name, int namlen, loff_t offset, u64 ino, |
1226 | unsigned int d_type) | 1231 | unsigned int d_type) |
1227 | { | 1232 | { |
1228 | struct compat_dirent __user * dirent; | 1233 | struct compat_dirent __user * dirent; |
1229 | struct getdents32_callback * buf = (struct getdents32_callback *) __buf; | 1234 | struct getdents32_callback * buf = (struct getdents32_callback *) __buf; |
1230 | int reclen = ROUND_UP(offsetof(struct compat_dirent, d_name) + namlen + 1, 4); | 1235 | int reclen = ROUND_UP(offsetof(struct compat_dirent, d_name) + namlen + 1, 4); |
1236 | u32 d_ino; | ||
1231 | 1237 | ||
1232 | buf->error = -EINVAL; /* only used if we fail.. */ | 1238 | buf->error = -EINVAL; /* only used if we fail.. */ |
1233 | if (reclen > buf->count) | 1239 | if (reclen > buf->count) |
1234 | return -EINVAL; | 1240 | return -EINVAL; |
1241 | d_ino = ino; | ||
1242 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
1243 | return -EOVERFLOW; | ||
1235 | buf->error = -EFAULT; /* only used if we fail.. */ | 1244 | buf->error = -EFAULT; /* only used if we fail.. */ |
1236 | dirent = buf->previous; | 1245 | dirent = buf->previous; |
1237 | if (dirent) | 1246 | if (dirent) |
@@ -1239,7 +1248,7 @@ filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino, | |||
1239 | return -EFAULT; | 1248 | return -EFAULT; |
1240 | dirent = buf->current_dir; | 1249 | dirent = buf->current_dir; |
1241 | buf->previous = dirent; | 1250 | buf->previous = dirent; |
1242 | if (put_user(ino, &dirent->d_ino) | 1251 | if (put_user(d_ino, &dirent->d_ino) |
1243 | || put_user(reclen, &dirent->d_reclen) | 1252 | || put_user(reclen, &dirent->d_reclen) |
1244 | || copy_to_user(dirent->d_name, name, namlen) | 1253 | || copy_to_user(dirent->d_name, name, namlen) |
1245 | || put_user(0, dirent->d_name + namlen)) | 1254 | || put_user(0, dirent->d_name + namlen)) |
@@ -1287,17 +1296,21 @@ out: | |||
1287 | } | 1296 | } |
1288 | 1297 | ||
1289 | static int | 1298 | static int |
1290 | fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino, | 1299 | fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, u64 ino, |
1291 | unsigned int d_type) | 1300 | unsigned int d_type) |
1292 | { | 1301 | { |
1293 | struct readdir32_callback * buf = (struct readdir32_callback *) __buf; | 1302 | struct readdir32_callback * buf = (struct readdir32_callback *) __buf; |
1294 | struct old_linux32_dirent __user * dirent; | 1303 | struct old_linux32_dirent __user * dirent; |
1304 | u32 d_ino; | ||
1295 | 1305 | ||
1296 | if (buf->count) | 1306 | if (buf->count) |
1297 | return -EINVAL; | 1307 | return -EINVAL; |
1308 | d_ino = ino; | ||
1309 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
1310 | return -EOVERFLOW; | ||
1298 | buf->count++; | 1311 | buf->count++; |
1299 | dirent = buf->dirent; | 1312 | dirent = buf->dirent; |
1300 | if (put_user(ino, &dirent->d_ino) | 1313 | if (put_user(d_ino, &dirent->d_ino) |
1301 | || put_user(offset, &dirent->d_offset) | 1314 | || put_user(offset, &dirent->d_offset) |
1302 | || put_user(namlen, &dirent->d_namlen) | 1315 | || put_user(namlen, &dirent->d_namlen) |
1303 | || copy_to_user(dirent->d_name, name, namlen) | 1316 | || copy_to_user(dirent->d_name, name, namlen) |
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 52cada45b353..53f4171fc188 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c | |||
@@ -77,6 +77,8 @@ int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) | |||
77 | memset(&tmp, 0, sizeof(tmp)); | 77 | memset(&tmp, 0, sizeof(tmp)); |
78 | tmp.st_dev = new_encode_dev(stat->dev); | 78 | tmp.st_dev = new_encode_dev(stat->dev); |
79 | tmp.st_ino = stat->ino; | 79 | tmp.st_ino = stat->ino; |
80 | if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino) | ||
81 | return -EOVERFLOW; | ||
80 | tmp.st_mode = stat->mode; | 82 | tmp.st_mode = stat->mode; |
81 | tmp.st_nlink = stat->nlink; | 83 | tmp.st_nlink = stat->nlink; |
82 | SET_UID(tmp.st_uid, stat->uid); | 84 | SET_UID(tmp.st_uid, stat->uid); |
diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c index 11bb97174972..93c74fefff76 100644 --- a/arch/mips/kernel/sysirix.c +++ b/arch/mips/kernel/sysirix.c | |||
@@ -1739,12 +1739,13 @@ struct irix_dirent32_callback { | |||
1739 | #define ROUND_UP32(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1)) | 1739 | #define ROUND_UP32(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1)) |
1740 | 1740 | ||
1741 | static int irix_filldir32(void *__buf, const char *name, | 1741 | static int irix_filldir32(void *__buf, const char *name, |
1742 | int namlen, loff_t offset, ino_t ino, unsigned int d_type) | 1742 | int namlen, loff_t offset, u64 ino, unsigned int d_type) |
1743 | { | 1743 | { |
1744 | struct irix_dirent32 __user *dirent; | 1744 | struct irix_dirent32 __user *dirent; |
1745 | struct irix_dirent32_callback *buf = __buf; | 1745 | struct irix_dirent32_callback *buf = __buf; |
1746 | unsigned short reclen = ROUND_UP32(NAME_OFFSET32(dirent) + namlen + 1); | 1746 | unsigned short reclen = ROUND_UP32(NAME_OFFSET32(dirent) + namlen + 1); |
1747 | int err = 0; | 1747 | int err = 0; |
1748 | u32 d_ino; | ||
1748 | 1749 | ||
1749 | #ifdef DEBUG_GETDENTS | 1750 | #ifdef DEBUG_GETDENTS |
1750 | printk("\nirix_filldir32[reclen<%d>namlen<%d>count<%d>]", | 1751 | printk("\nirix_filldir32[reclen<%d>namlen<%d>count<%d>]", |
@@ -1753,12 +1754,15 @@ static int irix_filldir32(void *__buf, const char *name, | |||
1753 | buf->error = -EINVAL; /* only used if we fail.. */ | 1754 | buf->error = -EINVAL; /* only used if we fail.. */ |
1754 | if (reclen > buf->count) | 1755 | if (reclen > buf->count) |
1755 | return -EINVAL; | 1756 | return -EINVAL; |
1757 | d_ino = ino; | ||
1758 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
1759 | return -EOVERFLOW; | ||
1756 | dirent = buf->previous; | 1760 | dirent = buf->previous; |
1757 | if (dirent) | 1761 | if (dirent) |
1758 | err = __put_user(offset, &dirent->d_off); | 1762 | err = __put_user(offset, &dirent->d_off); |
1759 | dirent = buf->current_dir; | 1763 | dirent = buf->current_dir; |
1760 | err |= __put_user(dirent, &buf->previous); | 1764 | err |= __put_user(dirent, &buf->previous); |
1761 | err |= __put_user(ino, &dirent->d_ino); | 1765 | err |= __put_user(d_ino, &dirent->d_ino); |
1762 | err |= __put_user(reclen, &dirent->d_reclen); | 1766 | err |= __put_user(reclen, &dirent->d_reclen); |
1763 | err |= copy_to_user((char __user *)dirent->d_name, name, namlen) ? -EFAULT : 0; | 1767 | err |= copy_to_user((char __user *)dirent->d_name, name, namlen) ? -EFAULT : 0; |
1764 | err |= __put_user(0, &dirent->d_name[namlen]); | 1768 | err |= __put_user(0, &dirent->d_name[namlen]); |
@@ -1837,7 +1841,7 @@ struct irix_dirent64_callback { | |||
1837 | #define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1)) | 1841 | #define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1)) |
1838 | 1842 | ||
1839 | static int irix_filldir64(void *__buf, const char *name, | 1843 | static int irix_filldir64(void *__buf, const char *name, |
1840 | int namlen, loff_t offset, ino_t ino, unsigned int d_type) | 1844 | int namlen, loff_t offset, u64 ino, unsigned int d_type) |
1841 | { | 1845 | { |
1842 | struct irix_dirent64 __user *dirent; | 1846 | struct irix_dirent64 __user *dirent; |
1843 | struct irix_dirent64_callback * buf = __buf; | 1847 | struct irix_dirent64_callback * buf = __buf; |
diff --git a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c index d7c80edf4489..6e79dbf3f6bd 100644 --- a/arch/parisc/hpux/fs.c +++ b/arch/parisc/hpux/fs.c | |||
@@ -77,17 +77,21 @@ static int filldir(void * __buf, const char * name, int namlen, loff_t offset, | |||
77 | { | 77 | { |
78 | struct hpux_dirent * dirent; | 78 | struct hpux_dirent * dirent; |
79 | struct getdents_callback * buf = (struct getdents_callback *) __buf; | 79 | struct getdents_callback * buf = (struct getdents_callback *) __buf; |
80 | ino_t d_ino; | ||
80 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); | 81 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); |
81 | 82 | ||
82 | buf->error = -EINVAL; /* only used if we fail.. */ | 83 | buf->error = -EINVAL; /* only used if we fail.. */ |
83 | if (reclen > buf->count) | 84 | if (reclen > buf->count) |
84 | return -EINVAL; | 85 | return -EINVAL; |
86 | d_ino = ino; | ||
87 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
88 | return -EOVERFLOW; | ||
85 | dirent = buf->previous; | 89 | dirent = buf->previous; |
86 | if (dirent) | 90 | if (dirent) |
87 | put_user(offset, &dirent->d_off); | 91 | put_user(offset, &dirent->d_off); |
88 | dirent = buf->current_dir; | 92 | dirent = buf->current_dir; |
89 | buf->previous = dirent; | 93 | buf->previous = dirent; |
90 | put_user(ino, &dirent->d_ino); | 94 | put_user(d_ino, &dirent->d_ino); |
91 | put_user(reclen, &dirent->d_reclen); | 95 | put_user(reclen, &dirent->d_reclen); |
92 | put_user(namlen, &dirent->d_namlen); | 96 | put_user(namlen, &dirent->d_namlen); |
93 | copy_to_user(dirent->d_name, name, namlen); | 97 | copy_to_user(dirent->d_name, name, namlen); |
diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c index b74869803081..e3b30bc36453 100644 --- a/arch/parisc/kernel/sys_parisc32.c +++ b/arch/parisc/kernel/sys_parisc32.c | |||
@@ -237,14 +237,19 @@ int sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user | |||
237 | 237 | ||
238 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) | 238 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) |
239 | { | 239 | { |
240 | compat_ino_t ino; | ||
240 | int err; | 241 | int err; |
241 | 242 | ||
242 | if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) || | 243 | if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) || |
243 | !new_valid_dev(stat->rdev)) | 244 | !new_valid_dev(stat->rdev)) |
244 | return -EOVERFLOW; | 245 | return -EOVERFLOW; |
245 | 246 | ||
247 | ino = stat->ino; | ||
248 | if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino) | ||
249 | return -EOVERFLOW; | ||
250 | |||
246 | err = put_user(new_encode_dev(stat->dev), &statbuf->st_dev); | 251 | err = put_user(new_encode_dev(stat->dev), &statbuf->st_dev); |
247 | err |= put_user(stat->ino, &statbuf->st_ino); | 252 | err |= put_user(ino, &statbuf->st_ino); |
248 | err |= put_user(stat->mode, &statbuf->st_mode); | 253 | err |= put_user(stat->mode, &statbuf->st_mode); |
249 | err |= put_user(stat->nlink, &statbuf->st_nlink); | 254 | err |= put_user(stat->nlink, &statbuf->st_nlink); |
250 | err |= put_user(0, &statbuf->st_reserved1); | 255 | err |= put_user(0, &statbuf->st_reserved1); |
@@ -312,16 +317,20 @@ filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino, | |||
312 | struct linux32_dirent __user * dirent; | 317 | struct linux32_dirent __user * dirent; |
313 | struct getdents32_callback * buf = (struct getdents32_callback *) __buf; | 318 | struct getdents32_callback * buf = (struct getdents32_callback *) __buf; |
314 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4); | 319 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4); |
320 | u32 d_ino; | ||
315 | 321 | ||
316 | buf->error = -EINVAL; /* only used if we fail.. */ | 322 | buf->error = -EINVAL; /* only used if we fail.. */ |
317 | if (reclen > buf->count) | 323 | if (reclen > buf->count) |
318 | return -EINVAL; | 324 | return -EINVAL; |
325 | d_ino = ino; | ||
326 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
327 | return -EOVERFLOW; | ||
319 | dirent = buf->previous; | 328 | dirent = buf->previous; |
320 | if (dirent) | 329 | if (dirent) |
321 | put_user(offset, &dirent->d_off); | 330 | put_user(offset, &dirent->d_off); |
322 | dirent = buf->current_dir; | 331 | dirent = buf->current_dir; |
323 | buf->previous = dirent; | 332 | buf->previous = dirent; |
324 | put_user(ino, &dirent->d_ino); | 333 | put_user(d_ino, &dirent->d_ino); |
325 | put_user(reclen, &dirent->d_reclen); | 334 | put_user(reclen, &dirent->d_reclen); |
326 | copy_to_user(dirent->d_name, name, namlen); | 335 | copy_to_user(dirent->d_name, name, namlen); |
327 | put_user(0, dirent->d_name + namlen); | 336 | put_user(0, dirent->d_name + namlen); |
@@ -371,12 +380,16 @@ fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t | |||
371 | { | 380 | { |
372 | struct readdir32_callback * buf = (struct readdir32_callback *) __buf; | 381 | struct readdir32_callback * buf = (struct readdir32_callback *) __buf; |
373 | struct old_linux32_dirent __user * dirent; | 382 | struct old_linux32_dirent __user * dirent; |
383 | u32 d_ino; | ||
374 | 384 | ||
375 | if (buf->count) | 385 | if (buf->count) |
376 | return -EINVAL; | 386 | return -EINVAL; |
387 | d_ino = ino; | ||
388 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
389 | return -EOVERFLOW; | ||
377 | buf->count++; | 390 | buf->count++; |
378 | dirent = buf->dirent; | 391 | dirent = buf->dirent; |
379 | put_user(ino, &dirent->d_ino); | 392 | put_user(d_ino, &dirent->d_ino); |
380 | put_user(offset, &dirent->d_offset); | 393 | put_user(offset, &dirent->d_offset); |
381 | put_user(namlen, &dirent->d_namlen); | 394 | put_user(namlen, &dirent->d_namlen); |
382 | copy_to_user(dirent->d_name, name, namlen); | 395 | copy_to_user(dirent->d_name, name, namlen); |
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 01667d1d571d..a00fe7236555 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile | |||
@@ -20,6 +20,7 @@ CROSS32_COMPILE ?= | |||
20 | CROSS32CC := $(CROSS32_COMPILE)gcc | 20 | CROSS32CC := $(CROSS32_COMPILE)gcc |
21 | CROSS32AS := $(CROSS32_COMPILE)as | 21 | CROSS32AS := $(CROSS32_COMPILE)as |
22 | CROSS32LD := $(CROSS32_COMPILE)ld | 22 | CROSS32LD := $(CROSS32_COMPILE)ld |
23 | CROSS32AR := $(CROSS32_COMPILE)ar | ||
23 | CROSS32OBJCOPY := $(CROSS32_COMPILE)objcopy | 24 | CROSS32OBJCOPY := $(CROSS32_COMPILE)objcopy |
24 | 25 | ||
25 | ifeq ($(HAS_BIARCH),y) | 26 | ifeq ($(HAS_BIARCH),y) |
@@ -28,10 +29,11 @@ CROSS32CC := $(CC) -m32 | |||
28 | CROSS32AS := $(AS) -a32 | 29 | CROSS32AS := $(AS) -a32 |
29 | CROSS32LD := $(LD) -m elf32ppc | 30 | CROSS32LD := $(LD) -m elf32ppc |
30 | CROSS32OBJCOPY := $(OBJCOPY) | 31 | CROSS32OBJCOPY := $(OBJCOPY) |
32 | CROSS32AR := $(AR) | ||
31 | endif | 33 | endif |
32 | endif | 34 | endif |
33 | 35 | ||
34 | export CROSS32CC CROSS32AS CROSS32LD CROSS32OBJCOPY | 36 | export CROSS32CC CROSS32AS CROSS32LD CROSS32AR CROSS32OBJCOPY |
35 | 37 | ||
36 | KBUILD_DEFCONFIG := $(shell uname -m)_defconfig | 38 | KBUILD_DEFCONFIG := $(shell uname -m)_defconfig |
37 | 39 | ||
@@ -146,7 +148,7 @@ all: $(KBUILD_IMAGE) | |||
146 | 148 | ||
147 | CPPFLAGS_vmlinux.lds := -Upowerpc | 149 | CPPFLAGS_vmlinux.lds := -Upowerpc |
148 | 150 | ||
149 | BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm uImage vmlinux.bin | 151 | BOOT_TARGETS = zImage zImage.initrd uImage |
150 | 152 | ||
151 | PHONY += $(BOOT_TARGETS) | 153 | PHONY += $(BOOT_TARGETS) |
152 | 154 | ||
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index e73774136b55..c383d56bbe18 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile | |||
@@ -20,33 +20,34 @@ | |||
20 | # CROSS32_COMPILE is setup as a prefix just like CROSS_COMPILE | 20 | # CROSS32_COMPILE is setup as a prefix just like CROSS_COMPILE |
21 | # in the toplevel makefile. | 21 | # in the toplevel makefile. |
22 | 22 | ||
23 | all: $(obj)/zImage | ||
23 | 24 | ||
24 | HOSTCC := gcc | 25 | HOSTCC := gcc |
25 | BOOTCFLAGS := $(HOSTCFLAGS) -fno-builtin -nostdinc -isystem \ | 26 | BOOTCFLAGS := $(HOSTCFLAGS) -fno-builtin -nostdinc -isystem \ |
26 | $(shell $(CROSS32CC) -print-file-name=include) -fPIC | 27 | $(shell $(CROSS32CC) -print-file-name=include) -fPIC |
27 | BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc | 28 | BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc |
28 | OBJCOPYFLAGS := contents,alloc,load,readonly,data | 29 | |
29 | OBJCOPY_COFF_ARGS := -O aixcoff-rs6000 --set-start 0x500000 | 30 | ifeq ($(call cc-option-yn, -fstack-protector),y) |
30 | OBJCOPY_MIB_ARGS := -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment | 31 | BOOTCFLAGS += -fno-stack-protector |
32 | endif | ||
33 | |||
34 | BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) | ||
31 | 35 | ||
32 | zlib := inffast.c inflate.c inftrees.c | 36 | zlib := inffast.c inflate.c inftrees.c |
33 | zlibheader := inffast.h inffixed.h inflate.h inftrees.h infutil.h | 37 | zlibheader := inffast.h inffixed.h inflate.h inftrees.h infutil.h |
34 | zliblinuxheader := zlib.h zconf.h zutil.h | 38 | zliblinuxheader := zlib.h zconf.h zutil.h |
35 | 39 | ||
36 | $(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader)) | 40 | $(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) \ |
37 | #$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h) | 41 | $(addprefix $(obj)/,$(zlibheader)) |
42 | |||
43 | src-wlib := string.S stdio.c main.c div64.S $(zlib) | ||
44 | src-plat := of.c | ||
45 | src-boot := crt0.S $(src-wlib) $(src-plat) empty.c | ||
38 | 46 | ||
39 | src-boot-$(CONFIG_PPC_MULTIPLATFORM) := of.c | ||
40 | src-boot := crt0.S string.S stdio.c main.c div64.S $(src-boot-y) | ||
41 | src-boot += $(zlib) | ||
42 | src-boot := $(addprefix $(obj)/, $(src-boot)) | 47 | src-boot := $(addprefix $(obj)/, $(src-boot)) |
43 | obj-boot := $(addsuffix .o, $(basename $(src-boot))) | 48 | obj-boot := $(addsuffix .o, $(basename $(src-boot))) |
44 | 49 | obj-wlib := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-wlib)))) | |
45 | ifeq ($(call cc-option-yn, -fstack-protector),y) | 50 | obj-plat := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-plat)))) |
46 | BOOTCFLAGS += -fno-stack-protector | ||
47 | endif | ||
48 | |||
49 | BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) | ||
50 | 51 | ||
51 | quiet_cmd_copy_zlib = COPY $@ | 52 | quiet_cmd_copy_zlib = COPY $@ |
52 | cmd_copy_zlib = sed "s@__attribute_used__@@;s@<linux/\([^>]\+\).*@\"\1\"@" $< > $@ | 53 | cmd_copy_zlib = sed "s@__attribute_used__@@;s@<linux/\([^>]\+\).*@\"\1\"@" $< > $@ |
@@ -66,8 +67,14 @@ $(addprefix $(obj)/,$(zlibheader)): $(obj)/%: $(srctree)/lib/zlib_inflate/% | |||
66 | $(addprefix $(obj)/,$(zliblinuxheader)): $(obj)/%: $(srctree)/include/linux/% | 67 | $(addprefix $(obj)/,$(zliblinuxheader)): $(obj)/%: $(srctree)/include/linux/% |
67 | $(call cmd,copy_zliblinuxheader) | 68 | $(call cmd,copy_zliblinuxheader) |
68 | 69 | ||
69 | clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) | 70 | $(obj)/empty.c: |
71 | @touch $@ | ||
72 | |||
73 | $(obj)/zImage.lds $(obj)/zImage.coff.lds: $(obj)/%: $(srctree)/$(src)/%.S | ||
74 | @cp $< $@ | ||
70 | 75 | ||
76 | clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \ | ||
77 | $(obj)/empty.c | ||
71 | 78 | ||
72 | quiet_cmd_bootcc = BOOTCC $@ | 79 | quiet_cmd_bootcc = BOOTCC $@ |
73 | cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $< | 80 | cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $< |
@@ -75,146 +82,97 @@ quiet_cmd_bootcc = BOOTCC $@ | |||
75 | quiet_cmd_bootas = BOOTAS $@ | 82 | quiet_cmd_bootas = BOOTAS $@ |
76 | cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $< | 83 | cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $< |
77 | 84 | ||
78 | quiet_cmd_bootld = BOOTLD $@ | 85 | quiet_cmd_bootar = BOOTAR $@ |
79 | cmd_bootld = $(CROSS32LD) -T $(srctree)/$(src)/$(3) -o $@ $(2) | 86 | cmd_bootar = $(CROSS32AR) -cr $@.$$$$ $^; mv $@.$$$$ $@ |
80 | 87 | ||
81 | $(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c | 88 | $(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c |
82 | $(call if_changed_dep,bootcc) | 89 | $(call if_changed_dep,bootcc) |
83 | $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S | 90 | $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S |
84 | $(call if_changed_dep,bootas) | 91 | $(call if_changed_dep,bootas) |
85 | 92 | ||
86 | #----------------------------------------------------------- | 93 | $(obj)/wrapper.a: $(obj-wlib) |
87 | # ELF sections within the zImage bootloader/wrapper | 94 | $(call cmd,bootar) |
88 | #----------------------------------------------------------- | ||
89 | required := vmlinux.strip | ||
90 | initrd := initrd | ||
91 | 95 | ||
92 | obj-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.o, $(section))) | 96 | hostprogs-y := addnote addRamDisk hack-coff |
93 | src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section))) | ||
94 | gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section))) | ||
95 | 97 | ||
96 | hostprogs-y := addnote addRamDisk hack-coff | 98 | extra-y := $(obj)/crt0.o $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \ |
99 | $(obj)/zImage.lds $(obj)/zImage.coff.lds | ||
97 | 100 | ||
98 | targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd \ | 101 | wrapper :=$(srctree)/$(src)/wrapper |
99 | zImage.coff zImage.initrd.coff miboot.image miboot.initrd.image \ | 102 | wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff) |
100 | $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \ | ||
101 | $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \ | ||
102 | $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \ | ||
103 | vmlinux.initrd dummy.o | ||
104 | extra-y := initrd.o | ||
105 | 103 | ||
106 | quiet_cmd_ramdisk = RAMDISK $@ | 104 | ############# |
107 | cmd_ramdisk = $(obj)/addRamDisk $(obj)/ramdisk.image.gz $< $@ | 105 | # Bits for building various flavours of zImage |
108 | 106 | ||
109 | quiet_cmd_stripvm = STRIP $@ | 107 | ifneq ($(CROSS32_COMPILE),) |
110 | cmd_stripvm = $(STRIP) -s -R .comment $< -o $@ | 108 | CROSSWRAP := -C $(CROSS32_COMPILE) |
109 | else | ||
110 | ifneq ($(CROSS_COMPILE),) | ||
111 | CROSSWRAP := -C $(CROSS_COMPILE) | ||
112 | endif | ||
113 | endif | ||
111 | 114 | ||
112 | vmlinux.strip: vmlinux | 115 | quiet_cmd_wrap = WRAP $@ |
113 | $(call if_changed,stripvm) | 116 | cmd_wrap =$(wrapper) -c -o $@ -p $2 $(CROSSWRAP) vmlinux |
114 | $(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz | 117 | quiet_cmd_wrap_initrd = WRAP $@ |
115 | $(call if_changed,ramdisk) | 118 | cmd_wrap_initrd =$(wrapper) -c -o $@ -p $2 $(CROSSWRAP) \ |
119 | -i $(obj)/ramdisk.image.gz vmlinux | ||
116 | 120 | ||
117 | quiet_cmd_addsection = ADDSEC $@ | 121 | $(obj)/zImage.chrp: vmlinux $(wrapperbits) |
118 | cmd_addsection = $(CROSS32OBJCOPY) $@ \ | 122 | $(call cmd,wrap,chrp) |
119 | --add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(patsubst %.o,%.gz, $@) \ | ||
120 | --set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(OBJCOPYFLAGS) | ||
121 | 123 | ||
122 | quiet_cmd_addnote = ADDNOTE $@ | 124 | $(obj)/zImage.initrd.chrp: vmlinux $(wrapperbits) |
123 | cmd_addnote = $(obj)/addnote $@ | 125 | $(call cmd,wrap_initrd,chrp) |
124 | 126 | ||
125 | quiet_cmd_gen-miboot = GEN $@ | 127 | $(obj)/zImage.pseries: vmlinux $(wrapperbits) |
126 | cmd_gen-miboot = $(OBJCOPY) $(OBJCOPY_MIB_ARGS) \ | 128 | $(call cmd,wrap,pseries) |
127 | --add-section=$1=$(word 2, $^) $< $@ | ||
128 | 129 | ||
129 | quiet_cmd_gencoff = COFF $@ | 130 | $(obj)/zImage.initrd.pseries: vmlinux $(wrapperbits) |
130 | cmd_gencoff = $(OBJCOPY) $(OBJCOPY_COFF_ARGS) $@ && \ | 131 | $(call cmd,wrap_initrd,pseries) |
131 | $(obj)/hack-coff $@ | ||
132 | 132 | ||
133 | $(call gz-sec, $(required)): $(obj)/kernel-%.gz: % | 133 | $(obj)/zImage.pmac: vmlinux $(wrapperbits) |
134 | $(call if_changed,gzip) | 134 | $(call cmd,wrap,pmac) |
135 | 135 | ||
136 | $(obj)/kernel-initrd.gz: $(obj)/ramdisk.image.gz | 136 | $(obj)/zImage.initrd.pmac: vmlinux $(wrapperbits) |
137 | cp -f $(obj)/ramdisk.image.gz $@ | 137 | $(call cmd,wrap_initrd,pmac) |
138 | 138 | ||
139 | $(call src-sec, $(required) $(initrd)): $(obj)/kernel-%.c: $(obj)/kernel-%.gz | 139 | $(obj)/zImage.coff: vmlinux $(wrapperbits) |
140 | @touch $@ | 140 | $(call cmd,wrap,pmaccoff) |
141 | 141 | ||
142 | $(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c | 142 | $(obj)/zImage.initrd.coff: vmlinux $(wrapperbits) |
143 | $(call if_changed_dep,bootcc) | 143 | $(call cmd,wrap_initrd,pmaccoff) |
144 | $(call cmd,addsection) | 144 | |
145 | $(obj)/zImage.miboot: vmlinux $(wrapperbits) | ||
146 | $(call cmd,wrap,miboot) | ||
145 | 147 | ||
146 | $(obj)/zImage.vmode $(obj)/zImage.coff: obj-boot += $(call obj-sec, $(required)) | 148 | $(obj)/zImage.initrd.miboot: vmlinux $(wrapperbits) |
147 | $(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) $(srctree)/$(src)/zImage.lds | 149 | $(call cmd,wrap_initrd,miboot) |
148 | $(call cmd,bootld,$(obj-boot),zImage.lds) | ||
149 | 150 | ||
150 | $(obj)/zImage.initrd.vmode $(obj)/zImage.initrd.coff: obj-boot += $(call obj-sec, $(required) $(initrd)) | 151 | $(obj)/uImage: vmlinux $(wrapperbits) |
151 | $(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(srctree)/$(src)/zImage.lds | 152 | $(call cmd,wrap,uboot) |
152 | $(call cmd,bootld,$(obj-boot),zImage.lds) | 153 | |
154 | image-$(CONFIG_PPC_PSERIES) += zImage.pseries | ||
155 | image-$(CONFIG_PPC_MAPLE) += zImage.pseries | ||
156 | image-$(CONFIG_PPC_CELL) += zImage.pseries | ||
157 | image-$(CONFIG_PPC_CHRP) += zImage.chrp | ||
158 | image-$(CONFIG_PPC_PMAC) += zImage.pmac | ||
159 | image-$(CONFIG_DEFAULT_UIMAGE) += uImage | ||
153 | 160 | ||
154 | # For 32-bit powermacs, build the COFF and miboot images | 161 | # For 32-bit powermacs, build the COFF and miboot images |
155 | # as well as the ELF images. | 162 | # as well as the ELF images. |
156 | coffimage-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/zImage.coff | 163 | ifeq ($(CONFIG_PPC32),y) |
157 | coffrdimg-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/zImage.initrd.coff | 164 | image-$(CONFIG_PPC_PMAC) += zImage.coff zImage.miboot |
158 | mibootimg-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/miboot.image | 165 | endif |
159 | mibrdimg-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/miboot.initrd.image | 166 | |
160 | 167 | initrd-y := $(patsubst zImage%, zImage.initrd%, $(image-y)) | |
161 | $(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote $(coffimage-y-y) \ | 168 | |
162 | $(mibootimg-y-y) | 169 | $(obj)/zImage: $(addprefix $(obj)/, $(image-y)) |
163 | @cp -f $< $@ | 170 | @rm -f $@; ln $< $@ |
164 | $(call if_changed,addnote) | 171 | $(obj)/zImage.initrd: $(addprefix $(obj)/, $(initrd-y)) |
165 | 172 | @rm -f $@; ln $< $@ | |
166 | $(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote \ | 173 | |
167 | $(coffrdimg-y-y) $(mibrdimg-y-y) | 174 | install: $(CONFIGURE) $(image-y) |
168 | @cp -f $< $@ | 175 | sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" $< |
169 | $(call if_changed,addnote) | 176 | |
170 | 177 | clean-files += $(addprefix $(objtree)/, $(obj-boot) vmlinux.strip.gz) | |
171 | $(obj)/zImage.coff: $(call obj-sec, $(required)) $(obj-boot) \ | 178 | clean-files += $(addprefix $(objtree)/, $(obj-boot) vmlinux.bin.gz) |
172 | $(srctree)/$(src)/zImage.coff.lds $(obj)/hack-coff | ||
173 | $(call cmd,bootld,$(obj-boot),zImage.coff.lds) | ||
174 | $(call cmd,gencoff) | ||
175 | |||
176 | $(obj)/zImage.initrd.coff: $(call obj-sec, $(required) $(initrd)) $(obj-boot) \ | ||
177 | $(srctree)/$(src)/zImage.coff.lds $(obj)/hack-coff | ||
178 | $(call cmd,bootld,$(obj-boot),zImage.coff.lds) | ||
179 | $(call cmd,gencoff) | ||
180 | |||
181 | $(obj)/miboot.image: $(obj)/dummy.o $(obj)/vmlinux.gz | ||
182 | $(call cmd,gen-miboot,image) | ||
183 | |||
184 | $(obj)/miboot.initrd.image: $(obj)/miboot.image $(images)/ramdisk.image.gz | ||
185 | $(call cmd,gen-miboot,initrd) | ||
186 | |||
187 | #----------------------------------------------------------- | ||
188 | # build u-boot images | ||
189 | #----------------------------------------------------------- | ||
190 | quiet_cmd_mygzip = GZIP $@ | ||
191 | cmd_mygzip = gzip -f -9 < $< > $@.$$$$ && mv $@.$$$$ $@ | ||
192 | |||
193 | quiet_cmd_objbin = OBJCOPY $@ | ||
194 | cmd_objbin = $(OBJCOPY) -O binary $< $@ | ||
195 | |||
196 | quiet_cmd_uimage = UIMAGE $@ | ||
197 | cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A ppc -O linux -T kernel \ | ||
198 | -C gzip -a 00000000 -e 00000000 -n 'Linux-$(KERNELRELEASE)' \ | ||
199 | -d $< $@ | ||
200 | |||
201 | MKIMAGE := $(srctree)/scripts/mkuboot.sh | ||
202 | targets += uImage | ||
203 | extra-y += vmlinux.bin vmlinux.gz | ||
204 | |||
205 | $(obj)/vmlinux.bin: vmlinux FORCE | ||
206 | $(call if_changed,objbin) | ||
207 | |||
208 | $(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE | ||
209 | $(call if_changed,mygzip) | ||
210 | |||
211 | $(obj)/uImage: $(obj)/vmlinux.gz | ||
212 | $(Q)rm -f $@ | ||
213 | $(call cmd,uimage) | ||
214 | @echo -n ' Image: $@ ' | ||
215 | @if [ -f $@ ]; then echo 'is ready' ; else echo 'not made'; fi | ||
216 | |||
217 | install: $(CONFIGURE) $(BOOTIMAGE) | ||
218 | sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" "$(BOOTIMAGE)" | ||
219 | |||
220 | clean-files += $(addprefix $(objtree)/, $(obj-boot) vmlinux.strip) | ||
diff --git a/arch/powerpc/boot/dts/mpc8560ads.dts b/arch/powerpc/boot/dts/mpc8560ads.dts new file mode 100644 index 000000000000..2b168486aeba --- /dev/null +++ b/arch/powerpc/boot/dts/mpc8560ads.dts | |||
@@ -0,0 +1,302 @@ | |||
1 | /* | ||
2 | * MPC8560 ADS Device Tree Source | ||
3 | * | ||
4 | * Copyright 2006 Freescale Semiconductor Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | */ | ||
11 | |||
12 | |||
13 | / { | ||
14 | model = "MPC8560ADS"; | ||
15 | compatible = "MPC85xxADS"; | ||
16 | #address-cells = <1>; | ||
17 | #size-cells = <1>; | ||
18 | linux,phandle = <100>; | ||
19 | |||
20 | cpus { | ||
21 | #cpus = <1>; | ||
22 | #address-cells = <1>; | ||
23 | #size-cells = <0>; | ||
24 | linux,phandle = <200>; | ||
25 | |||
26 | PowerPC,8560@0 { | ||
27 | device_type = "cpu"; | ||
28 | reg = <0>; | ||
29 | d-cache-line-size = <20>; // 32 bytes | ||
30 | i-cache-line-size = <20>; // 32 bytes | ||
31 | d-cache-size = <8000>; // L1, 32K | ||
32 | i-cache-size = <8000>; // L1, 32K | ||
33 | timebase-frequency = <04ead9a0>; | ||
34 | bus-frequency = <13ab6680>; | ||
35 | clock-frequency = <312c8040>; | ||
36 | 32-bit; | ||
37 | linux,phandle = <201>; | ||
38 | linux,boot-cpu; | ||
39 | }; | ||
40 | }; | ||
41 | |||
42 | memory { | ||
43 | device_type = "memory"; | ||
44 | linux,phandle = <300>; | ||
45 | reg = <00000000 10000000>; | ||
46 | }; | ||
47 | |||
48 | soc8560@e0000000 { | ||
49 | #address-cells = <1>; | ||
50 | #size-cells = <1>; | ||
51 | #interrupt-cells = <2>; | ||
52 | device_type = "soc"; | ||
53 | ranges = <0 e0000000 00100000>; | ||
54 | reg = <e0000000 00000200>; | ||
55 | bus-frequency = <13ab6680>; | ||
56 | |||
57 | mdio@24520 { | ||
58 | device_type = "mdio"; | ||
59 | compatible = "gianfar"; | ||
60 | reg = <24520 20>; | ||
61 | linux,phandle = <24520>; | ||
62 | #address-cells = <1>; | ||
63 | #size-cells = <0>; | ||
64 | ethernet-phy@0 { | ||
65 | linux,phandle = <2452000>; | ||
66 | interrupt-parent = <40000>; | ||
67 | interrupts = <35 1>; | ||
68 | reg = <0>; | ||
69 | device_type = "ethernet-phy"; | ||
70 | }; | ||
71 | ethernet-phy@1 { | ||
72 | linux,phandle = <2452001>; | ||
73 | interrupt-parent = <40000>; | ||
74 | interrupts = <35 1>; | ||
75 | reg = <1>; | ||
76 | device_type = "ethernet-phy"; | ||
77 | }; | ||
78 | ethernet-phy@2 { | ||
79 | linux,phandle = <2452002>; | ||
80 | interrupt-parent = <40000>; | ||
81 | interrupts = <37 1>; | ||
82 | reg = <2>; | ||
83 | device_type = "ethernet-phy"; | ||
84 | }; | ||
85 | ethernet-phy@3 { | ||
86 | linux,phandle = <2452003>; | ||
87 | interrupt-parent = <40000>; | ||
88 | interrupts = <37 1>; | ||
89 | reg = <3>; | ||
90 | device_type = "ethernet-phy"; | ||
91 | }; | ||
92 | }; | ||
93 | |||
94 | ethernet@24000 { | ||
95 | device_type = "network"; | ||
96 | model = "TSEC"; | ||
97 | compatible = "gianfar"; | ||
98 | reg = <24000 1000>; | ||
99 | address = [ 00 00 0C 00 00 FD ]; | ||
100 | interrupts = <d 2 e 2 12 2>; | ||
101 | interrupt-parent = <40000>; | ||
102 | phy-handle = <2452000>; | ||
103 | }; | ||
104 | |||
105 | ethernet@25000 { | ||
106 | #address-cells = <1>; | ||
107 | #size-cells = <0>; | ||
108 | device_type = "network"; | ||
109 | model = "TSEC"; | ||
110 | compatible = "gianfar"; | ||
111 | reg = <25000 1000>; | ||
112 | address = [ 00 00 0C 00 01 FD ]; | ||
113 | interrupts = <13 2 14 2 18 2>; | ||
114 | interrupt-parent = <40000>; | ||
115 | phy-handle = <2452001>; | ||
116 | }; | ||
117 | |||
118 | pci@8000 { | ||
119 | linux,phandle = <8000>; | ||
120 | #interrupt-cells = <1>; | ||
121 | #size-cells = <2>; | ||
122 | #address-cells = <3>; | ||
123 | compatible = "85xx"; | ||
124 | device_type = "pci"; | ||
125 | reg = <8000 400>; | ||
126 | clock-frequency = <3f940aa>; | ||
127 | interrupt-map-mask = <f800 0 0 7>; | ||
128 | interrupt-map = < | ||
129 | |||
130 | /* IDSEL 0x2 */ | ||
131 | 1000 0 0 1 40000 31 1 | ||
132 | 1000 0 0 2 40000 32 1 | ||
133 | 1000 0 0 3 40000 33 1 | ||
134 | 1000 0 0 4 40000 34 1 | ||
135 | |||
136 | /* IDSEL 0x3 */ | ||
137 | 1800 0 0 1 40000 34 1 | ||
138 | 1800 0 0 2 40000 31 1 | ||
139 | 1800 0 0 3 40000 32 1 | ||
140 | 1800 0 0 4 40000 33 1 | ||
141 | |||
142 | /* IDSEL 0x4 */ | ||
143 | 2000 0 0 1 40000 33 1 | ||
144 | 2000 0 0 2 40000 34 1 | ||
145 | 2000 0 0 3 40000 31 1 | ||
146 | 2000 0 0 4 40000 32 1 | ||
147 | |||
148 | /* IDSEL 0x5 */ | ||
149 | 2800 0 0 1 40000 32 1 | ||
150 | 2800 0 0 2 40000 33 1 | ||
151 | 2800 0 0 3 40000 34 1 | ||
152 | 2800 0 0 4 40000 31 1 | ||
153 | |||
154 | /* IDSEL 12 */ | ||
155 | 6000 0 0 1 40000 31 1 | ||
156 | 6000 0 0 2 40000 32 1 | ||
157 | 6000 0 0 3 40000 33 1 | ||
158 | 6000 0 0 4 40000 34 1 | ||
159 | |||
160 | /* IDSEL 13 */ | ||
161 | 6800 0 0 1 40000 34 1 | ||
162 | 6800 0 0 2 40000 31 1 | ||
163 | 6800 0 0 3 40000 32 1 | ||
164 | 6800 0 0 4 40000 33 1 | ||
165 | |||
166 | /* IDSEL 14*/ | ||
167 | 7000 0 0 1 40000 33 1 | ||
168 | 7000 0 0 2 40000 34 1 | ||
169 | 7000 0 0 3 40000 31 1 | ||
170 | 7000 0 0 4 40000 32 1 | ||
171 | |||
172 | /* IDSEL 15 */ | ||
173 | 7800 0 0 1 40000 32 1 | ||
174 | 7800 0 0 2 40000 33 1 | ||
175 | 7800 0 0 3 40000 34 1 | ||
176 | 7800 0 0 4 40000 31 1 | ||
177 | |||
178 | /* IDSEL 18 */ | ||
179 | 9000 0 0 1 40000 31 1 | ||
180 | 9000 0 0 2 40000 32 1 | ||
181 | 9000 0 0 3 40000 33 1 | ||
182 | 9000 0 0 4 40000 34 1 | ||
183 | |||
184 | /* IDSEL 19 */ | ||
185 | 9800 0 0 1 40000 34 1 | ||
186 | 9800 0 0 2 40000 31 1 | ||
187 | 9800 0 0 3 40000 32 1 | ||
188 | 9800 0 0 4 40000 33 1 | ||
189 | |||
190 | /* IDSEL 20 */ | ||
191 | a000 0 0 1 40000 33 1 | ||
192 | a000 0 0 2 40000 34 1 | ||
193 | a000 0 0 3 40000 31 1 | ||
194 | a000 0 0 4 40000 32 1 | ||
195 | |||
196 | /* IDSEL 21 */ | ||
197 | a800 0 0 1 40000 32 1 | ||
198 | a800 0 0 2 40000 33 1 | ||
199 | a800 0 0 3 40000 34 1 | ||
200 | a800 0 0 4 40000 31 1>; | ||
201 | |||
202 | interrupt-parent = <40000>; | ||
203 | interrupts = <42 0>; | ||
204 | bus-range = <0 0>; | ||
205 | ranges = <02000000 0 80000000 80000000 0 20000000 | ||
206 | 01000000 0 00000000 e2000000 0 01000000>; | ||
207 | }; | ||
208 | |||
209 | pic@40000 { | ||
210 | linux,phandle = <40000>; | ||
211 | interrupt-controller; | ||
212 | #address-cells = <0>; | ||
213 | #interrupt-cells = <2>; | ||
214 | reg = <40000 20100>; | ||
215 | built-in; | ||
216 | device_type = "open-pic"; | ||
217 | }; | ||
218 | |||
219 | cpm@e0000000 { | ||
220 | linux,phandle = <e0000000>; | ||
221 | #address-cells = <1>; | ||
222 | #size-cells = <1>; | ||
223 | #interrupt-cells = <2>; | ||
224 | device_type = "cpm"; | ||
225 | model = "CPM2"; | ||
226 | ranges = <0 0 c0000>; | ||
227 | reg = <80000 40000>; | ||
228 | command-proc = <919c0>; | ||
229 | brg-frequency = <9d5b340>; | ||
230 | |||
231 | pic@90c00 { | ||
232 | linux,phandle = <90c00>; | ||
233 | interrupt-controller; | ||
234 | #address-cells = <0>; | ||
235 | #interrupt-cells = <2>; | ||
236 | interrupts = <1e 0>; | ||
237 | interrupt-parent = <40000>; | ||
238 | reg = <90c00 80>; | ||
239 | built-in; | ||
240 | device_type = "cpm-pic"; | ||
241 | }; | ||
242 | |||
243 | scc@91a00 { | ||
244 | device_type = "serial"; | ||
245 | compatible = "cpm_uart"; | ||
246 | model = "SCC"; | ||
247 | device-id = <1>; | ||
248 | reg = <91a00 20 88000 100>; | ||
249 | clock-setup = <00ffffff 0>; | ||
250 | rx-clock = <1>; | ||
251 | tx-clock = <1>; | ||
252 | current-speed = <1c200>; | ||
253 | interrupts = <64 1>; | ||
254 | interrupt-parent = <90c00>; | ||
255 | }; | ||
256 | |||
257 | scc@91a20 { | ||
258 | device_type = "serial"; | ||
259 | compatible = "cpm_uart"; | ||
260 | model = "SCC"; | ||
261 | device-id = <2>; | ||
262 | reg = <91a20 20 88100 100>; | ||
263 | clock-setup = <ff00ffff 90000>; | ||
264 | rx-clock = <2>; | ||
265 | tx-clock = <2>; | ||
266 | current-speed = <1c200>; | ||
267 | interrupts = <65 1>; | ||
268 | interrupt-parent = <90c00>; | ||
269 | }; | ||
270 | |||
271 | fcc@91320 { | ||
272 | device_type = "network"; | ||
273 | compatible = "fs_enet"; | ||
274 | model = "FCC"; | ||
275 | device-id = <2>; | ||
276 | reg = <91320 20 88500 100 913a0 30>; | ||
277 | mac-address = [ 00 00 0C 00 02 FD ]; | ||
278 | clock-setup = <ff00ffff 250000>; | ||
279 | rx-clock = <15>; | ||
280 | tx-clock = <16>; | ||
281 | interrupts = <5d 1>; | ||
282 | interrupt-parent = <90c00>; | ||
283 | phy-handle = <2452002>; | ||
284 | }; | ||
285 | |||
286 | fcc@91340 { | ||
287 | device_type = "network"; | ||
288 | compatible = "fs_enet"; | ||
289 | model = "FCC"; | ||
290 | device-id = <3>; | ||
291 | reg = <91340 20 88600 100 913d0 30>; | ||
292 | mac-address = [ 00 00 0C 00 03 FD ]; | ||
293 | clock-setup = <ffff00ff 3700>; | ||
294 | rx-clock = <17>; | ||
295 | tx-clock = <18>; | ||
296 | interrupts = <5e 1>; | ||
297 | interrupt-parent = <90c00>; | ||
298 | phy-handle = <2452003>; | ||
299 | }; | ||
300 | }; | ||
301 | }; | ||
302 | }; | ||
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper new file mode 100755 index 000000000000..eab7318729e9 --- /dev/null +++ b/arch/powerpc/boot/wrapper | |||
@@ -0,0 +1,204 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | # Copyright (C) 2006 Paul Mackerras, IBM Corporation <paulus@samba.org> | ||
4 | # This program may be used under the terms of version 2 of the GNU | ||
5 | # General Public License. | ||
6 | |||
7 | # This script takes a kernel binary and optionally an initrd image | ||
8 | # and/or a device-tree blob, and creates a bootable zImage for a | ||
9 | # given platform. | ||
10 | |||
11 | # Options: | ||
12 | # -o zImage specify output file | ||
13 | # -p platform specify platform (links in $platform.o) | ||
14 | # -i initrd specify initrd file | ||
15 | # -d devtree specify device-tree blob | ||
16 | # -s tree.dts specify device-tree source file (needs dtc installed) | ||
17 | # -c cache $kernel.strip.gz (use if present & newer, else make) | ||
18 | # -C prefix specify command prefix for cross-building tools | ||
19 | # (strip, objcopy, ld) | ||
20 | # -D dir specify directory containing data files used by script | ||
21 | # (default ./arch/powerpc/boot) | ||
22 | # -W dir specify working directory for temporary files (default .) | ||
23 | |||
24 | # defaults | ||
25 | kernel= | ||
26 | ofile=zImage | ||
27 | platform=of | ||
28 | initrd= | ||
29 | dtb= | ||
30 | dts= | ||
31 | cacheit= | ||
32 | |||
33 | # cross-compilation prefix | ||
34 | CROSS= | ||
35 | |||
36 | # directory for object and other files used by this script | ||
37 | object=arch/powerpc/boot | ||
38 | |||
39 | # directory for working files | ||
40 | tmpdir=. | ||
41 | |||
42 | usage() { | ||
43 | echo 'Usage: wrapper [-o output] [-p platform] [-i initrd]' >&2 | ||
44 | echo ' [-d devtree] [-s tree.dts] [-c] [-C cross-prefix]' >&2 | ||
45 | echo ' [-D datadir] [-W workingdir] [vmlinux]' >&2 | ||
46 | exit 1 | ||
47 | } | ||
48 | |||
49 | while [ "$#" -gt 0 ]; do | ||
50 | case "$1" in | ||
51 | -o) | ||
52 | shift | ||
53 | [ "$#" -gt 0 ] || usage | ||
54 | ofile="$1" | ||
55 | ;; | ||
56 | -p) | ||
57 | shift | ||
58 | [ "$#" -gt 0 ] || usage | ||
59 | platform="$1" | ||
60 | ;; | ||
61 | -i) | ||
62 | shift | ||
63 | [ "$#" -gt 0 ] || usage | ||
64 | initrd="$1" | ||
65 | ;; | ||
66 | -d) | ||
67 | shift | ||
68 | [ "$#" -gt 0 ] || usage | ||
69 | dtb="$1" | ||
70 | ;; | ||
71 | -s) | ||
72 | shift | ||
73 | [ "$#" -gt 0 ] || usage | ||
74 | dts="$1" | ||
75 | ;; | ||
76 | -c) | ||
77 | cacheit=y | ||
78 | ;; | ||
79 | -C) | ||
80 | shift | ||
81 | [ "$#" -gt 0 ] || usage | ||
82 | CROSS="$1" | ||
83 | ;; | ||
84 | -D) | ||
85 | shift | ||
86 | [ "$#" -gt 0 ] || usage | ||
87 | object="$1" | ||
88 | ;; | ||
89 | -W) | ||
90 | shift | ||
91 | [ "$#" -gt 0 ] || usage | ||
92 | tmpdir="$1" | ||
93 | ;; | ||
94 | -?) | ||
95 | usage | ||
96 | ;; | ||
97 | *) | ||
98 | [ -z "$kernel" ] || usage | ||
99 | kernel="$1" | ||
100 | ;; | ||
101 | esac | ||
102 | shift | ||
103 | done | ||
104 | |||
105 | if [ -n "$dts" ]; then | ||
106 | if [ -z "$dtb" ]; then | ||
107 | dtb="$platform.dtb" | ||
108 | fi | ||
109 | dtc -O dtb -o "$dtb" -b 0 -V 16 "$dts" || exit 1 | ||
110 | fi | ||
111 | |||
112 | if [ -z "$kernel" ]; then | ||
113 | kernel=vmlinux | ||
114 | fi | ||
115 | |||
116 | platformo=$object/"$platform".o | ||
117 | lds=$object/zImage.lds | ||
118 | ext=strip | ||
119 | objflags=-S | ||
120 | tmp=$tmpdir/zImage.$$.o | ||
121 | ksection=.kernel:vmlinux.strip | ||
122 | isection=.kernel:initrd | ||
123 | |||
124 | case "$platform" in | ||
125 | pmac|pseries|chrp) | ||
126 | platformo=$object/of.o | ||
127 | ;; | ||
128 | pmaccoff) | ||
129 | platformo=$object/of.o | ||
130 | lds=$object/zImage.coff.lds | ||
131 | ;; | ||
132 | miboot|uboot) | ||
133 | # miboot and U-boot want just the bare bits, not an ELF binary | ||
134 | ext=bin | ||
135 | objflags="-O binary" | ||
136 | tmp="$ofile" | ||
137 | ksection=image | ||
138 | isection=initrd | ||
139 | ;; | ||
140 | esac | ||
141 | |||
142 | vmz="$tmpdir/`basename \"$kernel\"`.$ext" | ||
143 | if [ -z "$cacheit" -o ! -f "$vmz.gz" -o "$vmz.gz" -ot "$kernel" ]; then | ||
144 | ${CROSS}objcopy $objflags "$kernel" "$vmz.$$" | ||
145 | gzip -f -9 "$vmz.$$" | ||
146 | if [ -n "$cacheit" ]; then | ||
147 | mv -f "$vmz.$$.gz" "$vmz.gz" | ||
148 | else | ||
149 | vmz="$vmz.$$" | ||
150 | fi | ||
151 | fi | ||
152 | |||
153 | case "$platform" in | ||
154 | uboot) | ||
155 | rm -f "$ofile" | ||
156 | version=`${CROSS}strings "$kernel" | grep '^Linux version [-0-9.]' | \ | ||
157 | cut -d' ' -f3` | ||
158 | if [ -n "$version" ]; then | ||
159 | version="-n Linux-$version" | ||
160 | fi | ||
161 | mkimage -A ppc -O linux -T kernel -C gzip -a 00000000 -e 00000000 \ | ||
162 | $version -d "$vmz.gz" "$ofile" | ||
163 | if [ -z "$cacheit" ]; then | ||
164 | rm -f $vmz.gz | ||
165 | fi | ||
166 | exit 0 | ||
167 | ;; | ||
168 | esac | ||
169 | |||
170 | addsec() { | ||
171 | ${CROSS}objcopy $4 $1 \ | ||
172 | --add-section=$3="$2" \ | ||
173 | --set-section-flags=$3=contents,alloc,load,readonly,data | ||
174 | } | ||
175 | |||
176 | addsec $tmp "$vmz.gz" $ksection $object/empty.o | ||
177 | if [ -z "$cacheit" ]; then | ||
178 | rm -f "$vmz.gz" | ||
179 | fi | ||
180 | |||
181 | if [ -n "$initrd" ]; then | ||
182 | addsec $tmp "$initrd" initrd | ||
183 | fi | ||
184 | |||
185 | if [ -n "$dtb" ]; then | ||
186 | addsec $tmp "$dtb" dtb | ||
187 | fi | ||
188 | |||
189 | if [ "$platform" != "miboot" ]; then | ||
190 | ${CROSS}ld -m elf32ppc -T $lds -o "$ofile" \ | ||
191 | $object/crt0.o $platformo $tmp $object/wrapper.a | ||
192 | rm $tmp | ||
193 | fi | ||
194 | |||
195 | # post-processing needed for some platforms | ||
196 | case "$platform" in | ||
197 | pseries|chrp) | ||
198 | $object/addnote "$ofile" | ||
199 | ;; | ||
200 | pmaccoff) | ||
201 | ${CROSS}objcopy -O aixcoff-rs6000 --set-start 0x500000 "$ofile" | ||
202 | $object/hack-coff "$ofile" | ||
203 | ;; | ||
204 | esac | ||
diff --git a/arch/powerpc/boot/zImage.coff.lds b/arch/powerpc/boot/zImage.coff.lds.S index 6016251a1a2c..6016251a1a2c 100644 --- a/arch/powerpc/boot/zImage.coff.lds +++ b/arch/powerpc/boot/zImage.coff.lds.S | |||
diff --git a/arch/powerpc/boot/zImage.lds b/arch/powerpc/boot/zImage.lds.S index 4b6bb3ffe3dc..4b6bb3ffe3dc 100644 --- a/arch/powerpc/boot/zImage.lds +++ b/arch/powerpc/boot/zImage.lds.S | |||
diff --git a/arch/powerpc/configs/chrp32_defconfig b/arch/powerpc/configs/chrp32_defconfig index bbf2b5f8a8cb..fee72f8a2fb7 100644 --- a/arch/powerpc/configs/chrp32_defconfig +++ b/arch/powerpc/configs/chrp32_defconfig | |||
@@ -492,7 +492,7 @@ CONFIG_SCSI_SPI_ATTRS=y | |||
492 | # CONFIG_MEGARAID_NEWGEN is not set | 492 | # CONFIG_MEGARAID_NEWGEN is not set |
493 | # CONFIG_MEGARAID_LEGACY is not set | 493 | # CONFIG_MEGARAID_LEGACY is not set |
494 | # CONFIG_MEGARAID_SAS is not set | 494 | # CONFIG_MEGARAID_SAS is not set |
495 | # CONFIG_SCSI_SATA is not set | 495 | # CONFIG_ATA is not set |
496 | # CONFIG_SCSI_HPTIOP is not set | 496 | # CONFIG_SCSI_HPTIOP is not set |
497 | # CONFIG_SCSI_BUSLOGIC is not set | 497 | # CONFIG_SCSI_BUSLOGIC is not set |
498 | # CONFIG_SCSI_DMX3191D is not set | 498 | # CONFIG_SCSI_DMX3191D is not set |
diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig index 4b9c2ed925f5..92d0a9dd0b8f 100644 --- a/arch/powerpc/configs/g5_defconfig +++ b/arch/powerpc/configs/g5_defconfig | |||
@@ -490,23 +490,23 @@ CONFIG_SCSI_SPI_ATTRS=y | |||
490 | # CONFIG_MEGARAID_NEWGEN is not set | 490 | # CONFIG_MEGARAID_NEWGEN is not set |
491 | # CONFIG_MEGARAID_LEGACY is not set | 491 | # CONFIG_MEGARAID_LEGACY is not set |
492 | # CONFIG_MEGARAID_SAS is not set | 492 | # CONFIG_MEGARAID_SAS is not set |
493 | CONFIG_SCSI_SATA=y | 493 | CONFIG_ATA=y |
494 | # CONFIG_SCSI_SATA_AHCI is not set | 494 | # CONFIG_SATA_AHCI is not set |
495 | CONFIG_SCSI_SATA_SVW=y | 495 | CONFIG_SATA_SVW=y |
496 | # CONFIG_SCSI_ATA_PIIX is not set | 496 | # CONFIG_SCSI_ATA_PIIX is not set |
497 | # CONFIG_SCSI_SATA_MV is not set | 497 | # CONFIG_SATA_MV is not set |
498 | # CONFIG_SCSI_SATA_NV is not set | 498 | # CONFIG_SATA_NV is not set |
499 | # CONFIG_SCSI_PDC_ADMA is not set | 499 | # CONFIG_SCSI_PDC_ADMA is not set |
500 | # CONFIG_SCSI_HPTIOP is not set | 500 | # CONFIG_SCSI_HPTIOP is not set |
501 | # CONFIG_SCSI_SATA_QSTOR is not set | 501 | # CONFIG_SATA_QSTOR is not set |
502 | # CONFIG_SCSI_SATA_PROMISE is not set | 502 | # CONFIG_SATA_PROMISE is not set |
503 | # CONFIG_SCSI_SATA_SX4 is not set | 503 | # CONFIG_SATA_SX4 is not set |
504 | # CONFIG_SCSI_SATA_SIL is not set | 504 | # CONFIG_SATA_SIL is not set |
505 | # CONFIG_SCSI_SATA_SIL24 is not set | 505 | # CONFIG_SATA_SIL24 is not set |
506 | # CONFIG_SCSI_SATA_SIS is not set | 506 | # CONFIG_SATA_SIS is not set |
507 | # CONFIG_SCSI_SATA_ULI is not set | 507 | # CONFIG_SATA_ULI is not set |
508 | # CONFIG_SCSI_SATA_VIA is not set | 508 | # CONFIG_SATA_VIA is not set |
509 | # CONFIG_SCSI_SATA_VITESSE is not set | 509 | # CONFIG_SATA_VITESSE is not set |
510 | # CONFIG_SCSI_BUSLOGIC is not set | 510 | # CONFIG_SCSI_BUSLOGIC is not set |
511 | # CONFIG_SCSI_DMX3191D is not set | 511 | # CONFIG_SCSI_DMX3191D is not set |
512 | # CONFIG_SCSI_EATA is not set | 512 | # CONFIG_SCSI_EATA is not set |
diff --git a/arch/powerpc/configs/iseries_defconfig b/arch/powerpc/configs/iseries_defconfig index eb0885ea0731..d58f82f836f8 100644 --- a/arch/powerpc/configs/iseries_defconfig +++ b/arch/powerpc/configs/iseries_defconfig | |||
@@ -475,7 +475,7 @@ CONFIG_SCSI_FC_ATTRS=y | |||
475 | # CONFIG_MEGARAID_NEWGEN is not set | 475 | # CONFIG_MEGARAID_NEWGEN is not set |
476 | # CONFIG_MEGARAID_LEGACY is not set | 476 | # CONFIG_MEGARAID_LEGACY is not set |
477 | # CONFIG_MEGARAID_SAS is not set | 477 | # CONFIG_MEGARAID_SAS is not set |
478 | # CONFIG_SCSI_SATA is not set | 478 | # CONFIG_ATA is not set |
479 | # CONFIG_SCSI_HPTIOP is not set | 479 | # CONFIG_SCSI_HPTIOP is not set |
480 | # CONFIG_SCSI_BUSLOGIC is not set | 480 | # CONFIG_SCSI_BUSLOGIC is not set |
481 | # CONFIG_SCSI_DMX3191D is not set | 481 | # CONFIG_SCSI_DMX3191D is not set |
diff --git a/arch/powerpc/configs/mpc7448_hpc2_defconfig b/arch/powerpc/configs/mpc7448_hpc2_defconfig index 719fba4eb421..d1811e754518 100644 --- a/arch/powerpc/configs/mpc7448_hpc2_defconfig +++ b/arch/powerpc/configs/mpc7448_hpc2_defconfig | |||
@@ -413,23 +413,23 @@ CONFIG_BLK_DEV_SD=y | |||
413 | # CONFIG_MEGARAID_NEWGEN is not set | 413 | # CONFIG_MEGARAID_NEWGEN is not set |
414 | # CONFIG_MEGARAID_LEGACY is not set | 414 | # CONFIG_MEGARAID_LEGACY is not set |
415 | # CONFIG_MEGARAID_SAS is not set | 415 | # CONFIG_MEGARAID_SAS is not set |
416 | CONFIG_SCSI_SATA=y | 416 | CONFIG_ATA=y |
417 | # CONFIG_SCSI_SATA_AHCI is not set | 417 | # CONFIG_SATA_AHCI is not set |
418 | # CONFIG_SCSI_SATA_SVW is not set | 418 | # CONFIG_SATA_SVW is not set |
419 | # CONFIG_SCSI_ATA_PIIX is not set | 419 | # CONFIG_SCSI_ATA_PIIX is not set |
420 | CONFIG_SCSI_SATA_MV=y | 420 | CONFIG_SATA_MV=y |
421 | # CONFIG_SCSI_SATA_NV is not set | 421 | # CONFIG_SATA_NV is not set |
422 | # CONFIG_SCSI_PDC_ADMA is not set | 422 | # CONFIG_SCSI_PDC_ADMA is not set |
423 | # CONFIG_SCSI_HPTIOP is not set | 423 | # CONFIG_SCSI_HPTIOP is not set |
424 | # CONFIG_SCSI_SATA_QSTOR is not set | 424 | # CONFIG_SATA_QSTOR is not set |
425 | # CONFIG_SCSI_SATA_PROMISE is not set | 425 | # CONFIG_SATA_PROMISE is not set |
426 | # CONFIG_SCSI_SATA_SX4 is not set | 426 | # CONFIG_SATA_SX4 is not set |
427 | # CONFIG_SCSI_SATA_SIL is not set | 427 | # CONFIG_SATA_SIL is not set |
428 | # CONFIG_SCSI_SATA_SIL24 is not set | 428 | # CONFIG_SATA_SIL24 is not set |
429 | # CONFIG_SCSI_SATA_SIS is not set | 429 | # CONFIG_SATA_SIS is not set |
430 | # CONFIG_SCSI_SATA_ULI is not set | 430 | # CONFIG_SATA_ULI is not set |
431 | # CONFIG_SCSI_SATA_VIA is not set | 431 | # CONFIG_SATA_VIA is not set |
432 | # CONFIG_SCSI_SATA_VITESSE is not set | 432 | # CONFIG_SATA_VITESSE is not set |
433 | # CONFIG_SCSI_BUSLOGIC is not set | 433 | # CONFIG_SCSI_BUSLOGIC is not set |
434 | # CONFIG_SCSI_DMX3191D is not set | 434 | # CONFIG_SCSI_DMX3191D is not set |
435 | # CONFIG_SCSI_EATA is not set | 435 | # CONFIG_SCSI_EATA is not set |
diff --git a/arch/powerpc/configs/mpc834x_itx_defconfig b/arch/powerpc/configs/mpc834x_itx_defconfig index 8da6a47f0339..cd3535e1a095 100644 --- a/arch/powerpc/configs/mpc834x_itx_defconfig +++ b/arch/powerpc/configs/mpc834x_itx_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.18-rc6 | 3 | # Linux kernel version: 2.6.18 |
4 | # Sun Sep 10 10:28:05 2006 | 4 | # Mon Sep 25 19:41:14 2006 |
5 | # | 5 | # |
6 | # CONFIG_PPC64 is not set | 6 | # CONFIG_PPC64 is not set |
7 | CONFIG_PPC32=y | 7 | CONFIG_PPC32=y |
@@ -21,6 +21,7 @@ CONFIG_ARCH_MAY_HAVE_PC_FDC=y | |||
21 | CONFIG_PPC_OF=y | 21 | CONFIG_PPC_OF=y |
22 | CONFIG_PPC_UDBG_16550=y | 22 | CONFIG_PPC_UDBG_16550=y |
23 | # CONFIG_GENERIC_TBSYNC is not set | 23 | # CONFIG_GENERIC_TBSYNC is not set |
24 | CONFIG_AUDIT_ARCH=y | ||
24 | CONFIG_DEFAULT_UIMAGE=y | 25 | CONFIG_DEFAULT_UIMAGE=y |
25 | 26 | ||
26 | # | 27 | # |
@@ -61,25 +62,25 @@ CONFIG_SYSVIPC=y | |||
61 | # CONFIG_POSIX_MQUEUE is not set | 62 | # CONFIG_POSIX_MQUEUE is not set |
62 | # CONFIG_BSD_PROCESS_ACCT is not set | 63 | # CONFIG_BSD_PROCESS_ACCT is not set |
63 | # CONFIG_TASKSTATS is not set | 64 | # CONFIG_TASKSTATS is not set |
64 | CONFIG_SYSCTL=y | ||
65 | # CONFIG_AUDIT is not set | 65 | # CONFIG_AUDIT is not set |
66 | # CONFIG_IKCONFIG is not set | 66 | # CONFIG_IKCONFIG is not set |
67 | # CONFIG_RELAY is not set | 67 | # CONFIG_RELAY is not set |
68 | CONFIG_INITRAMFS_SOURCE="" | 68 | CONFIG_INITRAMFS_SOURCE="" |
69 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | 69 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set |
70 | CONFIG_EMBEDDED=y | 70 | CONFIG_EMBEDDED=y |
71 | CONFIG_SYSCTL=y | ||
71 | # CONFIG_KALLSYMS is not set | 72 | # CONFIG_KALLSYMS is not set |
72 | CONFIG_HOTPLUG=y | 73 | CONFIG_HOTPLUG=y |
73 | CONFIG_PRINTK=y | 74 | CONFIG_PRINTK=y |
74 | CONFIG_BUG=y | 75 | CONFIG_BUG=y |
75 | CONFIG_ELF_CORE=y | 76 | CONFIG_ELF_CORE=y |
76 | CONFIG_BASE_FULL=y | 77 | CONFIG_BASE_FULL=y |
77 | CONFIG_RT_MUTEXES=y | ||
78 | CONFIG_FUTEX=y | 78 | CONFIG_FUTEX=y |
79 | # CONFIG_EPOLL is not set | 79 | # CONFIG_EPOLL is not set |
80 | CONFIG_SHMEM=y | 80 | CONFIG_SHMEM=y |
81 | CONFIG_SLAB=y | 81 | CONFIG_SLAB=y |
82 | CONFIG_VM_EVENT_COUNTERS=y | 82 | CONFIG_VM_EVENT_COUNTERS=y |
83 | CONFIG_RT_MUTEXES=y | ||
83 | # CONFIG_TINY_SHMEM is not set | 84 | # CONFIG_TINY_SHMEM is not set |
84 | CONFIG_BASE_SMALL=0 | 85 | CONFIG_BASE_SMALL=0 |
85 | # CONFIG_SLOB is not set | 86 | # CONFIG_SLOB is not set |
@@ -259,7 +260,6 @@ CONFIG_TCP_CONG_BIC=y | |||
259 | # CONFIG_ATALK is not set | 260 | # CONFIG_ATALK is not set |
260 | # CONFIG_X25 is not set | 261 | # CONFIG_X25 is not set |
261 | # CONFIG_LAPB is not set | 262 | # CONFIG_LAPB is not set |
262 | # CONFIG_NET_DIVERT is not set | ||
263 | # CONFIG_ECONET is not set | 263 | # CONFIG_ECONET is not set |
264 | # CONFIG_WAN_ROUTER is not set | 264 | # CONFIG_WAN_ROUTER is not set |
265 | 265 | ||
@@ -313,6 +313,7 @@ CONFIG_MTD_CHAR=y | |||
313 | # CONFIG_NFTL is not set | 313 | # CONFIG_NFTL is not set |
314 | # CONFIG_INFTL is not set | 314 | # CONFIG_INFTL is not set |
315 | # CONFIG_RFD_FTL is not set | 315 | # CONFIG_RFD_FTL is not set |
316 | # CONFIG_SSFDC is not set | ||
316 | 317 | ||
317 | # | 318 | # |
318 | # RAM/ROM/Flash chip drivers | 319 | # RAM/ROM/Flash chip drivers |
@@ -464,23 +465,23 @@ CONFIG_SCSI_SPI_ATTRS=y | |||
464 | # CONFIG_MEGARAID_NEWGEN is not set | 465 | # CONFIG_MEGARAID_NEWGEN is not set |
465 | # CONFIG_MEGARAID_LEGACY is not set | 466 | # CONFIG_MEGARAID_LEGACY is not set |
466 | # CONFIG_MEGARAID_SAS is not set | 467 | # CONFIG_MEGARAID_SAS is not set |
467 | CONFIG_SCSI_SATA=y | 468 | CONFIG_ATA=y |
468 | # CONFIG_SCSI_SATA_AHCI is not set | 469 | # CONFIG_SATA_AHCI is not set |
469 | # CONFIG_SCSI_SATA_SVW is not set | 470 | # CONFIG_SATA_SVW is not set |
470 | # CONFIG_SCSI_ATA_PIIX is not set | 471 | # CONFIG_SCSI_ATA_PIIX is not set |
471 | # CONFIG_SCSI_SATA_MV is not set | 472 | # CONFIG_SATA_MV is not set |
472 | # CONFIG_SCSI_SATA_NV is not set | 473 | # CONFIG_SATA_NV is not set |
473 | # CONFIG_SCSI_PDC_ADMA is not set | 474 | # CONFIG_SCSI_PDC_ADMA is not set |
474 | # CONFIG_SCSI_HPTIOP is not set | 475 | # CONFIG_SCSI_HPTIOP is not set |
475 | # CONFIG_SCSI_SATA_QSTOR is not set | 476 | # CONFIG_SATA_QSTOR is not set |
476 | # CONFIG_SCSI_SATA_PROMISE is not set | 477 | # CONFIG_SATA_PROMISE is not set |
477 | # CONFIG_SCSI_SATA_SX4 is not set | 478 | # CONFIG_SATA_SX4 is not set |
478 | CONFIG_SCSI_SATA_SIL=y | 479 | CONFIG_SATA_SIL=y |
479 | # CONFIG_SCSI_SATA_SIL24 is not set | 480 | # CONFIG_SATA_SIL24 is not set |
480 | # CONFIG_SCSI_SATA_SIS is not set | 481 | # CONFIG_SATA_SIS is not set |
481 | # CONFIG_SCSI_SATA_ULI is not set | 482 | # CONFIG_SATA_ULI is not set |
482 | # CONFIG_SCSI_SATA_VIA is not set | 483 | # CONFIG_SATA_VIA is not set |
483 | # CONFIG_SCSI_SATA_VITESSE is not set | 484 | # CONFIG_SATA_VITESSE is not set |
484 | # CONFIG_SCSI_BUSLOGIC is not set | 485 | # CONFIG_SCSI_BUSLOGIC is not set |
485 | # CONFIG_SCSI_DMX3191D is not set | 486 | # CONFIG_SCSI_DMX3191D is not set |
486 | # CONFIG_SCSI_EATA is not set | 487 | # CONFIG_SCSI_EATA is not set |
@@ -1277,11 +1278,11 @@ CONFIG_PLIST=y | |||
1277 | # | 1278 | # |
1278 | # Kernel hacking | 1279 | # Kernel hacking |
1279 | # | 1280 | # |
1280 | CONFIG_PRINTK_TIME=y | 1281 | # CONFIG_PRINTK_TIME is not set |
1281 | # CONFIG_MAGIC_SYSRQ is not set | 1282 | # CONFIG_MAGIC_SYSRQ is not set |
1282 | # CONFIG_UNUSED_SYMBOLS is not set | 1283 | # CONFIG_UNUSED_SYMBOLS is not set |
1283 | CONFIG_DEBUG_KERNEL=y | 1284 | CONFIG_DEBUG_KERNEL=y |
1284 | CONFIG_LOG_BUF_SHIFT=17 | 1285 | CONFIG_LOG_BUF_SHIFT=14 |
1285 | CONFIG_DETECT_SOFTLOCKUP=y | 1286 | CONFIG_DETECT_SOFTLOCKUP=y |
1286 | # CONFIG_SCHEDSTATS is not set | 1287 | # CONFIG_SCHEDSTATS is not set |
1287 | # CONFIG_DEBUG_SLAB is not set | 1288 | # CONFIG_DEBUG_SLAB is not set |
@@ -1293,15 +1294,15 @@ CONFIG_DETECT_SOFTLOCKUP=y | |||
1293 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | 1294 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set |
1294 | # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set | 1295 | # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set |
1295 | # CONFIG_DEBUG_KOBJECT is not set | 1296 | # CONFIG_DEBUG_KOBJECT is not set |
1296 | CONFIG_DEBUG_INFO=y | 1297 | # CONFIG_DEBUG_INFO is not set |
1297 | # CONFIG_DEBUG_FS is not set | 1298 | # CONFIG_DEBUG_FS is not set |
1298 | # CONFIG_DEBUG_VM is not set | 1299 | # CONFIG_DEBUG_VM is not set |
1299 | CONFIG_FORCED_INLINING=y | 1300 | CONFIG_FORCED_INLINING=y |
1300 | # CONFIG_RCU_TORTURE_TEST is not set | 1301 | # CONFIG_RCU_TORTURE_TEST is not set |
1301 | # CONFIG_DEBUGGER is not set | 1302 | # CONFIG_DEBUGGER is not set |
1302 | # CONFIG_BDI_SWITCH is not set | 1303 | # CONFIG_BDI_SWITCH is not set |
1303 | CONFIG_BOOTX_TEXT=y | 1304 | # CONFIG_BOOTX_TEXT is not set |
1304 | CONFIG_SERIAL_TEXT_DEBUG=y | 1305 | # CONFIG_SERIAL_TEXT_DEBUG is not set |
1305 | # CONFIG_PPC_EARLY_DEBUG is not set | 1306 | # CONFIG_PPC_EARLY_DEBUG is not set |
1306 | 1307 | ||
1307 | # | 1308 | # |
@@ -1314,6 +1315,8 @@ CONFIG_SERIAL_TEXT_DEBUG=y | |||
1314 | # Cryptographic options | 1315 | # Cryptographic options |
1315 | # | 1316 | # |
1316 | CONFIG_CRYPTO=y | 1317 | CONFIG_CRYPTO=y |
1318 | CONFIG_CRYPTO_ALGAPI=y | ||
1319 | # CONFIG_CRYPTO_MANAGER is not set | ||
1317 | # CONFIG_CRYPTO_HMAC is not set | 1320 | # CONFIG_CRYPTO_HMAC is not set |
1318 | # CONFIG_CRYPTO_NULL is not set | 1321 | # CONFIG_CRYPTO_NULL is not set |
1319 | # CONFIG_CRYPTO_MD4 is not set | 1322 | # CONFIG_CRYPTO_MD4 is not set |
@@ -1323,6 +1326,8 @@ CONFIG_CRYPTO_MD5=y | |||
1323 | # CONFIG_CRYPTO_SHA512 is not set | 1326 | # CONFIG_CRYPTO_SHA512 is not set |
1324 | # CONFIG_CRYPTO_WP512 is not set | 1327 | # CONFIG_CRYPTO_WP512 is not set |
1325 | # CONFIG_CRYPTO_TGR192 is not set | 1328 | # CONFIG_CRYPTO_TGR192 is not set |
1329 | # CONFIG_CRYPTO_ECB is not set | ||
1330 | # CONFIG_CRYPTO_CBC is not set | ||
1326 | CONFIG_CRYPTO_DES=y | 1331 | CONFIG_CRYPTO_DES=y |
1327 | # CONFIG_CRYPTO_BLOWFISH is not set | 1332 | # CONFIG_CRYPTO_BLOWFISH is not set |
1328 | # CONFIG_CRYPTO_TWOFISH is not set | 1333 | # CONFIG_CRYPTO_TWOFISH is not set |
diff --git a/arch/powerpc/configs/mpc8560_ads_defconfig b/arch/powerpc/configs/mpc8560_ads_defconfig new file mode 100644 index 000000000000..ddc2a7b07ba0 --- /dev/null +++ b/arch/powerpc/configs/mpc8560_ads_defconfig | |||
@@ -0,0 +1,854 @@ | |||
1 | # | ||
2 | # Automatically generated make config: don't edit | ||
3 | # Linux kernel version: 2.6.18-rc4 | ||
4 | # Fri Aug 11 16:45:05 2006 | ||
5 | # | ||
6 | # CONFIG_PPC64 is not set | ||
7 | CONFIG_PPC32=y | ||
8 | CONFIG_PPC_MERGE=y | ||
9 | CONFIG_MMU=y | ||
10 | CONFIG_GENERIC_HARDIRQS=y | ||
11 | CONFIG_IRQ_PER_CPU=y | ||
12 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | ||
13 | CONFIG_GENERIC_HWEIGHT=y | ||
14 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
15 | CONFIG_GENERIC_FIND_NEXT_BIT=y | ||
16 | CONFIG_PPC=y | ||
17 | CONFIG_EARLY_PRINTK=y | ||
18 | CONFIG_GENERIC_NVRAM=y | ||
19 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y | ||
20 | CONFIG_ARCH_MAY_HAVE_PC_FDC=y | ||
21 | CONFIG_PPC_OF=y | ||
22 | # CONFIG_PPC_UDBG_16550 is not set | ||
23 | # CONFIG_GENERIC_TBSYNC is not set | ||
24 | CONFIG_DEFAULT_UIMAGE=y | ||
25 | |||
26 | # | ||
27 | # Processor support | ||
28 | # | ||
29 | # CONFIG_CLASSIC32 is not set | ||
30 | # CONFIG_PPC_52xx is not set | ||
31 | # CONFIG_PPC_82xx is not set | ||
32 | # CONFIG_PPC_83xx is not set | ||
33 | CONFIG_PPC_85xx=y | ||
34 | # CONFIG_PPC_86xx is not set | ||
35 | # CONFIG_40x is not set | ||
36 | # CONFIG_44x is not set | ||
37 | # CONFIG_8xx is not set | ||
38 | # CONFIG_E200 is not set | ||
39 | CONFIG_85xx=y | ||
40 | CONFIG_E500=y | ||
41 | CONFIG_BOOKE=y | ||
42 | CONFIG_FSL_BOOKE=y | ||
43 | # CONFIG_PHYS_64BIT is not set | ||
44 | CONFIG_SPE=y | ||
45 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | ||
46 | |||
47 | # | ||
48 | # Code maturity level options | ||
49 | # | ||
50 | CONFIG_EXPERIMENTAL=y | ||
51 | CONFIG_BROKEN_ON_SMP=y | ||
52 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
53 | |||
54 | # | ||
55 | # General setup | ||
56 | # | ||
57 | CONFIG_LOCALVERSION="" | ||
58 | CONFIG_LOCALVERSION_AUTO=y | ||
59 | CONFIG_SWAP=y | ||
60 | CONFIG_SYSVIPC=y | ||
61 | # CONFIG_POSIX_MQUEUE is not set | ||
62 | # CONFIG_BSD_PROCESS_ACCT is not set | ||
63 | # CONFIG_TASKSTATS is not set | ||
64 | CONFIG_SYSCTL=y | ||
65 | # CONFIG_AUDIT is not set | ||
66 | # CONFIG_IKCONFIG is not set | ||
67 | # CONFIG_RELAY is not set | ||
68 | CONFIG_INITRAMFS_SOURCE="" | ||
69 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
70 | CONFIG_EMBEDDED=y | ||
71 | CONFIG_KALLSYMS=y | ||
72 | # CONFIG_KALLSYMS_ALL is not set | ||
73 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
74 | CONFIG_HOTPLUG=y | ||
75 | CONFIG_PRINTK=y | ||
76 | CONFIG_BUG=y | ||
77 | CONFIG_ELF_CORE=y | ||
78 | CONFIG_BASE_FULL=y | ||
79 | CONFIG_RT_MUTEXES=y | ||
80 | CONFIG_FUTEX=y | ||
81 | CONFIG_EPOLL=y | ||
82 | CONFIG_SHMEM=y | ||
83 | CONFIG_SLAB=y | ||
84 | CONFIG_VM_EVENT_COUNTERS=y | ||
85 | # CONFIG_TINY_SHMEM is not set | ||
86 | CONFIG_BASE_SMALL=0 | ||
87 | # CONFIG_SLOB is not set | ||
88 | |||
89 | # | ||
90 | # Loadable module support | ||
91 | # | ||
92 | # CONFIG_MODULES is not set | ||
93 | |||
94 | # | ||
95 | # Block layer | ||
96 | # | ||
97 | # CONFIG_LBD is not set | ||
98 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
99 | # CONFIG_LSF is not set | ||
100 | |||
101 | # | ||
102 | # IO Schedulers | ||
103 | # | ||
104 | CONFIG_IOSCHED_NOOP=y | ||
105 | CONFIG_IOSCHED_AS=y | ||
106 | CONFIG_IOSCHED_DEADLINE=y | ||
107 | CONFIG_IOSCHED_CFQ=y | ||
108 | CONFIG_DEFAULT_AS=y | ||
109 | # CONFIG_DEFAULT_DEADLINE is not set | ||
110 | # CONFIG_DEFAULT_CFQ is not set | ||
111 | # CONFIG_DEFAULT_NOOP is not set | ||
112 | CONFIG_DEFAULT_IOSCHED="anticipatory" | ||
113 | CONFIG_MPIC=y | ||
114 | CONFIG_CPM2=y | ||
115 | # CONFIG_WANT_EARLY_SERIAL is not set | ||
116 | |||
117 | # | ||
118 | # Platform support | ||
119 | # | ||
120 | # CONFIG_MPC8540_ADS is not set | ||
121 | CONFIG_MPC8560_ADS=y | ||
122 | # CONFIG_MPC85xx_CDS is not set | ||
123 | CONFIG_MPC8560=y | ||
124 | CONFIG_PPC_INDIRECT_PCI_BE=y | ||
125 | |||
126 | # | ||
127 | # Kernel options | ||
128 | # | ||
129 | # CONFIG_HIGHMEM is not set | ||
130 | # CONFIG_HZ_100 is not set | ||
131 | CONFIG_HZ_250=y | ||
132 | # CONFIG_HZ_1000 is not set | ||
133 | CONFIG_HZ=250 | ||
134 | CONFIG_PREEMPT_NONE=y | ||
135 | # CONFIG_PREEMPT_VOLUNTARY is not set | ||
136 | # CONFIG_PREEMPT is not set | ||
137 | CONFIG_BINFMT_ELF=y | ||
138 | CONFIG_BINFMT_MISC=y | ||
139 | # CONFIG_MATH_EMULATION is not set | ||
140 | CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y | ||
141 | # CONFIG_PC_KEYBOARD is not set | ||
142 | CONFIG_ARCH_FLATMEM_ENABLE=y | ||
143 | CONFIG_SELECT_MEMORY_MODEL=y | ||
144 | CONFIG_FLATMEM_MANUAL=y | ||
145 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
146 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
147 | CONFIG_FLATMEM=y | ||
148 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
149 | # CONFIG_SPARSEMEM_STATIC is not set | ||
150 | CONFIG_SPLIT_PTLOCK_CPUS=4 | ||
151 | # CONFIG_RESOURCES_64BIT is not set | ||
152 | # CONFIG_PROC_DEVICETREE is not set | ||
153 | # CONFIG_CMDLINE_BOOL is not set | ||
154 | # CONFIG_PM is not set | ||
155 | # CONFIG_SOFTWARE_SUSPEND is not set | ||
156 | # CONFIG_SECCOMP is not set | ||
157 | CONFIG_ISA_DMA_API=y | ||
158 | |||
159 | # | ||
160 | # Bus options | ||
161 | # | ||
162 | # CONFIG_PPC_I8259 is not set | ||
163 | CONFIG_PPC_INDIRECT_PCI=y | ||
164 | CONFIG_FSL_SOC=y | ||
165 | CONFIG_PCI=y | ||
166 | CONFIG_PCI_DOMAINS=y | ||
167 | # CONFIG_PCIEPORTBUS is not set | ||
168 | CONFIG_PCI_DEBUG=y | ||
169 | |||
170 | # | ||
171 | # PCCARD (PCMCIA/CardBus) support | ||
172 | # | ||
173 | # CONFIG_PCCARD is not set | ||
174 | |||
175 | # | ||
176 | # PCI Hotplug Support | ||
177 | # | ||
178 | # CONFIG_HOTPLUG_PCI is not set | ||
179 | |||
180 | # | ||
181 | # Advanced setup | ||
182 | # | ||
183 | # CONFIG_ADVANCED_OPTIONS is not set | ||
184 | |||
185 | # | ||
186 | # Default settings for advanced configuration options are used | ||
187 | # | ||
188 | CONFIG_HIGHMEM_START=0xfe000000 | ||
189 | CONFIG_LOWMEM_SIZE=0x30000000 | ||
190 | CONFIG_KERNEL_START=0xc0000000 | ||
191 | CONFIG_TASK_SIZE=0x80000000 | ||
192 | CONFIG_BOOT_LOAD=0x00800000 | ||
193 | |||
194 | # | ||
195 | # Networking | ||
196 | # | ||
197 | CONFIG_NET=y | ||
198 | |||
199 | # | ||
200 | # Networking options | ||
201 | # | ||
202 | # CONFIG_NETDEBUG is not set | ||
203 | CONFIG_PACKET=y | ||
204 | # CONFIG_PACKET_MMAP is not set | ||
205 | CONFIG_UNIX=y | ||
206 | CONFIG_XFRM=y | ||
207 | # CONFIG_XFRM_USER is not set | ||
208 | # CONFIG_NET_KEY is not set | ||
209 | CONFIG_INET=y | ||
210 | CONFIG_IP_MULTICAST=y | ||
211 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
212 | CONFIG_IP_FIB_HASH=y | ||
213 | CONFIG_IP_PNP=y | ||
214 | CONFIG_IP_PNP_DHCP=y | ||
215 | CONFIG_IP_PNP_BOOTP=y | ||
216 | # CONFIG_IP_PNP_RARP is not set | ||
217 | # CONFIG_NET_IPIP is not set | ||
218 | # CONFIG_NET_IPGRE is not set | ||
219 | # CONFIG_IP_MROUTE is not set | ||
220 | # CONFIG_ARPD is not set | ||
221 | CONFIG_SYN_COOKIES=y | ||
222 | # CONFIG_INET_AH is not set | ||
223 | # CONFIG_INET_ESP is not set | ||
224 | # CONFIG_INET_IPCOMP is not set | ||
225 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
226 | # CONFIG_INET_TUNNEL is not set | ||
227 | CONFIG_INET_XFRM_MODE_TRANSPORT=y | ||
228 | CONFIG_INET_XFRM_MODE_TUNNEL=y | ||
229 | CONFIG_INET_DIAG=y | ||
230 | CONFIG_INET_TCP_DIAG=y | ||
231 | # CONFIG_TCP_CONG_ADVANCED is not set | ||
232 | CONFIG_TCP_CONG_BIC=y | ||
233 | # CONFIG_IPV6 is not set | ||
234 | # CONFIG_INET6_XFRM_TUNNEL is not set | ||
235 | # CONFIG_INET6_TUNNEL is not set | ||
236 | # CONFIG_NETWORK_SECMARK is not set | ||
237 | # CONFIG_NETFILTER is not set | ||
238 | |||
239 | # | ||
240 | # DCCP Configuration (EXPERIMENTAL) | ||
241 | # | ||
242 | # CONFIG_IP_DCCP is not set | ||
243 | |||
244 | # | ||
245 | # SCTP Configuration (EXPERIMENTAL) | ||
246 | # | ||
247 | # CONFIG_IP_SCTP is not set | ||
248 | |||
249 | # | ||
250 | # TIPC Configuration (EXPERIMENTAL) | ||
251 | # | ||
252 | # CONFIG_TIPC is not set | ||
253 | # CONFIG_ATM is not set | ||
254 | # CONFIG_BRIDGE is not set | ||
255 | # CONFIG_VLAN_8021Q is not set | ||
256 | # CONFIG_DECNET is not set | ||
257 | # CONFIG_LLC2 is not set | ||
258 | # CONFIG_IPX is not set | ||
259 | # CONFIG_ATALK is not set | ||
260 | # CONFIG_X25 is not set | ||
261 | # CONFIG_LAPB is not set | ||
262 | # CONFIG_NET_DIVERT is not set | ||
263 | # CONFIG_ECONET is not set | ||
264 | # CONFIG_WAN_ROUTER is not set | ||
265 | |||
266 | # | ||
267 | # QoS and/or fair queueing | ||
268 | # | ||
269 | # CONFIG_NET_SCHED is not set | ||
270 | |||
271 | # | ||
272 | # Network testing | ||
273 | # | ||
274 | # CONFIG_NET_PKTGEN is not set | ||
275 | # CONFIG_HAMRADIO is not set | ||
276 | # CONFIG_IRDA is not set | ||
277 | # CONFIG_BT is not set | ||
278 | # CONFIG_IEEE80211 is not set | ||
279 | |||
280 | # | ||
281 | # Device Drivers | ||
282 | # | ||
283 | |||
284 | # | ||
285 | # Generic Driver Options | ||
286 | # | ||
287 | CONFIG_STANDALONE=y | ||
288 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
289 | # CONFIG_FW_LOADER is not set | ||
290 | # CONFIG_DEBUG_DRIVER is not set | ||
291 | # CONFIG_SYS_HYPERVISOR is not set | ||
292 | |||
293 | # | ||
294 | # Connector - unified userspace <-> kernelspace linker | ||
295 | # | ||
296 | # CONFIG_CONNECTOR is not set | ||
297 | |||
298 | # | ||
299 | # Memory Technology Devices (MTD) | ||
300 | # | ||
301 | # CONFIG_MTD is not set | ||
302 | |||
303 | # | ||
304 | # Parallel port support | ||
305 | # | ||
306 | # CONFIG_PARPORT is not set | ||
307 | |||
308 | # | ||
309 | # Plug and Play support | ||
310 | # | ||
311 | |||
312 | # | ||
313 | # Block devices | ||
314 | # | ||
315 | # CONFIG_BLK_DEV_FD is not set | ||
316 | # CONFIG_BLK_CPQ_DA is not set | ||
317 | # CONFIG_BLK_CPQ_CISS_DA is not set | ||
318 | # CONFIG_BLK_DEV_DAC960 is not set | ||
319 | # CONFIG_BLK_DEV_UMEM is not set | ||
320 | # CONFIG_BLK_DEV_COW_COMMON is not set | ||
321 | CONFIG_BLK_DEV_LOOP=y | ||
322 | # CONFIG_BLK_DEV_CRYPTOLOOP is not set | ||
323 | # CONFIG_BLK_DEV_NBD is not set | ||
324 | # CONFIG_BLK_DEV_SX8 is not set | ||
325 | CONFIG_BLK_DEV_RAM=y | ||
326 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
327 | CONFIG_BLK_DEV_RAM_SIZE=32768 | ||
328 | CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 | ||
329 | CONFIG_BLK_DEV_INITRD=y | ||
330 | # CONFIG_CDROM_PKTCDVD is not set | ||
331 | # CONFIG_ATA_OVER_ETH is not set | ||
332 | |||
333 | # | ||
334 | # ATA/ATAPI/MFM/RLL support | ||
335 | # | ||
336 | # CONFIG_IDE is not set | ||
337 | |||
338 | # | ||
339 | # SCSI device support | ||
340 | # | ||
341 | # CONFIG_RAID_ATTRS is not set | ||
342 | # CONFIG_SCSI is not set | ||
343 | |||
344 | # | ||
345 | # Multi-device support (RAID and LVM) | ||
346 | # | ||
347 | # CONFIG_MD is not set | ||
348 | |||
349 | # | ||
350 | # Fusion MPT device support | ||
351 | # | ||
352 | # CONFIG_FUSION is not set | ||
353 | |||
354 | # | ||
355 | # IEEE 1394 (FireWire) support | ||
356 | # | ||
357 | # CONFIG_IEEE1394 is not set | ||
358 | |||
359 | # | ||
360 | # I2O device support | ||
361 | # | ||
362 | # CONFIG_I2O is not set | ||
363 | |||
364 | # | ||
365 | # Macintosh device drivers | ||
366 | # | ||
367 | # CONFIG_WINDFARM is not set | ||
368 | |||
369 | # | ||
370 | # Network device support | ||
371 | # | ||
372 | CONFIG_NETDEVICES=y | ||
373 | # CONFIG_DUMMY is not set | ||
374 | # CONFIG_BONDING is not set | ||
375 | # CONFIG_EQUALIZER is not set | ||
376 | # CONFIG_TUN is not set | ||
377 | |||
378 | # | ||
379 | # ARCnet devices | ||
380 | # | ||
381 | # CONFIG_ARCNET is not set | ||
382 | |||
383 | # | ||
384 | # PHY device support | ||
385 | # | ||
386 | CONFIG_PHYLIB=y | ||
387 | |||
388 | # | ||
389 | # MII PHY device drivers | ||
390 | # | ||
391 | CONFIG_MARVELL_PHY=y | ||
392 | CONFIG_DAVICOM_PHY=y | ||
393 | # CONFIG_QSEMI_PHY is not set | ||
394 | # CONFIG_LXT_PHY is not set | ||
395 | # CONFIG_CICADA_PHY is not set | ||
396 | # CONFIG_VITESSE_PHY is not set | ||
397 | # CONFIG_SMSC_PHY is not set | ||
398 | # CONFIG_FIXED_PHY is not set | ||
399 | |||
400 | # | ||
401 | # Ethernet (10 or 100Mbit) | ||
402 | # | ||
403 | CONFIG_NET_ETHERNET=y | ||
404 | CONFIG_MII=y | ||
405 | # CONFIG_HAPPYMEAL is not set | ||
406 | # CONFIG_SUNGEM is not set | ||
407 | # CONFIG_CASSINI is not set | ||
408 | # CONFIG_NET_VENDOR_3COM is not set | ||
409 | |||
410 | # | ||
411 | # Tulip family network device support | ||
412 | # | ||
413 | # CONFIG_NET_TULIP is not set | ||
414 | # CONFIG_HP100 is not set | ||
415 | # CONFIG_NET_PCI is not set | ||
416 | CONFIG_FS_ENET=y | ||
417 | # CONFIG_FS_ENET_HAS_SCC is not set | ||
418 | CONFIG_FS_ENET_HAS_FCC=y | ||
419 | |||
420 | # | ||
421 | # Ethernet (1000 Mbit) | ||
422 | # | ||
423 | # CONFIG_ACENIC is not set | ||
424 | # CONFIG_DL2K is not set | ||
425 | CONFIG_E1000=y | ||
426 | CONFIG_E1000_NAPI=y | ||
427 | # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set | ||
428 | # CONFIG_NS83820 is not set | ||
429 | # CONFIG_HAMACHI is not set | ||
430 | # CONFIG_YELLOWFIN is not set | ||
431 | # CONFIG_R8169 is not set | ||
432 | # CONFIG_SIS190 is not set | ||
433 | # CONFIG_SKGE is not set | ||
434 | # CONFIG_SKY2 is not set | ||
435 | # CONFIG_SK98LIN is not set | ||
436 | # CONFIG_TIGON3 is not set | ||
437 | # CONFIG_BNX2 is not set | ||
438 | CONFIG_GIANFAR=y | ||
439 | CONFIG_GFAR_NAPI=y | ||
440 | |||
441 | # | ||
442 | # Ethernet (10000 Mbit) | ||
443 | # | ||
444 | # CONFIG_CHELSIO_T1 is not set | ||
445 | # CONFIG_IXGB is not set | ||
446 | # CONFIG_S2IO is not set | ||
447 | # CONFIG_MYRI10GE is not set | ||
448 | |||
449 | # | ||
450 | # Token Ring devices | ||
451 | # | ||
452 | # CONFIG_TR is not set | ||
453 | |||
454 | # | ||
455 | # Wireless LAN (non-hamradio) | ||
456 | # | ||
457 | # CONFIG_NET_RADIO is not set | ||
458 | |||
459 | # | ||
460 | # Wan interfaces | ||
461 | # | ||
462 | # CONFIG_WAN is not set | ||
463 | # CONFIG_FDDI is not set | ||
464 | # CONFIG_HIPPI is not set | ||
465 | # CONFIG_PPP is not set | ||
466 | # CONFIG_SLIP is not set | ||
467 | # CONFIG_SHAPER is not set | ||
468 | # CONFIG_NETCONSOLE is not set | ||
469 | # CONFIG_NETPOLL is not set | ||
470 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
471 | |||
472 | # | ||
473 | # ISDN subsystem | ||
474 | # | ||
475 | # CONFIG_ISDN is not set | ||
476 | |||
477 | # | ||
478 | # Telephony Support | ||
479 | # | ||
480 | # CONFIG_PHONE is not set | ||
481 | |||
482 | # | ||
483 | # Input device support | ||
484 | # | ||
485 | CONFIG_INPUT=y | ||
486 | |||
487 | # | ||
488 | # Userland interfaces | ||
489 | # | ||
490 | # CONFIG_INPUT_MOUSEDEV is not set | ||
491 | # CONFIG_INPUT_JOYDEV is not set | ||
492 | # CONFIG_INPUT_TSDEV is not set | ||
493 | # CONFIG_INPUT_EVDEV is not set | ||
494 | # CONFIG_INPUT_EVBUG is not set | ||
495 | |||
496 | # | ||
497 | # Input Device Drivers | ||
498 | # | ||
499 | # CONFIG_INPUT_KEYBOARD is not set | ||
500 | # CONFIG_INPUT_MOUSE is not set | ||
501 | # CONFIG_INPUT_JOYSTICK is not set | ||
502 | # CONFIG_INPUT_TOUCHSCREEN is not set | ||
503 | # CONFIG_INPUT_MISC is not set | ||
504 | |||
505 | # | ||
506 | # Hardware I/O ports | ||
507 | # | ||
508 | # CONFIG_SERIO is not set | ||
509 | # CONFIG_GAMEPORT is not set | ||
510 | |||
511 | # | ||
512 | # Character devices | ||
513 | # | ||
514 | # CONFIG_VT is not set | ||
515 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
516 | |||
517 | # | ||
518 | # Serial drivers | ||
519 | # | ||
520 | # CONFIG_SERIAL_8250 is not set | ||
521 | |||
522 | # | ||
523 | # Non-8250 serial port support | ||
524 | # | ||
525 | CONFIG_SERIAL_CORE=y | ||
526 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
527 | CONFIG_SERIAL_CPM=y | ||
528 | CONFIG_SERIAL_CPM_CONSOLE=y | ||
529 | CONFIG_SERIAL_CPM_SCC1=y | ||
530 | CONFIG_SERIAL_CPM_SCC2=y | ||
531 | # CONFIG_SERIAL_CPM_SCC3 is not set | ||
532 | # CONFIG_SERIAL_CPM_SCC4 is not set | ||
533 | # CONFIG_SERIAL_CPM_SMC1 is not set | ||
534 | # CONFIG_SERIAL_CPM_SMC2 is not set | ||
535 | # CONFIG_SERIAL_JSM is not set | ||
536 | CONFIG_UNIX98_PTYS=y | ||
537 | CONFIG_LEGACY_PTYS=y | ||
538 | CONFIG_LEGACY_PTY_COUNT=256 | ||
539 | # CONFIG_BRIQ_PANEL is not set | ||
540 | |||
541 | # | ||
542 | # IPMI | ||
543 | # | ||
544 | # CONFIG_IPMI_HANDLER is not set | ||
545 | |||
546 | # | ||
547 | # Watchdog Cards | ||
548 | # | ||
549 | # CONFIG_WATCHDOG is not set | ||
550 | CONFIG_HW_RANDOM=y | ||
551 | # CONFIG_NVRAM is not set | ||
552 | CONFIG_GEN_RTC=y | ||
553 | # CONFIG_GEN_RTC_X is not set | ||
554 | # CONFIG_DTLK is not set | ||
555 | # CONFIG_R3964 is not set | ||
556 | # CONFIG_APPLICOM is not set | ||
557 | |||
558 | # | ||
559 | # Ftape, the floppy tape device driver | ||
560 | # | ||
561 | # CONFIG_AGP is not set | ||
562 | # CONFIG_DRM is not set | ||
563 | # CONFIG_RAW_DRIVER is not set | ||
564 | |||
565 | # | ||
566 | # TPM devices | ||
567 | # | ||
568 | # CONFIG_TCG_TPM is not set | ||
569 | # CONFIG_TELCLOCK is not set | ||
570 | |||
571 | # | ||
572 | # I2C support | ||
573 | # | ||
574 | # CONFIG_I2C is not set | ||
575 | |||
576 | # | ||
577 | # SPI support | ||
578 | # | ||
579 | # CONFIG_SPI is not set | ||
580 | # CONFIG_SPI_MASTER is not set | ||
581 | |||
582 | # | ||
583 | # Dallas's 1-wire bus | ||
584 | # | ||
585 | |||
586 | # | ||
587 | # Hardware Monitoring support | ||
588 | # | ||
589 | CONFIG_HWMON=y | ||
590 | # CONFIG_HWMON_VID is not set | ||
591 | # CONFIG_SENSORS_ABITUGURU is not set | ||
592 | # CONFIG_SENSORS_F71805F is not set | ||
593 | # CONFIG_HWMON_DEBUG_CHIP is not set | ||
594 | |||
595 | # | ||
596 | # Misc devices | ||
597 | # | ||
598 | |||
599 | # | ||
600 | # Multimedia devices | ||
601 | # | ||
602 | # CONFIG_VIDEO_DEV is not set | ||
603 | CONFIG_VIDEO_V4L2=y | ||
604 | |||
605 | # | ||
606 | # Digital Video Broadcasting Devices | ||
607 | # | ||
608 | # CONFIG_DVB is not set | ||
609 | |||
610 | # | ||
611 | # Graphics support | ||
612 | # | ||
613 | CONFIG_FIRMWARE_EDID=y | ||
614 | # CONFIG_FB is not set | ||
615 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | ||
616 | |||
617 | # | ||
618 | # Sound | ||
619 | # | ||
620 | # CONFIG_SOUND is not set | ||
621 | |||
622 | # | ||
623 | # USB support | ||
624 | # | ||
625 | CONFIG_USB_ARCH_HAS_HCD=y | ||
626 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
627 | CONFIG_USB_ARCH_HAS_EHCI=y | ||
628 | # CONFIG_USB is not set | ||
629 | |||
630 | # | ||
631 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' | ||
632 | # | ||
633 | |||
634 | # | ||
635 | # USB Gadget Support | ||
636 | # | ||
637 | # CONFIG_USB_GADGET is not set | ||
638 | |||
639 | # | ||
640 | # MMC/SD Card support | ||
641 | # | ||
642 | # CONFIG_MMC is not set | ||
643 | |||
644 | # | ||
645 | # LED devices | ||
646 | # | ||
647 | # CONFIG_NEW_LEDS is not set | ||
648 | |||
649 | # | ||
650 | # LED drivers | ||
651 | # | ||
652 | |||
653 | # | ||
654 | # LED Triggers | ||
655 | # | ||
656 | |||
657 | # | ||
658 | # InfiniBand support | ||
659 | # | ||
660 | # CONFIG_INFINIBAND is not set | ||
661 | |||
662 | # | ||
663 | # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) | ||
664 | # | ||
665 | |||
666 | # | ||
667 | # Real Time Clock | ||
668 | # | ||
669 | # CONFIG_RTC_CLASS is not set | ||
670 | |||
671 | # | ||
672 | # DMA Engine support | ||
673 | # | ||
674 | # CONFIG_DMA_ENGINE is not set | ||
675 | |||
676 | # | ||
677 | # DMA Clients | ||
678 | # | ||
679 | |||
680 | # | ||
681 | # DMA Devices | ||
682 | # | ||
683 | |||
684 | # | ||
685 | # File systems | ||
686 | # | ||
687 | CONFIG_EXT2_FS=y | ||
688 | # CONFIG_EXT2_FS_XATTR is not set | ||
689 | # CONFIG_EXT2_FS_XIP is not set | ||
690 | CONFIG_EXT3_FS=y | ||
691 | CONFIG_EXT3_FS_XATTR=y | ||
692 | # CONFIG_EXT3_FS_POSIX_ACL is not set | ||
693 | # CONFIG_EXT3_FS_SECURITY is not set | ||
694 | CONFIG_JBD=y | ||
695 | # CONFIG_JBD_DEBUG is not set | ||
696 | CONFIG_FS_MBCACHE=y | ||
697 | # CONFIG_REISERFS_FS is not set | ||
698 | # CONFIG_JFS_FS is not set | ||
699 | # CONFIG_FS_POSIX_ACL is not set | ||
700 | # CONFIG_XFS_FS is not set | ||
701 | # CONFIG_OCFS2_FS is not set | ||
702 | # CONFIG_MINIX_FS is not set | ||
703 | # CONFIG_ROMFS_FS is not set | ||
704 | CONFIG_INOTIFY=y | ||
705 | CONFIG_INOTIFY_USER=y | ||
706 | # CONFIG_QUOTA is not set | ||
707 | CONFIG_DNOTIFY=y | ||
708 | # CONFIG_AUTOFS_FS is not set | ||
709 | # CONFIG_AUTOFS4_FS is not set | ||
710 | # CONFIG_FUSE_FS is not set | ||
711 | |||
712 | # | ||
713 | # CD-ROM/DVD Filesystems | ||
714 | # | ||
715 | # CONFIG_ISO9660_FS is not set | ||
716 | # CONFIG_UDF_FS is not set | ||
717 | |||
718 | # | ||
719 | # DOS/FAT/NT Filesystems | ||
720 | # | ||
721 | # CONFIG_MSDOS_FS is not set | ||
722 | # CONFIG_VFAT_FS is not set | ||
723 | # CONFIG_NTFS_FS is not set | ||
724 | |||
725 | # | ||
726 | # Pseudo filesystems | ||
727 | # | ||
728 | CONFIG_PROC_FS=y | ||
729 | CONFIG_PROC_KCORE=y | ||
730 | CONFIG_SYSFS=y | ||
731 | CONFIG_TMPFS=y | ||
732 | # CONFIG_HUGETLB_PAGE is not set | ||
733 | CONFIG_RAMFS=y | ||
734 | # CONFIG_CONFIGFS_FS is not set | ||
735 | |||
736 | # | ||
737 | # Miscellaneous filesystems | ||
738 | # | ||
739 | # CONFIG_ADFS_FS is not set | ||
740 | # CONFIG_AFFS_FS is not set | ||
741 | # CONFIG_HFS_FS is not set | ||
742 | # CONFIG_HFSPLUS_FS is not set | ||
743 | # CONFIG_BEFS_FS is not set | ||
744 | # CONFIG_BFS_FS is not set | ||
745 | # CONFIG_EFS_FS is not set | ||
746 | # CONFIG_CRAMFS is not set | ||
747 | # CONFIG_VXFS_FS is not set | ||
748 | # CONFIG_HPFS_FS is not set | ||
749 | # CONFIG_QNX4FS_FS is not set | ||
750 | # CONFIG_SYSV_FS is not set | ||
751 | # CONFIG_UFS_FS is not set | ||
752 | |||
753 | # | ||
754 | # Network File Systems | ||
755 | # | ||
756 | CONFIG_NFS_FS=y | ||
757 | # CONFIG_NFS_V3 is not set | ||
758 | # CONFIG_NFS_V4 is not set | ||
759 | # CONFIG_NFS_DIRECTIO is not set | ||
760 | # CONFIG_NFSD is not set | ||
761 | CONFIG_ROOT_NFS=y | ||
762 | CONFIG_LOCKD=y | ||
763 | CONFIG_NFS_COMMON=y | ||
764 | CONFIG_SUNRPC=y | ||
765 | # CONFIG_RPCSEC_GSS_KRB5 is not set | ||
766 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | ||
767 | # CONFIG_SMB_FS is not set | ||
768 | # CONFIG_CIFS is not set | ||
769 | # CONFIG_NCP_FS is not set | ||
770 | # CONFIG_CODA_FS is not set | ||
771 | # CONFIG_AFS_FS is not set | ||
772 | # CONFIG_9P_FS is not set | ||
773 | |||
774 | # | ||
775 | # Partition Types | ||
776 | # | ||
777 | CONFIG_PARTITION_ADVANCED=y | ||
778 | # CONFIG_ACORN_PARTITION is not set | ||
779 | # CONFIG_OSF_PARTITION is not set | ||
780 | # CONFIG_AMIGA_PARTITION is not set | ||
781 | # CONFIG_ATARI_PARTITION is not set | ||
782 | # CONFIG_MAC_PARTITION is not set | ||
783 | # CONFIG_MSDOS_PARTITION is not set | ||
784 | # CONFIG_LDM_PARTITION is not set | ||
785 | # CONFIG_SGI_PARTITION is not set | ||
786 | # CONFIG_ULTRIX_PARTITION is not set | ||
787 | # CONFIG_SUN_PARTITION is not set | ||
788 | # CONFIG_KARMA_PARTITION is not set | ||
789 | # CONFIG_EFI_PARTITION is not set | ||
790 | |||
791 | # | ||
792 | # Native Language Support | ||
793 | # | ||
794 | # CONFIG_NLS is not set | ||
795 | |||
796 | # | ||
797 | # Library routines | ||
798 | # | ||
799 | # CONFIG_CRC_CCITT is not set | ||
800 | # CONFIG_CRC16 is not set | ||
801 | CONFIG_CRC32=y | ||
802 | # CONFIG_LIBCRC32C is not set | ||
803 | CONFIG_PLIST=y | ||
804 | |||
805 | # | ||
806 | # Instrumentation Support | ||
807 | # | ||
808 | # CONFIG_PROFILING is not set | ||
809 | |||
810 | # | ||
811 | # Kernel hacking | ||
812 | # | ||
813 | # CONFIG_PRINTK_TIME is not set | ||
814 | # CONFIG_MAGIC_SYSRQ is not set | ||
815 | # CONFIG_UNUSED_SYMBOLS is not set | ||
816 | CONFIG_DEBUG_KERNEL=y | ||
817 | CONFIG_LOG_BUF_SHIFT=14 | ||
818 | CONFIG_DETECT_SOFTLOCKUP=y | ||
819 | # CONFIG_SCHEDSTATS is not set | ||
820 | # CONFIG_DEBUG_SLAB is not set | ||
821 | # CONFIG_DEBUG_RT_MUTEXES is not set | ||
822 | # CONFIG_RT_MUTEX_TESTER is not set | ||
823 | # CONFIG_DEBUG_SPINLOCK is not set | ||
824 | CONFIG_DEBUG_MUTEXES=y | ||
825 | # CONFIG_DEBUG_RWSEMS is not set | ||
826 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | ||
827 | # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set | ||
828 | # CONFIG_DEBUG_KOBJECT is not set | ||
829 | # CONFIG_DEBUG_INFO is not set | ||
830 | # CONFIG_DEBUG_FS is not set | ||
831 | # CONFIG_DEBUG_VM is not set | ||
832 | # CONFIG_UNWIND_INFO is not set | ||
833 | CONFIG_FORCED_INLINING=y | ||
834 | # CONFIG_RCU_TORTURE_TEST is not set | ||
835 | # CONFIG_DEBUGGER is not set | ||
836 | # CONFIG_KGDB_CONSOLE is not set | ||
837 | # CONFIG_BDI_SWITCH is not set | ||
838 | # CONFIG_BOOTX_TEXT is not set | ||
839 | # CONFIG_PPC_EARLY_DEBUG is not set | ||
840 | |||
841 | # | ||
842 | # Security options | ||
843 | # | ||
844 | # CONFIG_KEYS is not set | ||
845 | # CONFIG_SECURITY is not set | ||
846 | |||
847 | # | ||
848 | # Cryptographic options | ||
849 | # | ||
850 | # CONFIG_CRYPTO is not set | ||
851 | |||
852 | # | ||
853 | # Hardware crypto devices | ||
854 | # | ||
diff --git a/arch/powerpc/configs/pmac32_defconfig b/arch/powerpc/configs/pmac32_defconfig index 6861dde7d77b..765c8bb90ddd 100644 --- a/arch/powerpc/configs/pmac32_defconfig +++ b/arch/powerpc/configs/pmac32_defconfig | |||
@@ -682,7 +682,7 @@ CONFIG_SCSI_AIC7XXX_OLD=m | |||
682 | # CONFIG_MEGARAID_NEWGEN is not set | 682 | # CONFIG_MEGARAID_NEWGEN is not set |
683 | # CONFIG_MEGARAID_LEGACY is not set | 683 | # CONFIG_MEGARAID_LEGACY is not set |
684 | # CONFIG_MEGARAID_SAS is not set | 684 | # CONFIG_MEGARAID_SAS is not set |
685 | # CONFIG_SCSI_SATA is not set | 685 | # CONFIG_ATA is not set |
686 | # CONFIG_SCSI_HPTIOP is not set | 686 | # CONFIG_SCSI_HPTIOP is not set |
687 | # CONFIG_SCSI_BUSLOGIC is not set | 687 | # CONFIG_SCSI_BUSLOGIC is not set |
688 | # CONFIG_SCSI_DMX3191D is not set | 688 | # CONFIG_SCSI_DMX3191D is not set |
@@ -1826,7 +1826,7 @@ CONFIG_OPROFILE=y | |||
1826 | # Kernel hacking | 1826 | # Kernel hacking |
1827 | # | 1827 | # |
1828 | # CONFIG_PRINTK_TIME is not set | 1828 | # CONFIG_PRINTK_TIME is not set |
1829 | # CONFIG_MAGIC_SYSRQ is not set | 1829 | CONFIG_MAGIC_SYSRQ=y |
1830 | # CONFIG_UNUSED_SYMBOLS is not set | 1830 | # CONFIG_UNUSED_SYMBOLS is not set |
1831 | CONFIG_DEBUG_KERNEL=y | 1831 | CONFIG_DEBUG_KERNEL=y |
1832 | CONFIG_LOG_BUF_SHIFT=14 | 1832 | CONFIG_LOG_BUF_SHIFT=14 |
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig index 7517d0c5303f..be11df7c11aa 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig | |||
@@ -520,23 +520,23 @@ CONFIG_SCSI_ISCSI_ATTRS=m | |||
520 | # CONFIG_MEGARAID_NEWGEN is not set | 520 | # CONFIG_MEGARAID_NEWGEN is not set |
521 | # CONFIG_MEGARAID_LEGACY is not set | 521 | # CONFIG_MEGARAID_LEGACY is not set |
522 | # CONFIG_MEGARAID_SAS is not set | 522 | # CONFIG_MEGARAID_SAS is not set |
523 | CONFIG_SCSI_SATA=y | 523 | CONFIG_ATA=y |
524 | # CONFIG_SCSI_SATA_AHCI is not set | 524 | # CONFIG_SATA_AHCI is not set |
525 | CONFIG_SCSI_SATA_SVW=y | 525 | CONFIG_SATA_SVW=y |
526 | # CONFIG_SCSI_ATA_PIIX is not set | 526 | # CONFIG_SCSI_ATA_PIIX is not set |
527 | # CONFIG_SCSI_SATA_MV is not set | 527 | # CONFIG_SATA_MV is not set |
528 | # CONFIG_SCSI_SATA_NV is not set | 528 | # CONFIG_SATA_NV is not set |
529 | # CONFIG_SCSI_PDC_ADMA is not set | 529 | # CONFIG_SCSI_PDC_ADMA is not set |
530 | # CONFIG_SCSI_HPTIOP is not set | 530 | # CONFIG_SCSI_HPTIOP is not set |
531 | # CONFIG_SCSI_SATA_QSTOR is not set | 531 | # CONFIG_SATA_QSTOR is not set |
532 | # CONFIG_SCSI_SATA_PROMISE is not set | 532 | # CONFIG_SATA_PROMISE is not set |
533 | # CONFIG_SCSI_SATA_SX4 is not set | 533 | # CONFIG_SATA_SX4 is not set |
534 | # CONFIG_SCSI_SATA_SIL is not set | 534 | # CONFIG_SATA_SIL is not set |
535 | # CONFIG_SCSI_SATA_SIL24 is not set | 535 | # CONFIG_SATA_SIL24 is not set |
536 | # CONFIG_SCSI_SATA_SIS is not set | 536 | # CONFIG_SATA_SIS is not set |
537 | # CONFIG_SCSI_SATA_ULI is not set | 537 | # CONFIG_SATA_ULI is not set |
538 | # CONFIG_SCSI_SATA_VIA is not set | 538 | # CONFIG_SATA_VIA is not set |
539 | # CONFIG_SCSI_SATA_VITESSE is not set | 539 | # CONFIG_SATA_VITESSE is not set |
540 | # CONFIG_SCSI_BUSLOGIC is not set | 540 | # CONFIG_SCSI_BUSLOGIC is not set |
541 | # CONFIG_SCSI_DMX3191D is not set | 541 | # CONFIG_SCSI_DMX3191D is not set |
542 | # CONFIG_SCSI_EATA is not set | 542 | # CONFIG_SCSI_EATA is not set |
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index a8cdf312e1b0..44175fb7adec 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig | |||
@@ -506,7 +506,7 @@ CONFIG_SCSI_SAS_ATTRS=m | |||
506 | # CONFIG_MEGARAID_NEWGEN is not set | 506 | # CONFIG_MEGARAID_NEWGEN is not set |
507 | # CONFIG_MEGARAID_LEGACY is not set | 507 | # CONFIG_MEGARAID_LEGACY is not set |
508 | # CONFIG_MEGARAID_SAS is not set | 508 | # CONFIG_MEGARAID_SAS is not set |
509 | # CONFIG_SCSI_SATA is not set | 509 | # CONFIG_ATA is not set |
510 | # CONFIG_SCSI_HPTIOP is not set | 510 | # CONFIG_SCSI_HPTIOP is not set |
511 | # CONFIG_SCSI_BUSLOGIC is not set | 511 | # CONFIG_SCSI_BUSLOGIC is not set |
512 | # CONFIG_SCSI_DMX3191D is not set | 512 | # CONFIG_SCSI_DMX3191D is not set |
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index b4432332341f..c3f58f2f9f52 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -777,7 +777,6 @@ unsigned int irq_alloc_virt(struct irq_host *host, | |||
777 | { | 777 | { |
778 | unsigned long flags; | 778 | unsigned long flags; |
779 | unsigned int i, j, found = NO_IRQ; | 779 | unsigned int i, j, found = NO_IRQ; |
780 | unsigned int limit = irq_virq_count - count; | ||
781 | 780 | ||
782 | if (count == 0 || count > (irq_virq_count - NUM_ISA_INTERRUPTS)) | 781 | if (count == 0 || count > (irq_virq_count - NUM_ISA_INTERRUPTS)) |
783 | return NO_IRQ; | 782 | return NO_IRQ; |
@@ -794,14 +793,16 @@ unsigned int irq_alloc_virt(struct irq_host *host, | |||
794 | /* Look for count consecutive numbers in the allocatable | 793 | /* Look for count consecutive numbers in the allocatable |
795 | * (non-legacy) space | 794 | * (non-legacy) space |
796 | */ | 795 | */ |
797 | for (i = NUM_ISA_INTERRUPTS; i <= limit; ) { | 796 | for (i = NUM_ISA_INTERRUPTS, j = 0; i < irq_virq_count; i++) { |
798 | for (j = i; j < (i + count); j++) | 797 | if (irq_map[i].host != NULL) |
799 | if (irq_map[j].host != NULL) { | 798 | j = 0; |
800 | i = j + 1; | 799 | else |
801 | continue; | 800 | j++; |
802 | } | 801 | |
803 | found = i; | 802 | if (j == count) { |
804 | break; | 803 | found = i - count + 1; |
804 | break; | ||
805 | } | ||
805 | } | 806 | } |
806 | if (found == NO_IRQ) { | 807 | if (found == NO_IRQ) { |
807 | spin_unlock_irqrestore(&irq_big_lock, flags); | 808 | spin_unlock_irqrestore(&irq_big_lock, flags); |
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index dea75d73f983..975102a020d9 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c | |||
@@ -526,9 +526,7 @@ static void do_syscall_trace(void) | |||
526 | 526 | ||
527 | void do_syscall_trace_enter(struct pt_regs *regs) | 527 | void do_syscall_trace_enter(struct pt_regs *regs) |
528 | { | 528 | { |
529 | #ifdef CONFIG_PPC64 | ||
530 | secure_computing(regs->gpr[0]); | 529 | secure_computing(regs->gpr[0]); |
531 | #endif | ||
532 | 530 | ||
533 | if (test_thread_flag(TIF_SYSCALL_TRACE) | 531 | if (test_thread_flag(TIF_SYSCALL_TRACE) |
534 | && (current->ptrace & PT_PTRACED)) | 532 | && (current->ptrace & PT_PTRACED)) |
@@ -548,12 +546,8 @@ void do_syscall_trace_enter(struct pt_regs *regs) | |||
548 | 546 | ||
549 | void do_syscall_trace_leave(struct pt_regs *regs) | 547 | void do_syscall_trace_leave(struct pt_regs *regs) |
550 | { | 548 | { |
551 | #ifdef CONFIG_PPC32 | ||
552 | secure_computing(regs->gpr[0]); | ||
553 | #endif | ||
554 | |||
555 | if (unlikely(current->audit_context)) | 549 | if (unlikely(current->audit_context)) |
556 | audit_syscall_exit((regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS, | 550 | audit_syscall_exit((regs->ccr&0x10000000)?AUDITSC_FAILURE:AUDITSC_SUCCESS, |
557 | regs->result); | 551 | regs->result); |
558 | 552 | ||
559 | if ((test_thread_flag(TIF_SYSCALL_TRACE) | 553 | if ((test_thread_flag(TIF_SYSCALL_TRACE) |
@@ -561,8 +555,3 @@ void do_syscall_trace_leave(struct pt_regs *regs) | |||
561 | && (current->ptrace & PT_PTRACED)) | 555 | && (current->ptrace & PT_PTRACED)) |
562 | do_syscall_trace(); | 556 | do_syscall_trace(); |
563 | } | 557 | } |
564 | |||
565 | #ifdef CONFIG_PPC32 | ||
566 | EXPORT_SYMBOL(do_syscall_trace_enter); | ||
567 | EXPORT_SYMBOL(do_syscall_trace_leave); | ||
568 | #endif | ||
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index 5e391fc25340..d15c33e95959 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c | |||
@@ -69,16 +69,20 @@ struct readdir_callback32 { | |||
69 | }; | 69 | }; |
70 | 70 | ||
71 | static int fillonedir(void * __buf, const char * name, int namlen, | 71 | static int fillonedir(void * __buf, const char * name, int namlen, |
72 | off_t offset, ino_t ino, unsigned int d_type) | 72 | off_t offset, u64 ino, unsigned int d_type) |
73 | { | 73 | { |
74 | struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf; | 74 | struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf; |
75 | struct old_linux_dirent32 __user * dirent; | 75 | struct old_linux_dirent32 __user * dirent; |
76 | ino_t d_ino; | ||
76 | 77 | ||
77 | if (buf->count) | 78 | if (buf->count) |
78 | return -EINVAL; | 79 | return -EINVAL; |
80 | d_ino = ino; | ||
81 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
82 | return -EOVERFLOW; | ||
79 | buf->count++; | 83 | buf->count++; |
80 | dirent = buf->dirent; | 84 | dirent = buf->dirent; |
81 | put_user(ino, &dirent->d_ino); | 85 | put_user(d_ino, &dirent->d_ino); |
82 | put_user(offset, &dirent->d_offset); | 86 | put_user(offset, &dirent->d_offset); |
83 | put_user(namlen, &dirent->d_namlen); | 87 | put_user(namlen, &dirent->d_namlen); |
84 | copy_to_user(dirent->d_name, name, namlen); | 88 | copy_to_user(dirent->d_name, name, namlen); |
@@ -120,15 +124,20 @@ asmlinkage long ppc32_select(u32 n, compat_ulong_t __user *inp, | |||
120 | 124 | ||
121 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) | 125 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) |
122 | { | 126 | { |
127 | compat_ino_t ino; | ||
123 | long err; | 128 | long err; |
124 | 129 | ||
125 | if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) || | 130 | if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) || |
126 | !new_valid_dev(stat->rdev)) | 131 | !new_valid_dev(stat->rdev)) |
127 | return -EOVERFLOW; | 132 | return -EOVERFLOW; |
128 | 133 | ||
134 | ino = stat->ino; | ||
135 | if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino) | ||
136 | return -EOVERFLOW; | ||
137 | |||
129 | err = access_ok(VERIFY_WRITE, statbuf, sizeof(*statbuf)) ? 0 : -EFAULT; | 138 | err = access_ok(VERIFY_WRITE, statbuf, sizeof(*statbuf)) ? 0 : -EFAULT; |
130 | err |= __put_user(new_encode_dev(stat->dev), &statbuf->st_dev); | 139 | err |= __put_user(new_encode_dev(stat->dev), &statbuf->st_dev); |
131 | err |= __put_user(stat->ino, &statbuf->st_ino); | 140 | err |= __put_user(ino, &statbuf->st_ino); |
132 | err |= __put_user(stat->mode, &statbuf->st_mode); | 141 | err |= __put_user(stat->mode, &statbuf->st_mode); |
133 | err |= __put_user(stat->nlink, &statbuf->st_nlink); | 142 | err |= __put_user(stat->nlink, &statbuf->st_nlink); |
134 | err |= __put_user(stat->uid, &statbuf->st_uid); | 143 | err |= __put_user(stat->uid, &statbuf->st_uid); |
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index 406f308ddead..d45a168bdaca 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c | |||
@@ -25,8 +25,8 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices); | |||
25 | /* SMT stuff */ | 25 | /* SMT stuff */ |
26 | 26 | ||
27 | #ifdef CONFIG_PPC_MULTIPLATFORM | 27 | #ifdef CONFIG_PPC_MULTIPLATFORM |
28 | /* default to snooze disabled */ | 28 | /* Time in microseconds we delay before sleeping in the idle loop */ |
29 | DEFINE_PER_CPU(unsigned long, smt_snooze_delay); | 29 | DEFINE_PER_CPU(unsigned long, smt_snooze_delay) = { 100 }; |
30 | 30 | ||
31 | static ssize_t store_smt_snooze_delay(struct sys_device *dev, const char *buf, | 31 | static ssize_t store_smt_snooze_delay(struct sys_device *dev, const char *buf, |
32 | size_t count) | 32 | size_t count) |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 8b278d85ca4e..85b9244a098c 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -1041,6 +1041,48 @@ void __init time_init(void) | |||
1041 | set_dec(tb_ticks_per_jiffy); | 1041 | set_dec(tb_ticks_per_jiffy); |
1042 | } | 1042 | } |
1043 | 1043 | ||
1044 | #ifdef CONFIG_RTC_CLASS | ||
1045 | static int set_rtc_class_time(struct rtc_time *tm) | ||
1046 | { | ||
1047 | int err; | ||
1048 | struct class_device *class_dev = | ||
1049 | rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); | ||
1050 | |||
1051 | if (class_dev == NULL) | ||
1052 | return -ENODEV; | ||
1053 | |||
1054 | err = rtc_set_time(class_dev, tm); | ||
1055 | |||
1056 | rtc_class_close(class_dev); | ||
1057 | |||
1058 | return 0; | ||
1059 | } | ||
1060 | |||
1061 | static void get_rtc_class_time(struct rtc_time *tm) | ||
1062 | { | ||
1063 | int err; | ||
1064 | struct class_device *class_dev = | ||
1065 | rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); | ||
1066 | |||
1067 | if (class_dev == NULL) | ||
1068 | return; | ||
1069 | |||
1070 | err = rtc_read_time(class_dev, tm); | ||
1071 | |||
1072 | rtc_class_close(class_dev); | ||
1073 | |||
1074 | return; | ||
1075 | } | ||
1076 | |||
1077 | int __init rtc_class_hookup(void) | ||
1078 | { | ||
1079 | ppc_md.get_rtc_time = get_rtc_class_time; | ||
1080 | ppc_md.set_rtc_time = set_rtc_class_time; | ||
1081 | |||
1082 | return 0; | ||
1083 | } | ||
1084 | #endif /* CONFIG_RTC_CLASS */ | ||
1085 | |||
1044 | 1086 | ||
1045 | #define FEBRUARY 2 | 1087 | #define FEBRUARY 2 |
1046 | #define STARTOFTIME 1970 | 1088 | #define STARTOFTIME 1970 |
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 336dd191f768..a0360ae10d0c 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile | |||
@@ -14,9 +14,15 @@ endif | |||
14 | obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \ | 14 | obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \ |
15 | memcpy_64.o usercopy_64.o mem_64.o string.o \ | 15 | memcpy_64.o usercopy_64.o mem_64.o string.o \ |
16 | strcase.o | 16 | strcase.o |
17 | obj-$(CONFIG_QUICC_ENGINE) += rheap.o | ||
17 | obj-$(CONFIG_XMON) += sstep.o | 18 | obj-$(CONFIG_XMON) += sstep.o |
18 | 19 | ||
19 | ifeq ($(CONFIG_PPC64),y) | 20 | ifeq ($(CONFIG_PPC64),y) |
20 | obj-$(CONFIG_SMP) += locks.o | 21 | obj-$(CONFIG_SMP) += locks.o |
21 | obj-$(CONFIG_DEBUG_KERNEL) += sstep.o | 22 | obj-$(CONFIG_DEBUG_KERNEL) += sstep.o |
22 | endif | 23 | endif |
24 | |||
25 | # Temporary hack until we have migrated to asm-powerpc | ||
26 | ifeq ($(CONFIG_PPC_MERGE),y) | ||
27 | obj-$(CONFIG_CPM2) += rheap.o | ||
28 | endif | ||
diff --git a/arch/powerpc/lib/rheap.c b/arch/powerpc/lib/rheap.c index 31e511856dc5..57bf991ccd6e 100644 --- a/arch/powerpc/lib/rheap.c +++ b/arch/powerpc/lib/rheap.c | |||
@@ -423,17 +423,21 @@ void *rh_detach_region(rh_info_t * info, void *start, int size) | |||
423 | return (void *)s; | 423 | return (void *)s; |
424 | } | 424 | } |
425 | 425 | ||
426 | void *rh_alloc(rh_info_t * info, int size, const char *owner) | 426 | void *rh_alloc_align(rh_info_t * info, int size, int alignment, const char *owner) |
427 | { | 427 | { |
428 | struct list_head *l; | 428 | struct list_head *l; |
429 | rh_block_t *blk; | 429 | rh_block_t *blk; |
430 | rh_block_t *newblk; | 430 | rh_block_t *newblk; |
431 | void *start; | 431 | void *start; |
432 | 432 | ||
433 | /* Validate size */ | 433 | /* Validate size, (must be power of two) */ |
434 | if (size <= 0) | 434 | if (size <= 0 || (alignment & (alignment - 1)) != 0) |
435 | return ERR_PTR(-EINVAL); | 435 | return ERR_PTR(-EINVAL); |
436 | 436 | ||
437 | /* given alignment larger that default rheap alignment */ | ||
438 | if (alignment > info->alignment) | ||
439 | size += alignment - 1; | ||
440 | |||
437 | /* Align to configured alignment */ | 441 | /* Align to configured alignment */ |
438 | size = (size + (info->alignment - 1)) & ~(info->alignment - 1); | 442 | size = (size + (info->alignment - 1)) & ~(info->alignment - 1); |
439 | 443 | ||
@@ -476,15 +480,27 @@ void *rh_alloc(rh_info_t * info, int size, const char *owner) | |||
476 | 480 | ||
477 | attach_taken_block(info, newblk); | 481 | attach_taken_block(info, newblk); |
478 | 482 | ||
483 | /* for larger alignment return fixed up pointer */ | ||
484 | /* this is no problem with the deallocator since */ | ||
485 | /* we scan for pointers that lie in the blocks */ | ||
486 | if (alignment > info->alignment) | ||
487 | start = (void *)(((unsigned long)start + alignment - 1) & | ||
488 | ~(alignment - 1)); | ||
489 | |||
479 | return start; | 490 | return start; |
480 | } | 491 | } |
481 | 492 | ||
493 | void *rh_alloc(rh_info_t * info, int size, const char *owner) | ||
494 | { | ||
495 | return rh_alloc_align(info, size, info->alignment, owner); | ||
496 | } | ||
497 | |||
482 | /* allocate at precisely the given address */ | 498 | /* allocate at precisely the given address */ |
483 | void *rh_alloc_fixed(rh_info_t * info, void *start, int size, const char *owner) | 499 | void *rh_alloc_fixed(rh_info_t * info, void *start, int size, const char *owner) |
484 | { | 500 | { |
485 | struct list_head *l; | 501 | struct list_head *l; |
486 | rh_block_t *blk, *newblk1, *newblk2; | 502 | rh_block_t *blk, *newblk1, *newblk2; |
487 | unsigned long s, e, m, bs, be; | 503 | unsigned long s, e, m, bs = 0, be = 0; |
488 | 504 | ||
489 | /* Validate size */ | 505 | /* Validate size */ |
490 | if (size <= 0) | 506 | if (size <= 0) |
diff --git a/arch/powerpc/math-emu/Makefile b/arch/powerpc/math-emu/Makefile index 754143e8936b..29bc9126241b 100644 --- a/arch/powerpc/math-emu/Makefile +++ b/arch/powerpc/math-emu/Makefile | |||
@@ -11,3 +11,6 @@ obj-$(CONFIG_MATH_EMULATION) += fabs.o fadd.o fadds.o fcmpo.o fcmpu.o \ | |||
11 | mcrfs.o mffs.o mtfsb0.o mtfsb1.o \ | 11 | mcrfs.o mffs.o mtfsb0.o mtfsb1.o \ |
12 | mtfsf.o mtfsfi.o stfiwx.o stfs.o \ | 12 | mtfsf.o mtfsfi.o stfiwx.o stfs.o \ |
13 | udivmodti4.o | 13 | udivmodti4.o |
14 | |||
15 | CFLAGS_fabs.o = -fno-builtin-fabs | ||
16 | CFLAGS_math.o = -fno-builtin-fabs | ||
diff --git a/arch/powerpc/oprofile/backtrace.c b/arch/powerpc/oprofile/backtrace.c index 75f57bc96b40..b4278cfd1f80 100644 --- a/arch/powerpc/oprofile/backtrace.c +++ b/arch/powerpc/oprofile/backtrace.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/sched.h> | 11 | #include <linux/sched.h> |
12 | #include <asm/processor.h> | 12 | #include <asm/processor.h> |
13 | #include <asm/uaccess.h> | 13 | #include <asm/uaccess.h> |
14 | #include <asm/compat.h> | ||
14 | 15 | ||
15 | #define STACK_SP(STACK) *(STACK) | 16 | #define STACK_SP(STACK) *(STACK) |
16 | 17 | ||
@@ -26,8 +27,9 @@ | |||
26 | static unsigned int user_getsp32(unsigned int sp, int is_first) | 27 | static unsigned int user_getsp32(unsigned int sp, int is_first) |
27 | { | 28 | { |
28 | unsigned int stack_frame[2]; | 29 | unsigned int stack_frame[2]; |
30 | void __user *p = compat_ptr(sp); | ||
29 | 31 | ||
30 | if (!access_ok(VERIFY_READ, sp, sizeof(stack_frame))) | 32 | if (!access_ok(VERIFY_READ, p, sizeof(stack_frame))) |
31 | return 0; | 33 | return 0; |
32 | 34 | ||
33 | /* | 35 | /* |
@@ -35,8 +37,7 @@ static unsigned int user_getsp32(unsigned int sp, int is_first) | |||
35 | * which means that we've done all that we can do from | 37 | * which means that we've done all that we can do from |
36 | * interrupt context. | 38 | * interrupt context. |
37 | */ | 39 | */ |
38 | if (__copy_from_user_inatomic(stack_frame, (void *)(long)sp, | 40 | if (__copy_from_user_inatomic(stack_frame, p, sizeof(stack_frame))) |
39 | sizeof(stack_frame))) | ||
40 | return 0; | 41 | return 0; |
41 | 42 | ||
42 | if (!is_first) | 43 | if (!is_first) |
@@ -54,10 +55,10 @@ static unsigned long user_getsp64(unsigned long sp, int is_first) | |||
54 | { | 55 | { |
55 | unsigned long stack_frame[3]; | 56 | unsigned long stack_frame[3]; |
56 | 57 | ||
57 | if (!access_ok(VERIFY_READ, sp, sizeof(stack_frame))) | 58 | if (!access_ok(VERIFY_READ, (void __user *)sp, sizeof(stack_frame))) |
58 | return 0; | 59 | return 0; |
59 | 60 | ||
60 | if (__copy_from_user_inatomic(stack_frame, (void *)sp, | 61 | if (__copy_from_user_inatomic(stack_frame, (void __user *)sp, |
61 | sizeof(stack_frame))) | 62 | sizeof(stack_frame))) |
62 | return 0; | 63 | return 0; |
63 | 64 | ||
diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c index 969fbb6d8c46..8c676d763bb0 100644 --- a/arch/powerpc/platforms/83xx/mpc834x_itx.c +++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c | |||
@@ -109,6 +109,10 @@ static int __init mpc834x_itx_probe(void) | |||
109 | return 1; | 109 | return 1; |
110 | } | 110 | } |
111 | 111 | ||
112 | #ifdef CONFIG_RTC_CLASS | ||
113 | late_initcall(rtc_class_hookup); | ||
114 | #endif | ||
115 | |||
112 | define_machine(mpc834x_itx) { | 116 | define_machine(mpc834x_itx) { |
113 | .name = "MPC834x ITX", | 117 | .name = "MPC834x ITX", |
114 | .probe = mpc834x_itx_probe, | 118 | .probe = mpc834x_itx_probe, |
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index c3268d9877e4..0584f3c7e884 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig | |||
@@ -11,6 +11,12 @@ config MPC8540_ADS | |||
11 | help | 11 | help |
12 | This option enables support for the MPC 8540 ADS board | 12 | This option enables support for the MPC 8540 ADS board |
13 | 13 | ||
14 | config MPC8560_ADS | ||
15 | bool "Freescale MPC8560 ADS" | ||
16 | select DEFAULT_UIMAGE | ||
17 | help | ||
18 | This option enables support for the MPC 8560 ADS board | ||
19 | |||
14 | config MPC85xx_CDS | 20 | config MPC85xx_CDS |
15 | bool "Freescale MPC85xx CDS" | 21 | bool "Freescale MPC85xx CDS" |
16 | select DEFAULT_UIMAGE | 22 | select DEFAULT_UIMAGE |
@@ -25,6 +31,11 @@ config MPC8540 | |||
25 | select PPC_INDIRECT_PCI | 31 | select PPC_INDIRECT_PCI |
26 | default y if MPC8540_ADS || MPC85xx_CDS | 32 | default y if MPC8540_ADS || MPC85xx_CDS |
27 | 33 | ||
34 | config MPC8560 | ||
35 | bool | ||
36 | select PPC_INDIRECT_PCI | ||
37 | default y if MPC8560_ADS | ||
38 | |||
28 | config PPC_INDIRECT_PCI_BE | 39 | config PPC_INDIRECT_PCI_BE |
29 | bool | 40 | bool |
30 | depends on PPC_85xx | 41 | depends on PPC_85xx |
@@ -34,4 +45,14 @@ config MPIC | |||
34 | bool | 45 | bool |
35 | default y | 46 | default y |
36 | 47 | ||
48 | config CPM2 | ||
49 | bool | ||
50 | depends on MPC8560 | ||
51 | default y | ||
52 | help | ||
53 | The CPM2 (Communications Processor Module) is a coprocessor on | ||
54 | embedded CPUs made by Motorola. Selecting this option means that | ||
55 | you wish to build a kernel for a machine with a CPM2 coprocessor | ||
56 | on it. | ||
57 | |||
37 | endmenu | 58 | endmenu |
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index 7615aa59c78b..282f5d0d0152 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile | |||
@@ -3,4 +3,5 @@ | |||
3 | # | 3 | # |
4 | obj-$(CONFIG_PPC_85xx) += misc.o pci.o | 4 | obj-$(CONFIG_PPC_85xx) += misc.o pci.o |
5 | obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o | 5 | obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o |
6 | obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o | ||
6 | obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o | 7 | obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o |
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c index cae6b73357d5..28070e7ae507 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c | |||
@@ -32,6 +32,13 @@ | |||
32 | #include <sysdev/fsl_soc.h> | 32 | #include <sysdev/fsl_soc.h> |
33 | #include "mpc85xx.h" | 33 | #include "mpc85xx.h" |
34 | 34 | ||
35 | #ifdef CONFIG_CPM2 | ||
36 | #include <linux/fs_enet_pd.h> | ||
37 | #include <asm/cpm2.h> | ||
38 | #include <sysdev/cpm2_pic.h> | ||
39 | #include <asm/fs_pd.h> | ||
40 | #endif | ||
41 | |||
35 | #ifndef CONFIG_PCI | 42 | #ifndef CONFIG_PCI |
36 | unsigned long isa_io_base = 0; | 43 | unsigned long isa_io_base = 0; |
37 | unsigned long isa_mem_base = 0; | 44 | unsigned long isa_mem_base = 0; |
@@ -57,12 +64,29 @@ mpc85xx_pcibios_fixup(void) | |||
57 | } | 64 | } |
58 | #endif /* CONFIG_PCI */ | 65 | #endif /* CONFIG_PCI */ |
59 | 66 | ||
67 | #ifdef CONFIG_CPM2 | ||
68 | |||
69 | static void cpm2_cascade(unsigned int irq, struct irq_desc *desc, | ||
70 | struct pt_regs *regs) | ||
71 | { | ||
72 | int cascade_irq; | ||
73 | |||
74 | while ((cascade_irq = cpm2_get_irq(regs)) >= 0) { | ||
75 | generic_handle_irq(cascade_irq, regs); | ||
76 | } | ||
77 | desc->chip->eoi(irq); | ||
78 | } | ||
79 | |||
80 | #endif /* CONFIG_CPM2 */ | ||
60 | 81 | ||
61 | void __init mpc85xx_ads_pic_init(void) | 82 | void __init mpc85xx_ads_pic_init(void) |
62 | { | 83 | { |
63 | struct mpic *mpic; | 84 | struct mpic *mpic; |
64 | struct resource r; | 85 | struct resource r; |
65 | struct device_node *np = NULL; | 86 | struct device_node *np = NULL; |
87 | #ifdef CONFIG_CPM2 | ||
88 | int irq; | ||
89 | #endif | ||
66 | 90 | ||
67 | np = of_find_node_by_type(np, "open-pic"); | 91 | np = of_find_node_by_type(np, "open-pic"); |
68 | 92 | ||
@@ -104,11 +128,103 @@ void __init mpc85xx_ads_pic_init(void) | |||
104 | mpic_assign_isu(mpic, 14, r.start + 0x10100); | 128 | mpic_assign_isu(mpic, 14, r.start + 0x10100); |
105 | 129 | ||
106 | mpic_init(mpic); | 130 | mpic_init(mpic); |
131 | |||
132 | #ifdef CONFIG_CPM2 | ||
133 | /* Setup CPM2 PIC */ | ||
134 | np = of_find_node_by_type(NULL, "cpm-pic"); | ||
135 | if (np == NULL) { | ||
136 | printk(KERN_ERR "PIC init: can not find cpm-pic node\n"); | ||
137 | return; | ||
138 | } | ||
139 | irq = irq_of_parse_and_map(np, 0); | ||
140 | |||
141 | cpm2_pic_init(np); | ||
142 | set_irq_chained_handler(irq, cpm2_cascade); | ||
143 | #endif | ||
107 | } | 144 | } |
108 | 145 | ||
109 | /* | 146 | /* |
110 | * Setup the architecture | 147 | * Setup the architecture |
111 | */ | 148 | */ |
149 | #ifdef CONFIG_CPM2 | ||
150 | void init_fcc_ioports(struct fs_platform_info *fpi) | ||
151 | { | ||
152 | struct io_port *io = cpm2_map(im_ioport); | ||
153 | int fcc_no = fs_get_fcc_index(fpi->fs_no); | ||
154 | int target; | ||
155 | u32 tempval; | ||
156 | |||
157 | switch(fcc_no) { | ||
158 | case 1: | ||
159 | tempval = in_be32(&io->iop_pdirb); | ||
160 | tempval &= ~PB2_DIRB0; | ||
161 | tempval |= PB2_DIRB1; | ||
162 | out_be32(&io->iop_pdirb, tempval); | ||
163 | |||
164 | tempval = in_be32(&io->iop_psorb); | ||
165 | tempval &= ~PB2_PSORB0; | ||
166 | tempval |= PB2_PSORB1; | ||
167 | out_be32(&io->iop_psorb, tempval); | ||
168 | |||
169 | tempval = in_be32(&io->iop_pparb); | ||
170 | tempval |= (PB2_DIRB0 | PB2_DIRB1); | ||
171 | out_be32(&io->iop_pparb, tempval); | ||
172 | |||
173 | target = CPM_CLK_FCC2; | ||
174 | break; | ||
175 | case 2: | ||
176 | tempval = in_be32(&io->iop_pdirb); | ||
177 | tempval &= ~PB3_DIRB0; | ||
178 | tempval |= PB3_DIRB1; | ||
179 | out_be32(&io->iop_pdirb, tempval); | ||
180 | |||
181 | tempval = in_be32(&io->iop_psorb); | ||
182 | tempval &= ~PB3_PSORB0; | ||
183 | tempval |= PB3_PSORB1; | ||
184 | out_be32(&io->iop_psorb, tempval); | ||
185 | |||
186 | tempval = in_be32(&io->iop_pparb); | ||
187 | tempval |= (PB3_DIRB0 | PB3_DIRB1); | ||
188 | out_be32(&io->iop_pparb, tempval); | ||
189 | |||
190 | tempval = in_be32(&io->iop_pdirc); | ||
191 | tempval |= PC3_DIRC1; | ||
192 | out_be32(&io->iop_pdirc, tempval); | ||
193 | |||
194 | tempval = in_be32(&io->iop_pparc); | ||
195 | tempval |= PC3_DIRC1; | ||
196 | out_be32(&io->iop_pparc, tempval); | ||
197 | |||
198 | target = CPM_CLK_FCC3; | ||
199 | break; | ||
200 | default: | ||
201 | printk(KERN_ERR "init_fcc_ioports: invalid FCC number\n"); | ||
202 | return; | ||
203 | } | ||
204 | |||
205 | /* Port C has clocks...... */ | ||
206 | tempval = in_be32(&io->iop_psorc); | ||
207 | tempval &= ~(PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8)); | ||
208 | out_be32(&io->iop_psorc, tempval); | ||
209 | |||
210 | tempval = in_be32(&io->iop_pdirc); | ||
211 | tempval &= ~(PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8)); | ||
212 | out_be32(&io->iop_pdirc, tempval); | ||
213 | tempval = in_be32(&io->iop_pparc); | ||
214 | tempval |= (PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8)); | ||
215 | out_be32(&io->iop_pparc, tempval); | ||
216 | |||
217 | cpm2_unmap(io); | ||
218 | |||
219 | /* Configure Serial Interface clock routing. | ||
220 | * First, clear FCC bits to zero, | ||
221 | * then set the ones we want. | ||
222 | */ | ||
223 | cpm2_clk_setup(target, fpi->clk_rx, CPM_CLK_RX); | ||
224 | cpm2_clk_setup(target, fpi->clk_tx, CPM_CLK_TX); | ||
225 | } | ||
226 | #endif | ||
227 | |||
112 | static void __init mpc85xx_ads_setup_arch(void) | 228 | static void __init mpc85xx_ads_setup_arch(void) |
113 | { | 229 | { |
114 | struct device_node *cpu; | 230 | struct device_node *cpu; |
@@ -131,6 +247,10 @@ static void __init mpc85xx_ads_setup_arch(void) | |||
131 | of_node_put(cpu); | 247 | of_node_put(cpu); |
132 | } | 248 | } |
133 | 249 | ||
250 | #ifdef CONFIG_CPM2 | ||
251 | cpm2_reset(); | ||
252 | #endif | ||
253 | |||
134 | #ifdef CONFIG_PCI | 254 | #ifdef CONFIG_PCI |
135 | for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) | 255 | for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) |
136 | add_bridge(np); | 256 | add_bridge(np); |
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.h b/arch/powerpc/platforms/85xx/mpc85xx_ads.h new file mode 100644 index 000000000000..effcbf78f851 --- /dev/null +++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.h | |||
@@ -0,0 +1,61 @@ | |||
1 | /* | ||
2 | * MPC85xx ADS board definitions | ||
3 | * | ||
4 | * Maintainer: Kumar Gala <galak@kernel.crashing.org> | ||
5 | * | ||
6 | * Copyright 2004 Freescale Semiconductor Inc. | ||
7 | * | ||
8 | * 2006 (c) MontaVista Software, Inc. | ||
9 | * Vitaly Bordug <vbordug@ru.mvista.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the | ||
13 | * Free Software Foundation; either version 2 of the License, or (at your | ||
14 | * option) any later version. | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #ifndef __MACH_MPC85XXADS_H | ||
19 | #define __MACH_MPC85XXADS_H | ||
20 | |||
21 | #include <linux/config.h> | ||
22 | #include <linux/initrd.h> | ||
23 | #include <sysdev/fsl_soc.h> | ||
24 | |||
25 | #define BCSR_ADDR ((uint)0xf8000000) | ||
26 | #define BCSR_SIZE ((uint)(32 * 1024)) | ||
27 | |||
28 | #ifdef CONFIG_CPM2 | ||
29 | |||
30 | #define MPC85xx_CPM_OFFSET (0x80000) | ||
31 | |||
32 | #define CPM_MAP_ADDR (get_immrbase() + MPC85xx_CPM_OFFSET) | ||
33 | #define CPM_IRQ_OFFSET 60 | ||
34 | |||
35 | #define SIU_INT_SMC1 ((uint)0x04+CPM_IRQ_OFFSET) | ||
36 | #define SIU_INT_SMC2 ((uint)0x05+CPM_IRQ_OFFSET) | ||
37 | #define SIU_INT_SCC1 ((uint)0x28+CPM_IRQ_OFFSET) | ||
38 | #define SIU_INT_SCC2 ((uint)0x29+CPM_IRQ_OFFSET) | ||
39 | #define SIU_INT_SCC3 ((uint)0x2a+CPM_IRQ_OFFSET) | ||
40 | #define SIU_INT_SCC4 ((uint)0x2b+CPM_IRQ_OFFSET) | ||
41 | |||
42 | /* FCC1 Clock Source Configuration. These can be | ||
43 | * redefined in the board specific file. | ||
44 | * Can only choose from CLK9-12 */ | ||
45 | #define F1_RXCLK 12 | ||
46 | #define F1_TXCLK 11 | ||
47 | |||
48 | /* FCC2 Clock Source Configuration. These can be | ||
49 | * redefined in the board specific file. | ||
50 | * Can only choose from CLK13-16 */ | ||
51 | #define F2_RXCLK 13 | ||
52 | #define F2_TXCLK 14 | ||
53 | |||
54 | /* FCC3 Clock Source Configuration. These can be | ||
55 | * redefined in the board specific file. | ||
56 | * Can only choose from CLK13-16 */ | ||
57 | #define F3_RXCLK 15 | ||
58 | #define F3_TXCLK 16 | ||
59 | |||
60 | #endif /* CONFIG_CPM2 */ | ||
61 | #endif /* __MACH_MPC85XXADS_H */ | ||
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 3bd36d46ab4a..0f5c8ebc7fc3 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c | |||
@@ -538,7 +538,7 @@ static void __iomem * __init map_spe_prop(struct spu *spu, | |||
538 | 538 | ||
539 | const void *p; | 539 | const void *p; |
540 | int proplen; | 540 | int proplen; |
541 | void* ret = NULL; | 541 | void __iomem *ret = NULL; |
542 | int err = 0; | 542 | int err = 0; |
543 | 543 | ||
544 | p = get_property(n, name, &proplen); | 544 | p = get_property(n, name, &proplen); |
@@ -562,7 +562,7 @@ static void spu_unmap(struct spu *spu) | |||
562 | iounmap(spu->priv2); | 562 | iounmap(spu->priv2); |
563 | iounmap(spu->priv1); | 563 | iounmap(spu->priv1); |
564 | iounmap(spu->problem); | 564 | iounmap(spu->problem); |
565 | iounmap((u8 __iomem *)spu->local_store); | 565 | iounmap((__force u8 __iomem *)spu->local_store); |
566 | } | 566 | } |
567 | 567 | ||
568 | /* This function shall be abstracted for HV platforms */ | 568 | /* This function shall be abstracted for HV platforms */ |
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 58e794f9da1b..51fd197ab5dd 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c | |||
@@ -1342,7 +1342,7 @@ static u64 spufs_id_get(void *data) | |||
1342 | 1342 | ||
1343 | return num; | 1343 | return num; |
1344 | } | 1344 | } |
1345 | DEFINE_SIMPLE_ATTRIBUTE(spufs_id_ops, spufs_id_get, 0, "0x%llx\n") | 1345 | DEFINE_SIMPLE_ATTRIBUTE(spufs_id_ops, spufs_id_get, NULL, "0x%llx\n") |
1346 | 1346 | ||
1347 | struct tree_descr spufs_dir_contents[] = { | 1347 | struct tree_descr spufs_dir_contents[] = { |
1348 | { "mem", &spufs_mem_fops, 0666, }, | 1348 | { "mem", &spufs_mem_fops, 0666, }, |
diff --git a/arch/powerpc/platforms/cell/spufs/hw_ops.c b/arch/powerpc/platforms/cell/spufs/hw_ops.c index c8670f519734..efc452e71ab0 100644 --- a/arch/powerpc/platforms/cell/spufs/hw_ops.c +++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c | |||
@@ -234,7 +234,7 @@ static void spu_hw_runcntl_stop(struct spu_context *ctx) | |||
234 | 234 | ||
235 | static int spu_hw_set_mfc_query(struct spu_context * ctx, u32 mask, u32 mode) | 235 | static int spu_hw_set_mfc_query(struct spu_context * ctx, u32 mask, u32 mode) |
236 | { | 236 | { |
237 | struct spu_problem *prob = ctx->spu->problem; | 237 | struct spu_problem __iomem *prob = ctx->spu->problem; |
238 | int ret; | 238 | int ret; |
239 | 239 | ||
240 | spin_lock_irq(&ctx->spu->register_lock); | 240 | spin_lock_irq(&ctx->spu->register_lock); |
@@ -263,7 +263,7 @@ static int spu_hw_send_mfc_command(struct spu_context *ctx, | |||
263 | struct mfc_dma_command *cmd) | 263 | struct mfc_dma_command *cmd) |
264 | { | 264 | { |
265 | u32 status; | 265 | u32 status; |
266 | struct spu_problem *prob = ctx->spu->problem; | 266 | struct spu_problem __iomem *prob = ctx->spu->problem; |
267 | 267 | ||
268 | spin_lock_irq(&ctx->spu->register_lock); | 268 | spin_lock_irq(&ctx->spu->register_lock); |
269 | out_be32(&prob->mfc_lsa_W, cmd->lsa); | 269 | out_be32(&prob->mfc_lsa_W, cmd->lsa); |
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c index c3aa46b8e2b9..1b827618e05f 100644 --- a/arch/powerpc/platforms/maple/pci.c +++ b/arch/powerpc/platforms/maple/pci.c | |||
@@ -96,14 +96,14 @@ static unsigned long u3_agp_cfa1(u8 bus, u8 devfn, u8 off) | |||
96 | 1UL; | 96 | 1UL; |
97 | } | 97 | } |
98 | 98 | ||
99 | static unsigned long u3_agp_cfg_access(struct pci_controller* hose, | 99 | static volatile void __iomem *u3_agp_cfg_access(struct pci_controller* hose, |
100 | u8 bus, u8 dev_fn, u8 offset) | 100 | u8 bus, u8 dev_fn, u8 offset) |
101 | { | 101 | { |
102 | unsigned int caddr; | 102 | unsigned int caddr; |
103 | 103 | ||
104 | if (bus == hose->first_busno) { | 104 | if (bus == hose->first_busno) { |
105 | if (dev_fn < (11 << 3)) | 105 | if (dev_fn < (11 << 3)) |
106 | return 0; | 106 | return NULL; |
107 | caddr = u3_agp_cfa0(dev_fn, offset); | 107 | caddr = u3_agp_cfa0(dev_fn, offset); |
108 | } else | 108 | } else |
109 | caddr = u3_agp_cfa1(bus, dev_fn, offset); | 109 | caddr = u3_agp_cfa1(bus, dev_fn, offset); |
@@ -114,14 +114,14 @@ static unsigned long u3_agp_cfg_access(struct pci_controller* hose, | |||
114 | } while (in_le32(hose->cfg_addr) != caddr); | 114 | } while (in_le32(hose->cfg_addr) != caddr); |
115 | 115 | ||
116 | offset &= 0x07; | 116 | offset &= 0x07; |
117 | return ((unsigned long)hose->cfg_data) + offset; | 117 | return hose->cfg_data + offset; |
118 | } | 118 | } |
119 | 119 | ||
120 | static int u3_agp_read_config(struct pci_bus *bus, unsigned int devfn, | 120 | static int u3_agp_read_config(struct pci_bus *bus, unsigned int devfn, |
121 | int offset, int len, u32 *val) | 121 | int offset, int len, u32 *val) |
122 | { | 122 | { |
123 | struct pci_controller *hose; | 123 | struct pci_controller *hose; |
124 | unsigned long addr; | 124 | volatile void __iomem *addr; |
125 | 125 | ||
126 | hose = pci_bus_to_host(bus); | 126 | hose = pci_bus_to_host(bus); |
127 | if (hose == NULL) | 127 | if (hose == NULL) |
@@ -136,13 +136,13 @@ static int u3_agp_read_config(struct pci_bus *bus, unsigned int devfn, | |||
136 | */ | 136 | */ |
137 | switch (len) { | 137 | switch (len) { |
138 | case 1: | 138 | case 1: |
139 | *val = in_8((u8 *)addr); | 139 | *val = in_8(addr); |
140 | break; | 140 | break; |
141 | case 2: | 141 | case 2: |
142 | *val = in_le16((u16 *)addr); | 142 | *val = in_le16(addr); |
143 | break; | 143 | break; |
144 | default: | 144 | default: |
145 | *val = in_le32((u32 *)addr); | 145 | *val = in_le32(addr); |
146 | break; | 146 | break; |
147 | } | 147 | } |
148 | return PCIBIOS_SUCCESSFUL; | 148 | return PCIBIOS_SUCCESSFUL; |
@@ -152,7 +152,7 @@ static int u3_agp_write_config(struct pci_bus *bus, unsigned int devfn, | |||
152 | int offset, int len, u32 val) | 152 | int offset, int len, u32 val) |
153 | { | 153 | { |
154 | struct pci_controller *hose; | 154 | struct pci_controller *hose; |
155 | unsigned long addr; | 155 | volatile void __iomem *addr; |
156 | 156 | ||
157 | hose = pci_bus_to_host(bus); | 157 | hose = pci_bus_to_host(bus); |
158 | if (hose == NULL) | 158 | if (hose == NULL) |
@@ -167,16 +167,16 @@ static int u3_agp_write_config(struct pci_bus *bus, unsigned int devfn, | |||
167 | */ | 167 | */ |
168 | switch (len) { | 168 | switch (len) { |
169 | case 1: | 169 | case 1: |
170 | out_8((u8 *)addr, val); | 170 | out_8(addr, val); |
171 | (void) in_8((u8 *)addr); | 171 | (void) in_8(addr); |
172 | break; | 172 | break; |
173 | case 2: | 173 | case 2: |
174 | out_le16((u16 *)addr, val); | 174 | out_le16(addr, val); |
175 | (void) in_le16((u16 *)addr); | 175 | (void) in_le16(addr); |
176 | break; | 176 | break; |
177 | default: | 177 | default: |
178 | out_le32((u32 *)addr, val); | 178 | out_le32(addr, val); |
179 | (void) in_le32((u32 *)addr); | 179 | (void) in_le32(addr); |
180 | break; | 180 | break; |
181 | } | 181 | } |
182 | return PCIBIOS_SUCCESSFUL; | 182 | return PCIBIOS_SUCCESSFUL; |
@@ -198,22 +198,22 @@ static unsigned long u3_ht_cfa1(u8 bus, u8 devfn, u8 off) | |||
198 | return u3_ht_cfa0(devfn, off) + (bus << 16) + 0x01000000UL; | 198 | return u3_ht_cfa0(devfn, off) + (bus << 16) + 0x01000000UL; |
199 | } | 199 | } |
200 | 200 | ||
201 | static unsigned long u3_ht_cfg_access(struct pci_controller* hose, | 201 | static volatile void __iomem *u3_ht_cfg_access(struct pci_controller* hose, |
202 | u8 bus, u8 devfn, u8 offset) | 202 | u8 bus, u8 devfn, u8 offset) |
203 | { | 203 | { |
204 | if (bus == hose->first_busno) { | 204 | if (bus == hose->first_busno) { |
205 | if (PCI_SLOT(devfn) == 0) | 205 | if (PCI_SLOT(devfn) == 0) |
206 | return 0; | 206 | return NULL; |
207 | return ((unsigned long)hose->cfg_data) + u3_ht_cfa0(devfn, offset); | 207 | return hose->cfg_data + u3_ht_cfa0(devfn, offset); |
208 | } else | 208 | } else |
209 | return ((unsigned long)hose->cfg_data) + u3_ht_cfa1(bus, devfn, offset); | 209 | return hose->cfg_data + u3_ht_cfa1(bus, devfn, offset); |
210 | } | 210 | } |
211 | 211 | ||
212 | static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, | 212 | static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, |
213 | int offset, int len, u32 *val) | 213 | int offset, int len, u32 *val) |
214 | { | 214 | { |
215 | struct pci_controller *hose; | 215 | struct pci_controller *hose; |
216 | unsigned long addr; | 216 | volatile void __iomem *addr; |
217 | 217 | ||
218 | hose = pci_bus_to_host(bus); | 218 | hose = pci_bus_to_host(bus); |
219 | if (hose == NULL) | 219 | if (hose == NULL) |
@@ -232,13 +232,13 @@ static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, | |||
232 | */ | 232 | */ |
233 | switch (len) { | 233 | switch (len) { |
234 | case 1: | 234 | case 1: |
235 | *val = in_8((u8 *)addr); | 235 | *val = in_8(addr); |
236 | break; | 236 | break; |
237 | case 2: | 237 | case 2: |
238 | *val = in_le16((u16 *)addr); | 238 | *val = in_le16(addr); |
239 | break; | 239 | break; |
240 | default: | 240 | default: |
241 | *val = in_le32((u32 *)addr); | 241 | *val = in_le32(addr); |
242 | break; | 242 | break; |
243 | } | 243 | } |
244 | return PCIBIOS_SUCCESSFUL; | 244 | return PCIBIOS_SUCCESSFUL; |
@@ -248,7 +248,7 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, | |||
248 | int offset, int len, u32 val) | 248 | int offset, int len, u32 val) |
249 | { | 249 | { |
250 | struct pci_controller *hose; | 250 | struct pci_controller *hose; |
251 | unsigned long addr; | 251 | volatile void __iomem *addr; |
252 | 252 | ||
253 | hose = pci_bus_to_host(bus); | 253 | hose = pci_bus_to_host(bus); |
254 | if (hose == NULL) | 254 | if (hose == NULL) |
@@ -266,16 +266,16 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, | |||
266 | */ | 266 | */ |
267 | switch (len) { | 267 | switch (len) { |
268 | case 1: | 268 | case 1: |
269 | out_8((u8 *)addr, val); | 269 | out_8(addr, val); |
270 | (void) in_8((u8 *)addr); | 270 | (void) in_8(addr); |
271 | break; | 271 | break; |
272 | case 2: | 272 | case 2: |
273 | out_le16((u16 *)addr, val); | 273 | out_le16(addr, val); |
274 | (void) in_le16((u16 *)addr); | 274 | (void) in_le16(addr); |
275 | break; | 275 | break; |
276 | default: | 276 | default: |
277 | out_le32((u32 *)addr, val); | 277 | out_le32(addr, val); |
278 | (void) in_le32((u32 *)addr); | 278 | (void) in_le32(addr); |
279 | break; | 279 | break; |
280 | } | 280 | } |
281 | return PCIBIOS_SUCCESSFUL; | 281 | return PCIBIOS_SUCCESSFUL; |
@@ -315,7 +315,7 @@ static void __init setup_u3_ht(struct pci_controller* hose) | |||
315 | * the reg address cell, we shall fix that by killing struct | 315 | * the reg address cell, we shall fix that by killing struct |
316 | * reg_property and using some accessor functions instead | 316 | * reg_property and using some accessor functions instead |
317 | */ | 317 | */ |
318 | hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000, 0x02000000); | 318 | hose->cfg_data = ioremap(0xf2000000, 0x02000000); |
319 | 319 | ||
320 | hose->first_busno = 0; | 320 | hose->first_busno = 0; |
321 | hose->last_busno = 0xef; | 321 | hose->last_busno = 0xef; |
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 84bc8f7e17ef..3c2d63ebf787 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c | |||
@@ -225,6 +225,7 @@ static void __eeh_mark_slot (struct device_node *dn, int mode_flag) | |||
225 | 225 | ||
226 | void eeh_mark_slot (struct device_node *dn, int mode_flag) | 226 | void eeh_mark_slot (struct device_node *dn, int mode_flag) |
227 | { | 227 | { |
228 | struct pci_dev *dev; | ||
228 | dn = find_device_pe (dn); | 229 | dn = find_device_pe (dn); |
229 | 230 | ||
230 | /* Back up one, since config addrs might be shared */ | 231 | /* Back up one, since config addrs might be shared */ |
@@ -232,6 +233,12 @@ void eeh_mark_slot (struct device_node *dn, int mode_flag) | |||
232 | dn = dn->parent; | 233 | dn = dn->parent; |
233 | 234 | ||
234 | PCI_DN(dn)->eeh_mode |= mode_flag; | 235 | PCI_DN(dn)->eeh_mode |= mode_flag; |
236 | |||
237 | /* Mark the pci device too */ | ||
238 | dev = PCI_DN(dn)->pcidev; | ||
239 | if (dev) | ||
240 | dev->error_state = pci_channel_io_frozen; | ||
241 | |||
235 | __eeh_mark_slot (dn->child, mode_flag); | 242 | __eeh_mark_slot (dn->child, mode_flag); |
236 | } | 243 | } |
237 | 244 | ||
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 98189d8efaca..43dbf737698c 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
@@ -415,12 +415,6 @@ static int pSeries_check_legacy_ioport(unsigned int baseport) | |||
415 | return -ENODEV; | 415 | return -ENODEV; |
416 | of_node_put(np); | 416 | of_node_put(np); |
417 | break; | 417 | break; |
418 | case PARALLEL_BASE: | ||
419 | np = of_find_node_by_type(NULL, "parallel"); | ||
420 | if (np == NULL) | ||
421 | return -ENODEV; | ||
422 | of_node_put(np); | ||
423 | break; | ||
424 | } | 418 | } |
425 | return 0; | 419 | return 0; |
426 | } | 420 | } |
@@ -483,7 +477,6 @@ static void pseries_dedicated_idle_sleep(void) | |||
483 | { | 477 | { |
484 | unsigned int cpu = smp_processor_id(); | 478 | unsigned int cpu = smp_processor_id(); |
485 | unsigned long start_snooze; | 479 | unsigned long start_snooze; |
486 | unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay); | ||
487 | 480 | ||
488 | /* | 481 | /* |
489 | * Indicate to the HV that we are idle. Now would be | 482 | * Indicate to the HV that we are idle. Now would be |
@@ -496,9 +489,9 @@ static void pseries_dedicated_idle_sleep(void) | |||
496 | * has been checked recently. If we should poll for a little | 489 | * has been checked recently. If we should poll for a little |
497 | * while, do so. | 490 | * while, do so. |
498 | */ | 491 | */ |
499 | if (*smt_snooze_delay) { | 492 | if (__get_cpu_var(smt_snooze_delay)) { |
500 | start_snooze = get_tb() + | 493 | start_snooze = get_tb() + |
501 | *smt_snooze_delay * tb_ticks_per_usec; | 494 | __get_cpu_var(smt_snooze_delay) * tb_ticks_per_usec; |
502 | local_irq_enable(); | 495 | local_irq_enable(); |
503 | set_thread_flag(TIF_POLLING_NRFLAG); | 496 | set_thread_flag(TIF_POLLING_NRFLAG); |
504 | 497 | ||
@@ -518,24 +511,7 @@ static void pseries_dedicated_idle_sleep(void) | |||
518 | goto out; | 511 | goto out; |
519 | } | 512 | } |
520 | 513 | ||
521 | /* | 514 | cede_processor(); |
522 | * If not SMT, cede processor. If CPU is running SMT | ||
523 | * cede if the other thread is not idle, so that it can | ||
524 | * go single-threaded. If the other thread is idle, | ||
525 | * we ask the hypervisor if it has pending work it | ||
526 | * wants to do and cede if it does. Otherwise we keep | ||
527 | * polling in order to reduce interrupt latency. | ||
528 | * | ||
529 | * Doing the cede when the other thread is active will | ||
530 | * result in this thread going dormant, meaning the other | ||
531 | * thread gets to run in single-threaded (ST) mode, which | ||
532 | * is slightly faster than SMT mode with this thread at | ||
533 | * very low priority. The cede enables interrupts, which | ||
534 | * doesn't matter here. | ||
535 | */ | ||
536 | if (!cpu_has_feature(CPU_FTR_SMT) || !lppaca[cpu ^ 1].idle | ||
537 | || poll_pending() == H_PENDING) | ||
538 | cede_processor(); | ||
539 | 515 | ||
540 | out: | 516 | out: |
541 | HMT_medium(); | 517 | HMT_medium(); |
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index e5e999ea891a..f15f4d78aee9 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile | |||
@@ -17,3 +17,8 @@ ifeq ($(CONFIG_PPC_MERGE),y) | |||
17 | obj-$(CONFIG_PPC_I8259) += i8259.o | 17 | obj-$(CONFIG_PPC_I8259) += i8259.o |
18 | obj-$(CONFIG_PPC_83xx) += ipic.o | 18 | obj-$(CONFIG_PPC_83xx) += ipic.o |
19 | endif | 19 | endif |
20 | |||
21 | # Temporary hack until we have migrated to asm-powerpc | ||
22 | ifeq ($(ARCH),powerpc) | ||
23 | obj-$(CONFIG_CPM2) += cpm2_common.o cpm2_pic.o | ||
24 | endif | ||
diff --git a/arch/powerpc/sysdev/cpm2_common.c b/arch/powerpc/sysdev/cpm2_common.c new file mode 100644 index 000000000000..ec265995d5d8 --- /dev/null +++ b/arch/powerpc/sysdev/cpm2_common.c | |||
@@ -0,0 +1,309 @@ | |||
1 | /* | ||
2 | * General Purpose functions for the global management of the | ||
3 | * 8260 Communication Processor Module. | ||
4 | * Copyright (c) 1999-2001 Dan Malek <dan@embeddedalley.com> | ||
5 | * Copyright (c) 2000 MontaVista Software, Inc (source@mvista.com) | ||
6 | * 2.3.99 Updates | ||
7 | * | ||
8 | * 2006 (c) MontaVista Software, Inc. | ||
9 | * Vitaly Bordug <vbordug@ru.mvista.com> | ||
10 | * Merged to arch/powerpc from arch/ppc/syslib/cpm2_common.c | ||
11 | * | ||
12 | * This file is licensed under the terms of the GNU General Public License | ||
13 | * version 2. This program is licensed "as is" without any warranty of any | ||
14 | * kind, whether express or implied. | ||
15 | */ | ||
16 | |||
17 | /* | ||
18 | * | ||
19 | * In addition to the individual control of the communication | ||
20 | * channels, there are a few functions that globally affect the | ||
21 | * communication processor. | ||
22 | * | ||
23 | * Buffer descriptors must be allocated from the dual ported memory | ||
24 | * space. The allocator for that is here. When the communication | ||
25 | * process is reset, we reclaim the memory available. There is | ||
26 | * currently no deallocator for this memory. | ||
27 | */ | ||
28 | #include <linux/errno.h> | ||
29 | #include <linux/sched.h> | ||
30 | #include <linux/kernel.h> | ||
31 | #include <linux/param.h> | ||
32 | #include <linux/string.h> | ||
33 | #include <linux/mm.h> | ||
34 | #include <linux/interrupt.h> | ||
35 | #include <linux/module.h> | ||
36 | #include <asm/io.h> | ||
37 | #include <asm/irq.h> | ||
38 | #include <asm/mpc8260.h> | ||
39 | #include <asm/page.h> | ||
40 | #include <asm/pgtable.h> | ||
41 | #include <asm/cpm2.h> | ||
42 | #include <asm/rheap.h> | ||
43 | #include <asm/fs_pd.h> | ||
44 | |||
45 | #include <sysdev/fsl_soc.h> | ||
46 | |||
47 | static void cpm2_dpinit(void); | ||
48 | cpm_cpm2_t *cpmp; /* Pointer to comm processor space */ | ||
49 | |||
50 | /* We allocate this here because it is used almost exclusively for | ||
51 | * the communication processor devices. | ||
52 | */ | ||
53 | cpm2_map_t *cpm2_immr; | ||
54 | intctl_cpm2_t *cpm2_intctl; | ||
55 | |||
56 | #define CPM_MAP_SIZE (0x40000) /* 256k - the PQ3 reserve this amount | ||
57 | of space for CPM as it is larger | ||
58 | than on PQ2 */ | ||
59 | |||
60 | void | ||
61 | cpm2_reset(void) | ||
62 | { | ||
63 | cpm2_immr = (cpm2_map_t *)ioremap(CPM_MAP_ADDR, CPM_MAP_SIZE); | ||
64 | cpm2_intctl = cpm2_map(im_intctl); | ||
65 | |||
66 | /* Reclaim the DP memory for our use. | ||
67 | */ | ||
68 | cpm2_dpinit(); | ||
69 | |||
70 | /* Tell everyone where the comm processor resides. | ||
71 | */ | ||
72 | cpmp = &cpm2_immr->im_cpm; | ||
73 | } | ||
74 | |||
75 | /* Set a baud rate generator. This needs lots of work. There are | ||
76 | * eight BRGs, which can be connected to the CPM channels or output | ||
77 | * as clocks. The BRGs are in two different block of internal | ||
78 | * memory mapped space. | ||
79 | * The baud rate clock is the system clock divided by something. | ||
80 | * It was set up long ago during the initial boot phase and is | ||
81 | * is given to us. | ||
82 | * Baud rate clocks are zero-based in the driver code (as that maps | ||
83 | * to port numbers). Documentation uses 1-based numbering. | ||
84 | */ | ||
85 | #define BRG_INT_CLK (get_brgfreq()) | ||
86 | #define BRG_UART_CLK (BRG_INT_CLK/16) | ||
87 | |||
88 | /* This function is used by UARTS, or anything else that uses a 16x | ||
89 | * oversampled clock. | ||
90 | */ | ||
91 | void | ||
92 | cpm_setbrg(uint brg, uint rate) | ||
93 | { | ||
94 | volatile uint *bp; | ||
95 | |||
96 | /* This is good enough to get SMCs running..... | ||
97 | */ | ||
98 | if (brg < 4) { | ||
99 | bp = cpm2_map_size(im_brgc1, 16); | ||
100 | } else { | ||
101 | bp = cpm2_map_size(im_brgc5, 16); | ||
102 | brg -= 4; | ||
103 | } | ||
104 | bp += brg; | ||
105 | *bp = ((BRG_UART_CLK / rate) << 1) | CPM_BRG_EN; | ||
106 | |||
107 | cpm2_unmap(bp); | ||
108 | } | ||
109 | |||
110 | /* This function is used to set high speed synchronous baud rate | ||
111 | * clocks. | ||
112 | */ | ||
113 | void | ||
114 | cpm2_fastbrg(uint brg, uint rate, int div16) | ||
115 | { | ||
116 | volatile uint *bp; | ||
117 | |||
118 | if (brg < 4) { | ||
119 | bp = cpm2_map_size(im_brgc1, 16); | ||
120 | } | ||
121 | else { | ||
122 | bp = cpm2_map_size(im_brgc5, 16); | ||
123 | brg -= 4; | ||
124 | } | ||
125 | bp += brg; | ||
126 | *bp = ((BRG_INT_CLK / rate) << 1) | CPM_BRG_EN; | ||
127 | if (div16) | ||
128 | *bp |= CPM_BRG_DIV16; | ||
129 | |||
130 | cpm2_unmap(bp); | ||
131 | } | ||
132 | |||
133 | int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode) | ||
134 | { | ||
135 | int ret = 0; | ||
136 | int shift; | ||
137 | int i, bits = 0; | ||
138 | cpmux_t *im_cpmux; | ||
139 | u32 *reg; | ||
140 | u32 mask = 7; | ||
141 | u8 clk_map [24][3] = { | ||
142 | {CPM_CLK_FCC1, CPM_BRG5, 0}, | ||
143 | {CPM_CLK_FCC1, CPM_BRG6, 1}, | ||
144 | {CPM_CLK_FCC1, CPM_BRG7, 2}, | ||
145 | {CPM_CLK_FCC1, CPM_BRG8, 3}, | ||
146 | {CPM_CLK_FCC1, CPM_CLK9, 4}, | ||
147 | {CPM_CLK_FCC1, CPM_CLK10, 5}, | ||
148 | {CPM_CLK_FCC1, CPM_CLK11, 6}, | ||
149 | {CPM_CLK_FCC1, CPM_CLK12, 7}, | ||
150 | {CPM_CLK_FCC2, CPM_BRG5, 0}, | ||
151 | {CPM_CLK_FCC2, CPM_BRG6, 1}, | ||
152 | {CPM_CLK_FCC2, CPM_BRG7, 2}, | ||
153 | {CPM_CLK_FCC2, CPM_BRG8, 3}, | ||
154 | {CPM_CLK_FCC2, CPM_CLK13, 4}, | ||
155 | {CPM_CLK_FCC2, CPM_CLK14, 5}, | ||
156 | {CPM_CLK_FCC2, CPM_CLK15, 6}, | ||
157 | {CPM_CLK_FCC2, CPM_CLK16, 7}, | ||
158 | {CPM_CLK_FCC3, CPM_BRG5, 0}, | ||
159 | {CPM_CLK_FCC3, CPM_BRG6, 1}, | ||
160 | {CPM_CLK_FCC3, CPM_BRG7, 2}, | ||
161 | {CPM_CLK_FCC3, CPM_BRG8, 3}, | ||
162 | {CPM_CLK_FCC3, CPM_CLK13, 4}, | ||
163 | {CPM_CLK_FCC3, CPM_CLK14, 5}, | ||
164 | {CPM_CLK_FCC3, CPM_CLK15, 6}, | ||
165 | {CPM_CLK_FCC3, CPM_CLK16, 7} | ||
166 | }; | ||
167 | |||
168 | im_cpmux = cpm2_map(im_cpmux); | ||
169 | |||
170 | switch (target) { | ||
171 | case CPM_CLK_SCC1: | ||
172 | reg = &im_cpmux->cmx_scr; | ||
173 | shift = 24; | ||
174 | case CPM_CLK_SCC2: | ||
175 | reg = &im_cpmux->cmx_scr; | ||
176 | shift = 16; | ||
177 | break; | ||
178 | case CPM_CLK_SCC3: | ||
179 | reg = &im_cpmux->cmx_scr; | ||
180 | shift = 8; | ||
181 | break; | ||
182 | case CPM_CLK_SCC4: | ||
183 | reg = &im_cpmux->cmx_scr; | ||
184 | shift = 0; | ||
185 | break; | ||
186 | case CPM_CLK_FCC1: | ||
187 | reg = &im_cpmux->cmx_fcr; | ||
188 | shift = 24; | ||
189 | break; | ||
190 | case CPM_CLK_FCC2: | ||
191 | reg = &im_cpmux->cmx_fcr; | ||
192 | shift = 16; | ||
193 | break; | ||
194 | case CPM_CLK_FCC3: | ||
195 | reg = &im_cpmux->cmx_fcr; | ||
196 | shift = 8; | ||
197 | break; | ||
198 | default: | ||
199 | printk(KERN_ERR "cpm2_clock_setup: invalid clock target\n"); | ||
200 | return -EINVAL; | ||
201 | } | ||
202 | |||
203 | if (mode == CPM_CLK_RX) | ||
204 | shift +=3; | ||
205 | |||
206 | for (i=0; i<24; i++) { | ||
207 | if (clk_map[i][0] == target && clk_map[i][1] == clock) { | ||
208 | bits = clk_map[i][2]; | ||
209 | break; | ||
210 | } | ||
211 | } | ||
212 | if (i == sizeof(clk_map)/3) | ||
213 | ret = -EINVAL; | ||
214 | |||
215 | bits <<= shift; | ||
216 | mask <<= shift; | ||
217 | out_be32(reg, (in_be32(reg) & ~mask) | bits); | ||
218 | |||
219 | cpm2_unmap(im_cpmux); | ||
220 | return ret; | ||
221 | } | ||
222 | |||
223 | /* | ||
224 | * dpalloc / dpfree bits. | ||
225 | */ | ||
226 | static spinlock_t cpm_dpmem_lock; | ||
227 | /* 16 blocks should be enough to satisfy all requests | ||
228 | * until the memory subsystem goes up... */ | ||
229 | static rh_block_t cpm_boot_dpmem_rh_block[16]; | ||
230 | static rh_info_t cpm_dpmem_info; | ||
231 | static u8* im_dprambase; | ||
232 | |||
233 | static void cpm2_dpinit(void) | ||
234 | { | ||
235 | spin_lock_init(&cpm_dpmem_lock); | ||
236 | |||
237 | im_dprambase = ioremap(CPM_MAP_ADDR, CPM_DATAONLY_BASE + CPM_DATAONLY_SIZE); | ||
238 | |||
239 | /* initialize the info header */ | ||
240 | rh_init(&cpm_dpmem_info, 1, | ||
241 | sizeof(cpm_boot_dpmem_rh_block) / | ||
242 | sizeof(cpm_boot_dpmem_rh_block[0]), | ||
243 | cpm_boot_dpmem_rh_block); | ||
244 | |||
245 | /* Attach the usable dpmem area */ | ||
246 | /* XXX: This is actually crap. CPM_DATAONLY_BASE and | ||
247 | * CPM_DATAONLY_SIZE is only a subset of the available dpram. It | ||
248 | * varies with the processor and the microcode patches activated. | ||
249 | * But the following should be at least safe. | ||
250 | */ | ||
251 | rh_attach_region(&cpm_dpmem_info, (void *)CPM_DATAONLY_BASE, | ||
252 | CPM_DATAONLY_SIZE); | ||
253 | } | ||
254 | |||
255 | /* This function returns an index into the DPRAM area. | ||
256 | */ | ||
257 | uint cpm_dpalloc(uint size, uint align) | ||
258 | { | ||
259 | void *start; | ||
260 | unsigned long flags; | ||
261 | |||
262 | spin_lock_irqsave(&cpm_dpmem_lock, flags); | ||
263 | cpm_dpmem_info.alignment = align; | ||
264 | start = rh_alloc(&cpm_dpmem_info, size, "commproc"); | ||
265 | spin_unlock_irqrestore(&cpm_dpmem_lock, flags); | ||
266 | |||
267 | return (uint)start; | ||
268 | } | ||
269 | EXPORT_SYMBOL(cpm_dpalloc); | ||
270 | |||
271 | int cpm_dpfree(uint offset) | ||
272 | { | ||
273 | int ret; | ||
274 | unsigned long flags; | ||
275 | |||
276 | spin_lock_irqsave(&cpm_dpmem_lock, flags); | ||
277 | ret = rh_free(&cpm_dpmem_info, (void *)offset); | ||
278 | spin_unlock_irqrestore(&cpm_dpmem_lock, flags); | ||
279 | |||
280 | return ret; | ||
281 | } | ||
282 | EXPORT_SYMBOL(cpm_dpfree); | ||
283 | |||
284 | /* not sure if this is ever needed */ | ||
285 | uint cpm_dpalloc_fixed(uint offset, uint size, uint align) | ||
286 | { | ||
287 | void *start; | ||
288 | unsigned long flags; | ||
289 | |||
290 | spin_lock_irqsave(&cpm_dpmem_lock, flags); | ||
291 | cpm_dpmem_info.alignment = align; | ||
292 | start = rh_alloc_fixed(&cpm_dpmem_info, (void *)offset, size, "commproc"); | ||
293 | spin_unlock_irqrestore(&cpm_dpmem_lock, flags); | ||
294 | |||
295 | return (uint)start; | ||
296 | } | ||
297 | EXPORT_SYMBOL(cpm_dpalloc_fixed); | ||
298 | |||
299 | void cpm_dpdump(void) | ||
300 | { | ||
301 | rh_dump(&cpm_dpmem_info); | ||
302 | } | ||
303 | EXPORT_SYMBOL(cpm_dpdump); | ||
304 | |||
305 | void *cpm_dpram_addr(uint offset) | ||
306 | { | ||
307 | return (void *)(im_dprambase + offset); | ||
308 | } | ||
309 | EXPORT_SYMBOL(cpm_dpram_addr); | ||
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c new file mode 100644 index 000000000000..51752990f7b9 --- /dev/null +++ b/arch/powerpc/sysdev/cpm2_pic.c | |||
@@ -0,0 +1,256 @@ | |||
1 | /* | ||
2 | * Platform information definitions. | ||
3 | * | ||
4 | * Copied from arch/ppc/syslib/cpm2_pic.c with minor subsequent updates | ||
5 | * to make in work in arch/powerpc/. Original (c) belongs to Dan Malek. | ||
6 | * | ||
7 | * Author: Vitaly Bordug <vbordug@ru.mvista.com> | ||
8 | * | ||
9 | * 1999-2001 (c) Dan Malek <dan@embeddedalley.com> | ||
10 | * 2006 (c) MontaVista Software, Inc. | ||
11 | * | ||
12 | * This file is licensed under the terms of the GNU General Public License | ||
13 | * version 2. This program is licensed "as is" without any warranty of any | ||
14 | * kind, whether express or implied. | ||
15 | */ | ||
16 | |||
17 | /* The CPM2 internal interrupt controller. It is usually | ||
18 | * the only interrupt controller. | ||
19 | * There are two 32-bit registers (high/low) for up to 64 | ||
20 | * possible interrupts. | ||
21 | * | ||
22 | * Now, the fun starts.....Interrupt Numbers DO NOT MAP | ||
23 | * in a simple arithmetic fashion to mask or pending registers. | ||
24 | * That is, interrupt 4 does not map to bit position 4. | ||
25 | * We create two tables, indexed by vector number, to indicate | ||
26 | * which register to use and which bit in the register to use. | ||
27 | */ | ||
28 | |||
29 | #include <linux/stddef.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/sched.h> | ||
32 | #include <linux/signal.h> | ||
33 | #include <linux/irq.h> | ||
34 | |||
35 | #include <asm/immap_cpm2.h> | ||
36 | #include <asm/mpc8260.h> | ||
37 | #include <asm/io.h> | ||
38 | #include <asm/prom.h> | ||
39 | |||
40 | #include "cpm2_pic.h" | ||
41 | |||
42 | static struct device_node *cpm2_pic_node; | ||
43 | static struct irq_host *cpm2_pic_host; | ||
44 | #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) | ||
45 | static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; | ||
46 | |||
47 | static const u_char irq_to_siureg[] = { | ||
48 | 1, 1, 1, 1, 1, 1, 1, 1, | ||
49 | 1, 1, 1, 1, 1, 1, 1, 1, | ||
50 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
51 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
52 | 1, 1, 1, 1, 1, 1, 1, 1, | ||
53 | 1, 1, 1, 1, 1, 1, 1, 1, | ||
54 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
55 | 0, 0, 0, 0, 0, 0, 0, 0 | ||
56 | }; | ||
57 | |||
58 | /* bit numbers do not match the docs, these are precomputed so the bit for | ||
59 | * a given irq is (1 << irq_to_siubit[irq]) */ | ||
60 | static const u_char irq_to_siubit[] = { | ||
61 | 0, 15, 14, 13, 12, 11, 10, 9, | ||
62 | 8, 7, 6, 5, 4, 3, 2, 1, | ||
63 | 2, 1, 0, 14, 13, 12, 11, 10, | ||
64 | 9, 8, 7, 6, 5, 4, 3, 0, | ||
65 | 31, 30, 29, 28, 27, 26, 25, 24, | ||
66 | 23, 22, 21, 20, 19, 18, 17, 16, | ||
67 | 16, 17, 18, 19, 20, 21, 22, 23, | ||
68 | 24, 25, 26, 27, 28, 29, 30, 31, | ||
69 | }; | ||
70 | |||
71 | static void cpm2_mask_irq(unsigned int irq_nr) | ||
72 | { | ||
73 | int bit, word; | ||
74 | volatile uint *simr; | ||
75 | |||
76 | irq_nr -= CPM_IRQ_OFFSET; | ||
77 | |||
78 | bit = irq_to_siubit[irq_nr]; | ||
79 | word = irq_to_siureg[irq_nr]; | ||
80 | |||
81 | simr = &(cpm2_intctl->ic_simrh); | ||
82 | ppc_cached_irq_mask[word] &= ~(1 << bit); | ||
83 | simr[word] = ppc_cached_irq_mask[word]; | ||
84 | } | ||
85 | |||
86 | static void cpm2_unmask_irq(unsigned int irq_nr) | ||
87 | { | ||
88 | int bit, word; | ||
89 | volatile uint *simr; | ||
90 | |||
91 | irq_nr -= CPM_IRQ_OFFSET; | ||
92 | |||
93 | bit = irq_to_siubit[irq_nr]; | ||
94 | word = irq_to_siureg[irq_nr]; | ||
95 | |||
96 | simr = &(cpm2_intctl->ic_simrh); | ||
97 | ppc_cached_irq_mask[word] |= 1 << bit; | ||
98 | simr[word] = ppc_cached_irq_mask[word]; | ||
99 | } | ||
100 | |||
101 | static void cpm2_mask_and_ack(unsigned int irq_nr) | ||
102 | { | ||
103 | int bit, word; | ||
104 | volatile uint *simr, *sipnr; | ||
105 | |||
106 | irq_nr -= CPM_IRQ_OFFSET; | ||
107 | |||
108 | bit = irq_to_siubit[irq_nr]; | ||
109 | word = irq_to_siureg[irq_nr]; | ||
110 | |||
111 | simr = &(cpm2_intctl->ic_simrh); | ||
112 | sipnr = &(cpm2_intctl->ic_sipnrh); | ||
113 | ppc_cached_irq_mask[word] &= ~(1 << bit); | ||
114 | simr[word] = ppc_cached_irq_mask[word]; | ||
115 | sipnr[word] = 1 << bit; | ||
116 | } | ||
117 | |||
118 | static void cpm2_end_irq(unsigned int irq_nr) | ||
119 | { | ||
120 | int bit, word; | ||
121 | volatile uint *simr; | ||
122 | |||
123 | if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS)) | ||
124 | && irq_desc[irq_nr].action) { | ||
125 | |||
126 | irq_nr -= CPM_IRQ_OFFSET; | ||
127 | bit = irq_to_siubit[irq_nr]; | ||
128 | word = irq_to_siureg[irq_nr]; | ||
129 | |||
130 | simr = &(cpm2_intctl->ic_simrh); | ||
131 | ppc_cached_irq_mask[word] |= 1 << bit; | ||
132 | simr[word] = ppc_cached_irq_mask[word]; | ||
133 | /* | ||
134 | * Work around large numbers of spurious IRQs on PowerPC 82xx | ||
135 | * systems. | ||
136 | */ | ||
137 | mb(); | ||
138 | } | ||
139 | } | ||
140 | |||
141 | static struct irq_chip cpm2_pic = { | ||
142 | .typename = " CPM2 SIU ", | ||
143 | .enable = cpm2_unmask_irq, | ||
144 | .disable = cpm2_mask_irq, | ||
145 | .unmask = cpm2_unmask_irq, | ||
146 | .mask_ack = cpm2_mask_and_ack, | ||
147 | .end = cpm2_end_irq, | ||
148 | }; | ||
149 | |||
150 | int cpm2_get_irq(struct pt_regs *regs) | ||
151 | { | ||
152 | int irq; | ||
153 | unsigned long bits; | ||
154 | |||
155 | /* For CPM2, read the SIVEC register and shift the bits down | ||
156 | * to get the irq number. */ | ||
157 | bits = cpm2_intctl->ic_sivec; | ||
158 | irq = bits >> 26; | ||
159 | |||
160 | if (irq == 0) | ||
161 | return(-1); | ||
162 | return irq+CPM_IRQ_OFFSET; | ||
163 | } | ||
164 | |||
165 | static int cpm2_pic_host_match(struct irq_host *h, struct device_node *node) | ||
166 | { | ||
167 | return cpm2_pic_node == NULL || cpm2_pic_node == node; | ||
168 | } | ||
169 | |||
170 | static int cpm2_pic_host_map(struct irq_host *h, unsigned int virq, | ||
171 | irq_hw_number_t hw) | ||
172 | { | ||
173 | pr_debug("cpm2_pic_host_map(%d, 0x%lx)\n", virq, hw); | ||
174 | |||
175 | get_irq_desc(virq)->status |= IRQ_LEVEL; | ||
176 | set_irq_chip_and_handler(virq, &cpm2_pic, handle_level_irq); | ||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | static void cpm2_host_unmap(struct irq_host *h, unsigned int virq) | ||
181 | { | ||
182 | /* Make sure irq is masked in hardware */ | ||
183 | cpm2_mask_irq(virq); | ||
184 | |||
185 | /* remove chip and handler */ | ||
186 | set_irq_chip_and_handler(virq, NULL, NULL); | ||
187 | } | ||
188 | |||
189 | static int cpm2_pic_host_xlate(struct irq_host *h, struct device_node *ct, | ||
190 | u32 *intspec, unsigned int intsize, | ||
191 | irq_hw_number_t *out_hwirq, unsigned int *out_flags) | ||
192 | { | ||
193 | static const unsigned char map_cpm2_senses[4] = { | ||
194 | IRQ_TYPE_LEVEL_LOW, | ||
195 | IRQ_TYPE_LEVEL_HIGH, | ||
196 | IRQ_TYPE_EDGE_FALLING, | ||
197 | IRQ_TYPE_EDGE_RISING, | ||
198 | }; | ||
199 | |||
200 | *out_hwirq = intspec[0]; | ||
201 | if (intsize > 1 && intspec[1] < 4) | ||
202 | *out_flags = map_cpm2_senses[intspec[1]]; | ||
203 | else | ||
204 | *out_flags = IRQ_TYPE_NONE; | ||
205 | |||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | static struct irq_host_ops cpm2_pic_host_ops = { | ||
210 | .match = cpm2_pic_host_match, | ||
211 | .map = cpm2_pic_host_map, | ||
212 | .unmap = cpm2_host_unmap, | ||
213 | .xlate = cpm2_pic_host_xlate, | ||
214 | }; | ||
215 | |||
216 | void cpm2_pic_init(struct device_node *node) | ||
217 | { | ||
218 | int i; | ||
219 | |||
220 | /* Clear the CPM IRQ controller, in case it has any bits set | ||
221 | * from the bootloader | ||
222 | */ | ||
223 | |||
224 | /* Mask out everything */ | ||
225 | |||
226 | cpm2_intctl->ic_simrh = 0x00000000; | ||
227 | cpm2_intctl->ic_simrl = 0x00000000; | ||
228 | |||
229 | wmb(); | ||
230 | |||
231 | /* Ack everything */ | ||
232 | cpm2_intctl->ic_sipnrh = 0xffffffff; | ||
233 | cpm2_intctl->ic_sipnrl = 0xffffffff; | ||
234 | wmb(); | ||
235 | |||
236 | /* Dummy read of the vector */ | ||
237 | i = cpm2_intctl->ic_sivec; | ||
238 | rmb(); | ||
239 | |||
240 | /* Initialize the default interrupt mapping priorities, | ||
241 | * in case the boot rom changed something on us. | ||
242 | */ | ||
243 | cpm2_intctl->ic_sicr = 0; | ||
244 | cpm2_intctl->ic_scprrh = 0x05309770; | ||
245 | cpm2_intctl->ic_scprrl = 0x05309770; | ||
246 | |||
247 | /* create a legacy host */ | ||
248 | if (node) | ||
249 | cpm2_pic_node = of_node_get(node); | ||
250 | |||
251 | cpm2_pic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, 64, &cpm2_pic_host_ops, 64); | ||
252 | if (cpm2_pic_host == NULL) { | ||
253 | printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n"); | ||
254 | return; | ||
255 | } | ||
256 | } | ||
diff --git a/arch/powerpc/sysdev/cpm2_pic.h b/arch/powerpc/sysdev/cpm2_pic.h new file mode 100644 index 000000000000..d63e45d4df58 --- /dev/null +++ b/arch/powerpc/sysdev/cpm2_pic.h | |||
@@ -0,0 +1,10 @@ | |||
1 | #ifndef _PPC_KERNEL_CPM2_H | ||
2 | #define _PPC_KERNEL_CPM2_H | ||
3 | |||
4 | extern intctl_cpm2_t *cpm2_intctl; | ||
5 | |||
6 | extern int cpm2_get_irq(struct pt_regs *regs); | ||
7 | |||
8 | extern void cpm2_pic_init(struct device_node*); | ||
9 | |||
10 | #endif /* _PPC_KERNEL_CPM2_H */ | ||
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index 92ba378b7990..022ed275ea68 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c | |||
@@ -3,6 +3,9 @@ | |||
3 | * | 3 | * |
4 | * Maintained by Kumar Gala (see MAINTAINERS for contact information) | 4 | * Maintained by Kumar Gala (see MAINTAINERS for contact information) |
5 | * | 5 | * |
6 | * 2006 (c) MontaVista Software, Inc. | ||
7 | * Vitaly Bordug <vbordug@ru.mvista.com> | ||
8 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | 9 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of the GNU General Public License as published by the | 10 | * under the terms of the GNU General Public License as published by the |
8 | * Free Software Foundation; either version 2 of the License, or (at your | 11 | * Free Software Foundation; either version 2 of the License, or (at your |
@@ -20,15 +23,20 @@ | |||
20 | #include <linux/device.h> | 23 | #include <linux/device.h> |
21 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
22 | #include <linux/fsl_devices.h> | 25 | #include <linux/fsl_devices.h> |
26 | #include <linux/fs_enet_pd.h> | ||
27 | #include <linux/fs_uart_pd.h> | ||
23 | 28 | ||
24 | #include <asm/system.h> | 29 | #include <asm/system.h> |
25 | #include <asm/atomic.h> | 30 | #include <asm/atomic.h> |
26 | #include <asm/io.h> | 31 | #include <asm/io.h> |
27 | #include <asm/irq.h> | 32 | #include <asm/irq.h> |
33 | #include <asm/time.h> | ||
28 | #include <asm/prom.h> | 34 | #include <asm/prom.h> |
29 | #include <sysdev/fsl_soc.h> | 35 | #include <sysdev/fsl_soc.h> |
30 | #include <mm/mmu_decl.h> | 36 | #include <mm/mmu_decl.h> |
37 | #include <asm/cpm2.h> | ||
31 | 38 | ||
39 | extern void init_fcc_ioports(struct fs_platform_info*); | ||
32 | static phys_addr_t immrbase = -1; | 40 | static phys_addr_t immrbase = -1; |
33 | 41 | ||
34 | phys_addr_t get_immrbase(void) | 42 | phys_addr_t get_immrbase(void) |
@@ -42,7 +50,9 @@ phys_addr_t get_immrbase(void) | |||
42 | if (soc) { | 50 | if (soc) { |
43 | unsigned int size; | 51 | unsigned int size; |
44 | const void *prop = get_property(soc, "reg", &size); | 52 | const void *prop = get_property(soc, "reg", &size); |
45 | immrbase = of_translate_address(soc, prop); | 53 | |
54 | if (prop) | ||
55 | immrbase = of_translate_address(soc, prop); | ||
46 | of_node_put(soc); | 56 | of_node_put(soc); |
47 | }; | 57 | }; |
48 | 58 | ||
@@ -51,6 +61,59 @@ phys_addr_t get_immrbase(void) | |||
51 | 61 | ||
52 | EXPORT_SYMBOL(get_immrbase); | 62 | EXPORT_SYMBOL(get_immrbase); |
53 | 63 | ||
64 | #ifdef CONFIG_CPM2 | ||
65 | |||
66 | static u32 brgfreq = -1; | ||
67 | |||
68 | u32 get_brgfreq(void) | ||
69 | { | ||
70 | struct device_node *node; | ||
71 | |||
72 | if (brgfreq != -1) | ||
73 | return brgfreq; | ||
74 | |||
75 | node = of_find_node_by_type(NULL, "cpm"); | ||
76 | if (node) { | ||
77 | unsigned int size; | ||
78 | const unsigned int *prop = get_property(node, "brg-frequency", | ||
79 | &size); | ||
80 | |||
81 | if (prop) | ||
82 | brgfreq = *prop; | ||
83 | of_node_put(node); | ||
84 | }; | ||
85 | |||
86 | return brgfreq; | ||
87 | } | ||
88 | |||
89 | EXPORT_SYMBOL(get_brgfreq); | ||
90 | |||
91 | static u32 fs_baudrate = -1; | ||
92 | |||
93 | u32 get_baudrate(void) | ||
94 | { | ||
95 | struct device_node *node; | ||
96 | |||
97 | if (fs_baudrate != -1) | ||
98 | return fs_baudrate; | ||
99 | |||
100 | node = of_find_node_by_type(NULL, "serial"); | ||
101 | if (node) { | ||
102 | unsigned int size; | ||
103 | const unsigned int *prop = get_property(node, "current-speed", | ||
104 | &size); | ||
105 | |||
106 | if (prop) | ||
107 | fs_baudrate = *prop; | ||
108 | of_node_put(node); | ||
109 | }; | ||
110 | |||
111 | return fs_baudrate; | ||
112 | } | ||
113 | |||
114 | EXPORT_SYMBOL(get_baudrate); | ||
115 | #endif /* CONFIG_CPM2 */ | ||
116 | |||
54 | static int __init gfar_mdio_of_init(void) | 117 | static int __init gfar_mdio_of_init(void) |
55 | { | 118 | { |
56 | struct device_node *np; | 119 | struct device_node *np; |
@@ -85,8 +148,11 @@ static int __init gfar_mdio_of_init(void) | |||
85 | mdio_data.irq[k] = -1; | 148 | mdio_data.irq[k] = -1; |
86 | 149 | ||
87 | while ((child = of_get_next_child(np, child)) != NULL) { | 150 | while ((child = of_get_next_child(np, child)) != NULL) { |
88 | const u32 *id = get_property(child, "reg", NULL); | 151 | int irq = irq_of_parse_and_map(child, 0); |
89 | mdio_data.irq[*id] = irq_of_parse_and_map(child, 0); | 152 | if (irq != NO_IRQ) { |
153 | const u32 *id = get_property(child, "reg", NULL); | ||
154 | mdio_data.irq[*id] = irq; | ||
155 | } | ||
90 | } | 156 | } |
91 | 157 | ||
92 | ret = | 158 | ret = |
@@ -128,7 +194,7 @@ static int __init gfar_of_init(void) | |||
128 | const char *model; | 194 | const char *model; |
129 | const void *mac_addr; | 195 | const void *mac_addr; |
130 | const phandle *ph; | 196 | const phandle *ph; |
131 | int n_res = 1; | 197 | int n_res = 2; |
132 | 198 | ||
133 | memset(r, 0, sizeof(r)); | 199 | memset(r, 0, sizeof(r)); |
134 | memset(&gfar_data, 0, sizeof(gfar_data)); | 200 | memset(&gfar_data, 0, sizeof(gfar_data)); |
@@ -159,7 +225,7 @@ static int __init gfar_of_init(void) | |||
159 | 225 | ||
160 | gfar_dev = | 226 | gfar_dev = |
161 | platform_device_register_simple("fsl-gianfar", i, &r[0], | 227 | platform_device_register_simple("fsl-gianfar", i, &r[0], |
162 | n_res + 1); | 228 | n_res); |
163 | 229 | ||
164 | if (IS_ERR(gfar_dev)) { | 230 | if (IS_ERR(gfar_dev)) { |
165 | ret = PTR_ERR(gfar_dev); | 231 | ret = PTR_ERR(gfar_dev); |
@@ -478,3 +544,208 @@ err: | |||
478 | } | 544 | } |
479 | 545 | ||
480 | arch_initcall(fsl_usb_of_init); | 546 | arch_initcall(fsl_usb_of_init); |
547 | |||
548 | #ifdef CONFIG_CPM2 | ||
549 | |||
550 | static const char fcc_regs[] = "fcc_regs"; | ||
551 | static const char fcc_regs_c[] = "fcc_regs_c"; | ||
552 | static const char fcc_pram[] = "fcc_pram"; | ||
553 | static char bus_id[9][BUS_ID_SIZE]; | ||
554 | |||
555 | static int __init fs_enet_of_init(void) | ||
556 | { | ||
557 | struct device_node *np; | ||
558 | unsigned int i; | ||
559 | struct platform_device *fs_enet_dev; | ||
560 | struct resource res; | ||
561 | int ret; | ||
562 | |||
563 | for (np = NULL, i = 0; | ||
564 | (np = of_find_compatible_node(np, "network", "fs_enet")) != NULL; | ||
565 | i++) { | ||
566 | struct resource r[4]; | ||
567 | struct device_node *phy, *mdio; | ||
568 | struct fs_platform_info fs_enet_data; | ||
569 | const unsigned int *id, *phy_addr; | ||
570 | const void *mac_addr; | ||
571 | const phandle *ph; | ||
572 | const char *model; | ||
573 | |||
574 | memset(r, 0, sizeof(r)); | ||
575 | memset(&fs_enet_data, 0, sizeof(fs_enet_data)); | ||
576 | |||
577 | ret = of_address_to_resource(np, 0, &r[0]); | ||
578 | if (ret) | ||
579 | goto err; | ||
580 | r[0].name = fcc_regs; | ||
581 | |||
582 | ret = of_address_to_resource(np, 1, &r[1]); | ||
583 | if (ret) | ||
584 | goto err; | ||
585 | r[1].name = fcc_pram; | ||
586 | |||
587 | ret = of_address_to_resource(np, 2, &r[2]); | ||
588 | if (ret) | ||
589 | goto err; | ||
590 | r[2].name = fcc_regs_c; | ||
591 | |||
592 | r[3].start = r[3].end = irq_of_parse_and_map(np, 0); | ||
593 | r[3].flags = IORESOURCE_IRQ; | ||
594 | |||
595 | fs_enet_dev = | ||
596 | platform_device_register_simple("fsl-cpm-fcc", i, &r[0], 4); | ||
597 | |||
598 | if (IS_ERR(fs_enet_dev)) { | ||
599 | ret = PTR_ERR(fs_enet_dev); | ||
600 | goto err; | ||
601 | } | ||
602 | |||
603 | model = get_property(np, "model", NULL); | ||
604 | if (model == NULL) { | ||
605 | ret = -ENODEV; | ||
606 | goto unreg; | ||
607 | } | ||
608 | |||
609 | mac_addr = get_property(np, "mac-address", NULL); | ||
610 | memcpy(fs_enet_data.macaddr, mac_addr, 6); | ||
611 | |||
612 | ph = get_property(np, "phy-handle", NULL); | ||
613 | phy = of_find_node_by_phandle(*ph); | ||
614 | |||
615 | if (phy == NULL) { | ||
616 | ret = -ENODEV; | ||
617 | goto unreg; | ||
618 | } | ||
619 | |||
620 | phy_addr = get_property(phy, "reg", NULL); | ||
621 | fs_enet_data.phy_addr = *phy_addr; | ||
622 | |||
623 | id = get_property(np, "device-id", NULL); | ||
624 | fs_enet_data.fs_no = *id; | ||
625 | strcpy(fs_enet_data.fs_type, model); | ||
626 | |||
627 | mdio = of_get_parent(phy); | ||
628 | ret = of_address_to_resource(mdio, 0, &res); | ||
629 | if (ret) { | ||
630 | of_node_put(phy); | ||
631 | of_node_put(mdio); | ||
632 | goto unreg; | ||
633 | } | ||
634 | |||
635 | fs_enet_data.clk_rx = *((u32 *) get_property(np, "rx-clock", NULL)); | ||
636 | fs_enet_data.clk_tx = *((u32 *) get_property(np, "tx-clock", NULL)); | ||
637 | |||
638 | if (strstr(model, "FCC")) { | ||
639 | int fcc_index = *id - 1; | ||
640 | |||
641 | fs_enet_data.dpram_offset = (u32)cpm_dpram_addr(0); | ||
642 | fs_enet_data.rx_ring = 32; | ||
643 | fs_enet_data.tx_ring = 32; | ||
644 | fs_enet_data.rx_copybreak = 240; | ||
645 | fs_enet_data.use_napi = 0; | ||
646 | fs_enet_data.napi_weight = 17; | ||
647 | fs_enet_data.mem_offset = FCC_MEM_OFFSET(fcc_index); | ||
648 | fs_enet_data.cp_page = CPM_CR_FCC_PAGE(fcc_index); | ||
649 | fs_enet_data.cp_block = CPM_CR_FCC_SBLOCK(fcc_index); | ||
650 | |||
651 | snprintf((char*)&bus_id[(*id)], BUS_ID_SIZE, "%x:%02x", | ||
652 | (u32)res.start, fs_enet_data.phy_addr); | ||
653 | fs_enet_data.bus_id = (char*)&bus_id[(*id)]; | ||
654 | fs_enet_data.init_ioports = init_fcc_ioports; | ||
655 | } | ||
656 | |||
657 | of_node_put(phy); | ||
658 | of_node_put(mdio); | ||
659 | |||
660 | ret = platform_device_add_data(fs_enet_dev, &fs_enet_data, | ||
661 | sizeof(struct | ||
662 | fs_platform_info)); | ||
663 | if (ret) | ||
664 | goto unreg; | ||
665 | } | ||
666 | return 0; | ||
667 | |||
668 | unreg: | ||
669 | platform_device_unregister(fs_enet_dev); | ||
670 | err: | ||
671 | return ret; | ||
672 | } | ||
673 | |||
674 | arch_initcall(fs_enet_of_init); | ||
675 | |||
676 | static const char scc_regs[] = "regs"; | ||
677 | static const char scc_pram[] = "pram"; | ||
678 | |||
679 | static int __init cpm_uart_of_init(void) | ||
680 | { | ||
681 | struct device_node *np; | ||
682 | unsigned int i; | ||
683 | struct platform_device *cpm_uart_dev; | ||
684 | int ret; | ||
685 | |||
686 | for (np = NULL, i = 0; | ||
687 | (np = of_find_compatible_node(np, "serial", "cpm_uart")) != NULL; | ||
688 | i++) { | ||
689 | struct resource r[3]; | ||
690 | struct fs_uart_platform_info cpm_uart_data; | ||
691 | const int *id; | ||
692 | const char *model; | ||
693 | |||
694 | memset(r, 0, sizeof(r)); | ||
695 | memset(&cpm_uart_data, 0, sizeof(cpm_uart_data)); | ||
696 | |||
697 | ret = of_address_to_resource(np, 0, &r[0]); | ||
698 | if (ret) | ||
699 | goto err; | ||
700 | |||
701 | r[0].name = scc_regs; | ||
702 | |||
703 | ret = of_address_to_resource(np, 1, &r[1]); | ||
704 | if (ret) | ||
705 | goto err; | ||
706 | r[1].name = scc_pram; | ||
707 | |||
708 | r[2].start = r[2].end = irq_of_parse_and_map(np, 0); | ||
709 | r[2].flags = IORESOURCE_IRQ; | ||
710 | |||
711 | cpm_uart_dev = | ||
712 | platform_device_register_simple("fsl-cpm-scc:uart", i, &r[0], 3); | ||
713 | |||
714 | if (IS_ERR(cpm_uart_dev)) { | ||
715 | ret = PTR_ERR(cpm_uart_dev); | ||
716 | goto err; | ||
717 | } | ||
718 | |||
719 | id = get_property(np, "device-id", NULL); | ||
720 | cpm_uart_data.fs_no = *id; | ||
721 | |||
722 | model = (char*)get_property(np, "model", NULL); | ||
723 | strcpy(cpm_uart_data.fs_type, model); | ||
724 | |||
725 | cpm_uart_data.uart_clk = ppc_proc_freq; | ||
726 | |||
727 | cpm_uart_data.tx_num_fifo = 4; | ||
728 | cpm_uart_data.tx_buf_size = 32; | ||
729 | cpm_uart_data.rx_num_fifo = 4; | ||
730 | cpm_uart_data.rx_buf_size = 32; | ||
731 | cpm_uart_data.clk_rx = *((u32 *) get_property(np, "rx-clock", NULL)); | ||
732 | cpm_uart_data.clk_tx = *((u32 *) get_property(np, "tx-clock", NULL)); | ||
733 | |||
734 | ret = | ||
735 | platform_device_add_data(cpm_uart_dev, &cpm_uart_data, | ||
736 | sizeof(struct | ||
737 | fs_uart_platform_info)); | ||
738 | if (ret) | ||
739 | goto unreg; | ||
740 | } | ||
741 | |||
742 | return 0; | ||
743 | |||
744 | unreg: | ||
745 | platform_device_unregister(cpm_uart_dev); | ||
746 | err: | ||
747 | return ret; | ||
748 | } | ||
749 | |||
750 | arch_initcall(cpm_uart_of_init); | ||
751 | #endif /* CONFIG_CPM2 */ | ||
diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h index 5a3dd480d2fd..04e145b5fc32 100644 --- a/arch/powerpc/sysdev/fsl_soc.h +++ b/arch/powerpc/sysdev/fsl_soc.h | |||
@@ -5,6 +5,8 @@ | |||
5 | #include <asm/mmu.h> | 5 | #include <asm/mmu.h> |
6 | 6 | ||
7 | extern phys_addr_t get_immrbase(void); | 7 | extern phys_addr_t get_immrbase(void); |
8 | extern u32 get_brgfreq(void); | ||
9 | extern u32 get_baudrate(void); | ||
8 | 10 | ||
9 | #endif | 11 | #endif |
10 | #endif | 12 | #endif |
diff --git a/arch/ppc/boot/utils/mkbugboot.c b/arch/ppc/boot/utils/mkbugboot.c index 29115e01f60a..1640c4199ca6 100644 --- a/arch/ppc/boot/utils/mkbugboot.c +++ b/arch/ppc/boot/utils/mkbugboot.c | |||
@@ -19,36 +19,13 @@ | |||
19 | #include <stdlib.h> | 19 | #include <stdlib.h> |
20 | #include <errno.h> | 20 | #include <errno.h> |
21 | #include <fcntl.h> | 21 | #include <fcntl.h> |
22 | #include <netinet/in.h> | ||
22 | #ifdef __sun__ | 23 | #ifdef __sun__ |
23 | #include <inttypes.h> | 24 | #include <inttypes.h> |
24 | #else | 25 | #else |
25 | #include <stdint.h> | 26 | #include <stdint.h> |
26 | #endif | 27 | #endif |
27 | 28 | ||
28 | #ifdef __i386__ | ||
29 | #define cpu_to_be32(x) le32_to_cpu(x) | ||
30 | #define cpu_to_be16(x) le16_to_cpu(x) | ||
31 | #else | ||
32 | #define cpu_to_be32(x) (x) | ||
33 | #define cpu_to_be16(x) (x) | ||
34 | #endif | ||
35 | |||
36 | #define cpu_to_le32(x) le32_to_cpu((x)) | ||
37 | unsigned long le32_to_cpu(unsigned long x) | ||
38 | { | ||
39 | return (((x & 0x000000ffU) << 24) | | ||
40 | ((x & 0x0000ff00U) << 8) | | ||
41 | ((x & 0x00ff0000U) >> 8) | | ||
42 | ((x & 0xff000000U) >> 24)); | ||
43 | } | ||
44 | |||
45 | #define cpu_to_le16(x) le16_to_cpu((x)) | ||
46 | unsigned short le16_to_cpu(unsigned short x) | ||
47 | { | ||
48 | return (((x & 0x00ff) << 8) | | ||
49 | ((x & 0xff00) >> 8)); | ||
50 | } | ||
51 | |||
52 | /* size of read buffer */ | 29 | /* size of read buffer */ |
53 | #define SIZE 0x1000 | 30 | #define SIZE 0x1000 |
54 | 31 | ||
@@ -62,124 +39,109 @@ typedef struct bug_boot_header { | |||
62 | 39 | ||
63 | #define HEADER_SIZE sizeof(bug_boot_header_t) | 40 | #define HEADER_SIZE sizeof(bug_boot_header_t) |
64 | 41 | ||
65 | uint32_t copy_image(int32_t in_fd, int32_t out_fd) | 42 | void update_checksum(void *buf, size_t size, uint16_t *sum) |
66 | { | 43 | { |
67 | uint8_t buf[SIZE]; | 44 | uint32_t csum = *sum; |
68 | int n; | 45 | |
69 | uint32_t image_size = 0; | 46 | while (size) { |
70 | uint8_t zero = 0; | 47 | csum += *(uint16_t *)buf; |
71 | 48 | if (csum > 0xffff) | |
72 | lseek(in_fd, ELF_HEADER_SIZE, SEEK_SET); | 49 | csum -= 0xffff; |
73 | 50 | buf = (uint16_t *)buf + 1; | |
74 | /* Copy an image while recording its size */ | 51 | size -= 2; |
75 | while ( (n = read(in_fd, buf, SIZE)) > 0 ) | 52 | } |
76 | { | 53 | *sum = csum; |
77 | image_size = image_size + n; | ||
78 | write(out_fd, buf, n); | ||
79 | } | ||
80 | |||
81 | /* BUG romboot requires that our size is divisible by 2 */ | ||
82 | /* align image to 2 byte boundary */ | ||
83 | if (image_size % 2) | ||
84 | { | ||
85 | image_size++; | ||
86 | write(out_fd, &zero, 1); | ||
87 | } | ||
88 | |||
89 | return image_size; | ||
90 | } | 54 | } |
91 | 55 | ||
92 | void write_bugboot_header(int32_t out_fd, uint32_t boot_size) | 56 | uint32_t copy_image(int in_fd, int out_fd, uint16_t *sum) |
93 | { | 57 | { |
94 | uint8_t header_block[HEADER_SIZE]; | 58 | uint8_t buf[SIZE]; |
95 | bug_boot_header_t *bbh = (bug_boot_header_t *)&header_block[0]; | 59 | int offset = 0; |
96 | 60 | int n; | |
97 | memset(header_block, 0, HEADER_SIZE); | 61 | uint32_t image_size = 0; |
98 | 62 | ||
99 | /* Fill in the PPCBUG ROM boot header */ | 63 | lseek(in_fd, ELF_HEADER_SIZE, SEEK_SET); |
100 | strncpy(bbh->magic_word, "BOOT", 4); /* PPCBUG magic word */ | 64 | |
101 | bbh->entry_offset = cpu_to_be32(HEADER_SIZE); /* Entry address */ | 65 | /* Copy an image while recording its size */ |
102 | bbh->routine_length= cpu_to_be32(HEADER_SIZE+boot_size+2); /* Routine length */ | 66 | while ( (n = read(in_fd, buf + offset, SIZE - offset)) > 0 ) { |
103 | strncpy(bbh->routine_name, "LINUXROM", 8); /* Routine name */ | 67 | n += offset; |
104 | 68 | offset = n & 1; | |
105 | /* Output the header and bootloader to the file */ | 69 | n -= offset; |
106 | write(out_fd, header_block, HEADER_SIZE); | 70 | image_size = image_size + n; |
71 | /* who's going to deal with short writes? */ | ||
72 | write(out_fd, buf, n); | ||
73 | update_checksum(buf, n, sum); | ||
74 | if (offset) | ||
75 | buf[0] = buf[n]; | ||
76 | } | ||
77 | |||
78 | /* BUG romboot requires that our size is divisible by 2 */ | ||
79 | /* align image to 2 byte boundary */ | ||
80 | if (offset) { | ||
81 | image_size += 2; | ||
82 | buf[1] = '\0'; | ||
83 | write(out_fd, buf, 2); | ||
84 | update_checksum(buf, 2, sum); | ||
85 | } | ||
86 | return image_size; | ||
107 | } | 87 | } |
108 | 88 | ||
109 | uint16_t calc_checksum(int32_t bug_fd) | 89 | void write_bugboot_header(int out_fd, uint32_t boot_size, uint16_t *sum) |
110 | { | 90 | { |
111 | uint32_t checksum_var = 0; | 91 | static bug_boot_header_t bbh = { |
112 | uint8_t buf[2]; | 92 | .magic_word = "BOOT", |
113 | int n; | 93 | .routine_name = "LINUXROM" |
114 | 94 | }; | |
115 | /* Checksum loop */ | 95 | |
116 | while ( (n = read(bug_fd, buf, 2) ) ) | 96 | /* Fill in the PPCBUG ROM boot header */ |
117 | { | 97 | bbh.entry_offset = htonl(HEADER_SIZE); /* Entry address */ |
118 | checksum_var = checksum_var + *(uint16_t *)buf; | 98 | bbh.routine_length= htonl(HEADER_SIZE+boot_size+2); /* Routine length */ |
119 | 99 | ||
120 | /* If we carry out, mask it and add one to the checksum */ | 100 | /* Output the header and bootloader to the file */ |
121 | if (checksum_var >> 16) | 101 | write(out_fd, &bbh, sizeof(bug_boot_header_t)); |
122 | checksum_var = (checksum_var & 0x0000ffff) + 1; | 102 | update_checksum(&bbh, sizeof(bug_boot_header_t), sum); |
123 | } | ||
124 | |||
125 | return checksum_var; | ||
126 | } | 103 | } |
127 | 104 | ||
128 | int main(int argc, char *argv[]) | 105 | int main(int argc, char *argv[]) |
129 | { | 106 | { |
130 | int32_t image_fd, bugboot_fd; | 107 | int image_fd, bugboot_fd; |
131 | int argptr = 1; | 108 | uint32_t kernel_size = 0; |
132 | uint32_t kernel_size = 0; | 109 | uint16_t checksum = 0; |
133 | uint16_t checksum = 0; | ||
134 | uint8_t bugbootname[256]; | ||
135 | |||
136 | if ( (argc != 3) ) | ||
137 | { | ||
138 | fprintf(stderr, "usage: %s <kernel_image> <bugboot>\n",argv[0]); | ||
139 | exit(-1); | ||
140 | } | ||
141 | |||
142 | /* Get file args */ | ||
143 | |||
144 | /* kernel image file */ | ||
145 | if ((image_fd = open( argv[argptr] , 0)) < 0) | ||
146 | exit(-1); | ||
147 | argptr++; | ||
148 | 110 | ||
149 | /* bugboot file */ | 111 | if (argc != 3) { |
150 | if ( !strcmp( argv[argptr], "-" ) ) | 112 | fprintf(stderr, "usage: %s <kernel_image> <bugboot>\n",argv[0]); |
151 | bugboot_fd = 1; /* stdout */ | 113 | exit(-1); |
152 | else | 114 | } |
153 | if ((bugboot_fd = creat( argv[argptr] , 0755)) < 0) | ||
154 | exit(-1); | ||
155 | else | ||
156 | strcpy(bugbootname, argv[argptr]); | ||
157 | argptr++; | ||
158 | 115 | ||
159 | /* Set file position after ROM header block where zImage will be written */ | 116 | /* Get file args */ |
160 | lseek(bugboot_fd, HEADER_SIZE, SEEK_SET); | ||
161 | 117 | ||
162 | /* Copy kernel image into bugboot image */ | 118 | /* kernel image file */ |
163 | kernel_size = copy_image(image_fd, bugboot_fd); | 119 | if ((image_fd = open(argv[1] , 0)) < 0) |
164 | close(image_fd); | 120 | exit(-1); |
165 | 121 | ||
166 | /* Set file position to beginning where header/romboot will be written */ | 122 | /* bugboot file */ |
167 | lseek(bugboot_fd, 0, SEEK_SET); | 123 | if (!strcmp(argv[2], "-")) |
124 | bugboot_fd = 1; /* stdout */ | ||
125 | else if ((bugboot_fd = creat(argv[2] , 0755)) < 0) | ||
126 | exit(-1); | ||
168 | 127 | ||
169 | /* Write out BUG header/romboot */ | 128 | /* Set file position after ROM header block where zImage will be written */ |
170 | write_bugboot_header(bugboot_fd, kernel_size); | 129 | lseek(bugboot_fd, HEADER_SIZE, SEEK_SET); |
171 | 130 | ||
172 | /* Close bugboot file */ | 131 | /* Copy kernel image into bugboot image */ |
173 | close(bugboot_fd); | 132 | kernel_size = copy_image(image_fd, bugboot_fd, &checksum); |
174 | 133 | ||
175 | /* Reopen it as read/write */ | 134 | /* Set file position to beginning where header/romboot will be written */ |
176 | bugboot_fd = open(bugbootname, O_RDWR); | 135 | lseek(bugboot_fd, 0, SEEK_SET); |
177 | 136 | ||
178 | /* Calculate checksum */ | 137 | /* Write out BUG header/romboot */ |
179 | checksum = calc_checksum(bugboot_fd); | 138 | write_bugboot_header(bugboot_fd, kernel_size, &checksum); |
180 | 139 | ||
181 | /* Write out the calculated checksum */ | 140 | /* Write out the calculated checksum */ |
182 | write(bugboot_fd, &checksum, 2); | 141 | lseek(bugboot_fd, 0, SEEK_END); |
142 | write(bugboot_fd, &checksum, 2); | ||
183 | 143 | ||
184 | return 0; | 144 | /* Close bugboot file */ |
145 | close(bugboot_fd); | ||
146 | return 0; | ||
185 | } | 147 | } |
diff --git a/arch/ppc/boot/utils/mkprep.c b/arch/ppc/boot/utils/mkprep.c index f6d5a2f2fcf6..192bb397126f 100644 --- a/arch/ppc/boot/utils/mkprep.c +++ b/arch/ppc/boot/utils/mkprep.c | |||
@@ -15,279 +15,227 @@ | |||
15 | * Modified for Sparc hosted builds by Peter Wahl <PeterWahl@web.de> | 15 | * Modified for Sparc hosted builds by Peter Wahl <PeterWahl@web.de> |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <fcntl.h> | ||
19 | #include <stdio.h> | 18 | #include <stdio.h> |
20 | #include <stdlib.h> | ||
21 | #include <string.h> | 19 | #include <string.h> |
22 | #include <strings.h> | 20 | #include <stdlib.h> |
23 | #include <sys/stat.h> | ||
24 | #include <unistd.h> | ||
25 | |||
26 | #define cpu_to_le32(x) le32_to_cpu((x)) | ||
27 | unsigned long le32_to_cpu(unsigned long x) | ||
28 | { | ||
29 | return (((x & 0x000000ffU) << 24) | | ||
30 | ((x & 0x0000ff00U) << 8) | | ||
31 | ((x & 0x00ff0000U) >> 8) | | ||
32 | ((x & 0xff000000U) >> 24)); | ||
33 | } | ||
34 | |||
35 | |||
36 | #define cpu_to_le16(x) le16_to_cpu((x)) | ||
37 | unsigned short le16_to_cpu(unsigned short x) | ||
38 | { | ||
39 | return (((x & 0x00ff) << 8) | | ||
40 | ((x & 0xff00) >> 8)); | ||
41 | } | ||
42 | |||
43 | #define cpu_to_be32(x) (x) | ||
44 | #define be32_to_cpu(x) (x) | ||
45 | #define cpu_to_be16(x) (x) | ||
46 | #define be16_to_cpu(x) (x) | ||
47 | 21 | ||
48 | /* size of read buffer */ | 22 | /* size of read buffer */ |
49 | #define SIZE 0x1000 | 23 | #define SIZE 0x1000 |
50 | 24 | ||
51 | |||
52 | typedef unsigned long dword_t; | ||
53 | typedef unsigned short word_t; | ||
54 | typedef unsigned char byte_t; | ||
55 | typedef byte_t block_t[512]; | ||
56 | typedef byte_t page_t[4096]; | ||
57 | |||
58 | |||
59 | /* | 25 | /* |
60 | * Partition table entry | 26 | * Partition table entry |
61 | * - from the PReP spec | 27 | * - from the PReP spec |
62 | */ | 28 | */ |
63 | typedef struct partition_entry { | 29 | typedef struct partition_entry { |
64 | byte_t boot_indicator; | 30 | unsigned char boot_indicator; |
65 | byte_t starting_head; | 31 | unsigned char starting_head; |
66 | byte_t starting_sector; | 32 | unsigned char starting_sector; |
67 | byte_t starting_cylinder; | 33 | unsigned char starting_cylinder; |
68 | 34 | ||
69 | byte_t system_indicator; | 35 | unsigned char system_indicator; |
70 | byte_t ending_head; | 36 | unsigned char ending_head; |
71 | byte_t ending_sector; | 37 | unsigned char ending_sector; |
72 | byte_t ending_cylinder; | 38 | unsigned char ending_cylinder; |
73 | 39 | ||
74 | dword_t beginning_sector; | 40 | unsigned char beginning_sector[4]; |
75 | dword_t number_of_sectors; | 41 | unsigned char number_of_sectors[4]; |
76 | } partition_entry_t; | 42 | } partition_entry_t; |
77 | 43 | ||
78 | #define BootActive 0x80 | 44 | #define BootActive 0x80 |
79 | #define SystemPrep 0x41 | 45 | #define SystemPrep 0x41 |
80 | 46 | ||
81 | void copy_image(int , int); | 47 | void copy_image(FILE *, FILE *); |
82 | void write_prep_partition(int , int ); | 48 | void write_prep_partition(FILE *, FILE *); |
83 | void write_asm_data( int in, int out ); | 49 | void write_asm_data(FILE *, FILE *); |
84 | 50 | ||
85 | unsigned int elfhdr_size = 65536; | 51 | unsigned int elfhdr_size = 65536; |
86 | 52 | ||
87 | int main(int argc, char *argv[]) | 53 | int main(int argc, char *argv[]) |
88 | { | 54 | { |
89 | int in_fd, out_fd; | 55 | FILE *in, *out; |
90 | int argptr = 1; | 56 | int argptr = 1; |
91 | unsigned int prep = 0; | 57 | int prep = 0; |
92 | unsigned int asmoutput = 0; | 58 | int asmoutput = 0; |
93 | 59 | ||
94 | if ( (argc < 3) || (argc > 4) ) | 60 | if (argc < 3 || argc > 4) { |
95 | { | 61 | fprintf(stderr, "usage: %s [-pbp] [-asm] <boot-file> <image>\n", |
96 | fprintf(stderr, "usage: %s [-pbp] [-asm] <boot-file> <image>\n",argv[0]); | 62 | argv[0]); |
97 | exit(-1); | 63 | exit(-1); |
98 | } | 64 | } |
99 | 65 | ||
100 | /* needs to handle args more elegantly -- but this is a small/simple program */ | 66 | /* needs to handle args more elegantly -- but this is a small/simple program */ |
101 | 67 | ||
102 | /* check for -pbp */ | 68 | /* check for -pbp */ |
103 | if ( !strcmp( argv[argptr], "-pbp" ) ) | 69 | if (!strcmp(argv[argptr], "-pbp")) { |
104 | { | 70 | prep = 1; |
105 | prep = 1; | 71 | argptr++; |
106 | argptr++; | 72 | } |
107 | } | 73 | |
108 | 74 | /* check for -asm */ | |
109 | /* check for -asm */ | 75 | if (!strcmp(argv[argptr], "-asm")) { |
110 | if ( !strcmp( argv[argptr], "-asm" ) ) | 76 | asmoutput = 1; |
111 | { | 77 | argptr++; |
112 | asmoutput = 1; | 78 | } |
113 | argptr++; | 79 | |
114 | } | 80 | /* input file */ |
115 | 81 | if (!strcmp(argv[argptr], "-")) | |
116 | /* input file */ | 82 | in = stdin; |
117 | if ( !strcmp( argv[argptr], "-" ) ) | 83 | else if (!(in = fopen(argv[argptr], "r"))) |
118 | in_fd = 0; /* stdin */ | 84 | exit(-1); |
119 | else | 85 | argptr++; |
120 | if ((in_fd = open( argv[argptr] , 0)) < 0) | 86 | |
121 | exit(-1); | 87 | /* output file */ |
122 | argptr++; | 88 | if (!strcmp(argv[argptr], "-")) |
123 | 89 | out = stdout; | |
124 | /* output file */ | 90 | else if (!(out = fopen(argv[argptr], "w"))) |
125 | if ( !strcmp( argv[argptr], "-" ) ) | 91 | exit(-1); |
126 | out_fd = 1; /* stdout */ | 92 | argptr++; |
127 | else | 93 | |
128 | if ((out_fd = creat( argv[argptr] , 0755)) < 0) | 94 | /* skip elf header in input file */ |
129 | exit(-1); | 95 | /*if ( !prep )*/ |
130 | argptr++; | 96 | fseek(in, elfhdr_size, SEEK_SET); |
131 | 97 | ||
132 | /* skip elf header in input file */ | 98 | /* write prep partition if necessary */ |
133 | /*if ( !prep )*/ | 99 | if (prep) |
134 | lseek(in_fd, elfhdr_size, SEEK_SET); | 100 | write_prep_partition(in, out); |
135 | 101 | ||
136 | /* write prep partition if necessary */ | 102 | /* write input image to bootimage */ |
137 | if ( prep ) | 103 | if (asmoutput) |
138 | write_prep_partition( in_fd, out_fd ); | 104 | write_asm_data(in, out); |
139 | 105 | else | |
140 | /* write input image to bootimage */ | 106 | copy_image(in, out); |
141 | if ( asmoutput ) | 107 | |
142 | write_asm_data( in_fd, out_fd ); | 108 | return 0; |
143 | else | ||
144 | copy_image(in_fd, out_fd); | ||
145 | |||
146 | return 0; | ||
147 | } | 109 | } |
148 | 110 | ||
149 | void write_prep_partition(int in, int out) | 111 | void store_le32(unsigned int v, unsigned char *p) |
150 | { | 112 | { |
151 | unsigned char block[512]; | 113 | p[0] = v; |
152 | partition_entry_t pe; | 114 | p[1] = v >>= 8; |
153 | dword_t *entry = (dword_t *)&block[0]; | 115 | p[2] = v >>= 8; |
154 | dword_t *length = (dword_t *)&block[sizeof(long)]; | 116 | p[3] = v >> 8; |
155 | struct stat info; | 117 | } |
156 | 118 | ||
157 | if (fstat(in, &info) < 0) | 119 | void write_prep_partition(FILE *in, FILE *out) |
158 | { | 120 | { |
159 | fprintf(stderr,"info failed\n"); | 121 | unsigned char block[512]; |
160 | exit(-1); | 122 | partition_entry_t pe; |
161 | } | 123 | unsigned char *entry = block; |
162 | 124 | unsigned char *length = block + 4; | |
163 | bzero( block, sizeof block ); | 125 | long pos = ftell(in), size; |
164 | 126 | ||
165 | /* set entry point and boot image size skipping over elf header */ | 127 | if (fseek(in, 0, SEEK_END) < 0) { |
166 | #ifdef __i386__ | 128 | fprintf(stderr,"info failed\n"); |
167 | *entry = 0x400/*+65536*/; | 129 | exit(-1); |
168 | *length = info.st_size-elfhdr_size+0x400; | 130 | } |
169 | #else | 131 | size = ftell(in); |
170 | *entry = cpu_to_le32(0x400/*+65536*/); | 132 | if (fseek(in, pos, SEEK_SET) < 0) { |
171 | *length = cpu_to_le32(info.st_size-elfhdr_size+0x400); | 133 | fprintf(stderr,"info failed\n"); |
172 | #endif /* __i386__ */ | 134 | exit(-1); |
173 | 135 | } | |
174 | /* sets magic number for msdos partition (used by linux) */ | 136 | |
175 | block[510] = 0x55; | 137 | memset(block, '\0', sizeof(block)); |
176 | block[511] = 0xAA; | 138 | |
177 | 139 | /* set entry point and boot image size skipping over elf header */ | |
178 | /* | 140 | store_le32(0x400/*+65536*/, entry); |
179 | * Build a "PReP" partition table entry in the boot record | 141 | store_le32(size-elfhdr_size+0x400, length); |
180 | * - "PReP" may only look at the system_indicator | 142 | |
181 | */ | 143 | /* sets magic number for msdos partition (used by linux) */ |
182 | pe.boot_indicator = BootActive; | 144 | block[510] = 0x55; |
183 | pe.system_indicator = SystemPrep; | 145 | block[511] = 0xAA; |
184 | /* | 146 | |
185 | * The first block of the diskette is used by this "boot record" which | 147 | /* |
186 | * actually contains the partition table. (The first block of the | 148 | * Build a "PReP" partition table entry in the boot record |
187 | * partition contains the boot image, but I digress...) We'll set up | 149 | * - "PReP" may only look at the system_indicator |
188 | * one partition on the diskette and it shall contain the rest of the | 150 | */ |
189 | * diskette. | 151 | pe.boot_indicator = BootActive; |
190 | */ | 152 | pe.system_indicator = SystemPrep; |
191 | pe.starting_head = 0; /* zero-based */ | 153 | /* |
192 | pe.starting_sector = 2; /* one-based */ | 154 | * The first block of the diskette is used by this "boot record" which |
193 | pe.starting_cylinder = 0; /* zero-based */ | 155 | * actually contains the partition table. (The first block of the |
194 | pe.ending_head = 1; /* assumes two heads */ | 156 | * partition contains the boot image, but I digress...) We'll set up |
195 | pe.ending_sector = 18; /* assumes 18 sectors/track */ | 157 | * one partition on the diskette and it shall contain the rest of the |
196 | pe.ending_cylinder = 79; /* assumes 80 cylinders/diskette */ | 158 | * diskette. |
197 | 159 | */ | |
198 | /* | 160 | pe.starting_head = 0; /* zero-based */ |
199 | * The "PReP" software ignores the above fields and just looks at | 161 | pe.starting_sector = 2; /* one-based */ |
200 | * the next two. | 162 | pe.starting_cylinder = 0; /* zero-based */ |
201 | * - size of the diskette is (assumed to be) | 163 | pe.ending_head = 1; /* assumes two heads */ |
202 | * (2 tracks/cylinder)(18 sectors/tracks)(80 cylinders/diskette) | 164 | pe.ending_sector = 18; /* assumes 18 sectors/track */ |
203 | * - unlike the above sector numbers, the beginning sector is zero-based! | 165 | pe.ending_cylinder = 79; /* assumes 80 cylinders/diskette */ |
204 | */ | 166 | |
167 | /* | ||
168 | * The "PReP" software ignores the above fields and just looks at | ||
169 | * the next two. | ||
170 | * - size of the diskette is (assumed to be) | ||
171 | * (2 tracks/cylinder)(18 sectors/tracks)(80 cylinders/diskette) | ||
172 | * - unlike the above sector numbers, the beginning sector is zero-based! | ||
173 | */ | ||
205 | #if 0 | 174 | #if 0 |
206 | pe.beginning_sector = cpu_to_le32(1); | 175 | store_le32(1, pe.beginning_sector); |
207 | #else | ||
208 | /* This has to be 0 on the PowerStack? */ | ||
209 | #ifdef __i386__ | ||
210 | pe.beginning_sector = 0; | ||
211 | #else | 176 | #else |
212 | pe.beginning_sector = cpu_to_le32(0); | 177 | /* This has to be 0 on the PowerStack? */ |
213 | #endif /* __i386__ */ | 178 | store_le32(0, pe.beginning_sector); |
214 | #endif | 179 | #endif |
215 | 180 | ||
216 | #ifdef __i386__ | 181 | store_le32(2*18*80-1, pe.number_of_sectors); |
217 | pe.number_of_sectors = 2*18*80-1; | ||
218 | #else | ||
219 | pe.number_of_sectors = cpu_to_le32(2*18*80-1); | ||
220 | #endif /* __i386__ */ | ||
221 | 182 | ||
222 | memcpy(&block[0x1BE], &pe, sizeof(pe)); | 183 | memcpy(&block[0x1BE], &pe, sizeof(pe)); |
223 | 184 | ||
224 | write( out, block, sizeof(block) ); | 185 | fwrite(block, sizeof(block), 1, out); |
225 | write( out, entry, sizeof(*entry) ); | 186 | fwrite(entry, 4, 1, out); |
226 | write( out, length, sizeof(*length) ); | 187 | fwrite(length, 4, 1, out); |
227 | /* set file position to 2nd sector where image will be written */ | 188 | /* set file position to 2nd sector where image will be written */ |
228 | lseek( out, 0x400, SEEK_SET ); | 189 | fseek( out, 0x400, SEEK_SET ); |
229 | } | 190 | } |
230 | 191 | ||
231 | 192 | ||
232 | 193 | ||
233 | void | 194 | void copy_image(FILE *in, FILE *out) |
234 | copy_image(int in, int out) | ||
235 | { | 195 | { |
236 | char buf[SIZE]; | 196 | char buf[SIZE]; |
237 | int n; | 197 | int n; |
238 | 198 | ||
239 | while ( (n = read(in, buf, SIZE)) > 0 ) | 199 | while ( (n = fread(buf, 1, SIZE, in)) > 0 ) |
240 | write(out, buf, n); | 200 | fwrite(buf, 1, n, out); |
241 | } | 201 | } |
242 | 202 | ||
243 | 203 | ||
244 | void | 204 | void |
245 | write_asm_data( int in, int out ) | 205 | write_asm_data(FILE *in, FILE *out) |
246 | { | 206 | { |
247 | int i, cnt, pos, len; | 207 | int i, cnt, pos = 0; |
248 | unsigned int cksum, val; | 208 | unsigned int cksum = 0, val; |
249 | unsigned char *lp; | 209 | unsigned char *lp; |
250 | unsigned char buf[SIZE]; | 210 | unsigned char buf[SIZE]; |
251 | unsigned char str[256]; | 211 | size_t len; |
252 | 212 | ||
253 | write( out, "\t.data\n\t.globl input_data\ninput_data:\n", | 213 | fputs("\t.data\n\t.globl input_data\ninput_data:\n", out); |
254 | strlen( "\t.data\n\t.globl input_data\ninput_data:\n" ) ); | 214 | while ((len = fread(buf, 1, sizeof(buf), in)) > 0) { |
255 | pos = 0; | 215 | cnt = 0; |
256 | cksum = 0; | 216 | lp = buf; |
257 | while ((len = read(in, buf, sizeof(buf))) > 0) | 217 | /* Round up to longwords */ |
258 | { | 218 | while (len & 3) |
259 | cnt = 0; | 219 | buf[len++] = '\0'; |
260 | lp = (unsigned char *)buf; | 220 | for (i = 0; i < len; i += 4) { |
261 | len = (len + 3) & ~3; /* Round up to longwords */ | 221 | if (cnt == 0) |
262 | for (i = 0; i < len; i += 4) | 222 | fputs("\t.long\t", out); |
263 | { | 223 | fprintf(out, "0x%02X%02X%02X%02X", |
264 | if (cnt == 0) | 224 | lp[0], lp[1], lp[2], lp[3]); |
265 | { | 225 | val = *(unsigned long *)lp; |
266 | write( out, "\t.long\t", strlen( "\t.long\t" ) ); | 226 | cksum ^= val; |
267 | } | 227 | lp += 4; |
268 | sprintf( str, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]); | 228 | if (++cnt == 4) { |
269 | write( out, str, strlen(str) ); | 229 | cnt = 0; |
270 | val = *(unsigned long *)lp; | 230 | fprintf(out, " # %x \n", pos+i-12); |
271 | cksum ^= val; | 231 | } else { |
272 | lp += 4; | 232 | fputs(",", out); |
273 | if (++cnt == 4) | 233 | } |
274 | { | 234 | } |
275 | cnt = 0; | 235 | if (cnt) |
276 | sprintf( str, " # %x \n", pos+i-12); | 236 | fputs("0\n", out); |
277 | write( out, str, strlen(str) ); | 237 | pos += len; |
278 | } else | 238 | } |
279 | { | 239 | fprintf(out, "\t.globl input_len\ninput_len:\t.long\t0x%x\n", pos); |
280 | write( out, ",", 1 ); | 240 | fprintf(stderr, "cksum = %x\n", cksum); |
281 | } | ||
282 | } | ||
283 | if (cnt) | ||
284 | { | ||
285 | write( out, "0\n", 2 ); | ||
286 | } | ||
287 | pos += len; | ||
288 | } | ||
289 | sprintf(str, "\t.globl input_len\ninput_len:\t.long\t0x%x\n", pos); | ||
290 | write( out, str, strlen(str) ); | ||
291 | |||
292 | fprintf(stderr, "cksum = %x\n", cksum); | ||
293 | } | 241 | } |
diff --git a/arch/ppc/platforms/mpc8272ads_setup.c b/arch/ppc/platforms/mpc8272ads_setup.c index 2a35fe2b9b96..d5d36c372c8e 100644 --- a/arch/ppc/platforms/mpc8272ads_setup.c +++ b/arch/ppc/platforms/mpc8272ads_setup.c | |||
@@ -103,7 +103,7 @@ static struct fs_platform_info mpc82xx_enet_pdata[] = { | |||
103 | }, | 103 | }, |
104 | }; | 104 | }; |
105 | 105 | ||
106 | static void init_fcc1_ioports(void) | 106 | static void init_fcc1_ioports(struct fs_platform_info*) |
107 | { | 107 | { |
108 | struct io_port *io; | 108 | struct io_port *io; |
109 | u32 tempval; | 109 | u32 tempval; |
@@ -144,7 +144,7 @@ static void init_fcc1_ioports(void) | |||
144 | iounmap(immap); | 144 | iounmap(immap); |
145 | } | 145 | } |
146 | 146 | ||
147 | static void init_fcc2_ioports(void) | 147 | static void init_fcc2_ioports(struct fs_platform_info*) |
148 | { | 148 | { |
149 | cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t)); | 149 | cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t)); |
150 | u32 *bcsr = ioremap(BCSR_ADDR+12, sizeof(u32)); | 150 | u32 *bcsr = ioremap(BCSR_ADDR+12, sizeof(u32)); |
@@ -229,7 +229,7 @@ static void mpc8272ads_fixup_uart_pdata(struct platform_device *pdev, | |||
229 | } | 229 | } |
230 | } | 230 | } |
231 | 231 | ||
232 | static void init_scc1_uart_ioports(void) | 232 | static void init_scc1_uart_ioports(struct fs_uart_platform_info*) |
233 | { | 233 | { |
234 | cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t)); | 234 | cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t)); |
235 | 235 | ||
@@ -246,7 +246,7 @@ static void init_scc1_uart_ioports(void) | |||
246 | iounmap(immap); | 246 | iounmap(immap); |
247 | } | 247 | } |
248 | 248 | ||
249 | static void init_scc4_uart_ioports(void) | 249 | static void init_scc4_uart_ioports(struct fs_uart_platform_info*) |
250 | { | 250 | { |
251 | cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t)); | 251 | cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t)); |
252 | 252 | ||
diff --git a/arch/ppc/platforms/mpc866ads_setup.c b/arch/ppc/platforms/mpc866ads_setup.c index e12cece4c9fd..5f130dca3770 100644 --- a/arch/ppc/platforms/mpc866ads_setup.c +++ b/arch/ppc/platforms/mpc866ads_setup.c | |||
@@ -137,7 +137,7 @@ void __init board_init(void) | |||
137 | iounmap(bcsr_io); | 137 | iounmap(bcsr_io); |
138 | } | 138 | } |
139 | 139 | ||
140 | static void setup_fec1_ioports(void) | 140 | static void setup_fec1_ioports(struct fs_platform_info*) |
141 | { | 141 | { |
142 | immap_t *immap = (immap_t *) IMAP_ADDR; | 142 | immap_t *immap = (immap_t *) IMAP_ADDR; |
143 | 143 | ||
@@ -145,7 +145,7 @@ static void setup_fec1_ioports(void) | |||
145 | setbits16(&immap->im_ioport.iop_pddir, 0x1fff); | 145 | setbits16(&immap->im_ioport.iop_pddir, 0x1fff); |
146 | } | 146 | } |
147 | 147 | ||
148 | static void setup_scc1_ioports(void) | 148 | static void setup_scc1_ioports(struct fs_platform_info*) |
149 | { | 149 | { |
150 | immap_t *immap = (immap_t *) IMAP_ADDR; | 150 | immap_t *immap = (immap_t *) IMAP_ADDR; |
151 | unsigned *bcsr_io; | 151 | unsigned *bcsr_io; |
@@ -194,7 +194,7 @@ static void setup_scc1_ioports(void) | |||
194 | 194 | ||
195 | } | 195 | } |
196 | 196 | ||
197 | static void setup_smc1_ioports(void) | 197 | static void setup_smc1_ioports(struct fs_uart_platform_info*) |
198 | { | 198 | { |
199 | immap_t *immap = (immap_t *) IMAP_ADDR; | 199 | immap_t *immap = (immap_t *) IMAP_ADDR; |
200 | unsigned *bcsr_io; | 200 | unsigned *bcsr_io; |
@@ -216,7 +216,7 @@ static void setup_smc1_ioports(void) | |||
216 | 216 | ||
217 | } | 217 | } |
218 | 218 | ||
219 | static void setup_smc2_ioports(void) | 219 | static void setup_smc2_ioports(struct fs_uart_platform_info*) |
220 | { | 220 | { |
221 | immap_t *immap = (immap_t *) IMAP_ADDR; | 221 | immap_t *immap = (immap_t *) IMAP_ADDR; |
222 | unsigned *bcsr_io; | 222 | unsigned *bcsr_io; |
diff --git a/arch/ppc/platforms/mpc885ads_setup.c b/arch/ppc/platforms/mpc885ads_setup.c index 5dfa4e6c2af0..bf388ed04d46 100644 --- a/arch/ppc/platforms/mpc885ads_setup.c +++ b/arch/ppc/platforms/mpc885ads_setup.c | |||
@@ -161,7 +161,7 @@ void __init board_init(void) | |||
161 | #endif | 161 | #endif |
162 | } | 162 | } |
163 | 163 | ||
164 | static void setup_fec1_ioports(void) | 164 | static void setup_fec1_ioports(struct fs_platform_info*) |
165 | { | 165 | { |
166 | immap_t *immap = (immap_t *) IMAP_ADDR; | 166 | immap_t *immap = (immap_t *) IMAP_ADDR; |
167 | 167 | ||
@@ -181,7 +181,7 @@ static void setup_fec1_ioports(void) | |||
181 | clrbits32(&immap->im_cpm.cp_cptr, 0x00000100); | 181 | clrbits32(&immap->im_cpm.cp_cptr, 0x00000100); |
182 | } | 182 | } |
183 | 183 | ||
184 | static void setup_fec2_ioports(void) | 184 | static void setup_fec2_ioports(struct fs_platform_info*) |
185 | { | 185 | { |
186 | immap_t *immap = (immap_t *) IMAP_ADDR; | 186 | immap_t *immap = (immap_t *) IMAP_ADDR; |
187 | 187 | ||
@@ -193,7 +193,7 @@ static void setup_fec2_ioports(void) | |||
193 | clrbits32(&immap->im_cpm.cp_cptr, 0x00000080); | 193 | clrbits32(&immap->im_cpm.cp_cptr, 0x00000080); |
194 | } | 194 | } |
195 | 195 | ||
196 | static void setup_scc3_ioports(void) | 196 | static void setup_scc3_ioports(struct fs_platform_info*) |
197 | { | 197 | { |
198 | immap_t *immap = (immap_t *) IMAP_ADDR; | 198 | immap_t *immap = (immap_t *) IMAP_ADDR; |
199 | unsigned *bcsr_io; | 199 | unsigned *bcsr_io; |
@@ -315,7 +315,7 @@ static void __init mpc885ads_fixup_scc_enet_pdata(struct platform_device *pdev, | |||
315 | mpc885ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1); | 315 | mpc885ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1); |
316 | } | 316 | } |
317 | 317 | ||
318 | static void setup_smc1_ioports(void) | 318 | static void setup_smc1_ioports(struct fs_uart_platform_info*) |
319 | { | 319 | { |
320 | immap_t *immap = (immap_t *) IMAP_ADDR; | 320 | immap_t *immap = (immap_t *) IMAP_ADDR; |
321 | unsigned *bcsr_io; | 321 | unsigned *bcsr_io; |
@@ -335,7 +335,7 @@ static void setup_smc1_ioports(void) | |||
335 | clrbits16(&immap->im_cpm.cp_pbodr, iobits); | 335 | clrbits16(&immap->im_cpm.cp_pbodr, iobits); |
336 | } | 336 | } |
337 | 337 | ||
338 | static void setup_smc2_ioports(void) | 338 | static void setup_smc2_ioports(struct fs_uart_platform_info*) |
339 | { | 339 | { |
340 | immap_t *immap = (immap_t *) IMAP_ADDR; | 340 | immap_t *immap = (immap_t *) IMAP_ADDR; |
341 | unsigned *bcsr_io; | 341 | unsigned *bcsr_io; |
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index c46e3d48e410..e15e1489aef5 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c | |||
@@ -357,11 +357,16 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned | |||
357 | 357 | ||
358 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) | 358 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) |
359 | { | 359 | { |
360 | compat_ino_t ino; | ||
360 | int err; | 361 | int err; |
361 | 362 | ||
362 | if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev)) | 363 | if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev)) |
363 | return -EOVERFLOW; | 364 | return -EOVERFLOW; |
364 | 365 | ||
366 | ino = stat->ino; | ||
367 | if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino) | ||
368 | return -EOVERFLOW; | ||
369 | |||
365 | err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev); | 370 | err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev); |
366 | err |= put_user(stat->ino, &statbuf->st_ino); | 371 | err |= put_user(stat->ino, &statbuf->st_ino); |
367 | err |= put_user(stat->mode, &statbuf->st_mode); | 372 | err |= put_user(stat->mode, &statbuf->st_mode); |
diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c index 9d2cd97d1c3a..6f3ac548ee66 100644 --- a/arch/sparc/kernel/sys_sunos.c +++ b/arch/sparc/kernel/sys_sunos.c | |||
@@ -325,21 +325,25 @@ struct sunos_dirent_callback { | |||
325 | #define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1)) | 325 | #define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1)) |
326 | 326 | ||
327 | static int sunos_filldir(void * __buf, const char * name, int namlen, | 327 | static int sunos_filldir(void * __buf, const char * name, int namlen, |
328 | loff_t offset, ino_t ino, unsigned int d_type) | 328 | loff_t offset, u64 ino, unsigned int d_type) |
329 | { | 329 | { |
330 | struct sunos_dirent __user *dirent; | 330 | struct sunos_dirent __user *dirent; |
331 | struct sunos_dirent_callback * buf = __buf; | 331 | struct sunos_dirent_callback * buf = __buf; |
332 | unsigned long d_ino; | ||
332 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); | 333 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); |
333 | 334 | ||
334 | buf->error = -EINVAL; /* only used if we fail.. */ | 335 | buf->error = -EINVAL; /* only used if we fail.. */ |
335 | if (reclen > buf->count) | 336 | if (reclen > buf->count) |
336 | return -EINVAL; | 337 | return -EINVAL; |
338 | d_ino = ino; | ||
339 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
340 | return -EOVERFLOW; | ||
337 | dirent = buf->previous; | 341 | dirent = buf->previous; |
338 | if (dirent) | 342 | if (dirent) |
339 | put_user(offset, &dirent->d_off); | 343 | put_user(offset, &dirent->d_off); |
340 | dirent = buf->curr; | 344 | dirent = buf->curr; |
341 | buf->previous = dirent; | 345 | buf->previous = dirent; |
342 | put_user(ino, &dirent->d_ino); | 346 | put_user(d_ino, &dirent->d_ino); |
343 | put_user(namlen, &dirent->d_namlen); | 347 | put_user(namlen, &dirent->d_namlen); |
344 | put_user(reclen, &dirent->d_reclen); | 348 | put_user(reclen, &dirent->d_reclen); |
345 | copy_to_user(dirent->d_name, name, namlen); | 349 | copy_to_user(dirent->d_name, name, namlen); |
@@ -406,19 +410,23 @@ struct sunos_direntry_callback { | |||
406 | }; | 410 | }; |
407 | 411 | ||
408 | static int sunos_filldirentry(void * __buf, const char * name, int namlen, | 412 | static int sunos_filldirentry(void * __buf, const char * name, int namlen, |
409 | loff_t offset, ino_t ino, unsigned int d_type) | 413 | loff_t offset, u64 ino, unsigned int d_type) |
410 | { | 414 | { |
411 | struct sunos_direntry __user *dirent; | 415 | struct sunos_direntry __user *dirent; |
412 | struct sunos_direntry_callback *buf = __buf; | 416 | struct sunos_direntry_callback *buf = __buf; |
417 | unsigned long d_ino; | ||
413 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); | 418 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); |
414 | 419 | ||
415 | buf->error = -EINVAL; /* only used if we fail.. */ | 420 | buf->error = -EINVAL; /* only used if we fail.. */ |
416 | if (reclen > buf->count) | 421 | if (reclen > buf->count) |
417 | return -EINVAL; | 422 | return -EINVAL; |
423 | d_ino = ino; | ||
424 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
425 | return -EOVERFLOW; | ||
418 | dirent = buf->previous; | 426 | dirent = buf->previous; |
419 | dirent = buf->curr; | 427 | dirent = buf->curr; |
420 | buf->previous = dirent; | 428 | buf->previous = dirent; |
421 | put_user(ino, &dirent->d_ino); | 429 | put_user(d_ino, &dirent->d_ino); |
422 | put_user(namlen, &dirent->d_namlen); | 430 | put_user(namlen, &dirent->d_namlen); |
423 | put_user(reclen, &dirent->d_reclen); | 431 | put_user(reclen, &dirent->d_reclen); |
424 | copy_to_user(dirent->d_name, name, namlen); | 432 | copy_to_user(dirent->d_name, name, namlen); |
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index 7c6499ce1767..e27cb71bd8e2 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c | |||
@@ -338,12 +338,17 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned | |||
338 | 338 | ||
339 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) | 339 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) |
340 | { | 340 | { |
341 | compat_ino_t ino; | ||
341 | int err; | 342 | int err; |
342 | 343 | ||
343 | if (stat->size > MAX_NON_LFS || !old_valid_dev(stat->dev) || | 344 | if (stat->size > MAX_NON_LFS || !old_valid_dev(stat->dev) || |
344 | !old_valid_dev(stat->rdev)) | 345 | !old_valid_dev(stat->rdev)) |
345 | return -EOVERFLOW; | 346 | return -EOVERFLOW; |
346 | 347 | ||
348 | ino = stat->ino; | ||
349 | if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino) | ||
350 | return -EOVERFLOW; | ||
351 | |||
347 | err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev); | 352 | err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev); |
348 | err |= put_user(stat->ino, &statbuf->st_ino); | 353 | err |= put_user(stat->ino, &statbuf->st_ino); |
349 | err |= put_user(stat->mode, &statbuf->st_mode); | 354 | err |= put_user(stat->mode, &statbuf->st_mode); |
diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c index b21e8dd41a66..7da72d3b322a 100644 --- a/arch/sparc64/kernel/sys_sunos32.c +++ b/arch/sparc64/kernel/sys_sunos32.c | |||
@@ -281,16 +281,20 @@ static int sunos_filldir(void * __buf, const char * name, int namlen, | |||
281 | struct sunos_dirent __user *dirent; | 281 | struct sunos_dirent __user *dirent; |
282 | struct sunos_dirent_callback * buf = (struct sunos_dirent_callback *) __buf; | 282 | struct sunos_dirent_callback * buf = (struct sunos_dirent_callback *) __buf; |
283 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); | 283 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); |
284 | u32 d_ino; | ||
284 | 285 | ||
285 | buf->error = -EINVAL; /* only used if we fail.. */ | 286 | buf->error = -EINVAL; /* only used if we fail.. */ |
286 | if (reclen > buf->count) | 287 | if (reclen > buf->count) |
287 | return -EINVAL; | 288 | return -EINVAL; |
289 | d_ino = ino; | ||
290 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
291 | return -EOVERFLOW; | ||
288 | dirent = buf->previous; | 292 | dirent = buf->previous; |
289 | if (dirent) | 293 | if (dirent) |
290 | put_user(offset, &dirent->d_off); | 294 | put_user(offset, &dirent->d_off); |
291 | dirent = buf->curr; | 295 | dirent = buf->curr; |
292 | buf->previous = dirent; | 296 | buf->previous = dirent; |
293 | put_user(ino, &dirent->d_ino); | 297 | put_user(d_ino, &dirent->d_ino); |
294 | put_user(namlen, &dirent->d_namlen); | 298 | put_user(namlen, &dirent->d_namlen); |
295 | put_user(reclen, &dirent->d_reclen); | 299 | put_user(reclen, &dirent->d_reclen); |
296 | if (copy_to_user(dirent->d_name, name, namlen)) | 300 | if (copy_to_user(dirent->d_name, name, namlen)) |
@@ -364,14 +368,18 @@ static int sunos_filldirentry(void * __buf, const char * name, int namlen, | |||
364 | struct sunos_direntry_callback * buf = | 368 | struct sunos_direntry_callback * buf = |
365 | (struct sunos_direntry_callback *) __buf; | 369 | (struct sunos_direntry_callback *) __buf; |
366 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); | 370 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); |
371 | u32 d_ino; | ||
367 | 372 | ||
368 | buf->error = -EINVAL; /* only used if we fail.. */ | 373 | buf->error = -EINVAL; /* only used if we fail.. */ |
369 | if (reclen > buf->count) | 374 | if (reclen > buf->count) |
370 | return -EINVAL; | 375 | return -EINVAL; |
376 | d_ino = ino; | ||
377 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
378 | return -EOVERFLOW; | ||
371 | dirent = buf->previous; | 379 | dirent = buf->previous; |
372 | dirent = buf->curr; | 380 | dirent = buf->curr; |
373 | buf->previous = dirent; | 381 | buf->previous = dirent; |
374 | put_user(ino, &dirent->d_ino); | 382 | put_user(d_ino, &dirent->d_ino); |
375 | put_user(namlen, &dirent->d_namlen); | 383 | put_user(namlen, &dirent->d_namlen); |
376 | put_user(reclen, &dirent->d_reclen); | 384 | put_user(reclen, &dirent->d_reclen); |
377 | if (copy_to_user(dirent->d_name, name, namlen)) | 385 | if (copy_to_user(dirent->d_name, name, namlen)) |
diff --git a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c index 0f0eb6aa1c40..12a940cc791f 100644 --- a/arch/sparc64/solaris/fs.c +++ b/arch/sparc64/solaris/fs.c | |||
@@ -82,12 +82,17 @@ struct sol_stat64 { | |||
82 | 82 | ||
83 | static inline int putstat(struct sol_stat __user *ubuf, struct kstat *kbuf) | 83 | static inline int putstat(struct sol_stat __user *ubuf, struct kstat *kbuf) |
84 | { | 84 | { |
85 | u32 ino; | ||
86 | |||
85 | if (kbuf->size > MAX_NON_LFS || | 87 | if (kbuf->size > MAX_NON_LFS || |
86 | !sysv_valid_dev(kbuf->dev) || | 88 | !sysv_valid_dev(kbuf->dev) || |
87 | !sysv_valid_dev(kbuf->rdev)) | 89 | !sysv_valid_dev(kbuf->rdev)) |
88 | return -EOVERFLOW; | 90 | return -EOVERFLOW; |
91 | ino = kbuf->ino; | ||
92 | if (sizeof(ino) < sizeof(kbuf->ino) && ino != kbuf->ino) | ||
93 | return -EOVERFLOW; | ||
89 | if (put_user (sysv_encode_dev(kbuf->dev), &ubuf->st_dev) || | 94 | if (put_user (sysv_encode_dev(kbuf->dev), &ubuf->st_dev) || |
90 | __put_user (kbuf->ino, &ubuf->st_ino) || | 95 | __put_user (ino, &ubuf->st_ino) || |
91 | __put_user (kbuf->mode, &ubuf->st_mode) || | 96 | __put_user (kbuf->mode, &ubuf->st_mode) || |
92 | __put_user (kbuf->nlink, &ubuf->st_nlink) || | 97 | __put_user (kbuf->nlink, &ubuf->st_nlink) || |
93 | __put_user (kbuf->uid, &ubuf->st_uid) || | 98 | __put_user (kbuf->uid, &ubuf->st_uid) || |
diff --git a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c index 26a01717cc1a..c9bac3af29d6 100644 --- a/arch/x86_64/ia32/sys_ia32.c +++ b/arch/x86_64/ia32/sys_ia32.c | |||
@@ -76,6 +76,8 @@ | |||
76 | 76 | ||
77 | int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf) | 77 | int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf) |
78 | { | 78 | { |
79 | compat_ino_t ino; | ||
80 | |||
79 | typeof(ubuf->st_uid) uid = 0; | 81 | typeof(ubuf->st_uid) uid = 0; |
80 | typeof(ubuf->st_gid) gid = 0; | 82 | typeof(ubuf->st_gid) gid = 0; |
81 | SET_UID(uid, kbuf->uid); | 83 | SET_UID(uid, kbuf->uid); |
@@ -84,9 +86,12 @@ int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf) | |||
84 | return -EOVERFLOW; | 86 | return -EOVERFLOW; |
85 | if (kbuf->size >= 0x7fffffff) | 87 | if (kbuf->size >= 0x7fffffff) |
86 | return -EOVERFLOW; | 88 | return -EOVERFLOW; |
89 | ino = kbuf->ino; | ||
90 | if (sizeof(ino) < sizeof(kbuf->ino) && ino != kbuf->ino) | ||
91 | return -EOVERFLOW; | ||
87 | if (!access_ok(VERIFY_WRITE, ubuf, sizeof(struct compat_stat)) || | 92 | if (!access_ok(VERIFY_WRITE, ubuf, sizeof(struct compat_stat)) || |
88 | __put_user (old_encode_dev(kbuf->dev), &ubuf->st_dev) || | 93 | __put_user (old_encode_dev(kbuf->dev), &ubuf->st_dev) || |
89 | __put_user (kbuf->ino, &ubuf->st_ino) || | 94 | __put_user (ino, &ubuf->st_ino) || |
90 | __put_user (kbuf->mode, &ubuf->st_mode) || | 95 | __put_user (kbuf->mode, &ubuf->st_mode) || |
91 | __put_user (kbuf->nlink, &ubuf->st_nlink) || | 96 | __put_user (kbuf->nlink, &ubuf->st_nlink) || |
92 | __put_user (uid, &ubuf->st_uid) || | 97 | __put_user (uid, &ubuf->st_uid) || |
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c index 135ff25e6b44..6472e321cad7 100644 --- a/arch/x86_64/kernel/apic.c +++ b/arch/x86_64/kernel/apic.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/kernel_stat.h> | 25 | #include <linux/kernel_stat.h> |
26 | #include <linux/sysdev.h> | 26 | #include <linux/sysdev.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/ioport.h> | ||
29 | 28 | ||
30 | #include <asm/atomic.h> | 29 | #include <asm/atomic.h> |
31 | #include <asm/smp.h> | 30 | #include <asm/smp.h> |
@@ -46,11 +45,6 @@ int apic_calibrate_pmtmr __initdata; | |||
46 | 45 | ||
47 | int disable_apic_timer __initdata; | 46 | int disable_apic_timer __initdata; |
48 | 47 | ||
49 | static struct resource lapic_resource = { | ||
50 | .name = "Local APIC", | ||
51 | .flags = IORESOURCE_MEM | IORESOURCE_BUSY, | ||
52 | }; | ||
53 | |||
54 | /* | 48 | /* |
55 | * cpu_mask that denotes the CPUs that needs timer interrupt coming in as | 49 | * cpu_mask that denotes the CPUs that needs timer interrupt coming in as |
56 | * IPIs in place of local APIC timers | 50 | * IPIs in place of local APIC timers |
@@ -591,40 +585,6 @@ static int __init detect_init_APIC (void) | |||
591 | return 0; | 585 | return 0; |
592 | } | 586 | } |
593 | 587 | ||
594 | #ifdef CONFIG_X86_IO_APIC | ||
595 | static struct resource * __init ioapic_setup_resources(void) | ||
596 | { | ||
597 | #define IOAPIC_RESOURCE_NAME_SIZE 11 | ||
598 | unsigned long n; | ||
599 | struct resource *res; | ||
600 | char *mem; | ||
601 | int i; | ||
602 | |||
603 | if (nr_ioapics <= 0) | ||
604 | return NULL; | ||
605 | |||
606 | n = IOAPIC_RESOURCE_NAME_SIZE + sizeof(struct resource); | ||
607 | n *= nr_ioapics; | ||
608 | |||
609 | res = alloc_bootmem(n); | ||
610 | |||
611 | if (!res) | ||
612 | return NULL; | ||
613 | |||
614 | memset(res, 0, n); | ||
615 | mem = (void *)&res[nr_ioapics]; | ||
616 | |||
617 | for (i = 0; i < nr_ioapics; i++) { | ||
618 | res[i].name = mem; | ||
619 | res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY; | ||
620 | snprintf(mem, IOAPIC_RESOURCE_NAME_SIZE, "IOAPIC %u", i); | ||
621 | mem += IOAPIC_RESOURCE_NAME_SIZE; | ||
622 | } | ||
623 | |||
624 | return res; | ||
625 | } | ||
626 | #endif | ||
627 | |||
628 | void __init init_apic_mappings(void) | 588 | void __init init_apic_mappings(void) |
629 | { | 589 | { |
630 | unsigned long apic_phys; | 590 | unsigned long apic_phys; |
@@ -644,11 +604,6 @@ void __init init_apic_mappings(void) | |||
644 | apic_mapped = 1; | 604 | apic_mapped = 1; |
645 | apic_printk(APIC_VERBOSE,"mapped APIC to %16lx (%16lx)\n", APIC_BASE, apic_phys); | 605 | apic_printk(APIC_VERBOSE,"mapped APIC to %16lx (%16lx)\n", APIC_BASE, apic_phys); |
646 | 606 | ||
647 | /* Put local APIC into the resource map. */ | ||
648 | lapic_resource.start = apic_phys; | ||
649 | lapic_resource.end = lapic_resource.start + PAGE_SIZE - 1; | ||
650 | insert_resource(&iomem_resource, &lapic_resource); | ||
651 | |||
652 | /* | 607 | /* |
653 | * Fetch the APIC ID of the BSP in case we have a | 608 | * Fetch the APIC ID of the BSP in case we have a |
654 | * default configuration (or the MP table is broken). | 609 | * default configuration (or the MP table is broken). |
@@ -658,9 +613,7 @@ void __init init_apic_mappings(void) | |||
658 | { | 613 | { |
659 | unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0; | 614 | unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0; |
660 | int i; | 615 | int i; |
661 | struct resource *ioapic_res; | ||
662 | 616 | ||
663 | ioapic_res = ioapic_setup_resources(); | ||
664 | for (i = 0; i < nr_ioapics; i++) { | 617 | for (i = 0; i < nr_ioapics; i++) { |
665 | if (smp_found_config) { | 618 | if (smp_found_config) { |
666 | ioapic_phys = mp_ioapics[i].mpc_apicaddr; | 619 | ioapic_phys = mp_ioapics[i].mpc_apicaddr; |
@@ -672,13 +625,6 @@ void __init init_apic_mappings(void) | |||
672 | apic_printk(APIC_VERBOSE,"mapped IOAPIC to %016lx (%016lx)\n", | 625 | apic_printk(APIC_VERBOSE,"mapped IOAPIC to %016lx (%016lx)\n", |
673 | __fix_to_virt(idx), ioapic_phys); | 626 | __fix_to_virt(idx), ioapic_phys); |
674 | idx++; | 627 | idx++; |
675 | |||
676 | if (ioapic_res) { | ||
677 | ioapic_res->start = ioapic_phys; | ||
678 | ioapic_res->end = ioapic_phys + (4 * 1024) - 1; | ||
679 | insert_resource(&iomem_resource, ioapic_res); | ||
680 | ioapic_res++; | ||
681 | } | ||
682 | } | 628 | } |
683 | } | 629 | } |
684 | } | 630 | } |
diff --git a/block/ioctl.c b/block/ioctl.c index 309760b7e37f..58aab630dfc1 100644 --- a/block/ioctl.c +++ b/block/ioctl.c | |||
@@ -199,8 +199,8 @@ static int blkdev_locked_ioctl(struct file *file, struct block_device *bdev, | |||
199 | return -ENOIOCTLCMD; | 199 | return -ENOIOCTLCMD; |
200 | } | 200 | } |
201 | 201 | ||
202 | static int blkdev_driver_ioctl(struct inode *inode, struct file *file, | 202 | int blkdev_driver_ioctl(struct inode *inode, struct file *file, |
203 | struct gendisk *disk, unsigned cmd, unsigned long arg) | 203 | struct gendisk *disk, unsigned cmd, unsigned long arg) |
204 | { | 204 | { |
205 | int ret; | 205 | int ret; |
206 | if (disk->fops->unlocked_ioctl) | 206 | if (disk->fops->unlocked_ioctl) |
@@ -215,6 +215,7 @@ static int blkdev_driver_ioctl(struct inode *inode, struct file *file, | |||
215 | 215 | ||
216 | return -ENOTTY; | 216 | return -ENOTTY; |
217 | } | 217 | } |
218 | EXPORT_SYMBOL_GPL(blkdev_driver_ioctl); | ||
218 | 219 | ||
219 | int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd, | 220 | int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd, |
220 | unsigned long arg) | 221 | unsigned long arg) |
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c index cf656ecbe507..8c757438f350 100644 --- a/drivers/ata/pata_hpt366.c +++ b/drivers/ata/pata_hpt366.c | |||
@@ -429,7 +429,7 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
429 | 429 | ||
430 | /* PCI clocking determines the ATA timing values to use */ | 430 | /* PCI clocking determines the ATA timing values to use */ |
431 | /* info_hpt366 is safe against re-entry so we can scribble on it */ | 431 | /* info_hpt366 is safe against re-entry so we can scribble on it */ |
432 | switch(reg1 & 0x700) { | 432 | switch((reg1 & 0x700) >> 8) { |
433 | case 5: | 433 | case 5: |
434 | info_hpt366.private_data = &hpt366_40; | 434 | info_hpt366.private_data = &hpt366_40; |
435 | break; | 435 | break; |
diff --git a/drivers/block/umem.c b/drivers/block/umem.c index 5d8925bd9045..cbb9d0f21acc 100644 --- a/drivers/block/umem.c +++ b/drivers/block/umem.c | |||
@@ -552,7 +552,8 @@ static void process_page(unsigned long data) | |||
552 | static int mm_make_request(request_queue_t *q, struct bio *bio) | 552 | static int mm_make_request(request_queue_t *q, struct bio *bio) |
553 | { | 553 | { |
554 | struct cardinfo *card = q->queuedata; | 554 | struct cardinfo *card = q->queuedata; |
555 | pr_debug("mm_make_request %ld %d\n", bh->b_rsector, bh->b_size); | 555 | pr_debug("mm_make_request %llu %u\n", |
556 | (unsigned long long)bio->bi_sector, bio->bi_size); | ||
556 | 557 | ||
557 | bio->bi_phys_segments = bio->bi_idx; /* count of completed segments*/ | 558 | bio->bi_phys_segments = bio->bi_idx; /* count of completed segments*/ |
558 | spin_lock_irq(&card->lock); | 559 | spin_lock_irq(&card->lock); |
diff --git a/drivers/char/hvc_iseries.c b/drivers/char/hvc_iseries.c index 4747729459c7..8b6f197e5f8c 100644 --- a/drivers/char/hvc_iseries.c +++ b/drivers/char/hvc_iseries.c | |||
@@ -153,9 +153,7 @@ static int put_chars(uint32_t vtermno, const char *buf, int count) | |||
153 | spin_lock_irqsave(&consolelock, flags); | 153 | spin_lock_irqsave(&consolelock, flags); |
154 | 154 | ||
155 | if (viochar_is_console(pi) && !viopath_isactive(pi->lp)) { | 155 | if (viochar_is_console(pi) && !viopath_isactive(pi->lp)) { |
156 | spin_lock_irqsave(&consoleloglock, flags); | ||
157 | HvCall_writeLogBuffer(buf, count); | 156 | HvCall_writeLogBuffer(buf, count); |
158 | spin_unlock_irqrestore(&consoleloglock, flags); | ||
159 | sent = count; | 157 | sent = count; |
160 | goto done; | 158 | goto done; |
161 | } | 159 | } |
@@ -171,11 +169,8 @@ static int put_chars(uint32_t vtermno, const char *buf, int count) | |||
171 | 169 | ||
172 | len = (count > VIOCHAR_MAX_DATA) ? VIOCHAR_MAX_DATA : count; | 170 | len = (count > VIOCHAR_MAX_DATA) ? VIOCHAR_MAX_DATA : count; |
173 | 171 | ||
174 | if (viochar_is_console(pi)) { | 172 | if (viochar_is_console(pi)) |
175 | spin_lock_irqsave(&consoleloglock, flags); | ||
176 | HvCall_writeLogBuffer(buf, len); | 173 | HvCall_writeLogBuffer(buf, len); |
177 | spin_unlock_irqrestore(&consoleloglock, flags); | ||
178 | } | ||
179 | 174 | ||
180 | init_data_event(viochar, pi->lp); | 175 | init_data_event(viochar, pi->lp); |
181 | 176 | ||
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index 4828bc914ce3..62ef511d143b 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c | |||
@@ -779,8 +779,6 @@ retry: | |||
779 | ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0 ); | 779 | ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0 ); |
780 | goto out; | 780 | goto out; |
781 | 781 | ||
782 | out_class: | ||
783 | class_destroy(ip2_class); | ||
784 | out_chrdev: | 782 | out_chrdev: |
785 | unregister_chrdev(IP2_IPL_MAJOR, "ip2"); | 783 | unregister_chrdev(IP2_IPL_MAJOR, "ip2"); |
786 | out: | 784 | out: |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 908521e36d81..b106c45abfc9 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -217,6 +217,11 @@ struct smi_info | |||
217 | struct list_head link; | 217 | struct list_head link; |
218 | }; | 218 | }; |
219 | 219 | ||
220 | #define SI_MAX_PARMS 4 | ||
221 | |||
222 | static int force_kipmid[SI_MAX_PARMS]; | ||
223 | static int num_force_kipmid; | ||
224 | |||
220 | static int try_smi_init(struct smi_info *smi); | 225 | static int try_smi_init(struct smi_info *smi); |
221 | 226 | ||
222 | static ATOMIC_NOTIFIER_HEAD(xaction_notifier_list); | 227 | static ATOMIC_NOTIFIER_HEAD(xaction_notifier_list); |
@@ -908,6 +913,7 @@ static int smi_start_processing(void *send_info, | |||
908 | ipmi_smi_t intf) | 913 | ipmi_smi_t intf) |
909 | { | 914 | { |
910 | struct smi_info *new_smi = send_info; | 915 | struct smi_info *new_smi = send_info; |
916 | int enable = 0; | ||
911 | 917 | ||
912 | new_smi->intf = intf; | 918 | new_smi->intf = intf; |
913 | 919 | ||
@@ -917,10 +923,18 @@ static int smi_start_processing(void *send_info, | |||
917 | mod_timer(&new_smi->si_timer, jiffies + SI_TIMEOUT_JIFFIES); | 923 | mod_timer(&new_smi->si_timer, jiffies + SI_TIMEOUT_JIFFIES); |
918 | 924 | ||
919 | /* | 925 | /* |
926 | * Check if the user forcefully enabled the daemon. | ||
927 | */ | ||
928 | if (new_smi->intf_num < num_force_kipmid) | ||
929 | enable = force_kipmid[new_smi->intf_num]; | ||
930 | /* | ||
920 | * The BT interface is efficient enough to not need a thread, | 931 | * The BT interface is efficient enough to not need a thread, |
921 | * and there is no need for a thread if we have interrupts. | 932 | * and there is no need for a thread if we have interrupts. |
922 | */ | 933 | */ |
923 | if ((new_smi->si_type != SI_BT) && (!new_smi->irq)) { | 934 | else if ((new_smi->si_type != SI_BT) && (!new_smi->irq)) |
935 | enable = 1; | ||
936 | |||
937 | if (enable) { | ||
924 | new_smi->thread = kthread_run(ipmi_thread, new_smi, | 938 | new_smi->thread = kthread_run(ipmi_thread, new_smi, |
925 | "kipmi%d", new_smi->intf_num); | 939 | "kipmi%d", new_smi->intf_num); |
926 | if (IS_ERR(new_smi->thread)) { | 940 | if (IS_ERR(new_smi->thread)) { |
@@ -948,7 +962,6 @@ static struct ipmi_smi_handlers handlers = | |||
948 | /* There can be 4 IO ports passed in (with or without IRQs), 4 addresses, | 962 | /* There can be 4 IO ports passed in (with or without IRQs), 4 addresses, |
949 | a default IO port, and 1 ACPI/SPMI address. That sets SI_MAX_DRIVERS */ | 963 | a default IO port, and 1 ACPI/SPMI address. That sets SI_MAX_DRIVERS */ |
950 | 964 | ||
951 | #define SI_MAX_PARMS 4 | ||
952 | static LIST_HEAD(smi_infos); | 965 | static LIST_HEAD(smi_infos); |
953 | static DEFINE_MUTEX(smi_infos_lock); | 966 | static DEFINE_MUTEX(smi_infos_lock); |
954 | static int smi_num; /* Used to sequence the SMIs */ | 967 | static int smi_num; /* Used to sequence the SMIs */ |
@@ -1021,6 +1034,10 @@ MODULE_PARM_DESC(slave_addrs, "Set the default IPMB slave address for" | |||
1021 | " the controller. Normally this is 0x20, but can be" | 1034 | " the controller. Normally this is 0x20, but can be" |
1022 | " overridden by this parm. This is an array indexed" | 1035 | " overridden by this parm. This is an array indexed" |
1023 | " by interface number."); | 1036 | " by interface number."); |
1037 | module_param_array(force_kipmid, int, &num_force_kipmid, 0); | ||
1038 | MODULE_PARM_DESC(force_kipmid, "Force the kipmi daemon to be enabled (1) or" | ||
1039 | " disabled(0). Normally the IPMI driver auto-detects" | ||
1040 | " this, but the value may be overridden by this parm."); | ||
1024 | 1041 | ||
1025 | 1042 | ||
1026 | #define IPMI_IO_ADDR_SPACE 0 | 1043 | #define IPMI_IO_ADDR_SPACE 0 |
@@ -1734,6 +1751,7 @@ static void __devinit dmi_find_bmc(void) | |||
1734 | int rv; | 1751 | int rv; |
1735 | 1752 | ||
1736 | while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, NULL, dev))) { | 1753 | while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, NULL, dev))) { |
1754 | memset(&data, 0, sizeof(data)); | ||
1737 | rv = decode_dmi((struct dmi_header *) dev->device_data, &data); | 1755 | rv = decode_dmi((struct dmi_header *) dev->device_data, &data); |
1738 | if (!rv) | 1756 | if (!rv) |
1739 | try_init_dmi(&data); | 1757 | try_init_dmi(&data); |
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c index d30dc09dbbc9..9df0ca1be0e3 100644 --- a/drivers/char/tipar.c +++ b/drivers/char/tipar.c | |||
@@ -224,14 +224,16 @@ probe_ti_parallel(int minor) | |||
224 | { | 224 | { |
225 | int i; | 225 | int i; |
226 | int seq[] = { 0x00, 0x20, 0x10, 0x30 }; | 226 | int seq[] = { 0x00, 0x20, 0x10, 0x30 }; |
227 | int data; | ||
227 | 228 | ||
228 | for (i = 3; i >= 0; i--) { | 229 | for (i = 3; i >= 0; i--) { |
229 | outbyte(3, minor); | 230 | outbyte(3, minor); |
230 | outbyte(i, minor); | 231 | outbyte(i, minor); |
231 | udelay(delay); | 232 | udelay(delay); |
233 | data = inbyte(minor) & 0x30; | ||
232 | pr_debug("tipar: Probing -> %i: 0x%02x 0x%02x\n", i, | 234 | pr_debug("tipar: Probing -> %i: 0x%02x 0x%02x\n", i, |
233 | data & 0x30, seq[i]); | 235 | data, seq[i]); |
234 | if ((inbyte(minor) & 0x30) != seq[i]) { | 236 | if (data != seq[i]) { |
235 | outbyte(3, minor); | 237 | outbyte(3, minor); |
236 | return -1; | 238 | return -1; |
237 | } | 239 | } |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index ec0c070bf15f..8e4413f6fbaf 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -106,7 +106,8 @@ | |||
106 | #define MAX_NR_CON_DRIVER 16 | 106 | #define MAX_NR_CON_DRIVER 16 |
107 | 107 | ||
108 | #define CON_DRIVER_FLAG_MODULE 1 | 108 | #define CON_DRIVER_FLAG_MODULE 1 |
109 | #define CON_DRIVER_FLAG_INIT 2 | 109 | #define CON_DRIVER_FLAG_INIT 2 |
110 | #define CON_DRIVER_FLAG_ATTR 4 | ||
110 | 111 | ||
111 | struct con_driver { | 112 | struct con_driver { |
112 | const struct consw *con; | 113 | const struct consw *con; |
@@ -138,14 +139,6 @@ const struct consw *conswitchp; | |||
138 | extern void vcs_make_sysfs(struct tty_struct *tty); | 139 | extern void vcs_make_sysfs(struct tty_struct *tty); |
139 | extern void vcs_remove_sysfs(struct tty_struct *tty); | 140 | extern void vcs_remove_sysfs(struct tty_struct *tty); |
140 | 141 | ||
141 | extern void console_map_init(void); | ||
142 | #ifdef CONFIG_PROM_CONSOLE | ||
143 | extern void prom_con_init(void); | ||
144 | #endif | ||
145 | #ifdef CONFIG_MDA_CONSOLE | ||
146 | extern int mda_console_init(void); | ||
147 | #endif | ||
148 | |||
149 | struct vc vc_cons [MAX_NR_CONSOLES]; | 142 | struct vc vc_cons [MAX_NR_CONSOLES]; |
150 | 143 | ||
151 | #ifndef VT_SINGLE_DRIVER | 144 | #ifndef VT_SINGLE_DRIVER |
@@ -3070,22 +3063,37 @@ static struct class_device_attribute class_device_attrs[] = { | |||
3070 | static int vtconsole_init_class_device(struct con_driver *con) | 3063 | static int vtconsole_init_class_device(struct con_driver *con) |
3071 | { | 3064 | { |
3072 | int i; | 3065 | int i; |
3066 | int error = 0; | ||
3073 | 3067 | ||
3068 | con->flag |= CON_DRIVER_FLAG_ATTR; | ||
3074 | class_set_devdata(con->class_dev, con); | 3069 | class_set_devdata(con->class_dev, con); |
3075 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) | 3070 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) { |
3076 | class_device_create_file(con->class_dev, | 3071 | error = class_device_create_file(con->class_dev, |
3072 | &class_device_attrs[i]); | ||
3073 | if (error) | ||
3074 | break; | ||
3075 | } | ||
3076 | |||
3077 | if (error) { | ||
3078 | while (--i >= 0) | ||
3079 | class_device_remove_file(con->class_dev, | ||
3077 | &class_device_attrs[i]); | 3080 | &class_device_attrs[i]); |
3081 | con->flag &= ~CON_DRIVER_FLAG_ATTR; | ||
3082 | } | ||
3078 | 3083 | ||
3079 | return 0; | 3084 | return error; |
3080 | } | 3085 | } |
3081 | 3086 | ||
3082 | static void vtconsole_deinit_class_device(struct con_driver *con) | 3087 | static void vtconsole_deinit_class_device(struct con_driver *con) |
3083 | { | 3088 | { |
3084 | int i; | 3089 | int i; |
3085 | 3090 | ||
3086 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) | 3091 | if (con->flag & CON_DRIVER_FLAG_ATTR) { |
3087 | class_device_remove_file(con->class_dev, | 3092 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) |
3088 | &class_device_attrs[i]); | 3093 | class_device_remove_file(con->class_dev, |
3094 | &class_device_attrs[i]); | ||
3095 | con->flag &= ~CON_DRIVER_FLAG_ATTR; | ||
3096 | } | ||
3089 | } | 3097 | } |
3090 | 3098 | ||
3091 | /** | 3099 | /** |
@@ -3184,6 +3192,7 @@ int register_con_driver(const struct consw *csw, int first, int last) | |||
3184 | } else { | 3192 | } else { |
3185 | vtconsole_init_class_device(con_driver); | 3193 | vtconsole_init_class_device(con_driver); |
3186 | } | 3194 | } |
3195 | |||
3187 | err: | 3196 | err: |
3188 | release_console_sem(); | 3197 | release_console_sem(); |
3189 | module_put(owner); | 3198 | module_put(owner); |
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig index 77ab7e020da0..06f3fa2fe877 100644 --- a/drivers/char/watchdog/Kconfig +++ b/drivers/char/watchdog/Kconfig | |||
@@ -172,6 +172,17 @@ config OMAP_WATCHDOG | |||
172 | Support for TI OMAP1610/OMAP1710/OMAP2420 watchdog. Say 'Y' here to | 172 | Support for TI OMAP1610/OMAP1710/OMAP2420 watchdog. Say 'Y' here to |
173 | enable the OMAP1610/OMAP1710 watchdog timer. | 173 | enable the OMAP1610/OMAP1710 watchdog timer. |
174 | 174 | ||
175 | config PNX4008_WATCHDOG | ||
176 | tristate "PNX4008 Watchdog" | ||
177 | depends on WATCHDOG && ARCH_PNX4008 | ||
178 | help | ||
179 | Say Y here if to include support for the watchdog timer | ||
180 | in the PNX4008 processor. | ||
181 | This driver can be built as a module by choosing M. The module | ||
182 | will be called pnx4008_wdt. | ||
183 | |||
184 | Say N if you are unsure. | ||
185 | |||
175 | # X86 (i386 + ia64 + x86_64) Architecture | 186 | # X86 (i386 + ia64 + x86_64) Architecture |
176 | 187 | ||
177 | config ACQUIRE_WDT | 188 | config ACQUIRE_WDT |
diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile index 5099f8be8cc5..6ffca7cb56ab 100644 --- a/drivers/char/watchdog/Makefile +++ b/drivers/char/watchdog/Makefile | |||
@@ -33,6 +33,7 @@ obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o | |||
33 | obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o | 33 | obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o |
34 | obj-$(CONFIG_MPCORE_WATCHDOG) += mpcore_wdt.o | 34 | obj-$(CONFIG_MPCORE_WATCHDOG) += mpcore_wdt.o |
35 | obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o | 35 | obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o |
36 | obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o | ||
36 | 37 | ||
37 | # X86 (i386 + ia64 + x86_64) Architecture | 38 | # X86 (i386 + ia64 + x86_64) Architecture |
38 | obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o | 39 | obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o |
diff --git a/drivers/char/watchdog/acquirewdt.c b/drivers/char/watchdog/acquirewdt.c index c77fe3cf2852..154d67e591e5 100644 --- a/drivers/char/watchdog/acquirewdt.c +++ b/drivers/char/watchdog/acquirewdt.c | |||
@@ -183,7 +183,7 @@ static int acq_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
183 | } | 183 | } |
184 | 184 | ||
185 | default: | 185 | default: |
186 | return -ENOIOCTLCMD; | 186 | return -ENOTTY; |
187 | } | 187 | } |
188 | } | 188 | } |
189 | 189 | ||
diff --git a/drivers/char/watchdog/advantechwdt.c b/drivers/char/watchdog/advantechwdt.c index 8069be445edc..9d732769ba01 100644 --- a/drivers/char/watchdog/advantechwdt.c +++ b/drivers/char/watchdog/advantechwdt.c | |||
@@ -176,7 +176,7 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
176 | } | 176 | } |
177 | 177 | ||
178 | default: | 178 | default: |
179 | return -ENOIOCTLCMD; | 179 | return -ENOTTY; |
180 | } | 180 | } |
181 | return 0; | 181 | return 0; |
182 | } | 182 | } |
diff --git a/drivers/char/watchdog/alim1535_wdt.c b/drivers/char/watchdog/alim1535_wdt.c index c5c94e4c9495..01b0d132ee41 100644 --- a/drivers/char/watchdog/alim1535_wdt.c +++ b/drivers/char/watchdog/alim1535_wdt.c | |||
@@ -236,7 +236,7 @@ static int ali_ioctl(struct inode *inode, struct file *file, | |||
236 | return put_user(timeout, p); | 236 | return put_user(timeout, p); |
237 | 237 | ||
238 | default: | 238 | default: |
239 | return -ENOIOCTLCMD; | 239 | return -ENOTTY; |
240 | } | 240 | } |
241 | } | 241 | } |
242 | 242 | ||
@@ -330,17 +330,20 @@ static int __init ali_find_watchdog(void) | |||
330 | u32 wdog; | 330 | u32 wdog; |
331 | 331 | ||
332 | /* Check for a 1535 series bridge */ | 332 | /* Check for a 1535 series bridge */ |
333 | pdev = pci_find_device(PCI_VENDOR_ID_AL, 0x1535, NULL); | 333 | pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x1535, NULL); |
334 | if(pdev == NULL) | 334 | if(pdev == NULL) |
335 | return -ENODEV; | 335 | return -ENODEV; |
336 | pci_dev_put(pdev); | ||
336 | 337 | ||
337 | /* Check for the a 7101 PMU */ | 338 | /* Check for the a 7101 PMU */ |
338 | pdev = pci_find_device(PCI_VENDOR_ID_AL, 0x7101, NULL); | 339 | pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x7101, NULL); |
339 | if(pdev == NULL) | 340 | if(pdev == NULL) |
340 | return -ENODEV; | 341 | return -ENODEV; |
341 | 342 | ||
342 | if(pci_enable_device(pdev)) | 343 | if(pci_enable_device(pdev)) { |
344 | pci_dev_put(pdev); | ||
343 | return -EIO; | 345 | return -EIO; |
346 | } | ||
344 | 347 | ||
345 | ali_pci = pdev; | 348 | ali_pci = pdev; |
346 | 349 | ||
@@ -447,6 +450,7 @@ static void __exit watchdog_exit(void) | |||
447 | /* Deregister */ | 450 | /* Deregister */ |
448 | unregister_reboot_notifier(&ali_notifier); | 451 | unregister_reboot_notifier(&ali_notifier); |
449 | misc_deregister(&ali_miscdev); | 452 | misc_deregister(&ali_miscdev); |
453 | pci_dev_put(ali_pci); | ||
450 | } | 454 | } |
451 | 455 | ||
452 | module_init(watchdog_init); | 456 | module_init(watchdog_init); |
diff --git a/drivers/char/watchdog/alim7101_wdt.c b/drivers/char/watchdog/alim7101_wdt.c index ffd7684f999b..5948863b592b 100644 --- a/drivers/char/watchdog/alim7101_wdt.c +++ b/drivers/char/watchdog/alim7101_wdt.c | |||
@@ -277,7 +277,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u | |||
277 | case WDIOC_GETTIMEOUT: | 277 | case WDIOC_GETTIMEOUT: |
278 | return put_user(timeout, p); | 278 | return put_user(timeout, p); |
279 | default: | 279 | default: |
280 | return -ENOIOCTLCMD; | 280 | return -ENOTTY; |
281 | } | 281 | } |
282 | } | 282 | } |
283 | 283 | ||
@@ -333,6 +333,7 @@ static void __exit alim7101_wdt_unload(void) | |||
333 | /* Deregister */ | 333 | /* Deregister */ |
334 | misc_deregister(&wdt_miscdev); | 334 | misc_deregister(&wdt_miscdev); |
335 | unregister_reboot_notifier(&wdt_notifier); | 335 | unregister_reboot_notifier(&wdt_notifier); |
336 | pci_dev_put(alim7101_pmu); | ||
336 | } | 337 | } |
337 | 338 | ||
338 | static int __init alim7101_wdt_init(void) | 339 | static int __init alim7101_wdt_init(void) |
@@ -342,7 +343,8 @@ static int __init alim7101_wdt_init(void) | |||
342 | char tmp; | 343 | char tmp; |
343 | 344 | ||
344 | printk(KERN_INFO PFX "Steve Hill <steve@navaho.co.uk>.\n"); | 345 | printk(KERN_INFO PFX "Steve Hill <steve@navaho.co.uk>.\n"); |
345 | alim7101_pmu = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,NULL); | 346 | alim7101_pmu = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, |
347 | NULL); | ||
346 | if (!alim7101_pmu) { | 348 | if (!alim7101_pmu) { |
347 | printk(KERN_INFO PFX "ALi M7101 PMU not present - WDT not set\n"); | 349 | printk(KERN_INFO PFX "ALi M7101 PMU not present - WDT not set\n"); |
348 | return -EBUSY; | 350 | return -EBUSY; |
@@ -351,21 +353,23 @@ static int __init alim7101_wdt_init(void) | |||
351 | /* Set the WDT in the PMU to 1 second */ | 353 | /* Set the WDT in the PMU to 1 second */ |
352 | pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, 0x02); | 354 | pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, 0x02); |
353 | 355 | ||
354 | ali1543_south = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); | 356 | ali1543_south = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, |
357 | NULL); | ||
355 | if (!ali1543_south) { | 358 | if (!ali1543_south) { |
356 | printk(KERN_INFO PFX "ALi 1543 South-Bridge not present - WDT not set\n"); | 359 | printk(KERN_INFO PFX "ALi 1543 South-Bridge not present - WDT not set\n"); |
357 | return -EBUSY; | 360 | goto err_out; |
358 | } | 361 | } |
359 | pci_read_config_byte(ali1543_south, 0x5e, &tmp); | 362 | pci_read_config_byte(ali1543_south, 0x5e, &tmp); |
363 | pci_dev_put(ali1543_south); | ||
360 | if ((tmp & 0x1e) == 0x00) { | 364 | if ((tmp & 0x1e) == 0x00) { |
361 | if (!use_gpio) { | 365 | if (!use_gpio) { |
362 | printk(KERN_INFO PFX "Detected old alim7101 revision 'a1d'. If this is a cobalt board, set the 'use_gpio' module parameter.\n"); | 366 | printk(KERN_INFO PFX "Detected old alim7101 revision 'a1d'. If this is a cobalt board, set the 'use_gpio' module parameter.\n"); |
363 | return -EBUSY; | 367 | goto err_out; |
364 | } | 368 | } |
365 | nowayout = 1; | 369 | nowayout = 1; |
366 | } else if ((tmp & 0x1e) != 0x12 && (tmp & 0x1e) != 0x00) { | 370 | } else if ((tmp & 0x1e) != 0x12 && (tmp & 0x1e) != 0x00) { |
367 | printk(KERN_INFO PFX "ALi 1543 South-Bridge does not have the correct revision number (???1001?) - WDT not set\n"); | 371 | printk(KERN_INFO PFX "ALi 1543 South-Bridge does not have the correct revision number (???1001?) - WDT not set\n"); |
368 | return -EBUSY; | 372 | goto err_out; |
369 | } | 373 | } |
370 | 374 | ||
371 | if(timeout < 1 || timeout > 3600) /* arbitrary upper limit */ | 375 | if(timeout < 1 || timeout > 3600) /* arbitrary upper limit */ |
@@ -404,6 +408,7 @@ static int __init alim7101_wdt_init(void) | |||
404 | err_out_miscdev: | 408 | err_out_miscdev: |
405 | misc_deregister(&wdt_miscdev); | 409 | misc_deregister(&wdt_miscdev); |
406 | err_out: | 410 | err_out: |
411 | pci_dev_put(alim7101_pmu); | ||
407 | return rc; | 412 | return rc; |
408 | } | 413 | } |
409 | 414 | ||
diff --git a/drivers/char/watchdog/at91_wdt.c b/drivers/char/watchdog/at91_wdt.c index cc266715ea32..4e7a1145e78f 100644 --- a/drivers/char/watchdog/at91_wdt.c +++ b/drivers/char/watchdog/at91_wdt.c | |||
@@ -168,7 +168,7 @@ static int at91_wdt_ioctl(struct inode *inode, struct file *file, | |||
168 | return 0; | 168 | return 0; |
169 | 169 | ||
170 | default: | 170 | default: |
171 | return -ENOIOCTLCMD; | 171 | return -ENOTTY; |
172 | } | 172 | } |
173 | } | 173 | } |
174 | 174 | ||
diff --git a/drivers/char/watchdog/booke_wdt.c b/drivers/char/watchdog/booke_wdt.c index e3cefc538b40..488902231cc2 100644 --- a/drivers/char/watchdog/booke_wdt.c +++ b/drivers/char/watchdog/booke_wdt.c | |||
@@ -125,7 +125,7 @@ static int booke_wdt_ioctl (struct inode *inode, struct file *file, | |||
125 | return -EINVAL; | 125 | return -EINVAL; |
126 | return 0; | 126 | return 0; |
127 | default: | 127 | default: |
128 | return -ENOIOCTLCMD; | 128 | return -ENOTTY; |
129 | } | 129 | } |
130 | 130 | ||
131 | return 0; | 131 | return 0; |
diff --git a/drivers/char/watchdog/cpu5wdt.c b/drivers/char/watchdog/cpu5wdt.c index 04c7e49918db..00bdabb90f27 100644 --- a/drivers/char/watchdog/cpu5wdt.c +++ b/drivers/char/watchdog/cpu5wdt.c | |||
@@ -183,7 +183,7 @@ static int cpu5wdt_ioctl(struct inode *inode, struct file *file, unsigned int cm | |||
183 | } | 183 | } |
184 | break; | 184 | break; |
185 | default: | 185 | default: |
186 | return -ENOIOCTLCMD; | 186 | return -ENOTTY; |
187 | } | 187 | } |
188 | return 0; | 188 | return 0; |
189 | } | 189 | } |
diff --git a/drivers/char/watchdog/ep93xx_wdt.c b/drivers/char/watchdog/ep93xx_wdt.c index 77c8a955ae9e..01cf123b1616 100644 --- a/drivers/char/watchdog/ep93xx_wdt.c +++ b/drivers/char/watchdog/ep93xx_wdt.c | |||
@@ -144,7 +144,7 @@ static int | |||
144 | ep93xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 144 | ep93xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, |
145 | unsigned long arg) | 145 | unsigned long arg) |
146 | { | 146 | { |
147 | int ret = -ENOIOCTLCMD; | 147 | int ret = -ENOTTY; |
148 | 148 | ||
149 | switch (cmd) { | 149 | switch (cmd) { |
150 | case WDIOC_GETSUPPORT: | 150 | case WDIOC_GETSUPPORT: |
diff --git a/drivers/char/watchdog/eurotechwdt.c b/drivers/char/watchdog/eurotechwdt.c index 62dbccb2f6df..4f4269754c46 100644 --- a/drivers/char/watchdog/eurotechwdt.c +++ b/drivers/char/watchdog/eurotechwdt.c | |||
@@ -240,7 +240,7 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file, | |||
240 | 240 | ||
241 | switch(cmd) { | 241 | switch(cmd) { |
242 | default: | 242 | default: |
243 | return -ENOIOCTLCMD; | 243 | return -ENOTTY; |
244 | 244 | ||
245 | case WDIOC_GETSUPPORT: | 245 | case WDIOC_GETSUPPORT: |
246 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; | 246 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; |
diff --git a/drivers/char/watchdog/i6300esb.c b/drivers/char/watchdog/i6300esb.c index 870539eabbf3..fb64df4d7c87 100644 --- a/drivers/char/watchdog/i6300esb.c +++ b/drivers/char/watchdog/i6300esb.c | |||
@@ -315,7 +315,7 @@ static int esb_ioctl (struct inode *inode, struct file *file, | |||
315 | return put_user(heartbeat, p); | 315 | return put_user(heartbeat, p); |
316 | 316 | ||
317 | default: | 317 | default: |
318 | return -ENOIOCTLCMD; | 318 | return -ENOTTY; |
319 | } | 319 | } |
320 | } | 320 | } |
321 | 321 | ||
diff --git a/drivers/char/watchdog/i8xx_tco.c b/drivers/char/watchdog/i8xx_tco.c index 8385dd36eefe..e0627d79707b 100644 --- a/drivers/char/watchdog/i8xx_tco.c +++ b/drivers/char/watchdog/i8xx_tco.c | |||
@@ -356,7 +356,7 @@ static int i8xx_tco_ioctl (struct inode *inode, struct file *file, | |||
356 | } | 356 | } |
357 | 357 | ||
358 | default: | 358 | default: |
359 | return -ENOIOCTLCMD; | 359 | return -ENOTTY; |
360 | } | 360 | } |
361 | } | 361 | } |
362 | 362 | ||
@@ -406,18 +406,18 @@ static struct notifier_block i8xx_tco_notifier = { | |||
406 | * want to register another driver on the same PCI id. | 406 | * want to register another driver on the same PCI id. |
407 | */ | 407 | */ |
408 | static struct pci_device_id i8xx_tco_pci_tbl[] = { | 408 | static struct pci_device_id i8xx_tco_pci_tbl[] = { |
409 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, PCI_ANY_ID, PCI_ANY_ID, }, | 409 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0) }, |
410 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0, PCI_ANY_ID, PCI_ANY_ID, }, | 410 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0) }, |
411 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, PCI_ANY_ID, PCI_ANY_ID, }, | 411 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0) }, |
412 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10, PCI_ANY_ID, PCI_ANY_ID, }, | 412 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10) }, |
413 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, PCI_ANY_ID, PCI_ANY_ID, }, | 413 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0) }, |
414 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, PCI_ANY_ID, PCI_ANY_ID, }, | 414 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12) }, |
415 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, PCI_ANY_ID, PCI_ANY_ID, }, | 415 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0) }, |
416 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, PCI_ANY_ID, PCI_ANY_ID, }, | 416 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12) }, |
417 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_0, PCI_ANY_ID, PCI_ANY_ID, }, | 417 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_0) }, |
418 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, PCI_ANY_ID, PCI_ANY_ID, }, | 418 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0) }, |
419 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1, PCI_ANY_ID, PCI_ANY_ID, }, | 419 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1) }, |
420 | { 0, }, /* End of list */ | 420 | { }, /* End of list */ |
421 | }; | 421 | }; |
422 | MODULE_DEVICE_TABLE (pci, i8xx_tco_pci_tbl); | 422 | MODULE_DEVICE_TABLE (pci, i8xx_tco_pci_tbl); |
423 | 423 | ||
@@ -434,12 +434,11 @@ static unsigned char __init i8xx_tco_getdevice (void) | |||
434 | * Find the PCI device | 434 | * Find the PCI device |
435 | */ | 435 | */ |
436 | 436 | ||
437 | while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | 437 | for_each_pci_dev(dev) |
438 | if (pci_match_id(i8xx_tco_pci_tbl, dev)) { | 438 | if (pci_match_id(i8xx_tco_pci_tbl, dev)) { |
439 | i8xx_tco_pci = dev; | 439 | i8xx_tco_pci = dev; |
440 | break; | 440 | break; |
441 | } | 441 | } |
442 | } | ||
443 | 442 | ||
444 | if (i8xx_tco_pci) { | 443 | if (i8xx_tco_pci) { |
445 | /* | 444 | /* |
@@ -454,6 +453,7 @@ static unsigned char __init i8xx_tco_getdevice (void) | |||
454 | /* Something's wrong here, ACPIBASE has to be set */ | 453 | /* Something's wrong here, ACPIBASE has to be set */ |
455 | if (badr == 0x0001 || badr == 0x0000) { | 454 | if (badr == 0x0001 || badr == 0x0000) { |
456 | printk (KERN_ERR PFX "failed to get TCOBASE address\n"); | 455 | printk (KERN_ERR PFX "failed to get TCOBASE address\n"); |
456 | pci_dev_put(i8xx_tco_pci); | ||
457 | return 0; | 457 | return 0; |
458 | } | 458 | } |
459 | 459 | ||
@@ -465,6 +465,7 @@ static unsigned char __init i8xx_tco_getdevice (void) | |||
465 | pci_read_config_byte (i8xx_tco_pci, 0xd4, &val1); | 465 | pci_read_config_byte (i8xx_tco_pci, 0xd4, &val1); |
466 | if (val1 & 0x02) { | 466 | if (val1 & 0x02) { |
467 | printk (KERN_ERR PFX "failed to reset NO_REBOOT flag, reboot disabled by hardware\n"); | 467 | printk (KERN_ERR PFX "failed to reset NO_REBOOT flag, reboot disabled by hardware\n"); |
468 | pci_dev_put(i8xx_tco_pci); | ||
468 | return 0; /* Cannot reset NO_REBOOT bit */ | 469 | return 0; /* Cannot reset NO_REBOOT bit */ |
469 | } | 470 | } |
470 | } | 471 | } |
@@ -476,6 +477,7 @@ static unsigned char __init i8xx_tco_getdevice (void) | |||
476 | if (!request_region (SMI_EN + 1, 1, "i8xx TCO")) { | 477 | if (!request_region (SMI_EN + 1, 1, "i8xx TCO")) { |
477 | printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", | 478 | printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", |
478 | SMI_EN + 1); | 479 | SMI_EN + 1); |
480 | pci_dev_put(i8xx_tco_pci); | ||
479 | return 0; | 481 | return 0; |
480 | } | 482 | } |
481 | val1 = inb (SMI_EN + 1); | 483 | val1 = inb (SMI_EN + 1); |
@@ -542,6 +544,7 @@ unreg_notifier: | |||
542 | unreg_region: | 544 | unreg_region: |
543 | release_region (TCOBASE, 0x10); | 545 | release_region (TCOBASE, 0x10); |
544 | out: | 546 | out: |
547 | pci_dev_put(i8xx_tco_pci); | ||
545 | return ret; | 548 | return ret; |
546 | } | 549 | } |
547 | 550 | ||
@@ -555,6 +558,8 @@ static void __exit watchdog_cleanup (void) | |||
555 | misc_deregister (&i8xx_tco_miscdev); | 558 | misc_deregister (&i8xx_tco_miscdev); |
556 | unregister_reboot_notifier(&i8xx_tco_notifier); | 559 | unregister_reboot_notifier(&i8xx_tco_notifier); |
557 | release_region (TCOBASE, 0x10); | 560 | release_region (TCOBASE, 0x10); |
561 | |||
562 | pci_dev_put(i8xx_tco_pci); | ||
558 | } | 563 | } |
559 | 564 | ||
560 | module_init(watchdog_init); | 565 | module_init(watchdog_init); |
diff --git a/drivers/char/watchdog/ib700wdt.c b/drivers/char/watchdog/ib700wdt.c index fd95f7327798..c1ed209a138c 100644 --- a/drivers/char/watchdog/ib700wdt.c +++ b/drivers/char/watchdog/ib700wdt.c | |||
@@ -199,7 +199,7 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
199 | break; | 199 | break; |
200 | 200 | ||
201 | default: | 201 | default: |
202 | return -ENOIOCTLCMD; | 202 | return -ENOTTY; |
203 | } | 203 | } |
204 | return 0; | 204 | return 0; |
205 | } | 205 | } |
diff --git a/drivers/char/watchdog/ibmasr.c b/drivers/char/watchdog/ibmasr.c index 26ceee7a4df0..dd6760f1a23b 100644 --- a/drivers/char/watchdog/ibmasr.c +++ b/drivers/char/watchdog/ibmasr.c | |||
@@ -295,7 +295,7 @@ static int asr_ioctl(struct inode *inode, struct file *file, | |||
295 | } | 295 | } |
296 | } | 296 | } |
297 | 297 | ||
298 | return -ENOIOCTLCMD; | 298 | return -ENOTTY; |
299 | } | 299 | } |
300 | 300 | ||
301 | static int asr_open(struct inode *inode, struct file *file) | 301 | static int asr_open(struct inode *inode, struct file *file) |
diff --git a/drivers/char/watchdog/indydog.c b/drivers/char/watchdog/indydog.c index dacc1c20a310..0bc239308989 100644 --- a/drivers/char/watchdog/indydog.c +++ b/drivers/char/watchdog/indydog.c | |||
@@ -112,7 +112,7 @@ static int indydog_ioctl(struct inode *inode, struct file *file, | |||
112 | 112 | ||
113 | switch (cmd) { | 113 | switch (cmd) { |
114 | default: | 114 | default: |
115 | return -ENOIOCTLCMD; | 115 | return -ENOTTY; |
116 | case WDIOC_GETSUPPORT: | 116 | case WDIOC_GETSUPPORT: |
117 | if (copy_to_user((struct watchdog_info *)arg, | 117 | if (copy_to_user((struct watchdog_info *)arg, |
118 | &ident, sizeof(ident))) | 118 | &ident, sizeof(ident))) |
diff --git a/drivers/char/watchdog/ixp2000_wdt.c b/drivers/char/watchdog/ixp2000_wdt.c index 692908819e26..c91d9a660ec0 100644 --- a/drivers/char/watchdog/ixp2000_wdt.c +++ b/drivers/char/watchdog/ixp2000_wdt.c | |||
@@ -107,7 +107,7 @@ static int | |||
107 | ixp2000_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 107 | ixp2000_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, |
108 | unsigned long arg) | 108 | unsigned long arg) |
109 | { | 109 | { |
110 | int ret = -ENOIOCTLCMD; | 110 | int ret = -ENOTTY; |
111 | int time; | 111 | int time; |
112 | 112 | ||
113 | switch (cmd) { | 113 | switch (cmd) { |
diff --git a/drivers/char/watchdog/ixp4xx_wdt.c b/drivers/char/watchdog/ixp4xx_wdt.c index 9db5cf2c38c3..db477f712388 100644 --- a/drivers/char/watchdog/ixp4xx_wdt.c +++ b/drivers/char/watchdog/ixp4xx_wdt.c | |||
@@ -102,7 +102,7 @@ static int | |||
102 | ixp4xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 102 | ixp4xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, |
103 | unsigned long arg) | 103 | unsigned long arg) |
104 | { | 104 | { |
105 | int ret = -ENOIOCTLCMD; | 105 | int ret = -ENOTTY; |
106 | int time; | 106 | int time; |
107 | 107 | ||
108 | switch (cmd) { | 108 | switch (cmd) { |
diff --git a/drivers/char/watchdog/machzwd.c b/drivers/char/watchdog/machzwd.c index 23734e07fb22..276577d08fba 100644 --- a/drivers/char/watchdog/machzwd.c +++ b/drivers/char/watchdog/machzwd.c | |||
@@ -329,7 +329,7 @@ static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
329 | break; | 329 | break; |
330 | 330 | ||
331 | default: | 331 | default: |
332 | return -ENOIOCTLCMD; | 332 | return -ENOTTY; |
333 | } | 333 | } |
334 | 334 | ||
335 | return 0; | 335 | return 0; |
@@ -426,8 +426,7 @@ static int __init zf_init(void) | |||
426 | printk(KERN_INFO PFX ": MachZ ZF-Logic Watchdog driver initializing.\n"); | 426 | printk(KERN_INFO PFX ": MachZ ZF-Logic Watchdog driver initializing.\n"); |
427 | 427 | ||
428 | ret = zf_get_ZFL_version(); | 428 | ret = zf_get_ZFL_version(); |
429 | printk("%#x\n", ret); | 429 | if ((!ret) || (ret == 0xffff)) { |
430 | if((!ret) || (ret != 0xffff)){ | ||
431 | printk(KERN_WARNING PFX ": no ZF-Logic found\n"); | 430 | printk(KERN_WARNING PFX ": no ZF-Logic found\n"); |
432 | return -ENODEV; | 431 | return -ENODEV; |
433 | } | 432 | } |
diff --git a/drivers/char/watchdog/mixcomwd.c b/drivers/char/watchdog/mixcomwd.c index ae943324d251..c2dac0aa1d62 100644 --- a/drivers/char/watchdog/mixcomwd.c +++ b/drivers/char/watchdog/mixcomwd.c | |||
@@ -185,7 +185,7 @@ static int mixcomwd_ioctl(struct inode *inode, struct file *file, | |||
185 | mixcomwd_ping(); | 185 | mixcomwd_ping(); |
186 | break; | 186 | break; |
187 | default: | 187 | default: |
188 | return -ENOIOCTLCMD; | 188 | return -ENOTTY; |
189 | } | 189 | } |
190 | return 0; | 190 | return 0; |
191 | } | 191 | } |
diff --git a/drivers/char/watchdog/mpc83xx_wdt.c b/drivers/char/watchdog/mpc83xx_wdt.c index a480903ee1a5..18ca752e2f90 100644 --- a/drivers/char/watchdog/mpc83xx_wdt.c +++ b/drivers/char/watchdog/mpc83xx_wdt.c | |||
@@ -125,7 +125,7 @@ static int mpc83xx_wdt_ioctl(struct inode *inode, struct file *file, | |||
125 | case WDIOC_GETTIMEOUT: | 125 | case WDIOC_GETTIMEOUT: |
126 | return put_user(timeout_sec, p); | 126 | return put_user(timeout_sec, p); |
127 | default: | 127 | default: |
128 | return -ENOIOCTLCMD; | 128 | return -ENOTTY; |
129 | } | 129 | } |
130 | } | 130 | } |
131 | 131 | ||
diff --git a/drivers/char/watchdog/mpc8xx_wdt.c b/drivers/char/watchdog/mpc8xx_wdt.c index 35dd9e6e1140..8aaed10dd499 100644 --- a/drivers/char/watchdog/mpc8xx_wdt.c +++ b/drivers/char/watchdog/mpc8xx_wdt.c | |||
@@ -126,7 +126,7 @@ static int mpc8xx_wdt_ioctl(struct inode *inode, struct file *file, | |||
126 | break; | 126 | break; |
127 | 127 | ||
128 | default: | 128 | default: |
129 | return -ENOIOCTLCMD; | 129 | return -ENOTTY; |
130 | } | 130 | } |
131 | 131 | ||
132 | return 0; | 132 | return 0; |
diff --git a/drivers/char/watchdog/mpcore_wdt.c b/drivers/char/watchdog/mpcore_wdt.c index 54b3c56ead0d..02d336ace504 100644 --- a/drivers/char/watchdog/mpcore_wdt.c +++ b/drivers/char/watchdog/mpcore_wdt.c | |||
@@ -221,7 +221,7 @@ static int mpcore_wdt_ioctl(struct inode *inode, struct file *file, | |||
221 | } uarg; | 221 | } uarg; |
222 | 222 | ||
223 | if (_IOC_DIR(cmd) && _IOC_SIZE(cmd) > sizeof(uarg)) | 223 | if (_IOC_DIR(cmd) && _IOC_SIZE(cmd) > sizeof(uarg)) |
224 | return -ENOIOCTLCMD; | 224 | return -ENOTTY; |
225 | 225 | ||
226 | if (_IOC_DIR(cmd) & _IOC_WRITE) { | 226 | if (_IOC_DIR(cmd) & _IOC_WRITE) { |
227 | ret = copy_from_user(&uarg, (void __user *)arg, _IOC_SIZE(cmd)); | 227 | ret = copy_from_user(&uarg, (void __user *)arg, _IOC_SIZE(cmd)); |
@@ -271,7 +271,7 @@ static int mpcore_wdt_ioctl(struct inode *inode, struct file *file, | |||
271 | break; | 271 | break; |
272 | 272 | ||
273 | default: | 273 | default: |
274 | return -ENOIOCTLCMD; | 274 | return -ENOTTY; |
275 | } | 275 | } |
276 | 276 | ||
277 | if (ret == 0 && _IOC_DIR(cmd) & _IOC_READ) { | 277 | if (ret == 0 && _IOC_DIR(cmd) & _IOC_READ) { |
diff --git a/drivers/char/watchdog/mv64x60_wdt.c b/drivers/char/watchdog/mv64x60_wdt.c index 5c8fab345b40..b887cdb01334 100644 --- a/drivers/char/watchdog/mv64x60_wdt.c +++ b/drivers/char/watchdog/mv64x60_wdt.c | |||
@@ -160,7 +160,7 @@ static int mv64x60_wdt_ioctl(struct inode *inode, struct file *file, | |||
160 | break; | 160 | break; |
161 | 161 | ||
162 | default: | 162 | default: |
163 | return -ENOIOCTLCMD; | 163 | return -ENOTTY; |
164 | } | 164 | } |
165 | 165 | ||
166 | return 0; | 166 | return 0; |
diff --git a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c index cd7d1b6a5d9f..6f8515db5b07 100644 --- a/drivers/char/watchdog/pcwd.c +++ b/drivers/char/watchdog/pcwd.c | |||
@@ -572,7 +572,7 @@ static int pcwd_ioctl(struct inode *inode, struct file *file, | |||
572 | 572 | ||
573 | switch(cmd) { | 573 | switch(cmd) { |
574 | default: | 574 | default: |
575 | return -ENOIOCTLCMD; | 575 | return -ENOTTY; |
576 | 576 | ||
577 | case WDIOC_GETSUPPORT: | 577 | case WDIOC_GETSUPPORT: |
578 | if(copy_to_user(argp, &ident, sizeof(ident))) | 578 | if(copy_to_user(argp, &ident, sizeof(ident))) |
diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c index c7cfd6dbfe1b..2de6e497c140 100644 --- a/drivers/char/watchdog/pcwd_pci.c +++ b/drivers/char/watchdog/pcwd_pci.c | |||
@@ -541,7 +541,7 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file, | |||
541 | } | 541 | } |
542 | 542 | ||
543 | default: | 543 | default: |
544 | return -ENOIOCTLCMD; | 544 | return -ENOTTY; |
545 | } | 545 | } |
546 | } | 546 | } |
547 | 547 | ||
diff --git a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c index b7ae73dcdd08..77662cb0ac46 100644 --- a/drivers/char/watchdog/pcwd_usb.c +++ b/drivers/char/watchdog/pcwd_usb.c | |||
@@ -445,7 +445,7 @@ static int usb_pcwd_ioctl(struct inode *inode, struct file *file, | |||
445 | } | 445 | } |
446 | 446 | ||
447 | default: | 447 | default: |
448 | return -ENOIOCTLCMD; | 448 | return -ENOTTY; |
449 | } | 449 | } |
450 | } | 450 | } |
451 | 451 | ||
diff --git a/drivers/char/watchdog/pnx4008_wdt.c b/drivers/char/watchdog/pnx4008_wdt.c new file mode 100644 index 000000000000..e7f0450a939d --- /dev/null +++ b/drivers/char/watchdog/pnx4008_wdt.c | |||
@@ -0,0 +1,362 @@ | |||
1 | /* | ||
2 | * drivers/char/watchdog/pnx4008_wdt.c | ||
3 | * | ||
4 | * Watchdog driver for PNX4008 board | ||
5 | * | ||
6 | * Authors: Dmitry Chigirev <source@mvista.com>, | ||
7 | * Vitaly Wool <vitalywool@gmail.com> | ||
8 | * Based on sa1100 driver, | ||
9 | * Copyright (C) 2000 Oleg Drokin <green@crimea.edu> | ||
10 | * | ||
11 | * 2005-2006 (c) MontaVista Software, Inc. This file is licensed under | ||
12 | * the terms of the GNU General Public License version 2. This program | ||
13 | * is licensed "as is" without any warranty of any kind, whether express | ||
14 | * or implied. | ||
15 | */ | ||
16 | |||
17 | #include <linux/config.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/moduleparam.h> | ||
20 | #include <linux/types.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/fs.h> | ||
23 | #include <linux/miscdevice.h> | ||
24 | #include <linux/watchdog.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/bitops.h> | ||
27 | #include <linux/ioport.h> | ||
28 | #include <linux/device.h> | ||
29 | #include <linux/platform_device.h> | ||
30 | #include <linux/clk.h> | ||
31 | #include <linux/spinlock.h> | ||
32 | |||
33 | #include <asm/hardware.h> | ||
34 | #include <asm/uaccess.h> | ||
35 | #include <asm/io.h> | ||
36 | |||
37 | #define MODULE_NAME "PNX4008-WDT: " | ||
38 | |||
39 | /* WatchDog Timer - Chapter 23 Page 207 */ | ||
40 | |||
41 | #define DEFAULT_HEARTBEAT 19 | ||
42 | #define MAX_HEARTBEAT 60 | ||
43 | |||
44 | /* Watchdog timer register set definition */ | ||
45 | #define WDTIM_INT(p) ((p) + 0x0) | ||
46 | #define WDTIM_CTRL(p) ((p) + 0x4) | ||
47 | #define WDTIM_COUNTER(p) ((p) + 0x8) | ||
48 | #define WDTIM_MCTRL(p) ((p) + 0xC) | ||
49 | #define WDTIM_MATCH0(p) ((p) + 0x10) | ||
50 | #define WDTIM_EMR(p) ((p) + 0x14) | ||
51 | #define WDTIM_PULSE(p) ((p) + 0x18) | ||
52 | #define WDTIM_RES(p) ((p) + 0x1C) | ||
53 | |||
54 | /* WDTIM_INT bit definitions */ | ||
55 | #define MATCH_INT 1 | ||
56 | |||
57 | /* WDTIM_CTRL bit definitions */ | ||
58 | #define COUNT_ENAB 1 | ||
59 | #define RESET_COUNT (1<<1) | ||
60 | #define DEBUG_EN (1<<2) | ||
61 | |||
62 | /* WDTIM_MCTRL bit definitions */ | ||
63 | #define MR0_INT 1 | ||
64 | #undef RESET_COUNT0 | ||
65 | #define RESET_COUNT0 (1<<2) | ||
66 | #define STOP_COUNT0 (1<<2) | ||
67 | #define M_RES1 (1<<3) | ||
68 | #define M_RES2 (1<<4) | ||
69 | #define RESFRC1 (1<<5) | ||
70 | #define RESFRC2 (1<<6) | ||
71 | |||
72 | /* WDTIM_EMR bit definitions */ | ||
73 | #define EXT_MATCH0 1 | ||
74 | #define MATCH_OUTPUT_HIGH (2<<4) /*a MATCH_CTRL setting */ | ||
75 | |||
76 | /* WDTIM_RES bit definitions */ | ||
77 | #define WDOG_RESET 1 /* read only */ | ||
78 | |||
79 | #define WDOG_COUNTER_RATE 13000000 /*the counter clock is 13 MHz fixed */ | ||
80 | |||
81 | static int nowayout = WATCHDOG_NOWAYOUT; | ||
82 | static int heartbeat = DEFAULT_HEARTBEAT; | ||
83 | |||
84 | static spinlock_t io_lock; | ||
85 | static unsigned long wdt_status; | ||
86 | #define WDT_IN_USE 0 | ||
87 | #define WDT_OK_TO_CLOSE 1 | ||
88 | #define WDT_REGION_INITED 2 | ||
89 | #define WDT_DEVICE_INITED 3 | ||
90 | |||
91 | static unsigned long boot_status; | ||
92 | |||
93 | static struct resource *wdt_mem; | ||
94 | static void __iomem *wdt_base; | ||
95 | struct clk *wdt_clk; | ||
96 | |||
97 | static void wdt_enable(void) | ||
98 | { | ||
99 | spin_lock(&io_lock); | ||
100 | |||
101 | if (wdt_clk) | ||
102 | clk_set_rate(wdt_clk, 1); | ||
103 | |||
104 | /* stop counter, initiate counter reset */ | ||
105 | __raw_writel(RESET_COUNT, WDTIM_CTRL(wdt_base)); | ||
106 | /*wait for reset to complete. 100% guarantee event */ | ||
107 | while (__raw_readl(WDTIM_COUNTER(wdt_base))) | ||
108 | cpu_relax(); | ||
109 | /* internal and external reset, stop after that */ | ||
110 | __raw_writel(M_RES2 | STOP_COUNT0 | RESET_COUNT0, | ||
111 | WDTIM_MCTRL(wdt_base)); | ||
112 | /* configure match output */ | ||
113 | __raw_writel(MATCH_OUTPUT_HIGH, WDTIM_EMR(wdt_base)); | ||
114 | /* clear interrupt, just in case */ | ||
115 | __raw_writel(MATCH_INT, WDTIM_INT(wdt_base)); | ||
116 | /* the longest pulse period 65541/(13*10^6) seconds ~ 5 ms. */ | ||
117 | __raw_writel(0xFFFF, WDTIM_PULSE(wdt_base)); | ||
118 | __raw_writel(heartbeat * WDOG_COUNTER_RATE, WDTIM_MATCH0(wdt_base)); | ||
119 | /*enable counter, stop when debugger active */ | ||
120 | __raw_writel(COUNT_ENAB | DEBUG_EN, WDTIM_CTRL(wdt_base)); | ||
121 | |||
122 | spin_unlock(&io_lock); | ||
123 | } | ||
124 | |||
125 | static void wdt_disable(void) | ||
126 | { | ||
127 | spin_lock(&io_lock); | ||
128 | |||
129 | __raw_writel(0, WDTIM_CTRL(wdt_base)); /*stop counter */ | ||
130 | if (wdt_clk) | ||
131 | clk_set_rate(wdt_clk, 0); | ||
132 | |||
133 | spin_unlock(&io_lock); | ||
134 | } | ||
135 | |||
136 | static int pnx4008_wdt_open(struct inode *inode, struct file *file) | ||
137 | { | ||
138 | if (test_and_set_bit(WDT_IN_USE, &wdt_status)) | ||
139 | return -EBUSY; | ||
140 | |||
141 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); | ||
142 | |||
143 | wdt_enable(); | ||
144 | |||
145 | return nonseekable_open(inode, file); | ||
146 | } | ||
147 | |||
148 | static ssize_t | ||
149 | pnx4008_wdt_write(struct file *file, const char *data, size_t len, | ||
150 | loff_t * ppos) | ||
151 | { | ||
152 | /* Can't seek (pwrite) on this device */ | ||
153 | if (ppos != &file->f_pos) | ||
154 | return -ESPIPE; | ||
155 | |||
156 | if (len) { | ||
157 | if (!nowayout) { | ||
158 | size_t i; | ||
159 | |||
160 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); | ||
161 | |||
162 | for (i = 0; i != len; i++) { | ||
163 | char c; | ||
164 | |||
165 | if (get_user(c, data + i)) | ||
166 | return -EFAULT; | ||
167 | if (c == 'V') | ||
168 | set_bit(WDT_OK_TO_CLOSE, &wdt_status); | ||
169 | } | ||
170 | } | ||
171 | wdt_enable(); | ||
172 | } | ||
173 | |||
174 | return len; | ||
175 | } | ||
176 | |||
177 | static struct watchdog_info ident = { | ||
178 | .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | | ||
179 | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, | ||
180 | .identity = "PNX4008 Watchdog", | ||
181 | }; | ||
182 | |||
183 | static int | ||
184 | pnx4008_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | ||
185 | unsigned long arg) | ||
186 | { | ||
187 | int ret = -ENOIOCTLCMD; | ||
188 | int time; | ||
189 | |||
190 | switch (cmd) { | ||
191 | case WDIOC_GETSUPPORT: | ||
192 | ret = copy_to_user((struct watchdog_info *)arg, &ident, | ||
193 | sizeof(ident)) ? -EFAULT : 0; | ||
194 | break; | ||
195 | |||
196 | case WDIOC_GETSTATUS: | ||
197 | ret = put_user(0, (int *)arg); | ||
198 | break; | ||
199 | |||
200 | case WDIOC_GETBOOTSTATUS: | ||
201 | ret = put_user(boot_status, (int *)arg); | ||
202 | break; | ||
203 | |||
204 | case WDIOC_SETTIMEOUT: | ||
205 | ret = get_user(time, (int *)arg); | ||
206 | if (ret) | ||
207 | break; | ||
208 | |||
209 | if (time <= 0 || time > MAX_HEARTBEAT) { | ||
210 | ret = -EINVAL; | ||
211 | break; | ||
212 | } | ||
213 | |||
214 | heartbeat = time; | ||
215 | wdt_enable(); | ||
216 | /* Fall through */ | ||
217 | |||
218 | case WDIOC_GETTIMEOUT: | ||
219 | ret = put_user(heartbeat, (int *)arg); | ||
220 | break; | ||
221 | |||
222 | case WDIOC_KEEPALIVE: | ||
223 | wdt_enable(); | ||
224 | ret = 0; | ||
225 | break; | ||
226 | } | ||
227 | return ret; | ||
228 | } | ||
229 | |||
230 | static int pnx4008_wdt_release(struct inode *inode, struct file *file) | ||
231 | { | ||
232 | if (!test_bit(WDT_OK_TO_CLOSE, &wdt_status)) | ||
233 | printk(KERN_WARNING "WATCHDOG: Device closed unexpectdly\n"); | ||
234 | |||
235 | wdt_disable(); | ||
236 | clear_bit(WDT_IN_USE, &wdt_status); | ||
237 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | static struct file_operations pnx4008_wdt_fops = { | ||
243 | .owner = THIS_MODULE, | ||
244 | .llseek = no_llseek, | ||
245 | .write = pnx4008_wdt_write, | ||
246 | .ioctl = pnx4008_wdt_ioctl, | ||
247 | .open = pnx4008_wdt_open, | ||
248 | .release = pnx4008_wdt_release, | ||
249 | }; | ||
250 | |||
251 | static struct miscdevice pnx4008_wdt_miscdev = { | ||
252 | .minor = WATCHDOG_MINOR, | ||
253 | .name = "watchdog", | ||
254 | .fops = &pnx4008_wdt_fops, | ||
255 | }; | ||
256 | |||
257 | static int pnx4008_wdt_probe(struct platform_device *pdev) | ||
258 | { | ||
259 | int ret = 0, size; | ||
260 | struct resource *res; | ||
261 | |||
262 | spin_lock_init(&io_lock); | ||
263 | |||
264 | if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT) | ||
265 | heartbeat = DEFAULT_HEARTBEAT; | ||
266 | |||
267 | printk(KERN_INFO MODULE_NAME | ||
268 | "PNX4008 Watchdog Timer: heartbeat %d sec\n", heartbeat); | ||
269 | |||
270 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
271 | if (res == NULL) { | ||
272 | printk(KERN_INFO MODULE_NAME | ||
273 | "failed to get memory region resouce\n"); | ||
274 | return -ENOENT; | ||
275 | } | ||
276 | |||
277 | size = res->end - res->start + 1; | ||
278 | wdt_mem = request_mem_region(res->start, size, pdev->name); | ||
279 | |||
280 | if (wdt_mem == NULL) { | ||
281 | printk(KERN_INFO MODULE_NAME "failed to get memory region\n"); | ||
282 | return -ENOENT; | ||
283 | } | ||
284 | wdt_base = (void __iomem *)IO_ADDRESS(res->start); | ||
285 | |||
286 | wdt_clk = clk_get(&pdev->dev, "wdt_ck"); | ||
287 | if (!wdt_clk) { | ||
288 | release_resource(wdt_mem); | ||
289 | kfree(wdt_mem); | ||
290 | goto out; | ||
291 | } else | ||
292 | clk_set_rate(wdt_clk, 1); | ||
293 | |||
294 | ret = misc_register(&pnx4008_wdt_miscdev); | ||
295 | if (ret < 0) { | ||
296 | printk(KERN_ERR MODULE_NAME "cannot register misc device\n"); | ||
297 | release_resource(wdt_mem); | ||
298 | kfree(wdt_mem); | ||
299 | clk_set_rate(wdt_clk, 0); | ||
300 | } else { | ||
301 | boot_status = (__raw_readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ? | ||
302 | WDIOF_CARDRESET : 0; | ||
303 | wdt_disable(); /*disable for now */ | ||
304 | set_bit(WDT_DEVICE_INITED, &wdt_status); | ||
305 | } | ||
306 | |||
307 | out: | ||
308 | return ret; | ||
309 | } | ||
310 | |||
311 | static int pnx4008_wdt_remove(struct platform_device *pdev) | ||
312 | { | ||
313 | misc_deregister(&pnx4008_wdt_miscdev); | ||
314 | if (wdt_clk) { | ||
315 | clk_set_rate(wdt_clk, 0); | ||
316 | clk_put(wdt_clk); | ||
317 | wdt_clk = NULL; | ||
318 | } | ||
319 | if (wdt_mem) { | ||
320 | release_resource(wdt_mem); | ||
321 | kfree(wdt_mem); | ||
322 | wdt_mem = NULL; | ||
323 | } | ||
324 | return 0; | ||
325 | } | ||
326 | |||
327 | static struct platform_driver platform_wdt_driver = { | ||
328 | .driver = { | ||
329 | .name = "watchdog", | ||
330 | }, | ||
331 | .probe = pnx4008_wdt_probe, | ||
332 | .remove = pnx4008_wdt_remove, | ||
333 | }; | ||
334 | |||
335 | static int __init pnx4008_wdt_init(void) | ||
336 | { | ||
337 | return platform_driver_register(&platform_wdt_driver); | ||
338 | } | ||
339 | |||
340 | static void __exit pnx4008_wdt_exit(void) | ||
341 | { | ||
342 | return platform_driver_unregister(&platform_wdt_driver); | ||
343 | } | ||
344 | |||
345 | module_init(pnx4008_wdt_init); | ||
346 | module_exit(pnx4008_wdt_exit); | ||
347 | |||
348 | MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>"); | ||
349 | MODULE_DESCRIPTION("PNX4008 Watchdog Driver"); | ||
350 | |||
351 | module_param(heartbeat, int, 0); | ||
352 | MODULE_PARM_DESC(heartbeat, | ||
353 | "Watchdog heartbeat period in seconds from 1 to " | ||
354 | __MODULE_STRING(MAX_HEARTBEAT) ", default " | ||
355 | __MODULE_STRING(DEFAULT_HEARTBEAT)); | ||
356 | |||
357 | module_param(nowayout, int, 0); | ||
358 | MODULE_PARM_DESC(nowayout, | ||
359 | "Set to 1 to keep watchdog running after device release"); | ||
360 | |||
361 | MODULE_LICENSE("GPL"); | ||
362 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | ||
diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c index be978e8ed754..b36a04ae9ab8 100644 --- a/drivers/char/watchdog/s3c2410_wdt.c +++ b/drivers/char/watchdog/s3c2410_wdt.c | |||
@@ -62,7 +62,7 @@ | |||
62 | #define CONFIG_S3C2410_WATCHDOG_ATBOOT (0) | 62 | #define CONFIG_S3C2410_WATCHDOG_ATBOOT (0) |
63 | #define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME (15) | 63 | #define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME (15) |
64 | 64 | ||
65 | static int nowayout = WATCHDOG_NOWAYOUT; | 65 | static int nowayout = WATCHDOG_NOWAYOUT; |
66 | static int tmr_margin = CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME; | 66 | static int tmr_margin = CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME; |
67 | static int tmr_atboot = CONFIG_S3C2410_WATCHDOG_ATBOOT; | 67 | static int tmr_atboot = CONFIG_S3C2410_WATCHDOG_ATBOOT; |
68 | static int soft_noboot = 0; | 68 | static int soft_noboot = 0; |
@@ -213,11 +213,10 @@ static int s3c2410wdt_open(struct inode *inode, struct file *file) | |||
213 | if(down_trylock(&open_lock)) | 213 | if(down_trylock(&open_lock)) |
214 | return -EBUSY; | 214 | return -EBUSY; |
215 | 215 | ||
216 | if (nowayout) { | 216 | if (nowayout) |
217 | __module_get(THIS_MODULE); | 217 | __module_get(THIS_MODULE); |
218 | } else { | 218 | |
219 | allow_close = CLOSE_STATE_ALLOW; | 219 | allow_close = CLOSE_STATE_NOT; |
220 | } | ||
221 | 220 | ||
222 | /* start the timer */ | 221 | /* start the timer */ |
223 | s3c2410wdt_start(); | 222 | s3c2410wdt_start(); |
@@ -230,6 +229,7 @@ static int s3c2410wdt_release(struct inode *inode, struct file *file) | |||
230 | * Shut off the timer. | 229 | * Shut off the timer. |
231 | * Lock it in if it's a module and we set nowayout | 230 | * Lock it in if it's a module and we set nowayout |
232 | */ | 231 | */ |
232 | |||
233 | if (allow_close == CLOSE_STATE_ALLOW) { | 233 | if (allow_close == CLOSE_STATE_ALLOW) { |
234 | s3c2410wdt_stop(); | 234 | s3c2410wdt_stop(); |
235 | } else { | 235 | } else { |
@@ -288,7 +288,7 @@ static int s3c2410wdt_ioctl(struct inode *inode, struct file *file, | |||
288 | 288 | ||
289 | switch (cmd) { | 289 | switch (cmd) { |
290 | default: | 290 | default: |
291 | return -ENOIOCTLCMD; | 291 | return -ENOTTY; |
292 | 292 | ||
293 | case WDIOC_GETSUPPORT: | 293 | case WDIOC_GETSUPPORT: |
294 | return copy_to_user(argp, &s3c2410_wdt_ident, | 294 | return copy_to_user(argp, &s3c2410_wdt_ident, |
diff --git a/drivers/char/watchdog/sa1100_wdt.c b/drivers/char/watchdog/sa1100_wdt.c index 1fc16d995788..33c1137f17d6 100644 --- a/drivers/char/watchdog/sa1100_wdt.c +++ b/drivers/char/watchdog/sa1100_wdt.c | |||
@@ -90,7 +90,7 @@ static struct watchdog_info ident = { | |||
90 | static int sa1100dog_ioctl(struct inode *inode, struct file *file, | 90 | static int sa1100dog_ioctl(struct inode *inode, struct file *file, |
91 | unsigned int cmd, unsigned long arg) | 91 | unsigned int cmd, unsigned long arg) |
92 | { | 92 | { |
93 | int ret = -ENOIOCTLCMD; | 93 | int ret = -ENOTTY; |
94 | int time; | 94 | int time; |
95 | void __user *argp = (void __user *)arg; | 95 | void __user *argp = (void __user *)arg; |
96 | int __user *p = argp; | 96 | int __user *p = argp; |
diff --git a/drivers/char/watchdog/sbc60xxwdt.c b/drivers/char/watchdog/sbc60xxwdt.c index 4663c2fd53cd..c7b2045bc76b 100644 --- a/drivers/char/watchdog/sbc60xxwdt.c +++ b/drivers/char/watchdog/sbc60xxwdt.c | |||
@@ -235,7 +235,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
235 | switch(cmd) | 235 | switch(cmd) |
236 | { | 236 | { |
237 | default: | 237 | default: |
238 | return -ENOIOCTLCMD; | 238 | return -ENOTTY; |
239 | case WDIOC_GETSUPPORT: | 239 | case WDIOC_GETSUPPORT: |
240 | return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; | 240 | return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; |
241 | case WDIOC_GETSTATUS: | 241 | case WDIOC_GETSTATUS: |
diff --git a/drivers/char/watchdog/sbc_epx_c3.c b/drivers/char/watchdog/sbc_epx_c3.c index bfc475dabe6d..8882b427d24f 100644 --- a/drivers/char/watchdog/sbc_epx_c3.c +++ b/drivers/char/watchdog/sbc_epx_c3.c | |||
@@ -141,7 +141,7 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file, | |||
141 | 141 | ||
142 | return retval; | 142 | return retval; |
143 | default: | 143 | default: |
144 | return -ENOIOCTLCMD; | 144 | return -ENOTTY; |
145 | } | 145 | } |
146 | } | 146 | } |
147 | 147 | ||
diff --git a/drivers/char/watchdog/sc1200wdt.c b/drivers/char/watchdog/sc1200wdt.c index 7c3cf293a5af..d8d0f28e0acf 100644 --- a/drivers/char/watchdog/sc1200wdt.c +++ b/drivers/char/watchdog/sc1200wdt.c | |||
@@ -180,7 +180,7 @@ static int sc1200wdt_ioctl(struct inode *inode, struct file *file, unsigned int | |||
180 | 180 | ||
181 | switch (cmd) { | 181 | switch (cmd) { |
182 | default: | 182 | default: |
183 | return -ENOIOCTLCMD; /* Keep Pavel Machek amused ;) */ | 183 | return -ENOTTY; |
184 | 184 | ||
185 | case WDIOC_GETSUPPORT: | 185 | case WDIOC_GETSUPPORT: |
186 | if (copy_to_user(argp, &ident, sizeof ident)) | 186 | if (copy_to_user(argp, &ident, sizeof ident)) |
diff --git a/drivers/char/watchdog/sc520_wdt.c b/drivers/char/watchdog/sc520_wdt.c index 2c7c9db71be8..caec37ba750a 100644 --- a/drivers/char/watchdog/sc520_wdt.c +++ b/drivers/char/watchdog/sc520_wdt.c | |||
@@ -290,7 +290,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
290 | switch(cmd) | 290 | switch(cmd) |
291 | { | 291 | { |
292 | default: | 292 | default: |
293 | return -ENOIOCTLCMD; | 293 | return -ENOTTY; |
294 | case WDIOC_GETSUPPORT: | 294 | case WDIOC_GETSUPPORT: |
295 | return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; | 295 | return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; |
296 | case WDIOC_GETSTATUS: | 296 | case WDIOC_GETSTATUS: |
diff --git a/drivers/char/watchdog/scx200_wdt.c b/drivers/char/watchdog/scx200_wdt.c index c561299a5537..fc0e0347f9d2 100644 --- a/drivers/char/watchdog/scx200_wdt.c +++ b/drivers/char/watchdog/scx200_wdt.c | |||
@@ -166,7 +166,7 @@ static int scx200_wdt_ioctl(struct inode *inode, struct file *file, | |||
166 | 166 | ||
167 | switch (cmd) { | 167 | switch (cmd) { |
168 | default: | 168 | default: |
169 | return -ENOIOCTLCMD; | 169 | return -ENOTTY; |
170 | case WDIOC_GETSUPPORT: | 170 | case WDIOC_GETSUPPORT: |
171 | if(copy_to_user(argp, &ident, sizeof(ident))) | 171 | if(copy_to_user(argp, &ident, sizeof(ident))) |
172 | return -EFAULT; | 172 | return -EFAULT; |
diff --git a/drivers/char/watchdog/shwdt.c b/drivers/char/watchdog/shwdt.c index e5b8c64f1d65..dc403629aeb3 100644 --- a/drivers/char/watchdog/shwdt.c +++ b/drivers/char/watchdog/shwdt.c | |||
@@ -360,7 +360,7 @@ static int sh_wdt_ioctl(struct inode *inode, struct file *file, | |||
360 | 360 | ||
361 | return retval; | 361 | return retval; |
362 | default: | 362 | default: |
363 | return -ENOIOCTLCMD; | 363 | return -ENOTTY; |
364 | } | 364 | } |
365 | 365 | ||
366 | return 0; | 366 | return 0; |
diff --git a/drivers/char/watchdog/softdog.c b/drivers/char/watchdog/softdog.c index ef8da517545a..4067e1f8a368 100644 --- a/drivers/char/watchdog/softdog.c +++ b/drivers/char/watchdog/softdog.c | |||
@@ -203,7 +203,7 @@ static int softdog_ioctl(struct inode *inode, struct file *file, | |||
203 | }; | 203 | }; |
204 | switch (cmd) { | 204 | switch (cmd) { |
205 | default: | 205 | default: |
206 | return -ENOIOCTLCMD; | 206 | return -ENOTTY; |
207 | case WDIOC_GETSUPPORT: | 207 | case WDIOC_GETSUPPORT: |
208 | return copy_to_user(argp, &ident, | 208 | return copy_to_user(argp, &ident, |
209 | sizeof(ident)) ? -EFAULT : 0; | 209 | sizeof(ident)) ? -EFAULT : 0; |
diff --git a/drivers/char/watchdog/w83627hf_wdt.c b/drivers/char/watchdog/w83627hf_wdt.c index 13f16d41c2fd..b4adc527e687 100644 --- a/drivers/char/watchdog/w83627hf_wdt.c +++ b/drivers/char/watchdog/w83627hf_wdt.c | |||
@@ -223,7 +223,7 @@ wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
223 | } | 223 | } |
224 | 224 | ||
225 | default: | 225 | default: |
226 | return -ENOIOCTLCMD; | 226 | return -ENOTTY; |
227 | } | 227 | } |
228 | return 0; | 228 | return 0; |
229 | } | 229 | } |
diff --git a/drivers/char/watchdog/w83877f_wdt.c b/drivers/char/watchdog/w83877f_wdt.c index ccf6c0915945..b0e5f84d6baf 100644 --- a/drivers/char/watchdog/w83877f_wdt.c +++ b/drivers/char/watchdog/w83877f_wdt.c | |||
@@ -252,7 +252,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
252 | switch(cmd) | 252 | switch(cmd) |
253 | { | 253 | { |
254 | default: | 254 | default: |
255 | return -ENOIOCTLCMD; | 255 | return -ENOTTY; |
256 | case WDIOC_GETSUPPORT: | 256 | case WDIOC_GETSUPPORT: |
257 | return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; | 257 | return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; |
258 | case WDIOC_GETSTATUS: | 258 | case WDIOC_GETSTATUS: |
diff --git a/drivers/char/watchdog/w83977f_wdt.c b/drivers/char/watchdog/w83977f_wdt.c index 98f4e17db70a..2c8d5d8bd4e8 100644 --- a/drivers/char/watchdog/w83977f_wdt.c +++ b/drivers/char/watchdog/w83977f_wdt.c | |||
@@ -393,7 +393,7 @@ static int wdt_ioctl(struct inode *inode, struct file *file, | |||
393 | switch(cmd) | 393 | switch(cmd) |
394 | { | 394 | { |
395 | default: | 395 | default: |
396 | return -ENOIOCTLCMD; | 396 | return -ENOTTY; |
397 | 397 | ||
398 | case WDIOC_GETSUPPORT: | 398 | case WDIOC_GETSUPPORT: |
399 | return copy_to_user(uarg.ident, &ident, sizeof(ident)) ? -EFAULT : 0; | 399 | return copy_to_user(uarg.ident, &ident, sizeof(ident)) ? -EFAULT : 0; |
diff --git a/drivers/char/watchdog/wafer5823wdt.c b/drivers/char/watchdog/wafer5823wdt.c index 2bb6a9d6ad28..163e028ef9ed 100644 --- a/drivers/char/watchdog/wafer5823wdt.c +++ b/drivers/char/watchdog/wafer5823wdt.c | |||
@@ -174,7 +174,7 @@ static int wafwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
174 | } | 174 | } |
175 | 175 | ||
176 | default: | 176 | default: |
177 | return -ENOIOCTLCMD; | 177 | return -ENOTTY; |
178 | } | 178 | } |
179 | return 0; | 179 | return 0; |
180 | } | 180 | } |
diff --git a/drivers/char/watchdog/wdrtas.c b/drivers/char/watchdog/wdrtas.c index 5c38cdf41731..1d64e277567d 100644 --- a/drivers/char/watchdog/wdrtas.c +++ b/drivers/char/watchdog/wdrtas.c | |||
@@ -385,7 +385,7 @@ wdrtas_ioctl(struct inode *inode, struct file *file, | |||
385 | return put_user(wdrtas_interval, argp); | 385 | return put_user(wdrtas_interval, argp); |
386 | 386 | ||
387 | default: | 387 | default: |
388 | return -ENOIOCTLCMD; | 388 | return -ENOTTY; |
389 | } | 389 | } |
390 | } | 390 | } |
391 | 391 | ||
diff --git a/drivers/char/watchdog/wdt.c b/drivers/char/watchdog/wdt.c index 70be81e39a61..13f23f4a2233 100644 --- a/drivers/char/watchdog/wdt.c +++ b/drivers/char/watchdog/wdt.c | |||
@@ -341,7 +341,7 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
341 | switch(cmd) | 341 | switch(cmd) |
342 | { | 342 | { |
343 | default: | 343 | default: |
344 | return -ENOIOCTLCMD; | 344 | return -ENOTTY; |
345 | case WDIOC_GETSUPPORT: | 345 | case WDIOC_GETSUPPORT: |
346 | return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; | 346 | return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; |
347 | 347 | ||
diff --git a/drivers/char/watchdog/wdt285.c b/drivers/char/watchdog/wdt285.c index 6555fb844f23..89a249e23fde 100644 --- a/drivers/char/watchdog/wdt285.c +++ b/drivers/char/watchdog/wdt285.c | |||
@@ -137,7 +137,7 @@ watchdog_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
137 | unsigned long arg) | 137 | unsigned long arg) |
138 | { | 138 | { |
139 | unsigned int new_margin; | 139 | unsigned int new_margin; |
140 | int ret = -ENOIOCTLCMD; | 140 | int ret = -ENOTTY; |
141 | 141 | ||
142 | switch(cmd) { | 142 | switch(cmd) { |
143 | case WDIOC_GETSUPPORT: | 143 | case WDIOC_GETSUPPORT: |
diff --git a/drivers/char/watchdog/wdt977.c b/drivers/char/watchdog/wdt977.c index a0935bc775f8..6253041b235b 100644 --- a/drivers/char/watchdog/wdt977.c +++ b/drivers/char/watchdog/wdt977.c | |||
@@ -361,7 +361,7 @@ static int wdt977_ioctl(struct inode *inode, struct file *file, | |||
361 | switch(cmd) | 361 | switch(cmd) |
362 | { | 362 | { |
363 | default: | 363 | default: |
364 | return -ENOIOCTLCMD; | 364 | return -ENOTTY; |
365 | 365 | ||
366 | case WDIOC_GETSUPPORT: | 366 | case WDIOC_GETSUPPORT: |
367 | return copy_to_user(uarg.ident, &ident, | 367 | return copy_to_user(uarg.ident, &ident, |
diff --git a/drivers/char/watchdog/wdt_pci.c b/drivers/char/watchdog/wdt_pci.c index 5918ca2c9c35..74d8cf836e13 100644 --- a/drivers/char/watchdog/wdt_pci.c +++ b/drivers/char/watchdog/wdt_pci.c | |||
@@ -386,7 +386,7 @@ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
386 | switch(cmd) | 386 | switch(cmd) |
387 | { | 387 | { |
388 | default: | 388 | default: |
389 | return -ENOIOCTLCMD; | 389 | return -ENOTTY; |
390 | case WDIOC_GETSUPPORT: | 390 | case WDIOC_GETSUPPORT: |
391 | return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; | 391 | return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; |
392 | 392 | ||
diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c index 23b086685453..fc17599c905e 100644 --- a/drivers/firmware/dell_rbu.c +++ b/drivers/firmware/dell_rbu.c | |||
@@ -227,7 +227,7 @@ static int packetize_data(void *data, size_t length) | |||
227 | int packet_length; | 227 | int packet_length; |
228 | u8 *temp; | 228 | u8 *temp; |
229 | u8 *end = (u8 *) data + length; | 229 | u8 *end = (u8 *) data + length; |
230 | pr_debug("packetize_data: data length %d\n", length); | 230 | pr_debug("packetize_data: data length %zd\n", length); |
231 | if (!rbu_data.packetsize) { | 231 | if (!rbu_data.packetsize) { |
232 | printk(KERN_WARNING | 232 | printk(KERN_WARNING |
233 | "dell_rbu: packetsize not specified\n"); | 233 | "dell_rbu: packetsize not specified\n"); |
@@ -249,7 +249,7 @@ static int packetize_data(void *data, size_t length) | |||
249 | if ((rc = create_packet(temp, packet_length))) | 249 | if ((rc = create_packet(temp, packet_length))) |
250 | return rc; | 250 | return rc; |
251 | 251 | ||
252 | pr_debug("%lu:%lu\n", temp, (end - temp)); | 252 | pr_debug("%p:%lu\n", temp, (end - temp)); |
253 | temp += packet_length; | 253 | temp += packet_length; |
254 | } | 254 | } |
255 | 255 | ||
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 69d627bd537a..abcabb295592 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig | |||
@@ -56,7 +56,7 @@ if IDE | |||
56 | 56 | ||
57 | config IDE_MAX_HWIFS | 57 | config IDE_MAX_HWIFS |
58 | int "Max IDE interfaces" | 58 | int "Max IDE interfaces" |
59 | depends on ALPHA || SUPERH || IA64 | 59 | depends on ALPHA || SUPERH || IA64 || EMBEDDED |
60 | default 4 | 60 | default 4 |
61 | help | 61 | help |
62 | This is the maximum number of IDE hardware interfaces that will | 62 | This is the maximum number of IDE hardware interfaces that will |
@@ -594,6 +594,12 @@ config BLK_DEV_HPT366 | |||
594 | ide-probe at boot. It is reported to support DVD II drives, by the | 594 | ide-probe at boot. It is reported to support DVD II drives, by the |
595 | manufacturer. | 595 | manufacturer. |
596 | 596 | ||
597 | config BLK_DEV_JMICRON | ||
598 | tristate "JMicron JMB36x support" | ||
599 | help | ||
600 | Basic support for the JMicron ATA controllers. For full support | ||
601 | use the libata drivers. | ||
602 | |||
597 | config BLK_DEV_SC1200 | 603 | config BLK_DEV_SC1200 |
598 | tristate "National SCx200 chipset support" | 604 | tristate "National SCx200 chipset support" |
599 | help | 605 | help |
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index c3546fe9af63..56efed6742d4 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c | |||
@@ -145,14 +145,12 @@ int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *driv | |||
145 | { | 145 | { |
146 | for ( ; drive_table->id_model ; drive_table++) | 146 | for ( ; drive_table->id_model ; drive_table++) |
147 | if ((!strcmp(drive_table->id_model, id->model)) && | 147 | if ((!strcmp(drive_table->id_model, id->model)) && |
148 | ((strstr(drive_table->id_firmware, id->fw_rev)) || | 148 | ((strstr(id->fw_rev, drive_table->id_firmware)) || |
149 | (!strcmp(drive_table->id_firmware, "ALL")))) | 149 | (!strcmp(drive_table->id_firmware, "ALL")))) |
150 | return 1; | 150 | return 1; |
151 | return 0; | 151 | return 0; |
152 | } | 152 | } |
153 | 153 | ||
154 | EXPORT_SYMBOL_GPL(ide_in_drive_list); | ||
155 | |||
156 | /** | 154 | /** |
157 | * ide_dma_intr - IDE DMA interrupt handler | 155 | * ide_dma_intr - IDE DMA interrupt handler |
158 | * @drive: the drive the interrupt is for | 156 | * @drive: the drive the interrupt is for |
@@ -798,26 +796,23 @@ static int ide_release_dma_engine(ide_hwif_t *hwif) | |||
798 | 796 | ||
799 | static int ide_release_iomio_dma(ide_hwif_t *hwif) | 797 | static int ide_release_iomio_dma(ide_hwif_t *hwif) |
800 | { | 798 | { |
801 | if ((hwif->dma_extra) && (hwif->channel == 0)) | ||
802 | release_region((hwif->dma_base + 16), hwif->dma_extra); | ||
803 | release_region(hwif->dma_base, 8); | 799 | release_region(hwif->dma_base, 8); |
804 | if (hwif->dma_base2) | 800 | if (hwif->extra_ports) |
805 | release_region(hwif->dma_base, 8); | 801 | release_region(hwif->extra_base, hwif->extra_ports); |
806 | return 1; | 802 | return 1; |
807 | } | 803 | } |
808 | 804 | ||
809 | /* | 805 | /* |
810 | * Needed for allowing full modular support of ide-driver | 806 | * Needed for allowing full modular support of ide-driver |
811 | */ | 807 | */ |
812 | int ide_release_dma (ide_hwif_t *hwif) | 808 | int ide_release_dma(ide_hwif_t *hwif) |
813 | { | 809 | { |
810 | ide_release_dma_engine(hwif); | ||
811 | |||
814 | if (hwif->mmio == 2) | 812 | if (hwif->mmio == 2) |
815 | return 1; | 813 | return 1; |
816 | if (hwif->chipset == ide_etrax100) | 814 | else |
817 | return 1; | 815 | return ide_release_iomio_dma(hwif); |
818 | |||
819 | ide_release_dma_engine(hwif); | ||
820 | return ide_release_iomio_dma(hwif); | ||
821 | } | 816 | } |
822 | 817 | ||
823 | static int ide_allocate_dma_engine(ide_hwif_t *hwif) | 818 | static int ide_allocate_dma_engine(ide_hwif_t *hwif) |
@@ -829,10 +824,9 @@ static int ide_allocate_dma_engine(ide_hwif_t *hwif) | |||
829 | if (hwif->dmatable_cpu) | 824 | if (hwif->dmatable_cpu) |
830 | return 0; | 825 | return 0; |
831 | 826 | ||
832 | printk(KERN_ERR "%s: -- Error, unable to allocate%s DMA table(s).\n", | 827 | printk(KERN_ERR "%s: -- Error, unable to allocate DMA table.\n", |
833 | hwif->cds->name, !hwif->dmatable_cpu ? " CPU" : ""); | 828 | hwif->cds->name); |
834 | 829 | ||
835 | ide_release_dma_engine(hwif); | ||
836 | return 1; | 830 | return 1; |
837 | } | 831 | } |
838 | 832 | ||
@@ -840,9 +834,7 @@ static int ide_mapped_mmio_dma(ide_hwif_t *hwif, unsigned long base, unsigned in | |||
840 | { | 834 | { |
841 | printk(KERN_INFO " %s: MMIO-DMA ", hwif->name); | 835 | printk(KERN_INFO " %s: MMIO-DMA ", hwif->name); |
842 | 836 | ||
843 | hwif->dma_base = base; | 837 | hwif->dma_base = base; |
844 | if (hwif->cds->extra && hwif->channel == 0) | ||
845 | hwif->dma_extra = hwif->cds->extra; | ||
846 | 838 | ||
847 | if(hwif->mate) | 839 | if(hwif->mate) |
848 | hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base : base; | 840 | hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base : base; |
@@ -854,29 +846,33 @@ static int ide_mapped_mmio_dma(ide_hwif_t *hwif, unsigned long base, unsigned in | |||
854 | static int ide_iomio_dma(ide_hwif_t *hwif, unsigned long base, unsigned int ports) | 846 | static int ide_iomio_dma(ide_hwif_t *hwif, unsigned long base, unsigned int ports) |
855 | { | 847 | { |
856 | printk(KERN_INFO " %s: BM-DMA at 0x%04lx-0x%04lx", | 848 | printk(KERN_INFO " %s: BM-DMA at 0x%04lx-0x%04lx", |
857 | hwif->name, base, base + ports - 1); | 849 | hwif->name, base, base + ports - 1); |
850 | |||
858 | if (!request_region(base, ports, hwif->name)) { | 851 | if (!request_region(base, ports, hwif->name)) { |
859 | printk(" -- Error, ports in use.\n"); | 852 | printk(" -- Error, ports in use.\n"); |
860 | return 1; | 853 | return 1; |
861 | } | 854 | } |
855 | |||
862 | hwif->dma_base = base; | 856 | hwif->dma_base = base; |
863 | if ((hwif->cds->extra) && (hwif->channel == 0)) { | 857 | |
864 | request_region(base+16, hwif->cds->extra, hwif->cds->name); | 858 | if (hwif->cds->extra) { |
865 | hwif->dma_extra = hwif->cds->extra; | 859 | hwif->extra_base = base + (hwif->channel ? 8 : 16); |
860 | |||
861 | if (!hwif->mate || !hwif->mate->extra_ports) { | ||
862 | if (!request_region(hwif->extra_base, | ||
863 | hwif->cds->extra, hwif->cds->name)) { | ||
864 | printk(" -- Error, extra ports in use.\n"); | ||
865 | release_region(base, ports); | ||
866 | return 1; | ||
867 | } | ||
868 | hwif->extra_ports = hwif->cds->extra; | ||
869 | } | ||
866 | } | 870 | } |
867 | 871 | ||
868 | if(hwif->mate) | 872 | if(hwif->mate) |
869 | hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base : base; | 873 | hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base:base; |
870 | else | 874 | else |
871 | hwif->dma_master = base; | 875 | hwif->dma_master = base; |
872 | if (hwif->dma_base2) { | ||
873 | if (!request_region(hwif->dma_base2, ports, hwif->name)) | ||
874 | { | ||
875 | printk(" -- Error, secondary ports in use.\n"); | ||
876 | release_region(base, ports); | ||
877 | return 1; | ||
878 | } | ||
879 | } | ||
880 | return 0; | 876 | return 0; |
881 | } | 877 | } |
882 | 878 | ||
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 38479a29d3e1..ba6039b55b41 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -59,8 +59,6 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, | |||
59 | { | 59 | { |
60 | int ret = 1; | 60 | int ret = 1; |
61 | 61 | ||
62 | BUG_ON(!blk_rq_started(rq)); | ||
63 | |||
64 | /* | 62 | /* |
65 | * if failfast is set on a request, override number of sectors and | 63 | * if failfast is set on a request, override number of sectors and |
66 | * complete the whole request right now | 64 | * complete the whole request right now |
@@ -82,7 +80,8 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, | |||
82 | 80 | ||
83 | if (!end_that_request_first(rq, uptodate, nr_sectors)) { | 81 | if (!end_that_request_first(rq, uptodate, nr_sectors)) { |
84 | add_disk_randomness(rq->rq_disk); | 82 | add_disk_randomness(rq->rq_disk); |
85 | blkdev_dequeue_request(rq); | 83 | if (!list_empty(&rq->queuelist)) |
84 | blkdev_dequeue_request(rq); | ||
86 | HWGROUP(drive)->rq = NULL; | 85 | HWGROUP(drive)->rq = NULL; |
87 | end_that_request_last(rq, uptodate); | 86 | end_that_request_last(rq, uptodate); |
88 | ret = 0; | 87 | ret = 0; |
@@ -135,7 +134,8 @@ enum { | |||
135 | ide_pm_flush_cache = ide_pm_state_start_suspend, | 134 | ide_pm_flush_cache = ide_pm_state_start_suspend, |
136 | idedisk_pm_standby, | 135 | idedisk_pm_standby, |
137 | 136 | ||
138 | idedisk_pm_idle = ide_pm_state_start_resume, | 137 | idedisk_pm_restore_pio = ide_pm_state_start_resume, |
138 | idedisk_pm_idle, | ||
139 | ide_pm_restore_dma, | 139 | ide_pm_restore_dma, |
140 | }; | 140 | }; |
141 | 141 | ||
@@ -156,7 +156,10 @@ static void ide_complete_power_step(ide_drive_t *drive, struct request *rq, u8 s | |||
156 | case idedisk_pm_standby: /* Suspend step 2 (standby) complete */ | 156 | case idedisk_pm_standby: /* Suspend step 2 (standby) complete */ |
157 | pm->pm_step = ide_pm_state_completed; | 157 | pm->pm_step = ide_pm_state_completed; |
158 | break; | 158 | break; |
159 | case idedisk_pm_idle: /* Resume step 1 (idle) complete */ | 159 | case idedisk_pm_restore_pio: /* Resume step 1 complete */ |
160 | pm->pm_step = idedisk_pm_idle; | ||
161 | break; | ||
162 | case idedisk_pm_idle: /* Resume step 2 (idle) complete */ | ||
160 | pm->pm_step = ide_pm_restore_dma; | 163 | pm->pm_step = ide_pm_restore_dma; |
161 | break; | 164 | break; |
162 | } | 165 | } |
@@ -170,8 +173,11 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * | |||
170 | memset(args, 0, sizeof(*args)); | 173 | memset(args, 0, sizeof(*args)); |
171 | 174 | ||
172 | if (drive->media != ide_disk) { | 175 | if (drive->media != ide_disk) { |
173 | /* skip idedisk_pm_idle for ATAPI devices */ | 176 | /* |
174 | if (pm->pm_step == idedisk_pm_idle) | 177 | * skip idedisk_pm_restore_pio and idedisk_pm_idle for ATAPI |
178 | * devices | ||
179 | */ | ||
180 | if (pm->pm_step == idedisk_pm_restore_pio) | ||
175 | pm->pm_step = ide_pm_restore_dma; | 181 | pm->pm_step = ide_pm_restore_dma; |
176 | } | 182 | } |
177 | 183 | ||
@@ -198,13 +204,19 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * | |||
198 | args->handler = &task_no_data_intr; | 204 | args->handler = &task_no_data_intr; |
199 | return do_rw_taskfile(drive, args); | 205 | return do_rw_taskfile(drive, args); |
200 | 206 | ||
201 | case idedisk_pm_idle: /* Resume step 1 (idle) */ | 207 | case idedisk_pm_restore_pio: /* Resume step 1 (restore PIO) */ |
208 | if (drive->hwif->tuneproc != NULL) | ||
209 | drive->hwif->tuneproc(drive, 255); | ||
210 | ide_complete_power_step(drive, rq, 0, 0); | ||
211 | return ide_stopped; | ||
212 | |||
213 | case idedisk_pm_idle: /* Resume step 2 (idle) */ | ||
202 | args->tfRegister[IDE_COMMAND_OFFSET] = WIN_IDLEIMMEDIATE; | 214 | args->tfRegister[IDE_COMMAND_OFFSET] = WIN_IDLEIMMEDIATE; |
203 | args->command_type = IDE_DRIVE_TASK_NO_DATA; | 215 | args->command_type = IDE_DRIVE_TASK_NO_DATA; |
204 | args->handler = task_no_data_intr; | 216 | args->handler = task_no_data_intr; |
205 | return do_rw_taskfile(drive, args); | 217 | return do_rw_taskfile(drive, args); |
206 | 218 | ||
207 | case ide_pm_restore_dma: /* Resume step 2 (restore DMA) */ | 219 | case ide_pm_restore_dma: /* Resume step 3 (restore DMA) */ |
208 | /* | 220 | /* |
209 | * Right now, all we do is call hwif->ide_dma_check(drive), | 221 | * Right now, all we do is call hwif->ide_dma_check(drive), |
210 | * we could be smarter and check for current xfer_speed | 222 | * we could be smarter and check for current xfer_speed |
@@ -1346,6 +1358,10 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) | |||
1346 | * make sure request is sane | 1358 | * make sure request is sane |
1347 | */ | 1359 | */ |
1348 | rq = HWGROUP(drive)->rq; | 1360 | rq = HWGROUP(drive)->rq; |
1361 | |||
1362 | if (!rq) | ||
1363 | goto out; | ||
1364 | |||
1349 | HWGROUP(drive)->rq = NULL; | 1365 | HWGROUP(drive)->rq = NULL; |
1350 | 1366 | ||
1351 | rq->errors = 0; | 1367 | rq->errors = 0; |
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 77703acaec17..badde6331775 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -998,6 +998,7 @@ static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive) | |||
998 | } | 998 | } |
999 | /* done polling */ | 999 | /* done polling */ |
1000 | hwgroup->polling = 0; | 1000 | hwgroup->polling = 0; |
1001 | hwgroup->resetting = 0; | ||
1001 | return ide_stopped; | 1002 | return ide_stopped; |
1002 | } | 1003 | } |
1003 | 1004 | ||
@@ -1057,6 +1058,7 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) | |||
1057 | } | 1058 | } |
1058 | } | 1059 | } |
1059 | hwgroup->polling = 0; /* done polling */ | 1060 | hwgroup->polling = 0; /* done polling */ |
1061 | hwgroup->resetting = 0; /* done reset attempt */ | ||
1060 | return ide_stopped; | 1062 | return ide_stopped; |
1061 | } | 1063 | } |
1062 | 1064 | ||
@@ -1143,6 +1145,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | |||
1143 | 1145 | ||
1144 | /* For an ATAPI device, first try an ATAPI SRST. */ | 1146 | /* For an ATAPI device, first try an ATAPI SRST. */ |
1145 | if (drive->media != ide_disk && !do_not_try_atapi) { | 1147 | if (drive->media != ide_disk && !do_not_try_atapi) { |
1148 | hwgroup->resetting = 1; | ||
1146 | pre_reset(drive); | 1149 | pre_reset(drive); |
1147 | SELECT_DRIVE(drive); | 1150 | SELECT_DRIVE(drive); |
1148 | udelay (20); | 1151 | udelay (20); |
@@ -1168,6 +1171,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | |||
1168 | return ide_stopped; | 1171 | return ide_stopped; |
1169 | } | 1172 | } |
1170 | 1173 | ||
1174 | hwgroup->resetting = 1; | ||
1171 | /* | 1175 | /* |
1172 | * Note that we also set nIEN while resetting the device, | 1176 | * Note that we also set nIEN while resetting the device, |
1173 | * to mask unwanted interrupts from the interface during the reset. | 1177 | * to mask unwanted interrupts from the interface during the reset. |
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 850ef63cc986..8237d89eec6e 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c | |||
@@ -71,75 +71,96 @@ EXPORT_SYMBOL(ide_xfer_verbose); | |||
71 | /** | 71 | /** |
72 | * ide_dma_speed - compute DMA speed | 72 | * ide_dma_speed - compute DMA speed |
73 | * @drive: drive | 73 | * @drive: drive |
74 | * @mode; intended mode | 74 | * @mode: modes available |
75 | * | 75 | * |
76 | * Checks the drive capabilities and returns the speed to use | 76 | * Checks the drive capabilities and returns the speed to use |
77 | * for the transfer. Returns -1 if the requested mode is unknown | 77 | * for the DMA transfer. Returns 0 if the drive is incapable |
78 | * (eg PIO) | 78 | * of DMA transfers. |
79 | */ | 79 | */ |
80 | 80 | ||
81 | u8 ide_dma_speed(ide_drive_t *drive, u8 mode) | 81 | u8 ide_dma_speed(ide_drive_t *drive, u8 mode) |
82 | { | 82 | { |
83 | struct hd_driveid *id = drive->id; | 83 | struct hd_driveid *id = drive->id; |
84 | ide_hwif_t *hwif = HWIF(drive); | 84 | ide_hwif_t *hwif = HWIF(drive); |
85 | u8 ultra_mask, mwdma_mask, swdma_mask; | ||
85 | u8 speed = 0; | 86 | u8 speed = 0; |
86 | 87 | ||
87 | if (drive->media != ide_disk && hwif->atapi_dma == 0) | 88 | if (drive->media != ide_disk && hwif->atapi_dma == 0) |
88 | return 0; | 89 | return 0; |
89 | 90 | ||
90 | switch(mode) { | 91 | /* Capable of UltraDMA modes? */ |
91 | case 0x04: | 92 | ultra_mask = id->dma_ultra & hwif->ultra_mask; |
92 | if ((id->dma_ultra & 0x0040) && | 93 | |
93 | (id->dma_ultra & hwif->ultra_mask)) | 94 | if (!(id->field_valid & 4)) |
94 | { speed = XFER_UDMA_6; break; } | 95 | mode = 0; /* fallback to MW/SW DMA if no UltraDMA */ |
95 | case 0x03: | 96 | |
96 | if ((id->dma_ultra & 0x0020) && | 97 | switch (mode) { |
97 | (id->dma_ultra & hwif->ultra_mask)) | 98 | case 4: |
98 | { speed = XFER_UDMA_5; break; } | 99 | if (ultra_mask & 0x40) { |
99 | case 0x02: | 100 | speed = XFER_UDMA_6; |
100 | if ((id->dma_ultra & 0x0010) && | 101 | break; |
101 | (id->dma_ultra & hwif->ultra_mask)) | 102 | } |
102 | { speed = XFER_UDMA_4; break; } | 103 | case 3: |
103 | if ((id->dma_ultra & 0x0008) && | 104 | if (ultra_mask & 0x20) { |
104 | (id->dma_ultra & hwif->ultra_mask)) | 105 | speed = XFER_UDMA_5; |
105 | { speed = XFER_UDMA_3; break; } | 106 | break; |
106 | case 0x01: | 107 | } |
107 | if ((id->dma_ultra & 0x0004) && | 108 | case 2: |
108 | (id->dma_ultra & hwif->ultra_mask)) | 109 | if (ultra_mask & 0x10) { |
109 | { speed = XFER_UDMA_2; break; } | 110 | speed = XFER_UDMA_4; |
110 | if ((id->dma_ultra & 0x0002) && | 111 | break; |
111 | (id->dma_ultra & hwif->ultra_mask)) | 112 | } |
112 | { speed = XFER_UDMA_1; break; } | 113 | if (ultra_mask & 0x08) { |
113 | if ((id->dma_ultra & 0x0001) && | 114 | speed = XFER_UDMA_3; |
114 | (id->dma_ultra & hwif->ultra_mask)) | 115 | break; |
115 | { speed = XFER_UDMA_0; break; } | 116 | } |
116 | case 0x00: | 117 | case 1: |
117 | if ((id->dma_mword & 0x0004) && | 118 | if (ultra_mask & 0x04) { |
118 | (id->dma_mword & hwif->mwdma_mask)) | 119 | speed = XFER_UDMA_2; |
119 | { speed = XFER_MW_DMA_2; break; } | 120 | break; |
120 | if ((id->dma_mword & 0x0002) && | 121 | } |
121 | (id->dma_mword & hwif->mwdma_mask)) | 122 | if (ultra_mask & 0x02) { |
122 | { speed = XFER_MW_DMA_1; break; } | 123 | speed = XFER_UDMA_1; |
123 | if ((id->dma_mword & 0x0001) && | 124 | break; |
124 | (id->dma_mword & hwif->mwdma_mask)) | 125 | } |
125 | { speed = XFER_MW_DMA_0; break; } | 126 | if (ultra_mask & 0x01) { |
126 | if ((id->dma_1word & 0x0004) && | 127 | speed = XFER_UDMA_0; |
127 | (id->dma_1word & hwif->swdma_mask)) | 128 | break; |
128 | { speed = XFER_SW_DMA_2; break; } | 129 | } |
129 | if ((id->dma_1word & 0x0002) && | 130 | case 0: |
130 | (id->dma_1word & hwif->swdma_mask)) | 131 | mwdma_mask = id->dma_mword & hwif->mwdma_mask; |
131 | { speed = XFER_SW_DMA_1; break; } | ||
132 | if ((id->dma_1word & 0x0001) && | ||
133 | (id->dma_1word & hwif->swdma_mask)) | ||
134 | { speed = XFER_SW_DMA_0; break; } | ||
135 | } | ||
136 | 132 | ||
137 | // printk("%s: %s: mode 0x%02x, speed 0x%02x\n", | 133 | if (mwdma_mask & 0x04) { |
138 | // __FUNCTION__, drive->name, mode, speed); | 134 | speed = XFER_MW_DMA_2; |
135 | break; | ||
136 | } | ||
137 | if (mwdma_mask & 0x02) { | ||
138 | speed = XFER_MW_DMA_1; | ||
139 | break; | ||
140 | } | ||
141 | if (mwdma_mask & 0x01) { | ||
142 | speed = XFER_MW_DMA_0; | ||
143 | break; | ||
144 | } | ||
145 | |||
146 | swdma_mask = id->dma_1word & hwif->swdma_mask; | ||
147 | |||
148 | if (swdma_mask & 0x04) { | ||
149 | speed = XFER_SW_DMA_2; | ||
150 | break; | ||
151 | } | ||
152 | if (swdma_mask & 0x02) { | ||
153 | speed = XFER_SW_DMA_1; | ||
154 | break; | ||
155 | } | ||
156 | if (swdma_mask & 0x01) { | ||
157 | speed = XFER_SW_DMA_0; | ||
158 | break; | ||
159 | } | ||
160 | } | ||
139 | 161 | ||
140 | return speed; | 162 | return speed; |
141 | } | 163 | } |
142 | |||
143 | EXPORT_SYMBOL(ide_dma_speed); | 164 | EXPORT_SYMBOL(ide_dma_speed); |
144 | 165 | ||
145 | 166 | ||
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 9cadf0106c6c..dad9c47ebb69 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -623,6 +623,8 @@ static void hwif_release_dev (struct device *dev) | |||
623 | 623 | ||
624 | static void hwif_register (ide_hwif_t *hwif) | 624 | static void hwif_register (ide_hwif_t *hwif) |
625 | { | 625 | { |
626 | int ret; | ||
627 | |||
626 | /* register with global device tree */ | 628 | /* register with global device tree */ |
627 | strlcpy(hwif->gendev.bus_id,hwif->name,BUS_ID_SIZE); | 629 | strlcpy(hwif->gendev.bus_id,hwif->name,BUS_ID_SIZE); |
628 | hwif->gendev.driver_data = hwif; | 630 | hwif->gendev.driver_data = hwif; |
@@ -634,7 +636,10 @@ static void hwif_register (ide_hwif_t *hwif) | |||
634 | hwif->gendev.parent = NULL; | 636 | hwif->gendev.parent = NULL; |
635 | } | 637 | } |
636 | hwif->gendev.release = hwif_release_dev; | 638 | hwif->gendev.release = hwif_release_dev; |
637 | device_register(&hwif->gendev); | 639 | ret = device_register(&hwif->gendev); |
640 | if (ret < 0) | ||
641 | printk(KERN_WARNING "IDE: %s: device_register error: %d\n", | ||
642 | __FUNCTION__, ret); | ||
638 | } | 643 | } |
639 | 644 | ||
640 | static int wait_hwif_ready(ide_hwif_t *hwif) | 645 | static int wait_hwif_ready(ide_hwif_t *hwif) |
@@ -884,13 +889,19 @@ int probe_hwif_init_with_fixup(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif) | |||
884 | 889 | ||
885 | if (hwif->present) { | 890 | if (hwif->present) { |
886 | u16 unit = 0; | 891 | u16 unit = 0; |
892 | int ret; | ||
893 | |||
887 | for (unit = 0; unit < MAX_DRIVES; ++unit) { | 894 | for (unit = 0; unit < MAX_DRIVES; ++unit) { |
888 | ide_drive_t *drive = &hwif->drives[unit]; | 895 | ide_drive_t *drive = &hwif->drives[unit]; |
889 | /* For now don't attach absent drives, we may | 896 | /* For now don't attach absent drives, we may |
890 | want them on default or a new "empty" class | 897 | want them on default or a new "empty" class |
891 | for hotplug reprobing ? */ | 898 | for hotplug reprobing ? */ |
892 | if (drive->present) { | 899 | if (drive->present) { |
893 | device_register(&drive->gendev); | 900 | ret = device_register(&drive->gendev); |
901 | if (ret < 0) | ||
902 | printk(KERN_WARNING "IDE: %s: " | ||
903 | "device_register error: %d\n", | ||
904 | __FUNCTION__, ret); | ||
894 | } | 905 | } |
895 | } | 906 | } |
896 | } | 907 | } |
@@ -1409,8 +1420,14 @@ int ideprobe_init (void) | |||
1409 | if (hwif->chipset == ide_unknown || hwif->chipset == ide_forced) | 1420 | if (hwif->chipset == ide_unknown || hwif->chipset == ide_forced) |
1410 | hwif->chipset = ide_generic; | 1421 | hwif->chipset = ide_generic; |
1411 | for (unit = 0; unit < MAX_DRIVES; ++unit) | 1422 | for (unit = 0; unit < MAX_DRIVES; ++unit) |
1412 | if (hwif->drives[unit].present) | 1423 | if (hwif->drives[unit].present) { |
1413 | device_register(&hwif->drives[unit].gendev); | 1424 | int ret = device_register( |
1425 | &hwif->drives[unit].gendev); | ||
1426 | if (ret < 0) | ||
1427 | printk(KERN_WARNING "IDE: %s: " | ||
1428 | "device_register error: %d\n", | ||
1429 | __FUNCTION__, ret); | ||
1430 | } | ||
1414 | } | 1431 | } |
1415 | } | 1432 | } |
1416 | return 0; | 1433 | return 0; |
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index 41b74b13a00c..aa049dab3d95 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c | |||
@@ -326,15 +326,24 @@ static int ide_replace_subdriver(ide_drive_t *drive, const char *driver) | |||
326 | { | 326 | { |
327 | struct device *dev = &drive->gendev; | 327 | struct device *dev = &drive->gendev; |
328 | int ret = 1; | 328 | int ret = 1; |
329 | int err; | ||
329 | 330 | ||
330 | down_write(&dev->bus->subsys.rwsem); | 331 | down_write(&dev->bus->subsys.rwsem); |
331 | device_release_driver(dev); | 332 | device_release_driver(dev); |
332 | /* FIXME: device can still be in use by previous driver */ | 333 | /* FIXME: device can still be in use by previous driver */ |
333 | strlcpy(drive->driver_req, driver, sizeof(drive->driver_req)); | 334 | strlcpy(drive->driver_req, driver, sizeof(drive->driver_req)); |
334 | device_attach(dev); | 335 | err = device_attach(dev); |
336 | if (err < 0) | ||
337 | printk(KERN_WARNING "IDE: %s: device_attach error: %d\n", | ||
338 | __FUNCTION__, err); | ||
335 | drive->driver_req[0] = 0; | 339 | drive->driver_req[0] = 0; |
336 | if (dev->driver == NULL) | 340 | if (dev->driver == NULL) { |
337 | device_attach(dev); | 341 | err = device_attach(dev); |
342 | if (err < 0) | ||
343 | printk(KERN_WARNING | ||
344 | "IDE: %s: device_attach(2) error: %d\n", | ||
345 | __FUNCTION__, err); | ||
346 | } | ||
338 | if (dev->driver && !strcmp(dev->driver->name, driver)) | 347 | if (dev->driver && !strcmp(dev->driver->name, driver)) |
339 | ret = 0; | 348 | ret = 0; |
340 | up_write(&dev->bus->subsys.rwsem); | 349 | up_write(&dev->bus->subsys.rwsem); |
@@ -526,7 +535,12 @@ static int proc_print_driver(struct device_driver *drv, void *data) | |||
526 | 535 | ||
527 | static int ide_drivers_show(struct seq_file *s, void *p) | 536 | static int ide_drivers_show(struct seq_file *s, void *p) |
528 | { | 537 | { |
529 | bus_for_each_drv(&ide_bus_type, NULL, s, proc_print_driver); | 538 | int err; |
539 | |||
540 | err = bus_for_each_drv(&ide_bus_type, NULL, s, proc_print_driver); | ||
541 | if (err < 0) | ||
542 | printk(KERN_WARNING "IDE: %s: bus_for_each_drv error: %d\n", | ||
543 | __FUNCTION__, err); | ||
530 | return 0; | 544 | return 0; |
531 | } | 545 | } |
532 | 546 | ||
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 2b1a1389c318..287a66201150 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
@@ -450,7 +450,7 @@ void ide_hwif_release_regions(ide_hwif_t *hwif) | |||
450 | * @hwif: hwif to update | 450 | * @hwif: hwif to update |
451 | * @tmp_hwif: template | 451 | * @tmp_hwif: template |
452 | * | 452 | * |
453 | * Restore hwif to a previous state by copying most settngs | 453 | * Restore hwif to a previous state by copying most settings |
454 | * from the template. | 454 | * from the template. |
455 | */ | 455 | */ |
456 | 456 | ||
@@ -539,9 +539,10 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) | |||
539 | hwif->dma_vendor3 = tmp_hwif->dma_vendor3; | 539 | hwif->dma_vendor3 = tmp_hwif->dma_vendor3; |
540 | hwif->dma_prdtable = tmp_hwif->dma_prdtable; | 540 | hwif->dma_prdtable = tmp_hwif->dma_prdtable; |
541 | 541 | ||
542 | hwif->dma_extra = tmp_hwif->dma_extra; | ||
543 | hwif->config_data = tmp_hwif->config_data; | 542 | hwif->config_data = tmp_hwif->config_data; |
544 | hwif->select_data = tmp_hwif->select_data; | 543 | hwif->select_data = tmp_hwif->select_data; |
544 | hwif->extra_base = tmp_hwif->extra_base; | ||
545 | hwif->extra_ports = tmp_hwif->extra_ports; | ||
545 | hwif->autodma = tmp_hwif->autodma; | 546 | hwif->autodma = tmp_hwif->autodma; |
546 | hwif->udma_four = tmp_hwif->udma_four; | 547 | hwif->udma_four = tmp_hwif->udma_four; |
547 | hwif->no_dsc = tmp_hwif->no_dsc; | 548 | hwif->no_dsc = tmp_hwif->no_dsc; |
@@ -550,7 +551,7 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) | |||
550 | } | 551 | } |
551 | 552 | ||
552 | /** | 553 | /** |
553 | * ide_unregister - free an ide interface | 554 | * ide_unregister - free an IDE interface |
554 | * @index: index of interface (will change soon to a pointer) | 555 | * @index: index of interface (will change soon to a pointer) |
555 | * | 556 | * |
556 | * Perform the final unregister of an IDE interface. At the moment | 557 | * Perform the final unregister of an IDE interface. At the moment |
@@ -563,8 +564,8 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) | |||
563 | * deadlocking the IDE layer. The shutdown callback is called | 564 | * deadlocking the IDE layer. The shutdown callback is called |
564 | * before we take the lock and free resources. It is up to the | 565 | * before we take the lock and free resources. It is up to the |
565 | * caller to be sure there is no pending I/O here, and that | 566 | * caller to be sure there is no pending I/O here, and that |
566 | * the interfce will not be reopened (present/vanishing locking | 567 | * the interface will not be reopened (present/vanishing locking |
567 | * isnt yet done btw). After we commit to the final kill we | 568 | * isn't yet done BTW). After we commit to the final kill we |
568 | * call the cleanup callback with the ide locks held. | 569 | * call the cleanup callback with the ide locks held. |
569 | * | 570 | * |
570 | * Unregister restores the hwif structures to the default state. | 571 | * Unregister restores the hwif structures to the default state. |
@@ -674,6 +675,9 @@ void ide_unregister(unsigned int index) | |||
674 | hwif->dma_status = 0; | 675 | hwif->dma_status = 0; |
675 | hwif->dma_vendor3 = 0; | 676 | hwif->dma_vendor3 = 0; |
676 | hwif->dma_prdtable = 0; | 677 | hwif->dma_prdtable = 0; |
678 | |||
679 | hwif->extra_base = 0; | ||
680 | hwif->extra_ports = 0; | ||
677 | } | 681 | } |
678 | 682 | ||
679 | /* copy original settings */ | 683 | /* copy original settings */ |
@@ -1360,6 +1364,11 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device | |||
1360 | 1364 | ||
1361 | spin_lock_irqsave(&ide_lock, flags); | 1365 | spin_lock_irqsave(&ide_lock, flags); |
1362 | 1366 | ||
1367 | if (HWGROUP(drive)->resetting) { | ||
1368 | spin_unlock_irqrestore(&ide_lock, flags); | ||
1369 | return -EBUSY; | ||
1370 | } | ||
1371 | |||
1363 | ide_abort(drive, "drive reset"); | 1372 | ide_abort(drive, "drive reset"); |
1364 | 1373 | ||
1365 | BUG_ON(HWGROUP(drive)->handler); | 1374 | BUG_ON(HWGROUP(drive)->handler); |
@@ -1993,10 +2002,16 @@ EXPORT_SYMBOL_GPL(ide_bus_type); | |||
1993 | */ | 2002 | */ |
1994 | static int __init ide_init(void) | 2003 | static int __init ide_init(void) |
1995 | { | 2004 | { |
2005 | int ret; | ||
2006 | |||
1996 | printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n"); | 2007 | printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n"); |
1997 | system_bus_speed = ide_system_bus_speed(); | 2008 | system_bus_speed = ide_system_bus_speed(); |
1998 | 2009 | ||
1999 | bus_register(&ide_bus_type); | 2010 | ret = bus_register(&ide_bus_type); |
2011 | if (ret < 0) { | ||
2012 | printk(KERN_WARNING "IDE: bus_register error: %d\n", ret); | ||
2013 | return ret; | ||
2014 | } | ||
2000 | 2015 | ||
2001 | init_ide_data(); | 2016 | init_ide_data(); |
2002 | 2017 | ||
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index 602797a44208..bef4759f70e5 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c | |||
@@ -120,7 +120,7 @@ static int ide_probe(struct pcmcia_device *link) | |||
120 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | 120 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; |
121 | link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; | 121 | link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; |
122 | link->io.IOAddrLines = 3; | 122 | link->io.IOAddrLines = 3; |
123 | link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; | 123 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; |
124 | link->irq.IRQInfo1 = IRQ_LEVEL_ID; | 124 | link->irq.IRQInfo1 = IRQ_LEVEL_ID; |
125 | link->conf.Attributes = CONF_ENABLE_IRQ; | 125 | link->conf.Attributes = CONF_ENABLE_IRQ; |
126 | link->conf.IntType = INT_MEMORY_AND_IO; | 126 | link->conf.IntType = INT_MEMORY_AND_IO; |
@@ -398,12 +398,17 @@ static struct pcmcia_device_id ide_ids[] = { | |||
398 | PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149), | 398 | PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149), |
399 | PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674), | 399 | PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674), |
400 | PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2 ", 0xe37be2b5, 0x8671043b), | 400 | PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2 ", 0xe37be2b5, 0x8671043b), |
401 | PCMCIA_DEVICE_PROD_ID12("M-Systems", "CF500", 0x7ed2ad87, 0x7a13045c), | ||
401 | PCMCIA_DEVICE_PROD_ID2("NinjaATA-", 0xebe0bd79), | 402 | PCMCIA_DEVICE_PROD_ID2("NinjaATA-", 0xebe0bd79), |
402 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591), | 403 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591), |
403 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728), | 404 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728), |
404 | PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1), | 405 | PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1), |
406 | PCMCIA_DEVICE_PROD_ID12("SEAGATE", "ST1", 0x87c1b330, 0xe1f30883), | ||
407 | PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "04/05/06", 0x43d74cb4, 0x6a22777d), | ||
408 | PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6), | ||
405 | PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), | 409 | PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), |
406 | PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443), | 410 | PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443), |
411 | PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8), | ||
407 | PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), | 412 | PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), |
408 | PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), | 413 | PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), |
409 | PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e), | 414 | PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e), |
diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile index f35d684edc25..640a54b09b5a 100644 --- a/drivers/ide/pci/Makefile +++ b/drivers/ide/pci/Makefile | |||
@@ -14,6 +14,7 @@ obj-$(CONFIG_BLK_DEV_HPT366) += hpt366.o | |||
14 | #obj-$(CONFIG_BLK_DEV_HPT37X) += hpt37x.o | 14 | #obj-$(CONFIG_BLK_DEV_HPT37X) += hpt37x.o |
15 | obj-$(CONFIG_BLK_DEV_IT8172) += it8172.o | 15 | obj-$(CONFIG_BLK_DEV_IT8172) += it8172.o |
16 | obj-$(CONFIG_BLK_DEV_IT821X) += it821x.o | 16 | obj-$(CONFIG_BLK_DEV_IT821X) += it821x.o |
17 | obj-$(CONFIG_BLK_DEV_JMICRON) += jmicron.o | ||
17 | obj-$(CONFIG_BLK_DEV_NS87415) += ns87415.o | 18 | obj-$(CONFIG_BLK_DEV_NS87415) += ns87415.o |
18 | obj-$(CONFIG_BLK_DEV_OPTI621) += opti621.o | 19 | obj-$(CONFIG_BLK_DEV_OPTI621) += opti621.o |
19 | obj-$(CONFIG_BLK_DEV_PDC202XX_OLD) += pdc202xx_old.o | 20 | obj-$(CONFIG_BLK_DEV_PDC202XX_OLD) += pdc202xx_old.o |
diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c index 380bb28c7c54..ae405fa32236 100644 --- a/drivers/ide/pci/cs5530.c +++ b/drivers/ide/pci/cs5530.c | |||
@@ -222,23 +222,23 @@ static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const ch | |||
222 | unsigned long flags; | 222 | unsigned long flags; |
223 | 223 | ||
224 | dev = NULL; | 224 | dev = NULL; |
225 | while ((dev = pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) { | 225 | while ((dev = pci_get_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) { |
226 | switch (dev->device) { | 226 | switch (dev->device) { |
227 | case PCI_DEVICE_ID_CYRIX_PCI_MASTER: | 227 | case PCI_DEVICE_ID_CYRIX_PCI_MASTER: |
228 | master_0 = dev; | 228 | master_0 = pci_dev_get(dev); |
229 | break; | 229 | break; |
230 | case PCI_DEVICE_ID_CYRIX_5530_LEGACY: | 230 | case PCI_DEVICE_ID_CYRIX_5530_LEGACY: |
231 | cs5530_0 = dev; | 231 | cs5530_0 = pci_dev_get(dev); |
232 | break; | 232 | break; |
233 | } | 233 | } |
234 | } | 234 | } |
235 | if (!master_0) { | 235 | if (!master_0) { |
236 | printk(KERN_ERR "%s: unable to locate PCI MASTER function\n", name); | 236 | printk(KERN_ERR "%s: unable to locate PCI MASTER function\n", name); |
237 | return 0; | 237 | goto out; |
238 | } | 238 | } |
239 | if (!cs5530_0) { | 239 | if (!cs5530_0) { |
240 | printk(KERN_ERR "%s: unable to locate CS5530 LEGACY function\n", name); | 240 | printk(KERN_ERR "%s: unable to locate CS5530 LEGACY function\n", name); |
241 | return 0; | 241 | goto out; |
242 | } | 242 | } |
243 | 243 | ||
244 | spin_lock_irqsave(&ide_lock, flags); | 244 | spin_lock_irqsave(&ide_lock, flags); |
@@ -296,6 +296,9 @@ static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const ch | |||
296 | 296 | ||
297 | spin_unlock_irqrestore(&ide_lock, flags); | 297 | spin_unlock_irqrestore(&ide_lock, flags); |
298 | 298 | ||
299 | out: | ||
300 | pci_dev_put(master_0); | ||
301 | pci_dev_put(cs5530_0); | ||
299 | return 0; | 302 | return 0; |
300 | } | 303 | } |
301 | 304 | ||
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c index 120929fbe7a3..64330c459bd4 100644 --- a/drivers/ide/pci/cy82c693.c +++ b/drivers/ide/pci/cy82c693.c | |||
@@ -281,7 +281,7 @@ static void cy82c693_tune_drive (ide_drive_t *drive, u8 pio) | |||
281 | 281 | ||
282 | /* select primary or secondary channel */ | 282 | /* select primary or secondary channel */ |
283 | if (hwif->index > 0) { /* drive is on the secondary channel */ | 283 | if (hwif->index > 0) { /* drive is on the secondary channel */ |
284 | dev = pci_find_slot(dev->bus->number, dev->devfn+1); | 284 | dev = pci_get_slot(dev->bus, dev->devfn+1); |
285 | if (!dev) { | 285 | if (!dev) { |
286 | printk(KERN_ERR "%s: tune_drive: " | 286 | printk(KERN_ERR "%s: tune_drive: " |
287 | "Cannot find secondary interface!\n", | 287 | "Cannot find secondary interface!\n", |
@@ -500,8 +500,9 @@ static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_dev | |||
500 | Function 1 is primary IDE channel, function 2 - secondary. */ | 500 | Function 1 is primary IDE channel, function 2 - secondary. */ |
501 | if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && | 501 | if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && |
502 | PCI_FUNC(dev->devfn) == 1) { | 502 | PCI_FUNC(dev->devfn) == 1) { |
503 | dev2 = pci_find_slot(dev->bus->number, dev->devfn + 1); | 503 | dev2 = pci_get_slot(dev->bus, dev->devfn + 1); |
504 | ret = ide_setup_pci_devices(dev, dev2, d); | 504 | ret = ide_setup_pci_devices(dev, dev2, d); |
505 | /* We leak pci refs here but thats ok - we can't be unloaded */ | ||
505 | } | 506 | } |
506 | return ret; | 507 | return ret; |
507 | } | 508 | } |
diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c index 78810ba982e9..0cb7b9b520ea 100644 --- a/drivers/ide/pci/generic.c +++ b/drivers/ide/pci/generic.c | |||
@@ -41,15 +41,8 @@ | |||
41 | 41 | ||
42 | static int ide_generic_all; /* Set to claim all devices */ | 42 | static int ide_generic_all; /* Set to claim all devices */ |
43 | 43 | ||
44 | #ifndef MODULE | 44 | module_param_named(all_generic_ide, ide_generic_all, bool, 0444); |
45 | static int __init ide_generic_all_on(char *unused) | 45 | MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers."); |
46 | { | ||
47 | ide_generic_all = 1; | ||
48 | printk(KERN_INFO "IDE generic will claim all unknown PCI IDE storage controllers.\n"); | ||
49 | return 1; | ||
50 | } | ||
51 | __setup("all-generic-ide", ide_generic_all_on); | ||
52 | #endif | ||
53 | 46 | ||
54 | static void __devinit init_hwif_generic (ide_hwif_t *hwif) | 47 | static void __devinit init_hwif_generic (ide_hwif_t *hwif) |
55 | { | 48 | { |
diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c new file mode 100644 index 000000000000..68c74bbf8b06 --- /dev/null +++ b/drivers/ide/pci/jmicron.c | |||
@@ -0,0 +1,269 @@ | |||
1 | |||
2 | /* | ||
3 | * Copyright (C) 2006 Red Hat <alan@redhat.com> | ||
4 | * | ||
5 | * May be copied or modified under the terms of the GNU General Public License | ||
6 | */ | ||
7 | |||
8 | #include <linux/config.h> | ||
9 | #include <linux/types.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/pci.h> | ||
12 | #include <linux/delay.h> | ||
13 | #include <linux/hdreg.h> | ||
14 | #include <linux/ide.h> | ||
15 | #include <linux/init.h> | ||
16 | |||
17 | #include <asm/io.h> | ||
18 | |||
19 | typedef enum { | ||
20 | PORT_PATA0 = 0, | ||
21 | PORT_PATA1 = 1, | ||
22 | PORT_SATA = 2, | ||
23 | } port_type; | ||
24 | |||
25 | /** | ||
26 | * jmicron_ratemask - Compute available modes | ||
27 | * @drive: IDE drive | ||
28 | * | ||
29 | * Compute the available speeds for the devices on the interface. This | ||
30 | * is all modes to ATA133 clipped by drive cable setup. | ||
31 | */ | ||
32 | |||
33 | static u8 jmicron_ratemask(ide_drive_t *drive) | ||
34 | { | ||
35 | u8 mode = 4; | ||
36 | if (!eighty_ninty_three(drive)) | ||
37 | mode = min(mode, (u8)1); | ||
38 | return mode; | ||
39 | } | ||
40 | |||
41 | /** | ||
42 | * ata66_jmicron - Cable check | ||
43 | * @hwif: IDE port | ||
44 | * | ||
45 | * Return 1 if the cable is 80pin | ||
46 | */ | ||
47 | |||
48 | static int __devinit ata66_jmicron(ide_hwif_t *hwif) | ||
49 | { | ||
50 | struct pci_dev *pdev = hwif->pci_dev; | ||
51 | |||
52 | u32 control; | ||
53 | u32 control5; | ||
54 | |||
55 | int port = hwif->channel; | ||
56 | port_type port_map[2]; | ||
57 | |||
58 | pci_read_config_dword(pdev, 0x40, &control); | ||
59 | |||
60 | /* There are two basic mappings. One has the two SATA ports merged | ||
61 | as master/slave and the secondary as PATA, the other has only the | ||
62 | SATA port mapped */ | ||
63 | if (control & (1 << 23)) { | ||
64 | port_map[0] = PORT_SATA; | ||
65 | port_map[1] = PORT_PATA0; | ||
66 | } else { | ||
67 | port_map[0] = PORT_SATA; | ||
68 | port_map[1] = PORT_SATA; | ||
69 | } | ||
70 | |||
71 | /* The 365/366 may have this bit set to map the second PATA port | ||
72 | as the internal primary channel */ | ||
73 | pci_read_config_dword(pdev, 0x80, &control5); | ||
74 | if (control5 & (1<<24)) | ||
75 | port_map[0] = PORT_PATA1; | ||
76 | |||
77 | /* The two ports may then be logically swapped by the firmware */ | ||
78 | if (control & (1 << 22)) | ||
79 | port = port ^ 1; | ||
80 | |||
81 | /* | ||
82 | * Now we know which physical port we are talking about we can | ||
83 | * actually do our cable checking etc. Thankfully we don't need | ||
84 | * to do the plumbing for other cases. | ||
85 | */ | ||
86 | switch (port_map[port]) | ||
87 | { | ||
88 | case PORT_PATA0: | ||
89 | if (control & (1 << 3)) /* 40/80 pin primary */ | ||
90 | return 1; | ||
91 | return 0; | ||
92 | case PORT_PATA1: | ||
93 | if (control5 & (1 << 19)) /* 40/80 pin secondary */ | ||
94 | return 0; | ||
95 | return 1; | ||
96 | case PORT_SATA: | ||
97 | return 1; | ||
98 | } | ||
99 | } | ||
100 | |||
101 | static void jmicron_tuneproc (ide_drive_t *drive, byte mode_wanted) | ||
102 | { | ||
103 | return; | ||
104 | } | ||
105 | |||
106 | /** | ||
107 | * config_jmicron_chipset_for_pio - set drive timings | ||
108 | * @drive: drive to tune | ||
109 | * @speed we want | ||
110 | * | ||
111 | */ | ||
112 | |||
113 | static void config_jmicron_chipset_for_pio (ide_drive_t *drive, byte set_speed) | ||
114 | { | ||
115 | u8 speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL); | ||
116 | if (set_speed) | ||
117 | (void) ide_config_drive_speed(drive, speed); | ||
118 | } | ||
119 | |||
120 | /** | ||
121 | * jmicron_tune_chipset - set controller timings | ||
122 | * @drive: Drive to set up | ||
123 | * @xferspeed: speed we want to achieve | ||
124 | * | ||
125 | * As the JMicron snoops for timings all we actually need to do is | ||
126 | * make sure we don't set an invalid mode. We do need to honour | ||
127 | * the cable detect here. | ||
128 | */ | ||
129 | |||
130 | static int jmicron_tune_chipset (ide_drive_t *drive, byte xferspeed) | ||
131 | { | ||
132 | |||
133 | u8 speed = ide_rate_filter(jmicron_ratemask(drive), xferspeed); | ||
134 | |||
135 | return ide_config_drive_speed(drive, speed); | ||
136 | } | ||
137 | |||
138 | /** | ||
139 | * config_chipset_for_dma - configure for DMA | ||
140 | * @drive: drive to configure | ||
141 | * | ||
142 | * As the JMicron snoops for timings all we actually need to do is | ||
143 | * make sure we don't set an invalid mode. | ||
144 | */ | ||
145 | |||
146 | static int config_chipset_for_dma (ide_drive_t *drive) | ||
147 | { | ||
148 | u8 speed = ide_dma_speed(drive, jmicron_ratemask(drive)); | ||
149 | |||
150 | config_jmicron_chipset_for_pio(drive, !speed); | ||
151 | jmicron_tune_chipset(drive, speed); | ||
152 | return ide_dma_enable(drive); | ||
153 | } | ||
154 | |||
155 | /** | ||
156 | * jmicron_configure_drive_for_dma - set up for DMA transfers | ||
157 | * @drive: drive we are going to set up | ||
158 | * | ||
159 | * As the JMicron snoops for timings all we actually need to do is | ||
160 | * make sure we don't set an invalid mode. | ||
161 | */ | ||
162 | |||
163 | static int jmicron_config_drive_for_dma (ide_drive_t *drive) | ||
164 | { | ||
165 | ide_hwif_t *hwif = drive->hwif; | ||
166 | |||
167 | if (ide_use_dma(drive)) { | ||
168 | if (config_chipset_for_dma(drive)) | ||
169 | return hwif->ide_dma_on(drive); | ||
170 | } | ||
171 | config_jmicron_chipset_for_pio(drive, 1); | ||
172 | return hwif->ide_dma_off_quietly(drive); | ||
173 | } | ||
174 | |||
175 | /** | ||
176 | * init_hwif_jmicron - set up hwif structs | ||
177 | * @hwif: interface to set up | ||
178 | * | ||
179 | * Minimal set up is required for the Jmicron hardware. | ||
180 | */ | ||
181 | |||
182 | static void __devinit init_hwif_jmicron(ide_hwif_t *hwif) | ||
183 | { | ||
184 | hwif->speedproc = &jmicron_tune_chipset; | ||
185 | hwif->tuneproc = &jmicron_tuneproc; | ||
186 | |||
187 | hwif->drives[0].autotune = 1; | ||
188 | hwif->drives[1].autotune = 1; | ||
189 | |||
190 | if (!hwif->dma_base) | ||
191 | goto fallback; | ||
192 | |||
193 | hwif->atapi_dma = 1; | ||
194 | hwif->ultra_mask = 0x7f; | ||
195 | hwif->mwdma_mask = 0x07; | ||
196 | |||
197 | hwif->ide_dma_check = &jmicron_config_drive_for_dma; | ||
198 | if (!(hwif->udma_four)) | ||
199 | hwif->udma_four = ata66_jmicron(hwif); | ||
200 | |||
201 | hwif->autodma = 1; | ||
202 | hwif->drives[0].autodma = hwif->autodma; | ||
203 | hwif->drives[1].autodma = hwif->autodma; | ||
204 | return; | ||
205 | fallback: | ||
206 | hwif->autodma = 0; | ||
207 | return; | ||
208 | } | ||
209 | |||
210 | #define DECLARE_JMB_DEV(name_str) \ | ||
211 | { \ | ||
212 | .name = name_str, \ | ||
213 | .init_hwif = init_hwif_jmicron, \ | ||
214 | .channels = 2, \ | ||
215 | .autodma = AUTODMA, \ | ||
216 | .bootable = ON_BOARD, \ | ||
217 | .enablebits = { {0x40, 1, 1}, {0x40, 0x10, 0x10} }, \ | ||
218 | } | ||
219 | |||
220 | static ide_pci_device_t jmicron_chipsets[] __devinitdata = { | ||
221 | /* 0 */ DECLARE_JMB_DEV("JMB361"), | ||
222 | /* 1 */ DECLARE_JMB_DEV("JMB363"), | ||
223 | /* 2 */ DECLARE_JMB_DEV("JMB365"), | ||
224 | /* 3 */ DECLARE_JMB_DEV("JMB366"), | ||
225 | /* 4 */ DECLARE_JMB_DEV("JMB368"), | ||
226 | }; | ||
227 | |||
228 | /** | ||
229 | * jmicron_init_one - pci layer discovery entry | ||
230 | * @dev: PCI device | ||
231 | * @id: ident table entry | ||
232 | * | ||
233 | * Called by the PCI code when it finds a Jmicron controller. | ||
234 | * We then use the IDE PCI generic helper to do most of the work. | ||
235 | */ | ||
236 | |||
237 | static int __devinit jmicron_init_one(struct pci_dev *dev, const struct pci_device_id *id) | ||
238 | { | ||
239 | ide_setup_pci_device(dev, &jmicron_chipsets[id->driver_data]); | ||
240 | return 0; | ||
241 | } | ||
242 | |||
243 | static struct pci_device_id jmicron_pci_tbl[] = { | ||
244 | { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361), 0}, | ||
245 | { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363), 1}, | ||
246 | { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365), 2}, | ||
247 | { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366), 3}, | ||
248 | { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368), 4}, | ||
249 | { 0, }, | ||
250 | }; | ||
251 | |||
252 | MODULE_DEVICE_TABLE(pci, jmicron_pci_tbl); | ||
253 | |||
254 | static struct pci_driver driver = { | ||
255 | .name = "JMicron IDE", | ||
256 | .id_table = jmicron_pci_tbl, | ||
257 | .probe = jmicron_init_one, | ||
258 | }; | ||
259 | |||
260 | static int __init jmicron_ide_init(void) | ||
261 | { | ||
262 | return ide_pci_register_driver(&driver); | ||
263 | } | ||
264 | |||
265 | module_init(jmicron_ide_init); | ||
266 | |||
267 | MODULE_AUTHOR("Alan Cox"); | ||
268 | MODULE_DESCRIPTION("PCI driver module for the JMicron in legacy modes"); | ||
269 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c index b46022a11bef..184cdacddeb6 100644 --- a/drivers/ide/pci/pdc202xx_old.c +++ b/drivers/ide/pci/pdc202xx_old.c | |||
@@ -154,7 +154,8 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed) | |||
154 | u8 AP, BP, CP, DP; | 154 | u8 AP, BP, CP, DP; |
155 | u8 TA = 0, TB = 0, TC = 0; | 155 | u8 TA = 0, TB = 0, TC = 0; |
156 | 156 | ||
157 | if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0)) | 157 | if (drive->media != ide_disk && |
158 | drive->media != ide_cdrom && speed < XFER_SW_DMA_0) | ||
158 | return -1; | 159 | return -1; |
159 | 160 | ||
160 | pci_read_config_dword(dev, drive_pci, &drive_conf); | 161 | pci_read_config_dword(dev, drive_pci, &drive_conf); |
@@ -330,14 +331,12 @@ static int config_chipset_for_dma (ide_drive_t *drive) | |||
330 | 331 | ||
331 | chipset_is_set: | 332 | chipset_is_set: |
332 | 333 | ||
333 | if (drive->media == ide_disk) { | 334 | pci_read_config_byte(dev, (drive_pci), &AP); |
334 | pci_read_config_byte(dev, (drive_pci), &AP); | 335 | if (id->capability & 4) /* IORDY_EN */ |
335 | if (id->capability & 4) /* IORDY_EN */ | 336 | pci_write_config_byte(dev, (drive_pci), AP|IORDY_EN); |
336 | pci_write_config_byte(dev, (drive_pci), AP|IORDY_EN); | 337 | pci_read_config_byte(dev, (drive_pci), &AP); |
337 | pci_read_config_byte(dev, (drive_pci), &AP); | 338 | if (drive->media == ide_disk) /* PREFETCH_EN */ |
338 | if (drive->media == ide_disk) /* PREFETCH_EN */ | 339 | pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN); |
339 | pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN); | ||
340 | } | ||
341 | 340 | ||
342 | speed = ide_dma_speed(drive, pdc202xx_ratemask(drive)); | 341 | speed = ide_dma_speed(drive, pdc202xx_ratemask(drive)); |
343 | 342 | ||
@@ -385,7 +384,7 @@ static void pdc202xx_old_ide_dma_start(ide_drive_t *drive) | |||
385 | { | 384 | { |
386 | if (drive->current_speed > XFER_UDMA_2) | 385 | if (drive->current_speed > XFER_UDMA_2) |
387 | pdc_old_enable_66MHz_clock(drive->hwif); | 386 | pdc_old_enable_66MHz_clock(drive->hwif); |
388 | if (drive->addressing == 1) { | 387 | if (drive->media != ide_disk || drive->addressing == 1) { |
389 | struct request *rq = HWGROUP(drive)->rq; | 388 | struct request *rq = HWGROUP(drive)->rq; |
390 | ide_hwif_t *hwif = HWIF(drive); | 389 | ide_hwif_t *hwif = HWIF(drive); |
391 | unsigned long high_16 = hwif->dma_master; | 390 | unsigned long high_16 = hwif->dma_master; |
@@ -405,7 +404,7 @@ static void pdc202xx_old_ide_dma_start(ide_drive_t *drive) | |||
405 | 404 | ||
406 | static int pdc202xx_old_ide_dma_end(ide_drive_t *drive) | 405 | static int pdc202xx_old_ide_dma_end(ide_drive_t *drive) |
407 | { | 406 | { |
408 | if (drive->addressing == 1) { | 407 | if (drive->media != ide_disk || drive->addressing == 1) { |
409 | ide_hwif_t *hwif = HWIF(drive); | 408 | ide_hwif_t *hwif = HWIF(drive); |
410 | unsigned long high_16 = hwif->dma_master; | 409 | unsigned long high_16 = hwif->dma_master; |
411 | unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20); | 410 | unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20); |
@@ -519,6 +518,7 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif) | |||
519 | hwif->ultra_mask = 0x3f; | 518 | hwif->ultra_mask = 0x3f; |
520 | hwif->mwdma_mask = 0x07; | 519 | hwif->mwdma_mask = 0x07; |
521 | hwif->swdma_mask = 0x07; | 520 | hwif->swdma_mask = 0x07; |
521 | hwif->atapi_dma = 1; | ||
522 | 522 | ||
523 | hwif->err_stops_fifo = 1; | 523 | hwif->err_stops_fifo = 1; |
524 | 524 | ||
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c index eb5bab1890cd..cdc3aab9ebcb 100644 --- a/drivers/ide/pci/piix.c +++ b/drivers/ide/pci/piix.c | |||
@@ -222,13 +222,15 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio) | |||
222 | u16 master_data; | 222 | u16 master_data; |
223 | u8 slave_data; | 223 | u8 slave_data; |
224 | static DEFINE_SPINLOCK(tune_lock); | 224 | static DEFINE_SPINLOCK(tune_lock); |
225 | int control = 0; | ||
225 | 226 | ||
226 | /* ISP RTC */ | 227 | /* ISP RTC */ |
227 | u8 timings[][2] = { { 0, 0 }, | 228 | static const u8 timings[][2]= { |
228 | { 0, 0 }, | 229 | { 0, 0 }, |
229 | { 1, 0 }, | 230 | { 0, 0 }, |
230 | { 2, 1 }, | 231 | { 1, 0 }, |
231 | { 2, 3 }, }; | 232 | { 2, 1 }, |
233 | { 2, 3 }, }; | ||
232 | 234 | ||
233 | pio = ide_get_best_pio_mode(drive, pio, 5, NULL); | 235 | pio = ide_get_best_pio_mode(drive, pio, 5, NULL); |
234 | 236 | ||
@@ -239,19 +241,30 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio) | |||
239 | */ | 241 | */ |
240 | spin_lock_irqsave(&tune_lock, flags); | 242 | spin_lock_irqsave(&tune_lock, flags); |
241 | pci_read_config_word(dev, master_port, &master_data); | 243 | pci_read_config_word(dev, master_port, &master_data); |
244 | |||
245 | if (pio >= 2) | ||
246 | control |= 1; /* Programmable timing on */ | ||
247 | if (drive->media == ide_disk) | ||
248 | control |= 4; /* Prefetch, post write */ | ||
249 | if (pio >= 3) | ||
250 | control |= 2; /* IORDY */ | ||
242 | if (is_slave) { | 251 | if (is_slave) { |
243 | master_data = master_data | 0x4000; | 252 | master_data = master_data | 0x4000; |
244 | if (pio > 1) | 253 | if (pio > 1) { |
245 | /* enable PPE, IE and TIME */ | 254 | /* enable PPE, IE and TIME */ |
246 | master_data = master_data | 0x0070; | 255 | master_data = master_data | (control << 4); |
256 | } else { | ||
257 | master_data &= ~0x0070; | ||
258 | } | ||
247 | pci_read_config_byte(dev, slave_port, &slave_data); | 259 | pci_read_config_byte(dev, slave_port, &slave_data); |
248 | slave_data = slave_data & (hwif->channel ? 0x0f : 0xf0); | 260 | slave_data = slave_data & (hwif->channel ? 0x0f : 0xf0); |
249 | slave_data = slave_data | (((timings[pio][0] << 2) | timings[pio][1]) << (hwif->channel ? 4 : 0)); | 261 | slave_data = slave_data | (((timings[pio][0] << 2) | timings[pio][1]) << (hwif->channel ? 4 : 0)); |
250 | } else { | 262 | } else { |
251 | master_data = master_data & 0xccf8; | 263 | master_data = master_data & 0xccf8; |
252 | if (pio > 1) | 264 | if (pio > 1) { |
253 | /* enable PPE, IE and TIME */ | 265 | /* enable PPE, IE and TIME */ |
254 | master_data = master_data | 0x0007; | 266 | master_data = master_data | control; |
267 | } | ||
255 | master_data = master_data | (timings[pio][0] << 12) | (timings[pio][1] << 8); | 268 | master_data = master_data | (timings[pio][0] << 12) | (timings[pio][1] << 8); |
256 | } | 269 | } |
257 | pci_write_config_word(dev, master_port, master_data); | 270 | pci_write_config_word(dev, master_port, master_data); |
diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c index fc2b5496b6d2..ff80937d94dd 100644 --- a/drivers/ide/pci/sc1200.c +++ b/drivers/ide/pci/sc1200.c | |||
@@ -323,6 +323,7 @@ static void sc1200_tuneproc (ide_drive_t *drive, byte pio) /* mode=255 means "au | |||
323 | } | 323 | } |
324 | } | 324 | } |
325 | 325 | ||
326 | #ifdef CONFIG_PM | ||
326 | static ide_hwif_t *lookup_pci_dev (ide_hwif_t *prev, struct pci_dev *dev) | 327 | static ide_hwif_t *lookup_pci_dev (ide_hwif_t *prev, struct pci_dev *dev) |
327 | { | 328 | { |
328 | int h; | 329 | int h; |
@@ -451,6 +452,7 @@ static int sc1200_resume (struct pci_dev *dev) | |||
451 | } | 452 | } |
452 | return 0; | 453 | return 0; |
453 | } | 454 | } |
455 | #endif | ||
454 | 456 | ||
455 | /* | 457 | /* |
456 | * This gets invoked by the IDE driver once for each channel, | 458 | * This gets invoked by the IDE driver once for each channel, |
@@ -499,8 +501,10 @@ static struct pci_driver driver = { | |||
499 | .name = "SC1200_IDE", | 501 | .name = "SC1200_IDE", |
500 | .id_table = sc1200_pci_tbl, | 502 | .id_table = sc1200_pci_tbl, |
501 | .probe = sc1200_init_one, | 503 | .probe = sc1200_init_one, |
504 | #ifdef CONFIG_PM | ||
502 | .suspend = sc1200_suspend, | 505 | .suspend = sc1200_suspend, |
503 | .resume = sc1200_resume, | 506 | .resume = sc1200_resume, |
507 | #endif | ||
504 | }; | 508 | }; |
505 | 509 | ||
506 | static int sc1200_ide_init(void) | 510 | static int sc1200_ide_init(void) |
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index d8a0d87df734..f3fe287fbd89 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c | |||
@@ -220,7 +220,7 @@ sgiioc4_ide_dma_end(ide_drive_t * drive) | |||
220 | ide_hwif_t *hwif = HWIF(drive); | 220 | ide_hwif_t *hwif = HWIF(drive); |
221 | u64 dma_base = hwif->dma_base; | 221 | u64 dma_base = hwif->dma_base; |
222 | int dma_stat = 0; | 222 | int dma_stat = 0; |
223 | unsigned long *ending_dma = (unsigned long *) hwif->dma_base2; | 223 | unsigned long *ending_dma = ide_get_hwifdata(hwif); |
224 | 224 | ||
225 | hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4); | 225 | hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4); |
226 | 226 | ||
@@ -369,6 +369,7 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base) | |||
369 | { | 369 | { |
370 | void __iomem *virt_dma_base; | 370 | void __iomem *virt_dma_base; |
371 | int num_ports = sizeof (ioc4_dma_regs_t); | 371 | int num_ports = sizeof (ioc4_dma_regs_t); |
372 | void *pad; | ||
372 | 373 | ||
373 | printk(KERN_INFO "%s: BM-DMA at 0x%04lx-0x%04lx\n", hwif->name, | 374 | printk(KERN_INFO "%s: BM-DMA at 0x%04lx-0x%04lx\n", hwif->name, |
374 | dma_base, dma_base + num_ports - 1); | 375 | dma_base, dma_base + num_ports - 1); |
@@ -400,17 +401,14 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base) | |||
400 | 401 | ||
401 | hwif->sg_max_nents = IOC4_PRD_ENTRIES; | 402 | hwif->sg_max_nents = IOC4_PRD_ENTRIES; |
402 | 403 | ||
403 | hwif->dma_base2 = (unsigned long) | 404 | pad = pci_alloc_consistent(hwif->pci_dev, IOC4_IDE_CACHELINE_SIZE, |
404 | pci_alloc_consistent(hwif->pci_dev, | 405 | (dma_addr_t *) &(hwif->dma_status)); |
405 | IOC4_IDE_CACHELINE_SIZE, | ||
406 | (dma_addr_t *) &(hwif->dma_status)); | ||
407 | 406 | ||
408 | if (!hwif->dma_base2) | 407 | if (pad) { |
409 | goto dma_base2alloc_failure; | 408 | ide_set_hwifdata(hwif, pad); |
410 | 409 | return; | |
411 | return; | 410 | } |
412 | 411 | ||
413 | dma_base2alloc_failure: | ||
414 | pci_free_consistent(hwif->pci_dev, | 412 | pci_free_consistent(hwif->pci_dev, |
415 | IOC4_PRD_ENTRIES * IOC4_PRD_BYTES, | 413 | IOC4_PRD_ENTRIES * IOC4_PRD_BYTES, |
416 | hwif->dmatable_cpu, hwif->dmatable_dma); | 414 | hwif->dmatable_cpu, hwif->dmatable_dma); |
@@ -476,7 +474,7 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive) | |||
476 | hwif->OUTL(dma_addr, dma_base + IOC4_DMA_PTR_L * 4); | 474 | hwif->OUTL(dma_addr, dma_base + IOC4_DMA_PTR_L * 4); |
477 | 475 | ||
478 | /* Address of the Ending DMA */ | 476 | /* Address of the Ending DMA */ |
479 | memset((unsigned int *) hwif->dma_base2, 0, IOC4_IDE_CACHELINE_SIZE); | 477 | memset(ide_get_hwifdata(hwif), 0, IOC4_IDE_CACHELINE_SIZE); |
480 | ending_dma_addr = cpu_to_le32(hwif->dma_status); | 478 | ending_dma_addr = cpu_to_le32(hwif->dma_status); |
481 | hwif->OUTL(ending_dma_addr, dma_base + IOC4_DMA_END_ADDR * 4); | 479 | hwif->OUTL(ending_dma_addr, dma_base + IOC4_DMA_END_ADDR * 4); |
482 | 480 | ||
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c index 20b392948f36..697f566fb90a 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/pci/siimage.c | |||
@@ -898,7 +898,6 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif) | |||
898 | base = (unsigned long) addr; | 898 | base = (unsigned long) addr; |
899 | 899 | ||
900 | hwif->dma_base = base + (ch ? 0x08 : 0x00); | 900 | hwif->dma_base = base + (ch ? 0x08 : 0x00); |
901 | hwif->dma_base2 = base + (ch ? 0x18 : 0x10); | ||
902 | hwif->mmio = 2; | 901 | hwif->mmio = 2; |
903 | } | 902 | } |
904 | 903 | ||
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index 9b7589e8e93e..2af634d7acf4 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c | |||
@@ -248,7 +248,7 @@ static struct via_isa_bridge *via_config_find(struct pci_dev **isa) | |||
248 | u8 t; | 248 | u8 t; |
249 | 249 | ||
250 | for (via_config = via_isa_bridges; via_config->id; via_config++) | 250 | for (via_config = via_isa_bridges; via_config->id; via_config++) |
251 | if ((*isa = pci_find_device(PCI_VENDOR_ID_VIA + | 251 | if ((*isa = pci_get_device(PCI_VENDOR_ID_VIA + |
252 | !!(via_config->flags & VIA_BAD_ID), | 252 | !!(via_config->flags & VIA_BAD_ID), |
253 | via_config->id, NULL))) { | 253 | via_config->id, NULL))) { |
254 | 254 | ||
@@ -256,6 +256,7 @@ static struct via_isa_bridge *via_config_find(struct pci_dev **isa) | |||
256 | if (t >= via_config->rev_min && | 256 | if (t >= via_config->rev_min && |
257 | t <= via_config->rev_max) | 257 | t <= via_config->rev_max) |
258 | break; | 258 | break; |
259 | pci_dev_put(*isa); | ||
259 | } | 260 | } |
260 | 261 | ||
261 | return via_config; | 262 | return via_config; |
@@ -283,6 +284,7 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const | |||
283 | via_config = via_config_find(&isa); | 284 | via_config = via_config_find(&isa); |
284 | if (!via_config->id) { | 285 | if (!via_config->id) { |
285 | printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n"); | 286 | printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n"); |
287 | pci_dev_put(isa); | ||
286 | return -ENODEV; | 288 | return -ENODEV; |
287 | } | 289 | } |
288 | 290 | ||
@@ -361,6 +363,7 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const | |||
361 | via_dma[via_config->flags & VIA_UDMA], | 363 | via_dma[via_config->flags & VIA_UDMA], |
362 | pci_name(dev)); | 364 | pci_name(dev)); |
363 | 365 | ||
366 | pci_dev_put(isa); | ||
364 | return 0; | 367 | return 0; |
365 | } | 368 | } |
366 | 369 | ||
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index eb0945284acc..0719b6484824 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c | |||
@@ -101,7 +101,7 @@ static ide_hwif_t *ide_match_hwif(unsigned long io_base, u8 bootable, const char | |||
101 | return hwif; /* pick an unused entry */ | 101 | return hwif; /* pick an unused entry */ |
102 | } | 102 | } |
103 | } | 103 | } |
104 | for (h = 0; h < 2; ++h) { | 104 | for (h = 0; h < 2 && h < MAX_HWIFS; ++h) { |
105 | hwif = ide_hwifs + h; | 105 | hwif = ide_hwifs + h; |
106 | if (hwif->chipset == ide_unknown) | 106 | if (hwif->chipset == ide_unknown) |
107 | return hwif; /* pick an unused entry */ | 107 | return hwif; /* pick an unused entry */ |
@@ -795,24 +795,6 @@ int __ide_pci_register_driver(struct pci_driver *driver, struct module *module) | |||
795 | EXPORT_SYMBOL_GPL(__ide_pci_register_driver); | 795 | EXPORT_SYMBOL_GPL(__ide_pci_register_driver); |
796 | 796 | ||
797 | /** | 797 | /** |
798 | * ide_unregister_pci_driver - unregister an IDE driver | ||
799 | * @driver: driver to remove | ||
800 | * | ||
801 | * Unregister a currently installed IDE driver. Returns are the same | ||
802 | * as for pci_unregister_driver | ||
803 | */ | ||
804 | |||
805 | void ide_pci_unregister_driver(struct pci_driver *driver) | ||
806 | { | ||
807 | if(!pre_init) | ||
808 | pci_unregister_driver(driver); | ||
809 | else | ||
810 | list_del(&driver->node); | ||
811 | } | ||
812 | |||
813 | EXPORT_SYMBOL_GPL(ide_pci_unregister_driver); | ||
814 | |||
815 | /** | ||
816 | * ide_scan_pcidev - find an IDE driver for a device | 798 | * ide_scan_pcidev - find an IDE driver for a device |
817 | * @dev: PCI device to check | 799 | * @dev: PCI device to check |
818 | * | 800 | * |
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 1178bd434d1b..9ae4f3a67c70 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
@@ -874,23 +874,25 @@ static struct rdma_id_private *cma_new_id(struct rdma_cm_id *listen_id, | |||
874 | __u16 port; | 874 | __u16 port; |
875 | u8 ip_ver; | 875 | u8 ip_ver; |
876 | 876 | ||
877 | if (cma_get_net_info(ib_event->private_data, listen_id->ps, | ||
878 | &ip_ver, &port, &src, &dst)) | ||
879 | goto err; | ||
880 | |||
877 | id = rdma_create_id(listen_id->event_handler, listen_id->context, | 881 | id = rdma_create_id(listen_id->event_handler, listen_id->context, |
878 | listen_id->ps); | 882 | listen_id->ps); |
879 | if (IS_ERR(id)) | 883 | if (IS_ERR(id)) |
880 | return NULL; | 884 | goto err; |
885 | |||
886 | cma_save_net_info(&id->route.addr, &listen_id->route.addr, | ||
887 | ip_ver, port, src, dst); | ||
881 | 888 | ||
882 | rt = &id->route; | 889 | rt = &id->route; |
883 | rt->num_paths = ib_event->param.req_rcvd.alternate_path ? 2 : 1; | 890 | rt->num_paths = ib_event->param.req_rcvd.alternate_path ? 2 : 1; |
884 | rt->path_rec = kmalloc(sizeof *rt->path_rec * rt->num_paths, GFP_KERNEL); | 891 | rt->path_rec = kmalloc(sizeof *rt->path_rec * rt->num_paths, |
892 | GFP_KERNEL); | ||
885 | if (!rt->path_rec) | 893 | if (!rt->path_rec) |
886 | goto err; | 894 | goto destroy_id; |
887 | 895 | ||
888 | if (cma_get_net_info(ib_event->private_data, listen_id->ps, | ||
889 | &ip_ver, &port, &src, &dst)) | ||
890 | goto err; | ||
891 | |||
892 | cma_save_net_info(&id->route.addr, &listen_id->route.addr, | ||
893 | ip_ver, port, src, dst); | ||
894 | rt->path_rec[0] = *ib_event->param.req_rcvd.primary_path; | 896 | rt->path_rec[0] = *ib_event->param.req_rcvd.primary_path; |
895 | if (rt->num_paths == 2) | 897 | if (rt->num_paths == 2) |
896 | rt->path_rec[1] = *ib_event->param.req_rcvd.alternate_path; | 898 | rt->path_rec[1] = *ib_event->param.req_rcvd.alternate_path; |
@@ -903,8 +905,10 @@ static struct rdma_id_private *cma_new_id(struct rdma_cm_id *listen_id, | |||
903 | id_priv = container_of(id, struct rdma_id_private, id); | 905 | id_priv = container_of(id, struct rdma_id_private, id); |
904 | id_priv->state = CMA_CONNECT; | 906 | id_priv->state = CMA_CONNECT; |
905 | return id_priv; | 907 | return id_priv; |
906 | err: | 908 | |
909 | destroy_id: | ||
907 | rdma_destroy_id(id); | 910 | rdma_destroy_id(id); |
911 | err: | ||
908 | return NULL; | 912 | return NULL; |
909 | } | 913 | } |
910 | 914 | ||
@@ -932,6 +936,7 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) | |||
932 | mutex_unlock(&lock); | 936 | mutex_unlock(&lock); |
933 | if (ret) { | 937 | if (ret) { |
934 | ret = -ENODEV; | 938 | ret = -ENODEV; |
939 | cma_exch(conn_id, CMA_DESTROYING); | ||
935 | cma_release_remove(conn_id); | 940 | cma_release_remove(conn_id); |
936 | rdma_destroy_id(&conn_id->id); | 941 | rdma_destroy_id(&conn_id->id); |
937 | goto out; | 942 | goto out; |
@@ -1307,6 +1312,7 @@ static void cma_query_handler(int status, struct ib_sa_path_rec *path_rec, | |||
1307 | work->old_state = CMA_ROUTE_QUERY; | 1312 | work->old_state = CMA_ROUTE_QUERY; |
1308 | work->new_state = CMA_ADDR_RESOLVED; | 1313 | work->new_state = CMA_ADDR_RESOLVED; |
1309 | work->event.event = RDMA_CM_EVENT_ROUTE_ERROR; | 1314 | work->event.event = RDMA_CM_EVENT_ROUTE_ERROR; |
1315 | work->event.status = status; | ||
1310 | } | 1316 | } |
1311 | 1317 | ||
1312 | queue_work(cma_wq, &work->work); | 1318 | queue_work(cma_wq, &work->work); |
@@ -1862,6 +1868,11 @@ static int cma_connect_ib(struct rdma_id_private *id_priv, | |||
1862 | 1868 | ||
1863 | ret = ib_send_cm_req(id_priv->cm_id.ib, &req); | 1869 | ret = ib_send_cm_req(id_priv->cm_id.ib, &req); |
1864 | out: | 1870 | out: |
1871 | if (ret && !IS_ERR(id_priv->cm_id.ib)) { | ||
1872 | ib_destroy_cm_id(id_priv->cm_id.ib); | ||
1873 | id_priv->cm_id.ib = NULL; | ||
1874 | } | ||
1875 | |||
1865 | kfree(private_data); | 1876 | kfree(private_data); |
1866 | return ret; | 1877 | return ret; |
1867 | } | 1878 | } |
@@ -1889,10 +1900,8 @@ static int cma_connect_iw(struct rdma_id_private *id_priv, | |||
1889 | cm_id->remote_addr = *sin; | 1900 | cm_id->remote_addr = *sin; |
1890 | 1901 | ||
1891 | ret = cma_modify_qp_rtr(&id_priv->id); | 1902 | ret = cma_modify_qp_rtr(&id_priv->id); |
1892 | if (ret) { | 1903 | if (ret) |
1893 | iw_destroy_cm_id(cm_id); | 1904 | goto out; |
1894 | return ret; | ||
1895 | } | ||
1896 | 1905 | ||
1897 | iw_param.ord = conn_param->initiator_depth; | 1906 | iw_param.ord = conn_param->initiator_depth; |
1898 | iw_param.ird = conn_param->responder_resources; | 1907 | iw_param.ird = conn_param->responder_resources; |
@@ -1904,6 +1913,10 @@ static int cma_connect_iw(struct rdma_id_private *id_priv, | |||
1904 | iw_param.qpn = conn_param->qp_num; | 1913 | iw_param.qpn = conn_param->qp_num; |
1905 | ret = iw_cm_connect(cm_id, &iw_param); | 1914 | ret = iw_cm_connect(cm_id, &iw_param); |
1906 | out: | 1915 | out: |
1916 | if (ret && !IS_ERR(cm_id)) { | ||
1917 | iw_destroy_cm_id(cm_id); | ||
1918 | id_priv->cm_id.iw = NULL; | ||
1919 | } | ||
1907 | return ret; | 1920 | return ret; |
1908 | } | 1921 | } |
1909 | 1922 | ||
@@ -2142,12 +2155,9 @@ static int cma_remove_id_dev(struct rdma_id_private *id_priv) | |||
2142 | 2155 | ||
2143 | static void cma_process_remove(struct cma_device *cma_dev) | 2156 | static void cma_process_remove(struct cma_device *cma_dev) |
2144 | { | 2157 | { |
2145 | struct list_head remove_list; | ||
2146 | struct rdma_id_private *id_priv; | 2158 | struct rdma_id_private *id_priv; |
2147 | int ret; | 2159 | int ret; |
2148 | 2160 | ||
2149 | INIT_LIST_HEAD(&remove_list); | ||
2150 | |||
2151 | mutex_lock(&lock); | 2161 | mutex_lock(&lock); |
2152 | while (!list_empty(&cma_dev->id_list)) { | 2162 | while (!list_empty(&cma_dev->id_list)) { |
2153 | id_priv = list_entry(cma_dev->id_list.next, | 2163 | id_priv = list_entry(cma_dev->id_list.next, |
@@ -2158,8 +2168,7 @@ static void cma_process_remove(struct cma_device *cma_dev) | |||
2158 | continue; | 2168 | continue; |
2159 | } | 2169 | } |
2160 | 2170 | ||
2161 | list_del(&id_priv->list); | 2171 | list_del_init(&id_priv->list); |
2162 | list_add_tail(&id_priv->list, &remove_list); | ||
2163 | atomic_inc(&id_priv->refcount); | 2172 | atomic_inc(&id_priv->refcount); |
2164 | mutex_unlock(&lock); | 2173 | mutex_unlock(&lock); |
2165 | 2174 | ||
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index 2380994418a5..024d511c4b58 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c | |||
@@ -49,7 +49,7 @@ | |||
49 | MODULE_LICENSE("Dual BSD/GPL"); | 49 | MODULE_LICENSE("Dual BSD/GPL"); |
50 | MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>"); | 50 | MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>"); |
51 | MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver"); | 51 | MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver"); |
52 | MODULE_VERSION("SVNEHCA_0016"); | 52 | MODULE_VERSION("SVNEHCA_0017"); |
53 | 53 | ||
54 | int ehca_open_aqp1 = 0; | 54 | int ehca_open_aqp1 = 0; |
55 | int ehca_debug_level = 0; | 55 | int ehca_debug_level = 0; |
@@ -239,7 +239,7 @@ init_node_guid1: | |||
239 | return ret; | 239 | return ret; |
240 | } | 240 | } |
241 | 241 | ||
242 | int ehca_register_device(struct ehca_shca *shca) | 242 | int ehca_init_device(struct ehca_shca *shca) |
243 | { | 243 | { |
244 | int ret; | 244 | int ret; |
245 | 245 | ||
@@ -317,11 +317,6 @@ int ehca_register_device(struct ehca_shca *shca) | |||
317 | /* shca->ib_device.process_mad = ehca_process_mad; */ | 317 | /* shca->ib_device.process_mad = ehca_process_mad; */ |
318 | shca->ib_device.mmap = ehca_mmap; | 318 | shca->ib_device.mmap = ehca_mmap; |
319 | 319 | ||
320 | ret = ib_register_device(&shca->ib_device); | ||
321 | if (ret) | ||
322 | ehca_err(&shca->ib_device, | ||
323 | "ib_register_device() failed ret=%x", ret); | ||
324 | |||
325 | return ret; | 320 | return ret; |
326 | } | 321 | } |
327 | 322 | ||
@@ -561,9 +556,9 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev, | |||
561 | goto probe1; | 556 | goto probe1; |
562 | } | 557 | } |
563 | 558 | ||
564 | ret = ehca_register_device(shca); | 559 | ret = ehca_init_device(shca); |
565 | if (ret) { | 560 | if (ret) { |
566 | ehca_gen_err("Cannot register Infiniband device"); | 561 | ehca_gen_err("Cannot init ehca device struct"); |
567 | goto probe1; | 562 | goto probe1; |
568 | } | 563 | } |
569 | 564 | ||
@@ -571,7 +566,7 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev, | |||
571 | ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, 2048); | 566 | ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, 2048); |
572 | if (ret) { | 567 | if (ret) { |
573 | ehca_err(&shca->ib_device, "Cannot create EQ."); | 568 | ehca_err(&shca->ib_device, "Cannot create EQ."); |
574 | goto probe2; | 569 | goto probe1; |
575 | } | 570 | } |
576 | 571 | ||
577 | ret = ehca_create_eq(shca, &shca->neq, EHCA_NEQ, 513); | 572 | ret = ehca_create_eq(shca, &shca->neq, EHCA_NEQ, 513); |
@@ -600,6 +595,13 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev, | |||
600 | goto probe5; | 595 | goto probe5; |
601 | } | 596 | } |
602 | 597 | ||
598 | ret = ib_register_device(&shca->ib_device); | ||
599 | if (ret) { | ||
600 | ehca_err(&shca->ib_device, | ||
601 | "ib_register_device() failed ret=%x", ret); | ||
602 | goto probe6; | ||
603 | } | ||
604 | |||
603 | /* create AQP1 for port 1 */ | 605 | /* create AQP1 for port 1 */ |
604 | if (ehca_open_aqp1 == 1) { | 606 | if (ehca_open_aqp1 == 1) { |
605 | shca->sport[0].port_state = IB_PORT_DOWN; | 607 | shca->sport[0].port_state = IB_PORT_DOWN; |
@@ -607,7 +609,7 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev, | |||
607 | if (ret) { | 609 | if (ret) { |
608 | ehca_err(&shca->ib_device, | 610 | ehca_err(&shca->ib_device, |
609 | "Cannot create AQP1 for port 1."); | 611 | "Cannot create AQP1 for port 1."); |
610 | goto probe6; | 612 | goto probe7; |
611 | } | 613 | } |
612 | } | 614 | } |
613 | 615 | ||
@@ -618,7 +620,7 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev, | |||
618 | if (ret) { | 620 | if (ret) { |
619 | ehca_err(&shca->ib_device, | 621 | ehca_err(&shca->ib_device, |
620 | "Cannot create AQP1 for port 2."); | 622 | "Cannot create AQP1 for port 2."); |
621 | goto probe7; | 623 | goto probe8; |
622 | } | 624 | } |
623 | } | 625 | } |
624 | 626 | ||
@@ -630,12 +632,15 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev, | |||
630 | 632 | ||
631 | return 0; | 633 | return 0; |
632 | 634 | ||
633 | probe7: | 635 | probe8: |
634 | ret = ehca_destroy_aqp1(&shca->sport[0]); | 636 | ret = ehca_destroy_aqp1(&shca->sport[0]); |
635 | if (ret) | 637 | if (ret) |
636 | ehca_err(&shca->ib_device, | 638 | ehca_err(&shca->ib_device, |
637 | "Cannot destroy AQP1 for port 1. ret=%x", ret); | 639 | "Cannot destroy AQP1 for port 1. ret=%x", ret); |
638 | 640 | ||
641 | probe7: | ||
642 | ib_unregister_device(&shca->ib_device); | ||
643 | |||
639 | probe6: | 644 | probe6: |
640 | ret = ehca_dereg_internal_maxmr(shca); | 645 | ret = ehca_dereg_internal_maxmr(shca); |
641 | if (ret) | 646 | if (ret) |
@@ -660,9 +665,6 @@ probe3: | |||
660 | ehca_err(&shca->ib_device, | 665 | ehca_err(&shca->ib_device, |
661 | "Cannot destroy EQ. ret=%x", ret); | 666 | "Cannot destroy EQ. ret=%x", ret); |
662 | 667 | ||
663 | probe2: | ||
664 | ib_unregister_device(&shca->ib_device); | ||
665 | |||
666 | probe1: | 668 | probe1: |
667 | ib_dealloc_device(&shca->ib_device); | 669 | ib_dealloc_device(&shca->ib_device); |
668 | 670 | ||
@@ -750,7 +752,7 @@ int __init ehca_module_init(void) | |||
750 | int ret; | 752 | int ret; |
751 | 753 | ||
752 | printk(KERN_INFO "eHCA Infiniband Device Driver " | 754 | printk(KERN_INFO "eHCA Infiniband Device Driver " |
753 | "(Rel.: SVNEHCA_0016)\n"); | 755 | "(Rel.: SVNEHCA_0017)\n"); |
754 | idr_init(&ehca_qp_idr); | 756 | idr_init(&ehca_qp_idr); |
755 | idr_init(&ehca_cq_idr); | 757 | idr_init(&ehca_cq_idr); |
756 | spin_lock_init(&ehca_qp_idr_lock); | 758 | spin_lock_init(&ehca_qp_idr_lock); |
diff --git a/drivers/infiniband/hw/ehca/ehca_tools.h b/drivers/infiniband/hw/ehca/ehca_tools.h index 9f56bb846d93..809da3ef706b 100644 --- a/drivers/infiniband/hw/ehca/ehca_tools.h +++ b/drivers/infiniband/hw/ehca/ehca_tools.h | |||
@@ -117,7 +117,7 @@ extern int ehca_debug_level; | |||
117 | unsigned int l = (unsigned int)(len); \ | 117 | unsigned int l = (unsigned int)(len); \ |
118 | unsigned char *deb = (unsigned char*)(adr); \ | 118 | unsigned char *deb = (unsigned char*)(adr); \ |
119 | for (x = 0; x < l; x += 16) { \ | 119 | for (x = 0; x < l; x += 16) { \ |
120 | printk("EHCA_DMP:%s" format \ | 120 | printk("EHCA_DMP:%s " format \ |
121 | " adr=%p ofs=%04x %016lx %016lx\n", \ | 121 | " adr=%p ofs=%04x %016lx %016lx\n", \ |
122 | __FUNCTION__, ##args, deb, x, \ | 122 | __FUNCTION__, ##args, deb, x, \ |
123 | *((u64 *)&deb[0]), *((u64 *)&deb[8])); \ | 123 | *((u64 *)&deb[0]), *((u64 *)&deb[8])); \ |
diff --git a/drivers/infiniband/hw/ipath/ipath_rc.c b/drivers/infiniband/hw/ipath/ipath_rc.c index a504cf67f272..ce6038743c5c 100644 --- a/drivers/infiniband/hw/ipath/ipath_rc.c +++ b/drivers/infiniband/hw/ipath/ipath_rc.c | |||
@@ -241,10 +241,7 @@ int ipath_make_rc_req(struct ipath_qp *qp, | |||
241 | * original work request since we may need to resend | 241 | * original work request since we may need to resend |
242 | * it. | 242 | * it. |
243 | */ | 243 | */ |
244 | qp->s_sge.sge = wqe->sg_list[0]; | 244 | len = wqe->length; |
245 | qp->s_sge.sg_list = wqe->sg_list + 1; | ||
246 | qp->s_sge.num_sge = wqe->wr.num_sge; | ||
247 | qp->s_len = len = wqe->length; | ||
248 | ss = &qp->s_sge; | 245 | ss = &qp->s_sge; |
249 | bth2 = 0; | 246 | bth2 = 0; |
250 | switch (wqe->wr.opcode) { | 247 | switch (wqe->wr.opcode) { |
@@ -368,14 +365,23 @@ int ipath_make_rc_req(struct ipath_qp *qp, | |||
368 | default: | 365 | default: |
369 | goto done; | 366 | goto done; |
370 | } | 367 | } |
368 | qp->s_sge.sge = wqe->sg_list[0]; | ||
369 | qp->s_sge.sg_list = wqe->sg_list + 1; | ||
370 | qp->s_sge.num_sge = wqe->wr.num_sge; | ||
371 | qp->s_len = wqe->length; | ||
371 | if (newreq) { | 372 | if (newreq) { |
372 | qp->s_tail++; | 373 | qp->s_tail++; |
373 | if (qp->s_tail >= qp->s_size) | 374 | if (qp->s_tail >= qp->s_size) |
374 | qp->s_tail = 0; | 375 | qp->s_tail = 0; |
375 | } | 376 | } |
376 | bth2 |= qp->s_psn++ & IPATH_PSN_MASK; | 377 | bth2 |= qp->s_psn & IPATH_PSN_MASK; |
377 | if ((int)(qp->s_psn - qp->s_next_psn) > 0) | 378 | if (wqe->wr.opcode == IB_WR_RDMA_READ) |
378 | qp->s_next_psn = qp->s_psn; | 379 | qp->s_psn = wqe->lpsn + 1; |
380 | else { | ||
381 | qp->s_psn++; | ||
382 | if ((int)(qp->s_psn - qp->s_next_psn) > 0) | ||
383 | qp->s_next_psn = qp->s_psn; | ||
384 | } | ||
379 | /* | 385 | /* |
380 | * Put the QP on the pending list so lost ACKs will cause | 386 | * Put the QP on the pending list so lost ACKs will cause |
381 | * a retry. More than one request can be pending so the | 387 | * a retry. More than one request can be pending so the |
@@ -690,13 +696,6 @@ void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc) | |||
690 | struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last); | 696 | struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last); |
691 | struct ipath_ibdev *dev; | 697 | struct ipath_ibdev *dev; |
692 | 698 | ||
693 | /* | ||
694 | * If there are no requests pending, we are done. | ||
695 | */ | ||
696 | if (ipath_cmp24(psn, qp->s_next_psn) >= 0 || | ||
697 | qp->s_last == qp->s_tail) | ||
698 | goto done; | ||
699 | |||
700 | if (qp->s_retry == 0) { | 699 | if (qp->s_retry == 0) { |
701 | wc->wr_id = wqe->wr.wr_id; | 700 | wc->wr_id = wqe->wr.wr_id; |
702 | wc->status = IB_WC_RETRY_EXC_ERR; | 701 | wc->status = IB_WC_RETRY_EXC_ERR; |
@@ -731,8 +730,6 @@ void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc) | |||
731 | dev->n_rc_resends += (int)qp->s_psn - (int)psn; | 730 | dev->n_rc_resends += (int)qp->s_psn - (int)psn; |
732 | 731 | ||
733 | reset_psn(qp, psn); | 732 | reset_psn(qp, psn); |
734 | |||
735 | done: | ||
736 | tasklet_hi_schedule(&qp->s_task); | 733 | tasklet_hi_schedule(&qp->s_task); |
737 | 734 | ||
738 | bail: | 735 | bail: |
@@ -765,6 +762,7 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode) | |||
765 | struct ib_wc wc; | 762 | struct ib_wc wc; |
766 | struct ipath_swqe *wqe; | 763 | struct ipath_swqe *wqe; |
767 | int ret = 0; | 764 | int ret = 0; |
765 | u32 ack_psn; | ||
768 | 766 | ||
769 | /* | 767 | /* |
770 | * Remove the QP from the timeout queue (or RNR timeout queue). | 768 | * Remove the QP from the timeout queue (or RNR timeout queue). |
@@ -777,26 +775,26 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode) | |||
777 | list_del_init(&qp->timerwait); | 775 | list_del_init(&qp->timerwait); |
778 | spin_unlock(&dev->pending_lock); | 776 | spin_unlock(&dev->pending_lock); |
779 | 777 | ||
778 | /* Nothing is pending to ACK/NAK. */ | ||
779 | if (unlikely(qp->s_last == qp->s_tail)) | ||
780 | goto bail; | ||
781 | |||
780 | /* | 782 | /* |
781 | * Note that NAKs implicitly ACK outstanding SEND and RDMA write | 783 | * Note that NAKs implicitly ACK outstanding SEND and RDMA write |
782 | * requests and implicitly NAK RDMA read and atomic requests issued | 784 | * requests and implicitly NAK RDMA read and atomic requests issued |
783 | * before the NAK'ed request. The MSN won't include the NAK'ed | 785 | * before the NAK'ed request. The MSN won't include the NAK'ed |
784 | * request but will include an ACK'ed request(s). | 786 | * request but will include an ACK'ed request(s). |
785 | */ | 787 | */ |
788 | ack_psn = psn; | ||
789 | if (aeth >> 29) | ||
790 | ack_psn--; | ||
786 | wqe = get_swqe_ptr(qp, qp->s_last); | 791 | wqe = get_swqe_ptr(qp, qp->s_last); |
787 | 792 | ||
788 | /* Nothing is pending to ACK/NAK. */ | ||
789 | if (qp->s_last == qp->s_tail) | ||
790 | goto bail; | ||
791 | |||
792 | /* | 793 | /* |
793 | * The MSN might be for a later WQE than the PSN indicates so | 794 | * The MSN might be for a later WQE than the PSN indicates so |
794 | * only complete WQEs that the PSN finishes. | 795 | * only complete WQEs that the PSN finishes. |
795 | */ | 796 | */ |
796 | while (ipath_cmp24(psn, wqe->lpsn) >= 0) { | 797 | while (ipath_cmp24(ack_psn, wqe->lpsn) >= 0) { |
797 | /* If we are ACKing a WQE, the MSN should be >= the SSN. */ | ||
798 | if (ipath_cmp24(aeth, wqe->ssn) < 0) | ||
799 | break; | ||
800 | /* | 798 | /* |
801 | * If this request is a RDMA read or atomic, and the ACK is | 799 | * If this request is a RDMA read or atomic, and the ACK is |
802 | * for a later operation, this ACK NAKs the RDMA read or | 800 | * for a later operation, this ACK NAKs the RDMA read or |
@@ -807,7 +805,8 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode) | |||
807 | * is sent but before the response is received. | 805 | * is sent but before the response is received. |
808 | */ | 806 | */ |
809 | if ((wqe->wr.opcode == IB_WR_RDMA_READ && | 807 | if ((wqe->wr.opcode == IB_WR_RDMA_READ && |
810 | opcode != OP(RDMA_READ_RESPONSE_LAST)) || | 808 | (opcode != OP(RDMA_READ_RESPONSE_LAST) || |
809 | ipath_cmp24(ack_psn, wqe->lpsn) != 0)) || | ||
811 | ((wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP || | 810 | ((wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP || |
812 | wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD) && | 811 | wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD) && |
813 | (opcode != OP(ATOMIC_ACKNOWLEDGE) || | 812 | (opcode != OP(ATOMIC_ACKNOWLEDGE) || |
@@ -825,6 +824,10 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode) | |||
825 | */ | 824 | */ |
826 | goto bail; | 825 | goto bail; |
827 | } | 826 | } |
827 | if (wqe->wr.opcode == IB_WR_RDMA_READ || | ||
828 | wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP || | ||
829 | wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD) | ||
830 | tasklet_hi_schedule(&qp->s_task); | ||
828 | /* Post a send completion queue entry if requested. */ | 831 | /* Post a send completion queue entry if requested. */ |
829 | if (!test_bit(IPATH_S_SIGNAL_REQ_WR, &qp->s_flags) || | 832 | if (!test_bit(IPATH_S_SIGNAL_REQ_WR, &qp->s_flags) || |
830 | (wqe->wr.send_flags & IB_SEND_SIGNALED)) { | 833 | (wqe->wr.send_flags & IB_SEND_SIGNALED)) { |
@@ -1055,7 +1058,8 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev, | |||
1055 | /* no AETH, no ACK */ | 1058 | /* no AETH, no ACK */ |
1056 | if (unlikely(ipath_cmp24(psn, qp->s_last_psn + 1))) { | 1059 | if (unlikely(ipath_cmp24(psn, qp->s_last_psn + 1))) { |
1057 | dev->n_rdma_seq++; | 1060 | dev->n_rdma_seq++; |
1058 | ipath_restart_rc(qp, qp->s_last_psn + 1, &wc); | 1061 | if (qp->s_last != qp->s_tail) |
1062 | ipath_restart_rc(qp, qp->s_last_psn + 1, &wc); | ||
1059 | goto ack_done; | 1063 | goto ack_done; |
1060 | } | 1064 | } |
1061 | rdma_read: | 1065 | rdma_read: |
@@ -1091,7 +1095,8 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev, | |||
1091 | /* ACKs READ req. */ | 1095 | /* ACKs READ req. */ |
1092 | if (unlikely(ipath_cmp24(psn, qp->s_last_psn + 1))) { | 1096 | if (unlikely(ipath_cmp24(psn, qp->s_last_psn + 1))) { |
1093 | dev->n_rdma_seq++; | 1097 | dev->n_rdma_seq++; |
1094 | ipath_restart_rc(qp, qp->s_last_psn + 1, &wc); | 1098 | if (qp->s_last != qp->s_tail) |
1099 | ipath_restart_rc(qp, qp->s_last_psn + 1, &wc); | ||
1095 | goto ack_done; | 1100 | goto ack_done; |
1096 | } | 1101 | } |
1097 | /* FALLTHROUGH */ | 1102 | /* FALLTHROUGH */ |
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index e10350360f2f..e4823ab2b127 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c | |||
@@ -1721,11 +1721,11 @@ static void hisax_b_l1l2(struct hisax_if *ifc, int pr, void *arg) | |||
1721 | hisax_b_sched_event(bcs, B_RCVBUFREADY); | 1721 | hisax_b_sched_event(bcs, B_RCVBUFREADY); |
1722 | break; | 1722 | break; |
1723 | case PH_DATA | CONFIRM: | 1723 | case PH_DATA | CONFIRM: |
1724 | bcs->tx_cnt -= (int) arg; | 1724 | bcs->tx_cnt -= (long)arg; |
1725 | if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag)) { | 1725 | if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag)) { |
1726 | u_long flags; | 1726 | u_long flags; |
1727 | spin_lock_irqsave(&bcs->aclock, flags); | 1727 | spin_lock_irqsave(&bcs->aclock, flags); |
1728 | bcs->ackcnt += (int) arg; | 1728 | bcs->ackcnt += (long)arg; |
1729 | spin_unlock_irqrestore(&bcs->aclock, flags); | 1729 | spin_unlock_irqrestore(&bcs->aclock, flags); |
1730 | schedule_event(bcs, B_ACKPENDING); | 1730 | schedule_event(bcs, B_ACKPENDING); |
1731 | } | 1731 | } |
@@ -1789,7 +1789,7 @@ static void hisax_b_l2l1(struct PStack *st, int pr, void *arg) | |||
1789 | 1789 | ||
1790 | switch (pr) { | 1790 | switch (pr) { |
1791 | case PH_ACTIVATE | REQUEST: | 1791 | case PH_ACTIVATE | REQUEST: |
1792 | B_L2L1(b_if, pr, (void *) st->l1.mode); | 1792 | B_L2L1(b_if, pr, (void *)(unsigned long)st->l1.mode); |
1793 | break; | 1793 | break; |
1794 | case PH_DATA | REQUEST: | 1794 | case PH_DATA | REQUEST: |
1795 | case PH_PULL | INDICATION: | 1795 | case PH_PULL | INDICATION: |
diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c index 3a5ca8a68fc4..0ca5e66d2f5a 100644 --- a/drivers/isdn/hisax/hfc4s8s_l1.c +++ b/drivers/isdn/hisax/hfc4s8s_l1.c | |||
@@ -424,7 +424,7 @@ bch_l2l1(struct hisax_if *ifc, int pr, void *arg) | |||
424 | struct hfc4s8s_btype *bch = ifc->priv; | 424 | struct hfc4s8s_btype *bch = ifc->priv; |
425 | struct hfc4s8s_l1 *l1 = bch->l1p; | 425 | struct hfc4s8s_l1 *l1 = bch->l1p; |
426 | struct sk_buff *skb = (struct sk_buff *) arg; | 426 | struct sk_buff *skb = (struct sk_buff *) arg; |
427 | int mode = (int) arg; | 427 | long mode = (long) arg; |
428 | u_long flags; | 428 | u_long flags; |
429 | 429 | ||
430 | switch (pr) { | 430 | switch (pr) { |
@@ -914,7 +914,7 @@ tx_d_frame(struct hfc4s8s_l1 *l1p) | |||
914 | struct sk_buff *skb; | 914 | struct sk_buff *skb; |
915 | u_char f1, f2; | 915 | u_char f1, f2; |
916 | u_char *cp; | 916 | u_char *cp; |
917 | int cnt; | 917 | long cnt; |
918 | 918 | ||
919 | if (l1p->l1_state != 7) | 919 | if (l1p->l1_state != 7) |
920 | return; | 920 | return; |
@@ -980,7 +980,8 @@ tx_b_frame(struct hfc4s8s_btype *bch) | |||
980 | struct sk_buff *skb; | 980 | struct sk_buff *skb; |
981 | struct hfc4s8s_l1 *l1 = bch->l1p; | 981 | struct hfc4s8s_l1 *l1 = bch->l1p; |
982 | u_char *cp; | 982 | u_char *cp; |
983 | int cnt, max, hdlc_num, ack_len = 0; | 983 | int cnt, max, hdlc_num; |
984 | long ack_len = 0; | ||
984 | 985 | ||
985 | if (!l1->enabled || (bch->mode == L1_MODE_NULL)) | 986 | if (!l1->enabled || (bch->mode == L1_MODE_NULL)) |
986 | return; | 987 | return; |
diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c index f27c1608a3a7..b7e8e23be337 100644 --- a/drivers/isdn/hisax/hfc_sx.c +++ b/drivers/isdn/hisax/hfc_sx.c | |||
@@ -970,7 +970,7 @@ HFCSX_l1hw(struct PStack *st, int pr, void *arg) | |||
970 | break; | 970 | break; |
971 | case (HW_TESTLOOP | REQUEST): | 971 | case (HW_TESTLOOP | REQUEST): |
972 | spin_lock_irqsave(&cs->lock, flags); | 972 | spin_lock_irqsave(&cs->lock, flags); |
973 | switch ((int) arg) { | 973 | switch ((long) arg) { |
974 | case (1): | 974 | case (1): |
975 | Write_hfc(cs, HFCSX_B1_SSL, 0x80); /* tx slot */ | 975 | Write_hfc(cs, HFCSX_B1_SSL, 0x80); /* tx slot */ |
976 | Write_hfc(cs, HFCSX_B1_RSL, 0x80); /* rx slot */ | 976 | Write_hfc(cs, HFCSX_B1_RSL, 0x80); /* rx slot */ |
@@ -986,7 +986,7 @@ HFCSX_l1hw(struct PStack *st, int pr, void *arg) | |||
986 | default: | 986 | default: |
987 | spin_unlock_irqrestore(&cs->lock, flags); | 987 | spin_unlock_irqrestore(&cs->lock, flags); |
988 | if (cs->debug & L1_DEB_WARN) | 988 | if (cs->debug & L1_DEB_WARN) |
989 | debugl1(cs, "hfcsx_l1hw loop invalid %4x", (int) arg); | 989 | debugl1(cs, "hfcsx_l1hw loop invalid %4lx", arg); |
990 | return; | 990 | return; |
991 | } | 991 | } |
992 | cs->hw.hfcsx.trm |= 0x80; /* enable IOM-loop */ | 992 | cs->hw.hfcsx.trm |= 0x80; /* enable IOM-loop */ |
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c index b5e571a52694..6b88ecb5047d 100644 --- a/drivers/isdn/hisax/hfc_usb.c +++ b/drivers/isdn/hisax/hfc_usb.c | |||
@@ -696,7 +696,7 @@ tx_iso_complete(struct urb *urb, struct pt_regs *regs) | |||
696 | fifo->delete_flg = TRUE; | 696 | fifo->delete_flg = TRUE; |
697 | fifo->hif->l1l2(fifo->hif, | 697 | fifo->hif->l1l2(fifo->hif, |
698 | PH_DATA | CONFIRM, | 698 | PH_DATA | CONFIRM, |
699 | (void *) fifo->skbuff-> | 699 | (void *) (unsigned long) fifo->skbuff-> |
700 | truesize); | 700 | truesize); |
701 | if (fifo->skbuff && fifo->delete_flg) { | 701 | if (fifo->skbuff && fifo->delete_flg) { |
702 | dev_kfree_skb_any(fifo->skbuff); | 702 | dev_kfree_skb_any(fifo->skbuff); |
@@ -1144,7 +1144,7 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) | |||
1144 | set_hfcmode(hfc, | 1144 | set_hfcmode(hfc, |
1145 | (fifo->fifonum == | 1145 | (fifo->fifonum == |
1146 | HFCUSB_B1_TX) ? 0 : 1, | 1146 | HFCUSB_B1_TX) ? 0 : 1, |
1147 | (int) arg); | 1147 | (long) arg); |
1148 | fifo->hif->l1l2(fifo->hif, | 1148 | fifo->hif->l1l2(fifo->hif, |
1149 | PH_ACTIVATE | INDICATION, | 1149 | PH_ACTIVATE | INDICATION, |
1150 | NULL); | 1150 | NULL); |
diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c index 1d7cf3bd6aa3..881a4165cfb4 100644 --- a/drivers/isdn/hisax/hisax_fcpcipnp.c +++ b/drivers/isdn/hisax/hisax_fcpcipnp.c | |||
@@ -546,7 +546,7 @@ static inline void hdlc_xpr_irq(struct fritz_bcs *bcs) | |||
546 | } | 546 | } |
547 | bcs->tx_cnt = 0; | 547 | bcs->tx_cnt = 0; |
548 | bcs->tx_skb = NULL; | 548 | bcs->tx_skb = NULL; |
549 | B_L1L2(bcs, PH_DATA | CONFIRM, (void *) skb->truesize); | 549 | B_L1L2(bcs, PH_DATA | CONFIRM, (void *)(unsigned long)skb->truesize); |
550 | dev_kfree_skb_irq(skb); | 550 | dev_kfree_skb_irq(skb); |
551 | } | 551 | } |
552 | 552 | ||
@@ -635,7 +635,7 @@ static void fritz_b_l2l1(struct hisax_if *ifc, int pr, void *arg) | |||
635 | hdlc_fill_fifo(bcs); | 635 | hdlc_fill_fifo(bcs); |
636 | break; | 636 | break; |
637 | case PH_ACTIVATE | REQUEST: | 637 | case PH_ACTIVATE | REQUEST: |
638 | mode = (int) arg; | 638 | mode = (long) arg; |
639 | DBG(4,"B%d,PH_ACTIVATE_REQUEST %d", bcs->channel + 1, mode); | 639 | DBG(4,"B%d,PH_ACTIVATE_REQUEST %d", bcs->channel + 1, mode); |
640 | modehdlc(bcs, mode); | 640 | modehdlc(bcs, mode); |
641 | B_L1L2(bcs, PH_ACTIVATE | INDICATION, NULL); | 641 | B_L1L2(bcs, PH_ACTIVATE | INDICATION, NULL); |
@@ -998,18 +998,15 @@ static int __init hisax_fcpcipnp_init(void) | |||
998 | 998 | ||
999 | retval = pci_register_driver(&fcpci_driver); | 999 | retval = pci_register_driver(&fcpci_driver); |
1000 | if (retval) | 1000 | if (retval) |
1001 | goto out; | 1001 | return retval; |
1002 | #ifdef __ISAPNP__ | 1002 | #ifdef __ISAPNP__ |
1003 | retval = pnp_register_driver(&fcpnp_driver); | 1003 | retval = pnp_register_driver(&fcpnp_driver); |
1004 | if (retval < 0) | 1004 | if (retval < 0) { |
1005 | goto out_unregister_pci; | 1005 | pci_unregister_driver(&fcpci_driver); |
1006 | return retval; | ||
1007 | } | ||
1006 | #endif | 1008 | #endif |
1007 | return 0; | 1009 | return 0; |
1008 | |||
1009 | out_unregister_pci: | ||
1010 | pci_unregister_driver(&fcpci_driver); | ||
1011 | out: | ||
1012 | return retval; | ||
1013 | } | 1010 | } |
1014 | 1011 | ||
1015 | static void __exit hisax_fcpcipnp_exit(void) | 1012 | static void __exit hisax_fcpcipnp_exit(void) |
diff --git a/drivers/isdn/hisax/st5481_b.c b/drivers/isdn/hisax/st5481_b.c index 22fd5db18d48..aca2a3954b14 100644 --- a/drivers/isdn/hisax/st5481_b.c +++ b/drivers/isdn/hisax/st5481_b.c | |||
@@ -86,7 +86,7 @@ static void usb_b_out(struct st5481_bcs *bcs,int buf_nr) | |||
86 | if (!skb->len) { | 86 | if (!skb->len) { |
87 | // Frame sent | 87 | // Frame sent |
88 | b_out->tx_skb = NULL; | 88 | b_out->tx_skb = NULL; |
89 | B_L1L2(bcs, PH_DATA | CONFIRM, (void *) skb->truesize); | 89 | B_L1L2(bcs, PH_DATA | CONFIRM, (void *)(unsigned long) skb->truesize); |
90 | dev_kfree_skb_any(skb); | 90 | dev_kfree_skb_any(skb); |
91 | 91 | ||
92 | /* if (!(bcs->tx_skb = skb_dequeue(&bcs->sq))) { */ | 92 | /* if (!(bcs->tx_skb = skb_dequeue(&bcs->sq))) { */ |
@@ -350,7 +350,7 @@ void st5481_b_l2l1(struct hisax_if *ifc, int pr, void *arg) | |||
350 | { | 350 | { |
351 | struct st5481_bcs *bcs = ifc->priv; | 351 | struct st5481_bcs *bcs = ifc->priv; |
352 | struct sk_buff *skb = arg; | 352 | struct sk_buff *skb = arg; |
353 | int mode; | 353 | long mode; |
354 | 354 | ||
355 | DBG(4, ""); | 355 | DBG(4, ""); |
356 | 356 | ||
@@ -360,8 +360,8 @@ void st5481_b_l2l1(struct hisax_if *ifc, int pr, void *arg) | |||
360 | bcs->b_out.tx_skb = skb; | 360 | bcs->b_out.tx_skb = skb; |
361 | break; | 361 | break; |
362 | case PH_ACTIVATE | REQUEST: | 362 | case PH_ACTIVATE | REQUEST: |
363 | mode = (int) arg; | 363 | mode = (long) arg; |
364 | DBG(4,"B%d,PH_ACTIVATE_REQUEST %d", bcs->channel + 1, mode); | 364 | DBG(4,"B%d,PH_ACTIVATE_REQUEST %ld", bcs->channel + 1, mode); |
365 | st5481B_mode(bcs, mode); | 365 | st5481B_mode(bcs, mode); |
366 | B_L1L2(bcs, PH_ACTIVATE | INDICATION, NULL); | 366 | B_L1L2(bcs, PH_ACTIVATE | INDICATION, NULL); |
367 | break; | 367 | break; |
diff --git a/drivers/isdn/hisax/st5481_d.c b/drivers/isdn/hisax/st5481_d.c index 493dc94992e5..98adec440590 100644 --- a/drivers/isdn/hisax/st5481_d.c +++ b/drivers/isdn/hisax/st5481_d.c | |||
@@ -374,7 +374,7 @@ static void usb_d_out_complete(struct urb *urb, struct pt_regs *regs) | |||
374 | { | 374 | { |
375 | struct st5481_adapter *adapter = urb->context; | 375 | struct st5481_adapter *adapter = urb->context; |
376 | struct st5481_d_out *d_out = &adapter->d_out; | 376 | struct st5481_d_out *d_out = &adapter->d_out; |
377 | int buf_nr; | 377 | long buf_nr; |
378 | 378 | ||
379 | DBG(2, ""); | 379 | DBG(2, ""); |
380 | 380 | ||
@@ -546,7 +546,7 @@ static void dout_reseted(struct FsmInst *fsm, int event, void *arg) | |||
546 | static void dout_complete(struct FsmInst *fsm, int event, void *arg) | 546 | static void dout_complete(struct FsmInst *fsm, int event, void *arg) |
547 | { | 547 | { |
548 | struct st5481_adapter *adapter = fsm->userdata; | 548 | struct st5481_adapter *adapter = fsm->userdata; |
549 | int buf_nr = (int) arg; | 549 | long buf_nr = (long) arg; |
550 | 550 | ||
551 | usb_d_out(adapter, buf_nr); | 551 | usb_d_out(adapter, buf_nr); |
552 | } | 552 | } |
diff --git a/drivers/isdn/sc/command.c b/drivers/isdn/sc/command.c index b4b24335f716..04b8a58f03b5 100644 --- a/drivers/isdn/sc/command.c +++ b/drivers/isdn/sc/command.c | |||
@@ -103,9 +103,6 @@ int command(isdn_ctrl *cmd) | |||
103 | return -ENODEV; | 103 | return -ENODEV; |
104 | } | 104 | } |
105 | 105 | ||
106 | pr_debug("%s: Received %s command from Link Layer\n", | ||
107 | sc_adapter[card]->devicename, commands[cmd->command]); | ||
108 | |||
109 | /* | 106 | /* |
110 | * Dispatch the command | 107 | * Dispatch the command |
111 | */ | 108 | */ |
@@ -118,7 +115,7 @@ int command(isdn_ctrl *cmd) | |||
118 | memcpy(&cmdptr, cmd->parm.num, sizeof(unsigned long)); | 115 | memcpy(&cmdptr, cmd->parm.num, sizeof(unsigned long)); |
119 | if (copy_from_user(&ioc, (scs_ioctl __user *)cmdptr, | 116 | if (copy_from_user(&ioc, (scs_ioctl __user *)cmdptr, |
120 | sizeof(scs_ioctl))) { | 117 | sizeof(scs_ioctl))) { |
121 | pr_debug("%s: Failed to verify user space 0x%x\n", | 118 | pr_debug("%s: Failed to verify user space 0x%lx\n", |
122 | sc_adapter[card]->devicename, cmdptr); | 119 | sc_adapter[card]->devicename, cmdptr); |
123 | return -EFAULT; | 120 | return -EFAULT; |
124 | } | 121 | } |
@@ -195,7 +192,7 @@ static int dial(int card, unsigned long channel, setup_parm setup) | |||
195 | strlen(Phone), | 192 | strlen(Phone), |
196 | (unsigned int *) Phone); | 193 | (unsigned int *) Phone); |
197 | 194 | ||
198 | pr_debug("%s: Dialing %s on channel %d\n", | 195 | pr_debug("%s: Dialing %s on channel %lu\n", |
199 | sc_adapter[card]->devicename, Phone, channel+1); | 196 | sc_adapter[card]->devicename, Phone, channel+1); |
200 | 197 | ||
201 | return status; | 198 | return status; |
@@ -217,7 +214,7 @@ static int answer(int card, unsigned long channel) | |||
217 | } | 214 | } |
218 | 215 | ||
219 | indicate_status(card, ISDN_STAT_BCONN,channel,NULL); | 216 | indicate_status(card, ISDN_STAT_BCONN,channel,NULL); |
220 | pr_debug("%s: Answered incoming call on channel %s\n", | 217 | pr_debug("%s: Answered incoming call on channel %lu\n", |
221 | sc_adapter[card]->devicename, channel+1); | 218 | sc_adapter[card]->devicename, channel+1); |
222 | return 0; | 219 | return 0; |
223 | } | 220 | } |
@@ -240,7 +237,7 @@ static int hangup(int card, unsigned long channel) | |||
240 | (unsigned char) channel+1, | 237 | (unsigned char) channel+1, |
241 | 0, | 238 | 0, |
242 | NULL); | 239 | NULL); |
243 | pr_debug("%s: Sent HANGUP message to channel %d\n", | 240 | pr_debug("%s: Sent HANGUP message to channel %lu\n", |
244 | sc_adapter[card]->devicename, channel+1); | 241 | sc_adapter[card]->devicename, channel+1); |
245 | return status; | 242 | return status; |
246 | } | 243 | } |
@@ -260,9 +257,6 @@ static int setl2(int card, unsigned long arg) | |||
260 | protocol = arg >> 8; | 257 | protocol = arg >> 8; |
261 | channel = arg & 0xff; | 258 | channel = arg & 0xff; |
262 | sc_adapter[card]->channel[channel].l2_proto = protocol; | 259 | sc_adapter[card]->channel[channel].l2_proto = protocol; |
263 | pr_debug("%s: Level 2 protocol for channel %d set to %s from %d\n", | ||
264 | sc_adapter[card]->devicename, channel+1, | ||
265 | l2protos[sc_adapter[card]->channel[channel].l2_proto],protocol); | ||
266 | 260 | ||
267 | /* | 261 | /* |
268 | * check that the adapter is also set to the correct protocol | 262 | * check that the adapter is also set to the correct protocol |
@@ -293,8 +287,6 @@ static int setl3(int card, unsigned long channel) | |||
293 | } | 287 | } |
294 | 288 | ||
295 | sc_adapter[card]->channel[channel].l3_proto = protocol; | 289 | sc_adapter[card]->channel[channel].l3_proto = protocol; |
296 | pr_debug("%s: Level 3 protocol for channel %d set to %s\n", | ||
297 | sc_adapter[card]->devicename, channel+1, l3protos[protocol]); | ||
298 | return 0; | 290 | return 0; |
299 | } | 291 | } |
300 | 292 | ||
@@ -311,7 +303,7 @@ static int acceptb(int card, unsigned long channel) | |||
311 | return -ENOBUFS; | 303 | return -ENOBUFS; |
312 | } | 304 | } |
313 | 305 | ||
314 | pr_debug("%s: B-Channel connection accepted on channel %d\n", | 306 | pr_debug("%s: B-Channel connection accepted on channel %lu\n", |
315 | sc_adapter[card]->devicename, channel+1); | 307 | sc_adapter[card]->devicename, channel+1); |
316 | indicate_status(card, ISDN_STAT_BCONN, channel, NULL); | 308 | indicate_status(card, ISDN_STAT_BCONN, channel, NULL); |
317 | return 0; | 309 | return 0; |
@@ -326,7 +318,7 @@ static int clreaz(int card, unsigned long arg) | |||
326 | 318 | ||
327 | strcpy(sc_adapter[card]->channel[arg].eazlist, ""); | 319 | strcpy(sc_adapter[card]->channel[arg].eazlist, ""); |
328 | sc_adapter[card]->channel[arg].eazclear = 1; | 320 | sc_adapter[card]->channel[arg].eazclear = 1; |
329 | pr_debug("%s: EAZ List cleared for channel %d\n", | 321 | pr_debug("%s: EAZ List cleared for channel %lu\n", |
330 | sc_adapter[card]->devicename, arg+1); | 322 | sc_adapter[card]->devicename, arg+1); |
331 | return 0; | 323 | return 0; |
332 | } | 324 | } |
@@ -340,7 +332,7 @@ static int seteaz(int card, unsigned long arg, char *num) | |||
340 | 332 | ||
341 | strcpy(sc_adapter[card]->channel[arg].eazlist, num); | 333 | strcpy(sc_adapter[card]->channel[arg].eazlist, num); |
342 | sc_adapter[card]->channel[arg].eazclear = 0; | 334 | sc_adapter[card]->channel[arg].eazclear = 0; |
343 | pr_debug("%s: EAZ list for channel %d set to: %s\n", | 335 | pr_debug("%s: EAZ list for channel %lu set to: %s\n", |
344 | sc_adapter[card]->devicename, arg+1, | 336 | sc_adapter[card]->devicename, arg+1, |
345 | sc_adapter[card]->channel[arg].eazlist); | 337 | sc_adapter[card]->channel[arg].eazlist); |
346 | return 0; | 338 | return 0; |
diff --git a/drivers/isdn/sc/event.c b/drivers/isdn/sc/event.c index 5b8c7c1a7663..57367325ef04 100644 --- a/drivers/isdn/sc/event.c +++ b/drivers/isdn/sc/event.c | |||
@@ -45,8 +45,10 @@ int indicate_status(int card, int event,ulong Channel,char *Data) | |||
45 | { | 45 | { |
46 | isdn_ctrl cmd; | 46 | isdn_ctrl cmd; |
47 | 47 | ||
48 | #ifdef DEBUG | ||
48 | pr_debug("%s: Indicating event %s on Channel %d\n", | 49 | pr_debug("%s: Indicating event %s on Channel %d\n", |
49 | sc_adapter[card]->devicename, events[event-256], Channel); | 50 | sc_adapter[card]->devicename, events[event-256], Channel); |
51 | #endif | ||
50 | if (Data != NULL){ | 52 | if (Data != NULL){ |
51 | pr_debug("%s: Event data: %s\n", sc_adapter[card]->devicename, | 53 | pr_debug("%s: Event data: %s\n", sc_adapter[card]->devicename, |
52 | Data); | 54 | Data); |
diff --git a/drivers/isdn/sc/interrupt.c b/drivers/isdn/sc/interrupt.c index 8631d338d69a..ae6263125ac2 100644 --- a/drivers/isdn/sc/interrupt.c +++ b/drivers/isdn/sc/interrupt.c | |||
@@ -91,7 +91,7 @@ irqreturn_t interrupt_handler(int interrupt, void *cardptr, struct pt_regs *regs | |||
91 | */ | 91 | */ |
92 | if (IS_CE_MESSAGE(rcvmsg, Lnk, 1, Read)) | 92 | if (IS_CE_MESSAGE(rcvmsg, Lnk, 1, Read)) |
93 | { | 93 | { |
94 | pr_debug("%s: Received packet 0x%x bytes long at 0x%x\n", | 94 | pr_debug("%s: Received packet 0x%x bytes long at 0x%lx\n", |
95 | sc_adapter[card]->devicename, | 95 | sc_adapter[card]->devicename, |
96 | rcvmsg.msg_data.response.msg_len, | 96 | rcvmsg.msg_data.response.msg_len, |
97 | rcvmsg.msg_data.response.buff_offset); | 97 | rcvmsg.msg_data.response.buff_offset); |
diff --git a/drivers/isdn/sc/timer.c b/drivers/isdn/sc/timer.c index aced19aac5a2..f43282be0ada 100644 --- a/drivers/isdn/sc/timer.c +++ b/drivers/isdn/sc/timer.c | |||
@@ -76,7 +76,7 @@ void check_reset(unsigned long data) | |||
76 | if (sc_adapter[card]->StartOnReset) | 76 | if (sc_adapter[card]->StartOnReset) |
77 | startproc(card); | 77 | startproc(card); |
78 | } else { | 78 | } else { |
79 | pr_debug("%s: No signature yet, waiting another %d jiffies.\n", | 79 | pr_debug("%s: No signature yet, waiting another %lu jiffies.\n", |
80 | sc_adapter[card]->devicename, CHECKRESET_TIME); | 80 | sc_adapter[card]->devicename, CHECKRESET_TIME); |
81 | mod_timer(&sc_adapter[card]->reset_timer, jiffies+CHECKRESET_TIME); | 81 | mod_timer(&sc_adapter[card]->reset_timer, jiffies+CHECKRESET_TIME); |
82 | spin_unlock_irqrestore(&sc_adapter[card]->lock, flags); | 82 | spin_unlock_irqrestore(&sc_adapter[card]->lock, flags); |
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 80b89649e676..4f04fd0956a0 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c | |||
@@ -336,8 +336,10 @@ int __init find_via_pmu(void) | |||
336 | if (gaddr != OF_BAD_ADDR) | 336 | if (gaddr != OF_BAD_ADDR) |
337 | gpio_reg = ioremap(gaddr, 0x10); | 337 | gpio_reg = ioremap(gaddr, 0x10); |
338 | } | 338 | } |
339 | if (gpio_reg == NULL) | 339 | if (gpio_reg == NULL) { |
340 | printk(KERN_ERR "via-pmu: Can't find GPIO reg !\n"); | 340 | printk(KERN_ERR "via-pmu: Can't find GPIO reg !\n"); |
341 | goto fail_gpio; | ||
342 | } | ||
341 | } else | 343 | } else |
342 | pmu_kind = PMU_UNKNOWN; | 344 | pmu_kind = PMU_UNKNOWN; |
343 | 345 | ||
@@ -365,6 +367,9 @@ int __init find_via_pmu(void) | |||
365 | return 1; | 367 | return 1; |
366 | fail: | 368 | fail: |
367 | of_node_put(vias); | 369 | of_node_put(vias); |
370 | iounmap(gpio_reg); | ||
371 | gpio_reg = NULL; | ||
372 | fail_gpio: | ||
368 | vias = NULL; | 373 | vias = NULL; |
369 | return 0; | 374 | return 0; |
370 | } | 375 | } |
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig index 6dd31a291d84..c92c1521546d 100644 --- a/drivers/md/Kconfig +++ b/drivers/md/Kconfig | |||
@@ -138,16 +138,16 @@ config MD_RAID456 | |||
138 | If unsure, say Y. | 138 | If unsure, say Y. |
139 | 139 | ||
140 | config MD_RAID5_RESHAPE | 140 | config MD_RAID5_RESHAPE |
141 | bool "Support adding drives to a raid-5 array (experimental)" | 141 | bool "Support adding drives to a raid-5 array" |
142 | depends on MD_RAID456 && EXPERIMENTAL | 142 | depends on MD_RAID456 |
143 | default y | ||
143 | ---help--- | 144 | ---help--- |
144 | A RAID-5 set can be expanded by adding extra drives. This | 145 | A RAID-5 set can be expanded by adding extra drives. This |
145 | requires "restriping" the array which means (almost) every | 146 | requires "restriping" the array which means (almost) every |
146 | block must be written to a different place. | 147 | block must be written to a different place. |
147 | 148 | ||
148 | This option allows such restriping to be done while the array | 149 | This option allows such restriping to be done while the array |
149 | is online. However it is still EXPERIMENTAL code. It should | 150 | is online. |
150 | work, but please be sure that you have backups. | ||
151 | 151 | ||
152 | You will need mdadm version 2.4.1 or later to use this | 152 | You will need mdadm version 2.4.1 or later to use this |
153 | feature safely. During the early stage of reshape there is | 153 | feature safely. During the early stage of reshape there is |
@@ -164,6 +164,8 @@ config MD_RAID5_RESHAPE | |||
164 | There should be enough spares already present to make the new | 164 | There should be enough spares already present to make the new |
165 | array workable. | 165 | array workable. |
166 | 166 | ||
167 | If unsure, say Y. | ||
168 | |||
167 | config MD_MULTIPATH | 169 | config MD_MULTIPATH |
168 | tristate "Multipath I/O support" | 170 | tristate "Multipath I/O support" |
169 | depends on BLK_DEV_MD | 171 | depends on BLK_DEV_MD |
@@ -201,6 +203,14 @@ config BLK_DEV_DM | |||
201 | 203 | ||
202 | If unsure, say N. | 204 | If unsure, say N. |
203 | 205 | ||
206 | config DM_DEBUG | ||
207 | boolean "Device mapper debugging support" | ||
208 | depends on BLK_DEV_DM && EXPERIMENTAL | ||
209 | ---help--- | ||
210 | Enable this for messages that may help debug device-mapper problems. | ||
211 | |||
212 | If unsure, say N. | ||
213 | |||
204 | config DM_CRYPT | 214 | config DM_CRYPT |
205 | tristate "Crypt target support" | 215 | tristate "Crypt target support" |
206 | depends on BLK_DEV_DM && EXPERIMENTAL | 216 | depends on BLK_DEV_DM && EXPERIMENTAL |
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index ecc56765d949..8e67634e79a0 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -613,6 +613,7 @@ static inline unsigned long file_page_offset(unsigned long chunk) | |||
613 | static inline struct page *filemap_get_page(struct bitmap *bitmap, | 613 | static inline struct page *filemap_get_page(struct bitmap *bitmap, |
614 | unsigned long chunk) | 614 | unsigned long chunk) |
615 | { | 615 | { |
616 | if (file_page_index(chunk) >= bitmap->file_pages) return NULL; | ||
616 | return bitmap->filemap[file_page_index(chunk) - file_page_index(0)]; | 617 | return bitmap->filemap[file_page_index(chunk) - file_page_index(0)]; |
617 | } | 618 | } |
618 | 619 | ||
@@ -739,6 +740,7 @@ static void bitmap_file_set_bit(struct bitmap *bitmap, sector_t block) | |||
739 | } | 740 | } |
740 | 741 | ||
741 | page = filemap_get_page(bitmap, chunk); | 742 | page = filemap_get_page(bitmap, chunk); |
743 | if (!page) return; | ||
742 | bit = file_page_offset(chunk); | 744 | bit = file_page_offset(chunk); |
743 | 745 | ||
744 | /* set the bit */ | 746 | /* set the bit */ |
@@ -1322,6 +1324,18 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int n | |||
1322 | 1324 | ||
1323 | } | 1325 | } |
1324 | 1326 | ||
1327 | /* dirty the memory and file bits for bitmap chunks "s" to "e" */ | ||
1328 | void bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e) | ||
1329 | { | ||
1330 | unsigned long chunk; | ||
1331 | |||
1332 | for (chunk = s; chunk <= e; chunk++) { | ||
1333 | sector_t sec = chunk << CHUNK_BLOCK_SHIFT(bitmap); | ||
1334 | bitmap_set_memory_bits(bitmap, sec, 1); | ||
1335 | bitmap_file_set_bit(bitmap, sec); | ||
1336 | } | ||
1337 | } | ||
1338 | |||
1325 | /* | 1339 | /* |
1326 | * flush out any pending updates | 1340 | * flush out any pending updates |
1327 | */ | 1341 | */ |
@@ -1430,8 +1444,7 @@ int bitmap_create(mddev_t *mddev) | |||
1430 | if (err) | 1444 | if (err) |
1431 | goto error; | 1445 | goto error; |
1432 | 1446 | ||
1433 | bitmap->chunkshift = find_first_bit(&bitmap->chunksize, | 1447 | bitmap->chunkshift = ffz(~bitmap->chunksize); |
1434 | sizeof(bitmap->chunksize)); | ||
1435 | 1448 | ||
1436 | /* now that chunksize and chunkshift are set, we can use these macros */ | 1449 | /* now that chunksize and chunkshift are set, we can use these macros */ |
1437 | chunks = (blocks + CHUNK_BLOCK_RATIO(bitmap) - 1) / | 1450 | chunks = (blocks + CHUNK_BLOCK_RATIO(bitmap) - 1) / |
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index bdbd34993a80..655d816760e5 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2003 Christophe Saout <christophe@saout.de> | 2 | * Copyright (C) 2003 Christophe Saout <christophe@saout.de> |
3 | * Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org> | 3 | * Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org> |
4 | * Copyright (C) 2006 Red Hat, Inc. All rights reserved. | ||
4 | * | 5 | * |
5 | * This file is released under the GPL. | 6 | * This file is released under the GPL. |
6 | */ | 7 | */ |
@@ -22,17 +23,19 @@ | |||
22 | #include "dm.h" | 23 | #include "dm.h" |
23 | 24 | ||
24 | #define DM_MSG_PREFIX "crypt" | 25 | #define DM_MSG_PREFIX "crypt" |
26 | #define MESG_STR(x) x, sizeof(x) | ||
25 | 27 | ||
26 | /* | 28 | /* |
27 | * per bio private data | 29 | * per bio private data |
28 | */ | 30 | */ |
29 | struct crypt_io { | 31 | struct crypt_io { |
30 | struct dm_target *target; | 32 | struct dm_target *target; |
31 | struct bio *bio; | 33 | struct bio *base_bio; |
32 | struct bio *first_clone; | 34 | struct bio *first_clone; |
33 | struct work_struct work; | 35 | struct work_struct work; |
34 | atomic_t pending; | 36 | atomic_t pending; |
35 | int error; | 37 | int error; |
38 | int post_process; | ||
36 | }; | 39 | }; |
37 | 40 | ||
38 | /* | 41 | /* |
@@ -63,6 +66,7 @@ struct crypt_iv_operations { | |||
63 | * Crypt: maps a linear range of a block device | 66 | * Crypt: maps a linear range of a block device |
64 | * and encrypts / decrypts at the same time. | 67 | * and encrypts / decrypts at the same time. |
65 | */ | 68 | */ |
69 | enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID }; | ||
66 | struct crypt_config { | 70 | struct crypt_config { |
67 | struct dm_dev *dev; | 71 | struct dm_dev *dev; |
68 | sector_t start; | 72 | sector_t start; |
@@ -73,6 +77,7 @@ struct crypt_config { | |||
73 | */ | 77 | */ |
74 | mempool_t *io_pool; | 78 | mempool_t *io_pool; |
75 | mempool_t *page_pool; | 79 | mempool_t *page_pool; |
80 | struct bio_set *bs; | ||
76 | 81 | ||
77 | /* | 82 | /* |
78 | * crypto related data | 83 | * crypto related data |
@@ -86,11 +91,12 @@ struct crypt_config { | |||
86 | char cipher[CRYPTO_MAX_ALG_NAME]; | 91 | char cipher[CRYPTO_MAX_ALG_NAME]; |
87 | char chainmode[CRYPTO_MAX_ALG_NAME]; | 92 | char chainmode[CRYPTO_MAX_ALG_NAME]; |
88 | struct crypto_blkcipher *tfm; | 93 | struct crypto_blkcipher *tfm; |
94 | unsigned long flags; | ||
89 | unsigned int key_size; | 95 | unsigned int key_size; |
90 | u8 key[0]; | 96 | u8 key[0]; |
91 | }; | 97 | }; |
92 | 98 | ||
93 | #define MIN_IOS 256 | 99 | #define MIN_IOS 16 |
94 | #define MIN_POOL_PAGES 32 | 100 | #define MIN_POOL_PAGES 32 |
95 | #define MIN_BIO_PAGES 8 | 101 | #define MIN_BIO_PAGES 8 |
96 | 102 | ||
@@ -306,6 +312,14 @@ static int crypt_convert(struct crypt_config *cc, | |||
306 | return r; | 312 | return r; |
307 | } | 313 | } |
308 | 314 | ||
315 | static void dm_crypt_bio_destructor(struct bio *bio) | ||
316 | { | ||
317 | struct crypt_io *io = bio->bi_private; | ||
318 | struct crypt_config *cc = io->target->private; | ||
319 | |||
320 | bio_free(bio, cc->bs); | ||
321 | } | ||
322 | |||
309 | /* | 323 | /* |
310 | * Generate a new unfragmented bio with the given size | 324 | * Generate a new unfragmented bio with the given size |
311 | * This should never violate the device limitations | 325 | * This should never violate the device limitations |
@@ -315,34 +329,33 @@ static struct bio * | |||
315 | crypt_alloc_buffer(struct crypt_config *cc, unsigned int size, | 329 | crypt_alloc_buffer(struct crypt_config *cc, unsigned int size, |
316 | struct bio *base_bio, unsigned int *bio_vec_idx) | 330 | struct bio *base_bio, unsigned int *bio_vec_idx) |
317 | { | 331 | { |
318 | struct bio *bio; | 332 | struct bio *clone; |
319 | unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; | 333 | unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; |
320 | gfp_t gfp_mask = GFP_NOIO | __GFP_HIGHMEM; | 334 | gfp_t gfp_mask = GFP_NOIO | __GFP_HIGHMEM; |
321 | unsigned int i; | 335 | unsigned int i; |
322 | 336 | ||
323 | /* | 337 | if (base_bio) { |
324 | * Use __GFP_NOMEMALLOC to tell the VM to act less aggressively and | 338 | clone = bio_alloc_bioset(GFP_NOIO, base_bio->bi_max_vecs, cc->bs); |
325 | * to fail earlier. This is not necessary but increases throughput. | 339 | __bio_clone(clone, base_bio); |
326 | * FIXME: Is this really intelligent? | 340 | } else |
327 | */ | 341 | clone = bio_alloc_bioset(GFP_NOIO, nr_iovecs, cc->bs); |
328 | if (base_bio) | 342 | |
329 | bio = bio_clone(base_bio, GFP_NOIO|__GFP_NOMEMALLOC); | 343 | if (!clone) |
330 | else | ||
331 | bio = bio_alloc(GFP_NOIO|__GFP_NOMEMALLOC, nr_iovecs); | ||
332 | if (!bio) | ||
333 | return NULL; | 344 | return NULL; |
334 | 345 | ||
346 | clone->bi_destructor = dm_crypt_bio_destructor; | ||
347 | |||
335 | /* if the last bio was not complete, continue where that one ended */ | 348 | /* if the last bio was not complete, continue where that one ended */ |
336 | bio->bi_idx = *bio_vec_idx; | 349 | clone->bi_idx = *bio_vec_idx; |
337 | bio->bi_vcnt = *bio_vec_idx; | 350 | clone->bi_vcnt = *bio_vec_idx; |
338 | bio->bi_size = 0; | 351 | clone->bi_size = 0; |
339 | bio->bi_flags &= ~(1 << BIO_SEG_VALID); | 352 | clone->bi_flags &= ~(1 << BIO_SEG_VALID); |
340 | 353 | ||
341 | /* bio->bi_idx pages have already been allocated */ | 354 | /* clone->bi_idx pages have already been allocated */ |
342 | size -= bio->bi_idx * PAGE_SIZE; | 355 | size -= clone->bi_idx * PAGE_SIZE; |
343 | 356 | ||
344 | for(i = bio->bi_idx; i < nr_iovecs; i++) { | 357 | for (i = clone->bi_idx; i < nr_iovecs; i++) { |
345 | struct bio_vec *bv = bio_iovec_idx(bio, i); | 358 | struct bio_vec *bv = bio_iovec_idx(clone, i); |
346 | 359 | ||
347 | bv->bv_page = mempool_alloc(cc->page_pool, gfp_mask); | 360 | bv->bv_page = mempool_alloc(cc->page_pool, gfp_mask); |
348 | if (!bv->bv_page) | 361 | if (!bv->bv_page) |
@@ -353,7 +366,7 @@ crypt_alloc_buffer(struct crypt_config *cc, unsigned int size, | |||
353 | * return a partially allocated bio, the caller will then try | 366 | * return a partially allocated bio, the caller will then try |
354 | * to allocate additional bios while submitting this partial bio | 367 | * to allocate additional bios while submitting this partial bio |
355 | */ | 368 | */ |
356 | if ((i - bio->bi_idx) == (MIN_BIO_PAGES - 1)) | 369 | if ((i - clone->bi_idx) == (MIN_BIO_PAGES - 1)) |
357 | gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT; | 370 | gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT; |
358 | 371 | ||
359 | bv->bv_offset = 0; | 372 | bv->bv_offset = 0; |
@@ -362,13 +375,13 @@ crypt_alloc_buffer(struct crypt_config *cc, unsigned int size, | |||
362 | else | 375 | else |
363 | bv->bv_len = size; | 376 | bv->bv_len = size; |
364 | 377 | ||
365 | bio->bi_size += bv->bv_len; | 378 | clone->bi_size += bv->bv_len; |
366 | bio->bi_vcnt++; | 379 | clone->bi_vcnt++; |
367 | size -= bv->bv_len; | 380 | size -= bv->bv_len; |
368 | } | 381 | } |
369 | 382 | ||
370 | if (!bio->bi_size) { | 383 | if (!clone->bi_size) { |
371 | bio_put(bio); | 384 | bio_put(clone); |
372 | return NULL; | 385 | return NULL; |
373 | } | 386 | } |
374 | 387 | ||
@@ -376,13 +389,13 @@ crypt_alloc_buffer(struct crypt_config *cc, unsigned int size, | |||
376 | * Remember the last bio_vec allocated to be able | 389 | * Remember the last bio_vec allocated to be able |
377 | * to correctly continue after the splitting. | 390 | * to correctly continue after the splitting. |
378 | */ | 391 | */ |
379 | *bio_vec_idx = bio->bi_vcnt; | 392 | *bio_vec_idx = clone->bi_vcnt; |
380 | 393 | ||
381 | return bio; | 394 | return clone; |
382 | } | 395 | } |
383 | 396 | ||
384 | static void crypt_free_buffer_pages(struct crypt_config *cc, | 397 | static void crypt_free_buffer_pages(struct crypt_config *cc, |
385 | struct bio *bio, unsigned int bytes) | 398 | struct bio *clone, unsigned int bytes) |
386 | { | 399 | { |
387 | unsigned int i, start, end; | 400 | unsigned int i, start, end; |
388 | struct bio_vec *bv; | 401 | struct bio_vec *bv; |
@@ -396,19 +409,19 @@ static void crypt_free_buffer_pages(struct crypt_config *cc, | |||
396 | * A fix to the bi_idx issue in the kernel is in the works, so | 409 | * A fix to the bi_idx issue in the kernel is in the works, so |
397 | * we will hopefully be able to revert to the cleaner solution soon. | 410 | * we will hopefully be able to revert to the cleaner solution soon. |
398 | */ | 411 | */ |
399 | i = bio->bi_vcnt - 1; | 412 | i = clone->bi_vcnt - 1; |
400 | bv = bio_iovec_idx(bio, i); | 413 | bv = bio_iovec_idx(clone, i); |
401 | end = (i << PAGE_SHIFT) + (bv->bv_offset + bv->bv_len) - bio->bi_size; | 414 | end = (i << PAGE_SHIFT) + (bv->bv_offset + bv->bv_len) - clone->bi_size; |
402 | start = end - bytes; | 415 | start = end - bytes; |
403 | 416 | ||
404 | start >>= PAGE_SHIFT; | 417 | start >>= PAGE_SHIFT; |
405 | if (!bio->bi_size) | 418 | if (!clone->bi_size) |
406 | end = bio->bi_vcnt; | 419 | end = clone->bi_vcnt; |
407 | else | 420 | else |
408 | end >>= PAGE_SHIFT; | 421 | end >>= PAGE_SHIFT; |
409 | 422 | ||
410 | for(i = start; i < end; i++) { | 423 | for (i = start; i < end; i++) { |
411 | bv = bio_iovec_idx(bio, i); | 424 | bv = bio_iovec_idx(clone, i); |
412 | BUG_ON(!bv->bv_page); | 425 | BUG_ON(!bv->bv_page); |
413 | mempool_free(bv->bv_page, cc->page_pool); | 426 | mempool_free(bv->bv_page, cc->page_pool); |
414 | bv->bv_page = NULL; | 427 | bv->bv_page = NULL; |
@@ -432,7 +445,7 @@ static void dec_pending(struct crypt_io *io, int error) | |||
432 | if (io->first_clone) | 445 | if (io->first_clone) |
433 | bio_put(io->first_clone); | 446 | bio_put(io->first_clone); |
434 | 447 | ||
435 | bio_endio(io->bio, io->bio->bi_size, io->error); | 448 | bio_endio(io->base_bio, io->base_bio->bi_size, io->error); |
436 | 449 | ||
437 | mempool_free(io, cc->io_pool); | 450 | mempool_free(io, cc->io_pool); |
438 | } | 451 | } |
@@ -441,29 +454,179 @@ static void dec_pending(struct crypt_io *io, int error) | |||
441 | * kcryptd: | 454 | * kcryptd: |
442 | * | 455 | * |
443 | * Needed because it would be very unwise to do decryption in an | 456 | * Needed because it would be very unwise to do decryption in an |
444 | * interrupt context, so bios returning from read requests get | 457 | * interrupt context. |
445 | * queued here. | ||
446 | */ | 458 | */ |
447 | static struct workqueue_struct *_kcryptd_workqueue; | 459 | static struct workqueue_struct *_kcryptd_workqueue; |
460 | static void kcryptd_do_work(void *data); | ||
448 | 461 | ||
449 | static void kcryptd_do_work(void *data) | 462 | static void kcryptd_queue_io(struct crypt_io *io) |
450 | { | 463 | { |
451 | struct crypt_io *io = (struct crypt_io *) data; | 464 | INIT_WORK(&io->work, kcryptd_do_work, io); |
452 | struct crypt_config *cc = (struct crypt_config *) io->target->private; | 465 | queue_work(_kcryptd_workqueue, &io->work); |
466 | } | ||
467 | |||
468 | static int crypt_endio(struct bio *clone, unsigned int done, int error) | ||
469 | { | ||
470 | struct crypt_io *io = clone->bi_private; | ||
471 | struct crypt_config *cc = io->target->private; | ||
472 | unsigned read_io = bio_data_dir(clone) == READ; | ||
473 | |||
474 | /* | ||
475 | * free the processed pages, even if | ||
476 | * it's only a partially completed write | ||
477 | */ | ||
478 | if (!read_io) | ||
479 | crypt_free_buffer_pages(cc, clone, done); | ||
480 | |||
481 | /* keep going - not finished yet */ | ||
482 | if (unlikely(clone->bi_size)) | ||
483 | return 1; | ||
484 | |||
485 | if (!read_io) | ||
486 | goto out; | ||
487 | |||
488 | if (unlikely(!bio_flagged(clone, BIO_UPTODATE))) { | ||
489 | error = -EIO; | ||
490 | goto out; | ||
491 | } | ||
492 | |||
493 | bio_put(clone); | ||
494 | io->post_process = 1; | ||
495 | kcryptd_queue_io(io); | ||
496 | return 0; | ||
497 | |||
498 | out: | ||
499 | bio_put(clone); | ||
500 | dec_pending(io, error); | ||
501 | return error; | ||
502 | } | ||
503 | |||
504 | static void clone_init(struct crypt_io *io, struct bio *clone) | ||
505 | { | ||
506 | struct crypt_config *cc = io->target->private; | ||
507 | |||
508 | clone->bi_private = io; | ||
509 | clone->bi_end_io = crypt_endio; | ||
510 | clone->bi_bdev = cc->dev->bdev; | ||
511 | clone->bi_rw = io->base_bio->bi_rw; | ||
512 | } | ||
513 | |||
514 | static void process_read(struct crypt_io *io) | ||
515 | { | ||
516 | struct crypt_config *cc = io->target->private; | ||
517 | struct bio *base_bio = io->base_bio; | ||
518 | struct bio *clone; | ||
519 | sector_t sector = base_bio->bi_sector - io->target->begin; | ||
520 | |||
521 | atomic_inc(&io->pending); | ||
522 | |||
523 | /* | ||
524 | * The block layer might modify the bvec array, so always | ||
525 | * copy the required bvecs because we need the original | ||
526 | * one in order to decrypt the whole bio data *afterwards*. | ||
527 | */ | ||
528 | clone = bio_alloc_bioset(GFP_NOIO, bio_segments(base_bio), cc->bs); | ||
529 | if (unlikely(!clone)) { | ||
530 | dec_pending(io, -ENOMEM); | ||
531 | return; | ||
532 | } | ||
533 | |||
534 | clone_init(io, clone); | ||
535 | clone->bi_destructor = dm_crypt_bio_destructor; | ||
536 | clone->bi_idx = 0; | ||
537 | clone->bi_vcnt = bio_segments(base_bio); | ||
538 | clone->bi_size = base_bio->bi_size; | ||
539 | clone->bi_sector = cc->start + sector; | ||
540 | memcpy(clone->bi_io_vec, bio_iovec(base_bio), | ||
541 | sizeof(struct bio_vec) * clone->bi_vcnt); | ||
542 | |||
543 | generic_make_request(clone); | ||
544 | } | ||
545 | |||
546 | static void process_write(struct crypt_io *io) | ||
547 | { | ||
548 | struct crypt_config *cc = io->target->private; | ||
549 | struct bio *base_bio = io->base_bio; | ||
550 | struct bio *clone; | ||
453 | struct convert_context ctx; | 551 | struct convert_context ctx; |
454 | int r; | 552 | unsigned remaining = base_bio->bi_size; |
553 | sector_t sector = base_bio->bi_sector - io->target->begin; | ||
554 | unsigned bvec_idx = 0; | ||
555 | |||
556 | atomic_inc(&io->pending); | ||
557 | |||
558 | crypt_convert_init(cc, &ctx, NULL, base_bio, sector, 1); | ||
559 | |||
560 | /* | ||
561 | * The allocated buffers can be smaller than the whole bio, | ||
562 | * so repeat the whole process until all the data can be handled. | ||
563 | */ | ||
564 | while (remaining) { | ||
565 | clone = crypt_alloc_buffer(cc, base_bio->bi_size, | ||
566 | io->first_clone, &bvec_idx); | ||
567 | if (unlikely(!clone)) { | ||
568 | dec_pending(io, -ENOMEM); | ||
569 | return; | ||
570 | } | ||
571 | |||
572 | ctx.bio_out = clone; | ||
573 | |||
574 | if (unlikely(crypt_convert(cc, &ctx) < 0)) { | ||
575 | crypt_free_buffer_pages(cc, clone, clone->bi_size); | ||
576 | bio_put(clone); | ||
577 | dec_pending(io, -EIO); | ||
578 | return; | ||
579 | } | ||
580 | |||
581 | clone_init(io, clone); | ||
582 | clone->bi_sector = cc->start + sector; | ||
583 | |||
584 | if (!io->first_clone) { | ||
585 | /* | ||
586 | * hold a reference to the first clone, because it | ||
587 | * holds the bio_vec array and that can't be freed | ||
588 | * before all other clones are released | ||
589 | */ | ||
590 | bio_get(clone); | ||
591 | io->first_clone = clone; | ||
592 | } | ||
593 | |||
594 | remaining -= clone->bi_size; | ||
595 | sector += bio_sectors(clone); | ||
596 | |||
597 | /* prevent bio_put of first_clone */ | ||
598 | if (remaining) | ||
599 | atomic_inc(&io->pending); | ||
455 | 600 | ||
456 | crypt_convert_init(cc, &ctx, io->bio, io->bio, | 601 | generic_make_request(clone); |
457 | io->bio->bi_sector - io->target->begin, 0); | ||
458 | r = crypt_convert(cc, &ctx); | ||
459 | 602 | ||
460 | dec_pending(io, r); | 603 | /* out of memory -> run queues */ |
604 | if (remaining) | ||
605 | blk_congestion_wait(bio_data_dir(clone), HZ/100); | ||
606 | } | ||
461 | } | 607 | } |
462 | 608 | ||
463 | static void kcryptd_queue_io(struct crypt_io *io) | 609 | static void process_read_endio(struct crypt_io *io) |
464 | { | 610 | { |
465 | INIT_WORK(&io->work, kcryptd_do_work, io); | 611 | struct crypt_config *cc = io->target->private; |
466 | queue_work(_kcryptd_workqueue, &io->work); | 612 | struct convert_context ctx; |
613 | |||
614 | crypt_convert_init(cc, &ctx, io->base_bio, io->base_bio, | ||
615 | io->base_bio->bi_sector - io->target->begin, 0); | ||
616 | |||
617 | dec_pending(io, crypt_convert(cc, &ctx)); | ||
618 | } | ||
619 | |||
620 | static void kcryptd_do_work(void *data) | ||
621 | { | ||
622 | struct crypt_io *io = data; | ||
623 | |||
624 | if (io->post_process) | ||
625 | process_read_endio(io); | ||
626 | else if (bio_data_dir(io->base_bio) == READ) | ||
627 | process_read(io); | ||
628 | else | ||
629 | process_write(io); | ||
467 | } | 630 | } |
468 | 631 | ||
469 | /* | 632 | /* |
@@ -477,7 +640,7 @@ static int crypt_decode_key(u8 *key, char *hex, unsigned int size) | |||
477 | 640 | ||
478 | buffer[2] = '\0'; | 641 | buffer[2] = '\0'; |
479 | 642 | ||
480 | for(i = 0; i < size; i++) { | 643 | for (i = 0; i < size; i++) { |
481 | buffer[0] = *hex++; | 644 | buffer[0] = *hex++; |
482 | buffer[1] = *hex++; | 645 | buffer[1] = *hex++; |
483 | 646 | ||
@@ -500,13 +663,38 @@ static void crypt_encode_key(char *hex, u8 *key, unsigned int size) | |||
500 | { | 663 | { |
501 | unsigned int i; | 664 | unsigned int i; |
502 | 665 | ||
503 | for(i = 0; i < size; i++) { | 666 | for (i = 0; i < size; i++) { |
504 | sprintf(hex, "%02x", *key); | 667 | sprintf(hex, "%02x", *key); |
505 | hex += 2; | 668 | hex += 2; |
506 | key++; | 669 | key++; |
507 | } | 670 | } |
508 | } | 671 | } |
509 | 672 | ||
673 | static int crypt_set_key(struct crypt_config *cc, char *key) | ||
674 | { | ||
675 | unsigned key_size = strlen(key) >> 1; | ||
676 | |||
677 | if (cc->key_size && cc->key_size != key_size) | ||
678 | return -EINVAL; | ||
679 | |||
680 | cc->key_size = key_size; /* initial settings */ | ||
681 | |||
682 | if ((!key_size && strcmp(key, "-")) || | ||
683 | (key_size && crypt_decode_key(cc->key, key, key_size) < 0)) | ||
684 | return -EINVAL; | ||
685 | |||
686 | set_bit(DM_CRYPT_KEY_VALID, &cc->flags); | ||
687 | |||
688 | return 0; | ||
689 | } | ||
690 | |||
691 | static int crypt_wipe_key(struct crypt_config *cc) | ||
692 | { | ||
693 | clear_bit(DM_CRYPT_KEY_VALID, &cc->flags); | ||
694 | memset(&cc->key, 0, cc->key_size * sizeof(u8)); | ||
695 | return 0; | ||
696 | } | ||
697 | |||
510 | /* | 698 | /* |
511 | * Construct an encryption mapping: | 699 | * Construct an encryption mapping: |
512 | * <cipher> <key> <iv_offset> <dev_path> <start> | 700 | * <cipher> <key> <iv_offset> <dev_path> <start> |
@@ -539,16 +727,14 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
539 | 727 | ||
540 | key_size = strlen(argv[1]) >> 1; | 728 | key_size = strlen(argv[1]) >> 1; |
541 | 729 | ||
542 | cc = kmalloc(sizeof(*cc) + key_size * sizeof(u8), GFP_KERNEL); | 730 | cc = kzalloc(sizeof(*cc) + key_size * sizeof(u8), GFP_KERNEL); |
543 | if (cc == NULL) { | 731 | if (cc == NULL) { |
544 | ti->error = | 732 | ti->error = |
545 | "Cannot allocate transparent encryption context"; | 733 | "Cannot allocate transparent encryption context"; |
546 | return -ENOMEM; | 734 | return -ENOMEM; |
547 | } | 735 | } |
548 | 736 | ||
549 | cc->key_size = key_size; | 737 | if (crypt_set_key(cc, argv[1])) { |
550 | if ((!key_size && strcmp(argv[1], "-") != 0) || | ||
551 | (key_size && crypt_decode_key(cc->key, argv[1], key_size) < 0)) { | ||
552 | ti->error = "Error decoding key"; | 738 | ti->error = "Error decoding key"; |
553 | goto bad1; | 739 | goto bad1; |
554 | } | 740 | } |
@@ -626,6 +812,12 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
626 | goto bad4; | 812 | goto bad4; |
627 | } | 813 | } |
628 | 814 | ||
815 | cc->bs = bioset_create(MIN_IOS, MIN_IOS, 4); | ||
816 | if (!cc->bs) { | ||
817 | ti->error = "Cannot allocate crypt bioset"; | ||
818 | goto bad_bs; | ||
819 | } | ||
820 | |||
629 | if (crypto_blkcipher_setkey(tfm, cc->key, key_size) < 0) { | 821 | if (crypto_blkcipher_setkey(tfm, cc->key, key_size) < 0) { |
630 | ti->error = "Error setting key"; | 822 | ti->error = "Error setting key"; |
631 | goto bad5; | 823 | goto bad5; |
@@ -665,6 +857,8 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
665 | return 0; | 857 | return 0; |
666 | 858 | ||
667 | bad5: | 859 | bad5: |
860 | bioset_free(cc->bs); | ||
861 | bad_bs: | ||
668 | mempool_destroy(cc->page_pool); | 862 | mempool_destroy(cc->page_pool); |
669 | bad4: | 863 | bad4: |
670 | mempool_destroy(cc->io_pool); | 864 | mempool_destroy(cc->io_pool); |
@@ -684,6 +878,7 @@ static void crypt_dtr(struct dm_target *ti) | |||
684 | { | 878 | { |
685 | struct crypt_config *cc = (struct crypt_config *) ti->private; | 879 | struct crypt_config *cc = (struct crypt_config *) ti->private; |
686 | 880 | ||
881 | bioset_free(cc->bs); | ||
687 | mempool_destroy(cc->page_pool); | 882 | mempool_destroy(cc->page_pool); |
688 | mempool_destroy(cc->io_pool); | 883 | mempool_destroy(cc->io_pool); |
689 | 884 | ||
@@ -698,147 +893,21 @@ static void crypt_dtr(struct dm_target *ti) | |||
698 | kfree(cc); | 893 | kfree(cc); |
699 | } | 894 | } |
700 | 895 | ||
701 | static int crypt_endio(struct bio *bio, unsigned int done, int error) | ||
702 | { | ||
703 | struct crypt_io *io = (struct crypt_io *) bio->bi_private; | ||
704 | struct crypt_config *cc = (struct crypt_config *) io->target->private; | ||
705 | |||
706 | if (bio_data_dir(bio) == WRITE) { | ||
707 | /* | ||
708 | * free the processed pages, even if | ||
709 | * it's only a partially completed write | ||
710 | */ | ||
711 | crypt_free_buffer_pages(cc, bio, done); | ||
712 | } | ||
713 | |||
714 | if (bio->bi_size) | ||
715 | return 1; | ||
716 | |||
717 | bio_put(bio); | ||
718 | |||
719 | /* | ||
720 | * successful reads are decrypted by the worker thread | ||
721 | */ | ||
722 | if ((bio_data_dir(bio) == READ) | ||
723 | && bio_flagged(bio, BIO_UPTODATE)) { | ||
724 | kcryptd_queue_io(io); | ||
725 | return 0; | ||
726 | } | ||
727 | |||
728 | dec_pending(io, error); | ||
729 | return error; | ||
730 | } | ||
731 | |||
732 | static inline struct bio * | ||
733 | crypt_clone(struct crypt_config *cc, struct crypt_io *io, struct bio *bio, | ||
734 | sector_t sector, unsigned int *bvec_idx, | ||
735 | struct convert_context *ctx) | ||
736 | { | ||
737 | struct bio *clone; | ||
738 | |||
739 | if (bio_data_dir(bio) == WRITE) { | ||
740 | clone = crypt_alloc_buffer(cc, bio->bi_size, | ||
741 | io->first_clone, bvec_idx); | ||
742 | if (clone) { | ||
743 | ctx->bio_out = clone; | ||
744 | if (crypt_convert(cc, ctx) < 0) { | ||
745 | crypt_free_buffer_pages(cc, clone, | ||
746 | clone->bi_size); | ||
747 | bio_put(clone); | ||
748 | return NULL; | ||
749 | } | ||
750 | } | ||
751 | } else { | ||
752 | /* | ||
753 | * The block layer might modify the bvec array, so always | ||
754 | * copy the required bvecs because we need the original | ||
755 | * one in order to decrypt the whole bio data *afterwards*. | ||
756 | */ | ||
757 | clone = bio_alloc(GFP_NOIO, bio_segments(bio)); | ||
758 | if (clone) { | ||
759 | clone->bi_idx = 0; | ||
760 | clone->bi_vcnt = bio_segments(bio); | ||
761 | clone->bi_size = bio->bi_size; | ||
762 | memcpy(clone->bi_io_vec, bio_iovec(bio), | ||
763 | sizeof(struct bio_vec) * clone->bi_vcnt); | ||
764 | } | ||
765 | } | ||
766 | |||
767 | if (!clone) | ||
768 | return NULL; | ||
769 | |||
770 | clone->bi_private = io; | ||
771 | clone->bi_end_io = crypt_endio; | ||
772 | clone->bi_bdev = cc->dev->bdev; | ||
773 | clone->bi_sector = cc->start + sector; | ||
774 | clone->bi_rw = bio->bi_rw; | ||
775 | |||
776 | return clone; | ||
777 | } | ||
778 | |||
779 | static int crypt_map(struct dm_target *ti, struct bio *bio, | 896 | static int crypt_map(struct dm_target *ti, struct bio *bio, |
780 | union map_info *map_context) | 897 | union map_info *map_context) |
781 | { | 898 | { |
782 | struct crypt_config *cc = (struct crypt_config *) ti->private; | 899 | struct crypt_config *cc = ti->private; |
783 | struct crypt_io *io = mempool_alloc(cc->io_pool, GFP_NOIO); | 900 | struct crypt_io *io; |
784 | struct convert_context ctx; | ||
785 | struct bio *clone; | ||
786 | unsigned int remaining = bio->bi_size; | ||
787 | sector_t sector = bio->bi_sector - ti->begin; | ||
788 | unsigned int bvec_idx = 0; | ||
789 | 901 | ||
902 | io = mempool_alloc(cc->io_pool, GFP_NOIO); | ||
790 | io->target = ti; | 903 | io->target = ti; |
791 | io->bio = bio; | 904 | io->base_bio = bio; |
792 | io->first_clone = NULL; | 905 | io->first_clone = NULL; |
793 | io->error = 0; | 906 | io->error = io->post_process = 0; |
794 | atomic_set(&io->pending, 1); /* hold a reference */ | 907 | atomic_set(&io->pending, 0); |
795 | 908 | kcryptd_queue_io(io); | |
796 | if (bio_data_dir(bio) == WRITE) | ||
797 | crypt_convert_init(cc, &ctx, NULL, bio, sector, 1); | ||
798 | |||
799 | /* | ||
800 | * The allocated buffers can be smaller than the whole bio, | ||
801 | * so repeat the whole process until all the data can be handled. | ||
802 | */ | ||
803 | while (remaining) { | ||
804 | clone = crypt_clone(cc, io, bio, sector, &bvec_idx, &ctx); | ||
805 | if (!clone) | ||
806 | goto cleanup; | ||
807 | |||
808 | if (!io->first_clone) { | ||
809 | /* | ||
810 | * hold a reference to the first clone, because it | ||
811 | * holds the bio_vec array and that can't be freed | ||
812 | * before all other clones are released | ||
813 | */ | ||
814 | bio_get(clone); | ||
815 | io->first_clone = clone; | ||
816 | } | ||
817 | atomic_inc(&io->pending); | ||
818 | 909 | ||
819 | remaining -= clone->bi_size; | ||
820 | sector += bio_sectors(clone); | ||
821 | |||
822 | generic_make_request(clone); | ||
823 | |||
824 | /* out of memory -> run queues */ | ||
825 | if (remaining) | ||
826 | blk_congestion_wait(bio_data_dir(clone), HZ/100); | ||
827 | } | ||
828 | |||
829 | /* drop reference, clones could have returned before we reach this */ | ||
830 | dec_pending(io, 0); | ||
831 | return 0; | 910 | return 0; |
832 | |||
833 | cleanup: | ||
834 | if (io->first_clone) { | ||
835 | dec_pending(io, -ENOMEM); | ||
836 | return 0; | ||
837 | } | ||
838 | |||
839 | /* if no bio has been dispatched yet, we can directly return the error */ | ||
840 | mempool_free(io, cc->io_pool); | ||
841 | return -ENOMEM; | ||
842 | } | 911 | } |
843 | 912 | ||
844 | static int crypt_status(struct dm_target *ti, status_type_t type, | 913 | static int crypt_status(struct dm_target *ti, status_type_t type, |
@@ -883,14 +952,71 @@ static int crypt_status(struct dm_target *ti, status_type_t type, | |||
883 | return 0; | 952 | return 0; |
884 | } | 953 | } |
885 | 954 | ||
955 | static void crypt_postsuspend(struct dm_target *ti) | ||
956 | { | ||
957 | struct crypt_config *cc = ti->private; | ||
958 | |||
959 | set_bit(DM_CRYPT_SUSPENDED, &cc->flags); | ||
960 | } | ||
961 | |||
962 | static int crypt_preresume(struct dm_target *ti) | ||
963 | { | ||
964 | struct crypt_config *cc = ti->private; | ||
965 | |||
966 | if (!test_bit(DM_CRYPT_KEY_VALID, &cc->flags)) { | ||
967 | DMERR("aborting resume - crypt key is not set."); | ||
968 | return -EAGAIN; | ||
969 | } | ||
970 | |||
971 | return 0; | ||
972 | } | ||
973 | |||
974 | static void crypt_resume(struct dm_target *ti) | ||
975 | { | ||
976 | struct crypt_config *cc = ti->private; | ||
977 | |||
978 | clear_bit(DM_CRYPT_SUSPENDED, &cc->flags); | ||
979 | } | ||
980 | |||
981 | /* Message interface | ||
982 | * key set <key> | ||
983 | * key wipe | ||
984 | */ | ||
985 | static int crypt_message(struct dm_target *ti, unsigned argc, char **argv) | ||
986 | { | ||
987 | struct crypt_config *cc = ti->private; | ||
988 | |||
989 | if (argc < 2) | ||
990 | goto error; | ||
991 | |||
992 | if (!strnicmp(argv[0], MESG_STR("key"))) { | ||
993 | if (!test_bit(DM_CRYPT_SUSPENDED, &cc->flags)) { | ||
994 | DMWARN("not suspended during key manipulation."); | ||
995 | return -EINVAL; | ||
996 | } | ||
997 | if (argc == 3 && !strnicmp(argv[1], MESG_STR("set"))) | ||
998 | return crypt_set_key(cc, argv[2]); | ||
999 | if (argc == 2 && !strnicmp(argv[1], MESG_STR("wipe"))) | ||
1000 | return crypt_wipe_key(cc); | ||
1001 | } | ||
1002 | |||
1003 | error: | ||
1004 | DMWARN("unrecognised message received."); | ||
1005 | return -EINVAL; | ||
1006 | } | ||
1007 | |||
886 | static struct target_type crypt_target = { | 1008 | static struct target_type crypt_target = { |
887 | .name = "crypt", | 1009 | .name = "crypt", |
888 | .version= {1, 1, 0}, | 1010 | .version= {1, 3, 0}, |
889 | .module = THIS_MODULE, | 1011 | .module = THIS_MODULE, |
890 | .ctr = crypt_ctr, | 1012 | .ctr = crypt_ctr, |
891 | .dtr = crypt_dtr, | 1013 | .dtr = crypt_dtr, |
892 | .map = crypt_map, | 1014 | .map = crypt_map, |
893 | .status = crypt_status, | 1015 | .status = crypt_status, |
1016 | .postsuspend = crypt_postsuspend, | ||
1017 | .preresume = crypt_preresume, | ||
1018 | .resume = crypt_resume, | ||
1019 | .message = crypt_message, | ||
894 | }; | 1020 | }; |
895 | 1021 | ||
896 | static int __init dm_crypt_init(void) | 1022 | static int __init dm_crypt_init(void) |
diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c index d12379b5cdb5..99cdffa7fbfe 100644 --- a/drivers/md/dm-exception-store.c +++ b/drivers/md/dm-exception-store.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | 18 | ||
19 | #define DM_MSG_PREFIX "snapshots" | 19 | #define DM_MSG_PREFIX "snapshots" |
20 | #define DM_CHUNK_SIZE_DEFAULT_SECTORS 32 /* 16KB */ | ||
20 | 21 | ||
21 | /*----------------------------------------------------------------- | 22 | /*----------------------------------------------------------------- |
22 | * Persistent snapshots, by persistent we mean that the snapshot | 23 | * Persistent snapshots, by persistent we mean that the snapshot |
@@ -150,6 +151,7 @@ static int alloc_area(struct pstore *ps) | |||
150 | static void free_area(struct pstore *ps) | 151 | static void free_area(struct pstore *ps) |
151 | { | 152 | { |
152 | vfree(ps->area); | 153 | vfree(ps->area); |
154 | ps->area = NULL; | ||
153 | } | 155 | } |
154 | 156 | ||
155 | /* | 157 | /* |
@@ -198,48 +200,79 @@ static int read_header(struct pstore *ps, int *new_snapshot) | |||
198 | int r; | 200 | int r; |
199 | struct disk_header *dh; | 201 | struct disk_header *dh; |
200 | chunk_t chunk_size; | 202 | chunk_t chunk_size; |
203 | int chunk_size_supplied = 1; | ||
201 | 204 | ||
202 | r = chunk_io(ps, 0, READ); | 205 | /* |
206 | * Use default chunk size (or hardsect_size, if larger) if none supplied | ||
207 | */ | ||
208 | if (!ps->snap->chunk_size) { | ||
209 | ps->snap->chunk_size = max(DM_CHUNK_SIZE_DEFAULT_SECTORS, | ||
210 | bdev_hardsect_size(ps->snap->cow->bdev) >> 9); | ||
211 | ps->snap->chunk_mask = ps->snap->chunk_size - 1; | ||
212 | ps->snap->chunk_shift = ffs(ps->snap->chunk_size) - 1; | ||
213 | chunk_size_supplied = 0; | ||
214 | } | ||
215 | |||
216 | r = dm_io_get(sectors_to_pages(ps->snap->chunk_size)); | ||
203 | if (r) | 217 | if (r) |
204 | return r; | 218 | return r; |
205 | 219 | ||
220 | r = alloc_area(ps); | ||
221 | if (r) | ||
222 | goto bad1; | ||
223 | |||
224 | r = chunk_io(ps, 0, READ); | ||
225 | if (r) | ||
226 | goto bad2; | ||
227 | |||
206 | dh = (struct disk_header *) ps->area; | 228 | dh = (struct disk_header *) ps->area; |
207 | 229 | ||
208 | if (le32_to_cpu(dh->magic) == 0) { | 230 | if (le32_to_cpu(dh->magic) == 0) { |
209 | *new_snapshot = 1; | 231 | *new_snapshot = 1; |
232 | return 0; | ||
233 | } | ||
210 | 234 | ||
211 | } else if (le32_to_cpu(dh->magic) == SNAP_MAGIC) { | 235 | if (le32_to_cpu(dh->magic) != SNAP_MAGIC) { |
212 | *new_snapshot = 0; | 236 | DMWARN("Invalid or corrupt snapshot"); |
213 | ps->valid = le32_to_cpu(dh->valid); | ||
214 | ps->version = le32_to_cpu(dh->version); | ||
215 | chunk_size = le32_to_cpu(dh->chunk_size); | ||
216 | if (ps->snap->chunk_size != chunk_size) { | ||
217 | DMWARN("chunk size %llu in device metadata overrides " | ||
218 | "table chunk size of %llu.", | ||
219 | (unsigned long long)chunk_size, | ||
220 | (unsigned long long)ps->snap->chunk_size); | ||
221 | |||
222 | /* We had a bogus chunk_size. Fix stuff up. */ | ||
223 | dm_io_put(sectors_to_pages(ps->snap->chunk_size)); | ||
224 | free_area(ps); | ||
225 | |||
226 | ps->snap->chunk_size = chunk_size; | ||
227 | ps->snap->chunk_mask = chunk_size - 1; | ||
228 | ps->snap->chunk_shift = ffs(chunk_size) - 1; | ||
229 | |||
230 | r = alloc_area(ps); | ||
231 | if (r) | ||
232 | return r; | ||
233 | |||
234 | r = dm_io_get(sectors_to_pages(chunk_size)); | ||
235 | if (r) | ||
236 | return r; | ||
237 | } | ||
238 | } else { | ||
239 | DMWARN("Invalid/corrupt snapshot"); | ||
240 | r = -ENXIO; | 237 | r = -ENXIO; |
238 | goto bad2; | ||
241 | } | 239 | } |
242 | 240 | ||
241 | *new_snapshot = 0; | ||
242 | ps->valid = le32_to_cpu(dh->valid); | ||
243 | ps->version = le32_to_cpu(dh->version); | ||
244 | chunk_size = le32_to_cpu(dh->chunk_size); | ||
245 | |||
246 | if (!chunk_size_supplied || ps->snap->chunk_size == chunk_size) | ||
247 | return 0; | ||
248 | |||
249 | DMWARN("chunk size %llu in device metadata overrides " | ||
250 | "table chunk size of %llu.", | ||
251 | (unsigned long long)chunk_size, | ||
252 | (unsigned long long)ps->snap->chunk_size); | ||
253 | |||
254 | /* We had a bogus chunk_size. Fix stuff up. */ | ||
255 | dm_io_put(sectors_to_pages(ps->snap->chunk_size)); | ||
256 | free_area(ps); | ||
257 | |||
258 | ps->snap->chunk_size = chunk_size; | ||
259 | ps->snap->chunk_mask = chunk_size - 1; | ||
260 | ps->snap->chunk_shift = ffs(chunk_size) - 1; | ||
261 | |||
262 | r = dm_io_get(sectors_to_pages(chunk_size)); | ||
263 | if (r) | ||
264 | return r; | ||
265 | |||
266 | r = alloc_area(ps); | ||
267 | if (r) | ||
268 | goto bad1; | ||
269 | |||
270 | return 0; | ||
271 | |||
272 | bad2: | ||
273 | free_area(ps); | ||
274 | bad1: | ||
275 | dm_io_put(sectors_to_pages(ps->snap->chunk_size)); | ||
243 | return r; | 276 | return r; |
244 | } | 277 | } |
245 | 278 | ||
@@ -263,42 +296,29 @@ static int write_header(struct pstore *ps) | |||
263 | */ | 296 | */ |
264 | static struct disk_exception *get_exception(struct pstore *ps, uint32_t index) | 297 | static struct disk_exception *get_exception(struct pstore *ps, uint32_t index) |
265 | { | 298 | { |
266 | if (index >= ps->exceptions_per_area) | 299 | BUG_ON(index >= ps->exceptions_per_area); |
267 | return NULL; | ||
268 | 300 | ||
269 | return ((struct disk_exception *) ps->area) + index; | 301 | return ((struct disk_exception *) ps->area) + index; |
270 | } | 302 | } |
271 | 303 | ||
272 | static int read_exception(struct pstore *ps, | 304 | static void read_exception(struct pstore *ps, |
273 | uint32_t index, struct disk_exception *result) | 305 | uint32_t index, struct disk_exception *result) |
274 | { | 306 | { |
275 | struct disk_exception *e; | 307 | struct disk_exception *e = get_exception(ps, index); |
276 | |||
277 | e = get_exception(ps, index); | ||
278 | if (!e) | ||
279 | return -EINVAL; | ||
280 | 308 | ||
281 | /* copy it */ | 309 | /* copy it */ |
282 | result->old_chunk = le64_to_cpu(e->old_chunk); | 310 | result->old_chunk = le64_to_cpu(e->old_chunk); |
283 | result->new_chunk = le64_to_cpu(e->new_chunk); | 311 | result->new_chunk = le64_to_cpu(e->new_chunk); |
284 | |||
285 | return 0; | ||
286 | } | 312 | } |
287 | 313 | ||
288 | static int write_exception(struct pstore *ps, | 314 | static void write_exception(struct pstore *ps, |
289 | uint32_t index, struct disk_exception *de) | 315 | uint32_t index, struct disk_exception *de) |
290 | { | 316 | { |
291 | struct disk_exception *e; | 317 | struct disk_exception *e = get_exception(ps, index); |
292 | |||
293 | e = get_exception(ps, index); | ||
294 | if (!e) | ||
295 | return -EINVAL; | ||
296 | 318 | ||
297 | /* copy it */ | 319 | /* copy it */ |
298 | e->old_chunk = cpu_to_le64(de->old_chunk); | 320 | e->old_chunk = cpu_to_le64(de->old_chunk); |
299 | e->new_chunk = cpu_to_le64(de->new_chunk); | 321 | e->new_chunk = cpu_to_le64(de->new_chunk); |
300 | |||
301 | return 0; | ||
302 | } | 322 | } |
303 | 323 | ||
304 | /* | 324 | /* |
@@ -316,10 +336,7 @@ static int insert_exceptions(struct pstore *ps, int *full) | |||
316 | *full = 1; | 336 | *full = 1; |
317 | 337 | ||
318 | for (i = 0; i < ps->exceptions_per_area; i++) { | 338 | for (i = 0; i < ps->exceptions_per_area; i++) { |
319 | r = read_exception(ps, i, &de); | 339 | read_exception(ps, i, &de); |
320 | |||
321 | if (r) | ||
322 | return r; | ||
323 | 340 | ||
324 | /* | 341 | /* |
325 | * If the new_chunk is pointing at the start of | 342 | * If the new_chunk is pointing at the start of |
@@ -519,6 +536,16 @@ static void persistent_commit(struct exception_store *store, | |||
519 | if (r) | 536 | if (r) |
520 | ps->valid = 0; | 537 | ps->valid = 0; |
521 | 538 | ||
539 | /* | ||
540 | * Have we completely filled the current area ? | ||
541 | */ | ||
542 | if (ps->current_committed == ps->exceptions_per_area) { | ||
543 | ps->current_committed = 0; | ||
544 | r = zero_area(ps, ps->current_area + 1); | ||
545 | if (r) | ||
546 | ps->valid = 0; | ||
547 | } | ||
548 | |||
522 | for (i = 0; i < ps->callback_count; i++) { | 549 | for (i = 0; i < ps->callback_count; i++) { |
523 | cb = ps->callbacks + i; | 550 | cb = ps->callbacks + i; |
524 | cb->callback(cb->context, r == 0 ? 1 : 0); | 551 | cb->callback(cb->context, r == 0 ? 1 : 0); |
@@ -526,16 +553,6 @@ static void persistent_commit(struct exception_store *store, | |||
526 | 553 | ||
527 | ps->callback_count = 0; | 554 | ps->callback_count = 0; |
528 | } | 555 | } |
529 | |||
530 | /* | ||
531 | * Have we completely filled the current area ? | ||
532 | */ | ||
533 | if (ps->current_committed == ps->exceptions_per_area) { | ||
534 | ps->current_committed = 0; | ||
535 | r = zero_area(ps, ps->current_area + 1); | ||
536 | if (r) | ||
537 | ps->valid = 0; | ||
538 | } | ||
539 | } | 556 | } |
540 | 557 | ||
541 | static void persistent_drop(struct exception_store *store) | 558 | static void persistent_drop(struct exception_store *store) |
@@ -547,32 +564,22 @@ static void persistent_drop(struct exception_store *store) | |||
547 | DMWARN("write header failed"); | 564 | DMWARN("write header failed"); |
548 | } | 565 | } |
549 | 566 | ||
550 | int dm_create_persistent(struct exception_store *store, uint32_t chunk_size) | 567 | int dm_create_persistent(struct exception_store *store) |
551 | { | 568 | { |
552 | int r; | ||
553 | struct pstore *ps; | 569 | struct pstore *ps; |
554 | 570 | ||
555 | r = dm_io_get(sectors_to_pages(chunk_size)); | ||
556 | if (r) | ||
557 | return r; | ||
558 | |||
559 | /* allocate the pstore */ | 571 | /* allocate the pstore */ |
560 | ps = kmalloc(sizeof(*ps), GFP_KERNEL); | 572 | ps = kmalloc(sizeof(*ps), GFP_KERNEL); |
561 | if (!ps) { | 573 | if (!ps) |
562 | r = -ENOMEM; | 574 | return -ENOMEM; |
563 | goto bad; | ||
564 | } | ||
565 | 575 | ||
566 | ps->snap = store->snap; | 576 | ps->snap = store->snap; |
567 | ps->valid = 1; | 577 | ps->valid = 1; |
568 | ps->version = SNAPSHOT_DISK_VERSION; | 578 | ps->version = SNAPSHOT_DISK_VERSION; |
579 | ps->area = NULL; | ||
569 | ps->next_free = 2; /* skipping the header and first area */ | 580 | ps->next_free = 2; /* skipping the header and first area */ |
570 | ps->current_committed = 0; | 581 | ps->current_committed = 0; |
571 | 582 | ||
572 | r = alloc_area(ps); | ||
573 | if (r) | ||
574 | goto bad; | ||
575 | |||
576 | ps->callback_count = 0; | 583 | ps->callback_count = 0; |
577 | atomic_set(&ps->pending_count, 0); | 584 | atomic_set(&ps->pending_count, 0); |
578 | ps->callbacks = NULL; | 585 | ps->callbacks = NULL; |
@@ -586,13 +593,6 @@ int dm_create_persistent(struct exception_store *store, uint32_t chunk_size) | |||
586 | store->context = ps; | 593 | store->context = ps; |
587 | 594 | ||
588 | return 0; | 595 | return 0; |
589 | |||
590 | bad: | ||
591 | dm_io_put(sectors_to_pages(chunk_size)); | ||
592 | if (ps && ps->area) | ||
593 | free_area(ps); | ||
594 | kfree(ps); | ||
595 | return r; | ||
596 | } | 596 | } |
597 | 597 | ||
598 | /*----------------------------------------------------------------- | 598 | /*----------------------------------------------------------------- |
@@ -642,18 +642,16 @@ static void transient_fraction_full(struct exception_store *store, | |||
642 | *denominator = get_dev_size(store->snap->cow->bdev); | 642 | *denominator = get_dev_size(store->snap->cow->bdev); |
643 | } | 643 | } |
644 | 644 | ||
645 | int dm_create_transient(struct exception_store *store, | 645 | int dm_create_transient(struct exception_store *store) |
646 | struct dm_snapshot *s, int blocksize) | ||
647 | { | 646 | { |
648 | struct transient_c *tc; | 647 | struct transient_c *tc; |
649 | 648 | ||
650 | memset(store, 0, sizeof(*store)); | ||
651 | store->destroy = transient_destroy; | 649 | store->destroy = transient_destroy; |
652 | store->read_metadata = transient_read_metadata; | 650 | store->read_metadata = transient_read_metadata; |
653 | store->prepare_exception = transient_prepare; | 651 | store->prepare_exception = transient_prepare; |
654 | store->commit_exception = transient_commit; | 652 | store->commit_exception = transient_commit; |
653 | store->drop_snapshot = NULL; | ||
655 | store->fraction_full = transient_fraction_full; | 654 | store->fraction_full = transient_fraction_full; |
656 | store->snap = s; | ||
657 | 655 | ||
658 | tc = kmalloc(sizeof(struct transient_c), GFP_KERNEL); | 656 | tc = kmalloc(sizeof(struct transient_c), GFP_KERNEL); |
659 | if (!tc) | 657 | if (!tc) |
diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c index 47b3c62bbdb8..00234909b3db 100644 --- a/drivers/md/dm-linear.c +++ b/drivers/md/dm-linear.c | |||
@@ -98,14 +98,31 @@ static int linear_status(struct dm_target *ti, status_type_t type, | |||
98 | return 0; | 98 | return 0; |
99 | } | 99 | } |
100 | 100 | ||
101 | static int linear_ioctl(struct dm_target *ti, struct inode *inode, | ||
102 | struct file *filp, unsigned int cmd, | ||
103 | unsigned long arg) | ||
104 | { | ||
105 | struct linear_c *lc = (struct linear_c *) ti->private; | ||
106 | struct block_device *bdev = lc->dev->bdev; | ||
107 | struct file fake_file = {}; | ||
108 | struct dentry fake_dentry = {}; | ||
109 | |||
110 | fake_file.f_mode = lc->dev->mode; | ||
111 | fake_file.f_dentry = &fake_dentry; | ||
112 | fake_dentry.d_inode = bdev->bd_inode; | ||
113 | |||
114 | return blkdev_driver_ioctl(bdev->bd_inode, &fake_file, bdev->bd_disk, cmd, arg); | ||
115 | } | ||
116 | |||
101 | static struct target_type linear_target = { | 117 | static struct target_type linear_target = { |
102 | .name = "linear", | 118 | .name = "linear", |
103 | .version= {1, 0, 1}, | 119 | .version= {1, 0, 2}, |
104 | .module = THIS_MODULE, | 120 | .module = THIS_MODULE, |
105 | .ctr = linear_ctr, | 121 | .ctr = linear_ctr, |
106 | .dtr = linear_dtr, | 122 | .dtr = linear_dtr, |
107 | .map = linear_map, | 123 | .map = linear_map, |
108 | .status = linear_status, | 124 | .status = linear_status, |
125 | .ioctl = linear_ioctl, | ||
109 | }; | 126 | }; |
110 | 127 | ||
111 | int __init dm_linear_init(void) | 128 | int __init dm_linear_init(void) |
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 93f701ea87bc..d754e0bc6e90 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
@@ -114,12 +114,10 @@ static void trigger_event(void *data); | |||
114 | 114 | ||
115 | static struct pgpath *alloc_pgpath(void) | 115 | static struct pgpath *alloc_pgpath(void) |
116 | { | 116 | { |
117 | struct pgpath *pgpath = kmalloc(sizeof(*pgpath), GFP_KERNEL); | 117 | struct pgpath *pgpath = kzalloc(sizeof(*pgpath), GFP_KERNEL); |
118 | 118 | ||
119 | if (pgpath) { | 119 | if (pgpath) |
120 | memset(pgpath, 0, sizeof(*pgpath)); | ||
121 | pgpath->path.is_active = 1; | 120 | pgpath->path.is_active = 1; |
122 | } | ||
123 | 121 | ||
124 | return pgpath; | 122 | return pgpath; |
125 | } | 123 | } |
@@ -133,12 +131,10 @@ static struct priority_group *alloc_priority_group(void) | |||
133 | { | 131 | { |
134 | struct priority_group *pg; | 132 | struct priority_group *pg; |
135 | 133 | ||
136 | pg = kmalloc(sizeof(*pg), GFP_KERNEL); | 134 | pg = kzalloc(sizeof(*pg), GFP_KERNEL); |
137 | if (!pg) | ||
138 | return NULL; | ||
139 | 135 | ||
140 | memset(pg, 0, sizeof(*pg)); | 136 | if (pg) |
141 | INIT_LIST_HEAD(&pg->pgpaths); | 137 | INIT_LIST_HEAD(&pg->pgpaths); |
142 | 138 | ||
143 | return pg; | 139 | return pg; |
144 | } | 140 | } |
@@ -168,13 +164,12 @@ static void free_priority_group(struct priority_group *pg, | |||
168 | kfree(pg); | 164 | kfree(pg); |
169 | } | 165 | } |
170 | 166 | ||
171 | static struct multipath *alloc_multipath(void) | 167 | static struct multipath *alloc_multipath(struct dm_target *ti) |
172 | { | 168 | { |
173 | struct multipath *m; | 169 | struct multipath *m; |
174 | 170 | ||
175 | m = kmalloc(sizeof(*m), GFP_KERNEL); | 171 | m = kzalloc(sizeof(*m), GFP_KERNEL); |
176 | if (m) { | 172 | if (m) { |
177 | memset(m, 0, sizeof(*m)); | ||
178 | INIT_LIST_HEAD(&m->priority_groups); | 173 | INIT_LIST_HEAD(&m->priority_groups); |
179 | spin_lock_init(&m->lock); | 174 | spin_lock_init(&m->lock); |
180 | m->queue_io = 1; | 175 | m->queue_io = 1; |
@@ -185,6 +180,8 @@ static struct multipath *alloc_multipath(void) | |||
185 | kfree(m); | 180 | kfree(m); |
186 | return NULL; | 181 | return NULL; |
187 | } | 182 | } |
183 | m->ti = ti; | ||
184 | ti->private = m; | ||
188 | } | 185 | } |
189 | 186 | ||
190 | return m; | 187 | return m; |
@@ -557,8 +554,7 @@ static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps, | |||
557 | } | 554 | } |
558 | 555 | ||
559 | static struct priority_group *parse_priority_group(struct arg_set *as, | 556 | static struct priority_group *parse_priority_group(struct arg_set *as, |
560 | struct multipath *m, | 557 | struct multipath *m) |
561 | struct dm_target *ti) | ||
562 | { | 558 | { |
563 | static struct param _params[] = { | 559 | static struct param _params[] = { |
564 | {1, 1024, "invalid number of paths"}, | 560 | {1, 1024, "invalid number of paths"}, |
@@ -568,6 +564,7 @@ static struct priority_group *parse_priority_group(struct arg_set *as, | |||
568 | int r; | 564 | int r; |
569 | unsigned i, nr_selector_args, nr_params; | 565 | unsigned i, nr_selector_args, nr_params; |
570 | struct priority_group *pg; | 566 | struct priority_group *pg; |
567 | struct dm_target *ti = m->ti; | ||
571 | 568 | ||
572 | if (as->argc < 2) { | 569 | if (as->argc < 2) { |
573 | as->argc = 0; | 570 | as->argc = 0; |
@@ -624,12 +621,12 @@ static struct priority_group *parse_priority_group(struct arg_set *as, | |||
624 | return NULL; | 621 | return NULL; |
625 | } | 622 | } |
626 | 623 | ||
627 | static int parse_hw_handler(struct arg_set *as, struct multipath *m, | 624 | static int parse_hw_handler(struct arg_set *as, struct multipath *m) |
628 | struct dm_target *ti) | ||
629 | { | 625 | { |
630 | int r; | 626 | int r; |
631 | struct hw_handler_type *hwht; | 627 | struct hw_handler_type *hwht; |
632 | unsigned hw_argc; | 628 | unsigned hw_argc; |
629 | struct dm_target *ti = m->ti; | ||
633 | 630 | ||
634 | static struct param _params[] = { | 631 | static struct param _params[] = { |
635 | {0, 1024, "invalid number of hardware handler args"}, | 632 | {0, 1024, "invalid number of hardware handler args"}, |
@@ -661,11 +658,11 @@ static int parse_hw_handler(struct arg_set *as, struct multipath *m, | |||
661 | return 0; | 658 | return 0; |
662 | } | 659 | } |
663 | 660 | ||
664 | static int parse_features(struct arg_set *as, struct multipath *m, | 661 | static int parse_features(struct arg_set *as, struct multipath *m) |
665 | struct dm_target *ti) | ||
666 | { | 662 | { |
667 | int r; | 663 | int r; |
668 | unsigned argc; | 664 | unsigned argc; |
665 | struct dm_target *ti = m->ti; | ||
669 | 666 | ||
670 | static struct param _params[] = { | 667 | static struct param _params[] = { |
671 | {0, 1, "invalid number of feature args"}, | 668 | {0, 1, "invalid number of feature args"}, |
@@ -704,19 +701,17 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc, | |||
704 | as.argc = argc; | 701 | as.argc = argc; |
705 | as.argv = argv; | 702 | as.argv = argv; |
706 | 703 | ||
707 | m = alloc_multipath(); | 704 | m = alloc_multipath(ti); |
708 | if (!m) { | 705 | if (!m) { |
709 | ti->error = "can't allocate multipath"; | 706 | ti->error = "can't allocate multipath"; |
710 | return -EINVAL; | 707 | return -EINVAL; |
711 | } | 708 | } |
712 | 709 | ||
713 | m->ti = ti; | 710 | r = parse_features(&as, m); |
714 | |||
715 | r = parse_features(&as, m, ti); | ||
716 | if (r) | 711 | if (r) |
717 | goto bad; | 712 | goto bad; |
718 | 713 | ||
719 | r = parse_hw_handler(&as, m, ti); | 714 | r = parse_hw_handler(&as, m); |
720 | if (r) | 715 | if (r) |
721 | goto bad; | 716 | goto bad; |
722 | 717 | ||
@@ -732,7 +727,7 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc, | |||
732 | while (as.argc) { | 727 | while (as.argc) { |
733 | struct priority_group *pg; | 728 | struct priority_group *pg; |
734 | 729 | ||
735 | pg = parse_priority_group(&as, m, ti); | 730 | pg = parse_priority_group(&as, m); |
736 | if (!pg) { | 731 | if (!pg) { |
737 | r = -EINVAL; | 732 | r = -EINVAL; |
738 | goto bad; | 733 | goto bad; |
@@ -752,8 +747,6 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc, | |||
752 | goto bad; | 747 | goto bad; |
753 | } | 748 | } |
754 | 749 | ||
755 | ti->private = m; | ||
756 | |||
757 | return 0; | 750 | return 0; |
758 | 751 | ||
759 | bad: | 752 | bad: |
@@ -1266,12 +1259,47 @@ error: | |||
1266 | return -EINVAL; | 1259 | return -EINVAL; |
1267 | } | 1260 | } |
1268 | 1261 | ||
1262 | static int multipath_ioctl(struct dm_target *ti, struct inode *inode, | ||
1263 | struct file *filp, unsigned int cmd, | ||
1264 | unsigned long arg) | ||
1265 | { | ||
1266 | struct multipath *m = (struct multipath *) ti->private; | ||
1267 | struct block_device *bdev = NULL; | ||
1268 | unsigned long flags; | ||
1269 | struct file fake_file = {}; | ||
1270 | struct dentry fake_dentry = {}; | ||
1271 | int r = 0; | ||
1272 | |||
1273 | fake_file.f_dentry = &fake_dentry; | ||
1274 | |||
1275 | spin_lock_irqsave(&m->lock, flags); | ||
1276 | |||
1277 | if (!m->current_pgpath) | ||
1278 | __choose_pgpath(m); | ||
1279 | |||
1280 | if (m->current_pgpath) { | ||
1281 | bdev = m->current_pgpath->path.dev->bdev; | ||
1282 | fake_dentry.d_inode = bdev->bd_inode; | ||
1283 | fake_file.f_mode = m->current_pgpath->path.dev->mode; | ||
1284 | } | ||
1285 | |||
1286 | if (m->queue_io) | ||
1287 | r = -EAGAIN; | ||
1288 | else if (!bdev) | ||
1289 | r = -EIO; | ||
1290 | |||
1291 | spin_unlock_irqrestore(&m->lock, flags); | ||
1292 | |||
1293 | return r ? : blkdev_driver_ioctl(bdev->bd_inode, &fake_file, | ||
1294 | bdev->bd_disk, cmd, arg); | ||
1295 | } | ||
1296 | |||
1269 | /*----------------------------------------------------------------- | 1297 | /*----------------------------------------------------------------- |
1270 | * Module setup | 1298 | * Module setup |
1271 | *---------------------------------------------------------------*/ | 1299 | *---------------------------------------------------------------*/ |
1272 | static struct target_type multipath_target = { | 1300 | static struct target_type multipath_target = { |
1273 | .name = "multipath", | 1301 | .name = "multipath", |
1274 | .version = {1, 0, 4}, | 1302 | .version = {1, 0, 5}, |
1275 | .module = THIS_MODULE, | 1303 | .module = THIS_MODULE, |
1276 | .ctr = multipath_ctr, | 1304 | .ctr = multipath_ctr, |
1277 | .dtr = multipath_dtr, | 1305 | .dtr = multipath_dtr, |
@@ -1281,6 +1309,7 @@ static struct target_type multipath_target = { | |||
1281 | .resume = multipath_resume, | 1309 | .resume = multipath_resume, |
1282 | .status = multipath_status, | 1310 | .status = multipath_status, |
1283 | .message = multipath_message, | 1311 | .message = multipath_message, |
1312 | .ioctl = multipath_ioctl, | ||
1284 | }; | 1313 | }; |
1285 | 1314 | ||
1286 | static int __init dm_multipath_init(void) | 1315 | static int __init dm_multipath_init(void) |
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index c54de989eb00..659224cb7c53 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
@@ -1213,9 +1213,9 @@ static int mirror_status(struct dm_target *ti, status_type_t type, | |||
1213 | break; | 1213 | break; |
1214 | 1214 | ||
1215 | case STATUSTYPE_TABLE: | 1215 | case STATUSTYPE_TABLE: |
1216 | DMEMIT("%d ", ms->nr_mirrors); | 1216 | DMEMIT("%d", ms->nr_mirrors); |
1217 | for (m = 0; m < ms->nr_mirrors; m++) | 1217 | for (m = 0; m < ms->nr_mirrors; m++) |
1218 | DMEMIT("%s %llu ", ms->mirror[m].dev->name, | 1218 | DMEMIT(" %s %llu", ms->mirror[m].dev->name, |
1219 | (unsigned long long)ms->mirror[m].offset); | 1219 | (unsigned long long)ms->mirror[m].offset); |
1220 | } | 1220 | } |
1221 | 1221 | ||
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 1d0fafda0f76..5281e0094072 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c | |||
@@ -39,6 +39,9 @@ | |||
39 | */ | 39 | */ |
40 | #define SNAPSHOT_PAGES 256 | 40 | #define SNAPSHOT_PAGES 256 |
41 | 41 | ||
42 | struct workqueue_struct *ksnapd; | ||
43 | static void flush_queued_bios(void *data); | ||
44 | |||
42 | struct pending_exception { | 45 | struct pending_exception { |
43 | struct exception e; | 46 | struct exception e; |
44 | 47 | ||
@@ -56,7 +59,7 @@ struct pending_exception { | |||
56 | 59 | ||
57 | /* | 60 | /* |
58 | * The primary pending_exception is the one that holds | 61 | * The primary pending_exception is the one that holds |
59 | * the sibling_count and the list of origin_bios for a | 62 | * the ref_count and the list of origin_bios for a |
60 | * group of pending_exceptions. It is always last to get freed. | 63 | * group of pending_exceptions. It is always last to get freed. |
61 | * These fields get set up when writing to the origin. | 64 | * These fields get set up when writing to the origin. |
62 | */ | 65 | */ |
@@ -69,7 +72,7 @@ struct pending_exception { | |||
69 | * the sibling concerned and not pe->primary_pe->snap->lock unless | 72 | * the sibling concerned and not pe->primary_pe->snap->lock unless |
70 | * they are the same. | 73 | * they are the same. |
71 | */ | 74 | */ |
72 | atomic_t sibling_count; | 75 | atomic_t ref_count; |
73 | 76 | ||
74 | /* Pointer back to snapshot context */ | 77 | /* Pointer back to snapshot context */ |
75 | struct dm_snapshot *snap; | 78 | struct dm_snapshot *snap; |
@@ -387,15 +390,46 @@ static inline ulong round_up(ulong n, ulong size) | |||
387 | return (n + size) & ~size; | 390 | return (n + size) & ~size; |
388 | } | 391 | } |
389 | 392 | ||
390 | static void read_snapshot_metadata(struct dm_snapshot *s) | 393 | static int set_chunk_size(struct dm_snapshot *s, const char *chunk_size_arg, |
394 | char **error) | ||
391 | { | 395 | { |
392 | if (s->store.read_metadata(&s->store)) { | 396 | unsigned long chunk_size; |
393 | down_write(&s->lock); | 397 | char *value; |
394 | s->valid = 0; | 398 | |
395 | up_write(&s->lock); | 399 | chunk_size = simple_strtoul(chunk_size_arg, &value, 10); |
400 | if (*chunk_size_arg == '\0' || *value != '\0') { | ||
401 | *error = "Invalid chunk size"; | ||
402 | return -EINVAL; | ||
403 | } | ||
404 | |||
405 | if (!chunk_size) { | ||
406 | s->chunk_size = s->chunk_mask = s->chunk_shift = 0; | ||
407 | return 0; | ||
408 | } | ||
409 | |||
410 | /* | ||
411 | * Chunk size must be multiple of page size. Silently | ||
412 | * round up if it's not. | ||
413 | */ | ||
414 | chunk_size = round_up(chunk_size, PAGE_SIZE >> 9); | ||
415 | |||
416 | /* Check chunk_size is a power of 2 */ | ||
417 | if (chunk_size & (chunk_size - 1)) { | ||
418 | *error = "Chunk size is not a power of 2"; | ||
419 | return -EINVAL; | ||
420 | } | ||
396 | 421 | ||
397 | dm_table_event(s->table); | 422 | /* Validate the chunk size against the device block size */ |
423 | if (chunk_size % (bdev_hardsect_size(s->cow->bdev) >> 9)) { | ||
424 | *error = "Chunk size is not a multiple of device blocksize"; | ||
425 | return -EINVAL; | ||
398 | } | 426 | } |
427 | |||
428 | s->chunk_size = chunk_size; | ||
429 | s->chunk_mask = chunk_size - 1; | ||
430 | s->chunk_shift = ffs(chunk_size) - 1; | ||
431 | |||
432 | return 0; | ||
399 | } | 433 | } |
400 | 434 | ||
401 | /* | 435 | /* |
@@ -404,15 +438,12 @@ static void read_snapshot_metadata(struct dm_snapshot *s) | |||
404 | static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | 438 | static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) |
405 | { | 439 | { |
406 | struct dm_snapshot *s; | 440 | struct dm_snapshot *s; |
407 | unsigned long chunk_size; | ||
408 | int r = -EINVAL; | 441 | int r = -EINVAL; |
409 | char persistent; | 442 | char persistent; |
410 | char *origin_path; | 443 | char *origin_path; |
411 | char *cow_path; | 444 | char *cow_path; |
412 | char *value; | ||
413 | int blocksize; | ||
414 | 445 | ||
415 | if (argc < 4) { | 446 | if (argc != 4) { |
416 | ti->error = "requires exactly 4 arguments"; | 447 | ti->error = "requires exactly 4 arguments"; |
417 | r = -EINVAL; | 448 | r = -EINVAL; |
418 | goto bad1; | 449 | goto bad1; |
@@ -428,13 +459,6 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
428 | goto bad1; | 459 | goto bad1; |
429 | } | 460 | } |
430 | 461 | ||
431 | chunk_size = simple_strtoul(argv[3], &value, 10); | ||
432 | if (chunk_size == 0 || value == NULL) { | ||
433 | ti->error = "Invalid chunk size"; | ||
434 | r = -EINVAL; | ||
435 | goto bad1; | ||
436 | } | ||
437 | |||
438 | s = kmalloc(sizeof(*s), GFP_KERNEL); | 462 | s = kmalloc(sizeof(*s), GFP_KERNEL); |
439 | if (s == NULL) { | 463 | if (s == NULL) { |
440 | ti->error = "Cannot allocate snapshot context private " | 464 | ti->error = "Cannot allocate snapshot context private " |
@@ -457,36 +481,17 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
457 | goto bad2; | 481 | goto bad2; |
458 | } | 482 | } |
459 | 483 | ||
460 | /* | 484 | r = set_chunk_size(s, argv[3], &ti->error); |
461 | * Chunk size must be multiple of page size. Silently | 485 | if (r) |
462 | * round up if it's not. | ||
463 | */ | ||
464 | chunk_size = round_up(chunk_size, PAGE_SIZE >> 9); | ||
465 | |||
466 | /* Validate the chunk size against the device block size */ | ||
467 | blocksize = s->cow->bdev->bd_disk->queue->hardsect_size; | ||
468 | if (chunk_size % (blocksize >> 9)) { | ||
469 | ti->error = "Chunk size is not a multiple of device blocksize"; | ||
470 | r = -EINVAL; | ||
471 | goto bad3; | ||
472 | } | ||
473 | |||
474 | /* Check chunk_size is a power of 2 */ | ||
475 | if (chunk_size & (chunk_size - 1)) { | ||
476 | ti->error = "Chunk size is not a power of 2"; | ||
477 | r = -EINVAL; | ||
478 | goto bad3; | 486 | goto bad3; |
479 | } | ||
480 | 487 | ||
481 | s->chunk_size = chunk_size; | ||
482 | s->chunk_mask = chunk_size - 1; | ||
483 | s->type = persistent; | 488 | s->type = persistent; |
484 | s->chunk_shift = ffs(chunk_size) - 1; | ||
485 | 489 | ||
486 | s->valid = 1; | 490 | s->valid = 1; |
487 | s->active = 0; | 491 | s->active = 0; |
488 | s->last_percent = 0; | 492 | s->last_percent = 0; |
489 | init_rwsem(&s->lock); | 493 | init_rwsem(&s->lock); |
494 | spin_lock_init(&s->pe_lock); | ||
490 | s->table = ti->table; | 495 | s->table = ti->table; |
491 | 496 | ||
492 | /* Allocate hash table for COW data */ | 497 | /* Allocate hash table for COW data */ |
@@ -496,16 +501,12 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
496 | goto bad3; | 501 | goto bad3; |
497 | } | 502 | } |
498 | 503 | ||
499 | /* | ||
500 | * Check the persistent flag - done here because we need the iobuf | ||
501 | * to check the LV header | ||
502 | */ | ||
503 | s->store.snap = s; | 504 | s->store.snap = s; |
504 | 505 | ||
505 | if (persistent == 'P') | 506 | if (persistent == 'P') |
506 | r = dm_create_persistent(&s->store, chunk_size); | 507 | r = dm_create_persistent(&s->store); |
507 | else | 508 | else |
508 | r = dm_create_transient(&s->store, s, blocksize); | 509 | r = dm_create_transient(&s->store); |
509 | 510 | ||
510 | if (r) { | 511 | if (r) { |
511 | ti->error = "Couldn't create exception store"; | 512 | ti->error = "Couldn't create exception store"; |
@@ -520,7 +521,14 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
520 | } | 521 | } |
521 | 522 | ||
522 | /* Metadata must only be loaded into one table at once */ | 523 | /* Metadata must only be loaded into one table at once */ |
523 | read_snapshot_metadata(s); | 524 | r = s->store.read_metadata(&s->store); |
525 | if (r) { | ||
526 | ti->error = "Failed to read snapshot metadata"; | ||
527 | goto bad6; | ||
528 | } | ||
529 | |||
530 | bio_list_init(&s->queued_bios); | ||
531 | INIT_WORK(&s->queued_bios_work, flush_queued_bios, s); | ||
524 | 532 | ||
525 | /* Add snapshot to the list of snapshots for this origin */ | 533 | /* Add snapshot to the list of snapshots for this origin */ |
526 | /* Exceptions aren't triggered till snapshot_resume() is called */ | 534 | /* Exceptions aren't triggered till snapshot_resume() is called */ |
@@ -560,6 +568,8 @@ static void snapshot_dtr(struct dm_target *ti) | |||
560 | { | 568 | { |
561 | struct dm_snapshot *s = (struct dm_snapshot *) ti->private; | 569 | struct dm_snapshot *s = (struct dm_snapshot *) ti->private; |
562 | 570 | ||
571 | flush_workqueue(ksnapd); | ||
572 | |||
563 | /* Prevent further origin writes from using this snapshot. */ | 573 | /* Prevent further origin writes from using this snapshot. */ |
564 | /* After this returns there can be no new kcopyd jobs. */ | 574 | /* After this returns there can be no new kcopyd jobs. */ |
565 | unregister_snapshot(s); | 575 | unregister_snapshot(s); |
@@ -593,6 +603,19 @@ static void flush_bios(struct bio *bio) | |||
593 | } | 603 | } |
594 | } | 604 | } |
595 | 605 | ||
606 | static void flush_queued_bios(void *data) | ||
607 | { | ||
608 | struct dm_snapshot *s = (struct dm_snapshot *) data; | ||
609 | struct bio *queued_bios; | ||
610 | unsigned long flags; | ||
611 | |||
612 | spin_lock_irqsave(&s->pe_lock, flags); | ||
613 | queued_bios = bio_list_get(&s->queued_bios); | ||
614 | spin_unlock_irqrestore(&s->pe_lock, flags); | ||
615 | |||
616 | flush_bios(queued_bios); | ||
617 | } | ||
618 | |||
596 | /* | 619 | /* |
597 | * Error a list of buffers. | 620 | * Error a list of buffers. |
598 | */ | 621 | */ |
@@ -608,28 +631,7 @@ static void error_bios(struct bio *bio) | |||
608 | } | 631 | } |
609 | } | 632 | } |
610 | 633 | ||
611 | static inline void error_snapshot_bios(struct pending_exception *pe) | 634 | static void __invalidate_snapshot(struct dm_snapshot *s, int err) |
612 | { | ||
613 | error_bios(bio_list_get(&pe->snapshot_bios)); | ||
614 | } | ||
615 | |||
616 | static struct bio *__flush_bios(struct pending_exception *pe) | ||
617 | { | ||
618 | /* | ||
619 | * If this pe is involved in a write to the origin and | ||
620 | * it is the last sibling to complete then release | ||
621 | * the bios for the original write to the origin. | ||
622 | */ | ||
623 | |||
624 | if (pe->primary_pe && | ||
625 | atomic_dec_and_test(&pe->primary_pe->sibling_count)) | ||
626 | return bio_list_get(&pe->primary_pe->origin_bios); | ||
627 | |||
628 | return NULL; | ||
629 | } | ||
630 | |||
631 | static void __invalidate_snapshot(struct dm_snapshot *s, | ||
632 | struct pending_exception *pe, int err) | ||
633 | { | 635 | { |
634 | if (!s->valid) | 636 | if (!s->valid) |
635 | return; | 637 | return; |
@@ -639,9 +641,6 @@ static void __invalidate_snapshot(struct dm_snapshot *s, | |||
639 | else if (err == -ENOMEM) | 641 | else if (err == -ENOMEM) |
640 | DMERR("Invalidating snapshot: Unable to allocate exception."); | 642 | DMERR("Invalidating snapshot: Unable to allocate exception."); |
641 | 643 | ||
642 | if (pe) | ||
643 | remove_exception(&pe->e); | ||
644 | |||
645 | if (s->store.drop_snapshot) | 644 | if (s->store.drop_snapshot) |
646 | s->store.drop_snapshot(&s->store); | 645 | s->store.drop_snapshot(&s->store); |
647 | 646 | ||
@@ -650,78 +649,95 @@ static void __invalidate_snapshot(struct dm_snapshot *s, | |||
650 | dm_table_event(s->table); | 649 | dm_table_event(s->table); |
651 | } | 650 | } |
652 | 651 | ||
652 | static void get_pending_exception(struct pending_exception *pe) | ||
653 | { | ||
654 | atomic_inc(&pe->ref_count); | ||
655 | } | ||
656 | |||
657 | static struct bio *put_pending_exception(struct pending_exception *pe) | ||
658 | { | ||
659 | struct pending_exception *primary_pe; | ||
660 | struct bio *origin_bios = NULL; | ||
661 | |||
662 | primary_pe = pe->primary_pe; | ||
663 | |||
664 | /* | ||
665 | * If this pe is involved in a write to the origin and | ||
666 | * it is the last sibling to complete then release | ||
667 | * the bios for the original write to the origin. | ||
668 | */ | ||
669 | if (primary_pe && | ||
670 | atomic_dec_and_test(&primary_pe->ref_count)) | ||
671 | origin_bios = bio_list_get(&primary_pe->origin_bios); | ||
672 | |||
673 | /* | ||
674 | * Free the pe if it's not linked to an origin write or if | ||
675 | * it's not itself a primary pe. | ||
676 | */ | ||
677 | if (!primary_pe || primary_pe != pe) | ||
678 | free_pending_exception(pe); | ||
679 | |||
680 | /* | ||
681 | * Free the primary pe if nothing references it. | ||
682 | */ | ||
683 | if (primary_pe && !atomic_read(&primary_pe->ref_count)) | ||
684 | free_pending_exception(primary_pe); | ||
685 | |||
686 | return origin_bios; | ||
687 | } | ||
688 | |||
653 | static void pending_complete(struct pending_exception *pe, int success) | 689 | static void pending_complete(struct pending_exception *pe, int success) |
654 | { | 690 | { |
655 | struct exception *e; | 691 | struct exception *e; |
656 | struct pending_exception *primary_pe; | ||
657 | struct dm_snapshot *s = pe->snap; | 692 | struct dm_snapshot *s = pe->snap; |
658 | struct bio *flush = NULL; | 693 | struct bio *origin_bios = NULL; |
694 | struct bio *snapshot_bios = NULL; | ||
695 | int error = 0; | ||
659 | 696 | ||
660 | if (!success) { | 697 | if (!success) { |
661 | /* Read/write error - snapshot is unusable */ | 698 | /* Read/write error - snapshot is unusable */ |
662 | down_write(&s->lock); | 699 | down_write(&s->lock); |
663 | __invalidate_snapshot(s, pe, -EIO); | 700 | __invalidate_snapshot(s, -EIO); |
664 | flush = __flush_bios(pe); | 701 | error = 1; |
665 | up_write(&s->lock); | ||
666 | |||
667 | error_snapshot_bios(pe); | ||
668 | goto out; | 702 | goto out; |
669 | } | 703 | } |
670 | 704 | ||
671 | e = alloc_exception(); | 705 | e = alloc_exception(); |
672 | if (!e) { | 706 | if (!e) { |
673 | down_write(&s->lock); | 707 | down_write(&s->lock); |
674 | __invalidate_snapshot(s, pe, -ENOMEM); | 708 | __invalidate_snapshot(s, -ENOMEM); |
675 | flush = __flush_bios(pe); | 709 | error = 1; |
676 | up_write(&s->lock); | ||
677 | |||
678 | error_snapshot_bios(pe); | ||
679 | goto out; | 710 | goto out; |
680 | } | 711 | } |
681 | *e = pe->e; | 712 | *e = pe->e; |
682 | 713 | ||
683 | /* | ||
684 | * Add a proper exception, and remove the | ||
685 | * in-flight exception from the list. | ||
686 | */ | ||
687 | down_write(&s->lock); | 714 | down_write(&s->lock); |
688 | if (!s->valid) { | 715 | if (!s->valid) { |
689 | flush = __flush_bios(pe); | ||
690 | up_write(&s->lock); | ||
691 | |||
692 | free_exception(e); | 716 | free_exception(e); |
693 | 717 | error = 1; | |
694 | error_snapshot_bios(pe); | ||
695 | goto out; | 718 | goto out; |
696 | } | 719 | } |
697 | 720 | ||
721 | /* | ||
722 | * Add a proper exception, and remove the | ||
723 | * in-flight exception from the list. | ||
724 | */ | ||
698 | insert_exception(&s->complete, e); | 725 | insert_exception(&s->complete, e); |
726 | |||
727 | out: | ||
699 | remove_exception(&pe->e); | 728 | remove_exception(&pe->e); |
700 | flush = __flush_bios(pe); | 729 | snapshot_bios = bio_list_get(&pe->snapshot_bios); |
730 | origin_bios = put_pending_exception(pe); | ||
701 | 731 | ||
702 | up_write(&s->lock); | 732 | up_write(&s->lock); |
703 | 733 | ||
704 | /* Submit any pending write bios */ | 734 | /* Submit any pending write bios */ |
705 | flush_bios(bio_list_get(&pe->snapshot_bios)); | 735 | if (error) |
706 | 736 | error_bios(snapshot_bios); | |
707 | out: | 737 | else |
708 | primary_pe = pe->primary_pe; | 738 | flush_bios(snapshot_bios); |
709 | |||
710 | /* | ||
711 | * Free the pe if it's not linked to an origin write or if | ||
712 | * it's not itself a primary pe. | ||
713 | */ | ||
714 | if (!primary_pe || primary_pe != pe) | ||
715 | free_pending_exception(pe); | ||
716 | |||
717 | /* | ||
718 | * Free the primary pe if nothing references it. | ||
719 | */ | ||
720 | if (primary_pe && !atomic_read(&primary_pe->sibling_count)) | ||
721 | free_pending_exception(primary_pe); | ||
722 | 739 | ||
723 | if (flush) | 740 | flush_bios(origin_bios); |
724 | flush_bios(flush); | ||
725 | } | 741 | } |
726 | 742 | ||
727 | static void commit_callback(void *context, int success) | 743 | static void commit_callback(void *context, int success) |
@@ -822,7 +838,7 @@ __find_pending_exception(struct dm_snapshot *s, struct bio *bio) | |||
822 | bio_list_init(&pe->origin_bios); | 838 | bio_list_init(&pe->origin_bios); |
823 | bio_list_init(&pe->snapshot_bios); | 839 | bio_list_init(&pe->snapshot_bios); |
824 | pe->primary_pe = NULL; | 840 | pe->primary_pe = NULL; |
825 | atomic_set(&pe->sibling_count, 1); | 841 | atomic_set(&pe->ref_count, 0); |
826 | pe->snap = s; | 842 | pe->snap = s; |
827 | pe->started = 0; | 843 | pe->started = 0; |
828 | 844 | ||
@@ -831,6 +847,7 @@ __find_pending_exception(struct dm_snapshot *s, struct bio *bio) | |||
831 | return NULL; | 847 | return NULL; |
832 | } | 848 | } |
833 | 849 | ||
850 | get_pending_exception(pe); | ||
834 | insert_exception(&s->pending, &pe->e); | 851 | insert_exception(&s->pending, &pe->e); |
835 | 852 | ||
836 | out: | 853 | out: |
@@ -850,7 +867,6 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio, | |||
850 | { | 867 | { |
851 | struct exception *e; | 868 | struct exception *e; |
852 | struct dm_snapshot *s = (struct dm_snapshot *) ti->private; | 869 | struct dm_snapshot *s = (struct dm_snapshot *) ti->private; |
853 | int copy_needed = 0; | ||
854 | int r = 1; | 870 | int r = 1; |
855 | chunk_t chunk; | 871 | chunk_t chunk; |
856 | struct pending_exception *pe = NULL; | 872 | struct pending_exception *pe = NULL; |
@@ -865,32 +881,31 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio, | |||
865 | if (unlikely(bio_barrier(bio))) | 881 | if (unlikely(bio_barrier(bio))) |
866 | return -EOPNOTSUPP; | 882 | return -EOPNOTSUPP; |
867 | 883 | ||
884 | /* FIXME: should only take write lock if we need | ||
885 | * to copy an exception */ | ||
886 | down_write(&s->lock); | ||
887 | |||
888 | if (!s->valid) { | ||
889 | r = -EIO; | ||
890 | goto out_unlock; | ||
891 | } | ||
892 | |||
893 | /* If the block is already remapped - use that, else remap it */ | ||
894 | e = lookup_exception(&s->complete, chunk); | ||
895 | if (e) { | ||
896 | remap_exception(s, e, bio); | ||
897 | goto out_unlock; | ||
898 | } | ||
899 | |||
868 | /* | 900 | /* |
869 | * Write to snapshot - higher level takes care of RW/RO | 901 | * Write to snapshot - higher level takes care of RW/RO |
870 | * flags so we should only get this if we are | 902 | * flags so we should only get this if we are |
871 | * writeable. | 903 | * writeable. |
872 | */ | 904 | */ |
873 | if (bio_rw(bio) == WRITE) { | 905 | if (bio_rw(bio) == WRITE) { |
874 | |||
875 | /* FIXME: should only take write lock if we need | ||
876 | * to copy an exception */ | ||
877 | down_write(&s->lock); | ||
878 | |||
879 | if (!s->valid) { | ||
880 | r = -EIO; | ||
881 | goto out_unlock; | ||
882 | } | ||
883 | |||
884 | /* If the block is already remapped - use that, else remap it */ | ||
885 | e = lookup_exception(&s->complete, chunk); | ||
886 | if (e) { | ||
887 | remap_exception(s, e, bio); | ||
888 | goto out_unlock; | ||
889 | } | ||
890 | |||
891 | pe = __find_pending_exception(s, bio); | 906 | pe = __find_pending_exception(s, bio); |
892 | if (!pe) { | 907 | if (!pe) { |
893 | __invalidate_snapshot(s, pe, -ENOMEM); | 908 | __invalidate_snapshot(s, -ENOMEM); |
894 | r = -EIO; | 909 | r = -EIO; |
895 | goto out_unlock; | 910 | goto out_unlock; |
896 | } | 911 | } |
@@ -898,45 +913,27 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio, | |||
898 | remap_exception(s, &pe->e, bio); | 913 | remap_exception(s, &pe->e, bio); |
899 | bio_list_add(&pe->snapshot_bios, bio); | 914 | bio_list_add(&pe->snapshot_bios, bio); |
900 | 915 | ||
916 | r = 0; | ||
917 | |||
901 | if (!pe->started) { | 918 | if (!pe->started) { |
902 | /* this is protected by snap->lock */ | 919 | /* this is protected by snap->lock */ |
903 | pe->started = 1; | 920 | pe->started = 1; |
904 | copy_needed = 1; | 921 | up_write(&s->lock); |
905 | } | ||
906 | |||
907 | r = 0; | ||
908 | |||
909 | out_unlock: | ||
910 | up_write(&s->lock); | ||
911 | |||
912 | if (copy_needed) | ||
913 | start_copy(pe); | 922 | start_copy(pe); |
914 | } else { | 923 | goto out; |
924 | } | ||
925 | } else | ||
915 | /* | 926 | /* |
916 | * FIXME: this read path scares me because we | 927 | * FIXME: this read path scares me because we |
917 | * always use the origin when we have a pending | 928 | * always use the origin when we have a pending |
918 | * exception. However I can't think of a | 929 | * exception. However I can't think of a |
919 | * situation where this is wrong - ejt. | 930 | * situation where this is wrong - ejt. |
920 | */ | 931 | */ |
932 | bio->bi_bdev = s->origin->bdev; | ||
921 | 933 | ||
922 | /* Do reads */ | 934 | out_unlock: |
923 | down_read(&s->lock); | 935 | up_write(&s->lock); |
924 | 936 | out: | |
925 | if (!s->valid) { | ||
926 | up_read(&s->lock); | ||
927 | return -EIO; | ||
928 | } | ||
929 | |||
930 | /* See if it it has been remapped */ | ||
931 | e = lookup_exception(&s->complete, chunk); | ||
932 | if (e) | ||
933 | remap_exception(s, e, bio); | ||
934 | else | ||
935 | bio->bi_bdev = s->origin->bdev; | ||
936 | |||
937 | up_read(&s->lock); | ||
938 | } | ||
939 | |||
940 | return r; | 937 | return r; |
941 | } | 938 | } |
942 | 939 | ||
@@ -1025,7 +1022,7 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio) | |||
1025 | * is already remapped in this snapshot | 1022 | * is already remapped in this snapshot |
1026 | * and trigger an exception if not. | 1023 | * and trigger an exception if not. |
1027 | * | 1024 | * |
1028 | * sibling_count is initialised to 1 so pending_complete() | 1025 | * ref_count is initialised to 1 so pending_complete() |
1029 | * won't destroy the primary_pe while we're inside this loop. | 1026 | * won't destroy the primary_pe while we're inside this loop. |
1030 | */ | 1027 | */ |
1031 | e = lookup_exception(&snap->complete, chunk); | 1028 | e = lookup_exception(&snap->complete, chunk); |
@@ -1034,7 +1031,7 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio) | |||
1034 | 1031 | ||
1035 | pe = __find_pending_exception(snap, bio); | 1032 | pe = __find_pending_exception(snap, bio); |
1036 | if (!pe) { | 1033 | if (!pe) { |
1037 | __invalidate_snapshot(snap, pe, ENOMEM); | 1034 | __invalidate_snapshot(snap, -ENOMEM); |
1038 | goto next_snapshot; | 1035 | goto next_snapshot; |
1039 | } | 1036 | } |
1040 | 1037 | ||
@@ -1056,8 +1053,8 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio) | |||
1056 | } | 1053 | } |
1057 | 1054 | ||
1058 | if (!pe->primary_pe) { | 1055 | if (!pe->primary_pe) { |
1059 | atomic_inc(&primary_pe->sibling_count); | ||
1060 | pe->primary_pe = primary_pe; | 1056 | pe->primary_pe = primary_pe; |
1057 | get_pending_exception(primary_pe); | ||
1061 | } | 1058 | } |
1062 | 1059 | ||
1063 | if (!pe->started) { | 1060 | if (!pe->started) { |
@@ -1070,20 +1067,20 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio) | |||
1070 | } | 1067 | } |
1071 | 1068 | ||
1072 | if (!primary_pe) | 1069 | if (!primary_pe) |
1073 | goto out; | 1070 | return r; |
1074 | 1071 | ||
1075 | /* | 1072 | /* |
1076 | * If this is the first time we're processing this chunk and | 1073 | * If this is the first time we're processing this chunk and |
1077 | * sibling_count is now 1 it means all the pending exceptions | 1074 | * ref_count is now 1 it means all the pending exceptions |
1078 | * got completed while we were in the loop above, so it falls to | 1075 | * got completed while we were in the loop above, so it falls to |
1079 | * us here to remove the primary_pe and submit any origin_bios. | 1076 | * us here to remove the primary_pe and submit any origin_bios. |
1080 | */ | 1077 | */ |
1081 | 1078 | ||
1082 | if (first && atomic_dec_and_test(&primary_pe->sibling_count)) { | 1079 | if (first && atomic_dec_and_test(&primary_pe->ref_count)) { |
1083 | flush_bios(bio_list_get(&primary_pe->origin_bios)); | 1080 | flush_bios(bio_list_get(&primary_pe->origin_bios)); |
1084 | free_pending_exception(primary_pe); | 1081 | free_pending_exception(primary_pe); |
1085 | /* If we got here, pe_queue is necessarily empty. */ | 1082 | /* If we got here, pe_queue is necessarily empty. */ |
1086 | goto out; | 1083 | return r; |
1087 | } | 1084 | } |
1088 | 1085 | ||
1089 | /* | 1086 | /* |
@@ -1092,7 +1089,6 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio) | |||
1092 | list_for_each_entry_safe(pe, next_pe, &pe_queue, list) | 1089 | list_for_each_entry_safe(pe, next_pe, &pe_queue, list) |
1093 | start_copy(pe); | 1090 | start_copy(pe); |
1094 | 1091 | ||
1095 | out: | ||
1096 | return r; | 1092 | return r; |
1097 | } | 1093 | } |
1098 | 1094 | ||
@@ -1205,7 +1201,7 @@ static int origin_status(struct dm_target *ti, status_type_t type, char *result, | |||
1205 | 1201 | ||
1206 | static struct target_type origin_target = { | 1202 | static struct target_type origin_target = { |
1207 | .name = "snapshot-origin", | 1203 | .name = "snapshot-origin", |
1208 | .version = {1, 4, 0}, | 1204 | .version = {1, 5, 0}, |
1209 | .module = THIS_MODULE, | 1205 | .module = THIS_MODULE, |
1210 | .ctr = origin_ctr, | 1206 | .ctr = origin_ctr, |
1211 | .dtr = origin_dtr, | 1207 | .dtr = origin_dtr, |
@@ -1216,7 +1212,7 @@ static struct target_type origin_target = { | |||
1216 | 1212 | ||
1217 | static struct target_type snapshot_target = { | 1213 | static struct target_type snapshot_target = { |
1218 | .name = "snapshot", | 1214 | .name = "snapshot", |
1219 | .version = {1, 4, 0}, | 1215 | .version = {1, 5, 0}, |
1220 | .module = THIS_MODULE, | 1216 | .module = THIS_MODULE, |
1221 | .ctr = snapshot_ctr, | 1217 | .ctr = snapshot_ctr, |
1222 | .dtr = snapshot_dtr, | 1218 | .dtr = snapshot_dtr, |
@@ -1275,8 +1271,17 @@ static int __init dm_snapshot_init(void) | |||
1275 | goto bad5; | 1271 | goto bad5; |
1276 | } | 1272 | } |
1277 | 1273 | ||
1274 | ksnapd = create_singlethread_workqueue("ksnapd"); | ||
1275 | if (!ksnapd) { | ||
1276 | DMERR("Failed to create ksnapd workqueue."); | ||
1277 | r = -ENOMEM; | ||
1278 | goto bad6; | ||
1279 | } | ||
1280 | |||
1278 | return 0; | 1281 | return 0; |
1279 | 1282 | ||
1283 | bad6: | ||
1284 | mempool_destroy(pending_pool); | ||
1280 | bad5: | 1285 | bad5: |
1281 | kmem_cache_destroy(pending_cache); | 1286 | kmem_cache_destroy(pending_cache); |
1282 | bad4: | 1287 | bad4: |
@@ -1294,6 +1299,8 @@ static void __exit dm_snapshot_exit(void) | |||
1294 | { | 1299 | { |
1295 | int r; | 1300 | int r; |
1296 | 1301 | ||
1302 | destroy_workqueue(ksnapd); | ||
1303 | |||
1297 | r = dm_unregister_target(&snapshot_target); | 1304 | r = dm_unregister_target(&snapshot_target); |
1298 | if (r) | 1305 | if (r) |
1299 | DMERR("snapshot unregister failed %d", r); | 1306 | DMERR("snapshot unregister failed %d", r); |
diff --git a/drivers/md/dm-snap.h b/drivers/md/dm-snap.h index fdec1e2dc871..15fa2ae6cdc2 100644 --- a/drivers/md/dm-snap.h +++ b/drivers/md/dm-snap.h | |||
@@ -10,7 +10,9 @@ | |||
10 | #define DM_SNAPSHOT_H | 10 | #define DM_SNAPSHOT_H |
11 | 11 | ||
12 | #include "dm.h" | 12 | #include "dm.h" |
13 | #include "dm-bio-list.h" | ||
13 | #include <linux/blkdev.h> | 14 | #include <linux/blkdev.h> |
15 | #include <linux/workqueue.h> | ||
14 | 16 | ||
15 | struct exception_table { | 17 | struct exception_table { |
16 | uint32_t hash_mask; | 18 | uint32_t hash_mask; |
@@ -112,10 +114,20 @@ struct dm_snapshot { | |||
112 | struct exception_table pending; | 114 | struct exception_table pending; |
113 | struct exception_table complete; | 115 | struct exception_table complete; |
114 | 116 | ||
117 | /* | ||
118 | * pe_lock protects all pending_exception operations and access | ||
119 | * as well as the snapshot_bios list. | ||
120 | */ | ||
121 | spinlock_t pe_lock; | ||
122 | |||
115 | /* The on disk metadata handler */ | 123 | /* The on disk metadata handler */ |
116 | struct exception_store store; | 124 | struct exception_store store; |
117 | 125 | ||
118 | struct kcopyd_client *kcopyd_client; | 126 | struct kcopyd_client *kcopyd_client; |
127 | |||
128 | /* Queue of snapshot writes for ksnapd to flush */ | ||
129 | struct bio_list queued_bios; | ||
130 | struct work_struct queued_bios_work; | ||
119 | }; | 131 | }; |
120 | 132 | ||
121 | /* | 133 | /* |
@@ -128,10 +140,9 @@ int dm_add_exception(struct dm_snapshot *s, chunk_t old, chunk_t new); | |||
128 | * Constructor and destructor for the default persistent | 140 | * Constructor and destructor for the default persistent |
129 | * store. | 141 | * store. |
130 | */ | 142 | */ |
131 | int dm_create_persistent(struct exception_store *store, uint32_t chunk_size); | 143 | int dm_create_persistent(struct exception_store *store); |
132 | 144 | ||
133 | int dm_create_transient(struct exception_store *store, | 145 | int dm_create_transient(struct exception_store *store); |
134 | struct dm_snapshot *s, int blocksize); | ||
135 | 146 | ||
136 | /* | 147 | /* |
137 | * Return the number of sectors in the device. | 148 | * Return the number of sectors in the device. |
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 75fe9493e6af..05befa91807a 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
@@ -522,56 +522,61 @@ static int __table_get_device(struct dm_table *t, struct dm_target *ti, | |||
522 | return 0; | 522 | return 0; |
523 | } | 523 | } |
524 | 524 | ||
525 | 525 | void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev) | |
526 | int dm_get_device(struct dm_target *ti, const char *path, sector_t start, | ||
527 | sector_t len, int mode, struct dm_dev **result) | ||
528 | { | 526 | { |
529 | int r = __table_get_device(ti->table, ti, path, | 527 | request_queue_t *q = bdev_get_queue(bdev); |
530 | start, len, mode, result); | 528 | struct io_restrictions *rs = &ti->limits; |
531 | if (!r) { | 529 | |
532 | request_queue_t *q = bdev_get_queue((*result)->bdev); | 530 | /* |
533 | struct io_restrictions *rs = &ti->limits; | 531 | * Combine the device limits low. |
534 | 532 | * | |
535 | /* | 533 | * FIXME: if we move an io_restriction struct |
536 | * Combine the device limits low. | 534 | * into q this would just be a call to |
537 | * | 535 | * combine_restrictions_low() |
538 | * FIXME: if we move an io_restriction struct | 536 | */ |
539 | * into q this would just be a call to | 537 | rs->max_sectors = |
540 | * combine_restrictions_low() | 538 | min_not_zero(rs->max_sectors, q->max_sectors); |
541 | */ | 539 | |
540 | /* FIXME: Device-Mapper on top of RAID-0 breaks because DM | ||
541 | * currently doesn't honor MD's merge_bvec_fn routine. | ||
542 | * In this case, we'll force DM to use PAGE_SIZE or | ||
543 | * smaller I/O, just to be safe. A better fix is in the | ||
544 | * works, but add this for the time being so it will at | ||
545 | * least operate correctly. | ||
546 | */ | ||
547 | if (q->merge_bvec_fn) | ||
542 | rs->max_sectors = | 548 | rs->max_sectors = |
543 | min_not_zero(rs->max_sectors, q->max_sectors); | 549 | min_not_zero(rs->max_sectors, |
550 | (unsigned int) (PAGE_SIZE >> 9)); | ||
544 | 551 | ||
545 | /* FIXME: Device-Mapper on top of RAID-0 breaks because DM | 552 | rs->max_phys_segments = |
546 | * currently doesn't honor MD's merge_bvec_fn routine. | 553 | min_not_zero(rs->max_phys_segments, |
547 | * In this case, we'll force DM to use PAGE_SIZE or | 554 | q->max_phys_segments); |
548 | * smaller I/O, just to be safe. A better fix is in the | ||
549 | * works, but add this for the time being so it will at | ||
550 | * least operate correctly. | ||
551 | */ | ||
552 | if (q->merge_bvec_fn) | ||
553 | rs->max_sectors = | ||
554 | min_not_zero(rs->max_sectors, | ||
555 | (unsigned int) (PAGE_SIZE >> 9)); | ||
556 | 555 | ||
557 | rs->max_phys_segments = | 556 | rs->max_hw_segments = |
558 | min_not_zero(rs->max_phys_segments, | 557 | min_not_zero(rs->max_hw_segments, q->max_hw_segments); |
559 | q->max_phys_segments); | ||
560 | 558 | ||
561 | rs->max_hw_segments = | 559 | rs->hardsect_size = max(rs->hardsect_size, q->hardsect_size); |
562 | min_not_zero(rs->max_hw_segments, q->max_hw_segments); | ||
563 | 560 | ||
564 | rs->hardsect_size = max(rs->hardsect_size, q->hardsect_size); | 561 | rs->max_segment_size = |
562 | min_not_zero(rs->max_segment_size, q->max_segment_size); | ||
565 | 563 | ||
566 | rs->max_segment_size = | 564 | rs->seg_boundary_mask = |
567 | min_not_zero(rs->max_segment_size, q->max_segment_size); | 565 | min_not_zero(rs->seg_boundary_mask, |
566 | q->seg_boundary_mask); | ||
568 | 567 | ||
569 | rs->seg_boundary_mask = | 568 | rs->no_cluster |= !test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); |
570 | min_not_zero(rs->seg_boundary_mask, | 569 | } |
571 | q->seg_boundary_mask); | 570 | EXPORT_SYMBOL_GPL(dm_set_device_limits); |
572 | 571 | ||
573 | rs->no_cluster |= !test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); | 572 | int dm_get_device(struct dm_target *ti, const char *path, sector_t start, |
574 | } | 573 | sector_t len, int mode, struct dm_dev **result) |
574 | { | ||
575 | int r = __table_get_device(ti->table, ti, path, | ||
576 | start, len, mode, result); | ||
577 | |||
578 | if (!r) | ||
579 | dm_set_device_limits(ti, (*result)->bdev); | ||
575 | 580 | ||
576 | return r; | 581 | return r; |
577 | } | 582 | } |
@@ -939,9 +944,20 @@ void dm_table_postsuspend_targets(struct dm_table *t) | |||
939 | return suspend_targets(t, 1); | 944 | return suspend_targets(t, 1); |
940 | } | 945 | } |
941 | 946 | ||
942 | void dm_table_resume_targets(struct dm_table *t) | 947 | int dm_table_resume_targets(struct dm_table *t) |
943 | { | 948 | { |
944 | int i; | 949 | int i, r = 0; |
950 | |||
951 | for (i = 0; i < t->num_targets; i++) { | ||
952 | struct dm_target *ti = t->targets + i; | ||
953 | |||
954 | if (!ti->type->preresume) | ||
955 | continue; | ||
956 | |||
957 | r = ti->type->preresume(ti); | ||
958 | if (r) | ||
959 | return r; | ||
960 | } | ||
945 | 961 | ||
946 | for (i = 0; i < t->num_targets; i++) { | 962 | for (i = 0; i < t->num_targets; i++) { |
947 | struct dm_target *ti = t->targets + i; | 963 | struct dm_target *ti = t->targets + i; |
@@ -949,6 +965,8 @@ void dm_table_resume_targets(struct dm_table *t) | |||
949 | if (ti->type->resume) | 965 | if (ti->type->resume) |
950 | ti->type->resume(ti); | 966 | ti->type->resume(ti); |
951 | } | 967 | } |
968 | |||
969 | return 0; | ||
952 | } | 970 | } |
953 | 971 | ||
954 | int dm_table_any_congested(struct dm_table *t, int bdi_bits) | 972 | int dm_table_any_congested(struct dm_table *t, int bdi_bits) |
@@ -983,6 +1001,11 @@ int dm_table_flush_all(struct dm_table *t) | |||
983 | { | 1001 | { |
984 | struct list_head *d, *devices = dm_table_get_devices(t); | 1002 | struct list_head *d, *devices = dm_table_get_devices(t); |
985 | int ret = 0; | 1003 | int ret = 0; |
1004 | unsigned i; | ||
1005 | |||
1006 | for (i = 0; i < t->num_targets; i++) | ||
1007 | if (t->targets[i].type->flush) | ||
1008 | t->targets[i].type->flush(&t->targets[i]); | ||
986 | 1009 | ||
987 | for (d = devices->next; d != devices; d = d->next) { | 1010 | for (d = devices->next; d != devices; d = d->next) { |
988 | struct dm_dev *dd = list_entry(d, struct dm_dev, list); | 1011 | struct dm_dev *dd = list_entry(d, struct dm_dev, list); |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index c99bf9f01759..b5764a86c8b5 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/idr.h> | 20 | #include <linux/idr.h> |
21 | #include <linux/hdreg.h> | 21 | #include <linux/hdreg.h> |
22 | #include <linux/blktrace_api.h> | 22 | #include <linux/blktrace_api.h> |
23 | #include <linux/smp_lock.h> | ||
23 | 24 | ||
24 | #define DM_MSG_PREFIX "core" | 25 | #define DM_MSG_PREFIX "core" |
25 | 26 | ||
@@ -101,6 +102,8 @@ struct mapped_device { | |||
101 | mempool_t *io_pool; | 102 | mempool_t *io_pool; |
102 | mempool_t *tio_pool; | 103 | mempool_t *tio_pool; |
103 | 104 | ||
105 | struct bio_set *bs; | ||
106 | |||
104 | /* | 107 | /* |
105 | * Event handling. | 108 | * Event handling. |
106 | */ | 109 | */ |
@@ -121,16 +124,10 @@ struct mapped_device { | |||
121 | static kmem_cache_t *_io_cache; | 124 | static kmem_cache_t *_io_cache; |
122 | static kmem_cache_t *_tio_cache; | 125 | static kmem_cache_t *_tio_cache; |
123 | 126 | ||
124 | static struct bio_set *dm_set; | ||
125 | |||
126 | static int __init local_init(void) | 127 | static int __init local_init(void) |
127 | { | 128 | { |
128 | int r; | 129 | int r; |
129 | 130 | ||
130 | dm_set = bioset_create(16, 16, 4); | ||
131 | if (!dm_set) | ||
132 | return -ENOMEM; | ||
133 | |||
134 | /* allocate a slab for the dm_ios */ | 131 | /* allocate a slab for the dm_ios */ |
135 | _io_cache = kmem_cache_create("dm_io", | 132 | _io_cache = kmem_cache_create("dm_io", |
136 | sizeof(struct dm_io), 0, 0, NULL, NULL); | 133 | sizeof(struct dm_io), 0, 0, NULL, NULL); |
@@ -164,8 +161,6 @@ static void local_exit(void) | |||
164 | kmem_cache_destroy(_tio_cache); | 161 | kmem_cache_destroy(_tio_cache); |
165 | kmem_cache_destroy(_io_cache); | 162 | kmem_cache_destroy(_io_cache); |
166 | 163 | ||
167 | bioset_free(dm_set); | ||
168 | |||
169 | if (unregister_blkdev(_major, _name) < 0) | 164 | if (unregister_blkdev(_major, _name) < 0) |
170 | DMERR("unregister_blkdev failed"); | 165 | DMERR("unregister_blkdev failed"); |
171 | 166 | ||
@@ -288,6 +283,45 @@ static int dm_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo) | |||
288 | return dm_get_geometry(md, geo); | 283 | return dm_get_geometry(md, geo); |
289 | } | 284 | } |
290 | 285 | ||
286 | static int dm_blk_ioctl(struct inode *inode, struct file *file, | ||
287 | unsigned int cmd, unsigned long arg) | ||
288 | { | ||
289 | struct mapped_device *md; | ||
290 | struct dm_table *map; | ||
291 | struct dm_target *tgt; | ||
292 | int r = -ENOTTY; | ||
293 | |||
294 | /* We don't really need this lock, but we do need 'inode'. */ | ||
295 | unlock_kernel(); | ||
296 | |||
297 | md = inode->i_bdev->bd_disk->private_data; | ||
298 | |||
299 | map = dm_get_table(md); | ||
300 | |||
301 | if (!map || !dm_table_get_size(map)) | ||
302 | goto out; | ||
303 | |||
304 | /* We only support devices that have a single target */ | ||
305 | if (dm_table_get_num_targets(map) != 1) | ||
306 | goto out; | ||
307 | |||
308 | tgt = dm_table_get_target(map, 0); | ||
309 | |||
310 | if (dm_suspended(md)) { | ||
311 | r = -EAGAIN; | ||
312 | goto out; | ||
313 | } | ||
314 | |||
315 | if (tgt->type->ioctl) | ||
316 | r = tgt->type->ioctl(tgt, inode, file, cmd, arg); | ||
317 | |||
318 | out: | ||
319 | dm_table_put(map); | ||
320 | |||
321 | lock_kernel(); | ||
322 | return r; | ||
323 | } | ||
324 | |||
291 | static inline struct dm_io *alloc_io(struct mapped_device *md) | 325 | static inline struct dm_io *alloc_io(struct mapped_device *md) |
292 | { | 326 | { |
293 | return mempool_alloc(md->io_pool, GFP_NOIO); | 327 | return mempool_alloc(md->io_pool, GFP_NOIO); |
@@ -435,7 +469,7 @@ static int clone_endio(struct bio *bio, unsigned int done, int error) | |||
435 | { | 469 | { |
436 | int r = 0; | 470 | int r = 0; |
437 | struct target_io *tio = bio->bi_private; | 471 | struct target_io *tio = bio->bi_private; |
438 | struct dm_io *io = tio->io; | 472 | struct mapped_device *md = tio->io->md; |
439 | dm_endio_fn endio = tio->ti->type->end_io; | 473 | dm_endio_fn endio = tio->ti->type->end_io; |
440 | 474 | ||
441 | if (bio->bi_size) | 475 | if (bio->bi_size) |
@@ -454,9 +488,15 @@ static int clone_endio(struct bio *bio, unsigned int done, int error) | |||
454 | return 1; | 488 | return 1; |
455 | } | 489 | } |
456 | 490 | ||
457 | free_tio(io->md, tio); | 491 | dec_pending(tio->io, error); |
458 | dec_pending(io, error); | 492 | |
493 | /* | ||
494 | * Store md for cleanup instead of tio which is about to get freed. | ||
495 | */ | ||
496 | bio->bi_private = md->bs; | ||
497 | |||
459 | bio_put(bio); | 498 | bio_put(bio); |
499 | free_tio(md, tio); | ||
460 | return r; | 500 | return r; |
461 | } | 501 | } |
462 | 502 | ||
@@ -485,6 +525,7 @@ static void __map_bio(struct dm_target *ti, struct bio *clone, | |||
485 | { | 525 | { |
486 | int r; | 526 | int r; |
487 | sector_t sector; | 527 | sector_t sector; |
528 | struct mapped_device *md; | ||
488 | 529 | ||
489 | /* | 530 | /* |
490 | * Sanity checks. | 531 | * Sanity checks. |
@@ -514,10 +555,14 @@ static void __map_bio(struct dm_target *ti, struct bio *clone, | |||
514 | 555 | ||
515 | else if (r < 0) { | 556 | else if (r < 0) { |
516 | /* error the io and bail out */ | 557 | /* error the io and bail out */ |
517 | struct dm_io *io = tio->io; | 558 | md = tio->io->md; |
518 | free_tio(tio->io->md, tio); | 559 | dec_pending(tio->io, r); |
519 | dec_pending(io, r); | 560 | /* |
561 | * Store bio_set for cleanup. | ||
562 | */ | ||
563 | clone->bi_private = md->bs; | ||
520 | bio_put(clone); | 564 | bio_put(clone); |
565 | free_tio(md, tio); | ||
521 | } | 566 | } |
522 | } | 567 | } |
523 | 568 | ||
@@ -533,7 +578,9 @@ struct clone_info { | |||
533 | 578 | ||
534 | static void dm_bio_destructor(struct bio *bio) | 579 | static void dm_bio_destructor(struct bio *bio) |
535 | { | 580 | { |
536 | bio_free(bio, dm_set); | 581 | struct bio_set *bs = bio->bi_private; |
582 | |||
583 | bio_free(bio, bs); | ||
537 | } | 584 | } |
538 | 585 | ||
539 | /* | 586 | /* |
@@ -541,12 +588,12 @@ static void dm_bio_destructor(struct bio *bio) | |||
541 | */ | 588 | */ |
542 | static struct bio *split_bvec(struct bio *bio, sector_t sector, | 589 | static struct bio *split_bvec(struct bio *bio, sector_t sector, |
543 | unsigned short idx, unsigned int offset, | 590 | unsigned short idx, unsigned int offset, |
544 | unsigned int len) | 591 | unsigned int len, struct bio_set *bs) |
545 | { | 592 | { |
546 | struct bio *clone; | 593 | struct bio *clone; |
547 | struct bio_vec *bv = bio->bi_io_vec + idx; | 594 | struct bio_vec *bv = bio->bi_io_vec + idx; |
548 | 595 | ||
549 | clone = bio_alloc_bioset(GFP_NOIO, 1, dm_set); | 596 | clone = bio_alloc_bioset(GFP_NOIO, 1, bs); |
550 | clone->bi_destructor = dm_bio_destructor; | 597 | clone->bi_destructor = dm_bio_destructor; |
551 | *clone->bi_io_vec = *bv; | 598 | *clone->bi_io_vec = *bv; |
552 | 599 | ||
@@ -566,11 +613,13 @@ static struct bio *split_bvec(struct bio *bio, sector_t sector, | |||
566 | */ | 613 | */ |
567 | static struct bio *clone_bio(struct bio *bio, sector_t sector, | 614 | static struct bio *clone_bio(struct bio *bio, sector_t sector, |
568 | unsigned short idx, unsigned short bv_count, | 615 | unsigned short idx, unsigned short bv_count, |
569 | unsigned int len) | 616 | unsigned int len, struct bio_set *bs) |
570 | { | 617 | { |
571 | struct bio *clone; | 618 | struct bio *clone; |
572 | 619 | ||
573 | clone = bio_clone(bio, GFP_NOIO); | 620 | clone = bio_alloc_bioset(GFP_NOIO, bio->bi_max_vecs, bs); |
621 | __bio_clone(clone, bio); | ||
622 | clone->bi_destructor = dm_bio_destructor; | ||
574 | clone->bi_sector = sector; | 623 | clone->bi_sector = sector; |
575 | clone->bi_idx = idx; | 624 | clone->bi_idx = idx; |
576 | clone->bi_vcnt = idx + bv_count; | 625 | clone->bi_vcnt = idx + bv_count; |
@@ -601,7 +650,8 @@ static void __clone_and_map(struct clone_info *ci) | |||
601 | * the remaining io with a single clone. | 650 | * the remaining io with a single clone. |
602 | */ | 651 | */ |
603 | clone = clone_bio(bio, ci->sector, ci->idx, | 652 | clone = clone_bio(bio, ci->sector, ci->idx, |
604 | bio->bi_vcnt - ci->idx, ci->sector_count); | 653 | bio->bi_vcnt - ci->idx, ci->sector_count, |
654 | ci->md->bs); | ||
605 | __map_bio(ti, clone, tio); | 655 | __map_bio(ti, clone, tio); |
606 | ci->sector_count = 0; | 656 | ci->sector_count = 0; |
607 | 657 | ||
@@ -624,7 +674,8 @@ static void __clone_and_map(struct clone_info *ci) | |||
624 | len += bv_len; | 674 | len += bv_len; |
625 | } | 675 | } |
626 | 676 | ||
627 | clone = clone_bio(bio, ci->sector, ci->idx, i - ci->idx, len); | 677 | clone = clone_bio(bio, ci->sector, ci->idx, i - ci->idx, len, |
678 | ci->md->bs); | ||
628 | __map_bio(ti, clone, tio); | 679 | __map_bio(ti, clone, tio); |
629 | 680 | ||
630 | ci->sector += len; | 681 | ci->sector += len; |
@@ -653,7 +704,8 @@ static void __clone_and_map(struct clone_info *ci) | |||
653 | len = min(remaining, max); | 704 | len = min(remaining, max); |
654 | 705 | ||
655 | clone = split_bvec(bio, ci->sector, ci->idx, | 706 | clone = split_bvec(bio, ci->sector, ci->idx, |
656 | bv->bv_offset + offset, len); | 707 | bv->bv_offset + offset, len, |
708 | ci->md->bs); | ||
657 | 709 | ||
658 | __map_bio(ti, clone, tio); | 710 | __map_bio(ti, clone, tio); |
659 | 711 | ||
@@ -903,7 +955,7 @@ static struct mapped_device *alloc_dev(int minor) | |||
903 | 955 | ||
904 | md->queue = blk_alloc_queue(GFP_KERNEL); | 956 | md->queue = blk_alloc_queue(GFP_KERNEL); |
905 | if (!md->queue) | 957 | if (!md->queue) |
906 | goto bad1; | 958 | goto bad1_free_minor; |
907 | 959 | ||
908 | md->queue->queuedata = md; | 960 | md->queue->queuedata = md; |
909 | md->queue->backing_dev_info.congested_fn = dm_any_congested; | 961 | md->queue->backing_dev_info.congested_fn = dm_any_congested; |
@@ -921,6 +973,10 @@ static struct mapped_device *alloc_dev(int minor) | |||
921 | if (!md->tio_pool) | 973 | if (!md->tio_pool) |
922 | goto bad3; | 974 | goto bad3; |
923 | 975 | ||
976 | md->bs = bioset_create(16, 16, 4); | ||
977 | if (!md->bs) | ||
978 | goto bad_no_bioset; | ||
979 | |||
924 | md->disk = alloc_disk(1); | 980 | md->disk = alloc_disk(1); |
925 | if (!md->disk) | 981 | if (!md->disk) |
926 | goto bad4; | 982 | goto bad4; |
@@ -948,11 +1004,14 @@ static struct mapped_device *alloc_dev(int minor) | |||
948 | return md; | 1004 | return md; |
949 | 1005 | ||
950 | bad4: | 1006 | bad4: |
1007 | bioset_free(md->bs); | ||
1008 | bad_no_bioset: | ||
951 | mempool_destroy(md->tio_pool); | 1009 | mempool_destroy(md->tio_pool); |
952 | bad3: | 1010 | bad3: |
953 | mempool_destroy(md->io_pool); | 1011 | mempool_destroy(md->io_pool); |
954 | bad2: | 1012 | bad2: |
955 | blk_cleanup_queue(md->queue); | 1013 | blk_cleanup_queue(md->queue); |
1014 | bad1_free_minor: | ||
956 | free_minor(minor); | 1015 | free_minor(minor); |
957 | bad1: | 1016 | bad1: |
958 | module_put(THIS_MODULE); | 1017 | module_put(THIS_MODULE); |
@@ -971,6 +1030,7 @@ static void free_dev(struct mapped_device *md) | |||
971 | } | 1030 | } |
972 | mempool_destroy(md->tio_pool); | 1031 | mempool_destroy(md->tio_pool); |
973 | mempool_destroy(md->io_pool); | 1032 | mempool_destroy(md->io_pool); |
1033 | bioset_free(md->bs); | ||
974 | del_gendisk(md->disk); | 1034 | del_gendisk(md->disk); |
975 | free_minor(minor); | 1035 | free_minor(minor); |
976 | 1036 | ||
@@ -1319,7 +1379,9 @@ int dm_resume(struct mapped_device *md) | |||
1319 | if (!map || !dm_table_get_size(map)) | 1379 | if (!map || !dm_table_get_size(map)) |
1320 | goto out; | 1380 | goto out; |
1321 | 1381 | ||
1322 | dm_table_resume_targets(map); | 1382 | r = dm_table_resume_targets(map); |
1383 | if (r) | ||
1384 | goto out; | ||
1323 | 1385 | ||
1324 | down_write(&md->io_lock); | 1386 | down_write(&md->io_lock); |
1325 | clear_bit(DMF_BLOCK_IO, &md->flags); | 1387 | clear_bit(DMF_BLOCK_IO, &md->flags); |
@@ -1337,6 +1399,8 @@ int dm_resume(struct mapped_device *md) | |||
1337 | 1399 | ||
1338 | dm_table_unplug_all(map); | 1400 | dm_table_unplug_all(map); |
1339 | 1401 | ||
1402 | kobject_uevent(&md->disk->kobj, KOBJ_CHANGE); | ||
1403 | |||
1340 | r = 0; | 1404 | r = 0; |
1341 | 1405 | ||
1342 | out: | 1406 | out: |
@@ -1377,6 +1441,7 @@ int dm_suspended(struct mapped_device *md) | |||
1377 | static struct block_device_operations dm_blk_dops = { | 1441 | static struct block_device_operations dm_blk_dops = { |
1378 | .open = dm_blk_open, | 1442 | .open = dm_blk_open, |
1379 | .release = dm_blk_close, | 1443 | .release = dm_blk_close, |
1444 | .ioctl = dm_blk_ioctl, | ||
1380 | .getgeo = dm_blk_getgeo, | 1445 | .getgeo = dm_blk_getgeo, |
1381 | .owner = THIS_MODULE | 1446 | .owner = THIS_MODULE |
1382 | }; | 1447 | }; |
diff --git a/drivers/md/dm.h b/drivers/md/dm.h index 3c03c0ecab7e..a48ec5e3c1f4 100644 --- a/drivers/md/dm.h +++ b/drivers/md/dm.h | |||
@@ -21,6 +21,11 @@ | |||
21 | #define DMERR(f, arg...) printk(KERN_ERR DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg) | 21 | #define DMERR(f, arg...) printk(KERN_ERR DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg) |
22 | #define DMWARN(f, arg...) printk(KERN_WARNING DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg) | 22 | #define DMWARN(f, arg...) printk(KERN_WARNING DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg) |
23 | #define DMINFO(f, arg...) printk(KERN_INFO DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg) | 23 | #define DMINFO(f, arg...) printk(KERN_INFO DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg) |
24 | #ifdef CONFIG_DM_DEBUG | ||
25 | # define DMDEBUG(f, arg...) printk(KERN_DEBUG DM_NAME ": " DM_MSG_PREFIX " DEBUG: " f "\n", ## arg) | ||
26 | #else | ||
27 | # define DMDEBUG(f, arg...) do {} while (0) | ||
28 | #endif | ||
24 | 29 | ||
25 | #define DMEMIT(x...) sz += ((sz >= maxlen) ? \ | 30 | #define DMEMIT(x...) sz += ((sz >= maxlen) ? \ |
26 | 0 : scnprintf(result + sz, maxlen - sz, x)) | 31 | 0 : scnprintf(result + sz, maxlen - sz, x)) |
@@ -52,7 +57,7 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q); | |||
52 | struct list_head *dm_table_get_devices(struct dm_table *t); | 57 | struct list_head *dm_table_get_devices(struct dm_table *t); |
53 | void dm_table_presuspend_targets(struct dm_table *t); | 58 | void dm_table_presuspend_targets(struct dm_table *t); |
54 | void dm_table_postsuspend_targets(struct dm_table *t); | 59 | void dm_table_postsuspend_targets(struct dm_table *t); |
55 | void dm_table_resume_targets(struct dm_table *t); | 60 | int dm_table_resume_targets(struct dm_table *t); |
56 | int dm_table_any_congested(struct dm_table *t, int bdi_bits); | 61 | int dm_table_any_congested(struct dm_table *t, int bdi_bits); |
57 | void dm_table_unplug_all(struct dm_table *t); | 62 | void dm_table_unplug_all(struct dm_table *t); |
58 | int dm_table_flush_all(struct dm_table *t); | 63 | int dm_table_flush_all(struct dm_table *t); |
diff --git a/drivers/md/linear.c b/drivers/md/linear.c index b99c19c7eb22..c625ddb8833d 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c | |||
@@ -111,6 +111,19 @@ static int linear_issue_flush(request_queue_t *q, struct gendisk *disk, | |||
111 | return ret; | 111 | return ret; |
112 | } | 112 | } |
113 | 113 | ||
114 | static int linear_congested(void *data, int bits) | ||
115 | { | ||
116 | mddev_t *mddev = data; | ||
117 | linear_conf_t *conf = mddev_to_conf(mddev); | ||
118 | int i, ret = 0; | ||
119 | |||
120 | for (i = 0; i < mddev->raid_disks && !ret ; i++) { | ||
121 | request_queue_t *q = bdev_get_queue(conf->disks[i].rdev->bdev); | ||
122 | ret |= bdi_congested(&q->backing_dev_info, bits); | ||
123 | } | ||
124 | return ret; | ||
125 | } | ||
126 | |||
114 | static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | 127 | static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) |
115 | { | 128 | { |
116 | linear_conf_t *conf; | 129 | linear_conf_t *conf; |
@@ -269,6 +282,8 @@ static int linear_run (mddev_t *mddev) | |||
269 | blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec); | 282 | blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec); |
270 | mddev->queue->unplug_fn = linear_unplug; | 283 | mddev->queue->unplug_fn = linear_unplug; |
271 | mddev->queue->issue_flush_fn = linear_issue_flush; | 284 | mddev->queue->issue_flush_fn = linear_issue_flush; |
285 | mddev->queue->backing_dev_info.congested_fn = linear_congested; | ||
286 | mddev->queue->backing_dev_info.congested_data = mddev; | ||
272 | return 0; | 287 | return 0; |
273 | } | 288 | } |
274 | 289 | ||
diff --git a/drivers/md/md.c b/drivers/md/md.c index 8dbab2ef3885..38a0a5741d52 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -389,8 +389,12 @@ static int super_written(struct bio *bio, unsigned int bytes_done, int error) | |||
389 | if (bio->bi_size) | 389 | if (bio->bi_size) |
390 | return 1; | 390 | return 1; |
391 | 391 | ||
392 | if (error || !test_bit(BIO_UPTODATE, &bio->bi_flags)) | 392 | if (error || !test_bit(BIO_UPTODATE, &bio->bi_flags)) { |
393 | printk("md: super_written gets error=%d, uptodate=%d\n", | ||
394 | error, test_bit(BIO_UPTODATE, &bio->bi_flags)); | ||
395 | WARN_ON(test_bit(BIO_UPTODATE, &bio->bi_flags)); | ||
393 | md_error(mddev, rdev); | 396 | md_error(mddev, rdev); |
397 | } | ||
394 | 398 | ||
395 | if (atomic_dec_and_test(&mddev->pending_writes)) | 399 | if (atomic_dec_and_test(&mddev->pending_writes)) |
396 | wake_up(&mddev->sb_wait); | 400 | wake_up(&mddev->sb_wait); |
@@ -1587,7 +1591,7 @@ static void sync_sbs(mddev_t * mddev, int nospares) | |||
1587 | } | 1591 | } |
1588 | } | 1592 | } |
1589 | 1593 | ||
1590 | void md_update_sb(mddev_t * mddev) | 1594 | static void md_update_sb(mddev_t * mddev, int force_change) |
1591 | { | 1595 | { |
1592 | int err; | 1596 | int err; |
1593 | struct list_head *tmp; | 1597 | struct list_head *tmp; |
@@ -1598,7 +1602,18 @@ void md_update_sb(mddev_t * mddev) | |||
1598 | repeat: | 1602 | repeat: |
1599 | spin_lock_irq(&mddev->write_lock); | 1603 | spin_lock_irq(&mddev->write_lock); |
1600 | 1604 | ||
1601 | if (mddev->degraded && mddev->sb_dirty == 3) | 1605 | set_bit(MD_CHANGE_PENDING, &mddev->flags); |
1606 | if (test_and_clear_bit(MD_CHANGE_DEVS, &mddev->flags)) | ||
1607 | force_change = 1; | ||
1608 | if (test_and_clear_bit(MD_CHANGE_CLEAN, &mddev->flags)) | ||
1609 | /* just a clean<-> dirty transition, possibly leave spares alone, | ||
1610 | * though if events isn't the right even/odd, we will have to do | ||
1611 | * spares after all | ||
1612 | */ | ||
1613 | nospares = 1; | ||
1614 | if (force_change) | ||
1615 | nospares = 0; | ||
1616 | if (mddev->degraded) | ||
1602 | /* If the array is degraded, then skipping spares is both | 1617 | /* If the array is degraded, then skipping spares is both |
1603 | * dangerous and fairly pointless. | 1618 | * dangerous and fairly pointless. |
1604 | * Dangerous because a device that was removed from the array | 1619 | * Dangerous because a device that was removed from the array |
@@ -1608,20 +1623,14 @@ repeat: | |||
1608 | * then a recovery will happen and soon that array won't | 1623 | * then a recovery will happen and soon that array won't |
1609 | * be degraded any more and the spare can go back to sleep then. | 1624 | * be degraded any more and the spare can go back to sleep then. |
1610 | */ | 1625 | */ |
1611 | mddev->sb_dirty = 1; | 1626 | nospares = 0; |
1612 | 1627 | ||
1613 | sync_req = mddev->in_sync; | 1628 | sync_req = mddev->in_sync; |
1614 | mddev->utime = get_seconds(); | 1629 | mddev->utime = get_seconds(); |
1615 | if (mddev->sb_dirty == 3) | ||
1616 | /* just a clean<-> dirty transition, possibly leave spares alone, | ||
1617 | * though if events isn't the right even/odd, we will have to do | ||
1618 | * spares after all | ||
1619 | */ | ||
1620 | nospares = 1; | ||
1621 | 1630 | ||
1622 | /* If this is just a dirty<->clean transition, and the array is clean | 1631 | /* If this is just a dirty<->clean transition, and the array is clean |
1623 | * and 'events' is odd, we can roll back to the previous clean state */ | 1632 | * and 'events' is odd, we can roll back to the previous clean state */ |
1624 | if (mddev->sb_dirty == 3 | 1633 | if (nospares |
1625 | && (mddev->in_sync && mddev->recovery_cp == MaxSector) | 1634 | && (mddev->in_sync && mddev->recovery_cp == MaxSector) |
1626 | && (mddev->events & 1)) | 1635 | && (mddev->events & 1)) |
1627 | mddev->events--; | 1636 | mddev->events--; |
@@ -1652,7 +1661,6 @@ repeat: | |||
1652 | MD_BUG(); | 1661 | MD_BUG(); |
1653 | mddev->events --; | 1662 | mddev->events --; |
1654 | } | 1663 | } |
1655 | mddev->sb_dirty = 2; | ||
1656 | sync_sbs(mddev, nospares); | 1664 | sync_sbs(mddev, nospares); |
1657 | 1665 | ||
1658 | /* | 1666 | /* |
@@ -1660,7 +1668,7 @@ repeat: | |||
1660 | * nonpersistent superblocks | 1668 | * nonpersistent superblocks |
1661 | */ | 1669 | */ |
1662 | if (!mddev->persistent) { | 1670 | if (!mddev->persistent) { |
1663 | mddev->sb_dirty = 0; | 1671 | clear_bit(MD_CHANGE_PENDING, &mddev->flags); |
1664 | spin_unlock_irq(&mddev->write_lock); | 1672 | spin_unlock_irq(&mddev->write_lock); |
1665 | wake_up(&mddev->sb_wait); | 1673 | wake_up(&mddev->sb_wait); |
1666 | return; | 1674 | return; |
@@ -1697,20 +1705,20 @@ repeat: | |||
1697 | break; | 1705 | break; |
1698 | } | 1706 | } |
1699 | md_super_wait(mddev); | 1707 | md_super_wait(mddev); |
1700 | /* if there was a failure, sb_dirty was set to 1, and we re-write super */ | 1708 | /* if there was a failure, MD_CHANGE_DEVS was set, and we re-write super */ |
1701 | 1709 | ||
1702 | spin_lock_irq(&mddev->write_lock); | 1710 | spin_lock_irq(&mddev->write_lock); |
1703 | if (mddev->in_sync != sync_req|| mddev->sb_dirty == 1) { | 1711 | if (mddev->in_sync != sync_req || |
1712 | test_bit(MD_CHANGE_DEVS, &mddev->flags)) { | ||
1704 | /* have to write it out again */ | 1713 | /* have to write it out again */ |
1705 | spin_unlock_irq(&mddev->write_lock); | 1714 | spin_unlock_irq(&mddev->write_lock); |
1706 | goto repeat; | 1715 | goto repeat; |
1707 | } | 1716 | } |
1708 | mddev->sb_dirty = 0; | 1717 | clear_bit(MD_CHANGE_PENDING, &mddev->flags); |
1709 | spin_unlock_irq(&mddev->write_lock); | 1718 | spin_unlock_irq(&mddev->write_lock); |
1710 | wake_up(&mddev->sb_wait); | 1719 | wake_up(&mddev->sb_wait); |
1711 | 1720 | ||
1712 | } | 1721 | } |
1713 | EXPORT_SYMBOL_GPL(md_update_sb); | ||
1714 | 1722 | ||
1715 | /* words written to sysfs files may, or my not, be \n terminated. | 1723 | /* words written to sysfs files may, or my not, be \n terminated. |
1716 | * We want to accept with case. For this we use cmd_match. | 1724 | * We want to accept with case. For this we use cmd_match. |
@@ -1783,7 +1791,7 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
1783 | else { | 1791 | else { |
1784 | mddev_t *mddev = rdev->mddev; | 1792 | mddev_t *mddev = rdev->mddev; |
1785 | kick_rdev_from_array(rdev); | 1793 | kick_rdev_from_array(rdev); |
1786 | md_update_sb(mddev); | 1794 | md_update_sb(mddev, 1); |
1787 | md_new_event(mddev); | 1795 | md_new_event(mddev); |
1788 | err = 0; | 1796 | err = 0; |
1789 | } | 1797 | } |
@@ -2426,7 +2434,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len) | |||
2426 | spin_lock_irq(&mddev->write_lock); | 2434 | spin_lock_irq(&mddev->write_lock); |
2427 | if (atomic_read(&mddev->writes_pending) == 0) { | 2435 | if (atomic_read(&mddev->writes_pending) == 0) { |
2428 | mddev->in_sync = 1; | 2436 | mddev->in_sync = 1; |
2429 | mddev->sb_dirty = 1; | 2437 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); |
2430 | } | 2438 | } |
2431 | spin_unlock_irq(&mddev->write_lock); | 2439 | spin_unlock_irq(&mddev->write_lock); |
2432 | } else { | 2440 | } else { |
@@ -2438,7 +2446,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len) | |||
2438 | case active: | 2446 | case active: |
2439 | if (mddev->pers) { | 2447 | if (mddev->pers) { |
2440 | restart_array(mddev); | 2448 | restart_array(mddev); |
2441 | mddev->sb_dirty = 0; | 2449 | clear_bit(MD_CHANGE_CLEAN, &mddev->flags); |
2442 | wake_up(&mddev->sb_wait); | 2450 | wake_up(&mddev->sb_wait); |
2443 | err = 0; | 2451 | err = 0; |
2444 | } else { | 2452 | } else { |
@@ -2520,6 +2528,36 @@ static struct md_sysfs_entry md_new_device = | |||
2520 | __ATTR(new_dev, S_IWUSR, null_show, new_dev_store); | 2528 | __ATTR(new_dev, S_IWUSR, null_show, new_dev_store); |
2521 | 2529 | ||
2522 | static ssize_t | 2530 | static ssize_t |
2531 | bitmap_store(mddev_t *mddev, const char *buf, size_t len) | ||
2532 | { | ||
2533 | char *end; | ||
2534 | unsigned long chunk, end_chunk; | ||
2535 | |||
2536 | if (!mddev->bitmap) | ||
2537 | goto out; | ||
2538 | /* buf should be <chunk> <chunk> ... or <chunk>-<chunk> ... (range) */ | ||
2539 | while (*buf) { | ||
2540 | chunk = end_chunk = simple_strtoul(buf, &end, 0); | ||
2541 | if (buf == end) break; | ||
2542 | if (*end == '-') { /* range */ | ||
2543 | buf = end + 1; | ||
2544 | end_chunk = simple_strtoul(buf, &end, 0); | ||
2545 | if (buf == end) break; | ||
2546 | } | ||
2547 | if (*end && !isspace(*end)) break; | ||
2548 | bitmap_dirty_bits(mddev->bitmap, chunk, end_chunk); | ||
2549 | buf = end; | ||
2550 | while (isspace(*buf)) buf++; | ||
2551 | } | ||
2552 | bitmap_unplug(mddev->bitmap); /* flush the bits to disk */ | ||
2553 | out: | ||
2554 | return len; | ||
2555 | } | ||
2556 | |||
2557 | static struct md_sysfs_entry md_bitmap = | ||
2558 | __ATTR(bitmap_set_bits, S_IWUSR, null_show, bitmap_store); | ||
2559 | |||
2560 | static ssize_t | ||
2523 | size_show(mddev_t *mddev, char *page) | 2561 | size_show(mddev_t *mddev, char *page) |
2524 | { | 2562 | { |
2525 | return sprintf(page, "%llu\n", (unsigned long long)mddev->size); | 2563 | return sprintf(page, "%llu\n", (unsigned long long)mddev->size); |
@@ -2543,7 +2581,7 @@ size_store(mddev_t *mddev, const char *buf, size_t len) | |||
2543 | 2581 | ||
2544 | if (mddev->pers) { | 2582 | if (mddev->pers) { |
2545 | err = update_size(mddev, size); | 2583 | err = update_size(mddev, size); |
2546 | md_update_sb(mddev); | 2584 | md_update_sb(mddev, 1); |
2547 | } else { | 2585 | } else { |
2548 | if (mddev->size == 0 || | 2586 | if (mddev->size == 0 || |
2549 | mddev->size > size) | 2587 | mddev->size > size) |
@@ -2839,6 +2877,7 @@ static struct attribute *md_redundancy_attrs[] = { | |||
2839 | &md_sync_completed.attr, | 2877 | &md_sync_completed.attr, |
2840 | &md_suspend_lo.attr, | 2878 | &md_suspend_lo.attr, |
2841 | &md_suspend_hi.attr, | 2879 | &md_suspend_hi.attr, |
2880 | &md_bitmap.attr, | ||
2842 | NULL, | 2881 | NULL, |
2843 | }; | 2882 | }; |
2844 | static struct attribute_group md_redundancy_group = { | 2883 | static struct attribute_group md_redundancy_group = { |
@@ -3111,8 +3150,8 @@ static int do_md_run(mddev_t * mddev) | |||
3111 | 3150 | ||
3112 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 3151 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
3113 | 3152 | ||
3114 | if (mddev->sb_dirty) | 3153 | if (mddev->flags) |
3115 | md_update_sb(mddev); | 3154 | md_update_sb(mddev, 0); |
3116 | 3155 | ||
3117 | set_capacity(disk, mddev->array_size<<1); | 3156 | set_capacity(disk, mddev->array_size<<1); |
3118 | 3157 | ||
@@ -3275,10 +3314,10 @@ static int do_md_stop(mddev_t * mddev, int mode) | |||
3275 | if (mddev->ro) | 3314 | if (mddev->ro) |
3276 | mddev->ro = 0; | 3315 | mddev->ro = 0; |
3277 | } | 3316 | } |
3278 | if (!mddev->in_sync || mddev->sb_dirty) { | 3317 | if (!mddev->in_sync || mddev->flags) { |
3279 | /* mark array as shutdown cleanly */ | 3318 | /* mark array as shutdown cleanly */ |
3280 | mddev->in_sync = 1; | 3319 | mddev->in_sync = 1; |
3281 | md_update_sb(mddev); | 3320 | md_update_sb(mddev, 1); |
3282 | } | 3321 | } |
3283 | if (mode == 1) | 3322 | if (mode == 1) |
3284 | set_disk_ro(disk, 1); | 3323 | set_disk_ro(disk, 1); |
@@ -3374,6 +3413,7 @@ static void autorun_devices(int part) | |||
3374 | 3413 | ||
3375 | printk(KERN_INFO "md: autorun ...\n"); | 3414 | printk(KERN_INFO "md: autorun ...\n"); |
3376 | while (!list_empty(&pending_raid_disks)) { | 3415 | while (!list_empty(&pending_raid_disks)) { |
3416 | int unit; | ||
3377 | dev_t dev; | 3417 | dev_t dev; |
3378 | LIST_HEAD(candidates); | 3418 | LIST_HEAD(candidates); |
3379 | rdev0 = list_entry(pending_raid_disks.next, | 3419 | rdev0 = list_entry(pending_raid_disks.next, |
@@ -3393,16 +3433,19 @@ static void autorun_devices(int part) | |||
3393 | * mostly sane superblocks. It's time to allocate the | 3433 | * mostly sane superblocks. It's time to allocate the |
3394 | * mddev. | 3434 | * mddev. |
3395 | */ | 3435 | */ |
3396 | if (rdev0->preferred_minor < 0 || rdev0->preferred_minor >= MAX_MD_DEVS) { | 3436 | if (part) { |
3437 | dev = MKDEV(mdp_major, | ||
3438 | rdev0->preferred_minor << MdpMinorShift); | ||
3439 | unit = MINOR(dev) >> MdpMinorShift; | ||
3440 | } else { | ||
3441 | dev = MKDEV(MD_MAJOR, rdev0->preferred_minor); | ||
3442 | unit = MINOR(dev); | ||
3443 | } | ||
3444 | if (rdev0->preferred_minor != unit) { | ||
3397 | printk(KERN_INFO "md: unit number in %s is bad: %d\n", | 3445 | printk(KERN_INFO "md: unit number in %s is bad: %d\n", |
3398 | bdevname(rdev0->bdev, b), rdev0->preferred_minor); | 3446 | bdevname(rdev0->bdev, b), rdev0->preferred_minor); |
3399 | break; | 3447 | break; |
3400 | } | 3448 | } |
3401 | if (part) | ||
3402 | dev = MKDEV(mdp_major, | ||
3403 | rdev0->preferred_minor << MdpMinorShift); | ||
3404 | else | ||
3405 | dev = MKDEV(MD_MAJOR, rdev0->preferred_minor); | ||
3406 | 3449 | ||
3407 | md_probe(dev, NULL, NULL); | 3450 | md_probe(dev, NULL, NULL); |
3408 | mddev = mddev_find(dev); | 3451 | mddev = mddev_find(dev); |
@@ -3440,67 +3483,6 @@ static void autorun_devices(int part) | |||
3440 | printk(KERN_INFO "md: ... autorun DONE.\n"); | 3483 | printk(KERN_INFO "md: ... autorun DONE.\n"); |
3441 | } | 3484 | } |
3442 | 3485 | ||
3443 | /* | ||
3444 | * import RAID devices based on one partition | ||
3445 | * if possible, the array gets run as well. | ||
3446 | */ | ||
3447 | |||
3448 | static int autostart_array(dev_t startdev) | ||
3449 | { | ||
3450 | char b[BDEVNAME_SIZE]; | ||
3451 | int err = -EINVAL, i; | ||
3452 | mdp_super_t *sb = NULL; | ||
3453 | mdk_rdev_t *start_rdev = NULL, *rdev; | ||
3454 | |||
3455 | start_rdev = md_import_device(startdev, 0, 0); | ||
3456 | if (IS_ERR(start_rdev)) | ||
3457 | return err; | ||
3458 | |||
3459 | |||
3460 | /* NOTE: this can only work for 0.90.0 superblocks */ | ||
3461 | sb = (mdp_super_t*)page_address(start_rdev->sb_page); | ||
3462 | if (sb->major_version != 0 || | ||
3463 | sb->minor_version != 90 ) { | ||
3464 | printk(KERN_WARNING "md: can only autostart 0.90.0 arrays\n"); | ||
3465 | export_rdev(start_rdev); | ||
3466 | return err; | ||
3467 | } | ||
3468 | |||
3469 | if (test_bit(Faulty, &start_rdev->flags)) { | ||
3470 | printk(KERN_WARNING | ||
3471 | "md: can not autostart based on faulty %s!\n", | ||
3472 | bdevname(start_rdev->bdev,b)); | ||
3473 | export_rdev(start_rdev); | ||
3474 | return err; | ||
3475 | } | ||
3476 | list_add(&start_rdev->same_set, &pending_raid_disks); | ||
3477 | |||
3478 | for (i = 0; i < MD_SB_DISKS; i++) { | ||
3479 | mdp_disk_t *desc = sb->disks + i; | ||
3480 | dev_t dev = MKDEV(desc->major, desc->minor); | ||
3481 | |||
3482 | if (!dev) | ||
3483 | continue; | ||
3484 | if (dev == startdev) | ||
3485 | continue; | ||
3486 | if (MAJOR(dev) != desc->major || MINOR(dev) != desc->minor) | ||
3487 | continue; | ||
3488 | rdev = md_import_device(dev, 0, 0); | ||
3489 | if (IS_ERR(rdev)) | ||
3490 | continue; | ||
3491 | |||
3492 | list_add(&rdev->same_set, &pending_raid_disks); | ||
3493 | } | ||
3494 | |||
3495 | /* | ||
3496 | * possibly return codes | ||
3497 | */ | ||
3498 | autorun_devices(0); | ||
3499 | return 0; | ||
3500 | |||
3501 | } | ||
3502 | |||
3503 | |||
3504 | static int get_version(void __user * arg) | 3486 | static int get_version(void __user * arg) |
3505 | { | 3487 | { |
3506 | mdu_version_t ver; | 3488 | mdu_version_t ver; |
@@ -3808,7 +3790,7 @@ static int hot_remove_disk(mddev_t * mddev, dev_t dev) | |||
3808 | goto busy; | 3790 | goto busy; |
3809 | 3791 | ||
3810 | kick_rdev_from_array(rdev); | 3792 | kick_rdev_from_array(rdev); |
3811 | md_update_sb(mddev); | 3793 | md_update_sb(mddev, 1); |
3812 | md_new_event(mddev); | 3794 | md_new_event(mddev); |
3813 | 3795 | ||
3814 | return 0; | 3796 | return 0; |
@@ -3885,7 +3867,7 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev) | |||
3885 | 3867 | ||
3886 | rdev->raid_disk = -1; | 3868 | rdev->raid_disk = -1; |
3887 | 3869 | ||
3888 | md_update_sb(mddev); | 3870 | md_update_sb(mddev, 1); |
3889 | 3871 | ||
3890 | /* | 3872 | /* |
3891 | * Kick recovery, maybe this spare has to be added to the | 3873 | * Kick recovery, maybe this spare has to be added to the |
@@ -4016,7 +3998,8 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info) | |||
4016 | 3998 | ||
4017 | mddev->max_disks = MD_SB_DISKS; | 3999 | mddev->max_disks = MD_SB_DISKS; |
4018 | 4000 | ||
4019 | mddev->sb_dirty = 1; | 4001 | mddev->flags = 0; |
4002 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | ||
4020 | 4003 | ||
4021 | mddev->default_bitmap_offset = MD_SB_BYTES >> 9; | 4004 | mddev->default_bitmap_offset = MD_SB_BYTES >> 9; |
4022 | mddev->bitmap_offset = 0; | 4005 | mddev->bitmap_offset = 0; |
@@ -4185,7 +4168,7 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info) | |||
4185 | mddev->bitmap_offset = 0; | 4168 | mddev->bitmap_offset = 0; |
4186 | } | 4169 | } |
4187 | } | 4170 | } |
4188 | md_update_sb(mddev); | 4171 | md_update_sb(mddev, 1); |
4189 | return rv; | 4172 | return rv; |
4190 | } | 4173 | } |
4191 | 4174 | ||
@@ -4259,27 +4242,6 @@ static int md_ioctl(struct inode *inode, struct file *file, | |||
4259 | goto abort; | 4242 | goto abort; |
4260 | } | 4243 | } |
4261 | 4244 | ||
4262 | |||
4263 | if (cmd == START_ARRAY) { | ||
4264 | /* START_ARRAY doesn't need to lock the array as autostart_array | ||
4265 | * does the locking, and it could even be a different array | ||
4266 | */ | ||
4267 | static int cnt = 3; | ||
4268 | if (cnt > 0 ) { | ||
4269 | printk(KERN_WARNING | ||
4270 | "md: %s(pid %d) used deprecated START_ARRAY ioctl. " | ||
4271 | "This will not be supported beyond July 2006\n", | ||
4272 | current->comm, current->pid); | ||
4273 | cnt--; | ||
4274 | } | ||
4275 | err = autostart_array(new_decode_dev(arg)); | ||
4276 | if (err) { | ||
4277 | printk(KERN_WARNING "md: autostart failed!\n"); | ||
4278 | goto abort; | ||
4279 | } | ||
4280 | goto done; | ||
4281 | } | ||
4282 | |||
4283 | err = mddev_lock(mddev); | 4245 | err = mddev_lock(mddev); |
4284 | if (err) { | 4246 | if (err) { |
4285 | printk(KERN_INFO | 4247 | printk(KERN_INFO |
@@ -4687,9 +4649,11 @@ static void status_resync(struct seq_file *seq, mddev_t * mddev) | |||
4687 | seq_printf(seq, " %s =%3u.%u%% (%llu/%llu)", | 4649 | seq_printf(seq, " %s =%3u.%u%% (%llu/%llu)", |
4688 | (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)? | 4650 | (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)? |
4689 | "reshape" : | 4651 | "reshape" : |
4690 | (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) ? | 4652 | (test_bit(MD_RECOVERY_CHECK, &mddev->recovery)? |
4691 | "resync" : "recovery")), | 4653 | "check" : |
4692 | per_milli/10, per_milli % 10, | 4654 | (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) ? |
4655 | "resync" : "recovery"))), | ||
4656 | per_milli/10, per_milli % 10, | ||
4693 | (unsigned long long) resync, | 4657 | (unsigned long long) resync, |
4694 | (unsigned long long) max_blocks); | 4658 | (unsigned long long) max_blocks); |
4695 | 4659 | ||
@@ -5042,12 +5006,12 @@ void md_write_start(mddev_t *mddev, struct bio *bi) | |||
5042 | spin_lock_irq(&mddev->write_lock); | 5006 | spin_lock_irq(&mddev->write_lock); |
5043 | if (mddev->in_sync) { | 5007 | if (mddev->in_sync) { |
5044 | mddev->in_sync = 0; | 5008 | mddev->in_sync = 0; |
5045 | mddev->sb_dirty = 3; | 5009 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); |
5046 | md_wakeup_thread(mddev->thread); | 5010 | md_wakeup_thread(mddev->thread); |
5047 | } | 5011 | } |
5048 | spin_unlock_irq(&mddev->write_lock); | 5012 | spin_unlock_irq(&mddev->write_lock); |
5049 | } | 5013 | } |
5050 | wait_event(mddev->sb_wait, mddev->sb_dirty==0); | 5014 | wait_event(mddev->sb_wait, mddev->flags==0); |
5051 | } | 5015 | } |
5052 | 5016 | ||
5053 | void md_write_end(mddev_t *mddev) | 5017 | void md_write_end(mddev_t *mddev) |
@@ -5078,6 +5042,7 @@ void md_do_sync(mddev_t *mddev) | |||
5078 | int skipped = 0; | 5042 | int skipped = 0; |
5079 | struct list_head *rtmp; | 5043 | struct list_head *rtmp; |
5080 | mdk_rdev_t *rdev; | 5044 | mdk_rdev_t *rdev; |
5045 | char *desc; | ||
5081 | 5046 | ||
5082 | /* just incase thread restarts... */ | 5047 | /* just incase thread restarts... */ |
5083 | if (test_bit(MD_RECOVERY_DONE, &mddev->recovery)) | 5048 | if (test_bit(MD_RECOVERY_DONE, &mddev->recovery)) |
@@ -5085,6 +5050,18 @@ void md_do_sync(mddev_t *mddev) | |||
5085 | if (mddev->ro) /* never try to sync a read-only array */ | 5050 | if (mddev->ro) /* never try to sync a read-only array */ |
5086 | return; | 5051 | return; |
5087 | 5052 | ||
5053 | if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { | ||
5054 | if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery)) | ||
5055 | desc = "data-check"; | ||
5056 | else if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) | ||
5057 | desc = "requested-resync"; | ||
5058 | else | ||
5059 | desc = "resync"; | ||
5060 | } else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) | ||
5061 | desc = "reshape"; | ||
5062 | else | ||
5063 | desc = "recovery"; | ||
5064 | |||
5088 | /* we overload curr_resync somewhat here. | 5065 | /* we overload curr_resync somewhat here. |
5089 | * 0 == not engaged in resync at all | 5066 | * 0 == not engaged in resync at all |
5090 | * 2 == checking that there is no conflict with another sync | 5067 | * 2 == checking that there is no conflict with another sync |
@@ -5128,10 +5105,10 @@ void md_do_sync(mddev_t *mddev) | |||
5128 | prepare_to_wait(&resync_wait, &wq, TASK_UNINTERRUPTIBLE); | 5105 | prepare_to_wait(&resync_wait, &wq, TASK_UNINTERRUPTIBLE); |
5129 | if (!kthread_should_stop() && | 5106 | if (!kthread_should_stop() && |
5130 | mddev2->curr_resync >= mddev->curr_resync) { | 5107 | mddev2->curr_resync >= mddev->curr_resync) { |
5131 | printk(KERN_INFO "md: delaying resync of %s" | 5108 | printk(KERN_INFO "md: delaying %s of %s" |
5132 | " until %s has finished resync (they" | 5109 | " until %s has finished (they" |
5133 | " share one or more physical units)\n", | 5110 | " share one or more physical units)\n", |
5134 | mdname(mddev), mdname(mddev2)); | 5111 | desc, mdname(mddev), mdname(mddev2)); |
5135 | mddev_put(mddev2); | 5112 | mddev_put(mddev2); |
5136 | schedule(); | 5113 | schedule(); |
5137 | finish_wait(&resync_wait, &wq); | 5114 | finish_wait(&resync_wait, &wq); |
@@ -5167,12 +5144,12 @@ void md_do_sync(mddev_t *mddev) | |||
5167 | j = rdev->recovery_offset; | 5144 | j = rdev->recovery_offset; |
5168 | } | 5145 | } |
5169 | 5146 | ||
5170 | printk(KERN_INFO "md: syncing RAID array %s\n", mdname(mddev)); | 5147 | printk(KERN_INFO "md: %s of RAID array %s\n", desc, mdname(mddev)); |
5171 | printk(KERN_INFO "md: minimum _guaranteed_ reconstruction speed:" | 5148 | printk(KERN_INFO "md: minimum _guaranteed_ speed:" |
5172 | " %d KB/sec/disc.\n", speed_min(mddev)); | 5149 | " %d KB/sec/disk.\n", speed_min(mddev)); |
5173 | printk(KERN_INFO "md: using maximum available idle IO bandwidth " | 5150 | printk(KERN_INFO "md: using maximum available idle IO bandwidth " |
5174 | "(but not more than %d KB/sec) for reconstruction.\n", | 5151 | "(but not more than %d KB/sec) for %s.\n", |
5175 | speed_max(mddev)); | 5152 | speed_max(mddev), desc); |
5176 | 5153 | ||
5177 | is_mddev_idle(mddev); /* this also initializes IO event counters */ | 5154 | is_mddev_idle(mddev); /* this also initializes IO event counters */ |
5178 | 5155 | ||
@@ -5198,8 +5175,8 @@ void md_do_sync(mddev_t *mddev) | |||
5198 | 5175 | ||
5199 | if (j>2) { | 5176 | if (j>2) { |
5200 | printk(KERN_INFO | 5177 | printk(KERN_INFO |
5201 | "md: resuming recovery of %s from checkpoint.\n", | 5178 | "md: resuming %s of %s from checkpoint.\n", |
5202 | mdname(mddev)); | 5179 | desc, mdname(mddev)); |
5203 | mddev->curr_resync = j; | 5180 | mddev->curr_resync = j; |
5204 | } | 5181 | } |
5205 | 5182 | ||
@@ -5282,7 +5259,7 @@ void md_do_sync(mddev_t *mddev) | |||
5282 | } | 5259 | } |
5283 | } | 5260 | } |
5284 | } | 5261 | } |
5285 | printk(KERN_INFO "md: %s: sync done.\n",mdname(mddev)); | 5262 | printk(KERN_INFO "md: %s: %s done.\n",mdname(mddev), desc); |
5286 | /* | 5263 | /* |
5287 | * this also signals 'finished resyncing' to md_stop | 5264 | * this also signals 'finished resyncing' to md_stop |
5288 | */ | 5265 | */ |
@@ -5302,8 +5279,8 @@ void md_do_sync(mddev_t *mddev) | |||
5302 | if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { | 5279 | if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { |
5303 | if (mddev->curr_resync >= mddev->recovery_cp) { | 5280 | if (mddev->curr_resync >= mddev->recovery_cp) { |
5304 | printk(KERN_INFO | 5281 | printk(KERN_INFO |
5305 | "md: checkpointing recovery of %s.\n", | 5282 | "md: checkpointing %s of %s.\n", |
5306 | mdname(mddev)); | 5283 | desc, mdname(mddev)); |
5307 | mddev->recovery_cp = mddev->curr_resync; | 5284 | mddev->recovery_cp = mddev->curr_resync; |
5308 | } | 5285 | } |
5309 | } else | 5286 | } else |
@@ -5317,7 +5294,6 @@ void md_do_sync(mddev_t *mddev) | |||
5317 | !test_bit(In_sync, &rdev->flags) && | 5294 | !test_bit(In_sync, &rdev->flags) && |
5318 | rdev->recovery_offset < mddev->curr_resync) | 5295 | rdev->recovery_offset < mddev->curr_resync) |
5319 | rdev->recovery_offset = mddev->curr_resync; | 5296 | rdev->recovery_offset = mddev->curr_resync; |
5320 | mddev->sb_dirty = 1; | ||
5321 | } | 5297 | } |
5322 | } | 5298 | } |
5323 | 5299 | ||
@@ -5374,7 +5350,7 @@ void md_check_recovery(mddev_t *mddev) | |||
5374 | } | 5350 | } |
5375 | 5351 | ||
5376 | if ( ! ( | 5352 | if ( ! ( |
5377 | mddev->sb_dirty || | 5353 | mddev->flags || |
5378 | test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) || | 5354 | test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) || |
5379 | test_bit(MD_RECOVERY_DONE, &mddev->recovery) || | 5355 | test_bit(MD_RECOVERY_DONE, &mddev->recovery) || |
5380 | (mddev->safemode == 1) || | 5356 | (mddev->safemode == 1) || |
@@ -5390,14 +5366,14 @@ void md_check_recovery(mddev_t *mddev) | |||
5390 | if (mddev->safemode && !atomic_read(&mddev->writes_pending) && | 5366 | if (mddev->safemode && !atomic_read(&mddev->writes_pending) && |
5391 | !mddev->in_sync && mddev->recovery_cp == MaxSector) { | 5367 | !mddev->in_sync && mddev->recovery_cp == MaxSector) { |
5392 | mddev->in_sync = 1; | 5368 | mddev->in_sync = 1; |
5393 | mddev->sb_dirty = 3; | 5369 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); |
5394 | } | 5370 | } |
5395 | if (mddev->safemode == 1) | 5371 | if (mddev->safemode == 1) |
5396 | mddev->safemode = 0; | 5372 | mddev->safemode = 0; |
5397 | spin_unlock_irq(&mddev->write_lock); | 5373 | spin_unlock_irq(&mddev->write_lock); |
5398 | 5374 | ||
5399 | if (mddev->sb_dirty) | 5375 | if (mddev->flags) |
5400 | md_update_sb(mddev); | 5376 | md_update_sb(mddev, 0); |
5401 | 5377 | ||
5402 | 5378 | ||
5403 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) && | 5379 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) && |
@@ -5416,7 +5392,7 @@ void md_check_recovery(mddev_t *mddev) | |||
5416 | /* activate any spares */ | 5392 | /* activate any spares */ |
5417 | mddev->pers->spare_active(mddev); | 5393 | mddev->pers->spare_active(mddev); |
5418 | } | 5394 | } |
5419 | md_update_sb(mddev); | 5395 | md_update_sb(mddev, 1); |
5420 | 5396 | ||
5421 | /* if array is no-longer degraded, then any saved_raid_disk | 5397 | /* if array is no-longer degraded, then any saved_raid_disk |
5422 | * information must be scrapped | 5398 | * information must be scrapped |
@@ -5556,22 +5532,15 @@ static void md_geninit(void) | |||
5556 | 5532 | ||
5557 | static int __init md_init(void) | 5533 | static int __init md_init(void) |
5558 | { | 5534 | { |
5559 | printk(KERN_INFO "md: md driver %d.%d.%d MAX_MD_DEVS=%d," | ||
5560 | " MD_SB_DISKS=%d\n", | ||
5561 | MD_MAJOR_VERSION, MD_MINOR_VERSION, | ||
5562 | MD_PATCHLEVEL_VERSION, MAX_MD_DEVS, MD_SB_DISKS); | ||
5563 | printk(KERN_INFO "md: bitmap version %d.%d\n", BITMAP_MAJOR_HI, | ||
5564 | BITMAP_MINOR); | ||
5565 | |||
5566 | if (register_blkdev(MAJOR_NR, "md")) | 5535 | if (register_blkdev(MAJOR_NR, "md")) |
5567 | return -1; | 5536 | return -1; |
5568 | if ((mdp_major=register_blkdev(0, "mdp"))<=0) { | 5537 | if ((mdp_major=register_blkdev(0, "mdp"))<=0) { |
5569 | unregister_blkdev(MAJOR_NR, "md"); | 5538 | unregister_blkdev(MAJOR_NR, "md"); |
5570 | return -1; | 5539 | return -1; |
5571 | } | 5540 | } |
5572 | blk_register_region(MKDEV(MAJOR_NR, 0), MAX_MD_DEVS, THIS_MODULE, | 5541 | blk_register_region(MKDEV(MAJOR_NR, 0), 1UL<<MINORBITS, THIS_MODULE, |
5573 | md_probe, NULL, NULL); | 5542 | md_probe, NULL, NULL); |
5574 | blk_register_region(MKDEV(mdp_major, 0), MAX_MD_DEVS<<MdpMinorShift, THIS_MODULE, | 5543 | blk_register_region(MKDEV(mdp_major, 0), 1UL<<MINORBITS, THIS_MODULE, |
5575 | md_probe, NULL, NULL); | 5544 | md_probe, NULL, NULL); |
5576 | 5545 | ||
5577 | register_reboot_notifier(&md_notifier); | 5546 | register_reboot_notifier(&md_notifier); |
@@ -5630,8 +5599,8 @@ static __exit void md_exit(void) | |||
5630 | mddev_t *mddev; | 5599 | mddev_t *mddev; |
5631 | struct list_head *tmp; | 5600 | struct list_head *tmp; |
5632 | 5601 | ||
5633 | blk_unregister_region(MKDEV(MAJOR_NR,0), MAX_MD_DEVS); | 5602 | blk_unregister_region(MKDEV(MAJOR_NR,0), 1U << MINORBITS); |
5634 | blk_unregister_region(MKDEV(mdp_major,0), MAX_MD_DEVS << MdpMinorShift); | 5603 | blk_unregister_region(MKDEV(mdp_major,0), 1U << MINORBITS); |
5635 | 5604 | ||
5636 | unregister_blkdev(MAJOR_NR,"md"); | 5605 | unregister_blkdev(MAJOR_NR,"md"); |
5637 | unregister_blkdev(mdp_major, "mdp"); | 5606 | unregister_blkdev(mdp_major, "mdp"); |
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 1cc9de44ce86..171ff41b52b0 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c | |||
@@ -228,6 +228,28 @@ static int multipath_issue_flush(request_queue_t *q, struct gendisk *disk, | |||
228 | rcu_read_unlock(); | 228 | rcu_read_unlock(); |
229 | return ret; | 229 | return ret; |
230 | } | 230 | } |
231 | static int multipath_congested(void *data, int bits) | ||
232 | { | ||
233 | mddev_t *mddev = data; | ||
234 | multipath_conf_t *conf = mddev_to_conf(mddev); | ||
235 | int i, ret = 0; | ||
236 | |||
237 | rcu_read_lock(); | ||
238 | for (i = 0; i < mddev->raid_disks ; i++) { | ||
239 | mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev); | ||
240 | if (rdev && !test_bit(Faulty, &rdev->flags)) { | ||
241 | request_queue_t *q = bdev_get_queue(rdev->bdev); | ||
242 | |||
243 | ret |= bdi_congested(&q->backing_dev_info, bits); | ||
244 | /* Just like multipath_map, we just check the | ||
245 | * first available device | ||
246 | */ | ||
247 | break; | ||
248 | } | ||
249 | } | ||
250 | rcu_read_unlock(); | ||
251 | return ret; | ||
252 | } | ||
231 | 253 | ||
232 | /* | 254 | /* |
233 | * Careful, this can execute in IRQ contexts as well! | 255 | * Careful, this can execute in IRQ contexts as well! |
@@ -253,7 +275,7 @@ static void multipath_error (mddev_t *mddev, mdk_rdev_t *rdev) | |||
253 | char b[BDEVNAME_SIZE]; | 275 | char b[BDEVNAME_SIZE]; |
254 | clear_bit(In_sync, &rdev->flags); | 276 | clear_bit(In_sync, &rdev->flags); |
255 | set_bit(Faulty, &rdev->flags); | 277 | set_bit(Faulty, &rdev->flags); |
256 | mddev->sb_dirty = 1; | 278 | set_bit(MD_CHANGE_DEVS, &mddev->flags); |
257 | conf->working_disks--; | 279 | conf->working_disks--; |
258 | printk(KERN_ALERT "multipath: IO failure on %s," | 280 | printk(KERN_ALERT "multipath: IO failure on %s," |
259 | " disabling IO path. \n Operation continuing" | 281 | " disabling IO path. \n Operation continuing" |
@@ -470,7 +492,6 @@ static int multipath_run (mddev_t *mddev) | |||
470 | } | 492 | } |
471 | 493 | ||
472 | conf->raid_disks = mddev->raid_disks; | 494 | conf->raid_disks = mddev->raid_disks; |
473 | mddev->sb_dirty = 1; | ||
474 | conf->mddev = mddev; | 495 | conf->mddev = mddev; |
475 | spin_lock_init(&conf->device_lock); | 496 | spin_lock_init(&conf->device_lock); |
476 | INIT_LIST_HEAD(&conf->retry_list); | 497 | INIT_LIST_HEAD(&conf->retry_list); |
@@ -510,6 +531,8 @@ static int multipath_run (mddev_t *mddev) | |||
510 | 531 | ||
511 | mddev->queue->unplug_fn = multipath_unplug; | 532 | mddev->queue->unplug_fn = multipath_unplug; |
512 | mddev->queue->issue_flush_fn = multipath_issue_flush; | 533 | mddev->queue->issue_flush_fn = multipath_issue_flush; |
534 | mddev->queue->backing_dev_info.congested_fn = multipath_congested; | ||
535 | mddev->queue->backing_dev_info.congested_data = mddev; | ||
513 | 536 | ||
514 | return 0; | 537 | return 0; |
515 | 538 | ||
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index cb8c6317e4e5..dfe32149ad3a 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c | |||
@@ -60,6 +60,21 @@ static int raid0_issue_flush(request_queue_t *q, struct gendisk *disk, | |||
60 | return ret; | 60 | return ret; |
61 | } | 61 | } |
62 | 62 | ||
63 | static int raid0_congested(void *data, int bits) | ||
64 | { | ||
65 | mddev_t *mddev = data; | ||
66 | raid0_conf_t *conf = mddev_to_conf(mddev); | ||
67 | mdk_rdev_t **devlist = conf->strip_zone[0].dev; | ||
68 | int i, ret = 0; | ||
69 | |||
70 | for (i = 0; i < mddev->raid_disks && !ret ; i++) { | ||
71 | request_queue_t *q = bdev_get_queue(devlist[i]->bdev); | ||
72 | |||
73 | ret |= bdi_congested(&q->backing_dev_info, bits); | ||
74 | } | ||
75 | return ret; | ||
76 | } | ||
77 | |||
63 | 78 | ||
64 | static int create_strip_zones (mddev_t *mddev) | 79 | static int create_strip_zones (mddev_t *mddev) |
65 | { | 80 | { |
@@ -236,6 +251,8 @@ static int create_strip_zones (mddev_t *mddev) | |||
236 | mddev->queue->unplug_fn = raid0_unplug; | 251 | mddev->queue->unplug_fn = raid0_unplug; |
237 | 252 | ||
238 | mddev->queue->issue_flush_fn = raid0_issue_flush; | 253 | mddev->queue->issue_flush_fn = raid0_issue_flush; |
254 | mddev->queue->backing_dev_info.congested_fn = raid0_congested; | ||
255 | mddev->queue->backing_dev_info.congested_data = mddev; | ||
239 | 256 | ||
240 | printk("raid0: done.\n"); | 257 | printk("raid0: done.\n"); |
241 | return 0; | 258 | return 0; |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 3b4d69c05623..dc9d2def0270 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -271,7 +271,7 @@ static int raid1_end_read_request(struct bio *bio, unsigned int bytes_done, int | |||
271 | */ | 271 | */ |
272 | update_head_pos(mirror, r1_bio); | 272 | update_head_pos(mirror, r1_bio); |
273 | 273 | ||
274 | if (uptodate || conf->working_disks <= 1) { | 274 | if (uptodate || (conf->raid_disks - conf->mddev->degraded) <= 1) { |
275 | /* | 275 | /* |
276 | * Set R1BIO_Uptodate in our master bio, so that | 276 | * Set R1BIO_Uptodate in our master bio, so that |
277 | * we will return a good error code for to the higher | 277 | * we will return a good error code for to the higher |
@@ -601,6 +601,32 @@ static int raid1_issue_flush(request_queue_t *q, struct gendisk *disk, | |||
601 | return ret; | 601 | return ret; |
602 | } | 602 | } |
603 | 603 | ||
604 | static int raid1_congested(void *data, int bits) | ||
605 | { | ||
606 | mddev_t *mddev = data; | ||
607 | conf_t *conf = mddev_to_conf(mddev); | ||
608 | int i, ret = 0; | ||
609 | |||
610 | rcu_read_lock(); | ||
611 | for (i = 0; i < mddev->raid_disks; i++) { | ||
612 | mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev); | ||
613 | if (rdev && !test_bit(Faulty, &rdev->flags)) { | ||
614 | request_queue_t *q = bdev_get_queue(rdev->bdev); | ||
615 | |||
616 | /* Note the '|| 1' - when read_balance prefers | ||
617 | * non-congested targets, it can be removed | ||
618 | */ | ||
619 | if ((bits & (1<<BDI_write_congested)) || 1) | ||
620 | ret |= bdi_congested(&q->backing_dev_info, bits); | ||
621 | else | ||
622 | ret &= bdi_congested(&q->backing_dev_info, bits); | ||
623 | } | ||
624 | } | ||
625 | rcu_read_unlock(); | ||
626 | return ret; | ||
627 | } | ||
628 | |||
629 | |||
604 | /* Barriers.... | 630 | /* Barriers.... |
605 | * Sometimes we need to suspend IO while we do something else, | 631 | * Sometimes we need to suspend IO while we do something else, |
606 | * either some resync/recovery, or reconfigure the array. | 632 | * either some resync/recovery, or reconfigure the array. |
@@ -929,7 +955,7 @@ static void status(struct seq_file *seq, mddev_t *mddev) | |||
929 | int i; | 955 | int i; |
930 | 956 | ||
931 | seq_printf(seq, " [%d/%d] [", conf->raid_disks, | 957 | seq_printf(seq, " [%d/%d] [", conf->raid_disks, |
932 | conf->working_disks); | 958 | conf->raid_disks - mddev->degraded); |
933 | rcu_read_lock(); | 959 | rcu_read_lock(); |
934 | for (i = 0; i < conf->raid_disks; i++) { | 960 | for (i = 0; i < conf->raid_disks; i++) { |
935 | mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev); | 961 | mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev); |
@@ -953,26 +979,27 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) | |||
953 | * else mark the drive as failed | 979 | * else mark the drive as failed |
954 | */ | 980 | */ |
955 | if (test_bit(In_sync, &rdev->flags) | 981 | if (test_bit(In_sync, &rdev->flags) |
956 | && conf->working_disks == 1) | 982 | && (conf->raid_disks - mddev->degraded) == 1) |
957 | /* | 983 | /* |
958 | * Don't fail the drive, act as though we were just a | 984 | * Don't fail the drive, act as though we were just a |
959 | * normal single drive | 985 | * normal single drive |
960 | */ | 986 | */ |
961 | return; | 987 | return; |
962 | if (test_bit(In_sync, &rdev->flags)) { | 988 | if (test_and_clear_bit(In_sync, &rdev->flags)) { |
989 | unsigned long flags; | ||
990 | spin_lock_irqsave(&conf->device_lock, flags); | ||
963 | mddev->degraded++; | 991 | mddev->degraded++; |
964 | conf->working_disks--; | 992 | spin_unlock_irqrestore(&conf->device_lock, flags); |
965 | /* | 993 | /* |
966 | * if recovery is running, make sure it aborts. | 994 | * if recovery is running, make sure it aborts. |
967 | */ | 995 | */ |
968 | set_bit(MD_RECOVERY_ERR, &mddev->recovery); | 996 | set_bit(MD_RECOVERY_ERR, &mddev->recovery); |
969 | } | 997 | } |
970 | clear_bit(In_sync, &rdev->flags); | ||
971 | set_bit(Faulty, &rdev->flags); | 998 | set_bit(Faulty, &rdev->flags); |
972 | mddev->sb_dirty = 1; | 999 | set_bit(MD_CHANGE_DEVS, &mddev->flags); |
973 | printk(KERN_ALERT "raid1: Disk failure on %s, disabling device. \n" | 1000 | printk(KERN_ALERT "raid1: Disk failure on %s, disabling device. \n" |
974 | " Operation continuing on %d devices\n", | 1001 | " Operation continuing on %d devices\n", |
975 | bdevname(rdev->bdev,b), conf->working_disks); | 1002 | bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded); |
976 | } | 1003 | } |
977 | 1004 | ||
978 | static void print_conf(conf_t *conf) | 1005 | static void print_conf(conf_t *conf) |
@@ -984,7 +1011,7 @@ static void print_conf(conf_t *conf) | |||
984 | printk("(!conf)\n"); | 1011 | printk("(!conf)\n"); |
985 | return; | 1012 | return; |
986 | } | 1013 | } |
987 | printk(" --- wd:%d rd:%d\n", conf->working_disks, | 1014 | printk(" --- wd:%d rd:%d\n", conf->raid_disks - conf->mddev->degraded, |
988 | conf->raid_disks); | 1015 | conf->raid_disks); |
989 | 1016 | ||
990 | rcu_read_lock(); | 1017 | rcu_read_lock(); |
@@ -1023,10 +1050,11 @@ static int raid1_spare_active(mddev_t *mddev) | |||
1023 | mdk_rdev_t *rdev = conf->mirrors[i].rdev; | 1050 | mdk_rdev_t *rdev = conf->mirrors[i].rdev; |
1024 | if (rdev | 1051 | if (rdev |
1025 | && !test_bit(Faulty, &rdev->flags) | 1052 | && !test_bit(Faulty, &rdev->flags) |
1026 | && !test_bit(In_sync, &rdev->flags)) { | 1053 | && !test_and_set_bit(In_sync, &rdev->flags)) { |
1027 | conf->working_disks++; | 1054 | unsigned long flags; |
1055 | spin_lock_irqsave(&conf->device_lock, flags); | ||
1028 | mddev->degraded--; | 1056 | mddev->degraded--; |
1029 | set_bit(In_sync, &rdev->flags); | 1057 | spin_unlock_irqrestore(&conf->device_lock, flags); |
1030 | } | 1058 | } |
1031 | } | 1059 | } |
1032 | 1060 | ||
@@ -1368,6 +1396,95 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio) | |||
1368 | * 3. Performs writes following reads for array syncronising. | 1396 | * 3. Performs writes following reads for array syncronising. |
1369 | */ | 1397 | */ |
1370 | 1398 | ||
1399 | static void fix_read_error(conf_t *conf, int read_disk, | ||
1400 | sector_t sect, int sectors) | ||
1401 | { | ||
1402 | mddev_t *mddev = conf->mddev; | ||
1403 | while(sectors) { | ||
1404 | int s = sectors; | ||
1405 | int d = read_disk; | ||
1406 | int success = 0; | ||
1407 | int start; | ||
1408 | mdk_rdev_t *rdev; | ||
1409 | |||
1410 | if (s > (PAGE_SIZE>>9)) | ||
1411 | s = PAGE_SIZE >> 9; | ||
1412 | |||
1413 | do { | ||
1414 | /* Note: no rcu protection needed here | ||
1415 | * as this is synchronous in the raid1d thread | ||
1416 | * which is the thread that might remove | ||
1417 | * a device. If raid1d ever becomes multi-threaded.... | ||
1418 | */ | ||
1419 | rdev = conf->mirrors[d].rdev; | ||
1420 | if (rdev && | ||
1421 | test_bit(In_sync, &rdev->flags) && | ||
1422 | sync_page_io(rdev->bdev, | ||
1423 | sect + rdev->data_offset, | ||
1424 | s<<9, | ||
1425 | conf->tmppage, READ)) | ||
1426 | success = 1; | ||
1427 | else { | ||
1428 | d++; | ||
1429 | if (d == conf->raid_disks) | ||
1430 | d = 0; | ||
1431 | } | ||
1432 | } while (!success && d != read_disk); | ||
1433 | |||
1434 | if (!success) { | ||
1435 | /* Cannot read from anywhere -- bye bye array */ | ||
1436 | md_error(mddev, conf->mirrors[read_disk].rdev); | ||
1437 | break; | ||
1438 | } | ||
1439 | /* write it back and re-read */ | ||
1440 | start = d; | ||
1441 | while (d != read_disk) { | ||
1442 | if (d==0) | ||
1443 | d = conf->raid_disks; | ||
1444 | d--; | ||
1445 | rdev = conf->mirrors[d].rdev; | ||
1446 | if (rdev && | ||
1447 | test_bit(In_sync, &rdev->flags)) { | ||
1448 | if (sync_page_io(rdev->bdev, | ||
1449 | sect + rdev->data_offset, | ||
1450 | s<<9, conf->tmppage, WRITE) | ||
1451 | == 0) | ||
1452 | /* Well, this device is dead */ | ||
1453 | md_error(mddev, rdev); | ||
1454 | } | ||
1455 | } | ||
1456 | d = start; | ||
1457 | while (d != read_disk) { | ||
1458 | char b[BDEVNAME_SIZE]; | ||
1459 | if (d==0) | ||
1460 | d = conf->raid_disks; | ||
1461 | d--; | ||
1462 | rdev = conf->mirrors[d].rdev; | ||
1463 | if (rdev && | ||
1464 | test_bit(In_sync, &rdev->flags)) { | ||
1465 | if (sync_page_io(rdev->bdev, | ||
1466 | sect + rdev->data_offset, | ||
1467 | s<<9, conf->tmppage, READ) | ||
1468 | == 0) | ||
1469 | /* Well, this device is dead */ | ||
1470 | md_error(mddev, rdev); | ||
1471 | else { | ||
1472 | atomic_add(s, &rdev->corrected_errors); | ||
1473 | printk(KERN_INFO | ||
1474 | "raid1:%s: read error corrected " | ||
1475 | "(%d sectors at %llu on %s)\n", | ||
1476 | mdname(mddev), s, | ||
1477 | (unsigned long long)sect + | ||
1478 | rdev->data_offset, | ||
1479 | bdevname(rdev->bdev, b)); | ||
1480 | } | ||
1481 | } | ||
1482 | } | ||
1483 | sectors -= s; | ||
1484 | sect += s; | ||
1485 | } | ||
1486 | } | ||
1487 | |||
1371 | static void raid1d(mddev_t *mddev) | 1488 | static void raid1d(mddev_t *mddev) |
1372 | { | 1489 | { |
1373 | r1bio_t *r1_bio; | 1490 | r1bio_t *r1_bio; |
@@ -1460,86 +1577,14 @@ static void raid1d(mddev_t *mddev) | |||
1460 | * This is all done synchronously while the array is | 1577 | * This is all done synchronously while the array is |
1461 | * frozen | 1578 | * frozen |
1462 | */ | 1579 | */ |
1463 | sector_t sect = r1_bio->sector; | 1580 | if (mddev->ro == 0) { |
1464 | int sectors = r1_bio->sectors; | 1581 | freeze_array(conf); |
1465 | freeze_array(conf); | 1582 | fix_read_error(conf, r1_bio->read_disk, |
1466 | if (mddev->ro == 0) while(sectors) { | 1583 | r1_bio->sector, |
1467 | int s = sectors; | 1584 | r1_bio->sectors); |
1468 | int d = r1_bio->read_disk; | 1585 | unfreeze_array(conf); |
1469 | int success = 0; | ||
1470 | |||
1471 | if (s > (PAGE_SIZE>>9)) | ||
1472 | s = PAGE_SIZE >> 9; | ||
1473 | |||
1474 | do { | ||
1475 | /* Note: no rcu protection needed here | ||
1476 | * as this is synchronous in the raid1d thread | ||
1477 | * which is the thread that might remove | ||
1478 | * a device. If raid1d ever becomes multi-threaded.... | ||
1479 | */ | ||
1480 | rdev = conf->mirrors[d].rdev; | ||
1481 | if (rdev && | ||
1482 | test_bit(In_sync, &rdev->flags) && | ||
1483 | sync_page_io(rdev->bdev, | ||
1484 | sect + rdev->data_offset, | ||
1485 | s<<9, | ||
1486 | conf->tmppage, READ)) | ||
1487 | success = 1; | ||
1488 | else { | ||
1489 | d++; | ||
1490 | if (d == conf->raid_disks) | ||
1491 | d = 0; | ||
1492 | } | ||
1493 | } while (!success && d != r1_bio->read_disk); | ||
1494 | |||
1495 | if (success) { | ||
1496 | /* write it back and re-read */ | ||
1497 | int start = d; | ||
1498 | while (d != r1_bio->read_disk) { | ||
1499 | if (d==0) | ||
1500 | d = conf->raid_disks; | ||
1501 | d--; | ||
1502 | rdev = conf->mirrors[d].rdev; | ||
1503 | if (rdev && | ||
1504 | test_bit(In_sync, &rdev->flags)) { | ||
1505 | if (sync_page_io(rdev->bdev, | ||
1506 | sect + rdev->data_offset, | ||
1507 | s<<9, conf->tmppage, WRITE) == 0) | ||
1508 | /* Well, this device is dead */ | ||
1509 | md_error(mddev, rdev); | ||
1510 | } | ||
1511 | } | ||
1512 | d = start; | ||
1513 | while (d != r1_bio->read_disk) { | ||
1514 | if (d==0) | ||
1515 | d = conf->raid_disks; | ||
1516 | d--; | ||
1517 | rdev = conf->mirrors[d].rdev; | ||
1518 | if (rdev && | ||
1519 | test_bit(In_sync, &rdev->flags)) { | ||
1520 | if (sync_page_io(rdev->bdev, | ||
1521 | sect + rdev->data_offset, | ||
1522 | s<<9, conf->tmppage, READ) == 0) | ||
1523 | /* Well, this device is dead */ | ||
1524 | md_error(mddev, rdev); | ||
1525 | else { | ||
1526 | atomic_add(s, &rdev->corrected_errors); | ||
1527 | printk(KERN_INFO "raid1:%s: read error corrected (%d sectors at %llu on %s)\n", | ||
1528 | mdname(mddev), s, (unsigned long long)(sect + rdev->data_offset), bdevname(rdev->bdev, b)); | ||
1529 | } | ||
1530 | } | ||
1531 | } | ||
1532 | } else { | ||
1533 | /* Cannot read from anywhere -- bye bye array */ | ||
1534 | md_error(mddev, conf->mirrors[r1_bio->read_disk].rdev); | ||
1535 | break; | ||
1536 | } | ||
1537 | sectors -= s; | ||
1538 | sect += s; | ||
1539 | } | 1586 | } |
1540 | 1587 | ||
1541 | unfreeze_array(conf); | ||
1542 | |||
1543 | bio = r1_bio->bios[r1_bio->read_disk]; | 1588 | bio = r1_bio->bios[r1_bio->read_disk]; |
1544 | if ((disk=read_balance(conf, r1_bio)) == -1) { | 1589 | if ((disk=read_balance(conf, r1_bio)) == -1) { |
1545 | printk(KERN_ALERT "raid1: %s: unrecoverable I/O" | 1590 | printk(KERN_ALERT "raid1: %s: unrecoverable I/O" |
@@ -1884,15 +1929,11 @@ static int run(mddev_t *mddev) | |||
1884 | blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); | 1929 | blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); |
1885 | 1930 | ||
1886 | disk->head_position = 0; | 1931 | disk->head_position = 0; |
1887 | if (!test_bit(Faulty, &rdev->flags) && test_bit(In_sync, &rdev->flags)) | ||
1888 | conf->working_disks++; | ||
1889 | } | 1932 | } |
1890 | conf->raid_disks = mddev->raid_disks; | 1933 | conf->raid_disks = mddev->raid_disks; |
1891 | conf->mddev = mddev; | 1934 | conf->mddev = mddev; |
1892 | spin_lock_init(&conf->device_lock); | 1935 | spin_lock_init(&conf->device_lock); |
1893 | INIT_LIST_HEAD(&conf->retry_list); | 1936 | INIT_LIST_HEAD(&conf->retry_list); |
1894 | if (conf->working_disks == 1) | ||
1895 | mddev->recovery_cp = MaxSector; | ||
1896 | 1937 | ||
1897 | spin_lock_init(&conf->resync_lock); | 1938 | spin_lock_init(&conf->resync_lock); |
1898 | init_waitqueue_head(&conf->wait_barrier); | 1939 | init_waitqueue_head(&conf->wait_barrier); |
@@ -1900,11 +1941,6 @@ static int run(mddev_t *mddev) | |||
1900 | bio_list_init(&conf->pending_bio_list); | 1941 | bio_list_init(&conf->pending_bio_list); |
1901 | bio_list_init(&conf->flushing_bio_list); | 1942 | bio_list_init(&conf->flushing_bio_list); |
1902 | 1943 | ||
1903 | if (!conf->working_disks) { | ||
1904 | printk(KERN_ERR "raid1: no operational mirrors for %s\n", | ||
1905 | mdname(mddev)); | ||
1906 | goto out_free_conf; | ||
1907 | } | ||
1908 | 1944 | ||
1909 | mddev->degraded = 0; | 1945 | mddev->degraded = 0; |
1910 | for (i = 0; i < conf->raid_disks; i++) { | 1946 | for (i = 0; i < conf->raid_disks; i++) { |
@@ -1917,6 +1953,13 @@ static int run(mddev_t *mddev) | |||
1917 | mddev->degraded++; | 1953 | mddev->degraded++; |
1918 | } | 1954 | } |
1919 | } | 1955 | } |
1956 | if (mddev->degraded == conf->raid_disks) { | ||
1957 | printk(KERN_ERR "raid1: no operational mirrors for %s\n", | ||
1958 | mdname(mddev)); | ||
1959 | goto out_free_conf; | ||
1960 | } | ||
1961 | if (conf->raid_disks - mddev->degraded == 1) | ||
1962 | mddev->recovery_cp = MaxSector; | ||
1920 | 1963 | ||
1921 | /* | 1964 | /* |
1922 | * find the first working one and use it as a starting point | 1965 | * find the first working one and use it as a starting point |
@@ -1948,6 +1991,8 @@ static int run(mddev_t *mddev) | |||
1948 | 1991 | ||
1949 | mddev->queue->unplug_fn = raid1_unplug; | 1992 | mddev->queue->unplug_fn = raid1_unplug; |
1950 | mddev->queue->issue_flush_fn = raid1_issue_flush; | 1993 | mddev->queue->issue_flush_fn = raid1_issue_flush; |
1994 | mddev->queue->backing_dev_info.congested_fn = raid1_congested; | ||
1995 | mddev->queue->backing_dev_info.congested_data = mddev; | ||
1951 | 1996 | ||
1952 | return 0; | 1997 | return 0; |
1953 | 1998 | ||
@@ -2035,7 +2080,7 @@ static int raid1_reshape(mddev_t *mddev) | |||
2035 | mirror_info_t *newmirrors; | 2080 | mirror_info_t *newmirrors; |
2036 | conf_t *conf = mddev_to_conf(mddev); | 2081 | conf_t *conf = mddev_to_conf(mddev); |
2037 | int cnt, raid_disks; | 2082 | int cnt, raid_disks; |
2038 | 2083 | unsigned long flags; | |
2039 | int d, d2; | 2084 | int d, d2; |
2040 | 2085 | ||
2041 | /* Cannot change chunk_size, layout, or level */ | 2086 | /* Cannot change chunk_size, layout, or level */ |
@@ -2094,7 +2139,9 @@ static int raid1_reshape(mddev_t *mddev) | |||
2094 | kfree(conf->poolinfo); | 2139 | kfree(conf->poolinfo); |
2095 | conf->poolinfo = newpoolinfo; | 2140 | conf->poolinfo = newpoolinfo; |
2096 | 2141 | ||
2142 | spin_lock_irqsave(&conf->device_lock, flags); | ||
2097 | mddev->degraded += (raid_disks - conf->raid_disks); | 2143 | mddev->degraded += (raid_disks - conf->raid_disks); |
2144 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
2098 | conf->raid_disks = mddev->raid_disks = raid_disks; | 2145 | conf->raid_disks = mddev->raid_disks = raid_disks; |
2099 | mddev->delta_disks = 0; | 2146 | mddev->delta_disks = 0; |
2100 | 2147 | ||
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 016ddb831c9b..1250f0eab4af 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -648,6 +648,26 @@ static int raid10_issue_flush(request_queue_t *q, struct gendisk *disk, | |||
648 | return ret; | 648 | return ret; |
649 | } | 649 | } |
650 | 650 | ||
651 | static int raid10_congested(void *data, int bits) | ||
652 | { | ||
653 | mddev_t *mddev = data; | ||
654 | conf_t *conf = mddev_to_conf(mddev); | ||
655 | int i, ret = 0; | ||
656 | |||
657 | rcu_read_lock(); | ||
658 | for (i = 0; i < mddev->raid_disks && ret == 0; i++) { | ||
659 | mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev); | ||
660 | if (rdev && !test_bit(Faulty, &rdev->flags)) { | ||
661 | request_queue_t *q = bdev_get_queue(rdev->bdev); | ||
662 | |||
663 | ret |= bdi_congested(&q->backing_dev_info, bits); | ||
664 | } | ||
665 | } | ||
666 | rcu_read_unlock(); | ||
667 | return ret; | ||
668 | } | ||
669 | |||
670 | |||
651 | /* Barriers.... | 671 | /* Barriers.... |
652 | * Sometimes we need to suspend IO while we do something else, | 672 | * Sometimes we need to suspend IO while we do something else, |
653 | * either some resync/recovery, or reconfigure the array. | 673 | * either some resync/recovery, or reconfigure the array. |
@@ -921,7 +941,7 @@ static void status(struct seq_file *seq, mddev_t *mddev) | |||
921 | seq_printf(seq, " %d far-copies", conf->far_copies); | 941 | seq_printf(seq, " %d far-copies", conf->far_copies); |
922 | } | 942 | } |
923 | seq_printf(seq, " [%d/%d] [", conf->raid_disks, | 943 | seq_printf(seq, " [%d/%d] [", conf->raid_disks, |
924 | conf->working_disks); | 944 | conf->raid_disks - mddev->degraded); |
925 | for (i = 0; i < conf->raid_disks; i++) | 945 | for (i = 0; i < conf->raid_disks; i++) |
926 | seq_printf(seq, "%s", | 946 | seq_printf(seq, "%s", |
927 | conf->mirrors[i].rdev && | 947 | conf->mirrors[i].rdev && |
@@ -941,7 +961,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) | |||
941 | * else mark the drive as failed | 961 | * else mark the drive as failed |
942 | */ | 962 | */ |
943 | if (test_bit(In_sync, &rdev->flags) | 963 | if (test_bit(In_sync, &rdev->flags) |
944 | && conf->working_disks == 1) | 964 | && conf->raid_disks-mddev->degraded == 1) |
945 | /* | 965 | /* |
946 | * Don't fail the drive, just return an IO error. | 966 | * Don't fail the drive, just return an IO error. |
947 | * The test should really be more sophisticated than | 967 | * The test should really be more sophisticated than |
@@ -950,20 +970,21 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) | |||
950 | * really dead" tests... | 970 | * really dead" tests... |
951 | */ | 971 | */ |
952 | return; | 972 | return; |
953 | if (test_bit(In_sync, &rdev->flags)) { | 973 | if (test_and_clear_bit(In_sync, &rdev->flags)) { |
974 | unsigned long flags; | ||
975 | spin_lock_irqsave(&conf->device_lock, flags); | ||
954 | mddev->degraded++; | 976 | mddev->degraded++; |
955 | conf->working_disks--; | 977 | spin_unlock_irqrestore(&conf->device_lock, flags); |
956 | /* | 978 | /* |
957 | * if recovery is running, make sure it aborts. | 979 | * if recovery is running, make sure it aborts. |
958 | */ | 980 | */ |
959 | set_bit(MD_RECOVERY_ERR, &mddev->recovery); | 981 | set_bit(MD_RECOVERY_ERR, &mddev->recovery); |
960 | } | 982 | } |
961 | clear_bit(In_sync, &rdev->flags); | ||
962 | set_bit(Faulty, &rdev->flags); | 983 | set_bit(Faulty, &rdev->flags); |
963 | mddev->sb_dirty = 1; | 984 | set_bit(MD_CHANGE_DEVS, &mddev->flags); |
964 | printk(KERN_ALERT "raid10: Disk failure on %s, disabling device. \n" | 985 | printk(KERN_ALERT "raid10: Disk failure on %s, disabling device. \n" |
965 | " Operation continuing on %d devices\n", | 986 | " Operation continuing on %d devices\n", |
966 | bdevname(rdev->bdev,b), conf->working_disks); | 987 | bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded); |
967 | } | 988 | } |
968 | 989 | ||
969 | static void print_conf(conf_t *conf) | 990 | static void print_conf(conf_t *conf) |
@@ -976,7 +997,7 @@ static void print_conf(conf_t *conf) | |||
976 | printk("(!conf)\n"); | 997 | printk("(!conf)\n"); |
977 | return; | 998 | return; |
978 | } | 999 | } |
979 | printk(" --- wd:%d rd:%d\n", conf->working_disks, | 1000 | printk(" --- wd:%d rd:%d\n", conf->raid_disks - conf->mddev->degraded, |
980 | conf->raid_disks); | 1001 | conf->raid_disks); |
981 | 1002 | ||
982 | for (i = 0; i < conf->raid_disks; i++) { | 1003 | for (i = 0; i < conf->raid_disks; i++) { |
@@ -1034,10 +1055,11 @@ static int raid10_spare_active(mddev_t *mddev) | |||
1034 | tmp = conf->mirrors + i; | 1055 | tmp = conf->mirrors + i; |
1035 | if (tmp->rdev | 1056 | if (tmp->rdev |
1036 | && !test_bit(Faulty, &tmp->rdev->flags) | 1057 | && !test_bit(Faulty, &tmp->rdev->flags) |
1037 | && !test_bit(In_sync, &tmp->rdev->flags)) { | 1058 | && !test_and_set_bit(In_sync, &tmp->rdev->flags)) { |
1038 | conf->working_disks++; | 1059 | unsigned long flags; |
1060 | spin_lock_irqsave(&conf->device_lock, flags); | ||
1039 | mddev->degraded--; | 1061 | mddev->degraded--; |
1040 | set_bit(In_sync, &tmp->rdev->flags); | 1062 | spin_unlock_irqrestore(&conf->device_lock, flags); |
1041 | } | 1063 | } |
1042 | } | 1064 | } |
1043 | 1065 | ||
@@ -1350,9 +1372,119 @@ static void recovery_request_write(mddev_t *mddev, r10bio_t *r10_bio) | |||
1350 | * | 1372 | * |
1351 | * 1. Retries failed read operations on working mirrors. | 1373 | * 1. Retries failed read operations on working mirrors. |
1352 | * 2. Updates the raid superblock when problems encounter. | 1374 | * 2. Updates the raid superblock when problems encounter. |
1353 | * 3. Performs writes following reads for array syncronising. | 1375 | * 3. Performs writes following reads for array synchronising. |
1354 | */ | 1376 | */ |
1355 | 1377 | ||
1378 | static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio) | ||
1379 | { | ||
1380 | int sect = 0; /* Offset from r10_bio->sector */ | ||
1381 | int sectors = r10_bio->sectors; | ||
1382 | mdk_rdev_t*rdev; | ||
1383 | while(sectors) { | ||
1384 | int s = sectors; | ||
1385 | int sl = r10_bio->read_slot; | ||
1386 | int success = 0; | ||
1387 | int start; | ||
1388 | |||
1389 | if (s > (PAGE_SIZE>>9)) | ||
1390 | s = PAGE_SIZE >> 9; | ||
1391 | |||
1392 | rcu_read_lock(); | ||
1393 | do { | ||
1394 | int d = r10_bio->devs[sl].devnum; | ||
1395 | rdev = rcu_dereference(conf->mirrors[d].rdev); | ||
1396 | if (rdev && | ||
1397 | test_bit(In_sync, &rdev->flags)) { | ||
1398 | atomic_inc(&rdev->nr_pending); | ||
1399 | rcu_read_unlock(); | ||
1400 | success = sync_page_io(rdev->bdev, | ||
1401 | r10_bio->devs[sl].addr + | ||
1402 | sect + rdev->data_offset, | ||
1403 | s<<9, | ||
1404 | conf->tmppage, READ); | ||
1405 | rdev_dec_pending(rdev, mddev); | ||
1406 | rcu_read_lock(); | ||
1407 | if (success) | ||
1408 | break; | ||
1409 | } | ||
1410 | sl++; | ||
1411 | if (sl == conf->copies) | ||
1412 | sl = 0; | ||
1413 | } while (!success && sl != r10_bio->read_slot); | ||
1414 | rcu_read_unlock(); | ||
1415 | |||
1416 | if (!success) { | ||
1417 | /* Cannot read from anywhere -- bye bye array */ | ||
1418 | int dn = r10_bio->devs[r10_bio->read_slot].devnum; | ||
1419 | md_error(mddev, conf->mirrors[dn].rdev); | ||
1420 | break; | ||
1421 | } | ||
1422 | |||
1423 | start = sl; | ||
1424 | /* write it back and re-read */ | ||
1425 | rcu_read_lock(); | ||
1426 | while (sl != r10_bio->read_slot) { | ||
1427 | int d; | ||
1428 | if (sl==0) | ||
1429 | sl = conf->copies; | ||
1430 | sl--; | ||
1431 | d = r10_bio->devs[sl].devnum; | ||
1432 | rdev = rcu_dereference(conf->mirrors[d].rdev); | ||
1433 | if (rdev && | ||
1434 | test_bit(In_sync, &rdev->flags)) { | ||
1435 | atomic_inc(&rdev->nr_pending); | ||
1436 | rcu_read_unlock(); | ||
1437 | atomic_add(s, &rdev->corrected_errors); | ||
1438 | if (sync_page_io(rdev->bdev, | ||
1439 | r10_bio->devs[sl].addr + | ||
1440 | sect + rdev->data_offset, | ||
1441 | s<<9, conf->tmppage, WRITE) | ||
1442 | == 0) | ||
1443 | /* Well, this device is dead */ | ||
1444 | md_error(mddev, rdev); | ||
1445 | rdev_dec_pending(rdev, mddev); | ||
1446 | rcu_read_lock(); | ||
1447 | } | ||
1448 | } | ||
1449 | sl = start; | ||
1450 | while (sl != r10_bio->read_slot) { | ||
1451 | int d; | ||
1452 | if (sl==0) | ||
1453 | sl = conf->copies; | ||
1454 | sl--; | ||
1455 | d = r10_bio->devs[sl].devnum; | ||
1456 | rdev = rcu_dereference(conf->mirrors[d].rdev); | ||
1457 | if (rdev && | ||
1458 | test_bit(In_sync, &rdev->flags)) { | ||
1459 | char b[BDEVNAME_SIZE]; | ||
1460 | atomic_inc(&rdev->nr_pending); | ||
1461 | rcu_read_unlock(); | ||
1462 | if (sync_page_io(rdev->bdev, | ||
1463 | r10_bio->devs[sl].addr + | ||
1464 | sect + rdev->data_offset, | ||
1465 | s<<9, conf->tmppage, READ) == 0) | ||
1466 | /* Well, this device is dead */ | ||
1467 | md_error(mddev, rdev); | ||
1468 | else | ||
1469 | printk(KERN_INFO | ||
1470 | "raid10:%s: read error corrected" | ||
1471 | " (%d sectors at %llu on %s)\n", | ||
1472 | mdname(mddev), s, | ||
1473 | (unsigned long long)sect+ | ||
1474 | rdev->data_offset, | ||
1475 | bdevname(rdev->bdev, b)); | ||
1476 | |||
1477 | rdev_dec_pending(rdev, mddev); | ||
1478 | rcu_read_lock(); | ||
1479 | } | ||
1480 | } | ||
1481 | rcu_read_unlock(); | ||
1482 | |||
1483 | sectors -= s; | ||
1484 | sect += s; | ||
1485 | } | ||
1486 | } | ||
1487 | |||
1356 | static void raid10d(mddev_t *mddev) | 1488 | static void raid10d(mddev_t *mddev) |
1357 | { | 1489 | { |
1358 | r10bio_t *r10_bio; | 1490 | r10bio_t *r10_bio; |
@@ -1413,105 +1545,12 @@ static void raid10d(mddev_t *mddev) | |||
1413 | * This is all done synchronously while the array is | 1545 | * This is all done synchronously while the array is |
1414 | * frozen. | 1546 | * frozen. |
1415 | */ | 1547 | */ |
1416 | int sect = 0; /* Offset from r10_bio->sector */ | 1548 | if (mddev->ro == 0) { |
1417 | int sectors = r10_bio->sectors; | 1549 | freeze_array(conf); |
1418 | freeze_array(conf); | 1550 | fix_read_error(conf, mddev, r10_bio); |
1419 | if (mddev->ro == 0) while(sectors) { | 1551 | unfreeze_array(conf); |
1420 | int s = sectors; | ||
1421 | int sl = r10_bio->read_slot; | ||
1422 | int success = 0; | ||
1423 | |||
1424 | if (s > (PAGE_SIZE>>9)) | ||
1425 | s = PAGE_SIZE >> 9; | ||
1426 | |||
1427 | rcu_read_lock(); | ||
1428 | do { | ||
1429 | int d = r10_bio->devs[sl].devnum; | ||
1430 | rdev = rcu_dereference(conf->mirrors[d].rdev); | ||
1431 | if (rdev && | ||
1432 | test_bit(In_sync, &rdev->flags)) { | ||
1433 | atomic_inc(&rdev->nr_pending); | ||
1434 | rcu_read_unlock(); | ||
1435 | success = sync_page_io(rdev->bdev, | ||
1436 | r10_bio->devs[sl].addr + | ||
1437 | sect + rdev->data_offset, | ||
1438 | s<<9, | ||
1439 | conf->tmppage, READ); | ||
1440 | rdev_dec_pending(rdev, mddev); | ||
1441 | rcu_read_lock(); | ||
1442 | if (success) | ||
1443 | break; | ||
1444 | } | ||
1445 | sl++; | ||
1446 | if (sl == conf->copies) | ||
1447 | sl = 0; | ||
1448 | } while (!success && sl != r10_bio->read_slot); | ||
1449 | rcu_read_unlock(); | ||
1450 | |||
1451 | if (success) { | ||
1452 | int start = sl; | ||
1453 | /* write it back and re-read */ | ||
1454 | rcu_read_lock(); | ||
1455 | while (sl != r10_bio->read_slot) { | ||
1456 | int d; | ||
1457 | if (sl==0) | ||
1458 | sl = conf->copies; | ||
1459 | sl--; | ||
1460 | d = r10_bio->devs[sl].devnum; | ||
1461 | rdev = rcu_dereference(conf->mirrors[d].rdev); | ||
1462 | if (rdev && | ||
1463 | test_bit(In_sync, &rdev->flags)) { | ||
1464 | atomic_inc(&rdev->nr_pending); | ||
1465 | rcu_read_unlock(); | ||
1466 | atomic_add(s, &rdev->corrected_errors); | ||
1467 | if (sync_page_io(rdev->bdev, | ||
1468 | r10_bio->devs[sl].addr + | ||
1469 | sect + rdev->data_offset, | ||
1470 | s<<9, conf->tmppage, WRITE) == 0) | ||
1471 | /* Well, this device is dead */ | ||
1472 | md_error(mddev, rdev); | ||
1473 | rdev_dec_pending(rdev, mddev); | ||
1474 | rcu_read_lock(); | ||
1475 | } | ||
1476 | } | ||
1477 | sl = start; | ||
1478 | while (sl != r10_bio->read_slot) { | ||
1479 | int d; | ||
1480 | if (sl==0) | ||
1481 | sl = conf->copies; | ||
1482 | sl--; | ||
1483 | d = r10_bio->devs[sl].devnum; | ||
1484 | rdev = rcu_dereference(conf->mirrors[d].rdev); | ||
1485 | if (rdev && | ||
1486 | test_bit(In_sync, &rdev->flags)) { | ||
1487 | atomic_inc(&rdev->nr_pending); | ||
1488 | rcu_read_unlock(); | ||
1489 | if (sync_page_io(rdev->bdev, | ||
1490 | r10_bio->devs[sl].addr + | ||
1491 | sect + rdev->data_offset, | ||
1492 | s<<9, conf->tmppage, READ) == 0) | ||
1493 | /* Well, this device is dead */ | ||
1494 | md_error(mddev, rdev); | ||
1495 | else | ||
1496 | printk(KERN_INFO "raid10:%s: read error corrected (%d sectors at %llu on %s)\n", | ||
1497 | mdname(mddev), s, (unsigned long long)(sect+rdev->data_offset), bdevname(rdev->bdev, b)); | ||
1498 | |||
1499 | rdev_dec_pending(rdev, mddev); | ||
1500 | rcu_read_lock(); | ||
1501 | } | ||
1502 | } | ||
1503 | rcu_read_unlock(); | ||
1504 | } else { | ||
1505 | /* Cannot read from anywhere -- bye bye array */ | ||
1506 | md_error(mddev, conf->mirrors[r10_bio->devs[r10_bio->read_slot].devnum].rdev); | ||
1507 | break; | ||
1508 | } | ||
1509 | sectors -= s; | ||
1510 | sect += s; | ||
1511 | } | 1552 | } |
1512 | 1553 | ||
1513 | unfreeze_array(conf); | ||
1514 | |||
1515 | bio = r10_bio->devs[r10_bio->read_slot].bio; | 1554 | bio = r10_bio->devs[r10_bio->read_slot].bio; |
1516 | r10_bio->devs[r10_bio->read_slot].bio = | 1555 | r10_bio->devs[r10_bio->read_slot].bio = |
1517 | mddev->ro ? IO_BLOCKED : NULL; | 1556 | mddev->ro ? IO_BLOCKED : NULL; |
@@ -2018,8 +2057,6 @@ static int run(mddev_t *mddev) | |||
2018 | mddev->queue->max_sectors = (PAGE_SIZE>>9); | 2057 | mddev->queue->max_sectors = (PAGE_SIZE>>9); |
2019 | 2058 | ||
2020 | disk->head_position = 0; | 2059 | disk->head_position = 0; |
2021 | if (!test_bit(Faulty, &rdev->flags) && test_bit(In_sync, &rdev->flags)) | ||
2022 | conf->working_disks++; | ||
2023 | } | 2060 | } |
2024 | conf->raid_disks = mddev->raid_disks; | 2061 | conf->raid_disks = mddev->raid_disks; |
2025 | conf->mddev = mddev; | 2062 | conf->mddev = mddev; |
@@ -2077,6 +2114,8 @@ static int run(mddev_t *mddev) | |||
2077 | 2114 | ||
2078 | mddev->queue->unplug_fn = raid10_unplug; | 2115 | mddev->queue->unplug_fn = raid10_unplug; |
2079 | mddev->queue->issue_flush_fn = raid10_issue_flush; | 2116 | mddev->queue->issue_flush_fn = raid10_issue_flush; |
2117 | mddev->queue->backing_dev_info.congested_fn = raid10_congested; | ||
2118 | mddev->queue->backing_dev_info.congested_data = mddev; | ||
2080 | 2119 | ||
2081 | /* Calculate max read-ahead size. | 2120 | /* Calculate max read-ahead size. |
2082 | * We need to readahead at least twice a whole stripe.... | 2121 | * We need to readahead at least twice a whole stripe.... |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 450066007160..37e4ff661b6c 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -636,7 +636,6 @@ static int raid5_end_write_request (struct bio *bi, unsigned int bytes_done, | |||
636 | struct stripe_head *sh = bi->bi_private; | 636 | struct stripe_head *sh = bi->bi_private; |
637 | raid5_conf_t *conf = sh->raid_conf; | 637 | raid5_conf_t *conf = sh->raid_conf; |
638 | int disks = sh->disks, i; | 638 | int disks = sh->disks, i; |
639 | unsigned long flags; | ||
640 | int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags); | 639 | int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags); |
641 | 640 | ||
642 | if (bi->bi_size) | 641 | if (bi->bi_size) |
@@ -654,7 +653,6 @@ static int raid5_end_write_request (struct bio *bi, unsigned int bytes_done, | |||
654 | return 0; | 653 | return 0; |
655 | } | 654 | } |
656 | 655 | ||
657 | spin_lock_irqsave(&conf->device_lock, flags); | ||
658 | if (!uptodate) | 656 | if (!uptodate) |
659 | md_error(conf->mddev, conf->disks[i].rdev); | 657 | md_error(conf->mddev, conf->disks[i].rdev); |
660 | 658 | ||
@@ -662,8 +660,7 @@ static int raid5_end_write_request (struct bio *bi, unsigned int bytes_done, | |||
662 | 660 | ||
663 | clear_bit(R5_LOCKED, &sh->dev[i].flags); | 661 | clear_bit(R5_LOCKED, &sh->dev[i].flags); |
664 | set_bit(STRIPE_HANDLE, &sh->state); | 662 | set_bit(STRIPE_HANDLE, &sh->state); |
665 | __release_stripe(conf, sh); | 663 | release_stripe(sh); |
666 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
667 | return 0; | 664 | return 0; |
668 | } | 665 | } |
669 | 666 | ||
@@ -696,12 +693,12 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) | |||
696 | PRINTK("raid5: error called\n"); | 693 | PRINTK("raid5: error called\n"); |
697 | 694 | ||
698 | if (!test_bit(Faulty, &rdev->flags)) { | 695 | if (!test_bit(Faulty, &rdev->flags)) { |
699 | mddev->sb_dirty = 1; | 696 | set_bit(MD_CHANGE_DEVS, &mddev->flags); |
700 | if (test_bit(In_sync, &rdev->flags)) { | 697 | if (test_and_clear_bit(In_sync, &rdev->flags)) { |
701 | conf->working_disks--; | 698 | unsigned long flags; |
699 | spin_lock_irqsave(&conf->device_lock, flags); | ||
702 | mddev->degraded++; | 700 | mddev->degraded++; |
703 | conf->failed_disks++; | 701 | spin_unlock_irqrestore(&conf->device_lock, flags); |
704 | clear_bit(In_sync, &rdev->flags); | ||
705 | /* | 702 | /* |
706 | * if recovery was running, make sure it aborts. | 703 | * if recovery was running, make sure it aborts. |
707 | */ | 704 | */ |
@@ -711,7 +708,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) | |||
711 | printk (KERN_ALERT | 708 | printk (KERN_ALERT |
712 | "raid5: Disk failure on %s, disabling device." | 709 | "raid5: Disk failure on %s, disabling device." |
713 | " Operation continuing on %d devices\n", | 710 | " Operation continuing on %d devices\n", |
714 | bdevname(rdev->bdev,b), conf->working_disks); | 711 | bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded); |
715 | } | 712 | } |
716 | } | 713 | } |
717 | 714 | ||
@@ -1353,10 +1350,9 @@ static int page_is_zero(struct page *p) | |||
1353 | static int stripe_to_pdidx(sector_t stripe, raid5_conf_t *conf, int disks) | 1350 | static int stripe_to_pdidx(sector_t stripe, raid5_conf_t *conf, int disks) |
1354 | { | 1351 | { |
1355 | int sectors_per_chunk = conf->chunk_size >> 9; | 1352 | int sectors_per_chunk = conf->chunk_size >> 9; |
1356 | sector_t x = stripe; | ||
1357 | int pd_idx, dd_idx; | 1353 | int pd_idx, dd_idx; |
1358 | int chunk_offset = sector_div(x, sectors_per_chunk); | 1354 | int chunk_offset = sector_div(stripe, sectors_per_chunk); |
1359 | stripe = x; | 1355 | |
1360 | raid5_compute_sector(stripe*(disks-1)*sectors_per_chunk | 1356 | raid5_compute_sector(stripe*(disks-1)*sectors_per_chunk |
1361 | + chunk_offset, disks, disks-1, &dd_idx, &pd_idx, conf); | 1357 | + chunk_offset, disks, disks-1, &dd_idx, &pd_idx, conf); |
1362 | return pd_idx; | 1358 | return pd_idx; |
@@ -2597,6 +2593,24 @@ static int raid5_issue_flush(request_queue_t *q, struct gendisk *disk, | |||
2597 | return ret; | 2593 | return ret; |
2598 | } | 2594 | } |
2599 | 2595 | ||
2596 | static int raid5_congested(void *data, int bits) | ||
2597 | { | ||
2598 | mddev_t *mddev = data; | ||
2599 | raid5_conf_t *conf = mddev_to_conf(mddev); | ||
2600 | |||
2601 | /* No difference between reads and writes. Just check | ||
2602 | * how busy the stripe_cache is | ||
2603 | */ | ||
2604 | if (conf->inactive_blocked) | ||
2605 | return 1; | ||
2606 | if (conf->quiesce) | ||
2607 | return 1; | ||
2608 | if (list_empty_careful(&conf->inactive_list)) | ||
2609 | return 1; | ||
2610 | |||
2611 | return 0; | ||
2612 | } | ||
2613 | |||
2600 | static int make_request(request_queue_t *q, struct bio * bi) | 2614 | static int make_request(request_queue_t *q, struct bio * bi) |
2601 | { | 2615 | { |
2602 | mddev_t *mddev = q->queuedata; | 2616 | mddev_t *mddev = q->queuedata; |
@@ -2781,9 +2795,9 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped | |||
2781 | wait_event(conf->wait_for_overlap, | 2795 | wait_event(conf->wait_for_overlap, |
2782 | atomic_read(&conf->reshape_stripes)==0); | 2796 | atomic_read(&conf->reshape_stripes)==0); |
2783 | mddev->reshape_position = conf->expand_progress; | 2797 | mddev->reshape_position = conf->expand_progress; |
2784 | mddev->sb_dirty = 1; | 2798 | set_bit(MD_CHANGE_DEVS, &mddev->flags); |
2785 | md_wakeup_thread(mddev->thread); | 2799 | md_wakeup_thread(mddev->thread); |
2786 | wait_event(mddev->sb_wait, mddev->sb_dirty == 0 || | 2800 | wait_event(mddev->sb_wait, mddev->flags == 0 || |
2787 | kthread_should_stop()); | 2801 | kthread_should_stop()); |
2788 | spin_lock_irq(&conf->device_lock); | 2802 | spin_lock_irq(&conf->device_lock); |
2789 | conf->expand_lo = mddev->reshape_position; | 2803 | conf->expand_lo = mddev->reshape_position; |
@@ -3074,6 +3088,7 @@ static int run(mddev_t *mddev) | |||
3074 | mdk_rdev_t *rdev; | 3088 | mdk_rdev_t *rdev; |
3075 | struct disk_info *disk; | 3089 | struct disk_info *disk; |
3076 | struct list_head *tmp; | 3090 | struct list_head *tmp; |
3091 | int working_disks = 0; | ||
3077 | 3092 | ||
3078 | if (mddev->level != 5 && mddev->level != 4 && mddev->level != 6) { | 3093 | if (mddev->level != 5 && mddev->level != 4 && mddev->level != 6) { |
3079 | printk(KERN_ERR "raid5: %s: raid level not set to 4/5/6 (%d)\n", | 3094 | printk(KERN_ERR "raid5: %s: raid level not set to 4/5/6 (%d)\n", |
@@ -3176,14 +3191,14 @@ static int run(mddev_t *mddev) | |||
3176 | printk(KERN_INFO "raid5: device %s operational as raid" | 3191 | printk(KERN_INFO "raid5: device %s operational as raid" |
3177 | " disk %d\n", bdevname(rdev->bdev,b), | 3192 | " disk %d\n", bdevname(rdev->bdev,b), |
3178 | raid_disk); | 3193 | raid_disk); |
3179 | conf->working_disks++; | 3194 | working_disks++; |
3180 | } | 3195 | } |
3181 | } | 3196 | } |
3182 | 3197 | ||
3183 | /* | 3198 | /* |
3184 | * 0 for a fully functional array, 1 or 2 for a degraded array. | 3199 | * 0 for a fully functional array, 1 or 2 for a degraded array. |
3185 | */ | 3200 | */ |
3186 | mddev->degraded = conf->failed_disks = conf->raid_disks - conf->working_disks; | 3201 | mddev->degraded = conf->raid_disks - working_disks; |
3187 | conf->mddev = mddev; | 3202 | conf->mddev = mddev; |
3188 | conf->chunk_size = mddev->chunk_size; | 3203 | conf->chunk_size = mddev->chunk_size; |
3189 | conf->level = mddev->level; | 3204 | conf->level = mddev->level; |
@@ -3218,7 +3233,7 @@ static int run(mddev_t *mddev) | |||
3218 | if (mddev->degraded > conf->max_degraded) { | 3233 | if (mddev->degraded > conf->max_degraded) { |
3219 | printk(KERN_ERR "raid5: not enough operational devices for %s" | 3234 | printk(KERN_ERR "raid5: not enough operational devices for %s" |
3220 | " (%d/%d failed)\n", | 3235 | " (%d/%d failed)\n", |
3221 | mdname(mddev), conf->failed_disks, conf->raid_disks); | 3236 | mdname(mddev), mddev->degraded, conf->raid_disks); |
3222 | goto abort; | 3237 | goto abort; |
3223 | } | 3238 | } |
3224 | 3239 | ||
@@ -3299,6 +3314,9 @@ static int run(mddev_t *mddev) | |||
3299 | 3314 | ||
3300 | mddev->queue->unplug_fn = raid5_unplug_device; | 3315 | mddev->queue->unplug_fn = raid5_unplug_device; |
3301 | mddev->queue->issue_flush_fn = raid5_issue_flush; | 3316 | mddev->queue->issue_flush_fn = raid5_issue_flush; |
3317 | mddev->queue->backing_dev_info.congested_fn = raid5_congested; | ||
3318 | mddev->queue->backing_dev_info.congested_data = mddev; | ||
3319 | |||
3302 | mddev->array_size = mddev->size * (conf->previous_raid_disks - | 3320 | mddev->array_size = mddev->size * (conf->previous_raid_disks - |
3303 | conf->max_degraded); | 3321 | conf->max_degraded); |
3304 | 3322 | ||
@@ -3375,7 +3393,7 @@ static void status (struct seq_file *seq, mddev_t *mddev) | |||
3375 | int i; | 3393 | int i; |
3376 | 3394 | ||
3377 | seq_printf (seq, " level %d, %dk chunk, algorithm %d", mddev->level, mddev->chunk_size >> 10, mddev->layout); | 3395 | seq_printf (seq, " level %d, %dk chunk, algorithm %d", mddev->level, mddev->chunk_size >> 10, mddev->layout); |
3378 | seq_printf (seq, " [%d/%d] [", conf->raid_disks, conf->working_disks); | 3396 | seq_printf (seq, " [%d/%d] [", conf->raid_disks, conf->raid_disks - mddev->degraded); |
3379 | for (i = 0; i < conf->raid_disks; i++) | 3397 | for (i = 0; i < conf->raid_disks; i++) |
3380 | seq_printf (seq, "%s", | 3398 | seq_printf (seq, "%s", |
3381 | conf->disks[i].rdev && | 3399 | conf->disks[i].rdev && |
@@ -3397,8 +3415,8 @@ static void print_raid5_conf (raid5_conf_t *conf) | |||
3397 | printk("(conf==NULL)\n"); | 3415 | printk("(conf==NULL)\n"); |
3398 | return; | 3416 | return; |
3399 | } | 3417 | } |
3400 | printk(" --- rd:%d wd:%d fd:%d\n", conf->raid_disks, | 3418 | printk(" --- rd:%d wd:%d\n", conf->raid_disks, |
3401 | conf->working_disks, conf->failed_disks); | 3419 | conf->raid_disks - conf->mddev->degraded); |
3402 | 3420 | ||
3403 | for (i = 0; i < conf->raid_disks; i++) { | 3421 | for (i = 0; i < conf->raid_disks; i++) { |
3404 | char b[BDEVNAME_SIZE]; | 3422 | char b[BDEVNAME_SIZE]; |
@@ -3420,11 +3438,11 @@ static int raid5_spare_active(mddev_t *mddev) | |||
3420 | tmp = conf->disks + i; | 3438 | tmp = conf->disks + i; |
3421 | if (tmp->rdev | 3439 | if (tmp->rdev |
3422 | && !test_bit(Faulty, &tmp->rdev->flags) | 3440 | && !test_bit(Faulty, &tmp->rdev->flags) |
3423 | && !test_bit(In_sync, &tmp->rdev->flags)) { | 3441 | && !test_and_set_bit(In_sync, &tmp->rdev->flags)) { |
3442 | unsigned long flags; | ||
3443 | spin_lock_irqsave(&conf->device_lock, flags); | ||
3424 | mddev->degraded--; | 3444 | mddev->degraded--; |
3425 | conf->failed_disks--; | 3445 | spin_unlock_irqrestore(&conf->device_lock, flags); |
3426 | conf->working_disks++; | ||
3427 | set_bit(In_sync, &tmp->rdev->flags); | ||
3428 | } | 3446 | } |
3429 | } | 3447 | } |
3430 | print_raid5_conf(conf); | 3448 | print_raid5_conf(conf); |
@@ -3560,6 +3578,7 @@ static int raid5_start_reshape(mddev_t *mddev) | |||
3560 | struct list_head *rtmp; | 3578 | struct list_head *rtmp; |
3561 | int spares = 0; | 3579 | int spares = 0; |
3562 | int added_devices = 0; | 3580 | int added_devices = 0; |
3581 | unsigned long flags; | ||
3563 | 3582 | ||
3564 | if (mddev->degraded || | 3583 | if (mddev->degraded || |
3565 | test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) | 3584 | test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) |
@@ -3593,7 +3612,6 @@ static int raid5_start_reshape(mddev_t *mddev) | |||
3593 | if (raid5_add_disk(mddev, rdev)) { | 3612 | if (raid5_add_disk(mddev, rdev)) { |
3594 | char nm[20]; | 3613 | char nm[20]; |
3595 | set_bit(In_sync, &rdev->flags); | 3614 | set_bit(In_sync, &rdev->flags); |
3596 | conf->working_disks++; | ||
3597 | added_devices++; | 3615 | added_devices++; |
3598 | rdev->recovery_offset = 0; | 3616 | rdev->recovery_offset = 0; |
3599 | sprintf(nm, "rd%d", rdev->raid_disk); | 3617 | sprintf(nm, "rd%d", rdev->raid_disk); |
@@ -3602,10 +3620,12 @@ static int raid5_start_reshape(mddev_t *mddev) | |||
3602 | break; | 3620 | break; |
3603 | } | 3621 | } |
3604 | 3622 | ||
3623 | spin_lock_irqsave(&conf->device_lock, flags); | ||
3605 | mddev->degraded = (conf->raid_disks - conf->previous_raid_disks) - added_devices; | 3624 | mddev->degraded = (conf->raid_disks - conf->previous_raid_disks) - added_devices; |
3625 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
3606 | mddev->raid_disks = conf->raid_disks; | 3626 | mddev->raid_disks = conf->raid_disks; |
3607 | mddev->reshape_position = 0; | 3627 | mddev->reshape_position = 0; |
3608 | mddev->sb_dirty = 1; | 3628 | set_bit(MD_CHANGE_DEVS, &mddev->flags); |
3609 | 3629 | ||
3610 | clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); | 3630 | clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); |
3611 | clear_bit(MD_RECOVERY_CHECK, &mddev->recovery); | 3631 | clear_bit(MD_RECOVERY_CHECK, &mddev->recovery); |
diff --git a/drivers/net/Space.c b/drivers/net/Space.c index 9953201c670d..a67f5efc983f 100644 --- a/drivers/net/Space.c +++ b/drivers/net/Space.c | |||
@@ -165,7 +165,7 @@ static struct devprobe2 mca_probes[] __initdata = { | |||
165 | * look for EISA/PCI/MCA cards in addition to ISA cards). | 165 | * look for EISA/PCI/MCA cards in addition to ISA cards). |
166 | */ | 166 | */ |
167 | static struct devprobe2 isa_probes[] __initdata = { | 167 | static struct devprobe2 isa_probes[] __initdata = { |
168 | #ifdef CONFIG_HP100 /* ISA, EISA & PCI */ | 168 | #if defined(CONFIG_HP100) && defined(CONFIG_ISA) /* ISA, EISA */ |
169 | {hp100_probe, 0}, | 169 | {hp100_probe, 0}, |
170 | #endif | 170 | #endif |
171 | #ifdef CONFIG_3C515 | 171 | #ifdef CONFIG_3C515 |
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index 34412bc7c4b6..d01870619a4a 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c | |||
@@ -944,12 +944,13 @@ extern int fs_mii_connect(struct net_device *dev); | |||
944 | extern void fs_mii_disconnect(struct net_device *dev); | 944 | extern void fs_mii_disconnect(struct net_device *dev); |
945 | 945 | ||
946 | static struct net_device *fs_init_instance(struct device *dev, | 946 | static struct net_device *fs_init_instance(struct device *dev, |
947 | const struct fs_platform_info *fpi) | 947 | struct fs_platform_info *fpi) |
948 | { | 948 | { |
949 | struct net_device *ndev = NULL; | 949 | struct net_device *ndev = NULL; |
950 | struct fs_enet_private *fep = NULL; | 950 | struct fs_enet_private *fep = NULL; |
951 | int privsize, i, r, err = 0, registered = 0; | 951 | int privsize, i, r, err = 0, registered = 0; |
952 | 952 | ||
953 | fpi->fs_no = fs_get_id(fpi); | ||
953 | /* guard */ | 954 | /* guard */ |
954 | if ((unsigned int)fpi->fs_no >= FS_MAX_INDEX) | 955 | if ((unsigned int)fpi->fs_no >= FS_MAX_INDEX) |
955 | return ERR_PTR(-EINVAL); | 956 | return ERR_PTR(-EINVAL); |
@@ -971,7 +972,7 @@ static struct net_device *fs_init_instance(struct device *dev, | |||
971 | dev_set_drvdata(dev, ndev); | 972 | dev_set_drvdata(dev, ndev); |
972 | fep->fpi = fpi; | 973 | fep->fpi = fpi; |
973 | if (fpi->init_ioports) | 974 | if (fpi->init_ioports) |
974 | fpi->init_ioports(); | 975 | fpi->init_ioports((struct fs_platform_info *)fpi); |
975 | 976 | ||
976 | #ifdef CONFIG_FS_ENET_HAS_FEC | 977 | #ifdef CONFIG_FS_ENET_HAS_FEC |
977 | if (fs_get_fec_index(fpi->fs_no) >= 0) | 978 | if (fs_get_fec_index(fpi->fs_no) >= 0) |
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c index 561db440bc2c..ae8ad4f763bf 100644 --- a/drivers/net/hp100.c +++ b/drivers/net/hp100.c | |||
@@ -188,7 +188,7 @@ struct hp100_private { | |||
188 | /* | 188 | /* |
189 | * variables | 189 | * variables |
190 | */ | 190 | */ |
191 | #ifndef MODULE | 191 | #ifdef CONFIG_ISA |
192 | static const char *hp100_isa_tbl[] = { | 192 | static const char *hp100_isa_tbl[] = { |
193 | "HWPF150", /* HP J2573 rev A */ | 193 | "HWPF150", /* HP J2573 rev A */ |
194 | "HWP1950", /* HP J2573 */ | 194 | "HWP1950", /* HP J2573 */ |
@@ -335,7 +335,7 @@ static __devinit const char *hp100_read_id(int ioaddr) | |||
335 | return str; | 335 | return str; |
336 | } | 336 | } |
337 | 337 | ||
338 | #ifndef MODULE | 338 | #ifdef CONFIG_ISA |
339 | static __init int hp100_isa_probe1(struct net_device *dev, int ioaddr) | 339 | static __init int hp100_isa_probe1(struct net_device *dev, int ioaddr) |
340 | { | 340 | { |
341 | const char *sig; | 341 | const char *sig; |
@@ -393,7 +393,9 @@ static int __init hp100_isa_probe(struct net_device *dev, int addr) | |||
393 | } | 393 | } |
394 | return err; | 394 | return err; |
395 | } | 395 | } |
396 | #endif /* CONFIG_ISA */ | ||
396 | 397 | ||
398 | #if !defined(MODULE) && defined(CONFIG_ISA) | ||
397 | struct net_device * __init hp100_probe(int unit) | 399 | struct net_device * __init hp100_probe(int unit) |
398 | { | 400 | { |
399 | struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private)); | 401 | struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private)); |
@@ -423,7 +425,7 @@ struct net_device * __init hp100_probe(int unit) | |||
423 | free_netdev(dev); | 425 | free_netdev(dev); |
424 | return ERR_PTR(err); | 426 | return ERR_PTR(err); |
425 | } | 427 | } |
426 | #endif | 428 | #endif /* !MODULE && CONFIG_ISA */ |
427 | 429 | ||
428 | static int __devinit hp100_probe1(struct net_device *dev, int ioaddr, | 430 | static int __devinit hp100_probe1(struct net_device *dev, int ioaddr, |
429 | u_char bus, struct pci_dev *pci_dev) | 431 | u_char bus, struct pci_dev *pci_dev) |
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index 6469130c1413..c26a4b8e552a 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c | |||
@@ -200,8 +200,8 @@ static struct net_device_stats *ifb_get_stats(struct net_device *dev) | |||
200 | 200 | ||
201 | pr_debug("tasklets stats %ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld \n", | 201 | pr_debug("tasklets stats %ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld \n", |
202 | dp->st_task_enter, dp->st_txq_refl_try, dp->st_rxq_enter, | 202 | dp->st_task_enter, dp->st_txq_refl_try, dp->st_rxq_enter, |
203 | dp->st_rx2tx_tran dp->st_rxq_notenter, dp->st_rx_frm_egr, | 203 | dp->st_rx2tx_tran, dp->st_rxq_notenter, dp->st_rx_frm_egr, |
204 | dp->st_rx_frm_ing, dp->st_rxq_check, dp->st_rxq_rsch ); | 204 | dp->st_rx_frm_ing, dp->st_rxq_check, dp->st_rxq_rsch); |
205 | 205 | ||
206 | return stats; | 206 | return stats; |
207 | } | 207 | } |
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index 43894ddec7dc..fe800dc0be9f 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c | |||
@@ -3374,10 +3374,6 @@ __setup("parport_init_mode=",parport_init_mode_setup); | |||
3374 | 3374 | ||
3375 | static int __init parport_pc_init(void) | 3375 | static int __init parport_pc_init(void) |
3376 | { | 3376 | { |
3377 | #if defined(CONFIG_PPC_MERGE) | ||
3378 | if (check_legacy_ioport(PARALLEL_BASE)) | ||
3379 | return -ENODEV; | ||
3380 | #endif | ||
3381 | if (parse_parport_params()) | 3377 | if (parse_parport_params()) |
3382 | return -EINVAL; | 3378 | return -EINVAL; |
3383 | 3379 | ||
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c index f2e0179962e2..3ac5b123215a 100644 --- a/drivers/pnp/isapnp/core.c +++ b/drivers/pnp/isapnp/core.c | |||
@@ -1049,6 +1049,10 @@ static int __init isapnp_init(void) | |||
1049 | printk(KERN_INFO "isapnp: ISA Plug & Play support disabled\n"); | 1049 | printk(KERN_INFO "isapnp: ISA Plug & Play support disabled\n"); |
1050 | return 0; | 1050 | return 0; |
1051 | } | 1051 | } |
1052 | #ifdef CONFIG_PPC_MERGE | ||
1053 | if (check_legacy_ioport(_PIDXR) || check_legacy_ioport(_PNPWRP)) | ||
1054 | return -EINVAL; | ||
1055 | #endif | ||
1052 | #ifdef ISAPNP_REGION_OK | 1056 | #ifdef ISAPNP_REGION_OK |
1053 | if (!request_region(_PIDXR, 1, "isapnp index")) { | 1057 | if (!request_region(_PIDXR, 1, "isapnp index")) { |
1054 | printk(KERN_ERR "isapnp: Index Register 0x%x already used\n", _PIDXR); | 1058 | printk(KERN_ERR "isapnp: Index Register 0x%x already used\n", _PIDXR); |
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 0ae9ced00ed4..10c2daab99ac 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -320,8 +320,8 @@ static unsigned int serial_in(struct uart_8250_port *up, int offset) | |||
320 | 320 | ||
321 | case UPIO_TSI: | 321 | case UPIO_TSI: |
322 | if (offset == UART_IIR) { | 322 | if (offset == UART_IIR) { |
323 | tmp = readl((u32 *)(up->port.membase + UART_RX)); | 323 | tmp = readl(up->port.membase + (UART_IIR & ~3)); |
324 | return (cpu_to_le32(tmp) >> 8) & 0xff; | 324 | return (tmp >> 16) & 0xff; /* UART_IIR % 4 == 2 */ |
325 | } else | 325 | } else |
326 | return readb(up->port.membase + offset); | 326 | return readb(up->port.membase + offset); |
327 | 327 | ||
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 90ff96e3339b..a0d6136deb9b 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <asm/io.h> | 46 | #include <asm/io.h> |
47 | #include <asm/irq.h> | 47 | #include <asm/irq.h> |
48 | #include <asm/delay.h> | 48 | #include <asm/delay.h> |
49 | #include <asm/fs_pd.h> | ||
49 | 50 | ||
50 | #if defined(CONFIG_SERIAL_CPM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | 51 | #if defined(CONFIG_SERIAL_CPM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) |
51 | #define SUPPORT_SYSRQ | 52 | #define SUPPORT_SYSRQ |
@@ -1022,15 +1023,17 @@ int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con) | |||
1022 | { | 1023 | { |
1023 | struct resource *r; | 1024 | struct resource *r; |
1024 | struct fs_uart_platform_info *pdata = pdev->dev.platform_data; | 1025 | struct fs_uart_platform_info *pdata = pdev->dev.platform_data; |
1025 | int idx = pdata->fs_no; /* It is UART_SMCx or UART_SCCx index */ | 1026 | int idx; /* It is UART_SMCx or UART_SCCx index */ |
1026 | struct uart_cpm_port *pinfo; | 1027 | struct uart_cpm_port *pinfo; |
1027 | int line; | 1028 | int line; |
1028 | u32 mem, pram; | 1029 | u32 mem, pram; |
1029 | 1030 | ||
1031 | idx = pdata->fs_no = fs_uart_get_id(pdata); | ||
1032 | |||
1030 | line = cpm_uart_id2nr(idx); | 1033 | line = cpm_uart_id2nr(idx); |
1031 | if(line < 0) { | 1034 | if(line < 0) { |
1032 | printk(KERN_ERR"%s(): port %d is not registered", __FUNCTION__, idx); | 1035 | printk(KERN_ERR"%s(): port %d is not registered", __FUNCTION__, idx); |
1033 | return -1; | 1036 | return -EINVAL; |
1034 | } | 1037 | } |
1035 | 1038 | ||
1036 | pinfo = (struct uart_cpm_port *) &cpm_uart_ports[idx]; | 1039 | pinfo = (struct uart_cpm_port *) &cpm_uart_ports[idx]; |
@@ -1044,11 +1047,11 @@ int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con) | |||
1044 | 1047 | ||
1045 | if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"))) | 1048 | if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"))) |
1046 | return -EINVAL; | 1049 | return -EINVAL; |
1047 | mem = r->start; | 1050 | mem = (u32)ioremap(r->start, r->end - r->start + 1); |
1048 | 1051 | ||
1049 | if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pram"))) | 1052 | if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pram"))) |
1050 | return -EINVAL; | 1053 | return -EINVAL; |
1051 | pram = r->start; | 1054 | pram = (u32)ioremap(r->start, r->end - r->start + 1); |
1052 | 1055 | ||
1053 | if(idx > fsid_smc2_uart) { | 1056 | if(idx > fsid_smc2_uart) { |
1054 | pinfo->sccp = (scc_t *)mem; | 1057 | pinfo->sccp = (scc_t *)mem; |
@@ -1179,7 +1182,7 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) | |||
1179 | pdata = pdev->dev.platform_data; | 1182 | pdata = pdev->dev.platform_data; |
1180 | if (pdata) | 1183 | if (pdata) |
1181 | if (pdata->init_ioports) | 1184 | if (pdata->init_ioports) |
1182 | pdata->init_ioports(); | 1185 | pdata->init_ioports(pdata); |
1183 | 1186 | ||
1184 | cpm_uart_drv_get_platform_data(pdev, 1); | 1187 | cpm_uart_drv_get_platform_data(pdev, 1); |
1185 | } | 1188 | } |
@@ -1189,11 +1192,7 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) | |||
1189 | if (options) { | 1192 | if (options) { |
1190 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 1193 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
1191 | } else { | 1194 | } else { |
1192 | bd_t *bd = (bd_t *) __res; | 1195 | if ((baud = uart_baudrate()) == -1) |
1193 | |||
1194 | if (bd->bi_baudrate) | ||
1195 | baud = bd->bi_baudrate; | ||
1196 | else | ||
1197 | baud = 9600; | 1196 | baud = 9600; |
1198 | } | 1197 | } |
1199 | 1198 | ||
@@ -1266,13 +1265,14 @@ static int cpm_uart_drv_probe(struct device *dev) | |||
1266 | } | 1265 | } |
1267 | 1266 | ||
1268 | pdata = pdev->dev.platform_data; | 1267 | pdata = pdev->dev.platform_data; |
1269 | pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n", cpm_uart_id2nr(pdata->fs_no)); | ||
1270 | 1268 | ||
1271 | if ((ret = cpm_uart_drv_get_platform_data(pdev, 0))) | 1269 | if ((ret = cpm_uart_drv_get_platform_data(pdev, 0))) |
1272 | return ret; | 1270 | return ret; |
1273 | 1271 | ||
1272 | pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n", cpm_uart_id2nr(pdata->fs_no)); | ||
1273 | |||
1274 | if (pdata->init_ioports) | 1274 | if (pdata->init_ioports) |
1275 | pdata->init_ioports(); | 1275 | pdata->init_ioports(pdata); |
1276 | 1276 | ||
1277 | ret = uart_add_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port); | 1277 | ret = uart_add_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port); |
1278 | 1278 | ||
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c index ef3bb476c432..b691d3e14754 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c | |||
@@ -40,6 +40,7 @@ | |||
40 | 40 | ||
41 | #include <asm/io.h> | 41 | #include <asm/io.h> |
42 | #include <asm/irq.h> | 42 | #include <asm/irq.h> |
43 | #include <asm/fs_pd.h> | ||
43 | 44 | ||
44 | #include <linux/serial_core.h> | 45 | #include <linux/serial_core.h> |
45 | #include <linux/kernel.h> | 46 | #include <linux/kernel.h> |
@@ -50,8 +51,9 @@ | |||
50 | 51 | ||
51 | void cpm_line_cr_cmd(int line, int cmd) | 52 | void cpm_line_cr_cmd(int line, int cmd) |
52 | { | 53 | { |
53 | volatile cpm_cpm2_t *cp = cpmp; | ||
54 | ulong val; | 54 | ulong val; |
55 | volatile cpm_cpm2_t *cp = cpm2_map(im_cpm); | ||
56 | |||
55 | 57 | ||
56 | switch (line) { | 58 | switch (line) { |
57 | case UART_SMC1: | 59 | case UART_SMC1: |
@@ -84,11 +86,14 @@ void cpm_line_cr_cmd(int line, int cmd) | |||
84 | } | 86 | } |
85 | cp->cp_cpcr = val; | 87 | cp->cp_cpcr = val; |
86 | while (cp->cp_cpcr & CPM_CR_FLG) ; | 88 | while (cp->cp_cpcr & CPM_CR_FLG) ; |
89 | |||
90 | cpm2_unmap(cp); | ||
87 | } | 91 | } |
88 | 92 | ||
89 | void smc1_lineif(struct uart_cpm_port *pinfo) | 93 | void smc1_lineif(struct uart_cpm_port *pinfo) |
90 | { | 94 | { |
91 | volatile iop_cpm2_t *io = &cpm2_immr->im_ioport; | 95 | volatile iop_cpm2_t *io = cpm2_map(im_ioport); |
96 | volatile cpmux_t *cpmux = cpm2_map(im_cpmux); | ||
92 | 97 | ||
93 | /* SMC1 is only on port D */ | 98 | /* SMC1 is only on port D */ |
94 | io->iop_ppard |= 0x00c00000; | 99 | io->iop_ppard |= 0x00c00000; |
@@ -97,13 +102,17 @@ void smc1_lineif(struct uart_cpm_port *pinfo) | |||
97 | io->iop_psord &= ~0x00c00000; | 102 | io->iop_psord &= ~0x00c00000; |
98 | 103 | ||
99 | /* Wire BRG1 to SMC1 */ | 104 | /* Wire BRG1 to SMC1 */ |
100 | cpm2_immr->im_cpmux.cmx_smr &= 0x0f; | 105 | cpmux->cmx_smr &= 0x0f; |
101 | pinfo->brg = 1; | 106 | pinfo->brg = 1; |
107 | |||
108 | cpm2_unmap(cpmux); | ||
109 | cpm2_unmap(io); | ||
102 | } | 110 | } |
103 | 111 | ||
104 | void smc2_lineif(struct uart_cpm_port *pinfo) | 112 | void smc2_lineif(struct uart_cpm_port *pinfo) |
105 | { | 113 | { |
106 | volatile iop_cpm2_t *io = &cpm2_immr->im_ioport; | 114 | volatile iop_cpm2_t *io = cpm2_map(im_ioport); |
115 | volatile cpmux_t *cpmux = cpm2_map(im_cpmux); | ||
107 | 116 | ||
108 | /* SMC2 is only on port A */ | 117 | /* SMC2 is only on port A */ |
109 | io->iop_ppara |= 0x00c00000; | 118 | io->iop_ppara |= 0x00c00000; |
@@ -112,13 +121,17 @@ void smc2_lineif(struct uart_cpm_port *pinfo) | |||
112 | io->iop_psora &= ~0x00c00000; | 121 | io->iop_psora &= ~0x00c00000; |
113 | 122 | ||
114 | /* Wire BRG2 to SMC2 */ | 123 | /* Wire BRG2 to SMC2 */ |
115 | cpm2_immr->im_cpmux.cmx_smr &= 0xf0; | 124 | cpmux->cmx_smr &= 0xf0; |
116 | pinfo->brg = 2; | 125 | pinfo->brg = 2; |
126 | |||
127 | cpm2_unmap(cpmux); | ||
128 | cpm2_unmap(io); | ||
117 | } | 129 | } |
118 | 130 | ||
119 | void scc1_lineif(struct uart_cpm_port *pinfo) | 131 | void scc1_lineif(struct uart_cpm_port *pinfo) |
120 | { | 132 | { |
121 | volatile iop_cpm2_t *io = &cpm2_immr->im_ioport; | 133 | volatile iop_cpm2_t *io = cpm2_map(im_ioport); |
134 | volatile cpmux_t *cpmux = cpm2_map(im_cpmux); | ||
122 | 135 | ||
123 | /* Use Port D for SCC1 instead of other functions. */ | 136 | /* Use Port D for SCC1 instead of other functions. */ |
124 | io->iop_ppard |= 0x00000003; | 137 | io->iop_ppard |= 0x00000003; |
@@ -128,9 +141,12 @@ void scc1_lineif(struct uart_cpm_port *pinfo) | |||
128 | io->iop_pdird |= 0x00000002; /* Tx */ | 141 | io->iop_pdird |= 0x00000002; /* Tx */ |
129 | 142 | ||
130 | /* Wire BRG1 to SCC1 */ | 143 | /* Wire BRG1 to SCC1 */ |
131 | cpm2_immr->im_cpmux.cmx_scr &= 0x00ffffff; | 144 | cpmux->cmx_scr &= 0x00ffffff; |
132 | cpm2_immr->im_cpmux.cmx_scr |= 0x00000000; | 145 | cpmux->cmx_scr |= 0x00000000; |
133 | pinfo->brg = 1; | 146 | pinfo->brg = 1; |
147 | |||
148 | cpm2_unmap(cpmux); | ||
149 | cpm2_unmap(io); | ||
134 | } | 150 | } |
135 | 151 | ||
136 | void scc2_lineif(struct uart_cpm_port *pinfo) | 152 | void scc2_lineif(struct uart_cpm_port *pinfo) |
@@ -143,43 +159,57 @@ void scc2_lineif(struct uart_cpm_port *pinfo) | |||
143 | * be supported in a sane fashion. | 159 | * be supported in a sane fashion. |
144 | */ | 160 | */ |
145 | #ifndef CONFIG_STX_GP3 | 161 | #ifndef CONFIG_STX_GP3 |
146 | volatile iop_cpm2_t *io = &cpm2_immr->im_ioport; | 162 | volatile iop_cpm2_t *io = cpm2_map(im_ioport); |
163 | volatile cpmux_t *cpmux = cpm2_map(im_cpmux); | ||
164 | |||
147 | io->iop_pparb |= 0x008b0000; | 165 | io->iop_pparb |= 0x008b0000; |
148 | io->iop_pdirb |= 0x00880000; | 166 | io->iop_pdirb |= 0x00880000; |
149 | io->iop_psorb |= 0x00880000; | 167 | io->iop_psorb |= 0x00880000; |
150 | io->iop_pdirb &= ~0x00030000; | 168 | io->iop_pdirb &= ~0x00030000; |
151 | io->iop_psorb &= ~0x00030000; | 169 | io->iop_psorb &= ~0x00030000; |
152 | #endif | 170 | #endif |
153 | cpm2_immr->im_cpmux.cmx_scr &= 0xff00ffff; | 171 | cpmux->cmx_scr &= 0xff00ffff; |
154 | cpm2_immr->im_cpmux.cmx_scr |= 0x00090000; | 172 | cpmux->cmx_scr |= 0x00090000; |
155 | pinfo->brg = 2; | 173 | pinfo->brg = 2; |
174 | |||
175 | cpm2_unmap(cpmux); | ||
176 | cpm2_unmap(io); | ||
156 | } | 177 | } |
157 | 178 | ||
158 | void scc3_lineif(struct uart_cpm_port *pinfo) | 179 | void scc3_lineif(struct uart_cpm_port *pinfo) |
159 | { | 180 | { |
160 | volatile iop_cpm2_t *io = &cpm2_immr->im_ioport; | 181 | volatile iop_cpm2_t *io = cpm2_map(im_ioport); |
182 | volatile cpmux_t *cpmux = cpm2_map(im_cpmux); | ||
183 | |||
161 | io->iop_pparb |= 0x008b0000; | 184 | io->iop_pparb |= 0x008b0000; |
162 | io->iop_pdirb |= 0x00880000; | 185 | io->iop_pdirb |= 0x00880000; |
163 | io->iop_psorb |= 0x00880000; | 186 | io->iop_psorb |= 0x00880000; |
164 | io->iop_pdirb &= ~0x00030000; | 187 | io->iop_pdirb &= ~0x00030000; |
165 | io->iop_psorb &= ~0x00030000; | 188 | io->iop_psorb &= ~0x00030000; |
166 | cpm2_immr->im_cpmux.cmx_scr &= 0xffff00ff; | 189 | cpmux->cmx_scr &= 0xffff00ff; |
167 | cpm2_immr->im_cpmux.cmx_scr |= 0x00001200; | 190 | cpmux->cmx_scr |= 0x00001200; |
168 | pinfo->brg = 3; | 191 | pinfo->brg = 3; |
192 | |||
193 | cpm2_unmap(cpmux); | ||
194 | cpm2_unmap(io); | ||
169 | } | 195 | } |
170 | 196 | ||
171 | void scc4_lineif(struct uart_cpm_port *pinfo) | 197 | void scc4_lineif(struct uart_cpm_port *pinfo) |
172 | { | 198 | { |
173 | volatile iop_cpm2_t *io = &cpm2_immr->im_ioport; | 199 | volatile iop_cpm2_t *io = cpm2_map(im_ioport); |
200 | volatile cpmux_t *cpmux = cpm2_map(im_cpmux); | ||
174 | 201 | ||
175 | io->iop_ppard |= 0x00000600; | 202 | io->iop_ppard |= 0x00000600; |
176 | io->iop_psord &= ~0x00000600; /* Tx/Rx */ | 203 | io->iop_psord &= ~0x00000600; /* Tx/Rx */ |
177 | io->iop_pdird &= ~0x00000200; /* Rx */ | 204 | io->iop_pdird &= ~0x00000200; /* Rx */ |
178 | io->iop_pdird |= 0x00000400; /* Tx */ | 205 | io->iop_pdird |= 0x00000400; /* Tx */ |
179 | 206 | ||
180 | cpm2_immr->im_cpmux.cmx_scr &= 0xffffff00; | 207 | cpmux->cmx_scr &= 0xffffff00; |
181 | cpm2_immr->im_cpmux.cmx_scr |= 0x0000001b; | 208 | cpmux->cmx_scr |= 0x0000001b; |
182 | pinfo->brg = 4; | 209 | pinfo->brg = 4; |
210 | |||
211 | cpm2_unmap(cpmux); | ||
212 | cpm2_unmap(io); | ||
183 | } | 213 | } |
184 | 214 | ||
185 | /* | 215 | /* |
@@ -254,88 +284,103 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo) | |||
254 | /* Setup any dynamic params in the uart desc */ | 284 | /* Setup any dynamic params in the uart desc */ |
255 | int cpm_uart_init_portdesc(void) | 285 | int cpm_uart_init_portdesc(void) |
256 | { | 286 | { |
287 | #if defined(CONFIG_SERIAL_CPM_SMC1) || defined(CONFIG_SERIAL_CPM_SMC2) | ||
288 | u32 addr; | ||
289 | #endif | ||
257 | pr_debug("CPM uart[-]:init portdesc\n"); | 290 | pr_debug("CPM uart[-]:init portdesc\n"); |
258 | 291 | ||
259 | cpm_uart_nr = 0; | 292 | cpm_uart_nr = 0; |
260 | #ifdef CONFIG_SERIAL_CPM_SMC1 | 293 | #ifdef CONFIG_SERIAL_CPM_SMC1 |
261 | cpm_uart_ports[UART_SMC1].smcp = (smc_t *) & cpm2_immr->im_smc[0]; | 294 | cpm_uart_ports[UART_SMC1].smcp = (smc_t *) cpm2_map(im_smc[0]); |
262 | cpm_uart_ports[UART_SMC1].smcup = | ||
263 | (smc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SMC1]; | ||
264 | *(u16 *)(&cpm2_immr->im_dprambase[PROFF_SMC1_BASE]) = PROFF_SMC1; | ||
265 | cpm_uart_ports[UART_SMC1].port.mapbase = | 295 | cpm_uart_ports[UART_SMC1].port.mapbase = |
266 | (unsigned long)&cpm2_immr->im_smc[0]; | 296 | (unsigned long)cpm_uart_ports[UART_SMC1].smcp; |
297 | |||
298 | cpm_uart_ports[UART_SMC1].smcup = | ||
299 | (smc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SMC1], PROFF_SMC_SIZE); | ||
300 | addr = (u16 *)cpm2_map_size(im_dprambase[PROFF_SMC1_BASE], 2); | ||
301 | *addr = PROFF_SMC1; | ||
302 | cpm2_unmap(addr); | ||
303 | |||
267 | cpm_uart_ports[UART_SMC1].smcp->smc_smcm |= (SMCM_RX | SMCM_TX); | 304 | cpm_uart_ports[UART_SMC1].smcp->smc_smcm |= (SMCM_RX | SMCM_TX); |
268 | cpm_uart_ports[UART_SMC1].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); | 305 | cpm_uart_ports[UART_SMC1].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); |
269 | cpm_uart_ports[UART_SMC1].port.uartclk = (((bd_t *) __res)->bi_intfreq); | 306 | cpm_uart_ports[UART_SMC1].port.uartclk = uart_clock(); |
270 | cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1; | 307 | cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1; |
271 | #endif | 308 | #endif |
272 | 309 | ||
273 | #ifdef CONFIG_SERIAL_CPM_SMC2 | 310 | #ifdef CONFIG_SERIAL_CPM_SMC2 |
274 | cpm_uart_ports[UART_SMC2].smcp = (smc_t *) & cpm2_immr->im_smc[1]; | 311 | cpm_uart_ports[UART_SMC2].smcp = (smc_t *) cpm2_map(im_smc[1]); |
275 | cpm_uart_ports[UART_SMC2].smcup = | ||
276 | (smc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SMC2]; | ||
277 | *(u16 *)(&cpm2_immr->im_dprambase[PROFF_SMC2_BASE]) = PROFF_SMC2; | ||
278 | cpm_uart_ports[UART_SMC2].port.mapbase = | 312 | cpm_uart_ports[UART_SMC2].port.mapbase = |
279 | (unsigned long)&cpm2_immr->im_smc[1]; | 313 | (unsigned long)cpm_uart_ports[UART_SMC2].smcp; |
314 | |||
315 | cpm_uart_ports[UART_SMC2].smcup = | ||
316 | (smc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SMC2], PROFF_SMC_SIZE); | ||
317 | addr = (u16 *)cpm2_map_size(im_dprambase[PROFF_SMC2_BASE], 2); | ||
318 | *addr = PROFF_SMC2; | ||
319 | cpm2_unmap(addr); | ||
320 | |||
280 | cpm_uart_ports[UART_SMC2].smcp->smc_smcm |= (SMCM_RX | SMCM_TX); | 321 | cpm_uart_ports[UART_SMC2].smcp->smc_smcm |= (SMCM_RX | SMCM_TX); |
281 | cpm_uart_ports[UART_SMC2].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); | 322 | cpm_uart_ports[UART_SMC2].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); |
282 | cpm_uart_ports[UART_SMC2].port.uartclk = (((bd_t *) __res)->bi_intfreq); | 323 | cpm_uart_ports[UART_SMC2].port.uartclk = uart_clock(); |
283 | cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2; | 324 | cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2; |
284 | #endif | 325 | #endif |
285 | 326 | ||
286 | #ifdef CONFIG_SERIAL_CPM_SCC1 | 327 | #ifdef CONFIG_SERIAL_CPM_SCC1 |
287 | cpm_uart_ports[UART_SCC1].sccp = (scc_t *) & cpm2_immr->im_scc[0]; | 328 | cpm_uart_ports[UART_SCC1].sccp = (scc_t *) cpm2_map(im_scc[0]); |
288 | cpm_uart_ports[UART_SCC1].sccup = | ||
289 | (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC1]; | ||
290 | cpm_uart_ports[UART_SCC1].port.mapbase = | 329 | cpm_uart_ports[UART_SCC1].port.mapbase = |
291 | (unsigned long)&cpm2_immr->im_scc[0]; | 330 | (unsigned long)cpm_uart_ports[UART_SCC1].sccp; |
331 | cpm_uart_ports[UART_SCC1].sccup = | ||
332 | (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC1], PROFF_SCC_SIZE); | ||
333 | |||
292 | cpm_uart_ports[UART_SCC1].sccp->scc_sccm &= | 334 | cpm_uart_ports[UART_SCC1].sccp->scc_sccm &= |
293 | ~(UART_SCCM_TX | UART_SCCM_RX); | 335 | ~(UART_SCCM_TX | UART_SCCM_RX); |
294 | cpm_uart_ports[UART_SCC1].sccp->scc_gsmrl &= | 336 | cpm_uart_ports[UART_SCC1].sccp->scc_gsmrl &= |
295 | ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); | 337 | ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); |
296 | cpm_uart_ports[UART_SCC1].port.uartclk = (((bd_t *) __res)->bi_intfreq); | 338 | cpm_uart_ports[UART_SCC1].port.uartclk = uart_clock(); |
297 | cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1; | 339 | cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1; |
298 | #endif | 340 | #endif |
299 | 341 | ||
300 | #ifdef CONFIG_SERIAL_CPM_SCC2 | 342 | #ifdef CONFIG_SERIAL_CPM_SCC2 |
301 | cpm_uart_ports[UART_SCC2].sccp = (scc_t *) & cpm2_immr->im_scc[1]; | 343 | cpm_uart_ports[UART_SCC2].sccp = (scc_t *) cpm2_map(im_scc[1]); |
302 | cpm_uart_ports[UART_SCC2].sccup = | ||
303 | (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC2]; | ||
304 | cpm_uart_ports[UART_SCC2].port.mapbase = | 344 | cpm_uart_ports[UART_SCC2].port.mapbase = |
305 | (unsigned long)&cpm2_immr->im_scc[1]; | 345 | (unsigned long)cpm_uart_ports[UART_SCC2].sccp; |
346 | cpm_uart_ports[UART_SCC2].sccup = | ||
347 | (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC2], PROFF_SCC_SIZE); | ||
348 | |||
306 | cpm_uart_ports[UART_SCC2].sccp->scc_sccm &= | 349 | cpm_uart_ports[UART_SCC2].sccp->scc_sccm &= |
307 | ~(UART_SCCM_TX | UART_SCCM_RX); | 350 | ~(UART_SCCM_TX | UART_SCCM_RX); |
308 | cpm_uart_ports[UART_SCC2].sccp->scc_gsmrl &= | 351 | cpm_uart_ports[UART_SCC2].sccp->scc_gsmrl &= |
309 | ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); | 352 | ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); |
310 | cpm_uart_ports[UART_SCC2].port.uartclk = (((bd_t *) __res)->bi_intfreq); | 353 | cpm_uart_ports[UART_SCC2].port.uartclk = uart_clock(); |
311 | cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2; | 354 | cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2; |
312 | #endif | 355 | #endif |
313 | 356 | ||
314 | #ifdef CONFIG_SERIAL_CPM_SCC3 | 357 | #ifdef CONFIG_SERIAL_CPM_SCC3 |
315 | cpm_uart_ports[UART_SCC3].sccp = (scc_t *) & cpm2_immr->im_scc[2]; | 358 | cpm_uart_ports[UART_SCC3].sccp = (scc_t *) cpm2_map(im_scc[2]); |
316 | cpm_uart_ports[UART_SCC3].sccup = | ||
317 | (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC3]; | ||
318 | cpm_uart_ports[UART_SCC3].port.mapbase = | 359 | cpm_uart_ports[UART_SCC3].port.mapbase = |
319 | (unsigned long)&cpm2_immr->im_scc[2]; | 360 | (unsigned long)cpm_uart_ports[UART_SCC3].sccp; |
361 | cpm_uart_ports[UART_SCC3].sccup = | ||
362 | (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC3], PROFF_SCC_SIZE); | ||
363 | |||
320 | cpm_uart_ports[UART_SCC3].sccp->scc_sccm &= | 364 | cpm_uart_ports[UART_SCC3].sccp->scc_sccm &= |
321 | ~(UART_SCCM_TX | UART_SCCM_RX); | 365 | ~(UART_SCCM_TX | UART_SCCM_RX); |
322 | cpm_uart_ports[UART_SCC3].sccp->scc_gsmrl &= | 366 | cpm_uart_ports[UART_SCC3].sccp->scc_gsmrl &= |
323 | ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); | 367 | ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); |
324 | cpm_uart_ports[UART_SCC3].port.uartclk = (((bd_t *) __res)->bi_intfreq); | 368 | cpm_uart_ports[UART_SCC3].port.uartclk = uart_clock(); |
325 | cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3; | 369 | cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3; |
326 | #endif | 370 | #endif |
327 | 371 | ||
328 | #ifdef CONFIG_SERIAL_CPM_SCC4 | 372 | #ifdef CONFIG_SERIAL_CPM_SCC4 |
329 | cpm_uart_ports[UART_SCC4].sccp = (scc_t *) & cpm2_immr->im_scc[3]; | 373 | cpm_uart_ports[UART_SCC4].sccp = (scc_t *) cpm2_map(im_scc[3]); |
330 | cpm_uart_ports[UART_SCC4].sccup = | ||
331 | (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC4]; | ||
332 | cpm_uart_ports[UART_SCC4].port.mapbase = | 374 | cpm_uart_ports[UART_SCC4].port.mapbase = |
333 | (unsigned long)&cpm2_immr->im_scc[3]; | 375 | (unsigned long)cpm_uart_ports[UART_SCC4].sccp; |
376 | cpm_uart_ports[UART_SCC4].sccup = | ||
377 | (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC4], PROFF_SCC_SIZE); | ||
378 | |||
334 | cpm_uart_ports[UART_SCC4].sccp->scc_sccm &= | 379 | cpm_uart_ports[UART_SCC4].sccp->scc_sccm &= |
335 | ~(UART_SCCM_TX | UART_SCCM_RX); | 380 | ~(UART_SCCM_TX | UART_SCCM_RX); |
336 | cpm_uart_ports[UART_SCC4].sccp->scc_gsmrl &= | 381 | cpm_uart_ports[UART_SCC4].sccp->scc_gsmrl &= |
337 | ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); | 382 | ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); |
338 | cpm_uart_ports[UART_SCC4].port.uartclk = (((bd_t *) __res)->bi_intfreq); | 383 | cpm_uart_ports[UART_SCC4].port.uartclk = uart_clock(); |
339 | cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4; | 384 | cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4; |
340 | #endif | 385 | #endif |
341 | 386 | ||
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.h b/drivers/serial/cpm_uart/cpm_uart_cpm2.h index 4793fecf8ece..a663300d3476 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.h +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.h | |||
@@ -40,6 +40,6 @@ static inline void cpm_set_smc_fcr(volatile smc_uart_t * up) | |||
40 | up->smc_tfcr = CPMFCR_GBL | CPMFCR_EB; | 40 | up->smc_tfcr = CPMFCR_GBL | CPMFCR_EB; |
41 | } | 41 | } |
42 | 42 | ||
43 | #define DPRAM_BASE ((unsigned char *)&cpm2_immr->im_dprambase[0]) | 43 | #define DPRAM_BASE ((unsigned char *)cpm_dpram_addr(0)) |
44 | 44 | ||
45 | #endif | 45 | #endif |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index e0ef3328942c..a1c8923b0bf5 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -53,6 +53,11 @@ config FB | |||
53 | (e.g. an accelerated X server) and that are not frame buffer | 53 | (e.g. an accelerated X server) and that are not frame buffer |
54 | device-aware may cause unexpected results. If unsure, say N. | 54 | device-aware may cause unexpected results. If unsure, say N. |
55 | 55 | ||
56 | config FB_DDC | ||
57 | tristate | ||
58 | depends on FB && I2C && I2C_ALGOBIT | ||
59 | default n | ||
60 | |||
56 | config FB_CFB_FILLRECT | 61 | config FB_CFB_FILLRECT |
57 | tristate | 62 | tristate |
58 | depends on FB | 63 | depends on FB |
@@ -696,6 +701,7 @@ config FB_NVIDIA | |||
696 | depends on FB && PCI | 701 | depends on FB && PCI |
697 | select I2C_ALGOBIT if FB_NVIDIA_I2C | 702 | select I2C_ALGOBIT if FB_NVIDIA_I2C |
698 | select I2C if FB_NVIDIA_I2C | 703 | select I2C if FB_NVIDIA_I2C |
704 | select FB_DDC if FB_NVIDIA_I2C | ||
699 | select FB_MODE_HELPERS | 705 | select FB_MODE_HELPERS |
700 | select FB_CFB_FILLRECT | 706 | select FB_CFB_FILLRECT |
701 | select FB_CFB_COPYAREA | 707 | select FB_CFB_COPYAREA |
@@ -734,6 +740,7 @@ config FB_RIVA | |||
734 | depends on FB && PCI | 740 | depends on FB && PCI |
735 | select I2C_ALGOBIT if FB_RIVA_I2C | 741 | select I2C_ALGOBIT if FB_RIVA_I2C |
736 | select I2C if FB_RIVA_I2C | 742 | select I2C if FB_RIVA_I2C |
743 | select FB_DDC if FB_RIVA_I2C | ||
737 | select FB_MODE_HELPERS | 744 | select FB_MODE_HELPERS |
738 | select FB_CFB_FILLRECT | 745 | select FB_CFB_FILLRECT |
739 | select FB_CFB_COPYAREA | 746 | select FB_CFB_COPYAREA |
@@ -822,6 +829,7 @@ config FB_I810_I2C | |||
822 | depends on FB_I810 && FB_I810_GTF | 829 | depends on FB_I810 && FB_I810_GTF |
823 | select I2C | 830 | select I2C |
824 | select I2C_ALGOBIT | 831 | select I2C_ALGOBIT |
832 | select FB_DDC | ||
825 | help | 833 | help |
826 | 834 | ||
827 | config FB_INTEL | 835 | config FB_INTEL |
@@ -1012,6 +1020,7 @@ config FB_RADEON | |||
1012 | depends on FB && PCI | 1020 | depends on FB && PCI |
1013 | select I2C_ALGOBIT if FB_RADEON_I2C | 1021 | select I2C_ALGOBIT if FB_RADEON_I2C |
1014 | select I2C if FB_RADEON_I2C | 1022 | select I2C if FB_RADEON_I2C |
1023 | select FB_DDC if FB_RADEON_I2C | ||
1015 | select FB_MODE_HELPERS | 1024 | select FB_MODE_HELPERS |
1016 | select FB_CFB_FILLRECT | 1025 | select FB_CFB_FILLRECT |
1017 | select FB_CFB_COPYAREA | 1026 | select FB_CFB_COPYAREA |
@@ -1140,6 +1149,7 @@ config FB_SAVAGE | |||
1140 | depends on FB && PCI && EXPERIMENTAL | 1149 | depends on FB && PCI && EXPERIMENTAL |
1141 | select I2C_ALGOBIT if FB_SAVAGE_I2C | 1150 | select I2C_ALGOBIT if FB_SAVAGE_I2C |
1142 | select I2C if FB_SAVAGE_I2C | 1151 | select I2C if FB_SAVAGE_I2C |
1152 | select FB_DDC if FB_SAVAGE_I2C | ||
1143 | select FB_MODE_HELPERS | 1153 | select FB_MODE_HELPERS |
1144 | select FB_CFB_FILLRECT | 1154 | select FB_CFB_FILLRECT |
1145 | select FB_CFB_COPYAREA | 1155 | select FB_CFB_COPYAREA |
@@ -1619,7 +1629,8 @@ config FB_VIRTUAL | |||
1619 | kernel option `video=vfb:'. | 1629 | kernel option `video=vfb:'. |
1620 | 1630 | ||
1621 | To compile this driver as a module, choose M here: the | 1631 | To compile this driver as a module, choose M here: the |
1622 | module will be called vfb. | 1632 | module will be called vfb. In order to load it, you must use |
1633 | the vfb_enable=1 option. | ||
1623 | 1634 | ||
1624 | If unsure, say N. | 1635 | If unsure, say N. |
1625 | if VT | 1636 | if VT |
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 481c6c9695f8..a6980e9a2481 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile | |||
@@ -18,6 +18,7 @@ obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o | |||
18 | obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o | 18 | obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o |
19 | obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o | 19 | obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o |
20 | obj-$(CONFIG_FB_MACMODES) += macmodes.o | 20 | obj-$(CONFIG_FB_MACMODES) += macmodes.o |
21 | obj-$(CONFIG_FB_DDC) += fb_ddc.o | ||
21 | 22 | ||
22 | # Hardware specific drivers go first | 23 | # Hardware specific drivers go first |
23 | obj-$(CONFIG_FB_RETINAZ3) += retz3fb.o | 24 | obj-$(CONFIG_FB_RETINAZ3) += retz3fb.o |
diff --git a/drivers/video/aty/atyfb.h b/drivers/video/aty/atyfb.h index 55fb8b04489b..b04f49fb976a 100644 --- a/drivers/video/aty/atyfb.h +++ b/drivers/video/aty/atyfb.h | |||
@@ -355,5 +355,9 @@ static inline void wait_for_idle(struct atyfb_par *par) | |||
355 | 355 | ||
356 | extern void aty_reset_engine(const struct atyfb_par *par); | 356 | extern void aty_reset_engine(const struct atyfb_par *par); |
357 | extern void aty_init_engine(struct atyfb_par *par, struct fb_info *info); | 357 | extern void aty_init_engine(struct atyfb_par *par, struct fb_info *info); |
358 | extern void aty_st_pll_ct(int offset, u8 val, const struct atyfb_par *par); | ||
359 | extern u8 aty_ld_pll_ct(int offset, const struct atyfb_par *par); | 358 | extern u8 aty_ld_pll_ct(int offset, const struct atyfb_par *par); |
359 | |||
360 | void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area); | ||
361 | void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect); | ||
362 | void atyfb_imageblit(struct fb_info *info, const struct fb_image *image); | ||
363 | |||
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index 19a71f045784..b45c9fd1b330 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c | |||
@@ -240,9 +240,6 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | |||
240 | static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info); | 240 | static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info); |
241 | static int atyfb_blank(int blank, struct fb_info *info); | 241 | static int atyfb_blank(int blank, struct fb_info *info); |
242 | static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg); | 242 | static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg); |
243 | extern void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect); | ||
244 | extern void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area); | ||
245 | extern void atyfb_imageblit(struct fb_info *info, const struct fb_image *image); | ||
246 | #ifdef __sparc__ | 243 | #ifdef __sparc__ |
247 | static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma); | 244 | static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma); |
248 | #endif | 245 | #endif |
@@ -3863,6 +3860,7 @@ static int __devinit atyfb_setup(char *options) | |||
3863 | 3860 | ||
3864 | static int __devinit atyfb_init(void) | 3861 | static int __devinit atyfb_init(void) |
3865 | { | 3862 | { |
3863 | int err1 = 1, err2 = 1; | ||
3866 | #ifndef MODULE | 3864 | #ifndef MODULE |
3867 | char *option = NULL; | 3865 | char *option = NULL; |
3868 | 3866 | ||
@@ -3872,12 +3870,13 @@ static int __devinit atyfb_init(void) | |||
3872 | #endif | 3870 | #endif |
3873 | 3871 | ||
3874 | #ifdef CONFIG_PCI | 3872 | #ifdef CONFIG_PCI |
3875 | pci_register_driver(&atyfb_driver); | 3873 | err1 = pci_register_driver(&atyfb_driver); |
3876 | #endif | 3874 | #endif |
3877 | #ifdef CONFIG_ATARI | 3875 | #ifdef CONFIG_ATARI |
3878 | atyfb_atari_probe(); | 3876 | err2 = atyfb_atari_probe(); |
3879 | #endif | 3877 | #endif |
3880 | return 0; | 3878 | |
3879 | return (err1 && err2) ? -ENODEV : 0; | ||
3881 | } | 3880 | } |
3882 | 3881 | ||
3883 | static void __exit atyfb_exit(void) | 3882 | static void __exit atyfb_exit(void) |
diff --git a/drivers/video/aty/mach64_ct.c b/drivers/video/aty/mach64_ct.c index e7056934c6a8..5080816be653 100644 --- a/drivers/video/aty/mach64_ct.c +++ b/drivers/video/aty/mach64_ct.c | |||
@@ -27,7 +27,7 @@ u8 aty_ld_pll_ct(int offset, const struct atyfb_par *par) | |||
27 | return res; | 27 | return res; |
28 | } | 28 | } |
29 | 29 | ||
30 | void aty_st_pll_ct(int offset, u8 val, const struct atyfb_par *par) | 30 | static void aty_st_pll_ct(int offset, u8 val, const struct atyfb_par *par) |
31 | { | 31 | { |
32 | /* write addr byte */ | 32 | /* write addr byte */ |
33 | aty_st_8(CLOCK_CNTL_ADDR, ((offset << 2) & PLL_ADDR) | PLL_WR_EN, par); | 33 | aty_st_8(CLOCK_CNTL_ADDR, ((offset << 2) & PLL_ADDR) | PLL_WR_EN, par); |
diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c index 9aaca58c074a..676754520099 100644 --- a/drivers/video/aty/radeon_i2c.c +++ b/drivers/video/aty/radeon_i2c.c | |||
@@ -16,8 +16,6 @@ | |||
16 | #include "radeonfb.h" | 16 | #include "radeonfb.h" |
17 | #include "../edid.h" | 17 | #include "../edid.h" |
18 | 18 | ||
19 | #define RADEON_DDC 0x50 | ||
20 | |||
21 | static void radeon_gpio_setscl(void* data, int state) | 19 | static void radeon_gpio_setscl(void* data, int state) |
22 | { | 20 | { |
23 | struct radeon_i2c_chan *chan = data; | 21 | struct radeon_i2c_chan *chan = data; |
@@ -138,108 +136,10 @@ void radeon_delete_i2c_busses(struct radeonfb_info *rinfo) | |||
138 | rinfo->i2c[3].rinfo = NULL; | 136 | rinfo->i2c[3].rinfo = NULL; |
139 | } | 137 | } |
140 | 138 | ||
141 | 139 | int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, | |
142 | static u8 *radeon_do_probe_i2c_edid(struct radeon_i2c_chan *chan) | 140 | u8 **out_edid) |
143 | { | ||
144 | u8 start = 0x0; | ||
145 | struct i2c_msg msgs[] = { | ||
146 | { | ||
147 | .addr = RADEON_DDC, | ||
148 | .len = 1, | ||
149 | .buf = &start, | ||
150 | }, { | ||
151 | .addr = RADEON_DDC, | ||
152 | .flags = I2C_M_RD, | ||
153 | .len = EDID_LENGTH, | ||
154 | }, | ||
155 | }; | ||
156 | u8 *buf; | ||
157 | |||
158 | buf = kmalloc(EDID_LENGTH, GFP_KERNEL); | ||
159 | if (!buf) { | ||
160 | dev_warn(&chan->rinfo->pdev->dev, "Out of memory!\n"); | ||
161 | return NULL; | ||
162 | } | ||
163 | msgs[1].buf = buf; | ||
164 | |||
165 | if (i2c_transfer(&chan->adapter, msgs, 2) == 2) | ||
166 | return buf; | ||
167 | dev_dbg(&chan->rinfo->pdev->dev, "Unable to read EDID block.\n"); | ||
168 | kfree(buf); | ||
169 | return NULL; | ||
170 | } | ||
171 | |||
172 | |||
173 | int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, u8 **out_edid) | ||
174 | { | 141 | { |
175 | u32 reg = rinfo->i2c[conn-1].ddc_reg; | 142 | u8 *edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter); |
176 | u8 *edid = NULL; | ||
177 | int i, j; | ||
178 | |||
179 | OUTREG(reg, INREG(reg) & | ||
180 | ~(VGA_DDC_DATA_OUTPUT | VGA_DDC_CLK_OUTPUT)); | ||
181 | |||
182 | OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN)); | ||
183 | (void)INREG(reg); | ||
184 | |||
185 | for (i = 0; i < 3; i++) { | ||
186 | /* For some old monitors we need the | ||
187 | * following process to initialize/stop DDC | ||
188 | */ | ||
189 | OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN)); | ||
190 | (void)INREG(reg); | ||
191 | msleep(13); | ||
192 | |||
193 | OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN)); | ||
194 | (void)INREG(reg); | ||
195 | for (j = 0; j < 5; j++) { | ||
196 | msleep(10); | ||
197 | if (INREG(reg) & VGA_DDC_CLK_INPUT) | ||
198 | break; | ||
199 | } | ||
200 | if (j == 5) | ||
201 | continue; | ||
202 | |||
203 | OUTREG(reg, INREG(reg) | VGA_DDC_DATA_OUT_EN); | ||
204 | (void)INREG(reg); | ||
205 | msleep(15); | ||
206 | OUTREG(reg, INREG(reg) | VGA_DDC_CLK_OUT_EN); | ||
207 | (void)INREG(reg); | ||
208 | msleep(15); | ||
209 | OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN)); | ||
210 | (void)INREG(reg); | ||
211 | msleep(15); | ||
212 | |||
213 | /* Do the real work */ | ||
214 | edid = radeon_do_probe_i2c_edid(&rinfo->i2c[conn-1]); | ||
215 | |||
216 | OUTREG(reg, INREG(reg) | | ||
217 | (VGA_DDC_DATA_OUT_EN | VGA_DDC_CLK_OUT_EN)); | ||
218 | (void)INREG(reg); | ||
219 | msleep(15); | ||
220 | |||
221 | OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN)); | ||
222 | (void)INREG(reg); | ||
223 | for (j = 0; j < 10; j++) { | ||
224 | msleep(10); | ||
225 | if (INREG(reg) & VGA_DDC_CLK_INPUT) | ||
226 | break; | ||
227 | } | ||
228 | |||
229 | OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN)); | ||
230 | (void)INREG(reg); | ||
231 | msleep(15); | ||
232 | OUTREG(reg, INREG(reg) | | ||
233 | (VGA_DDC_DATA_OUT_EN | VGA_DDC_CLK_OUT_EN)); | ||
234 | (void)INREG(reg); | ||
235 | if (edid) | ||
236 | break; | ||
237 | } | ||
238 | /* Release the DDC lines when done or the Apple Cinema HD display | ||
239 | * will switch off | ||
240 | */ | ||
241 | OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN | VGA_DDC_DATA_OUT_EN)); | ||
242 | (void)INREG(reg); | ||
243 | 143 | ||
244 | if (out_edid) | 144 | if (out_edid) |
245 | *out_edid = edid; | 145 | *out_edid = edid; |
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c index 365de5dcc888..9a2b0d69b0ae 100644 --- a/drivers/video/aty/radeon_pm.c +++ b/drivers/video/aty/radeon_pm.c | |||
@@ -86,6 +86,9 @@ static struct radeon_device_id radeon_workaround_list[] = { | |||
86 | BUGFIX("Samsung P35", | 86 | BUGFIX("Samsung P35", |
87 | PCI_VENDOR_ID_SAMSUNG, 0xc00c, | 87 | PCI_VENDOR_ID_SAMSUNG, 0xc00c, |
88 | radeon_pm_off, radeon_reinitialize_M10), | 88 | radeon_pm_off, radeon_reinitialize_M10), |
89 | BUGFIX("Acer Aspire 2010", | ||
90 | PCI_VENDOR_ID_AI, 0x0061, | ||
91 | radeon_pm_off, radeon_reinitialize_M10), | ||
89 | { .ident = NULL } | 92 | { .ident = NULL } |
90 | }; | 93 | }; |
91 | 94 | ||
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c index f25d5d648333..ef5c16f7f5a6 100644 --- a/drivers/video/au1100fb.c +++ b/drivers/video/au1100fb.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * <c.pellegrin@exadron.com> | 8 | * <c.pellegrin@exadron.com> |
9 | * | 9 | * |
10 | * PM support added by Rodolfo Giometti <giometti@linux.it> | 10 | * PM support added by Rodolfo Giometti <giometti@linux.it> |
11 | * Cursor enable/disable by Rodolfo Giometti <giometti@linux.it> | ||
11 | * | 12 | * |
12 | * Copyright 2002 MontaVista Software | 13 | * Copyright 2002 MontaVista Software |
13 | * Author: MontaVista Software, Inc. | 14 | * Author: MontaVista Software, Inc. |
@@ -110,6 +111,10 @@ static struct fb_var_screeninfo au1100fb_var __initdata = { | |||
110 | 111 | ||
111 | static struct au1100fb_drv_info drv_info; | 112 | static struct au1100fb_drv_info drv_info; |
112 | 113 | ||
114 | static int nocursor = 0; | ||
115 | module_param(nocursor, int, 0644); | ||
116 | MODULE_PARM_DESC(nocursor, "cursor enable/disable"); | ||
117 | |||
113 | /* | 118 | /* |
114 | * Set hardware with var settings. This will enable the controller with a specific | 119 | * Set hardware with var settings. This will enable the controller with a specific |
115 | * mode, normally validated with the fb_check_var method | 120 | * mode, normally validated with the fb_check_var method |
@@ -422,6 +427,17 @@ int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma) | |||
422 | return 0; | 427 | return 0; |
423 | } | 428 | } |
424 | 429 | ||
430 | /* fb_cursor | ||
431 | * Used to disable cursor drawing... | ||
432 | */ | ||
433 | int au1100fb_fb_cursor(struct fb_info *info, struct fb_cursor *cursor) | ||
434 | { | ||
435 | if (nocursor) | ||
436 | return 0; | ||
437 | else | ||
438 | return -EINVAL; /* just to force soft_cursor() call */ | ||
439 | } | ||
440 | |||
425 | static struct fb_ops au1100fb_ops = | 441 | static struct fb_ops au1100fb_ops = |
426 | { | 442 | { |
427 | .owner = THIS_MODULE, | 443 | .owner = THIS_MODULE, |
@@ -433,6 +449,7 @@ static struct fb_ops au1100fb_ops = | |||
433 | .fb_imageblit = cfb_imageblit, | 449 | .fb_imageblit = cfb_imageblit, |
434 | .fb_rotate = au1100fb_fb_rotate, | 450 | .fb_rotate = au1100fb_fb_rotate, |
435 | .fb_mmap = au1100fb_fb_mmap, | 451 | .fb_mmap = au1100fb_fb_mmap, |
452 | .fb_cursor = au1100fb_fb_cursor, | ||
436 | }; | 453 | }; |
437 | 454 | ||
438 | 455 | ||
@@ -677,7 +694,7 @@ int au1100fb_setup(char *options) | |||
677 | if (options) { | 694 | if (options) { |
678 | while ((this_opt = strsep(&options,",")) != NULL) { | 695 | while ((this_opt = strsep(&options,",")) != NULL) { |
679 | /* Panel option */ | 696 | /* Panel option */ |
680 | if (!strncmp(this_opt, "panel:", 6)) { | 697 | if (!strncmp(this_opt, "panel:", 6)) { |
681 | int i; | 698 | int i; |
682 | this_opt += 6; | 699 | this_opt += 6; |
683 | for (i = 0; i < num_panels; i++) { | 700 | for (i = 0; i < num_panels; i++) { |
@@ -685,13 +702,18 @@ int au1100fb_setup(char *options) | |||
685 | known_lcd_panels[i].name, | 702 | known_lcd_panels[i].name, |
686 | strlen(this_opt))) { | 703 | strlen(this_opt))) { |
687 | panel_idx = i; | 704 | panel_idx = i; |
688 | break; | 705 | break; |
706 | } | ||
689 | } | 707 | } |
690 | } | ||
691 | if (i >= num_panels) { | 708 | if (i >= num_panels) { |
692 | print_warn("Panel %s not supported!", this_opt); | 709 | print_warn("Panel %s not supported!", this_opt); |
693 | } | 710 | } |
694 | } | 711 | } |
712 | if (!strncmp(this_opt, "nocursor", 8)) { | ||
713 | this_opt += 8; | ||
714 | nocursor = 1; | ||
715 | print_info("Cursor disabled"); | ||
716 | } | ||
695 | /* Mode option (only option that start with digit) */ | 717 | /* Mode option (only option that start with digit) */ |
696 | else if (isdigit(this_opt[0])) { | 718 | else if (isdigit(this_opt[0])) { |
697 | mode = kmalloc(strlen(this_opt) + 1, GFP_KERNEL); | 719 | mode = kmalloc(strlen(this_opt) + 1, GFP_KERNEL); |
@@ -700,7 +722,7 @@ int au1100fb_setup(char *options) | |||
700 | /* Unsupported option */ | 722 | /* Unsupported option */ |
701 | else { | 723 | else { |
702 | print_warn("Unsupported option \"%s\"", this_opt); | 724 | print_warn("Unsupported option \"%s\"", this_opt); |
703 | } | 725 | } |
704 | } | 726 | } |
705 | } | 727 | } |
706 | 728 | ||
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 1b4f75d1f8a9..8c041daa3a15 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -133,6 +133,7 @@ static int info_idx = -1; | |||
133 | 133 | ||
134 | /* console rotation */ | 134 | /* console rotation */ |
135 | static int rotate; | 135 | static int rotate; |
136 | static int fbcon_has_sysfs; | ||
136 | 137 | ||
137 | static const struct consw fb_con; | 138 | static const struct consw fb_con; |
138 | 139 | ||
@@ -396,9 +397,8 @@ static void fb_flashcursor(void *private) | |||
396 | vc = vc_cons[ops->currcon].d; | 397 | vc = vc_cons[ops->currcon].d; |
397 | 398 | ||
398 | if (!vc || !CON_IS_VISIBLE(vc) || | 399 | if (!vc || !CON_IS_VISIBLE(vc) || |
399 | fbcon_is_inactive(vc, info) || | ||
400 | registered_fb[con2fb_map[vc->vc_num]] != info || | 400 | registered_fb[con2fb_map[vc->vc_num]] != info || |
401 | vc_cons[ops->currcon].d->vc_deccm != 1) { | 401 | vc->vc_deccm != 1) { |
402 | release_console_sem(); | 402 | release_console_sem(); |
403 | return; | 403 | return; |
404 | } | 404 | } |
@@ -2166,7 +2166,12 @@ static int fbcon_switch(struct vc_data *vc) | |||
2166 | fbcon_del_cursor_timer(old_info); | 2166 | fbcon_del_cursor_timer(old_info); |
2167 | } | 2167 | } |
2168 | 2168 | ||
2169 | fbcon_add_cursor_timer(info); | 2169 | if (fbcon_is_inactive(vc, info) || |
2170 | ops->blank_state != FB_BLANK_UNBLANK) | ||
2171 | fbcon_del_cursor_timer(info); | ||
2172 | else | ||
2173 | fbcon_add_cursor_timer(info); | ||
2174 | |||
2170 | set_blitting_type(vc, info); | 2175 | set_blitting_type(vc, info); |
2171 | ops->cursor_reset = 1; | 2176 | ops->cursor_reset = 1; |
2172 | 2177 | ||
@@ -2276,10 +2281,11 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) | |||
2276 | update_screen(vc); | 2281 | update_screen(vc); |
2277 | } | 2282 | } |
2278 | 2283 | ||
2279 | if (!blank) | 2284 | if (fbcon_is_inactive(vc, info) || |
2280 | fbcon_add_cursor_timer(info); | 2285 | ops->blank_state != FB_BLANK_UNBLANK) |
2281 | else | ||
2282 | fbcon_del_cursor_timer(info); | 2286 | fbcon_del_cursor_timer(info); |
2287 | else | ||
2288 | fbcon_add_cursor_timer(info); | ||
2283 | 2289 | ||
2284 | return 0; | 2290 | return 0; |
2285 | } | 2291 | } |
@@ -3161,11 +3167,26 @@ static struct class_device_attribute class_device_attrs[] = { | |||
3161 | 3167 | ||
3162 | static int fbcon_init_class_device(void) | 3168 | static int fbcon_init_class_device(void) |
3163 | { | 3169 | { |
3164 | int i; | 3170 | int i, error = 0; |
3171 | |||
3172 | fbcon_has_sysfs = 1; | ||
3173 | |||
3174 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) { | ||
3175 | error = class_device_create_file(fbcon_class_device, | ||
3176 | &class_device_attrs[i]); | ||
3177 | |||
3178 | if (error) | ||
3179 | break; | ||
3180 | } | ||
3181 | |||
3182 | if (error) { | ||
3183 | while (--i >= 0) | ||
3184 | class_device_remove_file(fbcon_class_device, | ||
3185 | &class_device_attrs[i]); | ||
3186 | |||
3187 | fbcon_has_sysfs = 0; | ||
3188 | } | ||
3165 | 3189 | ||
3166 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) | ||
3167 | class_device_create_file(fbcon_class_device, | ||
3168 | &class_device_attrs[i]); | ||
3169 | return 0; | 3190 | return 0; |
3170 | } | 3191 | } |
3171 | 3192 | ||
@@ -3225,7 +3246,10 @@ static void fbcon_exit(void) | |||
3225 | module_put(info->fbops->owner); | 3246 | module_put(info->fbops->owner); |
3226 | 3247 | ||
3227 | if (info->fbcon_par) { | 3248 | if (info->fbcon_par) { |
3249 | struct fbcon_ops *ops = info->fbcon_par; | ||
3250 | |||
3228 | fbcon_del_cursor_timer(info); | 3251 | fbcon_del_cursor_timer(info); |
3252 | kfree(ops->cursor_src); | ||
3229 | kfree(info->fbcon_par); | 3253 | kfree(info->fbcon_par); |
3230 | info->fbcon_par = NULL; | 3254 | info->fbcon_par = NULL; |
3231 | } | 3255 | } |
@@ -3271,9 +3295,13 @@ static void __exit fbcon_deinit_class_device(void) | |||
3271 | { | 3295 | { |
3272 | int i; | 3296 | int i; |
3273 | 3297 | ||
3274 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) | 3298 | if (fbcon_has_sysfs) { |
3275 | class_device_remove_file(fbcon_class_device, | 3299 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) |
3276 | &class_device_attrs[i]); | 3300 | class_device_remove_file(fbcon_class_device, |
3301 | &class_device_attrs[i]); | ||
3302 | |||
3303 | fbcon_has_sysfs = 0; | ||
3304 | } | ||
3277 | } | 3305 | } |
3278 | 3306 | ||
3279 | static void __exit fb_console_exit(void) | 3307 | static void __exit fb_console_exit(void) |
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h index f244ad066d68..b9386d168c04 100644 --- a/drivers/video/console/fbcon.h +++ b/drivers/video/console/fbcon.h | |||
@@ -80,6 +80,8 @@ struct fbcon_ops { | |||
80 | char *cursor_data; | 80 | char *cursor_data; |
81 | u8 *fontbuffer; | 81 | u8 *fontbuffer; |
82 | u8 *fontdata; | 82 | u8 *fontdata; |
83 | u8 *cursor_src; | ||
84 | u32 cursor_size; | ||
83 | u32 fd_size; | 85 | u32 fd_size; |
84 | }; | 86 | }; |
85 | /* | 87 | /* |
diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c index 4481c80b8b2a..825e6d6972a7 100644 --- a/drivers/video/console/fbcon_ccw.c +++ b/drivers/video/console/fbcon_ccw.c | |||
@@ -391,7 +391,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode, | |||
391 | ops->cursor_reset = 0; | 391 | ops->cursor_reset = 0; |
392 | } | 392 | } |
393 | 393 | ||
394 | int ccw_update_start(struct fb_info *info) | 394 | static int ccw_update_start(struct fb_info *info) |
395 | { | 395 | { |
396 | struct fbcon_ops *ops = info->fbcon_par; | 396 | struct fbcon_ops *ops = info->fbcon_par; |
397 | u32 yoffset; | 397 | u32 yoffset; |
diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c index 7f92c06afea7..c637e6318803 100644 --- a/drivers/video/console/fbcon_cw.c +++ b/drivers/video/console/fbcon_cw.c | |||
@@ -375,7 +375,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode, | |||
375 | ops->cursor_reset = 0; | 375 | ops->cursor_reset = 0; |
376 | } | 376 | } |
377 | 377 | ||
378 | int cw_update_start(struct fb_info *info) | 378 | static int cw_update_start(struct fb_info *info) |
379 | { | 379 | { |
380 | struct fbcon_ops *ops = info->fbcon_par; | 380 | struct fbcon_ops *ops = info->fbcon_par; |
381 | u32 vxres = GETVXRES(ops->p->scrollmode, info); | 381 | u32 vxres = GETVXRES(ops->p->scrollmode, info); |
diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c index ab91005e64dc..1473506df5d0 100644 --- a/drivers/video/console/fbcon_ud.c +++ b/drivers/video/console/fbcon_ud.c | |||
@@ -415,7 +415,7 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode, | |||
415 | ops->cursor_reset = 0; | 415 | ops->cursor_reset = 0; |
416 | } | 416 | } |
417 | 417 | ||
418 | int ud_update_start(struct fb_info *info) | 418 | static int ud_update_start(struct fb_info *info) |
419 | { | 419 | { |
420 | struct fbcon_ops *ops = info->fbcon_par; | 420 | struct fbcon_ops *ops = info->fbcon_par; |
421 | int xoffset, yoffset; | 421 | int xoffset, yoffset; |
diff --git a/drivers/video/console/softcursor.c b/drivers/video/console/softcursor.c index 557c563e4aed..7d07d8383569 100644 --- a/drivers/video/console/softcursor.c +++ b/drivers/video/console/softcursor.c | |||
@@ -20,11 +20,12 @@ | |||
20 | 20 | ||
21 | int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) | 21 | int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) |
22 | { | 22 | { |
23 | struct fbcon_ops *ops = info->fbcon_par; | ||
23 | unsigned int scan_align = info->pixmap.scan_align - 1; | 24 | unsigned int scan_align = info->pixmap.scan_align - 1; |
24 | unsigned int buf_align = info->pixmap.buf_align - 1; | 25 | unsigned int buf_align = info->pixmap.buf_align - 1; |
25 | unsigned int i, size, dsize, s_pitch, d_pitch; | 26 | unsigned int i, size, dsize, s_pitch, d_pitch; |
26 | struct fb_image *image; | 27 | struct fb_image *image; |
27 | u8 *dst, *src; | 28 | u8 *dst; |
28 | 29 | ||
29 | if (info->state != FBINFO_STATE_RUNNING) | 30 | if (info->state != FBINFO_STATE_RUNNING) |
30 | return 0; | 31 | return 0; |
@@ -32,11 +33,19 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) | |||
32 | s_pitch = (cursor->image.width + 7) >> 3; | 33 | s_pitch = (cursor->image.width + 7) >> 3; |
33 | dsize = s_pitch * cursor->image.height; | 34 | dsize = s_pitch * cursor->image.height; |
34 | 35 | ||
35 | src = kmalloc(dsize + sizeof(struct fb_image), GFP_ATOMIC); | 36 | if (dsize + sizeof(struct fb_image) != ops->cursor_size) { |
36 | if (!src) | 37 | if (ops->cursor_src != NULL) |
37 | return -ENOMEM; | 38 | kfree(ops->cursor_src); |
39 | ops->cursor_size = dsize + sizeof(struct fb_image); | ||
38 | 40 | ||
39 | image = (struct fb_image *) (src + dsize); | 41 | ops->cursor_src = kmalloc(ops->cursor_size, GFP_ATOMIC); |
42 | if (!ops->cursor_src) { | ||
43 | ops->cursor_size = 0; | ||
44 | return -ENOMEM; | ||
45 | } | ||
46 | } | ||
47 | |||
48 | image = (struct fb_image *) (ops->cursor_src + dsize); | ||
40 | *image = cursor->image; | 49 | *image = cursor->image; |
41 | d_pitch = (s_pitch + scan_align) & ~scan_align; | 50 | d_pitch = (s_pitch + scan_align) & ~scan_align; |
42 | 51 | ||
@@ -48,21 +57,23 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) | |||
48 | switch (cursor->rop) { | 57 | switch (cursor->rop) { |
49 | case ROP_XOR: | 58 | case ROP_XOR: |
50 | for (i = 0; i < dsize; i++) | 59 | for (i = 0; i < dsize; i++) |
51 | src[i] = image->data[i] ^ cursor->mask[i]; | 60 | ops->cursor_src[i] = image->data[i] ^ |
61 | cursor->mask[i]; | ||
52 | break; | 62 | break; |
53 | case ROP_COPY: | 63 | case ROP_COPY: |
54 | default: | 64 | default: |
55 | for (i = 0; i < dsize; i++) | 65 | for (i = 0; i < dsize; i++) |
56 | src[i] = image->data[i] & cursor->mask[i]; | 66 | ops->cursor_src[i] = image->data[i] & |
67 | cursor->mask[i]; | ||
57 | break; | 68 | break; |
58 | } | 69 | } |
59 | } else | 70 | } else |
60 | memcpy(src, image->data, dsize); | 71 | memcpy(ops->cursor_src, image->data, dsize); |
61 | 72 | ||
62 | fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, image->height); | 73 | fb_pad_aligned_buffer(dst, d_pitch, ops->cursor_src, s_pitch, |
74 | image->height); | ||
63 | image->data = dst; | 75 | image->data = dst; |
64 | info->fbops->fb_imageblit(info, image); | 76 | info->fbops->fb_imageblit(info, image); |
65 | kfree(src); | ||
66 | return 0; | 77 | return 0; |
67 | } | 78 | } |
68 | 79 | ||
diff --git a/drivers/video/fb_ddc.c b/drivers/video/fb_ddc.c new file mode 100644 index 000000000000..3aa6ebf68f17 --- /dev/null +++ b/drivers/video/fb_ddc.c | |||
@@ -0,0 +1,116 @@ | |||
1 | /* | ||
2 | * driver/vide/fb_ddc.c - DDC/EDID read support. | ||
3 | * | ||
4 | * Copyright (C) 2006 Dennis Munsie <dmunsie@cecropia.com> | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file COPYING in the main directory of this archive | ||
8 | * for more details. | ||
9 | */ | ||
10 | |||
11 | #include <linux/delay.h> | ||
12 | #include <linux/device.h> | ||
13 | #include <linux/fb.h> | ||
14 | #include <linux/i2c-algo-bit.h> | ||
15 | |||
16 | #include "edid.h" | ||
17 | |||
18 | #define DDC_ADDR 0x50 | ||
19 | |||
20 | static unsigned char *fb_do_probe_ddc_edid(struct i2c_adapter *adapter) | ||
21 | { | ||
22 | unsigned char start = 0x0; | ||
23 | struct i2c_msg msgs[] = { | ||
24 | { | ||
25 | .addr = DDC_ADDR, | ||
26 | .len = 1, | ||
27 | .buf = &start, | ||
28 | }, { | ||
29 | .addr = DDC_ADDR, | ||
30 | .flags = I2C_M_RD, | ||
31 | .len = EDID_LENGTH, | ||
32 | } | ||
33 | }; | ||
34 | unsigned char *buf; | ||
35 | |||
36 | buf = kmalloc(EDID_LENGTH, GFP_KERNEL); | ||
37 | if (!buf) { | ||
38 | dev_warn(&adapter->dev, "unable to allocate memory for EDID " | ||
39 | "block.\n"); | ||
40 | return NULL; | ||
41 | } | ||
42 | msgs[1].buf = buf; | ||
43 | |||
44 | if (i2c_transfer(adapter, msgs, 2) == 2) | ||
45 | return buf; | ||
46 | |||
47 | dev_warn(&adapter->dev, "unable to read EDID block.\n"); | ||
48 | kfree(buf); | ||
49 | return NULL; | ||
50 | } | ||
51 | |||
52 | unsigned char *fb_ddc_read(struct i2c_adapter *adapter) | ||
53 | { | ||
54 | struct i2c_algo_bit_data *algo_data = adapter->algo_data; | ||
55 | unsigned char *edid = NULL; | ||
56 | int i, j; | ||
57 | |||
58 | algo_data->setscl(algo_data->data, 1); | ||
59 | algo_data->setscl(algo_data->data, 0); | ||
60 | |||
61 | for (i = 0; i < 3; i++) { | ||
62 | /* For some old monitors we need the | ||
63 | * following process to initialize/stop DDC | ||
64 | */ | ||
65 | algo_data->setsda(algo_data->data, 0); | ||
66 | msleep(13); | ||
67 | |||
68 | algo_data->setscl(algo_data->data, 1); | ||
69 | for (j = 0; j < 5; j++) { | ||
70 | msleep(10); | ||
71 | if (algo_data->getscl(algo_data->data)) | ||
72 | break; | ||
73 | } | ||
74 | if (j == 5) | ||
75 | continue; | ||
76 | |||
77 | algo_data->setsda(algo_data->data, 0); | ||
78 | msleep(15); | ||
79 | algo_data->setscl(algo_data->data, 0); | ||
80 | msleep(15); | ||
81 | algo_data->setsda(algo_data->data, 1); | ||
82 | msleep(15); | ||
83 | |||
84 | /* Do the real work */ | ||
85 | edid = fb_do_probe_ddc_edid(adapter); | ||
86 | algo_data->setsda(algo_data->data, 0); | ||
87 | algo_data->setscl(algo_data->data, 0); | ||
88 | msleep(15); | ||
89 | |||
90 | algo_data->setscl(algo_data->data, 1); | ||
91 | for (j = 0; j < 10; j++) { | ||
92 | msleep(10); | ||
93 | if (algo_data->getscl(algo_data->data)) | ||
94 | break; | ||
95 | } | ||
96 | |||
97 | algo_data->setsda(algo_data->data, 1); | ||
98 | msleep(15); | ||
99 | algo_data->setscl(algo_data->data, 0); | ||
100 | if (edid) | ||
101 | break; | ||
102 | } | ||
103 | /* Release the DDC lines when done or the Apple Cinema HD display | ||
104 | * will switch off | ||
105 | */ | ||
106 | algo_data->setsda(algo_data->data, 0); | ||
107 | algo_data->setscl(algo_data->data, 0); | ||
108 | |||
109 | return edid; | ||
110 | } | ||
111 | |||
112 | EXPORT_SYMBOL_GPL(fb_ddc_read); | ||
113 | |||
114 | MODULE_AUTHOR("Dennis Munsie <dmunsie@cecropia.com>"); | ||
115 | MODULE_DESCRIPTION("DDC/EDID reading support"); | ||
116 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 17961e3ecaa0..93ffcdd95f50 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -554,7 +554,8 @@ static int fbmem_read_proc(char *buf, char **start, off_t offset, | |||
554 | int clen; | 554 | int clen; |
555 | 555 | ||
556 | clen = 0; | 556 | clen = 0; |
557 | for (fi = registered_fb; fi < ®istered_fb[FB_MAX] && len < 4000; fi++) | 557 | for (fi = registered_fb; fi < ®istered_fb[FB_MAX] && clen < 4000; |
558 | fi++) | ||
558 | if (*fi) | 559 | if (*fi) |
559 | clen += sprintf(buf + clen, "%d %s\n", | 560 | clen += sprintf(buf + clen, "%d %s\n", |
560 | (*fi)->node, | 561 | (*fi)->node, |
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c index c151dcf68786..d3a50417ed9a 100644 --- a/drivers/video/fbsysfs.c +++ b/drivers/video/fbsysfs.c | |||
@@ -20,6 +20,8 @@ | |||
20 | #include <linux/console.h> | 20 | #include <linux/console.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | 22 | ||
23 | #define FB_SYSFS_FLAG_ATTR 1 | ||
24 | |||
23 | /** | 25 | /** |
24 | * framebuffer_alloc - creates a new frame buffer info structure | 26 | * framebuffer_alloc - creates a new frame buffer info structure |
25 | * | 27 | * |
@@ -483,12 +485,27 @@ static struct class_device_attribute class_device_attrs[] = { | |||
483 | 485 | ||
484 | int fb_init_class_device(struct fb_info *fb_info) | 486 | int fb_init_class_device(struct fb_info *fb_info) |
485 | { | 487 | { |
486 | unsigned int i; | 488 | int i, error = 0; |
489 | |||
487 | class_set_devdata(fb_info->class_device, fb_info); | 490 | class_set_devdata(fb_info->class_device, fb_info); |
488 | 491 | ||
489 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) | 492 | fb_info->class_flag |= FB_SYSFS_FLAG_ATTR; |
490 | class_device_create_file(fb_info->class_device, | 493 | |
491 | &class_device_attrs[i]); | 494 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) { |
495 | error = class_device_create_file(fb_info->class_device, | ||
496 | &class_device_attrs[i]); | ||
497 | |||
498 | if (error) | ||
499 | break; | ||
500 | } | ||
501 | |||
502 | if (error) { | ||
503 | while (--i >= 0) | ||
504 | class_device_remove_file(fb_info->class_device, | ||
505 | &class_device_attrs[i]); | ||
506 | fb_info->class_flag &= ~FB_SYSFS_FLAG_ATTR; | ||
507 | } | ||
508 | |||
492 | return 0; | 509 | return 0; |
493 | } | 510 | } |
494 | 511 | ||
@@ -496,9 +513,13 @@ void fb_cleanup_class_device(struct fb_info *fb_info) | |||
496 | { | 513 | { |
497 | unsigned int i; | 514 | unsigned int i; |
498 | 515 | ||
499 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) | 516 | if (fb_info->class_flag & FB_SYSFS_FLAG_ATTR) { |
500 | class_device_remove_file(fb_info->class_device, | 517 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) |
501 | &class_device_attrs[i]); | 518 | class_device_remove_file(fb_info->class_device, |
519 | &class_device_attrs[i]); | ||
520 | |||
521 | fb_info->class_flag &= ~FB_SYSFS_FLAG_ATTR; | ||
522 | } | ||
502 | } | 523 | } |
503 | 524 | ||
504 | #ifdef CONFIG_FB_BACKLIGHT | 525 | #ifdef CONFIG_FB_BACKLIGHT |
diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/i810/i810-i2c.c index 7d06b38e80a0..b38d805db313 100644 --- a/drivers/video/i810/i810-i2c.c +++ b/drivers/video/i810/i810-i2c.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include "i810_main.h" | 19 | #include "i810_main.h" |
20 | #include "../edid.h" | 20 | #include "../edid.h" |
21 | 21 | ||
22 | #define I810_DDC 0x50 | ||
23 | /* bit locations in the registers */ | 22 | /* bit locations in the registers */ |
24 | #define SCL_DIR_MASK 0x0001 | 23 | #define SCL_DIR_MASK 0x0001 |
25 | #define SCL_DIR 0x0002 | 24 | #define SCL_DIR 0x0002 |
@@ -150,53 +149,14 @@ void i810_delete_i2c_busses(struct i810fb_par *par) | |||
150 | par->chan[2].par = NULL; | 149 | par->chan[2].par = NULL; |
151 | } | 150 | } |
152 | 151 | ||
153 | static u8 *i810_do_probe_i2c_edid(struct i810fb_i2c_chan *chan) | ||
154 | { | ||
155 | u8 start = 0x0; | ||
156 | struct i2c_msg msgs[] = { | ||
157 | { | ||
158 | .addr = I810_DDC, | ||
159 | .len = 1, | ||
160 | .buf = &start, | ||
161 | }, { | ||
162 | .addr = I810_DDC, | ||
163 | .flags = I2C_M_RD, | ||
164 | .len = EDID_LENGTH, | ||
165 | }, | ||
166 | }; | ||
167 | u8 *buf; | ||
168 | |||
169 | buf = kmalloc(EDID_LENGTH, GFP_KERNEL); | ||
170 | if (!buf) { | ||
171 | DPRINTK("i810-i2c: Failed to allocate memory\n"); | ||
172 | return NULL; | ||
173 | } | ||
174 | msgs[1].buf = buf; | ||
175 | |||
176 | if (i2c_transfer(&chan->adapter, msgs, 2) == 2) { | ||
177 | DPRINTK("i810-i2c: I2C Transfer successful\n"); | ||
178 | return buf; | ||
179 | } | ||
180 | |||
181 | DPRINTK("i810-i2c: Unable to read EDID block.\n"); | ||
182 | kfree(buf); | ||
183 | return NULL; | ||
184 | } | ||
185 | |||
186 | int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid, int conn) | 152 | int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid, int conn) |
187 | { | 153 | { |
188 | struct i810fb_par *par = info->par; | 154 | struct i810fb_par *par = info->par; |
189 | u8 *edid = NULL; | 155 | u8 *edid = NULL; |
190 | int i; | ||
191 | 156 | ||
192 | DPRINTK("i810-i2c: Probe DDC%i Bus\n", conn+1); | 157 | DPRINTK("i810-i2c: Probe DDC%i Bus\n", conn+1); |
193 | if (conn < par->ddc_num) { | 158 | if (conn < par->ddc_num) { |
194 | for (i = 0; i < 3; i++) { | 159 | edid = fb_ddc_read(&par->chan[conn].adapter); |
195 | /* Do the real work */ | ||
196 | edid = i810_do_probe_i2c_edid(&par->chan[conn]); | ||
197 | if (edid) | ||
198 | break; | ||
199 | } | ||
200 | } else { | 160 | } else { |
201 | const u8 *e = fb_firmware_edid(info->device); | 161 | const u8 *e = fb_firmware_edid(info->device); |
202 | 162 | ||
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c index d42edaccb84c..b55a12d95eb2 100644 --- a/drivers/video/i810/i810_main.c +++ b/drivers/video/i810/i810_main.c | |||
@@ -1602,7 +1602,10 @@ static int i810fb_resume(struct pci_dev *dev) | |||
1602 | acquire_console_sem(); | 1602 | acquire_console_sem(); |
1603 | pci_set_power_state(dev, PCI_D0); | 1603 | pci_set_power_state(dev, PCI_D0); |
1604 | pci_restore_state(dev); | 1604 | pci_restore_state(dev); |
1605 | pci_enable_device(dev); | 1605 | |
1606 | if (pci_enable_device(dev)) | ||
1607 | goto fail; | ||
1608 | |||
1606 | pci_set_master(dev); | 1609 | pci_set_master(dev); |
1607 | agp_bind_memory(par->i810_gtt.i810_fb_memory, | 1610 | agp_bind_memory(par->i810_gtt.i810_fb_memory, |
1608 | par->fb.offset); | 1611 | par->fb.offset); |
@@ -1611,6 +1614,7 @@ static int i810fb_resume(struct pci_dev *dev) | |||
1611 | i810fb_set_par(info); | 1614 | i810fb_set_par(info); |
1612 | fb_set_suspend (info, 0); | 1615 | fb_set_suspend (info, 0); |
1613 | info->fbops->fb_blank(VESA_NO_BLANKING, info); | 1616 | info->fbops->fb_blank(VESA_NO_BLANKING, info); |
1617 | fail: | ||
1614 | release_console_sem(); | 1618 | release_console_sem(); |
1615 | return 0; | 1619 | return 0; |
1616 | } | 1620 | } |
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c index 4a57dabb77d4..7acf01c181ee 100644 --- a/drivers/video/matrox/matroxfb_base.c +++ b/drivers/video/matrox/matroxfb_base.c | |||
@@ -2277,10 +2277,13 @@ static void __init matroxfb_init_params(void) { | |||
2277 | } | 2277 | } |
2278 | } | 2278 | } |
2279 | 2279 | ||
2280 | static void __init matrox_init(void) { | 2280 | static int __init matrox_init(void) { |
2281 | int err; | ||
2282 | |||
2281 | matroxfb_init_params(); | 2283 | matroxfb_init_params(); |
2282 | pci_register_driver(&matroxfb_driver); | 2284 | err = pci_register_driver(&matroxfb_driver); |
2283 | dev = -1; /* accept all new devices... */ | 2285 | dev = -1; /* accept all new devices... */ |
2286 | return err; | ||
2284 | } | 2287 | } |
2285 | 2288 | ||
2286 | /* **************************** exit-time only **************************** */ | 2289 | /* **************************** exit-time only **************************** */ |
@@ -2437,6 +2440,7 @@ static int __initdata initialized = 0; | |||
2437 | static int __init matroxfb_init(void) | 2440 | static int __init matroxfb_init(void) |
2438 | { | 2441 | { |
2439 | char *option = NULL; | 2442 | char *option = NULL; |
2443 | int err = 0; | ||
2440 | 2444 | ||
2441 | DBG(__FUNCTION__) | 2445 | DBG(__FUNCTION__) |
2442 | 2446 | ||
@@ -2448,11 +2452,11 @@ static int __init matroxfb_init(void) | |||
2448 | return -ENXIO; | 2452 | return -ENXIO; |
2449 | if (!initialized) { | 2453 | if (!initialized) { |
2450 | initialized = 1; | 2454 | initialized = 1; |
2451 | matrox_init(); | 2455 | err = matrox_init(); |
2452 | } | 2456 | } |
2453 | hotplug = 1; | 2457 | hotplug = 1; |
2454 | /* never return failure, user can hotplug matrox later... */ | 2458 | /* never return failure, user can hotplug matrox later... */ |
2455 | return 0; | 2459 | return err; |
2456 | } | 2460 | } |
2457 | 2461 | ||
2458 | module_init(matroxfb_init); | 2462 | module_init(matroxfb_init); |
diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c index 6849ab75d403..a32d1af79e07 100644 --- a/drivers/video/mbx/mbxfb.c +++ b/drivers/video/mbx/mbxfb.c | |||
@@ -118,8 +118,19 @@ static unsigned int mbxfb_get_pixclock(unsigned int pixclock_ps, | |||
118 | /* convert pixclock to KHz */ | 118 | /* convert pixclock to KHz */ |
119 | pixclock = PICOS2KHZ(pixclock_ps); | 119 | pixclock = PICOS2KHZ(pixclock_ps); |
120 | 120 | ||
121 | /* PLL output freq = (ref_clk * M) / (N * 2^P) | ||
122 | * | ||
123 | * M: 1 to 63 | ||
124 | * N: 1 to 7 | ||
125 | * P: 0 to 7 | ||
126 | */ | ||
127 | |||
128 | /* RAPH: When N==1, the resulting pixel clock appears to | ||
129 | * get divided by 2. Preventing N=1 by starting the following | ||
130 | * loop at 2 prevents this. Is this a bug with my chip | ||
131 | * revision or something I dont understand? */ | ||
121 | for (m = 1; m < 64; m++) { | 132 | for (m = 1; m < 64; m++) { |
122 | for (n = 1; n < 8; n++) { | 133 | for (n = 2; n < 8; n++) { |
123 | for (p = 0; p < 8; p++) { | 134 | for (p = 0; p < 8; p++) { |
124 | clk = (ref_clk * m) / (n * (1 << p)); | 135 | clk = (ref_clk * m) / (n * (1 << p)); |
125 | err = (clk > pixclock) ? (clk - pixclock) : | 136 | err = (clk > pixclock) ? (clk - pixclock) : |
@@ -244,8 +255,8 @@ static int mbxfb_set_par(struct fb_info *info) | |||
244 | 255 | ||
245 | /* setup resolution */ | 256 | /* setup resolution */ |
246 | gsctrl &= ~(FMsk(GSCTRL_GSWIDTH) | FMsk(GSCTRL_GSHEIGHT)); | 257 | gsctrl &= ~(FMsk(GSCTRL_GSWIDTH) | FMsk(GSCTRL_GSHEIGHT)); |
247 | gsctrl |= Gsctrl_Width(info->var.xres - 1) | | 258 | gsctrl |= Gsctrl_Width(info->var.xres) | |
248 | Gsctrl_Height(info->var.yres - 1); | 259 | Gsctrl_Height(info->var.yres); |
249 | writel(gsctrl, GSCTRL); | 260 | writel(gsctrl, GSCTRL); |
250 | udelay(1000); | 261 | udelay(1000); |
251 | 262 | ||
@@ -402,8 +413,8 @@ static void __devinit setup_graphics(struct fb_info *fbi) | |||
402 | { | 413 | { |
403 | unsigned long gsctrl; | 414 | unsigned long gsctrl; |
404 | 415 | ||
405 | gsctrl = GSCTRL_GAMMA_EN | Gsctrl_Width(fbi->var.xres - 1) | | 416 | gsctrl = GSCTRL_GAMMA_EN | Gsctrl_Width(fbi->var.xres) | |
406 | Gsctrl_Height(fbi->var.yres - 1); | 417 | Gsctrl_Height(fbi->var.yres); |
407 | switch (fbi->var.bits_per_pixel) { | 418 | switch (fbi->var.bits_per_pixel) { |
408 | case 16: | 419 | case 16: |
409 | if (fbi->var.green.length == 5) | 420 | if (fbi->var.green.length == 5) |
diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c index 19eef3a09023..e48de3c9fd13 100644 --- a/drivers/video/nvidia/nv_i2c.c +++ b/drivers/video/nvidia/nv_i2c.c | |||
@@ -160,51 +160,12 @@ void nvidia_delete_i2c_busses(struct nvidia_par *par) | |||
160 | 160 | ||
161 | } | 161 | } |
162 | 162 | ||
163 | static u8 *nvidia_do_probe_i2c_edid(struct nvidia_i2c_chan *chan) | ||
164 | { | ||
165 | u8 start = 0x0; | ||
166 | struct i2c_msg msgs[] = { | ||
167 | { | ||
168 | .addr = 0x50, | ||
169 | .len = 1, | ||
170 | .buf = &start, | ||
171 | }, { | ||
172 | .addr = 0x50, | ||
173 | .flags = I2C_M_RD, | ||
174 | .len = EDID_LENGTH, | ||
175 | }, | ||
176 | }; | ||
177 | u8 *buf; | ||
178 | |||
179 | if (!chan->par) | ||
180 | return NULL; | ||
181 | |||
182 | buf = kmalloc(EDID_LENGTH, GFP_KERNEL); | ||
183 | if (!buf) { | ||
184 | dev_warn(&chan->par->pci_dev->dev, "Out of memory!\n"); | ||
185 | return NULL; | ||
186 | } | ||
187 | msgs[1].buf = buf; | ||
188 | |||
189 | if (i2c_transfer(&chan->adapter, msgs, 2) == 2) | ||
190 | return buf; | ||
191 | dev_dbg(&chan->par->pci_dev->dev, "Unable to read EDID block.\n"); | ||
192 | kfree(buf); | ||
193 | return NULL; | ||
194 | } | ||
195 | |||
196 | int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid) | 163 | int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid) |
197 | { | 164 | { |
198 | struct nvidia_par *par = info->par; | 165 | struct nvidia_par *par = info->par; |
199 | u8 *edid = NULL; | 166 | u8 *edid; |
200 | int i; | 167 | |
201 | 168 | edid = fb_ddc_read(&par->chan[conn - 1].adapter); | |
202 | for (i = 0; i < 3; i++) { | ||
203 | /* Do the real work */ | ||
204 | edid = nvidia_do_probe_i2c_edid(&par->chan[conn - 1]); | ||
205 | if (edid) | ||
206 | break; | ||
207 | } | ||
208 | 169 | ||
209 | if (!edid && conn == 1) { | 170 | if (!edid && conn == 1) { |
210 | /* try to get from firmware */ | 171 | /* try to get from firmware */ |
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index f8cd4c519aeb..eb24107bcc81 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c | |||
@@ -28,6 +28,9 @@ | |||
28 | #include <asm/prom.h> | 28 | #include <asm/prom.h> |
29 | #include <asm/pci-bridge.h> | 29 | #include <asm/pci-bridge.h> |
30 | #endif | 30 | #endif |
31 | #ifdef CONFIG_BOOTX_TEXT | ||
32 | #include <asm/btext.h> | ||
33 | #endif | ||
31 | 34 | ||
32 | #include "nv_local.h" | 35 | #include "nv_local.h" |
33 | #include "nv_type.h" | 36 | #include "nv_type.h" |
@@ -681,6 +684,13 @@ static int nvidiafb_set_par(struct fb_info *info) | |||
681 | 684 | ||
682 | nvidia_vga_protect(par, 0); | 685 | nvidia_vga_protect(par, 0); |
683 | 686 | ||
687 | #ifdef CONFIG_BOOTX_TEXT | ||
688 | /* Update debug text engine */ | ||
689 | btext_update_display(info->fix.smem_start, | ||
690 | info->var.xres, info->var.yres, | ||
691 | info->var.bits_per_pixel, info->fix.line_length); | ||
692 | #endif | ||
693 | |||
684 | NVTRACE_LEAVE(); | 694 | NVTRACE_LEAVE(); |
685 | return 0; | 695 | return 0; |
686 | } | 696 | } |
@@ -984,7 +994,10 @@ static int nvidiafb_resume(struct pci_dev *dev) | |||
984 | 994 | ||
985 | if (par->pm_state != PM_EVENT_FREEZE) { | 995 | if (par->pm_state != PM_EVENT_FREEZE) { |
986 | pci_restore_state(dev); | 996 | pci_restore_state(dev); |
987 | pci_enable_device(dev); | 997 | |
998 | if (pci_enable_device(dev)) | ||
999 | goto fail; | ||
1000 | |||
988 | pci_set_master(dev); | 1001 | pci_set_master(dev); |
989 | } | 1002 | } |
990 | 1003 | ||
@@ -993,6 +1006,7 @@ static int nvidiafb_resume(struct pci_dev *dev) | |||
993 | fb_set_suspend (info, 0); | 1006 | fb_set_suspend (info, 0); |
994 | nvidiafb_blank(FB_BLANK_UNBLANK, info); | 1007 | nvidiafb_blank(FB_BLANK_UNBLANK, info); |
995 | 1008 | ||
1009 | fail: | ||
996 | release_console_sem(); | 1010 | release_console_sem(); |
997 | return 0; | 1011 | return 0; |
998 | } | 1012 | } |
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index 4acde4f7dbf8..b120896c8ab4 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c | |||
@@ -393,8 +393,8 @@ static void riva_bl_init(struct riva_par *par) | |||
393 | mutex_lock(&info->bl_mutex); | 393 | mutex_lock(&info->bl_mutex); |
394 | info->bl_dev = bd; | 394 | info->bl_dev = bd; |
395 | fb_bl_default_curve(info, 0, | 395 | fb_bl_default_curve(info, 0, |
396 | 0x158 * FB_BACKLIGHT_MAX / MAX_LEVEL, | 396 | MIN_LEVEL * FB_BACKLIGHT_MAX / MAX_LEVEL, |
397 | 0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL); | 397 | FB_BACKLIGHT_MAX); |
398 | mutex_unlock(&info->bl_mutex); | 398 | mutex_unlock(&info->bl_mutex); |
399 | 399 | ||
400 | down(&bd->sem); | 400 | down(&bd->sem); |
@@ -784,7 +784,7 @@ static void riva_load_video_mode(struct fb_info *info) | |||
784 | 784 | ||
785 | NVTRACE_ENTER(); | 785 | NVTRACE_ENTER(); |
786 | /* time to calculate */ | 786 | /* time to calculate */ |
787 | rivafb_blank(1, info); | 787 | rivafb_blank(FB_BLANK_NORMAL, info); |
788 | 788 | ||
789 | bpp = info->var.bits_per_pixel; | 789 | bpp = info->var.bits_per_pixel; |
790 | if (bpp == 16 && info->var.green.length == 5) | 790 | if (bpp == 16 && info->var.green.length == 5) |
@@ -917,7 +917,7 @@ static void riva_load_video_mode(struct fb_info *info) | |||
917 | par->current_state = newmode; | 917 | par->current_state = newmode; |
918 | riva_load_state(par, &par->current_state); | 918 | riva_load_state(par, &par->current_state); |
919 | par->riva.LockUnlock(&par->riva, 0); /* important for HW cursor */ | 919 | par->riva.LockUnlock(&par->riva, 0); /* important for HW cursor */ |
920 | rivafb_blank(0, info); | 920 | rivafb_blank(FB_BLANK_UNBLANK, info); |
921 | NVTRACE_LEAVE(); | 921 | NVTRACE_LEAVE(); |
922 | } | 922 | } |
923 | 923 | ||
diff --git a/drivers/video/riva/rivafb-i2c.c b/drivers/video/riva/rivafb-i2c.c index 9751c37c0bfd..c15b259af644 100644 --- a/drivers/video/riva/rivafb-i2c.c +++ b/drivers/video/riva/rivafb-i2c.c | |||
@@ -25,8 +25,6 @@ | |||
25 | #include "rivafb.h" | 25 | #include "rivafb.h" |
26 | #include "../edid.h" | 26 | #include "../edid.h" |
27 | 27 | ||
28 | #define RIVA_DDC 0x50 | ||
29 | |||
30 | static void riva_gpio_setscl(void* data, int state) | 28 | static void riva_gpio_setscl(void* data, int state) |
31 | { | 29 | { |
32 | struct riva_i2c_chan *chan = data; | 30 | struct riva_i2c_chan *chan = data; |
@@ -158,50 +156,12 @@ void riva_delete_i2c_busses(struct riva_par *par) | |||
158 | par->chan[2].par = NULL; | 156 | par->chan[2].par = NULL; |
159 | } | 157 | } |
160 | 158 | ||
161 | static u8 *riva_do_probe_i2c_edid(struct riva_i2c_chan *chan) | ||
162 | { | ||
163 | u8 start = 0x0; | ||
164 | struct i2c_msg msgs[] = { | ||
165 | { | ||
166 | .addr = RIVA_DDC, | ||
167 | .len = 1, | ||
168 | .buf = &start, | ||
169 | }, { | ||
170 | .addr = RIVA_DDC, | ||
171 | .flags = I2C_M_RD, | ||
172 | .len = EDID_LENGTH, | ||
173 | }, | ||
174 | }; | ||
175 | u8 *buf; | ||
176 | |||
177 | if (!chan->par) | ||
178 | return NULL; | ||
179 | |||
180 | buf = kmalloc(EDID_LENGTH, GFP_KERNEL); | ||
181 | if (!buf) { | ||
182 | dev_warn(&chan->par->pdev->dev, "Out of memory!\n"); | ||
183 | return NULL; | ||
184 | } | ||
185 | msgs[1].buf = buf; | ||
186 | |||
187 | if (i2c_transfer(&chan->adapter, msgs, 2) == 2) | ||
188 | return buf; | ||
189 | dev_dbg(&chan->par->pdev->dev, "Unable to read EDID block.\n"); | ||
190 | kfree(buf); | ||
191 | return NULL; | ||
192 | } | ||
193 | |||
194 | int riva_probe_i2c_connector(struct riva_par *par, int conn, u8 **out_edid) | 159 | int riva_probe_i2c_connector(struct riva_par *par, int conn, u8 **out_edid) |
195 | { | 160 | { |
196 | u8 *edid = NULL; | 161 | u8 *edid = NULL; |
197 | int i; | ||
198 | 162 | ||
199 | for (i = 0; i < 3; i++) { | 163 | edid = fb_ddc_read(&par->chan[conn-1].adapter); |
200 | /* Do the real work */ | 164 | |
201 | edid = riva_do_probe_i2c_edid(&par->chan[conn-1]); | ||
202 | if (edid) | ||
203 | break; | ||
204 | } | ||
205 | if (out_edid) | 165 | if (out_edid) |
206 | *out_edid = edid; | 166 | *out_edid = edid; |
207 | if (!edid) | 167 | if (!edid) |
diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c index d7d810dbf0bd..3f94223b7f0c 100644 --- a/drivers/video/savage/savagefb-i2c.c +++ b/drivers/video/savage/savagefb-i2c.c | |||
@@ -213,52 +213,15 @@ void savagefb_delete_i2c_busses(struct fb_info *info) | |||
213 | par->chan.par = NULL; | 213 | par->chan.par = NULL; |
214 | } | 214 | } |
215 | 215 | ||
216 | static u8 *savage_do_probe_i2c_edid(struct savagefb_i2c_chan *chan) | ||
217 | { | ||
218 | u8 start = 0x0; | ||
219 | struct i2c_msg msgs[] = { | ||
220 | { | ||
221 | .addr = SAVAGE_DDC, | ||
222 | .len = 1, | ||
223 | .buf = &start, | ||
224 | }, { | ||
225 | .addr = SAVAGE_DDC, | ||
226 | .flags = I2C_M_RD, | ||
227 | .len = EDID_LENGTH, | ||
228 | }, | ||
229 | }; | ||
230 | u8 *buf = NULL; | ||
231 | |||
232 | if (chan->par) { | ||
233 | buf = kmalloc(EDID_LENGTH, GFP_KERNEL); | ||
234 | |||
235 | if (buf) { | ||
236 | msgs[1].buf = buf; | ||
237 | |||
238 | if (i2c_transfer(&chan->adapter, msgs, 2) != 2) { | ||
239 | dev_dbg(&chan->par->pcidev->dev, | ||
240 | "Unable to read EDID block.\n"); | ||
241 | kfree(buf); | ||
242 | buf = NULL; | ||
243 | } | ||
244 | } | ||
245 | } | ||
246 | |||
247 | return buf; | ||
248 | } | ||
249 | |||
250 | int savagefb_probe_i2c_connector(struct fb_info *info, u8 **out_edid) | 216 | int savagefb_probe_i2c_connector(struct fb_info *info, u8 **out_edid) |
251 | { | 217 | { |
252 | struct savagefb_par *par = info->par; | 218 | struct savagefb_par *par = info->par; |
253 | u8 *edid = NULL; | 219 | u8 *edid; |
254 | int i; | 220 | |
255 | 221 | if (par->chan.par) | |
256 | for (i = 0; i < 3; i++) { | 222 | edid = fb_ddc_read(&par->chan.adapter); |
257 | /* Do the real work */ | 223 | else |
258 | edid = savage_do_probe_i2c_edid(&par->chan); | 224 | edid = NULL; |
259 | if (edid) | ||
260 | break; | ||
261 | } | ||
262 | 225 | ||
263 | if (!edid) { | 226 | if (!edid) { |
264 | /* try to get from firmware */ | 227 | /* try to get from firmware */ |
diff --git a/drivers/video/sis/init.h b/drivers/video/sis/init.h index 7ecab87cef02..59d12844b4dd 100644 --- a/drivers/video/sis/init.h +++ b/drivers/video/sis/init.h | |||
@@ -77,16 +77,9 @@ | |||
77 | #include <linux/types.h> | 77 | #include <linux/types.h> |
78 | #include <asm/io.h> | 78 | #include <asm/io.h> |
79 | #include <linux/fb.h> | 79 | #include <linux/fb.h> |
80 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
81 | #include <video/fbcon.h> | ||
82 | #endif | ||
83 | #include "sis.h" | 80 | #include "sis.h" |
84 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
85 | #include <linux/sisfb.h> | ||
86 | #else | ||
87 | #include <video/sisfb.h> | 81 | #include <video/sisfb.h> |
88 | #endif | 82 | #endif |
89 | #endif | ||
90 | 83 | ||
91 | /* Mode numbers */ | 84 | /* Mode numbers */ |
92 | static const unsigned short ModeIndex_320x200[] = {0x59, 0x41, 0x00, 0x4f}; | 85 | static const unsigned short ModeIndex_320x200[] = {0x59, 0x41, 0x00, 0x4f}; |
diff --git a/drivers/video/sis/init301.h b/drivers/video/sis/init301.h index bc321dc57e92..4f3a28699d37 100644 --- a/drivers/video/sis/init301.h +++ b/drivers/video/sis/init301.h | |||
@@ -71,16 +71,9 @@ | |||
71 | #include <linux/types.h> | 71 | #include <linux/types.h> |
72 | #include <asm/io.h> | 72 | #include <asm/io.h> |
73 | #include <linux/fb.h> | 73 | #include <linux/fb.h> |
74 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
75 | #include <video/fbcon.h> | ||
76 | #endif | ||
77 | #include "sis.h" | 74 | #include "sis.h" |
78 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
79 | #include <linux/sisfb.h> | ||
80 | #else | ||
81 | #include <video/sisfb.h> | 75 | #include <video/sisfb.h> |
82 | #endif | 76 | #endif |
83 | #endif | ||
84 | 77 | ||
85 | static const unsigned char SiS_YPbPrTable[3][64] = { | 78 | static const unsigned char SiS_YPbPrTable[3][64] = { |
86 | { | 79 | { |
diff --git a/drivers/video/sis/initextlfb.c b/drivers/video/sis/initextlfb.c index 09f5d758b6c0..c3884a29f4c5 100644 --- a/drivers/video/sis/initextlfb.c +++ b/drivers/video/sis/initextlfb.c | |||
@@ -34,12 +34,10 @@ | |||
34 | #include <linux/types.h> | 34 | #include <linux/types.h> |
35 | #include <linux/fb.h> | 35 | #include <linux/fb.h> |
36 | 36 | ||
37 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
38 | int sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr, | 37 | int sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr, |
39 | unsigned char modeno, unsigned char rateindex); | 38 | unsigned char modeno, unsigned char rateindex); |
40 | int sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno, | 39 | int sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno, |
41 | unsigned char rateindex, struct fb_var_screeninfo *var); | 40 | unsigned char rateindex, struct fb_var_screeninfo *var); |
42 | #endif | ||
43 | BOOLEAN sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno, | 41 | BOOLEAN sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno, |
44 | int *htotal, int *vtotal, unsigned char rateindex); | 42 | int *htotal, int *vtotal, unsigned char rateindex); |
45 | 43 | ||
@@ -49,7 +47,6 @@ extern BOOLEAN SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *Mode | |||
49 | extern void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, | 47 | extern void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, |
50 | int xres, int yres, struct fb_var_screeninfo *var, BOOLEAN writeres); | 48 | int xres, int yres, struct fb_var_screeninfo *var, BOOLEAN writeres); |
51 | 49 | ||
52 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
53 | int | 50 | int |
54 | sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr, unsigned char modeno, | 51 | sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr, unsigned char modeno, |
55 | unsigned char rateindex) | 52 | unsigned char rateindex) |
@@ -177,7 +174,6 @@ sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno, | |||
177 | 174 | ||
178 | return 1; | 175 | return 1; |
179 | } | 176 | } |
180 | #endif /* Linux >= 2.5 */ | ||
181 | 177 | ||
182 | BOOLEAN | 178 | BOOLEAN |
183 | sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno, int *htotal, | 179 | sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno, int *htotal, |
diff --git a/drivers/video/sis/osdef.h b/drivers/video/sis/osdef.h index f59568020eb2..d048bd39961b 100644 --- a/drivers/video/sis/osdef.h +++ b/drivers/video/sis/osdef.h | |||
@@ -100,11 +100,7 @@ | |||
100 | #define SIS315H | 100 | #define SIS315H |
101 | #endif | 101 | #endif |
102 | 102 | ||
103 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
104 | #define SIS_LINUX_KERNEL_26 | 103 | #define SIS_LINUX_KERNEL_26 |
105 | #else | ||
106 | #define SIS_LINUX_KERNEL_24 | ||
107 | #endif | ||
108 | 104 | ||
109 | #if !defined(SIS300) && !defined(SIS315H) | 105 | #if !defined(SIS300) && !defined(SIS315H) |
110 | #warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set | 106 | #warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set |
diff --git a/drivers/video/sis/sis_accel.c b/drivers/video/sis/sis_accel.c index 3b7ce032e2ed..7addf91d2fea 100644 --- a/drivers/video/sis/sis_accel.c +++ b/drivers/video/sis/sis_accel.c | |||
@@ -32,22 +32,10 @@ | |||
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <linux/kernel.h> | 33 | #include <linux/kernel.h> |
34 | #include <linux/fb.h> | 34 | #include <linux/fb.h> |
35 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
36 | #include <linux/console.h> | ||
37 | #endif | ||
38 | #include <linux/ioport.h> | 35 | #include <linux/ioport.h> |
39 | #include <linux/types.h> | 36 | #include <linux/types.h> |
40 | |||
41 | #include <asm/io.h> | 37 | #include <asm/io.h> |
42 | 38 | ||
43 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
44 | #include <video/fbcon.h> | ||
45 | #include <video/fbcon-cfb8.h> | ||
46 | #include <video/fbcon-cfb16.h> | ||
47 | #include <video/fbcon-cfb24.h> | ||
48 | #include <video/fbcon-cfb32.h> | ||
49 | #endif | ||
50 | |||
51 | #include "sis.h" | 39 | #include "sis.h" |
52 | #include "sis_accel.h" | 40 | #include "sis_accel.h" |
53 | 41 | ||
@@ -91,11 +79,9 @@ static const u8 sisPatALUConv[] = | |||
91 | 0xFF, /* dest = 0xFF; 1, GXset, 0xF */ | 79 | 0xFF, /* dest = 0xFF; 1, GXset, 0xF */ |
92 | }; | 80 | }; |
93 | 81 | ||
94 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34) | ||
95 | static const int myrops[] = { | 82 | static const int myrops[] = { |
96 | 3, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 | 83 | 3, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 |
97 | }; | 84 | }; |
98 | #endif | ||
99 | 85 | ||
100 | /* 300 series ----------------------------------------------------- */ | 86 | /* 300 series ----------------------------------------------------- */ |
101 | #ifdef CONFIG_FB_SIS_300 | 87 | #ifdef CONFIG_FB_SIS_300 |
@@ -315,8 +301,6 @@ void sisfb_syncaccel(struct sis_video_info *ivideo) | |||
315 | } | 301 | } |
316 | } | 302 | } |
317 | 303 | ||
318 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) /* --------------- 2.5 --------------- */ | ||
319 | |||
320 | int fbcon_sis_sync(struct fb_info *info) | 304 | int fbcon_sis_sync(struct fb_info *info) |
321 | { | 305 | { |
322 | struct sis_video_info *ivideo = (struct sis_video_info *)info->par; | 306 | struct sis_video_info *ivideo = (struct sis_video_info *)info->par; |
@@ -438,13 +422,3 @@ void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area) | |||
438 | 422 | ||
439 | sisfb_syncaccel(ivideo); | 423 | sisfb_syncaccel(ivideo); |
440 | } | 424 | } |
441 | |||
442 | #endif | ||
443 | |||
444 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* -------------- 2.4 --------------- */ | ||
445 | |||
446 | #include "sisfb_accel_2_4.h" | ||
447 | |||
448 | #endif /* KERNEL VERSION */ | ||
449 | |||
450 | |||
diff --git a/drivers/video/sis/sis_accel.h b/drivers/video/sis/sis_accel.h index 046e2c4a8e09..30e03cdf6b85 100644 --- a/drivers/video/sis/sis_accel.h +++ b/drivers/video/sis/sis_accel.h | |||
@@ -390,25 +390,11 @@ | |||
390 | MMIO_OUT32(ivideo->mmio_vbase, FIRE_TRIGGER, 0); \ | 390 | MMIO_OUT32(ivideo->mmio_vbase, FIRE_TRIGGER, 0); \ |
391 | CmdQueLen -= 2; | 391 | CmdQueLen -= 2; |
392 | 392 | ||
393 | |||
394 | int sisfb_initaccel(struct sis_video_info *ivideo); | 393 | int sisfb_initaccel(struct sis_video_info *ivideo); |
395 | void sisfb_syncaccel(struct sis_video_info *ivideo); | 394 | void sisfb_syncaccel(struct sis_video_info *ivideo); |
396 | 395 | ||
397 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33) | ||
398 | void fbcon_sis_bmove(struct display *p, int srcy, int srcx, int dsty, | ||
399 | int dstx, int height, int width); | ||
400 | void fbcon_sis_revc(struct display *p, int srcy, int srcx); | ||
401 | void fbcon_sis_clear8(struct vc_data *conp, struct display *p, int srcy, | ||
402 | int srcx, int height, int width); | ||
403 | void fbcon_sis_clear16(struct vc_data *conp, struct display *p, int srcy, | ||
404 | int srcx, int height, int width); | ||
405 | void fbcon_sis_clear32(struct vc_data *conp, struct display *p, int srcy, | ||
406 | int srcx, int height, int width); | ||
407 | #endif | ||
408 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34) | ||
409 | int fbcon_sis_sync(struct fb_info *info); | 396 | int fbcon_sis_sync(struct fb_info *info); |
410 | void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect); | 397 | void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect); |
411 | void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area); | 398 | void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area); |
412 | #endif | ||
413 | 399 | ||
414 | #endif | 400 | #endif |
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index 895ebda7d9e3..baaf495a0a6d 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c | |||
@@ -35,9 +35,7 @@ | |||
35 | 35 | ||
36 | #include <linux/version.h> | 36 | #include <linux/version.h> |
37 | #include <linux/module.h> | 37 | #include <linux/module.h> |
38 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
39 | #include <linux/moduleparam.h> | 38 | #include <linux/moduleparam.h> |
40 | #endif | ||
41 | #include <linux/kernel.h> | 39 | #include <linux/kernel.h> |
42 | #include <linux/smp_lock.h> | 40 | #include <linux/smp_lock.h> |
43 | #include <linux/spinlock.h> | 41 | #include <linux/spinlock.h> |
@@ -58,9 +56,6 @@ | |||
58 | #include <linux/init.h> | 56 | #include <linux/init.h> |
59 | #include <linux/pci.h> | 57 | #include <linux/pci.h> |
60 | #include <linux/vmalloc.h> | 58 | #include <linux/vmalloc.h> |
61 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
62 | #include <linux/vt_kern.h> | ||
63 | #endif | ||
64 | #include <linux/capability.h> | 59 | #include <linux/capability.h> |
65 | #include <linux/fs.h> | 60 | #include <linux/fs.h> |
66 | #include <linux/types.h> | 61 | #include <linux/types.h> |
@@ -70,35 +65,9 @@ | |||
70 | #include <asm/mtrr.h> | 65 | #include <asm/mtrr.h> |
71 | #endif | 66 | #endif |
72 | 67 | ||
73 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
74 | #include <video/fbcon.h> | ||
75 | #include <video/fbcon-cfb8.h> | ||
76 | #include <video/fbcon-cfb16.h> | ||
77 | #include <video/fbcon-cfb24.h> | ||
78 | #include <video/fbcon-cfb32.h> | ||
79 | #endif | ||
80 | |||
81 | #include "sis.h" | 68 | #include "sis.h" |
82 | #include "sis_main.h" | 69 | #include "sis_main.h" |
83 | 70 | ||
84 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
85 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3) | ||
86 | #error "This version of sisfb requires at least 2.6.3" | ||
87 | #endif | ||
88 | #endif | ||
89 | |||
90 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
91 | #ifdef FBCON_HAS_CFB8 | ||
92 | extern struct display_switch fbcon_sis8; | ||
93 | #endif | ||
94 | #ifdef FBCON_HAS_CFB16 | ||
95 | extern struct display_switch fbcon_sis16; | ||
96 | #endif | ||
97 | #ifdef FBCON_HAS_CFB32 | ||
98 | extern struct display_switch fbcon_sis32; | ||
99 | #endif | ||
100 | #endif | ||
101 | |||
102 | static void sisfb_handle_command(struct sis_video_info *ivideo, | 71 | static void sisfb_handle_command(struct sis_video_info *ivideo, |
103 | struct sisfb_cmd *sisfb_command); | 72 | struct sisfb_cmd *sisfb_command); |
104 | 73 | ||
@@ -114,17 +83,7 @@ sisfb_setdefaultparms(void) | |||
114 | sisfb_max = -1; | 83 | sisfb_max = -1; |
115 | sisfb_userom = -1; | 84 | sisfb_userom = -1; |
116 | sisfb_useoem = -1; | 85 | sisfb_useoem = -1; |
117 | #ifdef MODULE | ||
118 | /* Module: "None" for 2.4, default mode for 2.5+ */ | ||
119 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
120 | sisfb_mode_idx = -1; | ||
121 | #else | ||
122 | sisfb_mode_idx = MODE_INDEX_NONE; | ||
123 | #endif | ||
124 | #else | ||
125 | /* Static: Default mode */ | ||
126 | sisfb_mode_idx = -1; | 86 | sisfb_mode_idx = -1; |
127 | #endif | ||
128 | sisfb_parm_rate = -1; | 87 | sisfb_parm_rate = -1; |
129 | sisfb_crt1off = 0; | 88 | sisfb_crt1off = 0; |
130 | sisfb_forcecrt1 = -1; | 89 | sisfb_forcecrt1 = -1; |
@@ -142,10 +101,6 @@ sisfb_setdefaultparms(void) | |||
142 | sisfb_tvxposoffset = 0; | 101 | sisfb_tvxposoffset = 0; |
143 | sisfb_tvyposoffset = 0; | 102 | sisfb_tvyposoffset = 0; |
144 | sisfb_nocrt2rate = 0; | 103 | sisfb_nocrt2rate = 0; |
145 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
146 | sisfb_inverse = 0; | ||
147 | sisfb_fontname[0] = 0; | ||
148 | #endif | ||
149 | #if !defined(__i386__) && !defined(__x86_64__) | 104 | #if !defined(__i386__) && !defined(__x86_64__) |
150 | sisfb_resetcard = 0; | 105 | sisfb_resetcard = 0; |
151 | sisfb_videoram = 0; | 106 | sisfb_videoram = 0; |
@@ -162,14 +117,11 @@ sisfb_search_vesamode(unsigned int vesamode, BOOLEAN quiet) | |||
162 | /* We don't know the hardware specs yet and there is no ivideo */ | 117 | /* We don't know the hardware specs yet and there is no ivideo */ |
163 | 118 | ||
164 | if(vesamode == 0) { | 119 | if(vesamode == 0) { |
165 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
166 | sisfb_mode_idx = MODE_INDEX_NONE; | ||
167 | #else | ||
168 | if(!quiet) | 120 | if(!quiet) |
169 | printk(KERN_ERR "sisfb: Invalid mode. Using default.\n"); | 121 | printk(KERN_ERR "sisfb: Invalid mode. Using default.\n"); |
170 | 122 | ||
171 | sisfb_mode_idx = DEFAULT_MODE; | 123 | sisfb_mode_idx = DEFAULT_MODE; |
172 | #endif | 124 | |
173 | return; | 125 | return; |
174 | } | 126 | } |
175 | 127 | ||
@@ -215,7 +167,6 @@ sisfb_search_mode(char *name, BOOLEAN quiet) | |||
215 | return; | 167 | return; |
216 | } | 168 | } |
217 | 169 | ||
218 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
219 | if(!strnicmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) { | 170 | if(!strnicmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) { |
220 | if(!quiet) | 171 | if(!quiet) |
221 | printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n"); | 172 | printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n"); |
@@ -223,7 +174,7 @@ sisfb_search_mode(char *name, BOOLEAN quiet) | |||
223 | sisfb_mode_idx = DEFAULT_MODE; | 174 | sisfb_mode_idx = DEFAULT_MODE; |
224 | return; | 175 | return; |
225 | } | 176 | } |
226 | #endif | 177 | |
227 | if(strlen(name) <= 19) { | 178 | if(strlen(name) <= 19) { |
228 | strcpy(strbuf1, name); | 179 | strcpy(strbuf1, name); |
229 | for(i = 0; i < strlen(strbuf1); i++) { | 180 | for(i = 0; i < strlen(strbuf1); i++) { |
@@ -1315,20 +1266,7 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in | |||
1315 | ivideo->refresh_rate = 60; | 1266 | ivideo->refresh_rate = 60; |
1316 | } | 1267 | } |
1317 | 1268 | ||
1318 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
1319 | if(ivideo->sisfb_thismonitor.datavalid) { | ||
1320 | if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, ivideo->sisfb_mode_idx, | ||
1321 | ivideo->rate_idx, ivideo->refresh_rate)) { | ||
1322 | printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n"); | ||
1323 | } | ||
1324 | } | ||
1325 | #endif | ||
1326 | |||
1327 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
1328 | if(((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) && isactive) { | ||
1329 | #else | ||
1330 | if(isactive) { | 1269 | if(isactive) { |
1331 | #endif | ||
1332 | /* If acceleration to be used? Need to know | 1270 | /* If acceleration to be used? Need to know |
1333 | * before pre/post_set_mode() | 1271 | * before pre/post_set_mode() |
1334 | */ | 1272 | */ |
@@ -1367,9 +1305,7 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in | |||
1367 | ivideo->current_linelength = ivideo->video_linelength; | 1305 | ivideo->current_linelength = ivideo->video_linelength; |
1368 | ivideo->current_pixclock = var->pixclock; | 1306 | ivideo->current_pixclock = var->pixclock; |
1369 | ivideo->current_refresh_rate = ivideo->refresh_rate; | 1307 | ivideo->current_refresh_rate = ivideo->refresh_rate; |
1370 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
1371 | ivideo->sisfb_lastrates[ivideo->mode_no] = ivideo->refresh_rate; | 1308 | ivideo->sisfb_lastrates[ivideo->mode_no] = ivideo->refresh_rate; |
1372 | #endif | ||
1373 | } | 1309 | } |
1374 | 1310 | ||
1375 | return 0; | 1311 | return 0; |
@@ -1435,18 +1371,6 @@ sisfb_pan_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var) | |||
1435 | return 0; | 1371 | return 0; |
1436 | } | 1372 | } |
1437 | 1373 | ||
1438 | /* ------------ FBDev related routines for 2.4 series ----------- */ | ||
1439 | |||
1440 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
1441 | |||
1442 | #include "sisfb_fbdev_2_4.h" | ||
1443 | |||
1444 | #endif | ||
1445 | |||
1446 | /* ------------ FBDev related routines for 2.6 series ----------- */ | ||
1447 | |||
1448 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
1449 | |||
1450 | static int | 1374 | static int |
1451 | sisfb_open(struct fb_info *info, int user) | 1375 | sisfb_open(struct fb_info *info, int user) |
1452 | { | 1376 | { |
@@ -1744,8 +1668,6 @@ sisfb_blank(int blank, struct fb_info *info) | |||
1744 | return sisfb_myblank(ivideo, blank); | 1668 | return sisfb_myblank(ivideo, blank); |
1745 | } | 1669 | } |
1746 | 1670 | ||
1747 | #endif | ||
1748 | |||
1749 | /* ----------- FBDev related routines for all series ---------- */ | 1671 | /* ----------- FBDev related routines for all series ---------- */ |
1750 | 1672 | ||
1751 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) | 1673 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) |
@@ -1969,20 +1891,6 @@ sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info) | |||
1969 | 1891 | ||
1970 | /* ---------------- fb_ops structures ----------------- */ | 1892 | /* ---------------- fb_ops structures ----------------- */ |
1971 | 1893 | ||
1972 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
1973 | static struct fb_ops sisfb_ops = { | ||
1974 | .owner = THIS_MODULE, | ||
1975 | .fb_get_fix = sisfb_get_fix, | ||
1976 | .fb_get_var = sisfb_get_var, | ||
1977 | .fb_set_var = sisfb_set_var, | ||
1978 | .fb_get_cmap = sisfb_get_cmap, | ||
1979 | .fb_set_cmap = sisfb_set_cmap, | ||
1980 | .fb_pan_display = sisfb_pan_display, | ||
1981 | .fb_ioctl = sisfb_ioctl | ||
1982 | }; | ||
1983 | #endif | ||
1984 | |||
1985 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
1986 | static struct fb_ops sisfb_ops = { | 1894 | static struct fb_ops sisfb_ops = { |
1987 | .owner = THIS_MODULE, | 1895 | .owner = THIS_MODULE, |
1988 | .fb_open = sisfb_open, | 1896 | .fb_open = sisfb_open, |
@@ -2004,7 +1912,6 @@ static struct fb_ops sisfb_ops = { | |||
2004 | #endif | 1912 | #endif |
2005 | .fb_ioctl = sisfb_ioctl | 1913 | .fb_ioctl = sisfb_ioctl |
2006 | }; | 1914 | }; |
2007 | #endif | ||
2008 | 1915 | ||
2009 | /* ---------------- Chip generation dependent routines ---------------- */ | 1916 | /* ---------------- Chip generation dependent routines ---------------- */ |
2010 | 1917 | ||
@@ -4100,16 +4007,6 @@ sisfb_setup(char *options) | |||
4100 | sisfb_search_mode(this_opt + 5, FALSE); | 4007 | sisfb_search_mode(this_opt + 5, FALSE); |
4101 | } else if(!strnicmp(this_opt, "vesa:", 5)) { | 4008 | } else if(!strnicmp(this_opt, "vesa:", 5)) { |
4102 | sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0), FALSE); | 4009 | sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0), FALSE); |
4103 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
4104 | } else if(!strnicmp(this_opt, "inverse", 7)) { | ||
4105 | sisfb_inverse = 1; | ||
4106 | /* fb_invert_cmaps(); */ | ||
4107 | } else if(!strnicmp(this_opt, "font:", 5)) { | ||
4108 | if(strlen(this_opt + 5) < 40) { | ||
4109 | strncpy(sisfb_fontname, this_opt + 5, sizeof(sisfb_fontname) - 1); | ||
4110 | sisfb_fontname[sizeof(sisfb_fontname) - 1] = '\0'; | ||
4111 | } | ||
4112 | #endif | ||
4113 | } else if(!strnicmp(this_opt, "rate:", 5)) { | 4010 | } else if(!strnicmp(this_opt, "rate:", 5)) { |
4114 | sisfb_parm_rate = simple_strtoul(this_opt + 5, NULL, 0); | 4011 | sisfb_parm_rate = simple_strtoul(this_opt + 5, NULL, 0); |
4115 | } else if(!strnicmp(this_opt, "forcecrt1:", 10)) { | 4012 | } else if(!strnicmp(this_opt, "forcecrt1:", 10)) { |
@@ -5870,17 +5767,9 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
5870 | if(sisfb_off) | 5767 | if(sisfb_off) |
5871 | return -ENXIO; | 5768 | return -ENXIO; |
5872 | 5769 | ||
5873 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,3)) | ||
5874 | sis_fb_info = framebuffer_alloc(sizeof(*ivideo), &pdev->dev); | 5770 | sis_fb_info = framebuffer_alloc(sizeof(*ivideo), &pdev->dev); |
5875 | if(!sis_fb_info) | 5771 | if(!sis_fb_info) |
5876 | return -ENOMEM; | 5772 | return -ENOMEM; |
5877 | #else | ||
5878 | sis_fb_info = kmalloc(sizeof(*sis_fb_info) + sizeof(*ivideo), GFP_KERNEL); | ||
5879 | if(!sis_fb_info) | ||
5880 | return -ENOMEM; | ||
5881 | memset(sis_fb_info, 0, sizeof(*sis_fb_info) + sizeof(*ivideo)); | ||
5882 | sis_fb_info->par = ((char *)sis_fb_info + sizeof(*sis_fb_info)); | ||
5883 | #endif | ||
5884 | 5773 | ||
5885 | ivideo = (struct sis_video_info *)sis_fb_info->par; | 5774 | ivideo = (struct sis_video_info *)sis_fb_info->par; |
5886 | ivideo->memyselfandi = sis_fb_info; | 5775 | ivideo->memyselfandi = sis_fb_info; |
@@ -5970,10 +5859,6 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
5970 | ivideo->tvxpos = sisfb_tvxposoffset; | 5859 | ivideo->tvxpos = sisfb_tvxposoffset; |
5971 | ivideo->tvypos = sisfb_tvyposoffset; | 5860 | ivideo->tvypos = sisfb_tvyposoffset; |
5972 | ivideo->sisfb_nocrt2rate = sisfb_nocrt2rate; | 5861 | ivideo->sisfb_nocrt2rate = sisfb_nocrt2rate; |
5973 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0) | ||
5974 | ivideo->sisfb_inverse = sisfb_inverse; | ||
5975 | #endif | ||
5976 | |||
5977 | ivideo->refresh_rate = 0; | 5862 | ivideo->refresh_rate = 0; |
5978 | if(ivideo->sisfb_parm_rate != -1) { | 5863 | if(ivideo->sisfb_parm_rate != -1) { |
5979 | ivideo->refresh_rate = ivideo->sisfb_parm_rate; | 5864 | ivideo->refresh_rate = ivideo->sisfb_parm_rate; |
@@ -6049,10 +5934,6 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
6049 | } | 5934 | } |
6050 | } | 5935 | } |
6051 | 5936 | ||
6052 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
6053 | strcpy(sis_fb_info->modename, ivideo->myid); | ||
6054 | #endif | ||
6055 | |||
6056 | ivideo->SiS_Pr.ChipType = ivideo->chip; | 5937 | ivideo->SiS_Pr.ChipType = ivideo->chip; |
6057 | 5938 | ||
6058 | ivideo->SiS_Pr.ivideo = (void *)ivideo; | 5939 | ivideo->SiS_Pr.ivideo = (void *)ivideo; |
@@ -6134,20 +6015,6 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
6134 | #endif | 6015 | #endif |
6135 | } | 6016 | } |
6136 | 6017 | ||
6137 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
6138 | #ifdef MODULE | ||
6139 | if((reg & 0x80) && (reg != 0xff)) { | ||
6140 | if((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) | ||
6141 | != 0xFF) { | ||
6142 | printk(KERN_INFO "sisfb: Cannot initialize display mode, " | ||
6143 | "X server is active\n"); | ||
6144 | ret = -EBUSY; | ||
6145 | goto error_4; | ||
6146 | } | ||
6147 | } | ||
6148 | #endif | ||
6149 | #endif | ||
6150 | |||
6151 | /* Search and copy ROM image */ | 6018 | /* Search and copy ROM image */ |
6152 | ivideo->bios_abase = NULL; | 6019 | ivideo->bios_abase = NULL; |
6153 | ivideo->SiS_Pr.VirtualRomBase = NULL; | 6020 | ivideo->SiS_Pr.VirtualRomBase = NULL; |
@@ -6281,9 +6148,6 @@ error_0: iounmap(ivideo->video_vbase); | |||
6281 | error_1: release_mem_region(ivideo->video_base, ivideo->video_size); | 6148 | error_1: release_mem_region(ivideo->video_base, ivideo->video_size); |
6282 | error_2: release_mem_region(ivideo->mmio_base, ivideo->mmio_size); | 6149 | error_2: release_mem_region(ivideo->mmio_base, ivideo->mmio_size); |
6283 | error_3: vfree(ivideo->bios_abase); | 6150 | error_3: vfree(ivideo->bios_abase); |
6284 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
6285 | error_4: | ||
6286 | #endif | ||
6287 | if(ivideo->lpcdev) | 6151 | if(ivideo->lpcdev) |
6288 | SIS_PCI_PUT_DEVICE(ivideo->lpcdev); | 6152 | SIS_PCI_PUT_DEVICE(ivideo->lpcdev); |
6289 | if(ivideo->nbridge) | 6153 | if(ivideo->nbridge) |
@@ -6586,7 +6450,6 @@ error_4: | |||
6586 | sis_fb_info->fix = ivideo->sisfb_fix; | 6450 | sis_fb_info->fix = ivideo->sisfb_fix; |
6587 | sis_fb_info->screen_base = ivideo->video_vbase + ivideo->video_offset; | 6451 | sis_fb_info->screen_base = ivideo->video_vbase + ivideo->video_offset; |
6588 | sis_fb_info->fbops = &sisfb_ops; | 6452 | sis_fb_info->fbops = &sisfb_ops; |
6589 | |||
6590 | sisfb_get_fix(&sis_fb_info->fix, -1, sis_fb_info); | 6453 | sisfb_get_fix(&sis_fb_info->fix, -1, sis_fb_info); |
6591 | sis_fb_info->pseudo_palette = ivideo->pseudo_palette; | 6454 | sis_fb_info->pseudo_palette = ivideo->pseudo_palette; |
6592 | 6455 | ||
@@ -6603,10 +6466,6 @@ error_4: | |||
6603 | } | 6466 | } |
6604 | #endif | 6467 | #endif |
6605 | 6468 | ||
6606 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
6607 | vc_resize_con(1, 1, 0); | ||
6608 | #endif | ||
6609 | |||
6610 | if(register_framebuffer(sis_fb_info) < 0) { | 6469 | if(register_framebuffer(sis_fb_info) < 0) { |
6611 | printk(KERN_ERR "sisfb: Fatal error: Failed to register framebuffer\n"); | 6470 | printk(KERN_ERR "sisfb: Fatal error: Failed to register framebuffer\n"); |
6612 | ret = -EINVAL; | 6471 | ret = -EINVAL; |
@@ -6653,12 +6512,7 @@ error_4: | |||
6653 | 6512 | ||
6654 | 6513 | ||
6655 | printk(KERN_INFO "fb%d: %s frame buffer device version %d.%d.%d\n", | 6514 | printk(KERN_INFO "fb%d: %s frame buffer device version %d.%d.%d\n", |
6656 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | 6515 | sis_fb_info->node, ivideo->myid, VER_MAJOR, VER_MINOR, VER_LEVEL); |
6657 | GET_FB_IDX(sis_fb_info->node), | ||
6658 | #else | ||
6659 | sis_fb_info->node, | ||
6660 | #endif | ||
6661 | ivideo->myid, VER_MAJOR, VER_MINOR, VER_LEVEL); | ||
6662 | 6516 | ||
6663 | printk(KERN_INFO "sisfb: Copyright (C) 2001-2005 Thomas Winischhofer\n"); | 6517 | printk(KERN_INFO "sisfb: Copyright (C) 2001-2005 Thomas Winischhofer\n"); |
6664 | 6518 | ||
@@ -6732,11 +6586,7 @@ static void __devexit sisfb_remove(struct pci_dev *pdev) | |||
6732 | /* Unregister the framebuffer */ | 6586 | /* Unregister the framebuffer */ |
6733 | if(ivideo->registered) { | 6587 | if(ivideo->registered) { |
6734 | unregister_framebuffer(sis_fb_info); | 6588 | unregister_framebuffer(sis_fb_info); |
6735 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,3)) | ||
6736 | framebuffer_release(sis_fb_info); | 6589 | framebuffer_release(sis_fb_info); |
6737 | #else | ||
6738 | kfree(sis_fb_info); | ||
6739 | #endif | ||
6740 | } | 6590 | } |
6741 | 6591 | ||
6742 | /* OK, our ivideo is gone for good from here. */ | 6592 | /* OK, our ivideo is gone for good from here. */ |
@@ -6762,7 +6612,6 @@ static struct pci_driver sisfb_driver = { | |||
6762 | 6612 | ||
6763 | SISINITSTATIC int __init sisfb_init(void) | 6613 | SISINITSTATIC int __init sisfb_init(void) |
6764 | { | 6614 | { |
6765 | #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8) | ||
6766 | #ifndef MODULE | 6615 | #ifndef MODULE |
6767 | char *options = NULL; | 6616 | char *options = NULL; |
6768 | 6617 | ||
@@ -6771,15 +6620,12 @@ SISINITSTATIC int __init sisfb_init(void) | |||
6771 | 6620 | ||
6772 | sisfb_setup(options); | 6621 | sisfb_setup(options); |
6773 | #endif | 6622 | #endif |
6774 | #endif | ||
6775 | return pci_register_driver(&sisfb_driver); | 6623 | return pci_register_driver(&sisfb_driver); |
6776 | } | 6624 | } |
6777 | 6625 | ||
6778 | #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8) | ||
6779 | #ifndef MODULE | 6626 | #ifndef MODULE |
6780 | module_init(sisfb_init); | 6627 | module_init(sisfb_init); |
6781 | #endif | 6628 | #endif |
6782 | #endif | ||
6783 | 6629 | ||
6784 | /*****************************************************/ | 6630 | /*****************************************************/ |
6785 | /* MODULE */ | 6631 | /* MODULE */ |
@@ -6799,9 +6645,6 @@ static int pdc1 = -1; | |||
6799 | static int noaccel = -1; | 6645 | static int noaccel = -1; |
6800 | static int noypan = -1; | 6646 | static int noypan = -1; |
6801 | static int nomax = -1; | 6647 | static int nomax = -1; |
6802 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
6803 | static int inverse = 0; | ||
6804 | #endif | ||
6805 | static int userom = -1; | 6648 | static int userom = -1; |
6806 | static int useoem = -1; | 6649 | static int useoem = -1; |
6807 | static char *tvstandard = NULL; | 6650 | static char *tvstandard = NULL; |
@@ -6861,10 +6704,6 @@ static int __init sisfb_init_module(void) | |||
6861 | else if(nomax == 0) | 6704 | else if(nomax == 0) |
6862 | sisfb_max = 1; | 6705 | sisfb_max = 1; |
6863 | 6706 | ||
6864 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
6865 | if(inverse) sisfb_inverse = 1; | ||
6866 | #endif | ||
6867 | |||
6868 | if(mem) | 6707 | if(mem) |
6869 | sisfb_parm_mem = mem; | 6708 | sisfb_parm_mem = mem; |
6870 | 6709 | ||
@@ -6913,35 +6752,6 @@ MODULE_DESCRIPTION("SiS 300/540/630/730/315/55x/65x/661/74x/330/76x/34x, XGI V3X | |||
6913 | MODULE_LICENSE("GPL"); | 6752 | MODULE_LICENSE("GPL"); |
6914 | MODULE_AUTHOR("Thomas Winischhofer <thomas@winischhofer.net>, Others"); | 6753 | MODULE_AUTHOR("Thomas Winischhofer <thomas@winischhofer.net>, Others"); |
6915 | 6754 | ||
6916 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
6917 | MODULE_PARM(mem, "i"); | ||
6918 | MODULE_PARM(noaccel, "i"); | ||
6919 | MODULE_PARM(noypan, "i"); | ||
6920 | MODULE_PARM(nomax, "i"); | ||
6921 | MODULE_PARM(userom, "i"); | ||
6922 | MODULE_PARM(useoem, "i"); | ||
6923 | MODULE_PARM(mode, "s"); | ||
6924 | MODULE_PARM(vesa, "i"); | ||
6925 | MODULE_PARM(rate, "i"); | ||
6926 | MODULE_PARM(forcecrt1, "i"); | ||
6927 | MODULE_PARM(forcecrt2type, "s"); | ||
6928 | MODULE_PARM(scalelcd, "i"); | ||
6929 | MODULE_PARM(pdc, "i"); | ||
6930 | MODULE_PARM(pdc1, "i"); | ||
6931 | MODULE_PARM(specialtiming, "s"); | ||
6932 | MODULE_PARM(lvdshl, "i"); | ||
6933 | MODULE_PARM(tvstandard, "s"); | ||
6934 | MODULE_PARM(tvxposoffset, "i"); | ||
6935 | MODULE_PARM(tvyposoffset, "i"); | ||
6936 | MODULE_PARM(nocrt2rate, "i"); | ||
6937 | MODULE_PARM(inverse, "i"); | ||
6938 | #if !defined(__i386__) && !defined(__x86_64__) | ||
6939 | MODULE_PARM(resetcard, "i"); | ||
6940 | MODULE_PARM(videoram, "i"); | ||
6941 | #endif | ||
6942 | #endif | ||
6943 | |||
6944 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
6945 | module_param(mem, int, 0); | 6755 | module_param(mem, int, 0); |
6946 | module_param(noaccel, int, 0); | 6756 | module_param(noaccel, int, 0); |
6947 | module_param(noypan, int, 0); | 6757 | module_param(noypan, int, 0); |
@@ -6966,18 +6776,7 @@ module_param(nocrt2rate, int, 0); | |||
6966 | module_param(resetcard, int, 0); | 6776 | module_param(resetcard, int, 0); |
6967 | module_param(videoram, int, 0); | 6777 | module_param(videoram, int, 0); |
6968 | #endif | 6778 | #endif |
6969 | #endif | ||
6970 | 6779 | ||
6971 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
6972 | MODULE_PARM_DESC(mem, | ||
6973 | "\nDetermines the beginning of the video memory heap in KB. This heap is used\n" | ||
6974 | "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n" | ||
6975 | "on the amount of video RAM available. If 8MB of video RAM or less is available,\n" | ||
6976 | "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n" | ||
6977 | "otherwise at 12288KB. On 315/330/340 series, the heap size is 32KB by default.\n" | ||
6978 | "The value is to be specified without 'KB' and must match the MaxXFBMem setting\n" | ||
6979 | "for XFree86 4.x/X.org 6.7 and later.\n"); | ||
6980 | #else | ||
6981 | MODULE_PARM_DESC(mem, | 6780 | MODULE_PARM_DESC(mem, |
6982 | "\nDetermines the beginning of the video memory heap in KB. This heap is used\n" | 6781 | "\nDetermines the beginning of the video memory heap in KB. This heap is used\n" |
6983 | "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n" | 6782 | "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n" |
@@ -6985,7 +6784,6 @@ MODULE_PARM_DESC(mem, | |||
6985 | "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n" | 6784 | "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n" |
6986 | "otherwise at 12288KB. On 315/330/340 series, the heap size is 32KB by default.\n" | 6785 | "otherwise at 12288KB. On 315/330/340 series, the heap size is 32KB by default.\n" |
6987 | "The value is to be specified without 'KB'.\n"); | 6786 | "The value is to be specified without 'KB'.\n"); |
6988 | #endif | ||
6989 | 6787 | ||
6990 | MODULE_PARM_DESC(noaccel, | 6788 | MODULE_PARM_DESC(noaccel, |
6991 | "\nIf set to anything other than 0, 2D acceleration will be disabled.\n" | 6789 | "\nIf set to anything other than 0, 2D acceleration will be disabled.\n" |
@@ -7002,23 +6800,6 @@ MODULE_PARM_DESC(nomax, | |||
7002 | "enable the user to positively specify a virtual Y size of the screen using\n" | 6800 | "enable the user to positively specify a virtual Y size of the screen using\n" |
7003 | "fbset. (default: 0)\n"); | 6801 | "fbset. (default: 0)\n"); |
7004 | 6802 | ||
7005 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
7006 | MODULE_PARM_DESC(mode, | ||
7007 | "\nSelects the desired display mode in the format [X]x[Y]x[Depth], eg.\n" | ||
7008 | "1024x768x16. Other formats supported include XxY-Depth and\n" | ||
7009 | "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n" | ||
7010 | "number, it will be interpreted as a VESA mode number. (default: none if\n" | ||
7011 | "sisfb is a module; this leaves the console untouched and the driver will\n" | ||
7012 | "only do the video memory management for eg. DRM/DRI; 800x600x8 if sisfb\n" | ||
7013 | "is in the kernel)\n"); | ||
7014 | MODULE_PARM_DESC(vesa, | ||
7015 | "\nSelects the desired display mode by VESA defined mode number, eg. 0x117\n" | ||
7016 | "(default: 0x0000 if sisfb is a module; this leaves the console untouched\n" | ||
7017 | "and the driver will only do the video memory management for eg. DRM/DRI;\n" | ||
7018 | "0x0103 if sisfb is in the kernel)\n"); | ||
7019 | #endif | ||
7020 | |||
7021 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
7022 | MODULE_PARM_DESC(mode, | 6803 | MODULE_PARM_DESC(mode, |
7023 | "\nSelects the desired default display mode in the format XxYxDepth,\n" | 6804 | "\nSelects the desired default display mode in the format XxYxDepth,\n" |
7024 | "eg. 1024x768x16. Other formats supported include XxY-Depth and\n" | 6805 | "eg. 1024x768x16. Other formats supported include XxY-Depth and\n" |
@@ -7028,7 +6809,6 @@ MODULE_PARM_DESC(mode, | |||
7028 | MODULE_PARM_DESC(vesa, | 6809 | MODULE_PARM_DESC(vesa, |
7029 | "\nSelects the desired default display mode by VESA defined mode number, eg.\n" | 6810 | "\nSelects the desired default display mode by VESA defined mode number, eg.\n" |
7030 | "0x117 (default: 0x0103)\n"); | 6811 | "0x117 (default: 0x0103)\n"); |
7031 | #endif | ||
7032 | 6812 | ||
7033 | MODULE_PARM_DESC(rate, | 6813 | MODULE_PARM_DESC(rate, |
7034 | "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n" | 6814 | "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n" |
@@ -7094,12 +6874,6 @@ MODULE_PARM_DESC(nocrt2rate, | |||
7094 | "\nSetting this to 1 will force the driver to use the default refresh rate for\n" | 6874 | "\nSetting this to 1 will force the driver to use the default refresh rate for\n" |
7095 | "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n"); | 6875 | "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n"); |
7096 | 6876 | ||
7097 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
7098 | MODULE_PARM_DESC(inverse, | ||
7099 | "\nSetting this to anything but 0 should invert the display colors, but this\n" | ||
7100 | "does not seem to work. (default: 0)\n"); | ||
7101 | #endif | ||
7102 | |||
7103 | #if !defined(__i386__) && !defined(__x86_64__) | 6877 | #if !defined(__i386__) && !defined(__x86_64__) |
7104 | #ifdef CONFIG_FB_SIS_300 | 6878 | #ifdef CONFIG_FB_SIS_300 |
7105 | MODULE_PARM_DESC(resetcard, | 6879 | MODULE_PARM_DESC(resetcard, |
diff --git a/drivers/video/sis/sis_main.h b/drivers/video/sis/sis_main.h index 70b6df371b8e..88e4f1e41470 100644 --- a/drivers/video/sis/sis_main.h +++ b/drivers/video/sis/sis_main.h | |||
@@ -67,15 +67,7 @@ static int sisfb_ypan = -1; | |||
67 | static int sisfb_max = -1; | 67 | static int sisfb_max = -1; |
68 | static int sisfb_userom = 1; | 68 | static int sisfb_userom = 1; |
69 | static int sisfb_useoem = -1; | 69 | static int sisfb_useoem = -1; |
70 | #ifdef MODULE | ||
71 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
72 | static int sisfb_mode_idx = -1; | ||
73 | #else | ||
74 | static int sisfb_mode_idx = MODE_INDEX_NONE; /* Don't use a mode by default if we are a module */ | ||
75 | #endif | ||
76 | #else | ||
77 | static int sisfb_mode_idx = -1; /* Use a default mode if we are inside the kernel */ | 70 | static int sisfb_mode_idx = -1; /* Use a default mode if we are inside the kernel */ |
78 | #endif | ||
79 | static int sisfb_parm_rate = -1; | 71 | static int sisfb_parm_rate = -1; |
80 | static int sisfb_crt1off = 0; | 72 | static int sisfb_crt1off = 0; |
81 | static int sisfb_forcecrt1 = -1; | 73 | static int sisfb_forcecrt1 = -1; |
@@ -93,10 +85,6 @@ static int sisfb_tvstd = -1; | |||
93 | static int sisfb_tvxposoffset = 0; | 85 | static int sisfb_tvxposoffset = 0; |
94 | static int sisfb_tvyposoffset = 0; | 86 | static int sisfb_tvyposoffset = 0; |
95 | static int sisfb_nocrt2rate = 0; | 87 | static int sisfb_nocrt2rate = 0; |
96 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
97 | static int sisfb_inverse = 0; | ||
98 | static char sisfb_fontname[40]; | ||
99 | #endif | ||
100 | #if !defined(__i386__) && !defined(__x86_64__) | 88 | #if !defined(__i386__) && !defined(__x86_64__) |
101 | static int sisfb_resetcard = 0; | 89 | static int sisfb_resetcard = 0; |
102 | static int sisfb_videoram = 0; | 90 | static int sisfb_videoram = 0; |
@@ -687,54 +675,8 @@ SISINITSTATIC int sisfb_init(void); | |||
687 | static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, | 675 | static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, |
688 | struct fb_info *info); | 676 | struct fb_info *info); |
689 | 677 | ||
690 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
691 | static int sisfb_get_fix(struct fb_fix_screeninfo *fix, | ||
692 | int con, | ||
693 | struct fb_info *info); | ||
694 | static int sisfb_get_var(struct fb_var_screeninfo *var, | ||
695 | int con, | ||
696 | struct fb_info *info); | ||
697 | static int sisfb_set_var(struct fb_var_screeninfo *var, | ||
698 | int con, | ||
699 | struct fb_info *info); | ||
700 | static void sisfb_crtc_to_var(struct sis_video_info *ivideo, | ||
701 | struct fb_var_screeninfo *var); | ||
702 | static int sisfb_get_cmap(struct fb_cmap *cmap, | ||
703 | int kspc, | ||
704 | int con, | ||
705 | struct fb_info *info); | ||
706 | static int sisfb_set_cmap(struct fb_cmap *cmap, | ||
707 | int kspc, | ||
708 | int con, | ||
709 | struct fb_info *info); | ||
710 | static int sisfb_update_var(int con, | ||
711 | struct fb_info *info); | ||
712 | static int sisfb_switch(int con, | ||
713 | struct fb_info *info); | ||
714 | static void sisfb_blank(int blank, | ||
715 | struct fb_info *info); | ||
716 | static void sisfb_set_disp(int con, | ||
717 | struct fb_var_screeninfo *var, | ||
718 | struct fb_info *info); | ||
719 | static int sis_getcolreg(unsigned regno, unsigned *red, unsigned *green, | ||
720 | unsigned *blue, unsigned *transp, | ||
721 | struct fb_info *fb_info); | ||
722 | static void sisfb_do_install_cmap(int con, | ||
723 | struct fb_info *info); | ||
724 | static int sisfb_ioctl(struct inode *inode, struct file *file, | ||
725 | unsigned int cmd, unsigned long arg, int con, | ||
726 | struct fb_info *info); | ||
727 | #endif | ||
728 | |||
729 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
730 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) | ||
731 | static int sisfb_ioctl(struct fb_info *info, unsigned int cmd, | 678 | static int sisfb_ioctl(struct fb_info *info, unsigned int cmd, |
732 | unsigned long arg); | 679 | unsigned long arg); |
733 | #else | ||
734 | static int sisfb_ioctl(struct inode *inode, struct file *file, | ||
735 | unsigned int cmd, unsigned long arg, | ||
736 | struct fb_info *info); | ||
737 | #endif | ||
738 | static int sisfb_set_par(struct fb_info *info); | 680 | static int sisfb_set_par(struct fb_info *info); |
739 | static int sisfb_blank(int blank, | 681 | static int sisfb_blank(int blank, |
740 | struct fb_info *info); | 682 | struct fb_info *info); |
@@ -743,7 +685,6 @@ extern void fbcon_sis_fillrect(struct fb_info *info, | |||
743 | extern void fbcon_sis_copyarea(struct fb_info *info, | 685 | extern void fbcon_sis_copyarea(struct fb_info *info, |
744 | const struct fb_copyarea *area); | 686 | const struct fb_copyarea *area); |
745 | extern int fbcon_sis_sync(struct fb_info *info); | 687 | extern int fbcon_sis_sync(struct fb_info *info); |
746 | #endif | ||
747 | 688 | ||
748 | /* Internal 2D accelerator functions */ | 689 | /* Internal 2D accelerator functions */ |
749 | extern int sisfb_initaccel(struct sis_video_info *ivideo); | 690 | extern int sisfb_initaccel(struct sis_video_info *ivideo); |
@@ -811,16 +752,10 @@ extern BOOLEAN SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr); | |||
811 | 752 | ||
812 | extern BOOLEAN sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno, | 753 | extern BOOLEAN sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno, |
813 | int *htotal, int *vtotal, unsigned char rateindex); | 754 | int *htotal, int *vtotal, unsigned char rateindex); |
814 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
815 | extern int sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr, | 755 | extern int sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr, |
816 | unsigned char modeno, unsigned char rateindex); | 756 | unsigned char modeno, unsigned char rateindex); |
817 | extern int sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno, | 757 | extern int sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno, |
818 | unsigned char rateindex, struct fb_var_screeninfo *var); | 758 | unsigned char rateindex, struct fb_var_screeninfo *var); |
819 | #endif | ||
820 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
821 | extern void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres, | ||
822 | int yres, struct fb_var_screeninfo *var, BOOLEAN writeres); | ||
823 | #endif | ||
824 | 759 | ||
825 | /* Chrontel TV, DDC and DPMS functions */ | 760 | /* Chrontel TV, DDC and DPMS functions */ |
826 | extern unsigned short SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg); | 761 | extern unsigned short SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg); |
diff --git a/drivers/video/sis/vgatypes.h b/drivers/video/sis/vgatypes.h index 831b9f42264b..05d08b7889a1 100644 --- a/drivers/video/sis/vgatypes.h +++ b/drivers/video/sis/vgatypes.h | |||
@@ -73,12 +73,10 @@ typedef unsigned int BOOLEAN; | |||
73 | 73 | ||
74 | #ifdef SIS_LINUX_KERNEL | 74 | #ifdef SIS_LINUX_KERNEL |
75 | typedef unsigned long SISIOADDRESS; | 75 | typedef unsigned long SISIOADDRESS; |
76 | #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8) | ||
77 | #include <linux/types.h> /* Need __iomem */ | 76 | #include <linux/types.h> /* Need __iomem */ |
78 | #undef SISIOMEMTYPE | 77 | #undef SISIOMEMTYPE |
79 | #define SISIOMEMTYPE __iomem | 78 | #define SISIOMEMTYPE __iomem |
80 | #endif | 79 | #endif |
81 | #endif | ||
82 | 80 | ||
83 | #ifdef SIS_XORG_XF86 | 81 | #ifdef SIS_XORG_XF86 |
84 | #if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,0,0,0) | 82 | #if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,0,0,0) |
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c index dad54e73147b..711cb11d6eb3 100644 --- a/drivers/video/sstfb.c +++ b/drivers/video/sstfb.c | |||
@@ -17,7 +17,10 @@ | |||
17 | * (port driver to new frambuffer infrastructure) | 17 | * (port driver to new frambuffer infrastructure) |
18 | * 01/2003 Helge Deller <deller@gmx.de> | 18 | * 01/2003 Helge Deller <deller@gmx.de> |
19 | * (initial work on fb hardware acceleration for voodoo2) | 19 | * (initial work on fb hardware acceleration for voodoo2) |
20 | * | 20 | * 08/2006 Alan Cox <alan@redhat.com> |
21 | * Remove never finished and bogus 24/32bit support | ||
22 | * Clean up macro abuse | ||
23 | * Minor tidying for format. | ||
21 | */ | 24 | */ |
22 | 25 | ||
23 | /* | 26 | /* |
@@ -40,6 +43,7 @@ | |||
40 | through the fifo. warning: issuing a nop command seems to need pci_fifo | 43 | through the fifo. warning: issuing a nop command seems to need pci_fifo |
41 | -FIXME: in case of failure in the init sequence, be sure we return to a safe | 44 | -FIXME: in case of failure in the init sequence, be sure we return to a safe |
42 | state. | 45 | state. |
46 | - FIXME: Use accelerator for 2D scroll | ||
43 | -FIXME: 4MB boards have banked memory (FbiInit2 bits 1 & 20) | 47 | -FIXME: 4MB boards have banked memory (FbiInit2 bits 1 & 20) |
44 | */ | 48 | */ |
45 | 49 | ||
@@ -67,9 +71,6 @@ | |||
67 | 71 | ||
68 | #undef SST_DEBUG | 72 | #undef SST_DEBUG |
69 | 73 | ||
70 | /* enable 24/32 bpp functions ? (completely untested!) */ | ||
71 | #undef EN_24_32_BPP | ||
72 | |||
73 | /* | 74 | /* |
74 | Default video mode . | 75 | Default video mode . |
75 | 0 800x600@60 took from glide | 76 | 0 800x600@60 took from glide |
@@ -377,7 +378,11 @@ static void sstfb_clear_screen(struct fb_info *info) | |||
377 | * sstfb_check_var - Optional function. Validates a var passed in. | 378 | * sstfb_check_var - Optional function. Validates a var passed in. |
378 | * @var: frame buffer variable screen structure | 379 | * @var: frame buffer variable screen structure |
379 | * @info: frame buffer structure that represents a single frame buffer | 380 | * @info: frame buffer structure that represents a single frame buffer |
381 | * | ||
382 | * Limit to the abilities of a single chip as SLI is not supported | ||
383 | * by this driver. | ||
380 | */ | 384 | */ |
385 | |||
381 | static int sstfb_check_var(struct fb_var_screeninfo *var, | 386 | static int sstfb_check_var(struct fb_var_screeninfo *var, |
382 | struct fb_info *info) | 387 | struct fb_info *info) |
383 | { | 388 | { |
@@ -390,7 +395,7 @@ static int sstfb_check_var(struct fb_var_screeninfo *var, | |||
390 | unsigned int freq; | 395 | unsigned int freq; |
391 | 396 | ||
392 | if (sst_calc_pll(PICOS2KHZ(var->pixclock), &freq, &par->pll)) { | 397 | if (sst_calc_pll(PICOS2KHZ(var->pixclock), &freq, &par->pll)) { |
393 | eprintk("Pixclock at %ld KHZ out of range\n", | 398 | printk(KERN_ERR "sstfb: Pixclock at %ld KHZ out of range\n", |
394 | PICOS2KHZ(var->pixclock)); | 399 | PICOS2KHZ(var->pixclock)); |
395 | return -EINVAL; | 400 | return -EINVAL; |
396 | } | 401 | } |
@@ -409,27 +414,15 @@ static int sstfb_check_var(struct fb_var_screeninfo *var, | |||
409 | case 0 ... 16 : | 414 | case 0 ... 16 : |
410 | var->bits_per_pixel = 16; | 415 | var->bits_per_pixel = 16; |
411 | break; | 416 | break; |
412 | #ifdef EN_24_32_BPP | ||
413 | case 17 ... 24 : | ||
414 | var->bits_per_pixel = 24; | ||
415 | break; | ||
416 | case 25 ... 32 : | ||
417 | var->bits_per_pixel = 32; | ||
418 | break; | ||
419 | #endif | ||
420 | default : | 417 | default : |
421 | eprintk("Unsupported bpp %d\n", var->bits_per_pixel); | 418 | printk(KERN_ERR "sstfb: Unsupported bpp %d\n", var->bits_per_pixel); |
422 | return -EINVAL; | 419 | return -EINVAL; |
423 | } | 420 | } |
424 | 421 | ||
425 | /* validity tests */ | 422 | /* validity tests */ |
426 | if ((var->xres <= 1) || (yDim <= 0 ) | 423 | if (var->xres <= 1 || yDim <= 0 || var->hsync_len <= 1 || |
427 | || (var->hsync_len <= 1) | 424 | hSyncOff <= 1 || var->left_margin <= 2 || vSyncOn <= 0 || |
428 | || (hSyncOff <= 1) | 425 | vSyncOff <= 0 || vBackPorch <= 0) { |
429 | || (var->left_margin <= 2) | ||
430 | || (vSyncOn <= 0) | ||
431 | || (vSyncOff <= 0) | ||
432 | || (vBackPorch <= 0)) { | ||
433 | return -EINVAL; | 426 | return -EINVAL; |
434 | } | 427 | } |
435 | 428 | ||
@@ -437,21 +430,17 @@ static int sstfb_check_var(struct fb_var_screeninfo *var, | |||
437 | /* Voodoo 2 limits */ | 430 | /* Voodoo 2 limits */ |
438 | tiles_in_X = (var->xres + 63 ) / 64 * 2; | 431 | tiles_in_X = (var->xres + 63 ) / 64 * 2; |
439 | 432 | ||
440 | if (((var->xres - 1) >= POW2(11)) || (yDim >= POW2(11))) { | 433 | if (var->xres > POW2(11) || yDim >= POW2(11)) { |
441 | eprintk("Unsupported resolution %dx%d\n", | 434 | printk(KERN_ERR "sstfb: Unsupported resolution %dx%d\n", |
442 | var->xres, var->yres); | 435 | var->xres, var->yres); |
443 | return -EINVAL; | 436 | return -EINVAL; |
444 | } | 437 | } |
445 | 438 | ||
446 | if (((var->hsync_len-1) >= POW2(9)) | 439 | if (var->hsync_len > POW2(9) || hSyncOff > POW2(11) || |
447 | || ((hSyncOff-1) >= POW2(11)) | 440 | var->left_margin - 2 >= POW2(9) || vSyncOn >= POW2(13) || |
448 | || ((var->left_margin - 2) >= POW2(9)) | 441 | vSyncOff >= POW2(13) || vBackPorch >= POW2(9) || |
449 | || (vSyncOn >= POW2(13)) | 442 | tiles_in_X >= POW2(6) || tiles_in_X <= 0) { |
450 | || (vSyncOff >= POW2(13)) | 443 | printk(KERN_ERR "sstfb: Unsupported timings\n"); |
451 | || (vBackPorch >= POW2(9)) | ||
452 | || (tiles_in_X >= POW2(6)) | ||
453 | || (tiles_in_X <= 0)) { | ||
454 | eprintk("Unsupported Timings\n"); | ||
455 | return -EINVAL; | 444 | return -EINVAL; |
456 | } | 445 | } |
457 | } else { | 446 | } else { |
@@ -459,24 +448,20 @@ static int sstfb_check_var(struct fb_var_screeninfo *var, | |||
459 | tiles_in_X = (var->xres + 63 ) / 64; | 448 | tiles_in_X = (var->xres + 63 ) / 64; |
460 | 449 | ||
461 | if (var->vmode) { | 450 | if (var->vmode) { |
462 | eprintk("Interlace/Doublescan not supported %#x\n", | 451 | printk(KERN_ERR "sstfb: Interlace/doublescan not supported %#x\n", |
463 | var->vmode); | 452 | var->vmode); |
464 | return -EINVAL; | 453 | return -EINVAL; |
465 | } | 454 | } |
466 | if (((var->xres - 1) >= POW2(10)) || (var->yres >= POW2(10))) { | 455 | if (var->xres > POW2(10) || var->yres >= POW2(10)) { |
467 | eprintk("Unsupported resolution %dx%d\n", | 456 | printk(KERN_ERR "sstfb: Unsupported resolution %dx%d\n", |
468 | var->xres, var->yres); | 457 | var->xres, var->yres); |
469 | return -EINVAL; | 458 | return -EINVAL; |
470 | } | 459 | } |
471 | if (((var->hsync_len - 1) >= POW2(8)) | 460 | if (var->hsync_len > POW2(8) || hSyncOff - 1 > POW2(10) || |
472 | || ((hSyncOff-1) >= POW2(10)) | 461 | var->left_margin - 2 >= POW2(8) || vSyncOn >= POW2(12) || |
473 | || ((var->left_margin - 2) >= POW2(8)) | 462 | vSyncOff >= POW2(12) || vBackPorch >= POW2(8) || |
474 | || (vSyncOn >= POW2(12)) | 463 | tiles_in_X >= POW2(4) || tiles_in_X <= 0) { |
475 | || (vSyncOff >= POW2(12)) | 464 | printk(KERN_ERR "sstfb: Unsupported timings\n"); |
476 | || (vBackPorch >= POW2(8)) | ||
477 | || (tiles_in_X >= POW2(4)) | ||
478 | || (tiles_in_X <= 0)) { | ||
479 | eprintk("Unsupported Timings\n"); | ||
480 | return -EINVAL; | 465 | return -EINVAL; |
481 | } | 466 | } |
482 | } | 467 | } |
@@ -486,8 +471,8 @@ static int sstfb_check_var(struct fb_var_screeninfo *var, | |||
486 | real_length = tiles_in_X * (IS_VOODOO2(par) ? 32 : 64 ) | 471 | real_length = tiles_in_X * (IS_VOODOO2(par) ? 32 : 64 ) |
487 | * ((var->bits_per_pixel == 16) ? 2 : 4); | 472 | * ((var->bits_per_pixel == 16) ? 2 : 4); |
488 | 473 | ||
489 | if ((real_length * yDim) > info->fix.smem_len) { | 474 | if (real_length * yDim > info->fix.smem_len) { |
490 | eprintk("Not enough video memory\n"); | 475 | printk(KERN_ERR "sstfb: Not enough video memory\n"); |
491 | return -ENOMEM; | 476 | return -ENOMEM; |
492 | } | 477 | } |
493 | 478 | ||
@@ -515,20 +500,6 @@ static int sstfb_check_var(struct fb_var_screeninfo *var, | |||
515 | var->blue.offset = 0; | 500 | var->blue.offset = 0; |
516 | var->transp.offset = 0; | 501 | var->transp.offset = 0; |
517 | break; | 502 | break; |
518 | #ifdef EN_24_32_BPP | ||
519 | case 24: /* RGB 888 LfbMode 4 */ | ||
520 | case 32: /* ARGB 8888 LfbMode 5 */ | ||
521 | var->red.length = 8; | ||
522 | var->green.length = 8; | ||
523 | var->blue.length = 8; | ||
524 | var->transp.length = 0; | ||
525 | |||
526 | var->red.offset = 16; | ||
527 | var->green.offset = 8; | ||
528 | var->blue.offset = 0; | ||
529 | var->transp.offset = 0; /* in 24bpp we fake a 32 bpp mode */ | ||
530 | break; | ||
531 | #endif | ||
532 | default: | 503 | default: |
533 | return -EINVAL; | 504 | return -EINVAL; |
534 | } | 505 | } |
@@ -653,13 +624,6 @@ static int sstfb_set_par(struct fb_info *info) | |||
653 | case 16: | 624 | case 16: |
654 | fbiinit1 |= SEL_SOURCE_VCLK_2X_SEL; | 625 | fbiinit1 |= SEL_SOURCE_VCLK_2X_SEL; |
655 | break; | 626 | break; |
656 | #ifdef EN_24_32_BPP | ||
657 | case 24: | ||
658 | case 32: | ||
659 | /* sst_set_bits(FBIINIT1, SEL_SOURCE_VCLK_2X_DIV2 | EN_24BPP);*/ | ||
660 | fbiinit1 |= SEL_SOURCE_VCLK_2X_SEL | EN_24BPP; | ||
661 | break; | ||
662 | #endif | ||
663 | default: | 627 | default: |
664 | return -EINVAL; | 628 | return -EINVAL; |
665 | } | 629 | } |
@@ -690,14 +654,6 @@ static int sstfb_set_par(struct fb_info *info) | |||
690 | case 16: | 654 | case 16: |
691 | lfbmode = LFB_565; | 655 | lfbmode = LFB_565; |
692 | break; | 656 | break; |
693 | #ifdef EN_24_32_BPP | ||
694 | case 24: | ||
695 | lfbmode = LFB_888; | ||
696 | break; | ||
697 | case 32: | ||
698 | lfbmode = LFB_8888; | ||
699 | break; | ||
700 | #endif | ||
701 | default: | 657 | default: |
702 | return -EINVAL; | 658 | return -EINVAL; |
703 | } | 659 | } |
@@ -789,8 +745,7 @@ static int sstfb_ioctl(struct fb_info *info, u_int cmd, u_long arg) | |||
789 | return -EFAULT; | 745 | return -EFAULT; |
790 | if (val > info->fix.smem_len) | 746 | if (val > info->fix.smem_len) |
791 | val = info->fix.smem_len; | 747 | val = info->fix.smem_len; |
792 | printk("filling %#x \n", val); | 748 | for (p = 0 ; p < val; p += 2) |
793 | for (p=0 ; p<val; p+=2) | ||
794 | writew(p >> 6, info->screen_base + p); | 749 | writew(p >> 6, info->screen_base + p); |
795 | return 0; | 750 | return 0; |
796 | 751 | ||
@@ -802,13 +757,10 @@ static int sstfb_ioctl(struct fb_info *info, u_int cmd, u_long arg) | |||
802 | pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, | 757 | pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, |
803 | tmp | PCI_EN_INIT_WR ); | 758 | tmp | PCI_EN_INIT_WR ); |
804 | fbiinit0 = sst_read (FBIINIT0); | 759 | fbiinit0 = sst_read (FBIINIT0); |
805 | if (val) { | 760 | if (val) |
806 | sst_write(FBIINIT0, fbiinit0 & ~EN_VGA_PASSTHROUGH); | 761 | sst_write(FBIINIT0, fbiinit0 & ~EN_VGA_PASSTHROUGH); |
807 | iprintk("Disabling VGA pass-through\n"); | 762 | else |
808 | } else { | ||
809 | sst_write(FBIINIT0, fbiinit0 | EN_VGA_PASSTHROUGH); | 763 | sst_write(FBIINIT0, fbiinit0 | EN_VGA_PASSTHROUGH); |
810 | iprintk("Enabling VGA pass-through\n"); | ||
811 | } | ||
812 | pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, tmp); | 764 | pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, tmp); |
813 | return 0; | 765 | return 0; |
814 | 766 | ||
@@ -884,9 +836,9 @@ static int __devinit sst_get_memsize(struct fb_info *info, __u32 *memsize) | |||
884 | u8 __iomem *fbbase_virt = info->screen_base; | 836 | u8 __iomem *fbbase_virt = info->screen_base; |
885 | 837 | ||
886 | /* force memsize */ | 838 | /* force memsize */ |
887 | if ((mem >= 1 ) && (mem <= 4)) { | 839 | if (mem >= 1 && mem <= 4) { |
888 | *memsize = (mem * 0x100000); | 840 | *memsize = (mem * 0x100000); |
889 | iprintk("supplied memsize: %#x\n", *memsize); | 841 | printk(KERN_INFO "supplied memsize: %#x\n", *memsize); |
890 | return 1; | 842 | return 1; |
891 | } | 843 | } |
892 | 844 | ||
@@ -927,7 +879,7 @@ static int __devinit sst_detect_att(struct fb_info *info) | |||
927 | struct sstfb_par *par = info->par; | 879 | struct sstfb_par *par = info->par; |
928 | int i, mir, dir; | 880 | int i, mir, dir; |
929 | 881 | ||
930 | for (i=0; i<3; i++) { | 882 | for (i = 0; i < 3; i++) { |
931 | sst_dac_write(DACREG_WMA, 0); /* backdoor */ | 883 | sst_dac_write(DACREG_WMA, 0); /* backdoor */ |
932 | sst_dac_read(DACREG_RMR); /* read 4 times RMR */ | 884 | sst_dac_read(DACREG_RMR); /* read 4 times RMR */ |
933 | sst_dac_read(DACREG_RMR); | 885 | sst_dac_read(DACREG_RMR); |
@@ -940,7 +892,7 @@ static int __devinit sst_detect_att(struct fb_info *info) | |||
940 | /*the 7th, device ID register */ | 892 | /*the 7th, device ID register */ |
941 | dir = sst_dac_read(DACREG_RMR); | 893 | dir = sst_dac_read(DACREG_RMR); |
942 | f_ddprintk("mir: %#x, dir: %#x\n", mir, dir); | 894 | f_ddprintk("mir: %#x, dir: %#x\n", mir, dir); |
943 | if ((mir == DACREG_MIR_ATT ) && (dir == DACREG_DIR_ATT)) { | 895 | if (mir == DACREG_MIR_ATT && dir == DACREG_DIR_ATT) { |
944 | return 1; | 896 | return 1; |
945 | } | 897 | } |
946 | } | 898 | } |
@@ -1134,12 +1086,6 @@ static void sst_set_vidmod_att_ti(struct fb_info *info, const int bpp) | |||
1134 | case 16: | 1086 | case 16: |
1135 | sst_dac_write(DACREG_RMR, (cr0 & 0x0f) | DACREG_CR0_16BPP); | 1087 | sst_dac_write(DACREG_RMR, (cr0 & 0x0f) | DACREG_CR0_16BPP); |
1136 | break; | 1088 | break; |
1137 | #ifdef EN_24_32_BPP | ||
1138 | case 24: | ||
1139 | case 32: | ||
1140 | sst_dac_write(DACREG_RMR, (cr0 & 0x0f) | DACREG_CR0_24BPP); | ||
1141 | break; | ||
1142 | #endif | ||
1143 | default: | 1089 | default: |
1144 | dprintk("%s: bad depth '%u'\n", __FUNCTION__, bpp); | 1090 | dprintk("%s: bad depth '%u'\n", __FUNCTION__, bpp); |
1145 | break; | 1091 | break; |
@@ -1154,12 +1100,6 @@ static void sst_set_vidmod_ics(struct fb_info *info, const int bpp) | |||
1154 | case 16: | 1100 | case 16: |
1155 | sst_dac_write(DACREG_ICS_CMD, DACREG_ICS_CMD_16BPP); | 1101 | sst_dac_write(DACREG_ICS_CMD, DACREG_ICS_CMD_16BPP); |
1156 | break; | 1102 | break; |
1157 | #ifdef EN_24_32_BPP | ||
1158 | case 24: | ||
1159 | case 32: | ||
1160 | sst_dac_write(DACREG_ICS_CMD, DACREG_ICS_CMD_24BPP); | ||
1161 | break; | ||
1162 | #endif | ||
1163 | default: | 1103 | default: |
1164 | dprintk("%s: bad depth '%u'\n", __FUNCTION__, bpp); | 1104 | dprintk("%s: bad depth '%u'\n", __FUNCTION__, bpp); |
1165 | break; | 1105 | break; |
@@ -1250,7 +1190,7 @@ static int __devinit sst_init(struct fb_info *info, struct sstfb_par *par) | |||
1250 | PCI_EN_INIT_WR | PCI_REMAP_DAC ); | 1190 | PCI_EN_INIT_WR | PCI_REMAP_DAC ); |
1251 | /* detect dac type */ | 1191 | /* detect dac type */ |
1252 | if (!sst_detect_dactype(info, par)) { | 1192 | if (!sst_detect_dactype(info, par)) { |
1253 | eprintk("Unknown dac type\n"); | 1193 | printk(KERN_ERR "sstfb: unknown dac type.\n"); |
1254 | //FIXME watch it: we are not in a safe state, bad bad bad. | 1194 | //FIXME watch it: we are not in a safe state, bad bad bad. |
1255 | return 0; | 1195 | return 0; |
1256 | } | 1196 | } |
@@ -1258,10 +1198,10 @@ static int __devinit sst_init(struct fb_info *info, struct sstfb_par *par) | |||
1258 | /* set graphic clock */ | 1198 | /* set graphic clock */ |
1259 | par->gfx_clock = spec->default_gfx_clock; | 1199 | par->gfx_clock = spec->default_gfx_clock; |
1260 | if ((gfxclk >10 ) && (gfxclk < spec->max_gfxclk)) { | 1200 | if ((gfxclk >10 ) && (gfxclk < spec->max_gfxclk)) { |
1261 | iprintk("Using supplied graphic freq : %dMHz\n", gfxclk); | 1201 | printk(KERN_INFO "sstfb: Using supplied graphic freq : %dMHz\n", gfxclk); |
1262 | par->gfx_clock = gfxclk *1000; | 1202 | par->gfx_clock = gfxclk *1000; |
1263 | } else if (gfxclk) { | 1203 | } else if (gfxclk) { |
1264 | wprintk ("%dMhz is way out of spec! Using default\n", gfxclk); | 1204 | printk(KERN_WARNING "sstfb: %dMhz is way out of spec! Using default\n", gfxclk); |
1265 | } | 1205 | } |
1266 | 1206 | ||
1267 | sst_calc_pll(par->gfx_clock, &Fout, &gfx_timings); | 1207 | sst_calc_pll(par->gfx_clock, &Fout, &gfx_timings); |
@@ -1396,7 +1336,7 @@ static int __devinit sstfb_probe(struct pci_dev *pdev, | |||
1396 | 1336 | ||
1397 | /* Enable device in PCI config. */ | 1337 | /* Enable device in PCI config. */ |
1398 | if ((err=pci_enable_device(pdev))) { | 1338 | if ((err=pci_enable_device(pdev))) { |
1399 | eprintk("cannot enable device\n"); | 1339 | printk(KERN_ERR "cannot enable device\n"); |
1400 | return err; | 1340 | return err; |
1401 | } | 1341 | } |
1402 | 1342 | ||
@@ -1422,39 +1362,39 @@ static int __devinit sstfb_probe(struct pci_dev *pdev, | |||
1422 | fix->smem_start = fix->mmio_start + 0x400000; | 1362 | fix->smem_start = fix->mmio_start + 0x400000; |
1423 | 1363 | ||
1424 | if (!request_mem_region(fix->mmio_start, fix->mmio_len, "sstfb MMIO")) { | 1364 | if (!request_mem_region(fix->mmio_start, fix->mmio_len, "sstfb MMIO")) { |
1425 | eprintk("cannot reserve mmio memory\n"); | 1365 | printk(KERN_ERR "sstfb: cannot reserve mmio memory\n"); |
1426 | goto fail_mmio_mem; | 1366 | goto fail_mmio_mem; |
1427 | } | 1367 | } |
1428 | 1368 | ||
1429 | if (!request_mem_region(fix->smem_start, 0x400000,"sstfb FB")) { | 1369 | if (!request_mem_region(fix->smem_start, 0x400000,"sstfb FB")) { |
1430 | eprintk("cannot reserve fb memory\n"); | 1370 | printk(KERN_ERR "sstfb: cannot reserve fb memory\n"); |
1431 | goto fail_fb_mem; | 1371 | goto fail_fb_mem; |
1432 | } | 1372 | } |
1433 | 1373 | ||
1434 | par->mmio_vbase = ioremap_nocache(fix->mmio_start, | 1374 | par->mmio_vbase = ioremap_nocache(fix->mmio_start, |
1435 | fix->mmio_len); | 1375 | fix->mmio_len); |
1436 | if (!par->mmio_vbase) { | 1376 | if (!par->mmio_vbase) { |
1437 | eprintk("cannot remap register area %#lx\n", | 1377 | printk(KERN_ERR "sstfb: cannot remap register area %#lx\n", |
1438 | fix->mmio_start); | 1378 | fix->mmio_start); |
1439 | goto fail_mmio_remap; | 1379 | goto fail_mmio_remap; |
1440 | } | 1380 | } |
1441 | info->screen_base = ioremap_nocache(fix->smem_start, 0x400000); | 1381 | info->screen_base = ioremap_nocache(fix->smem_start, 0x400000); |
1442 | if (!info->screen_base) { | 1382 | if (!info->screen_base) { |
1443 | eprintk("cannot remap framebuffer %#lx\n", | 1383 | printk(KERN_ERR "sstfb: cannot remap framebuffer %#lx\n", |
1444 | fix->smem_start); | 1384 | fix->smem_start); |
1445 | goto fail_fb_remap; | 1385 | goto fail_fb_remap; |
1446 | } | 1386 | } |
1447 | 1387 | ||
1448 | if (!sst_init(info, par)) { | 1388 | if (!sst_init(info, par)) { |
1449 | eprintk("Init failed\n"); | 1389 | printk(KERN_ERR "sstfb: Init failed\n"); |
1450 | goto fail; | 1390 | goto fail; |
1451 | } | 1391 | } |
1452 | sst_get_memsize(info, &fix->smem_len); | 1392 | sst_get_memsize(info, &fix->smem_len); |
1453 | strlcpy(fix->id, spec->name, sizeof(fix->id)); | 1393 | strlcpy(fix->id, spec->name, sizeof(fix->id)); |
1454 | 1394 | ||
1455 | iprintk("%s (revision %d) with %s dac\n", | 1395 | printk(KERN_INFO "%s (revision %d) with %s dac\n", |
1456 | fix->id, par->revision, par->dac_sw.name); | 1396 | fix->id, par->revision, par->dac_sw.name); |
1457 | iprintk("framebuffer at %#lx, mapped to 0x%p, size %dMB\n", | 1397 | printk(KERN_INFO "framebuffer at %#lx, mapped to 0x%p, size %dMB\n", |
1458 | fix->smem_start, info->screen_base, | 1398 | fix->smem_start, info->screen_base, |
1459 | fix->smem_len >> 20); | 1399 | fix->smem_len >> 20); |
1460 | 1400 | ||
@@ -1471,24 +1411,25 @@ static int __devinit sstfb_probe(struct pci_dev *pdev, | |||
1471 | fix->accel = FB_ACCEL_NONE; /* FIXME */ | 1411 | fix->accel = FB_ACCEL_NONE; /* FIXME */ |
1472 | /* | 1412 | /* |
1473 | * According to the specs, the linelength must be of 1024 *pixels* | 1413 | * According to the specs, the linelength must be of 1024 *pixels* |
1474 | * and the 24bpp mode is in fact a 32 bpp mode. | 1414 | * and the 24bpp mode is in fact a 32 bpp mode (and both are in |
1415 | * fact dithered to 16bit). | ||
1475 | */ | 1416 | */ |
1476 | fix->line_length = 2048; /* default value, for 24 or 32bit: 4096 */ | 1417 | fix->line_length = 2048; /* default value, for 24 or 32bit: 4096 */ |
1477 | 1418 | ||
1478 | if ( mode_option && | 1419 | if ( mode_option && |
1479 | fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 16)) { | 1420 | fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 16)) { |
1480 | eprintk("can't set supplied video mode. Using default\n"); | 1421 | printk(KERN_ERR "sstfb: can't set supplied video mode. Using default\n"); |
1481 | info->var = sstfb_default; | 1422 | info->var = sstfb_default; |
1482 | } else | 1423 | } else |
1483 | info->var = sstfb_default; | 1424 | info->var = sstfb_default; |
1484 | 1425 | ||
1485 | if (sstfb_check_var(&info->var, info)) { | 1426 | if (sstfb_check_var(&info->var, info)) { |
1486 | eprintk("invalid default video mode.\n"); | 1427 | printk(KERN_ERR "sstfb: invalid default video mode.\n"); |
1487 | goto fail; | 1428 | goto fail; |
1488 | } | 1429 | } |
1489 | 1430 | ||
1490 | if (sstfb_set_par(info)) { | 1431 | if (sstfb_set_par(info)) { |
1491 | eprintk("can't set default video mode.\n"); | 1432 | printk(KERN_ERR "sstfb: can't set default video mode.\n"); |
1492 | goto fail; | 1433 | goto fail; |
1493 | } | 1434 | } |
1494 | 1435 | ||
@@ -1497,7 +1438,7 @@ static int __devinit sstfb_probe(struct pci_dev *pdev, | |||
1497 | /* register fb */ | 1438 | /* register fb */ |
1498 | info->device = &pdev->dev; | 1439 | info->device = &pdev->dev; |
1499 | if (register_framebuffer(info) < 0) { | 1440 | if (register_framebuffer(info) < 0) { |
1500 | eprintk("can't register framebuffer.\n"); | 1441 | printk(KERN_ERR "sstfb: can't register framebuffer.\n"); |
1501 | goto fail; | 1442 | goto fail; |
1502 | } | 1443 | } |
1503 | 1444 | ||
@@ -1711,4 +1652,3 @@ module_param(gfxclk, int, 0); | |||
1711 | MODULE_PARM_DESC(gfxclk, "Force graphic chip frequency in MHz. DANGEROUS. (default=auto)"); | 1652 | MODULE_PARM_DESC(gfxclk, "Force graphic chip frequency in MHz. DANGEROUS. (default=auto)"); |
1712 | module_param(slowpci, bool, 0); | 1653 | module_param(slowpci, bool, 0); |
1713 | MODULE_PARM_DESC(slowpci, "Uses slow PCI settings (0 or 1) (default=0)"); | 1654 | MODULE_PARM_DESC(slowpci, "Uses slow PCI settings (0 or 1) (default=0)"); |
1714 | |||
diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 2fc99877cb0d..cf8a2cb28505 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c | |||
@@ -30,7 +30,7 @@ static int afs_dir_readdir(struct file *file, void *dirent, filldir_t filldir); | |||
30 | static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd); | 30 | static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd); |
31 | static int afs_d_delete(struct dentry *dentry); | 31 | static int afs_d_delete(struct dentry *dentry); |
32 | static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen, | 32 | static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen, |
33 | loff_t fpos, ino_t ino, unsigned dtype); | 33 | loff_t fpos, u64 ino, unsigned dtype); |
34 | 34 | ||
35 | const struct file_operations afs_dir_file_operations = { | 35 | const struct file_operations afs_dir_file_operations = { |
36 | .open = afs_dir_open, | 36 | .open = afs_dir_open, |
@@ -409,7 +409,7 @@ static int afs_dir_readdir(struct file *file, void *cookie, filldir_t filldir) | |||
409 | * uniquifier through dtype | 409 | * uniquifier through dtype |
410 | */ | 410 | */ |
411 | static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen, | 411 | static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen, |
412 | loff_t fpos, ino_t ino, unsigned dtype) | 412 | loff_t fpos, u64 ino, unsigned dtype) |
413 | { | 413 | { |
414 | struct afs_dir_lookup_cookie *cookie = _cookie; | 414 | struct afs_dir_lookup_cookie *cookie = _cookie; |
415 | 415 | ||
@@ -675,7 +675,7 @@ static ssize_t aio_run_iocb(struct kiocb *iocb) | |||
675 | } | 675 | } |
676 | 676 | ||
677 | if (!(iocb->ki_retried & 0xff)) { | 677 | if (!(iocb->ki_retried & 0xff)) { |
678 | pr_debug("%ld retry: %d of %d\n", iocb->ki_retried, | 678 | pr_debug("%ld retry: %zd of %zd\n", iocb->ki_retried, |
679 | iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes); | 679 | iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes); |
680 | } | 680 | } |
681 | 681 | ||
@@ -1008,7 +1008,7 @@ int fastcall aio_complete(struct kiocb *iocb, long res, long res2) | |||
1008 | 1008 | ||
1009 | pr_debug("added to ring %p at [%lu]\n", iocb, tail); | 1009 | pr_debug("added to ring %p at [%lu]\n", iocb, tail); |
1010 | 1010 | ||
1011 | pr_debug("%ld retries: %d of %d\n", iocb->ki_retried, | 1011 | pr_debug("%ld retries: %zd of %zd\n", iocb->ki_retried, |
1012 | iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes); | 1012 | iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes); |
1013 | put_rq: | 1013 | put_rq: |
1014 | /* everything turned out well, dispose of the aiocb. */ | 1014 | /* everything turned out well, dispose of the aiocb. */ |
diff --git a/fs/compat.c b/fs/compat.c index d98c96f4a44d..4d3fbcb2ddb1 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -914,20 +914,24 @@ struct compat_readdir_callback { | |||
914 | }; | 914 | }; |
915 | 915 | ||
916 | static int compat_fillonedir(void *__buf, const char *name, int namlen, | 916 | static int compat_fillonedir(void *__buf, const char *name, int namlen, |
917 | loff_t offset, ino_t ino, unsigned int d_type) | 917 | loff_t offset, u64 ino, unsigned int d_type) |
918 | { | 918 | { |
919 | struct compat_readdir_callback *buf = __buf; | 919 | struct compat_readdir_callback *buf = __buf; |
920 | struct compat_old_linux_dirent __user *dirent; | 920 | struct compat_old_linux_dirent __user *dirent; |
921 | compat_ulong_t d_ino; | ||
921 | 922 | ||
922 | if (buf->result) | 923 | if (buf->result) |
923 | return -EINVAL; | 924 | return -EINVAL; |
925 | d_ino = ino; | ||
926 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
927 | return -EOVERFLOW; | ||
924 | buf->result++; | 928 | buf->result++; |
925 | dirent = buf->dirent; | 929 | dirent = buf->dirent; |
926 | if (!access_ok(VERIFY_WRITE, dirent, | 930 | if (!access_ok(VERIFY_WRITE, dirent, |
927 | (unsigned long)(dirent->d_name + namlen + 1) - | 931 | (unsigned long)(dirent->d_name + namlen + 1) - |
928 | (unsigned long)dirent)) | 932 | (unsigned long)dirent)) |
929 | goto efault; | 933 | goto efault; |
930 | if ( __put_user(ino, &dirent->d_ino) || | 934 | if ( __put_user(d_ino, &dirent->d_ino) || |
931 | __put_user(offset, &dirent->d_offset) || | 935 | __put_user(offset, &dirent->d_offset) || |
932 | __put_user(namlen, &dirent->d_namlen) || | 936 | __put_user(namlen, &dirent->d_namlen) || |
933 | __copy_to_user(dirent->d_name, name, namlen) || | 937 | __copy_to_user(dirent->d_name, name, namlen) || |
@@ -978,22 +982,26 @@ struct compat_getdents_callback { | |||
978 | }; | 982 | }; |
979 | 983 | ||
980 | static int compat_filldir(void *__buf, const char *name, int namlen, | 984 | static int compat_filldir(void *__buf, const char *name, int namlen, |
981 | loff_t offset, ino_t ino, unsigned int d_type) | 985 | loff_t offset, u64 ino, unsigned int d_type) |
982 | { | 986 | { |
983 | struct compat_linux_dirent __user * dirent; | 987 | struct compat_linux_dirent __user * dirent; |
984 | struct compat_getdents_callback *buf = __buf; | 988 | struct compat_getdents_callback *buf = __buf; |
989 | compat_ulong_t d_ino; | ||
985 | int reclen = COMPAT_ROUND_UP(NAME_OFFSET(dirent) + namlen + 2); | 990 | int reclen = COMPAT_ROUND_UP(NAME_OFFSET(dirent) + namlen + 2); |
986 | 991 | ||
987 | buf->error = -EINVAL; /* only used if we fail.. */ | 992 | buf->error = -EINVAL; /* only used if we fail.. */ |
988 | if (reclen > buf->count) | 993 | if (reclen > buf->count) |
989 | return -EINVAL; | 994 | return -EINVAL; |
995 | d_ino = ino; | ||
996 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
997 | return -EOVERFLOW; | ||
990 | dirent = buf->previous; | 998 | dirent = buf->previous; |
991 | if (dirent) { | 999 | if (dirent) { |
992 | if (__put_user(offset, &dirent->d_off)) | 1000 | if (__put_user(offset, &dirent->d_off)) |
993 | goto efault; | 1001 | goto efault; |
994 | } | 1002 | } |
995 | dirent = buf->current_dir; | 1003 | dirent = buf->current_dir; |
996 | if (__put_user(ino, &dirent->d_ino)) | 1004 | if (__put_user(d_ino, &dirent->d_ino)) |
997 | goto efault; | 1005 | goto efault; |
998 | if (__put_user(reclen, &dirent->d_reclen)) | 1006 | if (__put_user(reclen, &dirent->d_reclen)) |
999 | goto efault; | 1007 | goto efault; |
@@ -1064,7 +1072,7 @@ struct compat_getdents_callback64 { | |||
1064 | }; | 1072 | }; |
1065 | 1073 | ||
1066 | static int compat_filldir64(void * __buf, const char * name, int namlen, loff_t offset, | 1074 | static int compat_filldir64(void * __buf, const char * name, int namlen, loff_t offset, |
1067 | ino_t ino, unsigned int d_type) | 1075 | u64 ino, unsigned int d_type) |
1068 | { | 1076 | { |
1069 | struct linux_dirent64 __user *dirent; | 1077 | struct linux_dirent64 __user *dirent; |
1070 | struct compat_getdents_callback64 *buf = __buf; | 1078 | struct compat_getdents_callback64 *buf = __buf; |
diff --git a/fs/configfs/file.c b/fs/configfs/file.c index 85105e50f7db..e6d5754a715e 100644 --- a/fs/configfs/file.c +++ b/fs/configfs/file.c | |||
@@ -137,8 +137,8 @@ configfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *pp | |||
137 | if ((retval = fill_read_buffer(file->f_dentry,buffer))) | 137 | if ((retval = fill_read_buffer(file->f_dentry,buffer))) |
138 | goto out; | 138 | goto out; |
139 | } | 139 | } |
140 | pr_debug("%s: count = %d, ppos = %lld, buf = %s\n", | 140 | pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n", |
141 | __FUNCTION__,count,*ppos,buffer->page); | 141 | __FUNCTION__, count, *ppos, buffer->page); |
142 | retval = flush_read_buffer(buffer,buf,count,ppos); | 142 | retval = flush_read_buffer(buffer,buf,count,ppos); |
143 | out: | 143 | out: |
144 | up(&buffer->sem); | 144 | up(&buffer->sem); |
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 8d544334bcd2..557d5b614fae 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -720,9 +720,10 @@ static int ep_getfd(int *efd, struct inode **einode, struct file **efile, | |||
720 | 720 | ||
721 | /* Allocates an inode from the eventpoll file system */ | 721 | /* Allocates an inode from the eventpoll file system */ |
722 | inode = ep_eventpoll_inode(); | 722 | inode = ep_eventpoll_inode(); |
723 | error = PTR_ERR(inode); | 723 | if (IS_ERR(inode)) { |
724 | if (IS_ERR(inode)) | 724 | error = PTR_ERR(inode); |
725 | goto eexit_2; | 725 | goto eexit_2; |
726 | } | ||
726 | 727 | ||
727 | /* Allocates a free descriptor to plug the file onto */ | 728 | /* Allocates a free descriptor to plug the file onto */ |
728 | error = get_unused_fd(); | 729 | error = get_unused_fd(); |
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c index 4c39009350f3..93e77c3d2490 100644 --- a/fs/exportfs/expfs.c +++ b/fs/exportfs/expfs.c | |||
@@ -315,7 +315,7 @@ struct getdents_callback { | |||
315 | * the name matching the specified inode number. | 315 | * the name matching the specified inode number. |
316 | */ | 316 | */ |
317 | static int filldir_one(void * __buf, const char * name, int len, | 317 | static int filldir_one(void * __buf, const char * name, int len, |
318 | loff_t pos, ino_t ino, unsigned int d_type) | 318 | loff_t pos, u64 ino, unsigned int d_type) |
319 | { | 319 | { |
320 | struct getdents_callback *buf = __buf; | 320 | struct getdents_callback *buf = __buf; |
321 | int result = 0; | 321 | int result = 0; |
diff --git a/fs/fat/dir.c b/fs/fat/dir.c index 3e50a4166283..69c439f44387 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c | |||
@@ -648,7 +648,7 @@ static int fat_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
648 | } | 648 | } |
649 | 649 | ||
650 | static int fat_ioctl_filldir(void *__buf, const char *name, int name_len, | 650 | static int fat_ioctl_filldir(void *__buf, const char *name, int name_len, |
651 | loff_t offset, ino_t ino, unsigned int d_type) | 651 | loff_t offset, u64 ino, unsigned int d_type) |
652 | { | 652 | { |
653 | struct fat_ioctl_filldir_callback *buf = __buf; | 653 | struct fat_ioctl_filldir_callback *buf = __buf; |
654 | struct dirent __user *d1 = buf->dirent; | 654 | struct dirent __user *d1 = buf->dirent; |
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index e35d7e52fdeb..1cbd2e4ee122 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c | |||
@@ -184,7 +184,7 @@ struct dentry_list_arg { | |||
184 | 184 | ||
185 | static int | 185 | static int |
186 | nfsd4_build_dentrylist(void *arg, const char *name, int namlen, | 186 | nfsd4_build_dentrylist(void *arg, const char *name, int namlen, |
187 | loff_t offset, ino_t ino, unsigned int d_type) | 187 | loff_t offset, u64 ino, unsigned int d_type) |
188 | { | 188 | { |
189 | struct dentry_list_arg *dla = arg; | 189 | struct dentry_list_arg *dla = arg; |
190 | struct list_head *dentries = &dla->dentries; | 190 | struct list_head *dentries = &dla->dentries; |
diff --git a/fs/readdir.c b/fs/readdir.c index b6109329b607..bff3ee58e2f8 100644 --- a/fs/readdir.c +++ b/fs/readdir.c | |||
@@ -69,20 +69,24 @@ struct readdir_callback { | |||
69 | }; | 69 | }; |
70 | 70 | ||
71 | static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset, | 71 | static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset, |
72 | ino_t ino, unsigned int d_type) | 72 | u64 ino, unsigned int d_type) |
73 | { | 73 | { |
74 | struct readdir_callback * buf = (struct readdir_callback *) __buf; | 74 | struct readdir_callback * buf = (struct readdir_callback *) __buf; |
75 | struct old_linux_dirent __user * dirent; | 75 | struct old_linux_dirent __user * dirent; |
76 | unsigned long d_ino; | ||
76 | 77 | ||
77 | if (buf->result) | 78 | if (buf->result) |
78 | return -EINVAL; | 79 | return -EINVAL; |
80 | d_ino = ino; | ||
81 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
82 | return -EOVERFLOW; | ||
79 | buf->result++; | 83 | buf->result++; |
80 | dirent = buf->dirent; | 84 | dirent = buf->dirent; |
81 | if (!access_ok(VERIFY_WRITE, dirent, | 85 | if (!access_ok(VERIFY_WRITE, dirent, |
82 | (unsigned long)(dirent->d_name + namlen + 1) - | 86 | (unsigned long)(dirent->d_name + namlen + 1) - |
83 | (unsigned long)dirent)) | 87 | (unsigned long)dirent)) |
84 | goto efault; | 88 | goto efault; |
85 | if ( __put_user(ino, &dirent->d_ino) || | 89 | if ( __put_user(d_ino, &dirent->d_ino) || |
86 | __put_user(offset, &dirent->d_offset) || | 90 | __put_user(offset, &dirent->d_offset) || |
87 | __put_user(namlen, &dirent->d_namlen) || | 91 | __put_user(namlen, &dirent->d_namlen) || |
88 | __copy_to_user(dirent->d_name, name, namlen) || | 92 | __copy_to_user(dirent->d_name, name, namlen) || |
@@ -138,22 +142,26 @@ struct getdents_callback { | |||
138 | }; | 142 | }; |
139 | 143 | ||
140 | static int filldir(void * __buf, const char * name, int namlen, loff_t offset, | 144 | static int filldir(void * __buf, const char * name, int namlen, loff_t offset, |
141 | ino_t ino, unsigned int d_type) | 145 | u64 ino, unsigned int d_type) |
142 | { | 146 | { |
143 | struct linux_dirent __user * dirent; | 147 | struct linux_dirent __user * dirent; |
144 | struct getdents_callback * buf = (struct getdents_callback *) __buf; | 148 | struct getdents_callback * buf = (struct getdents_callback *) __buf; |
149 | unsigned long d_ino; | ||
145 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 2); | 150 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 2); |
146 | 151 | ||
147 | buf->error = -EINVAL; /* only used if we fail.. */ | 152 | buf->error = -EINVAL; /* only used if we fail.. */ |
148 | if (reclen > buf->count) | 153 | if (reclen > buf->count) |
149 | return -EINVAL; | 154 | return -EINVAL; |
155 | d_ino = ino; | ||
156 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
157 | return -EOVERFLOW; | ||
150 | dirent = buf->previous; | 158 | dirent = buf->previous; |
151 | if (dirent) { | 159 | if (dirent) { |
152 | if (__put_user(offset, &dirent->d_off)) | 160 | if (__put_user(offset, &dirent->d_off)) |
153 | goto efault; | 161 | goto efault; |
154 | } | 162 | } |
155 | dirent = buf->current_dir; | 163 | dirent = buf->current_dir; |
156 | if (__put_user(ino, &dirent->d_ino)) | 164 | if (__put_user(d_ino, &dirent->d_ino)) |
157 | goto efault; | 165 | goto efault; |
158 | if (__put_user(reclen, &dirent->d_reclen)) | 166 | if (__put_user(reclen, &dirent->d_reclen)) |
159 | goto efault; | 167 | goto efault; |
@@ -222,7 +230,7 @@ struct getdents_callback64 { | |||
222 | }; | 230 | }; |
223 | 231 | ||
224 | static int filldir64(void * __buf, const char * name, int namlen, loff_t offset, | 232 | static int filldir64(void * __buf, const char * name, int namlen, loff_t offset, |
225 | ino_t ino, unsigned int d_type) | 233 | u64 ino, unsigned int d_type) |
226 | { | 234 | { |
227 | struct linux_dirent64 __user *dirent; | 235 | struct linux_dirent64 __user *dirent; |
228 | struct getdents_callback64 * buf = (struct getdents_callback64 *) __buf; | 236 | struct getdents_callback64 * buf = (struct getdents_callback64 *) __buf; |
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index d935fb9394e3..7bdb0ed443e1 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
@@ -773,7 +773,7 @@ int reiserfs_xattr_del(struct inode *inode, const char *name) | |||
773 | 773 | ||
774 | static int | 774 | static int |
775 | reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen, | 775 | reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen, |
776 | loff_t offset, ino_t ino, unsigned int d_type) | 776 | loff_t offset, u64 ino, unsigned int d_type) |
777 | { | 777 | { |
778 | struct dentry *xadir = (struct dentry *)buf; | 778 | struct dentry *xadir = (struct dentry *)buf; |
779 | 779 | ||
@@ -851,7 +851,7 @@ struct reiserfs_chown_buf { | |||
851 | /* XXX: If there is a better way to do this, I'd love to hear about it */ | 851 | /* XXX: If there is a better way to do this, I'd love to hear about it */ |
852 | static int | 852 | static int |
853 | reiserfs_chown_xattrs_filler(void *buf, const char *name, int namelen, | 853 | reiserfs_chown_xattrs_filler(void *buf, const char *name, int namelen, |
854 | loff_t offset, ino_t ino, unsigned int d_type) | 854 | loff_t offset, u64 ino, unsigned int d_type) |
855 | { | 855 | { |
856 | struct reiserfs_chown_buf *chown_buf = (struct reiserfs_chown_buf *)buf; | 856 | struct reiserfs_chown_buf *chown_buf = (struct reiserfs_chown_buf *)buf; |
857 | struct dentry *xafile, *xadir = chown_buf->xadir; | 857 | struct dentry *xafile, *xadir = chown_buf->xadir; |
@@ -1036,7 +1036,7 @@ struct reiserfs_listxattr_buf { | |||
1036 | 1036 | ||
1037 | static int | 1037 | static int |
1038 | reiserfs_listxattr_filler(void *buf, const char *name, int namelen, | 1038 | reiserfs_listxattr_filler(void *buf, const char *name, int namelen, |
1039 | loff_t offset, ino_t ino, unsigned int d_type) | 1039 | loff_t offset, u64 ino, unsigned int d_type) |
1040 | { | 1040 | { |
1041 | struct reiserfs_listxattr_buf *b = (struct reiserfs_listxattr_buf *)buf; | 1041 | struct reiserfs_listxattr_buf *b = (struct reiserfs_listxattr_buf *)buf; |
1042 | int len = 0; | 1042 | int len = 0; |
@@ -140,6 +140,8 @@ static int cp_old_stat(struct kstat *stat, struct __old_kernel_stat __user * sta | |||
140 | memset(&tmp, 0, sizeof(struct __old_kernel_stat)); | 140 | memset(&tmp, 0, sizeof(struct __old_kernel_stat)); |
141 | tmp.st_dev = old_encode_dev(stat->dev); | 141 | tmp.st_dev = old_encode_dev(stat->dev); |
142 | tmp.st_ino = stat->ino; | 142 | tmp.st_ino = stat->ino; |
143 | if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino) | ||
144 | return -EOVERFLOW; | ||
143 | tmp.st_mode = stat->mode; | 145 | tmp.st_mode = stat->mode; |
144 | tmp.st_nlink = stat->nlink; | 146 | tmp.st_nlink = stat->nlink; |
145 | if (tmp.st_nlink != stat->nlink) | 147 | if (tmp.st_nlink != stat->nlink) |
@@ -210,6 +212,8 @@ static int cp_new_stat(struct kstat *stat, struct stat __user *statbuf) | |||
210 | tmp.st_dev = new_encode_dev(stat->dev); | 212 | tmp.st_dev = new_encode_dev(stat->dev); |
211 | #endif | 213 | #endif |
212 | tmp.st_ino = stat->ino; | 214 | tmp.st_ino = stat->ino; |
215 | if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino) | ||
216 | return -EOVERFLOW; | ||
213 | tmp.st_mode = stat->mode; | 217 | tmp.st_mode = stat->mode; |
214 | tmp.st_nlink = stat->nlink; | 218 | tmp.st_nlink = stat->nlink; |
215 | if (tmp.st_nlink != stat->nlink) | 219 | if (tmp.st_nlink != stat->nlink) |
@@ -347,6 +351,8 @@ static long cp_new_stat64(struct kstat *stat, struct stat64 __user *statbuf) | |||
347 | tmp.st_rdev = huge_encode_dev(stat->rdev); | 351 | tmp.st_rdev = huge_encode_dev(stat->rdev); |
348 | #endif | 352 | #endif |
349 | tmp.st_ino = stat->ino; | 353 | tmp.st_ino = stat->ino; |
354 | if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino) | ||
355 | return -EOVERFLOW; | ||
350 | #ifdef STAT64_HAS_BROKEN_ST_INO | 356 | #ifdef STAT64_HAS_BROKEN_ST_INO |
351 | tmp.__st_ino = stat->ino; | 357 | tmp.__st_ino = stat->ino; |
352 | #endif | 358 | #endif |
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index cf3786625bfa..146f1dedec84 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -157,8 +157,8 @@ sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |||
157 | if ((retval = fill_read_buffer(file->f_dentry,buffer))) | 157 | if ((retval = fill_read_buffer(file->f_dentry,buffer))) |
158 | goto out; | 158 | goto out; |
159 | } | 159 | } |
160 | pr_debug("%s: count = %d, ppos = %lld, buf = %s\n", | 160 | pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n", |
161 | __FUNCTION__,count,*ppos,buffer->page); | 161 | __FUNCTION__, count, *ppos, buffer->page); |
162 | retval = flush_read_buffer(buffer,buf,count,ppos); | 162 | retval = flush_read_buffer(buffer,buf,count,ppos); |
163 | out: | 163 | out: |
164 | up(&buffer->sem); | 164 | up(&buffer->sem); |
diff --git a/include/asm-arm/arch-pnx4008/clock.h b/include/asm-arm/arch-pnx4008/clock.h index 91ae0030fdf2..ce155e161269 100644 --- a/include/asm-arm/arch-pnx4008/clock.h +++ b/include/asm-arm/arch-pnx4008/clock.h | |||
@@ -32,6 +32,7 @@ struct clk; | |||
32 | #define KEYCLKCTRL_REG (PWRMAN_VA_BASE + 0xb0) | 32 | #define KEYCLKCTRL_REG (PWRMAN_VA_BASE + 0xb0) |
33 | #define TSCLKCTRL_REG (PWRMAN_VA_BASE + 0xb4) | 33 | #define TSCLKCTRL_REG (PWRMAN_VA_BASE + 0xb4) |
34 | #define PWMCLKCTRL_REG (PWRMAN_VA_BASE + 0xb8) | 34 | #define PWMCLKCTRL_REG (PWRMAN_VA_BASE + 0xb8) |
35 | #define TIMCLKCTRL_REG (PWRMAN_VA_BASE + 0xbc) | ||
35 | #define SPICTRL_REG (PWRMAN_VA_BASE + 0xc4) | 36 | #define SPICTRL_REG (PWRMAN_VA_BASE + 0xc4) |
36 | #define FLASHCLKCTRL_REG (PWRMAN_VA_BASE + 0xc8) | 37 | #define FLASHCLKCTRL_REG (PWRMAN_VA_BASE + 0xc8) |
37 | #define UART3CLK_REG (PWRMAN_VA_BASE + 0xd0) | 38 | #define UART3CLK_REG (PWRMAN_VA_BASE + 0xd0) |
diff --git a/include/asm-i386/mca_dma.h b/include/asm-i386/mca_dma.h index 4b3b526c5a3f..fbb1f3b71279 100644 --- a/include/asm-i386/mca_dma.h +++ b/include/asm-i386/mca_dma.h | |||
@@ -181,7 +181,7 @@ static __inline__ void mca_set_dma_io(unsigned int dmanr, unsigned int io_addr) | |||
181 | * @mode: mode to set | 181 | * @mode: mode to set |
182 | * | 182 | * |
183 | * The DMA controller supports several modes. The mode values you can | 183 | * The DMA controller supports several modes. The mode values you can |
184 | * set are : | 184 | * set are- |
185 | * | 185 | * |
186 | * %MCA_DMA_MODE_READ when reading from the DMA device. | 186 | * %MCA_DMA_MODE_READ when reading from the DMA device. |
187 | * | 187 | * |
@@ -190,7 +190,6 @@ static __inline__ void mca_set_dma_io(unsigned int dmanr, unsigned int io_addr) | |||
190 | * %MCA_DMA_MODE_IO to do DMA to or from an I/O port. | 190 | * %MCA_DMA_MODE_IO to do DMA to or from an I/O port. |
191 | * | 191 | * |
192 | * %MCA_DMA_MODE_16 to do 16bit transfers. | 192 | * %MCA_DMA_MODE_16 to do 16bit transfers. |
193 | * | ||
194 | */ | 193 | */ |
195 | 194 | ||
196 | static __inline__ void mca_set_dma_mode(unsigned int dmanr, unsigned int mode) | 195 | static __inline__ void mca_set_dma_mode(unsigned int dmanr, unsigned int mode) |
diff --git a/include/asm-i386/topology.h b/include/asm-i386/topology.h index 6adbd9b1ae88..978d09596130 100644 --- a/include/asm-i386/topology.h +++ b/include/asm-i386/topology.h | |||
@@ -74,6 +74,7 @@ static inline int node_to_first_cpu(int node) | |||
74 | #define SD_NODE_INIT (struct sched_domain) { \ | 74 | #define SD_NODE_INIT (struct sched_domain) { \ |
75 | .span = CPU_MASK_NONE, \ | 75 | .span = CPU_MASK_NONE, \ |
76 | .parent = NULL, \ | 76 | .parent = NULL, \ |
77 | .child = NULL, \ | ||
77 | .groups = NULL, \ | 78 | .groups = NULL, \ |
78 | .min_interval = 8, \ | 79 | .min_interval = 8, \ |
79 | .max_interval = 32, \ | 80 | .max_interval = 32, \ |
diff --git a/include/asm-ia64/topology.h b/include/asm-ia64/topology.h index 937c21257523..a6e38565ab4c 100644 --- a/include/asm-ia64/topology.h +++ b/include/asm-ia64/topology.h | |||
@@ -59,6 +59,7 @@ void build_cpu_to_node_map(void); | |||
59 | #define SD_CPU_INIT (struct sched_domain) { \ | 59 | #define SD_CPU_INIT (struct sched_domain) { \ |
60 | .span = CPU_MASK_NONE, \ | 60 | .span = CPU_MASK_NONE, \ |
61 | .parent = NULL, \ | 61 | .parent = NULL, \ |
62 | .child = NULL, \ | ||
62 | .groups = NULL, \ | 63 | .groups = NULL, \ |
63 | .min_interval = 1, \ | 64 | .min_interval = 1, \ |
64 | .max_interval = 4, \ | 65 | .max_interval = 4, \ |
@@ -84,6 +85,7 @@ void build_cpu_to_node_map(void); | |||
84 | #define SD_NODE_INIT (struct sched_domain) { \ | 85 | #define SD_NODE_INIT (struct sched_domain) { \ |
85 | .span = CPU_MASK_NONE, \ | 86 | .span = CPU_MASK_NONE, \ |
86 | .parent = NULL, \ | 87 | .parent = NULL, \ |
88 | .child = NULL, \ | ||
87 | .groups = NULL, \ | 89 | .groups = NULL, \ |
88 | .min_interval = 8, \ | 90 | .min_interval = 8, \ |
89 | .max_interval = 8*(min(num_online_cpus(), 32)), \ | 91 | .max_interval = 8*(min(num_online_cpus(), 32)), \ |
diff --git a/include/asm-mips/mach-ip27/topology.h b/include/asm-mips/mach-ip27/topology.h index 59d26b52ba32..a13b715fd9ca 100644 --- a/include/asm-mips/mach-ip27/topology.h +++ b/include/asm-mips/mach-ip27/topology.h | |||
@@ -22,6 +22,7 @@ extern unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES]; | |||
22 | #define SD_NODE_INIT (struct sched_domain) { \ | 22 | #define SD_NODE_INIT (struct sched_domain) { \ |
23 | .span = CPU_MASK_NONE, \ | 23 | .span = CPU_MASK_NONE, \ |
24 | .parent = NULL, \ | 24 | .parent = NULL, \ |
25 | .child = NULL, \ | ||
25 | .groups = NULL, \ | 26 | .groups = NULL, \ |
26 | .min_interval = 8, \ | 27 | .min_interval = 8, \ |
27 | .max_interval = 32, \ | 28 | .max_interval = 32, \ |
diff --git a/include/asm-powerpc/fs_pd.h b/include/asm-powerpc/fs_pd.h new file mode 100644 index 000000000000..3d0e819d37f1 --- /dev/null +++ b/include/asm-powerpc/fs_pd.h | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | * Platform information definitions. | ||
3 | * | ||
4 | * 2006 (c) MontaVista Software, Inc. | ||
5 | * Vitaly Bordug <vbordug@ru.mvista.com> | ||
6 | * | ||
7 | * This file is licensed under the terms of the GNU General Public License | ||
8 | * version 2. This program is licensed "as is" without any warranty of any | ||
9 | * kind, whether express or implied. | ||
10 | */ | ||
11 | |||
12 | #ifndef FS_PD_H | ||
13 | #define FS_PD_H | ||
14 | #include <asm/cpm2.h> | ||
15 | #include <sysdev/fsl_soc.h> | ||
16 | #include <asm/time.h> | ||
17 | |||
18 | static inline int uart_baudrate(void) | ||
19 | { | ||
20 | return get_baudrate(); | ||
21 | } | ||
22 | |||
23 | static inline int uart_clock(void) | ||
24 | { | ||
25 | return ppc_proc_freq; | ||
26 | } | ||
27 | |||
28 | #define cpm2_map(member) \ | ||
29 | ({ \ | ||
30 | u32 offset = offsetof(cpm2_map_t, member); \ | ||
31 | void *addr = ioremap (CPM_MAP_ADDR + offset, \ | ||
32 | sizeof( ((cpm2_map_t*)0)->member)); \ | ||
33 | addr; \ | ||
34 | }) | ||
35 | |||
36 | #define cpm2_map_size(member, size) \ | ||
37 | ({ \ | ||
38 | u32 offset = offsetof(cpm2_map_t, member); \ | ||
39 | void *addr = ioremap (CPM_MAP_ADDR + offset, size); \ | ||
40 | addr; \ | ||
41 | }) | ||
42 | |||
43 | #define cpm2_unmap(addr) iounmap(addr) | ||
44 | |||
45 | #endif | ||
diff --git a/include/asm-powerpc/io.h b/include/asm-powerpc/io.h index 19b2ec1ec665..cbbd8c648df1 100644 --- a/include/asm-powerpc/io.h +++ b/include/asm-powerpc/io.h | |||
@@ -11,7 +11,6 @@ | |||
11 | 11 | ||
12 | /* Check of existence of legacy devices */ | 12 | /* Check of existence of legacy devices */ |
13 | extern int check_legacy_ioport(unsigned long base_port); | 13 | extern int check_legacy_ioport(unsigned long base_port); |
14 | #define PARALLEL_BASE 0x378 | ||
15 | #define PNPBIOS_BASE 0xf000 /* only relevant for PReP */ | 14 | #define PNPBIOS_BASE 0xf000 /* only relevant for PReP */ |
16 | 15 | ||
17 | #ifndef CONFIG_PPC64 | 16 | #ifndef CONFIG_PPC64 |
diff --git a/include/asm-powerpc/mpc85xx.h b/include/asm-powerpc/mpc85xx.h new file mode 100644 index 000000000000..ccdb8a21138f --- /dev/null +++ b/include/asm-powerpc/mpc85xx.h | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * include/asm-powerpc/mpc85xx.h | ||
3 | * | ||
4 | * MPC85xx definitions | ||
5 | * | ||
6 | * Maintainer: Kumar Gala <galak@kernel.crashing.org> | ||
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_MPC85xx_H__ | ||
18 | #define __ASM_MPC85xx_H__ | ||
19 | |||
20 | #include <asm/mmu.h> | ||
21 | |||
22 | #ifdef CONFIG_85xx | ||
23 | |||
24 | #if defined(CONFIG_MPC8540_ADS) || defined(CONFIG_MPC8560_ADS) | ||
25 | #include <platforms/85xx/mpc85xx_ads.h> | ||
26 | #endif | ||
27 | #if defined(CONFIG_MPC8555_CDS) || defined(CONFIG_MPC8548_CDS) | ||
28 | #include <platforms/85xx/mpc8555_cds.h> | ||
29 | #endif | ||
30 | #ifdef CONFIG_MPC85xx_CDS | ||
31 | #include <platforms/85xx/mpc85xx_cds.h> | ||
32 | #endif | ||
33 | |||
34 | #define _IO_BASE isa_io_base | ||
35 | #define _ISA_MEM_BASE isa_mem_base | ||
36 | #ifdef CONFIG_PCI | ||
37 | #define PCI_DRAM_OFFSET pci_dram_offset | ||
38 | #else | ||
39 | #define PCI_DRAM_OFFSET 0 | ||
40 | #endif | ||
41 | |||
42 | /* Let modules/drivers get at CCSRBAR */ | ||
43 | extern phys_addr_t get_ccsrbar(void); | ||
44 | |||
45 | #ifdef MODULE | ||
46 | #define CCSRBAR get_ccsrbar() | ||
47 | #else | ||
48 | #define CCSRBAR BOARD_CCSRBAR | ||
49 | #endif | ||
50 | |||
51 | #endif /* CONFIG_85xx */ | ||
52 | #endif /* __ASM_MPC85xx_H__ */ | ||
53 | #endif /* __KERNEL__ */ | ||
diff --git a/include/asm-powerpc/time.h b/include/asm-powerpc/time.h index 5785ac4737b5..b051d4c88c3b 100644 --- a/include/asm-powerpc/time.h +++ b/include/asm-powerpc/time.h | |||
@@ -39,6 +39,10 @@ extern void generic_calibrate_decr(void); | |||
39 | extern void wakeup_decrementer(void); | 39 | extern void wakeup_decrementer(void); |
40 | extern void snapshot_timebase(void); | 40 | extern void snapshot_timebase(void); |
41 | 41 | ||
42 | #ifdef CONFIG_RTC_CLASS | ||
43 | extern int __init rtc_class_hookup(void); | ||
44 | #endif | ||
45 | |||
42 | /* Some sane defaults: 125 MHz timebase, 1GHz processor */ | 46 | /* Some sane defaults: 125 MHz timebase, 1GHz processor */ |
43 | extern unsigned long ppc_proc_freq; | 47 | extern unsigned long ppc_proc_freq; |
44 | #define DEFAULT_PROC_FREQ (DEFAULT_TB_FREQ * 8) | 48 | #define DEFAULT_PROC_FREQ (DEFAULT_TB_FREQ * 8) |
@@ -234,4 +238,4 @@ extern void snapshot_timebases(void); | |||
234 | #endif | 238 | #endif |
235 | 239 | ||
236 | #endif /* __KERNEL__ */ | 240 | #endif /* __KERNEL__ */ |
237 | #endif /* __PPC64_TIME_H */ | 241 | #endif /* __POWERPC_TIME_H */ |
diff --git a/include/asm-powerpc/topology.h b/include/asm-powerpc/topology.h index bbc3844b086f..8f7ee16781a4 100644 --- a/include/asm-powerpc/topology.h +++ b/include/asm-powerpc/topology.h | |||
@@ -43,6 +43,7 @@ extern int pcibus_to_node(struct pci_bus *bus); | |||
43 | #define SD_NODE_INIT (struct sched_domain) { \ | 43 | #define SD_NODE_INIT (struct sched_domain) { \ |
44 | .span = CPU_MASK_NONE, \ | 44 | .span = CPU_MASK_NONE, \ |
45 | .parent = NULL, \ | 45 | .parent = NULL, \ |
46 | .child = NULL, \ | ||
46 | .groups = NULL, \ | 47 | .groups = NULL, \ |
47 | .min_interval = 8, \ | 48 | .min_interval = 8, \ |
48 | .max_interval = 32, \ | 49 | .max_interval = 32, \ |
diff --git a/include/asm-ppc/cpm2.h b/include/asm-ppc/cpm2.h index f6a7ff04ffe5..220cc2debe08 100644 --- a/include/asm-ppc/cpm2.h +++ b/include/asm-ppc/cpm2.h | |||
@@ -42,6 +42,8 @@ | |||
42 | #define CPM_CR_IDMA4_SBLOCK (0x17) | 42 | #define CPM_CR_IDMA4_SBLOCK (0x17) |
43 | #define CPM_CR_MCC1_SBLOCK (0x1c) | 43 | #define CPM_CR_MCC1_SBLOCK (0x1c) |
44 | 44 | ||
45 | #define CPM_CR_FCC_SBLOCK(x) (x + 0x10) | ||
46 | |||
45 | #define CPM_CR_SCC1_PAGE (0x00) | 47 | #define CPM_CR_SCC1_PAGE (0x00) |
46 | #define CPM_CR_SCC2_PAGE (0x01) | 48 | #define CPM_CR_SCC2_PAGE (0x01) |
47 | #define CPM_CR_SCC3_PAGE (0x02) | 49 | #define CPM_CR_SCC3_PAGE (0x02) |
@@ -62,6 +64,8 @@ | |||
62 | #define CPM_CR_MCC1_PAGE (0x07) | 64 | #define CPM_CR_MCC1_PAGE (0x07) |
63 | #define CPM_CR_MCC2_PAGE (0x08) | 65 | #define CPM_CR_MCC2_PAGE (0x08) |
64 | 66 | ||
67 | #define CPM_CR_FCC_PAGE(x) (x + 0x04) | ||
68 | |||
65 | /* Some opcodes (there are more...later) | 69 | /* Some opcodes (there are more...later) |
66 | */ | 70 | */ |
67 | #define CPM_CR_INIT_TRX ((ushort)0x0000) | 71 | #define CPM_CR_INIT_TRX ((ushort)0x0000) |
@@ -173,6 +177,10 @@ typedef struct cpm_buf_desc { | |||
173 | #define PROFF_I2C_BASE ((uint)0x8afc) | 177 | #define PROFF_I2C_BASE ((uint)0x8afc) |
174 | #define PROFF_IDMA4_BASE ((uint)0x8afe) | 178 | #define PROFF_IDMA4_BASE ((uint)0x8afe) |
175 | 179 | ||
180 | #define PROFF_SCC_SIZE ((uint)0x100) | ||
181 | #define PROFF_FCC_SIZE ((uint)0x100) | ||
182 | #define PROFF_SMC_SIZE ((uint)64) | ||
183 | |||
176 | /* The SMCs are relocated to any of the first eight DPRAM pages. | 184 | /* The SMCs are relocated to any of the first eight DPRAM pages. |
177 | * We will fix these at the first locations of DPRAM, until we | 185 | * We will fix these at the first locations of DPRAM, until we |
178 | * get some microcode patches :-). | 186 | * get some microcode patches :-). |
@@ -1186,7 +1194,60 @@ typedef struct im_idma { | |||
1186 | #define FCC_MEM_OFFSET(x) (CPM_FCC_SPECIAL_BASE + (x*128)) | 1194 | #define FCC_MEM_OFFSET(x) (CPM_FCC_SPECIAL_BASE + (x*128)) |
1187 | #define FCC1_MEM_OFFSET FCC_MEM_OFFSET(0) | 1195 | #define FCC1_MEM_OFFSET FCC_MEM_OFFSET(0) |
1188 | #define FCC2_MEM_OFFSET FCC_MEM_OFFSET(1) | 1196 | #define FCC2_MEM_OFFSET FCC_MEM_OFFSET(1) |
1189 | #define FCC2_MEM_OFFSET FCC_MEM_OFFSET(2) | 1197 | #define FCC3_MEM_OFFSET FCC_MEM_OFFSET(2) |
1198 | |||
1199 | /* Clocks and GRG's */ | ||
1200 | |||
1201 | enum cpm_clk_dir { | ||
1202 | CPM_CLK_RX, | ||
1203 | CPM_CLK_TX, | ||
1204 | CPM_CLK_RTX | ||
1205 | }; | ||
1206 | |||
1207 | enum cpm_clk_target { | ||
1208 | CPM_CLK_SCC1, | ||
1209 | CPM_CLK_SCC2, | ||
1210 | CPM_CLK_SCC3, | ||
1211 | CPM_CLK_SCC4, | ||
1212 | CPM_CLK_FCC1, | ||
1213 | CPM_CLK_FCC2, | ||
1214 | CPM_CLK_FCC3 | ||
1215 | }; | ||
1216 | |||
1217 | enum cpm_clk { | ||
1218 | CPM_CLK_NONE = 0, | ||
1219 | CPM_BRG1, /* Baud Rate Generator 1 */ | ||
1220 | CPM_BRG2, /* Baud Rate Generator 2 */ | ||
1221 | CPM_BRG3, /* Baud Rate Generator 3 */ | ||
1222 | CPM_BRG4, /* Baud Rate Generator 4 */ | ||
1223 | CPM_BRG5, /* Baud Rate Generator 5 */ | ||
1224 | CPM_BRG6, /* Baud Rate Generator 6 */ | ||
1225 | CPM_BRG7, /* Baud Rate Generator 7 */ | ||
1226 | CPM_BRG8, /* Baud Rate Generator 8 */ | ||
1227 | CPM_CLK1, /* Clock 1 */ | ||
1228 | CPM_CLK2, /* Clock 2 */ | ||
1229 | CPM_CLK3, /* Clock 3 */ | ||
1230 | CPM_CLK4, /* Clock 4 */ | ||
1231 | CPM_CLK5, /* Clock 5 */ | ||
1232 | CPM_CLK6, /* Clock 6 */ | ||
1233 | CPM_CLK7, /* Clock 7 */ | ||
1234 | CPM_CLK8, /* Clock 8 */ | ||
1235 | CPM_CLK9, /* Clock 9 */ | ||
1236 | CPM_CLK10, /* Clock 10 */ | ||
1237 | CPM_CLK11, /* Clock 11 */ | ||
1238 | CPM_CLK12, /* Clock 12 */ | ||
1239 | CPM_CLK13, /* Clock 13 */ | ||
1240 | CPM_CLK14, /* Clock 14 */ | ||
1241 | CPM_CLK15, /* Clock 15 */ | ||
1242 | CPM_CLK16, /* Clock 16 */ | ||
1243 | CPM_CLK17, /* Clock 17 */ | ||
1244 | CPM_CLK18, /* Clock 18 */ | ||
1245 | CPM_CLK19, /* Clock 19 */ | ||
1246 | CPM_CLK20, /* Clock 20 */ | ||
1247 | CPM_CLK_DUMMY | ||
1248 | }; | ||
1249 | |||
1250 | extern int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode); | ||
1190 | 1251 | ||
1191 | #endif /* __CPM2__ */ | 1252 | #endif /* __CPM2__ */ |
1192 | #endif /* __KERNEL__ */ | 1253 | #endif /* __KERNEL__ */ |
diff --git a/include/asm-ppc/fs_pd.h b/include/asm-ppc/fs_pd.h new file mode 100644 index 000000000000..8691327653af --- /dev/null +++ b/include/asm-ppc/fs_pd.h | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | * Platform information definitions. | ||
3 | * | ||
4 | * 2006 (c) MontaVista Software, Inc. | ||
5 | * Vitaly Bordug <vbordug@ru.mvista.com> | ||
6 | * | ||
7 | * This file is licensed under the terms of the GNU General Public License | ||
8 | * version 2. This program is licensed "as is" without any warranty of any | ||
9 | * kind, whether express or implied. | ||
10 | */ | ||
11 | |||
12 | #ifndef FS_PD_H | ||
13 | #define FS_PD_H | ||
14 | |||
15 | static inline int uart_baudrate(void) | ||
16 | { | ||
17 | int baud; | ||
18 | bd_t *bd = (bd_t *) __res; | ||
19 | |||
20 | if (bd->bi_baudrate) | ||
21 | baud = bd->bi_baudrate; | ||
22 | else | ||
23 | baud = -1; | ||
24 | return baud; | ||
25 | } | ||
26 | |||
27 | static inline int uart_clock(void) | ||
28 | { | ||
29 | return (((bd_t *) __res)->bi_intfreq); | ||
30 | } | ||
31 | |||
32 | #define cpm2_map(member) (&cpm2_immr->member) | ||
33 | #define cpm2_map_size(member, size) (&cpm2_immr->member) | ||
34 | #define cpm2_unmap(addr) do {} while(0) | ||
35 | |||
36 | #endif | ||
diff --git a/include/asm-ppc/rheap.h b/include/asm-ppc/rheap.h index e6ca1f67cedc..65b93225a778 100644 --- a/include/asm-ppc/rheap.h +++ b/include/asm-ppc/rheap.h | |||
@@ -62,6 +62,10 @@ extern int rh_attach_region(rh_info_t * info, void *start, int size); | |||
62 | /* Detach a free region */ | 62 | /* Detach a free region */ |
63 | extern void *rh_detach_region(rh_info_t * info, void *start, int size); | 63 | extern void *rh_detach_region(rh_info_t * info, void *start, int size); |
64 | 64 | ||
65 | /* Allocate the given size from the remote heap (with alignment) */ | ||
66 | extern void *rh_alloc_align(rh_info_t * info, int size, int alignment, | ||
67 | const char *owner); | ||
68 | |||
65 | /* Allocate the given size from the remote heap */ | 69 | /* Allocate the given size from the remote heap */ |
66 | extern void *rh_alloc(rh_info_t * info, int size, const char *owner); | 70 | extern void *rh_alloc(rh_info_t * info, int size, const char *owner); |
67 | 71 | ||
diff --git a/include/asm-x86_64/topology.h b/include/asm-x86_64/topology.h index 6e7a2e976b04..5c8f49280dbc 100644 --- a/include/asm-x86_64/topology.h +++ b/include/asm-x86_64/topology.h | |||
@@ -31,6 +31,7 @@ extern int __node_distance(int, int); | |||
31 | #define SD_NODE_INIT (struct sched_domain) { \ | 31 | #define SD_NODE_INIT (struct sched_domain) { \ |
32 | .span = CPU_MASK_NONE, \ | 32 | .span = CPU_MASK_NONE, \ |
33 | .parent = NULL, \ | 33 | .parent = NULL, \ |
34 | .child = NULL, \ | ||
34 | .groups = NULL, \ | 35 | .groups = NULL, \ |
35 | .min_interval = 8, \ | 36 | .min_interval = 8, \ |
36 | .max_interval = 32, \ | 37 | .max_interval = 32, \ |
diff --git a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h index d5b7abc4f409..4e1663d7691e 100644 --- a/include/linux/compat_ioctl.h +++ b/include/linux/compat_ioctl.h | |||
@@ -122,10 +122,10 @@ COMPATIBLE_IOCTL(PROTECT_ARRAY) | |||
122 | ULONG_IOCTL(HOT_ADD_DISK) | 122 | ULONG_IOCTL(HOT_ADD_DISK) |
123 | ULONG_IOCTL(SET_DISK_FAULTY) | 123 | ULONG_IOCTL(SET_DISK_FAULTY) |
124 | COMPATIBLE_IOCTL(RUN_ARRAY) | 124 | COMPATIBLE_IOCTL(RUN_ARRAY) |
125 | ULONG_IOCTL(START_ARRAY) | ||
126 | COMPATIBLE_IOCTL(STOP_ARRAY) | 125 | COMPATIBLE_IOCTL(STOP_ARRAY) |
127 | COMPATIBLE_IOCTL(STOP_ARRAY_RO) | 126 | COMPATIBLE_IOCTL(STOP_ARRAY_RO) |
128 | COMPATIBLE_IOCTL(RESTART_ARRAY_RW) | 127 | COMPATIBLE_IOCTL(RESTART_ARRAY_RW) |
128 | ULONG_IOCTL(SET_BITMAP_FILE) | ||
129 | /* DM */ | 129 | /* DM */ |
130 | COMPATIBLE_IOCTL(DM_VERSION_32) | 130 | COMPATIBLE_IOCTL(DM_VERSION_32) |
131 | COMPATIBLE_IOCTL(DM_REMOVE_ALL_32) | 131 | COMPATIBLE_IOCTL(DM_REMOVE_ALL_32) |
diff --git a/include/linux/console.h b/include/linux/console.h index 76a1807726eb..7d0420274de0 100644 --- a/include/linux/console.h +++ b/include/linux/console.h | |||
@@ -129,6 +129,9 @@ static inline void suspend_console(void) {} | |||
129 | static inline void resume_console(void) {} | 129 | static inline void resume_console(void) {} |
130 | #endif /* CONFIG_DISABLE_CONSOLE_SUSPEND */ | 130 | #endif /* CONFIG_DISABLE_CONSOLE_SUSPEND */ |
131 | 131 | ||
132 | int mda_console_init(void); | ||
133 | void prom_con_init(void); | ||
134 | |||
132 | /* Some debug stub to catch some of the obvious races in the VT code */ | 135 | /* Some debug stub to catch some of the obvious races in the VT code */ |
133 | #if 1 | 136 | #if 1 |
134 | #define WARN_CONSOLE_UNLOCKED() WARN_ON(!is_console_locked() && !oops_in_progress) | 137 | #define WARN_CONSOLE_UNLOCKED() WARN_ON(!is_console_locked() && !oops_in_progress) |
diff --git a/include/linux/consolemap.h b/include/linux/consolemap.h index 65842efc1b70..82c9a1f11020 100644 --- a/include/linux/consolemap.h +++ b/include/linux/consolemap.h | |||
@@ -13,3 +13,4 @@ struct vc_data; | |||
13 | extern unsigned char inverse_translate(struct vc_data *conp, int glyph); | 13 | extern unsigned char inverse_translate(struct vc_data *conp, int glyph); |
14 | extern unsigned short *set_translate(int m, struct vc_data *vc); | 14 | extern unsigned short *set_translate(int m, struct vc_data *vc); |
15 | extern int conv_uni_to_pc(struct vc_data *conp, long ucs); | 15 | extern int conv_uni_to_pc(struct vc_data *conp, long ucs); |
16 | void console_map_init(void); | ||
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index e3d1c33d1558..03ef41c1eaac 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h | |||
@@ -55,8 +55,10 @@ typedef int (*dm_endio_fn) (struct dm_target *ti, | |||
55 | struct bio *bio, int error, | 55 | struct bio *bio, int error, |
56 | union map_info *map_context); | 56 | union map_info *map_context); |
57 | 57 | ||
58 | typedef void (*dm_flush_fn) (struct dm_target *ti); | ||
58 | typedef void (*dm_presuspend_fn) (struct dm_target *ti); | 59 | typedef void (*dm_presuspend_fn) (struct dm_target *ti); |
59 | typedef void (*dm_postsuspend_fn) (struct dm_target *ti); | 60 | typedef void (*dm_postsuspend_fn) (struct dm_target *ti); |
61 | typedef int (*dm_preresume_fn) (struct dm_target *ti); | ||
60 | typedef void (*dm_resume_fn) (struct dm_target *ti); | 62 | typedef void (*dm_resume_fn) (struct dm_target *ti); |
61 | 63 | ||
62 | typedef int (*dm_status_fn) (struct dm_target *ti, status_type_t status_type, | 64 | typedef int (*dm_status_fn) (struct dm_target *ti, status_type_t status_type, |
@@ -64,9 +66,18 @@ typedef int (*dm_status_fn) (struct dm_target *ti, status_type_t status_type, | |||
64 | 66 | ||
65 | typedef int (*dm_message_fn) (struct dm_target *ti, unsigned argc, char **argv); | 67 | typedef int (*dm_message_fn) (struct dm_target *ti, unsigned argc, char **argv); |
66 | 68 | ||
69 | typedef int (*dm_ioctl_fn) (struct dm_target *ti, struct inode *inode, | ||
70 | struct file *filp, unsigned int cmd, | ||
71 | unsigned long arg); | ||
72 | |||
67 | void dm_error(const char *message); | 73 | void dm_error(const char *message); |
68 | 74 | ||
69 | /* | 75 | /* |
76 | * Combine device limits. | ||
77 | */ | ||
78 | void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev); | ||
79 | |||
80 | /* | ||
70 | * Constructors should call these functions to ensure destination devices | 81 | * Constructors should call these functions to ensure destination devices |
71 | * are opened/closed correctly. | 82 | * are opened/closed correctly. |
72 | * FIXME: too many arguments. | 83 | * FIXME: too many arguments. |
@@ -86,11 +97,14 @@ struct target_type { | |||
86 | dm_dtr_fn dtr; | 97 | dm_dtr_fn dtr; |
87 | dm_map_fn map; | 98 | dm_map_fn map; |
88 | dm_endio_fn end_io; | 99 | dm_endio_fn end_io; |
100 | dm_flush_fn flush; | ||
89 | dm_presuspend_fn presuspend; | 101 | dm_presuspend_fn presuspend; |
90 | dm_postsuspend_fn postsuspend; | 102 | dm_postsuspend_fn postsuspend; |
103 | dm_preresume_fn preresume; | ||
91 | dm_resume_fn resume; | 104 | dm_resume_fn resume; |
92 | dm_status_fn status; | 105 | dm_status_fn status; |
93 | dm_message_fn message; | 106 | dm_message_fn message; |
107 | dm_ioctl_fn ioctl; | ||
94 | }; | 108 | }; |
95 | 109 | ||
96 | struct io_restrictions { | 110 | struct io_restrictions { |
diff --git a/include/linux/dm-ioctl.h b/include/linux/dm-ioctl.h index 9623bb625090..8853fc4d1c5e 100644 --- a/include/linux/dm-ioctl.h +++ b/include/linux/dm-ioctl.h | |||
@@ -285,9 +285,9 @@ typedef char ioctl_struct[308]; | |||
285 | #define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl) | 285 | #define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl) |
286 | 286 | ||
287 | #define DM_VERSION_MAJOR 4 | 287 | #define DM_VERSION_MAJOR 4 |
288 | #define DM_VERSION_MINOR 7 | 288 | #define DM_VERSION_MINOR 10 |
289 | #define DM_VERSION_PATCHLEVEL 0 | 289 | #define DM_VERSION_PATCHLEVEL 0 |
290 | #define DM_VERSION_EXTRA "-ioctl (2006-06-24)" | 290 | #define DM_VERSION_EXTRA "-ioctl (2006-09-14)" |
291 | 291 | ||
292 | /* Status bits */ | 292 | /* Status bits */ |
293 | #define DM_READONLY_FLAG (1 << 0) /* In/Out */ | 293 | #define DM_READONLY_FLAG (1 << 0) /* In/Out */ |
diff --git a/include/linux/fb.h b/include/linux/fb.h index 2f335e966011..3e69241e6a81 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define _LINUX_FB_H | 2 | #define _LINUX_FB_H |
3 | 3 | ||
4 | #include <asm/types.h> | 4 | #include <asm/types.h> |
5 | #include <linux/i2c.h> | ||
5 | 6 | ||
6 | /* Definitions of frame buffers */ | 7 | /* Definitions of frame buffers */ |
7 | 8 | ||
@@ -775,6 +776,7 @@ struct fb_info { | |||
775 | struct fb_ops *fbops; | 776 | struct fb_ops *fbops; |
776 | struct device *device; | 777 | struct device *device; |
777 | struct class_device *class_device; /* sysfs per device attrs */ | 778 | struct class_device *class_device; /* sysfs per device attrs */ |
779 | int class_flag; /* private sysfs flags */ | ||
778 | #ifdef CONFIG_FB_TILEBLITTING | 780 | #ifdef CONFIG_FB_TILEBLITTING |
779 | struct fb_tile_ops *tileops; /* Tile Blitting */ | 781 | struct fb_tile_ops *tileops; /* Tile Blitting */ |
780 | #endif | 782 | #endif |
@@ -940,6 +942,7 @@ extern void fb_edid_to_monspecs(unsigned char *edid, | |||
940 | struct fb_monspecs *specs); | 942 | struct fb_monspecs *specs); |
941 | extern void fb_destroy_modedb(struct fb_videomode *modedb); | 943 | extern void fb_destroy_modedb(struct fb_videomode *modedb); |
942 | extern int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb); | 944 | extern int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb); |
945 | extern unsigned char *fb_ddc_read(struct i2c_adapter *adapter); | ||
943 | 946 | ||
944 | /* drivers/video/modedb.c */ | 947 | /* drivers/video/modedb.c */ |
945 | #define VESA_MODEDB_SIZE 34 | 948 | #define VESA_MODEDB_SIZE 34 |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 91c0b2a32a90..f53bf4ff1955 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -1049,7 +1049,7 @@ int generic_osync_inode(struct inode *, struct address_space *, int); | |||
1049 | * This allows the kernel to read directories into kernel space or | 1049 | * This allows the kernel to read directories into kernel space or |
1050 | * to have different dirent layouts depending on the binary type. | 1050 | * to have different dirent layouts depending on the binary type. |
1051 | */ | 1051 | */ |
1052 | typedef int (*filldir_t)(void *, const char *, int, loff_t, ino_t, unsigned); | 1052 | typedef int (*filldir_t)(void *, const char *, int, loff_t, u64, unsigned); |
1053 | 1053 | ||
1054 | struct block_device_operations { | 1054 | struct block_device_operations { |
1055 | int (*open) (struct inode *, struct file *); | 1055 | int (*open) (struct inode *, struct file *); |
@@ -1523,6 +1523,9 @@ extern const struct file_operations def_fifo_fops; | |||
1523 | #ifdef CONFIG_BLOCK | 1523 | #ifdef CONFIG_BLOCK |
1524 | extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long); | 1524 | extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long); |
1525 | extern int blkdev_ioctl(struct inode *, struct file *, unsigned, unsigned long); | 1525 | extern int blkdev_ioctl(struct inode *, struct file *, unsigned, unsigned long); |
1526 | extern int blkdev_driver_ioctl(struct inode *inode, struct file *file, | ||
1527 | struct gendisk *disk, unsigned cmd, | ||
1528 | unsigned long arg); | ||
1526 | extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long); | 1529 | extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long); |
1527 | extern int blkdev_get(struct block_device *, mode_t, unsigned); | 1530 | extern int blkdev_get(struct block_device *, mode_t, unsigned); |
1528 | extern int blkdev_put(struct block_device *); | 1531 | extern int blkdev_put(struct block_device *); |
diff --git a/include/linux/fs_enet_pd.h b/include/linux/fs_enet_pd.h index 74ed35a00a94..543cd3cd9e77 100644 --- a/include/linux/fs_enet_pd.h +++ b/include/linux/fs_enet_pd.h | |||
@@ -55,6 +55,30 @@ static inline int fs_get_scc_index(enum fs_id id) | |||
55 | return -1; | 55 | return -1; |
56 | } | 56 | } |
57 | 57 | ||
58 | static inline int fs_fec_index2id(int index) | ||
59 | { | ||
60 | int id = fsid_fec1 + index - 1; | ||
61 | if (id >= fsid_fec1 && id <= fsid_fec2) | ||
62 | return id; | ||
63 | return FS_MAX_INDEX; | ||
64 | } | ||
65 | |||
66 | static inline int fs_fcc_index2id(int index) | ||
67 | { | ||
68 | int id = fsid_fcc1 + index - 1; | ||
69 | if (id >= fsid_fcc1 && id <= fsid_fcc3) | ||
70 | return id; | ||
71 | return FS_MAX_INDEX; | ||
72 | } | ||
73 | |||
74 | static inline int fs_scc_index2id(int index) | ||
75 | { | ||
76 | int id = fsid_scc1 + index - 1; | ||
77 | if (id >= fsid_scc1 && id <= fsid_scc4) | ||
78 | return id; | ||
79 | return FS_MAX_INDEX; | ||
80 | } | ||
81 | |||
58 | enum fs_mii_method { | 82 | enum fs_mii_method { |
59 | fsmii_fixed, | 83 | fsmii_fixed, |
60 | fsmii_fec, | 84 | fsmii_fec, |
@@ -87,18 +111,21 @@ struct fs_mii_bb_platform_info { | |||
87 | }; | 111 | }; |
88 | 112 | ||
89 | struct fs_platform_info { | 113 | struct fs_platform_info { |
90 | 114 | ||
91 | void(*init_ioports)(void); | 115 | void(*init_ioports)(struct fs_platform_info *); |
92 | /* device specific information */ | 116 | /* device specific information */ |
93 | int fs_no; /* controller index */ | 117 | int fs_no; /* controller index */ |
118 | char fs_type[4]; /* controller type */ | ||
94 | 119 | ||
95 | u32 cp_page; /* CPM page */ | 120 | u32 cp_page; /* CPM page */ |
96 | u32 cp_block; /* CPM sblock */ | 121 | u32 cp_block; /* CPM sblock */ |
97 | 122 | ||
98 | u32 clk_trx; /* some stuff for pins & mux configuration*/ | 123 | u32 clk_trx; /* some stuff for pins & mux configuration*/ |
124 | u32 clk_rx; | ||
125 | u32 clk_tx; | ||
99 | u32 clk_route; | 126 | u32 clk_route; |
100 | u32 clk_mask; | 127 | u32 clk_mask; |
101 | 128 | ||
102 | u32 mem_offset; | 129 | u32 mem_offset; |
103 | u32 dpram_offset; | 130 | u32 dpram_offset; |
104 | u32 fcc_regs_c; | 131 | u32 fcc_regs_c; |
@@ -124,4 +151,16 @@ struct fs_mii_fec_platform_info { | |||
124 | u32 irq[32]; | 151 | u32 irq[32]; |
125 | u32 mii_speed; | 152 | u32 mii_speed; |
126 | }; | 153 | }; |
154 | |||
155 | static inline int fs_get_id(struct fs_platform_info *fpi) | ||
156 | { | ||
157 | if(strstr(fpi->fs_type, "SCC")) | ||
158 | return fs_scc_index2id(fpi->fs_no); | ||
159 | if(strstr(fpi->fs_type, "FCC")) | ||
160 | return fs_fcc_index2id(fpi->fs_no); | ||
161 | if(strstr(fpi->fs_type, "FEC")) | ||
162 | return fs_fec_index2id(fpi->fs_no); | ||
163 | return fpi->fs_no; | ||
164 | } | ||
165 | |||
127 | #endif | 166 | #endif |
diff --git a/include/linux/fs_uart_pd.h b/include/linux/fs_uart_pd.h index f5975126b712..809bb9ffc788 100644 --- a/include/linux/fs_uart_pd.h +++ b/include/linux/fs_uart_pd.h | |||
@@ -46,15 +46,27 @@ static inline int fs_uart_id_fsid2smc(int id) | |||
46 | } | 46 | } |
47 | 47 | ||
48 | struct fs_uart_platform_info { | 48 | struct fs_uart_platform_info { |
49 | void(*init_ioports)(void); | 49 | void(*init_ioports)(struct fs_uart_platform_info *); |
50 | /* device specific information */ | 50 | /* device specific information */ |
51 | int fs_no; /* controller index */ | 51 | int fs_no; /* controller index */ |
52 | char fs_type[4]; /* controller type */ | ||
52 | u32 uart_clk; | 53 | u32 uart_clk; |
53 | u8 tx_num_fifo; | 54 | u8 tx_num_fifo; |
54 | u8 tx_buf_size; | 55 | u8 tx_buf_size; |
55 | u8 rx_num_fifo; | 56 | u8 rx_num_fifo; |
56 | u8 rx_buf_size; | 57 | u8 rx_buf_size; |
57 | u8 brg; | 58 | u8 brg; |
59 | u8 clk_rx; | ||
60 | u8 clk_tx; | ||
58 | }; | 61 | }; |
59 | 62 | ||
63 | static inline int fs_uart_get_id(struct fs_uart_platform_info *fpi) | ||
64 | { | ||
65 | if(strstr(fpi->fs_type, "SMC")) | ||
66 | return fs_uart_id_smc2fsid(fpi->fs_no); | ||
67 | if(strstr(fpi->fs_type, "SCC")) | ||
68 | return fs_uart_id_scc2fsid(fpi->fs_no); | ||
69 | return fpi->fs_no; | ||
70 | } | ||
71 | |||
60 | #endif | 72 | #endif |
diff --git a/include/linux/ide.h b/include/linux/ide.h index 99620451d958..07d8d725541f 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
@@ -251,7 +251,8 @@ static inline void ide_std_init_ports(hw_regs_t *hw, | |||
251 | 251 | ||
252 | #include <asm/ide.h> | 252 | #include <asm/ide.h> |
253 | 253 | ||
254 | #ifndef MAX_HWIFS | 254 | #if !defined(MAX_HWIFS) || defined(CONFIG_EMBEDDED) |
255 | #undef MAX_HWIFS | ||
255 | #define MAX_HWIFS CONFIG_IDE_MAX_HWIFS | 256 | #define MAX_HWIFS CONFIG_IDE_MAX_HWIFS |
256 | #endif | 257 | #endif |
257 | 258 | ||
@@ -773,12 +774,13 @@ typedef struct hwif_s { | |||
773 | unsigned long dma_status; /* dma status register */ | 774 | unsigned long dma_status; /* dma status register */ |
774 | unsigned long dma_vendor3; /* dma vendor 3 register */ | 775 | unsigned long dma_vendor3; /* dma vendor 3 register */ |
775 | unsigned long dma_prdtable; /* actual prd table address */ | 776 | unsigned long dma_prdtable; /* actual prd table address */ |
776 | unsigned long dma_base2; /* extended base addr for dma ports */ | ||
777 | 777 | ||
778 | unsigned dma_extra; /* extra addr for dma ports */ | ||
779 | unsigned long config_data; /* for use by chipset-specific code */ | 778 | unsigned long config_data; /* for use by chipset-specific code */ |
780 | unsigned long select_data; /* for use by chipset-specific code */ | 779 | unsigned long select_data; /* for use by chipset-specific code */ |
781 | 780 | ||
781 | unsigned long extra_base; /* extra addr for dma ports */ | ||
782 | unsigned extra_ports; /* number of extra dma ports */ | ||
783 | |||
782 | unsigned noprobe : 1; /* don't probe for this interface */ | 784 | unsigned noprobe : 1; /* don't probe for this interface */ |
783 | unsigned present : 1; /* this interface exists */ | 785 | unsigned present : 1; /* this interface exists */ |
784 | unsigned hold : 1; /* this interface is always present */ | 786 | unsigned hold : 1; /* this interface is always present */ |
@@ -823,6 +825,9 @@ typedef struct hwgroup_s { | |||
823 | unsigned int sleeping : 1; | 825 | unsigned int sleeping : 1; |
824 | /* BOOL: polling active & poll_timeout field valid */ | 826 | /* BOOL: polling active & poll_timeout field valid */ |
825 | unsigned int polling : 1; | 827 | unsigned int polling : 1; |
828 | /* BOOL: in a polling reset situation. Must not trigger another reset yet */ | ||
829 | unsigned int resetting : 1; | ||
830 | |||
826 | /* current drive */ | 831 | /* current drive */ |
827 | ide_drive_t *drive; | 832 | ide_drive_t *drive; |
828 | /* ptr to current hwif in linked-list */ | 833 | /* ptr to current hwif in linked-list */ |
@@ -1190,7 +1195,6 @@ extern int ideprobe_init(void); | |||
1190 | extern void ide_scan_pcibus(int scan_direction) __init; | 1195 | extern void ide_scan_pcibus(int scan_direction) __init; |
1191 | extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *owner); | 1196 | extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *owner); |
1192 | #define ide_pci_register_driver(d) __ide_pci_register_driver(d, THIS_MODULE) | 1197 | #define ide_pci_register_driver(d) __ide_pci_register_driver(d, THIS_MODULE) |
1193 | extern void ide_pci_unregister_driver(struct pci_driver *driver); | ||
1194 | void ide_pci_setup_ports(struct pci_dev *, struct ide_pci_device_s *, int, ata_index_t *); | 1198 | void ide_pci_setup_ports(struct pci_dev *, struct ide_pci_device_s *, int, ata_index_t *); |
1195 | extern void ide_setup_pci_noise (struct pci_dev *dev, struct ide_pci_device_s *d); | 1199 | extern void ide_setup_pci_noise (struct pci_dev *dev, struct ide_pci_device_s *d); |
1196 | 1200 | ||
diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h index 849043ce4ed6..1cebcbc28b47 100644 --- a/include/linux/kallsyms.h +++ b/include/linux/kallsyms.h | |||
@@ -12,6 +12,10 @@ | |||
12 | /* Lookup the address for a symbol. Returns 0 if not found. */ | 12 | /* Lookup the address for a symbol. Returns 0 if not found. */ |
13 | unsigned long kallsyms_lookup_name(const char *name); | 13 | unsigned long kallsyms_lookup_name(const char *name); |
14 | 14 | ||
15 | extern int kallsyms_lookup_size_offset(unsigned long addr, | ||
16 | unsigned long *symbolsize, | ||
17 | unsigned long *offset); | ||
18 | |||
15 | /* Lookup an address. modname is set to NULL if it's in the kernel. */ | 19 | /* Lookup an address. modname is set to NULL if it's in the kernel. */ |
16 | const char *kallsyms_lookup(unsigned long addr, | 20 | const char *kallsyms_lookup(unsigned long addr, |
17 | unsigned long *symbolsize, | 21 | unsigned long *symbolsize, |
@@ -28,6 +32,13 @@ static inline unsigned long kallsyms_lookup_name(const char *name) | |||
28 | return 0; | 32 | return 0; |
29 | } | 33 | } |
30 | 34 | ||
35 | static inline int kallsyms_lookup_size_offset(unsigned long addr, | ||
36 | unsigned long *symbolsize, | ||
37 | unsigned long *offset) | ||
38 | { | ||
39 | return 0; | ||
40 | } | ||
41 | |||
31 | static inline const char *kallsyms_lookup(unsigned long addr, | 42 | static inline const char *kallsyms_lookup(unsigned long addr, |
32 | unsigned long *symbolsize, | 43 | unsigned long *symbolsize, |
33 | unsigned long *offset, | 44 | unsigned long *offset, |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 4d00988dad03..80f39cab470a 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -216,8 +216,10 @@ extern void dump_stack(void); | |||
216 | #define pr_debug(fmt,arg...) \ | 216 | #define pr_debug(fmt,arg...) \ |
217 | printk(KERN_DEBUG fmt,##arg) | 217 | printk(KERN_DEBUG fmt,##arg) |
218 | #else | 218 | #else |
219 | #define pr_debug(fmt,arg...) \ | 219 | static inline int __attribute__ ((format (printf, 1, 2))) pr_debug(const char * fmt, ...) |
220 | do { } while (0) | 220 | { |
221 | return 0; | ||
222 | } | ||
221 | #endif | 223 | #endif |
222 | 224 | ||
223 | #define pr_info(fmt,arg...) \ | 225 | #define pr_info(fmt,arg...) \ |
diff --git a/include/linux/pid.h b/include/linux/pid.h index 17b9e04d3586..2c0007d17218 100644 --- a/include/linux/pid.h +++ b/include/linux/pid.h | |||
@@ -105,28 +105,28 @@ static inline pid_t pid_nr(struct pid *pid) | |||
105 | } | 105 | } |
106 | 106 | ||
107 | 107 | ||
108 | #define do_each_task_pid(who, type, task) \ | 108 | #define do_each_task_pid(who, type, task) \ |
109 | do { \ | 109 | do { \ |
110 | struct hlist_node *pos___; \ | 110 | struct hlist_node *pos___; \ |
111 | struct pid *pid___ = find_pid(who); \ | 111 | struct pid *pid___ = find_pid(who); \ |
112 | if (pid___ != NULL) \ | 112 | if (pid___ != NULL) \ |
113 | hlist_for_each_entry_rcu((task), pos___, \ | 113 | hlist_for_each_entry_rcu((task), pos___, \ |
114 | &pid___->tasks[type], pids[type].node) { | 114 | &pid___->tasks[type], pids[type].node) { |
115 | 115 | ||
116 | #define while_each_task_pid(who, type, task) \ | 116 | #define while_each_task_pid(who, type, task) \ |
117 | } \ | 117 | } \ |
118 | } while (0) | 118 | } while (0) |
119 | 119 | ||
120 | 120 | ||
121 | #define do_each_pid_task(pid, type, task) \ | 121 | #define do_each_pid_task(pid, type, task) \ |
122 | do { \ | 122 | do { \ |
123 | struct hlist_node *pos___; \ | 123 | struct hlist_node *pos___; \ |
124 | if (pid != NULL) \ | 124 | if (pid != NULL) \ |
125 | hlist_for_each_entry_rcu((task), pos___, \ | 125 | hlist_for_each_entry_rcu((task), pos___, \ |
126 | &pid->tasks[type], pids[type].node) { | 126 | &pid->tasks[type], pids[type].node) { |
127 | 127 | ||
128 | #define while_each_pid_task(pid, type, task) \ | 128 | #define while_each_pid_task(pid, type, task) \ |
129 | } \ | 129 | } \ |
130 | } while (0) | 130 | } while (0) |
131 | 131 | ||
132 | #endif /* _LINUX_PID_H */ | 132 | #endif /* _LINUX_PID_H */ |
diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h index 63df898fe2e9..84d887751855 100644 --- a/include/linux/raid/bitmap.h +++ b/include/linux/raid/bitmap.h | |||
@@ -265,6 +265,8 @@ int bitmap_update_sb(struct bitmap *bitmap); | |||
265 | int bitmap_setallbits(struct bitmap *bitmap); | 265 | int bitmap_setallbits(struct bitmap *bitmap); |
266 | void bitmap_write_all(struct bitmap *bitmap); | 266 | void bitmap_write_all(struct bitmap *bitmap); |
267 | 267 | ||
268 | void bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e); | ||
269 | |||
268 | /* these are exported */ | 270 | /* these are exported */ |
269 | int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, | 271 | int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, |
270 | unsigned long sectors, int behind); | 272 | unsigned long sectors, int behind); |
diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h index c588709acbbc..866a1e2b0ce0 100644 --- a/include/linux/raid/md.h +++ b/include/linux/raid/md.h | |||
@@ -95,7 +95,6 @@ extern int sync_page_io(struct block_device *bdev, sector_t sector, int size, | |||
95 | extern void md_do_sync(mddev_t *mddev); | 95 | extern void md_do_sync(mddev_t *mddev); |
96 | extern void md_new_event(mddev_t *mddev); | 96 | extern void md_new_event(mddev_t *mddev); |
97 | 97 | ||
98 | extern void md_update_sb(mddev_t * mddev); | ||
99 | 98 | ||
100 | #endif /* CONFIG_MD */ | 99 | #endif /* CONFIG_MD */ |
101 | #endif | 100 | #endif |
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index 920b94fe31fa..8245c282168b 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h | |||
@@ -31,18 +31,15 @@ | |||
31 | #define LEVEL_NONE (-1000000) | 31 | #define LEVEL_NONE (-1000000) |
32 | 32 | ||
33 | #define MaxSector (~(sector_t)0) | 33 | #define MaxSector (~(sector_t)0) |
34 | #define MD_THREAD_NAME_MAX 14 | ||
35 | 34 | ||
36 | typedef struct mddev_s mddev_t; | 35 | typedef struct mddev_s mddev_t; |
37 | typedef struct mdk_rdev_s mdk_rdev_t; | 36 | typedef struct mdk_rdev_s mdk_rdev_t; |
38 | 37 | ||
39 | #define MAX_MD_DEVS 256 /* Max number of md dev */ | ||
40 | |||
41 | /* | 38 | /* |
42 | * options passed in raidrun: | 39 | * options passed in raidrun: |
43 | */ | 40 | */ |
44 | 41 | ||
45 | /* Currently this must fix in an 'int' */ | 42 | /* Currently this must fit in an 'int' */ |
46 | #define MAX_CHUNK_SIZE (1<<30) | 43 | #define MAX_CHUNK_SIZE (1<<30) |
47 | 44 | ||
48 | /* | 45 | /* |
@@ -116,7 +113,11 @@ struct mddev_s | |||
116 | dev_t unit; | 113 | dev_t unit; |
117 | int md_minor; | 114 | int md_minor; |
118 | struct list_head disks; | 115 | struct list_head disks; |
119 | int sb_dirty; | 116 | unsigned long flags; |
117 | #define MD_CHANGE_DEVS 0 /* Some device status has changed */ | ||
118 | #define MD_CHANGE_CLEAN 1 /* transition to or from 'clean' */ | ||
119 | #define MD_CHANGE_PENDING 2 /* superblock update in progress */ | ||
120 | |||
120 | int ro; | 121 | int ro; |
121 | 122 | ||
122 | struct gendisk *gendisk; | 123 | struct gendisk *gendisk; |
diff --git a/include/linux/raid/md_u.h b/include/linux/raid/md_u.h index 81da20ccec4d..7192035fc4b0 100644 --- a/include/linux/raid/md_u.h +++ b/include/linux/raid/md_u.h | |||
@@ -41,7 +41,7 @@ | |||
41 | 41 | ||
42 | /* usage */ | 42 | /* usage */ |
43 | #define RUN_ARRAY _IOW (MD_MAJOR, 0x30, mdu_param_t) | 43 | #define RUN_ARRAY _IOW (MD_MAJOR, 0x30, mdu_param_t) |
44 | #define START_ARRAY _IO (MD_MAJOR, 0x31) | 44 | /* 0x31 was START_ARRAY */ |
45 | #define STOP_ARRAY _IO (MD_MAJOR, 0x32) | 45 | #define STOP_ARRAY _IO (MD_MAJOR, 0x32) |
46 | #define STOP_ARRAY_RO _IO (MD_MAJOR, 0x33) | 46 | #define STOP_ARRAY_RO _IO (MD_MAJOR, 0x33) |
47 | #define RESTART_ARRAY_RW _IO (MD_MAJOR, 0x34) | 47 | #define RESTART_ARRAY_RW _IO (MD_MAJOR, 0x34) |
diff --git a/include/linux/raid/raid1.h b/include/linux/raid/raid1.h index 3009c813d83d..0a9ba7c3302e 100644 --- a/include/linux/raid/raid1.h +++ b/include/linux/raid/raid1.h | |||
@@ -30,7 +30,6 @@ struct r1_private_data_s { | |||
30 | mddev_t *mddev; | 30 | mddev_t *mddev; |
31 | mirror_info_t *mirrors; | 31 | mirror_info_t *mirrors; |
32 | int raid_disks; | 32 | int raid_disks; |
33 | int working_disks; | ||
34 | int last_used; | 33 | int last_used; |
35 | sector_t next_seq_sect; | 34 | sector_t next_seq_sect; |
36 | spinlock_t device_lock; | 35 | spinlock_t device_lock; |
diff --git a/include/linux/raid/raid10.h b/include/linux/raid/raid10.h index c41e56a7c090..e9091cfeb286 100644 --- a/include/linux/raid/raid10.h +++ b/include/linux/raid/raid10.h | |||
@@ -16,7 +16,6 @@ struct r10_private_data_s { | |||
16 | mddev_t *mddev; | 16 | mddev_t *mddev; |
17 | mirror_info_t *mirrors; | 17 | mirror_info_t *mirrors; |
18 | int raid_disks; | 18 | int raid_disks; |
19 | int working_disks; | ||
20 | spinlock_t device_lock; | 19 | spinlock_t device_lock; |
21 | 20 | ||
22 | /* geometry */ | 21 | /* geometry */ |
diff --git a/include/linux/raid/raid5.h b/include/linux/raid/raid5.h index 20ed4c997636..f13299a15591 100644 --- a/include/linux/raid/raid5.h +++ b/include/linux/raid/raid5.h | |||
@@ -195,8 +195,9 @@ struct stripe_head { | |||
195 | * it to the count of prereading stripes. | 195 | * it to the count of prereading stripes. |
196 | * When write is initiated, or the stripe refcnt == 0 (just in case) we | 196 | * When write is initiated, or the stripe refcnt == 0 (just in case) we |
197 | * clear the PREREAD_ACTIVE flag and decrement the count | 197 | * clear the PREREAD_ACTIVE flag and decrement the count |
198 | * Whenever the delayed queue is empty and the device is not plugged, we | 198 | * Whenever the 'handle' queue is empty and the device is not plugged, we |
199 | * move any strips from delayed to handle and clear the DELAYED flag and set PREREAD_ACTIVE. | 199 | * move any strips from delayed to handle and clear the DELAYED flag and set |
200 | * PREREAD_ACTIVE. | ||
200 | * In stripe_handle, if we find pre-reading is necessary, we do it if | 201 | * In stripe_handle, if we find pre-reading is necessary, we do it if |
201 | * PREREAD_ACTIVE is set, else we set DELAYED which will send it to the delayed queue. | 202 | * PREREAD_ACTIVE is set, else we set DELAYED which will send it to the delayed queue. |
202 | * HANDLE gets cleared if stripe_handle leave nothing locked. | 203 | * HANDLE gets cleared if stripe_handle leave nothing locked. |
@@ -213,7 +214,7 @@ struct raid5_private_data { | |||
213 | struct disk_info *spare; | 214 | struct disk_info *spare; |
214 | int chunk_size, level, algorithm; | 215 | int chunk_size, level, algorithm; |
215 | int max_degraded; | 216 | int max_degraded; |
216 | int raid_disks, working_disks, failed_disks; | 217 | int raid_disks; |
217 | int max_nr_stripes; | 218 | int max_nr_stripes; |
218 | 219 | ||
219 | /* used during an expand */ | 220 | /* used during an expand */ |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 38530232d92f..331f4502e92b 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -625,9 +625,17 @@ enum idle_type | |||
625 | #define SD_WAKE_BALANCE 64 /* Perform balancing at task wakeup */ | 625 | #define SD_WAKE_BALANCE 64 /* Perform balancing at task wakeup */ |
626 | #define SD_SHARE_CPUPOWER 128 /* Domain members share cpu power */ | 626 | #define SD_SHARE_CPUPOWER 128 /* Domain members share cpu power */ |
627 | #define SD_POWERSAVINGS_BALANCE 256 /* Balance for power savings */ | 627 | #define SD_POWERSAVINGS_BALANCE 256 /* Balance for power savings */ |
628 | #define SD_SHARE_PKG_RESOURCES 512 /* Domain members share cpu pkg resources */ | ||
628 | 629 | ||
629 | #define BALANCE_FOR_POWER ((sched_mc_power_savings || sched_smt_power_savings) \ | 630 | #define BALANCE_FOR_MC_POWER \ |
630 | ? SD_POWERSAVINGS_BALANCE : 0) | 631 | (sched_smt_power_savings ? SD_POWERSAVINGS_BALANCE : 0) |
632 | |||
633 | #define BALANCE_FOR_PKG_POWER \ | ||
634 | ((sched_mc_power_savings || sched_smt_power_savings) ? \ | ||
635 | SD_POWERSAVINGS_BALANCE : 0) | ||
636 | |||
637 | #define test_sd_parent(sd, flag) ((sd->parent && \ | ||
638 | (sd->parent->flags & flag)) ? 1 : 0) | ||
631 | 639 | ||
632 | 640 | ||
633 | struct sched_group { | 641 | struct sched_group { |
@@ -644,6 +652,7 @@ struct sched_group { | |||
644 | struct sched_domain { | 652 | struct sched_domain { |
645 | /* These fields must be setup */ | 653 | /* These fields must be setup */ |
646 | struct sched_domain *parent; /* top domain must be null terminated */ | 654 | struct sched_domain *parent; /* top domain must be null terminated */ |
655 | struct sched_domain *child; /* bottom domain must be null terminated */ | ||
647 | struct sched_group *groups; /* the balancing groups of the domain */ | 656 | struct sched_group *groups; /* the balancing groups of the domain */ |
648 | cpumask_t span; /* span of all CPUs in this domain */ | 657 | cpumask_t span; /* span of all CPUs in this domain */ |
649 | unsigned long min_interval; /* Minimum balance interval ms */ | 658 | unsigned long min_interval; /* Minimum balance interval ms */ |
diff --git a/include/linux/stat.h b/include/linux/stat.h index 8669291352db..679ef0d70b6b 100644 --- a/include/linux/stat.h +++ b/include/linux/stat.h | |||
@@ -57,7 +57,7 @@ | |||
57 | #include <linux/time.h> | 57 | #include <linux/time.h> |
58 | 58 | ||
59 | struct kstat { | 59 | struct kstat { |
60 | unsigned long ino; | 60 | u64 ino; |
61 | dev_t dev; | 61 | dev_t dev; |
62 | umode_t mode; | 62 | umode_t mode; |
63 | unsigned int nlink; | 63 | unsigned int nlink; |
diff --git a/include/linux/topology.h b/include/linux/topology.h index ec1eca85290a..da508d1998e4 100644 --- a/include/linux/topology.h +++ b/include/linux/topology.h | |||
@@ -89,6 +89,7 @@ | |||
89 | #define SD_SIBLING_INIT (struct sched_domain) { \ | 89 | #define SD_SIBLING_INIT (struct sched_domain) { \ |
90 | .span = CPU_MASK_NONE, \ | 90 | .span = CPU_MASK_NONE, \ |
91 | .parent = NULL, \ | 91 | .parent = NULL, \ |
92 | .child = NULL, \ | ||
92 | .groups = NULL, \ | 93 | .groups = NULL, \ |
93 | .min_interval = 1, \ | 94 | .min_interval = 1, \ |
94 | .max_interval = 2, \ | 95 | .max_interval = 2, \ |
@@ -114,11 +115,44 @@ | |||
114 | #endif | 115 | #endif |
115 | #endif /* CONFIG_SCHED_SMT */ | 116 | #endif /* CONFIG_SCHED_SMT */ |
116 | 117 | ||
118 | #ifdef CONFIG_SCHED_MC | ||
119 | /* Common values for MC siblings. for now mostly derived from SD_CPU_INIT */ | ||
120 | #ifndef SD_MC_INIT | ||
121 | #define SD_MC_INIT (struct sched_domain) { \ | ||
122 | .span = CPU_MASK_NONE, \ | ||
123 | .parent = NULL, \ | ||
124 | .child = NULL, \ | ||
125 | .groups = NULL, \ | ||
126 | .min_interval = 1, \ | ||
127 | .max_interval = 4, \ | ||
128 | .busy_factor = 64, \ | ||
129 | .imbalance_pct = 125, \ | ||
130 | .cache_nice_tries = 1, \ | ||
131 | .per_cpu_gain = 100, \ | ||
132 | .busy_idx = 2, \ | ||
133 | .idle_idx = 1, \ | ||
134 | .newidle_idx = 2, \ | ||
135 | .wake_idx = 1, \ | ||
136 | .forkexec_idx = 1, \ | ||
137 | .flags = SD_LOAD_BALANCE \ | ||
138 | | SD_BALANCE_NEWIDLE \ | ||
139 | | SD_BALANCE_EXEC \ | ||
140 | | SD_WAKE_AFFINE \ | ||
141 | | SD_SHARE_PKG_RESOURCES\ | ||
142 | | BALANCE_FOR_MC_POWER, \ | ||
143 | .last_balance = jiffies, \ | ||
144 | .balance_interval = 1, \ | ||
145 | .nr_balance_failed = 0, \ | ||
146 | } | ||
147 | #endif | ||
148 | #endif /* CONFIG_SCHED_MC */ | ||
149 | |||
117 | /* Common values for CPUs */ | 150 | /* Common values for CPUs */ |
118 | #ifndef SD_CPU_INIT | 151 | #ifndef SD_CPU_INIT |
119 | #define SD_CPU_INIT (struct sched_domain) { \ | 152 | #define SD_CPU_INIT (struct sched_domain) { \ |
120 | .span = CPU_MASK_NONE, \ | 153 | .span = CPU_MASK_NONE, \ |
121 | .parent = NULL, \ | 154 | .parent = NULL, \ |
155 | .child = NULL, \ | ||
122 | .groups = NULL, \ | 156 | .groups = NULL, \ |
123 | .min_interval = 1, \ | 157 | .min_interval = 1, \ |
124 | .max_interval = 4, \ | 158 | .max_interval = 4, \ |
@@ -135,7 +169,7 @@ | |||
135 | | SD_BALANCE_NEWIDLE \ | 169 | | SD_BALANCE_NEWIDLE \ |
136 | | SD_BALANCE_EXEC \ | 170 | | SD_BALANCE_EXEC \ |
137 | | SD_WAKE_AFFINE \ | 171 | | SD_WAKE_AFFINE \ |
138 | | BALANCE_FOR_POWER, \ | 172 | | BALANCE_FOR_PKG_POWER,\ |
139 | .last_balance = jiffies, \ | 173 | .last_balance = jiffies, \ |
140 | .balance_interval = 1, \ | 174 | .balance_interval = 1, \ |
141 | .nr_balance_failed = 0, \ | 175 | .nr_balance_failed = 0, \ |
@@ -146,6 +180,7 @@ | |||
146 | #define SD_ALLNODES_INIT (struct sched_domain) { \ | 180 | #define SD_ALLNODES_INIT (struct sched_domain) { \ |
147 | .span = CPU_MASK_NONE, \ | 181 | .span = CPU_MASK_NONE, \ |
148 | .parent = NULL, \ | 182 | .parent = NULL, \ |
183 | .child = NULL, \ | ||
149 | .groups = NULL, \ | 184 | .groups = NULL, \ |
150 | .min_interval = 64, \ | 185 | .min_interval = 64, \ |
151 | .max_interval = 64*num_online_cpus(), \ | 186 | .max_interval = 64*num_online_cpus(), \ |
@@ -165,15 +200,6 @@ | |||
165 | .nr_balance_failed = 0, \ | 200 | .nr_balance_failed = 0, \ |
166 | } | 201 | } |
167 | 202 | ||
168 | #ifdef CONFIG_SCHED_MC | ||
169 | #ifndef SD_MC_INIT | ||
170 | /* for now its same as SD_CPU_INIT. | ||
171 | * TBD: Tune Domain parameters! | ||
172 | */ | ||
173 | #define SD_MC_INIT SD_CPU_INIT | ||
174 | #endif | ||
175 | #endif | ||
176 | |||
177 | #ifdef CONFIG_NUMA | 203 | #ifdef CONFIG_NUMA |
178 | #ifndef SD_NODE_INIT | 204 | #ifndef SD_NODE_INIT |
179 | #error Please define an appropriate SD_NODE_INIT in include/asm/topology.h!!! | 205 | #error Please define an appropriate SD_NODE_INIT in include/asm/topology.h!!! |
diff --git a/include/video/sstfb.h b/include/video/sstfb.h index 3570f9c9b111..5dbf5e7e50a8 100644 --- a/include/video/sstfb.h +++ b/include/video/sstfb.h | |||
@@ -68,10 +68,6 @@ | |||
68 | # define print_var(X,Y...) | 68 | # define print_var(X,Y...) |
69 | #endif | 69 | #endif |
70 | 70 | ||
71 | #define eprintk(X...) printk(KERN_ERR "sstfb: " X) | ||
72 | #define iprintk(X...) printk(KERN_INFO "sstfb: " X) | ||
73 | #define wprintk(X...) printk(KERN_WARNING "sstfb: " X) | ||
74 | |||
75 | #define BIT(x) (1ul<<(x)) | 71 | #define BIT(x) (1ul<<(x)) |
76 | #define POW2(x) (1ul<<(x)) | 72 | #define POW2(x) (1ul<<(x)) |
77 | 73 | ||
diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c index 2429e1bf8c60..753dc54a6649 100644 --- a/init/do_mounts_md.c +++ b/init/do_mounts_md.c | |||
@@ -20,7 +20,7 @@ static struct { | |||
20 | int level; | 20 | int level; |
21 | int chunk; | 21 | int chunk; |
22 | char *device_names; | 22 | char *device_names; |
23 | } md_setup_args[MAX_MD_DEVS] __initdata; | 23 | } md_setup_args[256] __initdata; |
24 | 24 | ||
25 | static int md_setup_ents __initdata; | 25 | static int md_setup_ents __initdata; |
26 | 26 | ||
@@ -61,10 +61,6 @@ static int __init md_setup(char *str) | |||
61 | return 0; | 61 | return 0; |
62 | } | 62 | } |
63 | str1 = str; | 63 | str1 = str; |
64 | if (minor >= MAX_MD_DEVS) { | ||
65 | printk(KERN_WARNING "md: md=%d, Minor device number too high.\n", minor); | ||
66 | return 0; | ||
67 | } | ||
68 | for (ent=0 ; ent< md_setup_ents ; ent++) | 64 | for (ent=0 ; ent< md_setup_ents ; ent++) |
69 | if (md_setup_args[ent].minor == minor && | 65 | if (md_setup_args[ent].minor == minor && |
70 | md_setup_args[ent].partitioned == partitioned) { | 66 | md_setup_args[ent].partitioned == partitioned) { |
@@ -72,7 +68,7 @@ static int __init md_setup(char *str) | |||
72 | "Replacing previous definition.\n", partitioned?"d":"", minor); | 68 | "Replacing previous definition.\n", partitioned?"d":"", minor); |
73 | break; | 69 | break; |
74 | } | 70 | } |
75 | if (ent >= MAX_MD_DEVS) { | 71 | if (ent >= ARRAY_SIZE(md_setup_args)) { |
76 | printk(KERN_WARNING "md: md=%s%d - too many md initialisations\n", partitioned?"d":"", minor); | 72 | printk(KERN_WARNING "md: md=%s%d - too many md initialisations\n", partitioned?"d":"", minor); |
77 | return 0; | 73 | return 0; |
78 | } | 74 | } |
diff --git a/kernel/dma.c b/kernel/dma.c index aef0a45b7893..2020644c938a 100644 --- a/kernel/dma.c +++ b/kernel/dma.c | |||
@@ -62,6 +62,11 @@ static struct dma_chan dma_chan_busy[MAX_DMA_CHANNELS] = { | |||
62 | }; | 62 | }; |
63 | 63 | ||
64 | 64 | ||
65 | /** | ||
66 | * request_dma - request and reserve a system DMA channel | ||
67 | * @dmanr: DMA channel number | ||
68 | * @device_id: reserving device ID string, used in /proc/dma | ||
69 | */ | ||
65 | int request_dma(unsigned int dmanr, const char * device_id) | 70 | int request_dma(unsigned int dmanr, const char * device_id) |
66 | { | 71 | { |
67 | if (dmanr >= MAX_DMA_CHANNELS) | 72 | if (dmanr >= MAX_DMA_CHANNELS) |
@@ -76,7 +81,10 @@ int request_dma(unsigned int dmanr, const char * device_id) | |||
76 | return 0; | 81 | return 0; |
77 | } /* request_dma */ | 82 | } /* request_dma */ |
78 | 83 | ||
79 | 84 | /** | |
85 | * free_dma - free a reserved system DMA channel | ||
86 | * @dmanr: DMA channel number | ||
87 | */ | ||
80 | void free_dma(unsigned int dmanr) | 88 | void free_dma(unsigned int dmanr) |
81 | { | 89 | { |
82 | if (dmanr >= MAX_DMA_CHANNELS) { | 90 | if (dmanr >= MAX_DMA_CHANNELS) { |
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c index 342bca62c496..eeac3e313b2b 100644 --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c | |||
@@ -69,6 +69,15 @@ static inline int is_kernel(unsigned long addr) | |||
69 | return in_gate_area_no_task(addr); | 69 | return in_gate_area_no_task(addr); |
70 | } | 70 | } |
71 | 71 | ||
72 | static int is_ksym_addr(unsigned long addr) | ||
73 | { | ||
74 | if (all_var) | ||
75 | return is_kernel(addr); | ||
76 | |||
77 | return is_kernel_text(addr) || is_kernel_inittext(addr) || | ||
78 | is_kernel_extratext(addr); | ||
79 | } | ||
80 | |||
72 | /* expand a compressed symbol data into the resulting uncompressed string, | 81 | /* expand a compressed symbol data into the resulting uncompressed string, |
73 | given the offset to where the symbol is in the compressed stream */ | 82 | given the offset to where the symbol is in the compressed stream */ |
74 | static unsigned int kallsyms_expand_symbol(unsigned int off, char *result) | 83 | static unsigned int kallsyms_expand_symbol(unsigned int off, char *result) |
@@ -155,6 +164,73 @@ unsigned long kallsyms_lookup_name(const char *name) | |||
155 | return module_kallsyms_lookup_name(name); | 164 | return module_kallsyms_lookup_name(name); |
156 | } | 165 | } |
157 | 166 | ||
167 | static unsigned long get_symbol_pos(unsigned long addr, | ||
168 | unsigned long *symbolsize, | ||
169 | unsigned long *offset) | ||
170 | { | ||
171 | unsigned long symbol_start = 0, symbol_end = 0; | ||
172 | unsigned long i, low, high, mid; | ||
173 | |||
174 | /* This kernel should never had been booted. */ | ||
175 | BUG_ON(!kallsyms_addresses); | ||
176 | |||
177 | /* do a binary search on the sorted kallsyms_addresses array */ | ||
178 | low = 0; | ||
179 | high = kallsyms_num_syms; | ||
180 | |||
181 | while (high - low > 1) { | ||
182 | mid = (low + high) / 2; | ||
183 | if (kallsyms_addresses[mid] <= addr) | ||
184 | low = mid; | ||
185 | else | ||
186 | high = mid; | ||
187 | } | ||
188 | |||
189 | /* | ||
190 | * search for the first aliased symbol. Aliased | ||
191 | * symbols are symbols with the same address | ||
192 | */ | ||
193 | while (low && kallsyms_addresses[low-1] == kallsyms_addresses[low]) | ||
194 | --low; | ||
195 | |||
196 | symbol_start = kallsyms_addresses[low]; | ||
197 | |||
198 | /* Search for next non-aliased symbol */ | ||
199 | for (i = low + 1; i < kallsyms_num_syms; i++) { | ||
200 | if (kallsyms_addresses[i] > symbol_start) { | ||
201 | symbol_end = kallsyms_addresses[i]; | ||
202 | break; | ||
203 | } | ||
204 | } | ||
205 | |||
206 | /* if we found no next symbol, we use the end of the section */ | ||
207 | if (!symbol_end) { | ||
208 | if (is_kernel_inittext(addr)) | ||
209 | symbol_end = (unsigned long)_einittext; | ||
210 | else if (all_var) | ||
211 | symbol_end = (unsigned long)_end; | ||
212 | else | ||
213 | symbol_end = (unsigned long)_etext; | ||
214 | } | ||
215 | |||
216 | *symbolsize = symbol_end - symbol_start; | ||
217 | *offset = addr - symbol_start; | ||
218 | |||
219 | return low; | ||
220 | } | ||
221 | |||
222 | /* | ||
223 | * Lookup an address but don't bother to find any names. | ||
224 | */ | ||
225 | int kallsyms_lookup_size_offset(unsigned long addr, unsigned long *symbolsize, | ||
226 | unsigned long *offset) | ||
227 | { | ||
228 | if (is_ksym_addr(addr)) | ||
229 | return !!get_symbol_pos(addr, symbolsize, offset); | ||
230 | |||
231 | return !!module_address_lookup(addr, symbolsize, offset, NULL); | ||
232 | } | ||
233 | |||
158 | /* | 234 | /* |
159 | * Lookup an address | 235 | * Lookup an address |
160 | * - modname is set to NULL if it's in the kernel | 236 | * - modname is set to NULL if it's in the kernel |
@@ -167,57 +243,18 @@ const char *kallsyms_lookup(unsigned long addr, | |||
167 | unsigned long *offset, | 243 | unsigned long *offset, |
168 | char **modname, char *namebuf) | 244 | char **modname, char *namebuf) |
169 | { | 245 | { |
170 | unsigned long i, low, high, mid; | ||
171 | const char *msym; | 246 | const char *msym; |
172 | 247 | ||
173 | /* This kernel should never had been booted. */ | ||
174 | BUG_ON(!kallsyms_addresses); | ||
175 | |||
176 | namebuf[KSYM_NAME_LEN] = 0; | 248 | namebuf[KSYM_NAME_LEN] = 0; |
177 | namebuf[0] = 0; | 249 | namebuf[0] = 0; |
178 | 250 | ||
179 | if ((all_var && is_kernel(addr)) || | 251 | if (is_ksym_addr(addr)) { |
180 | (!all_var && (is_kernel_text(addr) || is_kernel_inittext(addr) || | 252 | unsigned long pos; |
181 | is_kernel_extratext(addr)))) { | ||
182 | unsigned long symbol_end = 0; | ||
183 | |||
184 | /* do a binary search on the sorted kallsyms_addresses array */ | ||
185 | low = 0; | ||
186 | high = kallsyms_num_syms; | ||
187 | |||
188 | while (high-low > 1) { | ||
189 | mid = (low + high) / 2; | ||
190 | if (kallsyms_addresses[mid] <= addr) low = mid; | ||
191 | else high = mid; | ||
192 | } | ||
193 | |||
194 | /* search for the first aliased symbol. Aliased symbols are | ||
195 | symbols with the same address */ | ||
196 | while (low && kallsyms_addresses[low - 1] == kallsyms_addresses[low]) | ||
197 | --low; | ||
198 | 253 | ||
254 | pos = get_symbol_pos(addr, symbolsize, offset); | ||
199 | /* Grab name */ | 255 | /* Grab name */ |
200 | kallsyms_expand_symbol(get_symbol_offset(low), namebuf); | 256 | kallsyms_expand_symbol(get_symbol_offset(pos), namebuf); |
201 | |||
202 | /* Search for next non-aliased symbol */ | ||
203 | for (i = low + 1; i < kallsyms_num_syms; i++) { | ||
204 | if (kallsyms_addresses[i] > kallsyms_addresses[low]) { | ||
205 | symbol_end = kallsyms_addresses[i]; | ||
206 | break; | ||
207 | } | ||
208 | } | ||
209 | |||
210 | /* if we found no next symbol, we use the end of the section */ | ||
211 | if (!symbol_end) { | ||
212 | if (is_kernel_inittext(addr)) | ||
213 | symbol_end = (unsigned long)_einittext; | ||
214 | else | ||
215 | symbol_end = all_var ? (unsigned long)_end : (unsigned long)_etext; | ||
216 | } | ||
217 | |||
218 | *symbolsize = symbol_end - kallsyms_addresses[low]; | ||
219 | *modname = NULL; | 257 | *modname = NULL; |
220 | *offset = addr - kallsyms_addresses[low]; | ||
221 | return namebuf; | 258 | return namebuf; |
222 | } | 259 | } |
223 | 260 | ||
diff --git a/kernel/module.c b/kernel/module.c index 7c77a0a9275c..7f60e782de1e 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -2040,7 +2040,8 @@ const char *module_address_lookup(unsigned long addr, | |||
2040 | list_for_each_entry(mod, &modules, list) { | 2040 | list_for_each_entry(mod, &modules, list) { |
2041 | if (within(addr, mod->module_init, mod->init_size) | 2041 | if (within(addr, mod->module_init, mod->init_size) |
2042 | || within(addr, mod->module_core, mod->core_size)) { | 2042 | || within(addr, mod->module_core, mod->core_size)) { |
2043 | *modname = mod->name; | 2043 | if (modname) |
2044 | *modname = mod->name; | ||
2044 | return get_ksymbol(mod, addr, size, offset); | 2045 | return get_ksymbol(mod, addr, size, offset); |
2045 | } | 2046 | } |
2046 | } | 2047 | } |
diff --git a/kernel/resource.c b/kernel/resource.c index 9db38a1a7520..6de60c12143e 100644 --- a/kernel/resource.c +++ b/kernel/resource.c | |||
@@ -193,6 +193,13 @@ static int __release_resource(struct resource *old) | |||
193 | return -EINVAL; | 193 | return -EINVAL; |
194 | } | 194 | } |
195 | 195 | ||
196 | /** | ||
197 | * request_resource - request and reserve an I/O or memory resource | ||
198 | * @root: root resource descriptor | ||
199 | * @new: resource descriptor desired by caller | ||
200 | * | ||
201 | * Returns 0 for success, negative error code on error. | ||
202 | */ | ||
196 | int request_resource(struct resource *root, struct resource *new) | 203 | int request_resource(struct resource *root, struct resource *new) |
197 | { | 204 | { |
198 | struct resource *conflict; | 205 | struct resource *conflict; |
@@ -205,6 +212,15 @@ int request_resource(struct resource *root, struct resource *new) | |||
205 | 212 | ||
206 | EXPORT_SYMBOL(request_resource); | 213 | EXPORT_SYMBOL(request_resource); |
207 | 214 | ||
215 | /** | ||
216 | * ____request_resource - reserve a resource, with resource conflict returned | ||
217 | * @root: root resource descriptor | ||
218 | * @new: resource descriptor desired by caller | ||
219 | * | ||
220 | * Returns: | ||
221 | * On success, NULL is returned. | ||
222 | * On error, a pointer to the conflicting resource is returned. | ||
223 | */ | ||
208 | struct resource *____request_resource(struct resource *root, struct resource *new) | 224 | struct resource *____request_resource(struct resource *root, struct resource *new) |
209 | { | 225 | { |
210 | struct resource *conflict; | 226 | struct resource *conflict; |
@@ -217,6 +233,10 @@ struct resource *____request_resource(struct resource *root, struct resource *ne | |||
217 | 233 | ||
218 | EXPORT_SYMBOL(____request_resource); | 234 | EXPORT_SYMBOL(____request_resource); |
219 | 235 | ||
236 | /** | ||
237 | * release_resource - release a previously reserved resource | ||
238 | * @old: resource pointer | ||
239 | */ | ||
220 | int release_resource(struct resource *old) | 240 | int release_resource(struct resource *old) |
221 | { | 241 | { |
222 | int retval; | 242 | int retval; |
@@ -315,8 +335,16 @@ static int find_resource(struct resource *root, struct resource *new, | |||
315 | return -EBUSY; | 335 | return -EBUSY; |
316 | } | 336 | } |
317 | 337 | ||
318 | /* | 338 | /** |
319 | * Allocate empty slot in the resource tree given range and alignment. | 339 | * allocate_resource - allocate empty slot in the resource tree given range & alignment |
340 | * @root: root resource descriptor | ||
341 | * @new: resource descriptor desired by caller | ||
342 | * @size: requested resource region size | ||
343 | * @min: minimum size to allocate | ||
344 | * @max: maximum size to allocate | ||
345 | * @align: alignment requested, in bytes | ||
346 | * @alignf: alignment function, optional, called if not NULL | ||
347 | * @alignf_data: arbitrary data to pass to the @alignf function | ||
320 | */ | 348 | */ |
321 | int allocate_resource(struct resource *root, struct resource *new, | 349 | int allocate_resource(struct resource *root, struct resource *new, |
322 | resource_size_t size, resource_size_t min, | 350 | resource_size_t size, resource_size_t min, |
@@ -407,10 +435,15 @@ int insert_resource(struct resource *parent, struct resource *new) | |||
407 | return result; | 435 | return result; |
408 | } | 436 | } |
409 | 437 | ||
410 | /* | 438 | /** |
439 | * adjust_resource - modify a resource's start and size | ||
440 | * @res: resource to modify | ||
441 | * @start: new start value | ||
442 | * @size: new size | ||
443 | * | ||
411 | * Given an existing resource, change its start and size to match the | 444 | * Given an existing resource, change its start and size to match the |
412 | * arguments. Returns -EBUSY if it can't fit. Existing children of | 445 | * arguments. Returns 0 on success, -EBUSY if it can't fit. |
413 | * the resource are assumed to be immutable. | 446 | * Existing children of the resource are assumed to be immutable. |
414 | */ | 447 | */ |
415 | int adjust_resource(struct resource *res, resource_size_t start, resource_size_t size) | 448 | int adjust_resource(struct resource *res, resource_size_t start, resource_size_t size) |
416 | { | 449 | { |
@@ -456,11 +489,19 @@ EXPORT_SYMBOL(adjust_resource); | |||
456 | * Note how this, unlike the above, knows about | 489 | * Note how this, unlike the above, knows about |
457 | * the IO flag meanings (busy etc). | 490 | * the IO flag meanings (busy etc). |
458 | * | 491 | * |
459 | * Request-region creates a new busy region. | 492 | * request_region creates a new busy region. |
460 | * | 493 | * |
461 | * Check-region returns non-zero if the area is already busy | 494 | * check_region returns non-zero if the area is already busy. |
462 | * | 495 | * |
463 | * Release-region releases a matching busy region. | 496 | * release_region releases a matching busy region. |
497 | */ | ||
498 | |||
499 | /** | ||
500 | * __request_region - create a new busy resource region | ||
501 | * @parent: parent resource descriptor | ||
502 | * @start: resource start address | ||
503 | * @n: resource region size | ||
504 | * @name: reserving caller's ID string | ||
464 | */ | 505 | */ |
465 | struct resource * __request_region(struct resource *parent, | 506 | struct resource * __request_region(struct resource *parent, |
466 | resource_size_t start, resource_size_t n, | 507 | resource_size_t start, resource_size_t n, |
@@ -497,9 +538,23 @@ struct resource * __request_region(struct resource *parent, | |||
497 | } | 538 | } |
498 | return res; | 539 | return res; |
499 | } | 540 | } |
500 | |||
501 | EXPORT_SYMBOL(__request_region); | 541 | EXPORT_SYMBOL(__request_region); |
502 | 542 | ||
543 | /** | ||
544 | * __check_region - check if a resource region is busy or free | ||
545 | * @parent: parent resource descriptor | ||
546 | * @start: resource start address | ||
547 | * @n: resource region size | ||
548 | * | ||
549 | * Returns 0 if the region is free at the moment it is checked, | ||
550 | * returns %-EBUSY if the region is busy. | ||
551 | * | ||
552 | * NOTE: | ||
553 | * This function is deprecated because its use is racy. | ||
554 | * Even if it returns 0, a subsequent call to request_region() | ||
555 | * may fail because another driver etc. just allocated the region. | ||
556 | * Do NOT use it. It will be removed from the kernel. | ||
557 | */ | ||
503 | int __check_region(struct resource *parent, resource_size_t start, | 558 | int __check_region(struct resource *parent, resource_size_t start, |
504 | resource_size_t n) | 559 | resource_size_t n) |
505 | { | 560 | { |
@@ -513,9 +568,16 @@ int __check_region(struct resource *parent, resource_size_t start, | |||
513 | kfree(res); | 568 | kfree(res); |
514 | return 0; | 569 | return 0; |
515 | } | 570 | } |
516 | |||
517 | EXPORT_SYMBOL(__check_region); | 571 | EXPORT_SYMBOL(__check_region); |
518 | 572 | ||
573 | /** | ||
574 | * __release_region - release a previously reserved resource region | ||
575 | * @parent: parent resource descriptor | ||
576 | * @start: resource start address | ||
577 | * @n: resource region size | ||
578 | * | ||
579 | * The described resource region must match a currently busy region. | ||
580 | */ | ||
519 | void __release_region(struct resource *parent, resource_size_t start, | 581 | void __release_region(struct resource *parent, resource_size_t start, |
520 | resource_size_t n) | 582 | resource_size_t n) |
521 | { | 583 | { |
@@ -553,7 +615,6 @@ void __release_region(struct resource *parent, resource_size_t start, | |||
553 | "<%016llx-%016llx>\n", (unsigned long long)start, | 615 | "<%016llx-%016llx>\n", (unsigned long long)start, |
554 | (unsigned long long)end); | 616 | (unsigned long long)end); |
555 | } | 617 | } |
556 | |||
557 | EXPORT_SYMBOL(__release_region); | 618 | EXPORT_SYMBOL(__release_region); |
558 | 619 | ||
559 | /* | 620 | /* |
diff --git a/kernel/sched.c b/kernel/sched.c index e4e54e86f4a2..53608a59d6e3 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -1232,7 +1232,7 @@ nextgroup: | |||
1232 | } | 1232 | } |
1233 | 1233 | ||
1234 | /* | 1234 | /* |
1235 | * find_idlest_queue - find the idlest runqueue among the cpus in group. | 1235 | * find_idlest_cpu - find the idlest cpu among the cpus in group. |
1236 | */ | 1236 | */ |
1237 | static int | 1237 | static int |
1238 | find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu) | 1238 | find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu) |
@@ -1286,21 +1286,29 @@ static int sched_balance_self(int cpu, int flag) | |||
1286 | while (sd) { | 1286 | while (sd) { |
1287 | cpumask_t span; | 1287 | cpumask_t span; |
1288 | struct sched_group *group; | 1288 | struct sched_group *group; |
1289 | int new_cpu; | 1289 | int new_cpu, weight; |
1290 | int weight; | 1290 | |
1291 | if (!(sd->flags & flag)) { | ||
1292 | sd = sd->child; | ||
1293 | continue; | ||
1294 | } | ||
1291 | 1295 | ||
1292 | span = sd->span; | 1296 | span = sd->span; |
1293 | group = find_idlest_group(sd, t, cpu); | 1297 | group = find_idlest_group(sd, t, cpu); |
1294 | if (!group) | 1298 | if (!group) { |
1295 | goto nextlevel; | 1299 | sd = sd->child; |
1300 | continue; | ||
1301 | } | ||
1296 | 1302 | ||
1297 | new_cpu = find_idlest_cpu(group, t, cpu); | 1303 | new_cpu = find_idlest_cpu(group, t, cpu); |
1298 | if (new_cpu == -1 || new_cpu == cpu) | 1304 | if (new_cpu == -1 || new_cpu == cpu) { |
1299 | goto nextlevel; | 1305 | /* Now try balancing at a lower domain level of cpu */ |
1306 | sd = sd->child; | ||
1307 | continue; | ||
1308 | } | ||
1300 | 1309 | ||
1301 | /* Now try balancing at a lower domain level */ | 1310 | /* Now try balancing at a lower domain level of new_cpu */ |
1302 | cpu = new_cpu; | 1311 | cpu = new_cpu; |
1303 | nextlevel: | ||
1304 | sd = NULL; | 1312 | sd = NULL; |
1305 | weight = cpus_weight(span); | 1313 | weight = cpus_weight(span); |
1306 | for_each_domain(cpu, tmp) { | 1314 | for_each_domain(cpu, tmp) { |
@@ -2533,8 +2541,14 @@ static int load_balance(int this_cpu, struct rq *this_rq, | |||
2533 | struct rq *busiest; | 2541 | struct rq *busiest; |
2534 | cpumask_t cpus = CPU_MASK_ALL; | 2542 | cpumask_t cpus = CPU_MASK_ALL; |
2535 | 2543 | ||
2544 | /* | ||
2545 | * When power savings policy is enabled for the parent domain, idle | ||
2546 | * sibling can pick up load irrespective of busy siblings. In this case, | ||
2547 | * let the state of idle sibling percolate up as IDLE, instead of | ||
2548 | * portraying it as NOT_IDLE. | ||
2549 | */ | ||
2536 | if (idle != NOT_IDLE && sd->flags & SD_SHARE_CPUPOWER && | 2550 | if (idle != NOT_IDLE && sd->flags & SD_SHARE_CPUPOWER && |
2537 | !sched_smt_power_savings) | 2551 | !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE)) |
2538 | sd_idle = 1; | 2552 | sd_idle = 1; |
2539 | 2553 | ||
2540 | schedstat_inc(sd, lb_cnt[idle]); | 2554 | schedstat_inc(sd, lb_cnt[idle]); |
@@ -2630,7 +2644,7 @@ redo: | |||
2630 | } | 2644 | } |
2631 | 2645 | ||
2632 | if (!nr_moved && !sd_idle && sd->flags & SD_SHARE_CPUPOWER && | 2646 | if (!nr_moved && !sd_idle && sd->flags & SD_SHARE_CPUPOWER && |
2633 | !sched_smt_power_savings) | 2647 | !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE)) |
2634 | return -1; | 2648 | return -1; |
2635 | return nr_moved; | 2649 | return nr_moved; |
2636 | 2650 | ||
@@ -2646,7 +2660,7 @@ out_one_pinned: | |||
2646 | sd->balance_interval *= 2; | 2660 | sd->balance_interval *= 2; |
2647 | 2661 | ||
2648 | if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER && | 2662 | if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER && |
2649 | !sched_smt_power_savings) | 2663 | !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE)) |
2650 | return -1; | 2664 | return -1; |
2651 | return 0; | 2665 | return 0; |
2652 | } | 2666 | } |
@@ -2668,7 +2682,14 @@ load_balance_newidle(int this_cpu, struct rq *this_rq, struct sched_domain *sd) | |||
2668 | int sd_idle = 0; | 2682 | int sd_idle = 0; |
2669 | cpumask_t cpus = CPU_MASK_ALL; | 2683 | cpumask_t cpus = CPU_MASK_ALL; |
2670 | 2684 | ||
2671 | if (sd->flags & SD_SHARE_CPUPOWER && !sched_smt_power_savings) | 2685 | /* |
2686 | * When power savings policy is enabled for the parent domain, idle | ||
2687 | * sibling can pick up load irrespective of busy siblings. In this case, | ||
2688 | * let the state of idle sibling percolate up as IDLE, instead of | ||
2689 | * portraying it as NOT_IDLE. | ||
2690 | */ | ||
2691 | if (sd->flags & SD_SHARE_CPUPOWER && | ||
2692 | !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE)) | ||
2672 | sd_idle = 1; | 2693 | sd_idle = 1; |
2673 | 2694 | ||
2674 | schedstat_inc(sd, lb_cnt[NEWLY_IDLE]); | 2695 | schedstat_inc(sd, lb_cnt[NEWLY_IDLE]); |
@@ -2709,7 +2730,8 @@ redo: | |||
2709 | 2730 | ||
2710 | if (!nr_moved) { | 2731 | if (!nr_moved) { |
2711 | schedstat_inc(sd, lb_failed[NEWLY_IDLE]); | 2732 | schedstat_inc(sd, lb_failed[NEWLY_IDLE]); |
2712 | if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER) | 2733 | if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER && |
2734 | !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE)) | ||
2713 | return -1; | 2735 | return -1; |
2714 | } else | 2736 | } else |
2715 | sd->nr_balance_failed = 0; | 2737 | sd->nr_balance_failed = 0; |
@@ -2719,7 +2741,7 @@ redo: | |||
2719 | out_balanced: | 2741 | out_balanced: |
2720 | schedstat_inc(sd, lb_balanced[NEWLY_IDLE]); | 2742 | schedstat_inc(sd, lb_balanced[NEWLY_IDLE]); |
2721 | if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER && | 2743 | if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER && |
2722 | !sched_smt_power_savings) | 2744 | !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE)) |
2723 | return -1; | 2745 | return -1; |
2724 | sd->nr_balance_failed = 0; | 2746 | sd->nr_balance_failed = 0; |
2725 | 2747 | ||
@@ -4817,7 +4839,7 @@ void show_state(void) | |||
4817 | * NOTE: this function does not set the idle thread's NEED_RESCHED | 4839 | * NOTE: this function does not set the idle thread's NEED_RESCHED |
4818 | * flag, to make booting more robust. | 4840 | * flag, to make booting more robust. |
4819 | */ | 4841 | */ |
4820 | void __devinit init_idle(struct task_struct *idle, int cpu) | 4842 | void __cpuinit init_idle(struct task_struct *idle, int cpu) |
4821 | { | 4843 | { |
4822 | struct rq *rq = cpu_rq(cpu); | 4844 | struct rq *rq = cpu_rq(cpu); |
4823 | unsigned long flags; | 4845 | unsigned long flags; |
@@ -5392,7 +5414,9 @@ static int sd_degenerate(struct sched_domain *sd) | |||
5392 | if (sd->flags & (SD_LOAD_BALANCE | | 5414 | if (sd->flags & (SD_LOAD_BALANCE | |
5393 | SD_BALANCE_NEWIDLE | | 5415 | SD_BALANCE_NEWIDLE | |
5394 | SD_BALANCE_FORK | | 5416 | SD_BALANCE_FORK | |
5395 | SD_BALANCE_EXEC)) { | 5417 | SD_BALANCE_EXEC | |
5418 | SD_SHARE_CPUPOWER | | ||
5419 | SD_SHARE_PKG_RESOURCES)) { | ||
5396 | if (sd->groups != sd->groups->next) | 5420 | if (sd->groups != sd->groups->next) |
5397 | return 0; | 5421 | return 0; |
5398 | } | 5422 | } |
@@ -5426,7 +5450,9 @@ sd_parent_degenerate(struct sched_domain *sd, struct sched_domain *parent) | |||
5426 | pflags &= ~(SD_LOAD_BALANCE | | 5450 | pflags &= ~(SD_LOAD_BALANCE | |
5427 | SD_BALANCE_NEWIDLE | | 5451 | SD_BALANCE_NEWIDLE | |
5428 | SD_BALANCE_FORK | | 5452 | SD_BALANCE_FORK | |
5429 | SD_BALANCE_EXEC); | 5453 | SD_BALANCE_EXEC | |
5454 | SD_SHARE_CPUPOWER | | ||
5455 | SD_SHARE_PKG_RESOURCES); | ||
5430 | } | 5456 | } |
5431 | if (~cflags & pflags) | 5457 | if (~cflags & pflags) |
5432 | return 0; | 5458 | return 0; |
@@ -5448,12 +5474,18 @@ static void cpu_attach_domain(struct sched_domain *sd, int cpu) | |||
5448 | struct sched_domain *parent = tmp->parent; | 5474 | struct sched_domain *parent = tmp->parent; |
5449 | if (!parent) | 5475 | if (!parent) |
5450 | break; | 5476 | break; |
5451 | if (sd_parent_degenerate(tmp, parent)) | 5477 | if (sd_parent_degenerate(tmp, parent)) { |
5452 | tmp->parent = parent->parent; | 5478 | tmp->parent = parent->parent; |
5479 | if (parent->parent) | ||
5480 | parent->parent->child = tmp; | ||
5481 | } | ||
5453 | } | 5482 | } |
5454 | 5483 | ||
5455 | if (sd && sd_degenerate(sd)) | 5484 | if (sd && sd_degenerate(sd)) { |
5456 | sd = sd->parent; | 5485 | sd = sd->parent; |
5486 | if (sd) | ||
5487 | sd->child = NULL; | ||
5488 | } | ||
5457 | 5489 | ||
5458 | sched_domain_debug(sd, cpu); | 5490 | sched_domain_debug(sd, cpu); |
5459 | 5491 | ||
@@ -5461,7 +5493,7 @@ static void cpu_attach_domain(struct sched_domain *sd, int cpu) | |||
5461 | } | 5493 | } |
5462 | 5494 | ||
5463 | /* cpus with isolated domains */ | 5495 | /* cpus with isolated domains */ |
5464 | static cpumask_t __devinitdata cpu_isolated_map = CPU_MASK_NONE; | 5496 | static cpumask_t __cpuinitdata cpu_isolated_map = CPU_MASK_NONE; |
5465 | 5497 | ||
5466 | /* Setup the mask of cpus configured for isolated domains */ | 5498 | /* Setup the mask of cpus configured for isolated domains */ |
5467 | static int __init isolated_cpu_setup(char *str) | 5499 | static int __init isolated_cpu_setup(char *str) |
@@ -5489,15 +5521,17 @@ __setup ("isolcpus=", isolated_cpu_setup); | |||
5489 | * covered by the given span, and will set each group's ->cpumask correctly, | 5521 | * covered by the given span, and will set each group's ->cpumask correctly, |
5490 | * and ->cpu_power to 0. | 5522 | * and ->cpu_power to 0. |
5491 | */ | 5523 | */ |
5492 | static void init_sched_build_groups(struct sched_group groups[], cpumask_t span, | 5524 | static void |
5493 | int (*group_fn)(int cpu)) | 5525 | init_sched_build_groups(struct sched_group groups[], cpumask_t span, |
5526 | const cpumask_t *cpu_map, | ||
5527 | int (*group_fn)(int cpu, const cpumask_t *cpu_map)) | ||
5494 | { | 5528 | { |
5495 | struct sched_group *first = NULL, *last = NULL; | 5529 | struct sched_group *first = NULL, *last = NULL; |
5496 | cpumask_t covered = CPU_MASK_NONE; | 5530 | cpumask_t covered = CPU_MASK_NONE; |
5497 | int i; | 5531 | int i; |
5498 | 5532 | ||
5499 | for_each_cpu_mask(i, span) { | 5533 | for_each_cpu_mask(i, span) { |
5500 | int group = group_fn(i); | 5534 | int group = group_fn(i, cpu_map); |
5501 | struct sched_group *sg = &groups[group]; | 5535 | struct sched_group *sg = &groups[group]; |
5502 | int j; | 5536 | int j; |
5503 | 5537 | ||
@@ -5508,7 +5542,7 @@ static void init_sched_build_groups(struct sched_group groups[], cpumask_t span, | |||
5508 | sg->cpu_power = 0; | 5542 | sg->cpu_power = 0; |
5509 | 5543 | ||
5510 | for_each_cpu_mask(j, span) { | 5544 | for_each_cpu_mask(j, span) { |
5511 | if (group_fn(j) != group) | 5545 | if (group_fn(j, cpu_map) != group) |
5512 | continue; | 5546 | continue; |
5513 | 5547 | ||
5514 | cpu_set(j, covered); | 5548 | cpu_set(j, covered); |
@@ -5975,13 +6009,15 @@ static void calibrate_migration_costs(const cpumask_t *cpu_map) | |||
5975 | #endif | 6009 | #endif |
5976 | ); | 6010 | ); |
5977 | if (system_state == SYSTEM_BOOTING) { | 6011 | if (system_state == SYSTEM_BOOTING) { |
5978 | printk("migration_cost="); | 6012 | if (num_online_cpus() > 1) { |
5979 | for (distance = 0; distance <= max_distance; distance++) { | 6013 | printk("migration_cost="); |
5980 | if (distance) | 6014 | for (distance = 0; distance <= max_distance; distance++) { |
5981 | printk(","); | 6015 | if (distance) |
5982 | printk("%ld", (long)migration_cost[distance] / 1000); | 6016 | printk(","); |
6017 | printk("%ld", (long)migration_cost[distance] / 1000); | ||
6018 | } | ||
6019 | printk("\n"); | ||
5983 | } | 6020 | } |
5984 | printk("\n"); | ||
5985 | } | 6021 | } |
5986 | j1 = jiffies; | 6022 | j1 = jiffies; |
5987 | if (migration_debug) | 6023 | if (migration_debug) |
@@ -6084,7 +6120,7 @@ int sched_smt_power_savings = 0, sched_mc_power_savings = 0; | |||
6084 | static DEFINE_PER_CPU(struct sched_domain, cpu_domains); | 6120 | static DEFINE_PER_CPU(struct sched_domain, cpu_domains); |
6085 | static struct sched_group sched_group_cpus[NR_CPUS]; | 6121 | static struct sched_group sched_group_cpus[NR_CPUS]; |
6086 | 6122 | ||
6087 | static int cpu_to_cpu_group(int cpu) | 6123 | static int cpu_to_cpu_group(int cpu, const cpumask_t *cpu_map) |
6088 | { | 6124 | { |
6089 | return cpu; | 6125 | return cpu; |
6090 | } | 6126 | } |
@@ -6095,31 +6131,36 @@ static int cpu_to_cpu_group(int cpu) | |||
6095 | */ | 6131 | */ |
6096 | #ifdef CONFIG_SCHED_MC | 6132 | #ifdef CONFIG_SCHED_MC |
6097 | static DEFINE_PER_CPU(struct sched_domain, core_domains); | 6133 | static DEFINE_PER_CPU(struct sched_domain, core_domains); |
6098 | static struct sched_group *sched_group_core_bycpu[NR_CPUS]; | 6134 | static struct sched_group sched_group_core[NR_CPUS]; |
6099 | #endif | 6135 | #endif |
6100 | 6136 | ||
6101 | #if defined(CONFIG_SCHED_MC) && defined(CONFIG_SCHED_SMT) | 6137 | #if defined(CONFIG_SCHED_MC) && defined(CONFIG_SCHED_SMT) |
6102 | static int cpu_to_core_group(int cpu) | 6138 | static int cpu_to_core_group(int cpu, const cpumask_t *cpu_map) |
6103 | { | 6139 | { |
6104 | return first_cpu(cpu_sibling_map[cpu]); | 6140 | cpumask_t mask = cpu_sibling_map[cpu]; |
6141 | cpus_and(mask, mask, *cpu_map); | ||
6142 | return first_cpu(mask); | ||
6105 | } | 6143 | } |
6106 | #elif defined(CONFIG_SCHED_MC) | 6144 | #elif defined(CONFIG_SCHED_MC) |
6107 | static int cpu_to_core_group(int cpu) | 6145 | static int cpu_to_core_group(int cpu, const cpumask_t *cpu_map) |
6108 | { | 6146 | { |
6109 | return cpu; | 6147 | return cpu; |
6110 | } | 6148 | } |
6111 | #endif | 6149 | #endif |
6112 | 6150 | ||
6113 | static DEFINE_PER_CPU(struct sched_domain, phys_domains); | 6151 | static DEFINE_PER_CPU(struct sched_domain, phys_domains); |
6114 | static struct sched_group *sched_group_phys_bycpu[NR_CPUS]; | 6152 | static struct sched_group sched_group_phys[NR_CPUS]; |
6115 | 6153 | ||
6116 | static int cpu_to_phys_group(int cpu) | 6154 | static int cpu_to_phys_group(int cpu, const cpumask_t *cpu_map) |
6117 | { | 6155 | { |
6118 | #ifdef CONFIG_SCHED_MC | 6156 | #ifdef CONFIG_SCHED_MC |
6119 | cpumask_t mask = cpu_coregroup_map(cpu); | 6157 | cpumask_t mask = cpu_coregroup_map(cpu); |
6158 | cpus_and(mask, mask, *cpu_map); | ||
6120 | return first_cpu(mask); | 6159 | return first_cpu(mask); |
6121 | #elif defined(CONFIG_SCHED_SMT) | 6160 | #elif defined(CONFIG_SCHED_SMT) |
6122 | return first_cpu(cpu_sibling_map[cpu]); | 6161 | cpumask_t mask = cpu_sibling_map[cpu]; |
6162 | cpus_and(mask, mask, *cpu_map); | ||
6163 | return first_cpu(mask); | ||
6123 | #else | 6164 | #else |
6124 | return cpu; | 6165 | return cpu; |
6125 | #endif | 6166 | #endif |
@@ -6137,7 +6178,7 @@ static struct sched_group **sched_group_nodes_bycpu[NR_CPUS]; | |||
6137 | static DEFINE_PER_CPU(struct sched_domain, allnodes_domains); | 6178 | static DEFINE_PER_CPU(struct sched_domain, allnodes_domains); |
6138 | static struct sched_group *sched_group_allnodes_bycpu[NR_CPUS]; | 6179 | static struct sched_group *sched_group_allnodes_bycpu[NR_CPUS]; |
6139 | 6180 | ||
6140 | static int cpu_to_allnodes_group(int cpu) | 6181 | static int cpu_to_allnodes_group(int cpu, const cpumask_t *cpu_map) |
6141 | { | 6182 | { |
6142 | return cpu_to_node(cpu); | 6183 | return cpu_to_node(cpu); |
6143 | } | 6184 | } |
@@ -6169,12 +6210,11 @@ next_sg: | |||
6169 | } | 6210 | } |
6170 | #endif | 6211 | #endif |
6171 | 6212 | ||
6213 | #ifdef CONFIG_NUMA | ||
6172 | /* Free memory allocated for various sched_group structures */ | 6214 | /* Free memory allocated for various sched_group structures */ |
6173 | static void free_sched_groups(const cpumask_t *cpu_map) | 6215 | static void free_sched_groups(const cpumask_t *cpu_map) |
6174 | { | 6216 | { |
6175 | int cpu; | 6217 | int cpu, i; |
6176 | #ifdef CONFIG_NUMA | ||
6177 | int i; | ||
6178 | 6218 | ||
6179 | for_each_cpu_mask(cpu, *cpu_map) { | 6219 | for_each_cpu_mask(cpu, *cpu_map) { |
6180 | struct sched_group *sched_group_allnodes | 6220 | struct sched_group *sched_group_allnodes |
@@ -6211,19 +6251,63 @@ next_sg: | |||
6211 | kfree(sched_group_nodes); | 6251 | kfree(sched_group_nodes); |
6212 | sched_group_nodes_bycpu[cpu] = NULL; | 6252 | sched_group_nodes_bycpu[cpu] = NULL; |
6213 | } | 6253 | } |
6254 | } | ||
6255 | #else | ||
6256 | static void free_sched_groups(const cpumask_t *cpu_map) | ||
6257 | { | ||
6258 | } | ||
6214 | #endif | 6259 | #endif |
6215 | for_each_cpu_mask(cpu, *cpu_map) { | 6260 | |
6216 | if (sched_group_phys_bycpu[cpu]) { | 6261 | /* |
6217 | kfree(sched_group_phys_bycpu[cpu]); | 6262 | * Initialize sched groups cpu_power. |
6218 | sched_group_phys_bycpu[cpu] = NULL; | 6263 | * |
6219 | } | 6264 | * cpu_power indicates the capacity of sched group, which is used while |
6220 | #ifdef CONFIG_SCHED_MC | 6265 | * distributing the load between different sched groups in a sched domain. |
6221 | if (sched_group_core_bycpu[cpu]) { | 6266 | * Typically cpu_power for all the groups in a sched domain will be same unless |
6222 | kfree(sched_group_core_bycpu[cpu]); | 6267 | * there are asymmetries in the topology. If there are asymmetries, group |
6223 | sched_group_core_bycpu[cpu] = NULL; | 6268 | * having more cpu_power will pickup more load compared to the group having |
6224 | } | 6269 | * less cpu_power. |
6225 | #endif | 6270 | * |
6271 | * cpu_power will be a multiple of SCHED_LOAD_SCALE. This multiple represents | ||
6272 | * the maximum number of tasks a group can handle in the presence of other idle | ||
6273 | * or lightly loaded groups in the same sched domain. | ||
6274 | */ | ||
6275 | static void init_sched_groups_power(int cpu, struct sched_domain *sd) | ||
6276 | { | ||
6277 | struct sched_domain *child; | ||
6278 | struct sched_group *group; | ||
6279 | |||
6280 | WARN_ON(!sd || !sd->groups); | ||
6281 | |||
6282 | if (cpu != first_cpu(sd->groups->cpumask)) | ||
6283 | return; | ||
6284 | |||
6285 | child = sd->child; | ||
6286 | |||
6287 | /* | ||
6288 | * For perf policy, if the groups in child domain share resources | ||
6289 | * (for example cores sharing some portions of the cache hierarchy | ||
6290 | * or SMT), then set this domain groups cpu_power such that each group | ||
6291 | * can handle only one task, when there are other idle groups in the | ||
6292 | * same sched domain. | ||
6293 | */ | ||
6294 | if (!child || (!(sd->flags & SD_POWERSAVINGS_BALANCE) && | ||
6295 | (child->flags & | ||
6296 | (SD_SHARE_CPUPOWER | SD_SHARE_PKG_RESOURCES)))) { | ||
6297 | sd->groups->cpu_power = SCHED_LOAD_SCALE; | ||
6298 | return; | ||
6226 | } | 6299 | } |
6300 | |||
6301 | sd->groups->cpu_power = 0; | ||
6302 | |||
6303 | /* | ||
6304 | * add cpu_power of each child group to this groups cpu_power | ||
6305 | */ | ||
6306 | group = child->groups; | ||
6307 | do { | ||
6308 | sd->groups->cpu_power += group->cpu_power; | ||
6309 | group = group->next; | ||
6310 | } while (group != child->groups); | ||
6227 | } | 6311 | } |
6228 | 6312 | ||
6229 | /* | 6313 | /* |
@@ -6233,10 +6317,7 @@ next_sg: | |||
6233 | static int build_sched_domains(const cpumask_t *cpu_map) | 6317 | static int build_sched_domains(const cpumask_t *cpu_map) |
6234 | { | 6318 | { |
6235 | int i; | 6319 | int i; |
6236 | struct sched_group *sched_group_phys = NULL; | 6320 | struct sched_domain *sd; |
6237 | #ifdef CONFIG_SCHED_MC | ||
6238 | struct sched_group *sched_group_core = NULL; | ||
6239 | #endif | ||
6240 | #ifdef CONFIG_NUMA | 6321 | #ifdef CONFIG_NUMA |
6241 | struct sched_group **sched_group_nodes = NULL; | 6322 | struct sched_group **sched_group_nodes = NULL; |
6242 | struct sched_group *sched_group_allnodes = NULL; | 6323 | struct sched_group *sched_group_allnodes = NULL; |
@@ -6268,9 +6349,10 @@ static int build_sched_domains(const cpumask_t *cpu_map) | |||
6268 | > SD_NODES_PER_DOMAIN*cpus_weight(nodemask)) { | 6349 | > SD_NODES_PER_DOMAIN*cpus_weight(nodemask)) { |
6269 | if (!sched_group_allnodes) { | 6350 | if (!sched_group_allnodes) { |
6270 | sched_group_allnodes | 6351 | sched_group_allnodes |
6271 | = kmalloc(sizeof(struct sched_group) | 6352 | = kmalloc_node(sizeof(struct sched_group) |
6272 | * MAX_NUMNODES, | 6353 | * MAX_NUMNODES, |
6273 | GFP_KERNEL); | 6354 | GFP_KERNEL, |
6355 | cpu_to_node(i)); | ||
6274 | if (!sched_group_allnodes) { | 6356 | if (!sched_group_allnodes) { |
6275 | printk(KERN_WARNING | 6357 | printk(KERN_WARNING |
6276 | "Can not alloc allnodes sched group\n"); | 6358 | "Can not alloc allnodes sched group\n"); |
@@ -6282,7 +6364,7 @@ static int build_sched_domains(const cpumask_t *cpu_map) | |||
6282 | sd = &per_cpu(allnodes_domains, i); | 6364 | sd = &per_cpu(allnodes_domains, i); |
6283 | *sd = SD_ALLNODES_INIT; | 6365 | *sd = SD_ALLNODES_INIT; |
6284 | sd->span = *cpu_map; | 6366 | sd->span = *cpu_map; |
6285 | group = cpu_to_allnodes_group(i); | 6367 | group = cpu_to_allnodes_group(i, cpu_map); |
6286 | sd->groups = &sched_group_allnodes[group]; | 6368 | sd->groups = &sched_group_allnodes[group]; |
6287 | p = sd; | 6369 | p = sd; |
6288 | } else | 6370 | } else |
@@ -6292,60 +6374,42 @@ static int build_sched_domains(const cpumask_t *cpu_map) | |||
6292 | *sd = SD_NODE_INIT; | 6374 | *sd = SD_NODE_INIT; |
6293 | sd->span = sched_domain_node_span(cpu_to_node(i)); | 6375 | sd->span = sched_domain_node_span(cpu_to_node(i)); |
6294 | sd->parent = p; | 6376 | sd->parent = p; |
6377 | if (p) | ||
6378 | p->child = sd; | ||
6295 | cpus_and(sd->span, sd->span, *cpu_map); | 6379 | cpus_and(sd->span, sd->span, *cpu_map); |
6296 | #endif | 6380 | #endif |
6297 | 6381 | ||
6298 | if (!sched_group_phys) { | ||
6299 | sched_group_phys | ||
6300 | = kmalloc(sizeof(struct sched_group) * NR_CPUS, | ||
6301 | GFP_KERNEL); | ||
6302 | if (!sched_group_phys) { | ||
6303 | printk (KERN_WARNING "Can not alloc phys sched" | ||
6304 | "group\n"); | ||
6305 | goto error; | ||
6306 | } | ||
6307 | sched_group_phys_bycpu[i] = sched_group_phys; | ||
6308 | } | ||
6309 | |||
6310 | p = sd; | 6382 | p = sd; |
6311 | sd = &per_cpu(phys_domains, i); | 6383 | sd = &per_cpu(phys_domains, i); |
6312 | group = cpu_to_phys_group(i); | 6384 | group = cpu_to_phys_group(i, cpu_map); |
6313 | *sd = SD_CPU_INIT; | 6385 | *sd = SD_CPU_INIT; |
6314 | sd->span = nodemask; | 6386 | sd->span = nodemask; |
6315 | sd->parent = p; | 6387 | sd->parent = p; |
6388 | if (p) | ||
6389 | p->child = sd; | ||
6316 | sd->groups = &sched_group_phys[group]; | 6390 | sd->groups = &sched_group_phys[group]; |
6317 | 6391 | ||
6318 | #ifdef CONFIG_SCHED_MC | 6392 | #ifdef CONFIG_SCHED_MC |
6319 | if (!sched_group_core) { | ||
6320 | sched_group_core | ||
6321 | = kmalloc(sizeof(struct sched_group) * NR_CPUS, | ||
6322 | GFP_KERNEL); | ||
6323 | if (!sched_group_core) { | ||
6324 | printk (KERN_WARNING "Can not alloc core sched" | ||
6325 | "group\n"); | ||
6326 | goto error; | ||
6327 | } | ||
6328 | sched_group_core_bycpu[i] = sched_group_core; | ||
6329 | } | ||
6330 | |||
6331 | p = sd; | 6393 | p = sd; |
6332 | sd = &per_cpu(core_domains, i); | 6394 | sd = &per_cpu(core_domains, i); |
6333 | group = cpu_to_core_group(i); | 6395 | group = cpu_to_core_group(i, cpu_map); |
6334 | *sd = SD_MC_INIT; | 6396 | *sd = SD_MC_INIT; |
6335 | sd->span = cpu_coregroup_map(i); | 6397 | sd->span = cpu_coregroup_map(i); |
6336 | cpus_and(sd->span, sd->span, *cpu_map); | 6398 | cpus_and(sd->span, sd->span, *cpu_map); |
6337 | sd->parent = p; | 6399 | sd->parent = p; |
6400 | p->child = sd; | ||
6338 | sd->groups = &sched_group_core[group]; | 6401 | sd->groups = &sched_group_core[group]; |
6339 | #endif | 6402 | #endif |
6340 | 6403 | ||
6341 | #ifdef CONFIG_SCHED_SMT | 6404 | #ifdef CONFIG_SCHED_SMT |
6342 | p = sd; | 6405 | p = sd; |
6343 | sd = &per_cpu(cpu_domains, i); | 6406 | sd = &per_cpu(cpu_domains, i); |
6344 | group = cpu_to_cpu_group(i); | 6407 | group = cpu_to_cpu_group(i, cpu_map); |
6345 | *sd = SD_SIBLING_INIT; | 6408 | *sd = SD_SIBLING_INIT; |
6346 | sd->span = cpu_sibling_map[i]; | 6409 | sd->span = cpu_sibling_map[i]; |
6347 | cpus_and(sd->span, sd->span, *cpu_map); | 6410 | cpus_and(sd->span, sd->span, *cpu_map); |
6348 | sd->parent = p; | 6411 | sd->parent = p; |
6412 | p->child = sd; | ||
6349 | sd->groups = &sched_group_cpus[group]; | 6413 | sd->groups = &sched_group_cpus[group]; |
6350 | #endif | 6414 | #endif |
6351 | } | 6415 | } |
@@ -6359,7 +6423,7 @@ static int build_sched_domains(const cpumask_t *cpu_map) | |||
6359 | continue; | 6423 | continue; |
6360 | 6424 | ||
6361 | init_sched_build_groups(sched_group_cpus, this_sibling_map, | 6425 | init_sched_build_groups(sched_group_cpus, this_sibling_map, |
6362 | &cpu_to_cpu_group); | 6426 | cpu_map, &cpu_to_cpu_group); |
6363 | } | 6427 | } |
6364 | #endif | 6428 | #endif |
6365 | 6429 | ||
@@ -6371,7 +6435,7 @@ static int build_sched_domains(const cpumask_t *cpu_map) | |||
6371 | if (i != first_cpu(this_core_map)) | 6435 | if (i != first_cpu(this_core_map)) |
6372 | continue; | 6436 | continue; |
6373 | init_sched_build_groups(sched_group_core, this_core_map, | 6437 | init_sched_build_groups(sched_group_core, this_core_map, |
6374 | &cpu_to_core_group); | 6438 | cpu_map, &cpu_to_core_group); |
6375 | } | 6439 | } |
6376 | #endif | 6440 | #endif |
6377 | 6441 | ||
@@ -6385,14 +6449,14 @@ static int build_sched_domains(const cpumask_t *cpu_map) | |||
6385 | continue; | 6449 | continue; |
6386 | 6450 | ||
6387 | init_sched_build_groups(sched_group_phys, nodemask, | 6451 | init_sched_build_groups(sched_group_phys, nodemask, |
6388 | &cpu_to_phys_group); | 6452 | cpu_map, &cpu_to_phys_group); |
6389 | } | 6453 | } |
6390 | 6454 | ||
6391 | #ifdef CONFIG_NUMA | 6455 | #ifdef CONFIG_NUMA |
6392 | /* Set up node groups */ | 6456 | /* Set up node groups */ |
6393 | if (sched_group_allnodes) | 6457 | if (sched_group_allnodes) |
6394 | init_sched_build_groups(sched_group_allnodes, *cpu_map, | 6458 | init_sched_build_groups(sched_group_allnodes, *cpu_map, |
6395 | &cpu_to_allnodes_group); | 6459 | cpu_map, &cpu_to_allnodes_group); |
6396 | 6460 | ||
6397 | for (i = 0; i < MAX_NUMNODES; i++) { | 6461 | for (i = 0; i < MAX_NUMNODES; i++) { |
6398 | /* Set up node groups */ | 6462 | /* Set up node groups */ |
@@ -6464,72 +6528,20 @@ static int build_sched_domains(const cpumask_t *cpu_map) | |||
6464 | /* Calculate CPU power for physical packages and nodes */ | 6528 | /* Calculate CPU power for physical packages and nodes */ |
6465 | #ifdef CONFIG_SCHED_SMT | 6529 | #ifdef CONFIG_SCHED_SMT |
6466 | for_each_cpu_mask(i, *cpu_map) { | 6530 | for_each_cpu_mask(i, *cpu_map) { |
6467 | struct sched_domain *sd; | ||
6468 | sd = &per_cpu(cpu_domains, i); | 6531 | sd = &per_cpu(cpu_domains, i); |
6469 | sd->groups->cpu_power = SCHED_LOAD_SCALE; | 6532 | init_sched_groups_power(i, sd); |
6470 | } | 6533 | } |
6471 | #endif | 6534 | #endif |
6472 | #ifdef CONFIG_SCHED_MC | 6535 | #ifdef CONFIG_SCHED_MC |
6473 | for_each_cpu_mask(i, *cpu_map) { | 6536 | for_each_cpu_mask(i, *cpu_map) { |
6474 | int power; | ||
6475 | struct sched_domain *sd; | ||
6476 | sd = &per_cpu(core_domains, i); | 6537 | sd = &per_cpu(core_domains, i); |
6477 | if (sched_smt_power_savings) | 6538 | init_sched_groups_power(i, sd); |
6478 | power = SCHED_LOAD_SCALE * cpus_weight(sd->groups->cpumask); | ||
6479 | else | ||
6480 | power = SCHED_LOAD_SCALE + (cpus_weight(sd->groups->cpumask)-1) | ||
6481 | * SCHED_LOAD_SCALE / 10; | ||
6482 | sd->groups->cpu_power = power; | ||
6483 | } | 6539 | } |
6484 | #endif | 6540 | #endif |
6485 | 6541 | ||
6486 | for_each_cpu_mask(i, *cpu_map) { | 6542 | for_each_cpu_mask(i, *cpu_map) { |
6487 | struct sched_domain *sd; | ||
6488 | #ifdef CONFIG_SCHED_MC | ||
6489 | sd = &per_cpu(phys_domains, i); | 6543 | sd = &per_cpu(phys_domains, i); |
6490 | if (i != first_cpu(sd->groups->cpumask)) | 6544 | init_sched_groups_power(i, sd); |
6491 | continue; | ||
6492 | |||
6493 | sd->groups->cpu_power = 0; | ||
6494 | if (sched_mc_power_savings || sched_smt_power_savings) { | ||
6495 | int j; | ||
6496 | |||
6497 | for_each_cpu_mask(j, sd->groups->cpumask) { | ||
6498 | struct sched_domain *sd1; | ||
6499 | sd1 = &per_cpu(core_domains, j); | ||
6500 | /* | ||
6501 | * for each core we will add once | ||
6502 | * to the group in physical domain | ||
6503 | */ | ||
6504 | if (j != first_cpu(sd1->groups->cpumask)) | ||
6505 | continue; | ||
6506 | |||
6507 | if (sched_smt_power_savings) | ||
6508 | sd->groups->cpu_power += sd1->groups->cpu_power; | ||
6509 | else | ||
6510 | sd->groups->cpu_power += SCHED_LOAD_SCALE; | ||
6511 | } | ||
6512 | } else | ||
6513 | /* | ||
6514 | * This has to be < 2 * SCHED_LOAD_SCALE | ||
6515 | * Lets keep it SCHED_LOAD_SCALE, so that | ||
6516 | * while calculating NUMA group's cpu_power | ||
6517 | * we can simply do | ||
6518 | * numa_group->cpu_power += phys_group->cpu_power; | ||
6519 | * | ||
6520 | * See "only add power once for each physical pkg" | ||
6521 | * comment below | ||
6522 | */ | ||
6523 | sd->groups->cpu_power = SCHED_LOAD_SCALE; | ||
6524 | #else | ||
6525 | int power; | ||
6526 | sd = &per_cpu(phys_domains, i); | ||
6527 | if (sched_smt_power_savings) | ||
6528 | power = SCHED_LOAD_SCALE * cpus_weight(sd->groups->cpumask); | ||
6529 | else | ||
6530 | power = SCHED_LOAD_SCALE; | ||
6531 | sd->groups->cpu_power = power; | ||
6532 | #endif | ||
6533 | } | 6545 | } |
6534 | 6546 | ||
6535 | #ifdef CONFIG_NUMA | 6547 | #ifdef CONFIG_NUMA |
@@ -6537,7 +6549,7 @@ static int build_sched_domains(const cpumask_t *cpu_map) | |||
6537 | init_numa_sched_groups_power(sched_group_nodes[i]); | 6549 | init_numa_sched_groups_power(sched_group_nodes[i]); |
6538 | 6550 | ||
6539 | if (sched_group_allnodes) { | 6551 | if (sched_group_allnodes) { |
6540 | int group = cpu_to_allnodes_group(first_cpu(*cpu_map)); | 6552 | int group = cpu_to_allnodes_group(first_cpu(*cpu_map), cpu_map); |
6541 | struct sched_group *sg = &sched_group_allnodes[group]; | 6553 | struct sched_group *sg = &sched_group_allnodes[group]; |
6542 | 6554 | ||
6543 | init_numa_sched_groups_power(sg); | 6555 | init_numa_sched_groups_power(sg); |
@@ -6563,9 +6575,11 @@ static int build_sched_domains(const cpumask_t *cpu_map) | |||
6563 | 6575 | ||
6564 | return 0; | 6576 | return 0; |
6565 | 6577 | ||
6578 | #ifdef CONFIG_NUMA | ||
6566 | error: | 6579 | error: |
6567 | free_sched_groups(cpu_map); | 6580 | free_sched_groups(cpu_map); |
6568 | return -ENOMEM; | 6581 | return -ENOMEM; |
6582 | #endif | ||
6569 | } | 6583 | } |
6570 | /* | 6584 | /* |
6571 | * Set up scheduler domains and groups. Callers must hold the hotplug lock. | 6585 | * Set up scheduler domains and groups. Callers must hold the hotplug lock. |
@@ -6747,11 +6761,20 @@ static int update_sched_domains(struct notifier_block *nfb, | |||
6747 | 6761 | ||
6748 | void __init sched_init_smp(void) | 6762 | void __init sched_init_smp(void) |
6749 | { | 6763 | { |
6764 | cpumask_t non_isolated_cpus; | ||
6765 | |||
6750 | lock_cpu_hotplug(); | 6766 | lock_cpu_hotplug(); |
6751 | arch_init_sched_domains(&cpu_online_map); | 6767 | arch_init_sched_domains(&cpu_online_map); |
6768 | cpus_andnot(non_isolated_cpus, cpu_online_map, cpu_isolated_map); | ||
6769 | if (cpus_empty(non_isolated_cpus)) | ||
6770 | cpu_set(smp_processor_id(), non_isolated_cpus); | ||
6752 | unlock_cpu_hotplug(); | 6771 | unlock_cpu_hotplug(); |
6753 | /* XXX: Theoretical race here - CPU may be hotplugged now */ | 6772 | /* XXX: Theoretical race here - CPU may be hotplugged now */ |
6754 | hotcpu_notifier(update_sched_domains, 0); | 6773 | hotcpu_notifier(update_sched_domains, 0); |
6774 | |||
6775 | /* Move init over to a non-isolated CPU */ | ||
6776 | if (set_cpus_allowed(current, non_isolated_cpus) < 0) | ||
6777 | BUG(); | ||
6755 | } | 6778 | } |
6756 | #else | 6779 | #else |
6757 | void __init sched_init_smp(void) | 6780 | void __init sched_init_smp(void) |
diff --git a/lib/sort.c b/lib/sort.c index 5f3b51ffa1dc..488788b341cb 100644 --- a/lib/sort.c +++ b/lib/sort.c | |||
@@ -49,15 +49,15 @@ void sort(void *base, size_t num, size_t size, | |||
49 | void (*swap)(void *, void *, int size)) | 49 | void (*swap)(void *, void *, int size)) |
50 | { | 50 | { |
51 | /* pre-scale counters for performance */ | 51 | /* pre-scale counters for performance */ |
52 | int i = (num/2) * size, n = num * size, c, r; | 52 | int i = (num/2 - 1) * size, n = num * size, c, r; |
53 | 53 | ||
54 | if (!swap) | 54 | if (!swap) |
55 | swap = (size == 4 ? u32_swap : generic_swap); | 55 | swap = (size == 4 ? u32_swap : generic_swap); |
56 | 56 | ||
57 | /* heapify */ | 57 | /* heapify */ |
58 | for ( ; i >= 0; i -= size) { | 58 | for ( ; i >= 0; i -= size) { |
59 | for (r = i; r * 2 < n; r = c) { | 59 | for (r = i; r * 2 + size < n; r = c) { |
60 | c = r * 2; | 60 | c = r * 2 + size; |
61 | if (c < n - size && cmp(base + c, base + c + size) < 0) | 61 | if (c < n - size && cmp(base + c, base + c + size) < 0) |
62 | c += size; | 62 | c += size; |
63 | if (cmp(base + r, base + c) >= 0) | 63 | if (cmp(base + r, base + c) >= 0) |
@@ -69,8 +69,8 @@ void sort(void *base, size_t num, size_t size, | |||
69 | /* sort */ | 69 | /* sort */ |
70 | for (i = n - size; i >= 0; i -= size) { | 70 | for (i = n - size; i >= 0; i -= size) { |
71 | swap(base, base + i, size); | 71 | swap(base, base + i, size); |
72 | for (r = 0; r * 2 < i; r = c) { | 72 | for (r = 0; r * 2 + size < i; r = c) { |
73 | c = r * 2; | 73 | c = r * 2 + size; |
74 | if (c < i - size && cmp(base + c, base + c + size) < 0) | 74 | if (c < i - size && cmp(base + c, base + c + size) < 0) |
75 | c += size; | 75 | c += size; |
76 | if (cmp(base + r, base + c) >= 0) | 76 | if (cmp(base + r, base + c) >= 0) |
diff --git a/scripts/.gitignore b/scripts/.gitignore index a234e524a490..a1f52cb47200 100644 --- a/scripts/.gitignore +++ b/scripts/.gitignore | |||
@@ -5,3 +5,4 @@ conmakehash | |||
5 | kallsyms | 5 | kallsyms |
6 | pnmtologo | 6 | pnmtologo |
7 | bin2c | 7 | bin2c |
8 | unifdef | ||
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 4b2721ca97da..6c5469b1473b 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost | |||
@@ -32,6 +32,10 @@ | |||
32 | # Step 4 is solely used to allow module versioning in external modules, | 32 | # Step 4 is solely used to allow module versioning in external modules, |
33 | # where the CRC of each module is retrieved from the Module.symers file. | 33 | # where the CRC of each module is retrieved from the Module.symers file. |
34 | 34 | ||
35 | # KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined | ||
36 | # symbols in the final module linking stage | ||
37 | # KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules. | ||
38 | # This is solely usefull to speed up test compiles | ||
35 | PHONY := _modpost | 39 | PHONY := _modpost |
36 | _modpost: __modpost | 40 | _modpost: __modpost |
37 | 41 | ||
@@ -46,7 +50,8 @@ modulesymfile := $(KBUILD_EXTMOD)/Module.symvers | |||
46 | __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod))) | 50 | __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod))) |
47 | modules := $(patsubst %.o,%.ko, $(wildcard $(__modules:.ko=.o))) | 51 | modules := $(patsubst %.o,%.ko, $(wildcard $(__modules:.ko=.o))) |
48 | 52 | ||
49 | _modpost: $(modules) | 53 | # Stop after building .o files if NOFINAL is set. Makes compile tests quicker |
54 | _modpost: $(if $(KBUILD_MODPOST_NOFINAL), $(modules:.ko:.o),$(modules)) | ||
50 | 55 | ||
51 | 56 | ||
52 | # Step 2), invoke modpost | 57 | # Step 2), invoke modpost |
@@ -58,7 +63,7 @@ quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules | |||
58 | $(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \ | 63 | $(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \ |
59 | $(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \ | 64 | $(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \ |
60 | $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \ | 65 | $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \ |
61 | $(if $(KBUILD_EXTMOD),-w) \ | 66 | $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) \ |
62 | $(wildcard vmlinux) $(filter-out FORCE,$^) | 67 | $(wildcard vmlinux) $(filter-out FORCE,$^) |
63 | 68 | ||
64 | PHONY += __modpost | 69 | PHONY += __modpost |
@@ -92,7 +97,7 @@ targets += $(modules:.ko=.mod.o) | |||
92 | 97 | ||
93 | # Step 6), final link of the modules | 98 | # Step 6), final link of the modules |
94 | quiet_cmd_ld_ko_o = LD [M] $@ | 99 | quiet_cmd_ld_ko_o = LD [M] $@ |
95 | cmd_ld_ko_o = $(LD) $(LDFLAGS) $(LDFLAGS_MODULE) -o $@ \ | 100 | cmd_ld_ko_o = $(LD) $(LDFLAGS) $(LDFLAGS_MODULE) -o $@ \ |
96 | $(filter-out FORCE,$^) | 101 | $(filter-out FORCE,$^) |
97 | 102 | ||
98 | $(modules): %.ko :%.o %.mod.o FORCE | 103 | $(modules): %.ko :%.o %.mod.o FORCE |
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index a90d3cc76bfa..7e7e147875bf 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile | |||
@@ -11,7 +11,6 @@ gconfig: $(obj)/gconf | |||
11 | $< arch/$(ARCH)/Kconfig | 11 | $< arch/$(ARCH)/Kconfig |
12 | 12 | ||
13 | menuconfig: $(obj)/mconf | 13 | menuconfig: $(obj)/mconf |
14 | $(Q)$(MAKE) $(build)=scripts/kconfig/lxdialog | ||
15 | $< arch/$(ARCH)/Kconfig | 14 | $< arch/$(ARCH)/Kconfig |
16 | 15 | ||
17 | config: $(obj)/conf | 16 | config: $(obj)/conf |
@@ -81,6 +80,23 @@ help: | |||
81 | @echo ' allyesconfig - New config where all options are accepted with yes' | 80 | @echo ' allyesconfig - New config where all options are accepted with yes' |
82 | @echo ' allnoconfig - New config where all options are answered with no' | 81 | @echo ' allnoconfig - New config where all options are answered with no' |
83 | 82 | ||
83 | # lxdialog stuff | ||
84 | check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh | ||
85 | |||
86 | # Use reursively expanded variables so we do not call gcc unless | ||
87 | # we really need to do so. (Do not call gcc as part of make mrproper) | ||
88 | HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) | ||
89 | HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) | ||
90 | |||
91 | HOST_EXTRACFLAGS += -DLOCALE | ||
92 | |||
93 | PHONY += $(obj)/dochecklxdialog | ||
94 | $(obj)/dochecklxdialog: | ||
95 | $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_LOADLIBES) | ||
96 | |||
97 | always := dochecklxdialog | ||
98 | |||
99 | |||
84 | # =========================================================================== | 100 | # =========================================================================== |
85 | # Shared Makefile for the various kconfig executables: | 101 | # Shared Makefile for the various kconfig executables: |
86 | # conf: Used for defconfig, oldconfig and related targets | 102 | # conf: Used for defconfig, oldconfig and related targets |
@@ -92,11 +108,19 @@ help: | |||
92 | # Based on GTK which needs to be installed to compile it | 108 | # Based on GTK which needs to be installed to compile it |
93 | # object files used by all kconfig flavours | 109 | # object files used by all kconfig flavours |
94 | 110 | ||
95 | hostprogs-y := conf mconf qconf gconf kxgettext | 111 | lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o |
112 | lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o | ||
113 | |||
96 | conf-objs := conf.o zconf.tab.o | 114 | conf-objs := conf.o zconf.tab.o |
97 | mconf-objs := mconf.o zconf.tab.o | 115 | mconf-objs := mconf.o zconf.tab.o $(lxdialog) |
98 | kxgettext-objs := kxgettext.o zconf.tab.o | 116 | kxgettext-objs := kxgettext.o zconf.tab.o |
99 | 117 | ||
118 | hostprogs-y := conf qconf gconf kxgettext | ||
119 | |||
120 | ifeq ($(MAKECMDGOALS),menuconfig) | ||
121 | hostprogs-y += mconf | ||
122 | endif | ||
123 | |||
100 | ifeq ($(MAKECMDGOALS),xconfig) | 124 | ifeq ($(MAKECMDGOALS),xconfig) |
101 | qconf-target := 1 | 125 | qconf-target := 1 |
102 | endif | 126 | endif |
@@ -116,7 +140,6 @@ endif | |||
116 | 140 | ||
117 | clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \ | 141 | clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \ |
118 | .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c | 142 | .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c |
119 | subdir- += lxdialog | ||
120 | 143 | ||
121 | # Needed for systems without gettext | 144 | # Needed for systems without gettext |
122 | KBUILD_HAVE_NLS := $(shell \ | 145 | KBUILD_HAVE_NLS := $(shell \ |
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 69f96b398c22..66b15ef02931 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c | |||
@@ -517,7 +517,7 @@ int conf_write(const char *name) | |||
517 | fclose(out); | 517 | fclose(out); |
518 | 518 | ||
519 | if (*tmpname) { | 519 | if (*tmpname) { |
520 | strcat(dirname, name ? name : conf_get_configname()); | 520 | strcat(dirname, basename); |
521 | strcat(dirname, ".old"); | 521 | strcat(dirname, ".old"); |
522 | rename(newname, dirname); | 522 | rename(newname, dirname); |
523 | if (rename(tmpname, newname)) | 523 | if (rename(tmpname, newname)) |
diff --git a/scripts/kconfig/lxdialog/Makefile b/scripts/kconfig/lxdialog/Makefile deleted file mode 100644 index a8b026326247..000000000000 --- a/scripts/kconfig/lxdialog/Makefile +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | # Makefile to build lxdialog package | ||
2 | # | ||
3 | |||
4 | check-lxdialog := $(srctree)/$(src)/check-lxdialog.sh | ||
5 | |||
6 | # Use reursively expanded variables so we do not call gcc unless | ||
7 | # we really need to do so. (Do not call gcc as part of make mrproper) | ||
8 | HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) | ||
9 | HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) | ||
10 | |||
11 | HOST_EXTRACFLAGS += -DLOCALE | ||
12 | |||
13 | PHONY += dochecklxdialog | ||
14 | $(obj)/dochecklxdialog: | ||
15 | $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_LOADLIBES) | ||
16 | |||
17 | hostprogs-y := lxdialog | ||
18 | always := $(hostprogs-y) dochecklxdialog | ||
19 | |||
20 | lxdialog-objs := checklist.o menubox.o textbox.o yesno.o inputbox.o \ | ||
21 | util.o lxdialog.o msgbox.o | ||
diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c index 79886413b6d5..cf697080dddd 100644 --- a/scripts/kconfig/lxdialog/checklist.c +++ b/scripts/kconfig/lxdialog/checklist.c | |||
@@ -28,25 +28,25 @@ static int list_width, check_x, item_x; | |||
28 | /* | 28 | /* |
29 | * Print list item | 29 | * Print list item |
30 | */ | 30 | */ |
31 | static void print_item(WINDOW * win, const char *item, int status, int choice, | 31 | static void print_item(WINDOW * win, int choice, int selected) |
32 | int selected) | ||
33 | { | 32 | { |
34 | int i; | 33 | int i; |
35 | 34 | ||
36 | /* Clear 'residue' of last item */ | 35 | /* Clear 'residue' of last item */ |
37 | wattrset(win, menubox_attr); | 36 | wattrset(win, dlg.menubox.atr); |
38 | wmove(win, choice, 0); | 37 | wmove(win, choice, 0); |
39 | for (i = 0; i < list_width; i++) | 38 | for (i = 0; i < list_width; i++) |
40 | waddch(win, ' '); | 39 | waddch(win, ' '); |
41 | 40 | ||
42 | wmove(win, choice, check_x); | 41 | wmove(win, choice, check_x); |
43 | wattrset(win, selected ? check_selected_attr : check_attr); | 42 | wattrset(win, selected ? dlg.check_selected.atr |
44 | wprintw(win, "(%c)", status ? 'X' : ' '); | 43 | : dlg.check.atr); |
45 | 44 | wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' '); | |
46 | wattrset(win, selected ? tag_selected_attr : tag_attr); | 45 | |
47 | mvwaddch(win, choice, item_x, item[0]); | 46 | wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr); |
48 | wattrset(win, selected ? item_selected_attr : item_attr); | 47 | mvwaddch(win, choice, item_x, item_str()[0]); |
49 | waddstr(win, (char *)item + 1); | 48 | wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr); |
49 | waddstr(win, (char *)item_str() + 1); | ||
50 | if (selected) { | 50 | if (selected) { |
51 | wmove(win, choice, check_x + 1); | 51 | wmove(win, choice, check_x + 1); |
52 | wrefresh(win); | 52 | wrefresh(win); |
@@ -62,11 +62,11 @@ static void print_arrows(WINDOW * win, int choice, int item_no, int scroll, | |||
62 | wmove(win, y, x); | 62 | wmove(win, y, x); |
63 | 63 | ||
64 | if (scroll > 0) { | 64 | if (scroll > 0) { |
65 | wattrset(win, uarrow_attr); | 65 | wattrset(win, dlg.uarrow.atr); |
66 | waddch(win, ACS_UARROW); | 66 | waddch(win, ACS_UARROW); |
67 | waddstr(win, "(-)"); | 67 | waddstr(win, "(-)"); |
68 | } else { | 68 | } else { |
69 | wattrset(win, menubox_attr); | 69 | wattrset(win, dlg.menubox.atr); |
70 | waddch(win, ACS_HLINE); | 70 | waddch(win, ACS_HLINE); |
71 | waddch(win, ACS_HLINE); | 71 | waddch(win, ACS_HLINE); |
72 | waddch(win, ACS_HLINE); | 72 | waddch(win, ACS_HLINE); |
@@ -77,11 +77,11 @@ static void print_arrows(WINDOW * win, int choice, int item_no, int scroll, | |||
77 | wmove(win, y, x); | 77 | wmove(win, y, x); |
78 | 78 | ||
79 | if ((height < item_no) && (scroll + choice < item_no - 1)) { | 79 | if ((height < item_no) && (scroll + choice < item_no - 1)) { |
80 | wattrset(win, darrow_attr); | 80 | wattrset(win, dlg.darrow.atr); |
81 | waddch(win, ACS_DARROW); | 81 | waddch(win, ACS_DARROW); |
82 | waddstr(win, "(+)"); | 82 | waddstr(win, "(+)"); |
83 | } else { | 83 | } else { |
84 | wattrset(win, menubox_border_attr); | 84 | wattrset(win, dlg.menubox_border.atr); |
85 | waddch(win, ACS_HLINE); | 85 | waddch(win, ACS_HLINE); |
86 | waddch(win, ACS_HLINE); | 86 | waddch(win, ACS_HLINE); |
87 | waddch(win, ACS_HLINE); | 87 | waddch(win, ACS_HLINE); |
@@ -109,32 +109,29 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected) | |||
109 | * in the style of radiolist (only one option turned on at a time). | 109 | * in the style of radiolist (only one option turned on at a time). |
110 | */ | 110 | */ |
111 | int dialog_checklist(const char *title, const char *prompt, int height, | 111 | int dialog_checklist(const char *title, const char *prompt, int height, |
112 | int width, int list_height, int item_no, | 112 | int width, int list_height) |
113 | const char *const *items) | ||
114 | { | 113 | { |
115 | int i, x, y, box_x, box_y; | 114 | int i, x, y, box_x, box_y; |
116 | int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status; | 115 | int key = 0, button = 0, choice = 0, scroll = 0, max_choice; |
117 | WINDOW *dialog, *list; | 116 | WINDOW *dialog, *list; |
118 | 117 | ||
119 | /* Allocate space for storing item on/off status */ | 118 | /* which item to highlight */ |
120 | if ((status = malloc(sizeof(int) * item_no)) == NULL) { | 119 | item_foreach() { |
121 | endwin(); | 120 | if (item_is_tag('X')) |
122 | fprintf(stderr, | 121 | choice = item_n(); |
123 | "\nCan't allocate memory in dialog_checklist().\n"); | 122 | if (item_is_selected()) { |
124 | exit(-1); | 123 | choice = item_n(); |
124 | break; | ||
125 | } | ||
125 | } | 126 | } |
126 | 127 | ||
127 | /* Initializes status */ | 128 | do_resize: |
128 | for (i = 0; i < item_no; i++) { | 129 | if (getmaxy(stdscr) < (height + 6)) |
129 | status[i] = !strcasecmp(items[i * 3 + 2], "on"); | 130 | return -ERRDISPLAYTOOSMALL; |
130 | if ((!choice && status[i]) | 131 | if (getmaxx(stdscr) < (width + 6)) |
131 | || !strcasecmp(items[i * 3 + 2], "selected")) | 132 | return -ERRDISPLAYTOOSMALL; |
132 | choice = i + 1; | ||
133 | } | ||
134 | if (choice) | ||
135 | choice--; | ||
136 | 133 | ||
137 | max_choice = MIN(list_height, item_no); | 134 | max_choice = MIN(list_height, item_count()); |
138 | 135 | ||
139 | /* center dialog box on screen */ | 136 | /* center dialog box on screen */ |
140 | x = (COLS - width) / 2; | 137 | x = (COLS - width) / 2; |
@@ -145,17 +142,18 @@ int dialog_checklist(const char *title, const char *prompt, int height, | |||
145 | dialog = newwin(height, width, y, x); | 142 | dialog = newwin(height, width, y, x); |
146 | keypad(dialog, TRUE); | 143 | keypad(dialog, TRUE); |
147 | 144 | ||
148 | draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); | 145 | draw_box(dialog, 0, 0, height, width, |
149 | wattrset(dialog, border_attr); | 146 | dlg.dialog.atr, dlg.border.atr); |
147 | wattrset(dialog, dlg.border.atr); | ||
150 | mvwaddch(dialog, height - 3, 0, ACS_LTEE); | 148 | mvwaddch(dialog, height - 3, 0, ACS_LTEE); |
151 | for (i = 0; i < width - 2; i++) | 149 | for (i = 0; i < width - 2; i++) |
152 | waddch(dialog, ACS_HLINE); | 150 | waddch(dialog, ACS_HLINE); |
153 | wattrset(dialog, dialog_attr); | 151 | wattrset(dialog, dlg.dialog.atr); |
154 | waddch(dialog, ACS_RTEE); | 152 | waddch(dialog, ACS_RTEE); |
155 | 153 | ||
156 | print_title(dialog, title, width); | 154 | print_title(dialog, title, width); |
157 | 155 | ||
158 | wattrset(dialog, dialog_attr); | 156 | wattrset(dialog, dlg.dialog.atr); |
159 | print_autowrap(dialog, prompt, width - 2, 1, 3); | 157 | print_autowrap(dialog, prompt, width - 2, 1, 3); |
160 | 158 | ||
161 | list_width = width - 6; | 159 | list_width = width - 6; |
@@ -170,12 +168,12 @@ int dialog_checklist(const char *title, const char *prompt, int height, | |||
170 | 168 | ||
171 | /* draw a box around the list items */ | 169 | /* draw a box around the list items */ |
172 | draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2, | 170 | draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2, |
173 | menubox_border_attr, menubox_attr); | 171 | dlg.menubox_border.atr, dlg.menubox.atr); |
174 | 172 | ||
175 | /* Find length of longest item in order to center checklist */ | 173 | /* Find length of longest item in order to center checklist */ |
176 | check_x = 0; | 174 | check_x = 0; |
177 | for (i = 0; i < item_no; i++) | 175 | item_foreach() |
178 | check_x = MAX(check_x, +strlen(items[i * 3 + 1]) + 4); | 176 | check_x = MAX(check_x, strlen(item_str()) + 4); |
179 | 177 | ||
180 | check_x = (list_width - check_x) / 2; | 178 | check_x = (list_width - check_x) / 2; |
181 | item_x = check_x + 4; | 179 | item_x = check_x + 4; |
@@ -187,14 +185,11 @@ int dialog_checklist(const char *title, const char *prompt, int height, | |||
187 | 185 | ||
188 | /* Print the list */ | 186 | /* Print the list */ |
189 | for (i = 0; i < max_choice; i++) { | 187 | for (i = 0; i < max_choice; i++) { |
190 | if (i != choice) | 188 | item_set(scroll + i); |
191 | print_item(list, items[(scroll + i) * 3 + 1], | 189 | print_item(list, i, i == choice); |
192 | status[i + scroll], i, 0); | ||
193 | } | 190 | } |
194 | print_item(list, items[(scroll + choice) * 3 + 1], | ||
195 | status[choice + scroll], choice, 1); | ||
196 | 191 | ||
197 | print_arrows(dialog, choice, item_no, scroll, | 192 | print_arrows(dialog, choice, item_count(), scroll, |
198 | box_y, box_x + check_x + 5, list_height); | 193 | box_y, box_x + check_x + 5, list_height); |
199 | 194 | ||
200 | print_buttons(dialog, height, width, 0); | 195 | print_buttons(dialog, height, width, 0); |
@@ -203,13 +198,14 @@ int dialog_checklist(const char *title, const char *prompt, int height, | |||
203 | wnoutrefresh(list); | 198 | wnoutrefresh(list); |
204 | doupdate(); | 199 | doupdate(); |
205 | 200 | ||
206 | while (key != ESC) { | 201 | while (key != KEY_ESC) { |
207 | key = wgetch(dialog); | 202 | key = wgetch(dialog); |
208 | 203 | ||
209 | for (i = 0; i < max_choice; i++) | 204 | for (i = 0; i < max_choice; i++) { |
210 | if (toupper(key) == | 205 | item_set(i + scroll); |
211 | toupper(items[(scroll + i) * 3 + 1][0])) | 206 | if (toupper(key) == toupper(item_str()[0])) |
212 | break; | 207 | break; |
208 | } | ||
213 | 209 | ||
214 | if (i < max_choice || key == KEY_UP || key == KEY_DOWN || | 210 | if (i < max_choice || key == KEY_UP || key == KEY_DOWN || |
215 | key == '+' || key == '-') { | 211 | key == '+' || key == '-') { |
@@ -220,15 +216,16 @@ int dialog_checklist(const char *title, const char *prompt, int height, | |||
220 | /* Scroll list down */ | 216 | /* Scroll list down */ |
221 | if (list_height > 1) { | 217 | if (list_height > 1) { |
222 | /* De-highlight current first item */ | 218 | /* De-highlight current first item */ |
223 | print_item(list, items[scroll * 3 + 1], | 219 | item_set(scroll); |
224 | status[scroll], 0, FALSE); | 220 | print_item(list, 0, FALSE); |
225 | scrollok(list, TRUE); | 221 | scrollok(list, TRUE); |
226 | wscrl(list, -1); | 222 | wscrl(list, -1); |
227 | scrollok(list, FALSE); | 223 | scrollok(list, FALSE); |
228 | } | 224 | } |
229 | scroll--; | 225 | scroll--; |
230 | print_item(list, items[scroll * 3 + 1], status[scroll], 0, TRUE); | 226 | item_set(scroll); |
231 | print_arrows(dialog, choice, item_no, | 227 | print_item(list, 0, TRUE); |
228 | print_arrows(dialog, choice, item_count(), | ||
232 | scroll, box_y, box_x + check_x + 5, list_height); | 229 | scroll, box_y, box_x + check_x + 5, list_height); |
233 | 230 | ||
234 | wnoutrefresh(dialog); | 231 | wnoutrefresh(dialog); |
@@ -239,23 +236,24 @@ int dialog_checklist(const char *title, const char *prompt, int height, | |||
239 | i = choice - 1; | 236 | i = choice - 1; |
240 | } else if (key == KEY_DOWN || key == '+') { | 237 | } else if (key == KEY_DOWN || key == '+') { |
241 | if (choice == max_choice - 1) { | 238 | if (choice == max_choice - 1) { |
242 | if (scroll + choice >= item_no - 1) | 239 | if (scroll + choice >= item_count() - 1) |
243 | continue; | 240 | continue; |
244 | /* Scroll list up */ | 241 | /* Scroll list up */ |
245 | if (list_height > 1) { | 242 | if (list_height > 1) { |
246 | /* De-highlight current last item before scrolling up */ | 243 | /* De-highlight current last item before scrolling up */ |
247 | print_item(list, items[(scroll + max_choice - 1) * 3 + 1], | 244 | item_set(scroll + max_choice - 1); |
248 | status[scroll + max_choice - 1], | 245 | print_item(list, |
249 | max_choice - 1, FALSE); | 246 | max_choice - 1, |
247 | FALSE); | ||
250 | scrollok(list, TRUE); | 248 | scrollok(list, TRUE); |
251 | wscrl(list, 1); | 249 | wscrl(list, 1); |
252 | scrollok(list, FALSE); | 250 | scrollok(list, FALSE); |
253 | } | 251 | } |
254 | scroll++; | 252 | scroll++; |
255 | print_item(list, items[(scroll + max_choice - 1) * 3 + 1], | 253 | item_set(scroll + max_choice - 1); |
256 | status[scroll + max_choice - 1], max_choice - 1, TRUE); | 254 | print_item(list, max_choice - 1, TRUE); |
257 | 255 | ||
258 | print_arrows(dialog, choice, item_no, | 256 | print_arrows(dialog, choice, item_count(), |
259 | scroll, box_y, box_x + check_x + 5, list_height); | 257 | scroll, box_y, box_x + check_x + 5, list_height); |
260 | 258 | ||
261 | wnoutrefresh(dialog); | 259 | wnoutrefresh(dialog); |
@@ -267,12 +265,12 @@ int dialog_checklist(const char *title, const char *prompt, int height, | |||
267 | } | 265 | } |
268 | if (i != choice) { | 266 | if (i != choice) { |
269 | /* De-highlight current item */ | 267 | /* De-highlight current item */ |
270 | print_item(list, items[(scroll + choice) * 3 + 1], | 268 | item_set(scroll + choice); |
271 | status[scroll + choice], choice, FALSE); | 269 | print_item(list, choice, FALSE); |
272 | /* Highlight new item */ | 270 | /* Highlight new item */ |
273 | choice = i; | 271 | choice = i; |
274 | print_item(list, items[(scroll + choice) * 3 + 1], | 272 | item_set(scroll + choice); |
275 | status[scroll + choice], choice, TRUE); | 273 | print_item(list, choice, TRUE); |
276 | wnoutrefresh(dialog); | 274 | wnoutrefresh(dialog); |
277 | wrefresh(list); | 275 | wrefresh(list); |
278 | } | 276 | } |
@@ -282,10 +280,19 @@ int dialog_checklist(const char *title, const char *prompt, int height, | |||
282 | case 'H': | 280 | case 'H': |
283 | case 'h': | 281 | case 'h': |
284 | case '?': | 282 | case '?': |
285 | fprintf(stderr, "%s", items[(scroll + choice) * 3]); | 283 | button = 1; |
284 | /* fall-through */ | ||
285 | case 'S': | ||
286 | case 's': | ||
287 | case ' ': | ||
288 | case '\n': | ||
289 | item_foreach() | ||
290 | item_set_selected(0); | ||
291 | item_set(scroll + choice); | ||
292 | item_set_selected(1); | ||
293 | delwin(list); | ||
286 | delwin(dialog); | 294 | delwin(dialog); |
287 | free(status); | 295 | return button; |
288 | return 1; | ||
289 | case TAB: | 296 | case TAB: |
290 | case KEY_LEFT: | 297 | case KEY_LEFT: |
291 | case KEY_RIGHT: | 298 | case KEY_RIGHT: |
@@ -295,42 +302,24 @@ int dialog_checklist(const char *title, const char *prompt, int height, | |||
295 | print_buttons(dialog, height, width, button); | 302 | print_buttons(dialog, height, width, button); |
296 | wrefresh(dialog); | 303 | wrefresh(dialog); |
297 | break; | 304 | break; |
298 | case 'S': | ||
299 | case 's': | ||
300 | case ' ': | ||
301 | case '\n': | ||
302 | if (!button) { | ||
303 | if (!status[scroll + choice]) { | ||
304 | for (i = 0; i < item_no; i++) | ||
305 | status[i] = 0; | ||
306 | status[scroll + choice] = 1; | ||
307 | for (i = 0; i < max_choice; i++) | ||
308 | print_item(list, items[(scroll + i) * 3 + 1], | ||
309 | status[scroll + i], i, i == choice); | ||
310 | } | ||
311 | wnoutrefresh(dialog); | ||
312 | wrefresh(list); | ||
313 | |||
314 | for (i = 0; i < item_no; i++) | ||
315 | if (status[i]) | ||
316 | fprintf(stderr, "%s", items[i * 3]); | ||
317 | } else | ||
318 | fprintf(stderr, "%s", items[(scroll + choice) * 3]); | ||
319 | delwin(dialog); | ||
320 | free(status); | ||
321 | return button; | ||
322 | case 'X': | 305 | case 'X': |
323 | case 'x': | 306 | case 'x': |
324 | key = ESC; | 307 | key = KEY_ESC; |
325 | case ESC: | 308 | break; |
309 | case KEY_ESC: | ||
310 | key = on_key_esc(dialog); | ||
326 | break; | 311 | break; |
312 | case KEY_RESIZE: | ||
313 | delwin(list); | ||
314 | delwin(dialog); | ||
315 | on_key_resize(); | ||
316 | goto do_resize; | ||
327 | } | 317 | } |
328 | 318 | ||
329 | /* Now, update everything... */ | 319 | /* Now, update everything... */ |
330 | doupdate(); | 320 | doupdate(); |
331 | } | 321 | } |
332 | 322 | delwin(list); | |
333 | delwin(dialog); | 323 | delwin(dialog); |
334 | free(status); | 324 | return key; /* ESC pressed */ |
335 | return -1; /* ESC pressed */ | ||
336 | } | 325 | } |
diff --git a/scripts/kconfig/lxdialog/colors.h b/scripts/kconfig/lxdialog/colors.h deleted file mode 100644 index db071df12bbb..000000000000 --- a/scripts/kconfig/lxdialog/colors.h +++ /dev/null | |||
@@ -1,154 +0,0 @@ | |||
1 | /* | ||
2 | * colors.h -- color attribute definitions | ||
3 | * | ||
4 | * AUTHOR: Savio Lam (lam836@cs.cuhk.hk) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version 2 | ||
9 | * of the License, or (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | * Default color definitions | ||
23 | * | ||
24 | * *_FG = foreground | ||
25 | * *_BG = background | ||
26 | * *_HL = highlight? | ||
27 | */ | ||
28 | #define SCREEN_FG COLOR_CYAN | ||
29 | #define SCREEN_BG COLOR_BLUE | ||
30 | #define SCREEN_HL TRUE | ||
31 | |||
32 | #define SHADOW_FG COLOR_BLACK | ||
33 | #define SHADOW_BG COLOR_BLACK | ||
34 | #define SHADOW_HL TRUE | ||
35 | |||
36 | #define DIALOG_FG COLOR_BLACK | ||
37 | #define DIALOG_BG COLOR_WHITE | ||
38 | #define DIALOG_HL FALSE | ||
39 | |||
40 | #define TITLE_FG COLOR_YELLOW | ||
41 | #define TITLE_BG COLOR_WHITE | ||
42 | #define TITLE_HL TRUE | ||
43 | |||
44 | #define BORDER_FG COLOR_WHITE | ||
45 | #define BORDER_BG COLOR_WHITE | ||
46 | #define BORDER_HL TRUE | ||
47 | |||
48 | #define BUTTON_ACTIVE_FG COLOR_WHITE | ||
49 | #define BUTTON_ACTIVE_BG COLOR_BLUE | ||
50 | #define BUTTON_ACTIVE_HL TRUE | ||
51 | |||
52 | #define BUTTON_INACTIVE_FG COLOR_BLACK | ||
53 | #define BUTTON_INACTIVE_BG COLOR_WHITE | ||
54 | #define BUTTON_INACTIVE_HL FALSE | ||
55 | |||
56 | #define BUTTON_KEY_ACTIVE_FG COLOR_WHITE | ||
57 | #define BUTTON_KEY_ACTIVE_BG COLOR_BLUE | ||
58 | #define BUTTON_KEY_ACTIVE_HL TRUE | ||
59 | |||
60 | #define BUTTON_KEY_INACTIVE_FG COLOR_RED | ||
61 | #define BUTTON_KEY_INACTIVE_BG COLOR_WHITE | ||
62 | #define BUTTON_KEY_INACTIVE_HL FALSE | ||
63 | |||
64 | #define BUTTON_LABEL_ACTIVE_FG COLOR_YELLOW | ||
65 | #define BUTTON_LABEL_ACTIVE_BG COLOR_BLUE | ||
66 | #define BUTTON_LABEL_ACTIVE_HL TRUE | ||
67 | |||
68 | #define BUTTON_LABEL_INACTIVE_FG COLOR_BLACK | ||
69 | #define BUTTON_LABEL_INACTIVE_BG COLOR_WHITE | ||
70 | #define BUTTON_LABEL_INACTIVE_HL TRUE | ||
71 | |||
72 | #define INPUTBOX_FG COLOR_BLACK | ||
73 | #define INPUTBOX_BG COLOR_WHITE | ||
74 | #define INPUTBOX_HL FALSE | ||
75 | |||
76 | #define INPUTBOX_BORDER_FG COLOR_BLACK | ||
77 | #define INPUTBOX_BORDER_BG COLOR_WHITE | ||
78 | #define INPUTBOX_BORDER_HL FALSE | ||
79 | |||
80 | #define SEARCHBOX_FG COLOR_BLACK | ||
81 | #define SEARCHBOX_BG COLOR_WHITE | ||
82 | #define SEARCHBOX_HL FALSE | ||
83 | |||
84 | #define SEARCHBOX_TITLE_FG COLOR_YELLOW | ||
85 | #define SEARCHBOX_TITLE_BG COLOR_WHITE | ||
86 | #define SEARCHBOX_TITLE_HL TRUE | ||
87 | |||
88 | #define SEARCHBOX_BORDER_FG COLOR_WHITE | ||
89 | #define SEARCHBOX_BORDER_BG COLOR_WHITE | ||
90 | #define SEARCHBOX_BORDER_HL TRUE | ||
91 | |||
92 | #define POSITION_INDICATOR_FG COLOR_YELLOW | ||
93 | #define POSITION_INDICATOR_BG COLOR_WHITE | ||
94 | #define POSITION_INDICATOR_HL TRUE | ||
95 | |||
96 | #define MENUBOX_FG COLOR_BLACK | ||
97 | #define MENUBOX_BG COLOR_WHITE | ||
98 | #define MENUBOX_HL FALSE | ||
99 | |||
100 | #define MENUBOX_BORDER_FG COLOR_WHITE | ||
101 | #define MENUBOX_BORDER_BG COLOR_WHITE | ||
102 | #define MENUBOX_BORDER_HL TRUE | ||
103 | |||
104 | #define ITEM_FG COLOR_BLACK | ||
105 | #define ITEM_BG COLOR_WHITE | ||
106 | #define ITEM_HL FALSE | ||
107 | |||
108 | #define ITEM_SELECTED_FG COLOR_WHITE | ||
109 | #define ITEM_SELECTED_BG COLOR_BLUE | ||
110 | #define ITEM_SELECTED_HL TRUE | ||
111 | |||
112 | #define TAG_FG COLOR_YELLOW | ||
113 | #define TAG_BG COLOR_WHITE | ||
114 | #define TAG_HL TRUE | ||
115 | |||
116 | #define TAG_SELECTED_FG COLOR_YELLOW | ||
117 | #define TAG_SELECTED_BG COLOR_BLUE | ||
118 | #define TAG_SELECTED_HL TRUE | ||
119 | |||
120 | #define TAG_KEY_FG COLOR_YELLOW | ||
121 | #define TAG_KEY_BG COLOR_WHITE | ||
122 | #define TAG_KEY_HL TRUE | ||
123 | |||
124 | #define TAG_KEY_SELECTED_FG COLOR_YELLOW | ||
125 | #define TAG_KEY_SELECTED_BG COLOR_BLUE | ||
126 | #define TAG_KEY_SELECTED_HL TRUE | ||
127 | |||
128 | #define CHECK_FG COLOR_BLACK | ||
129 | #define CHECK_BG COLOR_WHITE | ||
130 | #define CHECK_HL FALSE | ||
131 | |||
132 | #define CHECK_SELECTED_FG COLOR_WHITE | ||
133 | #define CHECK_SELECTED_BG COLOR_BLUE | ||
134 | #define CHECK_SELECTED_HL TRUE | ||
135 | |||
136 | #define UARROW_FG COLOR_GREEN | ||
137 | #define UARROW_BG COLOR_WHITE | ||
138 | #define UARROW_HL TRUE | ||
139 | |||
140 | #define DARROW_FG COLOR_GREEN | ||
141 | #define DARROW_BG COLOR_WHITE | ||
142 | #define DARROW_HL TRUE | ||
143 | |||
144 | /* End of default color definitions */ | ||
145 | |||
146 | #define C_ATTR(x,y) ((x ? A_BOLD : 0) | COLOR_PAIR((y))) | ||
147 | #define COLOR_NAME_LEN 10 | ||
148 | #define COLOR_COUNT 8 | ||
149 | |||
150 | /* | ||
151 | * Global variables | ||
152 | */ | ||
153 | |||
154 | extern int color_table[][3]; | ||
diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h index af3cf716e215..8dea47f9d3e4 100644 --- a/scripts/kconfig/lxdialog/dialog.h +++ b/scripts/kconfig/lxdialog/dialog.h | |||
@@ -48,7 +48,7 @@ | |||
48 | 48 | ||
49 | #define TR(params) _tracef params | 49 | #define TR(params) _tracef params |
50 | 50 | ||
51 | #define ESC 27 | 51 | #define KEY_ESC 27 |
52 | #define TAB 9 | 52 | #define TAB 9 |
53 | #define MAX_LEN 2048 | 53 | #define MAX_LEN 2048 |
54 | #define BUF_SIZE (10*1024) | 54 | #define BUF_SIZE (10*1024) |
@@ -86,63 +86,111 @@ | |||
86 | #define ACS_DARROW 'v' | 86 | #define ACS_DARROW 'v' |
87 | #endif | 87 | #endif |
88 | 88 | ||
89 | /* error return codes */ | ||
90 | #define ERRDISPLAYTOOSMALL (KEY_MAX + 1) | ||
91 | |||
89 | /* | 92 | /* |
90 | * Attribute names | 93 | * Color definitions |
91 | */ | 94 | */ |
92 | #define screen_attr attributes[0] | 95 | struct dialog_color { |
93 | #define shadow_attr attributes[1] | 96 | chtype atr; /* Color attribute */ |
94 | #define dialog_attr attributes[2] | 97 | int fg; /* foreground */ |
95 | #define title_attr attributes[3] | 98 | int bg; /* background */ |
96 | #define border_attr attributes[4] | 99 | int hl; /* highlight this item */ |
97 | #define button_active_attr attributes[5] | 100 | }; |
98 | #define button_inactive_attr attributes[6] | 101 | |
99 | #define button_key_active_attr attributes[7] | 102 | struct dialog_info { |
100 | #define button_key_inactive_attr attributes[8] | 103 | const char *backtitle; |
101 | #define button_label_active_attr attributes[9] | 104 | struct dialog_color screen; |
102 | #define button_label_inactive_attr attributes[10] | 105 | struct dialog_color shadow; |
103 | #define inputbox_attr attributes[11] | 106 | struct dialog_color dialog; |
104 | #define inputbox_border_attr attributes[12] | 107 | struct dialog_color title; |
105 | #define searchbox_attr attributes[13] | 108 | struct dialog_color border; |
106 | #define searchbox_title_attr attributes[14] | 109 | struct dialog_color button_active; |
107 | #define searchbox_border_attr attributes[15] | 110 | struct dialog_color button_inactive; |
108 | #define position_indicator_attr attributes[16] | 111 | struct dialog_color button_key_active; |
109 | #define menubox_attr attributes[17] | 112 | struct dialog_color button_key_inactive; |
110 | #define menubox_border_attr attributes[18] | 113 | struct dialog_color button_label_active; |
111 | #define item_attr attributes[19] | 114 | struct dialog_color button_label_inactive; |
112 | #define item_selected_attr attributes[20] | 115 | struct dialog_color inputbox; |
113 | #define tag_attr attributes[21] | 116 | struct dialog_color inputbox_border; |
114 | #define tag_selected_attr attributes[22] | 117 | struct dialog_color searchbox; |
115 | #define tag_key_attr attributes[23] | 118 | struct dialog_color searchbox_title; |
116 | #define tag_key_selected_attr attributes[24] | 119 | struct dialog_color searchbox_border; |
117 | #define check_attr attributes[25] | 120 | struct dialog_color position_indicator; |
118 | #define check_selected_attr attributes[26] | 121 | struct dialog_color menubox; |
119 | #define uarrow_attr attributes[27] | 122 | struct dialog_color menubox_border; |
120 | #define darrow_attr attributes[28] | 123 | struct dialog_color item; |
121 | 124 | struct dialog_color item_selected; | |
122 | /* number of attributes */ | 125 | struct dialog_color tag; |
123 | #define ATTRIBUTE_COUNT 29 | 126 | struct dialog_color tag_selected; |
127 | struct dialog_color tag_key; | ||
128 | struct dialog_color tag_key_selected; | ||
129 | struct dialog_color check; | ||
130 | struct dialog_color check_selected; | ||
131 | struct dialog_color uarrow; | ||
132 | struct dialog_color darrow; | ||
133 | }; | ||
124 | 134 | ||
125 | /* | 135 | /* |
126 | * Global variables | 136 | * Global variables |
127 | */ | 137 | */ |
128 | extern bool use_colors; | 138 | extern struct dialog_info dlg; |
129 | extern bool use_shadow; | 139 | extern char dialog_input_result[]; |
130 | |||
131 | extern chtype attributes[]; | ||
132 | |||
133 | extern const char *backtitle; | ||
134 | 140 | ||
135 | /* | 141 | /* |
136 | * Function prototypes | 142 | * Function prototypes |
137 | */ | 143 | */ |
138 | extern void create_rc(const char *filename); | ||
139 | extern int parse_rc(void); | ||
140 | 144 | ||
141 | void init_dialog(void); | 145 | /* item list as used by checklist and menubox */ |
146 | void item_reset(void); | ||
147 | void item_make(const char *fmt, ...); | ||
148 | void item_add_str(const char *fmt, ...); | ||
149 | void item_set_tag(char tag); | ||
150 | void item_set_data(void *p); | ||
151 | void item_set_selected(int val); | ||
152 | int item_activate_selected(void); | ||
153 | void *item_data(void); | ||
154 | char item_tag(void); | ||
155 | |||
156 | /* item list manipulation for lxdialog use */ | ||
157 | #define MAXITEMSTR 200 | ||
158 | struct dialog_item { | ||
159 | char str[MAXITEMSTR]; /* promtp displayed */ | ||
160 | char tag; | ||
161 | void *data; /* pointer to menu item - used by menubox+checklist */ | ||
162 | int selected; /* Set to 1 by dialog_*() function if selected. */ | ||
163 | }; | ||
164 | |||
165 | /* list of lialog_items */ | ||
166 | struct dialog_list { | ||
167 | struct dialog_item node; | ||
168 | struct dialog_list *next; | ||
169 | }; | ||
170 | |||
171 | extern struct dialog_list *item_cur; | ||
172 | extern struct dialog_list item_nil; | ||
173 | extern struct dialog_list *item_head; | ||
174 | |||
175 | int item_count(void); | ||
176 | void item_set(int n); | ||
177 | int item_n(void); | ||
178 | const char *item_str(void); | ||
179 | int item_is_selected(void); | ||
180 | int item_is_tag(char tag); | ||
181 | #define item_foreach() \ | ||
182 | for (item_cur = item_head ? item_head: item_cur; \ | ||
183 | item_cur && (item_cur != &item_nil); item_cur = item_cur->next) | ||
184 | |||
185 | /* generic key handlers */ | ||
186 | int on_key_esc(WINDOW *win); | ||
187 | int on_key_resize(void); | ||
188 | |||
189 | void init_dialog(const char *backtitle); | ||
190 | void reset_dialog(void); | ||
142 | void end_dialog(void); | 191 | void end_dialog(void); |
143 | void attr_clear(WINDOW * win, int height, int width, chtype attr); | 192 | void attr_clear(WINDOW * win, int height, int width, chtype attr); |
144 | void dialog_clear(void); | 193 | void dialog_clear(void); |
145 | void color_setup(void); | ||
146 | void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x); | 194 | void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x); |
147 | void print_button(WINDOW * win, const char *label, int y, int x, int selected); | 195 | void print_button(WINDOW * win, const char *label, int y, int x, int selected); |
148 | void print_title(WINDOW *dialog, const char *title, int width); | 196 | void print_title(WINDOW *dialog, const char *title, int width); |
@@ -155,12 +203,10 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width); | |||
155 | int dialog_msgbox(const char *title, const char *prompt, int height, | 203 | int dialog_msgbox(const char *title, const char *prompt, int height, |
156 | int width, int pause); | 204 | int width, int pause); |
157 | int dialog_textbox(const char *title, const char *file, int height, int width); | 205 | int dialog_textbox(const char *title, const char *file, int height, int width); |
158 | int dialog_menu(const char *title, const char *prompt, int height, int width, | 206 | int dialog_menu(const char *title, const char *prompt, |
159 | int menu_height, const char *choice, int item_no, | 207 | const void *selected, int *s_scroll); |
160 | const char *const *items); | ||
161 | int dialog_checklist(const char *title, const char *prompt, int height, | 208 | int dialog_checklist(const char *title, const char *prompt, int height, |
162 | int width, int list_height, int item_no, | 209 | int width, int list_height); |
163 | const char *const *items); | ||
164 | extern char dialog_input_result[]; | 210 | extern char dialog_input_result[]; |
165 | int dialog_inputbox(const char *title, const char *prompt, int height, | 211 | int dialog_inputbox(const char *title, const char *prompt, int height, |
166 | int width, const char *init); | 212 | int width, const char *init); |
diff --git a/scripts/kconfig/lxdialog/inputbox.c b/scripts/kconfig/lxdialog/inputbox.c index 779503726b0a..05e72066b359 100644 --- a/scripts/kconfig/lxdialog/inputbox.c +++ b/scripts/kconfig/lxdialog/inputbox.c | |||
@@ -49,6 +49,17 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width | |||
49 | char *instr = dialog_input_result; | 49 | char *instr = dialog_input_result; |
50 | WINDOW *dialog; | 50 | WINDOW *dialog; |
51 | 51 | ||
52 | if (!init) | ||
53 | instr[0] = '\0'; | ||
54 | else | ||
55 | strcpy(instr, init); | ||
56 | |||
57 | do_resize: | ||
58 | if (getmaxy(stdscr) <= (height - 2)) | ||
59 | return -ERRDISPLAYTOOSMALL; | ||
60 | if (getmaxx(stdscr) <= (width - 2)) | ||
61 | return -ERRDISPLAYTOOSMALL; | ||
62 | |||
52 | /* center dialog box on screen */ | 63 | /* center dialog box on screen */ |
53 | x = (COLS - width) / 2; | 64 | x = (COLS - width) / 2; |
54 | y = (LINES - height) / 2; | 65 | y = (LINES - height) / 2; |
@@ -58,17 +69,18 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width | |||
58 | dialog = newwin(height, width, y, x); | 69 | dialog = newwin(height, width, y, x); |
59 | keypad(dialog, TRUE); | 70 | keypad(dialog, TRUE); |
60 | 71 | ||
61 | draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); | 72 | draw_box(dialog, 0, 0, height, width, |
62 | wattrset(dialog, border_attr); | 73 | dlg.dialog.atr, dlg.border.atr); |
74 | wattrset(dialog, dlg.border.atr); | ||
63 | mvwaddch(dialog, height - 3, 0, ACS_LTEE); | 75 | mvwaddch(dialog, height - 3, 0, ACS_LTEE); |
64 | for (i = 0; i < width - 2; i++) | 76 | for (i = 0; i < width - 2; i++) |
65 | waddch(dialog, ACS_HLINE); | 77 | waddch(dialog, ACS_HLINE); |
66 | wattrset(dialog, dialog_attr); | 78 | wattrset(dialog, dlg.dialog.atr); |
67 | waddch(dialog, ACS_RTEE); | 79 | waddch(dialog, ACS_RTEE); |
68 | 80 | ||
69 | print_title(dialog, title, width); | 81 | print_title(dialog, title, width); |
70 | 82 | ||
71 | wattrset(dialog, dialog_attr); | 83 | wattrset(dialog, dlg.dialog.atr); |
72 | print_autowrap(dialog, prompt, width - 2, 1, 3); | 84 | print_autowrap(dialog, prompt, width - 2, 1, 3); |
73 | 85 | ||
74 | /* Draw the input field box */ | 86 | /* Draw the input field box */ |
@@ -76,18 +88,14 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width | |||
76 | getyx(dialog, y, x); | 88 | getyx(dialog, y, x); |
77 | box_y = y + 2; | 89 | box_y = y + 2; |
78 | box_x = (width - box_width) / 2; | 90 | box_x = (width - box_width) / 2; |
79 | draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2, border_attr, dialog_attr); | 91 | draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2, |
92 | dlg.border.atr, dlg.dialog.atr); | ||
80 | 93 | ||
81 | print_buttons(dialog, height, width, 0); | 94 | print_buttons(dialog, height, width, 0); |
82 | 95 | ||
83 | /* Set up the initial value */ | 96 | /* Set up the initial value */ |
84 | wmove(dialog, box_y, box_x); | 97 | wmove(dialog, box_y, box_x); |
85 | wattrset(dialog, inputbox_attr); | 98 | wattrset(dialog, dlg.inputbox.atr); |
86 | |||
87 | if (!init) | ||
88 | instr[0] = '\0'; | ||
89 | else | ||
90 | strcpy(instr, init); | ||
91 | 99 | ||
92 | input_x = strlen(instr); | 100 | input_x = strlen(instr); |
93 | 101 | ||
@@ -104,7 +112,7 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width | |||
104 | 112 | ||
105 | wrefresh(dialog); | 113 | wrefresh(dialog); |
106 | 114 | ||
107 | while (key != ESC) { | 115 | while (key != KEY_ESC) { |
108 | key = wgetch(dialog); | 116 | key = wgetch(dialog); |
109 | 117 | ||
110 | if (button == -1) { /* Input box selected */ | 118 | if (button == -1) { /* Input box selected */ |
@@ -120,7 +128,7 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width | |||
120 | case KEY_BACKSPACE: | 128 | case KEY_BACKSPACE: |
121 | case 127: | 129 | case 127: |
122 | if (input_x || scroll) { | 130 | if (input_x || scroll) { |
123 | wattrset(dialog, inputbox_attr); | 131 | wattrset(dialog, dlg.inputbox.atr); |
124 | if (!input_x) { | 132 | if (!input_x) { |
125 | scroll = scroll < box_width - 1 ? 0 : scroll - (box_width - 1); | 133 | scroll = scroll < box_width - 1 ? 0 : scroll - (box_width - 1); |
126 | wmove(dialog, box_y, box_x); | 134 | wmove(dialog, box_y, box_x); |
@@ -140,7 +148,7 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width | |||
140 | default: | 148 | default: |
141 | if (key < 0x100 && isprint(key)) { | 149 | if (key < 0x100 && isprint(key)) { |
142 | if (scroll + input_x < MAX_LEN) { | 150 | if (scroll + input_x < MAX_LEN) { |
143 | wattrset(dialog, inputbox_attr); | 151 | wattrset(dialog, dlg.inputbox.atr); |
144 | instr[scroll + input_x] = key; | 152 | instr[scroll + input_x] = key; |
145 | instr[scroll + input_x + 1] = '\0'; | 153 | instr[scroll + input_x + 1] = '\0'; |
146 | if (input_x == box_width - 1) { | 154 | if (input_x == box_width - 1) { |
@@ -213,12 +221,18 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width | |||
213 | return (button == -1 ? 0 : button); | 221 | return (button == -1 ? 0 : button); |
214 | case 'X': | 222 | case 'X': |
215 | case 'x': | 223 | case 'x': |
216 | key = ESC; | 224 | key = KEY_ESC; |
217 | case ESC: | 225 | break; |
226 | case KEY_ESC: | ||
227 | key = on_key_esc(dialog); | ||
218 | break; | 228 | break; |
229 | case KEY_RESIZE: | ||
230 | delwin(dialog); | ||
231 | on_key_resize(); | ||
232 | goto do_resize; | ||
219 | } | 233 | } |
220 | } | 234 | } |
221 | 235 | ||
222 | delwin(dialog); | 236 | delwin(dialog); |
223 | return -1; /* ESC pressed */ | 237 | return KEY_ESC; /* ESC pressed */ |
224 | } | 238 | } |
diff --git a/scripts/kconfig/lxdialog/lxdialog.c b/scripts/kconfig/lxdialog/lxdialog.c deleted file mode 100644 index 79f6c5fb5cef..000000000000 --- a/scripts/kconfig/lxdialog/lxdialog.c +++ /dev/null | |||
@@ -1,204 +0,0 @@ | |||
1 | /* | ||
2 | * dialog - Display simple dialog boxes from shell scripts | ||
3 | * | ||
4 | * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) | ||
5 | * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version 2 | ||
10 | * of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | ||
21 | |||
22 | #include "dialog.h" | ||
23 | |||
24 | static void Usage(const char *name); | ||
25 | |||
26 | typedef int (jumperFn) (const char *title, int argc, const char *const *argv); | ||
27 | |||
28 | struct Mode { | ||
29 | char *name; | ||
30 | int argmin, argmax, argmod; | ||
31 | jumperFn *jumper; | ||
32 | }; | ||
33 | |||
34 | jumperFn j_menu, j_radiolist, j_yesno, j_textbox, j_inputbox; | ||
35 | jumperFn j_msgbox, j_infobox; | ||
36 | |||
37 | static struct Mode modes[] = { | ||
38 | {"--menu", 9, 0, 3, j_menu}, | ||
39 | {"--radiolist", 9, 0, 3, j_radiolist}, | ||
40 | {"--yesno", 5, 5, 1, j_yesno}, | ||
41 | {"--textbox", 5, 5, 1, j_textbox}, | ||
42 | {"--inputbox", 5, 6, 1, j_inputbox}, | ||
43 | {"--msgbox", 5, 5, 1, j_msgbox}, | ||
44 | {"--infobox", 5, 5, 1, j_infobox}, | ||
45 | {NULL, 0, 0, 0, NULL} | ||
46 | }; | ||
47 | |||
48 | static struct Mode *modePtr; | ||
49 | |||
50 | #ifdef LOCALE | ||
51 | #include <locale.h> | ||
52 | #endif | ||
53 | |||
54 | int main(int argc, const char *const *argv) | ||
55 | { | ||
56 | int offset = 0, opt_clear = 0, end_common_opts = 0, retval; | ||
57 | const char *title = NULL; | ||
58 | |||
59 | #ifdef LOCALE | ||
60 | (void)setlocale(LC_ALL, ""); | ||
61 | #endif | ||
62 | |||
63 | #ifdef TRACE | ||
64 | trace(TRACE_CALLS | TRACE_UPDATE); | ||
65 | #endif | ||
66 | if (argc < 2) { | ||
67 | Usage(argv[0]); | ||
68 | exit(-1); | ||
69 | } | ||
70 | |||
71 | while (offset < argc - 1 && !end_common_opts) { /* Common options */ | ||
72 | if (!strcmp(argv[offset + 1], "--title")) { | ||
73 | if (argc - offset < 3 || title != NULL) { | ||
74 | Usage(argv[0]); | ||
75 | exit(-1); | ||
76 | } else { | ||
77 | title = argv[offset + 2]; | ||
78 | offset += 2; | ||
79 | } | ||
80 | } else if (!strcmp(argv[offset + 1], "--backtitle")) { | ||
81 | if (backtitle != NULL) { | ||
82 | Usage(argv[0]); | ||
83 | exit(-1); | ||
84 | } else { | ||
85 | backtitle = argv[offset + 2]; | ||
86 | offset += 2; | ||
87 | } | ||
88 | } else if (!strcmp(argv[offset + 1], "--clear")) { | ||
89 | if (opt_clear) { /* Hey, "--clear" can't appear twice! */ | ||
90 | Usage(argv[0]); | ||
91 | exit(-1); | ||
92 | } else if (argc == 2) { /* we only want to clear the screen */ | ||
93 | init_dialog(); | ||
94 | refresh(); /* init_dialog() will clear the screen for us */ | ||
95 | end_dialog(); | ||
96 | return 0; | ||
97 | } else { | ||
98 | opt_clear = 1; | ||
99 | offset++; | ||
100 | } | ||
101 | } else /* no more common options */ | ||
102 | end_common_opts = 1; | ||
103 | } | ||
104 | |||
105 | if (argc - 1 == offset) { /* no more options */ | ||
106 | Usage(argv[0]); | ||
107 | exit(-1); | ||
108 | } | ||
109 | /* use a table to look for the requested mode, to avoid code duplication */ | ||
110 | |||
111 | for (modePtr = modes; modePtr->name; modePtr++) /* look for the mode */ | ||
112 | if (!strcmp(argv[offset + 1], modePtr->name)) | ||
113 | break; | ||
114 | |||
115 | if (!modePtr->name) | ||
116 | Usage(argv[0]); | ||
117 | if (argc - offset < modePtr->argmin) | ||
118 | Usage(argv[0]); | ||
119 | if (modePtr->argmax && argc - offset > modePtr->argmax) | ||
120 | Usage(argv[0]); | ||
121 | |||
122 | init_dialog(); | ||
123 | retval = (*(modePtr->jumper)) (title, argc - offset, argv + offset); | ||
124 | |||
125 | if (opt_clear) { /* clear screen before exit */ | ||
126 | attr_clear(stdscr, LINES, COLS, screen_attr); | ||
127 | refresh(); | ||
128 | } | ||
129 | end_dialog(); | ||
130 | |||
131 | exit(retval); | ||
132 | } | ||
133 | |||
134 | /* | ||
135 | * Print program usage | ||
136 | */ | ||
137 | static void Usage(const char *name) | ||
138 | { | ||
139 | fprintf(stderr, "\ | ||
140 | \ndialog, by Savio Lam (lam836@cs.cuhk.hk).\ | ||
141 | \n patched by Stuart Herbert (S.Herbert@shef.ac.uk)\ | ||
142 | \n modified/gutted for use as a Linux kernel config tool by \ | ||
143 | \n William Roadcap (roadcapw@cfw.com)\ | ||
144 | \n\ | ||
145 | \n* Display dialog boxes from shell scripts *\ | ||
146 | \n\ | ||
147 | \nUsage: %s --clear\ | ||
148 | \n %s [--title <title>] [--backtitle <backtitle>] --clear <Box options>\ | ||
149 | \n\ | ||
150 | \nBox options:\ | ||
151 | \n\ | ||
152 | \n --menu <text> <height> <width> <menu height> <tag1> <item1>...\ | ||
153 | \n --radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...\ | ||
154 | \n --textbox <file> <height> <width>\ | ||
155 | \n --inputbox <text> <height> <width> [<init>]\ | ||
156 | \n --yesno <text> <height> <width>\ | ||
157 | \n", name, name); | ||
158 | exit(-1); | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * These are the program jumpers | ||
163 | */ | ||
164 | |||
165 | int j_menu(const char *t, int ac, const char *const *av) | ||
166 | { | ||
167 | return dialog_menu(t, av[2], atoi(av[3]), atoi(av[4]), | ||
168 | atoi(av[5]), av[6], (ac - 6) / 2, av + 7); | ||
169 | } | ||
170 | |||
171 | int j_radiolist(const char *t, int ac, const char *const *av) | ||
172 | { | ||
173 | return dialog_checklist(t, av[2], atoi(av[3]), atoi(av[4]), | ||
174 | atoi(av[5]), (ac - 6) / 3, av + 6); | ||
175 | } | ||
176 | |||
177 | int j_textbox(const char *t, int ac, const char *const *av) | ||
178 | { | ||
179 | return dialog_textbox(t, av[2], atoi(av[3]), atoi(av[4])); | ||
180 | } | ||
181 | |||
182 | int j_yesno(const char *t, int ac, const char *const *av) | ||
183 | { | ||
184 | return dialog_yesno(t, av[2], atoi(av[3]), atoi(av[4])); | ||
185 | } | ||
186 | |||
187 | int j_inputbox(const char *t, int ac, const char *const *av) | ||
188 | { | ||
189 | int ret = dialog_inputbox(t, av[2], atoi(av[3]), atoi(av[4]), | ||
190 | ac == 6 ? av[5] : (char *)NULL); | ||
191 | if (ret == 0) | ||
192 | fprintf(stderr, dialog_input_result); | ||
193 | return ret; | ||
194 | } | ||
195 | |||
196 | int j_msgbox(const char *t, int ac, const char *const *av) | ||
197 | { | ||
198 | return dialog_msgbox(t, av[2], atoi(av[3]), atoi(av[4]), 1); | ||
199 | } | ||
200 | |||
201 | int j_infobox(const char *t, int ac, const char *const *av) | ||
202 | { | ||
203 | return dialog_msgbox(t, av[2], atoi(av[3]), atoi(av[4]), 0); | ||
204 | } | ||
diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c index bf8052f4fd4a..0d83159d9012 100644 --- a/scripts/kconfig/lxdialog/menubox.c +++ b/scripts/kconfig/lxdialog/menubox.c | |||
@@ -63,19 +63,19 @@ static int menu_width, item_x; | |||
63 | /* | 63 | /* |
64 | * Print menu item | 64 | * Print menu item |
65 | */ | 65 | */ |
66 | static void do_print_item(WINDOW * win, const char *item, int choice, | 66 | static void do_print_item(WINDOW * win, const char *item, int line_y, |
67 | int selected, int hotkey) | 67 | int selected, int hotkey) |
68 | { | 68 | { |
69 | int j; | 69 | int j; |
70 | char *menu_item = malloc(menu_width + 1); | 70 | char *menu_item = malloc(menu_width + 1); |
71 | 71 | ||
72 | strncpy(menu_item, item, menu_width - item_x); | 72 | strncpy(menu_item, item, menu_width - item_x); |
73 | menu_item[menu_width] = 0; | 73 | menu_item[menu_width - item_x] = '\0'; |
74 | j = first_alpha(menu_item, "YyNnMmHh"); | 74 | j = first_alpha(menu_item, "YyNnMmHh"); |
75 | 75 | ||
76 | /* Clear 'residue' of last item */ | 76 | /* Clear 'residue' of last item */ |
77 | wattrset(win, menubox_attr); | 77 | wattrset(win, dlg.menubox.atr); |
78 | wmove(win, choice, 0); | 78 | wmove(win, line_y, 0); |
79 | #if OLD_NCURSES | 79 | #if OLD_NCURSES |
80 | { | 80 | { |
81 | int i; | 81 | int i; |
@@ -85,23 +85,24 @@ static void do_print_item(WINDOW * win, const char *item, int choice, | |||
85 | #else | 85 | #else |
86 | wclrtoeol(win); | 86 | wclrtoeol(win); |
87 | #endif | 87 | #endif |
88 | wattrset(win, selected ? item_selected_attr : item_attr); | 88 | wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr); |
89 | mvwaddstr(win, choice, item_x, menu_item); | 89 | mvwaddstr(win, line_y, item_x, menu_item); |
90 | if (hotkey) { | 90 | if (hotkey) { |
91 | wattrset(win, selected ? tag_key_selected_attr : tag_key_attr); | 91 | wattrset(win, selected ? dlg.tag_key_selected.atr |
92 | mvwaddch(win, choice, item_x + j, menu_item[j]); | 92 | : dlg.tag_key.atr); |
93 | mvwaddch(win, line_y, item_x + j, menu_item[j]); | ||
93 | } | 94 | } |
94 | if (selected) { | 95 | if (selected) { |
95 | wmove(win, choice, item_x + 1); | 96 | wmove(win, line_y, item_x + 1); |
96 | } | 97 | } |
97 | free(menu_item); | 98 | free(menu_item); |
98 | wrefresh(win); | 99 | wrefresh(win); |
99 | } | 100 | } |
100 | 101 | ||
101 | #define print_item(index, choice, selected) \ | 102 | #define print_item(index, choice, selected) \ |
102 | do {\ | 103 | do { \ |
103 | int hotkey = (items[(index) * 2][0] != ':'); \ | 104 | item_set(index); \ |
104 | do_print_item(menu, items[(index) * 2 + 1], choice, selected, hotkey); \ | 105 | do_print_item(menu, item_str(), choice, selected, !item_is_tag(':')); \ |
105 | } while (0) | 106 | } while (0) |
106 | 107 | ||
107 | /* | 108 | /* |
@@ -117,11 +118,11 @@ static void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x, | |||
117 | wmove(win, y, x); | 118 | wmove(win, y, x); |
118 | 119 | ||
119 | if (scroll > 0) { | 120 | if (scroll > 0) { |
120 | wattrset(win, uarrow_attr); | 121 | wattrset(win, dlg.uarrow.atr); |
121 | waddch(win, ACS_UARROW); | 122 | waddch(win, ACS_UARROW); |
122 | waddstr(win, "(-)"); | 123 | waddstr(win, "(-)"); |
123 | } else { | 124 | } else { |
124 | wattrset(win, menubox_attr); | 125 | wattrset(win, dlg.menubox.atr); |
125 | waddch(win, ACS_HLINE); | 126 | waddch(win, ACS_HLINE); |
126 | waddch(win, ACS_HLINE); | 127 | waddch(win, ACS_HLINE); |
127 | waddch(win, ACS_HLINE); | 128 | waddch(win, ACS_HLINE); |
@@ -133,11 +134,11 @@ static void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x, | |||
133 | wrefresh(win); | 134 | wrefresh(win); |
134 | 135 | ||
135 | if ((height < item_no) && (scroll + height < item_no)) { | 136 | if ((height < item_no) && (scroll + height < item_no)) { |
136 | wattrset(win, darrow_attr); | 137 | wattrset(win, dlg.darrow.atr); |
137 | waddch(win, ACS_DARROW); | 138 | waddch(win, ACS_DARROW); |
138 | waddstr(win, "(+)"); | 139 | waddstr(win, "(+)"); |
139 | } else { | 140 | } else { |
140 | wattrset(win, menubox_border_attr); | 141 | wattrset(win, dlg.menubox_border.atr); |
141 | waddch(win, ACS_HLINE); | 142 | waddch(win, ACS_HLINE); |
142 | waddch(win, ACS_HLINE); | 143 | waddch(win, ACS_HLINE); |
143 | waddch(win, ACS_HLINE); | 144 | waddch(win, ACS_HLINE); |
@@ -178,17 +179,26 @@ static void do_scroll(WINDOW *win, int *scroll, int n) | |||
178 | /* | 179 | /* |
179 | * Display a menu for choosing among a number of options | 180 | * Display a menu for choosing among a number of options |
180 | */ | 181 | */ |
181 | int dialog_menu(const char *title, const char *prompt, int height, int width, | 182 | int dialog_menu(const char *title, const char *prompt, |
182 | int menu_height, const char *current, int item_no, | 183 | const void *selected, int *s_scroll) |
183 | const char *const *items) | ||
184 | { | 184 | { |
185 | int i, j, x, y, box_x, box_y; | 185 | int i, j, x, y, box_x, box_y; |
186 | int height, width, menu_height; | ||
186 | int key = 0, button = 0, scroll = 0, choice = 0; | 187 | int key = 0, button = 0, scroll = 0, choice = 0; |
187 | int first_item = 0, max_choice; | 188 | int first_item = 0, max_choice; |
188 | WINDOW *dialog, *menu; | 189 | WINDOW *dialog, *menu; |
189 | FILE *f; | ||
190 | 190 | ||
191 | max_choice = MIN(menu_height, item_no); | 191 | do_resize: |
192 | height = getmaxy(stdscr); | ||
193 | width = getmaxx(stdscr); | ||
194 | if (height < 15 || width < 65) | ||
195 | return -ERRDISPLAYTOOSMALL; | ||
196 | |||
197 | height -= 4; | ||
198 | width -= 5; | ||
199 | menu_height = height - 10; | ||
200 | |||
201 | max_choice = MIN(menu_height, item_count()); | ||
192 | 202 | ||
193 | /* center dialog box on screen */ | 203 | /* center dialog box on screen */ |
194 | x = (COLS - width) / 2; | 204 | x = (COLS - width) / 2; |
@@ -199,18 +209,19 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, | |||
199 | dialog = newwin(height, width, y, x); | 209 | dialog = newwin(height, width, y, x); |
200 | keypad(dialog, TRUE); | 210 | keypad(dialog, TRUE); |
201 | 211 | ||
202 | draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); | 212 | draw_box(dialog, 0, 0, height, width, |
203 | wattrset(dialog, border_attr); | 213 | dlg.dialog.atr, dlg.border.atr); |
214 | wattrset(dialog, dlg.border.atr); | ||
204 | mvwaddch(dialog, height - 3, 0, ACS_LTEE); | 215 | mvwaddch(dialog, height - 3, 0, ACS_LTEE); |
205 | for (i = 0; i < width - 2; i++) | 216 | for (i = 0; i < width - 2; i++) |
206 | waddch(dialog, ACS_HLINE); | 217 | waddch(dialog, ACS_HLINE); |
207 | wattrset(dialog, dialog_attr); | 218 | wattrset(dialog, dlg.dialog.atr); |
208 | wbkgdset(dialog, dialog_attr & A_COLOR); | 219 | wbkgdset(dialog, dlg.dialog.atr & A_COLOR); |
209 | waddch(dialog, ACS_RTEE); | 220 | waddch(dialog, ACS_RTEE); |
210 | 221 | ||
211 | print_title(dialog, title, width); | 222 | print_title(dialog, title, width); |
212 | 223 | ||
213 | wattrset(dialog, dialog_attr); | 224 | wattrset(dialog, dlg.dialog.atr); |
214 | print_autowrap(dialog, prompt, width - 2, 1, 3); | 225 | print_autowrap(dialog, prompt, width - 2, 1, 3); |
215 | 226 | ||
216 | menu_width = width - 6; | 227 | menu_width = width - 6; |
@@ -224,33 +235,29 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, | |||
224 | 235 | ||
225 | /* draw a box around the menu items */ | 236 | /* draw a box around the menu items */ |
226 | draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2, | 237 | draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2, |
227 | menubox_border_attr, menubox_attr); | 238 | dlg.menubox_border.atr, dlg.menubox.atr); |
228 | 239 | ||
229 | item_x = (menu_width - 70) / 2; | 240 | if (menu_width >= 80) |
241 | item_x = (menu_width - 70) / 2; | ||
242 | else | ||
243 | item_x = 4; | ||
230 | 244 | ||
231 | /* Set choice to default item */ | 245 | /* Set choice to default item */ |
232 | for (i = 0; i < item_no; i++) | 246 | item_foreach() |
233 | if (strcmp(current, items[i * 2]) == 0) | 247 | if (selected && (selected == item_data())) |
234 | choice = i; | 248 | choice = item_n(); |
235 | 249 | /* get the saved scroll info */ | |
236 | /* get the scroll info from the temp file */ | 250 | scroll = *s_scroll; |
237 | if ((f = fopen("lxdialog.scrltmp", "r")) != NULL) { | 251 | if ((scroll <= choice) && (scroll + max_choice > choice) && |
238 | if ((fscanf(f, "%d\n", &scroll) == 1) && (scroll <= choice) && | 252 | (scroll >= 0) && (scroll + max_choice <= item_count())) { |
239 | (scroll + max_choice > choice) && (scroll >= 0) && | 253 | first_item = scroll; |
240 | (scroll + max_choice <= item_no)) { | 254 | choice = choice - scroll; |
241 | first_item = scroll; | 255 | } else { |
242 | choice = choice - scroll; | 256 | scroll = 0; |
243 | fclose(f); | ||
244 | } else { | ||
245 | scroll = 0; | ||
246 | remove("lxdialog.scrltmp"); | ||
247 | fclose(f); | ||
248 | f = NULL; | ||
249 | } | ||
250 | } | 257 | } |
251 | if ((choice >= max_choice) || (f == NULL && choice >= max_choice / 2)) { | 258 | if ((choice >= max_choice)) { |
252 | if (choice >= item_no - max_choice / 2) | 259 | if (choice >= item_count() - max_choice / 2) |
253 | scroll = first_item = item_no - max_choice; | 260 | scroll = first_item = item_count() - max_choice; |
254 | else | 261 | else |
255 | scroll = first_item = choice - max_choice / 2; | 262 | scroll = first_item = choice - max_choice / 2; |
256 | choice = choice - scroll; | 263 | choice = choice - scroll; |
@@ -263,14 +270,14 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, | |||
263 | 270 | ||
264 | wnoutrefresh(menu); | 271 | wnoutrefresh(menu); |
265 | 272 | ||
266 | print_arrows(dialog, item_no, scroll, | 273 | print_arrows(dialog, item_count(), scroll, |
267 | box_y, box_x + item_x + 1, menu_height); | 274 | box_y, box_x + item_x + 1, menu_height); |
268 | 275 | ||
269 | print_buttons(dialog, height, width, 0); | 276 | print_buttons(dialog, height, width, 0); |
270 | wmove(menu, choice, item_x + 1); | 277 | wmove(menu, choice, item_x + 1); |
271 | wrefresh(menu); | 278 | wrefresh(menu); |
272 | 279 | ||
273 | while (key != ESC) { | 280 | while (key != KEY_ESC) { |
274 | key = wgetch(menu); | 281 | key = wgetch(menu); |
275 | 282 | ||
276 | if (key < 256 && isalpha(key)) | 283 | if (key < 256 && isalpha(key)) |
@@ -280,14 +287,16 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, | |||
280 | i = max_choice; | 287 | i = max_choice; |
281 | else { | 288 | else { |
282 | for (i = choice + 1; i < max_choice; i++) { | 289 | for (i = choice + 1; i < max_choice; i++) { |
283 | j = first_alpha(items[(scroll + i) * 2 + 1], "YyNnMmHh"); | 290 | item_set(scroll + i); |
284 | if (key == tolower(items[(scroll + i) * 2 + 1][j])) | 291 | j = first_alpha(item_str(), "YyNnMmHh"); |
292 | if (key == tolower(item_str()[j])) | ||
285 | break; | 293 | break; |
286 | } | 294 | } |
287 | if (i == max_choice) | 295 | if (i == max_choice) |
288 | for (i = 0; i < max_choice; i++) { | 296 | for (i = 0; i < max_choice; i++) { |
289 | j = first_alpha(items [(scroll + i) * 2 + 1], "YyNnMmHh"); | 297 | item_set(scroll + i); |
290 | if (key == tolower(items[(scroll + i) * 2 + 1][j])) | 298 | j = first_alpha(item_str(), "YyNnMmHh"); |
299 | if (key == tolower(item_str()[j])) | ||
291 | break; | 300 | break; |
292 | } | 301 | } |
293 | } | 302 | } |
@@ -312,7 +321,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, | |||
312 | print_item(scroll+choice, choice, FALSE); | 321 | print_item(scroll+choice, choice, FALSE); |
313 | 322 | ||
314 | if ((choice > max_choice - 3) && | 323 | if ((choice > max_choice - 3) && |
315 | (scroll + max_choice < item_no)) { | 324 | (scroll + max_choice < item_count())) { |
316 | /* Scroll menu up */ | 325 | /* Scroll menu up */ |
317 | do_scroll(menu, &scroll, 1); | 326 | do_scroll(menu, &scroll, 1); |
318 | 327 | ||
@@ -335,7 +344,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, | |||
335 | 344 | ||
336 | } else if (key == KEY_NPAGE) { | 345 | } else if (key == KEY_NPAGE) { |
337 | for (i = 0; (i < max_choice); i++) { | 346 | for (i = 0; (i < max_choice); i++) { |
338 | if (scroll + max_choice < item_no) { | 347 | if (scroll + max_choice < item_count()) { |
339 | do_scroll(menu, &scroll, 1); | 348 | do_scroll(menu, &scroll, 1); |
340 | print_item(scroll+max_choice-1, | 349 | print_item(scroll+max_choice-1, |
341 | max_choice - 1, FALSE); | 350 | max_choice - 1, FALSE); |
@@ -349,7 +358,7 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, | |||
349 | 358 | ||
350 | print_item(scroll + choice, choice, TRUE); | 359 | print_item(scroll + choice, choice, TRUE); |
351 | 360 | ||
352 | print_arrows(dialog, item_no, scroll, | 361 | print_arrows(dialog, item_count(), scroll, |
353 | box_y, box_x + item_x + 1, menu_height); | 362 | box_y, box_x + item_x + 1, menu_height); |
354 | 363 | ||
355 | wnoutrefresh(dialog); | 364 | wnoutrefresh(dialog); |
@@ -375,12 +384,11 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, | |||
375 | case 'm': | 384 | case 'm': |
376 | case '/': | 385 | case '/': |
377 | /* save scroll info */ | 386 | /* save scroll info */ |
378 | if ((f = fopen("lxdialog.scrltmp", "w")) != NULL) { | 387 | *s_scroll = scroll; |
379 | fprintf(f, "%d\n", scroll); | 388 | delwin(menu); |
380 | fclose(f); | ||
381 | } | ||
382 | delwin(dialog); | 389 | delwin(dialog); |
383 | fprintf(stderr, "%s\n", items[(scroll + choice) * 2]); | 390 | item_set(scroll + choice); |
391 | item_set_selected(1); | ||
384 | switch (key) { | 392 | switch (key) { |
385 | case 's': | 393 | case 's': |
386 | return 3; | 394 | return 3; |
@@ -400,27 +408,27 @@ int dialog_menu(const char *title, const char *prompt, int height, int width, | |||
400 | case '?': | 408 | case '?': |
401 | button = 2; | 409 | button = 2; |
402 | case '\n': | 410 | case '\n': |
411 | *s_scroll = scroll; | ||
412 | delwin(menu); | ||
403 | delwin(dialog); | 413 | delwin(dialog); |
404 | if (button == 2) | 414 | item_set(scroll + choice); |
405 | fprintf(stderr, "%s \"%s\"\n", | 415 | item_set_selected(1); |
406 | items[(scroll + choice) * 2], | ||
407 | items[(scroll + choice) * 2 + 1] + | ||
408 | first_alpha(items [(scroll + choice) * 2 + 1], "")); | ||
409 | else | ||
410 | fprintf(stderr, "%s\n", | ||
411 | items[(scroll + choice) * 2]); | ||
412 | |||
413 | remove("lxdialog.scrltmp"); | ||
414 | return button; | 416 | return button; |
415 | case 'e': | 417 | case 'e': |
416 | case 'x': | 418 | case 'x': |
417 | key = ESC; | 419 | key = KEY_ESC; |
418 | case ESC: | 420 | break; |
421 | case KEY_ESC: | ||
422 | key = on_key_esc(menu); | ||
419 | break; | 423 | break; |
424 | case KEY_RESIZE: | ||
425 | on_key_resize(); | ||
426 | delwin(menu); | ||
427 | delwin(dialog); | ||
428 | goto do_resize; | ||
420 | } | 429 | } |
421 | } | 430 | } |
422 | 431 | delwin(menu); | |
423 | delwin(dialog); | 432 | delwin(dialog); |
424 | remove("lxdialog.scrltmp"); | 433 | return key; /* ESC pressed */ |
425 | return -1; /* ESC pressed */ | ||
426 | } | 434 | } |
diff --git a/scripts/kconfig/lxdialog/msgbox.c b/scripts/kconfig/lxdialog/msgbox.c deleted file mode 100644 index 7323f5471f69..000000000000 --- a/scripts/kconfig/lxdialog/msgbox.c +++ /dev/null | |||
@@ -1,71 +0,0 @@ | |||
1 | /* | ||
2 | * msgbox.c -- implements the message box and info box | ||
3 | * | ||
4 | * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) | ||
5 | * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com) | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version 2 | ||
10 | * of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | ||
21 | |||
22 | #include "dialog.h" | ||
23 | |||
24 | /* | ||
25 | * Display a message box. Program will pause and display an "OK" button | ||
26 | * if the parameter 'pause' is non-zero. | ||
27 | */ | ||
28 | int dialog_msgbox(const char *title, const char *prompt, int height, int width, | ||
29 | int pause) | ||
30 | { | ||
31 | int i, x, y, key = 0; | ||
32 | WINDOW *dialog; | ||
33 | |||
34 | /* center dialog box on screen */ | ||
35 | x = (COLS - width) / 2; | ||
36 | y = (LINES - height) / 2; | ||
37 | |||
38 | draw_shadow(stdscr, y, x, height, width); | ||
39 | |||
40 | dialog = newwin(height, width, y, x); | ||
41 | keypad(dialog, TRUE); | ||
42 | |||
43 | draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); | ||
44 | |||
45 | print_title(dialog, title, width); | ||
46 | |||
47 | wattrset(dialog, dialog_attr); | ||
48 | print_autowrap(dialog, prompt, width - 2, 1, 2); | ||
49 | |||
50 | if (pause) { | ||
51 | wattrset(dialog, border_attr); | ||
52 | mvwaddch(dialog, height - 3, 0, ACS_LTEE); | ||
53 | for (i = 0; i < width - 2; i++) | ||
54 | waddch(dialog, ACS_HLINE); | ||
55 | wattrset(dialog, dialog_attr); | ||
56 | waddch(dialog, ACS_RTEE); | ||
57 | |||
58 | print_button(dialog, " Ok ", height - 2, width / 2 - 4, TRUE); | ||
59 | |||
60 | wrefresh(dialog); | ||
61 | while (key != ESC && key != '\n' && key != ' ' && | ||
62 | key != 'O' && key != 'o' && key != 'X' && key != 'x') | ||
63 | key = wgetch(dialog); | ||
64 | } else { | ||
65 | key = '\n'; | ||
66 | wrefresh(dialog); | ||
67 | } | ||
68 | |||
69 | delwin(dialog); | ||
70 | return key == ESC ? -1 : 0; | ||
71 | } | ||
diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c index 77848bb8e07f..fabfc1ad789d 100644 --- a/scripts/kconfig/lxdialog/textbox.c +++ b/scripts/kconfig/lxdialog/textbox.c | |||
@@ -25,56 +25,62 @@ static void back_lines(int n); | |||
25 | static void print_page(WINDOW * win, int height, int width); | 25 | static void print_page(WINDOW * win, int height, int width); |
26 | static void print_line(WINDOW * win, int row, int width); | 26 | static void print_line(WINDOW * win, int row, int width); |
27 | static char *get_line(void); | 27 | static char *get_line(void); |
28 | static void print_position(WINDOW * win, int height, int width); | 28 | static void print_position(WINDOW * win); |
29 | |||
30 | static int hscroll; | ||
31 | static int begin_reached, end_reached, page_length; | ||
32 | static const char *buf; | ||
33 | static const char *page; | ||
34 | |||
35 | /* | ||
36 | * refresh window content | ||
37 | */ | ||
38 | static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw, | ||
39 | int cur_y, int cur_x) | ||
40 | { | ||
41 | print_page(box, boxh, boxw); | ||
42 | print_position(dialog); | ||
43 | wmove(dialog, cur_y, cur_x); /* Restore cursor position */ | ||
44 | wrefresh(dialog); | ||
45 | } | ||
29 | 46 | ||
30 | static int hscroll, fd, file_size, bytes_read; | ||
31 | static int begin_reached = 1, end_reached, page_length; | ||
32 | static char *buf, *page; | ||
33 | 47 | ||
34 | /* | 48 | /* |
35 | * Display text from a file in a dialog box. | 49 | * Display text from a file in a dialog box. |
36 | */ | 50 | */ |
37 | int dialog_textbox(const char *title, const char *file, int height, int width) | 51 | int dialog_textbox(const char *title, const char *tbuf, |
52 | int initial_height, int initial_width) | ||
38 | { | 53 | { |
39 | int i, x, y, cur_x, cur_y, fpos, key = 0; | 54 | int i, x, y, cur_x, cur_y, key = 0; |
55 | int height, width, boxh, boxw; | ||
40 | int passed_end; | 56 | int passed_end; |
41 | char search_term[MAX_LEN + 1]; | 57 | WINDOW *dialog, *box; |
42 | WINDOW *dialog, *text; | ||
43 | |||
44 | search_term[0] = '\0'; /* no search term entered yet */ | ||
45 | 58 | ||
46 | /* Open input file for reading */ | 59 | begin_reached = 1; |
47 | if ((fd = open(file, O_RDONLY)) == -1) { | 60 | end_reached = 0; |
48 | endwin(); | 61 | page_length = 0; |
49 | fprintf(stderr, "\nCan't open input file in dialog_textbox().\n"); | 62 | hscroll = 0; |
50 | exit(-1); | 63 | buf = tbuf; |
51 | } | 64 | page = buf; /* page is pointer to start of page to be displayed */ |
52 | /* Get file size. Actually, 'file_size' is the real file size - 1, | 65 | |
53 | since it's only the last byte offset from the beginning */ | 66 | do_resize: |
54 | if ((file_size = lseek(fd, 0, SEEK_END)) == -1) { | 67 | getmaxyx(stdscr, height, width); |
55 | endwin(); | 68 | if (height < 8 || width < 8) |
56 | fprintf(stderr, "\nError getting file size in dialog_textbox().\n"); | 69 | return -ERRDISPLAYTOOSMALL; |
57 | exit(-1); | 70 | if (initial_height != 0) |
58 | } | 71 | height = initial_height; |
59 | /* Restore file pointer to beginning of file after getting file size */ | 72 | else |
60 | if (lseek(fd, 0, SEEK_SET) == -1) { | 73 | if (height > 4) |
61 | endwin(); | 74 | height -= 4; |
62 | fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n"); | 75 | else |
63 | exit(-1); | 76 | height = 0; |
64 | } | 77 | if (initial_width != 0) |
65 | /* Allocate space for read buffer */ | 78 | width = initial_width; |
66 | if ((buf = malloc(BUF_SIZE + 1)) == NULL) { | 79 | else |
67 | endwin(); | 80 | if (width > 5) |
68 | fprintf(stderr, "\nCan't allocate memory in dialog_textbox().\n"); | 81 | width -= 5; |
69 | exit(-1); | 82 | else |
70 | } | 83 | width = 0; |
71 | if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) { | ||
72 | endwin(); | ||
73 | fprintf(stderr, "\nError reading file in dialog_textbox().\n"); | ||
74 | exit(-1); | ||
75 | } | ||
76 | buf[bytes_read] = '\0'; /* mark end of valid data */ | ||
77 | page = buf; /* page is pointer to start of page to be displayed */ | ||
78 | 84 | ||
79 | /* center dialog box on screen */ | 85 | /* center dialog box on screen */ |
80 | x = (COLS - width) / 2; | 86 | x = (COLS - width) / 2; |
@@ -85,22 +91,25 @@ int dialog_textbox(const char *title, const char *file, int height, int width) | |||
85 | dialog = newwin(height, width, y, x); | 91 | dialog = newwin(height, width, y, x); |
86 | keypad(dialog, TRUE); | 92 | keypad(dialog, TRUE); |
87 | 93 | ||
88 | /* Create window for text region, used for scrolling text */ | 94 | /* Create window for box region, used for scrolling text */ |
89 | text = subwin(dialog, height - 4, width - 2, y + 1, x + 1); | 95 | boxh = height - 4; |
90 | wattrset(text, dialog_attr); | 96 | boxw = width - 2; |
91 | wbkgdset(text, dialog_attr & A_COLOR); | 97 | box = subwin(dialog, boxh, boxw, y + 1, x + 1); |
98 | wattrset(box, dlg.dialog.atr); | ||
99 | wbkgdset(box, dlg.dialog.atr & A_COLOR); | ||
92 | 100 | ||
93 | keypad(text, TRUE); | 101 | keypad(box, TRUE); |
94 | 102 | ||
95 | /* register the new window, along with its borders */ | 103 | /* register the new window, along with its borders */ |
96 | draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); | 104 | draw_box(dialog, 0, 0, height, width, |
105 | dlg.dialog.atr, dlg.border.atr); | ||
97 | 106 | ||
98 | wattrset(dialog, border_attr); | 107 | wattrset(dialog, dlg.border.atr); |
99 | mvwaddch(dialog, height - 3, 0, ACS_LTEE); | 108 | mvwaddch(dialog, height - 3, 0, ACS_LTEE); |
100 | for (i = 0; i < width - 2; i++) | 109 | for (i = 0; i < width - 2; i++) |
101 | waddch(dialog, ACS_HLINE); | 110 | waddch(dialog, ACS_HLINE); |
102 | wattrset(dialog, dialog_attr); | 111 | wattrset(dialog, dlg.dialog.atr); |
103 | wbkgdset(dialog, dialog_attr & A_COLOR); | 112 | wbkgdset(dialog, dlg.dialog.atr & A_COLOR); |
104 | waddch(dialog, ACS_RTEE); | 113 | waddch(dialog, ACS_RTEE); |
105 | 114 | ||
106 | print_title(dialog, title, width); | 115 | print_title(dialog, title, width); |
@@ -110,85 +119,37 @@ int dialog_textbox(const char *title, const char *file, int height, int width) | |||
110 | getyx(dialog, cur_y, cur_x); /* Save cursor position */ | 119 | getyx(dialog, cur_y, cur_x); /* Save cursor position */ |
111 | 120 | ||
112 | /* Print first page of text */ | 121 | /* Print first page of text */ |
113 | attr_clear(text, height - 4, width - 2, dialog_attr); | 122 | attr_clear(box, boxh, boxw, dlg.dialog.atr); |
114 | print_page(text, height - 4, width - 2); | 123 | refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x); |
115 | print_position(dialog, height, width); | ||
116 | wmove(dialog, cur_y, cur_x); /* Restore cursor position */ | ||
117 | wrefresh(dialog); | ||
118 | 124 | ||
119 | while ((key != ESC) && (key != '\n')) { | 125 | while ((key != KEY_ESC) && (key != '\n')) { |
120 | key = wgetch(dialog); | 126 | key = wgetch(dialog); |
121 | switch (key) { | 127 | switch (key) { |
122 | case 'E': /* Exit */ | 128 | case 'E': /* Exit */ |
123 | case 'e': | 129 | case 'e': |
124 | case 'X': | 130 | case 'X': |
125 | case 'x': | 131 | case 'x': |
132 | delwin(box); | ||
126 | delwin(dialog); | 133 | delwin(dialog); |
127 | free(buf); | ||
128 | close(fd); | ||
129 | return 0; | 134 | return 0; |
130 | case 'g': /* First page */ | 135 | case 'g': /* First page */ |
131 | case KEY_HOME: | 136 | case KEY_HOME: |
132 | if (!begin_reached) { | 137 | if (!begin_reached) { |
133 | begin_reached = 1; | 138 | begin_reached = 1; |
134 | /* First page not in buffer? */ | ||
135 | if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { | ||
136 | endwin(); | ||
137 | fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n"); | ||
138 | exit(-1); | ||
139 | } | ||
140 | if (fpos > bytes_read) { /* Yes, we have to read it in */ | ||
141 | if (lseek(fd, 0, SEEK_SET) == -1) { | ||
142 | endwin(); | ||
143 | fprintf(stderr, "\nError moving file pointer in " | ||
144 | "dialog_textbox().\n"); | ||
145 | exit(-1); | ||
146 | } | ||
147 | if ((bytes_read = | ||
148 | read(fd, buf, BUF_SIZE)) == -1) { | ||
149 | endwin(); | ||
150 | fprintf(stderr, "\nError reading file in dialog_textbox().\n"); | ||
151 | exit(-1); | ||
152 | } | ||
153 | buf[bytes_read] = '\0'; | ||
154 | } | ||
155 | page = buf; | 139 | page = buf; |
156 | print_page(text, height - 4, width - 2); | 140 | refresh_text_box(dialog, box, boxh, boxw, |
157 | print_position(dialog, height, width); | 141 | cur_y, cur_x); |
158 | wmove(dialog, cur_y, cur_x); /* Restore cursor position */ | ||
159 | wrefresh(dialog); | ||
160 | } | 142 | } |
161 | break; | 143 | break; |
162 | case 'G': /* Last page */ | 144 | case 'G': /* Last page */ |
163 | case KEY_END: | 145 | case KEY_END: |
164 | 146 | ||
165 | end_reached = 1; | 147 | end_reached = 1; |
166 | /* Last page not in buffer? */ | 148 | /* point to last char in buf */ |
167 | if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { | 149 | page = buf + strlen(buf); |
168 | endwin(); | 150 | back_lines(boxh); |
169 | fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n"); | 151 | refresh_text_box(dialog, box, boxh, boxw, |
170 | exit(-1); | 152 | cur_y, cur_x); |
171 | } | ||
172 | if (fpos < file_size) { /* Yes, we have to read it in */ | ||
173 | if (lseek(fd, -BUF_SIZE, SEEK_END) == -1) { | ||
174 | endwin(); | ||
175 | fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n"); | ||
176 | exit(-1); | ||
177 | } | ||
178 | if ((bytes_read = | ||
179 | read(fd, buf, BUF_SIZE)) == -1) { | ||
180 | endwin(); | ||
181 | fprintf(stderr, "\nError reading file in dialog_textbox().\n"); | ||
182 | exit(-1); | ||
183 | } | ||
184 | buf[bytes_read] = '\0'; | ||
185 | } | ||
186 | page = buf + bytes_read; | ||
187 | back_lines(height - 4); | ||
188 | print_page(text, height - 4, width - 2); | ||
189 | print_position(dialog, height, width); | ||
190 | wmove(dialog, cur_y, cur_x); /* Restore cursor position */ | ||
191 | wrefresh(dialog); | ||
192 | break; | 153 | break; |
193 | case 'K': /* Previous line */ | 154 | case 'K': /* Previous line */ |
194 | case 'k': | 155 | case 'k': |
@@ -196,21 +157,23 @@ int dialog_textbox(const char *title, const char *file, int height, int width) | |||
196 | if (!begin_reached) { | 157 | if (!begin_reached) { |
197 | back_lines(page_length + 1); | 158 | back_lines(page_length + 1); |
198 | 159 | ||
199 | /* We don't call print_page() here but use scrolling to ensure | 160 | /* We don't call print_page() here but use |
200 | faster screen update. However, 'end_reached' and | 161 | * scrolling to ensure faster screen update. |
201 | 'page_length' should still be updated, and 'page' should | 162 | * However, 'end_reached' and 'page_length' |
202 | point to start of next page. This is done by calling | 163 | * should still be updated, and 'page' should |
203 | get_line() in the following 'for' loop. */ | 164 | * point to start of next page. This is done |
204 | scrollok(text, TRUE); | 165 | * by calling get_line() in the following |
205 | wscrl(text, -1); /* Scroll text region down one line */ | 166 | * 'for' loop. */ |
206 | scrollok(text, FALSE); | 167 | scrollok(box, TRUE); |
168 | wscrl(box, -1); /* Scroll box region down one line */ | ||
169 | scrollok(box, FALSE); | ||
207 | page_length = 0; | 170 | page_length = 0; |
208 | passed_end = 0; | 171 | passed_end = 0; |
209 | for (i = 0; i < height - 4; i++) { | 172 | for (i = 0; i < boxh; i++) { |
210 | if (!i) { | 173 | if (!i) { |
211 | /* print first line of page */ | 174 | /* print first line of page */ |
212 | print_line(text, 0, width - 2); | 175 | print_line(box, 0, boxw); |
213 | wnoutrefresh(text); | 176 | wnoutrefresh(box); |
214 | } else | 177 | } else |
215 | /* Called to update 'end_reached' and 'page' */ | 178 | /* Called to update 'end_reached' and 'page' */ |
216 | get_line(); | 179 | get_line(); |
@@ -220,7 +183,7 @@ int dialog_textbox(const char *title, const char *file, int height, int width) | |||
220 | passed_end = 1; | 183 | passed_end = 1; |
221 | } | 184 | } |
222 | 185 | ||
223 | print_position(dialog, height, width); | 186 | print_position(dialog); |
224 | wmove(dialog, cur_y, cur_x); /* Restore cursor position */ | 187 | wmove(dialog, cur_y, cur_x); /* Restore cursor position */ |
225 | wrefresh(dialog); | 188 | wrefresh(dialog); |
226 | } | 189 | } |
@@ -230,23 +193,21 @@ int dialog_textbox(const char *title, const char *file, int height, int width) | |||
230 | case KEY_PPAGE: | 193 | case KEY_PPAGE: |
231 | if (begin_reached) | 194 | if (begin_reached) |
232 | break; | 195 | break; |
233 | back_lines(page_length + height - 4); | 196 | back_lines(page_length + boxh); |
234 | print_page(text, height - 4, width - 2); | 197 | refresh_text_box(dialog, box, boxh, boxw, |
235 | print_position(dialog, height, width); | 198 | cur_y, cur_x); |
236 | wmove(dialog, cur_y, cur_x); | ||
237 | wrefresh(dialog); | ||
238 | break; | 199 | break; |
239 | case 'J': /* Next line */ | 200 | case 'J': /* Next line */ |
240 | case 'j': | 201 | case 'j': |
241 | case KEY_DOWN: | 202 | case KEY_DOWN: |
242 | if (!end_reached) { | 203 | if (!end_reached) { |
243 | begin_reached = 0; | 204 | begin_reached = 0; |
244 | scrollok(text, TRUE); | 205 | scrollok(box, TRUE); |
245 | scroll(text); /* Scroll text region up one line */ | 206 | scroll(box); /* Scroll box region up one line */ |
246 | scrollok(text, FALSE); | 207 | scrollok(box, FALSE); |
247 | print_line(text, height - 5, width - 2); | 208 | print_line(box, boxh - 1, boxw); |
248 | wnoutrefresh(text); | 209 | wnoutrefresh(box); |
249 | print_position(dialog, height, width); | 210 | print_position(dialog); |
250 | wmove(dialog, cur_y, cur_x); /* Restore cursor position */ | 211 | wmove(dialog, cur_y, cur_x); /* Restore cursor position */ |
251 | wrefresh(dialog); | 212 | wrefresh(dialog); |
252 | } | 213 | } |
@@ -257,10 +218,8 @@ int dialog_textbox(const char *title, const char *file, int height, int width) | |||
257 | break; | 218 | break; |
258 | 219 | ||
259 | begin_reached = 0; | 220 | begin_reached = 0; |
260 | print_page(text, height - 4, width - 2); | 221 | refresh_text_box(dialog, box, boxh, boxw, |
261 | print_position(dialog, height, width); | 222 | cur_y, cur_x); |
262 | wmove(dialog, cur_y, cur_x); | ||
263 | wrefresh(dialog); | ||
264 | break; | 223 | break; |
265 | case '0': /* Beginning of line */ | 224 | case '0': /* Beginning of line */ |
266 | case 'H': /* Scroll left */ | 225 | case 'H': /* Scroll left */ |
@@ -275,9 +234,8 @@ int dialog_textbox(const char *title, const char *file, int height, int width) | |||
275 | hscroll--; | 234 | hscroll--; |
276 | /* Reprint current page to scroll horizontally */ | 235 | /* Reprint current page to scroll horizontally */ |
277 | back_lines(page_length); | 236 | back_lines(page_length); |
278 | print_page(text, height - 4, width - 2); | 237 | refresh_text_box(dialog, box, boxh, boxw, |
279 | wmove(dialog, cur_y, cur_x); | 238 | cur_y, cur_x); |
280 | wrefresh(dialog); | ||
281 | break; | 239 | break; |
282 | case 'L': /* Scroll right */ | 240 | case 'L': /* Scroll right */ |
283 | case 'l': | 241 | case 'l': |
@@ -287,131 +245,56 @@ int dialog_textbox(const char *title, const char *file, int height, int width) | |||
287 | hscroll++; | 245 | hscroll++; |
288 | /* Reprint current page to scroll horizontally */ | 246 | /* Reprint current page to scroll horizontally */ |
289 | back_lines(page_length); | 247 | back_lines(page_length); |
290 | print_page(text, height - 4, width - 2); | 248 | refresh_text_box(dialog, box, boxh, boxw, |
291 | wmove(dialog, cur_y, cur_x); | 249 | cur_y, cur_x); |
292 | wrefresh(dialog); | ||
293 | break; | 250 | break; |
294 | case ESC: | 251 | case KEY_ESC: |
252 | key = on_key_esc(dialog); | ||
295 | break; | 253 | break; |
254 | case KEY_RESIZE: | ||
255 | back_lines(height); | ||
256 | delwin(box); | ||
257 | delwin(dialog); | ||
258 | on_key_resize(); | ||
259 | goto do_resize; | ||
296 | } | 260 | } |
297 | } | 261 | } |
298 | 262 | delwin(box); | |
299 | delwin(dialog); | 263 | delwin(dialog); |
300 | free(buf); | 264 | return key; /* ESC pressed */ |
301 | close(fd); | ||
302 | return -1; /* ESC pressed */ | ||
303 | } | 265 | } |
304 | 266 | ||
305 | /* | 267 | /* |
306 | * Go back 'n' lines in text file. Called by dialog_textbox(). | 268 | * Go back 'n' lines in text. Called by dialog_textbox(). |
307 | * 'page' will be updated to point to the desired line in 'buf'. | 269 | * 'page' will be updated to point to the desired line in 'buf'. |
308 | */ | 270 | */ |
309 | static void back_lines(int n) | 271 | static void back_lines(int n) |
310 | { | 272 | { |
311 | int i, fpos; | 273 | int i; |
312 | 274 | ||
313 | begin_reached = 0; | 275 | begin_reached = 0; |
314 | /* We have to distinguish between end_reached and !end_reached | 276 | /* Go back 'n' lines */ |
315 | since at end of file, the line is not ended by a '\n'. | 277 | for (i = 0; i < n; i++) { |
316 | The code inside 'if' basically does a '--page' to move one | 278 | if (*page == '\0') { |
317 | character backward so as to skip '\n' of the previous line */ | 279 | if (end_reached) { |
318 | if (!end_reached) { | 280 | end_reached = 0; |
319 | /* Either beginning of buffer or beginning of file reached? */ | 281 | continue; |
320 | if (page == buf) { | ||
321 | if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { | ||
322 | endwin(); | ||
323 | fprintf(stderr, "\nError moving file pointer in " | ||
324 | "back_lines().\n"); | ||
325 | exit(-1); | ||
326 | } | ||
327 | if (fpos > bytes_read) { /* Not beginning of file yet */ | ||
328 | /* We've reached beginning of buffer, but not beginning of | ||
329 | file yet, so read previous part of file into buffer. | ||
330 | Note that we only move backward for BUF_SIZE/2 bytes, | ||
331 | but not BUF_SIZE bytes to avoid re-reading again in | ||
332 | print_page() later */ | ||
333 | /* Really possible to move backward BUF_SIZE/2 bytes? */ | ||
334 | if (fpos < BUF_SIZE / 2 + bytes_read) { | ||
335 | /* No, move less then */ | ||
336 | if (lseek(fd, 0, SEEK_SET) == -1) { | ||
337 | endwin(); | ||
338 | fprintf(stderr, "\nError moving file pointer in " | ||
339 | "back_lines().\n"); | ||
340 | exit(-1); | ||
341 | } | ||
342 | page = buf + fpos - bytes_read; | ||
343 | } else { /* Move backward BUF_SIZE/2 bytes */ | ||
344 | if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) == -1) { | ||
345 | endwin(); | ||
346 | fprintf(stderr, "\nError moving file pointer " | ||
347 | "in back_lines().\n"); | ||
348 | exit(-1); | ||
349 | } | ||
350 | page = buf + BUF_SIZE / 2; | ||
351 | } | ||
352 | if ((bytes_read = | ||
353 | read(fd, buf, BUF_SIZE)) == -1) { | ||
354 | endwin(); | ||
355 | fprintf(stderr, "\nError reading file in back_lines().\n"); | ||
356 | exit(-1); | ||
357 | } | ||
358 | buf[bytes_read] = '\0'; | ||
359 | } else { /* Beginning of file reached */ | ||
360 | begin_reached = 1; | ||
361 | return; | ||
362 | } | 282 | } |
363 | } | 283 | } |
364 | if (*(--page) != '\n') { /* '--page' here */ | 284 | if (page == buf) { |
365 | /* Something's wrong... */ | 285 | begin_reached = 1; |
366 | endwin(); | 286 | return; |
367 | fprintf(stderr, "\nInternal error in back_lines().\n"); | ||
368 | exit(-1); | ||
369 | } | 287 | } |
370 | } | 288 | page--; |
371 | /* Go back 'n' lines */ | ||
372 | for (i = 0; i < n; i++) | ||
373 | do { | 289 | do { |
374 | if (page == buf) { | 290 | if (page == buf) { |
375 | if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { | 291 | begin_reached = 1; |
376 | endwin(); | 292 | return; |
377 | fprintf(stderr, "\nError moving file pointer in back_lines().\n"); | ||
378 | exit(-1); | ||
379 | } | ||
380 | if (fpos > bytes_read) { | ||
381 | /* Really possible to move backward BUF_SIZE/2 bytes? */ | ||
382 | if (fpos < BUF_SIZE / 2 + bytes_read) { | ||
383 | /* No, move less then */ | ||
384 | if (lseek(fd, 0, SEEK_SET) == -1) { | ||
385 | endwin(); | ||
386 | fprintf(stderr, "\nError moving file pointer " | ||
387 | "in back_lines().\n"); | ||
388 | exit(-1); | ||
389 | } | ||
390 | page = buf + fpos - bytes_read; | ||
391 | } else { /* Move backward BUF_SIZE/2 bytes */ | ||
392 | if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) == -1) { | ||
393 | endwin(); | ||
394 | fprintf(stderr, "\nError moving file pointer" | ||
395 | " in back_lines().\n"); | ||
396 | exit(-1); | ||
397 | } | ||
398 | page = buf + BUF_SIZE / 2; | ||
399 | } | ||
400 | if ((bytes_read = | ||
401 | read(fd, buf, BUF_SIZE)) == -1) { | ||
402 | endwin(); | ||
403 | fprintf(stderr, "\nError reading file in " | ||
404 | "back_lines().\n"); | ||
405 | exit(-1); | ||
406 | } | ||
407 | buf[bytes_read] = '\0'; | ||
408 | } else { /* Beginning of file reached */ | ||
409 | begin_reached = 1; | ||
410 | return; | ||
411 | } | ||
412 | } | 293 | } |
413 | } while (*(--page) != '\n'); | 294 | page--; |
414 | page++; | 295 | } while (*page != '\n'); |
296 | page++; | ||
297 | } | ||
415 | } | 298 | } |
416 | 299 | ||
417 | /* | 300 | /* |
@@ -466,33 +349,14 @@ static void print_line(WINDOW * win, int row, int width) | |||
466 | */ | 349 | */ |
467 | static char *get_line(void) | 350 | static char *get_line(void) |
468 | { | 351 | { |
469 | int i = 0, fpos; | 352 | int i = 0; |
470 | static char line[MAX_LEN + 1]; | 353 | static char line[MAX_LEN + 1]; |
471 | 354 | ||
472 | end_reached = 0; | 355 | end_reached = 0; |
473 | while (*page != '\n') { | 356 | while (*page != '\n') { |
474 | if (*page == '\0') { | 357 | if (*page == '\0') { |
475 | /* Either end of file or end of buffer reached */ | 358 | if (!end_reached) { |
476 | if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { | 359 | end_reached = 1; |
477 | endwin(); | ||
478 | fprintf(stderr, "\nError moving file pointer in " | ||
479 | "get_line().\n"); | ||
480 | exit(-1); | ||
481 | } | ||
482 | if (fpos < file_size) { /* Not end of file yet */ | ||
483 | /* We've reached end of buffer, but not end of file yet, | ||
484 | so read next part of file into buffer */ | ||
485 | if ((bytes_read = | ||
486 | read(fd, buf, BUF_SIZE)) == -1) { | ||
487 | endwin(); | ||
488 | fprintf(stderr, "\nError reading file in get_line().\n"); | ||
489 | exit(-1); | ||
490 | } | ||
491 | buf[bytes_read] = '\0'; | ||
492 | page = buf; | ||
493 | } else { | ||
494 | if (!end_reached) | ||
495 | end_reached = 1; | ||
496 | break; | 360 | break; |
497 | } | 361 | } |
498 | } else if (i < MAX_LEN) | 362 | } else if (i < MAX_LEN) |
@@ -515,19 +379,13 @@ static char *get_line(void) | |||
515 | /* | 379 | /* |
516 | * Print current position | 380 | * Print current position |
517 | */ | 381 | */ |
518 | static void print_position(WINDOW * win, int height, int width) | 382 | static void print_position(WINDOW * win) |
519 | { | 383 | { |
520 | int fpos, percent; | 384 | int percent; |
521 | 385 | ||
522 | if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { | 386 | wattrset(win, dlg.position_indicator.atr); |
523 | endwin(); | 387 | wbkgdset(win, dlg.position_indicator.atr & A_COLOR); |
524 | fprintf(stderr, "\nError moving file pointer in print_position().\n"); | 388 | percent = (page - buf) * 100 / strlen(buf); |
525 | exit(-1); | 389 | wmove(win, getmaxy(win) - 3, getmaxx(win) - 9); |
526 | } | ||
527 | wattrset(win, position_indicator_attr); | ||
528 | wbkgdset(win, position_indicator_attr & A_COLOR); | ||
529 | percent = !file_size ? | ||
530 | 100 : ((fpos - bytes_read + page - buf) * 100) / file_size; | ||
531 | wmove(win, height - 3, width - 9); | ||
532 | wprintw(win, "(%3d%%)", percent); | 390 | wprintw(win, "(%3d%%)", percent); |
533 | } | 391 | } |
diff --git a/scripts/kconfig/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c index f82cebb9ff06..ebc781b493d7 100644 --- a/scripts/kconfig/lxdialog/util.c +++ b/scripts/kconfig/lxdialog/util.c | |||
@@ -21,85 +21,217 @@ | |||
21 | 21 | ||
22 | #include "dialog.h" | 22 | #include "dialog.h" |
23 | 23 | ||
24 | /* use colors by default? */ | 24 | struct dialog_info dlg; |
25 | bool use_colors = 1; | ||
26 | 25 | ||
27 | const char *backtitle = NULL; | 26 | static void set_mono_theme(void) |
27 | { | ||
28 | dlg.screen.atr = A_NORMAL; | ||
29 | dlg.shadow.atr = A_NORMAL; | ||
30 | dlg.dialog.atr = A_NORMAL; | ||
31 | dlg.title.atr = A_BOLD; | ||
32 | dlg.border.atr = A_NORMAL; | ||
33 | dlg.button_active.atr = A_REVERSE; | ||
34 | dlg.button_inactive.atr = A_DIM; | ||
35 | dlg.button_key_active.atr = A_REVERSE; | ||
36 | dlg.button_key_inactive.atr = A_BOLD; | ||
37 | dlg.button_label_active.atr = A_REVERSE; | ||
38 | dlg.button_label_inactive.atr = A_NORMAL; | ||
39 | dlg.inputbox.atr = A_NORMAL; | ||
40 | dlg.inputbox_border.atr = A_NORMAL; | ||
41 | dlg.searchbox.atr = A_NORMAL; | ||
42 | dlg.searchbox_title.atr = A_BOLD; | ||
43 | dlg.searchbox_border.atr = A_NORMAL; | ||
44 | dlg.position_indicator.atr = A_BOLD; | ||
45 | dlg.menubox.atr = A_NORMAL; | ||
46 | dlg.menubox_border.atr = A_NORMAL; | ||
47 | dlg.item.atr = A_NORMAL; | ||
48 | dlg.item_selected.atr = A_REVERSE; | ||
49 | dlg.tag.atr = A_BOLD; | ||
50 | dlg.tag_selected.atr = A_REVERSE; | ||
51 | dlg.tag_key.atr = A_BOLD; | ||
52 | dlg.tag_key_selected.atr = A_REVERSE; | ||
53 | dlg.check.atr = A_BOLD; | ||
54 | dlg.check_selected.atr = A_REVERSE; | ||
55 | dlg.uarrow.atr = A_BOLD; | ||
56 | dlg.darrow.atr = A_BOLD; | ||
57 | } | ||
58 | |||
59 | #define DLG_COLOR(dialog, f, b, h) \ | ||
60 | do { \ | ||
61 | dlg.dialog.fg = (f); \ | ||
62 | dlg.dialog.bg = (b); \ | ||
63 | dlg.dialog.hl = (h); \ | ||
64 | } while (0) | ||
65 | |||
66 | static void set_classic_theme(void) | ||
67 | { | ||
68 | DLG_COLOR(screen, COLOR_CYAN, COLOR_BLUE, true); | ||
69 | DLG_COLOR(shadow, COLOR_BLACK, COLOR_BLACK, true); | ||
70 | DLG_COLOR(dialog, COLOR_BLACK, COLOR_WHITE, false); | ||
71 | DLG_COLOR(title, COLOR_YELLOW, COLOR_WHITE, true); | ||
72 | DLG_COLOR(border, COLOR_WHITE, COLOR_WHITE, true); | ||
73 | DLG_COLOR(button_active, COLOR_WHITE, COLOR_BLUE, true); | ||
74 | DLG_COLOR(button_inactive, COLOR_BLACK, COLOR_WHITE, false); | ||
75 | DLG_COLOR(button_key_active, COLOR_WHITE, COLOR_BLUE, true); | ||
76 | DLG_COLOR(button_key_inactive, COLOR_RED, COLOR_WHITE, false); | ||
77 | DLG_COLOR(button_label_active, COLOR_YELLOW, COLOR_BLUE, true); | ||
78 | DLG_COLOR(button_label_inactive, COLOR_BLACK, COLOR_WHITE, true); | ||
79 | DLG_COLOR(inputbox, COLOR_BLACK, COLOR_WHITE, false); | ||
80 | DLG_COLOR(inputbox_border, COLOR_BLACK, COLOR_WHITE, false); | ||
81 | DLG_COLOR(searchbox, COLOR_BLACK, COLOR_WHITE, false); | ||
82 | DLG_COLOR(searchbox_title, COLOR_YELLOW, COLOR_WHITE, true); | ||
83 | DLG_COLOR(searchbox_border, COLOR_WHITE, COLOR_WHITE, true); | ||
84 | DLG_COLOR(position_indicator, COLOR_YELLOW, COLOR_WHITE, true); | ||
85 | DLG_COLOR(menubox, COLOR_BLACK, COLOR_WHITE, false); | ||
86 | DLG_COLOR(menubox_border, COLOR_WHITE, COLOR_WHITE, true); | ||
87 | DLG_COLOR(item, COLOR_BLACK, COLOR_WHITE, false); | ||
88 | DLG_COLOR(item_selected, COLOR_WHITE, COLOR_BLUE, true); | ||
89 | DLG_COLOR(tag, COLOR_YELLOW, COLOR_WHITE, true); | ||
90 | DLG_COLOR(tag_selected, COLOR_YELLOW, COLOR_BLUE, true); | ||
91 | DLG_COLOR(tag_key, COLOR_YELLOW, COLOR_WHITE, true); | ||
92 | DLG_COLOR(tag_key_selected, COLOR_YELLOW, COLOR_BLUE, true); | ||
93 | DLG_COLOR(check, COLOR_BLACK, COLOR_WHITE, false); | ||
94 | DLG_COLOR(check_selected, COLOR_WHITE, COLOR_BLUE, true); | ||
95 | DLG_COLOR(uarrow, COLOR_GREEN, COLOR_WHITE, true); | ||
96 | DLG_COLOR(darrow, COLOR_GREEN, COLOR_WHITE, true); | ||
97 | } | ||
98 | |||
99 | static void set_blackbg_theme(void) | ||
100 | { | ||
101 | DLG_COLOR(screen, COLOR_RED, COLOR_BLACK, true); | ||
102 | DLG_COLOR(shadow, COLOR_BLACK, COLOR_BLACK, false); | ||
103 | DLG_COLOR(dialog, COLOR_WHITE, COLOR_BLACK, false); | ||
104 | DLG_COLOR(title, COLOR_RED, COLOR_BLACK, false); | ||
105 | DLG_COLOR(border, COLOR_BLACK, COLOR_BLACK, true); | ||
106 | |||
107 | DLG_COLOR(button_active, COLOR_YELLOW, COLOR_RED, false); | ||
108 | DLG_COLOR(button_inactive, COLOR_YELLOW, COLOR_BLACK, false); | ||
109 | DLG_COLOR(button_key_active, COLOR_YELLOW, COLOR_RED, true); | ||
110 | DLG_COLOR(button_key_inactive, COLOR_RED, COLOR_BLACK, false); | ||
111 | DLG_COLOR(button_label_active, COLOR_WHITE, COLOR_RED, false); | ||
112 | DLG_COLOR(button_label_inactive, COLOR_BLACK, COLOR_BLACK, true); | ||
113 | |||
114 | DLG_COLOR(inputbox, COLOR_YELLOW, COLOR_BLACK, false); | ||
115 | DLG_COLOR(inputbox_border, COLOR_YELLOW, COLOR_BLACK, false); | ||
116 | |||
117 | DLG_COLOR(searchbox, COLOR_YELLOW, COLOR_BLACK, false); | ||
118 | DLG_COLOR(searchbox_title, COLOR_YELLOW, COLOR_BLACK, true); | ||
119 | DLG_COLOR(searchbox_border, COLOR_BLACK, COLOR_BLACK, true); | ||
120 | |||
121 | DLG_COLOR(position_indicator, COLOR_RED, COLOR_BLACK, false); | ||
122 | |||
123 | DLG_COLOR(menubox, COLOR_YELLOW, COLOR_BLACK, false); | ||
124 | DLG_COLOR(menubox_border, COLOR_BLACK, COLOR_BLACK, true); | ||
125 | |||
126 | DLG_COLOR(item, COLOR_WHITE, COLOR_BLACK, false); | ||
127 | DLG_COLOR(item_selected, COLOR_WHITE, COLOR_RED, false); | ||
128 | |||
129 | DLG_COLOR(tag, COLOR_RED, COLOR_BLACK, false); | ||
130 | DLG_COLOR(tag_selected, COLOR_YELLOW, COLOR_RED, true); | ||
131 | DLG_COLOR(tag_key, COLOR_RED, COLOR_BLACK, false); | ||
132 | DLG_COLOR(tag_key_selected, COLOR_YELLOW, COLOR_RED, true); | ||
133 | |||
134 | DLG_COLOR(check, COLOR_YELLOW, COLOR_BLACK, false); | ||
135 | DLG_COLOR(check_selected, COLOR_YELLOW, COLOR_RED, true); | ||
136 | |||
137 | DLG_COLOR(uarrow, COLOR_RED, COLOR_BLACK, false); | ||
138 | DLG_COLOR(darrow, COLOR_RED, COLOR_BLACK, false); | ||
139 | } | ||
140 | |||
141 | static void set_bluetitle_theme(void) | ||
142 | { | ||
143 | set_classic_theme(); | ||
144 | DLG_COLOR(title, COLOR_BLUE, COLOR_WHITE, true); | ||
145 | DLG_COLOR(button_key_active, COLOR_YELLOW, COLOR_BLUE, true); | ||
146 | DLG_COLOR(button_label_active, COLOR_WHITE, COLOR_BLUE, true); | ||
147 | DLG_COLOR(searchbox_title, COLOR_BLUE, COLOR_WHITE, true); | ||
148 | DLG_COLOR(position_indicator, COLOR_BLUE, COLOR_WHITE, true); | ||
149 | DLG_COLOR(tag, COLOR_BLUE, COLOR_WHITE, true); | ||
150 | DLG_COLOR(tag_key, COLOR_BLUE, COLOR_WHITE, true); | ||
151 | |||
152 | } | ||
28 | 153 | ||
29 | /* | 154 | /* |
30 | * Attribute values, default is for mono display | 155 | * Select color theme |
31 | */ | 156 | */ |
32 | chtype attributes[] = { | 157 | static int set_theme(const char *theme) |
33 | A_NORMAL, /* screen_attr */ | 158 | { |
34 | A_NORMAL, /* shadow_attr */ | 159 | int use_color = 1; |
35 | A_NORMAL, /* dialog_attr */ | 160 | if (!theme) |
36 | A_BOLD, /* title_attr */ | 161 | set_bluetitle_theme(); |
37 | A_NORMAL, /* border_attr */ | 162 | else if (strcmp(theme, "classic") == 0) |
38 | A_REVERSE, /* button_active_attr */ | 163 | set_classic_theme(); |
39 | A_DIM, /* button_inactive_attr */ | 164 | else if (strcmp(theme, "bluetitle") == 0) |
40 | A_REVERSE, /* button_key_active_attr */ | 165 | set_bluetitle_theme(); |
41 | A_BOLD, /* button_key_inactive_attr */ | 166 | else if (strcmp(theme, "blackbg") == 0) |
42 | A_REVERSE, /* button_label_active_attr */ | 167 | set_blackbg_theme(); |
43 | A_NORMAL, /* button_label_inactive_attr */ | 168 | else if (strcmp(theme, "mono") == 0) |
44 | A_NORMAL, /* inputbox_attr */ | 169 | use_color = 0; |
45 | A_NORMAL, /* inputbox_border_attr */ | 170 | |
46 | A_NORMAL, /* searchbox_attr */ | 171 | return use_color; |
47 | A_BOLD, /* searchbox_title_attr */ | 172 | } |
48 | A_NORMAL, /* searchbox_border_attr */ | 173 | |
49 | A_BOLD, /* position_indicator_attr */ | 174 | static void init_one_color(struct dialog_color *color) |
50 | A_NORMAL, /* menubox_attr */ | 175 | { |
51 | A_NORMAL, /* menubox_border_attr */ | 176 | static int pair = 0; |
52 | A_NORMAL, /* item_attr */ | 177 | |
53 | A_REVERSE, /* item_selected_attr */ | 178 | pair++; |
54 | A_BOLD, /* tag_attr */ | 179 | init_pair(pair, color->fg, color->bg); |
55 | A_REVERSE, /* tag_selected_attr */ | 180 | if (color->hl) |
56 | A_BOLD, /* tag_key_attr */ | 181 | color->atr = A_BOLD | COLOR_PAIR(pair); |
57 | A_REVERSE, /* tag_key_selected_attr */ | 182 | else |
58 | A_BOLD, /* check_attr */ | 183 | color->atr = COLOR_PAIR(pair); |
59 | A_REVERSE, /* check_selected_attr */ | 184 | } |
60 | A_BOLD, /* uarrow_attr */ | 185 | |
61 | A_BOLD /* darrow_attr */ | 186 | static void init_dialog_colors(void) |
62 | }; | 187 | { |
63 | 188 | init_one_color(&dlg.screen); | |
64 | #include "colors.h" | 189 | init_one_color(&dlg.shadow); |
190 | init_one_color(&dlg.dialog); | ||
191 | init_one_color(&dlg.title); | ||
192 | init_one_color(&dlg.border); | ||
193 | init_one_color(&dlg.button_active); | ||
194 | init_one_color(&dlg.button_inactive); | ||
195 | init_one_color(&dlg.button_key_active); | ||
196 | init_one_color(&dlg.button_key_inactive); | ||
197 | init_one_color(&dlg.button_label_active); | ||
198 | init_one_color(&dlg.button_label_inactive); | ||
199 | init_one_color(&dlg.inputbox); | ||
200 | init_one_color(&dlg.inputbox_border); | ||
201 | init_one_color(&dlg.searchbox); | ||
202 | init_one_color(&dlg.searchbox_title); | ||
203 | init_one_color(&dlg.searchbox_border); | ||
204 | init_one_color(&dlg.position_indicator); | ||
205 | init_one_color(&dlg.menubox); | ||
206 | init_one_color(&dlg.menubox_border); | ||
207 | init_one_color(&dlg.item); | ||
208 | init_one_color(&dlg.item_selected); | ||
209 | init_one_color(&dlg.tag); | ||
210 | init_one_color(&dlg.tag_selected); | ||
211 | init_one_color(&dlg.tag_key); | ||
212 | init_one_color(&dlg.tag_key_selected); | ||
213 | init_one_color(&dlg.check); | ||
214 | init_one_color(&dlg.check_selected); | ||
215 | init_one_color(&dlg.uarrow); | ||
216 | init_one_color(&dlg.darrow); | ||
217 | } | ||
65 | 218 | ||
66 | /* | 219 | /* |
67 | * Table of color values | 220 | * Setup for color display |
68 | */ | 221 | */ |
69 | int color_table[][3] = { | 222 | static void color_setup(const char *theme) |
70 | {SCREEN_FG, SCREEN_BG, SCREEN_HL}, | 223 | { |
71 | {SHADOW_FG, SHADOW_BG, SHADOW_HL}, | 224 | if (set_theme(theme)) { |
72 | {DIALOG_FG, DIALOG_BG, DIALOG_HL}, | 225 | if (has_colors()) { /* Terminal supports color? */ |
73 | {TITLE_FG, TITLE_BG, TITLE_HL}, | 226 | start_color(); |
74 | {BORDER_FG, BORDER_BG, BORDER_HL}, | 227 | init_dialog_colors(); |
75 | {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL}, | 228 | } |
76 | {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL}, | 229 | } |
77 | {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL}, | 230 | else |
78 | {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, | 231 | { |
79 | BUTTON_KEY_INACTIVE_HL}, | 232 | set_mono_theme(); |
80 | {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, | 233 | } |
81 | BUTTON_LABEL_ACTIVE_HL}, | 234 | } |
82 | {BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG, | ||
83 | BUTTON_LABEL_INACTIVE_HL}, | ||
84 | {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL}, | ||
85 | {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL}, | ||
86 | {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL}, | ||
87 | {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL}, | ||
88 | {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL}, | ||
89 | {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL}, | ||
90 | {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL}, | ||
91 | {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL}, | ||
92 | {ITEM_FG, ITEM_BG, ITEM_HL}, | ||
93 | {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL}, | ||
94 | {TAG_FG, TAG_BG, TAG_HL}, | ||
95 | {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL}, | ||
96 | {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL}, | ||
97 | {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL}, | ||
98 | {CHECK_FG, CHECK_BG, CHECK_HL}, | ||
99 | {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL}, | ||
100 | {UARROW_FG, UARROW_BG, UARROW_HL}, | ||
101 | {DARROW_FG, DARROW_BG, DARROW_HL}, | ||
102 | }; /* color_table */ | ||
103 | 235 | ||
104 | /* | 236 | /* |
105 | * Set window to attribute 'attr' | 237 | * Set window to attribute 'attr' |
@@ -119,13 +251,13 @@ void attr_clear(WINDOW * win, int height, int width, chtype attr) | |||
119 | 251 | ||
120 | void dialog_clear(void) | 252 | void dialog_clear(void) |
121 | { | 253 | { |
122 | attr_clear(stdscr, LINES, COLS, screen_attr); | 254 | attr_clear(stdscr, LINES, COLS, dlg.screen.atr); |
123 | /* Display background title if it exists ... - SLH */ | 255 | /* Display background title if it exists ... - SLH */ |
124 | if (backtitle != NULL) { | 256 | if (dlg.backtitle != NULL) { |
125 | int i; | 257 | int i; |
126 | 258 | ||
127 | wattrset(stdscr, screen_attr); | 259 | wattrset(stdscr, dlg.screen.atr); |
128 | mvwaddstr(stdscr, 0, 1, (char *)backtitle); | 260 | mvwaddstr(stdscr, 0, 1, (char *)dlg.backtitle); |
129 | wmove(stdscr, 1, 1); | 261 | wmove(stdscr, 1, 1); |
130 | for (i = 1; i < COLS - 1; i++) | 262 | for (i = 1; i < COLS - 1; i++) |
131 | waddch(stdscr, ACS_HLINE); | 263 | waddch(stdscr, ACS_HLINE); |
@@ -136,40 +268,22 @@ void dialog_clear(void) | |||
136 | /* | 268 | /* |
137 | * Do some initialization for dialog | 269 | * Do some initialization for dialog |
138 | */ | 270 | */ |
139 | void init_dialog(void) | 271 | void init_dialog(const char *backtitle) |
272 | { | ||
273 | dlg.backtitle = backtitle; | ||
274 | color_setup(getenv("MENUCONFIG_COLOR")); | ||
275 | } | ||
276 | |||
277 | void reset_dialog(void) | ||
140 | { | 278 | { |
141 | initscr(); /* Init curses */ | 279 | initscr(); /* Init curses */ |
142 | keypad(stdscr, TRUE); | 280 | keypad(stdscr, TRUE); |
143 | cbreak(); | 281 | cbreak(); |
144 | noecho(); | 282 | noecho(); |
145 | |||
146 | if (use_colors) /* Set up colors */ | ||
147 | color_setup(); | ||
148 | |||
149 | dialog_clear(); | 283 | dialog_clear(); |
150 | } | 284 | } |
151 | 285 | ||
152 | /* | 286 | /* |
153 | * Setup for color display | ||
154 | */ | ||
155 | void color_setup(void) | ||
156 | { | ||
157 | int i; | ||
158 | |||
159 | if (has_colors()) { /* Terminal supports color? */ | ||
160 | start_color(); | ||
161 | |||
162 | /* Initialize color pairs */ | ||
163 | for (i = 0; i < ATTRIBUTE_COUNT; i++) | ||
164 | init_pair(i + 1, color_table[i][0], color_table[i][1]); | ||
165 | |||
166 | /* Setup color attributes */ | ||
167 | for (i = 0; i < ATTRIBUTE_COUNT; i++) | ||
168 | attributes[i] = C_ATTR(color_table[i][2], i + 1); | ||
169 | } | ||
170 | } | ||
171 | |||
172 | /* | ||
173 | * End using dialog functions. | 287 | * End using dialog functions. |
174 | */ | 288 | */ |
175 | void end_dialog(void) | 289 | void end_dialog(void) |
@@ -184,7 +298,7 @@ void print_title(WINDOW *dialog, const char *title, int width) | |||
184 | { | 298 | { |
185 | if (title) { | 299 | if (title) { |
186 | int tlen = MIN(width - 2, strlen(title)); | 300 | int tlen = MIN(width - 2, strlen(title)); |
187 | wattrset(dialog, title_attr); | 301 | wattrset(dialog, dlg.title.atr); |
188 | mvwaddch(dialog, 0, (width - tlen) / 2 - 1, ' '); | 302 | mvwaddch(dialog, 0, (width - tlen) / 2 - 1, ' '); |
189 | mvwaddnstr(dialog, 0, (width - tlen)/2, title, tlen); | 303 | mvwaddnstr(dialog, 0, (width - tlen)/2, title, tlen); |
190 | waddch(dialog, ' '); | 304 | waddch(dialog, ' '); |
@@ -264,21 +378,23 @@ void print_button(WINDOW * win, const char *label, int y, int x, int selected) | |||
264 | int i, temp; | 378 | int i, temp; |
265 | 379 | ||
266 | wmove(win, y, x); | 380 | wmove(win, y, x); |
267 | wattrset(win, selected ? button_active_attr : button_inactive_attr); | 381 | wattrset(win, selected ? dlg.button_active.atr |
382 | : dlg.button_inactive.atr); | ||
268 | waddstr(win, "<"); | 383 | waddstr(win, "<"); |
269 | temp = strspn(label, " "); | 384 | temp = strspn(label, " "); |
270 | label += temp; | 385 | label += temp; |
271 | wattrset(win, selected ? button_label_active_attr | 386 | wattrset(win, selected ? dlg.button_label_active.atr |
272 | : button_label_inactive_attr); | 387 | : dlg.button_label_inactive.atr); |
273 | for (i = 0; i < temp; i++) | 388 | for (i = 0; i < temp; i++) |
274 | waddch(win, ' '); | 389 | waddch(win, ' '); |
275 | wattrset(win, selected ? button_key_active_attr | 390 | wattrset(win, selected ? dlg.button_key_active.atr |
276 | : button_key_inactive_attr); | 391 | : dlg.button_key_inactive.atr); |
277 | waddch(win, label[0]); | 392 | waddch(win, label[0]); |
278 | wattrset(win, selected ? button_label_active_attr | 393 | wattrset(win, selected ? dlg.button_label_active.atr |
279 | : button_label_inactive_attr); | 394 | : dlg.button_label_inactive.atr); |
280 | waddstr(win, (char *)label + 1); | 395 | waddstr(win, (char *)label + 1); |
281 | wattrset(win, selected ? button_active_attr : button_inactive_attr); | 396 | wattrset(win, selected ? dlg.button_active.atr |
397 | : dlg.button_inactive.atr); | ||
282 | waddstr(win, ">"); | 398 | waddstr(win, ">"); |
283 | wmove(win, y, x + temp + 1); | 399 | wmove(win, y, x + temp + 1); |
284 | } | 400 | } |
@@ -326,7 +442,7 @@ void draw_shadow(WINDOW * win, int y, int x, int height, int width) | |||
326 | int i; | 442 | int i; |
327 | 443 | ||
328 | if (has_colors()) { /* Whether terminal supports color? */ | 444 | if (has_colors()) { /* Whether terminal supports color? */ |
329 | wattrset(win, shadow_attr); | 445 | wattrset(win, dlg.shadow.atr); |
330 | wmove(win, y + height, x + 2); | 446 | wmove(win, y + height, x + 2); |
331 | for (i = 0; i < width; i++) | 447 | for (i = 0; i < width; i++) |
332 | waddch(win, winch(win) & A_CHARTEXT); | 448 | waddch(win, winch(win) & A_CHARTEXT); |
@@ -360,3 +476,167 @@ int first_alpha(const char *string, const char *exempt) | |||
360 | 476 | ||
361 | return 0; | 477 | return 0; |
362 | } | 478 | } |
479 | |||
480 | /* | ||
481 | * ncurses uses ESC to detect escaped char sequences. This resutl in | ||
482 | * a small timeout before ESC is actually delivered to the application. | ||
483 | * lxdialog suggest <ESC> <ESC> which is correctly translated to two | ||
484 | * times esc. But then we need to ignore the second esc to avoid stepping | ||
485 | * out one menu too much. Filter away all escaped key sequences since | ||
486 | * keypad(FALSE) turn off ncurses support for escape sequences - and thats | ||
487 | * needed to make notimeout() do as expected. | ||
488 | */ | ||
489 | int on_key_esc(WINDOW *win) | ||
490 | { | ||
491 | int key; | ||
492 | int key2; | ||
493 | int key3; | ||
494 | |||
495 | nodelay(win, TRUE); | ||
496 | keypad(win, FALSE); | ||
497 | key = wgetch(win); | ||
498 | key2 = wgetch(win); | ||
499 | do { | ||
500 | key3 = wgetch(win); | ||
501 | } while (key3 != ERR); | ||
502 | nodelay(win, FALSE); | ||
503 | keypad(win, TRUE); | ||
504 | if (key == KEY_ESC && key2 == ERR) | ||
505 | return KEY_ESC; | ||
506 | else if (key != ERR && key != KEY_ESC && key2 == ERR) | ||
507 | ungetch(key); | ||
508 | |||
509 | return -1; | ||
510 | } | ||
511 | |||
512 | /* redraw screen in new size */ | ||
513 | int on_key_resize(void) | ||
514 | { | ||
515 | dialog_clear(); | ||
516 | return KEY_RESIZE; | ||
517 | } | ||
518 | |||
519 | struct dialog_list *item_cur; | ||
520 | struct dialog_list item_nil; | ||
521 | struct dialog_list *item_head; | ||
522 | |||
523 | void item_reset(void) | ||
524 | { | ||
525 | struct dialog_list *p, *next; | ||
526 | |||
527 | for (p = item_head; p; p = next) { | ||
528 | next = p->next; | ||
529 | free(p); | ||
530 | } | ||
531 | item_head = NULL; | ||
532 | item_cur = &item_nil; | ||
533 | } | ||
534 | |||
535 | void item_make(const char *fmt, ...) | ||
536 | { | ||
537 | va_list ap; | ||
538 | struct dialog_list *p = malloc(sizeof(*p)); | ||
539 | |||
540 | if (item_head) | ||
541 | item_cur->next = p; | ||
542 | else | ||
543 | item_head = p; | ||
544 | item_cur = p; | ||
545 | memset(p, 0, sizeof(*p)); | ||
546 | |||
547 | va_start(ap, fmt); | ||
548 | vsnprintf(item_cur->node.str, sizeof(item_cur->node.str), fmt, ap); | ||
549 | va_end(ap); | ||
550 | } | ||
551 | |||
552 | void item_add_str(const char *fmt, ...) | ||
553 | { | ||
554 | va_list ap; | ||
555 | size_t avail; | ||
556 | |||
557 | avail = sizeof(item_cur->node.str) - strlen(item_cur->node.str); | ||
558 | |||
559 | va_start(ap, fmt); | ||
560 | vsnprintf(item_cur->node.str + strlen(item_cur->node.str), | ||
561 | avail, fmt, ap); | ||
562 | item_cur->node.str[sizeof(item_cur->node.str) - 1] = '\0'; | ||
563 | va_end(ap); | ||
564 | } | ||
565 | |||
566 | void item_set_tag(char tag) | ||
567 | { | ||
568 | item_cur->node.tag = tag; | ||
569 | } | ||
570 | void item_set_data(void *ptr) | ||
571 | { | ||
572 | item_cur->node.data = ptr; | ||
573 | } | ||
574 | |||
575 | void item_set_selected(int val) | ||
576 | { | ||
577 | item_cur->node.selected = val; | ||
578 | } | ||
579 | |||
580 | int item_activate_selected(void) | ||
581 | { | ||
582 | item_foreach() | ||
583 | if (item_is_selected()) | ||
584 | return 1; | ||
585 | return 0; | ||
586 | } | ||
587 | |||
588 | void *item_data(void) | ||
589 | { | ||
590 | return item_cur->node.data; | ||
591 | } | ||
592 | |||
593 | char item_tag(void) | ||
594 | { | ||
595 | return item_cur->node.tag; | ||
596 | } | ||
597 | |||
598 | int item_count(void) | ||
599 | { | ||
600 | int n = 0; | ||
601 | struct dialog_list *p; | ||
602 | |||
603 | for (p = item_head; p; p = p->next) | ||
604 | n++; | ||
605 | return n; | ||
606 | } | ||
607 | |||
608 | void item_set(int n) | ||
609 | { | ||
610 | int i = 0; | ||
611 | item_foreach() | ||
612 | if (i++ == n) | ||
613 | return; | ||
614 | } | ||
615 | |||
616 | int item_n(void) | ||
617 | { | ||
618 | int n = 0; | ||
619 | struct dialog_list *p; | ||
620 | |||
621 | for (p = item_head; p; p = p->next) { | ||
622 | if (p == item_cur) | ||
623 | return n; | ||
624 | n++; | ||
625 | } | ||
626 | return 0; | ||
627 | } | ||
628 | |||
629 | const char *item_str(void) | ||
630 | { | ||
631 | return item_cur->node.str; | ||
632 | } | ||
633 | |||
634 | int item_is_selected(void) | ||
635 | { | ||
636 | return (item_cur->node.selected != 0); | ||
637 | } | ||
638 | |||
639 | int item_is_tag(char tag) | ||
640 | { | ||
641 | return (item_cur->node.tag == tag); | ||
642 | } | ||
diff --git a/scripts/kconfig/lxdialog/yesno.c b/scripts/kconfig/lxdialog/yesno.c index cb2568aae3ed..ee0a04e3e012 100644 --- a/scripts/kconfig/lxdialog/yesno.c +++ b/scripts/kconfig/lxdialog/yesno.c | |||
@@ -44,6 +44,12 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width) | |||
44 | int i, x, y, key = 0, button = 0; | 44 | int i, x, y, key = 0, button = 0; |
45 | WINDOW *dialog; | 45 | WINDOW *dialog; |
46 | 46 | ||
47 | do_resize: | ||
48 | if (getmaxy(stdscr) < (height + 4)) | ||
49 | return -ERRDISPLAYTOOSMALL; | ||
50 | if (getmaxx(stdscr) < (width + 4)) | ||
51 | return -ERRDISPLAYTOOSMALL; | ||
52 | |||
47 | /* center dialog box on screen */ | 53 | /* center dialog box on screen */ |
48 | x = (COLS - width) / 2; | 54 | x = (COLS - width) / 2; |
49 | y = (LINES - height) / 2; | 55 | y = (LINES - height) / 2; |
@@ -53,22 +59,23 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width) | |||
53 | dialog = newwin(height, width, y, x); | 59 | dialog = newwin(height, width, y, x); |
54 | keypad(dialog, TRUE); | 60 | keypad(dialog, TRUE); |
55 | 61 | ||
56 | draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); | 62 | draw_box(dialog, 0, 0, height, width, |
57 | wattrset(dialog, border_attr); | 63 | dlg.dialog.atr, dlg.border.atr); |
64 | wattrset(dialog, dlg.border.atr); | ||
58 | mvwaddch(dialog, height - 3, 0, ACS_LTEE); | 65 | mvwaddch(dialog, height - 3, 0, ACS_LTEE); |
59 | for (i = 0; i < width - 2; i++) | 66 | for (i = 0; i < width - 2; i++) |
60 | waddch(dialog, ACS_HLINE); | 67 | waddch(dialog, ACS_HLINE); |
61 | wattrset(dialog, dialog_attr); | 68 | wattrset(dialog, dlg.dialog.atr); |
62 | waddch(dialog, ACS_RTEE); | 69 | waddch(dialog, ACS_RTEE); |
63 | 70 | ||
64 | print_title(dialog, title, width); | 71 | print_title(dialog, title, width); |
65 | 72 | ||
66 | wattrset(dialog, dialog_attr); | 73 | wattrset(dialog, dlg.dialog.atr); |
67 | print_autowrap(dialog, prompt, width - 2, 1, 3); | 74 | print_autowrap(dialog, prompt, width - 2, 1, 3); |
68 | 75 | ||
69 | print_buttons(dialog, height, width, 0); | 76 | print_buttons(dialog, height, width, 0); |
70 | 77 | ||
71 | while (key != ESC) { | 78 | while (key != KEY_ESC) { |
72 | key = wgetch(dialog); | 79 | key = wgetch(dialog); |
73 | switch (key) { | 80 | switch (key) { |
74 | case 'Y': | 81 | case 'Y': |
@@ -92,11 +99,16 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width) | |||
92 | case '\n': | 99 | case '\n': |
93 | delwin(dialog); | 100 | delwin(dialog); |
94 | return button; | 101 | return button; |
95 | case ESC: | 102 | case KEY_ESC: |
103 | key = on_key_esc(dialog); | ||
96 | break; | 104 | break; |
105 | case KEY_RESIZE: | ||
106 | delwin(dialog); | ||
107 | on_key_resize(); | ||
108 | goto do_resize; | ||
97 | } | 109 | } |
98 | } | 110 | } |
99 | 111 | ||
100 | delwin(dialog); | 112 | delwin(dialog); |
101 | return -1; /* ESC pressed */ | 113 | return key; /* ESC pressed */ |
102 | } | 114 | } |
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index 7f973195e79a..08a4c7af93ea 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #define LKC_DIRECT_LINK | 25 | #define LKC_DIRECT_LINK |
26 | #include "lkc.h" | 26 | #include "lkc.h" |
27 | #include "lxdialog/dialog.h" | ||
27 | 28 | ||
28 | static char menu_backtitle[128]; | 29 | static char menu_backtitle[128]; |
29 | static const char mconf_readme[] = N_( | 30 | static const char mconf_readme[] = N_( |
@@ -159,7 +160,21 @@ static const char mconf_readme[] = N_( | |||
159 | "\n" | 160 | "\n" |
160 | "Note that this mode can eventually be a little more CPU expensive\n" | 161 | "Note that this mode can eventually be a little more CPU expensive\n" |
161 | "(especially with a larger number of unrolled categories) than the\n" | 162 | "(especially with a larger number of unrolled categories) than the\n" |
162 | "default mode.\n"), | 163 | "default mode.\n" |
164 | "\n" | ||
165 | "Different color themes available\n" | ||
166 | "--------------------------------\n" | ||
167 | "It is possible to select different color themes using the variable\n" | ||
168 | "MENUCONFIG_COLOR. To select a theme use:\n" | ||
169 | "\n" | ||
170 | "make MENUCONFIG_COLOR=<theme> menuconfig\n" | ||
171 | "\n" | ||
172 | "Available themes are\n" | ||
173 | " mono => selects colors suitable for monochrome displays\n" | ||
174 | " blackbg => selects a color scheme with black background\n" | ||
175 | " classic => theme with blue background. The classic look\n" | ||
176 | " bluetitle => a LCD friendly version of classic. (default)\n" | ||
177 | "\n"), | ||
163 | menu_instructions[] = N_( | 178 | menu_instructions[] = N_( |
164 | "Arrow keys navigate the menu. " | 179 | "Arrow keys navigate the menu. " |
165 | "<Enter> selects submenus --->. " | 180 | "<Enter> selects submenus --->. " |
@@ -256,16 +271,12 @@ search_help[] = N_( | |||
256 | " USB$ => find all CONFIG_ symbols ending with USB\n" | 271 | " USB$ => find all CONFIG_ symbols ending with USB\n" |
257 | "\n"); | 272 | "\n"); |
258 | 273 | ||
259 | static char buf[4096], *bufptr = buf; | ||
260 | static char input_buf[4096]; | ||
261 | static char filename[PATH_MAX+1] = ".config"; | 274 | static char filename[PATH_MAX+1] = ".config"; |
262 | static char *args[1024], **argptr = args; | ||
263 | static int indent; | 275 | static int indent; |
264 | static struct termios ios_org; | 276 | static struct termios ios_org; |
265 | static int rows = 0, cols = 0; | 277 | static int rows = 0, cols = 0; |
266 | static struct menu *current_menu; | 278 | static struct menu *current_menu; |
267 | static int child_count; | 279 | static int child_count; |
268 | static int do_resize; | ||
269 | static int single_menu_mode; | 280 | static int single_menu_mode; |
270 | 281 | ||
271 | static void conf(struct menu *menu); | 282 | static void conf(struct menu *menu); |
@@ -276,12 +287,6 @@ static void conf_save(void); | |||
276 | static void show_textbox(const char *title, const char *text, int r, int c); | 287 | static void show_textbox(const char *title, const char *text, int r, int c); |
277 | static void show_helptext(const char *title, const char *text); | 288 | static void show_helptext(const char *title, const char *text); |
278 | static void show_help(struct menu *menu); | 289 | static void show_help(struct menu *menu); |
279 | static void show_file(const char *filename, const char *title, int r, int c); | ||
280 | |||
281 | static void cprint_init(void); | ||
282 | static int cprint1(const char *fmt, ...); | ||
283 | static void cprint_done(void); | ||
284 | static int cprint(const char *fmt, ...); | ||
285 | 290 | ||
286 | static void init_wsize(void) | 291 | static void init_wsize(void) |
287 | { | 292 | { |
@@ -318,54 +323,6 @@ static void init_wsize(void) | |||
318 | cols -= 5; | 323 | cols -= 5; |
319 | } | 324 | } |
320 | 325 | ||
321 | static void cprint_init(void) | ||
322 | { | ||
323 | bufptr = buf; | ||
324 | argptr = args; | ||
325 | memset(args, 0, sizeof(args)); | ||
326 | indent = 0; | ||
327 | child_count = 0; | ||
328 | cprint("./scripts/kconfig/lxdialog/lxdialog"); | ||
329 | cprint("--backtitle"); | ||
330 | cprint(menu_backtitle); | ||
331 | } | ||
332 | |||
333 | static int cprint1(const char *fmt, ...) | ||
334 | { | ||
335 | va_list ap; | ||
336 | int res; | ||
337 | |||
338 | if (!*argptr) | ||
339 | *argptr = bufptr; | ||
340 | va_start(ap, fmt); | ||
341 | res = vsprintf(bufptr, fmt, ap); | ||
342 | va_end(ap); | ||
343 | bufptr += res; | ||
344 | |||
345 | return res; | ||
346 | } | ||
347 | |||
348 | static void cprint_done(void) | ||
349 | { | ||
350 | *bufptr++ = 0; | ||
351 | argptr++; | ||
352 | } | ||
353 | |||
354 | static int cprint(const char *fmt, ...) | ||
355 | { | ||
356 | va_list ap; | ||
357 | int res; | ||
358 | |||
359 | *argptr++ = bufptr; | ||
360 | va_start(ap, fmt); | ||
361 | res = vsprintf(bufptr, fmt, ap); | ||
362 | va_end(ap); | ||
363 | bufptr += res; | ||
364 | *bufptr++ = 0; | ||
365 | |||
366 | return res; | ||
367 | } | ||
368 | |||
369 | static void get_prompt_str(struct gstr *r, struct property *prop) | 326 | static void get_prompt_str(struct gstr *r, struct property *prop) |
370 | { | 327 | { |
371 | int i, j; | 328 | int i, j; |
@@ -438,108 +395,17 @@ static struct gstr get_relations_str(struct symbol **sym_arr) | |||
438 | return res; | 395 | return res; |
439 | } | 396 | } |
440 | 397 | ||
441 | pid_t pid; | ||
442 | |||
443 | static void winch_handler(int sig) | ||
444 | { | ||
445 | if (!do_resize) { | ||
446 | kill(pid, SIGINT); | ||
447 | do_resize = 1; | ||
448 | } | ||
449 | } | ||
450 | |||
451 | static int exec_conf(void) | ||
452 | { | ||
453 | int pipefd[2], stat, size; | ||
454 | struct sigaction sa; | ||
455 | sigset_t sset, osset; | ||
456 | |||
457 | sigemptyset(&sset); | ||
458 | sigaddset(&sset, SIGINT); | ||
459 | sigprocmask(SIG_BLOCK, &sset, &osset); | ||
460 | |||
461 | signal(SIGINT, SIG_DFL); | ||
462 | |||
463 | sa.sa_handler = winch_handler; | ||
464 | sigemptyset(&sa.sa_mask); | ||
465 | sa.sa_flags = SA_RESTART; | ||
466 | sigaction(SIGWINCH, &sa, NULL); | ||
467 | |||
468 | *argptr++ = NULL; | ||
469 | |||
470 | pipe(pipefd); | ||
471 | pid = fork(); | ||
472 | if (pid == 0) { | ||
473 | sigprocmask(SIG_SETMASK, &osset, NULL); | ||
474 | dup2(pipefd[1], 2); | ||
475 | close(pipefd[0]); | ||
476 | close(pipefd[1]); | ||
477 | execv(args[0], args); | ||
478 | _exit(EXIT_FAILURE); | ||
479 | } | ||
480 | |||
481 | close(pipefd[1]); | ||
482 | bufptr = input_buf; | ||
483 | while (1) { | ||
484 | size = input_buf + sizeof(input_buf) - bufptr; | ||
485 | size = read(pipefd[0], bufptr, size); | ||
486 | if (size <= 0) { | ||
487 | if (size < 0) { | ||
488 | if (errno == EINTR || errno == EAGAIN) | ||
489 | continue; | ||
490 | perror("read"); | ||
491 | } | ||
492 | break; | ||
493 | } | ||
494 | bufptr += size; | ||
495 | } | ||
496 | *bufptr++ = 0; | ||
497 | close(pipefd[0]); | ||
498 | waitpid(pid, &stat, 0); | ||
499 | |||
500 | if (do_resize) { | ||
501 | init_wsize(); | ||
502 | do_resize = 0; | ||
503 | sigprocmask(SIG_SETMASK, &osset, NULL); | ||
504 | return -1; | ||
505 | } | ||
506 | if (WIFSIGNALED(stat)) { | ||
507 | printf("\finterrupted(%d)\n", WTERMSIG(stat)); | ||
508 | exit(1); | ||
509 | } | ||
510 | #if 0 | ||
511 | printf("\fexit state: %d\nexit data: '%s'\n", WEXITSTATUS(stat), input_buf); | ||
512 | sleep(1); | ||
513 | #endif | ||
514 | sigpending(&sset); | ||
515 | if (sigismember(&sset, SIGINT)) { | ||
516 | printf("\finterrupted\n"); | ||
517 | exit(1); | ||
518 | } | ||
519 | sigprocmask(SIG_SETMASK, &osset, NULL); | ||
520 | |||
521 | return WEXITSTATUS(stat); | ||
522 | } | ||
523 | |||
524 | static void search_conf(void) | 398 | static void search_conf(void) |
525 | { | 399 | { |
526 | struct symbol **sym_arr; | 400 | struct symbol **sym_arr; |
527 | int stat; | ||
528 | struct gstr res; | 401 | struct gstr res; |
529 | 402 | int dres; | |
530 | again: | 403 | again: |
531 | cprint_init(); | 404 | dialog_clear(); |
532 | cprint("--title"); | 405 | dres = dialog_inputbox(_("Search Configuration Parameter"), |
533 | cprint(_("Search Configuration Parameter")); | 406 | _("Enter CONFIG_ (sub)string to search for (omit CONFIG_)"), |
534 | cprint("--inputbox"); | 407 | 10, 75, ""); |
535 | cprint(_("Enter CONFIG_ (sub)string to search for (omit CONFIG_)")); | 408 | switch (dres) { |
536 | cprint("10"); | ||
537 | cprint("75"); | ||
538 | cprint(""); | ||
539 | stat = exec_conf(); | ||
540 | if (stat < 0) | ||
541 | goto again; | ||
542 | switch (stat) { | ||
543 | case 0: | 409 | case 0: |
544 | break; | 410 | break; |
545 | case 1: | 411 | case 1: |
@@ -549,7 +415,7 @@ again: | |||
549 | return; | 415 | return; |
550 | } | 416 | } |
551 | 417 | ||
552 | sym_arr = sym_re_search(input_buf); | 418 | sym_arr = sym_re_search(dialog_input_result); |
553 | res = get_relations_str(sym_arr); | 419 | res = get_relations_str(sym_arr); |
554 | free(sym_arr); | 420 | free(sym_arr); |
555 | show_textbox(_("Search Results"), str_get(&res), 0, 0); | 421 | show_textbox(_("Search Results"), str_get(&res), 0, 0); |
@@ -576,24 +442,24 @@ static void build_conf(struct menu *menu) | |||
576 | switch (prop->type) { | 442 | switch (prop->type) { |
577 | case P_MENU: | 443 | case P_MENU: |
578 | child_count++; | 444 | child_count++; |
579 | cprint("m%p", menu); | ||
580 | |||
581 | if (single_menu_mode) { | 445 | if (single_menu_mode) { |
582 | cprint1("%s%*c%s", | 446 | item_make("%s%*c%s", |
583 | menu->data ? "-->" : "++>", | 447 | menu->data ? "-->" : "++>", |
584 | indent + 1, ' ', prompt); | 448 | indent + 1, ' ', prompt); |
585 | } else | 449 | } else |
586 | cprint1(" %*c%s --->", indent + 1, ' ', prompt); | 450 | item_make(" %*c%s --->", indent + 1, ' ', prompt); |
587 | 451 | ||
588 | cprint_done(); | 452 | item_set_tag('m'); |
453 | item_set_data(menu); | ||
589 | if (single_menu_mode && menu->data) | 454 | if (single_menu_mode && menu->data) |
590 | goto conf_childs; | 455 | goto conf_childs; |
591 | return; | 456 | return; |
592 | default: | 457 | default: |
593 | if (prompt) { | 458 | if (prompt) { |
594 | child_count++; | 459 | child_count++; |
595 | cprint(":%p", menu); | 460 | item_make("---%*c%s", indent + 1, ' ', prompt); |
596 | cprint("---%*c%s", indent + 1, ' ', prompt); | 461 | item_set_tag(':'); |
462 | item_set_data(menu); | ||
597 | } | 463 | } |
598 | } | 464 | } |
599 | } else | 465 | } else |
@@ -614,10 +480,9 @@ static void build_conf(struct menu *menu) | |||
614 | 480 | ||
615 | val = sym_get_tristate_value(sym); | 481 | val = sym_get_tristate_value(sym); |
616 | if (sym_is_changable(sym)) { | 482 | if (sym_is_changable(sym)) { |
617 | cprint("t%p", menu); | ||
618 | switch (type) { | 483 | switch (type) { |
619 | case S_BOOLEAN: | 484 | case S_BOOLEAN: |
620 | cprint1("[%c]", val == no ? ' ' : '*'); | 485 | item_make("[%c]", val == no ? ' ' : '*'); |
621 | break; | 486 | break; |
622 | case S_TRISTATE: | 487 | case S_TRISTATE: |
623 | switch (val) { | 488 | switch (val) { |
@@ -625,84 +490,87 @@ static void build_conf(struct menu *menu) | |||
625 | case mod: ch = 'M'; break; | 490 | case mod: ch = 'M'; break; |
626 | default: ch = ' '; break; | 491 | default: ch = ' '; break; |
627 | } | 492 | } |
628 | cprint1("<%c>", ch); | 493 | item_make("<%c>", ch); |
629 | break; | 494 | break; |
630 | } | 495 | } |
496 | item_set_tag('t'); | ||
497 | item_set_data(menu); | ||
631 | } else { | 498 | } else { |
632 | cprint("%c%p", def_menu ? 't' : ':', menu); | 499 | item_make(" "); |
633 | cprint1(" "); | 500 | item_set_tag(def_menu ? 't' : ':'); |
501 | item_set_data(menu); | ||
634 | } | 502 | } |
635 | 503 | ||
636 | cprint1("%*c%s", indent + 1, ' ', menu_get_prompt(menu)); | 504 | item_add_str("%*c%s", indent + 1, ' ', menu_get_prompt(menu)); |
637 | if (val == yes) { | 505 | if (val == yes) { |
638 | if (def_menu) { | 506 | if (def_menu) { |
639 | cprint1(" (%s)", menu_get_prompt(def_menu)); | 507 | item_add_str(" (%s)", menu_get_prompt(def_menu)); |
640 | cprint1(" --->"); | 508 | item_add_str(" --->"); |
641 | cprint_done(); | ||
642 | if (def_menu->list) { | 509 | if (def_menu->list) { |
643 | indent += 2; | 510 | indent += 2; |
644 | build_conf(def_menu); | 511 | build_conf(def_menu); |
645 | indent -= 2; | 512 | indent -= 2; |
646 | } | 513 | } |
647 | } else | 514 | } |
648 | cprint_done(); | ||
649 | return; | 515 | return; |
650 | } | 516 | } |
651 | cprint_done(); | ||
652 | } else { | 517 | } else { |
653 | if (menu == current_menu) { | 518 | if (menu == current_menu) { |
654 | cprint(":%p", menu); | 519 | item_make("---%*c%s", indent + 1, ' ', menu_get_prompt(menu)); |
655 | cprint("---%*c%s", indent + 1, ' ', menu_get_prompt(menu)); | 520 | item_set_tag(':'); |
521 | item_set_data(menu); | ||
656 | goto conf_childs; | 522 | goto conf_childs; |
657 | } | 523 | } |
658 | child_count++; | 524 | child_count++; |
659 | val = sym_get_tristate_value(sym); | 525 | val = sym_get_tristate_value(sym); |
660 | if (sym_is_choice_value(sym) && val == yes) { | 526 | if (sym_is_choice_value(sym) && val == yes) { |
661 | cprint(":%p", menu); | 527 | item_make(" "); |
662 | cprint1(" "); | 528 | item_set_tag(':'); |
529 | item_set_data(menu); | ||
663 | } else { | 530 | } else { |
664 | switch (type) { | 531 | switch (type) { |
665 | case S_BOOLEAN: | 532 | case S_BOOLEAN: |
666 | cprint("t%p", menu); | ||
667 | if (sym_is_changable(sym)) | 533 | if (sym_is_changable(sym)) |
668 | cprint1("[%c]", val == no ? ' ' : '*'); | 534 | item_make("[%c]", val == no ? ' ' : '*'); |
669 | else | 535 | else |
670 | cprint1("---"); | 536 | item_make("---"); |
537 | item_set_tag('t'); | ||
538 | item_set_data(menu); | ||
671 | break; | 539 | break; |
672 | case S_TRISTATE: | 540 | case S_TRISTATE: |
673 | cprint("t%p", menu); | ||
674 | switch (val) { | 541 | switch (val) { |
675 | case yes: ch = '*'; break; | 542 | case yes: ch = '*'; break; |
676 | case mod: ch = 'M'; break; | 543 | case mod: ch = 'M'; break; |
677 | default: ch = ' '; break; | 544 | default: ch = ' '; break; |
678 | } | 545 | } |
679 | if (sym_is_changable(sym)) | 546 | if (sym_is_changable(sym)) |
680 | cprint1("<%c>", ch); | 547 | item_make("<%c>", ch); |
681 | else | 548 | else |
682 | cprint1("---"); | 549 | item_make("---"); |
550 | item_set_tag('t'); | ||
551 | item_set_data(menu); | ||
683 | break; | 552 | break; |
684 | default: | 553 | default: |
685 | cprint("s%p", menu); | 554 | tmp = 2 + strlen(sym_get_string_value(sym)); /* () = 2 */ |
686 | tmp = cprint1("(%s)", sym_get_string_value(sym)); | 555 | item_make("(%s)", sym_get_string_value(sym)); |
687 | tmp = indent - tmp + 4; | 556 | tmp = indent - tmp + 4; |
688 | if (tmp < 0) | 557 | if (tmp < 0) |
689 | tmp = 0; | 558 | tmp = 0; |
690 | cprint1("%*c%s%s", tmp, ' ', menu_get_prompt(menu), | 559 | item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu), |
691 | (sym_has_value(sym) || !sym_is_changable(sym)) ? | 560 | (sym_has_value(sym) || !sym_is_changable(sym)) ? |
692 | "" : " (NEW)"); | 561 | "" : " (NEW)"); |
693 | cprint_done(); | 562 | item_set_tag('s'); |
563 | item_set_data(menu); | ||
694 | goto conf_childs; | 564 | goto conf_childs; |
695 | } | 565 | } |
696 | } | 566 | } |
697 | cprint1("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu), | 567 | item_add_str("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu), |
698 | (sym_has_value(sym) || !sym_is_changable(sym)) ? | 568 | (sym_has_value(sym) || !sym_is_changable(sym)) ? |
699 | "" : " (NEW)"); | 569 | "" : " (NEW)"); |
700 | if (menu->prompt->type == P_MENU) { | 570 | if (menu->prompt->type == P_MENU) { |
701 | cprint1(" --->"); | 571 | item_add_str(" --->"); |
702 | cprint_done(); | ||
703 | return; | 572 | return; |
704 | } | 573 | } |
705 | cprint_done(); | ||
706 | } | 574 | } |
707 | 575 | ||
708 | conf_childs: | 576 | conf_childs: |
@@ -717,59 +585,45 @@ static void conf(struct menu *menu) | |||
717 | struct menu *submenu; | 585 | struct menu *submenu; |
718 | const char *prompt = menu_get_prompt(menu); | 586 | const char *prompt = menu_get_prompt(menu); |
719 | struct symbol *sym; | 587 | struct symbol *sym; |
720 | char active_entry[40]; | 588 | struct menu *active_menu = NULL; |
721 | int stat, type, i; | 589 | int res; |
590 | int s_scroll = 0; | ||
722 | 591 | ||
723 | unlink("lxdialog.scrltmp"); | ||
724 | active_entry[0] = 0; | ||
725 | while (1) { | 592 | while (1) { |
726 | cprint_init(); | 593 | item_reset(); |
727 | cprint("--title"); | ||
728 | cprint("%s", prompt ? prompt : _("Main Menu")); | ||
729 | cprint("--menu"); | ||
730 | cprint(_(menu_instructions)); | ||
731 | cprint("%d", rows); | ||
732 | cprint("%d", cols); | ||
733 | cprint("%d", rows - 10); | ||
734 | cprint("%s", active_entry); | ||
735 | current_menu = menu; | 594 | current_menu = menu; |
736 | build_conf(menu); | 595 | build_conf(menu); |
737 | if (!child_count) | 596 | if (!child_count) |
738 | break; | 597 | break; |
739 | if (menu == &rootmenu) { | 598 | if (menu == &rootmenu) { |
740 | cprint(":"); | 599 | item_make("--- "); |
741 | cprint("--- "); | 600 | item_set_tag(':'); |
742 | cprint("L"); | 601 | item_make(_(" Load an Alternate Configuration File")); |
743 | cprint(_(" Load an Alternate Configuration File")); | 602 | item_set_tag('L'); |
744 | cprint("S"); | 603 | item_make(_(" Save an Alternate Configuration File")); |
745 | cprint(_(" Save Configuration to an Alternate File")); | 604 | item_set_tag('S'); |
746 | } | 605 | } |
747 | stat = exec_conf(); | 606 | dialog_clear(); |
748 | if (stat < 0) | 607 | res = dialog_menu(prompt ? prompt : _("Main Menu"), |
749 | continue; | 608 | _(menu_instructions), |
750 | 609 | active_menu, &s_scroll); | |
751 | if (stat == 1 || stat == 255) | 610 | if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL) |
752 | break; | 611 | break; |
753 | 612 | if (!item_activate_selected()) | |
754 | type = input_buf[0]; | 613 | continue; |
755 | if (!type) | 614 | if (!item_tag()) |
756 | continue; | 615 | continue; |
757 | 616 | ||
758 | for (i = 0; input_buf[i] && !isspace(input_buf[i]); i++) | 617 | submenu = item_data(); |
759 | ; | 618 | active_menu = item_data(); |
760 | if (i >= sizeof(active_entry)) | 619 | if (submenu) |
761 | i = sizeof(active_entry) - 1; | ||
762 | input_buf[i] = 0; | ||
763 | strcpy(active_entry, input_buf); | ||
764 | |||
765 | sym = NULL; | ||
766 | submenu = NULL; | ||
767 | if (sscanf(input_buf + 1, "%p", &submenu) == 1) | ||
768 | sym = submenu->sym; | 620 | sym = submenu->sym; |
621 | else | ||
622 | sym = NULL; | ||
769 | 623 | ||
770 | switch (stat) { | 624 | switch (res) { |
771 | case 0: | 625 | case 0: |
772 | switch (type) { | 626 | switch (item_tag()) { |
773 | case 'm': | 627 | case 'm': |
774 | if (single_menu_mode) | 628 | if (single_menu_mode) |
775 | submenu->data = (void *) (long) !submenu->data; | 629 | submenu->data = (void *) (long) !submenu->data; |
@@ -800,7 +654,7 @@ static void conf(struct menu *menu) | |||
800 | show_helptext("README", _(mconf_readme)); | 654 | show_helptext("README", _(mconf_readme)); |
801 | break; | 655 | break; |
802 | case 3: | 656 | case 3: |
803 | if (type == 't') { | 657 | if (item_is_tag('t')) { |
804 | if (sym_set_tristate_value(sym, yes)) | 658 | if (sym_set_tristate_value(sym, yes)) |
805 | break; | 659 | break; |
806 | if (sym_set_tristate_value(sym, mod)) | 660 | if (sym_set_tristate_value(sym, mod)) |
@@ -808,17 +662,17 @@ static void conf(struct menu *menu) | |||
808 | } | 662 | } |
809 | break; | 663 | break; |
810 | case 4: | 664 | case 4: |
811 | if (type == 't') | 665 | if (item_is_tag('t')) |
812 | sym_set_tristate_value(sym, no); | 666 | sym_set_tristate_value(sym, no); |
813 | break; | 667 | break; |
814 | case 5: | 668 | case 5: |
815 | if (type == 't') | 669 | if (item_is_tag('t')) |
816 | sym_set_tristate_value(sym, mod); | 670 | sym_set_tristate_value(sym, mod); |
817 | break; | 671 | break; |
818 | case 6: | 672 | case 6: |
819 | if (type == 't') | 673 | if (item_is_tag('t')) |
820 | sym_toggle_tristate_value(sym); | 674 | sym_toggle_tristate_value(sym); |
821 | else if (type == 'm') | 675 | else if (item_is_tag('m')) |
822 | conf(submenu); | 676 | conf(submenu); |
823 | break; | 677 | break; |
824 | case 7: | 678 | case 7: |
@@ -830,13 +684,8 @@ static void conf(struct menu *menu) | |||
830 | 684 | ||
831 | static void show_textbox(const char *title, const char *text, int r, int c) | 685 | static void show_textbox(const char *title, const char *text, int r, int c) |
832 | { | 686 | { |
833 | int fd; | 687 | dialog_clear(); |
834 | 688 | dialog_textbox(title, text, r, c); | |
835 | fd = creat(".help.tmp", 0777); | ||
836 | write(fd, text, strlen(text)); | ||
837 | close(fd); | ||
838 | show_file(".help.tmp", title, r, c); | ||
839 | unlink(".help.tmp"); | ||
840 | } | 689 | } |
841 | 690 | ||
842 | static void show_helptext(const char *title, const char *text) | 691 | static void show_helptext(const char *title, const char *text) |
@@ -864,68 +713,52 @@ static void show_help(struct menu *menu) | |||
864 | str_free(&help); | 713 | str_free(&help); |
865 | } | 714 | } |
866 | 715 | ||
867 | static void show_file(const char *filename, const char *title, int r, int c) | ||
868 | { | ||
869 | do { | ||
870 | cprint_init(); | ||
871 | if (title) { | ||
872 | cprint("--title"); | ||
873 | cprint("%s", title); | ||
874 | } | ||
875 | cprint("--textbox"); | ||
876 | cprint("%s", filename); | ||
877 | cprint("%d", r ? r : rows); | ||
878 | cprint("%d", c ? c : cols); | ||
879 | } while (exec_conf() < 0); | ||
880 | } | ||
881 | |||
882 | static void conf_choice(struct menu *menu) | 716 | static void conf_choice(struct menu *menu) |
883 | { | 717 | { |
884 | const char *prompt = menu_get_prompt(menu); | 718 | const char *prompt = menu_get_prompt(menu); |
885 | struct menu *child; | 719 | struct menu *child; |
886 | struct symbol *active; | 720 | struct symbol *active; |
887 | int stat; | ||
888 | 721 | ||
889 | active = sym_get_choice_value(menu->sym); | 722 | active = sym_get_choice_value(menu->sym); |
890 | while (1) { | 723 | while (1) { |
891 | cprint_init(); | 724 | int res; |
892 | cprint("--title"); | 725 | int selected; |
893 | cprint("%s", prompt ? prompt : _("Main Menu")); | 726 | item_reset(); |
894 | cprint("--radiolist"); | ||
895 | cprint(_(radiolist_instructions)); | ||
896 | cprint("15"); | ||
897 | cprint("70"); | ||
898 | cprint("6"); | ||
899 | 727 | ||
900 | current_menu = menu; | 728 | current_menu = menu; |
901 | for (child = menu->list; child; child = child->next) { | 729 | for (child = menu->list; child; child = child->next) { |
902 | if (!menu_is_visible(child)) | 730 | if (!menu_is_visible(child)) |
903 | continue; | 731 | continue; |
904 | cprint("%p", child); | 732 | item_make("%s", menu_get_prompt(child)); |
905 | cprint("%s", menu_get_prompt(child)); | 733 | item_set_data(child); |
734 | if (child->sym == active) | ||
735 | item_set_selected(1); | ||
906 | if (child->sym == sym_get_choice_value(menu->sym)) | 736 | if (child->sym == sym_get_choice_value(menu->sym)) |
907 | cprint("ON"); | 737 | item_set_tag('X'); |
908 | else if (child->sym == active) | ||
909 | cprint("SELECTED"); | ||
910 | else | ||
911 | cprint("OFF"); | ||
912 | } | 738 | } |
913 | 739 | dialog_clear(); | |
914 | stat = exec_conf(); | 740 | res = dialog_checklist(prompt ? prompt : _("Main Menu"), |
915 | switch (stat) { | 741 | _(radiolist_instructions), |
742 | 15, 70, 6); | ||
743 | selected = item_activate_selected(); | ||
744 | switch (res) { | ||
916 | case 0: | 745 | case 0: |
917 | if (sscanf(input_buf, "%p", &child) != 1) | 746 | if (selected) { |
918 | break; | 747 | child = item_data(); |
919 | sym_set_tristate_value(child->sym, yes); | 748 | sym_set_tristate_value(child->sym, yes); |
749 | } | ||
920 | return; | 750 | return; |
921 | case 1: | 751 | case 1: |
922 | if (sscanf(input_buf, "%p", &child) == 1) { | 752 | if (selected) { |
753 | child = item_data(); | ||
923 | show_help(child); | 754 | show_help(child); |
924 | active = child->sym; | 755 | active = child->sym; |
925 | } else | 756 | } else |
926 | show_help(menu); | 757 | show_help(menu); |
927 | break; | 758 | break; |
928 | case 255: | 759 | case KEY_ESC: |
760 | return; | ||
761 | case -ERRDISPLAYTOOSMALL: | ||
929 | return; | 762 | return; |
930 | } | 763 | } |
931 | } | 764 | } |
@@ -934,40 +767,38 @@ static void conf_choice(struct menu *menu) | |||
934 | static void conf_string(struct menu *menu) | 767 | static void conf_string(struct menu *menu) |
935 | { | 768 | { |
936 | const char *prompt = menu_get_prompt(menu); | 769 | const char *prompt = menu_get_prompt(menu); |
937 | int stat; | ||
938 | 770 | ||
939 | while (1) { | 771 | while (1) { |
940 | cprint_init(); | 772 | int res; |
941 | cprint("--title"); | 773 | char *heading; |
942 | cprint("%s", prompt ? prompt : _("Main Menu")); | 774 | |
943 | cprint("--inputbox"); | ||
944 | switch (sym_get_type(menu->sym)) { | 775 | switch (sym_get_type(menu->sym)) { |
945 | case S_INT: | 776 | case S_INT: |
946 | cprint(_(inputbox_instructions_int)); | 777 | heading = _(inputbox_instructions_int); |
947 | break; | 778 | break; |
948 | case S_HEX: | 779 | case S_HEX: |
949 | cprint(_(inputbox_instructions_hex)); | 780 | heading = _(inputbox_instructions_hex); |
950 | break; | 781 | break; |
951 | case S_STRING: | 782 | case S_STRING: |
952 | cprint(_(inputbox_instructions_string)); | 783 | heading = _(inputbox_instructions_string); |
953 | break; | 784 | break; |
954 | default: | 785 | default: |
955 | /* panic? */; | 786 | heading = "Internal mconf error!"; |
956 | } | 787 | } |
957 | cprint("10"); | 788 | dialog_clear(); |
958 | cprint("75"); | 789 | res = dialog_inputbox(prompt ? prompt : _("Main Menu"), |
959 | cprint("%s", sym_get_string_value(menu->sym)); | 790 | heading, 10, 75, |
960 | stat = exec_conf(); | 791 | sym_get_string_value(menu->sym)); |
961 | switch (stat) { | 792 | switch (res) { |
962 | case 0: | 793 | case 0: |
963 | if (sym_set_string_value(menu->sym, input_buf)) | 794 | if (sym_set_string_value(menu->sym, dialog_input_result)) |
964 | return; | 795 | return; |
965 | show_textbox(NULL, _("You have made an invalid entry."), 5, 43); | 796 | show_textbox(NULL, _("You have made an invalid entry."), 5, 43); |
966 | break; | 797 | break; |
967 | case 1: | 798 | case 1: |
968 | show_help(menu); | 799 | show_help(menu); |
969 | break; | 800 | break; |
970 | case 255: | 801 | case KEY_ESC: |
971 | return; | 802 | return; |
972 | } | 803 | } |
973 | } | 804 | } |
@@ -975,28 +806,24 @@ static void conf_string(struct menu *menu) | |||
975 | 806 | ||
976 | static void conf_load(void) | 807 | static void conf_load(void) |
977 | { | 808 | { |
978 | int stat; | ||
979 | 809 | ||
980 | while (1) { | 810 | while (1) { |
981 | cprint_init(); | 811 | int res; |
982 | cprint("--inputbox"); | 812 | dialog_clear(); |
983 | cprint(load_config_text); | 813 | res = dialog_inputbox(NULL, load_config_text, |
984 | cprint("11"); | 814 | 11, 55, filename); |
985 | cprint("55"); | 815 | switch(res) { |
986 | cprint("%s", filename); | ||
987 | stat = exec_conf(); | ||
988 | switch(stat) { | ||
989 | case 0: | 816 | case 0: |
990 | if (!input_buf[0]) | 817 | if (!dialog_input_result[0]) |
991 | return; | 818 | return; |
992 | if (!conf_read(input_buf)) | 819 | if (!conf_read(dialog_input_result)) |
993 | return; | 820 | return; |
994 | show_textbox(NULL, _("File does not exist!"), 5, 38); | 821 | show_textbox(NULL, _("File does not exist!"), 5, 38); |
995 | break; | 822 | break; |
996 | case 1: | 823 | case 1: |
997 | show_helptext(_("Load Alternate Configuration"), load_config_help); | 824 | show_helptext(_("Load Alternate Configuration"), load_config_help); |
998 | break; | 825 | break; |
999 | case 255: | 826 | case KEY_ESC: |
1000 | return; | 827 | return; |
1001 | } | 828 | } |
1002 | } | 829 | } |
@@ -1004,28 +831,23 @@ static void conf_load(void) | |||
1004 | 831 | ||
1005 | static void conf_save(void) | 832 | static void conf_save(void) |
1006 | { | 833 | { |
1007 | int stat; | ||
1008 | |||
1009 | while (1) { | 834 | while (1) { |
1010 | cprint_init(); | 835 | int res; |
1011 | cprint("--inputbox"); | 836 | dialog_clear(); |
1012 | cprint(save_config_text); | 837 | res = dialog_inputbox(NULL, save_config_text, |
1013 | cprint("11"); | 838 | 11, 55, filename); |
1014 | cprint("55"); | 839 | switch(res) { |
1015 | cprint("%s", filename); | ||
1016 | stat = exec_conf(); | ||
1017 | switch(stat) { | ||
1018 | case 0: | 840 | case 0: |
1019 | if (!input_buf[0]) | 841 | if (!dialog_input_result[0]) |
1020 | return; | 842 | return; |
1021 | if (!conf_write(input_buf)) | 843 | if (!conf_write(dialog_input_result)) |
1022 | return; | 844 | return; |
1023 | show_textbox(NULL, _("Can't create file! Probably a nonexistent directory."), 5, 60); | 845 | show_textbox(NULL, _("Can't create file! Probably a nonexistent directory."), 5, 60); |
1024 | break; | 846 | break; |
1025 | case 1: | 847 | case 1: |
1026 | show_helptext(_("Save Alternate Configuration"), save_config_help); | 848 | show_helptext(_("Save Alternate Configuration"), save_config_help); |
1027 | break; | 849 | break; |
1028 | case 255: | 850 | case KEY_ESC: |
1029 | return; | 851 | return; |
1030 | } | 852 | } |
1031 | } | 853 | } |
@@ -1034,15 +856,13 @@ static void conf_save(void) | |||
1034 | static void conf_cleanup(void) | 856 | static void conf_cleanup(void) |
1035 | { | 857 | { |
1036 | tcsetattr(1, TCSAFLUSH, &ios_org); | 858 | tcsetattr(1, TCSAFLUSH, &ios_org); |
1037 | unlink(".help.tmp"); | ||
1038 | unlink("lxdialog.scrltmp"); | ||
1039 | } | 859 | } |
1040 | 860 | ||
1041 | int main(int ac, char **av) | 861 | int main(int ac, char **av) |
1042 | { | 862 | { |
1043 | struct symbol *sym; | 863 | struct symbol *sym; |
1044 | char *mode; | 864 | char *mode; |
1045 | int stat; | 865 | int res; |
1046 | 866 | ||
1047 | setlocale(LC_ALL, ""); | 867 | setlocale(LC_ALL, ""); |
1048 | bindtextdomain(PACKAGE, LOCALEDIR); | 868 | bindtextdomain(PACKAGE, LOCALEDIR); |
@@ -1065,18 +885,19 @@ int main(int ac, char **av) | |||
1065 | tcgetattr(1, &ios_org); | 885 | tcgetattr(1, &ios_org); |
1066 | atexit(conf_cleanup); | 886 | atexit(conf_cleanup); |
1067 | init_wsize(); | 887 | init_wsize(); |
1068 | conf(&rootmenu); | 888 | reset_dialog(); |
1069 | 889 | init_dialog(menu_backtitle); | |
1070 | do { | 890 | do { |
1071 | cprint_init(); | 891 | conf(&rootmenu); |
1072 | cprint("--yesno"); | 892 | dialog_clear(); |
1073 | cprint(_("Do you wish to save your new kernel configuration?")); | 893 | res = dialog_yesno(NULL, |
1074 | cprint("5"); | 894 | _("Do you wish to save your " |
1075 | cprint("60"); | 895 | "new kernel configuration?\n" |
1076 | stat = exec_conf(); | 896 | "<ESC><ESC> to continue."), |
1077 | } while (stat < 0); | 897 | 6, 60); |
1078 | 898 | } while (res == KEY_ESC); | |
1079 | if (stat == 0) { | 899 | end_dialog(); |
900 | if (res == 0) { | ||
1080 | if (conf_write(NULL)) { | 901 | if (conf_write(NULL)) { |
1081 | fprintf(stderr, _("\n\n" | 902 | fprintf(stderr, _("\n\n" |
1082 | "Error during writing of the kernel configuration.\n" | 903 | "Error during writing of the kernel configuration.\n" |
diff --git a/sound/oss/trident.c b/sound/oss/trident.c index ce79cd82478a..147c816a1f22 100644 --- a/sound/oss/trident.c +++ b/sound/oss/trident.c | |||
@@ -1862,7 +1862,7 @@ trident_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos | |||
1862 | unsigned swptr; | 1862 | unsigned swptr; |
1863 | int cnt; | 1863 | int cnt; |
1864 | 1864 | ||
1865 | pr_debug("trident: trident_read called, count = %d\n", count); | 1865 | pr_debug("trident: trident_read called, count = %zd\n", count); |
1866 | 1866 | ||
1867 | VALIDATE_STATE(state); | 1867 | VALIDATE_STATE(state); |
1868 | 1868 | ||
@@ -1978,7 +1978,7 @@ trident_write(struct file *file, const char __user *buffer, size_t count, loff_t | |||
1978 | unsigned int copy_count; | 1978 | unsigned int copy_count; |
1979 | int lret; /* for lock_set_fmt */ | 1979 | int lret; /* for lock_set_fmt */ |
1980 | 1980 | ||
1981 | pr_debug("trident: trident_write called, count = %d\n", count); | 1981 | pr_debug("trident: trident_write called, count = %zd\n", count); |
1982 | 1982 | ||
1983 | VALIDATE_STATE(state); | 1983 | VALIDATE_STATE(state); |
1984 | 1984 | ||