Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pci-iommu_table.c
Go to the documentation of this file.
1 #include <linux/dma-mapping.h>
2 #include <asm/iommu_table.h>
3 #include <linux/string.h>
4 #include <linux/kallsyms.h>
5 
6 
7 #define DEBUG 1
8 
9 static struct iommu_table_entry * __init
10 find_dependents_of(struct iommu_table_entry *start,
11  struct iommu_table_entry *finish,
12  struct iommu_table_entry *q)
13 {
14  struct iommu_table_entry *p;
15 
16  if (!q)
17  return NULL;
18 
19  for (p = start; p < finish; p++)
20  if (p->detect == q->depend)
21  return p;
22 
23  return NULL;
24 }
25 
26 
28  struct iommu_table_entry *finish) {
29 
30  struct iommu_table_entry *p, *q, tmp;
31 
32  for (p = start; p < finish; p++) {
33 again:
34  q = find_dependents_of(start, finish, p);
35  /* We are bit sneaky here. We use the memory address to figure
36  * out if the node we depend on is past our point, if so, swap.
37  */
38  if (q > p) {
39  tmp = *p;
40  memmove(p, q, sizeof(*p));
41  *q = tmp;
42  goto again;
43  }
44  }
45 
46 }
47 
48 #ifdef DEBUG
50  struct iommu_table_entry *finish)
51 {
52  struct iommu_table_entry *p, *q, *x;
53 
54  /* Simple cyclic dependency checker. */
55  for (p = start; p < finish; p++) {
56  q = find_dependents_of(start, finish, p);
57  x = find_dependents_of(start, finish, q);
58  if (p == x) {
59  printk(KERN_ERR "CYCLIC DEPENDENCY FOUND! %pS depends on %pS and vice-versa. BREAKING IT.\n",
60  p->detect, q->detect);
61  /* Heavy handed way..*/
62  x->depend = 0;
63  }
64  }
65 
66  for (p = start; p < finish; p++) {
67  q = find_dependents_of(p, finish, p);
68  if (q && q > p) {
69  printk(KERN_ERR "EXECUTION ORDER INVALID! %pS should be called before %pS!\n",
70  p->detect, q->detect);
71  }
72  }
73 }
74 #else
75 inline void check_iommu_entries(struct iommu_table_entry *start,
76  struct iommu_table_entry *finish)
77 {
78 }
79 #endif