diff options
author | Dmitry Torokhov <dtor_core@ameritech.net> | 2006-01-29 21:51:31 -0500 |
---|---|---|
committer | Dmitry Torokhov <dtor_core@ameritech.net> | 2006-01-29 21:51:31 -0500 |
commit | 84c61896bd756a440c54be07b6e97ad230f31a16 (patch) | |
tree | 549455a63ef49d763b7f96952b53bd52327acbeb | |
parent | 0399addd71565b27eae27821fa04dad44f8644fe (diff) |
Input: db9 - fix possible crash with Saturn gamepads
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
-rw-r--r-- | drivers/input/joystick/db9.c | 70 |
1 files changed, 36 insertions, 34 deletions
diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c index 499344c72756..98479b82842d 100644 --- a/drivers/input/joystick/db9.c +++ b/drivers/input/joystick/db9.c | |||
@@ -275,68 +275,70 @@ static unsigned char db9_saturn_read_packet(struct parport *port, unsigned char | |||
275 | /* | 275 | /* |
276 | * db9_saturn_report() analyzes packet and reports. | 276 | * db9_saturn_report() analyzes packet and reports. |
277 | */ | 277 | */ |
278 | static int db9_saturn_report(unsigned char id, unsigned char data[60], struct input_dev *dev, int n, int max_pads) | 278 | static int db9_saturn_report(unsigned char id, unsigned char data[60], struct input_dev *devs[], int n, int max_pads) |
279 | { | 279 | { |
280 | struct input_dev *dev; | ||
280 | int tmp, i, j; | 281 | int tmp, i, j; |
281 | 282 | ||
282 | tmp = (id == 0x41) ? 60 : 10; | 283 | tmp = (id == 0x41) ? 60 : 10; |
283 | for (j = 0; (j < tmp) && (n < max_pads); j += 10, n++) { | 284 | for (j = 0; j < tmp && n < max_pads; j += 10, n++) { |
285 | dev = devs[n]; | ||
284 | switch (data[j]) { | 286 | switch (data[j]) { |
285 | case 0x16: /* multi controller (analog 4 axis) */ | 287 | case 0x16: /* multi controller (analog 4 axis) */ |
286 | input_report_abs(dev + n, db9_abs[5], data[j + 6]); | 288 | input_report_abs(dev, db9_abs[5], data[j + 6]); |
287 | case 0x15: /* mission stick (analog 3 axis) */ | 289 | case 0x15: /* mission stick (analog 3 axis) */ |
288 | input_report_abs(dev + n, db9_abs[3], data[j + 4]); | 290 | input_report_abs(dev, db9_abs[3], data[j + 4]); |
289 | input_report_abs(dev + n, db9_abs[4], data[j + 5]); | 291 | input_report_abs(dev, db9_abs[4], data[j + 5]); |
290 | case 0x13: /* racing controller (analog 1 axis) */ | 292 | case 0x13: /* racing controller (analog 1 axis) */ |
291 | input_report_abs(dev + n, db9_abs[2], data[j + 3]); | 293 | input_report_abs(dev, db9_abs[2], data[j + 3]); |
292 | case 0x34: /* saturn keyboard (udlr ZXC ASD QE Esc) */ | 294 | case 0x34: /* saturn keyboard (udlr ZXC ASD QE Esc) */ |
293 | case 0x02: /* digital pad (digital 2 axis + buttons) */ | 295 | case 0x02: /* digital pad (digital 2 axis + buttons) */ |
294 | input_report_abs(dev + n, db9_abs[0], !(data[j + 1] & 128) - !(data[j + 1] & 64)); | 296 | input_report_abs(dev, db9_abs[0], !(data[j + 1] & 128) - !(data[j + 1] & 64)); |
295 | input_report_abs(dev + n, db9_abs[1], !(data[j + 1] & 32) - !(data[j + 1] & 16)); | 297 | input_report_abs(dev, db9_abs[1], !(data[j + 1] & 32) - !(data[j + 1] & 16)); |
296 | for (i = 0; i < 9; i++) | 298 | for (i = 0; i < 9; i++) |
297 | input_report_key(dev + n, db9_cd32_btn[i], ~data[j + db9_saturn_byte[i]] & db9_saturn_mask[i]); | 299 | input_report_key(dev, db9_cd32_btn[i], ~data[j + db9_saturn_byte[i]] & db9_saturn_mask[i]); |
298 | break; | 300 | break; |
299 | case 0x19: /* mission stick x2 (analog 6 axis + buttons) */ | 301 | case 0x19: /* mission stick x2 (analog 6 axis + buttons) */ |
300 | input_report_abs(dev + n, db9_abs[0], !(data[j + 1] & 128) - !(data[j + 1] & 64)); | 302 | input_report_abs(dev, db9_abs[0], !(data[j + 1] & 128) - !(data[j + 1] & 64)); |
301 | input_report_abs(dev + n, db9_abs[1], !(data[j + 1] & 32) - !(data[j + 1] & 16)); | 303 | input_report_abs(dev, db9_abs[1], !(data[j + 1] & 32) - !(data[j + 1] & 16)); |
302 | for (i = 0; i < 9; i++) | 304 | for (i = 0; i < 9; i++) |
303 | input_report_key(dev + n, db9_cd32_btn[i], ~data[j + db9_saturn_byte[i]] & db9_saturn_mask[i]); | 305 | input_report_key(dev, db9_cd32_btn[i], ~data[j + db9_saturn_byte[i]] & db9_saturn_mask[i]); |
304 | input_report_abs(dev + n, db9_abs[2], data[j + 3]); | 306 | input_report_abs(dev, db9_abs[2], data[j + 3]); |
305 | input_report_abs(dev + n, db9_abs[3], data[j + 4]); | 307 | input_report_abs(dev, db9_abs[3], data[j + 4]); |
306 | input_report_abs(dev + n, db9_abs[4], data[j + 5]); | 308 | input_report_abs(dev, db9_abs[4], data[j + 5]); |
307 | /* | 309 | /* |
308 | input_report_abs(dev + n, db9_abs[8], (data[j + 6] & 128 ? 0 : 1) - (data[j + 6] & 64 ? 0 : 1)); | 310 | input_report_abs(dev, db9_abs[8], (data[j + 6] & 128 ? 0 : 1) - (data[j + 6] & 64 ? 0 : 1)); |
309 | input_report_abs(dev + n, db9_abs[9], (data[j + 6] & 32 ? 0 : 1) - (data[j + 6] & 16 ? 0 : 1)); | 311 | input_report_abs(dev, db9_abs[9], (data[j + 6] & 32 ? 0 : 1) - (data[j + 6] & 16 ? 0 : 1)); |
310 | */ | 312 | */ |
311 | input_report_abs(dev + n, db9_abs[6], data[j + 7]); | 313 | input_report_abs(dev, db9_abs[6], data[j + 7]); |
312 | input_report_abs(dev + n, db9_abs[7], data[j + 8]); | 314 | input_report_abs(dev, db9_abs[7], data[j + 8]); |
313 | input_report_abs(dev + n, db9_abs[5], data[j + 9]); | 315 | input_report_abs(dev, db9_abs[5], data[j + 9]); |
314 | break; | 316 | break; |
315 | case 0xd3: /* sankyo ff (analog 1 axis + stop btn) */ | 317 | case 0xd3: /* sankyo ff (analog 1 axis + stop btn) */ |
316 | input_report_key(dev + n, BTN_A, data[j + 3] & 0x80); | 318 | input_report_key(dev, BTN_A, data[j + 3] & 0x80); |
317 | input_report_abs(dev + n, db9_abs[2], data[j + 3] & 0x7f); | 319 | input_report_abs(dev, db9_abs[2], data[j + 3] & 0x7f); |
318 | break; | 320 | break; |
319 | case 0xe3: /* shuttle mouse (analog 2 axis + buttons. signed value) */ | 321 | case 0xe3: /* shuttle mouse (analog 2 axis + buttons. signed value) */ |
320 | input_report_key(dev + n, BTN_START, data[j + 1] & 0x08); | 322 | input_report_key(dev, BTN_START, data[j + 1] & 0x08); |
321 | input_report_key(dev + n, BTN_A, data[j + 1] & 0x04); | 323 | input_report_key(dev, BTN_A, data[j + 1] & 0x04); |
322 | input_report_key(dev + n, BTN_C, data[j + 1] & 0x02); | 324 | input_report_key(dev, BTN_C, data[j + 1] & 0x02); |
323 | input_report_key(dev + n, BTN_B, data[j + 1] & 0x01); | 325 | input_report_key(dev, BTN_B, data[j + 1] & 0x01); |
324 | input_report_abs(dev + n, db9_abs[2], data[j + 2] ^ 0x80); | 326 | input_report_abs(dev, db9_abs[2], data[j + 2] ^ 0x80); |
325 | input_report_abs(dev + n, db9_abs[3], (0xff-(data[j + 3] ^ 0x80))+1); /* */ | 327 | input_report_abs(dev, db9_abs[3], (0xff-(data[j + 3] ^ 0x80))+1); /* */ |
326 | break; | 328 | break; |
327 | case 0xff: | 329 | case 0xff: |
328 | default: /* no pad */ | 330 | default: /* no pad */ |
329 | input_report_abs(dev + n, db9_abs[0], 0); | 331 | input_report_abs(dev, db9_abs[0], 0); |
330 | input_report_abs(dev + n, db9_abs[1], 0); | 332 | input_report_abs(dev, db9_abs[1], 0); |
331 | for (i = 0; i < 9; i++) | 333 | for (i = 0; i < 9; i++) |
332 | input_report_key(dev + n, db9_cd32_btn[i], 0); | 334 | input_report_key(dev, db9_cd32_btn[i], 0); |
333 | break; | 335 | break; |
334 | } | 336 | } |
335 | } | 337 | } |
336 | return n; | 338 | return n; |
337 | } | 339 | } |
338 | 340 | ||
339 | static int db9_saturn(int mode, struct parport *port, struct input_dev *dev) | 341 | static int db9_saturn(int mode, struct parport *port, struct input_dev *devs[]) |
340 | { | 342 | { |
341 | unsigned char id, data[60]; | 343 | unsigned char id, data[60]; |
342 | int type, n, max_pads; | 344 | int type, n, max_pads; |
@@ -361,7 +363,7 @@ static int db9_saturn(int mode, struct parport *port, struct input_dev *dev) | |||
361 | max_pads = min(db9_modes[mode].n_pads, DB9_MAX_DEVICES); | 363 | max_pads = min(db9_modes[mode].n_pads, DB9_MAX_DEVICES); |
362 | for (tmp = 0, i = 0; i < n; i++) { | 364 | for (tmp = 0, i = 0; i < n; i++) { |
363 | id = db9_saturn_read_packet(port, data, type + i, 1); | 365 | id = db9_saturn_read_packet(port, data, type + i, 1); |
364 | tmp = db9_saturn_report(id, data, dev, tmp, max_pads); | 366 | tmp = db9_saturn_report(id, data, devs, tmp, max_pads); |
365 | } | 367 | } |
366 | return 0; | 368 | return 0; |
367 | } | 369 | } |
@@ -489,7 +491,7 @@ static void db9_timer(unsigned long private) | |||
489 | case DB9_SATURN_DPP: | 491 | case DB9_SATURN_DPP: |
490 | case DB9_SATURN_DPP_2: | 492 | case DB9_SATURN_DPP_2: |
491 | 493 | ||
492 | db9_saturn(db9->mode, port, dev); | 494 | db9_saturn(db9->mode, port, db9->dev); |
493 | break; | 495 | break; |
494 | 496 | ||
495 | case DB9_CD32_PAD: | 497 | case DB9_CD32_PAD: |