⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ioctl32.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 5 页
字号:
		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;static 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;	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));	kiov = (sg_iovec_t *) sgp->dxferp;	for (i = 0; i < sgp->iovec_count; i++) {		u32 iov_base32;		if (__get_user(iov_base32, &uiov->iov_base) ||		    __get_user(kiov->iov_len, &uiov->iov_len))			return -EFAULT;		kiov->iov_base = kmalloc(kiov->iov_len, GFP_KERNEL);		if (!kiov->iov_base)			return -ENOMEM;		if (copy_from_user(kiov->iov_base,				   (void *) A(iov_base32),				   kiov->iov_len))			return -EFAULT;		uiov++;		kiov++;	}	return 0;}static int copy_back_sg_iovec(sg_io_hdr_t *sgp, u32 uptr32){	sg_iovec32_t *uiov = (sg_iovec32_t *) A(uptr32);	sg_iovec_t *kiov = (sg_iovec_t *) sgp->dxferp;	int i;	for (i = 0; i < sgp->iovec_count; i++) {		u32 iov_base32;		if (__get_user(iov_base32, &uiov->iov_base))			return -EFAULT;		if (copy_to_user((void *) A(iov_base32),				 kiov->iov_base,				 kiov->iov_len))			return -EFAULT;		uiov++;		kiov++;	}	return 0;}static void free_sg_iovec(sg_io_hdr_t *sgp){	sg_iovec_t *kiov = (sg_iovec_t *) sgp->dxferp;	int i;	for (i = 0; i < sgp->iovec_count; i++) {		if (kiov->iov_base) {			kfree(kiov->iov_base);			kiov->iov_base = NULL;		}		kiov++;	}	kfree(sgp->dxferp);	sgp->dxferp = NULL;}static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg){	sg_io_hdr32_t *sg_io32;	sg_io_hdr_t sg_io64;	u32 dxferp32, cmdp32, sbp32;	mm_segment_t old_fs;	int err = 0;	sg_io32 = (sg_io_hdr32_t *)arg;	err = __get_user(sg_io64.interface_id, &sg_io32->interface_id);	err |= __get_user(sg_io64.dxfer_direction, &sg_io32->dxfer_direction);	err |= __get_user(sg_io64.cmd_len, &sg_io32->cmd_len);	err |= __get_user(sg_io64.mx_sb_len, &sg_io32->mx_sb_len);	err |= __get_user(sg_io64.iovec_count, &sg_io32->iovec_count);	err |= __get_user(sg_io64.dxfer_len, &sg_io32->dxfer_len);	err |= __get_user(sg_io64.timeout, &sg_io32->timeout);	err |= __get_user(sg_io64.flags, &sg_io32->flags);	err |= __get_user(sg_io64.pack_id, &sg_io32->pack_id);	sg_io64.dxferp = NULL;	sg_io64.cmdp = NULL;	sg_io64.sbp = NULL;	err |= __get_user(cmdp32, &sg_io32->cmdp);	sg_io64.cmdp = kmalloc(sg_io64.cmd_len, GFP_KERNEL);	if (!sg_io64.cmdp) {		err = -ENOMEM;		goto out;	}	if (copy_from_user(sg_io64.cmdp,			   (void *) A(cmdp32),			   sg_io64.cmd_len)) {		err = -EFAULT;		goto out;	}	err |= __get_user(sbp32, &sg_io32->sbp);	sg_io64.sbp = kmalloc(sg_io64.mx_sb_len, GFP_KERNEL);	if (!sg_io64.sbp) {		err = -ENOMEM;		goto out;	}	if (copy_from_user(sg_io64.sbp,			   (void *) A(sbp32),			   sg_io64.mx_sb_len)) {		err = -EFAULT;		goto out;	}	err |= __get_user(dxferp32, &sg_io32->dxferp);	if (sg_io64.iovec_count) {		int ret;		if ((ret = alloc_sg_iovec(&sg_io64, dxferp32))) {			err = ret;			goto out;		}	} else {		sg_io64.dxferp = kmalloc(sg_io64.dxfer_len, GFP_KERNEL);		if (!sg_io64.dxferp) {			err = -ENOMEM;			goto out;		}		if (copy_from_user(sg_io64.dxferp,				   (void *) A(dxferp32),				   sg_io64.dxfer_len)) {			err = -EFAULT;			goto out;		}	}	/* Unused internally, do not even bother to copy it over. */	sg_io64.usr_ptr = NULL;	if (err)		return -EFAULT;	old_fs = get_fs();	set_fs (KERNEL_DS);	err = sys_ioctl (fd, cmd, (unsigned long) &sg_io64);	set_fs (old_fs);	if (err < 0)		goto out;	err = __put_user(sg_io64.pack_id, &sg_io32->pack_id);	err |= __put_user(sg_io64.status, &sg_io32->status);	err |= __put_user(sg_io64.masked_status, &sg_io32->masked_status);	err |= __put_user(sg_io64.msg_status, &sg_io32->msg_status);	err |= __put_user(sg_io64.sb_len_wr, &sg_io32->sb_len_wr);	err |= __put_user(sg_io64.host_status, &sg_io32->host_status);	err |= __put_user(sg_io64.driver_status, &sg_io32->driver_status);	err |= __put_user(sg_io64.resid, &sg_io32->resid);	err |= __put_user(sg_io64.duration, &sg_io32->duration);	err |= __put_user(sg_io64.info, &sg_io32->info);	err |= copy_to_user((void *)A(sbp32), sg_io64.sbp, sg_io64.mx_sb_len);	if (sg_io64.dxferp) {		if (sg_io64.iovec_count)			err |= copy_back_sg_iovec(&sg_io64, dxferp32);		else			err |= copy_to_user((void *)A(dxferp32),					    sg_io64.dxferp,					    sg_io64.dxfer_len);	}	if (err)		err = -EFAULT;out:	if (sg_io64.cmdp)		kfree(sg_io64.cmdp);	if (sg_io64.sbp)		kfree(sg_io64.sbp);	if (sg_io64.dxferp) {		if (sg_io64.iovec_count) {			free_sg_iovec(&sg_io64);		} else {			kfree(sg_io64.dxferp);		}	}	return err;}struct ppp_option_data32 {	__kernel_caddr_t32	ptr;	__u32			length;	int			transmit;};#define PPPIOCSCOMPRESS32	_IOW('t', 77, struct ppp_option_data32)struct ppp_idle32 {	__kernel_time_t32 xmit_idle;	__kernel_time_t32 recv_idle;};#define PPPIOCGIDLE32		_IOR('t', 63, struct ppp_idle32)static int ppp_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg){	mm_segment_t old_fs = get_fs();	struct ppp_option_data32 data32;	struct ppp_option_data data;	struct ppp_idle32 idle32;	struct ppp_idle idle;	unsigned int kcmd;	void *karg;	int err = 0;	switch (cmd) {	case PPPIOCGIDLE32:		kcmd = PPPIOCGIDLE;		karg = &idle;		break;	case PPPIOCSCOMPRESS32:		if (copy_from_user(&data32, (struct ppp_option_data32 *)arg, sizeof(struct ppp_option_data32)))			return -EFAULT;		data.ptr = kmalloc (data32.length, GFP_KERNEL);		if (!data.ptr)			return -ENOMEM;		if (copy_from_user(data.ptr, (__u8 *)A(data32.ptr), data32.length)) {			kfree(data.ptr);			return -EFAULT;		}		data.length = data32.length;		data.transmit = data32.transmit;		kcmd = PPPIOCSCOMPRESS;		karg = &data;		break;	default:		do {			static int count = 0;			if (++count <= 20)				printk("ppp_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);	switch (cmd) {	case PPPIOCGIDLE32:		if (err)			return err;		idle32.xmit_idle = idle.xmit_idle;		idle32.recv_idle = idle.recv_idle;		if (copy_to_user((struct ppp_idle32 *)arg, &idle32, sizeof(struct ppp_idle32)))			return -EFAULT;		break;	case PPPIOCSCOMPRESS32:		kfree(data.ptr);		break;	default:		break;	}	return err;}struct mtget32 {	__u32	mt_type;	__u32	mt_resid;	__u32	mt_dsreg;	__u32	mt_gstat;	__u32	mt_erreg;	__kernel_daddr_t32	mt_fileno;	__kernel_daddr_t32	mt_blkno;};#define MTIOCGET32	_IOR('m', 2, struct mtget32)struct mtpos32 {	__u32	mt_blkno;};#define MTIOCPOS32	_IOR('m', 3, struct mtpos32)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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -