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
)
56 pnp_printf(buffer
, "%sport %#llx-%#llx, align %#llx, size %#llx, "
57 "%i-bit address decoding\n", space
,
58 (unsigned long long) port
->min
,
59 (unsigned long long) port
->max
,
60 port
->align
? ((unsigned long long) port
->align
- 1) : 0,
61 (unsigned long long) port
->size
,
62 port
->flags
& IORESOURCE_IO_16BIT_ADDR
? 16 : 10);
65 static void pnp_print_irq(pnp_info_buffer_t
* buffer
, char *space
,
70 pnp_printf(buffer
, "%sirq ", space
);
71 for (i
= 0; i
< PNP_IRQ_NR
; i
++)
72 if (test_bit(i
, irq
->map
.bits
)) {
74 pnp_printf(buffer
, ",");
79 pnp_printf(buffer
, "2/9");
81 pnp_printf(buffer
, "%i", i
);
83 if (bitmap_empty(irq
->map
.bits
, PNP_IRQ_NR
))
84 pnp_printf(buffer
, "<none>");
85 if (irq
->flags
& IORESOURCE_IRQ_HIGHEDGE
)
86 pnp_printf(buffer
, " High-Edge");
87 if (irq
->flags
& IORESOURCE_IRQ_LOWEDGE
)
88 pnp_printf(buffer
, " Low-Edge");
89 if (irq
->flags
& IORESOURCE_IRQ_HIGHLEVEL
)
90 pnp_printf(buffer
, " High-Level");
91 if (irq
->flags
& IORESOURCE_IRQ_LOWLEVEL
)
92 pnp_printf(buffer
, " Low-Level");
93 if (irq
->flags
& IORESOURCE_IRQ_OPTIONAL
)
94 pnp_printf(buffer
, " (optional)");
95 pnp_printf(buffer
, "\n");
98 static void pnp_print_dma(pnp_info_buffer_t
* buffer
, char *space
,
104 pnp_printf(buffer
, "%sdma ", space
);
105 for (i
= 0; i
< 8; i
++)
106 if (dma
->map
& (1 << i
)) {
108 pnp_printf(buffer
, ",");
112 pnp_printf(buffer
, "%i", i
);
115 pnp_printf(buffer
, "<none>");
116 switch (dma
->flags
& IORESOURCE_DMA_TYPE_MASK
) {
117 case IORESOURCE_DMA_8BIT
:
120 case IORESOURCE_DMA_8AND16BIT
:
126 pnp_printf(buffer
, " %s", s
);
127 if (dma
->flags
& IORESOURCE_DMA_MASTER
)
128 pnp_printf(buffer
, " master");
129 if (dma
->flags
& IORESOURCE_DMA_BYTE
)
130 pnp_printf(buffer
, " byte-count");
131 if (dma
->flags
& IORESOURCE_DMA_WORD
)
132 pnp_printf(buffer
, " word-count");
133 switch (dma
->flags
& IORESOURCE_DMA_SPEED_MASK
) {
134 case IORESOURCE_DMA_TYPEA
:
137 case IORESOURCE_DMA_TYPEB
:
140 case IORESOURCE_DMA_TYPEF
:
147 pnp_printf(buffer
, " %s\n", s
);
150 static void pnp_print_mem(pnp_info_buffer_t
* buffer
, char *space
,
155 pnp_printf(buffer
, "%sMemory %#llx-%#llx, align %#llx, size %#llx",
156 space
, (unsigned long long) mem
->min
,
157 (unsigned long long) mem
->max
,
158 (unsigned long long) mem
->align
,
159 (unsigned long long) mem
->size
);
160 if (mem
->flags
& IORESOURCE_MEM_WRITEABLE
)
161 pnp_printf(buffer
, ", writeable");
162 if (mem
->flags
& IORESOURCE_MEM_CACHEABLE
)
163 pnp_printf(buffer
, ", cacheable");
164 if (mem
->flags
& IORESOURCE_MEM_RANGELENGTH
)
165 pnp_printf(buffer
, ", range-length");
166 if (mem
->flags
& IORESOURCE_MEM_SHADOWABLE
)
167 pnp_printf(buffer
, ", shadowable");
168 if (mem
->flags
& IORESOURCE_MEM_EXPANSIONROM
)
169 pnp_printf(buffer
, ", expansion ROM");
170 switch (mem
->flags
& IORESOURCE_MEM_TYPE_MASK
) {
171 case IORESOURCE_MEM_8BIT
:
174 case IORESOURCE_MEM_8AND16BIT
:
177 case IORESOURCE_MEM_32BIT
:
183 pnp_printf(buffer
, ", %s\n", s
);
186 static void pnp_print_option(pnp_info_buffer_t
* buffer
, char *space
,
187 struct pnp_option
*option
, int dep
)
190 struct pnp_port
*port
;
196 switch (option
->priority
) {
197 case PNP_RES_PRIORITY_PREFERRED
:
200 case PNP_RES_PRIORITY_ACCEPTABLE
:
203 case PNP_RES_PRIORITY_FUNCTIONAL
:
209 pnp_printf(buffer
, "Dependent: %02i - Priority %s\n", dep
, s
);
212 for (port
= option
->port
; port
; port
= port
->next
)
213 pnp_print_port(buffer
, space
, port
);
214 for (irq
= option
->irq
; irq
; irq
= irq
->next
)
215 pnp_print_irq(buffer
, space
, irq
);
216 for (dma
= option
->dma
; dma
; dma
= dma
->next
)
217 pnp_print_dma(buffer
, space
, dma
);
218 for (mem
= option
->mem
; mem
; mem
= mem
->next
)
219 pnp_print_mem(buffer
, space
, mem
);
222 static ssize_t
pnp_show_options(struct device
*dmdev
,
223 struct device_attribute
*attr
, char *buf
)
225 struct pnp_dev
*dev
= to_pnp_dev(dmdev
);
226 pnp_info_buffer_t
*buffer
;
227 struct pnp_option
*independent
= dev
->independent
;
228 struct pnp_option
*dependent
= dev
->dependent
;
231 buffer
= pnp_alloc(sizeof(pnp_info_buffer_t
));
235 buffer
->len
= PAGE_SIZE
;
236 buffer
->buffer
= buf
;
237 buffer
->curr
= buffer
->buffer
;
239 pnp_print_option(buffer
, "", independent
, 0);
242 pnp_print_option(buffer
, " ", dependent
, dep
);
243 dependent
= dependent
->next
;
246 ret
= (buffer
->curr
- buf
);
251 static DEVICE_ATTR(options
, S_IRUGO
, pnp_show_options
, NULL
);
253 static ssize_t
pnp_show_current_resources(struct device
*dmdev
,
254 struct device_attribute
*attr
,
257 struct pnp_dev
*dev
= to_pnp_dev(dmdev
);
258 pnp_info_buffer_t
*buffer
;
259 struct pnp_resource
*pnp_res
;
260 struct resource
*res
;
266 buffer
= pnp_alloc(sizeof(pnp_info_buffer_t
));
270 buffer
->len
= PAGE_SIZE
;
271 buffer
->buffer
= buf
;
272 buffer
->curr
= buffer
->buffer
;
274 pnp_printf(buffer
, "state = %s\n", dev
->active
? "active" : "disabled");
276 list_for_each_entry(pnp_res
, &dev
->resources
, list
) {
279 pnp_printf(buffer
, pnp_resource_type_name(res
));
281 if (res
->flags
& IORESOURCE_DISABLED
) {
282 pnp_printf(buffer
, " disabled\n");
286 switch (pnp_resource_type(res
)) {
289 pnp_printf(buffer
, " %#llx-%#llx\n",
290 (unsigned long long) res
->start
,
291 (unsigned long long) res
->end
);
295 pnp_printf(buffer
, " %lld\n",
296 (unsigned long long) res
->start
);
301 ret
= (buffer
->curr
- buf
);
306 static ssize_t
pnp_set_current_resources(struct device
*dmdev
,
307 struct device_attribute
*attr
,
308 const char *ubuf
, size_t count
)
310 struct pnp_dev
*dev
= to_pnp_dev(dmdev
);
311 char *buf
= (void *)ubuf
;
313 resource_size_t start
, end
;
315 if (dev
->status
& PNP_ATTACHED
) {
317 dev_info(&dev
->dev
, "in use; can't configure\n");
321 while (isspace(*buf
))
323 if (!strnicmp(buf
, "disable", 7)) {
324 retval
= pnp_disable_dev(dev
);
327 if (!strnicmp(buf
, "activate", 8)) {
328 retval
= pnp_activate_dev(dev
);
331 if (!strnicmp(buf
, "fill", 4)) {
334 retval
= pnp_auto_config_dev(dev
);
337 if (!strnicmp(buf
, "auto", 4)) {
340 pnp_init_resources(dev
);
341 retval
= pnp_auto_config_dev(dev
);
344 if (!strnicmp(buf
, "clear", 5)) {
347 pnp_init_resources(dev
);
350 if (!strnicmp(buf
, "get", 3)) {
351 mutex_lock(&pnp_res_mutex
);
352 if (pnp_can_read(dev
))
353 dev
->protocol
->get(dev
);
354 mutex_unlock(&pnp_res_mutex
);
357 if (!strnicmp(buf
, "set", 3)) {
361 pnp_init_resources(dev
);
362 mutex_lock(&pnp_res_mutex
);
364 while (isspace(*buf
))
366 if (!strnicmp(buf
, "io", 2)) {
368 while (isspace(*buf
))
370 start
= simple_strtoul(buf
, &buf
, 0);
371 while (isspace(*buf
))
375 while (isspace(*buf
))
377 end
= simple_strtoul(buf
, &buf
, 0);
380 pnp_add_io_resource(dev
, start
, end
, 0);
383 if (!strnicmp(buf
, "mem", 3)) {
385 while (isspace(*buf
))
387 start
= simple_strtoul(buf
, &buf
, 0);
388 while (isspace(*buf
))
392 while (isspace(*buf
))
394 end
= simple_strtoul(buf
, &buf
, 0);
397 pnp_add_mem_resource(dev
, start
, end
, 0);
400 if (!strnicmp(buf
, "irq", 3)) {
402 while (isspace(*buf
))
404 start
= simple_strtoul(buf
, &buf
, 0);
405 pnp_add_irq_resource(dev
, start
, 0);
408 if (!strnicmp(buf
, "dma", 3)) {
410 while (isspace(*buf
))
412 start
= simple_strtoul(buf
, &buf
, 0);
413 pnp_add_dma_resource(dev
, start
, 0);
418 mutex_unlock(&pnp_res_mutex
);
428 static DEVICE_ATTR(resources
, S_IRUGO
| S_IWUSR
,
429 pnp_show_current_resources
, pnp_set_current_resources
);
431 static ssize_t
pnp_show_current_ids(struct device
*dmdev
,
432 struct device_attribute
*attr
, char *buf
)
435 struct pnp_dev
*dev
= to_pnp_dev(dmdev
);
436 struct pnp_id
*pos
= dev
->id
;
439 str
+= sprintf(str
, "%s\n", pos
->id
);
445 static DEVICE_ATTR(id
, S_IRUGO
, pnp_show_current_ids
, NULL
);
447 int pnp_interface_attach_device(struct pnp_dev
*dev
)
449 int rc
= device_create_file(&dev
->dev
, &dev_attr_options
);
453 rc
= device_create_file(&dev
->dev
, &dev_attr_resources
);
456 rc
= device_create_file(&dev
->dev
, &dev_attr_id
);
463 device_remove_file(&dev
->dev
, &dev_attr_resources
);
465 device_remove_file(&dev
->dev
, &dev_attr_options
);