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 unified 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,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: pci.c,v 1.118 2008/06/12 22:44:47 cegger Exp $ */ 1/* $NetBSD: pci.c,v 1.119 2008/09/19 14:37:13 joerg Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1995, 1996, 1997, 1998 4 * Copyright (c) 1995, 1996, 1997, 1998
5 * Christopher G. Demetriou. All rights reserved. 5 * Christopher G. Demetriou. All rights reserved.
6 * Copyright (c) 1994 Charles M. Hannum. All rights reserved. 6 * Copyright (c) 1994 Charles M. Hannum. All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -26,27 +26,27 @@ @@ -26,27 +26,27 @@
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34/* 34/*
35 * PCI bus autoconfiguration. 35 * PCI bus autoconfiguration.
36 */ 36 */
37 37
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39__KERNEL_RCSID(0, "$NetBSD: pci.c,v 1.118 2008/06/12 22:44:47 cegger Exp $"); 39__KERNEL_RCSID(0, "$NetBSD: pci.c,v 1.119 2008/09/19 14:37:13 joerg Exp $");
40 40
41#include "opt_pci.h" 41#include "opt_pci.h"
42 42
43#include <sys/param.h> 43#include <sys/param.h>
44#include <sys/malloc.h> 44#include <sys/malloc.h>
45#include <sys/systm.h> 45#include <sys/systm.h>
46#include <sys/device.h> 46#include <sys/device.h>
47 47
48#include <dev/pci/pcireg.h> 48#include <dev/pci/pcireg.h>
49#include <dev/pci/pcivar.h> 49#include <dev/pci/pcivar.h>
50#include <dev/pci/pcidevs.h> 50#include <dev/pci/pcidevs.h>
51 51
52#include <uvm/uvm_extern.h> 52#include <uvm/uvm_extern.h>
@@ -422,30 +422,35 @@ pci_get_capability(pci_chipset_tag_t pc, @@ -422,30 +422,35 @@ pci_get_capability(pci_chipset_tag_t pc,
422 case 0: /* standard device header */ 422 case 0: /* standard device header */
423 case 1: /* PCI-PCI bridge header */ 423 case 1: /* PCI-PCI bridge header */
424 ofs = PCI_CAPLISTPTR_REG; 424 ofs = PCI_CAPLISTPTR_REG;
425 break; 425 break;
426 case 2: /* PCI-CardBus Bridge header */ 426 case 2: /* PCI-CardBus Bridge header */
427 ofs = PCI_CARDBUS_CAPLISTPTR_REG; 427 ofs = PCI_CARDBUS_CAPLISTPTR_REG;
428 break; 428 break;
429 default: 429 default:
430 return (0); 430 return (0);
431 } 431 }
432 432
433 ofs = PCI_CAPLIST_PTR(pci_conf_read(pc, tag, ofs)); 433 ofs = PCI_CAPLIST_PTR(pci_conf_read(pc, tag, ofs));
434 while (ofs != 0) { 434 while (ofs != 0) {
435#ifdef DIAGNOSTIC 435 if ((ofs & 3) || (ofs < 0x40)) {
436 if ((ofs & 3) || (ofs < 0x40)) 436 int bus, device, function;
437 panic("pci_get_capability"); 437
438#endif 438 pci_decompose_tag(pc, tag, &bus, &device, &function);
 439
 440 printf("Skipping broken PCI header on %d:%d:%d\n",
 441 bus, device, function);
 442 break;
 443 }
439 reg = pci_conf_read(pc, tag, ofs); 444 reg = pci_conf_read(pc, tag, ofs);
440 if (PCI_CAPLIST_CAP(reg) == capid) { 445 if (PCI_CAPLIST_CAP(reg) == capid) {
441 if (offset) 446 if (offset)
442 *offset = ofs; 447 *offset = ofs;
443 if (value) 448 if (value)
444 *value = reg; 449 *value = reg;
445 return (1); 450 return (1);
446 } 451 }
447 ofs = PCI_CAPLIST_NEXT(reg); 452 ofs = PCI_CAPLIST_NEXT(reg);
448 } 453 }
449 454
450 return (0); 455 return (0);
451} 456}