Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/hyperv/vmbus/vmbus.c
Show First 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | |||||
#define VMBUS_GPADL_START 0xe1e10 | #define VMBUS_GPADL_START 0xe1e10 | ||||
struct vmbus_msghc { | struct vmbus_msghc { | ||||
struct vmbus_xact *mh_xact; | struct vmbus_xact *mh_xact; | ||||
struct hypercall_postmsg_in mh_inprm_save; | struct hypercall_postmsg_in mh_inprm_save; | ||||
}; | }; | ||||
static void vmbus_identify(driver_t *, device_t); | |||||
static int vmbus_probe(device_t); | static int vmbus_probe(device_t); | ||||
static int vmbus_attach(device_t); | static int vmbus_attach(device_t); | ||||
static int vmbus_detach(device_t); | static int vmbus_detach(device_t); | ||||
static int vmbus_read_ivar(device_t, device_t, int, | static int vmbus_read_ivar(device_t, device_t, int, | ||||
uintptr_t *); | uintptr_t *); | ||||
static int vmbus_child_pnpinfo_str(device_t, device_t, | static int vmbus_child_pnpinfo_str(device_t, device_t, | ||||
char *, size_t); | char *, size_t); | ||||
static struct resource *vmbus_alloc_resource(device_t dev, | static struct resource *vmbus_alloc_resource(device_t dev, | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | |||||
static const vmbus_chanmsg_proc_t | static const vmbus_chanmsg_proc_t | ||||
vmbus_chanmsg_handlers[VMBUS_CHANMSG_TYPE_MAX] = { | vmbus_chanmsg_handlers[VMBUS_CHANMSG_TYPE_MAX] = { | ||||
VMBUS_CHANMSG_PROC(CHOFFER_DONE, vmbus_scan_done), | VMBUS_CHANMSG_PROC(CHOFFER_DONE, vmbus_scan_done), | ||||
VMBUS_CHANMSG_PROC_WAKEUP(CONNECT_RESP) | VMBUS_CHANMSG_PROC_WAKEUP(CONNECT_RESP) | ||||
}; | }; | ||||
static device_method_t vmbus_methods[] = { | static device_method_t vmbus_methods[] = { | ||||
/* Device interface */ | /* Device interface */ | ||||
DEVMETHOD(device_identify, vmbus_identify), | |||||
DEVMETHOD(device_probe, vmbus_probe), | DEVMETHOD(device_probe, vmbus_probe), | ||||
DEVMETHOD(device_attach, vmbus_attach), | DEVMETHOD(device_attach, vmbus_attach), | ||||
DEVMETHOD(device_detach, vmbus_detach), | DEVMETHOD(device_detach, vmbus_detach), | ||||
DEVMETHOD(device_shutdown, bus_generic_shutdown), | DEVMETHOD(device_shutdown, bus_generic_shutdown), | ||||
DEVMETHOD(device_suspend, bus_generic_suspend), | DEVMETHOD(device_suspend, bus_generic_suspend), | ||||
DEVMETHOD(device_resume, bus_generic_resume), | DEVMETHOD(device_resume, bus_generic_resume), | ||||
/* Bus interface */ | /* Bus interface */ | ||||
Show All 30 Lines | |||||
static driver_t vmbus_driver = { | static driver_t vmbus_driver = { | ||||
"vmbus", | "vmbus", | ||||
vmbus_methods, | vmbus_methods, | ||||
sizeof(struct vmbus_softc) | sizeof(struct vmbus_softc) | ||||
}; | }; | ||||
static devclass_t vmbus_devclass; | static devclass_t vmbus_devclass; | ||||
DRIVER_MODULE(vmbus, acpi, vmbus_driver, vmbus_devclass, NULL, NULL); | DRIVER_MODULE(vmbus, pcib, vmbus_driver, vmbus_devclass, NULL, NULL); | ||||
DRIVER_MODULE(vmbus, acpi_syscontainer, vmbus_driver, vmbus_devclass, | |||||
NULL, NULL); | |||||
MODULE_DEPEND(vmbus, acpi, 1, 1, 1); | MODULE_DEPEND(vmbus, acpi, 1, 1, 1); | ||||
MODULE_DEPEND(vmbus, pci, 1, 1, 1); | MODULE_DEPEND(vmbus, pci, 1, 1, 1); | ||||
MODULE_VERSION(vmbus, 1); | MODULE_VERSION(vmbus, 1); | ||||
static __inline struct vmbus_softc * | static __inline struct vmbus_softc * | ||||
vmbus_get_softc(void) | vmbus_get_softc(void) | ||||
{ | { | ||||
return vmbus_sc; | return vmbus_sc; | ||||
▲ Show 20 Lines • Show All 859 Lines • ▼ Show 20 Lines | #endif | ||||
{ | { | ||||
res = BUS_ALLOC_RESOURCE(parent, child, type, rid, start, | res = BUS_ALLOC_RESOURCE(parent, child, type, rid, start, | ||||
end, count, flags); | end, count, flags); | ||||
} | } | ||||
return (res); | return (res); | ||||
} | } | ||||
static device_t | |||||
get_nexus(device_t vmbus) | |||||
{ | |||||
device_t acpi = device_get_parent(vmbus); | |||||
device_t nexus = device_get_parent(acpi); | |||||
return (nexus); | |||||
} | |||||
static int | static int | ||||
vmbus_alloc_msi(device_t bus, device_t dev, int count, int maxcount, int *irqs) | vmbus_alloc_msi(device_t bus, device_t dev, int count, int maxcount, int *irqs) | ||||
{ | { | ||||
return (PCIB_ALLOC_MSI(get_nexus(bus), dev, count, maxcount, irqs)); | |||||
return (PCIB_ALLOC_MSI(device_get_parent(bus), dev, count, maxcount, | |||||
irqs)); | |||||
} | } | ||||
static int | static int | ||||
vmbus_release_msi(device_t bus, device_t dev, int count, int *irqs) | vmbus_release_msi(device_t bus, device_t dev, int count, int *irqs) | ||||
{ | { | ||||
return (PCIB_RELEASE_MSI(get_nexus(bus), dev, count, irqs)); | |||||
return (PCIB_RELEASE_MSI(device_get_parent(bus), dev, count, irqs)); | |||||
} | } | ||||
static int | static int | ||||
vmbus_alloc_msix(device_t bus, device_t dev, int *irq) | vmbus_alloc_msix(device_t bus, device_t dev, int *irq) | ||||
{ | { | ||||
return (PCIB_ALLOC_MSIX(get_nexus(bus), dev, irq)); | |||||
return (PCIB_ALLOC_MSIX(device_get_parent(bus), dev, irq)); | |||||
} | } | ||||
static int | static int | ||||
vmbus_release_msix(device_t bus, device_t dev, int irq) | vmbus_release_msix(device_t bus, device_t dev, int irq) | ||||
{ | { | ||||
return (PCIB_RELEASE_MSIX(get_nexus(bus), dev, irq)); | |||||
return (PCIB_RELEASE_MSIX(device_get_parent(bus), dev, irq)); | |||||
} | } | ||||
static int | static int | ||||
vmbus_map_msi(device_t bus, device_t dev, int irq, uint64_t *addr, | vmbus_map_msi(device_t bus, device_t dev, int irq, uint64_t *addr, | ||||
uint32_t *data) | uint32_t *data) | ||||
{ | { | ||||
return (PCIB_MAP_MSI(get_nexus(bus), dev, irq, addr, data)); | |||||
return (PCIB_MAP_MSI(device_get_parent(bus), dev, irq, addr, data)); | |||||
} | } | ||||
static uint32_t | static uint32_t | ||||
vmbus_get_version_method(device_t bus, device_t dev) | vmbus_get_version_method(device_t bus, device_t dev) | ||||
{ | { | ||||
struct vmbus_softc *sc = device_get_softc(bus); | struct vmbus_softc *sc = device_get_softc(bus); | ||||
return sc->vmbus_version; | return sc->vmbus_version; | ||||
▲ Show 20 Lines • Show All 97 Lines • ▼ Show 20 Lines | vmbus_get_crs(device_t dev, device_t vmbus_dev, enum parse_pass pass) | ||||
if (bootverbose && ACPI_FAILURE(status)) | if (bootverbose && ACPI_FAILURE(status)) | ||||
device_printf(dev, "_CRS: not found, pass=%d\n", pass); | device_printf(dev, "_CRS: not found, pass=%d\n", pass); | ||||
} | } | ||||
static void | static void | ||||
vmbus_get_mmio_res_pass(device_t dev, enum parse_pass pass) | vmbus_get_mmio_res_pass(device_t dev, enum parse_pass pass) | ||||
{ | { | ||||
device_t acpi0, pcib0 = NULL; | device_t acpi0, parent; | ||||
device_t *children; | |||||
int i, count; | |||||
/* Try to find _CRS on VMBus device */ | parent = device_get_parent(dev); | ||||
vmbus_get_crs(dev, dev, pass); | |||||
/* Try to find _CRS on VMBus device's parent */ | acpi0 = device_get_parent(parent); | ||||
acpi0 = device_get_parent(dev); | if (strcmp("acpi0", device_get_nameunit(acpi0)) == 0) { | ||||
vmbus_get_crs(acpi0, dev, pass); | device_t *children; | ||||
int count; | |||||
/* Try to locate pcib0 and find _CRS on it */ | /* | ||||
if (device_get_children(acpi0, &children, &count) != 0) | * Try to locate VMBUS resources and find _CRS on them. | ||||
return; | */ | ||||
if (device_get_children(acpi0, &children, &count) == 0) { | |||||
int i; | |||||
for (i = 0; i < count; i++) { | for (i = 0; i < count; ++i) { | ||||
if (!device_is_attached(children[i])) | if (!device_is_attached(children[i])) | ||||
continue; | continue; | ||||
if (strcmp("pcib0", device_get_nameunit(children[i]))) | if (strcmp("vmbus_res", | ||||
continue; | device_get_name(children[i])) == 0) | ||||
vmbus_get_crs(children[i], dev, pass); | |||||
} | |||||
free(children, M_TEMP); | |||||
} | |||||
pcib0 = children[i]; | /* | ||||
break; | * Try to find _CRS on acpi. | ||||
*/ | |||||
vmbus_get_crs(acpi0, dev, pass); | |||||
} else { | |||||
device_printf(dev, "not grandchild of acpi\n"); | |||||
} | } | ||||
if (pcib0) | /* | ||||
vmbus_get_crs(pcib0, dev, pass); | * Try to find _CRS on parent. | ||||
*/ | |||||
free(children, M_TEMP); | vmbus_get_crs(parent, dev, pass); | ||||
} | } | ||||
static void | static void | ||||
vmbus_get_mmio_res(device_t dev) | vmbus_get_mmio_res(device_t dev) | ||||
{ | { | ||||
struct vmbus_softc *sc = device_get_softc(dev); | struct vmbus_softc *sc = device_get_softc(dev); | ||||
/* | /* | ||||
* We walk the resources twice to make sure that: in the resource | * We walk the resources twice to make sure that: in the resource | ||||
Show All 13 Lines | |||||
vmbus_free_mmio_res(device_t dev) | vmbus_free_mmio_res(device_t dev) | ||||
{ | { | ||||
struct vmbus_softc *sc = device_get_softc(dev); | struct vmbus_softc *sc = device_get_softc(dev); | ||||
pcib_host_res_free(dev, &sc->vmbus_mmio_res); | pcib_host_res_free(dev, &sc->vmbus_mmio_res); | ||||
} | } | ||||
#endif /* NEW_PCIB */ | #endif /* NEW_PCIB */ | ||||
static void | |||||
vmbus_identify(driver_t *driver, device_t parent) | |||||
{ | |||||
if (device_get_unit(parent) != 0 || vm_guest != VM_GUEST_HV || | |||||
(hyperv_features & CPUID_HV_MSR_SYNIC) == 0) | |||||
return; | |||||
device_add_child(parent, "vmbus", -1); | |||||
} | |||||
static int | static int | ||||
vmbus_probe(device_t dev) | vmbus_probe(device_t dev) | ||||
{ | { | ||||
char *id[] = { "VMBUS", NULL }; | |||||
if (ACPI_ID_PROBE(device_get_parent(dev), dev, id) == NULL || | if (device_get_unit(dev) != 0 || vm_guest != VM_GUEST_HV || | ||||
device_get_unit(dev) != 0 || vm_guest != VM_GUEST_HV || | |||||
(hyperv_features & CPUID_HV_MSR_SYNIC) == 0) | (hyperv_features & CPUID_HV_MSR_SYNIC) == 0) | ||||
return (ENXIO); | return (ENXIO); | ||||
device_set_desc(dev, "Hyper-V Vmbus"); | device_set_desc(dev, "Hyper-V Vmbus"); | ||||
return (BUS_PROBE_DEFAULT); | return (BUS_PROBE_DEFAULT); | ||||
} | } | ||||
/** | /** | ||||
* @brief Main vmbus driver initialization routine. | * @brief Main vmbus driver initialization routine. | ||||
* | * | ||||
* Here, we | * Here, we | ||||
* - initialize the vmbus driver context | * - initialize the vmbus driver context | ||||
▲ Show 20 Lines • Show All 223 Lines • Show Last 20 Lines |