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/eisa/cac_eisa.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 /*      $OpenBSD: cac_eisa.c,v 1.7 2022/04/06 18:59:28 naddy Exp $      */
    2 /*      $NetBSD: cac_eisa.c,v 1.1 2000/09/01 12:15:20 ad Exp $  */
    3 
    4 /*-
    5  * Copyright (c) 2000 The NetBSD Foundation, Inc.
    6  * All rights reserved.
    7  *
    8  * This code is derived from software contributed to The NetBSD Foundation
    9  * by Andrew Doran.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   30  * POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 /*
   34  * Copyright (c) 2000 Jonathan Lemon
   35  * Copyright (c) 1999 by Matthew N. Dodd <winter@jurai.net>
   36  * All Rights Reserved.
   37  *
   38  * Redistribution and use in source and binary forms, with or without
   39  * modification, are permitted provided that the following conditions
   40  * are met:
   41  * 1. Redistributions of source code must retain the above copyright
   42  *    notice, this list of conditions, and the following disclaimer,
   43  *    without modification, immediately at the beginning of the file.
   44  * 2. The name of the author may not be used to endorse or promote products
   45  *    derived from this software without specific prior written permission.
   46  *
   47  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   48  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   49  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   50  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
   51  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   52  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   53  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   54  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   55  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   56  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   57  * SUCH DAMAGE.
   58  */
   59 
   60 /*
   61  * EISA front-end for cac(4) driver.
   62  */
   63 
   64 #include <sys/param.h>
   65 #include <sys/systm.h>
   66 #include <sys/device.h>
   67 
   68 #include <machine/bus.h>
   69 #include <machine/intr.h>
   70 
   71 #include <dev/eisa/eisavar.h>
   72 #include <dev/eisa/eisadevs.h>
   73 
   74 #include <scsi/scsi_all.h>
   75 #include <scsi/scsi_disk.h>
   76 #include <scsi/scsiconf.h>
   77 
   78 #include <dev/ic/cacreg.h>
   79 #include <dev/ic/cacvar.h>
   80 
   81 #define CAC_EISA_SLOT_OFFSET            0x0c88
   82 #define CAC_EISA_IOSIZE                 0x0017
   83 #define CAC_EISA_IOCONF                 0x38
   84 
   85 int     cac_eisa_match(struct device *, void *, void *);
   86 void    cac_eisa_attach(struct device *, struct device *, void *);
   87 
   88 struct  cac_ccb *cac_eisa_l0_completed(struct cac_softc *);
   89 int     cac_eisa_l0_fifo_full(struct cac_softc *);
   90 void    cac_eisa_l0_intr_enable(struct cac_softc *, int);
   91 int     cac_eisa_l0_intr_pending(struct cac_softc *);
   92 void    cac_eisa_l0_submit(struct cac_softc *, struct cac_ccb *);
   93 
   94 const struct cfattach cac_eisa_ca = {
   95         sizeof(struct cac_softc), cac_eisa_match, cac_eisa_attach
   96 };
   97 
   98 static const
   99 struct cac_linkage cac_eisa_l0 = {
  100         cac_eisa_l0_completed,
  101         cac_eisa_l0_fifo_full,
  102         cac_eisa_l0_intr_enable,
  103         cac_eisa_l0_intr_pending,
  104         cac_eisa_l0_submit
  105 };
  106 
  107 static const
  108 struct cac_eisa_type {
  109         const char      *ct_prodstr;
  110         const char      *ct_typestr;
  111         const struct    cac_linkage *ct_linkage;
  112 } cac_eisa_type[] = {
  113         { "CPQ4001",    "IDA",          &cac_eisa_l0 },
  114         { "CPQ4002",    "IDA-2",        &cac_eisa_l0 },
  115         { "CPQ4010",    "IEAS",         &cac_eisa_l0 },
  116         { "CPQ4020",    "SMART",        &cac_eisa_l0 },
  117         { "CPQ4030",    "SMART-2/E",    &cac_l0 },
  118 };
  119 
  120 int
  121 cac_eisa_match(struct device *parent, void *match, void *aux)
  122 {
  123         struct eisa_attach_args *ea;
  124         int i;
  125 
  126         ea = aux;
  127 
  128         for (i = 0; i < sizeof(cac_eisa_type) / sizeof(cac_eisa_type[0]); i++)
  129                 if (strcmp(ea->ea_idstring, cac_eisa_type[i].ct_prodstr) == 0)
  130                         return (1);
  131 
  132         return (0);
  133 }
  134 
  135 void
  136 cac_eisa_attach(struct device *parent, struct device *self, void *aux)
  137 {
  138         struct eisa_attach_args *ea;
  139         bus_space_handle_t ioh;
  140         eisa_chipset_tag_t ec;
  141         eisa_intr_handle_t ih;
  142         struct cac_softc *sc;
  143         bus_space_tag_t iot;
  144         const char *intrstr;
  145         int irq, i;
  146         
  147         ea = aux;
  148         sc = (struct cac_softc *)self;
  149         iot = ea->ea_iot;
  150         ec = ea->ea_ec;
  151         
  152         if (bus_space_map(iot, EISA_SLOT_ADDR(ea->ea_slot) +
  153             CAC_EISA_SLOT_OFFSET, CAC_EISA_IOSIZE, 0, &ioh)) {
  154                 printf(": can't map i/o space\n");
  155                 return;
  156         }
  157 
  158         /*
  159          * Print board type and attach to the bus-independent code.
  160          */
  161         for (i = 0; i < nitems(cac_eisa_type); i++)
  162                 if (strcmp(ea->ea_idstring, cac_eisa_type[i].ct_prodstr) == 0)
  163                         break;
  164 
  165         if (i == nitems(cac_eisa_type)) {
  166                 printf(": failed to attach %s\n", ea->ea_idstring);
  167                 return;
  168         }
  169 
  170         sc->sc_iot = iot;
  171         sc->sc_ioh = ioh;
  172         sc->sc_dmat = ea->ea_dmat;
  173 
  174         /* 
  175          * Map and establish the interrupt.
  176          */
  177         switch (bus_space_read_1(iot, ioh, CAC_EISA_IOCONF) & 0xf0) {
  178         case 0x20:
  179                 irq = 10;
  180                 break;
  181         case 0x10:
  182                 irq = 11;
  183                 break;
  184         case 0x40:
  185                 irq = 14;
  186                 break;
  187         case 0x80:
  188                 irq = 15;
  189                 break;
  190         default:
  191                 printf(": controller on invalid IRQ\n");
  192                 return;
  193         }
  194 
  195         if (eisa_intr_map(ec, irq, &ih)) {
  196                 printf(": can't map interrupt (%d)\n", irq);
  197                 return;
  198         }
  199         
  200         intrstr = eisa_intr_string(ec, ih);
  201         if ((sc->sc_ih = eisa_intr_establish(ec, ih, IST_LEVEL, IPL_BIO,
  202             cac_intr, sc, sc->sc_dv.dv_xname)) == NULL) {
  203                 printf(": can't establish interrupt");
  204                 if (intrstr != NULL)
  205                         printf(" at %s", intrstr);
  206                 printf("\n");
  207                 return;
  208         }
  209 
  210         printf(" %s: Compaq %s\n", intrstr, cac_eisa_type[i].ct_typestr);
  211         sc->sc_cl = cac_eisa_type[i].ct_linkage;
  212         cac_init(sc, 0);
  213 }
  214 
  215 /*
  216  * Linkage specific to EISA boards.
  217  */
  218 
  219 int
  220 cac_eisa_l0_fifo_full(struct cac_softc *sc)
  221 {
  222 
  223         return ((cac_inb(sc, CAC_EISAREG_SYSTEM_DOORBELL) &
  224             CAC_EISA_CHANNEL_CLEAR) == 0);
  225 }
  226 
  227 void
  228 cac_eisa_l0_submit(struct cac_softc *sc, struct cac_ccb *ccb)
  229 {
  230         u_int16_t size;
  231 
  232         /*
  233          * On these boards, `ccb_hdr.size' is actually for control flags.
  234          * Set it to zero and pass the value by means of an I/O port.
  235          */
  236         size = letoh16(ccb->ccb_hdr.size) << 2;
  237         ccb->ccb_hdr.size = 0;
  238 
  239         bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, (caddr_t)ccb - sc->sc_ccbs,
  240             sizeof(struct cac_ccb), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  241 
  242         cac_outb(sc, CAC_EISAREG_SYSTEM_DOORBELL, CAC_EISA_CHANNEL_CLEAR);
  243         cac_outl(sc, CAC_EISAREG_LIST_ADDR, ccb->ccb_paddr);
  244         cac_outw(sc, CAC_EISAREG_LIST_LEN, size);
  245         cac_outb(sc, CAC_EISAREG_LOCAL_DOORBELL, CAC_EISA_CHANNEL_BUSY);
  246 }
  247 
  248 struct cac_ccb *
  249 cac_eisa_l0_completed(struct cac_softc *sc)
  250 {
  251         struct cac_ccb *ccb;
  252         u_int32_t off;
  253         u_int8_t status;
  254 
  255         if ((cac_inb(sc, CAC_EISAREG_SYSTEM_DOORBELL) &
  256             CAC_EISA_CHANNEL_BUSY) == 0)
  257                 return (NULL);
  258 
  259         cac_outb(sc, CAC_EISAREG_SYSTEM_DOORBELL, CAC_EISA_CHANNEL_BUSY);
  260         off = cac_inl(sc, CAC_EISAREG_COMPLETE_ADDR);
  261         status = cac_inb(sc, CAC_EISAREG_LIST_STATUS);
  262         cac_outb(sc, CAC_EISAREG_LOCAL_DOORBELL, CAC_EISA_CHANNEL_CLEAR);
  263 
  264         if (off == 0)
  265                 return (NULL);
  266 
  267         off = (off & ~3) - sc->sc_ccbs_paddr;
  268         ccb = (struct cac_ccb *)(sc->sc_ccbs + off);
  269 
  270         bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, off, sizeof(struct cac_ccb),
  271             BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
  272 
  273         ccb->ccb_req.error = status;
  274         return (ccb);
  275 }
  276 
  277 int
  278 cac_eisa_l0_intr_pending(struct cac_softc *sc)
  279 {
  280 
  281         return (cac_inb(sc, CAC_EISAREG_SYSTEM_DOORBELL) &
  282             CAC_EISA_CHANNEL_BUSY);
  283 }
  284 
  285 void
  286 cac_eisa_l0_intr_enable(struct cac_softc *sc, int state)
  287 {
  288 
  289         if (state) {
  290                 cac_outb(sc, CAC_EISAREG_SYSTEM_DOORBELL,
  291                     ~CAC_EISA_CHANNEL_CLEAR);
  292                 cac_outb(sc, CAC_EISAREG_LOCAL_DOORBELL,
  293                     CAC_EISA_CHANNEL_BUSY);
  294                 cac_outb(sc, CAC_EISAREG_INTR_MASK, CAC_INTR_ENABLE);
  295                 cac_outb(sc, CAC_EISAREG_SYSTEM_MASK, CAC_INTR_ENABLE);
  296         } else
  297                 cac_outb(sc, CAC_EISAREG_SYSTEM_MASK, CAC_INTR_DISABLE);
  298 }

Cache object: 1fbad95ba9a74817b6859924844ae402


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