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:
parent
e4268c5913
commit
3a1b3a3fa7
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=49220
@ -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; \
|
||||
|
Loading…
Reference in New Issue
Block a user