Date: Mon, 19 Oct 2009 04:56:45 GMT From: Alexander <bas@it-core.org> To: freebsd-gnats-submit@FreeBSD.org Subject: i386/139743: [ichsmb] [patch] ichsmb driver doesn't detects SMB bus on Asus P4B533/P4PE motherboards Message-ID: <200910190456.n9J4ujqt078519@www.freebsd.org> Resent-Message-ID: <200910190500.n9J50AIH007804@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 139743 >Category: i386 >Synopsis: [ichsmb] [patch] ichsmb driver doesn't detects SMB bus on Asus P4B533/P4PE motherboards >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-i386 >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Mon Oct 19 05:00:10 UTC 2009 >Closed-Date: >Last-Modified: >Originator: Alexander >Release: 7.2-STABLE >Organization: >Environment: FreeBSD freebsd.local 7.2-RELEASE-p4 FreeBSD 7.2-RELEASE-p4 #2: Tue Oct 13 09:08:02 YEKST 2009 bas@freebsd.local:/usr/obj/usr/src/sys/MYROUTER i386 >Description: Asus hides the SMBus PCI bridge within the ICH2 or ICH4 southbridge on Asus P4B533/P4PE mainboards. So ichsmb driver doesn't detects SMB bus. Bug has been known as http://www.freebsd.org/cgi/query-pr.cgi?pr=60226 , but was closed by "feedback timeout". >How-To-Repeat: Include device smbus device ichsmb device smb to the kernel config file, recompile kernel and reboot. New kernel will not detects SMB bus. pciconf -lv will not list it too. >Fix: I ported patch, given in http://www.freebsd.org/cgi/query-pr.cgi?pr=60226 to 7.2-STABLE. Ported patch goes in attach. On my machine (Asus P4PE motherboard) SMBus works after patching. Patch attached with submission follows: diff -ur /usr/src/sys/dev/pci.old/pci.c /usr/src/sys/dev/pci/pci.c --- /usr/src/sys/dev/pci.old/pci.c 2009-04-15 09:14:26.000000000 +0600 +++ /usr/src/sys/dev/pci/pci.c 2009-10-13 08:41:43.000000000 +0600 @@ -112,6 +112,9 @@ static void pci_resume_msi(device_t dev); static void pci_resume_msix(device_t dev); +static void pci_fix_asus_smbus(device_t dev); + + static device_method_t pci_methods[] = { /* Device interface */ DEVMETHOD(device_probe, pci_probe), @@ -179,16 +182,22 @@ int type; #define PCI_QUIRK_MAP_REG 1 /* PCI map register in weird place */ #define PCI_QUIRK_DISABLE_MSI 2 /* MSI/MSI-X doesn't work */ +#define PCI_QUIRK_FIXUP_ROUTINE 4 /* PCI needs a fix to continue */ int arg1; int arg2; + void (*fixup_func)(device_t dev); }; struct pci_quirk pci_quirks[] = { /* The Intel 82371AB and 82443MX has a map register at offset 0x90. */ - { 0x71138086, PCI_QUIRK_MAP_REG, 0x90, 0 }, - { 0x719b8086, PCI_QUIRK_MAP_REG, 0x90, 0 }, + { 0x71138086, PCI_QUIRK_MAP_REG, 0x90, 0, NULL }, + { 0x719b8086, PCI_QUIRK_MAP_REG, 0x90, 0, NULL }, /* As does the Serverworks OSB4 (the SMBus mapping register) */ - { 0x02001166, PCI_QUIRK_MAP_REG, 0x90, 0 }, + { 0x02001166, PCI_QUIRK_MAP_REG, 0x90, 0, NULL }, + + /* The ASUS P4B-motherboards needs a hack to enable the Intel 801SMBus */ + { 0x24408086, PCI_QUIRK_FIXUP_ROUTINE, 0, 0, &pci_fix_asus_smbus }, + { 0x24C08086, PCI_QUIRK_FIXUP_ROUTINE, 0, 0, &pci_fix_asus_smbus }, /* * MSI doesn't work with the ServerWorks CNB20-HE Host Bridge @@ -395,6 +404,26 @@ cfg->hdrtype = 1; } +/* asus p4b/p4pe hack */ +static void +pci_fix_asus_smbus(device_t dev) +{ + int pmccfg; + + /* read subsystem vendor-id */ + pmccfg = pci_read_config(dev, 0xF2, 2); + printf(" [-] pmccfg: %.4x\n",pmccfg); + if( pmccfg & 0x8 ){ + pmccfg &= ~0x8; + pci_write_config(dev, 0xF2, pmccfg, 2); + pmccfg = pci_read_config(dev, 0xF2, 2); + if( pmccfg & 0x8 ) + printf("Could not enable Intel 801SMBus!\n"); + else + printf("Enabled Intel 801SMBus\n"); + } +} + /* extract header type specific config data */ static void @@ -2555,10 +2584,12 @@ * Add additional, quirked resources. */ for (q = &pci_quirks[0]; q->devid; q++) { - if (q->devid == ((cfg->device << 16) | cfg->vendor) - && q->type == PCI_QUIRK_MAP_REG) - pci_add_map(pcib, bus, dev, b, s, f, q->arg1, rl, - force, 0); + if (q->devid == ((cfg->device << 16) | cfg->vendor) ){ + if( q->type == PCI_QUIRK_MAP_REG ) + pci_add_map(pcib, bus, dev, b, s, f, q->arg1, rl, force, 0); + else if( q->type == PCI_QUIRK_FIXUP_ROUTINE ) + q->fixup_func(dev); + } } if (cfg->intpin > 0 && PCI_INTERRUPT_VALID(cfg->intline)) { >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200910190456.n9J4ujqt078519>