diff --git a/src/add-ons/kernel/bus_managers/acpi/acpi_module.c b/src/add-ons/kernel/bus_managers/acpi/acpi_module.c index 4f269a8c08..63255b0f78 100644 --- a/src/add-ons/kernel/bus_managers/acpi/acpi_module.c +++ b/src/add-ons/kernel/bus_managers/acpi/acpi_module.c @@ -255,5 +255,6 @@ _EXPORT module_info *modules[] = { (module_info *) &acpi_module, (module_info *) &sACPIModule, (module_info *) &acpi_ns_dump_module, + (module_info *) &gACPIDeviceModule, NULL }; diff --git a/src/add-ons/kernel/bus_managers/acpi/acpi_priv.h b/src/add-ons/kernel/bus_managers/acpi/acpi_priv.h index f3162ff005..e36cee45a9 100644 --- a/src/add-ons/kernel/bus_managers/acpi/acpi_priv.h +++ b/src/add-ons/kernel/bus_managers/acpi/acpi_priv.h @@ -63,6 +63,8 @@ extern struct acpi_module_info acpi_module; extern pnp_devfs_driver_info acpi_ns_dump_module; +extern acpi_device_module_info gACPIDeviceModule; + void enable_fixed_event (uint32 event); void disable_fixed_event (uint32 event); diff --git a/src/add-ons/kernel/bus_managers/pci/pci_module.c b/src/add-ons/kernel/bus_managers/pci/pci_module.c index 71c9094f93..94bff4cf05 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci_module.c +++ b/src/add-ons/kernel/bus_managers/pci/pci_module.c @@ -121,7 +121,7 @@ pci_module_register_child_devices(void *cookie) { B_DRIVER_MAPPING, B_STRING_TYPE, { string: "%"PCI_DEVICE_VENDOR_ID_ITEM "%|_%" PCI_DEVICE_DEVICE_ID_ITEM "%" }}, // ToDo: this is a hack - { B_DRIVER_DEVICE_TYPE, B_STRING_TYPE, { string: device.class_base == 1 ? "drivers/dev/disk" : "drivers/dev" }}, + { B_DRIVER_DEVICE_TYPE, B_STRING_TYPE, { string: device.class_base == PCI_mass_storage ? "drivers/dev/disk" : "drivers/dev" }}, { NULL } }; device_node_handle deviceNode; diff --git a/src/add-ons/kernel/drivers/power/acpi_thermal/acpi_thermal.c b/src/add-ons/kernel/drivers/power/acpi_thermal/acpi_thermal.c index b9b5af9596..9e8700f00b 100644 --- a/src/add-ons/kernel/drivers/power/acpi_thermal/acpi_thermal.c +++ b/src/add-ons/kernel/drivers/power/acpi_thermal/acpi_thermal.c @@ -3,167 +3,72 @@ Obtains general status of passive devices, monitors / sets critical temperatures Controls active devices. +++++ */ -#include "acpi_thermal_dev.h" +#include +#include +#include +#include + +#include +#include + +#include +#include #include "acpi_thermal.h" -int32 api_version = B_CUR_DRIVER_API_VERSION; -acpi_module_info *acpi; +#define ACPI_THERMAL_MODULE_NAME "drivers/bin/acpi_thermal/acpi_device_v1" -static thermal_dev *device_list = NULL; -static sem_id dev_list_lock = -1; -static int device_count = 0; +/* Base Namespace devices are published to */ +#define ACPI_THERMAL_BASENAME "acpi/thermal/%d" -static char **device_names = NULL; +// name of pnp generator of path ids +#define ACPI_THERMAL_PATHID_GENERATOR "acpi_thermal/path_id" -/* Enumerates the devices of ACPI_THERMAL_TYPE - * looking for devices with _CRT and _TMP methods. - * Those devices, be they passive or active - * are usefull things to monitor / control. - */ -void enumerate_devices (char* parent) +device_manager_info *gDeviceManager; + +typedef struct acpi_ns_device_info { + device_node_handle node; + acpi_device_module_info *acpi; + acpi_device acpi_cookie; +} acpi_thermal_device_info; + + +status_t acpi_thermal_control(acpi_thermal_device_info* device, uint32 op, void* arg, size_t len); + + +static status_t +acpi_thermal_open(acpi_thermal_device_info *device, uint32 flags, void** cookie) { - char result[255]; - void *counter = NULL; - thermal_dev *td = NULL; - - acpi_object_type buf; - size_t bufsize = sizeof(buf); - - while (acpi->get_next_entry(ACPI_TYPE_THERMAL, parent, result, 255, &counter) == B_OK) { - if ((acpi->evaluate_method(result, "_TMP", &buf, bufsize, NULL, 0) == B_OK) && - (acpi->evaluate_method(result, "_CRT", &buf, bufsize, NULL, 0) == B_OK)) - { - td = (thermal_dev *) malloc(sizeof(thermal_dev)); - if (td != NULL) { - td->open = 0; - td->num = device_count; - - dprintf("acpi_thermal: Adding thermal device from: %s\n", result); - td->path = malloc(sizeof(char) * strlen(result) + 1); - strcpy(td->path, result); - - acquire_sem(dev_list_lock); - td->next = device_list; - device_list = td; - device_count++; - release_sem(dev_list_lock); - } - } - enumerate_devices(result); - } -} - -void -cleanup_published_names(void) -{ - int i; - - dprintf("acpi_thermal: cleanup_published_names()\n"); - if (device_names) { - for (i = 0; device_names[i]; i++){ - free(device_names[i]); - } - free(device_names); - } -} - -status_t -init_hardware (void) -{ - return B_OK; -} - -status_t -init_driver (void) -{ - if (get_module(B_ACPI_MODULE_NAME, (module_info **)&acpi) < 0) { - dprintf("Failed to get ACPI module\n"); - return B_ERROR; - } - - if ((dev_list_lock = create_sem(1, "dev_list_lock")) < 0) { - put_module(B_ACPI_MODULE_NAME); - return dev_list_lock; - } - - enumerate_devices("\\"); + *cookie = device; return B_OK; } -void -uninit_driver (void) -{ - thermal_dev *td; - acquire_sem(dev_list_lock); - td = device_list; - - while (td != NULL) { - device_list = td->next; - device_count--; - - free(td->path); - free(td); - td = device_list; - } - - delete_sem(dev_list_lock); - - put_module(B_ACPI_MODULE_NAME); - - cleanup_published_names(); -} - - static status_t -acpi_thermal_open (const char *name, uint32 flags, void** cookie) +acpi_thermal_read(acpi_thermal_device_info* device, off_t position, void *buf, size_t* num_bytes) { - thermal_dev *td; - int devnum = atoi(name + strlen(basename)); - - acquire_sem(dev_list_lock); - for (td = device_list; td; td = td->next) { - if (td->num == devnum) { - dprintf("acpi_thermal: opening ACPI path %s\n", td->path); - td->open++; - *cookie = td; - - release_sem(dev_list_lock); - return B_OK; - } - } - release_sem(dev_list_lock); - - *cookie = NULL; - return B_ERROR; -} - -static status_t -acpi_thermal_read (void* cookie, off_t position, void *buf, size_t* num_bytes) -{ - int i; acpi_thermal_type therm_info; if (*num_bytes < 1) return B_IO_ERROR; if (position == 0) { + size_t max_len = *num_bytes; + char *str = (char *)buf; dprintf("acpi_thermal: read()\n"); - acpi_thermal_control(cookie, drvOpGetThermalType, &therm_info, 0); - sprintf((char *)buf, "ACPI Thermal Device %u\n", therm_info.devnum); - *num_bytes = strlen((char *)buf); - - sprintf((char *)buf + *num_bytes, " Critical Temperature: %lu.%lu K\n", + acpi_thermal_control(device, drvOpGetThermalType, &therm_info, 0); + + snprintf(str, max_len, " Critical Temperature: %lu.%lu K\n", (therm_info.critical_temp / 10), (therm_info.critical_temp % 10)); - *num_bytes = strlen((char *)buf); - sprintf((char *)buf + *num_bytes, " Current Temperature: %lu.%lu K\n", + max_len -= strlen(str); + str += strlen(str); + snprintf(str, max_len, " Current Temperature: %lu.%lu K\n", (therm_info.current_temp / 10), (therm_info.current_temp % 10)); - *num_bytes = strlen((char *)buf); - + if (therm_info.hot_temp > 0) { - sprintf((char *)buf + *num_bytes, " Hot Temperature: %lu.%lu K\n", + max_len -= strlen(str); + str += strlen(str); + snprintf(str, max_len, " Hot Temperature: %lu.%lu K\n", (therm_info.hot_temp / 10), (therm_info.hot_temp % 10)); - *num_bytes = strlen((char *)buf); } if (therm_info.passive_package) { @@ -183,6 +88,7 @@ acpi_thermal_read (void* cookie, off_t position, void *buf, size_t* num_bytes) */ free(therm_info.passive_package); } + *num_bytes = strlen((char *)buf); } else { *num_bytes = 0; } @@ -190,19 +96,19 @@ acpi_thermal_read (void* cookie, off_t position, void *buf, size_t* num_bytes) return B_OK; } + static status_t acpi_thermal_write (void* cookie, off_t position, const void* buffer, size_t* num_bytes) { return B_ERROR; } -static status_t -acpi_thermal_control (void* cookie, uint32 op, void* arg, size_t len) + +status_t +acpi_thermal_control (acpi_thermal_device_info* device, uint32 op, void* arg, size_t len) { status_t err = B_ERROR; - thermal_dev *td = (thermal_dev *)cookie; - char objname[255]; acpi_thermal_type *att = NULL; size_t bufsize = sizeof(acpi_object_type); @@ -214,12 +120,11 @@ acpi_thermal_control (void* cookie, uint32 op, void* arg, size_t len) att = (acpi_thermal_type *)arg; // Read basic temperature thresholds. - att->devnum = td->num; - err = acpi->evaluate_method(td->path, "_CRT", &buf, bufsize, NULL, 0); + err = device->acpi->evaluate_method(device->acpi_cookie, "_CRT", &buf, bufsize, NULL, 0); att->critical_temp = buf.data.integer; - err = acpi->evaluate_method(td->path, "_TMP", &buf, bufsize, NULL, 0); + err = device->acpi->evaluate_method(device->acpi_cookie, "_TMP", &buf, bufsize, NULL, 0); att->current_temp = buf.data.integer; - err = acpi->evaluate_method(td->path, "_HOT", &buf, bufsize, NULL, 0); + err = device->acpi->evaluate_method(device->acpi_cookie, "_HOT", &buf, bufsize, NULL, 0); if (err == B_OK) { att->hot_temp = buf.data.integer; } else { @@ -229,8 +134,7 @@ acpi_thermal_control (void* cookie, uint32 op, void* arg, size_t len) // Read Passive Cooling devices att->passive_package = NULL; - sprintf(objname, "%s._PSL", td->path); - err = acpi->get_object(objname, &(att->passive_package)); + err = device->acpi->get_object(device->acpi_cookie, "_PSL", &(att->passive_package)); att->active_count = 0; att->active_devices = NULL; @@ -242,63 +146,176 @@ acpi_thermal_control (void* cookie, uint32 op, void* arg, size_t len) return err; } + static status_t acpi_thermal_close (void* cookie) { return B_OK; } + static status_t acpi_thermal_free (void* cookie) -{ - thermal_dev *td = (thermal_dev *)cookie; - - acquire_sem(dev_list_lock); - td->open--; - release_sem(dev_list_lock); - +{ return B_OK; } -device_hooks acpi_thermal_hooks = { - acpi_thermal_open, /* -> open entry point */ - acpi_thermal_close, /* -> close entry point */ - acpi_thermal_free, /* -> free cookie */ - acpi_thermal_control, /* -> control entry point */ - acpi_thermal_read, /* -> read entry point */ - acpi_thermal_write, /* -> write entry point */ - NULL, NULL, NULL, NULL + +static float +acpi_thermal_support(device_node_handle parent, bool *_noConnection) +{ + char *bus; + uint32 device_type; + + // make sure parent is really the ACPI bus manager + if (gDeviceManager->get_attr_string(parent, B_DRIVER_BUS, &bus, false) != B_OK) { + dprintf("no bus\n"); + return 0.0; + } + + if (strcmp(bus, "acpi")) { + dprintf("bad bus\n"); + goto err; + } + + // check whether it's really a thermal Device + if (gDeviceManager->get_attr_uint32(parent, ACPI_DEVICE_TYPE_ITEM, &device_type, false) != B_OK + || device_type != ACPI_TYPE_THERMAL) { + dprintf("bad type\n"); + goto err; + } + + // TODO check there are _CRT and _TMP ? + + free(bus); + return 0.6; +err: + free(bus); + return 0.0; +} + + +static status_t +acpi_thermal_init_device(device_node_handle node, void *user_cookie, void **cookie) +{ + acpi_thermal_device_info *device; + status_t res; + + device = (acpi_thermal_device_info *)calloc(1, sizeof(*device)); + if (device == NULL) + return B_NO_MEMORY; + + device->node = node; + + // register it everywhere + res = gDeviceManager->init_driver(gDeviceManager->get_parent(node), NULL, + (driver_module_info **)&device->acpi, (void**) &device->acpi_cookie); + if (res != B_OK) + goto err; + + *cookie = device; + return B_OK; + +err: + free(device); + return res; +} + + +static status_t +acpi_thermal_uninit_device(acpi_thermal_device_info *device) +{ + gDeviceManager->uninit_driver(gDeviceManager->get_parent(device->node)); + free(device); + + return B_OK; +} + + +static status_t +acpi_thermal_added(device_node_handle node) +{ + int path_id; + char name[128]; + + path_id = gDeviceManager->create_id(ACPI_THERMAL_PATHID_GENERATOR); + if (path_id < 0) { + return B_ERROR; + } + + snprintf(name, sizeof(name), ACPI_THERMAL_BASENAME, path_id); + { + device_attr attrs[] = { + { B_DRIVER_MODULE, B_STRING_TYPE, { string: ACPI_THERMAL_MODULE_NAME }}, + + { PNP_DRIVER_CONNECTION, B_STRING_TYPE, { string: "acpi_thermal" }}, + // we want devfs on top of us (who wouldn't?) + { B_DRIVER_FIXED_CHILD, B_STRING_TYPE, { string: PNP_DEVFS_MODULE_NAME }}, + + { PNP_MANAGER_ID_GENERATOR, B_STRING_TYPE, { string: ACPI_THERMAL_PATHID_GENERATOR }}, + { PNP_MANAGER_AUTO_ID, B_UINT32_TYPE, { ui32: path_id }}, + + // tell which name we want to have in devfs + { PNP_DEVFS_FILENAME, B_STRING_TYPE, { string: name }}, + { NULL } + }; + + return gDeviceManager->register_device(node, attrs, NULL, &node); + } + +} + + +static status_t +std_ops(int32 op, ...) +{ + switch (op) { + case B_MODULE_INIT: + case B_MODULE_UNINIT: + return B_OK; + + default: + return B_ERROR; + } +} + +module_dependency module_dependencies[] = { + { B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager }, + {} }; -const char** -publish_devices() -{ - thermal_dev *td; - int i; - - dprintf("acpi_thermal: publish_devices()\n"); - - cleanup_published_names(); - - acquire_sem(dev_list_lock); - device_names = (char **) malloc(sizeof(char*) * (device_count + 1)); - if (device_names) { - for (i = 0, td = device_list; td; td = td->next) { - if ((device_names[i] = (char *) malloc(strlen(basename) + 4))) { - sprintf(device_names[i], "%s%d", basename, td->num); - dprintf("acpi_thermal: Publishing \"/dev/%s\"\n", device_names[i]); - i++; - } - } - device_names[i] = NULL; - } - release_sem(dev_list_lock); - - return (const char**) device_names; -} -device_hooks* -find_device(const char* name) -{ - return &acpi_thermal_hooks; -} +pnp_devfs_driver_info acpi_thermal_dump_module = { + { + { + ACPI_THERMAL_MODULE_NAME, + 0, + std_ops + }, + + acpi_thermal_support, + acpi_thermal_added, + acpi_thermal_init_device, + (status_t (*) (void *))acpi_thermal_uninit_device, + NULL + }, + + (pnp_device_open_hook) &acpi_thermal_open, + acpi_thermal_close, + acpi_thermal_free, + (device_control_hook) &acpi_thermal_control, + + (device_read_hook) acpi_thermal_read, + acpi_thermal_write, + + NULL, + NULL, + + NULL, + NULL +}; + +module_info *modules[] = { + (module_info *)&acpi_thermal_dump_module, + NULL +}; diff --git a/src/add-ons/kernel/drivers/power/acpi_thermal/acpi_thermal.h b/src/add-ons/kernel/drivers/power/acpi_thermal/acpi_thermal.h index fd9133aba1..c41db23bc2 100644 --- a/src/add-ons/kernel/drivers/power/acpi_thermal/acpi_thermal.h +++ b/src/add-ons/kernel/drivers/power/acpi_thermal/acpi_thermal.h @@ -16,9 +16,6 @@ typedef struct acpi_thermal_active_object acpi_thermal_active_object; typedef struct acpi_thermal_type acpi_thermal_type; struct acpi_thermal_type { - /* Published thermal device number */ - int devnum; - /* Required fields for thermal devices */ uint32 critical_temp; uint32 current_temp; @@ -41,4 +38,4 @@ struct acpi_thermal_active_object { acpi_object_type *active_package; }; -#endif /* _ACPI_THERMAL_H */ \ No newline at end of file +#endif /* _ACPI_THERMAL_H */ diff --git a/src/add-ons/kernel/drivers/power/acpi_thermal/acpi_thermal_dev.h b/src/add-ons/kernel/drivers/power/acpi_thermal/acpi_thermal_dev.h deleted file mode 100644 index 6d8bfa24df..0000000000 --- a/src/add-ons/kernel/drivers/power/acpi_thermal/acpi_thermal_dev.h +++ /dev/null @@ -1,44 +0,0 @@ -/* ++++++++++ - ACPI Generic Thermal Zone Driver. - Obtains general status of passive devices, monitors / sets critical temperatures - Controls active devices. -+++++ */ -#ifndef _ACPI_THERMAL_DEV_H -#define _ACPI_THERMAL_DEV_H - -#include -#include -#include -#include - -#include -#include - -#include - -/* Base Namespace devices are published to */ -static const char *basename = "power/thermal/"; - -typedef struct thermal_dev thermal_dev; -struct thermal_dev -{ - thermal_dev *next; - - int num; - int open; - char* path; -}; - -/* - * builds the device lsit - */ -void enumerate_devices (char* base); - -/* - * Frees allocated memory to device list entries - */ -void cleanup_published_names (void); - -static status_t acpi_thermal_control (void* cookie, uint32 op, void* arg, size_t len); - -#endif /* _ACPI_THERMAL_DEV_H */