Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/nvdimm/nvdimm.c
Show First 20 Lines • Show All 221 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
nvdimm_resume(device_t dev) | nvdimm_resume(device_t dev) | ||||
{ | { | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | |||||
nvdimm_root_create_spa(void *nfitsubtbl, void *arg) | |||||
{ | |||||
enum SPA_mapping_type spa_type; | |||||
ACPI_NFIT_SYSTEM_ADDRESS *nfitaddr; | |||||
struct SPA_mapping *spa; | |||||
struct nvdimm_root_dev *dev; | |||||
int error; | |||||
nfitaddr = nfitsubtbl; | |||||
dev = arg; | |||||
spa_type = nvdimm_spa_type_from_uuid( | |||||
(struct uuid *)nfitaddr->RangeGuid); | |||||
if (spa_type == SPA_TYPE_UNKNOWN) | |||||
return (0); | |||||
spa = malloc(sizeof(struct SPA_mapping), M_NVDIMM, M_WAITOK | M_ZERO); | |||||
error = nvdimm_spa_init(spa, nfitaddr, spa_type); | |||||
if (error != 0) { | |||||
nvdimm_spa_fini(spa); | |||||
free(spa, M_NVDIMM); | |||||
} | |||||
SLIST_INSERT_HEAD(&dev->spas, spa, link); | |||||
return (0); | |||||
} | |||||
static ACPI_STATUS | static ACPI_STATUS | ||||
nvdimm_root_create_dev(ACPI_HANDLE handle, UINT32 nesting_level, void *context, | nvdimm_root_create_dev(ACPI_HANDLE handle, UINT32 nesting_level, void *context, | ||||
void **return_value) | void **return_value) | ||||
{ | { | ||||
ACPI_STATUS status; | ACPI_STATUS status; | ||||
ACPI_DEVICE_INFO *device_info; | ACPI_DEVICE_INFO *device_info; | ||||
device_t parent, child; | device_t parent, child; | ||||
uintptr_t *ivars; | uintptr_t *ivars; | ||||
Show All 33 Lines | nvdimm_root_probe(device_t dev) | ||||
return (rv); | return (rv); | ||||
} | } | ||||
static int | static int | ||||
nvdimm_root_attach(device_t dev) | nvdimm_root_attach(device_t dev) | ||||
{ | { | ||||
ACPI_HANDLE handle; | ACPI_HANDLE handle; | ||||
ACPI_STATUS status; | ACPI_STATUS status; | ||||
ACPI_TABLE_NFIT *nfitbl; | |||||
int error; | int error; | ||||
handle = acpi_get_handle(dev); | handle = acpi_get_handle(dev); | ||||
status = AcpiWalkNamespace(ACPI_TYPE_DEVICE, handle, 1, | status = AcpiWalkNamespace(ACPI_TYPE_DEVICE, handle, 1, | ||||
nvdimm_root_create_dev, NULL, dev, NULL); | nvdimm_root_create_dev, NULL, dev, NULL); | ||||
if (ACPI_FAILURE(status)) | if (ACPI_FAILURE(status)) | ||||
device_printf(dev, "failed adding children\n"); | device_printf(dev, "failed adding children\n"); | ||||
error = bus_generic_attach(dev); | error = bus_generic_attach(dev); | ||||
if (error != 0) | |||||
return (error); | return (error); | ||||
status = AcpiGetTable(ACPI_SIG_NFIT, 1, (ACPI_TABLE_HEADER **)&nfitbl); | |||||
if (ACPI_FAILURE(status)) { | |||||
device_printf(dev, "cannot get NFIT\n"); | |||||
return (ENXIO); | |||||
} | } | ||||
error = nvdimm_iterate_nfit(nfitbl, ACPI_NFIT_TYPE_SYSTEM_ADDRESS, | |||||
nvdimm_root_create_spa, device_get_softc(dev)); | |||||
AcpiPutTable(&nfitbl->Header); | |||||
return (error); | |||||
} | |||||
static int | static int | ||||
nvdimm_root_detach(device_t dev) | nvdimm_root_detach(device_t dev) | ||||
{ | { | ||||
struct nvdimm_root_dev *root; | |||||
struct SPA_mapping *spa, *next; | |||||
device_t *children; | device_t *children; | ||||
int i, error, num_children; | int i, error, num_children; | ||||
root = device_get_softc(dev); | |||||
SLIST_FOREACH_SAFE(spa, &root->spas, link, next) { | |||||
nvdimm_spa_fini(spa); | |||||
SLIST_REMOVE_HEAD(&root->spas, link); | |||||
free(spa, M_NVDIMM); | |||||
} | |||||
error = bus_generic_detach(dev); | error = bus_generic_detach(dev); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
error = device_get_children(dev, &children, &num_children); | error = device_get_children(dev, &children, &num_children); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
for (i = 0; i < num_children; i++) | for (i = 0; i < num_children; i++) | ||||
free(device_get_ivars(children[i]), M_NVDIMM); | free(device_get_ivars(children[i]), M_NVDIMM); | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | static device_method_t nvdimm_root_methods[] = { | ||||
DEVMETHOD(bus_read_ivar, nvdimm_root_read_ivar), | DEVMETHOD(bus_read_ivar, nvdimm_root_read_ivar), | ||||
DEVMETHOD(bus_write_ivar, nvdimm_root_write_ivar), | DEVMETHOD(bus_write_ivar, nvdimm_root_write_ivar), | ||||
DEVMETHOD_END | DEVMETHOD_END | ||||
}; | }; | ||||
static driver_t nvdimm_root_driver = { | static driver_t nvdimm_root_driver = { | ||||
"nvdimm_root", | "nvdimm_root", | ||||
nvdimm_root_methods, | nvdimm_root_methods, | ||||
sizeof(struct nvdimm_root_dev), | |||||
}; | }; | ||||
DRIVER_MODULE(nvdimm_root, acpi, nvdimm_root_driver, nvdimm_root_devclass, NULL, | DRIVER_MODULE(nvdimm_root, acpi, nvdimm_root_driver, nvdimm_root_devclass, NULL, | ||||
NULL); | NULL); | ||||
DRIVER_MODULE(nvdimm, nvdimm_root, nvdimm_driver, nvdimm_devclass, NULL, NULL); | DRIVER_MODULE(nvdimm, nvdimm_root, nvdimm_driver, nvdimm_devclass, NULL, NULL); | ||||
MODULE_DEPEND(nvdimm, acpi, 1, 1, 1); | MODULE_DEPEND(nvdimm, acpi, 1, 1, 1); |