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 (__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 227int 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 289static irqreturn_t pnp_test_handler(int irq, void *dev_id) 290{ 291 return IRQ_HANDLED; 292} 293 294#ifdef CONFIG_PCI 295static 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 334static 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 349int 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 > 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_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 413int 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 == 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 472unsigned 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 479struct 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} 492EXPORT_SYMBOL(pnp_get_resource); 493 494static 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 506struct pnp_resource *pnp_add_resource(struct pnp_dev *dev, 507 struct resource *res) 508{ 509 struct pnp_resource *pnp_res; 510 511 pnp_res = pnp_new_resource(dev); 512 if (!pnp_res) { 513 dev_err(&dev->dev, "can't add resource %pR\n", res); 514 return NULL; 515 } 516 517 pnp_res->res = *res; 518 pnp_res->res.name = dev->name; 519 dev_dbg(&dev->dev, "%pR\n", res); 520 return pnp_res; 521} 522 523struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, 524 int flags) 525{ 526 struct pnp_resource *pnp_res; 527 struct resource *res; 528 529 pnp_res = pnp_new_resource(dev); 530 if (!pnp_res) { 531 dev_err(&dev->dev, "can't add resource for IRQ %d\n", irq); 532 return NULL; 533 } 534 535 res = &pnp_res->res; 536 res->flags = IORESOURCE_IRQ | flags; 537 res->start = irq; 538 res->end = irq; 539 540 dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); 541 return pnp_res; 542} 543 544struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma, 545 int flags) 546{ 547 struct pnp_resource *pnp_res; 548 struct resource *res; 549 550 pnp_res = pnp_new_resource(dev); 551 if (!pnp_res) { 552 dev_err(&dev->dev, "can't add resource for DMA %d\n", dma); 553 return NULL; 554 } 555 556 res = &pnp_res->res; 557 res->flags = IORESOURCE_DMA | flags; 558 res->start = dma; 559 res->end = dma; 560 561 dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); 562 return pnp_res; 563} 564 565struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev, 566 resource_size_t start, 567 resource_size_t end, int flags) 568{ 569 struct pnp_resource *pnp_res; 570 struct resource *res; 571 572 pnp_res = pnp_new_resource(dev); 573 if (!pnp_res) { 574 dev_err(&dev->dev, "can't add resource for IO %#llx-%#llx\n", 575 (unsigned long long) start, 576 (unsigned long long) end); 577 return NULL; 578 } 579 580 res = &pnp_res->res; 581 res->flags = IORESOURCE_IO | flags; 582 res->start = start; 583 res->end = end; 584 585 dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); 586 return pnp_res; 587} 588 589struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, 590 resource_size_t start, 591 resource_size_t end, int flags) 592{ 593 struct pnp_resource *pnp_res; 594 struct resource *res; 595 596 pnp_res = pnp_new_resource(dev); 597 if (!pnp_res) { 598 dev_err(&dev->dev, "can't add resource for MEM %#llx-%#llx\n", 599 (unsigned long long) start, 600 (unsigned long long) end); 601 return NULL; 602 } 603 604 res = &pnp_res->res; 605 res->flags = IORESOURCE_MEM | flags; 606 res->start = start; 607 res->end = end; 608 609 dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); 610 return pnp_res; 611} 612 613struct pnp_resource *pnp_add_bus_resource(struct pnp_dev *dev, 614 resource_size_t start, 615 resource_size_t end) 616{ 617 struct pnp_resource *pnp_res; 618 struct resource *res; 619 620 pnp_res = pnp_new_resource(dev); 621 if (!pnp_res) { 622 dev_err(&dev->dev, "can't add resource for BUS %#llx-%#llx\n", 623 (unsigned long long) start, 624 (unsigned long long) end); 625 return NULL; 626 } 627 628 res = &pnp_res->res; 629 res->flags = IORESOURCE_BUS; 630 res->start = start; 631 res->end = end; 632 633 dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); 634 return pnp_res; 635} 636 637/* 638 * Determine whether the specified resource is a possible configuration 639 * for this device. 640 */ 641int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t start, 642 resource_size_t size) 643{ 644 struct pnp_option *option; 645 struct pnp_port *port; 646 struct pnp_mem *mem; 647 struct pnp_irq *irq; 648 struct pnp_dma *dma; 649 650 list_for_each_entry(option, &dev->options, list) { 651 if (option->type != type) 652 continue; 653 654 switch (option->type) { 655 case IORESOURCE_IO: 656 port = &option->u.port; 657 if (port->min == start && port->size == size) 658 return 1; 659 break; 660 case IORESOURCE_MEM: 661 mem = &option->u.mem; 662 if (mem->min == start && mem->size == size) 663 return 1; 664 break; 665 case IORESOURCE_IRQ: 666 irq = &option->u.irq; 667 if (start < PNP_IRQ_NR && 668 test_bit(start, irq->map.bits)) 669 return 1; 670 break; 671 case IORESOURCE_DMA: 672 dma = &option->u.dma; 673 if (dma->map & (1 << start)) 674 return 1; 675 break; 676 } 677 } 678 679 return 0; 680} 681EXPORT_SYMBOL(pnp_possible_config); 682 683int pnp_range_reserved(resource_size_t start, resource_size_t end) 684{ 685 struct pnp_dev *dev; 686 struct pnp_resource *pnp_res; 687 resource_size_t *dev_start, *dev_end; 688 689 pnp_for_each_dev(dev) { 690 list_for_each_entry(pnp_res, &dev->resources, list) { 691 dev_start = &pnp_res->res.start; 692 dev_end = &pnp_res->res.end; 693 if (ranged_conflict(&start, &end, dev_start, dev_end)) 694 return 1; 695 } 696 } 697 return 0; 698} 699EXPORT_SYMBOL(pnp_range_reserved); 700 701/* format is: pnp_reserve_irq=irq1[,irq2] .... */ 702static int __init pnp_setup_reserve_irq(char *str) 703{ 704 int i; 705 706 for (i = 0; i < 16; i++) 707 if (get_option(&str, &pnp_reserve_irq[i]) != 2) 708 break; 709 return 1; 710} 711 712__setup("pnp_reserve_irq=", pnp_setup_reserve_irq); 713 714/* format is: pnp_reserve_dma=dma1[,dma2] .... */ 715static int __init pnp_setup_reserve_dma(char *str) 716{ 717 int i; 718 719 for (i = 0; i < 8; i++) 720 if (get_option(&str, &pnp_reserve_dma[i]) != 2) 721 break; 722 return 1; 723} 724 725__setup("pnp_reserve_dma=", pnp_setup_reserve_dma); 726 727/* format is: pnp_reserve_io=io1,size1[,io2,size2] .... */ 728static int __init pnp_setup_reserve_io(char *str) 729{ 730 int i; 731 732 for (i = 0; i < 16; i++) 733 if (get_option(&str, &pnp_reserve_io[i]) != 2) 734 break; 735 return 1; 736} 737 738__setup("pnp_reserve_io=", pnp_setup_reserve_io); 739 740/* format is: pnp_reserve_mem=mem1,size1[,mem2,size2] .... */ 741static int __init pnp_setup_reserve_mem(char *str) 742{ 743 int i; 744 745 for (i = 0; i < 16; i++) 746 if (get_option(&str, &pnp_reserve_mem[i]) != 2) 747 break; 748 return 1; 749} 750 751__setup("pnp_reserve_mem=", pnp_setup_reserve_mem); 752