svn commit: r294430 - in head/sys: arm/mv dev/pci

Zbigniew Bodek zbb at FreeBSD.org
Wed Jan 20 14:05:23 UTC 2016


Author: zbb
Date: Wed Jan 20 14:05:21 2016
New Revision: 294430
URL: https://svnweb.freebsd.org/changeset/base/294430

Log:
  Fix invalid root link detection in mv_pci driver
  
  mv_pci driver omitted slot 0, which can be valid device on Armada38x.
  New mechanism detects if device is root link, basing on vendor's
  and device's IDs.
  It is restricted to Armada38x; on other machines, behaviour remains
  the same.
  
  Reviewed by:    andrew
  Obtained from:  Semihalf
  Sponsored by:   Stormshield
  Submitted by:   Bartosz Szczepanek <bsz at semihalf.com>
  Differential revision:  https://reviews.freebsd.org/D4377

Modified:
  head/sys/arm/mv/mv_pci.c
  head/sys/arm/mv/mvreg.h
  head/sys/dev/pci/pcireg.h

Modified: head/sys/arm/mv/mv_pci.c
==============================================================================
--- head/sys/arm/mv/mv_pci.c	Wed Jan 20 14:02:36 2016	(r294429)
+++ head/sys/arm/mv/mv_pci.c	Wed Jan 20 14:05:21 2016	(r294430)
@@ -1,7 +1,7 @@
 /*-
  * Copyright (c) 2008 MARVELL INTERNATIONAL LTD.
  * Copyright (c) 2010 The FreeBSD Foundation
- * Copyright (c) 2010-2012 Semihalf
+ * Copyright (c) 2010-2015 Semihalf
  * All rights reserved.
  *
  * Developed by Semihalf.
@@ -1016,6 +1016,25 @@ mv_pcib_maxslots(device_t dev)
 	return ((sc->sc_type != MV_TYPE_PCI) ? 1 : PCI_SLOTMAX);
 }
 
+static int
+mv_pcib_root_slot(device_t dev, u_int bus, u_int slot, u_int func)
+{
+#if defined(SOC_MV_ARMADA38X)
+	struct mv_pcib_softc *sc = device_get_softc(dev);
+	uint32_t vendor, device;
+
+	vendor = mv_pcib_hw_cfgread(sc, bus, slot, func, PCIR_VENDOR,
+	    PCIR_VENDOR_LENGTH);
+	device = mv_pcib_hw_cfgread(sc, bus, slot, func, PCIR_DEVICE,
+	    PCIR_DEVICE_LENGTH) & MV_DEV_FAMILY_MASK;
+
+	return (vendor == PCI_VENDORID_MRVL && device == MV_DEV_ARMADA38X);
+#else
+	/* On platforms other than Armada38x, root link is always at slot 0 */
+	return (slot == 0);
+#endif
+}
+
 static uint32_t
 mv_pcib_read_config(device_t dev, u_int bus, u_int slot, u_int func,
     u_int reg, int bytes)
@@ -1024,7 +1043,7 @@ mv_pcib_read_config(device_t dev, u_int 
 
 	/* Return ~0 if link is inactive or trying to read from Root */
 	if ((bus_space_read_4(sc->sc_bst, sc->sc_bsh, PCIE_REG_STATUS) &
-	    PCIE_STATUS_LINK_DOWN) || (slot == 0))
+	    PCIE_STATUS_LINK_DOWN) || mv_pcib_root_slot(dev, bus, slot, func))
 		return (~0U);
 
 	return (mv_pcib_hw_cfgread(sc, bus, slot, func, reg, bytes));
@@ -1038,7 +1057,7 @@ mv_pcib_write_config(device_t dev, u_int
 
 	/* Return if link is inactive or trying to write to Root */
 	if ((bus_space_read_4(sc->sc_bst, sc->sc_bsh, PCIE_REG_STATUS) &
-	    PCIE_STATUS_LINK_DOWN) || (slot == 0))
+	    PCIE_STATUS_LINK_DOWN) || mv_pcib_root_slot(dev, bus, slot, func))
 		return;
 
 	mv_pcib_hw_cfgwrite(sc, bus, slot, func, reg, val, bytes);

Modified: head/sys/arm/mv/mvreg.h
==============================================================================
--- head/sys/arm/mv/mvreg.h	Wed Jan 20 14:02:36 2016	(r294429)
+++ head/sys/arm/mv/mvreg.h	Wed Jan 20 14:05:21 2016	(r294430)
@@ -438,6 +438,7 @@
 
 #define MV_DEV_FAMILY_MASK	0xff00
 #define MV_DEV_DISCOVERY	0x7800
+#define	MV_DEV_ARMADA38X	0x6800
 
 /*
  * Doorbell register control

Modified: head/sys/dev/pci/pcireg.h
==============================================================================
--- head/sys/dev/pci/pcireg.h	Wed Jan 20 14:02:36 2016	(r294429)
+++ head/sys/dev/pci/pcireg.h	Wed Jan 20 14:05:21 2016	(r294430)
@@ -690,6 +690,9 @@
 #define	PCIR_VENDOR_LENGTH	0x2
 #define	PCIR_VENDOR_DATA	0x3
 
+/* PCI Device capability definitions */
+#define	PCIR_DEVICE_LENGTH	0x2
+
 /* PCI EHCI Debug Port definitions */
 #define	PCIR_DEBUG_PORT		0x2
 #define	PCIM_DEBUG_PORT_OFFSET		0x1FFF


More information about the svn-src-head mailing list