3bda513a6bd36cb92ea092ef3fd4ae13c7a6ad19
[linux-2.6.git] / drivers / pnp / manager.c
1 /*
2  * manager.c - Resource Management, Conflict Resolution, Activation and Disabling of Devices
3  *
4  * based on isapnp.c resource management (c) Jaroslav Kysela <perex@suse.cz>
5  * Copyright 2003 Adam Belay <ambx1@neo.rr.com>
6  */
7
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 "base.h"
16
17 DECLARE_MUTEX(pnp_res_mutex);
18
19 static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
20 {
21         resource_size_t *start, *end;
22         unsigned long *flags;
23
24         if (!dev || !rule)
25                 return -EINVAL;
26
27         if (idx >= PNP_MAX_PORT) {
28                 pnp_err
29                     ("More than 4 ports is incompatible with pnp specifications.");
30                 /* pretend we were successful so at least the manager won't try again */
31                 return 1;
32         }
33
34         /* check if this resource has been manually set, if so skip */
35         if (!(dev->res.port_resource[idx].flags & IORESOURCE_AUTO))
36                 return 1;
37
38         start = &dev->res.port_resource[idx].start;
39         end = &dev->res.port_resource[idx].end;
40         flags = &dev->res.port_resource[idx].flags;
41
42         /* set the initial values */
43         *flags |= rule->flags | IORESOURCE_IO;
44         *flags &= ~IORESOURCE_UNSET;
45
46         if (!rule->size) {
47                 *flags |= IORESOURCE_DISABLED;
48                 return 1;       /* skip disabled resource requests */
49         }
50
51         *start = rule->min;
52         *end = *start + rule->size - 1;
53
54         /* run through until pnp_check_port is happy */
55         while (!pnp_check_port(dev, idx)) {
56                 *start += rule->align;
57                 *end = *start + rule->size - 1;
58                 if (*start > rule->max || !rule->align)
59                         return 0;
60         }
61         return 1;
62 }
63
64 static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
65 {
66         resource_size_t *start, *end;
67         unsigned long *flags;
68
69         if (!dev || !rule)
70                 return -EINVAL;
71
72         if (idx >= PNP_MAX_MEM) {
73                 pnp_err
74                     ("More than 8 mems is incompatible with pnp specifications.");
75                 /* pretend we were successful so at least the manager won't try again */
76                 return 1;
77         }
78
79         /* check if this resource has been manually set, if so skip */
80         if (!(dev->res.mem_resource[idx].flags & IORESOURCE_AUTO))
81                 return 1;
82
83         start = &dev->res.mem_resource[idx].start;
84         end = &dev->res.mem_resource[idx].end;
85         flags = &dev->res.mem_resource[idx].flags;
86
87         /* set the initial values */
88         *flags |= rule->flags | IORESOURCE_MEM;
89         *flags &= ~IORESOURCE_UNSET;
90
91         /* convert pnp flags to standard Linux flags */
92         if (!(rule->flags & IORESOURCE_MEM_WRITEABLE))
93                 *flags |= IORESOURCE_READONLY;
94         if (rule->flags & IORESOURCE_MEM_CACHEABLE)
95                 *flags |= IORESOURCE_CACHEABLE;
96         if (rule->flags & IORESOURCE_MEM_RANGELENGTH)
97                 *flags |= IORESOURCE_RANGELENGTH;
98         if (rule->flags & IORESOURCE_MEM_SHADOWABLE)
99                 *flags |= IORESOURCE_SHADOWABLE;
100
101         if (!rule->size) {
102                 *flags |= IORESOURCE_DISABLED;
103                 return 1;       /* skip disabled resource requests */
104         }
105
106         *start = rule->min;
107         *end = *start + rule->size - 1;
108
109         /* run through until pnp_check_mem is happy */
110         while (!pnp_check_mem(dev, idx)) {
111                 *start += rule->align;
112                 *end = *start + rule->size - 1;
113                 if (*start > rule->max || !rule->align)
114                         return 0;
115         }
116         return 1;
117 }
118
119 static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
120 {
121         resource_size_t *start, *end;
122         unsigned long *flags;
123         int i;
124
125         /* IRQ priority: this table is good for i386 */
126         static unsigned short xtab[16] = {
127                 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2
128         };
129
130         if (!dev || !rule)
131                 return -EINVAL;
132
133         if (idx >= PNP_MAX_IRQ) {
134                 pnp_err
135                     ("More than 2 irqs is incompatible with pnp specifications.");
136                 /* pretend we were successful so at least the manager won't try again */
137                 return 1;
138         }
139
140         /* check if this resource has been manually set, if so skip */
141         if (!(dev->res.irq_resource[idx].flags & IORESOURCE_AUTO))
142                 return 1;
143
144         start = &dev->res.irq_resource[idx].start;
145         end = &dev->res.irq_resource[idx].end;
146         flags = &dev->res.irq_resource[idx].flags;
147
148         /* set the initial values */
149         *flags |= rule->flags | IORESOURCE_IRQ;
150         *flags &= ~IORESOURCE_UNSET;
151
152         if (bitmap_empty(rule->map, PNP_IRQ_NR)) {
153                 *flags |= IORESOURCE_DISABLED;
154                 return 1;       /* skip disabled resource requests */
155         }
156
157         /* TBD: need check for >16 IRQ */
158         *start = find_next_bit(rule->map, PNP_IRQ_NR, 16);
159         if (*start < PNP_IRQ_NR) {
160                 *end = *start;
161                 return 1;
162         }
163         for (i = 0; i < 16; i++) {
164                 if (test_bit(xtab[i], rule->map)) {
165                         *start = *end = xtab[i];
166                         if (pnp_check_irq(dev, idx))
167                                 return 1;
168                 }
169         }
170         return 0;
171 }
172
173 static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
174 {
175         resource_size_t *start, *end;
176         unsigned long *flags;
177         int i;
178
179         /* DMA priority: this table is good for i386 */
180         static unsigned short xtab[8] = {
181                 1, 3, 5, 6, 7, 0, 2, 4
182         };
183
184         if (!dev || !rule)
185                 return -EINVAL;
186
187         if (idx >= PNP_MAX_DMA) {
188                 pnp_err
189                     ("More than 2 dmas is incompatible with pnp specifications.");
190                 /* pretend we were successful so at least the manager won't try again */
191                 return 1;
192         }
193
194         /* check if this resource has been manually set, if so skip */
195         if (!(dev->res.dma_resource[idx].flags & IORESOURCE_AUTO))
196                 return 1;
197
198         start = &dev->res.dma_resource[idx].start;
199         end = &dev->res.dma_resource[idx].end;
200         flags = &dev->res.dma_resource[idx].flags;
201
202         /* set the initial values */
203         *flags |= rule->flags | IORESOURCE_DMA;
204         *flags &= ~IORESOURCE_UNSET;
205
206         if (!rule->map) {
207                 *flags |= IORESOURCE_DISABLED;
208                 return 1;       /* skip disabled resource requests */
209         }
210
211         for (i = 0; i < 8; i++) {
212                 if (rule->map & (1 << xtab[i])) {
213                         *start = *end = xtab[i];
214                         if (pnp_check_dma(dev, idx))
215                                 return 1;
216                 }
217         }
218         return 0;
219 }
220
221 /**
222  * pnp_init_resources - Resets a resource table to default values.
223  * @table: pointer to the desired resource table
224  */
225 void pnp_init_resource_table(struct pnp_resource_table *table)
226 {
227         int idx;
228
229         for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
230                 table->irq_resource[idx].name = NULL;
231                 table->irq_resource[idx].start = -1;
232                 table->irq_resource[idx].end = -1;
233                 table->irq_resource[idx].flags =
234                     IORESOURCE_IRQ | IORESOURCE_AUTO | IORESOURCE_UNSET;
235         }
236         for (idx = 0; idx < PNP_MAX_DMA; idx++) {
237                 table->dma_resource[idx].name = NULL;
238                 table->dma_resource[idx].start = -1;
239                 table->dma_resource[idx].end = -1;
240                 table->dma_resource[idx].flags =
241                     IORESOURCE_DMA | IORESOURCE_AUTO | IORESOURCE_UNSET;
242         }
243         for (idx = 0; idx < PNP_MAX_PORT; idx++) {
244                 table->port_resource[idx].name = NULL;
245                 table->port_resource[idx].start = 0;
246                 table->port_resource[idx].end = 0;
247                 table->port_resource[idx].flags =
248                     IORESOURCE_IO | IORESOURCE_AUTO | IORESOURCE_UNSET;
249         }
250         for (idx = 0; idx < PNP_MAX_MEM; idx++) {
251                 table->mem_resource[idx].name = NULL;
252                 table->mem_resource[idx].start = 0;
253                 table->mem_resource[idx].end = 0;
254                 table->mem_resource[idx].flags =
255                     IORESOURCE_MEM | IORESOURCE_AUTO | IORESOURCE_UNSET;
256         }
257 }
258
259 /**
260  * pnp_clean_resources - clears resources that were not manually set
261  * @res: the resources to clean
262  */
263 static void pnp_clean_resource_table(struct pnp_resource_table *res)
264 {
265         int idx;
266
267         for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
268                 if (!(res->irq_resource[idx].flags & IORESOURCE_AUTO))
269                         continue;
270                 res->irq_resource[idx].start = -1;
271                 res->irq_resource[idx].end = -1;
272                 res->irq_resource[idx].flags =
273                     IORESOURCE_IRQ | IORESOURCE_AUTO | IORESOURCE_UNSET;
274         }
275         for (idx = 0; idx < PNP_MAX_DMA; idx++) {
276                 if (!(res->dma_resource[idx].flags & IORESOURCE_AUTO))
277                         continue;
278                 res->dma_resource[idx].start = -1;
279                 res->dma_resource[idx].end = -1;
280                 res->dma_resource[idx].flags =
281                     IORESOURCE_DMA | IORESOURCE_AUTO | IORESOURCE_UNSET;
282         }
283         for (idx = 0; idx < PNP_MAX_PORT; idx++) {
284                 if (!(res->port_resource[idx].flags & IORESOURCE_AUTO))
285                         continue;
286                 res->port_resource[idx].start = 0;
287                 res->port_resource[idx].end = 0;
288                 res->port_resource[idx].flags =
289                     IORESOURCE_IO | IORESOURCE_AUTO | IORESOURCE_UNSET;
290         }
291         for (idx = 0; idx < PNP_MAX_MEM; idx++) {
292                 if (!(res->mem_resource[idx].flags & IORESOURCE_AUTO))
293                         continue;
294                 res->mem_resource[idx].start = 0;
295                 res->mem_resource[idx].end = 0;
296                 res->mem_resource[idx].flags =
297                     IORESOURCE_MEM | IORESOURCE_AUTO | IORESOURCE_UNSET;
298         }
299 }
300
301 /**
302  * pnp_assign_resources - assigns resources to the device based on the specified dependent number
303  * @dev: pointer to the desired device
304  * @depnum: the dependent function number
305  *
306  * Only set depnum to 0 if the device does not have dependent options.
307  */
308 static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
309 {
310         struct pnp_port *port;
311         struct pnp_mem *mem;
312         struct pnp_irq *irq;
313         struct pnp_dma *dma;
314         int nport = 0, nmem = 0, nirq = 0, ndma = 0;
315
316         if (!pnp_can_configure(dev))
317                 return -ENODEV;
318
319         down(&pnp_res_mutex);
320         pnp_clean_resource_table(&dev->res);    /* start with a fresh slate */
321         if (dev->independent) {
322                 port = dev->independent->port;
323                 mem = dev->independent->mem;
324                 irq = dev->independent->irq;
325                 dma = dev->independent->dma;
326                 while (port) {
327                         if (!pnp_assign_port(dev, port, nport))
328                                 goto fail;
329                         nport++;
330                         port = port->next;
331                 }
332                 while (mem) {
333                         if (!pnp_assign_mem(dev, mem, nmem))
334                                 goto fail;
335                         nmem++;
336                         mem = mem->next;
337                 }
338                 while (irq) {
339                         if (!pnp_assign_irq(dev, irq, nirq))
340                                 goto fail;
341                         nirq++;
342                         irq = irq->next;
343                 }
344                 while (dma) {
345                         if (!pnp_assign_dma(dev, dma, ndma))
346                                 goto fail;
347                         ndma++;
348                         dma = dma->next;
349                 }
350         }
351
352         if (depnum) {
353                 struct pnp_option *dep;
354                 int i;
355                 for (i = 1, dep = dev->dependent; i < depnum;
356                      i++, dep = dep->next)
357                         if (!dep)
358                                 goto fail;
359                 port = dep->port;
360                 mem = dep->mem;
361                 irq = dep->irq;
362                 dma = dep->dma;
363                 while (port) {
364                         if (!pnp_assign_port(dev, port, nport))
365                                 goto fail;
366                         nport++;
367                         port = port->next;
368                 }
369                 while (mem) {
370                         if (!pnp_assign_mem(dev, mem, nmem))
371                                 goto fail;
372                         nmem++;
373                         mem = mem->next;
374                 }
375                 while (irq) {
376                         if (!pnp_assign_irq(dev, irq, nirq))
377                                 goto fail;
378                         nirq++;
379                         irq = irq->next;
380                 }
381                 while (dma) {
382                         if (!pnp_assign_dma(dev, dma, ndma))
383                                 goto fail;
384                         ndma++;
385                         dma = dma->next;
386                 }
387         } else if (dev->dependent)
388                 goto fail;
389
390         up(&pnp_res_mutex);
391         return 1;
392
393       fail:
394         pnp_clean_resource_table(&dev->res);
395         up(&pnp_res_mutex);
396         return 0;
397 }
398
399 /**
400  * pnp_manual_config_dev - Disables Auto Config and Manually sets the resource table
401  * @dev: pointer to the desired device
402  * @res: pointer to the new resource config
403  * @mode: 0 or PNP_CONFIG_FORCE
404  *
405  * This function can be used by drivers that want to manually set thier resources.
406  */
407 int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res,
408                           int mode)
409 {
410         int i;
411         struct pnp_resource_table *bak;
412
413         if (!dev || !res)
414                 return -EINVAL;
415         if (!pnp_can_configure(dev))
416                 return -ENODEV;
417         bak = pnp_alloc(sizeof(struct pnp_resource_table));
418         if (!bak)
419                 return -ENOMEM;
420         *bak = dev->res;
421
422         down(&pnp_res_mutex);
423         dev->res = *res;
424         if (!(mode & PNP_CONFIG_FORCE)) {
425                 for (i = 0; i < PNP_MAX_PORT; i++) {
426                         if (!pnp_check_port(dev, i))
427                                 goto fail;
428                 }
429                 for (i = 0; i < PNP_MAX_MEM; i++) {
430                         if (!pnp_check_mem(dev, i))
431                                 goto fail;
432                 }
433                 for (i = 0; i < PNP_MAX_IRQ; i++) {
434                         if (!pnp_check_irq(dev, i))
435                                 goto fail;
436                 }
437                 for (i = 0; i < PNP_MAX_DMA; i++) {
438                         if (!pnp_check_dma(dev, i))
439                                 goto fail;
440                 }
441         }
442         up(&pnp_res_mutex);
443
444         kfree(bak);
445         return 0;
446
447       fail:
448         dev->res = *bak;
449         up(&pnp_res_mutex);
450         kfree(bak);
451         return -EINVAL;
452 }
453
454 /**
455  * pnp_auto_config_dev - automatically assigns resources to a device
456  * @dev: pointer to the desired device
457  */
458 int pnp_auto_config_dev(struct pnp_dev *dev)
459 {
460         struct pnp_option *dep;
461         int i = 1;
462
463         if (!dev)
464                 return -EINVAL;
465
466         if (!pnp_can_configure(dev)) {
467                 pnp_dbg("Device %s does not support resource configuration.",
468                         dev->dev.bus_id);
469                 return -ENODEV;
470         }
471
472         if (!dev->dependent) {
473                 if (pnp_assign_resources(dev, 0))
474                         return 0;
475         } else {
476                 dep = dev->dependent;
477                 do {
478                         if (pnp_assign_resources(dev, i))
479                                 return 0;
480                         dep = dep->next;
481                         i++;
482                 } while (dep);
483         }
484
485         pnp_err("Unable to assign resources to device %s.", dev->dev.bus_id);
486         return -EBUSY;
487 }
488
489 /**
490  * pnp_start_dev - low-level start of the PnP device
491  * @dev: pointer to the desired device
492  *
493  * assumes that resources have already been allocated
494  */
495 int pnp_start_dev(struct pnp_dev *dev)
496 {
497         if (!pnp_can_write(dev)) {
498                 pnp_dbg("Device %s does not support activation.",
499                         dev->dev.bus_id);
500                 return -EINVAL;
501         }
502
503         if (dev->protocol->set(dev, &dev->res) < 0) {
504                 pnp_err("Failed to activate device %s.", dev->dev.bus_id);
505                 return -EIO;
506         }
507
508         pnp_info("Device %s activated.", dev->dev.bus_id);
509         return 0;
510 }
511
512 /**
513  * pnp_stop_dev - low-level disable of the PnP device
514  * @dev: pointer to the desired device
515  *
516  * does not free resources
517  */
518 int pnp_stop_dev(struct pnp_dev *dev)
519 {
520         if (!pnp_can_disable(dev)) {
521                 pnp_dbg("Device %s does not support disabling.",
522                         dev->dev.bus_id);
523                 return -EINVAL;
524         }
525         if (dev->protocol->disable(dev) < 0) {
526                 pnp_err("Failed to disable device %s.", dev->dev.bus_id);
527                 return -EIO;
528         }
529
530         pnp_info("Device %s disabled.", dev->dev.bus_id);
531         return 0;
532 }
533
534 /**
535  * pnp_activate_dev - activates a PnP device for use
536  * @dev: pointer to the desired device
537  *
538  * does not validate or set resources so be careful.
539  */
540 int pnp_activate_dev(struct pnp_dev *dev)
541 {
542         int error;
543
544         if (!dev)
545                 return -EINVAL;
546         if (dev->active)
547                 return 0;       /* the device is already active */
548
549         /* ensure resources are allocated */
550         if (pnp_auto_config_dev(dev))
551                 return -EBUSY;
552
553         error = pnp_start_dev(dev);
554         if (error)
555                 return error;
556
557         dev->active = 1;
558         return 1;
559 }
560
561 /**
562  * pnp_disable_dev - disables device
563  * @dev: pointer to the desired device
564  *
565  * inform the correct pnp protocol so that resources can be used by other devices
566  */
567 int pnp_disable_dev(struct pnp_dev *dev)
568 {
569         int error;
570
571         if (!dev)
572                 return -EINVAL;
573         if (!dev->active)
574                 return 0;       /* the device is already disabled */
575
576         error = pnp_stop_dev(dev);
577         if (error)
578                 return error;
579
580         dev->active = 0;
581
582         /* release the resources so that other devices can use them */
583         down(&pnp_res_mutex);
584         pnp_clean_resource_table(&dev->res);
585         up(&pnp_res_mutex);
586
587         return 1;
588 }
589
590 /**
591  * pnp_resource_change - change one resource
592  * @resource: pointer to resource to be changed
593  * @start: start of region
594  * @size: size of region
595  */
596 void pnp_resource_change(struct resource *resource, resource_size_t start,
597                          resource_size_t size)
598 {
599         if (resource == NULL)
600                 return;
601         resource->flags &= ~(IORESOURCE_AUTO | IORESOURCE_UNSET);
602         resource->start = start;
603         resource->end = start + size - 1;
604 }
605
606 EXPORT_SYMBOL(pnp_manual_config_dev);
607 EXPORT_SYMBOL(pnp_start_dev);
608 EXPORT_SYMBOL(pnp_stop_dev);
609 EXPORT_SYMBOL(pnp_activate_dev);
610 EXPORT_SYMBOL(pnp_disable_dev);
611 EXPORT_SYMBOL(pnp_resource_change);
612 EXPORT_SYMBOL(pnp_init_resource_table);