📄 ioctl32.c
字号:
struct mtconfiginfo32 { __u32 mt_type; __u32 ifc_type; __u16 irqnr; __u16 dmanr; __u16 port; __u32 debug; __u32 have_dens:1; __u32 have_bsf:1; __u32 have_fsr:1; __u32 have_bsr:1; __u32 have_eod:1; __u32 have_seek:1; __u32 have_tell:1; __u32 have_ras1:1; __u32 have_ras2:1; __u32 have_ras3:1; __u32 have_qfa:1; __u32 pad1:5; char reserved[10];};#define MTIOCGETCONFIG32 _IOR('m', 4, struct mtconfiginfo32)#define MTIOCSETCONFIG32 _IOW('m', 5, struct mtconfiginfo32)static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg){ mm_segment_t old_fs = get_fs(); struct mtconfiginfo info; struct mtget get; struct mtpos pos; unsigned long kcmd; void *karg; int err = 0; switch(cmd) { case MTIOCPOS32: kcmd = MTIOCPOS; karg = &pos; break; case MTIOCGET32: kcmd = MTIOCGET; karg = &get; break; case MTIOCGETCONFIG32: kcmd = MTIOCGETCONFIG; karg = &info; break; case MTIOCSETCONFIG32: kcmd = MTIOCSETCONFIG; karg = &info; err = __get_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type); err |= __get_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type); err |= __get_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr); err |= __get_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr); err |= __get_user(info.port, &((struct mtconfiginfo32 *)arg)->port); err |= __get_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug); err |= __copy_from_user((char *)&info.debug + sizeof(info.debug), (char *)&((struct mtconfiginfo32 *)arg)->debug + sizeof(((struct mtconfiginfo32 *)arg)->debug), sizeof(__u32)); if (err) return -EFAULT; break; default: do { static int count = 0; if (++count <= 20) printk("mt_ioctl: Unknown cmd fd(%d) " "cmd(%08x) arg(%08x)\n", (int)fd, (unsigned int)cmd, (unsigned int)arg); } while(0); return -EINVAL; } set_fs (KERNEL_DS); err = sys_ioctl (fd, kcmd, (unsigned long)karg); set_fs (old_fs); if (err) return err; switch (cmd) { case MTIOCPOS32: err = __put_user(pos.mt_blkno, &((struct mtpos32 *)arg)->mt_blkno); break; case MTIOCGET32: err = __put_user(get.mt_type, &((struct mtget32 *)arg)->mt_type); err |= __put_user(get.mt_resid, &((struct mtget32 *)arg)->mt_resid); err |= __put_user(get.mt_dsreg, &((struct mtget32 *)arg)->mt_dsreg); err |= __put_user(get.mt_gstat, &((struct mtget32 *)arg)->mt_gstat); err |= __put_user(get.mt_erreg, &((struct mtget32 *)arg)->mt_erreg); err |= __put_user(get.mt_fileno, &((struct mtget32 *)arg)->mt_fileno); err |= __put_user(get.mt_blkno, &((struct mtget32 *)arg)->mt_blkno); break; case MTIOCGETCONFIG32: err = __put_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type); err |= __put_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type); err |= __put_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr); err |= __put_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr); err |= __put_user(info.port, &((struct mtconfiginfo32 *)arg)->port); err |= __put_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug); err |= __copy_to_user((char *)&((struct mtconfiginfo32 *)arg)->debug + sizeof(((struct mtconfiginfo32 *)arg)->debug), (char *)&info.debug + sizeof(info.debug), sizeof(__u32)); break; case MTIOCSETCONFIG32: break; } return err ? -EFAULT: 0;}#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int)static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg){ return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg);}struct ioctl32_handler { unsigned int cmd; int (*function)(unsigned int, unsigned int, unsigned long);};struct ioctl32_list { struct ioctl32_handler handler; struct ioctl32_list *next;};#define IOCTL32_DEFAULT(cmd) { { cmd, (void *) sys_ioctl }, 0 }#define IOCTL32_HANDLER(cmd, handler) { { cmd, (void *) handler }, 0 }static struct ioctl32_list ioctl32_handler_table[] = { IOCTL32_DEFAULT(TCGETA), IOCTL32_DEFAULT(TCSETA), IOCTL32_DEFAULT(TCSETAW), IOCTL32_DEFAULT(TCSETAF), IOCTL32_DEFAULT(TCSBRK), IOCTL32_DEFAULT(TCXONC), IOCTL32_DEFAULT(TCFLSH), IOCTL32_DEFAULT(TCGETS), IOCTL32_DEFAULT(TCSETS), IOCTL32_DEFAULT(TCSETSW), IOCTL32_DEFAULT(TCSETSF), IOCTL32_DEFAULT(TIOCLINUX), IOCTL32_DEFAULT(TIOCGETD), IOCTL32_DEFAULT(TIOCSETD), IOCTL32_DEFAULT(TIOCEXCL), IOCTL32_DEFAULT(TIOCNXCL), IOCTL32_DEFAULT(TIOCCONS), IOCTL32_DEFAULT(TIOCGSOFTCAR), IOCTL32_DEFAULT(TIOCSSOFTCAR), IOCTL32_DEFAULT(TIOCSWINSZ), IOCTL32_DEFAULT(TIOCGWINSZ), IOCTL32_DEFAULT(TIOCMGET), IOCTL32_DEFAULT(TIOCMBIC), IOCTL32_DEFAULT(TIOCMBIS), IOCTL32_DEFAULT(TIOCMSET), IOCTL32_DEFAULT(TIOCPKT), IOCTL32_DEFAULT(TIOCNOTTY), IOCTL32_DEFAULT(TIOCSTI), IOCTL32_DEFAULT(TIOCOUTQ), IOCTL32_DEFAULT(TIOCSPGRP), IOCTL32_DEFAULT(TIOCGPGRP), IOCTL32_DEFAULT(TIOCSCTTY), IOCTL32_DEFAULT(TIOCGPTN), IOCTL32_DEFAULT(TIOCSPTLCK), IOCTL32_DEFAULT(TIOCGSERIAL), IOCTL32_DEFAULT(TIOCSSERIAL), IOCTL32_DEFAULT(TIOCSERGETLSR), IOCTL32_DEFAULT(FIOCLEX), IOCTL32_DEFAULT(FIONCLEX), IOCTL32_DEFAULT(FIOASYNC), IOCTL32_DEFAULT(FIONBIO), IOCTL32_DEFAULT(FIONREAD), IOCTL32_DEFAULT(PIO_FONT), IOCTL32_DEFAULT(GIO_FONT), IOCTL32_DEFAULT(KDSIGACCEPT), IOCTL32_DEFAULT(KDGETKEYCODE), IOCTL32_DEFAULT(KDSETKEYCODE), IOCTL32_DEFAULT(KIOCSOUND), IOCTL32_DEFAULT(KDMKTONE), IOCTL32_DEFAULT(KDGKBTYPE), IOCTL32_DEFAULT(KDSETMODE), IOCTL32_DEFAULT(KDGETMODE), IOCTL32_DEFAULT(KDSKBMODE), IOCTL32_DEFAULT(KDGKBMODE), IOCTL32_DEFAULT(KDSKBMETA), IOCTL32_DEFAULT(KDGKBMETA), IOCTL32_DEFAULT(KDGKBENT), IOCTL32_DEFAULT(KDSKBENT), IOCTL32_DEFAULT(KDGKBSENT), IOCTL32_DEFAULT(KDSKBSENT), IOCTL32_DEFAULT(KDGKBDIACR), IOCTL32_DEFAULT(KDSKBDIACR), IOCTL32_DEFAULT(KDGKBLED), IOCTL32_DEFAULT(KDSKBLED), IOCTL32_DEFAULT(KDGETLED), IOCTL32_DEFAULT(KDSETLED), IOCTL32_DEFAULT(GIO_SCRNMAP), IOCTL32_DEFAULT(PIO_SCRNMAP), IOCTL32_DEFAULT(GIO_UNISCRNMAP), IOCTL32_DEFAULT(PIO_UNISCRNMAP), IOCTL32_DEFAULT(PIO_FONTRESET), IOCTL32_DEFAULT(PIO_UNIMAPCLR), IOCTL32_DEFAULT(VT_SETMODE), IOCTL32_DEFAULT(VT_GETMODE), IOCTL32_DEFAULT(VT_GETSTATE), IOCTL32_DEFAULT(VT_OPENQRY), IOCTL32_DEFAULT(VT_ACTIVATE), IOCTL32_DEFAULT(VT_WAITACTIVE), IOCTL32_DEFAULT(VT_RELDISP), IOCTL32_DEFAULT(VT_DISALLOCATE), IOCTL32_DEFAULT(VT_RESIZE), IOCTL32_DEFAULT(VT_RESIZEX), IOCTL32_DEFAULT(VT_LOCKSWITCH), IOCTL32_DEFAULT(VT_UNLOCKSWITCH),#ifdef CONFIG_NET /* Socket level stuff */ IOCTL32_DEFAULT(FIOSETOWN), IOCTL32_DEFAULT(SIOCSPGRP), IOCTL32_DEFAULT(FIOGETOWN), IOCTL32_DEFAULT(SIOCGPGRP), IOCTL32_DEFAULT(SIOCATMARK), IOCTL32_DEFAULT(SIOCSIFLINK), IOCTL32_DEFAULT(SIOCSIFENCAP), IOCTL32_DEFAULT(SIOCGIFENCAP), IOCTL32_DEFAULT(SIOCSIFBR), IOCTL32_DEFAULT(SIOCGIFBR), IOCTL32_DEFAULT(SIOCSARP), IOCTL32_DEFAULT(SIOCGARP), IOCTL32_DEFAULT(SIOCDARP), IOCTL32_DEFAULT(SIOCSRARP), IOCTL32_DEFAULT(SIOCGRARP), IOCTL32_DEFAULT(SIOCDRARP), IOCTL32_DEFAULT(SIOCADDDLCI), IOCTL32_DEFAULT(SIOCDELDLCI), IOCTL32_HANDLER(SIOCGIFNAME, dev_ifname32), IOCTL32_HANDLER(SIOCGIFCONF, dev_ifconf), IOCTL32_HANDLER(SIOCGIFFLAGS, dev_ifsioc), IOCTL32_HANDLER(SIOCSIFFLAGS, dev_ifsioc), IOCTL32_HANDLER(SIOCGIFMETRIC, dev_ifsioc), IOCTL32_HANDLER(SIOCSIFMETRIC, dev_ifsioc), IOCTL32_HANDLER(SIOCGIFMTU, dev_ifsioc), IOCTL32_HANDLER(SIOCSIFMTU, dev_ifsioc), IOCTL32_HANDLER(SIOCGIFMEM, dev_ifsioc), IOCTL32_HANDLER(SIOCSIFMEM, dev_ifsioc), IOCTL32_HANDLER(SIOCGIFHWADDR, dev_ifsioc), IOCTL32_HANDLER(SIOCSIFHWADDR, dev_ifsioc), IOCTL32_HANDLER(SIOCADDMULTI, dev_ifsioc), IOCTL32_HANDLER(SIOCDELMULTI, dev_ifsioc), IOCTL32_HANDLER(SIOCGIFINDEX, dev_ifsioc), IOCTL32_HANDLER(SIOCGIFMAP, dev_ifsioc), IOCTL32_HANDLER(SIOCSIFMAP, dev_ifsioc), IOCTL32_HANDLER(SIOCGIFADDR, dev_ifsioc), IOCTL32_HANDLER(SIOCSIFADDR, dev_ifsioc), IOCTL32_HANDLER(SIOCGIFBRDADDR, dev_ifsioc), IOCTL32_HANDLER(SIOCSIFBRDADDR, dev_ifsioc), IOCTL32_HANDLER(SIOCGIFDSTADDR, dev_ifsioc), IOCTL32_HANDLER(SIOCSIFDSTADDR, dev_ifsioc), IOCTL32_HANDLER(SIOCGIFNETMASK, dev_ifsioc), IOCTL32_HANDLER(SIOCSIFNETMASK, dev_ifsioc), IOCTL32_HANDLER(SIOCSIFPFLAGS, dev_ifsioc), IOCTL32_HANDLER(SIOCGIFPFLAGS, dev_ifsioc), IOCTL32_HANDLER(SIOCGIFTXQLEN, dev_ifsioc), IOCTL32_HANDLER(SIOCSIFTXQLEN, dev_ifsioc), IOCTL32_HANDLER(SIOCADDRT, routing_ioctl), IOCTL32_HANDLER(SIOCDELRT, routing_ioctl), /* * Note SIOCRTMSG is no longer, so this is safe and * the user would * have seen just an -EINVAL anyways. */ IOCTL32_HANDLER(SIOCRTMSG, ret_einval), IOCTL32_HANDLER(SIOCGSTAMP, do_siocgstamp),#endif /* CONFIG_NET */ IOCTL32_HANDLER(EXT2_IOC32_GETFLAGS, do_ext2_ioctl), IOCTL32_HANDLER(EXT2_IOC32_SETFLAGS, do_ext2_ioctl), IOCTL32_HANDLER(EXT2_IOC32_GETVERSION, do_ext2_ioctl), IOCTL32_HANDLER(EXT2_IOC32_SETVERSION, do_ext2_ioctl), IOCTL32_HANDLER(HDIO_GETGEO, hdio_getgeo), /* hdreg.h ioctls */ IOCTL32_HANDLER(HDIO_GET_UNMASKINTR, hdio_ioctl_trans), IOCTL32_HANDLER(HDIO_GET_MULTCOUNT, hdio_ioctl_trans), // HDIO_OBSOLETE_IDENTITY IOCTL32_HANDLER(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans), IOCTL32_HANDLER(HDIO_GET_32BIT, hdio_ioctl_trans), IOCTL32_HANDLER(HDIO_GET_NOWERR, hdio_ioctl_trans), IOCTL32_HANDLER(HDIO_GET_DMA, hdio_ioctl_trans), IOCTL32_HANDLER(HDIO_GET_NICE, hdio_ioctl_trans), IOCTL32_DEFAULT(HDIO_GET_IDENTITY), IOCTL32_DEFAULT(HDIO_DRIVE_RESET), // HDIO_TRISTATE_HWIF /* not implemented */ // HDIO_DRIVE_TASK /* To do, need specs */ IOCTL32_DEFAULT(HDIO_DRIVE_CMD), IOCTL32_DEFAULT(HDIO_SET_MULTCOUNT), IOCTL32_DEFAULT(HDIO_SET_UNMASKINTR), IOCTL32_DEFAULT(HDIO_SET_KEEPSETTINGS), IOCTL32_DEFAULT(HDIO_SET_32BIT), IOCTL32_DEFAULT(HDIO_SET_NOWERR), IOCTL32_DEFAULT(HDIO_SET_DMA), IOCTL32_DEFAULT(HDIO_SET_PIO_MODE), IOCTL32_DEFAULT(HDIO_SCAN_HWIF), IOCTL32_DEFAULT(HDIO_SET_NICE), //HDIO_UNREGISTER_HWIF IOCTL32_DEFAULT(BLKROSET), /* fs.h ioctls */ IOCTL32_DEFAULT(BLKROGET), IOCTL32_DEFAULT(BLKRRPART), IOCTL32_HANDLER(BLKGETSIZE, w_long), IOCTL32_DEFAULT(BLKFLSBUF), IOCTL32_DEFAULT(BLKRASET), IOCTL32_HANDLER(BLKRAGET, w_long), IOCTL32_DEFAULT(BLKFRASET), IOCTL32_HANDLER(BLKFRAGET, w_long), IOCTL32_DEFAULT(BLKSECTSET), IOCTL32_HANDLER(BLKSECTGET, w_long), IOCTL32_DEFAULT(BLKSSZGET), IOCTL32_HANDLER(BLKPG, blkpg_ioctl_trans), IOCTL32_DEFAULT(BLKELVGET), IOCTL32_DEFAULT(BLKELVSET), IOCTL32_DEFAULT(BLKBSZGET), IOCTL32_DEFAULT(BLKBSZSET),#ifdef CONFIG_MD /* status */ IOCTL32_DEFAULT(RAID_VERSION), IOCTL32_DEFAULT(GET_ARRAY_INFO), IOCTL32_DEFAULT(GET_DISK_INFO), IOCTL32_DEFAULT(PRINT_RAID_DEBUG), IOCTL32_DEFAULT(RAID_AUTORUN), /* configuration */ IOCTL32_DEFAULT(CLEAR_ARRAY), IOCTL32_DEFAULT(ADD_NEW_DISK), IOCTL32_DEFAULT(HOT_REMOVE_DISK), IOCTL32_DEFAULT(SET_ARRAY_INFO), IOCTL32_DEFAULT(SET_DISK_INFO), IOCTL32_DEFAULT(WRITE_RAID_INFO), IOCTL32_DEFAULT(UNPROTECT_ARRAY), IOCTL32_DEFAULT(PROTECT_ARRAY), IOCTL32_DEFAULT(HOT_ADD_DISK), IOCTL32_DEFAULT(SET_DISK_FAULTY), /* usage */ IOCTL32_DEFAULT(RUN_ARRAY), IOCTL32_DEFAULT(START_ARRAY), IOCTL32_DEFAULT(STOP_ARRAY), IOCTL32_DEFAULT(STOP_ARRAY_RO), IOCTL32_DEFAULT(RESTART_ARRAY_RW),#endif /* CONFIG_MD */ IOCTL32_DEFAULT(MTIOCTOP), /* mtio.h ioctls */ IOCTL32_HANDLER(MTIOCGET32, mt_ioctl_trans), IOCTL32_HANDLER(MTIOCPOS32, mt_ioctl_trans), IOCTL32_HANDLER(MTIOCGETCONFIG32, mt_ioctl_trans), IOCTL32_HANDLER(MTIOCSETCONFIG32, mt_ioctl_trans), // MTIOCRDFTSEG // MTIOCWRFTSEG // MTIOCVOLINFO // MTIOCGETSIZE // MTIOCFTFORMAT // MTIOCFTCMD IOCTL32_DEFAULT(AUTOFS_IOC_READY), /* auto_fs.h ioctls */ IOCTL32_DEFAULT(AUTOFS_IOC_FAIL), IOCTL32_DEFAULT(AUTOFS_IOC_CATATONIC), IOCTL32_DEFAULT(AUTOFS_IOC_PROTOVER), IOCTL32_HANDLER(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout), IOCTL32_DEFAULT(AUTOFS_IOC_EXPIRE)};#define NR_IOCTL32_HANDLERS (sizeof(ioctl32_handler_table) / \ sizeof(ioctl32_handler_table[0]))static struct ioctl32_list *ioctl32_hash_table[1024];static inline int ioctl32_hash(unsigned int cmd){ return ((cmd >> 6) ^ (cmd >> 4) ^ cmd) & 0x3ff;}int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned int arg){ int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp); struct file *filp; struct ioctl32_list *l; int error; l = ioctl32_hash_table[ioctl32_hash(cmd)]; error = -EBADF; filp = fget(fd); if (!filp) return error; if (!filp->f_op || !filp->f_op->ioctl) { error = sys_ioctl (fd, cmd, arg); goto out; } while (l && l->handler.cmd != cmd) l = l->next; if (l) { handler = (void *)l->handler.function; error = handler(fd, cmd, arg, filp); } else { error = -EINVAL; printk("unknown ioctl: %08x\n", cmd); }out: fput(filp); return error;}static void ioctl32_insert(struct ioctl32_list *entry){ int hash = ioctl32_hash(entry->handler.cmd); if (!ioctl32_hash_table[hash]) ioctl32_hash_table[hash] = entry; else { struct ioctl32_list *l; l = ioctl32_hash_table[hash]; while (l->next) l = l->next; l->next = entry; entry->next = 0; }}static int __init init_ioctl32(void){ int i; for (i = 0; i < NR_IOCTL32_HANDLERS; i++) ioctl32_insert(&ioctl32_handler_table[i]); return 0;}__initcall(init_ioctl32);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -