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