diff options
Diffstat (limited to 'drivers')
117 files changed, 4312 insertions, 1394 deletions
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index efd0b4db7c8e..8822eca58ffa 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig | |||
@@ -59,6 +59,19 @@ config HW_RANDOM_GEODE | |||
59 | 59 | ||
60 | If unsure, say Y. | 60 | If unsure, say Y. |
61 | 61 | ||
62 | config HW_RANDOM_N2RNG | ||
63 | tristate "Niagara2 Random Number Generator support" | ||
64 | depends on HW_RANDOM && SPARC64 | ||
65 | default HW_RANDOM | ||
66 | ---help--- | ||
67 | This driver provides kernel-side support for the Random Number | ||
68 | Generator hardware found on Niagara2 cpus. | ||
69 | |||
70 | To compile this driver as a module, choose M here: the | ||
71 | module will be called n2-rng. | ||
72 | |||
73 | If unsure, say Y. | ||
74 | |||
62 | config HW_RANDOM_VIA | 75 | config HW_RANDOM_VIA |
63 | tristate "VIA HW Random Number Generator support" | 76 | tristate "VIA HW Random Number Generator support" |
64 | depends on HW_RANDOM && X86_32 | 77 | depends on HW_RANDOM && X86_32 |
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile index b4940ddbb35f..b6effb7522c2 100644 --- a/drivers/char/hw_random/Makefile +++ b/drivers/char/hw_random/Makefile | |||
@@ -7,6 +7,8 @@ rng-core-y := core.o | |||
7 | obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o | 7 | obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o |
8 | obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o | 8 | obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o |
9 | obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o | 9 | obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o |
10 | obj-$(CONFIG_HW_RANDOM_N2RNG) += n2-rng.o | ||
11 | n2-rng-y := n2-drv.o n2-asm.o | ||
10 | obj-$(CONFIG_HW_RANDOM_VIA) += via-rng.o | 12 | obj-$(CONFIG_HW_RANDOM_VIA) += via-rng.o |
11 | obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o | 13 | obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o |
12 | obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o | 14 | obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o |
diff --git a/drivers/char/hw_random/n2-asm.S b/drivers/char/hw_random/n2-asm.S new file mode 100644 index 000000000000..9b6eb5cd59f6 --- /dev/null +++ b/drivers/char/hw_random/n2-asm.S | |||
@@ -0,0 +1,79 @@ | |||
1 | /* n2-asm.S: Niagara2 RNG hypervisor call assembler. | ||
2 | * | ||
3 | * Copyright (C) 2008 David S. Miller <davem@davemloft.net> | ||
4 | */ | ||
5 | #include <linux/linkage.h> | ||
6 | #include <asm/hypervisor.h> | ||
7 | #include "n2rng.h" | ||
8 | |||
9 | .text | ||
10 | |||
11 | ENTRY(sun4v_rng_get_diag_ctl) | ||
12 | mov HV_FAST_RNG_GET_DIAG_CTL, %o5 | ||
13 | ta HV_FAST_TRAP | ||
14 | retl | ||
15 | nop | ||
16 | ENDPROC(sun4v_rng_get_diag_ctl) | ||
17 | |||
18 | ENTRY(sun4v_rng_ctl_read_v1) | ||
19 | mov %o1, %o3 | ||
20 | mov %o2, %o4 | ||
21 | mov HV_FAST_RNG_CTL_READ, %o5 | ||
22 | ta HV_FAST_TRAP | ||
23 | stx %o1, [%o3] | ||
24 | retl | ||
25 | stx %o2, [%o4] | ||
26 | ENDPROC(sun4v_rng_ctl_read_v1) | ||
27 | |||
28 | ENTRY(sun4v_rng_ctl_read_v2) | ||
29 | save %sp, -192, %sp | ||
30 | mov %i0, %o0 | ||
31 | mov %i1, %o1 | ||
32 | mov HV_FAST_RNG_CTL_READ, %o5 | ||
33 | ta HV_FAST_TRAP | ||
34 | stx %o1, [%i2] | ||
35 | stx %o2, [%i3] | ||
36 | stx %o3, [%i4] | ||
37 | stx %o4, [%i5] | ||
38 | ret | ||
39 | restore %g0, %o0, %o0 | ||
40 | ENDPROC(sun4v_rng_ctl_read_v2) | ||
41 | |||
42 | ENTRY(sun4v_rng_ctl_write_v1) | ||
43 | mov %o3, %o4 | ||
44 | mov HV_FAST_RNG_CTL_WRITE, %o5 | ||
45 | ta HV_FAST_TRAP | ||
46 | retl | ||
47 | stx %o1, [%o4] | ||
48 | ENDPROC(sun4v_rng_ctl_write_v1) | ||
49 | |||
50 | ENTRY(sun4v_rng_ctl_write_v2) | ||
51 | mov HV_FAST_RNG_CTL_WRITE, %o5 | ||
52 | ta HV_FAST_TRAP | ||
53 | retl | ||
54 | nop | ||
55 | ENDPROC(sun4v_rng_ctl_write_v2) | ||
56 | |||
57 | ENTRY(sun4v_rng_data_read_diag_v1) | ||
58 | mov %o2, %o4 | ||
59 | mov HV_FAST_RNG_DATA_READ_DIAG, %o5 | ||
60 | ta HV_FAST_TRAP | ||
61 | retl | ||
62 | stx %o1, [%o4] | ||
63 | ENDPROC(sun4v_rng_data_read_diag_v1) | ||
64 | |||
65 | ENTRY(sun4v_rng_data_read_diag_v2) | ||
66 | mov %o3, %o4 | ||
67 | mov HV_FAST_RNG_DATA_READ_DIAG, %o5 | ||
68 | ta HV_FAST_TRAP | ||
69 | retl | ||
70 | stx %o1, [%o4] | ||
71 | ENDPROC(sun4v_rng_data_read_diag_v2) | ||
72 | |||
73 | ENTRY(sun4v_rng_data_read) | ||
74 | mov %o1, %o4 | ||
75 | mov HV_FAST_RNG_DATA_READ, %o5 | ||
76 | ta HV_FAST_TRAP | ||
77 | retl | ||
78 | stx %o1, [%o4] | ||
79 | ENDPROC(sun4v_rng_data_read) | ||
diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c new file mode 100644 index 000000000000..5220f541df25 --- /dev/null +++ b/drivers/char/hw_random/n2-drv.c | |||
@@ -0,0 +1,771 @@ | |||
1 | /* n2-drv.c: Niagara-2 RNG driver. | ||
2 | * | ||
3 | * Copyright (C) 2008 David S. Miller <davem@davemloft.net> | ||
4 | */ | ||
5 | |||
6 | #include <linux/kernel.h> | ||
7 | #include <linux/module.h> | ||
8 | #include <linux/types.h> | ||
9 | #include <linux/delay.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/slab.h> | ||
12 | #include <linux/workqueue.h> | ||
13 | #include <linux/preempt.h> | ||
14 | #include <linux/hw_random.h> | ||
15 | |||
16 | #include <linux/of.h> | ||
17 | #include <linux/of_device.h> | ||
18 | |||
19 | #include <asm/hypervisor.h> | ||
20 | |||
21 | #include "n2rng.h" | ||
22 | |||
23 | #define DRV_MODULE_NAME "n2rng" | ||
24 | #define PFX DRV_MODULE_NAME ": " | ||
25 | #define DRV_MODULE_VERSION "0.1" | ||
26 | #define DRV_MODULE_RELDATE "May 15, 2008" | ||
27 | |||
28 | static char version[] __devinitdata = | ||
29 | DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; | ||
30 | |||
31 | MODULE_AUTHOR("David S. Miller (davem@davemloft.net)"); | ||
32 | MODULE_DESCRIPTION("Niagara2 RNG driver"); | ||
33 | MODULE_LICENSE("GPL"); | ||
34 | MODULE_VERSION(DRV_MODULE_VERSION); | ||
35 | |||
36 | /* The Niagara2 RNG provides a 64-bit read-only random number | ||
37 | * register, plus a control register. Access to the RNG is | ||
38 | * virtualized through the hypervisor so that both guests and control | ||
39 | * nodes can access the device. | ||
40 | * | ||
41 | * The entropy source consists of raw entropy sources, each | ||
42 | * constructed from a voltage controlled oscillator whose phase is | ||
43 | * jittered by thermal noise sources. | ||
44 | * | ||
45 | * The oscillator in each of the three raw entropy sources run at | ||
46 | * different frequencies. Normally, all three generator outputs are | ||
47 | * gathered, xored together, and fed into a CRC circuit, the output of | ||
48 | * which is the 64-bit read-only register. | ||
49 | * | ||
50 | * Some time is necessary for all the necessary entropy to build up | ||
51 | * such that a full 64-bits of entropy are available in the register. | ||
52 | * In normal operating mode (RNG_CTL_LFSR is set), the chip implements | ||
53 | * an interlock which blocks register reads until sufficient entropy | ||
54 | * is available. | ||
55 | * | ||
56 | * A control register is provided for adjusting various aspects of RNG | ||
57 | * operation, and to enable diagnostic modes. Each of the three raw | ||
58 | * entropy sources has an enable bit (RNG_CTL_ES{1,2,3}). Also | ||
59 | * provided are fields for controlling the minimum time in cycles | ||
60 | * between read accesses to the register (RNG_CTL_WAIT, this controls | ||
61 | * the interlock described in the previous paragraph). | ||
62 | * | ||
63 | * The standard setting is to have the mode bit (RNG_CTL_LFSR) set, | ||
64 | * all three entropy sources enabled, and the interlock time set | ||
65 | * appropriately. | ||
66 | * | ||
67 | * The CRC polynomial used by the chip is: | ||
68 | * | ||
69 | * P(X) = x64 + x61 + x57 + x56 + x52 + x51 + x50 + x48 + x47 + x46 + | ||
70 | * x43 + x42 + x41 + x39 + x38 + x37 + x35 + x32 + x28 + x25 + | ||
71 | * x22 + x21 + x17 + x15 + x13 + x12 + x11 + x7 + x5 + x + 1 | ||
72 | * | ||
73 | * The RNG_CTL_VCO value of each noise cell must be programmed | ||
74 | * seperately. This is why 4 control register values must be provided | ||
75 | * to the hypervisor. During a write, the hypervisor writes them all, | ||
76 | * one at a time, to the actual RNG_CTL register. The first three | ||
77 | * values are used to setup the desired RNG_CTL_VCO for each entropy | ||
78 | * source, for example: | ||
79 | * | ||
80 | * control 0: (1 << RNG_CTL_VCO_SHIFT) | RNG_CTL_ES1 | ||
81 | * control 1: (2 << RNG_CTL_VCO_SHIFT) | RNG_CTL_ES2 | ||
82 | * control 2: (3 << RNG_CTL_VCO_SHIFT) | RNG_CTL_ES3 | ||
83 | * | ||
84 | * And then the fourth value sets the final chip state and enables | ||
85 | * desired. | ||
86 | */ | ||
87 | |||
88 | static int n2rng_hv_err_trans(unsigned long hv_err) | ||
89 | { | ||
90 | switch (hv_err) { | ||
91 | case HV_EOK: | ||
92 | return 0; | ||
93 | case HV_EWOULDBLOCK: | ||
94 | return -EAGAIN; | ||
95 | case HV_ENOACCESS: | ||
96 | return -EPERM; | ||
97 | case HV_EIO: | ||
98 | return -EIO; | ||
99 | case HV_EBUSY: | ||
100 | return -EBUSY; | ||
101 | case HV_EBADALIGN: | ||
102 | case HV_ENORADDR: | ||
103 | return -EFAULT; | ||
104 | default: | ||
105 | return -EINVAL; | ||
106 | } | ||
107 | } | ||
108 | |||
109 | static unsigned long n2rng_generic_read_control_v2(unsigned long ra, | ||
110 | unsigned long unit) | ||
111 | { | ||
112 | unsigned long hv_err, state, ticks, watchdog_delta, watchdog_status; | ||
113 | int block = 0, busy = 0; | ||
114 | |||
115 | while (1) { | ||
116 | hv_err = sun4v_rng_ctl_read_v2(ra, unit, &state, | ||
117 | &ticks, | ||
118 | &watchdog_delta, | ||
119 | &watchdog_status); | ||
120 | if (hv_err == HV_EOK) | ||
121 | break; | ||
122 | |||
123 | if (hv_err == HV_EBUSY) { | ||
124 | if (++busy >= N2RNG_BUSY_LIMIT) | ||
125 | break; | ||
126 | |||
127 | udelay(1); | ||
128 | } else if (hv_err == HV_EWOULDBLOCK) { | ||
129 | if (++block >= N2RNG_BLOCK_LIMIT) | ||
130 | break; | ||
131 | |||
132 | __delay(ticks); | ||
133 | } else | ||
134 | break; | ||
135 | } | ||
136 | |||
137 | return hv_err; | ||
138 | } | ||
139 | |||
140 | /* In multi-socket situations, the hypervisor might need to | ||
141 | * queue up the RNG control register write if it's for a unit | ||
142 | * that is on a cpu socket other than the one we are executing on. | ||
143 | * | ||
144 | * We poll here waiting for a successful read of that control | ||
145 | * register to make sure the write has been actually performed. | ||
146 | */ | ||
147 | static unsigned long n2rng_control_settle_v2(struct n2rng *np, int unit) | ||
148 | { | ||
149 | unsigned long ra = __pa(&np->scratch_control[0]); | ||
150 | |||
151 | return n2rng_generic_read_control_v2(ra, unit); | ||
152 | } | ||
153 | |||
154 | static unsigned long n2rng_write_ctl_one(struct n2rng *np, int unit, | ||
155 | unsigned long state, | ||
156 | unsigned long control_ra, | ||
157 | unsigned long watchdog_timeout, | ||
158 | unsigned long *ticks) | ||
159 | { | ||
160 | unsigned long hv_err; | ||
161 | |||
162 | if (np->hvapi_major == 1) { | ||
163 | hv_err = sun4v_rng_ctl_write_v1(control_ra, state, | ||
164 | watchdog_timeout, ticks); | ||
165 | } else { | ||
166 | hv_err = sun4v_rng_ctl_write_v2(control_ra, state, | ||
167 | watchdog_timeout, unit); | ||
168 | if (hv_err == HV_EOK) | ||
169 | hv_err = n2rng_control_settle_v2(np, unit); | ||
170 | *ticks = N2RNG_ACCUM_CYCLES_DEFAULT; | ||
171 | } | ||
172 | |||
173 | return hv_err; | ||
174 | } | ||
175 | |||
176 | static int n2rng_generic_read_data(unsigned long data_ra) | ||
177 | { | ||
178 | unsigned long ticks, hv_err; | ||
179 | int block = 0, hcheck = 0; | ||
180 | |||
181 | while (1) { | ||
182 | hv_err = sun4v_rng_data_read(data_ra, &ticks); | ||
183 | if (hv_err == HV_EOK) | ||
184 | return 0; | ||
185 | |||
186 | if (hv_err == HV_EWOULDBLOCK) { | ||
187 | if (++block >= N2RNG_BLOCK_LIMIT) | ||
188 | return -EWOULDBLOCK; | ||
189 | __delay(ticks); | ||
190 | } else if (hv_err == HV_ENOACCESS) { | ||
191 | return -EPERM; | ||
192 | } else if (hv_err == HV_EIO) { | ||
193 | if (++hcheck >= N2RNG_HCHECK_LIMIT) | ||
194 | return -EIO; | ||
195 | udelay(10000); | ||
196 | } else | ||
197 | return -ENODEV; | ||
198 | } | ||
199 | } | ||
200 | |||
201 | static unsigned long n2rng_read_diag_data_one(struct n2rng *np, | ||
202 | unsigned long unit, | ||
203 | unsigned long data_ra, | ||
204 | unsigned long data_len, | ||
205 | unsigned long *ticks) | ||
206 | { | ||
207 | unsigned long hv_err; | ||
208 | |||
209 | if (np->hvapi_major == 1) { | ||
210 | hv_err = sun4v_rng_data_read_diag_v1(data_ra, data_len, ticks); | ||
211 | } else { | ||
212 | hv_err = sun4v_rng_data_read_diag_v2(data_ra, data_len, | ||
213 | unit, ticks); | ||
214 | if (!*ticks) | ||
215 | *ticks = N2RNG_ACCUM_CYCLES_DEFAULT; | ||
216 | } | ||
217 | return hv_err; | ||
218 | } | ||
219 | |||
220 | static int n2rng_generic_read_diag_data(struct n2rng *np, | ||
221 | unsigned long unit, | ||
222 | unsigned long data_ra, | ||
223 | unsigned long data_len) | ||
224 | { | ||
225 | unsigned long ticks, hv_err; | ||
226 | int block = 0; | ||
227 | |||
228 | while (1) { | ||
229 | hv_err = n2rng_read_diag_data_one(np, unit, | ||
230 | data_ra, data_len, | ||
231 | &ticks); | ||
232 | if (hv_err == HV_EOK) | ||
233 | return 0; | ||
234 | |||
235 | if (hv_err == HV_EWOULDBLOCK) { | ||
236 | if (++block >= N2RNG_BLOCK_LIMIT) | ||
237 | return -EWOULDBLOCK; | ||
238 | __delay(ticks); | ||
239 | } else if (hv_err == HV_ENOACCESS) { | ||
240 | return -EPERM; | ||
241 | } else if (hv_err == HV_EIO) { | ||
242 | return -EIO; | ||
243 | } else | ||
244 | return -ENODEV; | ||
245 | } | ||
246 | } | ||
247 | |||
248 | |||
249 | static int n2rng_generic_write_control(struct n2rng *np, | ||
250 | unsigned long control_ra, | ||
251 | unsigned long unit, | ||
252 | unsigned long state) | ||
253 | { | ||
254 | unsigned long hv_err, ticks; | ||
255 | int block = 0, busy = 0; | ||
256 | |||
257 | while (1) { | ||
258 | hv_err = n2rng_write_ctl_one(np, unit, state, control_ra, | ||
259 | np->wd_timeo, &ticks); | ||
260 | if (hv_err == HV_EOK) | ||
261 | return 0; | ||
262 | |||
263 | if (hv_err == HV_EWOULDBLOCK) { | ||
264 | if (++block >= N2RNG_BLOCK_LIMIT) | ||
265 | return -EWOULDBLOCK; | ||
266 | __delay(ticks); | ||
267 | } else if (hv_err == HV_EBUSY) { | ||
268 | if (++busy >= N2RNG_BUSY_LIMIT) | ||
269 | return -EBUSY; | ||
270 | udelay(1); | ||
271 | } else | ||
272 | return -ENODEV; | ||
273 | } | ||
274 | } | ||
275 | |||
276 | /* Just try to see if we can successfully access the control register | ||
277 | * of the RNG on the domain on which we are currently executing. | ||
278 | */ | ||
279 | static int n2rng_try_read_ctl(struct n2rng *np) | ||
280 | { | ||
281 | unsigned long hv_err; | ||
282 | unsigned long x; | ||
283 | |||
284 | if (np->hvapi_major == 1) { | ||
285 | hv_err = sun4v_rng_get_diag_ctl(); | ||
286 | } else { | ||
287 | /* We purposefully give invalid arguments, HV_NOACCESS | ||
288 | * is higher priority than the errors we'd get from | ||
289 | * these other cases, and that's the error we are | ||
290 | * truly interested in. | ||
291 | */ | ||
292 | hv_err = sun4v_rng_ctl_read_v2(0UL, ~0UL, &x, &x, &x, &x); | ||
293 | switch (hv_err) { | ||
294 | case HV_EWOULDBLOCK: | ||
295 | case HV_ENOACCESS: | ||
296 | break; | ||
297 | default: | ||
298 | hv_err = HV_EOK; | ||
299 | break; | ||
300 | } | ||
301 | } | ||
302 | |||
303 | return n2rng_hv_err_trans(hv_err); | ||
304 | } | ||
305 | |||
306 | #define CONTROL_DEFAULT_BASE \ | ||
307 | ((2 << RNG_CTL_ASEL_SHIFT) | \ | ||
308 | (N2RNG_ACCUM_CYCLES_DEFAULT << RNG_CTL_WAIT_SHIFT) | \ | ||
309 | RNG_CTL_LFSR) | ||
310 | |||
311 | #define CONTROL_DEFAULT_0 \ | ||
312 | (CONTROL_DEFAULT_BASE | \ | ||
313 | (1 << RNG_CTL_VCO_SHIFT) | \ | ||
314 | RNG_CTL_ES1) | ||
315 | #define CONTROL_DEFAULT_1 \ | ||
316 | (CONTROL_DEFAULT_BASE | \ | ||
317 | (2 << RNG_CTL_VCO_SHIFT) | \ | ||
318 | RNG_CTL_ES2) | ||
319 | #define CONTROL_DEFAULT_2 \ | ||
320 | (CONTROL_DEFAULT_BASE | \ | ||
321 | (3 << RNG_CTL_VCO_SHIFT) | \ | ||
322 | RNG_CTL_ES3) | ||
323 | #define CONTROL_DEFAULT_3 \ | ||
324 | (CONTROL_DEFAULT_BASE | \ | ||
325 | RNG_CTL_ES1 | RNG_CTL_ES2 | RNG_CTL_ES3) | ||
326 | |||
327 | static void n2rng_control_swstate_init(struct n2rng *np) | ||
328 | { | ||
329 | int i; | ||
330 | |||
331 | np->flags |= N2RNG_FLAG_CONTROL; | ||
332 | |||
333 | np->health_check_sec = N2RNG_HEALTH_CHECK_SEC_DEFAULT; | ||
334 | np->accum_cycles = N2RNG_ACCUM_CYCLES_DEFAULT; | ||
335 | np->wd_timeo = N2RNG_WD_TIMEO_DEFAULT; | ||
336 | |||
337 | for (i = 0; i < np->num_units; i++) { | ||
338 | struct n2rng_unit *up = &np->units[i]; | ||
339 | |||
340 | up->control[0] = CONTROL_DEFAULT_0; | ||
341 | up->control[1] = CONTROL_DEFAULT_1; | ||
342 | up->control[2] = CONTROL_DEFAULT_2; | ||
343 | up->control[3] = CONTROL_DEFAULT_3; | ||
344 | } | ||
345 | |||
346 | np->hv_state = HV_RNG_STATE_UNCONFIGURED; | ||
347 | } | ||
348 | |||
349 | static int n2rng_grab_diag_control(struct n2rng *np) | ||
350 | { | ||
351 | int i, busy_count, err = -ENODEV; | ||
352 | |||
353 | busy_count = 0; | ||
354 | for (i = 0; i < 100; i++) { | ||
355 | err = n2rng_try_read_ctl(np); | ||
356 | if (err != -EAGAIN) | ||
357 | break; | ||
358 | |||
359 | if (++busy_count > 100) { | ||
360 | dev_err(&np->op->dev, | ||
361 | "Grab diag control timeout.\n"); | ||
362 | return -ENODEV; | ||
363 | } | ||
364 | |||
365 | udelay(1); | ||
366 | } | ||
367 | |||
368 | return err; | ||
369 | } | ||
370 | |||
371 | static int n2rng_init_control(struct n2rng *np) | ||
372 | { | ||
373 | int err = n2rng_grab_diag_control(np); | ||
374 | |||
375 | /* Not in the control domain, that's OK we are only a consumer | ||
376 | * of the RNG data, we don't setup and program it. | ||
377 | */ | ||
378 | if (err == -EPERM) | ||
379 | return 0; | ||
380 | if (err) | ||
381 | return err; | ||
382 | |||
383 | n2rng_control_swstate_init(np); | ||
384 | |||
385 | return 0; | ||
386 | } | ||
387 | |||
388 | static int n2rng_data_read(struct hwrng *rng, u32 *data) | ||
389 | { | ||
390 | struct n2rng *np = (struct n2rng *) rng->priv; | ||
391 | unsigned long ra = __pa(&np->test_data); | ||
392 | int len; | ||
393 | |||
394 | if (!(np->flags & N2RNG_FLAG_READY)) { | ||
395 | len = 0; | ||
396 | } else if (np->flags & N2RNG_FLAG_BUFFER_VALID) { | ||
397 | np->flags &= ~N2RNG_FLAG_BUFFER_VALID; | ||
398 | *data = np->buffer; | ||
399 | len = 4; | ||
400 | } else { | ||
401 | int err = n2rng_generic_read_data(ra); | ||
402 | if (!err) { | ||
403 | np->buffer = np->test_data >> 32; | ||
404 | *data = np->test_data & 0xffffffff; | ||
405 | len = 4; | ||
406 | } else { | ||
407 | dev_err(&np->op->dev, "RNG error, restesting\n"); | ||
408 | np->flags &= ~N2RNG_FLAG_READY; | ||
409 | if (!(np->flags & N2RNG_FLAG_SHUTDOWN)) | ||
410 | schedule_delayed_work(&np->work, 0); | ||
411 | len = 0; | ||
412 | } | ||
413 | } | ||
414 | |||
415 | return len; | ||
416 | } | ||
417 | |||
418 | /* On a guest node, just make sure we can read random data properly. | ||
419 | * If a control node reboots or reloads it's n2rng driver, this won't | ||
420 | * work during that time. So we have to keep probing until the device | ||
421 | * becomes usable. | ||
422 | */ | ||
423 | static int n2rng_guest_check(struct n2rng *np) | ||
424 | { | ||
425 | unsigned long ra = __pa(&np->test_data); | ||
426 | |||
427 | return n2rng_generic_read_data(ra); | ||
428 | } | ||
429 | |||
430 | static int n2rng_entropy_diag_read(struct n2rng *np, unsigned long unit, | ||
431 | u64 *pre_control, u64 pre_state, | ||
432 | u64 *buffer, unsigned long buf_len, | ||
433 | u64 *post_control, u64 post_state) | ||
434 | { | ||
435 | unsigned long post_ctl_ra = __pa(post_control); | ||
436 | unsigned long pre_ctl_ra = __pa(pre_control); | ||
437 | unsigned long buffer_ra = __pa(buffer); | ||
438 | int err; | ||
439 | |||
440 | err = n2rng_generic_write_control(np, pre_ctl_ra, unit, pre_state); | ||
441 | if (err) | ||
442 | return err; | ||
443 | |||
444 | err = n2rng_generic_read_diag_data(np, unit, | ||
445 | buffer_ra, buf_len); | ||
446 | |||
447 | (void) n2rng_generic_write_control(np, post_ctl_ra, unit, | ||
448 | post_state); | ||
449 | |||
450 | return err; | ||
451 | } | ||
452 | |||
453 | static u64 advance_polynomial(u64 poly, u64 val, int count) | ||
454 | { | ||
455 | int i; | ||
456 | |||
457 | for (i = 0; i < count; i++) { | ||
458 | int highbit_set = ((s64)val < 0); | ||
459 | |||
460 | val <<= 1; | ||
461 | if (highbit_set) | ||
462 | val ^= poly; | ||
463 | } | ||
464 | |||
465 | return val; | ||
466 | } | ||
467 | |||
468 | static int n2rng_test_buffer_find(struct n2rng *np, u64 val) | ||
469 | { | ||
470 | int i, count = 0; | ||
471 | |||
472 | /* Purposefully skip over the first word. */ | ||
473 | for (i = 1; i < SELFTEST_BUFFER_WORDS; i++) { | ||
474 | if (np->test_buffer[i] == val) | ||
475 | count++; | ||
476 | } | ||
477 | return count; | ||
478 | } | ||
479 | |||
480 | static void n2rng_dump_test_buffer(struct n2rng *np) | ||
481 | { | ||
482 | int i; | ||
483 | |||
484 | for (i = 0; i < SELFTEST_BUFFER_WORDS; i++) | ||
485 | dev_err(&np->op->dev, "Test buffer slot %d [0x%016lx]\n", | ||
486 | i, np->test_buffer[i]); | ||
487 | } | ||
488 | |||
489 | static int n2rng_check_selftest_buffer(struct n2rng *np, unsigned long unit) | ||
490 | { | ||
491 | u64 val = SELFTEST_VAL; | ||
492 | int err, matches, limit; | ||
493 | |||
494 | matches = 0; | ||
495 | for (limit = 0; limit < SELFTEST_LOOPS_MAX; limit++) { | ||
496 | matches += n2rng_test_buffer_find(np, val); | ||
497 | if (matches >= SELFTEST_MATCH_GOAL) | ||
498 | break; | ||
499 | val = advance_polynomial(SELFTEST_POLY, val, 1); | ||
500 | } | ||
501 | |||
502 | err = 0; | ||
503 | if (limit >= SELFTEST_LOOPS_MAX) { | ||
504 | err = -ENODEV; | ||
505 | dev_err(&np->op->dev, "Selftest failed on unit %lu\n", unit); | ||
506 | n2rng_dump_test_buffer(np); | ||
507 | } else | ||
508 | dev_info(&np->op->dev, "Selftest passed on unit %lu\n", unit); | ||
509 | |||
510 | return err; | ||
511 | } | ||
512 | |||
513 | static int n2rng_control_selftest(struct n2rng *np, unsigned long unit) | ||
514 | { | ||
515 | int err; | ||
516 | |||
517 | np->test_control[0] = (0x2 << RNG_CTL_ASEL_SHIFT); | ||
518 | np->test_control[1] = (0x2 << RNG_CTL_ASEL_SHIFT); | ||
519 | np->test_control[2] = (0x2 << RNG_CTL_ASEL_SHIFT); | ||
520 | np->test_control[3] = ((0x2 << RNG_CTL_ASEL_SHIFT) | | ||
521 | RNG_CTL_LFSR | | ||
522 | ((SELFTEST_TICKS - 2) << RNG_CTL_WAIT_SHIFT)); | ||
523 | |||
524 | |||
525 | err = n2rng_entropy_diag_read(np, unit, np->test_control, | ||
526 | HV_RNG_STATE_HEALTHCHECK, | ||
527 | np->test_buffer, | ||
528 | sizeof(np->test_buffer), | ||
529 | &np->units[unit].control[0], | ||
530 | np->hv_state); | ||
531 | if (err) | ||
532 | return err; | ||
533 | |||
534 | return n2rng_check_selftest_buffer(np, unit); | ||
535 | } | ||
536 | |||
537 | static int n2rng_control_check(struct n2rng *np) | ||
538 | { | ||
539 | int i; | ||
540 | |||
541 | for (i = 0; i < np->num_units; i++) { | ||
542 | int err = n2rng_control_selftest(np, i); | ||
543 | if (err) | ||
544 | return err; | ||
545 | } | ||
546 | return 0; | ||
547 | } | ||
548 | |||
549 | /* The sanity checks passed, install the final configuration into the | ||
550 | * chip, it's ready to use. | ||
551 | */ | ||
552 | static int n2rng_control_configure_units(struct n2rng *np) | ||
553 | { | ||
554 | int unit, err; | ||
555 | |||
556 | err = 0; | ||
557 | for (unit = 0; unit < np->num_units; unit++) { | ||
558 | struct n2rng_unit *up = &np->units[unit]; | ||
559 | unsigned long ctl_ra = __pa(&up->control[0]); | ||
560 | int esrc; | ||
561 | u64 base; | ||
562 | |||
563 | base = ((np->accum_cycles << RNG_CTL_WAIT_SHIFT) | | ||
564 | (2 << RNG_CTL_ASEL_SHIFT) | | ||
565 | RNG_CTL_LFSR); | ||
566 | |||
567 | /* XXX This isn't the best. We should fetch a bunch | ||
568 | * XXX of words using each entropy source combined XXX | ||
569 | * with each VCO setting, and see which combinations | ||
570 | * XXX give the best random data. | ||
571 | */ | ||
572 | for (esrc = 0; esrc < 3; esrc++) | ||
573 | up->control[esrc] = base | | ||
574 | (esrc << RNG_CTL_VCO_SHIFT) | | ||
575 | (RNG_CTL_ES1 << esrc); | ||
576 | |||
577 | up->control[3] = base | | ||
578 | (RNG_CTL_ES1 | RNG_CTL_ES2 | RNG_CTL_ES3); | ||
579 | |||
580 | err = n2rng_generic_write_control(np, ctl_ra, unit, | ||
581 | HV_RNG_STATE_CONFIGURED); | ||
582 | if (err) | ||
583 | break; | ||
584 | } | ||
585 | |||
586 | return err; | ||
587 | } | ||
588 | |||
589 | static void n2rng_work(struct work_struct *work) | ||
590 | { | ||
591 | struct n2rng *np = container_of(work, struct n2rng, work.work); | ||
592 | int err = 0; | ||
593 | |||
594 | if (!(np->flags & N2RNG_FLAG_CONTROL)) { | ||
595 | err = n2rng_guest_check(np); | ||
596 | } else { | ||
597 | preempt_disable(); | ||
598 | err = n2rng_control_check(np); | ||
599 | preempt_enable(); | ||
600 | |||
601 | if (!err) | ||
602 | err = n2rng_control_configure_units(np); | ||
603 | } | ||
604 | |||
605 | if (!err) { | ||
606 | np->flags |= N2RNG_FLAG_READY; | ||
607 | dev_info(&np->op->dev, "RNG ready\n"); | ||
608 | } | ||
609 | |||
610 | if (err && !(np->flags & N2RNG_FLAG_SHUTDOWN)) | ||
611 | schedule_delayed_work(&np->work, HZ * 2); | ||
612 | } | ||
613 | |||
614 | static void __devinit n2rng_driver_version(void) | ||
615 | { | ||
616 | static int n2rng_version_printed; | ||
617 | |||
618 | if (n2rng_version_printed++ == 0) | ||
619 | pr_info("%s", version); | ||
620 | } | ||
621 | |||
622 | static int __devinit n2rng_probe(struct of_device *op, | ||
623 | const struct of_device_id *match) | ||
624 | { | ||
625 | int victoria_falls = (match->data != NULL); | ||
626 | int err = -ENOMEM; | ||
627 | struct n2rng *np; | ||
628 | |||
629 | n2rng_driver_version(); | ||
630 | |||
631 | np = kzalloc(sizeof(*np), GFP_KERNEL); | ||
632 | if (!np) | ||
633 | goto out; | ||
634 | np->op = op; | ||
635 | |||
636 | INIT_DELAYED_WORK(&np->work, n2rng_work); | ||
637 | |||
638 | if (victoria_falls) | ||
639 | np->flags |= N2RNG_FLAG_VF; | ||
640 | |||
641 | err = -ENODEV; | ||
642 | np->hvapi_major = 2; | ||
643 | if (sun4v_hvapi_register(HV_GRP_RNG, | ||
644 | np->hvapi_major, | ||
645 | &np->hvapi_minor)) { | ||
646 | np->hvapi_major = 1; | ||
647 | if (sun4v_hvapi_register(HV_GRP_RNG, | ||
648 | np->hvapi_major, | ||
649 | &np->hvapi_minor)) { | ||
650 | dev_err(&op->dev, "Cannot register suitable " | ||
651 | "HVAPI version.\n"); | ||
652 | goto out_free; | ||
653 | } | ||
654 | } | ||
655 | |||
656 | if (np->flags & N2RNG_FLAG_VF) { | ||
657 | if (np->hvapi_major < 2) { | ||
658 | dev_err(&op->dev, "VF RNG requires HVAPI major " | ||
659 | "version 2 or later, got %lu\n", | ||
660 | np->hvapi_major); | ||
661 | goto out_hvapi_unregister; | ||
662 | } | ||
663 | np->num_units = of_getintprop_default(op->node, | ||
664 | "rng-#units", 0); | ||
665 | if (!np->num_units) { | ||
666 | dev_err(&op->dev, "VF RNG lacks rng-#units property\n"); | ||
667 | goto out_hvapi_unregister; | ||
668 | } | ||
669 | } else | ||
670 | np->num_units = 1; | ||
671 | |||
672 | dev_info(&op->dev, "Registered RNG HVAPI major %lu minor %lu\n", | ||
673 | np->hvapi_major, np->hvapi_minor); | ||
674 | |||
675 | np->units = kzalloc(sizeof(struct n2rng_unit) * np->num_units, | ||
676 | GFP_KERNEL); | ||
677 | err = -ENOMEM; | ||
678 | if (!np->units) | ||
679 | goto out_hvapi_unregister; | ||
680 | |||
681 | err = n2rng_init_control(np); | ||
682 | if (err) | ||
683 | goto out_free_units; | ||
684 | |||
685 | dev_info(&op->dev, "Found %s RNG, units: %d\n", | ||
686 | ((np->flags & N2RNG_FLAG_VF) ? | ||
687 | "Victoria Falls" : "Niagara2"), | ||
688 | np->num_units); | ||
689 | |||
690 | np->hwrng.name = "n2rng"; | ||
691 | np->hwrng.data_read = n2rng_data_read; | ||
692 | np->hwrng.priv = (unsigned long) np; | ||
693 | |||
694 | err = hwrng_register(&np->hwrng); | ||
695 | if (err) | ||
696 | goto out_free_units; | ||
697 | |||
698 | dev_set_drvdata(&op->dev, np); | ||
699 | |||
700 | schedule_delayed_work(&np->work, 0); | ||
701 | |||
702 | return 0; | ||
703 | |||
704 | out_free_units: | ||
705 | kfree(np->units); | ||
706 | np->units = NULL; | ||
707 | |||
708 | out_hvapi_unregister: | ||
709 | sun4v_hvapi_unregister(HV_GRP_RNG); | ||
710 | |||
711 | out_free: | ||
712 | kfree(np); | ||
713 | out: | ||
714 | return err; | ||
715 | } | ||
716 | |||
717 | static int __devexit n2rng_remove(struct of_device *op) | ||
718 | { | ||
719 | struct n2rng *np = dev_get_drvdata(&op->dev); | ||
720 | |||
721 | np->flags |= N2RNG_FLAG_SHUTDOWN; | ||
722 | |||
723 | cancel_delayed_work_sync(&np->work); | ||
724 | |||
725 | hwrng_unregister(&np->hwrng); | ||
726 | |||
727 | sun4v_hvapi_unregister(HV_GRP_RNG); | ||
728 | |||
729 | kfree(np->units); | ||
730 | np->units = NULL; | ||
731 | |||
732 | kfree(np); | ||
733 | |||
734 | dev_set_drvdata(&op->dev, NULL); | ||
735 | |||
736 | return 0; | ||
737 | } | ||
738 | |||
739 | static struct of_device_id n2rng_match[] = { | ||
740 | { | ||
741 | .name = "random-number-generator", | ||
742 | .compatible = "SUNW,n2-rng", | ||
743 | }, | ||
744 | { | ||
745 | .name = "random-number-generator", | ||
746 | .compatible = "SUNW,vf-rng", | ||
747 | .data = (void *) 1, | ||
748 | }, | ||
749 | {}, | ||
750 | }; | ||
751 | MODULE_DEVICE_TABLE(of, n2rng_match); | ||
752 | |||
753 | static struct of_platform_driver n2rng_driver = { | ||
754 | .name = "n2rng", | ||
755 | .match_table = n2rng_match, | ||
756 | .probe = n2rng_probe, | ||
757 | .remove = __devexit_p(n2rng_remove), | ||
758 | }; | ||
759 | |||
760 | static int __init n2rng_init(void) | ||
761 | { | ||
762 | return of_register_driver(&n2rng_driver, &of_bus_type); | ||
763 | } | ||
764 | |||
765 | static void __exit n2rng_exit(void) | ||
766 | { | ||
767 | of_unregister_driver(&n2rng_driver); | ||
768 | } | ||
769 | |||
770 | module_init(n2rng_init); | ||
771 | module_exit(n2rng_exit); | ||
diff --git a/drivers/char/hw_random/n2rng.h b/drivers/char/hw_random/n2rng.h new file mode 100644 index 000000000000..a2b81e7bfc18 --- /dev/null +++ b/drivers/char/hw_random/n2rng.h | |||
@@ -0,0 +1,118 @@ | |||
1 | /* n2rng.h: Niagara2 RNG defines. | ||
2 | * | ||
3 | * Copyright (C) 2008 David S. Miller <davem@davemloft.net> | ||
4 | */ | ||
5 | |||
6 | #ifndef _N2RNG_H | ||
7 | #define _N2RNG_H | ||
8 | |||
9 | #define RNG_CTL_WAIT 0x0000000001fffe00ULL /* Minimum wait time */ | ||
10 | #define RNG_CTL_WAIT_SHIFT 9 | ||
11 | #define RNG_CTL_BYPASS 0x0000000000000100ULL /* VCO voltage source */ | ||
12 | #define RNG_CTL_VCO 0x00000000000000c0ULL /* VCO rate control */ | ||
13 | #define RNG_CTL_VCO_SHIFT 6 | ||
14 | #define RNG_CTL_ASEL 0x0000000000000030ULL /* Analog MUX select */ | ||
15 | #define RNG_CTL_ASEL_SHIFT 4 | ||
16 | #define RNG_CTL_LFSR 0x0000000000000008ULL /* Use LFSR or plain shift */ | ||
17 | #define RNG_CTL_ES3 0x0000000000000004ULL /* Enable entropy source 3 */ | ||
18 | #define RNG_CTL_ES2 0x0000000000000002ULL /* Enable entropy source 2 */ | ||
19 | #define RNG_CTL_ES1 0x0000000000000001ULL /* Enable entropy source 1 */ | ||
20 | |||
21 | #define HV_FAST_RNG_GET_DIAG_CTL 0x130 | ||
22 | #define HV_FAST_RNG_CTL_READ 0x131 | ||
23 | #define HV_FAST_RNG_CTL_WRITE 0x132 | ||
24 | #define HV_FAST_RNG_DATA_READ_DIAG 0x133 | ||
25 | #define HV_FAST_RNG_DATA_READ 0x134 | ||
26 | |||
27 | #define HV_RNG_STATE_UNCONFIGURED 0 | ||
28 | #define HV_RNG_STATE_CONFIGURED 1 | ||
29 | #define HV_RNG_STATE_HEALTHCHECK 2 | ||
30 | #define HV_RNG_STATE_ERROR 3 | ||
31 | |||
32 | #define HV_RNG_NUM_CONTROL 4 | ||
33 | |||
34 | #ifndef __ASSEMBLY__ | ||
35 | extern unsigned long sun4v_rng_get_diag_ctl(void); | ||
36 | extern unsigned long sun4v_rng_ctl_read_v1(unsigned long ctl_regs_ra, | ||
37 | unsigned long *state, | ||
38 | unsigned long *tick_delta); | ||
39 | extern unsigned long sun4v_rng_ctl_read_v2(unsigned long ctl_regs_ra, | ||
40 | unsigned long unit, | ||
41 | unsigned long *state, | ||
42 | unsigned long *tick_delta, | ||
43 | unsigned long *watchdog, | ||
44 | unsigned long *write_status); | ||
45 | extern unsigned long sun4v_rng_ctl_write_v1(unsigned long ctl_regs_ra, | ||
46 | unsigned long state, | ||
47 | unsigned long write_timeout, | ||
48 | unsigned long *tick_delta); | ||
49 | extern unsigned long sun4v_rng_ctl_write_v2(unsigned long ctl_regs_ra, | ||
50 | unsigned long state, | ||
51 | unsigned long write_timeout, | ||
52 | unsigned long unit); | ||
53 | extern unsigned long sun4v_rng_data_read_diag_v1(unsigned long data_ra, | ||
54 | unsigned long len, | ||
55 | unsigned long *tick_delta); | ||
56 | extern unsigned long sun4v_rng_data_read_diag_v2(unsigned long data_ra, | ||
57 | unsigned long len, | ||
58 | unsigned long unit, | ||
59 | unsigned long *tick_delta); | ||
60 | extern unsigned long sun4v_rng_data_read(unsigned long data_ra, | ||
61 | unsigned long *tick_delta); | ||
62 | |||
63 | struct n2rng_unit { | ||
64 | u64 control[HV_RNG_NUM_CONTROL]; | ||
65 | }; | ||
66 | |||
67 | struct n2rng { | ||
68 | struct of_device *op; | ||
69 | |||
70 | unsigned long flags; | ||
71 | #define N2RNG_FLAG_VF 0x00000001 /* Victoria Falls RNG, else N2 */ | ||
72 | #define N2RNG_FLAG_CONTROL 0x00000002 /* Operating in control domain */ | ||
73 | #define N2RNG_FLAG_READY 0x00000008 /* Ready for hw-rng layer */ | ||
74 | #define N2RNG_FLAG_SHUTDOWN 0x00000010 /* Driver unregistering */ | ||
75 | #define N2RNG_FLAG_BUFFER_VALID 0x00000020 /* u32 buffer holds valid data */ | ||
76 | |||
77 | int num_units; | ||
78 | struct n2rng_unit *units; | ||
79 | |||
80 | struct hwrng hwrng; | ||
81 | u32 buffer; | ||
82 | |||
83 | /* Registered hypervisor group API major and minor version. */ | ||
84 | unsigned long hvapi_major; | ||
85 | unsigned long hvapi_minor; | ||
86 | |||
87 | struct delayed_work work; | ||
88 | |||
89 | unsigned long hv_state; /* HV_RNG_STATE_foo */ | ||
90 | |||
91 | unsigned long health_check_sec; | ||
92 | unsigned long accum_cycles; | ||
93 | unsigned long wd_timeo; | ||
94 | #define N2RNG_HEALTH_CHECK_SEC_DEFAULT 0 | ||
95 | #define N2RNG_ACCUM_CYCLES_DEFAULT 2048 | ||
96 | #define N2RNG_WD_TIMEO_DEFAULT 0 | ||
97 | |||
98 | u64 scratch_control[HV_RNG_NUM_CONTROL]; | ||
99 | |||
100 | #define SELFTEST_TICKS 38859 | ||
101 | #define SELFTEST_VAL ((u64)0xB8820C7BD387E32C) | ||
102 | #define SELFTEST_POLY ((u64)0x231DCEE91262B8A3) | ||
103 | #define SELFTEST_MATCH_GOAL 6 | ||
104 | #define SELFTEST_LOOPS_MAX 40000 | ||
105 | #define SELFTEST_BUFFER_WORDS 8 | ||
106 | |||
107 | u64 test_data; | ||
108 | u64 test_control[HV_RNG_NUM_CONTROL]; | ||
109 | u64 test_buffer[SELFTEST_BUFFER_WORDS]; | ||
110 | }; | ||
111 | |||
112 | #define N2RNG_BLOCK_LIMIT 60000 | ||
113 | #define N2RNG_BUSY_LIMIT 100 | ||
114 | #define N2RNG_HCHECK_LIMIT 100 | ||
115 | |||
116 | #endif /* !(__ASSEMBLY__) */ | ||
117 | |||
118 | #endif /* _N2RNG_H */ | ||
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index 6ef1c565705c..7930fba4bafc 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c | |||
@@ -598,7 +598,7 @@ static int stli_parsebrd(struct stlconf *confp, char **argp); | |||
598 | static int stli_open(struct tty_struct *tty, struct file *filp); | 598 | static int stli_open(struct tty_struct *tty, struct file *filp); |
599 | static void stli_close(struct tty_struct *tty, struct file *filp); | 599 | static void stli_close(struct tty_struct *tty, struct file *filp); |
600 | static int stli_write(struct tty_struct *tty, const unsigned char *buf, int count); | 600 | static int stli_write(struct tty_struct *tty, const unsigned char *buf, int count); |
601 | static void stli_putchar(struct tty_struct *tty, unsigned char ch); | 601 | static int stli_putchar(struct tty_struct *tty, unsigned char ch); |
602 | static void stli_flushchars(struct tty_struct *tty); | 602 | static void stli_flushchars(struct tty_struct *tty); |
603 | static int stli_writeroom(struct tty_struct *tty); | 603 | static int stli_writeroom(struct tty_struct *tty); |
604 | static int stli_charsinbuffer(struct tty_struct *tty); | 604 | static int stli_charsinbuffer(struct tty_struct *tty); |
@@ -826,7 +826,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp) | |||
826 | */ | 826 | */ |
827 | portp->port.tty = tty; | 827 | portp->port.tty = tty; |
828 | tty->driver_data = portp; | 828 | tty->driver_data = portp; |
829 | portp->refcount++; | 829 | portp->port.count++; |
830 | 830 | ||
831 | wait_event_interruptible(portp->raw_wait, | 831 | wait_event_interruptible(portp->raw_wait, |
832 | !test_bit(ST_INITIALIZING, &portp->state)); | 832 | !test_bit(ST_INITIALIZING, &portp->state)); |
@@ -888,9 +888,9 @@ static void stli_close(struct tty_struct *tty, struct file *filp) | |||
888 | spin_unlock_irqrestore(&stli_lock, flags); | 888 | spin_unlock_irqrestore(&stli_lock, flags); |
889 | return; | 889 | return; |
890 | } | 890 | } |
891 | if ((tty->count == 1) && (portp->refcount != 1)) | 891 | if ((tty->count == 1) && (portp->port.count != 1)) |
892 | portp->refcount = 1; | 892 | portp->port.count = 1; |
893 | if (portp->refcount-- > 1) { | 893 | if (portp->port.count-- > 1) { |
894 | spin_unlock_irqrestore(&stli_lock, flags); | 894 | spin_unlock_irqrestore(&stli_lock, flags); |
895 | return; | 895 | return; |
896 | } | 896 | } |
@@ -925,8 +925,8 @@ static void stli_close(struct tty_struct *tty, struct file *filp) | |||
925 | clear_bit(ST_TXBUSY, &portp->state); | 925 | clear_bit(ST_TXBUSY, &portp->state); |
926 | clear_bit(ST_RXSTOP, &portp->state); | 926 | clear_bit(ST_RXSTOP, &portp->state); |
927 | set_bit(TTY_IO_ERROR, &tty->flags); | 927 | set_bit(TTY_IO_ERROR, &tty->flags); |
928 | if (tty->ldisc.flush_buffer) | 928 | if (tty->ldisc.ops->flush_buffer) |
929 | (tty->ldisc.flush_buffer)(tty); | 929 | (tty->ldisc.ops->flush_buffer)(tty); |
930 | set_bit(ST_DOFLUSHRX, &portp->state); | 930 | set_bit(ST_DOFLUSHRX, &portp->state); |
931 | stli_flushbuffer(tty); | 931 | stli_flushbuffer(tty); |
932 | 932 | ||
@@ -1202,7 +1202,7 @@ static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct | |||
1202 | spin_lock_irqsave(&stli_lock, flags); | 1202 | spin_lock_irqsave(&stli_lock, flags); |
1203 | portp->openwaitcnt++; | 1203 | portp->openwaitcnt++; |
1204 | if (! tty_hung_up_p(filp)) | 1204 | if (! tty_hung_up_p(filp)) |
1205 | portp->refcount--; | 1205 | portp->port.count--; |
1206 | spin_unlock_irqrestore(&stli_lock, flags); | 1206 | spin_unlock_irqrestore(&stli_lock, flags); |
1207 | 1207 | ||
1208 | for (;;) { | 1208 | for (;;) { |
@@ -1231,7 +1231,7 @@ static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct | |||
1231 | 1231 | ||
1232 | spin_lock_irqsave(&stli_lock, flags); | 1232 | spin_lock_irqsave(&stli_lock, flags); |
1233 | if (! tty_hung_up_p(filp)) | 1233 | if (! tty_hung_up_p(filp)) |
1234 | portp->refcount++; | 1234 | portp->port.count++; |
1235 | portp->openwaitcnt--; | 1235 | portp->openwaitcnt--; |
1236 | spin_unlock_irqrestore(&stli_lock, flags); | 1236 | spin_unlock_irqrestore(&stli_lock, flags); |
1237 | 1237 | ||
@@ -1333,7 +1333,7 @@ static int stli_write(struct tty_struct *tty, const unsigned char *buf, int coun | |||
1333 | * first them do the new ports. | 1333 | * first them do the new ports. |
1334 | */ | 1334 | */ |
1335 | 1335 | ||
1336 | static void stli_putchar(struct tty_struct *tty, unsigned char ch) | 1336 | static int stli_putchar(struct tty_struct *tty, unsigned char ch) |
1337 | { | 1337 | { |
1338 | if (tty != stli_txcooktty) { | 1338 | if (tty != stli_txcooktty) { |
1339 | if (stli_txcooktty != NULL) | 1339 | if (stli_txcooktty != NULL) |
@@ -1342,6 +1342,7 @@ static void stli_putchar(struct tty_struct *tty, unsigned char ch) | |||
1342 | } | 1342 | } |
1343 | 1343 | ||
1344 | stli_txcookbuf[stli_txcooksize++] = ch; | 1344 | stli_txcookbuf[stli_txcooksize++] = ch; |
1345 | return 0; | ||
1345 | } | 1346 | } |
1346 | 1347 | ||
1347 | /*****************************************************************************/ | 1348 | /*****************************************************************************/ |
@@ -1660,7 +1661,6 @@ static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm | |||
1660 | { | 1661 | { |
1661 | struct stliport *portp; | 1662 | struct stliport *portp; |
1662 | struct stlibrd *brdp; | 1663 | struct stlibrd *brdp; |
1663 | unsigned int ival; | ||
1664 | int rc; | 1664 | int rc; |
1665 | void __user *argp = (void __user *)arg; | 1665 | void __user *argp = (void __user *)arg; |
1666 | 1666 | ||
@@ -1857,7 +1857,7 @@ static void stli_hangup(struct tty_struct *tty) | |||
1857 | set_bit(TTY_IO_ERROR, &tty->flags); | 1857 | set_bit(TTY_IO_ERROR, &tty->flags); |
1858 | portp->port.tty = NULL; | 1858 | portp->port.tty = NULL; |
1859 | portp->port.flags &= ~ASYNC_NORMAL_ACTIVE; | 1859 | portp->port.flags &= ~ASYNC_NORMAL_ACTIVE; |
1860 | portp->refcount = 0; | 1860 | portp->port.count = 0; |
1861 | spin_unlock_irqrestore(&stli_lock, flags); | 1861 | spin_unlock_irqrestore(&stli_lock, flags); |
1862 | 1862 | ||
1863 | wake_up_interruptible(&portp->port.open_wait); | 1863 | wake_up_interruptible(&portp->port.open_wait); |
@@ -4246,7 +4246,7 @@ static int stli_portcmdstats(struct stliport *portp) | |||
4246 | stli_comstats.panel = portp->panelnr; | 4246 | stli_comstats.panel = portp->panelnr; |
4247 | stli_comstats.port = portp->portnr; | 4247 | stli_comstats.port = portp->portnr; |
4248 | stli_comstats.state = portp->state; | 4248 | stli_comstats.state = portp->state; |
4249 | stli_comstats.flags = portp->port.flag; | 4249 | stli_comstats.flags = portp->port.flags; |
4250 | 4250 | ||
4251 | spin_lock_irqsave(&brd_lock, flags); | 4251 | spin_lock_irqsave(&brd_lock, flags); |
4252 | if (portp->port.tty != NULL) { | 4252 | if (portp->port.tty != NULL) { |
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index d9a0a53c842d..7b3a212c86b1 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -46,6 +46,8 @@ | |||
46 | 46 | ||
47 | extern void ctrl_alt_del(void); | 47 | extern void ctrl_alt_del(void); |
48 | 48 | ||
49 | #define to_handle_h(n) container_of(n, struct input_handle, h_node) | ||
50 | |||
49 | /* | 51 | /* |
50 | * Exported functions/variables | 52 | * Exported functions/variables |
51 | */ | 53 | */ |
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c index 50f22690d611..a4d92d246d52 100644 --- a/drivers/hwmon/hdaps.c +++ b/drivers/hwmon/hdaps.c | |||
@@ -581,6 +581,8 @@ static int __init hdaps_init(void) | |||
581 | /* initialize the input class */ | 581 | /* initialize the input class */ |
582 | idev = hdaps_idev->input; | 582 | idev = hdaps_idev->input; |
583 | idev->name = "hdaps"; | 583 | idev->name = "hdaps"; |
584 | idev->phys = "isa1600/input0"; | ||
585 | idev->id.bustype = BUS_ISA; | ||
584 | idev->dev.parent = &pdev->dev; | 586 | idev->dev.parent = &pdev->dev; |
585 | idev->evbit[0] = BIT_MASK(EV_ABS); | 587 | idev->evbit[0] = BIT_MASK(EV_ABS); |
586 | input_set_abs_params(idev, ABS_X, | 588 | input_set_abs_params(idev, ABS_X, |
diff --git a/drivers/input/evbug.c b/drivers/input/evbug.c index c21f2f127234..0353601ac3b5 100644 --- a/drivers/input/evbug.c +++ b/drivers/input/evbug.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: evbug.c,v 1.10 2001/09/25 10:12:07 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 1999-2001 Vojtech Pavlik | 2 | * Copyright (c) 1999-2001 Vojtech Pavlik |
5 | */ | 3 | */ |
6 | 4 | ||
@@ -41,7 +39,7 @@ MODULE_LICENSE("GPL"); | |||
41 | static void evbug_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) | 39 | static void evbug_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) |
42 | { | 40 | { |
43 | printk(KERN_DEBUG "evbug.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n", | 41 | printk(KERN_DEBUG "evbug.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n", |
44 | handle->dev->phys, type, code, value); | 42 | handle->dev->dev.bus_id, type, code, value); |
45 | } | 43 | } |
46 | 44 | ||
47 | static int evbug_connect(struct input_handler *handler, struct input_dev *dev, | 45 | static int evbug_connect(struct input_handler *handler, struct input_dev *dev, |
@@ -66,7 +64,10 @@ static int evbug_connect(struct input_handler *handler, struct input_dev *dev, | |||
66 | if (error) | 64 | if (error) |
67 | goto err_unregister_handle; | 65 | goto err_unregister_handle; |
68 | 66 | ||
69 | printk(KERN_DEBUG "evbug.c: Connected device: \"%s\", %s\n", dev->name, dev->phys); | 67 | printk(KERN_DEBUG "evbug.c: Connected device: %s (%s at %s)\n", |
68 | dev->dev.bus_id, | ||
69 | dev->name ?: "unknown", | ||
70 | dev->phys ?: "unknown"); | ||
70 | 71 | ||
71 | return 0; | 72 | return 0; |
72 | 73 | ||
@@ -79,7 +80,8 @@ static int evbug_connect(struct input_handler *handler, struct input_dev *dev, | |||
79 | 80 | ||
80 | static void evbug_disconnect(struct input_handle *handle) | 81 | static void evbug_disconnect(struct input_handle *handle) |
81 | { | 82 | { |
82 | printk(KERN_DEBUG "evbug.c: Disconnected device: %s\n", handle->dev->phys); | 83 | printk(KERN_DEBUG "evbug.c: Disconnected device: %s\n", |
84 | handle->dev->dev.bus_id); | ||
83 | 85 | ||
84 | input_close_device(handle); | 86 | input_close_device(handle); |
85 | input_unregister_handle(handle); | 87 | input_unregister_handle(handle); |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index b32984bc516f..2d65411f6763 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -300,6 +300,35 @@ struct input_event_compat { | |||
300 | __s32 value; | 300 | __s32 value; |
301 | }; | 301 | }; |
302 | 302 | ||
303 | struct ff_periodic_effect_compat { | ||
304 | __u16 waveform; | ||
305 | __u16 period; | ||
306 | __s16 magnitude; | ||
307 | __s16 offset; | ||
308 | __u16 phase; | ||
309 | |||
310 | struct ff_envelope envelope; | ||
311 | |||
312 | __u32 custom_len; | ||
313 | compat_uptr_t custom_data; | ||
314 | }; | ||
315 | |||
316 | struct ff_effect_compat { | ||
317 | __u16 type; | ||
318 | __s16 id; | ||
319 | __u16 direction; | ||
320 | struct ff_trigger trigger; | ||
321 | struct ff_replay replay; | ||
322 | |||
323 | union { | ||
324 | struct ff_constant_effect constant; | ||
325 | struct ff_ramp_effect ramp; | ||
326 | struct ff_periodic_effect_compat periodic; | ||
327 | struct ff_condition_effect condition[2]; /* One for each axis */ | ||
328 | struct ff_rumble_effect rumble; | ||
329 | } u; | ||
330 | }; | ||
331 | |||
303 | /* Note to the author of this code: did it ever occur to | 332 | /* Note to the author of this code: did it ever occur to |
304 | you why the ifdefs are needed? Think about it again. -AK */ | 333 | you why the ifdefs are needed? Think about it again. -AK */ |
305 | #ifdef CONFIG_X86_64 | 334 | #ifdef CONFIG_X86_64 |
@@ -368,6 +397,42 @@ static int evdev_event_to_user(char __user *buffer, | |||
368 | return 0; | 397 | return 0; |
369 | } | 398 | } |
370 | 399 | ||
400 | static int evdev_ff_effect_from_user(const char __user *buffer, size_t size, | ||
401 | struct ff_effect *effect) | ||
402 | { | ||
403 | if (COMPAT_TEST) { | ||
404 | struct ff_effect_compat *compat_effect; | ||
405 | |||
406 | if (size != sizeof(struct ff_effect_compat)) | ||
407 | return -EINVAL; | ||
408 | |||
409 | /* | ||
410 | * It so happens that the pointer which needs to be changed | ||
411 | * is the last field in the structure, so we can copy the | ||
412 | * whole thing and replace just the pointer. | ||
413 | */ | ||
414 | |||
415 | compat_effect = (struct ff_effect_compat *)effect; | ||
416 | |||
417 | if (copy_from_user(compat_effect, buffer, | ||
418 | sizeof(struct ff_effect_compat))) | ||
419 | return -EFAULT; | ||
420 | |||
421 | if (compat_effect->type == FF_PERIODIC && | ||
422 | compat_effect->u.periodic.waveform == FF_CUSTOM) | ||
423 | effect->u.periodic.custom_data = | ||
424 | compat_ptr(compat_effect->u.periodic.custom_data); | ||
425 | } else { | ||
426 | if (size != sizeof(struct ff_effect)) | ||
427 | return -EINVAL; | ||
428 | |||
429 | if (copy_from_user(effect, buffer, sizeof(struct ff_effect))) | ||
430 | return -EFAULT; | ||
431 | } | ||
432 | |||
433 | return 0; | ||
434 | } | ||
435 | |||
371 | #else | 436 | #else |
372 | 437 | ||
373 | static inline size_t evdev_event_size(void) | 438 | static inline size_t evdev_event_size(void) |
@@ -393,6 +458,18 @@ static int evdev_event_to_user(char __user *buffer, | |||
393 | return 0; | 458 | return 0; |
394 | } | 459 | } |
395 | 460 | ||
461 | static int evdev_ff_effect_from_user(const char __user *buffer, size_t size, | ||
462 | struct ff_effect *effect) | ||
463 | { | ||
464 | if (size != sizeof(struct ff_effect)) | ||
465 | return -EINVAL; | ||
466 | |||
467 | if (copy_from_user(effect, buffer, sizeof(struct ff_effect))) | ||
468 | return -EFAULT; | ||
469 | |||
470 | return 0; | ||
471 | } | ||
472 | |||
396 | #endif /* CONFIG_COMPAT */ | 473 | #endif /* CONFIG_COMPAT */ |
397 | 474 | ||
398 | static ssize_t evdev_write(struct file *file, const char __user *buffer, | 475 | static ssize_t evdev_write(struct file *file, const char __user *buffer, |
@@ -633,17 +710,6 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
633 | 710 | ||
634 | return input_set_keycode(dev, t, v); | 711 | return input_set_keycode(dev, t, v); |
635 | 712 | ||
636 | case EVIOCSFF: | ||
637 | if (copy_from_user(&effect, p, sizeof(effect))) | ||
638 | return -EFAULT; | ||
639 | |||
640 | error = input_ff_upload(dev, &effect, file); | ||
641 | |||
642 | if (put_user(effect.id, &(((struct ff_effect __user *)p)->id))) | ||
643 | return -EFAULT; | ||
644 | |||
645 | return error; | ||
646 | |||
647 | case EVIOCRMFF: | 713 | case EVIOCRMFF: |
648 | return input_ff_erase(dev, (int)(unsigned long) p, file); | 714 | return input_ff_erase(dev, (int)(unsigned long) p, file); |
649 | 715 | ||
@@ -733,6 +799,19 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
733 | 799 | ||
734 | if (_IOC_DIR(cmd) == _IOC_WRITE) { | 800 | if (_IOC_DIR(cmd) == _IOC_WRITE) { |
735 | 801 | ||
802 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCSFF)) { | ||
803 | |||
804 | if (evdev_ff_effect_from_user(p, _IOC_SIZE(cmd), &effect)) | ||
805 | return -EFAULT; | ||
806 | |||
807 | error = input_ff_upload(dev, &effect, file); | ||
808 | |||
809 | if (put_user(effect.id, &(((struct ff_effect __user *)p)->id))) | ||
810 | return -EFAULT; | ||
811 | |||
812 | return error; | ||
813 | } | ||
814 | |||
736 | if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) { | 815 | if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) { |
737 | 816 | ||
738 | t = _IOC_NR(cmd) & ABS_MAX; | 817 | t = _IOC_NR(cmd) & ABS_MAX; |
diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c index d226d935b0dc..6790e975a98c 100644 --- a/drivers/input/ff-memless.c +++ b/drivers/input/ff-memless.c | |||
@@ -247,9 +247,9 @@ static void ml_combine_effects(struct ff_effect *effect, | |||
247 | * in s8, this should be changed to something more generic | 247 | * in s8, this should be changed to something more generic |
248 | */ | 248 | */ |
249 | effect->u.ramp.start_level = | 249 | effect->u.ramp.start_level = |
250 | max(min(effect->u.ramp.start_level + x, 0x7f), -0x80); | 250 | clamp_val(effect->u.ramp.start_level + x, -0x80, 0x7f); |
251 | effect->u.ramp.end_level = | 251 | effect->u.ramp.end_level = |
252 | max(min(effect->u.ramp.end_level + y, 0x7f), -0x80); | 252 | clamp_val(effect->u.ramp.end_level + y, -0x80, 0x7f); |
253 | break; | 253 | break; |
254 | 254 | ||
255 | case FF_RUMBLE: | 255 | case FF_RUMBLE: |
diff --git a/drivers/input/gameport/emu10k1-gp.c b/drivers/input/gameport/emu10k1-gp.c index 9793ac36d17f..b04930f7ea7d 100644 --- a/drivers/input/gameport/emu10k1-gp.c +++ b/drivers/input/gameport/emu10k1-gp.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: emu10k1-gp.c,v 1.8 2002/01/22 20:40:46 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 2001 Vojtech Pavlik | 2 | * Copyright (c) 2001 Vojtech Pavlik |
5 | */ | 3 | */ |
6 | 4 | ||
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index c5600ac5feb3..078e4eed0894 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c | |||
@@ -36,7 +36,6 @@ EXPORT_SYMBOL(__gameport_register_driver); | |||
36 | EXPORT_SYMBOL(gameport_unregister_driver); | 36 | EXPORT_SYMBOL(gameport_unregister_driver); |
37 | EXPORT_SYMBOL(gameport_open); | 37 | EXPORT_SYMBOL(gameport_open); |
38 | EXPORT_SYMBOL(gameport_close); | 38 | EXPORT_SYMBOL(gameport_close); |
39 | EXPORT_SYMBOL(gameport_rescan); | ||
40 | EXPORT_SYMBOL(gameport_set_phys); | 39 | EXPORT_SYMBOL(gameport_set_phys); |
41 | EXPORT_SYMBOL(gameport_start_polling); | 40 | EXPORT_SYMBOL(gameport_start_polling); |
42 | EXPORT_SYMBOL(gameport_stop_polling); | 41 | EXPORT_SYMBOL(gameport_stop_polling); |
@@ -230,8 +229,6 @@ static void gameport_find_driver(struct gameport *gameport) | |||
230 | */ | 229 | */ |
231 | 230 | ||
232 | enum gameport_event_type { | 231 | enum gameport_event_type { |
233 | GAMEPORT_RESCAN, | ||
234 | GAMEPORT_RECONNECT, | ||
235 | GAMEPORT_REGISTER_PORT, | 232 | GAMEPORT_REGISTER_PORT, |
236 | GAMEPORT_REGISTER_DRIVER, | 233 | GAMEPORT_REGISTER_DRIVER, |
237 | }; | 234 | }; |
@@ -365,15 +362,6 @@ static void gameport_handle_event(void) | |||
365 | gameport_add_port(event->object); | 362 | gameport_add_port(event->object); |
366 | break; | 363 | break; |
367 | 364 | ||
368 | case GAMEPORT_RECONNECT: | ||
369 | gameport_reconnect_port(event->object); | ||
370 | break; | ||
371 | |||
372 | case GAMEPORT_RESCAN: | ||
373 | gameport_disconnect_port(event->object); | ||
374 | gameport_find_driver(event->object); | ||
375 | break; | ||
376 | |||
377 | case GAMEPORT_REGISTER_DRIVER: | 365 | case GAMEPORT_REGISTER_DRIVER: |
378 | gameport_add_driver(event->object); | 366 | gameport_add_driver(event->object); |
379 | break; | 367 | break; |
@@ -651,16 +639,6 @@ static void gameport_disconnect_port(struct gameport *gameport) | |||
651 | device_release_driver(&gameport->dev); | 639 | device_release_driver(&gameport->dev); |
652 | } | 640 | } |
653 | 641 | ||
654 | void gameport_rescan(struct gameport *gameport) | ||
655 | { | ||
656 | gameport_queue_event(gameport, NULL, GAMEPORT_RESCAN); | ||
657 | } | ||
658 | |||
659 | void gameport_reconnect(struct gameport *gameport) | ||
660 | { | ||
661 | gameport_queue_event(gameport, NULL, GAMEPORT_RECONNECT); | ||
662 | } | ||
663 | |||
664 | /* | 642 | /* |
665 | * Submits register request to kgameportd for subsequent execution. | 643 | * Submits register request to kgameportd for subsequent execution. |
666 | * Note that port registration is always asynchronous. | 644 | * Note that port registration is always asynchronous. |
diff --git a/drivers/input/gameport/lightning.c b/drivers/input/gameport/lightning.c index 6b4d4561d465..06ad36ed3483 100644 --- a/drivers/input/gameport/lightning.c +++ b/drivers/input/gameport/lightning.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: lightning.c,v 1.20 2002/01/22 20:41:31 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 1998-2001 Vojtech Pavlik | 2 | * Copyright (c) 1998-2001 Vojtech Pavlik |
5 | */ | 3 | */ |
6 | 4 | ||
diff --git a/drivers/input/gameport/ns558.c b/drivers/input/gameport/ns558.c index 7b7a546323cf..2b282cde4b89 100644 --- a/drivers/input/gameport/ns558.c +++ b/drivers/input/gameport/ns558.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: ns558.c,v 1.43 2002/01/24 19:23:21 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 1999-2001 Vojtech Pavlik | 2 | * Copyright (c) 1999-2001 Vojtech Pavlik |
5 | * Copyright (c) 1999 Brian Gerst | 3 | * Copyright (c) 1999 Brian Gerst |
6 | */ | 4 | */ |
diff --git a/drivers/input/input.c b/drivers/input/input.c index 408df0bd6be5..c13ced3e0d3d 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -242,7 +242,7 @@ static void input_handle_event(struct input_dev *dev, | |||
242 | break; | 242 | break; |
243 | } | 243 | } |
244 | 244 | ||
245 | if (type != EV_SYN) | 245 | if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN) |
246 | dev->sync = 0; | 246 | dev->sync = 0; |
247 | 247 | ||
248 | if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event) | 248 | if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event) |
diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c index 52ba16f487c7..92498d470b1f 100644 --- a/drivers/input/joystick/a3d.c +++ b/drivers/input/joystick/a3d.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: a3d.c,v 1.21 2002/01/22 20:11:50 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 1998-2001 Vojtech Pavlik | 2 | * Copyright (c) 1998-2001 Vojtech Pavlik |
5 | */ | 3 | */ |
6 | 4 | ||
diff --git a/drivers/input/joystick/amijoy.c b/drivers/input/joystick/amijoy.c index deb9f825f92c..05022f07ec77 100644 --- a/drivers/input/joystick/amijoy.c +++ b/drivers/input/joystick/amijoy.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: amijoy.c,v 1.13 2002/01/22 20:26:32 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 1998-2001 Vojtech Pavlik | 2 | * Copyright (c) 1998-2001 Vojtech Pavlik |
5 | */ | 3 | */ |
6 | 4 | ||
diff --git a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c index 55646a6d89f5..639b975a8ed7 100644 --- a/drivers/input/joystick/cobra.c +++ b/drivers/input/joystick/cobra.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: cobra.c,v 1.19 2002/01/22 20:26:52 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 1999-2001 Vojtech Pavlik | 2 | * Copyright (c) 1999-2001 Vojtech Pavlik |
5 | */ | 3 | */ |
6 | 4 | ||
diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c index 960e501c60c8..523959484753 100644 --- a/drivers/input/joystick/db9.c +++ b/drivers/input/joystick/db9.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: db9.c,v 1.13 2002/04/07 20:13:37 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 1999-2001 Vojtech Pavlik | 2 | * Copyright (c) 1999-2001 Vojtech Pavlik |
5 | * | 3 | * |
6 | * Based on the work of: | 4 | * Based on the work of: |
diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c index 1f6302c0eb3f..cb6eef1f2d99 100644 --- a/drivers/input/joystick/gf2k.c +++ b/drivers/input/joystick/gf2k.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: gf2k.c,v 1.19 2002/01/22 20:27:43 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 1998-2001 Vojtech Pavlik | 2 | * Copyright (c) 1998-2001 Vojtech Pavlik |
5 | */ | 3 | */ |
6 | 4 | ||
diff --git a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c index fd3853ab1aad..684e07cfccc8 100644 --- a/drivers/input/joystick/grip.c +++ b/drivers/input/joystick/grip.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: grip.c,v 1.21 2002/01/22 20:27:57 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 1998-2001 Vojtech Pavlik | 2 | * Copyright (c) 1998-2001 Vojtech Pavlik |
5 | */ | 3 | */ |
6 | 4 | ||
diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c index c57e21d68c00..8279481b16e7 100644 --- a/drivers/input/joystick/grip_mp.c +++ b/drivers/input/joystick/grip_mp.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: grip_mp.c,v 1.9 2002/07/20 19:28:45 bonnland Exp $ | ||
3 | * | ||
4 | * Driver for the Gravis Grip Multiport, a gamepad "hub" that | 2 | * Driver for the Gravis Grip Multiport, a gamepad "hub" that |
5 | * connects up to four 9-pin digital gamepads/joysticks. | 3 | * connects up to four 9-pin digital gamepads/joysticks. |
6 | * Driver tested on SMP and UP kernel versions 2.4.18-4 and 2.4.18-5. | 4 | * Driver tested on SMP and UP kernel versions 2.4.18-4 and 2.4.18-5. |
diff --git a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c index aa6bfb3fb8cd..25ec3fad9f27 100644 --- a/drivers/input/joystick/guillemot.c +++ b/drivers/input/joystick/guillemot.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: guillemot.c,v 1.10 2002/01/22 20:28:12 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 2001 Vojtech Pavlik | 2 | * Copyright (c) 2001 Vojtech Pavlik |
5 | */ | 3 | */ |
6 | 4 | ||
diff --git a/drivers/input/joystick/iforce/iforce-ff.c b/drivers/input/joystick/iforce/iforce-ff.c index f2a4381d0ab8..7839b7b6fa96 100644 --- a/drivers/input/joystick/iforce/iforce-ff.c +++ b/drivers/input/joystick/iforce/iforce-ff.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: iforce-ff.c,v 1.9 2002/02/02 19:28:35 jdeneux Exp $ | ||
3 | * | ||
4 | * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz> | 2 | * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz> |
5 | * Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com> | 3 | * Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com> |
6 | * | 4 | * |
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index a2517fa72eb8..61ee6e38739d 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: iforce-main.c,v 1.19 2002/07/07 10:22:50 jdeneux Exp $ | ||
3 | * | ||
4 | * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz> | 2 | * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz> |
5 | * Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com> | 3 | * Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com> |
6 | * | 4 | * |
diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c index 45c4939ced75..015b50aa76fc 100644 --- a/drivers/input/joystick/iforce/iforce-packets.c +++ b/drivers/input/joystick/iforce/iforce-packets.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: iforce-packets.c,v 1.16 2002/07/07 10:22:50 jdeneux Exp $ | ||
3 | * | ||
4 | * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz> | 2 | * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz> |
5 | * Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com> | 3 | * Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com> |
6 | * | 4 | * |
diff --git a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c index 7b4bc19cef27..46d5041d2d9d 100644 --- a/drivers/input/joystick/iforce/iforce-serio.c +++ b/drivers/input/joystick/iforce/iforce-serio.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: iforce-serio.c,v 1.4 2002/01/28 22:45:00 jdeneux Exp $ | ||
3 | * | ||
4 | * Copyright (c) 2000-2001 Vojtech Pavlik <vojtech@ucw.cz> | 2 | * Copyright (c) 2000-2001 Vojtech Pavlik <vojtech@ucw.cz> |
5 | * Copyright (c) 2001, 2007 Johann Deneux <johann.deneux@gmail.com> | 3 | * Copyright (c) 2001, 2007 Johann Deneux <johann.deneux@gmail.com> |
6 | * | 4 | * |
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c index 7fb3cf81cfbf..851cc4087c2f 100644 --- a/drivers/input/joystick/iforce/iforce-usb.c +++ b/drivers/input/joystick/iforce/iforce-usb.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: iforce-usb.c,v 1.16 2002/06/09 11:08:04 jdeneux Exp $ | ||
3 | * | ||
4 | * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz> | 2 | * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz> |
5 | * Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com> | 3 | * Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com> |
6 | * | 4 | * |
@@ -89,10 +87,10 @@ static void iforce_usb_irq(struct urb *urb) | |||
89 | case -ESHUTDOWN: | 87 | case -ESHUTDOWN: |
90 | /* this urb is terminated, clean up */ | 88 | /* this urb is terminated, clean up */ |
91 | dbg("%s - urb shutting down with status: %d", | 89 | dbg("%s - urb shutting down with status: %d", |
92 | __FUNCTION__, urb->status); | 90 | __func__, urb->status); |
93 | return; | 91 | return; |
94 | default: | 92 | default: |
95 | dbg("%s - urb has status of: %d", __FUNCTION__, urb->status); | 93 | dbg("%s - urb has status of: %d", __func__, urb->status); |
96 | goto exit; | 94 | goto exit; |
97 | } | 95 | } |
98 | 96 | ||
@@ -103,7 +101,7 @@ exit: | |||
103 | status = usb_submit_urb (urb, GFP_ATOMIC); | 101 | status = usb_submit_urb (urb, GFP_ATOMIC); |
104 | if (status) | 102 | if (status) |
105 | err ("%s - usb_submit_urb failed with result %d", | 103 | err ("%s - usb_submit_urb failed with result %d", |
106 | __FUNCTION__, status); | 104 | __func__, status); |
107 | } | 105 | } |
108 | 106 | ||
109 | static void iforce_usb_out(struct urb *urb) | 107 | static void iforce_usb_out(struct urb *urb) |
diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h index a964a7cfd210..f2d91f4028ca 100644 --- a/drivers/input/joystick/iforce/iforce.h +++ b/drivers/input/joystick/iforce/iforce.h | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: iforce.h,v 1.13 2002/07/07 10:22:50 jdeneux Exp $ | ||
3 | * | ||
4 | * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz> | 2 | * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz> |
5 | * Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com> | 3 | * Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com> |
6 | * | 4 | * |
diff --git a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c index bc8ea95dfd0e..8c3290b68205 100644 --- a/drivers/input/joystick/interact.c +++ b/drivers/input/joystick/interact.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: interact.c,v 1.16 2002/01/22 20:28:25 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 2001 Vojtech Pavlik | 2 | * Copyright (c) 2001 Vojtech Pavlik |
5 | * | 3 | * |
6 | * Based on the work of: | 4 | * Based on the work of: |
diff --git a/drivers/input/joystick/joydump.c b/drivers/input/joystick/joydump.c index 88ec5a918f2e..2a1b82c8b31c 100644 --- a/drivers/input/joystick/joydump.c +++ b/drivers/input/joystick/joydump.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: joydump.c,v 1.1 2002/01/23 06:56:16 jsimmons Exp $ | ||
3 | * | ||
4 | * Copyright (c) 1996-2001 Vojtech Pavlik | 2 | * Copyright (c) 1996-2001 Vojtech Pavlik |
5 | */ | 3 | */ |
6 | 4 | ||
diff --git a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c index 54e676948ebb..40e40780747d 100644 --- a/drivers/input/joystick/magellan.c +++ b/drivers/input/joystick/magellan.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: magellan.c,v 1.16 2002/01/22 20:28:39 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 1999-2001 Vojtech Pavlik | 2 | * Copyright (c) 1999-2001 Vojtech Pavlik |
5 | */ | 3 | */ |
6 | 4 | ||
diff --git a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c index d4087fd49656..0cd9b29356a8 100644 --- a/drivers/input/joystick/spaceball.c +++ b/drivers/input/joystick/spaceball.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: spaceball.c,v 1.17 2002/01/22 20:29:03 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 1999-2001 Vojtech Pavlik | 2 | * Copyright (c) 1999-2001 Vojtech Pavlik |
5 | * | 3 | * |
6 | * Based on the work of: | 4 | * Based on the work of: |
diff --git a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c index f7ce4004f4ba..a694bf8e557b 100644 --- a/drivers/input/joystick/spaceorb.c +++ b/drivers/input/joystick/spaceorb.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: spaceorb.c,v 1.15 2002/01/22 20:29:19 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 1999-2001 Vojtech Pavlik | 2 | * Copyright (c) 1999-2001 Vojtech Pavlik |
5 | * | 3 | * |
6 | * Based on the work of: | 4 | * Based on the work of: |
diff --git a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c index baa10b2f7ba1..e0db9f5e4b41 100644 --- a/drivers/input/joystick/stinger.c +++ b/drivers/input/joystick/stinger.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: stinger.c,v 1.10 2002/01/22 20:29:31 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 2000-2001 Vojtech Pavlik | 2 | * Copyright (c) 2000-2001 Vojtech Pavlik |
5 | * Copyright (c) 2000 Mark Fletcher | 3 | * Copyright (c) 2000 Mark Fletcher |
6 | */ | 4 | */ |
diff --git a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c index 0feeb8acb532..60c37bcb938d 100644 --- a/drivers/input/joystick/tmdc.c +++ b/drivers/input/joystick/tmdc.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: tmdc.c,v 1.31 2002/01/22 20:29:52 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 1998-2001 Vojtech Pavlik | 2 | * Copyright (c) 1998-2001 Vojtech Pavlik |
5 | * | 3 | * |
6 | * Based on the work of: | 4 | * Based on the work of: |
diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c index 989483f53160..b6f859869540 100644 --- a/drivers/input/joystick/turbografx.c +++ b/drivers/input/joystick/turbografx.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: turbografx.c,v 1.14 2002/01/22 20:30:39 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 1998-2001 Vojtech Pavlik | 2 | * Copyright (c) 1998-2001 Vojtech Pavlik |
5 | * | 3 | * |
6 | * Based on the work of: | 4 | * Based on the work of: |
diff --git a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c index 1085c841fec4..3f4ec73c9553 100644 --- a/drivers/input/joystick/twidjoy.c +++ b/drivers/input/joystick/twidjoy.c | |||
@@ -1,8 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: twidjoy.c,v 1.5 2002/01/22 20:31:53 vojtech Exp $ | ||
3 | * | ||
4 | * derived from CVS-ID "stinger.c,v 1.5 2001/05/29 12:57:18 vojtech Exp" | ||
5 | * | ||
6 | * Copyright (c) 2001 Arndt Schoenewald | 2 | * Copyright (c) 2001 Arndt Schoenewald |
7 | * Copyright (c) 2000-2001 Vojtech Pavlik | 3 | * Copyright (c) 2000-2001 Vojtech Pavlik |
8 | * Copyright (c) 2000 Mark Fletcher | 4 | * Copyright (c) 2000 Mark Fletcher |
diff --git a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c index e928b6e3724a..f72c83e15e60 100644 --- a/drivers/input/joystick/warrior.c +++ b/drivers/input/joystick/warrior.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: warrior.c,v 1.14 2002/01/22 20:32:10 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 1999-2001 Vojtech Pavlik | 2 | * Copyright (c) 1999-2001 Vojtech Pavlik |
5 | */ | 3 | */ |
6 | 4 | ||
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index b29e3affb805..87d3e7eabffd 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
@@ -418,11 +418,11 @@ static void xpad_irq_in(struct urb *urb) | |||
418 | case -ESHUTDOWN: | 418 | case -ESHUTDOWN: |
419 | /* this urb is terminated, clean up */ | 419 | /* this urb is terminated, clean up */ |
420 | dbg("%s - urb shutting down with status: %d", | 420 | dbg("%s - urb shutting down with status: %d", |
421 | __FUNCTION__, status); | 421 | __func__, status); |
422 | return; | 422 | return; |
423 | default: | 423 | default: |
424 | dbg("%s - nonzero urb status received: %d", | 424 | dbg("%s - nonzero urb status received: %d", |
425 | __FUNCTION__, status); | 425 | __func__, status); |
426 | goto exit; | 426 | goto exit; |
427 | } | 427 | } |
428 | 428 | ||
@@ -441,7 +441,7 @@ exit: | |||
441 | retval = usb_submit_urb (urb, GFP_ATOMIC); | 441 | retval = usb_submit_urb (urb, GFP_ATOMIC); |
442 | if (retval) | 442 | if (retval) |
443 | err ("%s - usb_submit_urb failed with result %d", | 443 | err ("%s - usb_submit_urb failed with result %d", |
444 | __FUNCTION__, retval); | 444 | __func__, retval); |
445 | } | 445 | } |
446 | 446 | ||
447 | static void xpad_bulk_out(struct urb *urb) | 447 | static void xpad_bulk_out(struct urb *urb) |
@@ -477,11 +477,11 @@ static void xpad_irq_out(struct urb *urb) | |||
477 | case -ESHUTDOWN: | 477 | case -ESHUTDOWN: |
478 | /* this urb is terminated, clean up */ | 478 | /* this urb is terminated, clean up */ |
479 | dbg("%s - urb shutting down with status: %d", | 479 | dbg("%s - urb shutting down with status: %d", |
480 | __FUNCTION__, status); | 480 | __func__, status); |
481 | return; | 481 | return; |
482 | default: | 482 | default: |
483 | dbg("%s - nonzero urb status received: %d", | 483 | dbg("%s - nonzero urb status received: %d", |
484 | __FUNCTION__, status); | 484 | __func__, status); |
485 | goto exit; | 485 | goto exit; |
486 | } | 486 | } |
487 | 487 | ||
@@ -489,7 +489,7 @@ exit: | |||
489 | retval = usb_submit_urb(urb, GFP_ATOMIC); | 489 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
490 | if (retval) | 490 | if (retval) |
491 | err("%s - usb_submit_urb failed with result %d", | 491 | err("%s - usb_submit_urb failed with result %d", |
492 | __FUNCTION__, retval); | 492 | __func__, retval); |
493 | } | 493 | } |
494 | 494 | ||
495 | static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) | 495 | static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) |
diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c index 81bf7562aca0..35149ec455a9 100644 --- a/drivers/input/keyboard/amikbd.c +++ b/drivers/input/keyboard/amikbd.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: amikbd.c,v 1.13 2002/02/01 16:02:24 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 2000-2001 Vojtech Pavlik | 2 | * Copyright (c) 2000-2001 Vojtech Pavlik |
5 | * | 3 | * |
6 | * Based on the work of: | 4 | * Based on the work of: |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index af58a6f1e898..b1ce10f50bcf 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -68,7 +68,7 @@ MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and | |||
68 | * are loadable via an userland utility. | 68 | * are loadable via an userland utility. |
69 | */ | 69 | */ |
70 | 70 | ||
71 | static unsigned char atkbd_set2_keycode[512] = { | 71 | static const unsigned short atkbd_set2_keycode[512] = { |
72 | 72 | ||
73 | #ifdef CONFIG_KEYBOARD_ATKBD_HP_KEYCODES | 73 | #ifdef CONFIG_KEYBOARD_ATKBD_HP_KEYCODES |
74 | 74 | ||
@@ -99,7 +99,7 @@ static unsigned char atkbd_set2_keycode[512] = { | |||
99 | #endif | 99 | #endif |
100 | }; | 100 | }; |
101 | 101 | ||
102 | static unsigned char atkbd_set3_keycode[512] = { | 102 | static const unsigned short atkbd_set3_keycode[512] = { |
103 | 103 | ||
104 | 0, 0, 0, 0, 0, 0, 0, 59, 1,138,128,129,130, 15, 41, 60, | 104 | 0, 0, 0, 0, 0, 0, 0, 59, 1,138,128,129,130, 15, 41, 60, |
105 | 131, 29, 42, 86, 58, 16, 2, 61,133, 56, 44, 31, 30, 17, 3, 62, | 105 | 131, 29, 42, 86, 58, 16, 2, 61,133, 56, 44, 31, 30, 17, 3, 62, |
@@ -115,7 +115,7 @@ static unsigned char atkbd_set3_keycode[512] = { | |||
115 | 148,149,147,140 | 115 | 148,149,147,140 |
116 | }; | 116 | }; |
117 | 117 | ||
118 | static unsigned char atkbd_unxlate_table[128] = { | 118 | static const unsigned short atkbd_unxlate_table[128] = { |
119 | 0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13, | 119 | 0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13, |
120 | 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27, | 120 | 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27, |
121 | 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42, | 121 | 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42, |
@@ -161,7 +161,7 @@ static unsigned char atkbd_unxlate_table[128] = { | |||
161 | #define ATKBD_SCR_LEFT 249 | 161 | #define ATKBD_SCR_LEFT 249 |
162 | #define ATKBD_SCR_RIGHT 248 | 162 | #define ATKBD_SCR_RIGHT 248 |
163 | 163 | ||
164 | #define ATKBD_SPECIAL 248 | 164 | #define ATKBD_SPECIAL ATKBD_SCR_RIGHT |
165 | 165 | ||
166 | #define ATKBD_LED_EVENT_BIT 0 | 166 | #define ATKBD_LED_EVENT_BIT 0 |
167 | #define ATKBD_REP_EVENT_BIT 1 | 167 | #define ATKBD_REP_EVENT_BIT 1 |
@@ -173,7 +173,7 @@ static unsigned char atkbd_unxlate_table[128] = { | |||
173 | #define ATKBD_XL_HANGEUL 0x10 | 173 | #define ATKBD_XL_HANGEUL 0x10 |
174 | #define ATKBD_XL_HANJA 0x20 | 174 | #define ATKBD_XL_HANJA 0x20 |
175 | 175 | ||
176 | static struct { | 176 | static const struct { |
177 | unsigned char keycode; | 177 | unsigned char keycode; |
178 | unsigned char set2; | 178 | unsigned char set2; |
179 | } atkbd_scroll_keys[] = { | 179 | } atkbd_scroll_keys[] = { |
@@ -200,7 +200,7 @@ struct atkbd { | |||
200 | char phys[32]; | 200 | char phys[32]; |
201 | 201 | ||
202 | unsigned short id; | 202 | unsigned short id; |
203 | unsigned char keycode[512]; | 203 | unsigned short keycode[512]; |
204 | DECLARE_BITMAP(force_release_mask, 512); | 204 | DECLARE_BITMAP(force_release_mask, 512); |
205 | unsigned char set; | 205 | unsigned char set; |
206 | unsigned char translated; | 206 | unsigned char translated; |
@@ -357,7 +357,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | |||
357 | unsigned int code = data; | 357 | unsigned int code = data; |
358 | int scroll = 0, hscroll = 0, click = -1; | 358 | int scroll = 0, hscroll = 0, click = -1; |
359 | int value; | 359 | int value; |
360 | unsigned char keycode; | 360 | unsigned short keycode; |
361 | 361 | ||
362 | #ifdef ATKBD_DEBUG | 362 | #ifdef ATKBD_DEBUG |
363 | printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags); | 363 | printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags); |
@@ -851,6 +851,23 @@ static void atkbd_latitude_keymap_fixup(struct atkbd *atkbd) | |||
851 | } | 851 | } |
852 | 852 | ||
853 | /* | 853 | /* |
854 | * Perform fixup for HP system that doesn't generate release | ||
855 | * for its video switch | ||
856 | */ | ||
857 | static void atkbd_hp_keymap_fixup(struct atkbd *atkbd) | ||
858 | { | ||
859 | const unsigned int forced_release_keys[] = { | ||
860 | 0x94, | ||
861 | }; | ||
862 | int i; | ||
863 | |||
864 | if (atkbd->set == 2) | ||
865 | for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++) | ||
866 | __set_bit(forced_release_keys[i], | ||
867 | atkbd->force_release_mask); | ||
868 | } | ||
869 | |||
870 | /* | ||
854 | * atkbd_set_keycode_table() initializes keyboard's keycode table | 871 | * atkbd_set_keycode_table() initializes keyboard's keycode table |
855 | * according to the selected scancode set | 872 | * according to the selected scancode set |
856 | */ | 873 | */ |
@@ -961,16 +978,16 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd) | |||
961 | input_dev->evbit[0] |= BIT_MASK(EV_REL); | 978 | input_dev->evbit[0] |= BIT_MASK(EV_REL); |
962 | input_dev->relbit[0] = BIT_MASK(REL_WHEEL) | | 979 | input_dev->relbit[0] = BIT_MASK(REL_WHEEL) | |
963 | BIT_MASK(REL_HWHEEL); | 980 | BIT_MASK(REL_HWHEEL); |
964 | set_bit(BTN_MIDDLE, input_dev->keybit); | 981 | __set_bit(BTN_MIDDLE, input_dev->keybit); |
965 | } | 982 | } |
966 | 983 | ||
967 | input_dev->keycode = atkbd->keycode; | 984 | input_dev->keycode = atkbd->keycode; |
968 | input_dev->keycodesize = sizeof(unsigned char); | 985 | input_dev->keycodesize = sizeof(unsigned short); |
969 | input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode); | 986 | input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode); |
970 | 987 | ||
971 | for (i = 0; i < 512; i++) | 988 | for (i = 0; i < 512; i++) |
972 | if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL) | 989 | if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL) |
973 | set_bit(atkbd->keycode[i], input_dev->keybit); | 990 | __set_bit(atkbd->keycode[i], input_dev->keybit); |
974 | } | 991 | } |
975 | 992 | ||
976 | /* | 993 | /* |
@@ -1452,6 +1469,15 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1452 | .callback = atkbd_setup_fixup, | 1469 | .callback = atkbd_setup_fixup, |
1453 | .driver_data = atkbd_latitude_keymap_fixup, | 1470 | .driver_data = atkbd_latitude_keymap_fixup, |
1454 | }, | 1471 | }, |
1472 | { | ||
1473 | .ident = "HP 2133", | ||
1474 | .matches = { | ||
1475 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
1476 | DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"), | ||
1477 | }, | ||
1478 | .callback = atkbd_setup_fixup, | ||
1479 | .driver_data = atkbd_hp_keymap_fixup, | ||
1480 | }, | ||
1455 | { } | 1481 | { } |
1456 | }; | 1482 | }; |
1457 | 1483 | ||
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index bbd00c3fe98c..be58730e636a 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c | |||
@@ -26,23 +26,54 @@ | |||
26 | 26 | ||
27 | #include <asm/gpio.h> | 27 | #include <asm/gpio.h> |
28 | 28 | ||
29 | struct gpio_button_data { | ||
30 | struct gpio_keys_button *button; | ||
31 | struct input_dev *input; | ||
32 | struct timer_list timer; | ||
33 | }; | ||
34 | |||
35 | struct gpio_keys_drvdata { | ||
36 | struct input_dev *input; | ||
37 | struct gpio_button_data data[0]; | ||
38 | }; | ||
39 | |||
40 | static void gpio_keys_report_event(struct gpio_keys_button *button, | ||
41 | struct input_dev *input) | ||
42 | { | ||
43 | unsigned int type = button->type ?: EV_KEY; | ||
44 | int state = (gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low; | ||
45 | |||
46 | input_event(input, type, button->code, !!state); | ||
47 | input_sync(input); | ||
48 | } | ||
49 | |||
50 | static void gpio_check_button(unsigned long _data) | ||
51 | { | ||
52 | struct gpio_button_data *data = (struct gpio_button_data *)_data; | ||
53 | |||
54 | gpio_keys_report_event(data->button, data->input); | ||
55 | } | ||
56 | |||
29 | static irqreturn_t gpio_keys_isr(int irq, void *dev_id) | 57 | static irqreturn_t gpio_keys_isr(int irq, void *dev_id) |
30 | { | 58 | { |
31 | int i; | ||
32 | struct platform_device *pdev = dev_id; | 59 | struct platform_device *pdev = dev_id; |
33 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | 60 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; |
34 | struct input_dev *input = platform_get_drvdata(pdev); | 61 | struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); |
62 | int i; | ||
35 | 63 | ||
36 | for (i = 0; i < pdata->nbuttons; i++) { | 64 | for (i = 0; i < pdata->nbuttons; i++) { |
37 | struct gpio_keys_button *button = &pdata->buttons[i]; | 65 | struct gpio_keys_button *button = &pdata->buttons[i]; |
38 | int gpio = button->gpio; | ||
39 | 66 | ||
40 | if (irq == gpio_to_irq(gpio)) { | 67 | if (irq == gpio_to_irq(button->gpio)) { |
41 | unsigned int type = button->type ?: EV_KEY; | 68 | struct gpio_button_data *bdata = &ddata->data[i]; |
42 | int state = (gpio_get_value(gpio) ? 1 : 0) ^ button->active_low; | 69 | |
70 | if (button->debounce_interval) | ||
71 | mod_timer(&bdata->timer, | ||
72 | jiffies + | ||
73 | msecs_to_jiffies(button->debounce_interval)); | ||
74 | else | ||
75 | gpio_keys_report_event(button, bdata->input); | ||
43 | 76 | ||
44 | input_event(input, type, button->code, !!state); | ||
45 | input_sync(input); | ||
46 | return IRQ_HANDLED; | 77 | return IRQ_HANDLED; |
47 | } | 78 | } |
48 | } | 79 | } |
@@ -53,17 +84,21 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id) | |||
53 | static int __devinit gpio_keys_probe(struct platform_device *pdev) | 84 | static int __devinit gpio_keys_probe(struct platform_device *pdev) |
54 | { | 85 | { |
55 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | 86 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; |
87 | struct gpio_keys_drvdata *ddata; | ||
56 | struct input_dev *input; | 88 | struct input_dev *input; |
57 | int i, error; | 89 | int i, error; |
58 | int wakeup = 0; | 90 | int wakeup = 0; |
59 | 91 | ||
92 | ddata = kzalloc(sizeof(struct gpio_keys_drvdata) + | ||
93 | pdata->nbuttons * sizeof(struct gpio_button_data), | ||
94 | GFP_KERNEL); | ||
60 | input = input_allocate_device(); | 95 | input = input_allocate_device(); |
61 | if (!input) | 96 | if (!ddata || !input) { |
62 | return -ENOMEM; | 97 | error = -ENOMEM; |
63 | 98 | goto fail1; | |
64 | platform_set_drvdata(pdev, input); | 99 | } |
65 | 100 | ||
66 | input->evbit[0] = BIT_MASK(EV_KEY); | 101 | platform_set_drvdata(pdev, ddata); |
67 | 102 | ||
68 | input->name = pdev->name; | 103 | input->name = pdev->name; |
69 | input->phys = "gpio-keys/input0"; | 104 | input->phys = "gpio-keys/input0"; |
@@ -74,16 +109,23 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
74 | input->id.product = 0x0001; | 109 | input->id.product = 0x0001; |
75 | input->id.version = 0x0100; | 110 | input->id.version = 0x0100; |
76 | 111 | ||
112 | ddata->input = input; | ||
113 | |||
77 | for (i = 0; i < pdata->nbuttons; i++) { | 114 | for (i = 0; i < pdata->nbuttons; i++) { |
78 | struct gpio_keys_button *button = &pdata->buttons[i]; | 115 | struct gpio_keys_button *button = &pdata->buttons[i]; |
116 | struct gpio_button_data *bdata = &ddata->data[i]; | ||
79 | int irq; | 117 | int irq; |
80 | unsigned int type = button->type ?: EV_KEY; | 118 | unsigned int type = button->type ?: EV_KEY; |
81 | 119 | ||
120 | bdata->input = input; | ||
121 | setup_timer(&bdata->timer, | ||
122 | gpio_check_button, (unsigned long)bdata); | ||
123 | |||
82 | error = gpio_request(button->gpio, button->desc ?: "gpio_keys"); | 124 | error = gpio_request(button->gpio, button->desc ?: "gpio_keys"); |
83 | if (error < 0) { | 125 | if (error < 0) { |
84 | pr_err("gpio-keys: failed to request GPIO %d," | 126 | pr_err("gpio-keys: failed to request GPIO %d," |
85 | " error %d\n", button->gpio, error); | 127 | " error %d\n", button->gpio, error); |
86 | goto fail; | 128 | goto fail2; |
87 | } | 129 | } |
88 | 130 | ||
89 | error = gpio_direction_input(button->gpio); | 131 | error = gpio_direction_input(button->gpio); |
@@ -92,7 +134,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
92 | " direction for GPIO %d, error %d\n", | 134 | " direction for GPIO %d, error %d\n", |
93 | button->gpio, error); | 135 | button->gpio, error); |
94 | gpio_free(button->gpio); | 136 | gpio_free(button->gpio); |
95 | goto fail; | 137 | goto fail2; |
96 | } | 138 | } |
97 | 139 | ||
98 | irq = gpio_to_irq(button->gpio); | 140 | irq = gpio_to_irq(button->gpio); |
@@ -102,7 +144,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
102 | " for GPIO %d, error %d\n", | 144 | " for GPIO %d, error %d\n", |
103 | button->gpio, error); | 145 | button->gpio, error); |
104 | gpio_free(button->gpio); | 146 | gpio_free(button->gpio); |
105 | goto fail; | 147 | goto fail2; |
106 | } | 148 | } |
107 | 149 | ||
108 | error = request_irq(irq, gpio_keys_isr, | 150 | error = request_irq(irq, gpio_keys_isr, |
@@ -114,7 +156,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
114 | pr_err("gpio-keys: Unable to claim irq %d; error %d\n", | 156 | pr_err("gpio-keys: Unable to claim irq %d; error %d\n", |
115 | irq, error); | 157 | irq, error); |
116 | gpio_free(button->gpio); | 158 | gpio_free(button->gpio); |
117 | goto fail; | 159 | goto fail2; |
118 | } | 160 | } |
119 | 161 | ||
120 | if (button->wakeup) | 162 | if (button->wakeup) |
@@ -127,21 +169,25 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
127 | if (error) { | 169 | if (error) { |
128 | pr_err("gpio-keys: Unable to register input device, " | 170 | pr_err("gpio-keys: Unable to register input device, " |
129 | "error: %d\n", error); | 171 | "error: %d\n", error); |
130 | goto fail; | 172 | goto fail2; |
131 | } | 173 | } |
132 | 174 | ||
133 | device_init_wakeup(&pdev->dev, wakeup); | 175 | device_init_wakeup(&pdev->dev, wakeup); |
134 | 176 | ||
135 | return 0; | 177 | return 0; |
136 | 178 | ||
137 | fail: | 179 | fail2: |
138 | while (--i >= 0) { | 180 | while (--i >= 0) { |
139 | free_irq(gpio_to_irq(pdata->buttons[i].gpio), pdev); | 181 | free_irq(gpio_to_irq(pdata->buttons[i].gpio), pdev); |
182 | if (pdata->buttons[i].debounce_interval) | ||
183 | del_timer_sync(&ddata->data[i].timer); | ||
140 | gpio_free(pdata->buttons[i].gpio); | 184 | gpio_free(pdata->buttons[i].gpio); |
141 | } | 185 | } |
142 | 186 | ||
143 | platform_set_drvdata(pdev, NULL); | 187 | platform_set_drvdata(pdev, NULL); |
188 | fail1: | ||
144 | input_free_device(input); | 189 | input_free_device(input); |
190 | kfree(ddata); | ||
145 | 191 | ||
146 | return error; | 192 | return error; |
147 | } | 193 | } |
@@ -149,7 +195,8 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
149 | static int __devexit gpio_keys_remove(struct platform_device *pdev) | 195 | static int __devexit gpio_keys_remove(struct platform_device *pdev) |
150 | { | 196 | { |
151 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | 197 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; |
152 | struct input_dev *input = platform_get_drvdata(pdev); | 198 | struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); |
199 | struct input_dev *input = ddata->input; | ||
153 | int i; | 200 | int i; |
154 | 201 | ||
155 | device_init_wakeup(&pdev->dev, 0); | 202 | device_init_wakeup(&pdev->dev, 0); |
@@ -157,6 +204,8 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev) | |||
157 | for (i = 0; i < pdata->nbuttons; i++) { | 204 | for (i = 0; i < pdata->nbuttons; i++) { |
158 | int irq = gpio_to_irq(pdata->buttons[i].gpio); | 205 | int irq = gpio_to_irq(pdata->buttons[i].gpio); |
159 | free_irq(irq, pdev); | 206 | free_irq(irq, pdev); |
207 | if (pdata->buttons[i].debounce_interval) | ||
208 | del_timer_sync(&ddata->data[i].timer); | ||
160 | gpio_free(pdata->buttons[i].gpio); | 209 | gpio_free(pdata->buttons[i].gpio); |
161 | } | 210 | } |
162 | 211 | ||
diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c index 32e2c2605d95..4730ef35c732 100644 --- a/drivers/input/keyboard/lkkbd.c +++ b/drivers/input/keyboard/lkkbd.c | |||
@@ -538,11 +538,11 @@ lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code, | |||
538 | switch (code) { | 538 | switch (code) { |
539 | case SND_CLICK: | 539 | case SND_CLICK: |
540 | if (value == 0) { | 540 | if (value == 0) { |
541 | DBG ("%s: Deactivating key clicks\n", __FUNCTION__); | 541 | DBG ("%s: Deactivating key clicks\n", __func__); |
542 | lk->serio->write (lk->serio, LK_CMD_DISABLE_KEYCLICK); | 542 | lk->serio->write (lk->serio, LK_CMD_DISABLE_KEYCLICK); |
543 | lk->serio->write (lk->serio, LK_CMD_DISABLE_CTRCLICK); | 543 | lk->serio->write (lk->serio, LK_CMD_DISABLE_CTRCLICK); |
544 | } else { | 544 | } else { |
545 | DBG ("%s: Activating key clicks\n", __FUNCTION__); | 545 | DBG ("%s: Activating key clicks\n", __func__); |
546 | lk->serio->write (lk->serio, LK_CMD_ENABLE_KEYCLICK); | 546 | lk->serio->write (lk->serio, LK_CMD_ENABLE_KEYCLICK); |
547 | lk->serio->write (lk->serio, volume_to_hw (lk->keyclick_volume)); | 547 | lk->serio->write (lk->serio, volume_to_hw (lk->keyclick_volume)); |
548 | lk->serio->write (lk->serio, LK_CMD_ENABLE_CTRCLICK); | 548 | lk->serio->write (lk->serio, LK_CMD_ENABLE_CTRCLICK); |
@@ -560,7 +560,7 @@ lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code, | |||
560 | 560 | ||
561 | default: | 561 | default: |
562 | printk (KERN_ERR "%s (): Got unknown type %d, code %d, value %d\n", | 562 | printk (KERN_ERR "%s (): Got unknown type %d, code %d, value %d\n", |
563 | __FUNCTION__, type, code, value); | 563 | __func__, type, code, value); |
564 | } | 564 | } |
565 | 565 | ||
566 | return -1; | 566 | return -1; |
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index 45767e73f071..6f1516f50750 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c | |||
@@ -105,6 +105,8 @@ struct pxa27x_keypad { | |||
105 | struct input_dev *input_dev; | 105 | struct input_dev *input_dev; |
106 | void __iomem *mmio_base; | 106 | void __iomem *mmio_base; |
107 | 107 | ||
108 | int irq; | ||
109 | |||
108 | /* matrix key code map */ | 110 | /* matrix key code map */ |
109 | unsigned int matrix_keycodes[MAX_MATRIX_KEY_NUM]; | 111 | unsigned int matrix_keycodes[MAX_MATRIX_KEY_NUM]; |
110 | 112 | ||
@@ -392,6 +394,10 @@ static int pxa27x_keypad_suspend(struct platform_device *pdev, pm_message_t stat | |||
392 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); | 394 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); |
393 | 395 | ||
394 | clk_disable(keypad->clk); | 396 | clk_disable(keypad->clk); |
397 | |||
398 | if (device_may_wakeup(&pdev->dev)) | ||
399 | enable_irq_wake(keypad->irq); | ||
400 | |||
395 | return 0; | 401 | return 0; |
396 | } | 402 | } |
397 | 403 | ||
@@ -400,6 +406,9 @@ static int pxa27x_keypad_resume(struct platform_device *pdev) | |||
400 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); | 406 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); |
401 | struct input_dev *input_dev = keypad->input_dev; | 407 | struct input_dev *input_dev = keypad->input_dev; |
402 | 408 | ||
409 | if (device_may_wakeup(&pdev->dev)) | ||
410 | disable_irq_wake(keypad->irq); | ||
411 | |||
403 | mutex_lock(&input_dev->mutex); | 412 | mutex_lock(&input_dev->mutex); |
404 | 413 | ||
405 | if (input_dev->users) { | 414 | if (input_dev->users) { |
@@ -509,6 +518,8 @@ static int __devinit pxa27x_keypad_probe(struct platform_device *pdev) | |||
509 | goto failed_free_dev; | 518 | goto failed_free_dev; |
510 | } | 519 | } |
511 | 520 | ||
521 | keypad->irq = irq; | ||
522 | |||
512 | /* Register the input device */ | 523 | /* Register the input device */ |
513 | error = input_register_device(input_dev); | 524 | error = input_register_device(input_dev); |
514 | if (error) { | 525 | if (error) { |
@@ -516,6 +527,8 @@ static int __devinit pxa27x_keypad_probe(struct platform_device *pdev) | |||
516 | goto failed_free_irq; | 527 | goto failed_free_irq; |
517 | } | 528 | } |
518 | 529 | ||
530 | device_init_wakeup(&pdev->dev, 1); | ||
531 | |||
519 | return 0; | 532 | return 0; |
520 | 533 | ||
521 | failed_free_irq: | 534 | failed_free_irq: |
@@ -539,7 +552,7 @@ static int __devexit pxa27x_keypad_remove(struct platform_device *pdev) | |||
539 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); | 552 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); |
540 | struct resource *res; | 553 | struct resource *res; |
541 | 554 | ||
542 | free_irq(platform_get_irq(pdev, 0), pdev); | 555 | free_irq(keypad->irq, pdev); |
543 | 556 | ||
544 | clk_disable(keypad->clk); | 557 | clk_disable(keypad->clk); |
545 | clk_put(keypad->clk); | 558 | clk_put(keypad->clk); |
diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c index be0f5d19d023..9fce6d1e29b2 100644 --- a/drivers/input/keyboard/sunkbd.c +++ b/drivers/input/keyboard/sunkbd.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: sunkbd.c,v 1.14 2001/09/25 10:12:07 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 1999-2001 Vojtech Pavlik | 2 | * Copyright (c) 1999-2001 Vojtech Pavlik |
5 | */ | 3 | */ |
6 | 4 | ||
diff --git a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c index 152a2c070508..37b01d777a4a 100644 --- a/drivers/input/keyboard/xtkbd.c +++ b/drivers/input/keyboard/xtkbd.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: xtkbd.c,v 1.11 2001/09/25 10:12:07 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 1999-2001 Vojtech Pavlik | 2 | * Copyright (c) 1999-2001 Vojtech Pavlik |
5 | */ | 3 | */ |
6 | 4 | ||
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 432699d61c58..e99b7882f382 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
@@ -189,6 +189,16 @@ config INPUT_UINPUT | |||
189 | To compile this driver as a module, choose M here: the | 189 | To compile this driver as a module, choose M here: the |
190 | module will be called uinput. | 190 | module will be called uinput. |
191 | 191 | ||
192 | config INPUT_SGI_BTNS | ||
193 | tristate "SGI Indy/O2 volume button interface" | ||
194 | depends on SGI_IP22 || SGI_IP32 | ||
195 | select INPUT_POLLDEV | ||
196 | help | ||
197 | Say Y here if you want to support SGI Indy/O2 volume button interface. | ||
198 | |||
199 | To compile this driver as a module, choose M here: the | ||
200 | module will be called sgi_btns. | ||
201 | |||
192 | config HP_SDC_RTC | 202 | config HP_SDC_RTC |
193 | tristate "HP SDC Real Time Clock" | 203 | tristate "HP SDC Real Time Clock" |
194 | depends on GSC || HP300 | 204 | depends on GSC || HP300 |
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index ebd39f291d25..f48009b52226 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile | |||
@@ -19,3 +19,4 @@ obj-$(CONFIG_INPUT_YEALINK) += yealink.o | |||
19 | obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o | 19 | obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o |
20 | obj-$(CONFIG_INPUT_UINPUT) += uinput.o | 20 | obj-$(CONFIG_INPUT_UINPUT) += uinput.o |
21 | obj-$(CONFIG_INPUT_APANEL) += apanel.o | 21 | obj-$(CONFIG_INPUT_APANEL) += apanel.o |
22 | obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o | ||
diff --git a/drivers/input/misc/ati_remote.c b/drivers/input/misc/ati_remote.c index f3b86c2b0797..debfc1af9d95 100644 --- a/drivers/input/misc/ati_remote.c +++ b/drivers/input/misc/ati_remote.c | |||
@@ -330,7 +330,7 @@ static int ati_remote_open(struct input_dev *inputdev) | |||
330 | ati_remote->irq_urb->dev = ati_remote->udev; | 330 | ati_remote->irq_urb->dev = ati_remote->udev; |
331 | if (usb_submit_urb(ati_remote->irq_urb, GFP_KERNEL)) { | 331 | if (usb_submit_urb(ati_remote->irq_urb, GFP_KERNEL)) { |
332 | dev_err(&ati_remote->interface->dev, | 332 | dev_err(&ati_remote->interface->dev, |
333 | "%s: usb_submit_urb failed!\n", __FUNCTION__); | 333 | "%s: usb_submit_urb failed!\n", __func__); |
334 | return -EIO; | 334 | return -EIO; |
335 | } | 335 | } |
336 | 336 | ||
@@ -356,7 +356,7 @@ static void ati_remote_irq_out(struct urb *urb) | |||
356 | 356 | ||
357 | if (urb->status) { | 357 | if (urb->status) { |
358 | dev_dbg(&ati_remote->interface->dev, "%s: status %d\n", | 358 | dev_dbg(&ati_remote->interface->dev, "%s: status %d\n", |
359 | __FUNCTION__, urb->status); | 359 | __func__, urb->status); |
360 | return; | 360 | return; |
361 | } | 361 | } |
362 | 362 | ||
@@ -601,17 +601,17 @@ static void ati_remote_irq_in(struct urb *urb) | |||
601 | case -ENOENT: | 601 | case -ENOENT: |
602 | case -ESHUTDOWN: | 602 | case -ESHUTDOWN: |
603 | dev_dbg(&ati_remote->interface->dev, "%s: urb error status, unlink? \n", | 603 | dev_dbg(&ati_remote->interface->dev, "%s: urb error status, unlink? \n", |
604 | __FUNCTION__); | 604 | __func__); |
605 | return; | 605 | return; |
606 | default: /* error */ | 606 | default: /* error */ |
607 | dev_dbg(&ati_remote->interface->dev, "%s: Nonzero urb status %d\n", | 607 | dev_dbg(&ati_remote->interface->dev, "%s: Nonzero urb status %d\n", |
608 | __FUNCTION__, urb->status); | 608 | __func__, urb->status); |
609 | } | 609 | } |
610 | 610 | ||
611 | retval = usb_submit_urb(urb, GFP_ATOMIC); | 611 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
612 | if (retval) | 612 | if (retval) |
613 | dev_err(&ati_remote->interface->dev, "%s: usb_submit_urb()=%d\n", | 613 | dev_err(&ati_remote->interface->dev, "%s: usb_submit_urb()=%d\n", |
614 | __FUNCTION__, retval); | 614 | __func__, retval); |
615 | } | 615 | } |
616 | 616 | ||
617 | /* | 617 | /* |
@@ -734,7 +734,7 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de | |||
734 | int err = -ENOMEM; | 734 | int err = -ENOMEM; |
735 | 735 | ||
736 | if (iface_host->desc.bNumEndpoints != 2) { | 736 | if (iface_host->desc.bNumEndpoints != 2) { |
737 | err("%s: Unexpected desc.bNumEndpoints\n", __FUNCTION__); | 737 | err("%s: Unexpected desc.bNumEndpoints\n", __func__); |
738 | return -ENODEV; | 738 | return -ENODEV; |
739 | } | 739 | } |
740 | 740 | ||
@@ -742,11 +742,11 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de | |||
742 | endpoint_out = &iface_host->endpoint[1].desc; | 742 | endpoint_out = &iface_host->endpoint[1].desc; |
743 | 743 | ||
744 | if (!usb_endpoint_is_int_in(endpoint_in)) { | 744 | if (!usb_endpoint_is_int_in(endpoint_in)) { |
745 | err("%s: Unexpected endpoint_in\n", __FUNCTION__); | 745 | err("%s: Unexpected endpoint_in\n", __func__); |
746 | return -ENODEV; | 746 | return -ENODEV; |
747 | } | 747 | } |
748 | if (le16_to_cpu(endpoint_in->wMaxPacketSize) == 0) { | 748 | if (le16_to_cpu(endpoint_in->wMaxPacketSize) == 0) { |
749 | err("%s: endpoint_in message size==0? \n", __FUNCTION__); | 749 | err("%s: endpoint_in message size==0? \n", __func__); |
750 | return -ENODEV; | 750 | return -ENODEV; |
751 | } | 751 | } |
752 | 752 | ||
@@ -814,7 +814,7 @@ static void ati_remote_disconnect(struct usb_interface *interface) | |||
814 | ati_remote = usb_get_intfdata(interface); | 814 | ati_remote = usb_get_intfdata(interface); |
815 | usb_set_intfdata(interface, NULL); | 815 | usb_set_intfdata(interface, NULL); |
816 | if (!ati_remote) { | 816 | if (!ati_remote) { |
817 | warn("%s - null device?\n", __FUNCTION__); | 817 | warn("%s - null device?\n", __func__); |
818 | return; | 818 | return; |
819 | } | 819 | } |
820 | 820 | ||
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c index f2709b82485c..a7fabafbd94c 100644 --- a/drivers/input/misc/ati_remote2.c +++ b/drivers/input/misc/ati_remote2.c | |||
@@ -137,14 +137,14 @@ static int ati_remote2_open(struct input_dev *idev) | |||
137 | r = usb_submit_urb(ar2->urb[0], GFP_KERNEL); | 137 | r = usb_submit_urb(ar2->urb[0], GFP_KERNEL); |
138 | if (r) { | 138 | if (r) { |
139 | dev_err(&ar2->intf[0]->dev, | 139 | dev_err(&ar2->intf[0]->dev, |
140 | "%s: usb_submit_urb() = %d\n", __FUNCTION__, r); | 140 | "%s: usb_submit_urb() = %d\n", __func__, r); |
141 | return r; | 141 | return r; |
142 | } | 142 | } |
143 | r = usb_submit_urb(ar2->urb[1], GFP_KERNEL); | 143 | r = usb_submit_urb(ar2->urb[1], GFP_KERNEL); |
144 | if (r) { | 144 | if (r) { |
145 | usb_kill_urb(ar2->urb[0]); | 145 | usb_kill_urb(ar2->urb[0]); |
146 | dev_err(&ar2->intf[1]->dev, | 146 | dev_err(&ar2->intf[1]->dev, |
147 | "%s: usb_submit_urb() = %d\n", __FUNCTION__, r); | 147 | "%s: usb_submit_urb() = %d\n", __func__, r); |
148 | return r; | 148 | return r; |
149 | } | 149 | } |
150 | 150 | ||
@@ -294,17 +294,17 @@ static void ati_remote2_complete_mouse(struct urb *urb) | |||
294 | case -ECONNRESET: | 294 | case -ECONNRESET: |
295 | case -ESHUTDOWN: | 295 | case -ESHUTDOWN: |
296 | dev_dbg(&ar2->intf[0]->dev, | 296 | dev_dbg(&ar2->intf[0]->dev, |
297 | "%s(): urb status = %d\n", __FUNCTION__, urb->status); | 297 | "%s(): urb status = %d\n", __func__, urb->status); |
298 | return; | 298 | return; |
299 | default: | 299 | default: |
300 | dev_err(&ar2->intf[0]->dev, | 300 | dev_err(&ar2->intf[0]->dev, |
301 | "%s(): urb status = %d\n", __FUNCTION__, urb->status); | 301 | "%s(): urb status = %d\n", __func__, urb->status); |
302 | } | 302 | } |
303 | 303 | ||
304 | r = usb_submit_urb(urb, GFP_ATOMIC); | 304 | r = usb_submit_urb(urb, GFP_ATOMIC); |
305 | if (r) | 305 | if (r) |
306 | dev_err(&ar2->intf[0]->dev, | 306 | dev_err(&ar2->intf[0]->dev, |
307 | "%s(): usb_submit_urb() = %d\n", __FUNCTION__, r); | 307 | "%s(): usb_submit_urb() = %d\n", __func__, r); |
308 | } | 308 | } |
309 | 309 | ||
310 | static void ati_remote2_complete_key(struct urb *urb) | 310 | static void ati_remote2_complete_key(struct urb *urb) |
@@ -321,17 +321,17 @@ static void ati_remote2_complete_key(struct urb *urb) | |||
321 | case -ECONNRESET: | 321 | case -ECONNRESET: |
322 | case -ESHUTDOWN: | 322 | case -ESHUTDOWN: |
323 | dev_dbg(&ar2->intf[1]->dev, | 323 | dev_dbg(&ar2->intf[1]->dev, |
324 | "%s(): urb status = %d\n", __FUNCTION__, urb->status); | 324 | "%s(): urb status = %d\n", __func__, urb->status); |
325 | return; | 325 | return; |
326 | default: | 326 | default: |
327 | dev_err(&ar2->intf[1]->dev, | 327 | dev_err(&ar2->intf[1]->dev, |
328 | "%s(): urb status = %d\n", __FUNCTION__, urb->status); | 328 | "%s(): urb status = %d\n", __func__, urb->status); |
329 | } | 329 | } |
330 | 330 | ||
331 | r = usb_submit_urb(urb, GFP_ATOMIC); | 331 | r = usb_submit_urb(urb, GFP_ATOMIC); |
332 | if (r) | 332 | if (r) |
333 | dev_err(&ar2->intf[1]->dev, | 333 | dev_err(&ar2->intf[1]->dev, |
334 | "%s(): usb_submit_urb() = %d\n", __FUNCTION__, r); | 334 | "%s(): usb_submit_urb() = %d\n", __func__, r); |
335 | } | 335 | } |
336 | 336 | ||
337 | static int ati_remote2_input_init(struct ati_remote2 *ar2) | 337 | static int ati_remote2_input_init(struct ati_remote2 *ar2) |
@@ -438,7 +438,7 @@ static int ati_remote2_setup(struct ati_remote2 *ar2) | |||
438 | channel, 0x0, NULL, 0, USB_CTRL_SET_TIMEOUT); | 438 | channel, 0x0, NULL, 0, USB_CTRL_SET_TIMEOUT); |
439 | if (r) { | 439 | if (r) { |
440 | dev_err(&ar2->udev->dev, "%s - failed to set channel due to error: %d\n", | 440 | dev_err(&ar2->udev->dev, "%s - failed to set channel due to error: %d\n", |
441 | __FUNCTION__, r); | 441 | __func__, r); |
442 | return r; | 442 | return r; |
443 | } | 443 | } |
444 | 444 | ||
diff --git a/drivers/input/misc/keyspan_remote.c b/drivers/input/misc/keyspan_remote.c index 952938a8e991..86afdd1fdf9d 100644 --- a/drivers/input/misc/keyspan_remote.c +++ b/drivers/input/misc/keyspan_remote.c | |||
@@ -159,7 +159,7 @@ static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed) | |||
159 | if (dev->data.pos >= dev->data.len) { | 159 | if (dev->data.pos >= dev->data.len) { |
160 | dev_dbg(&dev->udev->dev, | 160 | dev_dbg(&dev->udev->dev, |
161 | "%s - Error ran out of data. pos: %d, len: %d\n", | 161 | "%s - Error ran out of data. pos: %d, len: %d\n", |
162 | __FUNCTION__, dev->data.pos, dev->data.len); | 162 | __func__, dev->data.pos, dev->data.len); |
163 | return -1; | 163 | return -1; |
164 | } | 164 | } |
165 | 165 | ||
@@ -267,7 +267,7 @@ static void keyspan_check_data(struct usb_keyspan *remote) | |||
267 | remote->data.tester = remote->data.tester >> 6; | 267 | remote->data.tester = remote->data.tester >> 6; |
268 | remote->data.bits_left -= 6; | 268 | remote->data.bits_left -= 6; |
269 | } else { | 269 | } else { |
270 | err("%s - Unknown sequence found in system data.\n", __FUNCTION__); | 270 | err("%s - Unknown sequence found in system data.\n", __func__); |
271 | remote->stage = 0; | 271 | remote->stage = 0; |
272 | return; | 272 | return; |
273 | } | 273 | } |
@@ -286,7 +286,7 @@ static void keyspan_check_data(struct usb_keyspan *remote) | |||
286 | remote->data.tester = remote->data.tester >> 6; | 286 | remote->data.tester = remote->data.tester >> 6; |
287 | remote->data.bits_left -= 6; | 287 | remote->data.bits_left -= 6; |
288 | } else { | 288 | } else { |
289 | err("%s - Unknown sequence found in button data.\n", __FUNCTION__); | 289 | err("%s - Unknown sequence found in button data.\n", __func__); |
290 | remote->stage = 0; | 290 | remote->stage = 0; |
291 | return; | 291 | return; |
292 | } | 292 | } |
@@ -302,7 +302,7 @@ static void keyspan_check_data(struct usb_keyspan *remote) | |||
302 | remote->data.tester = remote->data.tester >> 6; | 302 | remote->data.tester = remote->data.tester >> 6; |
303 | remote->data.bits_left -= 6; | 303 | remote->data.bits_left -= 6; |
304 | } else { | 304 | } else { |
305 | err("%s - Error in message, invalid toggle.\n", __FUNCTION__); | 305 | err("%s - Error in message, invalid toggle.\n", __func__); |
306 | remote->stage = 0; | 306 | remote->stage = 0; |
307 | return; | 307 | return; |
308 | } | 308 | } |
@@ -317,7 +317,7 @@ static void keyspan_check_data(struct usb_keyspan *remote) | |||
317 | 317 | ||
318 | dev_dbg(&remote->udev->dev, | 318 | dev_dbg(&remote->udev->dev, |
319 | "%s found valid message: system: %d, button: %d, toggle: %d\n", | 319 | "%s found valid message: system: %d, button: %d, toggle: %d\n", |
320 | __FUNCTION__, message.system, message.button, message.toggle); | 320 | __func__, message.system, message.button, message.toggle); |
321 | 321 | ||
322 | if (message.toggle != remote->toggle) { | 322 | if (message.toggle != remote->toggle) { |
323 | keyspan_report_button(remote, message.button, 1); | 323 | keyspan_report_button(remote, message.button, 1); |
@@ -341,7 +341,7 @@ static int keyspan_setup(struct usb_device* dev) | |||
341 | 0x11, 0x40, 0x5601, 0x0, NULL, 0, 0); | 341 | 0x11, 0x40, 0x5601, 0x0, NULL, 0, 0); |
342 | if (retval) { | 342 | if (retval) { |
343 | dev_dbg(&dev->dev, "%s - failed to set bit rate due to error: %d\n", | 343 | dev_dbg(&dev->dev, "%s - failed to set bit rate due to error: %d\n", |
344 | __FUNCTION__, retval); | 344 | __func__, retval); |
345 | return(retval); | 345 | return(retval); |
346 | } | 346 | } |
347 | 347 | ||
@@ -349,7 +349,7 @@ static int keyspan_setup(struct usb_device* dev) | |||
349 | 0x44, 0x40, 0x0, 0x0, NULL, 0, 0); | 349 | 0x44, 0x40, 0x0, 0x0, NULL, 0, 0); |
350 | if (retval) { | 350 | if (retval) { |
351 | dev_dbg(&dev->dev, "%s - failed to set resume sensitivity due to error: %d\n", | 351 | dev_dbg(&dev->dev, "%s - failed to set resume sensitivity due to error: %d\n", |
352 | __FUNCTION__, retval); | 352 | __func__, retval); |
353 | return(retval); | 353 | return(retval); |
354 | } | 354 | } |
355 | 355 | ||
@@ -357,11 +357,11 @@ static int keyspan_setup(struct usb_device* dev) | |||
357 | 0x22, 0x40, 0x0, 0x0, NULL, 0, 0); | 357 | 0x22, 0x40, 0x0, 0x0, NULL, 0, 0); |
358 | if (retval) { | 358 | if (retval) { |
359 | dev_dbg(&dev->dev, "%s - failed to turn receive on due to error: %d\n", | 359 | dev_dbg(&dev->dev, "%s - failed to turn receive on due to error: %d\n", |
360 | __FUNCTION__, retval); | 360 | __func__, retval); |
361 | return(retval); | 361 | return(retval); |
362 | } | 362 | } |
363 | 363 | ||
364 | dev_dbg(&dev->dev, "%s - Setup complete.\n", __FUNCTION__); | 364 | dev_dbg(&dev->dev, "%s - Setup complete.\n", __func__); |
365 | return(retval); | 365 | return(retval); |
366 | } | 366 | } |
367 | 367 | ||
@@ -397,7 +397,7 @@ static void keyspan_irq_recv(struct urb *urb) | |||
397 | resubmit: | 397 | resubmit: |
398 | retval = usb_submit_urb(urb, GFP_ATOMIC); | 398 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
399 | if (retval) | 399 | if (retval) |
400 | err ("%s - usb_submit_urb failed with result: %d", __FUNCTION__, retval); | 400 | err ("%s - usb_submit_urb failed with result: %d", __func__, retval); |
401 | } | 401 | } |
402 | 402 | ||
403 | static int keyspan_open(struct input_dev *dev) | 403 | static int keyspan_open(struct input_dev *dev) |
diff --git a/drivers/input/misc/powermate.c b/drivers/input/misc/powermate.c index 7a7b8c7b9633..a53c4885fbad 100644 --- a/drivers/input/misc/powermate.c +++ b/drivers/input/misc/powermate.c | |||
@@ -96,10 +96,10 @@ static void powermate_irq(struct urb *urb) | |||
96 | case -ENOENT: | 96 | case -ENOENT: |
97 | case -ESHUTDOWN: | 97 | case -ESHUTDOWN: |
98 | /* this urb is terminated, clean up */ | 98 | /* this urb is terminated, clean up */ |
99 | dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); | 99 | dbg("%s - urb shutting down with status: %d", __func__, urb->status); |
100 | return; | 100 | return; |
101 | default: | 101 | default: |
102 | dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); | 102 | dbg("%s - nonzero urb status received: %d", __func__, urb->status); |
103 | goto exit; | 103 | goto exit; |
104 | } | 104 | } |
105 | 105 | ||
@@ -112,7 +112,7 @@ exit: | |||
112 | retval = usb_submit_urb (urb, GFP_ATOMIC); | 112 | retval = usb_submit_urb (urb, GFP_ATOMIC); |
113 | if (retval) | 113 | if (retval) |
114 | err ("%s - usb_submit_urb failed with result %d", | 114 | err ("%s - usb_submit_urb failed with result %d", |
115 | __FUNCTION__, retval); | 115 | __func__, retval); |
116 | } | 116 | } |
117 | 117 | ||
118 | /* Decide if we need to issue a control message and do so. Must be called with pm->lock taken */ | 118 | /* Decide if we need to issue a control message and do so. Must be called with pm->lock taken */ |
diff --git a/drivers/input/misc/sgi_btns.c b/drivers/input/misc/sgi_btns.c new file mode 100644 index 000000000000..ce238f59b3c8 --- /dev/null +++ b/drivers/input/misc/sgi_btns.c | |||
@@ -0,0 +1,178 @@ | |||
1 | /* | ||
2 | * SGI Volume Button interface driver | ||
3 | * | ||
4 | * Copyright (C) 2008 Thomas Bogendoerfer <tsbogend@alpha.franken.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | */ | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/input-polldev.h> | ||
22 | #include <linux/ioport.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | |||
26 | #ifdef CONFIG_SGI_IP22 | ||
27 | #include <asm/sgi/ioc.h> | ||
28 | |||
29 | static inline u8 button_status(void) | ||
30 | { | ||
31 | u8 status; | ||
32 | |||
33 | status = readb(&sgioc->panel) ^ 0xa0; | ||
34 | return ((status & 0x80) >> 6) | ((status & 0x20) >> 5); | ||
35 | } | ||
36 | #endif | ||
37 | |||
38 | #ifdef CONFIG_SGI_IP32 | ||
39 | #include <asm/ip32/mace.h> | ||
40 | |||
41 | static inline u8 button_status(void) | ||
42 | { | ||
43 | u64 status; | ||
44 | |||
45 | status = readq(&mace->perif.audio.control); | ||
46 | writeq(status & ~(3U << 23), &mace->perif.audio.control); | ||
47 | |||
48 | return (status >> 23) & 3; | ||
49 | } | ||
50 | #endif | ||
51 | |||
52 | #define BUTTONS_POLL_INTERVAL 30 /* msec */ | ||
53 | #define BUTTONS_COUNT_THRESHOLD 3 | ||
54 | |||
55 | static const unsigned short sgi_map[] = { | ||
56 | KEY_VOLUMEDOWN, | ||
57 | KEY_VOLUMEUP | ||
58 | }; | ||
59 | |||
60 | struct buttons_dev { | ||
61 | struct input_polled_dev *poll_dev; | ||
62 | unsigned short keymap[ARRAY_SIZE(sgi_map)]; | ||
63 | int count[ARRAY_SIZE(sgi_map)]; | ||
64 | }; | ||
65 | |||
66 | static void handle_buttons(struct input_polled_dev *dev) | ||
67 | { | ||
68 | struct buttons_dev *bdev = dev->private; | ||
69 | struct input_dev *input = dev->input; | ||
70 | u8 status; | ||
71 | int i; | ||
72 | |||
73 | status = button_status(); | ||
74 | |||
75 | for (i = 0; i < ARRAY_SIZE(bdev->keymap); i++) { | ||
76 | if (status & (1U << i)) { | ||
77 | if (++bdev->count[i] == BUTTONS_COUNT_THRESHOLD) { | ||
78 | input_event(input, EV_MSC, MSC_SCAN, i); | ||
79 | input_report_key(input, bdev->keymap[i], 1); | ||
80 | input_sync(input); | ||
81 | } | ||
82 | } else { | ||
83 | if (bdev->count[i] >= BUTTONS_COUNT_THRESHOLD) { | ||
84 | input_event(input, EV_MSC, MSC_SCAN, i); | ||
85 | input_report_key(input, bdev->keymap[i], 0); | ||
86 | input_sync(input); | ||
87 | } | ||
88 | bdev->count[i] = 0; | ||
89 | } | ||
90 | } | ||
91 | } | ||
92 | |||
93 | static int __devinit sgi_buttons_probe(struct platform_device *pdev) | ||
94 | { | ||
95 | struct buttons_dev *bdev; | ||
96 | struct input_polled_dev *poll_dev; | ||
97 | struct input_dev *input; | ||
98 | int error, i; | ||
99 | |||
100 | bdev = kzalloc(sizeof(struct buttons_dev), GFP_KERNEL); | ||
101 | poll_dev = input_allocate_polled_device(); | ||
102 | if (!bdev || !poll_dev) { | ||
103 | error = -ENOMEM; | ||
104 | goto err_free_mem; | ||
105 | } | ||
106 | |||
107 | memcpy(bdev->keymap, sgi_map, sizeof(bdev->keymap)); | ||
108 | |||
109 | poll_dev->private = bdev; | ||
110 | poll_dev->poll = handle_buttons; | ||
111 | poll_dev->poll_interval = BUTTONS_POLL_INTERVAL; | ||
112 | |||
113 | input = poll_dev->input; | ||
114 | input->name = "SGI buttons"; | ||
115 | input->phys = "sgi/input0"; | ||
116 | input->id.bustype = BUS_HOST; | ||
117 | input->dev.parent = &pdev->dev; | ||
118 | |||
119 | input->keycode = bdev->keymap; | ||
120 | input->keycodemax = ARRAY_SIZE(bdev->keymap); | ||
121 | input->keycodesize = sizeof(unsigned short); | ||
122 | |||
123 | input_set_capability(input, EV_MSC, MSC_SCAN); | ||
124 | __set_bit(EV_KEY, input->evbit); | ||
125 | for (i = 0; i < ARRAY_SIZE(sgi_map); i++) | ||
126 | __set_bit(bdev->keymap[i], input->keybit); | ||
127 | __clear_bit(KEY_RESERVED, input->keybit); | ||
128 | |||
129 | bdev->poll_dev = poll_dev; | ||
130 | dev_set_drvdata(&pdev->dev, bdev); | ||
131 | |||
132 | error = input_register_polled_device(poll_dev); | ||
133 | if (error) | ||
134 | goto err_free_mem; | ||
135 | |||
136 | return 0; | ||
137 | |||
138 | err_free_mem: | ||
139 | input_free_polled_device(poll_dev); | ||
140 | kfree(bdev); | ||
141 | dev_set_drvdata(&pdev->dev, NULL); | ||
142 | return error; | ||
143 | } | ||
144 | |||
145 | static int __devexit sgi_buttons_remove(struct platform_device *pdev) | ||
146 | { | ||
147 | struct device *dev = &pdev->dev; | ||
148 | struct buttons_dev *bdev = dev_get_drvdata(dev); | ||
149 | |||
150 | input_unregister_polled_device(bdev->poll_dev); | ||
151 | input_free_polled_device(bdev->poll_dev); | ||
152 | kfree(bdev); | ||
153 | dev_set_drvdata(dev, NULL); | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | static struct platform_driver sgi_buttons_driver = { | ||
159 | .probe = sgi_buttons_probe, | ||
160 | .remove = __devexit_p(sgi_buttons_remove), | ||
161 | .driver = { | ||
162 | .name = "sgibtns", | ||
163 | .owner = THIS_MODULE, | ||
164 | }, | ||
165 | }; | ||
166 | |||
167 | static int __init sgi_buttons_init(void) | ||
168 | { | ||
169 | return platform_driver_register(&sgi_buttons_driver); | ||
170 | } | ||
171 | |||
172 | static void __exit sgi_buttons_exit(void) | ||
173 | { | ||
174 | platform_driver_unregister(&sgi_buttons_driver); | ||
175 | } | ||
176 | |||
177 | module_init(sgi_buttons_init); | ||
178 | module_exit(sgi_buttons_exit); | ||
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index 72176f3d49cb..fe268be3293b 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c | |||
@@ -1186,7 +1186,7 @@ static int wistron_setkeycode(struct input_dev *dev, int scancode, int keycode) | |||
1186 | 1186 | ||
1187 | static int __devinit setup_input_dev(void) | 1187 | static int __devinit setup_input_dev(void) |
1188 | { | 1188 | { |
1189 | const struct key_entry *key; | 1189 | struct key_entry *key; |
1190 | struct input_dev *input_dev; | 1190 | struct input_dev *input_dev; |
1191 | int error; | 1191 | int error; |
1192 | 1192 | ||
@@ -1219,6 +1219,23 @@ static int __devinit setup_input_dev(void) | |||
1219 | set_bit(key->sw.code, input_dev->swbit); | 1219 | set_bit(key->sw.code, input_dev->swbit); |
1220 | break; | 1220 | break; |
1221 | 1221 | ||
1222 | /* if wifi or bluetooth are not available, create normal keys */ | ||
1223 | case KE_WIFI: | ||
1224 | if (!have_wifi) { | ||
1225 | key->type = KE_KEY; | ||
1226 | key->keycode = KEY_WLAN; | ||
1227 | key--; | ||
1228 | } | ||
1229 | break; | ||
1230 | |||
1231 | case KE_BLUETOOTH: | ||
1232 | if (!have_bluetooth) { | ||
1233 | key->type = KE_KEY; | ||
1234 | key->keycode = KEY_BLUETOOTH; | ||
1235 | key--; | ||
1236 | } | ||
1237 | break; | ||
1238 | |||
1222 | default: | 1239 | default: |
1223 | break; | 1240 | break; |
1224 | } | 1241 | } |
diff --git a/drivers/input/misc/yealink.c b/drivers/input/misc/yealink.c index 46279ef2b649..facefd3dba29 100644 --- a/drivers/input/misc/yealink.c +++ b/drivers/input/misc/yealink.c | |||
@@ -119,6 +119,8 @@ struct yealink_dev { | |||
119 | u8 lcdMap[ARRAY_SIZE(lcdMap)]; /* state of LCD, LED ... */ | 119 | u8 lcdMap[ARRAY_SIZE(lcdMap)]; /* state of LCD, LED ... */ |
120 | int key_code; /* last reported key */ | 120 | int key_code; /* last reported key */ |
121 | 121 | ||
122 | unsigned int shutdown:1; | ||
123 | |||
122 | int stat_ix; | 124 | int stat_ix; |
123 | union { | 125 | union { |
124 | struct yld_status s; | 126 | struct yld_status s; |
@@ -424,10 +426,10 @@ send_update: | |||
424 | static void urb_irq_callback(struct urb *urb) | 426 | static void urb_irq_callback(struct urb *urb) |
425 | { | 427 | { |
426 | struct yealink_dev *yld = urb->context; | 428 | struct yealink_dev *yld = urb->context; |
427 | int ret; | 429 | int ret, status = urb->status; |
428 | 430 | ||
429 | if (urb->status) | 431 | if (status) |
430 | err("%s - urb status %d", __FUNCTION__, urb->status); | 432 | err("%s - urb status %d", __func__, status); |
431 | 433 | ||
432 | switch (yld->irq_data->cmd) { | 434 | switch (yld->irq_data->cmd) { |
433 | case CMD_KEYPRESS: | 435 | case CMD_KEYPRESS: |
@@ -447,33 +449,38 @@ static void urb_irq_callback(struct urb *urb) | |||
447 | 449 | ||
448 | yealink_do_idle_tasks(yld); | 450 | yealink_do_idle_tasks(yld); |
449 | 451 | ||
450 | ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC); | 452 | if (!yld->shutdown) { |
451 | if (ret) | 453 | ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC); |
452 | err("%s - usb_submit_urb failed %d", __FUNCTION__, ret); | 454 | if (ret && ret != -EPERM) |
455 | err("%s - usb_submit_urb failed %d", __func__, ret); | ||
456 | } | ||
453 | } | 457 | } |
454 | 458 | ||
455 | static void urb_ctl_callback(struct urb *urb) | 459 | static void urb_ctl_callback(struct urb *urb) |
456 | { | 460 | { |
457 | struct yealink_dev *yld = urb->context; | 461 | struct yealink_dev *yld = urb->context; |
458 | int ret; | 462 | int ret = 0, status = urb->status; |
459 | 463 | ||
460 | if (urb->status) | 464 | if (status) |
461 | err("%s - urb status %d", __FUNCTION__, urb->status); | 465 | err("%s - urb status %d", __func__, status); |
462 | 466 | ||
463 | switch (yld->ctl_data->cmd) { | 467 | switch (yld->ctl_data->cmd) { |
464 | case CMD_KEYPRESS: | 468 | case CMD_KEYPRESS: |
465 | case CMD_SCANCODE: | 469 | case CMD_SCANCODE: |
466 | /* ask for a response */ | 470 | /* ask for a response */ |
467 | ret = usb_submit_urb(yld->urb_irq, GFP_ATOMIC); | 471 | if (!yld->shutdown) |
472 | ret = usb_submit_urb(yld->urb_irq, GFP_ATOMIC); | ||
468 | break; | 473 | break; |
469 | default: | 474 | default: |
470 | /* send new command */ | 475 | /* send new command */ |
471 | yealink_do_idle_tasks(yld); | 476 | yealink_do_idle_tasks(yld); |
472 | ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC); | 477 | if (!yld->shutdown) |
478 | ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC); | ||
479 | break; | ||
473 | } | 480 | } |
474 | 481 | ||
475 | if (ret) | 482 | if (ret && ret != -EPERM) |
476 | err("%s - usb_submit_urb failed %d", __FUNCTION__, ret); | 483 | err("%s - usb_submit_urb failed %d", __func__, ret); |
477 | } | 484 | } |
478 | 485 | ||
479 | /******************************************************************************* | 486 | /******************************************************************************* |
@@ -505,7 +512,7 @@ static int input_open(struct input_dev *dev) | |||
505 | struct yealink_dev *yld = input_get_drvdata(dev); | 512 | struct yealink_dev *yld = input_get_drvdata(dev); |
506 | int i, ret; | 513 | int i, ret; |
507 | 514 | ||
508 | dbg("%s", __FUNCTION__); | 515 | dbg("%s", __func__); |
509 | 516 | ||
510 | /* force updates to device */ | 517 | /* force updates to device */ |
511 | for (i = 0; i<sizeof(yld->master); i++) | 518 | for (i = 0; i<sizeof(yld->master); i++) |
@@ -521,7 +528,7 @@ static int input_open(struct input_dev *dev) | |||
521 | yld->ctl_data->sum = 0x100-CMD_INIT-10; | 528 | yld->ctl_data->sum = 0x100-CMD_INIT-10; |
522 | if ((ret = usb_submit_urb(yld->urb_ctl, GFP_KERNEL)) != 0) { | 529 | if ((ret = usb_submit_urb(yld->urb_ctl, GFP_KERNEL)) != 0) { |
523 | dbg("%s - usb_submit_urb failed with result %d", | 530 | dbg("%s - usb_submit_urb failed with result %d", |
524 | __FUNCTION__, ret); | 531 | __func__, ret); |
525 | return ret; | 532 | return ret; |
526 | } | 533 | } |
527 | return 0; | 534 | return 0; |
@@ -531,8 +538,18 @@ static void input_close(struct input_dev *dev) | |||
531 | { | 538 | { |
532 | struct yealink_dev *yld = input_get_drvdata(dev); | 539 | struct yealink_dev *yld = input_get_drvdata(dev); |
533 | 540 | ||
541 | yld->shutdown = 1; | ||
542 | /* | ||
543 | * Make sure the flag is seen by other CPUs before we start | ||
544 | * killing URBs so new URBs won't be submitted | ||
545 | */ | ||
546 | smp_wmb(); | ||
547 | |||
534 | usb_kill_urb(yld->urb_ctl); | 548 | usb_kill_urb(yld->urb_ctl); |
535 | usb_kill_urb(yld->urb_irq); | 549 | usb_kill_urb(yld->urb_irq); |
550 | |||
551 | yld->shutdown = 0; | ||
552 | smp_wmb(); | ||
536 | } | 553 | } |
537 | 554 | ||
538 | /******************************************************************************* | 555 | /******************************************************************************* |
@@ -809,9 +826,6 @@ static int usb_cleanup(struct yealink_dev *yld, int err) | |||
809 | if (yld == NULL) | 826 | if (yld == NULL) |
810 | return err; | 827 | return err; |
811 | 828 | ||
812 | usb_kill_urb(yld->urb_irq); /* parameter validation in core/urb */ | ||
813 | usb_kill_urb(yld->urb_ctl); /* parameter validation in core/urb */ | ||
814 | |||
815 | if (yld->idev) { | 829 | if (yld->idev) { |
816 | if (err) | 830 | if (err) |
817 | input_free_device(yld->idev); | 831 | input_free_device(yld->idev); |
diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c index ce6fdec19e14..1f41ae94f26b 100644 --- a/drivers/input/mouse/appletouch.c +++ b/drivers/input/mouse/appletouch.c | |||
@@ -2,12 +2,13 @@ | |||
2 | * Apple USB Touchpad (for post-February 2005 PowerBooks and MacBooks) driver | 2 | * Apple USB Touchpad (for post-February 2005 PowerBooks and MacBooks) driver |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com) | 4 | * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com) |
5 | * Copyright (C) 2005 Johannes Berg (johannes@sipsolutions.net) | 5 | * Copyright (C) 2005-2008 Johannes Berg (johannes@sipsolutions.net) |
6 | * Copyright (C) 2005 Stelian Pop (stelian@popies.net) | 6 | * Copyright (C) 2005 Stelian Pop (stelian@popies.net) |
7 | * Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de) | 7 | * Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de) |
8 | * Copyright (C) 2005 Peter Osterlund (petero2@telia.com) | 8 | * Copyright (C) 2005 Peter Osterlund (petero2@telia.com) |
9 | * Copyright (C) 2005 Michael Hanselmann (linux-kernel@hansmi.ch) | 9 | * Copyright (C) 2005 Michael Hanselmann (linux-kernel@hansmi.ch) |
10 | * Copyright (C) 2006 Nicolas Boichat (nicolas@boichat.ch) | 10 | * Copyright (C) 2006 Nicolas Boichat (nicolas@boichat.ch) |
11 | * Copyright (C) 2007-2008 Sven Anders (anders@anduras.de) | ||
11 | * | 12 | * |
12 | * Thanks to Alex Harper <basilisk@foobox.net> for his inputs. | 13 | * Thanks to Alex Harper <basilisk@foobox.net> for his inputs. |
13 | * | 14 | * |
@@ -34,77 +35,64 @@ | |||
34 | #include <linux/module.h> | 35 | #include <linux/module.h> |
35 | #include <linux/usb/input.h> | 36 | #include <linux/usb/input.h> |
36 | 37 | ||
37 | /* Apple has powerbooks which have the keyboard with different Product IDs */ | 38 | /* Type of touchpad */ |
38 | #define APPLE_VENDOR_ID 0x05AC | 39 | enum atp_touchpad_type { |
39 | 40 | ATP_FOUNTAIN, | |
40 | /* These names come from Info.plist in AppleUSBTrackpad.kext */ | 41 | ATP_GEYSER1, |
41 | #define FOUNTAIN_ANSI_PRODUCT_ID 0x020E | 42 | ATP_GEYSER2, |
42 | #define FOUNTAIN_ISO_PRODUCT_ID 0x020F | 43 | ATP_GEYSER3, |
43 | 44 | ATP_GEYSER4 | |
44 | #define FOUNTAIN_TP_ONLY_PRODUCT_ID 0x030A | 45 | }; |
45 | |||
46 | #define GEYSER1_TP_ONLY_PRODUCT_ID 0x030B | ||
47 | |||
48 | #define GEYSER_ANSI_PRODUCT_ID 0x0214 | ||
49 | #define GEYSER_ISO_PRODUCT_ID 0x0215 | ||
50 | #define GEYSER_JIS_PRODUCT_ID 0x0216 | ||
51 | |||
52 | /* MacBook devices */ | ||
53 | #define GEYSER3_ANSI_PRODUCT_ID 0x0217 | ||
54 | #define GEYSER3_ISO_PRODUCT_ID 0x0218 | ||
55 | #define GEYSER3_JIS_PRODUCT_ID 0x0219 | ||
56 | |||
57 | /* | ||
58 | * Geyser IV: same as Geyser III according to Info.plist in AppleUSBTrackpad.kext | ||
59 | * -> same IOClass (AppleUSBGrIIITrackpad), same acceleration tables | ||
60 | */ | ||
61 | #define GEYSER4_ANSI_PRODUCT_ID 0x021A | ||
62 | #define GEYSER4_ISO_PRODUCT_ID 0x021B | ||
63 | #define GEYSER4_JIS_PRODUCT_ID 0x021C | ||
64 | |||
65 | #define GEYSER4_HF_ANSI_PRODUCT_ID 0x0229 | ||
66 | #define GEYSER4_HF_ISO_PRODUCT_ID 0x022A | ||
67 | #define GEYSER4_HF_JIS_PRODUCT_ID 0x022B | ||
68 | 46 | ||
69 | #define ATP_DEVICE(prod) \ | 47 | #define ATP_DEVICE(prod, type) \ |
48 | { \ | ||
70 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ | 49 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ |
71 | USB_DEVICE_ID_MATCH_INT_CLASS | \ | 50 | USB_DEVICE_ID_MATCH_INT_CLASS | \ |
72 | USB_DEVICE_ID_MATCH_INT_PROTOCOL, \ | 51 | USB_DEVICE_ID_MATCH_INT_PROTOCOL, \ |
73 | .idVendor = APPLE_VENDOR_ID, \ | 52 | .idVendor = 0x05ac, /* Apple */ \ |
74 | .idProduct = (prod), \ | 53 | .idProduct = (prod), \ |
75 | .bInterfaceClass = 0x03, \ | 54 | .bInterfaceClass = 0x03, \ |
76 | .bInterfaceProtocol = 0x02 | 55 | .bInterfaceProtocol = 0x02, \ |
56 | .driver_info = ATP_ ## type, \ | ||
57 | } | ||
58 | |||
59 | /* | ||
60 | * Table of devices (Product IDs) that work with this driver. | ||
61 | * (The names come from Info.plist in AppleUSBTrackpad.kext, | ||
62 | * According to Info.plist Geyser IV is the same as Geyser III.) | ||
63 | */ | ||
77 | 64 | ||
78 | /* table of devices that work with this driver */ | ||
79 | static struct usb_device_id atp_table [] = { | 65 | static struct usb_device_id atp_table [] = { |
80 | { ATP_DEVICE(FOUNTAIN_ANSI_PRODUCT_ID) }, | 66 | /* PowerBooks Feb 2005, iBooks G4 */ |
81 | { ATP_DEVICE(FOUNTAIN_ISO_PRODUCT_ID) }, | 67 | ATP_DEVICE(0x020e, FOUNTAIN), /* FOUNTAIN ANSI */ |
82 | { ATP_DEVICE(FOUNTAIN_TP_ONLY_PRODUCT_ID) }, | 68 | ATP_DEVICE(0x020f, FOUNTAIN), /* FOUNTAIN ISO */ |
83 | { ATP_DEVICE(GEYSER1_TP_ONLY_PRODUCT_ID) }, | 69 | ATP_DEVICE(0x030a, FOUNTAIN), /* FOUNTAIN TP ONLY */ |
70 | ATP_DEVICE(0x030b, GEYSER1), /* GEYSER 1 TP ONLY */ | ||
84 | 71 | ||
85 | /* PowerBooks Oct 2005 */ | 72 | /* PowerBooks Oct 2005 */ |
86 | { ATP_DEVICE(GEYSER_ANSI_PRODUCT_ID) }, | 73 | ATP_DEVICE(0x0214, GEYSER2), /* GEYSER 2 ANSI */ |
87 | { ATP_DEVICE(GEYSER_ISO_PRODUCT_ID) }, | 74 | ATP_DEVICE(0x0215, GEYSER2), /* GEYSER 2 ISO */ |
88 | { ATP_DEVICE(GEYSER_JIS_PRODUCT_ID) }, | 75 | ATP_DEVICE(0x0216, GEYSER2), /* GEYSER 2 JIS */ |
89 | 76 | ||
90 | /* Core Duo MacBook & MacBook Pro */ | 77 | /* Core Duo MacBook & MacBook Pro */ |
91 | { ATP_DEVICE(GEYSER3_ANSI_PRODUCT_ID) }, | 78 | ATP_DEVICE(0x0217, GEYSER3), /* GEYSER 3 ANSI */ |
92 | { ATP_DEVICE(GEYSER3_ISO_PRODUCT_ID) }, | 79 | ATP_DEVICE(0x0218, GEYSER3), /* GEYSER 3 ISO */ |
93 | { ATP_DEVICE(GEYSER3_JIS_PRODUCT_ID) }, | 80 | ATP_DEVICE(0x0219, GEYSER3), /* GEYSER 3 JIS */ |
94 | 81 | ||
95 | /* Core2 Duo MacBook & MacBook Pro */ | 82 | /* Core2 Duo MacBook & MacBook Pro */ |
96 | { ATP_DEVICE(GEYSER4_ANSI_PRODUCT_ID) }, | 83 | ATP_DEVICE(0x021a, GEYSER4), /* GEYSER 4 ANSI */ |
97 | { ATP_DEVICE(GEYSER4_ISO_PRODUCT_ID) }, | 84 | ATP_DEVICE(0x021b, GEYSER4), /* GEYSER 4 ISO */ |
98 | { ATP_DEVICE(GEYSER4_JIS_PRODUCT_ID) }, | 85 | ATP_DEVICE(0x021c, GEYSER4), /* GEYSER 4 JIS */ |
99 | 86 | ||
100 | { ATP_DEVICE(GEYSER4_HF_ANSI_PRODUCT_ID) }, | 87 | /* Core2 Duo MacBook3,1 */ |
101 | { ATP_DEVICE(GEYSER4_HF_ISO_PRODUCT_ID) }, | 88 | ATP_DEVICE(0x0229, GEYSER4), /* GEYSER 4 HF ANSI */ |
102 | { ATP_DEVICE(GEYSER4_HF_JIS_PRODUCT_ID) }, | 89 | ATP_DEVICE(0x022a, GEYSER4), /* GEYSER 4 HF ISO */ |
90 | ATP_DEVICE(0x022b, GEYSER4), /* GEYSER 4 HF JIS */ | ||
103 | 91 | ||
104 | /* Terminating entry */ | 92 | /* Terminating entry */ |
105 | { } | 93 | { } |
106 | }; | 94 | }; |
107 | MODULE_DEVICE_TABLE (usb, atp_table); | 95 | MODULE_DEVICE_TABLE(usb, atp_table); |
108 | 96 | ||
109 | /* | 97 | /* |
110 | * number of sensors. Note that only 16 instead of 26 X (horizontal) | 98 | * number of sensors. Note that only 16 instead of 26 X (horizontal) |
@@ -124,9 +112,13 @@ MODULE_DEVICE_TABLE (usb, atp_table); | |||
124 | * We try to keep the touchpad aspect ratio while still doing only simple | 112 | * We try to keep the touchpad aspect ratio while still doing only simple |
125 | * arithmetics. | 113 | * arithmetics. |
126 | * The factors below give coordinates like: | 114 | * The factors below give coordinates like: |
127 | * 0 <= x < 960 on 12" and 15" Powerbooks | 115 | * |
128 | * 0 <= x < 1600 on 17" Powerbooks | 116 | * 0 <= x < 960 on 12" and 15" Powerbooks |
129 | * 0 <= y < 646 | 117 | * 0 <= x < 1600 on 17" Powerbooks and 17" MacBook Pro |
118 | * 0 <= x < 1216 on MacBooks and 15" MacBook Pro | ||
119 | * | ||
120 | * 0 <= y < 646 on all Powerbooks | ||
121 | * 0 <= y < 774 on all MacBooks | ||
130 | */ | 122 | */ |
131 | #define ATP_XFACT 64 | 123 | #define ATP_XFACT 64 |
132 | #define ATP_YFACT 43 | 124 | #define ATP_YFACT 43 |
@@ -147,43 +139,46 @@ MODULE_DEVICE_TABLE (usb, atp_table); | |||
147 | /* Structure to hold all of our device specific stuff */ | 139 | /* Structure to hold all of our device specific stuff */ |
148 | struct atp { | 140 | struct atp { |
149 | char phys[64]; | 141 | char phys[64]; |
150 | struct usb_device * udev; /* usb device */ | 142 | struct usb_device *udev; /* usb device */ |
151 | struct urb * urb; /* usb request block */ | 143 | struct urb *urb; /* usb request block */ |
152 | signed char * data; /* transferred data */ | 144 | signed char *data; /* transferred data */ |
153 | struct input_dev * input; /* input dev */ | 145 | struct input_dev *input; /* input dev */ |
154 | unsigned char open; /* non-zero if opened */ | 146 | enum atp_touchpad_type type; /* type of touchpad */ |
155 | unsigned char valid; /* are the sensors valid ? */ | 147 | bool open; |
156 | unsigned char size_detect_done; | 148 | bool valid; /* are the samples valid? */ |
157 | unsigned char overflowwarn; /* overflow warning printed? */ | 149 | bool size_detect_done; |
150 | bool overflow_warned; | ||
158 | int x_old; /* last reported x/y, */ | 151 | int x_old; /* last reported x/y, */ |
159 | int y_old; /* used for smoothing */ | 152 | int y_old; /* used for smoothing */ |
160 | /* current value of the sensors */ | ||
161 | signed char xy_cur[ATP_XSENSORS + ATP_YSENSORS]; | 153 | signed char xy_cur[ATP_XSENSORS + ATP_YSENSORS]; |
162 | /* last value of the sensors */ | ||
163 | signed char xy_old[ATP_XSENSORS + ATP_YSENSORS]; | 154 | signed char xy_old[ATP_XSENSORS + ATP_YSENSORS]; |
164 | /* accumulated sensors */ | ||
165 | int xy_acc[ATP_XSENSORS + ATP_YSENSORS]; | 155 | int xy_acc[ATP_XSENSORS + ATP_YSENSORS]; |
166 | int datalen; /* size of an USB urb transfer */ | 156 | int datalen; /* size of USB transfer */ |
167 | int idlecount; /* number of empty packets */ | 157 | int idlecount; /* number of empty packets */ |
168 | struct work_struct work; | 158 | struct work_struct work; |
169 | }; | 159 | }; |
170 | 160 | ||
171 | #define dbg_dump(msg, tab) \ | 161 | #define dbg_dump(msg, tab) \ |
172 | if (debug > 1) { \ | 162 | if (debug > 1) { \ |
173 | int i; \ | 163 | int __i; \ |
174 | printk("appletouch: %s %lld", msg, (long long)jiffies); \ | 164 | printk(KERN_DEBUG "appletouch: %s", msg); \ |
175 | for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) \ | 165 | for (__i = 0; __i < ATP_XSENSORS + ATP_YSENSORS; __i++) \ |
176 | printk(" %02x", tab[i]); \ | 166 | printk(" %02x", tab[__i]); \ |
177 | printk("\n"); \ | 167 | printk("\n"); \ |
178 | } | 168 | } |
179 | 169 | ||
180 | #define dprintk(format, a...) \ | 170 | #define dprintk(format, a...) \ |
181 | do { \ | 171 | do { \ |
182 | if (debug) printk(KERN_DEBUG format, ##a); \ | 172 | if (debug) \ |
173 | printk(KERN_DEBUG format, ##a); \ | ||
183 | } while (0) | 174 | } while (0) |
184 | 175 | ||
185 | MODULE_AUTHOR("Johannes Berg, Stelian Pop, Frank Arnold, Michael Hanselmann"); | 176 | MODULE_AUTHOR("Johannes Berg"); |
186 | MODULE_DESCRIPTION("Apple PowerBooks USB touchpad driver"); | 177 | MODULE_AUTHOR("Stelian Pop"); |
178 | MODULE_AUTHOR("Frank Arnold"); | ||
179 | MODULE_AUTHOR("Michael Hanselmann"); | ||
180 | MODULE_AUTHOR("Sven Anders"); | ||
181 | MODULE_DESCRIPTION("Apple PowerBook and MacBook USB touchpad driver"); | ||
187 | MODULE_LICENSE("GPL"); | 182 | MODULE_LICENSE("GPL"); |
188 | 183 | ||
189 | /* | 184 | /* |
@@ -191,46 +186,14 @@ MODULE_LICENSE("GPL"); | |||
191 | */ | 186 | */ |
192 | static int threshold = ATP_THRESHOLD; | 187 | static int threshold = ATP_THRESHOLD; |
193 | module_param(threshold, int, 0644); | 188 | module_param(threshold, int, 0644); |
194 | MODULE_PARM_DESC(threshold, "Discards any change in data from a sensor (trackpad has hundreds of these sensors) less than this value"); | 189 | MODULE_PARM_DESC(threshold, "Discard any change in data from a sensor" |
190 | " (the trackpad has many of these sensors)" | ||
191 | " less than this value."); | ||
195 | 192 | ||
196 | static int debug = 1; | 193 | static int debug; |
197 | module_param(debug, int, 0644); | 194 | module_param(debug, int, 0644); |
198 | MODULE_PARM_DESC(debug, "Activate debugging output"); | 195 | MODULE_PARM_DESC(debug, "Activate debugging output"); |
199 | 196 | ||
200 | static inline int atp_is_fountain(struct atp *dev) | ||
201 | { | ||
202 | u16 productId = le16_to_cpu(dev->udev->descriptor.idProduct); | ||
203 | |||
204 | return productId == FOUNTAIN_ANSI_PRODUCT_ID || | ||
205 | productId == FOUNTAIN_ISO_PRODUCT_ID || | ||
206 | productId == FOUNTAIN_TP_ONLY_PRODUCT_ID; | ||
207 | } | ||
208 | |||
209 | /* Checks if the device a Geyser 2 (ANSI, ISO, JIS) */ | ||
210 | static inline int atp_is_geyser_2(struct atp *dev) | ||
211 | { | ||
212 | u16 productId = le16_to_cpu(dev->udev->descriptor.idProduct); | ||
213 | |||
214 | return (productId == GEYSER_ANSI_PRODUCT_ID) || | ||
215 | (productId == GEYSER_ISO_PRODUCT_ID) || | ||
216 | (productId == GEYSER_JIS_PRODUCT_ID); | ||
217 | } | ||
218 | |||
219 | static inline int atp_is_geyser_3(struct atp *dev) | ||
220 | { | ||
221 | u16 productId = le16_to_cpu(dev->udev->descriptor.idProduct); | ||
222 | |||
223 | return (productId == GEYSER3_ANSI_PRODUCT_ID) || | ||
224 | (productId == GEYSER3_ISO_PRODUCT_ID) || | ||
225 | (productId == GEYSER3_JIS_PRODUCT_ID) || | ||
226 | (productId == GEYSER4_ANSI_PRODUCT_ID) || | ||
227 | (productId == GEYSER4_ISO_PRODUCT_ID) || | ||
228 | (productId == GEYSER4_JIS_PRODUCT_ID) || | ||
229 | (productId == GEYSER4_HF_ANSI_PRODUCT_ID) || | ||
230 | (productId == GEYSER4_HF_ISO_PRODUCT_ID) || | ||
231 | (productId == GEYSER4_HF_JIS_PRODUCT_ID); | ||
232 | } | ||
233 | |||
234 | /* | 197 | /* |
235 | * By default newer Geyser devices send standard USB HID mouse | 198 | * By default newer Geyser devices send standard USB HID mouse |
236 | * packets (Report ID 2). This code changes device mode, so it | 199 | * packets (Report ID 2). This code changes device mode, so it |
@@ -240,6 +203,7 @@ static int atp_geyser_init(struct usb_device *udev) | |||
240 | { | 203 | { |
241 | char data[8]; | 204 | char data[8]; |
242 | int size; | 205 | int size; |
206 | int i; | ||
243 | 207 | ||
244 | size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | 208 | size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), |
245 | ATP_GEYSER_MODE_READ_REQUEST_ID, | 209 | ATP_GEYSER_MODE_READ_REQUEST_ID, |
@@ -248,8 +212,11 @@ static int atp_geyser_init(struct usb_device *udev) | |||
248 | ATP_GEYSER_MODE_REQUEST_INDEX, &data, 8, 5000); | 212 | ATP_GEYSER_MODE_REQUEST_INDEX, &data, 8, 5000); |
249 | 213 | ||
250 | if (size != 8) { | 214 | if (size != 8) { |
251 | err("Could not do mode read request from device" | 215 | dprintk("atp_geyser_init: read error\n"); |
252 | " (Geyser Raw mode)"); | 216 | for (i = 0; i < 8; i++) |
217 | dprintk("appletouch[%d]: %d\n", i, data[i]); | ||
218 | |||
219 | err("Failed to read mode from device."); | ||
253 | return -EIO; | 220 | return -EIO; |
254 | } | 221 | } |
255 | 222 | ||
@@ -263,8 +230,11 @@ static int atp_geyser_init(struct usb_device *udev) | |||
263 | ATP_GEYSER_MODE_REQUEST_INDEX, &data, 8, 5000); | 230 | ATP_GEYSER_MODE_REQUEST_INDEX, &data, 8, 5000); |
264 | 231 | ||
265 | if (size != 8) { | 232 | if (size != 8) { |
266 | err("Could not do mode write request to device" | 233 | dprintk("atp_geyser_init: write error\n"); |
267 | " (Geyser Raw mode)"); | 234 | for (i = 0; i < 8; i++) |
235 | dprintk("appletouch[%d]: %d\n", i, data[i]); | ||
236 | |||
237 | err("Failed to request geyser raw mode"); | ||
268 | return -EIO; | 238 | return -EIO; |
269 | } | 239 | } |
270 | return 0; | 240 | return 0; |
@@ -280,15 +250,15 @@ static void atp_reinit(struct work_struct *work) | |||
280 | struct usb_device *udev = dev->udev; | 250 | struct usb_device *udev = dev->udev; |
281 | int retval; | 251 | int retval; |
282 | 252 | ||
253 | dprintk("appletouch: putting appletouch to sleep (reinit)\n"); | ||
283 | dev->idlecount = 0; | 254 | dev->idlecount = 0; |
284 | 255 | ||
285 | atp_geyser_init(udev); | 256 | atp_geyser_init(udev); |
286 | 257 | ||
287 | retval = usb_submit_urb(dev->urb, GFP_ATOMIC); | 258 | retval = usb_submit_urb(dev->urb, GFP_ATOMIC); |
288 | if (retval) { | 259 | if (retval) |
289 | err("%s - usb_submit_urb failed with result %d", | 260 | err("atp_reinit: usb_submit_urb failed with error %d", |
290 | __FUNCTION__, retval); | 261 | retval); |
291 | } | ||
292 | } | 262 | } |
293 | 263 | ||
294 | static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact, | 264 | static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact, |
@@ -323,7 +293,8 @@ static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact, | |||
323 | * | 293 | * |
324 | * - Jason Parekh <jasonparekh@gmail.com> | 294 | * - Jason Parekh <jasonparekh@gmail.com> |
325 | */ | 295 | */ |
326 | if (i < 1 || (!is_increasing && xy_sensors[i - 1] < xy_sensors[i])) { | 296 | if (i < 1 || |
297 | (!is_increasing && xy_sensors[i - 1] < xy_sensors[i])) { | ||
327 | (*fingers)++; | 298 | (*fingers)++; |
328 | is_increasing = 1; | 299 | is_increasing = 1; |
329 | } else if (i > 0 && xy_sensors[i - 1] >= xy_sensors[i]) { | 300 | } else if (i > 0 && xy_sensors[i - 1] >= xy_sensors[i]) { |
@@ -331,11 +302,11 @@ static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact, | |||
331 | } | 302 | } |
332 | 303 | ||
333 | /* | 304 | /* |
334 | * Subtracts threshold so a high sensor that just passes the threshold | 305 | * Subtracts threshold so a high sensor that just passes the |
335 | * won't skew the calculated absolute coordinate. Fixes an issue | 306 | * threshold won't skew the calculated absolute coordinate. |
336 | * where slowly moving the mouse would occassionaly jump a number of | 307 | * Fixes an issue where slowly moving the mouse would |
337 | * pixels (let me restate--slowly moving the mouse makes this issue | 308 | * occasionally jump a number of pixels (slowly moving the |
338 | * most apparent). | 309 | * finger makes this issue most apparent.) |
339 | */ | 310 | */ |
340 | pcum += (xy_sensors[i] - threshold) * i; | 311 | pcum += (xy_sensors[i] - threshold) * i; |
341 | psum += (xy_sensors[i] - threshold); | 312 | psum += (xy_sensors[i] - threshold); |
@@ -356,7 +327,7 @@ static inline void atp_report_fingers(struct input_dev *input, int fingers) | |||
356 | input_report_key(input, BTN_TOOL_TRIPLETAP, fingers > 2); | 327 | input_report_key(input, BTN_TOOL_TRIPLETAP, fingers > 2); |
357 | } | 328 | } |
358 | 329 | ||
359 | static void atp_complete(struct urb* urb) | 330 | static void atp_complete(struct urb *urb) |
360 | { | 331 | { |
361 | int x, y, x_z, y_z, x_f, y_f; | 332 | int x, y, x_z, y_z, x_f, y_f; |
362 | int retval, i, j; | 333 | int retval, i, j; |
@@ -368,22 +339,22 @@ static void atp_complete(struct urb* urb) | |||
368 | /* success */ | 339 | /* success */ |
369 | break; | 340 | break; |
370 | case -EOVERFLOW: | 341 | case -EOVERFLOW: |
371 | if(!dev->overflowwarn) { | 342 | if (!dev->overflow_warned) { |
372 | printk(KERN_WARNING "appletouch: OVERFLOW with data " | 343 | printk(KERN_WARNING "appletouch: OVERFLOW with data " |
373 | "length %d, actual length is %d\n", | 344 | "length %d, actual length is %d\n", |
374 | dev->datalen, dev->urb->actual_length); | 345 | dev->datalen, dev->urb->actual_length); |
375 | dev->overflowwarn = 1; | 346 | dev->overflow_warned = true; |
376 | } | 347 | } |
377 | case -ECONNRESET: | 348 | case -ECONNRESET: |
378 | case -ENOENT: | 349 | case -ENOENT: |
379 | case -ESHUTDOWN: | 350 | case -ESHUTDOWN: |
380 | /* This urb is terminated, clean up */ | 351 | /* This urb is terminated, clean up */ |
381 | dbg("%s - urb shutting down with status: %d", | 352 | dbg("atp_complete: urb shutting down with status: %d", |
382 | __FUNCTION__, urb->status); | 353 | urb->status); |
383 | return; | 354 | return; |
384 | default: | 355 | default: |
385 | dbg("%s - nonzero urb status received: %d", | 356 | dbg("atp_complete: nonzero urb status received: %d", |
386 | __FUNCTION__, urb->status); | 357 | urb->status); |
387 | goto exit; | 358 | goto exit; |
388 | } | 359 | } |
389 | 360 | ||
@@ -396,7 +367,7 @@ static void atp_complete(struct urb* urb) | |||
396 | } | 367 | } |
397 | 368 | ||
398 | /* reorder the sensors values */ | 369 | /* reorder the sensors values */ |
399 | if (atp_is_geyser_3(dev)) { | 370 | if (dev->type == ATP_GEYSER3 || dev->type == ATP_GEYSER4) { |
400 | memset(dev->xy_cur, 0, sizeof(dev->xy_cur)); | 371 | memset(dev->xy_cur, 0, sizeof(dev->xy_cur)); |
401 | 372 | ||
402 | /* | 373 | /* |
@@ -415,7 +386,7 @@ static void atp_complete(struct urb* urb) | |||
415 | dev->xy_cur[ATP_XSENSORS + i] = dev->data[j + 1]; | 386 | dev->xy_cur[ATP_XSENSORS + i] = dev->data[j + 1]; |
416 | dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 2]; | 387 | dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 2]; |
417 | } | 388 | } |
418 | } else if (atp_is_geyser_2(dev)) { | 389 | } else if (dev->type == ATP_GEYSER2) { |
419 | memset(dev->xy_cur, 0, sizeof(dev->xy_cur)); | 390 | memset(dev->xy_cur, 0, sizeof(dev->xy_cur)); |
420 | 391 | ||
421 | /* | 392 | /* |
@@ -438,7 +409,7 @@ static void atp_complete(struct urb* urb) | |||
438 | } else { | 409 | } else { |
439 | for (i = 0; i < 8; i++) { | 410 | for (i = 0; i < 8; i++) { |
440 | /* X values */ | 411 | /* X values */ |
441 | dev->xy_cur[i ] = dev->data[5 * i + 2]; | 412 | dev->xy_cur[i + 0] = dev->data[5 * i + 2]; |
442 | dev->xy_cur[i + 8] = dev->data[5 * i + 4]; | 413 | dev->xy_cur[i + 8] = dev->data[5 * i + 4]; |
443 | dev->xy_cur[i + 16] = dev->data[5 * i + 42]; | 414 | dev->xy_cur[i + 16] = dev->data[5 * i + 42]; |
444 | if (i < 2) | 415 | if (i < 2) |
@@ -454,21 +425,22 @@ static void atp_complete(struct urb* urb) | |||
454 | 425 | ||
455 | if (!dev->valid) { | 426 | if (!dev->valid) { |
456 | /* first sample */ | 427 | /* first sample */ |
457 | dev->valid = 1; | 428 | dev->valid = true; |
458 | dev->x_old = dev->y_old = -1; | 429 | dev->x_old = dev->y_old = -1; |
459 | memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old)); | 430 | memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old)); |
460 | 431 | ||
461 | if (dev->size_detect_done || | 432 | if (dev->size_detect_done || |
462 | atp_is_geyser_3(dev)) /* No 17" Macbooks (yet) */ | 433 | dev->type == ATP_GEYSER3) /* No 17" Macbooks (yet) */ |
463 | goto exit; | 434 | goto exit; |
464 | 435 | ||
465 | /* 17" Powerbooks have extra X sensors */ | 436 | /* 17" Powerbooks have extra X sensors */ |
466 | for (i = (atp_is_geyser_2(dev) ? 15 : 16); i < ATP_XSENSORS; i++) { | 437 | for (i = (dev->type == ATP_GEYSER2 ? 15 : 16); |
438 | i < ATP_XSENSORS; i++) { | ||
467 | if (!dev->xy_cur[i]) | 439 | if (!dev->xy_cur[i]) |
468 | continue; | 440 | continue; |
469 | 441 | ||
470 | printk(KERN_INFO "appletouch: 17\" model detected.\n"); | 442 | printk(KERN_INFO "appletouch: 17\" model detected.\n"); |
471 | if (atp_is_geyser_2(dev)) | 443 | if (dev->type == ATP_GEYSER2) |
472 | input_set_abs_params(dev->input, ABS_X, 0, | 444 | input_set_abs_params(dev->input, ABS_X, 0, |
473 | (20 - 1) * | 445 | (20 - 1) * |
474 | ATP_XFACT - 1, | 446 | ATP_XFACT - 1, |
@@ -548,11 +520,15 @@ static void atp_complete(struct urb* urb) | |||
548 | * several hundred times a second. Re-initialization does not | 520 | * several hundred times a second. Re-initialization does not |
549 | * work on Fountain touchpads. | 521 | * work on Fountain touchpads. |
550 | */ | 522 | */ |
551 | if (!atp_is_fountain(dev)) { | 523 | if (dev->type != ATP_FOUNTAIN) { |
524 | /* | ||
525 | * Button must not be pressed when entering suspend, | ||
526 | * otherwise we will never release the button. | ||
527 | */ | ||
552 | if (!x && !y && !key) { | 528 | if (!x && !y && !key) { |
553 | dev->idlecount++; | 529 | dev->idlecount++; |
554 | if (dev->idlecount == 10) { | 530 | if (dev->idlecount == 10) { |
555 | dev->valid = 0; | 531 | dev->valid = false; |
556 | schedule_work(&dev->work); | 532 | schedule_work(&dev->work); |
557 | /* Don't resubmit urb here, wait for reinit */ | 533 | /* Don't resubmit urb here, wait for reinit */ |
558 | return; | 534 | return; |
@@ -561,12 +537,11 @@ static void atp_complete(struct urb* urb) | |||
561 | dev->idlecount = 0; | 537 | dev->idlecount = 0; |
562 | } | 538 | } |
563 | 539 | ||
564 | exit: | 540 | exit: |
565 | retval = usb_submit_urb(dev->urb, GFP_ATOMIC); | 541 | retval = usb_submit_urb(dev->urb, GFP_ATOMIC); |
566 | if (retval) { | 542 | if (retval) |
567 | err("%s - usb_submit_urb failed with result %d", | 543 | err("atp_complete: usb_submit_urb failed with result %d", |
568 | __FUNCTION__, retval); | 544 | retval); |
569 | } | ||
570 | } | 545 | } |
571 | 546 | ||
572 | static int atp_open(struct input_dev *input) | 547 | static int atp_open(struct input_dev *input) |
@@ -593,7 +568,7 @@ static int atp_handle_geyser(struct atp *dev) | |||
593 | { | 568 | { |
594 | struct usb_device *udev = dev->udev; | 569 | struct usb_device *udev = dev->udev; |
595 | 570 | ||
596 | if (!atp_is_fountain(dev)) { | 571 | if (dev->type != ATP_FOUNTAIN) { |
597 | /* switch to raw sensor mode */ | 572 | /* switch to raw sensor mode */ |
598 | if (atp_geyser_init(udev)) | 573 | if (atp_geyser_init(udev)) |
599 | return -EIO; | 574 | return -EIO; |
@@ -604,7 +579,8 @@ static int atp_handle_geyser(struct atp *dev) | |||
604 | return 0; | 579 | return 0; |
605 | } | 580 | } |
606 | 581 | ||
607 | static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id) | 582 | static int atp_probe(struct usb_interface *iface, |
583 | const struct usb_device_id *id) | ||
608 | { | 584 | { |
609 | struct atp *dev; | 585 | struct atp *dev; |
610 | struct input_dev *input_dev; | 586 | struct input_dev *input_dev; |
@@ -640,13 +616,12 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id | |||
640 | 616 | ||
641 | dev->udev = udev; | 617 | dev->udev = udev; |
642 | dev->input = input_dev; | 618 | dev->input = input_dev; |
643 | dev->overflowwarn = 0; | 619 | dev->type = id->driver_info; |
644 | if (atp_is_geyser_3(dev)) | 620 | dev->overflow_warned = false; |
645 | dev->datalen = 64; | 621 | if (dev->type == ATP_FOUNTAIN || dev->type == ATP_GEYSER1) |
646 | else if (atp_is_geyser_2(dev)) | ||
647 | dev->datalen = 64; | ||
648 | else | ||
649 | dev->datalen = 81; | 622 | dev->datalen = 81; |
623 | else | ||
624 | dev->datalen = 64; | ||
650 | 625 | ||
651 | dev->urb = usb_alloc_urb(0, GFP_KERNEL); | 626 | dev->urb = usb_alloc_urb(0, GFP_KERNEL); |
652 | if (!dev->urb) | 627 | if (!dev->urb) |
@@ -680,7 +655,7 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id | |||
680 | 655 | ||
681 | set_bit(EV_ABS, input_dev->evbit); | 656 | set_bit(EV_ABS, input_dev->evbit); |
682 | 657 | ||
683 | if (atp_is_geyser_3(dev)) { | 658 | if (dev->type == ATP_GEYSER3 || dev->type == ATP_GEYSER4) { |
684 | /* | 659 | /* |
685 | * MacBook have 20 X sensors, 10 Y sensors | 660 | * MacBook have 20 X sensors, 10 Y sensors |
686 | */ | 661 | */ |
@@ -688,7 +663,7 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id | |||
688 | ((20 - 1) * ATP_XFACT) - 1, ATP_FUZZ, 0); | 663 | ((20 - 1) * ATP_XFACT) - 1, ATP_FUZZ, 0); |
689 | input_set_abs_params(input_dev, ABS_Y, 0, | 664 | input_set_abs_params(input_dev, ABS_Y, 0, |
690 | ((10 - 1) * ATP_YFACT) - 1, ATP_FUZZ, 0); | 665 | ((10 - 1) * ATP_YFACT) - 1, ATP_FUZZ, 0); |
691 | } else if (atp_is_geyser_2(dev)) { | 666 | } else if (dev->type == ATP_GEYSER2) { |
692 | /* | 667 | /* |
693 | * Oct 2005 15" PowerBooks have 15 X sensors, 17" are detected | 668 | * Oct 2005 15" PowerBooks have 15 X sensors, 17" are detected |
694 | * later. | 669 | * later. |
@@ -703,9 +678,11 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id | |||
703 | * 17" models are detected later. | 678 | * 17" models are detected later. |
704 | */ | 679 | */ |
705 | input_set_abs_params(input_dev, ABS_X, 0, | 680 | input_set_abs_params(input_dev, ABS_X, 0, |
706 | (16 - 1) * ATP_XFACT - 1, ATP_FUZZ, 0); | 681 | (16 - 1) * ATP_XFACT - 1, |
682 | ATP_FUZZ, 0); | ||
707 | input_set_abs_params(input_dev, ABS_Y, 0, | 683 | input_set_abs_params(input_dev, ABS_Y, 0, |
708 | (ATP_YSENSORS - 1) * ATP_YFACT - 1, ATP_FUZZ, 0); | 684 | (ATP_YSENSORS - 1) * ATP_YFACT - 1, |
685 | ATP_FUZZ, 0); | ||
709 | } | 686 | } |
710 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0); | 687 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0); |
711 | 688 | ||
@@ -774,7 +751,7 @@ static int atp_suspend(struct usb_interface *iface, pm_message_t message) | |||
774 | struct atp *dev = usb_get_intfdata(iface); | 751 | struct atp *dev = usb_get_intfdata(iface); |
775 | 752 | ||
776 | usb_kill_urb(dev->urb); | 753 | usb_kill_urb(dev->urb); |
777 | dev->valid = 0; | 754 | dev->valid = false; |
778 | 755 | ||
779 | return 0; | 756 | return 0; |
780 | } | 757 | } |
diff --git a/drivers/input/mouse/atarimouse.c b/drivers/input/mouse/atarimouse.c index 98a3561d4b05..adf45b3040e9 100644 --- a/drivers/input/mouse/atarimouse.c +++ b/drivers/input/mouse/atarimouse.c | |||
@@ -57,15 +57,12 @@ MODULE_AUTHOR("Michael Schmitz <schmitz@biophys.uni-duesseldorf.de>"); | |||
57 | MODULE_DESCRIPTION("Atari mouse driver"); | 57 | MODULE_DESCRIPTION("Atari mouse driver"); |
58 | MODULE_LICENSE("GPL"); | 58 | MODULE_LICENSE("GPL"); |
59 | 59 | ||
60 | static int mouse_threshold[2] = {2,2}; | 60 | static int mouse_threshold[2] = {2, 2}; |
61 | module_param_array(mouse_threshold, int, NULL, 0); | ||
61 | 62 | ||
62 | #ifdef __MODULE__ | ||
63 | MODULE_PARM(mouse_threshold, "2i"); | ||
64 | #endif | ||
65 | #ifdef FIXED_ATARI_JOYSTICK | 63 | #ifdef FIXED_ATARI_JOYSTICK |
66 | extern int atari_mouse_buttons; | 64 | extern int atari_mouse_buttons; |
67 | #endif | 65 | #endif |
68 | static int atamouse_used = 0; | ||
69 | 66 | ||
70 | static struct input_dev *atamouse_dev; | 67 | static struct input_dev *atamouse_dev; |
71 | 68 | ||
@@ -97,9 +94,6 @@ static void atamouse_interrupt(char *buf) | |||
97 | 94 | ||
98 | static int atamouse_open(struct input_dev *dev) | 95 | static int atamouse_open(struct input_dev *dev) |
99 | { | 96 | { |
100 | if (atamouse_used++) | ||
101 | return 0; | ||
102 | |||
103 | #ifdef FIXED_ATARI_JOYSTICK | 97 | #ifdef FIXED_ATARI_JOYSTICK |
104 | atari_mouse_buttons = 0; | 98 | atari_mouse_buttons = 0; |
105 | #endif | 99 | #endif |
@@ -107,23 +101,24 @@ static int atamouse_open(struct input_dev *dev) | |||
107 | ikbd_mouse_thresh(mouse_threshold[0], mouse_threshold[1]); | 101 | ikbd_mouse_thresh(mouse_threshold[0], mouse_threshold[1]); |
108 | ikbd_mouse_rel_pos(); | 102 | ikbd_mouse_rel_pos(); |
109 | atari_input_mouse_interrupt_hook = atamouse_interrupt; | 103 | atari_input_mouse_interrupt_hook = atamouse_interrupt; |
104 | |||
110 | return 0; | 105 | return 0; |
111 | } | 106 | } |
112 | 107 | ||
113 | static void atamouse_close(struct input_dev *dev) | 108 | static void atamouse_close(struct input_dev *dev) |
114 | { | 109 | { |
115 | if (!--atamouse_used) { | 110 | ikbd_mouse_disable(); |
116 | ikbd_mouse_disable(); | 111 | atari_mouse_interrupt_hook = NULL; |
117 | atari_mouse_interrupt_hook = NULL; | ||
118 | } | ||
119 | } | 112 | } |
120 | 113 | ||
121 | static int __init atamouse_init(void) | 114 | static int __init atamouse_init(void) |
122 | { | 115 | { |
116 | int error; | ||
117 | |||
123 | if (!MACH_IS_ATARI || !ATARIHW_PRESENT(ST_MFP)) | 118 | if (!MACH_IS_ATARI || !ATARIHW_PRESENT(ST_MFP)) |
124 | return -ENODEV; | 119 | return -ENODEV; |
125 | 120 | ||
126 | if (!(atari_keyb_init())) | 121 | if (!atari_keyb_init()) |
127 | return -ENODEV; | 122 | return -ENODEV; |
128 | 123 | ||
129 | atamouse_dev = input_allocate_device(); | 124 | atamouse_dev = input_allocate_device(); |
@@ -141,12 +136,14 @@ static int __init atamouse_init(void) | |||
141 | atamouse_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); | 136 | atamouse_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); |
142 | atamouse_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) | | 137 | atamouse_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) | |
143 | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); | 138 | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); |
139 | |||
144 | atamouse_dev->open = atamouse_open; | 140 | atamouse_dev->open = atamouse_open; |
145 | atamouse_dev->close = atamouse_close; | 141 | atamouse_dev->close = atamouse_close; |
146 | 142 | ||
147 | if (input_register_device(atamouse_dev)) { | 143 | error = input_register_device(atamouse_dev); |
144 | if (error) { | ||
148 | input_free_device(atamouse_dev); | 145 | input_free_device(atamouse_dev); |
149 | return -ENOMEM; | 146 | return error; |
150 | } | 147 | } |
151 | 148 | ||
152 | return 0; | 149 | return 0; |
diff --git a/drivers/input/mouse/hil_ptr.c b/drivers/input/mouse/hil_ptr.c index 27f88fbb7136..e532c48410ea 100644 --- a/drivers/input/mouse/hil_ptr.c +++ b/drivers/input/mouse/hil_ptr.c | |||
@@ -247,19 +247,24 @@ static void hil_ptr_disconnect(struct serio *serio) | |||
247 | 247 | ||
248 | static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) | 248 | static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) |
249 | { | 249 | { |
250 | struct hil_ptr *ptr; | 250 | struct hil_ptr *ptr; |
251 | const char *txt; | 251 | const char *txt; |
252 | unsigned int i, naxsets, btntype; | 252 | unsigned int i, naxsets, btntype; |
253 | uint8_t did, *idd; | 253 | uint8_t did, *idd; |
254 | 254 | int error; | |
255 | if (!(ptr = kzalloc(sizeof(struct hil_ptr), GFP_KERNEL))) | 255 | |
256 | ptr = kzalloc(sizeof(struct hil_ptr), GFP_KERNEL); | ||
257 | if (!ptr) | ||
256 | return -ENOMEM; | 258 | return -ENOMEM; |
257 | 259 | ||
258 | ptr->dev = input_allocate_device(); | 260 | ptr->dev = input_allocate_device(); |
259 | if (!ptr->dev) | 261 | if (!ptr->dev) { |
262 | error = -ENOMEM; | ||
260 | goto bail0; | 263 | goto bail0; |
264 | } | ||
261 | 265 | ||
262 | if (serio_open(serio, driver)) | 266 | error = serio_open(serio, driver); |
267 | if (error) | ||
263 | goto bail1; | 268 | goto bail1; |
264 | 269 | ||
265 | serio_set_drvdata(serio, ptr); | 270 | serio_set_drvdata(serio, ptr); |
@@ -297,6 +302,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) | |||
297 | did = ptr->idd[0]; | 302 | did = ptr->idd[0]; |
298 | idd = ptr->idd + 1; | 303 | idd = ptr->idd + 1; |
299 | txt = "unknown"; | 304 | txt = "unknown"; |
305 | |||
300 | if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) { | 306 | if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) { |
301 | ptr->dev->evbit[0] = BIT_MASK(EV_REL); | 307 | ptr->dev->evbit[0] = BIT_MASK(EV_REL); |
302 | txt = "relative"; | 308 | txt = "relative"; |
@@ -306,8 +312,11 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) | |||
306 | ptr->dev->evbit[0] = BIT_MASK(EV_ABS); | 312 | ptr->dev->evbit[0] = BIT_MASK(EV_ABS); |
307 | txt = "absolute"; | 313 | txt = "absolute"; |
308 | } | 314 | } |
309 | if (!ptr->dev->evbit[0]) | 315 | |
316 | if (!ptr->dev->evbit[0]) { | ||
317 | error = -ENODEV; | ||
310 | goto bail2; | 318 | goto bail2; |
319 | } | ||
311 | 320 | ||
312 | ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd); | 321 | ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd); |
313 | if (ptr->nbtn) | 322 | if (ptr->nbtn) |
@@ -380,13 +389,19 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) | |||
380 | ptr->dev->id.version = 0x0100; /* TODO: get from ptr->rsc */ | 389 | ptr->dev->id.version = 0x0100; /* TODO: get from ptr->rsc */ |
381 | ptr->dev->dev.parent = &serio->dev; | 390 | ptr->dev->dev.parent = &serio->dev; |
382 | 391 | ||
383 | input_register_device(ptr->dev); | 392 | error = input_register_device(ptr->dev); |
393 | if (error) { | ||
394 | printk(KERN_INFO PREFIX "Unable to register input device\n"); | ||
395 | goto bail2; | ||
396 | } | ||
397 | |||
384 | printk(KERN_INFO "input: %s (%s), ID: %d\n", | 398 | printk(KERN_INFO "input: %s (%s), ID: %d\n", |
385 | ptr->dev->name, | 399 | ptr->dev->name, |
386 | (btntype == BTN_MOUSE) ? "HIL mouse":"HIL tablet or touchpad", | 400 | (btntype == BTN_MOUSE) ? "HIL mouse":"HIL tablet or touchpad", |
387 | did); | 401 | did); |
388 | 402 | ||
389 | return 0; | 403 | return 0; |
404 | |||
390 | bail2: | 405 | bail2: |
391 | serio_close(serio); | 406 | serio_close(serio); |
392 | bail1: | 407 | bail1: |
@@ -394,7 +409,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) | |||
394 | bail0: | 409 | bail0: |
395 | kfree(ptr); | 410 | kfree(ptr); |
396 | serio_set_drvdata(serio, NULL); | 411 | serio_set_drvdata(serio, NULL); |
397 | return -ENODEV; | 412 | return error; |
398 | } | 413 | } |
399 | 414 | ||
400 | static struct serio_device_id hil_ptr_ids[] = { | 415 | static struct serio_device_id hil_ptr_ids[] = { |
diff --git a/drivers/input/mouse/inport.c b/drivers/input/mouse/inport.c index 06c35fc553c0..3827a22362de 100644 --- a/drivers/input/mouse/inport.c +++ b/drivers/input/mouse/inport.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: inport.c,v 1.11 2001/09/25 10:12:07 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 1999-2001 Vojtech Pavlik | 2 | * Copyright (c) 1999-2001 Vojtech Pavlik |
5 | * | 3 | * |
6 | * Based on the work of: | 4 | * Based on the work of: |
diff --git a/drivers/input/mouse/logibm.c b/drivers/input/mouse/logibm.c index 9ea895593b27..e2413113df22 100644 --- a/drivers/input/mouse/logibm.c +++ b/drivers/input/mouse/logibm.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: logibm.c,v 1.11 2001/09/25 10:12:07 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 1999-2001 Vojtech Pavlik | 2 | * Copyright (c) 1999-2001 Vojtech Pavlik |
5 | * | 3 | * |
6 | * Based on the work of: | 4 | * Based on the work of: |
diff --git a/drivers/input/mouse/pc110pad.c b/drivers/input/mouse/pc110pad.c index 61cff8374e6c..fd09c8df81f2 100644 --- a/drivers/input/mouse/pc110pad.c +++ b/drivers/input/mouse/pc110pad.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: pc110pad.c,v 1.12 2001/09/25 10:12:07 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 2000-2001 Vojtech Pavlik | 2 | * Copyright (c) 2000-2001 Vojtech Pavlik |
5 | * | 3 | * |
6 | * Based on the work of: | 4 | * Based on the work of: |
diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c index ed917bfd086a..17ff137b9bd5 100644 --- a/drivers/input/mouse/sermouse.c +++ b/drivers/input/mouse/sermouse.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: sermouse.c,v 1.17 2002/03/13 10:03:43 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 1999-2001 Vojtech Pavlik | 2 | * Copyright (c) 1999-2001 Vojtech Pavlik |
5 | */ | 3 | */ |
6 | 4 | ||
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index ec4b6610f730..27d70d326ff3 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig | |||
@@ -190,4 +190,14 @@ config SERIO_RAW | |||
190 | To compile this driver as a module, choose M here: the | 190 | To compile this driver as a module, choose M here: the |
191 | module will be called serio_raw. | 191 | module will be called serio_raw. |
192 | 192 | ||
193 | config SERIO_XILINX_XPS_PS2 | ||
194 | tristate "Xilinx XPS PS/2 Controller Support" | ||
195 | depends on PPC | ||
196 | help | ||
197 | This driver supports XPS PS/2 IP from the Xilinx EDK on | ||
198 | PowerPC platform. | ||
199 | |||
200 | To compile this driver as a module, choose M here: the | ||
201 | module will be called xilinx_ps2. | ||
202 | |||
193 | endif | 203 | endif |
diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile index 38b886887cbc..9b6c8135955f 100644 --- a/drivers/input/serio/Makefile +++ b/drivers/input/serio/Makefile | |||
@@ -21,3 +21,4 @@ obj-$(CONFIG_SERIO_PCIPS2) += pcips2.o | |||
21 | obj-$(CONFIG_SERIO_MACEPS2) += maceps2.o | 21 | obj-$(CONFIG_SERIO_MACEPS2) += maceps2.o |
22 | obj-$(CONFIG_SERIO_LIBPS2) += libps2.o | 22 | obj-$(CONFIG_SERIO_LIBPS2) += libps2.o |
23 | obj-$(CONFIG_SERIO_RAW) += serio_raw.o | 23 | obj-$(CONFIG_SERIO_RAW) += serio_raw.o |
24 | obj-$(CONFIG_SERIO_XILINX_XPS_PS2) += xilinx_ps2.o | ||
diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c index 0d35018c23a9..d1380fc72cc6 100644 --- a/drivers/input/serio/ct82c710.c +++ b/drivers/input/serio/ct82c710.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: ct82c710.c,v 1.11 2001/09/25 10:12:07 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 1999-2001 Vojtech Pavlik | 2 | * Copyright (c) 1999-2001 Vojtech Pavlik |
5 | */ | 3 | */ |
6 | 4 | ||
diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c index 93a1a6ba216a..37586a68d345 100644 --- a/drivers/input/serio/hil_mlc.c +++ b/drivers/input/serio/hil_mlc.c | |||
@@ -76,7 +76,7 @@ static struct timer_list hil_mlcs_kicker; | |||
76 | static int hil_mlcs_probe; | 76 | static int hil_mlcs_probe; |
77 | 77 | ||
78 | static void hil_mlcs_process(unsigned long unused); | 78 | static void hil_mlcs_process(unsigned long unused); |
79 | DECLARE_TASKLET_DISABLED(hil_mlcs_tasklet, hil_mlcs_process, 0); | 79 | static DECLARE_TASKLET_DISABLED(hil_mlcs_tasklet, hil_mlcs_process, 0); |
80 | 80 | ||
81 | 81 | ||
82 | /* #define HIL_MLC_DEBUG */ | 82 | /* #define HIL_MLC_DEBUG */ |
@@ -459,7 +459,7 @@ static int hilse_operate(hil_mlc *mlc, int repoll) | |||
459 | #define OUT_LAST(pack) \ | 459 | #define OUT_LAST(pack) \ |
460 | { HILSE_OUT_LAST, { .packet = pack }, 0, 0, 0, 0 }, | 460 | { HILSE_OUT_LAST, { .packet = pack }, 0, 0, 0, 0 }, |
461 | 461 | ||
462 | const struct hilse_node hil_mlc_se[HILSEN_END] = { | 462 | static const struct hilse_node hil_mlc_se[HILSEN_END] = { |
463 | 463 | ||
464 | /* 0 HILSEN_START */ | 464 | /* 0 HILSEN_START */ |
465 | FUNC(hilse_init_lcv, 0, HILSEN_NEXT, HILSEN_SLEEP, 0) | 465 | FUNC(hilse_init_lcv, 0, HILSEN_NEXT, HILSEN_SLEEP, 0) |
@@ -784,7 +784,7 @@ static void hil_mlcs_process(unsigned long unused) | |||
784 | 784 | ||
785 | /************************* Keepalive timer task *********************/ | 785 | /************************* Keepalive timer task *********************/ |
786 | 786 | ||
787 | void hil_mlcs_timer(unsigned long data) | 787 | static void hil_mlcs_timer(unsigned long data) |
788 | { | 788 | { |
789 | hil_mlcs_probe = 1; | 789 | hil_mlcs_probe = 1; |
790 | tasklet_schedule(&hil_mlcs_tasklet); | 790 | tasklet_schedule(&hil_mlcs_tasklet); |
diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c index edfedd9a166c..7b233a492ad5 100644 --- a/drivers/input/serio/hp_sdc.c +++ b/drivers/input/serio/hp_sdc.c | |||
@@ -105,6 +105,10 @@ EXPORT_SYMBOL(__hp_sdc_enqueue_transaction); | |||
105 | EXPORT_SYMBOL(hp_sdc_enqueue_transaction); | 105 | EXPORT_SYMBOL(hp_sdc_enqueue_transaction); |
106 | EXPORT_SYMBOL(hp_sdc_dequeue_transaction); | 106 | EXPORT_SYMBOL(hp_sdc_dequeue_transaction); |
107 | 107 | ||
108 | static unsigned int hp_sdc_disabled; | ||
109 | module_param_named(no_hpsdc, hp_sdc_disabled, bool, 0); | ||
110 | MODULE_PARM_DESC(no_hpsdc, "Do not enable HP SDC driver."); | ||
111 | |||
108 | static hp_i8042_sdc hp_sdc; /* All driver state is kept in here. */ | 112 | static hp_i8042_sdc hp_sdc; /* All driver state is kept in here. */ |
109 | 113 | ||
110 | /*************** primitives for use in any context *********************/ | 114 | /*************** primitives for use in any context *********************/ |
@@ -980,6 +984,11 @@ static int __init hp_sdc_register(void) | |||
980 | unsigned char i; | 984 | unsigned char i; |
981 | #endif | 985 | #endif |
982 | 986 | ||
987 | if (hp_sdc_disabled) { | ||
988 | printk(KERN_WARNING PREFIX "HP SDC driver disabled by no_hpsdc=1.\n"); | ||
989 | return -ENODEV; | ||
990 | } | ||
991 | |||
983 | hp_sdc.dev = NULL; | 992 | hp_sdc.dev = NULL; |
984 | hp_sdc.dev_err = 0; | 993 | hp_sdc.dev_err = 0; |
985 | #if defined(__hppa__) | 994 | #if defined(__hppa__) |
diff --git a/drivers/input/serio/hp_sdc_mlc.c b/drivers/input/serio/hp_sdc_mlc.c index 587398f5c9df..b587e2d576ac 100644 --- a/drivers/input/serio/hp_sdc_mlc.c +++ b/drivers/input/serio/hp_sdc_mlc.c | |||
@@ -50,7 +50,7 @@ MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>"); | |||
50 | MODULE_DESCRIPTION("Glue for onboard HIL MLC in HP-PARISC machines"); | 50 | MODULE_DESCRIPTION("Glue for onboard HIL MLC in HP-PARISC machines"); |
51 | MODULE_LICENSE("Dual BSD/GPL"); | 51 | MODULE_LICENSE("Dual BSD/GPL"); |
52 | 52 | ||
53 | struct hp_sdc_mlc_priv_s { | 53 | static struct hp_sdc_mlc_priv_s { |
54 | int emtestmode; | 54 | int emtestmode; |
55 | hp_sdc_transaction trans; | 55 | hp_sdc_transaction trans; |
56 | u8 tseq[16]; | 56 | u8 tseq[16]; |
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 78eb7841174c..fe732a574ec2 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -63,13 +63,22 @@ static inline void i8042_write_command(int val) | |||
63 | outb(val, I8042_COMMAND_REG); | 63 | outb(val, I8042_COMMAND_REG); |
64 | } | 64 | } |
65 | 65 | ||
66 | #if defined(__i386__) || defined(__x86_64__) | 66 | #ifdef CONFIG_X86 |
67 | 67 | ||
68 | #include <linux/dmi.h> | 68 | #include <linux/dmi.h> |
69 | 69 | ||
70 | static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | 70 | static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { |
71 | { | 71 | { |
72 | /* AUX LOOP command does not raise AUX IRQ */ | 72 | /* AUX LOOP command does not raise AUX IRQ */ |
73 | .ident = "Arima-Rioworks HDAMB", | ||
74 | .matches = { | ||
75 | DMI_MATCH(DMI_BOARD_VENDOR, "RIOWORKS"), | ||
76 | DMI_MATCH(DMI_BOARD_NAME, "HDAMB"), | ||
77 | DMI_MATCH(DMI_BOARD_VERSION, "Rev E"), | ||
78 | }, | ||
79 | }, | ||
80 | { | ||
81 | /* AUX LOOP command does not raise AUX IRQ */ | ||
73 | .ident = "ASUS P65UP5", | 82 | .ident = "ASUS P65UP5", |
74 | .matches = { | 83 | .matches = { |
75 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), | 84 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), |
@@ -118,6 +127,14 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
118 | DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2"), | 127 | DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2"), |
119 | }, | 128 | }, |
120 | }, | 129 | }, |
130 | { | ||
131 | .ident = "Medion MAM 2070", | ||
132 | .matches = { | ||
133 | DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), | ||
134 | DMI_MATCH(DMI_PRODUCT_NAME, "MAM 2070"), | ||
135 | DMI_MATCH(DMI_PRODUCT_VERSION, "5a"), | ||
136 | }, | ||
137 | }, | ||
121 | { } | 138 | { } |
122 | }; | 139 | }; |
123 | 140 | ||
@@ -291,17 +308,36 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | |||
291 | DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"), | 308 | DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"), |
292 | }, | 309 | }, |
293 | }, | 310 | }, |
311 | { | ||
312 | .ident = "Acer Aspire 1360", | ||
313 | .matches = { | ||
314 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
315 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"), | ||
316 | }, | ||
317 | }, | ||
318 | { | ||
319 | .ident = "Gericom Bellagio", | ||
320 | .matches = { | ||
321 | DMI_MATCH(DMI_SYS_VENDOR, "Gericom"), | ||
322 | DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"), | ||
323 | }, | ||
324 | }, | ||
294 | { } | 325 | { } |
295 | }; | 326 | }; |
296 | 327 | ||
297 | 328 | #ifdef CONFIG_PNP | |
298 | 329 | static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = { | |
330 | { | ||
331 | .ident = "Intel MBO Desktop D845PESV", | ||
332 | .matches = { | ||
333 | DMI_MATCH(DMI_BOARD_NAME, "D845PESV"), | ||
334 | DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), | ||
335 | }, | ||
336 | }, | ||
337 | { } | ||
338 | }; | ||
299 | #endif | 339 | #endif |
300 | 340 | ||
301 | #ifdef CONFIG_X86 | ||
302 | |||
303 | #include <linux/dmi.h> | ||
304 | |||
305 | /* | 341 | /* |
306 | * Some Wistron based laptops need us to explicitly enable the 'Dritek | 342 | * Some Wistron based laptops need us to explicitly enable the 'Dritek |
307 | * keyboard extension' to make their extra keys start generating scancodes. | 343 | * keyboard extension' to make their extra keys start generating scancodes. |
@@ -331,6 +367,13 @@ static struct dmi_system_id __initdata i8042_dmi_dritek_table[] = { | |||
331 | }, | 367 | }, |
332 | }, | 368 | }, |
333 | { | 369 | { |
370 | .ident = "Acer Aspire 5720", | ||
371 | .matches = { | ||
372 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
373 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"), | ||
374 | }, | ||
375 | }, | ||
376 | { | ||
334 | .ident = "Acer Aspire 9110", | 377 | .ident = "Acer Aspire 9110", |
335 | .matches = { | 378 | .matches = { |
336 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 379 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
@@ -356,7 +399,6 @@ static struct dmi_system_id __initdata i8042_dmi_dritek_table[] = { | |||
356 | 399 | ||
357 | #endif /* CONFIG_X86 */ | 400 | #endif /* CONFIG_X86 */ |
358 | 401 | ||
359 | |||
360 | #ifdef CONFIG_PNP | 402 | #ifdef CONFIG_PNP |
361 | #include <linux/pnp.h> | 403 | #include <linux/pnp.h> |
362 | 404 | ||
@@ -466,6 +508,11 @@ static int __init i8042_pnp_init(void) | |||
466 | int pnp_data_busted = 0; | 508 | int pnp_data_busted = 0; |
467 | int err; | 509 | int err; |
468 | 510 | ||
511 | #ifdef CONFIG_X86 | ||
512 | if (dmi_check_system(i8042_dmi_nopnp_table)) | ||
513 | i8042_nopnp = 1; | ||
514 | #endif | ||
515 | |||
469 | if (i8042_nopnp) { | 516 | if (i8042_nopnp) { |
470 | printk(KERN_INFO "i8042: PNP detection disabled\n"); | 517 | printk(KERN_INFO "i8042: PNP detection disabled\n"); |
471 | return 0; | 518 | return 0; |
@@ -591,15 +638,13 @@ static int __init i8042_platform_init(void) | |||
591 | i8042_reset = 1; | 638 | i8042_reset = 1; |
592 | #endif | 639 | #endif |
593 | 640 | ||
594 | #if defined(__i386__) || defined(__x86_64__) | 641 | #ifdef CONFIG_X86 |
595 | if (dmi_check_system(i8042_dmi_noloop_table)) | 642 | if (dmi_check_system(i8042_dmi_noloop_table)) |
596 | i8042_noloop = 1; | 643 | i8042_noloop = 1; |
597 | 644 | ||
598 | if (dmi_check_system(i8042_dmi_nomux_table)) | 645 | if (dmi_check_system(i8042_dmi_nomux_table)) |
599 | i8042_nomux = 1; | 646 | i8042_nomux = 1; |
600 | #endif | ||
601 | 647 | ||
602 | #ifdef CONFIG_X86 | ||
603 | if (dmi_check_system(i8042_dmi_dritek_table)) | 648 | if (dmi_check_system(i8042_dmi_dritek_table)) |
604 | i8042_dritek = 1; | 649 | i8042_dritek = 1; |
605 | #endif /* CONFIG_X86 */ | 650 | #endif /* CONFIG_X86 */ |
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index b819239d74dc..2b304c22c200 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c | |||
@@ -26,15 +26,6 @@ MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>"); | |||
26 | MODULE_DESCRIPTION("PS/2 driver library"); | 26 | MODULE_DESCRIPTION("PS/2 driver library"); |
27 | MODULE_LICENSE("GPL"); | 27 | MODULE_LICENSE("GPL"); |
28 | 28 | ||
29 | /* Work structure to schedule execution of a command */ | ||
30 | struct ps2work { | ||
31 | struct work_struct work; | ||
32 | struct ps2dev *ps2dev; | ||
33 | int command; | ||
34 | unsigned char param[0]; | ||
35 | }; | ||
36 | |||
37 | |||
38 | /* | 29 | /* |
39 | * ps2_sendbyte() sends a byte to the device and waits for acknowledge. | 30 | * ps2_sendbyte() sends a byte to the device and waits for acknowledge. |
40 | * It doesn't handle retransmission, though it could - because if there | 31 | * It doesn't handle retransmission, though it could - because if there |
@@ -246,49 +237,6 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) | |||
246 | EXPORT_SYMBOL(ps2_command); | 237 | EXPORT_SYMBOL(ps2_command); |
247 | 238 | ||
248 | /* | 239 | /* |
249 | * ps2_execute_scheduled_command() sends a command, previously scheduled by | ||
250 | * ps2_schedule_command(), to a PS/2 device (keyboard, mouse, etc.) | ||
251 | */ | ||
252 | |||
253 | static void ps2_execute_scheduled_command(struct work_struct *work) | ||
254 | { | ||
255 | struct ps2work *ps2work = container_of(work, struct ps2work, work); | ||
256 | |||
257 | ps2_command(ps2work->ps2dev, ps2work->param, ps2work->command); | ||
258 | kfree(ps2work); | ||
259 | } | ||
260 | |||
261 | /* | ||
262 | * ps2_schedule_command() allows to schedule delayed execution of a PS/2 | ||
263 | * command and can be used to issue a command from an interrupt or softirq | ||
264 | * context. | ||
265 | */ | ||
266 | |||
267 | int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int command) | ||
268 | { | ||
269 | struct ps2work *ps2work; | ||
270 | int send = (command >> 12) & 0xf; | ||
271 | int receive = (command >> 8) & 0xf; | ||
272 | |||
273 | if (!(ps2work = kmalloc(sizeof(struct ps2work) + max(send, receive), GFP_ATOMIC))) | ||
274 | return -1; | ||
275 | |||
276 | memset(ps2work, 0, sizeof(struct ps2work)); | ||
277 | ps2work->ps2dev = ps2dev; | ||
278 | ps2work->command = command; | ||
279 | memcpy(ps2work->param, param, send); | ||
280 | INIT_WORK(&ps2work->work, ps2_execute_scheduled_command); | ||
281 | |||
282 | if (!schedule_work(&ps2work->work)) { | ||
283 | kfree(ps2work); | ||
284 | return -1; | ||
285 | } | ||
286 | |||
287 | return 0; | ||
288 | } | ||
289 | EXPORT_SYMBOL(ps2_schedule_command); | ||
290 | |||
291 | /* | ||
292 | * ps2_init() initializes ps2dev structure | 240 | * ps2_init() initializes ps2dev structure |
293 | */ | 241 | */ |
294 | 242 | ||
diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c index d962a8d78b14..e36a0901646c 100644 --- a/drivers/input/serio/q40kbd.c +++ b/drivers/input/serio/q40kbd.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: q40kbd.c,v 1.12 2002/02/02 22:26:44 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 2000-2001 Vojtech Pavlik | 2 | * Copyright (c) 2000-2001 Vojtech Pavlik |
5 | * | 3 | * |
6 | * Based on the work of: | 4 | * Based on the work of: |
@@ -49,7 +47,7 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | |||
49 | MODULE_DESCRIPTION("Q40 PS/2 keyboard controller driver"); | 47 | MODULE_DESCRIPTION("Q40 PS/2 keyboard controller driver"); |
50 | MODULE_LICENSE("GPL"); | 48 | MODULE_LICENSE("GPL"); |
51 | 49 | ||
52 | DEFINE_SPINLOCK(q40kbd_lock); | 50 | static DEFINE_SPINLOCK(q40kbd_lock); |
53 | static struct serio *q40kbd_port; | 51 | static struct serio *q40kbd_port; |
54 | static struct platform_device *q40kbd_device; | 52 | static struct platform_device *q40kbd_device; |
55 | 53 | ||
diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c index 34c59d9c6205..1567b7782478 100644 --- a/drivers/input/serio/rpckbd.c +++ b/drivers/input/serio/rpckbd.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: rpckbd.c,v 1.7 2001/09/25 10:12:07 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 2000-2001 Vojtech Pavlik | 2 | * Copyright (c) 2000-2001 Vojtech Pavlik |
5 | * Copyright (c) 2002 Russell King | 3 | * Copyright (c) 2002 Russell King |
6 | */ | 4 | */ |
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 7f5293828fbf..78f2abb5c11b 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
@@ -331,9 +331,10 @@ static void serio_handle_event(void) | |||
331 | } | 331 | } |
332 | 332 | ||
333 | /* | 333 | /* |
334 | * Remove all events that have been submitted for a given serio port. | 334 | * Remove all events that have been submitted for a given |
335 | * object, be it serio port or driver. | ||
335 | */ | 336 | */ |
336 | static void serio_remove_pending_events(struct serio *serio) | 337 | static void serio_remove_pending_events(void *object) |
337 | { | 338 | { |
338 | struct list_head *node, *next; | 339 | struct list_head *node, *next; |
339 | struct serio_event *event; | 340 | struct serio_event *event; |
@@ -343,7 +344,7 @@ static void serio_remove_pending_events(struct serio *serio) | |||
343 | 344 | ||
344 | list_for_each_safe(node, next, &serio_event_list) { | 345 | list_for_each_safe(node, next, &serio_event_list) { |
345 | event = list_entry(node, struct serio_event, node); | 346 | event = list_entry(node, struct serio_event, node); |
346 | if (event->object == serio) { | 347 | if (event->object == object) { |
347 | list_del_init(node); | 348 | list_del_init(node); |
348 | serio_free_event(event); | 349 | serio_free_event(event); |
349 | } | 350 | } |
@@ -837,7 +838,9 @@ void serio_unregister_driver(struct serio_driver *drv) | |||
837 | struct serio *serio; | 838 | struct serio *serio; |
838 | 839 | ||
839 | mutex_lock(&serio_mutex); | 840 | mutex_lock(&serio_mutex); |
841 | |||
840 | drv->manual_bind = 1; /* so serio_find_driver ignores it */ | 842 | drv->manual_bind = 1; /* so serio_find_driver ignores it */ |
843 | serio_remove_pending_events(drv); | ||
841 | 844 | ||
842 | start_over: | 845 | start_over: |
843 | list_for_each_entry(serio, &serio_list, node) { | 846 | list_for_each_entry(serio, &serio_list, node) { |
diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c new file mode 100644 index 000000000000..0ed044d5e685 --- /dev/null +++ b/drivers/input/serio/xilinx_ps2.c | |||
@@ -0,0 +1,380 @@ | |||
1 | /* | ||
2 | * Xilinx XPS PS/2 device driver | ||
3 | * | ||
4 | * (c) 2005 MontaVista Software, Inc. | ||
5 | * (c) 2008 Xilinx, Inc. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | * | ||
12 | * You should have received a copy of the GNU General Public License along | ||
13 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
14 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
15 | */ | ||
16 | |||
17 | |||
18 | #include <linux/module.h> | ||
19 | #include <linux/serio.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/errno.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/list.h> | ||
24 | #include <linux/io.h> | ||
25 | |||
26 | #include <linux/of_device.h> | ||
27 | #include <linux/of_platform.h> | ||
28 | |||
29 | #define DRIVER_NAME "xilinx_ps2" | ||
30 | |||
31 | /* Register offsets for the xps2 device */ | ||
32 | #define XPS2_SRST_OFFSET 0x00000000 /* Software Reset register */ | ||
33 | #define XPS2_STATUS_OFFSET 0x00000004 /* Status register */ | ||
34 | #define XPS2_RX_DATA_OFFSET 0x00000008 /* Receive Data register */ | ||
35 | #define XPS2_TX_DATA_OFFSET 0x0000000C /* Transmit Data register */ | ||
36 | #define XPS2_GIER_OFFSET 0x0000002C /* Global Interrupt Enable reg */ | ||
37 | #define XPS2_IPISR_OFFSET 0x00000030 /* Interrupt Status register */ | ||
38 | #define XPS2_IPIER_OFFSET 0x00000038 /* Interrupt Enable register */ | ||
39 | |||
40 | /* Reset Register Bit Definitions */ | ||
41 | #define XPS2_SRST_RESET 0x0000000A /* Software Reset */ | ||
42 | |||
43 | /* Status Register Bit Positions */ | ||
44 | #define XPS2_STATUS_RX_FULL 0x00000001 /* Receive Full */ | ||
45 | #define XPS2_STATUS_TX_FULL 0x00000002 /* Transmit Full */ | ||
46 | |||
47 | /* Bit definitions for ISR/IER registers. Both the registers have the same bit | ||
48 | * definitions and are only defined once. */ | ||
49 | #define XPS2_IPIXR_WDT_TOUT 0x00000001 /* Watchdog Timeout Interrupt */ | ||
50 | #define XPS2_IPIXR_TX_NOACK 0x00000002 /* Transmit No ACK Interrupt */ | ||
51 | #define XPS2_IPIXR_TX_ACK 0x00000004 /* Transmit ACK (Data) Interrupt */ | ||
52 | #define XPS2_IPIXR_RX_OVF 0x00000008 /* Receive Overflow Interrupt */ | ||
53 | #define XPS2_IPIXR_RX_ERR 0x00000010 /* Receive Error Interrupt */ | ||
54 | #define XPS2_IPIXR_RX_FULL 0x00000020 /* Receive Data Interrupt */ | ||
55 | |||
56 | /* Mask for all the Transmit Interrupts */ | ||
57 | #define XPS2_IPIXR_TX_ALL (XPS2_IPIXR_TX_NOACK | XPS2_IPIXR_TX_ACK) | ||
58 | |||
59 | /* Mask for all the Receive Interrupts */ | ||
60 | #define XPS2_IPIXR_RX_ALL (XPS2_IPIXR_RX_OVF | XPS2_IPIXR_RX_ERR | \ | ||
61 | XPS2_IPIXR_RX_FULL) | ||
62 | |||
63 | /* Mask for all the Interrupts */ | ||
64 | #define XPS2_IPIXR_ALL (XPS2_IPIXR_TX_ALL | XPS2_IPIXR_RX_ALL | \ | ||
65 | XPS2_IPIXR_WDT_TOUT) | ||
66 | |||
67 | /* Global Interrupt Enable mask */ | ||
68 | #define XPS2_GIER_GIE_MASK 0x80000000 | ||
69 | |||
70 | struct xps2data { | ||
71 | int irq; | ||
72 | u32 phys_addr; | ||
73 | u32 remap_size; | ||
74 | spinlock_t lock; | ||
75 | u8 rxb; /* Rx buffer */ | ||
76 | void __iomem *base_address; /* virt. address of control registers */ | ||
77 | unsigned int dfl; | ||
78 | struct serio serio; /* serio */ | ||
79 | }; | ||
80 | |||
81 | /************************************/ | ||
82 | /* XPS PS/2 data transmission calls */ | ||
83 | /************************************/ | ||
84 | |||
85 | /* | ||
86 | * xps2_recv() will attempt to receive a byte of data from the PS/2 port. | ||
87 | */ | ||
88 | static int xps2_recv(struct xps2data *drvdata, u8 *byte) | ||
89 | { | ||
90 | u32 sr; | ||
91 | int status = -1; | ||
92 | |||
93 | /* If there is data available in the PS/2 receiver, read it */ | ||
94 | sr = in_be32(drvdata->base_address + XPS2_STATUS_OFFSET); | ||
95 | if (sr & XPS2_STATUS_RX_FULL) { | ||
96 | *byte = in_be32(drvdata->base_address + XPS2_RX_DATA_OFFSET); | ||
97 | status = 0; | ||
98 | } | ||
99 | |||
100 | return status; | ||
101 | } | ||
102 | |||
103 | /*********************/ | ||
104 | /* Interrupt handler */ | ||
105 | /*********************/ | ||
106 | static irqreturn_t xps2_interrupt(int irq, void *dev_id) | ||
107 | { | ||
108 | struct xps2data *drvdata = dev_id; | ||
109 | u32 intr_sr; | ||
110 | u8 c; | ||
111 | int status; | ||
112 | |||
113 | /* Get the PS/2 interrupts and clear them */ | ||
114 | intr_sr = in_be32(drvdata->base_address + XPS2_IPISR_OFFSET); | ||
115 | out_be32(drvdata->base_address + XPS2_IPISR_OFFSET, intr_sr); | ||
116 | |||
117 | /* Check which interrupt is active */ | ||
118 | if (intr_sr & XPS2_IPIXR_RX_OVF) | ||
119 | printk(KERN_WARNING "%s: receive overrun error\n", | ||
120 | drvdata->serio.name); | ||
121 | |||
122 | if (intr_sr & XPS2_IPIXR_RX_ERR) | ||
123 | drvdata->dfl |= SERIO_PARITY; | ||
124 | |||
125 | if (intr_sr & (XPS2_IPIXR_TX_NOACK | XPS2_IPIXR_WDT_TOUT)) | ||
126 | drvdata->dfl |= SERIO_TIMEOUT; | ||
127 | |||
128 | if (intr_sr & XPS2_IPIXR_RX_FULL) { | ||
129 | status = xps2_recv(drvdata, &drvdata->rxb); | ||
130 | |||
131 | /* Error, if a byte is not received */ | ||
132 | if (status) { | ||
133 | printk(KERN_ERR | ||
134 | "%s: wrong rcvd byte count (%d)\n", | ||
135 | drvdata->serio.name, status); | ||
136 | } else { | ||
137 | c = drvdata->rxb; | ||
138 | serio_interrupt(&drvdata->serio, c, drvdata->dfl); | ||
139 | drvdata->dfl = 0; | ||
140 | } | ||
141 | } | ||
142 | |||
143 | if (intr_sr & XPS2_IPIXR_TX_ACK) | ||
144 | drvdata->dfl = 0; | ||
145 | |||
146 | return IRQ_HANDLED; | ||
147 | } | ||
148 | |||
149 | /*******************/ | ||
150 | /* serio callbacks */ | ||
151 | /*******************/ | ||
152 | |||
153 | /* | ||
154 | * sxps2_write() sends a byte out through the PS/2 interface. | ||
155 | */ | ||
156 | static int sxps2_write(struct serio *pserio, unsigned char c) | ||
157 | { | ||
158 | struct xps2data *drvdata = pserio->port_data; | ||
159 | unsigned long flags; | ||
160 | u32 sr; | ||
161 | int status = -1; | ||
162 | |||
163 | spin_lock_irqsave(&drvdata->lock, flags); | ||
164 | |||
165 | /* If the PS/2 transmitter is empty send a byte of data */ | ||
166 | sr = in_be32(drvdata->base_address + XPS2_STATUS_OFFSET); | ||
167 | if (!(sr & XPS2_STATUS_TX_FULL)) { | ||
168 | out_be32(drvdata->base_address + XPS2_TX_DATA_OFFSET, c); | ||
169 | status = 0; | ||
170 | } | ||
171 | |||
172 | spin_unlock_irqrestore(&drvdata->lock, flags); | ||
173 | |||
174 | return status; | ||
175 | } | ||
176 | |||
177 | /* | ||
178 | * sxps2_open() is called when a port is open by the higher layer. | ||
179 | */ | ||
180 | static int sxps2_open(struct serio *pserio) | ||
181 | { | ||
182 | struct xps2data *drvdata = pserio->port_data; | ||
183 | int retval; | ||
184 | |||
185 | retval = request_irq(drvdata->irq, &xps2_interrupt, 0, | ||
186 | DRIVER_NAME, drvdata); | ||
187 | if (retval) { | ||
188 | printk(KERN_ERR | ||
189 | "%s: Couldn't allocate interrupt %d\n", | ||
190 | drvdata->serio.name, drvdata->irq); | ||
191 | return retval; | ||
192 | } | ||
193 | |||
194 | /* start reception by enabling the interrupts */ | ||
195 | out_be32(drvdata->base_address + XPS2_GIER_OFFSET, XPS2_GIER_GIE_MASK); | ||
196 | out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, XPS2_IPIXR_RX_ALL); | ||
197 | (void)xps2_recv(drvdata, &drvdata->rxb); | ||
198 | |||
199 | return 0; /* success */ | ||
200 | } | ||
201 | |||
202 | /* | ||
203 | * sxps2_close() frees the interrupt. | ||
204 | */ | ||
205 | static void sxps2_close(struct serio *pserio) | ||
206 | { | ||
207 | struct xps2data *drvdata = pserio->port_data; | ||
208 | |||
209 | /* Disable the PS2 interrupts */ | ||
210 | out_be32(drvdata->base_address + XPS2_GIER_OFFSET, 0x00); | ||
211 | out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, 0x00); | ||
212 | free_irq(drvdata->irq, drvdata); | ||
213 | } | ||
214 | |||
215 | /*********************/ | ||
216 | /* Device setup code */ | ||
217 | /*********************/ | ||
218 | |||
219 | static int xps2_setup(struct device *dev, struct resource *regs_res, | ||
220 | struct resource *irq_res) | ||
221 | { | ||
222 | struct xps2data *drvdata; | ||
223 | struct serio *serio; | ||
224 | unsigned long remap_size; | ||
225 | int retval; | ||
226 | |||
227 | if (!dev) | ||
228 | return -EINVAL; | ||
229 | |||
230 | if (!regs_res || !irq_res) { | ||
231 | dev_err(dev, "IO resource(s) not found\n"); | ||
232 | return -EINVAL; | ||
233 | } | ||
234 | |||
235 | drvdata = kzalloc(sizeof(struct xps2data), GFP_KERNEL); | ||
236 | if (!drvdata) { | ||
237 | dev_err(dev, "Couldn't allocate device private record\n"); | ||
238 | return -ENOMEM; | ||
239 | } | ||
240 | |||
241 | dev_set_drvdata(dev, drvdata); | ||
242 | |||
243 | spin_lock_init(&drvdata->lock); | ||
244 | drvdata->irq = irq_res->start; | ||
245 | |||
246 | remap_size = regs_res->end - regs_res->start + 1; | ||
247 | if (!request_mem_region(regs_res->start, remap_size, DRIVER_NAME)) { | ||
248 | dev_err(dev, "Couldn't lock memory region at 0x%08X\n", | ||
249 | (unsigned int)regs_res->start); | ||
250 | retval = -EBUSY; | ||
251 | goto failed1; | ||
252 | } | ||
253 | |||
254 | /* Fill in configuration data and add them to the list */ | ||
255 | drvdata->phys_addr = regs_res->start; | ||
256 | drvdata->remap_size = remap_size; | ||
257 | drvdata->base_address = ioremap(regs_res->start, remap_size); | ||
258 | if (drvdata->base_address == NULL) { | ||
259 | dev_err(dev, "Couldn't ioremap memory at 0x%08X\n", | ||
260 | (unsigned int)regs_res->start); | ||
261 | retval = -EFAULT; | ||
262 | goto failed2; | ||
263 | } | ||
264 | |||
265 | /* Disable all the interrupts, just in case */ | ||
266 | out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, 0); | ||
267 | |||
268 | /* Reset the PS2 device and abort any current transaction, to make sure | ||
269 | * we have the PS2 in a good state */ | ||
270 | out_be32(drvdata->base_address + XPS2_SRST_OFFSET, XPS2_SRST_RESET); | ||
271 | |||
272 | dev_info(dev, "Xilinx PS2 at 0x%08X mapped to 0x%08X, irq=%d\n", | ||
273 | drvdata->phys_addr, (u32)drvdata->base_address, drvdata->irq); | ||
274 | |||
275 | serio = &drvdata->serio; | ||
276 | serio->id.type = SERIO_8042; | ||
277 | serio->write = sxps2_write; | ||
278 | serio->open = sxps2_open; | ||
279 | serio->close = sxps2_close; | ||
280 | serio->port_data = drvdata; | ||
281 | serio->dev.parent = dev; | ||
282 | snprintf(serio->name, sizeof(serio->name), | ||
283 | "Xilinx XPS PS/2 at %08X", drvdata->phys_addr); | ||
284 | snprintf(serio->phys, sizeof(serio->phys), | ||
285 | "xilinxps2/serio at %08X", drvdata->phys_addr); | ||
286 | serio_register_port(serio); | ||
287 | |||
288 | return 0; /* success */ | ||
289 | |||
290 | failed2: | ||
291 | release_mem_region(regs_res->start, remap_size); | ||
292 | failed1: | ||
293 | kfree(drvdata); | ||
294 | dev_set_drvdata(dev, NULL); | ||
295 | |||
296 | return retval; | ||
297 | } | ||
298 | |||
299 | /***************************/ | ||
300 | /* OF Platform Bus Support */ | ||
301 | /***************************/ | ||
302 | |||
303 | static int __devinit xps2_of_probe(struct of_device *ofdev, const struct | ||
304 | of_device_id * match) | ||
305 | { | ||
306 | struct resource r_irq; /* Interrupt resources */ | ||
307 | struct resource r_mem; /* IO mem resources */ | ||
308 | int rc = 0; | ||
309 | |||
310 | printk(KERN_INFO "Device Tree Probing \'%s\'\n", | ||
311 | ofdev->node->name); | ||
312 | |||
313 | /* Get iospace for the device */ | ||
314 | rc = of_address_to_resource(ofdev->node, 0, &r_mem); | ||
315 | if (rc) { | ||
316 | dev_err(&ofdev->dev, "invalid address\n"); | ||
317 | return rc; | ||
318 | } | ||
319 | |||
320 | /* Get IRQ for the device */ | ||
321 | rc = of_irq_to_resource(ofdev->node, 0, &r_irq); | ||
322 | if (rc == NO_IRQ) { | ||
323 | dev_err(&ofdev->dev, "no IRQ found\n"); | ||
324 | return rc; | ||
325 | } | ||
326 | |||
327 | return xps2_setup(&ofdev->dev, &r_mem, &r_irq); | ||
328 | } | ||
329 | |||
330 | static int __devexit xps2_of_remove(struct of_device *of_dev) | ||
331 | { | ||
332 | struct device *dev = &of_dev->dev; | ||
333 | struct xps2data *drvdata; | ||
334 | |||
335 | if (!dev) | ||
336 | return -EINVAL; | ||
337 | |||
338 | drvdata = dev_get_drvdata(dev); | ||
339 | |||
340 | serio_unregister_port(&drvdata->serio); | ||
341 | iounmap(drvdata->base_address); | ||
342 | release_mem_region(drvdata->phys_addr, drvdata->remap_size); | ||
343 | kfree(drvdata); | ||
344 | |||
345 | dev_set_drvdata(dev, NULL); | ||
346 | |||
347 | return 0; /* success */ | ||
348 | } | ||
349 | |||
350 | /* Match table for of_platform binding */ | ||
351 | static struct of_device_id xps2_of_match[] __devinitdata = { | ||
352 | { .compatible = "xlnx,xps-ps2-1.00.a", }, | ||
353 | { /* end of list */ }, | ||
354 | }; | ||
355 | MODULE_DEVICE_TABLE(of, xps2_of_match); | ||
356 | |||
357 | static struct of_platform_driver xps2_of_driver = { | ||
358 | .name = DRIVER_NAME, | ||
359 | .match_table = xps2_of_match, | ||
360 | .probe = xps2_of_probe, | ||
361 | .remove = __devexit_p(xps2_of_remove), | ||
362 | }; | ||
363 | |||
364 | static int __init xps2_init(void) | ||
365 | { | ||
366 | return of_register_platform_driver(&xps2_of_driver); | ||
367 | } | ||
368 | |||
369 | static void __exit xps2_cleanup(void) | ||
370 | { | ||
371 | of_unregister_platform_driver(&xps2_of_driver); | ||
372 | } | ||
373 | |||
374 | module_init(xps2_init); | ||
375 | module_exit(xps2_cleanup); | ||
376 | |||
377 | MODULE_AUTHOR("Xilinx, Inc."); | ||
378 | MODULE_DESCRIPTION("Xilinx XPS PS/2 driver"); | ||
379 | MODULE_LICENSE("GPL"); | ||
380 | |||
diff --git a/drivers/input/tablet/acecad.c b/drivers/input/tablet/acecad.c index b973d0ef6d16..570e0e83ac46 100644 --- a/drivers/input/tablet/acecad.c +++ b/drivers/input/tablet/acecad.c | |||
@@ -73,10 +73,10 @@ static void usb_acecad_irq(struct urb *urb) | |||
73 | case -ENOENT: | 73 | case -ENOENT: |
74 | case -ESHUTDOWN: | 74 | case -ESHUTDOWN: |
75 | /* this urb is terminated, clean up */ | 75 | /* this urb is terminated, clean up */ |
76 | dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); | 76 | dbg("%s - urb shutting down with status: %d", __func__, urb->status); |
77 | return; | 77 | return; |
78 | default: | 78 | default: |
79 | dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); | 79 | dbg("%s - nonzero urb status received: %d", __func__, urb->status); |
80 | goto resubmit; | 80 | goto resubmit; |
81 | } | 81 | } |
82 | 82 | ||
diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 55c1134d6137..8f037a1d44a6 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c | |||
@@ -449,12 +449,12 @@ static void aiptek_irq(struct urb *urb) | |||
449 | case -ESHUTDOWN: | 449 | case -ESHUTDOWN: |
450 | /* This urb is terminated, clean up */ | 450 | /* This urb is terminated, clean up */ |
451 | dbg("%s - urb shutting down with status: %d", | 451 | dbg("%s - urb shutting down with status: %d", |
452 | __FUNCTION__, urb->status); | 452 | __func__, urb->status); |
453 | return; | 453 | return; |
454 | 454 | ||
455 | default: | 455 | default: |
456 | dbg("%s - nonzero urb status received: %d", | 456 | dbg("%s - nonzero urb status received: %d", |
457 | __FUNCTION__, urb->status); | 457 | __func__, urb->status); |
458 | goto exit; | 458 | goto exit; |
459 | } | 459 | } |
460 | 460 | ||
@@ -813,7 +813,7 @@ exit: | |||
813 | retval = usb_submit_urb(urb, GFP_ATOMIC); | 813 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
814 | if (retval != 0) { | 814 | if (retval != 0) { |
815 | err("%s - usb_submit_urb failed with result %d", | 815 | err("%s - usb_submit_urb failed with result %d", |
816 | __FUNCTION__, retval); | 816 | __func__, retval); |
817 | } | 817 | } |
818 | } | 818 | } |
819 | 819 | ||
diff --git a/drivers/input/tablet/gtco.c b/drivers/input/tablet/gtco.c index 1e748e46d12e..b9b7a98bc5a5 100644 --- a/drivers/input/tablet/gtco.c +++ b/drivers/input/tablet/gtco.c | |||
@@ -863,7 +863,7 @@ static int gtco_probe(struct usb_interface *usbinterface, | |||
863 | gtco->urbinfo = usb_alloc_urb(0, GFP_KERNEL); | 863 | gtco->urbinfo = usb_alloc_urb(0, GFP_KERNEL); |
864 | if (!gtco->urbinfo) { | 864 | if (!gtco->urbinfo) { |
865 | err("Failed to allocate URB"); | 865 | err("Failed to allocate URB"); |
866 | return -ENOMEM; | 866 | error = -ENOMEM; |
867 | goto err_free_buf; | 867 | goto err_free_buf; |
868 | } | 868 | } |
869 | 869 | ||
diff --git a/drivers/input/tablet/kbtab.c b/drivers/input/tablet/kbtab.c index f23f5a97fb38..d89112fa6e6b 100644 --- a/drivers/input/tablet/kbtab.c +++ b/drivers/input/tablet/kbtab.c | |||
@@ -56,10 +56,10 @@ static void kbtab_irq(struct urb *urb) | |||
56 | case -ENOENT: | 56 | case -ENOENT: |
57 | case -ESHUTDOWN: | 57 | case -ESHUTDOWN: |
58 | /* this urb is terminated, clean up */ | 58 | /* this urb is terminated, clean up */ |
59 | dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); | 59 | dbg("%s - urb shutting down with status: %d", __func__, urb->status); |
60 | return; | 60 | return; |
61 | default: | 61 | default: |
62 | dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); | 62 | dbg("%s - nonzero urb status received: %d", __func__, urb->status); |
63 | goto exit; | 63 | goto exit; |
64 | } | 64 | } |
65 | 65 | ||
@@ -88,7 +88,7 @@ static void kbtab_irq(struct urb *urb) | |||
88 | retval = usb_submit_urb (urb, GFP_ATOMIC); | 88 | retval = usb_submit_urb (urb, GFP_ATOMIC); |
89 | if (retval) | 89 | if (retval) |
90 | err ("%s - usb_submit_urb failed with result %d", | 90 | err ("%s - usb_submit_urb failed with result %d", |
91 | __FUNCTION__, retval); | 91 | __func__, retval); |
92 | } | 92 | } |
93 | 93 | ||
94 | static struct usb_device_id kbtab_ids[] = { | 94 | static struct usb_device_id kbtab_ids[] = { |
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h index 706619d06f71..ca62ec639f8f 100644 --- a/drivers/input/tablet/wacom.h +++ b/drivers/input/tablet/wacom.h | |||
@@ -105,7 +105,7 @@ struct wacom { | |||
105 | struct urb *irq; | 105 | struct urb *irq; |
106 | struct wacom_wac * wacom_wac; | 106 | struct wacom_wac * wacom_wac; |
107 | struct mutex lock; | 107 | struct mutex lock; |
108 | int open:1; | 108 | unsigned int open:1; |
109 | char phys[32]; | 109 | char phys[32]; |
110 | }; | 110 | }; |
111 | 111 | ||
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 71cc0c140790..5fbc463baf5a 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
@@ -56,10 +56,10 @@ static void wacom_sys_irq(struct urb *urb) | |||
56 | case -ENOENT: | 56 | case -ENOENT: |
57 | case -ESHUTDOWN: | 57 | case -ESHUTDOWN: |
58 | /* this urb is terminated, clean up */ | 58 | /* this urb is terminated, clean up */ |
59 | dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); | 59 | dbg("%s - urb shutting down with status: %d", __func__, urb->status); |
60 | return; | 60 | return; |
61 | default: | 61 | default: |
62 | dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); | 62 | dbg("%s - nonzero urb status received: %d", __func__, urb->status); |
63 | goto exit; | 63 | goto exit; |
64 | } | 64 | } |
65 | 65 | ||
@@ -74,7 +74,7 @@ static void wacom_sys_irq(struct urb *urb) | |||
74 | retval = usb_submit_urb (urb, GFP_ATOMIC); | 74 | retval = usb_submit_urb (urb, GFP_ATOMIC); |
75 | if (retval) | 75 | if (retval) |
76 | err ("%s - usb_submit_urb failed with result %d", | 76 | err ("%s - usb_submit_urb failed with result %d", |
77 | __FUNCTION__, retval); | 77 | __func__, retval); |
78 | } | 78 | } |
79 | 79 | ||
80 | void wacom_report_key(void *wcombo, unsigned int key_type, int key_data) | 80 | void wacom_report_key(void *wcombo, unsigned int key_type, int key_data) |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 192513e1f04c..bf3d9a8b2c1b 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -56,7 +56,7 @@ static int wacom_penpartner_irq(struct wacom_wac *wacom, void *wcombo) | |||
56 | static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo) | 56 | static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo) |
57 | { | 57 | { |
58 | unsigned char *data = wacom->data; | 58 | unsigned char *data = wacom->data; |
59 | int prox, id, pressure; | 59 | int prox, pressure; |
60 | 60 | ||
61 | if (data[0] != 2) { | 61 | if (data[0] != 2) { |
62 | dbg("wacom_pl_irq: received unknown report #%d", data[0]); | 62 | dbg("wacom_pl_irq: received unknown report #%d", data[0]); |
@@ -65,7 +65,7 @@ static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo) | |||
65 | 65 | ||
66 | prox = data[1] & 0x40; | 66 | prox = data[1] & 0x40; |
67 | 67 | ||
68 | id = ERASER_DEVICE_ID; | 68 | wacom->id[0] = ERASER_DEVICE_ID; |
69 | if (prox) { | 69 | if (prox) { |
70 | 70 | ||
71 | pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); | 71 | pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); |
@@ -99,10 +99,10 @@ static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo) | |||
99 | if (wacom->tool[1] != BTN_TOOL_RUBBER) { | 99 | if (wacom->tool[1] != BTN_TOOL_RUBBER) { |
100 | /* Unknown tool selected default to pen tool */ | 100 | /* Unknown tool selected default to pen tool */ |
101 | wacom->tool[1] = BTN_TOOL_PEN; | 101 | wacom->tool[1] = BTN_TOOL_PEN; |
102 | id = STYLUS_DEVICE_ID; | 102 | wacom->id[0] = STYLUS_DEVICE_ID; |
103 | } | 103 | } |
104 | wacom_report_key(wcombo, wacom->tool[1], prox); /* report in proximity for tool */ | 104 | wacom_report_key(wcombo, wacom->tool[1], prox); /* report in proximity for tool */ |
105 | wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */ | 105 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ |
106 | wacom_report_abs(wcombo, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14)); | 106 | wacom_report_abs(wcombo, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14)); |
107 | wacom_report_abs(wcombo, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14)); | 107 | wacom_report_abs(wcombo, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14)); |
108 | wacom_report_abs(wcombo, ABS_PRESSURE, pressure); | 108 | wacom_report_abs(wcombo, ABS_PRESSURE, pressure); |
@@ -127,7 +127,6 @@ static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo) | |||
127 | static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo) | 127 | static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo) |
128 | { | 128 | { |
129 | unsigned char *data = wacom->data; | 129 | unsigned char *data = wacom->data; |
130 | int id; | ||
131 | 130 | ||
132 | if (data[0] != 2) { | 131 | if (data[0] != 2) { |
133 | printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]); | 132 | printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]); |
@@ -137,13 +136,13 @@ static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo) | |||
137 | if (data[1] & 0x04) { | 136 | if (data[1] & 0x04) { |
138 | wacom_report_key(wcombo, BTN_TOOL_RUBBER, data[1] & 0x20); | 137 | wacom_report_key(wcombo, BTN_TOOL_RUBBER, data[1] & 0x20); |
139 | wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x08); | 138 | wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x08); |
140 | id = ERASER_DEVICE_ID; | 139 | wacom->id[0] = ERASER_DEVICE_ID; |
141 | } else { | 140 | } else { |
142 | wacom_report_key(wcombo, BTN_TOOL_PEN, data[1] & 0x20); | 141 | wacom_report_key(wcombo, BTN_TOOL_PEN, data[1] & 0x20); |
143 | wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01); | 142 | wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01); |
144 | id = STYLUS_DEVICE_ID; | 143 | wacom->id[0] = STYLUS_DEVICE_ID; |
145 | } | 144 | } |
146 | wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */ | 145 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ |
147 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); | 146 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); |
148 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); | 147 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); |
149 | wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6])); | 148 | wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6])); |
@@ -155,27 +154,26 @@ static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo) | |||
155 | static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | 154 | static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) |
156 | { | 155 | { |
157 | unsigned char *data = wacom->data; | 156 | unsigned char *data = wacom->data; |
158 | int x, y, id, rw; | 157 | int x, y, rw; |
159 | 158 | ||
160 | if (data[0] != 2) { | 159 | if (data[0] != 2) { |
161 | dbg("wacom_graphire_irq: received unknown report #%d", data[0]); | 160 | dbg("wacom_graphire_irq: received unknown report #%d", data[0]); |
162 | return 0; | 161 | return 0; |
163 | } | 162 | } |
164 | 163 | ||
165 | id = STYLUS_DEVICE_ID; | 164 | if (data[1] & 0x80) { |
166 | if ((data[1] & 0x80) && ((data[1] & 0x07) || data[2] || data[3] || data[4] | ||
167 | || data[5] || data[6] || (data[7] & 0x07))) { | ||
168 | /* in prox and not a pad data */ | 165 | /* in prox and not a pad data */ |
169 | 166 | ||
170 | switch ((data[1] >> 5) & 3) { | 167 | switch ((data[1] >> 5) & 3) { |
171 | 168 | ||
172 | case 0: /* Pen */ | 169 | case 0: /* Pen */ |
173 | wacom->tool[0] = BTN_TOOL_PEN; | 170 | wacom->tool[0] = BTN_TOOL_PEN; |
171 | wacom->id[0] = STYLUS_DEVICE_ID; | ||
174 | break; | 172 | break; |
175 | 173 | ||
176 | case 1: /* Rubber */ | 174 | case 1: /* Rubber */ |
177 | wacom->tool[0] = BTN_TOOL_RUBBER; | 175 | wacom->tool[0] = BTN_TOOL_RUBBER; |
178 | id = ERASER_DEVICE_ID; | 176 | wacom->id[0] = ERASER_DEVICE_ID; |
179 | break; | 177 | break; |
180 | 178 | ||
181 | case 2: /* Mouse with wheel */ | 179 | case 2: /* Mouse with wheel */ |
@@ -190,7 +188,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
190 | 188 | ||
191 | case 3: /* Mouse without wheel */ | 189 | case 3: /* Mouse without wheel */ |
192 | wacom->tool[0] = BTN_TOOL_MOUSE; | 190 | wacom->tool[0] = BTN_TOOL_MOUSE; |
193 | id = CURSOR_DEVICE_ID; | 191 | wacom->id[0] = CURSOR_DEVICE_ID; |
194 | wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); | 192 | wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); |
195 | wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); | 193 | wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); |
196 | if (wacom->features->type == WACOM_G4 || | 194 | if (wacom->features->type == WACOM_G4 || |
@@ -210,9 +208,9 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
210 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); | 208 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); |
211 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04); | 209 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04); |
212 | } | 210 | } |
213 | wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */ | 211 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ |
214 | wacom_report_key(wcombo, wacom->tool[0], 1); | 212 | wacom_report_key(wcombo, wacom->tool[0], 1); |
215 | } else if (!(data[1] & 0x90)) { | 213 | } else if (wacom->id[0]) { |
216 | wacom_report_abs(wcombo, ABS_X, 0); | 214 | wacom_report_abs(wcombo, ABS_X, 0); |
217 | wacom_report_abs(wcombo, ABS_Y, 0); | 215 | wacom_report_abs(wcombo, ABS_Y, 0); |
218 | if (wacom->tool[0] == BTN_TOOL_MOUSE) { | 216 | if (wacom->tool[0] == BTN_TOOL_MOUSE) { |
@@ -225,6 +223,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
225 | wacom_report_key(wcombo, BTN_STYLUS, 0); | 223 | wacom_report_key(wcombo, BTN_STYLUS, 0); |
226 | wacom_report_key(wcombo, BTN_STYLUS2, 0); | 224 | wacom_report_key(wcombo, BTN_STYLUS2, 0); |
227 | } | 225 | } |
226 | wacom->id[0] = 0; | ||
228 | wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ | 227 | wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ |
229 | wacom_report_key(wcombo, wacom->tool[0], 0); | 228 | wacom_report_key(wcombo, wacom->tool[0], 0); |
230 | } | 229 | } |
@@ -234,13 +233,13 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
234 | case WACOM_G4: | 233 | case WACOM_G4: |
235 | if (data[7] & 0xf8) { | 234 | if (data[7] & 0xf8) { |
236 | wacom_input_sync(wcombo); /* sync last event */ | 235 | wacom_input_sync(wcombo); /* sync last event */ |
237 | wacom->id[1] = 1; | 236 | wacom->id[1] = PAD_DEVICE_ID; |
238 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); | 237 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); |
239 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); | 238 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); |
240 | rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3); | 239 | rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3); |
241 | wacom_report_rel(wcombo, REL_WHEEL, rw); | 240 | wacom_report_rel(wcombo, REL_WHEEL, rw); |
242 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); | 241 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); |
243 | wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID); | 242 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); |
244 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | 243 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); |
245 | } else if (wacom->id[1]) { | 244 | } else if (wacom->id[1]) { |
246 | wacom_input_sync(wcombo); /* sync last event */ | 245 | wacom_input_sync(wcombo); /* sync last event */ |
@@ -255,14 +254,14 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
255 | case WACOM_MO: | 254 | case WACOM_MO: |
256 | if ((data[7] & 0xf8) || (data[8] & 0xff)) { | 255 | if ((data[7] & 0xf8) || (data[8] & 0xff)) { |
257 | wacom_input_sync(wcombo); /* sync last event */ | 256 | wacom_input_sync(wcombo); /* sync last event */ |
258 | wacom->id[1] = 1; | 257 | wacom->id[1] = PAD_DEVICE_ID; |
259 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); | 258 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); |
260 | wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); | 259 | wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); |
261 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x10)); | 260 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x10)); |
262 | wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); | 261 | wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); |
263 | wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); | 262 | wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); |
264 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); | 263 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); |
265 | wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID); | 264 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); |
266 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | 265 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); |
267 | } else if (wacom->id[1]) { | 266 | } else if (wacom->id[1]) { |
268 | wacom_input_sync(wcombo); /* sync last event */ | 267 | wacom_input_sync(wcombo); /* sync last event */ |
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 565ec711c2ee..e57366521572 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
@@ -103,6 +103,18 @@ config TOUCHSCREEN_MTOUCH | |||
103 | To compile this driver as a module, choose M here: the | 103 | To compile this driver as a module, choose M here: the |
104 | module will be called mtouch. | 104 | module will be called mtouch. |
105 | 105 | ||
106 | config TOUCHSCREEN_INEXIO | ||
107 | tristate "iNexio serial touchscreens" | ||
108 | select SERIO | ||
109 | help | ||
110 | Say Y here if you have an iNexio serial touchscreen connected to | ||
111 | your system. | ||
112 | |||
113 | If unsure, say N. | ||
114 | |||
115 | To compile this driver as a module, choose M here: the | ||
116 | module will be called inexio. | ||
117 | |||
106 | config TOUCHSCREEN_MK712 | 118 | config TOUCHSCREEN_MK712 |
107 | tristate "ICS MicroClock MK712 touchscreen" | 119 | tristate "ICS MicroClock MK712 touchscreen" |
108 | help | 120 | help |
@@ -134,6 +146,18 @@ config TOUCHSCREEN_HP7XX | |||
134 | To compile this driver as a module, choose M here: the | 146 | To compile this driver as a module, choose M here: the |
135 | module will be called jornada720_ts. | 147 | module will be called jornada720_ts. |
136 | 148 | ||
149 | config TOUCHSCREEN_HTCPEN | ||
150 | tristate "HTC Shift X9500 touchscreen" | ||
151 | depends on ISA | ||
152 | help | ||
153 | Say Y here if you have an HTC Shift UMPC also known as HTC X9500 | ||
154 | Clio / Shangrila and want to support the built-in touchscreen. | ||
155 | |||
156 | If unsure, say N. | ||
157 | |||
158 | To compile this driver as a module, choose M here: the | ||
159 | module will be called htcpen. | ||
160 | |||
137 | config TOUCHSCREEN_PENMOUNT | 161 | config TOUCHSCREEN_PENMOUNT |
138 | tristate "Penmount serial touchscreen" | 162 | tristate "Penmount serial touchscreen" |
139 | select SERIO | 163 | select SERIO |
@@ -146,6 +170,17 @@ config TOUCHSCREEN_PENMOUNT | |||
146 | To compile this driver as a module, choose M here: the | 170 | To compile this driver as a module, choose M here: the |
147 | module will be called penmount. | 171 | module will be called penmount. |
148 | 172 | ||
173 | config TOUCHSCREEN_MIGOR | ||
174 | tristate "Renesas MIGO-R touchscreen" | ||
175 | depends on SH_MIGOR && I2C | ||
176 | help | ||
177 | Say Y here to enable MIGO-R touchscreen support. | ||
178 | |||
179 | If unsure, say N. | ||
180 | |||
181 | To compile this driver as a module, choose M here: the | ||
182 | module will be called migor_ts. | ||
183 | |||
149 | config TOUCHSCREEN_TOUCHRIGHT | 184 | config TOUCHSCREEN_TOUCHRIGHT |
150 | tristate "Touchright serial touchscreen" | 185 | tristate "Touchright serial touchscreen" |
151 | select SERIO | 186 | select SERIO |
@@ -316,4 +351,15 @@ config TOUCHSCREEN_USB_GOTOP | |||
316 | bool "GoTop Super_Q2/GogoPen/PenPower tablet device support" if EMBEDDED | 351 | bool "GoTop Super_Q2/GogoPen/PenPower tablet device support" if EMBEDDED |
317 | depends on TOUCHSCREEN_USB_COMPOSITE | 352 | depends on TOUCHSCREEN_USB_COMPOSITE |
318 | 353 | ||
354 | config TOUCHSCREEN_TOUCHIT213 | ||
355 | tristate "Sahara TouchIT-213 touchscreen" | ||
356 | select SERIO | ||
357 | help | ||
358 | Say Y here if you have a Sahara TouchIT-213 Tablet PC. | ||
359 | |||
360 | If unsure, say N. | ||
361 | |||
362 | To compile this driver as a module, choose M here: the | ||
363 | module will be called touchit213. | ||
364 | |||
319 | endif | 365 | endif |
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 3c096d75651d..39a804cd80f1 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile | |||
@@ -12,12 +12,16 @@ obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o | |||
12 | obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o | 12 | obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o |
13 | obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o | 13 | obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o |
14 | obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o | 14 | obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o |
15 | obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o | ||
16 | obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o | ||
15 | obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o | 17 | obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o |
16 | obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o | 18 | obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o |
17 | obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o | 19 | obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o |
18 | obj-$(CONFIG_TOUCHSCREEN_HP7XX) += jornada720_ts.o | 20 | obj-$(CONFIG_TOUCHSCREEN_HP7XX) += jornada720_ts.o |
21 | obj-$(CONFIG_TOUCHSCREEN_HTCPEN) += htcpen.o | ||
19 | obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o | 22 | obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o |
20 | obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o | 23 | obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o |
24 | obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o | ||
21 | obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o | 25 | obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o |
22 | obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o | 26 | obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o |
23 | obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o | 27 | obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o |
diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c index a48a15868c4a..a54f90e02ab6 100644 --- a/drivers/input/touchscreen/gunze.c +++ b/drivers/input/touchscreen/gunze.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: gunze.c,v 1.12 2001/09/25 10:12:07 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 2000-2001 Vojtech Pavlik | 2 | * Copyright (c) 2000-2001 Vojtech Pavlik |
5 | */ | 3 | */ |
6 | 4 | ||
diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c index 28ae15ed12c5..4f86081dc7fc 100644 --- a/drivers/input/touchscreen/h3600_ts_input.c +++ b/drivers/input/touchscreen/h3600_ts_input.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: h3600_ts_input.c,v 1.4 2002/01/23 06:39:37 jsimmons Exp $ | ||
3 | * | ||
4 | * Copyright (c) 2001 "Crazy" James Simmons jsimmons@transvirtual.com | 2 | * Copyright (c) 2001 "Crazy" James Simmons jsimmons@transvirtual.com |
5 | * | 3 | * |
6 | * Sponsored by Transvirtual Technology. | 4 | * Sponsored by Transvirtual Technology. |
diff --git a/drivers/input/touchscreen/htcpen.c b/drivers/input/touchscreen/htcpen.c new file mode 100644 index 000000000000..62811de6f18f --- /dev/null +++ b/drivers/input/touchscreen/htcpen.c | |||
@@ -0,0 +1,255 @@ | |||
1 | /* | ||
2 | * HTC Shift touchscreen driver | ||
3 | * | ||
4 | * Copyright (C) 2008 Pau Oliva Fora <pof@eslack.org> | ||
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 version 2 as published | ||
8 | * by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/errno.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/input.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/irq.h> | ||
19 | #include <linux/isa.h> | ||
20 | #include <linux/ioport.h> | ||
21 | #include <linux/dmi.h> | ||
22 | |||
23 | MODULE_AUTHOR("Pau Oliva Fora <pau@eslack.org>"); | ||
24 | MODULE_DESCRIPTION("HTC Shift touchscreen driver"); | ||
25 | MODULE_LICENSE("GPL"); | ||
26 | |||
27 | #define HTCPEN_PORT_IRQ_CLEAR 0x068 | ||
28 | #define HTCPEN_PORT_INIT 0x06c | ||
29 | #define HTCPEN_PORT_INDEX 0x0250 | ||
30 | #define HTCPEN_PORT_DATA 0x0251 | ||
31 | #define HTCPEN_IRQ 3 | ||
32 | |||
33 | #define DEVICE_ENABLE 0xa2 | ||
34 | #define DEVICE_DISABLE 0xa3 | ||
35 | |||
36 | #define X_INDEX 3 | ||
37 | #define Y_INDEX 5 | ||
38 | #define TOUCH_INDEX 0xb | ||
39 | #define LSB_XY_INDEX 0xc | ||
40 | #define X_AXIS_MAX 2040 | ||
41 | #define Y_AXIS_MAX 2040 | ||
42 | |||
43 | static int invert_x; | ||
44 | module_param(invert_x, bool, 0644); | ||
45 | MODULE_PARM_DESC(invert_x, "If set, X axis is inverted"); | ||
46 | static int invert_y; | ||
47 | module_param(invert_y, bool, 0644); | ||
48 | MODULE_PARM_DESC(invert_y, "If set, Y axis is inverted"); | ||
49 | |||
50 | static struct pnp_device_id pnp_ids[] = { | ||
51 | { .id = "PNP0cc0" }, | ||
52 | { .id = "" } | ||
53 | }; | ||
54 | MODULE_DEVICE_TABLE(pnp, pnp_ids); | ||
55 | |||
56 | static irqreturn_t htcpen_interrupt(int irq, void *handle) | ||
57 | { | ||
58 | struct input_dev *htcpen_dev = handle; | ||
59 | unsigned short x, y, xy; | ||
60 | |||
61 | /* 0 = press; 1 = release */ | ||
62 | outb_p(TOUCH_INDEX, HTCPEN_PORT_INDEX); | ||
63 | |||
64 | if (inb_p(HTCPEN_PORT_DATA)) { | ||
65 | input_report_key(htcpen_dev, BTN_TOUCH, 0); | ||
66 | } else { | ||
67 | outb_p(X_INDEX, HTCPEN_PORT_INDEX); | ||
68 | x = inb_p(HTCPEN_PORT_DATA); | ||
69 | |||
70 | outb_p(Y_INDEX, HTCPEN_PORT_INDEX); | ||
71 | y = inb_p(HTCPEN_PORT_DATA); | ||
72 | |||
73 | outb_p(LSB_XY_INDEX, HTCPEN_PORT_INDEX); | ||
74 | xy = inb_p(HTCPEN_PORT_DATA); | ||
75 | |||
76 | /* get high resolution value of X and Y using LSB */ | ||
77 | x = X_AXIS_MAX - ((x * 8) + ((xy >> 4) & 0xf)); | ||
78 | y = (y * 8) + (xy & 0xf); | ||
79 | if (invert_x) | ||
80 | x = X_AXIS_MAX - x; | ||
81 | if (invert_y) | ||
82 | y = Y_AXIS_MAX - y; | ||
83 | |||
84 | if (x != X_AXIS_MAX && x != 0) { | ||
85 | input_report_key(htcpen_dev, BTN_TOUCH, 1); | ||
86 | input_report_abs(htcpen_dev, ABS_X, x); | ||
87 | input_report_abs(htcpen_dev, ABS_Y, y); | ||
88 | } | ||
89 | } | ||
90 | |||
91 | input_sync(htcpen_dev); | ||
92 | |||
93 | inb_p(HTCPEN_PORT_IRQ_CLEAR); | ||
94 | |||
95 | return IRQ_HANDLED; | ||
96 | } | ||
97 | |||
98 | static int htcpen_open(struct input_dev *dev) | ||
99 | { | ||
100 | outb_p(DEVICE_ENABLE, HTCPEN_PORT_INIT); | ||
101 | |||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | static void htcpen_close(struct input_dev *dev) | ||
106 | { | ||
107 | outb_p(DEVICE_DISABLE, HTCPEN_PORT_INIT); | ||
108 | synchronize_irq(HTCPEN_IRQ); | ||
109 | } | ||
110 | |||
111 | static int __devinit htcpen_isa_probe(struct device *dev, unsigned int id) | ||
112 | { | ||
113 | struct input_dev *htcpen_dev; | ||
114 | int err = -EBUSY; | ||
115 | |||
116 | if (!request_region(HTCPEN_PORT_IRQ_CLEAR, 1, "htcpen")) { | ||
117 | printk(KERN_ERR "htcpen: unable to get IO region 0x%x\n", | ||
118 | HTCPEN_PORT_IRQ_CLEAR); | ||
119 | goto request_region1_failed; | ||
120 | } | ||
121 | |||
122 | if (!request_region(HTCPEN_PORT_INIT, 1, "htcpen")) { | ||
123 | printk(KERN_ERR "htcpen: unable to get IO region 0x%x\n", | ||
124 | HTCPEN_PORT_INIT); | ||
125 | goto request_region2_failed; | ||
126 | } | ||
127 | |||
128 | if (!request_region(HTCPEN_PORT_INDEX, 2, "htcpen")) { | ||
129 | printk(KERN_ERR "htcpen: unable to get IO region 0x%x\n", | ||
130 | HTCPEN_PORT_INDEX); | ||
131 | goto request_region3_failed; | ||
132 | } | ||
133 | |||
134 | htcpen_dev = input_allocate_device(); | ||
135 | if (!htcpen_dev) { | ||
136 | printk(KERN_ERR "htcpen: can't allocate device\n"); | ||
137 | err = -ENOMEM; | ||
138 | goto input_alloc_failed; | ||
139 | } | ||
140 | |||
141 | htcpen_dev->name = "HTC Shift EC TouchScreen"; | ||
142 | htcpen_dev->id.bustype = BUS_ISA; | ||
143 | |||
144 | htcpen_dev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY); | ||
145 | htcpen_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
146 | input_set_abs_params(htcpen_dev, ABS_X, 0, X_AXIS_MAX, 0, 0); | ||
147 | input_set_abs_params(htcpen_dev, ABS_Y, 0, Y_AXIS_MAX, 0, 0); | ||
148 | |||
149 | htcpen_dev->open = htcpen_open; | ||
150 | htcpen_dev->close = htcpen_close; | ||
151 | |||
152 | err = request_irq(HTCPEN_IRQ, htcpen_interrupt, 0, "htcpen", | ||
153 | htcpen_dev); | ||
154 | if (err) { | ||
155 | printk(KERN_ERR "htcpen: irq busy\n"); | ||
156 | goto request_irq_failed; | ||
157 | } | ||
158 | |||
159 | inb_p(HTCPEN_PORT_IRQ_CLEAR); | ||
160 | |||
161 | err = input_register_device(htcpen_dev); | ||
162 | if (err) | ||
163 | goto input_register_failed; | ||
164 | |||
165 | dev_set_drvdata(dev, htcpen_dev); | ||
166 | |||
167 | return 0; | ||
168 | |||
169 | input_register_failed: | ||
170 | free_irq(HTCPEN_IRQ, htcpen_dev); | ||
171 | request_irq_failed: | ||
172 | input_free_device(htcpen_dev); | ||
173 | input_alloc_failed: | ||
174 | release_region(HTCPEN_PORT_INDEX, 2); | ||
175 | request_region3_failed: | ||
176 | release_region(HTCPEN_PORT_INIT, 1); | ||
177 | request_region2_failed: | ||
178 | release_region(HTCPEN_PORT_IRQ_CLEAR, 1); | ||
179 | request_region1_failed: | ||
180 | return err; | ||
181 | } | ||
182 | |||
183 | static int __devexit htcpen_isa_remove(struct device *dev, unsigned int id) | ||
184 | { | ||
185 | struct input_dev *htcpen_dev = dev_get_drvdata(dev); | ||
186 | |||
187 | input_unregister_device(htcpen_dev); | ||
188 | |||
189 | free_irq(HTCPEN_IRQ, htcpen_dev); | ||
190 | |||
191 | release_region(HTCPEN_PORT_INDEX, 2); | ||
192 | release_region(HTCPEN_PORT_INIT, 1); | ||
193 | release_region(HTCPEN_PORT_IRQ_CLEAR, 1); | ||
194 | |||
195 | dev_set_drvdata(dev, NULL); | ||
196 | |||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | #ifdef CONFIG_PM | ||
201 | static int htcpen_isa_suspend(struct device *dev, unsigned int n, | ||
202 | pm_message_t state) | ||
203 | { | ||
204 | outb_p(DEVICE_DISABLE, HTCPEN_PORT_INIT); | ||
205 | |||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | static int htcpen_isa_resume(struct device *dev, unsigned int n) | ||
210 | { | ||
211 | outb_p(DEVICE_ENABLE, HTCPEN_PORT_INIT); | ||
212 | |||
213 | return 0; | ||
214 | } | ||
215 | #endif | ||
216 | |||
217 | static struct isa_driver htcpen_isa_driver = { | ||
218 | .probe = htcpen_isa_probe, | ||
219 | .remove = __devexit_p(htcpen_isa_remove), | ||
220 | #ifdef CONFIG_PM | ||
221 | .suspend = htcpen_isa_suspend, | ||
222 | .resume = htcpen_isa_resume, | ||
223 | #endif | ||
224 | .driver = { | ||
225 | .owner = THIS_MODULE, | ||
226 | .name = "htcpen", | ||
227 | } | ||
228 | }; | ||
229 | |||
230 | static struct dmi_system_id __initdata htcshift_dmi_table[] = { | ||
231 | { | ||
232 | .ident = "Shift", | ||
233 | .matches = { | ||
234 | DMI_MATCH(DMI_SYS_VENDOR, "High Tech Computer Corp"), | ||
235 | DMI_MATCH(DMI_PRODUCT_NAME, "Shift"), | ||
236 | }, | ||
237 | }, | ||
238 | { } | ||
239 | }; | ||
240 | |||
241 | static int __init htcpen_isa_init(void) | ||
242 | { | ||
243 | if (!dmi_check_system(htcshift_dmi_table)) | ||
244 | return -ENODEV; | ||
245 | |||
246 | return isa_register_driver(&htcpen_isa_driver, 1); | ||
247 | } | ||
248 | |||
249 | static void __exit htcpen_isa_exit(void) | ||
250 | { | ||
251 | isa_unregister_driver(&htcpen_isa_driver); | ||
252 | } | ||
253 | |||
254 | module_init(htcpen_isa_init); | ||
255 | module_exit(htcpen_isa_exit); | ||
diff --git a/drivers/input/touchscreen/inexio.c b/drivers/input/touchscreen/inexio.c new file mode 100644 index 000000000000..192ade0a0fb9 --- /dev/null +++ b/drivers/input/touchscreen/inexio.c | |||
@@ -0,0 +1,207 @@ | |||
1 | /* | ||
2 | * iNexio serial touchscreen driver | ||
3 | * | ||
4 | * Copyright (c) 2008 Richard Lemon | ||
5 | * Based on the mtouch driver (c) Vojtech Pavlik and Dan Streetman | ||
6 | * | ||
7 | */ | ||
8 | |||
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 version 2 as published by | ||
12 | * the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | /* | ||
16 | * 2008/06/19 Richard Lemon <richard@codelemon.com> | ||
17 | * Copied mtouch.c and edited for iNexio protocol | ||
18 | */ | ||
19 | |||
20 | #include <linux/errno.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/input.h> | ||
25 | #include <linux/serio.h> | ||
26 | #include <linux/init.h> | ||
27 | |||
28 | #define DRIVER_DESC "iNexio serial touchscreen driver" | ||
29 | |||
30 | MODULE_AUTHOR("Richard Lemon <richard@codelemon.com>"); | ||
31 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
32 | MODULE_LICENSE("GPL"); | ||
33 | |||
34 | /* | ||
35 | * Definitions & global arrays. | ||
36 | */ | ||
37 | |||
38 | #define INEXIO_FORMAT_TOUCH_BIT 0x01 | ||
39 | #define INEXIO_FORMAT_LENGTH 5 | ||
40 | #define INEXIO_RESPONSE_BEGIN_BYTE 0x80 | ||
41 | |||
42 | /* todo: check specs for max length of all responses */ | ||
43 | #define INEXIO_MAX_LENGTH 16 | ||
44 | |||
45 | #define INEXIO_MIN_XC 0 | ||
46 | #define INEXIO_MAX_XC 0x3fff | ||
47 | #define INEXIO_MIN_YC 0 | ||
48 | #define INEXIO_MAX_YC 0x3fff | ||
49 | |||
50 | #define INEXIO_GET_XC(data) (((data[1])<<7) | data[2]) | ||
51 | #define INEXIO_GET_YC(data) (((data[3])<<7) | data[4]) | ||
52 | #define INEXIO_GET_TOUCHED(data) (INEXIO_FORMAT_TOUCH_BIT & data[0]) | ||
53 | |||
54 | /* | ||
55 | * Per-touchscreen data. | ||
56 | */ | ||
57 | |||
58 | struct inexio { | ||
59 | struct input_dev *dev; | ||
60 | struct serio *serio; | ||
61 | int idx; | ||
62 | unsigned char data[INEXIO_MAX_LENGTH]; | ||
63 | char phys[32]; | ||
64 | }; | ||
65 | |||
66 | static void inexio_process_data(struct inexio *pinexio) | ||
67 | { | ||
68 | struct input_dev *dev = pinexio->dev; | ||
69 | |||
70 | if (INEXIO_FORMAT_LENGTH == ++pinexio->idx) { | ||
71 | input_report_abs(dev, ABS_X, INEXIO_GET_XC(pinexio->data)); | ||
72 | input_report_abs(dev, ABS_Y, INEXIO_GET_YC(pinexio->data)); | ||
73 | input_report_key(dev, BTN_TOUCH, INEXIO_GET_TOUCHED(pinexio->data)); | ||
74 | input_sync(dev); | ||
75 | |||
76 | pinexio->idx = 0; | ||
77 | } | ||
78 | } | ||
79 | |||
80 | static irqreturn_t inexio_interrupt(struct serio *serio, | ||
81 | unsigned char data, unsigned int flags) | ||
82 | { | ||
83 | struct inexio* pinexio = serio_get_drvdata(serio); | ||
84 | |||
85 | pinexio->data[pinexio->idx] = data; | ||
86 | |||
87 | if (INEXIO_RESPONSE_BEGIN_BYTE&pinexio->data[0]) | ||
88 | inexio_process_data(pinexio); | ||
89 | else | ||
90 | printk(KERN_DEBUG "inexio.c: unknown/unsynchronized data from device, byte %x\n",pinexio->data[0]); | ||
91 | |||
92 | return IRQ_HANDLED; | ||
93 | } | ||
94 | |||
95 | /* | ||
96 | * inexio_disconnect() is the opposite of inexio_connect() | ||
97 | */ | ||
98 | |||
99 | static void inexio_disconnect(struct serio *serio) | ||
100 | { | ||
101 | struct inexio* pinexio = serio_get_drvdata(serio); | ||
102 | |||
103 | input_get_device(pinexio->dev); | ||
104 | input_unregister_device(pinexio->dev); | ||
105 | serio_close(serio); | ||
106 | serio_set_drvdata(serio, NULL); | ||
107 | input_put_device(pinexio->dev); | ||
108 | kfree(pinexio); | ||
109 | } | ||
110 | |||
111 | /* | ||
112 | * inexio_connect() is the routine that is called when someone adds a | ||
113 | * new serio device that supports iNexio protocol and registers it as | ||
114 | * an input device. This is usually accomplished using inputattach. | ||
115 | */ | ||
116 | |||
117 | static int inexio_connect(struct serio *serio, struct serio_driver *drv) | ||
118 | { | ||
119 | struct inexio *pinexio; | ||
120 | struct input_dev *input_dev; | ||
121 | int err; | ||
122 | |||
123 | pinexio = kzalloc(sizeof(struct inexio), GFP_KERNEL); | ||
124 | input_dev = input_allocate_device(); | ||
125 | if (!pinexio || !input_dev) { | ||
126 | err = -ENOMEM; | ||
127 | goto fail1; | ||
128 | } | ||
129 | |||
130 | pinexio->serio = serio; | ||
131 | pinexio->dev = input_dev; | ||
132 | snprintf(pinexio->phys, sizeof(pinexio->phys), "%s/input0", serio->phys); | ||
133 | |||
134 | input_dev->name = "iNexio Serial TouchScreen"; | ||
135 | input_dev->phys = pinexio->phys; | ||
136 | input_dev->id.bustype = BUS_RS232; | ||
137 | input_dev->id.vendor = SERIO_INEXIO; | ||
138 | input_dev->id.product = 0; | ||
139 | input_dev->id.version = 0x0001; | ||
140 | input_dev->dev.parent = &serio->dev; | ||
141 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
142 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
143 | input_set_abs_params(pinexio->dev, ABS_X, INEXIO_MIN_XC, INEXIO_MAX_XC, 0, 0); | ||
144 | input_set_abs_params(pinexio->dev, ABS_Y, INEXIO_MIN_YC, INEXIO_MAX_YC, 0, 0); | ||
145 | |||
146 | serio_set_drvdata(serio, pinexio); | ||
147 | |||
148 | err = serio_open(serio, drv); | ||
149 | if (err) | ||
150 | goto fail2; | ||
151 | |||
152 | err = input_register_device(pinexio->dev); | ||
153 | if (err) | ||
154 | goto fail3; | ||
155 | |||
156 | return 0; | ||
157 | |||
158 | fail3: serio_close(serio); | ||
159 | fail2: serio_set_drvdata(serio, NULL); | ||
160 | fail1: input_free_device(input_dev); | ||
161 | kfree(pinexio); | ||
162 | return err; | ||
163 | } | ||
164 | |||
165 | /* | ||
166 | * The serio driver structure. | ||
167 | */ | ||
168 | |||
169 | static struct serio_device_id inexio_serio_ids[] = { | ||
170 | { | ||
171 | .type = SERIO_RS232, | ||
172 | .proto = SERIO_INEXIO, | ||
173 | .id = SERIO_ANY, | ||
174 | .extra = SERIO_ANY, | ||
175 | }, | ||
176 | { 0 } | ||
177 | }; | ||
178 | |||
179 | MODULE_DEVICE_TABLE(serio, inexio_serio_ids); | ||
180 | |||
181 | static struct serio_driver inexio_drv = { | ||
182 | .driver = { | ||
183 | .name = "inexio", | ||
184 | }, | ||
185 | .description = DRIVER_DESC, | ||
186 | .id_table = inexio_serio_ids, | ||
187 | .interrupt = inexio_interrupt, | ||
188 | .connect = inexio_connect, | ||
189 | .disconnect = inexio_disconnect, | ||
190 | }; | ||
191 | |||
192 | /* | ||
193 | * The functions for inserting/removing us as a module. | ||
194 | */ | ||
195 | |||
196 | static int __init inexio_init(void) | ||
197 | { | ||
198 | return serio_register_driver(&inexio_drv); | ||
199 | } | ||
200 | |||
201 | static void __exit inexio_exit(void) | ||
202 | { | ||
203 | serio_unregister_driver(&inexio_drv); | ||
204 | } | ||
205 | |||
206 | module_init(inexio_init); | ||
207 | module_exit(inexio_exit); | ||
diff --git a/drivers/input/touchscreen/migor_ts.c b/drivers/input/touchscreen/migor_ts.c new file mode 100644 index 000000000000..c1cd99d58981 --- /dev/null +++ b/drivers/input/touchscreen/migor_ts.c | |||
@@ -0,0 +1,250 @@ | |||
1 | /* | ||
2 | * Touch Screen driver for Renesas MIGO-R Platform | ||
3 | * | ||
4 | * Copyright (c) 2008 Magnus Damm | ||
5 | * Copyright (c) 2007 Ujjwal Pande <ujjwal@kenati.com>, | ||
6 | * Kenati Technologies Pvt Ltd. | ||
7 | * | ||
8 | * This file is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public | ||
10 | * License as published by the Free Software Foundation; either | ||
11 | * version 2 of the License, or (at your option) any later version. | ||
12 | * | ||
13 | * This file is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public | ||
19 | * License along with this library; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/input.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <asm/io.h> | ||
27 | #include <linux/i2c.h> | ||
28 | #include <linux/timer.h> | ||
29 | |||
30 | #define EVENT_PENDOWN 1 | ||
31 | #define EVENT_REPEAT 2 | ||
32 | #define EVENT_PENUP 3 | ||
33 | |||
34 | struct migor_ts_priv { | ||
35 | struct i2c_client *client; | ||
36 | struct input_dev *input; | ||
37 | struct delayed_work work; | ||
38 | int irq; | ||
39 | }; | ||
40 | |||
41 | static const u_int8_t migor_ts_ena_seq[17] = { 0x33, 0x22, 0x11, | ||
42 | 0x01, 0x06, 0x07, }; | ||
43 | static const u_int8_t migor_ts_dis_seq[17] = { }; | ||
44 | |||
45 | static void migor_ts_poscheck(struct work_struct *work) | ||
46 | { | ||
47 | struct migor_ts_priv *priv = container_of(work, | ||
48 | struct migor_ts_priv, | ||
49 | work.work); | ||
50 | unsigned short xpos, ypos; | ||
51 | unsigned char event; | ||
52 | u_int8_t buf[16]; | ||
53 | |||
54 | memset(buf, 0, sizeof(buf)); | ||
55 | |||
56 | /* Set Index 0 */ | ||
57 | buf[0] = 0; | ||
58 | if (i2c_master_send(priv->client, buf, 1) != 1) { | ||
59 | dev_err(&priv->client->dev, "Unable to write i2c index\n"); | ||
60 | goto out; | ||
61 | } | ||
62 | |||
63 | /* Now do Page Read */ | ||
64 | if (i2c_master_recv(priv->client, buf, sizeof(buf)) != sizeof(buf)) { | ||
65 | dev_err(&priv->client->dev, "Unable to read i2c page\n"); | ||
66 | goto out; | ||
67 | } | ||
68 | |||
69 | ypos = ((buf[9] & 0x03) << 8 | buf[8]); | ||
70 | xpos = ((buf[11] & 0x03) << 8 | buf[10]); | ||
71 | event = buf[12]; | ||
72 | |||
73 | if (event == EVENT_PENDOWN || event == EVENT_REPEAT) { | ||
74 | input_report_key(priv->input, BTN_TOUCH, 1); | ||
75 | input_report_abs(priv->input, ABS_X, ypos); /*X-Y swap*/ | ||
76 | input_report_abs(priv->input, ABS_Y, xpos); | ||
77 | input_sync(priv->input); | ||
78 | } else if (event == EVENT_PENUP) { | ||
79 | input_report_key(priv->input, BTN_TOUCH, 0); | ||
80 | input_sync(priv->input); | ||
81 | } | ||
82 | out: | ||
83 | enable_irq(priv->irq); | ||
84 | } | ||
85 | |||
86 | static irqreturn_t migor_ts_isr(int irq, void *dev_id) | ||
87 | { | ||
88 | struct migor_ts_priv *priv = dev_id; | ||
89 | |||
90 | /* the touch screen controller chip is hooked up to the cpu | ||
91 | * using i2c and a single interrupt line. the interrupt line | ||
92 | * is pulled low whenever someone taps the screen. to deassert | ||
93 | * the interrupt line we need to acknowledge the interrupt by | ||
94 | * communicating with the controller over the slow i2c bus. | ||
95 | * | ||
96 | * we can't acknowledge from interrupt context since the i2c | ||
97 | * bus controller may sleep, so we just disable the interrupt | ||
98 | * here and handle the acknowledge using delayed work. | ||
99 | */ | ||
100 | |||
101 | disable_irq_nosync(irq); | ||
102 | schedule_delayed_work(&priv->work, HZ / 20); | ||
103 | |||
104 | return IRQ_HANDLED; | ||
105 | } | ||
106 | |||
107 | |||
108 | static int migor_ts_open(struct input_dev *dev) | ||
109 | { | ||
110 | struct migor_ts_priv *priv = input_get_drvdata(dev); | ||
111 | struct i2c_client *client = priv->client; | ||
112 | int count; | ||
113 | |||
114 | /* enable controller */ | ||
115 | count = i2c_master_send(client, migor_ts_ena_seq, | ||
116 | sizeof(migor_ts_ena_seq)); | ||
117 | if (count != sizeof(migor_ts_ena_seq)) { | ||
118 | dev_err(&client->dev, "Unable to enable touchscreen.\n"); | ||
119 | return -ENXIO; | ||
120 | } | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | static void migor_ts_close(struct input_dev *dev) | ||
126 | { | ||
127 | struct migor_ts_priv *priv = input_get_drvdata(dev); | ||
128 | struct i2c_client *client = priv->client; | ||
129 | |||
130 | disable_irq(priv->irq); | ||
131 | |||
132 | /* cancel pending work and wait for migor_ts_poscheck() to finish */ | ||
133 | if (cancel_delayed_work_sync(&priv->work)) { | ||
134 | /* | ||
135 | * if migor_ts_poscheck was canceled we need to enable IRQ | ||
136 | * here to balance disable done in migor_ts_isr. | ||
137 | */ | ||
138 | enable_irq(priv->irq); | ||
139 | } | ||
140 | |||
141 | /* disable controller */ | ||
142 | i2c_master_send(client, migor_ts_dis_seq, sizeof(migor_ts_dis_seq)); | ||
143 | |||
144 | enable_irq(priv->irq); | ||
145 | } | ||
146 | |||
147 | static int migor_ts_probe(struct i2c_client *client, | ||
148 | const struct i2c_device_id *idp) | ||
149 | { | ||
150 | struct migor_ts_priv *priv; | ||
151 | struct input_dev *input; | ||
152 | int error; | ||
153 | |||
154 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
155 | if (!priv) { | ||
156 | dev_err(&client->dev, "failed to allocate driver data\n"); | ||
157 | error = -ENOMEM; | ||
158 | goto err0; | ||
159 | } | ||
160 | |||
161 | dev_set_drvdata(&client->dev, priv); | ||
162 | |||
163 | input = input_allocate_device(); | ||
164 | if (!input) { | ||
165 | dev_err(&client->dev, "Failed to allocate input device.\n"); | ||
166 | error = -ENOMEM; | ||
167 | goto err1; | ||
168 | } | ||
169 | |||
170 | input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
171 | input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
172 | |||
173 | input_set_abs_params(input, ABS_X, 95, 955, 0, 0); | ||
174 | input_set_abs_params(input, ABS_Y, 85, 935, 0, 0); | ||
175 | |||
176 | input->name = client->driver_name; | ||
177 | input->id.bustype = BUS_I2C; | ||
178 | input->dev.parent = &client->dev; | ||
179 | |||
180 | input->open = migor_ts_open; | ||
181 | input->close = migor_ts_close; | ||
182 | |||
183 | input_set_drvdata(input, priv); | ||
184 | |||
185 | priv->client = client; | ||
186 | priv->input = input; | ||
187 | INIT_DELAYED_WORK(&priv->work, migor_ts_poscheck); | ||
188 | priv->irq = client->irq; | ||
189 | |||
190 | error = input_register_device(input); | ||
191 | if (error) | ||
192 | goto err1; | ||
193 | |||
194 | error = request_irq(priv->irq, migor_ts_isr, IRQF_TRIGGER_LOW, | ||
195 | client->driver_name, priv); | ||
196 | if (error) { | ||
197 | dev_err(&client->dev, "Unable to request touchscreen IRQ.\n"); | ||
198 | goto err2; | ||
199 | } | ||
200 | |||
201 | return 0; | ||
202 | |||
203 | err2: | ||
204 | input_unregister_device(input); | ||
205 | input = NULL; /* so we dont try to free it below */ | ||
206 | err1: | ||
207 | input_free_device(input); | ||
208 | kfree(priv); | ||
209 | err0: | ||
210 | dev_set_drvdata(&client->dev, NULL); | ||
211 | return error; | ||
212 | } | ||
213 | |||
214 | static int migor_ts_remove(struct i2c_client *client) | ||
215 | { | ||
216 | struct migor_ts_priv *priv = dev_get_drvdata(&client->dev); | ||
217 | |||
218 | free_irq(priv->irq, priv); | ||
219 | input_unregister_device(priv->input); | ||
220 | kfree(priv); | ||
221 | |||
222 | dev_set_drvdata(&client->dev, NULL); | ||
223 | |||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | static struct i2c_driver migor_ts_driver = { | ||
228 | .driver = { | ||
229 | .name = "migor_ts", | ||
230 | }, | ||
231 | .probe = migor_ts_probe, | ||
232 | .remove = migor_ts_remove, | ||
233 | }; | ||
234 | |||
235 | static int __init migor_ts_init(void) | ||
236 | { | ||
237 | return i2c_add_driver(&migor_ts_driver); | ||
238 | } | ||
239 | |||
240 | static void __exit migor_ts_exit(void) | ||
241 | { | ||
242 | i2c_del_driver(&migor_ts_driver); | ||
243 | } | ||
244 | |||
245 | MODULE_DESCRIPTION("MigoR Touchscreen driver"); | ||
246 | MODULE_AUTHOR("Magnus Damm <damm@opensource.se>"); | ||
247 | MODULE_LICENSE("GPL"); | ||
248 | |||
249 | module_init(migor_ts_init); | ||
250 | module_exit(migor_ts_exit); | ||
diff --git a/drivers/input/touchscreen/touchit213.c b/drivers/input/touchscreen/touchit213.c new file mode 100644 index 000000000000..d1297ba19daf --- /dev/null +++ b/drivers/input/touchscreen/touchit213.c | |||
@@ -0,0 +1,234 @@ | |||
1 | /* | ||
2 | * Sahara TouchIT-213 serial touchscreen driver | ||
3 | * | ||
4 | * Copyright (c) 2007-2008 Claudio Nieder <private@claudio.ch> | ||
5 | * | ||
6 | * Based on Touchright driver (drivers/input/touchscreen/touchright.c) | ||
7 | * Copyright (c) 2006 Rick Koch <n1gp@hotmail.com> | ||
8 | * Copyright (c) 2004 Vojtech Pavlik | ||
9 | * and Dan Streetman <ddstreet@ieee.org> | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * This program is free software; you can redistribute it and/or modify it | ||
14 | * under the terms of the GNU General Public License version 2 as published | ||
15 | * by the Free Software Foundation. | ||
16 | */ | ||
17 | |||
18 | #include <linux/errno.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/input.h> | ||
23 | #include <linux/serio.h> | ||
24 | #include <linux/init.h> | ||
25 | |||
26 | #define DRIVER_DESC "Sahara TouchIT-213 serial touchscreen driver" | ||
27 | |||
28 | MODULE_AUTHOR("Claudio Nieder <private@claudio.ch>"); | ||
29 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
30 | MODULE_LICENSE("GPL"); | ||
31 | |||
32 | /* | ||
33 | * Definitions & global arrays. | ||
34 | */ | ||
35 | |||
36 | /* | ||
37 | * Data is received through COM1 at 9600bit/s,8bit,no parity in packets | ||
38 | * of 5 byte each. | ||
39 | * | ||
40 | * +--------+ +--------+ +--------+ +--------+ +--------+ | ||
41 | * |1000000p| |0xxxxxxx| |0xxxxxxx| |0yyyyyyy| |0yyyyyyy| | ||
42 | * +--------+ +--------+ +--------+ +--------+ +--------+ | ||
43 | * MSB LSB MSB LSB | ||
44 | * | ||
45 | * The value of p is 1 as long as the screen is touched and 0 when | ||
46 | * reporting the location where touching stopped, e.g. where the pen was | ||
47 | * lifted from the screen. | ||
48 | * | ||
49 | * When holding the screen in landscape mode as the BIOS text output is | ||
50 | * presented, x is the horizontal axis with values growing from left to | ||
51 | * right and y is the vertical axis with values growing from top to | ||
52 | * bottom. | ||
53 | * | ||
54 | * When holding the screen in portrait mode with the Sahara logo in its | ||
55 | * correct position, x ist the vertical axis with values growing from | ||
56 | * top to bottom and y is the horizontal axis with values growing from | ||
57 | * right to left. | ||
58 | */ | ||
59 | |||
60 | #define T213_FORMAT_TOUCH_BIT 0x01 | ||
61 | #define T213_FORMAT_STATUS_BYTE 0x80 | ||
62 | #define T213_FORMAT_STATUS_MASK ~T213_FORMAT_TOUCH_BIT | ||
63 | |||
64 | /* | ||
65 | * On my Sahara Touch-IT 213 I have observed x values from 0 to 0x7f0 | ||
66 | * and y values from 0x1d to 0x7e9, so the actual measurement is | ||
67 | * probably done with an 11 bit precision. | ||
68 | */ | ||
69 | #define T213_MIN_XC 0 | ||
70 | #define T213_MAX_XC 0x07ff | ||
71 | #define T213_MIN_YC 0 | ||
72 | #define T213_MAX_YC 0x07ff | ||
73 | |||
74 | /* | ||
75 | * Per-touchscreen data. | ||
76 | */ | ||
77 | |||
78 | struct touchit213 { | ||
79 | struct input_dev *dev; | ||
80 | struct serio *serio; | ||
81 | int idx; | ||
82 | unsigned char csum; | ||
83 | unsigned char data[5]; | ||
84 | char phys[32]; | ||
85 | }; | ||
86 | |||
87 | static irqreturn_t touchit213_interrupt(struct serio *serio, | ||
88 | unsigned char data, unsigned int flags) | ||
89 | { | ||
90 | struct touchit213 *touchit213 = serio_get_drvdata(serio); | ||
91 | struct input_dev *dev = touchit213->dev; | ||
92 | |||
93 | touchit213->data[touchit213->idx] = data; | ||
94 | |||
95 | switch (touchit213->idx++) { | ||
96 | case 0: | ||
97 | if ((touchit213->data[0] & T213_FORMAT_STATUS_MASK) != | ||
98 | T213_FORMAT_STATUS_BYTE) { | ||
99 | pr_debug("unsynchronized data: 0x%02x\n", data); | ||
100 | touchit213->idx = 0; | ||
101 | } | ||
102 | break; | ||
103 | |||
104 | case 4: | ||
105 | touchit213->idx = 0; | ||
106 | input_report_abs(dev, ABS_X, | ||
107 | (touchit213->data[1] << 7) | touchit213->data[2]); | ||
108 | input_report_abs(dev, ABS_Y, | ||
109 | (touchit213->data[3] << 7) | touchit213->data[4]); | ||
110 | input_report_key(dev, BTN_TOUCH, | ||
111 | touchit213->data[0] & T213_FORMAT_TOUCH_BIT); | ||
112 | input_sync(dev); | ||
113 | break; | ||
114 | } | ||
115 | |||
116 | return IRQ_HANDLED; | ||
117 | } | ||
118 | |||
119 | /* | ||
120 | * touchit213_disconnect() is the opposite of touchit213_connect() | ||
121 | */ | ||
122 | |||
123 | static void touchit213_disconnect(struct serio *serio) | ||
124 | { | ||
125 | struct touchit213 *touchit213 = serio_get_drvdata(serio); | ||
126 | |||
127 | input_get_device(touchit213->dev); | ||
128 | input_unregister_device(touchit213->dev); | ||
129 | serio_close(serio); | ||
130 | serio_set_drvdata(serio, NULL); | ||
131 | input_put_device(touchit213->dev); | ||
132 | kfree(touchit213); | ||
133 | } | ||
134 | |||
135 | /* | ||
136 | * touchit213_connect() is the routine that is called when someone adds a | ||
137 | * new serio device that supports the Touchright protocol and registers it as | ||
138 | * an input device. | ||
139 | */ | ||
140 | |||
141 | static int touchit213_connect(struct serio *serio, struct serio_driver *drv) | ||
142 | { | ||
143 | struct touchit213 *touchit213; | ||
144 | struct input_dev *input_dev; | ||
145 | int err; | ||
146 | |||
147 | touchit213 = kzalloc(sizeof(struct touchit213), GFP_KERNEL); | ||
148 | input_dev = input_allocate_device(); | ||
149 | if (!touchit213 || !input_dev) { | ||
150 | err = -ENOMEM; | ||
151 | goto fail1; | ||
152 | } | ||
153 | |||
154 | touchit213->serio = serio; | ||
155 | touchit213->dev = input_dev; | ||
156 | snprintf(touchit213->phys, sizeof(touchit213->phys), | ||
157 | "%s/input0", serio->phys); | ||
158 | |||
159 | input_dev->name = "Sahara Touch-iT213 Serial TouchScreen"; | ||
160 | input_dev->phys = touchit213->phys; | ||
161 | input_dev->id.bustype = BUS_RS232; | ||
162 | input_dev->id.vendor = SERIO_TOUCHIT213; | ||
163 | input_dev->id.product = 0; | ||
164 | input_dev->id.version = 0x0100; | ||
165 | input_dev->dev.parent = &serio->dev; | ||
166 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
167 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
168 | input_set_abs_params(touchit213->dev, ABS_X, | ||
169 | T213_MIN_XC, T213_MAX_XC, 0, 0); | ||
170 | input_set_abs_params(touchit213->dev, ABS_Y, | ||
171 | T213_MIN_YC, T213_MAX_YC, 0, 0); | ||
172 | |||
173 | serio_set_drvdata(serio, touchit213); | ||
174 | |||
175 | err = serio_open(serio, drv); | ||
176 | if (err) | ||
177 | goto fail2; | ||
178 | |||
179 | err = input_register_device(touchit213->dev); | ||
180 | if (err) | ||
181 | goto fail3; | ||
182 | |||
183 | return 0; | ||
184 | |||
185 | fail3: serio_close(serio); | ||
186 | fail2: serio_set_drvdata(serio, NULL); | ||
187 | fail1: input_free_device(input_dev); | ||
188 | kfree(touchit213); | ||
189 | return err; | ||
190 | } | ||
191 | |||
192 | /* | ||
193 | * The serio driver structure. | ||
194 | */ | ||
195 | |||
196 | static struct serio_device_id touchit213_serio_ids[] = { | ||
197 | { | ||
198 | .type = SERIO_RS232, | ||
199 | .proto = SERIO_TOUCHIT213, | ||
200 | .id = SERIO_ANY, | ||
201 | .extra = SERIO_ANY, | ||
202 | }, | ||
203 | { 0 } | ||
204 | }; | ||
205 | |||
206 | MODULE_DEVICE_TABLE(serio, touchit213_serio_ids); | ||
207 | |||
208 | static struct serio_driver touchit213_drv = { | ||
209 | .driver = { | ||
210 | .name = "touchit213", | ||
211 | }, | ||
212 | .description = DRIVER_DESC, | ||
213 | .id_table = touchit213_serio_ids, | ||
214 | .interrupt = touchit213_interrupt, | ||
215 | .connect = touchit213_connect, | ||
216 | .disconnect = touchit213_disconnect, | ||
217 | }; | ||
218 | |||
219 | /* | ||
220 | * The functions for inserting/removing us as a module. | ||
221 | */ | ||
222 | |||
223 | static int __init touchit213_init(void) | ||
224 | { | ||
225 | return serio_register_driver(&touchit213_drv); | ||
226 | } | ||
227 | |||
228 | static void __exit touchit213_exit(void) | ||
229 | { | ||
230 | serio_unregister_driver(&touchit213_drv); | ||
231 | } | ||
232 | |||
233 | module_init(touchit213_init); | ||
234 | module_exit(touchit213_exit); | ||
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 3a0a8ca57076..fdd645c214a2 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include <linux/init.h> | 49 | #include <linux/init.h> |
50 | #include <linux/usb.h> | 50 | #include <linux/usb.h> |
51 | #include <linux/usb/input.h> | 51 | #include <linux/usb/input.h> |
52 | #include <linux/hid.h> | ||
52 | 53 | ||
53 | 54 | ||
54 | #define DRIVER_VERSION "v0.6" | 55 | #define DRIVER_VERSION "v0.6" |
@@ -101,7 +102,7 @@ struct usbtouch_usb { | |||
101 | 102 | ||
102 | /* device types */ | 103 | /* device types */ |
103 | enum { | 104 | enum { |
104 | DEVTPYE_DUMMY = -1, | 105 | DEVTYPE_IGNORE = -1, |
105 | DEVTYPE_EGALAX, | 106 | DEVTYPE_EGALAX, |
106 | DEVTYPE_PANJIT, | 107 | DEVTYPE_PANJIT, |
107 | DEVTYPE_3M, | 108 | DEVTYPE_3M, |
@@ -115,8 +116,21 @@ enum { | |||
115 | DEVTYPE_GOTOP, | 116 | DEVTYPE_GOTOP, |
116 | }; | 117 | }; |
117 | 118 | ||
119 | #define USB_DEVICE_HID_CLASS(vend, prod) \ | ||
120 | .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS \ | ||
121 | | USB_DEVICE_ID_MATCH_DEVICE, \ | ||
122 | .idVendor = (vend), \ | ||
123 | .idProduct = (prod), \ | ||
124 | .bInterfaceClass = USB_INTERFACE_CLASS_HID, \ | ||
125 | .bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE | ||
126 | |||
118 | static struct usb_device_id usbtouch_devices[] = { | 127 | static struct usb_device_id usbtouch_devices[] = { |
119 | #ifdef CONFIG_TOUCHSCREEN_USB_EGALAX | 128 | #ifdef CONFIG_TOUCHSCREEN_USB_EGALAX |
129 | /* ignore the HID capable devices, handled by usbhid */ | ||
130 | {USB_DEVICE_HID_CLASS(0x0eef, 0x0001), .driver_info = DEVTYPE_IGNORE}, | ||
131 | {USB_DEVICE_HID_CLASS(0x0eef, 0x0002), .driver_info = DEVTYPE_IGNORE}, | ||
132 | |||
133 | /* normal device IDs */ | ||
120 | {USB_DEVICE(0x3823, 0x0001), .driver_info = DEVTYPE_EGALAX}, | 134 | {USB_DEVICE(0x3823, 0x0001), .driver_info = DEVTYPE_EGALAX}, |
121 | {USB_DEVICE(0x3823, 0x0002), .driver_info = DEVTYPE_EGALAX}, | 135 | {USB_DEVICE(0x3823, 0x0002), .driver_info = DEVTYPE_EGALAX}, |
122 | {USB_DEVICE(0x0123, 0x0001), .driver_info = DEVTYPE_EGALAX}, | 136 | {USB_DEVICE(0x0123, 0x0001), .driver_info = DEVTYPE_EGALAX}, |
@@ -262,7 +276,7 @@ static int mtouch_init(struct usbtouch_usb *usbtouch) | |||
262 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 276 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
263 | 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); | 277 | 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); |
264 | dbg("%s - usb_control_msg - MTOUCHUSB_RESET - bytes|err: %d", | 278 | dbg("%s - usb_control_msg - MTOUCHUSB_RESET - bytes|err: %d", |
265 | __FUNCTION__, ret); | 279 | __func__, ret); |
266 | if (ret < 0) | 280 | if (ret < 0) |
267 | return ret; | 281 | return ret; |
268 | msleep(150); | 282 | msleep(150); |
@@ -273,7 +287,7 @@ static int mtouch_init(struct usbtouch_usb *usbtouch) | |||
273 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 287 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
274 | 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT); | 288 | 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT); |
275 | dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d", | 289 | dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d", |
276 | __FUNCTION__, ret); | 290 | __func__, ret); |
277 | if (ret >= 0) | 291 | if (ret >= 0) |
278 | break; | 292 | break; |
279 | if (ret != -EPIPE) | 293 | if (ret != -EPIPE) |
@@ -793,18 +807,18 @@ static void usbtouch_irq(struct urb *urb) | |||
793 | case -ETIME: | 807 | case -ETIME: |
794 | /* this urb is timing out */ | 808 | /* this urb is timing out */ |
795 | dbg("%s - urb timed out - was the device unplugged?", | 809 | dbg("%s - urb timed out - was the device unplugged?", |
796 | __FUNCTION__); | 810 | __func__); |
797 | return; | 811 | return; |
798 | case -ECONNRESET: | 812 | case -ECONNRESET: |
799 | case -ENOENT: | 813 | case -ENOENT: |
800 | case -ESHUTDOWN: | 814 | case -ESHUTDOWN: |
801 | /* this urb is terminated, clean up */ | 815 | /* this urb is terminated, clean up */ |
802 | dbg("%s - urb shutting down with status: %d", | 816 | dbg("%s - urb shutting down with status: %d", |
803 | __FUNCTION__, urb->status); | 817 | __func__, urb->status); |
804 | return; | 818 | return; |
805 | default: | 819 | default: |
806 | dbg("%s - nonzero urb status received: %d", | 820 | dbg("%s - nonzero urb status received: %d", |
807 | __FUNCTION__, urb->status); | 821 | __func__, urb->status); |
808 | goto exit; | 822 | goto exit; |
809 | } | 823 | } |
810 | 824 | ||
@@ -814,7 +828,7 @@ exit: | |||
814 | retval = usb_submit_urb(urb, GFP_ATOMIC); | 828 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
815 | if (retval) | 829 | if (retval) |
816 | err("%s - usb_submit_urb failed with result: %d", | 830 | err("%s - usb_submit_urb failed with result: %d", |
817 | __FUNCTION__, retval); | 831 | __func__, retval); |
818 | } | 832 | } |
819 | 833 | ||
820 | static int usbtouch_open(struct input_dev *input) | 834 | static int usbtouch_open(struct input_dev *input) |
@@ -857,6 +871,10 @@ static int usbtouch_probe(struct usb_interface *intf, | |||
857 | struct usbtouch_device_info *type; | 871 | struct usbtouch_device_info *type; |
858 | int err = -ENOMEM; | 872 | int err = -ENOMEM; |
859 | 873 | ||
874 | /* some devices are ignored */ | ||
875 | if (id->driver_info == DEVTYPE_IGNORE) | ||
876 | return -ENODEV; | ||
877 | |||
860 | interface = intf->cur_altsetting; | 878 | interface = intf->cur_altsetting; |
861 | endpoint = &interface->endpoint[0].desc; | 879 | endpoint = &interface->endpoint[0].desc; |
862 | 880 | ||
@@ -883,7 +901,7 @@ static int usbtouch_probe(struct usb_interface *intf, | |||
883 | 901 | ||
884 | usbtouch->irq = usb_alloc_urb(0, GFP_KERNEL); | 902 | usbtouch->irq = usb_alloc_urb(0, GFP_KERNEL); |
885 | if (!usbtouch->irq) { | 903 | if (!usbtouch->irq) { |
886 | dbg("%s - usb_alloc_urb failed: usbtouch->irq", __FUNCTION__); | 904 | dbg("%s - usb_alloc_urb failed: usbtouch->irq", __func__); |
887 | goto out_free_buffers; | 905 | goto out_free_buffers; |
888 | } | 906 | } |
889 | 907 | ||
@@ -939,14 +957,14 @@ static int usbtouch_probe(struct usb_interface *intf, | |||
939 | if (type->init) { | 957 | if (type->init) { |
940 | err = type->init(usbtouch); | 958 | err = type->init(usbtouch); |
941 | if (err) { | 959 | if (err) { |
942 | dbg("%s - type->init() failed, err: %d", __FUNCTION__, err); | 960 | dbg("%s - type->init() failed, err: %d", __func__, err); |
943 | goto out_free_buffers; | 961 | goto out_free_buffers; |
944 | } | 962 | } |
945 | } | 963 | } |
946 | 964 | ||
947 | err = input_register_device(usbtouch->input); | 965 | err = input_register_device(usbtouch->input); |
948 | if (err) { | 966 | if (err) { |
949 | dbg("%s - input_register_device failed, err: %d", __FUNCTION__, err); | 967 | dbg("%s - input_register_device failed, err: %d", __func__, err); |
950 | goto out_free_buffers; | 968 | goto out_free_buffers; |
951 | } | 969 | } |
952 | 970 | ||
@@ -966,12 +984,12 @@ static void usbtouch_disconnect(struct usb_interface *intf) | |||
966 | { | 984 | { |
967 | struct usbtouch_usb *usbtouch = usb_get_intfdata(intf); | 985 | struct usbtouch_usb *usbtouch = usb_get_intfdata(intf); |
968 | 986 | ||
969 | dbg("%s - called", __FUNCTION__); | 987 | dbg("%s - called", __func__); |
970 | 988 | ||
971 | if (!usbtouch) | 989 | if (!usbtouch) |
972 | return; | 990 | return; |
973 | 991 | ||
974 | dbg("%s - usbtouch is initialized, cleaning up", __FUNCTION__); | 992 | dbg("%s - usbtouch is initialized, cleaning up", __func__); |
975 | usb_set_intfdata(intf, NULL); | 993 | usb_set_intfdata(intf, NULL); |
976 | usb_kill_urb(usbtouch->irq); | 994 | usb_kill_urb(usbtouch->irq); |
977 | input_unregister_device(usbtouch->input); | 995 | input_unregister_device(usbtouch->input); |
diff --git a/drivers/input/touchscreen/wm9712.c b/drivers/input/touchscreen/wm9712.c index 0b6e4cfa6a21..4c5d85a249ae 100644 --- a/drivers/input/touchscreen/wm9712.c +++ b/drivers/input/touchscreen/wm9712.c | |||
@@ -168,6 +168,18 @@ static void wm9712_phy_init(struct wm97xx *wm) | |||
168 | 64000 / rpu); | 168 | 64000 / rpu); |
169 | } | 169 | } |
170 | 170 | ||
171 | /* WM9712 five wire */ | ||
172 | if (five_wire) { | ||
173 | dig2 |= WM9712_45W; | ||
174 | dev_dbg(wm->dev, "setting 5-wire touchscreen mode."); | ||
175 | |||
176 | if (pil) { | ||
177 | dev_warn(wm->dev, "pressure measurement is not " | ||
178 | "supported in 5-wire mode\n"); | ||
179 | pil = 0; | ||
180 | } | ||
181 | } | ||
182 | |||
171 | /* touchpanel pressure current*/ | 183 | /* touchpanel pressure current*/ |
172 | if (pil == 2) { | 184 | if (pil == 2) { |
173 | dig2 |= WM9712_PIL; | 185 | dig2 |= WM9712_PIL; |
@@ -179,12 +191,6 @@ static void wm9712_phy_init(struct wm97xx *wm) | |||
179 | if (!pil) | 191 | if (!pil) |
180 | pressure = 0; | 192 | pressure = 0; |
181 | 193 | ||
182 | /* WM9712 five wire */ | ||
183 | if (five_wire) { | ||
184 | dig2 |= WM9712_45W; | ||
185 | dev_dbg(wm->dev, "setting 5-wire touchscreen mode."); | ||
186 | } | ||
187 | |||
188 | /* polling mode sample settling delay */ | 194 | /* polling mode sample settling delay */ |
189 | if (delay < 0 || delay > 15) { | 195 | if (delay < 0 || delay > 15) { |
190 | dev_dbg(wm->dev, "supplied delay out of range."); | 196 | dev_dbg(wm->dev, "supplied delay out of range."); |
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c index 59ea520a5d7a..5396c67ba0a4 100644 --- a/drivers/macintosh/adbhid.c +++ b/drivers/macintosh/adbhid.c | |||
@@ -219,11 +219,13 @@ struct adbhid { | |||
219 | int flags; | 219 | int flags; |
220 | }; | 220 | }; |
221 | 221 | ||
222 | #define FLAG_FN_KEY_PRESSED 0x00000001 | 222 | #define FLAG_FN_KEY_PRESSED 0x00000001 |
223 | #define FLAG_POWER_FROM_FN 0x00000002 | 223 | #define FLAG_POWER_FROM_FN 0x00000002 |
224 | #define FLAG_EMU_FWDEL_DOWN 0x00000004 | 224 | #define FLAG_EMU_FWDEL_DOWN 0x00000004 |
225 | #define FLAG_CAPSLOCK_TRANSLATE 0x00000008 | 225 | #define FLAG_CAPSLOCK_TRANSLATE 0x00000008 |
226 | #define FLAG_CAPSLOCK_DOWN 0x00000010 | 226 | #define FLAG_CAPSLOCK_DOWN 0x00000010 |
227 | #define FLAG_CAPSLOCK_IGNORE_NEXT 0x00000020 | ||
228 | #define FLAG_POWER_KEY_PRESSED 0x00000040 | ||
227 | 229 | ||
228 | static struct adbhid *adbhid[16]; | 230 | static struct adbhid *adbhid[16]; |
229 | 231 | ||
@@ -291,11 +293,20 @@ adbhid_input_keycode(int id, int scancode, int repeat) | |||
291 | if (keycode == ADB_KEY_CAPSLOCK && !up_flag) { | 293 | if (keycode == ADB_KEY_CAPSLOCK && !up_flag) { |
292 | /* Key pressed, turning on the CapsLock LED. | 294 | /* Key pressed, turning on the CapsLock LED. |
293 | * The next 0xff will be interpreted as a release. */ | 295 | * The next 0xff will be interpreted as a release. */ |
294 | ahid->flags |= FLAG_CAPSLOCK_TRANSLATE | 296 | if (ahid->flags & FLAG_CAPSLOCK_IGNORE_NEXT) { |
297 | /* Throw away this key event if it happens | ||
298 | * just after resume. */ | ||
299 | ahid->flags &= ~FLAG_CAPSLOCK_IGNORE_NEXT; | ||
300 | return; | ||
301 | } else { | ||
302 | ahid->flags |= FLAG_CAPSLOCK_TRANSLATE | ||
295 | | FLAG_CAPSLOCK_DOWN; | 303 | | FLAG_CAPSLOCK_DOWN; |
296 | } else if (scancode == 0xff) { | 304 | } |
305 | } else if (scancode == 0xff && | ||
306 | !(ahid->flags & FLAG_POWER_KEY_PRESSED)) { | ||
297 | /* Scancode 0xff usually signifies that the capslock | 307 | /* Scancode 0xff usually signifies that the capslock |
298 | * key was either pressed or released. */ | 308 | * key was either pressed or released, or that the |
309 | * power button was released. */ | ||
299 | if (ahid->flags & FLAG_CAPSLOCK_TRANSLATE) { | 310 | if (ahid->flags & FLAG_CAPSLOCK_TRANSLATE) { |
300 | keycode = ADB_KEY_CAPSLOCK; | 311 | keycode = ADB_KEY_CAPSLOCK; |
301 | if (ahid->flags & FLAG_CAPSLOCK_DOWN) { | 312 | if (ahid->flags & FLAG_CAPSLOCK_DOWN) { |
@@ -309,7 +320,7 @@ adbhid_input_keycode(int id, int scancode, int repeat) | |||
309 | } | 320 | } |
310 | } else { | 321 | } else { |
311 | printk(KERN_INFO "Spurious caps lock event " | 322 | printk(KERN_INFO "Spurious caps lock event " |
312 | "(scancode 0xff)."); | 323 | "(scancode 0xff).\n"); |
313 | } | 324 | } |
314 | } | 325 | } |
315 | } | 326 | } |
@@ -336,6 +347,12 @@ adbhid_input_keycode(int id, int scancode, int repeat) | |||
336 | } | 347 | } |
337 | break; | 348 | break; |
338 | case ADB_KEY_POWER: | 349 | case ADB_KEY_POWER: |
350 | /* Keep track of the power key state */ | ||
351 | if (up_flag) | ||
352 | ahid->flags &= ~FLAG_POWER_KEY_PRESSED; | ||
353 | else | ||
354 | ahid->flags |= FLAG_POWER_KEY_PRESSED; | ||
355 | |||
339 | /* Fn + Command will produce a bogus "power" keycode */ | 356 | /* Fn + Command will produce a bogus "power" keycode */ |
340 | if (ahid->flags & FLAG_FN_KEY_PRESSED) { | 357 | if (ahid->flags & FLAG_FN_KEY_PRESSED) { |
341 | keycode = ADB_KEY_CMD; | 358 | keycode = ADB_KEY_CMD; |
@@ -681,6 +698,21 @@ static int adbhid_kbd_event(struct input_dev *dev, unsigned int type, unsigned i | |||
681 | return -1; | 698 | return -1; |
682 | } | 699 | } |
683 | 700 | ||
701 | static void | ||
702 | adbhid_kbd_capslock_remember(void) | ||
703 | { | ||
704 | struct adbhid *ahid; | ||
705 | int i; | ||
706 | |||
707 | for (i = 1; i < 16; i++) { | ||
708 | ahid = adbhid[i]; | ||
709 | |||
710 | if (ahid && ahid->id == ADB_KEYBOARD) | ||
711 | if (ahid->flags & FLAG_CAPSLOCK_TRANSLATE) | ||
712 | ahid->flags |= FLAG_CAPSLOCK_IGNORE_NEXT; | ||
713 | } | ||
714 | } | ||
715 | |||
684 | static int | 716 | static int |
685 | adb_message_handler(struct notifier_block *this, unsigned long code, void *x) | 717 | adb_message_handler(struct notifier_block *this, unsigned long code, void *x) |
686 | { | 718 | { |
@@ -697,8 +729,17 @@ adb_message_handler(struct notifier_block *this, unsigned long code, void *x) | |||
697 | } | 729 | } |
698 | 730 | ||
699 | /* Stop pending led requests */ | 731 | /* Stop pending led requests */ |
700 | while(leds_req_pending) | 732 | while (leds_req_pending) |
701 | adb_poll(); | 733 | adb_poll(); |
734 | |||
735 | /* After resume, and if the capslock LED is on, the PMU will | ||
736 | * send a "capslock down" key event. This confuses the | ||
737 | * restore_capslock_events logic. Remember if the capslock | ||
738 | * LED was on before suspend so the unwanted key event can | ||
739 | * be ignored after resume. */ | ||
740 | if (restore_capslock_events) | ||
741 | adbhid_kbd_capslock_remember(); | ||
742 | |||
702 | break; | 743 | break; |
703 | 744 | ||
704 | case ADB_MSG_POST_RESET: | 745 | case ADB_MSG_POST_RESET: |
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index b26927ce889c..621a272a2c74 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -225,7 +225,7 @@ static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long inde | |||
225 | || test_bit(Faulty, &rdev->flags)) | 225 | || test_bit(Faulty, &rdev->flags)) |
226 | continue; | 226 | continue; |
227 | 227 | ||
228 | target = (rdev->sb_offset << 1) + offset + index * (PAGE_SIZE/512); | 228 | target = rdev->sb_start + offset + index * (PAGE_SIZE/512); |
229 | 229 | ||
230 | if (sync_page_io(rdev->bdev, target, PAGE_SIZE, page, READ)) { | 230 | if (sync_page_io(rdev->bdev, target, PAGE_SIZE, page, READ)) { |
231 | page->index = index; | 231 | page->index = index; |
@@ -241,10 +241,10 @@ static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long inde | |||
241 | static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait) | 241 | static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait) |
242 | { | 242 | { |
243 | mdk_rdev_t *rdev; | 243 | mdk_rdev_t *rdev; |
244 | struct list_head *tmp; | ||
245 | mddev_t *mddev = bitmap->mddev; | 244 | mddev_t *mddev = bitmap->mddev; |
246 | 245 | ||
247 | rdev_for_each(rdev, tmp, mddev) | 246 | rcu_read_lock(); |
247 | rdev_for_each_rcu(rdev, mddev) | ||
248 | if (test_bit(In_sync, &rdev->flags) | 248 | if (test_bit(In_sync, &rdev->flags) |
249 | && !test_bit(Faulty, &rdev->flags)) { | 249 | && !test_bit(Faulty, &rdev->flags)) { |
250 | int size = PAGE_SIZE; | 250 | int size = PAGE_SIZE; |
@@ -260,32 +260,37 @@ static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait) | |||
260 | + (long)(page->index * (PAGE_SIZE/512)) | 260 | + (long)(page->index * (PAGE_SIZE/512)) |
261 | + size/512 > 0) | 261 | + size/512 > 0) |
262 | /* bitmap runs in to metadata */ | 262 | /* bitmap runs in to metadata */ |
263 | return -EINVAL; | 263 | goto bad_alignment; |
264 | if (rdev->data_offset + mddev->size*2 | 264 | if (rdev->data_offset + mddev->size*2 |
265 | > rdev->sb_offset*2 + bitmap->offset) | 265 | > rdev->sb_start + bitmap->offset) |
266 | /* data runs in to bitmap */ | 266 | /* data runs in to bitmap */ |
267 | return -EINVAL; | 267 | goto bad_alignment; |
268 | } else if (rdev->sb_offset*2 < rdev->data_offset) { | 268 | } else if (rdev->sb_start < rdev->data_offset) { |
269 | /* METADATA BITMAP DATA */ | 269 | /* METADATA BITMAP DATA */ |
270 | if (rdev->sb_offset*2 | 270 | if (rdev->sb_start |
271 | + bitmap->offset | 271 | + bitmap->offset |
272 | + page->index*(PAGE_SIZE/512) + size/512 | 272 | + page->index*(PAGE_SIZE/512) + size/512 |
273 | > rdev->data_offset) | 273 | > rdev->data_offset) |
274 | /* bitmap runs in to data */ | 274 | /* bitmap runs in to data */ |
275 | return -EINVAL; | 275 | goto bad_alignment; |
276 | } else { | 276 | } else { |
277 | /* DATA METADATA BITMAP - no problems */ | 277 | /* DATA METADATA BITMAP - no problems */ |
278 | } | 278 | } |
279 | md_super_write(mddev, rdev, | 279 | md_super_write(mddev, rdev, |
280 | (rdev->sb_offset<<1) + bitmap->offset | 280 | rdev->sb_start + bitmap->offset |
281 | + page->index * (PAGE_SIZE/512), | 281 | + page->index * (PAGE_SIZE/512), |
282 | size, | 282 | size, |
283 | page); | 283 | page); |
284 | } | 284 | } |
285 | rcu_read_unlock(); | ||
285 | 286 | ||
286 | if (wait) | 287 | if (wait) |
287 | md_super_wait(mddev); | 288 | md_super_wait(mddev); |
288 | return 0; | 289 | return 0; |
290 | |||
291 | bad_alignment: | ||
292 | rcu_read_unlock(); | ||
293 | return -EINVAL; | ||
289 | } | 294 | } |
290 | 295 | ||
291 | static void bitmap_file_kick(struct bitmap *bitmap); | 296 | static void bitmap_file_kick(struct bitmap *bitmap); |
@@ -454,8 +459,11 @@ void bitmap_update_sb(struct bitmap *bitmap) | |||
454 | spin_unlock_irqrestore(&bitmap->lock, flags); | 459 | spin_unlock_irqrestore(&bitmap->lock, flags); |
455 | sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0); | 460 | sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0); |
456 | sb->events = cpu_to_le64(bitmap->mddev->events); | 461 | sb->events = cpu_to_le64(bitmap->mddev->events); |
457 | if (!bitmap->mddev->degraded) | 462 | if (bitmap->mddev->events < bitmap->events_cleared) { |
458 | sb->events_cleared = cpu_to_le64(bitmap->mddev->events); | 463 | /* rocking back to read-only */ |
464 | bitmap->events_cleared = bitmap->mddev->events; | ||
465 | sb->events_cleared = cpu_to_le64(bitmap->events_cleared); | ||
466 | } | ||
459 | kunmap_atomic(sb, KM_USER0); | 467 | kunmap_atomic(sb, KM_USER0); |
460 | write_page(bitmap, bitmap->sb_page, 1); | 468 | write_page(bitmap, bitmap->sb_page, 1); |
461 | } | 469 | } |
@@ -1085,9 +1093,19 @@ void bitmap_daemon_work(struct bitmap *bitmap) | |||
1085 | } else | 1093 | } else |
1086 | spin_unlock_irqrestore(&bitmap->lock, flags); | 1094 | spin_unlock_irqrestore(&bitmap->lock, flags); |
1087 | lastpage = page; | 1095 | lastpage = page; |
1088 | /* | 1096 | |
1089 | printk("bitmap clean at page %lu\n", j); | 1097 | /* We are possibly going to clear some bits, so make |
1090 | */ | 1098 | * sure that events_cleared is up-to-date. |
1099 | */ | ||
1100 | if (bitmap->need_sync) { | ||
1101 | bitmap_super_t *sb; | ||
1102 | bitmap->need_sync = 0; | ||
1103 | sb = kmap_atomic(bitmap->sb_page, KM_USER0); | ||
1104 | sb->events_cleared = | ||
1105 | cpu_to_le64(bitmap->events_cleared); | ||
1106 | kunmap_atomic(sb, KM_USER0); | ||
1107 | write_page(bitmap, bitmap->sb_page, 1); | ||
1108 | } | ||
1091 | spin_lock_irqsave(&bitmap->lock, flags); | 1109 | spin_lock_irqsave(&bitmap->lock, flags); |
1092 | clear_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); | 1110 | clear_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); |
1093 | } | 1111 | } |
@@ -1257,6 +1275,12 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto | |||
1257 | return; | 1275 | return; |
1258 | } | 1276 | } |
1259 | 1277 | ||
1278 | if (success && | ||
1279 | bitmap->events_cleared < bitmap->mddev->events) { | ||
1280 | bitmap->events_cleared = bitmap->mddev->events; | ||
1281 | bitmap->need_sync = 1; | ||
1282 | } | ||
1283 | |||
1260 | if (!success && ! (*bmc & NEEDED_MASK)) | 1284 | if (!success && ! (*bmc & NEEDED_MASK)) |
1261 | *bmc |= NEEDED_MASK; | 1285 | *bmc |= NEEDED_MASK; |
1262 | 1286 | ||
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index ab6a61db63ce..13956437bc81 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c | |||
@@ -1216,9 +1216,24 @@ error: | |||
1216 | return -EINVAL; | 1216 | return -EINVAL; |
1217 | } | 1217 | } |
1218 | 1218 | ||
1219 | static int crypt_merge(struct dm_target *ti, struct bvec_merge_data *bvm, | ||
1220 | struct bio_vec *biovec, int max_size) | ||
1221 | { | ||
1222 | struct crypt_config *cc = ti->private; | ||
1223 | struct request_queue *q = bdev_get_queue(cc->dev->bdev); | ||
1224 | |||
1225 | if (!q->merge_bvec_fn) | ||
1226 | return max_size; | ||
1227 | |||
1228 | bvm->bi_bdev = cc->dev->bdev; | ||
1229 | bvm->bi_sector = cc->start + bvm->bi_sector - ti->begin; | ||
1230 | |||
1231 | return min(max_size, q->merge_bvec_fn(q, bvm, biovec)); | ||
1232 | } | ||
1233 | |||
1219 | static struct target_type crypt_target = { | 1234 | static struct target_type crypt_target = { |
1220 | .name = "crypt", | 1235 | .name = "crypt", |
1221 | .version= {1, 5, 0}, | 1236 | .version= {1, 6, 0}, |
1222 | .module = THIS_MODULE, | 1237 | .module = THIS_MODULE, |
1223 | .ctr = crypt_ctr, | 1238 | .ctr = crypt_ctr, |
1224 | .dtr = crypt_dtr, | 1239 | .dtr = crypt_dtr, |
@@ -1228,6 +1243,7 @@ static struct target_type crypt_target = { | |||
1228 | .preresume = crypt_preresume, | 1243 | .preresume = crypt_preresume, |
1229 | .resume = crypt_resume, | 1244 | .resume = crypt_resume, |
1230 | .message = crypt_message, | 1245 | .message = crypt_message, |
1246 | .merge = crypt_merge, | ||
1231 | }; | 1247 | }; |
1232 | 1248 | ||
1233 | static int __init dm_crypt_init(void) | 1249 | static int __init dm_crypt_init(void) |
diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c index 17753d80ad22..6449bcdf84ca 100644 --- a/drivers/md/dm-linear.c +++ b/drivers/md/dm-linear.c | |||
@@ -69,13 +69,25 @@ static void linear_dtr(struct dm_target *ti) | |||
69 | kfree(lc); | 69 | kfree(lc); |
70 | } | 70 | } |
71 | 71 | ||
72 | static int linear_map(struct dm_target *ti, struct bio *bio, | 72 | static sector_t linear_map_sector(struct dm_target *ti, sector_t bi_sector) |
73 | union map_info *map_context) | ||
74 | { | 73 | { |
75 | struct linear_c *lc = (struct linear_c *) ti->private; | 74 | struct linear_c *lc = ti->private; |
75 | |||
76 | return lc->start + (bi_sector - ti->begin); | ||
77 | } | ||
78 | |||
79 | static void linear_map_bio(struct dm_target *ti, struct bio *bio) | ||
80 | { | ||
81 | struct linear_c *lc = ti->private; | ||
76 | 82 | ||
77 | bio->bi_bdev = lc->dev->bdev; | 83 | bio->bi_bdev = lc->dev->bdev; |
78 | bio->bi_sector = lc->start + (bio->bi_sector - ti->begin); | 84 | bio->bi_sector = linear_map_sector(ti, bio->bi_sector); |
85 | } | ||
86 | |||
87 | static int linear_map(struct dm_target *ti, struct bio *bio, | ||
88 | union map_info *map_context) | ||
89 | { | ||
90 | linear_map_bio(ti, bio); | ||
79 | 91 | ||
80 | return DM_MAPIO_REMAPPED; | 92 | return DM_MAPIO_REMAPPED; |
81 | } | 93 | } |
@@ -114,15 +126,31 @@ static int linear_ioctl(struct dm_target *ti, struct inode *inode, | |||
114 | return blkdev_driver_ioctl(bdev->bd_inode, &fake_file, bdev->bd_disk, cmd, arg); | 126 | return blkdev_driver_ioctl(bdev->bd_inode, &fake_file, bdev->bd_disk, cmd, arg); |
115 | } | 127 | } |
116 | 128 | ||
129 | static int linear_merge(struct dm_target *ti, struct bvec_merge_data *bvm, | ||
130 | struct bio_vec *biovec, int max_size) | ||
131 | { | ||
132 | struct linear_c *lc = ti->private; | ||
133 | struct request_queue *q = bdev_get_queue(lc->dev->bdev); | ||
134 | |||
135 | if (!q->merge_bvec_fn) | ||
136 | return max_size; | ||
137 | |||
138 | bvm->bi_bdev = lc->dev->bdev; | ||
139 | bvm->bi_sector = linear_map_sector(ti, bvm->bi_sector); | ||
140 | |||
141 | return min(max_size, q->merge_bvec_fn(q, bvm, biovec)); | ||
142 | } | ||
143 | |||
117 | static struct target_type linear_target = { | 144 | static struct target_type linear_target = { |
118 | .name = "linear", | 145 | .name = "linear", |
119 | .version= {1, 0, 2}, | 146 | .version= {1, 0, 3}, |
120 | .module = THIS_MODULE, | 147 | .module = THIS_MODULE, |
121 | .ctr = linear_ctr, | 148 | .ctr = linear_ctr, |
122 | .dtr = linear_dtr, | 149 | .dtr = linear_dtr, |
123 | .map = linear_map, | 150 | .map = linear_map, |
124 | .status = linear_status, | 151 | .status = linear_status, |
125 | .ioctl = linear_ioctl, | 152 | .ioctl = linear_ioctl, |
153 | .merge = linear_merge, | ||
126 | }; | 154 | }; |
127 | 155 | ||
128 | int __init dm_linear_init(void) | 156 | int __init dm_linear_init(void) |
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index 67a6f31b7fc3..5b48478c79f5 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c | |||
@@ -831,7 +831,7 @@ static struct dm_dirty_log_type _disk_type = { | |||
831 | .status = disk_status, | 831 | .status = disk_status, |
832 | }; | 832 | }; |
833 | 833 | ||
834 | int __init dm_dirty_log_init(void) | 834 | static int __init dm_dirty_log_init(void) |
835 | { | 835 | { |
836 | int r; | 836 | int r; |
837 | 837 | ||
@@ -848,7 +848,7 @@ int __init dm_dirty_log_init(void) | |||
848 | return r; | 848 | return r; |
849 | } | 849 | } |
850 | 850 | ||
851 | void __exit dm_dirty_log_exit(void) | 851 | static void __exit dm_dirty_log_exit(void) |
852 | { | 852 | { |
853 | dm_dirty_log_type_unregister(&_disk_type); | 853 | dm_dirty_log_type_unregister(&_disk_type); |
854 | dm_dirty_log_type_unregister(&_core_type); | 854 | dm_dirty_log_type_unregister(&_core_type); |
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 9f7302d4878d..fea966d66f98 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
@@ -525,8 +525,10 @@ static int parse_path_selector(struct arg_set *as, struct priority_group *pg, | |||
525 | } | 525 | } |
526 | 526 | ||
527 | r = read_param(_params, shift(as), &ps_argc, &ti->error); | 527 | r = read_param(_params, shift(as), &ps_argc, &ti->error); |
528 | if (r) | 528 | if (r) { |
529 | dm_put_path_selector(pst); | ||
529 | return -EINVAL; | 530 | return -EINVAL; |
531 | } | ||
530 | 532 | ||
531 | r = pst->create(&pg->ps, ps_argc, as->argv); | 533 | r = pst->create(&pg->ps, ps_argc, as->argv); |
532 | if (r) { | 534 | if (r) { |
@@ -623,8 +625,10 @@ static struct priority_group *parse_priority_group(struct arg_set *as, | |||
623 | struct pgpath *pgpath; | 625 | struct pgpath *pgpath; |
624 | struct arg_set path_args; | 626 | struct arg_set path_args; |
625 | 627 | ||
626 | if (as->argc < nr_params) | 628 | if (as->argc < nr_params) { |
629 | ti->error = "not enough path parameters"; | ||
627 | goto bad; | 630 | goto bad; |
631 | } | ||
628 | 632 | ||
629 | path_args.argc = nr_params; | 633 | path_args.argc = nr_params; |
630 | path_args.argv = as->argv; | 634 | path_args.argv = as->argv; |
@@ -867,7 +871,7 @@ static int reinstate_path(struct pgpath *pgpath) | |||
867 | if (pgpath->path.is_active) | 871 | if (pgpath->path.is_active) |
868 | goto out; | 872 | goto out; |
869 | 873 | ||
870 | if (!pgpath->pg->ps.type) { | 874 | if (!pgpath->pg->ps.type->reinstate_path) { |
871 | DMWARN("Reinstate path not supported by path selector %s", | 875 | DMWARN("Reinstate path not supported by path selector %s", |
872 | pgpath->pg->ps.type->name); | 876 | pgpath->pg->ps.type->name); |
873 | r = -EINVAL; | 877 | r = -EINVAL; |
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 1ba8a47d61b1..6e5528aecc98 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c | |||
@@ -40,6 +40,11 @@ | |||
40 | */ | 40 | */ |
41 | #define SNAPSHOT_PAGES (((1UL << 20) >> PAGE_SHIFT) ? : 1) | 41 | #define SNAPSHOT_PAGES (((1UL << 20) >> PAGE_SHIFT) ? : 1) |
42 | 42 | ||
43 | /* | ||
44 | * The size of the mempool used to track chunks in use. | ||
45 | */ | ||
46 | #define MIN_IOS 256 | ||
47 | |||
43 | static struct workqueue_struct *ksnapd; | 48 | static struct workqueue_struct *ksnapd; |
44 | static void flush_queued_bios(struct work_struct *work); | 49 | static void flush_queued_bios(struct work_struct *work); |
45 | 50 | ||
@@ -91,7 +96,63 @@ struct dm_snap_pending_exception { | |||
91 | */ | 96 | */ |
92 | static struct kmem_cache *exception_cache; | 97 | static struct kmem_cache *exception_cache; |
93 | static struct kmem_cache *pending_cache; | 98 | static struct kmem_cache *pending_cache; |
94 | static mempool_t *pending_pool; | 99 | |
100 | struct dm_snap_tracked_chunk { | ||
101 | struct hlist_node node; | ||
102 | chunk_t chunk; | ||
103 | }; | ||
104 | |||
105 | static struct kmem_cache *tracked_chunk_cache; | ||
106 | |||
107 | static struct dm_snap_tracked_chunk *track_chunk(struct dm_snapshot *s, | ||
108 | chunk_t chunk) | ||
109 | { | ||
110 | struct dm_snap_tracked_chunk *c = mempool_alloc(s->tracked_chunk_pool, | ||
111 | GFP_NOIO); | ||
112 | unsigned long flags; | ||
113 | |||
114 | c->chunk = chunk; | ||
115 | |||
116 | spin_lock_irqsave(&s->tracked_chunk_lock, flags); | ||
117 | hlist_add_head(&c->node, | ||
118 | &s->tracked_chunk_hash[DM_TRACKED_CHUNK_HASH(chunk)]); | ||
119 | spin_unlock_irqrestore(&s->tracked_chunk_lock, flags); | ||
120 | |||
121 | return c; | ||
122 | } | ||
123 | |||
124 | static void stop_tracking_chunk(struct dm_snapshot *s, | ||
125 | struct dm_snap_tracked_chunk *c) | ||
126 | { | ||
127 | unsigned long flags; | ||
128 | |||
129 | spin_lock_irqsave(&s->tracked_chunk_lock, flags); | ||
130 | hlist_del(&c->node); | ||
131 | spin_unlock_irqrestore(&s->tracked_chunk_lock, flags); | ||
132 | |||
133 | mempool_free(c, s->tracked_chunk_pool); | ||
134 | } | ||
135 | |||
136 | static int __chunk_is_tracked(struct dm_snapshot *s, chunk_t chunk) | ||
137 | { | ||
138 | struct dm_snap_tracked_chunk *c; | ||
139 | struct hlist_node *hn; | ||
140 | int found = 0; | ||
141 | |||
142 | spin_lock_irq(&s->tracked_chunk_lock); | ||
143 | |||
144 | hlist_for_each_entry(c, hn, | ||
145 | &s->tracked_chunk_hash[DM_TRACKED_CHUNK_HASH(chunk)], node) { | ||
146 | if (c->chunk == chunk) { | ||
147 | found = 1; | ||
148 | break; | ||
149 | } | ||
150 | } | ||
151 | |||
152 | spin_unlock_irq(&s->tracked_chunk_lock); | ||
153 | |||
154 | return found; | ||
155 | } | ||
95 | 156 | ||
96 | /* | 157 | /* |
97 | * One of these per registered origin, held in the snapshot_origins hash | 158 | * One of these per registered origin, held in the snapshot_origins hash |
@@ -302,14 +363,19 @@ static void free_exception(struct dm_snap_exception *e) | |||
302 | kmem_cache_free(exception_cache, e); | 363 | kmem_cache_free(exception_cache, e); |
303 | } | 364 | } |
304 | 365 | ||
305 | static struct dm_snap_pending_exception *alloc_pending_exception(void) | 366 | static struct dm_snap_pending_exception *alloc_pending_exception(struct dm_snapshot *s) |
306 | { | 367 | { |
307 | return mempool_alloc(pending_pool, GFP_NOIO); | 368 | struct dm_snap_pending_exception *pe = mempool_alloc(s->pending_pool, |
369 | GFP_NOIO); | ||
370 | |||
371 | pe->snap = s; | ||
372 | |||
373 | return pe; | ||
308 | } | 374 | } |
309 | 375 | ||
310 | static void free_pending_exception(struct dm_snap_pending_exception *pe) | 376 | static void free_pending_exception(struct dm_snap_pending_exception *pe) |
311 | { | 377 | { |
312 | mempool_free(pe, pending_pool); | 378 | mempool_free(pe, pe->snap->pending_pool); |
313 | } | 379 | } |
314 | 380 | ||
315 | static void insert_completed_exception(struct dm_snapshot *s, | 381 | static void insert_completed_exception(struct dm_snapshot *s, |
@@ -482,6 +548,7 @@ static int set_chunk_size(struct dm_snapshot *s, const char *chunk_size_arg, | |||
482 | static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | 548 | static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) |
483 | { | 549 | { |
484 | struct dm_snapshot *s; | 550 | struct dm_snapshot *s; |
551 | int i; | ||
485 | int r = -EINVAL; | 552 | int r = -EINVAL; |
486 | char persistent; | 553 | char persistent; |
487 | char *origin_path; | 554 | char *origin_path; |
@@ -564,11 +631,30 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
564 | goto bad5; | 631 | goto bad5; |
565 | } | 632 | } |
566 | 633 | ||
634 | s->pending_pool = mempool_create_slab_pool(MIN_IOS, pending_cache); | ||
635 | if (!s->pending_pool) { | ||
636 | ti->error = "Could not allocate mempool for pending exceptions"; | ||
637 | goto bad6; | ||
638 | } | ||
639 | |||
640 | s->tracked_chunk_pool = mempool_create_slab_pool(MIN_IOS, | ||
641 | tracked_chunk_cache); | ||
642 | if (!s->tracked_chunk_pool) { | ||
643 | ti->error = "Could not allocate tracked_chunk mempool for " | ||
644 | "tracking reads"; | ||
645 | goto bad_tracked_chunk_pool; | ||
646 | } | ||
647 | |||
648 | for (i = 0; i < DM_TRACKED_CHUNK_HASH_SIZE; i++) | ||
649 | INIT_HLIST_HEAD(&s->tracked_chunk_hash[i]); | ||
650 | |||
651 | spin_lock_init(&s->tracked_chunk_lock); | ||
652 | |||
567 | /* Metadata must only be loaded into one table at once */ | 653 | /* Metadata must only be loaded into one table at once */ |
568 | r = s->store.read_metadata(&s->store); | 654 | r = s->store.read_metadata(&s->store); |
569 | if (r < 0) { | 655 | if (r < 0) { |
570 | ti->error = "Failed to read snapshot metadata"; | 656 | ti->error = "Failed to read snapshot metadata"; |
571 | goto bad6; | 657 | goto bad_load_and_register; |
572 | } else if (r > 0) { | 658 | } else if (r > 0) { |
573 | s->valid = 0; | 659 | s->valid = 0; |
574 | DMWARN("Snapshot is marked invalid."); | 660 | DMWARN("Snapshot is marked invalid."); |
@@ -582,7 +668,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
582 | if (register_snapshot(s)) { | 668 | if (register_snapshot(s)) { |
583 | r = -EINVAL; | 669 | r = -EINVAL; |
584 | ti->error = "Cannot register snapshot origin"; | 670 | ti->error = "Cannot register snapshot origin"; |
585 | goto bad6; | 671 | goto bad_load_and_register; |
586 | } | 672 | } |
587 | 673 | ||
588 | ti->private = s; | 674 | ti->private = s; |
@@ -590,6 +676,12 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
590 | 676 | ||
591 | return 0; | 677 | return 0; |
592 | 678 | ||
679 | bad_load_and_register: | ||
680 | mempool_destroy(s->tracked_chunk_pool); | ||
681 | |||
682 | bad_tracked_chunk_pool: | ||
683 | mempool_destroy(s->pending_pool); | ||
684 | |||
593 | bad6: | 685 | bad6: |
594 | dm_kcopyd_client_destroy(s->kcopyd_client); | 686 | dm_kcopyd_client_destroy(s->kcopyd_client); |
595 | 687 | ||
@@ -624,6 +716,9 @@ static void __free_exceptions(struct dm_snapshot *s) | |||
624 | 716 | ||
625 | static void snapshot_dtr(struct dm_target *ti) | 717 | static void snapshot_dtr(struct dm_target *ti) |
626 | { | 718 | { |
719 | #ifdef CONFIG_DM_DEBUG | ||
720 | int i; | ||
721 | #endif | ||
627 | struct dm_snapshot *s = ti->private; | 722 | struct dm_snapshot *s = ti->private; |
628 | 723 | ||
629 | flush_workqueue(ksnapd); | 724 | flush_workqueue(ksnapd); |
@@ -632,8 +727,17 @@ static void snapshot_dtr(struct dm_target *ti) | |||
632 | /* After this returns there can be no new kcopyd jobs. */ | 727 | /* After this returns there can be no new kcopyd jobs. */ |
633 | unregister_snapshot(s); | 728 | unregister_snapshot(s); |
634 | 729 | ||
730 | #ifdef CONFIG_DM_DEBUG | ||
731 | for (i = 0; i < DM_TRACKED_CHUNK_HASH_SIZE; i++) | ||
732 | BUG_ON(!hlist_empty(&s->tracked_chunk_hash[i])); | ||
733 | #endif | ||
734 | |||
735 | mempool_destroy(s->tracked_chunk_pool); | ||
736 | |||
635 | __free_exceptions(s); | 737 | __free_exceptions(s); |
636 | 738 | ||
739 | mempool_destroy(s->pending_pool); | ||
740 | |||
637 | dm_put_device(ti, s->origin); | 741 | dm_put_device(ti, s->origin); |
638 | dm_put_device(ti, s->cow); | 742 | dm_put_device(ti, s->cow); |
639 | 743 | ||
@@ -772,6 +876,13 @@ static void pending_complete(struct dm_snap_pending_exception *pe, int success) | |||
772 | } | 876 | } |
773 | 877 | ||
774 | /* | 878 | /* |
879 | * Check for conflicting reads. This is extremely improbable, | ||
880 | * so yield() is sufficient and there is no need for a wait queue. | ||
881 | */ | ||
882 | while (__chunk_is_tracked(s, pe->e.old_chunk)) | ||
883 | yield(); | ||
884 | |||
885 | /* | ||
775 | * Add a proper exception, and remove the | 886 | * Add a proper exception, and remove the |
776 | * in-flight exception from the list. | 887 | * in-flight exception from the list. |
777 | */ | 888 | */ |
@@ -873,7 +984,7 @@ __find_pending_exception(struct dm_snapshot *s, struct bio *bio) | |||
873 | * to hold the lock while we do this. | 984 | * to hold the lock while we do this. |
874 | */ | 985 | */ |
875 | up_write(&s->lock); | 986 | up_write(&s->lock); |
876 | pe = alloc_pending_exception(); | 987 | pe = alloc_pending_exception(s); |
877 | down_write(&s->lock); | 988 | down_write(&s->lock); |
878 | 989 | ||
879 | if (!s->valid) { | 990 | if (!s->valid) { |
@@ -893,7 +1004,6 @@ __find_pending_exception(struct dm_snapshot *s, struct bio *bio) | |||
893 | bio_list_init(&pe->snapshot_bios); | 1004 | bio_list_init(&pe->snapshot_bios); |
894 | pe->primary_pe = NULL; | 1005 | pe->primary_pe = NULL; |
895 | atomic_set(&pe->ref_count, 0); | 1006 | atomic_set(&pe->ref_count, 0); |
896 | pe->snap = s; | ||
897 | pe->started = 0; | 1007 | pe->started = 0; |
898 | 1008 | ||
899 | if (s->store.prepare_exception(&s->store, &pe->e)) { | 1009 | if (s->store.prepare_exception(&s->store, &pe->e)) { |
@@ -974,14 +1084,10 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio, | |||
974 | start_copy(pe); | 1084 | start_copy(pe); |
975 | goto out; | 1085 | goto out; |
976 | } | 1086 | } |
977 | } else | 1087 | } else { |
978 | /* | ||
979 | * FIXME: this read path scares me because we | ||
980 | * always use the origin when we have a pending | ||
981 | * exception. However I can't think of a | ||
982 | * situation where this is wrong - ejt. | ||
983 | */ | ||
984 | bio->bi_bdev = s->origin->bdev; | 1088 | bio->bi_bdev = s->origin->bdev; |
1089 | map_context->ptr = track_chunk(s, chunk); | ||
1090 | } | ||
985 | 1091 | ||
986 | out_unlock: | 1092 | out_unlock: |
987 | up_write(&s->lock); | 1093 | up_write(&s->lock); |
@@ -989,6 +1095,18 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio, | |||
989 | return r; | 1095 | return r; |
990 | } | 1096 | } |
991 | 1097 | ||
1098 | static int snapshot_end_io(struct dm_target *ti, struct bio *bio, | ||
1099 | int error, union map_info *map_context) | ||
1100 | { | ||
1101 | struct dm_snapshot *s = ti->private; | ||
1102 | struct dm_snap_tracked_chunk *c = map_context->ptr; | ||
1103 | |||
1104 | if (c) | ||
1105 | stop_tracking_chunk(s, c); | ||
1106 | |||
1107 | return 0; | ||
1108 | } | ||
1109 | |||
992 | static void snapshot_resume(struct dm_target *ti) | 1110 | static void snapshot_resume(struct dm_target *ti) |
993 | { | 1111 | { |
994 | struct dm_snapshot *s = ti->private; | 1112 | struct dm_snapshot *s = ti->private; |
@@ -1266,6 +1384,7 @@ static struct target_type snapshot_target = { | |||
1266 | .ctr = snapshot_ctr, | 1384 | .ctr = snapshot_ctr, |
1267 | .dtr = snapshot_dtr, | 1385 | .dtr = snapshot_dtr, |
1268 | .map = snapshot_map, | 1386 | .map = snapshot_map, |
1387 | .end_io = snapshot_end_io, | ||
1269 | .resume = snapshot_resume, | 1388 | .resume = snapshot_resume, |
1270 | .status = snapshot_status, | 1389 | .status = snapshot_status, |
1271 | }; | 1390 | }; |
@@ -1306,9 +1425,9 @@ static int __init dm_snapshot_init(void) | |||
1306 | goto bad4; | 1425 | goto bad4; |
1307 | } | 1426 | } |
1308 | 1427 | ||
1309 | pending_pool = mempool_create_slab_pool(128, pending_cache); | 1428 | tracked_chunk_cache = KMEM_CACHE(dm_snap_tracked_chunk, 0); |
1310 | if (!pending_pool) { | 1429 | if (!tracked_chunk_cache) { |
1311 | DMERR("Couldn't create pending pool."); | 1430 | DMERR("Couldn't create cache to track chunks in use."); |
1312 | r = -ENOMEM; | 1431 | r = -ENOMEM; |
1313 | goto bad5; | 1432 | goto bad5; |
1314 | } | 1433 | } |
@@ -1317,13 +1436,13 @@ static int __init dm_snapshot_init(void) | |||
1317 | if (!ksnapd) { | 1436 | if (!ksnapd) { |
1318 | DMERR("Failed to create ksnapd workqueue."); | 1437 | DMERR("Failed to create ksnapd workqueue."); |
1319 | r = -ENOMEM; | 1438 | r = -ENOMEM; |
1320 | goto bad6; | 1439 | goto bad_pending_pool; |
1321 | } | 1440 | } |
1322 | 1441 | ||
1323 | return 0; | 1442 | return 0; |
1324 | 1443 | ||
1325 | bad6: | 1444 | bad_pending_pool: |
1326 | mempool_destroy(pending_pool); | 1445 | kmem_cache_destroy(tracked_chunk_cache); |
1327 | bad5: | 1446 | bad5: |
1328 | kmem_cache_destroy(pending_cache); | 1447 | kmem_cache_destroy(pending_cache); |
1329 | bad4: | 1448 | bad4: |
@@ -1352,9 +1471,9 @@ static void __exit dm_snapshot_exit(void) | |||
1352 | DMERR("origin unregister failed %d", r); | 1471 | DMERR("origin unregister failed %d", r); |
1353 | 1472 | ||
1354 | exit_origin_hash(); | 1473 | exit_origin_hash(); |
1355 | mempool_destroy(pending_pool); | ||
1356 | kmem_cache_destroy(pending_cache); | 1474 | kmem_cache_destroy(pending_cache); |
1357 | kmem_cache_destroy(exception_cache); | 1475 | kmem_cache_destroy(exception_cache); |
1476 | kmem_cache_destroy(tracked_chunk_cache); | ||
1358 | } | 1477 | } |
1359 | 1478 | ||
1360 | /* Module hooks */ | 1479 | /* Module hooks */ |
diff --git a/drivers/md/dm-snap.h b/drivers/md/dm-snap.h index 24f9fb73b982..292c15609ae3 100644 --- a/drivers/md/dm-snap.h +++ b/drivers/md/dm-snap.h | |||
@@ -130,6 +130,10 @@ struct exception_store { | |||
130 | void *context; | 130 | void *context; |
131 | }; | 131 | }; |
132 | 132 | ||
133 | #define DM_TRACKED_CHUNK_HASH_SIZE 16 | ||
134 | #define DM_TRACKED_CHUNK_HASH(x) ((unsigned long)(x) & \ | ||
135 | (DM_TRACKED_CHUNK_HASH_SIZE - 1)) | ||
136 | |||
133 | struct dm_snapshot { | 137 | struct dm_snapshot { |
134 | struct rw_semaphore lock; | 138 | struct rw_semaphore lock; |
135 | struct dm_target *ti; | 139 | struct dm_target *ti; |
@@ -157,6 +161,8 @@ struct dm_snapshot { | |||
157 | /* The last percentage we notified */ | 161 | /* The last percentage we notified */ |
158 | int last_percent; | 162 | int last_percent; |
159 | 163 | ||
164 | mempool_t *pending_pool; | ||
165 | |||
160 | struct exception_table pending; | 166 | struct exception_table pending; |
161 | struct exception_table complete; | 167 | struct exception_table complete; |
162 | 168 | ||
@@ -174,6 +180,11 @@ struct dm_snapshot { | |||
174 | /* Queue of snapshot writes for ksnapd to flush */ | 180 | /* Queue of snapshot writes for ksnapd to flush */ |
175 | struct bio_list queued_bios; | 181 | struct bio_list queued_bios; |
176 | struct work_struct queued_bios_work; | 182 | struct work_struct queued_bios_work; |
183 | |||
184 | /* Chunks with outstanding reads */ | ||
185 | mempool_t *tracked_chunk_pool; | ||
186 | spinlock_t tracked_chunk_lock; | ||
187 | struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE]; | ||
177 | }; | 188 | }; |
178 | 189 | ||
179 | /* | 190 | /* |
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 94116eaf4709..798e468103b8 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
@@ -506,14 +506,13 @@ void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev) | |||
506 | rs->max_sectors = | 506 | rs->max_sectors = |
507 | min_not_zero(rs->max_sectors, q->max_sectors); | 507 | min_not_zero(rs->max_sectors, q->max_sectors); |
508 | 508 | ||
509 | /* FIXME: Device-Mapper on top of RAID-0 breaks because DM | 509 | /* |
510 | * currently doesn't honor MD's merge_bvec_fn routine. | 510 | * Check if merge fn is supported. |
511 | * In this case, we'll force DM to use PAGE_SIZE or | 511 | * If not we'll force DM to use PAGE_SIZE or |
512 | * smaller I/O, just to be safe. A better fix is in the | 512 | * smaller I/O, just to be safe. |
513 | * works, but add this for the time being so it will at | ||
514 | * least operate correctly. | ||
515 | */ | 513 | */ |
516 | if (q->merge_bvec_fn) | 514 | |
515 | if (q->merge_bvec_fn && !ti->type->merge) | ||
517 | rs->max_sectors = | 516 | rs->max_sectors = |
518 | min_not_zero(rs->max_sectors, | 517 | min_not_zero(rs->max_sectors, |
519 | (unsigned int) (PAGE_SIZE >> 9)); | 518 | (unsigned int) (PAGE_SIZE >> 9)); |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 372369b1cc20..bca448e11878 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -37,8 +37,8 @@ static DEFINE_SPINLOCK(_minor_lock); | |||
37 | struct dm_io { | 37 | struct dm_io { |
38 | struct mapped_device *md; | 38 | struct mapped_device *md; |
39 | int error; | 39 | int error; |
40 | struct bio *bio; | ||
41 | atomic_t io_count; | 40 | atomic_t io_count; |
41 | struct bio *bio; | ||
42 | unsigned long start_time; | 42 | unsigned long start_time; |
43 | }; | 43 | }; |
44 | 44 | ||
@@ -829,6 +829,49 @@ static int __split_bio(struct mapped_device *md, struct bio *bio) | |||
829 | * CRUD END | 829 | * CRUD END |
830 | *---------------------------------------------------------------*/ | 830 | *---------------------------------------------------------------*/ |
831 | 831 | ||
832 | static int dm_merge_bvec(struct request_queue *q, | ||
833 | struct bvec_merge_data *bvm, | ||
834 | struct bio_vec *biovec) | ||
835 | { | ||
836 | struct mapped_device *md = q->queuedata; | ||
837 | struct dm_table *map = dm_get_table(md); | ||
838 | struct dm_target *ti; | ||
839 | sector_t max_sectors; | ||
840 | int max_size; | ||
841 | |||
842 | if (unlikely(!map)) | ||
843 | return 0; | ||
844 | |||
845 | ti = dm_table_find_target(map, bvm->bi_sector); | ||
846 | |||
847 | /* | ||
848 | * Find maximum amount of I/O that won't need splitting | ||
849 | */ | ||
850 | max_sectors = min(max_io_len(md, bvm->bi_sector, ti), | ||
851 | (sector_t) BIO_MAX_SECTORS); | ||
852 | max_size = (max_sectors << SECTOR_SHIFT) - bvm->bi_size; | ||
853 | if (max_size < 0) | ||
854 | max_size = 0; | ||
855 | |||
856 | /* | ||
857 | * merge_bvec_fn() returns number of bytes | ||
858 | * it can accept at this offset | ||
859 | * max is precomputed maximal io size | ||
860 | */ | ||
861 | if (max_size && ti->type->merge) | ||
862 | max_size = ti->type->merge(ti, bvm, biovec, max_size); | ||
863 | |||
864 | /* | ||
865 | * Always allow an entire first page | ||
866 | */ | ||
867 | if (max_size <= biovec->bv_len && !(bvm->bi_size >> SECTOR_SHIFT)) | ||
868 | max_size = biovec->bv_len; | ||
869 | |||
870 | dm_table_put(map); | ||
871 | |||
872 | return max_size; | ||
873 | } | ||
874 | |||
832 | /* | 875 | /* |
833 | * The request function that just remaps the bio built up by | 876 | * The request function that just remaps the bio built up by |
834 | * dm_merge_bvec. | 877 | * dm_merge_bvec. |
@@ -1032,6 +1075,7 @@ static struct mapped_device *alloc_dev(int minor) | |||
1032 | blk_queue_make_request(md->queue, dm_request); | 1075 | blk_queue_make_request(md->queue, dm_request); |
1033 | blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY); | 1076 | blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY); |
1034 | md->queue->unplug_fn = dm_unplug_all; | 1077 | md->queue->unplug_fn = dm_unplug_all; |
1078 | blk_queue_merge_bvec(md->queue, dm_merge_bvec); | ||
1035 | 1079 | ||
1036 | md->io_pool = mempool_create_slab_pool(MIN_IOS, _io_cache); | 1080 | md->io_pool = mempool_create_slab_pool(MIN_IOS, _io_cache); |
1037 | if (!md->io_pool) | 1081 | if (!md->io_pool) |
diff --git a/drivers/md/dm.h b/drivers/md/dm.h index 8c03b634e62e..1e59a0b0a78a 100644 --- a/drivers/md/dm.h +++ b/drivers/md/dm.h | |||
@@ -100,12 +100,6 @@ int dm_lock_for_deletion(struct mapped_device *md); | |||
100 | 100 | ||
101 | void dm_kobject_uevent(struct mapped_device *md); | 101 | void dm_kobject_uevent(struct mapped_device *md); |
102 | 102 | ||
103 | /* | ||
104 | * Dirty log | ||
105 | */ | ||
106 | int dm_dirty_log_init(void); | ||
107 | void dm_dirty_log_exit(void); | ||
108 | |||
109 | int dm_kcopyd_init(void); | 103 | int dm_kcopyd_init(void); |
110 | void dm_kcopyd_exit(void); | 104 | void dm_kcopyd_exit(void); |
111 | 105 | ||
diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c index d107ddceefcd..268547dbfbd3 100644 --- a/drivers/md/faulty.c +++ b/drivers/md/faulty.c | |||
@@ -297,7 +297,7 @@ static int run(mddev_t *mddev) | |||
297 | rdev_for_each(rdev, tmp, mddev) | 297 | rdev_for_each(rdev, tmp, mddev) |
298 | conf->rdev = rdev; | 298 | conf->rdev = rdev; |
299 | 299 | ||
300 | mddev->array_size = mddev->size; | 300 | mddev->array_sectors = mddev->size * 2; |
301 | mddev->private = conf; | 301 | mddev->private = conf; |
302 | 302 | ||
303 | reconfig(mddev, mddev->layout, -1); | 303 | reconfig(mddev, mddev->layout, -1); |
diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 6a866d7c8ae5..b1eebf88c209 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c | |||
@@ -122,13 +122,13 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
122 | return NULL; | 122 | return NULL; |
123 | 123 | ||
124 | cnt = 0; | 124 | cnt = 0; |
125 | conf->array_size = 0; | 125 | conf->array_sectors = 0; |
126 | 126 | ||
127 | rdev_for_each(rdev, tmp, mddev) { | 127 | rdev_for_each(rdev, tmp, mddev) { |
128 | int j = rdev->raid_disk; | 128 | int j = rdev->raid_disk; |
129 | dev_info_t *disk = conf->disks + j; | 129 | dev_info_t *disk = conf->disks + j; |
130 | 130 | ||
131 | if (j < 0 || j > raid_disks || disk->rdev) { | 131 | if (j < 0 || j >= raid_disks || disk->rdev) { |
132 | printk("linear: disk numbering problem. Aborting!\n"); | 132 | printk("linear: disk numbering problem. Aborting!\n"); |
133 | goto out; | 133 | goto out; |
134 | } | 134 | } |
@@ -146,7 +146,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
146 | blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); | 146 | blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); |
147 | 147 | ||
148 | disk->size = rdev->size; | 148 | disk->size = rdev->size; |
149 | conf->array_size += rdev->size; | 149 | conf->array_sectors += rdev->size * 2; |
150 | 150 | ||
151 | cnt++; | 151 | cnt++; |
152 | } | 152 | } |
@@ -155,7 +155,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
155 | goto out; | 155 | goto out; |
156 | } | 156 | } |
157 | 157 | ||
158 | min_spacing = conf->array_size; | 158 | min_spacing = conf->array_sectors / 2; |
159 | sector_div(min_spacing, PAGE_SIZE/sizeof(struct dev_info *)); | 159 | sector_div(min_spacing, PAGE_SIZE/sizeof(struct dev_info *)); |
160 | 160 | ||
161 | /* min_spacing is the minimum spacing that will fit the hash | 161 | /* min_spacing is the minimum spacing that will fit the hash |
@@ -164,7 +164,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
164 | * that is larger than min_spacing as use the size of that as | 164 | * that is larger than min_spacing as use the size of that as |
165 | * the actual spacing | 165 | * the actual spacing |
166 | */ | 166 | */ |
167 | conf->hash_spacing = conf->array_size; | 167 | conf->hash_spacing = conf->array_sectors / 2; |
168 | for (i=0; i < cnt-1 ; i++) { | 168 | for (i=0; i < cnt-1 ; i++) { |
169 | sector_t sz = 0; | 169 | sector_t sz = 0; |
170 | int j; | 170 | int j; |
@@ -194,7 +194,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
194 | unsigned round; | 194 | unsigned round; |
195 | unsigned long base; | 195 | unsigned long base; |
196 | 196 | ||
197 | sz = conf->array_size >> conf->preshift; | 197 | sz = conf->array_sectors >> (conf->preshift + 1); |
198 | sz += 1; /* force round-up */ | 198 | sz += 1; /* force round-up */ |
199 | base = conf->hash_spacing >> conf->preshift; | 199 | base = conf->hash_spacing >> conf->preshift; |
200 | round = sector_div(sz, base); | 200 | round = sector_div(sz, base); |
@@ -221,7 +221,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
221 | curr_offset = 0; | 221 | curr_offset = 0; |
222 | i = 0; | 222 | i = 0; |
223 | for (curr_offset = 0; | 223 | for (curr_offset = 0; |
224 | curr_offset < conf->array_size; | 224 | curr_offset < conf->array_sectors / 2; |
225 | curr_offset += conf->hash_spacing) { | 225 | curr_offset += conf->hash_spacing) { |
226 | 226 | ||
227 | while (i < raid_disks-1 && | 227 | while (i < raid_disks-1 && |
@@ -258,7 +258,7 @@ static int linear_run (mddev_t *mddev) | |||
258 | if (!conf) | 258 | if (!conf) |
259 | return 1; | 259 | return 1; |
260 | mddev->private = conf; | 260 | mddev->private = conf; |
261 | mddev->array_size = conf->array_size; | 261 | mddev->array_sectors = conf->array_sectors; |
262 | 262 | ||
263 | blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec); | 263 | blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec); |
264 | mddev->queue->unplug_fn = linear_unplug; | 264 | mddev->queue->unplug_fn = linear_unplug; |
@@ -292,8 +292,8 @@ static int linear_add(mddev_t *mddev, mdk_rdev_t *rdev) | |||
292 | newconf->prev = mddev_to_conf(mddev); | 292 | newconf->prev = mddev_to_conf(mddev); |
293 | mddev->private = newconf; | 293 | mddev->private = newconf; |
294 | mddev->raid_disks++; | 294 | mddev->raid_disks++; |
295 | mddev->array_size = newconf->array_size; | 295 | mddev->array_sectors = newconf->array_sectors; |
296 | set_capacity(mddev->gendisk, mddev->array_size << 1); | 296 | set_capacity(mddev->gendisk, mddev->array_sectors); |
297 | return 0; | 297 | return 0; |
298 | } | 298 | } |
299 | 299 | ||
diff --git a/drivers/md/md.c b/drivers/md/md.c index 2580ac1b9b0f..c2ff77ccec50 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -169,7 +169,6 @@ void md_new_event(mddev_t *mddev) | |||
169 | { | 169 | { |
170 | atomic_inc(&md_event_count); | 170 | atomic_inc(&md_event_count); |
171 | wake_up(&md_event_waiters); | 171 | wake_up(&md_event_waiters); |
172 | sysfs_notify(&mddev->kobj, NULL, "sync_action"); | ||
173 | } | 172 | } |
174 | EXPORT_SYMBOL_GPL(md_new_event); | 173 | EXPORT_SYMBOL_GPL(md_new_event); |
175 | 174 | ||
@@ -274,10 +273,12 @@ static mddev_t * mddev_find(dev_t unit) | |||
274 | INIT_LIST_HEAD(&new->all_mddevs); | 273 | INIT_LIST_HEAD(&new->all_mddevs); |
275 | init_timer(&new->safemode_timer); | 274 | init_timer(&new->safemode_timer); |
276 | atomic_set(&new->active, 1); | 275 | atomic_set(&new->active, 1); |
276 | atomic_set(&new->openers, 0); | ||
277 | spin_lock_init(&new->write_lock); | 277 | spin_lock_init(&new->write_lock); |
278 | init_waitqueue_head(&new->sb_wait); | 278 | init_waitqueue_head(&new->sb_wait); |
279 | init_waitqueue_head(&new->recovery_wait); | 279 | init_waitqueue_head(&new->recovery_wait); |
280 | new->reshape_position = MaxSector; | 280 | new->reshape_position = MaxSector; |
281 | new->resync_min = 0; | ||
281 | new->resync_max = MaxSector; | 282 | new->resync_max = MaxSector; |
282 | new->level = LEVEL_NONE; | 283 | new->level = LEVEL_NONE; |
283 | 284 | ||
@@ -347,21 +348,20 @@ static struct mdk_personality *find_pers(int level, char *clevel) | |||
347 | return NULL; | 348 | return NULL; |
348 | } | 349 | } |
349 | 350 | ||
351 | /* return the offset of the super block in 512byte sectors */ | ||
350 | static inline sector_t calc_dev_sboffset(struct block_device *bdev) | 352 | static inline sector_t calc_dev_sboffset(struct block_device *bdev) |
351 | { | 353 | { |
352 | sector_t size = bdev->bd_inode->i_size >> BLOCK_SIZE_BITS; | 354 | sector_t num_sectors = bdev->bd_inode->i_size / 512; |
353 | return MD_NEW_SIZE_BLOCKS(size); | 355 | return MD_NEW_SIZE_SECTORS(num_sectors); |
354 | } | 356 | } |
355 | 357 | ||
356 | static sector_t calc_dev_size(mdk_rdev_t *rdev, unsigned chunk_size) | 358 | static sector_t calc_num_sectors(mdk_rdev_t *rdev, unsigned chunk_size) |
357 | { | 359 | { |
358 | sector_t size; | 360 | sector_t num_sectors = rdev->sb_start; |
359 | |||
360 | size = rdev->sb_offset; | ||
361 | 361 | ||
362 | if (chunk_size) | 362 | if (chunk_size) |
363 | size &= ~((sector_t)chunk_size/1024 - 1); | 363 | num_sectors &= ~((sector_t)chunk_size/512 - 1); |
364 | return size; | 364 | return num_sectors; |
365 | } | 365 | } |
366 | 366 | ||
367 | static int alloc_disk_sb(mdk_rdev_t * rdev) | 367 | static int alloc_disk_sb(mdk_rdev_t * rdev) |
@@ -372,7 +372,7 @@ static int alloc_disk_sb(mdk_rdev_t * rdev) | |||
372 | rdev->sb_page = alloc_page(GFP_KERNEL); | 372 | rdev->sb_page = alloc_page(GFP_KERNEL); |
373 | if (!rdev->sb_page) { | 373 | if (!rdev->sb_page) { |
374 | printk(KERN_ALERT "md: out of memory.\n"); | 374 | printk(KERN_ALERT "md: out of memory.\n"); |
375 | return -EINVAL; | 375 | return -ENOMEM; |
376 | } | 376 | } |
377 | 377 | ||
378 | return 0; | 378 | return 0; |
@@ -384,7 +384,7 @@ static void free_disk_sb(mdk_rdev_t * rdev) | |||
384 | put_page(rdev->sb_page); | 384 | put_page(rdev->sb_page); |
385 | rdev->sb_loaded = 0; | 385 | rdev->sb_loaded = 0; |
386 | rdev->sb_page = NULL; | 386 | rdev->sb_page = NULL; |
387 | rdev->sb_offset = 0; | 387 | rdev->sb_start = 0; |
388 | rdev->size = 0; | 388 | rdev->size = 0; |
389 | } | 389 | } |
390 | } | 390 | } |
@@ -530,7 +530,7 @@ static int read_disk_sb(mdk_rdev_t * rdev, int size) | |||
530 | return 0; | 530 | return 0; |
531 | 531 | ||
532 | 532 | ||
533 | if (!sync_page_io(rdev->bdev, rdev->sb_offset<<1, size, rdev->sb_page, READ)) | 533 | if (!sync_page_io(rdev->bdev, rdev->sb_start, size, rdev->sb_page, READ)) |
534 | goto fail; | 534 | goto fail; |
535 | rdev->sb_loaded = 1; | 535 | rdev->sb_loaded = 1; |
536 | return 0; | 536 | return 0; |
@@ -543,17 +543,12 @@ fail: | |||
543 | 543 | ||
544 | static int uuid_equal(mdp_super_t *sb1, mdp_super_t *sb2) | 544 | static int uuid_equal(mdp_super_t *sb1, mdp_super_t *sb2) |
545 | { | 545 | { |
546 | if ( (sb1->set_uuid0 == sb2->set_uuid0) && | 546 | return sb1->set_uuid0 == sb2->set_uuid0 && |
547 | (sb1->set_uuid1 == sb2->set_uuid1) && | 547 | sb1->set_uuid1 == sb2->set_uuid1 && |
548 | (sb1->set_uuid2 == sb2->set_uuid2) && | 548 | sb1->set_uuid2 == sb2->set_uuid2 && |
549 | (sb1->set_uuid3 == sb2->set_uuid3)) | 549 | sb1->set_uuid3 == sb2->set_uuid3; |
550 | |||
551 | return 1; | ||
552 | |||
553 | return 0; | ||
554 | } | 550 | } |
555 | 551 | ||
556 | |||
557 | static int sb_equal(mdp_super_t *sb1, mdp_super_t *sb2) | 552 | static int sb_equal(mdp_super_t *sb1, mdp_super_t *sb2) |
558 | { | 553 | { |
559 | int ret; | 554 | int ret; |
@@ -564,7 +559,7 @@ static int sb_equal(mdp_super_t *sb1, mdp_super_t *sb2) | |||
564 | 559 | ||
565 | if (!tmp1 || !tmp2) { | 560 | if (!tmp1 || !tmp2) { |
566 | ret = 0; | 561 | ret = 0; |
567 | printk(KERN_INFO "md.c: sb1 is not equal to sb2!\n"); | 562 | printk(KERN_INFO "md.c sb_equal(): failed to allocate memory!\n"); |
568 | goto abort; | 563 | goto abort; |
569 | } | 564 | } |
570 | 565 | ||
@@ -577,11 +572,7 @@ static int sb_equal(mdp_super_t *sb1, mdp_super_t *sb2) | |||
577 | tmp1->nr_disks = 0; | 572 | tmp1->nr_disks = 0; |
578 | tmp2->nr_disks = 0; | 573 | tmp2->nr_disks = 0; |
579 | 574 | ||
580 | if (memcmp(tmp1, tmp2, MD_SB_GENERIC_CONSTANT_WORDS * 4)) | 575 | ret = (memcmp(tmp1, tmp2, MD_SB_GENERIC_CONSTANT_WORDS * 4) == 0); |
581 | ret = 0; | ||
582 | else | ||
583 | ret = 1; | ||
584 | |||
585 | abort: | 576 | abort: |
586 | kfree(tmp1); | 577 | kfree(tmp1); |
587 | kfree(tmp2); | 578 | kfree(tmp2); |
@@ -658,11 +649,14 @@ static unsigned int calc_sb_csum(mdp_super_t * sb) | |||
658 | */ | 649 | */ |
659 | 650 | ||
660 | struct super_type { | 651 | struct super_type { |
661 | char *name; | 652 | char *name; |
662 | struct module *owner; | 653 | struct module *owner; |
663 | int (*load_super)(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version); | 654 | int (*load_super)(mdk_rdev_t *rdev, mdk_rdev_t *refdev, |
664 | int (*validate_super)(mddev_t *mddev, mdk_rdev_t *rdev); | 655 | int minor_version); |
665 | void (*sync_super)(mddev_t *mddev, mdk_rdev_t *rdev); | 656 | int (*validate_super)(mddev_t *mddev, mdk_rdev_t *rdev); |
657 | void (*sync_super)(mddev_t *mddev, mdk_rdev_t *rdev); | ||
658 | unsigned long long (*rdev_size_change)(mdk_rdev_t *rdev, | ||
659 | sector_t num_sectors); | ||
666 | }; | 660 | }; |
667 | 661 | ||
668 | /* | 662 | /* |
@@ -673,16 +667,14 @@ static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version | |||
673 | char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; | 667 | char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; |
674 | mdp_super_t *sb; | 668 | mdp_super_t *sb; |
675 | int ret; | 669 | int ret; |
676 | sector_t sb_offset; | ||
677 | 670 | ||
678 | /* | 671 | /* |
679 | * Calculate the position of the superblock, | 672 | * Calculate the position of the superblock (512byte sectors), |
680 | * it's at the end of the disk. | 673 | * it's at the end of the disk. |
681 | * | 674 | * |
682 | * It also happens to be a multiple of 4Kb. | 675 | * It also happens to be a multiple of 4Kb. |
683 | */ | 676 | */ |
684 | sb_offset = calc_dev_sboffset(rdev->bdev); | 677 | rdev->sb_start = calc_dev_sboffset(rdev->bdev); |
685 | rdev->sb_offset = sb_offset; | ||
686 | 678 | ||
687 | ret = read_disk_sb(rdev, MD_SB_BYTES); | 679 | ret = read_disk_sb(rdev, MD_SB_BYTES); |
688 | if (ret) return ret; | 680 | if (ret) return ret; |
@@ -759,7 +751,7 @@ static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version | |||
759 | else | 751 | else |
760 | ret = 0; | 752 | ret = 0; |
761 | } | 753 | } |
762 | rdev->size = calc_dev_size(rdev, sb->chunk_size); | 754 | rdev->size = calc_num_sectors(rdev, sb->chunk_size) / 2; |
763 | 755 | ||
764 | if (rdev->size < sb->size && sb->level > 1) | 756 | if (rdev->size < sb->size && sb->level > 1) |
765 | /* "this cannot possibly happen" ... */ | 757 | /* "this cannot possibly happen" ... */ |
@@ -1004,6 +996,26 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1004 | } | 996 | } |
1005 | 997 | ||
1006 | /* | 998 | /* |
999 | * rdev_size_change for 0.90.0 | ||
1000 | */ | ||
1001 | static unsigned long long | ||
1002 | super_90_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors) | ||
1003 | { | ||
1004 | if (num_sectors && num_sectors < rdev->mddev->size * 2) | ||
1005 | return 0; /* component must fit device */ | ||
1006 | if (rdev->mddev->bitmap_offset) | ||
1007 | return 0; /* can't move bitmap */ | ||
1008 | rdev->sb_start = calc_dev_sboffset(rdev->bdev); | ||
1009 | if (!num_sectors || num_sectors > rdev->sb_start) | ||
1010 | num_sectors = rdev->sb_start; | ||
1011 | md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, | ||
1012 | rdev->sb_page); | ||
1013 | md_super_wait(rdev->mddev); | ||
1014 | return num_sectors / 2; /* kB for sysfs */ | ||
1015 | } | ||
1016 | |||
1017 | |||
1018 | /* | ||
1007 | * version 1 superblock | 1019 | * version 1 superblock |
1008 | */ | 1020 | */ |
1009 | 1021 | ||
@@ -1034,12 +1046,12 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) | |||
1034 | { | 1046 | { |
1035 | struct mdp_superblock_1 *sb; | 1047 | struct mdp_superblock_1 *sb; |
1036 | int ret; | 1048 | int ret; |
1037 | sector_t sb_offset; | 1049 | sector_t sb_start; |
1038 | char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; | 1050 | char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; |
1039 | int bmask; | 1051 | int bmask; |
1040 | 1052 | ||
1041 | /* | 1053 | /* |
1042 | * Calculate the position of the superblock. | 1054 | * Calculate the position of the superblock in 512byte sectors. |
1043 | * It is always aligned to a 4K boundary and | 1055 | * It is always aligned to a 4K boundary and |
1044 | * depeding on minor_version, it can be: | 1056 | * depeding on minor_version, it can be: |
1045 | * 0: At least 8K, but less than 12K, from end of device | 1057 | * 0: At least 8K, but less than 12K, from end of device |
@@ -1048,22 +1060,20 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) | |||
1048 | */ | 1060 | */ |
1049 | switch(minor_version) { | 1061 | switch(minor_version) { |
1050 | case 0: | 1062 | case 0: |
1051 | sb_offset = rdev->bdev->bd_inode->i_size >> 9; | 1063 | sb_start = rdev->bdev->bd_inode->i_size >> 9; |
1052 | sb_offset -= 8*2; | 1064 | sb_start -= 8*2; |
1053 | sb_offset &= ~(sector_t)(4*2-1); | 1065 | sb_start &= ~(sector_t)(4*2-1); |
1054 | /* convert from sectors to K */ | ||
1055 | sb_offset /= 2; | ||
1056 | break; | 1066 | break; |
1057 | case 1: | 1067 | case 1: |
1058 | sb_offset = 0; | 1068 | sb_start = 0; |
1059 | break; | 1069 | break; |
1060 | case 2: | 1070 | case 2: |
1061 | sb_offset = 4; | 1071 | sb_start = 8; |
1062 | break; | 1072 | break; |
1063 | default: | 1073 | default: |
1064 | return -EINVAL; | 1074 | return -EINVAL; |
1065 | } | 1075 | } |
1066 | rdev->sb_offset = sb_offset; | 1076 | rdev->sb_start = sb_start; |
1067 | 1077 | ||
1068 | /* superblock is rarely larger than 1K, but it can be larger, | 1078 | /* superblock is rarely larger than 1K, but it can be larger, |
1069 | * and it is safe to read 4k, so we do that | 1079 | * and it is safe to read 4k, so we do that |
@@ -1077,7 +1087,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) | |||
1077 | if (sb->magic != cpu_to_le32(MD_SB_MAGIC) || | 1087 | if (sb->magic != cpu_to_le32(MD_SB_MAGIC) || |
1078 | sb->major_version != cpu_to_le32(1) || | 1088 | sb->major_version != cpu_to_le32(1) || |
1079 | le32_to_cpu(sb->max_dev) > (4096-256)/2 || | 1089 | le32_to_cpu(sb->max_dev) > (4096-256)/2 || |
1080 | le64_to_cpu(sb->super_offset) != (rdev->sb_offset<<1) || | 1090 | le64_to_cpu(sb->super_offset) != rdev->sb_start || |
1081 | (le32_to_cpu(sb->feature_map) & ~MD_FEATURE_ALL) != 0) | 1091 | (le32_to_cpu(sb->feature_map) & ~MD_FEATURE_ALL) != 0) |
1082 | return -EINVAL; | 1092 | return -EINVAL; |
1083 | 1093 | ||
@@ -1113,7 +1123,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) | |||
1113 | rdev->sb_size = (rdev->sb_size | bmask) + 1; | 1123 | rdev->sb_size = (rdev->sb_size | bmask) + 1; |
1114 | 1124 | ||
1115 | if (minor_version | 1125 | if (minor_version |
1116 | && rdev->data_offset < sb_offset + (rdev->sb_size/512)) | 1126 | && rdev->data_offset < sb_start + (rdev->sb_size/512)) |
1117 | return -EINVAL; | 1127 | return -EINVAL; |
1118 | 1128 | ||
1119 | if (sb->level == cpu_to_le32(LEVEL_MULTIPATH)) | 1129 | if (sb->level == cpu_to_le32(LEVEL_MULTIPATH)) |
@@ -1149,7 +1159,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) | |||
1149 | if (minor_version) | 1159 | if (minor_version) |
1150 | rdev->size = ((rdev->bdev->bd_inode->i_size>>9) - le64_to_cpu(sb->data_offset)) / 2; | 1160 | rdev->size = ((rdev->bdev->bd_inode->i_size>>9) - le64_to_cpu(sb->data_offset)) / 2; |
1151 | else | 1161 | else |
1152 | rdev->size = rdev->sb_offset; | 1162 | rdev->size = rdev->sb_start / 2; |
1153 | if (rdev->size < le64_to_cpu(sb->data_size)/2) | 1163 | if (rdev->size < le64_to_cpu(sb->data_size)/2) |
1154 | return -EINVAL; | 1164 | return -EINVAL; |
1155 | rdev->size = le64_to_cpu(sb->data_size)/2; | 1165 | rdev->size = le64_to_cpu(sb->data_size)/2; |
@@ -1328,35 +1338,74 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1328 | sb->sb_csum = calc_sb_1_csum(sb); | 1338 | sb->sb_csum = calc_sb_1_csum(sb); |
1329 | } | 1339 | } |
1330 | 1340 | ||
1341 | static unsigned long long | ||
1342 | super_1_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors) | ||
1343 | { | ||
1344 | struct mdp_superblock_1 *sb; | ||
1345 | sector_t max_sectors; | ||
1346 | if (num_sectors && num_sectors < rdev->mddev->size * 2) | ||
1347 | return 0; /* component must fit device */ | ||
1348 | if (rdev->sb_start < rdev->data_offset) { | ||
1349 | /* minor versions 1 and 2; superblock before data */ | ||
1350 | max_sectors = rdev->bdev->bd_inode->i_size >> 9; | ||
1351 | max_sectors -= rdev->data_offset; | ||
1352 | if (!num_sectors || num_sectors > max_sectors) | ||
1353 | num_sectors = max_sectors; | ||
1354 | } else if (rdev->mddev->bitmap_offset) { | ||
1355 | /* minor version 0 with bitmap we can't move */ | ||
1356 | return 0; | ||
1357 | } else { | ||
1358 | /* minor version 0; superblock after data */ | ||
1359 | sector_t sb_start; | ||
1360 | sb_start = (rdev->bdev->bd_inode->i_size >> 9) - 8*2; | ||
1361 | sb_start &= ~(sector_t)(4*2 - 1); | ||
1362 | max_sectors = rdev->size * 2 + sb_start - rdev->sb_start; | ||
1363 | if (!num_sectors || num_sectors > max_sectors) | ||
1364 | num_sectors = max_sectors; | ||
1365 | rdev->sb_start = sb_start; | ||
1366 | } | ||
1367 | sb = (struct mdp_superblock_1 *) page_address(rdev->sb_page); | ||
1368 | sb->data_size = cpu_to_le64(num_sectors); | ||
1369 | sb->super_offset = rdev->sb_start; | ||
1370 | sb->sb_csum = calc_sb_1_csum(sb); | ||
1371 | md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, | ||
1372 | rdev->sb_page); | ||
1373 | md_super_wait(rdev->mddev); | ||
1374 | return num_sectors / 2; /* kB for sysfs */ | ||
1375 | } | ||
1331 | 1376 | ||
1332 | static struct super_type super_types[] = { | 1377 | static struct super_type super_types[] = { |
1333 | [0] = { | 1378 | [0] = { |
1334 | .name = "0.90.0", | 1379 | .name = "0.90.0", |
1335 | .owner = THIS_MODULE, | 1380 | .owner = THIS_MODULE, |
1336 | .load_super = super_90_load, | 1381 | .load_super = super_90_load, |
1337 | .validate_super = super_90_validate, | 1382 | .validate_super = super_90_validate, |
1338 | .sync_super = super_90_sync, | 1383 | .sync_super = super_90_sync, |
1384 | .rdev_size_change = super_90_rdev_size_change, | ||
1339 | }, | 1385 | }, |
1340 | [1] = { | 1386 | [1] = { |
1341 | .name = "md-1", | 1387 | .name = "md-1", |
1342 | .owner = THIS_MODULE, | 1388 | .owner = THIS_MODULE, |
1343 | .load_super = super_1_load, | 1389 | .load_super = super_1_load, |
1344 | .validate_super = super_1_validate, | 1390 | .validate_super = super_1_validate, |
1345 | .sync_super = super_1_sync, | 1391 | .sync_super = super_1_sync, |
1392 | .rdev_size_change = super_1_rdev_size_change, | ||
1346 | }, | 1393 | }, |
1347 | }; | 1394 | }; |
1348 | 1395 | ||
1349 | static int match_mddev_units(mddev_t *mddev1, mddev_t *mddev2) | 1396 | static int match_mddev_units(mddev_t *mddev1, mddev_t *mddev2) |
1350 | { | 1397 | { |
1351 | struct list_head *tmp, *tmp2; | ||
1352 | mdk_rdev_t *rdev, *rdev2; | 1398 | mdk_rdev_t *rdev, *rdev2; |
1353 | 1399 | ||
1354 | rdev_for_each(rdev, tmp, mddev1) | 1400 | rcu_read_lock(); |
1355 | rdev_for_each(rdev2, tmp2, mddev2) | 1401 | rdev_for_each_rcu(rdev, mddev1) |
1402 | rdev_for_each_rcu(rdev2, mddev2) | ||
1356 | if (rdev->bdev->bd_contains == | 1403 | if (rdev->bdev->bd_contains == |
1357 | rdev2->bdev->bd_contains) | 1404 | rdev2->bdev->bd_contains) { |
1405 | rcu_read_unlock(); | ||
1358 | return 1; | 1406 | return 1; |
1359 | 1407 | } | |
1408 | rcu_read_unlock(); | ||
1360 | return 0; | 1409 | return 0; |
1361 | } | 1410 | } |
1362 | 1411 | ||
@@ -1423,7 +1472,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) | |||
1423 | kobject_del(&rdev->kobj); | 1472 | kobject_del(&rdev->kobj); |
1424 | goto fail; | 1473 | goto fail; |
1425 | } | 1474 | } |
1426 | list_add(&rdev->same_set, &mddev->disks); | 1475 | list_add_rcu(&rdev->same_set, &mddev->disks); |
1427 | bd_claim_by_disk(rdev->bdev, rdev->bdev->bd_holder, mddev->gendisk); | 1476 | bd_claim_by_disk(rdev->bdev, rdev->bdev->bd_holder, mddev->gendisk); |
1428 | return 0; | 1477 | return 0; |
1429 | 1478 | ||
@@ -1448,14 +1497,16 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev) | |||
1448 | return; | 1497 | return; |
1449 | } | 1498 | } |
1450 | bd_release_from_disk(rdev->bdev, rdev->mddev->gendisk); | 1499 | bd_release_from_disk(rdev->bdev, rdev->mddev->gendisk); |
1451 | list_del_init(&rdev->same_set); | 1500 | list_del_rcu(&rdev->same_set); |
1452 | printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b)); | 1501 | printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b)); |
1453 | rdev->mddev = NULL; | 1502 | rdev->mddev = NULL; |
1454 | sysfs_remove_link(&rdev->kobj, "block"); | 1503 | sysfs_remove_link(&rdev->kobj, "block"); |
1455 | 1504 | ||
1456 | /* We need to delay this, otherwise we can deadlock when | 1505 | /* We need to delay this, otherwise we can deadlock when |
1457 | * writing to 'remove' to "dev/state" | 1506 | * writing to 'remove' to "dev/state". We also need |
1507 | * to delay it due to rcu usage. | ||
1458 | */ | 1508 | */ |
1509 | synchronize_rcu(); | ||
1459 | INIT_WORK(&rdev->del_work, md_delayed_delete); | 1510 | INIT_WORK(&rdev->del_work, md_delayed_delete); |
1460 | kobject_get(&rdev->kobj); | 1511 | kobject_get(&rdev->kobj); |
1461 | schedule_work(&rdev->del_work); | 1512 | schedule_work(&rdev->del_work); |
@@ -1511,7 +1562,6 @@ static void export_rdev(mdk_rdev_t * rdev) | |||
1511 | if (rdev->mddev) | 1562 | if (rdev->mddev) |
1512 | MD_BUG(); | 1563 | MD_BUG(); |
1513 | free_disk_sb(rdev); | 1564 | free_disk_sb(rdev); |
1514 | list_del_init(&rdev->same_set); | ||
1515 | #ifndef MODULE | 1565 | #ifndef MODULE |
1516 | if (test_bit(AutoDetected, &rdev->flags)) | 1566 | if (test_bit(AutoDetected, &rdev->flags)) |
1517 | md_autodetect_dev(rdev->bdev->bd_dev); | 1567 | md_autodetect_dev(rdev->bdev->bd_dev); |
@@ -1758,11 +1808,11 @@ repeat: | |||
1758 | dprintk("%s ", bdevname(rdev->bdev,b)); | 1808 | dprintk("%s ", bdevname(rdev->bdev,b)); |
1759 | if (!test_bit(Faulty, &rdev->flags)) { | 1809 | if (!test_bit(Faulty, &rdev->flags)) { |
1760 | md_super_write(mddev,rdev, | 1810 | md_super_write(mddev,rdev, |
1761 | rdev->sb_offset<<1, rdev->sb_size, | 1811 | rdev->sb_start, rdev->sb_size, |
1762 | rdev->sb_page); | 1812 | rdev->sb_page); |
1763 | dprintk(KERN_INFO "(write) %s's sb offset: %llu\n", | 1813 | dprintk(KERN_INFO "(write) %s's sb offset: %llu\n", |
1764 | bdevname(rdev->bdev,b), | 1814 | bdevname(rdev->bdev,b), |
1765 | (unsigned long long)rdev->sb_offset); | 1815 | (unsigned long long)rdev->sb_start); |
1766 | rdev->sb_events = mddev->events; | 1816 | rdev->sb_events = mddev->events; |
1767 | 1817 | ||
1768 | } else | 1818 | } else |
@@ -1787,7 +1837,7 @@ repeat: | |||
1787 | 1837 | ||
1788 | } | 1838 | } |
1789 | 1839 | ||
1790 | /* words written to sysfs files may, or my not, be \n terminated. | 1840 | /* words written to sysfs files may, or may not, be \n terminated. |
1791 | * We want to accept with case. For this we use cmd_match. | 1841 | * We want to accept with case. For this we use cmd_match. |
1792 | */ | 1842 | */ |
1793 | static int cmd_match(const char *cmd, const char *str) | 1843 | static int cmd_match(const char *cmd, const char *str) |
@@ -1886,6 +1936,8 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
1886 | 1936 | ||
1887 | err = 0; | 1937 | err = 0; |
1888 | } | 1938 | } |
1939 | if (!err) | ||
1940 | sysfs_notify(&rdev->kobj, NULL, "state"); | ||
1889 | return err ? err : len; | 1941 | return err ? err : len; |
1890 | } | 1942 | } |
1891 | static struct rdev_sysfs_entry rdev_state = | 1943 | static struct rdev_sysfs_entry rdev_state = |
@@ -1931,7 +1983,7 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
1931 | slot = -1; | 1983 | slot = -1; |
1932 | else if (e==buf || (*e && *e!= '\n')) | 1984 | else if (e==buf || (*e && *e!= '\n')) |
1933 | return -EINVAL; | 1985 | return -EINVAL; |
1934 | if (rdev->mddev->pers) { | 1986 | if (rdev->mddev->pers && slot == -1) { |
1935 | /* Setting 'slot' on an active array requires also | 1987 | /* Setting 'slot' on an active array requires also |
1936 | * updating the 'rd%d' link, and communicating | 1988 | * updating the 'rd%d' link, and communicating |
1937 | * with the personality with ->hot_*_disk. | 1989 | * with the personality with ->hot_*_disk. |
@@ -1939,8 +1991,6 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
1939 | * failed/spare devices. This normally happens automatically, | 1991 | * failed/spare devices. This normally happens automatically, |
1940 | * but not when the metadata is externally managed. | 1992 | * but not when the metadata is externally managed. |
1941 | */ | 1993 | */ |
1942 | if (slot != -1) | ||
1943 | return -EBUSY; | ||
1944 | if (rdev->raid_disk == -1) | 1994 | if (rdev->raid_disk == -1) |
1945 | return -EEXIST; | 1995 | return -EEXIST; |
1946 | /* personality does all needed checks */ | 1996 | /* personality does all needed checks */ |
@@ -1954,6 +2004,43 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
1954 | sysfs_remove_link(&rdev->mddev->kobj, nm); | 2004 | sysfs_remove_link(&rdev->mddev->kobj, nm); |
1955 | set_bit(MD_RECOVERY_NEEDED, &rdev->mddev->recovery); | 2005 | set_bit(MD_RECOVERY_NEEDED, &rdev->mddev->recovery); |
1956 | md_wakeup_thread(rdev->mddev->thread); | 2006 | md_wakeup_thread(rdev->mddev->thread); |
2007 | } else if (rdev->mddev->pers) { | ||
2008 | mdk_rdev_t *rdev2; | ||
2009 | struct list_head *tmp; | ||
2010 | /* Activating a spare .. or possibly reactivating | ||
2011 | * if we every get bitmaps working here. | ||
2012 | */ | ||
2013 | |||
2014 | if (rdev->raid_disk != -1) | ||
2015 | return -EBUSY; | ||
2016 | |||
2017 | if (rdev->mddev->pers->hot_add_disk == NULL) | ||
2018 | return -EINVAL; | ||
2019 | |||
2020 | rdev_for_each(rdev2, tmp, rdev->mddev) | ||
2021 | if (rdev2->raid_disk == slot) | ||
2022 | return -EEXIST; | ||
2023 | |||
2024 | rdev->raid_disk = slot; | ||
2025 | if (test_bit(In_sync, &rdev->flags)) | ||
2026 | rdev->saved_raid_disk = slot; | ||
2027 | else | ||
2028 | rdev->saved_raid_disk = -1; | ||
2029 | err = rdev->mddev->pers-> | ||
2030 | hot_add_disk(rdev->mddev, rdev); | ||
2031 | if (err) { | ||
2032 | rdev->raid_disk = -1; | ||
2033 | return err; | ||
2034 | } else | ||
2035 | sysfs_notify(&rdev->kobj, NULL, "state"); | ||
2036 | sprintf(nm, "rd%d", rdev->raid_disk); | ||
2037 | if (sysfs_create_link(&rdev->mddev->kobj, &rdev->kobj, nm)) | ||
2038 | printk(KERN_WARNING | ||
2039 | "md: cannot register " | ||
2040 | "%s for %s\n", | ||
2041 | nm, mdname(rdev->mddev)); | ||
2042 | |||
2043 | /* don't wakeup anyone, leave that to userspace. */ | ||
1957 | } else { | 2044 | } else { |
1958 | if (slot >= rdev->mddev->raid_disks) | 2045 | if (slot >= rdev->mddev->raid_disks) |
1959 | return -ENOSPC; | 2046 | return -ENOSPC; |
@@ -1962,6 +2049,7 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
1962 | clear_bit(Faulty, &rdev->flags); | 2049 | clear_bit(Faulty, &rdev->flags); |
1963 | clear_bit(WriteMostly, &rdev->flags); | 2050 | clear_bit(WriteMostly, &rdev->flags); |
1964 | set_bit(In_sync, &rdev->flags); | 2051 | set_bit(In_sync, &rdev->flags); |
2052 | sysfs_notify(&rdev->kobj, NULL, "state"); | ||
1965 | } | 2053 | } |
1966 | return len; | 2054 | return len; |
1967 | } | 2055 | } |
@@ -1983,7 +2071,7 @@ offset_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
1983 | unsigned long long offset = simple_strtoull(buf, &e, 10); | 2071 | unsigned long long offset = simple_strtoull(buf, &e, 10); |
1984 | if (e==buf || (*e && *e != '\n')) | 2072 | if (e==buf || (*e && *e != '\n')) |
1985 | return -EINVAL; | 2073 | return -EINVAL; |
1986 | if (rdev->mddev->pers) | 2074 | if (rdev->mddev->pers && rdev->raid_disk >= 0) |
1987 | return -EBUSY; | 2075 | return -EBUSY; |
1988 | if (rdev->size && rdev->mddev->external) | 2076 | if (rdev->size && rdev->mddev->external) |
1989 | /* Must set offset before size, so overlap checks | 2077 | /* Must set offset before size, so overlap checks |
@@ -2015,17 +2103,30 @@ static int overlaps(sector_t s1, sector_t l1, sector_t s2, sector_t l2) | |||
2015 | static ssize_t | 2103 | static ssize_t |
2016 | rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) | 2104 | rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) |
2017 | { | 2105 | { |
2018 | char *e; | 2106 | unsigned long long size; |
2019 | unsigned long long size = simple_strtoull(buf, &e, 10); | ||
2020 | unsigned long long oldsize = rdev->size; | 2107 | unsigned long long oldsize = rdev->size; |
2021 | mddev_t *my_mddev = rdev->mddev; | 2108 | mddev_t *my_mddev = rdev->mddev; |
2022 | 2109 | ||
2023 | if (e==buf || (*e && *e != '\n')) | 2110 | if (strict_strtoull(buf, 10, &size) < 0) |
2024 | return -EINVAL; | 2111 | return -EINVAL; |
2025 | if (my_mddev->pers) | 2112 | if (size < my_mddev->size) |
2026 | return -EBUSY; | 2113 | return -EINVAL; |
2114 | if (my_mddev->pers && rdev->raid_disk >= 0) { | ||
2115 | if (my_mddev->persistent) { | ||
2116 | size = super_types[my_mddev->major_version]. | ||
2117 | rdev_size_change(rdev, size * 2); | ||
2118 | if (!size) | ||
2119 | return -EBUSY; | ||
2120 | } else if (!size) { | ||
2121 | size = (rdev->bdev->bd_inode->i_size >> 10); | ||
2122 | size -= rdev->data_offset/2; | ||
2123 | } | ||
2124 | if (size < my_mddev->size) | ||
2125 | return -EINVAL; /* component must fit device */ | ||
2126 | } | ||
2127 | |||
2027 | rdev->size = size; | 2128 | rdev->size = size; |
2028 | if (size > oldsize && rdev->mddev->external) { | 2129 | if (size > oldsize && my_mddev->external) { |
2029 | /* need to check that all other rdevs with the same ->bdev | 2130 | /* need to check that all other rdevs with the same ->bdev |
2030 | * do not overlap. We need to unlock the mddev to avoid | 2131 | * do not overlap. We need to unlock the mddev to avoid |
2031 | * a deadlock. We have already changed rdev->size, and if | 2132 | * a deadlock. We have already changed rdev->size, and if |
@@ -2044,8 +2145,9 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
2044 | if (test_bit(AllReserved, &rdev2->flags) || | 2145 | if (test_bit(AllReserved, &rdev2->flags) || |
2045 | (rdev->bdev == rdev2->bdev && | 2146 | (rdev->bdev == rdev2->bdev && |
2046 | rdev != rdev2 && | 2147 | rdev != rdev2 && |
2047 | overlaps(rdev->data_offset, rdev->size, | 2148 | overlaps(rdev->data_offset, rdev->size * 2, |
2048 | rdev2->data_offset, rdev2->size))) { | 2149 | rdev2->data_offset, |
2150 | rdev2->size * 2))) { | ||
2049 | overlap = 1; | 2151 | overlap = 1; |
2050 | break; | 2152 | break; |
2051 | } | 2153 | } |
@@ -2067,8 +2169,6 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
2067 | return -EBUSY; | 2169 | return -EBUSY; |
2068 | } | 2170 | } |
2069 | } | 2171 | } |
2070 | if (size < my_mddev->size || my_mddev->size == 0) | ||
2071 | my_mddev->size = size; | ||
2072 | return len; | 2172 | return len; |
2073 | } | 2173 | } |
2074 | 2174 | ||
@@ -2512,7 +2612,7 @@ __ATTR(resync_start, S_IRUGO|S_IWUSR, resync_start_show, resync_start_store); | |||
2512 | * When written, doesn't tear down array, but just stops it | 2612 | * When written, doesn't tear down array, but just stops it |
2513 | * suspended (not supported yet) | 2613 | * suspended (not supported yet) |
2514 | * All IO requests will block. The array can be reconfigured. | 2614 | * All IO requests will block. The array can be reconfigured. |
2515 | * Writing this, if accepted, will block until array is quiessent | 2615 | * Writing this, if accepted, will block until array is quiescent |
2516 | * readonly | 2616 | * readonly |
2517 | * no resync can happen. no superblocks get written. | 2617 | * no resync can happen. no superblocks get written. |
2518 | * write requests fail | 2618 | * write requests fail |
@@ -2585,7 +2685,7 @@ array_state_show(mddev_t *mddev, char *page) | |||
2585 | return sprintf(page, "%s\n", array_states[st]); | 2685 | return sprintf(page, "%s\n", array_states[st]); |
2586 | } | 2686 | } |
2587 | 2687 | ||
2588 | static int do_md_stop(mddev_t * mddev, int ro); | 2688 | static int do_md_stop(mddev_t * mddev, int ro, int is_open); |
2589 | static int do_md_run(mddev_t * mddev); | 2689 | static int do_md_run(mddev_t * mddev); |
2590 | static int restart_array(mddev_t *mddev); | 2690 | static int restart_array(mddev_t *mddev); |
2591 | 2691 | ||
@@ -2599,16 +2699,16 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len) | |||
2599 | break; | 2699 | break; |
2600 | case clear: | 2700 | case clear: |
2601 | /* stopping an active array */ | 2701 | /* stopping an active array */ |
2602 | if (atomic_read(&mddev->active) > 1) | 2702 | if (atomic_read(&mddev->openers) > 0) |
2603 | return -EBUSY; | 2703 | return -EBUSY; |
2604 | err = do_md_stop(mddev, 0); | 2704 | err = do_md_stop(mddev, 0, 0); |
2605 | break; | 2705 | break; |
2606 | case inactive: | 2706 | case inactive: |
2607 | /* stopping an active array */ | 2707 | /* stopping an active array */ |
2608 | if (mddev->pers) { | 2708 | if (mddev->pers) { |
2609 | if (atomic_read(&mddev->active) > 1) | 2709 | if (atomic_read(&mddev->openers) > 0) |
2610 | return -EBUSY; | 2710 | return -EBUSY; |
2611 | err = do_md_stop(mddev, 2); | 2711 | err = do_md_stop(mddev, 2, 0); |
2612 | } else | 2712 | } else |
2613 | err = 0; /* already inactive */ | 2713 | err = 0; /* already inactive */ |
2614 | break; | 2714 | break; |
@@ -2616,7 +2716,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len) | |||
2616 | break; /* not supported yet */ | 2716 | break; /* not supported yet */ |
2617 | case readonly: | 2717 | case readonly: |
2618 | if (mddev->pers) | 2718 | if (mddev->pers) |
2619 | err = do_md_stop(mddev, 1); | 2719 | err = do_md_stop(mddev, 1, 0); |
2620 | else { | 2720 | else { |
2621 | mddev->ro = 1; | 2721 | mddev->ro = 1; |
2622 | set_disk_ro(mddev->gendisk, 1); | 2722 | set_disk_ro(mddev->gendisk, 1); |
@@ -2626,7 +2726,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len) | |||
2626 | case read_auto: | 2726 | case read_auto: |
2627 | if (mddev->pers) { | 2727 | if (mddev->pers) { |
2628 | if (mddev->ro != 1) | 2728 | if (mddev->ro != 1) |
2629 | err = do_md_stop(mddev, 1); | 2729 | err = do_md_stop(mddev, 1, 0); |
2630 | else | 2730 | else |
2631 | err = restart_array(mddev); | 2731 | err = restart_array(mddev); |
2632 | if (err == 0) { | 2732 | if (err == 0) { |
@@ -2681,8 +2781,10 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len) | |||
2681 | } | 2781 | } |
2682 | if (err) | 2782 | if (err) |
2683 | return err; | 2783 | return err; |
2684 | else | 2784 | else { |
2785 | sysfs_notify(&mddev->kobj, NULL, "array_state"); | ||
2685 | return len; | 2786 | return len; |
2787 | } | ||
2686 | } | 2788 | } |
2687 | static struct md_sysfs_entry md_array_state = | 2789 | static struct md_sysfs_entry md_array_state = |
2688 | __ATTR(array_state, S_IRUGO|S_IWUSR, array_state_show, array_state_store); | 2790 | __ATTR(array_state, S_IRUGO|S_IWUSR, array_state_show, array_state_store); |
@@ -2785,7 +2887,7 @@ size_show(mddev_t *mddev, char *page) | |||
2785 | return sprintf(page, "%llu\n", (unsigned long long)mddev->size); | 2887 | return sprintf(page, "%llu\n", (unsigned long long)mddev->size); |
2786 | } | 2888 | } |
2787 | 2889 | ||
2788 | static int update_size(mddev_t *mddev, unsigned long size); | 2890 | static int update_size(mddev_t *mddev, sector_t num_sectors); |
2789 | 2891 | ||
2790 | static ssize_t | 2892 | static ssize_t |
2791 | size_store(mddev_t *mddev, const char *buf, size_t len) | 2893 | size_store(mddev_t *mddev, const char *buf, size_t len) |
@@ -2802,7 +2904,7 @@ size_store(mddev_t *mddev, const char *buf, size_t len) | |||
2802 | return -EINVAL; | 2904 | return -EINVAL; |
2803 | 2905 | ||
2804 | if (mddev->pers) { | 2906 | if (mddev->pers) { |
2805 | err = update_size(mddev, size); | 2907 | err = update_size(mddev, size * 2); |
2806 | md_update_sb(mddev, 1); | 2908 | md_update_sb(mddev, 1); |
2807 | } else { | 2909 | } else { |
2808 | if (mddev->size == 0 || | 2910 | if (mddev->size == 0 || |
@@ -2899,7 +3001,7 @@ action_show(mddev_t *mddev, char *page) | |||
2899 | type = "check"; | 3001 | type = "check"; |
2900 | else | 3002 | else |
2901 | type = "repair"; | 3003 | type = "repair"; |
2902 | } else | 3004 | } else if (test_bit(MD_RECOVERY_RECOVER, &mddev->recovery)) |
2903 | type = "recover"; | 3005 | type = "recover"; |
2904 | } | 3006 | } |
2905 | return sprintf(page, "%s\n", type); | 3007 | return sprintf(page, "%s\n", type); |
@@ -2921,15 +3023,19 @@ action_store(mddev_t *mddev, const char *page, size_t len) | |||
2921 | } else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) || | 3023 | } else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) || |
2922 | test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) | 3024 | test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) |
2923 | return -EBUSY; | 3025 | return -EBUSY; |
2924 | else if (cmd_match(page, "resync") || cmd_match(page, "recover")) | 3026 | else if (cmd_match(page, "resync")) |
3027 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | ||
3028 | else if (cmd_match(page, "recover")) { | ||
3029 | set_bit(MD_RECOVERY_RECOVER, &mddev->recovery); | ||
2925 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 3030 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
2926 | else if (cmd_match(page, "reshape")) { | 3031 | } else if (cmd_match(page, "reshape")) { |
2927 | int err; | 3032 | int err; |
2928 | if (mddev->pers->start_reshape == NULL) | 3033 | if (mddev->pers->start_reshape == NULL) |
2929 | return -EINVAL; | 3034 | return -EINVAL; |
2930 | err = mddev->pers->start_reshape(mddev); | 3035 | err = mddev->pers->start_reshape(mddev); |
2931 | if (err) | 3036 | if (err) |
2932 | return err; | 3037 | return err; |
3038 | sysfs_notify(&mddev->kobj, NULL, "degraded"); | ||
2933 | } else { | 3039 | } else { |
2934 | if (cmd_match(page, "check")) | 3040 | if (cmd_match(page, "check")) |
2935 | set_bit(MD_RECOVERY_CHECK, &mddev->recovery); | 3041 | set_bit(MD_RECOVERY_CHECK, &mddev->recovery); |
@@ -2940,6 +3046,7 @@ action_store(mddev_t *mddev, const char *page, size_t len) | |||
2940 | } | 3046 | } |
2941 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 3047 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
2942 | md_wakeup_thread(mddev->thread); | 3048 | md_wakeup_thread(mddev->thread); |
3049 | sysfs_notify(&mddev->kobj, NULL, "sync_action"); | ||
2943 | return len; | 3050 | return len; |
2944 | } | 3051 | } |
2945 | 3052 | ||
@@ -3049,11 +3156,11 @@ static ssize_t | |||
3049 | sync_speed_show(mddev_t *mddev, char *page) | 3156 | sync_speed_show(mddev_t *mddev, char *page) |
3050 | { | 3157 | { |
3051 | unsigned long resync, dt, db; | 3158 | unsigned long resync, dt, db; |
3052 | resync = (mddev->curr_mark_cnt - atomic_read(&mddev->recovery_active)); | 3159 | resync = mddev->curr_mark_cnt - atomic_read(&mddev->recovery_active); |
3053 | dt = ((jiffies - mddev->resync_mark) / HZ); | 3160 | dt = (jiffies - mddev->resync_mark) / HZ; |
3054 | if (!dt) dt++; | 3161 | if (!dt) dt++; |
3055 | db = resync - (mddev->resync_mark_cnt); | 3162 | db = resync - mddev->resync_mark_cnt; |
3056 | return sprintf(page, "%ld\n", db/dt/2); /* K/sec */ | 3163 | return sprintf(page, "%lu\n", db/dt/2); /* K/sec */ |
3057 | } | 3164 | } |
3058 | 3165 | ||
3059 | static struct md_sysfs_entry md_sync_speed = __ATTR_RO(sync_speed); | 3166 | static struct md_sysfs_entry md_sync_speed = __ATTR_RO(sync_speed); |
@@ -3075,6 +3182,36 @@ sync_completed_show(mddev_t *mddev, char *page) | |||
3075 | static struct md_sysfs_entry md_sync_completed = __ATTR_RO(sync_completed); | 3182 | static struct md_sysfs_entry md_sync_completed = __ATTR_RO(sync_completed); |
3076 | 3183 | ||
3077 | static ssize_t | 3184 | static ssize_t |
3185 | min_sync_show(mddev_t *mddev, char *page) | ||
3186 | { | ||
3187 | return sprintf(page, "%llu\n", | ||
3188 | (unsigned long long)mddev->resync_min); | ||
3189 | } | ||
3190 | static ssize_t | ||
3191 | min_sync_store(mddev_t *mddev, const char *buf, size_t len) | ||
3192 | { | ||
3193 | unsigned long long min; | ||
3194 | if (strict_strtoull(buf, 10, &min)) | ||
3195 | return -EINVAL; | ||
3196 | if (min > mddev->resync_max) | ||
3197 | return -EINVAL; | ||
3198 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) | ||
3199 | return -EBUSY; | ||
3200 | |||
3201 | /* Must be a multiple of chunk_size */ | ||
3202 | if (mddev->chunk_size) { | ||
3203 | if (min & (sector_t)((mddev->chunk_size>>9)-1)) | ||
3204 | return -EINVAL; | ||
3205 | } | ||
3206 | mddev->resync_min = min; | ||
3207 | |||
3208 | return len; | ||
3209 | } | ||
3210 | |||
3211 | static struct md_sysfs_entry md_min_sync = | ||
3212 | __ATTR(sync_min, S_IRUGO|S_IWUSR, min_sync_show, min_sync_store); | ||
3213 | |||
3214 | static ssize_t | ||
3078 | max_sync_show(mddev_t *mddev, char *page) | 3215 | max_sync_show(mddev_t *mddev, char *page) |
3079 | { | 3216 | { |
3080 | if (mddev->resync_max == MaxSector) | 3217 | if (mddev->resync_max == MaxSector) |
@@ -3089,9 +3226,10 @@ max_sync_store(mddev_t *mddev, const char *buf, size_t len) | |||
3089 | if (strncmp(buf, "max", 3) == 0) | 3226 | if (strncmp(buf, "max", 3) == 0) |
3090 | mddev->resync_max = MaxSector; | 3227 | mddev->resync_max = MaxSector; |
3091 | else { | 3228 | else { |
3092 | char *ep; | 3229 | unsigned long long max; |
3093 | unsigned long long max = simple_strtoull(buf, &ep, 10); | 3230 | if (strict_strtoull(buf, 10, &max)) |
3094 | if (ep == buf || (*ep != 0 && *ep != '\n')) | 3231 | return -EINVAL; |
3232 | if (max < mddev->resync_min) | ||
3095 | return -EINVAL; | 3233 | return -EINVAL; |
3096 | if (max < mddev->resync_max && | 3234 | if (max < mddev->resync_max && |
3097 | test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) | 3235 | test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) |
@@ -3222,6 +3360,7 @@ static struct attribute *md_redundancy_attrs[] = { | |||
3222 | &md_sync_speed.attr, | 3360 | &md_sync_speed.attr, |
3223 | &md_sync_force_parallel.attr, | 3361 | &md_sync_force_parallel.attr, |
3224 | &md_sync_completed.attr, | 3362 | &md_sync_completed.attr, |
3363 | &md_min_sync.attr, | ||
3225 | &md_max_sync.attr, | 3364 | &md_max_sync.attr, |
3226 | &md_suspend_lo.attr, | 3365 | &md_suspend_lo.attr, |
3227 | &md_suspend_hi.attr, | 3366 | &md_suspend_hi.attr, |
@@ -3326,9 +3465,9 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data) | |||
3326 | disk->queue = mddev->queue; | 3465 | disk->queue = mddev->queue; |
3327 | add_disk(disk); | 3466 | add_disk(disk); |
3328 | mddev->gendisk = disk; | 3467 | mddev->gendisk = disk; |
3329 | mutex_unlock(&disks_mutex); | ||
3330 | error = kobject_init_and_add(&mddev->kobj, &md_ktype, &disk->dev.kobj, | 3468 | error = kobject_init_and_add(&mddev->kobj, &md_ktype, &disk->dev.kobj, |
3331 | "%s", "md"); | 3469 | "%s", "md"); |
3470 | mutex_unlock(&disks_mutex); | ||
3332 | if (error) | 3471 | if (error) |
3333 | printk(KERN_WARNING "md: cannot register %s/md - name in use\n", | 3472 | printk(KERN_WARNING "md: cannot register %s/md - name in use\n", |
3334 | disk->disk_name); | 3473 | disk->disk_name); |
@@ -3341,7 +3480,11 @@ static void md_safemode_timeout(unsigned long data) | |||
3341 | { | 3480 | { |
3342 | mddev_t *mddev = (mddev_t *) data; | 3481 | mddev_t *mddev = (mddev_t *) data; |
3343 | 3482 | ||
3344 | mddev->safemode = 1; | 3483 | if (!atomic_read(&mddev->writes_pending)) { |
3484 | mddev->safemode = 1; | ||
3485 | if (mddev->external) | ||
3486 | sysfs_notify(&mddev->kobj, NULL, "array_state"); | ||
3487 | } | ||
3345 | md_wakeup_thread(mddev->thread); | 3488 | md_wakeup_thread(mddev->thread); |
3346 | } | 3489 | } |
3347 | 3490 | ||
@@ -3432,22 +3575,23 @@ static int do_md_run(mddev_t * mddev) | |||
3432 | * We don't want the data to overlap the metadata, | 3575 | * We don't want the data to overlap the metadata, |
3433 | * Internal Bitmap issues has handled elsewhere. | 3576 | * Internal Bitmap issues has handled elsewhere. |
3434 | */ | 3577 | */ |
3435 | if (rdev->data_offset < rdev->sb_offset) { | 3578 | if (rdev->data_offset < rdev->sb_start) { |
3436 | if (mddev->size && | 3579 | if (mddev->size && |
3437 | rdev->data_offset + mddev->size*2 | 3580 | rdev->data_offset + mddev->size*2 |
3438 | > rdev->sb_offset*2) { | 3581 | > rdev->sb_start) { |
3439 | printk("md: %s: data overlaps metadata\n", | 3582 | printk("md: %s: data overlaps metadata\n", |
3440 | mdname(mddev)); | 3583 | mdname(mddev)); |
3441 | return -EINVAL; | 3584 | return -EINVAL; |
3442 | } | 3585 | } |
3443 | } else { | 3586 | } else { |
3444 | if (rdev->sb_offset*2 + rdev->sb_size/512 | 3587 | if (rdev->sb_start + rdev->sb_size/512 |
3445 | > rdev->data_offset) { | 3588 | > rdev->data_offset) { |
3446 | printk("md: %s: metadata overlaps data\n", | 3589 | printk("md: %s: metadata overlaps data\n", |
3447 | mdname(mddev)); | 3590 | mdname(mddev)); |
3448 | return -EINVAL; | 3591 | return -EINVAL; |
3449 | } | 3592 | } |
3450 | } | 3593 | } |
3594 | sysfs_notify(&rdev->kobj, NULL, "state"); | ||
3451 | } | 3595 | } |
3452 | 3596 | ||
3453 | md_probe(mddev->unit, NULL, NULL); | 3597 | md_probe(mddev->unit, NULL, NULL); |
@@ -3519,7 +3663,9 @@ static int do_md_run(mddev_t * mddev) | |||
3519 | mddev->ro = 2; /* read-only, but switch on first write */ | 3663 | mddev->ro = 2; /* read-only, but switch on first write */ |
3520 | 3664 | ||
3521 | err = mddev->pers->run(mddev); | 3665 | err = mddev->pers->run(mddev); |
3522 | if (!err && mddev->pers->sync_request) { | 3666 | if (err) |
3667 | printk(KERN_ERR "md: pers->run() failed ...\n"); | ||
3668 | else if (mddev->pers->sync_request) { | ||
3523 | err = bitmap_create(mddev); | 3669 | err = bitmap_create(mddev); |
3524 | if (err) { | 3670 | if (err) { |
3525 | printk(KERN_ERR "%s: failed to create bitmap (%d)\n", | 3671 | printk(KERN_ERR "%s: failed to create bitmap (%d)\n", |
@@ -3528,7 +3674,6 @@ static int do_md_run(mddev_t * mddev) | |||
3528 | } | 3674 | } |
3529 | } | 3675 | } |
3530 | if (err) { | 3676 | if (err) { |
3531 | printk(KERN_ERR "md: pers->run() failed ...\n"); | ||
3532 | module_put(mddev->pers->owner); | 3677 | module_put(mddev->pers->owner); |
3533 | mddev->pers = NULL; | 3678 | mddev->pers = NULL; |
3534 | bitmap_destroy(mddev); | 3679 | bitmap_destroy(mddev); |
@@ -3563,7 +3708,7 @@ static int do_md_run(mddev_t * mddev) | |||
3563 | if (mddev->flags) | 3708 | if (mddev->flags) |
3564 | md_update_sb(mddev, 0); | 3709 | md_update_sb(mddev, 0); |
3565 | 3710 | ||
3566 | set_capacity(disk, mddev->array_size<<1); | 3711 | set_capacity(disk, mddev->array_sectors); |
3567 | 3712 | ||
3568 | /* If we call blk_queue_make_request here, it will | 3713 | /* If we call blk_queue_make_request here, it will |
3569 | * re-initialise max_sectors etc which may have been | 3714 | * re-initialise max_sectors etc which may have been |
@@ -3608,6 +3753,9 @@ static int do_md_run(mddev_t * mddev) | |||
3608 | 3753 | ||
3609 | mddev->changed = 1; | 3754 | mddev->changed = 1; |
3610 | md_new_event(mddev); | 3755 | md_new_event(mddev); |
3756 | sysfs_notify(&mddev->kobj, NULL, "array_state"); | ||
3757 | sysfs_notify(&mddev->kobj, NULL, "sync_action"); | ||
3758 | sysfs_notify(&mddev->kobj, NULL, "degraded"); | ||
3611 | kobject_uevent(&mddev->gendisk->dev.kobj, KOBJ_CHANGE); | 3759 | kobject_uevent(&mddev->gendisk->dev.kobj, KOBJ_CHANGE); |
3612 | return 0; | 3760 | return 0; |
3613 | } | 3761 | } |
@@ -3615,38 +3763,25 @@ static int do_md_run(mddev_t * mddev) | |||
3615 | static int restart_array(mddev_t *mddev) | 3763 | static int restart_array(mddev_t *mddev) |
3616 | { | 3764 | { |
3617 | struct gendisk *disk = mddev->gendisk; | 3765 | struct gendisk *disk = mddev->gendisk; |
3618 | int err; | ||
3619 | 3766 | ||
3620 | /* | 3767 | /* Complain if it has no devices */ |
3621 | * Complain if it has no devices | ||
3622 | */ | ||
3623 | err = -ENXIO; | ||
3624 | if (list_empty(&mddev->disks)) | 3768 | if (list_empty(&mddev->disks)) |
3625 | goto out; | 3769 | return -ENXIO; |
3626 | 3770 | if (!mddev->pers) | |
3627 | if (mddev->pers) { | 3771 | return -EINVAL; |
3628 | err = -EBUSY; | 3772 | if (!mddev->ro) |
3629 | if (!mddev->ro) | 3773 | return -EBUSY; |
3630 | goto out; | 3774 | mddev->safemode = 0; |
3631 | 3775 | mddev->ro = 0; | |
3632 | mddev->safemode = 0; | 3776 | set_disk_ro(disk, 0); |
3633 | mddev->ro = 0; | 3777 | printk(KERN_INFO "md: %s switched to read-write mode.\n", |
3634 | set_disk_ro(disk, 0); | 3778 | mdname(mddev)); |
3635 | 3779 | /* Kick recovery or resync if necessary */ | |
3636 | printk(KERN_INFO "md: %s switched to read-write mode.\n", | 3780 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
3637 | mdname(mddev)); | 3781 | md_wakeup_thread(mddev->thread); |
3638 | /* | 3782 | md_wakeup_thread(mddev->sync_thread); |
3639 | * Kick recovery or resync if necessary | 3783 | sysfs_notify(&mddev->kobj, NULL, "array_state"); |
3640 | */ | 3784 | return 0; |
3641 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | ||
3642 | md_wakeup_thread(mddev->thread); | ||
3643 | md_wakeup_thread(mddev->sync_thread); | ||
3644 | err = 0; | ||
3645 | } else | ||
3646 | err = -EINVAL; | ||
3647 | |||
3648 | out: | ||
3649 | return err; | ||
3650 | } | 3785 | } |
3651 | 3786 | ||
3652 | /* similar to deny_write_access, but accounts for our holding a reference | 3787 | /* similar to deny_write_access, but accounts for our holding a reference |
@@ -3680,16 +3815,17 @@ static void restore_bitmap_write_access(struct file *file) | |||
3680 | * 1 - switch to readonly | 3815 | * 1 - switch to readonly |
3681 | * 2 - stop but do not disassemble array | 3816 | * 2 - stop but do not disassemble array |
3682 | */ | 3817 | */ |
3683 | static int do_md_stop(mddev_t * mddev, int mode) | 3818 | static int do_md_stop(mddev_t * mddev, int mode, int is_open) |
3684 | { | 3819 | { |
3685 | int err = 0; | 3820 | int err = 0; |
3686 | struct gendisk *disk = mddev->gendisk; | 3821 | struct gendisk *disk = mddev->gendisk; |
3687 | 3822 | ||
3823 | if (atomic_read(&mddev->openers) > is_open) { | ||
3824 | printk("md: %s still in use.\n",mdname(mddev)); | ||
3825 | return -EBUSY; | ||
3826 | } | ||
3827 | |||
3688 | if (mddev->pers) { | 3828 | if (mddev->pers) { |
3689 | if (atomic_read(&mddev->active)>2) { | ||
3690 | printk("md: %s still in use.\n",mdname(mddev)); | ||
3691 | return -EBUSY; | ||
3692 | } | ||
3693 | 3829 | ||
3694 | if (mddev->sync_thread) { | 3830 | if (mddev->sync_thread) { |
3695 | set_bit(MD_RECOVERY_FROZEN, &mddev->recovery); | 3831 | set_bit(MD_RECOVERY_FROZEN, &mddev->recovery); |
@@ -3773,10 +3909,11 @@ static int do_md_stop(mddev_t * mddev, int mode) | |||
3773 | 3909 | ||
3774 | export_array(mddev); | 3910 | export_array(mddev); |
3775 | 3911 | ||
3776 | mddev->array_size = 0; | 3912 | mddev->array_sectors = 0; |
3777 | mddev->size = 0; | 3913 | mddev->size = 0; |
3778 | mddev->raid_disks = 0; | 3914 | mddev->raid_disks = 0; |
3779 | mddev->recovery_cp = 0; | 3915 | mddev->recovery_cp = 0; |
3916 | mddev->resync_min = 0; | ||
3780 | mddev->resync_max = MaxSector; | 3917 | mddev->resync_max = MaxSector; |
3781 | mddev->reshape_position = MaxSector; | 3918 | mddev->reshape_position = MaxSector; |
3782 | mddev->external = 0; | 3919 | mddev->external = 0; |
@@ -3811,6 +3948,7 @@ static int do_md_stop(mddev_t * mddev, int mode) | |||
3811 | mdname(mddev)); | 3948 | mdname(mddev)); |
3812 | err = 0; | 3949 | err = 0; |
3813 | md_new_event(mddev); | 3950 | md_new_event(mddev); |
3951 | sysfs_notify(&mddev->kobj, NULL, "array_state"); | ||
3814 | out: | 3952 | out: |
3815 | return err; | 3953 | return err; |
3816 | } | 3954 | } |
@@ -3836,7 +3974,7 @@ static void autorun_array(mddev_t *mddev) | |||
3836 | err = do_md_run (mddev); | 3974 | err = do_md_run (mddev); |
3837 | if (err) { | 3975 | if (err) { |
3838 | printk(KERN_WARNING "md: do_md_run() returned %d\n", err); | 3976 | printk(KERN_WARNING "md: do_md_run() returned %d\n", err); |
3839 | do_md_stop (mddev, 0); | 3977 | do_md_stop (mddev, 0, 0); |
3840 | } | 3978 | } |
3841 | } | 3979 | } |
3842 | 3980 | ||
@@ -3927,8 +4065,10 @@ static void autorun_devices(int part) | |||
3927 | /* on success, candidates will be empty, on error | 4065 | /* on success, candidates will be empty, on error |
3928 | * it won't... | 4066 | * it won't... |
3929 | */ | 4067 | */ |
3930 | rdev_for_each_list(rdev, tmp, candidates) | 4068 | rdev_for_each_list(rdev, tmp, candidates) { |
4069 | list_del_init(&rdev->same_set); | ||
3931 | export_rdev(rdev); | 4070 | export_rdev(rdev); |
4071 | } | ||
3932 | mddev_put(mddev); | 4072 | mddev_put(mddev); |
3933 | } | 4073 | } |
3934 | printk(KERN_INFO "md: ... autorun DONE.\n"); | 4074 | printk(KERN_INFO "md: ... autorun DONE.\n"); |
@@ -4009,9 +4149,11 @@ static int get_bitmap_file(mddev_t * mddev, void __user * arg) | |||
4009 | char *ptr, *buf = NULL; | 4149 | char *ptr, *buf = NULL; |
4010 | int err = -ENOMEM; | 4150 | int err = -ENOMEM; |
4011 | 4151 | ||
4012 | md_allow_write(mddev); | 4152 | if (md_allow_write(mddev)) |
4153 | file = kmalloc(sizeof(*file), GFP_NOIO); | ||
4154 | else | ||
4155 | file = kmalloc(sizeof(*file), GFP_KERNEL); | ||
4013 | 4156 | ||
4014 | file = kmalloc(sizeof(*file), GFP_KERNEL); | ||
4015 | if (!file) | 4157 | if (!file) |
4016 | goto out; | 4158 | goto out; |
4017 | 4159 | ||
@@ -4044,15 +4186,12 @@ out: | |||
4044 | static int get_disk_info(mddev_t * mddev, void __user * arg) | 4186 | static int get_disk_info(mddev_t * mddev, void __user * arg) |
4045 | { | 4187 | { |
4046 | mdu_disk_info_t info; | 4188 | mdu_disk_info_t info; |
4047 | unsigned int nr; | ||
4048 | mdk_rdev_t *rdev; | 4189 | mdk_rdev_t *rdev; |
4049 | 4190 | ||
4050 | if (copy_from_user(&info, arg, sizeof(info))) | 4191 | if (copy_from_user(&info, arg, sizeof(info))) |
4051 | return -EFAULT; | 4192 | return -EFAULT; |
4052 | 4193 | ||
4053 | nr = info.number; | 4194 | rdev = find_rdev_nr(mddev, info.number); |
4054 | |||
4055 | rdev = find_rdev_nr(mddev, nr); | ||
4056 | if (rdev) { | 4195 | if (rdev) { |
4057 | info.major = MAJOR(rdev->bdev->bd_dev); | 4196 | info.major = MAJOR(rdev->bdev->bd_dev); |
4058 | info.minor = MINOR(rdev->bdev->bd_dev); | 4197 | info.minor = MINOR(rdev->bdev->bd_dev); |
@@ -4172,8 +4311,12 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) | |||
4172 | } | 4311 | } |
4173 | if (err) | 4312 | if (err) |
4174 | export_rdev(rdev); | 4313 | export_rdev(rdev); |
4314 | else | ||
4315 | sysfs_notify(&rdev->kobj, NULL, "state"); | ||
4175 | 4316 | ||
4176 | md_update_sb(mddev, 1); | 4317 | md_update_sb(mddev, 1); |
4318 | if (mddev->degraded) | ||
4319 | set_bit(MD_RECOVERY_RECOVER, &mddev->recovery); | ||
4177 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 4320 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
4178 | md_wakeup_thread(mddev->thread); | 4321 | md_wakeup_thread(mddev->thread); |
4179 | return err; | 4322 | return err; |
@@ -4212,10 +4355,10 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) | |||
4212 | 4355 | ||
4213 | if (!mddev->persistent) { | 4356 | if (!mddev->persistent) { |
4214 | printk(KERN_INFO "md: nonpersistent superblock ...\n"); | 4357 | printk(KERN_INFO "md: nonpersistent superblock ...\n"); |
4215 | rdev->sb_offset = rdev->bdev->bd_inode->i_size >> BLOCK_SIZE_BITS; | 4358 | rdev->sb_start = rdev->bdev->bd_inode->i_size / 512; |
4216 | } else | 4359 | } else |
4217 | rdev->sb_offset = calc_dev_sboffset(rdev->bdev); | 4360 | rdev->sb_start = calc_dev_sboffset(rdev->bdev); |
4218 | rdev->size = calc_dev_size(rdev, mddev->chunk_size); | 4361 | rdev->size = calc_num_sectors(rdev, mddev->chunk_size) / 2; |
4219 | 4362 | ||
4220 | err = bind_rdev_to_array(rdev, mddev); | 4363 | err = bind_rdev_to_array(rdev, mddev); |
4221 | if (err) { | 4364 | if (err) { |
@@ -4232,9 +4375,6 @@ static int hot_remove_disk(mddev_t * mddev, dev_t dev) | |||
4232 | char b[BDEVNAME_SIZE]; | 4375 | char b[BDEVNAME_SIZE]; |
4233 | mdk_rdev_t *rdev; | 4376 | mdk_rdev_t *rdev; |
4234 | 4377 | ||
4235 | if (!mddev->pers) | ||
4236 | return -ENODEV; | ||
4237 | |||
4238 | rdev = find_rdev(mddev, dev); | 4378 | rdev = find_rdev(mddev, dev); |
4239 | if (!rdev) | 4379 | if (!rdev) |
4240 | return -ENXIO; | 4380 | return -ENXIO; |
@@ -4257,7 +4397,6 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev) | |||
4257 | { | 4397 | { |
4258 | char b[BDEVNAME_SIZE]; | 4398 | char b[BDEVNAME_SIZE]; |
4259 | int err; | 4399 | int err; |
4260 | unsigned int size; | ||
4261 | mdk_rdev_t *rdev; | 4400 | mdk_rdev_t *rdev; |
4262 | 4401 | ||
4263 | if (!mddev->pers) | 4402 | if (!mddev->pers) |
@@ -4285,13 +4424,11 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev) | |||
4285 | } | 4424 | } |
4286 | 4425 | ||
4287 | if (mddev->persistent) | 4426 | if (mddev->persistent) |
4288 | rdev->sb_offset = calc_dev_sboffset(rdev->bdev); | 4427 | rdev->sb_start = calc_dev_sboffset(rdev->bdev); |
4289 | else | 4428 | else |
4290 | rdev->sb_offset = | 4429 | rdev->sb_start = rdev->bdev->bd_inode->i_size / 512; |
4291 | rdev->bdev->bd_inode->i_size >> BLOCK_SIZE_BITS; | ||
4292 | 4430 | ||
4293 | size = calc_dev_size(rdev, mddev->chunk_size); | 4431 | rdev->size = calc_num_sectors(rdev, mddev->chunk_size) / 2; |
4294 | rdev->size = size; | ||
4295 | 4432 | ||
4296 | if (test_bit(Faulty, &rdev->flags)) { | 4433 | if (test_bit(Faulty, &rdev->flags)) { |
4297 | printk(KERN_WARNING | 4434 | printk(KERN_WARNING |
@@ -4476,24 +4613,24 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info) | |||
4476 | return 0; | 4613 | return 0; |
4477 | } | 4614 | } |
4478 | 4615 | ||
4479 | static int update_size(mddev_t *mddev, unsigned long size) | 4616 | static int update_size(mddev_t *mddev, sector_t num_sectors) |
4480 | { | 4617 | { |
4481 | mdk_rdev_t * rdev; | 4618 | mdk_rdev_t * rdev; |
4482 | int rv; | 4619 | int rv; |
4483 | struct list_head *tmp; | 4620 | struct list_head *tmp; |
4484 | int fit = (size == 0); | 4621 | int fit = (num_sectors == 0); |
4485 | 4622 | ||
4486 | if (mddev->pers->resize == NULL) | 4623 | if (mddev->pers->resize == NULL) |
4487 | return -EINVAL; | 4624 | return -EINVAL; |
4488 | /* The "size" is the amount of each device that is used. | 4625 | /* The "num_sectors" is the number of sectors of each device that |
4489 | * This can only make sense for arrays with redundancy. | 4626 | * is used. This can only make sense for arrays with redundancy. |
4490 | * linear and raid0 always use whatever space is available | 4627 | * linear and raid0 always use whatever space is available. We can only |
4491 | * We can only consider changing the size if no resync | 4628 | * consider changing this number if no resync or reconstruction is |
4492 | * or reconstruction is happening, and if the new size | 4629 | * happening, and if the new size is acceptable. It must fit before the |
4493 | * is acceptable. It must fit before the sb_offset or, | 4630 | * sb_start or, if that is <data_offset, it must fit before the size |
4494 | * if that is <data_offset, it must fit before the | 4631 | * of each device. If num_sectors is zero, we find the largest size |
4495 | * size of each device. | 4632 | * that fits. |
4496 | * If size is zero, we find the largest size that fits. | 4633 | |
4497 | */ | 4634 | */ |
4498 | if (mddev->sync_thread) | 4635 | if (mddev->sync_thread) |
4499 | return -EBUSY; | 4636 | return -EBUSY; |
@@ -4501,19 +4638,20 @@ static int update_size(mddev_t *mddev, unsigned long size) | |||
4501 | sector_t avail; | 4638 | sector_t avail; |
4502 | avail = rdev->size * 2; | 4639 | avail = rdev->size * 2; |
4503 | 4640 | ||
4504 | if (fit && (size == 0 || size > avail/2)) | 4641 | if (fit && (num_sectors == 0 || num_sectors > avail)) |
4505 | size = avail/2; | 4642 | num_sectors = avail; |
4506 | if (avail < ((sector_t)size << 1)) | 4643 | if (avail < num_sectors) |
4507 | return -ENOSPC; | 4644 | return -ENOSPC; |
4508 | } | 4645 | } |
4509 | rv = mddev->pers->resize(mddev, (sector_t)size *2); | 4646 | rv = mddev->pers->resize(mddev, num_sectors); |
4510 | if (!rv) { | 4647 | if (!rv) { |
4511 | struct block_device *bdev; | 4648 | struct block_device *bdev; |
4512 | 4649 | ||
4513 | bdev = bdget_disk(mddev->gendisk, 0); | 4650 | bdev = bdget_disk(mddev->gendisk, 0); |
4514 | if (bdev) { | 4651 | if (bdev) { |
4515 | mutex_lock(&bdev->bd_inode->i_mutex); | 4652 | mutex_lock(&bdev->bd_inode->i_mutex); |
4516 | i_size_write(bdev->bd_inode, (loff_t)mddev->array_size << 10); | 4653 | i_size_write(bdev->bd_inode, |
4654 | (loff_t)mddev->array_sectors << 9); | ||
4517 | mutex_unlock(&bdev->bd_inode->i_mutex); | 4655 | mutex_unlock(&bdev->bd_inode->i_mutex); |
4518 | bdput(bdev); | 4656 | bdput(bdev); |
4519 | } | 4657 | } |
@@ -4588,7 +4726,7 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info) | |||
4588 | return mddev->pers->reconfig(mddev, info->layout, -1); | 4726 | return mddev->pers->reconfig(mddev, info->layout, -1); |
4589 | } | 4727 | } |
4590 | if (info->size >= 0 && mddev->size != info->size) | 4728 | if (info->size >= 0 && mddev->size != info->size) |
4591 | rv = update_size(mddev, info->size); | 4729 | rv = update_size(mddev, (sector_t)info->size * 2); |
4592 | 4730 | ||
4593 | if (mddev->raid_disks != info->raid_disks) | 4731 | if (mddev->raid_disks != info->raid_disks) |
4594 | rv = update_raid_disks(mddev, info->raid_disks); | 4732 | rv = update_raid_disks(mddev, info->raid_disks); |
@@ -4641,6 +4779,12 @@ static int set_disk_faulty(mddev_t *mddev, dev_t dev) | |||
4641 | return 0; | 4779 | return 0; |
4642 | } | 4780 | } |
4643 | 4781 | ||
4782 | /* | ||
4783 | * We have a problem here : there is no easy way to give a CHS | ||
4784 | * virtual geometry. We currently pretend that we have a 2 heads | ||
4785 | * 4 sectors (with a BIG number of cylinders...). This drives | ||
4786 | * dosfs just mad... ;-) | ||
4787 | */ | ||
4644 | static int md_getgeo(struct block_device *bdev, struct hd_geometry *geo) | 4788 | static int md_getgeo(struct block_device *bdev, struct hd_geometry *geo) |
4645 | { | 4789 | { |
4646 | mddev_t *mddev = bdev->bd_disk->private_data; | 4790 | mddev_t *mddev = bdev->bd_disk->private_data; |
@@ -4785,19 +4929,13 @@ static int md_ioctl(struct inode *inode, struct file *file, | |||
4785 | goto done_unlock; | 4929 | goto done_unlock; |
4786 | 4930 | ||
4787 | case STOP_ARRAY: | 4931 | case STOP_ARRAY: |
4788 | err = do_md_stop (mddev, 0); | 4932 | err = do_md_stop (mddev, 0, 1); |
4789 | goto done_unlock; | 4933 | goto done_unlock; |
4790 | 4934 | ||
4791 | case STOP_ARRAY_RO: | 4935 | case STOP_ARRAY_RO: |
4792 | err = do_md_stop (mddev, 1); | 4936 | err = do_md_stop (mddev, 1, 1); |
4793 | goto done_unlock; | 4937 | goto done_unlock; |
4794 | 4938 | ||
4795 | /* | ||
4796 | * We have a problem here : there is no easy way to give a CHS | ||
4797 | * virtual geometry. We currently pretend that we have a 2 heads | ||
4798 | * 4 sectors (with a BIG number of cylinders...). This drives | ||
4799 | * dosfs just mad... ;-) | ||
4800 | */ | ||
4801 | } | 4939 | } |
4802 | 4940 | ||
4803 | /* | 4941 | /* |
@@ -4807,13 +4945,12 @@ static int md_ioctl(struct inode *inode, struct file *file, | |||
4807 | * here and hit the 'default' below, so only disallow | 4945 | * here and hit the 'default' below, so only disallow |
4808 | * 'md' ioctls, and switch to rw mode if started auto-readonly. | 4946 | * 'md' ioctls, and switch to rw mode if started auto-readonly. |
4809 | */ | 4947 | */ |
4810 | if (_IOC_TYPE(cmd) == MD_MAJOR && | 4948 | if (_IOC_TYPE(cmd) == MD_MAJOR && mddev->ro && mddev->pers) { |
4811 | mddev->ro && mddev->pers) { | ||
4812 | if (mddev->ro == 2) { | 4949 | if (mddev->ro == 2) { |
4813 | mddev->ro = 0; | 4950 | mddev->ro = 0; |
4814 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 4951 | sysfs_notify(&mddev->kobj, NULL, "array_state"); |
4815 | md_wakeup_thread(mddev->thread); | 4952 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
4816 | 4953 | md_wakeup_thread(mddev->thread); | |
4817 | } else { | 4954 | } else { |
4818 | err = -EROFS; | 4955 | err = -EROFS; |
4819 | goto abort_unlock; | 4956 | goto abort_unlock; |
@@ -4883,6 +5020,7 @@ static int md_open(struct inode *inode, struct file *file) | |||
4883 | 5020 | ||
4884 | err = 0; | 5021 | err = 0; |
4885 | mddev_get(mddev); | 5022 | mddev_get(mddev); |
5023 | atomic_inc(&mddev->openers); | ||
4886 | mddev_unlock(mddev); | 5024 | mddev_unlock(mddev); |
4887 | 5025 | ||
4888 | check_disk_change(inode->i_bdev); | 5026 | check_disk_change(inode->i_bdev); |
@@ -4895,6 +5033,7 @@ static int md_release(struct inode *inode, struct file * file) | |||
4895 | mddev_t *mddev = inode->i_bdev->bd_disk->private_data; | 5033 | mddev_t *mddev = inode->i_bdev->bd_disk->private_data; |
4896 | 5034 | ||
4897 | BUG_ON(!mddev); | 5035 | BUG_ON(!mddev); |
5036 | atomic_dec(&mddev->openers); | ||
4898 | mddev_put(mddev); | 5037 | mddev_put(mddev); |
4899 | 5038 | ||
4900 | return 0; | 5039 | return 0; |
@@ -5029,6 +5168,9 @@ void md_error(mddev_t *mddev, mdk_rdev_t *rdev) | |||
5029 | if (!mddev->pers->error_handler) | 5168 | if (!mddev->pers->error_handler) |
5030 | return; | 5169 | return; |
5031 | mddev->pers->error_handler(mddev,rdev); | 5170 | mddev->pers->error_handler(mddev,rdev); |
5171 | if (mddev->degraded) | ||
5172 | set_bit(MD_RECOVERY_RECOVER, &mddev->recovery); | ||
5173 | set_bit(StateChanged, &rdev->flags); | ||
5032 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); | 5174 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
5033 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 5175 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
5034 | md_wakeup_thread(mddev->thread); | 5176 | md_wakeup_thread(mddev->thread); |
@@ -5258,10 +5400,11 @@ static int md_seq_show(struct seq_file *seq, void *v) | |||
5258 | if (!list_empty(&mddev->disks)) { | 5400 | if (!list_empty(&mddev->disks)) { |
5259 | if (mddev->pers) | 5401 | if (mddev->pers) |
5260 | seq_printf(seq, "\n %llu blocks", | 5402 | seq_printf(seq, "\n %llu blocks", |
5261 | (unsigned long long)mddev->array_size); | 5403 | (unsigned long long) |
5404 | mddev->array_sectors / 2); | ||
5262 | else | 5405 | else |
5263 | seq_printf(seq, "\n %llu blocks", | 5406 | seq_printf(seq, "\n %llu blocks", |
5264 | (unsigned long long)size); | 5407 | (unsigned long long)size); |
5265 | } | 5408 | } |
5266 | if (mddev->persistent) { | 5409 | if (mddev->persistent) { |
5267 | if (mddev->major_version != 0 || | 5410 | if (mddev->major_version != 0 || |
@@ -5391,12 +5534,12 @@ int unregister_md_personality(struct mdk_personality *p) | |||
5391 | static int is_mddev_idle(mddev_t *mddev) | 5534 | static int is_mddev_idle(mddev_t *mddev) |
5392 | { | 5535 | { |
5393 | mdk_rdev_t * rdev; | 5536 | mdk_rdev_t * rdev; |
5394 | struct list_head *tmp; | ||
5395 | int idle; | 5537 | int idle; |
5396 | long curr_events; | 5538 | long curr_events; |
5397 | 5539 | ||
5398 | idle = 1; | 5540 | idle = 1; |
5399 | rdev_for_each(rdev, tmp, mddev) { | 5541 | rcu_read_lock(); |
5542 | rdev_for_each_rcu(rdev, mddev) { | ||
5400 | struct gendisk *disk = rdev->bdev->bd_contains->bd_disk; | 5543 | struct gendisk *disk = rdev->bdev->bd_contains->bd_disk; |
5401 | curr_events = disk_stat_read(disk, sectors[0]) + | 5544 | curr_events = disk_stat_read(disk, sectors[0]) + |
5402 | disk_stat_read(disk, sectors[1]) - | 5545 | disk_stat_read(disk, sectors[1]) - |
@@ -5428,6 +5571,7 @@ static int is_mddev_idle(mddev_t *mddev) | |||
5428 | idle = 0; | 5571 | idle = 0; |
5429 | } | 5572 | } |
5430 | } | 5573 | } |
5574 | rcu_read_unlock(); | ||
5431 | return idle; | 5575 | return idle; |
5432 | } | 5576 | } |
5433 | 5577 | ||
@@ -5451,6 +5595,7 @@ void md_done_sync(mddev_t *mddev, int blocks, int ok) | |||
5451 | */ | 5595 | */ |
5452 | void md_write_start(mddev_t *mddev, struct bio *bi) | 5596 | void md_write_start(mddev_t *mddev, struct bio *bi) |
5453 | { | 5597 | { |
5598 | int did_change = 0; | ||
5454 | if (bio_data_dir(bi) != WRITE) | 5599 | if (bio_data_dir(bi) != WRITE) |
5455 | return; | 5600 | return; |
5456 | 5601 | ||
@@ -5461,6 +5606,7 @@ void md_write_start(mddev_t *mddev, struct bio *bi) | |||
5461 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 5606 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
5462 | md_wakeup_thread(mddev->thread); | 5607 | md_wakeup_thread(mddev->thread); |
5463 | md_wakeup_thread(mddev->sync_thread); | 5608 | md_wakeup_thread(mddev->sync_thread); |
5609 | did_change = 1; | ||
5464 | } | 5610 | } |
5465 | atomic_inc(&mddev->writes_pending); | 5611 | atomic_inc(&mddev->writes_pending); |
5466 | if (mddev->safemode == 1) | 5612 | if (mddev->safemode == 1) |
@@ -5471,10 +5617,12 @@ void md_write_start(mddev_t *mddev, struct bio *bi) | |||
5471 | mddev->in_sync = 0; | 5617 | mddev->in_sync = 0; |
5472 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); | 5618 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); |
5473 | md_wakeup_thread(mddev->thread); | 5619 | md_wakeup_thread(mddev->thread); |
5620 | did_change = 1; | ||
5474 | } | 5621 | } |
5475 | spin_unlock_irq(&mddev->write_lock); | 5622 | spin_unlock_irq(&mddev->write_lock); |
5476 | sysfs_notify(&mddev->kobj, NULL, "array_state"); | ||
5477 | } | 5623 | } |
5624 | if (did_change) | ||
5625 | sysfs_notify(&mddev->kobj, NULL, "array_state"); | ||
5478 | wait_event(mddev->sb_wait, | 5626 | wait_event(mddev->sb_wait, |
5479 | !test_bit(MD_CHANGE_CLEAN, &mddev->flags) && | 5627 | !test_bit(MD_CHANGE_CLEAN, &mddev->flags) && |
5480 | !test_bit(MD_CHANGE_PENDING, &mddev->flags)); | 5628 | !test_bit(MD_CHANGE_PENDING, &mddev->flags)); |
@@ -5495,13 +5643,18 @@ void md_write_end(mddev_t *mddev) | |||
5495 | * may proceed without blocking. It is important to call this before | 5643 | * may proceed without blocking. It is important to call this before |
5496 | * attempting a GFP_KERNEL allocation while holding the mddev lock. | 5644 | * attempting a GFP_KERNEL allocation while holding the mddev lock. |
5497 | * Must be called with mddev_lock held. | 5645 | * Must be called with mddev_lock held. |
5646 | * | ||
5647 | * In the ->external case MD_CHANGE_CLEAN can not be cleared until mddev->lock | ||
5648 | * is dropped, so return -EAGAIN after notifying userspace. | ||
5498 | */ | 5649 | */ |
5499 | void md_allow_write(mddev_t *mddev) | 5650 | int md_allow_write(mddev_t *mddev) |
5500 | { | 5651 | { |
5501 | if (!mddev->pers) | 5652 | if (!mddev->pers) |
5502 | return; | 5653 | return 0; |
5503 | if (mddev->ro) | 5654 | if (mddev->ro) |
5504 | return; | 5655 | return 0; |
5656 | if (!mddev->pers->sync_request) | ||
5657 | return 0; | ||
5505 | 5658 | ||
5506 | spin_lock_irq(&mddev->write_lock); | 5659 | spin_lock_irq(&mddev->write_lock); |
5507 | if (mddev->in_sync) { | 5660 | if (mddev->in_sync) { |
@@ -5512,14 +5665,14 @@ void md_allow_write(mddev_t *mddev) | |||
5512 | mddev->safemode = 1; | 5665 | mddev->safemode = 1; |
5513 | spin_unlock_irq(&mddev->write_lock); | 5666 | spin_unlock_irq(&mddev->write_lock); |
5514 | md_update_sb(mddev, 0); | 5667 | md_update_sb(mddev, 0); |
5515 | |||
5516 | sysfs_notify(&mddev->kobj, NULL, "array_state"); | 5668 | sysfs_notify(&mddev->kobj, NULL, "array_state"); |
5517 | /* wait for the dirty state to be recorded in the metadata */ | ||
5518 | wait_event(mddev->sb_wait, | ||
5519 | !test_bit(MD_CHANGE_CLEAN, &mddev->flags) && | ||
5520 | !test_bit(MD_CHANGE_PENDING, &mddev->flags)); | ||
5521 | } else | 5669 | } else |
5522 | spin_unlock_irq(&mddev->write_lock); | 5670 | spin_unlock_irq(&mddev->write_lock); |
5671 | |||
5672 | if (test_bit(MD_CHANGE_CLEAN, &mddev->flags)) | ||
5673 | return -EAGAIN; | ||
5674 | else | ||
5675 | return 0; | ||
5523 | } | 5676 | } |
5524 | EXPORT_SYMBOL_GPL(md_allow_write); | 5677 | EXPORT_SYMBOL_GPL(md_allow_write); |
5525 | 5678 | ||
@@ -5625,9 +5778,11 @@ void md_do_sync(mddev_t *mddev) | |||
5625 | max_sectors = mddev->resync_max_sectors; | 5778 | max_sectors = mddev->resync_max_sectors; |
5626 | mddev->resync_mismatches = 0; | 5779 | mddev->resync_mismatches = 0; |
5627 | /* we don't use the checkpoint if there's a bitmap */ | 5780 | /* we don't use the checkpoint if there's a bitmap */ |
5628 | if (!mddev->bitmap && | 5781 | if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) |
5629 | !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) | 5782 | j = mddev->resync_min; |
5783 | else if (!mddev->bitmap) | ||
5630 | j = mddev->recovery_cp; | 5784 | j = mddev->recovery_cp; |
5785 | |||
5631 | } else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) | 5786 | } else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) |
5632 | max_sectors = mddev->size << 1; | 5787 | max_sectors = mddev->size << 1; |
5633 | else { | 5788 | else { |
@@ -5796,6 +5951,7 @@ void md_do_sync(mddev_t *mddev) | |||
5796 | 5951 | ||
5797 | skip: | 5952 | skip: |
5798 | mddev->curr_resync = 0; | 5953 | mddev->curr_resync = 0; |
5954 | mddev->resync_min = 0; | ||
5799 | mddev->resync_max = MaxSector; | 5955 | mddev->resync_max = MaxSector; |
5800 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); | 5956 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); |
5801 | wake_up(&resync_wait); | 5957 | wake_up(&resync_wait); |
@@ -5845,7 +6001,8 @@ static int remove_and_add_spares(mddev_t *mddev) | |||
5845 | if (rdev->raid_disk < 0 | 6001 | if (rdev->raid_disk < 0 |
5846 | && !test_bit(Faulty, &rdev->flags)) { | 6002 | && !test_bit(Faulty, &rdev->flags)) { |
5847 | rdev->recovery_offset = 0; | 6003 | rdev->recovery_offset = 0; |
5848 | if (mddev->pers->hot_add_disk(mddev,rdev)) { | 6004 | if (mddev->pers-> |
6005 | hot_add_disk(mddev, rdev) == 0) { | ||
5849 | char nm[20]; | 6006 | char nm[20]; |
5850 | sprintf(nm, "rd%d", rdev->raid_disk); | 6007 | sprintf(nm, "rd%d", rdev->raid_disk); |
5851 | if (sysfs_create_link(&mddev->kobj, | 6008 | if (sysfs_create_link(&mddev->kobj, |
@@ -5920,23 +6077,31 @@ void md_check_recovery(mddev_t *mddev) | |||
5920 | int spares = 0; | 6077 | int spares = 0; |
5921 | 6078 | ||
5922 | if (!mddev->external) { | 6079 | if (!mddev->external) { |
6080 | int did_change = 0; | ||
5923 | spin_lock_irq(&mddev->write_lock); | 6081 | spin_lock_irq(&mddev->write_lock); |
5924 | if (mddev->safemode && | 6082 | if (mddev->safemode && |
5925 | !atomic_read(&mddev->writes_pending) && | 6083 | !atomic_read(&mddev->writes_pending) && |
5926 | !mddev->in_sync && | 6084 | !mddev->in_sync && |
5927 | mddev->recovery_cp == MaxSector) { | 6085 | mddev->recovery_cp == MaxSector) { |
5928 | mddev->in_sync = 1; | 6086 | mddev->in_sync = 1; |
6087 | did_change = 1; | ||
5929 | if (mddev->persistent) | 6088 | if (mddev->persistent) |
5930 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); | 6089 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); |
5931 | } | 6090 | } |
5932 | if (mddev->safemode == 1) | 6091 | if (mddev->safemode == 1) |
5933 | mddev->safemode = 0; | 6092 | mddev->safemode = 0; |
5934 | spin_unlock_irq(&mddev->write_lock); | 6093 | spin_unlock_irq(&mddev->write_lock); |
6094 | if (did_change) | ||
6095 | sysfs_notify(&mddev->kobj, NULL, "array_state"); | ||
5935 | } | 6096 | } |
5936 | 6097 | ||
5937 | if (mddev->flags) | 6098 | if (mddev->flags) |
5938 | md_update_sb(mddev, 0); | 6099 | md_update_sb(mddev, 0); |
5939 | 6100 | ||
6101 | rdev_for_each(rdev, rtmp, mddev) | ||
6102 | if (test_and_clear_bit(StateChanged, &rdev->flags)) | ||
6103 | sysfs_notify(&rdev->kobj, NULL, "state"); | ||
6104 | |||
5940 | 6105 | ||
5941 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) && | 6106 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) && |
5942 | !test_bit(MD_RECOVERY_DONE, &mddev->recovery)) { | 6107 | !test_bit(MD_RECOVERY_DONE, &mddev->recovery)) { |
@@ -5951,7 +6116,9 @@ void md_check_recovery(mddev_t *mddev) | |||
5951 | if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { | 6116 | if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { |
5952 | /* success...*/ | 6117 | /* success...*/ |
5953 | /* activate any spares */ | 6118 | /* activate any spares */ |
5954 | mddev->pers->spare_active(mddev); | 6119 | if (mddev->pers->spare_active(mddev)) |
6120 | sysfs_notify(&mddev->kobj, NULL, | ||
6121 | "degraded"); | ||
5955 | } | 6122 | } |
5956 | md_update_sb(mddev, 1); | 6123 | md_update_sb(mddev, 1); |
5957 | 6124 | ||
@@ -5965,13 +6132,18 @@ void md_check_recovery(mddev_t *mddev) | |||
5965 | mddev->recovery = 0; | 6132 | mddev->recovery = 0; |
5966 | /* flag recovery needed just to double check */ | 6133 | /* flag recovery needed just to double check */ |
5967 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 6134 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
6135 | sysfs_notify(&mddev->kobj, NULL, "sync_action"); | ||
5968 | md_new_event(mddev); | 6136 | md_new_event(mddev); |
5969 | goto unlock; | 6137 | goto unlock; |
5970 | } | 6138 | } |
6139 | /* Set RUNNING before clearing NEEDED to avoid | ||
6140 | * any transients in the value of "sync_action". | ||
6141 | */ | ||
6142 | set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); | ||
6143 | clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | ||
5971 | /* Clear some bits that don't mean anything, but | 6144 | /* Clear some bits that don't mean anything, but |
5972 | * might be left set | 6145 | * might be left set |
5973 | */ | 6146 | */ |
5974 | clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | ||
5975 | clear_bit(MD_RECOVERY_INTR, &mddev->recovery); | 6147 | clear_bit(MD_RECOVERY_INTR, &mddev->recovery); |
5976 | clear_bit(MD_RECOVERY_DONE, &mddev->recovery); | 6148 | clear_bit(MD_RECOVERY_DONE, &mddev->recovery); |
5977 | 6149 | ||
@@ -5989,17 +6161,19 @@ void md_check_recovery(mddev_t *mddev) | |||
5989 | /* Cannot proceed */ | 6161 | /* Cannot proceed */ |
5990 | goto unlock; | 6162 | goto unlock; |
5991 | set_bit(MD_RECOVERY_RESHAPE, &mddev->recovery); | 6163 | set_bit(MD_RECOVERY_RESHAPE, &mddev->recovery); |
6164 | clear_bit(MD_RECOVERY_RECOVER, &mddev->recovery); | ||
5992 | } else if ((spares = remove_and_add_spares(mddev))) { | 6165 | } else if ((spares = remove_and_add_spares(mddev))) { |
5993 | clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); | 6166 | clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); |
5994 | clear_bit(MD_RECOVERY_CHECK, &mddev->recovery); | 6167 | clear_bit(MD_RECOVERY_CHECK, &mddev->recovery); |
6168 | set_bit(MD_RECOVERY_RECOVER, &mddev->recovery); | ||
5995 | } else if (mddev->recovery_cp < MaxSector) { | 6169 | } else if (mddev->recovery_cp < MaxSector) { |
5996 | set_bit(MD_RECOVERY_SYNC, &mddev->recovery); | 6170 | set_bit(MD_RECOVERY_SYNC, &mddev->recovery); |
6171 | clear_bit(MD_RECOVERY_RECOVER, &mddev->recovery); | ||
5997 | } else if (!test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) | 6172 | } else if (!test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) |
5998 | /* nothing to be done ... */ | 6173 | /* nothing to be done ... */ |
5999 | goto unlock; | 6174 | goto unlock; |
6000 | 6175 | ||
6001 | if (mddev->pers->sync_request) { | 6176 | if (mddev->pers->sync_request) { |
6002 | set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); | ||
6003 | if (spares && mddev->bitmap && ! mddev->bitmap->file) { | 6177 | if (spares && mddev->bitmap && ! mddev->bitmap->file) { |
6004 | /* We are adding a device or devices to an array | 6178 | /* We are adding a device or devices to an array |
6005 | * which has the bitmap stored on all devices. | 6179 | * which has the bitmap stored on all devices. |
@@ -6018,9 +6192,16 @@ void md_check_recovery(mddev_t *mddev) | |||
6018 | mddev->recovery = 0; | 6192 | mddev->recovery = 0; |
6019 | } else | 6193 | } else |
6020 | md_wakeup_thread(mddev->sync_thread); | 6194 | md_wakeup_thread(mddev->sync_thread); |
6195 | sysfs_notify(&mddev->kobj, NULL, "sync_action"); | ||
6021 | md_new_event(mddev); | 6196 | md_new_event(mddev); |
6022 | } | 6197 | } |
6023 | unlock: | 6198 | unlock: |
6199 | if (!mddev->sync_thread) { | ||
6200 | clear_bit(MD_RECOVERY_RUNNING, &mddev->recovery); | ||
6201 | if (test_and_clear_bit(MD_RECOVERY_RECOVER, | ||
6202 | &mddev->recovery)) | ||
6203 | sysfs_notify(&mddev->kobj, NULL, "sync_action"); | ||
6204 | } | ||
6024 | mddev_unlock(mddev); | 6205 | mddev_unlock(mddev); |
6025 | } | 6206 | } |
6026 | } | 6207 | } |
@@ -6047,7 +6228,7 @@ static int md_notify_reboot(struct notifier_block *this, | |||
6047 | 6228 | ||
6048 | for_each_mddev(mddev, tmp) | 6229 | for_each_mddev(mddev, tmp) |
6049 | if (mddev_trylock(mddev)) { | 6230 | if (mddev_trylock(mddev)) { |
6050 | do_md_stop (mddev, 1); | 6231 | do_md_stop (mddev, 1, 0); |
6051 | mddev_unlock(mddev); | 6232 | mddev_unlock(mddev); |
6052 | } | 6233 | } |
6053 | /* | 6234 | /* |
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index e968116e0de9..c4779ccba1c3 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c | |||
@@ -281,13 +281,18 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | |||
281 | { | 281 | { |
282 | multipath_conf_t *conf = mddev->private; | 282 | multipath_conf_t *conf = mddev->private; |
283 | struct request_queue *q; | 283 | struct request_queue *q; |
284 | int found = 0; | 284 | int err = -EEXIST; |
285 | int path; | 285 | int path; |
286 | struct multipath_info *p; | 286 | struct multipath_info *p; |
287 | int first = 0; | ||
288 | int last = mddev->raid_disks - 1; | ||
289 | |||
290 | if (rdev->raid_disk >= 0) | ||
291 | first = last = rdev->raid_disk; | ||
287 | 292 | ||
288 | print_multipath_conf(conf); | 293 | print_multipath_conf(conf); |
289 | 294 | ||
290 | for (path=0; path<mddev->raid_disks; path++) | 295 | for (path = first; path <= last; path++) |
291 | if ((p=conf->multipaths+path)->rdev == NULL) { | 296 | if ((p=conf->multipaths+path)->rdev == NULL) { |
292 | q = rdev->bdev->bd_disk->queue; | 297 | q = rdev->bdev->bd_disk->queue; |
293 | blk_queue_stack_limits(mddev->queue, q); | 298 | blk_queue_stack_limits(mddev->queue, q); |
@@ -307,11 +312,13 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | |||
307 | rdev->raid_disk = path; | 312 | rdev->raid_disk = path; |
308 | set_bit(In_sync, &rdev->flags); | 313 | set_bit(In_sync, &rdev->flags); |
309 | rcu_assign_pointer(p->rdev, rdev); | 314 | rcu_assign_pointer(p->rdev, rdev); |
310 | found = 1; | 315 | err = 0; |
316 | break; | ||
311 | } | 317 | } |
312 | 318 | ||
313 | print_multipath_conf(conf); | 319 | print_multipath_conf(conf); |
314 | return found; | 320 | |
321 | return err; | ||
315 | } | 322 | } |
316 | 323 | ||
317 | static int multipath_remove_disk(mddev_t *mddev, int number) | 324 | static int multipath_remove_disk(mddev_t *mddev, int number) |
@@ -497,7 +504,7 @@ static int multipath_run (mddev_t *mddev) | |||
497 | /* | 504 | /* |
498 | * Ok, everything is just fine now | 505 | * Ok, everything is just fine now |
499 | */ | 506 | */ |
500 | mddev->array_size = mddev->size; | 507 | mddev->array_sectors = mddev->size * 2; |
501 | 508 | ||
502 | mddev->queue->unplug_fn = multipath_unplug; | 509 | mddev->queue->unplug_fn = multipath_unplug; |
503 | mddev->queue->backing_dev_info.congested_fn = multipath_congested; | 510 | mddev->queue->backing_dev_info.congested_fn = multipath_congested; |
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index bcbb82594a19..183610635661 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c | |||
@@ -295,16 +295,16 @@ static int raid0_run (mddev_t *mddev) | |||
295 | goto out_free_conf; | 295 | goto out_free_conf; |
296 | 296 | ||
297 | /* calculate array device size */ | 297 | /* calculate array device size */ |
298 | mddev->array_size = 0; | 298 | mddev->array_sectors = 0; |
299 | rdev_for_each(rdev, tmp, mddev) | 299 | rdev_for_each(rdev, tmp, mddev) |
300 | mddev->array_size += rdev->size; | 300 | mddev->array_sectors += rdev->size * 2; |
301 | 301 | ||
302 | printk("raid0 : md_size is %llu blocks.\n", | 302 | printk("raid0 : md_size is %llu blocks.\n", |
303 | (unsigned long long)mddev->array_size); | 303 | (unsigned long long)mddev->array_sectors / 2); |
304 | printk("raid0 : conf->hash_spacing is %llu blocks.\n", | 304 | printk("raid0 : conf->hash_spacing is %llu blocks.\n", |
305 | (unsigned long long)conf->hash_spacing); | 305 | (unsigned long long)conf->hash_spacing); |
306 | { | 306 | { |
307 | sector_t s = mddev->array_size; | 307 | sector_t s = mddev->array_sectors / 2; |
308 | sector_t space = conf->hash_spacing; | 308 | sector_t space = conf->hash_spacing; |
309 | int round; | 309 | int round; |
310 | conf->preshift = 0; | 310 | conf->preshift = 0; |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index c610b947218a..03a5ab705c20 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -1100,11 +1100,16 @@ static int raid1_spare_active(mddev_t *mddev) | |||
1100 | static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | 1100 | static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) |
1101 | { | 1101 | { |
1102 | conf_t *conf = mddev->private; | 1102 | conf_t *conf = mddev->private; |
1103 | int found = 0; | 1103 | int err = -EEXIST; |
1104 | int mirror = 0; | 1104 | int mirror = 0; |
1105 | mirror_info_t *p; | 1105 | mirror_info_t *p; |
1106 | int first = 0; | ||
1107 | int last = mddev->raid_disks - 1; | ||
1106 | 1108 | ||
1107 | for (mirror=0; mirror < mddev->raid_disks; mirror++) | 1109 | if (rdev->raid_disk >= 0) |
1110 | first = last = rdev->raid_disk; | ||
1111 | |||
1112 | for (mirror = first; mirror <= last; mirror++) | ||
1108 | if ( !(p=conf->mirrors+mirror)->rdev) { | 1113 | if ( !(p=conf->mirrors+mirror)->rdev) { |
1109 | 1114 | ||
1110 | blk_queue_stack_limits(mddev->queue, | 1115 | blk_queue_stack_limits(mddev->queue, |
@@ -1119,7 +1124,7 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1119 | 1124 | ||
1120 | p->head_position = 0; | 1125 | p->head_position = 0; |
1121 | rdev->raid_disk = mirror; | 1126 | rdev->raid_disk = mirror; |
1122 | found = 1; | 1127 | err = 0; |
1123 | /* As all devices are equivalent, we don't need a full recovery | 1128 | /* As all devices are equivalent, we don't need a full recovery |
1124 | * if this was recently any drive of the array | 1129 | * if this was recently any drive of the array |
1125 | */ | 1130 | */ |
@@ -1130,7 +1135,7 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1130 | } | 1135 | } |
1131 | 1136 | ||
1132 | print_conf(conf); | 1137 | print_conf(conf); |
1133 | return found; | 1138 | return err; |
1134 | } | 1139 | } |
1135 | 1140 | ||
1136 | static int raid1_remove_disk(mddev_t *mddev, int number) | 1141 | static int raid1_remove_disk(mddev_t *mddev, int number) |
@@ -2038,7 +2043,7 @@ static int run(mddev_t *mddev) | |||
2038 | /* | 2043 | /* |
2039 | * Ok, everything is just fine now | 2044 | * Ok, everything is just fine now |
2040 | */ | 2045 | */ |
2041 | mddev->array_size = mddev->size; | 2046 | mddev->array_sectors = mddev->size * 2; |
2042 | 2047 | ||
2043 | mddev->queue->unplug_fn = raid1_unplug; | 2048 | mddev->queue->unplug_fn = raid1_unplug; |
2044 | mddev->queue->backing_dev_info.congested_fn = raid1_congested; | 2049 | mddev->queue->backing_dev_info.congested_fn = raid1_congested; |
@@ -2100,14 +2105,15 @@ static int raid1_resize(mddev_t *mddev, sector_t sectors) | |||
2100 | * any io in the removed space completes, but it hardly seems | 2105 | * any io in the removed space completes, but it hardly seems |
2101 | * worth it. | 2106 | * worth it. |
2102 | */ | 2107 | */ |
2103 | mddev->array_size = sectors>>1; | 2108 | mddev->array_sectors = sectors; |
2104 | set_capacity(mddev->gendisk, mddev->array_size << 1); | 2109 | set_capacity(mddev->gendisk, mddev->array_sectors); |
2105 | mddev->changed = 1; | 2110 | mddev->changed = 1; |
2106 | if (mddev->array_size > mddev->size && mddev->recovery_cp == MaxSector) { | 2111 | if (mddev->array_sectors / 2 > mddev->size && |
2112 | mddev->recovery_cp == MaxSector) { | ||
2107 | mddev->recovery_cp = mddev->size << 1; | 2113 | mddev->recovery_cp = mddev->size << 1; |
2108 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 2114 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
2109 | } | 2115 | } |
2110 | mddev->size = mddev->array_size; | 2116 | mddev->size = mddev->array_sectors / 2; |
2111 | mddev->resync_max_sectors = sectors; | 2117 | mddev->resync_max_sectors = sectors; |
2112 | return 0; | 2118 | return 0; |
2113 | } | 2119 | } |
@@ -2131,7 +2137,7 @@ static int raid1_reshape(mddev_t *mddev) | |||
2131 | conf_t *conf = mddev_to_conf(mddev); | 2137 | conf_t *conf = mddev_to_conf(mddev); |
2132 | int cnt, raid_disks; | 2138 | int cnt, raid_disks; |
2133 | unsigned long flags; | 2139 | unsigned long flags; |
2134 | int d, d2; | 2140 | int d, d2, err; |
2135 | 2141 | ||
2136 | /* Cannot change chunk_size, layout, or level */ | 2142 | /* Cannot change chunk_size, layout, or level */ |
2137 | if (mddev->chunk_size != mddev->new_chunk || | 2143 | if (mddev->chunk_size != mddev->new_chunk || |
@@ -2143,7 +2149,9 @@ static int raid1_reshape(mddev_t *mddev) | |||
2143 | return -EINVAL; | 2149 | return -EINVAL; |
2144 | } | 2150 | } |
2145 | 2151 | ||
2146 | md_allow_write(mddev); | 2152 | err = md_allow_write(mddev); |
2153 | if (err) | ||
2154 | return err; | ||
2147 | 2155 | ||
2148 | raid_disks = mddev->raid_disks + mddev->delta_disks; | 2156 | raid_disks = mddev->raid_disks + mddev->delta_disks; |
2149 | 2157 | ||
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 22bb2b1b886d..159535d73567 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -1114,24 +1114,30 @@ static int raid10_spare_active(mddev_t *mddev) | |||
1114 | static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | 1114 | static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) |
1115 | { | 1115 | { |
1116 | conf_t *conf = mddev->private; | 1116 | conf_t *conf = mddev->private; |
1117 | int found = 0; | 1117 | int err = -EEXIST; |
1118 | int mirror; | 1118 | int mirror; |
1119 | mirror_info_t *p; | 1119 | mirror_info_t *p; |
1120 | int first = 0; | ||
1121 | int last = mddev->raid_disks - 1; | ||
1120 | 1122 | ||
1121 | if (mddev->recovery_cp < MaxSector) | 1123 | if (mddev->recovery_cp < MaxSector) |
1122 | /* only hot-add to in-sync arrays, as recovery is | 1124 | /* only hot-add to in-sync arrays, as recovery is |
1123 | * very different from resync | 1125 | * very different from resync |
1124 | */ | 1126 | */ |
1125 | return 0; | 1127 | return -EBUSY; |
1126 | if (!enough(conf)) | 1128 | if (!enough(conf)) |
1127 | return 0; | 1129 | return -EINVAL; |
1130 | |||
1131 | if (rdev->raid_disk) | ||
1132 | first = last = rdev->raid_disk; | ||
1128 | 1133 | ||
1129 | if (rdev->saved_raid_disk >= 0 && | 1134 | if (rdev->saved_raid_disk >= 0 && |
1135 | rdev->saved_raid_disk >= first && | ||
1130 | conf->mirrors[rdev->saved_raid_disk].rdev == NULL) | 1136 | conf->mirrors[rdev->saved_raid_disk].rdev == NULL) |
1131 | mirror = rdev->saved_raid_disk; | 1137 | mirror = rdev->saved_raid_disk; |
1132 | else | 1138 | else |
1133 | mirror = 0; | 1139 | mirror = first; |
1134 | for ( ; mirror < mddev->raid_disks; mirror++) | 1140 | for ( ; mirror <= last ; mirror++) |
1135 | if ( !(p=conf->mirrors+mirror)->rdev) { | 1141 | if ( !(p=conf->mirrors+mirror)->rdev) { |
1136 | 1142 | ||
1137 | blk_queue_stack_limits(mddev->queue, | 1143 | blk_queue_stack_limits(mddev->queue, |
@@ -1146,7 +1152,7 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1146 | 1152 | ||
1147 | p->head_position = 0; | 1153 | p->head_position = 0; |
1148 | rdev->raid_disk = mirror; | 1154 | rdev->raid_disk = mirror; |
1149 | found = 1; | 1155 | err = 0; |
1150 | if (rdev->saved_raid_disk != mirror) | 1156 | if (rdev->saved_raid_disk != mirror) |
1151 | conf->fullsync = 1; | 1157 | conf->fullsync = 1; |
1152 | rcu_assign_pointer(p->rdev, rdev); | 1158 | rcu_assign_pointer(p->rdev, rdev); |
@@ -1154,7 +1160,7 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1154 | } | 1160 | } |
1155 | 1161 | ||
1156 | print_conf(conf); | 1162 | print_conf(conf); |
1157 | return found; | 1163 | return err; |
1158 | } | 1164 | } |
1159 | 1165 | ||
1160 | static int raid10_remove_disk(mddev_t *mddev, int number) | 1166 | static int raid10_remove_disk(mddev_t *mddev, int number) |
@@ -2159,7 +2165,7 @@ static int run(mddev_t *mddev) | |||
2159 | /* | 2165 | /* |
2160 | * Ok, everything is just fine now | 2166 | * Ok, everything is just fine now |
2161 | */ | 2167 | */ |
2162 | mddev->array_size = size << (conf->chunk_shift-1); | 2168 | mddev->array_sectors = size << conf->chunk_shift; |
2163 | mddev->resync_max_sectors = size << conf->chunk_shift; | 2169 | mddev->resync_max_sectors = size << conf->chunk_shift; |
2164 | 2170 | ||
2165 | mddev->queue->unplug_fn = raid10_unplug; | 2171 | mddev->queue->unplug_fn = raid10_unplug; |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 9ce7154845c6..55e7c56045a0 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -115,15 +115,20 @@ static void return_io(struct bio *return_bi) | |||
115 | return_bi = bi->bi_next; | 115 | return_bi = bi->bi_next; |
116 | bi->bi_next = NULL; | 116 | bi->bi_next = NULL; |
117 | bi->bi_size = 0; | 117 | bi->bi_size = 0; |
118 | bi->bi_end_io(bi, | 118 | bio_endio(bi, 0); |
119 | test_bit(BIO_UPTODATE, &bi->bi_flags) | ||
120 | ? 0 : -EIO); | ||
121 | bi = return_bi; | 119 | bi = return_bi; |
122 | } | 120 | } |
123 | } | 121 | } |
124 | 122 | ||
125 | static void print_raid5_conf (raid5_conf_t *conf); | 123 | static void print_raid5_conf (raid5_conf_t *conf); |
126 | 124 | ||
125 | static int stripe_operations_active(struct stripe_head *sh) | ||
126 | { | ||
127 | return sh->check_state || sh->reconstruct_state || | ||
128 | test_bit(STRIPE_BIOFILL_RUN, &sh->state) || | ||
129 | test_bit(STRIPE_COMPUTE_RUN, &sh->state); | ||
130 | } | ||
131 | |||
127 | static void __release_stripe(raid5_conf_t *conf, struct stripe_head *sh) | 132 | static void __release_stripe(raid5_conf_t *conf, struct stripe_head *sh) |
128 | { | 133 | { |
129 | if (atomic_dec_and_test(&sh->count)) { | 134 | if (atomic_dec_and_test(&sh->count)) { |
@@ -143,7 +148,7 @@ static void __release_stripe(raid5_conf_t *conf, struct stripe_head *sh) | |||
143 | } | 148 | } |
144 | md_wakeup_thread(conf->mddev->thread); | 149 | md_wakeup_thread(conf->mddev->thread); |
145 | } else { | 150 | } else { |
146 | BUG_ON(sh->ops.pending); | 151 | BUG_ON(stripe_operations_active(sh)); |
147 | if (test_and_clear_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) { | 152 | if (test_and_clear_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) { |
148 | atomic_dec(&conf->preread_active_stripes); | 153 | atomic_dec(&conf->preread_active_stripes); |
149 | if (atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD) | 154 | if (atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD) |
@@ -245,7 +250,7 @@ static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int | |||
245 | 250 | ||
246 | BUG_ON(atomic_read(&sh->count) != 0); | 251 | BUG_ON(atomic_read(&sh->count) != 0); |
247 | BUG_ON(test_bit(STRIPE_HANDLE, &sh->state)); | 252 | BUG_ON(test_bit(STRIPE_HANDLE, &sh->state)); |
248 | BUG_ON(sh->ops.pending || sh->ops.ack || sh->ops.complete); | 253 | BUG_ON(stripe_operations_active(sh)); |
249 | 254 | ||
250 | CHECK_DEVLOCK(); | 255 | CHECK_DEVLOCK(); |
251 | pr_debug("init_stripe called, stripe %llu\n", | 256 | pr_debug("init_stripe called, stripe %llu\n", |
@@ -346,62 +351,18 @@ static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector | |||
346 | return sh; | 351 | return sh; |
347 | } | 352 | } |
348 | 353 | ||
349 | /* test_and_ack_op() ensures that we only dequeue an operation once */ | ||
350 | #define test_and_ack_op(op, pend) \ | ||
351 | do { \ | ||
352 | if (test_bit(op, &sh->ops.pending) && \ | ||
353 | !test_bit(op, &sh->ops.complete)) { \ | ||
354 | if (test_and_set_bit(op, &sh->ops.ack)) \ | ||
355 | clear_bit(op, &pend); \ | ||
356 | else \ | ||
357 | ack++; \ | ||
358 | } else \ | ||
359 | clear_bit(op, &pend); \ | ||
360 | } while (0) | ||
361 | |||
362 | /* find new work to run, do not resubmit work that is already | ||
363 | * in flight | ||
364 | */ | ||
365 | static unsigned long get_stripe_work(struct stripe_head *sh) | ||
366 | { | ||
367 | unsigned long pending; | ||
368 | int ack = 0; | ||
369 | |||
370 | pending = sh->ops.pending; | ||
371 | |||
372 | test_and_ack_op(STRIPE_OP_BIOFILL, pending); | ||
373 | test_and_ack_op(STRIPE_OP_COMPUTE_BLK, pending); | ||
374 | test_and_ack_op(STRIPE_OP_PREXOR, pending); | ||
375 | test_and_ack_op(STRIPE_OP_BIODRAIN, pending); | ||
376 | test_and_ack_op(STRIPE_OP_POSTXOR, pending); | ||
377 | test_and_ack_op(STRIPE_OP_CHECK, pending); | ||
378 | if (test_and_clear_bit(STRIPE_OP_IO, &sh->ops.pending)) | ||
379 | ack++; | ||
380 | |||
381 | sh->ops.count -= ack; | ||
382 | if (unlikely(sh->ops.count < 0)) { | ||
383 | printk(KERN_ERR "pending: %#lx ops.pending: %#lx ops.ack: %#lx " | ||
384 | "ops.complete: %#lx\n", pending, sh->ops.pending, | ||
385 | sh->ops.ack, sh->ops.complete); | ||
386 | BUG(); | ||
387 | } | ||
388 | |||
389 | return pending; | ||
390 | } | ||
391 | |||
392 | static void | 354 | static void |
393 | raid5_end_read_request(struct bio *bi, int error); | 355 | raid5_end_read_request(struct bio *bi, int error); |
394 | static void | 356 | static void |
395 | raid5_end_write_request(struct bio *bi, int error); | 357 | raid5_end_write_request(struct bio *bi, int error); |
396 | 358 | ||
397 | static void ops_run_io(struct stripe_head *sh) | 359 | static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s) |
398 | { | 360 | { |
399 | raid5_conf_t *conf = sh->raid_conf; | 361 | raid5_conf_t *conf = sh->raid_conf; |
400 | int i, disks = sh->disks; | 362 | int i, disks = sh->disks; |
401 | 363 | ||
402 | might_sleep(); | 364 | might_sleep(); |
403 | 365 | ||
404 | set_bit(STRIPE_IO_STARTED, &sh->state); | ||
405 | for (i = disks; i--; ) { | 366 | for (i = disks; i--; ) { |
406 | int rw; | 367 | int rw; |
407 | struct bio *bi; | 368 | struct bio *bi; |
@@ -430,11 +391,11 @@ static void ops_run_io(struct stripe_head *sh) | |||
430 | rcu_read_unlock(); | 391 | rcu_read_unlock(); |
431 | 392 | ||
432 | if (rdev) { | 393 | if (rdev) { |
433 | if (test_bit(STRIPE_SYNCING, &sh->state) || | 394 | if (s->syncing || s->expanding || s->expanded) |
434 | test_bit(STRIPE_EXPAND_SOURCE, &sh->state) || | ||
435 | test_bit(STRIPE_EXPAND_READY, &sh->state)) | ||
436 | md_sync_acct(rdev->bdev, STRIPE_SECTORS); | 395 | md_sync_acct(rdev->bdev, STRIPE_SECTORS); |
437 | 396 | ||
397 | set_bit(STRIPE_IO_STARTED, &sh->state); | ||
398 | |||
438 | bi->bi_bdev = rdev->bdev; | 399 | bi->bi_bdev = rdev->bdev; |
439 | pr_debug("%s: for %llu schedule op %ld on disc %d\n", | 400 | pr_debug("%s: for %llu schedule op %ld on disc %d\n", |
440 | __func__, (unsigned long long)sh->sector, | 401 | __func__, (unsigned long long)sh->sector, |
@@ -528,38 +489,34 @@ static void ops_complete_biofill(void *stripe_head_ref) | |||
528 | (unsigned long long)sh->sector); | 489 | (unsigned long long)sh->sector); |
529 | 490 | ||
530 | /* clear completed biofills */ | 491 | /* clear completed biofills */ |
492 | spin_lock_irq(&conf->device_lock); | ||
531 | for (i = sh->disks; i--; ) { | 493 | for (i = sh->disks; i--; ) { |
532 | struct r5dev *dev = &sh->dev[i]; | 494 | struct r5dev *dev = &sh->dev[i]; |
533 | 495 | ||
534 | /* acknowledge completion of a biofill operation */ | 496 | /* acknowledge completion of a biofill operation */ |
535 | /* and check if we need to reply to a read request, | 497 | /* and check if we need to reply to a read request, |
536 | * new R5_Wantfill requests are held off until | 498 | * new R5_Wantfill requests are held off until |
537 | * !test_bit(STRIPE_OP_BIOFILL, &sh->ops.pending) | 499 | * !STRIPE_BIOFILL_RUN |
538 | */ | 500 | */ |
539 | if (test_and_clear_bit(R5_Wantfill, &dev->flags)) { | 501 | if (test_and_clear_bit(R5_Wantfill, &dev->flags)) { |
540 | struct bio *rbi, *rbi2; | 502 | struct bio *rbi, *rbi2; |
541 | 503 | ||
542 | /* The access to dev->read is outside of the | ||
543 | * spin_lock_irq(&conf->device_lock), but is protected | ||
544 | * by the STRIPE_OP_BIOFILL pending bit | ||
545 | */ | ||
546 | BUG_ON(!dev->read); | 504 | BUG_ON(!dev->read); |
547 | rbi = dev->read; | 505 | rbi = dev->read; |
548 | dev->read = NULL; | 506 | dev->read = NULL; |
549 | while (rbi && rbi->bi_sector < | 507 | while (rbi && rbi->bi_sector < |
550 | dev->sector + STRIPE_SECTORS) { | 508 | dev->sector + STRIPE_SECTORS) { |
551 | rbi2 = r5_next_bio(rbi, dev->sector); | 509 | rbi2 = r5_next_bio(rbi, dev->sector); |
552 | spin_lock_irq(&conf->device_lock); | ||
553 | if (--rbi->bi_phys_segments == 0) { | 510 | if (--rbi->bi_phys_segments == 0) { |
554 | rbi->bi_next = return_bi; | 511 | rbi->bi_next = return_bi; |
555 | return_bi = rbi; | 512 | return_bi = rbi; |
556 | } | 513 | } |
557 | spin_unlock_irq(&conf->device_lock); | ||
558 | rbi = rbi2; | 514 | rbi = rbi2; |
559 | } | 515 | } |
560 | } | 516 | } |
561 | } | 517 | } |
562 | set_bit(STRIPE_OP_BIOFILL, &sh->ops.complete); | 518 | spin_unlock_irq(&conf->device_lock); |
519 | clear_bit(STRIPE_BIOFILL_RUN, &sh->state); | ||
563 | 520 | ||
564 | return_io(return_bi); | 521 | return_io(return_bi); |
565 | 522 | ||
@@ -610,13 +567,14 @@ static void ops_complete_compute5(void *stripe_head_ref) | |||
610 | set_bit(R5_UPTODATE, &tgt->flags); | 567 | set_bit(R5_UPTODATE, &tgt->flags); |
611 | BUG_ON(!test_bit(R5_Wantcompute, &tgt->flags)); | 568 | BUG_ON(!test_bit(R5_Wantcompute, &tgt->flags)); |
612 | clear_bit(R5_Wantcompute, &tgt->flags); | 569 | clear_bit(R5_Wantcompute, &tgt->flags); |
613 | set_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete); | 570 | clear_bit(STRIPE_COMPUTE_RUN, &sh->state); |
571 | if (sh->check_state == check_state_compute_run) | ||
572 | sh->check_state = check_state_compute_result; | ||
614 | set_bit(STRIPE_HANDLE, &sh->state); | 573 | set_bit(STRIPE_HANDLE, &sh->state); |
615 | release_stripe(sh); | 574 | release_stripe(sh); |
616 | } | 575 | } |
617 | 576 | ||
618 | static struct dma_async_tx_descriptor * | 577 | static struct dma_async_tx_descriptor *ops_run_compute5(struct stripe_head *sh) |
619 | ops_run_compute5(struct stripe_head *sh, unsigned long pending) | ||
620 | { | 578 | { |
621 | /* kernel stack size limits the total number of disks */ | 579 | /* kernel stack size limits the total number of disks */ |
622 | int disks = sh->disks; | 580 | int disks = sh->disks; |
@@ -646,10 +604,6 @@ ops_run_compute5(struct stripe_head *sh, unsigned long pending) | |||
646 | ASYNC_TX_XOR_ZERO_DST, NULL, | 604 | ASYNC_TX_XOR_ZERO_DST, NULL, |
647 | ops_complete_compute5, sh); | 605 | ops_complete_compute5, sh); |
648 | 606 | ||
649 | /* ack now if postxor is not set to be run */ | ||
650 | if (tx && !test_bit(STRIPE_OP_POSTXOR, &pending)) | ||
651 | async_tx_ack(tx); | ||
652 | |||
653 | return tx; | 607 | return tx; |
654 | } | 608 | } |
655 | 609 | ||
@@ -659,8 +613,6 @@ static void ops_complete_prexor(void *stripe_head_ref) | |||
659 | 613 | ||
660 | pr_debug("%s: stripe %llu\n", __func__, | 614 | pr_debug("%s: stripe %llu\n", __func__, |
661 | (unsigned long long)sh->sector); | 615 | (unsigned long long)sh->sector); |
662 | |||
663 | set_bit(STRIPE_OP_PREXOR, &sh->ops.complete); | ||
664 | } | 616 | } |
665 | 617 | ||
666 | static struct dma_async_tx_descriptor * | 618 | static struct dma_async_tx_descriptor * |
@@ -680,7 +632,7 @@ ops_run_prexor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx) | |||
680 | for (i = disks; i--; ) { | 632 | for (i = disks; i--; ) { |
681 | struct r5dev *dev = &sh->dev[i]; | 633 | struct r5dev *dev = &sh->dev[i]; |
682 | /* Only process blocks that are known to be uptodate */ | 634 | /* Only process blocks that are known to be uptodate */ |
683 | if (dev->towrite && test_bit(R5_Wantprexor, &dev->flags)) | 635 | if (test_bit(R5_Wantdrain, &dev->flags)) |
684 | xor_srcs[count++] = dev->page; | 636 | xor_srcs[count++] = dev->page; |
685 | } | 637 | } |
686 | 638 | ||
@@ -692,16 +644,10 @@ ops_run_prexor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx) | |||
692 | } | 644 | } |
693 | 645 | ||
694 | static struct dma_async_tx_descriptor * | 646 | static struct dma_async_tx_descriptor * |
695 | ops_run_biodrain(struct stripe_head *sh, struct dma_async_tx_descriptor *tx, | 647 | ops_run_biodrain(struct stripe_head *sh, struct dma_async_tx_descriptor *tx) |
696 | unsigned long pending) | ||
697 | { | 648 | { |
698 | int disks = sh->disks; | 649 | int disks = sh->disks; |
699 | int pd_idx = sh->pd_idx, i; | 650 | int i; |
700 | |||
701 | /* check if prexor is active which means only process blocks | ||
702 | * that are part of a read-modify-write (Wantprexor) | ||
703 | */ | ||
704 | int prexor = test_bit(STRIPE_OP_PREXOR, &pending); | ||
705 | 651 | ||
706 | pr_debug("%s: stripe %llu\n", __func__, | 652 | pr_debug("%s: stripe %llu\n", __func__, |
707 | (unsigned long long)sh->sector); | 653 | (unsigned long long)sh->sector); |
@@ -709,20 +655,8 @@ ops_run_biodrain(struct stripe_head *sh, struct dma_async_tx_descriptor *tx, | |||
709 | for (i = disks; i--; ) { | 655 | for (i = disks; i--; ) { |
710 | struct r5dev *dev = &sh->dev[i]; | 656 | struct r5dev *dev = &sh->dev[i]; |
711 | struct bio *chosen; | 657 | struct bio *chosen; |
712 | int towrite; | ||
713 | |||
714 | towrite = 0; | ||
715 | if (prexor) { /* rmw */ | ||
716 | if (dev->towrite && | ||
717 | test_bit(R5_Wantprexor, &dev->flags)) | ||
718 | towrite = 1; | ||
719 | } else { /* rcw */ | ||
720 | if (i != pd_idx && dev->towrite && | ||
721 | test_bit(R5_LOCKED, &dev->flags)) | ||
722 | towrite = 1; | ||
723 | } | ||
724 | 658 | ||
725 | if (towrite) { | 659 | if (test_and_clear_bit(R5_Wantdrain, &dev->flags)) { |
726 | struct bio *wbi; | 660 | struct bio *wbi; |
727 | 661 | ||
728 | spin_lock(&sh->lock); | 662 | spin_lock(&sh->lock); |
@@ -747,18 +681,6 @@ ops_run_biodrain(struct stripe_head *sh, struct dma_async_tx_descriptor *tx, | |||
747 | static void ops_complete_postxor(void *stripe_head_ref) | 681 | static void ops_complete_postxor(void *stripe_head_ref) |
748 | { | 682 | { |
749 | struct stripe_head *sh = stripe_head_ref; | 683 | struct stripe_head *sh = stripe_head_ref; |
750 | |||
751 | pr_debug("%s: stripe %llu\n", __func__, | ||
752 | (unsigned long long)sh->sector); | ||
753 | |||
754 | set_bit(STRIPE_OP_POSTXOR, &sh->ops.complete); | ||
755 | set_bit(STRIPE_HANDLE, &sh->state); | ||
756 | release_stripe(sh); | ||
757 | } | ||
758 | |||
759 | static void ops_complete_write(void *stripe_head_ref) | ||
760 | { | ||
761 | struct stripe_head *sh = stripe_head_ref; | ||
762 | int disks = sh->disks, i, pd_idx = sh->pd_idx; | 684 | int disks = sh->disks, i, pd_idx = sh->pd_idx; |
763 | 685 | ||
764 | pr_debug("%s: stripe %llu\n", __func__, | 686 | pr_debug("%s: stripe %llu\n", __func__, |
@@ -770,16 +692,21 @@ static void ops_complete_write(void *stripe_head_ref) | |||
770 | set_bit(R5_UPTODATE, &dev->flags); | 692 | set_bit(R5_UPTODATE, &dev->flags); |
771 | } | 693 | } |
772 | 694 | ||
773 | set_bit(STRIPE_OP_BIODRAIN, &sh->ops.complete); | 695 | if (sh->reconstruct_state == reconstruct_state_drain_run) |
774 | set_bit(STRIPE_OP_POSTXOR, &sh->ops.complete); | 696 | sh->reconstruct_state = reconstruct_state_drain_result; |
697 | else if (sh->reconstruct_state == reconstruct_state_prexor_drain_run) | ||
698 | sh->reconstruct_state = reconstruct_state_prexor_drain_result; | ||
699 | else { | ||
700 | BUG_ON(sh->reconstruct_state != reconstruct_state_run); | ||
701 | sh->reconstruct_state = reconstruct_state_result; | ||
702 | } | ||
775 | 703 | ||
776 | set_bit(STRIPE_HANDLE, &sh->state); | 704 | set_bit(STRIPE_HANDLE, &sh->state); |
777 | release_stripe(sh); | 705 | release_stripe(sh); |
778 | } | 706 | } |
779 | 707 | ||
780 | static void | 708 | static void |
781 | ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx, | 709 | ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx) |
782 | unsigned long pending) | ||
783 | { | 710 | { |
784 | /* kernel stack size limits the total number of disks */ | 711 | /* kernel stack size limits the total number of disks */ |
785 | int disks = sh->disks; | 712 | int disks = sh->disks; |
@@ -787,9 +714,8 @@ ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx, | |||
787 | 714 | ||
788 | int count = 0, pd_idx = sh->pd_idx, i; | 715 | int count = 0, pd_idx = sh->pd_idx, i; |
789 | struct page *xor_dest; | 716 | struct page *xor_dest; |
790 | int prexor = test_bit(STRIPE_OP_PREXOR, &pending); | 717 | int prexor = 0; |
791 | unsigned long flags; | 718 | unsigned long flags; |
792 | dma_async_tx_callback callback; | ||
793 | 719 | ||
794 | pr_debug("%s: stripe %llu\n", __func__, | 720 | pr_debug("%s: stripe %llu\n", __func__, |
795 | (unsigned long long)sh->sector); | 721 | (unsigned long long)sh->sector); |
@@ -797,7 +723,8 @@ ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx, | |||
797 | /* check if prexor is active which means only process blocks | 723 | /* check if prexor is active which means only process blocks |
798 | * that are part of a read-modify-write (written) | 724 | * that are part of a read-modify-write (written) |
799 | */ | 725 | */ |
800 | if (prexor) { | 726 | if (sh->reconstruct_state == reconstruct_state_prexor_drain_run) { |
727 | prexor = 1; | ||
801 | xor_dest = xor_srcs[count++] = sh->dev[pd_idx].page; | 728 | xor_dest = xor_srcs[count++] = sh->dev[pd_idx].page; |
802 | for (i = disks; i--; ) { | 729 | for (i = disks; i--; ) { |
803 | struct r5dev *dev = &sh->dev[i]; | 730 | struct r5dev *dev = &sh->dev[i]; |
@@ -813,10 +740,6 @@ ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx, | |||
813 | } | 740 | } |
814 | } | 741 | } |
815 | 742 | ||
816 | /* check whether this postxor is part of a write */ | ||
817 | callback = test_bit(STRIPE_OP_BIODRAIN, &pending) ? | ||
818 | ops_complete_write : ops_complete_postxor; | ||
819 | |||
820 | /* 1/ if we prexor'd then the dest is reused as a source | 743 | /* 1/ if we prexor'd then the dest is reused as a source |
821 | * 2/ if we did not prexor then we are redoing the parity | 744 | * 2/ if we did not prexor then we are redoing the parity |
822 | * set ASYNC_TX_XOR_DROP_DST and ASYNC_TX_XOR_ZERO_DST | 745 | * set ASYNC_TX_XOR_DROP_DST and ASYNC_TX_XOR_ZERO_DST |
@@ -830,25 +753,20 @@ ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx, | |||
830 | if (unlikely(count == 1)) { | 753 | if (unlikely(count == 1)) { |
831 | flags &= ~(ASYNC_TX_XOR_DROP_DST | ASYNC_TX_XOR_ZERO_DST); | 754 | flags &= ~(ASYNC_TX_XOR_DROP_DST | ASYNC_TX_XOR_ZERO_DST); |
832 | tx = async_memcpy(xor_dest, xor_srcs[0], 0, 0, STRIPE_SIZE, | 755 | tx = async_memcpy(xor_dest, xor_srcs[0], 0, 0, STRIPE_SIZE, |
833 | flags, tx, callback, sh); | 756 | flags, tx, ops_complete_postxor, sh); |
834 | } else | 757 | } else |
835 | tx = async_xor(xor_dest, xor_srcs, 0, count, STRIPE_SIZE, | 758 | tx = async_xor(xor_dest, xor_srcs, 0, count, STRIPE_SIZE, |
836 | flags, tx, callback, sh); | 759 | flags, tx, ops_complete_postxor, sh); |
837 | } | 760 | } |
838 | 761 | ||
839 | static void ops_complete_check(void *stripe_head_ref) | 762 | static void ops_complete_check(void *stripe_head_ref) |
840 | { | 763 | { |
841 | struct stripe_head *sh = stripe_head_ref; | 764 | struct stripe_head *sh = stripe_head_ref; |
842 | int pd_idx = sh->pd_idx; | ||
843 | 765 | ||
844 | pr_debug("%s: stripe %llu\n", __func__, | 766 | pr_debug("%s: stripe %llu\n", __func__, |
845 | (unsigned long long)sh->sector); | 767 | (unsigned long long)sh->sector); |
846 | 768 | ||
847 | if (test_and_clear_bit(STRIPE_OP_MOD_DMA_CHECK, &sh->ops.pending) && | 769 | sh->check_state = check_state_check_result; |
848 | sh->ops.zero_sum_result == 0) | ||
849 | set_bit(R5_UPTODATE, &sh->dev[pd_idx].flags); | ||
850 | |||
851 | set_bit(STRIPE_OP_CHECK, &sh->ops.complete); | ||
852 | set_bit(STRIPE_HANDLE, &sh->state); | 770 | set_bit(STRIPE_HANDLE, &sh->state); |
853 | release_stripe(sh); | 771 | release_stripe(sh); |
854 | } | 772 | } |
@@ -875,46 +793,42 @@ static void ops_run_check(struct stripe_head *sh) | |||
875 | tx = async_xor_zero_sum(xor_dest, xor_srcs, 0, count, STRIPE_SIZE, | 793 | tx = async_xor_zero_sum(xor_dest, xor_srcs, 0, count, STRIPE_SIZE, |
876 | &sh->ops.zero_sum_result, 0, NULL, NULL, NULL); | 794 | &sh->ops.zero_sum_result, 0, NULL, NULL, NULL); |
877 | 795 | ||
878 | if (tx) | ||
879 | set_bit(STRIPE_OP_MOD_DMA_CHECK, &sh->ops.pending); | ||
880 | else | ||
881 | clear_bit(STRIPE_OP_MOD_DMA_CHECK, &sh->ops.pending); | ||
882 | |||
883 | atomic_inc(&sh->count); | 796 | atomic_inc(&sh->count); |
884 | tx = async_trigger_callback(ASYNC_TX_DEP_ACK | ASYNC_TX_ACK, tx, | 797 | tx = async_trigger_callback(ASYNC_TX_DEP_ACK | ASYNC_TX_ACK, tx, |
885 | ops_complete_check, sh); | 798 | ops_complete_check, sh); |
886 | } | 799 | } |
887 | 800 | ||
888 | static void raid5_run_ops(struct stripe_head *sh, unsigned long pending) | 801 | static void raid5_run_ops(struct stripe_head *sh, unsigned long ops_request) |
889 | { | 802 | { |
890 | int overlap_clear = 0, i, disks = sh->disks; | 803 | int overlap_clear = 0, i, disks = sh->disks; |
891 | struct dma_async_tx_descriptor *tx = NULL; | 804 | struct dma_async_tx_descriptor *tx = NULL; |
892 | 805 | ||
893 | if (test_bit(STRIPE_OP_BIOFILL, &pending)) { | 806 | if (test_bit(STRIPE_OP_BIOFILL, &ops_request)) { |
894 | ops_run_biofill(sh); | 807 | ops_run_biofill(sh); |
895 | overlap_clear++; | 808 | overlap_clear++; |
896 | } | 809 | } |
897 | 810 | ||
898 | if (test_bit(STRIPE_OP_COMPUTE_BLK, &pending)) | 811 | if (test_bit(STRIPE_OP_COMPUTE_BLK, &ops_request)) { |
899 | tx = ops_run_compute5(sh, pending); | 812 | tx = ops_run_compute5(sh); |
813 | /* terminate the chain if postxor is not set to be run */ | ||
814 | if (tx && !test_bit(STRIPE_OP_POSTXOR, &ops_request)) | ||
815 | async_tx_ack(tx); | ||
816 | } | ||
900 | 817 | ||
901 | if (test_bit(STRIPE_OP_PREXOR, &pending)) | 818 | if (test_bit(STRIPE_OP_PREXOR, &ops_request)) |
902 | tx = ops_run_prexor(sh, tx); | 819 | tx = ops_run_prexor(sh, tx); |
903 | 820 | ||
904 | if (test_bit(STRIPE_OP_BIODRAIN, &pending)) { | 821 | if (test_bit(STRIPE_OP_BIODRAIN, &ops_request)) { |
905 | tx = ops_run_biodrain(sh, tx, pending); | 822 | tx = ops_run_biodrain(sh, tx); |
906 | overlap_clear++; | 823 | overlap_clear++; |
907 | } | 824 | } |
908 | 825 | ||
909 | if (test_bit(STRIPE_OP_POSTXOR, &pending)) | 826 | if (test_bit(STRIPE_OP_POSTXOR, &ops_request)) |
910 | ops_run_postxor(sh, tx, pending); | 827 | ops_run_postxor(sh, tx); |
911 | 828 | ||
912 | if (test_bit(STRIPE_OP_CHECK, &pending)) | 829 | if (test_bit(STRIPE_OP_CHECK, &ops_request)) |
913 | ops_run_check(sh); | 830 | ops_run_check(sh); |
914 | 831 | ||
915 | if (test_bit(STRIPE_OP_IO, &pending)) | ||
916 | ops_run_io(sh); | ||
917 | |||
918 | if (overlap_clear) | 832 | if (overlap_clear) |
919 | for (i = disks; i--; ) { | 833 | for (i = disks; i--; ) { |
920 | struct r5dev *dev = &sh->dev[i]; | 834 | struct r5dev *dev = &sh->dev[i]; |
@@ -997,14 +911,16 @@ static int resize_stripes(raid5_conf_t *conf, int newsize) | |||
997 | struct stripe_head *osh, *nsh; | 911 | struct stripe_head *osh, *nsh; |
998 | LIST_HEAD(newstripes); | 912 | LIST_HEAD(newstripes); |
999 | struct disk_info *ndisks; | 913 | struct disk_info *ndisks; |
1000 | int err = 0; | 914 | int err; |
1001 | struct kmem_cache *sc; | 915 | struct kmem_cache *sc; |
1002 | int i; | 916 | int i; |
1003 | 917 | ||
1004 | if (newsize <= conf->pool_size) | 918 | if (newsize <= conf->pool_size) |
1005 | return 0; /* never bother to shrink */ | 919 | return 0; /* never bother to shrink */ |
1006 | 920 | ||
1007 | md_allow_write(conf->mddev); | 921 | err = md_allow_write(conf->mddev); |
922 | if (err) | ||
923 | return err; | ||
1008 | 924 | ||
1009 | /* Step 1 */ | 925 | /* Step 1 */ |
1010 | sc = kmem_cache_create(conf->cache_name[1-conf->active_name], | 926 | sc = kmem_cache_create(conf->cache_name[1-conf->active_name], |
@@ -1703,11 +1619,11 @@ static void compute_block_2(struct stripe_head *sh, int dd_idx1, int dd_idx2) | |||
1703 | } | 1619 | } |
1704 | } | 1620 | } |
1705 | 1621 | ||
1706 | static int | 1622 | static void |
1707 | handle_write_operations5(struct stripe_head *sh, int rcw, int expand) | 1623 | schedule_reconstruction5(struct stripe_head *sh, struct stripe_head_state *s, |
1624 | int rcw, int expand) | ||
1708 | { | 1625 | { |
1709 | int i, pd_idx = sh->pd_idx, disks = sh->disks; | 1626 | int i, pd_idx = sh->pd_idx, disks = sh->disks; |
1710 | int locked = 0; | ||
1711 | 1627 | ||
1712 | if (rcw) { | 1628 | if (rcw) { |
1713 | /* if we are not expanding this is a proper write request, and | 1629 | /* if we are not expanding this is a proper write request, and |
@@ -1715,53 +1631,48 @@ handle_write_operations5(struct stripe_head *sh, int rcw, int expand) | |||
1715 | * stripe cache | 1631 | * stripe cache |
1716 | */ | 1632 | */ |
1717 | if (!expand) { | 1633 | if (!expand) { |
1718 | set_bit(STRIPE_OP_BIODRAIN, &sh->ops.pending); | 1634 | sh->reconstruct_state = reconstruct_state_drain_run; |
1719 | sh->ops.count++; | 1635 | set_bit(STRIPE_OP_BIODRAIN, &s->ops_request); |
1720 | } | 1636 | } else |
1637 | sh->reconstruct_state = reconstruct_state_run; | ||
1721 | 1638 | ||
1722 | set_bit(STRIPE_OP_POSTXOR, &sh->ops.pending); | 1639 | set_bit(STRIPE_OP_POSTXOR, &s->ops_request); |
1723 | sh->ops.count++; | ||
1724 | 1640 | ||
1725 | for (i = disks; i--; ) { | 1641 | for (i = disks; i--; ) { |
1726 | struct r5dev *dev = &sh->dev[i]; | 1642 | struct r5dev *dev = &sh->dev[i]; |
1727 | 1643 | ||
1728 | if (dev->towrite) { | 1644 | if (dev->towrite) { |
1729 | set_bit(R5_LOCKED, &dev->flags); | 1645 | set_bit(R5_LOCKED, &dev->flags); |
1646 | set_bit(R5_Wantdrain, &dev->flags); | ||
1730 | if (!expand) | 1647 | if (!expand) |
1731 | clear_bit(R5_UPTODATE, &dev->flags); | 1648 | clear_bit(R5_UPTODATE, &dev->flags); |
1732 | locked++; | 1649 | s->locked++; |
1733 | } | 1650 | } |
1734 | } | 1651 | } |
1735 | if (locked + 1 == disks) | 1652 | if (s->locked + 1 == disks) |
1736 | if (!test_and_set_bit(STRIPE_FULL_WRITE, &sh->state)) | 1653 | if (!test_and_set_bit(STRIPE_FULL_WRITE, &sh->state)) |
1737 | atomic_inc(&sh->raid_conf->pending_full_writes); | 1654 | atomic_inc(&sh->raid_conf->pending_full_writes); |
1738 | } else { | 1655 | } else { |
1739 | BUG_ON(!(test_bit(R5_UPTODATE, &sh->dev[pd_idx].flags) || | 1656 | BUG_ON(!(test_bit(R5_UPTODATE, &sh->dev[pd_idx].flags) || |
1740 | test_bit(R5_Wantcompute, &sh->dev[pd_idx].flags))); | 1657 | test_bit(R5_Wantcompute, &sh->dev[pd_idx].flags))); |
1741 | 1658 | ||
1742 | set_bit(STRIPE_OP_PREXOR, &sh->ops.pending); | 1659 | sh->reconstruct_state = reconstruct_state_prexor_drain_run; |
1743 | set_bit(STRIPE_OP_BIODRAIN, &sh->ops.pending); | 1660 | set_bit(STRIPE_OP_PREXOR, &s->ops_request); |
1744 | set_bit(STRIPE_OP_POSTXOR, &sh->ops.pending); | 1661 | set_bit(STRIPE_OP_BIODRAIN, &s->ops_request); |
1745 | 1662 | set_bit(STRIPE_OP_POSTXOR, &s->ops_request); | |
1746 | sh->ops.count += 3; | ||
1747 | 1663 | ||
1748 | for (i = disks; i--; ) { | 1664 | for (i = disks; i--; ) { |
1749 | struct r5dev *dev = &sh->dev[i]; | 1665 | struct r5dev *dev = &sh->dev[i]; |
1750 | if (i == pd_idx) | 1666 | if (i == pd_idx) |
1751 | continue; | 1667 | continue; |
1752 | 1668 | ||
1753 | /* For a read-modify write there may be blocks that are | ||
1754 | * locked for reading while others are ready to be | ||
1755 | * written so we distinguish these blocks by the | ||
1756 | * R5_Wantprexor bit | ||
1757 | */ | ||
1758 | if (dev->towrite && | 1669 | if (dev->towrite && |
1759 | (test_bit(R5_UPTODATE, &dev->flags) || | 1670 | (test_bit(R5_UPTODATE, &dev->flags) || |
1760 | test_bit(R5_Wantcompute, &dev->flags))) { | 1671 | test_bit(R5_Wantcompute, &dev->flags))) { |
1761 | set_bit(R5_Wantprexor, &dev->flags); | 1672 | set_bit(R5_Wantdrain, &dev->flags); |
1762 | set_bit(R5_LOCKED, &dev->flags); | 1673 | set_bit(R5_LOCKED, &dev->flags); |
1763 | clear_bit(R5_UPTODATE, &dev->flags); | 1674 | clear_bit(R5_UPTODATE, &dev->flags); |
1764 | locked++; | 1675 | s->locked++; |
1765 | } | 1676 | } |
1766 | } | 1677 | } |
1767 | } | 1678 | } |
@@ -1771,13 +1682,11 @@ handle_write_operations5(struct stripe_head *sh, int rcw, int expand) | |||
1771 | */ | 1682 | */ |
1772 | set_bit(R5_LOCKED, &sh->dev[pd_idx].flags); | 1683 | set_bit(R5_LOCKED, &sh->dev[pd_idx].flags); |
1773 | clear_bit(R5_UPTODATE, &sh->dev[pd_idx].flags); | 1684 | clear_bit(R5_UPTODATE, &sh->dev[pd_idx].flags); |
1774 | locked++; | 1685 | s->locked++; |
1775 | 1686 | ||
1776 | pr_debug("%s: stripe %llu locked: %d pending: %lx\n", | 1687 | pr_debug("%s: stripe %llu locked: %d ops_request: %lx\n", |
1777 | __func__, (unsigned long long)sh->sector, | 1688 | __func__, (unsigned long long)sh->sector, |
1778 | locked, sh->ops.pending); | 1689 | s->locked, s->ops_request); |
1779 | |||
1780 | return locked; | ||
1781 | } | 1690 | } |
1782 | 1691 | ||
1783 | /* | 1692 | /* |
@@ -1876,7 +1785,7 @@ static int stripe_to_pdidx(sector_t stripe, raid5_conf_t *conf, int disks) | |||
1876 | } | 1785 | } |
1877 | 1786 | ||
1878 | static void | 1787 | static void |
1879 | handle_requests_to_failed_array(raid5_conf_t *conf, struct stripe_head *sh, | 1788 | handle_failed_stripe(raid5_conf_t *conf, struct stripe_head *sh, |
1880 | struct stripe_head_state *s, int disks, | 1789 | struct stripe_head_state *s, int disks, |
1881 | struct bio **return_bi) | 1790 | struct bio **return_bi) |
1882 | { | 1791 | { |
@@ -1967,48 +1876,38 @@ handle_requests_to_failed_array(raid5_conf_t *conf, struct stripe_head *sh, | |||
1967 | md_wakeup_thread(conf->mddev->thread); | 1876 | md_wakeup_thread(conf->mddev->thread); |
1968 | } | 1877 | } |
1969 | 1878 | ||
1970 | /* __handle_issuing_new_read_requests5 - returns 0 if there are no more disks | 1879 | /* fetch_block5 - checks the given member device to see if its data needs |
1971 | * to process | 1880 | * to be read or computed to satisfy a request. |
1881 | * | ||
1882 | * Returns 1 when no more member devices need to be checked, otherwise returns | ||
1883 | * 0 to tell the loop in handle_stripe_fill5 to continue | ||
1972 | */ | 1884 | */ |
1973 | static int __handle_issuing_new_read_requests5(struct stripe_head *sh, | 1885 | static int fetch_block5(struct stripe_head *sh, struct stripe_head_state *s, |
1974 | struct stripe_head_state *s, int disk_idx, int disks) | 1886 | int disk_idx, int disks) |
1975 | { | 1887 | { |
1976 | struct r5dev *dev = &sh->dev[disk_idx]; | 1888 | struct r5dev *dev = &sh->dev[disk_idx]; |
1977 | struct r5dev *failed_dev = &sh->dev[s->failed_num]; | 1889 | struct r5dev *failed_dev = &sh->dev[s->failed_num]; |
1978 | 1890 | ||
1979 | /* don't schedule compute operations or reads on the parity block while | ||
1980 | * a check is in flight | ||
1981 | */ | ||
1982 | if ((disk_idx == sh->pd_idx) && | ||
1983 | test_bit(STRIPE_OP_CHECK, &sh->ops.pending)) | ||
1984 | return ~0; | ||
1985 | |||
1986 | /* is the data in this block needed, and can we get it? */ | 1891 | /* is the data in this block needed, and can we get it? */ |
1987 | if (!test_bit(R5_LOCKED, &dev->flags) && | 1892 | if (!test_bit(R5_LOCKED, &dev->flags) && |
1988 | !test_bit(R5_UPTODATE, &dev->flags) && (dev->toread || | 1893 | !test_bit(R5_UPTODATE, &dev->flags) && |
1989 | (dev->towrite && !test_bit(R5_OVERWRITE, &dev->flags)) || | 1894 | (dev->toread || |
1990 | s->syncing || s->expanding || (s->failed && | 1895 | (dev->towrite && !test_bit(R5_OVERWRITE, &dev->flags)) || |
1991 | (failed_dev->toread || (failed_dev->towrite && | 1896 | s->syncing || s->expanding || |
1992 | !test_bit(R5_OVERWRITE, &failed_dev->flags) | 1897 | (s->failed && |
1993 | ))))) { | 1898 | (failed_dev->toread || |
1994 | /* 1/ We would like to get this block, possibly by computing it, | 1899 | (failed_dev->towrite && |
1995 | * but we might not be able to. | 1900 | !test_bit(R5_OVERWRITE, &failed_dev->flags)))))) { |
1996 | * | 1901 | /* We would like to get this block, possibly by computing it, |
1997 | * 2/ Since parity check operations potentially make the parity | 1902 | * otherwise read it if the backing disk is insync |
1998 | * block !uptodate it will need to be refreshed before any | ||
1999 | * compute operations on data disks are scheduled. | ||
2000 | * | ||
2001 | * 3/ We hold off parity block re-reads until check operations | ||
2002 | * have quiesced. | ||
2003 | */ | 1903 | */ |
2004 | if ((s->uptodate == disks - 1) && | 1904 | if ((s->uptodate == disks - 1) && |
2005 | (s->failed && disk_idx == s->failed_num) && | 1905 | (s->failed && disk_idx == s->failed_num)) { |
2006 | !test_bit(STRIPE_OP_CHECK, &sh->ops.pending)) { | 1906 | set_bit(STRIPE_COMPUTE_RUN, &sh->state); |
2007 | set_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending); | 1907 | set_bit(STRIPE_OP_COMPUTE_BLK, &s->ops_request); |
2008 | set_bit(R5_Wantcompute, &dev->flags); | 1908 | set_bit(R5_Wantcompute, &dev->flags); |
2009 | sh->ops.target = disk_idx; | 1909 | sh->ops.target = disk_idx; |
2010 | s->req_compute = 1; | 1910 | s->req_compute = 1; |
2011 | sh->ops.count++; | ||
2012 | /* Careful: from this point on 'uptodate' is in the eye | 1911 | /* Careful: from this point on 'uptodate' is in the eye |
2013 | * of raid5_run_ops which services 'compute' operations | 1912 | * of raid5_run_ops which services 'compute' operations |
2014 | * before writes. R5_Wantcompute flags a block that will | 1913 | * before writes. R5_Wantcompute flags a block that will |
@@ -2016,53 +1915,40 @@ static int __handle_issuing_new_read_requests5(struct stripe_head *sh, | |||
2016 | * subsequent operation. | 1915 | * subsequent operation. |
2017 | */ | 1916 | */ |
2018 | s->uptodate++; | 1917 | s->uptodate++; |
2019 | return 0; /* uptodate + compute == disks */ | 1918 | return 1; /* uptodate + compute == disks */ |
2020 | } else if (test_bit(R5_Insync, &dev->flags)) { | 1919 | } else if (test_bit(R5_Insync, &dev->flags)) { |
2021 | set_bit(R5_LOCKED, &dev->flags); | 1920 | set_bit(R5_LOCKED, &dev->flags); |
2022 | set_bit(R5_Wantread, &dev->flags); | 1921 | set_bit(R5_Wantread, &dev->flags); |
2023 | if (!test_and_set_bit(STRIPE_OP_IO, &sh->ops.pending)) | ||
2024 | sh->ops.count++; | ||
2025 | s->locked++; | 1922 | s->locked++; |
2026 | pr_debug("Reading block %d (sync=%d)\n", disk_idx, | 1923 | pr_debug("Reading block %d (sync=%d)\n", disk_idx, |
2027 | s->syncing); | 1924 | s->syncing); |
2028 | } | 1925 | } |
2029 | } | 1926 | } |
2030 | 1927 | ||
2031 | return ~0; | 1928 | return 0; |
2032 | } | 1929 | } |
2033 | 1930 | ||
2034 | static void handle_issuing_new_read_requests5(struct stripe_head *sh, | 1931 | /** |
1932 | * handle_stripe_fill5 - read or compute data to satisfy pending requests. | ||
1933 | */ | ||
1934 | static void handle_stripe_fill5(struct stripe_head *sh, | ||
2035 | struct stripe_head_state *s, int disks) | 1935 | struct stripe_head_state *s, int disks) |
2036 | { | 1936 | { |
2037 | int i; | 1937 | int i; |
2038 | 1938 | ||
2039 | /* Clear completed compute operations. Parity recovery | ||
2040 | * (STRIPE_OP_MOD_REPAIR_PD) implies a write-back which is handled | ||
2041 | * later on in this routine | ||
2042 | */ | ||
2043 | if (test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete) && | ||
2044 | !test_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending)) { | ||
2045 | clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete); | ||
2046 | clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.ack); | ||
2047 | clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending); | ||
2048 | } | ||
2049 | |||
2050 | /* look for blocks to read/compute, skip this if a compute | 1939 | /* look for blocks to read/compute, skip this if a compute |
2051 | * is already in flight, or if the stripe contents are in the | 1940 | * is already in flight, or if the stripe contents are in the |
2052 | * midst of changing due to a write | 1941 | * midst of changing due to a write |
2053 | */ | 1942 | */ |
2054 | if (!test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending) && | 1943 | if (!test_bit(STRIPE_COMPUTE_RUN, &sh->state) && !sh->check_state && |
2055 | !test_bit(STRIPE_OP_PREXOR, &sh->ops.pending) && | 1944 | !sh->reconstruct_state) |
2056 | !test_bit(STRIPE_OP_POSTXOR, &sh->ops.pending)) { | ||
2057 | for (i = disks; i--; ) | 1945 | for (i = disks; i--; ) |
2058 | if (__handle_issuing_new_read_requests5( | 1946 | if (fetch_block5(sh, s, i, disks)) |
2059 | sh, s, i, disks) == 0) | ||
2060 | break; | 1947 | break; |
2061 | } | ||
2062 | set_bit(STRIPE_HANDLE, &sh->state); | 1948 | set_bit(STRIPE_HANDLE, &sh->state); |
2063 | } | 1949 | } |
2064 | 1950 | ||
2065 | static void handle_issuing_new_read_requests6(struct stripe_head *sh, | 1951 | static void handle_stripe_fill6(struct stripe_head *sh, |
2066 | struct stripe_head_state *s, struct r6_state *r6s, | 1952 | struct stripe_head_state *s, struct r6_state *r6s, |
2067 | int disks) | 1953 | int disks) |
2068 | { | 1954 | { |
@@ -2121,12 +2007,12 @@ static void handle_issuing_new_read_requests6(struct stripe_head *sh, | |||
2121 | } | 2007 | } |
2122 | 2008 | ||
2123 | 2009 | ||
2124 | /* handle_completed_write_requests | 2010 | /* handle_stripe_clean_event |
2125 | * any written block on an uptodate or failed drive can be returned. | 2011 | * any written block on an uptodate or failed drive can be returned. |
2126 | * Note that if we 'wrote' to a failed drive, it will be UPTODATE, but | 2012 | * Note that if we 'wrote' to a failed drive, it will be UPTODATE, but |
2127 | * never LOCKED, so we don't need to test 'failed' directly. | 2013 | * never LOCKED, so we don't need to test 'failed' directly. |
2128 | */ | 2014 | */ |
2129 | static void handle_completed_write_requests(raid5_conf_t *conf, | 2015 | static void handle_stripe_clean_event(raid5_conf_t *conf, |
2130 | struct stripe_head *sh, int disks, struct bio **return_bi) | 2016 | struct stripe_head *sh, int disks, struct bio **return_bi) |
2131 | { | 2017 | { |
2132 | int i; | 2018 | int i; |
@@ -2171,7 +2057,7 @@ static void handle_completed_write_requests(raid5_conf_t *conf, | |||
2171 | md_wakeup_thread(conf->mddev->thread); | 2057 | md_wakeup_thread(conf->mddev->thread); |
2172 | } | 2058 | } |
2173 | 2059 | ||
2174 | static void handle_issuing_new_write_requests5(raid5_conf_t *conf, | 2060 | static void handle_stripe_dirtying5(raid5_conf_t *conf, |
2175 | struct stripe_head *sh, struct stripe_head_state *s, int disks) | 2061 | struct stripe_head *sh, struct stripe_head_state *s, int disks) |
2176 | { | 2062 | { |
2177 | int rmw = 0, rcw = 0, i; | 2063 | int rmw = 0, rcw = 0, i; |
@@ -2215,9 +2101,6 @@ static void handle_issuing_new_write_requests5(raid5_conf_t *conf, | |||
2215 | "%d for r-m-w\n", i); | 2101 | "%d for r-m-w\n", i); |
2216 | set_bit(R5_LOCKED, &dev->flags); | 2102 | set_bit(R5_LOCKED, &dev->flags); |
2217 | set_bit(R5_Wantread, &dev->flags); | 2103 | set_bit(R5_Wantread, &dev->flags); |
2218 | if (!test_and_set_bit( | ||
2219 | STRIPE_OP_IO, &sh->ops.pending)) | ||
2220 | sh->ops.count++; | ||
2221 | s->locked++; | 2104 | s->locked++; |
2222 | } else { | 2105 | } else { |
2223 | set_bit(STRIPE_DELAYED, &sh->state); | 2106 | set_bit(STRIPE_DELAYED, &sh->state); |
@@ -2241,9 +2124,6 @@ static void handle_issuing_new_write_requests5(raid5_conf_t *conf, | |||
2241 | "%d for Reconstruct\n", i); | 2124 | "%d for Reconstruct\n", i); |
2242 | set_bit(R5_LOCKED, &dev->flags); | 2125 | set_bit(R5_LOCKED, &dev->flags); |
2243 | set_bit(R5_Wantread, &dev->flags); | 2126 | set_bit(R5_Wantread, &dev->flags); |
2244 | if (!test_and_set_bit( | ||
2245 | STRIPE_OP_IO, &sh->ops.pending)) | ||
2246 | sh->ops.count++; | ||
2247 | s->locked++; | 2127 | s->locked++; |
2248 | } else { | 2128 | } else { |
2249 | set_bit(STRIPE_DELAYED, &sh->state); | 2129 | set_bit(STRIPE_DELAYED, &sh->state); |
@@ -2261,14 +2141,13 @@ static void handle_issuing_new_write_requests5(raid5_conf_t *conf, | |||
2261 | * simultaneously. If this is not the case then new writes need to be | 2141 | * simultaneously. If this is not the case then new writes need to be |
2262 | * held off until the compute completes. | 2142 | * held off until the compute completes. |
2263 | */ | 2143 | */ |
2264 | if ((s->req_compute || | 2144 | if ((s->req_compute || !test_bit(STRIPE_COMPUTE_RUN, &sh->state)) && |
2265 | !test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending)) && | 2145 | (s->locked == 0 && (rcw == 0 || rmw == 0) && |
2266 | (s->locked == 0 && (rcw == 0 || rmw == 0) && | 2146 | !test_bit(STRIPE_BIT_DELAY, &sh->state))) |
2267 | !test_bit(STRIPE_BIT_DELAY, &sh->state))) | 2147 | schedule_reconstruction5(sh, s, rcw == 0, 0); |
2268 | s->locked += handle_write_operations5(sh, rcw == 0, 0); | ||
2269 | } | 2148 | } |
2270 | 2149 | ||
2271 | static void handle_issuing_new_write_requests6(raid5_conf_t *conf, | 2150 | static void handle_stripe_dirtying6(raid5_conf_t *conf, |
2272 | struct stripe_head *sh, struct stripe_head_state *s, | 2151 | struct stripe_head *sh, struct stripe_head_state *s, |
2273 | struct r6_state *r6s, int disks) | 2152 | struct r6_state *r6s, int disks) |
2274 | { | 2153 | { |
@@ -2371,92 +2250,86 @@ static void handle_issuing_new_write_requests6(raid5_conf_t *conf, | |||
2371 | static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh, | 2250 | static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh, |
2372 | struct stripe_head_state *s, int disks) | 2251 | struct stripe_head_state *s, int disks) |
2373 | { | 2252 | { |
2374 | int canceled_check = 0; | 2253 | struct r5dev *dev = NULL; |
2375 | 2254 | ||
2376 | set_bit(STRIPE_HANDLE, &sh->state); | 2255 | set_bit(STRIPE_HANDLE, &sh->state); |
2377 | 2256 | ||
2378 | /* complete a check operation */ | 2257 | switch (sh->check_state) { |
2379 | if (test_and_clear_bit(STRIPE_OP_CHECK, &sh->ops.complete)) { | 2258 | case check_state_idle: |
2380 | clear_bit(STRIPE_OP_CHECK, &sh->ops.ack); | 2259 | /* start a new check operation if there are no failures */ |
2381 | clear_bit(STRIPE_OP_CHECK, &sh->ops.pending); | ||
2382 | if (s->failed == 0) { | 2260 | if (s->failed == 0) { |
2383 | if (sh->ops.zero_sum_result == 0) | ||
2384 | /* parity is correct (on disc, | ||
2385 | * not in buffer any more) | ||
2386 | */ | ||
2387 | set_bit(STRIPE_INSYNC, &sh->state); | ||
2388 | else { | ||
2389 | conf->mddev->resync_mismatches += | ||
2390 | STRIPE_SECTORS; | ||
2391 | if (test_bit( | ||
2392 | MD_RECOVERY_CHECK, &conf->mddev->recovery)) | ||
2393 | /* don't try to repair!! */ | ||
2394 | set_bit(STRIPE_INSYNC, &sh->state); | ||
2395 | else { | ||
2396 | set_bit(STRIPE_OP_COMPUTE_BLK, | ||
2397 | &sh->ops.pending); | ||
2398 | set_bit(STRIPE_OP_MOD_REPAIR_PD, | ||
2399 | &sh->ops.pending); | ||
2400 | set_bit(R5_Wantcompute, | ||
2401 | &sh->dev[sh->pd_idx].flags); | ||
2402 | sh->ops.target = sh->pd_idx; | ||
2403 | sh->ops.count++; | ||
2404 | s->uptodate++; | ||
2405 | } | ||
2406 | } | ||
2407 | } else | ||
2408 | canceled_check = 1; /* STRIPE_INSYNC is not set */ | ||
2409 | } | ||
2410 | |||
2411 | /* start a new check operation if there are no failures, the stripe is | ||
2412 | * not insync, and a repair is not in flight | ||
2413 | */ | ||
2414 | if (s->failed == 0 && | ||
2415 | !test_bit(STRIPE_INSYNC, &sh->state) && | ||
2416 | !test_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending)) { | ||
2417 | if (!test_and_set_bit(STRIPE_OP_CHECK, &sh->ops.pending)) { | ||
2418 | BUG_ON(s->uptodate != disks); | 2261 | BUG_ON(s->uptodate != disks); |
2262 | sh->check_state = check_state_run; | ||
2263 | set_bit(STRIPE_OP_CHECK, &s->ops_request); | ||
2419 | clear_bit(R5_UPTODATE, &sh->dev[sh->pd_idx].flags); | 2264 | clear_bit(R5_UPTODATE, &sh->dev[sh->pd_idx].flags); |
2420 | sh->ops.count++; | ||
2421 | s->uptodate--; | 2265 | s->uptodate--; |
2266 | break; | ||
2422 | } | 2267 | } |
2423 | } | 2268 | dev = &sh->dev[s->failed_num]; |
2424 | 2269 | /* fall through */ | |
2425 | /* check if we can clear a parity disk reconstruct */ | 2270 | case check_state_compute_result: |
2426 | if (test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete) && | 2271 | sh->check_state = check_state_idle; |
2427 | test_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending)) { | 2272 | if (!dev) |
2428 | 2273 | dev = &sh->dev[sh->pd_idx]; | |
2429 | clear_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending); | 2274 | |
2430 | clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete); | 2275 | /* check that a write has not made the stripe insync */ |
2431 | clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.ack); | 2276 | if (test_bit(STRIPE_INSYNC, &sh->state)) |
2432 | clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending); | 2277 | break; |
2433 | } | ||
2434 | |||
2435 | 2278 | ||
2436 | /* Wait for check parity and compute block operations to complete | ||
2437 | * before write-back. If a failure occurred while the check operation | ||
2438 | * was in flight we need to cycle this stripe through handle_stripe | ||
2439 | * since the parity block may not be uptodate | ||
2440 | */ | ||
2441 | if (!canceled_check && !test_bit(STRIPE_INSYNC, &sh->state) && | ||
2442 | !test_bit(STRIPE_OP_CHECK, &sh->ops.pending) && | ||
2443 | !test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending)) { | ||
2444 | struct r5dev *dev; | ||
2445 | /* either failed parity check, or recovery is happening */ | 2279 | /* either failed parity check, or recovery is happening */ |
2446 | if (s->failed == 0) | ||
2447 | s->failed_num = sh->pd_idx; | ||
2448 | dev = &sh->dev[s->failed_num]; | ||
2449 | BUG_ON(!test_bit(R5_UPTODATE, &dev->flags)); | 2280 | BUG_ON(!test_bit(R5_UPTODATE, &dev->flags)); |
2450 | BUG_ON(s->uptodate != disks); | 2281 | BUG_ON(s->uptodate != disks); |
2451 | 2282 | ||
2452 | set_bit(R5_LOCKED, &dev->flags); | 2283 | set_bit(R5_LOCKED, &dev->flags); |
2284 | s->locked++; | ||
2453 | set_bit(R5_Wantwrite, &dev->flags); | 2285 | set_bit(R5_Wantwrite, &dev->flags); |
2454 | if (!test_and_set_bit(STRIPE_OP_IO, &sh->ops.pending)) | ||
2455 | sh->ops.count++; | ||
2456 | 2286 | ||
2457 | clear_bit(STRIPE_DEGRADED, &sh->state); | 2287 | clear_bit(STRIPE_DEGRADED, &sh->state); |
2458 | s->locked++; | ||
2459 | set_bit(STRIPE_INSYNC, &sh->state); | 2288 | set_bit(STRIPE_INSYNC, &sh->state); |
2289 | break; | ||
2290 | case check_state_run: | ||
2291 | break; /* we will be called again upon completion */ | ||
2292 | case check_state_check_result: | ||
2293 | sh->check_state = check_state_idle; | ||
2294 | |||
2295 | /* if a failure occurred during the check operation, leave | ||
2296 | * STRIPE_INSYNC not set and let the stripe be handled again | ||
2297 | */ | ||
2298 | if (s->failed) | ||
2299 | break; | ||
2300 | |||
2301 | /* handle a successful check operation, if parity is correct | ||
2302 | * we are done. Otherwise update the mismatch count and repair | ||
2303 | * parity if !MD_RECOVERY_CHECK | ||
2304 | */ | ||
2305 | if (sh->ops.zero_sum_result == 0) | ||
2306 | /* parity is correct (on disc, | ||
2307 | * not in buffer any more) | ||
2308 | */ | ||
2309 | set_bit(STRIPE_INSYNC, &sh->state); | ||
2310 | else { | ||
2311 | conf->mddev->resync_mismatches += STRIPE_SECTORS; | ||
2312 | if (test_bit(MD_RECOVERY_CHECK, &conf->mddev->recovery)) | ||
2313 | /* don't try to repair!! */ | ||
2314 | set_bit(STRIPE_INSYNC, &sh->state); | ||
2315 | else { | ||
2316 | sh->check_state = check_state_compute_run; | ||
2317 | set_bit(STRIPE_COMPUTE_RUN, &sh->state); | ||
2318 | set_bit(STRIPE_OP_COMPUTE_BLK, &s->ops_request); | ||
2319 | set_bit(R5_Wantcompute, | ||
2320 | &sh->dev[sh->pd_idx].flags); | ||
2321 | sh->ops.target = sh->pd_idx; | ||
2322 | s->uptodate++; | ||
2323 | } | ||
2324 | } | ||
2325 | break; | ||
2326 | case check_state_compute_run: | ||
2327 | break; | ||
2328 | default: | ||
2329 | printk(KERN_ERR "%s: unknown check_state: %d sector: %llu\n", | ||
2330 | __func__, sh->check_state, | ||
2331 | (unsigned long long) sh->sector); | ||
2332 | BUG(); | ||
2460 | } | 2333 | } |
2461 | } | 2334 | } |
2462 | 2335 | ||
@@ -2641,15 +2514,14 @@ static void handle_stripe5(struct stripe_head *sh) | |||
2641 | struct bio *return_bi = NULL; | 2514 | struct bio *return_bi = NULL; |
2642 | struct stripe_head_state s; | 2515 | struct stripe_head_state s; |
2643 | struct r5dev *dev; | 2516 | struct r5dev *dev; |
2644 | unsigned long pending = 0; | ||
2645 | mdk_rdev_t *blocked_rdev = NULL; | 2517 | mdk_rdev_t *blocked_rdev = NULL; |
2646 | int prexor; | 2518 | int prexor; |
2647 | 2519 | ||
2648 | memset(&s, 0, sizeof(s)); | 2520 | memset(&s, 0, sizeof(s)); |
2649 | pr_debug("handling stripe %llu, state=%#lx cnt=%d, pd_idx=%d " | 2521 | pr_debug("handling stripe %llu, state=%#lx cnt=%d, pd_idx=%d check:%d " |
2650 | "ops=%lx:%lx:%lx\n", (unsigned long long)sh->sector, sh->state, | 2522 | "reconstruct:%d\n", (unsigned long long)sh->sector, sh->state, |
2651 | atomic_read(&sh->count), sh->pd_idx, | 2523 | atomic_read(&sh->count), sh->pd_idx, sh->check_state, |
2652 | sh->ops.pending, sh->ops.ack, sh->ops.complete); | 2524 | sh->reconstruct_state); |
2653 | 2525 | ||
2654 | spin_lock(&sh->lock); | 2526 | spin_lock(&sh->lock); |
2655 | clear_bit(STRIPE_HANDLE, &sh->state); | 2527 | clear_bit(STRIPE_HANDLE, &sh->state); |
@@ -2658,15 +2530,8 @@ static void handle_stripe5(struct stripe_head *sh) | |||
2658 | s.syncing = test_bit(STRIPE_SYNCING, &sh->state); | 2530 | s.syncing = test_bit(STRIPE_SYNCING, &sh->state); |
2659 | s.expanding = test_bit(STRIPE_EXPAND_SOURCE, &sh->state); | 2531 | s.expanding = test_bit(STRIPE_EXPAND_SOURCE, &sh->state); |
2660 | s.expanded = test_bit(STRIPE_EXPAND_READY, &sh->state); | 2532 | s.expanded = test_bit(STRIPE_EXPAND_READY, &sh->state); |
2661 | /* Now to look around and see what can be done */ | ||
2662 | |||
2663 | /* clean-up completed biofill operations */ | ||
2664 | if (test_bit(STRIPE_OP_BIOFILL, &sh->ops.complete)) { | ||
2665 | clear_bit(STRIPE_OP_BIOFILL, &sh->ops.pending); | ||
2666 | clear_bit(STRIPE_OP_BIOFILL, &sh->ops.ack); | ||
2667 | clear_bit(STRIPE_OP_BIOFILL, &sh->ops.complete); | ||
2668 | } | ||
2669 | 2533 | ||
2534 | /* Now to look around and see what can be done */ | ||
2670 | rcu_read_lock(); | 2535 | rcu_read_lock(); |
2671 | for (i=disks; i--; ) { | 2536 | for (i=disks; i--; ) { |
2672 | mdk_rdev_t *rdev; | 2537 | mdk_rdev_t *rdev; |
@@ -2680,10 +2545,10 @@ static void handle_stripe5(struct stripe_head *sh) | |||
2680 | /* maybe we can request a biofill operation | 2545 | /* maybe we can request a biofill operation |
2681 | * | 2546 | * |
2682 | * new wantfill requests are only permitted while | 2547 | * new wantfill requests are only permitted while |
2683 | * STRIPE_OP_BIOFILL is clear | 2548 | * ops_complete_biofill is guaranteed to be inactive |
2684 | */ | 2549 | */ |
2685 | if (test_bit(R5_UPTODATE, &dev->flags) && dev->toread && | 2550 | if (test_bit(R5_UPTODATE, &dev->flags) && dev->toread && |
2686 | !test_bit(STRIPE_OP_BIOFILL, &sh->ops.pending)) | 2551 | !test_bit(STRIPE_BIOFILL_RUN, &sh->state)) |
2687 | set_bit(R5_Wantfill, &dev->flags); | 2552 | set_bit(R5_Wantfill, &dev->flags); |
2688 | 2553 | ||
2689 | /* now count some things */ | 2554 | /* now count some things */ |
@@ -2727,8 +2592,10 @@ static void handle_stripe5(struct stripe_head *sh) | |||
2727 | goto unlock; | 2592 | goto unlock; |
2728 | } | 2593 | } |
2729 | 2594 | ||
2730 | if (s.to_fill && !test_and_set_bit(STRIPE_OP_BIOFILL, &sh->ops.pending)) | 2595 | if (s.to_fill && !test_bit(STRIPE_BIOFILL_RUN, &sh->state)) { |
2731 | sh->ops.count++; | 2596 | set_bit(STRIPE_OP_BIOFILL, &s.ops_request); |
2597 | set_bit(STRIPE_BIOFILL_RUN, &sh->state); | ||
2598 | } | ||
2732 | 2599 | ||
2733 | pr_debug("locked=%d uptodate=%d to_read=%d" | 2600 | pr_debug("locked=%d uptodate=%d to_read=%d" |
2734 | " to_write=%d failed=%d failed_num=%d\n", | 2601 | " to_write=%d failed=%d failed_num=%d\n", |
@@ -2738,8 +2605,7 @@ static void handle_stripe5(struct stripe_head *sh) | |||
2738 | * need to be failed | 2605 | * need to be failed |
2739 | */ | 2606 | */ |
2740 | if (s.failed > 1 && s.to_read+s.to_write+s.written) | 2607 | if (s.failed > 1 && s.to_read+s.to_write+s.written) |
2741 | handle_requests_to_failed_array(conf, sh, &s, disks, | 2608 | handle_failed_stripe(conf, sh, &s, disks, &return_bi); |
2742 | &return_bi); | ||
2743 | if (s.failed > 1 && s.syncing) { | 2609 | if (s.failed > 1 && s.syncing) { |
2744 | md_done_sync(conf->mddev, STRIPE_SECTORS,0); | 2610 | md_done_sync(conf->mddev, STRIPE_SECTORS,0); |
2745 | clear_bit(STRIPE_SYNCING, &sh->state); | 2611 | clear_bit(STRIPE_SYNCING, &sh->state); |
@@ -2755,48 +2621,25 @@ static void handle_stripe5(struct stripe_head *sh) | |||
2755 | !test_bit(R5_LOCKED, &dev->flags) && | 2621 | !test_bit(R5_LOCKED, &dev->flags) && |
2756 | test_bit(R5_UPTODATE, &dev->flags)) || | 2622 | test_bit(R5_UPTODATE, &dev->flags)) || |
2757 | (s.failed == 1 && s.failed_num == sh->pd_idx))) | 2623 | (s.failed == 1 && s.failed_num == sh->pd_idx))) |
2758 | handle_completed_write_requests(conf, sh, disks, &return_bi); | 2624 | handle_stripe_clean_event(conf, sh, disks, &return_bi); |
2759 | 2625 | ||
2760 | /* Now we might consider reading some blocks, either to check/generate | 2626 | /* Now we might consider reading some blocks, either to check/generate |
2761 | * parity, or to satisfy requests | 2627 | * parity, or to satisfy requests |
2762 | * or to load a block that is being partially written. | 2628 | * or to load a block that is being partially written. |
2763 | */ | 2629 | */ |
2764 | if (s.to_read || s.non_overwrite || | 2630 | if (s.to_read || s.non_overwrite || |
2765 | (s.syncing && (s.uptodate + s.compute < disks)) || s.expanding || | 2631 | (s.syncing && (s.uptodate + s.compute < disks)) || s.expanding) |
2766 | test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending)) | 2632 | handle_stripe_fill5(sh, &s, disks); |
2767 | handle_issuing_new_read_requests5(sh, &s, disks); | ||
2768 | 2633 | ||
2769 | /* Now we check to see if any write operations have recently | 2634 | /* Now we check to see if any write operations have recently |
2770 | * completed | 2635 | * completed |
2771 | */ | 2636 | */ |
2772 | |||
2773 | /* leave prexor set until postxor is done, allows us to distinguish | ||
2774 | * a rmw from a rcw during biodrain | ||
2775 | */ | ||
2776 | prexor = 0; | 2637 | prexor = 0; |
2777 | if (test_bit(STRIPE_OP_PREXOR, &sh->ops.complete) && | 2638 | if (sh->reconstruct_state == reconstruct_state_prexor_drain_result) |
2778 | test_bit(STRIPE_OP_POSTXOR, &sh->ops.complete)) { | ||
2779 | |||
2780 | prexor = 1; | 2639 | prexor = 1; |
2781 | clear_bit(STRIPE_OP_PREXOR, &sh->ops.complete); | 2640 | if (sh->reconstruct_state == reconstruct_state_drain_result || |
2782 | clear_bit(STRIPE_OP_PREXOR, &sh->ops.ack); | 2641 | sh->reconstruct_state == reconstruct_state_prexor_drain_result) { |
2783 | clear_bit(STRIPE_OP_PREXOR, &sh->ops.pending); | 2642 | sh->reconstruct_state = reconstruct_state_idle; |
2784 | |||
2785 | for (i = disks; i--; ) | ||
2786 | clear_bit(R5_Wantprexor, &sh->dev[i].flags); | ||
2787 | } | ||
2788 | |||
2789 | /* if only POSTXOR is set then this is an 'expand' postxor */ | ||
2790 | if (test_bit(STRIPE_OP_BIODRAIN, &sh->ops.complete) && | ||
2791 | test_bit(STRIPE_OP_POSTXOR, &sh->ops.complete)) { | ||
2792 | |||
2793 | clear_bit(STRIPE_OP_BIODRAIN, &sh->ops.complete); | ||
2794 | clear_bit(STRIPE_OP_BIODRAIN, &sh->ops.ack); | ||
2795 | clear_bit(STRIPE_OP_BIODRAIN, &sh->ops.pending); | ||
2796 | |||
2797 | clear_bit(STRIPE_OP_POSTXOR, &sh->ops.complete); | ||
2798 | clear_bit(STRIPE_OP_POSTXOR, &sh->ops.ack); | ||
2799 | clear_bit(STRIPE_OP_POSTXOR, &sh->ops.pending); | ||
2800 | 2643 | ||
2801 | /* All the 'written' buffers and the parity block are ready to | 2644 | /* All the 'written' buffers and the parity block are ready to |
2802 | * be written back to disk | 2645 | * be written back to disk |
@@ -2808,9 +2651,6 @@ static void handle_stripe5(struct stripe_head *sh) | |||
2808 | (i == sh->pd_idx || dev->written)) { | 2651 | (i == sh->pd_idx || dev->written)) { |
2809 | pr_debug("Writing block %d\n", i); | 2652 | pr_debug("Writing block %d\n", i); |
2810 | set_bit(R5_Wantwrite, &dev->flags); | 2653 | set_bit(R5_Wantwrite, &dev->flags); |
2811 | if (!test_and_set_bit( | ||
2812 | STRIPE_OP_IO, &sh->ops.pending)) | ||
2813 | sh->ops.count++; | ||
2814 | if (prexor) | 2654 | if (prexor) |
2815 | continue; | 2655 | continue; |
2816 | if (!test_bit(R5_Insync, &dev->flags) || | 2656 | if (!test_bit(R5_Insync, &dev->flags) || |
@@ -2832,20 +2672,18 @@ static void handle_stripe5(struct stripe_head *sh) | |||
2832 | * 2/ A 'check' operation is in flight, as it may clobber the parity | 2672 | * 2/ A 'check' operation is in flight, as it may clobber the parity |
2833 | * block. | 2673 | * block. |
2834 | */ | 2674 | */ |
2835 | if (s.to_write && !test_bit(STRIPE_OP_POSTXOR, &sh->ops.pending) && | 2675 | if (s.to_write && !sh->reconstruct_state && !sh->check_state) |
2836 | !test_bit(STRIPE_OP_CHECK, &sh->ops.pending)) | 2676 | handle_stripe_dirtying5(conf, sh, &s, disks); |
2837 | handle_issuing_new_write_requests5(conf, sh, &s, disks); | ||
2838 | 2677 | ||
2839 | /* maybe we need to check and possibly fix the parity for this stripe | 2678 | /* maybe we need to check and possibly fix the parity for this stripe |
2840 | * Any reads will already have been scheduled, so we just see if enough | 2679 | * Any reads will already have been scheduled, so we just see if enough |
2841 | * data is available. The parity check is held off while parity | 2680 | * data is available. The parity check is held off while parity |
2842 | * dependent operations are in flight. | 2681 | * dependent operations are in flight. |
2843 | */ | 2682 | */ |
2844 | if ((s.syncing && s.locked == 0 && | 2683 | if (sh->check_state || |
2845 | !test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending) && | 2684 | (s.syncing && s.locked == 0 && |
2846 | !test_bit(STRIPE_INSYNC, &sh->state)) || | 2685 | !test_bit(STRIPE_COMPUTE_RUN, &sh->state) && |
2847 | test_bit(STRIPE_OP_CHECK, &sh->ops.pending) || | 2686 | !test_bit(STRIPE_INSYNC, &sh->state))) |
2848 | test_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending)) | ||
2849 | handle_parity_checks5(conf, sh, &s, disks); | 2687 | handle_parity_checks5(conf, sh, &s, disks); |
2850 | 2688 | ||
2851 | if (s.syncing && s.locked == 0 && test_bit(STRIPE_INSYNC, &sh->state)) { | 2689 | if (s.syncing && s.locked == 0 && test_bit(STRIPE_INSYNC, &sh->state)) { |
@@ -2864,52 +2702,35 @@ static void handle_stripe5(struct stripe_head *sh) | |||
2864 | dev = &sh->dev[s.failed_num]; | 2702 | dev = &sh->dev[s.failed_num]; |
2865 | if (!test_bit(R5_ReWrite, &dev->flags)) { | 2703 | if (!test_bit(R5_ReWrite, &dev->flags)) { |
2866 | set_bit(R5_Wantwrite, &dev->flags); | 2704 | set_bit(R5_Wantwrite, &dev->flags); |
2867 | if (!test_and_set_bit(STRIPE_OP_IO, &sh->ops.pending)) | ||
2868 | sh->ops.count++; | ||
2869 | set_bit(R5_ReWrite, &dev->flags); | 2705 | set_bit(R5_ReWrite, &dev->flags); |
2870 | set_bit(R5_LOCKED, &dev->flags); | 2706 | set_bit(R5_LOCKED, &dev->flags); |
2871 | s.locked++; | 2707 | s.locked++; |
2872 | } else { | 2708 | } else { |
2873 | /* let's read it back */ | 2709 | /* let's read it back */ |
2874 | set_bit(R5_Wantread, &dev->flags); | 2710 | set_bit(R5_Wantread, &dev->flags); |
2875 | if (!test_and_set_bit(STRIPE_OP_IO, &sh->ops.pending)) | ||
2876 | sh->ops.count++; | ||
2877 | set_bit(R5_LOCKED, &dev->flags); | 2711 | set_bit(R5_LOCKED, &dev->flags); |
2878 | s.locked++; | 2712 | s.locked++; |
2879 | } | 2713 | } |
2880 | } | 2714 | } |
2881 | 2715 | ||
2882 | /* Finish postxor operations initiated by the expansion | 2716 | /* Finish reconstruct operations initiated by the expansion process */ |
2883 | * process | 2717 | if (sh->reconstruct_state == reconstruct_state_result) { |
2884 | */ | 2718 | sh->reconstruct_state = reconstruct_state_idle; |
2885 | if (test_bit(STRIPE_OP_POSTXOR, &sh->ops.complete) && | ||
2886 | !test_bit(STRIPE_OP_BIODRAIN, &sh->ops.pending)) { | ||
2887 | |||
2888 | clear_bit(STRIPE_EXPANDING, &sh->state); | 2719 | clear_bit(STRIPE_EXPANDING, &sh->state); |
2889 | 2720 | for (i = conf->raid_disks; i--; ) | |
2890 | clear_bit(STRIPE_OP_POSTXOR, &sh->ops.pending); | ||
2891 | clear_bit(STRIPE_OP_POSTXOR, &sh->ops.ack); | ||
2892 | clear_bit(STRIPE_OP_POSTXOR, &sh->ops.complete); | ||
2893 | |||
2894 | for (i = conf->raid_disks; i--; ) { | ||
2895 | set_bit(R5_Wantwrite, &sh->dev[i].flags); | 2721 | set_bit(R5_Wantwrite, &sh->dev[i].flags); |
2896 | set_bit(R5_LOCKED, &dev->flags); | 2722 | set_bit(R5_LOCKED, &dev->flags); |
2897 | s.locked++; | 2723 | s.locked++; |
2898 | if (!test_and_set_bit(STRIPE_OP_IO, &sh->ops.pending)) | ||
2899 | sh->ops.count++; | ||
2900 | } | ||
2901 | } | 2724 | } |
2902 | 2725 | ||
2903 | if (s.expanded && test_bit(STRIPE_EXPANDING, &sh->state) && | 2726 | if (s.expanded && test_bit(STRIPE_EXPANDING, &sh->state) && |
2904 | !test_bit(STRIPE_OP_POSTXOR, &sh->ops.pending)) { | 2727 | !sh->reconstruct_state) { |
2905 | /* Need to write out all blocks after computing parity */ | 2728 | /* Need to write out all blocks after computing parity */ |
2906 | sh->disks = conf->raid_disks; | 2729 | sh->disks = conf->raid_disks; |
2907 | sh->pd_idx = stripe_to_pdidx(sh->sector, conf, | 2730 | sh->pd_idx = stripe_to_pdidx(sh->sector, conf, |
2908 | conf->raid_disks); | 2731 | conf->raid_disks); |
2909 | s.locked += handle_write_operations5(sh, 1, 1); | 2732 | schedule_reconstruction5(sh, &s, 1, 1); |
2910 | } else if (s.expanded && | 2733 | } else if (s.expanded && !sh->reconstruct_state && s.locked == 0) { |
2911 | s.locked == 0 && | ||
2912 | !test_bit(STRIPE_OP_POSTXOR, &sh->ops.pending)) { | ||
2913 | clear_bit(STRIPE_EXPAND_READY, &sh->state); | 2734 | clear_bit(STRIPE_EXPAND_READY, &sh->state); |
2914 | atomic_dec(&conf->reshape_stripes); | 2735 | atomic_dec(&conf->reshape_stripes); |
2915 | wake_up(&conf->wait_for_overlap); | 2736 | wake_up(&conf->wait_for_overlap); |
@@ -2917,12 +2738,9 @@ static void handle_stripe5(struct stripe_head *sh) | |||
2917 | } | 2738 | } |
2918 | 2739 | ||
2919 | if (s.expanding && s.locked == 0 && | 2740 | if (s.expanding && s.locked == 0 && |
2920 | !test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending)) | 2741 | !test_bit(STRIPE_COMPUTE_RUN, &sh->state)) |
2921 | handle_stripe_expansion(conf, sh, NULL); | 2742 | handle_stripe_expansion(conf, sh, NULL); |
2922 | 2743 | ||
2923 | if (sh->ops.count) | ||
2924 | pending = get_stripe_work(sh); | ||
2925 | |||
2926 | unlock: | 2744 | unlock: |
2927 | spin_unlock(&sh->lock); | 2745 | spin_unlock(&sh->lock); |
2928 | 2746 | ||
@@ -2930,11 +2748,12 @@ static void handle_stripe5(struct stripe_head *sh) | |||
2930 | if (unlikely(blocked_rdev)) | 2748 | if (unlikely(blocked_rdev)) |
2931 | md_wait_for_blocked_rdev(blocked_rdev, conf->mddev); | 2749 | md_wait_for_blocked_rdev(blocked_rdev, conf->mddev); |
2932 | 2750 | ||
2933 | if (pending) | 2751 | if (s.ops_request) |
2934 | raid5_run_ops(sh, pending); | 2752 | raid5_run_ops(sh, s.ops_request); |
2935 | 2753 | ||
2936 | return_io(return_bi); | 2754 | ops_run_io(sh, &s); |
2937 | 2755 | ||
2756 | return_io(return_bi); | ||
2938 | } | 2757 | } |
2939 | 2758 | ||
2940 | static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page) | 2759 | static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page) |
@@ -3042,8 +2861,7 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page) | |||
3042 | * might need to be failed | 2861 | * might need to be failed |
3043 | */ | 2862 | */ |
3044 | if (s.failed > 2 && s.to_read+s.to_write+s.written) | 2863 | if (s.failed > 2 && s.to_read+s.to_write+s.written) |
3045 | handle_requests_to_failed_array(conf, sh, &s, disks, | 2864 | handle_failed_stripe(conf, sh, &s, disks, &return_bi); |
3046 | &return_bi); | ||
3047 | if (s.failed > 2 && s.syncing) { | 2865 | if (s.failed > 2 && s.syncing) { |
3048 | md_done_sync(conf->mddev, STRIPE_SECTORS,0); | 2866 | md_done_sync(conf->mddev, STRIPE_SECTORS,0); |
3049 | clear_bit(STRIPE_SYNCING, &sh->state); | 2867 | clear_bit(STRIPE_SYNCING, &sh->state); |
@@ -3068,7 +2886,7 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page) | |||
3068 | ( r6s.q_failed || ((test_bit(R5_Insync, &qdev->flags) | 2886 | ( r6s.q_failed || ((test_bit(R5_Insync, &qdev->flags) |
3069 | && !test_bit(R5_LOCKED, &qdev->flags) | 2887 | && !test_bit(R5_LOCKED, &qdev->flags) |
3070 | && test_bit(R5_UPTODATE, &qdev->flags))))) | 2888 | && test_bit(R5_UPTODATE, &qdev->flags))))) |
3071 | handle_completed_write_requests(conf, sh, disks, &return_bi); | 2889 | handle_stripe_clean_event(conf, sh, disks, &return_bi); |
3072 | 2890 | ||
3073 | /* Now we might consider reading some blocks, either to check/generate | 2891 | /* Now we might consider reading some blocks, either to check/generate |
3074 | * parity, or to satisfy requests | 2892 | * parity, or to satisfy requests |
@@ -3076,11 +2894,11 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page) | |||
3076 | */ | 2894 | */ |
3077 | if (s.to_read || s.non_overwrite || (s.to_write && s.failed) || | 2895 | if (s.to_read || s.non_overwrite || (s.to_write && s.failed) || |
3078 | (s.syncing && (s.uptodate < disks)) || s.expanding) | 2896 | (s.syncing && (s.uptodate < disks)) || s.expanding) |
3079 | handle_issuing_new_read_requests6(sh, &s, &r6s, disks); | 2897 | handle_stripe_fill6(sh, &s, &r6s, disks); |
3080 | 2898 | ||
3081 | /* now to consider writing and what else, if anything should be read */ | 2899 | /* now to consider writing and what else, if anything should be read */ |
3082 | if (s.to_write) | 2900 | if (s.to_write) |
3083 | handle_issuing_new_write_requests6(conf, sh, &s, &r6s, disks); | 2901 | handle_stripe_dirtying6(conf, sh, &s, &r6s, disks); |
3084 | 2902 | ||
3085 | /* maybe we need to check and possibly fix the parity for this stripe | 2903 | /* maybe we need to check and possibly fix the parity for this stripe |
3086 | * Any reads will already have been scheduled, so we just see if enough | 2904 | * Any reads will already have been scheduled, so we just see if enough |
@@ -3136,7 +2954,7 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page) | |||
3136 | } | 2954 | } |
3137 | 2955 | ||
3138 | if (s.expanding && s.locked == 0 && | 2956 | if (s.expanding && s.locked == 0 && |
3139 | !test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending)) | 2957 | !test_bit(STRIPE_COMPUTE_RUN, &sh->state)) |
3140 | handle_stripe_expansion(conf, sh, &r6s); | 2958 | handle_stripe_expansion(conf, sh, &r6s); |
3141 | 2959 | ||
3142 | unlock: | 2960 | unlock: |
@@ -3146,68 +2964,9 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page) | |||
3146 | if (unlikely(blocked_rdev)) | 2964 | if (unlikely(blocked_rdev)) |
3147 | md_wait_for_blocked_rdev(blocked_rdev, conf->mddev); | 2965 | md_wait_for_blocked_rdev(blocked_rdev, conf->mddev); |
3148 | 2966 | ||
3149 | return_io(return_bi); | 2967 | ops_run_io(sh, &s); |
3150 | |||
3151 | for (i=disks; i-- ;) { | ||
3152 | int rw; | ||
3153 | struct bio *bi; | ||
3154 | mdk_rdev_t *rdev; | ||
3155 | if (test_and_clear_bit(R5_Wantwrite, &sh->dev[i].flags)) | ||
3156 | rw = WRITE; | ||
3157 | else if (test_and_clear_bit(R5_Wantread, &sh->dev[i].flags)) | ||
3158 | rw = READ; | ||
3159 | else | ||
3160 | continue; | ||
3161 | |||
3162 | set_bit(STRIPE_IO_STARTED, &sh->state); | ||
3163 | |||
3164 | bi = &sh->dev[i].req; | ||
3165 | |||
3166 | bi->bi_rw = rw; | ||
3167 | if (rw == WRITE) | ||
3168 | bi->bi_end_io = raid5_end_write_request; | ||
3169 | else | ||
3170 | bi->bi_end_io = raid5_end_read_request; | ||
3171 | |||
3172 | rcu_read_lock(); | ||
3173 | rdev = rcu_dereference(conf->disks[i].rdev); | ||
3174 | if (rdev && test_bit(Faulty, &rdev->flags)) | ||
3175 | rdev = NULL; | ||
3176 | if (rdev) | ||
3177 | atomic_inc(&rdev->nr_pending); | ||
3178 | rcu_read_unlock(); | ||
3179 | 2968 | ||
3180 | if (rdev) { | 2969 | return_io(return_bi); |
3181 | if (s.syncing || s.expanding || s.expanded) | ||
3182 | md_sync_acct(rdev->bdev, STRIPE_SECTORS); | ||
3183 | |||
3184 | bi->bi_bdev = rdev->bdev; | ||
3185 | pr_debug("for %llu schedule op %ld on disc %d\n", | ||
3186 | (unsigned long long)sh->sector, bi->bi_rw, i); | ||
3187 | atomic_inc(&sh->count); | ||
3188 | bi->bi_sector = sh->sector + rdev->data_offset; | ||
3189 | bi->bi_flags = 1 << BIO_UPTODATE; | ||
3190 | bi->bi_vcnt = 1; | ||
3191 | bi->bi_max_vecs = 1; | ||
3192 | bi->bi_idx = 0; | ||
3193 | bi->bi_io_vec = &sh->dev[i].vec; | ||
3194 | bi->bi_io_vec[0].bv_len = STRIPE_SIZE; | ||
3195 | bi->bi_io_vec[0].bv_offset = 0; | ||
3196 | bi->bi_size = STRIPE_SIZE; | ||
3197 | bi->bi_next = NULL; | ||
3198 | if (rw == WRITE && | ||
3199 | test_bit(R5_ReWrite, &sh->dev[i].flags)) | ||
3200 | atomic_add(STRIPE_SECTORS, &rdev->corrected_errors); | ||
3201 | generic_make_request(bi); | ||
3202 | } else { | ||
3203 | if (rw == WRITE) | ||
3204 | set_bit(STRIPE_DEGRADED, &sh->state); | ||
3205 | pr_debug("skip op %ld on disc %d for sector %llu\n", | ||
3206 | bi->bi_rw, i, (unsigned long long)sh->sector); | ||
3207 | clear_bit(R5_LOCKED, &sh->dev[i].flags); | ||
3208 | set_bit(STRIPE_HANDLE, &sh->state); | ||
3209 | } | ||
3210 | } | ||
3211 | } | 2970 | } |
3212 | 2971 | ||
3213 | static void handle_stripe(struct stripe_head *sh, struct page *tmp_page) | 2972 | static void handle_stripe(struct stripe_head *sh, struct page *tmp_page) |
@@ -3697,9 +3456,7 @@ static int make_request(struct request_queue *q, struct bio * bi) | |||
3697 | if ( rw == WRITE ) | 3456 | if ( rw == WRITE ) |
3698 | md_write_end(mddev); | 3457 | md_write_end(mddev); |
3699 | 3458 | ||
3700 | bi->bi_end_io(bi, | 3459 | bio_endio(bi, 0); |
3701 | test_bit(BIO_UPTODATE, &bi->bi_flags) | ||
3702 | ? 0 : -EIO); | ||
3703 | } | 3460 | } |
3704 | return 0; | 3461 | return 0; |
3705 | } | 3462 | } |
@@ -3785,7 +3542,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped | |||
3785 | j == raid6_next_disk(sh->pd_idx, sh->disks)) | 3542 | j == raid6_next_disk(sh->pd_idx, sh->disks)) |
3786 | continue; | 3543 | continue; |
3787 | s = compute_blocknr(sh, j); | 3544 | s = compute_blocknr(sh, j); |
3788 | if (s < (mddev->array_size<<1)) { | 3545 | if (s < mddev->array_sectors) { |
3789 | skipped = 1; | 3546 | skipped = 1; |
3790 | continue; | 3547 | continue; |
3791 | } | 3548 | } |
@@ -4002,12 +3759,8 @@ static int retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio) | |||
4002 | spin_lock_irq(&conf->device_lock); | 3759 | spin_lock_irq(&conf->device_lock); |
4003 | remaining = --raid_bio->bi_phys_segments; | 3760 | remaining = --raid_bio->bi_phys_segments; |
4004 | spin_unlock_irq(&conf->device_lock); | 3761 | spin_unlock_irq(&conf->device_lock); |
4005 | if (remaining == 0) { | 3762 | if (remaining == 0) |
4006 | 3763 | bio_endio(raid_bio, 0); | |
4007 | raid_bio->bi_end_io(raid_bio, | ||
4008 | test_bit(BIO_UPTODATE, &raid_bio->bi_flags) | ||
4009 | ? 0 : -EIO); | ||
4010 | } | ||
4011 | if (atomic_dec_and_test(&conf->active_aligned_reads)) | 3764 | if (atomic_dec_and_test(&conf->active_aligned_reads)) |
4012 | wake_up(&conf->wait_for_stripe); | 3765 | wake_up(&conf->wait_for_stripe); |
4013 | return handled; | 3766 | return handled; |
@@ -4094,6 +3847,8 @@ raid5_store_stripe_cache_size(mddev_t *mddev, const char *page, size_t len) | |||
4094 | { | 3847 | { |
4095 | raid5_conf_t *conf = mddev_to_conf(mddev); | 3848 | raid5_conf_t *conf = mddev_to_conf(mddev); |
4096 | unsigned long new; | 3849 | unsigned long new; |
3850 | int err; | ||
3851 | |||
4097 | if (len >= PAGE_SIZE) | 3852 | if (len >= PAGE_SIZE) |
4098 | return -EINVAL; | 3853 | return -EINVAL; |
4099 | if (!conf) | 3854 | if (!conf) |
@@ -4109,7 +3864,9 @@ raid5_store_stripe_cache_size(mddev_t *mddev, const char *page, size_t len) | |||
4109 | else | 3864 | else |
4110 | break; | 3865 | break; |
4111 | } | 3866 | } |
4112 | md_allow_write(mddev); | 3867 | err = md_allow_write(mddev); |
3868 | if (err) | ||
3869 | return err; | ||
4113 | while (new > conf->max_nr_stripes) { | 3870 | while (new > conf->max_nr_stripes) { |
4114 | if (grow_one_stripe(conf)) | 3871 | if (grow_one_stripe(conf)) |
4115 | conf->max_nr_stripes++; | 3872 | conf->max_nr_stripes++; |
@@ -4434,7 +4191,7 @@ static int run(mddev_t *mddev) | |||
4434 | mddev->queue->backing_dev_info.congested_data = mddev; | 4191 | mddev->queue->backing_dev_info.congested_data = mddev; |
4435 | mddev->queue->backing_dev_info.congested_fn = raid5_congested; | 4192 | mddev->queue->backing_dev_info.congested_fn = raid5_congested; |
4436 | 4193 | ||
4437 | mddev->array_size = mddev->size * (conf->previous_raid_disks - | 4194 | mddev->array_sectors = 2 * mddev->size * (conf->previous_raid_disks - |
4438 | conf->max_degraded); | 4195 | conf->max_degraded); |
4439 | 4196 | ||
4440 | blk_queue_merge_bvec(mddev->queue, raid5_mergeable_bvec); | 4197 | blk_queue_merge_bvec(mddev->queue, raid5_mergeable_bvec); |
@@ -4609,35 +4366,41 @@ abort: | |||
4609 | static int raid5_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | 4366 | static int raid5_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) |
4610 | { | 4367 | { |
4611 | raid5_conf_t *conf = mddev->private; | 4368 | raid5_conf_t *conf = mddev->private; |
4612 | int found = 0; | 4369 | int err = -EEXIST; |
4613 | int disk; | 4370 | int disk; |
4614 | struct disk_info *p; | 4371 | struct disk_info *p; |
4372 | int first = 0; | ||
4373 | int last = conf->raid_disks - 1; | ||
4615 | 4374 | ||
4616 | if (mddev->degraded > conf->max_degraded) | 4375 | if (mddev->degraded > conf->max_degraded) |
4617 | /* no point adding a device */ | 4376 | /* no point adding a device */ |
4618 | return 0; | 4377 | return -EINVAL; |
4378 | |||
4379 | if (rdev->raid_disk >= 0) | ||
4380 | first = last = rdev->raid_disk; | ||
4619 | 4381 | ||
4620 | /* | 4382 | /* |
4621 | * find the disk ... but prefer rdev->saved_raid_disk | 4383 | * find the disk ... but prefer rdev->saved_raid_disk |
4622 | * if possible. | 4384 | * if possible. |
4623 | */ | 4385 | */ |
4624 | if (rdev->saved_raid_disk >= 0 && | 4386 | if (rdev->saved_raid_disk >= 0 && |
4387 | rdev->saved_raid_disk >= first && | ||
4625 | conf->disks[rdev->saved_raid_disk].rdev == NULL) | 4388 | conf->disks[rdev->saved_raid_disk].rdev == NULL) |
4626 | disk = rdev->saved_raid_disk; | 4389 | disk = rdev->saved_raid_disk; |
4627 | else | 4390 | else |
4628 | disk = 0; | 4391 | disk = first; |
4629 | for ( ; disk < conf->raid_disks; disk++) | 4392 | for ( ; disk <= last ; disk++) |
4630 | if ((p=conf->disks + disk)->rdev == NULL) { | 4393 | if ((p=conf->disks + disk)->rdev == NULL) { |
4631 | clear_bit(In_sync, &rdev->flags); | 4394 | clear_bit(In_sync, &rdev->flags); |
4632 | rdev->raid_disk = disk; | 4395 | rdev->raid_disk = disk; |
4633 | found = 1; | 4396 | err = 0; |
4634 | if (rdev->saved_raid_disk != disk) | 4397 | if (rdev->saved_raid_disk != disk) |
4635 | conf->fullsync = 1; | 4398 | conf->fullsync = 1; |
4636 | rcu_assign_pointer(p->rdev, rdev); | 4399 | rcu_assign_pointer(p->rdev, rdev); |
4637 | break; | 4400 | break; |
4638 | } | 4401 | } |
4639 | print_raid5_conf(conf); | 4402 | print_raid5_conf(conf); |
4640 | return found; | 4403 | return err; |
4641 | } | 4404 | } |
4642 | 4405 | ||
4643 | static int raid5_resize(mddev_t *mddev, sector_t sectors) | 4406 | static int raid5_resize(mddev_t *mddev, sector_t sectors) |
@@ -4652,8 +4415,9 @@ static int raid5_resize(mddev_t *mddev, sector_t sectors) | |||
4652 | raid5_conf_t *conf = mddev_to_conf(mddev); | 4415 | raid5_conf_t *conf = mddev_to_conf(mddev); |
4653 | 4416 | ||
4654 | sectors &= ~((sector_t)mddev->chunk_size/512 - 1); | 4417 | sectors &= ~((sector_t)mddev->chunk_size/512 - 1); |
4655 | mddev->array_size = (sectors * (mddev->raid_disks-conf->max_degraded))>>1; | 4418 | mddev->array_sectors = sectors * (mddev->raid_disks |
4656 | set_capacity(mddev->gendisk, mddev->array_size << 1); | 4419 | - conf->max_degraded); |
4420 | set_capacity(mddev->gendisk, mddev->array_sectors); | ||
4657 | mddev->changed = 1; | 4421 | mddev->changed = 1; |
4658 | if (sectors/2 > mddev->size && mddev->recovery_cp == MaxSector) { | 4422 | if (sectors/2 > mddev->size && mddev->recovery_cp == MaxSector) { |
4659 | mddev->recovery_cp = mddev->size << 1; | 4423 | mddev->recovery_cp = mddev->size << 1; |
@@ -4738,7 +4502,7 @@ static int raid5_start_reshape(mddev_t *mddev) | |||
4738 | rdev_for_each(rdev, rtmp, mddev) | 4502 | rdev_for_each(rdev, rtmp, mddev) |
4739 | if (rdev->raid_disk < 0 && | 4503 | if (rdev->raid_disk < 0 && |
4740 | !test_bit(Faulty, &rdev->flags)) { | 4504 | !test_bit(Faulty, &rdev->flags)) { |
4741 | if (raid5_add_disk(mddev, rdev)) { | 4505 | if (raid5_add_disk(mddev, rdev) == 0) { |
4742 | char nm[20]; | 4506 | char nm[20]; |
4743 | set_bit(In_sync, &rdev->flags); | 4507 | set_bit(In_sync, &rdev->flags); |
4744 | added_devices++; | 4508 | added_devices++; |
@@ -4786,15 +4550,16 @@ static void end_reshape(raid5_conf_t *conf) | |||
4786 | struct block_device *bdev; | 4550 | struct block_device *bdev; |
4787 | 4551 | ||
4788 | if (!test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) { | 4552 | if (!test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) { |
4789 | conf->mddev->array_size = conf->mddev->size * | 4553 | conf->mddev->array_sectors = 2 * conf->mddev->size * |
4790 | (conf->raid_disks - conf->max_degraded); | 4554 | (conf->raid_disks - conf->max_degraded); |
4791 | set_capacity(conf->mddev->gendisk, conf->mddev->array_size << 1); | 4555 | set_capacity(conf->mddev->gendisk, conf->mddev->array_sectors); |
4792 | conf->mddev->changed = 1; | 4556 | conf->mddev->changed = 1; |
4793 | 4557 | ||
4794 | bdev = bdget_disk(conf->mddev->gendisk, 0); | 4558 | bdev = bdget_disk(conf->mddev->gendisk, 0); |
4795 | if (bdev) { | 4559 | if (bdev) { |
4796 | mutex_lock(&bdev->bd_inode->i_mutex); | 4560 | mutex_lock(&bdev->bd_inode->i_mutex); |
4797 | i_size_write(bdev->bd_inode, (loff_t)conf->mddev->array_size << 10); | 4561 | i_size_write(bdev->bd_inode, |
4562 | (loff_t)conf->mddev->array_sectors << 9); | ||
4798 | mutex_unlock(&bdev->bd_inode->i_mutex); | 4563 | mutex_unlock(&bdev->bd_inode->i_mutex); |
4799 | bdput(bdev); | 4564 | bdput(bdev); |
4800 | } | 4565 | } |
diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c index 513ba61ae966..777637594acd 100644 --- a/drivers/sbus/char/uctrl.c +++ b/drivers/sbus/char/uctrl.c | |||
@@ -195,8 +195,8 @@ struct uctrl_driver { | |||
195 | 195 | ||
196 | static struct uctrl_driver drv; | 196 | static struct uctrl_driver drv; |
197 | 197 | ||
198 | void uctrl_get_event_status(void); | 198 | static void uctrl_get_event_status(void); |
199 | void uctrl_get_external_status(void); | 199 | static void uctrl_get_external_status(void); |
200 | 200 | ||
201 | static int | 201 | static int |
202 | uctrl_ioctl(struct inode *inode, struct file *file, | 202 | uctrl_ioctl(struct inode *inode, struct file *file, |
@@ -266,12 +266,6 @@ static struct miscdevice uctrl_dev = { | |||
266 | driver->regs->uctrl_stat = UCTRL_STAT_RXNE_STA; \ | 266 | driver->regs->uctrl_stat = UCTRL_STAT_RXNE_STA; \ |
267 | } | 267 | } |
268 | 268 | ||
269 | void uctrl_set_video(int status) | ||
270 | { | ||
271 | struct uctrl_driver *driver = &drv; | ||
272 | |||
273 | } | ||
274 | |||
275 | static void uctrl_do_txn(struct uctrl_txn *txn) | 269 | static void uctrl_do_txn(struct uctrl_txn *txn) |
276 | { | 270 | { |
277 | struct uctrl_driver *driver = &drv; | 271 | struct uctrl_driver *driver = &drv; |
@@ -311,7 +305,7 @@ static void uctrl_do_txn(struct uctrl_txn *txn) | |||
311 | } | 305 | } |
312 | } | 306 | } |
313 | 307 | ||
314 | void uctrl_get_event_status(void) | 308 | static void uctrl_get_event_status(void) |
315 | { | 309 | { |
316 | struct uctrl_driver *driver = &drv; | 310 | struct uctrl_driver *driver = &drv; |
317 | struct uctrl_txn txn; | 311 | struct uctrl_txn txn; |
@@ -331,7 +325,7 @@ void uctrl_get_event_status(void) | |||
331 | dprintk(("ev is %x\n", driver->status.event_status)); | 325 | dprintk(("ev is %x\n", driver->status.event_status)); |
332 | } | 326 | } |
333 | 327 | ||
334 | void uctrl_get_external_status(void) | 328 | static void uctrl_get_external_status(void) |
335 | { | 329 | { |
336 | struct uctrl_driver *driver = &drv; | 330 | struct uctrl_driver *driver = &drv; |
337 | struct uctrl_txn txn; | 331 | struct uctrl_txn txn; |
@@ -363,7 +357,7 @@ void uctrl_get_external_status(void) | |||
363 | static int __init ts102_uctrl_init(void) | 357 | static int __init ts102_uctrl_init(void) |
364 | { | 358 | { |
365 | struct uctrl_driver *driver = &drv; | 359 | struct uctrl_driver *driver = &drv; |
366 | int len, i; | 360 | int len; |
367 | struct linux_prom_irqs tmp_irq[2]; | 361 | struct linux_prom_irqs tmp_irq[2]; |
368 | unsigned int vaddr[2] = { 0, 0 }; | 362 | unsigned int vaddr[2] = { 0, 0 }; |
369 | int tmpnode, uctrlnode = prom_getchild(prom_root_node); | 363 | int tmpnode, uctrlnode = prom_getchild(prom_root_node); |
diff --git a/drivers/sbus/char/vfc.h b/drivers/sbus/char/vfc.h index f1aa1389ea4a..a5240c52aa0b 100644 --- a/drivers/sbus/char/vfc.h +++ b/drivers/sbus/char/vfc.h | |||
@@ -133,8 +133,6 @@ struct vfc_dev { | |||
133 | unsigned char saa9051_state_array[VFC_SAA9051_NR]; | 133 | unsigned char saa9051_state_array[VFC_SAA9051_NR]; |
134 | }; | 134 | }; |
135 | 135 | ||
136 | extern struct vfc_dev **vfc_dev_lst; | ||
137 | |||
138 | void captstat_reset(struct vfc_dev *); | 136 | void captstat_reset(struct vfc_dev *); |
139 | void memptr_reset(struct vfc_dev *); | 137 | void memptr_reset(struct vfc_dev *); |
140 | 138 | ||
@@ -145,8 +143,6 @@ int vfc_i2c_sendbuf(struct vfc_dev *, unsigned char, char *, int) ; | |||
145 | int vfc_i2c_recvbuf(struct vfc_dev *, unsigned char, char *, int) ; | 143 | int vfc_i2c_recvbuf(struct vfc_dev *, unsigned char, char *, int) ; |
146 | int vfc_i2c_reset_bus(struct vfc_dev *); | 144 | int vfc_i2c_reset_bus(struct vfc_dev *); |
147 | int vfc_init_i2c_bus(struct vfc_dev *); | 145 | int vfc_init_i2c_bus(struct vfc_dev *); |
148 | void vfc_lock_device(struct vfc_dev *); | ||
149 | void vfc_unlock_device(struct vfc_dev *); | ||
150 | 146 | ||
151 | #define VFC_CONTROL_DIAGMODE 0x10000000 | 147 | #define VFC_CONTROL_DIAGMODE 0x10000000 |
152 | #define VFC_CONTROL_MEMPTR 0x20000000 | 148 | #define VFC_CONTROL_MEMPTR 0x20000000 |
diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c index 1f6cb8ae2784..25181bb7d627 100644 --- a/drivers/sbus/char/vfc_dev.c +++ b/drivers/sbus/char/vfc_dev.c | |||
@@ -45,7 +45,7 @@ | |||
45 | #include <asm/vfc_ioctls.h> | 45 | #include <asm/vfc_ioctls.h> |
46 | 46 | ||
47 | static const struct file_operations vfc_fops; | 47 | static const struct file_operations vfc_fops; |
48 | struct vfc_dev **vfc_dev_lst; | 48 | static struct vfc_dev **vfc_dev_lst; |
49 | static char vfcstr[]="vfc"; | 49 | static char vfcstr[]="vfc"; |
50 | static unsigned char saa9051_init_array[VFC_SAA9051_NR] = { | 50 | static unsigned char saa9051_init_array[VFC_SAA9051_NR] = { |
51 | 0x00, 0x64, 0x72, 0x52, | 51 | 0x00, 0x64, 0x72, 0x52, |
@@ -54,18 +54,18 @@ static unsigned char saa9051_init_array[VFC_SAA9051_NR] = { | |||
54 | 0x3e | 54 | 0x3e |
55 | }; | 55 | }; |
56 | 56 | ||
57 | void vfc_lock_device(struct vfc_dev *dev) | 57 | static void vfc_lock_device(struct vfc_dev *dev) |
58 | { | 58 | { |
59 | mutex_lock(&dev->device_lock_mtx); | 59 | mutex_lock(&dev->device_lock_mtx); |
60 | } | 60 | } |
61 | 61 | ||
62 | void vfc_unlock_device(struct vfc_dev *dev) | 62 | static void vfc_unlock_device(struct vfc_dev *dev) |
63 | { | 63 | { |
64 | mutex_unlock(&dev->device_lock_mtx); | 64 | mutex_unlock(&dev->device_lock_mtx); |
65 | } | 65 | } |
66 | 66 | ||
67 | 67 | ||
68 | void vfc_captstat_reset(struct vfc_dev *dev) | 68 | static void vfc_captstat_reset(struct vfc_dev *dev) |
69 | { | 69 | { |
70 | dev->control_reg |= VFC_CONTROL_CAPTRESET; | 70 | dev->control_reg |= VFC_CONTROL_CAPTRESET; |
71 | sbus_writel(dev->control_reg, &dev->regs->control); | 71 | sbus_writel(dev->control_reg, &dev->regs->control); |
@@ -75,7 +75,7 @@ void vfc_captstat_reset(struct vfc_dev *dev) | |||
75 | sbus_writel(dev->control_reg, &dev->regs->control); | 75 | sbus_writel(dev->control_reg, &dev->regs->control); |
76 | } | 76 | } |
77 | 77 | ||
78 | void vfc_memptr_reset(struct vfc_dev *dev) | 78 | static void vfc_memptr_reset(struct vfc_dev *dev) |
79 | { | 79 | { |
80 | dev->control_reg |= VFC_CONTROL_MEMPTR; | 80 | dev->control_reg |= VFC_CONTROL_MEMPTR; |
81 | sbus_writel(dev->control_reg, &dev->regs->control); | 81 | sbus_writel(dev->control_reg, &dev->regs->control); |
@@ -85,7 +85,7 @@ void vfc_memptr_reset(struct vfc_dev *dev) | |||
85 | sbus_writel(dev->control_reg, &dev->regs->control); | 85 | sbus_writel(dev->control_reg, &dev->regs->control); |
86 | } | 86 | } |
87 | 87 | ||
88 | int vfc_csr_init(struct vfc_dev *dev) | 88 | static int vfc_csr_init(struct vfc_dev *dev) |
89 | { | 89 | { |
90 | dev->control_reg = 0x80000000; | 90 | dev->control_reg = 0x80000000; |
91 | sbus_writel(dev->control_reg, &dev->regs->control); | 91 | sbus_writel(dev->control_reg, &dev->regs->control); |
@@ -107,7 +107,7 @@ int vfc_csr_init(struct vfc_dev *dev) | |||
107 | return 0; | 107 | return 0; |
108 | } | 108 | } |
109 | 109 | ||
110 | int vfc_saa9051_init(struct vfc_dev *dev) | 110 | static int vfc_saa9051_init(struct vfc_dev *dev) |
111 | { | 111 | { |
112 | int i; | 112 | int i; |
113 | 113 | ||
@@ -119,7 +119,7 @@ int vfc_saa9051_init(struct vfc_dev *dev) | |||
119 | return 0; | 119 | return 0; |
120 | } | 120 | } |
121 | 121 | ||
122 | int init_vfc_hw(struct vfc_dev *dev) | 122 | static int init_vfc_hw(struct vfc_dev *dev) |
123 | { | 123 | { |
124 | vfc_lock_device(dev); | 124 | vfc_lock_device(dev); |
125 | vfc_csr_init(dev); | 125 | vfc_csr_init(dev); |
@@ -132,7 +132,7 @@ int init_vfc_hw(struct vfc_dev *dev) | |||
132 | return 0; | 132 | return 0; |
133 | } | 133 | } |
134 | 134 | ||
135 | int init_vfc_devstruct(struct vfc_dev *dev, int instance) | 135 | static int init_vfc_devstruct(struct vfc_dev *dev, int instance) |
136 | { | 136 | { |
137 | dev->instance=instance; | 137 | dev->instance=instance; |
138 | mutex_init(&dev->device_lock_mtx); | 138 | mutex_init(&dev->device_lock_mtx); |
@@ -141,7 +141,8 @@ int init_vfc_devstruct(struct vfc_dev *dev, int instance) | |||
141 | return 0; | 141 | return 0; |
142 | } | 142 | } |
143 | 143 | ||
144 | int init_vfc_device(struct sbus_dev *sdev,struct vfc_dev *dev, int instance) | 144 | static int init_vfc_device(struct sbus_dev *sdev,struct vfc_dev *dev, |
145 | int instance) | ||
145 | { | 146 | { |
146 | if(dev == NULL) { | 147 | if(dev == NULL) { |
147 | printk(KERN_ERR "VFC: Bogus pointer passed\n"); | 148 | printk(KERN_ERR "VFC: Bogus pointer passed\n"); |
@@ -168,7 +169,7 @@ int init_vfc_device(struct sbus_dev *sdev,struct vfc_dev *dev, int instance) | |||
168 | } | 169 | } |
169 | 170 | ||
170 | 171 | ||
171 | struct vfc_dev *vfc_get_dev_ptr(int instance) | 172 | static struct vfc_dev *vfc_get_dev_ptr(int instance) |
172 | { | 173 | { |
173 | return vfc_dev_lst[instance]; | 174 | return vfc_dev_lst[instance]; |
174 | } | 175 | } |
@@ -292,7 +293,7 @@ static int vfc_debug(struct vfc_dev *dev, int cmd, void __user *argp) | |||
292 | return 0; | 293 | return 0; |
293 | } | 294 | } |
294 | 295 | ||
295 | int vfc_capture_start(struct vfc_dev *dev) | 296 | static int vfc_capture_start(struct vfc_dev *dev) |
296 | { | 297 | { |
297 | vfc_captstat_reset(dev); | 298 | vfc_captstat_reset(dev); |
298 | dev->control_reg = sbus_readl(&dev->regs->control); | 299 | dev->control_reg = sbus_readl(&dev->regs->control); |
@@ -314,7 +315,7 @@ int vfc_capture_start(struct vfc_dev *dev) | |||
314 | return 0; | 315 | return 0; |
315 | } | 316 | } |
316 | 317 | ||
317 | int vfc_capture_poll(struct vfc_dev *dev) | 318 | static int vfc_capture_poll(struct vfc_dev *dev) |
318 | { | 319 | { |
319 | int timeout = 1000; | 320 | int timeout = 1000; |
320 | 321 | ||
@@ -390,8 +391,8 @@ static int vfc_set_control_ioctl(struct inode *inode, struct file *file, | |||
390 | } | 391 | } |
391 | 392 | ||
392 | 393 | ||
393 | int vfc_port_change_ioctl(struct inode *inode, struct file *file, | 394 | static int vfc_port_change_ioctl(struct inode *inode, struct file *file, |
394 | struct vfc_dev *dev, unsigned long arg) | 395 | struct vfc_dev *dev, unsigned long arg) |
395 | { | 396 | { |
396 | int ret = 0; | 397 | int ret = 0; |
397 | int cmd; | 398 | int cmd; |
@@ -460,8 +461,8 @@ int vfc_port_change_ioctl(struct inode *inode, struct file *file, | |||
460 | return ret; | 461 | return ret; |
461 | } | 462 | } |
462 | 463 | ||
463 | int vfc_set_video_ioctl(struct inode *inode, struct file *file, | 464 | static int vfc_set_video_ioctl(struct inode *inode, struct file *file, |
464 | struct vfc_dev *dev, unsigned long arg) | 465 | struct vfc_dev *dev, unsigned long arg) |
465 | { | 466 | { |
466 | int ret = 0; | 467 | int ret = 0; |
467 | int cmd; | 468 | int cmd; |
@@ -511,8 +512,8 @@ int vfc_set_video_ioctl(struct inode *inode, struct file *file, | |||
511 | return ret; | 512 | return ret; |
512 | } | 513 | } |
513 | 514 | ||
514 | int vfc_get_video_ioctl(struct inode *inode, struct file *file, | 515 | static int vfc_get_video_ioctl(struct inode *inode, struct file *file, |
515 | struct vfc_dev *dev, unsigned long arg) | 516 | struct vfc_dev *dev, unsigned long arg) |
516 | { | 517 | { |
517 | int ret = 0; | 518 | int ret = 0; |
518 | unsigned int status = NO_LOCK; | 519 | unsigned int status = NO_LOCK; |
diff --git a/drivers/sbus/char/vfc_i2c.c b/drivers/sbus/char/vfc_i2c.c index 9efed771f6c0..32b986e0ed78 100644 --- a/drivers/sbus/char/vfc_i2c.c +++ b/drivers/sbus/char/vfc_i2c.c | |||
@@ -114,7 +114,7 @@ int vfc_i2c_reset_bus(struct vfc_dev *dev) | |||
114 | return 0; | 114 | return 0; |
115 | } | 115 | } |
116 | 116 | ||
117 | int vfc_i2c_wait_for_bus(struct vfc_dev *dev) | 117 | static int vfc_i2c_wait_for_bus(struct vfc_dev *dev) |
118 | { | 118 | { |
119 | int timeout = 1000; | 119 | int timeout = 1000; |
120 | 120 | ||
@@ -126,7 +126,7 @@ int vfc_i2c_wait_for_bus(struct vfc_dev *dev) | |||
126 | return 0; | 126 | return 0; |
127 | } | 127 | } |
128 | 128 | ||
129 | int vfc_i2c_wait_for_pin(struct vfc_dev *dev, int ack) | 129 | static int vfc_i2c_wait_for_pin(struct vfc_dev *dev, int ack) |
130 | { | 130 | { |
131 | int timeout = 1000; | 131 | int timeout = 1000; |
132 | int s1; | 132 | int s1; |
@@ -144,7 +144,8 @@ int vfc_i2c_wait_for_pin(struct vfc_dev *dev, int ack) | |||
144 | } | 144 | } |
145 | 145 | ||
146 | #define SHIFT(a) ((a) << 24) | 146 | #define SHIFT(a) ((a) << 24) |
147 | int vfc_i2c_xmit_addr(struct vfc_dev *dev, unsigned char addr, char mode) | 147 | static int vfc_i2c_xmit_addr(struct vfc_dev *dev, unsigned char addr, |
148 | char mode) | ||
148 | { | 149 | { |
149 | int ret, raddr; | 150 | int ret, raddr; |
150 | #if 1 | 151 | #if 1 |
@@ -195,7 +196,7 @@ int vfc_i2c_xmit_addr(struct vfc_dev *dev, unsigned char addr, char mode) | |||
195 | return 0; | 196 | return 0; |
196 | } | 197 | } |
197 | 198 | ||
198 | int vfc_i2c_xmit_byte(struct vfc_dev *dev,unsigned char *byte) | 199 | static int vfc_i2c_xmit_byte(struct vfc_dev *dev,unsigned char *byte) |
199 | { | 200 | { |
200 | int ret; | 201 | int ret; |
201 | u32 val = SHIFT((unsigned int)*byte); | 202 | u32 val = SHIFT((unsigned int)*byte); |
@@ -218,7 +219,8 @@ int vfc_i2c_xmit_byte(struct vfc_dev *dev,unsigned char *byte) | |||
218 | return ret; | 219 | return ret; |
219 | } | 220 | } |
220 | 221 | ||
221 | int vfc_i2c_recv_byte(struct vfc_dev *dev, unsigned char *byte, int last) | 222 | static int vfc_i2c_recv_byte(struct vfc_dev *dev, unsigned char *byte, |
223 | int last) | ||
222 | { | 224 | { |
223 | int ret; | 225 | int ret; |
224 | 226 | ||
diff --git a/drivers/sbus/dvma.c b/drivers/sbus/dvma.c index 57e1526746a2..ab0d2de3324c 100644 --- a/drivers/sbus/dvma.c +++ b/drivers/sbus/dvma.c | |||
@@ -16,7 +16,7 @@ | |||
16 | 16 | ||
17 | struct sbus_dma *dma_chain; | 17 | struct sbus_dma *dma_chain; |
18 | 18 | ||
19 | void __init init_one_dvma(struct sbus_dma *dma, int num_dma) | 19 | static void __init init_one_dvma(struct sbus_dma *dma, int num_dma) |
20 | { | 20 | { |
21 | printk("dma%d: ", num_dma); | 21 | printk("dma%d: ", num_dma); |
22 | 22 | ||