Commit 567cfe2b authored by Adam Belay's avatar Adam Belay

[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.
parent d89c83be
...@@ -264,19 +264,49 @@ static int pnpbios_set_resources(struct pnp_dev * dev, struct pnp_resource_table ...@@ -264,19 +264,49 @@ static int pnpbios_set_resources(struct pnp_dev * dev, struct pnp_resource_table
return ret; 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) static int pnpbios_disable_resources(struct pnp_dev *dev)
{ {
struct pnp_bios_node * node; struct pnp_bios_node * node;
u8 nodenum = dev->number;
int ret; int ret;
/* just in case */ /* just in case */
if(dev->flags & PNPBIOS_NO_DISABLE || !pnpbios_is_dynamic(dev)) if(dev->flags & PNPBIOS_NO_DISABLE || !pnpbios_is_dynamic(dev))
return -EPERM; return -EPERM;
/* the value of this will be zero */
node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL); node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
if (!node) if (!node)
return -ENOMEM; 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); ret = pnp_bios_set_dev_node(dev->number, (char)PNPMODE_DYNAMIC, node);
kfree(node); kfree(node);
if (ret > 0) if (ret > 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment