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/ofisa/ofisa.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: ofisa.c,v 1.13 2003/01/01 00:10:22 thorpej Exp $       */
    2 
    3 /*
    4  * Copyright 1997, 1998
    5  * Digital Equipment Corporation. All rights reserved.
    6  *
    7  * This software is furnished under license and may be used and
    8  * copied only in accordance with the following terms and conditions.
    9  * Subject to these conditions, you may download, copy, install,
   10  * use, modify and distribute this software in source and/or binary
   11  * form. No title or ownership is transferred hereby.
   12  *
   13  * 1) Any source code used, modified or distributed must reproduce
   14  *    and retain this copyright notice and list of conditions as
   15  *    they appear in the source file.
   16  *
   17  * 2) No right is granted to use any trade name, trademark, or logo of
   18  *    Digital Equipment Corporation. Neither the "Digital Equipment
   19  *    Corporation" name nor any trademark or logo of Digital Equipment
   20  *    Corporation may be used to endorse or promote products derived
   21  *    from this software without the prior written permission of
   22  *    Digital Equipment Corporation.
   23  *
   24  * 3) This software is provided "AS-IS" and any express or implied
   25  *    warranties, including but not limited to, any implied warranties
   26  *    of merchantability, fitness for a particular purpose, or
   27  *    non-infringement are disclaimed. In no event shall DIGITAL be
   28  *    liable for any damages whatsoever, and in particular, DIGITAL
   29  *    shall not be liable for special, indirect, consequential, or
   30  *    incidental damages or damages for lost profits, loss of
   31  *    revenue or loss of use, whether such damages arise in contract,
   32  *    negligence, tort, under statute, in equity, at law or otherwise,
   33  *    even if advised of the possibility of such damage.
   34  */
   35 
   36 #include <sys/cdefs.h>
   37 __KERNEL_RCSID(0, "$NetBSD: ofisa.c,v 1.13 2003/01/01 00:10:22 thorpej Exp $");
   38 
   39 #include <sys/param.h>
   40 #include <sys/systm.h>
   41 #include <sys/device.h>
   42 #include <sys/malloc.h>
   43 #include <machine/bus.h>
   44 #include <machine/intr.h>
   45 
   46 #include <dev/ofw/openfirm.h>
   47 #include <dev/isa/isavar.h>
   48 #include <dev/ofisa/ofisavar.h>
   49 
   50 #include "isadma.h"
   51 
   52 #define OFW_MAX_STACK_BUF_SIZE  256
   53 
   54 static int      ofisamatch __P((struct device *, struct cfdata *, void *));
   55 static void     ofisaattach __P((struct device *, struct device *, void *));
   56 
   57 CFATTACH_DECL(ofisa, sizeof(struct device),
   58     ofisamatch, ofisaattach, NULL, NULL);
   59 
   60 extern struct cfdriver ofisa_cd;
   61 
   62 static int      ofisaprint __P((void *, const char *));
   63 
   64 static int
   65 ofisaprint(aux, pnp)
   66         void *aux;
   67         const char *pnp;
   68 {
   69         struct ofbus_attach_args *oba = aux;
   70         char name[64];
   71 
   72         (void)of_packagename(oba->oba_phandle, name, sizeof name);
   73         if (pnp)
   74                 aprint_normal("%s at %s", name, pnp);
   75         else
   76                 aprint_normal(" (%s)", name);
   77         return UNCONF;
   78 }
   79 
   80 int
   81 ofisamatch(parent, cf, aux)
   82         struct device *parent;
   83         struct cfdata *cf;
   84         void *aux;
   85 {
   86         struct ofbus_attach_args *oba = aux;
   87         static const char *const compatible_strings[] = { "pnpPNP,a00", NULL };
   88         int rv = 0;
   89 
   90         if (of_compatible(oba->oba_phandle, compatible_strings) != -1)
   91                 rv = 5;
   92 
   93 #ifdef _OFISA_MD_MATCH
   94         if (!rv)
   95                 rv = ofisa_md_match(parent, cf, aux);
   96 #endif
   97 
   98         return (rv);
   99 }
  100 
  101 void
  102 ofisaattach(parent, self, aux)
  103         struct device *parent, *self;
  104         void *aux;
  105 {
  106         struct ofbus_attach_args *oba = aux;
  107         struct isabus_attach_args iba;
  108         struct ofisa_attach_args aa;
  109         int child;
  110 
  111         if (ofisa_get_isabus_data(oba->oba_phandle, &iba) < 0) {
  112                 printf(": couldn't get essential bus data\n");
  113                 return;
  114         }
  115 
  116         printf("\n");
  117 
  118 #if NISADMA > 0
  119         /*
  120          * Initialize our DMA state.
  121          */
  122         isa_dmainit(iba.iba_ic, iba.iba_iot, iba.iba_dmat, self);
  123 #endif
  124 
  125         for (child = OF_child(oba->oba_phandle); child;
  126             child = OF_peer(child)) {
  127                 if (ofisa_ignore_child(oba->oba_phandle, child))
  128                         continue;
  129 
  130                 bzero(&aa, sizeof aa);
  131 
  132                 aa.oba.oba_busname = "ofw";                     /* XXX */
  133                 aa.oba.oba_phandle = child;
  134                 aa.iot = iba.iba_iot;
  135                 aa.memt = iba.iba_memt;
  136                 aa.dmat = iba.iba_dmat;
  137                 aa.ic = iba.iba_ic;
  138 
  139                 config_found(self, &aa, ofisaprint);
  140         }
  141 }
  142 
  143 int
  144 ofisa_reg_count(phandle)
  145         int phandle;
  146 {
  147         int len;
  148 
  149         len = OF_getproplen(phandle, "reg");
  150 
  151         /* nonexistent or obviously malformed "reg" property */
  152         if (len < 0 || (len % 12) != 0)
  153                 return (-1);
  154         return (len / 12);
  155 }
  156 
  157 int
  158 ofisa_reg_get(phandle, descp, ndescs)
  159         int phandle;
  160         struct ofisa_reg_desc *descp;
  161         int ndescs;
  162 {
  163         char *buf, *bp;
  164         int i, proplen, allocated, rv;
  165 
  166         i = ofisa_reg_count(phandle);
  167         if (i < 0)
  168                 return (-1);
  169         proplen = i * 12;
  170         ndescs = min(ndescs, i);
  171 
  172         i = ndescs * 12;
  173         if (i > OFW_MAX_STACK_BUF_SIZE) {
  174                 buf = malloc(i, M_TEMP, M_WAITOK);
  175                 allocated = 1;
  176         } else {
  177                 buf = alloca(i);
  178                 allocated = 0;
  179         }
  180 
  181         if (OF_getprop(phandle, "reg", buf, i) != proplen) {
  182                 rv = -1;
  183                 goto out;
  184         }
  185 
  186         for (i = 0, bp = buf; i < ndescs; i++, bp += 12) {
  187                 if (of_decode_int(&bp[0]) & 1)
  188                         descp[i].type = OFISA_REG_TYPE_IO;
  189                 else
  190                         descp[i].type = OFISA_REG_TYPE_MEM;
  191                 descp[i].addr = of_decode_int(&bp[4]);
  192                 descp[i].len = of_decode_int(&bp[8]);
  193         }
  194         rv = i;         /* number of descriptors processed (== ndescs) */
  195 
  196 out:
  197         if (allocated)
  198                 free(buf, M_TEMP);
  199         return (rv);
  200 }
  201 
  202 void
  203 ofisa_reg_print(descp, ndescs)
  204         struct ofisa_reg_desc *descp;
  205         int ndescs;
  206 {
  207         int i;
  208 
  209         if (ndescs == 0) {
  210                 printf("none");
  211                 return;
  212         }
  213 
  214         for (i = 0; i < ndescs; i++) {
  215                 printf("%s%s 0x%lx/%ld", i ? ", " : "",
  216                     descp[i].type == OFISA_REG_TYPE_IO ? "io" : "mem",
  217                     (long)descp[i].addr, (long)descp[i].len);
  218         }
  219 }
  220 
  221 int
  222 ofisa_intr_count(phandle)
  223         int phandle;
  224 {
  225         int len;
  226 
  227         len = OF_getproplen(phandle, "interrupts");
  228 
  229         /* nonexistent or obviously malformed "reg" property */
  230         if (len < 0 || (len % 8) != 0)
  231                 return (-1);
  232         return (len / 8);
  233 }
  234 
  235 int
  236 ofisa_intr_get(phandle, descp, ndescs)
  237         int phandle;
  238         struct ofisa_intr_desc *descp;
  239         int ndescs;
  240 {
  241         char *buf, *bp;
  242         int i, proplen, allocated, rv;
  243 
  244         i = ofisa_intr_count(phandle);
  245         if (i < 0)
  246                 return (-1);
  247         proplen = i * 8;
  248         ndescs = min(ndescs, i);
  249 
  250         i = ndescs * 8;
  251         if (i > OFW_MAX_STACK_BUF_SIZE) {
  252                 buf = malloc(i, M_TEMP, M_WAITOK);
  253                 allocated = 1;
  254         } else {
  255                 buf = alloca(i);
  256                 allocated = 0;
  257         }
  258 
  259         if (OF_getprop(phandle, "interrupts", buf, i) != proplen) {
  260                 rv = -1;
  261                 goto out;
  262         }
  263 
  264         for (i = 0, bp = buf; i < ndescs; i++, bp += 8) {
  265                 descp[i].irq = of_decode_int(&bp[0]);
  266                 switch (of_decode_int(&bp[4])) {
  267                 case 0:
  268                 case 1:
  269                         descp[i].share = IST_LEVEL;
  270                         break;
  271                 case 2:
  272                 case 3:
  273                         descp[i].share = IST_EDGE;
  274                         break;
  275 #ifdef DIAGNOSTIC
  276                 default:
  277                         /* Dunno what to do, so fail. */
  278                         printf("ofisa_intr_get: unknown intrerrupt type %d\n",
  279                             of_decode_int(&bp[4]));
  280                         rv = -1;
  281                         goto out;
  282 #endif
  283                 }
  284         }
  285         rv = i;         /* number of descriptors processed (== ndescs) */
  286 
  287 out:
  288         if (allocated)
  289                 free(buf, M_TEMP);
  290         return (rv);
  291 }
  292 
  293 void
  294 ofisa_intr_print(descp, ndescs)
  295         struct ofisa_intr_desc *descp;
  296         int ndescs;
  297 {
  298         int i;
  299 
  300         if (ndescs == 0) {
  301                 printf("none");
  302                 return;
  303         }
  304 
  305         for (i = 0; i < ndescs; i++) {
  306                 printf("%s%d (%s)", i ? ", " : "", descp[i].irq,
  307                     descp[i].share == IST_LEVEL ? "level" : "edge");
  308         }
  309 }
  310 
  311 int
  312 ofisa_dma_count(phandle)
  313         int phandle;
  314 {
  315         int len;
  316 
  317         len = OF_getproplen(phandle, "dma");
  318 
  319         /* nonexistent or obviously malformed "reg" property */
  320         if (len < 0 || (len % 20) != 0)
  321                 return (-1);
  322         return (len / 20);
  323 }
  324 
  325 int
  326 ofisa_dma_get(phandle, descp, ndescs)
  327         int phandle;
  328         struct ofisa_dma_desc *descp;
  329         int ndescs;
  330 {
  331         char *buf, *bp;
  332         int i, proplen, allocated, rv;
  333 
  334         i = ofisa_dma_count(phandle);
  335         if (i < 0)
  336                 return (-1);
  337         proplen = i * 20;
  338         ndescs = min(ndescs, i);
  339 
  340         i = ndescs * 20;
  341         if (i > OFW_MAX_STACK_BUF_SIZE) {
  342                 buf = malloc(i, M_TEMP, M_WAITOK);
  343                 allocated = 1;
  344         } else {
  345                 buf = alloca(i);
  346                 allocated = 0;
  347         }
  348 
  349         if (OF_getprop(phandle, "dma", buf, i) != proplen) {
  350                 rv = -1;
  351                 goto out;
  352         }
  353 
  354         for (i = 0, bp = buf; i < ndescs; i++, bp += 20) {
  355                 descp[i].drq = of_decode_int(&bp[0]);
  356                 descp[i].mode = of_decode_int(&bp[4]);
  357                 descp[i].width = of_decode_int(&bp[8]);
  358                 descp[i].countwidth = of_decode_int(&bp[12]);
  359                 descp[i].busmaster = of_decode_int(&bp[16]);
  360         }
  361         rv = i;         /* number of descriptors processed (== ndescs) */
  362 
  363 out:
  364         if (allocated)
  365                 free(buf, M_TEMP);
  366         return (rv);
  367 }
  368 
  369 void
  370 ofisa_dma_print(descp, ndescs)
  371         struct ofisa_dma_desc *descp;
  372         int ndescs;
  373 {
  374         char unkmode[16];
  375         const char *modestr;
  376         int i;
  377 
  378         if (ndescs == 0) {
  379                 printf("none");
  380                 return;
  381         }
  382 
  383         for (i = 0; i < ndescs; i++) {
  384                 switch (descp[i].mode) {
  385                 case OFISA_DMA_MODE_COMPAT:
  386                         modestr = "compat";
  387                         break;
  388                 case OFISA_DMA_MODE_A:
  389                         modestr = "A";
  390                         break;
  391                 case OFISA_DMA_MODE_B:
  392                         modestr = "B";
  393                         break;
  394                 case OFISA_DMA_MODE_F:
  395                         modestr = "F";
  396                         break;
  397                 case OFISA_DMA_MODE_C:
  398                         modestr = "C";
  399                         break;
  400                 default:
  401                         sprintf(unkmode, "??? (%d)", descp[i].mode);
  402                         modestr = unkmode;
  403                         break;
  404                 }
  405 
  406                 printf("%s%d %s mode %d-bit (%d-bit count)%s", i ? ", " : "",
  407                     descp[i].drq, modestr, descp[i].width,
  408                     descp[i].countwidth,
  409                     descp[i].busmaster ? " busmaster" : "");
  410 
  411         }
  412 }

Cache object: eab996399849fe657fea2d2160502427


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