public inbox for linux-acpi@vger.kernel.org
 help / color / mirror / Atom feed
* [patch 00/18] PNP: convert resource options to unified dynamic list, v2
@ 2008-06-04 22:09 Bjorn Helgaas
  2008-06-04 22:09 ` [patch 01/18] PNP: add pnp_possible_config() -- can a device could be configured this way? Bjorn Helgaas
                   ` (18 more replies)
  0 siblings, 19 replies; 31+ messages in thread
From: Bjorn Helgaas @ 2008-06-04 22:09 UTC (permalink / raw)
  To: Len Brown
  Cc: linux-acpi, linux-kernel, Adam Belay, Adam M Belay, Li Shaohua,
	Matthieu Castet, Thomas Renninger, Rene Herman, Jaroslav Kysela,
	Andrew Morton, Takashi Iwai

This patch series converts the PNP resource option structures
to a unified linked list.  This preserves resource order, which
is important for some devices.  The bulk of the series is in
the last patch, and it has more a more detailed changelog.

Rene Herman did some testing of ISA devices and reviewed
v1 of this series.  I think I addressed all his comments.
Any comments would be welcome.

This depends on some patches that are in -mm, but not yet
upstream.  In mmotm, these would probably go after
pnp-dont-sort-by-type-in-sys-resources.patch

Note that I incorporated Rene's ioport.h comment fix
(pnpacpi-fix-irq-flag-decoding-comment-fix.patch) into
this series, so you should drop that if you pick up this
series.

Change between v1 and v2:
    - rewrote 8250_pnp modem identification (first patch in series)
    - used bitmap_copy() rather than explicit loop to copy IRQ bitmaps
    - added "(optional)" note in /sys/.../options for IORESOURCE_IRQ_OPTIONAL
    - split out ISAPNP ENDDEP bug fix into a separate patch
    - restored "clear auto resources" when auto-assignment fails
    - removed 0x100 from option priority
    - allocated 12 bits for dependent option priority, 16 bits for set number
    - restored check for invalid dependent function priority
    - fixed AD1815 quirk (set OPTIONAL flag in the correct "flags" field)
    - fixed ioport.h ISA PnP comment (replaces Rene's
      pnpacpi-fix-irq-flag-decoding-comment-fix.patch)
    - rename "pnp_dependent_option()" to "pnp_new_dependent_set()"

Bjorn
-- 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [patch 01/18] PNP: add pnp_possible_config() -- can a device could be configured this way?
  2008-06-04 22:09 [patch 00/18] PNP: convert resource options to unified dynamic list, v2 Bjorn Helgaas
@ 2008-06-04 22:09 ` Bjorn Helgaas
  2008-06-14  8:05   ` Rene Herman
  2008-06-04 22:09 ` [patch 02/18] PNP: whitespace/coding style fixes Bjorn Helgaas
                   ` (17 subsequent siblings)
  18 siblings, 1 reply; 31+ messages in thread
From: Bjorn Helgaas @ 2008-06-04 22:09 UTC (permalink / raw)
  To: Len Brown
  Cc: linux-acpi, linux-kernel, Adam Belay, Adam M Belay, Li Shaohua,
	Matthieu Castet, Thomas Renninger, Rene Herman, Jaroslav Kysela,
	Andrew Morton, Takashi Iwai

[-- Attachment #1: pnp-new-option-interface-for-serial-pnp --]
[-- Type: text/plain, Size: 4927 bytes --]

As part of a heuristic to identify modem devices, 8250_pnp.c
checks to see whether a device can be configured at any of the
legacy COM port addresses.

This patch moves the code that traverses the PNP "possible resource
options" from 8250_pnp.c to the PNP subsystem.  This encapsulation
is important because a future patch will change the implementation
of those resource options.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>

---
 drivers/pnp/resource.c    |   61 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/serial/8250_pnp.c |   24 +++++-------------
 include/linux/pnp.h       |    3 ++
 3 files changed, 71 insertions(+), 17 deletions(-)

Index: work10/drivers/pnp/resource.c
===================================================================
--- work10.orig/drivers/pnp/resource.c	2008-06-04 13:46:55.000000000 -0600
+++ work10/drivers/pnp/resource.c	2008-06-04 15:30:51.000000000 -0600
@@ -624,6 +624,67 @@ struct pnp_resource *pnp_add_mem_resourc
 	return pnp_res;
 }
 
+static int pnp_possible_option(struct pnp_option *option, int type,
+			       resource_size_t start, resource_size_t size)
+{
+	struct pnp_option *tmp;
+	struct pnp_port *port;
+	struct pnp_mem *mem;
+	struct pnp_irq *irq;
+	struct pnp_dma *dma;
+
+	if (!option)
+		return 0;
+
+	for (tmp = option; tmp; tmp = tmp->next) {
+		switch (type) {
+		case IORESOURCE_IO:
+			for (port = tmp->port; port; port = port->next) {
+				if (port->min == start && port->size == size)
+					return 1;
+			}
+			break;
+		case IORESOURCE_MEM:
+			for (mem = tmp->mem; mem; mem = mem->next) {
+				if (mem->min == start && mem->size == size)
+					return 1;
+			}
+			break;
+		case IORESOURCE_IRQ:
+			for (irq = tmp->irq; irq; irq = irq->next) {
+				if (start < PNP_IRQ_NR &&
+				    test_bit(start, irq->map))
+					return 1;
+			}
+			break;
+		case IORESOURCE_DMA:
+			for (dma = tmp->dma; dma; dma = dma->next) {
+				if (dma->map & (1 << start))
+					return 1;
+			}
+			break;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * Determine whether the specified resource is a possible configuration
+ * for this device.
+ */
+int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t start,
+			resource_size_t size)
+{
+	if (pnp_possible_option(dev->independent, type, start, size))
+		return 1;
+
+	if (pnp_possible_option(dev->dependent, type, start, size))
+		return 1;
+
+	return 0;
+}
+
 /* format is: pnp_reserve_irq=irq1[,irq2] .... */
 static int __init pnp_setup_reserve_irq(char *str)
 {
Index: work10/drivers/serial/8250_pnp.c
===================================================================
--- work10.orig/drivers/serial/8250_pnp.c	2008-06-04 13:44:39.000000000 -0600
+++ work10/drivers/serial/8250_pnp.c	2008-06-04 15:31:24.000000000 -0600
@@ -383,21 +383,14 @@ static int __devinit check_name(char *na
 	return 0;
 }
 
-static int __devinit check_resources(struct pnp_option *option)
+static int __devinit check_resources(struct pnp_dev *dev)
 {
-	struct pnp_option *tmp;
-	if (!option)
-		return 0;
+	resource_size_t base[] = {0x2f8, 0x3f8, 0x2e8, 0x3e8};
+	int i;
 
-	for (tmp = option; tmp; tmp = tmp->next) {
-		struct pnp_port *port;
-		for (port = tmp->port; port; port = port->next)
-			if ((port->size == 8) &&
-			    ((port->min == 0x2f8) ||
-			     (port->min == 0x3f8) ||
-			     (port->min == 0x2e8) ||
-			     (port->min == 0x3e8)))
-				return 1;
+	for (i = 0; i < ARRAY_SIZE(base); i++) {
+		if (pnp_possible_config(dev, IORESOURCE_IO, base[i], 8))
+			return 1;
 	}
 
 	return 0;
@@ -420,10 +413,7 @@ static int __devinit serial_pnp_guess_bo
 		(dev->card && check_name(dev->card->name))))
 			return -ENODEV;
 
-	if (check_resources(dev->independent))
-		return 0;
-
-	if (check_resources(dev->dependent))
+	if (check_resources(dev))
 		return 0;
 
 	return -ENODEV;
Index: work10/include/linux/pnp.h
===================================================================
--- work10.orig/include/linux/pnp.h	2008-06-04 13:46:52.000000000 -0600
+++ work10/include/linux/pnp.h	2008-06-04 15:29:19.000000000 -0600
@@ -472,6 +472,8 @@ void pnp_unregister_card_driver(struct p
 extern struct list_head pnp_cards;
 
 /* resource management */
+int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t base,
+			resource_size_t size);
 int pnp_auto_config_dev(struct pnp_dev *dev);
 int pnp_start_dev(struct pnp_dev *dev);
 int pnp_stop_dev(struct pnp_dev *dev);
@@ -499,6 +501,7 @@ static inline int pnp_register_card_driv
 static inline void pnp_unregister_card_driver(struct pnp_card_driver *drv) { }
 
 /* resource management */
+static inline int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t base, resource_size_t size) { return 0; }
 static inline int pnp_auto_config_dev(struct pnp_dev *dev) { return -ENODEV; }
 static inline int pnp_start_dev(struct pnp_dev *dev) { return -ENODEV; }
 static inline int pnp_stop_dev(struct pnp_dev *dev) { return -ENODEV; }

-- 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [patch 02/18] PNP: whitespace/coding style fixes
  2008-06-04 22:09 [patch 00/18] PNP: convert resource options to unified dynamic list, v2 Bjorn Helgaas
  2008-06-04 22:09 ` [patch 01/18] PNP: add pnp_possible_config() -- can a device could be configured this way? Bjorn Helgaas
@ 2008-06-04 22:09 ` Bjorn Helgaas
  2008-06-04 22:09 ` [patch 03/18] PNP: IORESOURCE_* flags are PNP-specific, not ISA PNP-specific Bjorn Helgaas
                   ` (16 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Bjorn Helgaas @ 2008-06-04 22:09 UTC (permalink / raw)
  To: Len Brown
  Cc: linux-acpi, Rene Herman, linux-kernel, Adam Belay, Adam M Belay,
	Li Shaohua, Matthieu Castet, Thomas Renninger, Rene Herman,
	Jaroslav Kysela, Andrew Morton, Takashi Iwai

[-- Attachment #1: pnp-interface-style --]
[-- Type: text/plain, Size: 1897 bytes --]

No functional change; just make a couple declarations
consistent with the rest of the file.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>

Index: work10/drivers/pnp/interface.c
===================================================================
--- work10.orig/drivers/pnp/interface.c	2008-05-09 14:42:25.000000000 -0600
+++ work10/drivers/pnp/interface.c	2008-05-09 14:45:57.000000000 -0600
@@ -216,12 +216,12 @@ static ssize_t pnp_show_options(struct d
 				struct device_attribute *attr, char *buf)
 {
 	struct pnp_dev *dev = to_pnp_dev(dmdev);
+	pnp_info_buffer_t *buffer;
 	struct pnp_option *independent = dev->independent;
 	struct pnp_option *dependent = dev->dependent;
 	int ret, dep = 1;
 
-	pnp_info_buffer_t *buffer = (pnp_info_buffer_t *)
-	    pnp_alloc(sizeof(pnp_info_buffer_t));
+	buffer = pnp_alloc(sizeof(pnp_info_buffer_t));
 	if (!buffer)
 		return -ENOMEM;
 
@@ -248,17 +248,18 @@ static ssize_t pnp_show_current_resource
 					  char *buf)
 {
 	struct pnp_dev *dev = to_pnp_dev(dmdev);
+	pnp_info_buffer_t *buffer;
 	struct pnp_resource *pnp_res;
 	struct resource *res;
 	int ret;
-	pnp_info_buffer_t *buffer;
 
 	if (!dev)
 		return -EINVAL;
 
-	buffer = (pnp_info_buffer_t *) pnp_alloc(sizeof(pnp_info_buffer_t));
+	buffer = pnp_alloc(sizeof(pnp_info_buffer_t));
 	if (!buffer)
 		return -ENOMEM;
+
 	buffer->len = PAGE_SIZE;
 	buffer->buffer = buf;
 	buffer->curr = buffer->buffer;
@@ -295,9 +296,9 @@ static ssize_t pnp_show_current_resource
 	return ret;
 }
 
-static ssize_t
-pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
-			  const char *ubuf, size_t count)
+static ssize_t pnp_set_current_resources(struct device *dmdev,
+					 struct device_attribute *attr,
+					 const char *ubuf, size_t count)
 {
 	struct pnp_dev *dev = to_pnp_dev(dmdev);
 	char *buf = (void *)ubuf;

-- 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [patch 03/18] PNP: IORESOURCE_* flags are PNP-specific, not ISA PNP-specific
  2008-06-04 22:09 [patch 00/18] PNP: convert resource options to unified dynamic list, v2 Bjorn Helgaas
  2008-06-04 22:09 ` [patch 01/18] PNP: add pnp_possible_config() -- can a device could be configured this way? Bjorn Helgaas
  2008-06-04 22:09 ` [patch 02/18] PNP: whitespace/coding style fixes Bjorn Helgaas
@ 2008-06-04 22:09 ` Bjorn Helgaas
  2008-06-14  8:06   ` Rene Herman
  2008-06-04 22:09 ` [patch 04/18] PNP: define PNP-specific IORESOURCE_IO_* flags alongside IRQ, DMA, MEM Bjorn Helgaas
                   ` (15 subsequent siblings)
  18 siblings, 1 reply; 31+ messages in thread
From: Bjorn Helgaas @ 2008-06-04 22:09 UTC (permalink / raw)
  To: Len Brown
  Cc: linux-acpi, linux-kernel, Adam Belay, Adam M Belay, Li Shaohua,
	Matthieu Castet, Thomas Renninger, Rene Herman, Jaroslav Kysela,
	Andrew Morton, Takashi Iwai

[-- Attachment #1: pnp-ioresource-comment-fix --]
[-- Type: text/plain, Size: 1781 bytes --]

Change comments on the bus-specific IORESOURCE bit definitions
to indicate the PNP ones are not ISA-specific.  They are used
by PNPBIOS and PNPACPI in addition to ISAPNP.

Rene Herman <rene.herman@gmail.com> wrote this patch:
    http://marc.info/?l=linux-acpi&m=121200787202959&w=4.
I picked it up to resolve conflicts with other patches.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>

Index: work10/include/linux/ioport.h
===================================================================
--- work10.orig/include/linux/ioport.h	2008-06-03 14:22:29.000000000 -0600
+++ work10/include/linux/ioport.h	2008-06-03 14:32:52.000000000 -0600
@@ -53,14 +53,14 @@ struct resource_list {
 #define IORESOURCE_AUTO		0x40000000
 #define IORESOURCE_BUSY		0x80000000	/* Driver has marked this resource busy */
 
-/* ISA PnP IRQ specific bits (IORESOURCE_BITS) */
+/* PnP IRQ specific bits (IORESOURCE_BITS) */
 #define IORESOURCE_IRQ_HIGHEDGE		(1<<0)
 #define IORESOURCE_IRQ_LOWEDGE		(1<<1)
 #define IORESOURCE_IRQ_HIGHLEVEL	(1<<2)
 #define IORESOURCE_IRQ_LOWLEVEL		(1<<3)
 #define IORESOURCE_IRQ_SHAREABLE	(1<<4)
 
-/* ISA PnP DMA specific bits (IORESOURCE_BITS) */
+/* PnP DMA specific bits (IORESOURCE_BITS) */
 #define IORESOURCE_DMA_TYPE_MASK	(3<<0)
 #define IORESOURCE_DMA_8BIT		(0<<0)
 #define IORESOURCE_DMA_8AND16BIT	(1<<0)
@@ -76,7 +76,7 @@ struct resource_list {
 #define IORESOURCE_DMA_TYPEB		(2<<6)
 #define IORESOURCE_DMA_TYPEF		(3<<6)
 
-/* ISA PnP memory I/O specific bits (IORESOURCE_BITS) */
+/* PnP memory specific bits (IORESOURCE_BITS) */
 #define IORESOURCE_MEM_WRITEABLE	(1<<0)	/* dup: IORESOURCE_READONLY */
 #define IORESOURCE_MEM_CACHEABLE	(1<<1)	/* dup: IORESOURCE_CACHEABLE */
 #define IORESOURCE_MEM_RANGELENGTH	(1<<2)	/* dup: IORESOURCE_RANGELENGTH */

-- 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [patch 04/18] PNP: define PNP-specific IORESOURCE_IO_* flags alongside IRQ, DMA, MEM
  2008-06-04 22:09 [patch 00/18] PNP: convert resource options to unified dynamic list, v2 Bjorn Helgaas
                   ` (2 preceding siblings ...)
  2008-06-04 22:09 ` [patch 03/18] PNP: IORESOURCE_* flags are PNP-specific, not ISA PNP-specific Bjorn Helgaas
@ 2008-06-04 22:09 ` Bjorn Helgaas
  2008-06-04 22:09 ` [patch 05/18] PNP: make resource option structures private to PNP subsystem Bjorn Helgaas
                   ` (14 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Bjorn Helgaas @ 2008-06-04 22:09 UTC (permalink / raw)
  To: Len Brown
  Cc: linux-acpi, Rene Herman, linux-kernel, Adam Belay, Adam M Belay,
	Li Shaohua, Matthieu Castet, Thomas Renninger, Rene Herman,
	Jaroslav Kysela, Andrew Morton, Takashi Iwai

[-- Attachment #1: pnp-io-option-flags --]
[-- Type: text/plain, Size: 6075 bytes --]

PNP previously defined PNP_PORT_FLAG_16BITADDR and PNP_PORT_FLAG_FIXED
in a private header file, but put those flags in struct resource.flags
fields.  Better to make them IORESOURCE_IO_* flags like the existing
IRQ, DMA, and MEM flags.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>

---
 include/linux/ioport.h         |   10 +++++++---
 include/linux/pnp.h            |    3 ---
 drivers/pnp/interface.c        |    2 +-
 drivers/pnp/isapnp/core.c      |    4 ++--
 drivers/pnp/pnpacpi/rsparser.c |   10 +++++-----
 drivers/pnp/pnpbios/rsparser.c |    4 ++--
 6 files changed, 17 insertions(+), 16 deletions(-)

Index: work10/include/linux/ioport.h
===================================================================
--- work10.orig/include/linux/ioport.h	2008-06-03 14:32:52.000000000 -0600
+++ work10/include/linux/ioport.h	2008-06-03 14:33:22.000000000 -0600
@@ -88,6 +88,10 @@ struct resource_list {
 #define IORESOURCE_MEM_SHADOWABLE	(1<<5)	/* dup: IORESOURCE_SHADOWABLE */
 #define IORESOURCE_MEM_EXPANSIONROM	(1<<6)
 
+/* PnP I/O specific bits (IORESOURCE_BITS) */
+#define IORESOURCE_IO_16BIT_ADDR	(1<<0)
+#define IORESOURCE_IO_FIXED		(1<<1)
+
 /* PCI ROM control bits (IORESOURCE_BITS) */
 #define IORESOURCE_ROM_ENABLE		(1<<0)	/* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */
 #define IORESOURCE_ROM_SHADOW		(1<<1)	/* ROM is copy at C000:0 */
Index: work10/include/linux/pnp.h
===================================================================
--- work10.orig/include/linux/pnp.h	2008-06-03 14:32:38.000000000 -0600
+++ work10/include/linux/pnp.h	2008-06-03 14:33:01.000000000 -0600
@@ -175,9 +175,6 @@ static inline int pnp_dma_valid(struct p
 }
 
 
-#define PNP_PORT_FLAG_16BITADDR	(1<<0)
-#define PNP_PORT_FLAG_FIXED	(1<<1)
-
 struct pnp_port {
 	unsigned short min;	/* min base number */
 	unsigned short max;	/* max base number */
Index: work10/drivers/pnp/interface.c
===================================================================
--- work10.orig/drivers/pnp/interface.c	2008-06-03 14:32:38.000000000 -0600
+++ work10/drivers/pnp/interface.c	2008-06-03 14:33:01.000000000 -0600
@@ -57,7 +57,7 @@ static void pnp_print_port(pnp_info_buff
 		   "%sport 0x%x-0x%x, align 0x%x, size 0x%x, %i-bit address decoding\n",
 		   space, port->min, port->max,
 		   port->align ? (port->align - 1) : 0, port->size,
-		   port->flags & PNP_PORT_FLAG_16BITADDR ? 16 : 10);
+		   port->flags & IORESOURCE_IO_16BIT_ADDR ? 16 : 10);
 }
 
 static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space,
Index: work10/drivers/pnp/isapnp/core.c
===================================================================
--- work10.orig/drivers/pnp/isapnp/core.c	2008-06-03 14:32:38.000000000 -0600
+++ work10/drivers/pnp/isapnp/core.c	2008-06-03 14:33:01.000000000 -0600
@@ -486,7 +486,7 @@ static void __init isapnp_parse_port_res
 	port->max = (tmp[4] << 8) | tmp[3];
 	port->align = tmp[5];
 	port->size = tmp[6];
-	port->flags = tmp[0] ? PNP_PORT_FLAG_16BITADDR : 0;
+	port->flags = tmp[0] ? IORESOURCE_IO_16BIT_ADDR : 0;
 	pnp_register_port_resource(dev, option, port);
 }
 
@@ -507,7 +507,7 @@ static void __init isapnp_parse_fixed_po
 	port->min = port->max = (tmp[1] << 8) | tmp[0];
 	port->size = tmp[2];
 	port->align = 0;
-	port->flags = PNP_PORT_FLAG_FIXED;
+	port->flags = IORESOURCE_IO_FIXED;
 	pnp_register_port_resource(dev, option, port);
 }
 
Index: work10/drivers/pnp/pnpacpi/rsparser.c
===================================================================
--- work10.orig/drivers/pnp/pnpacpi/rsparser.c	2008-06-03 14:32:38.000000000 -0600
+++ work10/drivers/pnp/pnpacpi/rsparser.c	2008-06-03 14:33:01.000000000 -0600
@@ -178,7 +178,7 @@ static void pnpacpi_parse_allocated_iore
 	u64 end = start + len - 1;
 
 	if (io_decode == ACPI_DECODE_16)
-		flags |= PNP_PORT_FLAG_16BITADDR;
+		flags |= IORESOURCE_IO_16BIT_ADDR;
 	if (len == 0 || end >= 0x10003)
 		flags |= IORESOURCE_DISABLED;
 
@@ -451,7 +451,7 @@ static __init void pnpacpi_parse_port_op
 	port->align = io->alignment;
 	port->size = io->address_length;
 	port->flags = ACPI_DECODE_16 == io->io_decode ?
-	    PNP_PORT_FLAG_16BITADDR : 0;
+	    IORESOURCE_IO_16BIT_ADDR : 0;
 	pnp_register_port_resource(dev, option, port);
 }
 
@@ -469,7 +469,7 @@ static __init void pnpacpi_parse_fixed_p
 	port->min = port->max = io->address;
 	port->size = io->address_length;
 	port->align = 0;
-	port->flags = PNP_PORT_FLAG_FIXED;
+	port->flags = IORESOURCE_IO_FIXED;
 	pnp_register_port_resource(dev, option, port);
 }
 
@@ -575,7 +575,7 @@ static __init void pnpacpi_parse_address
 		port->min = port->max = p->minimum;
 		port->size = p->address_length;
 		port->align = 0;
-		port->flags = PNP_PORT_FLAG_FIXED;
+		port->flags = IORESOURCE_IO_FIXED;
 		pnp_register_port_resource(dev, option, port);
 	}
 }
@@ -890,7 +890,7 @@ static void pnpacpi_encode_io(struct pnp
 	struct acpi_resource_io *io = &resource->data.io;
 
 	/* Note: pnp_assign_port will copy pnp_port->flags into p->flags */
-	io->io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR) ?
+	io->io_decode = (p->flags & IORESOURCE_IO_16BIT_ADDR) ?
 	    ACPI_DECODE_16 : ACPI_DECODE_10;
 	io->minimum = p->start;
 	io->maximum = p->end;
Index: work10/drivers/pnp/pnpbios/rsparser.c
===================================================================
--- work10.orig/drivers/pnp/pnpbios/rsparser.c	2008-06-03 14:32:38.000000000 -0600
+++ work10/drivers/pnp/pnpbios/rsparser.c	2008-06-03 14:33:01.000000000 -0600
@@ -310,7 +310,7 @@ static __init void pnpbios_parse_port_op
 	port->max = (p[5] << 8) | p[4];
 	port->align = p[6];
 	port->size = p[7];
-	port->flags = p[1] ? PNP_PORT_FLAG_16BITADDR : 0;
+	port->flags = p[1] ? IORESOURCE_IO_16BIT_ADDR : 0;
 	pnp_register_port_resource(dev, option, port);
 }
 
@@ -326,7 +326,7 @@ static __init void pnpbios_parse_fixed_p
 	port->min = port->max = (p[2] << 8) | p[1];
 	port->size = p[3];
 	port->align = 0;
-	port->flags = PNP_PORT_FLAG_FIXED;
+	port->flags = IORESOURCE_IO_FIXED;
 	pnp_register_port_resource(dev, option, port);
 }
 

-- 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [patch 05/18] PNP: make resource option structures private to PNP subsystem
  2008-06-04 22:09 [patch 00/18] PNP: convert resource options to unified dynamic list, v2 Bjorn Helgaas
                   ` (3 preceding siblings ...)
  2008-06-04 22:09 ` [patch 04/18] PNP: define PNP-specific IORESOURCE_IO_* flags alongside IRQ, DMA, MEM Bjorn Helgaas
@ 2008-06-04 22:09 ` Bjorn Helgaas
  2008-06-14  8:07   ` Rene Herman
  2008-06-04 22:09 ` [patch 06/18] PNP: introduce pnp_irq_mask_t typedef Bjorn Helgaas
                   ` (13 subsequent siblings)
  18 siblings, 1 reply; 31+ messages in thread
From: Bjorn Helgaas @ 2008-06-04 22:09 UTC (permalink / raw)
  To: Len Brown
  Cc: linux-acpi, linux-kernel, Adam Belay, Adam M Belay, Li Shaohua,
	Matthieu Castet, Thomas Renninger, Rene Herman, Jaroslav Kysela,
	Andrew Morton, Takashi Iwai

[-- Attachment #1: pnp-make-option-structures-private --]
[-- Type: text/plain, Size: 4125 bytes --]

Nothing outside the PNP subsystem should need access to a
device's resource options, so this patch moves the option
structure declarations to a private header file.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>

Index: work10/drivers/pnp/base.h
===================================================================
--- work10.orig/drivers/pnp/base.h	2008-05-16 16:10:32.000000000 -0600
+++ work10/drivers/pnp/base.h	2008-05-16 16:10:56.000000000 -0600
@@ -19,6 +19,54 @@ void pnp_remove_card(struct pnp_card *ca
 int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev);
 void pnp_remove_card_device(struct pnp_dev *dev);
 
+struct pnp_port {
+	unsigned short min;	/* min base number */
+	unsigned short max;	/* max base number */
+	unsigned char align;	/* align boundary */
+	unsigned char size;	/* size of range */
+	unsigned char flags;	/* port flags */
+	unsigned char pad;	/* pad */
+	struct pnp_port *next;	/* next port */
+};
+
+#define PNP_IRQ_NR 256
+struct pnp_irq {
+	DECLARE_BITMAP(map, PNP_IRQ_NR);	/* bitmask for IRQ lines */
+	unsigned char flags;	/* IRQ flags */
+	unsigned char pad;	/* pad */
+	struct pnp_irq *next;	/* next IRQ */
+};
+
+struct pnp_dma {
+	unsigned char map;	/* bitmask for DMA channels */
+	unsigned char flags;	/* DMA flags */
+	struct pnp_dma *next;	/* next port */
+};
+
+struct pnp_mem {
+	unsigned int min;	/* min base number */
+	unsigned int max;	/* max base number */
+	unsigned int align;	/* align boundary */
+	unsigned int size;	/* size of range */
+	unsigned char flags;	/* memory flags */
+	unsigned char pad;	/* pad */
+	struct pnp_mem *next;	/* next memory resource */
+};
+
+#define PNP_RES_PRIORITY_PREFERRED	0
+#define PNP_RES_PRIORITY_ACCEPTABLE	1
+#define PNP_RES_PRIORITY_FUNCTIONAL	2
+#define PNP_RES_PRIORITY_INVALID	65535
+
+struct pnp_option {
+	unsigned short priority;	/* priority */
+	struct pnp_port *port;		/* first port */
+	struct pnp_irq *irq;		/* first IRQ */
+	struct pnp_dma *dma;		/* first DMA */
+	struct pnp_mem *mem;		/* first memory resource */
+	struct pnp_option *next;	/* used to chain dependent resources */
+};
+
 struct pnp_option *pnp_build_option(int priority);
 struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev);
 struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev,
Index: work10/include/linux/pnp.h
===================================================================
--- work10.orig/include/linux/pnp.h	2008-05-16 16:11:01.000000000 -0600
+++ work10/include/linux/pnp.h	2008-05-16 16:11:12.000000000 -0600
@@ -175,54 +175,6 @@ static inline int pnp_dma_valid(struct p
 }
 
 
-struct pnp_port {
-	unsigned short min;	/* min base number */
-	unsigned short max;	/* max base number */
-	unsigned char align;	/* align boundary */
-	unsigned char size;	/* size of range */
-	unsigned char flags;	/* port flags */
-	unsigned char pad;	/* pad */
-	struct pnp_port *next;	/* next port */
-};
-
-#define PNP_IRQ_NR 256
-struct pnp_irq {
-	DECLARE_BITMAP(map, PNP_IRQ_NR);	/* bitmask for IRQ lines */
-	unsigned char flags;	/* IRQ flags */
-	unsigned char pad;	/* pad */
-	struct pnp_irq *next;	/* next IRQ */
-};
-
-struct pnp_dma {
-	unsigned char map;	/* bitmask for DMA channels */
-	unsigned char flags;	/* DMA flags */
-	struct pnp_dma *next;	/* next port */
-};
-
-struct pnp_mem {
-	unsigned int min;	/* min base number */
-	unsigned int max;	/* max base number */
-	unsigned int align;	/* align boundary */
-	unsigned int size;	/* size of range */
-	unsigned char flags;	/* memory flags */
-	unsigned char pad;	/* pad */
-	struct pnp_mem *next;	/* next memory resource */
-};
-
-#define PNP_RES_PRIORITY_PREFERRED	0
-#define PNP_RES_PRIORITY_ACCEPTABLE	1
-#define PNP_RES_PRIORITY_FUNCTIONAL	2
-#define PNP_RES_PRIORITY_INVALID	65535
-
-struct pnp_option {
-	unsigned short priority;	/* priority */
-	struct pnp_port *port;		/* first port */
-	struct pnp_irq *irq;		/* first IRQ */
-	struct pnp_dma *dma;		/* first DMA */
-	struct pnp_mem *mem;		/* first memory resource */
-	struct pnp_option *next;	/* used to chain dependent resources */
-};
-
 /*
  * Device Management
  */

-- 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [patch 06/18] PNP: introduce pnp_irq_mask_t typedef
  2008-06-04 22:09 [patch 00/18] PNP: convert resource options to unified dynamic list, v2 Bjorn Helgaas
                   ` (4 preceding siblings ...)
  2008-06-04 22:09 ` [patch 05/18] PNP: make resource option structures private to PNP subsystem Bjorn Helgaas
@ 2008-06-04 22:09 ` Bjorn Helgaas
  2008-06-04 22:09 ` [patch 07/18] PNP: increase I/O port & memory option address sizes Bjorn Helgaas
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Bjorn Helgaas @ 2008-06-04 22:09 UTC (permalink / raw)
  To: Len Brown
  Cc: linux-acpi, Rene Herman, linux-kernel, Adam Belay, Adam M Belay,
	Li Shaohua, Matthieu Castet, Thomas Renninger, Rene Herman,
	Jaroslav Kysela, Andrew Morton, Takashi Iwai

[-- Attachment #1: pnp-irq-bitmap-decl --]
[-- Type: text/plain, Size: 6519 bytes --]

This adds a typedef for the IRQ bitmap, which should cause
no functional change, but will make it easier to pass a
pointer to a bitmap to pnp_register_irq_resource().

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>

Index: work10/drivers/pnp/base.h
===================================================================
--- work10.orig/drivers/pnp/base.h	2008-06-04 15:38:19.000000000 -0600
+++ work10/drivers/pnp/base.h	2008-06-04 15:38:25.000000000 -0600
@@ -30,8 +30,10 @@ struct pnp_port {
 };
 
 #define PNP_IRQ_NR 256
+typedef struct { DECLARE_BITMAP(bits, PNP_IRQ_NR); } pnp_irq_mask_t;
+
 struct pnp_irq {
-	DECLARE_BITMAP(map, PNP_IRQ_NR);	/* bitmask for IRQ lines */
+	pnp_irq_mask_t map;	/* bitmap for IRQ lines */
 	unsigned char flags;	/* IRQ flags */
 	unsigned char pad;	/* pad */
 	struct pnp_irq *next;	/* next IRQ */
Index: work10/drivers/pnp/resource.c
===================================================================
--- work10.orig/drivers/pnp/resource.c	2008-06-04 15:30:51.000000000 -0600
+++ work10/drivers/pnp/resource.c	2008-06-04 15:39:10.000000000 -0600
@@ -98,13 +98,13 @@ int pnp_register_irq_resource(struct pnp
 		int i;
 
 		for (i = 0; i < 16; i++)
-			if (test_bit(i, data->map))
+			if (test_bit(i, data->map.bits))
 				pcibios_penalize_isa_irq(i, 0);
 	}
 #endif
 
 #ifdef DEBUG
-	bitmap_scnprintf(buf, sizeof(buf), data->map, PNP_IRQ_NR);
+	bitmap_scnprintf(buf, sizeof(buf), data->map.bits, PNP_IRQ_NR);
 	dev_dbg(&dev->dev, "  irq bitmask %s flags %#x\n", buf,
 		data->flags);
 #endif
@@ -653,7 +653,7 @@ static int pnp_possible_option(struct pn
 		case IORESOURCE_IRQ:
 			for (irq = tmp->irq; irq; irq = irq->next) {
 				if (start < PNP_IRQ_NR &&
-				    test_bit(start, irq->map))
+				    test_bit(start, irq->map.bits))
 					return 1;
 			}
 			break;
Index: work10/drivers/pnp/manager.c
===================================================================
--- work10.orig/drivers/pnp/manager.c	2008-06-04 15:28:38.000000000 -0600
+++ work10/drivers/pnp/manager.c	2008-06-04 15:38:25.000000000 -0600
@@ -128,20 +128,20 @@ static int pnp_assign_irq(struct pnp_dev
 	res->start = -1;
 	res->end = -1;
 
-	if (bitmap_empty(rule->map, PNP_IRQ_NR)) {
+	if (bitmap_empty(rule->map.bits, PNP_IRQ_NR)) {
 		res->flags |= IORESOURCE_DISABLED;
 		dev_dbg(&dev->dev, "  irq %d disabled\n", idx);
 		goto __add;
 	}
 
 	/* TBD: need check for >16 IRQ */
-	res->start = find_next_bit(rule->map, PNP_IRQ_NR, 16);
+	res->start = find_next_bit(rule->map.bits, PNP_IRQ_NR, 16);
 	if (res->start < PNP_IRQ_NR) {
 		res->end = res->start;
 		goto __add;
 	}
 	for (i = 0; i < 16; i++) {
-		if (test_bit(xtab[i], rule->map)) {
+		if (test_bit(xtab[i], rule->map.bits)) {
 			res->start = res->end = xtab[i];
 			if (pnp_check_irq(dev, res))
 				goto __add;
Index: work10/drivers/pnp/interface.c
===================================================================
--- work10.orig/drivers/pnp/interface.c	2008-06-04 15:38:18.000000000 -0600
+++ work10/drivers/pnp/interface.c	2008-06-04 15:38:25.000000000 -0600
@@ -67,7 +67,7 @@ static void pnp_print_irq(pnp_info_buffe
 
 	pnp_printf(buffer, "%sirq ", space);
 	for (i = 0; i < PNP_IRQ_NR; i++)
-		if (test_bit(i, irq->map)) {
+		if (test_bit(i, irq->map.bits)) {
 			if (!first) {
 				pnp_printf(buffer, ",");
 			} else {
@@ -78,7 +78,7 @@ static void pnp_print_irq(pnp_info_buffe
 			else
 				pnp_printf(buffer, "%i", i);
 		}
-	if (bitmap_empty(irq->map, PNP_IRQ_NR))
+	if (bitmap_empty(irq->map.bits, PNP_IRQ_NR))
 		pnp_printf(buffer, "<none>");
 	if (irq->flags & IORESOURCE_IRQ_HIGHEDGE)
 		pnp_printf(buffer, " High-Edge");
Index: work10/drivers/pnp/isapnp/core.c
===================================================================
--- work10.orig/drivers/pnp/isapnp/core.c	2008-06-04 15:38:18.000000000 -0600
+++ work10/drivers/pnp/isapnp/core.c	2008-06-04 15:38:25.000000000 -0600
@@ -441,7 +441,7 @@ static void __init isapnp_parse_irq_reso
 	if (!irq)
 		return;
 	bits = (tmp[1] << 8) | tmp[0];
-	bitmap_copy(irq->map, &bits, 16);
+	bitmap_copy(irq->map.bits, &bits, 16);
 	if (size > 2)
 		irq->flags = tmp[2];
 	else
Index: work10/drivers/pnp/pnpacpi/rsparser.c
===================================================================
--- work10.orig/drivers/pnp/pnpacpi/rsparser.c	2008-06-04 15:38:18.000000000 -0600
+++ work10/drivers/pnp/pnpacpi/rsparser.c	2008-06-04 15:38:25.000000000 -0600
@@ -408,7 +408,7 @@ static __init void pnpacpi_parse_irq_opt
 
 	for (i = 0; i < p->interrupt_count; i++)
 		if (p->interrupts[i])
-			__set_bit(p->interrupts[i], irq->map);
+			__set_bit(p->interrupts[i], irq->map.bits);
 	irq->flags = irq_flags(p->triggering, p->polarity, p->sharable);
 
 	pnp_register_irq_resource(dev, option, irq);
@@ -429,7 +429,7 @@ static __init void pnpacpi_parse_ext_irq
 
 	for (i = 0; i < p->interrupt_count; i++)
 		if (p->interrupts[i])
-			__set_bit(p->interrupts[i], irq->map);
+			__set_bit(p->interrupts[i], irq->map.bits);
 	irq->flags = irq_flags(p->triggering, p->polarity, p->sharable);
 
 	pnp_register_irq_resource(dev, option, irq);
Index: work10/drivers/pnp/quirks.c
===================================================================
--- work10.orig/drivers/pnp/quirks.c	2008-06-04 15:28:38.000000000 -0600
+++ work10/drivers/pnp/quirks.c	2008-06-04 15:38:25.000000000 -0600
@@ -68,7 +68,7 @@ static void quirk_cmi8330_resources(stru
 
 		for (irq = res->irq; irq; irq = irq->next) {	// Valid irqs are 5, 7, 10
 			tmp = 0x04A0;
-			bitmap_copy(irq->map, &tmp, 16);	// 0000 0100 1010 0000
+			bitmap_copy(irq->map.bits, &tmp, 16);	// 0000 0100 1010 0000
 		}
 
 		for (dma = res->dma; dma; dma = dma->next)	// Valid 8bit dma channels are 1,3
@@ -187,7 +187,7 @@ static void quirk_ad1815_mpu_resources(s
 		if (!copy)
 			break;
 
-		memcpy(copy->map, irq->map, sizeof copy->map);
+		bitmap_copy(copy->map.bits, irq->map.bits, PNP_IRQ_NR);
 		copy->flags = irq->flags;
 
 		copy->next = res->irq; /* Yes, this is NULL */
Index: work10/drivers/pnp/pnpbios/rsparser.c
===================================================================
--- work10.orig/drivers/pnp/pnpbios/rsparser.c	2008-06-04 15:38:18.000000000 -0600
+++ work10/drivers/pnp/pnpbios/rsparser.c	2008-06-04 15:38:25.000000000 -0600
@@ -275,7 +275,7 @@ static __init void pnpbios_parse_irq_opt
 	if (!irq)
 		return;
 	bits = (p[2] << 8) | p[1];
-	bitmap_copy(irq->map, &bits, 16);
+	bitmap_copy(irq->map.bits, &bits, 16);
 	if (size > 2)
 		irq->flags = p[3];
 	else

-- 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [patch 07/18] PNP: increase I/O port & memory option address sizes
  2008-06-04 22:09 [patch 00/18] PNP: convert resource options to unified dynamic list, v2 Bjorn Helgaas
                   ` (5 preceding siblings ...)
  2008-06-04 22:09 ` [patch 06/18] PNP: introduce pnp_irq_mask_t typedef Bjorn Helgaas
@ 2008-06-04 22:09 ` Bjorn Helgaas
  2008-06-04 22:09 ` [patch 08/18] PNP: improve resource assignment debug Bjorn Helgaas
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Bjorn Helgaas @ 2008-06-04 22:09 UTC (permalink / raw)
  To: Len Brown
  Cc: linux-acpi, Rene Herman, linux-kernel, Adam Belay, Adam M Belay,
	Li Shaohua, Matthieu Castet, Thomas Renninger, Rene Herman,
	Jaroslav Kysela, Andrew Morton, Takashi Iwai

[-- Attachment #1: pnp-option-resource-size --]
[-- Type: text/plain, Size: 4617 bytes --]

ACPI Address Space Descriptors can be up to 64 bits wide.
We should keep track of the whole thing when parsing resource
options, so this patch changes PNP port and mem option
fields from "unsigned short" and "unsigned int" to
"resource_size_t".

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>

---
 drivers/pnp/base.h      |   16 ++++++++--------
 drivers/pnp/interface.c |   17 +++++++++++------
 drivers/pnp/resource.c  |   14 ++++++++++----
 3 files changed, 29 insertions(+), 18 deletions(-)

Index: work10/drivers/pnp/base.h
===================================================================
--- work10.orig/drivers/pnp/base.h	2008-05-16 16:13:34.000000000 -0600
+++ work10/drivers/pnp/base.h	2008-05-16 16:13:37.000000000 -0600
@@ -20,10 +20,10 @@ int pnp_add_card_device(struct pnp_card 
 void pnp_remove_card_device(struct pnp_dev *dev);
 
 struct pnp_port {
-	unsigned short min;	/* min base number */
-	unsigned short max;	/* max base number */
-	unsigned char align;	/* align boundary */
-	unsigned char size;	/* size of range */
+	resource_size_t min;	/* min base number */
+	resource_size_t max;	/* max base number */
+	resource_size_t align;	/* align boundary */
+	resource_size_t size;	/* size of range */
 	unsigned char flags;	/* port flags */
 	unsigned char pad;	/* pad */
 	struct pnp_port *next;	/* next port */
@@ -46,10 +46,10 @@ struct pnp_dma {
 };
 
 struct pnp_mem {
-	unsigned int min;	/* min base number */
-	unsigned int max;	/* max base number */
-	unsigned int align;	/* align boundary */
-	unsigned int size;	/* size of range */
+	resource_size_t min;	/* min base number */
+	resource_size_t max;	/* max base number */
+	resource_size_t align;	/* align boundary */
+	resource_size_t size;	/* size of range */
 	unsigned char flags;	/* memory flags */
 	unsigned char pad;	/* pad */
 	struct pnp_mem *next;	/* next memory resource */
Index: work10/drivers/pnp/interface.c
===================================================================
--- work10.orig/drivers/pnp/interface.c	2008-05-16 16:13:34.000000000 -0600
+++ work10/drivers/pnp/interface.c	2008-05-16 16:13:37.000000000 -0600
@@ -53,10 +53,12 @@ static int pnp_printf(pnp_info_buffer_t 
 static void pnp_print_port(pnp_info_buffer_t * buffer, char *space,
 			   struct pnp_port *port)
 {
-	pnp_printf(buffer,
-		   "%sport 0x%x-0x%x, align 0x%x, size 0x%x, %i-bit address decoding\n",
-		   space, port->min, port->max,
-		   port->align ? (port->align - 1) : 0, port->size,
+	pnp_printf(buffer, "%sport %#llx-%#llx, align %#llx, size %#llx, "
+		   "%i-bit address decoding\n", space,
+		   (unsigned long long) port->min,
+		   (unsigned long long) port->max,
+		   port->align ? ((unsigned long long) port->align - 1) : 0,
+		   (unsigned long long) port->size,
 		   port->flags & IORESOURCE_IO_16BIT_ADDR ? 16 : 10);
 }
 
@@ -148,8 +150,11 @@ static void pnp_print_mem(pnp_info_buffe
 {
 	char *s;
 
-	pnp_printf(buffer, "%sMemory 0x%x-0x%x, align 0x%x, size 0x%x",
-		   space, mem->min, mem->max, mem->align, mem->size);
+	pnp_printf(buffer, "%sMemory %#llx-%#llx, align %#llx, size %#llx",
+		   space, (unsigned long long) mem->min,
+		   (unsigned long long) mem->max,
+		   (unsigned long long) mem->align,
+		   (unsigned long long) mem->size);
 	if (mem->flags & IORESOURCE_MEM_WRITEABLE)
 		pnp_printf(buffer, ", writeable");
 	if (mem->flags & IORESOURCE_MEM_CACHEABLE)
Index: work10/drivers/pnp/resource.c
===================================================================
--- work10.orig/drivers/pnp/resource.c	2008-05-16 16:13:34.000000000 -0600
+++ work10/drivers/pnp/resource.c	2008-05-16 16:13:37.000000000 -0600
@@ -143,8 +143,11 @@ int pnp_register_port_resource(struct pn
 		option->port = data;
 
 	dev_dbg(&dev->dev, "  io  "
-		"min %#x max %#x align %d size %d flags %#x\n",
-		data->min, data->max, data->align, data->size, data->flags);
+		"min %#llx max %#llx align %lld size %lld flags %#x\n",
+		(unsigned long long) data->min,
+		(unsigned long long) data->max,
+		(unsigned long long) data->align,
+		(unsigned long long) data->size, data->flags);
 	return 0;
 }
 
@@ -162,8 +165,11 @@ int pnp_register_mem_resource(struct pnp
 		option->mem = data;
 
 	dev_dbg(&dev->dev, "  mem "
-		"min %#x max %#x align %d size %d flags %#x\n",
-		data->min, data->max, data->align, data->size, data->flags);
+		"min %#llx max %#llx align %lld size %lld flags %#x\n",
+		(unsigned long long) data->min,
+		(unsigned long long) data->max,
+		(unsigned long long) data->align,
+		(unsigned long long) data->size, data->flags);
 	return 0;
 }
 

-- 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [patch 08/18] PNP: improve resource assignment debug
  2008-06-04 22:09 [patch 00/18] PNP: convert resource options to unified dynamic list, v2 Bjorn Helgaas
                   ` (6 preceding siblings ...)
  2008-06-04 22:09 ` [patch 07/18] PNP: increase I/O port & memory option address sizes Bjorn Helgaas
@ 2008-06-04 22:09 ` Bjorn Helgaas
  2008-06-04 22:09 ` [patch 09/18] PNP: in debug resource dump, make empty list obvious Bjorn Helgaas
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Bjorn Helgaas @ 2008-06-04 22:09 UTC (permalink / raw)
  To: Len Brown
  Cc: linux-acpi, Rene Herman, linux-kernel, Adam Belay, Adam M Belay,
	Li Shaohua, Matthieu Castet, Thomas Renninger, Rene Herman,
	Jaroslav Kysela, Andrew Morton, Takashi Iwai

[-- Attachment #1: pnp-improve-assign-debug --]
[-- Type: text/plain, Size: 1326 bytes --]

When we fail to assign an I/O or MEM resource, include the min/max
in the debug output to help match it with the options.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>

Index: work10/drivers/pnp/manager.c
===================================================================
--- work10.orig/drivers/pnp/manager.c	2008-05-13 12:01:17.000000000 -0600
+++ work10/drivers/pnp/manager.c	2008-05-13 12:50:57.000000000 -0600
@@ -47,7 +47,10 @@ static int pnp_assign_port(struct pnp_de
 		res->start += rule->align;
 		res->end = res->start + rule->size - 1;
 		if (res->start > rule->max || !rule->align) {
-			dev_dbg(&dev->dev, "  couldn't assign io %d\n", idx);
+			dev_dbg(&dev->dev, "  couldn't assign io %d "
+				"(min %#llx max %#llx)\n", idx,
+				(unsigned long long) rule->min,
+				(unsigned long long) rule->max);
 			return 0;
 		}
 	}
@@ -96,7 +99,10 @@ static int pnp_assign_mem(struct pnp_dev
 		res->start += rule->align;
 		res->end = res->start + rule->size - 1;
 		if (res->start > rule->max || !rule->align) {
-			dev_dbg(&dev->dev, "  couldn't assign mem %d\n", idx);
+			dev_dbg(&dev->dev, "  couldn't assign mem %d "
+				"(min %#llx max %#llx)\n", idx,
+				(unsigned long long) rule->min,
+				(unsigned long long) rule->max);
 			return 0;
 		}
 	}

-- 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [patch 09/18] PNP: in debug resource dump, make empty list obvious
  2008-06-04 22:09 [patch 00/18] PNP: convert resource options to unified dynamic list, v2 Bjorn Helgaas
                   ` (7 preceding siblings ...)
  2008-06-04 22:09 ` [patch 08/18] PNP: improve resource assignment debug Bjorn Helgaas
@ 2008-06-04 22:09 ` Bjorn Helgaas
  2008-06-04 22:09 ` [patch 10/18] PNP: make resource assignment functions return 0 (success) or -EBUSY (failure) Bjorn Helgaas
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Bjorn Helgaas @ 2008-06-04 22:09 UTC (permalink / raw)
  To: Len Brown
  Cc: linux-acpi, Rene Herman, linux-kernel, Adam Belay, Adam M Belay,
	Li Shaohua, Matthieu Castet, Thomas Renninger, Rene Herman,
	Jaroslav Kysela, Andrew Morton, Takashi Iwai

[-- Attachment #1: pnp-improve-debug-resource-dump --]
[-- Type: text/plain, Size: 1024 bytes --]

If the resource list is empty, say that explicitly.  Previously,
it was confusing because often the heading was followed by zero
resource lines, then some "add resource" lines from auto-assignment,
so the "add" lines looked like current resources.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>

Index: work10/drivers/pnp/support.c
===================================================================
--- work10.orig/drivers/pnp/support.c	2008-05-16 16:01:26.000000000 -0600
+++ work10/drivers/pnp/support.c	2008-05-16 16:13:42.000000000 -0600
@@ -77,7 +77,12 @@ void dbg_pnp_show_resources(struct pnp_d
 	struct pnp_resource *pnp_res;
 	struct resource *res;
 
-	dev_dbg(&dev->dev, "current resources: %s\n", desc);
+	if (list_empty(&dev->resources)) {
+		dev_dbg(&dev->dev, "%s: no current resources\n", desc);
+		return;
+	}
+
+	dev_dbg(&dev->dev, "%s: current resources:\n", desc);
 	list_for_each_entry(pnp_res, &dev->resources, list) {
 		res = &pnp_res->res;
 

-- 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [patch 10/18] PNP: make resource assignment functions return 0 (success) or -EBUSY (failure)
  2008-06-04 22:09 [patch 00/18] PNP: convert resource options to unified dynamic list, v2 Bjorn Helgaas
                   ` (8 preceding siblings ...)
  2008-06-04 22:09 ` [patch 09/18] PNP: in debug resource dump, make empty list obvious Bjorn Helgaas
@ 2008-06-04 22:09 ` Bjorn Helgaas
  2008-06-04 22:09 ` [patch 11/18] PNP: remove redundant pnp_can_configure() check Bjorn Helgaas
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Bjorn Helgaas @ 2008-06-04 22:09 UTC (permalink / raw)
  To: Len Brown
  Cc: linux-acpi, Rene Herman, linux-kernel, Adam Belay, Adam M Belay,
	Li Shaohua, Matthieu Castet, Thomas Renninger, Rene Herman,
	Jaroslav Kysela, Andrew Morton, Takashi Iwai

[-- Attachment #1: pnp-change-assignment-return-values --]
[-- Type: text/plain, Size: 4614 bytes --]

This patch doesn't change any behavior; it just makes the return
values more conventional.

This changes pnp_assign_dma() from a void function to one that
returns an int, just like the other assignment functions.  For
now, at least, pnp_assign_dma() always returns 0 (success), so
it appears to never fail, just like before.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>

Index: work10/drivers/pnp/manager.c
===================================================================
--- work10.orig/drivers/pnp/manager.c	2008-05-13 13:27:01.000000000 -0600
+++ work10/drivers/pnp/manager.c	2008-05-13 13:29:05.000000000 -0600
@@ -26,7 +26,7 @@ static int pnp_assign_port(struct pnp_de
 		dev_dbg(&dev->dev, "  io %d already set to %#llx-%#llx "
 			"flags %#lx\n", idx, (unsigned long long) res->start,
 			(unsigned long long) res->end, res->flags);
-		return 1;
+		return 0;
 	}
 
 	res = &local_res;
@@ -51,13 +51,13 @@ static int pnp_assign_port(struct pnp_de
 				"(min %#llx max %#llx)\n", idx,
 				(unsigned long long) rule->min,
 				(unsigned long long) rule->max);
-			return 0;
+			return -EBUSY;
 		}
 	}
 
 __add:
 	pnp_add_io_resource(dev, res->start, res->end, res->flags);
-	return 1;
+	return 0;
 }
 
 static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
@@ -69,7 +69,7 @@ static int pnp_assign_mem(struct pnp_dev
 		dev_dbg(&dev->dev, "  mem %d already set to %#llx-%#llx "
 			"flags %#lx\n", idx, (unsigned long long) res->start,
 			(unsigned long long) res->end, res->flags);
-		return 1;
+		return 0;
 	}
 
 	res = &local_res;
@@ -103,13 +103,13 @@ static int pnp_assign_mem(struct pnp_dev
 				"(min %#llx max %#llx)\n", idx,
 				(unsigned long long) rule->min,
 				(unsigned long long) rule->max);
-			return 0;
+			return -EBUSY;
 		}
 	}
 
 __add:
 	pnp_add_mem_resource(dev, res->start, res->end, res->flags);
-	return 1;
+	return 0;
 }
 
 static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
@@ -126,7 +126,7 @@ static int pnp_assign_irq(struct pnp_dev
 	if (res) {
 		dev_dbg(&dev->dev, "  irq %d already set to %d flags %#lx\n",
 			idx, (int) res->start, res->flags);
-		return 1;
+		return 0;
 	}
 
 	res = &local_res;
@@ -154,14 +154,14 @@ static int pnp_assign_irq(struct pnp_dev
 		}
 	}
 	dev_dbg(&dev->dev, "  couldn't assign irq %d\n", idx);
-	return 0;
+	return -EBUSY;
 
 __add:
 	pnp_add_irq_resource(dev, res->start, res->flags);
-	return 1;
+	return 0;
 }
 
-static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
+static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
 {
 	struct resource *res, local_res;
 	int i;
@@ -175,7 +175,7 @@ static void pnp_assign_dma(struct pnp_de
 	if (res) {
 		dev_dbg(&dev->dev, "  dma %d already set to %d flags %#lx\n",
 			idx, (int) res->start, res->flags);
-		return;
+		return 0;
 	}
 
 	res = &local_res;
@@ -198,6 +198,7 @@ static void pnp_assign_dma(struct pnp_de
 
 __add:
 	pnp_add_dma_resource(dev, res->start, res->flags);
+	return 0;
 }
 
 void pnp_init_resources(struct pnp_dev *dev)
@@ -243,25 +244,26 @@ static int pnp_assign_resources(struct p
 		irq = dev->independent->irq;
 		dma = dev->independent->dma;
 		while (port) {
-			if (!pnp_assign_port(dev, port, nport))
+			if (pnp_assign_port(dev, port, nport) < 0)
 				goto fail;
 			nport++;
 			port = port->next;
 		}
 		while (mem) {
-			if (!pnp_assign_mem(dev, mem, nmem))
+			if (pnp_assign_mem(dev, mem, nmem) < 0)
 				goto fail;
 			nmem++;
 			mem = mem->next;
 		}
 		while (irq) {
-			if (!pnp_assign_irq(dev, irq, nirq))
+			if (pnp_assign_irq(dev, irq, nirq) < 0)
 				goto fail;
 			nirq++;
 			irq = irq->next;
 		}
 		while (dma) {
-			pnp_assign_dma(dev, dma, ndma);
+			if (pnp_assign_dma(dev, dma, ndma) < 0)
+				goto fail;
 			ndma++;
 			dma = dma->next;
 		}
@@ -281,25 +283,26 @@ static int pnp_assign_resources(struct p
 		irq = dep->irq;
 		dma = dep->dma;
 		while (port) {
-			if (!pnp_assign_port(dev, port, nport))
+			if (pnp_assign_port(dev, port, nport) < 0)
 				goto fail;
 			nport++;
 			port = port->next;
 		}
 		while (mem) {
-			if (!pnp_assign_mem(dev, mem, nmem))
+			if (pnp_assign_mem(dev, mem, nmem) < 0)
 				goto fail;
 			nmem++;
 			mem = mem->next;
 		}
 		while (irq) {
-			if (!pnp_assign_irq(dev, irq, nirq))
+			if (pnp_assign_irq(dev, irq, nirq) < 0)
 				goto fail;
 			nirq++;
 			irq = irq->next;
 		}
 		while (dma) {
-			pnp_assign_dma(dev, dma, ndma);
+			if (pnp_assign_dma(dev, dma, ndma) < 0)
+				goto fail;
 			ndma++;
 			dma = dma->next;
 		}

-- 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [patch 11/18] PNP: remove redundant pnp_can_configure() check
  2008-06-04 22:09 [patch 00/18] PNP: convert resource options to unified dynamic list, v2 Bjorn Helgaas
                   ` (9 preceding siblings ...)
  2008-06-04 22:09 ` [patch 10/18] PNP: make resource assignment functions return 0 (success) or -EBUSY (failure) Bjorn Helgaas
@ 2008-06-04 22:09 ` Bjorn Helgaas
  2008-06-04 22:09 ` [patch 12/18] PNP: centralize resource option allocations Bjorn Helgaas
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Bjorn Helgaas @ 2008-06-04 22:09 UTC (permalink / raw)
  To: Len Brown
  Cc: linux-acpi, Rene Herman, linux-kernel, Adam Belay, Adam M Belay,
	Li Shaohua, Matthieu Castet, Thomas Renninger, Rene Herman,
	Jaroslav Kysela, Andrew Morton, Takashi Iwai

[-- Attachment #1: pnp-remove-assign-configurability-check --]
[-- Type: text/plain, Size: 788 bytes --]

pnp_assign_resources() is static and the only caller checks
pnp_can_configure() before calling it, so no need to do it
again.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>

Index: work10/drivers/pnp/manager.c
===================================================================
--- work10.orig/drivers/pnp/manager.c	2008-05-13 13:29:57.000000000 -0600
+++ work10/drivers/pnp/manager.c	2008-05-13 13:30:21.000000000 -0600
@@ -231,9 +231,6 @@ static int pnp_assign_resources(struct p
 	struct pnp_dma *dma;
 	int nport = 0, nmem = 0, nirq = 0, ndma = 0;
 
-	if (!pnp_can_configure(dev))
-		return -ENODEV;
-
 	dbg_pnp_show_resources(dev, "before pnp_assign_resources");
 	mutex_lock(&pnp_res_mutex);
 	pnp_clean_resource_table(dev);

-- 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [patch 12/18] PNP: centralize resource option allocations
  2008-06-04 22:09 [patch 00/18] PNP: convert resource options to unified dynamic list, v2 Bjorn Helgaas
                   ` (10 preceding siblings ...)
  2008-06-04 22:09 ` [patch 11/18] PNP: remove redundant pnp_can_configure() check Bjorn Helgaas
@ 2008-06-04 22:09 ` Bjorn Helgaas
  2008-06-04 22:09 ` [patch 13/18] PNPACPI: ignore _PRS interrupt numbers larger than PNP_IRQ_NR Bjorn Helgaas
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Bjorn Helgaas @ 2008-06-04 22:09 UTC (permalink / raw)
  To: Len Brown
  Cc: linux-acpi, Rene Herman, linux-kernel, Adam Belay, Adam M Belay,
	Li Shaohua, Matthieu Castet, Thomas Renninger, Rene Herman,
	Jaroslav Kysela, Andrew Morton, Takashi Iwai

[-- Attachment #1: pnp-centralize-option-allocs --]
[-- Type: text/plain, Size: 23086 bytes --]

This patch moves all the option allocations (pnp_mem, pnp_port, etc)
into the pnp_register_{mem,port,irq,dma}_resource() functions.  This
will make it easier to rework the option data structures.

The non-trivial part of this patch is the IRQ handling.  The backends
have to allocate a local pnp_irq_mask_t bitmap, populate it, and pass
a pointer to pnp_register_irq_resource().

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>

---
 drivers/pnp/base.h             |   12 ++-
 drivers/pnp/isapnp/core.c      |  115 +++++++++++++------------------
 drivers/pnp/pnpacpi/rsparser.c |  149 +++++++++++++----------------------------
 drivers/pnp/pnpbios/rsparser.c |  112 ++++++++++++------------------
 drivers/pnp/resource.c         |   58 +++++++++++++--
 5 files changed, 200 insertions(+), 246 deletions(-)

Index: work10/drivers/pnp/base.h
===================================================================
--- work10.orig/drivers/pnp/base.h	2008-05-30 16:13:46.000000000 -0600
+++ work10/drivers/pnp/base.h	2008-06-02 10:10:27.000000000 -0600
@@ -74,13 +74,17 @@ struct pnp_option *pnp_register_independ
 struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev,
 						 int priority);
 int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option,
-			      struct pnp_irq *data);
+			      pnp_irq_mask_t *map, unsigned char flags);
 int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option,
-			      struct pnp_dma *data);
+			      unsigned char map, unsigned char flags);
 int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option,
-			       struct pnp_port *data);
+			       resource_size_t min, resource_size_t max,
+			       resource_size_t align, resource_size_t size,
+			       unsigned char flags);
 int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option,
-			      struct pnp_mem *data);
+			      resource_size_t min, resource_size_t max,
+			      resource_size_t align, resource_size_t size,
+			      unsigned char flags);
 void pnp_init_resources(struct pnp_dev *dev);
 
 void pnp_fixup_device(struct pnp_dev *dev);
Index: work10/drivers/pnp/isapnp/core.c
===================================================================
--- work10.orig/drivers/pnp/isapnp/core.c	2008-05-30 16:13:46.000000000 -0600
+++ work10/drivers/pnp/isapnp/core.c	2008-06-02 10:10:27.000000000 -0600
@@ -433,20 +433,20 @@ static void __init isapnp_parse_irq_reso
 					     int size)
 {
 	unsigned char tmp[3];
-	struct pnp_irq *irq;
 	unsigned long bits;
+	pnp_irq_mask_t map;
+	unsigned char flags = IORESOURCE_IRQ_HIGHEDGE;
 
 	isapnp_peek(tmp, size);
-	irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
-	if (!irq)
-		return;
 	bits = (tmp[1] << 8) | tmp[0];
-	bitmap_copy(irq->map.bits, &bits, 16);
+
+	bitmap_zero(map.bits, PNP_IRQ_NR);
+	bitmap_copy(map.bits, &bits, 16);
+
 	if (size > 2)
-		irq->flags = tmp[2];
-	else
-		irq->flags = IORESOURCE_IRQ_HIGHEDGE;
-	pnp_register_irq_resource(dev, option, irq);
+		flags = tmp[2];
+
+	pnp_register_irq_resource(dev, option, &map, flags);
 }
 
 /*
@@ -457,15 +457,9 @@ static void __init isapnp_parse_dma_reso
 					     int size)
 {
 	unsigned char tmp[2];
-	struct pnp_dma *dma;
 
 	isapnp_peek(tmp, size);
-	dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
-	if (!dma)
-		return;
-	dma->map = tmp[0];
-	dma->flags = tmp[1];
-	pnp_register_dma_resource(dev, option, dma);
+	pnp_register_dma_resource(dev, option, tmp[0], tmp[1]);
 }
 
 /*
@@ -476,18 +470,16 @@ static void __init isapnp_parse_port_res
 					      int size)
 {
 	unsigned char tmp[7];
-	struct pnp_port *port;
+	resource_size_t min, max, align, len;
+	unsigned char flags;
 
 	isapnp_peek(tmp, size);
-	port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
-	if (!port)
-		return;
-	port->min = (tmp[2] << 8) | tmp[1];
-	port->max = (tmp[4] << 8) | tmp[3];
-	port->align = tmp[5];
-	port->size = tmp[6];
-	port->flags = tmp[0] ? IORESOURCE_IO_16BIT_ADDR : 0;
-	pnp_register_port_resource(dev, option, port);
+	min = (tmp[2] << 8) | tmp[1];
+	max = (tmp[4] << 8) | tmp[3];
+	align = tmp[5];
+	len = tmp[6];
+	flags = tmp[0] ? IORESOURCE_IO_16BIT_ADDR : 0;
+	pnp_register_port_resource(dev, option, min, max, align, len, flags);
 }
 
 /*
@@ -498,17 +490,13 @@ static void __init isapnp_parse_fixed_po
 						    int size)
 {
 	unsigned char tmp[3];
-	struct pnp_port *port;
+	resource_size_t base, len;
 
 	isapnp_peek(tmp, size);
-	port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
-	if (!port)
-		return;
-	port->min = port->max = (tmp[1] << 8) | tmp[0];
-	port->size = tmp[2];
-	port->align = 0;
-	port->flags = IORESOURCE_IO_FIXED;
-	pnp_register_port_resource(dev, option, port);
+	base = (tmp[1] << 8) | tmp[0];
+	len = tmp[2];
+	pnp_register_port_resource(dev, option, base, base, 0, len,
+				   IORESOURCE_IO_FIXED);
 }
 
 /*
@@ -519,18 +507,16 @@ static void __init isapnp_parse_mem_reso
 					     int size)
 {
 	unsigned char tmp[9];
-	struct pnp_mem *mem;
+	resource_size_t min, max, align, len;
+	unsigned char flags;
 
 	isapnp_peek(tmp, size);
-	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
-	if (!mem)
-		return;
-	mem->min = ((tmp[2] << 8) | tmp[1]) << 8;
-	mem->max = ((tmp[4] << 8) | tmp[3]) << 8;
-	mem->align = (tmp[6] << 8) | tmp[5];
-	mem->size = ((tmp[8] << 8) | tmp[7]) << 8;
-	mem->flags = tmp[0];
-	pnp_register_mem_resource(dev, option, mem);
+	min = ((tmp[2] << 8) | tmp[1]) << 8;
+	max = ((tmp[4] << 8) | tmp[3]) << 8;
+	align = (tmp[6] << 8) | tmp[5];
+	len = ((tmp[8] << 8) | tmp[7]) << 8;
+	flags = tmp[0];
+	pnp_register_mem_resource(dev, option, min, max, align, len, flags);
 }
 
 /*
@@ -541,20 +527,16 @@ static void __init isapnp_parse_mem32_re
 					       int size)
 {
 	unsigned char tmp[17];
-	struct pnp_mem *mem;
+	resource_size_t min, max, align, len;
+	unsigned char flags;
 
 	isapnp_peek(tmp, size);
-	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
-	if (!mem)
-		return;
-	mem->min = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
-	mem->max = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
-	mem->align =
-	    (tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9];
-	mem->size =
-	    (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13];
-	mem->flags = tmp[0];
-	pnp_register_mem_resource(dev, option, mem);
+	min = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
+	max = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
+	align = (tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9];
+	len = (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13];
+	flags = tmp[0];
+	pnp_register_mem_resource(dev, option, min, max, align, len, flags);
 }
 
 /*
@@ -565,18 +547,14 @@ static void __init isapnp_parse_fixed_me
 						     int size)
 {
 	unsigned char tmp[9];
-	struct pnp_mem *mem;
+	resource_size_t base, len;
+	unsigned char flags;
 
 	isapnp_peek(tmp, size);
-	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
-	if (!mem)
-		return;
-	mem->min = mem->max =
-	    (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
-	mem->size = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
-	mem->align = 0;
-	mem->flags = tmp[0];
-	pnp_register_mem_resource(dev, option, mem);
+	base = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
+	len = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
+	flags = tmp[0];
+	pnp_register_mem_resource(dev, option, base, base, 0, len, flags);
 }
 
 /*
Index: work10/drivers/pnp/pnpacpi/rsparser.c
===================================================================
--- work10.orig/drivers/pnp/pnpacpi/rsparser.c	2008-05-30 16:13:46.000000000 -0600
+++ work10/drivers/pnp/pnpacpi/rsparser.c	2008-06-02 10:10:27.000000000 -0600
@@ -377,20 +377,16 @@ static __init void pnpacpi_parse_dma_opt
 					    struct acpi_resource_dma *p)
 {
 	int i;
-	struct pnp_dma *dma;
+	unsigned char map = 0, flags;
 
 	if (p->channel_count == 0)
 		return;
-	dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
-	if (!dma)
-		return;
 
 	for (i = 0; i < p->channel_count; i++)
-		dma->map |= 1 << p->channels[i];
-
-	dma->flags = dma_flags(p->type, p->bus_master, p->transfer);
+		map |= 1 << p->channels[i];
 
-	pnp_register_dma_resource(dev, option, dma);
+	flags = dma_flags(p->type, p->bus_master, p->transfer);
+	pnp_register_dma_resource(dev, option, map, flags);
 }
 
 static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev,
@@ -398,20 +394,19 @@ static __init void pnpacpi_parse_irq_opt
 					    struct acpi_resource_irq *p)
 {
 	int i;
-	struct pnp_irq *irq;
+	pnp_irq_mask_t map;
+	unsigned char flags;
 
 	if (p->interrupt_count == 0)
 		return;
-	irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
-	if (!irq)
-		return;
 
+	bitmap_zero(map.bits, PNP_IRQ_NR);
 	for (i = 0; i < p->interrupt_count; i++)
 		if (p->interrupts[i])
-			__set_bit(p->interrupts[i], irq->map.bits);
-	irq->flags = irq_flags(p->triggering, p->polarity, p->sharable);
+			__set_bit(p->interrupts[i], map.bits);
 
-	pnp_register_irq_resource(dev, option, irq);
+	flags = irq_flags(p->triggering, p->polarity, p->sharable);
+	pnp_register_irq_resource(dev, option, &map, flags);
 }
 
 static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev,
@@ -419,123 +414,90 @@ static __init void pnpacpi_parse_ext_irq
 					struct acpi_resource_extended_irq *p)
 {
 	int i;
-	struct pnp_irq *irq;
+	pnp_irq_mask_t map;
+	unsigned char flags;
 
 	if (p->interrupt_count == 0)
 		return;
-	irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
-	if (!irq)
-		return;
 
+	bitmap_zero(map.bits, PNP_IRQ_NR);
 	for (i = 0; i < p->interrupt_count; i++)
 		if (p->interrupts[i])
-			__set_bit(p->interrupts[i], irq->map.bits);
-	irq->flags = irq_flags(p->triggering, p->polarity, p->sharable);
+			__set_bit(p->interrupts[i], map.bits);
 
-	pnp_register_irq_resource(dev, option, irq);
+	flags = irq_flags(p->triggering, p->polarity, p->sharable);
+	pnp_register_irq_resource(dev, option, &map, flags);
 }
 
 static __init void pnpacpi_parse_port_option(struct pnp_dev *dev,
 					     struct pnp_option *option,
 					     struct acpi_resource_io *io)
 {
-	struct pnp_port *port;
+	unsigned char flags = 0;
 
 	if (io->address_length == 0)
 		return;
-	port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
-	if (!port)
-		return;
-	port->min = io->minimum;
-	port->max = io->maximum;
-	port->align = io->alignment;
-	port->size = io->address_length;
-	port->flags = ACPI_DECODE_16 == io->io_decode ?
-	    IORESOURCE_IO_16BIT_ADDR : 0;
-	pnp_register_port_resource(dev, option, port);
+
+	if (io->io_decode == ACPI_DECODE_16)
+		flags = IORESOURCE_IO_16BIT_ADDR;
+	pnp_register_port_resource(dev, option, io->minimum, io->maximum,
+				   io->alignment, io->address_length, flags);
 }
 
 static __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev,
 						   struct pnp_option *option,
 					struct acpi_resource_fixed_io *io)
 {
-	struct pnp_port *port;
-
 	if (io->address_length == 0)
 		return;
-	port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
-	if (!port)
-		return;
-	port->min = port->max = io->address;
-	port->size = io->address_length;
-	port->align = 0;
-	port->flags = IORESOURCE_IO_FIXED;
-	pnp_register_port_resource(dev, option, port);
+
+	pnp_register_port_resource(dev, option, io->address, io->address, 0,
+				   io->address_length, IORESOURCE_IO_FIXED);
 }
 
 static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev,
 					      struct pnp_option *option,
 					      struct acpi_resource_memory24 *p)
 {
-	struct pnp_mem *mem;
+	unsigned char flags = 0;
 
 	if (p->address_length == 0)
 		return;
-	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
-	if (!mem)
-		return;
-	mem->min = p->minimum;
-	mem->max = p->maximum;
-	mem->align = p->alignment;
-	mem->size = p->address_length;
 
-	mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
-	    IORESOURCE_MEM_WRITEABLE : 0;
-
-	pnp_register_mem_resource(dev, option, mem);
+	if (p->write_protect == ACPI_READ_WRITE_MEMORY)
+		flags = IORESOURCE_MEM_WRITEABLE;
+	pnp_register_mem_resource(dev, option, p->minimum, p->maximum,
+				  p->alignment, p->address_length, flags);
 }
 
 static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev,
 					      struct pnp_option *option,
 					      struct acpi_resource_memory32 *p)
 {
-	struct pnp_mem *mem;
+	unsigned char flags = 0;
 
 	if (p->address_length == 0)
 		return;
-	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
-	if (!mem)
-		return;
-	mem->min = p->minimum;
-	mem->max = p->maximum;
-	mem->align = p->alignment;
-	mem->size = p->address_length;
 
-	mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
-	    IORESOURCE_MEM_WRITEABLE : 0;
-
-	pnp_register_mem_resource(dev, option, mem);
+	if (p->write_protect == ACPI_READ_WRITE_MEMORY)
+		flags = IORESOURCE_MEM_WRITEABLE;
+	pnp_register_mem_resource(dev, option, p->minimum, p->maximum,
+				  p->alignment, p->address_length, flags);
 }
 
 static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev,
 						    struct pnp_option *option,
 					struct acpi_resource_fixed_memory32 *p)
 {
-	struct pnp_mem *mem;
+	unsigned char flags = 0;
 
 	if (p->address_length == 0)
 		return;
-	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
-	if (!mem)
-		return;
-	mem->min = mem->max = p->address;
-	mem->size = p->address_length;
-	mem->align = 0;
 
-	mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
-	    IORESOURCE_MEM_WRITEABLE : 0;
-
-	pnp_register_mem_resource(dev, option, mem);
+	if (p->write_protect == ACPI_READ_WRITE_MEMORY)
+		flags = IORESOURCE_MEM_WRITEABLE;
+	pnp_register_mem_resource(dev, option, p->address, p->address,
+				  0, p->address_length, flags);
 }
 
 static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
@@ -544,8 +506,7 @@ static __init void pnpacpi_parse_address
 {
 	struct acpi_resource_address64 addr, *p = &addr;
 	acpi_status status;
-	struct pnp_mem *mem;
-	struct pnp_port *port;
+	unsigned char flags = 0;
 
 	status = acpi_resource_to_address64(r, p);
 	if (!ACPI_SUCCESS(status)) {
@@ -558,26 +519,14 @@ static __init void pnpacpi_parse_address
 		return;
 
 	if (p->resource_type == ACPI_MEMORY_RANGE) {
-		mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
-		if (!mem)
-			return;
-		mem->min = mem->max = p->minimum;
-		mem->size = p->address_length;
-		mem->align = 0;
-		mem->flags = (p->info.mem.write_protect ==
-			      ACPI_READ_WRITE_MEMORY) ? IORESOURCE_MEM_WRITEABLE
-		    : 0;
-		pnp_register_mem_resource(dev, option, mem);
-	} else if (p->resource_type == ACPI_IO_RANGE) {
-		port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
-		if (!port)
-			return;
-		port->min = port->max = p->minimum;
-		port->size = p->address_length;
-		port->align = 0;
-		port->flags = IORESOURCE_IO_FIXED;
-		pnp_register_port_resource(dev, option, port);
-	}
+		if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY)
+			flags = IORESOURCE_MEM_WRITEABLE;
+		pnp_register_mem_resource(dev, option, p->minimum, p->minimum,
+					  0, p->address_length, flags);
+	} else if (p->resource_type == ACPI_IO_RANGE)
+		pnp_register_port_resource(dev, option, p->minimum, p->minimum,
+					   0, p->address_length,
+					   IORESOURCE_IO_FIXED);
 }
 
 struct acpipnp_parse_option_s {
Index: work10/drivers/pnp/pnpbios/rsparser.c
===================================================================
--- work10.orig/drivers/pnp/pnpbios/rsparser.c	2008-05-30 16:13:46.000000000 -0600
+++ work10/drivers/pnp/pnpbios/rsparser.c	2008-06-02 10:11:44.000000000 -0600
@@ -218,116 +218,96 @@ static __init void pnpbios_parse_mem_opt
 					    unsigned char *p, int size,
 					    struct pnp_option *option)
 {
-	struct pnp_mem *mem;
+	resource_size_t min, max, align, len;
+	unsigned char flags;
 
-	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
-	if (!mem)
-		return;
-	mem->min = ((p[5] << 8) | p[4]) << 8;
-	mem->max = ((p[7] << 8) | p[6]) << 8;
-	mem->align = (p[9] << 8) | p[8];
-	mem->size = ((p[11] << 8) | p[10]) << 8;
-	mem->flags = p[3];
-	pnp_register_mem_resource(dev, option, mem);
+	min = ((p[5] << 8) | p[4]) << 8;
+	max = ((p[7] << 8) | p[6]) << 8;
+	align = (p[9] << 8) | p[8];
+	len = ((p[11] << 8) | p[10]) << 8;
+	flags = p[3];
+	pnp_register_mem_resource(dev, option, min, max, align, len, flags);
 }
 
 static __init void pnpbios_parse_mem32_option(struct pnp_dev *dev,
 					      unsigned char *p, int size,
 					      struct pnp_option *option)
 {
-	struct pnp_mem *mem;
+	resource_size_t min, max, align, len;
+	unsigned char flags;
 
-	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
-	if (!mem)
-		return;
-	mem->min = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
-	mem->max = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
-	mem->align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12];
-	mem->size = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16];
-	mem->flags = p[3];
-	pnp_register_mem_resource(dev, option, mem);
+	min = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
+	max = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
+	align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12];
+	len = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16];
+	flags = p[3];
+	pnp_register_mem_resource(dev, option, min, max, align, len, flags);
 }
 
 static __init void pnpbios_parse_fixed_mem32_option(struct pnp_dev *dev,
 						    unsigned char *p, int size,
 						    struct pnp_option *option)
 {
-	struct pnp_mem *mem;
+	resource_size_t base, len;
+	unsigned char flags;
 
-	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
-	if (!mem)
-		return;
-	mem->min = mem->max = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
-	mem->size = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
-	mem->align = 0;
-	mem->flags = p[3];
-	pnp_register_mem_resource(dev, option, mem);
+	base = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
+	len = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
+	flags = p[3];
+	pnp_register_mem_resource(dev, option, base, base, 0, len, flags);
 }
 
 static __init void pnpbios_parse_irq_option(struct pnp_dev *dev,
 					    unsigned char *p, int size,
 					    struct pnp_option *option)
 {
-	struct pnp_irq *irq;
 	unsigned long bits;
+	pnp_irq_mask_t map;
+	unsigned char flags = IORESOURCE_IRQ_HIGHEDGE;
 
-	irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
-	if (!irq)
-		return;
 	bits = (p[2] << 8) | p[1];
-	bitmap_copy(irq->map.bits, &bits, 16);
+
+	bitmap_zero(map.bits, PNP_IRQ_NR);
+	bitmap_copy(map.bits, &bits, 16);
+
 	if (size > 2)
-		irq->flags = p[3];
-	else
-		irq->flags = IORESOURCE_IRQ_HIGHEDGE;
-	pnp_register_irq_resource(dev, option, irq);
+		flags = p[3];
+
+	pnp_register_irq_resource(dev, option, &map, flags);
 }
 
 static __init void pnpbios_parse_dma_option(struct pnp_dev *dev,
 					    unsigned char *p, int size,
 					    struct pnp_option *option)
 {
-	struct pnp_dma *dma;
-
-	dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
-	if (!dma)
-		return;
-	dma->map = p[1];
-	dma->flags = p[2];
-	pnp_register_dma_resource(dev, option, dma);
+	pnp_register_dma_resource(dev, option, p[1], p[2]);
 }
 
 static __init void pnpbios_parse_port_option(struct pnp_dev *dev,
 					     unsigned char *p, int size,
 					     struct pnp_option *option)
 {
-	struct pnp_port *port;
+	resource_size_t min, max, align, len;
+	unsigned char flags;
 
-	port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
-	if (!port)
-		return;
-	port->min = (p[3] << 8) | p[2];
-	port->max = (p[5] << 8) | p[4];
-	port->align = p[6];
-	port->size = p[7];
-	port->flags = p[1] ? IORESOURCE_IO_16BIT_ADDR : 0;
-	pnp_register_port_resource(dev, option, port);
+	min = (p[3] << 8) | p[2];
+	max = (p[5] << 8) | p[4];
+	align = p[6];
+	len = p[7];
+	flags = p[1] ? IORESOURCE_IO_16BIT_ADDR : 0;
+	pnp_register_port_resource(dev, option, min, max, align, len, flags);
 }
 
 static __init void pnpbios_parse_fixed_port_option(struct pnp_dev *dev,
 						   unsigned char *p, int size,
 						   struct pnp_option *option)
 {
-	struct pnp_port *port;
+	resource_size_t base, len;
 
-	port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
-	if (!port)
-		return;
-	port->min = port->max = (p[2] << 8) | p[1];
-	port->size = p[3];
-	port->align = 0;
-	port->flags = IORESOURCE_IO_FIXED;
-	pnp_register_port_resource(dev, option, port);
+	base = (p[2] << 8) | p[1];
+	len = p[3];
+	pnp_register_port_resource(dev, option, base, base, 0, len,
+				   IORESOURCE_IO_FIXED);
 }
 
 static __init unsigned char *
Index: work10/drivers/pnp/resource.c
===================================================================
--- work10.orig/drivers/pnp/resource.c	2008-05-30 16:13:46.000000000 -0600
+++ work10/drivers/pnp/resource.c	2008-06-02 10:10:27.000000000 -0600
@@ -78,13 +78,20 @@ struct pnp_option *pnp_register_dependen
 }
 
 int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option,
-			      struct pnp_irq *data)
+			      pnp_irq_mask_t *map, unsigned char flags)
 {
-	struct pnp_irq *ptr;
+	struct pnp_irq *data, *ptr;
 #ifdef DEBUG
 	char buf[PNP_IRQ_NR];   /* hex-encoded, so this is overkill but safe */
 #endif
 
+	data = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->map = *map;
+	data->flags = flags;
+
 	ptr = option->irq;
 	while (ptr && ptr->next)
 		ptr = ptr->next;
@@ -112,9 +119,16 @@ int pnp_register_irq_resource(struct pnp
 }
 
 int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option,
-			      struct pnp_dma *data)
+			      unsigned char map, unsigned char flags)
 {
-	struct pnp_dma *ptr;
+	struct pnp_dma *data, *ptr;
+
+	data = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->map = map;
+	data->flags = flags;
 
 	ptr = option->dma;
 	while (ptr && ptr->next)
@@ -130,9 +144,21 @@ int pnp_register_dma_resource(struct pnp
 }
 
 int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option,
-			       struct pnp_port *data)
-{
-	struct pnp_port *ptr;
+			       resource_size_t min, resource_size_t max,
+			       resource_size_t align, resource_size_t size,
+			       unsigned char flags)
+{
+	struct pnp_port *data, *ptr;
+
+	data = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->min = min;
+	data->max = max;
+	data->align = align;
+	data->size = size;
+	data->flags = flags;
 
 	ptr = option->port;
 	while (ptr && ptr->next)
@@ -152,9 +178,21 @@ int pnp_register_port_resource(struct pn
 }
 
 int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option,
-			      struct pnp_mem *data)
-{
-	struct pnp_mem *ptr;
+			      resource_size_t min, resource_size_t max,
+			      resource_size_t align, resource_size_t size,
+			      unsigned char flags)
+{
+	struct pnp_mem *data, *ptr;
+
+	data = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->min = min;
+	data->max = max;
+	data->align = align;
+	data->size = size;
+	data->flags = flags;
 
 	ptr = option->mem;
 	while (ptr && ptr->next)

-- 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [patch 13/18] PNPACPI: ignore _PRS interrupt numbers larger than PNP_IRQ_NR
  2008-06-04 22:09 [patch 00/18] PNP: convert resource options to unified dynamic list, v2 Bjorn Helgaas
                   ` (11 preceding siblings ...)
  2008-06-04 22:09 ` [patch 12/18] PNP: centralize resource option allocations Bjorn Helgaas
@ 2008-06-04 22:09 ` Bjorn Helgaas
  2008-06-04 22:09 ` [patch 14/18] PNP: rename pnp_register_*_resource() local variables Bjorn Helgaas
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Bjorn Helgaas @ 2008-06-04 22:09 UTC (permalink / raw)
  To: Len Brown
  Cc: linux-acpi, Rene Herman, linux-kernel, Adam Belay, Adam M Belay,
	Li Shaohua, Matthieu Castet, Thomas Renninger, Rene Herman,
	Jaroslav Kysela, Andrew Morton, Takashi Iwai

[-- Attachment #1: pnpacpi-extended-irq-option --]
[-- Type: text/plain, Size: 1556 bytes --]

ACPI Extended Interrupt Descriptors can encode 32-bit interrupt
numbers, so an interrupt number may exceed the size of the bitmap
we use to track possible IRQ settings.

To avoid corrupting memory, complain and ignore too-large interrupt
numbers.

There's similar code in pnpacpi_parse_irq_option(), but I didn't
change that because the small IRQ descriptor can only encode
IRQs 0-15, which do not exceed bitmap size.

In the future, we could handle IRQ numbers greater than PNP_IRQ_NR
by replacing the bitmap with a table or list.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>

Index: work10/drivers/pnp/pnpacpi/rsparser.c
===================================================================
--- work10.orig/drivers/pnp/pnpacpi/rsparser.c	2008-05-30 13:23:34.000000000 -0600
+++ work10/drivers/pnp/pnpacpi/rsparser.c	2008-05-30 14:45:52.000000000 -0600
@@ -421,9 +421,16 @@ static __init void pnpacpi_parse_ext_irq
 		return;
 
 	bitmap_zero(map.bits, PNP_IRQ_NR);
-	for (i = 0; i < p->interrupt_count; i++)
-		if (p->interrupts[i])
-			__set_bit(p->interrupts[i], map.bits);
+	for (i = 0; i < p->interrupt_count; i++) {
+		if (p->interrupts[i]) {
+			if (p->interrupts[i] < PNP_IRQ_NR)
+				__set_bit(p->interrupts[i], map.bits);
+			else
+				dev_err(&dev->dev, "ignoring IRQ %d option "
+					"(too large for %d entry bitmap)\n",
+					p->interrupts[i], PNP_IRQ_NR);
+		}
+	}
 
 	flags = irq_flags(p->triggering, p->polarity, p->sharable);
 	pnp_register_irq_resource(dev, option, &map, flags);

-- 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [patch 14/18] PNP: rename pnp_register_*_resource() local variables
  2008-06-04 22:09 [patch 00/18] PNP: convert resource options to unified dynamic list, v2 Bjorn Helgaas
                   ` (12 preceding siblings ...)
  2008-06-04 22:09 ` [patch 13/18] PNPACPI: ignore _PRS interrupt numbers larger than PNP_IRQ_NR Bjorn Helgaas
@ 2008-06-04 22:09 ` Bjorn Helgaas
  2008-06-04 22:09 ` [patch 15/18] PNP: support optional IRQ resources Bjorn Helgaas
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 31+ messages in thread
From: Bjorn Helgaas @ 2008-06-04 22:09 UTC (permalink / raw)
  To: Len Brown
  Cc: linux-acpi, Rene Herman, linux-kernel, Adam Belay, Adam M Belay,
	Li Shaohua, Matthieu Castet, Thomas Renninger, Rene Herman,
	Jaroslav Kysela, Andrew Morton, Takashi Iwai

[-- Attachment #1: pnp-register-renames --]
[-- Type: text/plain, Size: 4832 bytes --]

No functional change; just rename "data" to something more
descriptive.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>

Index: work10/drivers/pnp/resource.c
===================================================================
--- work10.orig/drivers/pnp/resource.c	2008-05-20 13:23:06.000000000 -0600
+++ work10/drivers/pnp/resource.c	2008-05-20 13:24:27.000000000 -0600
@@ -80,40 +80,40 @@ struct pnp_option *pnp_register_dependen
 int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option,
 			      pnp_irq_mask_t *map, unsigned char flags)
 {
-	struct pnp_irq *data, *ptr;
+	struct pnp_irq *irq, *ptr;
 #ifdef DEBUG
 	char buf[PNP_IRQ_NR];   /* hex-encoded, so this is overkill but safe */
 #endif
 
-	data = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
-	if (!data)
+	irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
+	if (!irq)
 		return -ENOMEM;
 
-	data->map = *map;
-	data->flags = flags;
+	irq->map = *map;
+	irq->flags = flags;
 
 	ptr = option->irq;
 	while (ptr && ptr->next)
 		ptr = ptr->next;
 	if (ptr)
-		ptr->next = data;
+		ptr->next = irq;
 	else
-		option->irq = data;
+		option->irq = irq;
 
 #ifdef CONFIG_PCI
 	{
 		int i;
 
 		for (i = 0; i < 16; i++)
-			if (test_bit(i, data->map.bits))
+			if (test_bit(i, irq->map.bits))
 				pcibios_penalize_isa_irq(i, 0);
 	}
 #endif
 
 #ifdef DEBUG
-	bitmap_scnprintf(buf, sizeof(buf), data->map.bits, PNP_IRQ_NR);
+	bitmap_scnprintf(buf, sizeof(buf), irq->map.bits, PNP_IRQ_NR);
 	dev_dbg(&dev->dev, "  irq bitmask %s flags %#x\n", buf,
-		data->flags);
+		irq->flags);
 #endif
 	return 0;
 }
@@ -121,25 +121,25 @@ int pnp_register_irq_resource(struct pnp
 int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option,
 			      unsigned char map, unsigned char flags)
 {
-	struct pnp_dma *data, *ptr;
+	struct pnp_dma *dma, *ptr;
 
-	data = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
-	if (!data)
+	dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
+	if (!dma)
 		return -ENOMEM;
 
-	data->map = map;
-	data->flags = flags;
+	dma->map = map;
+	dma->flags = flags;
 
 	ptr = option->dma;
 	while (ptr && ptr->next)
 		ptr = ptr->next;
 	if (ptr)
-		ptr->next = data;
+		ptr->next = dma;
 	else
-		option->dma = data;
+		option->dma = dma;
 
-	dev_dbg(&dev->dev, "  dma bitmask %#x flags %#x\n", data->map,
-		data->flags);
+	dev_dbg(&dev->dev, "  dma bitmask %#x flags %#x\n", dma->map,
+		dma->flags);
 	return 0;
 }
 
@@ -148,32 +148,32 @@ int pnp_register_port_resource(struct pn
 			       resource_size_t align, resource_size_t size,
 			       unsigned char flags)
 {
-	struct pnp_port *data, *ptr;
+	struct pnp_port *port, *ptr;
 
-	data = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
-	if (!data)
+	port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
+	if (!port)
 		return -ENOMEM;
 
-	data->min = min;
-	data->max = max;
-	data->align = align;
-	data->size = size;
-	data->flags = flags;
+	port->min = min;
+	port->max = max;
+	port->align = align;
+	port->size = size;
+	port->flags = flags;
 
 	ptr = option->port;
 	while (ptr && ptr->next)
 		ptr = ptr->next;
 	if (ptr)
-		ptr->next = data;
+		ptr->next = port;
 	else
-		option->port = data;
+		option->port = port;
 
 	dev_dbg(&dev->dev, "  io  "
 		"min %#llx max %#llx align %lld size %lld flags %#x\n",
-		(unsigned long long) data->min,
-		(unsigned long long) data->max,
-		(unsigned long long) data->align,
-		(unsigned long long) data->size, data->flags);
+		(unsigned long long) port->min,
+		(unsigned long long) port->max,
+		(unsigned long long) port->align,
+		(unsigned long long) port->size, port->flags);
 	return 0;
 }
 
@@ -182,32 +182,32 @@ int pnp_register_mem_resource(struct pnp
 			      resource_size_t align, resource_size_t size,
 			      unsigned char flags)
 {
-	struct pnp_mem *data, *ptr;
+	struct pnp_mem *mem, *ptr;
 
-	data = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
-	if (!data)
+	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
+	if (!mem)
 		return -ENOMEM;
 
-	data->min = min;
-	data->max = max;
-	data->align = align;
-	data->size = size;
-	data->flags = flags;
+	mem->min = min;
+	mem->max = max;
+	mem->align = align;
+	mem->size = size;
+	mem->flags = flags;
 
 	ptr = option->mem;
 	while (ptr && ptr->next)
 		ptr = ptr->next;
 	if (ptr)
-		ptr->next = data;
+		ptr->next = mem;
 	else
-		option->mem = data;
+		option->mem = mem;
 
 	dev_dbg(&dev->dev, "  mem "
 		"min %#llx max %#llx align %lld size %lld flags %#x\n",
-		(unsigned long long) data->min,
-		(unsigned long long) data->max,
-		(unsigned long long) data->align,
-		(unsigned long long) data->size, data->flags);
+		(unsigned long long) mem->min,
+		(unsigned long long) mem->max,
+		(unsigned long long) mem->align,
+		(unsigned long long) mem->size, mem->flags);
 	return 0;
 }
 

-- 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [patch 15/18] PNP: support optional IRQ resources
  2008-06-04 22:09 [patch 00/18] PNP: convert resource options to unified dynamic list, v2 Bjorn Helgaas
                   ` (13 preceding siblings ...)
  2008-06-04 22:09 ` [patch 14/18] PNP: rename pnp_register_*_resource() local variables Bjorn Helgaas
@ 2008-06-04 22:09 ` Bjorn Helgaas
  2008-06-14  8:29   ` Rene Herman
  2008-06-04 22:09 ` [patch 16/18] PNP: remove extra 0x100 bit from option priority Bjorn Helgaas
                   ` (3 subsequent siblings)
  18 siblings, 1 reply; 31+ messages in thread
From: Bjorn Helgaas @ 2008-06-04 22:09 UTC (permalink / raw)
  To: Len Brown
  Cc: linux-acpi, linux-kernel, Adam Belay, Adam M Belay, Li Shaohua,
	Matthieu Castet, Thomas Renninger, Rene Herman, Jaroslav Kysela,
	Andrew Morton, Takashi Iwai

[-- Attachment #1: pnp-optional-irqs --]
[-- Type: text/plain, Size: 5828 bytes --]

This patch adds an IORESOURCE_IRQ_OPTIONAL flag for use when
assigning resources to a device.  If the flag is set and we are
unable to assign an IRQ to the device, we can leave the IRQ
disabled but allow the overall resource allocation to succeed.

Some devices request an IRQ, but can run without an IRQ
(possibly with degraded performance).  This flag lets us run
the device without the IRQ instead of just leaving the
device disabled.

This is a reimplementation of this previous change by Rene
Herman <rene.herman@gmail.com>:
    http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=3b73a223661ed137c5d3d2635f954382e94f5a43

I reimplemented this for two reasons:
    - to prepare for converting all resource options into a single linked
      list, as opposed to the per-resource-type lists we have now, and
    - to preserve the order and number of resource options.

In PNPBIOS and ACPI, we configure a device by giving firmware a
list of resource assignments.  It is important that this list
has exactly the same number of resources, in the same order,
as the "template" list we got from the firmware in the first
place.

The problem of a sound card MPU401 being left disabled for want of
an IRQ was reported by Uwe Bugla <uwe.bugla@gmx.de>.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>

Index: work10/include/linux/ioport.h
===================================================================
--- work10.orig/include/linux/ioport.h	2008-06-03 14:49:43.000000000 -0600
+++ work10/include/linux/ioport.h	2008-06-03 15:04:50.000000000 -0600
@@ -59,6 +59,7 @@ struct resource_list {
 #define IORESOURCE_IRQ_HIGHLEVEL	(1<<2)
 #define IORESOURCE_IRQ_LOWLEVEL		(1<<3)
 #define IORESOURCE_IRQ_SHAREABLE	(1<<4)
+#define IORESOURCE_IRQ_OPTIONAL		(1<<5)
 
 /* PnP DMA specific bits (IORESOURCE_BITS) */
 #define IORESOURCE_DMA_TYPE_MASK	(3<<0)
Index: work10/drivers/pnp/manager.c
===================================================================
--- work10.orig/drivers/pnp/manager.c	2008-06-03 15:03:20.000000000 -0600
+++ work10/drivers/pnp/manager.c	2008-06-03 16:12:25.000000000 -0600
@@ -153,6 +153,15 @@ static int pnp_assign_irq(struct pnp_dev
 				goto __add;
 		}
 	}
+
+	if (rule->flags & IORESOURCE_IRQ_OPTIONAL) {
+		res->start = -1;
+		res->end = -1;
+		res->flags |= IORESOURCE_DISABLED;
+		dev_dbg(&dev->dev, "  irq %d disabled (optional)\n", idx);
+		goto __add;
+	}
+
 	dev_dbg(&dev->dev, "  couldn't assign irq %d\n", idx);
 	return -EBUSY;
 
Index: work10/drivers/pnp/quirks.c
===================================================================
--- work10.orig/drivers/pnp/quirks.c	2008-06-03 15:00:56.000000000 -0600
+++ work10/drivers/pnp/quirks.c	2008-06-03 16:12:25.000000000 -0600
@@ -118,34 +118,46 @@ static struct pnp_option *quirk_isapnp_m
 	struct pnp_option *res;
 
 	/*
-	 * Build a functional IRQ-less variant of each MPU option.
+	 * Build a functional IRQ-optional variant of each MPU option.
 	 */
 
 	for (res = dev->dependent; res; res = res->next) {
 		struct pnp_option *curr;
 		struct pnp_port *port;
-		struct pnp_port *copy;
+		struct pnp_port *copy_port;
+		struct pnp_irq *irq;
+		struct pnp_irq *copy_irq;
 
 		port = res->port;
-		if (!port || !res->irq)
+		irq = res->irq;
+		if (!port || !irq)
 			continue;
 
-		copy = pnp_alloc(sizeof *copy);
-		if (!copy)
+		copy_port = pnp_alloc(sizeof *copy_port);
+		if (!copy_port)
 			break;
 
-		copy->min = port->min;
-		copy->max = port->max;
-		copy->align = port->align;
-		copy->size = port->size;
-		copy->flags = port->flags;
+		copy_irq = pnp_alloc(sizeof *copy_irq);
+		if (!copy_irq) {
+			kfree(copy_port);
+			break;
+		}
+
+		*copy_port = *port;
+		copy_port->next = NULL;
+
+		*copy_irq = *irq;
+		copy_irq->flags |= IORESOURCE_IRQ_OPTIONAL;
+		copy_irq->next = NULL;
 
 		curr = pnp_build_option(PNP_RES_PRIORITY_FUNCTIONAL);
 		if (!curr) {
-			kfree(copy);
+			kfree(copy_port);
+			kfree(copy_irq);
 			break;
 		}
-		curr->port = copy;
+		curr->port = copy_port;
+		curr->irq = copy_irq;
 
 		if (prev)
 			prev->next = curr;
@@ -154,7 +166,7 @@ static struct pnp_option *quirk_isapnp_m
 		prev = curr;
 	}
 	if (head)
-		dev_info(&dev->dev, "adding IRQ-less MPU options\n");
+		dev_info(&dev->dev, "adding IRQ-optional MPU options\n");
 
 	return head;
 }
@@ -164,10 +176,6 @@ static void quirk_ad1815_mpu_resources(s
 	struct pnp_option *res;
 	struct pnp_irq *irq;
 
-	/*
-	 * Distribute the independent IRQ over the dependent options
-	 */
-
 	res = dev->independent;
 	if (!res)
 		return;
@@ -176,33 +184,10 @@ static void quirk_ad1815_mpu_resources(s
 	if (!irq || irq->next)
 		return;
 
-	res = dev->dependent;
-	if (!res)
-		return;
-
-	while (1) {
-		struct pnp_irq *copy;
-
-		copy = pnp_alloc(sizeof *copy);
-		if (!copy)
-			break;
-
-		bitmap_copy(copy->map.bits, irq->map.bits, PNP_IRQ_NR);
-		copy->flags = irq->flags;
-
-		copy->next = res->irq; /* Yes, this is NULL */
-		res->irq = copy;
-
-		if (!res->next)
-			break;
-		res = res->next;
-	}
-	kfree(irq);
+	irq->flags |= IORESOURCE_IRQ_OPTIONAL;
+	dev_info(&dev->dev, "made independent IRQ optional\n");
 
 	res->next = quirk_isapnp_mpu_options(dev);
-
-	res = dev->independent;
-	res->irq = NULL;
 }
 
 static void quirk_isapnp_mpu_resources(struct pnp_dev *dev)
Index: work10/drivers/pnp/interface.c
===================================================================
--- work10.orig/drivers/pnp/interface.c	2008-06-03 16:12:35.000000000 -0600
+++ work10/drivers/pnp/interface.c	2008-06-03 16:13:55.000000000 -0600
@@ -90,6 +90,8 @@ static void pnp_print_irq(pnp_info_buffe
 		pnp_printf(buffer, " High-Level");
 	if (irq->flags & IORESOURCE_IRQ_LOWLEVEL)
 		pnp_printf(buffer, " Low-Level");
+	if (irq->flags & IORESOURCE_IRQ_OPTIONAL)
+		pnp_printf(buffer, " (optional)");
 	pnp_printf(buffer, "\n");
 }
 

-- 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [patch 16/18] PNP: remove extra 0x100 bit from option priority
  2008-06-04 22:09 [patch 00/18] PNP: convert resource options to unified dynamic list, v2 Bjorn Helgaas
                   ` (14 preceding siblings ...)
  2008-06-04 22:09 ` [patch 15/18] PNP: support optional IRQ resources Bjorn Helgaas
@ 2008-06-04 22:09 ` Bjorn Helgaas
  2008-06-14  8:35   ` Rene Herman
  2008-06-04 22:09 ` [patch 17/18] ISAPNP: handle independent options following dependent ones Bjorn Helgaas
                   ` (2 subsequent siblings)
  18 siblings, 1 reply; 31+ messages in thread
From: Bjorn Helgaas @ 2008-06-04 22:09 UTC (permalink / raw)
  To: Len Brown
  Cc: linux-acpi, linux-kernel, Adam Belay, Adam M Belay, Li Shaohua,
	Matthieu Castet, Thomas Renninger, Rene Herman, Jaroslav Kysela,
	Andrew Morton, Takashi Iwai

[-- Attachment #1: pnp-remove-extra-priority-bits --]
[-- Type: text/plain, Size: 3231 bytes --]

When building resource options, ISAPNP and PNPBIOS set the priority
to something like "0x100 | PNP_RES_PRIORITY_ACCEPTABLE", but we 
immediately mask off the 0x100 again in pnp_build_option(), so that
bit looks superfluous.

Thanks to Rene Herman <rene.herman@gmail.com> for pointing this out.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>

Index: work10/drivers/pnp/isapnp/core.c
===================================================================
--- work10.orig/drivers/pnp/isapnp/core.c	2008-06-02 15:00:07.000000000 -0600
+++ work10/drivers/pnp/isapnp/core.c	2008-06-02 15:00:10.000000000 -0600
@@ -582,7 +582,7 @@ isapnp_parse_name(char *name, unsigned i
 static int __init isapnp_create_device(struct pnp_card *card,
 				       unsigned short size)
 {
-	int number = 0, skip = 0, priority = 0, compat = 0;
+	int number = 0, skip = 0, priority, compat = 0;
 	unsigned char type, tmp[17];
 	struct pnp_option *option;
 	struct pnp_dev *dev;
@@ -621,7 +621,6 @@ static int __init isapnp_create_device(s
 			} else {
 				skip = 1;
 			}
-			priority = 0;
 			compat = 0;
 			break;
 		case _STAG_COMPATDEVID:
@@ -650,10 +649,10 @@ static int __init isapnp_create_device(s
 		case _STAG_STARTDEP:
 			if (size > 1)
 				goto __skip;
-			priority = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE;
+			priority = PNP_RES_PRIORITY_ACCEPTABLE;
 			if (size > 0) {
 				isapnp_peek(tmp, size);
-				priority = 0x100 | tmp[0];
+				priority = tmp[0];
 				size = 0;
 			}
 			option = pnp_register_dependent_option(dev, priority);
@@ -663,7 +662,6 @@ static int __init isapnp_create_device(s
 		case _STAG_ENDDEP:
 			if (size != 0)
 				goto __skip;
-			priority = 0;
 			dev_dbg(&dev->dev, "end dependent options\n");
 			break;
 		case _STAG_IOPORT:
Index: work10/drivers/pnp/pnpbios/rsparser.c
===================================================================
--- work10.orig/drivers/pnp/pnpbios/rsparser.c	2008-06-02 15:00:07.000000000 -0600
+++ work10/drivers/pnp/pnpbios/rsparser.c	2008-06-02 15:00:10.000000000 -0600
@@ -315,7 +315,7 @@ pnpbios_parse_resource_option_data(unsig
 					struct pnp_dev *dev)
 {
 	unsigned int len, tag;
-	int priority = 0;
+	int priority;
 	struct pnp_option *option, *option_independent;
 
 	if (!p)
@@ -389,9 +389,9 @@ pnpbios_parse_resource_option_data(unsig
 		case SMALL_TAG_STARTDEP:
 			if (len > 1)
 				goto len_err;
-			priority = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE;
+			priority = PNP_RES_PRIORITY_ACCEPTABLE;
 			if (len > 0)
-				priority = 0x100 | p[1];
+				priority = p[1];
 			option = pnp_register_dependent_option(dev, priority);
 			if (!option)
 				return NULL;
Index: work10/drivers/pnp/pnpacpi/rsparser.c
===================================================================
--- work10.orig/drivers/pnp/pnpacpi/rsparser.c	2008-06-02 15:00:07.000000000 -0600
+++ work10/drivers/pnp/pnpacpi/rsparser.c	2008-06-02 15:00:10.000000000 -0600
@@ -545,7 +545,7 @@ struct acpipnp_parse_option_s {
 static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
 						  void *data)
 {
-	int priority = 0;
+	int priority;
 	struct acpipnp_parse_option_s *parse_data = data;
 	struct pnp_dev *dev = parse_data->dev;
 	struct pnp_option *option = parse_data->option;

-- 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [patch 17/18] ISAPNP: handle independent options following dependent ones
  2008-06-04 22:09 [patch 00/18] PNP: convert resource options to unified dynamic list, v2 Bjorn Helgaas
                   ` (15 preceding siblings ...)
  2008-06-04 22:09 ` [patch 16/18] PNP: remove extra 0x100 bit from option priority Bjorn Helgaas
@ 2008-06-04 22:09 ` Bjorn Helgaas
  2008-06-14  8:39   ` Rene Herman
  2008-06-04 22:09 ` [patch 18/18] PNP: convert resource options to single linked list Bjorn Helgaas
  2008-06-10  3:00 ` [patch 00/18] PNP: convert resource options to unified dynamic list, v2 Rene Herman
  18 siblings, 1 reply; 31+ messages in thread
From: Bjorn Helgaas @ 2008-06-04 22:09 UTC (permalink / raw)
  To: Len Brown
  Cc: linux-acpi, linux-kernel, Adam Belay, Adam M Belay, Li Shaohua,
	Matthieu Castet, Thomas Renninger, Rene Herman, Jaroslav Kysela,
	Andrew Morton, Takashi Iwai

[-- Attachment #1: isapnp-enddep-bugfix --]
[-- Type: text/plain, Size: 1829 bytes --]

The ISAPNP spec recommends that independent options precede
dependent ones, but this is not actually required.  The current
ISAPNP code incorrectly puts such trailing independent options
at the end of the last dependent option list.

This patch fixes that bug by resetting the current option list
to the independent list when we see an "End Dependent Functions"
tag.  PNPBIOS and PNPACPI handle this the same way.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>

Index: work10/drivers/pnp/isapnp/core.c
===================================================================
--- work10.orig/drivers/pnp/isapnp/core.c	2008-06-03 15:45:02.000000000 -0600
+++ work10/drivers/pnp/isapnp/core.c	2008-06-03 15:49:38.000000000 -0600
@@ -584,14 +584,14 @@ static int __init isapnp_create_device(s
 {
 	int number = 0, skip = 0, priority, compat = 0;
 	unsigned char type, tmp[17];
-	struct pnp_option *option;
+	struct pnp_option *option, *option_independent;
 	struct pnp_dev *dev;
 	u32 eisa_id;
 	char id[8];
 
 	if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
 		return 1;
-	option = pnp_register_independent_option(dev);
+	option_independent = option = pnp_register_independent_option(dev);
 	if (!option) {
 		kfree(dev);
 		return 1;
@@ -613,6 +613,7 @@ static int __init isapnp_create_device(s
 				size = 0;
 				skip = 0;
 				option = pnp_register_independent_option(dev);
+				option_independent = option;
 				if (!option) {
 					kfree(dev);
 					return 1;
@@ -662,6 +663,10 @@ static int __init isapnp_create_device(s
 		case _STAG_ENDDEP:
 			if (size != 0)
 				goto __skip;
+			if (option_independent == option)
+				dev_warn(&dev->dev, "missing "
+					 "_STAG_STARTDEP tag\n");
+			option = option_independent;
 			dev_dbg(&dev->dev, "end dependent options\n");
 			break;
 		case _STAG_IOPORT:

-- 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [patch 18/18] PNP: convert resource options to single linked list
  2008-06-04 22:09 [patch 00/18] PNP: convert resource options to unified dynamic list, v2 Bjorn Helgaas
                   ` (16 preceding siblings ...)
  2008-06-04 22:09 ` [patch 17/18] ISAPNP: handle independent options following dependent ones Bjorn Helgaas
@ 2008-06-04 22:09 ` Bjorn Helgaas
  2008-06-14 10:31   ` Rene Herman
  2008-06-10  3:00 ` [patch 00/18] PNP: convert resource options to unified dynamic list, v2 Rene Herman
  18 siblings, 1 reply; 31+ messages in thread
From: Bjorn Helgaas @ 2008-06-04 22:09 UTC (permalink / raw)
  To: Len Brown
  Cc: linux-acpi, linux-kernel, Adam Belay, Adam M Belay, Li Shaohua,
	Matthieu Castet, Thomas Renninger, Rene Herman, Jaroslav Kysela,
	Andrew Morton, Takashi Iwai

[-- Attachment #1: pnp-option-list --]
[-- Type: text/plain, Size: 63723 bytes --]

ISAPNP, PNPBIOS, and ACPI describe the "possible resource settings" of
a device, i.e., the possibilities an OS bus driver has when it assigns
I/O port, MMIO, and other resources to the device.

PNP used to maintain this "possible resource setting" information in
one independent option structure and a list of dependent option
structures for each device.  Each of these option structures had lists
of I/O, memory, IRQ, and DMA resources, for example:

  dev
    independent options
      ind-io0  -> ind-io1  ...
      ind-mem0 -> ind-mem1 ...
      ...
    dependent option set 0
      dep0-io0  -> dep0-io1  ...
      dep0-mem0 -> dep0-mem1 ...
      ...
    dependent option set 1
      dep1-io0  -> dep1-io1  ...
      dep1-mem0 -> dep1-mem1 ...
      ...
    ...

This data structure was designed for ISAPNP, where the OS configures
device resource settings by writing directly to configuration
registers.  The OS can write the registers in arbitrary order much
like it writes PCI BARs.

However, for PNPBIOS and ACPI devices, the OS uses firmware interfaces
that perform device configuration, and it is important to pass the
desired settings to those interfaces in the correct order.  The OS
learns the correct order by using firmware interfaces that return the
"current resource settings" and "possible resource settings," but the
option structures above doesn't store the ordering information.

This patch replaces the independent and dependent lists with a single
list of options.  For example, a device might have possible resource
settings like this:

  dev
    options
      ind-io0 -> dep0-io0 -> dep1->io0 -> ind-io1 ...

All the possible settings are in the same list, in the order they
come from the firmware "possible resource settings" list.  Each entry
is tagged with an independent/dependent flag.  Dependent entries also
have a "set number" and an optional priority value.  All dependent
entries must be assigned from the same set.  For example, the OS can
use all the entries from dependent set 0, or all the entries from
dependent set 1, but it cannot mix entries from set 0 with entries
from set 1.

Prior to this patch PNP didn't keep track of the order of this list,
and it assigned all independent options first, then all dependent
ones.  Using the example above, that resulted in a "desired
configuration" list like this:

  ind->io0 -> ind->io1 -> depN-io0 ...

instead of the list the firmware expects, which looks like this:

  ind->io0 -> depN-io0 -> ind-io1 ...

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>

---
 drivers/pnp/base.h             |   89 +++++++++---
 drivers/pnp/core.c             |    4 
 drivers/pnp/interface.c        |   75 ++++------
 drivers/pnp/isapnp/core.c      |   68 ++++-----
 drivers/pnp/manager.c          |  137 +++++--------------
 drivers/pnp/pnpacpi/rsparser.c |   93 +++++--------
 drivers/pnp/pnpbios/rsparser.c |   64 ++++-----
 drivers/pnp/quirks.c           |  288 ++++++++++++++++++++++-------------------
 drivers/pnp/resource.c         |  205 +++++------------------------
 drivers/pnp/support.c          |   79 +++++++++++
 include/linux/pnp.h            |    6 
 11 files changed, 524 insertions(+), 584 deletions(-)

Index: work10/drivers/pnp/base.h
===================================================================
--- work10.orig/drivers/pnp/base.h	2008-06-04 15:39:22.000000000 -0600
+++ work10/drivers/pnp/base.h	2008-06-04 15:39:35.000000000 -0600
@@ -1,3 +1,8 @@
+/*
+ * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
+ *	Bjorn Helgaas <bjorn.helgaas@hp.com>
+ */
+
 extern spinlock_t pnp_lock;
 void *pnp_alloc(long size);
 
@@ -25,8 +30,6 @@ struct pnp_port {
 	resource_size_t align;	/* align boundary */
 	resource_size_t size;	/* size of range */
 	unsigned char flags;	/* port flags */
-	unsigned char pad;	/* pad */
-	struct pnp_port *next;	/* next port */
 };
 
 #define PNP_IRQ_NR 256
@@ -35,14 +38,11 @@ typedef struct { DECLARE_BITMAP(bits, PN
 struct pnp_irq {
 	pnp_irq_mask_t map;	/* bitmap for IRQ lines */
 	unsigned char flags;	/* IRQ flags */
-	unsigned char pad;	/* pad */
-	struct pnp_irq *next;	/* next IRQ */
 };
 
 struct pnp_dma {
 	unsigned char map;	/* bitmask for DMA channels */
 	unsigned char flags;	/* DMA flags */
-	struct pnp_dma *next;	/* next port */
 };
 
 struct pnp_mem {
@@ -51,44 +51,96 @@ struct pnp_mem {
 	resource_size_t align;	/* align boundary */
 	resource_size_t size;	/* size of range */
 	unsigned char flags;	/* memory flags */
-	unsigned char pad;	/* pad */
-	struct pnp_mem *next;	/* next memory resource */
 };
 
+#define PNP_OPTION_DEPENDENT		0x80000000
+#define PNP_OPTION_SET_MASK		0xffff
+#define PNP_OPTION_SET_SHIFT		12
+#define PNP_OPTION_PRIORITY_MASK	0xfff
+#define PNP_OPTION_PRIORITY_SHIFT	0
+
 #define PNP_RES_PRIORITY_PREFERRED	0
 #define PNP_RES_PRIORITY_ACCEPTABLE	1
 #define PNP_RES_PRIORITY_FUNCTIONAL	2
-#define PNP_RES_PRIORITY_INVALID	65535
+#define PNP_RES_PRIORITY_INVALID	PNP_OPTION_PRIORITY_MASK
 
 struct pnp_option {
-	unsigned short priority;	/* priority */
-	struct pnp_port *port;		/* first port */
-	struct pnp_irq *irq;		/* first IRQ */
-	struct pnp_dma *dma;		/* first DMA */
-	struct pnp_mem *mem;		/* first memory resource */
-	struct pnp_option *next;	/* used to chain dependent resources */
+	struct list_head list;
+	unsigned int flags;	/* independent/dependent, set, priority */
+
+	unsigned long type;	/* IORESOURCE_{IO,MEM,IRQ,DMA} */
+	union {
+		struct pnp_port port;
+		struct pnp_irq irq;
+		struct pnp_dma dma;
+		struct pnp_mem mem;
+	} u;
 };
 
-struct pnp_option *pnp_build_option(int priority);
-struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev);
-struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev,
-						 int priority);
-int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option,
+int pnp_register_irq_resource(struct pnp_dev *dev, unsigned int option_flags,
 			      pnp_irq_mask_t *map, unsigned char flags);
-int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option,
+int pnp_register_dma_resource(struct pnp_dev *dev, unsigned int option_flags,
 			      unsigned char map, unsigned char flags);
-int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option,
+int pnp_register_port_resource(struct pnp_dev *dev, unsigned int option_flags,
 			       resource_size_t min, resource_size_t max,
 			       resource_size_t align, resource_size_t size,
 			       unsigned char flags);
-int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option,
+int pnp_register_mem_resource(struct pnp_dev *dev, unsigned int option_flags,
 			      resource_size_t min, resource_size_t max,
 			      resource_size_t align, resource_size_t size,
 			      unsigned char flags);
+
+static inline int pnp_option_is_dependent(struct pnp_option *option)
+{
+	return option->flags & PNP_OPTION_DEPENDENT ? 1 : 0;
+}
+
+static inline unsigned int pnp_option_set(struct pnp_option *option)
+{
+	return (option->flags >> PNP_OPTION_SET_SHIFT) & PNP_OPTION_SET_MASK;
+}
+
+static inline unsigned int pnp_option_priority(struct pnp_option *option)
+{
+	return (option->flags >> PNP_OPTION_PRIORITY_SHIFT) &
+	    PNP_OPTION_PRIORITY_MASK;
+}
+
+static inline unsigned int pnp_independent_option(void)
+{
+	return 0;
+}
+
+static inline unsigned int pnp_new_dependent_set(struct pnp_dev *dev,
+						 int priority)
+{
+	unsigned int flags;
+
+	if (priority > PNP_RES_PRIORITY_FUNCTIONAL) {
+		dev_warn(&dev->dev, "invalid dependent option priority %d "
+			 "clipped to %d", priority,
+			 PNP_RES_PRIORITY_INVALID);
+		priority = PNP_RES_PRIORITY_INVALID;
+	}
+
+	flags = PNP_OPTION_DEPENDENT |
+	    ((dev->num_dependent_sets & PNP_OPTION_SET_MASK) <<
+		PNP_OPTION_SET_SHIFT) |
+	    ((priority & PNP_OPTION_PRIORITY_MASK) <<
+		PNP_OPTION_PRIORITY_SHIFT);
+
+	dev->num_dependent_sets++;
+
+	return flags;
+}
+
+char *pnp_option_priority_name(struct pnp_option *option);
+void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option);
+
 void pnp_init_resources(struct pnp_dev *dev);
 
 void pnp_fixup_device(struct pnp_dev *dev);
-void pnp_free_option(struct pnp_option *option);
+void pnp_free_options(struct pnp_dev *dev);
 int __pnp_add_device(struct pnp_dev *dev);
 void __pnp_remove_device(struct pnp_dev *dev);
 
Index: work10/drivers/pnp/core.c
===================================================================
--- work10.orig/drivers/pnp/core.c	2008-06-04 15:28:37.000000000 -0600
+++ work10/drivers/pnp/core.c	2008-06-04 15:39:35.000000000 -0600
@@ -118,10 +118,9 @@ static void pnp_release_device(struct de
 {
 	struct pnp_dev *dev = to_pnp_dev(dmdev);
 
-	pnp_free_option(dev->independent);
-	pnp_free_option(dev->dependent);
 	pnp_free_ids(dev);
 	pnp_free_resources(dev);
+	pnp_free_options(dev);
 	kfree(dev);
 }
 
@@ -135,6 +134,7 @@ struct pnp_dev *pnp_alloc_dev(struct pnp
 		return NULL;
 
 	INIT_LIST_HEAD(&dev->resources);
+	INIT_LIST_HEAD(&dev->options);
 	dev->protocol = protocol;
 	dev->number = id;
 	dev->dma_mask = DMA_24BIT_MASK;
Index: work10/drivers/pnp/interface.c
===================================================================
--- work10.orig/drivers/pnp/interface.c	2008-06-04 15:39:24.000000000 -0600
+++ work10/drivers/pnp/interface.c	2008-06-04 15:39:35.000000000 -0600
@@ -3,6 +3,8 @@
  *
  * Some code, especially possible resource dumping is based on isapnp_proc.c (c) Jaroslav Kysela <perex@perex.cz>
  * Copyright 2002 Adam Belay <ambx1@neo.rr.com>
+ * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
+ *	Bjorn Helgaas <bjorn.helgaas@hp.com>
  */
 
 #include <linux/pnp.h>
@@ -184,39 +186,22 @@ static void pnp_print_mem(pnp_info_buffe
 }
 
 static void pnp_print_option(pnp_info_buffer_t * buffer, char *space,
-			     struct pnp_option *option, int dep)
+			     struct pnp_option *option)
 {
-	char *s;
-	struct pnp_port *port;
-	struct pnp_irq *irq;
-	struct pnp_dma *dma;
-	struct pnp_mem *mem;
-
-	if (dep) {
-		switch (option->priority) {
-		case PNP_RES_PRIORITY_PREFERRED:
-			s = "preferred";
-			break;
-		case PNP_RES_PRIORITY_ACCEPTABLE:
-			s = "acceptable";
-			break;
-		case PNP_RES_PRIORITY_FUNCTIONAL:
-			s = "functional";
-			break;
-		default:
-			s = "invalid";
-		}
-		pnp_printf(buffer, "Dependent: %02i - Priority %s\n", dep, s);
+	switch (option->type) {
+	case IORESOURCE_IO:
+		pnp_print_port(buffer, space, &option->u.port);
+		break;
+	case IORESOURCE_MEM:
+		pnp_print_mem(buffer, space, &option->u.mem);
+		break;
+	case IORESOURCE_IRQ:
+		pnp_print_irq(buffer, space, &option->u.irq);
+		break;
+	case IORESOURCE_DMA:
+		pnp_print_dma(buffer, space, &option->u.dma);
+		break;
 	}
-
-	for (port = option->port; port; port = port->next)
-		pnp_print_port(buffer, space, port);
-	for (irq = option->irq; irq; irq = irq->next)
-		pnp_print_irq(buffer, space, irq);
-	for (dma = option->dma; dma; dma = dma->next)
-		pnp_print_dma(buffer, space, dma);
-	for (mem = option->mem; mem; mem = mem->next)
-		pnp_print_mem(buffer, space, mem);
 }
 
 static ssize_t pnp_show_options(struct device *dmdev,
@@ -224,9 +209,9 @@ static ssize_t pnp_show_options(struct d
 {
 	struct pnp_dev *dev = to_pnp_dev(dmdev);
 	pnp_info_buffer_t *buffer;
-	struct pnp_option *independent = dev->independent;
-	struct pnp_option *dependent = dev->dependent;
-	int ret, dep = 1;
+	struct pnp_option *option;
+	int ret, dep = 0, set = 0;
+	char *indent;
 
 	buffer = pnp_alloc(sizeof(pnp_info_buffer_t));
 	if (!buffer)
@@ -235,14 +220,24 @@ static ssize_t pnp_show_options(struct d
 	buffer->len = PAGE_SIZE;
 	buffer->buffer = buf;
 	buffer->curr = buffer->buffer;
-	if (independent)
-		pnp_print_option(buffer, "", independent, 0);
 
-	while (dependent) {
-		pnp_print_option(buffer, "   ", dependent, dep);
-		dependent = dependent->next;
-		dep++;
+	list_for_each_entry(option, &dev->options, list) {
+		if (pnp_option_is_dependent(option)) {
+			indent = "  ";
+			if (!dep || pnp_option_set(option) != set) {
+				set = pnp_option_set(option);
+				dep = 1;
+				pnp_printf(buffer, "Dependent: %02i - "
+					   "Priority %s\n", set,
+					   pnp_option_priority_name(option));
+			}
+		} else {
+			dep = 0;
+			indent ="";
+		}
+		pnp_print_option(buffer, indent, option);
 	}
+
 	ret = (buffer->curr - buf);
 	kfree(buffer);
 	return ret;
Index: work10/drivers/pnp/isapnp/core.c
===================================================================
--- work10.orig/drivers/pnp/isapnp/core.c	2008-06-04 15:39:27.000000000 -0600
+++ work10/drivers/pnp/isapnp/core.c	2008-06-04 15:39:35.000000000 -0600
@@ -429,7 +429,7 @@ static struct pnp_dev *__init isapnp_par
  *  Add IRQ resource to resources list.
  */
 static void __init isapnp_parse_irq_resource(struct pnp_dev *dev,
-					     struct pnp_option *option,
+					     unsigned int option_flags,
 					     int size)
 {
 	unsigned char tmp[3];
@@ -446,27 +446,27 @@ static void __init isapnp_parse_irq_reso
 	if (size > 2)
 		flags = tmp[2];
 
-	pnp_register_irq_resource(dev, option, &map, flags);
+	pnp_register_irq_resource(dev, option_flags, &map, flags);
 }
 
 /*
  *  Add DMA resource to resources list.
  */
 static void __init isapnp_parse_dma_resource(struct pnp_dev *dev,
-					     struct pnp_option *option,
+					     unsigned int option_flags,
 					     int size)
 {
 	unsigned char tmp[2];
 
 	isapnp_peek(tmp, size);
-	pnp_register_dma_resource(dev, option, tmp[0], tmp[1]);
+	pnp_register_dma_resource(dev, option_flags, tmp[0], tmp[1]);
 }
 
 /*
  *  Add port resource to resources list.
  */
 static void __init isapnp_parse_port_resource(struct pnp_dev *dev,
-					      struct pnp_option *option,
+					      unsigned int option_flags,
 					      int size)
 {
 	unsigned char tmp[7];
@@ -479,14 +479,15 @@ static void __init isapnp_parse_port_res
 	align = tmp[5];
 	len = tmp[6];
 	flags = tmp[0] ? IORESOURCE_IO_16BIT_ADDR : 0;
-	pnp_register_port_resource(dev, option, min, max, align, len, flags);
+	pnp_register_port_resource(dev, option_flags,
+				   min, max, align, len, flags);
 }
 
 /*
  *  Add fixed port resource to resources list.
  */
 static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev,
-						    struct pnp_option *option,
+						    unsigned int option_flags,
 						    int size)
 {
 	unsigned char tmp[3];
@@ -495,7 +496,7 @@ static void __init isapnp_parse_fixed_po
 	isapnp_peek(tmp, size);
 	base = (tmp[1] << 8) | tmp[0];
 	len = tmp[2];
-	pnp_register_port_resource(dev, option, base, base, 0, len,
+	pnp_register_port_resource(dev, option_flags, base, base, 0, len,
 				   IORESOURCE_IO_FIXED);
 }
 
@@ -503,7 +504,7 @@ static void __init isapnp_parse_fixed_po
  *  Add memory resource to resources list.
  */
 static void __init isapnp_parse_mem_resource(struct pnp_dev *dev,
-					     struct pnp_option *option,
+					     unsigned int option_flags,
 					     int size)
 {
 	unsigned char tmp[9];
@@ -516,14 +517,15 @@ static void __init isapnp_parse_mem_reso
 	align = (tmp[6] << 8) | tmp[5];
 	len = ((tmp[8] << 8) | tmp[7]) << 8;
 	flags = tmp[0];
-	pnp_register_mem_resource(dev, option, min, max, align, len, flags);
+	pnp_register_mem_resource(dev, option_flags,
+				  min, max, align, len, flags);
 }
 
 /*
  *  Add 32-bit memory resource to resources list.
  */
 static void __init isapnp_parse_mem32_resource(struct pnp_dev *dev,
-					       struct pnp_option *option,
+					       unsigned int option_flags,
 					       int size)
 {
 	unsigned char tmp[17];
@@ -536,14 +538,15 @@ static void __init isapnp_parse_mem32_re
 	align = (tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9];
 	len = (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13];
 	flags = tmp[0];
-	pnp_register_mem_resource(dev, option, min, max, align, len, flags);
+	pnp_register_mem_resource(dev, option_flags,
+				  min, max, align, len, flags);
 }
 
 /*
  *  Add 32-bit fixed memory resource to resources list.
  */
 static void __init isapnp_parse_fixed_mem32_resource(struct pnp_dev *dev,
-						     struct pnp_option *option,
+						     unsigned int option_flags,
 						     int size)
 {
 	unsigned char tmp[9];
@@ -554,7 +557,7 @@ static void __init isapnp_parse_fixed_me
 	base = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
 	len = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
 	flags = tmp[0];
-	pnp_register_mem_resource(dev, option, base, base, 0, len, flags);
+	pnp_register_mem_resource(dev, option_flags, base, base, 0, len, flags);
 }
 
 /*
@@ -584,18 +587,14 @@ static int __init isapnp_create_device(s
 {
 	int number = 0, skip = 0, priority, compat = 0;
 	unsigned char type, tmp[17];
-	struct pnp_option *option, *option_independent;
+	unsigned int option_flags;
 	struct pnp_dev *dev;
 	u32 eisa_id;
 	char id[8];
 
 	if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
 		return 1;
-	option_independent = option = pnp_register_independent_option(dev);
-	if (!option) {
-		kfree(dev);
-		return 1;
-	}
+	option_flags = pnp_independent_option();
 	pnp_add_card_device(card, dev);
 
 	while (1) {
@@ -612,12 +611,7 @@ static int __init isapnp_create_device(s
 					return 1;
 				size = 0;
 				skip = 0;
-				option = pnp_register_independent_option(dev);
-				option_independent = option;
-				if (!option) {
-					kfree(dev);
-					return 1;
-				}
+				option_flags = pnp_independent_option();
 				pnp_add_card_device(card, dev);
 			} else {
 				skip = 1;
@@ -638,13 +632,13 @@ static int __init isapnp_create_device(s
 		case _STAG_IRQ:
 			if (size < 2 || size > 3)
 				goto __skip;
-			isapnp_parse_irq_resource(dev, option, size);
+			isapnp_parse_irq_resource(dev, option_flags, size);
 			size = 0;
 			break;
 		case _STAG_DMA:
 			if (size != 2)
 				goto __skip;
-			isapnp_parse_dma_resource(dev, option, size);
+			isapnp_parse_dma_resource(dev, option_flags, size);
 			size = 0;
 			break;
 		case _STAG_STARTDEP:
@@ -656,29 +650,24 @@ static int __init isapnp_create_device(s
 				priority = tmp[0];
 				size = 0;
 			}
-			option = pnp_register_dependent_option(dev, priority);
-			if (!option)
-				return 1;
+			option_flags = pnp_new_dependent_set(dev, priority);
 			break;
 		case _STAG_ENDDEP:
 			if (size != 0)
 				goto __skip;
-			if (option_independent == option)
-				dev_warn(&dev->dev, "missing "
-					 "_STAG_STARTDEP tag\n");
-			option = option_independent;
-			dev_dbg(&dev->dev, "end dependent options\n");
+			option_flags = pnp_independent_option();
 			break;
 		case _STAG_IOPORT:
 			if (size != 7)
 				goto __skip;
-			isapnp_parse_port_resource(dev, option, size);
+			isapnp_parse_port_resource(dev, option_flags, size);
 			size = 0;
 			break;
 		case _STAG_FIXEDIO:
 			if (size != 3)
 				goto __skip;
-			isapnp_parse_fixed_port_resource(dev, option, size);
+			isapnp_parse_fixed_port_resource(dev, option_flags,
+							 size);
 			size = 0;
 			break;
 		case _STAG_VENDOR:
@@ -686,7 +675,7 @@ static int __init isapnp_create_device(s
 		case _LTAG_MEMRANGE:
 			if (size != 9)
 				goto __skip;
-			isapnp_parse_mem_resource(dev, option, size);
+			isapnp_parse_mem_resource(dev, option_flags, size);
 			size = 0;
 			break;
 		case _LTAG_ANSISTR:
@@ -701,13 +690,14 @@ static int __init isapnp_create_device(s
 		case _LTAG_MEM32RANGE:
 			if (size != 17)
 				goto __skip;
-			isapnp_parse_mem32_resource(dev, option, size);
+			isapnp_parse_mem32_resource(dev, option_flags, size);
 			size = 0;
 			break;
 		case _LTAG_FIXEDMEM32RANGE:
 			if (size != 9)
 				goto __skip;
-			isapnp_parse_fixed_mem32_resource(dev, option, size);
+			isapnp_parse_fixed_mem32_resource(dev, option_flags,
+							  size);
 			size = 0;
 			break;
 		case _STAG_END:
Index: work10/drivers/pnp/manager.c
===================================================================
--- work10.orig/drivers/pnp/manager.c	2008-06-04 15:39:24.000000000 -0600
+++ work10/drivers/pnp/manager.c	2008-06-04 15:39:35.000000000 -0600
@@ -3,6 +3,8 @@
  *
  * based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz>
  * Copyright 2003 Adam Belay <ambx1@neo.rr.com>
+ * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
+ *	Bjorn Helgaas <bjorn.helgaas@hp.com>
  */
 
 #include <linux/errno.h>
@@ -228,102 +230,51 @@ static void pnp_clean_resource_table(str
 /**
  * pnp_assign_resources - assigns resources to the device based on the specified dependent number
  * @dev: pointer to the desired device
- * @depnum: the dependent function number
- *
- * Only set depnum to 0 if the device does not have dependent options.
+ * @set: the dependent function number
  */
-static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
+static int pnp_assign_resources(struct pnp_dev *dev, int set)
 {
-	struct pnp_port *port;
-	struct pnp_mem *mem;
-	struct pnp_irq *irq;
-	struct pnp_dma *dma;
+	struct pnp_option *option;
 	int nport = 0, nmem = 0, nirq = 0, ndma = 0;
+	int ret = 0;
 
-	dbg_pnp_show_resources(dev, "before pnp_assign_resources");
+	dev_dbg(&dev->dev, "pnp_assign_resources, try dependent set %d\n", set);
 	mutex_lock(&pnp_res_mutex);
 	pnp_clean_resource_table(dev);
-	if (dev->independent) {
-		dev_dbg(&dev->dev, "assigning independent options\n");
-		port = dev->independent->port;
-		mem = dev->independent->mem;
-		irq = dev->independent->irq;
-		dma = dev->independent->dma;
-		while (port) {
-			if (pnp_assign_port(dev, port, nport) < 0)
-				goto fail;
-			nport++;
-			port = port->next;
-		}
-		while (mem) {
-			if (pnp_assign_mem(dev, mem, nmem) < 0)
-				goto fail;
-			nmem++;
-			mem = mem->next;
-		}
-		while (irq) {
-			if (pnp_assign_irq(dev, irq, nirq) < 0)
-				goto fail;
-			nirq++;
-			irq = irq->next;
-		}
-		while (dma) {
-			if (pnp_assign_dma(dev, dma, ndma) < 0)
-				goto fail;
-			ndma++;
-			dma = dma->next;
-		}
-	}
 
-	if (depnum) {
-		struct pnp_option *dep;
-		int i;
-
-		dev_dbg(&dev->dev, "assigning dependent option %d\n", depnum);
-		for (i = 1, dep = dev->dependent; i < depnum;
-		     i++, dep = dep->next)
-			if (!dep)
-				goto fail;
-		port = dep->port;
-		mem = dep->mem;
-		irq = dep->irq;
-		dma = dep->dma;
-		while (port) {
-			if (pnp_assign_port(dev, port, nport) < 0)
-				goto fail;
-			nport++;
-			port = port->next;
-		}
-		while (mem) {
-			if (pnp_assign_mem(dev, mem, nmem) < 0)
-				goto fail;
-			nmem++;
-			mem = mem->next;
-		}
-		while (irq) {
-			if (pnp_assign_irq(dev, irq, nirq) < 0)
-				goto fail;
-			nirq++;
-			irq = irq->next;
-		}
-		while (dma) {
-			if (pnp_assign_dma(dev, dma, ndma) < 0)
-				goto fail;
-			ndma++;
-			dma = dma->next;
+	list_for_each_entry(option, &dev->options, list) {
+		if (pnp_option_is_dependent(option) &&
+		    pnp_option_set(option) != set)
+				continue;
+
+		switch (option->type) {
+		case IORESOURCE_IO:
+			ret = pnp_assign_port(dev, &option->u.port, nport++);
+			break;
+		case IORESOURCE_MEM:
+			ret = pnp_assign_mem(dev, &option->u.mem, nmem++);
+			break;
+		case IORESOURCE_IRQ:
+			ret = pnp_assign_irq(dev, &option->u.irq, nirq++);
+			break;
+		case IORESOURCE_DMA:
+			ret = pnp_assign_dma(dev, &option->u.dma, ndma++);
+			break;
+		default:
+			ret = -EINVAL;
+			break;
 		}
-	} else if (dev->dependent)
-		goto fail;
-
-	mutex_unlock(&pnp_res_mutex);
-	dbg_pnp_show_resources(dev, "after pnp_assign_resources");
-	return 1;
+		if (ret < 0)
+			break;
+	}
 
-fail:
-	pnp_clean_resource_table(dev);
 	mutex_unlock(&pnp_res_mutex);
-	dbg_pnp_show_resources(dev, "after pnp_assign_resources (failed)");
-	return 0;
+	if (ret) {
+		dev_dbg(&dev->dev, "pnp_assign_resources failed (%d)\n", ret);
+		pnp_clean_resource_table(dev);
+	} else
+		dbg_pnp_show_resources(dev, "pnp_assign_resources succeeded");
+	return ret;
 }
 
 /**
@@ -332,29 +283,25 @@ fail:
  */
 int pnp_auto_config_dev(struct pnp_dev *dev)
 {
-	struct pnp_option *dep;
-	int i = 1;
+	int i, ret = 0;
 
 	if (!pnp_can_configure(dev)) {
 		dev_dbg(&dev->dev, "configuration not supported\n");
 		return -ENODEV;
 	}
 
-	if (!dev->dependent) {
-		if (pnp_assign_resources(dev, 0))
+	ret = pnp_assign_resources(dev, 0);
+	if (ret == 0)
+		return 0;
+
+	for (i = 1; i < dev->num_dependent_sets; i++) {
+		ret = pnp_assign_resources(dev, i);
+		if (ret == 0)
 			return 0;
-	} else {
-		dep = dev->dependent;
-		do {
-			if (pnp_assign_resources(dev, i))
-				return 0;
-			dep = dep->next;
-			i++;
-		} while (dep);
 	}
 
 	dev_err(&dev->dev, "unable to assign resources\n");
-	return -EBUSY;
+	return ret;
 }
 
 /**
Index: work10/drivers/pnp/pnpacpi/rsparser.c
===================================================================
--- work10.orig/drivers/pnp/pnpacpi/rsparser.c	2008-06-04 15:39:25.000000000 -0600
+++ work10/drivers/pnp/pnpacpi/rsparser.c	2008-06-04 15:39:35.000000000 -0600
@@ -373,7 +373,7 @@ int pnpacpi_parse_allocated_resource(str
 }
 
 static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev,
-					    struct pnp_option *option,
+					    unsigned int option_flags,
 					    struct acpi_resource_dma *p)
 {
 	int i;
@@ -386,11 +386,11 @@ static __init void pnpacpi_parse_dma_opt
 		map |= 1 << p->channels[i];
 
 	flags = dma_flags(p->type, p->bus_master, p->transfer);
-	pnp_register_dma_resource(dev, option, map, flags);
+	pnp_register_dma_resource(dev, option_flags, map, flags);
 }
 
 static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev,
-					    struct pnp_option *option,
+					    unsigned int option_flags,
 					    struct acpi_resource_irq *p)
 {
 	int i;
@@ -406,11 +406,11 @@ static __init void pnpacpi_parse_irq_opt
 			__set_bit(p->interrupts[i], map.bits);
 
 	flags = irq_flags(p->triggering, p->polarity, p->sharable);
-	pnp_register_irq_resource(dev, option, &map, flags);
+	pnp_register_irq_resource(dev, option_flags, &map, flags);
 }
 
 static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev,
-						struct pnp_option *option,
+					unsigned int option_flags,
 					struct acpi_resource_extended_irq *p)
 {
 	int i;
@@ -433,11 +433,11 @@ static __init void pnpacpi_parse_ext_irq
 	}
 
 	flags = irq_flags(p->triggering, p->polarity, p->sharable);
-	pnp_register_irq_resource(dev, option, &map, flags);
+	pnp_register_irq_resource(dev, option_flags, &map, flags);
 }
 
 static __init void pnpacpi_parse_port_option(struct pnp_dev *dev,
-					     struct pnp_option *option,
+					     unsigned int option_flags,
 					     struct acpi_resource_io *io)
 {
 	unsigned char flags = 0;
@@ -447,23 +447,23 @@ static __init void pnpacpi_parse_port_op
 
 	if (io->io_decode == ACPI_DECODE_16)
 		flags = IORESOURCE_IO_16BIT_ADDR;
-	pnp_register_port_resource(dev, option, io->minimum, io->maximum,
+	pnp_register_port_resource(dev, option_flags, io->minimum, io->maximum,
 				   io->alignment, io->address_length, flags);
 }
 
 static __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev,
-						   struct pnp_option *option,
+					unsigned int option_flags,
 					struct acpi_resource_fixed_io *io)
 {
 	if (io->address_length == 0)
 		return;
 
-	pnp_register_port_resource(dev, option, io->address, io->address, 0,
-				   io->address_length, IORESOURCE_IO_FIXED);
+	pnp_register_port_resource(dev, option_flags, io->address, io->address,
+				   0, io->address_length, IORESOURCE_IO_FIXED);
 }
 
 static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev,
-					      struct pnp_option *option,
+					      unsigned int option_flags,
 					      struct acpi_resource_memory24 *p)
 {
 	unsigned char flags = 0;
@@ -473,12 +473,12 @@ static __init void pnpacpi_parse_mem24_o
 
 	if (p->write_protect == ACPI_READ_WRITE_MEMORY)
 		flags = IORESOURCE_MEM_WRITEABLE;
-	pnp_register_mem_resource(dev, option, p->minimum, p->maximum,
+	pnp_register_mem_resource(dev, option_flags, p->minimum, p->maximum,
 				  p->alignment, p->address_length, flags);
 }
 
 static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev,
-					      struct pnp_option *option,
+					      unsigned int option_flags,
 					      struct acpi_resource_memory32 *p)
 {
 	unsigned char flags = 0;
@@ -488,12 +488,12 @@ static __init void pnpacpi_parse_mem32_o
 
 	if (p->write_protect == ACPI_READ_WRITE_MEMORY)
 		flags = IORESOURCE_MEM_WRITEABLE;
-	pnp_register_mem_resource(dev, option, p->minimum, p->maximum,
+	pnp_register_mem_resource(dev, option_flags, p->minimum, p->maximum,
 				  p->alignment, p->address_length, flags);
 }
 
 static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev,
-						    struct pnp_option *option,
+					unsigned int option_flags,
 					struct acpi_resource_fixed_memory32 *p)
 {
 	unsigned char flags = 0;
@@ -503,12 +503,12 @@ static __init void pnpacpi_parse_fixed_m
 
 	if (p->write_protect == ACPI_READ_WRITE_MEMORY)
 		flags = IORESOURCE_MEM_WRITEABLE;
-	pnp_register_mem_resource(dev, option, p->address, p->address,
+	pnp_register_mem_resource(dev, option_flags, p->address, p->address,
 				  0, p->address_length, flags);
 }
 
 static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
-						struct pnp_option *option,
+						unsigned int option_flags,
 						struct acpi_resource *r)
 {
 	struct acpi_resource_address64 addr, *p = &addr;
@@ -528,18 +528,18 @@ static __init void pnpacpi_parse_address
 	if (p->resource_type == ACPI_MEMORY_RANGE) {
 		if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY)
 			flags = IORESOURCE_MEM_WRITEABLE;
-		pnp_register_mem_resource(dev, option, p->minimum, p->minimum,
-					  0, p->address_length, flags);
+		pnp_register_mem_resource(dev, option_flags, p->minimum,
+					  p->minimum, 0, p->address_length,
+					  flags);
 	} else if (p->resource_type == ACPI_IO_RANGE)
-		pnp_register_port_resource(dev, option, p->minimum, p->minimum,
-					   0, p->address_length,
+		pnp_register_port_resource(dev, option_flags, p->minimum,
+					   p->minimum, 0, p->address_length,
 					   IORESOURCE_IO_FIXED);
 }
 
 struct acpipnp_parse_option_s {
-	struct pnp_option *option;
-	struct pnp_option *option_independent;
 	struct pnp_dev *dev;
+	unsigned int option_flags;
 };
 
 static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
@@ -548,15 +548,15 @@ static __init acpi_status pnpacpi_option
 	int priority;
 	struct acpipnp_parse_option_s *parse_data = data;
 	struct pnp_dev *dev = parse_data->dev;
-	struct pnp_option *option = parse_data->option;
+	unsigned int option_flags = parse_data->option_flags;
 
 	switch (res->type) {
 	case ACPI_RESOURCE_TYPE_IRQ:
-		pnpacpi_parse_irq_option(dev, option, &res->data.irq);
+		pnpacpi_parse_irq_option(dev, option_flags, &res->data.irq);
 		break;
 
 	case ACPI_RESOURCE_TYPE_DMA:
-		pnpacpi_parse_dma_option(dev, option, &res->data.dma);
+		pnpacpi_parse_dma_option(dev, option_flags, &res->data.dma);
 		break;
 
 	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -576,31 +576,19 @@ static __init acpi_status pnpacpi_option
 			priority = PNP_RES_PRIORITY_INVALID;
 			break;
 		}
-		/* TBD: Consider performance/robustness bits */
-		option = pnp_register_dependent_option(dev, priority);
-		if (!option)
-			return AE_ERROR;
-		parse_data->option = option;
+		parse_data->option_flags = pnp_new_dependent_set(dev, priority);
 		break;
 
 	case ACPI_RESOURCE_TYPE_END_DEPENDENT:
-		/*only one EndDependentFn is allowed */
-		if (!parse_data->option_independent) {
-			dev_warn(&dev->dev, "more than one EndDependentFn "
-				 "in _PRS\n");
-			return AE_ERROR;
-		}
-		parse_data->option = parse_data->option_independent;
-		parse_data->option_independent = NULL;
-		dev_dbg(&dev->dev, "end dependent options\n");
+		parse_data->option_flags = pnp_independent_option();
 		break;
 
 	case ACPI_RESOURCE_TYPE_IO:
-		pnpacpi_parse_port_option(dev, option, &res->data.io);
+		pnpacpi_parse_port_option(dev, option_flags, &res->data.io);
 		break;
 
 	case ACPI_RESOURCE_TYPE_FIXED_IO:
-		pnpacpi_parse_fixed_port_option(dev, option,
+		pnpacpi_parse_fixed_port_option(dev, option_flags,
 					        &res->data.fixed_io);
 		break;
 
@@ -609,29 +597,31 @@ static __init acpi_status pnpacpi_option
 		break;
 
 	case ACPI_RESOURCE_TYPE_MEMORY24:
-		pnpacpi_parse_mem24_option(dev, option, &res->data.memory24);
+		pnpacpi_parse_mem24_option(dev, option_flags,
+					   &res->data.memory24);
 		break;
 
 	case ACPI_RESOURCE_TYPE_MEMORY32:
-		pnpacpi_parse_mem32_option(dev, option, &res->data.memory32);
+		pnpacpi_parse_mem32_option(dev, option_flags,
+					   &res->data.memory32);
 		break;
 
 	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
-		pnpacpi_parse_fixed_mem32_option(dev, option,
+		pnpacpi_parse_fixed_mem32_option(dev, option_flags,
 						 &res->data.fixed_memory32);
 		break;
 
 	case ACPI_RESOURCE_TYPE_ADDRESS16:
 	case ACPI_RESOURCE_TYPE_ADDRESS32:
 	case ACPI_RESOURCE_TYPE_ADDRESS64:
-		pnpacpi_parse_address_option(dev, option, res);
+		pnpacpi_parse_address_option(dev, option_flags, res);
 		break;
 
 	case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
 		break;
 
 	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
-		pnpacpi_parse_ext_irq_option(dev, option,
+		pnpacpi_parse_ext_irq_option(dev, option_flags,
 					     &res->data.extended_irq);
 		break;
 
@@ -655,12 +645,9 @@ int __init pnpacpi_parse_resource_option
 
 	dev_dbg(&dev->dev, "parse resource options\n");
 
-	parse_data.option = pnp_register_independent_option(dev);
-	if (!parse_data.option)
-		return -ENOMEM;
-
-	parse_data.option_independent = parse_data.option;
 	parse_data.dev = dev;
+	parse_data.option_flags = pnp_independent_option();
+
 	status = acpi_walk_resources(handle, METHOD_NAME__PRS,
 				     pnpacpi_option_resource, &parse_data);
 
Index: work10/drivers/pnp/pnpbios/rsparser.c
===================================================================
--- work10.orig/drivers/pnp/pnpbios/rsparser.c	2008-06-04 15:39:25.000000000 -0600
+++ work10/drivers/pnp/pnpbios/rsparser.c	2008-06-04 15:39:35.000000000 -0600
@@ -216,7 +216,7 @@ len_err:
 
 static __init void pnpbios_parse_mem_option(struct pnp_dev *dev,
 					    unsigned char *p, int size,
-					    struct pnp_option *option)
+					    unsigned int option_flags)
 {
 	resource_size_t min, max, align, len;
 	unsigned char flags;
@@ -226,12 +226,13 @@ static __init void pnpbios_parse_mem_opt
 	align = (p[9] << 8) | p[8];
 	len = ((p[11] << 8) | p[10]) << 8;
 	flags = p[3];
-	pnp_register_mem_resource(dev, option, min, max, align, len, flags);
+	pnp_register_mem_resource(dev, option_flags, min, max, align, len,
+				  flags);
 }
 
 static __init void pnpbios_parse_mem32_option(struct pnp_dev *dev,
 					      unsigned char *p, int size,
-					      struct pnp_option *option)
+					      unsigned int option_flags)
 {
 	resource_size_t min, max, align, len;
 	unsigned char flags;
@@ -241,12 +242,13 @@ static __init void pnpbios_parse_mem32_o
 	align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12];
 	len = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16];
 	flags = p[3];
-	pnp_register_mem_resource(dev, option, min, max, align, len, flags);
+	pnp_register_mem_resource(dev, option_flags, min, max, align, len,
+				  flags);
 }
 
 static __init void pnpbios_parse_fixed_mem32_option(struct pnp_dev *dev,
 						    unsigned char *p, int size,
-						    struct pnp_option *option)
+						    unsigned int option_flags)
 {
 	resource_size_t base, len;
 	unsigned char flags;
@@ -254,12 +256,12 @@ static __init void pnpbios_parse_fixed_m
 	base = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
 	len = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
 	flags = p[3];
-	pnp_register_mem_resource(dev, option, base, base, 0, len, flags);
+	pnp_register_mem_resource(dev, option_flags, base, base, 0, len, flags);
 }
 
 static __init void pnpbios_parse_irq_option(struct pnp_dev *dev,
 					    unsigned char *p, int size,
-					    struct pnp_option *option)
+					    unsigned int option_flags)
 {
 	unsigned long bits;
 	pnp_irq_mask_t map;
@@ -273,19 +275,19 @@ static __init void pnpbios_parse_irq_opt
 	if (size > 2)
 		flags = p[3];
 
-	pnp_register_irq_resource(dev, option, &map, flags);
+	pnp_register_irq_resource(dev, option_flags, &map, flags);
 }
 
 static __init void pnpbios_parse_dma_option(struct pnp_dev *dev,
 					    unsigned char *p, int size,
-					    struct pnp_option *option)
+					    unsigned int option_flags)
 {
-	pnp_register_dma_resource(dev, option, p[1], p[2]);
+	pnp_register_dma_resource(dev, option_flags, p[1], p[2]);
 }
 
 static __init void pnpbios_parse_port_option(struct pnp_dev *dev,
 					     unsigned char *p, int size,
-					     struct pnp_option *option)
+					     unsigned int option_flags)
 {
 	resource_size_t min, max, align, len;
 	unsigned char flags;
@@ -295,38 +297,35 @@ static __init void pnpbios_parse_port_op
 	align = p[6];
 	len = p[7];
 	flags = p[1] ? IORESOURCE_IO_16BIT_ADDR : 0;
-	pnp_register_port_resource(dev, option, min, max, align, len, flags);
+	pnp_register_port_resource(dev, option_flags, min, max, align, len,
+				   flags);
 }
 
 static __init void pnpbios_parse_fixed_port_option(struct pnp_dev *dev,
 						   unsigned char *p, int size,
-						   struct pnp_option *option)
+						   unsigned int option_flags)
 {
 	resource_size_t base, len;
 
 	base = (p[2] << 8) | p[1];
 	len = p[3];
-	pnp_register_port_resource(dev, option, base, base, 0, len,
+	pnp_register_port_resource(dev, option_flags, base, base, 0, len,
 				   IORESOURCE_IO_FIXED);
 }
 
 static __init unsigned char *
 pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
-					struct pnp_dev *dev)
+				   struct pnp_dev *dev)
 {
 	unsigned int len, tag;
 	int priority;
-	struct pnp_option *option, *option_independent;
+	unsigned int option_flags;
 
 	if (!p)
 		return NULL;
 
 	dev_dbg(&dev->dev, "parse resource options\n");
-
-	option_independent = option = pnp_register_independent_option(dev);
-	if (!option)
-		return NULL;
-
+	option_flags = pnp_independent_option();
 	while ((char *)p < (char *)end) {
 
 		/* determine the type of tag */
@@ -343,37 +342,38 @@ pnpbios_parse_resource_option_data(unsig
 		case LARGE_TAG_MEM:
 			if (len != 9)
 				goto len_err;
-			pnpbios_parse_mem_option(dev, p, len, option);
+			pnpbios_parse_mem_option(dev, p, len, option_flags);
 			break;
 
 		case LARGE_TAG_MEM32:
 			if (len != 17)
 				goto len_err;
-			pnpbios_parse_mem32_option(dev, p, len, option);
+			pnpbios_parse_mem32_option(dev, p, len, option_flags);
 			break;
 
 		case LARGE_TAG_FIXEDMEM32:
 			if (len != 9)
 				goto len_err;
-			pnpbios_parse_fixed_mem32_option(dev, p, len, option);
+			pnpbios_parse_fixed_mem32_option(dev, p, len,
+							 option_flags);
 			break;
 
 		case SMALL_TAG_IRQ:
 			if (len < 2 || len > 3)
 				goto len_err;
-			pnpbios_parse_irq_option(dev, p, len, option);
+			pnpbios_parse_irq_option(dev, p, len, option_flags);
 			break;
 
 		case SMALL_TAG_DMA:
 			if (len != 2)
 				goto len_err;
-			pnpbios_parse_dma_option(dev, p, len, option);
+			pnpbios_parse_dma_option(dev, p, len, option_flags);
 			break;
 
 		case SMALL_TAG_PORT:
 			if (len != 7)
 				goto len_err;
-			pnpbios_parse_port_option(dev, p, len, option);
+			pnpbios_parse_port_option(dev, p, len, option_flags);
 			break;
 
 		case SMALL_TAG_VENDOR:
@@ -383,7 +383,8 @@ pnpbios_parse_resource_option_data(unsig
 		case SMALL_TAG_FIXEDPORT:
 			if (len != 3)
 				goto len_err;
-			pnpbios_parse_fixed_port_option(dev, p, len, option);
+			pnpbios_parse_fixed_port_option(dev, p, len,
+							option_flags);
 			break;
 
 		case SMALL_TAG_STARTDEP:
@@ -392,19 +393,13 @@ pnpbios_parse_resource_option_data(unsig
 			priority = PNP_RES_PRIORITY_ACCEPTABLE;
 			if (len > 0)
 				priority = p[1];
-			option = pnp_register_dependent_option(dev, priority);
-			if (!option)
-				return NULL;
+			option_flags = pnp_new_dependent_set(dev, priority);
 			break;
 
 		case SMALL_TAG_ENDDEP:
 			if (len != 0)
 				goto len_err;
-			if (option_independent == option)
-				dev_warn(&dev->dev, "missing "
-					 "SMALL_TAG_STARTDEP tag\n");
-			option = option_independent;
-			dev_dbg(&dev->dev, "end dependent options\n");
+			option_flags = pnp_independent_option();
 			break;
 
 		case SMALL_TAG_END:
Index: work10/drivers/pnp/quirks.c
===================================================================
--- work10.orig/drivers/pnp/quirks.c	2008-06-04 15:39:24.000000000 -0600
+++ work10/drivers/pnp/quirks.c	2008-06-04 15:39:35.000000000 -0600
@@ -5,6 +5,8 @@
  *  when building up the resource structure for the first time.
  *
  *  Copyright (c) 2000 Peter Denison <peterd@pnd-pc.demon.co.uk>
+ *  Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
+ *	Bjorn Helgaas <bjorn.helgaas@hp.com>
  *
  *  Heavily based on PCI quirks handling which is
  *
@@ -20,188 +22,207 @@
 #include <linux/kallsyms.h>
 #include "base.h"
 
+static void quirk_awe32_add_ports(struct pnp_dev *dev,
+				  struct pnp_option *option,
+				  unsigned int offset)
+{
+	struct pnp_option *new_option;
+
+	new_option = kmalloc(sizeof(struct pnp_option), GFP_KERNEL);
+	if (!new_option) {
+		dev_err(&dev->dev, "couldn't add ioport region to option set "
+			"%d\n", pnp_option_set(option));
+		return;
+	}
+
+	*new_option = *option;
+	new_option->u.port.min += offset;
+	new_option->u.port.max += offset;
+	list_add(&new_option->list, &option->list);
+
+	dev_info(&dev->dev, "added ioport region %#llx-%#llx to set %d\n",
+		(unsigned long long) new_option->u.port.min,
+		(unsigned long long) new_option->u.port.max,
+		pnp_option_set(option));
+}
+
 static void quirk_awe32_resources(struct pnp_dev *dev)
 {
-	struct pnp_port *port, *port2, *port3;
-	struct pnp_option *res = dev->dependent;
+	struct pnp_option *option;
+	unsigned int set = ~0;
 
 	/*
-	 * Unfortunately the isapnp_add_port_resource is too tightly bound
-	 * into the PnP discovery sequence, and cannot be used. Link in the
-	 * two extra ports (at offset 0x400 and 0x800 from the one given) by
-	 * hand.
+	 * Add two extra ioport regions (at offset 0x400 and 0x800 from the
+	 * one given) to every dependent option set.
 	 */
-	for (; res; res = res->next) {
-		port2 = pnp_alloc(sizeof(struct pnp_port));
-		if (!port2)
-			return;
-		port3 = pnp_alloc(sizeof(struct pnp_port));
-		if (!port3) {
-			kfree(port2);
-			return;
+	list_for_each_entry(option, &dev->options, list) {
+		if (pnp_option_is_dependent(option) &&
+		    pnp_option_set(option) != set) {
+			set = pnp_option_set(option);
+			quirk_awe32_add_ports(dev, option, 0x800);
+			quirk_awe32_add_ports(dev, option, 0x400);
 		}
-		port = res->port;
-		memcpy(port2, port, sizeof(struct pnp_port));
-		memcpy(port3, port, sizeof(struct pnp_port));
-		port->next = port2;
-		port2->next = port3;
-		port2->min += 0x400;
-		port2->max += 0x400;
-		port3->min += 0x800;
-		port3->max += 0x800;
-		dev_info(&dev->dev,
-			"AWE32 quirk - added ioports 0x%lx and 0x%lx\n",
-			(unsigned long)port2->min,
-			(unsigned long)port3->min);
 	}
 }
 
 static void quirk_cmi8330_resources(struct pnp_dev *dev)
 {
-	struct pnp_option *res = dev->dependent;
-	unsigned long tmp;
-
-	for (; res; res = res->next) {
-
-		struct pnp_irq *irq;
-		struct pnp_dma *dma;
+	struct pnp_option *option;
+	struct pnp_irq *irq;
+	struct pnp_dma *dma;
 
-		for (irq = res->irq; irq; irq = irq->next) {	// Valid irqs are 5, 7, 10
-			tmp = 0x04A0;
-			bitmap_copy(irq->map.bits, &tmp, 16);	// 0000 0100 1010 0000
-		}
+	list_for_each_entry(option, &dev->options, list) {
+		if (!pnp_option_is_dependent(option))
+			continue;
 
-		for (dma = res->dma; dma; dma = dma->next)	// Valid 8bit dma channels are 1,3
+		if (option->type == IORESOURCE_IRQ) {
+			irq = &option->u.irq;
+			bitmap_zero(irq->map.bits, PNP_IRQ_NR);
+			__set_bit(5, irq->map.bits);
+			__set_bit(7, irq->map.bits);
+			__set_bit(10, irq->map.bits);
+			dev_info(&dev->dev, "set possible IRQs in "
+				 "option set %d to 5, 7, 10\n",
+				 pnp_option_set(option));
+		} else if (option->type == IORESOURCE_DMA) {
+			dma = &option->u.dma;
 			if ((dma->flags & IORESOURCE_DMA_TYPE_MASK) ==
-			    IORESOURCE_DMA_8BIT)
-				dma->map = 0x000A;
+						IORESOURCE_DMA_8BIT &&
+			    dma->map != 0x0A) {
+				dev_info(&dev->dev, "changing possible "
+					 "DMA channel mask in option set %d "
+					 "from %#02x to 0x0A (1, 3)\n",
+					 pnp_option_set(option), dma->map);
+				dma->map = 0x0A;
+			}
+		}
 	}
-	dev_info(&dev->dev, "CMI8330 quirk - forced possible IRQs to 5, 7, 10 "
-		"and DMA channels to 1, 3\n");
 }
 
 static void quirk_sb16audio_resources(struct pnp_dev *dev)
 {
+	struct pnp_option *option;
+	unsigned int prev_option_flags = ~0, n = 0;
 	struct pnp_port *port;
-	struct pnp_option *res = dev->dependent;
-	int changed = 0;
 
 	/*
-	 * The default range on the mpu port for these devices is 0x388-0x388.
+	 * The default range on the OPL port for these devices is 0x388-0x388.
 	 * Here we increase that range so that two such cards can be
 	 * auto-configured.
 	 */
+	list_for_each_entry(option, &dev->options, list) {
+		if (prev_option_flags != option->flags) {
+			prev_option_flags = option->flags;
+			n = 0;
+		}
 
-	for (; res; res = res->next) {
-		port = res->port;
-		if (!port)
-			continue;
-		port = port->next;
-		if (!port)
-			continue;
-		port = port->next;
-		if (!port)
-			continue;
-		if (port->min != port->max)
-			continue;
-		port->max += 0x70;
-		changed = 1;
+		if (pnp_option_is_dependent(option) &&
+		    option->type == IORESOURCE_IO) {
+			n++;
+			port = &option->u.port;
+			if (n == 3 && port->min == port->max) {
+				port->max += 0x70;
+				dev_info(&dev->dev, "increased option port "
+					 "range from %#llx-%#llx to "
+					 "%#llx-%#llx\n",
+					 (unsigned long long) port->min,
+					 (unsigned long long) port->min,
+					 (unsigned long long) port->min,
+					 (unsigned long long) port->max);
+			}
+		}
 	}
-	if (changed)
-		dev_info(&dev->dev, "SB audio device quirk - increased port range\n");
 }
 
-static struct pnp_option *quirk_isapnp_mpu_options(struct pnp_dev *dev)
+static struct pnp_option *pnp_clone_dependent_set(struct pnp_dev *dev,
+						  unsigned int set)
 {
-	struct pnp_option *head = NULL;
-	struct pnp_option *prev = NULL;
-	struct pnp_option *res;
-
-	/*
-	 * Build a functional IRQ-optional variant of each MPU option.
-	 */
-
-	for (res = dev->dependent; res; res = res->next) {
-		struct pnp_option *curr;
-		struct pnp_port *port;
-		struct pnp_port *copy_port;
-		struct pnp_irq *irq;
-		struct pnp_irq *copy_irq;
-
-		port = res->port;
-		irq = res->irq;
-		if (!port || !irq)
-			continue;
+	struct pnp_option *tail = NULL, *first_new_option = NULL;
+	struct pnp_option *option, *new_option;
+	unsigned int flags;
+
+	list_for_each_entry(option, &dev->options, list) {
+		if (pnp_option_is_dependent(option))
+			tail = option;
+	}
+	if (!tail) {
+		dev_err(&dev->dev, "no dependent option sets\n");
+		return NULL;
+	}
 
-		copy_port = pnp_alloc(sizeof *copy_port);
-		if (!copy_port)
-			break;
-
-		copy_irq = pnp_alloc(sizeof *copy_irq);
-		if (!copy_irq) {
-			kfree(copy_port);
-			break;
-		}
+	flags = pnp_new_dependent_set(dev, PNP_RES_PRIORITY_FUNCTIONAL);
+	list_for_each_entry(option, &dev->options, list) {
+		if (pnp_option_is_dependent(option) &&
+		    pnp_option_set(option) == set) {
+			new_option = kmalloc(sizeof(struct pnp_option),
+					     GFP_KERNEL);
+			if (!new_option) {
+				dev_err(&dev->dev, "couldn't clone dependent "
+					"set %d\n", set);
+				return NULL;
+			}
 
-		*copy_port = *port;
-		copy_port->next = NULL;
+			*new_option = *option;
+			new_option->flags = flags;
+			if (!first_new_option)
+				first_new_option = new_option;
 
-		*copy_irq = *irq;
-		copy_irq->flags |= IORESOURCE_IRQ_OPTIONAL;
-		copy_irq->next = NULL;
-
-		curr = pnp_build_option(PNP_RES_PRIORITY_FUNCTIONAL);
-		if (!curr) {
-			kfree(copy_port);
-			kfree(copy_irq);
-			break;
+			list_add(&new_option->list, &tail->list);
+			tail = new_option;
 		}
-		curr->port = copy_port;
-		curr->irq = copy_irq;
-
-		if (prev)
-			prev->next = curr;
-		else
-			head = curr;
-		prev = curr;
 	}
-	if (head)
-		dev_info(&dev->dev, "adding IRQ-optional MPU options\n");
 
-	return head;
+	return first_new_option;
 }
 
-static void quirk_ad1815_mpu_resources(struct pnp_dev *dev)
+
+static void quirk_add_irq_optional_dependent_sets(struct pnp_dev *dev)
 {
-	struct pnp_option *res;
+	struct pnp_option *new_option;
+	unsigned int num_sets, i, set;
 	struct pnp_irq *irq;
 
-	res = dev->independent;
-	if (!res)
-		return;
-
-	irq = res->irq;
-	if (!irq || irq->next)
-		return;
+	num_sets = dev->num_dependent_sets;
+	for (i = 0; i < num_sets; i++) {
+		new_option = pnp_clone_dependent_set(dev, i);
+		if (!new_option)
+			return;
 
-	irq->flags |= IORESOURCE_IRQ_OPTIONAL;
-	dev_info(&dev->dev, "made independent IRQ optional\n");
+		set = pnp_option_set(new_option);
+		while (new_option && pnp_option_set(new_option) == set) {
+			if (new_option->type == IORESOURCE_IRQ) {
+				irq = &new_option->u.irq;
+				irq->flags |= IORESOURCE_IRQ_OPTIONAL;
+			}
+			dbg_pnp_show_option(dev, new_option);
+			new_option = list_entry(new_option->list.next,
+						struct pnp_option, list);
+		}
 
-	res->next = quirk_isapnp_mpu_options(dev);
+		dev_info(&dev->dev, "added dependent option set %d (same as "
+			 "set %d except IRQ optional)\n", set, i);
+	}
 }
 
-static void quirk_isapnp_mpu_resources(struct pnp_dev *dev)
+static void quirk_ad1815_mpu_resources(struct pnp_dev *dev)
 {
-	struct pnp_option *res;
+	struct pnp_option *option;
+	struct pnp_irq *irq = NULL;
+	unsigned int independent_irqs = 0;
+
+	list_for_each_entry(option, &dev->options, list) {
+		if (option->type == IORESOURCE_IRQ &&
+		    !pnp_option_is_dependent(option)) {
+			independent_irqs++;
+			irq = &option->u.irq;
+		}
+	}
 
-	res = dev->dependent;
-	if (!res)
+	if (independent_irqs != 1)
 		return;
 
-	while (res->next)
-		res = res->next;
-
-	res->next = quirk_isapnp_mpu_options(dev);
+	irq->flags |= IORESOURCE_IRQ_OPTIONAL;
+	dev_info(&dev->dev, "made independent IRQ optional\n");
 }
 
 #include <linux/pci.h>
@@ -296,10 +317,10 @@ static struct pnp_fixup pnp_fixups[] = {
 	{"CTL0043", quirk_sb16audio_resources},
 	{"CTL0044", quirk_sb16audio_resources},
 	{"CTL0045", quirk_sb16audio_resources},
-	/* Add IRQ-less MPU options */
+	/* Add IRQ-optional MPU options */
 	{"ADS7151", quirk_ad1815_mpu_resources},
-	{"ADS7181", quirk_isapnp_mpu_resources},
-	{"AZT0002", quirk_isapnp_mpu_resources},
+	{"ADS7181", quirk_add_irq_optional_dependent_sets},
+	{"AZT0002", quirk_add_irq_optional_dependent_sets},
 	/* PnP resources that might overlap PCI BARs */
 	{"PNP0c01", quirk_system_pci_resources},
 	{"PNP0c02", quirk_system_pci_resources},
Index: work10/drivers/pnp/resource.c
===================================================================
--- work10.orig/drivers/pnp/resource.c	2008-06-04 15:39:23.000000000 -0600
+++ work10/drivers/pnp/resource.c	2008-06-04 15:48:36.000000000 -0600
@@ -3,6 +3,8 @@
  *
  * based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz>
  * Copyright 2003 Adam Belay <ambx1@neo.rr.com>
+ * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
+ *	Bjorn Helgaas <bjorn.helgaas@hp.com>
  */
 
 #include <linux/module.h>
@@ -28,78 +30,36 @@ static int pnp_reserve_mem[16] = {[0 ...
  * option registration
  */
 
-struct pnp_option *pnp_build_option(int priority)
+struct pnp_option *pnp_build_option(struct pnp_dev *dev, unsigned long type,
+				    unsigned int option_flags)
 {
-	struct pnp_option *option = pnp_alloc(sizeof(struct pnp_option));
+	struct pnp_option *option;
 
+	option = kzalloc(sizeof(struct pnp_option), GFP_KERNEL);
 	if (!option)
 		return NULL;
 
-	option->priority = priority & 0xff;
-	/* make sure the priority is valid */
-	if (option->priority > PNP_RES_PRIORITY_FUNCTIONAL)
-		option->priority = PNP_RES_PRIORITY_INVALID;
+	option->flags = option_flags;
+	option->type = type;
 
+	list_add_tail(&option->list, &dev->options);
 	return option;
 }
 
-struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev)
-{
-	struct pnp_option *option;
-
-	option = pnp_build_option(PNP_RES_PRIORITY_PREFERRED);
-
-	/* this should never happen but if it does we'll try to continue */
-	if (dev->independent)
-		dev_err(&dev->dev, "independent resource already registered\n");
-	dev->independent = option;
-
-	dev_dbg(&dev->dev, "new independent option\n");
-	return option;
-}
-
-struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev,
-						 int priority)
-{
-	struct pnp_option *option;
-
-	option = pnp_build_option(priority);
-
-	if (dev->dependent) {
-		struct pnp_option *parent = dev->dependent;
-		while (parent->next)
-			parent = parent->next;
-		parent->next = option;
-	} else
-		dev->dependent = option;
-
-	dev_dbg(&dev->dev, "new dependent option (priority %#x)\n", priority);
-	return option;
-}
-
-int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option,
+int pnp_register_irq_resource(struct pnp_dev *dev, unsigned int option_flags,
 			      pnp_irq_mask_t *map, unsigned char flags)
 {
-	struct pnp_irq *irq, *ptr;
-#ifdef DEBUG
-	char buf[PNP_IRQ_NR];   /* hex-encoded, so this is overkill but safe */
-#endif
+	struct pnp_option *option;
+	struct pnp_irq *irq;
 
-	irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
-	if (!irq)
+	option = pnp_build_option(dev, IORESOURCE_IRQ, option_flags);
+	if (!option)
 		return -ENOMEM;
 
+	irq = &option->u.irq;
 	irq->map = *map;
 	irq->flags = flags;
 
-	ptr = option->irq;
-	while (ptr && ptr->next)
-		ptr = ptr->next;
-	if (ptr)
-		ptr->next = irq;
-	else
-		option->irq = irq;
-
 #ifdef CONFIG_PCI
 	{
 		int i;
@@ -110,163 +70,81 @@ int pnp_register_irq_resource(struct pnp
 	}
 #endif
 
-#ifdef DEBUG
-	bitmap_scnprintf(buf, sizeof(buf), irq->map.bits, PNP_IRQ_NR);
-	dev_dbg(&dev->dev, "  irq bitmask %s flags %#x\n", buf,
-		irq->flags);
-#endif
+	dbg_pnp_show_option(dev, option);
 	return 0;
 }
 
-int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option,
+int pnp_register_dma_resource(struct pnp_dev *dev, unsigned int option_flags,
 			      unsigned char map, unsigned char flags)
 {
-	struct pnp_dma *dma, *ptr;
+	struct pnp_option *option;
+	struct pnp_dma *dma;
 
-	dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
-	if (!dma)
+	option = pnp_build_option(dev, IORESOURCE_DMA, option_flags);
+	if (!option)
 		return -ENOMEM;
 
+	dma = &option->u.dma;
 	dma->map = map;
 	dma->flags = flags;
 
-	ptr = option->dma;
-	while (ptr && ptr->next)
-		ptr = ptr->next;
-	if (ptr)
-		ptr->next = dma;
-	else
-		option->dma = dma;
-
-	dev_dbg(&dev->dev, "  dma bitmask %#x flags %#x\n", dma->map,
-		dma->flags);
+	dbg_pnp_show_option(dev, option);
 	return 0;
 }
 
-int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option,
+int pnp_register_port_resource(struct pnp_dev *dev, unsigned int option_flags,
 			       resource_size_t min, resource_size_t max,
 			       resource_size_t align, resource_size_t size,
 			       unsigned char flags)
 {
-	struct pnp_port *port, *ptr;
+	struct pnp_option *option;
+	struct pnp_port *port;
 
-	port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
-	if (!port)
+	option = pnp_build_option(dev, IORESOURCE_IO, option_flags);
+	if (!option)
 		return -ENOMEM;
 
+	port = &option->u.port;
 	port->min = min;
 	port->max = max;
 	port->align = align;
 	port->size = size;
 	port->flags = flags;
 
-	ptr = option->port;
-	while (ptr && ptr->next)
-		ptr = ptr->next;
-	if (ptr)
-		ptr->next = port;
-	else
-		option->port = port;
-
-	dev_dbg(&dev->dev, "  io  "
-		"min %#llx max %#llx align %lld size %lld flags %#x\n",
-		(unsigned long long) port->min,
-		(unsigned long long) port->max,
-		(unsigned long long) port->align,
-		(unsigned long long) port->size, port->flags);
+	dbg_pnp_show_option(dev, option);
 	return 0;
 }
 
-int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option,
+int pnp_register_mem_resource(struct pnp_dev *dev, unsigned int option_flags,
 			      resource_size_t min, resource_size_t max,
 			      resource_size_t align, resource_size_t size,
 			      unsigned char flags)
 {
-	struct pnp_mem *mem, *ptr;
+	struct pnp_option *option;
+	struct pnp_mem *mem;
 
-	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
-	if (!mem)
+	option = pnp_build_option(dev, IORESOURCE_MEM, option_flags);
+	if (!option)
 		return -ENOMEM;
 
+	mem = &option->u.mem;
 	mem->min = min;
 	mem->max = max;
 	mem->align = align;
 	mem->size = size;
 	mem->flags = flags;
 
-	ptr = option->mem;
-	while (ptr && ptr->next)
-		ptr = ptr->next;
-	if (ptr)
-		ptr->next = mem;
-	else
-		option->mem = mem;
-
-	dev_dbg(&dev->dev, "  mem "
-		"min %#llx max %#llx align %lld size %lld flags %#x\n",
-		(unsigned long long) mem->min,
-		(unsigned long long) mem->max,
-		(unsigned long long) mem->align,
-		(unsigned long long) mem->size, mem->flags);
+	dbg_pnp_show_option(dev, option);
 	return 0;
 }
 
-static void pnp_free_port(struct pnp_port *port)
-{
-	struct pnp_port *next;
-
-	while (port) {
-		next = port->next;
-		kfree(port);
-		port = next;
-	}
-}
-
-static void pnp_free_irq(struct pnp_irq *irq)
+void pnp_free_options(struct pnp_dev *dev)
 {
-	struct pnp_irq *next;
-
-	while (irq) {
-		next = irq->next;
-		kfree(irq);
-		irq = next;
-	}
-}
+	struct pnp_option *option, *tmp;
 
-static void pnp_free_dma(struct pnp_dma *dma)
-{
-	struct pnp_dma *next;
-
-	while (dma) {
-		next = dma->next;
-		kfree(dma);
-		dma = next;
-	}
-}
-
-static void pnp_free_mem(struct pnp_mem *mem)
-{
-	struct pnp_mem *next;
-
-	while (mem) {
-		next = mem->next;
-		kfree(mem);
-		mem = next;
-	}
-}
-
-void pnp_free_option(struct pnp_option *option)
-{
-	struct pnp_option *next;
-
-	while (option) {
-		next = option->next;
-		pnp_free_port(option->port);
-		pnp_free_irq(option->irq);
-		pnp_free_dma(option->dma);
-		pnp_free_mem(option->mem);
+	list_for_each_entry_safe(option, tmp, &dev->options, list) {
+		list_del(&option->list);
 		kfree(option);
-		option = next;
 	}
 }
 
@@ -668,44 +546,44 @@ struct pnp_resource *pnp_add_mem_resourc
 	return pnp_res;
 }
 
-static int pnp_possible_option(struct pnp_option *option, int type,
-			       resource_size_t start, resource_size_t size)
+/*
+ * Determine whether the specified resource is a possible configuration
+ * for this device.
+ */
+int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t start,
+			resource_size_t size)
 {
-	struct pnp_option *tmp;
+	struct pnp_option *option;
 	struct pnp_port *port;
 	struct pnp_mem *mem;
 	struct pnp_irq *irq;
 	struct pnp_dma *dma;
 
-	if (!option)
-		return 0;
+	list_for_each_entry(option, &dev->options, list) {
+		if (option->type != type)
+			continue;
 
-	for (tmp = option; tmp; tmp = tmp->next) {
-		switch (type) {
+		switch (option->type) {
 		case IORESOURCE_IO:
-			for (port = tmp->port; port; port = port->next) {
-				if (port->min == start && port->size == size)
-					return 1;
-			}
+			port = &option->u.port;
+			if (port->min == start && port->size == size)
+				return 1;
 			break;
 		case IORESOURCE_MEM:
-			for (mem = tmp->mem; mem; mem = mem->next) {
-				if (mem->min == start && mem->size == size)
-					return 1;
-			}
+			mem = &option->u.mem;
+			if (mem->min == start && mem->size == size)
+				return 1;
 			break;
 		case IORESOURCE_IRQ:
-			for (irq = tmp->irq; irq; irq = irq->next) {
-				if (start < PNP_IRQ_NR &&
-				    test_bit(start, irq->map.bits))
-					return 1;
-			}
+			irq = &option->u.irq;
+			if (start < PNP_IRQ_NR &&
+			    test_bit(start, irq->map.bits))
+				return 1;
 			break;
 		case IORESOURCE_DMA:
-			for (dma = tmp->dma; dma; dma = dma->next) {
-				if (dma->map & (1 << start))
-					return 1;
-			}
+			dma = &option->u.dma;
+			if (dma->map & (1 << start))
+				return 1;
 			break;
 		}
 	}
@@ -713,22 +591,6 @@ static int pnp_possible_option(struct pn
 	return 0;
 }
 
-/*
- * Determine whether the specified resource is a possible configuration
- * for this device.
- */
-int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t start,
-			resource_size_t size)
-{
-	if (pnp_possible_option(dev->independent, type, start, size))
-		return 1;
-
-	if (pnp_possible_option(dev->dependent, type, start, size))
-		return 1;
-
-	return 0;
-}
-
 /* format is: pnp_reserve_irq=irq1[,irq2] .... */
 static int __init pnp_setup_reserve_irq(char *str)
 {
Index: work10/drivers/pnp/support.c
===================================================================
--- work10.orig/drivers/pnp/support.c	2008-06-04 15:39:19.000000000 -0600
+++ work10/drivers/pnp/support.c	2008-06-04 15:39:35.000000000 -0600
@@ -2,6 +2,8 @@
  * support.c - standard functions for the use of pnp protocol drivers
  *
  * Copyright 2003 Adam Belay <ambx1@neo.rr.com>
+ * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
+ *	Bjorn Helgaas <bjorn.helgaas@hp.com>
  */
 
 #include <linux/module.h>
@@ -110,3 +112,80 @@ void dbg_pnp_show_resources(struct pnp_d
 	}
 #endif
 }
+
+char *pnp_option_priority_name(struct pnp_option *option)
+{
+	switch (pnp_option_priority(option)) {
+	case PNP_RES_PRIORITY_PREFERRED:
+		return "preferred";
+	case PNP_RES_PRIORITY_ACCEPTABLE:
+		return "acceptable";
+	case PNP_RES_PRIORITY_FUNCTIONAL:
+		return "functional";
+	}
+	return "invalid";
+}
+
+void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option)
+{
+#ifdef DEBUG
+	struct pnp_port *port;
+	struct pnp_mem *mem;
+	struct pnp_irq *irq;
+	struct pnp_dma *dma;
+	int i;
+
+	if (pnp_option_is_dependent(option))
+		dev_dbg(&dev->dev, "  dependent set %d (%s) ",
+			pnp_option_set(option),
+			pnp_option_priority_name(option));
+	else
+		dev_dbg(&dev->dev, "  independent ");
+
+	switch (option->type) {
+	case IORESOURCE_IO:
+		port = &option->u.port;
+		printk("io  min %#llx max %#llx align %lld size %lld flags %#x",
+			(unsigned long long) port->min,
+			(unsigned long long) port->max,
+			(unsigned long long) port->align,
+			(unsigned long long) port->size, port->flags);
+		break;
+	case IORESOURCE_MEM:
+		mem = &option->u.mem;
+		printk("mem min %#llx max %#llx align %lld size %lld flags %#x",
+		       (unsigned long long) mem->min,
+		       (unsigned long long) mem->max,
+		       (unsigned long long) mem->align,
+		       (unsigned long long) mem->size, mem->flags);
+		break;
+	case IORESOURCE_IRQ:
+		irq = &option->u.irq;
+		printk("irq");
+		if (bitmap_empty(irq->map.bits, PNP_IRQ_NR))
+			printk(" <none>");
+		else {
+			for (i = 0; i < PNP_IRQ_NR; i++)
+				if (test_bit(i, irq->map.bits))
+					printk(" %d", i);
+		}
+		printk(" flags %#x", irq->flags);
+		if (irq->flags & IORESOURCE_IRQ_OPTIONAL)
+			printk(" (optional)");
+		break;
+	case IORESOURCE_DMA:
+		dma = &option->u.dma;
+		printk("dma");
+		if (!dma->map)
+			printk(" <none>");
+		else {
+			for (i = 0; i < 8; i++)
+				if (dma->map & (1 << i))
+					printk(" %d", i);
+		}
+		printk(" (bitmask %#x) flags %#x", dma->map, dma->flags);
+		break;
+	}
+	printk("\n");
+#endif
+}
Index: work10/include/linux/pnp.h
===================================================================
--- work10.orig/include/linux/pnp.h	2008-06-04 15:38:19.000000000 -0600
+++ work10/include/linux/pnp.h	2008-06-04 15:39:35.000000000 -0600
@@ -1,6 +1,8 @@
 /*
  * Linux Plug and Play Support
  * Copyright by Adam Belay <ambx1@neo.rr.com>
+ * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
+ *	Bjorn Helgaas <bjorn.helgaas@hp.com>
  */
 
 #ifndef _LINUX_PNP_H
@@ -242,9 +244,9 @@ struct pnp_dev {
 
 	int active;
 	int capabilities;
-	struct pnp_option *independent;
-	struct pnp_option *dependent;
+	unsigned int num_dependent_sets;
 	struct list_head resources;
+	struct list_head options;
 
 	char name[PNP_NAME_LEN];	/* contains a human-readable name */
 	int flags;			/* used by protocols */

-- 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [patch 00/18] PNP: convert resource options to unified dynamic list, v2
  2008-06-04 22:09 [patch 00/18] PNP: convert resource options to unified dynamic list, v2 Bjorn Helgaas
                   ` (17 preceding siblings ...)
  2008-06-04 22:09 ` [patch 18/18] PNP: convert resource options to single linked list Bjorn Helgaas
@ 2008-06-10  3:00 ` Rene Herman
  2008-06-10 17:08   ` Bjorn Helgaas
  18 siblings, 1 reply; 31+ messages in thread
From: Rene Herman @ 2008-06-10  3:00 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Len Brown, linux-acpi, linux-kernel, Adam Belay, Adam M Belay,
	Li Shaohua, Matthieu Castet, Thomas Renninger, Jaroslav Kysela,
	Andrew Morton, Takashi Iwai

On 05-06-08 00:09, Bjorn Helgaas wrote:

> This patch series converts the PNP resource option structures
> to a unified linked list.  This preserves resource order, which
> is important for some devices.  The bulk of the series is in
> the last patch, and it has more a more detailed changelog.
> 
> Rene Herman did some testing of ISA devices and reviewed
> v1 of this series.  I think I addressed all his comments.
> Any comments would be welcome.
> 
> This depends on some patches that are in -mm, but not yet
> upstream.  In mmotm, these would probably go after
> pnp-dont-sort-by-type-in-sys-resources.patch

Perhaps it would've been different if I'd been a full-blown git wizzard 
but this is getting rather painful to test against mainline. Would it be 
possible for you to repost (privately or publicly) that which this 
depends on against current mainline?

I had to blow away my local trees here and while rebuilding the needed 
manual adjustments were just just enough to make me worry that I'd end 
up with something not entirely correct.

Rene.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [patch 00/18] PNP: convert resource options to unified dynamic list, v2
  2008-06-10  3:00 ` [patch 00/18] PNP: convert resource options to unified dynamic list, v2 Rene Herman
@ 2008-06-10 17:08   ` Bjorn Helgaas
  0 siblings, 0 replies; 31+ messages in thread
From: Bjorn Helgaas @ 2008-06-10 17:08 UTC (permalink / raw)
  To: Rene Herman
  Cc: Len Brown, linux-acpi, linux-kernel, Adam Belay, Adam M Belay,
	Li Shaohua, Matthieu Castet, Thomas Renninger, Jaroslav Kysela,
	Andrew Morton, Takashi Iwai

On Monday 09 June 2008 09:00:13 pm Rene Herman wrote:
> On 05-06-08 00:09, Bjorn Helgaas wrote:
> 
> > This patch series converts the PNP resource option structures
> > to a unified linked list.  This preserves resource order, which
> > is important for some devices.  The bulk of the series is in
> > the last patch, and it has more a more detailed changelog.
> > 
> > Rene Herman did some testing of ISA devices and reviewed
> > v1 of this series.  I think I addressed all his comments.
> > Any comments would be welcome.
> > 
> > This depends on some patches that are in -mm, but not yet
> > upstream.  In mmotm, these would probably go after
> > pnp-dont-sort-by-type-in-sys-resources.patch
> 
> Perhaps it would've been different if I'd been a full-blown git wizzard 
> but this is getting rather painful to test against mainline. Would it be 
> possible for you to repost (privately or publicly) that which this 
> depends on against current mainline?

Sure.  Here's my current quilt "patches" directory:

http://www.kernel.org/pub/linux/kernel/people/helgaas/2.6.26-rc5-pnp1.tar.bz2

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [patch 01/18] PNP: add pnp_possible_config() -- can a device could be configured this way?
  2008-06-04 22:09 ` [patch 01/18] PNP: add pnp_possible_config() -- can a device could be configured this way? Bjorn Helgaas
@ 2008-06-14  8:05   ` Rene Herman
  0 siblings, 0 replies; 31+ messages in thread
From: Rene Herman @ 2008-06-14  8:05 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Len Brown, linux-acpi, linux-kernel, Adam Belay, Adam M Belay,
	Li Shaohua, Matthieu Castet, Thomas Renninger, Jaroslav Kysela,
	Andrew Morton, Takashi Iwai

On 05-06-08 00:09, Bjorn Helgaas wrote:

> As part of a heuristic to identify modem devices, 8250_pnp.c
> checks to see whether a device can be configured at any of the
> legacy COM port addresses.
> 
> This patch moves the code that traverses the PNP "possible resource
> options" from 8250_pnp.c to the PNP subsystem.  This encapsulation
> is important because a future patch will change the implementation
> of those resource options.
> 
> Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>

Acked-by: Rene Herman <rene.herman@gmail.com>

Rene.


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [patch 03/18] PNP: IORESOURCE_* flags are PNP-specific, not ISA PNP-specific
  2008-06-04 22:09 ` [patch 03/18] PNP: IORESOURCE_* flags are PNP-specific, not ISA PNP-specific Bjorn Helgaas
@ 2008-06-14  8:06   ` Rene Herman
  0 siblings, 0 replies; 31+ messages in thread
From: Rene Herman @ 2008-06-14  8:06 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Len Brown, linux-acpi, linux-kernel, Adam Belay, Adam M Belay,
	Li Shaohua, Matthieu Castet, Thomas Renninger, Jaroslav Kysela,
	Andrew Morton, Takashi Iwai

On 05-06-08 00:09, Bjorn Helgaas wrote:

> Change comments on the bus-specific IORESOURCE bit definitions
> to indicate the PNP ones are not ISA-specific.  They are used
> by PNPBIOS and PNPACPI in addition to ISAPNP.
> 
> Rene Herman <rene.herman@gmail.com> wrote this patch:
>     http://marc.info/?l=linux-acpi&m=121200787202959&w=4.
> I picked it up to resolve conflicts with other patches.
> 
> Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>

Acked-by: Rene Herman <rene.herman@gmail.com>

Rene.


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [patch 05/18] PNP: make resource option structures private to PNP subsystem
  2008-06-04 22:09 ` [patch 05/18] PNP: make resource option structures private to PNP subsystem Bjorn Helgaas
@ 2008-06-14  8:07   ` Rene Herman
  0 siblings, 0 replies; 31+ messages in thread
From: Rene Herman @ 2008-06-14  8:07 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Len Brown, linux-acpi, linux-kernel, Adam Belay, Adam M Belay,
	Li Shaohua, Matthieu Castet, Thomas Renninger, Jaroslav Kysela,
	Andrew Morton, Takashi Iwai

On 05-06-08 00:09, Bjorn Helgaas wrote:

> Nothing outside the PNP subsystem should need access to a
> device's resource options, so this patch moves the option
> structure declarations to a private header file.
> 
> Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>

Acked-by: Rene Herman <rene.herman@gmail.com>

Rene.


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [patch 15/18] PNP: support optional IRQ resources
  2008-06-04 22:09 ` [patch 15/18] PNP: support optional IRQ resources Bjorn Helgaas
@ 2008-06-14  8:29   ` Rene Herman
  2008-06-16 15:41     ` Bjorn Helgaas
  0 siblings, 1 reply; 31+ messages in thread
From: Rene Herman @ 2008-06-14  8:29 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Len Brown, linux-acpi, linux-kernel, Adam Belay, Adam M Belay,
	Li Shaohua, Matthieu Castet, Thomas Renninger, Jaroslav Kysela,
	Andrew Morton, Takashi Iwai

On 05-06-08 00:09, Bjorn Helgaas wrote:

> This patch adds an IORESOURCE_IRQ_OPTIONAL flag for use when
> assigning resources to a device.  If the flag is set and we are
> unable to assign an IRQ to the device, we can leave the IRQ
> disabled but allow the overall resource allocation to succeed.
> 
> Some devices request an IRQ, but can run without an IRQ
> (possibly with degraded performance).  This flag lets us run
> the device without the IRQ instead of just leaving the
> device disabled.
> 
> This is a reimplementation of this previous change by Rene
> Herman <rene.herman@gmail.com>:
>     http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=3b73a223661ed137c5d3d2635f954382e94f5a43
> 
> I reimplemented this for two reasons:
>     - to prepare for converting all resource options into a single linked
>       list, as opposed to the per-resource-type lists we have now, and
>     - to preserve the order and number of resource options.
> 
> In PNPBIOS and ACPI, we configure a device by giving firmware a
> list of resource assignments.  It is important that this list
> has exactly the same number of resources, in the same order,
> as the "template" list we got from the firmware in the first
> place.
> 
> The problem of a sound card MPU401 being left disabled for want of
> an IRQ was reported by Uwe Bugla <uwe.bugla@gmx.de>.
> 
> Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>

You rework this again in the later patch doing the final switch over 
after which things end up right but also already at this point:

> @@ -176,33 +184,10 @@ static void quirk_ad1815_mpu_resources(s
>  	if (!irq || irq->next)
>  		return;
>  
> -	res = dev->dependent;
> -	if (!res)
> -		return;
> -
> -	while (1) {
> -		struct pnp_irq *copy;
> -
> -		copy = pnp_alloc(sizeof *copy);
> -		if (!copy)
> -			break;
> -
> -		bitmap_copy(copy->map.bits, irq->map.bits, PNP_IRQ_NR);
> -		copy->flags = irq->flags;
> -
> -		copy->next = res->irq; /* Yes, this is NULL */
> -		res->irq = copy;
> -
> -		if (!res->next)
> -			break;
> -		res = res->next;
> -	}
> -	kfree(irq);
> +	irq->flags |= IORESOURCE_IRQ_OPTIONAL;
> +	dev_info(&dev->dev, "made independent IRQ optional\n");
>  
>  	res->next = quirk_isapnp_mpu_options(dev);

... this line should just go.

Previously "res" ended up as the last dependent set through the while 
loop but now it's the independendent set which in this previous setup of 
things shouldn't even have a ->next. Just deleting this line makes this 
patch fine and

Acked-by: Rene Herman <rene.herman@gmail.com>

Rene.


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [patch 16/18] PNP: remove extra 0x100 bit from option priority
  2008-06-04 22:09 ` [patch 16/18] PNP: remove extra 0x100 bit from option priority Bjorn Helgaas
@ 2008-06-14  8:35   ` Rene Herman
  0 siblings, 0 replies; 31+ messages in thread
From: Rene Herman @ 2008-06-14  8:35 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Len Brown, linux-acpi, linux-kernel, Adam Belay, Adam M Belay,
	Li Shaohua, Matthieu Castet, Thomas Renninger, Jaroslav Kysela,
	Andrew Morton, Takashi Iwai

On 05-06-08 00:09, Bjorn Helgaas wrote:

> When building resource options, ISAPNP and PNPBIOS set the priority
> to something like "0x100 | PNP_RES_PRIORITY_ACCEPTABLE", but we 
> immediately mask off the 0x100 again in pnp_build_option(), so that
> bit looks superfluous.
> 
> Thanks to Rene Herman <rene.herman@gmail.com> for pointing this out.
> 
> Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>

Acked-by: Rene Herman <rene.herman@gmail.com>

Rene


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [patch 17/18] ISAPNP: handle independent options following dependent ones
  2008-06-04 22:09 ` [patch 17/18] ISAPNP: handle independent options following dependent ones Bjorn Helgaas
@ 2008-06-14  8:39   ` Rene Herman
  0 siblings, 0 replies; 31+ messages in thread
From: Rene Herman @ 2008-06-14  8:39 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Len Brown, linux-acpi, linux-kernel, Adam Belay, Adam M Belay,
	Li Shaohua, Matthieu Castet, Thomas Renninger, Jaroslav Kysela,
	Andrew Morton, Takashi Iwai

On 05-06-08 00:09, Bjorn Helgaas wrote:

> The ISAPNP spec recommends that independent options precede
> dependent ones, but this is not actually required.  The current
> ISAPNP code incorrectly puts such trailing independent options
> at the end of the last dependent option list.
> 
> This patch fixes that bug by resetting the current option list
> to the independent list when we see an "End Dependent Functions"
> tag.  PNPBIOS and PNPACPI handle this the same way.
> 
> Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>

Acked-by: Rene Herman <rene.herman@gmail.com>

Rene.


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [patch 18/18] PNP: convert resource options to single linked list
  2008-06-04 22:09 ` [patch 18/18] PNP: convert resource options to single linked list Bjorn Helgaas
@ 2008-06-14 10:31   ` Rene Herman
  2008-06-16 15:44     ` Bjorn Helgaas
  0 siblings, 1 reply; 31+ messages in thread
From: Rene Herman @ 2008-06-14 10:31 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Len Brown, linux-acpi, linux-kernel, Adam Belay, Adam M Belay,
	Li Shaohua, Matthieu Castet, Thomas Renninger, Jaroslav Kysela,
	Andrew Morton, Takashi Iwai

On 05-06-08 00:09, Bjorn Helgaas wrote:

> ISAPNP, PNPBIOS, and ACPI describe the "possible resource settings" of

[ ... ]

Acked-by: Rene Herman <rene.herman@gmail.com>

Only minor comment:

> +static inline unsigned int pnp_independent_option(void)
> +{
> +	return 0;
> +}

I think this is a somewhat unintuitive name (the function doesn't return 
an option) and now that the pnp_dependent_option() one has been renamed 
to pnp_new_dependent_set() even the symmetry doesn't survive.

pnp_independent_option_flags? pnp_independent_flags? Or better yet, just 
literal 0? That last one unless you have some as of yet unpublished plan 
for the abstraction ofcourse but this function seems to obscure more 
than it helps any at the moment.

Even if you agree, obviously also fine as follow-up patch.

Only trivial:

> +static int pnp_assign_resources(struct pnp_dev *dev, int set)
> {

[ ... ]

> -fail:
> -	pnp_clean_resource_table(dev);
>  	mutex_unlock(&pnp_res_mutex);
> -	dbg_pnp_show_resources(dev, "after pnp_assign_resources (failed)");
> -	return 0;
> +	if (ret) {
> +		dev_dbg(&dev->dev, "pnp_assign_resources failed (%d)\n", ret);
> +		pnp_clean_resource_table(dev);
> +	} else
> +		dbg_pnp_show_resources(dev, "pnp_assign_resources succeeded");
> +	return ret;
>  }

if (ret < 0) would agree with the rest.

>  int pnp_auto_config_dev(struct pnp_dev *dev)
>  {
> -	struct pnp_option *dep;
> -	int i = 1;
> +	int i, ret = 0;

int ret; will do;

Rene.


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [patch 15/18] PNP: support optional IRQ resources
  2008-06-14  8:29   ` Rene Herman
@ 2008-06-16 15:41     ` Bjorn Helgaas
  2008-06-16 16:26       ` Rene Herman
  0 siblings, 1 reply; 31+ messages in thread
From: Bjorn Helgaas @ 2008-06-16 15:41 UTC (permalink / raw)
  To: Rene Herman
  Cc: Len Brown, linux-acpi, linux-kernel, Adam Belay, Adam M Belay,
	Li Shaohua, Matthieu Castet, Thomas Renninger, Jaroslav Kysela,
	Andrew Morton, Takashi Iwai

On Saturday 14 June 2008 02:29:01 am Rene Herman wrote:
> On 05-06-08 00:09, Bjorn Helgaas wrote:
> 
> > This patch adds an IORESOURCE_IRQ_OPTIONAL flag for use when
> > assigning resources to a device.  If the flag is set and we are
> > unable to assign an IRQ to the device, we can leave the IRQ
> > disabled but allow the overall resource allocation to succeed.
> > 
> > Some devices request an IRQ, but can run without an IRQ
> > (possibly with degraded performance).  This flag lets us run
> > the device without the IRQ instead of just leaving the
> > device disabled.
> > 
> > This is a reimplementation of this previous change by Rene
> > Herman <rene.herman@gmail.com>:
> >     http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=3b73a223661ed137c5d3d2635f954382e94f5a43
> > 
> > I reimplemented this for two reasons:
> >     - to prepare for converting all resource options into a single linked
> >       list, as opposed to the per-resource-type lists we have now, and
> >     - to preserve the order and number of resource options.
> > 
> > In PNPBIOS and ACPI, we configure a device by giving firmware a
> > list of resource assignments.  It is important that this list
> > has exactly the same number of resources, in the same order,
> > as the "template" list we got from the firmware in the first
> > place.
> > 
> > The problem of a sound card MPU401 being left disabled for want of
> > an IRQ was reported by Uwe Bugla <uwe.bugla@gmx.de>.
> > 
> > Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
> 
> You rework this again in the later patch doing the final switch over 
> after which things end up right but also already at this point:
> 
> > @@ -176,33 +184,10 @@ static void quirk_ad1815_mpu_resources(s
> >  	if (!irq || irq->next)
> >  		return;
> >  
> > -	res = dev->dependent;
> > -	if (!res)
> > -		return;
> > -
> > -	while (1) {
> > -		struct pnp_irq *copy;
> > -
> > -		copy = pnp_alloc(sizeof *copy);
> > -		if (!copy)
> > -			break;
> > -
> > -		bitmap_copy(copy->map.bits, irq->map.bits, PNP_IRQ_NR);
> > -		copy->flags = irq->flags;
> > -
> > -		copy->next = res->irq; /* Yes, this is NULL */
> > -		res->irq = copy;
> > -
> > -		if (!res->next)
> > -			break;
> > -		res = res->next;
> > -	}
> > -	kfree(irq);
> > +	irq->flags |= IORESOURCE_IRQ_OPTIONAL;
> > +	dev_info(&dev->dev, "made independent IRQ optional\n");
> >  
> >  	res->next = quirk_isapnp_mpu_options(dev);
> 
> ... this line should just go.

You mean I should delete the "res->next = quirk_isapnp_mpu_options(dev)"
line?

> Previously "res" ended up as the last dependent set through the while 
> loop but now it's the independendent set which in this previous setup of 
> things shouldn't even have a ->next. Just deleting this line makes this 
> patch fine and
> 
> Acked-by: Rene Herman <rene.herman@gmail.com>

OK.  This will mean replacing patches 15 and 18 in this series.  If
I repost those two, is that easy for you to deal with, Andrew?

If I replace these, I'll also update patch 18 to fix the
pnp_independent_option() comment Rene made.

Bjorn

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [patch 18/18] PNP: convert resource options to single linked list
  2008-06-14 10:31   ` Rene Herman
@ 2008-06-16 15:44     ` Bjorn Helgaas
  0 siblings, 0 replies; 31+ messages in thread
From: Bjorn Helgaas @ 2008-06-16 15:44 UTC (permalink / raw)
  To: Rene Herman
  Cc: Len Brown, linux-acpi, linux-kernel, Adam Belay, Adam M Belay,
	Li Shaohua, Matthieu Castet, Thomas Renninger, Jaroslav Kysela,
	Andrew Morton, Takashi Iwai

On Saturday 14 June 2008 04:31:54 am Rene Herman wrote:
> On 05-06-08 00:09, Bjorn Helgaas wrote:
> 
> > ISAPNP, PNPBIOS, and ACPI describe the "possible resource settings" of
> 
> [ ... ]
> 
> Acked-by: Rene Herman <rene.herman@gmail.com>
> 
> Only minor comment:
> 
> > +static inline unsigned int pnp_independent_option(void)
> > +{
> > +	return 0;
> > +}
> 
> I think this is a somewhat unintuitive name (the function doesn't return 
> an option) and now that the pnp_dependent_option() one has been renamed 
> to pnp_new_dependent_set() even the symmetry doesn't survive.
> 
> pnp_independent_option_flags? pnp_independent_flags? Or better yet, just 
> literal 0? That last one unless you have some as of yet unpublished plan 
> for the abstraction ofcourse but this function seems to obscure more 
> than it helps any at the moment.

Yep, you're absolutely right.  I changed the dependent name at the
last minute and should have done something with independent at the
same time.  I like the literal 0 idea.

> Only trivial:
> 
> > +static int pnp_assign_resources(struct pnp_dev *dev, int set)
> > {
> 
> [ ... ]
> 
> > -fail:
> > -	pnp_clean_resource_table(dev);
> >  	mutex_unlock(&pnp_res_mutex);
> > -	dbg_pnp_show_resources(dev, "after pnp_assign_resources (failed)");
> > -	return 0;
> > +	if (ret) {
> > +		dev_dbg(&dev->dev, "pnp_assign_resources failed (%d)\n", ret);
> > +		pnp_clean_resource_table(dev);
> > +	} else
> > +		dbg_pnp_show_resources(dev, "pnp_assign_resources succeeded");
> > +	return ret;
> >  }
> 
> if (ret < 0) would agree with the rest.
> 
> >  int pnp_auto_config_dev(struct pnp_dev *dev)
> >  {
> > -	struct pnp_option *dep;
> > -	int i = 1;
> > +	int i, ret = 0;
> 
> int ret; will do;

Thanks, I'll fold those in, too.

Bjorn

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [patch 15/18] PNP: support optional IRQ resources
  2008-06-16 15:41     ` Bjorn Helgaas
@ 2008-06-16 16:26       ` Rene Herman
  0 siblings, 0 replies; 31+ messages in thread
From: Rene Herman @ 2008-06-16 16:26 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Len Brown, linux-acpi, linux-kernel, Adam Belay, Adam M Belay,
	Li Shaohua, Matthieu Castet, Thomas Renninger, Jaroslav Kysela,
	Andrew Morton, Takashi Iwai

On 16-06-08 17:41, Bjorn Helgaas wrote:

>>> @@ -176,33 +184,10 @@ static void quirk_ad1815_mpu_resources(s
>>>  	if (!irq || irq->next)
>>>  		return;
>>>  
>>> -	res = dev->dependent;
>>> -	if (!res)
>>> -		return;
>>> -
>>> -	while (1) {
>>> -		struct pnp_irq *copy;
>>> -
>>> -		copy = pnp_alloc(sizeof *copy);
>>> -		if (!copy)
>>> -			break;
>>> -
>>> -		bitmap_copy(copy->map.bits, irq->map.bits, PNP_IRQ_NR);
>>> -		copy->flags = irq->flags;
>>> -
>>> -		copy->next = res->irq; /* Yes, this is NULL */
>>> -		res->irq = copy;
>>> -
>>> -		if (!res->next)
>>> -			break;
>>> -		res = res->next;
>>> -	}
>>> -	kfree(irq);
>>> +	irq->flags |= IORESOURCE_IRQ_OPTIONAL;
>>> +	dev_info(&dev->dev, "made independent IRQ optional\n");
>>>  
>>>  	res->next = quirk_isapnp_mpu_options(dev);
>> 
>> ... this line should just go.
> 
> You mean I should delete the "res->next = quirk_isapnp_mpu_options(dev)"
> line?

Yes. With the optional flag, ad1815 doesn't need the cloning and due to 
the below it's actively wrong at this point in the series.

>> Previously "res" ended up as the last dependent set through the while 
>> loop but now it's the independendent set which in this previous setup of 
>> things shouldn't even have a ->next. Just deleting this line makes this 
>> patch fine and
>>
>> Acked-by: Rene Herman <rene.herman@gmail.com>
> 
> OK.  This will mean replacing patches 15 and 18 in this series.  If
> I repost those two, is that easy for you to deal with, Andrew?
> 
> If I replace these, I'll also update patch 18 to fix the
> pnp_independent_option() comment Rene made.

Rene.

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2008-06-16 16:26 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-06-04 22:09 [patch 00/18] PNP: convert resource options to unified dynamic list, v2 Bjorn Helgaas
2008-06-04 22:09 ` [patch 01/18] PNP: add pnp_possible_config() -- can a device could be configured this way? Bjorn Helgaas
2008-06-14  8:05   ` Rene Herman
2008-06-04 22:09 ` [patch 02/18] PNP: whitespace/coding style fixes Bjorn Helgaas
2008-06-04 22:09 ` [patch 03/18] PNP: IORESOURCE_* flags are PNP-specific, not ISA PNP-specific Bjorn Helgaas
2008-06-14  8:06   ` Rene Herman
2008-06-04 22:09 ` [patch 04/18] PNP: define PNP-specific IORESOURCE_IO_* flags alongside IRQ, DMA, MEM Bjorn Helgaas
2008-06-04 22:09 ` [patch 05/18] PNP: make resource option structures private to PNP subsystem Bjorn Helgaas
2008-06-14  8:07   ` Rene Herman
2008-06-04 22:09 ` [patch 06/18] PNP: introduce pnp_irq_mask_t typedef Bjorn Helgaas
2008-06-04 22:09 ` [patch 07/18] PNP: increase I/O port & memory option address sizes Bjorn Helgaas
2008-06-04 22:09 ` [patch 08/18] PNP: improve resource assignment debug Bjorn Helgaas
2008-06-04 22:09 ` [patch 09/18] PNP: in debug resource dump, make empty list obvious Bjorn Helgaas
2008-06-04 22:09 ` [patch 10/18] PNP: make resource assignment functions return 0 (success) or -EBUSY (failure) Bjorn Helgaas
2008-06-04 22:09 ` [patch 11/18] PNP: remove redundant pnp_can_configure() check Bjorn Helgaas
2008-06-04 22:09 ` [patch 12/18] PNP: centralize resource option allocations Bjorn Helgaas
2008-06-04 22:09 ` [patch 13/18] PNPACPI: ignore _PRS interrupt numbers larger than PNP_IRQ_NR Bjorn Helgaas
2008-06-04 22:09 ` [patch 14/18] PNP: rename pnp_register_*_resource() local variables Bjorn Helgaas
2008-06-04 22:09 ` [patch 15/18] PNP: support optional IRQ resources Bjorn Helgaas
2008-06-14  8:29   ` Rene Herman
2008-06-16 15:41     ` Bjorn Helgaas
2008-06-16 16:26       ` Rene Herman
2008-06-04 22:09 ` [patch 16/18] PNP: remove extra 0x100 bit from option priority Bjorn Helgaas
2008-06-14  8:35   ` Rene Herman
2008-06-04 22:09 ` [patch 17/18] ISAPNP: handle independent options following dependent ones Bjorn Helgaas
2008-06-14  8:39   ` Rene Herman
2008-06-04 22:09 ` [patch 18/18] PNP: convert resource options to single linked list Bjorn Helgaas
2008-06-14 10:31   ` Rene Herman
2008-06-16 15:44     ` Bjorn Helgaas
2008-06-10  3:00 ` [patch 00/18] PNP: convert resource options to unified dynamic list, v2 Rene Herman
2008-06-10 17:08   ` Bjorn Helgaas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox