📄 ioctl32.c
字号:
char red[256], green[256], blue[256]; u32 r, g, b; mm_segment_t old_fs = get_fs(); ret = get_user(f.index, &(((struct fbcmap32 *)arg)->index)); ret |= __get_user(f.count, &(((struct fbcmap32 *)arg)->count)); ret |= __get_user(r, &(((struct fbcmap32 *)arg)->red)); ret |= __get_user(g, &(((struct fbcmap32 *)arg)->green)); ret |= __get_user(b, &(((struct fbcmap32 *)arg)->blue)); if (ret) return -EFAULT; if ((f.index < 0) || (f.index > 255)) return -EINVAL; if (f.index + f.count > 256) f.count = 256 - f.index; if (cmd == FBIOPUTCMAP32) { ret = copy_from_user (red, (char *)A(r), f.count); ret |= copy_from_user (green, (char *)A(g), f.count); ret |= copy_from_user (blue, (char *)A(b), f.count); if (ret) return -EFAULT; } f.red = red; f.green = green; f.blue = blue; set_fs (KERNEL_DS); ret = sys_ioctl (fd, (cmd == FBIOPUTCMAP32) ? FBIOPUTCMAP_SPARC : FBIOGETCMAP_SPARC, (long)&f); set_fs (old_fs); if (!ret && cmd == FBIOGETCMAP32) { ret = copy_to_user ((char *)A(r), red, f.count); ret |= copy_to_user ((char *)A(g), green, f.count); ret |= copy_to_user ((char *)A(b), blue, f.count); } return ret ? -EFAULT : 0;}struct fbcursor32 { short set; /* what to set, choose from the list above */ short enable; /* cursor on/off */ struct fbcurpos pos; /* cursor position */ struct fbcurpos hot; /* cursor hot spot */ struct fbcmap32 cmap; /* color map info */ struct fbcurpos size; /* cursor bit map size */ u32 image; /* cursor image bits */ u32 mask; /* cursor mask bits */}; #define FBIOSCURSOR32 _IOW('F', 24, struct fbcursor32)#define FBIOGCURSOR32 _IOW('F', 25, struct fbcursor32)static inline int fbiogscursor(unsigned int fd, unsigned int cmd, unsigned long arg){ struct fbcursor f; int ret; char red[2], green[2], blue[2]; char image[128], mask[128]; u32 r, g, b; u32 m, i; mm_segment_t old_fs = get_fs(); ret = copy_from_user (&f, (struct fbcursor32 *)arg, 2 * sizeof (short) + 2 * sizeof(struct fbcurpos)); ret |= __get_user(f.size.fbx, &(((struct fbcursor32 *)arg)->size.fbx)); ret |= __get_user(f.size.fby, &(((struct fbcursor32 *)arg)->size.fby)); ret |= __get_user(f.cmap.index, &(((struct fbcursor32 *)arg)->cmap.index)); ret |= __get_user(f.cmap.count, &(((struct fbcursor32 *)arg)->cmap.count)); ret |= __get_user(r, &(((struct fbcursor32 *)arg)->cmap.red)); ret |= __get_user(g, &(((struct fbcursor32 *)arg)->cmap.green)); ret |= __get_user(b, &(((struct fbcursor32 *)arg)->cmap.blue)); ret |= __get_user(m, &(((struct fbcursor32 *)arg)->mask)); ret |= __get_user(i, &(((struct fbcursor32 *)arg)->image)); if (ret) return -EFAULT; if (f.set & FB_CUR_SETCMAP) { if ((uint) f.size.fby > 32) return -EINVAL; ret = copy_from_user (mask, (char *)A(m), f.size.fby * 4); ret |= copy_from_user (image, (char *)A(i), f.size.fby * 4); if (ret) return -EFAULT; f.image = image; f.mask = mask; } if (f.set & FB_CUR_SETCMAP) { ret = copy_from_user (red, (char *)A(r), 2); ret |= copy_from_user (green, (char *)A(g), 2); ret |= copy_from_user (blue, (char *)A(b), 2); if (ret) return -EFAULT; f.cmap.red = red; f.cmap.green = green; f.cmap.blue = blue; } set_fs (KERNEL_DS); ret = sys_ioctl (fd, FBIOSCURSOR, (long)&f); set_fs (old_fs); return ret;}struct fb_fix_screeninfo32 { char id[16]; __kernel_caddr_t32 smem_start; __u32 smem_len; __u32 type; __u32 type_aux; __u32 visual; __u16 xpanstep; __u16 ypanstep; __u16 ywrapstep; __u32 line_length; __kernel_caddr_t32 mmio_start; __u32 mmio_len; __u32 accel; __u16 reserved[3];};struct fb_cmap32 { __u32 start; __u32 len; __kernel_caddr_t32 red; __kernel_caddr_t32 green; __kernel_caddr_t32 blue; __kernel_caddr_t32 transp;};static int fb_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg){ mm_segment_t old_fs = get_fs(); u32 red = 0, green = 0, blue = 0, transp = 0; struct fb_fix_screeninfo fix; struct fb_cmap cmap; void *karg; int err = 0; memset(&cmap, 0, sizeof(cmap)); switch (cmd) { case FBIOGET_FSCREENINFO: karg = &fix; break; case FBIOGETCMAP: case FBIOPUTCMAP: karg = &cmap; err = __get_user(cmap.start, &((struct fb_cmap32 *)arg)->start); err |= __get_user(cmap.len, &((struct fb_cmap32 *)arg)->len); err |= __get_user(red, &((struct fb_cmap32 *)arg)->red); err |= __get_user(green, &((struct fb_cmap32 *)arg)->green); err |= __get_user(blue, &((struct fb_cmap32 *)arg)->blue); err |= __get_user(transp, &((struct fb_cmap32 *)arg)->transp); if (err) { err = -EFAULT; goto out; } err = -ENOMEM; cmap.red = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL); if (!cmap.red) goto out; cmap.green = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL); if (!cmap.green) goto out; cmap.blue = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL); if (!cmap.blue) goto out; if (transp) { cmap.transp = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL); if (!cmap.transp) goto out; } if (cmd == FBIOGETCMAP) break; err = __copy_from_user(cmap.red, (char *)A(red), cmap.len * sizeof(__u16)); err |= __copy_from_user(cmap.green, (char *)A(green), cmap.len * sizeof(__u16)); err |= __copy_from_user(cmap.blue, (char *)A(blue), cmap.len * sizeof(__u16)); if (cmap.transp) err |= __copy_from_user(cmap.transp, (char *)A(transp), cmap.len * sizeof(__u16)); if (err) { err = -EFAULT; goto out; } break; default: do { static int count = 0; if (++count <= 20) printk("%s: Unknown fb ioctl cmd fd(%d) " "cmd(%08x) arg(%08lx)\n", __FUNCTION__, fd, cmd, arg); } while(0); return -ENOSYS; } set_fs(KERNEL_DS); err = sys_ioctl(fd, cmd, (unsigned long)karg); set_fs(old_fs); if (err) goto out; switch (cmd) { case FBIOGET_FSCREENINFO: err = __copy_to_user((char *)((struct fb_fix_screeninfo32 *)arg)->id, (char *)fix.id, sizeof(fix.id)); err |= __put_user((__u32)(unsigned long)fix.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((__u32)(unsigned long)fix.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 |= __copy_to_user((char *)((struct fb_fix_screeninfo32 *)arg)->reserved, (char *)fix.reserved, sizeof(fix.reserved)); break; case FBIOGETCMAP: err = __copy_to_user((char *)A(red), cmap.red, cmap.len * sizeof(__u16)); err |= __copy_to_user((char *)A(green), cmap.blue, cmap.len * sizeof(__u16)); err |= __copy_to_user((char *)A(blue), cmap.blue, cmap.len * sizeof(__u16)); if (cmap.transp) err |= __copy_to_user((char *)A(transp), cmap.transp, cmap.len * sizeof(__u16)); break; case FBIOPUTCMAP: break; } if (err) err = -EFAULT;out: if (cmap.red) kfree(cmap.red); if (cmap.green) kfree(cmap.green); if (cmap.blue) kfree(cmap.blue); if (cmap.transp) kfree(cmap.transp); return err;}static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg){ mm_segment_t old_fs = get_fs(); unsigned long kval; unsigned int *uvp; int error; set_fs(KERNEL_DS); error = sys_ioctl(fd, cmd, (long)&kval); set_fs(old_fs); if(error == 0) { uvp = (unsigned int *)arg; if(put_user(kval, uvp)) error = -EFAULT; } return error;}struct floppy_struct32 { unsigned int size; unsigned int sect; unsigned int head; unsigned int track; unsigned int stretch; unsigned char gap; unsigned char rate; unsigned char spec1; unsigned char fmt_gap; const __kernel_caddr_t32 name;};struct floppy_drive_params32 { char cmos; u32 max_dtr; u32 hlt; u32 hut; u32 srt; u32 spinup; u32 spindown; unsigned char spindown_offset; unsigned char select_delay; unsigned char rps; unsigned char tracks; u32 timeout; unsigned char interleave_sect; struct floppy_max_errors max_errors; char flags; char read_track; short autodetect[8]; int checkfreq; int native_format;};struct floppy_drive_struct32 { signed char flags; u32 spinup_date; u32 select_date; u32 first_read_date; short probed_format; short track; short maxblock; short maxtrack; int generation; int keep_data; int fd_ref; int fd_device; int last_checked; __kernel_caddr_t32 dmabuf; int bufblocks;};struct floppy_fdc_state32 { int spec1; int spec2; int dtr; unsigned char version; unsigned char dor; u32 address; unsigned int rawcmd:2; unsigned int reset:1; unsigned int need_configure:1; unsigned int perp_mode:2; unsigned int has_fifo:1; unsigned int driver_version; unsigned char track[4];};struct floppy_write_errors32 { unsigned int write_errors; u32 first_error_sector; int first_error_generation; u32 last_error_sector; int last_error_generation; unsigned int badness;};#define FDSETPRM32 _IOW(2, 0x42, struct floppy_struct32)#define FDDEFPRM32 _IOW(2, 0x43, struct floppy_struct32)#define FDGETPRM32 _IOR(2, 0x04, struct floppy_struct32)#define FDSETDRVPRM32 _IOW(2, 0x90, struct floppy_drive_params32)#define FDGETDRVPRM32 _IOR(2, 0x11, struct floppy_drive_params32)#define FDGETDRVSTAT32 _IOR(2, 0x12, struct floppy_drive_struct32)#define FDPOLLDRVSTAT32 _IOR(2, 0x13, struct floppy_drive_struct32)#define FDGETFDCSTAT32 _IOR(2, 0x15, struct floppy_fdc_state32)#define FDWERRORGET32 _IOR(2, 0x17, struct floppy_write_errors32)static struct { unsigned int cmd32; unsigned int cmd;} fd_ioctl_trans_table[] = { { FDSETPRM32, FDSETPRM }, { FDDEFPRM32, FDDEFPRM }, { FDGETPRM32, FDGETPRM }, { FDSETDRVPRM32, FDSETDRVPRM }, { FDGETDRVPRM32, FDGETDRVPRM }, { FDGETDRVSTAT32, FDGETDRVSTAT }, { FDPOLLDRVSTAT32, FDPOLLDRVSTAT }, { FDGETFDCSTAT32, FDGETFDCSTAT }, { FDWERRORGET32, FDWERRORGET }};#define NR_FD_IOCTL_TRANS (sizeof(fd_ioctl_trans_table)/sizeof(fd_ioctl_trans_table[0]))static int fd_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg){ mm_segment_t old_fs = get_fs(); void *karg = NULL; unsigned int kcmd = 0; int i, err; for (i = 0; i < NR_FD_IOCTL_TRANS; i++) if (cmd == fd_ioctl_trans_table[i].cmd32) { kcmd = fd_ioctl_trans_table[i].cmd; break; } if (!kcmd) return -EINVAL; switch (cmd) { case FDSETPRM32: case FDDEFPRM32: case FDGETPRM32: { struct floppy_struct *f; f = karg = kmalloc(sizeof(struct floppy_struct), GFP_KERNEL); if (!karg) return -ENOMEM; if (cmd == FDGETPRM32) break; err = __get_user(f->size, &((struct floppy_struct32 *)arg)->size); err |= __get_user(f->sect, &((struct floppy_struct32 *)arg)->sect); err |= __get_user(f->head, &((struct floppy_struct32 *)arg)->head); err |= __get_user(f->track, &((struct floppy_struct32 *)arg)->track); err |= __get_user(f->stretch, &((struct floppy_struct32 *)arg)->stretch); err |= __get_user(f->gap, &((struct floppy_struct32 *)arg)->gap); err |= __get_user(f->rate, &((struct floppy_struct32 *)arg)->rate); err |= __get_user(f->spec1, &((struct floppy_struct32 *)arg)->spec1); err |= __get_user(f->fmt_gap, &((struct floppy_struct32 *)arg)->fmt_gap); err |= __get_user((u64)f->name, &((struct floppy_struct32 *)arg)->name); if (err) { err = -EFAULT; goto out; } break; } case FDSETDRVPRM32: case FDGETDRVPRM32: { struct floppy_drive_params *f; f = karg = kmalloc(sizeof(struct floppy_drive_params), GFP_KERNEL); if (!karg) return -ENOMEM; if (cmd == FDGETDRVPRM32) break; err = __get_user(f->cmos, &((struct floppy_drive_params32 *)arg)->cmos); err |= __get_user(f->max_dtr, &((struct floppy_drive_params32 *)arg)->max_dtr); err |= __get_user(f->hlt, &((struct floppy_drive_params32 *)arg)->hlt); err |= __get_user(f->hut, &((struct floppy_drive_params32 *)arg)->hut); err |= __get_user(f->srt, &((struct floppy_drive_params32 *)arg)->srt); err |= __get_user(f->spinup, &((struct floppy_drive_params32 *)arg)->spinup); err |= __get_user(f->spindown, &((struct floppy_drive_params32 *)arg)->spindown); err |= __get_user(f->spindown_offset, &((struct floppy_drive_params32 *)arg)->spindown_offset); err |= __get_user(f->select_delay, &((struct floppy_drive_params32 *)arg)->select_delay); err |= __get_user(f->rps, &((struct floppy_drive_params32 *)arg)->rps); err |= __get_user(f->tracks, &((struct floppy_drive_params32 *)arg)->tracks); err |= __get_user(f->timeout, &((struct floppy_drive_params32 *)arg)->timeout); err |= __get_user(f->interleave_sect, &((struct floppy_drive_params32 *)arg)->interleave_sect); err |= __copy_from_user(&f->max_errors, &((struct floppy_drive_params32 *)arg)->max_errors, sizeof(f->max_errors)); err |= __get_user(f->flags, &((struct floppy_drive_params32 *)arg)->flags); err |= __get_user(f->read_track, &((struct floppy_drive_params32 *)arg)->read_track); err |= __copy_from_user(f->autodetect, ((struct floppy_drive_params32 *)arg)->autodetect, sizeof(f->autodetect)); err |= __get_user(f->checkfreq, &((struct floppy_drive_params32 *)arg)->checkfreq); err |= __get_user(f->native_format, &((struct floppy_drive_params32 *)arg)->native_format); if (err) { err = -EFAULT; goto out; } break; } case FDGETDRVSTAT32: case FDPOLLDRVSTAT32: karg = kmalloc(sizeof(struct floppy_drive_struct), GFP_KERNEL); if (!karg) return -ENOMEM; break; case FDGETFDCSTAT32: karg = kmalloc(sizeof(struct floppy_fdc_state), GFP_KERNEL); if (!karg) return -ENOMEM; break; case FDWERRORGET32: karg = kmalloc(sizeof(struct floppy_write_errors), GFP_KERNEL); if (!karg) return -ENOMEM; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -