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$"); 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, void *arg) 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, arg, &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 *arg, 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 void *ar_parent; 415 }; 416 417 static void 418 acpi_res_set_init(device_t dev, void *arg, void **context) 419 { 420 struct acpi_res_context *cp; 421 422 if ((cp = AcpiOsAllocate(sizeof(*cp))) != NULL) { 423 bzero(cp, sizeof(*cp)); 424 cp->ar_parent = arg; 425 *context = cp; 426 } 427 } 428 429 static void 430 acpi_res_set_done(device_t dev, void *context) 431 { 432 struct acpi_res_context *cp = (struct acpi_res_context *)context; 433 434 if (cp == NULL) 435 return; 436 AcpiOsFree(cp); 437 } 438 439 static void 440 acpi_res_set_ioport(device_t dev, void *context, u_int32_t base, 441 u_int32_t length) 442 { 443 struct acpi_res_context *cp = (struct acpi_res_context *)context; 444 445 if (cp == NULL) 446 return; 447 bus_set_resource(dev, SYS_RES_IOPORT, cp->ar_nio++, base, length); 448 } 449 450 static void 451 acpi_res_set_iorange(device_t dev, void *context, u_int32_t low, 452 u_int32_t high, u_int32_t length, u_int32_t align) 453 { 454 struct acpi_res_context *cp = (struct acpi_res_context *)context; 455 456 if (cp == NULL) 457 return; 458 device_printf(dev, "I/O range not supported\n"); 459 } 460 461 static void 462 acpi_res_set_memory(device_t dev, void *context, u_int32_t base, 463 u_int32_t length) 464 { 465 struct acpi_res_context *cp = (struct acpi_res_context *)context; 466 467 if (cp == NULL) 468 return; 469 470 bus_set_resource(dev, SYS_RES_MEMORY, cp->ar_nmem++, base, length); 471 } 472 473 static void 474 acpi_res_set_memoryrange(device_t dev, void *context, u_int32_t low, 475 u_int32_t high, u_int32_t length, u_int32_t align) 476 { 477 struct acpi_res_context *cp = (struct acpi_res_context *)context; 478 479 if (cp == NULL) 480 return; 481 device_printf(dev, "memory range not supported\n"); 482 } 483 484 static void 485 acpi_res_set_irq(device_t dev, void *context, u_int32_t *irq, int count, 486 int trig, int pol) 487 { 488 struct acpi_res_context *cp = (struct acpi_res_context *)context; 489 490 if (cp == NULL || irq == NULL) 491 return; 492 493 /* This implements no resource relocation. */ 494 if (count != 1) 495 return; 496 497 bus_set_resource(dev, SYS_RES_IRQ, cp->ar_nirq++, *irq, 1); 498 BUS_CONFIG_INTR(dev, *irq, (trig == ACPI_EDGE_SENSITIVE) ? 499 INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL, (pol == ACPI_ACTIVE_HIGH) ? 500 INTR_POLARITY_HIGH : INTR_POLARITY_LOW); 501 } 502 503 static void 504 acpi_res_set_drq(device_t dev, void *context, u_int32_t *drq, int count) 505 { 506 struct acpi_res_context *cp = (struct acpi_res_context *)context; 507 508 if (cp == NULL || drq == NULL) 509 return; 510 511 /* This implements no resource relocation. */ 512 if (count != 1) 513 return; 514 515 bus_set_resource(dev, SYS_RES_DRQ, cp->ar_ndrq++, *drq, 1); 516 } 517 518 static void 519 acpi_res_set_start_dependant(device_t dev, void *context, int preference) 520 { 521 struct acpi_res_context *cp = (struct acpi_res_context *)context; 522 523 if (cp == NULL) 524 return; 525 device_printf(dev, "dependant functions not supported\n"); 526 } 527 528 static void 529 acpi_res_set_end_dependant(device_t dev, void *context) 530 { 531 struct acpi_res_context *cp = (struct acpi_res_context *)context; 532 533 if (cp == NULL) 534 return; 535 device_printf(dev, "dependant functions not supported\n"); 536 } 537 538 /* 539 * Resource-owning placeholders. 540 * 541 * This code "owns" system resource objects that aren't 542 * otherwise useful to devices, and which shouldn't be 543 * considered "free". 544 * 545 * Note that some systems claim *all* of the physical address space 546 * with a PNP0C01 device, so we cannot correctly "own" system memory 547 * here (must be done in the SMAP handler on x86 systems, for 548 * example). 549 */ 550 551 static int acpi_sysresource_probe(device_t dev); 552 static int acpi_sysresource_attach(device_t dev); 553 554 static device_method_t acpi_sysresource_methods[] = { 555 /* Device interface */ 556 DEVMETHOD(device_probe, acpi_sysresource_probe), 557 DEVMETHOD(device_attach, acpi_sysresource_attach), 558 559 {0, 0} 560 }; 561 562 static driver_t acpi_sysresource_driver = { 563 "acpi_sysresource", 564 acpi_sysresource_methods, 565 0, 566 }; 567 568 static devclass_t acpi_sysresource_devclass; 569 DRIVER_MODULE(acpi_sysresource, acpi, acpi_sysresource_driver, 570 acpi_sysresource_devclass, 0, 0); 571 MODULE_DEPEND(acpi_sysresource, acpi, 1, 1, 1); 572 573 static int 574 acpi_sysresource_probe(device_t dev) 575 { 576 if (!acpi_disabled("sysresource") && acpi_MatchHid(dev, "PNP0C02")) 577 device_set_desc(dev, "System Resource"); 578 else 579 return (ENXIO); 580 581 device_quiet(dev); 582 return (-100); 583 } 584 585 static int 586 acpi_sysresource_attach(device_t dev) 587 { 588 struct resource *res; 589 int i, rid; 590 591 /* 592 * Suck up all the resources that might have been assigned to us. 593 * Note that it's impossible to tell the difference between a 594 * resource that someone else has claimed, and one that doesn't 595 * exist. 596 */ 597 for (i = 0; i < 100; i++) { 598 rid = i; 599 res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, 0); 600 rid = i; 601 res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 0); 602 rid = i; 603 res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_SHAREABLE); 604 } 605 606 return (0); 607 } 608