Skip to content

Commit

Permalink
Merge tag 'for-linus-4.3' of git://git.code.sf.net/p/openipmi/linux-ipmi
Browse files Browse the repository at this point in the history
Pull IPMI updates from Corey Minyard:
 "Most of these have been sitting in linux-next for more than a release,
  particularly commit 0fbcf4a ("ipmi: Convert the IPMI SI ACPI
  handling to a platform device") which is probably the most complex
  patch.

  That is also the one that changes drivers/acpi/acpi_pnp.c.  The change
  in that file is only removing IPMI from a "special platform devices"
  list, since I convert it to the standard PNP interface.  I posted this
  one to the ACPI list twice and got no response, and it seems to work
  well in my testing, so I'm hoping it's good.

  Hidehiro Kawai posted a set of changes that improves the panic time
  handling in the IPMI driver.

  The rest of the changes are minor bug fixes or cleanups and some
  documentation"

* tag 'for-linus-4.3' of git://git.code.sf.net/p/openipmi/linux-ipmi:
  ipmi:ssif: Add a module parm to specify that SMBus alerts don't work
  ipmi: add of_device_id in MODULE_DEVICE_TABLE
  ipmi: Compensate for BMCs that wont set the irq enable bit
  ipmi: Don't call receive handler in the panic context
  ipmi: Avoid touching possible corrupted lists in the panic context
  ipmi: Don't flush messages in sender() in run-to-completion mode
  ipmi: Factor out message flushing procedure
  ipmi: Remove unneeded set_run_to_completion call
  ipmi: Make some data const that was only read
  ipmi: constify SSIF ACPI device ids
  ipmi: Delete an unnecessary check before the function call "cleanup_one_si"
  char:ipmi - Change 1 to true for bool type variables during initialization.
  impi:Remove unneeded setting of module owner to THIS_MODULE in the platform structure, powernv_ipmi_driver
  ipmi: Add a comment in how messages are delivered from the lower layer
  ipmi/powernv: Fix potential invalid pointer dereference
  ipmi: Convert the IPMI SI ACPI handling to a platform device
  ipmi: Add device tree bindings information
  • Loading branch information
Linus Torvalds committed Sep 9, 2015
2 parents f6f7a63 + bf2d087 commit a794b4f
Show file tree
Hide file tree
Showing 11 changed files with 437 additions and 280 deletions.
25 changes: 25 additions & 0 deletions Documentation/devicetree/bindings/ipmi.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
IPMI device

Required properties:
- compatible: should be one of ipmi-kcs, ipmi-smic, or ipmi-bt
- device_type: should be ipmi
- reg: Address and length of the register set for the device

Optional properties:
- interrupts: The interrupt for the device. Without this the interface
is polled.
- reg-size - The size of the register. Defaults to 1
- reg-spacing - The number of bytes between register starts. Defaults to 1
- reg-shift - The amount to shift the registers to the right to get the data
into bit zero.

Example:

smic@fff3a000 {
compatible = "ipmi-smic";
device_type = "ipmi";
reg = <0xfff3a000 0x1000>;
interrupts = <0 24 4>;
reg-size = <4>;
reg-spacing = <4>;
};
2 changes: 0 additions & 2 deletions drivers/acpi/acpi_pnp.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ static const struct acpi_device_id acpi_pnp_device_ids[] = {
{"PNP0600"}, /* Generic ESDI/IDE/ATA compatible hard disk controller */
/* floppy */
{"PNP0700"},
/* ipmi_si */
{"IPI0001"},
/* tpm_inf_pnp */
{"IFX0101"}, /* Infineon TPMs */
{"IFX0102"}, /* Infineon TPMs */
Expand Down
2 changes: 1 addition & 1 deletion drivers/char/ipmi/ipmi_bt_sm.c
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,7 @@ static int bt_size(void)
return sizeof(struct si_sm_data);
}

struct si_sm_handlers bt_smi_handlers = {
const struct si_sm_handlers bt_smi_handlers = {
.init_data = bt_init_data,
.start_transaction = bt_start_transaction,
.get_result = bt_get_result,
Expand Down
2 changes: 1 addition & 1 deletion drivers/char/ipmi/ipmi_kcs_sm.c
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ static void kcs_cleanup(struct si_sm_data *kcs)
{
}

struct si_sm_handlers kcs_smi_handlers = {
const struct si_sm_handlers kcs_smi_handlers = {
.init_data = init_kcs_data,
.start_transaction = start_kcs_transaction,
.get_result = get_kcs_result,
Expand Down
46 changes: 37 additions & 9 deletions drivers/char/ipmi/ipmi_msghandler.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ struct ipmi_smi {
* an umpreemptible region to use this. You must fetch the
* value into a local variable and make sure it is not NULL.
*/
struct ipmi_smi_handlers *handlers;
const struct ipmi_smi_handlers *handlers;
void *send_info;

#ifdef CONFIG_PROC_FS
Expand Down Expand Up @@ -744,7 +744,13 @@ static void deliver_response(struct ipmi_recv_msg *msg)
ipmi_inc_stat(intf, unhandled_local_responses);
}
ipmi_free_recv_msg(msg);
} else {
} else if (!oops_in_progress) {
/*
* If we are running in the panic context, calling the
* receive handler doesn't much meaning and has a deadlock
* risk. At this moment, simply skip it in that case.
*/

ipmi_user_t user = msg->user;
user->handler->ipmi_recv_hndl(msg, user->handler_data);
}
Expand Down Expand Up @@ -1015,7 +1021,7 @@ int ipmi_get_smi_info(int if_num, struct ipmi_smi_info *data)
{
int rv = 0;
ipmi_smi_t intf;
struct ipmi_smi_handlers *handlers;
const struct ipmi_smi_handlers *handlers;

mutex_lock(&ipmi_interfaces_mutex);
list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
Expand Down Expand Up @@ -1501,7 +1507,7 @@ static struct ipmi_smi_msg *smi_add_send_msg(ipmi_smi_t intf,
}


static void smi_send(ipmi_smi_t intf, struct ipmi_smi_handlers *handlers,
static void smi_send(ipmi_smi_t intf, const struct ipmi_smi_handlers *handlers,
struct ipmi_smi_msg *smi_msg, int priority)
{
int run_to_completion = intf->run_to_completion;
Expand Down Expand Up @@ -2747,7 +2753,7 @@ void ipmi_poll_interface(ipmi_user_t user)
}
EXPORT_SYMBOL(ipmi_poll_interface);

int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,
void *send_info,
struct ipmi_device_id *device_id,
struct device *si_dev,
Expand Down Expand Up @@ -3959,6 +3965,10 @@ void ipmi_smi_msg_received(ipmi_smi_t intf,

if (!run_to_completion)
spin_lock_irqsave(&intf->xmit_msgs_lock, flags);
/*
* We can get an asynchronous event or receive message in addition
* to commands we send.
*/
if (msg == intf->curr_msg)
intf->curr_msg = NULL;
if (!run_to_completion)
Expand Down Expand Up @@ -4015,7 +4025,7 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
unsigned int *waiting_msgs)
{
struct ipmi_recv_msg *msg;
struct ipmi_smi_handlers *handlers;
const struct ipmi_smi_handlers *handlers;

if (intf->in_shutdown)
return;
Expand Down Expand Up @@ -4082,7 +4092,7 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
ipmi_inc_stat(intf,
retransmitted_ipmb_commands);

smi_send(intf, intf->handlers, smi_msg, 0);
smi_send(intf, handlers, smi_msg, 0);
} else
ipmi_free_smi_msg(smi_msg);

Expand Down Expand Up @@ -4291,6 +4301,9 @@ static void ipmi_panic_request_and_wait(ipmi_smi_t intf,
0, 1); /* Don't retry, and don't wait. */
if (rv)
atomic_sub(2, &panic_done_count);
else if (intf->handlers->flush_messages)
intf->handlers->flush_messages(intf->send_info);

while (atomic_read(&panic_done_count) != 0)
ipmi_poll(intf);
}
Expand Down Expand Up @@ -4364,9 +4377,7 @@ static void send_panic_events(char *str)
/* Interface is not ready. */
continue;

intf->run_to_completion = 1;
/* Send the event announcing the panic. */
intf->handlers->set_run_to_completion(intf->send_info, 1);
ipmi_panic_request_and_wait(intf, &addr, &msg);
}

Expand Down Expand Up @@ -4506,6 +4517,23 @@ static int panic_event(struct notifier_block *this,
/* Interface is not ready. */
continue;

/*
* If we were interrupted while locking xmit_msgs_lock or
* waiting_rcv_msgs_lock, the corresponding list may be
* corrupted. In this case, drop items on the list for
* the safety.
*/
if (!spin_trylock(&intf->xmit_msgs_lock)) {
INIT_LIST_HEAD(&intf->xmit_msgs);
INIT_LIST_HEAD(&intf->hp_xmit_msgs);
} else
spin_unlock(&intf->xmit_msgs_lock);

if (!spin_trylock(&intf->waiting_rcv_msgs_lock))
INIT_LIST_HEAD(&intf->waiting_rcv_msgs);
else
spin_unlock(&intf->waiting_rcv_msgs_lock);

intf->run_to_completion = 1;
intf->handlers->set_run_to_completion(intf->send_info, 1);
}
Expand Down
10 changes: 8 additions & 2 deletions drivers/char/ipmi/ipmi_powernv.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,15 @@ static int ipmi_powernv_recv(struct ipmi_smi_powernv *smi)
pr_devel("%s: -> %d (size %lld)\n", __func__,
rc, rc == 0 ? size : 0);
if (rc) {
/* If came via the poll, and response was not yet ready */
if (rc == OPAL_EMPTY) {
spin_unlock_irqrestore(&smi->msg_lock, flags);
return 0;
}

smi->cur_msg = NULL;
spin_unlock_irqrestore(&smi->msg_lock, flags);
ipmi_free_smi_msg(msg);
send_error_reply(smi, msg, IPMI_ERR_UNSPECIFIED);
return 0;
}

Expand Down Expand Up @@ -300,7 +307,6 @@ static const struct of_device_id ipmi_powernv_match[] = {
static struct platform_driver powernv_ipmi_driver = {
.driver = {
.name = "ipmi-powernv",
.owner = THIS_MODULE,
.of_match_table = ipmi_powernv_match,
},
.probe = ipmi_powernv_probe,
Expand Down
Loading

0 comments on commit a794b4f

Please sign in to comment.