2 * resource.c - Contains functions for registering and analyzing resource information
4 * based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz>
5 * Copyright 2003 Adam Belay <ambx1@neo.rr.com>
8 #include <linux/module.h>
9 #include <linux/errno.h>
10 #include <linux/interrupt.h>
11 #include <linux/kernel.h>
15 #include <linux/pci.h>
16 #include <linux/ioport.h>
17 #include <linux/init.h>
19 #include <linux/pnp.h>
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 */
31 struct pnp_option
*pnp_build_option(int priority
)
33 struct pnp_option
*option
= pnp_alloc(sizeof(struct pnp_option
));
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
;
46 struct pnp_option
*pnp_register_independent_option(struct pnp_dev
*dev
)
48 struct pnp_option
*option
;
50 option
= pnp_build_option(PNP_RES_PRIORITY_PREFERRED
);
52 /* this should never happen but if it does we'll try to continue */
54 dev_err(&dev
->dev
, "independent resource already registered\n");
55 dev
->independent
= option
;
57 dev_dbg(&dev
->dev
, "new independent option\n");
61 struct pnp_option
*pnp_register_dependent_option(struct pnp_dev
*dev
,
64 struct pnp_option
*option
;
66 option
= pnp_build_option(priority
);
69 struct pnp_option
*parent
= dev
->dependent
;
71 parent
= parent
->next
;
72 parent
->next
= option
;
74 dev
->dependent
= option
;
76 dev_dbg(&dev
->dev
, "new dependent option (priority %#x)\n", priority
);
80 int pnp_register_irq_resource(struct pnp_dev
*dev
, struct pnp_option
*option
,
85 char buf
[PNP_IRQ_NR
]; /* hex-encoded, so this is overkill but safe */
89 while (ptr
&& ptr
->next
)
100 for (i
= 0; i
< 16; i
++)
101 if (test_bit(i
, data
->map
))
102 pcibios_penalize_isa_irq(i
, 0);
107 bitmap_scnprintf(buf
, sizeof(buf
), data
->map
, PNP_IRQ_NR
);
108 dev_dbg(&dev
->dev
, " irq bitmask %s flags %#x\n", buf
,
114 int pnp_register_dma_resource(struct pnp_dev
*dev
, struct pnp_option
*option
,
115 struct pnp_dma
*data
)
120 while (ptr
&& ptr
->next
)
127 dev_dbg(&dev
->dev
, " dma bitmask %#x flags %#x\n", data
->map
,
132 int pnp_register_port_resource(struct pnp_dev
*dev
, struct pnp_option
*option
,
133 struct pnp_port
*data
)
135 struct pnp_port
*ptr
;
138 while (ptr
&& ptr
->next
)
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
);
151 int pnp_register_mem_resource(struct pnp_dev
*dev
, struct pnp_option
*option
,
152 struct pnp_mem
*data
)
157 while (ptr
&& ptr
->next
)
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
);
170 static void pnp_free_port(struct pnp_port
*port
)
172 struct pnp_port
*next
;
181 static void pnp_free_irq(struct pnp_irq
*irq
)
183 struct pnp_irq
*next
;
192 static void pnp_free_dma(struct pnp_dma
*dma
)
194 struct pnp_dma
*next
;
203 static void pnp_free_mem(struct pnp_mem
*mem
)
205 struct pnp_mem
*next
;
214 void pnp_free_option(struct pnp_option
*option
)
216 struct pnp_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
);
230 * resource validity checking
233 #define length(start, end) (*(end) - *(start) + 1)
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)))
239 #define cannot_compare(flags) \
240 ((flags) & (IORESOURCE_UNSET | IORESOURCE_DISABLED))
242 int pnp_check_port(struct pnp_dev
*dev
, struct resource
*res
)
245 struct pnp_dev
*tdev
;
246 struct resource
*tres
;
247 resource_size_t
*port
, *end
, *tport
, *tend
;
252 /* if the resource doesn't exist, don't complain about it */
253 if (cannot_compare(res
->flags
))
256 /* check if the resource is already in use, skip if the
257 * device is active because it itself may be in use */
259 if (__check_region(&ioport_resource
, *port
, length(port
, end
)))
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
))
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
;
276 if (ranged_conflict(port
, end
, tport
, tend
))
281 /* check for conflicts with other pnp devices */
282 pnp_for_each_dev(tdev
) {
286 (tres
= pnp_get_resource(tdev
, IORESOURCE_IO
, i
));
288 if (tres
->flags
& IORESOURCE_IO
) {
289 if (cannot_compare(tres
->flags
))
291 tport
= &tres
->start
;
293 if (ranged_conflict(port
, end
, tport
, tend
))
302 int pnp_check_mem(struct pnp_dev
*dev
, struct resource
*res
)
305 struct pnp_dev
*tdev
;
306 struct resource
*tres
;
307 resource_size_t
*addr
, *end
, *taddr
, *tend
;
312 /* if the resource doesn't exist, don't complain about it */
313 if (cannot_compare(res
->flags
))
316 /* check if the resource is already in use, skip if the
317 * device is active because it itself may be in use */
319 if (check_mem_region(*addr
, length(addr
, end
)))
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
))
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
;
336 if (ranged_conflict(addr
, end
, taddr
, tend
))
341 /* check for conflicts with other pnp devices */
342 pnp_for_each_dev(tdev
) {
346 (tres
= pnp_get_resource(tdev
, IORESOURCE_MEM
, i
));
348 if (tres
->flags
& IORESOURCE_MEM
) {
349 if (cannot_compare(tres
->flags
))
351 taddr
= &tres
->start
;
353 if (ranged_conflict(addr
, end
, taddr
, tend
))
362 static irqreturn_t
pnp_test_handler(int irq
, void *dev_id
)
367 int pnp_check_irq(struct pnp_dev
*dev
, struct resource
*res
)
370 struct pnp_dev
*tdev
;
371 struct resource
*tres
;
372 resource_size_t
*irq
;
376 /* if the resource doesn't exist, don't complain about it */
377 if (cannot_compare(res
->flags
))
380 /* check if the resource is valid */
381 if (*irq
< 0 || *irq
> 15)
384 /* check if the resource is reserved */
385 for (i
= 0; i
< 16; i
++) {
386 if (pnp_reserve_irq
[i
] == *irq
)
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
)
399 /* check if the resource is being used by a pci device */
401 struct pci_dev
*pci
= NULL
;
402 for_each_pci_dev(pci
) {
403 if (pci
->irq
== *irq
) {
411 /* check if the resource is already in use, skip if the
412 * device is active because it itself may be in use */
414 if (request_irq(*irq
, pnp_test_handler
,
415 IRQF_DISABLED
| IRQF_PROBE_SHARED
, "pnp", NULL
))
417 free_irq(*irq
, NULL
);
420 /* check for conflicts with other pnp devices */
421 pnp_for_each_dev(tdev
) {
425 (tres
= pnp_get_resource(tdev
, IORESOURCE_IRQ
, i
));
427 if (tres
->flags
& IORESOURCE_IRQ
) {
428 if (cannot_compare(tres
->flags
))
430 if (tres
->start
== *irq
)
439 int pnp_check_dma(struct pnp_dev
*dev
, struct resource
*res
)
443 struct pnp_dev
*tdev
;
444 struct resource
*tres
;
445 resource_size_t
*dma
;
449 /* if the resource doesn't exist, don't complain about it */
450 if (cannot_compare(res
->flags
))
453 /* check if the resource is valid */
454 if (*dma
< 0 || *dma
== 4 || *dma
> 7)
457 /* check if the resource is reserved */
458 for (i
= 0; i
< 8; i
++) {
459 if (pnp_reserve_dma
[i
] == *dma
)
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
)
471 /* check if the resource is already in use, skip if the
472 * device is active because it itself may be in use */
474 if (request_dma(*dma
, "pnp"))
479 /* check for conflicts with other pnp devices */
480 pnp_for_each_dev(tdev
) {
484 (tres
= pnp_get_resource(tdev
, IORESOURCE_DMA
, i
));
486 if (tres
->flags
& IORESOURCE_DMA
) {
487 if (cannot_compare(tres
->flags
))
489 if (tres
->start
== *dma
)
497 /* IA64 does not have legacy DMA */
502 struct pnp_resource
*pnp_get_pnp_resource(struct pnp_dev
*dev
,
503 unsigned int type
, unsigned int num
)
505 struct pnp_resource_table
*res
= dev
->res
;
509 if (num
>= PNP_MAX_PORT
)
511 return &res
->port
[num
];
513 if (num
>= PNP_MAX_MEM
)
515 return &res
->mem
[num
];
517 if (num
>= PNP_MAX_IRQ
)
519 return &res
->irq
[num
];
521 if (num
>= PNP_MAX_DMA
)
523 return &res
->dma
[num
];
528 struct resource
*pnp_get_resource(struct pnp_dev
*dev
,
529 unsigned int type
, unsigned int num
)
531 struct pnp_resource
*pnp_res
;
533 pnp_res
= pnp_get_pnp_resource(dev
, type
, num
);
535 return &pnp_res
->res
;
539 EXPORT_SYMBOL(pnp_get_resource
);
541 static struct pnp_resource
*pnp_new_resource(struct pnp_dev
*dev
, int type
)
543 struct pnp_resource
*pnp_res
;
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
))
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
))
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
))
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
))
579 struct pnp_resource
*pnp_add_irq_resource(struct pnp_dev
*dev
, int irq
,
582 struct pnp_resource
*pnp_res
;
583 struct resource
*res
;
584 static unsigned char warned
;
586 pnp_res
= pnp_new_resource(dev
, IORESOURCE_IRQ
);
589 dev_err(&dev
->dev
, "can't add resource for IRQ %d\n",
597 res
->flags
= IORESOURCE_IRQ
| flags
;
601 dev_dbg(&dev
->dev
, " add irq %d flags %#x\n", irq
, flags
);
605 struct pnp_resource
*pnp_add_dma_resource(struct pnp_dev
*dev
, int dma
,
608 struct pnp_resource
*pnp_res
;
609 struct resource
*res
;
610 static unsigned char warned
;
612 pnp_res
= pnp_new_resource(dev
, IORESOURCE_DMA
);
615 dev_err(&dev
->dev
, "can't add resource for DMA %d\n",
623 res
->flags
= IORESOURCE_DMA
| flags
;
627 dev_dbg(&dev
->dev
, " add dma %d flags %#x\n", dma
, flags
);
631 struct pnp_resource
*pnp_add_io_resource(struct pnp_dev
*dev
,
632 resource_size_t start
,
633 resource_size_t end
, int flags
)
635 struct pnp_resource
*pnp_res
;
636 struct resource
*res
;
637 static unsigned char warned
;
639 pnp_res
= pnp_new_resource(dev
, IORESOURCE_IO
);
642 dev_err(&dev
->dev
, "can't add resource for IO "
643 "%#llx-%#llx\n",(unsigned long long) start
,
644 (unsigned long long) end
);
651 res
->flags
= IORESOURCE_IO
| flags
;
655 dev_dbg(&dev
->dev
, " add io %#llx-%#llx flags %#x\n",
656 (unsigned long long) start
, (unsigned long long) end
, flags
);
660 struct pnp_resource
*pnp_add_mem_resource(struct pnp_dev
*dev
,
661 resource_size_t start
,
662 resource_size_t end
, int flags
)
664 struct pnp_resource
*pnp_res
;
665 struct resource
*res
;
666 static unsigned char warned
;
668 pnp_res
= pnp_new_resource(dev
, IORESOURCE_MEM
);
671 dev_err(&dev
->dev
, "can't add resource for MEM "
672 "%#llx-%#llx\n",(unsigned long long) start
,
673 (unsigned long long) end
);
680 res
->flags
= IORESOURCE_MEM
| flags
;
684 dev_dbg(&dev
->dev
, " add mem %#llx-%#llx flags %#x\n",
685 (unsigned long long) start
, (unsigned long long) end
, flags
);
689 /* format is: pnp_reserve_irq=irq1[,irq2] .... */
690 static int __init
pnp_setup_reserve_irq(char *str
)
694 for (i
= 0; i
< 16; i
++)
695 if (get_option(&str
, &pnp_reserve_irq
[i
]) != 2)
700 __setup("pnp_reserve_irq=", pnp_setup_reserve_irq
);
702 /* format is: pnp_reserve_dma=dma1[,dma2] .... */
703 static int __init
pnp_setup_reserve_dma(char *str
)
707 for (i
= 0; i
< 8; i
++)
708 if (get_option(&str
, &pnp_reserve_dma
[i
]) != 2)
713 __setup("pnp_reserve_dma=", pnp_setup_reserve_dma
);
715 /* format is: pnp_reserve_io=io1,size1[,io2,size2] .... */
716 static int __init
pnp_setup_reserve_io(char *str
)
720 for (i
= 0; i
< 16; i
++)
721 if (get_option(&str
, &pnp_reserve_io
[i
]) != 2)
726 __setup("pnp_reserve_io=", pnp_setup_reserve_io
);
728 /* format is: pnp_reserve_mem=mem1,size1[,mem2,size2] .... */
729 static int __init
pnp_setup_reserve_mem(char *str
)
733 for (i
= 0; i
< 16; i
++)
734 if (get_option(&str
, &pnp_reserve_mem
[i
]) != 2)
739 __setup("pnp_reserve_mem=", pnp_setup_reserve_mem
);