aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlistair Popple <alistair@popple.id.au>2015-09-16 12:15:50 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-10-08 14:47:26 +1100
commit37a74a4d1b0badee5b971a676b09bbf18ff816a4 (patch)
tree5b17663c2f5dd8b07a9b1cdfb1c8290a8eaed95e
parentb4315f5520cb99312e139d55289a012af14ad042 (diff)
downloadskiboot-37a74a4d1b0badee5b971a676b09bbf18ff816a4.zip
skiboot-37a74a4d1b0badee5b971a676b09bbf18ff816a4.tar.gz
skiboot-37a74a4d1b0badee5b971a676b09bbf18ff816a4.tar.bz2
hw/bt.c: Timeout messages when bt interface isn't functional
During system bring up we may not have a properly functioning ipmi interface. This prevents skiboot completing the boot process as it waits for certain bt messages to complete before continuing. This patch alters the bt message timeouts to ensure messages timeout in the case of a non-responsive bt interface. Signed-off-by: Alistair Popple <alistair@popple.id.au> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
-rw-r--r--hw/bt.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/hw/bt.c b/hw/bt.c
index a53ff14..6d559d0 100644
--- a/hw/bt.c
+++ b/hw/bt.c
@@ -165,15 +165,11 @@ static void bt_reset_interface(void)
/* Try and send a message from the message queue. Caller must hold
* bt.bt_lock and bt.lock and ensue the message queue is not
* empty. */
-static void bt_send_msg(void)
+static void bt_send_msg(struct bt_msg *bt_msg)
{
int i;
- struct bt_msg *bt_msg;
struct ipmi_msg *ipmi_msg;
- bt_msg = list_top(&bt.msgq, struct bt_msg, link);
- assert(bt_msg);
-
ipmi_msg = &bt_msg->ipmi_msg;
/* Send the message */
@@ -195,7 +191,6 @@ static void bt_send_msg(void)
for (i = 0; i < ipmi_msg->req_size; i++)
bt_outb(ipmi_msg->data[i], BT_HOST2BMC);
- bt_msg->tb = mftb();
bt_outb(BT_CTRL_H2B_ATN, BT_CTRL);
bt_set_state(BT_STATE_RESP_WAIT);
@@ -346,9 +341,22 @@ static void print_debug_queue_info(void) {}
static void bt_send_and_unlock(void)
{
- if (lpc_ok() && bt_idle() && !list_empty(&bt.msgq)
- && bt.state == BT_STATE_IDLE)
- bt_send_msg();
+ if (lpc_ok() && !list_empty(&bt.msgq)) {
+ struct bt_msg *bt_msg;
+
+ bt_msg = list_top(&bt.msgq, struct bt_msg, link);
+ assert(bt_msg);
+
+ /* Start the message timeout once it gets to the top
+ * of the queue. This will ensure we timeout messages
+ * in the case of a broken bt interface as occurs when
+ * the BMC is not responding to any IPMI messages. */
+ if (bt_msg->tb == 0)
+ bt_msg->tb = mftb();
+
+ if (bt_idle() && bt.state == BT_STATE_IDLE)
+ bt_send_msg(bt_msg);
+ }
unlock(&bt.lock);
return;