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/ncv/ncr53c500_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: ncr53c500_pisa.c,v 1.28 1998/11/26 01:59:11 honda Exp $        */
    2 /*      $NetBSD$        */
    3 
    4 /*-
    5  * [Ported for FreeBSD]
    6  *  Copyright (c) 2000
    7  *      Noriaki Mitsunaga, Mitsuru Iwasaki and Takanori Watanabe.
    8  *      All rights reserved.
    9  * [NetBSD for NEC PC-98 series]
   10  *  Copyright (c) 1995, 1996, 1997, 1998
   11  *      NetBSD/pc98 porting staff. All rights reserved.
   12  *  Copyright (c) 1995, 1996, 1997, 1998
   13  *      Naofumi HONDA. 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: releng/8.4/sys/dev/ncv/ncr53c500_pccard.c 194023 2009-06-11 17:14:28Z avg $");
   41 
   42 #include <sys/param.h>
   43 #include <sys/errno.h>
   44 #include <sys/kernel.h>
   45 #include <sys/malloc.h>
   46 #include <sys/systm.h>
   47 
   48 #include <machine/bus.h>
   49 #include <machine/resource.h>
   50 #include <sys/rman.h>
   51 #include <compat/netbsd/dvcfg.h>
   52 
   53 #include <sys/device_port.h>
   54 
   55 #include <dev/pccard/pccardvar.h>
   56 
   57 #include <cam/scsi/scsi_low.h>
   58 #include <cam/scsi/scsi_low_pisa.h>
   59 
   60 #include <dev/ncv/ncr53c500reg.h>
   61 #include <dev/ncv/ncr53c500hw.h>
   62 #include <dev/ncv/ncr53c500var.h>
   63 
   64 #define KME_KXLC004_01 0x100
   65 #define OFFSET_KME_KXLC004_01 0x10
   66 
   67 
   68 #include "pccarddevs.h"
   69 
   70 static int ncvprobe(DEVPORT_PDEVICE devi);
   71 static int ncvattach(DEVPORT_PDEVICE devi);
   72 
   73 static void     ncv_card_unload(DEVPORT_PDEVICE);
   74 
   75 static const struct ncv_product {
   76         struct pccard_product   prod;
   77         int flags;
   78 } ncv_products[] = {
   79         { PCMCIA_CARD(EPSON, SC200), 0},
   80         { PCMCIA_CARD(PANASONIC, KXLC002), 0xb4d00000 },
   81         { PCMCIA_CARD(PANASONIC, KXLC003), 0xb4d00000 },        /* untested */
   82         { PCMCIA_CARD(PANASONIC, KXLC004), 0xb4d00100 },
   83         { PCMCIA_CARD(MACNICA, MPS100), 0xb6250000 },
   84         { PCMCIA_CARD(MACNICA, MPS110), 0 },
   85         { PCMCIA_CARD(NEC, PC9801N_J03R), 0 },
   86         { PCMCIA_CARD(NEWMEDIA, BASICS_SCSI), 0 },
   87         { PCMCIA_CARD(QLOGIC, PC05), 0x84d00000 },
   88 #define FLAGS_REX5572 0x84d00000
   89         { PCMCIA_CARD(RATOC, REX5572), FLAGS_REX5572 },
   90         { PCMCIA_CARD(RATOC, REX9530), 0x84d00000 },
   91         { { NULL }, 0 }
   92 };
   93 
   94 /*
   95  * Additional code for FreeBSD new-bus PCCard frontend
   96  */
   97 
   98 static void
   99 ncv_pccard_intr(void * arg)
  100 {
  101         ncvintr(arg);
  102 }
  103 
  104 static void
  105 ncv_release_resource(DEVPORT_PDEVICE dev)
  106 {
  107         struct ncv_softc        *sc = device_get_softc(dev);
  108 
  109         if (sc->ncv_intrhand) {
  110                 bus_teardown_intr(dev, sc->irq_res, sc->ncv_intrhand);
  111         }
  112 
  113         if (sc->port_res) {
  114                 bus_release_resource(dev, SYS_RES_IOPORT,
  115                                      sc->port_rid, sc->port_res);
  116         }
  117 
  118         if (sc->port_res_dmy) {
  119                 bus_release_resource(dev, SYS_RES_IOPORT,
  120                                      sc->port_rid_dmy, sc->port_res_dmy);
  121         }
  122 
  123         if (sc->irq_res) {
  124                 bus_release_resource(dev, SYS_RES_IRQ,
  125                                      sc->irq_rid, sc->irq_res);
  126         }
  127 
  128         if (sc->mem_res) {
  129                 bus_release_resource(dev, SYS_RES_MEMORY,
  130                                      sc->mem_rid, sc->mem_res);
  131         }
  132 }
  133 
  134 static int
  135 ncv_alloc_resource(DEVPORT_PDEVICE dev)
  136 {
  137         struct ncv_softc        *sc = device_get_softc(dev);
  138         u_int32_t               flags = DEVPORT_PDEVFLAGS(dev);
  139         u_long                  ioaddr, iosize, maddr, msize;
  140         int                     error;
  141         bus_addr_t              offset = 0;
  142 
  143         if(flags & KME_KXLC004_01)
  144                 offset = OFFSET_KME_KXLC004_01;
  145 
  146         error = bus_get_resource(dev, SYS_RES_IOPORT, 0, &ioaddr, &iosize);
  147         if (error || (iosize < (offset + NCVIOSZ))) {
  148                 return(ENOMEM);
  149         }
  150 
  151         sc->port_rid = 0;
  152         sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port_rid,
  153                                           ioaddr+offset, ioaddr+iosize-offset,
  154                                           iosize-offset, RF_ACTIVE);
  155         if (sc->port_res == NULL) {
  156                 ncv_release_resource(dev);
  157                 return(ENOMEM);
  158         }
  159 
  160         if (offset != 0) {
  161                 sc->port_rid_dmy = 0;
  162                 sc->port_res_dmy = bus_alloc_resource(dev, SYS_RES_IOPORT, 
  163                                                 &sc->port_rid_dmy,
  164                                                 ioaddr, ioaddr+offset, offset, 
  165                                                 RF_ACTIVE);
  166                 if (sc->port_res_dmy == NULL) {
  167                         printf("Warning: cannot allocate IOPORT partially.\n");
  168                 }
  169         } else {
  170                 sc->port_rid_dmy = 0;
  171                 sc->port_res_dmy = NULL;
  172         }
  173 
  174         sc->irq_rid = 0;
  175         sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
  176                                              RF_ACTIVE);
  177         if (sc->irq_res == NULL) {
  178                 ncv_release_resource(dev);
  179                 return(ENOMEM);
  180         }
  181 
  182         error = bus_get_resource(dev, SYS_RES_MEMORY, 0, &maddr, &msize);
  183         if (error) {
  184                 return(0);      /* XXX */
  185         }
  186 
  187         /* no need to allocate memory if not configured */
  188         if (maddr == 0 || msize == 0) {
  189                 return(0);
  190         }
  191 
  192         sc->mem_rid = 0;
  193         sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid,
  194                                              RF_ACTIVE);
  195         if (sc->mem_res == NULL) {
  196                 ncv_release_resource(dev);
  197                 return(ENOMEM);
  198         }
  199 
  200         return(0);
  201 }
  202 
  203 static int
  204 ncv_pccard_probe(device_t dev)
  205 {
  206         const struct ncv_product *pp;
  207         const char *vendorstr;
  208         const char *prodstr;
  209 
  210         if ((pp = (const struct ncv_product *) pccard_product_lookup(dev, 
  211             (const struct pccard_product *) ncv_products,
  212             sizeof(ncv_products[0]), NULL)) != NULL) {
  213                 if (pp->prod.pp_name != NULL)
  214                         device_set_desc(dev, pp->prod.pp_name);
  215                 device_set_flags(dev, pp->flags);
  216                 return(0);
  217         }
  218         if (pccard_get_vendor_str(dev, &vendorstr))
  219                 return(EIO);
  220         if (pccard_get_product_str(dev, &prodstr))
  221                 return(EIO);
  222         if (strcmp(vendorstr, "RATOC System Inc.") == 0 &&
  223                 strncmp(prodstr, "SOUND/SCSI2 CARD", 16) == 0) {
  224                 device_set_desc(dev, "RATOC REX-5572");
  225                 device_set_flags(dev, FLAGS_REX5572);
  226                 return (0);
  227         }
  228         return(EIO);
  229 }
  230 
  231 static int
  232 ncv_pccard_attach(device_t dev)
  233 {
  234         struct ncv_softc        *sc = device_get_softc(dev);
  235         int                     error;
  236 
  237         bzero(sc, sizeof(struct ncv_softc));
  238 
  239         error = ncv_alloc_resource(dev);
  240         if (error) {
  241                 return(error);
  242         }
  243 
  244         if (ncvprobe(dev) == 0) {
  245                 ncv_release_resource(dev);
  246                 return(ENXIO);
  247         }
  248         error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_CAM | INTR_ENTROPY,
  249                                NULL, ncv_pccard_intr, (void *)sc, &sc->ncv_intrhand);
  250         if (error) {
  251                 ncv_release_resource(dev);
  252                 return(error);
  253         }
  254 
  255         if (ncvattach(dev) == 0) {
  256                 ncv_release_resource(dev);
  257                 return(ENXIO);
  258         }
  259 
  260         return(0);
  261 }
  262 
  263 static  int
  264 ncv_pccard_detach(device_t dev)
  265 {
  266         ncv_card_unload(dev);
  267         ncv_release_resource(dev);
  268 
  269         return (0);
  270 }
  271 
  272 static device_method_t ncv_pccard_methods[] = {
  273         /* Device interface */
  274         DEVMETHOD(device_probe,         ncv_pccard_probe),
  275         DEVMETHOD(device_attach,        ncv_pccard_attach),
  276         DEVMETHOD(device_detach,        ncv_pccard_detach),
  277 
  278         { 0, 0 }
  279 };
  280 
  281 static driver_t ncv_pccard_driver = {
  282         "ncv",
  283         ncv_pccard_methods,
  284         sizeof(struct ncv_softc),
  285 };
  286 
  287 static devclass_t ncv_devclass;
  288 
  289 MODULE_DEPEND(ncv, scsi_low, 1, 1, 1);
  290 DRIVER_MODULE(ncv, pccard, ncv_pccard_driver, ncv_devclass, 0, 0);
  291 
  292 static void
  293 ncv_card_unload(DEVPORT_PDEVICE devi)
  294 {
  295         struct ncv_softc *sc = DEVPORT_PDEVGET_SOFTC(devi);
  296         intrmask_t s;
  297 
  298         s = splcam();
  299         scsi_low_deactivate((struct scsi_low_softc *)sc);
  300         scsi_low_dettach(&sc->sc_sclow);
  301         splx(s);
  302 }
  303 
  304 static int
  305 ncvprobe(DEVPORT_PDEVICE devi)
  306 {
  307         int rv;
  308         struct ncv_softc *sc = device_get_softc(devi);
  309         u_int32_t flags = DEVPORT_PDEVFLAGS(devi);
  310 
  311         rv = ncvprobesubr(rman_get_bustag(sc->port_res),
  312                           rman_get_bushandle(sc->port_res),
  313                           flags, NCV_HOSTID);
  314 
  315         return rv;
  316 }
  317 
  318 static int
  319 ncvattach(DEVPORT_PDEVICE devi)
  320 {
  321         struct ncv_softc *sc;
  322         struct scsi_low_softc *slp;
  323         u_int32_t flags = DEVPORT_PDEVFLAGS(devi);
  324         intrmask_t s;
  325         char dvname[16]; /* SCSI_LOW_DVNAME_LEN */
  326 
  327         strcpy(dvname, "ncv");
  328 
  329         sc = DEVPORT_PDEVALLOC_SOFTC(devi);
  330         if (sc == NULL) {
  331                 return(0);
  332         }
  333 
  334         slp = &sc->sc_sclow;
  335         slp->sl_dev = devi;
  336         sc->sc_iot = rman_get_bustag(sc->port_res);
  337         sc->sc_ioh = rman_get_bushandle(sc->port_res);
  338 
  339         slp->sl_hostid = NCV_HOSTID;
  340         slp->sl_cfgflags = flags;
  341 
  342         s = splcam();
  343         ncvattachsubr(sc);
  344         splx(s);
  345 
  346         return(NCVIOSZ);
  347 }

Cache object: 0e4cecae769db45d829f505e3532a955


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