Commit d32517e3 authored by Don Zickus's avatar Don Zickus Committed by Greg Kroah-Hartman
Browse files

staging: unisys: Convert bus creation to use visor_device



This patch removes the legacy bus_info struct and instead creates
and passes around a traditional struct device.

This allows us to remove a lot of the various look up code and
removes the doubt if the struct exists or not.

Half of the churn is just the conversion of visorchipset_bus_info
to visor_device.  Various cleanups include re-arranging the failure
paths to make more sense.

Signed-off-by: default avatarDon Zickus <dzickus@redhat.com>
Signed-off-by: default avatarBenjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 65bd6e46
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -220,4 +220,7 @@ void visorchannel_debug(struct visorchannel *channel, int num_queues,
			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
+48 −83
Original line number Diff line number Diff line
@@ -93,8 +93,8 @@ static struct workqueue_struct *periodic_dev_workqueue;
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);
@@ -950,8 +950,7 @@ EXPORT_SYMBOL_GPL(visorbus_disable_channel_interrupts);
 */
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;
@@ -1161,8 +1160,7 @@ static void
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;
@@ -1174,17 +1172,14 @@ fix_vbus_dev_info(struct visor_device *visordev)
			return;

	hdr_info = (struct spar_vbus_headerinfo *)visordev->vbus_hdr_info;

	visordrv = to_visor_driver(visordev->device.driver);
	if (!visorchipset_get_bus_info(bus_no, &bus_info))
	if (!hdr_info)
		return;

	dev = (struct visor_device *)(bus_info.bus_driver_context);
	if (!dev)
	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
@@ -1203,51 +1198,45 @@ fix_vbus_dev_info(struct visor_device *visordev)
	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,
@@ -1259,16 +1248,11 @@ create_bus_instance(struct visorchipset_bus_info *bus_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;
}
@@ -1331,57 +1315,38 @@ remove_all_visor_devices(void)
}

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;
	}
	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;
@@ -1389,24 +1354,24 @@ chipset_device_create(struct visorchipset_device_info *dev_info)
	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
+6 −28
Original line number Diff line number Diff line
@@ -49,35 +49,13 @@ struct visorchipset_device_info {
	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);
@@ -91,8 +69,8 @@ struct visorchipset_busdev_notifiers {
 *      -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);
@@ -112,10 +90,10 @@ visorchipset_register_busdev(
			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 */
+20 −75
Original line number Diff line number Diff line
@@ -56,8 +56,6 @@
#define UNISYS_SPAR_ID_ECX 0x70537379
#define UNISYS_SPAR_ID_EDX 0x34367261

#define BUS_ROOT_DEVICE	UINT_MAX

/*
 * Module parameters
 */
@@ -230,8 +228,8 @@ static void parahotplug_process_list(void);
 */
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,
@@ -698,16 +696,6 @@ static ssize_t remaining_steps_store(struct device *dev,
	return count;
}

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)
{
@@ -756,19 +744,6 @@ struct visor_device *visorbus_get_device_by_id(u32 bus_no, u32 dev_no,
}
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)
{
@@ -842,15 +817,8 @@ EXPORT_SYMBOL_GPL(visorchipset_register_busdev);
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);
@@ -1017,7 +985,7 @@ device_responder(enum controlvm_id cmd_id,
}

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)
{
@@ -1207,10 +1175,10 @@ bus_create(struct controlvm_message *inmsg)
	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);
@@ -1225,8 +1193,8 @@ bus_create(struct controlvm_message *inmsg)
		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);

@@ -1244,7 +1212,6 @@ bus_create(struct controlvm_message *inmsg)
		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);

@@ -1258,10 +1225,10 @@ bus_destroy(struct controlvm_message *inmsg)
{
	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)
@@ -1269,6 +1236,8 @@ bus_destroy(struct controlvm_message *inmsg)

	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
@@ -1277,15 +1246,14 @@ bus_configure(struct controlvm_message *inmsg,
{
	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);
@@ -1305,7 +1273,6 @@ bus_configure(struct controlvm_message *inmsg,
		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);
	}
@@ -1320,7 +1287,7 @@ my_device_create(struct controlvm_message *inmsg)
	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;

@@ -1331,7 +1298,7 @@ my_device_create(struct controlvm_message *inmsg)
		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);
@@ -2134,14 +2101,15 @@ setup_crash_devices_work_queue(struct work_struct *work)
}

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,
@@ -2152,7 +2120,7 @@ bus_create_response(struct visorchipset_bus_info *bus_info, int response)
}

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);
@@ -2160,8 +2128,7 @@ bus_destroy_response(struct visorchipset_bus_info *bus_info, int 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
@@ -2212,28 +2179,6 @@ device_resume_response(struct visorchipset_device_info *dev_info, int response)
	dev_info->pending_msg_hdr = NULL;
}

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)