aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pnp/interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pnp/interface.c')
-rw-r--r--drivers/pnp/interface.c207
1 files changed, 89 insertions, 118 deletions
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c
index 5695a79f3a52..a876ecf7028c 100644
--- a/drivers/pnp/interface.c
+++ b/drivers/pnp/interface.c
@@ -3,6 +3,8 @@
3 * 3 *
4 * Some code, especially possible resource dumping is based on isapnp_proc.c (c) Jaroslav Kysela <perex@perex.cz> 4 * Some code, especially possible resource dumping is based on isapnp_proc.c (c) Jaroslav Kysela <perex@perex.cz>
5 * Copyright 2002 Adam Belay <ambx1@neo.rr.com> 5 * Copyright 2002 Adam Belay <ambx1@neo.rr.com>
6 * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
7 * Bjorn Helgaas <bjorn.helgaas@hp.com>
6 */ 8 */
7 9
8#include <linux/pnp.h> 10#include <linux/pnp.h>
@@ -53,11 +55,13 @@ static int pnp_printf(pnp_info_buffer_t * buffer, char *fmt, ...)
53static void pnp_print_port(pnp_info_buffer_t * buffer, char *space, 55static void pnp_print_port(pnp_info_buffer_t * buffer, char *space,
54 struct pnp_port *port) 56 struct pnp_port *port)
55{ 57{
56 pnp_printf(buffer, 58 pnp_printf(buffer, "%sport %#llx-%#llx, align %#llx, size %#llx, "
57 "%sport 0x%x-0x%x, align 0x%x, size 0x%x, %i-bit address decoding\n", 59 "%i-bit address decoding\n", space,
58 space, port->min, port->max, 60 (unsigned long long) port->min,
59 port->align ? (port->align - 1) : 0, port->size, 61 (unsigned long long) port->max,
60 port->flags & PNP_PORT_FLAG_16BITADDR ? 16 : 10); 62 port->align ? ((unsigned long long) port->align - 1) : 0,
63 (unsigned long long) port->size,
64 port->flags & IORESOURCE_IO_16BIT_ADDR ? 16 : 10);
61} 65}
62 66
63static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space, 67static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space,
@@ -67,7 +71,7 @@ static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space,
67 71
68 pnp_printf(buffer, "%sirq ", space); 72 pnp_printf(buffer, "%sirq ", space);
69 for (i = 0; i < PNP_IRQ_NR; i++) 73 for (i = 0; i < PNP_IRQ_NR; i++)
70 if (test_bit(i, irq->map)) { 74 if (test_bit(i, irq->map.bits)) {
71 if (!first) { 75 if (!first) {
72 pnp_printf(buffer, ","); 76 pnp_printf(buffer, ",");
73 } else { 77 } else {
@@ -78,7 +82,7 @@ static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space,
78 else 82 else
79 pnp_printf(buffer, "%i", i); 83 pnp_printf(buffer, "%i", i);
80 } 84 }
81 if (bitmap_empty(irq->map, PNP_IRQ_NR)) 85 if (bitmap_empty(irq->map.bits, PNP_IRQ_NR))
82 pnp_printf(buffer, "<none>"); 86 pnp_printf(buffer, "<none>");
83 if (irq->flags & IORESOURCE_IRQ_HIGHEDGE) 87 if (irq->flags & IORESOURCE_IRQ_HIGHEDGE)
84 pnp_printf(buffer, " High-Edge"); 88 pnp_printf(buffer, " High-Edge");
@@ -88,6 +92,8 @@ static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space,
88 pnp_printf(buffer, " High-Level"); 92 pnp_printf(buffer, " High-Level");
89 if (irq->flags & IORESOURCE_IRQ_LOWLEVEL) 93 if (irq->flags & IORESOURCE_IRQ_LOWLEVEL)
90 pnp_printf(buffer, " Low-Level"); 94 pnp_printf(buffer, " Low-Level");
95 if (irq->flags & IORESOURCE_IRQ_OPTIONAL)
96 pnp_printf(buffer, " (optional)");
91 pnp_printf(buffer, "\n"); 97 pnp_printf(buffer, "\n");
92} 98}
93 99
@@ -148,8 +154,11 @@ static void pnp_print_mem(pnp_info_buffer_t * buffer, char *space,
148{ 154{
149 char *s; 155 char *s;
150 156
151 pnp_printf(buffer, "%sMemory 0x%x-0x%x, align 0x%x, size 0x%x", 157 pnp_printf(buffer, "%sMemory %#llx-%#llx, align %#llx, size %#llx",
152 space, mem->min, mem->max, mem->align, mem->size); 158 space, (unsigned long long) mem->min,
159 (unsigned long long) mem->max,
160 (unsigned long long) mem->align,
161 (unsigned long long) mem->size);
153 if (mem->flags & IORESOURCE_MEM_WRITEABLE) 162 if (mem->flags & IORESOURCE_MEM_WRITEABLE)
154 pnp_printf(buffer, ", writeable"); 163 pnp_printf(buffer, ", writeable");
155 if (mem->flags & IORESOURCE_MEM_CACHEABLE) 164 if (mem->flags & IORESOURCE_MEM_CACHEABLE)
@@ -177,65 +186,58 @@ static void pnp_print_mem(pnp_info_buffer_t * buffer, char *space,
177} 186}
178 187
179static void pnp_print_option(pnp_info_buffer_t * buffer, char *space, 188static void pnp_print_option(pnp_info_buffer_t * buffer, char *space,
180 struct pnp_option *option, int dep) 189 struct pnp_option *option)
181{ 190{
182 char *s; 191 switch (option->type) {
183 struct pnp_port *port; 192 case IORESOURCE_IO:
184 struct pnp_irq *irq; 193 pnp_print_port(buffer, space, &option->u.port);
185 struct pnp_dma *dma; 194 break;
186 struct pnp_mem *mem; 195 case IORESOURCE_MEM:
187 196 pnp_print_mem(buffer, space, &option->u.mem);
188 if (dep) { 197 break;
189 switch (option->priority) { 198 case IORESOURCE_IRQ:
190 case PNP_RES_PRIORITY_PREFERRED: 199 pnp_print_irq(buffer, space, &option->u.irq);
191 s = "preferred"; 200 break;
192 break; 201 case IORESOURCE_DMA:
193 case PNP_RES_PRIORITY_ACCEPTABLE: 202 pnp_print_dma(buffer, space, &option->u.dma);
194 s = "acceptable"; 203 break;
195 break;
196 case PNP_RES_PRIORITY_FUNCTIONAL:
197 s = "functional";
198 break;
199 default:
200 s = "invalid";
201 }
202 pnp_printf(buffer, "Dependent: %02i - Priority %s\n", dep, s);
203 } 204 }
204
205 for (port = option->port; port; port = port->next)
206 pnp_print_port(buffer, space, port);
207 for (irq = option->irq; irq; irq = irq->next)
208 pnp_print_irq(buffer, space, irq);
209 for (dma = option->dma; dma; dma = dma->next)
210 pnp_print_dma(buffer, space, dma);
211 for (mem = option->mem; mem; mem = mem->next)
212 pnp_print_mem(buffer, space, mem);
213} 205}
214 206
215static ssize_t pnp_show_options(struct device *dmdev, 207static ssize_t pnp_show_options(struct device *dmdev,
216 struct device_attribute *attr, char *buf) 208 struct device_attribute *attr, char *buf)
217{ 209{
218 struct pnp_dev *dev = to_pnp_dev(dmdev); 210 struct pnp_dev *dev = to_pnp_dev(dmdev);
219 struct pnp_option *independent = dev->independent; 211 pnp_info_buffer_t *buffer;
220 struct pnp_option *dependent = dev->dependent; 212 struct pnp_option *option;
221 int ret, dep = 1; 213 int ret, dep = 0, set = 0;
214 char *indent;
222 215
223 pnp_info_buffer_t *buffer = (pnp_info_buffer_t *) 216 buffer = pnp_alloc(sizeof(pnp_info_buffer_t));
224 pnp_alloc(sizeof(pnp_info_buffer_t));
225 if (!buffer) 217 if (!buffer)
226 return -ENOMEM; 218 return -ENOMEM;
227 219
228 buffer->len = PAGE_SIZE; 220 buffer->len = PAGE_SIZE;
229 buffer->buffer = buf; 221 buffer->buffer = buf;
230 buffer->curr = buffer->buffer; 222 buffer->curr = buffer->buffer;
231 if (independent)
232 pnp_print_option(buffer, "", independent, 0);
233 223
234 while (dependent) { 224 list_for_each_entry(option, &dev->options, list) {
235 pnp_print_option(buffer, " ", dependent, dep); 225 if (pnp_option_is_dependent(option)) {
236 dependent = dependent->next; 226 indent = " ";
237 dep++; 227 if (!dep || pnp_option_set(option) != set) {
228 set = pnp_option_set(option);
229 dep = 1;
230 pnp_printf(buffer, "Dependent: %02i - "
231 "Priority %s\n", set,
232 pnp_option_priority_name(option));
233 }
234 } else {
235 dep = 0;
236 indent = "";
237 }
238 pnp_print_option(buffer, indent, option);
238 } 239 }
240
239 ret = (buffer->curr - buf); 241 ret = (buffer->curr - buf);
240 kfree(buffer); 242 kfree(buffer);
241 return ret; 243 return ret;
@@ -248,79 +250,59 @@ static ssize_t pnp_show_current_resources(struct device *dmdev,
248 char *buf) 250 char *buf)
249{ 251{
250 struct pnp_dev *dev = to_pnp_dev(dmdev); 252 struct pnp_dev *dev = to_pnp_dev(dmdev);
251 struct resource *res;
252 int i, ret;
253 pnp_info_buffer_t *buffer; 253 pnp_info_buffer_t *buffer;
254 struct pnp_resource *pnp_res;
255 struct resource *res;
256 int ret;
254 257
255 if (!dev) 258 if (!dev)
256 return -EINVAL; 259 return -EINVAL;
257 260
258 buffer = (pnp_info_buffer_t *) pnp_alloc(sizeof(pnp_info_buffer_t)); 261 buffer = pnp_alloc(sizeof(pnp_info_buffer_t));
259 if (!buffer) 262 if (!buffer)
260 return -ENOMEM; 263 return -ENOMEM;
264
261 buffer->len = PAGE_SIZE; 265 buffer->len = PAGE_SIZE;
262 buffer->buffer = buf; 266 buffer->buffer = buf;
263 buffer->curr = buffer->buffer; 267 buffer->curr = buffer->buffer;
264 268
265 pnp_printf(buffer, "state = "); 269 pnp_printf(buffer, "state = %s\n", dev->active ? "active" : "disabled");
266 if (dev->active) 270
267 pnp_printf(buffer, "active\n"); 271 list_for_each_entry(pnp_res, &dev->resources, list) {
268 else 272 res = &pnp_res->res;
269 pnp_printf(buffer, "disabled\n"); 273
270 274 pnp_printf(buffer, pnp_resource_type_name(res));
271 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) { 275
272 if (pnp_resource_valid(res)) { 276 if (res->flags & IORESOURCE_DISABLED) {
273 pnp_printf(buffer, "io"); 277 pnp_printf(buffer, " disabled\n");
274 if (res->flags & IORESOURCE_DISABLED) 278 continue;
275 pnp_printf(buffer, " disabled\n");
276 else
277 pnp_printf(buffer, " 0x%llx-0x%llx\n",
278 (unsigned long long) res->start,
279 (unsigned long long) res->end);
280 }
281 }
282 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
283 if (pnp_resource_valid(res)) {
284 pnp_printf(buffer, "mem");
285 if (res->flags & IORESOURCE_DISABLED)
286 pnp_printf(buffer, " disabled\n");
287 else
288 pnp_printf(buffer, " 0x%llx-0x%llx\n",
289 (unsigned long long) res->start,
290 (unsigned long long) res->end);
291 }
292 }
293 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IRQ, i)); i++) {
294 if (pnp_resource_valid(res)) {
295 pnp_printf(buffer, "irq");
296 if (res->flags & IORESOURCE_DISABLED)
297 pnp_printf(buffer, " disabled\n");
298 else
299 pnp_printf(buffer, " %lld\n",
300 (unsigned long long) res->start);
301 } 279 }
302 } 280
303 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_DMA, i)); i++) { 281 switch (pnp_resource_type(res)) {
304 if (pnp_resource_valid(res)) { 282 case IORESOURCE_IO:
305 pnp_printf(buffer, "dma"); 283 case IORESOURCE_MEM:
306 if (res->flags & IORESOURCE_DISABLED) 284 pnp_printf(buffer, " %#llx-%#llx\n",
307 pnp_printf(buffer, " disabled\n"); 285 (unsigned long long) res->start,
308 else 286 (unsigned long long) res->end);
309 pnp_printf(buffer, " %lld\n", 287 break;
310 (unsigned long long) res->start); 288 case IORESOURCE_IRQ:
289 case IORESOURCE_DMA:
290 pnp_printf(buffer, " %lld\n",
291 (unsigned long long) res->start);
292 break;
311 } 293 }
312 } 294 }
295
313 ret = (buffer->curr - buf); 296 ret = (buffer->curr - buf);
314 kfree(buffer); 297 kfree(buffer);
315 return ret; 298 return ret;
316} 299}
317 300
318static ssize_t 301static ssize_t pnp_set_current_resources(struct device *dmdev,
319pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, 302 struct device_attribute *attr,
320 const char *ubuf, size_t count) 303 const char *ubuf, size_t count)
321{ 304{
322 struct pnp_dev *dev = to_pnp_dev(dmdev); 305 struct pnp_dev *dev = to_pnp_dev(dmdev);
323 struct pnp_resource *pnp_res;
324 char *buf = (void *)ubuf; 306 char *buf = (void *)ubuf;
325 int retval = 0; 307 int retval = 0;
326 resource_size_t start, end; 308 resource_size_t start, end;
@@ -368,7 +350,6 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
368 goto done; 350 goto done;
369 } 351 }
370 if (!strnicmp(buf, "set", 3)) { 352 if (!strnicmp(buf, "set", 3)) {
371 int nport = 0, nmem = 0, nirq = 0, ndma = 0;
372 if (dev->active) 353 if (dev->active)
373 goto done; 354 goto done;
374 buf += 3; 355 buf += 3;
@@ -391,10 +372,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
391 end = simple_strtoul(buf, &buf, 0); 372 end = simple_strtoul(buf, &buf, 0);
392 } else 373 } else
393 end = start; 374 end = start;
394 pnp_res = pnp_add_io_resource(dev, start, end, 375 pnp_add_io_resource(dev, start, end, 0);
395 0);
396 if (pnp_res)
397 pnp_res->index = nport++;
398 continue; 376 continue;
399 } 377 }
400 if (!strnicmp(buf, "mem", 3)) { 378 if (!strnicmp(buf, "mem", 3)) {
@@ -411,10 +389,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
411 end = simple_strtoul(buf, &buf, 0); 389 end = simple_strtoul(buf, &buf, 0);
412 } else 390 } else
413 end = start; 391 end = start;
414 pnp_res = pnp_add_mem_resource(dev, start, end, 392 pnp_add_mem_resource(dev, start, end, 0);
415 0);
416 if (pnp_res)
417 pnp_res->index = nmem++;
418 continue; 393 continue;
419 } 394 }
420 if (!strnicmp(buf, "irq", 3)) { 395 if (!strnicmp(buf, "irq", 3)) {
@@ -422,9 +397,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
422 while (isspace(*buf)) 397 while (isspace(*buf))
423 ++buf; 398 ++buf;
424 start = simple_strtoul(buf, &buf, 0); 399 start = simple_strtoul(buf, &buf, 0);
425 pnp_res = pnp_add_irq_resource(dev, start, 0); 400 pnp_add_irq_resource(dev, start, 0);
426 if (pnp_res)
427 pnp_res->index = nirq++;
428 continue; 401 continue;
429 } 402 }
430 if (!strnicmp(buf, "dma", 3)) { 403 if (!strnicmp(buf, "dma", 3)) {
@@ -432,9 +405,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
432 while (isspace(*buf)) 405 while (isspace(*buf))
433 ++buf; 406 ++buf;
434 start = simple_strtoul(buf, &buf, 0); 407 start = simple_strtoul(buf, &buf, 0);
435 pnp_res = pnp_add_dma_resource(dev, start, 0); 408 pnp_add_dma_resource(dev, start, 0);
436 if (pnp_res)
437 pnp_res->index = ndma++;
438 continue; 409 continue;
439 } 410 }
440 break; 411 break;