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/isa/atkbdc_isa.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  * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer as
   10  *    the first lines of this file unmodified.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
   16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   18  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   25  *
   26  * $FreeBSD$
   27  */
   28 
   29 #include "atkbdc.h"
   30 #include "opt_kbd.h"
   31 
   32 #if NATKBDC > 0
   33 
   34 #include <sys/param.h>
   35 #include <sys/systm.h>
   36 #include <sys/kernel.h>
   37 #include <sys/bus.h>
   38 #include <sys/malloc.h>
   39 
   40 #include <dev/kbd/atkbdcreg.h>
   41 
   42 #include <isa/isareg.h>
   43 #include <isa/isavar.h>
   44 
   45 MALLOC_DEFINE(M_ATKBDDEV, "atkbddev", "AT Keyboard device");
   46 
   47 /* children */
   48 typedef struct atkbdc_device {
   49         int flags;      /* configuration flags */
   50         int port;       /* port number (same as the controller's) */
   51         int irq;        /* ISA IRQ mask */
   52 } atkbdc_device_t;
   53 
   54 /* kbdc */
   55 devclass_t atkbdc_devclass;
   56 
   57 static int      atkbdc_probe(device_t dev);
   58 static int      atkbdc_attach(device_t dev);
   59 static void     atkbdc_print_child(device_t bus, device_t dev);
   60 static int      atkbdc_read_ivar(device_t bus, device_t dev, int index,
   61                                  u_long *val);
   62 static int      atkbdc_write_ivar(device_t bus, device_t dev, int index,
   63                                   u_long val);
   64 
   65 static device_method_t atkbdc_methods[] = {
   66         DEVMETHOD(device_probe,         atkbdc_probe),
   67         DEVMETHOD(device_attach,        atkbdc_attach),
   68 
   69         DEVMETHOD(bus_print_child,      atkbdc_print_child),
   70         DEVMETHOD(bus_read_ivar,        atkbdc_read_ivar),
   71         DEVMETHOD(bus_write_ivar,       atkbdc_write_ivar),
   72         DEVMETHOD(bus_alloc_resource,   bus_generic_alloc_resource),
   73         DEVMETHOD(bus_release_resource, bus_generic_release_resource),
   74         DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
   75         DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
   76         DEVMETHOD(bus_setup_intr,       bus_generic_setup_intr),
   77         DEVMETHOD(bus_teardown_intr,    bus_generic_teardown_intr),
   78 
   79         { 0, 0 }
   80 };
   81 
   82 static driver_t atkbdc_driver = {
   83         ATKBDC_DRIVER_NAME,
   84         atkbdc_methods,
   85         DRIVER_TYPE_MISC,
   86         sizeof(atkbdc_softc_t *),
   87 };
   88 
   89 static int
   90 atkbdc_probe(device_t dev)
   91 {
   92         atkbdc_softc_t *sc;
   93         int unit;
   94         int error;
   95 
   96         unit = device_get_unit(dev);
   97         sc = *(atkbdc_softc_t **)device_get_softc(dev);
   98         if (sc == NULL) {
   99                 /*
  100                  * We have to maintain two copies of the kbdc_softc struct,
  101                  * as the low-level console needs to have access to the
  102                  * keyboard controller before kbdc is probed and attached. 
  103                  * kbdc_soft[] contains the default entry for that purpose.
  104                  * See atkbdc.c. XXX
  105                  */
  106                 sc = atkbdc_get_softc(unit);
  107                 if (sc == NULL)
  108                         return ENOMEM;
  109         }
  110 
  111         device_set_desc(dev, "keyboard controller (i8042)");
  112 
  113         error = atkbdc_probe_unit(sc, unit, isa_get_port(dev));
  114         if (error == 0)
  115                 *(atkbdc_softc_t **)device_get_softc(dev) = sc;
  116 
  117         return error;
  118 }
  119 
  120 static void
  121 atkbdc_add_device(device_t dev, const char *name, int unit)
  122 {
  123         atkbdc_softc_t  *sc = *(atkbdc_softc_t **)device_get_softc(dev);
  124         atkbdc_device_t *kdev;
  125         device_t        child;
  126         int             t;
  127 
  128         kdev = malloc(sizeof(struct atkbdc_device), M_ATKBDDEV, M_NOWAIT);
  129         if (!kdev)
  130                 return;
  131         bzero(kdev, sizeof *kdev);
  132 
  133         kdev->port = sc->port;
  134 
  135         if (resource_int_value(name, unit, "irq", &t) == 0)
  136                 kdev->irq = t;
  137         else
  138                 kdev->irq = -1;
  139 
  140         if (resource_int_value(name, unit, "flags", &t) == 0)
  141                 kdev->flags = t;
  142         else
  143                 kdev->flags = 0;
  144 
  145         child = device_add_child(dev, name, unit, kdev);
  146 }
  147 
  148 static int
  149 atkbdc_attach(device_t dev)
  150 {
  151         atkbdc_softc_t  *sc;
  152         int             i;
  153 
  154         sc = *(atkbdc_softc_t **)device_get_softc(dev);
  155         if ((sc == NULL) || (sc->port <= 0))
  156                 return ENXIO;
  157 
  158         /*
  159          * Add all devices configured to be attached to atkbdc0.
  160          */
  161         for (i = resource_query_string(-1, "at", "atkbdc0");
  162              i != -1;
  163              i = resource_query_string(i, "at", "atkbdc0")) {
  164                 atkbdc_add_device(dev, resource_query_name(i),
  165                                   resource_query_unit(i));
  166         }
  167 
  168         /*
  169          * and atkbdc?
  170          */
  171         for (i = resource_query_string(-1, "at", "atkbdc");
  172              i != -1;
  173              i = resource_query_string(i, "at", "atkbdc")) {
  174                 atkbdc_add_device(dev, resource_query_name(i),
  175                                   resource_query_unit(i));
  176         }
  177 
  178         bus_generic_attach(dev);
  179 
  180         return 0;
  181 }
  182 
  183 static void
  184 atkbdc_print_child(device_t bus, device_t dev)
  185 {
  186         atkbdc_device_t *kbdcdev;
  187 
  188         kbdcdev = (atkbdc_device_t *)device_get_ivars(dev);
  189 
  190         if (kbdcdev->flags != 0)
  191                 printf(" flags 0x%x", kbdcdev->flags);
  192 
  193         printf(" on %s%d", device_get_name(bus), device_get_unit(bus));
  194 }
  195 
  196 static int
  197 atkbdc_read_ivar(device_t bus, device_t dev, int index, u_long *val)
  198 {
  199         atkbdc_device_t *ivar;
  200 
  201         ivar = (atkbdc_device_t *)device_get_ivars(dev);
  202         switch (index) {
  203         case KBDC_IVAR_PORT:
  204                 *val = (u_long)ivar->port;
  205                 break;
  206         case KBDC_IVAR_IRQ:
  207                 *val = (u_long)ivar->irq;
  208                 break;
  209         case KBDC_IVAR_FLAGS:
  210                 *val = (u_long)ivar->flags;
  211                 break;
  212         default:
  213                 return ENOENT;
  214         }
  215         return 0;
  216 }
  217 
  218 static int
  219 atkbdc_write_ivar(device_t bus, device_t dev, int index, u_long val)
  220 {
  221         atkbdc_device_t *ivar;
  222 
  223         ivar = (atkbdc_device_t *)device_get_ivars(dev);
  224         switch (index) {
  225         case KBDC_IVAR_PORT:
  226                 ivar->port = (int)val;
  227                 break;
  228         case KBDC_IVAR_IRQ:
  229                 ivar->irq = (int)val;
  230                 break;
  231         case KBDC_IVAR_FLAGS:
  232                 ivar->flags = (int)val;
  233                 break;
  234         default:
  235                 return ENOENT;
  236         }
  237         return 0;
  238 }
  239 
  240 DRIVER_MODULE(atkbdc, isa, atkbdc_driver, atkbdc_devclass, 0, 0);
  241 
  242 #endif /* NATKBDC > 0 */

Cache object: c4fe6cb868d874dc8a471974cc6db49c


[ 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.