Commit 273c9e3f authored by Konrad Sztyber's avatar Konrad Sztyber Committed by Jim Harris
Browse files

lib/vmd: initialize hotplug structures



Initialize the hotplug structures if the device is hotplug capable.

Change-Id: I2bab4ec820f37f352d79203e3ad37aef31bdc3c6
Signed-off-by: default avatarorden smith <orden.e.smith@intel.com>
Signed-off-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/470650


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarWojciech Malikowski <wojciech.malikowski@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
parent f9422819
Loading
Loading
Loading
Loading
+33 −7
Original line number Diff line number Diff line
@@ -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) {
+24 −31
Original line number Diff line number Diff line
@@ -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)
{