Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/x86/pci Add workaround for PCI prefetchable bit in ...



details:   https://anonhg.NetBSD.org/src/rev/12f1890a1211
branches:  trunk
changeset: 339839:12f1890a1211
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Thu Aug 13 04:52:40 2015 +0000

description:
Add workaround for PCI prefetchable bit in msipic_construct_msix_pic().
Some chips (e.g. Intel 82599) report SERR and MSI-X interrupt doesn't work.
This problem might not be the driver's bug but our PCI common part or VMs'
bug. See fxp(4), bge(4) and ixgbe(4). All of them has the same workaround
related to prefetchable bit. For the MSI-X table area, it should not have side
effect by prefetching. Until we find a real reason, we ignore the prefetchable
bit.

diffstat:

 sys/arch/x86/pci/msipic.c |  29 +++++++++++++++++++++++++++--
 1 files changed, 27 insertions(+), 2 deletions(-)

diffs (60 lines):

diff -r 614c1f4fde14 -r 12f1890a1211 sys/arch/x86/pci/msipic.c
--- a/sys/arch/x86/pci/msipic.c Thu Aug 13 04:39:33 2015 +0000
+++ b/sys/arch/x86/pci/msipic.c Thu Aug 13 04:52:40 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: msipic.c,v 1.6 2015/08/13 04:39:33 msaitoh Exp $       */
+/*     $NetBSD: msipic.c,v 1.7 2015/08/13 04:52:40 msaitoh Exp $       */
 
 /*
  * Copyright (c) 2015 Internet Initiative Japan Inc.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: msipic.c,v 1.6 2015/08/13 04:39:33 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: msipic.c,v 1.7 2015/08/13 04:52:40 msaitoh Exp $");
 
 #include "opt_intrdebug.h"
 
@@ -619,6 +619,8 @@
        size_t table_size;
        uint32_t table_offset;
        u_int memtype;
+       bus_addr_t memaddr;
+       int flags;
        int bir, bar, err, off, table_nentry;
        char pic_name_buf[MSIPICNAMEBUF];
 
@@ -684,9 +686,32 @@
          *     - Message Lower Address (32bit)
          */
        table_size = table_nentry * PCI_MSIX_TABLE_ENTRY_SIZE;
+#if 0
        err = pci_mapreg_submap(pa, bar, memtype, BUS_SPACE_MAP_LINEAR,
            roundup(table_size, PAGE_SIZE), table_offset,
            &bstag, &bshandle, NULL, &bssize);
+#else
+       /*
+        * Workaround for PCI prefetchable bit. Some chips (e.g. Intel 82599)
+        * report SERR and MSI-X doesn't work. This problem might not be the
+        * driver's bug but our PCI common part or VMs' bug. Until we find a
+        * real reason, we ignore the prefetchable bit.
+        */
+       if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, bar, memtype,
+               &memaddr, NULL, &flags) != 0) {
+               DPRINTF(("cannot get a map info.\n"));
+               msipic_destruct_common_msi_pic(msix_pic);
+               return NULL;
+       }
+       if ((flags & BUS_SPACE_MAP_PREFETCHABLE) != 0) {
+               DPRINTF(( "clear prefetchable bit\n"));
+               flags &= ~BUS_SPACE_MAP_PREFETCHABLE;
+       }
+       bssize = roundup(table_size, PAGE_SIZE);
+       err = bus_space_map(pa->pa_memt, memaddr + table_offset, bssize, flags,
+           &bshandle);
+       bstag = pa->pa_memt;
+#endif
        if (err) {
                DPRINTF(("cannot map msix table.\n"));
                msipic_destruct_common_msi_pic(msix_pic);



Home | Main Index | Thread Index | Old Index