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