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

📄 sys_sunos32.c

📁 linux嵌入式课程实践中的一个关于声卡驱动程序 。
💻 C
📖 第 1 页 / 共 3 页
字号:
	siginfo_t info;	static int cnt;	regs = current->thread.kregs;	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {		regs->tpc &= 0xffffffff;		regs->tnpc &= 0xffffffff;	}	info.si_signo = SIGSYS;	info.si_errno = 0;	info.si_code = __SI_FAULT|0x100;	info.si_addr = (void *)regs->tpc;	info.si_trapno = regs->u_regs[UREG_G1];	send_sig_info(SIGSYS, &info, current);	if (cnt++ < 4) {		printk("Process makes ni_syscall number %d, register dump:\n",		       (int) regs->u_regs[UREG_G1]);		show_regs(regs);	}	return -ENOSYS;}/* This is not a real and complete implementation yet, just to keep * the easy SunOS binaries happy. */asmlinkage int sunos_fpathconf(int fd, int name){	int ret;	switch(name) {	case _PCONF_LINK:		ret = LINK_MAX;		break;	case _PCONF_CANON:		ret = MAX_CANON;		break;	case _PCONF_INPUT:		ret = MAX_INPUT;		break;	case _PCONF_NAME:		ret = NAME_MAX;		break;	case _PCONF_PATH:		ret = PATH_MAX;		break;	case _PCONF_PIPE:		ret = PIPE_BUF;		break;	case _PCONF_CHRESTRICT:		/* XXX Investigate XXX */		ret = 1;		break;	case _PCONF_NOTRUNC:		/* XXX Investigate XXX */	case _PCONF_VDISABLE:		ret = 0;		break;	default:		ret = -EINVAL;		break;	}	return ret;}asmlinkage int sunos_pathconf(u32 u_path, int name){	int ret;	ret = sunos_fpathconf(0, name); /* XXX cheese XXX */	return ret;}/* SunOS mount system call emulation */extern asmlinkage intsys32_select(int n, u32 inp, u32 outp, u32 exp, u32 tvp);struct timeval32{	int tv_sec, tv_usec;};asmlinkage int sunos_select(int width, u32 inp, u32 outp, u32 exp, u32 tvp_x){	int ret;	/* SunOS binaries expect that select won't change the tvp contents */	ret = sys32_select (width, inp, outp, exp, tvp_x);	if (ret == -EINTR && tvp_x) {		struct timeval32 *tvp = (struct timeval32 *)A(tvp_x);		time_t sec, usec;		__get_user(sec, &tvp->tv_sec);		__get_user(usec, &tvp->tv_usec);		if (sec == 0 && usec == 0)			ret = 0;	}	return ret;}asmlinkage void sunos_nop(void){	return;}/* XXXXXXXXXX SunOS mount/umount. XXXXXXXXXXX */#define SMNT_RDONLY       1#define SMNT_NOSUID       2#define SMNT_NEWTYPE      4#define SMNT_GRPID        8#define SMNT_REMOUNT      16#define SMNT_NOSUB        32#define SMNT_MULTI        64#define SMNT_SYS5         128struct sunos_fh_t {	char fh_data [NFS_FHSIZE];};struct sunos_nfs_mount_args {	struct sockaddr_in  *addr; /* file server address */	struct nfs_fh *fh;     /* File handle to be mounted */	int        flags;      /* flags */	int        wsize;      /* write size in bytes */	int        rsize;      /* read size in bytes */	int        timeo;      /* initial timeout in .1 secs */	int        retrans;    /* times to retry send */	char       *hostname;  /* server's hostname */	int        acregmin;   /* attr cache file min secs */	int        acregmax;   /* attr cache file max secs */	int        acdirmin;   /* attr cache dir min secs */	int        acdirmax;   /* attr cache dir max secs */	char       *netname;   /* server's netname */};extern asmlinkage int sys_mount(char *, char *, char *, unsigned long, void *);extern asmlinkage int sys_connect(int fd, struct sockaddr *uservaddr, int addrlen);extern asmlinkage int sys_socket(int family, int type, int protocol);extern asmlinkage int sys_bind(int fd, struct sockaddr *umyaddr, int addrlen);/* Bind the socket on a local reserved port and connect it to the * remote server.  This on Linux/i386 is done by the mount program, * not by the kernel.  *//* XXXXXXXXXXXXXXXXXXXX */static intsunos_nfs_get_server_fd (int fd, struct sockaddr_in *addr){	struct sockaddr_in local;	struct sockaddr_in server;	int    try_port;	int    ret;	struct socket *socket;	struct inode  *inode;	struct file   *file;	file = fget(fd);	if(!file)		return 0;	inode = file->f_dentry->d_inode;	socket = &inode->u.socket_i;	local.sin_family = AF_INET;	local.sin_addr.s_addr = INADDR_ANY;	/* IPPORT_RESERVED = 1024, can't find the definition in the kernel */	try_port = 1024;	do {		local.sin_port = htons (--try_port);		ret = socket->ops->bind(socket, (struct sockaddr*)&local,					sizeof(local));	} while (ret && try_port > (1024 / 2));	if (ret) {		fput(file);		return 0;	}	server.sin_family = AF_INET;	server.sin_addr = addr->sin_addr;	server.sin_port = NFS_PORT;	/* Call sys_connect */	ret = socket->ops->connect (socket, (struct sockaddr *) &server,				    sizeof (server), file->f_flags);	fput(file);	if (ret < 0)		return 0;	return 1;}/* XXXXXXXXXXXXXXXXXXXX */static int get_default (int value, int def_value){    if (value)	return value;    else	return def_value;}/* XXXXXXXXXXXXXXXXXXXX */static int sunos_nfs_mount(char *dir_name, int linux_flags, void *data){	int  server_fd;	char *the_name;	struct nfs_mount_data linux_nfs_mount;	struct sunos_nfs_mount_args sunos_mount;	/* Ok, here comes the fun part: Linux's nfs mount needs a	 * socket connection to the server, but SunOS mount does not	 * require this, so we use the information on the destination	 * address to create a socket and bind it to a reserved	 * port on this system	 */	if (copy_from_user(&sunos_mount, data, sizeof(sunos_mount)))		return -EFAULT;	server_fd = sys_socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);	if (server_fd < 0)		return -ENXIO;	if (copy_from_user(&linux_nfs_mount.addr,sunos_mount.addr,				sizeof(*sunos_mount.addr)) ||	    copy_from_user(&linux_nfs_mount.root,sunos_mount.fh,				sizeof(*sunos_mount.fh))) {		sys_close (server_fd);		return -EFAULT;	}	if (!sunos_nfs_get_server_fd (server_fd, &linux_nfs_mount.addr)){		sys_close (server_fd);		return -ENXIO;	}	/* Now, bind it to a locally reserved port */	linux_nfs_mount.version  = NFS_MOUNT_VERSION;	linux_nfs_mount.flags    = sunos_mount.flags;	linux_nfs_mount.fd       = server_fd;		linux_nfs_mount.rsize    = get_default (sunos_mount.rsize, 8192);	linux_nfs_mount.wsize    = get_default (sunos_mount.wsize, 8192);	linux_nfs_mount.timeo    = get_default (sunos_mount.timeo, 10);	linux_nfs_mount.retrans  = sunos_mount.retrans;		linux_nfs_mount.acregmin = sunos_mount.acregmin;	linux_nfs_mount.acregmax = sunos_mount.acregmax;	linux_nfs_mount.acdirmin = sunos_mount.acdirmin;	linux_nfs_mount.acdirmax = sunos_mount.acdirmax;	the_name = getname(sunos_mount.hostname);	if(IS_ERR(the_name))		return PTR_ERR(the_name);	strncpy (linux_nfs_mount.hostname, the_name, 254);	linux_nfs_mount.hostname [255] = 0;	putname (the_name);		return do_mount ("", dir_name, "nfs", linux_flags, &linux_nfs_mount);}/* XXXXXXXXXXXXXXXXXXXX */asmlinkage intsunos_mount(char *type, char *dir, int flags, void *data){	int linux_flags = 0;	int ret = -EINVAL;	char *dev_fname = 0;	char *dir_page, *type_page;	if (!capable (CAP_SYS_ADMIN))		return -EPERM;	/* We don't handle the integer fs type */	if ((flags & SMNT_NEWTYPE) == 0)		goto out;	/* Do not allow for those flags we don't support */	if (flags & (SMNT_GRPID|SMNT_NOSUB|SMNT_MULTI|SMNT_SYS5))		goto out;	if(flags & SMNT_REMOUNT)		linux_flags |= MS_REMOUNT;	if(flags & SMNT_RDONLY)		linux_flags |= MS_RDONLY;	if(flags & SMNT_NOSUID)		linux_flags |= MS_NOSUID;	dir_page = getname(dir);	ret = PTR_ERR(dir_page);	if (IS_ERR(dir_page))		goto out;	type_page = getname(type);	ret = PTR_ERR(type_page);	if (IS_ERR(type_page))		goto out1;	if(strcmp(type_page, "ext2") == 0) {		dev_fname = getname(data);	} else if(strcmp(type_page, "iso9660") == 0) {		dev_fname = getname(data);	} else if(strcmp(type_page, "minix") == 0) {		dev_fname = getname(data);	} else if(strcmp(type_page, "nfs") == 0) {		ret = sunos_nfs_mount (dir_page, flags, data);		goto out2;        } else if(strcmp(type_page, "ufs") == 0) {		printk("Warning: UFS filesystem mounts unsupported.\n");		ret = -ENODEV;		goto out2;	} else if(strcmp(type_page, "proc")) {		ret = -ENODEV;		goto out2;	}	ret = PTR_ERR(dev_fname);	if (IS_ERR(dev_fname))		goto out2;	lock_kernel();	ret = do_mount(dev_fname, dir_page, type_page, linux_flags, NULL);	unlock_kernel();	if (dev_fname)		putname(dev_fname);out2:	putname(type_page);out1:	putname(dir_page);out:	return ret;}extern asmlinkage int sys_setsid(void);extern asmlinkage int sys_setpgid(pid_t, pid_t);asmlinkage int sunos_setpgrp(pid_t pid, pid_t pgid){	int ret;	/* So stupid... */	if((!pid || pid == current->pid) &&	   !pgid) {		sys_setsid();		ret = 0;	} else {		ret = sys_setpgid(pid, pgid);	}	return ret;}/* So stupid... */extern asmlinkage int sys32_wait4(__kernel_pid_t32 pid,				  u32 stat_addr, int options, u32 ru);asmlinkage int sunos_wait4(__kernel_pid_t32 pid, u32 stat_addr, int options, u32 ru){	int ret;	ret = sys32_wait4((pid ? pid : ((__kernel_pid_t32)-1)),			  stat_addr, options, ru);	return ret;}extern int kill_pg(int, int, int);asmlinkage int sunos_killpg(int pgrp, int sig){	return kill_pg(pgrp, sig, 0);}asmlinkage int sunos_audit(void){	printk ("sys_audit\n");	return -1;}extern asmlinkage u32 sunos_gethostid(void){	u32 ret;	ret = (((u32)idprom->id_machtype << 24) | ((u32)idprom->id_sernum));	return ret;}/* sysconf options, for SunOS compatibility */#define   _SC_ARG_MAX             1#define   _SC_CHILD_MAX           2#define   _SC_CLK_TCK             3#define   _SC_NGROUPS_MAX         4#define   _SC_OPEN_MAX            5#define   _SC_JOB_CONTROL         6#define   _SC_SAVED_IDS           7#define   _SC_VERSION             8extern asmlinkage s32 sunos_sysconf (int name){	s32 ret;	switch (name){	case _SC_ARG_MAX:		ret = ARG_MAX;		break;	case _SC_CHILD_MAX:		ret = CHILD_MAX;		break;	case _SC_CLK_TCK:		ret = HZ;		break;	case _SC_NGROUPS_MAX:		ret = NGROUPS_MAX;		break;	case _SC_OPEN_MAX:		ret = OPEN_MAX;		break;	case _SC_JOB_CONTROL:		ret = 1;	/* yes, we do support job control */		break;	case _SC_SAVED_IDS:		ret = 1;	/* yes, we do support saved uids  */		break;	case _SC_VERSION:		/* mhm, POSIX_VERSION is in /usr/include/unistd.h		 * should it go on /usr/include/linux?		 */		ret = 199009;		break;	default:		ret = -1;		break;	};	return ret;}asmlinkage int sunos_semsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 ptr){	union semun arg4;	int ret;	switch (op) {	case 0:		/* Most arguments match on a 1:1 basis but cmd doesn't */		switch(arg3) {		case 4:			arg3=GETPID; break;		case 5:			arg3=GETVAL; break;		case 6:			arg3=GETALL; break;		case 3:			arg3=GETNCNT; break;		case 7:			arg3=GETZCNT; break;		case 8:			arg3=SETVAL; break;		case 9:			arg3=SETALL; break;		}

⌨️ 快捷键说明

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