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 25static int pnp_reserve_irq[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some IRQ */ 26static int pnp_reserve_dma[8] = {[0 ... 7] = -1 }; /* reserve (don't use) some DMA */ 27static int pnp_reserve_io[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some I/O region */ 28static int pnp_reserve_mem[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some memory region */ 29 30/* 31 * option registration 32 */ 33 34static 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 50int 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 78int 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 96int 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 119int 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 142void 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 165int 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 (!request_region(*port, length(port, end), "pnp")) 183 return 0; 184 release_region(*port, length(port, end)); 185 } 186 187 /* check if the resource is reserved */ 188 for (i = 0; i < 8; i++) { 189 int rport = pnp_reserve_io[i << 1]; 190 int rend = pnp_reserve_io[(i << 1) + 1] + rport - 1; 191 if (ranged_conflict(port, end, &rport, &rend)) 192 return 0; 193 } 194 195 /* check for internal conflicts */ 196 for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) { 197 if (tres != res && tres->flags & IORESOURCE_IO) { 198 tport = &tres->start; 199 tend = &tres->end; 200 if (ranged_conflict(port, end, tport, tend)) 201 return 0; 202 } 203 } 204 205 /* check for conflicts with other pnp devices */ 206 pnp_for_each_dev(tdev) { 207 if (tdev == dev) 208 continue; 209 for (i = 0; 210 (tres = pnp_get_resource(tdev, IORESOURCE_IO, i)); 211 i++) { 212 if (tres->flags & IORESOURCE_IO) { 213 if (cannot_compare(tres->flags)) 214 continue; 215 if (tres->flags & IORESOURCE_WINDOW) 216 continue; 217 tport = &tres->start; 218 tend = &tres->end; 219 if (ranged_conflict(port, end, tport, tend)) 220 return 0; 221 } 222 } 223 } 224 225 return 1; 226} 227 228int pnp_check_mem(struct pnp_dev *dev, struct resource *res) 229{ 230 int i; 231 struct pnp_dev *tdev; 232 struct resource *tres; 233 resource_size_t *addr, *end, *taddr, *tend; 234 235 addr = &res->start; 236 end = &res->end; 237 238 /* if the resource doesn't exist, don't complain about it */ 239 if (cannot_compare(res->flags)) 240 return 1; 241 242 /* check if the resource is already in use, skip if the 243 * device is active because it itself may be in use */ 244 if (!dev->active) { 245 if (!request_mem_region(*addr, length(addr, end), "pnp")) 246 return 0; 247 release_mem_region(*addr, length(addr, end)); 248 } 249 250 /* check if the resource is reserved */ 251 for (i = 0; i < 8; i++) { 252 int raddr = pnp_reserve_mem[i << 1]; 253 int rend = pnp_reserve_mem[(i << 1) + 1] + raddr - 1; 254 if (ranged_conflict(addr, end, &raddr, &rend)) 255 return 0; 256 } 257 258 /* check for internal conflicts */ 259 for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) { 260 if (tres != res && tres->flags & IORESOURCE_MEM) { 261 taddr = &tres->start; 262 tend = &tres->end; 263 if (ranged_conflict(addr, end, taddr, tend)) 264 return 0; 265 } 266 } 267 268 /* check for conflicts with other pnp devices */ 269 pnp_for_each_dev(tdev) { 270 if (tdev == dev) 271 continue; 272 for (i = 0; 273 (tres = pnp_get_resource(tdev, IORESOURCE_MEM, i)); 274 i++) { 275 if (tres->flags & IORESOURCE_MEM) { 276 if (cannot_compare(tres->flags)) 277 continue; 278 if (tres->flags & IORESOURCE_WINDOW) 279 continue; 280 taddr = &tres->start; 281 tend = &tres->end; 282 if (ranged_conflict(addr, end, taddr, tend)) 283 return 0; 284 } 285 } 286 } 287 288 return 1; 289} 290 291static irqreturn_t pnp_test_handler(int irq, void *dev_id) 292{ 293 return IRQ_HANDLED; 294} 295 296#ifdef CONFIG_PCI 297static int pci_dev_uses_irq(struct pnp_dev *pnp, struct pci_dev *pci, 298 unsigned int irq) 299{ 300 u32 class; 301 u8 progif; 302 303 if (pci->irq == irq) { 304 pnp_dbg(&pnp->dev, " device %s using irq %d\n", 305 pci_name(pci), irq); 306 return 1; 307 } 308 309 /* 310 * See pci_setup_device() and ata_pci_sff_activate_host() for 311 * similar IDE legacy detection. 312 */ 313 pci_read_config_dword(pci, PCI_CLASS_REVISION, &class); 314 class >>= 8; /* discard revision ID */ 315 progif = class & 0xff; 316 class >>= 8; 317 318 if (class == PCI_CLASS_STORAGE_IDE) { 319 /* 320 * Unless both channels are native-PCI mode only, 321 * treat the compatibility IRQs as busy. 322 */ 323 if ((progif & 0x5) != 0x5) 324 if (pci_get_legacy_ide_irq(pci, 0) == irq || 325 pci_get_legacy_ide_irq(pci, 1) == irq) { 326 pnp_dbg(&pnp->dev, " legacy IDE device %s " 327 "using irq %d\n", pci_name(pci), irq); 328 return 1; 329 } 330 } 331 332 return 0; 333} 334#endif 335 336static int pci_uses_irq(struct pnp_dev *pnp, unsigned int irq) 337{ 338#ifdef CONFIG_PCI 339 struct pci_dev *pci = NULL; 340 341 for_each_pci_dev(pci) { 342 if (pci_dev_uses_irq(pnp, pci, irq)) { 343 pci_dev_put(pci); 344 return 1; 345 } 346 } 347#endif 348 return 0; 349} 350 351int pnp_check_irq(struct pnp_dev *dev, struct resource *res) 352{ 353 int i; 354 struct pnp_dev *tdev; 355 struct resource *tres; 356 resource_size_t *irq; 357 358 irq = &res->start; 359 360 /* if the resource doesn't exist, don't complain about it */ 361 if (cannot_compare(res->flags)) 362 return 1; 363 364 /* check if the resource is valid */ 365 if (*irq > 15) 366 return 0; 367 368 /* check if the resource is reserved */ 369 for (i = 0; i < 16; i++) { 370 if (pnp_reserve_irq[i] == *irq) 371 return 0; 372 } 373 374 /* check for internal conflicts */ 375 for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_IRQ, i)); i++) { 376 if (tres != res && tres->flags & IORESOURCE_IRQ) { 377 if (tres->start == *irq) 378 return 0; 379 } 380 } 381 382 /* check if the resource is being used by a pci device */ 383 if (pci_uses_irq(dev, *irq)) 384 return 0; 385 386 /* check if the resource is already in use, skip if the 387 * device is active because it itself may be in use */ 388 if (!dev->active) { 389 if (request_irq(*irq, pnp_test_handler, 390 IRQF_PROBE_SHARED, "pnp", NULL)) 391 return 0; 392 free_irq(*irq, NULL); 393 } 394 395 /* check for conflicts with other pnp devices */ 396 pnp_for_each_dev(tdev) { 397 if (tdev == dev) 398 continue; 399 for (i = 0; 400 (tres = pnp_get_resource(tdev, IORESOURCE_IRQ, i)); 401 i++) { 402 if (tres->flags & IORESOURCE_IRQ) { 403 if (cannot_compare(tres->flags)) 404 continue; 405 if (tres->start == *irq) 406 return 0; 407 } 408 } 409 } 410 411 return 1; 412} 413 414#ifdef CONFIG_ISA_DMA_API 415int pnp_check_dma(struct pnp_dev *dev, struct resource *res) 416{ 417 int i; 418 struct pnp_dev *tdev; 419 struct resource *tres; 420 resource_size_t *dma; 421 422 dma = &res->start; 423 424 /* if the resource doesn't exist, don't complain about it */ 425 if (cannot_compare(res->flags)) 426 return 1; 427 428 /* check if the resource is valid */ 429 if (*dma == 4 || *dma > 7) 430 return 0; 431 432 /* check if the resource is reserved */ 433 for (i = 0; i < 8; i++) { 434 if (pnp_reserve_dma[i] == *dma) 435 return 0; 436 } 437 438 /* check for internal conflicts */ 439 for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_DMA, i)); i++) { 440 if (tres != res && tres->flags & IORESOURCE_DMA) { 441 if (tres->start == *dma) 442 return 0; 443 } 444 } 445 446 /* check if the resource is already in use, skip if the 447 * device is active because it itself may be in use */ 448 if (!dev->active) { 449 if (request_dma(*dma, "pnp")) 450 return 0; 451 free_dma(*dma); 452 } 453 454 /* check for conflicts with other pnp devices */ 455 pnp_for_each_dev(tdev) { 456 if (tdev == dev) 457 continue; 458 for (i = 0; 459 (tres = pnp_get_resource(tdev, IORESOURCE_DMA, i)); 460 i++) { 461 if (tres->flags & IORESOURCE_DMA) { 462 if (cannot_compare(tres->flags)) 463 continue; 464 if (tres->start == *dma) 465 return 0; 466 } 467 } 468 } 469 470 return 1; 471} 472#endif /* CONFIG_ISA_DMA_API */ 473 474unsigned long pnp_resource_type(struct resource *res) 475{ 476 return res->flags & (IORESOURCE_IO | IORESOURCE_MEM | 477 IORESOURCE_IRQ | IORESOURCE_DMA | 478 IORESOURCE_BUS); 479} 480 481struct resource *pnp_get_resource(struct pnp_dev *dev, 482 unsigned long type, unsigned int num) 483{ 484 struct pnp_resource *pnp_res; 485 struct resource *res; 486 487 list_for_each_entry(pnp_res, &dev->resources, list) { 488 res = &pnp_res->res; 489 if (pnp_resource_type(res) == type && num-- == 0) 490 return res; 491 } 492 return NULL; 493} 494EXPORT_SYMBOL(pnp_get_resource); 495 496static struct pnp_resource *pnp_new_resource(struct pnp_dev *dev) 497{ 498 struct pnp_resource *pnp_res; 499 500 pnp_res = kzalloc(sizeof(struct pnp_resource), GFP_KERNEL); 501 if (!pnp_res) 502 return NULL; 503 504 list_add_tail(&pnp_res->list, &dev->resources); 505 return pnp_res; 506} 507 508struct pnp_resource *pnp_add_resource(struct pnp_dev *dev, 509 struct resource *res) 510{ 511 struct pnp_resource *pnp_res; 512 513 pnp_res = pnp_new_resource(dev); 514 if (!pnp_res) { 515 dev_err(&dev->dev, "can't add resource %pR\n", res); 516 return NULL; 517 } 518 519 pnp_res->res = *res; 520 pnp_res->res.name = dev->name; 521 dev_dbg(&dev->dev, "%pR\n", res); 522 return pnp_res; 523} 524 525struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, 526 int flags) 527{ 528 struct pnp_resource *pnp_res; 529 struct resource *res; 530 531 pnp_res = pnp_new_resource(dev); 532 if (!pnp_res) { 533 dev_err(&dev->dev, "can't add resource for IRQ %d\n", irq); 534 return NULL; 535 } 536 537 res = &pnp_res->res; 538 res->flags = IORESOURCE_IRQ | flags; 539 res->start = irq; 540 res->end = irq; 541 542 dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); 543 return pnp_res; 544} 545 546struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma, 547 int flags) 548{ 549 struct pnp_resource *pnp_res; 550 struct resource *res; 551 552 pnp_res = pnp_new_resource(dev); 553 if (!pnp_res) { 554 dev_err(&dev->dev, "can't add resource for DMA %d\n", dma); 555 return NULL; 556 } 557 558 res = &pnp_res->res; 559 res->flags = IORESOURCE_DMA | flags; 560 res->start = dma; 561 res->end = dma; 562 563 dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); 564 return pnp_res; 565} 566 567struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev, 568 resource_size_t start, 569 resource_size_t end, int flags) 570{ 571 struct pnp_resource *pnp_res; 572 struct resource *res; 573 574 pnp_res = pnp_new_resource(dev); 575 if (!pnp_res) { 576 dev_err(&dev->dev, "can't add resource for IO %#llx-%#llx\n", 577 (unsigned long long) start, 578 (unsigned long long) end); 579 return NULL; 580 } 581 582 res = &pnp_res->res; 583 res->flags = IORESOURCE_IO | flags; 584 res->start = start; 585 res->end = end; 586 587 dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); 588 return pnp_res; 589} 590 591struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, 592 resource_size_t start, 593 resource_size_t end, int flags) 594{ 595 struct pnp_resource *pnp_res; 596 struct resource *res; 597 598 pnp_res = pnp_new_resource(dev); 599 if (!pnp_res) { 600 dev_err(&dev->dev, "can't add resource for MEM %#llx-%#llx\n", 601 (unsigned long long) start, 602 (unsigned long long) end); 603 return NULL; 604 } 605 606 res = &pnp_res->res; 607 res->flags = IORESOURCE_MEM | flags; 608 res->start = start; 609 res->end = end; 610 611 dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); 612 return pnp_res; 613} 614 615struct pnp_resource *pnp_add_bus_resource(struct pnp_dev *dev, 616 resource_size_t start, 617 resource_size_t end) 618{ 619 struct pnp_resource *pnp_res; 620 struct resource *res; 621 622 pnp_res = pnp_new_resource(dev); 623 if (!pnp_res) { 624 dev_err(&dev->dev, "can't add resource for BUS %#llx-%#llx\n", 625 (unsigned long long) start, 626 (unsigned long long) end); 627 return NULL; 628 } 629 630 res = &pnp_res->res; 631 res->flags = IORESOURCE_BUS; 632 res->start = start; 633 res->end = end; 634 635 dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); 636 return pnp_res; 637} 638 639/* 640 * Determine whether the specified resource is a possible configuration 641 * for this device. 642 */ 643int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t start, 644 resource_size_t size) 645{ 646 struct pnp_option *option; 647 struct pnp_port *port; 648 struct pnp_mem *mem; 649 struct pnp_irq *irq; 650 struct pnp_dma *dma; 651 652 list_for_each_entry(option, &dev->options, list) { 653 if (option->type != type) 654 continue; 655 656 switch (option->type) { 657 case IORESOURCE_IO: 658 port = &option->u.port; 659 if (port->min == start && port->size == size) 660 return 1; 661 break; 662 case IORESOURCE_MEM: 663 mem = &option->u.mem; 664 if (mem->min == start && mem->size == size) 665 return 1; 666 break; 667 case IORESOURCE_IRQ: 668 irq = &option->u.irq; 669 if (start < PNP_IRQ_NR && 670 test_bit(start, irq->map.bits)) 671 return 1; 672 break; 673 case IORESOURCE_DMA: 674 dma = &option->u.dma; 675 if (dma->map & (1 << start)) 676 return 1; 677 break; 678 } 679 } 680 681 return 0; 682} 683EXPORT_SYMBOL(pnp_possible_config); 684 685int pnp_range_reserved(resource_size_t start, resource_size_t end) 686{ 687 struct pnp_dev *dev; 688 struct pnp_resource *pnp_res; 689 resource_size_t *dev_start, *dev_end; 690 691 pnp_for_each_dev(dev) { 692 list_for_each_entry(pnp_res, &dev->resources, list) { 693 dev_start = &pnp_res->res.start; 694 dev_end = &pnp_res->res.end; 695 if (ranged_conflict(&start, &end, dev_start, dev_end)) 696 return 1; 697 } 698 } 699 return 0; 700} 701EXPORT_SYMBOL(pnp_range_reserved); 702 703/* format is: pnp_reserve_irq=irq1[,irq2] .... */ 704static int __init pnp_setup_reserve_irq(char *str) 705{ 706 int i; 707 708 for (i = 0; i < 16; i++) 709 if (get_option(&str, &pnp_reserve_irq[i]) != 2) 710 break; 711 return 1; 712} 713 714__setup("pnp_reserve_irq=", pnp_setup_reserve_irq); 715 716/* format is: pnp_reserve_dma=dma1[,dma2] .... */ 717static int __init pnp_setup_reserve_dma(char *str) 718{ 719 int i; 720 721 for (i = 0; i < 8; i++) 722 if (get_option(&str, &pnp_reserve_dma[i]) != 2) 723 break; 724 return 1; 725} 726 727__setup("pnp_reserve_dma=", pnp_setup_reserve_dma); 728 729/* format is: pnp_reserve_io=io1,size1[,io2,size2] .... */ 730static int __init pnp_setup_reserve_io(char *str) 731{ 732 int i; 733 734 for (i = 0; i < 16; i++) 735 if (get_option(&str, &pnp_reserve_io[i]) != 2) 736 break; 737 return 1; 738} 739 740__setup("pnp_reserve_io=", pnp_setup_reserve_io); 741 742/* format is: pnp_reserve_mem=mem1,size1[,mem2,size2] .... */ 743static int __init pnp_setup_reserve_mem(char *str) 744{ 745 int i; 746 747 for (i = 0; i < 16; i++) 748 if (get_option(&str, &pnp_reserve_mem[i]) != 2) 749 break; 750 return 1; 751} 752 753__setup("pnp_reserve_mem=", pnp_setup_reserve_mem); 754