2 * interface.c - contains everything related to the user interface
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>
9 #include <linux/string.h>
10 #include <linux/errno.h>
11 #include <linux/list.h>
12 #include <linux/types.h>
13 #include <linux/pnp.h>
14 #include <linux/stat.h>
15 #include <linux/ctype.h>
16 #include <linux/slab.h>
17 #include <linux/mutex.h>
19 #include <asm/uaccess.h>
23 struct pnp_info_buffer
{
24 char *buffer
; /* pointer to begin of buffer */
25 char *curr
; /* current position in buffer */
26 unsigned long size
; /* current size */
27 unsigned long len
; /* total length of buffer */
28 int stop
; /* stop flag */
29 int error
; /* error code */
32 typedef struct pnp_info_buffer pnp_info_buffer_t
;
34 static int pnp_printf(pnp_info_buffer_t
* buffer
, char *fmt
, ...)
39 if (buffer
->stop
|| buffer
->error
)
42 res
= vsnprintf(buffer
->curr
, buffer
->len
- buffer
->size
, fmt
, args
);
44 if (buffer
->size
+ res
>= buffer
->len
) {
53 static void pnp_print_port(pnp_info_buffer_t
* buffer
, char *space
,
54 struct pnp_port
*port
)
57 "%sport 0x%x-0x%x, align 0x%x, size 0x%x, %i-bit address decoding\n",
58 space
, port
->min
, port
->max
,
59 port
->align
? (port
->align
- 1) : 0, port
->size
,
60 port
->flags
& PNP_PORT_FLAG_16BITADDR
? 16 : 10);
63 static void pnp_print_irq(pnp_info_buffer_t
* buffer
, char *space
,
68 pnp_printf(buffer
, "%sirq ", space
);
69 for (i
= 0; i
< PNP_IRQ_NR
; i
++)
70 if (test_bit(i
, irq
->map
)) {
72 pnp_printf(buffer
, ",");
77 pnp_printf(buffer
, "2/9");
79 pnp_printf(buffer
, "%i", i
);
81 if (bitmap_empty(irq
->map
, PNP_IRQ_NR
))
82 pnp_printf(buffer
, "<none>");
83 if (irq
->flags
& IORESOURCE_IRQ_HIGHEDGE
)
84 pnp_printf(buffer
, " High-Edge");
85 if (irq
->flags
& IORESOURCE_IRQ_LOWEDGE
)
86 pnp_printf(buffer
, " Low-Edge");
87 if (irq
->flags
& IORESOURCE_IRQ_HIGHLEVEL
)
88 pnp_printf(buffer
, " High-Level");
89 if (irq
->flags
& IORESOURCE_IRQ_LOWLEVEL
)
90 pnp_printf(buffer
, " Low-Level");
91 pnp_printf(buffer
, "\n");
94 static void pnp_print_dma(pnp_info_buffer_t
* buffer
, char *space
,
100 pnp_printf(buffer
, "%sdma ", space
);
101 for (i
= 0; i
< 8; i
++)
102 if (dma
->map
& (1 << i
)) {
104 pnp_printf(buffer
, ",");
108 pnp_printf(buffer
, "%i", i
);
111 pnp_printf(buffer
, "<none>");
112 switch (dma
->flags
& IORESOURCE_DMA_TYPE_MASK
) {
113 case IORESOURCE_DMA_8BIT
:
116 case IORESOURCE_DMA_8AND16BIT
:
122 pnp_printf(buffer
, " %s", s
);
123 if (dma
->flags
& IORESOURCE_DMA_MASTER
)
124 pnp_printf(buffer
, " master");
125 if (dma
->flags
& IORESOURCE_DMA_BYTE
)
126 pnp_printf(buffer
, " byte-count");
127 if (dma
->flags
& IORESOURCE_DMA_WORD
)
128 pnp_printf(buffer
, " word-count");
129 switch (dma
->flags
& IORESOURCE_DMA_SPEED_MASK
) {
130 case IORESOURCE_DMA_TYPEA
:
133 case IORESOURCE_DMA_TYPEB
:
136 case IORESOURCE_DMA_TYPEF
:
143 pnp_printf(buffer
, " %s\n", s
);
146 static void pnp_print_mem(pnp_info_buffer_t
* buffer
, char *space
,
151 pnp_printf(buffer
, "%sMemory 0x%x-0x%x, align 0x%x, size 0x%x",
152 space
, mem
->min
, mem
->max
, mem
->align
, mem
->size
);
153 if (mem
->flags
& IORESOURCE_MEM_WRITEABLE
)
154 pnp_printf(buffer
, ", writeable");
155 if (mem
->flags
& IORESOURCE_MEM_CACHEABLE
)
156 pnp_printf(buffer
, ", cacheable");
157 if (mem
->flags
& IORESOURCE_MEM_RANGELENGTH
)
158 pnp_printf(buffer
, ", range-length");
159 if (mem
->flags
& IORESOURCE_MEM_SHADOWABLE
)
160 pnp_printf(buffer
, ", shadowable");
161 if (mem
->flags
& IORESOURCE_MEM_EXPANSIONROM
)
162 pnp_printf(buffer
, ", expansion ROM");
163 switch (mem
->flags
& IORESOURCE_MEM_TYPE_MASK
) {
164 case IORESOURCE_MEM_8BIT
:
167 case IORESOURCE_MEM_8AND16BIT
:
170 case IORESOURCE_MEM_32BIT
:
176 pnp_printf(buffer
, ", %s\n", s
);
179 static void pnp_print_option(pnp_info_buffer_t
* buffer
, char *space
,
180 struct pnp_option
*option
, int dep
)
183 struct pnp_port
*port
;
189 switch (option
->priority
) {
190 case PNP_RES_PRIORITY_PREFERRED
:
193 case PNP_RES_PRIORITY_ACCEPTABLE
:
196 case PNP_RES_PRIORITY_FUNCTIONAL
:
202 pnp_printf(buffer
, "Dependent: %02i - Priority %s\n", dep
, s
);
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
);
215 static ssize_t
pnp_show_options(struct device
*dmdev
,
216 struct device_attribute
*attr
, char *buf
)
218 struct pnp_dev
*dev
= to_pnp_dev(dmdev
);
219 struct pnp_option
*independent
= dev
->independent
;
220 struct pnp_option
*dependent
= dev
->dependent
;
223 pnp_info_buffer_t
*buffer
= (pnp_info_buffer_t
*)
224 pnp_alloc(sizeof(pnp_info_buffer_t
));
228 buffer
->len
= PAGE_SIZE
;
229 buffer
->buffer
= buf
;
230 buffer
->curr
= buffer
->buffer
;
232 pnp_print_option(buffer
, "", independent
, 0);
235 pnp_print_option(buffer
, " ", dependent
, dep
);
236 dependent
= dependent
->next
;
239 ret
= (buffer
->curr
- buf
);
244 static DEVICE_ATTR(options
, S_IRUGO
, pnp_show_options
, NULL
);
246 static ssize_t
pnp_show_current_resources(struct device
*dmdev
,
247 struct device_attribute
*attr
,
250 struct pnp_dev
*dev
= to_pnp_dev(dmdev
);
251 struct resource
*res
;
253 pnp_info_buffer_t
*buffer
;
258 buffer
= (pnp_info_buffer_t
*) pnp_alloc(sizeof(pnp_info_buffer_t
));
261 buffer
->len
= PAGE_SIZE
;
262 buffer
->buffer
= buf
;
263 buffer
->curr
= buffer
->buffer
;
265 pnp_printf(buffer
, "state = ");
267 pnp_printf(buffer
, "active\n");
269 pnp_printf(buffer
, "disabled\n");
271 for (i
= 0; (res
= pnp_get_resource(dev
, IORESOURCE_IO
, i
)); i
++) {
272 if (pnp_resource_valid(res
)) {
273 pnp_printf(buffer
, "io");
274 if (res
->flags
& IORESOURCE_DISABLED
)
275 pnp_printf(buffer
, " disabled\n");
277 pnp_printf(buffer
, " 0x%llx-0x%llx\n",
278 (unsigned long long) res
->start
,
279 (unsigned long long) res
->end
);
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");
288 pnp_printf(buffer
, " 0x%llx-0x%llx\n",
289 (unsigned long long) res
->start
,
290 (unsigned long long) res
->end
);
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");
299 pnp_printf(buffer
, " %lld\n",
300 (unsigned long long) res
->start
);
303 for (i
= 0; (res
= pnp_get_resource(dev
, IORESOURCE_DMA
, i
)); i
++) {
304 if (pnp_resource_valid(res
)) {
305 pnp_printf(buffer
, "dma");
306 if (res
->flags
& IORESOURCE_DISABLED
)
307 pnp_printf(buffer
, " disabled\n");
309 pnp_printf(buffer
, " %lld\n",
310 (unsigned long long) res
->start
);
313 ret
= (buffer
->curr
- buf
);
319 pnp_set_current_resources(struct device
*dmdev
, struct device_attribute
*attr
,
320 const char *ubuf
, size_t count
)
322 struct pnp_dev
*dev
= to_pnp_dev(dmdev
);
323 struct pnp_resource
*pnp_res
;
324 char *buf
= (void *)ubuf
;
326 resource_size_t start
, end
;
328 if (dev
->status
& PNP_ATTACHED
) {
330 dev_info(&dev
->dev
, "in use; can't configure\n");
334 while (isspace(*buf
))
336 if (!strnicmp(buf
, "disable", 7)) {
337 retval
= pnp_disable_dev(dev
);
340 if (!strnicmp(buf
, "activate", 8)) {
341 retval
= pnp_activate_dev(dev
);
344 if (!strnicmp(buf
, "fill", 4)) {
347 retval
= pnp_auto_config_dev(dev
);
350 if (!strnicmp(buf
, "auto", 4)) {
353 pnp_init_resources(dev
);
354 retval
= pnp_auto_config_dev(dev
);
357 if (!strnicmp(buf
, "clear", 5)) {
360 pnp_init_resources(dev
);
363 if (!strnicmp(buf
, "get", 3)) {
364 mutex_lock(&pnp_res_mutex
);
365 if (pnp_can_read(dev
))
366 dev
->protocol
->get(dev
);
367 mutex_unlock(&pnp_res_mutex
);
370 if (!strnicmp(buf
, "set", 3)) {
371 int nport
= 0, nmem
= 0, nirq
= 0, ndma
= 0;
375 pnp_init_resources(dev
);
376 mutex_lock(&pnp_res_mutex
);
378 while (isspace(*buf
))
380 if (!strnicmp(buf
, "io", 2)) {
382 while (isspace(*buf
))
384 start
= simple_strtoul(buf
, &buf
, 0);
385 while (isspace(*buf
))
389 while (isspace(*buf
))
391 end
= simple_strtoul(buf
, &buf
, 0);
394 pnp_res
= pnp_add_io_resource(dev
, start
, end
,
397 pnp_res
->index
= nport
++;
400 if (!strnicmp(buf
, "mem", 3)) {
402 while (isspace(*buf
))
404 start
= simple_strtoul(buf
, &buf
, 0);
405 while (isspace(*buf
))
409 while (isspace(*buf
))
411 end
= simple_strtoul(buf
, &buf
, 0);
414 pnp_res
= pnp_add_mem_resource(dev
, start
, end
,
417 pnp_res
->index
= nmem
++;
420 if (!strnicmp(buf
, "irq", 3)) {
422 while (isspace(*buf
))
424 start
= simple_strtoul(buf
, &buf
, 0);
425 pnp_res
= pnp_add_irq_resource(dev
, start
, 0);
427 pnp_res
->index
= nirq
++;
430 if (!strnicmp(buf
, "dma", 3)) {
432 while (isspace(*buf
))
434 start
= simple_strtoul(buf
, &buf
, 0);
435 pnp_res
= pnp_add_dma_resource(dev
, start
, 0);
437 pnp_res
->index
= ndma
++;
442 mutex_unlock(&pnp_res_mutex
);
452 static DEVICE_ATTR(resources
, S_IRUGO
| S_IWUSR
,
453 pnp_show_current_resources
, pnp_set_current_resources
);
455 static ssize_t
pnp_show_current_ids(struct device
*dmdev
,
456 struct device_attribute
*attr
, char *buf
)
459 struct pnp_dev
*dev
= to_pnp_dev(dmdev
);
460 struct pnp_id
*pos
= dev
->id
;
463 str
+= sprintf(str
, "%s\n", pos
->id
);
469 static DEVICE_ATTR(id
, S_IRUGO
, pnp_show_current_ids
, NULL
);
471 int pnp_interface_attach_device(struct pnp_dev
*dev
)
473 int rc
= device_create_file(&dev
->dev
, &dev_attr_options
);
477 rc
= device_create_file(&dev
->dev
, &dev_attr_resources
);
480 rc
= device_create_file(&dev
->dev
, &dev_attr_id
);
487 device_remove_file(&dev
->dev
, &dev_attr_resources
);
489 device_remove_file(&dev
->dev
, &dev_attr_options
);