Fixes for IPMI
Add limits on the number of users and messages, plus sysfs interfaces to control those limits. Other than that, little cleanups, use dev_xxx() insted of pr_xxx(), create initializers for structures, fix a refcount leak, etc. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE/Q1c5nzg9ZpmiCaGYfOMkJGb/4EFAmKLc1sACgkQYfOMkJGb /4GeJw//SVxwQT1EVqSy70bFg3fxPKvXgTfKWPRwiWURDzBaj+JL9trS0OAbQIh9 OMUjOrxJcCu9sNtLJ8hRj9KZV0bLT1337HdQ2VXGRmhy4FPEg1YEoOT7Fwbfs3UM avy2doVgixMKH3OXwS3C8KGpRycHUjSNaSTFxdHgfJ7dC/3qwwctdI1lvbAPmuWd 68NY7sEl5XH1Y6Tp68MoV7iMKe+i7bKS/I9C00AhDKOZwF7UG2azAG5WcKVRXNxC QGHgMXGTdUfMTz7bjAo8y+zxREYhOv+IMUoAMHJc+7/KQFPbOOGBwbpj7Q4puMbU 1lyl+PAjl9MmBWQOwZSwvDBmma/2A138m5DB4/QUZxHKFCE9ESCpLgjk8lmhbxqU SUbU7H49GdoJt+V4THLVomEk8nS4MpMN2HfumIli2/OX5YSM2lY28jUPscATagyu 29w2Yr3lMGGuIdLL8vaTuWn0/GauUjYCWlKOdtHh74OcokpAFgnD3Sk2oOlvnr9Q d6qhJVdefwRA0LoQAjouYT4ZVtIu+2S7ql1ngShKdObmx+Z6qQgfLyKUncIqgGjv c31REL15llyFXCq9HfcNbzhFAJpVd77AOoPT+T6oZPQSGtTHxWmwzrmOM6rzJSde xkW9e88ZuIV4E4Gme2MuM1Gj5OY7Y0eaTiMPL6O7++4H9ZgGhto= =fVOh -----END PGP SIGNATURE----- Merge tag 'for-linus-4.19-1' of https://github.com/cminyard/linux-ipmi Pull IPMI update from Corey Minyard: "Add limits on the number of users and messages, plus sysfs interfaces to control those limits. Other than that, little cleanups, use dev_xxx() insted of pr_xxx(), create initializers for structures, fix a refcount leak, etc" * tag 'for-linus-4.19-1' of https://github.com/cminyard/linux-ipmi: ipmi:ipmb: Fix refcount leak in ipmi_ipmb_probe ipmi: remove unnecessary type castings ipmi: Make two logs unique ipmi:si: Convert pr_debug() to dev_dbg() ipmi: Convert pr_debug() to dev_dbg() ipmi: Fix pr_fmt to avoid compilation issues ipmi: Add an intializer for ipmi_recv_msg struct ipmi: Add an intializer for ipmi_smi_msg struct ipmi:ssif: Check for NULL msg when handling events and messages ipmi: use simple i2c probe function ipmi: Add a sysfs count of total outstanding messages for an interface ipmi: Add a sysfs interface to view the number of users ipmi: Limit the number of message a user may have outstanding ipmi: Add a limit on the number of users that may use IPMI
This commit is contained in:
commit
b1b5bf1640
|
@ -299,8 +299,7 @@ static int ipmb_slave_cb(struct i2c_client *client,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ipmb_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int ipmb_probe(struct i2c_client *client)
|
||||
{
|
||||
struct ipmb_dev *ipmb_dev;
|
||||
int ret;
|
||||
|
@ -369,7 +368,7 @@ static struct i2c_driver ipmb_driver = {
|
|||
.name = "ipmb-dev",
|
||||
.acpi_match_table = ACPI_PTR(acpi_ipmb_id),
|
||||
},
|
||||
.probe = ipmb_probe,
|
||||
.probe_new = ipmb_probe,
|
||||
.remove = ipmb_remove,
|
||||
.id_table = ipmb_id,
|
||||
};
|
||||
|
|
|
@ -442,8 +442,7 @@ static int ipmi_ipmb_remove(struct i2c_client *client)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ipmi_ipmb_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int ipmi_ipmb_probe(struct i2c_client *client)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
struct ipmi_ipmb_dev *iidev;
|
||||
|
@ -476,6 +475,7 @@ static int ipmi_ipmb_probe(struct i2c_client *client,
|
|||
slave_np = of_parse_phandle(dev->of_node, "slave-dev", 0);
|
||||
if (slave_np) {
|
||||
slave_adap = of_get_i2c_adapter_by_node(slave_np);
|
||||
of_node_put(slave_np);
|
||||
if (!slave_adap) {
|
||||
dev_notice(&client->dev,
|
||||
"Could not find slave adapter\n");
|
||||
|
@ -570,7 +570,7 @@ static struct i2c_driver ipmi_ipmb_driver = {
|
|||
.name = DEVICE_NAME,
|
||||
.of_match_table = of_ipmi_ipmb_match,
|
||||
},
|
||||
.probe = ipmi_ipmb_probe,
|
||||
.probe_new = ipmi_ipmb_probe,
|
||||
.remove = ipmi_ipmb_remove,
|
||||
.id_table = ipmi_ipmb_id,
|
||||
};
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
* Copyright 2002 MontaVista Software Inc.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "%s" fmt, "IPMI message handler: "
|
||||
#define dev_fmt pr_fmt
|
||||
#define pr_fmt(fmt) "IPMI message handler: " fmt
|
||||
#define dev_fmt(fmt) pr_fmt(fmt)
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/errno.h>
|
||||
|
@ -145,6 +145,18 @@ module_param(default_max_retries, uint, 0644);
|
|||
MODULE_PARM_DESC(default_max_retries,
|
||||
"The time (milliseconds) between retry sends in maintenance mode");
|
||||
|
||||
/* The default maximum number of users that may register. */
|
||||
static unsigned int max_users = 30;
|
||||
module_param(max_users, uint, 0644);
|
||||
MODULE_PARM_DESC(max_users,
|
||||
"The most users that may use the IPMI stack at one time.");
|
||||
|
||||
/* The default maximum number of message a user may have outstanding. */
|
||||
static unsigned int max_msgs_per_user = 100;
|
||||
module_param(max_msgs_per_user, uint, 0644);
|
||||
MODULE_PARM_DESC(max_msgs_per_user,
|
||||
"The most message a user may have outstanding.");
|
||||
|
||||
/* Call every ~1000 ms. */
|
||||
#define IPMI_TIMEOUT_TIME 1000
|
||||
|
||||
|
@ -187,6 +199,8 @@ struct ipmi_user {
|
|||
/* Does this interface receive IPMI events? */
|
||||
bool gets_events;
|
||||
|
||||
atomic_t nr_msgs;
|
||||
|
||||
/* Free must run in process context for RCU cleanup. */
|
||||
struct work_struct remove_work;
|
||||
};
|
||||
|
@ -442,6 +456,10 @@ struct ipmi_smi {
|
|||
*/
|
||||
struct list_head users;
|
||||
struct srcu_struct users_srcu;
|
||||
atomic_t nr_users;
|
||||
struct device_attribute nr_users_devattr;
|
||||
struct device_attribute nr_msgs_devattr;
|
||||
|
||||
|
||||
/* Used for wake ups at startup. */
|
||||
wait_queue_head_t waitq;
|
||||
|
@ -927,11 +945,13 @@ static int deliver_response(struct ipmi_smi *intf, struct ipmi_recv_msg *msg)
|
|||
* risk. At this moment, simply skip it in that case.
|
||||
*/
|
||||
ipmi_free_recv_msg(msg);
|
||||
atomic_dec(&msg->user->nr_msgs);
|
||||
} else {
|
||||
int index;
|
||||
struct ipmi_user *user = acquire_ipmi_user(msg->user, &index);
|
||||
|
||||
if (user) {
|
||||
atomic_dec(&user->nr_msgs);
|
||||
user->handler->ipmi_recv_hndl(msg, user->handler_data);
|
||||
release_ipmi_user(user, index);
|
||||
} else {
|
||||
|
@ -1230,6 +1250,11 @@ int ipmi_create_user(unsigned int if_num,
|
|||
goto out_kfree;
|
||||
|
||||
found:
|
||||
if (atomic_add_return(1, &intf->nr_users) > max_users) {
|
||||
rv = -EBUSY;
|
||||
goto out_kfree;
|
||||
}
|
||||
|
||||
INIT_WORK(&new_user->remove_work, free_user_work);
|
||||
|
||||
rv = init_srcu_struct(&new_user->release_barrier);
|
||||
|
@ -1244,6 +1269,7 @@ int ipmi_create_user(unsigned int if_num,
|
|||
/* Note that each existing user holds a refcount to the interface. */
|
||||
kref_get(&intf->refcount);
|
||||
|
||||
atomic_set(&new_user->nr_msgs, 0);
|
||||
kref_init(&new_user->refcount);
|
||||
new_user->handler = handler;
|
||||
new_user->handler_data = handler_data;
|
||||
|
@ -1262,6 +1288,7 @@ int ipmi_create_user(unsigned int if_num,
|
|||
return 0;
|
||||
|
||||
out_kfree:
|
||||
atomic_dec(&intf->nr_users);
|
||||
srcu_read_unlock(&ipmi_interfaces_srcu, index);
|
||||
vfree(new_user);
|
||||
return rv;
|
||||
|
@ -1336,6 +1363,7 @@ static void _ipmi_destroy_user(struct ipmi_user *user)
|
|||
/* Remove the user from the interface's sequence table. */
|
||||
spin_lock_irqsave(&intf->seq_lock, flags);
|
||||
list_del_rcu(&user->link);
|
||||
atomic_dec(&intf->nr_users);
|
||||
|
||||
for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) {
|
||||
if (intf->seq_table[i].inuse
|
||||
|
@ -2284,6 +2312,14 @@ static int i_ipmi_request(struct ipmi_user *user,
|
|||
struct ipmi_recv_msg *recv_msg;
|
||||
int rv = 0;
|
||||
|
||||
if (user) {
|
||||
if (atomic_add_return(1, &user->nr_msgs) > max_msgs_per_user) {
|
||||
/* Decrement will happen at the end of the routine. */
|
||||
rv = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (supplied_recv)
|
||||
recv_msg = supplied_recv;
|
||||
else {
|
||||
|
@ -2296,7 +2332,7 @@ static int i_ipmi_request(struct ipmi_user *user,
|
|||
recv_msg->user_msg_data = user_msg_data;
|
||||
|
||||
if (supplied_smi)
|
||||
smi_msg = (struct ipmi_smi_msg *) supplied_smi;
|
||||
smi_msg = supplied_smi;
|
||||
else {
|
||||
smi_msg = ipmi_alloc_smi_msg();
|
||||
if (smi_msg == NULL) {
|
||||
|
@ -2348,13 +2384,16 @@ out_err:
|
|||
ipmi_free_smi_msg(smi_msg);
|
||||
ipmi_free_recv_msg(recv_msg);
|
||||
} else {
|
||||
pr_debug("Send: %*ph\n", smi_msg->data_size, smi_msg->data);
|
||||
dev_dbg(intf->si_dev, "Send: %*ph\n",
|
||||
smi_msg->data_size, smi_msg->data);
|
||||
|
||||
smi_send(intf, intf->handlers, smi_msg, priority);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
out:
|
||||
if (rv && user)
|
||||
atomic_dec(&user->nr_msgs);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -3471,6 +3510,36 @@ void ipmi_poll_interface(struct ipmi_user *user)
|
|||
}
|
||||
EXPORT_SYMBOL(ipmi_poll_interface);
|
||||
|
||||
static ssize_t nr_users_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct ipmi_smi *intf = container_of(attr,
|
||||
struct ipmi_smi, nr_users_devattr);
|
||||
|
||||
return sysfs_emit(buf, "%d\n", atomic_read(&intf->nr_users));
|
||||
}
|
||||
static DEVICE_ATTR_RO(nr_users);
|
||||
|
||||
static ssize_t nr_msgs_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct ipmi_smi *intf = container_of(attr,
|
||||
struct ipmi_smi, nr_msgs_devattr);
|
||||
struct ipmi_user *user;
|
||||
int index;
|
||||
unsigned int count = 0;
|
||||
|
||||
index = srcu_read_lock(&intf->users_srcu);
|
||||
list_for_each_entry_rcu(user, &intf->users, link)
|
||||
count += atomic_read(&user->nr_msgs);
|
||||
srcu_read_unlock(&intf->users_srcu, index);
|
||||
|
||||
return sysfs_emit(buf, "%u\n", count);
|
||||
}
|
||||
static DEVICE_ATTR_RO(nr_msgs);
|
||||
|
||||
static void redo_bmc_reg(struct work_struct *work)
|
||||
{
|
||||
struct ipmi_smi *intf = container_of(work, struct ipmi_smi,
|
||||
|
@ -3529,6 +3598,7 @@ int ipmi_add_smi(struct module *owner,
|
|||
if (slave_addr != 0)
|
||||
intf->addrinfo[0].address = slave_addr;
|
||||
INIT_LIST_HEAD(&intf->users);
|
||||
atomic_set(&intf->nr_users, 0);
|
||||
intf->handlers = handlers;
|
||||
intf->send_info = send_info;
|
||||
spin_lock_init(&intf->seq_lock);
|
||||
|
@ -3592,6 +3662,20 @@ int ipmi_add_smi(struct module *owner,
|
|||
if (rv)
|
||||
goto out_err_bmc_reg;
|
||||
|
||||
intf->nr_users_devattr = dev_attr_nr_users;
|
||||
sysfs_attr_init(&intf->nr_users_devattr.attr);
|
||||
rv = device_create_file(intf->si_dev, &intf->nr_users_devattr);
|
||||
if (rv)
|
||||
goto out_err_bmc_reg;
|
||||
|
||||
intf->nr_msgs_devattr = dev_attr_nr_msgs;
|
||||
sysfs_attr_init(&intf->nr_msgs_devattr.attr);
|
||||
rv = device_create_file(intf->si_dev, &intf->nr_msgs_devattr);
|
||||
if (rv) {
|
||||
device_remove_file(intf->si_dev, &intf->nr_users_devattr);
|
||||
goto out_err_bmc_reg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Keep memory order straight for RCU readers. Make
|
||||
* sure everything else is committed to memory before
|
||||
|
@ -3691,6 +3775,9 @@ void ipmi_unregister_smi(struct ipmi_smi *intf)
|
|||
|
||||
/* At this point no users can be added to the interface. */
|
||||
|
||||
device_remove_file(intf->si_dev, &intf->nr_msgs_devattr);
|
||||
device_remove_file(intf->si_dev, &intf->nr_users_devattr);
|
||||
|
||||
/*
|
||||
* Call all the watcher interfaces to tell them that
|
||||
* an interface is going away.
|
||||
|
@ -3839,7 +3926,8 @@ static int handle_ipmb_get_msg_cmd(struct ipmi_smi *intf,
|
|||
msg->data[10] = ipmb_checksum(&msg->data[6], 4);
|
||||
msg->data_size = 11;
|
||||
|
||||
pr_debug("Invalid command: %*ph\n", msg->data_size, msg->data);
|
||||
dev_dbg(intf->si_dev, "Invalid command: %*ph\n",
|
||||
msg->data_size, msg->data);
|
||||
|
||||
rcu_read_lock();
|
||||
if (!intf->in_shutdown) {
|
||||
|
@ -3992,10 +4080,10 @@ static int handle_ipmb_direct_rcv_rsp(struct ipmi_smi *intf,
|
|||
struct ipmi_recv_msg *recv_msg;
|
||||
struct ipmi_ipmb_direct_addr *daddr;
|
||||
|
||||
recv_msg = (struct ipmi_recv_msg *) msg->user_data;
|
||||
recv_msg = msg->user_data;
|
||||
if (recv_msg == NULL) {
|
||||
dev_warn(intf->si_dev,
|
||||
"IPMI message received with no owner. This could be because of a malformed message, or because of a hardware error. Contact your hardware vendor for assistance.\n");
|
||||
"IPMI direct message received with no owner. This could be because of a malformed message, or because of a hardware error. Contact your hardware vendor for assistance.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -4410,10 +4498,10 @@ static int handle_bmc_rsp(struct ipmi_smi *intf,
|
|||
struct ipmi_recv_msg *recv_msg;
|
||||
struct ipmi_system_interface_addr *smi_addr;
|
||||
|
||||
recv_msg = (struct ipmi_recv_msg *) msg->user_data;
|
||||
recv_msg = msg->user_data;
|
||||
if (recv_msg == NULL) {
|
||||
dev_warn(intf->si_dev,
|
||||
"IPMI message received with no owner. This could be because of a malformed message, or because of a hardware error. Contact your hardware vendor for assistance.\n");
|
||||
"IPMI SMI message received with no owner. This could be because of a malformed message, or because of a hardware error. Contact your hardware vendor for assistance.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -4447,7 +4535,7 @@ static int handle_one_recv_msg(struct ipmi_smi *intf,
|
|||
unsigned char cc;
|
||||
bool is_cmd = !((msg->rsp[0] >> 2) & 1);
|
||||
|
||||
pr_debug("Recv: %*ph\n", msg->rsp_size, msg->rsp);
|
||||
dev_dbg(intf->si_dev, "Recv: %*ph\n", msg->rsp_size, msg->rsp);
|
||||
|
||||
if (msg->rsp_size < 2) {
|
||||
/* Message is too small to be correct. */
|
||||
|
@ -4831,7 +4919,8 @@ smi_from_recv_msg(struct ipmi_smi *intf, struct ipmi_recv_msg *recv_msg,
|
|||
smi_msg->data_size = recv_msg->msg.data_len;
|
||||
smi_msg->msgid = STORE_SEQ_IN_MSGID(seq, seqid);
|
||||
|
||||
pr_debug("Resend: %*ph\n", smi_msg->data_size, smi_msg->data);
|
||||
dev_dbg(intf->si_dev, "Resend: %*ph\n",
|
||||
smi_msg->data_size, smi_msg->data);
|
||||
|
||||
return smi_msg;
|
||||
}
|
||||
|
|
|
@ -94,12 +94,8 @@ static void dummy_recv_free(struct ipmi_recv_msg *msg)
|
|||
{
|
||||
atomic_dec(&dummy_count);
|
||||
}
|
||||
static struct ipmi_smi_msg halt_smi_msg = {
|
||||
.done = dummy_smi_free
|
||||
};
|
||||
static struct ipmi_recv_msg halt_recv_msg = {
|
||||
.done = dummy_recv_free
|
||||
};
|
||||
static struct ipmi_smi_msg halt_smi_msg = INIT_IPMI_SMI_MSG(dummy_smi_free);
|
||||
static struct ipmi_recv_msg halt_recv_msg = INIT_IPMI_RECV_MSG(dummy_recv_free);
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -264,15 +264,16 @@ static void cleanup_one_si(struct smi_info *smi_info);
|
|||
static void cleanup_ipmi_si(void);
|
||||
|
||||
#ifdef DEBUG_TIMING
|
||||
void debug_timestamp(char *msg)
|
||||
void debug_timestamp(struct smi_info *smi_info, char *msg)
|
||||
{
|
||||
struct timespec64 t;
|
||||
|
||||
ktime_get_ts64(&t);
|
||||
pr_debug("**%s: %lld.%9.9ld\n", msg, t.tv_sec, t.tv_nsec);
|
||||
dev_dbg(smi_info->io.dev, "**%s: %lld.%9.9ld\n",
|
||||
msg, t.tv_sec, t.tv_nsec);
|
||||
}
|
||||
#else
|
||||
#define debug_timestamp(x)
|
||||
#define debug_timestamp(smi_info, x)
|
||||
#endif
|
||||
|
||||
static ATOMIC_NOTIFIER_HEAD(xaction_notifier_list);
|
||||
|
@ -318,7 +319,7 @@ static enum si_sm_result start_next_msg(struct smi_info *smi_info)
|
|||
|
||||
smi_info->curr_msg = smi_info->waiting_msg;
|
||||
smi_info->waiting_msg = NULL;
|
||||
debug_timestamp("Start2");
|
||||
debug_timestamp(smi_info, "Start2");
|
||||
err = atomic_notifier_call_chain(&xaction_notifier_list,
|
||||
0, smi_info);
|
||||
if (err & NOTIFY_STOP_MASK) {
|
||||
|
@ -538,7 +539,7 @@ static void handle_transaction_done(struct smi_info *smi_info)
|
|||
{
|
||||
struct ipmi_smi_msg *msg;
|
||||
|
||||
debug_timestamp("Done");
|
||||
debug_timestamp(smi_info, "Done");
|
||||
switch (smi_info->si_state) {
|
||||
case SI_NORMAL:
|
||||
if (!smi_info->curr_msg)
|
||||
|
@ -901,7 +902,7 @@ static void sender(void *send_info,
|
|||
struct smi_info *smi_info = send_info;
|
||||
unsigned long flags;
|
||||
|
||||
debug_timestamp("Enqueue");
|
||||
debug_timestamp(smi_info, "Enqueue");
|
||||
|
||||
if (smi_info->run_to_completion) {
|
||||
/*
|
||||
|
@ -1079,7 +1080,7 @@ static void smi_timeout(struct timer_list *t)
|
|||
long timeout;
|
||||
|
||||
spin_lock_irqsave(&(smi_info->si_lock), flags);
|
||||
debug_timestamp("Timer");
|
||||
debug_timestamp(smi_info, "Timer");
|
||||
|
||||
jiffies_now = jiffies;
|
||||
time_diff = (((long)jiffies_now - (long)smi_info->last_timeout_jiffies)
|
||||
|
@ -1128,7 +1129,7 @@ irqreturn_t ipmi_si_irq_handler(int irq, void *data)
|
|||
|
||||
smi_inc_stat(smi_info, interrupts);
|
||||
|
||||
debug_timestamp("Interrupt");
|
||||
debug_timestamp(smi_info, "Interrupt");
|
||||
|
||||
smi_event_handler(smi_info, 0);
|
||||
spin_unlock_irqrestore(&(smi_info->si_lock), flags);
|
||||
|
|
|
@ -814,6 +814,14 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result,
|
|||
break;
|
||||
|
||||
case SSIF_GETTING_EVENTS:
|
||||
if (!msg) {
|
||||
/* Should never happen, but just in case. */
|
||||
dev_warn(&ssif_info->client->dev,
|
||||
"No message set while getting events\n");
|
||||
ipmi_ssif_unlock_cond(ssif_info, flags);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((result < 0) || (len < 3) || (msg->rsp[2] != 0)) {
|
||||
/* Error getting event, probably done. */
|
||||
msg->done(msg);
|
||||
|
@ -838,6 +846,14 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result,
|
|||
break;
|
||||
|
||||
case SSIF_GETTING_MESSAGES:
|
||||
if (!msg) {
|
||||
/* Should never happen, but just in case. */
|
||||
dev_warn(&ssif_info->client->dev,
|
||||
"No message set while getting messages\n");
|
||||
ipmi_ssif_unlock_cond(ssif_info, flags);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((result < 0) || (len < 3) || (msg->rsp[2] != 0)) {
|
||||
/* Error getting event, probably done. */
|
||||
msg->done(msg);
|
||||
|
@ -861,6 +877,13 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result,
|
|||
deliver_recv_msg(ssif_info, msg);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Should never happen, but just in case. */
|
||||
dev_warn(&ssif_info->client->dev,
|
||||
"Invalid state in message done handling: %d\n",
|
||||
ssif_info->ssif_state);
|
||||
ipmi_ssif_unlock_cond(ssif_info, flags);
|
||||
}
|
||||
|
||||
flags = ipmi_ssif_lock_cond(ssif_info, &oflags);
|
||||
|
@ -1053,7 +1076,7 @@ static void start_next_msg(struct ssif_info *ssif_info, unsigned long *flags)
|
|||
static void sender(void *send_info,
|
||||
struct ipmi_smi_msg *msg)
|
||||
{
|
||||
struct ssif_info *ssif_info = (struct ssif_info *) send_info;
|
||||
struct ssif_info *ssif_info = send_info;
|
||||
unsigned long oflags, *flags;
|
||||
|
||||
BUG_ON(ssif_info->waiting_msg);
|
||||
|
@ -1090,7 +1113,7 @@ static int get_smi_info(void *send_info, struct ipmi_smi_info *data)
|
|||
*/
|
||||
static void request_events(void *send_info)
|
||||
{
|
||||
struct ssif_info *ssif_info = (struct ssif_info *) send_info;
|
||||
struct ssif_info *ssif_info = send_info;
|
||||
unsigned long oflags, *flags;
|
||||
|
||||
if (!ssif_info->has_event_buffer)
|
||||
|
@ -1107,7 +1130,7 @@ static void request_events(void *send_info)
|
|||
*/
|
||||
static void ssif_set_need_watch(void *send_info, unsigned int watch_mask)
|
||||
{
|
||||
struct ssif_info *ssif_info = (struct ssif_info *) send_info;
|
||||
struct ssif_info *ssif_info = send_info;
|
||||
unsigned long oflags, *flags;
|
||||
long timeout = 0;
|
||||
|
||||
|
@ -1619,7 +1642,7 @@ static int ssif_check_and_remove(struct i2c_client *client,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
static int ssif_probe(struct i2c_client *client)
|
||||
{
|
||||
unsigned char msg[3];
|
||||
unsigned char *resp;
|
||||
|
@ -2037,7 +2060,7 @@ static struct i2c_driver ssif_i2c_driver = {
|
|||
.driver = {
|
||||
.name = DEVICE_NAME
|
||||
},
|
||||
.probe = ssif_probe,
|
||||
.probe_new = ssif_probe,
|
||||
.remove = ssif_remove,
|
||||
.alert = ssif_alert,
|
||||
.id_table = ssif_id,
|
||||
|
|
|
@ -354,12 +354,8 @@ static void msg_free_recv(struct ipmi_recv_msg *msg)
|
|||
complete(&msg_wait);
|
||||
}
|
||||
}
|
||||
static struct ipmi_smi_msg smi_msg = {
|
||||
.done = msg_free_smi
|
||||
};
|
||||
static struct ipmi_recv_msg recv_msg = {
|
||||
.done = msg_free_recv
|
||||
};
|
||||
static struct ipmi_smi_msg smi_msg = INIT_IPMI_SMI_MSG(msg_free_smi);
|
||||
static struct ipmi_recv_msg recv_msg = INIT_IPMI_RECV_MSG(msg_free_recv);
|
||||
|
||||
static int __ipmi_set_timeout(struct ipmi_smi_msg *smi_msg,
|
||||
struct ipmi_recv_msg *recv_msg,
|
||||
|
@ -475,12 +471,10 @@ static void panic_recv_free(struct ipmi_recv_msg *msg)
|
|||
atomic_dec(&panic_done_count);
|
||||
}
|
||||
|
||||
static struct ipmi_smi_msg panic_halt_heartbeat_smi_msg = {
|
||||
.done = panic_smi_free
|
||||
};
|
||||
static struct ipmi_recv_msg panic_halt_heartbeat_recv_msg = {
|
||||
.done = panic_recv_free
|
||||
};
|
||||
static struct ipmi_smi_msg panic_halt_heartbeat_smi_msg =
|
||||
INIT_IPMI_SMI_MSG(panic_smi_free);
|
||||
static struct ipmi_recv_msg panic_halt_heartbeat_recv_msg =
|
||||
INIT_IPMI_RECV_MSG(panic_recv_free);
|
||||
|
||||
static void panic_halt_ipmi_heartbeat(void)
|
||||
{
|
||||
|
@ -516,12 +510,10 @@ static void panic_halt_ipmi_heartbeat(void)
|
|||
atomic_sub(2, &panic_done_count);
|
||||
}
|
||||
|
||||
static struct ipmi_smi_msg panic_halt_smi_msg = {
|
||||
.done = panic_smi_free
|
||||
};
|
||||
static struct ipmi_recv_msg panic_halt_recv_msg = {
|
||||
.done = panic_recv_free
|
||||
};
|
||||
static struct ipmi_smi_msg panic_halt_smi_msg =
|
||||
INIT_IPMI_SMI_MSG(panic_smi_free);
|
||||
static struct ipmi_recv_msg panic_halt_recv_msg =
|
||||
INIT_IPMI_RECV_MSG(panic_recv_free);
|
||||
|
||||
/*
|
||||
* Special call, doesn't claim any locks. This is only to be called
|
||||
|
|
|
@ -72,6 +72,11 @@ struct ipmi_recv_msg {
|
|||
unsigned char msg_data[IPMI_MAX_MSG_LENGTH];
|
||||
};
|
||||
|
||||
#define INIT_IPMI_RECV_MSG(done_handler) \
|
||||
{ \
|
||||
.done = done_handler \
|
||||
}
|
||||
|
||||
/* Allocate and free the receive message. */
|
||||
void ipmi_free_recv_msg(struct ipmi_recv_msg *msg);
|
||||
|
||||
|
|
|
@ -125,6 +125,12 @@ struct ipmi_smi_msg {
|
|||
void (*done)(struct ipmi_smi_msg *msg);
|
||||
};
|
||||
|
||||
#define INIT_IPMI_SMI_MSG(done_handler) \
|
||||
{ \
|
||||
.done = done_handler, \
|
||||
.type = IPMI_SMI_MSG_TYPE_NORMAL \
|
||||
}
|
||||
|
||||
struct ipmi_smi_handlers {
|
||||
struct module *owner;
|
||||
|
||||
|
|
Loading…
Reference in New Issue