interface.c revision 95ab3669f7830682c7762e9c305a0c1dd44454cc
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * interface.c - contains everything related to the user interface 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4c1017a4cdb68ae5368fbc9ee42c77f1f5dca8916Jaroslav Kysela * Some code, especially possible resource dumping is based on isapnp_proc.c (c) Jaroslav Kysela <perex@perex.cz> 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright 2002 Adam Belay <ambx1@neo.rr.com> 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/pnp.h> 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/string.h> 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h> 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/list.h> 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/types.h> 13b3bd86e2fdce01d6b49271a553d2a18b3e0510f3Daniel Walker#include <linux/pnp.h> 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/stat.h> 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ctype.h> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/slab.h> 17b3bd86e2fdce01d6b49271a553d2a18b3e0510f3Daniel Walker#include <linux/mutex.h> 18b3bd86e2fdce01d6b49271a553d2a18b3e0510f3Daniel Walker 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/uaccess.h> 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "base.h" 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct pnp_info_buffer { 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *buffer; /* pointer to begin of buffer */ 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *curr; /* current position in buffer */ 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long size; /* current size */ 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long len; /* total length of buffer */ 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int stop; /* stop flag */ 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int error; /* error code */ 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstypedef struct pnp_info_buffer pnp_info_buffer_t; 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 349dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaasstatic int pnp_printf(pnp_info_buffer_t * buffer, char *fmt, ...) 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds va_list args; 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int res; 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buffer->stop || buffer->error) 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds va_start(args, fmt); 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds res = vsnprintf(buffer->curr, buffer->len - buffer->size, fmt, args); 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds va_end(args); 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buffer->size + res >= buffer->len) { 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buffer->stop = 1; 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buffer->curr += res; 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buffer->size += res; 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return res; 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 539dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaasstatic void pnp_print_port(pnp_info_buffer_t * buffer, char *space, 549dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas struct pnp_port *port) 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 569dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas pnp_printf(buffer, 579dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas "%sport 0x%x-0x%x, align 0x%x, size 0x%x, %i-bit address decoding\n", 589dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas space, port->min, port->max, 599dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas port->align ? (port->align - 1) : 0, port->size, 609dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas port->flags & PNP_PORT_FLAG_16BITADDR ? 16 : 10); 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 639dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaasstatic void pnp_print_irq(pnp_info_buffer_t * buffer, char *space, 649dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas struct pnp_irq *irq) 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int first = 1, i; 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_printf(buffer, "%sirq ", space); 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < PNP_IRQ_NR; i++) 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(i, irq->map)) { 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!first) { 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_printf(buffer, ","); 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds first = 0; 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (i == 2 || i == 9) 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_printf(buffer, "2/9"); 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_printf(buffer, "%i", i); 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bitmap_empty(irq->map, PNP_IRQ_NR)) 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_printf(buffer, "<none>"); 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (irq->flags & IORESOURCE_IRQ_HIGHEDGE) 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_printf(buffer, " High-Edge"); 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (irq->flags & IORESOURCE_IRQ_LOWEDGE) 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_printf(buffer, " Low-Edge"); 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (irq->flags & IORESOURCE_IRQ_HIGHLEVEL) 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_printf(buffer, " High-Level"); 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (irq->flags & IORESOURCE_IRQ_LOWLEVEL) 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_printf(buffer, " Low-Level"); 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_printf(buffer, "\n"); 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 949dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaasstatic void pnp_print_dma(pnp_info_buffer_t * buffer, char *space, 959dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas struct pnp_dma *dma) 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int first = 1, i; 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *s; 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_printf(buffer, "%sdma ", space); 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 8; i++) 1029dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (dma->map & (1 << i)) { 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!first) { 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_printf(buffer, ","); 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds first = 0; 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_printf(buffer, "%i", i); 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dma->map) 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_printf(buffer, "<none>"); 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (dma->flags & IORESOURCE_DMA_TYPE_MASK) { 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IORESOURCE_DMA_8BIT: 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s = "8-bit"; 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IORESOURCE_DMA_8AND16BIT: 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s = "8-bit&16-bit"; 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s = "16-bit"; 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_printf(buffer, " %s", s); 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dma->flags & IORESOURCE_DMA_MASTER) 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_printf(buffer, " master"); 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dma->flags & IORESOURCE_DMA_BYTE) 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_printf(buffer, " byte-count"); 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dma->flags & IORESOURCE_DMA_WORD) 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_printf(buffer, " word-count"); 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (dma->flags & IORESOURCE_DMA_SPEED_MASK) { 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IORESOURCE_DMA_TYPEA: 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s = "type-A"; 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IORESOURCE_DMA_TYPEB: 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s = "type-B"; 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IORESOURCE_DMA_TYPEF: 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s = "type-F"; 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s = "compatible"; 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_printf(buffer, " %s\n", s); 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1469dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaasstatic void pnp_print_mem(pnp_info_buffer_t * buffer, char *space, 1479dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas struct pnp_mem *mem) 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *s; 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_printf(buffer, "%sMemory 0x%x-0x%x, align 0x%x, size 0x%x", 1529dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas space, mem->min, mem->max, mem->align, mem->size); 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mem->flags & IORESOURCE_MEM_WRITEABLE) 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_printf(buffer, ", writeable"); 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mem->flags & IORESOURCE_MEM_CACHEABLE) 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_printf(buffer, ", cacheable"); 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mem->flags & IORESOURCE_MEM_RANGELENGTH) 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_printf(buffer, ", range-length"); 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mem->flags & IORESOURCE_MEM_SHADOWABLE) 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_printf(buffer, ", shadowable"); 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mem->flags & IORESOURCE_MEM_EXPANSIONROM) 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_printf(buffer, ", expansion ROM"); 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (mem->flags & IORESOURCE_MEM_TYPE_MASK) { 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IORESOURCE_MEM_8BIT: 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s = "8-bit"; 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IORESOURCE_MEM_8AND16BIT: 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s = "8-bit&16-bit"; 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IORESOURCE_MEM_32BIT: 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s = "32-bit"; 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s = "16-bit"; 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_printf(buffer, ", %s\n", s); 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1799dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaasstatic void pnp_print_option(pnp_info_buffer_t * buffer, char *space, 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pnp_option *option, int dep) 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *s; 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pnp_port *port; 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pnp_irq *irq; 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pnp_dma *dma; 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pnp_mem *mem; 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dep) { 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (option->priority) { 1909dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case PNP_RES_PRIORITY_PREFERRED: 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s = "preferred"; 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1939dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case PNP_RES_PRIORITY_ACCEPTABLE: 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s = "acceptable"; 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1969dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas case PNP_RES_PRIORITY_FUNCTIONAL: 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s = "functional"; 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1999dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas default: 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s = "invalid"; 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2029dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas pnp_printf(buffer, "Dependent: %02i - Priority %s\n", dep, s); 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (port = option->port; port; port = port->next) 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_print_port(buffer, space, port); 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (irq = option->irq; irq; irq = irq->next) 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_print_irq(buffer, space, irq); 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (dma = option->dma; dma; dma = dma->next) 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_print_dma(buffer, space, dma); 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (mem = option->mem; mem; mem = mem->next) 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_print_mem(buffer, space, mem); 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2159dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaasstatic ssize_t pnp_show_options(struct device *dmdev, 2169dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas struct device_attribute *attr, char *buf) 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pnp_dev *dev = to_pnp_dev(dmdev); 2199dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas struct pnp_option *independent = dev->independent; 2209dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas struct pnp_option *dependent = dev->dependent; 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret, dep = 1; 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_info_buffer_t *buffer = (pnp_info_buffer_t *) 2249dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas pnp_alloc(sizeof(pnp_info_buffer_t)); 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!buffer) 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buffer->len = PAGE_SIZE; 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buffer->buffer = buf; 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buffer->curr = buffer->buffer; 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (independent) 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_print_option(buffer, "", independent, 0); 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2349dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas while (dependent) { 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_print_option(buffer, " ", dependent, dep); 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dependent = dependent->next; 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dep++; 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = (buffer->curr - buf); 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(buffer); 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2449dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaasstatic DEVICE_ATTR(options, S_IRUGO, pnp_show_options, NULL); 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2469dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaasstatic ssize_t pnp_show_current_resources(struct device *dmdev, 2479dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas struct device_attribute *attr, 2489dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas char *buf) 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pnp_dev *dev = to_pnp_dev(dmdev); 25195ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas struct resource *res; 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i, ret; 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_info_buffer_t *buffer; 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dev) 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buffer = (pnp_info_buffer_t *) pnp_alloc(sizeof(pnp_info_buffer_t)); 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!buffer) 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buffer->len = PAGE_SIZE; 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buffer->buffer = buf; 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buffer->curr = buffer->buffer; 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2659dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas pnp_printf(buffer, "state = "); 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev->active) 2679dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas pnp_printf(buffer, "active\n"); 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 2699dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas pnp_printf(buffer, "disabled\n"); 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27195ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) { 27295ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas if (pnp_resource_valid(res)) { 2739dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas pnp_printf(buffer, "io"); 27495ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas if (res->flags & IORESOURCE_DISABLED) 2759dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas pnp_printf(buffer, " disabled\n"); 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 2779dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas pnp_printf(buffer, " 0x%llx-0x%llx\n", 27895ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas (unsigned long long) res->start, 27995ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas (unsigned long long) res->end); 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 28295ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) { 28395ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas if (pnp_resource_valid(res)) { 2849dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas pnp_printf(buffer, "mem"); 28595ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas if (res->flags & IORESOURCE_DISABLED) 2869dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas pnp_printf(buffer, " disabled\n"); 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 2889dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas pnp_printf(buffer, " 0x%llx-0x%llx\n", 28995ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas (unsigned long long) res->start, 29095ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas (unsigned long long) res->end); 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 29395ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IRQ, i)); i++) { 29495ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas if (pnp_resource_valid(res)) { 2959dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas pnp_printf(buffer, "irq"); 29695ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas if (res->flags & IORESOURCE_DISABLED) 2979dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas pnp_printf(buffer, " disabled\n"); 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 2999dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas pnp_printf(buffer, " %lld\n", 30095ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas (unsigned long long) res->start); 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 30395ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_DMA, i)); i++) { 30495ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas if (pnp_resource_valid(res)) { 3059dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas pnp_printf(buffer, "dma"); 30695ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas if (res->flags & IORESOURCE_DISABLED) 3079dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas pnp_printf(buffer, " disabled\n"); 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3099dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas pnp_printf(buffer, " %lld\n", 31095ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas (unsigned long long) res->start); 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = (buffer->curr - buf); 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(buffer); 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 3199dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaaspnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, 3209dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas const char *ubuf, size_t count) 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pnp_dev *dev = to_pnp_dev(dmdev); 323470feb113a23de365b6051efde0d69de86d9d2f8Bjorn Helgaas struct resource *res; 3249dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas char *buf = (void *)ubuf; 3259dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas int retval = 0; 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev->status & PNP_ATTACHED) { 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = -EBUSY; 329a05d0781695566296e74a3670dd5bbd3daf24ae2Bjorn Helgaas dev_info(&dev->dev, "in use; can't configure\n"); 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto done; 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (isspace(*buf)) 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++buf; 3359dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (!strnicmp(buf, "disable", 7)) { 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = pnp_disable_dev(dev); 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto done; 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3399dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (!strnicmp(buf, "activate", 8)) { 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = pnp_activate_dev(dev); 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto done; 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3439dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (!strnicmp(buf, "fill", 4)) { 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev->active) 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto done; 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = pnp_auto_config_dev(dev); 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto done; 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3499dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (!strnicmp(buf, "auto", 4)) { 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev->active) 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto done; 352f44900020926b2cb06b87f0f52643d6285514fc3Bjorn Helgaas pnp_init_resources(dev); 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = pnp_auto_config_dev(dev); 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto done; 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3569dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (!strnicmp(buf, "clear", 5)) { 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev->active) 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto done; 359f44900020926b2cb06b87f0f52643d6285514fc3Bjorn Helgaas pnp_init_resources(dev); 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto done; 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3629dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (!strnicmp(buf, "get", 3)) { 363b3bd86e2fdce01d6b49271a553d2a18b3e0510f3Daniel Walker mutex_lock(&pnp_res_mutex); 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pnp_can_read(dev)) 36559284cb4099411bc6f4915a5a4cb76414440c447Bjorn Helgaas dev->protocol->get(dev); 366b3bd86e2fdce01d6b49271a553d2a18b3e0510f3Daniel Walker mutex_unlock(&pnp_res_mutex); 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto done; 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3699dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (!strnicmp(buf, "set", 3)) { 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int nport = 0, nmem = 0, nirq = 0, ndma = 0; 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev->active) 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto done; 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf += 3; 374f44900020926b2cb06b87f0f52643d6285514fc3Bjorn Helgaas pnp_init_resources(dev); 375b3bd86e2fdce01d6b49271a553d2a18b3e0510f3Daniel Walker mutex_lock(&pnp_res_mutex); 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (1) { 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (isspace(*buf)) 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++buf; 3799dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (!strnicmp(buf, "io", 2)) { 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf += 2; 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (isspace(*buf)) 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++buf; 383f6505fef18644557f732468c1f22f84560d8a819Bjorn Helgaas res = pnp_get_resource(dev, IORESOURCE_IO, 384f6505fef18644557f732468c1f22f84560d8a819Bjorn Helgaas nport); 385f6505fef18644557f732468c1f22f84560d8a819Bjorn Helgaas if (!res) 386f6505fef18644557f732468c1f22f84560d8a819Bjorn Helgaas break; 387470feb113a23de365b6051efde0d69de86d9d2f8Bjorn Helgaas res->start = simple_strtoul(buf, &buf, 0); 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (isspace(*buf)) 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++buf; 3909dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (*buf == '-') { 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf += 1; 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (isspace(*buf)) 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++buf; 394470feb113a23de365b6051efde0d69de86d9d2f8Bjorn Helgaas res->end = simple_strtoul(buf, &buf, 0); 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 396470feb113a23de365b6051efde0d69de86d9d2f8Bjorn Helgaas res->end = res->start; 397470feb113a23de365b6051efde0d69de86d9d2f8Bjorn Helgaas res->flags = IORESOURCE_IO; 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nport++; 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4019dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (!strnicmp(buf, "mem", 3)) { 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf += 3; 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (isspace(*buf)) 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++buf; 405f6505fef18644557f732468c1f22f84560d8a819Bjorn Helgaas res = pnp_get_resource(dev, IORESOURCE_MEM, 406f6505fef18644557f732468c1f22f84560d8a819Bjorn Helgaas nmem); 407f6505fef18644557f732468c1f22f84560d8a819Bjorn Helgaas if (!res) 408f6505fef18644557f732468c1f22f84560d8a819Bjorn Helgaas break; 409470feb113a23de365b6051efde0d69de86d9d2f8Bjorn Helgaas res->start = simple_strtoul(buf, &buf, 0); 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (isspace(*buf)) 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++buf; 4129dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (*buf == '-') { 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf += 1; 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (isspace(*buf)) 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++buf; 416470feb113a23de365b6051efde0d69de86d9d2f8Bjorn Helgaas res->end = simple_strtoul(buf, &buf, 0); 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 418470feb113a23de365b6051efde0d69de86d9d2f8Bjorn Helgaas res->end = res->start; 419470feb113a23de365b6051efde0d69de86d9d2f8Bjorn Helgaas res->flags = IORESOURCE_MEM; 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nmem++; 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4239dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (!strnicmp(buf, "irq", 3)) { 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf += 3; 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (isspace(*buf)) 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++buf; 427f6505fef18644557f732468c1f22f84560d8a819Bjorn Helgaas res = pnp_get_resource(dev, IORESOURCE_IRQ, 428f6505fef18644557f732468c1f22f84560d8a819Bjorn Helgaas nirq); 429f6505fef18644557f732468c1f22f84560d8a819Bjorn Helgaas if (!res) 430f6505fef18644557f732468c1f22f84560d8a819Bjorn Helgaas break; 431470feb113a23de365b6051efde0d69de86d9d2f8Bjorn Helgaas res->start = res->end = 4329dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas simple_strtoul(buf, &buf, 0); 433470feb113a23de365b6051efde0d69de86d9d2f8Bjorn Helgaas res->flags = IORESOURCE_IRQ; 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nirq++; 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4379dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (!strnicmp(buf, "dma", 3)) { 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf += 3; 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (isspace(*buf)) 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++buf; 441f6505fef18644557f732468c1f22f84560d8a819Bjorn Helgaas res = pnp_get_resource(dev, IORESOURCE_DMA, 442f6505fef18644557f732468c1f22f84560d8a819Bjorn Helgaas ndma); 443f6505fef18644557f732468c1f22f84560d8a819Bjorn Helgaas if (!res) 444f6505fef18644557f732468c1f22f84560d8a819Bjorn Helgaas break; 445470feb113a23de365b6051efde0d69de86d9d2f8Bjorn Helgaas res->start = res->end = 4469dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas simple_strtoul(buf, &buf, 0); 447470feb113a23de365b6051efde0d69de86d9d2f8Bjorn Helgaas res->flags = IORESOURCE_DMA; 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ndma++; 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 453b3bd86e2fdce01d6b49271a553d2a18b3e0510f3Daniel Walker mutex_unlock(&pnp_res_mutex); 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto done; 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4561e0aa9ad721349781b728ec4226876247e3fd431Bjorn Helgaas 4571e0aa9ad721349781b728ec4226876247e3fd431Bjorn Helgaasdone: 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (retval < 0) 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return retval; 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4639dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaasstatic DEVICE_ATTR(resources, S_IRUGO | S_IWUSR, 4649dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas pnp_show_current_resources, pnp_set_current_resources); 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4669dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaasstatic ssize_t pnp_show_current_ids(struct device *dmdev, 4679dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas struct device_attribute *attr, char *buf) 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *str = buf; 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pnp_dev *dev = to_pnp_dev(dmdev); 4719dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas struct pnp_id *pos = dev->id; 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (pos) { 4749dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas str += sprintf(str, "%s\n", pos->id); 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pos = pos->next; 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (str - buf); 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4809dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaasstatic DEVICE_ATTR(id, S_IRUGO, pnp_show_current_ids, NULL); 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint pnp_interface_attach_device(struct pnp_dev *dev) 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4849dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas int rc = device_create_file(&dev->dev, &dev_attr_options); 48507d4e9af109221ab731c5aaf832e89776c64b013Bjorn Helgaas 4869dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (rc) 4879dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas goto err; 4889dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas rc = device_create_file(&dev->dev, &dev_attr_resources); 4899dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (rc) 4909dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas goto err_opt; 4919dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas rc = device_create_file(&dev->dev, &dev_attr_id); 4929dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (rc) 4939dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas goto err_res; 494bfc7ee207078e8ca51264355805e6f56b485be4bJeff Garzik 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 496bfc7ee207078e8ca51264355805e6f56b485be4bJeff Garzik 4971e0aa9ad721349781b728ec4226876247e3fd431Bjorn Helgaaserr_res: 4989dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas device_remove_file(&dev->dev, &dev_attr_resources); 4991e0aa9ad721349781b728ec4226876247e3fd431Bjorn Helgaaserr_opt: 5009dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas device_remove_file(&dev->dev, &dev_attr_options); 5011e0aa9ad721349781b728ec4226876247e3fd431Bjorn Helgaaserr: 502bfc7ee207078e8ca51264355805e6f56b485be4bJeff Garzik return rc; 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 504