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>
6 * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
7 * Bjorn Helgaas <bjorn.helgaas@hp.com>
10 #include <linux/pnp.h>
11 #include <linux/string.h>
12 #include <linux/errno.h>
13 #include <linux/list.h>
14 #include <linux/types.h>
15 #include <linux/stat.h>
16 #include <linux/ctype.h>
17 #include <linux/slab.h>
18 #include <linux/mutex.h>
20 #include <asm/uaccess.h>
24 struct pnp_info_buffer
{
25 char *buffer
; /* pointer to begin of buffer */
26 char *curr
; /* current position in buffer */
27 unsigned long size
; /* current size */
28 unsigned long len
; /* total length of buffer */
29 int stop
; /* stop flag */
30 int error
; /* error code */
33 typedef struct pnp_info_buffer pnp_info_buffer_t
;
35 static int pnp_printf(pnp_info_buffer_t
* buffer
, char *fmt
, ...)
40 if (buffer
->stop
|| buffer
->error
)
43 res
= vsnprintf(buffer
->curr
, buffer
->len
- buffer
->size
, fmt
, args
);
45 if (buffer
->size
+ res
>= buffer
->len
) {
54 static void pnp_print_port(pnp_info_buffer_t
* buffer
, char *space
,
55 struct pnp_port
*port
)
57 pnp_printf(buffer
, "%sport %#llx-%#llx, align %#llx, size %#llx, "
58 "%i-bit address decoding\n", space
,
59 (unsigned long long) port
->min
,
60 (unsigned long long) port
->max
,
61 port
->align
? ((unsigned long long) port
->align
- 1) : 0,
62 (unsigned long long) port
->size
,
63 port
->flags
& IORESOURCE_IO_16BIT_ADDR
? 16 : 10);
66 static void pnp_print_irq(pnp_info_buffer_t
* buffer
, char *space
,
71 pnp_printf(buffer
, "%sirq ", space
);
72 for (i
= 0; i
< PNP_IRQ_NR
; i
++)
73 if (test_bit(i
, irq
->map
.bits
)) {
75 pnp_printf(buffer
, ",");
80 pnp_printf(buffer
, "2/9");
82 pnp_printf(buffer
, "%i", i
);
84 if (bitmap_empty(irq
->map
.bits
, PNP_IRQ_NR
))
85 pnp_printf(buffer
, "<none>");
86 if (irq
->flags
& IORESOURCE_IRQ_HIGHEDGE
)
87 pnp_printf(buffer
, " High-Edge");
88 if (irq
->flags
& IORESOURCE_IRQ_LOWEDGE
)
89 pnp_printf(buffer
, " Low-Edge");
90 if (irq
->flags
& IORESOURCE_IRQ_HIGHLEVEL
)
91 pnp_printf(buffer
, " High-Level");
92 if (irq
->flags
& IORESOURCE_IRQ_LOWLEVEL
)
93 pnp_printf(buffer
, " Low-Level");
94 if (irq
->flags
& IORESOURCE_IRQ_OPTIONAL
)
95 pnp_printf(buffer
, " (optional)");
96 pnp_printf(buffer
, "\n");
99 static void pnp_print_dma(pnp_info_buffer_t
* buffer
, char *space
,
105 pnp_printf(buffer
, "%sdma ", space
);
106 for (i
= 0; i
< 8; i
++)
107 if (dma
->map
& (1 << i
)) {
109 pnp_printf(buffer
, ",");
113 pnp_printf(buffer
, "%i", i
);
116 pnp_printf(buffer
, "<none>");
117 switch (dma
->flags
& IORESOURCE_DMA_TYPE_MASK
) {
118 case IORESOURCE_DMA_8BIT
:
121 case IORESOURCE_DMA_8AND16BIT
:
127 pnp_printf(buffer
, " %s", s
);
128 if (dma
->flags
& IORESOURCE_DMA_MASTER
)
129 pnp_printf(buffer
, " master");
130 if (dma
->flags
& IORESOURCE_DMA_BYTE
)
131 pnp_printf(buffer
, " byte-count");
132 if (dma
->flags
& IORESOURCE_DMA_WORD
)
133 pnp_printf(buffer
, " word-count");
134 switch (dma
->flags
& IORESOURCE_DMA_SPEED_MASK
) {
135 case IORESOURCE_DMA_TYPEA
:
138 case IORESOURCE_DMA_TYPEB
:
141 case IORESOURCE_DMA_TYPEF
:
148 pnp_printf(buffer
, " %s\n", s
);
151 static void pnp_print_mem(pnp_info_buffer_t
* buffer
, char *space
,
156 pnp_printf(buffer
, "%sMemory %#llx-%#llx, align %#llx, size %#llx",
157 space
, (unsigned long long) mem
->min
,
158 (unsigned long long) mem
->max
,
159 (unsigned long long) mem
->align
,
160 (unsigned long long) mem
->size
);
161 if (mem
->flags
& IORESOURCE_MEM_WRITEABLE
)
162 pnp_printf(buffer
, ", writeable");
163 if (mem
->flags
& IORESOURCE_MEM_CACHEABLE
)
164 pnp_printf(buffer
, ", cacheable");
165 if (mem
->flags
& IORESOURCE_MEM_RANGELENGTH
)
166 pnp_printf(buffer
, ", range-length");
167 if (mem
->flags
& IORESOURCE_MEM_SHADOWABLE
)
168 pnp_printf(buffer
, ", shadowable");
169 if (mem
->flags
& IORESOURCE_MEM_EXPANSIONROM
)
170 pnp_printf(buffer
, ", expansion ROM");
171 switch (mem
->flags
& IORESOURCE_MEM_TYPE_MASK
) {
172 case IORESOURCE_MEM_8BIT
:
175 case IORESOURCE_MEM_8AND16BIT
:
178 case IORESOURCE_MEM_32BIT
:
184 pnp_printf(buffer
, ", %s\n", s
);
187 static void pnp_print_option(pnp_info_buffer_t
* buffer
, char *space
,
188 struct pnp_option
*option
)
190 switch (option
->type
) {
192 pnp_print_port(buffer
, space
, &option
->u
.port
);
195 pnp_print_mem(buffer
, space
, &option
->u
.mem
);
198 pnp_print_irq(buffer
, space
, &option
->u
.irq
);
201 pnp_print_dma(buffer
, space
, &option
->u
.dma
);
206 static ssize_t
pnp_show_options(struct device
*dmdev
,
207 struct device_attribute
*attr
, char *buf
)
209 struct pnp_dev
*dev
= to_pnp_dev(dmdev
);
210 pnp_info_buffer_t
*buffer
;
211 struct pnp_option
*option
;
212 int ret
, dep
= 0, set
= 0;
215 buffer
= pnp_alloc(sizeof(pnp_info_buffer_t
));
219 buffer
->len
= PAGE_SIZE
;
220 buffer
->buffer
= buf
;
221 buffer
->curr
= buffer
->buffer
;
223 list_for_each_entry(option
, &dev
->options
, list
) {
224 if (pnp_option_is_dependent(option
)) {
226 if (!dep
|| pnp_option_set(option
) != set
) {
227 set
= pnp_option_set(option
);
229 pnp_printf(buffer
, "Dependent: %02i - "
230 "Priority %s\n", set
,
231 pnp_option_priority_name(option
));
237 pnp_print_option(buffer
, indent
, option
);
240 ret
= (buffer
->curr
- buf
);
245 static ssize_t
pnp_show_current_resources(struct device
*dmdev
,
246 struct device_attribute
*attr
,
249 struct pnp_dev
*dev
= to_pnp_dev(dmdev
);
250 pnp_info_buffer_t
*buffer
;
251 struct pnp_resource
*pnp_res
;
252 struct resource
*res
;
258 buffer
= pnp_alloc(sizeof(pnp_info_buffer_t
));
262 buffer
->len
= PAGE_SIZE
;
263 buffer
->buffer
= buf
;
264 buffer
->curr
= buffer
->buffer
;
266 pnp_printf(buffer
, "state = %s\n", dev
->active
? "active" : "disabled");
268 list_for_each_entry(pnp_res
, &dev
->resources
, list
) {
271 pnp_printf(buffer
, pnp_resource_type_name(res
));
273 if (res
->flags
& IORESOURCE_DISABLED
) {
274 pnp_printf(buffer
, " disabled\n");
278 switch (pnp_resource_type(res
)) {
281 pnp_printf(buffer
, " %#llx-%#llx\n",
282 (unsigned long long) res
->start
,
283 (unsigned long long) res
->end
);
287 pnp_printf(buffer
, " %lld\n",
288 (unsigned long long) res
->start
);
293 ret
= (buffer
->curr
- buf
);
298 static ssize_t
pnp_set_current_resources(struct device
*dmdev
,
299 struct device_attribute
*attr
,
300 const char *ubuf
, size_t count
)
302 struct pnp_dev
*dev
= to_pnp_dev(dmdev
);
303 char *buf
= (void *)ubuf
;
305 resource_size_t start
, end
;
307 if (dev
->status
& PNP_ATTACHED
) {
309 dev_info(&dev
->dev
, "in use; can't configure\n");
313 buf
= skip_spaces(buf
);
314 if (!strnicmp(buf
, "disable", 7)) {
315 retval
= pnp_disable_dev(dev
);
318 if (!strnicmp(buf
, "activate", 8)) {
319 retval
= pnp_activate_dev(dev
);
322 if (!strnicmp(buf
, "fill", 4)) {
325 retval
= pnp_auto_config_dev(dev
);
328 if (!strnicmp(buf
, "auto", 4)) {
331 pnp_init_resources(dev
);
332 retval
= pnp_auto_config_dev(dev
);
335 if (!strnicmp(buf
, "clear", 5)) {
338 pnp_init_resources(dev
);
341 if (!strnicmp(buf
, "get", 3)) {
342 mutex_lock(&pnp_res_mutex
);
343 if (pnp_can_read(dev
))
344 dev
->protocol
->get(dev
);
345 mutex_unlock(&pnp_res_mutex
);
348 if (!strnicmp(buf
, "set", 3)) {
352 pnp_init_resources(dev
);
353 mutex_lock(&pnp_res_mutex
);
355 buf
= skip_spaces(buf
);
356 if (!strnicmp(buf
, "io", 2)) {
357 buf
= skip_spaces(buf
+ 2);
358 start
= simple_strtoul(buf
, &buf
, 0);
359 buf
= skip_spaces(buf
);
361 buf
= skip_spaces(buf
+ 1);
362 end
= simple_strtoul(buf
, &buf
, 0);
365 pnp_add_io_resource(dev
, start
, end
, 0);
368 if (!strnicmp(buf
, "mem", 3)) {
369 buf
= skip_spaces(buf
+ 3);
370 start
= simple_strtoul(buf
, &buf
, 0);
371 buf
= skip_spaces(buf
);
373 buf
= skip_spaces(buf
+ 1);
374 end
= simple_strtoul(buf
, &buf
, 0);
377 pnp_add_mem_resource(dev
, start
, end
, 0);
380 if (!strnicmp(buf
, "irq", 3)) {
381 buf
= skip_spaces(buf
+ 3);
382 start
= simple_strtoul(buf
, &buf
, 0);
383 pnp_add_irq_resource(dev
, start
, 0);
386 if (!strnicmp(buf
, "dma", 3)) {
387 buf
= skip_spaces(buf
+ 3);
388 start
= simple_strtoul(buf
, &buf
, 0);
389 pnp_add_dma_resource(dev
, start
, 0);
394 mutex_unlock(&pnp_res_mutex
);
404 static ssize_t
pnp_show_current_ids(struct device
*dmdev
,
405 struct device_attribute
*attr
, char *buf
)
408 struct pnp_dev
*dev
= to_pnp_dev(dmdev
);
409 struct pnp_id
*pos
= dev
->id
;
412 str
+= sprintf(str
, "%s\n", pos
->id
);
418 struct device_attribute pnp_interface_attrs
[] = {
419 __ATTR(resources
, S_IRUGO
| S_IWUSR
,
420 pnp_show_current_resources
,
421 pnp_set_current_resources
),
422 __ATTR(options
, S_IRUGO
, pnp_show_options
, NULL
),
423 __ATTR(id
, S_IRUGO
, pnp_show_current_ids
, NULL
),