Date: Wed, 03 Oct 2012 19:34:14 +0300 From: Andriy Gapon <avg@FreeBSD.org> To: "freebsd-acpi@freebsd.org" <freebsd-acpi@FreeBSD.org> Subject: acpi_wmi: move wmi_info_list into sc Message-ID: <506C6906.9070402@FreeBSD.org>
next in thread | raw e-mail | index | archive | help
Please take a look at the following patch and a commit message that explains it. I observed the problem on a system with acpi_wmi instances where one instance overrode GUID list from the other. commit f1f4109b1588872906ed56086e2680ac1af96268 Author: Andriy Gapon <avg@icyb.net.ua> Date: Thu Sep 27 13:48:18 2012 +0300 acpi_wmi: move wmi_info_list into sc different instances of acpi_wmi couldn't properly share it and in fact there was no reason to do that diff --git a/sys/dev/acpi_support/acpi_wmi.c b/sys/dev/acpi_support/acpi_wmi.c index 5a37979..5927ee1 100644 --- a/sys/dev/acpi_support/acpi_wmi.c +++ b/sys/dev/acpi_support/acpi_wmi.c @@ -74,6 +74,7 @@ struct acpi_wmi_softc { struct sbuf wmistat_sbuf; /* sbuf for /dev/wmistat output */ pid_t wmistat_open_pid; /* pid operating on /dev/wmistat */ int wmistat_bufptr; /* /dev/wmistat ptr to buffer position */ + TAILQ_HEAD(wmi_info_list_head, wmi_info) wmi_info_list; }; /* @@ -105,8 +106,6 @@ struct wmi_info { void *event_handler_user_data; /* ev handler cookie */ }; -TAILQ_HEAD(wmi_info_list_head, wmi_info) - wmi_info_list = TAILQ_HEAD_INITIALIZER(wmi_info_list); ACPI_SERIAL_DECL(acpi_wmi, "ACPI-WMI Mapping"); @@ -146,13 +145,13 @@ static ACPI_STATUS acpi_wmi_ec_handler(UINT32 function, void *region_context); #endif /* helpers */ -static ACPI_STATUS acpi_wmi_read_wdg_blocks(ACPI_HANDLE h); +static ACPI_STATUS acpi_wmi_read_wdg_blocks(struct acpi_wmi_softc *sc, ACPI_HANDLE h); static ACPI_STATUS acpi_wmi_toggle_we_event_generation(device_t dev, struct wmi_info *winfo, enum event_generation_state state); static int acpi_wmi_guid_string_to_guid(const UINT8 *guid_string, UINT8 *guid); -static struct wmi_info* acpi_wmi_lookup_wmi_info_by_guid_string( +static struct wmi_info* acpi_wmi_lookup_wmi_info_by_guid_string(struct acpi_wmi_softc *sc, const char *guid_string); static d_open_t acpi_wmi_wmistat_open; @@ -240,7 +239,7 @@ acpi_wmi_attach(device_t dev) ACPI_SERIAL_BEGIN(acpi_wmi); sc->wmi_dev = dev; sc->wmi_handle = acpi_get_handle(dev); - TAILQ_INIT(&wmi_info_list); + TAILQ_INIT(&sc->wmi_info_list); #if 0 /* XXX Only works with one EC, but nearly all systems only have one. */ if ((sc->ec_dev = devclass_get_device(devclass_find("acpi_ec"), 0)) @@ -263,7 +262,7 @@ acpi_wmi_attach(device_t dev) acpi_wmi_notify_handler); } #endif - else if (ACPI_FAILURE((status = acpi_wmi_read_wdg_blocks( + else if (ACPI_FAILURE((status = acpi_wmi_read_wdg_blocks(sc, sc->wmi_handle)))) { device_printf(sc->wmi_dev, "couldn't parse _WDG - %s\n", AcpiFormatException(status)); @@ -318,11 +317,11 @@ acpi_wmi_detach(device_t dev) AcpiRemoveAddressSpaceHandler(sc->wmi_handle, ACPI_ADR_SPACE_EC, acpi_wmi_ec_handler); #endif - TAILQ_FOREACH_SAFE(winfo, &wmi_info_list, wmi_list, tmp) { + TAILQ_FOREACH_SAFE(winfo, &sc->wmi_info_list, wmi_list, tmp) { if (winfo->event_handler) acpi_wmi_toggle_we_event_generation(dev, winfo, EVENT_GENERATION_OFF); - TAILQ_REMOVE(&wmi_info_list, winfo, wmi_list); + TAILQ_REMOVE(&sc->wmi_info_list, winfo, wmi_list); free(winfo, M_ACPIWMI); } if (sc->wmistat_bufptr != -1) { @@ -347,12 +346,14 @@ acpi_wmi_detach(device_t dev) static int acpi_wmi_provides_guid_string_method(device_t dev, const char *guid_string) { + struct acpi_wmi_softc *sc; struct wmi_info *winfo; int ret; + sc = device_get_softc(dev); ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); ACPI_SERIAL_BEGIN(acpi_wmi); - winfo = acpi_wmi_lookup_wmi_info_by_guid_string(guid_string); + winfo = acpi_wmi_lookup_wmi_info_by_guid_string(sc, guid_string); ret = (winfo == NULL)?0:winfo->ginfo.max_instance+1; ACPI_SERIAL_END(acpi_wmi); @@ -378,7 +379,7 @@ acpi_wmi_evaluate_call_method(device_t dev, const char *guid_string, sc = device_get_softc(dev); ACPI_SERIAL_BEGIN(acpi_wmi); - if ((winfo = acpi_wmi_lookup_wmi_info_by_guid_string(guid_string)) + if ((winfo = acpi_wmi_lookup_wmi_info_by_guid_string(sc, guid_string)) == NULL) status = AE_NOT_FOUND; else if (!(winfo->ginfo.flags & ACPI_WMI_REGFLAG_METHOD)) @@ -420,6 +421,7 @@ static ACPI_STATUS acpi_wmi_install_event_handler_method(device_t dev, const char *guid_string, ACPI_NOTIFY_HANDLER event_handler, void *data) { + struct acpi_wmi_softc *sc = device_get_softc(dev); struct wmi_info *winfo; ACPI_STATUS status; @@ -429,7 +431,7 @@ acpi_wmi_install_event_handler_method(device_t dev, const char *guid_string, ACPI_SERIAL_BEGIN(acpi_wmi); if (guid_string == NULL || event_handler == NULL) status = AE_BAD_PARAMETER; - else if ((winfo = acpi_wmi_lookup_wmi_info_by_guid_string(guid_string)) + else if ((winfo = acpi_wmi_lookup_wmi_info_by_guid_string(sc, guid_string)) == NULL) status = AE_NOT_EXIST; else if (winfo->event_handler != NULL || @@ -451,6 +453,7 @@ acpi_wmi_install_event_handler_method(device_t dev, const char *guid_string, static ACPI_STATUS acpi_wmi_remove_event_handler_method(device_t dev, const char *guid_string) { + struct acpi_wmi_softc *sc = device_get_softc(dev); struct wmi_info *winfo; ACPI_STATUS status; @@ -459,7 +462,7 @@ acpi_wmi_remove_event_handler_method(device_t dev, const char *guid_string) status = AE_OK; ACPI_SERIAL_BEGIN(acpi_wmi); if (guid_string && - (winfo = acpi_wmi_lookup_wmi_info_by_guid_string(guid_string)) + (winfo = acpi_wmi_lookup_wmi_info_by_guid_string(sc, guid_string)) != NULL && winfo->event_handler) { status = acpi_wmi_toggle_we_event_generation(dev, winfo, EVENT_GENERATION_OFF); @@ -494,7 +497,7 @@ acpi_wmi_get_event_data_method(device_t dev, UINT32 event_id, ACPI_BUFFER *out) params[0].Integer.Value = event_id; input.Pointer = params; input.Count = 1; - TAILQ_FOREACH(winfo, &wmi_info_list, wmi_list) { + TAILQ_FOREACH(winfo, &sc->wmi_info_list, wmi_list) { if ((winfo->ginfo.flags & ACPI_WMI_REGFLAG_EVENT) && ((UINT8) winfo->ginfo.oid[0] == event_id)) { status = AcpiEvaluateObject(sc->wmi_handle, "_WED", @@ -538,7 +541,7 @@ acpi_wmi_get_block_method(device_t dev, const char *guid_string, UINT8 instance, ACPI_SERIAL_BEGIN(acpi_wmi); if (guid_string == NULL || out == NULL) status = AE_BAD_PARAMETER; - else if ((winfo = acpi_wmi_lookup_wmi_info_by_guid_string(guid_string)) + else if ((winfo = acpi_wmi_lookup_wmi_info_by_guid_string(sc, guid_string)) == NULL) status = AE_ERROR; else if (instance > winfo->ginfo.max_instance) @@ -602,7 +605,7 @@ acpi_wmi_set_block_method(device_t dev, const char *guid_string, UINT8 instance, ACPI_SERIAL_BEGIN(acpi_wmi); if (guid_string == NULL || in == NULL) status = AE_BAD_DATA; - else if ((winfo = acpi_wmi_lookup_wmi_info_by_guid_string(guid_string)) + else if ((winfo = acpi_wmi_lookup_wmi_info_by_guid_string(sc, guid_string)) == NULL) status = AE_ERROR; else if (instance > winfo->ginfo.max_instance) @@ -636,6 +639,7 @@ acpi_wmi_set_block_method(device_t dev, const char *guid_string, UINT8 instance, static void acpi_wmi_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context) { + struct acpi_wmi_softc *sc = context; ACPI_NOTIFY_HANDLER handler; void *handler_data; struct wmi_info *winfo; @@ -645,7 +649,7 @@ acpi_wmi_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context) handler = NULL; handler_data = NULL; ACPI_SERIAL_BEGIN(acpi_wmi); - TAILQ_FOREACH(winfo, &wmi_info_list, wmi_list) { + TAILQ_FOREACH(winfo, &sc->wmi_info_list, wmi_list) { if ((winfo->ginfo.flags & ACPI_WMI_REGFLAG_EVENT) && ((UINT8) winfo->ginfo.oid[0] == notify)) { if (winfo->event_handler) { @@ -719,7 +723,7 @@ acpi_wmi_ec_handler(UINT32 function, ACPI_PHYSICAL_ADDRESS address, * into wmi_info_list. */ static ACPI_STATUS -acpi_wmi_read_wdg_blocks(ACPI_HANDLE h) +acpi_wmi_read_wdg_blocks(struct acpi_wmi_softc *sc, ACPI_HANDLE h) { ACPI_BUFFER out = {ACPI_ALLOCATE_BUFFER, NULL}; struct guid_info *ginfo; @@ -750,7 +754,7 @@ acpi_wmi_read_wdg_blocks(ACPI_HANDLE h) return (AE_NO_MEMORY); } winfo->ginfo = ginfo[i]; - TAILQ_INSERT_TAIL(&wmi_info_list, winfo, wmi_list); + TAILQ_INSERT_TAIL(&sc->wmi_info_list, winfo, wmi_list); } AcpiOsFree(out.Pointer); free(ginfo, M_ACPIWMI); @@ -860,7 +864,7 @@ acpi_wmi_guid_string_to_guid(const UINT8 *guid_string, UINT8 *guid) * Return NULL if the GUID is unknown in the _WDG */ static struct wmi_info* -acpi_wmi_lookup_wmi_info_by_guid_string(const char *guid_string) +acpi_wmi_lookup_wmi_info_by_guid_string(struct acpi_wmi_softc *sc, const char *guid_string) { char guid[16]; struct wmi_info *winfo; @@ -870,7 +874,7 @@ acpi_wmi_lookup_wmi_info_by_guid_string(const char *guid_string) ACPI_SERIAL_ASSERT(acpi_wmi); if (!acpi_wmi_guid_string_to_guid(guid_string, guid)) { - TAILQ_FOREACH(winfo, &wmi_info_list, wmi_list) { + TAILQ_FOREACH(winfo, &sc->wmi_info_list, wmi_list) { if (!memcmp(winfo->ginfo.guid, guid, 16)) { return (winfo); } @@ -969,7 +973,7 @@ acpi_wmi_wmistat_read(struct cdev *dev, struct uio *buf, int flag) sbuf_printf(&sc->wmistat_sbuf, "GUID " " INST EXPE METH STR " "EVENT OID\n"); - TAILQ_FOREACH(winfo, &wmi_info_list, wmi_list) { + TAILQ_FOREACH(winfo, &sc->wmi_info_list, wmi_list) { guid = (UINT8*)winfo->ginfo.guid; sbuf_printf(&sc->wmistat_sbuf, "{%02X%02X%02X%02X-%02X%02X-" -- Andriy Gapon
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?506C6906.9070402>