diff options
Diffstat (limited to 'drivers/pnp/support.c')
-rw-r--r-- | drivers/pnp/support.c | 171 |
1 files changed, 146 insertions, 25 deletions
diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c index 95b076c18c07..bbf78ef4ba02 100644 --- a/drivers/pnp/support.c +++ b/drivers/pnp/support.c | |||
@@ -2,6 +2,8 @@ | |||
2 | * support.c - standard functions for the use of pnp protocol drivers | 2 | * support.c - standard functions for the use of pnp protocol drivers |
3 | * | 3 | * |
4 | * Copyright 2003 Adam Belay <ambx1@neo.rr.com> | 4 | * Copyright 2003 Adam Belay <ambx1@neo.rr.com> |
5 | * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. | ||
6 | * Bjorn Helgaas <bjorn.helgaas@hp.com> | ||
5 | */ | 7 | */ |
6 | 8 | ||
7 | #include <linux/module.h> | 9 | #include <linux/module.h> |
@@ -16,6 +18,10 @@ | |||
16 | */ | 18 | */ |
17 | int pnp_is_active(struct pnp_dev *dev) | 19 | int pnp_is_active(struct pnp_dev *dev) |
18 | { | 20 | { |
21 | /* | ||
22 | * I don't think this is very reliable because pnp_disable_dev() | ||
23 | * only clears out auto-assigned resources. | ||
24 | */ | ||
19 | if (!pnp_port_start(dev, 0) && pnp_port_len(dev, 0) <= 1 && | 25 | if (!pnp_port_start(dev, 0) && pnp_port_len(dev, 0) <= 1 && |
20 | !pnp_mem_start(dev, 0) && pnp_mem_len(dev, 0) <= 1 && | 26 | !pnp_mem_start(dev, 0) && pnp_mem_len(dev, 0) <= 1 && |
21 | pnp_irq(dev, 0) == -1 && pnp_dma(dev, 0) == -1) | 27 | pnp_irq(dev, 0) == -1 && pnp_dma(dev, 0) == -1) |
@@ -52,39 +58,154 @@ void pnp_eisa_id_to_string(u32 id, char *str) | |||
52 | str[7] = '\0'; | 58 | str[7] = '\0'; |
53 | } | 59 | } |
54 | 60 | ||
61 | char *pnp_resource_type_name(struct resource *res) | ||
62 | { | ||
63 | switch (pnp_resource_type(res)) { | ||
64 | case IORESOURCE_IO: | ||
65 | return "io"; | ||
66 | case IORESOURCE_MEM: | ||
67 | return "mem"; | ||
68 | case IORESOURCE_IRQ: | ||
69 | return "irq"; | ||
70 | case IORESOURCE_DMA: | ||
71 | return "dma"; | ||
72 | } | ||
73 | return NULL; | ||
74 | } | ||
75 | |||
55 | void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc) | 76 | void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc) |
56 | { | 77 | { |
57 | #ifdef DEBUG | 78 | #ifdef DEBUG |
79 | char buf[128]; | ||
80 | int len = 0; | ||
81 | struct pnp_resource *pnp_res; | ||
58 | struct resource *res; | 82 | struct resource *res; |
59 | int i; | ||
60 | 83 | ||
61 | dev_dbg(&dev->dev, "current resources: %s\n", desc); | 84 | if (list_empty(&dev->resources)) { |
62 | 85 | dev_dbg(&dev->dev, "%s: no current resources\n", desc); | |
63 | for (i = 0; i < PNP_MAX_IRQ; i++) { | 86 | return; |
64 | res = pnp_get_resource(dev, IORESOURCE_IRQ, i); | ||
65 | if (res && !(res->flags & IORESOURCE_UNSET)) | ||
66 | dev_dbg(&dev->dev, " irq %lld flags %#lx\n", | ||
67 | (unsigned long long) res->start, res->flags); | ||
68 | } | 87 | } |
69 | for (i = 0; i < PNP_MAX_DMA; i++) { | 88 | |
70 | res = pnp_get_resource(dev, IORESOURCE_DMA, i); | 89 | dev_dbg(&dev->dev, "%s: current resources:\n", desc); |
71 | if (res && !(res->flags & IORESOURCE_UNSET)) | 90 | list_for_each_entry(pnp_res, &dev->resources, list) { |
72 | dev_dbg(&dev->dev, " dma %lld flags %#lx\n", | 91 | res = &pnp_res->res; |
73 | (unsigned long long) res->start, res->flags); | 92 | |
93 | len += snprintf(buf + len, sizeof(buf) - len, " %-3s ", | ||
94 | pnp_resource_type_name(res)); | ||
95 | |||
96 | if (res->flags & IORESOURCE_DISABLED) { | ||
97 | dev_dbg(&dev->dev, "%sdisabled\n", buf); | ||
98 | continue; | ||
99 | } | ||
100 | |||
101 | switch (pnp_resource_type(res)) { | ||
102 | case IORESOURCE_IO: | ||
103 | case IORESOURCE_MEM: | ||
104 | len += snprintf(buf + len, sizeof(buf) - len, | ||
105 | "%#llx-%#llx flags %#lx", | ||
106 | (unsigned long long) res->start, | ||
107 | (unsigned long long) res->end, | ||
108 | res->flags); | ||
109 | break; | ||
110 | case IORESOURCE_IRQ: | ||
111 | case IORESOURCE_DMA: | ||
112 | len += snprintf(buf + len, sizeof(buf) - len, | ||
113 | "%lld flags %#lx", | ||
114 | (unsigned long long) res->start, | ||
115 | res->flags); | ||
116 | break; | ||
117 | } | ||
118 | dev_dbg(&dev->dev, "%s\n", buf); | ||
74 | } | 119 | } |
75 | for (i = 0; i < PNP_MAX_PORT; i++) { | 120 | #endif |
76 | res = pnp_get_resource(dev, IORESOURCE_IO, i); | 121 | } |
77 | if (res && !(res->flags & IORESOURCE_UNSET)) | 122 | |
78 | dev_dbg(&dev->dev, " io %#llx-%#llx flags %#lx\n", | 123 | char *pnp_option_priority_name(struct pnp_option *option) |
79 | (unsigned long long) res->start, | 124 | { |
80 | (unsigned long long) res->end, res->flags); | 125 | switch (pnp_option_priority(option)) { |
126 | case PNP_RES_PRIORITY_PREFERRED: | ||
127 | return "preferred"; | ||
128 | case PNP_RES_PRIORITY_ACCEPTABLE: | ||
129 | return "acceptable"; | ||
130 | case PNP_RES_PRIORITY_FUNCTIONAL: | ||
131 | return "functional"; | ||
81 | } | 132 | } |
82 | for (i = 0; i < PNP_MAX_MEM; i++) { | 133 | return "invalid"; |
83 | res = pnp_get_resource(dev, IORESOURCE_MEM, i); | 134 | } |
84 | if (res && !(res->flags & IORESOURCE_UNSET)) | 135 | |
85 | dev_dbg(&dev->dev, " mem %#llx-%#llx flags %#lx\n", | 136 | void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option) |
86 | (unsigned long long) res->start, | 137 | { |
87 | (unsigned long long) res->end, res->flags); | 138 | #ifdef DEBUG |
139 | char buf[128]; | ||
140 | int len = 0, i; | ||
141 | struct pnp_port *port; | ||
142 | struct pnp_mem *mem; | ||
143 | struct pnp_irq *irq; | ||
144 | struct pnp_dma *dma; | ||
145 | |||
146 | if (pnp_option_is_dependent(option)) | ||
147 | len += snprintf(buf + len, sizeof(buf) - len, | ||
148 | " dependent set %d (%s) ", | ||
149 | pnp_option_set(option), | ||
150 | pnp_option_priority_name(option)); | ||
151 | else | ||
152 | len += snprintf(buf + len, sizeof(buf) - len, " independent "); | ||
153 | |||
154 | switch (option->type) { | ||
155 | case IORESOURCE_IO: | ||
156 | port = &option->u.port; | ||
157 | len += snprintf(buf + len, sizeof(buf) - len, "io min %#llx " | ||
158 | "max %#llx align %lld size %lld flags %#x", | ||
159 | (unsigned long long) port->min, | ||
160 | (unsigned long long) port->max, | ||
161 | (unsigned long long) port->align, | ||
162 | (unsigned long long) port->size, port->flags); | ||
163 | break; | ||
164 | case IORESOURCE_MEM: | ||
165 | mem = &option->u.mem; | ||
166 | len += snprintf(buf + len, sizeof(buf) - len, "mem min %#llx " | ||
167 | "max %#llx align %lld size %lld flags %#x", | ||
168 | (unsigned long long) mem->min, | ||
169 | (unsigned long long) mem->max, | ||
170 | (unsigned long long) mem->align, | ||
171 | (unsigned long long) mem->size, mem->flags); | ||
172 | break; | ||
173 | case IORESOURCE_IRQ: | ||
174 | irq = &option->u.irq; | ||
175 | len += snprintf(buf + len, sizeof(buf) - len, "irq"); | ||
176 | if (bitmap_empty(irq->map.bits, PNP_IRQ_NR)) | ||
177 | len += snprintf(buf + len, sizeof(buf) - len, | ||
178 | " <none>"); | ||
179 | else { | ||
180 | for (i = 0; i < PNP_IRQ_NR; i++) | ||
181 | if (test_bit(i, irq->map.bits)) | ||
182 | len += snprintf(buf + len, | ||
183 | sizeof(buf) - len, | ||
184 | " %d", i); | ||
185 | } | ||
186 | len += snprintf(buf + len, sizeof(buf) - len, " flags %#x", | ||
187 | irq->flags); | ||
188 | if (irq->flags & IORESOURCE_IRQ_OPTIONAL) | ||
189 | len += snprintf(buf + len, sizeof(buf) - len, | ||
190 | " (optional)"); | ||
191 | break; | ||
192 | case IORESOURCE_DMA: | ||
193 | dma = &option->u.dma; | ||
194 | len += snprintf(buf + len, sizeof(buf) - len, "dma"); | ||
195 | if (!dma->map) | ||
196 | len += snprintf(buf + len, sizeof(buf) - len, | ||
197 | " <none>"); | ||
198 | else { | ||
199 | for (i = 0; i < 8; i++) | ||
200 | if (dma->map & (1 << i)) | ||
201 | len += snprintf(buf + len, | ||
202 | sizeof(buf) - len, | ||
203 | " %d", i); | ||
204 | } | ||
205 | len += snprintf(buf + len, sizeof(buf) - len, " (bitmask %#x) " | ||
206 | "flags %#x", dma->map, dma->flags); | ||
207 | break; | ||
88 | } | 208 | } |
209 | dev_dbg(&dev->dev, "%s\n", buf); | ||
89 | #endif | 210 | #endif |
90 | } | 211 | } |