vmbus.c (307306) | vmbus.c (307307) |
---|---|
1/*- 2 * Copyright (c) 2009-2012,2016 Microsoft Corp. 3 * Copyright (c) 2012 NetApp Inc. 4 * Copyright (c) 2012 Citrix Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 16 unchanged lines hidden (view full) --- 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29/* 30 * VM Bus Driver Implementation 31 */ 32#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2009-2012,2016 Microsoft Corp. 3 * Copyright (c) 2012 NetApp Inc. 4 * Copyright (c) 2012 Citrix Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 16 unchanged lines hidden (view full) --- 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29/* 30 * VM Bus Driver Implementation 31 */ 32#include <sys/cdefs.h> |
33__FBSDID("$FreeBSD: stable/11/sys/dev/hyperv/vmbus/vmbus.c 307306 2016-10-14 08:34:44Z sephe $"); | 33__FBSDID("$FreeBSD: stable/11/sys/dev/hyperv/vmbus/vmbus.c 307307 2016-10-14 08:45:53Z sephe $"); |
34 35#include <sys/param.h> 36#include <sys/bus.h> 37#include <sys/kernel.h> 38#include <sys/lock.h> 39#include <sys/malloc.h> 40#include <sys/module.h> 41#include <sys/proc.h> --- 913 unchanged lines hidden (view full) --- 955 VMBUS_PCPU_GET(sc, message_tq, cpu) = NULL; 956 } 957 } 958} 959 960static int 961vmbus_read_ivar(device_t dev, device_t child, int index, uintptr_t *result) 962{ | 34 35#include <sys/param.h> 36#include <sys/bus.h> 37#include <sys/kernel.h> 38#include <sys/lock.h> 39#include <sys/malloc.h> 40#include <sys/module.h> 41#include <sys/proc.h> --- 913 unchanged lines hidden (view full) --- 955 VMBUS_PCPU_GET(sc, message_tq, cpu) = NULL; 956 } 957 } 958} 959 960static int 961vmbus_read_ivar(device_t dev, device_t child, int index, uintptr_t *result) 962{ |
963 struct hv_device *child_dev_ctx = device_get_ivars(child); 964 965 switch (index) { 966 case HV_VMBUS_IVAR_TYPE: 967 *result = (uintptr_t)&child_dev_ctx->class_id; 968 return (0); 969 970 case HV_VMBUS_IVAR_INSTANCE: 971 *result = (uintptr_t)&child_dev_ctx->device_id; 972 return (0); 973 974 case HV_VMBUS_IVAR_DEVCTX: 975 *result = (uintptr_t)child_dev_ctx; 976 return (0); 977 978 case HV_VMBUS_IVAR_NODE: 979 *result = (uintptr_t)child_dev_ctx->device; 980 return (0); 981 } | |
982 return (ENOENT); 983} 984 985static int | 963 return (ENOENT); 964} 965 966static int |
986vmbus_write_ivar(device_t dev, device_t child, int index, uintptr_t value) 987{ 988 switch (index) { 989 case HV_VMBUS_IVAR_TYPE: 990 case HV_VMBUS_IVAR_INSTANCE: 991 case HV_VMBUS_IVAR_DEVCTX: 992 case HV_VMBUS_IVAR_NODE: 993 /* read-only */ 994 return (EINVAL); 995 } 996 return (ENOENT); 997} 998 999static int | |
1000vmbus_child_pnpinfo_str(device_t dev, device_t child, char *buf, size_t buflen) 1001{ | 967vmbus_child_pnpinfo_str(device_t dev, device_t child, char *buf, size_t buflen) 968{ |
1002 struct hv_device *dev_ctx = device_get_ivars(child); | 969 const struct hv_vmbus_channel *chan; |
1003 char guidbuf[HYPERV_GUID_STRLEN]; 1004 | 970 char guidbuf[HYPERV_GUID_STRLEN]; 971 |
1005 if (dev_ctx == NULL) | 972 chan = vmbus_get_channel(child); 973 if (chan == NULL) { 974 /* Event timer device, which does not belong to a channel */ |
1006 return (0); | 975 return (0); |
976 } |
|
1007 1008 strlcat(buf, "classid=", buflen); | 977 978 strlcat(buf, "classid=", buflen); |
1009 hyperv_guid2str(&dev_ctx->class_id, guidbuf, sizeof(guidbuf)); | 979 hyperv_guid2str(&chan->ch_guid_type, guidbuf, sizeof(guidbuf)); |
1010 strlcat(buf, guidbuf, buflen); 1011 1012 strlcat(buf, " deviceid=", buflen); | 980 strlcat(buf, guidbuf, buflen); 981 982 strlcat(buf, " deviceid=", buflen); |
1013 hyperv_guid2str(&dev_ctx->device_id, guidbuf, sizeof(guidbuf)); | 983 hyperv_guid2str(&chan->ch_guid_inst, guidbuf, sizeof(guidbuf)); |
1014 strlcat(buf, guidbuf, buflen); 1015 1016 return (0); 1017} 1018 | 984 strlcat(buf, guidbuf, buflen); 985 986 return (0); 987} 988 |
1019struct hv_device * 1020hv_vmbus_child_device_create(struct hv_vmbus_channel *channel) | 989int 990hv_vmbus_child_device_register(struct hv_vmbus_channel *chan) |
1021{ | 991{ |
1022 hv_device *child_dev; | 992 struct vmbus_softc *sc = chan->vmbus_sc; 993 device_t parent = sc->vmbus_dev; 994 int error = 0; |
1023 | 995 |
1024 /* 1025 * Allocate the new child device 1026 */ 1027 child_dev = malloc(sizeof(hv_device), M_DEVBUF, M_WAITOK | M_ZERO); 1028 1029 child_dev->channel = channel; 1030 child_dev->class_id = channel->ch_guid_type; 1031 child_dev->device_id = channel->ch_guid_inst; 1032 1033 return (child_dev); 1034} 1035 1036void 1037hv_vmbus_child_device_register(struct vmbus_softc *sc, 1038 struct hv_device *child_dev) 1039{ 1040 device_t child, parent; 1041 1042 parent = sc->vmbus_dev; 1043 if (bootverbose) { 1044 char name[HYPERV_GUID_STRLEN]; 1045 1046 hyperv_guid2str(&child_dev->class_id, name, sizeof(name)); 1047 device_printf(parent, "add device, classid: %s\n", name); | 996 chan->ch_dev = device_add_child(parent, NULL, -1); 997 if (chan->ch_dev == NULL) { 998 device_printf(parent, "device_add_child for chan%u failed\n", 999 chan->ch_id); 1000 error = ENXIO; 1001 goto done; |
1048 } | 1002 } |
1003 device_set_ivars(chan->ch_dev, chan); |
|
1049 | 1004 |
1050 child = device_add_child(parent, NULL, -1); 1051 child_dev->device = child; 1052 device_set_ivars(child, child_dev); 1053 1054 /* New device was added to vmbus */ | 1005done: 1006 /* New device has been/should be added to vmbus. */ |
1055 vmbus_scan_newdev(sc); | 1007 vmbus_scan_newdev(sc); |
1008 return error; |
|
1056} 1057 1058int | 1009} 1010 1011int |
1059hv_vmbus_child_device_unregister(struct hv_device *child_dev) | 1012hv_vmbus_child_device_unregister(struct hv_vmbus_channel *chan) |
1060{ | 1013{ |
1061 int ret = 0; | 1014 int error; 1015 1016 if (chan->ch_dev == NULL) { 1017 /* Failed to add a device. */ 1018 return 0; 1019 } 1020 |
1062 /* 1063 * XXXKYS: Ensure that this is the opposite of 1064 * device_add_child() 1065 */ 1066 mtx_lock(&Giant); | 1021 /* 1022 * XXXKYS: Ensure that this is the opposite of 1023 * device_add_child() 1024 */ 1025 mtx_lock(&Giant); |
1067 ret = device_delete_child(vmbus_get_device(), child_dev->device); | 1026 error = device_delete_child(chan->vmbus_sc->vmbus_dev, chan->ch_dev); |
1068 mtx_unlock(&Giant); | 1027 mtx_unlock(&Giant); |
1069 return(ret); | 1028 1029 return error; |
1070} 1071 1072static int 1073vmbus_sysctl_version(SYSCTL_HANDLER_ARGS) 1074{ 1075 struct vmbus_softc *sc = arg1; 1076 char verstr[16]; 1077 --- 7 unchanged lines hidden (view full) --- 1085vmbus_get_version_method(device_t bus, device_t dev) 1086{ 1087 struct vmbus_softc *sc = device_get_softc(bus); 1088 1089 return sc->vmbus_version; 1090} 1091 1092static int | 1030} 1031 1032static int 1033vmbus_sysctl_version(SYSCTL_HANDLER_ARGS) 1034{ 1035 struct vmbus_softc *sc = arg1; 1036 char verstr[16]; 1037 --- 7 unchanged lines hidden (view full) --- 1045vmbus_get_version_method(device_t bus, device_t dev) 1046{ 1047 struct vmbus_softc *sc = device_get_softc(bus); 1048 1049 return sc->vmbus_version; 1050} 1051 1052static int |
1053vmbus_probe_guid_method(device_t bus, device_t dev, const struct hv_guid *guid) 1054{ 1055 const struct hv_vmbus_channel *chan = vmbus_get_channel(dev); 1056 1057 if (memcmp(&chan->ch_guid_type, guid, sizeof(struct hv_guid)) == 0) 1058 return 0; 1059 return ENXIO; 1060} 1061 1062static int |
|
1093vmbus_probe(device_t dev) 1094{ 1095 char *id[] = { "VMBUS", NULL }; 1096 1097 if (ACPI_ID_PROBE(device_get_parent(dev), dev, id) == NULL || 1098 device_get_unit(dev) != 0 || vm_guest != VM_GUEST_HV || 1099 (hyperv_features & CPUID_HV_MSR_SYNIC) == 0) 1100 return (ENXIO); --- 195 unchanged lines hidden (view full) --- 1296 DEVMETHOD(device_shutdown, bus_generic_shutdown), 1297 DEVMETHOD(device_suspend, bus_generic_suspend), 1298 DEVMETHOD(device_resume, bus_generic_resume), 1299 1300 /* Bus interface */ 1301 DEVMETHOD(bus_add_child, bus_generic_add_child), 1302 DEVMETHOD(bus_print_child, bus_generic_print_child), 1303 DEVMETHOD(bus_read_ivar, vmbus_read_ivar), | 1063vmbus_probe(device_t dev) 1064{ 1065 char *id[] = { "VMBUS", NULL }; 1066 1067 if (ACPI_ID_PROBE(device_get_parent(dev), dev, id) == NULL || 1068 device_get_unit(dev) != 0 || vm_guest != VM_GUEST_HV || 1069 (hyperv_features & CPUID_HV_MSR_SYNIC) == 0) 1070 return (ENXIO); --- 195 unchanged lines hidden (view full) --- 1266 DEVMETHOD(device_shutdown, bus_generic_shutdown), 1267 DEVMETHOD(device_suspend, bus_generic_suspend), 1268 DEVMETHOD(device_resume, bus_generic_resume), 1269 1270 /* Bus interface */ 1271 DEVMETHOD(bus_add_child, bus_generic_add_child), 1272 DEVMETHOD(bus_print_child, bus_generic_print_child), 1273 DEVMETHOD(bus_read_ivar, vmbus_read_ivar), |
1304 DEVMETHOD(bus_write_ivar, vmbus_write_ivar), | |
1305 DEVMETHOD(bus_child_pnpinfo_str, vmbus_child_pnpinfo_str), 1306 1307 /* Vmbus interface */ 1308 DEVMETHOD(vmbus_get_version, vmbus_get_version_method), | 1274 DEVMETHOD(bus_child_pnpinfo_str, vmbus_child_pnpinfo_str), 1275 1276 /* Vmbus interface */ 1277 DEVMETHOD(vmbus_get_version, vmbus_get_version_method), |
1278 DEVMETHOD(vmbus_probe_guid, vmbus_probe_guid_method), |
|
1309 1310 DEVMETHOD_END 1311}; 1312 1313static driver_t vmbus_driver = { 1314 "vmbus", 1315 vmbus_methods, 1316 sizeof(struct vmbus_softc) --- 16 unchanged lines hidden --- | 1279 1280 DEVMETHOD_END 1281}; 1282 1283static driver_t vmbus_driver = { 1284 "vmbus", 1285 vmbus_methods, 1286 sizeof(struct vmbus_softc) --- 16 unchanged lines hidden --- |