Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci The ServerWorks CSB5 smbus controller often time...
details: https://anonhg.NetBSD.org/src/rev/f423c31ab419
branches: trunk
changeset: 762021:f423c31ab419
user: hannken <hannken%NetBSD.org@localhost>
date: Sun Feb 13 11:20:12 2011 +0000
description:
The ServerWorks CSB5 smbus controller often times out and hangs until reboot.
Increase the delay between setting the command register and reading the
status register. Reset the smbus controller if it has timed out.
Tested on an IBM eServer x335.
diffstat:
sys/dev/pci/piixpm.c | 41 ++++++++++++++++++++++++++++++++++++++---
sys/dev/pci/piixpmreg.h | 3 ++-
2 files changed, 40 insertions(+), 4 deletions(-)
diffs (121 lines):
diff -r 4a77220006f4 -r f423c31ab419 sys/dev/pci/piixpm.c
--- a/sys/dev/pci/piixpm.c Sun Feb 13 11:00:58 2011 +0000
+++ b/sys/dev/pci/piixpm.c Sun Feb 13 11:20:12 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: piixpm.c,v 1.34 2011/02/10 13:52:36 hannken Exp $ */
+/* $NetBSD: piixpm.c,v 1.35 2011/02/13 11:20:12 hannken Exp $ */
/* $OpenBSD: piixpm.c,v 1.20 2006/02/27 08:25:02 grange Exp $ */
/*
@@ -22,7 +22,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: piixpm.c,v 1.34 2011/02/10 13:52:36 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: piixpm.c,v 1.35 2011/02/13 11:20:12 hannken Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -49,6 +49,9 @@
#define DPRINTF(x)
#endif
+#define PIIXPM_IS_CSB5(id) \
+ (PCI_VENDOR((id)) == PCI_VENDOR_SERVERWORKS && \
+ PCI_PRODUCT((id)) == PCI_PRODUCT_SERVERWORKS_CSB5)
#define PIIXPM_DELAY 200
#define PIIXPM_TIMEOUT 1
@@ -65,6 +68,7 @@
pci_chipset_tag_t sc_pc;
pcitag_t sc_pcitag;
+ pcireg_t sc_id;
struct i2c_controller sc_i2c_tag;
krwlock_t sc_i2c_rwlock;
@@ -85,6 +89,7 @@
static bool piixpm_suspend(device_t, const pmf_qual_t *);
static bool piixpm_resume(device_t, const pmf_qual_t *);
+static void piixpm_csb5_reset(void *);
static int piixpm_i2c_acquire_bus(void *, int);
static void piixpm_i2c_release_bus(void *, int);
static int piixpm_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *,
@@ -144,6 +149,7 @@
const char *intrstr = NULL;
sc->sc_dev = self;
+ sc->sc_id = pa->pa_id;
sc->sc_pc = pa->pa_pc;
sc->sc_pcitag = pa->pa_tag;
@@ -266,6 +272,27 @@
return true;
}
+static void
+piixpm_csb5_reset(void *arg)
+{
+ struct piixpm_softc *sc = arg;
+ pcireg_t base, hostc, pmbase;
+
+ base = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PIIX_SMB_BASE);
+ hostc = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PIIX_SMB_HOSTC);
+
+ pmbase = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PIIX_PM_BASE);
+ pmbase |= PIIX_PM_BASE_CSB5_RESET;
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, PIIX_PM_BASE, pmbase);
+ pmbase &= ~PIIX_PM_BASE_CSB5_RESET;
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, PIIX_PM_BASE, pmbase);
+
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, PIIX_SMB_BASE, base);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, PIIX_SMB_HOSTC, hostc);
+
+ (void) tsleep(&sc, PRIBIO, "csb5reset", hz/2);
+}
+
static int
piixpm_i2c_acquire_bus(void *cookie, int flags)
{
@@ -372,7 +399,10 @@
if (flags & I2C_F_POLL) {
/* Poll for completion */
- DELAY(PIIXPM_DELAY);
+ if (PIIXPM_IS_CSB5(sc->sc_id))
+ DELAY(2*PIIXPM_DELAY);
+ else
+ DELAY(PIIXPM_DELAY);
for (retries = 1000; retries > 0; retries--) {
st = bus_space_read_1(sc->sc_smb_iot, sc->sc_smb_ioh,
PIIX_SMB_HS);
@@ -406,6 +436,11 @@
if ((st & PIIX_SMB_HS_FAILED) == 0)
aprint_error_dev(sc->sc_dev, "transaction abort failed, status 0x%x\n", st);
bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_HS, st);
+ /*
+ * CSB5 needs hard reset to unlock the smbus after timeout.
+ */
+ if (PIIXPM_IS_CSB5(sc->sc_id))
+ piixpm_csb5_reset(sc);
return (1);
}
diff -r 4a77220006f4 -r f423c31ab419 sys/dev/pci/piixpmreg.h
--- a/sys/dev/pci/piixpmreg.h Sun Feb 13 11:00:58 2011 +0000
+++ b/sys/dev/pci/piixpmreg.h Sun Feb 13 11:20:12 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: piixpmreg.h,v 1.4 2006/06/26 17:33:40 drochner Exp $ */
+/* $NetBSD: piixpmreg.h,v 1.5 2011/02/13 11:20:12 hannken Exp $ */
/* $OpenBSD: piixreg.h,v 1.3 2006/01/03 22:39:03 grange Exp $ */
/*
@@ -30,6 +30,7 @@
/* PCI configuration registers */
#define PIIX_PM_BASE 0x40 /* Power management base address */
+#define PIIX_PM_BASE_CSB5_RESET 0x10 /* CSB5 PM reset */
#define PIIX_DEVACTA 0x54 /* Device activity A (function 3) */
#define PIIX_DEVACTB 0x58 /* Device activity B (function 3) */
#define PIIX_PMREGMISC 0x80 /* Misc. Power management */
Home |
Main Index |
Thread Index |
Old Index