Module Name:    src
Committed By:   cliff
Date:           Fri Jan 29 00:23:54 UTC 2010

Modified Files:
        src/sys/arch/mips/rmi [matt-nb5-mips64]: rmixl_pcie.c

Log Message:
- rmixl_cache_err_dis, rmixl_cache_err_restore, rmixl_cache_err_check
  inlines moved from here ro rmixlvar.h
- add a layer of interrupt dispatch to allow sharing link interrupts,
- enable and handle pcie link error interrupts
- initialize the PCIe INT and MSI config regs, make sure MSI ints are disabled!
- improve display names for link configurations
- be more thorough about 'mips_cpu_id' based variations


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.7 -r1.1.2.8 src/sys/arch/mips/rmi/rmixl_pcie.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/mips/rmi/rmixl_pcie.c
diff -u src/sys/arch/mips/rmi/rmixl_pcie.c:1.1.2.7 src/sys/arch/mips/rmi/rmixl_pcie.c:1.1.2.8
--- src/sys/arch/mips/rmi/rmixl_pcie.c:1.1.2.7	Wed Jan 20 09:04:35 2010
+++ src/sys/arch/mips/rmi/rmixl_pcie.c	Fri Jan 29 00:23:54 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: rmixl_pcie.c,v 1.1.2.7 2010/01/20 09:04:35 matt Exp $	*/
+/*	$NetBSD: rmixl_pcie.c,v 1.1.2.8 2010/01/29 00:23:54 cliff Exp $	*/
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -40,7 +40,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rmixl_pcie.c,v 1.1.2.7 2010/01/20 09:04:35 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rmixl_pcie.c,v 1.1.2.8 2010/01/29 00:23:54 cliff Exp $");
 
 #include "opt_pci.h"
 #include "pci.h"
@@ -125,6 +125,38 @@
 #define PCIE_ECFG_ERRS_OFFTAB_NENTRIES \
 	(sizeof(pcie_ecfg_errs_tab)/sizeof(pcie_ecfg_errs_tab[0]))
 
+typedef struct rmixl_pcie_int_csr {
+	uint r0;
+	uint r1;
+} rmixl_pcie_int_csr_t;
+
+static const rmixl_pcie_int_csr_t int_enb_offset[4] = {
+	{ RMIXL_PCIE_LINK0_INT_ENABLE0, RMIXL_PCIE_LINK0_INT_ENABLE1 },
+	{ RMIXL_PCIE_LINK1_INT_ENABLE0, RMIXL_PCIE_LINK1_INT_ENABLE1 },
+	{ RMIXL_PCIE_LINK2_INT_ENABLE0, RMIXL_PCIE_LINK2_INT_ENABLE1 },
+	{ RMIXL_PCIE_LINK3_INT_ENABLE0, RMIXL_PCIE_LINK3_INT_ENABLE1 },
+};
+
+static const rmixl_pcie_int_csr_t int_sts_offset[4] = {
+	{ RMIXL_PCIE_LINK0_INT_STATUS0, RMIXL_PCIE_LINK0_INT_STATUS1 },
+	{ RMIXL_PCIE_LINK1_INT_STATUS0, RMIXL_PCIE_LINK1_INT_STATUS1 },
+	{ RMIXL_PCIE_LINK2_INT_STATUS0, RMIXL_PCIE_LINK2_INT_STATUS1 },
+	{ RMIXL_PCIE_LINK3_INT_STATUS0, RMIXL_PCIE_LINK3_INT_STATUS1 },
+};
+
+static const u_int msi_enb_offset[4] = {
+	RMIXL_PCIE_LINK0_MSI_ENABLE,
+	RMIXL_PCIE_LINK1_MSI_ENABLE,
+	RMIXL_PCIE_LINK2_MSI_ENABLE,
+	RMIXL_PCIE_LINK3_MSI_ENABLE
+};
+
+#define RMIXL_PCIE_LINK_STATUS0_ERRORS	__BITS(6,4)
+#define RMIXL_PCIE_LINK_STATUS1_ERRORS	__BITS(10,0)
+#define RMIXL_PCIE_LINK_STATUS_ERRORS					\
+		((((uint64_t)RMIXL_PCIE_LINK_STATUS1_ERRORS) << 32) |	\
+		   (uint64_t)RMIXL_PCIE_LINK_STATUS0_ERRORS)
+
 static int	rmixl_pcie_match(device_t, cfdata_t, void *);
 static void	rmixl_pcie_attach(device_t, device_t, void *);
 static void	rmixl_pcie_init(struct rmixl_pcie_softc *);
@@ -136,6 +168,7 @@
 static void	rmixl_pcie_lnkcfg_2xx(rmixl_pcie_lnktab_t *, uint32_t);
 static void	rmixl_pcie_lnkcfg_1xx(rmixl_pcie_lnktab_t *, uint32_t);
 static void	rmixl_pcie_lnkcfg(struct rmixl_pcie_softc *);
+static void	rmixl_pcie_intcfg(struct rmixl_pcie_softc *);
 static void	rmixl_pcie_errata(struct rmixl_pcie_softc *);
 static void	rmixl_conf_interrupt(void *, int, int, int, int, int *);
 static int	rmixl_pcie_bus_maxdevs(void *, int);
@@ -155,9 +188,14 @@
 		rmixl_pcie_intr_string(void *, pci_intr_handle_t);
 static const struct evcnt *
 		rmixl_pcie_intr_evcnt(void *, pci_intr_handle_t);
+static pci_intr_handle_t
+		rmixl_pcie_make_pih(u_int, u_int, u_int);
+static void	rmixl_pcie_decompose_pih(pci_intr_handle_t, u_int *, u_int *, u_int *);
+static void	rmixl_pcie_intr_disestablish(void *, void *);
 static void	*rmixl_pcie_intr_establish(void *, pci_intr_handle_t,
 		    int, int (*)(void *), void *);
-static void	rmixl_pcie_intr_disestablish(void *, void *);
+static int	rmixl_pcie_intr(void *);
+static void	rmixl_pcie_link_error_intr(u_int, uint32_t, uint32_t);
 #if defined(DEBUG) || defined(DDB)
 int		rmixl_pcie_error_check(void);
 #endif
@@ -207,44 +245,6 @@
 
 static int rmixl_pcie_found;
 
-/*
- * rmixl_cache_err_dis:
- * - disable Cache, Data ECC, Snoop Tag Parity, Tag Parity errors
- * - clear the cache error log
- * - return previous value from RMIXL_PCR_L1D_CONFIG0
- */
-static inline uint64_t
-rmixl_cache_err_dis(void)
-{
-	uint64_t r;
-
-	r = rmixl_mfcr(RMIXL_PCR_L1D_CONFIG0);
-	rmixl_mtcr(RMIXL_PCR_L1D_CONFIG0, r & ~0x2e);
-	rmixl_mtcr(RMIXL_PCR_L1D_CACHE_ERROR_LOG, 0);
-	return r;
-}
-
-/*
- * rmixl_cache_err_restore:
- * - clear the cache error log, cache error overflow log,
- *   and cache interrupt registers
- * - restore previous value to RMIXL_PCR_L1D_CONFIG0
- */
-static inline void
-rmixl_cache_err_restore(uint64_t r)
-{
-	rmixl_mtcr(RMIXL_PCR_L1D_CACHE_ERROR_LOG, 0);
-	rmixl_mtcr(RMIXL_PCR_L1D_CACHE_ERROR_OVF_LO, 0);
-	rmixl_mtcr(RMIXL_PCR_L1D_CACHE_INTERRUPT, 0);
-	rmixl_mtcr(RMIXL_PCR_L1D_CONFIG0, r);
-}
-
-static inline uint64_t
-rmixl_cache_err_check(void)
-{
-	return rmixl_mfcr(RMIXL_PCR_L1D_CACHE_ERROR_LOG);
-}
-
 static int  
 rmixl_pcie_match(device_t parent, cfdata_t cf, void *aux)
 {        
@@ -258,7 +258,6 @@
 		return 0;
 
 	/* read GPIO Reset Configuration register */
-	/* XXX FIXME define the offset */
 	r = RMIXL_IOREG_READ(RMIXL_IO_DEV_GPIO + RMIXL_GPIO_RESET_CFG);
 	r >>= 26;
 	r &= 3;
@@ -284,6 +283,8 @@
 
 	rmixl_pcie_lnkcfg(sc);
 
+	rmixl_pcie_intcfg(sc);
+
 	rmixl_pcie_errata(sc);
 
 	sc->sc_29bit_dmat = obio->obio_29bit_dmat;
@@ -402,10 +403,10 @@
 		{{ LCFG_RC, 1}, {LCFG_RC, 1}, {LCFG_RC, 1}, {LCFG_RC, 1}},
 	};
 	static const char *lnkstr_4xx[4] = {
-		"EP 1x4",
-		"RC 1x4",
-		"EP 1x1, RC 4x1",
-		"RC 4x1"
+		"1EPx4",
+		"1RCx4",
+		"1EPx1, 3RCx1",
+		"4RCx1"
 	};
 	index = (grcr >> 20) & 3;
 	ltp->ncfgs = 4;
@@ -429,10 +430,10 @@
 		{{ LCFG_RC, 1}, {LCFG_RC, 1}},
 	};
 	static const char *lnkstr_408Lite[4] = {
-		"EP 1x4",
-		"RC 1x4",
-		"EP 1x1, RC 1x1",
-		"RC 2x1"
+		"4EPx4",
+		"1RCx4",
+		"1EPx1, 1RCx1",
+		"2RCx1"
 	};
 
 	index = (grcr >> 20) & 3;
@@ -455,8 +456,8 @@
 		{{ LCFG_RC, 1}, {LCFG_RC, 1}, {LCFG_RC, 1}, {LCFG_RC, 1}}
 	};
 	static const char *lnkstr_2xx[2] = {
-		"EP 1x1, RC 3x1",
-		"RC 4x1",
+		"1EPx1, 3RCx1",
+		"4RCx1",
 	};
 
 	index = (grcr >> 20) & 1;
@@ -479,8 +480,8 @@
 		{{ LCFG_RC, 1}, {LCFG_RC, 1}}
 	};
 	static const char *lnkstr_1xx[2] = {
-		"EP 1x1, RC 1x1",
-		"RC 2x1",
+		"1EPx1, 1RCx1",
+		"2RCx1",
 	};
 
 	index = (grcr >> 20) & 1;
@@ -530,6 +531,30 @@
 		device_xname(sc->sc_dev), sc->sc_pcie_lnktab.str);
 }
 
+/*
+ * rmixl_pcie_intcfg - init PCIe Link interrupt enables
+ */
+static void
+rmixl_pcie_intcfg(struct rmixl_pcie_softc *sc)
+{
+	rmixl_pcie_link_intr_t *lip;
+	int link;
+
+	DPRINTF(("%s: disable all link interrupts\n", __func__));
+	for (link=0; link < sc->sc_pcie_lnktab.ncfgs; link++) {
+		RMIXL_IOREG_WRITE(RMIXL_IO_DEV_PCIE_LE + int_enb_offset[link].r0,
+			RMIXL_PCIE_LINK_STATUS0_ERRORS); 
+		RMIXL_IOREG_WRITE(RMIXL_IO_DEV_PCIE_LE + int_enb_offset[link].r1,
+			RMIXL_PCIE_LINK_STATUS1_ERRORS); 
+		RMIXL_IOREG_WRITE(RMIXL_IO_DEV_PCIE_LE + msi_enb_offset[link], 0); 
+		lip = &sc->sc_link_intr[link];
+		LIST_INIT(&lip->dispatch);
+		lip->ih = NULL;
+		lip->link = link;
+		lip->enabled = false;
+	}
+}
+
 static void
 rmixl_pcie_errata(struct rmixl_pcie_softc *sc)
 {
@@ -735,17 +760,24 @@
 	r = (pcireg_t)(~PCIE_ECFG_RECR_RESV);
 	rmixl_pcie_conf_write(v, tag, RMIXL_PCIE_ECFG_RECR, r);
 
-
-	if (MIPS_PRID_IMPL(mips_options.mips_cpu_id) == MIPS_XLS408LITE) {
-		/*
-		 * establish ISR for PCIE Fatal Error interrupt
-		 * XXX for XLS408Lite, XLS2xx, XLS1xx only
-		 *     tested on XLS408Lite only
-		 */
-		(void)rmixl_intr_establish(29, IPL_HIGH,
-			RMIXL_INTR_LEVEL, RMIXL_INTR_HIGH,
-			rmixl_pcie_error_intr, v);
+	/*
+	 * establish ISR for PCIE Fatal Error interrupt
+	 * - for XLS4xxLite, XLS2xx, XLS1xx only
+	 */
+	switch (MIPS_PRID_IMPL(mips_options.mips_cpu_id)) {
+	case MIPS_XLS104:
+	case MIPS_XLS108:
+	case MIPS_XLS204:
+	case MIPS_XLS208:
+	case MIPS_XLS404LITE:
+	case MIPS_XLS408LITE:
+		sc->sc_fatal_ih = rmixl_intr_establish(29, IPL_HIGH, RMIXL_INTR_LEVEL,
+			RMIXL_INTR_HIGH, rmixl_pcie_error_intr, v);
+		break;
+	default:
+		break;
 	}
+
 #if defined(DEBUG) || defined(DDB)
 	rmixl_pcie_v = v;
 #endif
@@ -972,6 +1004,7 @@
 int
 rmixl_pcie_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *pih)
 {
+	u_int link;
 	u_int irq;
 
 #ifdef DEBUG
@@ -982,34 +1015,48 @@
 #endif
 
 	/*
-	 * XXX cpu implementation specific
+	 * PCIe Link INT irq assignment is cpu implementation specific
 	 */
 	switch (MIPS_PRID_IMPL(mips_options.mips_cpu_id)) {
+	case MIPS_XLS104:
+	case MIPS_XLS108:
+	case MIPS_XLS204:
+	case MIPS_XLS208:
+	case MIPS_XLS404LITE:
 	case MIPS_XLS408LITE:
 		switch (pa->pa_bus) {
 		case 1:
+			link = 0;
 			irq = 26;
 			break;
 		case 2:
+			link = 1;
 			irq = 27;
 			break;
 		default:
 			panic("%s: bad bus %d\n", __func__, pa->pa_bus);
 		}
 		break;
+	case MIPS_XLS404:
+	case MIPS_XLS408:
 	case MIPS_XLS416:
+	case MIPS_XLS608: 
 	case MIPS_XLS616:
 		switch (pa->pa_bus) {
 		case 1:
+			link = 0;
 			irq = 26;
 			break;
 		case 2:
+			link = 1;
 			irq = 27;
 			break;
 		case 3:
+			link = 2;
 			irq = 28;
 			break;
 		case 4:
+			link = 3;
 			irq = 29;
 			break;
 		default:
@@ -1021,7 +1068,10 @@
 			__func__, MIPS_PRID_IMPL(mips_options.mips_cpu_id));
 	}
 
-	*pih = irq;
+	if (pa->pa_intrpin != PCI_INTERRUPT_PIN_NONE)
+		*pih = rmixl_pcie_make_pih(link, pa->pa_intrpin - 1, irq);
+	else
+		*pih = ~0;
 
 	return 0;
 }
@@ -1033,6 +1083,11 @@
 	int irq = (int)pih;
 
 	switch (MIPS_PRID_IMPL(mips_options.mips_cpu_id)) {
+	case MIPS_XLS104:
+	case MIPS_XLS108:
+	case MIPS_XLS204:
+	case MIPS_XLS208:
+	case MIPS_XLS404LITE:
 	case MIPS_XLS408LITE:
 		switch (irq) {
 		case 26:
@@ -1041,6 +1096,10 @@
 			break;
 		}
 		break;
+	case MIPS_XLS404:
+	case MIPS_XLS408:
+	case MIPS_XLS416:
+	case MIPS_XLS608: 
 	case MIPS_XLS616:
 		switch (irq) {
 		case 26:
@@ -1051,6 +1110,9 @@
 			break;
 		}
 		break;
+	default:
+		panic("%s: cpu IMPL %#x not supported\n",
+			__func__, MIPS_PRID_IMPL(mips_options.mips_cpu_id));
 	}
 
 	return name;
@@ -1062,17 +1124,44 @@
 	return NULL;
 }
 
-static int
-rmixl_pcie_irq(pci_intr_handle_t pih)
+static pci_intr_handle_t
+rmixl_pcie_make_pih(u_int link, u_int bitno, u_int irq)
 {
-	return (int)pih;
+	pci_intr_handle_t pih;
+
+	KASSERT((link >= 0) && (link < RMIXL_PCIE_NLINKS_MAX));
+	KASSERT((bitno >= 0) && (bitno < 64));
+	KASSERT((irq >= 0) && (irq < 31));
+
+	pih  = (irq << 10);
+	pih |= (bitno << 4);
+	pih |= link;
+
+	return pih;
 }
 
+static void
+rmixl_pcie_decompose_pih(pci_intr_handle_t pih, u_int *link, u_int *bitno, u_int *irq)
+{
+	*link = (u_int)(pih & 0xf);
+	*bitno  = (u_int)((pih >> 4) & 0x3f);
+	*irq  = (u_int)(pih >> 10);
+
+	KASSERT((*link >= 0) && (*link < RMIXL_PCIE_NLINKS_MAX));
+	KASSERT((*bitno >= 0) && (*bitno < 64));
+	KASSERT((*irq >= 0) && (*irq < 31));
+}
+
+#if 0
+
 static void *
 rmixl_pcie_intr_establish(void *v, pci_intr_handle_t pih, int ipl,
 	int (*func)(void *), void *arg)
 {
-	return rmixl_intr_establish(rmixl_pcie_irq((int)pih), ipl,
+	u_int link, bitno, irq;
+
+	rmixl_pcie_decompose_pih(pih, &link, &bitno, &irq);
+	return rmixl_intr_establish(irq, ipl,
 		RMIXL_INTR_LEVEL, RMIXL_INTR_HIGH, func, arg);
 }
 
@@ -1082,6 +1171,202 @@
 	rmixl_intr_disestablish(ih);
 }
 
+#else	/* 0 */
+
+static void
+rmixl_pcie_intr_disestablish(void *v, void *ih)
+{
+	rmixl_pcie_softc_t *sc = v;
+	rmixl_pcie_link_dispatch_t *dip = ih;
+	rmixl_pcie_link_intr_t *lip = &sc->sc_link_intr[dip->link];;
+	uint32_t r;
+	uint32_t bit;
+	u_int offset;
+	u_int other;
+
+	DPRINTF(("%s: link=%d bitno=%d irq=%d\n", __func__, dip->link, dip->bitno, dip->irq));
+	LIST_REMOVE(dip, next);
+
+	rmixl_intr_disestablish(lip->ih);
+
+	if (dip->bitno < 32) {
+		bit = 1 << dip->bitno;
+		offset = int_enb_offset[dip->link].r0;
+		other  = int_enb_offset[dip->link].r1;
+	} else {
+		bit = 1 << (dip->bitno - 32);
+		offset = int_enb_offset[dip->link].r1;
+		other  = int_enb_offset[dip->link].r1;
+	}
+
+	/* disable this interrupt in the PCIe bridge */
+	r = RMIXL_IOREG_READ(RMIXL_IO_DEV_PCIE_LE + offset);
+	r &= ~bit;
+	RMIXL_IOREG_WRITE(RMIXL_IO_DEV_PCIE_LE + offset, r);
+
+	/*
+	 * if both STATUS0 and STATUS1 are 0
+	 * mark the link interrupt disabled
+	 */
+	if (r == 0) {
+		/* check the other reg */
+		if (RMIXL_IOREG_READ(RMIXL_IO_DEV_PCIE_LE + other) == 0) {
+			lip->enabled = false;
+			DPRINTF(("%s: disabled link %d\n", __func__, lip->link));
+		}
+	}
+
+	evcnt_detach(&dip->count);
+
+	free(dip, M_DEVBUF);
+
+}
+
+static void *
+rmixl_pcie_intr_establish(void *v, pci_intr_handle_t pih, int ipl,
+        int (*func)(void *), void *arg)
+{
+	rmixl_pcie_softc_t *sc = v;
+	u_int link, bitno, irq;
+	uint32_t r;
+	rmixl_pcie_link_intr_t *lip;
+	rmixl_pcie_link_dispatch_t *dip;
+	uint32_t bit;
+	u_int offset;
+	int s;
+	char strbuf[32];
+
+	if (pih == ~0) {
+		DPRINTF(("%s: bad pih=%#lx, implies PCI_INTERRUPT_PIN_NONE\n",
+			__func__, pih));
+		return NULL;
+	}
+
+	rmixl_pcie_decompose_pih(pih, &link, &bitno, &irq);
+	DPRINTF(("%s: link=%d bitno=%d irq=%d\n", __func__, link, bitno, irq));
+
+	lip = &sc->sc_link_intr[link];
+
+	s = splhigh();
+
+#ifdef DEBUG
+	LIST_FOREACH(dip, &lip->dispatch, next) {
+		if (dip->bitno == bitno)
+			panic("%s: bitno %d alread on dispatch list", __func__, bitno);
+	}
+#endif
+
+	/*
+	 * all intrs on a link get same ipl and sc
+	 * first intr established sets the standard
+	 */
+	if (lip->enabled == true) {
+		KASSERT(sc = lip->sc);
+		if (sc != lip->sc) {
+			printf("%s: sc %p mismatch\n", __func__, sc); 
+			goto out;
+		}
+		KASSERT(ipl = lip->ipl);
+		if (ipl != lip->ipl) {
+			printf("%s: ipl %d mismatch\n", __func__, ipl); 
+			goto out;
+		}
+	}
+
+	/*
+	 * allocate and initialize a dispatch handle
+	 */
+	dip = malloc(sizeof(*dip), M_DEVBUF, M_NOWAIT);
+	if (dip == NULL) {
+		printf("%s: cannot malloc dispatch handle\n", __func__);
+		goto out;
+	}
+
+	dip->link = link;
+	dip->bitno = bitno;
+	dip->irq = irq;
+	dip->func = func;
+	dip->arg = arg;
+	snprintf(strbuf, sizeof(strbuf), "link %d, bitno %d", link, bitno);
+	evcnt_attach_dynamic(&dip->count, EVCNT_TYPE_INTR, NULL,
+		"rmixl_pcie", strbuf);
+
+	if (bitno < 32) {
+		offset = int_enb_offset[link].r0;
+		bit = 1 << bitno;
+	} else {
+		offset = int_enb_offset[link].r1;
+		bit = 1 << (bitno - 32);
+	}
+
+	/* enable this interrupt in the PCIe bridge */
+	r = RMIXL_IOREG_READ(RMIXL_IO_DEV_PCIE_LE + offset); 
+	r |= bit;
+	RMIXL_IOREG_WRITE(RMIXL_IO_DEV_PCIE_LE + offset, r); 
+
+	if (lip->enabled == false) {
+		lip->ih = rmixl_intr_establish(irq, ipl,
+			RMIXL_INTR_LEVEL, RMIXL_INTR_HIGH, rmixl_pcie_intr, lip);
+		if (lip->ih == NULL)
+			panic("%s: cannot establish irq %d", __func__, link);
+
+		lip->sc = sc;
+		lip->ipl = ipl;
+		lip->enabled = true;
+		DPRINTF(("%s: enabled link %d\n", __func__, link));
+	}
+	LIST_INSERT_HEAD(&lip->dispatch, dip, next);
+
+ out:
+	splx(s);
+	return dip;
+}
+
+static int
+rmixl_pcie_intr(void *arg)
+{
+	rmixl_pcie_link_intr_t *lip = arg;
+	u_int link = lip->link;
+	int rv = 0;
+
+	uint32_t status0 = RMIXL_IOREG_READ(RMIXL_IO_DEV_PCIE_LE + int_sts_offset[link].r0); 
+	uint32_t status1 = RMIXL_IOREG_READ(RMIXL_IO_DEV_PCIE_LE + int_sts_offset[link].r1); 
+	uint64_t status = ((uint64_t)status1 << 32) | status0;
+	DPRINTF(("%s: %d:%#"PRIx64"\n", __func__, link, status));
+
+	if (status != 0) {
+		rmixl_pcie_link_dispatch_t *dip;
+
+		if (status & RMIXL_PCIE_LINK_STATUS_ERRORS)
+			rmixl_pcie_link_error_intr(link, status0, status1);
+
+		LIST_FOREACH(dip, &lip->dispatch, next) {
+			uint64_t bit = 1 << dip->bitno;
+			if ((status & bit) != 0) {
+				(void)(*dip->func)(dip->arg);
+				dip->count.ev_count++;
+				rv = 1;
+			}
+		}
+	}
+
+	return rv;
+}
+
+static void
+rmixl_pcie_link_error_intr(u_int link, uint32_t status0, uint32_t status1)
+{
+	printf("%s: mask %#"PRIx64"\n", 
+		__func__, RMIXL_PCIE_LINK_STATUS_ERRORS);
+	printf("%s: PCIe Link Error: link=%d status0=%#x status1=%#x\n",
+		__func__, link, status0, status1);
+#if defined(DDB) && defined(DEBUG)
+	Debugger();
+#endif
+}
+
+#endif	/* 0 */
+
 #if defined(DEBUG) || defined(DDB)
 /* this function exists to facilitate call from ddb */
 int

Reply via email to