Home | History | Annotate | Line # | Download | only in netbsd32
netbsd32_ioctl.c revision 1.8.2.1
      1 /*	$NetBSD: netbsd32_ioctl.c,v 1.8.2.1 2001/06/21 20:00:02 nathanw Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1998 Matthew R. Green
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. The name of the author may not be used to endorse or promote products
     16  *    derived from this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     23  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     25  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     26  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     28  * SUCH DAMAGE.
     29  */
     30 
     31 /*
     32  * handle ioctl conversions from netbsd32 -> sparc64
     33  */
     34 
     35 #include <sys/param.h>
     36 #include <sys/systm.h>
     37 #include <sys/filedesc.h>
     38 #include <sys/ioctl.h>
     39 #include <sys/file.h>
     40 #include <sys/proc.h>
     41 #include <sys/socketvar.h>
     42 #include <sys/audioio.h>
     43 #include <sys/disklabel.h>
     44 #include <sys/dkio.h>
     45 #include <sys/malloc.h>
     46 #include <sys/proc.h>
     47 #include <sys/sockio.h>
     48 #include <sys/socket.h>
     49 #include <sys/ttycom.h>
     50 #include <sys/mount.h>
     51 #include <sys/syscallargs.h>
     52 
     53 #ifdef __sparc__
     54 #include <machine/fbio.h>
     55 #include <machine/openpromio.h>
     56 #endif
     57 
     58 #include <net/if.h>
     59 #include <net/route.h>
     60 
     61 #include <netinet/in.h>
     62 #include <netinet/in_var.h>
     63 #include <netinet/igmp.h>
     64 #include <netinet/igmp_var.h>
     65 #include <netinet/ip_mroute.h>
     66 
     67 #include <compat/netbsd32/netbsd32.h>
     68 #include <compat/netbsd32/netbsd32_ioctl.h>
     69 #include <compat/netbsd32/netbsd32_syscallargs.h>
     70 
     71 /* prototypes for the converters */
     72 #ifdef __sparc__
     73 static __inline void
     74 netbsd32_to_fbcmap(struct netbsd32_fbcmap *, struct fbcmap *, u_long);
     75 static __inline void
     76 netbsd32_to_fbcursor(struct netbsd32_fbcursor *, struct fbcursor *, u_long);
     77 static __inline void
     78 netbsd32_to_opiocdesc(struct netbsd32_opiocdesc *, struct opiocdesc *, u_long);
     79 #endif
     80 static __inline void
     81 netbsd32_to_partinfo(struct netbsd32_partinfo *, struct partinfo *, u_long);
     82 static __inline void
     83 netbsd32_to_format_op(struct netbsd32_format_op *, struct format_op *, u_long);
     84 static __inline void
     85 netbsd32_to_ifconf(struct netbsd32_ifconf *, struct ifconf *, u_long);
     86 static __inline void
     87 netbsd32_to_ifmediareq(struct netbsd32_ifmediareq *, struct ifmediareq *, u_long);
     88 static __inline void
     89 netbsd32_to_ifdrv(struct netbsd32_ifdrv *, struct ifdrv *, u_long);
     90 static __inline void
     91 netbsd32_to_sioc_vif_req(struct netbsd32_sioc_vif_req *, struct sioc_vif_req *, u_long);
     92 static __inline void
     93 netbsd32_to_sioc_sg_req(struct netbsd32_sioc_sg_req *, struct sioc_sg_req *, u_long);
     94 
     95 #ifdef __sparc__
     96 static __inline void
     97 netbsd32_from_fbcmap(struct fbcmap *, struct netbsd32_fbcmap *);
     98 static __inline void
     99 netbsd32_from_fbcursor(struct fbcursor *, struct netbsd32_fbcursor *);
    100 static __inline void
    101 netbsd32_from_opiocdesc(struct opiocdesc *, struct netbsd32_opiocdesc *);
    102 #endif
    103 static __inline void
    104 netbsd32_from_partinfo(struct partinfo *, struct netbsd32_partinfo *);
    105 static __inline void
    106 netbsd32_from_format_op(struct format_op *, struct netbsd32_format_op *);
    107 static __inline void
    108 netbsd32_from_ifconf(struct ifconf *, struct netbsd32_ifconf *);
    109 static __inline void
    110 netbsd32_from_ifmediareq(struct ifmediareq *, struct netbsd32_ifmediareq *);
    111 static __inline void
    112 netbsd32_from_ifdrv(struct ifdrv *, struct netbsd32_ifdrv *);
    113 static __inline void
    114 netbsd32_from_sioc_vif_req(struct sioc_vif_req *, struct netbsd32_sioc_vif_req *);
    115 static __inline void
    116 netbsd32_from_sioc_sg_req(struct sioc_sg_req *, struct netbsd32_sioc_sg_req *);
    117 
    118 /* convert to/from different structures */
    119 
    120 #ifdef __sparc__
    121 
    122 static __inline void
    123 netbsd32_to_fbcmap(s32p, p, cmd)
    124 	struct netbsd32_fbcmap *s32p;
    125 	struct fbcmap *p;
    126 	u_long cmd;
    127 {
    128 
    129 	p->index = s32p->index;
    130 	p->count = s32p->count;
    131 	p->red = (u_char *)(u_long)s32p->red;
    132 	p->green = (u_char *)(u_long)s32p->green;
    133 	p->blue = (u_char *)(u_long)s32p->blue;
    134 }
    135 
    136 static __inline void
    137 netbsd32_to_fbcursor(s32p, p, cmd)
    138 	struct netbsd32_fbcursor *s32p;
    139 	struct fbcursor *p;
    140 	u_long cmd;
    141 {
    142 
    143 	p->set = s32p->set;
    144 	p->enable = s32p->enable;
    145 	p->pos = s32p->pos;
    146 	p->hot = s32p->hot;
    147 	netbsd32_to_fbcmap(&s32p->cmap, &p->cmap, cmd);
    148 	p->size = s32p->size;
    149 	p->image = (char *)(u_long)s32p->image;
    150 	p->mask = (char *)(u_long)s32p->mask;
    151 }
    152 
    153 static __inline void
    154 netbsd32_to_opiocdesc(s32p, p, cmd)
    155 	struct netbsd32_opiocdesc *s32p;
    156 	struct opiocdesc *p;
    157 	u_long cmd;
    158 {
    159 
    160 	p->op_nodeid = s32p->op_nodeid;
    161 	p->op_namelen = s32p->op_namelen;
    162 	p->op_name = (char *)(u_long)s32p->op_name;
    163 	p->op_buflen = s32p->op_buflen;
    164 	p->op_buf = (char *)(u_long)s32p->op_buf;
    165 }
    166 #endif
    167 
    168 static __inline void
    169 netbsd32_to_partinfo(s32p, p, cmd)
    170 	struct netbsd32_partinfo *s32p;
    171 	struct partinfo *p;
    172 	u_long cmd;
    173 {
    174 
    175 	p->disklab = (struct disklabel *)(u_long)s32p->disklab;
    176 	p->part = (struct partition *)(u_long)s32p->part;
    177 }
    178 
    179 static __inline void
    180 netbsd32_to_format_op(s32p, p, cmd)
    181 	struct netbsd32_format_op *s32p;
    182 	struct format_op *p;
    183 	u_long cmd;
    184 {
    185 
    186 	p->df_buf = (char *)(u_long)s32p->df_buf;
    187 	p->df_count = s32p->df_count;
    188 	p->df_startblk = s32p->df_startblk;
    189 	memcpy(p->df_reg, s32p->df_reg, sizeof(s32p->df_reg));
    190 }
    191 
    192 #if 0 /* XXX see below */
    193 static __inline void
    194 netbsd32_to_ifreq(s32p, p, cmd)
    195 	struct netbsd32_ifreq *s32p;
    196 	struct ifreq *p;
    197 	u_long cmd;	/* XXX unused yet */
    198 {
    199 
    200 	/*
    201 	 * XXX
    202 	 * struct ifreq says the same, but sometimes the ifr_data
    203 	 * union member needs to be converted to 64 bits... this
    204 	 * is very driver specific and so we ignore it for now..
    205 	 */
    206 	memcpy(p, s32p, sizeof *s32p);
    207 }
    208 #endif
    209 
    210 static __inline void
    211 netbsd32_to_ifconf(s32p, p, cmd)
    212 	struct netbsd32_ifconf *s32p;
    213 	struct ifconf *p;
    214 	u_long cmd;
    215 {
    216 
    217 	p->ifc_len = s32p->ifc_len;
    218 	/* ifc_buf & ifc_req are the same size so this works */
    219 	p->ifc_buf = (caddr_t)(u_long)s32p->ifc_buf;
    220 }
    221 
    222 static __inline void
    223 netbsd32_to_ifmediareq(s32p, p, cmd)
    224 	struct netbsd32_ifmediareq *s32p;
    225 	struct ifmediareq *p;
    226 	u_long cmd;
    227 {
    228 
    229 	memcpy(p, s32p, sizeof *s32p);
    230 	p->ifm_ulist = (int *)(u_long)s32p->ifm_ulist;
    231 }
    232 
    233 static __inline void
    234 netbsd32_to_ifdrv(s32p, p, cmd)
    235 	struct netbsd32_ifdrv *s32p;
    236 	struct ifdrv *p;
    237 	u_long cmd;
    238 {
    239 
    240 	memcpy(p, s32p, sizeof *s32p);
    241 	p->ifd_data = (void *)(u_long)s32p->ifd_data;
    242 }
    243 
    244 static __inline void
    245 netbsd32_to_sioc_vif_req(s32p, p, cmd)
    246 	struct netbsd32_sioc_vif_req *s32p;
    247 	struct sioc_vif_req *p;
    248 	u_long cmd;
    249 {
    250 
    251 	p->vifi = s32p->vifi;
    252 	p->icount = (u_long)s32p->icount;
    253 	p->ocount = (u_long)s32p->ocount;
    254 	p->ibytes = (u_long)s32p->ibytes;
    255 	p->obytes = (u_long)s32p->obytes;
    256 }
    257 
    258 static __inline void
    259 netbsd32_to_sioc_sg_req(s32p, p, cmd)
    260 	struct netbsd32_sioc_sg_req *s32p;
    261 	struct sioc_sg_req *p;
    262 	u_long cmd;
    263 {
    264 
    265 	p->src = s32p->src;
    266 	p->grp = s32p->grp;
    267 	p->pktcnt = (u_long)s32p->pktcnt;
    268 	p->bytecnt = (u_long)s32p->bytecnt;
    269 	p->wrong_if = (u_long)s32p->wrong_if;
    270 }
    271 
    272 /*
    273  * handle ioctl conversions from sparc64 -> netbsd32
    274  */
    275 
    276 #ifdef __sparc__
    277 
    278 static __inline void
    279 netbsd32_from_fbcmap(p, s32p)
    280 	struct fbcmap *p;
    281 	struct netbsd32_fbcmap *s32p;
    282 {
    283 
    284 	s32p->index = p->index;
    285 	s32p->count = p->count;
    286 /* filled in */
    287 #if 0
    288 	s32p->red = (netbsd32_u_charp)p->red;
    289 	s32p->green = (netbsd32_u_charp)p->green;
    290 	s32p->blue = (netbsd32_u_charp)p->blue;
    291 #endif
    292 }
    293 
    294 static __inline void
    295 netbsd32_from_fbcursor(p, s32p)
    296 	struct fbcursor *p;
    297 	struct netbsd32_fbcursor *s32p;
    298 {
    299 
    300 	s32p->set = p->set;
    301 	s32p->enable = p->enable;
    302 	s32p->pos = p->pos;
    303 	s32p->hot = p->hot;
    304 	netbsd32_from_fbcmap(&p->cmap, &s32p->cmap);
    305 	s32p->size = p->size;
    306 /* filled in */
    307 #if 0
    308 	s32p->image = (netbsd32_charp)p->image;
    309 	s32p->mask = (netbsd32_charp)p->mask;
    310 #endif
    311 }
    312 
    313 static __inline void
    314 netbsd32_from_opiocdesc(p, s32p)
    315 	struct opiocdesc *p;
    316 	struct netbsd32_opiocdesc *s32p;
    317 {
    318 
    319 	s32p->op_nodeid = p->op_nodeid;
    320 	s32p->op_namelen = p->op_namelen;
    321 	s32p->op_name = (netbsd32_charp)(u_long)p->op_name;
    322 	s32p->op_buflen = p->op_buflen;
    323 	s32p->op_buf = (netbsd32_charp)(u_long)p->op_buf;
    324 }
    325 
    326 #endif
    327 
    328 static __inline void
    329 netbsd32_from_partinfo(p, s32p)
    330 	struct partinfo *p;
    331 	struct netbsd32_partinfo *s32p;
    332 {
    333 
    334 	s32p->disklab = (netbsd32_disklabel_tp_t)(u_long)p->disklab;
    335 	s32p->part = s32p->part;
    336 }
    337 
    338 static __inline void
    339 netbsd32_from_format_op(p, s32p)
    340 	struct format_op *p;
    341 	struct netbsd32_format_op *s32p;
    342 {
    343 
    344 /* filled in */
    345 #if 0
    346 	s32p->df_buf = (netbsd32_charp)p->df_buf;
    347 #endif
    348 	s32p->df_count = p->df_count;
    349 	s32p->df_startblk = p->df_startblk;
    350 	memcpy(s32p->df_reg, p->df_reg, sizeof(p->df_reg));
    351 }
    352 
    353 #if 0 /* XXX see below */
    354 static __inline void
    355 netbsd32_from_ifreq(p, s32p, cmd)
    356 	struct ifreq *p;
    357 	struct netbsd32_ifreq *s32p;
    358 	u_long cmd;	/* XXX unused yet */
    359 {
    360 
    361 	/*
    362 	 * XXX
    363 	 * struct ifreq says the same, but sometimes the ifr_data
    364 	 * union member needs to be converted to 64 bits... this
    365 	 * is very driver specific and so we ignore it for now..
    366 	 */
    367 	*s32p = *p;
    368 }
    369 #endif
    370 
    371 static __inline void
    372 netbsd32_from_ifconf(p, s32p)
    373 	struct ifconf *p;
    374 	struct netbsd32_ifconf *s32p;
    375 {
    376 
    377 	s32p->ifc_len = p->ifc_len;
    378 	/* ifc_buf & ifc_req are the same size so this works */
    379 	s32p->ifc_buf = (netbsd32_caddr_t)(u_long)p->ifc_buf;
    380 }
    381 
    382 static __inline void
    383 netbsd32_from_ifmediareq(p, s32p)
    384 	struct ifmediareq *p;
    385 	struct netbsd32_ifmediareq *s32p;
    386 {
    387 
    388 	memcpy(s32p, p, sizeof *p);
    389 /* filled in? */
    390 #if 0
    391 	s32p->ifm_ulist = (netbsd32_intp_t)p->ifm_ulist;
    392 #endif
    393 }
    394 
    395 static __inline void
    396 netbsd32_from_ifdrv(p, s32p)
    397 	struct ifdrv *p;
    398 	struct netbsd32_ifdrv *s32p;
    399 {
    400 
    401 	memcpy(s32p, p, sizeof *p);
    402 /* filled in? */
    403 #if 0
    404 	s32p->ifm_data = (netbsd32_u_longp_t)p->ifm_data;
    405 #endif
    406 }
    407 
    408 static __inline void
    409 netbsd32_from_sioc_vif_req(p, s32p)
    410 	struct sioc_vif_req *p;
    411 	struct netbsd32_sioc_vif_req *s32p;
    412 {
    413 
    414 	s32p->vifi = p->vifi;
    415 	s32p->icount = (netbsd32_u_long)p->icount;
    416 	s32p->ocount = (netbsd32_u_long)p->ocount;
    417 	s32p->ibytes = (netbsd32_u_long)p->ibytes;
    418 	s32p->obytes = (netbsd32_u_long)p->obytes;
    419 }
    420 
    421 static __inline void
    422 netbsd32_from_sioc_sg_req(p, s32p)
    423 	struct sioc_sg_req *p;
    424 	struct netbsd32_sioc_sg_req *s32p;
    425 {
    426 
    427 	s32p->src = p->src;
    428 	s32p->grp = p->grp;
    429 	s32p->pktcnt = (netbsd32_u_long)p->pktcnt;
    430 	s32p->bytecnt = (netbsd32_u_long)p->bytecnt;
    431 	s32p->wrong_if = (netbsd32_u_long)p->wrong_if;
    432 }
    433 
    434 
    435 /*
    436  * main ioctl syscall.
    437  *
    438  * ok, here we are in the biggy.  we have to do fix ups depending
    439  * on the ioctl command before and afterwards.
    440  */
    441 int
    442 netbsd32_ioctl(p, v, retval)
    443 	struct proc *p;
    444 	void *v;
    445 	register_t *retval;
    446 {
    447 	struct netbsd32_ioctl_args /* {
    448 		syscallarg(int) fd;
    449 		syscallarg(netbsd32_u_long) com;
    450 		syscallarg(netbsd32_voidp) data;
    451 	} */ *uap = v;
    452 	struct file *fp;
    453 	struct filedesc *fdp;
    454 	u_long com;
    455 	int error = 0;
    456 	u_int size, size32;
    457 	caddr_t data, memp = NULL;
    458 	caddr_t data32, memp32 = NULL;
    459 	int tmp;
    460 #define STK_PARAMS	128
    461 	u_long stkbuf[STK_PARAMS/sizeof(u_long)];
    462 	u_long stkbuf32[STK_PARAMS/sizeof(u_long)];
    463 
    464 	/*
    465 	 * we need to translate some commands (_IOW) before calling sys_ioctl,
    466 	 * some after (_IOR), and some both (_IOWR).
    467 	 */
    468 #if 0
    469 	{
    470 char *dirs[8] = { "NONE!", "VOID", "OUT", "VOID|OUT!", "IN", "VOID|IN!",
    471 		"INOUT", "VOID|IN|OUT!" };
    472 
    473 printf("netbsd32_ioctl(%d, %x, %x): %s group %c base %d len %d\n",
    474        SCARG(uap, fd), SCARG(uap, com), SCARG(uap, data),
    475        dirs[((SCARG(uap, com) & IOC_DIRMASK)>>29)],
    476        IOCGROUP(SCARG(uap, com)), IOCBASECMD(SCARG(uap, com)),
    477        IOCPARM_LEN(SCARG(uap, com)));
    478 	}
    479 #endif
    480 
    481 	fdp = p->p_fd;
    482 	if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
    483 		return (EBADF);
    484 
    485 	FILE_USE(fp);
    486 
    487 	if ((fp->f_flag & (FREAD | FWRITE)) == 0) {
    488 		error = EBADF;
    489 		goto out;
    490 	}
    491 
    492 	switch (com = SCARG(uap, com)) {
    493 	case FIONCLEX:
    494 		fdp->fd_ofileflags[SCARG(uap, fd)] &= ~UF_EXCLOSE;
    495 		goto out;
    496 
    497 	case FIOCLEX:
    498 		fdp->fd_ofileflags[SCARG(uap, fd)] |= UF_EXCLOSE;
    499 		goto out;
    500 	}
    501 
    502 	/*
    503 	 * Interpret high order word to find amount of data to be
    504 	 * copied to/from the user's address space.
    505 	 */
    506 	size32 = IOCPARM_LEN(com);
    507 	if (size32 > IOCPARM_MAX) {
    508 		error = ENOTTY;
    509 		goto out;
    510 	}
    511 	memp = NULL;
    512 	if (size32 > sizeof(stkbuf)) {
    513 		memp32 = (caddr_t)malloc((u_long)size32, M_IOCTLOPS, M_WAITOK);
    514 		data32 = memp32;
    515 	} else
    516 		data32 = (caddr_t)stkbuf32;
    517 	if (com&IOC_IN) {
    518 		if (size32) {
    519 			error = copyin((caddr_t)(u_long)SCARG(uap, data),
    520 				       data32, size32);
    521 			if (error) {
    522 				if (memp32)
    523 					free(memp32, M_IOCTLOPS);
    524 				goto out;
    525 			}
    526 		} else
    527 			*(caddr_t *)data32 = (caddr_t)(u_long)SCARG(uap, data);
    528 	} else if ((com&IOC_OUT) && size32)
    529 		/*
    530 		 * Zero the buffer so the user always
    531 		 * gets back something deterministic.
    532 		 */
    533 		memset(data32, 0, size32);
    534 	else if (com&IOC_VOID)
    535 		*(caddr_t *)data32 = (caddr_t)(u_long)SCARG(uap, data);
    536 
    537 /* we define some handy macros here... */
    538 #define IOCTL_STRUCT_CONV_TO(cmd, type)	\
    539 		com = cmd; \
    540 		size = IOCPARM_LEN(com); \
    541 		if (size > sizeof(stkbuf)) \
    542 			data = memp = malloc(size, M_IOCTLOPS, M_WAITOK); \
    543 		else \
    544 			data = (caddr_t)stkbuf; \
    545 		__CONCAT(netbsd32_to_, type)((struct __CONCAT(netbsd32_, type) *) \
    546 			data32, (struct type *)data, com); \
    547 		error = (*fp->f_ops->fo_ioctl)(fp, com, data, p); \
    548 		__CONCAT(netbsd32_from_, type)((struct type *)data, \
    549 			(struct __CONCAT(netbsd32_, type) *)data32); \
    550 		break
    551 
    552 	/*
    553 	 * convert various structures, pointers, and other objects that
    554 	 * change size from 32 bit -> 64 bit, for all ioctl commands.
    555 	 */
    556 	switch (SCARG(uap, com)) {
    557 	case FIONBIO:
    558 		if ((tmp = *(int *)data32) != 0)
    559 			fp->f_flag |= FNONBLOCK;
    560 		else
    561 			fp->f_flag &= ~FNONBLOCK;
    562 		error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p);
    563 		break;
    564 
    565 	case FIOASYNC:
    566 		if ((tmp = *(int *)data32) != 0)
    567 			fp->f_flag |= FASYNC;
    568 		else
    569 			fp->f_flag &= ~FASYNC;
    570 		error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (caddr_t)&tmp, p);
    571 		break;
    572 
    573 	case FIOSETOWN:
    574 		tmp = *(int *)data32;
    575 		if (fp->f_type == DTYPE_SOCKET) {
    576 			((struct socket *)fp->f_data)->so_pgid = tmp;
    577 			error = 0;
    578 			break;
    579 		}
    580 		if (tmp <= 0) {
    581 			tmp = -tmp;
    582 		} else {
    583 			struct proc *p1 = pfind(tmp);
    584 			if (p1 == 0) {
    585 				error = ESRCH;
    586 				break;
    587 			}
    588 			tmp = p1->p_pgrp->pg_id;
    589 		}
    590 		error = (*fp->f_ops->fo_ioctl)
    591 			(fp, TIOCSPGRP, (caddr_t)&tmp, p);
    592 		break;
    593 
    594 	case FIOGETOWN:
    595 		if (fp->f_type == DTYPE_SOCKET) {
    596 			error = 0;
    597 			*(int *)data32 = ((struct socket *)fp->f_data)->so_pgid;
    598 			break;
    599 		}
    600 		error = (*fp->f_ops->fo_ioctl)(fp, TIOCGPGRP, data32, p);
    601 		*(int *)data32 = -*(int *)data32;
    602 		break;
    603 
    604 #ifdef __sparc__
    605 /*
    606  * Here are calls that need explicit conversion.
    607  */
    608 	case FBIOPUTCMAP32:
    609 		IOCTL_STRUCT_CONV_TO(FBIOPUTCMAP, fbcmap);
    610 	case FBIOGETCMAP32:
    611 		IOCTL_STRUCT_CONV_TO(FBIOGETCMAP, fbcmap);
    612 
    613 	case FBIOSCURSOR32:
    614 		IOCTL_STRUCT_CONV_TO(FBIOSCURSOR, fbcursor);
    615 	case FBIOGCURSOR32:
    616 		IOCTL_STRUCT_CONV_TO(FBIOGCURSOR, fbcursor);
    617 
    618 	case OPIOCGET32:
    619 		IOCTL_STRUCT_CONV_TO(OPIOCGET, opiocdesc);
    620 	case OPIOCSET32:
    621 		IOCTL_STRUCT_CONV_TO(OPIOCSET, opiocdesc);
    622 	case OPIOCNEXTPROP32:
    623 		IOCTL_STRUCT_CONV_TO(OPIOCNEXTPROP, opiocdesc);
    624 #endif
    625 
    626 	case DIOCGPART32:
    627 		IOCTL_STRUCT_CONV_TO(DIOCGPART, partinfo);
    628 
    629 	case DIOCRFORMAT32:
    630 		IOCTL_STRUCT_CONV_TO(DIOCRFORMAT, format_op);
    631 	case DIOCWFORMAT32:
    632 		IOCTL_STRUCT_CONV_TO(DIOCWFORMAT, format_op);
    633 
    634 /*
    635  * only a few ifreq syscalls need conversion and those are
    636  * all driver specific... XXX
    637  */
    638 #if 0
    639 	case SIOCGADDRROM3232:
    640 		IOCTL_STRUCT_CONV_TO(SIOCGADDRROM32, ifreq);
    641 	case SIOCGCHIPID32:
    642 		IOCTL_STRUCT_CONV_TO(SIOCGCHIPID, ifreq);
    643 	case SIOCSIFADDR32:
    644 		IOCTL_STRUCT_CONV_TO(SIOCSIFADDR, ifreq);
    645 	case OSIOCGIFADDR32:
    646 		IOCTL_STRUCT_CONV_TO(OSIOCGIFADDR, ifreq);
    647 	case SIOCGIFADDR32:
    648 		IOCTL_STRUCT_CONV_TO(SIOCGIFADDR, ifreq);
    649 	case SIOCSIFDSTADDR32:
    650 		IOCTL_STRUCT_CONV_TO(SIOCSIFDSTADDR, ifreq);
    651 	case OSIOCGIFDSTADDR32:
    652 		IOCTL_STRUCT_CONV_TO(OSIOCGIFDSTADDR, ifreq);
    653 	case SIOCGIFDSTADDR32:
    654 		IOCTL_STRUCT_CONV_TO(SIOCGIFDSTADDR, ifreq);
    655 	case SIOCSIFFLAGS32:
    656 		IOCTL_STRUCT_CONV_TO(SIOCSIFFLAGS, ifreq);
    657 	case SIOCGIFFLAGS32:
    658 		IOCTL_STRUCT_CONV_TO(SIOCGIFFLAGS, ifreq);
    659 	case OSIOCGIFBRDADDR32:
    660 		IOCTL_STRUCT_CONV_TO(OSIOCGIFBRDADDR, ifreq);
    661 	case SIOCGIFBRDADDR32:
    662 		IOCTL_STRUCT_CONV_TO(SIOCGIFBRDADDR, ifreq);
    663 	case SIOCSIFBRDADDR32:
    664 		IOCTL_STRUCT_CONV_TO(SIOCSIFBRDADDR, ifreq);
    665 	case OSIOCGIFNETMASK32:
    666 		IOCTL_STRUCT_CONV_TO(OSIOCGIFNETMASK, ifreq);
    667 	case SIOCGIFNETMASK32:
    668 		IOCTL_STRUCT_CONV_TO(SIOCGIFNETMASK, ifreq);
    669 	case SIOCSIFNETMASK32:
    670 		IOCTL_STRUCT_CONV_TO(SIOCSIFNETMASK, ifreq);
    671 	case SIOCGIFMETRIC32:
    672 		IOCTL_STRUCT_CONV_TO(SIOCGIFMETRIC, ifreq);
    673 	case SIOCSIFMETRIC32:
    674 		IOCTL_STRUCT_CONV_TO(SIOCSIFMETRIC, ifreq);
    675 	case SIOCDIFADDR32:
    676 		IOCTL_STRUCT_CONV_TO(SIOCDIFADDR, ifreq);
    677 	case SIOCADDMULTI32:
    678 		IOCTL_STRUCT_CONV_TO(SIOCADDMULTI, ifreq);
    679 	case SIOCDELMULTI32:
    680 		IOCTL_STRUCT_CONV_TO(SIOCDELMULTI, ifreq);
    681 	case SIOCSIFMEDIA32:
    682 		IOCTL_STRUCT_CONV_TO(SIOCSIFMEDIA, ifreq);
    683 	case SIOCSIFMTU32:
    684 		IOCTL_STRUCT_CONV_TO(SIOCSIFMTU, ifreq);
    685 	case SIOCGIFMTU32:
    686 		IOCTL_STRUCT_CONV_TO(SIOCGIFMTU, ifreq);
    687 	case SIOCSIFASYNCMAP32:
    688 		IOCTL_STRUCT_CONV_TO(SIOCSIFASYNCMAP, ifreq);
    689 	case SIOCGIFASYNCMAP32:
    690 		IOCTL_STRUCT_CONV_TO(SIOCGIFASYNCMAP, ifreq);
    691 /*		IOCTL_STRUCT_CONV_TO(BIOCGETIF, ifreq); READ ONLY */
    692 	case BIOCSETIF32:
    693 		IOCTL_STRUCT_CONV_TO(BIOCSETIF, ifreq);
    694 	case SIOCPHASE132:
    695 		IOCTL_STRUCT_CONV_TO(SIOCPHASE1, ifreq);
    696 	case SIOCPHASE232:
    697 		IOCTL_STRUCT_CONV_TO(SIOCPHASE2, ifreq);
    698 #endif
    699 
    700 	case OSIOCGIFCONF32:
    701 		IOCTL_STRUCT_CONV_TO(OSIOCGIFCONF, ifconf);
    702 	case SIOCGIFCONF32:
    703 		IOCTL_STRUCT_CONV_TO(SIOCGIFCONF, ifconf);
    704 
    705 	case SIOCGIFMEDIA32:
    706 		IOCTL_STRUCT_CONV_TO(SIOCGIFMEDIA, ifmediareq);
    707 
    708 	case SIOCSDRVSPEC32:
    709 		IOCTL_STRUCT_CONV_TO(SIOCSDRVSPEC, ifdrv);
    710 
    711 	case SIOCGETVIFCNT32:
    712 		IOCTL_STRUCT_CONV_TO(SIOCGETVIFCNT, sioc_vif_req);
    713 
    714 	case SIOCGETSGCNT32:
    715 		IOCTL_STRUCT_CONV_TO(SIOCGETSGCNT, sioc_sg_req);
    716 
    717 	default:
    718 		error = (*fp->f_ops->fo_ioctl)(fp, com, data32, p);
    719 		break;
    720 	}
    721 
    722 	/*
    723 	 * Copy any data to user, size was
    724 	 * already set and checked above.
    725 	 */
    726 	if (error == 0 && (com&IOC_OUT) && size32)
    727 		error = copyout(data32, (caddr_t)(u_long)SCARG(uap, data), size32);
    728 
    729 	/* if we malloced data, free it here */
    730 	if (memp32)
    731 		free(memp32, M_IOCTLOPS);
    732 	if (memp)
    733 		free(memp, M_IOCTLOPS);
    734 
    735  out:
    736 	FILE_UNUSE(fp, p);
    737 	return (error);
    738 }
    739