diff options
Diffstat (limited to 'drivers/staging/hv/vmbus_drv.c')
-rw-r--r-- | drivers/staging/hv/vmbus_drv.c | 517 |
1 files changed, 212 insertions, 305 deletions
diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 84fdb64d3ceb..b473f468dd83 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -29,7 +29,7 @@ #include <linux/slab.h> #include <linux/completion.h> #include "version_info.h" -#include "osd.h" +#include "hv_api.h" #include "logging.h" #include "vmbus.h" #include "channel.h" @@ -42,19 +42,13 @@ /* Main vmbus driver data structure */ struct vmbus_driver_context { - /* !! These must be the first 2 fields !! */ - /* FIXME, this is a bug */ - /* The driver field is not used in here. Instead, the bus field is */ - /* used to represent the driver */ - struct driver_context drv_ctx; - struct hv_driver drv_obj; struct bus_type bus; struct tasklet_struct msg_dpc; struct tasklet_struct event_dpc; /* The bus root device */ - struct vm_device device_ctx; + struct hv_device device_ctx; }; static int vmbus_match(struct device *device, struct device_driver *driver); @@ -62,8 +56,6 @@ static int vmbus_probe(struct device *device); static int vmbus_remove(struct device *device); static void vmbus_shutdown(struct device *device); static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env); -static void vmbus_msg_dpc(unsigned long data); -static void vmbus_event_dpc(unsigned long data); static irqreturn_t vmbus_isr(int irq, void *dev_id); @@ -113,7 +105,7 @@ static struct device_attribute vmbus_device_attrs[] = { }; /* The one and only one */ -static struct vmbus_driver_context g_vmbus_drv = { +static struct vmbus_driver_context vmbus_drv = { .bus.name = "vmbus", .bus.match = vmbus_match, .bus.shutdown = vmbus_shutdown, @@ -123,14 +115,14 @@ static struct vmbus_driver_context g_vmbus_drv = { .bus.dev_attrs = vmbus_device_attrs, }; -static const char *gDriverName = "hyperv"; +static const char *driver_name = "hyperv"; /* * Windows vmbus does not defined this. * We defined this to be consistent with other devices */ /* {c5295816-f63a-4d5f-8d1a-4daf999ca185} */ -static const struct hv_guid gVmbusDeviceType = { +static const struct hv_guid device_type = { .data = { 0x16, 0x58, 0x29, 0xc5, 0x3a, 0xf6, 0x5f, 0x4d, 0x8d, 0x1a, 0x4d, 0xaf, 0x99, 0x9c, 0xa1, 0x85 @@ -138,35 +130,28 @@ static const struct hv_guid gVmbusDeviceType = { }; /* {ac3760fc-9adf-40aa-9427-a70ed6de95c5} */ -static const struct hv_guid gVmbusDeviceId = { +static const struct hv_guid device_id = { .data = { 0xfc, 0x60, 0x37, 0xac, 0xdf, 0x9a, 0xaa, 0x40, 0x94, 0x27, 0xa7, 0x0e, 0xd6, 0xde, 0x95, 0xc5 } }; -static struct hv_device *gDevice; /* vmbus root device */ +static struct hv_device *vmbus_device; /* vmbus root device */ -/* - * VmbusChildDeviceAdd - Registers the child device with the vmbus - */ -int VmbusChildDeviceAdd(struct hv_device *ChildDevice) -{ - return vmbus_child_device_register(gDevice, ChildDevice); -} /* - * VmbusOnDeviceAdd - Callback when the root bus device is added + * vmbus_dev_add - Callback when the root bus device is added */ -static int VmbusOnDeviceAdd(struct hv_device *dev, void *AdditionalInfo) +static int vmbus_dev_add(struct hv_device *dev, void *info) { - u32 *irqvector = AdditionalInfo; + u32 *irqvector = info; int ret; - gDevice = dev; + vmbus_device = dev; - memcpy(&gDevice->deviceType, &gVmbusDeviceType, sizeof(struct hv_guid)); - memcpy(&gDevice->deviceInstance, &gVmbusDeviceId, + memcpy(&vmbus_device->dev_type, &device_type, sizeof(struct hv_guid)); + memcpy(&vmbus_device->dev_instance, &device_id, sizeof(struct hv_guid)); /* strcpy(dev->name, "vmbus"); */ @@ -174,34 +159,12 @@ static int VmbusOnDeviceAdd(struct hv_device *dev, void *AdditionalInfo) on_each_cpu(hv_synic_init, (void *)irqvector, 1); /* Connect to VMBus in the root partition */ - ret = VmbusConnect(); + ret = vmbus_connect(); /* VmbusSendEvent(device->localPortId+1); */ return ret; } -/* - * VmbusOnDeviceRemove - Callback when the root bus device is removed - */ -static int VmbusOnDeviceRemove(struct hv_device *dev) -{ - int ret = 0; - - vmbus_release_unattached_channels(); - VmbusDisconnect(); - on_each_cpu(hv_synic_cleanup, NULL, 1); - return ret; -} - -/* - * VmbusOnCleanup - Perform any cleanup when the driver is removed - */ -static void VmbusOnCleanup(struct hv_driver *drv) -{ - /* struct vmbus_driver *driver = (struct vmbus_driver *)drv; */ - - hv_cleanup(); -} struct onmessage_work_context { struct work_struct work; @@ -221,7 +184,7 @@ static void vmbus_onmessage_work(struct work_struct *work) /* * vmbus_on_msg_dpc - DPC routine to handle messages from the hypervisior */ -static void vmbus_on_msg_dpc(struct hv_driver *drv) +static void vmbus_on_msg_dpc(unsigned long data) { int cpu = smp_processor_id(); void *page_addr = hv_context.synic_message_page[cpu]; @@ -239,7 +202,7 @@ static void vmbus_on_msg_dpc(struct hv_driver *drv) continue; INIT_WORK(&ctx->work, vmbus_onmessage_work); memcpy(&ctx->msg, msg, sizeof(*msg)); - queue_work(gVmbusConnection.WorkQueue, &ctx->work); + queue_work(vmbus_connection.work_queue, &ctx->work); } msg->header.message_type = HVMSG_NONE; @@ -267,7 +230,7 @@ static void vmbus_on_msg_dpc(struct hv_driver *drv) /* * vmbus_on_isr - ISR routine */ -static int vmbus_on_isr(struct hv_driver *drv) +static int vmbus_on_isr(void) { int ret = 0; int cpu = smp_processor_id(); @@ -309,37 +272,38 @@ static void get_channel_info(struct hv_device *device, vmbus_get_debug_info(device->channel, &debug_info); - info->ChannelId = debug_info.relid; - info->ChannelState = debug_info.state; - memcpy(&info->ChannelType, &debug_info.interfacetype, + info->chn_id = debug_info.relid; + info->chn_state = debug_info.state; + memcpy(&info->chn_type, &debug_info.interfacetype, sizeof(struct hv_guid)); - memcpy(&info->ChannelInstance, &debug_info.interface_instance, + memcpy(&info->chn_instance, &debug_info.interface_instance, sizeof(struct hv_guid)); - info->MonitorId = debug_info.monitorid; + info->monitor_id = debug_info.monitorid; - info->ServerMonitorPending = debug_info.servermonitor_pending; - info->ServerMonitorLatency = debug_info.servermonitor_latency; - info->ServerMonitorConnectionId = debug_info.servermonitor_connectionid; + info->server_monitor_pending = debug_info.servermonitor_pending; + info->server_monitor_latency = debug_info.servermonitor_latency; + info->server_monitor_conn_id = debug_info.servermonitor_connectionid; - info->ClientMonitorPending = debug_info.clientmonitor_pending; - info->ClientMonitorLatency = debug_info.clientmonitor_latency; - info->ClientMonitorConnectionId = debug_info.clientmonitor_connectionid; + info->client_monitor_pending = debug_info.clientmonitor_pending; + info->client_monitor_latency = debug_info.clientmonitor_latency; + info->client_monitor_conn_id = debug_info.clientmonitor_connectionid; - info->Inbound.InterruptMask = debug_info.inbound.current_interrupt_mask; - info->Inbound.ReadIndex = debug_info.inbound.current_read_index; - info->Inbound.WriteIndex = debug_info.inbound.current_write_index; - info->Inbound.BytesAvailToRead = debug_info.inbound.bytes_avail_toread; - info->Inbound.BytesAvailToWrite = + info->inbound.int_mask = debug_info.inbound.current_interrupt_mask; + info->inbound.read_idx = debug_info.inbound.current_read_index; + info->inbound.write_idx = debug_info.inbound.current_write_index; + info->inbound.bytes_avail_toread = + debug_info.inbound.bytes_avail_toread; + info->inbound.bytes_avail_towrite = debug_info.inbound.bytes_avail_towrite; - info->Outbound.InterruptMask = + info->outbound.int_mask = debug_info.outbound.current_interrupt_mask; - info->Outbound.ReadIndex = debug_info.outbound.current_read_index; - info->Outbound.WriteIndex = debug_info.outbound.current_write_index; - info->Outbound.BytesAvailToRead = + info->outbound.read_idx = debug_info.outbound.current_read_index; + info->outbound.write_idx = debug_info.outbound.current_write_index; + info->outbound.bytes_avail_toread = debug_info.outbound.bytes_avail_toread; - info->Outbound.BytesAvailToWrite = + info->outbound.bytes_avail_towrite = debug_info.outbound.bytes_avail_towrite; } @@ -353,95 +317,95 @@ static ssize_t vmbus_show_device_attr(struct device *dev, struct device_attribute *dev_attr, char *buf) { - struct vm_device *device_ctx = device_to_vm_device(dev); + struct hv_device *device_ctx = device_to_hv_device(dev); struct hv_device_info device_info; memset(&device_info, 0, sizeof(struct hv_device_info)); - get_channel_info(&device_ctx->device_obj, &device_info); + get_channel_info(device_ctx, &device_info); if (!strcmp(dev_attr->attr.name, "class_id")) { return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-" "%02x%02x%02x%02x%02x%02x%02x%02x}\n", - device_info.ChannelType.data[3], - device_info.ChannelType.data[2], - device_info.ChannelType.data[1], - device_info.ChannelType.data[0], - device_info.ChannelType.data[5], - device_info.ChannelType.data[4], - device_info.ChannelType.data[7], - device_info.ChannelType.data[6], - device_info.ChannelType.data[8], - device_info.ChannelType.data[9], - device_info.ChannelType.data[10], - device_info.ChannelType.data[11], - device_info.ChannelType.data[12], - device_info.ChannelType.data[13], - device_info.ChannelType.data[14], - device_info.ChannelType.data[15]); + device_info.chn_type.data[3], + device_info.chn_type.data[2], + device_info.chn_type.data[1], + device_info.chn_type.data[0], + device_info.chn_type.data[5], + device_info.chn_type.data[4], + device_info.chn_type.data[7], + device_info.chn_type.data[6], + device_info.chn_type.data[8], + device_info.chn_type.data[9], + device_info.chn_type.data[10], + device_info.chn_type.data[11], + device_info.chn_type.data[12], + device_info.chn_type.data[13], + device_info.chn_type.data[14], + device_info.chn_type.data[15]); } else if (!strcmp(dev_attr->attr.name, "device_id")) { return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-" "%02x%02x%02x%02x%02x%02x%02x%02x}\n", - device_info.ChannelInstance.data[3], - device_info.ChannelInstance.data[2], - device_info.ChannelInstance.data[1], - device_info.ChannelInstance.data[0], - device_info.ChannelInstance.data[5], - device_info.ChannelInstance.data[4], - device_info.ChannelInstance.data[7], - device_info.ChannelInstance.data[6], - device_info.ChannelInstance.data[8], - device_info.ChannelInstance.data[9], - device_info.ChannelInstance.data[10], - device_info.ChannelInstance.data[11], - device_info.ChannelInstance.data[12], - device_info.ChannelInstance.data[13], - device_info.ChannelInstance.data[14], - device_info.ChannelInstance.data[15]); + device_info.chn_instance.data[3], + device_info.chn_instance.data[2], + device_info.chn_instance.data[1], + device_info.chn_instance.data[0], + device_info.chn_instance.data[5], + device_info.chn_instance.data[4], + device_info.chn_instance.data[7], + device_info.chn_instance.data[6], + device_info.chn_instance.data[8], + device_info.chn_instance.data[9], + device_info.chn_instance.data[10], + device_info.chn_instance.data[11], + device_info.chn_instance.data[12], + device_info.chn_instance.data[13], + device_info.chn_instance.data[14], + device_info.chn_instance.data[15]); } else if (!strcmp(dev_attr->attr.name, "state")) { - return sprintf(buf, "%d\n", device_info.ChannelState); + return sprintf(buf, "%d\n", device_info.chn_state); } else if (!strcmp(dev_attr->attr.name, "id")) { - return sprintf(buf, "%d\n", device_info.ChannelId); + return sprintf(buf, "%d\n", device_info.chn_id); } else if (!strcmp(dev_attr->attr.name, "out_intr_mask")) { - return sprintf(buf, "%d\n", device_info.Outbound.InterruptMask); + return sprintf(buf, "%d\n", device_info.outbound.int_mask); } else if (!strcmp(dev_attr->attr.name, "out_read_index")) { - return sprintf(buf, "%d\n", device_info.Outbound.ReadIndex); + return sprintf(buf, "%d\n", device_info.outbound.read_idx); } else if (!strcmp(dev_attr->attr.name, "out_write_index")) { - return sprintf(buf, "%d\n", device_info.Outbound.WriteIndex); + return sprintf(buf, "%d\n", device_info.outbound.write_idx); } else if (!strcmp(dev_attr->attr.name, "out_read_bytes_avail")) { return sprintf(buf, "%d\n", - device_info.Outbound.BytesAvailToRead); + device_info.outbound.bytes_avail_toread); } else if (!strcmp(dev_attr->attr.name, "out_write_bytes_avail")) { return sprintf(buf, "%d\n", - device_info.Outbound.BytesAvailToWrite); + device_info.outbound.bytes_avail_towrite); } else if (!strcmp(dev_attr->attr.name, "in_intr_mask")) { - return sprintf(buf, "%d\n", device_info.Inbound.InterruptMask); + return sprintf(buf, "%d\n", device_info.inbound.int_mask); } else if (!strcmp(dev_attr->attr.name, "in_read_index")) { - return sprintf(buf, "%d\n", device_info.Inbound.ReadIndex); + return sprintf(buf, "%d\n", device_info.inbound.read_idx); } else if (!strcmp(dev_attr->attr.name, "in_write_index")) { - return sprintf(buf, "%d\n", device_info.Inbound.WriteIndex); + return sprintf(buf, "%d\n", device_info.inbound.write_idx); } else if (!strcmp(dev_attr->attr.name, "in_read_bytes_avail")) { return sprintf(buf, "%d\n", - device_info.Inbound.BytesAvailToRead); + device_info.inbound.bytes_avail_toread); } else if (!strcmp(dev_attr->attr.name, "in_write_bytes_avail")) { return sprintf(buf, "%d\n", - device_info.Inbound.BytesAvailToWrite); + device_info.inbound.bytes_avail_towrite); } else if (!strcmp(dev_attr->attr.name, "monitor_id")) { - return sprintf(buf, "%d\n", device_info.MonitorId); + return sprintf(buf, "%d\n", device_info.monitor_id); } else if (!strcmp(dev_attr->attr.name, "server_monitor_pending")) { - return sprintf(buf, "%d\n", device_info.ServerMonitorPending); + return sprintf(buf, "%d\n", device_info.server_monitor_pending); } else if (!strcmp(dev_attr->attr.name, "server_monitor_latency")) { - return sprintf(buf, "%d\n", device_info.ServerMonitorLatency); + return sprintf(buf, "%d\n", device_info.server_monitor_latency); } else if (!strcmp(dev_attr->attr.name, "server_monitor_conn_id")) { return sprintf(buf, "%d\n", - device_info.ServerMonitorConnectionId); + device_info.server_monitor_conn_id); } else if (!strcmp(dev_attr->attr.name, "client_monitor_pending")) { - return sprintf(buf, "%d\n", device_info.ClientMonitorPending); + return sprintf(buf, "%d\n", device_info.client_monitor_pending); } else if (!strcmp(dev_attr->attr.name, "client_monitor_latency")) { - return sprintf(buf, "%d\n", device_info.ClientMonitorLatency); + return sprintf(buf, "%d\n", device_info.client_monitor_latency); } else if (!strcmp(dev_attr->attr.name, "client_monitor_conn_id")) { return sprintf(buf, "%d\n", - device_info.ClientMonitorConnectionId); + device_info.client_monitor_conn_id); } else { return 0; } @@ -461,9 +425,8 @@ static ssize_t vmbus_show_device_attr(struct device *dev, */ static int vmbus_bus_init(void) { - struct vmbus_driver_context *vmbus_drv_ctx = &g_vmbus_drv; - struct hv_driver *driver = &g_vmbus_drv.drv_obj; - struct vm_device *dev_ctx = &g_vmbus_drv.device_ctx; + struct vmbus_driver_context *vmbus_drv_ctx = &vmbus_drv; + struct hv_device *dev_ctx = &vmbus_drv.device_ctx; int ret; unsigned int vector; @@ -478,13 +441,6 @@ static int vmbus_bus_init(void) sizeof(struct vmbus_channel_packet_page_buffer), sizeof(struct vmbus_channel_packet_multipage_buffer)); - driver->name = gDriverName; - memcpy(&driver->deviceType, &gVmbusDeviceType, sizeof(struct hv_guid)); - - /* Setup dispatch table */ - driver->OnDeviceAdd = VmbusOnDeviceAdd; - driver->OnDeviceRemove = VmbusOnDeviceRemove; - driver->OnCleanup = VmbusOnCleanup; /* Hypervisor initialization...setup hypercall page..etc */ ret = hv_init(); @@ -494,22 +450,16 @@ static int vmbus_bus_init(void) goto cleanup; } - /* Sanity checks */ - if (!driver->OnDeviceAdd) { - DPRINT_ERR(VMBUS_DRV, "OnDeviceAdd() routine not set"); - ret = -1; - goto cleanup; - } - vmbus_drv_ctx->bus.name = driver->name; + vmbus_drv_ctx->bus.name = driver_name; /* Initialize the bus context */ - tasklet_init(&vmbus_drv_ctx->msg_dpc, vmbus_msg_dpc, - (unsigned long)driver); - tasklet_init(&vmbus_drv_ctx->event_dpc, vmbus_event_dpc, - (unsigned long)driver); + tasklet_init(&vmbus_drv_ctx->msg_dpc, vmbus_on_msg_dpc, + (unsigned long)NULL); + tasklet_init(&vmbus_drv_ctx->event_dpc, vmbus_on_event, + (unsigned long)NULL); - /* Now, register the bus driver with LDM */ + /* Now, register the bus with LDM */ ret = bus_register(&vmbus_drv_ctx->bus); if (ret) { ret = -1; @@ -518,7 +468,7 @@ static int vmbus_bus_init(void) /* Get the interrupt resource */ ret = request_irq(vmbus_irq, vmbus_isr, IRQF_SAMPLE_RANDOM, - driver->name, NULL); + driver_name, NULL); if (ret != 0) { DPRINT_ERR(VMBUS_DRV, "ERROR - Unable to request IRQ %d", @@ -533,10 +483,10 @@ static int vmbus_bus_init(void) DPRINT_INFO(VMBUS_DRV, "irq 0x%x vector 0x%x", vmbus_irq, vector); - /* Call to bus driver to add the root device */ - memset(dev_ctx, 0, sizeof(struct vm_device)); + /* Add the root device */ + memset(dev_ctx, 0, sizeof(struct hv_device)); - ret = driver->OnDeviceAdd(&dev_ctx->device_obj, &vector); + ret = vmbus_dev_add(dev_ctx, &vector); if (ret != 0) { DPRINT_ERR(VMBUS_DRV, "ERROR - Unable to add vmbus root device"); @@ -550,10 +500,6 @@ static int vmbus_bus_init(void) } /* strcpy(dev_ctx->device.bus_id, dev_ctx->device_obj.name); */ dev_set_name(&dev_ctx->device, "vmbus_0_0"); - memcpy(&dev_ctx->class_id, &dev_ctx->device_obj.deviceType, - sizeof(struct hv_guid)); - memcpy(&dev_ctx->device_id, &dev_ctx->device_obj.deviceInstance, - sizeof(struct hv_guid)); /* No need to bind a driver to the root device. */ dev_ctx->device.parent = NULL; @@ -563,7 +509,7 @@ static int vmbus_bus_init(void) /* Setup the device dispatch table */ dev_ctx->device.release = vmbus_bus_release; - /* Setup the bus as root device */ + /* register the root device */ ret = device_register(&dev_ctx->device); if (ret) { DPRINT_ERR(VMBUS_DRV, @@ -590,17 +536,15 @@ cleanup: */ static void vmbus_bus_exit(void) { - struct hv_driver *driver = &g_vmbus_drv.drv_obj; - struct vmbus_driver_context *vmbus_drv_ctx = &g_vmbus_drv; + struct vmbus_driver_context *vmbus_drv_ctx = &vmbus_drv; - struct vm_device *dev_ctx = &g_vmbus_drv.device_ctx; + struct hv_device *dev_ctx = &vmbus_drv.device_ctx; - /* Remove the root device */ - if (driver->OnDeviceRemove) - driver->OnDeviceRemove(&dev_ctx->device_obj); + vmbus_release_unattached_channels(); + vmbus_disconnect(); + on_each_cpu(hv_synic_cleanup, NULL, 1); - if (driver->OnCleanup) - driver->OnCleanup(driver); + hv_cleanup(); /* Unregister the root bus device */ device_unregister(&dev_ctx->device); @@ -616,9 +560,8 @@ static void vmbus_bus_exit(void) /** * vmbus_child_driver_register() - Register a vmbus's child driver - * @driver_ctx: Pointer to driver structure you want to register + * @drv: Pointer to driver structure you want to register * - * @driver_ctx is of type &struct driver_context * * Registers the given driver with Linux through the 'driver_register()' call * And sets up the hyper-v vmbus handling for this driver. @@ -626,17 +569,17 @@ static void vmbus_bus_exit(void) * * Mainly used by Hyper-V drivers. */ -int vmbus_child_driver_register(struct driver_context *driver_ctx) +int vmbus_child_driver_register(struct device_driver *drv) { int ret; DPRINT_INFO(VMBUS_DRV, "child driver (%p) registering - name %s", - driver_ctx, driver_ctx->driver.name); + drv, drv->name); /* The child driver on this vmbus */ - driver_ctx->driver.bus = &g_vmbus_drv.bus; + drv->bus = &vmbus_drv.bus; - ret = driver_register(&driver_ctx->driver); + ret = driver_register(drv); vmbus_request_offers(); @@ -646,23 +589,22 @@ EXPORT_SYMBOL(vmbus_child_driver_register); /** * vmbus_child_driver_unregister() - Unregister a vmbus's child driver - * @driver_ctx: Pointer to driver structure you want to un-register + * @drv: Pointer to driver structure you want to un-register * - * @driver_ctx is of type &struct driver_context * * Un-register the given driver with Linux through the 'driver_unregister()' * call. And ungegisters the driver from the Hyper-V vmbus handler. * * Mainly used by Hyper-V drivers. */ -void vmbus_child_driver_unregister(struct driver_context *driver_ctx) +void vmbus_child_driver_unregister(struct device_driver *drv) { DPRINT_INFO(VMBUS_DRV, "child driver (%p) unregistering - name %s", - driver_ctx, driver_ctx->driver.name); + drv, drv->name); - driver_unregister(&driver_ctx->driver); + driver_unregister(drv); - driver_ctx->driver.bus = NULL; + drv->bus = NULL; } EXPORT_SYMBOL(vmbus_child_driver_unregister); @@ -674,12 +616,11 @@ struct hv_device *vmbus_child_device_create(struct hv_guid *type, struct hv_guid *instance, struct vmbus_channel *channel) { - struct vm_device *child_device_ctx; struct hv_device *child_device_obj; /* Allocate the new child device */ - child_device_ctx = kzalloc(sizeof(struct vm_device), GFP_KERNEL); - if (!child_device_ctx) { + child_device_obj = kzalloc(sizeof(struct hv_device), GFP_KERNEL); + if (!child_device_obj) { DPRINT_ERR(VMBUS_DRV, "unable to allocate device_context for child device"); return NULL; @@ -690,7 +631,7 @@ struct hv_device *vmbus_child_device_create(struct hv_guid *type, "%02x%02x%02x%02x%02x%02x%02x%02x}," "id {%02x%02x%02x%02x-%02x%02x-%02x%02x-" "%02x%02x%02x%02x%02x%02x%02x%02x}", - &child_device_ctx->device, + &child_device_obj->device, type->data[3], type->data[2], type->data[1], type->data[0], type->data[5], type->data[4], type->data[7], type->data[6], type->data[8], type->data[9], type->data[10], type->data[11], @@ -704,58 +645,51 @@ struct hv_device *vmbus_child_device_create(struct hv_guid *type, instance->data[12], instance->data[13], instance->data[14], instance->data[15]); - child_device_obj = &child_device_ctx->device_obj; child_device_obj->channel = channel; - memcpy(&child_device_obj->deviceType, type, sizeof(struct hv_guid)); - memcpy(&child_device_obj->deviceInstance, instance, + memcpy(&child_device_obj->dev_type, type, sizeof(struct hv_guid)); + memcpy(&child_device_obj->dev_instance, instance, sizeof(struct hv_guid)); - memcpy(&child_device_ctx->class_id, type, sizeof(struct hv_guid)); - memcpy(&child_device_ctx->device_id, instance, sizeof(struct hv_guid)); return child_device_obj; } /* - * vmbus_child_device_register - Register the child device on the specified bus + * vmbus_child_device_register - Register the child device */ -int vmbus_child_device_register(struct hv_device *root_device_obj, - struct hv_device *child_device_obj) +int vmbus_child_device_register(struct hv_device *child_device_obj) { int ret = 0; - struct vm_device *root_device_ctx = - to_vm_device(root_device_obj); - struct vm_device *child_device_ctx = - to_vm_device(child_device_obj); + static atomic_t device_num = ATOMIC_INIT(0); DPRINT_DBG(VMBUS_DRV, "child device (%p) registering", - child_device_ctx); + child_device_obj); /* Set the device name. Otherwise, device_register() will fail. */ - dev_set_name(&child_device_ctx->device, "vmbus_0_%d", + dev_set_name(&child_device_obj->device, "vmbus_0_%d", atomic_inc_return(&device_num)); /* The new device belongs to this bus */ - child_device_ctx->device.bus = &g_vmbus_drv.bus; /* device->dev.bus; */ - child_device_ctx->device.parent = &root_device_ctx->device; - child_device_ctx->device.release = vmbus_device_release; + child_device_obj->device.bus = &vmbus_drv.bus; /* device->dev.bus; */ + child_device_obj->device.parent = &vmbus_device->device; + child_device_obj->device.release = vmbus_device_release; /* * Register with the LDM. This will kick off the driver/device * binding...which will eventually call vmbus_match() and vmbus_probe() */ - ret = device_register(&child_device_ctx->device); + ret = device_register(&child_device_obj->device); /* vmbus_probe() error does not get propergate to device_register(). */ - ret = child_device_ctx->probe_error; + ret = child_device_obj->probe_error; if (ret) DPRINT_ERR(VMBUS_DRV, "unable to register child device (%p)", - &child_device_ctx->device); + &child_device_obj->device); else DPRINT_INFO(VMBUS_DRV, "child device (%p) registered", - &child_device_ctx->device); + &child_device_obj->device); return ret; } @@ -766,19 +700,18 @@ int vmbus_child_device_register(struct hv_device *root_device_obj, */ void vmbus_child_device_unregister(struct hv_device *device_obj) { - struct vm_device *device_ctx = to_vm_device(device_obj); DPRINT_INFO(VMBUS_DRV, "unregistering child device (%p)", - &device_ctx->device); + &device_obj->device); /* * Kick off the process of unregistering the device. * This will call vmbus_remove() and eventually vmbus_device_release() */ - device_unregister(&device_ctx->device); + device_unregister(&device_obj->device); DPRINT_INFO(VMBUS_DRV, "child device (%p) unregistered", - &device_ctx->device); + &device_obj->device); } /* @@ -790,43 +723,43 @@ void vmbus_child_device_unregister(struct hv_device *device_obj) */ static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env) { - struct vm_device *device_ctx = device_to_vm_device(device); + struct hv_device *dev = device_to_hv_device(device); int ret; DPRINT_INFO(VMBUS_DRV, "generating uevent - VMBUS_DEVICE_CLASS_GUID={" "%02x%02x%02x%02x-%02x%02x-%02x%02x-" "%02x%02x%02x%02x%02x%02x%02x%02x}", - device_ctx->class_id.data[3], device_ctx->class_id.data[2], - device_ctx->class_id.data[1], device_ctx->class_id.data[0], - device_ctx->class_id.data[5], device_ctx->class_id.data[4], - device_ctx->class_id.data[7], device_ctx->class_id.data[6], - device_ctx->class_id.data[8], device_ctx->class_id.data[9], - device_ctx->class_id.data[10], - device_ctx->class_id.data[11], - device_ctx->class_id.data[12], - device_ctx->class_id.data[13], - device_ctx->class_id.data[14], - device_ctx->class_id.data[15]); + dev->dev_type.data[3], dev->dev_type.data[2], + dev->dev_type.data[1], dev->dev_type.data[0], + dev->dev_type.data[5], dev->dev_type.data[4], + dev->dev_type.data[7], dev->dev_type.data[6], + dev->dev_type.data[8], dev->dev_type.data[9], + dev->dev_type.data[10], + dev->dev_type.data[11], + dev->dev_type.data[12], + dev->dev_type.data[13], + dev->dev_type.data[14], + dev->dev_type.data[15]); ret = add_uevent_var(env, "VMBUS_DEVICE_CLASS_GUID={" "%02x%02x%02x%02x-%02x%02x-%02x%02x-" "%02x%02x%02x%02x%02x%02x%02x%02x}", - device_ctx->class_id.data[3], - device_ctx->class_id.data[2], - device_ctx->class_id.data[1], - device_ctx->class_id.data[0], - device_ctx->class_id.data[5], - device_ctx->class_id.data[4], - device_ctx->class_id.data[7], - device_ctx->class_id.data[6], - device_ctx->class_id.data[8], - device_ctx->class_id.data[9], - device_ctx->class_id.data[10], - device_ctx->class_id.data[11], - device_ctx->class_id.data[12], - device_ctx->class_id.data[13], - device_ctx->class_id.data[14], - device_ctx->class_id.data[15]); + dev->dev_type.data[3], + dev->dev_type.data[2], + dev->dev_type.data[1], + dev->dev_type.data[0], + dev->dev_type.data[5], + dev->dev_type.data[4], + dev->dev_type.data[7], + dev->dev_type.data[6], + dev->dev_type.data[8], + dev->dev_type.data[9], + dev->dev_type.data[10], + dev->dev_type.data[11], + dev->dev_type.data[12], + dev->dev_type.data[13], + dev->dev_type.data[14], + dev->dev_type.data[15]); if (ret) return ret; @@ -834,22 +767,22 @@ static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env) ret = add_uevent_var(env, "VMBUS_DEVICE_DEVICE_GUID={" "%02x%02x%02x%02x-%02x%02x-%02x%02x-" "%02x%02x%02x%02x%02x%02x%02x%02x}", - device_ctx->device_id.data[3], - device_ctx->device_id.data[2], - device_ctx->device_id.data[1], - device_ctx->device_id.data[0], - device_ctx->device_id.data[5], - device_ctx->device_id.data[4], - device_ctx->device_id.data[7], - device_ctx->device_id.data[6], - device_ctx->device_id.data[8], - device_ctx->device_id.data[9], - device_ctx->device_id.data[10], - device_ctx->device_id.data[11], - device_ctx->device_id.data[12], - device_ctx->device_id.data[13], - device_ctx->device_id.data[14], - device_ctx->device_id.data[15]); + dev->dev_instance.data[3], + dev->dev_instance.data[2], + dev->dev_instance.data[1], + dev->dev_instance.data[0], + dev->dev_instance.data[5], + dev->dev_instance.data[4], + dev->dev_instance.data[7], + dev->dev_instance.data[6], + dev->dev_instance.data[8], + dev->dev_instance.data[9], + dev->dev_instance.data[10], + dev->dev_instance.data[11], + dev->dev_instance.data[12], + dev->dev_instance.data[13], + dev->dev_instance.data[14], + dev->dev_instance.data[15]); if (ret) return ret; @@ -862,24 +795,18 @@ static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env) static int vmbus_match(struct device *device, struct device_driver *driver) { int match = 0; - struct driver_context *driver_ctx = driver_to_driver_context(driver); - struct vm_device *device_ctx = device_to_vm_device(device); + struct hv_driver *drv = drv_to_hv_drv(driver); + struct hv_device *device_ctx = device_to_hv_device(device); /* We found our driver ? */ - if (memcmp(&device_ctx->class_id, &driver_ctx->class_id, + if (memcmp(&device_ctx->dev_type, &drv->dev_type, sizeof(struct hv_guid)) == 0) { - /* - * !! NOTE: The driver_ctx is not a vmbus_drv_ctx. We typecast - * it here to access the struct hv_driver field - */ - struct vmbus_driver_context *vmbus_drv_ctx = - (struct vmbus_driver_context *)driver_ctx; - device_ctx->device_obj.Driver = &vmbus_drv_ctx->drv_obj; + device_ctx->drv = drv->priv; DPRINT_INFO(VMBUS_DRV, "device object (%p) set to driver object (%p)", - &device_ctx->device_obj, - device_ctx->device_obj.Driver); + &device_ctx, + device_ctx->drv); match = 1; } @@ -895,7 +822,7 @@ static int vmbus_match(struct device *device, struct device_driver *driver) */ static void vmbus_probe_failed_cb(struct work_struct *context) { - struct vm_device *device_ctx = (struct vm_device *)context; + struct hv_device *device_ctx = (struct hv_device *)context; /* * Kick off the process of unregistering the device. @@ -912,23 +839,23 @@ static void vmbus_probe_failed_cb(struct work_struct *context) static int vmbus_probe(struct device *child_device) { int ret = 0; - struct driver_context *driver_ctx = - driver_to_driver_context(child_device->driver); - struct vm_device *device_ctx = - device_to_vm_device(child_device); + struct hv_driver *drv = + drv_to_hv_drv(child_device->driver); + struct hv_device *dev = device_to_hv_device(child_device); /* Let the specific open-source driver handles the probe if it can */ - if (driver_ctx->probe) { - ret = device_ctx->probe_error = driver_ctx->probe(child_device); + if (drv->driver.probe) { + ret = dev->probe_error = + drv->driver.probe(child_device); if (ret != 0) { DPRINT_ERR(VMBUS_DRV, "probe() failed for device %s " "(%p) on driver %s (%d)...", dev_name(child_device), child_device, child_device->driver->name, ret); - INIT_WORK(&device_ctx->probe_failed_work_item, + INIT_WORK(&dev->probe_failed_work_item, vmbus_probe_failed_cb); - schedule_work(&device_ctx->probe_failed_work_item); + schedule_work(&dev->probe_failed_work_item); } } else { DPRINT_ERR(VMBUS_DRV, "probe() method not set for driver - %s", @@ -944,7 +871,7 @@ static int vmbus_probe(struct device *child_device) static int vmbus_remove(struct device *child_device) { int ret; - struct driver_context *driver_ctx; + struct hv_driver *drv; /* Special case root bus device */ if (child_device->parent == NULL) { @@ -956,14 +883,14 @@ static int vmbus_remove(struct device *child_device) } if (child_device->driver) { - driver_ctx = driver_to_driver_context(child_device->driver); + drv = drv_to_hv_drv(child_device->driver); /* * Let the specific open-source driver handles the removal if * it can */ - if (driver_ctx->remove) { - ret = driver_ctx->remove(child_device); + if (drv->driver.remove) { + ret = drv->driver.remove(child_device); } else { DPRINT_ERR(VMBUS_DRV, "remove() method not set for driver - %s", @@ -980,7 +907,7 @@ static int vmbus_remove(struct device *child_device) */ static void vmbus_shutdown(struct device *child_device) { - struct driver_context *driver_ctx; + struct hv_driver *drv; /* Special case root bus device */ if (child_device->parent == NULL) { @@ -995,11 +922,11 @@ static void vmbus_shutdown(struct device *child_device) if (!child_device->driver) return; - driver_ctx = driver_to_driver_context(child_device->driver); + drv = drv_to_hv_drv(child_device->driver); /* Let the specific open-source driver handles the removal if it can */ - if (driver_ctx->shutdown) - driver_ctx->shutdown(child_device); + if (drv->driver.shutdown) + drv->driver.shutdown(child_device); return; } @@ -1021,48 +948,28 @@ static void vmbus_bus_release(struct device *device) */ static void vmbus_device_release(struct device *device) { - struct vm_device *device_ctx = device_to_vm_device(device); + struct hv_device *device_ctx = device_to_hv_device(device); kfree(device_ctx); /* !!DO NOT REFERENCE device_ctx anymore at this point!! */ } -/* - * vmbus_msg_dpc - Tasklet routine to handle hypervisor messages - */ -static void vmbus_msg_dpc(unsigned long data) -{ - struct hv_driver *driver = (struct hv_driver *)data; - - /* Call to bus driver to handle interrupt */ - vmbus_on_msg_dpc(driver); -} -/* - * vmbus_event_dpc - Tasklet routine to handle hypervisor events - */ -static void vmbus_event_dpc(unsigned long data) -{ - /* Call to bus driver to handle interrupt */ - VmbusOnEvents(); -} static irqreturn_t vmbus_isr(int irq, void *dev_id) { - struct hv_driver *driver = &g_vmbus_drv.drv_obj; int ret; - /* Call to bus driver to handle interrupt */ - ret = vmbus_on_isr(driver); + ret = vmbus_on_isr(); /* Schedules a dpc if necessary */ if (ret > 0) { if (test_bit(0, (unsigned long *)&ret)) - tasklet_schedule(&g_vmbus_drv.msg_dpc); + tasklet_schedule(&vmbus_drv.msg_dpc); if (test_bit(1, (unsigned long *)&ret)) - tasklet_schedule(&g_vmbus_drv.event_dpc); + tasklet_schedule(&vmbus_drv.event_dpc); return IRQ_HANDLED; } else { |