Exemplo n.º 1
0
static int gpex_guest_aspace_notification(struct vmm_notifier_block *nb,
					  unsigned long evt, void *data)
{
	int ret = NOTIFY_DONE;
	int rc;
	struct gpex_state *gpex =
		container_of(nb, struct gpex_state, guest_aspace_client);

	vmm_mutex_lock(&gpex->lock);

	switch (evt) {
	case VMM_GUEST_ASPACE_EVENT_RESET:
		if ((rc =
		     pci_emu_register_controller(gpex->node,
						 gpex->guest,
						 gpex->controller))
		    != VMM_OK) {
			GPEX_LOG(LVL_ERR,
				   "Failed to attach PCI controller.\n");
			goto _failed;
		}
		ret = NOTIFY_OK;
		break;
	default:
		break;
	}

 _failed:
	vmm_mutex_unlock(&gpex->lock);

	return ret;
}
Exemplo n.º 2
0
static int gpex_emulator_probe(struct vmm_guest *guest,
			       struct vmm_emudev *edev,
			       const struct vmm_devtree_nodeid *eid)
{
	int rc = VMM_OK, i;
	char name[64];
	struct gpex_state *s;
	struct pci_class *class;

	s = vmm_zalloc(sizeof(struct gpex_state));
	if (!s) {
		GPEX_LOG(LVL_ERR, "Failed to allocate gpex state.\n");
		rc = VMM_EFAIL;
		goto _failed;
	}

	s->node = edev->node;
	s->guest = guest;
	s->controller = vmm_zalloc(sizeof(struct pci_host_controller));
	if (!s->controller) {
		GPEX_LOG(LVL_ERR, "Failed to allocate pci host contoller"
					"for gpex.\n");
		goto _failed;
	}
	INIT_MUTEX(&s->lock);
	INIT_LIST_HEAD(&s->controller->head);
	INIT_LIST_HEAD(&s->controller->attached_buses);
	INIT_SPIN_LOCK(&s->controller->lock);

	/* initialize class */
	class = PCI_CONTROLLER_TO_CLASS(s->controller);

	INIT_SPIN_LOCK(&class->lock);
	class->conf_header.vendor_id = PCI_VENDOR_ID_REDHAT;
	class->conf_header.device_id = PCI_DEVICE_ID_REDHAT_PCIE_HOST;
	class->config_read = gpex_config_read;
	class->config_write = gpex_config_write;

	rc = vmm_devtree_read_u32(edev->node, "nr_buses",
				  &s->controller->nr_buses);
	if (rc) {
		GPEX_LOG(LVL_ERR, "Failed to get fifo size in guest DTS.\n");
		goto _failed;
	}

	GPEX_LOG(LVL_VERBOSE, "%s: %d busses on this controller.\n",
		   __func__, s->controller->nr_buses);

	for (i = 0; i < s->controller->nr_buses; i++) {
		if ((rc = pci_emu_attach_new_pci_bus(s->controller, i))
		    != VMM_OK) {
			GPEX_LOG(LVL_ERR, "Failed to attach PCI bus %d\n",
				   i+1);
			goto _failed;
		}
	}

	strlcpy(name, guest->name, sizeof(name));
	strlcat(name, "/", sizeof(name));
	if (strlcat(name, edev->node->name, sizeof(name)) >= sizeof(name)) {
		rc = VMM_EOVERFLOW;
		goto _failed;
	}

	edev->priv = s;

	vmm_mutex_lock(&s->lock);

	if ((rc = pci_emu_register_controller(s->node, s->guest,
				s->controller)) != VMM_OK) {
			GPEX_LOG(LVL_ERR,
				   "Failed to attach PCI controller.\n");
			goto _controller_failed;
	}

	vmm_mutex_unlock(&s->lock);

	GPEX_LOG(LVL_VERBOSE, "Success.\n");

	goto _done;

_controller_failed:
	vmm_mutex_unlock(&s->lock);

_failed:
	if (s && s->controller) vmm_free(s->controller);
	if (s) vmm_free(s);

_done:
	return rc;
}