- bt->timeout = BT_NORMAL_TIMEOUT;
- bt->state = BT_STATE_XACTION_START;
- break;
-
- default: /* HOSED is supposed to be caught much earlier */
- error_recovery(bt, "internal logic error");
- break;
- }
- return SI_SM_CALL_WITH_DELAY;
+ bt->timeout = bt->BT_CAP_req2rsp;
+ BT_STATE_CHANGE(BT_STATE_XACTION_START,
+ SI_SM_CALL_WITH_DELAY);
+
+ /*
+ * Get BT Capabilities, using timing of upper level state machine.
+ * Set outreqs to prevent infinite loop on timeout.
+ */
+ case BT_STATE_CAPABILITIES_BEGIN:
+ bt->BT_CAP_outreqs = 1;
+ {
+ unsigned char GetBT_CAP[] = { 0x18, 0x36 };
+ bt->state = BT_STATE_IDLE;
+ bt_start_transaction(bt, GetBT_CAP, sizeof(GetBT_CAP));
+ }
+ bt->complete = BT_STATE_CAPABILITIES_END;
+ BT_STATE_CHANGE(BT_STATE_XACTION_START,
+ SI_SM_CALL_WITH_DELAY);
+
+ case BT_STATE_CAPABILITIES_END:
+ i = bt_get_result(bt, BT_CAP, sizeof(BT_CAP));
+ bt_init_data(bt, bt->io);
+ if ((i == 8) && !BT_CAP[2]) {
+ bt->BT_CAP_outreqs = BT_CAP[3];
+ bt->BT_CAP_req2rsp = BT_CAP[6] * 1000000;
+ bt->BT_CAP_retries = BT_CAP[7];
+ } else
+ printk(KERN_WARNING "IPMI BT: using default values\n");
+ if (!bt->BT_CAP_outreqs)
+ bt->BT_CAP_outreqs = 1;
+ printk(KERN_WARNING "IPMI BT: req2rsp=%ld secs retries=%d\n",
+ bt->BT_CAP_req2rsp / 1000000L, bt->BT_CAP_retries);
+ bt->timeout = bt->BT_CAP_req2rsp;
+ return SI_SM_CALL_WITHOUT_DELAY;
+
+ default: /* should never occur */
+ return error_recovery(bt,
+ status,
+ IPMI_ERR_UNSPECIFIED);
+ }
+ return SI_SM_CALL_WITH_DELAY;