Diff markup
1 /* 1 /*
2 * ipmi_bt_sm.c 2 * ipmi_bt_sm.c
3 * 3 *
4 * The state machine for an Open IPMI BT sub- 4 * The state machine for an Open IPMI BT sub-driver under ipmi_si.c, part
5 * of the driver architecture at http://sourc 5 * of the driver architecture at http://sourceforge.net/project/openipmi
6 * 6 *
7 * Author: Rocky Craig <first.last@hp.com 7 * Author: Rocky Craig <first.last@hp.com>
8 * 8 *
9 * This program is free software; you can red 9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public 10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version. 12 * option) any later version.
13 * 13 *
14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND AN 14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS FOR A PARTICUL 16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQU 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTIT 19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
20 * OF USE, DATA, OR PROFITS; OR BUSINESS INTE 20 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CON 21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
22 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) A 22 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
23 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF T 23 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 * 24 *
25 * You should have received a copy of the GNU 25 * You should have received a copy of the GNU General Public License along
26 * with this program; if not, write to the Fr 26 * with this program; if not, write to the Free Software Foundation, Inc.,
27 * 675 Mass Ave, Cambridge, MA 02139, USA. * 27 * 675 Mass Ave, Cambridge, MA 02139, USA. */
28 28
29 #include <linux/kernel.h> /* For printk. */ 29 #include <linux/kernel.h> /* For printk. */
30 #include <linux/string.h> 30 #include <linux/string.h>
31 #include <linux/module.h> 31 #include <linux/module.h>
32 #include <linux/moduleparam.h> 32 #include <linux/moduleparam.h>
33 #include <linux/ipmi_msgdefs.h> /* for 33 #include <linux/ipmi_msgdefs.h> /* for completion codes */
34 #include "ipmi_si_sm.h" 34 #include "ipmi_si_sm.h"
35 35
36 #define BT_DEBUG_OFF 0 /* Used in pro 36 #define BT_DEBUG_OFF 0 /* Used in production */
37 #define BT_DEBUG_ENABLE 1 /* Generic mes 37 #define BT_DEBUG_ENABLE 1 /* Generic messages */
38 #define BT_DEBUG_MSG 2 /* Prints all 38 #define BT_DEBUG_MSG 2 /* Prints all request/response buffers */
39 #define BT_DEBUG_STATES 4 /* Verbose loo 39 #define BT_DEBUG_STATES 4 /* Verbose look at state changes */
40 /* !! 40 /* BT_DEBUG_OFF must be zero to correspond to the default uninitialized
41 * BT_DEBUG_OFF must be zero to correspond to !! 41 value */
42 * value <<
43 */ <<
44 42
45 static int bt_debug; /* 0 == BT_DEBUG_OFF */ 43 static int bt_debug; /* 0 == BT_DEBUG_OFF */
46 44
47 module_param(bt_debug, int, 0644); 45 module_param(bt_debug, int, 0644);
48 MODULE_PARM_DESC(bt_debug, "debug bitmask, 1=e 46 MODULE_PARM_DESC(bt_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
49 47
50 /* !! 48 /* Typical "Get BT Capabilities" values are 2-3 retries, 5-10 seconds,
51 * Typical "Get BT Capabilities" values are 2- !! 49 and 64 byte buffers. However, one HP implementation wants 255 bytes of
52 * and 64 byte buffers. However, one HP imple !! 50 buffer (with a documented message of 160 bytes) so go for the max.
53 * buffer (with a documented message of 160 by !! 51 Since the Open IPMI architecture is single-message oriented at this
54 * Since the Open IPMI architecture is single- !! 52 stage, the queue depth of BT is of no concern. */
55 * stage, the queue depth of BT is of no conce <<
56 */ <<
57 53
58 #define BT_NORMAL_TIMEOUT 5 /* sec 54 #define BT_NORMAL_TIMEOUT 5 /* seconds */
59 #define BT_NORMAL_RETRY_LIMIT 2 55 #define BT_NORMAL_RETRY_LIMIT 2
60 #define BT_RESET_DELAY 6 /* sec 56 #define BT_RESET_DELAY 6 /* seconds after warm reset */
61 57
62 /* !! 58 /* States are written in chronological order and usually cover
63 * States are written in chronological order a !! 59 multiple rows of the state table discussion in the IPMI spec. */
64 * multiple rows of the state table discussion <<
65 */ <<
66 60
67 enum bt_states { 61 enum bt_states {
68 BT_STATE_IDLE = 0, /* Order is cr 62 BT_STATE_IDLE = 0, /* Order is critical in this list */
69 BT_STATE_XACTION_START, 63 BT_STATE_XACTION_START,
70 BT_STATE_WRITE_BYTES, 64 BT_STATE_WRITE_BYTES,
71 BT_STATE_WRITE_CONSUME, 65 BT_STATE_WRITE_CONSUME,
72 BT_STATE_READ_WAIT, 66 BT_STATE_READ_WAIT,
73 BT_STATE_CLEAR_B2H, 67 BT_STATE_CLEAR_B2H,
74 BT_STATE_READ_BYTES, 68 BT_STATE_READ_BYTES,
75 BT_STATE_RESET1, /* These must 69 BT_STATE_RESET1, /* These must come last */
76 BT_STATE_RESET2, 70 BT_STATE_RESET2,
77 BT_STATE_RESET3, 71 BT_STATE_RESET3,
78 BT_STATE_RESTART, 72 BT_STATE_RESTART,
79 BT_STATE_PRINTME, 73 BT_STATE_PRINTME,
80 BT_STATE_CAPABILITIES_BEGIN, 74 BT_STATE_CAPABILITIES_BEGIN,
81 BT_STATE_CAPABILITIES_END, 75 BT_STATE_CAPABILITIES_END,
82 BT_STATE_LONG_BUSY /* BT doesn't 76 BT_STATE_LONG_BUSY /* BT doesn't get hosed :-) */
83 }; 77 };
84 78
85 /* !! 79 /* Macros seen at the end of state "case" blocks. They help with legibility
86 * Macros seen at the end of state "case" bloc !! 80 and debugging. */
87 * and debugging. <<
88 */ <<
89 81
90 #define BT_STATE_CHANGE(X, Y) { bt->state = X; !! 82 #define BT_STATE_CHANGE(X,Y) { bt->state = X; return Y; }
91 83
92 #define BT_SI_SM_RETURN(Y) { last_printed = 84 #define BT_SI_SM_RETURN(Y) { last_printed = BT_STATE_PRINTME; return Y; }
93 85
94 struct si_sm_data { 86 struct si_sm_data {
95 enum bt_states state; 87 enum bt_states state;
96 unsigned char seq; /* BT 88 unsigned char seq; /* BT sequence number */
97 struct si_sm_io *io; 89 struct si_sm_io *io;
98 unsigned char write_data[IPMI_MAX_MS 90 unsigned char write_data[IPMI_MAX_MSG_LENGTH];
99 int write_count; 91 int write_count;
100 unsigned char read_data[IPMI_MAX_MSG 92 unsigned char read_data[IPMI_MAX_MSG_LENGTH];
101 int read_count; 93 int read_count;
102 int truncated; 94 int truncated;
103 long timeout; /* mic 95 long timeout; /* microseconds countdown */
104 int error_retries; /* end 96 int error_retries; /* end of "common" fields */
105 int nonzero_status; /* hun 97 int nonzero_status; /* hung BMCs stay all 0 */
106 enum bt_states complete; /* to 98 enum bt_states complete; /* to divert the state machine */
107 int BT_CAP_outreqs; 99 int BT_CAP_outreqs;
108 long BT_CAP_req2rsp; 100 long BT_CAP_req2rsp;
109 int BT_CAP_retries; /* Rec 101 int BT_CAP_retries; /* Recommended retries */
110 }; 102 };
111 103
112 #define BT_CLR_WR_PTR 0x01 /* See IPMI 1. 104 #define BT_CLR_WR_PTR 0x01 /* See IPMI 1.5 table 11.6.4 */
113 #define BT_CLR_RD_PTR 0x02 105 #define BT_CLR_RD_PTR 0x02
114 #define BT_H2B_ATN 0x04 106 #define BT_H2B_ATN 0x04
115 #define BT_B2H_ATN 0x08 107 #define BT_B2H_ATN 0x08
116 #define BT_SMS_ATN 0x10 108 #define BT_SMS_ATN 0x10
117 #define BT_OEM0 0x20 109 #define BT_OEM0 0x20
118 #define BT_H_BUSY 0x40 110 #define BT_H_BUSY 0x40
119 #define BT_B_BUSY 0x80 111 #define BT_B_BUSY 0x80
120 112
121 /* !! 113 /* Some bits are toggled on each write: write once to set it, once
122 * Some bits are toggled on each write: write !! 114 more to clear it; writing a zero does nothing. To absolutely
123 * more to clear it; writing a zero does nothi !! 115 clear it, check its state and write if set. This avoids the "get
124 * clear it, check its state and write if set. !! 116 current then use as mask" scheme to modify one bit. Note that the
125 * current then use as mask" scheme to modify !! 117 variable "bt" is hardcoded into these macros. */
126 * variable "bt" is hardcoded into these macro <<
127 */ <<
128 118
129 #define BT_STATUS bt->io->inputb(bt->io, 119 #define BT_STATUS bt->io->inputb(bt->io, 0)
130 #define BT_CONTROL(x) bt->io->outputb(bt->io 120 #define BT_CONTROL(x) bt->io->outputb(bt->io, 0, x)
131 121
132 #define BMC2HOST bt->io->inputb(bt->io, 122 #define BMC2HOST bt->io->inputb(bt->io, 1)
133 #define HOST2BMC(x) bt->io->outputb(bt->io 123 #define HOST2BMC(x) bt->io->outputb(bt->io, 1, x)
134 124
135 #define BT_INTMASK_R bt->io->inputb(bt->io, 125 #define BT_INTMASK_R bt->io->inputb(bt->io, 2)
136 #define BT_INTMASK_W(x) bt->io->outputb(bt->io 126 #define BT_INTMASK_W(x) bt->io->outputb(bt->io, 2, x)
137 127
138 /* !! 128 /* Convenience routines for debugging. These are not multi-open safe!
139 * Convenience routines for debugging. These !! 129 Note the macros have hardcoded variables in them. */
140 * Note the macros have hardcoded variables in <<
141 */ <<
142 130
143 static char *state2txt(unsigned char state) 131 static char *state2txt(unsigned char state)
144 { 132 {
145 switch (state) { 133 switch (state) {
146 case BT_STATE_IDLE: return 134 case BT_STATE_IDLE: return("IDLE");
147 case BT_STATE_XACTION_START: return 135 case BT_STATE_XACTION_START: return("XACTION");
148 case BT_STATE_WRITE_BYTES: return 136 case BT_STATE_WRITE_BYTES: return("WR_BYTES");
149 case BT_STATE_WRITE_CONSUME: return 137 case BT_STATE_WRITE_CONSUME: return("WR_CONSUME");
150 case BT_STATE_READ_WAIT: return 138 case BT_STATE_READ_WAIT: return("RD_WAIT");
151 case BT_STATE_CLEAR_B2H: return 139 case BT_STATE_CLEAR_B2H: return("CLEAR_B2H");
152 case BT_STATE_READ_BYTES: return 140 case BT_STATE_READ_BYTES: return("RD_BYTES");
153 case BT_STATE_RESET1: return 141 case BT_STATE_RESET1: return("RESET1");
154 case BT_STATE_RESET2: return 142 case BT_STATE_RESET2: return("RESET2");
155 case BT_STATE_RESET3: return 143 case BT_STATE_RESET3: return("RESET3");
156 case BT_STATE_RESTART: return 144 case BT_STATE_RESTART: return("RESTART");
157 case BT_STATE_LONG_BUSY: return 145 case BT_STATE_LONG_BUSY: return("LONG_BUSY");
158 case BT_STATE_CAPABILITIES_BEGIN: retu 146 case BT_STATE_CAPABILITIES_BEGIN: return("CAP_BEGIN");
159 case BT_STATE_CAPABILITIES_END: return 147 case BT_STATE_CAPABILITIES_END: return("CAP_END");
160 } 148 }
161 return("BAD STATE"); 149 return("BAD STATE");
162 } 150 }
163 #define STATE2TXT state2txt(bt->state) 151 #define STATE2TXT state2txt(bt->state)
164 152
165 static char *status2txt(unsigned char status) 153 static char *status2txt(unsigned char status)
166 { 154 {
167 /* 155 /*
168 * This cannot be called by two thread 156 * This cannot be called by two threads at the same time and
169 * the buffer is always consumed immed 157 * the buffer is always consumed immediately, so the static is
170 * safe to use. 158 * safe to use.
171 */ 159 */
172 static char buf[40]; 160 static char buf[40];
173 161
174 strcpy(buf, "[ "); 162 strcpy(buf, "[ ");
175 if (status & BT_B_BUSY) 163 if (status & BT_B_BUSY)
176 strcat(buf, "B_BUSY "); 164 strcat(buf, "B_BUSY ");
177 if (status & BT_H_BUSY) 165 if (status & BT_H_BUSY)
178 strcat(buf, "H_BUSY "); 166 strcat(buf, "H_BUSY ");
179 if (status & BT_OEM0) 167 if (status & BT_OEM0)
180 strcat(buf, "OEM0 "); 168 strcat(buf, "OEM0 ");
181 if (status & BT_SMS_ATN) 169 if (status & BT_SMS_ATN)
182 strcat(buf, "SMS "); 170 strcat(buf, "SMS ");
183 if (status & BT_B2H_ATN) 171 if (status & BT_B2H_ATN)
184 strcat(buf, "B2H "); 172 strcat(buf, "B2H ");
185 if (status & BT_H2B_ATN) 173 if (status & BT_H2B_ATN)
186 strcat(buf, "H2B "); 174 strcat(buf, "H2B ");
187 strcat(buf, "]"); 175 strcat(buf, "]");
188 return buf; 176 return buf;
189 } 177 }
190 #define STATUS2TXT status2txt(status) 178 #define STATUS2TXT status2txt(status)
191 179
192 /* called externally at insmod time, and inter 180 /* called externally at insmod time, and internally on cleanup */
193 181
194 static unsigned int bt_init_data(struct si_sm_ 182 static unsigned int bt_init_data(struct si_sm_data *bt, struct si_sm_io *io)
195 { 183 {
196 memset(bt, 0, sizeof(struct si_sm_data 184 memset(bt, 0, sizeof(struct si_sm_data));
197 if (bt->io != io) { !! 185 if (bt->io != io) { /* external: one-time only things */
198 /* external: one-time only thi <<
199 bt->io = io; 186 bt->io = io;
200 bt->seq = 0; 187 bt->seq = 0;
201 } 188 }
202 bt->state = BT_STATE_IDLE; /* sta 189 bt->state = BT_STATE_IDLE; /* start here */
203 bt->complete = BT_STATE_IDLE; /* end 190 bt->complete = BT_STATE_IDLE; /* end here */
204 bt->BT_CAP_req2rsp = BT_NORMAL_TIMEOUT 191 bt->BT_CAP_req2rsp = BT_NORMAL_TIMEOUT * 1000000;
205 bt->BT_CAP_retries = BT_NORMAL_RETRY_L 192 bt->BT_CAP_retries = BT_NORMAL_RETRY_LIMIT;
206 /* BT_CAP_outreqs == zero is a flag to 193 /* BT_CAP_outreqs == zero is a flag to read BT Capabilities */
207 return 3; /* We claim 3 bytes of space 194 return 3; /* We claim 3 bytes of space; ought to check SPMI table */
208 } 195 }
209 196
210 /* Jam a completion code (probably an error) i 197 /* Jam a completion code (probably an error) into a response */
211 198
212 static void force_result(struct si_sm_data *bt 199 static void force_result(struct si_sm_data *bt, unsigned char completion_code)
213 { 200 {
214 bt->read_data[0] = 4; 201 bt->read_data[0] = 4; /* # following bytes */
215 bt->read_data[1] = bt->write_data[1] | 202 bt->read_data[1] = bt->write_data[1] | 4; /* Odd NetFn/LUN */
216 bt->read_data[2] = bt->write_data[2]; 203 bt->read_data[2] = bt->write_data[2]; /* seq (ignored) */
217 bt->read_data[3] = bt->write_data[3]; 204 bt->read_data[3] = bt->write_data[3]; /* Command */
218 bt->read_data[4] = completion_code; 205 bt->read_data[4] = completion_code;
219 bt->read_count = 5; 206 bt->read_count = 5;
220 } 207 }
221 208
222 /* The upper state machine starts here */ 209 /* The upper state machine starts here */
223 210
224 static int bt_start_transaction(struct si_sm_d 211 static int bt_start_transaction(struct si_sm_data *bt,
225 unsigned char 212 unsigned char *data,
226 unsigned int s 213 unsigned int size)
227 { 214 {
228 unsigned int i; 215 unsigned int i;
229 216
230 if (size < 2) 217 if (size < 2)
231 return IPMI_REQ_LEN_INVALID_ER 218 return IPMI_REQ_LEN_INVALID_ERR;
232 if (size > IPMI_MAX_MSG_LENGTH) 219 if (size > IPMI_MAX_MSG_LENGTH)
233 return IPMI_REQ_LEN_EXCEEDED_E 220 return IPMI_REQ_LEN_EXCEEDED_ERR;
234 221
235 if (bt->state == BT_STATE_LONG_BUSY) 222 if (bt->state == BT_STATE_LONG_BUSY)
236 return IPMI_NODE_BUSY_ERR; 223 return IPMI_NODE_BUSY_ERR;
237 224
238 if (bt->state != BT_STATE_IDLE) 225 if (bt->state != BT_STATE_IDLE)
239 return IPMI_NOT_IN_MY_STATE_ER 226 return IPMI_NOT_IN_MY_STATE_ERR;
240 227
241 if (bt_debug & BT_DEBUG_MSG) { 228 if (bt_debug & BT_DEBUG_MSG) {
242 printk(KERN_WARNING "BT: +++++ 229 printk(KERN_WARNING "BT: +++++++++++++++++ New command\n");
243 printk(KERN_WARNING "BT: NetFn 230 printk(KERN_WARNING "BT: NetFn/LUN CMD [%d data]:", size - 2);
244 for (i = 0; i < size; i ++) 231 for (i = 0; i < size; i ++)
245 printk(" %02x", data[i !! 232 printk (" %02x", data[i]);
246 printk("\n"); 233 printk("\n");
247 } 234 }
248 bt->write_data[0] = size + 1; /* all 235 bt->write_data[0] = size + 1; /* all data plus seq byte */
249 bt->write_data[1] = *data; /* Net 236 bt->write_data[1] = *data; /* NetFn/LUN */
250 bt->write_data[2] = bt->seq++; 237 bt->write_data[2] = bt->seq++;
251 memcpy(bt->write_data + 3, data + 1, s 238 memcpy(bt->write_data + 3, data + 1, size - 1);
252 bt->write_count = size + 2; 239 bt->write_count = size + 2;
253 bt->error_retries = 0; 240 bt->error_retries = 0;
254 bt->nonzero_status = 0; 241 bt->nonzero_status = 0;
255 bt->truncated = 0; 242 bt->truncated = 0;
256 bt->state = BT_STATE_XACTION_START; 243 bt->state = BT_STATE_XACTION_START;
257 bt->timeout = bt->BT_CAP_req2rsp; 244 bt->timeout = bt->BT_CAP_req2rsp;
258 force_result(bt, IPMI_ERR_UNSPECIFIED) 245 force_result(bt, IPMI_ERR_UNSPECIFIED);
259 return 0; 246 return 0;
260 } 247 }
261 248
262 /* !! 249 /* After the upper state machine has been told SI_SM_TRANSACTION_COMPLETE
263 * After the upper state machine has been told !! 250 it calls this. Strip out the length and seq bytes. */
264 * it calls this. Strip out the length and se <<
265 */ <<
266 251
267 static int bt_get_result(struct si_sm_data *bt 252 static int bt_get_result(struct si_sm_data *bt,
268 unsigned char *data, 253 unsigned char *data,
269 unsigned int length) 254 unsigned int length)
270 { 255 {
271 int i, msg_len; 256 int i, msg_len;
272 257
273 msg_len = bt->read_count - 2; 258 msg_len = bt->read_count - 2; /* account for length & seq */
274 if (msg_len < 3 || msg_len > IPMI_MAX_ 259 if (msg_len < 3 || msg_len > IPMI_MAX_MSG_LENGTH) {
275 force_result(bt, IPMI_ERR_UNSP 260 force_result(bt, IPMI_ERR_UNSPECIFIED);
276 msg_len = 3; 261 msg_len = 3;
277 } 262 }
278 data[0] = bt->read_data[1]; 263 data[0] = bt->read_data[1];
279 data[1] = bt->read_data[3]; 264 data[1] = bt->read_data[3];
280 if (length < msg_len || bt->truncated) 265 if (length < msg_len || bt->truncated) {
281 data[2] = IPMI_ERR_MSG_TRUNCAT 266 data[2] = IPMI_ERR_MSG_TRUNCATED;
282 msg_len = 3; 267 msg_len = 3;
283 } else 268 } else
284 memcpy(data + 2, bt->read_data 269 memcpy(data + 2, bt->read_data + 4, msg_len - 2);
285 270
286 if (bt_debug & BT_DEBUG_MSG) { 271 if (bt_debug & BT_DEBUG_MSG) {
287 printk(KERN_WARNING "BT: resul !! 272 printk (KERN_WARNING "BT: result %d bytes:", msg_len);
288 for (i = 0; i < msg_len; i++) 273 for (i = 0; i < msg_len; i++)
289 printk(" %02x", data[i 274 printk(" %02x", data[i]);
290 printk("\n"); !! 275 printk ("\n");
291 } 276 }
292 return msg_len; 277 return msg_len;
293 } 278 }
294 279
295 /* This bit's functionality is optional */ 280 /* This bit's functionality is optional */
296 #define BT_BMC_HWRST 0x80 281 #define BT_BMC_HWRST 0x80
297 282
298 static void reset_flags(struct si_sm_data *bt) 283 static void reset_flags(struct si_sm_data *bt)
299 { 284 {
300 if (bt_debug) 285 if (bt_debug)
301 printk(KERN_WARNING "IPMI BT: 286 printk(KERN_WARNING "IPMI BT: flag reset %s\n",
302 status 287 status2txt(BT_STATUS));
303 if (BT_STATUS & BT_H_BUSY) 288 if (BT_STATUS & BT_H_BUSY)
304 BT_CONTROL(BT_H_BUSY); /* for 289 BT_CONTROL(BT_H_BUSY); /* force clear */
305 BT_CONTROL(BT_CLR_WR_PTR); /* alw 290 BT_CONTROL(BT_CLR_WR_PTR); /* always reset */
306 BT_CONTROL(BT_SMS_ATN); /* alw 291 BT_CONTROL(BT_SMS_ATN); /* always clear */
307 BT_INTMASK_W(BT_BMC_HWRST); 292 BT_INTMASK_W(BT_BMC_HWRST);
308 } 293 }
309 294
310 /* !! 295 /* Get rid of an unwanted/stale response. This should only be needed for
311 * Get rid of an unwanted/stale response. Thi !! 296 BMCs that support multiple outstanding requests. */
312 * BMCs that support multiple outstanding requ <<
313 */ <<
314 297
315 static void drain_BMC2HOST(struct si_sm_data * 298 static void drain_BMC2HOST(struct si_sm_data *bt)
316 { 299 {
317 int i, size; 300 int i, size;
318 301
319 if (!(BT_STATUS & BT_B2H_ATN)) /* Not 302 if (!(BT_STATUS & BT_B2H_ATN)) /* Not signalling a response */
320 return; 303 return;
321 304
322 BT_CONTROL(BT_H_BUSY); /* now 305 BT_CONTROL(BT_H_BUSY); /* now set */
323 BT_CONTROL(BT_B2H_ATN); /* alw 306 BT_CONTROL(BT_B2H_ATN); /* always clear */
324 BT_STATUS; /* pau 307 BT_STATUS; /* pause */
325 BT_CONTROL(BT_B2H_ATN); /* som 308 BT_CONTROL(BT_B2H_ATN); /* some BMCs are stubborn */
326 BT_CONTROL(BT_CLR_RD_PTR); /* alw 309 BT_CONTROL(BT_CLR_RD_PTR); /* always reset */
327 if (bt_debug) 310 if (bt_debug)
328 printk(KERN_WARNING "IPMI BT: 311 printk(KERN_WARNING "IPMI BT: stale response %s; ",
329 status2txt(BT_STATUS)) 312 status2txt(BT_STATUS));
330 size = BMC2HOST; 313 size = BMC2HOST;
331 for (i = 0; i < size ; i++) 314 for (i = 0; i < size ; i++)
332 BMC2HOST; 315 BMC2HOST;
333 BT_CONTROL(BT_H_BUSY); /* now 316 BT_CONTROL(BT_H_BUSY); /* now clear */
334 if (bt_debug) 317 if (bt_debug)
335 printk("drained %d bytes\n", s 318 printk("drained %d bytes\n", size + 1);
336 } 319 }
337 320
338 static inline void write_all_bytes(struct si_s 321 static inline void write_all_bytes(struct si_sm_data *bt)
339 { 322 {
340 int i; 323 int i;
341 324
342 if (bt_debug & BT_DEBUG_MSG) { 325 if (bt_debug & BT_DEBUG_MSG) {
343 printk(KERN_WARNING "BT: write 326 printk(KERN_WARNING "BT: write %d bytes seq=0x%02X",
344 bt->write_count, bt->s 327 bt->write_count, bt->seq);
345 for (i = 0; i < bt->write_coun 328 for (i = 0; i < bt->write_count; i++)
346 printk(" %02x", bt->wr !! 329 printk (" %02x", bt->write_data[i]);
347 printk("\n"); !! 330 printk ("\n");
348 } 331 }
349 for (i = 0; i < bt->write_count; i++) 332 for (i = 0; i < bt->write_count; i++)
350 HOST2BMC(bt->write_data[i]); 333 HOST2BMC(bt->write_data[i]);
351 } 334 }
352 335
353 static inline int read_all_bytes(struct si_sm_ 336 static inline int read_all_bytes(struct si_sm_data *bt)
354 { 337 {
355 unsigned char i; 338 unsigned char i;
356 339
357 /* !! 340 /* length is "framing info", minimum = 4: NetFn, Seq, Cmd, cCode.
358 * length is "framing info", minimum = !! 341 Keep layout of first four bytes aligned with write_data[] */
359 * Keep layout of first four bytes ali <<
360 */ <<
361 342
362 bt->read_data[0] = BMC2HOST; 343 bt->read_data[0] = BMC2HOST;
363 bt->read_count = bt->read_data[0]; 344 bt->read_count = bt->read_data[0];
364 345
365 if (bt->read_count < 4 || bt->read_cou 346 if (bt->read_count < 4 || bt->read_count >= IPMI_MAX_MSG_LENGTH) {
366 if (bt_debug & BT_DEBUG_MSG) 347 if (bt_debug & BT_DEBUG_MSG)
367 printk(KERN_WARNING "B 348 printk(KERN_WARNING "BT: bad raw rsp len=%d\n",
368 bt->read_count 349 bt->read_count);
369 bt->truncated = 1; 350 bt->truncated = 1;
370 return 1; /* let next XA 351 return 1; /* let next XACTION START clean it up */
371 } 352 }
372 for (i = 1; i <= bt->read_count; i++) 353 for (i = 1; i <= bt->read_count; i++)
373 bt->read_data[i] = BMC2HOST; 354 bt->read_data[i] = BMC2HOST;
374 bt->read_count++; /* Account int 355 bt->read_count++; /* Account internally for length byte */
375 356
376 if (bt_debug & BT_DEBUG_MSG) { 357 if (bt_debug & BT_DEBUG_MSG) {
377 int max = bt->read_count; 358 int max = bt->read_count;
378 359
379 printk(KERN_WARNING "BT: got % 360 printk(KERN_WARNING "BT: got %d bytes seq=0x%02X",
380 max, bt->read_data[2]) 361 max, bt->read_data[2]);
381 if (max > 16) 362 if (max > 16)
382 max = 16; 363 max = 16;
383 for (i = 0; i < max; i++) 364 for (i = 0; i < max; i++)
384 printk(KERN_CONT " %02 !! 365 printk (" %02x", bt->read_data[i]);
385 printk(KERN_CONT "%s\n", bt->r !! 366 printk ("%s\n", bt->read_count == max ? "" : " ...");
386 } 367 }
387 368
388 /* per the spec, the (NetFn[1], Seq[2] 369 /* per the spec, the (NetFn[1], Seq[2], Cmd[3]) tuples must match */
389 if ((bt->read_data[3] == bt->write_dat 370 if ((bt->read_data[3] == bt->write_data[3]) &&
390 (bt->read_data[2] == bt->write_dat 371 (bt->read_data[2] == bt->write_data[2]) &&
391 ((bt->read_data[1] & 0xF8) == (bt- 372 ((bt->read_data[1] & 0xF8) == (bt->write_data[1] & 0xF8)))
392 return 1; 373 return 1;
393 374
394 if (bt_debug & BT_DEBUG_MSG) 375 if (bt_debug & BT_DEBUG_MSG)
395 printk(KERN_WARNING "IPMI BT: 376 printk(KERN_WARNING "IPMI BT: bad packet: "
396 "want 0x(%02X, %02X, %02X) got 377 "want 0x(%02X, %02X, %02X) got (%02X, %02X, %02X)\n",
397 bt->write_data[1] | 0x04, bt-> 378 bt->write_data[1] | 0x04, bt->write_data[2], bt->write_data[3],
398 bt->read_data[1], bt->read_da 379 bt->read_data[1], bt->read_data[2], bt->read_data[3]);
399 return 0; 380 return 0;
400 } 381 }
401 382
402 /* Restart if retries are left, or return an e 383 /* Restart if retries are left, or return an error completion code */
403 384
404 static enum si_sm_result error_recovery(struct 385 static enum si_sm_result error_recovery(struct si_sm_data *bt,
405 unsign 386 unsigned char status,
406 unsign 387 unsigned char cCode)
407 { 388 {
408 char *reason; 389 char *reason;
409 390
410 bt->timeout = bt->BT_CAP_req2rsp; 391 bt->timeout = bt->BT_CAP_req2rsp;
411 392
412 switch (cCode) { 393 switch (cCode) {
413 case IPMI_TIMEOUT_ERR: 394 case IPMI_TIMEOUT_ERR:
414 reason = "timeout"; 395 reason = "timeout";
415 break; 396 break;
416 default: 397 default:
417 reason = "internal error"; 398 reason = "internal error";
418 break; 399 break;
419 } 400 }
420 401
421 printk(KERN_WARNING "IPMI BT: %s in %s 402 printk(KERN_WARNING "IPMI BT: %s in %s %s ", /* open-ended line */
422 reason, STATE2TXT, STATUS2TXT) 403 reason, STATE2TXT, STATUS2TXT);
423 404
424 /* !! 405 /* Per the IPMI spec, retries are based on the sequence number
425 * Per the IPMI spec, retries are base !! 406 known only to this module, so manage a restart here. */
426 * known only to this module, so manag <<
427 */ <<
428 (bt->error_retries)++; 407 (bt->error_retries)++;
429 if (bt->error_retries < bt->BT_CAP_ret 408 if (bt->error_retries < bt->BT_CAP_retries) {
430 printk("%d retries left\n", 409 printk("%d retries left\n",
431 bt->BT_CAP_retries - b 410 bt->BT_CAP_retries - bt->error_retries);
432 bt->state = BT_STATE_RESTART; 411 bt->state = BT_STATE_RESTART;
433 return SI_SM_CALL_WITHOUT_DELA 412 return SI_SM_CALL_WITHOUT_DELAY;
434 } 413 }
435 414
436 printk(KERN_WARNING "failed %d retries !! 415 printk("failed %d retries, sending error response\n",
437 bt->BT_CAP_retries); !! 416 bt->BT_CAP_retries);
438 if (!bt->nonzero_status) 417 if (!bt->nonzero_status)
439 printk(KERN_ERR "IPMI BT: stuc 418 printk(KERN_ERR "IPMI BT: stuck, try power cycle\n");
440 419
441 /* this is most likely during insmod * 420 /* this is most likely during insmod */
442 else if (bt->seq <= (unsigned char)(bt 421 else if (bt->seq <= (unsigned char)(bt->BT_CAP_retries & 0xFF)) {
443 printk(KERN_WARNING "IPMI: BT 422 printk(KERN_WARNING "IPMI: BT reset (takes 5 secs)\n");
444 bt->state = BT_STATE_RESET1; 423 bt->state = BT_STATE_RESET1;
445 return SI_SM_CALL_WITHOUT_DELA 424 return SI_SM_CALL_WITHOUT_DELAY;
446 } 425 }
447 426
448 /* !! 427 /* Concoct a useful error message, set up the next state, and
449 * Concoct a useful error message, set !! 428 be done with this sequence. */
450 * be done with this sequence. <<
451 */ <<
452 429
453 bt->state = BT_STATE_IDLE; 430 bt->state = BT_STATE_IDLE;
454 switch (cCode) { 431 switch (cCode) {
455 case IPMI_TIMEOUT_ERR: 432 case IPMI_TIMEOUT_ERR:
456 if (status & BT_B_BUSY) { 433 if (status & BT_B_BUSY) {
457 cCode = IPMI_NODE_BUSY 434 cCode = IPMI_NODE_BUSY_ERR;
458 bt->state = BT_STATE_L 435 bt->state = BT_STATE_LONG_BUSY;
459 } 436 }
460 break; 437 break;
461 default: 438 default:
462 break; 439 break;
463 } 440 }
464 force_result(bt, cCode); 441 force_result(bt, cCode);
465 return SI_SM_TRANSACTION_COMPLETE; 442 return SI_SM_TRANSACTION_COMPLETE;
466 } 443 }
467 444
468 /* Check status and (usually) take action and 445 /* Check status and (usually) take action and change this state machine. */
469 446
470 static enum si_sm_result bt_event(struct si_sm 447 static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
471 { 448 {
472 unsigned char status, BT_CAP[8]; 449 unsigned char status, BT_CAP[8];
473 static enum bt_states last_printed = B 450 static enum bt_states last_printed = BT_STATE_PRINTME;
474 int i; 451 int i;
475 452
476 status = BT_STATUS; 453 status = BT_STATUS;
477 bt->nonzero_status |= status; 454 bt->nonzero_status |= status;
478 if ((bt_debug & BT_DEBUG_STATES) && (b 455 if ((bt_debug & BT_DEBUG_STATES) && (bt->state != last_printed)) {
479 printk(KERN_WARNING "BT: %s %s 456 printk(KERN_WARNING "BT: %s %s TO=%ld - %ld \n",
480 STATE2TXT, 457 STATE2TXT,
481 STATUS2TXT, 458 STATUS2TXT,
482 bt->timeout, 459 bt->timeout,
483 time); 460 time);
484 last_printed = bt->state; 461 last_printed = bt->state;
485 } 462 }
486 463
487 /* !! 464 /* Commands that time out may still (eventually) provide a response.
488 * Commands that time out may still (e !! 465 This stale response will get in the way of a new response so remove
489 * This stale response will get in the !! 466 it if possible (hopefully during IDLE). Even if it comes up later
490 * it if possible (hopefully during ID !! 467 it will be rejected by its (now-forgotten) seq number. */
491 * it will be rejected by its (now-for <<
492 */ <<
493 468
494 if ((bt->state < BT_STATE_WRITE_BYTES) 469 if ((bt->state < BT_STATE_WRITE_BYTES) && (status & BT_B2H_ATN)) {
495 drain_BMC2HOST(bt); 470 drain_BMC2HOST(bt);
496 BT_SI_SM_RETURN(SI_SM_CALL_WIT 471 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
497 } 472 }
498 473
499 if ((bt->state != BT_STATE_IDLE) && 474 if ((bt->state != BT_STATE_IDLE) &&
500 (bt->state < BT_STATE_PRINTME)) { !! 475 (bt->state < BT_STATE_PRINTME)) { /* check timeout */
501 /* check timeout */ <<
502 bt->timeout -= time; 476 bt->timeout -= time;
503 if ((bt->timeout < 0) && (bt-> 477 if ((bt->timeout < 0) && (bt->state < BT_STATE_RESET1))
504 return error_recovery( 478 return error_recovery(bt,
505 479 status,
506 480 IPMI_TIMEOUT_ERR);
507 } 481 }
508 482
509 switch (bt->state) { 483 switch (bt->state) {
510 484
511 /* !! 485 /* Idle state first checks for asynchronous messages from another
512 * Idle state first checks for asynchr !! 486 channel, then does some opportunistic housekeeping. */
513 * channel, then does some opportunist <<
514 */ <<
515 487
516 case BT_STATE_IDLE: 488 case BT_STATE_IDLE:
517 if (status & BT_SMS_ATN) { 489 if (status & BT_SMS_ATN) {
518 BT_CONTROL(BT_SMS_ATN) 490 BT_CONTROL(BT_SMS_ATN); /* clear it */
519 return SI_SM_ATTN; 491 return SI_SM_ATTN;
520 } 492 }
521 493
522 if (status & BT_H_BUSY) 494 if (status & BT_H_BUSY) /* clear a leftover H_BUSY */
523 BT_CONTROL(BT_H_BUSY); 495 BT_CONTROL(BT_H_BUSY);
524 496
525 /* Read BT capabilities if it 497 /* Read BT capabilities if it hasn't been done yet */
526 if (!bt->BT_CAP_outreqs) 498 if (!bt->BT_CAP_outreqs)
527 BT_STATE_CHANGE(BT_STA 499 BT_STATE_CHANGE(BT_STATE_CAPABILITIES_BEGIN,
528 SI_SM_ 500 SI_SM_CALL_WITHOUT_DELAY);
529 bt->timeout = bt->BT_CAP_req2r 501 bt->timeout = bt->BT_CAP_req2rsp;
530 BT_SI_SM_RETURN(SI_SM_IDLE); 502 BT_SI_SM_RETURN(SI_SM_IDLE);
531 503
532 case BT_STATE_XACTION_START: 504 case BT_STATE_XACTION_START:
533 if (status & (BT_B_BUSY | BT_H 505 if (status & (BT_B_BUSY | BT_H2B_ATN))
534 BT_SI_SM_RETURN(SI_SM_ 506 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
535 if (BT_STATUS & BT_H_BUSY) 507 if (BT_STATUS & BT_H_BUSY)
536 BT_CONTROL(BT_H_BUSY); 508 BT_CONTROL(BT_H_BUSY); /* force clear */
537 BT_STATE_CHANGE(BT_STATE_WRITE 509 BT_STATE_CHANGE(BT_STATE_WRITE_BYTES,
538 SI_SM_CALL_WIT 510 SI_SM_CALL_WITHOUT_DELAY);
539 511
540 case BT_STATE_WRITE_BYTES: 512 case BT_STATE_WRITE_BYTES:
541 if (status & BT_H_BUSY) 513 if (status & BT_H_BUSY)
542 BT_CONTROL(BT_H_BUSY); 514 BT_CONTROL(BT_H_BUSY); /* clear */
543 BT_CONTROL(BT_CLR_WR_PTR); 515 BT_CONTROL(BT_CLR_WR_PTR);
544 write_all_bytes(bt); 516 write_all_bytes(bt);
545 BT_CONTROL(BT_H2B_ATN); /* can 517 BT_CONTROL(BT_H2B_ATN); /* can clear too fast to catch */
546 BT_STATE_CHANGE(BT_STATE_WRITE 518 BT_STATE_CHANGE(BT_STATE_WRITE_CONSUME,
547 SI_SM_CALL_WIT 519 SI_SM_CALL_WITHOUT_DELAY);
548 520
549 case BT_STATE_WRITE_CONSUME: 521 case BT_STATE_WRITE_CONSUME:
550 if (status & (BT_B_BUSY | BT_H 522 if (status & (BT_B_BUSY | BT_H2B_ATN))
551 BT_SI_SM_RETURN(SI_SM_ 523 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
552 BT_STATE_CHANGE(BT_STATE_READ_ 524 BT_STATE_CHANGE(BT_STATE_READ_WAIT,
553 SI_SM_CALL_WIT 525 SI_SM_CALL_WITHOUT_DELAY);
554 526
555 /* Spinning hard can suppress B2H_ATN 527 /* Spinning hard can suppress B2H_ATN and force a timeout */
556 528
557 case BT_STATE_READ_WAIT: 529 case BT_STATE_READ_WAIT:
558 if (!(status & BT_B2H_ATN)) 530 if (!(status & BT_B2H_ATN))
559 BT_SI_SM_RETURN(SI_SM_ 531 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
560 BT_CONTROL(BT_H_BUSY); 532 BT_CONTROL(BT_H_BUSY); /* set */
561 533
562 /* !! 534 /* Uncached, ordered writes should just proceeed serially but
563 * Uncached, ordered writes sh !! 535 some BMCs don't clear B2H_ATN with one hit. Fast-path a
564 * some BMCs don't clear B2H_A !! 536 workaround without too much penalty to the general case. */
565 * workaround without too much <<
566 */ <<
567 537
568 BT_CONTROL(BT_B2H_ATN); 538 BT_CONTROL(BT_B2H_ATN); /* clear it to ACK the BMC */
569 BT_STATE_CHANGE(BT_STATE_CLEAR 539 BT_STATE_CHANGE(BT_STATE_CLEAR_B2H,
570 SI_SM_CALL_WIT 540 SI_SM_CALL_WITHOUT_DELAY);
571 541
572 case BT_STATE_CLEAR_B2H: 542 case BT_STATE_CLEAR_B2H:
573 if (status & BT_B2H_ATN) { !! 543 if (status & BT_B2H_ATN) { /* keep hitting it */
574 /* keep hitting it */ <<
575 BT_CONTROL(BT_B2H_ATN) 544 BT_CONTROL(BT_B2H_ATN);
576 BT_SI_SM_RETURN(SI_SM_ 545 BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY);
577 } 546 }
578 BT_STATE_CHANGE(BT_STATE_READ_ 547 BT_STATE_CHANGE(BT_STATE_READ_BYTES,
579 SI_SM_CALL_WIT 548 SI_SM_CALL_WITHOUT_DELAY);
580 549
581 case BT_STATE_READ_BYTES: 550 case BT_STATE_READ_BYTES:
582 if (!(status & BT_H_BUSY)) !! 551 if (!(status & BT_H_BUSY)) /* check in case of retry */
583 /* check in case of re <<
584 BT_CONTROL(BT_H_BUSY); 552 BT_CONTROL(BT_H_BUSY);
585 BT_CONTROL(BT_CLR_RD_PTR); 553 BT_CONTROL(BT_CLR_RD_PTR); /* start of BMC2HOST buffer */
586 i = read_all_bytes(bt); 554 i = read_all_bytes(bt); /* true == packet seq match */
587 BT_CONTROL(BT_H_BUSY); 555 BT_CONTROL(BT_H_BUSY); /* NOW clear */
588 if (!i) 556 if (!i) /* Not my message */
589 BT_STATE_CHANGE(BT_STA 557 BT_STATE_CHANGE(BT_STATE_READ_WAIT,
590 SI_SM_ 558 SI_SM_CALL_WITHOUT_DELAY);
591 bt->state = bt->complete; 559 bt->state = bt->complete;
592 return bt->state == BT_STATE_I 560 return bt->state == BT_STATE_IDLE ? /* where to next? */
593 SI_SM_TRANSACTION_COMP 561 SI_SM_TRANSACTION_COMPLETE : /* normal */
594 SI_SM_CALL_WITHOUT_DEL 562 SI_SM_CALL_WITHOUT_DELAY; /* Startup magic */
595 563
596 case BT_STATE_LONG_BUSY: /* For 564 case BT_STATE_LONG_BUSY: /* For example: after FW update */
597 if (!(status & BT_B_BUSY)) { 565 if (!(status & BT_B_BUSY)) {
598 reset_flags(bt); 566 reset_flags(bt); /* next state is now IDLE */
599 bt_init_data(bt, bt->i 567 bt_init_data(bt, bt->io);
600 } 568 }
601 return SI_SM_CALL_WITH_DELAY; 569 return SI_SM_CALL_WITH_DELAY; /* No repeat printing */
602 570
603 case BT_STATE_RESET1: 571 case BT_STATE_RESET1:
604 reset_flags(bt); 572 reset_flags(bt);
605 drain_BMC2HOST(bt); 573 drain_BMC2HOST(bt);
606 BT_STATE_CHANGE(BT_STATE_RESET 574 BT_STATE_CHANGE(BT_STATE_RESET2,
607 SI_SM_CALL_WIT 575 SI_SM_CALL_WITH_DELAY);
608 576
609 case BT_STATE_RESET2: /* Sen 577 case BT_STATE_RESET2: /* Send a soft reset */
610 BT_CONTROL(BT_CLR_WR_PTR); 578 BT_CONTROL(BT_CLR_WR_PTR);
611 HOST2BMC(3); /* num 579 HOST2BMC(3); /* number of bytes following */
612 HOST2BMC(0x18); /* Net 580 HOST2BMC(0x18); /* NetFn/LUN == Application, LUN 0 */
613 HOST2BMC(42); /* Seq 581 HOST2BMC(42); /* Sequence number */
614 HOST2BMC(3); /* Cmd 582 HOST2BMC(3); /* Cmd == Soft reset */
615 BT_CONTROL(BT_H2B_ATN); 583 BT_CONTROL(BT_H2B_ATN);
616 bt->timeout = BT_RESET_DELAY * 584 bt->timeout = BT_RESET_DELAY * 1000000;
617 BT_STATE_CHANGE(BT_STATE_RESET 585 BT_STATE_CHANGE(BT_STATE_RESET3,
618 SI_SM_CALL_WIT 586 SI_SM_CALL_WITH_DELAY);
619 587
620 case BT_STATE_RESET3: /* Hol 588 case BT_STATE_RESET3: /* Hold off everything for a bit */
621 if (bt->timeout > 0) 589 if (bt->timeout > 0)
622 return SI_SM_CALL_WITH 590 return SI_SM_CALL_WITH_DELAY;
623 drain_BMC2HOST(bt); 591 drain_BMC2HOST(bt);
624 BT_STATE_CHANGE(BT_STATE_RESTA 592 BT_STATE_CHANGE(BT_STATE_RESTART,
625 SI_SM_CALL_WIT 593 SI_SM_CALL_WITH_DELAY);
626 594
627 case BT_STATE_RESTART: /* don 595 case BT_STATE_RESTART: /* don't reset retries or seq! */
628 bt->read_count = 0; 596 bt->read_count = 0;
629 bt->nonzero_status = 0; 597 bt->nonzero_status = 0;
630 bt->timeout = bt->BT_CAP_req2r 598 bt->timeout = bt->BT_CAP_req2rsp;
631 BT_STATE_CHANGE(BT_STATE_XACTI 599 BT_STATE_CHANGE(BT_STATE_XACTION_START,
632 SI_SM_CALL_WIT 600 SI_SM_CALL_WITH_DELAY);
633 601
634 /* !! 602 /* Get BT Capabilities, using timing of upper level state machine.
635 * Get BT Capabilities, using timing o !! 603 Set outreqs to prevent infinite loop on timeout. */
636 * Set outreqs to prevent infinite loo <<
637 */ <<
638 case BT_STATE_CAPABILITIES_BEGIN: 604 case BT_STATE_CAPABILITIES_BEGIN:
639 bt->BT_CAP_outreqs = 1; 605 bt->BT_CAP_outreqs = 1;
640 { 606 {
641 unsigned char GetBT_CA 607 unsigned char GetBT_CAP[] = { 0x18, 0x36 };
642 bt->state = BT_STATE_I 608 bt->state = BT_STATE_IDLE;
643 bt_start_transaction(b 609 bt_start_transaction(bt, GetBT_CAP, sizeof(GetBT_CAP));
644 } 610 }
645 bt->complete = BT_STATE_CAPABI 611 bt->complete = BT_STATE_CAPABILITIES_END;
646 BT_STATE_CHANGE(BT_STATE_XACTI 612 BT_STATE_CHANGE(BT_STATE_XACTION_START,
647 SI_SM_CALL_WIT 613 SI_SM_CALL_WITH_DELAY);
648 614
649 case BT_STATE_CAPABILITIES_END: 615 case BT_STATE_CAPABILITIES_END:
650 i = bt_get_result(bt, BT_CAP, 616 i = bt_get_result(bt, BT_CAP, sizeof(BT_CAP));
651 bt_init_data(bt, bt->io); 617 bt_init_data(bt, bt->io);
652 if ((i == 8) && !BT_CAP[2]) { 618 if ((i == 8) && !BT_CAP[2]) {
653 bt->BT_CAP_outreqs = B 619 bt->BT_CAP_outreqs = BT_CAP[3];
654 bt->BT_CAP_req2rsp = B 620 bt->BT_CAP_req2rsp = BT_CAP[6] * 1000000;
655 bt->BT_CAP_retries = B 621 bt->BT_CAP_retries = BT_CAP[7];
656 } else 622 } else
657 printk(KERN_WARNING "I 623 printk(KERN_WARNING "IPMI BT: using default values\n");
658 if (!bt->BT_CAP_outreqs) 624 if (!bt->BT_CAP_outreqs)
659 bt->BT_CAP_outreqs = 1 625 bt->BT_CAP_outreqs = 1;
660 printk(KERN_WARNING "IPMI BT: 626 printk(KERN_WARNING "IPMI BT: req2rsp=%ld secs retries=%d\n",
661 bt->BT_CAP_req2rsp / 1 627 bt->BT_CAP_req2rsp / 1000000L, bt->BT_CAP_retries);
662 bt->timeout = bt->BT_CAP_req2r 628 bt->timeout = bt->BT_CAP_req2rsp;
663 return SI_SM_CALL_WITHOUT_DELA 629 return SI_SM_CALL_WITHOUT_DELAY;
664 630
665 default: /* should never occur 631 default: /* should never occur */
666 return error_recovery(bt, 632 return error_recovery(bt,
667 status, 633 status,
668 IPMI_ERR 634 IPMI_ERR_UNSPECIFIED);
669 } 635 }
670 return SI_SM_CALL_WITH_DELAY; 636 return SI_SM_CALL_WITH_DELAY;
671 } 637 }
672 638
673 static int bt_detect(struct si_sm_data *bt) 639 static int bt_detect(struct si_sm_data *bt)
674 { 640 {
675 /* !! 641 /* It's impossible for the BT status and interrupt registers to be
676 * It's impossible for the BT status a !! 642 all 1's, (assuming a properly functioning, self-initialized BMC)
677 * all 1's, (assuming a properly funct !! 643 but that's what you get from reading a bogus address, so we
678 * but that's what you get from readin !! 644 test that first. The calling routine uses negative logic. */
679 * test that first. The calling routi <<
680 */ <<
681 645
682 if ((BT_STATUS == 0xFF) && (BT_INTMASK 646 if ((BT_STATUS == 0xFF) && (BT_INTMASK_R == 0xFF))
683 return 1; 647 return 1;
684 reset_flags(bt); 648 reset_flags(bt);
685 return 0; 649 return 0;
686 } 650 }
687 651
688 static void bt_cleanup(struct si_sm_data *bt) 652 static void bt_cleanup(struct si_sm_data *bt)
689 { 653 {
690 } 654 }
691 655
692 static int bt_size(void) 656 static int bt_size(void)
693 { 657 {
694 return sizeof(struct si_sm_data); 658 return sizeof(struct si_sm_data);
695 } 659 }
696 660
697 struct si_sm_handlers bt_smi_handlers = { !! 661 struct si_sm_handlers bt_smi_handlers =
>> 662 {
698 .init_data = bt_init_data 663 .init_data = bt_init_data,
699 .start_transaction = bt_start_tra 664 .start_transaction = bt_start_transaction,
700 .get_result = bt_get_resul 665 .get_result = bt_get_result,
701 .event = bt_event, 666 .event = bt_event,
702 .detect = bt_detect, 667 .detect = bt_detect,
703 .cleanup = bt_cleanup, 668 .cleanup = bt_cleanup,
704 .size = bt_size, 669 .size = bt_size,
705 }; 670 };
706 671
|
This page was automatically generated by the
LXR engine.
|