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/nsp/nsp_pccard.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 /*      $NecBSD: nsp_pisa.c,v 1.4 1999/04/15 01:35:54 kmatsuda Exp $    */
    2 /*      $NetBSD$        */
    3 
    4 /*-
    5  * SPDX-License-Identifier: BSD-3-Clause
    6  *
    7  * [Ported for FreeBSD]
    8  *  Copyright (c) 2000
    9  *      Noriaki Mitsunaga, Mitsuru Iwasaki and Takanori Watanabe.
   10  *      All rights reserved.
   11  * [NetBSD for NEC PC-98 series]
   12  *  Copyright (c) 1998
   13  *      NetBSD/pc98 porting staff. All rights reserved.
   14  * 
   15  *  Redistribution and use in source and binary forms, with or without
   16  *  modification, are permitted provided that the following conditions
   17  *  are met:
   18  *  1. Redistributions of source code must retain the above copyright
   19  *     notice, this list of conditions and the following disclaimer.
   20  *  2. Redistributions in binary form must reproduce the above copyright
   21  *     notice, this list of conditions and the following disclaimer in the
   22  *     documentation and/or other materials provided with the distribution.
   23  *  3. The name of the author may not be used to endorse or promote products
   24  *     derived from this software without specific prior written permission.
   25  * 
   26  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   27  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   28  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   29  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
   30  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   31  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   32  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   34  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   35  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 #include <sys/cdefs.h>
   40 __FBSDID("$FreeBSD$");
   41 
   42 #include <sys/param.h>
   43 #include <sys/bus.h>
   44 #include <sys/errno.h>
   45 #include <sys/kernel.h>
   46 #include <sys/malloc.h>
   47 #include <sys/module.h>
   48 #include <sys/systm.h>
   49 
   50 #include <machine/bus.h>
   51 #include <machine/resource.h>
   52 #include <sys/rman.h>
   53 
   54 #include <sys/bus.h>
   55 
   56 #include <dev/pccard/pccardvar.h>
   57 
   58 #include <cam/scsi/scsi_low.h>
   59 
   60 #include <dev/nsp/nspreg.h>
   61 #include <dev/nsp/nspvar.h>
   62 
   63 #define NSP_HOSTID      7
   64 
   65 #include "pccarddevs.h"
   66 
   67 #define PIO_MODE 0x100          /* pd_flags */
   68 
   69 static int nspprobe(device_t devi);
   70 static int nspattach(device_t devi);
   71 
   72 static  void    nsp_card_unload (device_t);
   73 
   74 const struct pccard_product nsp_products[] = {
   75         PCMCIA_CARD(IODATA3, CBSC16),
   76         PCMCIA_CARD(PANASONIC, KME),
   77         PCMCIA_CARD(WORKBIT2, NINJA_SCSI3),
   78         PCMCIA_CARD(WORKBIT, ULTRA_NINJA_16),
   79         { NULL }
   80 };
   81 
   82 /*
   83  * Additional code for FreeBSD new-bus PC Card frontend
   84  */
   85 
   86 static void
   87 nsp_pccard_intr(void * arg)
   88 {
   89         struct nsp_softc *sc;
   90 
   91         sc = arg;
   92         SCSI_LOW_LOCK(&sc->sc_sclow);
   93         nspintr(sc);
   94         SCSI_LOW_UNLOCK(&sc->sc_sclow);
   95 }
   96 
   97 static void
   98 nsp_release_resource(device_t dev)
   99 {
  100         struct nsp_softc        *sc = device_get_softc(dev);
  101 
  102         if (sc->nsp_intrhand)
  103                 bus_teardown_intr(dev, sc->irq_res, sc->nsp_intrhand);
  104         if (sc->port_res)
  105                 bus_release_resource(dev, SYS_RES_IOPORT,
  106                                      sc->port_rid, sc->port_res);
  107         if (sc->irq_res)
  108                 bus_release_resource(dev, SYS_RES_IRQ,
  109                                      sc->irq_rid, sc->irq_res);
  110         if (sc->mem_res)
  111                 bus_release_resource(dev, SYS_RES_MEMORY,
  112                                      sc->mem_rid, sc->mem_res);
  113         mtx_destroy(&sc->sc_sclow.sl_lock);
  114 }
  115 
  116 static int
  117 nsp_alloc_resource(device_t dev)
  118 {
  119         struct nsp_softc        *sc = device_get_softc(dev);
  120         rman_res_t              ioaddr, iosize, maddr, msize;
  121         int                     error;
  122 
  123         error = bus_get_resource(dev, SYS_RES_IOPORT, 0, &ioaddr, &iosize);
  124         if (error || iosize < NSP_IOSIZE)
  125                 return(ENOMEM);
  126 
  127         mtx_init(&sc->sc_sclow.sl_lock, "nsp", NULL, MTX_DEF);
  128         sc->port_rid = 0;
  129         sc->port_res = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT,
  130                                                    &sc->port_rid, NSP_IOSIZE,
  131                                                    RF_ACTIVE);
  132         if (sc->port_res == NULL) {
  133                 nsp_release_resource(dev);
  134                 return(ENOMEM);
  135         }
  136 
  137         sc->irq_rid = 0;
  138         sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
  139                                              RF_ACTIVE);
  140         if (sc->irq_res == NULL) {
  141                 nsp_release_resource(dev);
  142                 return(ENOMEM);
  143         }
  144 
  145         error = bus_get_resource(dev, SYS_RES_MEMORY, 0, &maddr, &msize);
  146         if (error)
  147                 return(0);      /* XXX */
  148 
  149         /* No need to allocate memory if not configured and it's in PIO mode */
  150         if (maddr == 0 || msize == 0) {
  151                 if ((device_get_flags(dev) & PIO_MODE) == 0) {
  152                         printf("Memory window was not configured. Configure or use in PIO mode.");
  153                         nsp_release_resource(dev);
  154                         return(ENOMEM);
  155                 }
  156                 /* no need to allocate memory if PIO mode */
  157                 return(0);
  158         }
  159 
  160         sc->mem_rid = 0;
  161         sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid,
  162                                              RF_ACTIVE);
  163         if (sc->mem_res == NULL) {
  164                 nsp_release_resource(dev);
  165                 return(ENOMEM);
  166         }
  167 
  168         return(0);
  169 }
  170 
  171 static int
  172 nsp_pccard_probe(device_t dev)
  173 {
  174         const struct pccard_product *pp;
  175 
  176         if ((pp = pccard_product_lookup(dev, nsp_products,
  177             sizeof(nsp_products[0]), NULL)) != NULL) {
  178                 if (pp->pp_name)
  179                         device_set_desc(dev, pp->pp_name);
  180                 return (BUS_PROBE_DEFAULT);
  181         }
  182         return(EIO);
  183 }
  184 
  185 static int
  186 nsp_pccard_attach(device_t dev)
  187 {
  188         struct nsp_softc        *sc = device_get_softc(dev);
  189         int                     error;
  190 
  191         error = nsp_alloc_resource(dev);
  192         if (error)
  193                 return(error);
  194         if (nspprobe(dev) == 0) {
  195                 nsp_release_resource(dev);
  196                 return(ENXIO);
  197         }
  198         error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_CAM | INTR_ENTROPY |
  199             INTR_MPSAFE, NULL, nsp_pccard_intr, sc, &sc->nsp_intrhand);
  200         if (error) {
  201                 nsp_release_resource(dev);
  202                 return(error);
  203         }
  204         if (nspattach(dev) == 0) {
  205                 nsp_release_resource(dev);
  206                 return(ENXIO);
  207         }
  208         gone_in_dev(dev, 12, "nsp(4) driver");
  209 
  210         return(0);
  211 }
  212 
  213 static int
  214 nsp_pccard_detach(device_t dev)
  215 {
  216         nsp_card_unload(dev);
  217         nsp_release_resource(dev);
  218 
  219         return (0);
  220 }
  221 
  222 static device_method_t nsp_pccard_methods[] = {
  223         /* Device interface */
  224         DEVMETHOD(device_probe,         nsp_pccard_probe),
  225         DEVMETHOD(device_attach,        nsp_pccard_attach),
  226         DEVMETHOD(device_detach,        nsp_pccard_detach),
  227         { 0, 0 }
  228 };
  229 
  230 static driver_t nsp_pccard_driver = {
  231         "nsp",
  232         nsp_pccard_methods,
  233         sizeof(struct nsp_softc),
  234 };
  235 
  236 static devclass_t nsp_devclass;
  237 
  238 MODULE_DEPEND(nsp, scsi_low, 1, 1, 1);
  239 DRIVER_MODULE(nsp, pccard, nsp_pccard_driver, nsp_devclass, 0, 0);
  240 PCCARD_PNP_INFO(nsp_products);
  241 
  242 static void
  243 nsp_card_unload(device_t devi)
  244 {
  245         struct nsp_softc *sc = device_get_softc(devi);
  246 
  247         scsi_low_deactivate(&sc->sc_sclow);
  248         scsi_low_detach(&sc->sc_sclow);
  249 }
  250 
  251 static  int
  252 nspprobe(device_t devi)
  253 {
  254         int rv;
  255         struct nsp_softc *sc = device_get_softc(devi);
  256 
  257         rv = nspprobesubr(sc->port_res,
  258                           device_get_flags(devi));
  259 
  260         return rv;
  261 }
  262 
  263 static  int
  264 nspattach(device_t devi)
  265 {
  266         struct nsp_softc *sc;
  267         struct scsi_low_softc *slp;
  268         u_int32_t flags = device_get_flags(devi);
  269         u_int   iobase = bus_get_resource_start(devi, SYS_RES_IOPORT, 0);
  270 
  271         if (iobase == 0) {
  272                 device_printf(devi, "no ioaddr is given\n");
  273                 return (ENXIO);
  274         }
  275 
  276         sc = device_get_softc(devi);
  277         slp = &sc->sc_sclow;
  278         slp->sl_dev = devi;
  279 
  280         if (sc->mem_res == NULL) {
  281                 device_printf(devi,
  282                     "WARNING: CANNOT GET Memory RESOURCE going PIO mode\n");
  283                 flags |= PIO_MODE;
  284         }
  285 
  286         /* slp->sl_irq = devi->pd_irq; */
  287         sc->sc_iclkdiv = CLKDIVR_20M;
  288         sc->sc_clkdiv = CLKDIVR_40M;
  289 
  290         slp->sl_hostid = NSP_HOSTID;
  291         slp->sl_cfgflags = flags;
  292 
  293         nspattachsubr(sc);
  294 
  295         return(NSP_IOSIZE);
  296 }

Cache object: 1e680e01b19c42d2a8ad6b25077b4ce0


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