Path: blob/main/sys/compat/freebsd32/freebsd32_ioctl.c
39478 views
/*-1* SPDX-License-Identifier: BSD-3-Clause2*3* Copyright (c) 2008 David E. O'Brien4* All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11* 2. Redistributions in binary form must reproduce the above copyright12* notice, this list of conditions and the following disclaimer in the13* documentation and/or other materials provided with the distribution.14* 3. Neither the name of the author nor the names of its contributors15* may be used to endorse or promote products derived from this software16* without specific prior written permission.17*18* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND19* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE20* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE21* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE22* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL23* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS24* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)25* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT26* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY27* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF28* SUCH DAMAGE.29*/3031#include <sys/param.h>32#include <sys/capsicum.h>33#include <sys/cdio.h>34#include <sys/fcntl.h>35#include <sys/filio.h>36#include <sys/file.h>37#include <sys/ioccom.h>38#include <sys/malloc.h>39#include <sys/memrange.h>40#include <sys/pciio.h>41#include <sys/proc.h>42#include <sys/syscall.h>43#include <sys/syscallsubr.h>44#include <sys/sysctl.h>45#include <sys/sysproto.h>46#include <sys/systm.h>47#include <sys/uio.h>4849#include <compat/freebsd32/freebsd32.h>50#include <compat/freebsd32/freebsd32_ioctl.h>51#include <compat/freebsd32/freebsd32_misc.h>52#include <compat/freebsd32/freebsd32_proto.h>5354CTASSERT(sizeof(struct mem_range_op32) == 12);5556static int57freebsd32_ioctl_memrange(struct thread *td,58struct freebsd32_ioctl_args *uap, struct file *fp)59{60struct mem_range_op mro;61struct mem_range_op32 mro32;62int error;63u_long com;6465if ((error = copyin(uap->data, &mro32, sizeof(mro32))) != 0)66return (error);6768PTRIN_CP(mro32, mro, mo_desc);69CP(mro32, mro, mo_arg[0]);70CP(mro32, mro, mo_arg[1]);7172com = _IOC_NEWTYPE(uap->com, struct mem_range_op);7374if ((error = fo_ioctl(fp, com, (caddr_t)&mro, td->td_ucred, td)) != 0)75return (error);7677if ( (com & IOC_OUT) ) {78CP(mro, mro32, mo_arg[0]);79CP(mro, mro32, mo_arg[1]);8081error = copyout(&mro32, uap->data, sizeof(mro32));82}8384return (error);85}8687static int88freebsd32_ioctl_barmmap(struct thread *td,89struct freebsd32_ioctl_args *uap, struct file *fp)90{91struct pci_bar_mmap32 pbm32;92struct pci_bar_mmap pbm;93int error;9495error = copyin(uap->data, &pbm32, sizeof(pbm32));96if (error != 0)97return (error);98PTRIN_CP(pbm32, pbm, pbm_map_base);99CP(pbm32, pbm, pbm_sel);100CP(pbm32, pbm, pbm_reg);101CP(pbm32, pbm, pbm_flags);102CP(pbm32, pbm, pbm_memattr);103pbm.pbm_bar_length = PAIR32TO64(uint64_t, pbm32.pbm_bar_length);104error = fo_ioctl(fp, PCIOCBARMMAP, (caddr_t)&pbm, td->td_ucred, td);105if (error == 0) {106PTROUT_CP(pbm, pbm32, pbm_map_base);107CP(pbm, pbm32, pbm_map_length);108#if BYTE_ORDER == LITTLE_ENDIAN109pbm32.pbm_bar_length1 = pbm.pbm_bar_length;110pbm32.pbm_bar_length2 = pbm.pbm_bar_length >> 32;111#else112pbm32.pbm_bar_length1 = pbm.pbm_bar_length >> 32;113pbm32.pbm_bar_length2 = pbm.pbm_bar_length;114#endif115CP(pbm, pbm32, pbm_bar_off);116error = copyout(&pbm32, uap->data, sizeof(pbm32));117}118return (error);119}120121static int122freebsd32_ioctl_sg(struct thread *td,123struct freebsd32_ioctl_args *uap, struct file *fp)124{125struct sg_io_hdr io;126struct sg_io_hdr32 io32;127int error;128129if ((error = copyin(uap->data, &io32, sizeof(io32))) != 0)130return (error);131132CP(io32, io, interface_id);133CP(io32, io, dxfer_direction);134CP(io32, io, cmd_len);135CP(io32, io, mx_sb_len);136CP(io32, io, iovec_count);137CP(io32, io, dxfer_len);138PTRIN_CP(io32, io, dxferp);139PTRIN_CP(io32, io, cmdp);140PTRIN_CP(io32, io, sbp);141CP(io32, io, timeout);142CP(io32, io, flags);143CP(io32, io, pack_id);144PTRIN_CP(io32, io, usr_ptr);145CP(io32, io, status);146CP(io32, io, masked_status);147CP(io32, io, msg_status);148CP(io32, io, sb_len_wr);149CP(io32, io, host_status);150CP(io32, io, driver_status);151CP(io32, io, resid);152CP(io32, io, duration);153CP(io32, io, info);154155if ((error = fo_ioctl(fp, SG_IO, (caddr_t)&io, td->td_ucred, td)) != 0)156return (error);157158CP(io, io32, interface_id);159CP(io, io32, dxfer_direction);160CP(io, io32, cmd_len);161CP(io, io32, mx_sb_len);162CP(io, io32, iovec_count);163CP(io, io32, dxfer_len);164PTROUT_CP(io, io32, dxferp);165PTROUT_CP(io, io32, cmdp);166PTROUT_CP(io, io32, sbp);167CP(io, io32, timeout);168CP(io, io32, flags);169CP(io, io32, pack_id);170PTROUT_CP(io, io32, usr_ptr);171CP(io, io32, status);172CP(io, io32, masked_status);173CP(io, io32, msg_status);174CP(io, io32, sb_len_wr);175CP(io, io32, host_status);176CP(io, io32, driver_status);177CP(io, io32, resid);178CP(io, io32, duration);179CP(io, io32, info);180181error = copyout(&io32, uap->data, sizeof(io32));182183return (error);184}185186int187freebsd32_ioctl(struct thread *td, struct freebsd32_ioctl_args *uap)188{189struct ioctl_args ap /*{190int fd;191u_long com;192caddr_t data;193}*/ ;194struct file *fp;195cap_rights_t rights;196int error;197198error = fget(td, uap->fd, cap_rights_init_one(&rights, CAP_IOCTL), &fp);199if (error != 0)200return (error);201if ((fp->f_flag & (FREAD | FWRITE)) == 0) {202fdrop(fp, td);203return (EBADF);204}205206switch (uap->com) {207case MEMRANGE_GET32: /* FALLTHROUGH */208case MEMRANGE_SET32:209error = freebsd32_ioctl_memrange(td, uap, fp);210break;211212case SG_IO_32:213error = freebsd32_ioctl_sg(td, uap, fp);214break;215216case PCIOCBARMMAP_32:217error = freebsd32_ioctl_barmmap(td, uap, fp);218break;219220default:221fdrop(fp, td);222ap.fd = uap->fd;223ap.com = uap->com;224PTRIN_CP(*uap, ap, data);225return sys_ioctl(td, &ap);226}227228fdrop(fp, td);229return (error);230}231232233