svn commit: r299002 - head/sys/dev/pci
John Baldwin
jhb at FreeBSD.org
Tue May 3 19:45:26 UTC 2016
Author: jhb
Date: Tue May 3 19:45:24 2016
New Revision: 299002
URL: https://svnweb.freebsd.org/changeset/base/299002
Log:
Save and restore SRIOV-related config registers.
Save the value of the IOV control and page size registers and restore
them (along with the VF count) in pci_cfg_save/pci_cfg_restore. This
ensures ARI remains enabled if a PF driver resets itself during the
PCI_IOV_INIT callback. This might also properly restore SRIOV state
across suspend/resume.
Reviewed by: rstone, vangyzen
Differential Revision: https://reviews.freebsd.org/D6192
Modified:
head/sys/dev/pci/pci.c
head/sys/dev/pci/pci_iov.c
head/sys/dev/pci/pci_iov_private.h
Modified: head/sys/dev/pci/pci.c
==============================================================================
--- head/sys/dev/pci/pci.c Tue May 3 19:42:58 2016 (r299001)
+++ head/sys/dev/pci/pci.c Tue May 3 19:45:24 2016 (r299002)
@@ -5643,6 +5643,10 @@ pci_cfg_restore(device_t dev, struct pci
pci_resume_msi(dev);
if (dinfo->cfg.msix.msix_location != 0)
pci_resume_msix(dev);
+
+ if (dinfo->cfg.iov != NULL)
+ pci_iov_cfg_restore(dev, dinfo);
+
}
static void
@@ -5755,6 +5759,9 @@ pci_cfg_save(device_t dev, struct pci_de
if (dinfo->cfg.pcix.pcix_location != 0)
pci_cfg_save_pcix(dev, dinfo);
+ if (dinfo->cfg.iov != NULL)
+ pci_iov_cfg_save(dev, dinfo);
+
/*
* don't set the state for display devices, base peripherals and
* memory devices since bad things happen when they are powered down.
Modified: head/sys/dev/pci/pci_iov.c
==============================================================================
--- head/sys/dev/pci/pci_iov.c Tue May 3 19:42:58 2016 (r299001)
+++ head/sys/dev/pci/pci_iov.c Tue May 3 19:45:24 2016 (r299002)
@@ -770,6 +770,29 @@ out:
return (error);
}
+void
+pci_iov_cfg_restore(device_t dev, struct pci_devinfo *dinfo)
+{
+ struct pcicfg_iov *iov;
+
+ iov = dinfo->cfg.iov;
+
+ IOV_WRITE(dinfo, PCIR_SRIOV_PAGE_SIZE, iov->iov_page_size, 4);
+ IOV_WRITE(dinfo, PCIR_SRIOV_NUM_VFS, iov->iov_num_vfs, 2);
+ IOV_WRITE(dinfo, PCIR_SRIOV_CTL, iov->iov_ctl, 2);
+}
+
+void
+pci_iov_cfg_save(device_t dev, struct pci_devinfo *dinfo)
+{
+ struct pcicfg_iov *iov;
+
+ iov = dinfo->cfg.iov;
+
+ iov->iov_page_size = IOV_READ(dinfo, PCIR_SRIOV_PAGE_SIZE, 4);
+ iov->iov_ctl = IOV_READ(dinfo, PCIR_SRIOV_CTL, 2);
+}
+
/* Return true if child is a VF of the given PF. */
static int
pci_iov_is_child_vf(struct pcicfg_iov *pf, device_t child)
Modified: head/sys/dev/pci/pci_iov_private.h
==============================================================================
--- head/sys/dev/pci/pci_iov_private.h Tue May 3 19:42:58 2016 (r299001)
+++ head/sys/dev/pci/pci_iov_private.h Tue May 3 19:45:24 2016 (r299002)
@@ -47,10 +47,16 @@ struct pcicfg_iov {
int iov_pos;
int iov_num_vfs;
uint32_t iov_flags;
+
+ uint16_t iov_ctl;
+ uint32_t iov_page_size;
};
#define IOV_RMAN_INITED 0x0001
#define IOV_BUSY 0x0002
+void pci_iov_cfg_restore(device_t dev, struct pci_devinfo *dinfo);
+void pci_iov_cfg_save(device_t dev, struct pci_devinfo *dinfo);
+
#endif
More information about the svn-src-head
mailing list