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/eisaconf.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 /*
    2  * EISA bus probe and attach routines 
    3  *
    4  * Copyright (c) 1995, 1996 Justin T. Gibbs.
    5  * All rights reserved.
    6  * 
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice immediately at the beginning of the file, without modification,
   12  *    this list of conditions, and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. The name of the author may not be used to endorse or promote products
   17  *    derived from this software without specific prior written permission.
   18  * 
   19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND  
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
   23  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  *
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 __FBSDID("$FreeBSD: releng/5.2/sys/dev/eisa/eisaconf.c 119418 2003-08-24 17:55:58Z obrien $");
   35 
   36 #include "opt_eisa.h"
   37 
   38 #include <sys/param.h>
   39 #include <sys/systm.h>
   40 #include <sys/queue.h>
   41 #include <sys/limits.h>
   42 #include <sys/malloc.h>
   43 #include <sys/kernel.h>
   44 #include <sys/module.h>
   45 #include <sys/bus.h>
   46 
   47 #include <machine/bus.h>
   48 #include <machine/resource.h>
   49 #include <sys/rman.h>
   50 
   51 #include <dev/eisa/eisaconf.h>
   52 
   53 typedef struct resvaddr {
   54         u_long  addr;                           /* start address */
   55         u_long  size;                           /* size of reserved area */
   56         int     flags;
   57         struct resource *res;                   /* resource manager handle */
   58         LIST_ENTRY(resvaddr) links;             /* List links */
   59 } resvaddr_t;
   60 
   61 LIST_HEAD(resvlist, resvaddr);
   62 
   63 struct irq_node {
   64         int     irq_no;
   65         int     irq_trigger;
   66         void    *idesc;
   67         TAILQ_ENTRY(irq_node) links;
   68 };
   69 
   70 TAILQ_HEAD(irqlist, irq_node);
   71 
   72 struct eisa_ioconf {
   73         int             slot;
   74         struct resvlist ioaddrs;        /* list of reserved I/O ranges */
   75         struct resvlist maddrs;         /* list of reserved memory ranges */
   76         struct irqlist  irqs;           /* list of reserved irqs */
   77 };
   78 
   79 /* To be replaced by the "super device" generic device structure... */
   80 struct eisa_device {
   81         eisa_id_t               id;
   82         struct eisa_ioconf      ioconf;
   83 };
   84 
   85 
   86 #define MAX_COL         79
   87 #ifndef EISA_SLOTS
   88 #define EISA_SLOTS 10   /* PCI clashes with higher ones.. fix later */
   89 #endif
   90 int num_eisa_slots = EISA_SLOTS;
   91 TUNABLE_INT("hw.eisa_slots", &num_eisa_slots);
   92 
   93 static devclass_t eisa_devclass;
   94 
   95 static void eisa_reg_print (device_t, char *, char *, int *);
   96 static struct irq_node * eisa_find_irq(struct eisa_device *e_dev, int rid);
   97 static struct resvaddr * eisa_find_maddr(struct eisa_device *e_dev, int rid);
   98 static struct resvaddr * eisa_find_ioaddr(struct eisa_device *e_dev, int rid);
   99 
  100 static int
  101 mainboard_probe(device_t dev)
  102 {
  103         char *idstring;
  104         eisa_id_t id = eisa_get_id(dev);
  105 
  106         if (eisa_get_slot(dev) != 0)
  107                 return (ENXIO);
  108 
  109         idstring = (char *)malloc(8 + sizeof(" (System Board)") + 1,
  110                                   M_DEVBUF, M_NOWAIT);
  111         if (idstring == NULL) {
  112                 panic("Eisa probe unable to malloc");
  113         }
  114         sprintf(idstring, "%c%c%c%03x%01x (System Board)",
  115                 EISA_MFCTR_CHAR0(id),
  116                 EISA_MFCTR_CHAR1(id),
  117                 EISA_MFCTR_CHAR2(id),
  118                 EISA_PRODUCT_ID(id),
  119                 EISA_REVISION_ID(id));
  120         device_set_desc(dev, idstring);
  121 
  122         return (0);
  123 }
  124 
  125 static int
  126 mainboard_attach(device_t dev)
  127 {
  128         return (0);
  129 }
  130 
  131 static device_method_t mainboard_methods[] = {
  132         /* Device interface */
  133         DEVMETHOD(device_probe,         mainboard_probe),
  134         DEVMETHOD(device_attach,        mainboard_attach),
  135 
  136         { 0, 0 }
  137 };
  138 
  139 static driver_t mainboard_driver = {
  140         "mainboard",
  141         mainboard_methods,
  142         1,
  143 };
  144 
  145 static devclass_t mainboard_devclass;
  146 
  147 DRIVER_MODULE(mainboard, eisa, mainboard_driver, mainboard_devclass, 0, 0);
  148                 
  149 /*
  150 ** probe for EISA devices
  151 */
  152 static int
  153 eisa_probe(device_t dev)
  154 {
  155         int i,slot;
  156         struct eisa_device *e_dev;
  157         device_t child;
  158         int eisaBase = 0xc80;
  159         eisa_id_t eisa_id;
  160         int devices_found = 0;
  161 
  162         device_set_desc(dev, "EISA bus");
  163 
  164         for (slot = 0; slot < num_eisa_slots; eisaBase+=0x1000, slot++) {
  165                 int id_size = sizeof(eisa_id);
  166                 eisa_id = 0;
  167                 for( i = 0; i < id_size; i++ ) {
  168                         outb(eisaBase,0x80 + i); /*Some cards require priming*/
  169                         eisa_id |= inb(eisaBase+i) << ((id_size-i-1)*CHAR_BIT);
  170                 }
  171                 if (eisa_id & 0x80000000)
  172                         continue;  /* no EISA card in slot */
  173 
  174                 devices_found++;
  175 
  176                 /* Prepare an eisa_device_node for this slot */
  177                 e_dev = (struct eisa_device *)malloc(sizeof(*e_dev),
  178                                                      M_DEVBUF, M_NOWAIT|M_ZERO);
  179                 if (!e_dev) {
  180                         device_printf(dev, "cannot malloc eisa_device");
  181                         break; /* Try to attach what we have already */
  182                 }
  183 
  184                 e_dev->id = eisa_id;
  185 
  186                 e_dev->ioconf.slot = slot; 
  187 
  188                 /* Initialize our lists of reserved addresses */
  189                 LIST_INIT(&(e_dev->ioconf.ioaddrs));
  190                 LIST_INIT(&(e_dev->ioconf.maddrs));
  191                 TAILQ_INIT(&(e_dev->ioconf.irqs));
  192 
  193                 child = device_add_child(dev, NULL, -1);
  194                 device_set_ivars(child, e_dev);
  195         }
  196 
  197         /*
  198          * EISA busses themselves are not easily detectable, the easiest way
  199          * to tell if there is an eisa bus is if we found something - there
  200          * should be a motherboard "card" there somewhere.
  201          */
  202         return devices_found ? 0 : ENXIO;
  203 }
  204 
  205 static void
  206 eisa_probe_nomatch(device_t dev, device_t child)
  207 {
  208         u_int32_t       eisa_id = eisa_get_id(child);
  209         u_int8_t        slot = eisa_get_slot(child);
  210 
  211         device_printf(dev, "unknown card %c%c%c%03x%01x (0x%08x) at slot %d\n",
  212                 EISA_MFCTR_CHAR0(eisa_id),
  213                 EISA_MFCTR_CHAR1(eisa_id),
  214                 EISA_MFCTR_CHAR2(eisa_id),
  215                 EISA_PRODUCT_ID(eisa_id),
  216                 EISA_REVISION_ID(eisa_id),
  217                 eisa_id,
  218                 slot);
  219 
  220         return;
  221 }
  222 
  223 static void
  224 eisa_reg_print (dev, string, separator, column)
  225         device_t        dev;
  226         char *          string;
  227         char *          separator;
  228         int *           column;
  229 {
  230         int length = strlen(string);
  231 
  232         length += (separator ? 2 : 1);
  233 
  234         if (((*column) + length) >= MAX_COL) {
  235                 printf("\n");
  236                 (*column) = 0;
  237         } else if ((*column) != 0) {
  238                 if (separator) {
  239                         printf("%c", *separator);
  240                         (*column)++;
  241                 }
  242                 printf(" ");
  243                 (*column)++;
  244         }
  245 
  246         if ((*column) == 0) {
  247                 (*column) += device_printf(dev, "%s", string);
  248         } else {
  249                 (*column) += printf("%s", string);
  250         }
  251 
  252         return;
  253 }
  254 
  255 static int
  256 eisa_print_child(device_t dev, device_t child)
  257 {
  258         char                    buf[81];
  259         struct eisa_device *    e_dev = device_get_ivars(child);
  260         int                     rid;
  261         struct irq_node *       irq;
  262         struct resvaddr *       resv;
  263         char                    separator = ',';
  264         int                     column = 0;
  265         int                     retval = 0;
  266 
  267         if (device_get_desc(child)) {
  268                 snprintf(buf, sizeof(buf), "<%s>", device_get_desc(child));
  269                 eisa_reg_print(child, buf, NULL, &column);
  270         }
  271 
  272         rid = 0;
  273         while ((resv = eisa_find_ioaddr(e_dev, rid++))) {
  274                 if ((resv->size == 1) ||
  275                     (resv->flags & RESVADDR_BITMASK)) {
  276                         snprintf(buf, sizeof(buf), "%s%lx",
  277                                 ((rid == 1) ? "at 0x" : "0x"),
  278                                 resv->addr);
  279                 } else {
  280                         snprintf(buf, sizeof(buf), "%s%lx-0x%lx",
  281                                 ((rid == 1) ? "at 0x" : "0x"),
  282                                 resv->addr,
  283                                 (resv->addr + (resv->size - 1)));
  284                 }
  285                 eisa_reg_print(child, buf, 
  286                         ((rid == 2) ? &separator : NULL), &column);
  287         }
  288 
  289         rid = 0;
  290         while ((resv = eisa_find_maddr(e_dev, rid++))) {
  291                 if ((resv->size == 1) ||
  292                     (resv->flags & RESVADDR_BITMASK)) {
  293                         snprintf(buf, sizeof(buf), "%s%lx",
  294                                 ((rid == 1) ? "at 0x" : "0x"),
  295                                 resv->addr);
  296                 } else {
  297                         snprintf(buf, sizeof(buf), "%s%lx-0x%lx",
  298                                 ((rid == 1) ? "at 0x" : "0x"),
  299                                 resv->addr,
  300                                 (resv->addr + (resv->size - 1)));
  301                 }
  302                 eisa_reg_print(child, buf, 
  303                         ((rid == 2) ? &separator : NULL), &column);
  304         }
  305 
  306         rid = 0;
  307         while ((irq = eisa_find_irq(e_dev, rid++)) != NULL) {
  308                 snprintf(buf, sizeof(buf), "irq %d (%s)", irq->irq_no,
  309                          (irq->irq_trigger ? "level" : "edge"));
  310                 eisa_reg_print(child, buf, 
  311                         ((rid == 1) ? &separator : NULL), &column);
  312         }
  313 
  314         snprintf(buf, sizeof(buf), "on %s slot %d\n",
  315                 device_get_nameunit(dev), eisa_get_slot(child));
  316         eisa_reg_print(child, buf, NULL, &column);
  317 
  318         return (retval);
  319 }
  320 
  321 static struct irq_node *
  322 eisa_find_irq(struct eisa_device *e_dev, int rid)
  323 {
  324         int i;
  325         struct irq_node *irq;
  326 
  327         for (i = 0, irq = TAILQ_FIRST(&e_dev->ioconf.irqs);
  328              i < rid && irq;
  329              i++, irq = TAILQ_NEXT(irq, links))
  330                 ;
  331         
  332         if (irq)
  333                 return (irq);
  334         else
  335                 return (NULL);
  336 }
  337 
  338 static struct resvaddr *
  339 eisa_find_maddr(struct eisa_device *e_dev, int rid)
  340 {
  341         int i;
  342         struct resvaddr *resv;
  343 
  344         for (i = 0, resv = LIST_FIRST(&e_dev->ioconf.maddrs);
  345              i < rid && resv;
  346              i++, resv = LIST_NEXT(resv, links))
  347                 ;
  348 
  349         return resv;
  350 }
  351 
  352 static struct resvaddr *
  353 eisa_find_ioaddr(struct eisa_device *e_dev, int rid)
  354 {
  355         int i;
  356         struct resvaddr *resv;
  357 
  358         for (i = 0, resv = LIST_FIRST(&e_dev->ioconf.ioaddrs);
  359              i < rid && resv;
  360              i++, resv = LIST_NEXT(resv, links))
  361                 ;
  362 
  363         return resv;
  364 }
  365 
  366 static int
  367 eisa_read_ivar(device_t dev, device_t child, int which, u_long *result)
  368 {
  369         struct eisa_device *e_dev = device_get_ivars(child);
  370         struct irq_node *irq;
  371 
  372         switch (which) {
  373         case EISA_IVAR_SLOT:
  374                 *result = e_dev->ioconf.slot;
  375                 break;
  376                 
  377         case EISA_IVAR_ID:
  378                 *result = e_dev->id;
  379                 break;
  380 
  381         case EISA_IVAR_IRQ:
  382                 /* XXX only first irq */
  383                 if ((irq = eisa_find_irq(e_dev, 0)) != NULL) {
  384                         *result = irq->irq_no;
  385                 } else {
  386                         *result = -1;
  387                 }
  388                 break;
  389 
  390         default:
  391                 return (ENOENT);
  392         }
  393 
  394         return (0);
  395 }
  396 
  397 static int
  398 eisa_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
  399 {
  400         return (EINVAL);
  401 }
  402 
  403 static struct resource *
  404 eisa_alloc_resource(device_t dev, device_t child, int type, int *rid,
  405                     u_long start, u_long end, u_long count, u_int flags)
  406 {
  407         int isdefault;
  408         struct eisa_device *e_dev = device_get_ivars(child);
  409         struct resource *rv, **rvp = 0;
  410 
  411         isdefault = (device_get_parent(child) == dev
  412                      && start == 0UL && end == ~0UL && count == 1);
  413 
  414         switch (type) {
  415         case SYS_RES_IRQ:
  416                 if (isdefault) {
  417                         struct irq_node * irq = eisa_find_irq(e_dev, *rid);
  418                         if (irq == NULL)
  419                                 return 0;
  420                         start = end = irq->irq_no;
  421                         count = 1;
  422                         if (irq->irq_trigger == EISA_TRIGGER_LEVEL) {
  423                                 flags |= RF_SHAREABLE;
  424                         } else {
  425                                 flags &= ~RF_SHAREABLE;
  426                         }
  427                 }
  428                 break;
  429 
  430         case SYS_RES_MEMORY:
  431                 if (isdefault) {
  432                         struct resvaddr *resv;
  433 
  434                         resv = eisa_find_maddr(e_dev, *rid);
  435                         if (!resv)
  436                                 return 0;
  437 
  438                         start = resv->addr;
  439                         end = resv->addr + (resv->size - 1);
  440                         count = resv->size;
  441                         rvp = &resv->res;
  442                 }
  443                 break;
  444 
  445         case SYS_RES_IOPORT:
  446                 if (isdefault) {
  447                         struct resvaddr *resv;
  448 
  449                         resv = eisa_find_ioaddr(e_dev, *rid);
  450                         if (!resv)
  451                                 return 0;
  452 
  453                         start = resv->addr;
  454                         end = resv->addr + (resv->size - 1);
  455                         count = resv->size;
  456                         rvp = &resv->res;
  457                 }
  458                 break;
  459 
  460         default:
  461                 return 0;
  462         }
  463 
  464         rv = BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
  465                                  type, rid, start, end, count, flags);
  466         if (rvp)
  467                 *rvp = rv;
  468 
  469         return rv;
  470 }
  471 
  472 static int
  473 eisa_release_resource(device_t dev, device_t child, int type, int rid,
  474                       struct resource *r)
  475 {
  476         int rv;
  477         struct eisa_device *e_dev = device_get_ivars(child);
  478         struct resvaddr *resv = 0;
  479 
  480         switch (type) {
  481         case SYS_RES_IRQ:
  482                 if (eisa_find_irq(e_dev, rid) == NULL)
  483                         return EINVAL;
  484                 break;
  485 
  486         case SYS_RES_MEMORY:
  487                 if (device_get_parent(child) == dev)
  488                         resv = eisa_find_maddr(e_dev, rid);
  489                 break;
  490 
  491 
  492         case SYS_RES_IOPORT:
  493                 if (device_get_parent(child) == dev)
  494                         resv = eisa_find_ioaddr(e_dev, rid);
  495                 break;
  496 
  497         default:
  498                 return (ENOENT);
  499         }
  500 
  501         rv = BUS_RELEASE_RESOURCE(device_get_parent(dev), child, type, rid, r);
  502 
  503         if (rv == 0) {
  504                 if (resv)
  505                         resv->res = 0;
  506         }
  507 
  508         return rv;
  509 }
  510 
  511 int
  512 eisa_add_intr(device_t dev, int irq, int trigger)
  513 {
  514         struct eisa_device *e_dev = device_get_ivars(dev);
  515         struct irq_node *irq_info;
  516  
  517         irq_info = (struct irq_node *)malloc(sizeof(*irq_info), M_DEVBUF,
  518                                              M_NOWAIT);
  519         if (irq_info == NULL)
  520                 return (1);
  521 
  522         irq_info->irq_no = irq;
  523         irq_info->irq_trigger = trigger;
  524         irq_info->idesc = NULL;
  525         TAILQ_INSERT_TAIL(&e_dev->ioconf.irqs, irq_info, links);
  526         return 0;
  527 }
  528 
  529 static int
  530 eisa_add_resvaddr(struct eisa_device *e_dev, struct resvlist *head, u_long base,
  531                   u_long size, int flags)
  532 {
  533         resvaddr_t *reservation;
  534 
  535         reservation = (resvaddr_t *)malloc(sizeof(resvaddr_t),
  536                                            M_DEVBUF, M_NOWAIT);
  537         if(!reservation)
  538                 return (ENOMEM);
  539 
  540         reservation->addr = base;
  541         reservation->size = size;
  542         reservation->flags = flags;
  543 
  544         if (!LIST_FIRST(head)) {
  545                 LIST_INSERT_HEAD(head, reservation, links);
  546         }
  547         else {
  548                 resvaddr_t *node;
  549                 LIST_FOREACH(node, head, links) {
  550                         if (node->addr > reservation->addr) {
  551                                 /*
  552                                  * List is sorted in increasing
  553                                  * address order.
  554                                  */
  555                                 LIST_INSERT_BEFORE(node, reservation, links);
  556                                 break;
  557                         }
  558 
  559                         if (node->addr == reservation->addr) {
  560                                 /*
  561                                  * If the entry we want to add
  562                                  * matches any already in here,
  563                                  * fail.
  564                                  */
  565                                 free(reservation, M_DEVBUF);
  566                                 return (EEXIST);
  567                         }
  568 
  569                         if (!LIST_NEXT(node, links)) {
  570                                 LIST_INSERT_AFTER(node, reservation, links);
  571                                 break;
  572                         }
  573                 }
  574         }
  575         return (0);
  576 }
  577 
  578 int
  579 eisa_add_mspace(device_t dev, u_long mbase, u_long msize, int flags)
  580 {
  581         struct eisa_device *e_dev = device_get_ivars(dev);
  582 
  583         return  eisa_add_resvaddr(e_dev, &(e_dev->ioconf.maddrs), mbase, msize,
  584                                   flags);
  585 }
  586 
  587 int
  588 eisa_add_iospace(device_t dev, u_long iobase, u_long iosize, int flags)
  589 {
  590         struct eisa_device *e_dev = device_get_ivars(dev);
  591 
  592         return  eisa_add_resvaddr(e_dev, &(e_dev->ioconf.ioaddrs), iobase,
  593                                   iosize, flags);
  594 }
  595 
  596 static device_method_t eisa_methods[] = {
  597         /* Device interface */
  598         DEVMETHOD(device_probe,         eisa_probe),
  599         DEVMETHOD(device_attach,        bus_generic_attach),
  600         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
  601         DEVMETHOD(device_suspend,       bus_generic_suspend),
  602         DEVMETHOD(device_resume,        bus_generic_resume),
  603 
  604         /* Bus interface */
  605         DEVMETHOD(bus_print_child,      eisa_print_child),
  606         DEVMETHOD(bus_probe_nomatch,    eisa_probe_nomatch),
  607         DEVMETHOD(bus_read_ivar,        eisa_read_ivar),
  608         DEVMETHOD(bus_write_ivar,       eisa_write_ivar),
  609         DEVMETHOD(bus_driver_added,     bus_generic_driver_added),
  610         DEVMETHOD(bus_alloc_resource,   eisa_alloc_resource),
  611         DEVMETHOD(bus_release_resource, eisa_release_resource),
  612         DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
  613         DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
  614         DEVMETHOD(bus_setup_intr,       bus_generic_setup_intr),
  615         DEVMETHOD(bus_teardown_intr,    bus_generic_teardown_intr),
  616 
  617         { 0, 0 }
  618 };
  619 
  620 static driver_t eisa_driver = {
  621         "eisa",
  622         eisa_methods,
  623         1,                      /* no softc */
  624 };
  625 
  626 DRIVER_MODULE(eisa, eisab, eisa_driver, eisa_devclass, 0, 0);
  627 DRIVER_MODULE(eisa, legacy, eisa_driver, eisa_devclass, 0, 0);

Cache object: a35f9dd2cf3c55d94653dc68a6b4a625


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