Lines Matching +full:ipmi +full:- +full:ipmb

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * acpi_ipmi.c - ACPI IPMI opregion
12 #include <linux/ipmi.h>
16 MODULE_DESCRIPTION("ACPI IPMI Opregion driver");
22 /* the IPMI timeout is 5s */
30 /* the IPMI request message list */
37 int ipmi_ifnum; /* IPMI interface number */
50 * NOTE: IPMI System Interface Selection
51 * There is no system interface specified by the IPMI operation
53 * handle set. IPMI messages passed from the ACPI codes are sent
54 * to this selected global IPMI system interface.
65 * In fact it can also be IPMB type. But we will have to
72 /* it is used to track whether the IPMI message is finished */
86 /* IPMI request/response buffer per ACPI 4.0, sec 5.5.2.4.3.2 */
121 kref_init(&ipmi_device->kref); in ipmi_dev_alloc()
122 INIT_LIST_HEAD(&ipmi_device->head); in ipmi_dev_alloc()
123 INIT_LIST_HEAD(&ipmi_device->tx_msg_list); in ipmi_dev_alloc()
124 spin_lock_init(&ipmi_device->tx_msg_lock); in ipmi_dev_alloc()
125 ipmi_device->handle = handle; in ipmi_dev_alloc()
126 ipmi_device->dev = get_device(dev); in ipmi_dev_alloc()
127 ipmi_device->ipmi_ifnum = iface; in ipmi_dev_alloc()
136 ipmi_device->user_interface = user; in ipmi_dev_alloc()
143 ipmi_destroy_user(ipmi_device->user_interface); in ipmi_dev_release()
144 put_device(ipmi_device->dev); in ipmi_dev_release()
150 struct acpi_ipmi_device *ipmi = in ipmi_dev_release_kref() local
153 ipmi_dev_release(ipmi); in ipmi_dev_release_kref()
158 list_del(&ipmi_device->head); in __ipmi_dev_kill()
166 ipmi_device->dead = true; in __ipmi_dev_kill()
176 kref_get(&ipmi_device->kref); in acpi_ipmi_dev_get()
185 kref_put(&ipmi_device->kref, ipmi_dev_release_kref); in acpi_ipmi_dev_put()
190 struct acpi_ipmi_device *ipmi; in ipmi_msg_alloc() local
193 ipmi = acpi_ipmi_dev_get(); in ipmi_msg_alloc()
194 if (!ipmi) in ipmi_msg_alloc()
199 acpi_ipmi_dev_put(ipmi); in ipmi_msg_alloc()
203 kref_init(&ipmi_msg->kref); in ipmi_msg_alloc()
204 init_completion(&ipmi_msg->tx_complete); in ipmi_msg_alloc()
205 INIT_LIST_HEAD(&ipmi_msg->head); in ipmi_msg_alloc()
206 ipmi_msg->device = ipmi; in ipmi_msg_alloc()
207 ipmi_msg->msg_done = ACPI_IPMI_UNKNOWN; in ipmi_msg_alloc()
214 acpi_ipmi_dev_put(tx_msg->device); in ipmi_msg_release()
228 kref_get(&tx_msg->kref); in acpi_ipmi_msg_get()
235 kref_put(&tx_msg->kref, ipmi_msg_release_kref); in acpi_ipmi_msg_put()
249 msg = &tx_msg->tx_message; in acpi_format_ipmi_request()
252 * IPMI network function and command are encoded in the address in acpi_format_ipmi_request()
253 * within the IPMI OpRegion; see ACPI 4.0, sec 5.5.2.4.3. in acpi_format_ipmi_request()
255 msg->netfn = IPMI_OP_RGN_NETFN(address); in acpi_format_ipmi_request()
256 msg->cmd = IPMI_OP_RGN_CMD(address); in acpi_format_ipmi_request()
257 msg->data = tx_msg->data; in acpi_format_ipmi_request()
260 * value is the parameter passed by the IPMI opregion space handler. in acpi_format_ipmi_request()
261 * It points to the IPMI request message buffer in acpi_format_ipmi_request()
266 if (buffer->length > ACPI_IPMI_MAX_MSG_LENGTH) { in acpi_format_ipmi_request()
267 dev_WARN_ONCE(tx_msg->device->dev, true, in acpi_format_ipmi_request()
269 buffer->length); in acpi_format_ipmi_request()
270 return -EINVAL; in acpi_format_ipmi_request()
272 msg->data_len = buffer->length; in acpi_format_ipmi_request()
273 memcpy(tx_msg->data, buffer->data, msg->data_len); in acpi_format_ipmi_request()
278 * the addr type should be changed to IPMB. Then we will have to parse in acpi_format_ipmi_request()
279 * the IPMI request message buffer to get the IPMB address. in acpi_format_ipmi_request()
282 tx_msg->addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; in acpi_format_ipmi_request()
283 tx_msg->addr.channel = IPMI_BMC_CHANNEL; in acpi_format_ipmi_request()
284 tx_msg->addr.data[0] = 0; in acpi_format_ipmi_request()
287 device = tx_msg->device; in acpi_format_ipmi_request()
289 spin_lock_irqsave(&device->tx_msg_lock, flags); in acpi_format_ipmi_request()
290 device->curr_msgid++; in acpi_format_ipmi_request()
291 tx_msg->tx_msgid = device->curr_msgid; in acpi_format_ipmi_request()
292 spin_unlock_irqrestore(&device->tx_msg_lock, flags); in acpi_format_ipmi_request()
304 * IPMI message returned by IPMI command. in acpi_format_ipmi_response()
309 * If the flag of msg_done is not set, it means that the IPMI command is in acpi_format_ipmi_response()
312 buffer->status = msg->msg_done; in acpi_format_ipmi_response()
313 if (msg->msg_done != ACPI_IPMI_OK) in acpi_format_ipmi_response()
317 * If the IPMI response message is obtained correctly, the status code in acpi_format_ipmi_response()
320 buffer->length = msg->rx_len; in acpi_format_ipmi_response()
321 memcpy(buffer->data, msg->data, msg->rx_len); in acpi_format_ipmi_response()
324 static void ipmi_flush_tx_msg(struct acpi_ipmi_device *ipmi) in ipmi_flush_tx_msg() argument
330 * NOTE: On-going ipmi_recv_msg in ipmi_flush_tx_msg()
337 spin_lock_irqsave(&ipmi->tx_msg_lock, flags); in ipmi_flush_tx_msg()
338 while (!list_empty(&ipmi->tx_msg_list)) { in ipmi_flush_tx_msg()
339 tx_msg = list_first_entry(&ipmi->tx_msg_list, in ipmi_flush_tx_msg()
342 list_del(&tx_msg->head); in ipmi_flush_tx_msg()
343 spin_unlock_irqrestore(&ipmi->tx_msg_lock, flags); in ipmi_flush_tx_msg()
346 complete(&tx_msg->tx_complete); in ipmi_flush_tx_msg()
348 spin_lock_irqsave(&ipmi->tx_msg_lock, flags); in ipmi_flush_tx_msg()
350 spin_unlock_irqrestore(&ipmi->tx_msg_lock, flags); in ipmi_flush_tx_msg()
353 static void ipmi_cancel_tx_msg(struct acpi_ipmi_device *ipmi, in ipmi_cancel_tx_msg() argument
359 spin_lock_irqsave(&ipmi->tx_msg_lock, flags); in ipmi_cancel_tx_msg()
360 list_for_each_entry_safe(iter, temp, &ipmi->tx_msg_list, head) { in ipmi_cancel_tx_msg()
363 list_del(&iter->head); in ipmi_cancel_tx_msg()
367 spin_unlock_irqrestore(&ipmi->tx_msg_lock, flags); in ipmi_cancel_tx_msg()
377 struct device *dev = ipmi_device->dev; in ipmi_msg_handler()
380 if (msg->user != ipmi_device->user_interface) { in ipmi_msg_handler()
383 msg->user, ipmi_device->user_interface); in ipmi_msg_handler()
387 spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); in ipmi_msg_handler()
388 list_for_each_entry_safe(iter, temp, &ipmi_device->tx_msg_list, head) { in ipmi_msg_handler()
389 if (msg->msgid == iter->tx_msgid) { in ipmi_msg_handler()
391 list_del(&iter->head); in ipmi_msg_handler()
395 spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); in ipmi_msg_handler()
400 msg->msgid); in ipmi_msg_handler()
405 if (msg->msg.data_len > ACPI_IPMI_MAX_MSG_LENGTH) { in ipmi_msg_handler()
408 msg->msg.data_len); in ipmi_msg_handler()
413 msg->recv_type = IPMI_RESPONSE_RECV_TYPE; in ipmi_msg_handler()
414 if (msg->recv_type == IPMI_RESPONSE_RECV_TYPE && in ipmi_msg_handler()
415 msg->msg.data_len == 1) { in ipmi_msg_handler()
416 if (msg->msg.data[0] == IPMI_TIMEOUT_COMPLETION_CODE) { in ipmi_msg_handler()
418 tx_msg->msg_done = ACPI_IPMI_TIMEOUT; in ipmi_msg_handler()
423 tx_msg->rx_len = msg->msg.data_len; in ipmi_msg_handler()
424 memcpy(tx_msg->data, msg->msg.data, tx_msg->rx_len); in ipmi_msg_handler()
425 tx_msg->msg_done = ACPI_IPMI_OK; in ipmi_msg_handler()
428 complete(&tx_msg->tx_complete); in ipmi_msg_handler()
453 dev_warn(smi_data.dev, "Can't create IPMI user interface\n"); in ipmi_register_bmc()
463 if (temp->handle == handle) in ipmi_register_bmc()
468 list_add_tail(&ipmi_device->head, &driver_data.ipmi_devices); in ipmi_register_bmc()
488 if (iter->ipmi_ifnum != iface) { in ipmi_bmc_gone()
507 * This is the IPMI opregion space handler.
508 * @function: indicates the read/write. In fact as the IPMI message is driven
510 * @address: This contains the netfn/command of IPMI request message.
512 * @value : it is an in/out parameter. It points to the IPMI message buffer.
513 * Before the IPMI message is sent, it represents the actual request
514 * IPMI message. After the IPMI message is finished, it represents
515 * the response IPMI message returned by IPMI command.
516 * @handler_context: IPMI device context.
530 * IPMI opregion message. in acpi_ipmi_space_handler()
531 * IPMI message is firstly written to the BMC and system software in acpi_ipmi_space_handler()
533 * of IPMI opregion. in acpi_ipmi_space_handler()
541 ipmi_device = tx_msg->device; in acpi_ipmi_space_handler()
551 if (ipmi_device->dead) { in acpi_ipmi_space_handler()
556 spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); in acpi_ipmi_space_handler()
557 list_add_tail(&tx_msg->head, &ipmi_device->tx_msg_list); in acpi_ipmi_space_handler()
558 spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); in acpi_ipmi_space_handler()
561 err = ipmi_request_settime(ipmi_device->user_interface, in acpi_ipmi_space_handler()
562 &tx_msg->addr, in acpi_ipmi_space_handler()
563 tx_msg->tx_msgid, in acpi_ipmi_space_handler()
564 &tx_msg->tx_message, in acpi_ipmi_space_handler()
570 wait_for_completion(&tx_msg->tx_complete); in acpi_ipmi_space_handler()
594 pr_warn("Can't register IPMI opregion space handle\n"); in acpi_ipmi_init()
595 return -EINVAL; in acpi_ipmi_init()
603 pr_err("Can't register IPMI system interface watcher\n"); in acpi_ipmi_init()
621 * is not called. So explicitly uninstall the ACPI IPMI oregion in acpi_ipmi_exit()