/drivers/char/ipmi/ipmi_smic_sm.c

https://bitbucket.org/evzijst/gittest · C · 599 lines · 455 code · 54 blank · 90 comment · 70 complexity · 7b9054923c2c507b8b867d6a60ef0cb3 MD5 · raw file

  1. /*
  2. * ipmi_smic_sm.c
  3. *
  4. * The state-machine driver for an IPMI SMIC driver
  5. *
  6. * It started as a copy of Corey Minyard's driver for the KSC interface
  7. * and the kernel patch "mmcdev-patch-245" by HP
  8. *
  9. * modified by: Hannes Schulz <schulz@schwaar.com>
  10. * ipmi@schwaar.com
  11. *
  12. *
  13. * Corey Minyard's driver for the KSC interface has the following
  14. * copyright notice:
  15. * Copyright 2002 MontaVista Software Inc.
  16. *
  17. * the kernel patch "mmcdev-patch-245" by HP has the following
  18. * copyright notice:
  19. * (c) Copyright 2001 Grant Grundler (c) Copyright
  20. * 2001 Hewlett-Packard Company
  21. *
  22. *
  23. * This program is free software; you can redistribute it and/or modify it
  24. * under the terms of the GNU General Public License as published by the
  25. * Free Software Foundation; either version 2 of the License, or (at your
  26. * option) any later version.
  27. *
  28. *
  29. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  30. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  31. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  32. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  33. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  34. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  35. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  36. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
  37. * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  38. * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  39. *
  40. * You should have received a copy of the GNU General Public License along
  41. * with this program; if not, write to the Free Software Foundation, Inc.,
  42. * 675 Mass Ave, Cambridge, MA 02139, USA. */
  43. #include <linux/kernel.h> /* For printk. */
  44. #include <linux/string.h>
  45. #include <linux/ipmi_msgdefs.h> /* for completion codes */
  46. #include "ipmi_si_sm.h"
  47. #define IPMI_SMIC_VERSION "v33"
  48. /* smic_debug is a bit-field
  49. * SMIC_DEBUG_ENABLE - turned on for now
  50. * SMIC_DEBUG_MSG - commands and their responses
  51. * SMIC_DEBUG_STATES - state machine
  52. */
  53. #define SMIC_DEBUG_STATES 4
  54. #define SMIC_DEBUG_MSG 2
  55. #define SMIC_DEBUG_ENABLE 1
  56. static int smic_debug = 1;
  57. enum smic_states {
  58. SMIC_IDLE,
  59. SMIC_START_OP,
  60. SMIC_OP_OK,
  61. SMIC_WRITE_START,
  62. SMIC_WRITE_NEXT,
  63. SMIC_WRITE_END,
  64. SMIC_WRITE2READ,
  65. SMIC_READ_START,
  66. SMIC_READ_NEXT,
  67. SMIC_READ_END,
  68. SMIC_HOSED
  69. };
  70. #define MAX_SMIC_READ_SIZE 80
  71. #define MAX_SMIC_WRITE_SIZE 80
  72. #define SMIC_MAX_ERROR_RETRIES 3
  73. /* Timeouts in microseconds. */
  74. #define SMIC_RETRY_TIMEOUT 100000
  75. /* SMIC Flags Register Bits */
  76. #define SMIC_RX_DATA_READY 0x80
  77. #define SMIC_TX_DATA_READY 0x40
  78. #define SMIC_SMI 0x10
  79. #define SMIC_EVM_DATA_AVAIL 0x08
  80. #define SMIC_SMS_DATA_AVAIL 0x04
  81. #define SMIC_FLAG_BSY 0x01
  82. /* SMIC Error Codes */
  83. #define EC_NO_ERROR 0x00
  84. #define EC_ABORTED 0x01
  85. #define EC_ILLEGAL_CONTROL 0x02
  86. #define EC_NO_RESPONSE 0x03
  87. #define EC_ILLEGAL_COMMAND 0x04
  88. #define EC_BUFFER_FULL 0x05
  89. struct si_sm_data
  90. {
  91. enum smic_states state;
  92. struct si_sm_io *io;
  93. unsigned char write_data[MAX_SMIC_WRITE_SIZE];
  94. int write_pos;
  95. int write_count;
  96. int orig_write_count;
  97. unsigned char read_data[MAX_SMIC_READ_SIZE];
  98. int read_pos;
  99. int truncated;
  100. unsigned int error_retries;
  101. long smic_timeout;
  102. };
  103. static unsigned int init_smic_data (struct si_sm_data *smic,
  104. struct si_sm_io *io)
  105. {
  106. smic->state = SMIC_IDLE;
  107. smic->io = io;
  108. smic->write_pos = 0;
  109. smic->write_count = 0;
  110. smic->orig_write_count = 0;
  111. smic->read_pos = 0;
  112. smic->error_retries = 0;
  113. smic->truncated = 0;
  114. smic->smic_timeout = SMIC_RETRY_TIMEOUT;
  115. /* We use 3 bytes of I/O. */
  116. return 3;
  117. }
  118. static int start_smic_transaction(struct si_sm_data *smic,
  119. unsigned char *data, unsigned int size)
  120. {
  121. unsigned int i;
  122. if ((size < 2) || (size > MAX_SMIC_WRITE_SIZE)) {
  123. return -1;
  124. }
  125. if ((smic->state != SMIC_IDLE) && (smic->state != SMIC_HOSED)) {
  126. return -2;
  127. }
  128. if (smic_debug & SMIC_DEBUG_MSG) {
  129. printk(KERN_INFO "start_smic_transaction -");
  130. for (i = 0; i < size; i ++) {
  131. printk (" %02x", (unsigned char) (data [i]));
  132. }
  133. printk ("\n");
  134. }
  135. smic->error_retries = 0;
  136. memcpy(smic->write_data, data, size);
  137. smic->write_count = size;
  138. smic->orig_write_count = size;
  139. smic->write_pos = 0;
  140. smic->read_pos = 0;
  141. smic->state = SMIC_START_OP;
  142. smic->smic_timeout = SMIC_RETRY_TIMEOUT;
  143. return 0;
  144. }
  145. static int smic_get_result(struct si_sm_data *smic,
  146. unsigned char *data, unsigned int length)
  147. {
  148. int i;
  149. if (smic_debug & SMIC_DEBUG_MSG) {
  150. printk (KERN_INFO "smic_get result -");
  151. for (i = 0; i < smic->read_pos; i ++) {
  152. printk (" %02x", (smic->read_data [i]));
  153. }
  154. printk ("\n");
  155. }
  156. if (length < smic->read_pos) {
  157. smic->read_pos = length;
  158. smic->truncated = 1;
  159. }
  160. memcpy(data, smic->read_data, smic->read_pos);
  161. if ((length >= 3) && (smic->read_pos < 3)) {
  162. data[2] = IPMI_ERR_UNSPECIFIED;
  163. smic->read_pos = 3;
  164. }
  165. if (smic->truncated) {
  166. data[2] = IPMI_ERR_MSG_TRUNCATED;
  167. smic->truncated = 0;
  168. }
  169. return smic->read_pos;
  170. }
  171. static inline unsigned char read_smic_flags(struct si_sm_data *smic)
  172. {
  173. return smic->io->inputb(smic->io, 2);
  174. }
  175. static inline unsigned char read_smic_status(struct si_sm_data *smic)
  176. {
  177. return smic->io->inputb(smic->io, 1);
  178. }
  179. static inline unsigned char read_smic_data(struct si_sm_data *smic)
  180. {
  181. return smic->io->inputb(smic->io, 0);
  182. }
  183. static inline void write_smic_flags(struct si_sm_data *smic,
  184. unsigned char flags)
  185. {
  186. smic->io->outputb(smic->io, 2, flags);
  187. }
  188. static inline void write_smic_control(struct si_sm_data *smic,
  189. unsigned char control)
  190. {
  191. smic->io->outputb(smic->io, 1, control);
  192. }
  193. static inline void write_si_sm_data (struct si_sm_data *smic,
  194. unsigned char data)
  195. {
  196. smic->io->outputb(smic->io, 0, data);
  197. }
  198. static inline void start_error_recovery(struct si_sm_data *smic, char *reason)
  199. {
  200. (smic->error_retries)++;
  201. if (smic->error_retries > SMIC_MAX_ERROR_RETRIES) {
  202. if (smic_debug & SMIC_DEBUG_ENABLE) {
  203. printk(KERN_WARNING
  204. "ipmi_smic_drv: smic hosed: %s\n", reason);
  205. }
  206. smic->state = SMIC_HOSED;
  207. } else {
  208. smic->write_count = smic->orig_write_count;
  209. smic->write_pos = 0;
  210. smic->read_pos = 0;
  211. smic->state = SMIC_START_OP;
  212. smic->smic_timeout = SMIC_RETRY_TIMEOUT;
  213. }
  214. }
  215. static inline void write_next_byte(struct si_sm_data *smic)
  216. {
  217. write_si_sm_data(smic, smic->write_data[smic->write_pos]);
  218. (smic->write_pos)++;
  219. (smic->write_count)--;
  220. }
  221. static inline void read_next_byte (struct si_sm_data *smic)
  222. {
  223. if (smic->read_pos >= MAX_SMIC_READ_SIZE) {
  224. read_smic_data (smic);
  225. smic->truncated = 1;
  226. } else {
  227. smic->read_data[smic->read_pos] = read_smic_data(smic);
  228. (smic->read_pos)++;
  229. }
  230. }
  231. /* SMIC Control/Status Code Components */
  232. #define SMIC_GET_STATUS 0x00 /* Control form's name */
  233. #define SMIC_READY 0x00 /* Status form's name */
  234. #define SMIC_WR_START 0x01 /* Unified Control/Status names... */
  235. #define SMIC_WR_NEXT 0x02
  236. #define SMIC_WR_END 0x03
  237. #define SMIC_RD_START 0x04
  238. #define SMIC_RD_NEXT 0x05
  239. #define SMIC_RD_END 0x06
  240. #define SMIC_CODE_MASK 0x0f
  241. #define SMIC_CONTROL 0x00
  242. #define SMIC_STATUS 0x80
  243. #define SMIC_CS_MASK 0x80
  244. #define SMIC_SMS 0x40
  245. #define SMIC_SMM 0x60
  246. #define SMIC_STREAM_MASK 0x60
  247. /* SMIC Control Codes */
  248. #define SMIC_CC_SMS_GET_STATUS (SMIC_CONTROL|SMIC_SMS|SMIC_GET_STATUS)
  249. #define SMIC_CC_SMS_WR_START (SMIC_CONTROL|SMIC_SMS|SMIC_WR_START)
  250. #define SMIC_CC_SMS_WR_NEXT (SMIC_CONTROL|SMIC_SMS|SMIC_WR_NEXT)
  251. #define SMIC_CC_SMS_WR_END (SMIC_CONTROL|SMIC_SMS|SMIC_WR_END)
  252. #define SMIC_CC_SMS_RD_START (SMIC_CONTROL|SMIC_SMS|SMIC_RD_START)
  253. #define SMIC_CC_SMS_RD_NEXT (SMIC_CONTROL|SMIC_SMS|SMIC_RD_NEXT)
  254. #define SMIC_CC_SMS_RD_END (SMIC_CONTROL|SMIC_SMS|SMIC_RD_END)
  255. #define SMIC_CC_SMM_GET_STATUS (SMIC_CONTROL|SMIC_SMM|SMIC_GET_STATUS)
  256. #define SMIC_CC_SMM_WR_START (SMIC_CONTROL|SMIC_SMM|SMIC_WR_START)
  257. #define SMIC_CC_SMM_WR_NEXT (SMIC_CONTROL|SMIC_SMM|SMIC_WR_NEXT)
  258. #define SMIC_CC_SMM_WR_END (SMIC_CONTROL|SMIC_SMM|SMIC_WR_END)
  259. #define SMIC_CC_SMM_RD_START (SMIC_CONTROL|SMIC_SMM|SMIC_RD_START)
  260. #define SMIC_CC_SMM_RD_NEXT (SMIC_CONTROL|SMIC_SMM|SMIC_RD_NEXT)
  261. #define SMIC_CC_SMM_RD_END (SMIC_CONTROL|SMIC_SMM|SMIC_RD_END)
  262. /* SMIC Status Codes */
  263. #define SMIC_SC_SMS_READY (SMIC_STATUS|SMIC_SMS|SMIC_READY)
  264. #define SMIC_SC_SMS_WR_START (SMIC_STATUS|SMIC_SMS|SMIC_WR_START)
  265. #define SMIC_SC_SMS_WR_NEXT (SMIC_STATUS|SMIC_SMS|SMIC_WR_NEXT)
  266. #define SMIC_SC_SMS_WR_END (SMIC_STATUS|SMIC_SMS|SMIC_WR_END)
  267. #define SMIC_SC_SMS_RD_START (SMIC_STATUS|SMIC_SMS|SMIC_RD_START)
  268. #define SMIC_SC_SMS_RD_NEXT (SMIC_STATUS|SMIC_SMS|SMIC_RD_NEXT)
  269. #define SMIC_SC_SMS_RD_END (SMIC_STATUS|SMIC_SMS|SMIC_RD_END)
  270. #define SMIC_SC_SMM_READY (SMIC_STATUS|SMIC_SMM|SMIC_READY)
  271. #define SMIC_SC_SMM_WR_START (SMIC_STATUS|SMIC_SMM|SMIC_WR_START)
  272. #define SMIC_SC_SMM_WR_NEXT (SMIC_STATUS|SMIC_SMM|SMIC_WR_NEXT)
  273. #define SMIC_SC_SMM_WR_END (SMIC_STATUS|SMIC_SMM|SMIC_WR_END)
  274. #define SMIC_SC_SMM_RD_START (SMIC_STATUS|SMIC_SMM|SMIC_RD_START)
  275. #define SMIC_SC_SMM_RD_NEXT (SMIC_STATUS|SMIC_SMM|SMIC_RD_NEXT)
  276. #define SMIC_SC_SMM_RD_END (SMIC_STATUS|SMIC_SMM|SMIC_RD_END)
  277. /* these are the control/status codes we actually use
  278. SMIC_CC_SMS_GET_STATUS 0x40
  279. SMIC_CC_SMS_WR_START 0x41
  280. SMIC_CC_SMS_WR_NEXT 0x42
  281. SMIC_CC_SMS_WR_END 0x43
  282. SMIC_CC_SMS_RD_START 0x44
  283. SMIC_CC_SMS_RD_NEXT 0x45
  284. SMIC_CC_SMS_RD_END 0x46
  285. SMIC_SC_SMS_READY 0xC0
  286. SMIC_SC_SMS_WR_START 0xC1
  287. SMIC_SC_SMS_WR_NEXT 0xC2
  288. SMIC_SC_SMS_WR_END 0xC3
  289. SMIC_SC_SMS_RD_START 0xC4
  290. SMIC_SC_SMS_RD_NEXT 0xC5
  291. SMIC_SC_SMS_RD_END 0xC6
  292. */
  293. static enum si_sm_result smic_event (struct si_sm_data *smic, long time)
  294. {
  295. unsigned char status;
  296. unsigned char flags;
  297. unsigned char data;
  298. if (smic->state == SMIC_HOSED) {
  299. init_smic_data(smic, smic->io);
  300. return SI_SM_HOSED;
  301. }
  302. if (smic->state != SMIC_IDLE) {
  303. if (smic_debug & SMIC_DEBUG_STATES) {
  304. printk(KERN_INFO
  305. "smic_event - smic->smic_timeout = %ld,"
  306. " time = %ld\n",
  307. smic->smic_timeout, time);
  308. }
  309. /* FIXME: smic_event is sometimes called with time > SMIC_RETRY_TIMEOUT */
  310. if (time < SMIC_RETRY_TIMEOUT) {
  311. smic->smic_timeout -= time;
  312. if (smic->smic_timeout < 0) {
  313. start_error_recovery(smic, "smic timed out.");
  314. return SI_SM_CALL_WITH_DELAY;
  315. }
  316. }
  317. }
  318. flags = read_smic_flags(smic);
  319. if (flags & SMIC_FLAG_BSY)
  320. return SI_SM_CALL_WITH_DELAY;
  321. status = read_smic_status (smic);
  322. if (smic_debug & SMIC_DEBUG_STATES)
  323. printk(KERN_INFO
  324. "smic_event - state = %d, flags = 0x%02x,"
  325. " status = 0x%02x\n",
  326. smic->state, flags, status);
  327. switch (smic->state) {
  328. case SMIC_IDLE:
  329. /* in IDLE we check for available messages */
  330. if (flags & (SMIC_SMI |
  331. SMIC_EVM_DATA_AVAIL | SMIC_SMS_DATA_AVAIL))
  332. {
  333. return SI_SM_ATTN;
  334. }
  335. return SI_SM_IDLE;
  336. case SMIC_START_OP:
  337. /* sanity check whether smic is really idle */
  338. write_smic_control(smic, SMIC_CC_SMS_GET_STATUS);
  339. write_smic_flags(smic, flags | SMIC_FLAG_BSY);
  340. smic->state = SMIC_OP_OK;
  341. break;
  342. case SMIC_OP_OK:
  343. if (status != SMIC_SC_SMS_READY) {
  344. /* this should not happen */
  345. start_error_recovery(smic,
  346. "state = SMIC_OP_OK,"
  347. " status != SMIC_SC_SMS_READY");
  348. return SI_SM_CALL_WITH_DELAY;
  349. }
  350. /* OK so far; smic is idle let us start ... */
  351. write_smic_control(smic, SMIC_CC_SMS_WR_START);
  352. write_next_byte(smic);
  353. write_smic_flags(smic, flags | SMIC_FLAG_BSY);
  354. smic->state = SMIC_WRITE_START;
  355. break;
  356. case SMIC_WRITE_START:
  357. if (status != SMIC_SC_SMS_WR_START) {
  358. start_error_recovery(smic,
  359. "state = SMIC_WRITE_START, "
  360. "status != SMIC_SC_SMS_WR_START");
  361. return SI_SM_CALL_WITH_DELAY;
  362. }
  363. /* we must not issue WR_(NEXT|END) unless
  364. TX_DATA_READY is set */
  365. if (flags & SMIC_TX_DATA_READY) {
  366. if (smic->write_count == 1) {
  367. /* last byte */
  368. write_smic_control(smic, SMIC_CC_SMS_WR_END);
  369. smic->state = SMIC_WRITE_END;
  370. } else {
  371. write_smic_control(smic, SMIC_CC_SMS_WR_NEXT);
  372. smic->state = SMIC_WRITE_NEXT;
  373. }
  374. write_next_byte(smic);
  375. write_smic_flags(smic, flags | SMIC_FLAG_BSY);
  376. }
  377. else {
  378. return SI_SM_CALL_WITH_DELAY;
  379. }
  380. break;
  381. case SMIC_WRITE_NEXT:
  382. if (status != SMIC_SC_SMS_WR_NEXT) {
  383. start_error_recovery(smic,
  384. "state = SMIC_WRITE_NEXT, "
  385. "status != SMIC_SC_SMS_WR_NEXT");
  386. return SI_SM_CALL_WITH_DELAY;
  387. }
  388. /* this is the same code as in SMIC_WRITE_START */
  389. if (flags & SMIC_TX_DATA_READY) {
  390. if (smic->write_count == 1) {
  391. write_smic_control(smic, SMIC_CC_SMS_WR_END);
  392. smic->state = SMIC_WRITE_END;
  393. }
  394. else {
  395. write_smic_control(smic, SMIC_CC_SMS_WR_NEXT);
  396. smic->state = SMIC_WRITE_NEXT;
  397. }
  398. write_next_byte(smic);
  399. write_smic_flags(smic, flags | SMIC_FLAG_BSY);
  400. }
  401. else {
  402. return SI_SM_CALL_WITH_DELAY;
  403. }
  404. break;
  405. case SMIC_WRITE_END:
  406. if (status != SMIC_SC_SMS_WR_END) {
  407. start_error_recovery (smic,
  408. "state = SMIC_WRITE_END, "
  409. "status != SMIC_SC_SMS_WR_END");
  410. return SI_SM_CALL_WITH_DELAY;
  411. }
  412. /* data register holds an error code */
  413. data = read_smic_data(smic);
  414. if (data != 0) {
  415. if (smic_debug & SMIC_DEBUG_ENABLE) {
  416. printk(KERN_INFO
  417. "SMIC_WRITE_END: data = %02x\n", data);
  418. }
  419. start_error_recovery(smic,
  420. "state = SMIC_WRITE_END, "
  421. "data != SUCCESS");
  422. return SI_SM_CALL_WITH_DELAY;
  423. } else {
  424. smic->state = SMIC_WRITE2READ;
  425. }
  426. break;
  427. case SMIC_WRITE2READ:
  428. /* we must wait for RX_DATA_READY to be set before we
  429. can continue */
  430. if (flags & SMIC_RX_DATA_READY) {
  431. write_smic_control(smic, SMIC_CC_SMS_RD_START);
  432. write_smic_flags(smic, flags | SMIC_FLAG_BSY);
  433. smic->state = SMIC_READ_START;
  434. } else {
  435. return SI_SM_CALL_WITH_DELAY;
  436. }
  437. break;
  438. case SMIC_READ_START:
  439. if (status != SMIC_SC_SMS_RD_START) {
  440. start_error_recovery(smic,
  441. "state = SMIC_READ_START, "
  442. "status != SMIC_SC_SMS_RD_START");
  443. return SI_SM_CALL_WITH_DELAY;
  444. }
  445. if (flags & SMIC_RX_DATA_READY) {
  446. read_next_byte(smic);
  447. write_smic_control(smic, SMIC_CC_SMS_RD_NEXT);
  448. write_smic_flags(smic, flags | SMIC_FLAG_BSY);
  449. smic->state = SMIC_READ_NEXT;
  450. } else {
  451. return SI_SM_CALL_WITH_DELAY;
  452. }
  453. break;
  454. case SMIC_READ_NEXT:
  455. switch (status) {
  456. /* smic tells us that this is the last byte to be read
  457. --> clean up */
  458. case SMIC_SC_SMS_RD_END:
  459. read_next_byte(smic);
  460. write_smic_control(smic, SMIC_CC_SMS_RD_END);
  461. write_smic_flags(smic, flags | SMIC_FLAG_BSY);
  462. smic->state = SMIC_READ_END;
  463. break;
  464. case SMIC_SC_SMS_RD_NEXT:
  465. if (flags & SMIC_RX_DATA_READY) {
  466. read_next_byte(smic);
  467. write_smic_control(smic, SMIC_CC_SMS_RD_NEXT);
  468. write_smic_flags(smic, flags | SMIC_FLAG_BSY);
  469. smic->state = SMIC_READ_NEXT;
  470. } else {
  471. return SI_SM_CALL_WITH_DELAY;
  472. }
  473. break;
  474. default:
  475. start_error_recovery(
  476. smic,
  477. "state = SMIC_READ_NEXT, "
  478. "status != SMIC_SC_SMS_RD_(NEXT|END)");
  479. return SI_SM_CALL_WITH_DELAY;
  480. }
  481. break;
  482. case SMIC_READ_END:
  483. if (status != SMIC_SC_SMS_READY) {
  484. start_error_recovery(smic,
  485. "state = SMIC_READ_END, "
  486. "status != SMIC_SC_SMS_READY");
  487. return SI_SM_CALL_WITH_DELAY;
  488. }
  489. data = read_smic_data(smic);
  490. /* data register holds an error code */
  491. if (data != 0) {
  492. if (smic_debug & SMIC_DEBUG_ENABLE) {
  493. printk(KERN_INFO
  494. "SMIC_READ_END: data = %02x\n", data);
  495. }
  496. start_error_recovery(smic,
  497. "state = SMIC_READ_END, "
  498. "data != SUCCESS");
  499. return SI_SM_CALL_WITH_DELAY;
  500. } else {
  501. smic->state = SMIC_IDLE;
  502. return SI_SM_TRANSACTION_COMPLETE;
  503. }
  504. case SMIC_HOSED:
  505. init_smic_data(smic, smic->io);
  506. return SI_SM_HOSED;
  507. default:
  508. if (smic_debug & SMIC_DEBUG_ENABLE) {
  509. printk(KERN_WARNING "smic->state = %d\n", smic->state);
  510. start_error_recovery(smic, "state = UNKNOWN");
  511. return SI_SM_CALL_WITH_DELAY;
  512. }
  513. }
  514. smic->smic_timeout = SMIC_RETRY_TIMEOUT;
  515. return SI_SM_CALL_WITHOUT_DELAY;
  516. }
  517. static int smic_detect(struct si_sm_data *smic)
  518. {
  519. /* It's impossible for the SMIC fnags register to be all 1's,
  520. (assuming a properly functioning, self-initialized BMC)
  521. but that's what you get from reading a bogus address, so we
  522. test that first. */
  523. if (read_smic_flags(smic) == 0xff)
  524. return 1;
  525. return 0;
  526. }
  527. static void smic_cleanup(struct si_sm_data *kcs)
  528. {
  529. }
  530. static int smic_size(void)
  531. {
  532. return sizeof(struct si_sm_data);
  533. }
  534. struct si_sm_handlers smic_smi_handlers =
  535. {
  536. .version = IPMI_SMIC_VERSION,
  537. .init_data = init_smic_data,
  538. .start_transaction = start_smic_transaction,
  539. .get_result = smic_get_result,
  540. .event = smic_event,
  541. .detect = smic_detect,
  542. .cleanup = smic_cleanup,
  543. .size = smic_size,
  544. };