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/pnp.h>
16 #include <linux/stat.h>
17 #include <linux/ctype.h>
18 #include <linux/slab.h>
19 #include <linux/mutex.h>
21 #include <asm/uaccess.h>
25 struct pnp_info_buffer
{
26 char *buffer
; /* pointer to begin of buffer */
27 char *curr
; /* current position in buffer */
28 unsigned long size
; /* current size */
29 unsigned long len
; /* total length of buffer */
30 int stop
; /* stop flag */
31 int error
; /* error code */
34 typedef struct pnp_info_buffer pnp_info_buffer_t
;
36 static int pnp_printf(pnp_info_buffer_t
* buffer
, char *fmt
, ...)
41 if (buffer
->stop
|| buffer
->error
)
44 res
= vsnprintf(buffer
->curr
, buffer
->len
- buffer
->size
, fmt
, args
);
46 if (buffer
->size
+ res
>= buffer
->len
) {
55 static void pnp_print_port(pnp_info_buffer_t
* buffer
, char *space
,
56 struct pnp_port
*port
)
58 pnp_printf(buffer
, "%sport %#llx-%#llx, align %#llx, size %#llx, "
59 "%i-bit address decoding\n", space
,
60 (unsigned long long) port
->min
,
61 (unsigned long long) port
->max
,
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);
67 static void pnp_print_irq(pnp_info_buffer_t
* buffer
, char *space
,
72 pnp_printf(buffer
, "%sirq ", space
);
73 for (i
= 0; i
< PNP_IRQ_NR
; i
++)
74 if (test_bit(i
, irq
->map
.bits
)) {
76 pnp_printf(buffer
, ",");
81 pnp_printf(buffer
, "2/9");
83 pnp_printf(buffer
, "%i", i
);
85 if (bitmap_empty(irq
->map
.bits
, PNP_IRQ_NR
))
86 pnp_printf(buffer
, "<none>");
87 if (irq
->flags
& IORESOURCE_IRQ_HIGHEDGE
)
88 pnp_printf(buffer
, " High-Edge");
89 if (irq
->flags
& IORESOURCE_IRQ_LOWEDGE
)
90 pnp_printf(buffer
, " Low-Edge");
91 if (irq
->flags
& IORESOURCE_IRQ_HIGHLEVEL
)
92 pnp_printf(buffer
, " High-Level");
93 if (irq
->flags
& IORESOURCE_IRQ_LOWLEVEL
)
94 pnp_printf(buffer
, " Low-Level");
95 if (irq
->flags
& IORESOURCE_IRQ_OPTIONAL
)
96 pnp_printf(buffer
, " (optional)");
97 pnp_printf(buffer
, "\n");
100 static void pnp_print_dma(pnp_info_buffer_t
* buffer
, char *space
,
106 pnp_printf(buffer
, "%sdma ", space
);
107 for (i
= 0; i
< 8; i
++)
108 if (dma
->map
& (1 << i
)) {
110 pnp_printf(buffer
, ",");
114 pnp_printf(buffer
, "%i", i
);
117 pnp_printf(buffer
, "<none>");
118 switch (dma
->flags
& IORESOURCE_DMA_TYPE_MASK
) {
119 case IORESOURCE_DMA_8BIT
:
122 case IORESOURCE_DMA_8AND16BIT
:
128 pnp_printf(buffer
, " %s", s
);
129 if (dma
->flags
& IORESOURCE_DMA_MASTER
)
130 pnp_printf(buffer
, " master");
131 if (dma
->flags
& IORESOURCE_DMA_BYTE
)
132 pnp_printf(buffer
, " byte-count");
133 if (dma
->flags
& IORESOURCE_DMA_WORD
)
134 pnp_printf(buffer
, " word-count");
135 switch (dma
->flags
& IORESOURCE_DMA_SPEED_MASK
) {
136 case IORESOURCE_DMA_TYPEA
:
139 case IORESOURCE_DMA_TYPEB
:
142 case IORESOURCE_DMA_TYPEF
:
149 pnp_printf(buffer
, " %s\n", s
);
152 static void pnp_print_mem(pnp_info_buffer_t
* buffer
, char *space
,
157 pnp_printf(buffer
, "%sMemory %#llx-%#llx, align %#llx, size %#llx",
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
);
162 if (mem
->flags
& IORESOURCE_MEM_WRITEABLE
)
163 pnp_printf(buffer
, ", writeable");
164 if (mem
->flags
& IORESOURCE_MEM_CACHEABLE
)
165 pnp_printf(buffer
, ", cacheable");
166 if (mem
->flags
& IORESOURCE_MEM_RANGELENGTH
)
167 pnp_printf(buffer
, ", range-length");
168 if (mem
->flags
& IORESOURCE_MEM_SHADOWABLE
)
169 pnp_printf(buffer
, ", shadowable");
170 if (mem
->flags
& IORESOURCE_MEM_EXPANSIONROM
)
171 pnp_printf(buffer
, ", expansion ROM");
172 switch (mem
->flags
& IORESOURCE_MEM_TYPE_MASK
) {
173 case IORESOURCE_MEM_8BIT
:
176 case IORESOURCE_MEM_8AND16BIT
:
179 case IORESOURCE_MEM_32BIT
:
185 pnp_printf(buffer
, ", %s\n", s
);
188 static void pnp_print_option(pnp_info_buffer_t
* buffer
, char *space
,
189 struct pnp_option
*option
)
191 switch (option
->type
) {
193 pnp_print_port(buffer
, space
, &option
->u
.port
);
196 pnp_print_mem(buffer
, space
, &option
->u
.mem
);
199 pnp_print_irq(buffer
, space
, &option
->u
.irq
);
202 pnp_print_dma(buffer
, space
, &option
->u
.dma
);
207 static ssize_t
pnp_show_options(struct device
*dmdev
,
208 struct device_attribute
*attr
, char *buf
)
210 struct pnp_dev
*dev
= to_pnp_dev(dmdev
);
211 pnp_info_buffer_t
*buffer
;
212 struct pnp_option
*option
;
213 int ret
, dep
= 0, set
= 0;
216 buffer
= pnp_alloc(sizeof(pnp_info_buffer_t
));
220 buffer
->len
= PAGE_SIZE
;
221 buffer
->buffer
= buf
;
222 buffer
->curr
= buffer
->buffer
;
224 list_for_each_entry(option
, &dev
->options
, list
) {
225 if (pnp_option_is_dependent(option
)) {
227 if (!dep
|| pnp_option_set(option
) != set
) {
228 set
= pnp_option_set(option
);
230 pnp_printf(buffer
, "Dependent: %02i - "
231 "Priority %s\n", set
,
232 pnp_option_priority_name(option
));
238 pnp_print_option(buffer
, indent
, option
);
241 ret
= (buffer
->curr
- buf
);
246 static DEVICE_ATTR(options
, S_IRUGO
, pnp_show_options
, NULL
);
248 static ssize_t
pnp_show_current_resources(struct device
*dmdev
,
249 struct device_attribute
*attr
,
252 struct pnp_dev
*dev
= to_pnp_dev(dmdev
);
253 pnp_info_buffer_t
*buffer
;
254 struct pnp_resource
*pnp_res
;
255 struct resource
*res
;
261 buffer
= pnp_alloc(sizeof(pnp_info_buffer_t
));
265 buffer
->len
= PAGE_SIZE
;
266 buffer
->buffer
= buf
;
267 buffer
->curr
= buffer
->buffer
;
269 pnp_printf(buffer
, "state = %s\n", dev
->active
? "active" : "disabled");
271 list_for_each_entry(pnp_res
, &dev
->resources
, list
) {
274 pnp_printf(buffer
, pnp_resource_type_name(res
));
276 if (res
->flags
& IORESOURCE_DISABLED
) {
277 pnp_printf(buffer
, " disabled\n");
281 switch (pnp_resource_type(res
)) {
284 pnp_printf(buffer
, " %#llx-%#llx\n",
285 (unsigned long long) res
->start
,
286 (unsigned long long) res
->end
);
290 pnp_printf(buffer
, " %lld\n",
291 (unsigned long long) res
->start
);
296 ret
= (buffer
->curr
- buf
);
301 static ssize_t
pnp_set_current_resources(struct device
*dmdev
,
302 struct device_attribute
*attr
,
303 const char *ubuf
, size_t count
)
305 struct pnp_dev
*dev
= to_pnp_dev(dmdev
);
306 char *buf
= (void *)ubuf
;
308 resource_size_t start
, end
;
310 if (dev
->status
& PNP_ATTACHED
) {
312 dev_info(&dev
->dev
, "in use; can't configure\n");
316 while (isspace(*buf
))
318 if (!strnicmp(buf
, "disable", 7)) {
319 retval
= pnp_disable_dev(dev
);
322 if (!strnicmp(buf
, "activate", 8)) {
323 retval
= pnp_activate_dev(dev
);
326 if (!strnicmp(buf
, "fill", 4)) {
329 retval
= pnp_auto_config_dev(dev
);
332 if (!strnicmp(buf
, "auto", 4)) {
335 pnp_init_resources(dev
);
336 retval
= pnp_auto_config_dev(dev
);
339 if (!strnicmp(buf
, "clear", 5)) {
342 pnp_init_resources(dev
);
345 if (!strnicmp(buf
, "get", 3)) {
346 mutex_lock(&pnp_res_mutex
);
347 if (pnp_can_read(dev
))
348 dev
->protocol
->get(dev
);
349 mutex_unlock(&pnp_res_mutex
);
352 if (!strnicmp(buf
, "set", 3)) {
356 pnp_init_resources(dev
);
357 mutex_lock(&pnp_res_mutex
);
359 while (isspace(*buf
))
361 if (!strnicmp(buf
, "io", 2)) {
363 while (isspace(*buf
))
365 start
= simple_strtoul(buf
, &buf
, 0);
366 while (isspace(*buf
))
370 while (isspace(*buf
))
372 end
= simple_strtoul(buf
, &buf
, 0);
375 pnp_add_io_resource(dev
, start
, end
, 0);
378 if (!strnicmp(buf
, "mem", 3)) {
380 while (isspace(*buf
))
382 start
= simple_strtoul(buf
, &buf
, 0);
383 while (isspace(*buf
))
387 while (isspace(*buf
))
389 end
= simple_strtoul(buf
, &buf
, 0);
392 pnp_add_mem_resource(dev
, start
, end
, 0);
395 if (!strnicmp(buf
, "irq", 3)) {
397 while (isspace(*buf
))
399 start
= simple_strtoul(buf
, &buf
, 0);
400 pnp_add_irq_resource(dev
, start
, 0);
403 if (!strnicmp(buf
, "dma", 3)) {
405 while (isspace(*buf
))
407 start
= simple_strtoul(buf
, &buf
, 0);
408 pnp_add_dma_resource(dev
, start
, 0);
413 mutex_unlock(&pnp_res_mutex
);
423 static DEVICE_ATTR(resources
, S_IRUGO
| S_IWUSR
,
424 pnp_show_current_resources
, pnp_set_current_resources
);
426 static ssize_t
pnp_show_current_ids(struct device
*dmdev
,
427 struct device_attribute
*attr
, char *buf
)
430 struct pnp_dev
*dev
= to_pnp_dev(dmdev
);
431 struct pnp_id
*pos
= dev
->id
;
434 str
+= sprintf(str
, "%s\n", pos
->id
);
440 static DEVICE_ATTR(id
, S_IRUGO
, pnp_show_current_ids
, NULL
);
442 int pnp_interface_attach_device(struct pnp_dev
*dev
)
444 int rc
= device_create_file(&dev
->dev
, &dev_attr_options
);
448 rc
= device_create_file(&dev
->dev
, &dev_attr_resources
);
451 rc
= device_create_file(&dev
->dev
, &dev_attr_id
);
458 device_remove_file(&dev
->dev
, &dev_attr_resources
);
460 device_remove_file(&dev
->dev
, &dev_attr_options
);