2 * manager.c - Resource Management, Conflict Resolution, Activation and Disabling of Devices
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/errno.h>
9 #include <linux/module.h>
10 #include <linux/init.h>
11 #include <linux/kernel.h>
12 #include <linux/pnp.h>
13 #include <linux/slab.h>
14 #include <linux/bitmap.h>
15 #include <linux/mutex.h>
18 DEFINE_MUTEX(pnp_res_mutex
);
20 static int pnp_assign_port(struct pnp_dev
*dev
, struct pnp_port
*rule
, int idx
)
24 if (idx
>= PNP_MAX_PORT
) {
25 dev_err(&dev
->dev
, "too many I/O port resources\n");
26 /* pretend we were successful so at least the manager won't try again */
30 res
= &dev
->res
.port_resource
[idx
];
32 /* check if this resource has been manually set, if so skip */
33 if (!(res
->flags
& IORESOURCE_AUTO
)) {
34 dev_dbg(&dev
->dev
, " io %d already set to %#llx-%#llx "
35 "flags %#lx\n", idx
, (unsigned long long) res
->start
,
36 (unsigned long long) res
->end
, res
->flags
);
40 /* set the initial values */
41 res
->flags
|= rule
->flags
| IORESOURCE_IO
;
42 res
->flags
&= ~IORESOURCE_UNSET
;
45 res
->flags
|= IORESOURCE_DISABLED
;
46 dev_dbg(&dev
->dev
, " io %d disabled\n", idx
);
47 return 1; /* skip disabled resource requests */
50 res
->start
= rule
->min
;
51 res
->end
= res
->start
+ rule
->size
- 1;
53 /* run through until pnp_check_port is happy */
54 while (!pnp_check_port(dev
, idx
)) {
55 res
->start
+= rule
->align
;
56 res
->end
= res
->start
+ rule
->size
- 1;
57 if (res
->start
> rule
->max
|| !rule
->align
) {
58 dev_dbg(&dev
->dev
, " couldn't assign io %d\n", idx
);
62 dev_dbg(&dev
->dev
, " assign io %d %#llx-%#llx\n", idx
,
63 (unsigned long long) res
->start
, (unsigned long long) res
->end
);
67 static int pnp_assign_mem(struct pnp_dev
*dev
, struct pnp_mem
*rule
, int idx
)
71 if (idx
>= PNP_MAX_MEM
) {
72 dev_err(&dev
->dev
, "too many memory resources\n");
73 /* pretend we were successful so at least the manager won't try again */
77 res
= &dev
->res
.mem_resource
[idx
];
79 /* check if this resource has been manually set, if so skip */
80 if (!(res
->flags
& IORESOURCE_AUTO
)) {
81 dev_dbg(&dev
->dev
, " mem %d already set to %#llx-%#llx "
82 "flags %#lx\n", idx
, (unsigned long long) res
->start
,
83 (unsigned long long) res
->end
, res
->flags
);
87 /* set the initial values */
88 res
->flags
|= rule
->flags
| IORESOURCE_MEM
;
89 res
->flags
&= ~IORESOURCE_UNSET
;
91 /* convert pnp flags to standard Linux flags */
92 if (!(rule
->flags
& IORESOURCE_MEM_WRITEABLE
))
93 res
->flags
|= IORESOURCE_READONLY
;
94 if (rule
->flags
& IORESOURCE_MEM_CACHEABLE
)
95 res
->flags
|= IORESOURCE_CACHEABLE
;
96 if (rule
->flags
& IORESOURCE_MEM_RANGELENGTH
)
97 res
->flags
|= IORESOURCE_RANGELENGTH
;
98 if (rule
->flags
& IORESOURCE_MEM_SHADOWABLE
)
99 res
->flags
|= IORESOURCE_SHADOWABLE
;
102 res
->flags
|= IORESOURCE_DISABLED
;
103 dev_dbg(&dev
->dev
, " mem %d disabled\n", idx
);
104 return 1; /* skip disabled resource requests */
107 res
->start
= rule
->min
;
108 res
->end
= res
->start
+ rule
->size
- 1;
110 /* run through until pnp_check_mem is happy */
111 while (!pnp_check_mem(dev
, idx
)) {
112 res
->start
+= rule
->align
;
113 res
->end
= res
->start
+ rule
->size
- 1;
114 if (res
->start
> rule
->max
|| !rule
->align
) {
115 dev_dbg(&dev
->dev
, " couldn't assign mem %d\n", idx
);
119 dev_dbg(&dev
->dev
, " assign mem %d %#llx-%#llx\n", idx
,
120 (unsigned long long) res
->start
, (unsigned long long) res
->end
);
124 static int pnp_assign_irq(struct pnp_dev
*dev
, struct pnp_irq
*rule
, int idx
)
126 struct resource
*res
;
129 /* IRQ priority: this table is good for i386 */
130 static unsigned short xtab
[16] = {
131 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2
134 if (idx
>= PNP_MAX_IRQ
) {
135 dev_err(&dev
->dev
, "too many IRQ resources\n");
136 /* pretend we were successful so at least the manager won't try again */
140 res
= &dev
->res
.irq_resource
[idx
];
142 /* check if this resource has been manually set, if so skip */
143 if (!(res
->flags
& IORESOURCE_AUTO
)) {
144 dev_dbg(&dev
->dev
, " irq %d already set to %d flags %#lx\n",
145 idx
, (int) res
->start
, res
->flags
);
149 /* set the initial values */
150 res
->flags
|= rule
->flags
| IORESOURCE_IRQ
;
151 res
->flags
&= ~IORESOURCE_UNSET
;
153 if (bitmap_empty(rule
->map
, PNP_IRQ_NR
)) {
154 res
->flags
|= IORESOURCE_DISABLED
;
155 dev_dbg(&dev
->dev
, " irq %d disabled\n", idx
);
156 return 1; /* skip disabled resource requests */
159 /* TBD: need check for >16 IRQ */
160 res
->start
= find_next_bit(rule
->map
, PNP_IRQ_NR
, 16);
161 if (res
->start
< PNP_IRQ_NR
) {
162 res
->end
= res
->start
;
163 dev_dbg(&dev
->dev
, " assign irq %d %d\n", idx
,
167 for (i
= 0; i
< 16; i
++) {
168 if (test_bit(xtab
[i
], rule
->map
)) {
169 res
->start
= res
->end
= xtab
[i
];
170 if (pnp_check_irq(dev
, idx
)) {
171 dev_dbg(&dev
->dev
, " assign irq %d %d\n", idx
,
177 dev_dbg(&dev
->dev
, " couldn't assign irq %d\n", idx
);
181 static void pnp_assign_dma(struct pnp_dev
*dev
, struct pnp_dma
*rule
, int idx
)
183 struct resource
*res
;
186 /* DMA priority: this table is good for i386 */
187 static unsigned short xtab
[8] = {
188 1, 3, 5, 6, 7, 0, 2, 4
191 if (idx
>= PNP_MAX_DMA
) {
192 dev_err(&dev
->dev
, "too many DMA resources\n");
196 res
= &dev
->res
.dma_resource
[idx
];
198 /* check if this resource has been manually set, if so skip */
199 if (!(res
->flags
& IORESOURCE_AUTO
)) {
200 dev_dbg(&dev
->dev
, " dma %d already set to %d flags %#lx\n",
201 idx
, (int) res
->start
, res
->flags
);
205 /* set the initial values */
206 res
->flags
|= rule
->flags
| IORESOURCE_DMA
;
207 res
->flags
&= ~IORESOURCE_UNSET
;
209 for (i
= 0; i
< 8; i
++) {
210 if (rule
->map
& (1 << xtab
[i
])) {
211 res
->start
= res
->end
= xtab
[i
];
212 if (pnp_check_dma(dev
, idx
)) {
213 dev_dbg(&dev
->dev
, " assign dma %d %d\n", idx
,
219 #ifdef MAX_DMA_CHANNELS
220 res
->start
= res
->end
= MAX_DMA_CHANNELS
;
222 res
->flags
|= IORESOURCE_UNSET
| IORESOURCE_DISABLED
;
223 dev_dbg(&dev
->dev
, " disable dma %d\n", idx
);
226 void pnp_init_resource(struct resource
*res
)
230 type
= res
->flags
& (IORESOURCE_IO
| IORESOURCE_MEM
|
231 IORESOURCE_IRQ
| IORESOURCE_DMA
);
234 res
->flags
= type
| IORESOURCE_AUTO
| IORESOURCE_UNSET
;
235 if (type
== IORESOURCE_IRQ
|| type
== IORESOURCE_DMA
) {
245 * pnp_init_resources - Resets a resource table to default values.
246 * @table: pointer to the desired resource table
248 void pnp_init_resources(struct pnp_dev
*dev
)
250 struct resource
*res
;
253 for (idx
= 0; idx
< PNP_MAX_IRQ
; idx
++) {
254 res
= &dev
->res
.irq_resource
[idx
];
255 res
->flags
= IORESOURCE_IRQ
;
256 pnp_init_resource(res
);
258 for (idx
= 0; idx
< PNP_MAX_DMA
; idx
++) {
259 res
= &dev
->res
.dma_resource
[idx
];
260 res
->flags
= IORESOURCE_DMA
;
261 pnp_init_resource(res
);
263 for (idx
= 0; idx
< PNP_MAX_PORT
; idx
++) {
264 res
= &dev
->res
.port_resource
[idx
];
265 res
->flags
= IORESOURCE_IO
;
266 pnp_init_resource(res
);
268 for (idx
= 0; idx
< PNP_MAX_MEM
; idx
++) {
269 res
= &dev
->res
.mem_resource
[idx
];
270 res
->flags
= IORESOURCE_MEM
;
271 pnp_init_resource(res
);
276 * pnp_clean_resources - clears resources that were not manually set
277 * @res: the resources to clean
279 static void pnp_clean_resource_table(struct pnp_dev
*dev
)
281 struct resource
*res
;
284 for (idx
= 0; idx
< PNP_MAX_IRQ
; idx
++) {
285 res
= &dev
->res
.irq_resource
[idx
];
286 if (res
->flags
& IORESOURCE_AUTO
) {
287 res
->flags
= IORESOURCE_IRQ
;
288 pnp_init_resource(res
);
291 for (idx
= 0; idx
< PNP_MAX_DMA
; idx
++) {
292 res
= &dev
->res
.dma_resource
[idx
];
293 if (res
->flags
& IORESOURCE_AUTO
) {
294 res
->flags
= IORESOURCE_DMA
;
295 pnp_init_resource(res
);
298 for (idx
= 0; idx
< PNP_MAX_PORT
; idx
++) {
299 res
= &dev
->res
.port_resource
[idx
];
300 if (res
->flags
& IORESOURCE_AUTO
) {
301 res
->flags
= IORESOURCE_IO
;
302 pnp_init_resource(res
);
305 for (idx
= 0; idx
< PNP_MAX_MEM
; idx
++) {
306 res
= &dev
->res
.mem_resource
[idx
];
307 if (res
->flags
& IORESOURCE_AUTO
) {
308 res
->flags
= IORESOURCE_MEM
;
309 pnp_init_resource(res
);
315 * pnp_assign_resources - assigns resources to the device based on the specified dependent number
316 * @dev: pointer to the desired device
317 * @depnum: the dependent function number
319 * Only set depnum to 0 if the device does not have dependent options.
321 static int pnp_assign_resources(struct pnp_dev
*dev
, int depnum
)
323 struct pnp_port
*port
;
327 int nport
= 0, nmem
= 0, nirq
= 0, ndma
= 0;
329 if (!pnp_can_configure(dev
))
332 dbg_pnp_show_resources(dev
, "before pnp_assign_resources");
333 mutex_lock(&pnp_res_mutex
);
334 pnp_clean_resource_table(dev
);
335 if (dev
->independent
) {
336 dev_dbg(&dev
->dev
, "assigning independent options\n");
337 port
= dev
->independent
->port
;
338 mem
= dev
->independent
->mem
;
339 irq
= dev
->independent
->irq
;
340 dma
= dev
->independent
->dma
;
342 if (!pnp_assign_port(dev
, port
, nport
))
348 if (!pnp_assign_mem(dev
, mem
, nmem
))
354 if (!pnp_assign_irq(dev
, irq
, nirq
))
360 pnp_assign_dma(dev
, dma
, ndma
);
367 struct pnp_option
*dep
;
370 dev_dbg(&dev
->dev
, "assigning dependent option %d\n", depnum
);
371 for (i
= 1, dep
= dev
->dependent
; i
< depnum
;
372 i
++, dep
= dep
->next
)
380 if (!pnp_assign_port(dev
, port
, nport
))
386 if (!pnp_assign_mem(dev
, mem
, nmem
))
392 if (!pnp_assign_irq(dev
, irq
, nirq
))
398 pnp_assign_dma(dev
, dma
, ndma
);
402 } else if (dev
->dependent
)
405 mutex_unlock(&pnp_res_mutex
);
406 dbg_pnp_show_resources(dev
, "after pnp_assign_resources");
410 pnp_clean_resource_table(dev
);
411 mutex_unlock(&pnp_res_mutex
);
412 dbg_pnp_show_resources(dev
, "after pnp_assign_resources (failed)");
417 * pnp_auto_config_dev - automatically assigns resources to a device
418 * @dev: pointer to the desired device
420 int pnp_auto_config_dev(struct pnp_dev
*dev
)
422 struct pnp_option
*dep
;
425 if (!pnp_can_configure(dev
)) {
426 dev_dbg(&dev
->dev
, "configuration not supported\n");
430 if (!dev
->dependent
) {
431 if (pnp_assign_resources(dev
, 0))
434 dep
= dev
->dependent
;
436 if (pnp_assign_resources(dev
, i
))
443 dev_err(&dev
->dev
, "unable to assign resources\n");
448 * pnp_start_dev - low-level start of the PnP device
449 * @dev: pointer to the desired device
451 * assumes that resources have already been allocated
453 int pnp_start_dev(struct pnp_dev
*dev
)
455 if (!pnp_can_write(dev
)) {
456 dev_dbg(&dev
->dev
, "activation not supported\n");
460 dbg_pnp_show_resources(dev
, "pnp_start_dev");
461 if (dev
->protocol
->set(dev
) < 0) {
462 dev_err(&dev
->dev
, "activation failed\n");
466 dev_info(&dev
->dev
, "activated\n");
471 * pnp_stop_dev - low-level disable of the PnP device
472 * @dev: pointer to the desired device
474 * does not free resources
476 int pnp_stop_dev(struct pnp_dev
*dev
)
478 if (!pnp_can_disable(dev
)) {
479 dev_dbg(&dev
->dev
, "disabling not supported\n");
482 if (dev
->protocol
->disable(dev
) < 0) {
483 dev_err(&dev
->dev
, "disable failed\n");
487 dev_info(&dev
->dev
, "disabled\n");
492 * pnp_activate_dev - activates a PnP device for use
493 * @dev: pointer to the desired device
495 * does not validate or set resources so be careful.
497 int pnp_activate_dev(struct pnp_dev
*dev
)
504 /* ensure resources are allocated */
505 if (pnp_auto_config_dev(dev
))
508 error
= pnp_start_dev(dev
);
517 * pnp_disable_dev - disables device
518 * @dev: pointer to the desired device
520 * inform the correct pnp protocol so that resources can be used by other devices
522 int pnp_disable_dev(struct pnp_dev
*dev
)
529 error
= pnp_stop_dev(dev
);
535 /* release the resources so that other devices can use them */
536 mutex_lock(&pnp_res_mutex
);
537 pnp_clean_resource_table(dev
);
538 mutex_unlock(&pnp_res_mutex
);
543 EXPORT_SYMBOL(pnp_start_dev
);
544 EXPORT_SYMBOL(pnp_stop_dev
);
545 EXPORT_SYMBOL(pnp_activate_dev
);
546 EXPORT_SYMBOL(pnp_disable_dev
);