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/bi/kdb.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 /*      $NetBSD: kdb.c,v 1.34 2003/11/04 23:19:12 he Exp $ */
    2 /*
    3  * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
    4  * All rights reserved.
    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  *    notice, this list of conditions and the following disclaimer.
   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  * 3. All advertising materials mentioning features or use of this software
   15  *    must display the following acknowledgement:
   16  *      This product includes software developed at Ludd, University of 
   17  *      Lule}, Sweden and its contributors.
   18  * 4. The name of the author may not be used to endorse or promote products
   19  *    derived from this software without specific prior written permission
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 /*
   34  * KDB50 disk device driver
   35  */
   36 /*
   37  * TODO
   38  *   Implement node reset routine.
   39  *   Nices hardware error handling.
   40  */
   41 
   42 #include <sys/cdefs.h>
   43 __KERNEL_RCSID(0, "$NetBSD: kdb.c,v 1.34 2003/11/04 23:19:12 he Exp $");
   44 
   45 #include <sys/param.h>
   46 #include <sys/kernel.h>
   47 #include <sys/buf.h>
   48 #include <sys/device.h>
   49 #include <sys/proc.h>
   50 #include <sys/user.h>
   51 #include <sys/malloc.h>
   52 #include <sys/systm.h>
   53 #include <sys/sched.h>
   54 
   55 #include <uvm/uvm_extern.h>
   56 
   57 #ifdef __vax__
   58 #include <machine/pte.h>
   59 #include <machine/pcb.h>
   60 #endif
   61 #include <machine/bus.h>
   62 
   63 #include <dev/bi/bireg.h>
   64 #include <dev/bi/bivar.h>
   65 #include <dev/bi/kdbreg.h>
   66 
   67 #include <dev/mscp/mscp.h>
   68 #include <dev/mscp/mscpreg.h>
   69 #include <dev/mscp/mscpvar.h>
   70 
   71 #include "locators.h"
   72 
   73 #define KDB_WL(adr, val) bus_space_write_4(sc->sc_iot, sc->sc_ioh, adr, val)
   74 #define KDB_RL(adr) bus_space_read_4(sc->sc_iot, sc->sc_ioh, adr)
   75 #define KDB_RS(adr) bus_space_read_2(sc->sc_iot, sc->sc_ioh, adr)
   76 
   77 #define     b_forw  b_hash.le_next
   78 /*
   79  * Software status, per controller.
   80  */
   81 struct  kdb_softc {
   82         struct  device sc_dev;          /* Autoconfig info */
   83         struct  evcnt sc_intrcnt;       /* Interrupt counting */
   84         caddr_t sc_kdb;                 /* Struct for kdb communication */
   85         struct  mscp_softc *sc_softc;   /* MSCP info (per mscpvar.h) */
   86         bus_dma_tag_t sc_dmat;
   87         bus_dmamap_t sc_cmap;           /* Control structures */
   88         bus_space_tag_t sc_iot;
   89         bus_space_handle_t sc_ioh;
   90 };
   91 
   92 int     kdbmatch __P((struct device *, struct cfdata *, void *));
   93 void    kdbattach __P((struct device *, struct device *, void *));
   94 void    kdbreset __P((int));
   95 void    kdbintr __P((void *));
   96 void    kdbctlrdone __P((struct device *));
   97 int     kdbprint __P((void *, const char *));
   98 void    kdbsaerror __P((struct device *, int));
   99 void    kdbgo __P((struct device *, struct mscp_xi *));
  100 
  101 CFATTACH_DECL(kdb, sizeof(struct kdb_softc),
  102     kdbmatch, kdbattach, NULL, NULL);
  103 
  104 /*
  105  * More driver definitions, for generic MSCP code.
  106  */
  107 struct  mscp_ctlr kdb_mscp_ctlr = {
  108         kdbctlrdone,
  109         kdbgo,
  110         kdbsaerror,
  111 };
  112 
  113 int
  114 kdbprint(aux, name)
  115         void    *aux;
  116         const char      *name;
  117 {
  118         if (name)
  119                 aprint_normal("%s: mscpbus", name);
  120         return UNCONF;
  121 }
  122 
  123 /*
  124  * Poke at a supposed KDB to see if it is there.
  125  */
  126 int
  127 kdbmatch(parent, cf, aux)
  128         struct  device *parent;
  129         struct  cfdata *cf;
  130         void    *aux;
  131 {
  132         struct bi_attach_args *ba = aux;
  133 
  134         if (bus_space_read_2(ba->ba_iot, ba->ba_ioh, BIREG_DTYPE) != BIDT_KDB50)
  135                 return 0;
  136 
  137         if (cf->cf_loc[BICF_NODE] != BICF_NODE_DEFAULT &&
  138             cf->cf_loc[BICF_NODE] != ba->ba_nodenr)
  139                 return 0;
  140 
  141         return 1;
  142 }
  143 
  144 void
  145 kdbattach(parent, self, aux)
  146         struct device *parent, *self;
  147         void *aux;
  148 {
  149         struct  kdb_softc *sc = (void *)self;
  150         struct  bi_attach_args *ba = aux;
  151         struct  mscp_attach_args ma;
  152         volatile int i = 10000;
  153         int error, rseg;
  154         bus_dma_segment_t seg;
  155 
  156         printf("\n");
  157         bi_intr_establish(ba->ba_icookie, ba->ba_ivec,
  158                 kdbintr, sc, &sc->sc_intrcnt);
  159         evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
  160                 sc->sc_dev.dv_xname, "intr");
  161 
  162         sc->sc_iot = ba->ba_iot;
  163         sc->sc_ioh = ba->ba_ioh;
  164         sc->sc_dmat = ba->ba_dmat;
  165 
  166         /*
  167          * Map the communication area and command and
  168          * response packets into Unibus space.
  169          */
  170         if ((error = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct mscp_pack),
  171             PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
  172                 printf("Alloc ctrl area %d\n", error);
  173                 return;
  174         }
  175         if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
  176             sizeof(struct mscp_pack), &sc->sc_kdb,
  177             BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
  178                 printf("Map ctrl area %d\n", error);
  179 err:            bus_dmamem_free(sc->sc_dmat, &seg, rseg);
  180                 return;
  181         }
  182         if ((error = bus_dmamap_create(sc->sc_dmat, sizeof(struct mscp_pack),
  183             1, sizeof(struct mscp_pack), 0, BUS_DMA_NOWAIT, &sc->sc_cmap))) {
  184                 printf("Create DMA map %d\n", error);
  185 err2:           bus_dmamem_unmap(sc->sc_dmat, sc->sc_kdb,
  186                     sizeof(struct mscp_pack));
  187                 goto err;
  188         }
  189         if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cmap, 
  190             sc->sc_kdb, sizeof(struct mscp_pack), 0, BUS_DMA_NOWAIT))) {
  191                 printf("Load ctrl map %d\n", error);
  192                 bus_dmamap_destroy(sc->sc_dmat, sc->sc_cmap);
  193                 goto err2;
  194         }
  195         memset(sc->sc_kdb, 0, sizeof(struct mscp_pack));
  196 
  197         ma.ma_mc = &kdb_mscp_ctlr;
  198         ma.ma_type = MSCPBUS_DISK|MSCPBUS_KDB;
  199         ma.ma_uda = (struct mscp_pack *)sc->sc_kdb;
  200         ma.ma_softc = &sc->sc_softc;
  201         ma.ma_iot = sc->sc_iot;
  202         ma.ma_iph = sc->sc_ioh + KDB_IP;
  203         ma.ma_sah = sc->sc_ioh + KDB_SA;
  204         ma.ma_swh = sc->sc_ioh + KDB_SW;
  205         ma.ma_dmat = sc->sc_dmat;
  206         ma.ma_dmam = sc->sc_cmap;
  207         ma.ma_ivec = ba->ba_ivec;
  208         ma.ma_ctlrnr = ba->ba_nodenr;
  209         ma.ma_adapnr = ba->ba_busnr;
  210 
  211         KDB_WL(BIREG_VAXBICSR, KDB_RL(BIREG_VAXBICSR) | BICSR_NRST);
  212         while (i--) /* Need delay??? */
  213                 ;
  214         KDB_WL(BIREG_INTRDES, ba->ba_intcpu); /* Interrupt on CPU # */
  215         KDB_WL(BIREG_BCICSR, KDB_RL(BIREG_BCICSR) |
  216             BCI_STOPEN | BCI_IDENTEN | BCI_UINTEN | BCI_INTEN);
  217         KDB_WL(BIREG_UINTRCSR, ba->ba_ivec);
  218         config_found(&sc->sc_dev, &ma, kdbprint);
  219 }
  220 
  221 void
  222 kdbgo(usc, mxi)
  223         struct device *usc;
  224         struct mscp_xi *mxi;
  225 {
  226         struct kdb_softc *sc = (void *)usc;
  227         struct buf *bp = mxi->mxi_bp;
  228         struct mscp *mp = mxi->mxi_mp;
  229         u_int32_t addr = (u_int32_t)bp->b_data;
  230         u_int32_t mapaddr;
  231         int err;
  232 
  233         /*
  234          * The KDB50 wants to read VAX Page tables directly, therefore
  235          * the result from bus_dmamap_load() is uninteresting. (But it
  236          * should never fail!).
  237          *
  238          * On VAX, point to the corresponding page tables. (user/sys)
  239          * On other systems, do something else... 
  240          */
  241         err = bus_dmamap_load(sc->sc_dmat, mxi->mxi_dmam, bp->b_data,
  242             bp->b_bcount, (bp->b_flags & B_PHYS ? bp->b_proc : 0),
  243             BUS_DMA_NOWAIT);
  244 
  245         if (err) /* Shouldn't happen */
  246                 panic("kdbgo: bus_dmamap_load: error %d", err);
  247 
  248 #ifdef __vax__
  249         /*
  250          * Get a pointer to the pte pointing out the first virtual address.
  251          * Use different ways in kernel and user space.
  252          */
  253         if ((bp->b_flags & B_PHYS) == 0) {
  254                 mapaddr = ((u_int32_t)kvtopte(addr)) & ~KERNBASE;
  255         } else {
  256 
  257 /* XXX: This code does not belong here! */
  258 #define UVTOPTE(addr, pmap) (((addr) < 0x40000000) ? \
  259     &(*pmap)->pm_p0br[PG_PFNUM(addr)] : &(*pmap)->pm_p1br[PG_PFNUM(addr)])
  260 
  261                 pmap_t *pmap = &bp->b_proc->p_vmspace->vm_map.pmap;
  262                 u_int32_t eaddr = addr + (bp->b_bcount - 1);
  263                 u_int32_t emapaddr = (u_int32_t)UVTOPTE(eaddr, pmap);
  264 
  265                 mapaddr = (u_int32_t)UVTOPTE(addr, pmap);
  266                 if (trunc_page(mapaddr) != trunc_page(emapaddr)) {
  267                         mp->mscp_seq.seq_bytecount =
  268                             (((round_page(mapaddr) - mapaddr)/4) * 512);
  269                 }
  270                 mapaddr = kvtophys(mapaddr);
  271         }
  272 #else
  273 #error Must write code to handle KDB50 on non-vax.
  274 #endif
  275 
  276         mp->mscp_seq.seq_mapbase = mapaddr;
  277         mxi->mxi_dmam->dm_segs[0].ds_addr = (addr & 511) | KDB_MAP;
  278         mscp_dgo(sc->sc_softc, mxi);
  279 }
  280 
  281 void
  282 kdbsaerror(usc, doreset)
  283         struct device *usc;
  284         int doreset;
  285 {
  286         struct  kdb_softc *sc = (void *)usc;
  287 
  288         if ((KDB_RS(KDB_SA) & MP_ERR) == 0)
  289                 return;
  290         printf("%s: controller error, sa=0x%x\n", sc->sc_dev.dv_xname,
  291             KDB_RS(KDB_SA));
  292         /* What to do now??? */
  293 }
  294 
  295 /*
  296  * Interrupt routine.  Depending on the state of the controller,
  297  * continue initialisation, or acknowledge command and response
  298  * interrupts, and process responses.
  299  */
  300 void
  301 kdbintr(void *arg)
  302 {
  303         struct kdb_softc *sc = arg;
  304 
  305         if (KDB_RS(KDB_SA) & MP_ERR) {  /* ctlr fatal error */
  306                 kdbsaerror(&sc->sc_dev, 1);
  307                 return;
  308         }
  309         KERNEL_LOCK(LK_CANRECURSE|LK_EXCLUSIVE);
  310         mscp_intr(sc->sc_softc);
  311         KERNEL_UNLOCK();
  312 }
  313 
  314 #ifdef notyet
  315 /*
  316  * The KDB50 has been reset.  Reinitialise the controller
  317  * and requeue outstanding I/O.
  318  */
  319 void
  320 kdbreset(ctlr)
  321         int ctlr;
  322 {
  323         struct kdb_softc *sc;
  324 
  325         sc = kdb_cd.cd_devs[ctlr];
  326         printf(" kdb%d", ctlr);
  327 
  328 
  329         /* reset queues and requeue pending transfers */
  330         mscp_requeue(sc->sc_softc);
  331 
  332         /*
  333          * If it fails to initialise we will notice later and
  334          * try again (and again...).  Do not call kdbstart()
  335          * here; it will be done after the controller finishes
  336          * initialisation.
  337          */
  338         if (kdbinit(sc))
  339                 printf(" (hung)");
  340 }
  341 #endif
  342 
  343 void
  344 kdbctlrdone(usc)
  345         struct device *usc;
  346 {
  347 }

Cache object: b2fae475ca5d14a8c27d2f63a6c07662


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