xref: /kvmtool/devices.c (revision b6dcc46671b81d443f811eaef8c148929afe8f59)
121ff329dSWill Deacon #include "kvm/devices.h"
221ff329dSWill Deacon #include "kvm/kvm.h"
3b5981636SWill Deacon #include "kvm/pci.h"
4b5981636SWill Deacon #include "kvm/virtio-mmio.h"
521ff329dSWill Deacon 
621ff329dSWill Deacon #include <linux/err.h>
721ff329dSWill Deacon #include <linux/rbtree.h>
821ff329dSWill Deacon 
921ff329dSWill Deacon struct device_bus {
1021ff329dSWill Deacon 	struct rb_root	root;
1121ff329dSWill Deacon 	int		dev_num;
1221ff329dSWill Deacon };
1321ff329dSWill Deacon 
1421ff329dSWill Deacon static struct device_bus device_trees[DEVICE_BUS_MAX] = {
1521ff329dSWill Deacon 	[0 ... (DEVICE_BUS_MAX - 1)] = { RB_ROOT, 0 },
1621ff329dSWill Deacon };
1721ff329dSWill Deacon 
1821ff329dSWill Deacon int device__register(struct device_header *dev)
1921ff329dSWill Deacon {
2021ff329dSWill Deacon 	struct device_bus *bus;
2121ff329dSWill Deacon 	struct rb_node **node, *parent = NULL;
2221ff329dSWill Deacon 
2321ff329dSWill Deacon 	if (dev->bus_type >= DEVICE_BUS_MAX) {
2421ff329dSWill Deacon 		pr_warning("Ignoring device registration on unknown bus %d\n",
2521ff329dSWill Deacon 			   dev->bus_type);
2621ff329dSWill Deacon 		return -EINVAL;
2721ff329dSWill Deacon 	}
2821ff329dSWill Deacon 
2921ff329dSWill Deacon 	bus = &device_trees[dev->bus_type];
3021ff329dSWill Deacon 	dev->dev_num = bus->dev_num++;
3121ff329dSWill Deacon 
32b5981636SWill Deacon 	switch (dev->bus_type) {
33b5981636SWill Deacon 	case DEVICE_BUS_PCI:
34b5981636SWill Deacon 		pci__assign_irq(dev);
35b5981636SWill Deacon 		break;
36b5981636SWill Deacon 	case DEVICE_BUS_MMIO:
37b5981636SWill Deacon 		virtio_mmio_assign_irq(dev);
38b5981636SWill Deacon 		break;
39b5981636SWill Deacon 	default:
40b5981636SWill Deacon 		break;
41b5981636SWill Deacon 	}
42b5981636SWill Deacon 
4321ff329dSWill Deacon 	node = &bus->root.rb_node;
4421ff329dSWill Deacon 	while (*node) {
4521ff329dSWill Deacon 		int num = rb_entry(*node, struct device_header, node)->dev_num;
4621ff329dSWill Deacon 		int result = dev->dev_num - num;
4721ff329dSWill Deacon 
48*b6dcc466SJames Morse 		parent = *node;
4921ff329dSWill Deacon 		if (result < 0)
5021ff329dSWill Deacon 			node = &((*node)->rb_left);
5121ff329dSWill Deacon 		else if (result > 0)
5221ff329dSWill Deacon 			node = &((*node)->rb_right);
5321ff329dSWill Deacon 		else
5421ff329dSWill Deacon 			return -EEXIST;
5521ff329dSWill Deacon 	}
5621ff329dSWill Deacon 
5721ff329dSWill Deacon 	rb_link_node(&dev->node, parent, node);
5821ff329dSWill Deacon 	rb_insert_color(&dev->node, &bus->root);
5921ff329dSWill Deacon 	return 0;
6021ff329dSWill Deacon }
6121ff329dSWill Deacon 
62bb7b03f3SWill Deacon void device__unregister(struct device_header *dev)
63bb7b03f3SWill Deacon {
64bb7b03f3SWill Deacon 	struct device_bus *bus = &device_trees[dev->bus_type];
65bb7b03f3SWill Deacon 	rb_erase(&dev->node, &bus->root);
66bb7b03f3SWill Deacon }
67bb7b03f3SWill Deacon 
6821ff329dSWill Deacon struct device_header *device__find_dev(enum device_bus_type bus_type, u8 dev_num)
6921ff329dSWill Deacon {
7021ff329dSWill Deacon 	struct rb_node *node;
7121ff329dSWill Deacon 
7221ff329dSWill Deacon 	if (bus_type >= DEVICE_BUS_MAX)
7321ff329dSWill Deacon 		return ERR_PTR(-EINVAL);
7421ff329dSWill Deacon 
7521ff329dSWill Deacon 	node = device_trees[bus_type].root.rb_node;
7621ff329dSWill Deacon 	while (node) {
7721ff329dSWill Deacon 		struct device_header *dev = rb_entry(node, struct device_header,
7821ff329dSWill Deacon 						     node);
7921ff329dSWill Deacon 		if (dev_num < dev->dev_num) {
8021ff329dSWill Deacon 			node = node->rb_left;
8121ff329dSWill Deacon 		} else if (dev_num > dev->dev_num) {
8221ff329dSWill Deacon 			node = node->rb_right;
8321ff329dSWill Deacon 		} else {
8421ff329dSWill Deacon 			return dev;
8521ff329dSWill Deacon 		}
8621ff329dSWill Deacon 	}
8721ff329dSWill Deacon 
8821ff329dSWill Deacon 	return NULL;
8921ff329dSWill Deacon }
9021ff329dSWill Deacon 
9121ff329dSWill Deacon struct device_header *device__first_dev(enum device_bus_type bus_type)
9221ff329dSWill Deacon {
9321ff329dSWill Deacon 	struct rb_node *node;
9421ff329dSWill Deacon 
9521ff329dSWill Deacon 	if (bus_type >= DEVICE_BUS_MAX)
9621ff329dSWill Deacon 		return NULL;
9721ff329dSWill Deacon 
9821ff329dSWill Deacon 	node = rb_first(&device_trees[bus_type].root);
9921ff329dSWill Deacon 	return node ? rb_entry(node, struct device_header, node) : NULL;
10021ff329dSWill Deacon }
10121ff329dSWill Deacon 
10221ff329dSWill Deacon struct device_header *device__next_dev(struct device_header *dev)
10321ff329dSWill Deacon {
10421ff329dSWill Deacon 	struct rb_node *node = rb_next(&dev->node);
10521ff329dSWill Deacon 	return node ? rb_entry(node, struct device_header, node) : NULL;
10621ff329dSWill Deacon }
107