summaryrefslogtreecommitdiffstats
path: root/sys/dev/hyperv/vmbus
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/hyperv/vmbus')
-rw-r--r--sys/dev/hyperv/vmbus/hv_channel.c4
-rw-r--r--sys/dev/hyperv/vmbus/hv_channel_mgmt.c24
-rw-r--r--sys/dev/hyperv/vmbus/hv_vmbus_priv.h9
-rw-r--r--sys/dev/hyperv/vmbus/vmbus.c120
-rw-r--r--sys/dev/hyperv/vmbus/vmbus_if.m10
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;
+};
OpenPOWER on IntegriCloud