Linux Audio

Check our new training course

Loading...
  1/*
  2 *    Implements HPUX syscalls.
  3 *
  4 *    Copyright (C) 1999 Matthew Wilcox <willy with parisc-linux.org>
  5 *    Copyright (C) 2000 Philipp Rumpf
  6 *    Copyright (C) 2000 John Marvin <jsm with parisc-linux.org>
  7 *    Copyright (C) 2000 Michael Ang <mang with subcarrier.org>
  8 *    Copyright (C) 2001 Nathan Neulinger <nneul at umr.edu>
  9 *
 10 *    This program is free software; you can redistribute it and/or modify
 11 *    it under the terms of the GNU General Public License as published by
 12 *    the Free Software Foundation; either version 2 of the License, or
 13 *    (at your option) any later version.
 14 *
 15 *    This program is distributed in the hope that it will be useful,
 16 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 17 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 18 *    GNU General Public License for more details.
 19 *
 20 *    You should have received a copy of the GNU General Public License
 21 *    along with this program; if not, write to the Free Software
 22 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 23 */
 24
 25#include <linux/capability.h>
 26#include <linux/file.h>
 27#include <linux/fs.h>
 28#include <linux/namei.h>
 29#include <linux/sched.h>
 30#include <linux/slab.h>
 31#include <linux/syscalls.h>
 32#include <linux/utsname.h>
 33#include <linux/vfs.h>
 34#include <linux/vmalloc.h>
 35
 36#include <asm/errno.h>
 37#include <asm/pgalloc.h>
 38#include <asm/uaccess.h>
 39
 40unsigned long hpux_brk(unsigned long addr)
 41{
 42	/* Sigh.  Looks like HP/UX libc relies on kernel bugs. */
 43	return sys_brk(addr + PAGE_SIZE);
 44}
 45
 46int hpux_sbrk(void)
 47{
 48	return -ENOSYS;
 49}
 50
 51/* Random other syscalls */
 52
 53int hpux_nice(int priority_change)
 54{
 55	return -ENOSYS;
 56}
 57
 58int hpux_ptrace(void)
 59{
 60	return -ENOSYS;
 61}
 62
 63int hpux_wait(int __user *stat_loc)
 64{
 65	return sys_waitpid(-1, stat_loc, 0);
 66}
 67
 68int hpux_setpgrp(void)
 69{
 70	return sys_setpgid(0,0);
 71}
 72
 73int hpux_setpgrp3(void)
 74{
 75	return hpux_setpgrp();
 76}
 77
 78#define _SC_CPU_VERSION	10001
 79#define _SC_OPEN_MAX	4
 80#define CPU_PA_RISC1_1	0x210
 81
 82int hpux_sysconf(int which)
 83{
 84	switch (which) {
 85	case _SC_CPU_VERSION:
 86		return CPU_PA_RISC1_1;
 87	case _SC_OPEN_MAX:
 88		return INT_MAX;
 89	default:
 90		return -EINVAL;
 91	}
 92}
 93
 94/*****************************************************************************/
 95
 96#define HPUX_UTSLEN 9
 97#define HPUX_SNLEN 15
 98
 99struct hpux_utsname {
100	char sysname[HPUX_UTSLEN];
101	char nodename[HPUX_UTSLEN];
102	char release[HPUX_UTSLEN];
103	char version[HPUX_UTSLEN];
104	char machine[HPUX_UTSLEN];
105	char idnumber[HPUX_SNLEN];
106} ;
107
108struct hpux_ustat {
109	int32_t		f_tfree;	/* total free (daddr_t)  */
110	u_int32_t	f_tinode;	/* total inodes free (ino_t)  */
111	char		f_fname[6];	/* filsys name */
112	char		f_fpack[6];	/* filsys pack name */
113	u_int32_t	f_blksize;	/* filsys block size (int) */
114};
115
116/*
117 * HPUX's utssys() call.  It's a collection of miscellaneous functions,
118 * alas, so there's no nice way of splitting them up.
119 */
120
121/*  This function is called from hpux_utssys(); HP-UX implements
122 *  ustat() as an option to utssys().
123 *
124 *  Now, struct ustat on HP-UX is exactly the same as on Linux, except
125 *  that it contains one addition field on the end, int32_t f_blksize.
126 *  So, we could have written this function to just call the Linux
127 *  sys_ustat(), (defined in linux/fs/super.c), and then just
128 *  added this additional field to the user's structure.  But I figure
129 *  if we're gonna be digging through filesystem structures to get
130 *  this, we might as well just do the whole enchilada all in one go.
131 *
132 *  So, most of this function is almost identical to sys_ustat().
133 *  I have placed comments at the few lines changed or added, to
134 *  aid in porting forward if and when sys_ustat() is changed from
135 *  its form in kernel 2.2.5.
136 */
137static int hpux_ustat(dev_t dev, struct hpux_ustat __user *ubuf)
138{
139	struct hpux_ustat tmp;  /* Changed to hpux_ustat */
140	struct kstatfs sbuf;
141	int err = vfs_ustat(dev, &sbuf);
142	if (err)
143		goto out;
144
145	memset(&tmp,0,sizeof(tmp));
146
147	tmp.f_tfree = (int32_t)sbuf.f_bfree;
148	tmp.f_tinode = (u_int32_t)sbuf.f_ffree;
149	tmp.f_blksize = (u_int32_t)sbuf.f_bsize;  /*  Added this line  */
150
151	err = copy_to_user(ubuf, &tmp, sizeof(tmp)) ? -EFAULT : 0;
152out:
153	return err;
154}
155
156/*
157 * Wrapper for hpux statfs call. At the moment, just calls the linux native one
158 * and ignores the extra fields at the end of the hpux statfs struct.
159 *
160 */
161
162typedef int32_t hpux_fsid_t[2];              /* file system ID type */
163typedef uint16_t hpux_site_t;
164
165struct hpux_statfs {
166     int32_t f_type;                    /* type of info, zero for now */
167     int32_t f_bsize;                   /* fundamental file system block size */
168     int32_t f_blocks;                  /* total blocks in file system */
169     int32_t f_bfree;                   /* free block in fs */
170     int32_t f_bavail;                  /* free blocks avail to non-superuser */
171     int32_t f_files;                   /* total file nodes in file system */
172     int32_t f_ffree;                   /* free file nodes in fs */
173     hpux_fsid_t  f_fsid;                    /* file system ID */
174     int32_t f_magic;                   /* file system magic number */
175     int32_t f_featurebits;             /* file system features */
176     int32_t f_spare[4];                /* spare for later */
177     hpux_site_t  f_cnode;                   /* cluster node where mounted */
178     int16_t f_pad;
179};
180
181static int do_statfs_hpux(struct kstatfs *st, struct hpux_statfs __user *p)
182{
183	struct hpux_statfs buf;
184	memset(&buf, 0, sizeof(buf));
185	buf.f_type = st->f_type;
186	buf.f_bsize = st->f_bsize;
187	buf.f_blocks = st->f_blocks;
188	buf.f_bfree = st->f_bfree;
189	buf.f_bavail = st->f_bavail;
190	buf.f_files = st->f_files;
191	buf.f_ffree = st->f_ffree;
192	buf.f_fsid[0] = st->f_fsid.val[0];
193	buf.f_fsid[1] = st->f_fsid.val[1];
194	if (copy_to_user(p, &buf, sizeof(buf)))
195		return -EFAULT;
196	return 0;
197}
198
199/* hpux statfs */
200asmlinkage long hpux_statfs(const char __user *pathname,
201						struct hpux_statfs __user *buf)
202{
203	struct kstatfs st;
204	int error = user_statfs(pathname, &st);
205	if (!error)
206		error = do_statfs_hpux(&st, buf);
207	return error;
208}
209
210asmlinkage long hpux_fstatfs(unsigned int fd, struct hpux_statfs __user * buf)
211{
212	struct kstatfs st;
213	int error = fd_statfs(fd, &st);
214	if (!error)
215		error = do_statfs_hpux(&st, buf);
216	return error;
217}
218
219
220/*  This function is called from hpux_utssys(); HP-UX implements
221 *  uname() as an option to utssys().
222 *
223 *  The form of this function is pretty much copied from sys_olduname(),
224 *  defined in linux/arch/i386/kernel/sys_i386.c.
225 */
226/*  TODO: Are these put_user calls OK?  Should they pass an int?
227 *        (I copied it from sys_i386.c like this.)
228 */
229static int hpux_uname(struct hpux_utsname __user *name)
230{
231	int error;
232
233	if (!name)
234		return -EFAULT;
235	if (!access_ok(VERIFY_WRITE,name,sizeof(struct hpux_utsname)))
236		return -EFAULT;
237
238	down_read(&uts_sem);
239
240	error = __copy_to_user(&name->sysname, &utsname()->sysname,
241			       HPUX_UTSLEN - 1);
242	error |= __put_user(0, name->sysname + HPUX_UTSLEN - 1);
243	error |= __copy_to_user(&name->nodename, &utsname()->nodename,
244				HPUX_UTSLEN - 1);
245	error |= __put_user(0, name->nodename + HPUX_UTSLEN - 1);
246	error |= __copy_to_user(&name->release, &utsname()->release,
247				HPUX_UTSLEN - 1);
248	error |= __put_user(0, name->release + HPUX_UTSLEN - 1);
249	error |= __copy_to_user(&name->version, &utsname()->version,
250				HPUX_UTSLEN - 1);
251	error |= __put_user(0, name->version + HPUX_UTSLEN - 1);
252	error |= __copy_to_user(&name->machine, &utsname()->machine,
253				HPUX_UTSLEN - 1);
254	error |= __put_user(0, name->machine + HPUX_UTSLEN - 1);
255
256	up_read(&uts_sem);
257
258	/*  HP-UX  utsname has no domainname field.  */
259
260	/*  TODO:  Implement idnumber!!!  */
261#if 0
262	error |= __put_user(0,name->idnumber);
263	error |= __put_user(0,name->idnumber+HPUX_SNLEN-1);
264#endif
265
266	error = error ? -EFAULT : 0;
267
268	return error;
269}
270
271/*  Note: HP-UX just uses the old suser() function to check perms
272 *  in this system call.  We'll use capable(CAP_SYS_ADMIN).
273 */
274int hpux_utssys(char __user *ubuf, int n, int type)
275{
276	int len;
277	int error;
278	switch( type ) {
279	case 0:
280		/*  uname():  */
281		return hpux_uname((struct hpux_utsname __user *)ubuf);
282		break ;
283	case 1:
284		/*  Obsolete (used to be umask().)  */
285		return -EFAULT ;
286		break ;
287	case 2:
288		/*  ustat():  */
289		return hpux_ustat(new_decode_dev(n),
290				  (struct hpux_ustat __user *)ubuf);
291		break;
292	case 3:
293		/*  setuname():
294		 *
295		 *  On linux (unlike HP-UX), utsname.nodename
296		 *  is the same as the hostname.
297		 *
298		 *  sys_sethostname() is defined in linux/kernel/sys.c.
299		 */
300		if (!capable(CAP_SYS_ADMIN))
301			return -EPERM;
302		/*  Unlike Linux, HP-UX returns an error if n==0:  */
303		if ( n <= 0 )
304			return -EINVAL ;
305		/*  Unlike Linux, HP-UX truncates it if n is too big:  */
306		len = (n <= __NEW_UTS_LEN) ? n : __NEW_UTS_LEN ;
307		return sys_sethostname(ubuf, len);
308		break ;
309	case 4:
310		/*  sethostname():
311		 *
312		 *  sys_sethostname() is defined in linux/kernel/sys.c.
313		 */
314		if (!capable(CAP_SYS_ADMIN))
315			return -EPERM;
316		/*  Unlike Linux, HP-UX returns an error if n==0:  */
317		if ( n <= 0 )
318			return -EINVAL ;
319		/*  Unlike Linux, HP-UX truncates it if n is too big:  */
320		len = (n <= __NEW_UTS_LEN) ? n : __NEW_UTS_LEN ;
321		return sys_sethostname(ubuf, len);
322		break ;
323	case 5:
324		/*  gethostname():
325		 *
326		 *  sys_gethostname() is defined in linux/kernel/sys.c.
327		 */
328		/*  Unlike Linux, HP-UX returns an error if n==0:  */
329		if ( n <= 0 )
330			return -EINVAL ;
331		return sys_gethostname(ubuf, n);
332		break ;
333	case 6:
334		/*  Supposedly called from setuname() in libc.
335		 *  TODO: When and why is this called?
336		 *        Is it ever even called?
337		 *
338		 *  This code should look a lot like sys_sethostname(),
339		 *  defined in linux/kernel/sys.c.  If that gets updated,
340		 *  update this code similarly.
341		 */
342		if (!capable(CAP_SYS_ADMIN))
343			return -EPERM;
344		/*  Unlike Linux, HP-UX returns an error if n==0:  */
345		if ( n <= 0 )
346			return -EINVAL ;
347		/*  Unlike Linux, HP-UX truncates it if n is too big:  */
348		len = (n <= __NEW_UTS_LEN) ? n : __NEW_UTS_LEN ;
349		/**/
350		/*  TODO:  print a warning about using this?  */
351		down_write(&uts_sem);
352		error = -EFAULT;
353		if (!copy_from_user(utsname()->sysname, ubuf, len)) {
354			utsname()->sysname[len] = 0;
355			error = 0;
356		}
357		up_write(&uts_sem);
358		return error;
359		break ;
360	case 7:
361		/*  Sets utsname.release, if you're allowed.
362		 *  Undocumented.  Used by swinstall to change the
363		 *  OS version, during OS updates.  Yuck!!!
364		 *
365		 *  This code should look a lot like sys_sethostname()
366		 *  in linux/kernel/sys.c.  If that gets updated, update
367		 *  this code similarly.
368		 */
369		if (!capable(CAP_SYS_ADMIN))
370			return -EPERM;
371		/*  Unlike Linux, HP-UX returns an error if n==0:  */
372		if ( n <= 0 )
373			return -EINVAL ;
374		/*  Unlike Linux, HP-UX truncates it if n is too big:  */
375		len = (n <= __NEW_UTS_LEN) ? n : __NEW_UTS_LEN ;
376		/**/
377		/*  TODO:  print a warning about this?  */
378		down_write(&uts_sem);
379		error = -EFAULT;
380		if (!copy_from_user(utsname()->release, ubuf, len)) {
381			utsname()->release[len] = 0;
382			error = 0;
383		}
384		up_write(&uts_sem);
385		return error;
386		break ;
387	default:
388		/*  This system call returns -EFAULT if given an unknown type.
389	 	 *  Why not -EINVAL?  I don't know, it's just not what they did.
390	 	 */
391		return -EFAULT ;
392	}
393}
394
395int hpux_getdomainname(char __user *name, int len)
396{
397 	int nlen;
398 	int err = -EFAULT;
399 	
400 	down_read(&uts_sem);
401 	
402	nlen = strlen(utsname()->domainname) + 1;
403
404	if (nlen < len)
405		len = nlen;
406	if(len > __NEW_UTS_LEN)
407		goto done;
408	if(copy_to_user(name, utsname()->domainname, len))
409		goto done;
410	err = 0;
411done:
412	up_read(&uts_sem);
413	return err;
414	
415}
416
417int hpux_pipe(int *kstack_fildes)
418{
419	return do_pipe_flags(kstack_fildes, 0);
420}
421
422/* lies - says it works, but it really didn't lock anything */
423int hpux_lockf(int fildes, int function, off_t size)
424{
425	return 0;
426}
427
428int hpux_sysfs(int opcode, unsigned long arg1, unsigned long arg2)
429{
430	char *fsname = NULL;
431	int len = 0;
432	int fstype;
433
434/*Unimplemented HP-UX syscall emulation. Syscall #334 (sysfs)
435  Args: 1 80057bf4 0 400179f0 0 0 0 */
436	printk(KERN_DEBUG "in hpux_sysfs\n");
437	printk(KERN_DEBUG "hpux_sysfs called with opcode = %d\n", opcode);
438	printk(KERN_DEBUG "hpux_sysfs called with arg1='%lx'\n", arg1);
439
440	if ( opcode == 1 ) { /* GETFSIND */	
441		char __user *user_fsname = (char __user *)arg1;
442		len = strlen_user(user_fsname);
443		printk(KERN_DEBUG "len of arg1 = %d\n", len);
444		if (len == 0)
445			return 0;
446		fsname = kmalloc(len, GFP_KERNEL);
447		if (!fsname) {
448			printk(KERN_DEBUG "failed to kmalloc fsname\n");
449			return 0;
450		}
451
452		if (copy_from_user(fsname, user_fsname, len)) {
453			printk(KERN_DEBUG "failed to copy_from_user fsname\n");
454			kfree(fsname);
455			return 0;
456		}
457
458		/* String could be altered by userspace after strlen_user() */
459		fsname[len] = '\0';
460
461		printk(KERN_DEBUG "that is '%s' as (char *)\n", fsname);
462		if ( !strcmp(fsname, "hfs") ) {
463			fstype = 0;
464		} else {
465			fstype = 0;
466		}
467
468		kfree(fsname);
469
470		printk(KERN_DEBUG "returning fstype=%d\n", fstype);
471		return fstype; /* something other than default */
472	}
473
474
475	return 0;
476}
477
478
479/* Table of syscall names and handle for unimplemented routines */
480static const char * const syscall_names[] = {
481	"nosys",                  /* 0 */
482	"exit",                  
483	"fork",                  
484	"read",                  
485	"write",                 
486	"open",                   /* 5 */
487	"close",                 
488	"wait",                  
489	"creat",                 
490	"link",                  
491	"unlink",                 /* 10 */
492	"execv",                 
493	"chdir",                 
494	"time",                  
495	"mknod",                 
496	"chmod",                  /* 15 */
497	"chown",                 
498	"brk",                   
499	"lchmod",                
500	"lseek",                 
501	"getpid",                 /* 20 */
502	"mount",                 
503	"umount",                
504	"setuid",                
505	"getuid",                
506	"stime",                  /* 25 */
507	"ptrace",                
508	"alarm",                 
509	NULL,                    
510	"pause",                 
511	"utime",                  /* 30 */
512	"stty",                  
513	"gtty",                  
514	"access",                
515	"nice",                  
516	"ftime",                  /* 35 */
517	"sync",                  
518	"kill",                  
519	"stat",                  
520	"setpgrp3",              
521	"lstat",                  /* 40 */
522	"dup",                   
523	"pipe",                  
524	"times",                 
525	"profil",                
526	"ki_call",                /* 45 */
527	"setgid",                
528	"getgid",                
529	NULL,                    
530	NULL,                    
531	NULL,                     /* 50 */
532	"acct",                  
533	"set_userthreadid",      
534	NULL,                    
535	"ioctl",                 
536	"reboot",                 /* 55 */
537	"symlink",               
538	"utssys",                
539	"readlink",              
540	"execve",                
541	"umask",                  /* 60 */
542	"chroot",                
543	"fcntl",                 
544	"ulimit",                
545	NULL,                    
546	NULL,                     /* 65 */
547	"vfork",                 
548	NULL,                    
549	NULL,                    
550	NULL,                    
551	NULL,                     /* 70 */
552	"mmap",                  
553	NULL,                    
554	"munmap",                
555	"mprotect",              
556	"madvise",                /* 75 */
557	"vhangup",               
558	"swapoff",               
559	NULL,                    
560	"getgroups",             
561	"setgroups",              /* 80 */
562	"getpgrp2",              
563	"setpgid/setpgrp2",      
564	"setitimer",             
565	"wait3",                 
566	"swapon",                 /* 85 */
567	"getitimer",             
568	NULL,                    
569	NULL,                    
570	NULL,                    
571	"dup2",                   /* 90 */
572	NULL,                    
573	"fstat",                 
574	"select",                
575	NULL,                    
576	"fsync",                  /* 95 */
577	"setpriority",           
578	NULL,                    
579	NULL,                    
580	NULL,                    
581	"getpriority",            /* 100 */
582	NULL,                    
583	NULL,                    
584	NULL,                    
585	NULL,                    
586	NULL,                     /* 105 */
587	NULL,                    
588	NULL,                    
589	"sigvector",             
590	"sigblock",              
591	"sigsetmask",             /* 110 */
592	"sigpause",              
593	"sigstack",              
594	NULL,                    
595	NULL,                    
596	NULL,                     /* 115 */
597	"gettimeofday",          
598	"getrusage",             
599	NULL,                    
600	NULL,                    
601	"readv",                  /* 120 */
602	"writev",                
603	"settimeofday",          
604	"fchown",                
605	"fchmod",                
606	NULL,                     /* 125 */
607	"setresuid",             
608	"setresgid",             
609	"rename",                
610	"truncate",              
611	"ftruncate",              /* 130 */
612	NULL,                    
613	"sysconf",               
614	NULL,                    
615	NULL,                    
616	NULL,                     /* 135 */
617	"mkdir",                 
618	"rmdir",                 
619	NULL,                    
620	"sigcleanup",            
621	"setcore",                /* 140 */
622	NULL,                    
623	"gethostid",             
624	"sethostid",             
625	"getrlimit",             
626	"setrlimit",              /* 145 */
627	NULL,                    
628	NULL,                    
629	"quotactl",              
630	"get_sysinfo",           
631	NULL,                     /* 150 */
632	"privgrp",               
633	"rtprio",                
634	"plock",                 
635	NULL,                    
636	"lockf",                  /* 155 */
637	"semget",                
638	NULL,                    
639	"semop",                 
640	"msgget",                
641	NULL,                     /* 160 */
642	"msgsnd",                
643	"msgrcv",                
644	"shmget",                
645	NULL,                    
646	"shmat",                  /* 165 */
647	"shmdt",                 
648	NULL,                    
649	"csp/nsp_init",          
650	"cluster",               
651	"mkrnod",                 /* 170 */
652	"test",                  
653	"unsp_open",             
654	NULL,                    
655	"getcontext",            
656	"osetcontext",            /* 175 */
657	"bigio",                 
658	"pipenode",              
659	"lsync",                 
660	"getmachineid",          
661	"cnodeid/mysite",         /* 180 */
662	"cnodes/sitels",         
663	"swapclients",           
664	"rmtprocess",            
665	"dskless_stats",         
666	"sigprocmask",            /* 185 */
667	"sigpending",            
668	"sigsuspend",            
669	"sigaction",             
670	NULL,                    
671	"nfssvc",                 /* 190 */
672	"getfh",                 
673	"getdomainname",         
674	"setdomainname",         
675	"async_daemon",          
676	"getdirentries",          /* 195 */
677	NULL,                
678	NULL,               
679	"vfsmount",              
680	NULL,                    
681	"waitpid",                /* 200 */
682	NULL,                    
683	NULL,                    
684	NULL,                    
685	NULL,                    
686	NULL,                     /* 205 */
687	NULL,                    
688	NULL,                    
689	NULL,                    
690	NULL,                    
691	NULL,                     /* 210 */
692	NULL,                    
693	NULL,                    
694	NULL,                    
695	NULL,                    
696	NULL,                     /* 215 */
697	NULL,                    
698	NULL,                    
699	NULL,                    
700	NULL,                    
701	NULL,                     /* 220 */
702	NULL,                    
703	NULL,                    
704	NULL,                    
705	"sigsetreturn",          
706	"sigsetstatemask",        /* 225 */
707	"bfactl",                
708	"cs",                    
709	"cds",                   
710	NULL,                    
711	"pathconf",               /* 230 */
712	"fpathconf",             
713	NULL,                    
714	NULL,                    
715	"nfs_fcntl",             
716	"ogetacl",                /* 235 */
717	"ofgetacl",              
718	"osetacl",               
719	"ofsetacl",              
720	"pstat",                 
721	"getaudid",               /* 240 */
722	"setaudid",              
723	"getaudproc",            
724	"setaudproc",            
725	"getevent",              
726	"setevent",               /* 245 */
727	"audwrite",              
728	"audswitch",             
729	"audctl",                
730	"ogetaccess",            
731	"fsctl",                  /* 250 */
732	"ulconnect",             
733	"ulcontrol",             
734	"ulcreate",              
735	"uldest",                
736	"ulrecv",                 /* 255 */
737	"ulrecvcn",              
738	"ulsend",                
739	"ulshutdown",            
740	"swapfs",                
741	"fss",                    /* 260 */
742	NULL,                    
743	NULL,                    
744	NULL,                    
745	NULL,                    
746	NULL,                     /* 265 */
747	NULL,                    
748	"tsync",                 
749	"getnumfds",             
750	"poll",                  
751	"getmsg",                 /* 270 */
752	"putmsg",                
753	"fchdir",                
754	"getmount_cnt",          
755	"getmount_entry",        
756	"accept",                 /* 275 */
757	"bind",                  
758	"connect",               
759	"getpeername",           
760	"getsockname",           
761	"getsockopt",             /* 280 */
762	"listen",                
763	"recv",                  
764	"recvfrom",              
765	"recvmsg",               
766	"send",                   /* 285 */
767	"sendmsg",               
768	"sendto",                
769	"setsockopt",            
770	"shutdown",              
771	"socket",                 /* 290 */
772	"socketpair",            
773	"proc_open",             
774	"proc_close",            
775	"proc_send",             
776	"proc_recv",              /* 295 */
777	"proc_sendrecv",         
778	"proc_syscall",          
779	"ipccreate",             
780	"ipcname",               
781	"ipcnamerase",            /* 300 */
782	"ipclookup",             
783	"ipcselect",             
784	"ipcconnect",            
785	"ipcrecvcn",             
786	"ipcsend",                /* 305 */
787	"ipcrecv",               
788	"ipcgetnodename",        
789	"ipcsetnodename",        
790	"ipccontrol",            
791	"ipcshutdown",            /* 310 */
792	"ipcdest",               
793	"semctl",                
794	"msgctl",                
795	"shmctl",                
796	"mpctl",                  /* 315 */
797	"exportfs",              
798	"getpmsg",               
799	"putpmsg",               
800	"strioctl",              
801	"msync",                  /* 320 */
802	"msleep",                
803	"mwakeup",               
804	"msem_init",             
805	"msem_remove",           
806	"adjtime",                /* 325 */
807	"kload",                 
808	"fattach",               
809	"fdetach",               
810	"serialize",             
811	"statvfs",                /* 330 */
812	"fstatvfs",              
813	"lchown",                
814	"getsid",                
815	"sysfs",                 
816	NULL,                     /* 335 */
817	NULL,                    
818	"sched_setparam",        
819	"sched_getparam",        
820	"sched_setscheduler",    
821	"sched_getscheduler",     /* 340 */
822	"sched_yield",           
823	"sched_get_priority_max",
824	"sched_get_priority_min",
825	"sched_rr_get_interval", 
826	"clock_settime",          /* 345 */
827	"clock_gettime",         
828	"clock_getres",          
829	"timer_create",          
830	"timer_delete",          
831	"timer_settime",          /* 350 */
832	"timer_gettime",         
833	"timer_getoverrun",      
834	"nanosleep",             
835	"toolbox",               
836	NULL,                     /* 355 */
837	"getdents",              
838	"getcontext",            
839	"sysinfo",               
840	"fcntl64",               
841	"ftruncate64",            /* 360 */
842	"fstat64",               
843	"getdirentries64",       
844	"getrlimit64",           
845	"lockf64",               
846	"lseek64",                /* 365 */
847	"lstat64",               
848	"mmap64",                
849	"setrlimit64",           
850	"stat64",                
851	"truncate64",             /* 370 */
852	"ulimit64",              
853	NULL,                    
854	NULL,                    
855	NULL,                    
856	NULL,                     /* 375 */
857	NULL,                    
858	NULL,                    
859	NULL,                    
860	NULL,                    
861	"setcontext",             /* 380 */
862	"sigaltstack",           
863	"waitid",                
864	"setpgrp",               
865	"recvmsg2",              
866	"sendmsg2",               /* 385 */
867	"socket2",               
868	"socketpair2",           
869	"setregid",              
870	"lwp_create",            
871	"lwp_terminate",          /* 390 */
872	"lwp_wait",              
873	"lwp_suspend",           
874	"lwp_resume",            
875	"lwp_self",              
876	"lwp_abort_syscall",      /* 395 */
877	"lwp_info",              
878	"lwp_kill",              
879	"ksleep",                
880	"kwakeup",               
881	"ksleep_abort",           /* 400 */
882	"lwp_proc_info",         
883	"lwp_exit",              
884	"lwp_continue",          
885	"getacl",                
886	"fgetacl",                /* 405 */
887	"setacl",                
888	"fsetacl",               
889	"getaccess",             
890	"lwp_mutex_init",        
891	"lwp_mutex_lock_sys",     /* 410 */
892	"lwp_mutex_unlock",      
893	"lwp_cond_init",         
894	"lwp_cond_signal",       
895	"lwp_cond_broadcast",    
896	"lwp_cond_wait_sys",      /* 415 */
897	"lwp_getscheduler",      
898	"lwp_setscheduler",      
899	"lwp_getprivate",        
900	"lwp_setprivate",        
901	"lwp_detach",             /* 420 */
902	"mlock",                 
903	"munlock",               
904	"mlockall",              
905	"munlockall",            
906	"shm_open",               /* 425 */
907	"shm_unlink",            
908	"sigqueue",              
909	"sigwaitinfo",           
910	"sigtimedwait",          
911	"sigwait",                /* 430 */
912	"aio_read",              
913	"aio_write",             
914	"lio_listio",            
915	"aio_error",             
916	"aio_return",             /* 435 */
917	"aio_cancel",            
918	"aio_suspend",           
919	"aio_fsync",             
920	"mq_open",               
921	"mq_unlink",              /* 440 */
922	"mq_send",               
923	"mq_receive",            
924	"mq_notify",             
925	"mq_setattr",            
926	"mq_getattr",             /* 445 */
927	"ksem_open",             
928	"ksem_unlink",           
929	"ksem_close",            
930	"ksem_destroy",          
931	"lw_sem_incr",            /* 450 */
932	"lw_sem_decr",           
933	"lw_sem_read",           
934	"mq_close",              
935};
936static const int syscall_names_max = 453;
937
938int
939hpux_unimplemented(unsigned long arg1,unsigned long arg2,unsigned long arg3,
940		   unsigned long arg4,unsigned long arg5,unsigned long arg6,
941		   unsigned long arg7,unsigned long sc_num)
942{
943	/* NOTE: sc_num trashes arg8 for the few syscalls that actually
944	 * have a valid 8th argument.
945	 */
946	const char *name = NULL;
947	if ( sc_num <= syscall_names_max && sc_num >= 0 ) {
948		name = syscall_names[sc_num];
949	}
950
951	if ( name ) {
952		printk(KERN_DEBUG "Unimplemented HP-UX syscall emulation. Syscall #%lu (%s)\n",
953		sc_num, name);
954	} else {
955		printk(KERN_DEBUG "Unimplemented unknown HP-UX syscall emulation. Syscall #%lu\n",
956		sc_num);
957	}
958	
959	printk(KERN_DEBUG "  Args: %lx %lx %lx %lx %lx %lx %lx\n",
960		arg1, arg2, arg3, arg4, arg5, arg6, arg7);
961
962	return -ENOSYS;
963}