summaryrefslogtreecommitdiff
path: root/drivers/pnp
diff options
context:
space:
mode:
authorBjorn Helgaas <bjorn.helgaas@hp.com>2008-06-27 16:57:16 -0600
committerAndi Kleen <andi@basil.nowhere.org>2008-07-16 23:27:07 +0200
commitbbe413b4fc7f791248c7ee00ce7b3778491a3700 (patch)
tree5225313f499012fa30419092ad8532a458531dc2 /drivers/pnp
parente2a1a6f1cfaf6ee770a8700e5df8a3708dae503b (diff)
downloadlwn-bbe413b4fc7f791248c7ee00ce7b3778491a3700.tar.gz
lwn-bbe413b4fc7f791248c7ee00ce7b3778491a3700.zip
ISAPNP: handle independent options following dependent ones
The ISAPNP spec recommends that independent options precede dependent ones, but this is not actually required. The current ISAPNP code incorrectly puts such trailing independent options at the end of the last dependent option list. This patch fixes that bug by resetting the current option list to the independent list when we see an "End Dependent Functions" tag. PNPBIOS and PNPACPI handle this the same way. Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Signed-off-by: Andi Kleen <ak@linux.intel.com> Acked-by: Rene Herman <rene.herman@gmail.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/pnp')
-rw-r--r--drivers/pnp/isapnp/core.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index 90718be66463..53cc4d6133e6 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -584,14 +584,14 @@ static int __init isapnp_create_device(struct pnp_card *card,
{
int number = 0, skip = 0, priority, compat = 0;
unsigned char type, tmp[17];
- struct pnp_option *option;
+ struct pnp_option *option, *option_independent;
struct pnp_dev *dev;
u32 eisa_id;
char id[8];
if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
return 1;
- option = pnp_register_independent_option(dev);
+ option_independent = option = pnp_register_independent_option(dev);
if (!option) {
kfree(dev);
return 1;
@@ -613,6 +613,7 @@ static int __init isapnp_create_device(struct pnp_card *card,
size = 0;
skip = 0;
option = pnp_register_independent_option(dev);
+ option_independent = option;
if (!option) {
kfree(dev);
return 1;
@@ -662,6 +663,10 @@ static int __init isapnp_create_device(struct pnp_card *card,
case _STAG_ENDDEP:
if (size != 0)
goto __skip;
+ if (option_independent == option)
+ dev_warn(&dev->dev, "missing "
+ "_STAG_STARTDEP tag\n");
+ option = option_independent;
dev_dbg(&dev->dev, "end dependent options\n");
break;
case _STAG_IOPORT: