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>
81 e = match_string(ipmi_panic_event_str, -1, strstrip(valcp)); in panic_op_write_handler()
106 …IPMI driver will attempt to store panic information in the event log in the event of a panic. Set…
111 /* Remain in auto-maintenance mode for this amount of time (in ms). */
152 "The most users that may use the IPMI stack at one time.");
169 * future, IPMI will add a way to know immediately if an event is in
199 /* Does this interface receive IPMI events? */
211 __acquires(user->release_barrier) in acquire_ipmi_user()
215 *index = srcu_read_lock(&user->release_barrier); in acquire_ipmi_user()
216 ruser = srcu_dereference(user->self, &user->release_barrier); in acquire_ipmi_user()
218 srcu_read_unlock(&user->release_barrier, *index); in acquire_ipmi_user()
224 srcu_read_unlock(&user->release_barrier, index); in release_ipmi_user()
335 * Various statistics for IPMI, these index stats[] in the ipmi_smi
351 /* Commands we sent out to the IPMB bus. */
354 /* Commands sent on the IPMB that had errors on the SEND CMD */
373 /* Responses I have sent to the IPMB bus. */
385 /* Commands we sent out to the IPMB bus. */
388 /* Commands sent on the IPMB that had errors on the SEND CMD */
400 /* Responses I have sent to the IPMB bus. */
427 /* Retransmissions on IPMB that failed. */
485 /* Driver-model device for the system interface. */
490 * sequence numbers for IPMB messages that go out of the
568 * If we are doing maintenance on something on IPMB, extend
575 * A cheap hack, if this is non-null and a message to an
603 * parameters passed by "low" level IPMI code.
618 * The driver model view of the IPMI messaging driver.
622 .name = "ipmi",
644 atomic_inc(&(intf)->stats[IPMI_STAT_ ## stat])
646 ((unsigned int) atomic_read(&(intf)->stats[IPMI_STAT_ ## stat]))
650 "device-tree", "platform"
663 return addr->addr_type == IPMI_LAN_ADDR_TYPE; in is_lan_addr()
668 return addr->addr_type == IPMI_IPMB_ADDR_TYPE; in is_ipmb_addr()
673 return addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE; in is_ipmb_bcast_addr()
678 return addr->addr_type == IPMI_IPMB_DIRECT_ADDR_TYPE; in is_ipmb_direct_addr()
686 list_del(&msg->link); in free_recv_msg_list()
696 list_del(&msg->link); in free_smi_msg_list()
707 cancel_work_sync(&intf->recv_work); in clean_up_interface_data()
709 free_smi_msg_list(&intf->waiting_rcv_msgs); in clean_up_interface_data()
710 free_recv_msg_list(&intf->waiting_events); in clean_up_interface_data()
716 mutex_lock(&intf->cmd_rcvrs_mutex); in clean_up_interface_data()
718 list_splice_init_rcu(&intf->cmd_rcvrs, &list, synchronize_rcu); in clean_up_interface_data()
719 mutex_unlock(&intf->cmd_rcvrs_mutex); in clean_up_interface_data()
725 if ((intf->seq_table[i].inuse) in clean_up_interface_data()
726 && (intf->seq_table[i].recv_msg)) in clean_up_interface_data()
727 ipmi_free_recv_msg(intf->seq_table[i].recv_msg); in clean_up_interface_data()
754 list_add(&watcher->link, &smi_watchers); in ipmi_smi_watcher_register()
759 int intf_num = READ_ONCE(intf->intf_num); in ipmi_smi_watcher_register()
761 if (intf_num == -1) in ipmi_smi_watcher_register()
763 watcher->new_smi(intf_num, intf->si_dev); in ipmi_smi_watcher_register()
776 list_del(&watcher->link); in ipmi_smi_watcher_unregister()
792 if (try_module_get(w->owner)) { in call_smi_watchers()
793 w->new_smi(i, dev); in call_smi_watchers()
794 module_put(w->owner); in call_smi_watchers()
803 if (addr1->addr_type != addr2->addr_type) in ipmi_addr_equal()
806 if (addr1->channel != addr2->channel) in ipmi_addr_equal()
809 if (addr1->addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) { in ipmi_addr_equal()
814 return (smi_addr1->lun == smi_addr2->lun); in ipmi_addr_equal()
823 return ((ipmb_addr1->slave_addr == ipmb_addr2->slave_addr) in ipmi_addr_equal()
824 && (ipmb_addr1->lun == ipmb_addr2->lun)); in ipmi_addr_equal()
833 return daddr1->slave_addr == daddr2->slave_addr && in ipmi_addr_equal()
834 daddr1->rq_lun == daddr2->rq_lun && in ipmi_addr_equal()
835 daddr1->rs_lun == daddr2->rs_lun; in ipmi_addr_equal()
844 return ((lan_addr1->remote_SWID == lan_addr2->remote_SWID) in ipmi_addr_equal()
845 && (lan_addr1->local_SWID == lan_addr2->local_SWID) in ipmi_addr_equal()
846 && (lan_addr1->session_handle in ipmi_addr_equal()
847 == lan_addr2->session_handle) in ipmi_addr_equal()
848 && (lan_addr1->lun == lan_addr2->lun)); in ipmi_addr_equal()
857 return -EINVAL; in ipmi_validate_addr()
859 if (addr->addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) { in ipmi_validate_addr()
860 if (addr->channel != IPMI_BMC_CHANNEL) in ipmi_validate_addr()
861 return -EINVAL; in ipmi_validate_addr()
865 if ((addr->channel == IPMI_BMC_CHANNEL) in ipmi_validate_addr()
866 || (addr->channel >= IPMI_MAX_CHANNELS) in ipmi_validate_addr()
867 || (addr->channel < 0)) in ipmi_validate_addr()
868 return -EINVAL; in ipmi_validate_addr()
872 return -EINVAL; in ipmi_validate_addr()
879 if (addr->channel != 0) in ipmi_validate_addr()
880 return -EINVAL; in ipmi_validate_addr()
882 return -EINVAL; in ipmi_validate_addr()
884 if (daddr->slave_addr & 0x01) in ipmi_validate_addr()
885 return -EINVAL; in ipmi_validate_addr()
886 if (daddr->rq_lun >= 4) in ipmi_validate_addr()
887 return -EINVAL; in ipmi_validate_addr()
888 if (daddr->rs_lun >= 4) in ipmi_validate_addr()
889 return -EINVAL; in ipmi_validate_addr()
895 return -EINVAL; in ipmi_validate_addr()
899 return -EINVAL; in ipmi_validate_addr()
926 if (!msg->user) { in deliver_response()
928 if (intf->null_user_handler) { in deliver_response()
929 intf->null_user_handler(intf, msg); in deliver_response()
932 rv = -EINVAL; in deliver_response()
942 atomic_dec(&msg->user->nr_msgs); in deliver_response()
945 struct ipmi_user *user = acquire_ipmi_user(msg->user, &index); in deliver_response()
948 atomic_dec(&user->nr_msgs); in deliver_response()
949 user->handler->ipmi_recv_hndl(msg, user->handler_data); in deliver_response()
954 rv = -EINVAL; in deliver_response()
973 msg->recv_type = IPMI_RESPONSE_RECV_TYPE; in deliver_err_response()
974 msg->msg_data[0] = err; in deliver_err_response()
975 msg->msg.netfn |= 1; /* Convert to a response. */ in deliver_err_response()
976 msg->msg.data_len = 1; in deliver_err_response()
977 msg->msg.data = msg->msg_data; in deliver_err_response()
985 if (!intf->handlers->set_need_watch) in smi_add_watch()
988 spin_lock_irqsave(&intf->watch_lock, iflags); in smi_add_watch()
990 intf->response_waiters++; in smi_add_watch()
993 intf->watchdog_waiters++; in smi_add_watch()
996 intf->command_waiters++; in smi_add_watch()
998 if ((intf->last_watch_mask & flags) != flags) { in smi_add_watch()
999 intf->last_watch_mask |= flags; in smi_add_watch()
1000 intf->handlers->set_need_watch(intf->send_info, in smi_add_watch()
1001 intf->last_watch_mask); in smi_add_watch()
1003 spin_unlock_irqrestore(&intf->watch_lock, iflags); in smi_add_watch()
1010 if (!intf->handlers->set_need_watch) in smi_remove_watch()
1013 spin_lock_irqsave(&intf->watch_lock, iflags); in smi_remove_watch()
1015 intf->response_waiters--; in smi_remove_watch()
1018 intf->watchdog_waiters--; in smi_remove_watch()
1021 intf->command_waiters--; in smi_remove_watch()
1024 if (intf->response_waiters) in smi_remove_watch()
1026 if (intf->watchdog_waiters) in smi_remove_watch()
1028 if (intf->command_waiters) in smi_remove_watch()
1031 if (intf->last_watch_mask != flags) { in smi_remove_watch()
1032 intf->last_watch_mask = flags; in smi_remove_watch()
1033 intf->handlers->set_need_watch(intf->send_info, in smi_remove_watch()
1034 intf->last_watch_mask); in smi_remove_watch()
1036 spin_unlock_irqrestore(&intf->watch_lock, iflags); in smi_remove_watch()
1060 for (i = intf->curr_seq; (i+1)%IPMI_IPMB_NUM_SEQ != intf->curr_seq; in intf_next_seq()
1062 if (!intf->seq_table[i].inuse) in intf_next_seq()
1066 if (!intf->seq_table[i].inuse) { in intf_next_seq()
1067 intf->seq_table[i].recv_msg = recv_msg; in intf_next_seq()
1073 intf->seq_table[i].timeout = MAX_MSG_TIMEOUT; in intf_next_seq()
1074 intf->seq_table[i].orig_timeout = timeout; in intf_next_seq()
1075 intf->seq_table[i].retries_left = retries; in intf_next_seq()
1076 intf->seq_table[i].broadcast = broadcast; in intf_next_seq()
1077 intf->seq_table[i].inuse = 1; in intf_next_seq()
1078 intf->seq_table[i].seqid = NEXT_SEQID(intf->seq_table[i].seqid); in intf_next_seq()
1080 *seqid = intf->seq_table[i].seqid; in intf_next_seq()
1081 intf->curr_seq = (i+1)%IPMI_IPMB_NUM_SEQ; in intf_next_seq()
1085 rv = -EAGAIN; in intf_next_seq()
1106 int rv = -ENODEV; in intf_find_seq()
1110 return -EINVAL; in intf_find_seq()
1112 spin_lock_irqsave(&intf->seq_lock, flags); in intf_find_seq()
1113 if (intf->seq_table[seq].inuse) { in intf_find_seq()
1114 struct ipmi_recv_msg *msg = intf->seq_table[seq].recv_msg; in intf_find_seq()
1116 if ((msg->addr.channel == channel) && (msg->msg.cmd == cmd) in intf_find_seq()
1117 && (msg->msg.netfn == netfn) in intf_find_seq()
1118 && (ipmi_addr_equal(addr, &msg->addr))) { in intf_find_seq()
1120 intf->seq_table[seq].inuse = 0; in intf_find_seq()
1125 spin_unlock_irqrestore(&intf->seq_lock, flags); in intf_find_seq()
1135 int rv = -ENODEV; in intf_start_seq_timer()
1143 spin_lock_irqsave(&intf->seq_lock, flags); in intf_start_seq_timer()
1148 if ((intf->seq_table[seq].inuse) in intf_start_seq_timer()
1149 && (intf->seq_table[seq].seqid == seqid)) { in intf_start_seq_timer()
1150 struct seq_table *ent = &intf->seq_table[seq]; in intf_start_seq_timer()
1151 ent->timeout = ent->orig_timeout; in intf_start_seq_timer()
1154 spin_unlock_irqrestore(&intf->seq_lock, flags); in intf_start_seq_timer()
1164 int rv = -ENODEV; in intf_err_seq()
1173 spin_lock_irqsave(&intf->seq_lock, flags); in intf_err_seq()
1178 if ((intf->seq_table[seq].inuse) in intf_err_seq()
1179 && (intf->seq_table[seq].seqid == seqid)) { in intf_err_seq()
1180 struct seq_table *ent = &intf->seq_table[seq]; in intf_err_seq()
1182 ent->inuse = 0; in intf_err_seq()
1184 msg = ent->recv_msg; in intf_err_seq()
1187 spin_unlock_irqrestore(&intf->seq_lock, flags); in intf_err_seq()
1200 cleanup_srcu_struct(&user->release_barrier); in free_user_work()
1223 return -EINVAL; in ipmi_create_user()
1235 return -ENOMEM; in ipmi_create_user()
1239 if (intf->intf_num == if_num) in ipmi_create_user()
1243 rv = -EINVAL; in ipmi_create_user()
1247 if (atomic_add_return(1, &intf->nr_users) > max_users) { in ipmi_create_user()
1248 rv = -EBUSY; in ipmi_create_user()
1252 INIT_WORK(&new_user->remove_work, free_user_work); in ipmi_create_user()
1254 rv = init_srcu_struct(&new_user->release_barrier); in ipmi_create_user()
1258 if (!try_module_get(intf->owner)) { in ipmi_create_user()
1259 rv = -ENODEV; in ipmi_create_user()
1264 kref_get(&intf->refcount); in ipmi_create_user()
1266 atomic_set(&new_user->nr_msgs, 0); in ipmi_create_user()
1267 kref_init(&new_user->refcount); in ipmi_create_user()
1268 new_user->handler = handler; in ipmi_create_user()
1269 new_user->handler_data = handler_data; in ipmi_create_user()
1270 new_user->intf = intf; in ipmi_create_user()
1271 new_user->gets_events = false; in ipmi_create_user()
1273 rcu_assign_pointer(new_user->self, new_user); in ipmi_create_user()
1274 spin_lock_irqsave(&intf->seq_lock, flags); in ipmi_create_user()
1275 list_add_rcu(&new_user->link, &intf->users); in ipmi_create_user()
1276 spin_unlock_irqrestore(&intf->seq_lock, flags); in ipmi_create_user()
1277 if (handler->ipmi_watchdog_pretimeout) in ipmi_create_user()
1285 atomic_dec(&intf->nr_users); in ipmi_create_user()
1299 if (intf->intf_num == if_num) in ipmi_get_smi_info()
1305 return -EINVAL; in ipmi_get_smi_info()
1308 if (!intf->handlers->get_smi_info) in ipmi_get_smi_info()
1309 rv = -ENOTTY; in ipmi_get_smi_info()
1311 rv = intf->handlers->get_smi_info(intf->send_info, data); in ipmi_get_smi_info()
1323 queue_work(remove_work_wq, &user->remove_work); in free_user()
1328 struct ipmi_smi *intf = user->intf; in _ipmi_destroy_user()
1340 synchronize_srcu(&user->release_barrier); in _ipmi_destroy_user()
1344 rcu_assign_pointer(user->self, NULL); in _ipmi_destroy_user()
1347 synchronize_srcu(&user->release_barrier); in _ipmi_destroy_user()
1349 if (user->handler->shutdown) in _ipmi_destroy_user()
1350 user->handler->shutdown(user->handler_data); in _ipmi_destroy_user()
1352 if (user->handler->ipmi_watchdog_pretimeout) in _ipmi_destroy_user()
1355 if (user->gets_events) in _ipmi_destroy_user()
1356 atomic_dec(&intf->event_waiters); in _ipmi_destroy_user()
1359 spin_lock_irqsave(&intf->seq_lock, flags); in _ipmi_destroy_user()
1360 list_del_rcu(&user->link); in _ipmi_destroy_user()
1361 atomic_dec(&intf->nr_users); in _ipmi_destroy_user()
1364 if (intf->seq_table[i].inuse in _ipmi_destroy_user()
1365 && (intf->seq_table[i].recv_msg->user == user)) { in _ipmi_destroy_user()
1366 intf->seq_table[i].inuse = 0; in _ipmi_destroy_user()
1368 ipmi_free_recv_msg(intf->seq_table[i].recv_msg); in _ipmi_destroy_user()
1371 spin_unlock_irqrestore(&intf->seq_lock, flags); in _ipmi_destroy_user()
1379 mutex_lock(&intf->cmd_rcvrs_mutex); in _ipmi_destroy_user()
1380 list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link, in _ipmi_destroy_user()
1381 lockdep_is_held(&intf->cmd_rcvrs_mutex)) { in _ipmi_destroy_user()
1382 if (rcvr->user == user) { in _ipmi_destroy_user()
1383 list_del_rcu(&rcvr->link); in _ipmi_destroy_user()
1384 rcvr->next = rcvrs; in _ipmi_destroy_user()
1388 mutex_unlock(&intf->cmd_rcvrs_mutex); in _ipmi_destroy_user()
1392 rcvrs = rcvr->next; in _ipmi_destroy_user()
1396 owner = intf->owner; in _ipmi_destroy_user()
1397 kref_put(&intf->refcount, intf_free); in _ipmi_destroy_user()
1405 kref_put(&user->refcount, free_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()
1540 intf->handlers->set_maintenance_mode( in maintenance_mode_update()
1541 intf->send_info, intf->maintenance_mode_enable); in maintenance_mode_update()
1548 struct ipmi_smi *intf = user->intf; in ipmi_set_maintenance_mode()
1552 return -ENODEV; in ipmi_set_maintenance_mode()
1554 spin_lock_irqsave(&intf->maintenance_mode_lock, flags); in ipmi_set_maintenance_mode()
1555 if (intf->maintenance_mode != mode) { in ipmi_set_maintenance_mode()
1558 intf->maintenance_mode_enable in ipmi_set_maintenance_mode()
1559 = (intf->auto_maintenance_timeout > 0); in ipmi_set_maintenance_mode()
1563 intf->maintenance_mode_enable = false; in ipmi_set_maintenance_mode()
1567 intf->maintenance_mode_enable = true; in ipmi_set_maintenance_mode()
1571 rv = -EINVAL; in ipmi_set_maintenance_mode()
1574 intf->maintenance_mode = mode; in ipmi_set_maintenance_mode()
1579 spin_unlock_irqrestore(&intf->maintenance_mode_lock, flags); in ipmi_set_maintenance_mode()
1589 struct ipmi_smi *intf = user->intf; in ipmi_set_gets_events()
1596 return -ENODEV; in ipmi_set_gets_events()
1600 spin_lock_irqsave(&intf->events_lock, flags); in ipmi_set_gets_events()
1601 if (user->gets_events == val) in ipmi_set_gets_events()
1604 user->gets_events = val; in ipmi_set_gets_events()
1607 if (atomic_inc_return(&intf->event_waiters) == 1) in ipmi_set_gets_events()
1610 atomic_dec(&intf->event_waiters); in ipmi_set_gets_events()
1613 if (intf->delivering_events) in ipmi_set_gets_events()
1621 while (user->gets_events && !list_empty(&intf->waiting_events)) { in ipmi_set_gets_events()
1622 list_for_each_entry_safe(msg, msg2, &intf->waiting_events, link) in ipmi_set_gets_events()
1623 list_move_tail(&msg->link, &msgs); in ipmi_set_gets_events()
1624 intf->waiting_events_count = 0; in ipmi_set_gets_events()
1625 if (intf->event_msg_printed) { in ipmi_set_gets_events()
1626 dev_warn(intf->si_dev, "Event queue no longer full\n"); in ipmi_set_gets_events()
1627 intf->event_msg_printed = 0; in ipmi_set_gets_events()
1630 intf->delivering_events = 1; in ipmi_set_gets_events()
1631 spin_unlock_irqrestore(&intf->events_lock, flags); in ipmi_set_gets_events()
1634 msg->user = user; in ipmi_set_gets_events()
1635 kref_get(&user->refcount); in ipmi_set_gets_events()
1639 spin_lock_irqsave(&intf->events_lock, flags); in ipmi_set_gets_events()
1640 intf->delivering_events = 0; in ipmi_set_gets_events()
1644 spin_unlock_irqrestore(&intf->events_lock, flags); in ipmi_set_gets_events()
1658 list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link, in find_cmd_rcvr()
1659 lockdep_is_held(&intf->cmd_rcvrs_mutex)) { in find_cmd_rcvr()
1660 if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd) in find_cmd_rcvr()
1661 && (rcvr->chans & (1 << chan))) in find_cmd_rcvr()
1674 list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link, in is_cmd_rcvr_exclusive()
1675 lockdep_is_held(&intf->cmd_rcvrs_mutex)) { in is_cmd_rcvr_exclusive()
1676 if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd) in is_cmd_rcvr_exclusive()
1677 && (rcvr->chans & chans)) in is_cmd_rcvr_exclusive()
1688 struct ipmi_smi *intf = user->intf; in ipmi_register_for_cmd()
1694 return -ENODEV; in ipmi_register_for_cmd()
1698 rv = -ENOMEM; in ipmi_register_for_cmd()
1701 rcvr->cmd = cmd; in ipmi_register_for_cmd()
1702 rcvr->netfn = netfn; in ipmi_register_for_cmd()
1703 rcvr->chans = chans; in ipmi_register_for_cmd()
1704 rcvr->user = user; in ipmi_register_for_cmd()
1706 mutex_lock(&intf->cmd_rcvrs_mutex); in ipmi_register_for_cmd()
1709 rv = -EBUSY; in ipmi_register_for_cmd()
1715 list_add_rcu(&rcvr->link, &intf->cmd_rcvrs); in ipmi_register_for_cmd()
1718 mutex_unlock(&intf->cmd_rcvrs_mutex); in ipmi_register_for_cmd()
1733 struct ipmi_smi *intf = user->intf; in ipmi_unregister_for_cmd()
1736 int i, rv = -ENOENT, index; in ipmi_unregister_for_cmd()
1740 return -ENODEV; in ipmi_unregister_for_cmd()
1742 mutex_lock(&intf->cmd_rcvrs_mutex); in ipmi_unregister_for_cmd()
1749 if (rcvr->user == user) { in ipmi_unregister_for_cmd()
1751 rcvr->chans &= ~chans; in ipmi_unregister_for_cmd()
1752 if (rcvr->chans == 0) { in ipmi_unregister_for_cmd()
1753 list_del_rcu(&rcvr->link); in ipmi_unregister_for_cmd()
1754 rcvr->next = rcvrs; in ipmi_unregister_for_cmd()
1759 mutex_unlock(&intf->cmd_rcvrs_mutex); in ipmi_unregister_for_cmd()
1765 rcvrs = rcvr->next; in ipmi_unregister_for_cmd()
1778 for (; size > 0; size--, data++) in ipmb_checksum()
1781 return -csum; in ipmb_checksum()
1796 /* Format the IPMB header data. */ in format_ipmb_msg()
1797 smi_msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2); in format_ipmb_msg()
1798 smi_msg->data[1] = IPMI_SEND_MSG_CMD; in format_ipmb_msg()
1799 smi_msg->data[2] = ipmb_addr->channel; in format_ipmb_msg()
1801 smi_msg->data[3] = 0; in format_ipmb_msg()
1802 smi_msg->data[i+3] = ipmb_addr->slave_addr; in format_ipmb_msg()
1803 smi_msg->data[i+4] = (msg->netfn << 2) | (ipmb_addr->lun & 0x3); in format_ipmb_msg()
1804 smi_msg->data[i+5] = ipmb_checksum(&smi_msg->data[i + 3], 2); in format_ipmb_msg()
1805 smi_msg->data[i+6] = source_address; in format_ipmb_msg()
1806 smi_msg->data[i+7] = (ipmb_seq << 2) | source_lun; in format_ipmb_msg()
1807 smi_msg->data[i+8] = msg->cmd; in format_ipmb_msg()
1810 if (msg->data_len > 0) in format_ipmb_msg()
1811 memcpy(&smi_msg->data[i + 9], msg->data, msg->data_len); in format_ipmb_msg()
1812 smi_msg->data_size = msg->data_len + 9; in format_ipmb_msg()
1815 smi_msg->data[i+smi_msg->data_size] in format_ipmb_msg()
1816 = ipmb_checksum(&smi_msg->data[i + 6], smi_msg->data_size - 6); in format_ipmb_msg()
1822 smi_msg->data_size += 1 + i; in format_ipmb_msg()
1824 smi_msg->msgid = msgid; in format_ipmb_msg()
1834 /* Format the IPMB header data. */ in format_lan_msg()
1835 smi_msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2); in format_lan_msg()
1836 smi_msg->data[1] = IPMI_SEND_MSG_CMD; in format_lan_msg()
1837 smi_msg->data[2] = lan_addr->channel; in format_lan_msg()
1838 smi_msg->data[3] = lan_addr->session_handle; in format_lan_msg()
1839 smi_msg->data[4] = lan_addr->remote_SWID; in format_lan_msg()
1840 smi_msg->data[5] = (msg->netfn << 2) | (lan_addr->lun & 0x3); in format_lan_msg()
1841 smi_msg->data[6] = ipmb_checksum(&smi_msg->data[4], 2); in format_lan_msg()
1842 smi_msg->data[7] = lan_addr->local_SWID; in format_lan_msg()
1843 smi_msg->data[8] = (ipmb_seq << 2) | source_lun; in format_lan_msg()
1844 smi_msg->data[9] = msg->cmd; in format_lan_msg()
1847 if (msg->data_len > 0) in format_lan_msg()
1848 memcpy(&smi_msg->data[10], msg->data, msg->data_len); in format_lan_msg()
1849 smi_msg->data_size = msg->data_len + 10; in format_lan_msg()
1852 smi_msg->data[smi_msg->data_size] in format_lan_msg()
1853 = ipmb_checksum(&smi_msg->data[7], smi_msg->data_size - 7); in format_lan_msg()
1859 smi_msg->data_size += 1; in format_lan_msg()
1861 smi_msg->msgid = msgid; in format_lan_msg()
1868 if (intf->curr_msg) { in smi_add_send_msg()
1870 list_add_tail(&smi_msg->link, &intf->hp_xmit_msgs); in smi_add_send_msg()
1872 list_add_tail(&smi_msg->link, &intf->xmit_msgs); in smi_add_send_msg()
1875 intf->curr_msg = smi_msg; in smi_add_send_msg()
1885 int run_to_completion = intf->run_to_completion; in smi_send()
1889 spin_lock_irqsave(&intf->xmit_msgs_lock, flags); in smi_send()
1893 spin_unlock_irqrestore(&intf->xmit_msgs_lock, flags); in smi_send()
1896 handlers->sender(intf->send_info, smi_msg); in smi_send()
1901 return (((msg->netfn == IPMI_NETFN_APP_REQUEST) in is_maintenance_mode_cmd()
1902 && ((msg->cmd == IPMI_COLD_RESET_CMD) in is_maintenance_mode_cmd()
1903 || (msg->cmd == IPMI_WARM_RESET_CMD))) in is_maintenance_mode_cmd()
1904 || (msg->netfn == IPMI_NETFN_FIRMWARE_REQUEST)); in is_maintenance_mode_cmd()
1918 if (msg->netfn & 1) in i_ipmi_req_sysintf()
1920 return -EINVAL; in i_ipmi_req_sysintf()
1923 if (smi_addr->lun > 3) { in i_ipmi_req_sysintf()
1925 return -EINVAL; in i_ipmi_req_sysintf()
1928 memcpy(&recv_msg->addr, smi_addr, sizeof(*smi_addr)); in i_ipmi_req_sysintf()
1930 if ((msg->netfn == IPMI_NETFN_APP_REQUEST) in i_ipmi_req_sysintf()
1931 && ((msg->cmd == IPMI_SEND_MSG_CMD) in i_ipmi_req_sysintf()
1932 || (msg->cmd == IPMI_GET_MSG_CMD) in i_ipmi_req_sysintf()
1933 || (msg->cmd == IPMI_READ_EVENT_MSG_BUFFER_CMD))) { in i_ipmi_req_sysintf()
1939 return -EINVAL; in i_ipmi_req_sysintf()
1945 spin_lock_irqsave(&intf->maintenance_mode_lock, flags); in i_ipmi_req_sysintf()
1946 intf->auto_maintenance_timeout in i_ipmi_req_sysintf()
1948 if (!intf->maintenance_mode in i_ipmi_req_sysintf()
1949 && !intf->maintenance_mode_enable) { in i_ipmi_req_sysintf()
1950 intf->maintenance_mode_enable = true; in i_ipmi_req_sysintf()
1953 spin_unlock_irqrestore(&intf->maintenance_mode_lock, in i_ipmi_req_sysintf()
1957 if (msg->data_len + 2 > IPMI_MAX_MSG_LENGTH) { in i_ipmi_req_sysintf()
1959 return -EMSGSIZE; in i_ipmi_req_sysintf()
1962 smi_msg->data[0] = (msg->netfn << 2) | (smi_addr->lun & 0x3); in i_ipmi_req_sysintf()
1963 smi_msg->data[1] = msg->cmd; in i_ipmi_req_sysintf()
1964 smi_msg->msgid = msgid; in i_ipmi_req_sysintf()
1965 smi_msg->user_data = recv_msg; in i_ipmi_req_sysintf()
1966 if (msg->data_len > 0) in i_ipmi_req_sysintf()
1967 memcpy(&smi_msg->data[2], msg->data, msg->data_len); in i_ipmi_req_sysintf()
1968 smi_msg->data_size = msg->data_len + 2; in i_ipmi_req_sysintf()
1992 if (addr->channel >= IPMI_MAX_CHANNELS) { in i_ipmi_req_ipmb()
1994 return -EINVAL; in i_ipmi_req_ipmb()
1997 chans = READ_ONCE(intf->channel_list)->c; in i_ipmi_req_ipmb()
1999 if (chans[addr->channel].medium != IPMI_CHANNEL_MEDIUM_IPMB) { in i_ipmi_req_ipmb()
2001 return -EINVAL; in i_ipmi_req_ipmb()
2004 if (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE) { in i_ipmi_req_ipmb()
2007 * message, but otherwise is the same as an IPMB in i_ipmi_req_ipmb()
2010 addr->addr_type = IPMI_IPMB_ADDR_TYPE; in i_ipmi_req_ipmb()
2019 if ((msg->data_len + 10 + broadcast) > IPMI_MAX_MSG_LENGTH) { in i_ipmi_req_ipmb()
2021 return -EMSGSIZE; in i_ipmi_req_ipmb()
2025 if (ipmb_addr->lun > 3) { in i_ipmi_req_ipmb()
2027 return -EINVAL; in i_ipmi_req_ipmb()
2030 memcpy(&recv_msg->addr, ipmb_addr, sizeof(*ipmb_addr)); in i_ipmi_req_ipmb()
2032 if (recv_msg->msg.netfn & 0x1) { in i_ipmi_req_ipmb()
2046 smi_msg->user_data = recv_msg; in i_ipmi_req_ipmb()
2051 spin_lock_irqsave(&intf->seq_lock, flags); in i_ipmi_req_ipmb()
2054 intf->ipmb_maintenance_mode_timeout = in i_ipmi_req_ipmb()
2057 if (intf->ipmb_maintenance_mode_timeout && retry_time_ms == 0) in i_ipmi_req_ipmb()
2095 memcpy(recv_msg->msg_data, smi_msg->data, in i_ipmi_req_ipmb()
2096 smi_msg->data_size); in i_ipmi_req_ipmb()
2097 recv_msg->msg.data = recv_msg->msg_data; in i_ipmi_req_ipmb()
2098 recv_msg->msg.data_len = smi_msg->data_size; in i_ipmi_req_ipmb()
2109 spin_unlock_irqrestore(&intf->seq_lock, flags); in i_ipmi_req_ipmb()
2124 bool is_cmd = !(recv_msg->msg.netfn & 0x1); in i_ipmi_req_ipmb_direct()
2126 if (!(intf->handlers->flags & IPMI_SMI_CAN_HANDLE_IPMB_DIRECT)) in i_ipmi_req_ipmb_direct()
2127 return -EAFNOSUPPORT; in i_ipmi_req_ipmb_direct()
2130 if (!is_cmd && msg->data_len < 1) { in i_ipmi_req_ipmb_direct()
2132 return -EINVAL; in i_ipmi_req_ipmb_direct()
2135 if ((msg->data_len + 4) > IPMI_MAX_MSG_LENGTH) { in i_ipmi_req_ipmb_direct()
2137 return -EMSGSIZE; in i_ipmi_req_ipmb_direct()
2141 if (daddr->rq_lun > 3 || daddr->rs_lun > 3) { in i_ipmi_req_ipmb_direct()
2143 return -EINVAL; in i_ipmi_req_ipmb_direct()
2146 smi_msg->type = IPMI_SMI_MSG_TYPE_IPMB_DIRECT; in i_ipmi_req_ipmb_direct()
2147 smi_msg->msgid = msgid; in i_ipmi_req_ipmb_direct()
2150 smi_msg->data[0] = msg->netfn << 2 | daddr->rs_lun; in i_ipmi_req_ipmb_direct()
2151 smi_msg->data[2] = recv_msg->msgid << 2 | daddr->rq_lun; in i_ipmi_req_ipmb_direct()
2153 smi_msg->data[0] = msg->netfn << 2 | daddr->rq_lun; in i_ipmi_req_ipmb_direct()
2154 smi_msg->data[2] = recv_msg->msgid << 2 | daddr->rs_lun; in i_ipmi_req_ipmb_direct()
2156 smi_msg->data[1] = daddr->slave_addr; in i_ipmi_req_ipmb_direct()
2157 smi_msg->data[3] = msg->cmd; in i_ipmi_req_ipmb_direct()
2159 memcpy(smi_msg->data + 4, msg->data, msg->data_len); in i_ipmi_req_ipmb_direct()
2160 smi_msg->data_size = msg->data_len + 4; in i_ipmi_req_ipmb_direct()
2162 smi_msg->user_data = recv_msg; in i_ipmi_req_ipmb_direct()
2183 if (addr->channel >= IPMI_MAX_CHANNELS) { in i_ipmi_req_lan()
2185 return -EINVAL; in i_ipmi_req_lan()
2188 chans = READ_ONCE(intf->channel_list)->c; in i_ipmi_req_lan()
2190 if ((chans[addr->channel].medium in i_ipmi_req_lan()
2192 && (chans[addr->channel].medium in i_ipmi_req_lan()
2195 return -EINVAL; in i_ipmi_req_lan()
2199 if ((msg->data_len + 12) > IPMI_MAX_MSG_LENGTH) { in i_ipmi_req_lan()
2201 return -EMSGSIZE; in i_ipmi_req_lan()
2205 if (lan_addr->lun > 3) { in i_ipmi_req_lan()
2207 return -EINVAL; in i_ipmi_req_lan()
2210 memcpy(&recv_msg->addr, lan_addr, sizeof(*lan_addr)); in i_ipmi_req_lan()
2212 if (recv_msg->msg.netfn & 0x1) { in i_ipmi_req_lan()
2225 smi_msg->user_data = recv_msg; in i_ipmi_req_lan()
2230 spin_lock_irqsave(&intf->seq_lock, flags); in i_ipmi_req_lan()
2265 memcpy(recv_msg->msg_data, smi_msg->data, in i_ipmi_req_lan()
2266 smi_msg->data_size); in i_ipmi_req_lan()
2267 recv_msg->msg.data = recv_msg->msg_data; in i_ipmi_req_lan()
2268 recv_msg->msg.data_len = smi_msg->data_size; in i_ipmi_req_lan()
2279 spin_unlock_irqrestore(&intf->seq_lock, flags); in i_ipmi_req_lan()
2310 if (atomic_add_return(1, &user->nr_msgs) > max_msgs_per_user) { in i_ipmi_request()
2312 rv = -EBUSY; in i_ipmi_request()
2322 rv = -ENOMEM; in i_ipmi_request()
2326 recv_msg->user_msg_data = user_msg_data; in i_ipmi_request()
2335 rv = -ENOMEM; in i_ipmi_request()
2341 if (intf->in_shutdown) { in i_ipmi_request()
2342 rv = -ENODEV; in i_ipmi_request()
2346 recv_msg->user = user; in i_ipmi_request()
2349 kref_get(&user->refcount); in i_ipmi_request()
2350 recv_msg->msgid = msgid; in i_ipmi_request()
2355 recv_msg->msg = *msg; in i_ipmi_request()
2357 if (addr->addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) { in i_ipmi_request()
2373 rv = -EINVAL; in i_ipmi_request()
2381 dev_dbg(intf->si_dev, "Send: %*ph\n", in i_ipmi_request()
2382 smi_msg->data_size, smi_msg->data); in i_ipmi_request()
2384 smi_send(intf, intf->handlers, smi_msg, priority); in i_ipmi_request()
2390 atomic_dec(&user->nr_msgs); in i_ipmi_request()
2399 if (addr->channel >= IPMI_MAX_CHANNELS) in check_addr()
2400 return -EINVAL; in check_addr()
2401 addr->channel = array_index_nospec(addr->channel, IPMI_MAX_CHANNELS); in check_addr()
2402 *lun = intf->addrinfo[addr->channel].lun; in check_addr()
2403 *saddr = intf->addrinfo[addr->channel].address; in check_addr()
2420 return -EINVAL; in ipmi_request_settime()
2424 return -ENODEV; in ipmi_request_settime()
2426 rv = check_addr(user->intf, addr, &saddr, &lun); in ipmi_request_settime()
2429 user->intf, in ipmi_request_settime()
2459 return -EINVAL; in ipmi_request_supply_msgs()
2463 return -ENODEV; in ipmi_request_supply_msgs()
2465 rv = check_addr(user->intf, addr, &saddr, &lun); in ipmi_request_supply_msgs()
2468 user->intf, in ipmi_request_supply_msgs()
2478 -1, 0); in ipmi_request_supply_msgs()
2490 if ((msg->addr.addr_type != IPMI_SYSTEM_INTERFACE_ADDR_TYPE) in bmc_device_id_handler()
2491 || (msg->msg.netfn != IPMI_NETFN_APP_RESPONSE) in bmc_device_id_handler()
2492 || (msg->msg.cmd != IPMI_GET_DEVICE_ID_CMD)) { in bmc_device_id_handler()
2493 dev_warn(intf->si_dev, in bmc_device_id_handler()
2495 msg->addr.addr_type, msg->msg.netfn, msg->msg.cmd); in bmc_device_id_handler()
2499 if (msg->msg.data[0]) { in bmc_device_id_handler()
2500 dev_warn(intf->si_dev, "device id fetch failed: 0x%2.2x\n", in bmc_device_id_handler()
2501 msg->msg.data[0]); in bmc_device_id_handler()
2502 intf->bmc->dyn_id_set = 0; in bmc_device_id_handler()
2506 rv = ipmi_demangle_device_id(msg->msg.netfn, msg->msg.cmd, in bmc_device_id_handler()
2507 msg->msg.data, msg->msg.data_len, &intf->bmc->fetch_id); in bmc_device_id_handler()
2509 dev_warn(intf->si_dev, "device id demangle failed: %d\n", rv); in bmc_device_id_handler()
2511 intf->bmc->cc = msg->msg.data[0]; in bmc_device_id_handler()
2512 intf->bmc->dyn_id_set = 0; in bmc_device_id_handler()
2519 intf->bmc->dyn_id_set = 1; in bmc_device_id_handler()
2522 wake_up(&intf->waitq); in bmc_device_id_handler()
2549 intf->addrinfo[0].address, in send_get_device_id_cmd()
2550 intf->addrinfo[0].lun, in send_get_device_id_cmd()
2551 -1, 0); in send_get_device_id_cmd()
2559 intf->null_user_handler = bmc_device_id_handler; in __get_device_id()
2562 bmc->cc = 0; in __get_device_id()
2563 bmc->dyn_id_set = 2; in __get_device_id()
2569 wait_event(intf->waitq, bmc->dyn_id_set != 2); in __get_device_id()
2571 if (!bmc->dyn_id_set) { in __get_device_id()
2572 if (bmc->cc != IPMI_CC_NO_ERROR && in __get_device_id()
2575 dev_warn(intf->si_dev, in __get_device_id()
2577 bmc->cc); in __get_device_id()
2581 rv = -EIO; /* Something went wrong in the fetch. */ in __get_device_id()
2588 intf->null_user_handler = NULL; in __get_device_id()
2611 mutex_lock(&bmc->dyn_mutex); in __bmc_get_device_id()
2613 if (list_empty(&bmc->intfs)) { in __bmc_get_device_id()
2614 mutex_unlock(&bmc->dyn_mutex); in __bmc_get_device_id()
2615 return -ENOENT; in __bmc_get_device_id()
2617 intf = list_first_entry(&bmc->intfs, struct ipmi_smi, in __bmc_get_device_id()
2619 kref_get(&intf->refcount); in __bmc_get_device_id()
2620 mutex_unlock(&bmc->dyn_mutex); in __bmc_get_device_id()
2621 mutex_lock(&intf->bmc_reg_mutex); in __bmc_get_device_id()
2622 mutex_lock(&bmc->dyn_mutex); in __bmc_get_device_id()
2623 if (intf != list_first_entry(&bmc->intfs, struct ipmi_smi, in __bmc_get_device_id()
2625 mutex_unlock(&intf->bmc_reg_mutex); in __bmc_get_device_id()
2626 kref_put(&intf->refcount, intf_free); in __bmc_get_device_id()
2630 mutex_lock(&intf->bmc_reg_mutex); in __bmc_get_device_id()
2631 bmc = intf->bmc; in __bmc_get_device_id()
2632 mutex_lock(&bmc->dyn_mutex); in __bmc_get_device_id()
2633 kref_get(&intf->refcount); in __bmc_get_device_id()
2637 if (intf->in_bmc_register || in __bmc_get_device_id()
2638 (bmc->dyn_id_set && time_is_after_jiffies(bmc->dyn_id_expiry))) in __bmc_get_device_id()
2641 prev_guid_set = bmc->dyn_guid_set; in __bmc_get_device_id()
2644 prev_dyn_id_set = bmc->dyn_id_set; in __bmc_get_device_id()
2653 if (!intf->bmc_registered in __bmc_get_device_id()
2654 || (!prev_guid_set && bmc->dyn_guid_set) in __bmc_get_device_id()
2655 || (!prev_dyn_id_set && bmc->dyn_id_set) in __bmc_get_device_id()
2656 || (prev_guid_set && bmc->dyn_guid_set in __bmc_get_device_id()
2657 && !guid_equal(&bmc->guid, &bmc->fetch_guid)) in __bmc_get_device_id()
2658 || bmc->id.device_id != bmc->fetch_id.device_id in __bmc_get_device_id()
2659 || bmc->id.manufacturer_id != bmc->fetch_id.manufacturer_id in __bmc_get_device_id()
2660 || bmc->id.product_id != bmc->fetch_id.product_id) { in __bmc_get_device_id()
2661 struct ipmi_device_id id = bmc->fetch_id; in __bmc_get_device_id()
2662 int guid_set = bmc->dyn_guid_set; in __bmc_get_device_id()
2665 guid = bmc->fetch_guid; in __bmc_get_device_id()
2666 mutex_unlock(&bmc->dyn_mutex); in __bmc_get_device_id()
2670 intf->bmc->id = id; in __bmc_get_device_id()
2671 intf->bmc->dyn_guid_set = guid_set; in __bmc_get_device_id()
2672 intf->bmc->guid = guid; in __bmc_get_device_id()
2685 mutex_unlock(&intf->bmc_reg_mutex); in __bmc_get_device_id()
2686 mutex_lock(&bmc->dyn_mutex); in __bmc_get_device_id()
2691 bmc = intf->bmc; in __bmc_get_device_id()
2692 mutex_lock(&bmc->dyn_mutex); in __bmc_get_device_id()
2694 } else if (memcmp(&bmc->fetch_id, &bmc->id, sizeof(bmc->id))) in __bmc_get_device_id()
2696 __scan_channels(intf, &bmc->fetch_id); in __bmc_get_device_id()
2698 bmc->dyn_id_expiry = jiffies + IPMI_DYN_DEV_ID_EXPIRY; in __bmc_get_device_id()
2703 bmc->dyn_id_set = prev_dyn_id_set; in __bmc_get_device_id()
2706 bmc->id = bmc->fetch_id; in __bmc_get_device_id()
2707 if (bmc->dyn_guid_set) in __bmc_get_device_id()
2708 bmc->guid = bmc->fetch_guid; in __bmc_get_device_id()
2714 bmc->dyn_guid_set = prev_guid_set; in __bmc_get_device_id()
2719 *id = bmc->id; in __bmc_get_device_id()
2722 *guid_set = bmc->dyn_guid_set; in __bmc_get_device_id()
2724 if (guid && bmc->dyn_guid_set) in __bmc_get_device_id()
2725 *guid = bmc->guid; in __bmc_get_device_id()
2728 mutex_unlock(&bmc->dyn_mutex); in __bmc_get_device_id()
2729 mutex_unlock(&intf->bmc_reg_mutex); in __bmc_get_device_id()
2731 kref_put(&intf->refcount, intf_free); in __bmc_get_device_id()
2739 return __bmc_get_device_id(intf, bmc, id, guid_set, guid, -1); in bmc_get_device_id()
2905 return -ENOENT; in guid_show()
2930 umode_t mode = attr->mode; in bmc_dev_attr_is_visible()
2968 if (dev->type != &bmc_device_type) in __find_bmc_guid()
2972 rv = bmc->dyn_guid_set && guid_equal(&bmc->guid, guid); in __find_bmc_guid()
2974 rv = kref_get_unless_zero(&bmc->usecount); in __find_bmc_guid()
2979 * Returns with the bmc's usecount incremented, if it is non-NULL.
3006 if (dev->type != &bmc_device_type) in __find_bmc_prod_dev_id()
3010 rv = (bmc->id.product_id == cid->product_id in __find_bmc_prod_dev_id()
3011 && bmc->id.device_id == cid->device_id); in __find_bmc_prod_dev_id()
3013 rv = kref_get_unless_zero(&bmc->usecount); in __find_bmc_prod_dev_id()
3018 * Returns with the bmc's usecount incremented, if it is non-NULL.
3051 int id = bmc->pdev.id; /* Unregister overwrites id */ in cleanup_bmc_work()
3053 platform_device_unregister(&bmc->pdev); in cleanup_bmc_work()
3067 queue_work(remove_work_wq, &bmc->remove_work); in cleanup_bmc_device()
3071 * Must be called with intf->bmc_reg_mutex held.
3075 struct bmc_device *bmc = intf->bmc; in __ipmi_bmc_unregister()
3077 if (!intf->bmc_registered) in __ipmi_bmc_unregister()
3080 sysfs_remove_link(&intf->si_dev->kobj, "bmc"); in __ipmi_bmc_unregister()
3081 sysfs_remove_link(&bmc->pdev.dev.kobj, intf->my_dev_name); in __ipmi_bmc_unregister()
3082 kfree(intf->my_dev_name); in __ipmi_bmc_unregister()
3083 intf->my_dev_name = NULL; in __ipmi_bmc_unregister()
3085 mutex_lock(&bmc->dyn_mutex); in __ipmi_bmc_unregister()
3086 list_del(&intf->bmc_link); in __ipmi_bmc_unregister()
3087 mutex_unlock(&bmc->dyn_mutex); in __ipmi_bmc_unregister()
3088 intf->bmc = &intf->tmp_bmc; in __ipmi_bmc_unregister()
3089 kref_put(&bmc->usecount, cleanup_bmc_device); in __ipmi_bmc_unregister()
3090 intf->bmc_registered = false; in __ipmi_bmc_unregister()
3095 mutex_lock(&intf->bmc_reg_mutex); in ipmi_bmc_unregister()
3097 mutex_unlock(&intf->bmc_reg_mutex); in ipmi_bmc_unregister()
3101 * Must be called with intf->bmc_reg_mutex held.
3117 intf->in_bmc_register = true; in __ipmi_bmc_register()
3118 mutex_unlock(&intf->bmc_reg_mutex); in __ipmi_bmc_register()
3129 id->product_id, in __ipmi_bmc_register()
3130 id->device_id); in __ipmi_bmc_register()
3142 intf->bmc = old_bmc; in __ipmi_bmc_register()
3143 mutex_lock(&bmc->dyn_mutex); in __ipmi_bmc_register()
3144 list_add_tail(&intf->bmc_link, &bmc->intfs); in __ipmi_bmc_register()
3145 mutex_unlock(&bmc->dyn_mutex); in __ipmi_bmc_register()
3147 dev_info(intf->si_dev, in __ipmi_bmc_register()
3149 bmc->id.manufacturer_id, in __ipmi_bmc_register()
3150 bmc->id.product_id, in __ipmi_bmc_register()
3151 bmc->id.device_id); in __ipmi_bmc_register()
3155 rv = -ENOMEM; in __ipmi_bmc_register()
3158 INIT_LIST_HEAD(&bmc->intfs); in __ipmi_bmc_register()
3159 mutex_init(&bmc->dyn_mutex); in __ipmi_bmc_register()
3160 INIT_WORK(&bmc->remove_work, cleanup_bmc_work); in __ipmi_bmc_register()
3162 bmc->id = *id; in __ipmi_bmc_register()
3163 bmc->dyn_id_set = 1; in __ipmi_bmc_register()
3164 bmc->dyn_guid_set = guid_set; in __ipmi_bmc_register()
3165 bmc->guid = *guid; in __ipmi_bmc_register()
3166 bmc->dyn_id_expiry = jiffies + IPMI_DYN_DEV_ID_EXPIRY; in __ipmi_bmc_register()
3168 bmc->pdev.name = "ipmi_bmc"; in __ipmi_bmc_register()
3176 bmc->pdev.dev.driver = &ipmidriver.driver; in __ipmi_bmc_register()
3177 bmc->pdev.id = rv; in __ipmi_bmc_register()
3178 bmc->pdev.dev.release = release_bmc_device; in __ipmi_bmc_register()
3179 bmc->pdev.dev.type = &bmc_device_type; in __ipmi_bmc_register()
3180 kref_init(&bmc->usecount); in __ipmi_bmc_register()
3182 intf->bmc = bmc; in __ipmi_bmc_register()
3183 mutex_lock(&bmc->dyn_mutex); in __ipmi_bmc_register()
3184 list_add_tail(&intf->bmc_link, &bmc->intfs); in __ipmi_bmc_register()
3185 mutex_unlock(&bmc->dyn_mutex); in __ipmi_bmc_register()
3187 rv = platform_device_register(&bmc->pdev); in __ipmi_bmc_register()
3189 dev_err(intf->si_dev, in __ipmi_bmc_register()
3195 dev_info(intf->si_dev, in __ipmi_bmc_register()
3197 bmc->id.manufacturer_id, in __ipmi_bmc_register()
3198 bmc->id.product_id, in __ipmi_bmc_register()
3199 bmc->id.device_id); in __ipmi_bmc_register()
3206 rv = sysfs_create_link(&intf->si_dev->kobj, &bmc->pdev.dev.kobj, "bmc"); in __ipmi_bmc_register()
3208 dev_err(intf->si_dev, "Unable to create bmc symlink: %d\n", rv); in __ipmi_bmc_register()
3212 if (intf_num == -1) in __ipmi_bmc_register()
3213 intf_num = intf->intf_num; in __ipmi_bmc_register()
3214 intf->my_dev_name = kasprintf(GFP_KERNEL, "ipmi%d", intf_num); in __ipmi_bmc_register()
3215 if (!intf->my_dev_name) { in __ipmi_bmc_register()
3216 rv = -ENOMEM; in __ipmi_bmc_register()
3217 dev_err(intf->si_dev, "Unable to allocate link from BMC: %d\n", in __ipmi_bmc_register()
3222 rv = sysfs_create_link(&bmc->pdev.dev.kobj, &intf->si_dev->kobj, in __ipmi_bmc_register()
3223 intf->my_dev_name); in __ipmi_bmc_register()
3225 dev_err(intf->si_dev, "Unable to create symlink to bmc: %d\n", in __ipmi_bmc_register()
3230 intf->bmc_registered = true; in __ipmi_bmc_register()
3234 mutex_lock(&intf->bmc_reg_mutex); in __ipmi_bmc_register()
3235 intf->in_bmc_register = false; in __ipmi_bmc_register()
3240 kfree(intf->my_dev_name); in __ipmi_bmc_register()
3241 intf->my_dev_name = NULL; in __ipmi_bmc_register()
3244 sysfs_remove_link(&intf->si_dev->kobj, "bmc"); in __ipmi_bmc_register()
3247 mutex_lock(&bmc->dyn_mutex); in __ipmi_bmc_register()
3248 list_del(&intf->bmc_link); in __ipmi_bmc_register()
3249 mutex_unlock(&bmc->dyn_mutex); in __ipmi_bmc_register()
3250 intf->bmc = &intf->tmp_bmc; in __ipmi_bmc_register()
3251 kref_put(&bmc->usecount, cleanup_bmc_device); in __ipmi_bmc_register()
3255 mutex_lock(&bmc->dyn_mutex); in __ipmi_bmc_register()
3256 list_del(&intf->bmc_link); in __ipmi_bmc_register()
3257 mutex_unlock(&bmc->dyn_mutex); in __ipmi_bmc_register()
3258 intf->bmc = &intf->tmp_bmc; in __ipmi_bmc_register()
3259 put_device(&bmc->pdev.dev); in __ipmi_bmc_register()
3286 intf->addrinfo[0].address, in send_guid_cmd()
3287 intf->addrinfo[0].lun, in send_guid_cmd()
3288 -1, 0); in send_guid_cmd()
3293 struct bmc_device *bmc = intf->bmc; in guid_handler()
3295 if ((msg->addr.addr_type != IPMI_SYSTEM_INTERFACE_ADDR_TYPE) in guid_handler()
3296 || (msg->msg.netfn != IPMI_NETFN_APP_RESPONSE) in guid_handler()
3297 || (msg->msg.cmd != IPMI_GET_DEVICE_GUID_CMD)) in guid_handler()
3301 if (msg->msg.data[0] != 0) { in guid_handler()
3303 bmc->dyn_guid_set = 0; in guid_handler()
3307 if (msg->msg.data_len < UUID_SIZE + 1) { in guid_handler()
3308 bmc->dyn_guid_set = 0; in guid_handler()
3309 dev_warn(intf->si_dev, in guid_handler()
3311 msg->msg.data_len, UUID_SIZE + 1); in guid_handler()
3315 import_guid(&bmc->fetch_guid, msg->msg.data + 1); in guid_handler()
3321 bmc->dyn_guid_set = 1; in guid_handler()
3323 wake_up(&intf->waitq); in guid_handler()
3329 struct bmc_device *bmc = intf->bmc; in __get_guid()
3331 bmc->dyn_guid_set = 2; in __get_guid()
3332 intf->null_user_handler = guid_handler; in __get_guid()
3336 bmc->dyn_guid_set = 0; in __get_guid()
3338 wait_event(intf->waitq, bmc->dyn_guid_set != 2); in __get_guid()
3343 intf->null_user_handler = NULL; in __get_guid()
3371 intf->addrinfo[0].address, in send_channel_info_cmd()
3372 intf->addrinfo[0].lun, in send_channel_info_cmd()
3373 -1, 0); in send_channel_info_cmd()
3381 unsigned int set = intf->curr_working_cset; in channel_handler()
3384 if ((msg->addr.addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) in channel_handler()
3385 && (msg->msg.netfn == IPMI_NETFN_APP_RESPONSE) in channel_handler()
3386 && (msg->msg.cmd == IPMI_GET_CHANNEL_INFO_CMD)) { in channel_handler()
3388 if (msg->msg.data[0] != 0) { in channel_handler()
3390 if (msg->msg.data[0] == IPMI_INVALID_COMMAND_ERR) { in channel_handler()
3394 * assume it has one IPMB at channel in channel_handler()
3397 intf->wchannels[set].c[0].medium in channel_handler()
3399 intf->wchannels[set].c[0].protocol in channel_handler()
3402 intf->channel_list = intf->wchannels + set; in channel_handler()
3403 intf->channels_ready = true; in channel_handler()
3404 wake_up(&intf->waitq); in channel_handler()
3409 if (msg->msg.data_len < 4) { in channel_handler()
3413 ch = intf->curr_channel; in channel_handler()
3414 chans = intf->wchannels[set].c; in channel_handler()
3415 chans[ch].medium = msg->msg.data[2] & 0x7f; in channel_handler()
3416 chans[ch].protocol = msg->msg.data[3] & 0x1f; in channel_handler()
3419 intf->curr_channel++; in channel_handler()
3420 if (intf->curr_channel >= IPMI_MAX_CHANNELS) { in channel_handler()
3421 intf->channel_list = intf->wchannels + set; in channel_handler()
3422 intf->channels_ready = true; in channel_handler()
3423 wake_up(&intf->waitq); in channel_handler()
3425 intf->channel_list = intf->wchannels + set; in channel_handler()
3426 intf->channels_ready = true; in channel_handler()
3427 rv = send_channel_info_cmd(intf, intf->curr_channel); in channel_handler()
3432 dev_warn(intf->si_dev, in channel_handler()
3434 intf->curr_channel, rv); in channel_handler()
3436 intf->channel_list = intf->wchannels + set; in channel_handler()
3437 intf->channels_ready = true; in channel_handler()
3438 wake_up(&intf->waitq); in channel_handler()
3446 * Must be holding intf->bmc_reg_mutex to call this.
3461 set = !intf->curr_working_cset; in __scan_channels()
3462 intf->curr_working_cset = set; in __scan_channels()
3463 memset(&intf->wchannels[set], 0, in __scan_channels()
3466 intf->null_user_handler = channel_handler; in __scan_channels()
3467 intf->curr_channel = 0; in __scan_channels()
3470 dev_warn(intf->si_dev, in __scan_channels()
3473 intf->null_user_handler = NULL; in __scan_channels()
3474 return -EIO; in __scan_channels()
3478 wait_event(intf->waitq, intf->channels_ready); in __scan_channels()
3479 intf->null_user_handler = NULL; in __scan_channels()
3481 unsigned int set = intf->curr_working_cset; in __scan_channels()
3483 /* Assume a single IPMB channel at zero. */ in __scan_channels()
3484 intf->wchannels[set].c[0].medium = IPMI_CHANNEL_MEDIUM_IPMB; in __scan_channels()
3485 intf->wchannels[set].c[0].protocol = IPMI_CHANNEL_PROTOCOL_IPMB; in __scan_channels()
3486 intf->channel_list = intf->wchannels + set; in __scan_channels()
3487 intf->channels_ready = true; in __scan_channels()
3495 if (intf->handlers->poll) in ipmi_poll()
3496 intf->handlers->poll(intf->send_info); in ipmi_poll()
3503 ipmi_poll(user->intf); in ipmi_poll_interface()
3514 return sysfs_emit(buf, "%d\n", atomic_read(&intf->nr_users)); in nr_users_show()
3528 index = srcu_read_lock(&intf->users_srcu); in nr_msgs_show()
3529 list_for_each_entry_rcu(user, &intf->users, link) in nr_msgs_show()
3530 count += atomic_read(&user->nr_msgs); in nr_msgs_show()
3531 srcu_read_unlock(&intf->users_srcu, index); in nr_msgs_show()
3542 if (!intf->in_shutdown) in redo_bmc_reg()
3545 kref_put(&intf->refcount, intf_free); in redo_bmc_reg()
3570 return -ENOMEM; in ipmi_add_smi()
3572 rv = init_srcu_struct(&intf->users_srcu); in ipmi_add_smi()
3578 intf->owner = owner; in ipmi_add_smi()
3579 intf->bmc = &intf->tmp_bmc; in ipmi_add_smi()
3580 INIT_LIST_HEAD(&intf->bmc->intfs); in ipmi_add_smi()
3581 mutex_init(&intf->bmc->dyn_mutex); in ipmi_add_smi()
3582 INIT_LIST_HEAD(&intf->bmc_link); in ipmi_add_smi()
3583 mutex_init(&intf->bmc_reg_mutex); in ipmi_add_smi()
3584 intf->intf_num = -1; /* Mark it invalid for now. */ in ipmi_add_smi()
3585 kref_init(&intf->refcount); in ipmi_add_smi()
3586 INIT_WORK(&intf->bmc_reg_work, redo_bmc_reg); in ipmi_add_smi()
3587 intf->si_dev = si_dev; in ipmi_add_smi()
3589 intf->addrinfo[j].address = IPMI_BMC_SLAVE_ADDR; in ipmi_add_smi()
3590 intf->addrinfo[j].lun = 2; in ipmi_add_smi()
3593 intf->addrinfo[0].address = slave_addr; in ipmi_add_smi()
3594 INIT_LIST_HEAD(&intf->users); in ipmi_add_smi()
3595 atomic_set(&intf->nr_users, 0); in ipmi_add_smi()
3596 intf->handlers = handlers; in ipmi_add_smi()
3597 intf->send_info = send_info; in ipmi_add_smi()
3598 spin_lock_init(&intf->seq_lock); in ipmi_add_smi()
3600 intf->seq_table[j].inuse = 0; in ipmi_add_smi()
3601 intf->seq_table[j].seqid = 0; in ipmi_add_smi()
3603 intf->curr_seq = 0; in ipmi_add_smi()
3604 spin_lock_init(&intf->waiting_rcv_msgs_lock); in ipmi_add_smi()
3605 INIT_LIST_HEAD(&intf->waiting_rcv_msgs); in ipmi_add_smi()
3606 INIT_WORK(&intf->recv_work, smi_recv_work); in ipmi_add_smi()
3607 atomic_set(&intf->watchdog_pretimeouts_to_deliver, 0); in ipmi_add_smi()
3608 spin_lock_init(&intf->xmit_msgs_lock); in ipmi_add_smi()
3609 INIT_LIST_HEAD(&intf->xmit_msgs); in ipmi_add_smi()
3610 INIT_LIST_HEAD(&intf->hp_xmit_msgs); in ipmi_add_smi()
3611 spin_lock_init(&intf->events_lock); in ipmi_add_smi()
3612 spin_lock_init(&intf->watch_lock); in ipmi_add_smi()
3613 atomic_set(&intf->event_waiters, 0); in ipmi_add_smi()
3614 intf->ticks_to_req_ev = IPMI_REQUEST_EV_TIME; in ipmi_add_smi()
3615 INIT_LIST_HEAD(&intf->waiting_events); in ipmi_add_smi()
3616 intf->waiting_events_count = 0; in ipmi_add_smi()
3617 mutex_init(&intf->cmd_rcvrs_mutex); in ipmi_add_smi()
3618 spin_lock_init(&intf->maintenance_mode_lock); in ipmi_add_smi()
3619 INIT_LIST_HEAD(&intf->cmd_rcvrs); in ipmi_add_smi()
3620 init_waitqueue_head(&intf->waitq); in ipmi_add_smi()
3622 atomic_set(&intf->stats[i], 0); in ipmi_add_smi()
3630 if (tintf->intf_num != i) { in ipmi_add_smi()
3631 link = &tintf->link; in ipmi_add_smi()
3638 list_add_rcu(&intf->link, &ipmi_interfaces); in ipmi_add_smi()
3640 list_add_tail_rcu(&intf->link, link); in ipmi_add_smi()
3642 rv = handlers->start_processing(send_info, intf); in ipmi_add_smi()
3652 mutex_lock(&intf->bmc_reg_mutex); in ipmi_add_smi()
3654 mutex_unlock(&intf->bmc_reg_mutex); in ipmi_add_smi()
3658 intf->nr_users_devattr = dev_attr_nr_users; in ipmi_add_smi()
3659 sysfs_attr_init(&intf->nr_users_devattr.attr); in ipmi_add_smi()
3660 rv = device_create_file(intf->si_dev, &intf->nr_users_devattr); in ipmi_add_smi()
3664 intf->nr_msgs_devattr = dev_attr_nr_msgs; in ipmi_add_smi()
3665 sysfs_attr_init(&intf->nr_msgs_devattr.attr); in ipmi_add_smi()
3666 rv = device_create_file(intf->si_dev, &intf->nr_msgs_devattr); in ipmi_add_smi()
3668 device_remove_file(intf->si_dev, &intf->nr_users_devattr); in ipmi_add_smi()
3678 intf->intf_num = i; in ipmi_add_smi()
3682 call_smi_watchers(i, intf->si_dev); in ipmi_add_smi()
3689 if (intf->handlers->shutdown) in ipmi_add_smi()
3690 intf->handlers->shutdown(intf->send_info); in ipmi_add_smi()
3692 list_del_rcu(&intf->link); in ipmi_add_smi()
3695 cleanup_srcu_struct(&intf->users_srcu); in ipmi_add_smi()
3696 kref_put(&intf->refcount, intf_free); in ipmi_add_smi()
3707 msg->rsp[0] = msg->data[0] | 4; in deliver_smi_err_response()
3708 msg->rsp[1] = msg->data[1]; in deliver_smi_err_response()
3709 msg->rsp[2] = err; in deliver_smi_err_response()
3710 msg->rsp_size = 3; in deliver_smi_err_response()
3728 list_splice_tail(&intf->hp_xmit_msgs, &tmplist); in cleanup_smi_msgs()
3729 list_splice_tail(&intf->xmit_msgs, &tmplist); in cleanup_smi_msgs()
3732 while (intf->curr_msg && !list_empty(&intf->waiting_rcv_msgs)) { in cleanup_smi_msgs()
3751 ent = &intf->seq_table[i]; in cleanup_smi_msgs()
3752 if (!ent->inuse) in cleanup_smi_msgs()
3754 deliver_err_response(intf, ent->recv_msg, IPMI_ERR_UNSPECIFIED); in cleanup_smi_msgs()
3765 intf_num = intf->intf_num; in ipmi_unregister_smi()
3767 intf->intf_num = -1; in ipmi_unregister_smi()
3768 intf->in_shutdown = true; in ipmi_unregister_smi()
3769 list_del_rcu(&intf->link); in ipmi_unregister_smi()
3775 device_remove_file(intf->si_dev, &intf->nr_msgs_devattr); in ipmi_unregister_smi()
3776 device_remove_file(intf->si_dev, &intf->nr_users_devattr); in ipmi_unregister_smi()
3784 w->smi_gone(intf_num); in ipmi_unregister_smi()
3787 index = srcu_read_lock(&intf->users_srcu); in ipmi_unregister_smi()
3788 while (!list_empty(&intf->users)) { in ipmi_unregister_smi()
3790 container_of(list_next_rcu(&intf->users), in ipmi_unregister_smi()
3795 srcu_read_unlock(&intf->users_srcu, index); in ipmi_unregister_smi()
3797 if (intf->handlers->shutdown) in ipmi_unregister_smi()
3798 intf->handlers->shutdown(intf->send_info); in ipmi_unregister_smi()
3804 cleanup_srcu_struct(&intf->users_srcu); in ipmi_unregister_smi()
3805 kref_put(&intf->refcount, intf_free); in ipmi_unregister_smi()
3819 if (msg->rsp_size < 11) { in handle_ipmb_get_msg_rsp()
3825 if (msg->rsp[2] != 0) { in handle_ipmb_get_msg_rsp()
3831 ipmb_addr.slave_addr = msg->rsp[6]; in handle_ipmb_get_msg_rsp()
3832 ipmb_addr.channel = msg->rsp[3] & 0x0f; in handle_ipmb_get_msg_rsp()
3833 ipmb_addr.lun = msg->rsp[7] & 3; in handle_ipmb_get_msg_rsp()
3840 msg->rsp[7] >> 2, in handle_ipmb_get_msg_rsp()
3841 msg->rsp[3] & 0x0f, in handle_ipmb_get_msg_rsp()
3842 msg->rsp[8], in handle_ipmb_get_msg_rsp()
3843 (msg->rsp[4] >> 2) & (~1), in handle_ipmb_get_msg_rsp()
3854 memcpy(recv_msg->msg_data, &msg->rsp[9], msg->rsp_size - 9); in handle_ipmb_get_msg_rsp()
3860 recv_msg->msg.netfn = msg->rsp[4] >> 2; in handle_ipmb_get_msg_rsp()
3861 recv_msg->msg.data = recv_msg->msg_data; in handle_ipmb_get_msg_rsp()
3862 recv_msg->msg.data_len = msg->rsp_size - 10; in handle_ipmb_get_msg_rsp()
3863 recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE; in handle_ipmb_get_msg_rsp()
3884 if (msg->rsp_size < 10) { in handle_ipmb_get_msg_cmd()
3890 if (msg->rsp[2] != 0) { in handle_ipmb_get_msg_cmd()
3895 netfn = msg->rsp[4] >> 2; in handle_ipmb_get_msg_cmd()
3896 cmd = msg->rsp[8]; in handle_ipmb_get_msg_cmd()
3897 chan = msg->rsp[3] & 0xf; in handle_ipmb_get_msg_cmd()
3902 user = rcvr->user; in handle_ipmb_get_msg_cmd()
3903 kref_get(&user->refcount); in handle_ipmb_get_msg_cmd()
3912 msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2); in handle_ipmb_get_msg_cmd()
3913 msg->data[1] = IPMI_SEND_MSG_CMD; in handle_ipmb_get_msg_cmd()
3914 msg->data[2] = msg->rsp[3]; in handle_ipmb_get_msg_cmd()
3915 msg->data[3] = msg->rsp[6]; in handle_ipmb_get_msg_cmd()
3916 msg->data[4] = ((netfn + 1) << 2) | (msg->rsp[7] & 0x3); in handle_ipmb_get_msg_cmd()
3917 msg->data[5] = ipmb_checksum(&msg->data[3], 2); in handle_ipmb_get_msg_cmd()
3918 msg->data[6] = intf->addrinfo[msg->rsp[3] & 0xf].address; in handle_ipmb_get_msg_cmd()
3920 msg->data[7] = (msg->rsp[7] & 0xfc) | (msg->rsp[4] & 0x3); in handle_ipmb_get_msg_cmd()
3921 msg->data[8] = msg->rsp[8]; /* cmd */ in handle_ipmb_get_msg_cmd()
3922 msg->data[9] = IPMI_INVALID_CMD_COMPLETION_CODE; in handle_ipmb_get_msg_cmd()
3923 msg->data[10] = ipmb_checksum(&msg->data[6], 4); in handle_ipmb_get_msg_cmd()
3924 msg->data_size = 11; in handle_ipmb_get_msg_cmd()
3926 dev_dbg(intf->si_dev, "Invalid command: %*ph\n", in handle_ipmb_get_msg_cmd()
3927 msg->data_size, msg->data); in handle_ipmb_get_msg_cmd()
3930 if (!intf->in_shutdown) { in handle_ipmb_get_msg_cmd()
3931 smi_send(intf, intf->handlers, msg, 0); in handle_ipmb_get_msg_cmd()
3937 rv = -1; in handle_ipmb_get_msg_cmd()
3949 kref_put(&user->refcount, free_user); 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->user = user; in handle_ipmb_get_msg_cmd()
3963 recv_msg->recv_type = IPMI_CMD_RECV_TYPE; in handle_ipmb_get_msg_cmd()
3964 recv_msg->msgid = msg->rsp[7] >> 2; in handle_ipmb_get_msg_cmd()
3965 recv_msg->msg.netfn = msg->rsp[4] >> 2; in handle_ipmb_get_msg_cmd()
3966 recv_msg->msg.cmd = msg->rsp[8]; in handle_ipmb_get_msg_cmd()
3967 recv_msg->msg.data = recv_msg->msg_data; in handle_ipmb_get_msg_cmd()
3973 recv_msg->msg.data_len = msg->rsp_size - 10; in handle_ipmb_get_msg_cmd()
3974 memcpy(recv_msg->msg_data, &msg->rsp[9], in handle_ipmb_get_msg_cmd()
3975 msg->rsp_size - 10); in handle_ipmb_get_msg_cmd()
3994 unsigned char netfn = msg->rsp[0] >> 2; in handle_ipmb_direct_rcv_cmd()
3995 unsigned char cmd = msg->rsp[3]; in handle_ipmb_direct_rcv_cmd()
4001 user = rcvr->user; in handle_ipmb_direct_rcv_cmd()
4002 kref_get(&user->refcount); in handle_ipmb_direct_rcv_cmd()
4011 msg->data[0] = (netfn + 1) << 2; in handle_ipmb_direct_rcv_cmd()
4012 msg->data[0] |= msg->rsp[2] & 0x3; /* rqLUN */ in handle_ipmb_direct_rcv_cmd()
4013 msg->data[1] = msg->rsp[1]; /* Addr */ in handle_ipmb_direct_rcv_cmd()
4014 msg->data[2] = msg->rsp[2] & ~0x3; /* rqSeq */ in handle_ipmb_direct_rcv_cmd()
4015 msg->data[2] |= msg->rsp[0] & 0x3; /* rsLUN */ in handle_ipmb_direct_rcv_cmd()
4016 msg->data[3] = cmd; in handle_ipmb_direct_rcv_cmd()
4017 msg->data[4] = IPMI_INVALID_CMD_COMPLETION_CODE; in handle_ipmb_direct_rcv_cmd()
4018 msg->data_size = 5; in handle_ipmb_direct_rcv_cmd()
4021 if (!intf->in_shutdown) { in handle_ipmb_direct_rcv_cmd()
4022 smi_send(intf, intf->handlers, msg, 0); in handle_ipmb_direct_rcv_cmd()
4028 rv = -1; in handle_ipmb_direct_rcv_cmd()
4040 kref_put(&user->refcount, free_user); in handle_ipmb_direct_rcv_cmd()
4043 daddr = (struct ipmi_ipmb_direct_addr *)&recv_msg->addr; in handle_ipmb_direct_rcv_cmd()
4044 daddr->addr_type = IPMI_IPMB_DIRECT_ADDR_TYPE; in handle_ipmb_direct_rcv_cmd()
4045 daddr->channel = 0; in handle_ipmb_direct_rcv_cmd()
4046 daddr->slave_addr = msg->rsp[1]; in handle_ipmb_direct_rcv_cmd()
4047 daddr->rs_lun = msg->rsp[0] & 3; in handle_ipmb_direct_rcv_cmd()
4048 daddr->rq_lun = msg->rsp[2] & 3; in handle_ipmb_direct_rcv_cmd()
4052 * from the IPMB header. in handle_ipmb_direct_rcv_cmd()
4054 recv_msg->user = user; in handle_ipmb_direct_rcv_cmd()
4055 recv_msg->recv_type = IPMI_CMD_RECV_TYPE; in handle_ipmb_direct_rcv_cmd()
4056 recv_msg->msgid = (msg->rsp[2] >> 2); in handle_ipmb_direct_rcv_cmd()
4057 recv_msg->msg.netfn = msg->rsp[0] >> 2; in handle_ipmb_direct_rcv_cmd()
4058 recv_msg->msg.cmd = msg->rsp[3]; in handle_ipmb_direct_rcv_cmd()
4059 recv_msg->msg.data = recv_msg->msg_data; in handle_ipmb_direct_rcv_cmd()
4061 recv_msg->msg.data_len = msg->rsp_size - 4; in handle_ipmb_direct_rcv_cmd()
4062 memcpy(recv_msg->msg_data, msg->rsp + 4, in handle_ipmb_direct_rcv_cmd()
4063 msg->rsp_size - 4); in handle_ipmb_direct_rcv_cmd()
4080 recv_msg = msg->user_data; in handle_ipmb_direct_rcv_rsp()
4082 dev_warn(intf->si_dev, in handle_ipmb_direct_rcv_rsp()
4083 …"IPMI direct message received with no owner. This could be because of a malformed message, or beca… in handle_ipmb_direct_rcv_rsp()
4087 recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE; in handle_ipmb_direct_rcv_rsp()
4088 recv_msg->msgid = msg->msgid; in handle_ipmb_direct_rcv_rsp()
4089 daddr = (struct ipmi_ipmb_direct_addr *) &recv_msg->addr; in handle_ipmb_direct_rcv_rsp()
4090 daddr->addr_type = IPMI_IPMB_DIRECT_ADDR_TYPE; in handle_ipmb_direct_rcv_rsp()
4091 daddr->channel = 0; in handle_ipmb_direct_rcv_rsp()
4092 daddr->slave_addr = msg->rsp[1]; in handle_ipmb_direct_rcv_rsp()
4093 daddr->rq_lun = msg->rsp[0] & 3; in handle_ipmb_direct_rcv_rsp()
4094 daddr->rs_lun = msg->rsp[2] & 3; in handle_ipmb_direct_rcv_rsp()
4095 recv_msg->msg.netfn = msg->rsp[0] >> 2; in handle_ipmb_direct_rcv_rsp()
4096 recv_msg->msg.cmd = msg->rsp[3]; in handle_ipmb_direct_rcv_rsp()
4097 memcpy(recv_msg->msg_data, &msg->rsp[4], msg->rsp_size - 4); in handle_ipmb_direct_rcv_rsp()
4098 recv_msg->msg.data = recv_msg->msg_data; in handle_ipmb_direct_rcv_rsp()
4099 recv_msg->msg.data_len = msg->rsp_size - 4; in handle_ipmb_direct_rcv_rsp()
4116 if (msg->rsp_size < 13) { in handle_lan_get_msg_rsp()
4122 if (msg->rsp[2] != 0) { in handle_lan_get_msg_rsp()
4128 lan_addr.session_handle = msg->rsp[4]; in handle_lan_get_msg_rsp()
4129 lan_addr.remote_SWID = msg->rsp[8]; in handle_lan_get_msg_rsp()
4130 lan_addr.local_SWID = msg->rsp[5]; in handle_lan_get_msg_rsp()
4131 lan_addr.channel = msg->rsp[3] & 0x0f; in handle_lan_get_msg_rsp()
4132 lan_addr.privilege = msg->rsp[3] >> 4; in handle_lan_get_msg_rsp()
4133 lan_addr.lun = msg->rsp[9] & 3; in handle_lan_get_msg_rsp()
4140 msg->rsp[9] >> 2, in handle_lan_get_msg_rsp()
4141 msg->rsp[3] & 0x0f, in handle_lan_get_msg_rsp()
4142 msg->rsp[10], in handle_lan_get_msg_rsp()
4143 (msg->rsp[6] >> 2) & (~1), in handle_lan_get_msg_rsp()
4154 memcpy(recv_msg->msg_data, &msg->rsp[11], msg->rsp_size - 11); in handle_lan_get_msg_rsp()
4160 recv_msg->msg.netfn = msg->rsp[6] >> 2; in handle_lan_get_msg_rsp()
4161 recv_msg->msg.data = recv_msg->msg_data; in handle_lan_get_msg_rsp()
4162 recv_msg->msg.data_len = msg->rsp_size - 12; in handle_lan_get_msg_rsp()
4163 recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE; in handle_lan_get_msg_rsp()
4184 if (msg->rsp_size < 12) { in handle_lan_get_msg_cmd()
4190 if (msg->rsp[2] != 0) { in handle_lan_get_msg_cmd()
4195 netfn = msg->rsp[6] >> 2; in handle_lan_get_msg_cmd()
4196 cmd = msg->rsp[10]; in handle_lan_get_msg_cmd()
4197 chan = msg->rsp[3] & 0xf; in handle_lan_get_msg_cmd()
4202 user = rcvr->user; in handle_lan_get_msg_cmd()
4203 kref_get(&user->refcount); in handle_lan_get_msg_cmd()
4225 kref_put(&user->refcount, free_user); in handle_lan_get_msg_cmd()
4228 lan_addr = (struct ipmi_lan_addr *) &recv_msg->addr; in handle_lan_get_msg_cmd()
4229 lan_addr->addr_type = IPMI_LAN_ADDR_TYPE; in handle_lan_get_msg_cmd()
4230 lan_addr->session_handle = msg->rsp[4]; in handle_lan_get_msg_cmd()
4231 lan_addr->remote_SWID = msg->rsp[8]; in handle_lan_get_msg_cmd()
4232 lan_addr->local_SWID = msg->rsp[5]; in handle_lan_get_msg_cmd()
4233 lan_addr->lun = msg->rsp[9] & 3; in handle_lan_get_msg_cmd()
4234 lan_addr->channel = msg->rsp[3] & 0xf; in handle_lan_get_msg_cmd()
4235 lan_addr->privilege = msg->rsp[3] >> 4; in handle_lan_get_msg_cmd()
4239 * from the IPMB header. in handle_lan_get_msg_cmd()
4241 recv_msg->user = user; 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()
4268 * the OEM. See IPMI 2.0 specification, Chapter 6 and
4287 if (msg->rsp_size < 4) { in handle_oem_get_msg_cmd()
4293 if (msg->rsp[2] != 0) { in handle_oem_get_msg_cmd()
4302 netfn = msg->rsp[0] >> 2; in handle_oem_get_msg_cmd()
4303 cmd = msg->rsp[1]; in handle_oem_get_msg_cmd()
4304 chan = msg->rsp[3] & 0xf; in handle_oem_get_msg_cmd()
4309 user = rcvr->user; in handle_oem_get_msg_cmd()
4310 kref_get(&user->refcount); in handle_oem_get_msg_cmd()
4334 kref_put(&user->refcount, free_user); in handle_oem_get_msg_cmd()
4343 &recv_msg->addr); in handle_oem_get_msg_cmd()
4344 smi_addr->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; in handle_oem_get_msg_cmd()
4345 smi_addr->channel = IPMI_BMC_CHANNEL; in handle_oem_get_msg_cmd()
4346 smi_addr->lun = msg->rsp[0] & 3; in handle_oem_get_msg_cmd()
4348 recv_msg->user = user; in handle_oem_get_msg_cmd()
4349 recv_msg->user_msg_data = NULL; in handle_oem_get_msg_cmd()
4350 recv_msg->recv_type = IPMI_OEM_RECV_TYPE; in handle_oem_get_msg_cmd()
4351 recv_msg->msg.netfn = msg->rsp[0] >> 2; in handle_oem_get_msg_cmd()
4352 recv_msg->msg.cmd = msg->rsp[1]; in handle_oem_get_msg_cmd()
4353 recv_msg->msg.data = recv_msg->msg_data; in handle_oem_get_msg_cmd()
4359 recv_msg->msg.data_len = msg->rsp_size - 4; in handle_oem_get_msg_cmd()
4360 memcpy(recv_msg->msg_data, &msg->rsp[4], in handle_oem_get_msg_cmd()
4361 msg->rsp_size - 4); in handle_oem_get_msg_cmd()
4377 recv_msg->msgid = 0; in copy_event_into_recv_msg()
4378 smi_addr = (struct ipmi_system_interface_addr *) &recv_msg->addr; in copy_event_into_recv_msg()
4379 smi_addr->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; in copy_event_into_recv_msg()
4380 smi_addr->channel = IPMI_BMC_CHANNEL; in copy_event_into_recv_msg()
4381 smi_addr->lun = msg->rsp[0] & 3; in copy_event_into_recv_msg()
4382 recv_msg->recv_type = IPMI_ASYNC_EVENT_RECV_TYPE; in copy_event_into_recv_msg()
4383 recv_msg->msg.netfn = msg->rsp[0] >> 2; in copy_event_into_recv_msg()
4384 recv_msg->msg.cmd = msg->rsp[1]; in copy_event_into_recv_msg()
4385 memcpy(recv_msg->msg_data, &msg->rsp[3], msg->rsp_size - 3); in copy_event_into_recv_msg()
4386 recv_msg->msg.data = recv_msg->msg_data; in copy_event_into_recv_msg()
4387 recv_msg->msg.data_len = msg->rsp_size - 3; in copy_event_into_recv_msg()
4399 if (msg->rsp_size < 19) { in handle_read_event_rsp()
4400 /* Message is too small to be an IPMB event. */ in handle_read_event_rsp()
4405 if (msg->rsp[2] != 0) { in handle_read_event_rsp()
4412 spin_lock_irqsave(&intf->events_lock, flags); in handle_read_event_rsp()
4420 index = srcu_read_lock(&intf->users_srcu); in handle_read_event_rsp()
4421 list_for_each_entry_rcu(user, &intf->users, link) { in handle_read_event_rsp()
4422 if (!user->gets_events) in handle_read_event_rsp()
4430 list_del(&recv_msg->link); in handle_read_event_rsp()
4445 recv_msg->user = user; in handle_read_event_rsp()
4446 kref_get(&user->refcount); in handle_read_event_rsp()
4447 list_add_tail(&recv_msg->link, &msgs); in handle_read_event_rsp()
4449 srcu_read_unlock(&intf->users_srcu, index); in handle_read_event_rsp()
4454 list_del(&recv_msg->link); in handle_read_event_rsp()
4457 } else if (intf->waiting_events_count < MAX_EVENTS_IN_QUEUE) { in handle_read_event_rsp()
4474 list_add_tail(&recv_msg->link, &intf->waiting_events); in handle_read_event_rsp()
4475 intf->waiting_events_count++; in handle_read_event_rsp()
4476 } else if (!intf->event_msg_printed) { in handle_read_event_rsp()
4481 dev_warn(intf->si_dev, in handle_read_event_rsp()
4483 intf->event_msg_printed = 1; in handle_read_event_rsp()
4487 spin_unlock_irqrestore(&intf->events_lock, flags); in handle_read_event_rsp()
4498 recv_msg = msg->user_data; in handle_bmc_rsp()
4500 dev_warn(intf->si_dev, in handle_bmc_rsp()
4501 …"IPMI SMI message received with no owner. This could be because of a malformed message, or because… in handle_bmc_rsp()
4505 recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE; in handle_bmc_rsp()
4506 recv_msg->msgid = msg->msgid; in handle_bmc_rsp()
4508 &recv_msg->addr); in handle_bmc_rsp()
4509 smi_addr->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; in handle_bmc_rsp()
4510 smi_addr->channel = IPMI_BMC_CHANNEL; in handle_bmc_rsp()
4511 smi_addr->lun = msg->rsp[0] & 3; in handle_bmc_rsp()
4512 recv_msg->msg.netfn = msg->rsp[0] >> 2; in handle_bmc_rsp()
4513 recv_msg->msg.cmd = msg->rsp[1]; in handle_bmc_rsp()
4514 memcpy(recv_msg->msg_data, &msg->rsp[2], msg->rsp_size - 2); in handle_bmc_rsp()
4515 recv_msg->msg.data = recv_msg->msg_data; in handle_bmc_rsp()
4516 recv_msg->msg.data_len = msg->rsp_size - 2; in handle_bmc_rsp()
4524 * 0 if the message should be freed, or -1 if the message should not
4533 bool is_cmd = !((msg->rsp[0] >> 2) & 1); in handle_one_recv_msg()
4535 dev_dbg(intf->si_dev, "Recv: %*ph\n", msg->rsp_size, msg->rsp); in handle_one_recv_msg()
4537 if (msg->rsp_size < 2) { in handle_one_recv_msg()
4539 dev_warn(intf->si_dev, in handle_one_recv_msg()
4541 (msg->data[0] >> 2) | 1, msg->data[1], msg->rsp_size); in handle_one_recv_msg()
4545 msg->rsp[0] = msg->data[0] | (1 << 2); in handle_one_recv_msg()
4546 msg->rsp[1] = msg->data[1]; in handle_one_recv_msg()
4547 msg->rsp[2] = IPMI_ERR_UNSPECIFIED; in handle_one_recv_msg()
4548 msg->rsp_size = 3; in handle_one_recv_msg()
4549 } else if (msg->type == IPMI_SMI_MSG_TYPE_IPMB_DIRECT) { in handle_one_recv_msg()
4551 if (is_cmd && (msg->rsp_size < 4)) { in handle_one_recv_msg()
4555 if (!is_cmd && (msg->rsp_size < 5)) { in handle_one_recv_msg()
4558 msg->rsp[0] = msg->data[0] & 0xfc; /* NetFN */ in handle_one_recv_msg()
4559 msg->rsp[0] |= (1 << 2); /* Make it a response */ in handle_one_recv_msg()
4560 msg->rsp[0] |= msg->data[2] & 3; /* rqLUN */ in handle_one_recv_msg()
4561 msg->rsp[1] = msg->data[1]; /* Addr */ in handle_one_recv_msg()
4562 msg->rsp[2] = msg->data[2] & 0xfc; /* rqSeq */ in handle_one_recv_msg()
4563 msg->rsp[2] |= msg->data[0] & 0x3; /* rsLUN */ in handle_one_recv_msg()
4564 msg->rsp[3] = msg->data[3]; /* Cmd */ in handle_one_recv_msg()
4565 msg->rsp[4] = IPMI_ERR_UNSPECIFIED; in handle_one_recv_msg()
4566 msg->rsp_size = 5; in handle_one_recv_msg()
4568 } else if ((msg->data_size >= 2) in handle_one_recv_msg()
4569 && (msg->data[0] == (IPMI_NETFN_APP_REQUEST << 2)) in handle_one_recv_msg()
4570 && (msg->data[1] == IPMI_SEND_MSG_CMD) in handle_one_recv_msg()
4571 && (msg->user_data == NULL)) { in handle_one_recv_msg()
4573 if (intf->in_shutdown) in handle_one_recv_msg()
4589 if ((msg->rsp_size >= 3) && (msg->rsp[2] != 0) in handle_one_recv_msg()
4590 && (msg->rsp[2] != IPMI_NODE_BUSY_ERR) in handle_one_recv_msg()
4591 && (msg->rsp[2] != IPMI_LOST_ARBITRATION_ERR) in handle_one_recv_msg()
4592 && (msg->rsp[2] != IPMI_BUS_ERR) in handle_one_recv_msg()
4593 && (msg->rsp[2] != IPMI_NAK_ON_WRITE_ERR)) { in handle_one_recv_msg()
4594 int ch = msg->rsp[3] & 0xf; in handle_one_recv_msg()
4599 chans = READ_ONCE(intf->channel_list)->c; in handle_one_recv_msg()
4605 intf_err_seq(intf, msg->msgid, msg->rsp[2]); in handle_one_recv_msg()
4608 intf_start_seq_timer(intf, msg->msgid); in handle_one_recv_msg()
4611 } else if (((msg->rsp[0] >> 2) != ((msg->data[0] >> 2) | 1)) in handle_one_recv_msg()
4612 || (msg->rsp[1] != msg->data[1])) { in handle_one_recv_msg()
4617 dev_warn(intf->si_dev, in handle_one_recv_msg()
4619 (msg->data[0] >> 2) | 1, msg->data[1], in handle_one_recv_msg()
4620 msg->rsp[0] >> 2, msg->rsp[1]); in handle_one_recv_msg()
4625 if (msg->type == IPMI_SMI_MSG_TYPE_IPMB_DIRECT) { in handle_one_recv_msg()
4626 if ((msg->data[0] >> 2) & 1) { in handle_one_recv_msg()
4629 cc = msg->rsp[4]; in handle_one_recv_msg()
4636 } else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2)) in handle_one_recv_msg()
4637 && (msg->rsp[1] == IPMI_SEND_MSG_CMD) in handle_one_recv_msg()
4638 && (msg->user_data != NULL)) { in handle_one_recv_msg()
4645 chan = msg->data[2] & 0x0f; in handle_one_recv_msg()
4649 cc = msg->rsp[2]; in handle_one_recv_msg()
4652 recv_msg = msg->user_data; in handle_one_recv_msg()
4658 recv_msg->recv_type = IPMI_RESPONSE_RESPONSE_TYPE; in handle_one_recv_msg()
4659 recv_msg->msg.data = recv_msg->msg_data; in handle_one_recv_msg()
4660 recv_msg->msg_data[0] = cc; in handle_one_recv_msg()
4661 recv_msg->msg.data_len = 1; in handle_one_recv_msg()
4663 } else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2)) in handle_one_recv_msg()
4664 && (msg->rsp[1] == IPMI_GET_MSG_CMD)) { in handle_one_recv_msg()
4668 chan = msg->rsp[3] & 0xf; in handle_one_recv_msg()
4681 if (!intf->channels_ready) { in handle_one_recv_msg()
4686 chans = READ_ONCE(intf->channel_list)->c; in handle_one_recv_msg()
4690 if (msg->rsp[4] & 0x04) { in handle_one_recv_msg()
4707 if (msg->rsp[6] & 0x04) { in handle_one_recv_msg()
4738 } else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2)) in handle_one_recv_msg()
4739 && (msg->rsp[1] == IPMI_READ_EVENT_MSG_BUFFER_CMD)) { in handle_one_recv_msg()
4759 int run_to_completion = intf->run_to_completion; in handle_new_recv_msgs()
4763 spin_lock_irqsave(&intf->waiting_rcv_msgs_lock, flags); in handle_new_recv_msgs()
4764 while (!list_empty(&intf->waiting_rcv_msgs)) { in handle_new_recv_msgs()
4765 smi_msg = list_entry(intf->waiting_rcv_msgs.next, in handle_new_recv_msgs()
4767 list_del(&smi_msg->link); in handle_new_recv_msgs()
4769 spin_unlock_irqrestore(&intf->waiting_rcv_msgs_lock, in handle_new_recv_msgs()
4773 spin_lock_irqsave(&intf->waiting_rcv_msgs_lock, flags); in handle_new_recv_msgs()
4782 list_add(&smi_msg->link, &intf->waiting_rcv_msgs); in handle_new_recv_msgs()
4792 spin_unlock_irqrestore(&intf->waiting_rcv_msgs_lock, flags); in handle_new_recv_msgs()
4795 * If the pretimout count is non-zero, decrement one from it and in handle_new_recv_msgs()
4798 if (atomic_add_unless(&intf->watchdog_pretimeouts_to_deliver, -1, 0)) { in handle_new_recv_msgs()
4802 index = srcu_read_lock(&intf->users_srcu); in handle_new_recv_msgs()
4803 list_for_each_entry_rcu(user, &intf->users, link) { in handle_new_recv_msgs()
4804 if (user->handler->ipmi_watchdog_pretimeout) in handle_new_recv_msgs()
4805 user->handler->ipmi_watchdog_pretimeout( in handle_new_recv_msgs()
4806 user->handler_data); in handle_new_recv_msgs()
4808 srcu_read_unlock(&intf->users_srcu, index); in handle_new_recv_msgs()
4814 unsigned long flags = 0; /* keep us warning-free. */ in smi_recv_work()
4816 int run_to_completion = intf->run_to_completion; in smi_recv_work()
4830 spin_lock_irqsave(&intf->xmit_msgs_lock, flags); in smi_recv_work()
4831 if (intf->curr_msg == NULL && !intf->in_shutdown) { in smi_recv_work()
4835 if (!list_empty(&intf->hp_xmit_msgs)) in smi_recv_work()
4836 entry = intf->hp_xmit_msgs.next; in smi_recv_work()
4837 else if (!list_empty(&intf->xmit_msgs)) in smi_recv_work()
4838 entry = intf->xmit_msgs.next; in smi_recv_work()
4843 intf->curr_msg = newmsg; in smi_recv_work()
4848 spin_unlock_irqrestore(&intf->xmit_msgs_lock, flags); in smi_recv_work()
4850 intf->handlers->sender(intf->send_info, newmsg); in smi_recv_work()
4861 unsigned long flags = 0; /* keep us warning-free. */ in ipmi_smi_msg_received()
4862 int run_to_completion = intf->run_to_completion; in ipmi_smi_msg_received()
4869 spin_lock_irqsave(&intf->waiting_rcv_msgs_lock, flags); in ipmi_smi_msg_received()
4870 list_add_tail(&msg->link, &intf->waiting_rcv_msgs); in ipmi_smi_msg_received()
4872 spin_unlock_irqrestore(&intf->waiting_rcv_msgs_lock, in ipmi_smi_msg_received()
4876 spin_lock_irqsave(&intf->xmit_msgs_lock, flags); in ipmi_smi_msg_received()
4881 if (msg == intf->curr_msg) in ipmi_smi_msg_received()
4882 intf->curr_msg = NULL; in ipmi_smi_msg_received()
4884 spin_unlock_irqrestore(&intf->xmit_msgs_lock, flags); in ipmi_smi_msg_received()
4887 smi_recv_work(&intf->recv_work); in ipmi_smi_msg_received()
4889 queue_work(system_bh_wq, &intf->recv_work); in ipmi_smi_msg_received()
4895 if (intf->in_shutdown) in ipmi_smi_watchdog_pretimeout()
4898 atomic_set(&intf->watchdog_pretimeouts_to_deliver, 1); in ipmi_smi_watchdog_pretimeout()
4899 queue_work(system_bh_wq, &intf->recv_work); in ipmi_smi_watchdog_pretimeout()
4915 memcpy(smi_msg->data, recv_msg->msg.data, recv_msg->msg.data_len); in smi_from_recv_msg()
4916 smi_msg->data_size = recv_msg->msg.data_len; in smi_from_recv_msg()
4917 smi_msg->msgid = STORE_SEQ_IN_MSGID(seq, seqid); in smi_from_recv_msg()
4919 dev_dbg(intf->si_dev, "Resend: %*ph\n", in smi_from_recv_msg()
4920 smi_msg->data_size, smi_msg->data); in smi_from_recv_msg()
4933 if (intf->in_shutdown) in check_msg_timeout()
4936 if (!ent->inuse) in check_msg_timeout()
4939 if (timeout_period < ent->timeout) { in check_msg_timeout()
4940 ent->timeout -= timeout_period; in check_msg_timeout()
4945 if (ent->retries_left == 0) { in check_msg_timeout()
4947 ent->inuse = 0; in check_msg_timeout()
4949 msg = ent->recv_msg; in check_msg_timeout()
4950 list_add_tail(&msg->link, timeouts); in check_msg_timeout()
4951 if (ent->broadcast) in check_msg_timeout()
4953 else if (is_lan_addr(&ent->recv_msg->addr)) in check_msg_timeout()
4967 ent->timeout = MAX_MSG_TIMEOUT; in check_msg_timeout()
4968 ent->retries_left--; in check_msg_timeout()
4969 smi_msg = smi_from_recv_msg(intf, ent->recv_msg, slot, in check_msg_timeout()
4970 ent->seqid); in check_msg_timeout()
4972 if (is_lan_addr(&ent->recv_msg->addr)) in check_msg_timeout()
4981 spin_unlock_irqrestore(&intf->seq_lock, *flags); in check_msg_timeout()
4990 if (intf->handlers) { in check_msg_timeout()
4991 if (is_lan_addr(&ent->recv_msg->addr)) in check_msg_timeout()
4998 smi_send(intf, intf->handlers, smi_msg, 0); in check_msg_timeout()
5002 spin_lock_irqsave(&intf->seq_lock, *flags); in check_msg_timeout()
5015 if (!intf->bmc_registered) { in ipmi_timeout_handler()
5016 kref_get(&intf->refcount); in ipmi_timeout_handler()
5017 if (!schedule_work(&intf->bmc_reg_work)) { in ipmi_timeout_handler()
5018 kref_put(&intf->refcount, intf_free); in ipmi_timeout_handler()
5029 spin_lock_irqsave(&intf->seq_lock, flags); in ipmi_timeout_handler()
5030 if (intf->ipmb_maintenance_mode_timeout) { in ipmi_timeout_handler()
5031 if (intf->ipmb_maintenance_mode_timeout <= timeout_period) in ipmi_timeout_handler()
5032 intf->ipmb_maintenance_mode_timeout = 0; in ipmi_timeout_handler()
5034 intf->ipmb_maintenance_mode_timeout -= timeout_period; in ipmi_timeout_handler()
5037 check_msg_timeout(intf, &intf->seq_table[i], in ipmi_timeout_handler()
5040 spin_unlock_irqrestore(&intf->seq_lock, flags); in ipmi_timeout_handler()
5053 if (intf->auto_maintenance_timeout > 0) { in ipmi_timeout_handler()
5054 spin_lock_irqsave(&intf->maintenance_mode_lock, flags); in ipmi_timeout_handler()
5055 if (intf->auto_maintenance_timeout > 0) { in ipmi_timeout_handler()
5056 intf->auto_maintenance_timeout in ipmi_timeout_handler()
5057 -= timeout_period; in ipmi_timeout_handler()
5058 if (!intf->maintenance_mode in ipmi_timeout_handler()
5059 && (intf->auto_maintenance_timeout <= 0)) { in ipmi_timeout_handler()
5060 intf->maintenance_mode_enable = false; in ipmi_timeout_handler()
5064 spin_unlock_irqrestore(&intf->maintenance_mode_lock, in ipmi_timeout_handler()
5068 queue_work(system_bh_wq, &intf->recv_work); in ipmi_timeout_handler()
5076 if (intf->maintenance_mode_enable) in ipmi_request_event()
5079 if (!intf->in_shutdown) in ipmi_request_event()
5080 intf->handlers->request_events(intf->send_info); in ipmi_request_event()
5098 if (atomic_read(&intf->event_waiters)) { in ipmi_timeout()
5099 intf->ticks_to_req_ev--; in ipmi_timeout()
5100 if (intf->ticks_to_req_ev == 0) { in ipmi_timeout()
5102 intf->ticks_to_req_ev = IPMI_REQUEST_EV_TIME; in ipmi_timeout()
5138 rv->done = free_smi_msg; in ipmi_alloc_smi_msg()
5139 rv->user_data = NULL; in ipmi_alloc_smi_msg()
5140 rv->type = IPMI_SMI_MSG_TYPE_NORMAL; in ipmi_alloc_smi_msg()
5161 rv->user = NULL; in ipmi_alloc_recv_msg()
5162 rv->done = free_recv_msg; in ipmi_alloc_recv_msg()
5170 if (msg->user && !oops_in_progress) in ipmi_free_recv_msg()
5171 kref_put(&msg->user->refcount, free_user); in ipmi_free_recv_msg()
5172 msg->done(msg); in ipmi_free_recv_msg()
5211 intf->addrinfo[0].address, in ipmi_panic_request_and_wait()
5212 intf->addrinfo[0].lun, in ipmi_panic_request_and_wait()
5216 else if (intf->handlers->flush_messages) in ipmi_panic_request_and_wait()
5217 intf->handlers->flush_messages(intf->send_info); in ipmi_panic_request_and_wait()
5226 if ((msg->addr.addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) in event_receiver_fetcher()
5227 && (msg->msg.netfn == IPMI_NETFN_SENSOR_EVENT_RESPONSE) in event_receiver_fetcher()
5228 && (msg->msg.cmd == IPMI_GET_EVENT_RECEIVER_CMD) in event_receiver_fetcher()
5229 && (msg->msg.data[0] == IPMI_CC_NO_ERROR)) { in event_receiver_fetcher()
5231 intf->event_receiver = msg->msg.data[1]; in event_receiver_fetcher()
5232 intf->event_receiver_lun = msg->msg.data[2] & 0x3; in event_receiver_fetcher()
5238 if ((msg->addr.addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) in device_id_fetcher()
5239 && (msg->msg.netfn == IPMI_NETFN_APP_RESPONSE) in device_id_fetcher()
5240 && (msg->msg.cmd == IPMI_GET_DEVICE_ID_CMD) in device_id_fetcher()
5241 && (msg->msg.data[0] == IPMI_CC_NO_ERROR)) { in device_id_fetcher()
5246 intf->local_sel_device = (msg->msg.data[6] >> 2) & 1; in device_id_fetcher()
5247 intf->local_event_generator = (msg->msg.data[6] >> 5) & 1; in device_id_fetcher()
5258 struct ipmi_ipmb_addr *ipmb; in send_panic_events() local
5265 si->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; in send_panic_events()
5266 si->channel = IPMI_BMC_CHANNEL; in send_panic_events()
5267 si->lun = 0; in send_panic_events()
5274 data[0] = 0x41; /* Kernel generator ID, IPMI table 5-4 */ in send_panic_events()
5275 data[1] = 0x03; /* This is for IPMI 1.0. */ in send_panic_events()
5276 data[2] = 0x20; /* OS Critical Stop, IPMI table 36-3 */ in send_panic_events()
5277 data[4] = 0x6f; /* Sensor specific, IPMI table 36-1 */ in send_panic_events()
5310 * OEM events. There's no way in IPMI to send OEM in send_panic_events()
5317 intf->local_sel_device = 0; in send_panic_events()
5318 intf->local_event_generator = 0; in send_panic_events()
5319 intf->event_receiver = 0; in send_panic_events()
5326 intf->null_user_handler = device_id_fetcher; in send_panic_events()
5329 if (intf->local_event_generator) { in send_panic_events()
5335 intf->null_user_handler = event_receiver_fetcher; in send_panic_events()
5338 intf->null_user_handler = NULL; in send_panic_events()
5342 * be 1 (it must be a valid IPMB address), it cannot in send_panic_events()
5345 if (((intf->event_receiver & 1) == 0) in send_panic_events()
5346 && (intf->event_receiver != 0) in send_panic_events()
5347 && (intf->event_receiver != intf->addrinfo[0].address)) { in send_panic_events()
5349 * The event receiver is valid, send an IPMB in send_panic_events()
5352 ipmb = (struct ipmi_ipmb_addr *) &addr; in send_panic_events()
5353 ipmb->addr_type = IPMI_IPMB_ADDR_TYPE; in send_panic_events()
5354 ipmb->channel = 0; /* FIXME - is this right? */ in send_panic_events()
5355 ipmb->lun = intf->event_receiver_lun; in send_panic_events()
5356 ipmb->slave_addr = intf->event_receiver; in send_panic_events()
5357 } else if (intf->local_sel_device) { in send_panic_events()
5364 si->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; in send_panic_events()
5365 si->channel = IPMI_BMC_CHANNEL; in send_panic_events()
5366 si->lun = 0; in send_panic_events()
5382 data[3] = intf->addrinfo[0].address; in send_panic_events()
5407 if (!intf->handlers || intf->intf_num == -1) in panic_event()
5411 if (!intf->handlers->poll) in panic_event()
5420 if (!spin_trylock(&intf->xmit_msgs_lock)) { in panic_event()
5421 INIT_LIST_HEAD(&intf->xmit_msgs); in panic_event()
5422 INIT_LIST_HEAD(&intf->hp_xmit_msgs); in panic_event()
5424 spin_unlock(&intf->xmit_msgs_lock); in panic_event()
5426 if (!spin_trylock(&intf->waiting_rcv_msgs_lock)) in panic_event()
5427 INIT_LIST_HEAD(&intf->waiting_rcv_msgs); in panic_event()
5429 spin_unlock(&intf->waiting_rcv_msgs_lock); in panic_event()
5431 intf->run_to_completion = 1; in panic_event()
5432 if (intf->handlers->set_run_to_completion) in panic_event()
5433 intf->handlers->set_run_to_completion(intf->send_info, in panic_event()
5436 list_for_each_entry_rcu(user, &intf->users, link) { in panic_event()
5437 if (user->handler->ipmi_panic_handler) in panic_event()
5438 user->handler->ipmi_panic_handler( in panic_event()
5439 user->handler_data); in panic_event()
5458 pr_err("Could not register IPMI driver\n"); in ipmi_register_driver()
5485 remove_work_wq = create_singlethread_workqueue("ipmi-msghandler-remove-wq"); in ipmi_init_msghandler()
5487 pr_err("unable to create ipmi-msghandler-remove-wq workqueue"); in ipmi_init_msghandler()
5488 rv = -ENOMEM; in ipmi_init_msghandler()
5563 MODULE_DESCRIPTION("Incoming and outgoing message routing for an IPMI interface.");