I found this problem on the AMD Geode db800 platform but it probably
affects other platforms and chipsets. LinuxBIOS sets every PCI device
PERR# enable and SERR# enable in the PCI Command Register. This is
probably not the right thing to do for a number of reasons.
The PCI spec is not clear on what should be done with a PERR# it is a
device, chipset and platform design desicsion and we don't know what the
platform or device will do. For example, PERR# can be connected to SERR#
which can be connected to reset. Instead of just getting a parity error
you have now reset the system, oops.
Also, PERR# is required to be reported to system software. This has to
be done through the driver via an interrupt (or through polling, ewwww).
As you can see, a lot of pieces need to be in place, the device has to
do the interrupt, the driver should do something with the PERR#, and
then? I don't know if the kernel does anything with the PERR# message.
LinuxBIOS is no longer in play so it can't do anything with the errors.
Because of the uncertainty of PERR# and SERR# I don't think that many
manufacturers use it, especially in the consumer space. They may still
detect and fix parity errors at the hardware level or in their driver,
just not use the PERR# and SERR signals. Note that is a device does have
a parity error it will still report it in
As I noted above, the SERR# can cause a system reset. I think that it
would be better to do nothing and maybe the device will stop/hang/etc
rather than to mysteriously reset. Again, let the system software decide
All this seems like a good reason to let the driver and/or system level
software enable PERR# and SERR# and for LinuxBIOS to leave them alone.
Dissenting opinions welcome.
Senior Firmware Engineer
(970) 226-9684 Office
Don't arbitrarily enable PERR# and SERR# for PCI devices.
It is platform specific.
Signed-off-by: Marc Jones <marc.jones(a)amd.com>
--- LinuxBIOSv2.orig/src/devices/pci_device.c 2007-09-25 11:20:10.000000000 -0600
+++ LinuxBIOSv2/src/devices/pci_device.c 2007-09-25 11:20:41.000000000 -0600
@@ -603,7 +603,6 @@
command = pci_read_config16(dev, PCI_COMMAND);
command |= dev->command;
- command |= (PCI_COMMAND_PARITY + PCI_COMMAND_SERR); /* error check */
printk_debug("%s cmd <- %02x\n", dev_path(dev), command);
pci_write_config16(dev, PCI_COMMAND, command);