Lines Matching +full:ipmi +full:- +full:ipmb
1 // SPDX-License-Identifier: GPL-2.0+
5 * Incoming and outgoing message routing for an IPMI interface.
14 #define pr_fmt(fmt) "IPMI message handler: " fmt
26 #include <linux/ipmi.h>
85 e = match_string(ipmi_panic_event_str, -1, strstrip(valcp)); in panic_op_write_handler()
110 …IPMI driver will attempt to store panic information in the event log in the event of a panic. Set…
115 /* Remain in auto-maintenance mode for this amount of time (in ms). */
156 "The most users that may use the IPMI stack at one time.");
173 * future, IPMI will add a way to know immediately if an event is in
197 /* Does this interface receive IPMI events? */
313 * Various statistics for IPMI, these index stats[] in the ipmi_smi
329 /* Commands we sent out to the IPMB bus. */
332 /* Commands sent on the IPMB that had errors on the SEND CMD */
351 /* Responses I have sent to the IPMB bus. */
363 /* Commands we sent out to the IPMB bus. */
366 /* Commands sent on the IPMB that had errors on the SEND CMD */
378 /* Responses I have sent to the IPMB bus. */
405 /* Retransmissions on IPMB that failed. */
463 /* Driver-model device for the system interface. */
468 * sequence numbers for IPMB messages that go out of the
556 * If we are doing maintenance on something on IPMB, extend
563 * A cheap hack, if this is non-null and a message to an
591 * parameters passed by "low" level IPMI code.
609 owner = user->intf->owner; in free_ipmi_user()
610 kref_put(&user->intf->refcount, intf_free); in free_ipmi_user()
617 kref_put(&user->refcount, free_ipmi_user); in release_ipmi_user()
622 if (!kref_get_unless_zero(&user->refcount)) in acquire_ipmi_user()
628 * The driver model view of the IPMI messaging driver.
632 .name = "ipmi",
651 atomic_inc(&(intf)->stats[IPMI_STAT_ ## stat])
653 ((unsigned int) atomic_read(&(intf)->stats[IPMI_STAT_ ## stat]))
657 "device-tree", "platform"
670 return addr->addr_type == IPMI_LAN_ADDR_TYPE; in is_lan_addr()
675 return addr->addr_type == IPMI_IPMB_ADDR_TYPE; in is_ipmb_addr()
680 return addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE; in is_ipmb_bcast_addr()
685 return addr->addr_type == IPMI_IPMB_DIRECT_ADDR_TYPE; in is_ipmb_direct_addr()
693 list_del(&msg->link); in free_recv_msg_list()
703 list_del(&msg->link); in free_smi_msg_list()
714 free_smi_msg_list(&intf->waiting_rcv_msgs); in intf_free()
715 free_recv_msg_list(&intf->waiting_events); in intf_free()
719 * interface. No need for locks, this is single-threaded. in intf_free()
721 list_for_each_entry_safe(rcvr, rcvr2, &intf->cmd_rcvrs, link) in intf_free()
725 if ((intf->seq_table[i].inuse) in intf_free()
726 && (intf->seq_table[i].recv_msg)) in intf_free()
727 ipmi_free_recv_msg(intf->seq_table[i].recv_msg); in intf_free()
751 list_add(&watcher->link, &smi_watchers); in ipmi_smi_watcher_register()
754 * Build an array of ipmi interfaces and fill it in, and in ipmi_smi_watcher_register()
766 rv = -ENOMEM; in ipmi_smi_watcher_register()
773 rv = -ENOMEM; in ipmi_smi_watcher_register()
780 int intf_num = READ_ONCE(intf->intf_num); in ipmi_smi_watcher_register()
782 if (intf_num == -1) in ipmi_smi_watcher_register()
784 devices[count] = intf->si_dev; in ipmi_smi_watcher_register()
792 watcher->new_smi(interfaces[i], devices[i]); in ipmi_smi_watcher_register()
806 list_del(&watcher->link); in ipmi_smi_watcher_unregister()
818 if (try_module_get(w->owner)) { in call_smi_watchers()
819 w->new_smi(i, dev); in call_smi_watchers()
820 module_put(w->owner); in call_smi_watchers()
828 if (addr1->addr_type != addr2->addr_type) in ipmi_addr_equal()
831 if (addr1->channel != addr2->channel) in ipmi_addr_equal()
834 if (addr1->addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) { in ipmi_addr_equal()
839 return (smi_addr1->lun == smi_addr2->lun); in ipmi_addr_equal()
848 return ((ipmb_addr1->slave_addr == ipmb_addr2->slave_addr) in ipmi_addr_equal()
849 && (ipmb_addr1->lun == ipmb_addr2->lun)); in ipmi_addr_equal()
858 return daddr1->slave_addr == daddr2->slave_addr && in ipmi_addr_equal()
859 daddr1->rq_lun == daddr2->rq_lun && in ipmi_addr_equal()
860 daddr1->rs_lun == daddr2->rs_lun; in ipmi_addr_equal()
869 return ((lan_addr1->remote_SWID == lan_addr2->remote_SWID) in ipmi_addr_equal()
870 && (lan_addr1->local_SWID == lan_addr2->local_SWID) in ipmi_addr_equal()
871 && (lan_addr1->session_handle in ipmi_addr_equal()
872 == lan_addr2->session_handle) in ipmi_addr_equal()
873 && (lan_addr1->lun == lan_addr2->lun)); in ipmi_addr_equal()
882 return -EINVAL; in ipmi_validate_addr()
884 if (addr->addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) { in ipmi_validate_addr()
885 if (addr->channel != IPMI_BMC_CHANNEL) in ipmi_validate_addr()
886 return -EINVAL; in ipmi_validate_addr()
890 if ((addr->channel == IPMI_BMC_CHANNEL) in ipmi_validate_addr()
891 || (addr->channel >= IPMI_MAX_CHANNELS) in ipmi_validate_addr()
892 || (addr->channel < 0)) in ipmi_validate_addr()
893 return -EINVAL; in ipmi_validate_addr()
897 return -EINVAL; in ipmi_validate_addr()
904 if (addr->channel != 0) in ipmi_validate_addr()
905 return -EINVAL; in ipmi_validate_addr()
907 return -EINVAL; in ipmi_validate_addr()
909 if (daddr->slave_addr & 0x01) in ipmi_validate_addr()
910 return -EINVAL; in ipmi_validate_addr()
911 if (daddr->rq_lun >= 4) in ipmi_validate_addr()
912 return -EINVAL; in ipmi_validate_addr()
913 if (daddr->rs_lun >= 4) in ipmi_validate_addr()
914 return -EINVAL; in ipmi_validate_addr()
920 return -EINVAL; in ipmi_validate_addr()
924 return -EINVAL; in ipmi_validate_addr()
951 if (!msg->user) { in deliver_response()
953 if (intf->null_user_handler) { in deliver_response()
954 intf->null_user_handler(intf, msg); in deliver_response()
957 rv = -EINVAL; in deliver_response()
972 mutex_lock(&intf->user_msgs_mutex); in deliver_response()
973 list_add_tail(&msg->link, &intf->user_msgs); in deliver_response()
974 mutex_unlock(&intf->user_msgs_mutex); in deliver_response()
975 queue_work(system_wq, &intf->smi_work); in deliver_response()
993 msg->recv_type = IPMI_RESPONSE_RECV_TYPE; in deliver_err_response()
994 msg->msg_data[0] = err; in deliver_err_response()
995 msg->msg.netfn |= 1; /* Convert to a response. */ in deliver_err_response()
996 msg->msg.data_len = 1; in deliver_err_response()
997 msg->msg.data = msg->msg_data; in deliver_err_response()
1005 if (!intf->handlers->set_need_watch) in smi_add_watch()
1008 spin_lock_irqsave(&intf->watch_lock, iflags); in smi_add_watch()
1010 intf->response_waiters++; in smi_add_watch()
1013 intf->watchdog_waiters++; in smi_add_watch()
1016 intf->command_waiters++; in smi_add_watch()
1018 if ((intf->last_watch_mask & flags) != flags) { in smi_add_watch()
1019 intf->last_watch_mask |= flags; in smi_add_watch()
1020 intf->handlers->set_need_watch(intf->send_info, in smi_add_watch()
1021 intf->last_watch_mask); in smi_add_watch()
1023 spin_unlock_irqrestore(&intf->watch_lock, iflags); in smi_add_watch()
1030 if (!intf->handlers->set_need_watch) in smi_remove_watch()
1033 spin_lock_irqsave(&intf->watch_lock, iflags); in smi_remove_watch()
1035 intf->response_waiters--; in smi_remove_watch()
1038 intf->watchdog_waiters--; in smi_remove_watch()
1041 intf->command_waiters--; in smi_remove_watch()
1044 if (intf->response_waiters) in smi_remove_watch()
1046 if (intf->watchdog_waiters) in smi_remove_watch()
1048 if (intf->command_waiters) in smi_remove_watch()
1051 if (intf->last_watch_mask != flags) { in smi_remove_watch()
1052 intf->last_watch_mask = flags; in smi_remove_watch()
1053 intf->handlers->set_need_watch(intf->send_info, in smi_remove_watch()
1054 intf->last_watch_mask); in smi_remove_watch()
1056 spin_unlock_irqrestore(&intf->watch_lock, iflags); in smi_remove_watch()
1080 for (i = intf->curr_seq; (i+1)%IPMI_IPMB_NUM_SEQ != intf->curr_seq; in intf_next_seq()
1082 if (!intf->seq_table[i].inuse) in intf_next_seq()
1086 if (!intf->seq_table[i].inuse) { in intf_next_seq()
1087 intf->seq_table[i].recv_msg = recv_msg; in intf_next_seq()
1093 intf->seq_table[i].timeout = MAX_MSG_TIMEOUT; in intf_next_seq()
1094 intf->seq_table[i].orig_timeout = timeout; in intf_next_seq()
1095 intf->seq_table[i].retries_left = retries; in intf_next_seq()
1096 intf->seq_table[i].broadcast = broadcast; in intf_next_seq()
1097 intf->seq_table[i].inuse = 1; in intf_next_seq()
1098 intf->seq_table[i].seqid = NEXT_SEQID(intf->seq_table[i].seqid); in intf_next_seq()
1100 *seqid = intf->seq_table[i].seqid; in intf_next_seq()
1101 intf->curr_seq = (i+1)%IPMI_IPMB_NUM_SEQ; in intf_next_seq()
1105 rv = -EAGAIN; in intf_next_seq()
1126 int rv = -ENODEV; in intf_find_seq()
1129 return -EINVAL; in intf_find_seq()
1131 mutex_lock(&intf->seq_lock); in intf_find_seq()
1132 if (intf->seq_table[seq].inuse) { in intf_find_seq()
1133 struct ipmi_recv_msg *msg = intf->seq_table[seq].recv_msg; in intf_find_seq()
1135 if ((msg->addr.channel == channel) && (msg->msg.cmd == cmd) in intf_find_seq()
1136 && (msg->msg.netfn == netfn) in intf_find_seq()
1137 && (ipmi_addr_equal(addr, &msg->addr))) { in intf_find_seq()
1139 intf->seq_table[seq].inuse = 0; in intf_find_seq()
1144 mutex_unlock(&intf->seq_lock); in intf_find_seq()
1154 int rv = -ENODEV; in intf_start_seq_timer()
1161 mutex_lock(&intf->seq_lock); in intf_start_seq_timer()
1166 if ((intf->seq_table[seq].inuse) in intf_start_seq_timer()
1167 && (intf->seq_table[seq].seqid == seqid)) { in intf_start_seq_timer()
1168 struct seq_table *ent = &intf->seq_table[seq]; in intf_start_seq_timer()
1169 ent->timeout = ent->orig_timeout; in intf_start_seq_timer()
1172 mutex_unlock(&intf->seq_lock); in intf_start_seq_timer()
1182 int rv = -ENODEV; in intf_err_seq()
1190 mutex_lock(&intf->seq_lock); in intf_err_seq()
1195 if ((intf->seq_table[seq].inuse) in intf_err_seq()
1196 && (intf->seq_table[seq].seqid == seqid)) { in intf_err_seq()
1197 struct seq_table *ent = &intf->seq_table[seq]; in intf_err_seq()
1199 ent->inuse = 0; in intf_err_seq()
1201 msg = ent->recv_msg; in intf_err_seq()
1204 mutex_unlock(&intf->seq_lock); in intf_err_seq()
1230 return -EINVAL; in ipmi_create_user()
1242 if (intf->intf_num == if_num) in ipmi_create_user()
1246 rv = -EINVAL; in ipmi_create_user()
1250 if (intf->in_shutdown) { in ipmi_create_user()
1251 rv = -ENODEV; in ipmi_create_user()
1255 if (atomic_add_return(1, &intf->nr_users) > max_users) { in ipmi_create_user()
1256 rv = -EBUSY; in ipmi_create_user()
1262 rv = -ENOMEM; in ipmi_create_user()
1266 if (!try_module_get(intf->owner)) { in ipmi_create_user()
1267 rv = -ENODEV; in ipmi_create_user()
1272 kref_get(&intf->refcount); in ipmi_create_user()
1274 atomic_set(&new_user->nr_msgs, 0); in ipmi_create_user()
1275 kref_init(&new_user->refcount); in ipmi_create_user()
1276 refcount_set(&new_user->destroyed, 1); in ipmi_create_user()
1277 kref_get(&new_user->refcount); /* Destroy owns a refcount. */ in ipmi_create_user()
1278 new_user->handler = handler; in ipmi_create_user()
1279 new_user->handler_data = handler_data; in ipmi_create_user()
1280 new_user->intf = intf; in ipmi_create_user()
1281 new_user->gets_events = false; in ipmi_create_user()
1283 mutex_lock(&intf->users_mutex); in ipmi_create_user()
1284 mutex_lock(&intf->seq_lock); in ipmi_create_user()
1285 list_add(&new_user->link, &intf->users); in ipmi_create_user()
1286 mutex_unlock(&intf->seq_lock); in ipmi_create_user()
1287 mutex_unlock(&intf->users_mutex); in ipmi_create_user()
1289 if (handler->ipmi_watchdog_pretimeout) in ipmi_create_user()
1295 atomic_dec(&intf->nr_users); in ipmi_create_user()
1308 int rv = -EINVAL; in ipmi_get_smi_info()
1313 if (intf->intf_num == if_num) { in ipmi_get_smi_info()
1314 if (!intf->handlers->get_smi_info) in ipmi_get_smi_info()
1315 rv = -ENOTTY; in ipmi_get_smi_info()
1317 rv = intf->handlers->get_smi_info(intf->send_info, data); in ipmi_get_smi_info()
1327 /* Must be called with intf->users_mutex held. */
1330 struct ipmi_smi *intf = user->intf; in _ipmi_destroy_user()
1336 if (!refcount_dec_if_one(&user->destroyed)) in _ipmi_destroy_user()
1339 if (user->handler->shutdown) in _ipmi_destroy_user()
1340 user->handler->shutdown(user->handler_data); in _ipmi_destroy_user()
1342 if (user->handler->ipmi_watchdog_pretimeout) in _ipmi_destroy_user()
1345 if (user->gets_events) in _ipmi_destroy_user()
1346 atomic_dec(&intf->event_waiters); in _ipmi_destroy_user()
1349 list_del(&user->link); in _ipmi_destroy_user()
1350 atomic_dec(&intf->nr_users); in _ipmi_destroy_user()
1352 mutex_lock(&intf->seq_lock); in _ipmi_destroy_user()
1354 if (intf->seq_table[i].inuse in _ipmi_destroy_user()
1355 && (intf->seq_table[i].recv_msg->user == user)) { in _ipmi_destroy_user()
1356 intf->seq_table[i].inuse = 0; in _ipmi_destroy_user()
1358 ipmi_free_recv_msg(intf->seq_table[i].recv_msg); in _ipmi_destroy_user()
1361 mutex_unlock(&intf->seq_lock); in _ipmi_destroy_user()
1369 mutex_lock(&intf->cmd_rcvrs_mutex); in _ipmi_destroy_user()
1370 list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link, in _ipmi_destroy_user()
1371 lockdep_is_held(&intf->cmd_rcvrs_mutex)) { in _ipmi_destroy_user()
1372 if (rcvr->user == user) { in _ipmi_destroy_user()
1373 list_del_rcu(&rcvr->link); in _ipmi_destroy_user()
1374 rcvr->next = rcvrs; in _ipmi_destroy_user()
1378 mutex_unlock(&intf->cmd_rcvrs_mutex); in _ipmi_destroy_user()
1381 rcvrs = rcvr->next; in _ipmi_destroy_user()
1385 mutex_lock(&intf->user_msgs_mutex); in _ipmi_destroy_user()
1386 list_for_each_entry_safe(msg, msg2, &intf->user_msgs, link) { in _ipmi_destroy_user()
1387 if (msg->user != user) in _ipmi_destroy_user()
1389 list_del(&msg->link); in _ipmi_destroy_user()
1392 mutex_unlock(&intf->user_msgs_mutex); in _ipmi_destroy_user()
1399 struct ipmi_smi *intf = user->intf; in ipmi_destroy_user()
1401 mutex_lock(&intf->users_mutex); in ipmi_destroy_user()
1403 mutex_unlock(&intf->users_mutex); in ipmi_destroy_user()
1405 kref_put(&user->refcount, free_ipmi_user); in ipmi_destroy_user()
1418 return -ENODEV; in ipmi_get_version()
1420 rv = bmc_get_device_id(user->intf, NULL, &id, NULL, NULL); in ipmi_get_version()
1439 return -ENODEV; in ipmi_set_my_address()
1442 rv = -EINVAL; in ipmi_set_my_address()
1445 user->intf->addrinfo[channel].address = address; in ipmi_set_my_address()
1461 return -ENODEV; in ipmi_get_my_address()
1464 rv = -EINVAL; in ipmi_get_my_address()
1467 *address = user->intf->addrinfo[channel].address; in ipmi_get_my_address()
1483 return -ENODEV; in ipmi_set_my_LUN()
1486 rv = -EINVAL; in ipmi_set_my_LUN()
1489 user->intf->addrinfo[channel].lun = LUN & 0x3; in ipmi_set_my_LUN()
1505 return -ENODEV; in ipmi_get_my_LUN()
1508 rv = -EINVAL; in ipmi_get_my_LUN()
1511 *address = user->intf->addrinfo[channel].lun; in ipmi_get_my_LUN()
1526 return -ENODEV; in ipmi_get_maintenance_mode()
1528 spin_lock_irqsave(&user->intf->maintenance_mode_lock, flags); in ipmi_get_maintenance_mode()
1529 mode = user->intf->maintenance_mode; in ipmi_get_maintenance_mode()
1530 spin_unlock_irqrestore(&user->intf->maintenance_mode_lock, flags); in ipmi_get_maintenance_mode()
1539 if (intf->handlers->set_maintenance_mode) in maintenance_mode_update()
1545 intf->handlers->set_maintenance_mode( in maintenance_mode_update()
1546 intf->send_info, in maintenance_mode_update()
1547 (intf->maintenance_mode_state == in maintenance_mode_update()
1555 struct ipmi_smi *intf = user->intf; in ipmi_set_maintenance_mode()
1559 return -ENODEV; in ipmi_set_maintenance_mode()
1561 spin_lock_irqsave(&intf->maintenance_mode_lock, flags); in ipmi_set_maintenance_mode()
1562 if (intf->maintenance_mode != mode) { in ipmi_set_maintenance_mode()
1569 intf->maintenance_mode_state = in ipmi_set_maintenance_mode()
1574 intf->maintenance_mode_state = in ipmi_set_maintenance_mode()
1579 rv = -EINVAL; in ipmi_set_maintenance_mode()
1582 intf->maintenance_mode = mode; in ipmi_set_maintenance_mode()
1587 spin_unlock_irqrestore(&intf->maintenance_mode_lock, flags); in ipmi_set_maintenance_mode()
1596 struct ipmi_smi *intf = user->intf; in ipmi_set_gets_events()
1602 return -ENODEV; in ipmi_set_gets_events()
1606 mutex_lock(&intf->events_mutex); in ipmi_set_gets_events()
1607 if (user->gets_events == val) in ipmi_set_gets_events()
1610 user->gets_events = val; in ipmi_set_gets_events()
1613 if (atomic_inc_return(&intf->event_waiters) == 1) in ipmi_set_gets_events()
1616 atomic_dec(&intf->event_waiters); in ipmi_set_gets_events()
1620 while (user->gets_events && !list_empty(&intf->waiting_events)) { in ipmi_set_gets_events()
1621 list_for_each_entry_safe(msg, msg2, &intf->waiting_events, link) in ipmi_set_gets_events()
1622 list_move_tail(&msg->link, &msgs); in ipmi_set_gets_events()
1623 intf->waiting_events_count = 0; in ipmi_set_gets_events()
1624 if (intf->event_msg_printed) { in ipmi_set_gets_events()
1625 dev_warn(intf->si_dev, "Event queue no longer full\n"); in ipmi_set_gets_events()
1626 intf->event_msg_printed = 0; in ipmi_set_gets_events()
1636 mutex_unlock(&intf->events_mutex); in ipmi_set_gets_events()
1650 list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link, in find_cmd_rcvr()
1651 lockdep_is_held(&intf->cmd_rcvrs_mutex)) { in find_cmd_rcvr()
1652 if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd) in find_cmd_rcvr()
1653 && (rcvr->chans & (1 << chan))) in find_cmd_rcvr()
1666 list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link, in is_cmd_rcvr_exclusive()
1667 lockdep_is_held(&intf->cmd_rcvrs_mutex)) { in is_cmd_rcvr_exclusive()
1668 if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd) in is_cmd_rcvr_exclusive()
1669 && (rcvr->chans & chans)) in is_cmd_rcvr_exclusive()
1680 struct ipmi_smi *intf = user->intf; in ipmi_register_for_cmd()
1686 return -ENODEV; in ipmi_register_for_cmd()
1690 rv = -ENOMEM; in ipmi_register_for_cmd()
1693 rcvr->cmd = cmd; in ipmi_register_for_cmd()
1694 rcvr->netfn = netfn; in ipmi_register_for_cmd()
1695 rcvr->chans = chans; in ipmi_register_for_cmd()
1696 rcvr->user = user; in ipmi_register_for_cmd()
1698 mutex_lock(&intf->cmd_rcvrs_mutex); in ipmi_register_for_cmd()
1701 rv = -EBUSY; in ipmi_register_for_cmd()
1707 list_add_rcu(&rcvr->link, &intf->cmd_rcvrs); in ipmi_register_for_cmd()
1710 mutex_unlock(&intf->cmd_rcvrs_mutex); in ipmi_register_for_cmd()
1725 struct ipmi_smi *intf = user->intf; in ipmi_unregister_for_cmd()
1728 int i, rv = -ENOENT; in ipmi_unregister_for_cmd()
1732 return -ENODEV; in ipmi_unregister_for_cmd()
1734 mutex_lock(&intf->cmd_rcvrs_mutex); in ipmi_unregister_for_cmd()
1741 if (rcvr->user == user) { in ipmi_unregister_for_cmd()
1743 rcvr->chans &= ~chans; in ipmi_unregister_for_cmd()
1744 if (rcvr->chans == 0) { in ipmi_unregister_for_cmd()
1745 list_del_rcu(&rcvr->link); in ipmi_unregister_for_cmd()
1746 rcvr->next = rcvrs; in ipmi_unregister_for_cmd()
1751 mutex_unlock(&intf->cmd_rcvrs_mutex); in ipmi_unregister_for_cmd()
1757 rcvrs = rcvr->next; in ipmi_unregister_for_cmd()
1770 for (; size > 0; size--, data++) in ipmb_checksum()
1773 return -csum; in ipmb_checksum()
1788 /* Format the IPMB header data. */ in format_ipmb_msg()
1789 smi_msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2); in format_ipmb_msg()
1790 smi_msg->data[1] = IPMI_SEND_MSG_CMD; in format_ipmb_msg()
1791 smi_msg->data[2] = ipmb_addr->channel; in format_ipmb_msg()
1793 smi_msg->data[3] = 0; in format_ipmb_msg()
1794 smi_msg->data[i+3] = ipmb_addr->slave_addr; in format_ipmb_msg()
1795 smi_msg->data[i+4] = (msg->netfn << 2) | (ipmb_addr->lun & 0x3); in format_ipmb_msg()
1796 smi_msg->data[i+5] = ipmb_checksum(&smi_msg->data[i + 3], 2); in format_ipmb_msg()
1797 smi_msg->data[i+6] = source_address; in format_ipmb_msg()
1798 smi_msg->data[i+7] = (ipmb_seq << 2) | source_lun; in format_ipmb_msg()
1799 smi_msg->data[i+8] = msg->cmd; in format_ipmb_msg()
1802 if (msg->data_len > 0) in format_ipmb_msg()
1803 memcpy(&smi_msg->data[i + 9], msg->data, msg->data_len); in format_ipmb_msg()
1804 smi_msg->data_size = msg->data_len + 9; in format_ipmb_msg()
1807 smi_msg->data[i+smi_msg->data_size] in format_ipmb_msg()
1808 = ipmb_checksum(&smi_msg->data[i + 6], smi_msg->data_size - 6); in format_ipmb_msg()
1814 smi_msg->data_size += 1 + i; in format_ipmb_msg()
1816 smi_msg->msgid = msgid; in format_ipmb_msg()
1826 /* Format the IPMB header data. */ in format_lan_msg()
1827 smi_msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2); in format_lan_msg()
1828 smi_msg->data[1] = IPMI_SEND_MSG_CMD; in format_lan_msg()
1829 smi_msg->data[2] = lan_addr->channel; in format_lan_msg()
1830 smi_msg->data[3] = lan_addr->session_handle; in format_lan_msg()
1831 smi_msg->data[4] = lan_addr->remote_SWID; in format_lan_msg()
1832 smi_msg->data[5] = (msg->netfn << 2) | (lan_addr->lun & 0x3); in format_lan_msg()
1833 smi_msg->data[6] = ipmb_checksum(&smi_msg->data[4], 2); in format_lan_msg()
1834 smi_msg->data[7] = lan_addr->local_SWID; in format_lan_msg()
1835 smi_msg->data[8] = (ipmb_seq << 2) | source_lun; in format_lan_msg()
1836 smi_msg->data[9] = msg->cmd; in format_lan_msg()
1839 if (msg->data_len > 0) in format_lan_msg()
1840 memcpy(&smi_msg->data[10], msg->data, msg->data_len); in format_lan_msg()
1841 smi_msg->data_size = msg->data_len + 10; in format_lan_msg()
1844 smi_msg->data[smi_msg->data_size] in format_lan_msg()
1845 = ipmb_checksum(&smi_msg->data[7], smi_msg->data_size - 7); in format_lan_msg()
1851 smi_msg->data_size += 1; in format_lan_msg()
1853 smi_msg->msgid = msgid; in format_lan_msg()
1860 if (intf->curr_msg) { in smi_add_send_msg()
1862 list_add_tail(&smi_msg->link, &intf->hp_xmit_msgs); in smi_add_send_msg()
1864 list_add_tail(&smi_msg->link, &intf->xmit_msgs); in smi_add_send_msg()
1867 intf->curr_msg = smi_msg; in smi_add_send_msg()
1877 int run_to_completion = READ_ONCE(intf->run_to_completion); in smi_send()
1881 spin_lock_irqsave(&intf->xmit_msgs_lock, flags); in smi_send()
1884 spin_unlock_irqrestore(&intf->xmit_msgs_lock, flags); in smi_send()
1887 handlers->sender(intf->send_info, smi_msg); in smi_send()
1892 return (((msg->netfn == IPMI_NETFN_APP_REQUEST) in is_maintenance_mode_cmd()
1893 && ((msg->cmd == IPMI_COLD_RESET_CMD) in is_maintenance_mode_cmd()
1894 || (msg->cmd == IPMI_WARM_RESET_CMD))) in is_maintenance_mode_cmd()
1895 || (msg->netfn == IPMI_NETFN_FIRMWARE_REQUEST)); in is_maintenance_mode_cmd()
1909 if (msg->netfn & 1) in i_ipmi_req_sysintf()
1911 return -EINVAL; in i_ipmi_req_sysintf()
1914 if (smi_addr->lun > 3) { in i_ipmi_req_sysintf()
1916 return -EINVAL; in i_ipmi_req_sysintf()
1919 memcpy(&recv_msg->addr, smi_addr, sizeof(*smi_addr)); in i_ipmi_req_sysintf()
1921 if ((msg->netfn == IPMI_NETFN_APP_REQUEST) in i_ipmi_req_sysintf()
1922 && ((msg->cmd == IPMI_SEND_MSG_CMD) in i_ipmi_req_sysintf()
1923 || (msg->cmd == IPMI_GET_MSG_CMD) in i_ipmi_req_sysintf()
1924 || (msg->cmd == IPMI_READ_EVENT_MSG_BUFFER_CMD))) { in i_ipmi_req_sysintf()
1930 return -EINVAL; in i_ipmi_req_sysintf()
1937 if (msg->netfn == IPMI_NETFN_FIRMWARE_REQUEST) in i_ipmi_req_sysintf()
1942 spin_lock_irqsave(&intf->maintenance_mode_lock, flags); in i_ipmi_req_sysintf()
1943 intf->auto_maintenance_timeout = maintenance_mode_timeout_ms; in i_ipmi_req_sysintf()
1944 if (!intf->maintenance_mode in i_ipmi_req_sysintf()
1945 && intf->maintenance_mode_state < newst) { in i_ipmi_req_sysintf()
1946 intf->maintenance_mode_state = newst; in i_ipmi_req_sysintf()
1950 spin_unlock_irqrestore(&intf->maintenance_mode_lock, in i_ipmi_req_sysintf()
1954 if (msg->data_len + 2 > IPMI_MAX_MSG_LENGTH) { in i_ipmi_req_sysintf()
1956 return -EMSGSIZE; in i_ipmi_req_sysintf()
1959 smi_msg->data[0] = (msg->netfn << 2) | (smi_addr->lun & 0x3); in i_ipmi_req_sysintf()
1960 smi_msg->data[1] = msg->cmd; in i_ipmi_req_sysintf()
1961 smi_msg->msgid = msgid; in i_ipmi_req_sysintf()
1962 smi_msg->recv_msg = recv_msg; in i_ipmi_req_sysintf()
1963 if (msg->data_len > 0) in i_ipmi_req_sysintf()
1964 memcpy(&smi_msg->data[2], msg->data, msg->data_len); in i_ipmi_req_sysintf()
1965 smi_msg->data_size = msg->data_len + 2; in i_ipmi_req_sysintf()
1989 if (addr->channel >= IPMI_MAX_CHANNELS) { in i_ipmi_req_ipmb()
1991 return -EINVAL; in i_ipmi_req_ipmb()
1994 chans = READ_ONCE(intf->channel_list)->c; in i_ipmi_req_ipmb()
1996 if (chans[addr->channel].medium != IPMI_CHANNEL_MEDIUM_IPMB) { in i_ipmi_req_ipmb()
1998 return -EINVAL; in i_ipmi_req_ipmb()
2001 if (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE) { in i_ipmi_req_ipmb()
2004 * message, but otherwise is the same as an IPMB in i_ipmi_req_ipmb()
2007 addr->addr_type = IPMI_IPMB_ADDR_TYPE; in i_ipmi_req_ipmb()
2016 if ((msg->data_len + 10 + broadcast) > IPMI_MAX_MSG_LENGTH) { in i_ipmi_req_ipmb()
2018 return -EMSGSIZE; in i_ipmi_req_ipmb()
2022 if (ipmb_addr->lun > 3) { in i_ipmi_req_ipmb()
2024 return -EINVAL; in i_ipmi_req_ipmb()
2027 memcpy(&recv_msg->addr, ipmb_addr, sizeof(*ipmb_addr)); in i_ipmi_req_ipmb()
2029 if (recv_msg->msg.netfn & 0x1) { in i_ipmi_req_ipmb()
2043 smi_msg->recv_msg = recv_msg; in i_ipmi_req_ipmb()
2045 mutex_lock(&intf->seq_lock); in i_ipmi_req_ipmb()
2048 intf->ipmb_maintenance_mode_timeout = in i_ipmi_req_ipmb()
2051 if (intf->ipmb_maintenance_mode_timeout && retry_time_ms == 0) in i_ipmi_req_ipmb()
2089 memcpy(recv_msg->msg_data, smi_msg->data, in i_ipmi_req_ipmb()
2090 smi_msg->data_size); in i_ipmi_req_ipmb()
2091 recv_msg->msg.data = recv_msg->msg_data; in i_ipmi_req_ipmb()
2092 recv_msg->msg.data_len = smi_msg->data_size; in i_ipmi_req_ipmb()
2103 mutex_unlock(&intf->seq_lock); in i_ipmi_req_ipmb()
2118 bool is_cmd = !(recv_msg->msg.netfn & 0x1); in i_ipmi_req_ipmb_direct()
2120 if (!(intf->handlers->flags & IPMI_SMI_CAN_HANDLE_IPMB_DIRECT)) in i_ipmi_req_ipmb_direct()
2121 return -EAFNOSUPPORT; in i_ipmi_req_ipmb_direct()
2124 if (!is_cmd && msg->data_len < 1) { in i_ipmi_req_ipmb_direct()
2126 return -EINVAL; in i_ipmi_req_ipmb_direct()
2129 if ((msg->data_len + 4) > IPMI_MAX_MSG_LENGTH) { in i_ipmi_req_ipmb_direct()
2131 return -EMSGSIZE; in i_ipmi_req_ipmb_direct()
2135 if (daddr->rq_lun > 3 || daddr->rs_lun > 3) { in i_ipmi_req_ipmb_direct()
2137 return -EINVAL; in i_ipmi_req_ipmb_direct()
2140 smi_msg->type = IPMI_SMI_MSG_TYPE_IPMB_DIRECT; in i_ipmi_req_ipmb_direct()
2141 smi_msg->msgid = msgid; in i_ipmi_req_ipmb_direct()
2144 smi_msg->data[0] = msg->netfn << 2 | daddr->rs_lun; in i_ipmi_req_ipmb_direct()
2145 smi_msg->data[2] = recv_msg->msgid << 2 | daddr->rq_lun; in i_ipmi_req_ipmb_direct()
2147 smi_msg->data[0] = msg->netfn << 2 | daddr->rq_lun; in i_ipmi_req_ipmb_direct()
2148 smi_msg->data[2] = recv_msg->msgid << 2 | daddr->rs_lun; in i_ipmi_req_ipmb_direct()
2150 smi_msg->data[1] = daddr->slave_addr; in i_ipmi_req_ipmb_direct()
2151 smi_msg->data[3] = msg->cmd; in i_ipmi_req_ipmb_direct()
2153 memcpy(smi_msg->data + 4, msg->data, msg->data_len); in i_ipmi_req_ipmb_direct()
2154 smi_msg->data_size = msg->data_len + 4; in i_ipmi_req_ipmb_direct()
2156 smi_msg->recv_msg = recv_msg; in i_ipmi_req_ipmb_direct()
2177 if (addr->channel >= IPMI_MAX_CHANNELS) { in i_ipmi_req_lan()
2179 return -EINVAL; in i_ipmi_req_lan()
2182 chans = READ_ONCE(intf->channel_list)->c; in i_ipmi_req_lan()
2184 if ((chans[addr->channel].medium in i_ipmi_req_lan()
2186 && (chans[addr->channel].medium in i_ipmi_req_lan()
2189 return -EINVAL; in i_ipmi_req_lan()
2193 if ((msg->data_len + 12) > IPMI_MAX_MSG_LENGTH) { in i_ipmi_req_lan()
2195 return -EMSGSIZE; in i_ipmi_req_lan()
2199 if (lan_addr->lun > 3) { in i_ipmi_req_lan()
2201 return -EINVAL; in i_ipmi_req_lan()
2204 memcpy(&recv_msg->addr, lan_addr, sizeof(*lan_addr)); in i_ipmi_req_lan()
2206 if (recv_msg->msg.netfn & 0x1) { in i_ipmi_req_lan()
2219 smi_msg->recv_msg = recv_msg; in i_ipmi_req_lan()
2221 mutex_lock(&intf->seq_lock); in i_ipmi_req_lan()
2256 memcpy(recv_msg->msg_data, smi_msg->data, in i_ipmi_req_lan()
2257 smi_msg->data_size); in i_ipmi_req_lan()
2258 recv_msg->msg.data = recv_msg->msg_data; in i_ipmi_req_lan()
2259 recv_msg->msg.data_len = smi_msg->data_size; in i_ipmi_req_lan()
2270 mutex_unlock(&intf->seq_lock); in i_ipmi_req_lan()
2298 int run_to_completion = READ_ONCE(intf->run_to_completion); in i_ipmi_request()
2303 recv_msg->user = user; in i_ipmi_request()
2305 atomic_inc(&user->nr_msgs); in i_ipmi_request()
2307 kref_get(&user->refcount); in i_ipmi_request()
2314 recv_msg->user_msg_data = user_msg_data; in i_ipmi_request()
2323 return -ENOMEM; in i_ipmi_request()
2328 mutex_lock(&intf->users_mutex); in i_ipmi_request()
2329 if (intf->maintenance_mode_state == IPMI_MAINTENANCE_MODE_STATE_RESET) { in i_ipmi_request()
2331 rv = -EBUSY; in i_ipmi_request()
2334 if (intf->in_shutdown) { in i_ipmi_request()
2335 rv = -ENODEV; in i_ipmi_request()
2339 recv_msg->msgid = msgid; in i_ipmi_request()
2344 recv_msg->msg = *msg; in i_ipmi_request()
2346 if (addr->addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) { in i_ipmi_request()
2362 rv = -EINVAL; in i_ipmi_request()
2372 dev_dbg(intf->si_dev, "Send: %*ph\n", in i_ipmi_request()
2373 smi_msg->data_size, smi_msg->data); in i_ipmi_request()
2375 smi_send(intf, intf->handlers, smi_msg, priority); in i_ipmi_request()
2378 mutex_unlock(&intf->users_mutex); in i_ipmi_request()
2388 if (addr->channel >= IPMI_MAX_CHANNELS) in check_addr()
2389 return -EINVAL; in check_addr()
2390 addr->channel = array_index_nospec(addr->channel, IPMI_MAX_CHANNELS); in check_addr()
2391 *lun = intf->addrinfo[addr->channel].lun; in check_addr()
2392 *saddr = intf->addrinfo[addr->channel].address; in check_addr()
2409 return -EINVAL; in ipmi_request_settime()
2413 return -ENODEV; in ipmi_request_settime()
2415 rv = check_addr(user->intf, addr, &saddr, &lun); in ipmi_request_settime()
2418 user->intf, in ipmi_request_settime()
2448 return -EINVAL; in ipmi_request_supply_msgs()
2452 return -ENODEV; in ipmi_request_supply_msgs()
2454 rv = check_addr(user->intf, addr, &saddr, &lun); in ipmi_request_supply_msgs()
2457 user->intf, in ipmi_request_supply_msgs()
2467 -1, 0); in ipmi_request_supply_msgs()
2479 if ((msg->addr.addr_type != IPMI_SYSTEM_INTERFACE_ADDR_TYPE) in bmc_device_id_handler()
2480 || (msg->msg.netfn != IPMI_NETFN_APP_RESPONSE) in bmc_device_id_handler()
2481 || (msg->msg.cmd != IPMI_GET_DEVICE_ID_CMD)) { in bmc_device_id_handler()
2482 dev_warn(intf->si_dev, in bmc_device_id_handler()
2484 msg->addr.addr_type, msg->msg.netfn, msg->msg.cmd); in bmc_device_id_handler()
2488 if (msg->msg.data[0]) { in bmc_device_id_handler()
2489 dev_warn(intf->si_dev, "device id fetch failed: 0x%2.2x\n", in bmc_device_id_handler()
2490 msg->msg.data[0]); in bmc_device_id_handler()
2491 intf->bmc->dyn_id_set = 0; in bmc_device_id_handler()
2495 rv = ipmi_demangle_device_id(msg->msg.netfn, msg->msg.cmd, in bmc_device_id_handler()
2496 msg->msg.data, msg->msg.data_len, &intf->bmc->fetch_id); in bmc_device_id_handler()
2498 dev_warn(intf->si_dev, "device id demangle failed: %d\n", rv); in bmc_device_id_handler()
2500 intf->bmc->cc = msg->msg.data[0]; in bmc_device_id_handler()
2501 intf->bmc->dyn_id_set = 0; in bmc_device_id_handler()
2508 intf->bmc->dyn_id_set = 1; in bmc_device_id_handler()
2511 wake_up(&intf->waitq); in bmc_device_id_handler()
2538 intf->addrinfo[0].address, in send_get_device_id_cmd()
2539 intf->addrinfo[0].lun, in send_get_device_id_cmd()
2540 -1, 0); in send_get_device_id_cmd()
2548 intf->null_user_handler = bmc_device_id_handler; in __get_device_id()
2551 bmc->cc = 0; in __get_device_id()
2552 bmc->dyn_id_set = 2; in __get_device_id()
2558 wait_event(intf->waitq, bmc->dyn_id_set != 2); in __get_device_id()
2560 if (!bmc->dyn_id_set) { in __get_device_id()
2561 if (bmc->cc != IPMI_CC_NO_ERROR && in __get_device_id()
2564 dev_warn(intf->si_dev, in __get_device_id()
2566 bmc->cc); in __get_device_id()
2570 rv = -EIO; /* Something went wrong in the fetch. */ in __get_device_id()
2577 intf->null_user_handler = NULL; in __get_device_id()
2600 mutex_lock(&bmc->dyn_mutex); in __bmc_get_device_id()
2602 if (list_empty(&bmc->intfs)) { in __bmc_get_device_id()
2603 mutex_unlock(&bmc->dyn_mutex); in __bmc_get_device_id()
2604 return -ENOENT; in __bmc_get_device_id()
2606 intf = list_first_entry(&bmc->intfs, struct ipmi_smi, in __bmc_get_device_id()
2608 kref_get(&intf->refcount); in __bmc_get_device_id()
2609 mutex_unlock(&bmc->dyn_mutex); in __bmc_get_device_id()
2610 mutex_lock(&intf->bmc_reg_mutex); in __bmc_get_device_id()
2611 mutex_lock(&bmc->dyn_mutex); in __bmc_get_device_id()
2612 if (intf != list_first_entry(&bmc->intfs, struct ipmi_smi, in __bmc_get_device_id()
2614 mutex_unlock(&intf->bmc_reg_mutex); in __bmc_get_device_id()
2615 kref_put(&intf->refcount, intf_free); in __bmc_get_device_id()
2619 mutex_lock(&intf->bmc_reg_mutex); in __bmc_get_device_id()
2620 bmc = intf->bmc; in __bmc_get_device_id()
2621 mutex_lock(&bmc->dyn_mutex); in __bmc_get_device_id()
2622 kref_get(&intf->refcount); in __bmc_get_device_id()
2626 if (intf->in_bmc_register || in __bmc_get_device_id()
2627 (bmc->dyn_id_set && time_is_after_jiffies(bmc->dyn_id_expiry))) in __bmc_get_device_id()
2631 if (intf->maintenance_mode_state) { in __bmc_get_device_id()
2632 rv = -EBUSY; in __bmc_get_device_id()
2636 prev_guid_set = bmc->dyn_guid_set; in __bmc_get_device_id()
2639 prev_dyn_id_set = bmc->dyn_id_set; in __bmc_get_device_id()
2648 if (!intf->bmc_registered in __bmc_get_device_id()
2649 || (!prev_guid_set && bmc->dyn_guid_set) in __bmc_get_device_id()
2650 || (!prev_dyn_id_set && bmc->dyn_id_set) in __bmc_get_device_id()
2651 || (prev_guid_set && bmc->dyn_guid_set in __bmc_get_device_id()
2652 && !guid_equal(&bmc->guid, &bmc->fetch_guid)) in __bmc_get_device_id()
2653 || bmc->id.device_id != bmc->fetch_id.device_id in __bmc_get_device_id()
2654 || bmc->id.manufacturer_id != bmc->fetch_id.manufacturer_id in __bmc_get_device_id()
2655 || bmc->id.product_id != bmc->fetch_id.product_id) { in __bmc_get_device_id()
2656 struct ipmi_device_id id = bmc->fetch_id; in __bmc_get_device_id()
2657 int guid_set = bmc->dyn_guid_set; in __bmc_get_device_id()
2660 guid = bmc->fetch_guid; in __bmc_get_device_id()
2661 mutex_unlock(&bmc->dyn_mutex); in __bmc_get_device_id()
2665 intf->bmc->id = id; in __bmc_get_device_id()
2666 intf->bmc->dyn_guid_set = guid_set; in __bmc_get_device_id()
2667 intf->bmc->guid = guid; in __bmc_get_device_id()
2680 mutex_unlock(&intf->bmc_reg_mutex); in __bmc_get_device_id()
2681 mutex_lock(&bmc->dyn_mutex); in __bmc_get_device_id()
2686 bmc = intf->bmc; in __bmc_get_device_id()
2687 mutex_lock(&bmc->dyn_mutex); in __bmc_get_device_id()
2689 } else if (memcmp(&bmc->fetch_id, &bmc->id, sizeof(bmc->id))) in __bmc_get_device_id()
2691 __scan_channels(intf, &bmc->fetch_id); in __bmc_get_device_id()
2693 bmc->dyn_id_expiry = jiffies + IPMI_DYN_DEV_ID_EXPIRY; in __bmc_get_device_id()
2698 bmc->dyn_id_set = prev_dyn_id_set; in __bmc_get_device_id()
2701 bmc->id = bmc->fetch_id; in __bmc_get_device_id()
2702 if (bmc->dyn_guid_set) in __bmc_get_device_id()
2703 bmc->guid = bmc->fetch_guid; in __bmc_get_device_id()
2709 bmc->dyn_guid_set = prev_guid_set; in __bmc_get_device_id()
2714 *id = bmc->id; in __bmc_get_device_id()
2717 *guid_set = bmc->dyn_guid_set; in __bmc_get_device_id()
2719 if (guid && bmc->dyn_guid_set) in __bmc_get_device_id()
2720 *guid = bmc->guid; in __bmc_get_device_id()
2723 mutex_unlock(&bmc->dyn_mutex); in __bmc_get_device_id()
2724 mutex_unlock(&intf->bmc_reg_mutex); in __bmc_get_device_id()
2726 kref_put(&intf->refcount, intf_free); in __bmc_get_device_id()
2734 return __bmc_get_device_id(intf, bmc, id, guid_set, guid, -1); in bmc_get_device_id()
2900 return -ENOENT; in guid_show()
2925 umode_t mode = attr->mode; in bmc_dev_attr_is_visible()
2963 if (dev->type != &bmc_device_type) in __find_bmc_guid()
2967 rv = bmc->dyn_guid_set && guid_equal(&bmc->guid, guid); in __find_bmc_guid()
2969 rv = kref_get_unless_zero(&bmc->usecount); in __find_bmc_guid()
2974 * Returns with the bmc's usecount incremented, if it is non-NULL.
3001 if (dev->type != &bmc_device_type) in __find_bmc_prod_dev_id()
3005 rv = (bmc->id.product_id == cid->product_id in __find_bmc_prod_dev_id()
3006 && bmc->id.device_id == cid->device_id); in __find_bmc_prod_dev_id()
3008 rv = kref_get_unless_zero(&bmc->usecount); in __find_bmc_prod_dev_id()
3013 * Returns with the bmc's usecount incremented, if it is non-NULL.
3046 int id = bmc->pdev.id; /* Unregister overwrites id */ in cleanup_bmc_work()
3048 platform_device_unregister(&bmc->pdev); in cleanup_bmc_work()
3062 queue_work(bmc_remove_work_wq, &bmc->remove_work); in cleanup_bmc_device()
3066 * Must be called with intf->bmc_reg_mutex held.
3070 struct bmc_device *bmc = intf->bmc; in __ipmi_bmc_unregister()
3072 if (!intf->bmc_registered) in __ipmi_bmc_unregister()
3075 sysfs_remove_link(&intf->si_dev->kobj, "bmc"); in __ipmi_bmc_unregister()
3076 sysfs_remove_link(&bmc->pdev.dev.kobj, intf->my_dev_name); in __ipmi_bmc_unregister()
3077 kfree(intf->my_dev_name); in __ipmi_bmc_unregister()
3078 intf->my_dev_name = NULL; in __ipmi_bmc_unregister()
3080 mutex_lock(&bmc->dyn_mutex); in __ipmi_bmc_unregister()
3081 list_del(&intf->bmc_link); in __ipmi_bmc_unregister()
3082 mutex_unlock(&bmc->dyn_mutex); in __ipmi_bmc_unregister()
3083 intf->bmc = &intf->tmp_bmc; in __ipmi_bmc_unregister()
3084 kref_put(&bmc->usecount, cleanup_bmc_device); in __ipmi_bmc_unregister()
3085 intf->bmc_registered = false; in __ipmi_bmc_unregister()
3090 mutex_lock(&intf->bmc_reg_mutex); in ipmi_bmc_unregister()
3092 mutex_unlock(&intf->bmc_reg_mutex); in ipmi_bmc_unregister()
3096 * Must be called with intf->bmc_reg_mutex held.
3112 intf->in_bmc_register = true; in __ipmi_bmc_register()
3113 mutex_unlock(&intf->bmc_reg_mutex); in __ipmi_bmc_register()
3124 id->product_id, in __ipmi_bmc_register()
3125 id->device_id); in __ipmi_bmc_register()
3137 intf->bmc = old_bmc; in __ipmi_bmc_register()
3138 mutex_lock(&bmc->dyn_mutex); in __ipmi_bmc_register()
3139 list_add_tail(&intf->bmc_link, &bmc->intfs); in __ipmi_bmc_register()
3140 mutex_unlock(&bmc->dyn_mutex); in __ipmi_bmc_register()
3142 dev_info(intf->si_dev, in __ipmi_bmc_register()
3144 bmc->id.manufacturer_id, in __ipmi_bmc_register()
3145 bmc->id.product_id, in __ipmi_bmc_register()
3146 bmc->id.device_id); in __ipmi_bmc_register()
3150 rv = -ENOMEM; in __ipmi_bmc_register()
3153 INIT_LIST_HEAD(&bmc->intfs); in __ipmi_bmc_register()
3154 mutex_init(&bmc->dyn_mutex); in __ipmi_bmc_register()
3155 INIT_WORK(&bmc->remove_work, cleanup_bmc_work); in __ipmi_bmc_register()
3157 bmc->id = *id; in __ipmi_bmc_register()
3158 bmc->dyn_id_set = 1; in __ipmi_bmc_register()
3159 bmc->dyn_guid_set = guid_set; in __ipmi_bmc_register()
3160 bmc->guid = *guid; in __ipmi_bmc_register()
3161 bmc->dyn_id_expiry = jiffies + IPMI_DYN_DEV_ID_EXPIRY; in __ipmi_bmc_register()
3163 bmc->pdev.name = "ipmi_bmc"; in __ipmi_bmc_register()
3171 bmc->pdev.dev.driver = &ipmidriver.driver; in __ipmi_bmc_register()
3172 bmc->pdev.id = rv; in __ipmi_bmc_register()
3173 bmc->pdev.dev.release = release_bmc_device; in __ipmi_bmc_register()
3174 bmc->pdev.dev.type = &bmc_device_type; in __ipmi_bmc_register()
3175 kref_init(&bmc->usecount); in __ipmi_bmc_register()
3177 intf->bmc = bmc; in __ipmi_bmc_register()
3178 mutex_lock(&bmc->dyn_mutex); in __ipmi_bmc_register()
3179 list_add_tail(&intf->bmc_link, &bmc->intfs); in __ipmi_bmc_register()
3180 mutex_unlock(&bmc->dyn_mutex); in __ipmi_bmc_register()
3182 rv = platform_device_register(&bmc->pdev); in __ipmi_bmc_register()
3184 dev_err(intf->si_dev, in __ipmi_bmc_register()
3190 dev_info(intf->si_dev, in __ipmi_bmc_register()
3192 bmc->id.manufacturer_id, in __ipmi_bmc_register()
3193 bmc->id.product_id, in __ipmi_bmc_register()
3194 bmc->id.device_id); in __ipmi_bmc_register()
3201 rv = sysfs_create_link(&intf->si_dev->kobj, &bmc->pdev.dev.kobj, "bmc"); in __ipmi_bmc_register()
3203 dev_err(intf->si_dev, "Unable to create bmc symlink: %d\n", rv); in __ipmi_bmc_register()
3207 if (intf_num == -1) in __ipmi_bmc_register()
3208 intf_num = intf->intf_num; in __ipmi_bmc_register()
3209 intf->my_dev_name = kasprintf(GFP_KERNEL, "ipmi%d", intf_num); in __ipmi_bmc_register()
3210 if (!intf->my_dev_name) { in __ipmi_bmc_register()
3211 rv = -ENOMEM; in __ipmi_bmc_register()
3212 dev_err(intf->si_dev, "Unable to allocate link from BMC: %d\n", in __ipmi_bmc_register()
3217 rv = sysfs_create_link(&bmc->pdev.dev.kobj, &intf->si_dev->kobj, in __ipmi_bmc_register()
3218 intf->my_dev_name); in __ipmi_bmc_register()
3220 dev_err(intf->si_dev, "Unable to create symlink to bmc: %d\n", in __ipmi_bmc_register()
3225 intf->bmc_registered = true; in __ipmi_bmc_register()
3229 mutex_lock(&intf->bmc_reg_mutex); in __ipmi_bmc_register()
3230 intf->in_bmc_register = false; in __ipmi_bmc_register()
3235 kfree(intf->my_dev_name); in __ipmi_bmc_register()
3236 intf->my_dev_name = NULL; in __ipmi_bmc_register()
3239 sysfs_remove_link(&intf->si_dev->kobj, "bmc"); in __ipmi_bmc_register()
3242 mutex_lock(&bmc->dyn_mutex); in __ipmi_bmc_register()
3243 list_del(&intf->bmc_link); in __ipmi_bmc_register()
3244 mutex_unlock(&bmc->dyn_mutex); in __ipmi_bmc_register()
3245 intf->bmc = &intf->tmp_bmc; in __ipmi_bmc_register()
3246 kref_put(&bmc->usecount, cleanup_bmc_device); in __ipmi_bmc_register()
3250 mutex_lock(&bmc->dyn_mutex); in __ipmi_bmc_register()
3251 list_del(&intf->bmc_link); in __ipmi_bmc_register()
3252 mutex_unlock(&bmc->dyn_mutex); in __ipmi_bmc_register()
3253 intf->bmc = &intf->tmp_bmc; in __ipmi_bmc_register()
3254 put_device(&bmc->pdev.dev); in __ipmi_bmc_register()
3281 intf->addrinfo[0].address, in send_guid_cmd()
3282 intf->addrinfo[0].lun, in send_guid_cmd()
3283 -1, 0); in send_guid_cmd()
3288 struct bmc_device *bmc = intf->bmc; in guid_handler()
3290 if ((msg->addr.addr_type != IPMI_SYSTEM_INTERFACE_ADDR_TYPE) in guid_handler()
3291 || (msg->msg.netfn != IPMI_NETFN_APP_RESPONSE) in guid_handler()
3292 || (msg->msg.cmd != IPMI_GET_DEVICE_GUID_CMD)) in guid_handler()
3296 if (msg->msg.data[0] != 0) { in guid_handler()
3298 bmc->dyn_guid_set = 0; in guid_handler()
3302 if (msg->msg.data_len < UUID_SIZE + 1) { in guid_handler()
3303 bmc->dyn_guid_set = 0; in guid_handler()
3304 dev_warn(intf->si_dev, in guid_handler()
3306 msg->msg.data_len, UUID_SIZE + 1); in guid_handler()
3310 import_guid(&bmc->fetch_guid, msg->msg.data + 1); in guid_handler()
3316 bmc->dyn_guid_set = 1; in guid_handler()
3318 wake_up(&intf->waitq); in guid_handler()
3324 struct bmc_device *bmc = intf->bmc; in __get_guid()
3326 bmc->dyn_guid_set = 2; in __get_guid()
3327 intf->null_user_handler = guid_handler; in __get_guid()
3331 bmc->dyn_guid_set = 0; in __get_guid()
3333 wait_event(intf->waitq, bmc->dyn_guid_set != 2); in __get_guid()
3338 intf->null_user_handler = NULL; in __get_guid()
3366 intf->addrinfo[0].address, in send_channel_info_cmd()
3367 intf->addrinfo[0].lun, in send_channel_info_cmd()
3368 -1, 0); in send_channel_info_cmd()
3376 unsigned int set = intf->curr_working_cset; in channel_handler()
3379 if ((msg->addr.addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) in channel_handler()
3380 && (msg->msg.netfn == IPMI_NETFN_APP_RESPONSE) in channel_handler()
3381 && (msg->msg.cmd == IPMI_GET_CHANNEL_INFO_CMD)) { in channel_handler()
3383 if (msg->msg.data[0] != 0) { in channel_handler()
3385 if (msg->msg.data[0] == IPMI_INVALID_COMMAND_ERR) { in channel_handler()
3389 * assume it has one IPMB at channel in channel_handler()
3392 intf->wchannels[set].c[0].medium in channel_handler()
3394 intf->wchannels[set].c[0].protocol in channel_handler()
3397 intf->channel_list = intf->wchannels + set; in channel_handler()
3398 intf->channels_ready = true; in channel_handler()
3399 wake_up(&intf->waitq); in channel_handler()
3404 if (msg->msg.data_len < 4) { in channel_handler()
3408 ch = intf->curr_channel; in channel_handler()
3409 chans = intf->wchannels[set].c; in channel_handler()
3410 chans[ch].medium = msg->msg.data[2] & 0x7f; in channel_handler()
3411 chans[ch].protocol = msg->msg.data[3] & 0x1f; in channel_handler()
3414 intf->curr_channel++; in channel_handler()
3415 if (intf->curr_channel >= IPMI_MAX_CHANNELS) { in channel_handler()
3416 intf->channel_list = intf->wchannels + set; in channel_handler()
3417 intf->channels_ready = true; in channel_handler()
3418 wake_up(&intf->waitq); in channel_handler()
3420 intf->channel_list = intf->wchannels + set; in channel_handler()
3421 intf->channels_ready = true; in channel_handler()
3422 rv = send_channel_info_cmd(intf, intf->curr_channel); in channel_handler()
3427 dev_warn(intf->si_dev, in channel_handler()
3429 intf->curr_channel, rv); in channel_handler()
3431 intf->channel_list = intf->wchannels + set; in channel_handler()
3432 intf->channels_ready = true; in channel_handler()
3433 wake_up(&intf->waitq); in channel_handler()
3441 * Must be holding intf->bmc_reg_mutex to call this.
3456 set = !intf->curr_working_cset; in __scan_channels()
3457 intf->curr_working_cset = set; in __scan_channels()
3458 memset(&intf->wchannels[set], 0, in __scan_channels()
3461 intf->null_user_handler = channel_handler; in __scan_channels()
3462 intf->curr_channel = 0; in __scan_channels()
3465 dev_warn(intf->si_dev, in __scan_channels()
3468 intf->null_user_handler = NULL; in __scan_channels()
3469 return -EIO; in __scan_channels()
3473 wait_event(intf->waitq, intf->channels_ready); in __scan_channels()
3474 intf->null_user_handler = NULL; in __scan_channels()
3476 unsigned int set = intf->curr_working_cset; in __scan_channels()
3478 /* Assume a single IPMB channel at zero. */ in __scan_channels()
3479 intf->wchannels[set].c[0].medium = IPMI_CHANNEL_MEDIUM_IPMB; in __scan_channels()
3480 intf->wchannels[set].c[0].protocol = IPMI_CHANNEL_PROTOCOL_IPMB; in __scan_channels()
3481 intf->channel_list = intf->wchannels + set; in __scan_channels()
3482 intf->channels_ready = true; in __scan_channels()
3490 if (intf->handlers->poll) in ipmi_poll()
3491 intf->handlers->poll(intf->send_info); in ipmi_poll()
3498 ipmi_poll(user->intf); in ipmi_poll_interface()
3509 return sysfs_emit(buf, "%d\n", atomic_read(&intf->nr_users)); in nr_users_show()
3522 mutex_lock(&intf->users_mutex); in nr_msgs_show()
3523 list_for_each_entry(user, &intf->users, link) in nr_msgs_show()
3524 count += atomic_read(&user->nr_msgs); in nr_msgs_show()
3525 mutex_unlock(&intf->users_mutex); in nr_msgs_show()
3539 return sysfs_emit(buf, "%u %d\n", intf->maintenance_mode_state, in maintenance_mode_show()
3540 intf->auto_maintenance_timeout); in maintenance_mode_show()
3549 if (!intf->in_shutdown) in redo_bmc_reg()
3552 kref_put(&intf->refcount, intf_free); in redo_bmc_reg()
3577 return -ENOMEM; in ipmi_add_smi()
3579 intf->owner = owner; in ipmi_add_smi()
3580 intf->bmc = &intf->tmp_bmc; in ipmi_add_smi()
3581 INIT_LIST_HEAD(&intf->bmc->intfs); in ipmi_add_smi()
3582 mutex_init(&intf->bmc->dyn_mutex); in ipmi_add_smi()
3583 INIT_LIST_HEAD(&intf->bmc_link); in ipmi_add_smi()
3584 mutex_init(&intf->bmc_reg_mutex); in ipmi_add_smi()
3585 intf->intf_num = -1; /* Mark it invalid for now. */ in ipmi_add_smi()
3586 kref_init(&intf->refcount); in ipmi_add_smi()
3587 INIT_WORK(&intf->bmc_reg_work, redo_bmc_reg); in ipmi_add_smi()
3588 intf->si_dev = si_dev; in ipmi_add_smi()
3590 intf->addrinfo[j].address = IPMI_BMC_SLAVE_ADDR; in ipmi_add_smi()
3591 intf->addrinfo[j].lun = 2; in ipmi_add_smi()
3594 intf->addrinfo[0].address = slave_addr; in ipmi_add_smi()
3595 INIT_LIST_HEAD(&intf->user_msgs); in ipmi_add_smi()
3596 mutex_init(&intf->user_msgs_mutex); in ipmi_add_smi()
3597 INIT_LIST_HEAD(&intf->users); in ipmi_add_smi()
3598 mutex_init(&intf->users_mutex); in ipmi_add_smi()
3599 atomic_set(&intf->nr_users, 0); in ipmi_add_smi()
3600 intf->handlers = handlers; in ipmi_add_smi()
3601 intf->send_info = send_info; in ipmi_add_smi()
3602 mutex_init(&intf->seq_lock); in ipmi_add_smi()
3604 intf->seq_table[j].inuse = 0; in ipmi_add_smi()
3605 intf->seq_table[j].seqid = 0; in ipmi_add_smi()
3607 intf->curr_seq = 0; in ipmi_add_smi()
3608 spin_lock_init(&intf->waiting_rcv_msgs_lock); in ipmi_add_smi()
3609 INIT_LIST_HEAD(&intf->waiting_rcv_msgs); in ipmi_add_smi()
3610 INIT_WORK(&intf->smi_work, smi_work); in ipmi_add_smi()
3611 atomic_set(&intf->watchdog_pretimeouts_to_deliver, 0); in ipmi_add_smi()
3612 spin_lock_init(&intf->xmit_msgs_lock); in ipmi_add_smi()
3613 INIT_LIST_HEAD(&intf->xmit_msgs); in ipmi_add_smi()
3614 INIT_LIST_HEAD(&intf->hp_xmit_msgs); in ipmi_add_smi()
3615 mutex_init(&intf->events_mutex); in ipmi_add_smi()
3616 spin_lock_init(&intf->watch_lock); in ipmi_add_smi()
3617 atomic_set(&intf->event_waiters, 0); in ipmi_add_smi()
3618 intf->ticks_to_req_ev = IPMI_REQUEST_EV_TIME; in ipmi_add_smi()
3619 INIT_LIST_HEAD(&intf->waiting_events); in ipmi_add_smi()
3620 intf->waiting_events_count = 0; in ipmi_add_smi()
3621 mutex_init(&intf->cmd_rcvrs_mutex); in ipmi_add_smi()
3622 spin_lock_init(&intf->maintenance_mode_lock); in ipmi_add_smi()
3623 INIT_LIST_HEAD(&intf->cmd_rcvrs); in ipmi_add_smi()
3624 init_waitqueue_head(&intf->waitq); in ipmi_add_smi()
3626 atomic_set(&intf->stats[i], 0); in ipmi_add_smi()
3638 if (tintf->intf_num != i) { in ipmi_add_smi()
3639 link = &tintf->link; in ipmi_add_smi()
3646 list_add(&intf->link, &ipmi_interfaces); in ipmi_add_smi()
3648 list_add_tail(&intf->link, link); in ipmi_add_smi()
3650 rv = handlers->start_processing(send_info, intf); in ipmi_add_smi()
3660 mutex_lock(&intf->bmc_reg_mutex); in ipmi_add_smi()
3662 mutex_unlock(&intf->bmc_reg_mutex); in ipmi_add_smi()
3666 intf->nr_users_devattr = dev_attr_nr_users; in ipmi_add_smi()
3667 sysfs_attr_init(&intf->nr_users_devattr.attr); in ipmi_add_smi()
3668 rv = device_create_file(intf->si_dev, &intf->nr_users_devattr); in ipmi_add_smi()
3672 intf->nr_msgs_devattr = dev_attr_nr_msgs; in ipmi_add_smi()
3673 sysfs_attr_init(&intf->nr_msgs_devattr.attr); in ipmi_add_smi()
3674 rv = device_create_file(intf->si_dev, &intf->nr_msgs_devattr); in ipmi_add_smi()
3676 device_remove_file(intf->si_dev, &intf->nr_users_devattr); in ipmi_add_smi()
3680 intf->maintenance_mode_devattr = dev_attr_maintenance_mode; in ipmi_add_smi()
3681 sysfs_attr_init(&intf->maintenance_mode_devattr.attr); in ipmi_add_smi()
3682 rv = device_create_file(intf->si_dev, &intf->maintenance_mode_devattr); in ipmi_add_smi()
3684 device_remove_file(intf->si_dev, &intf->nr_users_devattr); in ipmi_add_smi()
3688 intf->intf_num = i; in ipmi_add_smi()
3692 call_smi_watchers(i, intf->si_dev); in ipmi_add_smi()
3701 if (intf->handlers->shutdown) in ipmi_add_smi()
3702 intf->handlers->shutdown(intf->send_info); in ipmi_add_smi()
3704 list_del(&intf->link); in ipmi_add_smi()
3707 kref_put(&intf->refcount, intf_free); in ipmi_add_smi()
3718 msg->rsp[0] = msg->data[0] | 4; in deliver_smi_err_response()
3719 msg->rsp[1] = msg->data[1]; in deliver_smi_err_response()
3720 msg->rsp[2] = err; in deliver_smi_err_response()
3721 msg->rsp_size = 3; in deliver_smi_err_response()
3739 list_splice_tail(&intf->hp_xmit_msgs, &tmplist); in cleanup_smi_msgs()
3740 list_splice_tail(&intf->xmit_msgs, &tmplist); in cleanup_smi_msgs()
3743 while (intf->curr_msg && !list_empty(&intf->waiting_rcv_msgs)) { in cleanup_smi_msgs()
3762 ent = &intf->seq_table[i]; in cleanup_smi_msgs()
3763 if (!ent->inuse) in cleanup_smi_msgs()
3765 deliver_err_response(intf, ent->recv_msg, IPMI_ERR_UNSPECIFIED); in cleanup_smi_msgs()
3777 intf_num = intf->intf_num; in ipmi_unregister_smi()
3779 cancel_work_sync(&intf->smi_work); in ipmi_unregister_smi()
3782 intf->intf_num = -1; in ipmi_unregister_smi()
3783 intf->in_shutdown = true; in ipmi_unregister_smi()
3784 list_del(&intf->link); in ipmi_unregister_smi()
3792 if (intf->handlers->shutdown) in ipmi_unregister_smi()
3793 intf->handlers->shutdown(intf->send_info); in ipmi_unregister_smi()
3795 device_remove_file(intf->si_dev, &intf->maintenance_mode_devattr); in ipmi_unregister_smi()
3796 device_remove_file(intf->si_dev, &intf->nr_msgs_devattr); in ipmi_unregister_smi()
3797 device_remove_file(intf->si_dev, &intf->nr_users_devattr); in ipmi_unregister_smi()
3805 w->smi_gone(intf_num); in ipmi_unregister_smi()
3808 mutex_lock(&intf->users_mutex); in ipmi_unregister_smi()
3809 while (!list_empty(&intf->users)) { in ipmi_unregister_smi()
3810 struct ipmi_user *user = list_first_entry(&intf->users, in ipmi_unregister_smi()
3815 mutex_unlock(&intf->users_mutex); in ipmi_unregister_smi()
3821 kref_put(&intf->refcount, intf_free); in ipmi_unregister_smi()
3835 if (msg->rsp_size < 11) { in handle_ipmb_get_msg_rsp()
3841 if (msg->rsp[2] != 0) { in handle_ipmb_get_msg_rsp()
3847 ipmb_addr.slave_addr = msg->rsp[6]; in handle_ipmb_get_msg_rsp()
3848 ipmb_addr.channel = msg->rsp[3] & 0x0f; in handle_ipmb_get_msg_rsp()
3849 ipmb_addr.lun = msg->rsp[7] & 3; in handle_ipmb_get_msg_rsp()
3856 msg->rsp[7] >> 2, in handle_ipmb_get_msg_rsp()
3857 msg->rsp[3] & 0x0f, in handle_ipmb_get_msg_rsp()
3858 msg->rsp[8], in handle_ipmb_get_msg_rsp()
3859 (msg->rsp[4] >> 2) & (~1), in handle_ipmb_get_msg_rsp()
3870 memcpy(recv_msg->msg_data, &msg->rsp[9], msg->rsp_size - 9); in handle_ipmb_get_msg_rsp()
3876 recv_msg->msg.netfn = msg->rsp[4] >> 2; in handle_ipmb_get_msg_rsp()
3877 recv_msg->msg.data = recv_msg->msg_data; in handle_ipmb_get_msg_rsp()
3878 recv_msg->msg.data_len = msg->rsp_size - 10; in handle_ipmb_get_msg_rsp()
3879 recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE; in handle_ipmb_get_msg_rsp()
3900 if (msg->rsp_size < 10) { in handle_ipmb_get_msg_cmd()
3906 if (msg->rsp[2] != 0) { in handle_ipmb_get_msg_cmd()
3911 netfn = msg->rsp[4] >> 2; in handle_ipmb_get_msg_cmd()
3912 cmd = msg->rsp[8]; in handle_ipmb_get_msg_cmd()
3913 chan = msg->rsp[3] & 0xf; in handle_ipmb_get_msg_cmd()
3918 user = rcvr->user; in handle_ipmb_get_msg_cmd()
3927 msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2); in handle_ipmb_get_msg_cmd()
3928 msg->data[1] = IPMI_SEND_MSG_CMD; in handle_ipmb_get_msg_cmd()
3929 msg->data[2] = msg->rsp[3]; in handle_ipmb_get_msg_cmd()
3930 msg->data[3] = msg->rsp[6]; in handle_ipmb_get_msg_cmd()
3931 msg->data[4] = ((netfn + 1) << 2) | (msg->rsp[7] & 0x3); in handle_ipmb_get_msg_cmd()
3932 msg->data[5] = ipmb_checksum(&msg->data[3], 2); in handle_ipmb_get_msg_cmd()
3933 msg->data[6] = intf->addrinfo[msg->rsp[3] & 0xf].address; in handle_ipmb_get_msg_cmd()
3935 msg->data[7] = (msg->rsp[7] & 0xfc) | (msg->rsp[4] & 0x3); in handle_ipmb_get_msg_cmd()
3936 msg->data[8] = msg->rsp[8]; /* cmd */ in handle_ipmb_get_msg_cmd()
3937 msg->data[9] = IPMI_INVALID_CMD_COMPLETION_CODE; in handle_ipmb_get_msg_cmd()
3938 msg->data[10] = ipmb_checksum(&msg->data[6], 4); in handle_ipmb_get_msg_cmd()
3939 msg->data_size = 11; in handle_ipmb_get_msg_cmd()
3941 dev_dbg(intf->si_dev, "Invalid command: %*ph\n", in handle_ipmb_get_msg_cmd()
3942 msg->data_size, msg->data); in handle_ipmb_get_msg_cmd()
3944 smi_send(intf, intf->handlers, msg, 0); in handle_ipmb_get_msg_cmd()
3949 rv = -1; in handle_ipmb_get_msg_cmd()
3952 ipmb_addr = (struct ipmi_ipmb_addr *) &recv_msg->addr; in handle_ipmb_get_msg_cmd()
3953 ipmb_addr->addr_type = IPMI_IPMB_ADDR_TYPE; in handle_ipmb_get_msg_cmd()
3954 ipmb_addr->slave_addr = msg->rsp[6]; in handle_ipmb_get_msg_cmd()
3955 ipmb_addr->lun = msg->rsp[7] & 3; in handle_ipmb_get_msg_cmd()
3956 ipmb_addr->channel = msg->rsp[3] & 0xf; in handle_ipmb_get_msg_cmd()
3960 * from the IPMB header. in handle_ipmb_get_msg_cmd()
3962 recv_msg->recv_type = IPMI_CMD_RECV_TYPE; in handle_ipmb_get_msg_cmd()
3963 recv_msg->msgid = msg->rsp[7] >> 2; in handle_ipmb_get_msg_cmd()
3964 recv_msg->msg.netfn = msg->rsp[4] >> 2; in handle_ipmb_get_msg_cmd()
3965 recv_msg->msg.cmd = msg->rsp[8]; in handle_ipmb_get_msg_cmd()
3966 recv_msg->msg.data = recv_msg->msg_data; in handle_ipmb_get_msg_cmd()
3972 recv_msg->msg.data_len = msg->rsp_size - 10; in handle_ipmb_get_msg_cmd()
3973 memcpy(recv_msg->msg_data, &msg->rsp[9], in handle_ipmb_get_msg_cmd()
3974 msg->rsp_size - 10); in handle_ipmb_get_msg_cmd()
3998 unsigned char netfn = msg->rsp[0] >> 2; in handle_ipmb_direct_rcv_cmd()
3999 unsigned char cmd = msg->rsp[3]; in handle_ipmb_direct_rcv_cmd()
4005 user = rcvr->user; in handle_ipmb_direct_rcv_cmd()
4014 msg->data[0] = (netfn + 1) << 2; in handle_ipmb_direct_rcv_cmd()
4015 msg->data[0] |= msg->rsp[2] & 0x3; /* rqLUN */ in handle_ipmb_direct_rcv_cmd()
4016 msg->data[1] = msg->rsp[1]; /* Addr */ in handle_ipmb_direct_rcv_cmd()
4017 msg->data[2] = msg->rsp[2] & ~0x3; /* rqSeq */ in handle_ipmb_direct_rcv_cmd()
4018 msg->data[2] |= msg->rsp[0] & 0x3; /* rsLUN */ in handle_ipmb_direct_rcv_cmd()
4019 msg->data[3] = cmd; in handle_ipmb_direct_rcv_cmd()
4020 msg->data[4] = IPMI_INVALID_CMD_COMPLETION_CODE; in handle_ipmb_direct_rcv_cmd()
4021 msg->data_size = 5; in handle_ipmb_direct_rcv_cmd()
4023 smi_send(intf, intf->handlers, msg, 0); in handle_ipmb_direct_rcv_cmd()
4028 rv = -1; in handle_ipmb_direct_rcv_cmd()
4031 daddr = (struct ipmi_ipmb_direct_addr *)&recv_msg->addr; in handle_ipmb_direct_rcv_cmd()
4032 daddr->addr_type = IPMI_IPMB_DIRECT_ADDR_TYPE; in handle_ipmb_direct_rcv_cmd()
4033 daddr->channel = 0; in handle_ipmb_direct_rcv_cmd()
4034 daddr->slave_addr = msg->rsp[1]; in handle_ipmb_direct_rcv_cmd()
4035 daddr->rs_lun = msg->rsp[0] & 3; in handle_ipmb_direct_rcv_cmd()
4036 daddr->rq_lun = msg->rsp[2] & 3; in handle_ipmb_direct_rcv_cmd()
4040 * from the IPMB header. in handle_ipmb_direct_rcv_cmd()
4042 recv_msg->recv_type = IPMI_CMD_RECV_TYPE; in handle_ipmb_direct_rcv_cmd()
4043 recv_msg->msgid = (msg->rsp[2] >> 2); in handle_ipmb_direct_rcv_cmd()
4044 recv_msg->msg.netfn = msg->rsp[0] >> 2; in handle_ipmb_direct_rcv_cmd()
4045 recv_msg->msg.cmd = msg->rsp[3]; in handle_ipmb_direct_rcv_cmd()
4046 recv_msg->msg.data = recv_msg->msg_data; in handle_ipmb_direct_rcv_cmd()
4048 recv_msg->msg.data_len = msg->rsp_size - 4; in handle_ipmb_direct_rcv_cmd()
4049 memcpy(recv_msg->msg_data, msg->rsp + 4, in handle_ipmb_direct_rcv_cmd()
4050 msg->rsp_size - 4); in handle_ipmb_direct_rcv_cmd()
4072 recv_msg = msg->recv_msg; in handle_ipmb_direct_rcv_rsp()
4074 dev_warn(intf->si_dev, in handle_ipmb_direct_rcv_rsp()
4075 …"IPMI direct message received with no owner. This could be because of a malformed message, or beca… in handle_ipmb_direct_rcv_rsp()
4079 recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE; in handle_ipmb_direct_rcv_rsp()
4080 recv_msg->msgid = msg->msgid; in handle_ipmb_direct_rcv_rsp()
4081 daddr = (struct ipmi_ipmb_direct_addr *) &recv_msg->addr; in handle_ipmb_direct_rcv_rsp()
4082 daddr->addr_type = IPMI_IPMB_DIRECT_ADDR_TYPE; in handle_ipmb_direct_rcv_rsp()
4083 daddr->channel = 0; in handle_ipmb_direct_rcv_rsp()
4084 daddr->slave_addr = msg->rsp[1]; in handle_ipmb_direct_rcv_rsp()
4085 daddr->rq_lun = msg->rsp[0] & 3; in handle_ipmb_direct_rcv_rsp()
4086 daddr->rs_lun = msg->rsp[2] & 3; in handle_ipmb_direct_rcv_rsp()
4087 recv_msg->msg.netfn = msg->rsp[0] >> 2; in handle_ipmb_direct_rcv_rsp()
4088 recv_msg->msg.cmd = msg->rsp[3]; in handle_ipmb_direct_rcv_rsp()
4089 memcpy(recv_msg->msg_data, &msg->rsp[4], msg->rsp_size - 4); in handle_ipmb_direct_rcv_rsp()
4090 recv_msg->msg.data = recv_msg->msg_data; in handle_ipmb_direct_rcv_rsp()
4091 recv_msg->msg.data_len = msg->rsp_size - 4; in handle_ipmb_direct_rcv_rsp()
4108 if (msg->rsp_size < 13) { in handle_lan_get_msg_rsp()
4114 if (msg->rsp[2] != 0) { in handle_lan_get_msg_rsp()
4120 lan_addr.session_handle = msg->rsp[4]; in handle_lan_get_msg_rsp()
4121 lan_addr.remote_SWID = msg->rsp[8]; in handle_lan_get_msg_rsp()
4122 lan_addr.local_SWID = msg->rsp[5]; in handle_lan_get_msg_rsp()
4123 lan_addr.channel = msg->rsp[3] & 0x0f; in handle_lan_get_msg_rsp()
4124 lan_addr.privilege = msg->rsp[3] >> 4; in handle_lan_get_msg_rsp()
4125 lan_addr.lun = msg->rsp[9] & 3; in handle_lan_get_msg_rsp()
4132 msg->rsp[9] >> 2, in handle_lan_get_msg_rsp()
4133 msg->rsp[3] & 0x0f, in handle_lan_get_msg_rsp()
4134 msg->rsp[10], in handle_lan_get_msg_rsp()
4135 (msg->rsp[6] >> 2) & (~1), in handle_lan_get_msg_rsp()
4146 memcpy(recv_msg->msg_data, &msg->rsp[11], msg->rsp_size - 11); in handle_lan_get_msg_rsp()
4152 recv_msg->msg.netfn = msg->rsp[6] >> 2; in handle_lan_get_msg_rsp()
4153 recv_msg->msg.data = recv_msg->msg_data; in handle_lan_get_msg_rsp()
4154 recv_msg->msg.data_len = msg->rsp_size - 12; in handle_lan_get_msg_rsp()
4155 recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE; in handle_lan_get_msg_rsp()
4176 if (msg->rsp_size < 12) { in handle_lan_get_msg_cmd()
4182 if (msg->rsp[2] != 0) { in handle_lan_get_msg_cmd()
4187 netfn = msg->rsp[6] >> 2; in handle_lan_get_msg_cmd()
4188 cmd = msg->rsp[10]; in handle_lan_get_msg_cmd()
4189 chan = msg->rsp[3] & 0xf; in handle_lan_get_msg_cmd()
4194 user = rcvr->user; in handle_lan_get_msg_cmd()
4203 msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2); in handle_lan_get_msg_cmd()
4204 msg->data[1] = IPMI_SEND_MSG_CMD; in handle_lan_get_msg_cmd()
4205 msg->data[2] = chan; in handle_lan_get_msg_cmd()
4206 msg->data[3] = msg->rsp[4]; /* handle */ in handle_lan_get_msg_cmd()
4207 msg->data[4] = msg->rsp[8]; /* rsSWID */ in handle_lan_get_msg_cmd()
4208 msg->data[5] = ((netfn + 1) << 2) | (msg->rsp[9] & 0x3); in handle_lan_get_msg_cmd()
4209 msg->data[6] = ipmb_checksum(&msg->data[3], 3); in handle_lan_get_msg_cmd()
4210 msg->data[7] = msg->rsp[5]; /* rqSWID */ in handle_lan_get_msg_cmd()
4212 msg->data[8] = (msg->rsp[9] & 0xfc) | (msg->rsp[6] & 0x3); in handle_lan_get_msg_cmd()
4213 msg->data[9] = cmd; in handle_lan_get_msg_cmd()
4214 msg->data[10] = IPMI_INVALID_CMD_COMPLETION_CODE; in handle_lan_get_msg_cmd()
4215 msg->data[11] = ipmb_checksum(&msg->data[7], 4); in handle_lan_get_msg_cmd()
4216 msg->data_size = 12; in handle_lan_get_msg_cmd()
4218 dev_dbg(intf->si_dev, "Invalid command: %*ph\n", in handle_lan_get_msg_cmd()
4219 msg->data_size, msg->data); in handle_lan_get_msg_cmd()
4221 smi_send(intf, intf->handlers, msg, 0); in handle_lan_get_msg_cmd()
4226 rv = -1; in handle_lan_get_msg_cmd()
4229 lan_addr = (struct ipmi_lan_addr *) &recv_msg->addr; in handle_lan_get_msg_cmd()
4230 lan_addr->addr_type = IPMI_LAN_ADDR_TYPE; in handle_lan_get_msg_cmd()
4231 lan_addr->session_handle = msg->rsp[4]; in handle_lan_get_msg_cmd()
4232 lan_addr->remote_SWID = msg->rsp[8]; in handle_lan_get_msg_cmd()
4233 lan_addr->local_SWID = msg->rsp[5]; in handle_lan_get_msg_cmd()
4234 lan_addr->lun = msg->rsp[9] & 3; in handle_lan_get_msg_cmd()
4235 lan_addr->channel = msg->rsp[3] & 0xf; in handle_lan_get_msg_cmd()
4236 lan_addr->privilege = msg->rsp[3] >> 4; in handle_lan_get_msg_cmd()
4240 * from the IPMB header. in handle_lan_get_msg_cmd()
4242 recv_msg->recv_type = IPMI_CMD_RECV_TYPE; in handle_lan_get_msg_cmd()
4243 recv_msg->msgid = msg->rsp[9] >> 2; in handle_lan_get_msg_cmd()
4244 recv_msg->msg.netfn = msg->rsp[6] >> 2; in handle_lan_get_msg_cmd()
4245 recv_msg->msg.cmd = msg->rsp[10]; in handle_lan_get_msg_cmd()
4246 recv_msg->msg.data = recv_msg->msg_data; in handle_lan_get_msg_cmd()
4252 recv_msg->msg.data_len = msg->rsp_size - 12; in handle_lan_get_msg_cmd()
4253 memcpy(recv_msg->msg_data, &msg->rsp[11], in handle_lan_get_msg_cmd()
4254 msg->rsp_size - 12); in handle_lan_get_msg_cmd()
4273 * the OEM. See IPMI 2.0 specification, Chapter 6 and
4292 if (msg->rsp_size < 4) { in handle_oem_get_msg_cmd()
4298 if (msg->rsp[2] != 0) { in handle_oem_get_msg_cmd()
4307 netfn = msg->rsp[0] >> 2; in handle_oem_get_msg_cmd()
4308 cmd = msg->rsp[1]; in handle_oem_get_msg_cmd()
4309 chan = msg->rsp[3] & 0xf; in handle_oem_get_msg_cmd()
4314 user = rcvr->user; in handle_oem_get_msg_cmd()
4337 &recv_msg->addr); in handle_oem_get_msg_cmd()
4338 smi_addr->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; in handle_oem_get_msg_cmd()
4339 smi_addr->channel = IPMI_BMC_CHANNEL; in handle_oem_get_msg_cmd()
4340 smi_addr->lun = msg->rsp[0] & 3; in handle_oem_get_msg_cmd()
4342 recv_msg->user_msg_data = NULL; in handle_oem_get_msg_cmd()
4343 recv_msg->recv_type = IPMI_OEM_RECV_TYPE; in handle_oem_get_msg_cmd()
4344 recv_msg->msg.netfn = msg->rsp[0] >> 2; in handle_oem_get_msg_cmd()
4345 recv_msg->msg.cmd = msg->rsp[1]; in handle_oem_get_msg_cmd()
4346 recv_msg->msg.data = recv_msg->msg_data; in handle_oem_get_msg_cmd()
4352 recv_msg->msg.data_len = msg->rsp_size - 4; in handle_oem_get_msg_cmd()
4353 memcpy(recv_msg->msg_data, &msg->rsp[4], in handle_oem_get_msg_cmd()
4354 msg->rsp_size - 4); in handle_oem_get_msg_cmd()
4375 recv_msg->msgid = 0; in copy_event_into_recv_msg()
4376 smi_addr = (struct ipmi_system_interface_addr *) &recv_msg->addr; in copy_event_into_recv_msg()
4377 smi_addr->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; in copy_event_into_recv_msg()
4378 smi_addr->channel = IPMI_BMC_CHANNEL; in copy_event_into_recv_msg()
4379 smi_addr->lun = msg->rsp[0] & 3; in copy_event_into_recv_msg()
4380 recv_msg->recv_type = IPMI_ASYNC_EVENT_RECV_TYPE; in copy_event_into_recv_msg()
4381 recv_msg->msg.netfn = msg->rsp[0] >> 2; in copy_event_into_recv_msg()
4382 recv_msg->msg.cmd = msg->rsp[1]; in copy_event_into_recv_msg()
4383 memcpy(recv_msg->msg_data, &msg->rsp[3], msg->rsp_size - 3); in copy_event_into_recv_msg()
4384 recv_msg->msg.data = recv_msg->msg_data; in copy_event_into_recv_msg()
4385 recv_msg->msg.data_len = msg->rsp_size - 3; in copy_event_into_recv_msg()
4396 if (msg->rsp_size < 19) { in handle_read_event_rsp()
4397 /* Message is too small to be an IPMB event. */ in handle_read_event_rsp()
4402 if (msg->rsp[2] != 0) { in handle_read_event_rsp()
4409 mutex_lock(&intf->events_mutex); in handle_read_event_rsp()
4417 mutex_lock(&intf->users_mutex); in handle_read_event_rsp()
4418 list_for_each_entry(user, &intf->users, link) { in handle_read_event_rsp()
4419 if (!user->gets_events) in handle_read_event_rsp()
4424 mutex_unlock(&intf->users_mutex); in handle_read_event_rsp()
4427 user = recv_msg->user; in handle_read_event_rsp()
4428 list_del(&recv_msg->link); in handle_read_event_rsp()
4430 kref_put(&user->refcount, free_ipmi_user); in handle_read_event_rsp()
4444 list_add_tail(&recv_msg->link, &msgs); in handle_read_event_rsp()
4446 mutex_unlock(&intf->users_mutex); in handle_read_event_rsp()
4451 list_del(&recv_msg->link); in handle_read_event_rsp()
4454 } else if (intf->waiting_events_count < MAX_EVENTS_IN_QUEUE) { in handle_read_event_rsp()
4471 list_add_tail(&recv_msg->link, &intf->waiting_events); in handle_read_event_rsp()
4472 intf->waiting_events_count++; in handle_read_event_rsp()
4473 } else if (!intf->event_msg_printed) { in handle_read_event_rsp()
4478 dev_warn(intf->si_dev, in handle_read_event_rsp()
4480 intf->event_msg_printed = 1; in handle_read_event_rsp()
4484 mutex_unlock(&intf->events_mutex); in handle_read_event_rsp()
4495 recv_msg = msg->recv_msg; in handle_bmc_rsp()
4497 dev_warn(intf->si_dev, in handle_bmc_rsp()
4498 …"IPMI SMI message received with no owner. This could be because of a malformed message, or because… in handle_bmc_rsp()
4502 recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE; in handle_bmc_rsp()
4503 recv_msg->msgid = msg->msgid; in handle_bmc_rsp()
4505 &recv_msg->addr); in handle_bmc_rsp()
4506 smi_addr->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; in handle_bmc_rsp()
4507 smi_addr->channel = IPMI_BMC_CHANNEL; in handle_bmc_rsp()
4508 smi_addr->lun = msg->rsp[0] & 3; in handle_bmc_rsp()
4509 recv_msg->msg.netfn = msg->rsp[0] >> 2; in handle_bmc_rsp()
4510 recv_msg->msg.cmd = msg->rsp[1]; in handle_bmc_rsp()
4511 memcpy(recv_msg->msg_data, &msg->rsp[2], msg->rsp_size - 2); in handle_bmc_rsp()
4512 recv_msg->msg.data = recv_msg->msg_data; in handle_bmc_rsp()
4513 recv_msg->msg.data_len = msg->rsp_size - 2; in handle_bmc_rsp()
4521 * 0 if the message should be freed, or -1 if the message should not
4530 bool is_cmd = !((msg->rsp[0] >> 2) & 1); in handle_one_recv_msg()
4532 dev_dbg(intf->si_dev, "Recv: %*ph\n", msg->rsp_size, msg->rsp); in handle_one_recv_msg()
4534 if (msg->rsp_size < 2) { in handle_one_recv_msg()
4536 dev_warn_ratelimited(intf->si_dev, in handle_one_recv_msg()
4538 (msg->data[0] >> 2) | 1, in handle_one_recv_msg()
4539 msg->data[1], msg->rsp_size); in handle_one_recv_msg()
4543 msg->rsp[0] = msg->data[0] | (1 << 2); in handle_one_recv_msg()
4544 msg->rsp[1] = msg->data[1]; in handle_one_recv_msg()
4545 msg->rsp[2] = IPMI_ERR_UNSPECIFIED; in handle_one_recv_msg()
4546 msg->rsp_size = 3; in handle_one_recv_msg()
4547 } else if (msg->type == IPMI_SMI_MSG_TYPE_IPMB_DIRECT) { in handle_one_recv_msg()
4549 if (is_cmd && (msg->rsp_size < 4)) { in handle_one_recv_msg()
4553 if (!is_cmd && (msg->rsp_size < 5)) { in handle_one_recv_msg()
4556 msg->rsp[0] = msg->data[0] & 0xfc; /* NetFN */ in handle_one_recv_msg()
4557 msg->rsp[0] |= (1 << 2); /* Make it a response */ in handle_one_recv_msg()
4558 msg->rsp[0] |= msg->data[2] & 3; /* rqLUN */ in handle_one_recv_msg()
4559 msg->rsp[1] = msg->data[1]; /* Addr */ in handle_one_recv_msg()
4560 msg->rsp[2] = msg->data[2] & 0xfc; /* rqSeq */ in handle_one_recv_msg()
4561 msg->rsp[2] |= msg->data[0] & 0x3; /* rsLUN */ in handle_one_recv_msg()
4562 msg->rsp[3] = msg->data[3]; /* Cmd */ in handle_one_recv_msg()
4563 msg->rsp[4] = IPMI_ERR_UNSPECIFIED; in handle_one_recv_msg()
4564 msg->rsp_size = 5; in handle_one_recv_msg()
4566 } else if ((msg->data_size >= 2) in handle_one_recv_msg()
4567 && (msg->data[0] == (IPMI_NETFN_APP_REQUEST << 2)) in handle_one_recv_msg()
4568 && (msg->data[1] == IPMI_SEND_MSG_CMD) in handle_one_recv_msg()
4569 && (msg->recv_msg == NULL)) { in handle_one_recv_msg()
4571 if (intf->in_shutdown || intf->run_to_completion) in handle_one_recv_msg()
4587 if ((msg->rsp_size >= 3) && (msg->rsp[2] != 0) in handle_one_recv_msg()
4588 && (msg->rsp[2] != IPMI_NODE_BUSY_ERR) in handle_one_recv_msg()
4589 && (msg->rsp[2] != IPMI_LOST_ARBITRATION_ERR) in handle_one_recv_msg()
4590 && (msg->rsp[2] != IPMI_BUS_ERR) in handle_one_recv_msg()
4591 && (msg->rsp[2] != IPMI_NAK_ON_WRITE_ERR)) { in handle_one_recv_msg()
4592 int ch = msg->rsp[3] & 0xf; in handle_one_recv_msg()
4597 chans = READ_ONCE(intf->channel_list)->c; in handle_one_recv_msg()
4603 intf_err_seq(intf, msg->msgid, msg->rsp[2]); in handle_one_recv_msg()
4606 intf_start_seq_timer(intf, msg->msgid); in handle_one_recv_msg()
4609 } else if (((msg->rsp[0] >> 2) != ((msg->data[0] >> 2) | 1)) in handle_one_recv_msg()
4610 || (msg->rsp[1] != msg->data[1])) { in handle_one_recv_msg()
4615 dev_warn_ratelimited(intf->si_dev, in handle_one_recv_msg()
4617 (msg->data[0] >> 2) | 1, msg->data[1], in handle_one_recv_msg()
4618 msg->rsp[0] >> 2, msg->rsp[1]); in handle_one_recv_msg()
4623 if (msg->type == IPMI_SMI_MSG_TYPE_IPMB_DIRECT) { in handle_one_recv_msg()
4624 if ((msg->data[0] >> 2) & 1) { in handle_one_recv_msg()
4627 cc = msg->rsp[4]; in handle_one_recv_msg()
4634 } else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2)) in handle_one_recv_msg()
4635 && (msg->rsp[1] == IPMI_SEND_MSG_CMD) in handle_one_recv_msg()
4636 && (msg->recv_msg != NULL)) { in handle_one_recv_msg()
4643 if (intf->run_to_completion) in handle_one_recv_msg()
4646 chan = msg->data[2] & 0x0f; in handle_one_recv_msg()
4650 cc = msg->rsp[2]; in handle_one_recv_msg()
4653 recv_msg = msg->recv_msg; in handle_one_recv_msg()
4659 recv_msg->recv_type = IPMI_RESPONSE_RESPONSE_TYPE; in handle_one_recv_msg()
4660 recv_msg->msg.data = recv_msg->msg_data; in handle_one_recv_msg()
4661 recv_msg->msg_data[0] = cc; in handle_one_recv_msg()
4662 recv_msg->msg.data_len = 1; in handle_one_recv_msg()
4664 } else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2)) in handle_one_recv_msg()
4665 && (msg->rsp[1] == IPMI_GET_MSG_CMD)) { in handle_one_recv_msg()
4668 if (intf->run_to_completion) in handle_one_recv_msg()
4672 chan = msg->rsp[3] & 0xf; in handle_one_recv_msg()
4685 if (!intf->channels_ready) { in handle_one_recv_msg()
4690 chans = READ_ONCE(intf->channel_list)->c; in handle_one_recv_msg()
4694 if (msg->rsp[4] & 0x04) { in handle_one_recv_msg()
4711 if (msg->rsp[6] & 0x04) { in handle_one_recv_msg()
4742 } else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2)) in handle_one_recv_msg()
4743 && (msg->rsp[1] == IPMI_READ_EVENT_MSG_BUFFER_CMD)) { in handle_one_recv_msg()
4745 if (intf->run_to_completion) in handle_one_recv_msg()
4766 int run_to_completion = READ_ONCE(intf->run_to_completion); in handle_new_recv_msgs()
4770 spin_lock_irqsave(&intf->waiting_rcv_msgs_lock, flags); in handle_new_recv_msgs()
4771 while (!list_empty(&intf->waiting_rcv_msgs)) { in handle_new_recv_msgs()
4772 smi_msg = list_entry(intf->waiting_rcv_msgs.next, in handle_new_recv_msgs()
4774 list_del(&smi_msg->link); in handle_new_recv_msgs()
4776 spin_unlock_irqrestore(&intf->waiting_rcv_msgs_lock, in handle_new_recv_msgs()
4780 spin_lock_irqsave(&intf->waiting_rcv_msgs_lock, flags); in handle_new_recv_msgs()
4789 list_add(&smi_msg->link, &intf->waiting_rcv_msgs); in handle_new_recv_msgs()
4799 spin_unlock_irqrestore(&intf->waiting_rcv_msgs_lock, flags); in handle_new_recv_msgs()
4804 unsigned long flags = 0; /* keep us warning-free. */ in smi_work()
4806 int run_to_completion = READ_ONCE(intf->run_to_completion); in smi_work()
4820 spin_lock_irqsave(&intf->xmit_msgs_lock, flags); in smi_work()
4821 if (intf->curr_msg == NULL && !intf->in_shutdown) { in smi_work()
4825 if (!list_empty(&intf->hp_xmit_msgs)) in smi_work()
4826 entry = intf->hp_xmit_msgs.next; in smi_work()
4827 else if (!list_empty(&intf->xmit_msgs)) in smi_work()
4828 entry = intf->xmit_msgs.next; in smi_work()
4833 intf->curr_msg = newmsg; in smi_work()
4837 spin_unlock_irqrestore(&intf->xmit_msgs_lock, flags); in smi_work()
4840 cc = intf->handlers->sender(intf->send_info, newmsg); in smi_work()
4842 if (newmsg->recv_msg) in smi_work()
4844 newmsg->recv_msg, cc); in smi_work()
4858 * If the pretimout count is non-zero, decrement one from it and in smi_work()
4861 if (atomic_add_unless(&intf->watchdog_pretimeouts_to_deliver, -1, 0)) { in smi_work()
4864 mutex_lock(&intf->users_mutex); in smi_work()
4865 list_for_each_entry(user, &intf->users, link) { in smi_work()
4866 if (user->handler->ipmi_watchdog_pretimeout) in smi_work()
4867 user->handler->ipmi_watchdog_pretimeout( in smi_work()
4868 user->handler_data); in smi_work()
4870 mutex_unlock(&intf->users_mutex); in smi_work()
4878 kref_get(&intf->refcount); in smi_work()
4880 mutex_lock(&intf->user_msgs_mutex); in smi_work()
4881 list_for_each_entry_safe(msg, msg2, &intf->user_msgs, link) { in smi_work()
4882 struct ipmi_user *user = msg->user; in smi_work()
4884 list_del(&msg->link); in smi_work()
4886 if (refcount_read(&user->destroyed) == 0) in smi_work()
4889 user->handler->ipmi_recv_hndl(msg, user->handler_data); in smi_work()
4891 mutex_unlock(&intf->user_msgs_mutex); in smi_work()
4893 kref_put(&intf->refcount, intf_free); in smi_work()
4900 unsigned long flags = 0; /* keep us warning-free. */ in ipmi_smi_msg_received()
4901 int run_to_completion = READ_ONCE(intf->run_to_completion); in ipmi_smi_msg_received()
4908 spin_lock_irqsave(&intf->waiting_rcv_msgs_lock, flags); in ipmi_smi_msg_received()
4909 list_add_tail(&msg->link, &intf->waiting_rcv_msgs); in ipmi_smi_msg_received()
4911 spin_unlock_irqrestore(&intf->waiting_rcv_msgs_lock, in ipmi_smi_msg_received()
4915 spin_lock_irqsave(&intf->xmit_msgs_lock, flags); in ipmi_smi_msg_received()
4920 if (msg == intf->curr_msg) in ipmi_smi_msg_received()
4921 intf->curr_msg = NULL; in ipmi_smi_msg_received()
4923 spin_unlock_irqrestore(&intf->xmit_msgs_lock, flags); in ipmi_smi_msg_received()
4926 smi_work(&intf->smi_work); in ipmi_smi_msg_received()
4928 queue_work(system_wq, &intf->smi_work); in ipmi_smi_msg_received()
4934 if (intf->in_shutdown) in ipmi_smi_watchdog_pretimeout()
4937 atomic_set(&intf->watchdog_pretimeouts_to_deliver, 1); in ipmi_smi_watchdog_pretimeout()
4938 queue_work(system_wq, &intf->smi_work); in ipmi_smi_watchdog_pretimeout()
4954 memcpy(smi_msg->data, recv_msg->msg.data, recv_msg->msg.data_len); in smi_from_recv_msg()
4955 smi_msg->data_size = recv_msg->msg.data_len; in smi_from_recv_msg()
4956 smi_msg->msgid = STORE_SEQ_IN_MSGID(seq, seqid); in smi_from_recv_msg()
4958 dev_dbg(intf->si_dev, "Resend: %*ph\n", in smi_from_recv_msg()
4959 smi_msg->data_size, smi_msg->data); in smi_from_recv_msg()
4971 if (intf->in_shutdown) in check_msg_timeout()
4974 if (!ent->inuse) in check_msg_timeout()
4977 if (timeout_period < ent->timeout) { in check_msg_timeout()
4978 ent->timeout -= timeout_period; in check_msg_timeout()
4983 if (ent->retries_left == 0) { in check_msg_timeout()
4985 ent->inuse = 0; in check_msg_timeout()
4987 msg = ent->recv_msg; in check_msg_timeout()
4988 list_add_tail(&msg->link, timeouts); in check_msg_timeout()
4989 if (ent->broadcast) in check_msg_timeout()
4991 else if (is_lan_addr(&ent->recv_msg->addr)) in check_msg_timeout()
5005 ent->timeout = MAX_MSG_TIMEOUT; in check_msg_timeout()
5006 ent->retries_left--; in check_msg_timeout()
5007 smi_msg = smi_from_recv_msg(intf, ent->recv_msg, slot, in check_msg_timeout()
5008 ent->seqid); in check_msg_timeout()
5010 if (is_lan_addr(&ent->recv_msg->addr)) in check_msg_timeout()
5019 mutex_unlock(&intf->seq_lock); in check_msg_timeout()
5028 if (intf->handlers) { in check_msg_timeout()
5029 if (is_lan_addr(&ent->recv_msg->addr)) in check_msg_timeout()
5036 smi_send(intf, intf->handlers, smi_msg, 0); in check_msg_timeout()
5040 mutex_lock(&intf->seq_lock); in check_msg_timeout()
5053 if (!intf->bmc_registered) { in ipmi_timeout_handler()
5054 kref_get(&intf->refcount); in ipmi_timeout_handler()
5055 if (!schedule_work(&intf->bmc_reg_work)) { in ipmi_timeout_handler()
5056 kref_put(&intf->refcount, intf_free); in ipmi_timeout_handler()
5067 mutex_lock(&intf->seq_lock); in ipmi_timeout_handler()
5068 if (intf->ipmb_maintenance_mode_timeout) { in ipmi_timeout_handler()
5069 if (intf->ipmb_maintenance_mode_timeout <= timeout_period) in ipmi_timeout_handler()
5070 intf->ipmb_maintenance_mode_timeout = 0; in ipmi_timeout_handler()
5072 intf->ipmb_maintenance_mode_timeout -= timeout_period; in ipmi_timeout_handler()
5075 check_msg_timeout(intf, &intf->seq_table[i], in ipmi_timeout_handler()
5078 mutex_unlock(&intf->seq_lock); in ipmi_timeout_handler()
5091 if (intf->auto_maintenance_timeout > 0) { in ipmi_timeout_handler()
5092 spin_lock_irqsave(&intf->maintenance_mode_lock, flags); in ipmi_timeout_handler()
5093 if (intf->auto_maintenance_timeout > 0) { in ipmi_timeout_handler()
5094 intf->auto_maintenance_timeout in ipmi_timeout_handler()
5095 -= timeout_period; in ipmi_timeout_handler()
5096 if (!intf->maintenance_mode in ipmi_timeout_handler()
5097 && (intf->auto_maintenance_timeout <= 0)) { in ipmi_timeout_handler()
5098 intf->maintenance_mode_state = in ipmi_timeout_handler()
5100 intf->auto_maintenance_timeout = 0; in ipmi_timeout_handler()
5104 spin_unlock_irqrestore(&intf->maintenance_mode_lock, in ipmi_timeout_handler()
5108 queue_work(system_wq, &intf->smi_work); in ipmi_timeout_handler()
5116 if (intf->maintenance_mode_state) in ipmi_request_event()
5119 if (!intf->in_shutdown) in ipmi_request_event()
5120 intf->handlers->request_events(intf->send_info); in ipmi_request_event()
5138 if (atomic_read(&intf->event_waiters)) { in ipmi_timeout_work()
5139 intf->ticks_to_req_ev--; in ipmi_timeout_work()
5140 if (intf->ticks_to_req_ev == 0) { in ipmi_timeout_work()
5142 intf->ticks_to_req_ev = IPMI_REQUEST_EV_TIME; in ipmi_timeout_work()
5146 if (intf->maintenance_mode_state) in ipmi_timeout_work()
5190 rv->done = free_smi_msg; in ipmi_alloc_smi_msg()
5191 rv->recv_msg = NULL; in ipmi_alloc_smi_msg()
5192 rv->type = IPMI_SMI_MSG_TYPE_NORMAL; in ipmi_alloc_smi_msg()
5212 if (atomic_add_return(1, &user->nr_msgs) > max_msgs_per_user) { in ipmi_alloc_recv_msg()
5213 atomic_dec(&user->nr_msgs); in ipmi_alloc_recv_msg()
5214 return ERR_PTR(-EBUSY); in ipmi_alloc_recv_msg()
5221 atomic_dec(&user->nr_msgs); in ipmi_alloc_recv_msg()
5222 return ERR_PTR(-ENOMEM); in ipmi_alloc_recv_msg()
5225 rv->user = user; in ipmi_alloc_recv_msg()
5226 rv->done = free_recv_msg; in ipmi_alloc_recv_msg()
5228 kref_get(&user->refcount); in ipmi_alloc_recv_msg()
5235 if (msg->user && !oops_in_progress) { in ipmi_free_recv_msg()
5236 atomic_dec(&msg->user->nr_msgs); in ipmi_free_recv_msg()
5237 kref_put(&msg->user->refcount, free_ipmi_user); in ipmi_free_recv_msg()
5239 msg->done(msg); in ipmi_free_recv_msg()
5246 WARN_ON_ONCE(msg->user); /* User should not be set. */ in ipmi_set_recv_msg_user()
5247 msg->user = user; in ipmi_set_recv_msg_user()
5248 atomic_inc(&user->nr_msgs); in ipmi_set_recv_msg_user()
5249 kref_get(&user->refcount); in ipmi_set_recv_msg_user()
5287 intf->addrinfo[0].address, in _ipmi_panic_request_and_wait()
5288 intf->addrinfo[0].lun, in _ipmi_panic_request_and_wait()
5292 else if (intf->handlers->flush_messages) in _ipmi_panic_request_and_wait()
5293 intf->handlers->flush_messages(intf->send_info); in _ipmi_panic_request_and_wait()
5303 user->intf->run_to_completion = 1; in ipmi_panic_request_and_wait()
5304 _ipmi_panic_request_and_wait(user->intf, addr, msg); in ipmi_panic_request_and_wait()
5311 if ((msg->addr.addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) in event_receiver_fetcher()
5312 && (msg->msg.netfn == IPMI_NETFN_SENSOR_EVENT_RESPONSE) in event_receiver_fetcher()
5313 && (msg->msg.cmd == IPMI_GET_EVENT_RECEIVER_CMD) in event_receiver_fetcher()
5314 && (msg->msg.data[0] == IPMI_CC_NO_ERROR)) { in event_receiver_fetcher()
5316 intf->event_receiver = msg->msg.data[1]; in event_receiver_fetcher()
5317 intf->event_receiver_lun = msg->msg.data[2] & 0x3; in event_receiver_fetcher()
5323 if ((msg->addr.addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) in device_id_fetcher()
5324 && (msg->msg.netfn == IPMI_NETFN_APP_RESPONSE) in device_id_fetcher()
5325 && (msg->msg.cmd == IPMI_GET_DEVICE_ID_CMD) in device_id_fetcher()
5326 && (msg->msg.data[0] == IPMI_CC_NO_ERROR)) { in device_id_fetcher()
5331 intf->local_sel_device = (msg->msg.data[6] >> 2) & 1; in device_id_fetcher()
5332 intf->local_event_generator = (msg->msg.data[6] >> 5) & 1; in device_id_fetcher()
5343 struct ipmi_ipmb_addr *ipmb; in send_panic_events() local
5350 si->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; in send_panic_events()
5351 si->channel = IPMI_BMC_CHANNEL; in send_panic_events()
5352 si->lun = 0; in send_panic_events()
5359 data[0] = 0x41; /* Kernel generator ID, IPMI table 5-4 */ in send_panic_events()
5360 data[1] = 0x03; /* This is for IPMI 1.0. */ in send_panic_events()
5361 data[2] = 0x20; /* OS Critical Stop, IPMI table 36-3 */ in send_panic_events()
5362 data[4] = 0x6f; /* Sensor specific, IPMI table 36-1 */ in send_panic_events()
5395 * OEM events. There's no way in IPMI to send OEM in send_panic_events()
5402 intf->local_sel_device = 0; in send_panic_events()
5403 intf->local_event_generator = 0; in send_panic_events()
5404 intf->event_receiver = 0; in send_panic_events()
5411 intf->null_user_handler = device_id_fetcher; in send_panic_events()
5414 if (intf->local_event_generator) { in send_panic_events()
5420 intf->null_user_handler = event_receiver_fetcher; in send_panic_events()
5423 intf->null_user_handler = NULL; in send_panic_events()
5427 * be 1 (it must be a valid IPMB address), it cannot in send_panic_events()
5430 if (((intf->event_receiver & 1) == 0) in send_panic_events()
5431 && (intf->event_receiver != 0) in send_panic_events()
5432 && (intf->event_receiver != intf->addrinfo[0].address)) { in send_panic_events()
5434 * The event receiver is valid, send an IPMB in send_panic_events()
5437 ipmb = (struct ipmi_ipmb_addr *) &addr; in send_panic_events()
5438 ipmb->addr_type = IPMI_IPMB_ADDR_TYPE; in send_panic_events()
5439 ipmb->channel = 0; /* FIXME - is this right? */ in send_panic_events()
5440 ipmb->lun = intf->event_receiver_lun; in send_panic_events()
5441 ipmb->slave_addr = intf->event_receiver; in send_panic_events()
5442 } else if (intf->local_sel_device) { in send_panic_events()
5449 si->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; in send_panic_events()
5450 si->channel = IPMI_BMC_CHANNEL; in send_panic_events()
5451 si->lun = 0; in send_panic_events()
5467 data[3] = intf->addrinfo[0].address; in send_panic_events()
5492 if (!intf->handlers || intf->intf_num == -1) in panic_event()
5496 if (!intf->handlers->poll) in panic_event()
5505 if (!spin_trylock(&intf->xmit_msgs_lock)) { in panic_event()
5506 INIT_LIST_HEAD(&intf->xmit_msgs); in panic_event()
5507 INIT_LIST_HEAD(&intf->hp_xmit_msgs); in panic_event()
5509 spin_unlock(&intf->xmit_msgs_lock); in panic_event()
5511 if (!spin_trylock(&intf->waiting_rcv_msgs_lock)) in panic_event()
5512 INIT_LIST_HEAD(&intf->waiting_rcv_msgs); in panic_event()
5514 spin_unlock(&intf->waiting_rcv_msgs_lock); in panic_event()
5516 intf->run_to_completion = 1; in panic_event()
5517 if (intf->handlers->set_run_to_completion) in panic_event()
5518 intf->handlers->set_run_to_completion(intf->send_info, in panic_event()
5521 list_for_each_entry(user, &intf->users, link) { in panic_event()
5522 if (user->handler->ipmi_panic_handler) in panic_event()
5523 user->handler->ipmi_panic_handler( in panic_event()
5524 user->handler_data); in panic_event()
5543 pr_err("Could not register IPMI driver\n"); in ipmi_register_driver()
5566 bmc_remove_work_wq = create_singlethread_workqueue("ipmi-msghandler-remove-wq"); in ipmi_init_msghandler()
5568 pr_err("unable to create ipmi-msghandler-remove-wq workqueue"); in ipmi_init_msghandler()
5569 rv = -ENOMEM; in ipmi_init_msghandler()
5640 MODULE_DESCRIPTION("Incoming and outgoing message routing for an IPMI interface.");