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,
52 struct pnp_port *port)
55 "%sport 0x%x-0x%x, align 0x%x, size 0x%x, %i-bit address decoding\n",
56 space, port->min, port->max,
57 port->align ? (port->align - 1) : 0, port->size,
58 port->flags & PNP_PORT_FLAG_16BITADDR ? 16 : 10);
61 static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space,
66 pnp_printf(buffer, "%sirq ", space);
67 for (i = 0; i < PNP_IRQ_NR; i++)
68 if (test_bit(i, irq->map)) {
70 pnp_printf(buffer, ",");
75 pnp_printf(buffer, "2/9");
77 pnp_printf(buffer, "%i", i);
79 if (bitmap_empty(irq->map, PNP_IRQ_NR))
80 pnp_printf(buffer, "<none>");
81 if (irq->flags & IORESOURCE_IRQ_HIGHEDGE)
82 pnp_printf(buffer, " High-Edge");
83 if (irq->flags & IORESOURCE_IRQ_LOWEDGE)
84 pnp_printf(buffer, " Low-Edge");
85 if (irq->flags & IORESOURCE_IRQ_HIGHLEVEL)
86 pnp_printf(buffer, " High-Level");
87 if (irq->flags & IORESOURCE_IRQ_LOWLEVEL)
88 pnp_printf(buffer, " Low-Level");
89 pnp_printf(buffer, "\n");
92 static void pnp_print_dma(pnp_info_buffer_t * buffer, char *space,
98 pnp_printf(buffer, "%sdma ", space);
99 for (i = 0; i < 8; i++)
100 if (dma->map & (1 << i)) {
102 pnp_printf(buffer, ",");
106 pnp_printf(buffer, "%i", i);
109 pnp_printf(buffer, "<none>");
110 switch (dma->flags & IORESOURCE_DMA_TYPE_MASK) {
111 case IORESOURCE_DMA_8BIT:
114 case IORESOURCE_DMA_8AND16BIT:
120 pnp_printf(buffer, " %s", s);
121 if (dma->flags & IORESOURCE_DMA_MASTER)
122 pnp_printf(buffer, " master");
123 if (dma->flags & IORESOURCE_DMA_BYTE)
124 pnp_printf(buffer, " byte-count");
125 if (dma->flags & IORESOURCE_DMA_WORD)
126 pnp_printf(buffer, " word-count");
127 switch (dma->flags & IORESOURCE_DMA_SPEED_MASK) {
128 case IORESOURCE_DMA_TYPEA:
131 case IORESOURCE_DMA_TYPEB:
134 case IORESOURCE_DMA_TYPEF:
141 pnp_printf(buffer, " %s\n", s);
144 static void pnp_print_mem(pnp_info_buffer_t * buffer, char *space,
149 pnp_printf(buffer, "%sMemory 0x%x-0x%x, align 0x%x, size 0x%x",
150 space, mem->min, mem->max, mem->align, mem->size);
151 if (mem->flags & IORESOURCE_MEM_WRITEABLE)
152 pnp_printf(buffer, ", writeable");
153 if (mem->flags & IORESOURCE_MEM_CACHEABLE)
154 pnp_printf(buffer, ", cacheable");
155 if (mem->flags & IORESOURCE_MEM_RANGELENGTH)
156 pnp_printf(buffer, ", range-length");
157 if (mem->flags & IORESOURCE_MEM_SHADOWABLE)
158 pnp_printf(buffer, ", shadowable");
159 if (mem->flags & IORESOURCE_MEM_EXPANSIONROM)
160 pnp_printf(buffer, ", expansion ROM");
161 switch (mem->flags & IORESOURCE_MEM_TYPE_MASK) {
162 case IORESOURCE_MEM_8BIT:
165 case IORESOURCE_MEM_8AND16BIT:
168 case IORESOURCE_MEM_32BIT:
174 pnp_printf(buffer, ", %s\n", s);
177 static void pnp_print_option(pnp_info_buffer_t * buffer, char *space,
178 struct pnp_option *option, int dep)
181 struct pnp_port *port;
187 switch (option->priority) {
188 case PNP_RES_PRIORITY_PREFERRED:
191 case PNP_RES_PRIORITY_ACCEPTABLE:
194 case PNP_RES_PRIORITY_FUNCTIONAL:
200 pnp_printf(buffer, "Dependent: %02i - Priority %s\n", dep, s);
203 for (port = option->port; port; port = port->next)
204 pnp_print_port(buffer, space, port);
205 for (irq = option->irq; irq; irq = irq->next)
206 pnp_print_irq(buffer, space, irq);
207 for (dma = option->dma; dma; dma = dma->next)
208 pnp_print_dma(buffer, space, dma);
209 for (mem = option->mem; mem; mem = mem->next)
210 pnp_print_mem(buffer, space, mem);
213 static ssize_t pnp_show_options(struct device *dmdev,
214 struct device_attribute *attr, char *buf)
216 struct pnp_dev *dev = to_pnp_dev(dmdev);
217 struct pnp_option *independent = dev->independent;
218 struct pnp_option *dependent = dev->dependent;
221 pnp_info_buffer_t *buffer = (pnp_info_buffer_t *)
222 pnp_alloc(sizeof(pnp_info_buffer_t));
226 buffer->len = PAGE_SIZE;
227 buffer->buffer = buf;
228 buffer->curr = buffer->buffer;
230 pnp_print_option(buffer, "", independent, 0);
233 pnp_print_option(buffer, " ", dependent, dep);
234 dependent = dependent->next;
237 ret = (buffer->curr - buf);
242 static DEVICE_ATTR(options, S_IRUGO, pnp_show_options, NULL);
244 static ssize_t pnp_show_current_resources(struct device *dmdev,
245 struct device_attribute *attr,
248 struct pnp_dev *dev = to_pnp_dev(dmdev);
250 pnp_info_buffer_t *buffer;
255 buffer = (pnp_info_buffer_t *) pnp_alloc(sizeof(pnp_info_buffer_t));
258 buffer->len = PAGE_SIZE;
259 buffer->buffer = buf;
260 buffer->curr = buffer->buffer;
262 pnp_printf(buffer, "state = ");
264 pnp_printf(buffer, "active\n");
266 pnp_printf(buffer, "disabled\n");
268 for (i = 0; i < PNP_MAX_PORT; i++) {
269 if (pnp_port_valid(dev, i)) {
270 pnp_printf(buffer, "io");
271 if (pnp_port_flags(dev, i) & IORESOURCE_DISABLED)
272 pnp_printf(buffer, " disabled\n");
274 pnp_printf(buffer, " 0x%llx-0x%llx\n",
276 pnp_port_start(dev, i),
277 (unsigned long long)pnp_port_end(dev,
281 for (i = 0; i < PNP_MAX_MEM; i++) {
282 if (pnp_mem_valid(dev, i)) {
283 pnp_printf(buffer, "mem");
284 if (pnp_mem_flags(dev, i) & IORESOURCE_DISABLED)
285 pnp_printf(buffer, " disabled\n");
287 pnp_printf(buffer, " 0x%llx-0x%llx\n",
289 pnp_mem_start(dev, i),
290 (unsigned long long)pnp_mem_end(dev,
294 for (i = 0; i < PNP_MAX_IRQ; i++) {
295 if (pnp_irq_valid(dev, i)) {
296 pnp_printf(buffer, "irq");
297 if (pnp_irq_flags(dev, i) & IORESOURCE_DISABLED)
298 pnp_printf(buffer, " disabled\n");
300 pnp_printf(buffer, " %lld\n",
301 (unsigned long long)pnp_irq(dev, i));
304 for (i = 0; i < PNP_MAX_DMA; i++) {
305 if (pnp_dma_valid(dev, i)) {
306 pnp_printf(buffer, "dma");
307 if (pnp_dma_flags(dev, i) & IORESOURCE_DISABLED)
308 pnp_printf(buffer, " disabled\n");
310 pnp_printf(buffer, " %lld\n",
311 (unsigned long long)pnp_dma(dev, i));
314 ret = (buffer->curr - buf);
319 extern struct semaphore pnp_res_mutex;
322 pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
323 const char *ubuf, size_t count)
325 struct pnp_dev *dev = to_pnp_dev(dmdev);
326 char *buf = (void *)ubuf;
329 if (dev->status & PNP_ATTACHED) {
331 pnp_info("Device %s cannot be configured because it is in use.",
336 while (isspace(*buf))
338 if (!strnicmp(buf, "disable", 7)) {
339 retval = pnp_disable_dev(dev);
342 if (!strnicmp(buf, "activate", 8)) {
343 retval = pnp_activate_dev(dev);
346 if (!strnicmp(buf, "fill", 4)) {
349 retval = pnp_auto_config_dev(dev);
352 if (!strnicmp(buf, "auto", 4)) {
355 pnp_init_resource_table(&dev->res);
356 retval = pnp_auto_config_dev(dev);
359 if (!strnicmp(buf, "clear", 5)) {
362 pnp_init_resource_table(&dev->res);
365 if (!strnicmp(buf, "get", 3)) {
366 down(&pnp_res_mutex);
367 if (pnp_can_read(dev))
368 dev->protocol->get(dev, &dev->res);
372 if (!strnicmp(buf, "set", 3)) {
373 int nport = 0, nmem = 0, nirq = 0, ndma = 0;
377 pnp_init_resource_table(&dev->res);
378 down(&pnp_res_mutex);
380 while (isspace(*buf))
382 if (!strnicmp(buf, "io", 2)) {
384 while (isspace(*buf))
386 dev->res.port_resource[nport].start =
387 simple_strtoul(buf, &buf, 0);
388 while (isspace(*buf))
392 while (isspace(*buf))
394 dev->res.port_resource[nport].end =
395 simple_strtoul(buf, &buf, 0);
397 dev->res.port_resource[nport].end =
398 dev->res.port_resource[nport].start;
399 dev->res.port_resource[nport].flags =
402 if (nport >= PNP_MAX_PORT)
406 if (!strnicmp(buf, "mem", 3)) {
408 while (isspace(*buf))
410 dev->res.mem_resource[nmem].start =
411 simple_strtoul(buf, &buf, 0);
412 while (isspace(*buf))
416 while (isspace(*buf))
418 dev->res.mem_resource[nmem].end =
419 simple_strtoul(buf, &buf, 0);
421 dev->res.mem_resource[nmem].end =
422 dev->res.mem_resource[nmem].start;
423 dev->res.mem_resource[nmem].flags =
426 if (nmem >= PNP_MAX_MEM)
430 if (!strnicmp(buf, "irq", 3)) {
432 while (isspace(*buf))
434 dev->res.irq_resource[nirq].start =
435 dev->res.irq_resource[nirq].end =
436 simple_strtoul(buf, &buf, 0);
437 dev->res.irq_resource[nirq].flags =
440 if (nirq >= PNP_MAX_IRQ)
444 if (!strnicmp(buf, "dma", 3)) {
446 while (isspace(*buf))
448 dev->res.dma_resource[ndma].start =
449 dev->res.dma_resource[ndma].end =
450 simple_strtoul(buf, &buf, 0);
451 dev->res.dma_resource[ndma].flags =
454 if (ndma >= PNP_MAX_DMA)
469 static DEVICE_ATTR(resources, S_IRUGO | S_IWUSR,
470 pnp_show_current_resources, pnp_set_current_resources);
472 static ssize_t pnp_show_current_ids(struct device *dmdev,
473 struct device_attribute *attr, char *buf)
476 struct pnp_dev *dev = to_pnp_dev(dmdev);
477 struct pnp_id *pos = dev->id;
480 str += sprintf(str, "%s\n", pos->id);
486 static DEVICE_ATTR(id, S_IRUGO, pnp_show_current_ids, NULL);
488 int pnp_interface_attach_device(struct pnp_dev *dev)
490 int rc = device_create_file(&dev->dev, &dev_attr_options);
493 rc = device_create_file(&dev->dev, &dev_attr_resources);
496 rc = device_create_file(&dev->dev, &dev_attr_id);
503 device_remove_file(&dev->dev, &dev_attr_resources);
505 device_remove_file(&dev->dev, &dev_attr_options);