|
Lines 87-97
Link Here
|
| 87 |
goto out_func; |
87 |
goto out_func; |
| 88 |
memset(kbd->fn_handler, 0, sizeof(fn_handler_fn *) * NR_FN_HANDLER); |
88 |
memset(kbd->fn_handler, 0, sizeof(fn_handler_fn *) * NR_FN_HANDLER); |
| 89 |
kbd->accent_table = |
89 |
kbd->accent_table = |
| 90 |
kmalloc(sizeof(struct kbdiacr)*MAX_DIACR, GFP_KERNEL); |
90 |
kmalloc(sizeof(struct kbdiacruc)*MAX_DIACR, GFP_KERNEL); |
| 91 |
if (!kbd->accent_table) |
91 |
if (!kbd->accent_table) |
| 92 |
goto out_fn_handler; |
92 |
goto out_fn_handler; |
| 93 |
memcpy(kbd->accent_table, accent_table, |
93 |
memcpy(kbd->accent_table, accent_table, |
| 94 |
sizeof(struct kbdiacr)*MAX_DIACR); |
94 |
sizeof(struct kbdiacruc)*MAX_DIACR); |
| 95 |
kbd->accent_table_size = accent_table_size; |
95 |
kbd->accent_table_size = accent_table_size; |
| 96 |
return kbd; |
96 |
return kbd; |
| 97 |
|
97 |
|
|
Lines 464-470
Link Here
|
| 464 |
kbd_ioctl(struct kbd_data *kbd, struct file *file, |
464 |
kbd_ioctl(struct kbd_data *kbd, struct file *file, |
| 465 |
unsigned int cmd, unsigned long arg) |
465 |
unsigned int cmd, unsigned long arg) |
| 466 |
{ |
466 |
{ |
| 467 |
struct kbdiacrs __user *a; |
|
|
| 468 |
void __user *argp; |
467 |
void __user *argp; |
| 469 |
int ct, perm; |
468 |
int ct, perm; |
| 470 |
|
469 |
|
|
Lines 485-512
Link Here
|
| 485 |
case KDSKBSENT: |
484 |
case KDSKBSENT: |
| 486 |
return do_kdgkb_ioctl(kbd, argp, cmd, perm); |
485 |
return do_kdgkb_ioctl(kbd, argp, cmd, perm); |
| 487 |
case KDGKBDIACR: |
486 |
case KDGKBDIACR: |
| 488 |
a = argp; |
487 |
{ |
| 489 |
|
488 |
struct kbdiacrs __user *a = argp; |
| 490 |
if (put_user(kbd->accent_table_size, &a->kb_cnt)) |
489 |
struct kbdiacr diacr; |
| 491 |
return -EFAULT; |
490 |
int i; |
| 492 |
ct = kbd->accent_table_size; |
491 |
|
| 493 |
if (copy_to_user(a->kbdiacr, kbd->accent_table, |
492 |
if (put_user(accent_table_size, &a->kb_cnt)) |
| 494 |
ct * sizeof(struct kbdiacr))) |
|
|
| 495 |
return -EFAULT; |
493 |
return -EFAULT; |
|
|
494 |
for (i = 0; i < accent_table_size; i++) { |
| 495 |
diacr.diacr = accent_table[i].diacr; |
| 496 |
diacr.base = accent_table[i].base; |
| 497 |
diacr.result = accent_table[i].base > 0xff ? 0 : accent_table[i].base; |
| 498 |
if (copy_to_user(a->kbdiacr + i, &diacr, sizeof(struct kbdiacr))) |
| 499 |
return -EFAULT; |
| 500 |
} |
| 496 |
return 0; |
501 |
return 0; |
|
|
502 |
} |
| 503 |
case KDGKBDIACRUC: |
| 504 |
{ |
| 505 |
struct kbdiacrsuc __user *a = argp; |
| 506 |
|
| 507 |
if (put_user(accent_table_size, &a->kb_cnt)) |
| 508 |
return -EFAULT; |
| 509 |
if (copy_to_user(a->kbdiacruc, accent_table, accent_table_size*sizeof(struct kbdiacruc))) |
| 510 |
return -EFAULT; |
| 511 |
return 0; |
| 512 |
} |
| 497 |
case KDSKBDIACR: |
513 |
case KDSKBDIACR: |
| 498 |
a = argp; |
514 |
{ |
|
|
515 |
struct kbdiacrs __user *a = argp; |
| 516 |
struct kbdiacr diacr; |
| 517 |
int i; |
| 518 |
|
| 499 |
if (!perm) |
519 |
if (!perm) |
| 500 |
return -EPERM; |
520 |
return -EPERM; |
| 501 |
if (get_user(ct, &a->kb_cnt)) |
521 |
if (get_user(ct, &a->kb_cnt)) |
| 502 |
return -EFAULT; |
522 |
return -EFAULT; |
| 503 |
if (ct >= MAX_DIACR) |
523 |
if (ct >= MAX_DIACR) |
| 504 |
return -EINVAL; |
524 |
return -EINVAL; |
| 505 |
kbd->accent_table_size = ct; |
525 |
accent_table_size = ct; |
| 506 |
if (copy_from_user(kbd->accent_table, a->kbdiacr, |
526 |
for (i = 0; i < ct; i++) { |
| 507 |
ct * sizeof(struct kbdiacr))) |
527 |
if (copy_from_user(&diacr, a->kbdiacr, sizeof(struct kbdiacr))) |
| 508 |
return -EFAULT; |
528 |
return -EFAULT; |
|
|
529 |
accent_table[i].diacr = diacr.diacr; |
| 530 |
accent_table[i].base = diacr.base; |
| 531 |
accent_table[i].result = diacr.result; |
| 532 |
} |
| 509 |
return 0; |
533 |
return 0; |
|
|
534 |
} |
| 535 |
case KDSKBDIACRUC: |
| 536 |
{ |
| 537 |
struct kbdiacrsuc __user *a = argp; |
| 538 |
unsigned int ct; |
| 539 |
|
| 540 |
if (!perm) |
| 541 |
return -EPERM; |
| 542 |
if (get_user(ct,&a->kb_cnt)) |
| 543 |
return -EFAULT; |
| 544 |
if (ct >= MAX_DIACR) |
| 545 |
return -EINVAL; |
| 546 |
accent_table_size = ct; |
| 547 |
if (copy_from_user(accent_table, a->kbdiacruc, ct*sizeof(struct kbdiacruc))) |
| 548 |
return -EFAULT; |
| 549 |
return 0; |
| 550 |
} |
| 510 |
default: |
551 |
default: |
| 511 |
return -ENOIOCTLCMD; |
552 |
return -ENOIOCTLCMD; |
| 512 |
} |
553 |
} |