Fri Sep 19 14:37:13 2008 UTC ()
Complain about devices with misaligned PCI capability pointers instead
of panicing. Christoph Schug reported that such a device is made by
Nvidia.


(joerg)
diff -r1.118 -r1.119 src/sys/dev/pci/pci.c

cvs diff -r1.118 -r1.119 src/sys/dev/pci/pci.c (expand / switch to context diff)
--- src/sys/dev/pci/pci.c 2008/06/12 22:44:47 1.118
+++ src/sys/dev/pci/pci.c 2008/09/19 14:37:13 1.119
@@ -1,4 +1,4 @@
-/*	$NetBSD: pci.c,v 1.118 2008/06/12 22:44:47 cegger Exp $	*/
+/*	$NetBSD: pci.c,v 1.119 2008/09/19 14:37:13 joerg Exp $	*/
 
 /*
  * Copyright (c) 1995, 1996, 1997, 1998
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci.c,v 1.118 2008/06/12 22:44:47 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci.c,v 1.119 2008/09/19 14:37:13 joerg Exp $");
 
 #include "opt_pci.h"
 
@@ -432,10 +432,15 @@
 
 	ofs = PCI_CAPLIST_PTR(pci_conf_read(pc, tag, ofs));
 	while (ofs != 0) {
-#ifdef DIAGNOSTIC
-		if ((ofs & 3) || (ofs < 0x40))
-			panic("pci_get_capability");
-#endif
+		if ((ofs & 3) || (ofs < 0x40)) {
+			int bus, device, function;
+
+			pci_decompose_tag(pc, tag, &bus, &device, &function);
+
+			printf("Skipping broken PCI header on %d:%d:%d\n",
+			    bus, device, function);
+			break;
+		}
 		reg = pci_conf_read(pc, tag, ofs);
 		if (PCI_CAPLIST_CAP(reg) == capid) {
 			if (offset)