]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - 6/sys/alpha/osf1/osf1_ioctl.c
Clone Kip's Xen on stable/6 tree so that I can work on improving FreeBSD/amd64
[FreeBSD/FreeBSD.git] / 6 / sys / alpha / osf1 / osf1_ioctl.c
1 /*      $NetBSD: osf1_ioctl.c,v 1.5 1996/10/13 00:46:53 christos Exp $  */
2 /*-
3  * Copyright (c) 1994, 1995 Carnegie-Mellon University.
4  * All rights reserved.
5  *
6  * Author: Chris G. Demetriou
7  *
8  * Permission to use, copy, modify and distribute this software and
9  * its documentation is hereby granted, provided that both the copyright
10  * notice and this permission notice appear in all copies of the
11  * software, derivative works or modified versions, and any portions
12  * thereof, and that both notices appear in supporting documentation.
13  *
14  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
16  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17  *
18  * Carnegie Mellon requests users of this software to return to
19  *
20  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
21  *  School of Computer Science
22  *  Carnegie Mellon University
23  *  Pittsburgh PA 15213-3890
24  *
25  * any improvements or extensions that they make and grant Carnegie the
26  * rights to redistribute these changes.
27  */
28 /*
29  * Additional Copyright (c) 1999 by Andrew Gallatin
30  */
31
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
34
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/fcntl.h>
38 #include <sys/filio.h>
39 #include <sys/ioctl_compat.h>
40 #include <sys/termios.h>
41 #include <sys/filedesc.h>
42 #include <sys/file.h>
43 #include <sys/proc.h>
44 #include <sys/mount.h>
45 #include <sys/sysproto.h>
46 #include <alpha/osf1/osf1_signal.h>
47 #include <alpha/osf1/osf1_proto.h>
48 #include <alpha/osf1/osf1.h>
49 #include <sys/socket.h>
50 #include <net/if.h>
51 #include <net/if_dl.h>
52 #include <net/if_types.h>
53 #include <sys/sockio.h>
54
55 #include "opt_compat.h"
56
57 /*#define       IOCTL_DEBUG*/
58
59 int osf1_ioctl_i(struct thread *td, struct ioctl_args *nuap,
60                             int cmd, int dir, int len);
61 int osf1_ioctl_t(struct thread *td, struct ioctl_args *nuap,
62                             int cmd, int dir, int len);
63 int osf1_ioctl_f(struct thread *td, struct ioctl_args *nuap,
64                             int cmd, int dir, int len);
65 int osf1_ioctl_m(struct thread *td, struct ioctl_args *nuap,
66                             int cmd, int dir, int len);
67
68 int
69 osf1_ioctl(td, uap)
70         struct thread *td;
71         struct osf1_ioctl_args *uap;
72 {
73         char *dirstr;
74         unsigned int cmd, dir, group, len, op;
75         struct ioctl_args /* {
76                 syscallarg(int) fd;
77                 syscallarg(u_long) com;
78                 syscallarg(caddr_t) data;
79         } */ a;
80
81         op = uap->com;
82         dir = op & OSF1_IOC_DIRMASK;
83         group = OSF1_IOCGROUP(op);
84         cmd = OSF1_IOCCMD(op);
85         len = OSF1_IOCPARM_LEN(op);
86
87         switch (dir) {
88         case OSF1_IOC_VOID:
89                 dir = IOC_VOID;
90                 dirstr = "none";
91                 break;
92
93         case OSF1_IOC_OUT:
94                 dir = IOC_OUT;
95                 dirstr = "out";
96                 break;
97
98         case OSF1_IOC_IN:
99                 dir = IOC_IN;
100                 dirstr = "in";
101                 break;
102
103         case OSF1_IOC_INOUT:
104                 dir = IOC_INOUT;
105                 dirstr = "in-out";
106                 break;
107
108         default:
109                 return (EINVAL);
110                 break;
111         }
112 #ifdef IOCTL_DEBUG
113                 uprintf(
114                     "OSF/1 IOCTL: group = %c, cmd = %d, len = %d, dir = %s\n",
115                     group, cmd, len, dirstr);
116 #endif
117
118         a.fd = uap->fd;
119         a.com = (unsigned long)uap->com;
120         bzero(&a.com, sizeof(long));
121         a.com = _IOC(dir, group, cmd, len);
122         a.data = uap->data;
123         switch (group) {
124         case 'i':
125                 return osf1_ioctl_i(td, &a, cmd, dir, len);
126         case 't':
127                 return osf1_ioctl_t(td, &a, cmd, dir, len);
128         case 'f':
129                 return osf1_ioctl_f(td, &a, cmd, dir, len);
130         case 'm':
131                 return osf1_ioctl_m(td, &a, cmd, dir, len);
132         case 'S':
133                 /*
134                  * XXX SVR4 Streams IOCTLs are all unimpl.
135                  */
136
137 #ifndef IOCTL_DEBUG
138                 return (0);
139 #endif          
140         default:
141                 printf(
142                     "unimplented OSF/1 IOCTL: group = %c, cmd = %d, len = %d, dir = %s\n",
143                     group, cmd, len, dirstr);
144                 return (ENOTTY);
145         }
146 }
147
148 /*
149  * Structure used to query de and qe for physical addresses.
150  */
151 struct osf1_ifdevea {
152         char   ifr_name[IFNAMSIZ];      /* if name, e.g. "en0" */
153         u_char default_pa[6];           /* default hardware address */
154         u_char current_pa[6];           /* current physical address */
155 };
156
157
158 int
159 osf1_ioctl_i(td, uap, cmd, dir, len)
160         struct thread *td;
161         struct ioctl_args /* {
162                 syscallarg(int) fd;
163                 syscallarg(u_long) com;
164                 syscallarg(caddr_t) data;
165         } */ *uap;
166         int cmd;
167         int dir;
168         int len;
169 {
170
171         switch (cmd) {
172         case 20:                        /* OSF/1 OSIOCGIFCONF */
173         case 36:                        /* OSF/1  SIOCGIFCONF */
174         case 12:                        /* OSF/1 SIOCSIFADDR */
175         case 14:                        /* OSF/1 SIOCSIFDSTADDR */
176         case 16:                        /* OSF/1 SIOCSIFFLAGS (XXX) */
177         case 17:                        /* OSF/1 SIOCGIFFLAGS (XXX) */
178         case 19:                        /* OSF/1 SIOCSIFBRDADDR */
179         case 22:                        /* OSF/1 SIOCSIFNETMASK */
180         case 23:                        /* OSF/1 SIOCGIFMETRIC */
181         case 24:                        /* OSF/1 SIOCSIFMETRIC */
182         case 25:                        /* OSF/1 SIOCDIFADDR */
183         case 33:                        /* OSF/1 SIOCGIFADDR */
184         case 34:                        /* OSF/1 SIOCGIFDSTADDR */
185         case 35:                        /* OSF/1 SIOCGIFBRDADDR */
186         case 37:                        /* OSF/1 SIOCGIFNETMASK */
187                 /* same as in FreeBSD */
188                 return ioctl(td, uap);
189                 break;
190
191         case 62:                        /* OSF/1 SIOCRPHYSADDR */
192
193         {
194                 int                     ifn, retval;
195                 struct ifnet            *ifp;
196                 struct ifaddr           *ifa;
197                 struct sockaddr_dl      *sdl;
198                 struct osf1_ifdevea     *ifd = (struct osf1_ifdevea *)uap->data;
199                 
200                 /*
201                  * Note that we don't actually respect the name in the ifreq
202                  * structure, as DU interface names are all different.
203                  */
204                 for (ifn = 0; ifn < if_index; ifn++) {
205                         ifp = ifnet_byindex(ifn + 1);
206                         /* Only look at ether interfaces, exclude alteon nics
207                          * because osf/1 doesn't know about most of them.
208                          */
209                         if (ifp->if_type == IFT_ETHER 
210                             && strcmp(ifp->if_dname, "ti") != 0) {      /* looks good */
211                                 /* walk the address list */
212                                 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
213                                         if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) /* we have an address structure */
214                                             && (sdl->sdl_family == AF_LINK)             /* it's a link address */
215                                             && (sdl->sdl_type == IFT_ETHER)) {          /* for an ethernet link */
216                                                 retval = copyout(LLADDR(sdl),
217                                                     (caddr_t)&ifd->current_pa,
218                                                     6);
219                                                 if (!retval) {
220                                                         return(copyout(
221                                                             LLADDR(sdl),
222                                                             (caddr_t)&ifd->default_pa,
223                                                             6));
224                                                 }
225                                         }
226                                 }
227                         }
228                 }
229                 return(ENOENT);         /* ??? */
230         }
231
232
233         default:
234                 printf("osf1_ioctl_i: cmd = %d\n", cmd);
235                 return (ENOTTY);
236         }
237
238
239 }
240 #ifndef _SGTTYB_
241 #define _SGTTYB_
242 struct sgttyb {
243         char    sg_ispeed;              /* input speed */
244         char    sg_ospeed;              /* output speed */
245         char    sg_erase;               /* erase character */
246         char    sg_kill;                /* kill character */
247         short   sg_flags;               /* mode flags */
248 };
249 #endif
250
251 int
252 osf1_ioctl_t(td, uap, cmd, dir, len)
253         struct thread *td;
254         struct ioctl_args /* {
255                 syscallarg(int) fd;
256                 syscallarg(u_long) com;
257                 syscallarg(caddr_t) data;
258         } */ *uap;
259         int cmd;
260         int dir;
261         int len;
262 {
263         int retval;
264
265         switch (cmd) {
266 #ifdef COMPAT_43
267         case 0:                         /* OSF/1 COMPAT_43 TIOCGETD  */
268         case 1:                         /* OSF/1 COMPAT_43 TIOCSETD  */
269         case 8:                         /* OSF/1 COMPAT_43 TIOCGETP  */
270         case 9:                         /* OSF/1 COMPAT_43 TIOCSETP  */
271         case 10:                        /* OSF/1 COMPAT_43 TIOCSETN */
272         case 17:                        /* OSF/1 TIOCSETC (XXX) */
273         case 18:                        /* OSF/1 TIOCGETC (XXX) */
274         case 116:                       /* OSF/1 TIOCSLTC */
275         case 117:                       /* OSF/1 TIOCGLTC */
276         case 124:                       /* OSF/1 TIOCLGET */            
277         case 125:                       /* OSF/1 TIOCLSET */            
278         case 126:                       /* OSF/1 TIOCLBIC */            
279         case 127:                       /* OSF/1 TIOCLBIS */            
280 #endif
281         case 19:                        /* OSF/1 TIOCGETA (XXX) */
282         case 20:                        /* OSF/1 TIOCSETA (XXX) */
283         case 21:                        /* OSF/1 TIOCSETAW (XXX) */
284         case 22:                        /* OSF/1 TIOCSETAF (XXX) */
285         case 26:                        /* OSF/1 TIOCGETD (XXX) */
286         case 27:                        /* OSF/1 TIOCSETD (XXX) */
287         case 97:                        /* OSF/1 TIOCSCTTY */
288         case 103:                       /* OSF/1 TIOCSWINSZ */
289         case 104:                       /* OSF/1 TIOCGWINSZ */
290         case 110:                       /* OSF/1 TIOCSTART */
291         case 111:                       /* OSF/1 TIOCSTOP */
292         case 118:                       /* OSF/1 TIOCGPGRP */
293         case 119:                       /* OSF/1 TIOCGPGRP */
294                 /* same as in FreeBSD */
295                 break;
296
297
298         default:
299                 printf("osf1_ioctl_t: cmd = %d\n", cmd);
300                 return (ENOTTY);
301         }
302
303         retval = ioctl(td, uap);
304 #if 0
305         if (retval)
306                 printf("osf1_ioctl_t: cmd = %d, com = 0x%lx, retval = %d\n",
307                        cmd, uap->com,retval);
308 #endif
309         return retval;
310 }
311
312 /*
313  * file locking ioctl's
314  */
315
316 int
317 osf1_ioctl_f(td, uap, cmd, dir, len)
318         struct thread *td;
319         struct ioctl_args /* {
320                 syscallarg(int) fd;
321                 syscallarg(int) com;
322                 syscallarg(caddr_t) data;
323         } */ *uap;
324         int cmd;
325         int dir;
326         int len;
327 {
328
329         switch (cmd) {
330         case 1:                         /* OSF/1 FIOCLEX (XXX) */
331         case 2:                         /* OSF/1 FIONCLEX (XXX) */
332         case 127:                       /* OSF/1 FIONREAD (XXX) */
333         case 126:                       /* OSF/1 FIONREAD (XXX) */
334         case 125:                       /* OSF/1 FIOASYNC (XXX) */
335         case 124:                       /* OSF/1 FIOSETOWN (XXX) */
336         case 123:                       /* OSF/1 FIOGETOWN (XXX) */
337                 /* same as in FreeBSD */
338                 break;
339                 
340         default:
341                 printf("osf1_ioctl_f: cmd = %d\n", cmd);
342                 return (ENOTTY);
343         }
344
345         return ioctl(td, uap);
346 }
347
348 /*
349  * mag tape ioctl's
350  */
351
352 int
353 osf1_ioctl_m(td, uap, cmd, dir, len)
354         struct thread *td;
355         struct ioctl_args /* {
356                 syscallarg(int) fd;
357                 syscallarg(int) com;
358                 syscallarg(caddr_t) data;
359         } */ *uap;
360         int cmd;
361         int dir;
362         int len;
363 {
364
365         switch (cmd) {
366         case 1:                         /* OSF/1 MTIOCTOP (XXX) */
367         case 2:                         /* OSF/1 MTIOCGET (XXX) */
368                 /* same as in FreeBSD */
369                 break;
370                 
371         default:
372                 printf("osf1_ioctl_m: cmd = %d\n", cmd);
373                 return (ENOTTY);
374         }
375
376         return ioctl(td, uap);
377 }