* [patch 00/15] PNP: convert resource options to unified dynamic list, v1
@ 2008-05-30 22:48 Bjorn Helgaas
2008-05-30 22:48 ` [patch 01/15] serial: when guessing, check only active resources, not options Bjorn Helgaas
` (15 more replies)
0 siblings, 16 replies; 46+ messages in thread
From: Bjorn Helgaas @ 2008-05-30 22:48 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. There's more detail in the
comments for the last patch.
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
Bjorn
--
^ permalink raw reply [flat|nested] 46+ messages in thread
* [patch 01/15] serial: when guessing, check only active resources, not options
2008-05-30 22:48 [patch 00/15] PNP: convert resource options to unified dynamic list, v1 Bjorn Helgaas
@ 2008-05-30 22:48 ` Bjorn Helgaas
2008-06-01 19:42 ` Rene Herman
2008-05-30 22:48 ` [patch 02/15] PNP: whitespace/coding style fixes Bjorn Helgaas
` (14 subsequent siblings)
15 siblings, 1 reply; 46+ messages in thread
From: Bjorn Helgaas @ 2008-05-30 22:48 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: serial-pnp-check-current-resources-not-options --]
[-- Type: text/plain, Size: 2046 bytes --]
Given a completely unknown PNP device, if it happens to have
a modem-like string in its name and it matches a COM port
address, we assume it's a modem.
We used to check the address against all the possible resource
options for the device. But the device is already configured
and enabled, so we only need to check the resources it is
actually using. If we matched an address that wasn't currently
enabled, we would fail anyway as soon as we attempted to touch
the device at that address.
This removes a reference to the struct pnp_dev.{independent,dependent}
fields, which I will soon make private to the PNP subsystem.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Index: work10/drivers/serial/8250_pnp.c
===================================================================
--- work10.orig/drivers/serial/8250_pnp.c 2008-05-13 11:28:48.000000000 -0600
+++ work10/drivers/serial/8250_pnp.c 2008-05-13 11:29:16.000000000 -0600
@@ -383,22 +383,19 @@ 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)
+ resource_size_t port, size;
+
+ if (!pnp_port_valid(dev, 0))
return 0;
- 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;
- }
+ port = pnp_port_start(dev, 0);
+ size = pnp_port_len(dev, 0);
+
+ if (size == 8 &&
+ (port == 0x2f8 || port == 0x3f8 || port == 0x2e8 || port == 0x3e8))
+ return 1;
return 0;
}
@@ -420,10 +417,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;
--
^ permalink raw reply [flat|nested] 46+ messages in thread
* [patch 02/15] PNP: whitespace/coding style fixes
2008-05-30 22:48 [patch 00/15] PNP: convert resource options to unified dynamic list, v1 Bjorn Helgaas
2008-05-30 22:48 ` [patch 01/15] serial: when guessing, check only active resources, not options Bjorn Helgaas
@ 2008-05-30 22:48 ` Bjorn Helgaas
2008-06-01 19:52 ` Rene Herman
2008-05-30 22:48 ` [patch 03/15] PNP: define PNP-specific IORESOURCE_IO_* flags alongside IRQ, DMA, MEM Bjorn Helgaas
` (13 subsequent siblings)
15 siblings, 1 reply; 46+ messages in thread
From: Bjorn Helgaas @ 2008-05-30 22:48 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-interface-style --]
[-- Type: text/plain, Size: 1851 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>
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] 46+ messages in thread
* [patch 03/15] PNP: define PNP-specific IORESOURCE_IO_* flags alongside IRQ, DMA, MEM
2008-05-30 22:48 [patch 00/15] PNP: convert resource options to unified dynamic list, v1 Bjorn Helgaas
2008-05-30 22:48 ` [patch 01/15] serial: when guessing, check only active resources, not options Bjorn Helgaas
2008-05-30 22:48 ` [patch 02/15] PNP: whitespace/coding style fixes Bjorn Helgaas
@ 2008-05-30 22:48 ` Bjorn Helgaas
2008-06-01 21:03 ` Rene Herman
2008-05-30 22:48 ` [patch 04/15] PNP: make resource option structures private to PNP subsystem Bjorn Helgaas
` (12 subsequent siblings)
15 siblings, 1 reply; 46+ messages in thread
From: Bjorn Helgaas @ 2008-05-30 22:48 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-io-option-flags --]
[-- Type: text/plain, Size: 6486 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>
---
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-05-27 15:36:38.000000000 -0600
+++ work10/include/linux/ioport.h 2008-05-30 13:20:16.000000000 -0600
@@ -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) */
+/* ISA 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 */
@@ -88,6 +88,10 @@ struct resource_list {
#define IORESOURCE_MEM_SHADOWABLE (1<<5) /* dup: IORESOURCE_SHADOWABLE */
#define IORESOURCE_MEM_EXPANSIONROM (1<<6)
+/* ISA 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-05-27 15:36:38.000000000 -0600
+++ work10/include/linux/pnp.h 2008-05-30 13:20:16.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-05-27 16:09:33.000000000 -0600
+++ work10/drivers/pnp/interface.c 2008-05-30 13:20:16.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-05-27 15:36:38.000000000 -0600
+++ work10/drivers/pnp/isapnp/core.c 2008-05-30 13:20:16.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-05-27 16:09:30.000000000 -0600
+++ work10/drivers/pnp/pnpacpi/rsparser.c 2008-05-30 13:20:16.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-05-27 15:36:38.000000000 -0600
+++ work10/drivers/pnp/pnpbios/rsparser.c 2008-05-30 13:20:16.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] 46+ messages in thread
* [patch 04/15] PNP: make resource option structures private to PNP subsystem
2008-05-30 22:48 [patch 00/15] PNP: convert resource options to unified dynamic list, v1 Bjorn Helgaas
` (2 preceding siblings ...)
2008-05-30 22:48 ` [patch 03/15] PNP: define PNP-specific IORESOURCE_IO_* flags alongside IRQ, DMA, MEM Bjorn Helgaas
@ 2008-05-30 22:48 ` Bjorn Helgaas
2008-06-01 21:06 ` Rene Herman
2008-05-30 22:48 ` [patch 05/15] PNP: introduce pnp_irq_mask_t typedef Bjorn Helgaas
` (11 subsequent siblings)
15 siblings, 1 reply; 46+ messages in thread
From: Bjorn Helgaas @ 2008-05-30 22:48 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] 46+ messages in thread
* [patch 05/15] PNP: introduce pnp_irq_mask_t typedef
2008-05-30 22:48 [patch 00/15] PNP: convert resource options to unified dynamic list, v1 Bjorn Helgaas
` (3 preceding siblings ...)
2008-05-30 22:48 ` [patch 04/15] PNP: make resource option structures private to PNP subsystem Bjorn Helgaas
@ 2008-05-30 22:48 ` Bjorn Helgaas
2008-06-01 21:25 ` Rene Herman
2008-05-30 22:48 ` [patch 06/15] PNP: increase I/O port & memory option address sizes Bjorn Helgaas
` (10 subsequent siblings)
15 siblings, 1 reply; 46+ messages in thread
From: Bjorn Helgaas @ 2008-05-30 22:48 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-irq-bitmap-decl --]
[-- Type: text/plain, Size: 6198 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>
Index: work10/drivers/pnp/base.h
===================================================================
--- work10.orig/drivers/pnp/base.h 2008-05-30 13:20:29.000000000 -0600
+++ work10/drivers/pnp/base.h 2008-05-30 13:20:36.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-05-27 15:36:38.000000000 -0600
+++ work10/drivers/pnp/resource.c 2008-05-30 13:20:36.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
Index: work10/drivers/pnp/manager.c
===================================================================
--- work10.orig/drivers/pnp/manager.c 2008-05-27 15:36:38.000000000 -0600
+++ work10/drivers/pnp/manager.c 2008-05-30 13:20:36.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-05-30 13:20:16.000000000 -0600
+++ work10/drivers/pnp/interface.c 2008-05-30 13:20:36.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-05-30 13:20:16.000000000 -0600
+++ work10/drivers/pnp/isapnp/core.c 2008-05-30 13:20:36.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-05-30 13:20:16.000000000 -0600
+++ work10/drivers/pnp/pnpacpi/rsparser.c 2008-05-30 13:20:36.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-05-27 15:36:38.000000000 -0600
+++ work10/drivers/pnp/quirks.c 2008-05-30 13:20:36.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-05-30 13:20:16.000000000 -0600
+++ work10/drivers/pnp/pnpbios/rsparser.c 2008-05-30 13:20:36.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] 46+ messages in thread
* [patch 06/15] PNP: increase I/O port & memory option address sizes
2008-05-30 22:48 [patch 00/15] PNP: convert resource options to unified dynamic list, v1 Bjorn Helgaas
` (4 preceding siblings ...)
2008-05-30 22:48 ` [patch 05/15] PNP: introduce pnp_irq_mask_t typedef Bjorn Helgaas
@ 2008-05-30 22:48 ` Bjorn Helgaas
2008-06-01 21:39 ` Rene Herman
2008-05-30 22:49 ` [patch 07/15] PNP: improve resource assignment debug Bjorn Helgaas
` (9 subsequent siblings)
15 siblings, 1 reply; 46+ messages in thread
From: Bjorn Helgaas @ 2008-05-30 22:48 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-resource-size --]
[-- Type: text/plain, Size: 4571 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>
---
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] 46+ messages in thread
* [patch 07/15] PNP: improve resource assignment debug
2008-05-30 22:48 [patch 00/15] PNP: convert resource options to unified dynamic list, v1 Bjorn Helgaas
` (5 preceding siblings ...)
2008-05-30 22:48 ` [patch 06/15] PNP: increase I/O port & memory option address sizes Bjorn Helgaas
@ 2008-05-30 22:49 ` Bjorn Helgaas
2008-06-01 21:41 ` Rene Herman
2008-05-30 22:49 ` [patch 08/15] PNP: in debug resource dump, make empty list obvious Bjorn Helgaas
` (8 subsequent siblings)
15 siblings, 1 reply; 46+ messages in thread
From: Bjorn Helgaas @ 2008-05-30 22:49 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-improve-assign-debug --]
[-- Type: text/plain, Size: 1280 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>
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] 46+ messages in thread
* [patch 08/15] PNP: in debug resource dump, make empty list obvious
2008-05-30 22:48 [patch 00/15] PNP: convert resource options to unified dynamic list, v1 Bjorn Helgaas
` (6 preceding siblings ...)
2008-05-30 22:49 ` [patch 07/15] PNP: improve resource assignment debug Bjorn Helgaas
@ 2008-05-30 22:49 ` Bjorn Helgaas
2008-06-01 21:44 ` Rene Herman
2008-05-30 22:49 ` [patch 09/15] PNP: make resource assignment functions return 0 (success) or -EBUSY (failure) Bjorn Helgaas
` (7 subsequent siblings)
15 siblings, 1 reply; 46+ messages in thread
From: Bjorn Helgaas @ 2008-05-30 22:49 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-improve-debug-resource-dump --]
[-- Type: text/plain, Size: 978 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>
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] 46+ messages in thread
* [patch 09/15] PNP: make resource assignment functions return 0 (success) or -EBUSY (failure)
2008-05-30 22:48 [patch 00/15] PNP: convert resource options to unified dynamic list, v1 Bjorn Helgaas
` (7 preceding siblings ...)
2008-05-30 22:49 ` [patch 08/15] PNP: in debug resource dump, make empty list obvious Bjorn Helgaas
@ 2008-05-30 22:49 ` Bjorn Helgaas
2008-06-01 21:59 ` Rene Herman
2008-05-30 22:49 ` [patch 10/15] PNP: remove redundant pnp_can_configure() check Bjorn Helgaas
` (6 subsequent siblings)
15 siblings, 1 reply; 46+ messages in thread
From: Bjorn Helgaas @ 2008-05-30 22:49 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-change-assignment-return-values --]
[-- Type: text/plain, Size: 4568 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>
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] 46+ messages in thread
* [patch 10/15] PNP: remove redundant pnp_can_configure() check
2008-05-30 22:48 [patch 00/15] PNP: convert resource options to unified dynamic list, v1 Bjorn Helgaas
` (8 preceding siblings ...)
2008-05-30 22:49 ` [patch 09/15] PNP: make resource assignment functions return 0 (success) or -EBUSY (failure) Bjorn Helgaas
@ 2008-05-30 22:49 ` Bjorn Helgaas
2008-06-01 22:00 ` Rene Herman
2008-05-30 22:49 ` [patch 11/15] PNP: centralize resource option allocations Bjorn Helgaas
` (5 subsequent siblings)
15 siblings, 1 reply; 46+ messages in thread
From: Bjorn Helgaas @ 2008-05-30 22:49 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-assign-configurability-check --]
[-- Type: text/plain, Size: 742 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>
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] 46+ messages in thread
* [patch 11/15] PNP: centralize resource option allocations
2008-05-30 22:48 [patch 00/15] PNP: convert resource options to unified dynamic list, v1 Bjorn Helgaas
` (9 preceding siblings ...)
2008-05-30 22:49 ` [patch 10/15] PNP: remove redundant pnp_can_configure() check Bjorn Helgaas
@ 2008-05-30 22:49 ` Bjorn Helgaas
2008-06-01 23:21 ` Rene Herman
2008-05-30 22:49 ` [patch 12/15] PNPACPI: ignore _PRS interrupt numbers larger than PNP_IRQ_NR Bjorn Helgaas
` (4 subsequent siblings)
15 siblings, 1 reply; 46+ messages in thread
From: Bjorn Helgaas @ 2008-05-30 22:49 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-centralize-option-allocs --]
[-- Type: text/plain, Size: 23128 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>
---
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 13:22:01.000000000 -0600
+++ work10/drivers/pnp/base.h 2008-05-30 13:23:34.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 13:20:36.000000000 -0600
+++ work10/drivers/pnp/isapnp/core.c 2008-05-30 13:23:34.000000000 -0600
@@ -433,20 +433,23 @@ static void __init isapnp_parse_irq_reso
int size)
{
unsigned char tmp[3];
- struct pnp_irq *irq;
unsigned long bits;
+ int i;
+ 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);
+ for (i = 0; i < 15; i++)
+ if (bits & (1 << i))
+ __set_bit(i, map.bits);
+
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 +460,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 +473,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 +493,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 +510,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 +530,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 +550,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 13:20:36.000000000 -0600
+++ work10/drivers/pnp/pnpacpi/rsparser.c 2008-05-30 13:23:34.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 13:20:36.000000000 -0600
+++ work10/drivers/pnp/pnpbios/rsparser.c 2008-05-30 13:23:34.000000000 -0600
@@ -218,116 +218,98 @@ 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;
+ int i;
+ 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);
+ for (i = 0; i < 16; i++)
+ if (bits & (1 << i))
+ __set_bit(i, map.bits);
+
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, 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 13:22:01.000000000 -0600
+++ work10/drivers/pnp/resource.c 2008-05-30 13:23:34.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] 46+ messages in thread
* [patch 12/15] PNPACPI: ignore _PRS interrupt numbers larger than PNP_IRQ_NR
2008-05-30 22:48 [patch 00/15] PNP: convert resource options to unified dynamic list, v1 Bjorn Helgaas
` (10 preceding siblings ...)
2008-05-30 22:49 ` [patch 11/15] PNP: centralize resource option allocations Bjorn Helgaas
@ 2008-05-30 22:49 ` Bjorn Helgaas
2008-06-01 23:23 ` Rene Herman
2008-05-30 22:49 ` [patch 13/15] PNP: rename pnp_register_*_resource() local variables Bjorn Helgaas
` (3 subsequent siblings)
15 siblings, 1 reply; 46+ messages in thread
From: Bjorn Helgaas @ 2008-05-30 22:49 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: pnpacpi-extended-irq-option --]
[-- Type: text/plain, Size: 1510 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>
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] 46+ messages in thread
* [patch 13/15] PNP: rename pnp_register_*_resource() local variables
2008-05-30 22:48 [patch 00/15] PNP: convert resource options to unified dynamic list, v1 Bjorn Helgaas
` (11 preceding siblings ...)
2008-05-30 22:49 ` [patch 12/15] PNPACPI: ignore _PRS interrupt numbers larger than PNP_IRQ_NR Bjorn Helgaas
@ 2008-05-30 22:49 ` Bjorn Helgaas
2008-06-01 23:25 ` Rene Herman
2008-05-30 22:49 ` [patch 14/15] PNP: support optional IRQ resources Bjorn Helgaas
` (2 subsequent siblings)
15 siblings, 1 reply; 46+ messages in thread
From: Bjorn Helgaas @ 2008-05-30 22:49 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-register-renames --]
[-- Type: text/plain, Size: 4786 bytes --]
No functional change; just rename "data" to something more
descriptive.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.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] 46+ messages in thread
* [patch 14/15] PNP: support optional IRQ resources
2008-05-30 22:48 [patch 00/15] PNP: convert resource options to unified dynamic list, v1 Bjorn Helgaas
` (12 preceding siblings ...)
2008-05-30 22:49 ` [patch 13/15] PNP: rename pnp_register_*_resource() local variables Bjorn Helgaas
@ 2008-05-30 22:49 ` Bjorn Helgaas
2008-06-03 17:37 ` Rene Herman
2008-05-30 22:49 ` [patch 15/15] PNP: convert resource options to single linked list Bjorn Helgaas
2008-06-01 19:28 ` [patch 00/15] PNP: convert resource options to unified dynamic list, v1 Rene Herman
15 siblings, 1 reply; 46+ messages in thread
From: Bjorn Helgaas @ 2008-05-30 22:49 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: 5279 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 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-05-20 13:34:58.000000000 -0600
+++ work10/include/linux/ioport.h 2008-05-20 13:39:21.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)
/* ISA 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-05-20 13:39:21.000000000 -0600
+++ work10/drivers/pnp/manager.c 2008-05-20 13:39: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-05-20 13:39:36.000000000 -0600
+++ work10/drivers/pnp/quirks.c 2008-05-20 14:01:42.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)
--
^ permalink raw reply [flat|nested] 46+ messages in thread
* [patch 15/15] PNP: convert resource options to single linked list
2008-05-30 22:48 [patch 00/15] PNP: convert resource options to unified dynamic list, v1 Bjorn Helgaas
` (13 preceding siblings ...)
2008-05-30 22:49 ` [patch 14/15] PNP: support optional IRQ resources Bjorn Helgaas
@ 2008-05-30 22:49 ` Bjorn Helgaas
2008-06-03 19:57 ` Rene Herman
2008-06-03 21:13 ` Rene Herman
2008-06-01 19:28 ` [patch 00/15] PNP: convert resource options to unified dynamic list, v1 Rene Herman
15 siblings, 2 replies; 46+ messages in thread
From: Bjorn Helgaas @ 2008-05-30 22:49 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: 60852 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 use some entries from set 0 and some
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 ...
This reordering results in problems like the one I tried
unsuccessfully to fix here:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=41a5311465b9de6d18e78b733a2c6e1b33e89be8
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-05-30 14:44:14.000000000 -0600
+++ work10/drivers/pnp/base.h 2008-05-30 15:58:15.000000000 -0600
@@ -1,3 +1,8 @@
+/*
+ * (c) Copyright 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,8 +51,6 @@ 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_RES_PRIORITY_PREFERRED 0
@@ -60,35 +58,82 @@ struct pnp_mem {
#define PNP_RES_PRIORITY_FUNCTIONAL 2
#define PNP_RES_PRIORITY_INVALID 65535
+#define PNP_OPTION_DEPENDENT 0x80000000
+#define PNP_OPTION_SET_MASK 0xff
+#define PNP_OPTION_SET_SHIFT 16
+#define PNP_OPTION_PRIORITY_MASK 0xffff
+#define PNP_OPTION_PRIORITY_SHIFT 0
+
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_dependent_option(struct pnp_dev *dev,
+ int priority)
+{
+ unsigned int flags;
+
+ 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-05-30 14:44:14.000000000 -0600
+++ work10/drivers/pnp/core.c 2008-05-30 15:58:15.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-05-30 14:44:14.000000000 -0600
+++ work10/drivers/pnp/interface.c 2008-05-30 15:58:15.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>
+ * (c) Copyright 2008 Hewlett-Packard Development Company, L.P.
+ * Bjorn Helgaas <bjorn.helgaas@hp.com>
*/
#include <linux/pnp.h>
@@ -182,39 +184,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,
@@ -222,9 +207,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)
@@ -233,14 +218,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-05-30 14:44:14.000000000 -0600
+++ work10/drivers/pnp/isapnp/core.c 2008-05-30 15:58:15.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];
@@ -449,27 +449,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];
@@ -482,14 +482,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];
@@ -498,7 +499,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);
}
@@ -506,7 +507,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];
@@ -519,14 +520,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];
@@ -539,14 +541,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];
@@ -557,7 +560,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);
}
/*
@@ -587,18 +590,14 @@ static int __init isapnp_create_device(s
{
int number = 0, skip = 0, priority = 0, compat = 0;
unsigned char type, tmp[17];
- struct pnp_option *option;
+ 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 = pnp_register_independent_option(dev);
- if (!option) {
- kfree(dev);
- return 1;
- }
+ option_flags = pnp_independent_option();
pnp_add_card_device(card, dev);
while (1) {
@@ -615,11 +614,7 @@ static int __init isapnp_create_device(s
return 1;
size = 0;
skip = 0;
- option = pnp_register_independent_option(dev);
- if (!option) {
- kfree(dev);
- return 1;
- }
+ option_flags = pnp_independent_option();
pnp_add_card_device(card, dev);
} else {
skip = 1;
@@ -641,13 +636,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:
@@ -659,26 +654,24 @@ static int __init isapnp_create_device(s
priority = 0x100 | tmp[0];
size = 0;
}
- option = pnp_register_dependent_option(dev, priority);
- if (!option)
- return 1;
+ option_flags = pnp_dependent_option(dev, priority);
break;
case _STAG_ENDDEP:
if (size != 0)
goto __skip;
- priority = 0;
- 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 +679,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 +694,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-05-30 15:58:14.000000000 -0600
+++ work10/drivers/pnp/manager.c 2008-05-30 15:58:15.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>
+ * (c) Copyright 2008 Hewlett-Packard Development Company, L.P.
+ * Bjorn Helgaas <bjorn.helgaas@hp.com>
*/
#include <linux/errno.h>
@@ -228,102 +230,50 @@ 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;
+ 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;
}
- while (dma) {
- if (pnp_assign_dma(dev, dma, ndma) < 0)
- goto fail;
- ndma++;
- dma = dma->next;
- }
- } else if (dev->dependent)
- goto fail;
+ if (ret < 0)
+ break;
+ }
mutex_unlock(&pnp_res_mutex);
- dbg_pnp_show_resources(dev, "after pnp_assign_resources");
- return 1;
-
-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 == 0)
+ dbg_pnp_show_resources(dev, "pnp_assign_resources succeeded");
+ else
+ dev_dbg(&dev->dev, "pnp_assign_resources failed (%d)\n", ret);
+ return ret;
}
/**
@@ -332,29 +282,21 @@ 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))
+ for (i = 0; i == 0 || 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-05-30 14:45:52.000000000 -0600
+++ work10/drivers/pnp/pnpacpi/rsparser.c 2008-05-30 15:58:15.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 = 0;
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_dependent_option(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-05-30 14:44:14.000000000 -0600
+++ work10/drivers/pnp/pnpbios/rsparser.c 2008-05-30 15:58:15.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;
int i;
@@ -276,19 +278,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, flags;
@@ -297,18 +299,19 @@ 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);
}
@@ -318,17 +321,14 @@ pnpbios_parse_resource_option_data(unsig
{
unsigned int len, tag;
int priority = 0;
- 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 */
@@ -345,37 +345,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:
@@ -385,7 +386,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:
@@ -394,19 +396,13 @@ pnpbios_parse_resource_option_data(unsig
priority = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE;
if (len > 0)
priority = 0x100 | p[1];
- option = pnp_register_dependent_option(dev, priority);
- if (!option)
- return NULL;
+ option_flags = pnp_dependent_option(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-05-30 15:58:14.000000000 -0600
+++ work10/drivers/pnp/quirks.c 2008-05-30 15:58:15.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>
+ * (c) Copyright 2008 Hewlett-Packard Development Company, L.P.
+ * Bjorn Helgaas <bjorn.helgaas@hp.com>
*
* Heavily based on PCI quirks handling which is
*
@@ -20,188 +22,208 @@
#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)
+ IORESOURCE_DMA_8BIT &&
+ dma->map != 0x000A) {
+ dev_info(&dev->dev, "changing possible "
+ "DMA channel mask in option set %d "
+ "from %#x to 0xA (1, 3)\n",
+ pnp_option_set(option), dma->map);
dma->map = 0x000A;
+ }
+ }
}
- 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.
* 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_dependent_option(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, *irq_option = 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 = option;
+ }
+ }
- res = dev->dependent;
- if (!res)
+ if (independent_irqs != 1)
return;
- while (res->next)
- res = res->next;
+ irq_option->flags |= IORESOURCE_IRQ_OPTIONAL;
+ dev_info(&dev->dev, "made independent IRQ optional\n");
- res->next = quirk_isapnp_mpu_options(dev);
+ quirk_add_irq_optional_dependent_sets(dev);
}
#include <linux/pci.h>
@@ -296,10 +318,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-05-30 15:58:13.000000000 -0600
+++ work10/drivers/pnp/resource.c 2008-05-30 15:58:15.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>
+ * (c) Copyright 2008 Hewlett-Packard Development Company, L.P.
+ * Bjorn Helgaas <bjorn.helgaas@hp.com>
*/
#include <linux/module.h>
@@ -28,78 +30,37 @@ 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 +71,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)
-{
- struct pnp_irq *next;
-
- while (irq) {
- next = irq->next;
- kfree(irq);
- irq = next;
- }
-}
-
-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)
+void pnp_free_options(struct pnp_dev *dev)
{
- struct pnp_option *next;
+ struct pnp_option *option, *tmp;
- 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;
}
}
Index: work10/drivers/pnp/support.c
===================================================================
--- work10.orig/drivers/pnp/support.c 2008-05-30 14:44:14.000000000 -0600
+++ work10/drivers/pnp/support.c 2008-05-30 15:58:15.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>
+ * (c) Copyright 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-05-30 14:44:14.000000000 -0600
+++ work10/include/linux/pnp.h 2008-05-30 15:58:15.000000000 -0600
@@ -1,6 +1,8 @@
/*
* Linux Plug and Play Support
* Copyright by Adam Belay <ambx1@neo.rr.com>
+ * (c) Copyright 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] 46+ messages in thread
* Re: [patch 00/15] PNP: convert resource options to unified dynamic list, v1
2008-05-30 22:48 [patch 00/15] PNP: convert resource options to unified dynamic list, v1 Bjorn Helgaas
` (14 preceding siblings ...)
2008-05-30 22:49 ` [patch 15/15] PNP: convert resource options to single linked list Bjorn Helgaas
@ 2008-06-01 19:28 ` Rene Herman
2008-06-02 15:56 ` Bjorn Helgaas
15 siblings, 1 reply; 46+ messages in thread
From: Rene Herman @ 2008-06-01 19:28 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
[-- Attachment #1: Type: text/plain, Size: 1076 bytes --]
On 31-05-08 00:48, 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. There's more detail in the
> comments for the last patch.
>
> 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
Will look at this in more detail but as first testing feedback -- I need
this on top.
Both ISAPnP and PnPBIOS for some or other reason set the priority to
0x100 | prio after which that 0x100 is immediately masked of again in
pnp_build_option() leaving just the prio. Your new scheme reserves 16
bits for the priority though meaning the 0x100 survives causing it to be
considered "invalid" by at least pnp_option_priority_name() for example.
There cannot be any currently valid reason for the 0x100 it seems given
that it's immediately masked of again in pnp_build_option() so let's
just get rid of it...
[-- Attachment #2: pnp_priority.diff --]
[-- Type: text/plain, Size: 1155 bytes --]
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index d4c6b19..7556887 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -648,10 +648,10 @@ static int __init isapnp_create_device(struct pnp_card *card,
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_flags = pnp_dependent_option(dev, priority);
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
index e0bea09..a6c9539 100644
--- a/drivers/pnp/pnpbios/rsparser.c
+++ b/drivers/pnp/pnpbios/rsparser.c
@@ -393,9 +393,9 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
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_flags = pnp_dependent_option(dev, priority);
break;
^ permalink raw reply related [flat|nested] 46+ messages in thread
* Re: [patch 01/15] serial: when guessing, check only active resources, not options
2008-05-30 22:48 ` [patch 01/15] serial: when guessing, check only active resources, not options Bjorn Helgaas
@ 2008-06-01 19:42 ` Rene Herman
2008-06-02 15:21 ` Bjorn Helgaas
0 siblings, 1 reply; 46+ messages in thread
From: Rene Herman @ 2008-06-01 19:42 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 31-05-08 00:48, Bjorn Helgaas wrote:
> Given a completely unknown PNP device, if it happens to have
> a modem-like string in its name and it matches a COM port
> address, we assume it's a modem.
>
> We used to check the address against all the possible resource
> options for the device. But the device is already configured
> and enabled, so we only need to check the resources it is
> actually using. If we matched an address that wasn't currently
> enabled, we would fail anyway as soon as we attempted to touch
> the device at that address.
>
> This removes a reference to the struct pnp_dev.{independent,dependent}
> fields, which I will soon make private to the PNP subsystem.
>
> Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
This isn't quite right it seems. Or changes behaviour at least:
> Index: work10/drivers/serial/8250_pnp.c
> ===================================================================
> --- work10.orig/drivers/serial/8250_pnp.c 2008-05-13 11:28:48.000000000 -0600
> +++ work10/drivers/serial/8250_pnp.c 2008-05-13 11:29:16.000000000 -0600
> @@ -383,22 +383,19 @@ 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)
> + resource_size_t port, size;
> +
> + if (!pnp_port_valid(dev, 0))
> return 0;
>
> - 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;
> - }
> + port = pnp_port_start(dev, 0);
> + size = pnp_port_len(dev, 0);
> +
> + if (size == 8 &&
> + (port == 0x2f8 || port == 0x3f8 || port == 0x2e8 || port == 0x3e8))
> + return 1;
>
> return 0;
> }
> @@ -420,10 +417,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;
We used to cry "modem" if the device _could_ be configured using a COM
address while after this change we'd only do so if it _was_ configured
using one.
My old analog modem for example had 5 dependent sets -- the first with
the regular COM port addresses (0x3f8, 0x2f8, 0x3e8, 0x2e8) and a 5th
one listing a port range of (IIRC, something like that at least) 0x100
to 0xff8.
So say I'd have a PC with the regular two onboard COM ports at COM1 and
COM2 (0x3f8 and 0x2f8) and an additional serial controller providing
COM3 and COM4 (0x3e8 and 0x2e8). My modem would then be configured to
use 0x100 and this code would no longer trigger while it did use to.
Not that I care deeply or anything but whomever wrote this did no doubt
intend it to work this way...
Rene.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 02/15] PNP: whitespace/coding style fixes
2008-05-30 22:48 ` [patch 02/15] PNP: whitespace/coding style fixes Bjorn Helgaas
@ 2008-06-01 19:52 ` Rene Herman
0 siblings, 0 replies; 46+ messages in thread
From: Rene Herman @ 2008-06-01 19:52 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 31-05-08 00:48, Bjorn Helgaas wrote:
> 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>
By the way, noticed recently that Acked-by might not be the right tag
given that I'm not in any formal acking path or anything; feel free to
translate them into any tag of your liking. They're meant as "looked at
this and agree".
Rene.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 03/15] PNP: define PNP-specific IORESOURCE_IO_* flags alongside IRQ, DMA, MEM
2008-05-30 22:48 ` [patch 03/15] PNP: define PNP-specific IORESOURCE_IO_* flags alongside IRQ, DMA, MEM Bjorn Helgaas
@ 2008-06-01 21:03 ` Rene Herman
0 siblings, 0 replies; 46+ messages in thread
From: Rene Herman @ 2008-06-01 21:03 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 31-05-08 00:48, Bjorn Helgaas wrote:
> 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>
Wondered a bit since only PnPACPI seems to directly encode those flags
to a res->flags (as opposed to a port->flags) but pnp_assign_port()
copies them over verbatim indeed...
Rene.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 04/15] PNP: make resource option structures private to PNP subsystem
2008-05-30 22:48 ` [patch 04/15] PNP: make resource option structures private to PNP subsystem Bjorn Helgaas
@ 2008-06-01 21:06 ` Rene Herman
0 siblings, 0 replies; 46+ messages in thread
From: Rene Herman @ 2008-06-01 21: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 31-05-08 00:48, 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>
I guess this is dependent on the 8250_pnp note I sent earlier.
Rene.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 05/15] PNP: introduce pnp_irq_mask_t typedef
2008-05-30 22:48 ` [patch 05/15] PNP: introduce pnp_irq_mask_t typedef Bjorn Helgaas
@ 2008-06-01 21:25 ` Rene Herman
0 siblings, 0 replies; 46+ messages in thread
From: Rene Herman @ 2008-06-01 21:25 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 31-05-08 00:48, Bjorn Helgaas wrote:
> 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>
Rene.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 06/15] PNP: increase I/O port & memory option address sizes
2008-05-30 22:48 ` [patch 06/15] PNP: increase I/O port & memory option address sizes Bjorn Helgaas
@ 2008-06-01 21:39 ` Rene Herman
0 siblings, 0 replies; 46+ messages in thread
From: Rene Herman @ 2008-06-01 21: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 31-05-08 00:48, Bjorn Helgaas wrote:
> 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>
Rene.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 07/15] PNP: improve resource assignment debug
2008-05-30 22:49 ` [patch 07/15] PNP: improve resource assignment debug Bjorn Helgaas
@ 2008-06-01 21:41 ` Rene Herman
0 siblings, 0 replies; 46+ messages in thread
From: Rene Herman @ 2008-06-01 21:41 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 31-05-08 00:49, Bjorn Helgaas wrote:
> 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>
Rene.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 08/15] PNP: in debug resource dump, make empty list obvious
2008-05-30 22:49 ` [patch 08/15] PNP: in debug resource dump, make empty list obvious Bjorn Helgaas
@ 2008-06-01 21:44 ` Rene Herman
0 siblings, 0 replies; 46+ messages in thread
From: Rene Herman @ 2008-06-01 21:44 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 31-05-08 00:49, Bjorn Helgaas wrote:
> 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>
Rene.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 09/15] PNP: make resource assignment functions return 0 (success) or -EBUSY (failure)
2008-05-30 22:49 ` [patch 09/15] PNP: make resource assignment functions return 0 (success) or -EBUSY (failure) Bjorn Helgaas
@ 2008-06-01 21:59 ` Rene Herman
0 siblings, 0 replies; 46+ messages in thread
From: Rene Herman @ 2008-06-01 21:59 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 31-05-08 00:49, Bjorn Helgaas wrote:
> 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>
I believe it would a bit nicer to (as long as we're pretending it
matters in the first place) pass the return value back up from
pnp_check_foo() instead of returning -EBUSY always but <shrug>
Rene.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 10/15] PNP: remove redundant pnp_can_configure() check
2008-05-30 22:49 ` [patch 10/15] PNP: remove redundant pnp_can_configure() check Bjorn Helgaas
@ 2008-06-01 22:00 ` Rene Herman
0 siblings, 0 replies; 46+ messages in thread
From: Rene Herman @ 2008-06-01 22: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 31-05-08 00:49, Bjorn Helgaas wrote:
> 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>
Rene.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 11/15] PNP: centralize resource option allocations
2008-05-30 22:49 ` [patch 11/15] PNP: centralize resource option allocations Bjorn Helgaas
@ 2008-06-01 23:21 ` Rene Herman
2008-06-02 15:29 ` Bjorn Helgaas
0 siblings, 1 reply; 46+ messages in thread
From: Rene Herman @ 2008-06-01 23:21 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 31-05-08 00:49, Bjorn Helgaas wrote:
> 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>
[ ... ]
> Index: work10/drivers/pnp/isapnp/core.c
> ===================================================================
> --- work10.orig/drivers/pnp/isapnp/core.c 2008-05-30 13:20:36.000000000 -0600
> +++ work10/drivers/pnp/isapnp/core.c 2008-05-30 13:23:34.000000000 -0600
> @@ -433,20 +433,23 @@ static void __init isapnp_parse_irq_reso
> int size)
> {
> unsigned char tmp[3];
> - struct pnp_irq *irq;
> unsigned long bits;
> + int i;
> + 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);
> + for (i = 0; i < 15; i++)
> + if (bits & (1 << i))
> + __set_bit(i, map.bits);
> +
for (i = 0; i < 16; i++) (16 instead of 15) it would seem.
And why not simply:
bitmap_zero(map.bits, PNP_IRQ_NR);
bitmap_copy(map.bits, &bits, 16);
That last bit of the comment same for pnpbios_parse_irq_option(). Should
be fine, no?
> 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, flags;
unsigned char flags;
All the rest:
Acked-by: Rene Herman <rene.herman@gmail.com>
Rene.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 12/15] PNPACPI: ignore _PRS interrupt numbers larger than PNP_IRQ_NR
2008-05-30 22:49 ` [patch 12/15] PNPACPI: ignore _PRS interrupt numbers larger than PNP_IRQ_NR Bjorn Helgaas
@ 2008-06-01 23:23 ` Rene Herman
0 siblings, 0 replies; 46+ messages in thread
From: Rene Herman @ 2008-06-01 23:23 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 31-05-08 00:49, Bjorn Helgaas wrote:
> 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>
Rene.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 13/15] PNP: rename pnp_register_*_resource() local variables
2008-05-30 22:49 ` [patch 13/15] PNP: rename pnp_register_*_resource() local variables Bjorn Helgaas
@ 2008-06-01 23:25 ` Rene Herman
0 siblings, 0 replies; 46+ messages in thread
From: Rene Herman @ 2008-06-01 23:25 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 31-05-08 00:49, Bjorn Helgaas wrote:
> 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>
(last 2 after sleep)
Rene.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 01/15] serial: when guessing, check only active resources, not options
2008-06-01 19:42 ` Rene Herman
@ 2008-06-02 15:21 ` Bjorn Helgaas
0 siblings, 0 replies; 46+ messages in thread
From: Bjorn Helgaas @ 2008-06-02 15:21 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 Sunday 01 June 2008 01:42:01 pm Rene Herman wrote:
> We used to cry "modem" if the device _could_ be configured using a COM
> address while after this change we'd only do so if it _was_ configured
> using one.
>
> My old analog modem for example had 5 dependent sets -- the first with
> the regular COM port addresses (0x3f8, 0x2f8, 0x3e8, 0x2e8) and a 5th
> one listing a port range of (IIRC, something like that at least) 0x100
> to 0xff8.
>
> So say I'd have a PC with the regular two onboard COM ports at COM1 and
> COM2 (0x3f8 and 0x2f8) and an additional serial controller providing
> COM3 and COM4 (0x3e8 and 0x2e8). My modem would then be configured to
> use 0x100 and this code would no longer trigger while it did use to.
Ah, you're right. That scenario hadn't occurred to me. Let me see
if I can figure out a way to make that work again.
Bjorn
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 11/15] PNP: centralize resource option allocations
2008-06-01 23:21 ` Rene Herman
@ 2008-06-02 15:29 ` Bjorn Helgaas
0 siblings, 0 replies; 46+ messages in thread
From: Bjorn Helgaas @ 2008-06-02 15:29 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 Sunday 01 June 2008 05:21:10 pm Rene Herman wrote:
> On 31-05-08 00:49, Bjorn Helgaas wrote:
>
> > 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>
>
> [ ... ]
>
> > Index: work10/drivers/pnp/isapnp/core.c
> > ===================================================================
> > --- work10.orig/drivers/pnp/isapnp/core.c 2008-05-30 13:20:36.000000000 -0600
> > +++ work10/drivers/pnp/isapnp/core.c 2008-05-30 13:23:34.000000000 -0600
> > @@ -433,20 +433,23 @@ static void __init isapnp_parse_irq_reso
> > int size)
> > {
> > unsigned char tmp[3];
> > - struct pnp_irq *irq;
> > unsigned long bits;
> > + int i;
> > + 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);
> > + for (i = 0; i < 15; i++)
> > + if (bits & (1 << i))
> > + __set_bit(i, map.bits);
> > +
>
> for (i = 0; i < 16; i++) (16 instead of 15) it would seem.
Oops, typo on my part.
> And why not simply:
>
> bitmap_zero(map.bits, PNP_IRQ_NR);
> bitmap_copy(map.bits, &bits, 16);
>
> That last bit of the comment same for pnpbios_parse_irq_option(). Should
> be fine, no?
I suppose it should be fine. It's just that I was new to the bitmap
functions and nervous about copying between bitmaps of different sizes
and getting bits in the correct places. But I'll try to get over my
paranoia :-)
Bjorn
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 00/15] PNP: convert resource options to unified dynamic list, v1
2008-06-01 19:28 ` [patch 00/15] PNP: convert resource options to unified dynamic list, v1 Rene Herman
@ 2008-06-02 15:56 ` Bjorn Helgaas
0 siblings, 0 replies; 46+ messages in thread
From: Bjorn Helgaas @ 2008-06-02 15:56 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 Sunday 01 June 2008 01:28:23 pm Rene Herman wrote:
> On 31-05-08 00:48, 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. There's more detail in the
> > comments for the last patch.
> >
> > 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
>
> Will look at this in more detail but as first testing feedback -- I need
> this on top.
>
> Both ISAPnP and PnPBIOS for some or other reason set the priority to
> 0x100 | prio after which that 0x100 is immediately masked of again in
> pnp_build_option() leaving just the prio. Your new scheme reserves 16
> bits for the priority though meaning the 0x100 survives causing it to be
> considered "invalid" by at least pnp_option_priority_name() for example.
>
> There cannot be any currently valid reason for the 0x100 it seems given
> that it's immediately masked of again in pnp_build_option() so let's
> just get rid of it...
I agree, that bit looks superfluous. I added a patch to remove it.
Thanks,
Bjorn
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 14/15] PNP: support optional IRQ resources
2008-05-30 22:49 ` [patch 14/15] PNP: support optional IRQ resources Bjorn Helgaas
@ 2008-06-03 17:37 ` Rene Herman
2008-06-03 20:20 ` Bjorn Helgaas
0 siblings, 1 reply; 46+ messages in thread
From: Rene Herman @ 2008-06-03 17:37 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 31-05-08 00:49, 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 being left disabled for want of an
> IRQ was reported by Uwe Bugla <uwe.bugla@gmx.de>.
Nit -- the soundcard itself isn't left disabled, just its MPU401. It's
only the fact that ALSA mentions this fact which triggered the report.
> Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
>
> Index: work10/include/linux/ioport.h
> ===================================================================
> --- work10.orig/include/linux/ioport.h 2008-05-20 13:34:58.000000000 -0600
> +++ work10/include/linux/ioport.h 2008-05-20 13:39:21.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)
>
> /* ISA PnP DMA specific bits (IORESOURCE_BITS) */
> #define IORESOURCE_DMA_TYPE_MASK (3<<0)
Andrew scooped up a patch from a previous reaction of mine that deleted
the "ISA " from these comments. I tend to use comments as a great way of
avoiding actually reading code (I'm silly like that) and so as to be
burned a _bit_ less by it, I think it's good if they're accurate. In
this case for example, one might be tempted to assume these bits were
specific to drivers/pnp/isapnp.
<snip>
> @@ -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);
As commented yesterday, this line should just go. We don't need to clone
here (we do for the other two PNP IDs, so the cloning can't go entirely).
The actual (slight) problem with it not working is in 15/15...
> -
> - res = dev->independent;
> - res->irq = NULL;
> }
>
> static void quirk_isapnp_mpu_resources(struct pnp_dev *dev)
Rene.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 15/15] PNP: convert resource options to single linked list
2008-05-30 22:49 ` [patch 15/15] PNP: convert resource options to single linked list Bjorn Helgaas
@ 2008-06-03 19:57 ` Rene Herman
2008-06-03 23:03 ` Bjorn Helgaas
2008-06-03 23:52 ` Rene Herman
2008-06-03 21:13 ` Rene Herman
1 sibling, 2 replies; 46+ messages in thread
From: Rene Herman @ 2008-06-03 19:57 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 31-05-08 00:49, Bjorn Helgaas wrote:
> 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 ...
Just for the record -- due to an ISAPnP bug, ISAPnP doesn't actually at
the moment deal with independents following dependents at all (it does
not reset the option to independent upon seeing an _STAG_ENDDEP tag) and
the rework actually fixes this bug. The ISAPnP spec does recommend that
independents precede dependents, but does not guarantee.
Might be good to mention this in the log though? In the unlikely event
that some piece of ISAPnP hardware out there actually changes behaviour
(to "fixed" ...) that might be a hint in looking at it.
<snip>
> +#define PNP_OPTION_DEPENDENT 0x80000000
> +#define PNP_OPTION_SET_MASK 0xff
> +#define PNP_OPTION_SET_SHIFT 16
> +#define PNP_OPTION_PRIORITY_MASK 0xffff
> +#define PNP_OPTION_PRIORITY_SHIFT 0
I checked, and ISAPnP and PnPBIOS definitely limit the priority to 8-bit
and ACPI seems to as well meaning the (only) reason for using 16 would
be the RES_PRIORITY_INVALID value.
I have on the other hand not encountered text limiting the number of
dependents sets to 255 nor do I believe the old code enforced this?
Yes, I suppose this is exceedingly unlikely to be a practical issue.
<snip>
> static void pnp_print_option(pnp_info_buffer_t * buffer, char *space,
> - struct pnp_option *option, int dep)
> + struct pnp_option *option)
> + 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;
I believe it would be good if pnp_print_irq() now also displayed
"(optional)" if the flag is set.
> @@ -659,26 +654,24 @@ static int __init isapnp_create_device(s
> priority = 0x100 | tmp[0];
> size = 0;
> }
> - option = pnp_register_dependent_option(dev, priority);
> - if (!option)
> - return 1;
> + option_flags = pnp_dependent_option(dev, priority);
> break;
> case _STAG_ENDDEP:
> if (size != 0)
> goto __skip;
> - priority = 0;
> - dev_dbg(&dev->dev, "end dependent options\n");
> + option_flags = pnp_independent_option();
(here is the bugfix)
> -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;
> + 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;
> }
> - while (dma) {
> - if (pnp_assign_dma(dev, dma, ndma) < 0)
> - goto fail;
> - ndma++;
> - dma = dma->next;
> - }
> - } else if (dev->dependent)
> - goto fail;
> + if (ret < 0)
> + break;
> + }
Mmm. Previously when it failed halfway through it re-cleared the
resources (at label fail). Does it want to do so now also?
> mutex_unlock(&pnp_res_mutex);
> - dbg_pnp_show_resources(dev, "after pnp_assign_resources");
> - return 1;
> -
> -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 == 0)
> + dbg_pnp_show_resources(dev, "pnp_assign_resources succeeded");
> + else
> + dev_dbg(&dev->dev, "pnp_assign_resources failed (%d)\n", ret);
> + return ret;
> }
>
> /**
> @@ -332,29 +282,21 @@ 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))
> + for (i = 0; i == 0 || i < dev->num_dependent_sets; i++) {
> + ret = pnp_assign_resources(dev, i);
> + if (ret == 0)
> return 0;
Eeeew. Perhaps:
i = 0;
do {
ret = pnp_assign_resources(dev, i);
if (ret == 0)
return 0;
} while (++i < dev->num_dependent_sets);
<snip>
> Index: work10/drivers/pnp/quirks.c
> ===================================================================
> --- work10.orig/drivers/pnp/quirks.c 2008-05-30 15:58:14.000000000 -0600
> +++ work10/drivers/pnp/quirks.c 2008-05-30 15:58:15.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>
> + * (c) Copyright 2008 Hewlett-Packard Development Company, L.P.
> + * Bjorn Helgaas <bjorn.helgaas@hp.com>
> *
> * Heavily based on PCI quirks handling which is
> *
> @@ -20,188 +22,208 @@
> #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;
Why do you do 0x800, 0x400 in that order? Shouldn't it just be 0x400,
0x800 to mimick the old order?
> - 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)
> + IORESOURCE_DMA_8BIT &&
> + dma->map != 0x000A) {
It's a char, so 0x0A? 0x000A makes it looks like it's 16-bit.
> + dev_info(&dev->dev, "changing possible "
> + "DMA channel mask in option set %d "
> + "from %#x to 0xA (1, 3)\n",
> + pnp_option_set(option), dma->map);
> dma->map = 0x000A;
And here...
> + }
> + }
> }
> - 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.
> * Here we increase that range so that two such cards can be
> * auto-configured.
> */
While you're there -- s/mpu/OPL/.
> +static void quirk_ad1815_mpu_resources(struct pnp_dev *dev)
> {
> - struct pnp_option *res;
> + struct pnp_option *option, *irq_option = 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 = option;
> + }
> + }
>
> - res = dev->dependent;
> - if (!res)
> + if (independent_irqs != 1)
> return;
>
> - while (res->next)
> - res = res->next;
> + irq_option->flags |= IORESOURCE_IRQ_OPTIONAL;
You're in maze of unsigned variables, all named flags...
irq_option->u.irq.flags |= IORESOURCE_IRQ_OPTIONAL;
This was the thing that made things not work when I tested -- on an
AD1815...
> + dev_info(&dev->dev, "made independent IRQ optional\n");
>
> - res->next = quirk_isapnp_mpu_options(dev);
> + quirk_add_irq_optional_dependent_sets(dev);
And as before, this one be gone.
The other quirks look good -- but I have the hardware and will test them
specifically.
> Index: work10/drivers/pnp/resource.c
> ===================================================================
> --- work10.orig/drivers/pnp/resource.c 2008-05-30 15:58:13.000000000 -0600
> +++ work10/drivers/pnp/resource.c 2008-05-30 15:58:15.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>
> + * (c) Copyright 2008 Hewlett-Packard Development Company, L.P.
> + * Bjorn Helgaas <bjorn.helgaas@hp.com>
> */
>
> #include <linux/module.h>
> @@ -28,78 +30,37 @@ 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;
Dropping this made the 0x100 | prio ISAPnP/PnPBIOS bug appear. That
0x100 should go anyway but perhaps this limiting is still a good idea?
> + option->flags = option_flags;
> + option->type = type;
>
> + list_add_tail(&option->list, &dev->options);
> return option;
> }
Rene.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 14/15] PNP: support optional IRQ resources
2008-06-03 17:37 ` Rene Herman
@ 2008-06-03 20:20 ` Bjorn Helgaas
2008-06-03 20:25 ` Rene Herman
0 siblings, 1 reply; 46+ messages in thread
From: Bjorn Helgaas @ 2008-06-03 20:20 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 Tuesday 03 June 2008 11:37:05 am Rene Herman wrote:
> > Index: work10/include/linux/ioport.h
> > ===================================================================
> > --- work10.orig/include/linux/ioport.h 2008-05-20 13:34:58.000000000 -0600
> > +++ work10/include/linux/ioport.h 2008-05-20 13:39:21.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)
> >
> > /* ISA PnP DMA specific bits (IORESOURCE_BITS) */
> > #define IORESOURCE_DMA_TYPE_MASK (3<<0)
>
> Andrew scooped up a patch from a previous reaction of mine that deleted
> the "ISA " from these comments. I tend to use comments as a great way of
> avoiding actually reading code (I'm silly like that) and so as to be
> burned a _bit_ less by it, I think it's good if they're accurate. In
> this case for example, one might be tempted to assume these bits were
> specific to drivers/pnp/isapnp.
Yes, I see that's pnpacpi-fix-irq-flag-decoding-comment-fix.patch
in mmotm. How about if I incorporate that in my series (the one
Andrew hasn't yet picked up), since your patch will otherwise
conflict with it?
Bjorn
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 14/15] PNP: support optional IRQ resources
2008-06-03 20:20 ` Bjorn Helgaas
@ 2008-06-03 20:25 ` Rene Herman
0 siblings, 0 replies; 46+ messages in thread
From: Rene Herman @ 2008-06-03 20:25 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 03-06-08 22:20, Bjorn Helgaas wrote:
> On Tuesday 03 June 2008 11:37:05 am Rene Herman wrote:
>>> Index: work10/include/linux/ioport.h
>>> ===================================================================
>>> --- work10.orig/include/linux/ioport.h 2008-05-20 13:34:58.000000000 -0600
>>> +++ work10/include/linux/ioport.h 2008-05-20 13:39:21.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)
>>>
>>> /* ISA PnP DMA specific bits (IORESOURCE_BITS) */
>>> #define IORESOURCE_DMA_TYPE_MASK (3<<0)
>> Andrew scooped up a patch from a previous reaction of mine that deleted
>> the "ISA " from these comments. I tend to use comments as a great way of
>> avoiding actually reading code (I'm silly like that) and so as to be
>> burned a _bit_ less by it, I think it's good if they're accurate. In
>> this case for example, one might be tempted to assume these bits were
>> specific to drivers/pnp/isapnp.
>
> Yes, I see that's pnpacpi-fix-irq-flag-decoding-comment-fix.patch
> in mmotm. How about if I incorporate that in my series (the one
> Andrew hasn't yet picked up), since your patch will otherwise
> conflict with it?
Yep, that would be good.
Rene.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 15/15] PNP: convert resource options to single linked list
2008-05-30 22:49 ` [patch 15/15] PNP: convert resource options to single linked list Bjorn Helgaas
2008-06-03 19:57 ` Rene Herman
@ 2008-06-03 21:13 ` Rene Herman
2008-06-04 21:26 ` Bjorn Helgaas
1 sibling, 1 reply; 46+ messages in thread
From: Rene Herman @ 2008-06-03 21:13 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 31-05-08 00:49, Bjorn Helgaas wrote:
Forgot this comment:
> --- work10.orig/drivers/pnp/quirks.c 2008-05-30 15:58:14.000000000 -0600
> +++ work10/drivers/pnp/quirks.c 2008-05-30 15:58:15.000000000 -0600
> +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_dependent_option(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;
> }
This works, but I did the "disconnected chain build" that I did due to
finding it particularly clumsy to add to the dependent chain while
walking it.
This avoids actual problems due to num_sets = dev->num_dependents_sets
in caller and the pnp_option_set(option) == set in the loop (not unlike
the first version of the original checked for a present irq) but it's
again checking the options it just added itself.
If you feel that's perfectly fine then <shrug> but thought I'd still
remark on it in case it wasn't intentional.
Rene.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 15/15] PNP: convert resource options to single linked list
2008-06-03 19:57 ` Rene Herman
@ 2008-06-03 23:03 ` Bjorn Helgaas
2008-06-04 0:03 ` Rene Herman
2008-06-03 23:52 ` Rene Herman
1 sibling, 1 reply; 46+ messages in thread
From: Bjorn Helgaas @ 2008-06-03 23:03 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 Tuesday 03 June 2008 01:57:11 pm Rene Herman wrote:
> On 31-05-08 00:49, Bjorn Helgaas wrote:
> Just for the record -- due to an ISAPnP bug, ISAPnP doesn't actually at
> the moment deal with independents following dependents at all (it does
> not reset the option to independent upon seeing an _STAG_ENDDEP tag) and
> the rework actually fixes this bug. The ISAPnP spec does recommend that
> independents precede dependents, but does not guarantee.
>
> Might be good to mention this in the log though? In the unlikely event
> that some piece of ISAPnP hardware out there actually changes behaviour
> (to "fixed" ...) that might be a hint in looking at it.
I split that bugfix into a separate patch; thanks for
pointing this out.
> > +#define PNP_OPTION_DEPENDENT 0x80000000
> > +#define PNP_OPTION_SET_MASK 0xff
> > +#define PNP_OPTION_SET_SHIFT 16
> > +#define PNP_OPTION_PRIORITY_MASK 0xffff
> > +#define PNP_OPTION_PRIORITY_SHIFT 0
>
> I checked, and ISAPnP and PnPBIOS definitely limit the priority to 8-bit
> and ACPI seems to as well meaning the (only) reason for using 16 would
> be the RES_PRIORITY_INVALID value.
>
> I have on the other hand not encountered text limiting the number of
> dependents sets to 255 nor do I believe the old code enforced this?
>
> Yes, I suppose this is exceedingly unlikely to be a practical issue.
That's definitely backwards. I reversed the sizes, so we'll have
8 bits for the priority byte (including compatibility/performance/
robustness) and 16 bits for the dependent set number. Actually,
I made the priority field 12 bits so we'd have space to keep
PNP_RES_PRIORITY_INVALID as a truly out-of-band value.
> > static void pnp_print_option(pnp_info_buffer_t * buffer, char *space,
> > - struct pnp_option *option, int dep)
> > + struct pnp_option *option)
>
> > + 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;
>
> I believe it would be good if pnp_print_irq() now also displayed
> "(optional)" if the flag is set.
I agree; I added this to the patch that added IORESOURCE_IRQ_OPTIONAL.
> > @@ -659,26 +654,24 @@ static int __init isapnp_create_device(s
> > priority = 0x100 | tmp[0];
> > size = 0;
> > }
> > - option = pnp_register_dependent_option(dev, priority);
> > - if (!option)
> > - return 1;
> > + option_flags = pnp_dependent_option(dev, priority);
> > break;
> > case _STAG_ENDDEP:
> > if (size != 0)
> > goto __skip;
> > - priority = 0;
> > - dev_dbg(&dev->dev, "end dependent options\n");
> > + option_flags = pnp_independent_option();
>
> (here is the bugfix)
Yep, I split into a separate patch as mentioned above.
> > -static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
> > +static int pnp_assign_resources(struct pnp_dev *dev, int set)
> > {
> > ...
> Mmm. Previously when it failed halfway through it re-cleared the
> resources (at label fail). Does it want to do so now also?
Yes, I suppose so. I can't remember why I removed that, but it
shouldn't hurt, so I added it back.
> > mutex_unlock(&pnp_res_mutex);
> > - dbg_pnp_show_resources(dev, "after pnp_assign_resources");
> > - return 1;
> > -
> > -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 == 0)
> > + dbg_pnp_show_resources(dev, "pnp_assign_resources succeeded");
> > + else
> > + dev_dbg(&dev->dev, "pnp_assign_resources failed (%d)\n", ret);
> > + return ret;
> > }
> >
> > /**
> > @@ -332,29 +282,21 @@ 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))
> > + for (i = 0; i == 0 || i < dev->num_dependent_sets; i++) {
> > + ret = pnp_assign_resources(dev, i);
> > + if (ret == 0)
> > return 0;
>
> Eeeew. Perhaps:
>
> i = 0;
> do {
> ret = pnp_assign_resources(dev, i);
> if (ret == 0)
> return 0;
> } while (++i < dev->num_dependent_sets);
Heh :-) I vacillated on that one because I have a personal aversion
to "do { ... } while ()", especially with a pre-increment. How would
you feel about this alternative?
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;
}
> > - port2->min += 0x400;
> > - port2->max += 0x400;
> > - port3->min += 0x800;
> > - port3->max += 0x800;
>
> Why do you do 0x800, 0x400 in that order? Shouldn't it just be 0x400,
> 0x800 to mimick the old order?
I think they do end up in the correct order because I'm passing the
same list_head to both list_add() calls, e.g., we'll have something
like this:
io -> ...
io -> (io + 0x800) -> ...
io -> (io + 0x400) -> (io + 0x800) -> ...
> > + } else if (option->type == IORESOURCE_DMA) {
> > + dma = &option->u.dma;
> > if ((dma->flags & IORESOURCE_DMA_TYPE_MASK) ==
> > - IORESOURCE_DMA_8BIT)
> > + IORESOURCE_DMA_8BIT &&
> > + dma->map != 0x000A) {
>
> It's a char, so 0x0A? 0x000A makes it looks like it's 16-bit.
>
> > + dev_info(&dev->dev, "changing possible "
> > + "DMA channel mask in option set %d "
> > + "from %#x to 0xA (1, 3)\n",
> > + pnp_option_set(option), dma->map);
> > dma->map = 0x000A;
>
> And here...
Makes sense; I changed this as well as the dev_info() formats.
> > /*
> > * The default range on the mpu port for these devices is 0x388-0x388.
> > * Here we increase that range so that two such cards can be
> > * auto-configured.
> > */
>
> While you're there -- s/mpu/OPL/.
Done.
> > +static void quirk_ad1815_mpu_resources(struct pnp_dev *dev)
> > {
> > - struct pnp_option *res;
> > + struct pnp_option *option, *irq_option = 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 = option;
> > + }
> > + }
> >
> > - res = dev->dependent;
> > - if (!res)
> > + if (independent_irqs != 1)
> > return;
> >
> > - while (res->next)
> > - res = res->next;
> > + irq_option->flags |= IORESOURCE_IRQ_OPTIONAL;
>
> You're in maze of unsigned variables, all named flags...
>
> irq_option->u.irq.flags |= IORESOURCE_IRQ_OPTIONAL;
>
> This was the thing that made things not work when I tested -- on an
> AD1815...
Ah, of course, thanks. I changed "irq_option" to a "struct pnp_irq *irq"
like I should have done to begin with.
> > + dev_info(&dev->dev, "made independent IRQ optional\n");
> >
> > - res->next = quirk_isapnp_mpu_options(dev);
> > + quirk_add_irq_optional_dependent_sets(dev);
>
> And as before, this one be gone.
OK, great. I wasn't sure I had understood those quirks correctly,
so thanks for pointing this out.
> > -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;
>
> Dropping this made the 0x100 | prio ISAPnP/PnPBIOS bug appear. That
> 0x100 should go anyway but perhaps this limiting is still a good idea?
Yes; I added the check back to pnp_dependent_option().
PNP_RES_PRIORITY_INVALID was previously 65536, which requires a 16-bit
field. I changed it to 0xfff to fit in the 12-bit field I mentioned
earlier.
I need to go back over all your comments and make sure I've addressed
them all, then I'll post the revised patches, hopefully tomorrow.
Thanks again for all your work reviewing and testing these. It's
been incredibly useful.
Bjorn
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 15/15] PNP: convert resource options to single linked list
2008-06-03 19:57 ` Rene Herman
2008-06-03 23:03 ` Bjorn Helgaas
@ 2008-06-03 23:52 ` Rene Herman
2008-06-04 11:48 ` Rene Herman
1 sibling, 1 reply; 46+ messages in thread
From: Rene Herman @ 2008-06-03 23:52 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 03-06-08 21:57, Rene Herman wrote:
> The other quirks look good -- but I have the hardware and will test them
> specifically.
The other quirks are good (In the sense that they work as before. The
comments below doubting them have nothing to do with Bjorn reworking
them). The options display is with the 0x100 | prio thing fixed locally
already.
== 1 == quirk_awe32_resources, CTL0022:
* pre-quirk:
Dependent: 00 - Priority preferred
port 0x620-0x620, align 0x0, size 0x4, 16-bit address decoding
Dependent: 01 - Priority acceptable
port 0x620-0x680, align 0x1f, size 0x4, 16-bit address decoding
* post-quirk:
Dependent: 00 - Priority preferred
port 0x620-0x620, align 0x0, size 0x4, 16-bit address decoding
port 0xa20-0xa20, align 0x0, size 0x4, 16-bit address decoding
port 0xe20-0xe20, align 0x0, size 0x4, 16-bit address decoding
Dependent: 01 - Priority acceptable
port 0x620-0x680, align 0x1f, size 0x4, 16-bit address decoding
port 0xa20-0xa80, align 0x1f, size 0x4, 16-bit address decoding
port 0xe20-0xe80, align 0x1f, size 0x4, 16-bit address decoding
I actually expect this quirk to be totally bogus. This adds ports which
isapnp_set_resources is then going to try to program into hardware which
wouldn't be expecting them. The ALSA driver only references port0 (the
0x620 one) and hardcodes the two other ports at +0x400 and +0x800
itself. I expect the issue is simply that the offsetted ones alias and
somebody once thought this could be a way to just reserve those or
something.
It's been there since the dawning of time though. Will look at some
other time. Things work fine.
== 2 == quirk_cmi8330_resources, @X@0001 (Invalid ID!)
* pre-quirk:
Dependent: 00 - Priority preferred
port 0x220-0x220, align 0x0, size 0x10, 10-bit address decoding
irq 5 High-Edge
dma 1 8-bit byte-count compatible
dma 5 16-bit word-count compatible
Dependent: 01 - Priority acceptable
port 0x220-0x240, align 0x1f, size 0x10, 10-bit address decoding
irq 5,7,2/9,10 High-Edge
dma 0,1,3 8-bit byte-count compatible
dma 5,7 16-bit word-count compatible
Dependent: 02 - Priority acceptable
port 0x220-0x240, align 0x1f, size 0x10, 10-bit address decoding
irq 5,7,2/9,10,11,12 High-Edge
dma 0,1,3 8-bit byte-count compatible
dma 5,7 16-bit word-count compatible
* post-quirk:
Dependent: 00 - Priority preferred
port 0x220-0x220, align 0x0, size 0x10, 10-bit address decoding
irq 5,7,10 High-Edge
dma 1,3 8-bit byte-count compatible
dma 5 16-bit word-count compatible
Dependent: 01 - Priority acceptable
port 0x220-0x240, align 0x1f, size 0x10, 10-bit address decoding
irq 5,7,10 High-Edge
dma 1,3 8-bit byte-count compatible
dma 5,7 16-bit word-count compatible
Dependent: 02 - Priority acceptable
port 0x220-0x240, align 0x1f, size 0x10, 10-bit address decoding
irq 5,7,10 High-Edge
dma 1,3 8-bit byte-count compatible
dma 5,7 16-bit word-count compatible
I'll need to verify if this wasn't just someone with a busted DMA
channel 0 and too few free interrupts. Unlikely quirk...
== 3 == quirk_sb16audio_resources, CTL0042:
* pre-quirk:
Dependent: 00 - Priority preferred
irq 5 High-Edge
dma 1 8-bit byte-count compatible
dma 5 16-bit word-count compatible
port 0x220-0x220, align 0x0, size 0x10, 16-bit address decoding
port 0x330-0x330, align 0x0, size 0x2, 16-bit address decoding
port 0x388-0x388, align 0x0, size 0x4, 16-bit address decoding
Dependent: 01 - Priority acceptable
irq 5,7,2/9,10 High-Edge
dma 0,1,3 8-bit byte-count compatible
dma 5,6,7 16-bit word-count compatible
port 0x220-0x280, align 0x1f, size 0x10, 16-bit address decoding
port 0x300-0x330, align 0x2f, size 0x2, 16-bit address decoding
port 0x388-0x388, align 0x0, size 0x4, 16-bit address decoding
Dependent: 02 - Priority acceptable
irq 5,7,2/9,10 High-Edge
dma 0,1,3 8-bit byte-count compatible
dma 5,6,7 16-bit word-count compatible
port 0x220-0x280, align 0x1f, size 0x10, 16-bit address decoding
port 0x300-0x330, align 0x2f, size 0x2, 16-bit address decoding
Dependent: 03 - Priority acceptable
irq 5,7,2/9,10 High-Edge
dma 0,1,3 8-bit byte-count compatible
dma 5,6,7 16-bit word-count compatible
port 0x220-0x280, align 0x1f, size 0x10, 16-bit address decoding
Dependent: 04 - Priority acceptable
irq 5,7,2/9,10 High-Edge
dma 0,1,3 8-bit byte-count compatible
port 0x220-0x280, align 0x1f, size 0x10, 16-bit address decoding
port 0x300-0x330, align 0x2f, size 0x2, 16-bit address decoding
port 0x388-0x388, align 0x0, size 0x4, 16-bit address decoding
Dependent: 05 - Priority acceptable
irq 5,7,2/9,10 High-Edge
dma 0,1,3 8-bit byte-count compatible
port 0x220-0x280, align 0x1f, size 0x10, 16-bit address decoding
port 0x300-0x330, align 0x2f, size 0x2, 16-bit address decoding
Dependent: 06 - Priority acceptable
irq 5,7,2/9,10 High-Edge
dma 0,1,3 8-bit byte-count compatible
port 0x220-0x280, align 0x1f, size 0x10, 16-bit address decoding
Dependent: 07 - Priority functional
irq 5,7,2/9,10 High-Edge
dma 0,1,3 8-bit byte-count compatible
dma 5,6,7 16-bit word-count compatible
port 0x220-0x280, align 0x1f, size 0x10, 16-bit address decoding
port 0x300-0x330, align 0xf, size 0x2, 16-bit address decoding
port 0x388-0x394, align 0x3, size 0x4, 16-bit address decoding
* post-quirk:
Dependent: 00 - Priority preferred
irq 5 High-Edge
dma 1 8-bit byte-count compatible
dma 5 16-bit word-count compatible
port 0x220-0x220, align 0x0, size 0x10, 16-bit address decoding
port 0x330-0x330, align 0x0, size 0x2, 16-bit address decoding
port 0x388-0x3f8, align 0x0, size 0x4, 16-bit address decoding
Dependent: 01 - Priority acceptable
irq 5,7,2/9,10 High-Edge
dma 0,1,3 8-bit byte-count compatible
dma 5,6,7 16-bit word-count compatible
port 0x220-0x280, align 0x1f, size 0x10, 16-bit address decoding
port 0x300-0x330, align 0x2f, size 0x2, 16-bit address decoding
port 0x388-0x3f8, align 0x0, size 0x4, 16-bit address decoding
Dependent: 02 - Priority acceptable
irq 5,7,2/9,10 High-Edge
dma 0,1,3 8-bit byte-count compatible
dma 5,6,7 16-bit word-count compatible
port 0x220-0x280, align 0x1f, size 0x10, 16-bit address decoding
port 0x300-0x330, align 0x2f, size 0x2, 16-bit address decoding
Dependent: 03 - Priority acceptable
irq 5,7,2/9,10 High-Edge
dma 0,1,3 8-bit byte-count compatible
dma 5,6,7 16-bit word-count compatible
port 0x220-0x280, align 0x1f, size 0x10, 16-bit address decoding
Dependent: 04 - Priority acceptable
irq 5,7,2/9,10 High-Edge
dma 0,1,3 8-bit byte-count compatible
port 0x220-0x280, align 0x1f, size 0x10, 16-bit address decoding
port 0x300-0x330, align 0x2f, size 0x2, 16-bit address decoding
port 0x388-0x3f8, align 0x0, size 0x4, 16-bit address decoding
Dependent: 05 - Priority acceptable
irq 5,7,2/9,10 High-Edge
dma 0,1,3 8-bit byte-count compatible
port 0x220-0x280, align 0x1f, size 0x10, 16-bit address decoding
port 0x300-0x330, align 0x2f, size 0x2, 16-bit address decoding
Dependent: 06 - Priority acceptable
irq 5,7,2/9,10 High-Edge
dma 0,1,3 8-bit byte-count compatible
port 0x220-0x280, align 0x1f, size 0x10, 16-bit address decoding
Dependent: 07 - Priority functional
irq 5,7,2/9,10 High-Edge
dma 0,1,3 8-bit byte-count compatible
dma 5,6,7 16-bit word-count compatible
port 0x220-0x280, align 0x1f, size 0x10, 16-bit address decoding
port 0x300-0x330, align 0xf, size 0x2, 16-bit address decoding
port 0x388-0x394, align 0x3, size 0x4, 16-bit address decoding
I'll need to verify if the OPL chip in fact works when not on 0x388 (to
0x394 as set 7 allows for) or if this was just someone believing it
would. I haven't tested all supported IDs (I might have them all) but if
there are none that do _not_ allow the OPL to be completely absent as
this CTL0042 (an early Soundblaster AWE64) does, this quirk should just
go anyway.
=== 4 === quirk_ad1815_mpu_resources, ADS7151
These results are with the dependent cloning already removed locally.
* pre-quirk:
irq 5,7,2/9,11,12 High-Edge
Dependent: 00 - Priority preferred
port 0x330-0x330, align 0x0, size 0x2, 10-bit address decoding
Dependent: 01 - Priority acceptable
port 0x300-0x300, align 0x0, size 0x2, 10-bit address decoding
Dependent: 02 - Priority functional
port 0x100-0x3fe, align 0x1, size 0x2, 10-bit address decoding
* post-quirk:
irq 5,7,2/9,11,12 High-Edge
Dependent: 00 - Priority preferred
port 0x330-0x330, align 0x0, size 0x2, 10-bit address decoding
Dependent: 01 - Priority acceptable
port 0x300-0x300, align 0x0, size 0x2, 10-bit address decoding
Dependent: 02 - Priority functional
port 0x100-0x3fe, align 0x1, size 0x2, 10-bit address decoding
See why that "(optional)" flag display is good? :-) I ofcourse tested
things and the flag works great...
== 5 == quirk_add_irq_optional_dependent_sets, ADS7181
* pre-quirk:
Dependent: 00 - Priority preferred
irq 2/9 High-Edge
port 0x330-0x330, align 0xf, size 0x2, 16-bit address decoding
Dependent: 01 - Priority acceptable
irq 2/9 High-Edge
port 0x300-0x330, align 0xf, size 0x2, 16-bit address decoding
Dependent: 02 - Priority functional
irq 2/9,10,11 High-Edge
port 0x300-0x330, align 0xf, size 0x2, 16-bit address decoding
* post-quirk:
Dependent: 00 - Priority preferred
irq 2/9 High-Edge
port 0x330-0x330, align 0xf, size 0x2, 16-bit address decoding
Dependent: 01 - Priority acceptable
irq 2/9 High-Edge
port 0x300-0x330, align 0xf, size 0x2, 16-bit address decoding
Dependent: 02 - Priority functional
irq 2/9,10,11 High-Edge
port 0x300-0x330, align 0xf, size 0x2, 16-bit address decoding
Dependent: 03 - Priority functional
irq 2/9 High-Edge
port 0x330-0x330, align 0xf, size 0x2, 16-bit address decoding
Dependent: 04 - Priority functional
irq 2/9 High-Edge
port 0x300-0x330, align 0xf, size 0x2, 16-bit address decoding
Dependent: 05 - Priority functional
irq 2/9,10,11 High-Edge
port 0x300-0x330, align 0xf, size 0x2, 16-bit address decoding
Again needs the flag display to make sense but as intended and works fine.
The PCI one didn't change here...
Rene.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 15/15] PNP: convert resource options to single linked list
2008-06-03 23:03 ` Bjorn Helgaas
@ 2008-06-04 0:03 ` Rene Herman
0 siblings, 0 replies; 46+ messages in thread
From: Rene Herman @ 2008-06-04 0:03 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 04-06-08 01:03, Bjorn Helgaas wrote:
> That's definitely backwards. I reversed the sizes, so we'll have
> 8 bits for the priority byte (including compatibility/performance/
> robustness) and 16 bits for the dependent set number. Actually,
> I made the priority field 12 bits so we'd have space to keep
> PNP_RES_PRIORITY_INVALID as a truly out-of-band value.
Sounds perfect.
>>> + for (i = 0; i == 0 || i < dev->num_dependent_sets; i++) {
>>> + ret = pnp_assign_resources(dev, i);
>>> + if (ret == 0)
>>> return 0;
>> Eeeew. Perhaps:
>>
>> i = 0;
>> do {
>> ret = pnp_assign_resources(dev, i);
>> if (ret == 0)
>> return 0;
>> } while (++i < dev->num_dependent_sets);
>
> Heh :-) I vacillated on that one because I have a personal aversion
> to "do { ... } while ()", especially with a pre-increment. How would
> you feel about this alternative?
>
> 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;
> }
You could fix the pre-increment by sticking a i++ inside the loop body
but there's no arguing with personal aversions...
Yes, I think the latter is better. Straight-forward and clear.
>> Why do you do 0x800, 0x400 in that order? Shouldn't it just be 0x400,
>> 0x800 to mimick the old order?
>
> I think they do end up in the correct order because I'm passing the
> same list_head to both list_add() calls, e.g., we'll have something
> like this:
>
> io -> ...
> io -> (io + 0x800) -> ...
> io -> (io + 0x400) -> (io + 0x800) -> ...
Yep. Just needed to see it happen once in the quirk testing I just now did.
> I need to go back over all your comments and make sure I've addressed
> them all, then I'll post the revised patches, hopefully tomorrow.
>
> Thanks again for all your work reviewing and testing these. It's
> been incredibly useful.
I've been impressed by this work. This is a good redesign of PnP with a
fully bisectable way to get there. And PnP was in need of some work...
Rene.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 15/15] PNP: convert resource options to single linked list
2008-06-03 23:52 ` Rene Herman
@ 2008-06-04 11:48 ` Rene Herman
2008-06-04 20:50 ` Bjorn Helgaas
0 siblings, 1 reply; 46+ messages in thread
From: Rene Herman @ 2008-06-04 11:48 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 04-06-08 01:52, Rene Herman wrote:
Mmm. If you care for it:
> === 4 === quirk_ad1815_mpu_resources, ADS7151
>
> These results are with the dependent cloning already removed locally.
>
> * pre-quirk:
>
> irq 5,7,2/9,11,12 High-Edge
> Dependent: 00 - Priority preferred
> port 0x330-0x330, align 0x0, size 0x2, 10-bit address decoding
> Dependent: 01 - Priority acceptable
> port 0x300-0x300, align 0x0, size 0x2, 10-bit address decoding
> Dependent: 02 - Priority functional
> port 0x100-0x3fe, align 0x1, size 0x2, 10-bit address decoding
>
> * post-quirk:
>
> irq 5,7,2/9,11,12 High-Edge
> Dependent: 00 - Priority preferred
> port 0x330-0x330, align 0x0, size 0x2, 10-bit address decoding
> Dependent: 01 - Priority acceptable
> port 0x300-0x300, align 0x0, size 0x2, 10-bit address decoding
> Dependent: 02 - Priority functional
> port 0x100-0x3fe, align 0x1, size 0x2, 10-bit address decoding
>
>
> See why that "(optional)" flag display is good? :-) I ofcourse tested
> things and the flag works great...
>
>
> == 5 == quirk_add_irq_optional_dependent_sets, ADS7181
>
> * pre-quirk:
>
> Dependent: 00 - Priority preferred
> irq 2/9 High-Edge
> port 0x330-0x330, align 0xf, size 0x2, 16-bit address decoding
> Dependent: 01 - Priority acceptable
> irq 2/9 High-Edge
> port 0x300-0x330, align 0xf, size 0x2, 16-bit address decoding
> Dependent: 02 - Priority functional
> irq 2/9,10,11 High-Edge
> port 0x300-0x330, align 0xf, size 0x2, 16-bit address decoding
>
> * post-quirk:
>
> Dependent: 00 - Priority preferred
> irq 2/9 High-Edge
> port 0x330-0x330, align 0xf, size 0x2, 16-bit address decoding
> Dependent: 01 - Priority acceptable
> irq 2/9 High-Edge
> port 0x300-0x330, align 0xf, size 0x2, 16-bit address decoding
> Dependent: 02 - Priority functional
> irq 2/9,10,11 High-Edge
> port 0x300-0x330, align 0xf, size 0x2, 16-bit address decoding
> Dependent: 03 - Priority functional
> irq 2/9 High-Edge
> port 0x330-0x330, align 0xf, size 0x2, 16-bit address decoding
> Dependent: 04 - Priority functional
> irq 2/9 High-Edge
> port 0x300-0x330, align 0xf, size 0x2, 16-bit address decoding
> Dependent: 05 - Priority functional
> irq 2/9,10,11 High-Edge
> port 0x300-0x330, align 0xf, size 0x2, 16-bit address decoding
ADS7181 in fact might as well delete the IRQ from the dependents and add
"irq 2/9,10,11 High-Edge Optinal" in front as an independent same as
ADS7151. That way, all the cloning can go.
I'll probably place that on top if you don't, but you might already want
to since it loses all that code. Only difference would be that if IRQ 9
is taken and 10 free, the new situation would grab 330/10 while the old
would've taken 300/10, but that's in fact better...
Rene.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 15/15] PNP: convert resource options to single linked list
2008-06-04 11:48 ` Rene Herman
@ 2008-06-04 20:50 ` Bjorn Helgaas
2008-06-04 22:31 ` Rene Herman
0 siblings, 1 reply; 46+ messages in thread
From: Bjorn Helgaas @ 2008-06-04 20:50 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 Wednesday 04 June 2008 05:48:27 am Rene Herman wrote:
> On 04-06-08 01:52, Rene Herman wrote:
> ADS7181 in fact might as well delete the IRQ from the dependents and add
> "irq 2/9,10,11 High-Edge Optinal" in front as an independent same as
> ADS7151. That way, all the cloning can go.
We currently clone for AZT0002 as well as ADS7181. Can we do the
same for both? It would be nice to get rid of the cloning code
if we can.
Bjorn
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 15/15] PNP: convert resource options to single linked list
2008-06-03 21:13 ` Rene Herman
@ 2008-06-04 21:26 ` Bjorn Helgaas
0 siblings, 0 replies; 46+ messages in thread
From: Bjorn Helgaas @ 2008-06-04 21:26 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 Tuesday 03 June 2008 03:13:37 pm Rene Herman wrote:
> On 31-05-08 00:49, Bjorn Helgaas wrote:
>
> Forgot this comment:
>
> > --- work10.orig/drivers/pnp/quirks.c 2008-05-30 15:58:14.000000000 -0600
> > +++ work10/drivers/pnp/quirks.c 2008-05-30 15:58:15.000000000 -0600
>
> > +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_dependent_option(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;
> > }
>
> This works, but I did the "disconnected chain build" that I did due to
> finding it particularly clumsy to add to the dependent chain while
> walking it.
>
> This avoids actual problems due to num_sets = dev->num_dependents_sets
> in caller and the pnp_option_set(option) == set in the loop (not unlike
> the first version of the original checked for a present irq) but it's
> again checking the options it just added itself.
>
> If you feel that's perfectly fine then <shrug> but thought I'd still
> remark on it in case it wasn't intentional.
Hmmm... I think I see what you mean. It should work as-is, but
maybe it'd be more elegant to build the new list separately and use
list_splice to insert it.
Guess I'll wait for you to confirm whether we can rip out the list
clone altogether before trying this out.
Bjorn
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 15/15] PNP: convert resource options to single linked list
2008-06-04 20:50 ` Bjorn Helgaas
@ 2008-06-04 22:31 ` Rene Herman
2008-06-04 23:06 ` Bjorn Helgaas
0 siblings, 1 reply; 46+ messages in thread
From: Rene Herman @ 2008-06-04 22: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 04-06-08 22:50, Bjorn Helgaas wrote:
> On Wednesday 04 June 2008 05:48:27 am Rene Herman wrote:
>> On 04-06-08 01:52, Rene Herman wrote:
>
>> ADS7181 in fact might as well delete the IRQ from the dependents and add
>> "irq 2/9,10,11 High-Edge Optinal" in front as an independent same as
>> ADS7151. That way, all the cloning can go.
>
> We currently clone for AZT0002 as well as ADS7181. Can we do the
> same for both? It would be nice to get rid of the cloning code
> if we can.
Yes. AZT0002 (the MPU401 on an AZT2320 chip) is the exact same as
ADS7181 (the MPU401 on an AD1816 chip).
IORESOURCE_IRQ_OPTIONAL clears the path for doing things better. I see
its dependent 2 can then just go entirely in fact.
Hardware says:
Dependent: 00 - Priority preferred
irq 2/9 High-Edge
port 0x330-0x330, align 0xf, size 0x2, 16-bit address decoding
Dependent: 01 - Priority acceptable
irq 2/9 High-Edge
port 0x300-0x330, align 0xf, size 0x2, 16-bit address decoding
Dependent: 02 - Priority functional
irq 2/9,10,11 High-Edge
port 0x300-0x330, align 0xf, size 0x2, 16-bit address decoding
We want it to end up as:
irq 2/9,10,11 High-Edge (Optional)
Dependent: 00 - Priority preferred
port 0x330-0x330, align 0xf, size 0x2, 16-bit address decoding
Dependent: 01 - Priority acceptable
port 0x300-0x330, align 0xf, size 0x2, 16-bit address decoding
So walk dependents deleting IRQs, except last dependent IRQ which is
cloned into a new independent (inserted in front would be best for
ISAPnP since the spec does recommend this) while making it optional and
then just delete the last dependent completely (it would be same as the
previous dependent after all).
Rene.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [patch 15/15] PNP: convert resource options to single linked list
2008-06-04 22:31 ` Rene Herman
@ 2008-06-04 23:06 ` Bjorn Helgaas
0 siblings, 0 replies; 46+ messages in thread
From: Bjorn Helgaas @ 2008-06-04 23:06 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 Wednesday 04 June 2008 04:31:02 pm Rene Herman wrote:
> On 04-06-08 22:50, Bjorn Helgaas wrote:
>
> > On Wednesday 04 June 2008 05:48:27 am Rene Herman wrote:
> >> On 04-06-08 01:52, Rene Herman wrote:
> >
> >> ADS7181 in fact might as well delete the IRQ from the dependents and add
> >> "irq 2/9,10,11 High-Edge Optinal" in front as an independent same as
> >> ADS7151. That way, all the cloning can go.
> >
> > We currently clone for AZT0002 as well as ADS7181. Can we do the
> > same for both? It would be nice to get rid of the cloning code
> > if we can.
>
> Yes. AZT0002 (the MPU401 on an AZT2320 chip) is the exact same as
> ADS7181 (the MPU401 on an AD1816 chip).
>
> IORESOURCE_IRQ_OPTIONAL clears the path for doing things better. I see
> its dependent 2 can then just go entirely in fact.
>
> Hardware says:
>
> Dependent: 00 - Priority preferred
> irq 2/9 High-Edge
> port 0x330-0x330, align 0xf, size 0x2, 16-bit address decoding
> Dependent: 01 - Priority acceptable
> irq 2/9 High-Edge
> port 0x300-0x330, align 0xf, size 0x2, 16-bit address decoding
> Dependent: 02 - Priority functional
> irq 2/9,10,11 High-Edge
> port 0x300-0x330, align 0xf, size 0x2, 16-bit address decoding
>
> We want it to end up as:
>
> irq 2/9,10,11 High-Edge (Optional)
> Dependent: 00 - Priority preferred
> port 0x330-0x330, align 0xf, size 0x2, 16-bit address decoding
> Dependent: 01 - Priority acceptable
> port 0x300-0x330, align 0xf, size 0x2, 16-bit address decoding
>
> So walk dependents deleting IRQs, except last dependent IRQ which is
> cloned into a new independent (inserted in front would be best for
> ISAPnP since the spec does recommend this) while making it optional and
> then just delete the last dependent completely (it would be same as the
> previous dependent after all).
That would probably simplify things a bit. Although in the general
case, I suppose we'd want to make sure the options we delete are
a subset of the independent one we add. Will look at this more
tomorrow.
Bjorn
^ permalink raw reply [flat|nested] 46+ messages in thread
end of thread, other threads:[~2008-06-04 23:06 UTC | newest]
Thread overview: 46+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-05-30 22:48 [patch 00/15] PNP: convert resource options to unified dynamic list, v1 Bjorn Helgaas
2008-05-30 22:48 ` [patch 01/15] serial: when guessing, check only active resources, not options Bjorn Helgaas
2008-06-01 19:42 ` Rene Herman
2008-06-02 15:21 ` Bjorn Helgaas
2008-05-30 22:48 ` [patch 02/15] PNP: whitespace/coding style fixes Bjorn Helgaas
2008-06-01 19:52 ` Rene Herman
2008-05-30 22:48 ` [patch 03/15] PNP: define PNP-specific IORESOURCE_IO_* flags alongside IRQ, DMA, MEM Bjorn Helgaas
2008-06-01 21:03 ` Rene Herman
2008-05-30 22:48 ` [patch 04/15] PNP: make resource option structures private to PNP subsystem Bjorn Helgaas
2008-06-01 21:06 ` Rene Herman
2008-05-30 22:48 ` [patch 05/15] PNP: introduce pnp_irq_mask_t typedef Bjorn Helgaas
2008-06-01 21:25 ` Rene Herman
2008-05-30 22:48 ` [patch 06/15] PNP: increase I/O port & memory option address sizes Bjorn Helgaas
2008-06-01 21:39 ` Rene Herman
2008-05-30 22:49 ` [patch 07/15] PNP: improve resource assignment debug Bjorn Helgaas
2008-06-01 21:41 ` Rene Herman
2008-05-30 22:49 ` [patch 08/15] PNP: in debug resource dump, make empty list obvious Bjorn Helgaas
2008-06-01 21:44 ` Rene Herman
2008-05-30 22:49 ` [patch 09/15] PNP: make resource assignment functions return 0 (success) or -EBUSY (failure) Bjorn Helgaas
2008-06-01 21:59 ` Rene Herman
2008-05-30 22:49 ` [patch 10/15] PNP: remove redundant pnp_can_configure() check Bjorn Helgaas
2008-06-01 22:00 ` Rene Herman
2008-05-30 22:49 ` [patch 11/15] PNP: centralize resource option allocations Bjorn Helgaas
2008-06-01 23:21 ` Rene Herman
2008-06-02 15:29 ` Bjorn Helgaas
2008-05-30 22:49 ` [patch 12/15] PNPACPI: ignore _PRS interrupt numbers larger than PNP_IRQ_NR Bjorn Helgaas
2008-06-01 23:23 ` Rene Herman
2008-05-30 22:49 ` [patch 13/15] PNP: rename pnp_register_*_resource() local variables Bjorn Helgaas
2008-06-01 23:25 ` Rene Herman
2008-05-30 22:49 ` [patch 14/15] PNP: support optional IRQ resources Bjorn Helgaas
2008-06-03 17:37 ` Rene Herman
2008-06-03 20:20 ` Bjorn Helgaas
2008-06-03 20:25 ` Rene Herman
2008-05-30 22:49 ` [patch 15/15] PNP: convert resource options to single linked list Bjorn Helgaas
2008-06-03 19:57 ` Rene Herman
2008-06-03 23:03 ` Bjorn Helgaas
2008-06-04 0:03 ` Rene Herman
2008-06-03 23:52 ` Rene Herman
2008-06-04 11:48 ` Rene Herman
2008-06-04 20:50 ` Bjorn Helgaas
2008-06-04 22:31 ` Rene Herman
2008-06-04 23:06 ` Bjorn Helgaas
2008-06-03 21:13 ` Rene Herman
2008-06-04 21:26 ` Bjorn Helgaas
2008-06-01 19:28 ` [patch 00/15] PNP: convert resource options to unified dynamic list, v1 Rene Herman
2008-06-02 15:56 ` Bjorn Helgaas
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox