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