Date: Sat, 21 Aug 2004 18:43:17 -0700 (PDT) From: Dennis Holmes <dholmes@email.rahul.net> To: FreeBSD-gnats-submit@FreeBSD.org Cc: dholmes@liberator.dyndns.org Subject: i386/70810: [patch] Enable SMBus device on Asus P4B series motherboards Message-ID: <200408220143.i7M1hHYI020239@star-one.liberator.dyndns.org> Resent-Message-ID: <200408220150.i7M1oMSA029947@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 70810 >Category: i386 >Synopsis: [patch] Enable SMBus device on Asus P4B series motherboards >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-i386 >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Sun Aug 22 01:50:22 GMT 2004 >Closed-Date: >Last-Modified: >Originator: Dennis Holmes >Release: FreeBSD 4.8-RELEASE-p13 i386 >Organization: a little >Environment: Asus P4B266 with Intel 845D chipset System: FreeBSD star-one.liberator.dyndns.org 4.8-RELEASE-p13 FreeBSD 4.8-RELEASE-p13 #14: Mon Aug 2 10:52:46 PDT 2004 dholmes at star-one.liberator.dyndns.org:/usr/obj/usr/src/sys/STAR-ONE i386 >Description: On affected Asus motherboards, the smbus device in the chipset is disabled by the BIOS with no setup option to enable it. This prevents hardware (temp/fan/voltage) monitoring since the monitoring chip is only accessible via smbus. Additional information regarding the nature of the problem and the fix can be found on the following web pages: http://www.nt.phys.kyushu-u.ac.jp/shimizu/download/README-ASUS-P4motherboard.html http://www2.lm-sensors.nu/~lm78/cvs/lm_sensors2/prog/hotplug/README.p4b Note that the Linux fix of enabling the smbus device after boot requires that hot-pluggable device support be present in the kernel. In Freebsd the device can be enabled while running by using pciconf or pcitweak, but the kernel remains unaware of it. >How-To-Repeat: Observe via dmesg that the ichsmb and smbus devices are not found at boot time even with the appropriate devices configured in the kernel. >Fix: The included patch turns on the smbus device as soon as the parent chip is probed. Then the device is detected as the device probing sequence continues. I now have healthd working on my system after applying the patch. This adds a new PCI quirk and a kernel config option to activate the quirk. Now in dmesg I see: ichsmb0: <Intel 82801BA (ICH2) SMBus controller> port 0xe800-0xe80f irq 0 at device 31.3 on pci0 pci_cfgintr_search: linked (61) to configured irq 11 at 1:0:0 pci_cfgintr: 0:31 INTB routed to irq 11 smbus1: <System Management Bus> on ichsmb0 smb1: <SMBus general purpose I/O> on smbus1 (It is assigned smbus1 since I also have a Bt848-based video capture card which gets smbus0. I also had to tweak healthd to get it to use smbus1 and correct some of the monitoring values. If anyone is interested in those changes, let me know; some of it's not very pretty but I'll share.) The patch changes three files. Prior to each diff is the CVS ID string of the file against which the patch was generated. I realize these versions are a little old, but I don't have an installation of -current to play with. I did check to see that the files have not changed substantially in newer releases. I am also including a diff against the pci.c file from -current. This version had changed enough that the patch from my version didn't apply. Also, it looks like the location or nature of LINT has changed in -current, so I don't know how to handle updating it. This is my first PR submission; if you have any advice (other than the obvious of "upgrade!") or need additional info please let me know. ########## # Version: $FreeBSD: src/sys/i386/conf/LINT,v 1.749.2.138.2.1 2003/03/28 20:05:39 scottl Exp $ ########## --- /usr/src/sys/i386/conf/LINT.dist Fri Mar 28 12:05:39 2003 +++ /usr/src/sys/i386/conf/LINT Thu Aug 5 10:50:24 2004 @@ -2153,6 +2153,15 @@ device amdpm device smb + +# Some of the ASUS P-4 motherboard with ICH2(82801BA) and ICH4(82801DB) +# chipsets switch off the SMBus PCI device in the BIOS. Therefore, one +# has to enable it explicitly in order to make hardware-monitoring possible. +# For further details, see: +# http://www.nt.phys.kyushu-u.ac.jp/shimizu/download/README-ASUS-P4motherboard.html +# http://www2.lm-sensors.nu/~lm78/cvs/lm_sensors2/prog/hotplug/README.p4b + +options ASUS_P4B # Enable SMBus on Asus P4B series # # I2C Bus ########## # Version: $FreeBSD: src/sys/conf/options.i386,v 1.132.2.18 2003/03/14 21:22:35 jhb Exp $ ########## --- /usr/src/sys/conf/options.i386.dist Fri Mar 14 13:22:35 2003 +++ /usr/src/sys/conf/options.i386 Thu Jul 29 19:57:11 2004 @@ -214,6 +214,9 @@ # SMB/CIFS filesystem SMBFS +# Enable smbus device on Asus P4B +ASUS_P4B opt_pci.h + # ------------------------------- # EOF # ------------------------------- ########## # Version: $FreeBSD: src/sys/pci/pci.c,v 1.141.2.15 2002/04/30 17:48:18 tmm Exp $ ########## --- /usr/src/sys/pci/pci.c.dist Tue Apr 30 10:48:18 2002 +++ /usr/src/sys/pci/pci.c Mon Aug 2 10:50:31 2004 @@ -71,22 +71,26 @@ static void pci_read_extcap(pcicfgregs *cfg); struct pci_quirk { u_int32_t devid; /* Vendor/device of the card */ int type; #define PCI_QUIRK_MAP_REG 1 /* PCI map register in wierd place */ +#define PCI_QUIRK_CLEAR_BITS 2 /* Enable function by clearing some bits */ int arg1; int arg2; }; 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 }, +#ifdef ASUS_P4B + { 0x24408086, PCI_QUIRK_CLEAR_BITS, 0xf2, 0x0108 }, +#endif { 0 } }; /* map register information */ #define PCI_MAPMEM 0x01 /* memory map */ @@ -1356,21 +1360,33 @@ pci_add_resources(device_t dev, pcicfgregs* cfg) { struct pci_devinfo *dinfo = device_get_ivars(dev); struct resource_list *rl = &dinfo->resources; struct pci_quirk *q; int i; + u_int32_t val; for (i = 0; i < cfg->nummaps;) { i += pci_add_map(dev, cfg, PCIR_MAPS + i*4); } 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(dev, cfg, q->arg1); + if (q->devid == ((cfg->device << 16) | cfg->vendor)) { + switch (q->type) { + case PCI_QUIRK_MAP_REG: + pci_add_map(dev, cfg, q->arg1); + break; + case PCI_QUIRK_CLEAR_BITS: + val = pci_read_config(dev, q->arg1, 2); + if (val & q->arg2) { + val &= ~(q->arg2); + pci_write_config(dev, q->arg1, val, 2); + } + break; + } + } } if (cfg->intpin > 0 && cfg->intline != 255) resource_list_add(rl, SYS_RES_IRQ, 0, cfg->intline, cfg->intline, 1); } ########## # src/sys/dev/pci/pci.c from -current NOTE THAT THIS IS NOT TESTED! # Version: $FreeBSD: /repoman/r/ncvs/src/sys/dev/pci/pci.c,v 1.264 2004/07/02 13:42:36 imp Exp $ ########## --- pci.c.current Fri Jul 2 06:42:36 2004 +++ pci.c Thu Aug 5 13:01:36 2004 @@ -139,22 +139,26 @@ struct pci_quirk { uint32_t devid; /* Vendor/device of the card */ int type; #define PCI_QUIRK_MAP_REG 1 /* PCI map register in weird place */ +#define PCI_QUIRK_CLEAR_BITS 2 /* Enable function by clearing some bits */ int arg1; int arg2; }; 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 }, /* As does the Serverworks OSB4 (the SMBus mapping register) */ { 0x02001166, PCI_QUIRK_MAP_REG, 0x90, 0 }, +#ifdef ASUS_P4B + { 0x24408086, PCI_QUIRK_CLEAR_BITS, 0xf2, 0x0108 }, +#endif { 0 } }; /* map register information */ #define PCI_MAPMEM 0x01 /* memory map */ @@ -894,12 +898,13 @@ { struct pci_devinfo *dinfo = device_get_ivars(dev); pcicfgregs *cfg = &dinfo->cfg; struct resource_list *rl = &dinfo->resources; struct pci_quirk *q; int b, i, irq, f, s; + u_int32_t val; b = cfg->bus; s = cfg->slot; f = cfg->func; /* ATA devices needs special map treatment */ @@ -910,15 +915,26 @@ else for (i = 0; i < cfg->nummaps;) i += pci_add_map(pcib, bus, dev, b, s, f, PCIR_BAR(i), rl); 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); + if (q->devid == ((cfg->device << 16) | cfg->vendor)) { + switch (q->type) { + case PCI_QUIRK_MAP_REG: + pci_add_map(pcib, bus, dev, b, s, f, q->arg1, rl); + break; + case PCI_QUIRK_CLEAR_BITS: + val = pci_read_config(dev, q->arg1, 2); + if (val & q->arg2) { + val &= ~(q->arg2); + pci_write_config(dev, q->arg1, val, 2); + } + break; + } + } } if (cfg->intpin > 0 && PCI_INTERRUPT_VALID(cfg->intline)) { #if defined(__ia64__) || defined(__i386__) || defined(__amd64__) /* * Try to re-route interrupts. Sometimes the BIOS or >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200408220143.i7M1hHYI020239>