1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-15 10:17:20 +00:00

On an AS 600 5/266 (and possibly others), accessing the configuration

space of PCI devices that don't exist cause PCI master & target aborts
rather than returning ~0 or giving a machine check.  Bring in some code
from NetBSD to handle this properly.

obtained from:	NetBSD
reviewed by:	dfr
This commit is contained in:
Andrew Gallatin 1999-07-29 16:44:22 +00:00
parent e4268c5913
commit 3a1b3a3fa7
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=49220

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: cia.c,v 1.19 1999/06/05 13:30:13 dfr Exp $
* $Id: cia.c,v 1.20 1999/07/01 20:25:39 peter Exp $
*/
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -557,19 +557,42 @@ cia_swiz_maxdevs(u_int b)
} while(0); \
}
/*
* From NetBSD:
* Some (apparently-common) revisions of EB164 and AlphaStation
* firmware do the Wrong thing with PCI master and target aborts,
* which are caused by accesing the configuration space of devices
* that don't exist (for example).
*
* To work around this, we clear the CIA error register's PCI
* master and target abort bits before touching PCI configuration
* space and check it afterwards. If it indicates a master or target
* abort, the device wasn't there so we return ~0
*/
#define SWIZ_CFGREAD(b, s, f, r, width, type) \
type val = ~0; \
int ipl = 0; \
u_int32_t old_cfg = 0; \
u_int32_t old_cfg = 0, errbits; \
vm_offset_t off = CIA_SWIZ_CFGOFF(b, s, f, r); \
vm_offset_t kv = SPARSE_##width##_ADDRESS(KV(CIA_PCI_CONF), off); \
REGVAL(CIA_CSR_CIA_ERR) = CIA_ERR_RCVD_MAS_ABT|CIA_ERR_RCVD_TAR_ABT;\
alpha_mb(); \
CIA_TYPE1_SETUP(b,ipl,old_cfg); \
if (!badaddr((caddr_t)kv, sizeof(type))) { \
val = SPARSE_##width##_EXTRACT(off, SPARSE_READ(kv)); \
} \
CIA_TYPE1_TEARDOWN(b,ipl,old_cfg); \
return val;
errbits = REGVAL(CIA_CSR_CIA_ERR); \
if (errbits & (CIA_ERR_RCVD_MAS_ABT|CIA_ERR_RCVD_TAR_ABT)) \
val = ~0; \
if (errbits) { \
REGVAL(CIA_CSR_CIA_ERR) = errbits; \
alpha_mb(); \
alpha_pal_draina(); \
} \
return val;
#define SWIZ_CFGWRITE(b, s, f, r, data, width, type) \
int ipl = 0; \