From 81ae74c4eb56d6763f4554b9dd87603c00c788d5 Mon Sep 17 00:00:00 2001 From: drochner Date: Thu, 3 Jul 2008 13:37:34 +0000 Subject: [PATCH] On cardbus configuration reads, check for a master abort in the cbb and return all-ones explicitely. Since pccbb.c rev. 1.151 the cbb is set to translate cardbus master aborts which makes that the PCI configuration read on the primary bus returns random junk. This can cause the probing code to get confused. The issue was reported by KIYOHARA Takashi and Jonathan A. Kollasch, the patch was tested by KIYOHARA Takashi. --- sys/dev/pci/pccbb.c | 19 ++++++++++++++++--- sys/dev/pci/pccbbreg.h | 5 ++++- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/sys/dev/pci/pccbb.c b/sys/dev/pci/pccbb.c index 75090c6aedd9..e9a1590d9b64 100644 --- a/sys/dev/pci/pccbb.c +++ b/sys/dev/pci/pccbb.c @@ -1,4 +1,4 @@ -/* $NetBSD: pccbb.c,v 1.177 2008/06/26 20:57:10 drochner Exp $ */ +/* $NetBSD: pccbb.c,v 1.178 2008/07/03 13:37:34 drochner Exp $ */ /* * Copyright (c) 1998, 1999 and 2000 @@ -31,7 +31,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: pccbb.c,v 1.177 2008/06/26 20:57:10 drochner Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pccbb.c,v 1.178 2008/07/03 13:37:34 drochner Exp $"); /* #define CBB_DEBUG @@ -1893,8 +1893,21 @@ static cardbusreg_t pccbb_conf_read(cardbus_chipset_tag_t cc, cardbustag_t tag, int offset) { struct pccbb_softc *sc = (struct pccbb_softc *)cc; + pcitag_t brtag = sc->sc_tag; + cardbusreg_t reg; - return pci_conf_read(sc->sc_pc, tag, offset); + /* + * clear cardbus master abort status; it is OK to write without + * reading before because all bits are r/o or w1tc + */ + pci_conf_write(sc->sc_pc, brtag, PCI_CBB_SECSTATUS, + CBB_SECSTATUS_CBMABORT); + reg = pci_conf_read(sc->sc_pc, tag, offset); + /* check cardbus master abort status */ + if (pci_conf_read(sc->sc_pc, brtag, PCI_CBB_SECSTATUS) + & CBB_SECSTATUS_CBMABORT) + return (0xffffffff); + return reg; } /* diff --git a/sys/dev/pci/pccbbreg.h b/sys/dev/pci/pccbbreg.h index d4dc215b35f1..8a973cb582d3 100644 --- a/sys/dev/pci/pccbbreg.h +++ b/sys/dev/pci/pccbbreg.h @@ -1,4 +1,4 @@ -/* $NetBSD: pccbbreg.h,v 1.13 2007/11/16 18:36:52 dyoung Exp $ */ +/* $NetBSD: pccbbreg.h,v 1.14 2008/07/03 13:37:35 drochner Exp $ */ /* * Copyright (c) 1999 HAYAKAWA Koichi. All rights reserved. * @@ -36,6 +36,7 @@ #define PCI_SOCKBASE 0x10 /* Socket Base Address Register */ +#define PCI_CBB_SECSTATUS 0x14 /* secondary status (starts at 0x16) */ #define PCI_BUSNUM 0x18 /* latency timer, Subordinate bus number */ #define PCI_LEGACY 0x44 /* legacy IO register address (32 bits) */ #define PCI_SYSCTRL 0x80 /* System control */ @@ -44,6 +45,8 @@ #define PCI_CLASS_INTERFACE_MASK 0xffffff00 #define PCI_CLASS_INTERFACE_YENTA 0x06070000 +#define CBB_SECSTATUS_CBMABORT 0x20000000 + #define CB_SOCKET_EVENT 0x00 /* offset of cardbus socket event reg */ #define CB_SOCKET_MASK 0x04 /* offset of cardbus socket mask register */ #define CB_SOCKET_STAT 0x08 /* offset of cardbus socket present-state */