1 /* 2 * resource.c - Contains functions for registering and analyzing resource information 3 * 4 * based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz> 5 * Copyright 2003 Adam Belay <ambx1@neo.rr.com> 6 * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. 7 * Bjorn Helgaas <bjorn.helgaas@hp.com> 8 */ 9 10 #include <linux/module.h> 11 #include <linux/slab.h> 12 #include <linux/errno.h> 13 #include <linux/interrupt.h> 14 #include <linux/kernel.h> 15 #include <asm/io.h> 16 #include <asm/dma.h> 17 #include <asm/irq.h> 18 #include <linux/pci.h> 19 #include <linux/ioport.h> 20 #include <linux/init.h> 21 22 #include <linux/pnp.h> 23 #include "base.h" 24 25 static int pnp_reserve_irq[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some IRQ */ 26 static int pnp_reserve_dma[8] = {[0 ... 7] = -1 }; /* reserve (don't use) some DMA */ 27 static int pnp_reserve_io[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some I/O region */ 28 static int pnp_reserve_mem[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some memory region */ 29 30 /* 31 * option registration 32 */ 33 34 struct pnp_option *pnp_build_option(struct pnp_dev *dev, unsigned long type, 35 unsigned int option_flags) 36 { 37 struct pnp_option *option; 38 39 option = kzalloc(sizeof(struct pnp_option), GFP_KERNEL); 40 if (!option) 41 return NULL; 42 43 option->flags = option_flags; 44 option->type = type; 45 46 list_add_tail(&option->list, &dev->options); 47 return option; 48 } 49 50 int pnp_register_irq_resource(struct pnp_dev *dev, unsigned int option_flags, 51 pnp_irq_mask_t *map, unsigned char flags) 52 { 53 struct pnp_option *option; 54 struct pnp_irq *irq; 55 56 option = pnp_build_option(dev, IORESOURCE_IRQ, option_flags); 57 if (!option) 58 return -ENOMEM; 59 60 irq = &option->u.irq; 61 irq->map = *map; 62 irq->flags = flags; 63 64 #ifdef CONFIG_PCI 65 { 66 int i; 67 68 for (i = 0; i < 16; i++) 69 if (test_bit(i, irq->map.bits)) 70 pcibios_penalize_isa_irq(i, 0); 71 } 72 #endif 73 74 dbg_pnp_show_option(dev, option); 75 return 0; 76 } 77 78 int pnp_register_dma_resource(struct pnp_dev *dev, unsigned int option_flags, 79 unsigned char map, unsigned char flags) 80 { 81 struct pnp_option *option; 82 struct pnp_dma *dma; 83 84 option = pnp_build_option(dev, IORESOURCE_DMA, option_flags); 85 if (!option) 86 return -ENOMEM; 87 88 dma = &option->u.dma; 89 dma->map = map; 90 dma->flags = flags; 91 92 dbg_pnp_show_option(dev, option); 93 return 0; 94 } 95 96 int pnp_register_port_resource(struct pnp_dev *dev, unsigned int option_flags, 97 resource_size_t min, resource_size_t max, 98 resource_size_t align, resource_size_t size, 99 unsigned char flags) 100 { 101 struct pnp_option *option; 102 struct pnp_port *port; 103 104 option = pnp_build_option(dev, IORESOURCE_IO, option_flags); 105 if (!option) 106 return -ENOMEM; 107 108 port = &option->u.port; 109 port->min = min; 110 port->max = max; 111 port->align = align; 112 port->size = size; 113 port->flags = flags; 114 115 dbg_pnp_show_option(dev, option); 116 return 0; 117 } 118 119 int pnp_register_mem_resource(struct pnp_dev *dev, unsigned int option_flags, 120 resource_size_t min, resource_size_t max, 121 resource_size_t align, resource_size_t size, 122 unsigned char flags) 123 { 124 struct pnp_option *option; 125 struct pnp_mem *mem; 126 127 option = pnp_build_option(dev, IORESOURCE_MEM, option_flags); 128 if (!option) 129 return -ENOMEM; 130 131 mem = &option->u.mem; 132 mem->min = min; 133 mem->max = max; 134 mem->align = align; 135 mem->size = size; 136 mem->flags = flags; 137 138 dbg_pnp_show_option(dev, option); 139 return 0; 140 } 141 142 void pnp_free_options(struct pnp_dev *dev) 143 { 144 struct pnp_option *option, *tmp; 145 146 list_for_each_entry_safe(option, tmp, &dev->options, list) { 147 list_del(&option->list); 148 kfree(option); 149 } 150 } 151 152 /* 153 * resource validity checking 154 */ 155 156 #define length(start, end) (*(end) - *(start) + 1) 157 158 /* Two ranges conflict if one doesn't end before the other starts */ 159 #define ranged_conflict(starta, enda, startb, endb) \ 160 !((*(enda) < *(startb)) || (*(endb) < *(starta))) 161 162 #define cannot_compare(flags) \ 163 ((flags) & IORESOURCE_DISABLED) 164 165 int pnp_check_port(struct pnp_dev *dev, struct resource *res) 166 { 167 int i; 168 struct pnp_dev *tdev; 169 struct resource *tres; 170 resource_size_t *port, *end, *tport, *tend; 171 172 port = &res->start; 173 end = &res->end; 174 175 /* if the resource doesn't exist, don't complain about it */ 176 if (cannot_compare(res->flags)) 177 return 1; 178 179 /* check if the resource is already in use, skip if the 180 * device is active because it itself may be in use */ 181 if (!dev->active) { 182 if (__check_region(&ioport_resource, *port, length(port, end))) 183 return 0; 184 } 185 186 /* check if the resource is reserved */ 187 for (i = 0; i < 8; i++) { 188 int rport = pnp_reserve_io[i << 1]; 189 int rend = pnp_reserve_io[(i << 1) + 1] + rport - 1; 190 if (ranged_conflict(port, end, &rport, &rend)) 191 return 0; 192 } 193 194 /* check for internal conflicts */ 195 for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) { 196 if (tres != res && tres->flags & IORESOURCE_IO) { 197 tport = &tres->start; 198 tend = &tres->end; 199 if (ranged_conflict(port, end, tport, tend)) 200 return 0; 201 } 202 } 203 204 /* check for conflicts with other pnp devices */ 205 pnp_for_each_dev(tdev) { 206 if (tdev == dev) 207 continue; 208 for (i = 0; 209 (tres = pnp_get_resource(tdev, IORESOURCE_IO, i)); 210 i++) { 211 if (tres->flags & IORESOURCE_IO) { 212 if (cannot_compare(tres->flags)) 213 continue; 214 if (tres->flags & IORESOURCE_WINDOW) 215 continue; 216 tport = &tres->start; 217 tend = &tres->end; 218 if (ranged_conflict(port, end, tport, tend)) 219 return 0; 220 } 221 } 222 } 223 224 return 1; 225 } 226 227 int pnp_check_mem(struct pnp_dev *dev, struct resource *res) 228 { 229 int i; 230 struct pnp_dev *tdev; 231 struct resource *tres; 232 resource_size_t *addr, *end, *taddr, *tend; 233 234 addr = &res->start; 235 end = &res->end; 236 237 /* if the resource doesn't exist, don't complain about it */ 238 if (cannot_compare(res->flags)) 239 return 1; 240 241 /* check if the resource is already in use, skip if the 242 * device is active because it itself may be in use */ 243 if (!dev->active) { 244 if (check_mem_region(*addr, length(addr, end))) 245 return 0; 246 } 247 248 /* check if the resource is reserved */ 249 for (i = 0; i < 8; i++) { 250 int raddr = pnp_reserve_mem[i << 1]; 251 int rend = pnp_reserve_mem[(i << 1) + 1] + raddr - 1; 252 if (ranged_conflict(addr, end, &raddr, &rend)) 253 return 0; 254 } 255 256 /* check for internal conflicts */ 257 for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) { 258 if (tres != res && tres->flags & IORESOURCE_MEM) { 259 taddr = &tres->start; 260 tend = &tres->end; 261 if (ranged_conflict(addr, end, taddr, tend)) 262 return 0; 263 } 264 } 265 266 /* check for conflicts with other pnp devices */ 267 pnp_for_each_dev(tdev) { 268 if (tdev == dev) 269 continue; 270 for (i = 0; 271 (tres = pnp_get_resource(tdev, IORESOURCE_MEM, i)); 272 i++) { 273 if (tres->flags & IORESOURCE_MEM) { 274 if (cannot_compare(tres->flags)) 275 continue; 276 if (tres->flags & IORESOURCE_WINDOW) 277 continue; 278 taddr = &tres->start; 279 tend = &tres->end; 280 if (ranged_conflict(addr, end, taddr, tend)) 281 return 0; 282 } 283 } 284 } 285 286 return 1; 287 } 288 289 static irqreturn_t pnp_test_handler(int irq, void *dev_id) 290 { 291 return IRQ_HANDLED; 292 } 293 294 #ifdef CONFIG_PCI 295 static int pci_dev_uses_irq(struct pnp_dev *pnp, struct pci_dev *pci, 296 unsigned int irq) 297 { 298 u32 class; 299 u8 progif; 300 301 if (pci->irq == irq) { 302 pnp_dbg(&pnp->dev, " device %s using irq %d\n", 303 pci_name(pci), irq); 304 return 1; 305 } 306 307 /* 308 * See pci_setup_device() and ata_pci_sff_activate_host() for 309 * similar IDE legacy detection. 310 */ 311 pci_read_config_dword(pci, PCI_CLASS_REVISION, &class); 312 class >>= 8; /* discard revision ID */ 313 progif = class & 0xff; 314 class >>= 8; 315 316 if (class == PCI_CLASS_STORAGE_IDE) { 317 /* 318 * Unless both channels are native-PCI mode only, 319 * treat the compatibility IRQs as busy. 320 */ 321 if ((progif & 0x5) != 0x5) 322 if (pci_get_legacy_ide_irq(pci, 0) == irq || 323 pci_get_legacy_ide_irq(pci, 1) == irq) { 324 pnp_dbg(&pnp->dev, " legacy IDE device %s " 325 "using irq %d\n", pci_name(pci), irq); 326 return 1; 327 } 328 } 329 330 return 0; 331 } 332 #endif 333 334 static int pci_uses_irq(struct pnp_dev *pnp, unsigned int irq) 335 { 336 #ifdef CONFIG_PCI 337 struct pci_dev *pci = NULL; 338 339 for_each_pci_dev(pci) { 340 if (pci_dev_uses_irq(pnp, pci, irq)) { 341 pci_dev_put(pci); 342 return 1; 343 } 344 } 345 #endif 346 return 0; 347 } 348 349 int pnp_check_irq(struct pnp_dev *dev, struct resource *res) 350 { 351 int i; 352 struct pnp_dev *tdev; 353 struct resource *tres; 354 resource_size_t *irq; 355 356 irq = &res->start; 357 358 /* if the resource doesn't exist, don't complain about it */ 359 if (cannot_compare(res->flags)) 360 return 1; 361 362 /* check if the resource is valid */ 363 if (*irq < 0 || *irq > 15) 364 return 0; 365 366 /* check if the resource is reserved */ 367 for (i = 0; i < 16; i++) { 368 if (pnp_reserve_irq[i] == *irq) 369 return 0; 370 } 371 372 /* check for internal conflicts */ 373 for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_IRQ, i)); i++) { 374 if (tres != res && tres->flags & IORESOURCE_IRQ) { 375 if (tres->start == *irq) 376 return 0; 377 } 378 } 379 380 /* check if the resource is being used by a pci device */ 381 if (pci_uses_irq(dev, *irq)) 382 return 0; 383 384 /* check if the resource is already in use, skip if the 385 * device is active because it itself may be in use */ 386 if (!dev->active) { 387 if (request_irq(*irq, pnp_test_handler, 388 IRQF_DISABLED | IRQF_PROBE_SHARED, "pnp", NULL)) 389 return 0; 390 free_irq(*irq, NULL); 391 } 392 393 /* check for conflicts with other pnp devices */ 394 pnp_for_each_dev(tdev) { 395 if (tdev == dev) 396 continue; 397 for (i = 0; 398 (tres = pnp_get_resource(tdev, IORESOURCE_IRQ, i)); 399 i++) { 400 if (tres->flags & IORESOURCE_IRQ) { 401 if (cannot_compare(tres->flags)) 402 continue; 403 if (tres->start == *irq) 404 return 0; 405 } 406 } 407 } 408 409 return 1; 410 } 411 412 #ifdef CONFIG_ISA_DMA_API 413 int pnp_check_dma(struct pnp_dev *dev, struct resource *res) 414 { 415 int i; 416 struct pnp_dev *tdev; 417 struct resource *tres; 418 resource_size_t *dma; 419 420 dma = &res->start; 421 422 /* if the resource doesn't exist, don't complain about it */ 423 if (cannot_compare(res->flags)) 424 return 1; 425 426 /* check if the resource is valid */ 427 if (*dma < 0 || *dma == 4 || *dma > 7) 428 return 0; 429 430 /* check if the resource is reserved */ 431 for (i = 0; i < 8; i++) { 432 if (pnp_reserve_dma[i] == *dma) 433 return 0; 434 } 435 436 /* check for internal conflicts */ 437 for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_DMA, i)); i++) { 438 if (tres != res && tres->flags & IORESOURCE_DMA) { 439 if (tres->start == *dma) 440 return 0; 441 } 442 } 443 444 /* check if the resource is already in use, skip if the 445 * device is active because it itself may be in use */ 446 if (!dev->active) { 447 if (request_dma(*dma, "pnp")) 448 return 0; 449 free_dma(*dma); 450 } 451 452 /* check for conflicts with other pnp devices */ 453 pnp_for_each_dev(tdev) { 454 if (tdev == dev) 455 continue; 456 for (i = 0; 457 (tres = pnp_get_resource(tdev, IORESOURCE_DMA, i)); 458 i++) { 459 if (tres->flags & IORESOURCE_DMA) { 460 if (cannot_compare(tres->flags)) 461 continue; 462 if (tres->start == *dma) 463 return 0; 464 } 465 } 466 } 467 468 return 1; 469 } 470 #endif /* CONFIG_ISA_DMA_API */ 471 472 unsigned long pnp_resource_type(struct resource *res) 473 { 474 return res->flags & (IORESOURCE_IO | IORESOURCE_MEM | 475 IORESOURCE_IRQ | IORESOURCE_DMA | 476 IORESOURCE_BUS); 477 } 478 479 struct resource *pnp_get_resource(struct pnp_dev *dev, 480 unsigned long type, unsigned int num) 481 { 482 struct pnp_resource *pnp_res; 483 struct resource *res; 484 485 list_for_each_entry(pnp_res, &dev->resources, list) { 486 res = &pnp_res->res; 487 if (pnp_resource_type(res) == type && num-- == 0) 488 return res; 489 } 490 return NULL; 491 } 492 EXPORT_SYMBOL(pnp_get_resource); 493 494 static struct pnp_resource *pnp_new_resource(struct pnp_dev *dev) 495 { 496 struct pnp_resource *pnp_res; 497 498 pnp_res = kzalloc(sizeof(struct pnp_resource), GFP_KERNEL); 499 if (!pnp_res) 500 return NULL; 501 502 list_add_tail(&pnp_res->list, &dev->resources); 503 return pnp_res; 504 } 505 506 struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, 507 int flags) 508 { 509 struct pnp_resource *pnp_res; 510 struct resource *res; 511 512 pnp_res = pnp_new_resource(dev); 513 if (!pnp_res) { 514 dev_err(&dev->dev, "can't add resource for IRQ %d\n", irq); 515 return NULL; 516 } 517 518 res = &pnp_res->res; 519 res->flags = IORESOURCE_IRQ | flags; 520 res->start = irq; 521 res->end = irq; 522 523 dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); 524 return pnp_res; 525 } 526 527 struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma, 528 int flags) 529 { 530 struct pnp_resource *pnp_res; 531 struct resource *res; 532 533 pnp_res = pnp_new_resource(dev); 534 if (!pnp_res) { 535 dev_err(&dev->dev, "can't add resource for DMA %d\n", dma); 536 return NULL; 537 } 538 539 res = &pnp_res->res; 540 res->flags = IORESOURCE_DMA | flags; 541 res->start = dma; 542 res->end = dma; 543 544 dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); 545 return pnp_res; 546 } 547 548 struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev, 549 resource_size_t start, 550 resource_size_t end, int flags) 551 { 552 struct pnp_resource *pnp_res; 553 struct resource *res; 554 555 pnp_res = pnp_new_resource(dev); 556 if (!pnp_res) { 557 dev_err(&dev->dev, "can't add resource for IO %#llx-%#llx\n", 558 (unsigned long long) start, 559 (unsigned long long) end); 560 return NULL; 561 } 562 563 res = &pnp_res->res; 564 res->flags = IORESOURCE_IO | flags; 565 res->start = start; 566 res->end = end; 567 568 dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); 569 return pnp_res; 570 } 571 572 struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, 573 resource_size_t start, 574 resource_size_t end, int flags) 575 { 576 struct pnp_resource *pnp_res; 577 struct resource *res; 578 579 pnp_res = pnp_new_resource(dev); 580 if (!pnp_res) { 581 dev_err(&dev->dev, "can't add resource for MEM %#llx-%#llx\n", 582 (unsigned long long) start, 583 (unsigned long long) end); 584 return NULL; 585 } 586 587 res = &pnp_res->res; 588 res->flags = IORESOURCE_MEM | flags; 589 res->start = start; 590 res->end = end; 591 592 dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); 593 return pnp_res; 594 } 595 596 struct pnp_resource *pnp_add_bus_resource(struct pnp_dev *dev, 597 resource_size_t start, 598 resource_size_t end) 599 { 600 struct pnp_resource *pnp_res; 601 struct resource *res; 602 603 pnp_res = pnp_new_resource(dev); 604 if (!pnp_res) { 605 dev_err(&dev->dev, "can't add resource for BUS %#llx-%#llx\n", 606 (unsigned long long) start, 607 (unsigned long long) end); 608 return NULL; 609 } 610 611 res = &pnp_res->res; 612 res->flags = IORESOURCE_BUS; 613 res->start = start; 614 res->end = end; 615 616 dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); 617 return pnp_res; 618 } 619 620 /* 621 * Determine whether the specified resource is a possible configuration 622 * for this device. 623 */ 624 int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t start, 625 resource_size_t size) 626 { 627 struct pnp_option *option; 628 struct pnp_port *port; 629 struct pnp_mem *mem; 630 struct pnp_irq *irq; 631 struct pnp_dma *dma; 632 633 list_for_each_entry(option, &dev->options, list) { 634 if (option->type != type) 635 continue; 636 637 switch (option->type) { 638 case IORESOURCE_IO: 639 port = &option->u.port; 640 if (port->min == start && port->size == size) 641 return 1; 642 break; 643 case IORESOURCE_MEM: 644 mem = &option->u.mem; 645 if (mem->min == start && mem->size == size) 646 return 1; 647 break; 648 case IORESOURCE_IRQ: 649 irq = &option->u.irq; 650 if (start < PNP_IRQ_NR && 651 test_bit(start, irq->map.bits)) 652 return 1; 653 break; 654 case IORESOURCE_DMA: 655 dma = &option->u.dma; 656 if (dma->map & (1 << start)) 657 return 1; 658 break; 659 } 660 } 661 662 return 0; 663 } 664 EXPORT_SYMBOL(pnp_possible_config); 665 666 int pnp_range_reserved(resource_size_t start, resource_size_t end) 667 { 668 struct pnp_dev *dev; 669 struct pnp_resource *pnp_res; 670 resource_size_t *dev_start, *dev_end; 671 672 pnp_for_each_dev(dev) { 673 list_for_each_entry(pnp_res, &dev->resources, list) { 674 dev_start = &pnp_res->res.start; 675 dev_end = &pnp_res->res.end; 676 if (ranged_conflict(&start, &end, dev_start, dev_end)) 677 return 1; 678 } 679 } 680 return 0; 681 } 682 EXPORT_SYMBOL(pnp_range_reserved); 683 684 /* format is: pnp_reserve_irq=irq1[,irq2] .... */ 685 static int __init pnp_setup_reserve_irq(char *str) 686 { 687 int i; 688 689 for (i = 0; i < 16; i++) 690 if (get_option(&str, &pnp_reserve_irq[i]) != 2) 691 break; 692 return 1; 693 } 694 695 __setup("pnp_reserve_irq=", pnp_setup_reserve_irq); 696 697 /* format is: pnp_reserve_dma=dma1[,dma2] .... */ 698 static int __init pnp_setup_reserve_dma(char *str) 699 { 700 int i; 701 702 for (i = 0; i < 8; i++) 703 if (get_option(&str, &pnp_reserve_dma[i]) != 2) 704 break; 705 return 1; 706 } 707 708 __setup("pnp_reserve_dma=", pnp_setup_reserve_dma); 709 710 /* format is: pnp_reserve_io=io1,size1[,io2,size2] .... */ 711 static int __init pnp_setup_reserve_io(char *str) 712 { 713 int i; 714 715 for (i = 0; i < 16; i++) 716 if (get_option(&str, &pnp_reserve_io[i]) != 2) 717 break; 718 return 1; 719 } 720 721 __setup("pnp_reserve_io=", pnp_setup_reserve_io); 722 723 /* format is: pnp_reserve_mem=mem1,size1[,mem2,size2] .... */ 724 static int __init pnp_setup_reserve_mem(char *str) 725 { 726 int i; 727 728 for (i = 0; i < 16; i++) 729 if (get_option(&str, &pnp_reserve_mem[i]) != 2) 730 break; 731 return 1; 732 } 733 734 __setup("pnp_reserve_mem=", pnp_setup_reserve_mem); 735