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@suse.cz>
5 * Copyright 2002 Adam Belay <ambx1@neo.rr.com>
10 #include <linux/string.h>
11 #include <linux/errno.h>
12 #include <linux/list.h>
13 #include <linux/types.h>
14 #include <linux/stat.h>
15 #include <linux/ctype.h>
16 #include <linux/slab.h>
17 #include <asm/uaccess.h>
21 struct pnp_info_buffer
{
22 char *buffer
; /* pointer to begin of buffer */
23 char *curr
; /* current position in buffer */
24 unsigned long size
; /* current size */
25 unsigned long len
; /* total length of buffer */
26 int stop
; /* stop flag */
27 int error
; /* error code */
30 typedef struct pnp_info_buffer pnp_info_buffer_t
;
32 static int pnp_printf(pnp_info_buffer_t
* buffer
, char *fmt
,...)
37 if (buffer
->stop
|| buffer
->error
)
40 res
= vsnprintf(buffer
->curr
, buffer
->len
- buffer
->size
, fmt
, args
);
42 if (buffer
->size
+ res
>= buffer
->len
) {
51 static void pnp_print_port(pnp_info_buffer_t
*buffer
, char *space
, struct pnp_port
*port
)
53 pnp_printf(buffer
, "%sport 0x%x-0x%x, align 0x%x, size 0x%x, %i-bit address decoding\n",
54 space
, port
->min
, port
->max
, port
->align
? (port
->align
-1) : 0, port
->size
,
55 port
->flags
& PNP_PORT_FLAG_16BITADDR
? 16 : 10);
58 static void pnp_print_irq(pnp_info_buffer_t
*buffer
, char *space
, struct pnp_irq
*irq
)
62 pnp_printf(buffer
, "%sirq ", space
);
63 for (i
= 0; i
< PNP_IRQ_NR
; i
++)
64 if (test_bit(i
, irq
->map
)) {
66 pnp_printf(buffer
, ",");
71 pnp_printf(buffer
, "2/9");
73 pnp_printf(buffer
, "%i", i
);
75 if (bitmap_empty(irq
->map
, PNP_IRQ_NR
))
76 pnp_printf(buffer
, "<none>");
77 if (irq
->flags
& IORESOURCE_IRQ_HIGHEDGE
)
78 pnp_printf(buffer
, " High-Edge");
79 if (irq
->flags
& IORESOURCE_IRQ_LOWEDGE
)
80 pnp_printf(buffer
, " Low-Edge");
81 if (irq
->flags
& IORESOURCE_IRQ_HIGHLEVEL
)
82 pnp_printf(buffer
, " High-Level");
83 if (irq
->flags
& IORESOURCE_IRQ_LOWLEVEL
)
84 pnp_printf(buffer
, " Low-Level");
85 pnp_printf(buffer
, "\n");
88 static void pnp_print_dma(pnp_info_buffer_t
*buffer
, char *space
, struct pnp_dma
*dma
)
93 pnp_printf(buffer
, "%sdma ", space
);
94 for (i
= 0; i
< 8; i
++)
95 if (dma
->map
& (1<<i
)) {
97 pnp_printf(buffer
, ",");
101 pnp_printf(buffer
, "%i", i
);
104 pnp_printf(buffer
, "<none>");
105 switch (dma
->flags
& IORESOURCE_DMA_TYPE_MASK
) {
106 case IORESOURCE_DMA_8BIT
:
109 case IORESOURCE_DMA_8AND16BIT
:
115 pnp_printf(buffer
, " %s", s
);
116 if (dma
->flags
& IORESOURCE_DMA_MASTER
)
117 pnp_printf(buffer
, " master");
118 if (dma
->flags
& IORESOURCE_DMA_BYTE
)
119 pnp_printf(buffer
, " byte-count");
120 if (dma
->flags
& IORESOURCE_DMA_WORD
)
121 pnp_printf(buffer
, " word-count");
122 switch (dma
->flags
& IORESOURCE_DMA_SPEED_MASK
) {
123 case IORESOURCE_DMA_TYPEA
:
126 case IORESOURCE_DMA_TYPEB
:
129 case IORESOURCE_DMA_TYPEF
:
136 pnp_printf(buffer
, " %s\n", s
);
139 static void pnp_print_mem(pnp_info_buffer_t
*buffer
, char *space
, struct pnp_mem
*mem
)
143 pnp_printf(buffer
, "%sMemory 0x%x-0x%x, align 0x%x, size 0x%x",
144 space
, mem
->min
, mem
->max
, mem
->align
, mem
->size
);
145 if (mem
->flags
& IORESOURCE_MEM_WRITEABLE
)
146 pnp_printf(buffer
, ", writeable");
147 if (mem
->flags
& IORESOURCE_MEM_CACHEABLE
)
148 pnp_printf(buffer
, ", cacheable");
149 if (mem
->flags
& IORESOURCE_MEM_RANGELENGTH
)
150 pnp_printf(buffer
, ", range-length");
151 if (mem
->flags
& IORESOURCE_MEM_SHADOWABLE
)
152 pnp_printf(buffer
, ", shadowable");
153 if (mem
->flags
& IORESOURCE_MEM_EXPANSIONROM
)
154 pnp_printf(buffer
, ", expansion ROM");
155 switch (mem
->flags
& IORESOURCE_MEM_TYPE_MASK
) {
156 case IORESOURCE_MEM_8BIT
:
159 case IORESOURCE_MEM_8AND16BIT
:
162 case IORESOURCE_MEM_32BIT
:
168 pnp_printf(buffer
, ", %s\n", s
);
171 static void pnp_print_option(pnp_info_buffer_t
*buffer
, char *space
,
172 struct pnp_option
*option
, int dep
)
175 struct pnp_port
*port
;
181 switch (option
->priority
) {
182 case PNP_RES_PRIORITY_PREFERRED
:
185 case PNP_RES_PRIORITY_ACCEPTABLE
:
188 case PNP_RES_PRIORITY_FUNCTIONAL
:
194 pnp_printf(buffer
, "Dependent: %02i - Priority %s\n",dep
, s
);
197 for (port
= option
->port
; port
; port
= port
->next
)
198 pnp_print_port(buffer
, space
, port
);
199 for (irq
= option
->irq
; irq
; irq
= irq
->next
)
200 pnp_print_irq(buffer
, space
, irq
);
201 for (dma
= option
->dma
; dma
; dma
= dma
->next
)
202 pnp_print_dma(buffer
, space
, dma
);
203 for (mem
= option
->mem
; mem
; mem
= mem
->next
)
204 pnp_print_mem(buffer
, space
, mem
);
208 static ssize_t
pnp_show_options(struct device
*dmdev
, struct device_attribute
*attr
, char *buf
)
210 struct pnp_dev
*dev
= to_pnp_dev(dmdev
);
211 struct pnp_option
* independent
= dev
->independent
;
212 struct pnp_option
* dependent
= dev
->dependent
;
215 pnp_info_buffer_t
*buffer
= (pnp_info_buffer_t
*)
216 pnp_alloc(sizeof(pnp_info_buffer_t
));
220 buffer
->len
= PAGE_SIZE
;
221 buffer
->buffer
= buf
;
222 buffer
->curr
= buffer
->buffer
;
224 pnp_print_option(buffer
, "", independent
, 0);
227 pnp_print_option(buffer
, " ", dependent
, dep
);
228 dependent
= dependent
->next
;
231 ret
= (buffer
->curr
- buf
);
236 static DEVICE_ATTR(options
,S_IRUGO
,pnp_show_options
,NULL
);
239 static ssize_t
pnp_show_current_resources(struct device
*dmdev
, struct device_attribute
*attr
, char *buf
)
241 struct pnp_dev
*dev
= to_pnp_dev(dmdev
);
243 pnp_info_buffer_t
*buffer
;
248 buffer
= (pnp_info_buffer_t
*) pnp_alloc(sizeof(pnp_info_buffer_t
));
251 buffer
->len
= PAGE_SIZE
;
252 buffer
->buffer
= buf
;
253 buffer
->curr
= buffer
->buffer
;
255 pnp_printf(buffer
,"state = ");
257 pnp_printf(buffer
,"active\n");
259 pnp_printf(buffer
,"disabled\n");
261 for (i
= 0; i
< PNP_MAX_PORT
; i
++) {
262 if (pnp_port_valid(dev
, i
)) {
263 pnp_printf(buffer
,"io");
264 if (pnp_port_flags(dev
, i
) & IORESOURCE_DISABLED
)
265 pnp_printf(buffer
," disabled\n");
267 pnp_printf(buffer
," 0x%llx-0x%llx\n",
268 (unsigned long long)pnp_port_start(dev
, i
),
269 (unsigned long long)pnp_port_end(dev
, i
));
272 for (i
= 0; i
< PNP_MAX_MEM
; i
++) {
273 if (pnp_mem_valid(dev
, i
)) {
274 pnp_printf(buffer
,"mem");
275 if (pnp_mem_flags(dev
, i
) & IORESOURCE_DISABLED
)
276 pnp_printf(buffer
," disabled\n");
278 pnp_printf(buffer
," 0x%llx-0x%llx\n",
279 (unsigned long long)pnp_mem_start(dev
, i
),
280 (unsigned long long)pnp_mem_end(dev
, i
));
283 for (i
= 0; i
< PNP_MAX_IRQ
; i
++) {
284 if (pnp_irq_valid(dev
, i
)) {
285 pnp_printf(buffer
,"irq");
286 if (pnp_irq_flags(dev
, i
) & IORESOURCE_DISABLED
)
287 pnp_printf(buffer
," disabled\n");
289 pnp_printf(buffer
," %lld\n",
290 (unsigned long long)pnp_irq(dev
, i
));
293 for (i
= 0; i
< PNP_MAX_DMA
; i
++) {
294 if (pnp_dma_valid(dev
, i
)) {
295 pnp_printf(buffer
,"dma");
296 if (pnp_dma_flags(dev
, i
) & IORESOURCE_DISABLED
)
297 pnp_printf(buffer
," disabled\n");
299 pnp_printf(buffer
," %lld\n",
300 (unsigned long long)pnp_dma(dev
, i
));
303 ret
= (buffer
->curr
- buf
);
308 extern struct semaphore pnp_res_mutex
;
311 pnp_set_current_resources(struct device
* dmdev
, struct device_attribute
*attr
, const char * ubuf
, size_t count
)
313 struct pnp_dev
*dev
= to_pnp_dev(dmdev
);
314 char *buf
= (void *)ubuf
;
317 if (dev
->status
& PNP_ATTACHED
) {
319 pnp_info("Device %s cannot be configured because it is in use.", dev
->dev
.bus_id
);
323 while (isspace(*buf
))
325 if (!strnicmp(buf
,"disable",7)) {
326 retval
= pnp_disable_dev(dev
);
329 if (!strnicmp(buf
,"activate",8)) {
330 retval
= pnp_activate_dev(dev
);
333 if (!strnicmp(buf
,"fill",4)) {
336 retval
= pnp_auto_config_dev(dev
);
339 if (!strnicmp(buf
,"auto",4)) {
342 pnp_init_resource_table(&dev
->res
);
343 retval
= pnp_auto_config_dev(dev
);
346 if (!strnicmp(buf
,"clear",5)) {
349 pnp_init_resource_table(&dev
->res
);
352 if (!strnicmp(buf
,"get",3)) {
353 down(&pnp_res_mutex
);
354 if (pnp_can_read(dev
))
355 dev
->protocol
->get(dev
, &dev
->res
);
359 if (!strnicmp(buf
,"set",3)) {
360 int nport
= 0, nmem
= 0, nirq
= 0, ndma
= 0;
364 pnp_init_resource_table(&dev
->res
);
365 down(&pnp_res_mutex
);
367 while (isspace(*buf
))
369 if (!strnicmp(buf
,"io",2)) {
371 while (isspace(*buf
))
373 dev
->res
.port_resource
[nport
].start
= simple_strtoul(buf
,&buf
,0);
374 while (isspace(*buf
))
378 while (isspace(*buf
))
380 dev
->res
.port_resource
[nport
].end
= simple_strtoul(buf
,&buf
,0);
382 dev
->res
.port_resource
[nport
].end
= dev
->res
.port_resource
[nport
].start
;
383 dev
->res
.port_resource
[nport
].flags
= IORESOURCE_IO
;
385 if (nport
>= PNP_MAX_PORT
)
389 if (!strnicmp(buf
,"mem",3)) {
391 while (isspace(*buf
))
393 dev
->res
.mem_resource
[nmem
].start
= simple_strtoul(buf
,&buf
,0);
394 while (isspace(*buf
))
398 while (isspace(*buf
))
400 dev
->res
.mem_resource
[nmem
].end
= simple_strtoul(buf
,&buf
,0);
402 dev
->res
.mem_resource
[nmem
].end
= dev
->res
.mem_resource
[nmem
].start
;
403 dev
->res
.mem_resource
[nmem
].flags
= IORESOURCE_MEM
;
405 if (nmem
>= PNP_MAX_MEM
)
409 if (!strnicmp(buf
,"irq",3)) {
411 while (isspace(*buf
))
413 dev
->res
.irq_resource
[nirq
].start
=
414 dev
->res
.irq_resource
[nirq
].end
= simple_strtoul(buf
,&buf
,0);
415 dev
->res
.irq_resource
[nirq
].flags
= IORESOURCE_IRQ
;
417 if (nirq
>= PNP_MAX_IRQ
)
421 if (!strnicmp(buf
,"dma",3)) {
423 while (isspace(*buf
))
425 dev
->res
.dma_resource
[ndma
].start
=
426 dev
->res
.dma_resource
[ndma
].end
= simple_strtoul(buf
,&buf
,0);
427 dev
->res
.dma_resource
[ndma
].flags
= IORESOURCE_DMA
;
429 if (ndma
>= PNP_MAX_DMA
)
444 static DEVICE_ATTR(resources
,S_IRUGO
| S_IWUSR
,
445 pnp_show_current_resources
,pnp_set_current_resources
);
447 static ssize_t
pnp_show_current_ids(struct device
*dmdev
, struct device_attribute
*attr
, char *buf
)
450 struct pnp_dev
*dev
= to_pnp_dev(dmdev
);
451 struct pnp_id
* pos
= dev
->id
;
454 str
+= sprintf(str
,"%s\n", pos
->id
);
460 static DEVICE_ATTR(id
,S_IRUGO
,pnp_show_current_ids
,NULL
);
462 int pnp_interface_attach_device(struct pnp_dev
*dev
)
464 device_create_file(&dev
->dev
,&dev_attr_options
);
465 device_create_file(&dev
->dev
,&dev_attr_resources
);
466 device_create_file(&dev
->dev
,&dev_attr_id
);