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>
61f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
71f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas *	Bjorn Helgaas <bjorn.helgaas@hp.com>
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/pnp.h>
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/string.h>
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h>
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/list.h>
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/types.h>
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/stat.h>
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ctype.h>
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/slab.h>
18b3bd86e2fdce01d6b49271a553d2a18b3e0510f3Daniel Walker#include <linux/mutex.h>
19b3bd86e2fdce01d6b49271a553d2a18b3e0510f3Daniel Walker
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/uaccess.h>
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "base.h"
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct pnp_info_buffer {
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *buffer;		/* pointer to begin of buffer */
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *curr;		/* current position in buffer */
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long size;	/* current size */
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long len;	/* total length of buffer */
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int stop;		/* stop flag */
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int error;		/* error code */
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstypedef struct pnp_info_buffer pnp_info_buffer_t;
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
359dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaasstatic int pnp_printf(pnp_info_buffer_t * buffer, char *fmt, ...)
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	va_list args;
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int res;
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (buffer->stop || buffer->error)
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	va_start(args, fmt);
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	res = vsnprintf(buffer->curr, buffer->len - buffer->size, fmt, args);
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	va_end(args);
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (buffer->size + res >= buffer->len) {
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		buffer->stop = 1;
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buffer->curr += res;
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buffer->size += res;
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return res;
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
549dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaasstatic void pnp_print_port(pnp_info_buffer_t * buffer, char *space,
559dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas			   struct pnp_port *port)
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
57169aaffe885c56745188e7913f212a67beaa3b80Bjorn Helgaas	pnp_printf(buffer, "%sport %#llx-%#llx, align %#llx, size %#llx, "
58169aaffe885c56745188e7913f212a67beaa3b80Bjorn Helgaas		   "%i-bit address decoding\n", space,
59169aaffe885c56745188e7913f212a67beaa3b80Bjorn Helgaas		   (unsigned long long) port->min,
60169aaffe885c56745188e7913f212a67beaa3b80Bjorn Helgaas		   (unsigned long long) port->max,
61169aaffe885c56745188e7913f212a67beaa3b80Bjorn Helgaas		   port->align ? ((unsigned long long) port->align - 1) : 0,
62169aaffe885c56745188e7913f212a67beaa3b80Bjorn Helgaas		   (unsigned long long) port->size,
6308c9f262f268f7948be13bf3a5bda1d635c649b4Bjorn Helgaas		   port->flags & IORESOURCE_IO_16BIT_ADDR ? 16 : 10);
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
669dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaasstatic void pnp_print_irq(pnp_info_buffer_t * buffer, char *space,
679dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas			  struct pnp_irq *irq)
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int first = 1, i;
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pnp_printf(buffer, "%sirq ", space);
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < PNP_IRQ_NR; i++)
737aefff51854ccd33599c40b4e360d94cb2b7622fBjorn Helgaas		if (test_bit(i, irq->map.bits)) {
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (!first) {
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				pnp_printf(buffer, ",");
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			} else {
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				first = 0;
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (i == 2 || i == 9)
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				pnp_printf(buffer, "2/9");
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			else
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				pnp_printf(buffer, "%i", i);
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
847aefff51854ccd33599c40b4e360d94cb2b7622fBjorn Helgaas	if (bitmap_empty(irq->map.bits, PNP_IRQ_NR))
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pnp_printf(buffer, "<none>");
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (irq->flags & IORESOURCE_IRQ_HIGHEDGE)
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pnp_printf(buffer, " High-Edge");
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (irq->flags & IORESOURCE_IRQ_LOWEDGE)
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pnp_printf(buffer, " Low-Edge");
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (irq->flags & IORESOURCE_IRQ_HIGHLEVEL)
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pnp_printf(buffer, " High-Level");
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (irq->flags & IORESOURCE_IRQ_LOWLEVEL)
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pnp_printf(buffer, " Low-Level");
94d5ebde6ef5c2d51828f975a81d7d0e58bccfd833Bjorn Helgaas	if (irq->flags & IORESOURCE_IRQ_OPTIONAL)
95d5ebde6ef5c2d51828f975a81d7d0e58bccfd833Bjorn Helgaas		pnp_printf(buffer, " (optional)");
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pnp_printf(buffer, "\n");
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
999dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaasstatic void pnp_print_dma(pnp_info_buffer_t * buffer, char *space,
1009dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas			  struct pnp_dma *dma)
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int first = 1, i;
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *s;
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pnp_printf(buffer, "%sdma ", space);
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < 8; i++)
1079dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas		if (dma->map & (1 << i)) {
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (!first) {
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				pnp_printf(buffer, ",");
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			} else {
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				first = 0;
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			pnp_printf(buffer, "%i", i);
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!dma->map)
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pnp_printf(buffer, "<none>");
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (dma->flags & IORESOURCE_DMA_TYPE_MASK) {
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case IORESOURCE_DMA_8BIT:
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		s = "8-bit";
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case IORESOURCE_DMA_8AND16BIT:
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		s = "8-bit&16-bit";
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		s = "16-bit";
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pnp_printf(buffer, " %s", s);
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (dma->flags & IORESOURCE_DMA_MASTER)
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pnp_printf(buffer, " master");
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (dma->flags & IORESOURCE_DMA_BYTE)
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pnp_printf(buffer, " byte-count");
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (dma->flags & IORESOURCE_DMA_WORD)
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pnp_printf(buffer, " word-count");
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (dma->flags & IORESOURCE_DMA_SPEED_MASK) {
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case IORESOURCE_DMA_TYPEA:
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		s = "type-A";
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case IORESOURCE_DMA_TYPEB:
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		s = "type-B";
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case IORESOURCE_DMA_TYPEF:
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		s = "type-F";
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		s = "compatible";
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pnp_printf(buffer, " %s\n", s);
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1519dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaasstatic void pnp_print_mem(pnp_info_buffer_t * buffer, char *space,
1529dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas			  struct pnp_mem *mem)
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *s;
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
156169aaffe885c56745188e7913f212a67beaa3b80Bjorn Helgaas	pnp_printf(buffer, "%sMemory %#llx-%#llx, align %#llx, size %#llx",
157169aaffe885c56745188e7913f212a67beaa3b80Bjorn Helgaas		   space, (unsigned long long) mem->min,
158169aaffe885c56745188e7913f212a67beaa3b80Bjorn Helgaas		   (unsigned long long) mem->max,
159169aaffe885c56745188e7913f212a67beaa3b80Bjorn Helgaas		   (unsigned long long) mem->align,
160169aaffe885c56745188e7913f212a67beaa3b80Bjorn Helgaas		   (unsigned long long) mem->size);
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (mem->flags & IORESOURCE_MEM_WRITEABLE)
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pnp_printf(buffer, ", writeable");
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (mem->flags & IORESOURCE_MEM_CACHEABLE)
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pnp_printf(buffer, ", cacheable");
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (mem->flags & IORESOURCE_MEM_RANGELENGTH)
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pnp_printf(buffer, ", range-length");
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (mem->flags & IORESOURCE_MEM_SHADOWABLE)
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pnp_printf(buffer, ", shadowable");
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (mem->flags & IORESOURCE_MEM_EXPANSIONROM)
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pnp_printf(buffer, ", expansion ROM");
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (mem->flags & IORESOURCE_MEM_TYPE_MASK) {
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case IORESOURCE_MEM_8BIT:
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		s = "8-bit";
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case IORESOURCE_MEM_8AND16BIT:
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		s = "8-bit&16-bit";
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case IORESOURCE_MEM_32BIT:
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		s = "32-bit";
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		s = "16-bit";
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pnp_printf(buffer, ", %s\n", s);
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1879dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaasstatic void pnp_print_option(pnp_info_buffer_t * buffer, char *space,
1881f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas			     struct pnp_option *option)
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1901f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas	switch (option->type) {
1911f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas	case IORESOURCE_IO:
1921f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas		pnp_print_port(buffer, space, &option->u.port);
1931f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas		break;
1941f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas	case IORESOURCE_MEM:
1951f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas		pnp_print_mem(buffer, space, &option->u.mem);
1961f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas		break;
1971f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas	case IORESOURCE_IRQ:
1981f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas		pnp_print_irq(buffer, space, &option->u.irq);
1991f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas		break;
2001f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas	case IORESOURCE_DMA:
2011f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas		pnp_print_dma(buffer, space, &option->u.dma);
2021f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas		break;
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2069dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaasstatic ssize_t pnp_show_options(struct device *dmdev,
2079dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas				struct device_attribute *attr, char *buf)
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct pnp_dev *dev = to_pnp_dev(dmdev);
210b72ee1f11e373179ec703e0e5afaf585ed3a950aBjorn Helgaas	pnp_info_buffer_t *buffer;
2111f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas	struct pnp_option *option;
2121f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas	int ret, dep = 0, set = 0;
2131f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas	char *indent;
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
215b72ee1f11e373179ec703e0e5afaf585ed3a950aBjorn Helgaas	buffer = pnp_alloc(sizeof(pnp_info_buffer_t));
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!buffer)
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -ENOMEM;
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buffer->len = PAGE_SIZE;
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buffer->buffer = buf;
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buffer->curr = buffer->buffer;
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2231f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas	list_for_each_entry(option, &dev->options, list) {
2241f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas		if (pnp_option_is_dependent(option)) {
2251f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas			indent = "  ";
2261f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas			if (!dep || pnp_option_set(option) != set) {
2271f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas				set = pnp_option_set(option);
2281f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas				dep = 1;
2291f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas				pnp_printf(buffer, "Dependent: %02i - "
2301f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas					   "Priority %s\n", set,
2311f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas					   pnp_option_priority_name(option));
2321f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas			}
2331f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas		} else {
2341f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas			dep = 0;
2351f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas			indent = "";
2361f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas		}
2371f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas		pnp_print_option(buffer, indent, option);
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2391f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = (buffer->curr - buf);
2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kfree(buffer);
2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2459dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaasstatic ssize_t pnp_show_current_resources(struct device *dmdev,
2469dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas					  struct device_attribute *attr,
2479dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas					  char *buf)
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct pnp_dev *dev = to_pnp_dev(dmdev);
250b72ee1f11e373179ec703e0e5afaf585ed3a950aBjorn Helgaas	pnp_info_buffer_t *buffer;
251f61ed7e32d2d6a0a8c3c101da513ccedd542e14dBjorn Helgaas	struct pnp_resource *pnp_res;
25295ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas	struct resource *res;
253f61ed7e32d2d6a0a8c3c101da513ccedd542e14dBjorn Helgaas	int ret;
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!dev)
2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EINVAL;
2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
258b72ee1f11e373179ec703e0e5afaf585ed3a950aBjorn Helgaas	buffer = pnp_alloc(sizeof(pnp_info_buffer_t));
2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!buffer)
2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -ENOMEM;
261b72ee1f11e373179ec703e0e5afaf585ed3a950aBjorn Helgaas
2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buffer->len = PAGE_SIZE;
2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buffer->buffer = buf;
2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buffer->curr = buffer->buffer;
2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
266f61ed7e32d2d6a0a8c3c101da513ccedd542e14dBjorn Helgaas	pnp_printf(buffer, "state = %s\n", dev->active ? "active" : "disabled");
2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
268f61ed7e32d2d6a0a8c3c101da513ccedd542e14dBjorn Helgaas	list_for_each_entry(pnp_res, &dev->resources, list) {
269f61ed7e32d2d6a0a8c3c101da513ccedd542e14dBjorn Helgaas		res = &pnp_res->res;
270f61ed7e32d2d6a0a8c3c101da513ccedd542e14dBjorn Helgaas
271f61ed7e32d2d6a0a8c3c101da513ccedd542e14dBjorn Helgaas		pnp_printf(buffer, pnp_resource_type_name(res));
272f61ed7e32d2d6a0a8c3c101da513ccedd542e14dBjorn Helgaas
273f61ed7e32d2d6a0a8c3c101da513ccedd542e14dBjorn Helgaas		if (res->flags & IORESOURCE_DISABLED) {
274aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas			pnp_printf(buffer, " disabled\n");
275f61ed7e32d2d6a0a8c3c101da513ccedd542e14dBjorn Helgaas			continue;
276f61ed7e32d2d6a0a8c3c101da513ccedd542e14dBjorn Helgaas		}
277f61ed7e32d2d6a0a8c3c101da513ccedd542e14dBjorn Helgaas
278f61ed7e32d2d6a0a8c3c101da513ccedd542e14dBjorn Helgaas		switch (pnp_resource_type(res)) {
279f61ed7e32d2d6a0a8c3c101da513ccedd542e14dBjorn Helgaas		case IORESOURCE_IO:
280f61ed7e32d2d6a0a8c3c101da513ccedd542e14dBjorn Helgaas		case IORESOURCE_MEM:
2817e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas		case IORESOURCE_BUS:
282fa35b49260b615d634bfa1f767aa315fa323c2e9Bjorn Helgaas			pnp_printf(buffer, " %#llx-%#llx%s\n",
283aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas				   (unsigned long long) res->start,
284fa35b49260b615d634bfa1f767aa315fa323c2e9Bjorn Helgaas				   (unsigned long long) res->end,
285fa35b49260b615d634bfa1f767aa315fa323c2e9Bjorn Helgaas				   res->flags & IORESOURCE_WINDOW ?
286fa35b49260b615d634bfa1f767aa315fa323c2e9Bjorn Helgaas					" window" : "");
287f61ed7e32d2d6a0a8c3c101da513ccedd542e14dBjorn Helgaas			break;
288f61ed7e32d2d6a0a8c3c101da513ccedd542e14dBjorn Helgaas		case IORESOURCE_IRQ:
289f61ed7e32d2d6a0a8c3c101da513ccedd542e14dBjorn Helgaas		case IORESOURCE_DMA:
290aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas			pnp_printf(buffer, " %lld\n",
291aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas				   (unsigned long long) res->start);
292f61ed7e32d2d6a0a8c3c101da513ccedd542e14dBjorn Helgaas			break;
293f61ed7e32d2d6a0a8c3c101da513ccedd542e14dBjorn Helgaas		}
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
295f61ed7e32d2d6a0a8c3c101da513ccedd542e14dBjorn Helgaas
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = (buffer->curr - buf);
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kfree(buffer);
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
301b72ee1f11e373179ec703e0e5afaf585ed3a950aBjorn Helgaasstatic ssize_t pnp_set_current_resources(struct device *dmdev,
302b72ee1f11e373179ec703e0e5afaf585ed3a950aBjorn Helgaas					 struct device_attribute *attr,
303b72ee1f11e373179ec703e0e5afaf585ed3a950aBjorn Helgaas					 const char *ubuf, size_t count)
3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct pnp_dev *dev = to_pnp_dev(dmdev);
3069dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas	char *buf = (void *)ubuf;
3079dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas	int retval = 0;
308cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas	resource_size_t start, end;
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (dev->status & PNP_ATTACHED) {
3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		retval = -EBUSY;
312a05d0781695566296e74a3670dd5bbd3daf24ae2Bjorn Helgaas		dev_info(&dev->dev, "in use; can't configure\n");
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto done;
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
316e7d2860b690d4f3bed6824757c540579638e3d1eAndré Goddard Rosa	buf = skip_spaces(buf);
3179dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas	if (!strnicmp(buf, "disable", 7)) {
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		retval = pnp_disable_dev(dev);
3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto done;
3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3219dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas	if (!strnicmp(buf, "activate", 8)) {
3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		retval = pnp_activate_dev(dev);
3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto done;
3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3259dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas	if (!strnicmp(buf, "fill", 4)) {
3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (dev->active)
3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			goto done;
3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		retval = pnp_auto_config_dev(dev);
3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto done;
3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3319dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas	if (!strnicmp(buf, "auto", 4)) {
3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (dev->active)
3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			goto done;
334f44900020926b2cb06b87f0f52643d6285514fc3Bjorn Helgaas		pnp_init_resources(dev);
3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		retval = pnp_auto_config_dev(dev);
3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto done;
3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3389dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas	if (!strnicmp(buf, "clear", 5)) {
3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (dev->active)
3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			goto done;
341f44900020926b2cb06b87f0f52643d6285514fc3Bjorn Helgaas		pnp_init_resources(dev);
3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto done;
3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3449dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas	if (!strnicmp(buf, "get", 3)) {
345b3bd86e2fdce01d6b49271a553d2a18b3e0510f3Daniel Walker		mutex_lock(&pnp_res_mutex);
3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (pnp_can_read(dev))
34759284cb4099411bc6f4915a5a4cb76414440c447Bjorn Helgaas			dev->protocol->get(dev);
348b3bd86e2fdce01d6b49271a553d2a18b3e0510f3Daniel Walker		mutex_unlock(&pnp_res_mutex);
3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto done;
3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3519dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas	if (!strnicmp(buf, "set", 3)) {
3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (dev->active)
3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			goto done;
3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		buf += 3;
355f44900020926b2cb06b87f0f52643d6285514fc3Bjorn Helgaas		pnp_init_resources(dev);
356b3bd86e2fdce01d6b49271a553d2a18b3e0510f3Daniel Walker		mutex_lock(&pnp_res_mutex);
3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		while (1) {
358e7d2860b690d4f3bed6824757c540579638e3d1eAndré Goddard Rosa			buf = skip_spaces(buf);
3599dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas			if (!strnicmp(buf, "io", 2)) {
360e7d2860b690d4f3bed6824757c540579638e3d1eAndré Goddard Rosa				buf = skip_spaces(buf + 2);
361cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas				start = simple_strtoul(buf, &buf, 0);
362e7d2860b690d4f3bed6824757c540579638e3d1eAndré Goddard Rosa				buf = skip_spaces(buf);
3639dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas				if (*buf == '-') {
364e7d2860b690d4f3bed6824757c540579638e3d1eAndré Goddard Rosa					buf = skip_spaces(buf + 1);
365cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas					end = simple_strtoul(buf, &buf, 0);
3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				} else
367cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas					end = start;
36887e4acf3ebc02c9d0a2f7a37b655c49176c4d765Bjorn Helgaas				pnp_add_io_resource(dev, start, end, 0);
3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				continue;
3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
3719dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas			if (!strnicmp(buf, "mem", 3)) {
372e7d2860b690d4f3bed6824757c540579638e3d1eAndré Goddard Rosa				buf = skip_spaces(buf + 3);
373d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas				start = simple_strtoul(buf, &buf, 0);
374e7d2860b690d4f3bed6824757c540579638e3d1eAndré Goddard Rosa				buf = skip_spaces(buf);
3759dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas				if (*buf == '-') {
376e7d2860b690d4f3bed6824757c540579638e3d1eAndré Goddard Rosa					buf = skip_spaces(buf + 1);
377d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas					end = simple_strtoul(buf, &buf, 0);
3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				} else
379d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas					end = start;
38087e4acf3ebc02c9d0a2f7a37b655c49176c4d765Bjorn Helgaas				pnp_add_mem_resource(dev, start, end, 0);
3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				continue;
3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
3839dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas			if (!strnicmp(buf, "irq", 3)) {
384e7d2860b690d4f3bed6824757c540579638e3d1eAndré Goddard Rosa				buf = skip_spaces(buf + 3);
385dbddd0383c59d588f8db5e773b062756e39117ecBjorn Helgaas				start = simple_strtoul(buf, &buf, 0);
38687e4acf3ebc02c9d0a2f7a37b655c49176c4d765Bjorn Helgaas				pnp_add_irq_resource(dev, start, 0);
3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				continue;
3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
3899dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas			if (!strnicmp(buf, "dma", 3)) {
390e7d2860b690d4f3bed6824757c540579638e3d1eAndré Goddard Rosa				buf = skip_spaces(buf + 3);
391dc16f5f2ede8cc2acf8ac22857a7fecf3a4296c2Bjorn Helgaas				start = simple_strtoul(buf, &buf, 0);
39287e4acf3ebc02c9d0a2f7a37b655c49176c4d765Bjorn Helgaas				pnp_add_dma_resource(dev, start, 0);
3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				continue;
3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
397b3bd86e2fdce01d6b49271a553d2a18b3e0510f3Daniel Walker		mutex_unlock(&pnp_res_mutex);
3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto done;
3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4001e0aa9ad721349781b728ec4226876247e3fd431Bjorn Helgaas
4011e0aa9ad721349781b728ec4226876247e3fd431Bjorn Helgaasdone:
4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (retval < 0)
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return retval;
4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return count;
4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4079dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaasstatic ssize_t pnp_show_current_ids(struct device *dmdev,
4089dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas				    struct device_attribute *attr, char *buf)
4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *str = buf;
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct pnp_dev *dev = to_pnp_dev(dmdev);
4129dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas	struct pnp_id *pos = dev->id;
4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while (pos) {
4159dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas		str += sprintf(str, "%s\n", pos->id);
4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pos = pos->next;
4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return (str - buf);
4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4218a89efd18aa15bb832778baa4e6eee3857ecada4Drew Moseleystruct device_attribute pnp_interface_attrs[] = {
4228a89efd18aa15bb832778baa4e6eee3857ecada4Drew Moseley	__ATTR(resources, S_IRUGO | S_IWUSR,
4238a89efd18aa15bb832778baa4e6eee3857ecada4Drew Moseley		   pnp_show_current_resources,
4248a89efd18aa15bb832778baa4e6eee3857ecada4Drew Moseley		   pnp_set_current_resources),
4258a89efd18aa15bb832778baa4e6eee3857ecada4Drew Moseley	__ATTR(options, S_IRUGO, pnp_show_options, NULL),
4268a89efd18aa15bb832778baa4e6eee3857ecada4Drew Moseley	__ATTR(id, S_IRUGO, pnp_show_current_ids, NULL),
4278a89efd18aa15bb832778baa4e6eee3857ecada4Drew Moseley	__ATTR_NULL,
4288a89efd18aa15bb832778baa4e6eee3857ecada4Drew Moseley};
429