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/acpica/acpi_resource.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  * Copyright (c) 2000 Michael Smith
    3  * Copyright (c) 2000 BSDi
    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  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  */
   27 
   28 #include <sys/cdefs.h>
   29 __FBSDID("$FreeBSD: releng/5.2/sys/dev/acpica/acpi_resource.c 120453 2003-09-26 05:24:55Z njl $");
   30 
   31 #include "opt_acpi.h"
   32 #include <sys/param.h>
   33 #include <sys/kernel.h>
   34 #include <sys/bus.h>
   35 
   36 #include <machine/bus.h>
   37 #include <machine/resource.h>
   38 #include <sys/rman.h>
   39 
   40 #include "acpi.h"
   41 #include <dev/acpica/acpivar.h>
   42 
   43 /* Hooks for the ACPI CA debugging infrastructure */
   44 #define _COMPONENT      ACPI_BUS
   45 ACPI_MODULE_NAME("RESOURCE")
   46 
   47 /*
   48  * Fetch a device's resources and associate them with the device.
   49  *
   50  * Note that it might be nice to also locate ACPI-specific resource items, such
   51  * as GPE bits.
   52  *
   53  * We really need to split the resource-fetching code out from the
   54  * resource-parsing code, since we may want to use the parsing
   55  * code for _PRS someday.
   56  */
   57 ACPI_STATUS
   58 acpi_parse_resources(device_t dev, ACPI_HANDLE handle,
   59                      struct acpi_parse_resource_set *set)
   60 {
   61     ACPI_BUFFER         buf;
   62     ACPI_RESOURCE       *res;
   63     char                *curr, *last;
   64     ACPI_STATUS         status;
   65     void                *context;
   66 
   67     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
   68 
   69     /*
   70      * Special-case some devices that abuse _PRS/_CRS to mean
   71      * something other than "I consume this resource".
   72      *
   73      * XXX do we really need this?  It's only relevant once
   74      *     we start always-allocating these resources, and even
   75      *     then, the only special-cased device is likely to be
   76      *     the PCI interrupt link.
   77      */
   78 
   79     /* Fetch the device's current resources. */
   80     buf.Length = ACPI_ALLOCATE_BUFFER;
   81     if (ACPI_FAILURE((status = AcpiGetCurrentResources(handle, &buf)))) {
   82         if (status != AE_NOT_FOUND)
   83             printf("can't fetch resources for %s - %s\n",
   84                    acpi_name(handle), AcpiFormatException(status));
   85         return_ACPI_STATUS (status);
   86     }
   87     ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "%s - got %ld bytes of resources\n",
   88                      acpi_name(handle), (long)buf.Length));
   89     set->set_init(dev, &context);
   90 
   91     /* Iterate through the resources */
   92     curr = buf.Pointer;
   93     last = (char *)buf.Pointer + buf.Length;
   94     while (curr < last) {
   95         res = (ACPI_RESOURCE *)curr;
   96         curr += res->Length;
   97 
   98         /* Handle the individual resource types */
   99         switch(res->Id) {
  100         case ACPI_RSTYPE_END_TAG:
  101             ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "EndTag\n"));
  102             curr = last;
  103             break;
  104         case ACPI_RSTYPE_FIXED_IO:
  105             if (res->Data.FixedIo.RangeLength <= 0)
  106                 break;
  107             ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "FixedIo 0x%x/%d\n",
  108                              res->Data.FixedIo.BaseAddress,
  109                              res->Data.FixedIo.RangeLength));
  110             set->set_ioport(dev, context,
  111                             res->Data.FixedIo.BaseAddress,
  112                             res->Data.FixedIo.RangeLength);
  113             break;
  114         case ACPI_RSTYPE_IO:
  115             if (res->Data.Io.RangeLength <= 0)
  116                 break;
  117             if (res->Data.Io.MinBaseAddress == res->Data.Io.MaxBaseAddress) {
  118                 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Io 0x%x/%d\n",
  119                                  res->Data.Io.MinBaseAddress,
  120                                  res->Data.Io.RangeLength));
  121                 set->set_ioport(dev, context,
  122                                 res->Data.Io.MinBaseAddress,
  123                                 res->Data.Io.RangeLength);
  124             } else {
  125                 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Io 0x%x-0x%x/%d\n",
  126                                  res->Data.Io.MinBaseAddress,
  127                                  res->Data.Io.MaxBaseAddress, 
  128                                  res->Data.Io.RangeLength));
  129                 set->set_iorange(dev, context,
  130                                  res->Data.Io.MinBaseAddress,
  131                                  res->Data.Io.MaxBaseAddress, 
  132                                  res->Data.Io.RangeLength,
  133                                  res->Data.Io.Alignment);
  134             }
  135             break;
  136         case ACPI_RSTYPE_FIXED_MEM32:
  137             if (res->Data.FixedMemory32.RangeLength <= 0)
  138                 break;
  139             ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "FixedMemory32 0x%x/%d\n",
  140                               res->Data.FixedMemory32.RangeBaseAddress, 
  141                               res->Data.FixedMemory32.RangeLength));
  142             set->set_memory(dev, context,
  143                             res->Data.FixedMemory32.RangeBaseAddress, 
  144                             res->Data.FixedMemory32.RangeLength);
  145             break;
  146         case ACPI_RSTYPE_MEM32:
  147             if (res->Data.Memory32.RangeLength <= 0)
  148                 break;
  149             if (res->Data.Memory32.MinBaseAddress ==
  150                 res->Data.Memory32.MaxBaseAddress) {
  151 
  152                 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Memory32 0x%x/%d\n",
  153                                   res->Data.Memory32.MinBaseAddress, 
  154                                   res->Data.Memory32.RangeLength));
  155                 set->set_memory(dev, context,
  156                                 res->Data.Memory32.MinBaseAddress,
  157                                 res->Data.Memory32.RangeLength);
  158             } else {
  159                 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Memory32 0x%x-0x%x/%d\n",
  160                                  res->Data.Memory32.MinBaseAddress, 
  161                                  res->Data.Memory32.MaxBaseAddress,
  162                                  res->Data.Memory32.RangeLength));
  163                 set->set_memoryrange(dev, context,
  164                                      res->Data.Memory32.MinBaseAddress,
  165                                      res->Data.Memory32.MaxBaseAddress,
  166                                      res->Data.Memory32.RangeLength,
  167                                      res->Data.Memory32.Alignment);
  168             }
  169             break;
  170         case ACPI_RSTYPE_MEM24:
  171             if (res->Data.Memory24.RangeLength <= 0)
  172                 break;
  173             if (res->Data.Memory24.MinBaseAddress ==
  174                 res->Data.Memory24.MaxBaseAddress) {
  175 
  176                 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Memory24 0x%x/%d\n",
  177                                  res->Data.Memory24.MinBaseAddress, 
  178                                  res->Data.Memory24.RangeLength));
  179                 set->set_memory(dev, context, res->Data.Memory24.MinBaseAddress,
  180                                 res->Data.Memory24.RangeLength);
  181             } else {
  182                 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "Memory24 0x%x-0x%x/%d\n",
  183                                  res->Data.Memory24.MinBaseAddress, 
  184                                  res->Data.Memory24.MaxBaseAddress,
  185                                  res->Data.Memory24.RangeLength));
  186                 set->set_memoryrange(dev, context,
  187                                      res->Data.Memory24.MinBaseAddress,
  188                                      res->Data.Memory24.MaxBaseAddress,
  189                                      res->Data.Memory24.RangeLength,
  190                                      res->Data.Memory24.Alignment);
  191             }
  192             break;
  193         case ACPI_RSTYPE_IRQ:
  194             /*
  195              * from 1.0b 6.4.2 
  196              * "This structure is repeated for each separate interrupt
  197              * required"
  198              */
  199             set->set_irq(dev, context, res->Data.Irq.Interrupts,
  200                 res->Data.Irq.NumberOfInterrupts, res->Data.Irq.EdgeLevel,
  201                 res->Data.Irq.ActiveHighLow);
  202             break;
  203         case ACPI_RSTYPE_DMA:
  204             /*
  205              * from 1.0b 6.4.3 
  206              * "This structure is repeated for each separate dma channel
  207              * required"
  208              */
  209             set->set_drq(dev, context, res->Data.Dma.Channels,
  210                          res->Data.Dma.NumberOfChannels);
  211             break;
  212         case ACPI_RSTYPE_START_DPF:
  213             ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "start dependant functions\n"));
  214             set->set_start_dependant(dev, context,
  215                                      res->Data.StartDpf.CompatibilityPriority);
  216             break;
  217         case ACPI_RSTYPE_END_DPF:
  218             ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "end dependant functions\n"));
  219             set->set_end_dependant(dev, context);
  220             break;
  221         case ACPI_RSTYPE_ADDRESS32:
  222             if (res->Data.Address32.AddressLength <= 0)
  223                 break;
  224             if (res->Data.Address32.ProducerConsumer != ACPI_CONSUMER) {
  225                 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
  226                     "ignored Address32 %s producer\n",
  227                     res->Data.Address32.ResourceType == ACPI_IO_RANGE ?
  228                     "IO" : "Memory"));
  229                 break;
  230             }
  231             if (res->Data.Address32.ResourceType != ACPI_MEMORY_RANGE &&
  232                 res->Data.Address32.ResourceType != ACPI_IO_RANGE) {
  233                 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
  234                     "ignored Address32 for non-memory, non-I/O\n"));
  235                 break;
  236             }
  237 
  238             if (res->Data.Address32.MinAddressFixed == ACPI_ADDRESS_FIXED &&
  239                 res->Data.Address32.MaxAddressFixed == ACPI_ADDRESS_FIXED) {
  240 
  241                 if (res->Data.Address32.ResourceType == ACPI_MEMORY_RANGE) {
  242                     ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
  243                                      "Address32/Memory 0x%x/%d\n",
  244                                      res->Data.Address32.MinAddressRange,
  245                                      res->Data.Address32.AddressLength));
  246                     set->set_memory(dev, context,
  247                                     res->Data.Address32.MinAddressRange,
  248                                     res->Data.Address32.AddressLength);
  249                 } else {
  250                     ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
  251                                      "Address32/IO 0x%x/%d\n",
  252                                      res->Data.Address32.MinAddressRange,
  253                                      res->Data.Address32.AddressLength));
  254                     set->set_ioport(dev, context,
  255                                     res->Data.Address32.MinAddressRange,
  256                                     res->Data.Address32.AddressLength);
  257                 }
  258             } else {
  259                 if (res->Data.Address32.ResourceType == ACPI_MEMORY_RANGE) {
  260                     ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
  261                                      "Address32/Memory 0x%x-0x%x/%d\n",
  262                                      res->Data.Address32.MinAddressRange,
  263                                      res->Data.Address32.MaxAddressRange,
  264                                      res->Data.Address32.AddressLength));
  265                     set->set_memoryrange(dev, context,
  266                                           res->Data.Address32.MinAddressRange,
  267                                           res->Data.Address32.MaxAddressRange,
  268                                           res->Data.Address32.AddressLength,
  269                                           res->Data.Address32.Granularity);
  270                 } else {
  271                     ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
  272                                      "Address32/IO 0x%x-0x%x/%d\n",
  273                                      res->Data.Address32.MinAddressRange,
  274                                      res->Data.Address32.MaxAddressRange,
  275                                      res->Data.Address32.AddressLength));
  276                     set->set_iorange(dev, context,
  277                                      res->Data.Address32.MinAddressRange,
  278                                      res->Data.Address32.MaxAddressRange,
  279                                      res->Data.Address32.AddressLength,
  280                                      res->Data.Address32.Granularity);
  281                 }
  282             }               
  283             break;
  284         case ACPI_RSTYPE_ADDRESS16:
  285             if (res->Data.Address16.AddressLength <= 0)
  286                 break;
  287             if (res->Data.Address16.ProducerConsumer != ACPI_CONSUMER) {
  288                 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
  289                     "ignored Address16 %s producer\n",
  290                     res->Data.Address16.ResourceType == ACPI_IO_RANGE ?
  291                     "IO" : "Memory"));
  292                 break;
  293             }
  294             if (res->Data.Address16.ResourceType != ACPI_MEMORY_RANGE &&
  295                 res->Data.Address16.ResourceType != ACPI_IO_RANGE) {
  296                 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
  297                         "ignored Address16 for non-memory, non-I/O\n"));
  298                 break;
  299             }
  300 
  301             if (res->Data.Address16.MinAddressFixed == ACPI_ADDRESS_FIXED &&
  302                 res->Data.Address16.MaxAddressFixed == ACPI_ADDRESS_FIXED) {
  303 
  304                 if (res->Data.Address16.ResourceType == ACPI_MEMORY_RANGE) {
  305                     ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
  306                                      "Address16/Memory 0x%x/%d\n",
  307                                      res->Data.Address16.MinAddressRange,
  308                                      res->Data.Address16.AddressLength));
  309                     set->set_memory(dev, context,
  310                                     res->Data.Address16.MinAddressRange,
  311                                     res->Data.Address16.AddressLength);
  312                 } else {
  313                     ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
  314                                      "Address16/IO 0x%x/%d\n",
  315                                      res->Data.Address16.MinAddressRange,
  316                                      res->Data.Address16.AddressLength));
  317                     set->set_ioport(dev, context,
  318                                     res->Data.Address16.MinAddressRange,
  319                                     res->Data.Address16.AddressLength);
  320                 }
  321             } else {
  322                 if (res->Data.Address16.ResourceType == ACPI_MEMORY_RANGE) {
  323                     ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
  324                                      "Address16/Memory 0x%x-0x%x/%d\n",
  325                                      res->Data.Address16.MinAddressRange,
  326                                      res->Data.Address16.MaxAddressRange,
  327                                      res->Data.Address16.AddressLength));
  328                     set->set_memoryrange(dev, context,
  329                                           res->Data.Address16.MinAddressRange,
  330                                           res->Data.Address16.MaxAddressRange,
  331                                           res->Data.Address16.AddressLength,
  332                                           res->Data.Address16.Granularity);
  333                 } else {
  334                     ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
  335                                      "Address16/IO 0x%x-0x%x/%d\n",
  336                                      res->Data.Address16.MinAddressRange,
  337                                      res->Data.Address16.MaxAddressRange,
  338                                      res->Data.Address16.AddressLength));
  339                     set->set_iorange(dev, context,
  340                                      res->Data.Address16.MinAddressRange,
  341                                      res->Data.Address16.MaxAddressRange,
  342                                      res->Data.Address16.AddressLength,
  343                                      res->Data.Address16.Granularity);
  344                 }
  345             }               
  346             break;
  347         case ACPI_RSTYPE_ADDRESS64:
  348             ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
  349                              "unimplemented Address64 resource\n"));
  350             break;
  351         case ACPI_RSTYPE_EXT_IRQ:
  352             /* XXX special handling? */
  353             set->set_irq(dev, context,res->Data.ExtendedIrq.Interrupts,
  354                 res->Data.ExtendedIrq.NumberOfInterrupts,
  355                 res->Data.ExtendedIrq.EdgeLevel,
  356                 res->Data.ExtendedIrq.ActiveHighLow);
  357             break;
  358         case ACPI_RSTYPE_VENDOR:
  359             ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
  360                              "unimplemented VendorSpecific resource\n"));
  361             break;
  362         default:
  363             break;
  364         }
  365     }    
  366 
  367     AcpiOsFree(buf.Pointer);
  368     set->set_done(dev, context);
  369     return_ACPI_STATUS (AE_OK);
  370 }
  371 
  372 /*
  373  * Resource-set vectors used to attach _CRS-derived resources 
  374  * to an ACPI device.
  375  */
  376 static void     acpi_res_set_init(device_t dev, void **context);
  377 static void     acpi_res_set_done(device_t dev, void *context);
  378 static void     acpi_res_set_ioport(device_t dev, void *context,
  379                                     u_int32_t base, u_int32_t length);
  380 static void     acpi_res_set_iorange(device_t dev, void *context,
  381                                      u_int32_t low, u_int32_t high, 
  382                                      u_int32_t length, u_int32_t align);
  383 static void     acpi_res_set_memory(device_t dev, void *context,
  384                                     u_int32_t base, u_int32_t length);
  385 static void     acpi_res_set_memoryrange(device_t dev, void *context,
  386                                          u_int32_t low, u_int32_t high, 
  387                                          u_int32_t length, u_int32_t align);
  388 static void     acpi_res_set_irq(device_t dev, void *context, u_int32_t *irq,
  389                                  int count, int trig, int pol);
  390 static void     acpi_res_set_drq(device_t dev, void *context, u_int32_t *drq,
  391                                  int count);
  392 static void     acpi_res_set_start_dependant(device_t dev, void *context,
  393                                              int preference);
  394 static void     acpi_res_set_end_dependant(device_t dev, void *context);
  395 
  396 struct acpi_parse_resource_set acpi_res_parse_set = {
  397     acpi_res_set_init,
  398     acpi_res_set_done,
  399     acpi_res_set_ioport,
  400     acpi_res_set_iorange,
  401     acpi_res_set_memory,
  402     acpi_res_set_memoryrange,
  403     acpi_res_set_irq,
  404     acpi_res_set_drq,
  405     acpi_res_set_start_dependant,
  406     acpi_res_set_end_dependant
  407 };
  408 
  409 struct acpi_res_context {
  410     int         ar_nio;
  411     int         ar_nmem;
  412     int         ar_nirq;
  413     int         ar_ndrq;
  414 };
  415 
  416 static void
  417 acpi_res_set_init(device_t dev, void **context)
  418 {
  419     struct acpi_res_context     *cp;
  420 
  421     if ((cp = AcpiOsAllocate(sizeof(*cp))) != NULL) {
  422         bzero(cp, sizeof(*cp));
  423         *context = cp;
  424     }
  425 }
  426 
  427 static void
  428 acpi_res_set_done(device_t dev, void *context)
  429 {
  430     struct acpi_res_context     *cp = (struct acpi_res_context *)context;
  431 
  432     if (cp == NULL)
  433         return;
  434     AcpiOsFree(cp);
  435 }
  436 
  437 static void
  438 acpi_res_set_ioport(device_t dev, void *context, u_int32_t base,
  439                     u_int32_t length)
  440 {
  441     struct acpi_res_context     *cp = (struct acpi_res_context *)context;
  442 
  443     if (cp == NULL)
  444         return;
  445     bus_set_resource(dev, SYS_RES_IOPORT, cp->ar_nio++, base, length);
  446 }
  447 
  448 static void
  449 acpi_res_set_iorange(device_t dev, void *context, u_int32_t low,
  450                      u_int32_t high, u_int32_t length, u_int32_t align)
  451 {
  452     struct acpi_res_context     *cp = (struct acpi_res_context *)context;
  453 
  454     if (cp == NULL)
  455         return;
  456     device_printf(dev, "I/O range not supported\n");
  457 }
  458 
  459 static void
  460 acpi_res_set_memory(device_t dev, void *context, u_int32_t base,
  461                     u_int32_t length)
  462 {
  463     struct acpi_res_context     *cp = (struct acpi_res_context *)context;
  464 
  465     if (cp == NULL)
  466         return;
  467 
  468     bus_set_resource(dev, SYS_RES_MEMORY, cp->ar_nmem++, base, length);
  469 }
  470 
  471 static void
  472 acpi_res_set_memoryrange(device_t dev, void *context, u_int32_t low,
  473                          u_int32_t high, u_int32_t length, u_int32_t align)
  474 {
  475     struct acpi_res_context     *cp = (struct acpi_res_context *)context;
  476 
  477     if (cp == NULL)
  478         return;
  479     device_printf(dev, "memory range not supported\n");
  480 }
  481 
  482 static void
  483 acpi_res_set_irq(device_t dev, void *context, u_int32_t *irq, int count,
  484     int trig, int pol)
  485 {
  486     struct acpi_res_context     *cp = (struct acpi_res_context *)context;
  487 
  488     if (cp == NULL || irq == NULL)
  489         return;
  490 
  491     /* This implements no resource relocation. */
  492     if (count != 1)
  493         return;
  494 
  495     bus_set_resource(dev, SYS_RES_IRQ, cp->ar_nirq++, *irq, 1);
  496     BUS_CONFIG_INTR(dev, *irq, (trig == ACPI_EDGE_SENSITIVE) ?
  497         INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL, (pol == ACPI_ACTIVE_HIGH) ?
  498         INTR_POLARITY_HIGH : INTR_POLARITY_LOW);
  499 }
  500 
  501 static void
  502 acpi_res_set_drq(device_t dev, void *context, u_int32_t *drq, int count)
  503 {
  504     struct acpi_res_context     *cp = (struct acpi_res_context *)context;
  505 
  506     if (cp == NULL || drq == NULL)
  507         return;
  508     
  509     /* This implements no resource relocation. */
  510     if (count != 1)
  511         return;
  512 
  513     bus_set_resource(dev, SYS_RES_DRQ, cp->ar_ndrq++, *drq, 1);
  514 }
  515 
  516 static void
  517 acpi_res_set_start_dependant(device_t dev, void *context, int preference)
  518 {
  519     struct acpi_res_context     *cp = (struct acpi_res_context *)context;
  520 
  521     if (cp == NULL)
  522         return;
  523     device_printf(dev, "dependant functions not supported\n");
  524 }
  525 
  526 static void
  527 acpi_res_set_end_dependant(device_t dev, void *context)
  528 {
  529     struct acpi_res_context     *cp = (struct acpi_res_context *)context;
  530 
  531     if (cp == NULL)
  532         return;
  533     device_printf(dev, "dependant functions not supported\n");
  534 }
  535 
  536 /*
  537  * Resource-owning placeholders.
  538  *
  539  * This code "owns" system resource objects that aren't
  540  * otherwise useful to devices, and which shouldn't be
  541  * considered "free".
  542  *
  543  * Note that some systems claim *all* of the physical address space
  544  * with a PNP0C01 device, so we cannot correctly "own" system memory
  545  * here (must be done in the SMAP handler on x86 systems, for
  546  * example).
  547  */
  548 
  549 static int      acpi_sysresource_probe(device_t dev);
  550 static int      acpi_sysresource_attach(device_t dev);
  551 
  552 static device_method_t acpi_sysresource_methods[] = {
  553     /* Device interface */
  554     DEVMETHOD(device_probe,     acpi_sysresource_probe),
  555     DEVMETHOD(device_attach,    acpi_sysresource_attach),
  556 
  557     {0, 0}
  558 };
  559 
  560 static driver_t acpi_sysresource_driver = {
  561     "acpi_sysresource",
  562     acpi_sysresource_methods,
  563     0,
  564 };
  565 
  566 static devclass_t acpi_sysresource_devclass;
  567 DRIVER_MODULE(acpi_sysresource, acpi, acpi_sysresource_driver,
  568               acpi_sysresource_devclass, 0, 0);
  569 
  570 static int
  571 acpi_sysresource_probe(device_t dev)
  572 {
  573     if (!acpi_disabled("sysresource") && acpi_MatchHid(dev, "PNP0C02"))
  574         device_set_desc(dev, "System Resource");
  575     else
  576         return (ENXIO);
  577 
  578     device_quiet(dev);
  579     return (-100);
  580 }
  581 
  582 static int
  583 acpi_sysresource_attach(device_t dev)
  584 {
  585     struct resource     *res;
  586     int                 i, rid;
  587 
  588     /*
  589      * Suck up all the resources that might have been assigned to us.
  590      * Note that it's impossible to tell the difference between a
  591      * resource that someone else has claimed, and one that doesn't
  592      * exist.
  593      */
  594     for (i = 0; i < 100; i++) {
  595         rid = i;
  596         res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, 0);
  597         rid = i;
  598         res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0, 1, 0);
  599         rid = i;
  600         res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
  601                                  RF_SHAREABLE);
  602     }
  603 
  604     return (0);
  605 }

Cache object: 5a310cc0565b2808068c18f64f1910b1


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