diff options
Diffstat (limited to 'sys/dev/hyperv/vmbus')
-rw-r--r-- | sys/dev/hyperv/vmbus/hv_channel.c | 4 | ||||
-rw-r--r-- | sys/dev/hyperv/vmbus/hv_channel_mgmt.c | 24 | ||||
-rw-r--r-- | sys/dev/hyperv/vmbus/hv_vmbus_priv.h | 9 | ||||
-rw-r--r-- | sys/dev/hyperv/vmbus/vmbus.c | 120 | ||||
-rw-r--r-- | sys/dev/hyperv/vmbus/vmbus_if.m | 10 |
5 files changed, 70 insertions, 97 deletions
diff --git a/sys/dev/hyperv/vmbus/hv_channel.c b/sys/dev/hyperv/vmbus/hv_channel.c index 9b9f684..a7d9de8 100644 --- a/sys/dev/hyperv/vmbus/hv_channel.c +++ b/sys/dev/hyperv/vmbus/hv_channel.c @@ -106,10 +106,10 @@ vmbus_channel_sysctl_create(hv_vmbus_channel* channel) hv_vmbus_channel* primary_ch = channel->primary_channel; if (primary_ch == NULL) { - dev = channel->device->device; + dev = channel->ch_dev; ch_id = channel->ch_id; } else { - dev = primary_ch->device->device; + dev = primary_ch->ch_dev; ch_id = primary_ch->ch_id; sub_ch_id = channel->ch_subidx; } diff --git a/sys/dev/hyperv/vmbus/hv_channel_mgmt.c b/sys/dev/hyperv/vmbus/hv_channel_mgmt.c index b6d0eac..54a61c7 100644 --- a/sys/dev/hyperv/vmbus/hv_channel_mgmt.c +++ b/sys/dev/hyperv/vmbus/hv_channel_mgmt.c @@ -165,7 +165,7 @@ vmbus_channel_process_offer(hv_vmbus_channel *new_channel) * It is a sub channel offer, process it. */ new_channel->primary_channel = channel; - new_channel->device = channel->device; + new_channel->ch_dev = channel->ch_dev; mtx_lock(&channel->sc_lock); TAILQ_INSERT_TAIL(&channel->sc_list_anchor, new_channel, sc_list_entry); @@ -209,19 +209,15 @@ vmbus_channel_process_offer(hv_vmbus_channel *new_channel) new_channel->state = HV_CHANNEL_OPEN_STATE; /* - * Start the process of binding this offer to the driver - * (We need to set the device field before calling - * hv_vmbus_child_device_add()) - */ - new_channel->device = hv_vmbus_child_device_create(new_channel); - - /* * Add the new device to the bus. This will kick off device-driver * binding which eventually invokes the device driver's AddDevice() * method. + * + * NOTE: + * Error is ignored here; don't have much to do if error really + * happens. */ - hv_vmbus_child_device_register(new_channel->vmbus_sc, - new_channel->device); + hv_vmbus_child_device_register(new_channel); } void @@ -368,8 +364,8 @@ vmbus_chan_detach_task(void *xchan, int pending __unused) struct hv_vmbus_channel *chan = xchan; if (HV_VMBUS_CHAN_ISPRIMARY(chan)) { - /* Only primary channel owns the hv_device */ - hv_vmbus_child_device_unregister(chan->device); + /* Only primary channel owns the device */ + hv_vmbus_child_device_unregister(chan); /* NOTE: DO NOT free primary channel for now */ } else { struct vmbus_softc *sc = chan->vmbus_sc; @@ -449,8 +445,8 @@ hv_vmbus_release_unattached_channels(struct vmbus_softc *sc) TAILQ_REMOVE(&sc->vmbus_chlist, channel, ch_link); if (HV_VMBUS_CHAN_ISPRIMARY(channel)) { - /* Only primary channel owns the hv_device */ - hv_vmbus_child_device_unregister(channel->device); + /* Only primary channel owns the device */ + hv_vmbus_child_device_unregister(channel); } hv_vmbus_free_vmbus_channel(channel); } diff --git a/sys/dev/hyperv/vmbus/hv_vmbus_priv.h b/sys/dev/hyperv/vmbus/hv_vmbus_priv.h index b6cb8f8..8997ae8 100644 --- a/sys/dev/hyperv/vmbus/hv_vmbus_priv.h +++ b/sys/dev/hyperv/vmbus/hv_vmbus_priv.h @@ -212,12 +212,9 @@ void hv_vmbus_free_vmbus_channel(hv_vmbus_channel *channel); void hv_vmbus_release_unattached_channels( struct vmbus_softc *); -struct hv_device* hv_vmbus_child_device_create( - struct hv_vmbus_channel *channel); - -void hv_vmbus_child_device_register(struct vmbus_softc *, - struct hv_device *child_dev); +int hv_vmbus_child_device_register( + struct hv_vmbus_channel *chan); int hv_vmbus_child_device_unregister( - struct hv_device *child_dev); + struct hv_vmbus_channel *chan); #endif /* __HYPERV_PRIV_H__ */ diff --git a/sys/dev/hyperv/vmbus/vmbus.c b/sys/dev/hyperv/vmbus/vmbus.c index 350e120..cd0fd24 100644 --- a/sys/dev/hyperv/vmbus/vmbus.c +++ b/sys/dev/hyperv/vmbus/vmbus.c @@ -1040,113 +1040,73 @@ vmbus_intr_teardown(struct vmbus_softc *sc) static int vmbus_read_ivar(device_t dev, device_t child, int index, uintptr_t *result) { - struct hv_device *child_dev_ctx = device_get_ivars(child); - - switch (index) { - case HV_VMBUS_IVAR_TYPE: - *result = (uintptr_t)&child_dev_ctx->class_id; - return (0); - - case HV_VMBUS_IVAR_INSTANCE: - *result = (uintptr_t)&child_dev_ctx->device_id; - return (0); - - case HV_VMBUS_IVAR_DEVCTX: - *result = (uintptr_t)child_dev_ctx; - return (0); - - case HV_VMBUS_IVAR_NODE: - *result = (uintptr_t)child_dev_ctx->device; - return (0); - } - return (ENOENT); -} - -static int -vmbus_write_ivar(device_t dev, device_t child, int index, uintptr_t value) -{ - switch (index) { - case HV_VMBUS_IVAR_TYPE: - case HV_VMBUS_IVAR_INSTANCE: - case HV_VMBUS_IVAR_DEVCTX: - case HV_VMBUS_IVAR_NODE: - /* read-only */ - return (EINVAL); - } return (ENOENT); } static int vmbus_child_pnpinfo_str(device_t dev, device_t child, char *buf, size_t buflen) { - struct hv_device *dev_ctx = device_get_ivars(child); + const struct hv_vmbus_channel *chan; char guidbuf[HYPERV_GUID_STRLEN]; - if (dev_ctx == NULL) + chan = vmbus_get_channel(child); + if (chan == NULL) { + /* Event timer device, which does not belong to a channel */ return (0); + } strlcat(buf, "classid=", buflen); - hyperv_guid2str(&dev_ctx->class_id, guidbuf, sizeof(guidbuf)); + hyperv_guid2str(&chan->ch_guid_type, guidbuf, sizeof(guidbuf)); strlcat(buf, guidbuf, buflen); strlcat(buf, " deviceid=", buflen); - hyperv_guid2str(&dev_ctx->device_id, guidbuf, sizeof(guidbuf)); + hyperv_guid2str(&chan->ch_guid_inst, guidbuf, sizeof(guidbuf)); strlcat(buf, guidbuf, buflen); return (0); } -struct hv_device * -hv_vmbus_child_device_create(struct hv_vmbus_channel *channel) -{ - hv_device *child_dev; - - /* - * Allocate the new child device - */ - child_dev = malloc(sizeof(hv_device), M_DEVBUF, M_WAITOK | M_ZERO); - - child_dev->channel = channel; - child_dev->class_id = channel->ch_guid_type; - child_dev->device_id = channel->ch_guid_inst; - - return (child_dev); -} - -void -hv_vmbus_child_device_register(struct vmbus_softc *sc, - struct hv_device *child_dev) +int +hv_vmbus_child_device_register(struct hv_vmbus_channel *chan) { - device_t child, parent; - - parent = sc->vmbus_dev; - if (bootverbose) { - char name[HYPERV_GUID_STRLEN]; - - hyperv_guid2str(&child_dev->class_id, name, sizeof(name)); - device_printf(parent, "add device, classid: %s\n", name); + struct vmbus_softc *sc = chan->vmbus_sc; + device_t parent = sc->vmbus_dev; + int error = 0; + + chan->ch_dev = device_add_child(parent, NULL, -1); + if (chan->ch_dev == NULL) { + device_printf(parent, "device_add_child for chan%u failed\n", + chan->ch_id); + error = ENXIO; + goto done; } + device_set_ivars(chan->ch_dev, chan); - child = device_add_child(parent, NULL, -1); - child_dev->device = child; - device_set_ivars(child, child_dev); - - /* New device was added to vmbus */ +done: + /* New device has been/should be added to vmbus. */ vmbus_scan_newdev(sc); + return error; } int -hv_vmbus_child_device_unregister(struct hv_device *child_dev) +hv_vmbus_child_device_unregister(struct hv_vmbus_channel *chan) { - int ret = 0; + int error; + + if (chan->ch_dev == NULL) { + /* Failed to add a device. */ + return 0; + } + /* * XXXKYS: Ensure that this is the opposite of * device_add_child() */ mtx_lock(&Giant); - ret = device_delete_child(vmbus_get_device(), child_dev->device); + error = device_delete_child(chan->vmbus_sc->vmbus_dev, chan->ch_dev); mtx_unlock(&Giant); - return(ret); + + return error; } static int @@ -1170,6 +1130,16 @@ vmbus_get_version_method(device_t bus, device_t dev) } static int +vmbus_probe_guid_method(device_t bus, device_t dev, const struct hv_guid *guid) +{ + const struct hv_vmbus_channel *chan = vmbus_get_channel(dev); + + if (memcmp(&chan->ch_guid_type, guid, sizeof(struct hv_guid)) == 0) + return 0; + return ENXIO; +} + +static int vmbus_probe(device_t dev) { char *id[] = { "VMBUS", NULL }; @@ -1376,11 +1346,11 @@ static device_method_t vmbus_methods[] = { DEVMETHOD(bus_add_child, bus_generic_add_child), DEVMETHOD(bus_print_child, bus_generic_print_child), DEVMETHOD(bus_read_ivar, vmbus_read_ivar), - DEVMETHOD(bus_write_ivar, vmbus_write_ivar), DEVMETHOD(bus_child_pnpinfo_str, vmbus_child_pnpinfo_str), /* Vmbus interface */ DEVMETHOD(vmbus_get_version, vmbus_get_version_method), + DEVMETHOD(vmbus_probe_guid, vmbus_probe_guid_method), DEVMETHOD_END }; diff --git a/sys/dev/hyperv/vmbus/vmbus_if.m b/sys/dev/hyperv/vmbus/vmbus_if.m index 0782d00..3281ad2 100644 --- a/sys/dev/hyperv/vmbus/vmbus_if.m +++ b/sys/dev/hyperv/vmbus/vmbus_if.m @@ -31,7 +31,17 @@ INTERFACE vmbus; +HEADER { + struct hv_guid; +}; + METHOD uint32_t get_version { device_t bus; device_t dev; }; + +METHOD int probe_guid { + device_t bus; + device_t dev; + const struct hv_guid *guid; +}; |