lib/vmd: initialize hotplug structures

Initialize the hotplug structures if the device is hotplug capable.

Change-Id: I2bab4ec820f37f352d79203e3ad37aef31bdc3c6
Signed-off-by: orden smith <orden.e.smith@intel.com>
Signed-off-by: Konrad Sztyber <konrad.sztyber@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/470650
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Wojciech Malikowski <wojciech.malikowski@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
This commit is contained in:
Konrad Sztyber 2019-10-03 13:49:02 +02:00 committed by Jim Harris
parent f942281913
commit 273c9e3ffc
2 changed files with 57 additions and 38 deletions

View File

@ -34,6 +34,7 @@
#include "vmd.h"
#include "spdk/stdinc.h"
#include "spdk/likely.h"
static unsigned char *device_type[] = {
"PCI Express Endpoint",
@ -126,8 +127,8 @@ vmd_allocate_base_addr(struct vmd_adapter *vmd, struct vmd_pci_device *dev, uint
*/
if (dev) {
hp_bus = vmd_is_dev_in_hotplug_path(dev);
if (hp_bus && hp_bus->self) {
return vmd_hp_allocate_base_addr(hp_bus->self->hp, size);
if (hp_bus && hp_bus->self && hp_bus->self->hotplug_capable) {
return vmd_hp_allocate_base_addr(&hp_bus->self->hp, size);
}
}
@ -442,6 +443,30 @@ vmd_reset_base_limit_registers(struct vmd_pci_device *dev)
reg = dev->header->one.subordinate;
}
static void
vmd_init_hotplug(struct vmd_pci_device *dev, struct vmd_pci_bus *bus)
{
struct vmd_adapter *vmd = bus->vmd;
struct vmd_hot_plug *hp = &dev->hp;
dev->hotplug_capable = true;
hp->bar.size = 1 << 20;
if (!vmd->scan_completed) {
hp->bar.start = vmd_allocate_base_addr(vmd, NULL, hp->bar.size);
bus->self->header->one.mem_base = BRIDGE_BASEREG(hp->bar.start);
bus->self->header->one.mem_limit =
bus->self->header->one.mem_base + BRIDGE_BASEREG(hp->bar.size - 1);
} else {
hp->bar.start = (uint64_t)bus->self->header->one.mem_base << 16;
}
hp->bar.vaddr = (uint64_t)vmd->mem_vaddr + (hp->bar.start - vmd->membar);
SPDK_DEBUGLOG(SPDK_LOG_VMD, "%s: mem_base:mem_limit = %x : %x\n", __func__,
bus->self->header->one.mem_base, bus->self->header->one.mem_limit);
}
static struct vmd_pci_device *
vmd_alloc_dev(struct vmd_pci_bus *bus, uint32_t devfn)
{
@ -589,8 +614,8 @@ vmd_get_next_bus_number(struct vmd_pci_device *dev, struct vmd_adapter *vmd)
if (dev) {
hp_bus = vmd_is_dev_in_hotplug_path(dev);
if (hp_bus && hp_bus->self && hp_bus->self->hp) {
return vmd_hp_get_next_bus_number(hp_bus->self->hp);
if (hp_bus && hp_bus->self && hp_bus->self->hotplug_capable) {
return vmd_hp_get_next_bus_number(&hp_bus->self->hp);
}
}
@ -776,6 +801,7 @@ vmd_dev_init(struct vmd_pci_device *dev)
dev->pci.cfg_write = vmd_dev_cfg_write;
dev->pci.detach = vmd_dev_detach;
dev->cached_slot_control = dev->pcie_cap->slot_control;
dev->hotplug_capable = false;
if (vmd_is_supported_device(dev)) {
spdk_pci_addr_fmt(bdf, sizeof(bdf), &dev->pci.addr);
@ -862,13 +888,13 @@ vmd_scan_single_bus(struct vmd_pci_bus *bus, struct vmd_pci_device *parent_bridg
slot_cap.bit_field.hotplug_capable,
new_dev->pcie_cap->express_cap_register.bit_field.slot_implemented);
vmd_dev_init(new_dev);
if (slot_cap.bit_field.hotplug_capable &&
new_dev->pcie_cap->express_cap_register.bit_field.slot_implemented) {
new_dev->hp = vmd_new_hotplug(new_bus);
vmd_init_hotplug(new_dev, new_bus);
}
vmd_dev_init(new_dev);
dev_cnt += vmd_scan_single_bus(new_bus, new_dev);
if (new_dev->pcie_cap != NULL) {
if (new_dev->pcie_cap->express_cap_register.bit_field.device_type == SwitchUpstreamPort) {

View File

@ -71,6 +71,28 @@ struct vmd_pci_bus {
struct vmd_pci_bus *next; /* link for all buses found during scan */
};
/*
* memory element for base address assignment and reuse
*/
struct pci_mem_mgr {
uint32_t size : 30; /* size of memory element */
uint32_t in_use : 1;
uint32_t rsv : 1;
uint64_t addr;
};
struct vmd_hot_plug {
uint32_t count : 12;
uint32_t reserved_bus_count : 4;
uint32_t max_hotplug_bus_number : 8;
uint32_t next_bus_number : 8;
struct pci_bars bar;
union express_slot_status_register slot_status;
struct pci_mem_mgr mem[ADDR_ELEM_COUNT];
uint8_t bus_numbers[RESERVED_HOTPLUG_BUSES];
struct vmd_pci_bus *bus;
};
struct vmd_pci_device {
struct spdk_pci_device pci;
struct pci_bars bar[6];
@ -91,6 +113,7 @@ struct vmd_pci_device {
uint16_t did;
uint16_t pcie_flags, msix_table_size;
uint32_t devfn;
bool hotplug_capable;
uint32_t header_type : 1;
uint32_t multifunction : 1;
@ -100,35 +123,11 @@ struct vmd_pci_device {
uint32_t rsv1 : 12;
uint32_t target : 16;
struct vmd_hot_plug *hp;
struct vmd_hot_plug hp;
/* Cached version of the slot_control register */
union express_slot_control_register cached_slot_control;
};
/*
* memory element for base address assignment and reuse
*/
struct pci_mem_mgr {
uint32_t size : 30; /* size of memory element */
uint32_t in_use : 1;
uint32_t rsv : 1;
uint64_t addr;
};
struct vmd_hot_plug {
uint32_t count : 12;
uint32_t reserved_bus_count : 4;
uint32_t max_hotplug_bus_number : 8;
uint32_t next_bus_number : 8;
uint32_t addr_size;
uint64_t physical_addr;
union express_slot_status_register slot_status;
struct pci_mem_mgr mem[ADDR_ELEM_COUNT];
uint8_t bus_numbers[RESERVED_HOTPLUG_BUSES];
struct vmd_pci_bus *bus;
};
/*
* The VMD adapter
*/
@ -189,12 +188,6 @@ vmd_hp_enable_hotplug(struct vmd_hot_plug *hp)
}
static inline struct vmd_hot_plug *
vmd_new_hotplug(struct vmd_pci_bus *newBus)
{
return NULL;
}
static inline uint8_t
vmd_hp_get_next_bus_number(struct vmd_hot_plug *hp)
{