The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/io/iodev.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2004 Mark R V Murray
    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  *    in this position and unchanged.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
   18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   27  *
   28  */
   29 
   30 #include <sys/cdefs.h>
   31 __FBSDID("$FreeBSD$");
   32 
   33 #include <sys/param.h>
   34 #include <sys/conf.h>
   35 #include <sys/kernel.h>
   36 #include <sys/ioccom.h>
   37 #include <sys/module.h>
   38 #include <sys/priv.h>
   39 #include <sys/proc.h>
   40 #include <sys/systm.h>
   41 
   42 #include <machine/iodev.h>
   43 
   44 #include <dev/io/iodev.h>
   45 
   46 static int       ioopen(struct cdev *dev, int flags, int fmt,
   47                     struct thread *td);
   48 static int       ioclose(struct cdev *dev, int flags, int fmt,
   49                     struct thread *td);
   50 static int       ioioctl(struct cdev *dev, u_long cmd, caddr_t data,
   51                     int fflag, struct thread *td);
   52 
   53 static int       iopio_read(struct iodev_pio_req *req);
   54 static int       iopio_write(struct iodev_pio_req *req);
   55 
   56 static struct cdev *iodev;
   57 
   58 static struct cdevsw io_cdevsw = {
   59         .d_version =    D_VERSION,
   60         .d_open =       ioopen,
   61         .d_close =      ioclose,
   62         .d_ioctl =      ioioctl,
   63         .d_name =       "io",
   64 };
   65 
   66 /* ARGSUSED */
   67 static int
   68 ioopen(struct cdev *dev __unused, int flags __unused, int fmt __unused,
   69     struct thread *td)
   70 {
   71         int error;
   72 
   73         error = priv_check(td, PRIV_IO);
   74         if (error != 0)
   75                 return (error);
   76         error = securelevel_gt(td->td_ucred, 0);
   77         if (error != 0)
   78                 return (error);
   79         error = iodev_open(td);
   80 
   81         return (error);
   82 }
   83 
   84 /* ARGSUSED */
   85 static int
   86 ioclose(struct cdev *dev __unused, int flags __unused, int fmt __unused,
   87     struct thread *td)
   88 {
   89 
   90         return (iodev_close(td));
   91 }
   92 
   93 /* ARGSUSED */
   94 static int
   95 ioioctl(struct cdev *dev __unused, u_long cmd, caddr_t data,
   96     int fflag __unused, struct thread *td __unused)
   97 {
   98         struct iodev_pio_req *pio_req;
   99         int error;
  100 
  101         switch (cmd) {
  102         case IODEV_PIO:
  103                 pio_req = (struct iodev_pio_req *)data;
  104                 switch (pio_req->access) {
  105                 case IODEV_PIO_READ:
  106                         error = iopio_read(pio_req);
  107                         break;
  108                 case IODEV_PIO_WRITE:
  109                         error = iopio_write(pio_req);
  110                         break;
  111                 default:
  112                         error = EINVAL;
  113                         break;
  114                 }
  115                 break;
  116         default:
  117                 error = iodev_ioctl(cmd, data);
  118         }
  119 
  120         return (error);
  121 }
  122 
  123 static int
  124 iopio_read(struct iodev_pio_req *req)
  125 {
  126 
  127         switch (req->width) {
  128         case 1:
  129                 req->val = iodev_read_1(req->port);
  130                 break;
  131         case 2:
  132                 if (req->port & 1) {
  133                         req->val = iodev_read_1(req->port);
  134                         req->val |= iodev_read_1(req->port + 1) << 8;
  135                 } else
  136                         req->val = iodev_read_2(req->port);
  137                 break;
  138         case 4:
  139                 if (req->port & 1) {
  140                         req->val = iodev_read_1(req->port);
  141                         req->val |= iodev_read_2(req->port + 1) << 8;
  142                         req->val |= iodev_read_1(req->port + 3) << 24;
  143                 } else if (req->port & 2) {
  144                         req->val = iodev_read_2(req->port);
  145                         req->val |= iodev_read_2(req->port + 2) << 16;
  146                 } else
  147                         req->val = iodev_read_4(req->port);
  148                 break;
  149         default:
  150                 return (EINVAL);
  151         }
  152 
  153         return (0);
  154 }
  155 
  156 static int
  157 iopio_write(struct iodev_pio_req *req)
  158 {
  159 
  160         switch (req->width) {
  161         case 1:
  162                 iodev_write_1(req->port, req->val);
  163                 break;
  164         case 2:
  165                 if (req->port & 1) {
  166                         iodev_write_1(req->port, req->val);
  167                         iodev_write_1(req->port + 1, req->val >> 8);
  168                 } else
  169                         iodev_write_2(req->port, req->val);
  170                 break;
  171         case 4:
  172                 if (req->port & 1) {
  173                         iodev_write_1(req->port, req->val);
  174                         iodev_write_2(req->port + 1, req->val >> 8);
  175                         iodev_write_1(req->port + 3, req->val >> 24);
  176                 } else if (req->port & 2) {
  177                         iodev_write_2(req->port, req->val);
  178                         iodev_write_2(req->port + 2, req->val >> 16);
  179                 } else
  180                         iodev_write_4(req->port, req->val);
  181                 break;
  182         default:
  183                 return (EINVAL);
  184         }
  185 
  186         return (0);
  187 }
  188 
  189 /* ARGSUSED */
  190 static int
  191 io_modevent(module_t mod __unused, int type, void *data __unused)
  192 {
  193         switch(type) {
  194         case MOD_LOAD:
  195                 if (bootverbose)
  196                         printf("io: <I/O>\n");
  197                 iodev = make_dev(&io_cdevsw, 0,
  198                         UID_ROOT, GID_WHEEL, 0600, "io");
  199                 break;
  200 
  201         case MOD_UNLOAD:
  202                 destroy_dev(iodev);
  203                 break;
  204 
  205         case MOD_SHUTDOWN:
  206                 break;
  207 
  208         default:
  209                 return(EOPNOTSUPP);
  210                 break;
  211 
  212         }
  213 
  214         return (0);
  215 }
  216 
  217 DEV_MODULE(io, io_modevent, NULL);
  218 MODULE_VERSION(io, 1);

Cache object: 1e6e7afcbe1b5fb2610709453d3ca6cd


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.