📄 ioctl32.c
字号:
set_fs (KERNEL_DS); ret = sys_ioctl (fd, cmd, (long) r); set_fs (old_fs); if (mysock) sockfd_put(mysock); return ret;}struct hd_geometry32 { unsigned char heads; unsigned char sectors; unsigned short cylinders; u32 start;}; static int hdio_getgeo(unsigned int fd, unsigned int cmd, unsigned long arg){ mm_segment_t old_fs = get_fs(); struct hd_geometry geo; int err; set_fs (KERNEL_DS); err = sys_ioctl(fd, HDIO_GETGEO, (unsigned long)&geo); set_fs (old_fs); if (!err) { err = copy_to_user ((struct hd_geometry32 *)arg, &geo, 4); err |= __put_user (geo.start, &(((struct hd_geometry32 *)arg)->start)); } return err ? -EFAULT : 0;}struct hd_big_geometry32 { u8 heads; u8 sectors; u32 cylinders; u32 start;};static int hdio_getgeo_big(unsigned int fd, unsigned int cmd, unsigned long arg){ mm_segment_t old_fs = get_fs(); struct hd_big_geometry geo; int err; set_fs (KERNEL_DS); err = sys_ioctl(fd, HDIO_GETGEO_BIG, (unsigned long)&geo); set_fs (old_fs); if (err) return err; else { struct hd_big_geometry32 *user_geo = (struct hd_big_geometry32 *)arg; err = __put_user (geo.heads, &(user_geo->heads)); err |= __put_user (geo.sectors, &(user_geo->sectors)); err |= __put_user (geo.cylinders, &(user_geo->cylinders)); err |= __put_user (geo.start, &(user_geo->start)); } return err ? -EFAULT : 0;}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; default: return -EINVAL; } set_fs (KERNEL_DS); err = sys_ioctl (fd, kcmd, (unsigned long)karg); set_fs (old_fs); if (err) goto out; switch (cmd) { case FDGETPRM32: { struct floppy_struct *f = karg; err = __put_user(f->size, &((struct floppy_struct32 *)arg)->size); err |= __put_user(f->sect, &((struct floppy_struct32 *)arg)->sect); err |= __put_user(f->head, &((struct floppy_struct32 *)arg)->head); err |= __put_user(f->track, &((struct floppy_struct32 *)arg)->track); err |= __put_user(f->stretch, &((struct floppy_struct32 *)arg)->stretch); err |= __put_user(f->gap, &((struct floppy_struct32 *)arg)->gap); err |= __put_user(f->rate, &((struct floppy_struct32 *)arg)->rate); err |= __put_user(f->spec1, &((struct floppy_struct32 *)arg)->spec1); err |= __put_user(f->fmt_gap, &((struct floppy_struct32 *)arg)->fmt_gap); err |= __put_user((u64)f->name, &((struct floppy_struct32 *)arg)->name); break; } case FDGETDRVPRM32: { struct floppy_drive_params *f = karg; err = __put_user(f->cmos, &((struct floppy_drive_params32 *)arg)->cmos); err |= __put_user(f->max_dtr, &((struct floppy_drive_params32 *)arg)->max_dtr); err |= __put_user(f->hlt, &((struct floppy_drive_params32 *)arg)->hlt); err |= __put_user(f->hut, &((struct floppy_drive_params32 *)arg)->hut); err |= __put_user(f->srt, &((struct floppy_drive_params32 *)arg)->srt); err |= __put_user(f->spinup, &((struct floppy_drive_params32 *)arg)->spinup); err |= __put_user(f->spindown, &((struct floppy_drive_params32 *)arg)->spindown); err |= __put_user(f->spindown_offset, &((struct floppy_drive_params32 *)arg)->spindown_offset); err |= __put_user(f->select_delay, &((struct floppy_drive_params32 *)arg)->select_delay); err |= __put_user(f->rps, &((struct floppy_drive_params32 *)arg)->rps); err |= __put_user(f->tracks, &((struct floppy_drive_params32 *)arg)->tracks); err |= __put_user(f->timeout, &((struct floppy_drive_params32 *)arg)->timeout); err |= __put_user(f->interleave_sect, &((struct floppy_drive_params32 *)arg)->interleave_sect); err |= __copy_to_user(&((struct floppy_drive_params32 *)arg)->max_errors, &f->max_errors, sizeof(f->max_errors)); err |= __put_user(f->flags, &((struct floppy_drive_params32 *)arg)->flags); err |= __put_user(f->read_track, &((struct floppy_drive_params32 *)arg)->read_track); err |= __copy_to_user(((struct floppy_drive_params32 *)arg)->autodetect, f->autodetect, sizeof(f->autodetect)); err |= __put_user(f->checkfreq, &((struct floppy_drive_params32 *)arg)->checkfreq); err |= __put_user(f->native_format, &((struct floppy_drive_params32 *)arg)->native_format); break; } case FDGETDRVSTAT32: case FDPOLLDRVSTAT32: { struct floppy_drive_struct *f = karg; err = __put_user(f->flags, &((struct floppy_drive_struct32 *)arg)->flags); err |= __put_user(f->spinup_date, &((struct floppy_drive_struct32 *)arg)->spinup_date); err |= __put_user(f->select_date, &((struct floppy_drive_struct32 *)arg)->select_date); err |= __put_user(f->first_read_date, &((struct floppy_drive_struct32 *)arg)->first_read_date); err |= __put_user(f->probed_format, &((struct floppy_drive_struct32 *)arg)->probed_format); err |= __put_user(f->track, &((struct floppy_drive_struct32 *)arg)->track); err |= __put_user(f->maxblock, &((struct floppy_drive_struct32 *)arg)->maxblock); err |= __put_user(f->maxtrack, &((struct floppy_drive_struct32 *)arg)->maxtrack); err |= __put_user(f->generation, &((struct floppy_drive_struct32 *)arg)->generation); err |= __put_user(f->keep_data, &((struct floppy_drive_struct32 *)arg)->keep_data); err |= __put_user(f->fd_ref, &((struct floppy_drive_struct32 *)arg)->fd_ref); err |= __put_user(f->fd_device, &((struct floppy_drive_struct32 *)arg)->fd_device); err |= __put_user(f->last_checked, &((struct floppy_drive_struct32 *)arg)->last_checked); err |= __put_user((u64)f->dmabuf, &((struct floppy_drive_struct32 *)arg)->dmabuf); err |= __put_user((u64)f->bufblocks, &((struct floppy_drive_struct32 *)arg)->bufblocks); break; } case FDGETFDCSTAT32: { struct floppy_fdc_state *f = karg; err = __put_user(f->spec1, &((struct floppy_fdc_state32 *)arg)->spec1); err |= __put_user(f->spec2, &((struct floppy_fdc_state32 *)arg)->spec2); err |= __put_user(f->dtr, &((struct floppy_fdc_state32 *)arg)->dtr); err |= __put_user(f->version, &((struct floppy_fdc_state32 *)arg)->version); err |= __put_user(f->dor, &((struct floppy_fdc_state32 *)arg)->dor); err |= __put_user(f->address, &((struct floppy_fdc_state32 *)arg)->address); err |= __copy_to_user((char *)&((struct floppy_fdc_state32 *)arg)->address + sizeof(((struct floppy_fdc_state32 *)arg)->address), (char *)&f->address + sizeof(f->address), sizeof(int)); err |= __put_user(f->driver_version, &((struct floppy_fdc_state32 *)arg)->driver_version); err |= __copy_to_user(((struct floppy_fdc_state32 *)arg)->track, f->track, sizeof(f->track)); break; } case FDWERRORGET32: { struct floppy_write_errors *f = karg; err = __put_user(f->write_errors, &((struct floppy_write_errors32 *)arg)->write_errors); err |= __put_user(f->first_error_sector, &((struct floppy_write_errors32 *)arg)->first_error_sector); err |= __put_user(f->first_error_generation, &((struct floppy_write_errors32 *)arg)->first_error_generation); err |= __put_user(f->last_error_sector, &((struct floppy_write_errors32 *)arg)->last_error_sector); err |= __put_user(f->last_error_generation, &((struct floppy_write_errors32 *)arg)->last_error_generation); err |= __put_user(f->badness, &((struct floppy_write_errors32 *)arg)->badness); break; } default: break; } if (err) err = -EFAULT;out: if (karg) kfree(karg); return err;}typedef struct sg_io_hdr32 { s32 interface_id; /* [i] 'S' for SCSI generic (required) */ s32 dxfer_direction; /* [i] data transfer direction */ u8 cmd_len; /* [i] SCSI command length ( <= 16 bytes) */ u8 mx_sb_len; /* [i] max length to write to sbp */ u16 iovec_count; /* [i] 0 implies no scatter gather */ u32 dxfer_len; /* [i] byte count of data transfer */ u32 dxferp; /* [i], [*io] points to data transfer memory or scatter gather list */ u32 cmdp; /* [i], [*i] points to command to perform */ u32 sbp; /* [i], [*o] points to sense_buffer memory */ u32 timeout; /* [i] MAX_UINT->no timeout (unit: millisec) */ u32 flags; /* [i] 0 -> default, see SG_FLAG... */ s32 pack_id; /* [i->o] unused internally (normally) */ u32 usr_ptr; /* [i->o] unused internally */ u8 status; /* [o] scsi status */ u8 masked_status; /* [o] shifted, masked scsi status */ u8 msg_status; /* [o] messaging level data (optional) */ u8 sb_len_wr; /* [o] byte count actually written to sbp */ u16 host_status; /* [o] errors from host adapter */ u16 driver_status; /* [o] errors from software driver */ s32 resid; /* [o] dxfer_len - actual_transferred */ u32 duration; /* [o] time taken by cmd (unit: millisec) */ u32 info; /* [o] auxiliary information */} sg_io_hdr32_t; /* 64 bytes long (on sparc32) */typedef struct sg_iovec32 { u32 iov_base; u32 iov_len;} sg_iovec32_t;#define EMU_SG_MAX 128static int alloc_sg_iovec(sg_io_hdr_t *sgp, u32 uptr32){ sg_iovec32_t *uiov = (sg_iovec32_t *) A(uptr32); sg_iovec_t *kiov; int i; if (sgp->iovec_count > EMU_SG_MAX) return -EINVAL; sgp->dxferp = kmalloc(sgp->iovec_count * sizeof(sg_iovec_t), GFP_KERNEL); if (!sgp->dxferp) return -ENOMEM; memset(sgp->dxferp, 0, sgp->iovec_count * sizeof(sg_iovec_t));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -