📄 ioctl32.c
字号:
struct consolefontdesc32 { unsigned short charcount; /* characters in font (256 or 512) */ unsigned short charheight; /* scan lines per character (1-32) */ u32 chardata; /* font data in expanded form */};static int do_fontx_ioctl(unsigned int fd, int cmd, struct consolefontdesc32 *user_cfd, struct file *file){ struct consolefontdesc cfdarg; struct console_font_op op; int i, perm; perm = vt_check(file); if (perm < 0) return perm; if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc32))) return -EFAULT; cfdarg.chardata = (unsigned char *)A(((struct consolefontdesc32 *)&cfdarg)->chardata); switch (cmd) { case PIO_FONTX: if (!perm) return -EPERM; op.op = KD_FONT_OP_SET; op.flags = 0; op.width = 8; op.height = cfdarg.charheight; op.charcount = cfdarg.charcount; op.data = cfdarg.chardata; return con_font_op(fg_console, &op); case GIO_FONTX: if (!cfdarg.chardata) return 0; op.op = KD_FONT_OP_GET; op.flags = 0; op.width = 8; op.height = cfdarg.charheight; op.charcount = cfdarg.charcount; op.data = cfdarg.chardata; i = con_font_op(fg_console, &op); if (i) return i; cfdarg.charheight = op.height; cfdarg.charcount = op.charcount; ((struct consolefontdesc32 *)&cfdarg)->chardata = (unsigned long)cfdarg.chardata; if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc32))) return -EFAULT; return 0; } return -EINVAL;}struct console_font_op32 { unsigned int op; /* operation code KD_FONT_OP_* */ unsigned int flags; /* KD_FONT_FLAG_* */ unsigned int width, height; /* font size */ unsigned int charcount; u32 data; /* font data with height fixed to 32 */}; static int do_kdfontop_ioctl(unsigned int fd, unsigned int cmd, struct console_font_op32 *fontop, struct file *file){ struct console_font_op op; int perm = vt_check(file), i; struct vt_struct *vt; if (perm < 0) return perm; if (copy_from_user(&op, (void *) fontop, sizeof(struct console_font_op32))) return -EFAULT; if (!perm && op.op != KD_FONT_OP_GET) return -EPERM; op.data = (unsigned char *)A(((struct console_font_op32 *)&op)->data); op.flags |= KD_FONT_FLAG_OLD; vt = (struct vt_struct *)((struct tty_struct *)file->private_data)->driver_data; i = con_font_op(vt->vc_num, &op); if (i) return i; ((struct console_font_op32 *)&op)->data = (unsigned long)op.data; if (copy_to_user((void *) fontop, &op, sizeof(struct console_font_op32))) return -EFAULT; return 0;}struct fb_fix_screeninfo32 { char id[16]; /* identification string eg "TT Builtin" */ unsigned int smem_start; /* Start of frame buffer mem */ /* (physical address) */ __u32 smem_len; /* Length of frame buffer mem */ __u32 type; /* see FB_TYPE_* */ __u32 type_aux; /* Interleave for interleaved Planes */ __u32 visual; /* see FB_VISUAL_* */ __u16 xpanstep; /* zero if no hardware panning */ __u16 ypanstep; /* zero if no hardware panning */ __u16 ywrapstep; /* zero if no hardware ywrap */ __u32 line_length; /* length of a line in bytes */ unsigned int mmio_start; /* Start of Memory Mapped I/O */ /* (physical address) */ __u32 mmio_len; /* Length of Memory Mapped I/O */ __u32 accel; /* Type of acceleration available */ __u16 reserved[3]; /* Reserved for future compatibility */};static int do_fbioget_fscreeninfo_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg){ mm_segment_t old_fs = get_fs(); struct fb_fix_screeninfo fix; int err; set_fs(KERNEL_DS); err = sys_ioctl(fd, cmd, (long)&fix); set_fs(old_fs); if (err == 0) { unsigned int smem_start = fix.smem_start; /* lose top 32 bits */ unsigned int mmio_start = fix.mmio_start; /* lose top 32 bits */ int i; err = put_user(fix.id[0], &((struct fb_fix_screeninfo32 *)arg)->id[0]); for (i=1; i<16; i++) { err |= __put_user(fix.id[i], &((struct fb_fix_screeninfo32 *)arg)->id[i]); } err |= __put_user(smem_start, &((struct fb_fix_screeninfo32 *)arg)->smem_start); err |= __put_user(fix.smem_len, &((struct fb_fix_screeninfo32 *)arg)->smem_len); err |= __put_user(fix.type, &((struct fb_fix_screeninfo32 *)arg)->type); err |= __put_user(fix.type_aux, &((struct fb_fix_screeninfo32 *)arg)->type_aux); err |= __put_user(fix.visual, &((struct fb_fix_screeninfo32 *)arg)->visual); err |= __put_user(fix.xpanstep, &((struct fb_fix_screeninfo32 *)arg)->xpanstep); err |= __put_user(fix.ypanstep, &((struct fb_fix_screeninfo32 *)arg)->ypanstep); err |= __put_user(fix.ywrapstep, &((struct fb_fix_screeninfo32 *)arg)->ywrapstep); err |= __put_user(fix.line_length, &((struct fb_fix_screeninfo32 *)arg)->line_length); err |= __put_user(mmio_start, &((struct fb_fix_screeninfo32 *)arg)->mmio_start); err |= __put_user(fix.mmio_len, &((struct fb_fix_screeninfo32 *)arg)->mmio_len); err |= __put_user(fix.accel, &((struct fb_fix_screeninfo32 *)arg)->accel); err |= __put_user(fix.reserved[0], &((struct fb_fix_screeninfo32 *)arg)->reserved[0]); err |= __put_user(fix.reserved[1], &((struct fb_fix_screeninfo32 *)arg)->reserved[1]); err |= __put_user(fix.reserved[2], &((struct fb_fix_screeninfo32 *)arg)->reserved[2]); if (err) err = -EFAULT; } return err;}struct fb_cmap32 { __u32 start; /* First entry */ __u32 len; /* Number of entries */ __u32 redptr; /* Red values */ __u32 greenptr; __u32 blueptr; __u32 transpptr; /* transparency, can be NULL */};static int do_fbiogetcmap_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg){ mm_segment_t old_fs = get_fs(); struct fb_cmap cmap; int err; set_fs(KERNEL_DS); err = sys_ioctl(fd, cmd, (long)&cmap); set_fs(old_fs); if (err == 0) { __u32 redptr = (__u32)(__u64)cmap.red; __u32 greenptr = (__u32)(__u64)cmap.green; __u32 blueptr = (__u32)(__u64)cmap.blue; __u32 transpptr = (__u32)(__u64)cmap.transp; err = put_user(cmap.start, &((struct fb_cmap32 *)arg)->start); err |= __put_user(cmap.len, &((struct fb_cmap32 *)arg)->len); err |= __put_user(redptr, &((struct fb_cmap32 *)arg)->redptr); err |= __put_user(greenptr, &((struct fb_cmap32 *)arg)->greenptr); err |= __put_user(blueptr, &((struct fb_cmap32 *)arg)->blueptr); err |= __put_user(transpptr, &((struct fb_cmap32 *)arg)->transpptr); if (err) err = -EFAULT; } return err;}static int do_fbioputcmap_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg){ mm_segment_t old_fs = get_fs(); struct fb_cmap cmap; __u32 redptr, greenptr, blueptr, transpptr; int err; err = get_user(cmap.start, &((struct fb_cmap32 *)arg)->start); err |= __get_user(cmap.len, &((struct fb_cmap32 *)arg)->len); err |= __get_user(redptr, &((struct fb_cmap32 *)arg)->redptr); err |= __get_user(greenptr, &((struct fb_cmap32 *)arg)->greenptr); err |= __get_user(blueptr, &((struct fb_cmap32 *)arg)->blueptr); err |= __get_user(transpptr, &((struct fb_cmap32 *)arg)->transpptr); if (err) { err = -EFAULT; } else { cmap.red = (__u16 *)(__u64)redptr; cmap.green = (__u16 *)(__u64)greenptr; cmap.blue = (__u16 *)(__u64)blueptr; cmap.transp = (__u16 *)(__u64)transpptr; set_fs (KERNEL_DS); err = sys_ioctl (fd, cmd, (unsigned long)&cmap); set_fs (old_fs); } return err;}struct unimapdesc32 { unsigned short entry_ct; u32 entries;};static int do_unimap_ioctl(unsigned int fd, unsigned int cmd, struct unimapdesc32 *user_ud, struct file *file){ struct unimapdesc32 tmp; int perm = vt_check(file); if (perm < 0) return perm; if (copy_from_user(&tmp, user_ud, sizeof tmp)) return -EFAULT; switch (cmd) { case PIO_UNIMAP: if (!perm) return -EPERM; return con_set_unimap(fg_console, tmp.entry_ct, (struct unipair *)A(tmp.entries)); case GIO_UNIMAP: return con_get_unimap(fg_console, tmp.entry_ct, &(user_ud->entry_ct), (struct unipair *)A(tmp.entries)); } return 0;}#endif /* CONFIG_VT */static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long arg){ mm_segment_t old_fs = get_fs(); __kernel_uid_t kuid; int err; cmd = SMB_IOC_GETMOUNTUID; set_fs(KERNEL_DS); err = sys_ioctl(fd, cmd, (unsigned long)&kuid); set_fs(old_fs); if (err >= 0) err = put_user(kuid, (__kernel_uid_t32 *)arg); return err;}struct atmif_sioc32 { int number; int length; __kernel_caddr_t32 arg;};struct atm_iobuf32 { int length; __kernel_caddr_t32 buffer;};#define ATM_GETLINKRATE32 _IOW('a', ATMIOC_ITF+1, struct atmif_sioc32)#define ATM_GETNAMES32 _IOW('a', ATMIOC_ITF+3, struct atm_iobuf32)#define ATM_GETTYPE32 _IOW('a', ATMIOC_ITF+4, struct atmif_sioc32)#define ATM_GETESI32 _IOW('a', ATMIOC_ITF+5, struct atmif_sioc32)#define ATM_GETADDR32 _IOW('a', ATMIOC_ITF+6, struct atmif_sioc32)#define ATM_RSTADDR32 _IOW('a', ATMIOC_ITF+7, struct atmif_sioc32)#define ATM_ADDADDR32 _IOW('a', ATMIOC_ITF+8, struct atmif_sioc32)#define ATM_DELADDR32 _IOW('a', ATMIOC_ITF+9, struct atmif_sioc32)#define ATM_GETCIRANGE32 _IOW('a', ATMIOC_ITF+10, struct atmif_sioc32)#define ATM_SETCIRANGE32 _IOW('a', ATMIOC_ITF+11, struct atmif_sioc32)#define ATM_SETESI32 _IOW('a', ATMIOC_ITF+12, struct atmif_sioc32)#define ATM_SETESIF32 _IOW('a', ATMIOC_ITF+13, struct atmif_sioc32)#define ATM_GETSTAT32 _IOW('a', ATMIOC_SARCOM+0, struct atmif_sioc32)#define ATM_GETSTATZ32 _IOW('a', ATMIOC_SARCOM+1, struct atmif_sioc32)#define ATM_GETLOOP32 _IOW('a', ATMIOC_SARCOM+2, struct atmif_sioc32)#define ATM_SETLOOP32 _IOW('a', ATMIOC_SARCOM+3, struct atmif_sioc32)#define ATM_QUERYLOOP32 _IOW('a', ATMIOC_SARCOM+4, struct atmif_sioc32)static struct { unsigned int cmd32; unsigned int cmd;} atm_ioctl_map[] = { { ATM_GETLINKRATE32, ATM_GETLINKRATE }, { ATM_GETNAMES32, ATM_GETNAMES }, { ATM_GETTYPE32, ATM_GETTYPE }, { ATM_GETESI32, ATM_GETESI }, { ATM_GETADDR32, ATM_GETADDR }, { ATM_RSTADDR32, ATM_RSTADDR }, { ATM_ADDADDR32, ATM_ADDADDR }, { ATM_DELADDR32, ATM_DELADDR }, { ATM_GETCIRANGE32, ATM_GETCIRANGE }, { ATM_SETCIRANGE32, ATM_SETCIRANGE }, { ATM_SETESI32, ATM_SETESI }, { ATM_SETESIF32, ATM_SETESIF }, { ATM_GETSTAT32, ATM_GETSTAT }, { ATM_GETSTATZ32, ATM_GETSTATZ }, { ATM_GETLOOP32, ATM_GETLOOP }, { ATM_SETLOOP32, ATM_SETLOOP }, { ATM_QUERYLOOP32, ATM_QUERYLOOP }};#define NR_ATM_IOCTL (sizeof(atm_ioctl_map)/sizeof(atm_ioctl_map[0]))static int do_atm_iobuf(unsigned int fd, unsigned int cmd, unsigned long arg){ struct atm_iobuf32 iobuf32; struct atm_iobuf iobuf = { 0, NULL }; mm_segment_t old_fs; int err; err = copy_from_user(&iobuf32, (struct atm_iobuf32*)arg, sizeof(struct atm_iobuf32)); if (err) return -EFAULT; iobuf.length = iobuf32.length; if (iobuf32.buffer == (__kernel_caddr_t32) NULL || iobuf32.length == 0) { iobuf.buffer = (void*)(unsigned long)iobuf32.buffer; } else { iobuf.buffer = kmalloc(iobuf.length, GFP_KERNEL); if (iobuf.buffer == NULL) { err = -ENOMEM; goto out; } err = copy_from_user(iobuf.buffer, (void *)A(iobuf32.buffer), iobuf.length); if (err) { err = -EFAULT; goto out; } } old_fs = get_fs(); set_fs (KERNEL_DS); err = sys_ioctl (fd, cmd, (unsigned long)&iobuf); set_fs (old_fs); if (err) goto out; if (iobuf.buffer && iobuf.length > 0) { err = copy_to_user((void *)A(iobuf32.buffer), iobuf.buffer, iobuf.length); if (err) { err = -EFAULT; goto out; } } err = __put_user(iobuf.length, &(((struct atm_iobuf32*)arg)->length)); out: if (iobuf32.buffer && iobuf32.length > 0) kfree(iobuf.buffer); return err;}static int do_atmif_sioc(unsigned int fd, unsigned int cmd, unsigned long arg){ struct atmif_sioc32 sioc32; struct atmif_sioc sioc = { 0, 0, NULL }; mm_segment_t old_fs; int err; err = copy_from_user(&sioc32, (struct atmif_sioc32*)arg, sizeof(struct atmif_sioc32)); if (err) return -EFAULT; sioc.number = sioc32.number; sioc.length = sioc32.length; if (sioc32.arg == (__kernel_caddr_t32) NULL || sioc32.length == 0) { sioc.arg = (void*)(unsigned long)sioc32.arg; } else { sioc.arg = kmalloc(sioc.length, GFP_KERNEL); if (sioc.arg == NULL) { err = -ENOMEM; goto out; } err = copy_from_user(sioc.arg, (void *)A(sioc32.arg), sioc32.length); if (err) { err = -EFAULT; goto out; } } old_fs = get_fs(); set_fs (KERNEL_DS); err = sys_ioctl (fd, cmd, (unsigned long)&sioc); set_fs (old_fs); if (err) { goto out; } if (sioc.arg && sioc.length > 0) { err = copy_to_user((void *)A(sioc32.arg), sioc.arg, sioc.length); if (err) { err = -EFAULT; goto out; } } err = __put_user(sioc.length, &(((struct atmif_sioc32*)arg)->length)); out: if (sioc32.arg && sioc32.length > 0) kfree(sioc.arg); return err;}static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg){ int i; unsigned int cmd = 0; switch (cmd32) { case SONET_GETSTAT: case SONET_GETSTATZ: case SONET_GETDIAG: case SONET_SETDIAG: case SONET_CLRDIAG: case SONET_SETFRAMING: case SONET_GETFRAMING: case SONET_GETFRSENSE: return do_atmif_sioc(fd, cmd32, arg); } for (i = 0; i < NR_ATM_IOCTL; i++) { if (cmd32 == atm_ioctl_map[i].cmd32) { cmd = atm_ioctl_map[i].cmd; break; } } if (i == NR_ATM_IOCTL) { return -EINVAL; } switch (cmd) { c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -