Re: Question about the PCI bus.

Martin Mares (mj@atrey.karlin.mff.cuni.cz)
Wed, 4 Feb 1998 10:15:41 +0100


Hello,

> A friend of mine got a Toshiba 520 CDT laptop and we loaded rh5.0
> linux on it but the PCI chipset doesn't appear to be supported by
> Linux 2.1.84 yet. I have no problems with the pci chipset in my
> Toshiba 510 CDT. I was wondering where I could find some information
> about PCI as a reference. I don't know what is supposed to happen when
> the PCI bus driver probes the hardware. The error that is reported in
> the startup messages is:
>
> PCI: 00:10 [1179/060a/060700] has unknown header type 82, ignoring.
> PCI: 00:11 [1179/060a/060700] has unknown header type 82, ignoring.
>
> pci.c 92: pcibios_read_config_dwordbi(bus->number, devfn, PCI_VENDOR_ID, &l);
>
> is the line that seems to generate the error. I traced it into
> arch/i386/kernel/bios32.c but I didn't know what access_pci is set to
> in this system. So without having to buy and read all the pci manuals
> can anyone give me some pointers on what I can do to troubleshoot this
> problem.

I haven't found this header type in the PCI specs, but there is a brief
description of its structure in the Ralf Brown's Interrupt List. The following
makes the kernel recognize it.

Have a nice fortnight

-- 
Martin `MJ' Mares   <mj@ucw.cz>   http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
"System going down at 1:45 for disk crashing."

diff -ruN /usr/src/linux-2.1/drivers/pci/pci.c drivers/pci/pci.c --- /usr/src/linux-2.1/drivers/pci/pci.c Mon Feb 2 13:40:23 1998 +++ drivers/pci/pci.c Mon Feb 2 15:17:54 1998 @@ -1,9 +1,9 @@ /* - * $Id: pci.c,v 1.55 1997/12/27 12:17:54 mj Exp $ + * $Id: pci.c,v 1.58 1998/02/02 14:15:47 mj Exp $ * * PCI services that are built on top of the BIOS32 service. * - * Copyright 1993, 1994, 1995, 1997 Drew Eckhardt, Frederic Potter, + * Copyright 1993 -- 1998 Drew Eckhardt, Frederic Potter, * David Mosberger-Tang, Martin Mares */ @@ -18,7 +18,7 @@ #include <asm/page.h> struct pci_bus pci_root; -struct pci_dev *pci_devices = 0; +struct pci_dev *pci_devices = NULL; #undef DEBUG @@ -112,9 +112,10 @@ pcibios_read_config_dword(bus->number, devfn, PCI_CLASS_REVISION, &class); class >>= 8; /* upper 3 bytes */ dev->class = class; + dev->hdr_type = hdr_type; switch (hdr_type & 0x7f) { /* header type */ - case 0: /* standard header */ + case PCI_HEADER_TYPE_NORMAL: /* standard header */ if (class >> 8 == PCI_CLASS_BRIDGE_PCI) goto bad; /* read irq level (may be changed during pcibios_fixup()): */ @@ -129,12 +130,20 @@ dev->base_address[reg] = (l == 0xffffffff) ? 0 : l; } break; - case 1: /* bridge header */ + case PCI_HEADER_TYPE_BRIDGE: /* bridge header */ if (class >> 8 != PCI_CLASS_BRIDGE_PCI) goto bad; for (reg = 0; reg < 2; reg++) { pcibios_read_config_dword(bus->number, devfn, PCI_BASE_ADDRESS_0 + (reg << 2), &l); dev->base_address[reg] = (l == 0xffffffff) ? 0 : l; + } + break; + case PCI_HEADER_TYPE_CARDBUS: /* CardBus bridge header */ + if (class >> 16 != PCI_BASE_CLASS_BRIDGE) + goto bad; + for (reg = 0; reg < 2; reg++) { + pcibios_read_config_dword(bus->number, devfn, PCI_CB_MEMORY_BASE_0 + (reg << 3), &l); + dev->base_address[reg] = (l = 0xffffffff) ? 0 : l; } break; default: /* unknown header */ diff -ruN /usr/src/linux-2.1/drivers/pci/proc.c drivers/pci/proc.c --- /usr/src/linux-2.1/drivers/pci/proc.c Mon Feb 2 13:40:23 1998 +++ drivers/pci/proc.c Mon Feb 2 15:20:48 1998 @@ -1,12 +1,11 @@ /* - * $Id: proc.c,v 1.1 1997/12/22 17:22:31 mj Exp $ + * $Id: proc.c,v 1.4 1998/02/02 14:18:42 mj Exp $ * * Procfs interface for the PCI bus. * - * Copyright (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz> + * Copyright (c) 1997, 1998 Martin Mares <mj@atrey.karlin.mff.cuni.cz> */ -#include <linux/config.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/bios32.h> @@ -50,14 +49,27 @@ int pos = *ppos; unsigned char bus = dev->bus->number; unsigned char dfn = dev->devfn; - int cnt; + int cnt, size; - if (pos >= PCI_CFG_SPACE_SIZE) + /* + * Normal users can read only the standardized portion of the + * configuration space as several chips lock up when trying to read + * undefined locations (think of Intel PIIX4 as a typical example). + */ + + if (fsuser()) + size = PCI_CFG_SPACE_SIZE; + else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) + size = 128; + else + size = 64; + + if (pos >= size) return 0; - if (nbytes >= PCI_CFG_SPACE_SIZE) - nbytes = PCI_CFG_SPACE_SIZE; - if (pos + nbytes > PCI_CFG_SPACE_SIZE) - nbytes = PCI_CFG_SPACE_SIZE - pos; + if (nbytes >= size) + nbytes = size; + if (pos + nbytes > size) + nbytes = size - pos; cnt = nbytes; if (!access_ok(VERIFY_WRITE, buf, cnt)) --- /usr/src/linux-2.1/include/linux/pci.h Mon Feb 2 13:40:26 1998 +++ include/linux/pci.h Mon Feb 2 15:17:51 1998 @@ -1,5 +1,5 @@ /* - * $Id: pci.h,v 1.51 1997/12/27 13:55:23 mj Exp $ + * $Id: pci.h,v 1.55 1998/02/02 14:15:41 mj Exp $ * * PCI defines and function prototypes * Copyright 1994, Drew Eckhardt @@ -68,6 +68,10 @@ #define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */ #define PCI_LATENCY_TIMER 0x0d /* 8 bits */ #define PCI_HEADER_TYPE 0x0e /* 8 bits */ +#define PCI_HEADER_TYPE_NORMAL 0 +#define PCI_HEADER_TYPE_BRIDGE 1 +#define PCI_HEADER_TYPE_CARDBUS 2 + #define PCI_BIST 0x0f /* 8 bits */ #define PCI_BIST_CODE_MASK 0x0f /* Return result */ #define PCI_BIST_START 0x40 /* 1 to start BIST, 2 secs or less */ @@ -149,6 +153,36 @@ #define PCI_BRIDGE_CTL_BUS_RESET 0x40 /* Secondary bus reset */ #define PCI_BRIDGE_CTL_FAST_BACK 0x80 /* Fast Back2Back enabled on secondary interface */ +/* Header type 2 (CardBus bridges) -- detailed info welcome */ +#define PCI_CB_CARDBUS_BASE 0x10 /* CardBus Socket/ExCa base address */ +#define PCI_CB_CARDBUS_BASE_TYPE_MASK 0xfff +#define PCI_CB_CARDBUS_BASE_MASK ~0xfff +#define PCI_CB_CAPABILITIES 0x14 /* Offset of list of capabilities in cfg space */ +/* 0x15 reserved */ +#define PCI_CB_SEC_STATUS 0x16 /* Secondary status */ +#define PCI_CB_BUS_NUMBER 0x18 /* PCI bus number */ +#define PCI_CB_CARDBUS_NUMBER 0x19 /* CardBus bus number */ +#define PCI_CB_SUBORDINATE_BUS 0x1a /* Subordinate bus number */ +#define PCI_CB_CARDBUS_LATENCY 0x1b /* CardBus latency timer */ +#define PCI_CB_MEMORY_BASE_0 0x1c +#define PCI_CB_MEMORY_LIMIT_0 0x20 +#define PCI_CB_MEMORY_BASE_1 0x24 +#define PCI_CB_MEMORY_LIMIT_1 0x28 +#define PCI_CB_IO_BASE_0 0x2c +#define PCI_CB_IO_BASE_0_HI 0x2e +#define PCI_CB_IO_LIMIT_0 0x30 +#define PCI_CB_IO_LIMIT_0_HI 0x32 +#define PCI_CB_IO_BASE_1 0x34 +#define PCI_CB_IO_BASE_1_HI 0x36 +#define PCI_CB_IO_LIMIT_1 0x38 +#define PCI_CB_IO_LIMIT_1_HI 0x3a +/* 0x3c-0x3d are same as for htype 0 */ +/* 0x3e-0x3f are same as for htype 1 */ +#define PCI_CB_SUBSYSTEM_ID 0x40 +#define PCI_CB_SUBSYSTEM_VENDOR_ID 0x42 +#define PCI_CB_LEGACY_MODE_BASE 0x44 /* 16-bit PC Card legacy mode base address (ExCa) */ +/* 0x48-0x7f reserved */ + /* Device classes and subclasses */ #define PCI_CLASS_NOT_DEFINED 0x0000 @@ -903,6 +942,7 @@ unsigned short vendor; unsigned short device; unsigned int class; /* 3 bytes: (base,sub,prog-if) */ + unsigned int hdr_type; /* PCI header type */ unsigned int master : 1; /* set if device is master capable */ /* * In theory, the irq level can be read from configuration