struct seq_file *seq, u32 off);
void __iomem *visorchannel_get_header(struct visorchannel *channel);
+#define BUS_ROOT_DEVICE UINT_MAX
+struct visor_device *visorbus_get_device_by_id(u32 bus_no, u32 dev_no,
+ struct visor_device *from);
#endif
static long long bus_count; /** number of bus instances */
/** ever-increasing */
-static void chipset_bus_create(struct visorchipset_bus_info *bus_info);
-static void chipset_bus_destroy(struct visorchipset_bus_info *bus_info);
+static void chipset_bus_create(struct visor_device *bus_info);
+static void chipset_bus_destroy(struct visor_device *bus_info);
static void chipset_device_create(struct visorchipset_device_info *dev_info);
static void chipset_device_destroy(struct visorchipset_device_info *dev_info);
static void chipset_device_pause(struct visorchipset_device_info *dev_info);
*/
static int
create_visor_device(struct visor_device *bdev,
- struct visorchipset_device_info *dev_info,
- u64 partition_handle)
+ struct visorchipset_device_info *dev_info)
{
int rc = -1;
struct visor_device *dev = NULL;
fix_vbus_dev_info(struct visor_device *visordev)
{
int i;
- struct visorchipset_bus_info bus_info;
- struct visor_device *dev = NULL;
+ struct visor_device *bdev;
struct visor_driver *visordrv;
int bus_no = visordev->chipset_bus_no;
int dev_no = visordev->chipset_dev_no;
return;
hdr_info = (struct spar_vbus_headerinfo *)visordev->vbus_hdr_info;
+ if (!hdr_info)
+ return;
- visordrv = to_visor_driver(visordev->device.driver);
- if (!visorchipset_get_bus_info(bus_no, &bus_info))
- return;
-
- dev = (struct visor_device *)(bus_info.bus_driver_context);
- if (!dev)
- return;
+ bdev = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL);
+ if (!bdev)
+ return;
- if (!hdr_info)
- return;
+ visordrv = to_visor_driver(visordev->device.driver);
/* Within the list of device types (by GUID) that the driver
* says it supports, find out which one of those types matches
bus_device_info_init(&dev_info, chan_type_name,
visordrv->name, visordrv->version,
visordrv->vertag);
- write_vbus_dev_info(dev->visorchannel, hdr_info, &dev_info, dev_no);
+ write_vbus_dev_info(bdev->visorchannel, hdr_info, &dev_info, dev_no);
/* Re-write bus+chipset info, because it is possible that this
* was previously written by our evil counterpart, virtpci.
*/
- write_vbus_chp_info(dev->visorchannel, hdr_info, &chipset_driverinfo);
- write_vbus_bus_info(dev->visorchannel, hdr_info, &clientbus_driverinfo);
+ write_vbus_chp_info(bdev->visorchannel, hdr_info, &chipset_driverinfo);
+ write_vbus_bus_info(bdev->visorchannel, hdr_info,
+ &clientbus_driverinfo);
}
/** Create a device instance for the visor bus itself.
*/
-static struct visor_device *
-create_bus_instance(struct visorchipset_bus_info *bus_info)
+static int
+create_bus_instance(struct visor_device *dev)
{
- struct visor_device *rc = NULL;
- struct visor_device *dev = NULL;
- int id = bus_info->bus_no;
+ int rc;
+ int id = dev->chipset_bus_no;
struct spar_vbus_headerinfo *hdr_info;
POSTCODE_LINUX_2(BUS_CREATE_ENTRY_PC, POSTCODE_SEVERITY_INFO);
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev) {
- POSTCODE_LINUX_2(MALLOC_FAILURE_PC, POSTCODE_SEVERITY_ERR);
- rc = NULL;
- goto away;
- }
hdr_info = kzalloc(sizeof(*hdr_info), GFP_KERNEL);
if (!hdr_info) {
- rc = NULL;
- goto away_mem;
+ rc = -1;
+ goto away;
}
dev_set_name(&dev->device, "visorbus%d", id);
dev->device.bus = &visorbus_type;
dev->device.groups = visorbus_groups;
dev->device.release = visorbus_release_busdevice;
+
if (device_register(&dev->device) < 0) {
POSTCODE_LINUX_3(DEVICE_CREATE_FAILURE_PC, id,
POSTCODE_SEVERITY_ERR);
- rc = NULL;
- goto away_mem2;
+ rc = -1;
+ goto away_mem;
}
- dev->chipset_bus_no = id;
- dev->visorchannel = bus_info->visorchannel;
+
if (get_vbus_header_info(dev->visorchannel, hdr_info) >= 0) {
dev->vbus_hdr_info = (void *)hdr_info;
write_vbus_chp_info(dev->visorchannel, hdr_info,
}
bus_count++;
list_add_tail(&dev->list_all, &list_all_bus_instances);
- if (id == 0)
- dev = dev; /* for testing ONLY */
dev_set_drvdata(&dev->device, dev);
- rc = dev;
- return rc;
+ return 0;
-away_mem2:
- kfree(hdr_info);
away_mem:
- kfree(dev);
+ kfree(hdr_info);
away:
return rc;
}
}
static void
-chipset_bus_create(struct visorchipset_bus_info *bus_info)
+chipset_bus_create(struct visor_device *dev)
{
- struct visor_device *dev;
- int rc = -1;
- u32 bus_no = bus_info->bus_no;
+ int rc;
+ u32 bus_no = dev->chipset_bus_no;
POSTCODE_LINUX_3(BUS_CREATE_ENTRY_PC, bus_no, POSTCODE_SEVERITY_INFO);
- dev = create_bus_instance(bus_info);
- if (!dev)
- goto away;
- if (!visorchipset_set_bus_context(bus_info, dev))
- goto away;
+ rc = create_bus_instance(dev);
POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, bus_no, POSTCODE_SEVERITY_INFO);
- rc = 0;
-away:
- if (rc < 0) {
+
+ if (rc < 0)
POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus_no,
POSTCODE_SEVERITY_ERR);
- return;
- }
- POSTCODE_LINUX_3(CHIPSET_INIT_SUCCESS_PC, bus_no,
- POSTCODE_SEVERITY_INFO);
+ else
+ POSTCODE_LINUX_3(CHIPSET_INIT_SUCCESS_PC, bus_no,
+ POSTCODE_SEVERITY_INFO);
+
if (chipset_responders.bus_create)
- (*chipset_responders.bus_create) (bus_info, rc);
+ (*chipset_responders.bus_create) (dev, rc);
}
static void
-chipset_bus_destroy(struct visorchipset_bus_info *bus_info)
+chipset_bus_destroy(struct visor_device *dev)
{
- struct visor_device *dev;
- int rc = -1;
-
- dev = (struct visor_device *)(bus_info->bus_driver_context);
- if (!dev)
- goto away;
remove_bus_instance(dev);
- if (!visorchipset_set_bus_context(bus_info, NULL))
- goto away;
- rc = 0;
-away:
- if (rc < 0)
- return;
if (chipset_responders.bus_destroy)
- (*chipset_responders.bus_destroy)(bus_info, rc);
+ (*chipset_responders.bus_destroy)(dev, 0);
}
static void
chipset_device_create(struct visorchipset_device_info *dev_info)
{
- struct visorchipset_bus_info bus_info;
- struct visor_device *dev = NULL;
+ struct visor_device *bdev;
int rc = -1;
u32 bus_no = dev_info->bus_no;
u32 dev_no = dev_info->dev_no;
POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, dev_no, bus_no,
POSTCODE_SEVERITY_INFO);
- if (!visorchipset_get_bus_info(bus_no, &bus_info))
+ bdev = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL);
+ if (!bdev)
goto away;
+
POSTCODE_LINUX_4(DEVICE_CREATE_EXIT_PC, dev_no, bus_no,
POSTCODE_SEVERITY_INFO);
- rc = 0;
+
+ rc = create_visor_device(bdev, dev_info);
away:
if (rc < 0) {
POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no,
POSTCODE_SEVERITY_ERR);
- return;
+ if (chipset_responders.device_create)
+ (*chipset_responders.device_create)(dev_info, rc);
}
- dev = (struct visor_device *)(bus_info.bus_driver_context);
- rc = create_visor_device(dev, dev_info, bus_info.partition_handle);
+
POSTCODE_LINUX_4(DEVICE_CREATE_SUCCESS_PC, dev_no, bus_no,
POSTCODE_SEVERITY_INFO);
- if (rc < 0)
- if (chipset_responders.device_create)
- (*chipset_responders.device_create)(dev_info, rc);
}
static void
void *bus_driver_context;
};
-/** Attributes for a particular Supervisor bus.
- * (For a service partition acting as the server for buses/devices, there
- * is a 1-to-1 relationship between busses and guest partitions.)
- * Any visorchipset client can query these attributes using
- * visorchipset_get_client_bus_info() or visorchipset_get_bus_info().
- */
-struct visorchipset_bus_info {
- struct list_head entry;
- u32 bus_no;
- struct visorchipset_state state;
- struct visorchannel *visorchannel;
- uuid_le partition_uuid;
- u64 partition_handle;
- u8 *name; /* UTF8 */
- u8 *description; /* UTF8 */
- u64 reserved1;
- u32 reserved2;
- struct controlvm_message_header *pending_msg_hdr;/* CONTROLVM MsgHdr */
- /** For private use by the bus driver */
- void *bus_driver_context;
-};
-
/* These functions will be called from within visorchipset when certain
* events happen. (The implementation of these functions is outside of
* visorchipset.)
*/
struct visorchipset_busdev_notifiers {
- void (*bus_create)(struct visorchipset_bus_info *bus_info);
- void (*bus_destroy)(struct visorchipset_bus_info *bus_info);
+ void (*bus_create)(struct visor_device *bus_info);
+ void (*bus_destroy)(struct visor_device *bus_info);
void (*device_create)(struct visorchipset_device_info *bus_info);
void (*device_destroy)(struct visorchipset_device_info *bus_info);
void (*device_pause)(struct visorchipset_device_info *bus_info);
* -1 = it failed
*/
struct visorchipset_busdev_responders {
- void (*bus_create)(struct visorchipset_bus_info *p, int response);
- void (*bus_destroy)(struct visorchipset_bus_info *p, int response);
+ void (*bus_create)(struct visor_device *p, int response);
+ void (*bus_destroy)(struct visor_device *p, int response);
void (*device_create)(struct visorchipset_device_info *p, int response);
void (*device_destroy)(struct visorchipset_device_info *p,
int response);
struct ultra_vbus_deviceinfo *driver_info);
bool visorchipset_get_bus_info(u32 bus_no,
- struct visorchipset_bus_info *bus_info);
+ struct visor_device *bus_info);
bool visorchipset_get_device_info(u32 bus_no, u32 dev_no,
struct visorchipset_device_info *dev_info);
-bool visorchipset_set_bus_context(struct visorchipset_bus_info *bus_info,
+bool visorchipset_set_bus_context(struct visor_device *bus_info,
void *context);
/* visorbus init and exit functions */
#define UNISYS_SPAR_ID_ECX 0x70537379
#define UNISYS_SPAR_ID_EDX 0x34367261
-#define BUS_ROOT_DEVICE UINT_MAX
-
/*
* Module parameters
*/
*/
static struct visorchipset_busdev_notifiers busdev_notifiers;
-static void bus_create_response(struct visorchipset_bus_info *p, int response);
-static void bus_destroy_response(struct visorchipset_bus_info *p, int response);
+static void bus_create_response(struct visor_device *p, int response);
+static void bus_destroy_response(struct visor_device *p, int response);
static void device_create_response(struct visorchipset_device_info *p,
int response);
static void device_destroy_response(struct visorchipset_device_info *p,
}
static void
-bus_info_clear(void *v)
-{
- struct visorchipset_bus_info *p = (struct visorchipset_bus_info *) v;
-
- kfree(p->name);
- kfree(p->description);
- memset(p, 0, sizeof(struct visorchipset_bus_info));
-}
-
-static void
dev_info_clear(void *v)
{
struct visorchipset_device_info *p =
}
EXPORT_SYMBOL(visorbus_get_device_by_id);
-static struct visorchipset_bus_info *
-bus_find(struct list_head *list, u32 bus_no)
-{
- struct visorchipset_bus_info *p;
-
- list_for_each_entry(p, list, entry) {
- if (p->bus_no == bus_no)
- return p;
- }
-
- return NULL;
-}
-
static struct visorchipset_device_info *
device_find(struct list_head *list, u32 bus_no, u32 dev_no)
{
static void
cleanup_controlvm_structures(void)
{
- struct visorchipset_bus_info *bi, *tmp_bi;
struct visorchipset_device_info *di, *tmp_di;
- list_for_each_entry_safe(bi, tmp_bi, &bus_info_list, entry) {
- bus_info_clear(bi);
- list_del(&bi->entry);
- kfree(bi);
- }
-
list_for_each_entry_safe(di, tmp_di, &dev_info_list, entry) {
dev_info_clear(di);
list_del(&di->entry);
}
static void
-bus_epilog(struct visorchipset_bus_info *bus_info,
+bus_epilog(struct visor_device *bus_info,
u32 cmd, struct controlvm_message_header *msg_hdr,
int response, bool need_response)
{
struct controlvm_message_packet *cmd = &inmsg->cmd;
u32 bus_no = cmd->create_bus.bus_no;
int rc = CONTROLVM_RESP_SUCCESS;
- struct visorchipset_bus_info *bus_info;
+ struct visor_device *bus_info;
struct visorchannel *visorchannel;
- bus_info = bus_find(&bus_info_list, bus_no);
+ bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL);
if (bus_info && (bus_info->state.created == 1)) {
POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus_no,
POSTCODE_SEVERITY_ERR);
goto cleanup;
}
- INIT_LIST_HEAD(&bus_info->entry);
- bus_info->bus_no = bus_no;
+ bus_info->chipset_bus_no = bus_no;
+ bus_info->chipset_dev_no = BUS_ROOT_DEVICE;
POSTCODE_LINUX_3(BUS_CREATE_ENTRY_PC, bus_no, POSTCODE_SEVERITY_INFO);
goto cleanup;
}
bus_info->visorchannel = visorchannel;
- list_add(&bus_info->entry, &bus_info_list);
POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, bus_no, POSTCODE_SEVERITY_INFO);
{
struct controlvm_message_packet *cmd = &inmsg->cmd;
u32 bus_no = cmd->destroy_bus.bus_no;
- struct visorchipset_bus_info *bus_info;
+ struct visor_device *bus_info;
int rc = CONTROLVM_RESP_SUCCESS;
- bus_info = bus_find(&bus_info_list, bus_no);
+ bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL);
if (!bus_info)
rc = -CONTROLVM_RESP_ERROR_BUS_INVALID;
else if (bus_info->state.created == 0)
bus_epilog(bus_info, CONTROLVM_BUS_DESTROY, &inmsg->hdr,
rc, inmsg->hdr.flags.response_expected == 1);
+
+ /* bus_info is freed as part of the busdevice_release function */
}
static void
{
struct controlvm_message_packet *cmd = &inmsg->cmd;
u32 bus_no;
- struct visorchipset_bus_info *bus_info;
+ struct visor_device *bus_info;
int rc = CONTROLVM_RESP_SUCCESS;
- char s[99];
bus_no = cmd->configure_bus.bus_no;
POSTCODE_LINUX_3(BUS_CONFIGURE_ENTRY_PC, bus_no,
POSTCODE_SEVERITY_INFO);
- bus_info = bus_find(&bus_info_list, bus_no);
+ bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL);
if (!bus_info) {
POSTCODE_LINUX_3(BUS_CONFIGURE_FAILURE_PC, bus_no,
POSTCODE_SEVERITY_ERR);
parser_param_start(parser_ctx, PARSERSTRING_NAME);
bus_info->name = parser_string_get(parser_ctx);
- visorchannel_uuid_id(&bus_info->partition_uuid, s);
POSTCODE_LINUX_3(BUS_CONFIGURE_EXIT_PC, bus_no,
POSTCODE_SEVERITY_INFO);
}
u32 bus_no = cmd->create_device.bus_no;
u32 dev_no = cmd->create_device.dev_no;
struct visorchipset_device_info *dev_info;
- struct visorchipset_bus_info *bus_info;
+ struct visor_device *bus_info;
struct visorchannel *visorchannel;
int rc = CONTROLVM_RESP_SUCCESS;
rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE;
goto cleanup;
}
- bus_info = bus_find(&bus_info_list, bus_no);
+ bus_info = visorbus_get_device_by_id(bus_no, dev_no, NULL);
if (!bus_info) {
POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no,
POSTCODE_SEVERITY_ERR);
}
static void
-bus_create_response(struct visorchipset_bus_info *bus_info, int response)
+bus_create_response(struct visor_device *bus_info, int response)
{
if (response >= 0) {
bus_info->state.created = 1;
} else {
if (response != -CONTROLVM_RESP_ERROR_ALREADY_DONE)
/* undo the row we just created... */
- busdevices_del(&dev_info_list, bus_info->bus_no);
+ busdevices_del(&dev_info_list,
+ bus_info->chipset_bus_no);
}
bus_responder(CONTROLVM_BUS_CREATE, bus_info->pending_msg_hdr,
}
static void
-bus_destroy_response(struct visorchipset_bus_info *bus_info, int response)
+bus_destroy_response(struct visor_device *bus_info, int response)
{
bus_responder(CONTROLVM_BUS_DESTROY, bus_info->pending_msg_hdr,
response);
kfree(bus_info->pending_msg_hdr);
bus_info->pending_msg_hdr = NULL;
- bus_info_clear(bus_info);
- busdevices_del(&dev_info_list, bus_info->bus_no);
+ busdevices_del(&dev_info_list, bus_info->chipset_bus_no);
}
static void
}
bool
-visorchipset_get_bus_info(u32 bus_no, struct visorchipset_bus_info *bus_info)
-{
- void *p = bus_find(&bus_info_list, bus_no);
-
- if (!p)
- return false;
- memcpy(bus_info, p, sizeof(struct visorchipset_bus_info));
- return true;
-}
-EXPORT_SYMBOL_GPL(visorchipset_get_bus_info);
-
-bool
-visorchipset_set_bus_context(struct visorchipset_bus_info *p, void *context)
-{
- if (!p)
- return false;
- p->bus_driver_context = context;
- return true;
-}
-EXPORT_SYMBOL_GPL(visorchipset_set_bus_context);
-
-bool
visorchipset_get_device_info(u32 bus_no, u32 dev_no,
struct visorchipset_device_info *dev_info)
{