0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/module.h>
0012 #include <linux/slab.h>
0013 #include <linux/errno.h>
0014 #include <linux/interrupt.h>
0015 #include <linux/kernel.h>
0016 #include <asm/io.h>
0017 #include <asm/dma.h>
0018 #include <asm/irq.h>
0019 #include <linux/pci.h>
0020 #include <linux/libata.h>
0021 #include <linux/ioport.h>
0022 #include <linux/init.h>
0023
0024 #include <linux/pnp.h>
0025 #include "base.h"
0026
0027 static int pnp_reserve_irq[16] = {[0 ... 15] = -1 };
0028 static int pnp_reserve_dma[8] = {[0 ... 7] = -1 };
0029 static int pnp_reserve_io[16] = {[0 ... 15] = -1 };
0030 static int pnp_reserve_mem[16] = {[0 ... 15] = -1 };
0031
0032
0033
0034
0035
0036 static struct pnp_option *pnp_build_option(struct pnp_dev *dev, unsigned long type,
0037 unsigned int option_flags)
0038 {
0039 struct pnp_option *option;
0040
0041 option = kzalloc(sizeof(struct pnp_option), GFP_KERNEL);
0042 if (!option)
0043 return NULL;
0044
0045 option->flags = option_flags;
0046 option->type = type;
0047
0048 list_add_tail(&option->list, &dev->options);
0049 return option;
0050 }
0051
0052 int pnp_register_irq_resource(struct pnp_dev *dev, unsigned int option_flags,
0053 pnp_irq_mask_t *map, unsigned char flags)
0054 {
0055 struct pnp_option *option;
0056 struct pnp_irq *irq;
0057
0058 option = pnp_build_option(dev, IORESOURCE_IRQ, option_flags);
0059 if (!option)
0060 return -ENOMEM;
0061
0062 irq = &option->u.irq;
0063 irq->map = *map;
0064 irq->flags = flags;
0065
0066 #ifdef CONFIG_PCI
0067 {
0068 int i;
0069
0070 for (i = 0; i < 16; i++)
0071 if (test_bit(i, irq->map.bits))
0072 pcibios_penalize_isa_irq(i, 0);
0073 }
0074 #endif
0075
0076 dbg_pnp_show_option(dev, option);
0077 return 0;
0078 }
0079
0080 int pnp_register_dma_resource(struct pnp_dev *dev, unsigned int option_flags,
0081 unsigned char map, unsigned char flags)
0082 {
0083 struct pnp_option *option;
0084 struct pnp_dma *dma;
0085
0086 option = pnp_build_option(dev, IORESOURCE_DMA, option_flags);
0087 if (!option)
0088 return -ENOMEM;
0089
0090 dma = &option->u.dma;
0091 dma->map = map;
0092 dma->flags = flags;
0093
0094 dbg_pnp_show_option(dev, option);
0095 return 0;
0096 }
0097
0098 int pnp_register_port_resource(struct pnp_dev *dev, unsigned int option_flags,
0099 resource_size_t min, resource_size_t max,
0100 resource_size_t align, resource_size_t size,
0101 unsigned char flags)
0102 {
0103 struct pnp_option *option;
0104 struct pnp_port *port;
0105
0106 option = pnp_build_option(dev, IORESOURCE_IO, option_flags);
0107 if (!option)
0108 return -ENOMEM;
0109
0110 port = &option->u.port;
0111 port->min = min;
0112 port->max = max;
0113 port->align = align;
0114 port->size = size;
0115 port->flags = flags;
0116
0117 dbg_pnp_show_option(dev, option);
0118 return 0;
0119 }
0120
0121 int pnp_register_mem_resource(struct pnp_dev *dev, unsigned int option_flags,
0122 resource_size_t min, resource_size_t max,
0123 resource_size_t align, resource_size_t size,
0124 unsigned char flags)
0125 {
0126 struct pnp_option *option;
0127 struct pnp_mem *mem;
0128
0129 option = pnp_build_option(dev, IORESOURCE_MEM, option_flags);
0130 if (!option)
0131 return -ENOMEM;
0132
0133 mem = &option->u.mem;
0134 mem->min = min;
0135 mem->max = max;
0136 mem->align = align;
0137 mem->size = size;
0138 mem->flags = flags;
0139
0140 dbg_pnp_show_option(dev, option);
0141 return 0;
0142 }
0143
0144 void pnp_free_options(struct pnp_dev *dev)
0145 {
0146 struct pnp_option *option, *tmp;
0147
0148 list_for_each_entry_safe(option, tmp, &dev->options, list) {
0149 list_del(&option->list);
0150 kfree(option);
0151 }
0152 }
0153
0154
0155
0156
0157
0158 #define length(start, end) (*(end) - *(start) + 1)
0159
0160
0161 #define ranged_conflict(starta, enda, startb, endb) \
0162 !((*(enda) < *(startb)) || (*(endb) < *(starta)))
0163
0164 #define cannot_compare(flags) \
0165 ((flags) & IORESOURCE_DISABLED)
0166
0167 int pnp_check_port(struct pnp_dev *dev, struct resource *res)
0168 {
0169 int i;
0170 struct pnp_dev *tdev;
0171 struct resource *tres;
0172 resource_size_t *port, *end, *tport, *tend;
0173
0174 port = &res->start;
0175 end = &res->end;
0176
0177
0178 if (cannot_compare(res->flags))
0179 return 1;
0180
0181
0182
0183 if (!dev->active) {
0184 if (!request_region(*port, length(port, end), "pnp"))
0185 return 0;
0186 release_region(*port, length(port, end));
0187 }
0188
0189
0190 for (i = 0; i < 8; i++) {
0191 int rport = pnp_reserve_io[i << 1];
0192 int rend = pnp_reserve_io[(i << 1) + 1] + rport - 1;
0193 if (ranged_conflict(port, end, &rport, &rend))
0194 return 0;
0195 }
0196
0197
0198 for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) {
0199 if (tres != res && tres->flags & IORESOURCE_IO) {
0200 tport = &tres->start;
0201 tend = &tres->end;
0202 if (ranged_conflict(port, end, tport, tend))
0203 return 0;
0204 }
0205 }
0206
0207
0208 pnp_for_each_dev(tdev) {
0209 if (tdev == dev)
0210 continue;
0211 for (i = 0;
0212 (tres = pnp_get_resource(tdev, IORESOURCE_IO, i));
0213 i++) {
0214 if (tres->flags & IORESOURCE_IO) {
0215 if (cannot_compare(tres->flags))
0216 continue;
0217 if (tres->flags & IORESOURCE_WINDOW)
0218 continue;
0219 tport = &tres->start;
0220 tend = &tres->end;
0221 if (ranged_conflict(port, end, tport, tend))
0222 return 0;
0223 }
0224 }
0225 }
0226
0227 return 1;
0228 }
0229
0230 int pnp_check_mem(struct pnp_dev *dev, struct resource *res)
0231 {
0232 int i;
0233 struct pnp_dev *tdev;
0234 struct resource *tres;
0235 resource_size_t *addr, *end, *taddr, *tend;
0236
0237 addr = &res->start;
0238 end = &res->end;
0239
0240
0241 if (cannot_compare(res->flags))
0242 return 1;
0243
0244
0245
0246 if (!dev->active) {
0247 if (!request_mem_region(*addr, length(addr, end), "pnp"))
0248 return 0;
0249 release_mem_region(*addr, length(addr, end));
0250 }
0251
0252
0253 for (i = 0; i < 8; i++) {
0254 int raddr = pnp_reserve_mem[i << 1];
0255 int rend = pnp_reserve_mem[(i << 1) + 1] + raddr - 1;
0256 if (ranged_conflict(addr, end, &raddr, &rend))
0257 return 0;
0258 }
0259
0260
0261 for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
0262 if (tres != res && tres->flags & IORESOURCE_MEM) {
0263 taddr = &tres->start;
0264 tend = &tres->end;
0265 if (ranged_conflict(addr, end, taddr, tend))
0266 return 0;
0267 }
0268 }
0269
0270
0271 pnp_for_each_dev(tdev) {
0272 if (tdev == dev)
0273 continue;
0274 for (i = 0;
0275 (tres = pnp_get_resource(tdev, IORESOURCE_MEM, i));
0276 i++) {
0277 if (tres->flags & IORESOURCE_MEM) {
0278 if (cannot_compare(tres->flags))
0279 continue;
0280 if (tres->flags & IORESOURCE_WINDOW)
0281 continue;
0282 taddr = &tres->start;
0283 tend = &tres->end;
0284 if (ranged_conflict(addr, end, taddr, tend))
0285 return 0;
0286 }
0287 }
0288 }
0289
0290 return 1;
0291 }
0292
0293 static irqreturn_t pnp_test_handler(int irq, void *dev_id)
0294 {
0295 return IRQ_HANDLED;
0296 }
0297
0298 #ifdef CONFIG_PCI
0299 static int pci_dev_uses_irq(struct pnp_dev *pnp, struct pci_dev *pci,
0300 unsigned int irq)
0301 {
0302 u32 class;
0303 u8 progif;
0304
0305 if (pci->irq == irq) {
0306 pnp_dbg(&pnp->dev, " device %s using irq %d\n",
0307 pci_name(pci), irq);
0308 return 1;
0309 }
0310
0311
0312
0313
0314
0315 pci_read_config_dword(pci, PCI_CLASS_REVISION, &class);
0316 class >>= 8;
0317 progif = class & 0xff;
0318 class >>= 8;
0319
0320 if (class == PCI_CLASS_STORAGE_IDE) {
0321
0322
0323
0324
0325 if ((progif & 0x5) != 0x5)
0326 if (ATA_PRIMARY_IRQ(pci) == irq ||
0327 ATA_SECONDARY_IRQ(pci) == irq) {
0328 pnp_dbg(&pnp->dev, " legacy IDE device %s "
0329 "using irq %d\n", pci_name(pci), irq);
0330 return 1;
0331 }
0332 }
0333
0334 return 0;
0335 }
0336 #endif
0337
0338 static int pci_uses_irq(struct pnp_dev *pnp, unsigned int irq)
0339 {
0340 #ifdef CONFIG_PCI
0341 struct pci_dev *pci = NULL;
0342
0343 for_each_pci_dev(pci) {
0344 if (pci_dev_uses_irq(pnp, pci, irq)) {
0345 pci_dev_put(pci);
0346 return 1;
0347 }
0348 }
0349 #endif
0350 return 0;
0351 }
0352
0353 int pnp_check_irq(struct pnp_dev *dev, struct resource *res)
0354 {
0355 int i;
0356 struct pnp_dev *tdev;
0357 struct resource *tres;
0358 resource_size_t *irq;
0359
0360 irq = &res->start;
0361
0362
0363 if (cannot_compare(res->flags))
0364 return 1;
0365
0366
0367 if (*irq > 15)
0368 return 0;
0369
0370
0371 for (i = 0; i < 16; i++) {
0372 if (pnp_reserve_irq[i] == *irq)
0373 return 0;
0374 }
0375
0376
0377 for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_IRQ, i)); i++) {
0378 if (tres != res && tres->flags & IORESOURCE_IRQ) {
0379 if (tres->start == *irq)
0380 return 0;
0381 }
0382 }
0383
0384
0385 if (pci_uses_irq(dev, *irq))
0386 return 0;
0387
0388
0389
0390 if (!dev->active) {
0391 if (request_irq(*irq, pnp_test_handler,
0392 IRQF_PROBE_SHARED, "pnp", NULL))
0393 return 0;
0394 free_irq(*irq, NULL);
0395 }
0396
0397
0398 pnp_for_each_dev(tdev) {
0399 if (tdev == dev)
0400 continue;
0401 for (i = 0;
0402 (tres = pnp_get_resource(tdev, IORESOURCE_IRQ, i));
0403 i++) {
0404 if (tres->flags & IORESOURCE_IRQ) {
0405 if (cannot_compare(tres->flags))
0406 continue;
0407 if (tres->start == *irq)
0408 return 0;
0409 }
0410 }
0411 }
0412
0413 return 1;
0414 }
0415
0416 #ifdef CONFIG_ISA_DMA_API
0417 int pnp_check_dma(struct pnp_dev *dev, struct resource *res)
0418 {
0419 int i;
0420 struct pnp_dev *tdev;
0421 struct resource *tres;
0422 resource_size_t *dma;
0423
0424 dma = &res->start;
0425
0426
0427 if (cannot_compare(res->flags))
0428 return 1;
0429
0430
0431 if (*dma == 4 || *dma > 7)
0432 return 0;
0433
0434
0435 for (i = 0; i < 8; i++) {
0436 if (pnp_reserve_dma[i] == *dma)
0437 return 0;
0438 }
0439
0440
0441 for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_DMA, i)); i++) {
0442 if (tres != res && tres->flags & IORESOURCE_DMA) {
0443 if (tres->start == *dma)
0444 return 0;
0445 }
0446 }
0447
0448
0449
0450 if (!dev->active) {
0451 if (request_dma(*dma, "pnp"))
0452 return 0;
0453 free_dma(*dma);
0454 }
0455
0456
0457 pnp_for_each_dev(tdev) {
0458 if (tdev == dev)
0459 continue;
0460 for (i = 0;
0461 (tres = pnp_get_resource(tdev, IORESOURCE_DMA, i));
0462 i++) {
0463 if (tres->flags & IORESOURCE_DMA) {
0464 if (cannot_compare(tres->flags))
0465 continue;
0466 if (tres->start == *dma)
0467 return 0;
0468 }
0469 }
0470 }
0471
0472 return 1;
0473 }
0474 #endif
0475
0476 unsigned long pnp_resource_type(struct resource *res)
0477 {
0478 return res->flags & (IORESOURCE_IO | IORESOURCE_MEM |
0479 IORESOURCE_IRQ | IORESOURCE_DMA |
0480 IORESOURCE_BUS);
0481 }
0482
0483 struct resource *pnp_get_resource(struct pnp_dev *dev,
0484 unsigned long type, unsigned int num)
0485 {
0486 struct pnp_resource *pnp_res;
0487 struct resource *res;
0488
0489 list_for_each_entry(pnp_res, &dev->resources, list) {
0490 res = &pnp_res->res;
0491 if (pnp_resource_type(res) == type && num-- == 0)
0492 return res;
0493 }
0494 return NULL;
0495 }
0496 EXPORT_SYMBOL(pnp_get_resource);
0497
0498 static struct pnp_resource *pnp_new_resource(struct pnp_dev *dev)
0499 {
0500 struct pnp_resource *pnp_res;
0501
0502 pnp_res = kzalloc(sizeof(struct pnp_resource), GFP_KERNEL);
0503 if (!pnp_res)
0504 return NULL;
0505
0506 list_add_tail(&pnp_res->list, &dev->resources);
0507 return pnp_res;
0508 }
0509
0510 struct pnp_resource *pnp_add_resource(struct pnp_dev *dev,
0511 struct resource *res)
0512 {
0513 struct pnp_resource *pnp_res;
0514
0515 pnp_res = pnp_new_resource(dev);
0516 if (!pnp_res) {
0517 dev_err(&dev->dev, "can't add resource %pR\n", res);
0518 return NULL;
0519 }
0520
0521 pnp_res->res = *res;
0522 pnp_res->res.name = dev->name;
0523 dev_dbg(&dev->dev, "%pR\n", res);
0524 return pnp_res;
0525 }
0526
0527 struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
0528 int flags)
0529 {
0530 struct pnp_resource *pnp_res;
0531 struct resource *res;
0532
0533 pnp_res = pnp_new_resource(dev);
0534 if (!pnp_res) {
0535 dev_err(&dev->dev, "can't add resource for IRQ %d\n", irq);
0536 return NULL;
0537 }
0538
0539 res = &pnp_res->res;
0540 res->flags = IORESOURCE_IRQ | flags;
0541 res->start = irq;
0542 res->end = irq;
0543
0544 dev_dbg(&dev->dev, "%pR\n", res);
0545 return pnp_res;
0546 }
0547
0548 struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma,
0549 int flags)
0550 {
0551 struct pnp_resource *pnp_res;
0552 struct resource *res;
0553
0554 pnp_res = pnp_new_resource(dev);
0555 if (!pnp_res) {
0556 dev_err(&dev->dev, "can't add resource for DMA %d\n", dma);
0557 return NULL;
0558 }
0559
0560 res = &pnp_res->res;
0561 res->flags = IORESOURCE_DMA | flags;
0562 res->start = dma;
0563 res->end = dma;
0564
0565 dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res);
0566 return pnp_res;
0567 }
0568
0569 struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev,
0570 resource_size_t start,
0571 resource_size_t end, int flags)
0572 {
0573 struct pnp_resource *pnp_res;
0574 struct resource *res;
0575
0576 pnp_res = pnp_new_resource(dev);
0577 if (!pnp_res) {
0578 dev_err(&dev->dev, "can't add resource for IO %#llx-%#llx\n",
0579 (unsigned long long) start,
0580 (unsigned long long) end);
0581 return NULL;
0582 }
0583
0584 res = &pnp_res->res;
0585 res->flags = IORESOURCE_IO | flags;
0586 res->start = start;
0587 res->end = end;
0588
0589 dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res);
0590 return pnp_res;
0591 }
0592
0593 struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
0594 resource_size_t start,
0595 resource_size_t end, int flags)
0596 {
0597 struct pnp_resource *pnp_res;
0598 struct resource *res;
0599
0600 pnp_res = pnp_new_resource(dev);
0601 if (!pnp_res) {
0602 dev_err(&dev->dev, "can't add resource for MEM %#llx-%#llx\n",
0603 (unsigned long long) start,
0604 (unsigned long long) end);
0605 return NULL;
0606 }
0607
0608 res = &pnp_res->res;
0609 res->flags = IORESOURCE_MEM | flags;
0610 res->start = start;
0611 res->end = end;
0612
0613 dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res);
0614 return pnp_res;
0615 }
0616
0617 struct pnp_resource *pnp_add_bus_resource(struct pnp_dev *dev,
0618 resource_size_t start,
0619 resource_size_t end)
0620 {
0621 struct pnp_resource *pnp_res;
0622 struct resource *res;
0623
0624 pnp_res = pnp_new_resource(dev);
0625 if (!pnp_res) {
0626 dev_err(&dev->dev, "can't add resource for BUS %#llx-%#llx\n",
0627 (unsigned long long) start,
0628 (unsigned long long) end);
0629 return NULL;
0630 }
0631
0632 res = &pnp_res->res;
0633 res->flags = IORESOURCE_BUS;
0634 res->start = start;
0635 res->end = end;
0636
0637 dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res);
0638 return pnp_res;
0639 }
0640
0641
0642
0643
0644
0645 int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t start,
0646 resource_size_t size)
0647 {
0648 struct pnp_option *option;
0649 struct pnp_port *port;
0650 struct pnp_mem *mem;
0651 struct pnp_irq *irq;
0652 struct pnp_dma *dma;
0653
0654 list_for_each_entry(option, &dev->options, list) {
0655 if (option->type != type)
0656 continue;
0657
0658 switch (option->type) {
0659 case IORESOURCE_IO:
0660 port = &option->u.port;
0661 if (port->min == start && port->size == size)
0662 return 1;
0663 break;
0664 case IORESOURCE_MEM:
0665 mem = &option->u.mem;
0666 if (mem->min == start && mem->size == size)
0667 return 1;
0668 break;
0669 case IORESOURCE_IRQ:
0670 irq = &option->u.irq;
0671 if (start < PNP_IRQ_NR &&
0672 test_bit(start, irq->map.bits))
0673 return 1;
0674 break;
0675 case IORESOURCE_DMA:
0676 dma = &option->u.dma;
0677 if (dma->map & (1 << start))
0678 return 1;
0679 break;
0680 }
0681 }
0682
0683 return 0;
0684 }
0685 EXPORT_SYMBOL(pnp_possible_config);
0686
0687 int pnp_range_reserved(resource_size_t start, resource_size_t end)
0688 {
0689 struct pnp_dev *dev;
0690 struct pnp_resource *pnp_res;
0691 resource_size_t *dev_start, *dev_end;
0692
0693 pnp_for_each_dev(dev) {
0694 list_for_each_entry(pnp_res, &dev->resources, list) {
0695 dev_start = &pnp_res->res.start;
0696 dev_end = &pnp_res->res.end;
0697 if (ranged_conflict(&start, &end, dev_start, dev_end))
0698 return 1;
0699 }
0700 }
0701 return 0;
0702 }
0703 EXPORT_SYMBOL(pnp_range_reserved);
0704
0705
0706 static int __init pnp_setup_reserve_irq(char *str)
0707 {
0708 int i;
0709
0710 for (i = 0; i < 16; i++)
0711 if (get_option(&str, &pnp_reserve_irq[i]) != 2)
0712 break;
0713 return 1;
0714 }
0715
0716 __setup("pnp_reserve_irq=", pnp_setup_reserve_irq);
0717
0718
0719 static int __init pnp_setup_reserve_dma(char *str)
0720 {
0721 int i;
0722
0723 for (i = 0; i < 8; i++)
0724 if (get_option(&str, &pnp_reserve_dma[i]) != 2)
0725 break;
0726 return 1;
0727 }
0728
0729 __setup("pnp_reserve_dma=", pnp_setup_reserve_dma);
0730
0731
0732 static int __init pnp_setup_reserve_io(char *str)
0733 {
0734 int i;
0735
0736 for (i = 0; i < 16; i++)
0737 if (get_option(&str, &pnp_reserve_io[i]) != 2)
0738 break;
0739 return 1;
0740 }
0741
0742 __setup("pnp_reserve_io=", pnp_setup_reserve_io);
0743
0744
0745 static int __init pnp_setup_reserve_mem(char *str)
0746 {
0747 int i;
0748
0749 for (i = 0; i < 16; i++)
0750 if (get_option(&str, &pnp_reserve_mem[i]) != 2)
0751 break;
0752 return 1;
0753 }
0754
0755 __setup("pnp_reserve_mem=", pnp_setup_reserve_mem);