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