From 567cfe2b32b721588e2ca5a278fb8074352584e2 Mon Sep 17 00:00:00 2001 From: Adam Belay Date: Sun, 8 Feb 2004 15:31:19 +0000 Subject: [PATCH] [PNP]: Disable resources fix Some PnPBIOSes do not follow the specifications with regard to disabling devices. This patch preserves the tag bits, while zeroing the resource settings. Previously we would zero the entire buffer. It has been tested and appears to correct the issue while remaining compatible with unbroken PnPBIOSes. --- drivers/pnp/pnpbios/core.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c index 5385876b8cb63..fda35f6f2645e 100644 --- a/drivers/pnp/pnpbios/core.c +++ b/drivers/pnp/pnpbios/core.c @@ -264,19 +264,49 @@ static int pnpbios_set_resources(struct pnp_dev * dev, struct pnp_resource_table return ret; } +static void pnpbios_zero_data_stream(struct pnp_bios_node * node) +{ + unsigned char * p = (char *)node->data; + unsigned char * end = (char *)(node->data + node->size); + unsigned int len; + int i; + while ((char *)p < (char *)end) { + if(p[0] & 0x80) { /* large tag */ + len = (p[2] << 8) | p[1]; + p += 3; + } else { + if (((p[0]>>3) & 0x0f) == 0x0f) + return; + len = p[0] & 0x07; + p += 1; + } + for (i = 0; i < len; i++) + p[i] = 0; + p += len; + } + printk(KERN_ERR "PnPBIOS: Resource structure did not contain an end tag.\n"); +} + static int pnpbios_disable_resources(struct pnp_dev *dev) { struct pnp_bios_node * node; + u8 nodenum = dev->number; int ret; /* just in case */ if(dev->flags & PNPBIOS_NO_DISABLE || !pnpbios_is_dynamic(dev)) return -EPERM; - /* the value of this will be zero */ node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL); if (!node) return -ENOMEM; + + if (pnp_bios_get_dev_node(&nodenum, (char )PNPMODE_DYNAMIC, node)) { + kfree(node); + return -ENODEV; + } + pnpbios_zero_data_stream(node); + ret = pnp_bios_set_dev_node(dev->number, (char)PNPMODE_DYNAMIC, node); kfree(node); if (ret > 0) -- 2.53.0