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/si/si_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  * Device driver for Specialix range (SI/XIO) of serial line multiplexors.
    3  *
    4  * Copyright (C) 2000, Peter Wemm <peter@netplex.com.au>
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notices, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notices, 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 ``AS IS'' AND ANY EXPRESS OR IMPLIED
   16  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
   17  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
   18  * NO EVENT SHALL THE AUTHORS BE LIABLE.
   19  *
   20  */
   21 
   22 #include <sys/cdefs.h>
   23 __FBSDID("$FreeBSD$");
   24 
   25 #include "opt_debug_si.h"
   26 
   27 #include <sys/param.h>
   28 #include <sys/systm.h>
   29 #include <sys/kernel.h>
   30 #include <sys/module.h>
   31 #include <sys/bus.h>
   32 #include <machine/bus.h>
   33 #include <sys/rman.h>
   34 #include <machine/resource.h>
   35 
   36 #include <dev/si/sireg.h>
   37 #include <dev/si/sivar.h>
   38 
   39 #include <isa/isavar.h>
   40 
   41 /* Look for a valid board at the given mem addr */
   42 static int
   43 si_isa_probe(device_t dev)
   44 {
   45         struct si_softc *sc;
   46         int type;
   47         u_int i, ramsize;
   48         volatile unsigned char was, *ux;
   49         volatile unsigned char *maddr;
   50         unsigned char *paddr;
   51         int unit;
   52 
   53         /* No pnp support */
   54         if (isa_get_vendorid(dev))
   55                 return (ENXIO);
   56 
   57         sc = device_get_softc(dev);
   58         unit = device_get_unit(dev);
   59 
   60         sc->sc_mem_rid = 0;
   61         sc->sc_mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
   62                                             &sc->sc_mem_rid,
   63                                             0, ~0, SIPROBEALLOC, RF_ACTIVE);
   64         if (!sc->sc_mem_res) {
   65                 device_printf(dev, "cannot allocate memory resource\n");
   66                 return ENXIO;
   67         }
   68         paddr = (caddr_t)rman_get_start(sc->sc_mem_res);/* physical */
   69         maddr = rman_get_virtual(sc->sc_mem_res);       /* in kvm */
   70 
   71         DPRINT((0, DBG_AUTOBOOT, "si%d: probe at virtual=0x%x physical=0x%x\n",
   72                 unit, maddr, paddr));
   73 
   74         /*
   75          * this is a lie, but it's easier than trying to handle caching
   76          * and ram conflicts in the >1M and <16M region.
   77          */
   78         if ((caddr_t)paddr < (caddr_t)0xA0000 ||
   79             (caddr_t)paddr >= (caddr_t)0x100000) {
   80                 device_printf(dev, "maddr (%p) out of range\n", paddr);
   81                 goto fail;
   82         }
   83 
   84         if (((uintptr_t)paddr & 0x7fff) != 0) {
   85                 device_printf(dev, "maddr (%p) not on 32k boundary\n", paddr);
   86                 goto fail;
   87         }
   88 
   89         /* Is there anything out there? (0x17 is just an arbitrary number) */
   90         *maddr = 0x17;
   91         if (*maddr != 0x17) {
   92                 device_printf(dev, "0x17 check fail at phys %p\n", paddr);
   93                 goto fail;
   94         }
   95         /*
   96          * Let's look first for a JET ISA card, since that's pretty easy
   97          *
   98          * All jet hosts are supposed to have this string in the IDROM,
   99          * but it's not worth checking on self-IDing busses like PCI.
  100          */
  101         {
  102                 unsigned char *jet_chk_str = "JET HOST BY KEV#";
  103 
  104                 for (i = 0; i < strlen(jet_chk_str); i++)
  105                         if (jet_chk_str[i] != *(maddr + SIJETIDSTR + 2 * i))
  106                                 goto try_mk2;
  107         }
  108         DPRINT((0, DBG_AUTOBOOT|DBG_FAIL, "si%d: JET first check - 0x%x\n",
  109                 unit, (*(maddr+SIJETIDBASE))));
  110         if (*(maddr+SIJETIDBASE) != (SISPLXID&0xff))
  111                 goto try_mk2;
  112         DPRINT((0, DBG_AUTOBOOT|DBG_FAIL, "si%d: JET second check - 0x%x\n",
  113                 unit, (*(maddr+SIJETIDBASE+2))));
  114         if (*(maddr+SIJETIDBASE+2) != ((SISPLXID&0xff00)>>8))
  115                 goto try_mk2;
  116         /* It must be a Jet ISA or RIO card */
  117         DPRINT((0, DBG_AUTOBOOT|DBG_FAIL, "si%d: JET id check - 0x%x\n",
  118                 unit, (*(maddr+SIUNIQID))));
  119         if ((*(maddr+SIUNIQID) & 0xf0) != 0x20)
  120                 goto try_mk2;
  121         /* It must be a Jet ISA SI/XIO card */
  122         *(maddr + SIJETCONFIG) = 0;
  123         type = SIJETISA;
  124         ramsize = SIJET_RAMSIZE;
  125         goto got_card;
  126 
  127 try_mk2:
  128         /*
  129          * OK, now to see if whatever responded is really an SI card.
  130          * Try for a MK II next (SIHOST2)
  131          */
  132         for (i = SIPLSIG; i < SIPLSIG + 8; i++)
  133                 if ((*(maddr+i) & 7) != (~(unsigned char)i & 7))
  134                         goto try_mk1;
  135 
  136         /* It must be an SIHOST2 */
  137         *(maddr + SIPLRESET) = 0;
  138         *(maddr + SIPLIRQCLR) = 0;
  139         *(maddr + SIPLIRQSET) = 0x10;
  140         type = SIHOST2;
  141         ramsize = SIHOST2_RAMSIZE;
  142         goto got_card;
  143 
  144 try_mk1:
  145         /*
  146          * Its not a MK II, so try for a MK I (SIHOST)
  147          */
  148         *(maddr+SIRESET) = 0x0;         /* reset the card */
  149         *(maddr+SIINTCL) = 0x0;         /* clear int */
  150         *(maddr+SIRAM) = 0x17;
  151         if (*(maddr+SIRAM) != (unsigned char)0x17)
  152                 goto fail;
  153         *(maddr+0x7ff8) = 0x17;
  154         if (*(maddr+0x7ff8) != (unsigned char)0x17) {
  155                 device_printf(dev, "0x17 check fail at phys %p = 0x%x\n",
  156                     paddr+0x77f8, *(maddr+0x77f8));
  157                 goto fail;
  158         }
  159 
  160         /* It must be an SIHOST (maybe?) - there must be a better way XXX */
  161         type = SIHOST;
  162         ramsize = SIHOST_RAMSIZE;
  163 
  164 got_card:
  165         DPRINT((0, DBG_AUTOBOOT, "si%d: found type %d card, try memory test\n",
  166                 unit, type));
  167         /* Try the acid test */
  168         ux = maddr + SIRAM;
  169         for (i = 0; i < ramsize; i++, ux++)
  170                 *ux = (unsigned char)(i&0xff);
  171         ux = maddr + SIRAM;
  172         for (i = 0; i < ramsize; i++, ux++) {
  173                 if ((was = *ux) != (unsigned char)(i&0xff)) {
  174                         device_printf(dev,
  175                             "memtest fail at phys %p, was %x should be %x\n",
  176                             paddr + i, was, i & 0xff);
  177                         goto fail;
  178                 }
  179         }
  180 
  181         /* clear out the RAM */
  182         ux = maddr + SIRAM;
  183         for (i = 0; i < ramsize; i++)
  184                 *ux++ = 0;
  185         ux = maddr + SIRAM;
  186         for (i = 0; i < ramsize; i++) {
  187                 if ((was = *ux++) != 0) {
  188                         device_printf(dev, "clear fail at phys %p, was %x\n",
  189                             paddr + i, was);
  190                         goto fail;
  191                 }
  192         }
  193 
  194         /*
  195          * Success, we've found a valid board, now fill in
  196          * the adapter structure.
  197          */
  198         switch (type) {
  199         case SIHOST2:
  200                 switch (isa_get_irq(dev)) {
  201                 case 11:
  202                 case 12:
  203                 case 15:
  204                         break;
  205                 default:
  206                         device_printf(dev,
  207                             "bad IRQ value - %d (11, 12, 15 allowed)\n",
  208                             isa_get_irq(dev));
  209                         goto fail;
  210                 }
  211                 sc->sc_memsize = SIHOST2_MEMSIZE;
  212                 break;
  213         case SIHOST:
  214                 switch (isa_get_irq(dev)) {
  215                 case 11:
  216                 case 12:
  217                 case 15:
  218                         break;
  219                 default:
  220                         device_printf(dev,
  221                             "bad IRQ value - %d (11, 12, 15 allowed)\n",
  222                             isa_get_irq(dev));
  223                         goto fail;
  224                 }
  225                 sc->sc_memsize = SIHOST_MEMSIZE;
  226                 break;
  227         case SIJETISA:
  228                 switch (isa_get_irq(dev)) {
  229                 case 9:
  230                 case 10:
  231                 case 11:
  232                 case 12:
  233                 case 15:
  234                         break;
  235                 default:
  236                         device_printf(dev,
  237                             "bad IRQ value - %d (9, 10, 11, 12, 15 allowed)\n",
  238                             isa_get_irq(dev));
  239                         goto fail;
  240                 }
  241                 sc->sc_memsize = SIJETISA_MEMSIZE;
  242                 break;
  243         case SIMCA:             /* MCA */
  244         default:
  245                 device_printf(dev, "card type %d not supported\n", type);
  246                 goto fail;
  247         }
  248         sc->sc_type = type;
  249         bus_release_resource(dev, SYS_RES_MEMORY,
  250                              sc->sc_mem_rid, sc->sc_mem_res);
  251         sc->sc_mem_res = 0;
  252         return (0);             /* success! */
  253 
  254 fail:
  255         if (sc->sc_mem_res) {
  256                 bus_release_resource(dev, SYS_RES_MEMORY,
  257                                      sc->sc_mem_rid, sc->sc_mem_res);
  258                 sc->sc_mem_res = 0;
  259         }
  260         return(EINVAL);
  261 }
  262 
  263 static int
  264 si_isa_attach(device_t dev)
  265 {
  266         int error;
  267         void *ih;
  268         struct si_softc *sc;
  269 
  270         error = 0;
  271         ih = NULL;
  272         sc = device_get_softc(dev);
  273 
  274         sc->sc_mem_rid = 0;
  275         sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
  276                                                 &sc->sc_mem_rid,
  277                                                 RF_ACTIVE);
  278         if (!sc->sc_mem_res) {
  279                 device_printf(dev, "couldn't map memory\n");
  280                 goto fail;
  281         }
  282         sc->sc_paddr = (caddr_t)rman_get_start(sc->sc_mem_res);
  283         sc->sc_maddr = rman_get_virtual(sc->sc_mem_res);
  284 
  285         sc->sc_irq_rid = 0;
  286         sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, 
  287                                                 &sc->sc_irq_rid,
  288                                                 RF_ACTIVE | RF_SHAREABLE);
  289         if (!sc->sc_irq_res) {
  290                 device_printf(dev, "couldn't allocate interrupt\n");
  291                 goto fail;
  292         }
  293         sc->sc_irq = rman_get_start(sc->sc_irq_res);
  294         error = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_TTY,
  295                                si_intr, sc,&ih);
  296         if (error) {
  297                 device_printf(dev, "couldn't activate interrupt\n");
  298                 goto fail;
  299         }
  300 
  301         error = siattach(dev);
  302         if (error)
  303                 goto fail;
  304         return (0);             /* success */
  305 
  306 fail:
  307         if (error == 0)
  308                 error = ENXIO;
  309         if (sc->sc_irq_res) {
  310                 if (ih)
  311                         bus_teardown_intr(dev, sc->sc_irq_res, ih);
  312                 bus_release_resource(dev, SYS_RES_IRQ,
  313                                      sc->sc_irq_rid, sc->sc_irq_res);
  314                 sc->sc_irq_res = 0;
  315         }
  316         if (sc->sc_mem_res) {
  317                 bus_release_resource(dev, SYS_RES_MEMORY,
  318                                      sc->sc_mem_rid, sc->sc_mem_res);
  319                 sc->sc_mem_res = 0;
  320         }
  321         return (error);
  322 }
  323 
  324 static device_method_t si_isa_methods[] = {
  325         /* Device interface */
  326         DEVMETHOD(device_probe,         si_isa_probe),
  327         DEVMETHOD(device_attach,        si_isa_attach),
  328 
  329         { 0, 0 }
  330 };
  331 
  332 static driver_t si_isa_driver = {
  333         "si",
  334         si_isa_methods,
  335         sizeof(struct si_softc),
  336 };
  337 
  338 DRIVER_MODULE(si, isa, si_isa_driver, si_devclass, 0, 0);

Cache object: 1470c0ea0177562ec4b719d00d1c9cc7


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