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

📄 sys_ppc32.c

📁 microwindows移植到S3C44B0的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
}struct dqblk32 {    __u32 dqb_bhardlimit;    __u32 dqb_bsoftlimit;    __u32 dqb_curblocks;    __u32 dqb_ihardlimit;    __u32 dqb_isoftlimit;    __u32 dqb_curinodes;    __kernel_time_t32 dqb_btime;    __kernel_time_t32 dqb_itime;};                                extern asmlinkage long sys_quotactl(int cmd, const char *special, int id, caddr_t addr);/* Note: it is necessary to treat cmd and id as unsigned ints,  * with the corresponding cast to a signed int to insure that the  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */asmlinkage long sys32_quotactl(u32 cmd_parm, const char *special, u32 id_parm, unsigned long addr){  int cmd = (int)cmd_parm;  int id  = (int)id_parm;	int cmds = cmd >> SUBCMDSHIFT;	int err;	struct dqblk d;	mm_segment_t old_fs;	char *spec;		PPCDBG(PPCDBG_SYS32, "sys32_quotactl - entered - pid=%ld current=%lx comm=%s \n",		    current->pid, current, current->comm);	switch (cmds) {	case Q_GETQUOTA:		break;	case Q_SETQUOTA:	case Q_SETUSE:	case Q_SETQLIM:		if (copy_from_user (&d, (struct dqblk32 *)addr,				    sizeof (struct dqblk32)))			return -EFAULT;		d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime;		d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime;		break;	default:		return sys_quotactl(cmd, special,				    id, (caddr_t)addr);	}	spec = getname32 (special);	err = PTR_ERR(spec);	if (IS_ERR(spec)) return err;	old_fs = get_fs ();	set_fs (KERNEL_DS);	err = sys_quotactl(cmd, (const char *)spec, id, (caddr_t)&d);	set_fs (old_fs);	putname (spec);	if (cmds == Q_GETQUOTA) {		__kernel_time_t b = d.dqb_btime, i = d.dqb_itime;		((struct dqblk32 *)&d)->dqb_itime = i;		((struct dqblk32 *)&d)->dqb_btime = b;		if (copy_to_user ((struct dqblk32 *)addr, &d,				  sizeof (struct dqblk32)))			return -EFAULT;	}		PPCDBG(PPCDBG_SYS32, "sys32_quotactl - exited - pid=%ld current=%lx comm=%s \n",		    current->pid, current, current->comm);	return err;}/* readdir & getdents */#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))#define ROUND_UP(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))struct old_linux_dirent32 {	u32		d_ino;	u32		d_offset;	unsigned short	d_namlen;  /* unsigned char	d_type; */	char		d_name[1];};struct readdir_callback32 {	struct old_linux_dirent32 * dirent;	int count;};static int fillonedir(void * __buf, const char * name, int namlen,		                  off_t offset, ino_t ino, unsigned int d_type){	struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf;	struct old_linux_dirent32 * dirent;	if (buf->count)		return -EINVAL;	buf->count++;	dirent = buf->dirent;	put_user(ino, &dirent->d_ino);	put_user(offset, &dirent->d_offset);	put_user(namlen, &dirent->d_namlen);	copy_to_user(dirent->d_name, name, namlen);	put_user(0, dirent->d_name + namlen);	return 0;}asmlinkage int old32_readdir(unsigned int fd, struct old_linux_dirent32 *dirent, unsigned int count){	int error = -EBADF;	struct file * file;	struct readdir_callback32 buf;	file = fget(fd);	if (!file)		goto out;	buf.count = 0;	buf.dirent = dirent;	error = vfs_readdir(file, (filldir_t)fillonedir, &buf);	if (error < 0)		goto out_putf;	error = buf.count;out_putf:	fput(file);out:	return error;}#if 0struct linux_dirent32 {	u32		d_ino;	u32		d_off;	unsigned short	d_reclen;	char		d_name[1];};#elsestruct linux_dirent32 {	u32		d_ino;	u32		d_off;	unsigned short	d_reclen;  /* unsigned char	d_type; */	char		d_name[256];};#endifstruct getdents_callback32 {	struct linux_dirent32 * current_dir;	struct linux_dirent32 * previous;	int count;	int error;};static intfilldir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino,		               unsigned int d_type){	struct linux_dirent32 * dirent;	struct getdents_callback32 * buf = (struct getdents_callback32 *) __buf;	int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);	buf->error = -EINVAL;	/* only used if we fail.. */	if (reclen > buf->count)		return -EINVAL;	dirent = buf->previous;	if (dirent)		put_user(offset, &dirent->d_off);	dirent = buf->current_dir;	buf->previous = dirent;	put_user(ino, &dirent->d_ino);	put_user(reclen, &dirent->d_reclen);	/* put_user(d_type, &dirent->d_type); */	copy_to_user(dirent->d_name, name, namlen);	put_user(0, dirent->d_name + namlen);	((char *) dirent) += reclen;	buf->current_dir = dirent;	buf->count -= reclen;	return 0;}asmlinkage long sys32_getdents(unsigned int fd, struct linux_dirent32 *dirent, unsigned int count){	struct file * file;	struct linux_dirent32 * lastdirent;	struct getdents_callback32 buf;	int error = -EBADF;	PPCDBG(PPCDBG_SYS32NI, "sys32_getdents - running - fd=%x, pid=%ld, comm=%s \n", fd, current->pid, current->comm);	file = fget(fd);	if (!file)		goto out;	buf.current_dir = dirent;	buf.previous = NULL;	buf.count = count;	buf.error = 0;	error = vfs_readdir(file, (filldir_t)filldir, &buf);	if (error < 0)		goto out_putf;	lastdirent = buf.previous;	error = buf.error;	if(lastdirent) {		put_user(file->f_pos, &lastdirent->d_off);		error = count - buf.count;	} out_putf:	fput(file); out:	return error;}/* end of readdir & getdents *//* 32-bit timeval and related flotsam.  */struct timeval32{	int tv_sec, tv_usec;};struct itimerval32{	struct timeval32 it_interval;	struct timeval32 it_value;};/* * Ooo, nasty.  We need here to frob 32-bit unsigned longs to * 64-bit unsigned longs. */static inline intget_fd_set32(unsigned long n, unsigned long *fdset, u32 *ufdset){	if (ufdset) {		unsigned long odd;		if (verify_area(VERIFY_WRITE, ufdset, n*sizeof(u32)))			return -EFAULT;		odd = n & 1UL;		n &= ~1UL;		while (n) {			unsigned long h, l;			__get_user(l, ufdset);			__get_user(h, ufdset+1);			ufdset += 2;			*fdset++ = h << 32 | l;			n -= 2;		}		if (odd)			__get_user(*fdset, ufdset);	} else {		/* Tricky, must clear full unsigned long in the		 * kernel fdset at the end, this makes sure that		 * actually happens.		 */		memset(fdset, 0, ((n + 1) & ~1)*sizeof(u32));	}	return 0;}static inline voidset_fd_set32(unsigned long n, u32 *ufdset, unsigned long *fdset){	unsigned long odd;	if (!ufdset)		return;	odd = n & 1UL;	n &= ~1UL;	while (n) {		unsigned long h, l;		l = *fdset++;		h = l >> 32;		__put_user(l, ufdset);		__put_user(h, ufdset+1);		ufdset += 2;		n -= 2;	}	if (odd)		__put_user(*fdset, ufdset);}#define MAX_SELECT_SECONDS ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)asmlinkage long sys32_select(int n, u32 *inp, u32 *outp, u32 *exp, u32 tvp_x){	fd_set_bits fds;	struct timeval32 *tvp = (struct timeval32 *)AA(tvp_x);	char *bits;	unsigned long nn;	long timeout;	int ret, size;	  PPCDBG(PPCDBG_SYS32X, "sys32_select - entered - n=%x, inp=%p, outp=%p - pid=%ld comm=%s \n", n, inp, outp, current->pid, current->comm);	timeout = MAX_SCHEDULE_TIMEOUT;	if (tvp) {		time_t sec, usec;		if ((ret = verify_area(VERIFY_READ, tvp, sizeof(*tvp)))		    || (ret = __get_user(sec, &tvp->tv_sec))		    || (ret = __get_user(usec, &tvp->tv_usec)))			goto out_nofds;		ret = -EINVAL;		if(sec < 0 || usec < 0)			goto out_nofds;		if ((unsigned long) sec < MAX_SELECT_SECONDS) {			timeout = (usec + 1000000/HZ - 1) / (1000000/HZ);			timeout += sec * (unsigned long) HZ;		}	}	ret = -EINVAL;	if (n < 0)		goto out_nofds;	if (n > current->files->max_fdset)		n = current->files->max_fdset;	/*	 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),	 * since we used fdset we need to allocate memory in units of	 * long-words. 	 */	ret = -ENOMEM;	size = FDS_BYTES(n);	bits = kmalloc(6 * size, GFP_KERNEL);	if (!bits)		goto out_nofds;	fds.in      = (unsigned long *)  bits;	fds.out     = (unsigned long *) (bits +   size);	fds.ex      = (unsigned long *) (bits + 2*size);	fds.res_in  = (unsigned long *) (bits + 3*size);	fds.res_out = (unsigned long *) (bits + 4*size);	fds.res_ex  = (unsigned long *) (bits + 5*size);	nn = (n + 8*sizeof(u32) - 1) / (8*sizeof(u32));	if ((ret = get_fd_set32(nn, fds.in, inp)) ||	    (ret = get_fd_set32(nn, fds.out, outp)) ||	    (ret = get_fd_set32(nn, fds.ex, exp)))		goto out;	zero_fd_set(n, fds.res_in);	zero_fd_set(n, fds.res_out);	zero_fd_set(n, fds.res_ex);	ret = do_select(n, &fds, &timeout);	if (tvp && !(current->personality & STICKY_TIMEOUTS)) {		time_t sec = 0, usec = 0;		if (timeout) {			sec = timeout / HZ;			usec = timeout % HZ;			usec *= (1000000/HZ);		}		put_user(sec, &tvp->tv_sec);		put_user(usec, &tvp->tv_usec);	}  if (ret < 0)		goto out;	if (!ret) {		ret = -ERESTARTNOHAND;		if (signal_pending(current))			goto out;		ret = 0;	}	set_fd_set32(nn, inp, fds.res_in);	set_fd_set32(nn, outp, fds.res_out);	set_fd_set32(nn, exp, fds.res_ex);  out:	kfree(bits);out_nofds:	PPCDBG(PPCDBG_SYS32X, "sys32_select - exited - pid=%ld, comm=%s \n", current->pid, current->comm);	return ret;}/* * Due to some executables calling the wrong select we sometimes * get wrong args.  This determines how the args are being passed * (a single ptr to them all args passed) then calls * sys_select() with the appropriate args. -- Cort *//* Note: it is necessary to treat n as an unsigned int,  * with the corresponding cast to a signed int to insure that the  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */asmlinkage int ppc32_select(u32 n, u32* inp, u32* outp, u32* exp, u32 tvp_x){	if ((unsigned int)n >= 4096)		panic("ppc32_select - wrong arguments were passed in \n");	return sys32_select((int)n, inp, outp, exp, tvp_x);}static int cp_new_stat32(struct inode *inode, struct stat32 *statbuf){	unsigned long ino, blksize, blocks;	kdev_t dev, rdev;	umode_t mode;	nlink_t nlink;	uid_t uid;	gid_t gid;	off_t size;	time_t atime, mtime, ctime;	int err;	/* Stream the loads of inode data into the load buffer,	 * then we push it all into the store buffer below.  This	 * should give optimal cache performance.	 */	ino = inode->i_ino;	dev = inode->i_dev;	mode = inode->i_mode;	nlink = inode->i_nlink;	uid = inode->i_uid;	gid = inode->i_gid;	rdev = inode->i_rdev;	size = inode->i_size;	atime = inode->i_atime;	mtime = inode->i_mtime;	ctime = inode->i_ctime;	blksize = inode->i_blksize;	blocks = inode->i_blocks;	err  = put_user(kdev_t_to_nr(dev), &statbuf->st_dev);	err |= put_user(ino, &statbuf->st_ino);	err |= put_user(mode, &statbuf->st_mode);	err |= put_user(nlink, &statbuf->st_nlink);	err |= put_user(uid, &statbuf->st_uid);	err |= put_user(gid, &statbuf->st_gid);	err |= put_user(kdev_t_to_nr(rdev), &statbuf->st_rdev);	err |= put_user(size, &statbuf->st_size);	err |= put_user(atime, &statbuf->st_atime);	err |= put_user(0, &statbuf->__unused1);	err |= put_user(mtime, &statbuf->st_mtime);	err |= put_user(0, &statbuf->__unused2);	err |= put_user(ctime, &statbuf->st_ctime);	err |= put_user(0, &statbuf->__unused3);	if (blksize) {		err |= put_user(blksize, &statbuf->st_blksize);		err |= put_user(blocks, &statbuf->st_blocks);	} else {		unsigned int tmp_blocks;#define D_B   7#define I_B   (BLOCK_SIZE / sizeof(unsigned short))		tmp_blocks = (size + BLOCK_SIZE - 1) / BLOCK_SIZE;		if (tmp_blocks > D_B) {			unsigned int indirect;			indirect = (tmp_blocks - D_B + I_B - 1) / I_B;			tmp_blocks += indirect;			if (indirect > 1) {				indirect = (indirect - 1 + I_B - 1) / I_B;				tmp_blocks += indirect;				if (indirect > 1)					tmp_blocks++;			}		}		err |= put_user(BLOCK_SIZE, &statbuf->st_blksize);		err |= put_user((BLOCK_SIZE / 512) * tmp_blocks, &statbuf->st_blocks);#undef D_B#undef I_B	}	err |= put_user(0, &statbuf->__unused4[0]);	err |= put_user(0, &statbuf->__unused4[1]);	return err;}static __inline__ intdo_revalidate(struct dentry *dentry){	struct inode * inode = dentry->d_inode;	if (inode->i_op && inode->i_op->revalidate)		return inode->i_op->revalidate(dentry);	return 0;}asmlinkage long sys32_newstat(char* filename, struct stat32* statbuf){

⌨️ 快捷键说明

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