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@semihalf.com>
Differential revision:  https://reviews.freebsd.org/D4377
This commit is contained in:
Zbigniew Bodek 2016-01-20 14:05:21 +00:00
parent 515af5ce4e
commit 1e92574faa
3 changed files with 26 additions and 3 deletions

View File

@ -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 bus, u_int slot, u_int func,
/* 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 bus, u_int slot, u_int func,
/* 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);

View File

@ -438,6 +438,7 @@
#define MV_DEV_FAMILY_MASK 0xff00
#define MV_DEV_DISCOVERY 0x7800
#define MV_DEV_ARMADA38X 0x6800
/*
* Doorbell register control

View File

@ -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