.. | .. |
---|
39 | 39 | #include <linux/isdn/capiutil.h> |
---|
40 | 40 | #include <linux/isdn/capicmd.h> |
---|
41 | 41 | |
---|
42 | | -MODULE_DESCRIPTION("CAPI4Linux: Userspace /dev/capi20 interface"); |
---|
| 42 | +#include "kcapi.h" |
---|
| 43 | + |
---|
| 44 | +MODULE_DESCRIPTION("CAPI4Linux: kernel CAPI layer and /dev/capi20 interface"); |
---|
43 | 45 | MODULE_AUTHOR("Carsten Paeth"); |
---|
44 | 46 | MODULE_LICENSE("GPL"); |
---|
45 | 47 | |
---|
.. | .. |
---|
950 | 952 | return ret; |
---|
951 | 953 | } |
---|
952 | 954 | |
---|
| 955 | +#ifdef CONFIG_COMPAT |
---|
| 956 | +static long |
---|
| 957 | +capi_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
---|
| 958 | +{ |
---|
| 959 | + int ret; |
---|
| 960 | + |
---|
| 961 | + if (cmd == CAPI_MANUFACTURER_CMD) { |
---|
| 962 | + struct { |
---|
| 963 | + compat_ulong_t cmd; |
---|
| 964 | + compat_uptr_t data; |
---|
| 965 | + } mcmd32; |
---|
| 966 | + |
---|
| 967 | + if (!capable(CAP_SYS_ADMIN)) |
---|
| 968 | + return -EPERM; |
---|
| 969 | + if (copy_from_user(&mcmd32, compat_ptr(arg), sizeof(mcmd32))) |
---|
| 970 | + return -EFAULT; |
---|
| 971 | + |
---|
| 972 | + mutex_lock(&capi_mutex); |
---|
| 973 | + ret = capi20_manufacturer(mcmd32.cmd, compat_ptr(mcmd32.data)); |
---|
| 974 | + mutex_unlock(&capi_mutex); |
---|
| 975 | + |
---|
| 976 | + return ret; |
---|
| 977 | + } |
---|
| 978 | + |
---|
| 979 | + return capi_unlocked_ioctl(file, cmd, (unsigned long)compat_ptr(arg)); |
---|
| 980 | +} |
---|
| 981 | +#endif |
---|
| 982 | + |
---|
953 | 983 | static int capi_open(struct inode *inode, struct file *file) |
---|
954 | 984 | { |
---|
955 | 985 | struct capidev *cdev; |
---|
.. | .. |
---|
968 | 998 | list_add_tail(&cdev->list, &capidev_list); |
---|
969 | 999 | mutex_unlock(&capidev_list_lock); |
---|
970 | 1000 | |
---|
971 | | - return nonseekable_open(inode, file); |
---|
| 1001 | + return stream_open(inode, file); |
---|
972 | 1002 | } |
---|
973 | 1003 | |
---|
974 | 1004 | static int capi_release(struct inode *inode, struct file *file) |
---|
.. | .. |
---|
996 | 1026 | .write = capi_write, |
---|
997 | 1027 | .poll = capi_poll, |
---|
998 | 1028 | .unlocked_ioctl = capi_unlocked_ioctl, |
---|
| 1029 | +#ifdef CONFIG_COMPAT |
---|
| 1030 | + .compat_ioctl = capi_compat_ioctl, |
---|
| 1031 | +#endif |
---|
999 | 1032 | .open = capi_open, |
---|
1000 | 1033 | .release = capi_release, |
---|
1001 | 1034 | }; |
---|
.. | .. |
---|
1163 | 1196 | return mp->outbytes; |
---|
1164 | 1197 | } |
---|
1165 | 1198 | |
---|
1166 | | -static int capinc_tty_ioctl(struct tty_struct *tty, |
---|
1167 | | - unsigned int cmd, unsigned long arg) |
---|
1168 | | -{ |
---|
1169 | | - return -ENOIOCTLCMD; |
---|
1170 | | -} |
---|
1171 | | - |
---|
1172 | 1199 | static void capinc_tty_set_termios(struct tty_struct *tty, struct ktermios *old) |
---|
1173 | 1200 | { |
---|
1174 | 1201 | pr_debug("capinc_tty_set_termios\n"); |
---|
.. | .. |
---|
1244 | 1271 | .flush_chars = capinc_tty_flush_chars, |
---|
1245 | 1272 | .write_room = capinc_tty_write_room, |
---|
1246 | 1273 | .chars_in_buffer = capinc_tty_chars_in_buffer, |
---|
1247 | | - .ioctl = capinc_tty_ioctl, |
---|
1248 | 1274 | .set_termios = capinc_tty_set_termios, |
---|
1249 | 1275 | .throttle = capinc_tty_throttle, |
---|
1250 | 1276 | .unthrottle = capinc_tty_unthrottle, |
---|
.. | .. |
---|
1388 | 1414 | { |
---|
1389 | 1415 | const char *compileinfo; |
---|
1390 | 1416 | int major_ret; |
---|
| 1417 | + int ret; |
---|
| 1418 | + |
---|
| 1419 | + ret = kcapi_init(); |
---|
| 1420 | + if (ret) |
---|
| 1421 | + return ret; |
---|
1391 | 1422 | |
---|
1392 | 1423 | major_ret = register_chrdev(capi_major, "capi20", &capi_fops); |
---|
1393 | 1424 | if (major_ret < 0) { |
---|
1394 | 1425 | printk(KERN_ERR "capi20: unable to get major %d\n", capi_major); |
---|
| 1426 | + kcapi_exit(); |
---|
1395 | 1427 | return major_ret; |
---|
1396 | 1428 | } |
---|
1397 | 1429 | capi_class = class_create(THIS_MODULE, "capi"); |
---|
1398 | 1430 | if (IS_ERR(capi_class)) { |
---|
1399 | 1431 | unregister_chrdev(capi_major, "capi20"); |
---|
| 1432 | + kcapi_exit(); |
---|
1400 | 1433 | return PTR_ERR(capi_class); |
---|
1401 | 1434 | } |
---|
1402 | 1435 | |
---|
.. | .. |
---|
1406 | 1439 | device_destroy(capi_class, MKDEV(capi_major, 0)); |
---|
1407 | 1440 | class_destroy(capi_class); |
---|
1408 | 1441 | unregister_chrdev(capi_major, "capi20"); |
---|
| 1442 | + kcapi_exit(); |
---|
1409 | 1443 | return -ENOMEM; |
---|
1410 | 1444 | } |
---|
1411 | 1445 | |
---|
.. | .. |
---|
1431 | 1465 | unregister_chrdev(capi_major, "capi20"); |
---|
1432 | 1466 | |
---|
1433 | 1467 | capinc_tty_exit(); |
---|
| 1468 | + |
---|
| 1469 | + kcapi_exit(); |
---|
1434 | 1470 | } |
---|
1435 | 1471 | |
---|
1436 | 1472 | module_init(capi_init); |
---|