Skip to contentSkip to conversation

simple pnp bios io resources bug makes system unusable

DISCUSSION CarlosRomero 3 participants 3 messages Jul 1, 2003 – Jul 2, 2003

lore
Share & tools
lore
#0 lore raw

cat /sys/devices/pnp0/00\:0c/name
Reserved Motherboard Resources

cat /sys/devices/pnp0/00\:0c/resources
state = active
io 0x4d0-0x4d1
io 0xcf8-0xcff
io 0x3f7-0x3f7
io 0x401-0x407
io 0x298-0x298
io 0x00000000-0xffffffff
mem 0xfffe0000-0xffffffff
mem 0x100000-0x7ffffff

fixup: check for null io base, other devices are now able to initialize.

static void current_ioresource(struct pnp_resource_table * res, int io, int len)

{
       int i = 0;
+      if (!io) return;
       while ((res->port_resource[i].flags & IORESOURCE_IO) && i < 
PNP_MAX_PORT) i++;
       if (i < PNP_MAX_PORT) {
               res->port_resource[i].start = (unsigned long) io;
               res->port_resource[i].end = (unsigned long)(io + len - 1);
               res->port_resource[i].flags = IORESOURCE_IO;  // Also 
clears _UNSET flag
       }
}
#1 lore raw

The pnpbios is reserving the complete range of every possible io port. This causes device activation to fail for every device that needs an io port because that resource will always appear busy.

Quoted 14 lines · CarlosRomero

cat /sys/devices/pnp0/00\:0c/name
Reserved Motherboard Resources

cat /sys/devices/pnp0/00\:0c/resources
state = active
io 0x4d0-0x4d1
io 0xcf8-0xcff
io 0x3f7-0x3f7
io 0x401-0x407
io 0x298-0x298
io 0x00000000-0xffffffff
mem 0xfffe0000-0xffffffff
mem 0x100000-0x7ffffff

Quoted 1 line

fixup: check for null io base, other devices are now able to initialize.

Unfortunatly it's not quite that simple.

Quoted 5 lines

static void current_ioresource(struct pnp_resource_table * res, int io, int len)

{
       int i = 0;
Quoted 10 lines
+      if (!io) return;
       while ((res->port_resource[i].flags & IORESOURCE_IO) && i < 
PNP_MAX_PORT) i++;
       if (i < PNP_MAX_PORT) {
               res->port_resource[i].start = (unsigned long) io;
               res->port_resource[i].end = (unsigned long)(io + len - 1);
               res->port_resource[i].flags = IORESOURCE_IO;  // Also
clears _UNSET flag
       }
}

Below are two examples that both use a base of 0 in a valid way.

(one for mem)

# cat id
PNP0c01 /* this is a system device */
# cat resources
state = active
mem 0x0-0x9ffff
mem 0xe4000-0xfffff
mem 0x100000-0x3ffffff
mem 0xfff80000-0xfffbffff

(and one for io ports)

# cat id
PNP0200	/* this is an AT DMA Controller */
# cat resources
state = active
io 0x0-0xf
io 0x81-0x8f
io 0xc0-0xdf
dma 4

Therefore just eliminating base 0 addresses is not a proper solution.

Also if we just skip the culprit resource then the resource index number (a value that many drivers require to be consistent) will be offset by the number of skipped resources of the same type.

Currently I'm leaning toward this logic... if we have any of the following situations
- 0x00000000 for base and 0xffffffff for end
- 0x00000000 for base and 0x00000000 for end
- 0xffffffff for base and 0xffffffff for end then the resource range can be considered disabled.

Also a device can have a disabled resource but not be fully disabled, such as a parport with some features disabled (ECP etc). So the index number must be maintained, this will require some more complex changes.

I'll have a full fix out soon.

Thanks,
Adam

#2 lore raw

In article <[email protected]>,

Quoted 5 lines · Adam Belay

The pnpbios is reserving the complete range of every possible io port. This causes device activation to fail for every device that needs an io port because that resource will always appear busy.

No, I don't think that's what it is doing at all. Quite the reverse, in fact.

Look:

Quoted 4 lines · CarlosRomero
Quoted 3 lines

cat /sys/devices/pnp0/00\:0c/resources
io 0x00000000-0xffffffff

This means that "io" was zero, but more importantly, it means that "len" was zero too.

Quoted 3 lines
Quoted 1 line

fixup: check for null io base, other devices are now able to initialize.

Unfortunatly it's not quite that simple.

It _is_ that simple, but the code should check for "len" being zero, ie the fix looks like it should be just a simple

	if (!len)
		return;

and that should fix it.

Quoted 1 line

Below are two examples that both use a base of 0 in a valid way.

Yes, and clearly they don't have "len == 0".

Quoted 6 lines

Currently I'm leaning toward this logic... if we have any of the following situations
- 0x00000000 for base and 0xffffffff for end
- 0x00000000 for base and 0x00000000 for end
- 0xffffffff for base and 0xffffffff for end then the resource range can be considered disabled.

I would suggest:

- "len == 0" => obviously disabled (both IO and memory)
- "end < base" => obviously disabled due to overflow crap
- "end >= 0x10003" => IO disabled (yeah, non-x86 can have IO above
that range in PCI, but I think it's undefined behaviour)

all three should be cases of "obviously we can't validly have such a resource", and the "len == 0" case should trivially fix the case that CarlosRomero saw.

Linus