^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * acpi_ipmi.c - ACPI IPMI opregion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2010, 2013 Intel Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author: Zhao Yakui <yakui.zhao@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Lv Zheng <lv.zheng@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/ipmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) MODULE_AUTHOR("Zhao Yakui");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) MODULE_DESCRIPTION("ACPI IPMI Opregion driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define ACPI_IPMI_OK 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define ACPI_IPMI_TIMEOUT 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define ACPI_IPMI_UNKNOWN 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /* the IPMI timeout is 5s */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define IPMI_TIMEOUT (5000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define ACPI_IPMI_MAX_MSG_LENGTH 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct acpi_ipmi_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /* the device list attached to driver_data.ipmi_devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct list_head head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /* the IPMI request message list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct list_head tx_msg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) spinlock_t tx_msg_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) acpi_handle handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct ipmi_user *user_interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) int ipmi_ifnum; /* IPMI interface number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) long curr_msgid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) bool dead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct kref kref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct ipmi_driver_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct list_head ipmi_devices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct ipmi_smi_watcher bmc_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) const struct ipmi_user_hndl ipmi_hndlrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct mutex ipmi_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * NOTE: IPMI System Interface Selection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * There is no system interface specified by the IPMI operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * region access. We try to select one system interface with ACPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * handle set. IPMI messages passed from the ACPI codes are sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * to this selected global IPMI system interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct acpi_ipmi_device *selected_smi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct acpi_ipmi_msg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct list_head head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * General speaking the addr type should be SI_ADDR_TYPE. And
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * the addr channel should be BMC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * In fact it can also be IPMB type. But we will have to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * parse it from the Netfn command buffer. It is so complex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * that it is skipped.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct ipmi_addr addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) long tx_msgid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* it is used to track whether the IPMI message is finished */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct completion tx_complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct kernel_ipmi_msg tx_message;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) int msg_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* tx/rx data . And copy it from/to ACPI object buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) u8 data[ACPI_IPMI_MAX_MSG_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) u8 rx_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct acpi_ipmi_device *device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct kref kref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /* IPMI request/response buffer per ACPI 4.0, sec 5.5.2.4.3.2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct acpi_ipmi_buffer {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) u8 length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) u8 data[ACPI_IPMI_MAX_MSG_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static void ipmi_register_bmc(int iface, struct device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static void ipmi_bmc_gone(int iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static struct ipmi_driver_data driver_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .ipmi_devices = LIST_HEAD_INIT(driver_data.ipmi_devices),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .bmc_events = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .new_smi = ipmi_register_bmc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) .smi_gone = ipmi_bmc_gone,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) .ipmi_hndlrs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) .ipmi_recv_hndl = ipmi_msg_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) .ipmi_lock = __MUTEX_INITIALIZER(driver_data.ipmi_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static struct acpi_ipmi_device *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) ipmi_dev_alloc(int iface, struct device *dev, acpi_handle handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct acpi_ipmi_device *ipmi_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct ipmi_user *user;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) ipmi_device = kzalloc(sizeof(*ipmi_device), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (!ipmi_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) kref_init(&ipmi_device->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) INIT_LIST_HEAD(&ipmi_device->head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) INIT_LIST_HEAD(&ipmi_device->tx_msg_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) spin_lock_init(&ipmi_device->tx_msg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) ipmi_device->handle = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) ipmi_device->dev = get_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) ipmi_device->ipmi_ifnum = iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) err = ipmi_create_user(iface, &driver_data.ipmi_hndlrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) ipmi_device, &user);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) put_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) kfree(ipmi_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) ipmi_device->user_interface = user;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return ipmi_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static void ipmi_dev_release(struct acpi_ipmi_device *ipmi_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) ipmi_destroy_user(ipmi_device->user_interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) put_device(ipmi_device->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) kfree(ipmi_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static void ipmi_dev_release_kref(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct acpi_ipmi_device *ipmi =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) container_of(kref, struct acpi_ipmi_device, kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) ipmi_dev_release(ipmi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static void __ipmi_dev_kill(struct acpi_ipmi_device *ipmi_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) list_del(&ipmi_device->head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (driver_data.selected_smi == ipmi_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) driver_data.selected_smi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * Always setting dead flag after deleting from the list or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * list_for_each_entry() codes must get changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) ipmi_device->dead = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static struct acpi_ipmi_device *acpi_ipmi_dev_get(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct acpi_ipmi_device *ipmi_device = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) mutex_lock(&driver_data.ipmi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (driver_data.selected_smi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) ipmi_device = driver_data.selected_smi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) kref_get(&ipmi_device->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) mutex_unlock(&driver_data.ipmi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return ipmi_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static void acpi_ipmi_dev_put(struct acpi_ipmi_device *ipmi_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) kref_put(&ipmi_device->kref, ipmi_dev_release_kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static struct acpi_ipmi_msg *ipmi_msg_alloc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct acpi_ipmi_device *ipmi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) struct acpi_ipmi_msg *ipmi_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) ipmi = acpi_ipmi_dev_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (!ipmi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) ipmi_msg = kzalloc(sizeof(struct acpi_ipmi_msg), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (!ipmi_msg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) acpi_ipmi_dev_put(ipmi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) kref_init(&ipmi_msg->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) init_completion(&ipmi_msg->tx_complete);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) INIT_LIST_HEAD(&ipmi_msg->head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) ipmi_msg->device = ipmi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ipmi_msg->msg_done = ACPI_IPMI_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return ipmi_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static void ipmi_msg_release(struct acpi_ipmi_msg *tx_msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) acpi_ipmi_dev_put(tx_msg->device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) kfree(tx_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static void ipmi_msg_release_kref(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) struct acpi_ipmi_msg *tx_msg =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) container_of(kref, struct acpi_ipmi_msg, kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) ipmi_msg_release(tx_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) static struct acpi_ipmi_msg *acpi_ipmi_msg_get(struct acpi_ipmi_msg *tx_msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) kref_get(&tx_msg->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return tx_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static void acpi_ipmi_msg_put(struct acpi_ipmi_msg *tx_msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) kref_put(&tx_msg->kref, ipmi_msg_release_kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) #define IPMI_OP_RGN_NETFN(offset) ((offset >> 8) & 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) #define IPMI_OP_RGN_CMD(offset) (offset & 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static int acpi_format_ipmi_request(struct acpi_ipmi_msg *tx_msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) acpi_physical_address address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) acpi_integer *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct kernel_ipmi_msg *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) struct acpi_ipmi_buffer *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct acpi_ipmi_device *device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) msg = &tx_msg->tx_message;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * IPMI network function and command are encoded in the address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * within the IPMI OpRegion; see ACPI 4.0, sec 5.5.2.4.3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) msg->netfn = IPMI_OP_RGN_NETFN(address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) msg->cmd = IPMI_OP_RGN_CMD(address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) msg->data = tx_msg->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * value is the parameter passed by the IPMI opregion space handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * It points to the IPMI request message buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) buffer = (struct acpi_ipmi_buffer *)value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) /* copy the tx message data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (buffer->length > ACPI_IPMI_MAX_MSG_LENGTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) dev_WARN_ONCE(tx_msg->device->dev, true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) "Unexpected request (msg len %d).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) buffer->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) msg->data_len = buffer->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) memcpy(tx_msg->data, buffer->data, msg->data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * now the default type is SYSTEM_INTERFACE and channel type is BMC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * If the netfn is APP_REQUEST and the cmd is SEND_MESSAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * the addr type should be changed to IPMB. Then we will have to parse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * the IPMI request message buffer to get the IPMB address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * If so, please fix me.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) tx_msg->addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) tx_msg->addr.channel = IPMI_BMC_CHANNEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) tx_msg->addr.data[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /* Get the msgid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) device = tx_msg->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) spin_lock_irqsave(&device->tx_msg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) device->curr_msgid++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) tx_msg->tx_msgid = device->curr_msgid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) spin_unlock_irqrestore(&device->tx_msg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static void acpi_format_ipmi_response(struct acpi_ipmi_msg *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) acpi_integer *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) struct acpi_ipmi_buffer *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * value is also used as output parameter. It represents the response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * IPMI message returned by IPMI command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) buffer = (struct acpi_ipmi_buffer *)value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * If the flag of msg_done is not set, it means that the IPMI command is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * not executed correctly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) buffer->status = msg->msg_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (msg->msg_done != ACPI_IPMI_OK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * If the IPMI response message is obtained correctly, the status code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * will be ACPI_IPMI_OK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) buffer->length = msg->rx_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) memcpy(buffer->data, msg->data, msg->rx_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static void ipmi_flush_tx_msg(struct acpi_ipmi_device *ipmi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) struct acpi_ipmi_msg *tx_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * NOTE: On-going ipmi_recv_msg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) * ipmi_msg_handler() may still be invoked by ipmi_si after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) * flushing. But it is safe to do a fast flushing on module_exit()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * without waiting for all ipmi_recv_msg(s) to complete from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) * ipmi_msg_handler() as it is ensured by ipmi_si that all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) * ipmi_recv_msg(s) are freed after invoking ipmi_destroy_user().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) spin_lock_irqsave(&ipmi->tx_msg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) while (!list_empty(&ipmi->tx_msg_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) tx_msg = list_first_entry(&ipmi->tx_msg_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) struct acpi_ipmi_msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) list_del(&tx_msg->head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) spin_unlock_irqrestore(&ipmi->tx_msg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) /* wake up the sleep thread on the Tx msg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) complete(&tx_msg->tx_complete);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) acpi_ipmi_msg_put(tx_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) spin_lock_irqsave(&ipmi->tx_msg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) spin_unlock_irqrestore(&ipmi->tx_msg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static void ipmi_cancel_tx_msg(struct acpi_ipmi_device *ipmi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) struct acpi_ipmi_msg *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) struct acpi_ipmi_msg *tx_msg, *temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) bool msg_found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) spin_lock_irqsave(&ipmi->tx_msg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) list_for_each_entry_safe(tx_msg, temp, &ipmi->tx_msg_list, head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (msg == tx_msg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) msg_found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) list_del(&tx_msg->head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) spin_unlock_irqrestore(&ipmi->tx_msg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (msg_found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) acpi_ipmi_msg_put(tx_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) struct acpi_ipmi_device *ipmi_device = user_msg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) bool msg_found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) struct acpi_ipmi_msg *tx_msg, *temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) struct device *dev = ipmi_device->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (msg->user != ipmi_device->user_interface) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) dev_warn(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) "Unexpected response is returned. returned user %p, expected user %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) msg->user, ipmi_device->user_interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) goto out_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) list_for_each_entry_safe(tx_msg, temp, &ipmi_device->tx_msg_list, head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (msg->msgid == tx_msg->tx_msgid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) msg_found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) list_del(&tx_msg->head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (!msg_found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) dev_warn(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) "Unexpected response (msg id %ld) is returned.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) msg->msgid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) goto out_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) /* copy the response data to Rx_data buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (msg->msg.data_len > ACPI_IPMI_MAX_MSG_LENGTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) dev_WARN_ONCE(dev, true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) "Unexpected response (msg len %d).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) msg->msg.data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) goto out_comp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) /* response msg is an error msg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) msg->recv_type = IPMI_RESPONSE_RECV_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (msg->recv_type == IPMI_RESPONSE_RECV_TYPE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) msg->msg.data_len == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (msg->msg.data[0] == IPMI_TIMEOUT_COMPLETION_CODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) dev_dbg_once(dev, "Unexpected response (timeout).\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) tx_msg->msg_done = ACPI_IPMI_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) goto out_comp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) tx_msg->rx_len = msg->msg.data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) memcpy(tx_msg->data, msg->msg.data, tx_msg->rx_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) tx_msg->msg_done = ACPI_IPMI_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) out_comp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) complete(&tx_msg->tx_complete);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) acpi_ipmi_msg_put(tx_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) out_msg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) ipmi_free_recv_msg(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static void ipmi_register_bmc(int iface, struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) struct acpi_ipmi_device *ipmi_device, *temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct ipmi_smi_info smi_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) acpi_handle handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) err = ipmi_get_smi_info(iface, &smi_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (smi_data.addr_src != SI_ACPI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) goto err_ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) handle = smi_data.addr_info.acpi_info.acpi_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (!handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) goto err_ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) ipmi_device = ipmi_dev_alloc(iface, smi_data.dev, handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (!ipmi_device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) dev_warn(smi_data.dev, "Can't create IPMI user interface\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) goto err_ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) mutex_lock(&driver_data.ipmi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) list_for_each_entry(temp, &driver_data.ipmi_devices, head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) * if the corresponding ACPI handle is already added
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * to the device list, don't add it again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (temp->handle == handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) goto err_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (!driver_data.selected_smi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) driver_data.selected_smi = ipmi_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) list_add_tail(&ipmi_device->head, &driver_data.ipmi_devices);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) mutex_unlock(&driver_data.ipmi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) put_device(smi_data.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) err_lock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) mutex_unlock(&driver_data.ipmi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) ipmi_dev_release(ipmi_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) err_ref:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) put_device(smi_data.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) static void ipmi_bmc_gone(int iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct acpi_ipmi_device *ipmi_device, *temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) bool dev_found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) mutex_lock(&driver_data.ipmi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) list_for_each_entry_safe(ipmi_device, temp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) &driver_data.ipmi_devices, head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (ipmi_device->ipmi_ifnum != iface) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) dev_found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) __ipmi_dev_kill(ipmi_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (!driver_data.selected_smi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) driver_data.selected_smi = list_first_entry_or_null(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) &driver_data.ipmi_devices,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) struct acpi_ipmi_device, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) mutex_unlock(&driver_data.ipmi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (dev_found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) ipmi_flush_tx_msg(ipmi_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) acpi_ipmi_dev_put(ipmi_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * This is the IPMI opregion space handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * @function: indicates the read/write. In fact as the IPMI message is driven
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) * by command, only write is meaningful.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) * @address: This contains the netfn/command of IPMI request message.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * @bits : not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) * @value : it is an in/out parameter. It points to the IPMI message buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) * Before the IPMI message is sent, it represents the actual request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) * IPMI message. After the IPMI message is finished, it represents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * the response IPMI message returned by IPMI command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * @handler_context: IPMI device context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) static acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) acpi_ipmi_space_handler(u32 function, acpi_physical_address address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) u32 bits, acpi_integer *value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) void *handler_context, void *region_context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) struct acpi_ipmi_msg *tx_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) struct acpi_ipmi_device *ipmi_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) * IPMI opregion message.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * IPMI message is firstly written to the BMC and system software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * can get the respsonse. So it is unmeaningful for the read access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * of IPMI opregion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if ((function & ACPI_IO_MASK) == ACPI_READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) return AE_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) tx_msg = ipmi_msg_alloc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (!tx_msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) return AE_NOT_EXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) ipmi_device = tx_msg->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (acpi_format_ipmi_request(tx_msg, address, value) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) ipmi_msg_release(tx_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) return AE_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) acpi_ipmi_msg_get(tx_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) mutex_lock(&driver_data.ipmi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) /* Do not add a tx_msg that can not be flushed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (ipmi_device->dead) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) mutex_unlock(&driver_data.ipmi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) ipmi_msg_release(tx_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) return AE_NOT_EXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) list_add_tail(&tx_msg->head, &ipmi_device->tx_msg_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) mutex_unlock(&driver_data.ipmi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) err = ipmi_request_settime(ipmi_device->user_interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) &tx_msg->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) tx_msg->tx_msgid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) &tx_msg->tx_message,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) NULL, 0, 0, IPMI_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) status = AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) goto out_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) wait_for_completion(&tx_msg->tx_complete);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) acpi_format_ipmi_response(tx_msg, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) status = AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) out_msg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) ipmi_cancel_tx_msg(ipmi_device, tx_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) acpi_ipmi_msg_put(tx_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) static int __init acpi_ipmi_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (acpi_disabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) ACPI_ADR_SPACE_IPMI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) &acpi_ipmi_space_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) pr_warn("Can't register IPMI opregion space handle\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) result = ipmi_smi_watcher_register(&driver_data.bmc_events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) pr_err("Can't register IPMI system interface watcher\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) static void __exit acpi_ipmi_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) struct acpi_ipmi_device *ipmi_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (acpi_disabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) ipmi_smi_watcher_unregister(&driver_data.bmc_events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) * When one smi_watcher is unregistered, it is only deleted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) * from the smi_watcher list. But the smi_gone callback function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) * is not called. So explicitly uninstall the ACPI IPMI oregion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * handler and free it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) mutex_lock(&driver_data.ipmi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) while (!list_empty(&driver_data.ipmi_devices)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) ipmi_device = list_first_entry(&driver_data.ipmi_devices,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) struct acpi_ipmi_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) __ipmi_dev_kill(ipmi_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) mutex_unlock(&driver_data.ipmi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) ipmi_flush_tx_msg(ipmi_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) acpi_ipmi_dev_put(ipmi_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) mutex_lock(&driver_data.ipmi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) mutex_unlock(&driver_data.ipmi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) ACPI_ADR_SPACE_IPMI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) &acpi_ipmi_space_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) module_init(acpi_ipmi_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) module_exit(acpi_ipmi_exit);