From d32517e392b90354f79f6c7a357f96c37b5fe4fd Mon Sep 17 00:00:00 2001 From: Don Zickus Date: Thu, 4 Jun 2015 09:22:41 -0400 Subject: [PATCH] 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: Don Zickus Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/visorbus.h | 3 + .../staging/unisys/visorbus/visorbus_main.c | 131 +++++++----------- .../unisys/visorbus/visorbus_private.h | 34 +---- .../staging/unisys/visorbus/visorchipset.c | 95 +++---------- 4 files changed, 77 insertions(+), 186 deletions(-) diff --git a/drivers/staging/unisys/include/visorbus.h b/drivers/staging/unisys/include/visorbus.h index c60f7d41f640..e7f99848fe1a 100644 --- a/drivers/staging/unisys/include/visorbus.h +++ b/drivers/staging/unisys/include/visorbus.h @@ -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 diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index ec3022b5af9b..60bdf69264df 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -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; + 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 @@ -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; - } - 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; @@ -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 diff --git a/drivers/staging/unisys/visorbus/visorbus_private.h b/drivers/staging/unisys/visorbus/visorbus_private.h index af71809828dd..6fd55af8926c 100644 --- a/drivers/staging/unisys/visorbus/visorbus_private.h +++ b/drivers/staging/unisys/visorbus/visorbus_private.h @@ -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 */ diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c index 618732b6e2e1..4404f4fadd7e 100644 --- a/drivers/staging/unisys/visorbus/visorchipset.c +++ b/drivers/staging/unisys/visorbus/visorchipset.c @@ -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 @@ cleanup: } 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) -- 2.20.1