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/tc/tc.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: tc.c,v 1.36 2003/09/26 17:17:47 tsutsui Exp $  */
    2 
    3 /*
    4  * Copyright (c) 1994, 1995 Carnegie-Mellon University.
    5  * All rights reserved.
    6  *
    7  * Author: Chris G. Demetriou
    8  *
    9  * Permission to use, copy, modify and distribute this software and
   10  * its documentation is hereby granted, provided that both the copyright
   11  * notice and this permission notice appear in all copies of the
   12  * software, derivative works or modified versions, and any portions
   13  * thereof, and that both notices appear in supporting documentation.
   14  *
   15  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   16  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
   17  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   18  *
   19  * Carnegie Mellon requests users of this software to return to
   20  *
   21  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   22  *  School of Computer Science
   23  *  Carnegie Mellon University
   24  *  Pittsburgh PA 15213-3890
   25  *
   26  * any improvements or extensions that they make and grant Carnegie the
   27  * rights to redistribute these changes.
   28  */
   29 
   30 #include <sys/cdefs.h>
   31 __KERNEL_RCSID(0, "$NetBSD: tc.c,v 1.36 2003/09/26 17:17:47 tsutsui Exp $");
   32 
   33 #include "opt_tcverbose.h"
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #include <sys/device.h>
   38 
   39 #include <dev/tc/tcreg.h>
   40 #include <dev/tc/tcvar.h>
   41 #include <dev/tc/tcdevs.h>
   42 
   43 
   44 /* Definition of the driver for autoconfig. */
   45 int     tcmatch __P((struct device *, struct cfdata *, void *));
   46 void    tcattach __P((struct device *, struct device *, void *));
   47 
   48 CFATTACH_DECL(tc, sizeof(struct tc_softc),
   49     tcmatch, tcattach, NULL, NULL);
   50 
   51 extern struct cfdriver tc_cd;
   52 
   53 int     tcprint __P((void *, const char *));
   54 int     tcsubmatch __P((struct device *, struct cfdata *, void *));
   55 int     tc_checkslot __P((tc_addr_t, char *));
   56 void    tc_devinfo __P((const char *, char *));
   57 
   58 int
   59 tcmatch(parent, cf, aux)
   60         struct device *parent;
   61         struct cfdata *cf;
   62         void *aux;
   63 {
   64         struct tcbus_attach_args *tba = aux;
   65 
   66         if (strcmp(tba->tba_busname, cf->cf_name))
   67                 return (0);
   68 
   69         return (1);
   70 }
   71 
   72 void
   73 tcattach(parent, self, aux)
   74         struct device *parent;
   75         struct device *self;
   76         void *aux;
   77 {
   78         struct tc_softc *sc = (struct tc_softc *)self;
   79         struct tcbus_attach_args *tba = aux;
   80         struct tc_attach_args ta;
   81         const struct tc_builtin *builtin;
   82         struct tc_slotdesc *slot;
   83         tc_addr_t tcaddr;
   84         int i;
   85 
   86         printf(": %s MHz clock\n",
   87             tba->tba_speed == TC_SPEED_25_MHZ ? "25" : "12.5");
   88 
   89         /*
   90          * Save important CPU/chipset information.
   91          */
   92         sc->sc_speed = tba->tba_speed;
   93         sc->sc_nslots = tba->tba_nslots;
   94         sc->sc_slots = tba->tba_slots;
   95         sc->sc_intr_evcnt = tba->tba_intr_evcnt;
   96         sc->sc_intr_establish = tba->tba_intr_establish;
   97         sc->sc_intr_disestablish = tba->tba_intr_disestablish;
   98         sc->sc_get_dma_tag = tba->tba_get_dma_tag;
   99 
  100         /*
  101          * Try to configure each built-in device
  102          */
  103         for (i = 0; i < tba->tba_nbuiltins; i++) {
  104                 builtin = &tba->tba_builtins[i];
  105 
  106                 /* sanity check! */
  107                 if (builtin->tcb_slot > sc->sc_nslots)
  108                         panic("tcattach: builtin %d slot > nslots", i);
  109 
  110                 /*
  111                  * Make sure device is really there, because some
  112                  * built-in devices are really optional.
  113                  */
  114                 tcaddr = sc->sc_slots[builtin->tcb_slot].tcs_addr +
  115                     builtin->tcb_offset;
  116                 if (tc_badaddr(tcaddr))
  117                         continue;
  118 
  119                 /*
  120                  * Set up the device attachment information.
  121                  */
  122                 strncpy(ta.ta_modname, builtin->tcb_modname, TC_ROM_LLEN);
  123                 ta.ta_memt = tba->tba_memt;
  124                 ta.ta_dmat = (*sc->sc_get_dma_tag)(builtin->tcb_slot);
  125                 ta.ta_modname[TC_ROM_LLEN] = '\0';
  126                 ta.ta_slot = builtin->tcb_slot;
  127                 ta.ta_offset = builtin->tcb_offset;
  128                 ta.ta_addr = tcaddr;
  129                 ta.ta_cookie = builtin->tcb_cookie;
  130                 ta.ta_busspeed = sc->sc_speed;
  131 
  132                 /*
  133                  * Mark the slot as used, so we don't check it later.
  134                  */
  135                 sc->sc_slots[builtin->tcb_slot].tcs_used = 1;
  136 
  137                 /*
  138                  * Attach the device.
  139                  */
  140                 config_found_sm(self, &ta, tcprint, tcsubmatch);
  141         }
  142 
  143         /*
  144          * Try to configure each unused slot, last to first.
  145          */
  146         for (i = sc->sc_nslots - 1; i >= 0; i--) {
  147                 slot = &sc->sc_slots[i];
  148 
  149                 /* If already checked above, don't look again now. */
  150                 if (slot->tcs_used)
  151                         continue;
  152 
  153                 /*
  154                  * Make sure something is there, and find out what it is.
  155                  */
  156                 tcaddr = slot->tcs_addr;
  157                 if (tc_badaddr(tcaddr))
  158                         continue;
  159                 if (tc_checkslot(tcaddr, ta.ta_modname) == 0)
  160                         continue;
  161 
  162                 /*
  163                  * Set up the rest of the attachment information.
  164                  */
  165                 ta.ta_memt = tba->tba_memt;
  166                 ta.ta_dmat = (*sc->sc_get_dma_tag)(i);
  167                 ta.ta_slot = i;
  168                 ta.ta_offset = 0;
  169                 ta.ta_addr = tcaddr;
  170                 ta.ta_cookie = slot->tcs_cookie;
  171 
  172                 /*
  173                  * Mark the slot as used.
  174                  */
  175                 slot->tcs_used = 1;
  176 
  177                 /*
  178                  * Attach the device.
  179                  */
  180                 config_found_sm(self, &ta, tcprint, tcsubmatch);
  181         }
  182 }
  183 
  184 int
  185 tcprint(aux, pnp)
  186         void *aux;
  187         const char *pnp;
  188 {
  189         struct tc_attach_args *ta = aux;
  190         char devinfo[256];
  191 
  192         if (pnp) {
  193                 tc_devinfo(ta->ta_modname, devinfo);
  194                 aprint_normal("%s at %s", devinfo, pnp);
  195         }
  196         aprint_normal(" slot %d offset 0x%x", ta->ta_slot, ta->ta_offset);
  197         return (UNCONF);
  198 }
  199 
  200 int
  201 tcsubmatch(parent, cf, aux)
  202         struct device *parent;
  203         struct cfdata *cf;
  204         void *aux;
  205 {
  206         struct tc_attach_args *d = aux;
  207 
  208         if ((cf->tccf_slot != TCCF_SLOT_UNKNOWN) &&
  209             (cf->tccf_slot != d->ta_slot))
  210                 return 0;
  211         if ((cf->tccf_offset != TCCF_SLOT_UNKNOWN) &&
  212             (cf->tccf_offset != d->ta_offset))
  213                 return 0;
  214 
  215         return (config_match(parent, cf, aux));
  216 }
  217 
  218 
  219 #define NTC_ROMOFFS     2
  220 static tc_offset_t tc_slot_romoffs[NTC_ROMOFFS] = {
  221         TC_SLOT_ROM,
  222         TC_SLOT_PROTOROM,
  223 };
  224 
  225 int
  226 tc_checkslot(slotbase, namep)
  227         tc_addr_t slotbase;
  228         char *namep;
  229 {
  230         struct tc_rommap *romp;
  231         int i, j;
  232 
  233         for (i = 0; i < NTC_ROMOFFS; i++) {
  234                 romp = (struct tc_rommap *)
  235                     (slotbase + tc_slot_romoffs[i]);
  236 
  237                 switch (romp->tcr_width.v) {
  238                 case 1:
  239                 case 2:
  240                 case 4:
  241                         break;
  242 
  243                 default:
  244                         continue;
  245                 }
  246 
  247                 if (romp->tcr_stride.v != 4)
  248                         continue;
  249 
  250                 for (j = 0; j < 4; j++)
  251                         if (romp->tcr_test[j+0*romp->tcr_stride.v] != 0x55 ||
  252                             romp->tcr_test[j+1*romp->tcr_stride.v] != 0x00 ||
  253                             romp->tcr_test[j+2*romp->tcr_stride.v] != 0xaa ||
  254                             romp->tcr_test[j+3*romp->tcr_stride.v] != 0xff)
  255                                 continue;
  256 
  257                 for (j = 0; j < TC_ROM_LLEN; j++)
  258                         namep[j] = romp->tcr_modname[j].v;
  259                 namep[j] = '\0';
  260                 return (1);
  261         }
  262         return (0);
  263 }
  264 
  265 const struct evcnt *
  266 tc_intr_evcnt(struct device *dev, void *cookie)
  267 {
  268         struct tc_softc *sc = tc_cd.cd_devs[0];
  269 
  270         return ((*sc->sc_intr_evcnt)(dev, cookie));
  271 }
  272 
  273 void
  274 tc_intr_establish(dev, cookie, level, handler, arg)
  275         struct device *dev;
  276         void *cookie, *arg;
  277         int level;
  278         int (*handler) __P((void *));
  279 {
  280         struct tc_softc *sc = tc_cd.cd_devs[0];
  281 
  282         (*sc->sc_intr_establish)(dev, cookie, level, handler, arg);
  283 }
  284 
  285 void
  286 tc_intr_disestablish(dev, cookie)
  287         struct device *dev;
  288         void *cookie;
  289 {
  290         struct tc_softc *sc = tc_cd.cd_devs[0];
  291 
  292         (*sc->sc_intr_disestablish)(dev, cookie);
  293 }
  294 
  295 #ifdef TCVERBOSE
  296 /*
  297  * Descriptions of of known devices.
  298  */
  299 struct tc_knowndev {
  300         const char *id, *driver, *description;
  301 };
  302 
  303 #include <dev/tc/tcdevs_data.h>
  304 #endif /* TCVERBOSE */
  305 
  306 void
  307 tc_devinfo(id, cp)
  308         const char *id;
  309         char *cp;
  310 {
  311         const char *driver, *description;
  312 #ifdef TCVERBOSE
  313         struct tc_knowndev *tdp;
  314         int match;
  315         const char *unmatched = "unknown ";
  316 #else
  317         const char *unmatched = "";
  318 #endif
  319 
  320         driver = NULL;
  321         description = id;
  322 
  323 #ifdef TCVERBOSE
  324         /* find the device in the table, if possible. */
  325         tdp = tc_knowndevs;
  326         while (tdp->id != NULL) {
  327                 /* check this entry for a match */
  328                 match = !strcmp(tdp->id, id);
  329                 if (match) {
  330                         driver = tdp->driver;
  331                         description = tdp->description;
  332                         break;
  333                 }
  334                 tdp++;
  335         }
  336 #endif
  337 
  338         if (driver == NULL)
  339                 cp += sprintf(cp, "%sdevice %s", unmatched, id);
  340         else
  341                 cp += sprintf(cp, "%s (%s)", driver, description);
  342 }

Cache object: 7f5d1a6ae9a99e9be2a5a5a7ea6ee2e5


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