📄 fusiondev.c
字号:
FusionCallNew call; FusionCallExecute execute; FusionCallReturn call_ret; switch (_IOC_NR(cmd)) { case _IOC_NR(FUSION_CALL_NEW): if (copy_from_user (&call, (FusionCallNew*) arg, sizeof(call))) return -EFAULT; ret = fusion_call_new (dev, fusion_id, &call); if (ret) return ret; if (put_user (call.call_id, (int*) arg)) { fusion_call_destroy (dev, fusion_id, call.call_id); return -EFAULT; } return 0; case _IOC_NR(FUSION_CALL_EXECUTE): if (copy_from_user (&execute, (FusionCallExecute*) arg, sizeof(execute))) return -EFAULT; ret = fusion_call_execute (dev, fusion_id, &execute); if (ret) return ret; if (put_user (execute.ret_val, (int*) arg)) return -EFAULT; return 0; case _IOC_NR(FUSION_CALL_RETURN): if (copy_from_user (&call_ret, (FusionCallReturn*) arg, sizeof(call_ret))) return -EFAULT; return fusion_call_return (dev, fusion_id, &call_ret); case _IOC_NR(FUSION_CALL_DESTROY): if (get_user (id, (int*) arg)) return -EFAULT; return fusion_call_destroy (dev, fusion_id, id); } return -ENOSYS;}static intref_ioctl (FusionDev *dev, int fusion_id, unsigned int cmd, unsigned long arg){ int id; int ret; int refs; FusionRefWatch watch; FusionRefInherit inherit; switch (_IOC_NR(cmd)) { case _IOC_NR(FUSION_REF_NEW): ret = fusion_ref_new (dev, &id); if (ret) return ret; if (put_user (id, (int*) arg)) { fusion_ref_destroy (dev, id); return -EFAULT; } return 0; case _IOC_NR(FUSION_REF_UP): if (get_user (id, (int*) arg)) return -EFAULT; return fusion_ref_up (dev, id, fusion_id); case _IOC_NR(FUSION_REF_UP_GLOBAL): if (get_user (id, (int*) arg)) return -EFAULT; return fusion_ref_up (dev, id, 0); case _IOC_NR(FUSION_REF_DOWN): if (get_user (id, (int*) arg)) return -EFAULT; return fusion_ref_down (dev, id, fusion_id); case _IOC_NR(FUSION_REF_DOWN_GLOBAL): if (get_user (id, (int*) arg)) return -EFAULT; return fusion_ref_down (dev, id, 0); case _IOC_NR(FUSION_REF_ZERO_LOCK): if (get_user (id, (int*) arg)) return -EFAULT; return fusion_ref_zero_lock (dev, id, fusion_id); case _IOC_NR(FUSION_REF_ZERO_TRYLOCK): if (get_user (id, (int*) arg)) return -EFAULT; return fusion_ref_zero_trylock (dev, id, fusion_id); case _IOC_NR(FUSION_REF_UNLOCK): if (get_user (id, (int*) arg)) return -EFAULT; return fusion_ref_unlock (dev, id, fusion_id); case _IOC_NR(FUSION_REF_STAT): if (get_user (id, (int*) arg)) return -EFAULT; ret = fusion_ref_stat (dev, id, &refs); if (ret) return ret; return refs; case _IOC_NR(FUSION_REF_WATCH): if (copy_from_user (&watch, (FusionRefWatch*) arg, sizeof(watch))) return -EFAULT; return fusion_ref_watch (dev, watch.id, watch.call_id, watch.call_arg); case _IOC_NR(FUSION_REF_INHERIT): if (copy_from_user (&inherit, (FusionRefInherit*) arg, sizeof(inherit))) return -EFAULT; return fusion_ref_inherit (dev, inherit.id, inherit.from); case _IOC_NR(FUSION_REF_DESTROY): if (get_user (id, (int*) arg)) return -EFAULT; return fusion_ref_destroy (dev, id); } return -ENOSYS;}static intskirmish_ioctl (FusionDev *dev, int fusion_id, unsigned int cmd, unsigned long arg){ int id; int ret; switch (_IOC_NR(cmd)) { case _IOC_NR(FUSION_SKIRMISH_NEW): ret = fusion_skirmish_new (dev, &id); if (ret) return ret; if (put_user (id, (int*) arg)) { fusion_skirmish_destroy (dev, id); return -EFAULT; } return 0; case _IOC_NR(FUSION_SKIRMISH_PREVAIL): if (get_user (id, (int*) arg)) return -EFAULT; return fusion_skirmish_prevail (dev, id, fusion_id); case _IOC_NR(FUSION_SKIRMISH_SWOOP): if (get_user (id, (int*) arg)) return -EFAULT; return fusion_skirmish_swoop (dev, id, fusion_id); case _IOC_NR(FUSION_SKIRMISH_DISMISS): if (get_user (id, (int*) arg)) return -EFAULT; return fusion_skirmish_dismiss (dev, id, fusion_id); case _IOC_NR(FUSION_SKIRMISH_DESTROY): if (get_user (id, (int*) arg)) return -EFAULT; return fusion_skirmish_destroy (dev, id); } return -ENOSYS;}static intproperty_ioctl (FusionDev *dev, int fusion_id, unsigned int cmd, unsigned long arg){ int id; int ret; switch (_IOC_NR(cmd)) { case _IOC_NR(FUSION_PROPERTY_NEW): ret = fusion_property_new (dev, &id); if (ret) return ret; if (put_user (id, (int*) arg)) { fusion_property_destroy (dev, id); return -EFAULT; } return 0; case _IOC_NR(FUSION_PROPERTY_LEASE): if (get_user (id, (int*) arg)) return -EFAULT; return fusion_property_lease (dev, id, fusion_id); case _IOC_NR(FUSION_PROPERTY_PURCHASE): if (get_user (id, (int*) arg)) return -EFAULT; return fusion_property_purchase (dev, id, fusion_id); case _IOC_NR(FUSION_PROPERTY_CEDE): if (get_user (id, (int*) arg)) return -EFAULT; return fusion_property_cede (dev, id, fusion_id); case _IOC_NR(FUSION_PROPERTY_HOLDUP): if (get_user (id, (int*) arg)) return -EFAULT; return fusion_property_holdup (dev, id, fusion_id); case _IOC_NR(FUSION_PROPERTY_DESTROY): if (get_user (id, (int*) arg)) return -EFAULT; return fusion_property_destroy (dev, id); } return -ENOSYS;}static intreactor_ioctl (FusionDev *dev, int fusion_id, unsigned int cmd, unsigned long arg){ int id; int ret; FusionReactorDispatch dispatch; switch (_IOC_NR(cmd)) { case _IOC_NR(FUSION_REACTOR_NEW): ret = fusion_reactor_new (dev, &id); if (ret) return ret; if (put_user (id, (int*) arg)) { fusion_reactor_destroy (dev, id); return -EFAULT; } return 0; case _IOC_NR(FUSION_REACTOR_ATTACH): if (get_user (id, (int*) arg)) return -EFAULT; return fusion_reactor_attach (dev, id, fusion_id); case _IOC_NR(FUSION_REACTOR_DETACH): if (get_user (id, (int*) arg)) return -EFAULT; return fusion_reactor_detach (dev, id, fusion_id); case _IOC_NR(FUSION_REACTOR_DISPATCH): if (copy_from_user (&dispatch, (FusionReactorDispatch*) arg, sizeof(dispatch))) return -EFAULT; if (dispatch.msg_size <= 0) return -EINVAL; /* message data > 64k should be stored in shared memory */ if (dispatch.msg_size > 0x10000) return -EMSGSIZE; return fusion_reactor_dispatch (dev, dispatch.reactor_id, dispatch.self ? 0 : fusion_id, dispatch.msg_size, dispatch.msg_data); case _IOC_NR(FUSION_REACTOR_DESTROY): if (get_user (id, (int*) arg)) return -EFAULT; return fusion_reactor_destroy (dev, id); } return -ENOSYS;}static intfusion_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ int id = (int) file->private_data; FusionDev *dev = fusion_devs[iminor(inode)]; DEBUG( "fusion_ioctl (0x%08x)\n", cmd ); switch (_IOC_TYPE(cmd)) { case FT_LOUNGE: return lounge_ioctl( dev, id, cmd, arg ); case FT_MESSAGING: return messaging_ioctl( dev, id, cmd, arg ); case FT_CALL: return call_ioctl( dev, id, cmd, arg ); case FT_REF: return ref_ioctl( dev, id, cmd, arg ); case FT_SKIRMISH: return skirmish_ioctl( dev, id, cmd, arg ); case FT_PROPERTY: return property_ioctl( dev, id, cmd, arg ); case FT_REACTOR: return reactor_ioctl( dev, id, cmd, arg ); } return -ENOSYS;}static struct file_operations fusion_fops = { .owner = THIS_MODULE, .open = fusion_open, .flush = fusion_flush, .release = fusion_release, .read = fusion_read, .poll = fusion_poll, .ioctl = fusion_ioctl};/******************************************************************************/#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)static int __initregister_devices(void){ int i; if (register_chrdev (FUSION_MAJOR, "fusion", &fusion_fops)) { printk (KERN_ERR "fusion: unable to get major %d\n", FUSION_MAJOR); return -EIO; }#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 2)#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13) fusion_class = class_create (THIS_MODULE, "fusion");#else fusion_class = class_simple_create (THIS_MODULE, "fusion");#endif if (IS_ERR(fusion_class)) { unregister_chrdev (FUSION_MAJOR, "fusion"); return PTR_ERR(fusion_class); }#endif devfs_mk_dir("fusion"); for (i=0; i<NUM_MINORS; i++) {#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 2)#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13) class_device_create (fusion_class, MKDEV(FUSION_MAJOR, i), NULL, "fusion%d", i);#else class_simple_device_add (fusion_class, MKDEV(FUSION_MAJOR, i), NULL, "fusion%d", i);#endif#endif devfs_mk_cdev (MKDEV(FUSION_MAJOR, i), S_IFCHR | S_IRUSR | S_IWUSR, "fusion/%d", i); } return 0;}#elsestatic int __initregister_devices(void){ int i; char buf[16]; if (devfs_register_chrdev (FUSION_MAJOR, "fusion", &fusion_fops)) { printk (KERN_ERR "fusion: unable to get major %d\n", FUSION_MAJOR); return -EIO; } for (i=0; i<NUM_MINORS; i++) { snprintf (buf, 16, "fusion/%d", i); devfs_handles[i] = devfs_register (NULL, buf, DEVFS_FL_DEFAULT, FUSION_MAJOR, i, S_IFCHR | S_IRUSR | S_IWUSR, &fusion_fops, NULL); } return 0;}#endifint __initfusion_init(void){ int ret; ret = register_devices(); if (ret) return ret; proc_fusion_dir = proc_mkdir ("fusion", NULL); return 0;}/******************************************************************************/#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)static void __exitderegister_devices(void){ int i; unregister_chrdev (FUSION_MAJOR, "fusion"); for (i=0; i<NUM_MINORS; i++) {#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 2)#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13) class_device_destroy (fusion_class, MKDEV(FUSION_MAJOR, i));#else class_simple_device_remove (MKDEV(FUSION_MAJOR, i));#endif#endif devfs_remove ("fusion/%d", i); }#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 2)#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13) class_destroy (fusion_class);#else class_simple_destroy (fusion_class);#endif#endif devfs_remove ("fusion");}#elsestatic void __exitderegister_devices(void){ int i; devfs_unregister_chrdev (FUSION_MAJOR, "fusion"); for (i=0; i<NUM_MINORS; i++) devfs_unregister (devfs_handles[i]);}#endifvoid __exitfusion_exit(void){ deregister_devices(); remove_proc_entry ("fusion", NULL);}module_init(fusion_init);module_exit(fusion_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -