ipmi_smic_sm.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  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/module.h>
  46. #include <linux/moduleparam.h>
  47. #include <linux/ipmi_msgdefs.h> /* for completion codes */
  48. #include "ipmi_si_sm.h"
  49. /* smic_debug is a bit-field
  50. * SMIC_DEBUG_ENABLE - turned on for now
  51. * SMIC_DEBUG_MSG - commands and their responses
  52. * SMIC_DEBUG_STATES - state machine
  53. */
  54. #define SMIC_DEBUG_STATES 4
  55. #define SMIC_DEBUG_MSG 2
  56. #define SMIC_DEBUG_ENABLE 1
  57. static int smic_debug = 1;
  58. module_param(smic_debug, int, 0644);
  59. MODULE_PARM_DESC(smic_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
  60. enum smic_states {
  61. SMIC_IDLE,
  62. SMIC_START_OP,
  63. SMIC_OP_OK,
  64. SMIC_WRITE_START,
  65. SMIC_WRITE_NEXT,
  66. SMIC_WRITE_END,
  67. SMIC_WRITE2READ,
  68. SMIC_READ_START,
  69. SMIC_READ_NEXT,
  70. SMIC_READ_END,
  71. SMIC_HOSED
  72. };
  73. #define MAX_SMIC_READ_SIZE 80
  74. #define MAX_SMIC_WRITE_SIZE 80
  75. #define SMIC_MAX_ERROR_RETRIES 3
  76. /* Timeouts in microseconds. */
  77. #define SMIC_RETRY_TIMEOUT (2*USEC_PER_SEC)
  78. /* SMIC Flags Register Bits */
  79. #define SMIC_RX_DATA_READY 0x80
  80. #define SMIC_TX_DATA_READY 0x40
  81. /*
  82. * SMIC_SMI and SMIC_EVM_DATA_AVAIL are only used by
  83. * a few systems, and then only by Systems Management
  84. * Interrupts, not by the OS. Always ignore these bits.
  85. *
  86. */
  87. #define SMIC_SMI 0x10
  88. #define SMIC_EVM_DATA_AVAIL 0x08
  89. #define SMIC_SMS_DATA_AVAIL 0x04
  90. #define SMIC_FLAG_BSY 0x01
  91. /* SMIC Error Codes */
  92. #define EC_NO_ERROR 0x00
  93. #define EC_ABORTED 0x01
  94. #define EC_ILLEGAL_CONTROL 0x02
  95. #define EC_NO_RESPONSE 0x03
  96. #define EC_ILLEGAL_COMMAND 0x04
  97. #define EC_BUFFER_FULL 0x05
  98. struct si_sm_data {
  99. enum smic_states state;
  100. struct si_sm_io *io;
  101. unsigned char write_data[MAX_SMIC_WRITE_SIZE];
  102. int write_pos;
  103. int write_count;
  104. int orig_write_count;
  105. unsigned char read_data[MAX_SMIC_READ_SIZE];
  106. int read_pos;
  107. int truncated;
  108. unsigned int error_retries;
  109. long smic_timeout;
  110. };
  111. static unsigned int init_smic_data(struct si_sm_data *smic,
  112. struct si_sm_io *io)
  113. {
  114. smic->state = SMIC_IDLE;
  115. smic->io = io;
  116. smic->write_pos = 0;
  117. smic->write_count = 0;
  118. smic->orig_write_count = 0;
  119. smic->read_pos = 0;
  120. smic->error_retries = 0;
  121. smic->truncated = 0;
  122. smic->smic_timeout = SMIC_RETRY_TIMEOUT;
  123. /* We use 3 bytes of I/O. */
  124. return 3;
  125. }
  126. static int start_smic_transaction(struct si_sm_data *smic,
  127. unsigned char *data, unsigned int size)
  128. {
  129. unsigned int i;
  130. if (size < 2)
  131. return IPMI_REQ_LEN_INVALID_ERR;
  132. if (size > MAX_SMIC_WRITE_SIZE)
  133. return IPMI_REQ_LEN_EXCEEDED_ERR;
  134. if ((smic->state != SMIC_IDLE) && (smic->state != SMIC_HOSED))
  135. return IPMI_NOT_IN_MY_STATE_ERR;
  136. if (smic_debug & SMIC_DEBUG_MSG) {
  137. printk(KERN_DEBUG "start_smic_transaction -");
  138. for (i = 0; i < size; i++)
  139. printk(" %02x", (unsigned char) data[i]);
  140. printk("\n");
  141. }
  142. smic->error_retries = 0;
  143. memcpy(smic->write_data, data, size);
  144. smic->write_count = size;
  145. smic->orig_write_count = size;
  146. smic->write_pos = 0;
  147. smic->read_pos = 0;
  148. smic->state = SMIC_START_OP;
  149. smic->smic_timeout = SMIC_RETRY_TIMEOUT;
  150. return 0;
  151. }
  152. static int smic_get_result(struct si_sm_data *smic,
  153. unsigned char *data, unsigned int length)
  154. {
  155. int i;
  156. if (smic_debug & SMIC_DEBUG_MSG) {
  157. printk(KERN_DEBUG "smic_get result -");
  158. for (i = 0; i < smic->read_pos; i++)
  159. printk(" %02x", smic->read_data[i]);
  160. printk("\n");
  161. }
  162. if (length < smic->read_pos) {
  163. smic->read_pos = length;
  164. smic->truncated = 1;
  165. }
  166. memcpy(data, smic->read_data, smic->read_pos);
  167. if ((length >= 3) && (smic->read_pos < 3)) {
  168. data[2] = IPMI_ERR_UNSPECIFIED;
  169. smic->read_pos = 3;
  170. }
  171. if (smic->truncated) {
  172. data[2] = IPMI_ERR_MSG_TRUNCATED;
  173. smic->truncated = 0;
  174. }
  175. return smic->read_pos;
  176. }
  177. static inline unsigned char read_smic_flags(struct si_sm_data *smic)
  178. {
  179. return smic->io->inputb(smic->io, 2);
  180. }
  181. static inline unsigned char read_smic_status(struct si_sm_data *smic)
  182. {
  183. return smic->io->inputb(smic->io, 1);
  184. }
  185. static inline unsigned char read_smic_data(struct si_sm_data *smic)
  186. {
  187. return smic->io->inputb(smic->io, 0);
  188. }
  189. static inline void write_smic_flags(struct si_sm_data *smic,
  190. unsigned char flags)
  191. {
  192. smic->io->outputb(smic->io, 2, flags);
  193. }
  194. static inline void write_smic_control(struct si_sm_data *smic,
  195. unsigned char control)
  196. {
  197. smic->io->outputb(smic->io, 1, control);
  198. }
  199. static inline void write_si_sm_data(struct si_sm_data *smic,
  200. unsigned char data)
  201. {
  202. smic->io->outputb(smic->io, 0, data);
  203. }
  204. static inline void start_error_recovery(struct si_sm_data *smic, char *reason)
  205. {
  206. (smic->error_retries)++;
  207. if (smic->error_retries > SMIC_MAX_ERROR_RETRIES) {
  208. if (smic_debug & SMIC_DEBUG_ENABLE)
  209. printk(KERN_WARNING
  210. "ipmi_smic_drv: smic hosed: %s\n", reason);
  211. smic->state = SMIC_HOSED;
  212. } else {
  213. smic->write_count = smic->orig_write_count;
  214. smic->write_pos = 0;
  215. smic->read_pos = 0;
  216. smic->state = SMIC_START_OP;
  217. smic->smic_timeout = SMIC_RETRY_TIMEOUT;
  218. }
  219. }
  220. static inline void write_next_byte(struct si_sm_data *smic)
  221. {
  222. write_si_sm_data(smic, smic->write_data[smic->write_pos]);
  223. (smic->write_pos)++;
  224. (smic->write_count)--;
  225. }
  226. static inline void read_next_byte(struct si_sm_data *smic)
  227. {
  228. if (smic->read_pos >= MAX_SMIC_READ_SIZE) {
  229. read_smic_data(smic);
  230. smic->truncated = 1;
  231. } else {
  232. smic->read_data[smic->read_pos] = read_smic_data(smic);
  233. smic->read_pos++;
  234. }
  235. }
  236. /* SMIC Control/Status Code Components */
  237. #define SMIC_GET_STATUS 0x00 /* Control form's name */
  238. #define SMIC_READY 0x00 /* Status form's name */
  239. #define SMIC_WR_START 0x01 /* Unified Control/Status names... */
  240. #define SMIC_WR_NEXT 0x02
  241. #define SMIC_WR_END 0x03
  242. #define SMIC_RD_START 0x04
  243. #define SMIC_RD_NEXT 0x05
  244. #define SMIC_RD_END 0x06
  245. #define SMIC_CODE_MASK 0x0f
  246. #define SMIC_CONTROL 0x00
  247. #define SMIC_STATUS 0x80
  248. #define SMIC_CS_MASK 0x80
  249. #define SMIC_SMS 0x40
  250. #define SMIC_SMM 0x60
  251. #define SMIC_STREAM_MASK 0x60
  252. /* SMIC Control Codes */
  253. #define SMIC_CC_SMS_GET_STATUS (SMIC_CONTROL|SMIC_SMS|SMIC_GET_STATUS)
  254. #define SMIC_CC_SMS_WR_START (SMIC_CONTROL|SMIC_SMS|SMIC_WR_START)
  255. #define SMIC_CC_SMS_WR_NEXT (SMIC_CONTROL|SMIC_SMS|SMIC_WR_NEXT)
  256. #define SMIC_CC_SMS_WR_END (SMIC_CONTROL|SMIC_SMS|SMIC_WR_END)
  257. #define SMIC_CC_SMS_RD_START (SMIC_CONTROL|SMIC_SMS|SMIC_RD_START)
  258. #define SMIC_CC_SMS_RD_NEXT (SMIC_CONTROL|SMIC_SMS|SMIC_RD_NEXT)
  259. #define SMIC_CC_SMS_RD_END (SMIC_CONTROL|SMIC_SMS|SMIC_RD_END)
  260. #define SMIC_CC_SMM_GET_STATUS (SMIC_CONTROL|SMIC_SMM|SMIC_GET_STATUS)
  261. #define SMIC_CC_SMM_WR_START (SMIC_CONTROL|SMIC_SMM|SMIC_WR_START)
  262. #define SMIC_CC_SMM_WR_NEXT (SMIC_CONTROL|SMIC_SMM|SMIC_WR_NEXT)
  263. #define SMIC_CC_SMM_WR_END (SMIC_CONTROL|SMIC_SMM|SMIC_WR_END)
  264. #define SMIC_CC_SMM_RD_START (SMIC_CONTROL|SMIC_SMM|SMIC_RD_START)
  265. #define SMIC_CC_SMM_RD_NEXT (SMIC_CONTROL|SMIC_SMM|SMIC_RD_NEXT)
  266. #define SMIC_CC_SMM_RD_END (SMIC_CONTROL|SMIC_SMM|SMIC_RD_END)
  267. /* SMIC Status Codes */
  268. #define SMIC_SC_SMS_READY (SMIC_STATUS|SMIC_SMS|SMIC_READY)
  269. #define SMIC_SC_SMS_WR_START (SMIC_STATUS|SMIC_SMS|SMIC_WR_START)
  270. #define SMIC_SC_SMS_WR_NEXT (SMIC_STATUS|SMIC_SMS|SMIC_WR_NEXT)
  271. #define SMIC_SC_SMS_WR_END (SMIC_STATUS|SMIC_SMS|SMIC_WR_END)
  272. #define SMIC_SC_SMS_RD_START (SMIC_STATUS|SMIC_SMS|SMIC_RD_START)
  273. #define SMIC_SC_SMS_RD_NEXT (SMIC_STATUS|SMIC_SMS|SMIC_RD_NEXT)
  274. #define SMIC_SC_SMS_RD_END (SMIC_STATUS|SMIC_SMS|SMIC_RD_END)
  275. #define SMIC_SC_SMM_READY (SMIC_STATUS|SMIC_SMM|SMIC_READY)
  276. #define SMIC_SC_SMM_WR_START (SMIC_STATUS|SMIC_SMM|SMIC_WR_START)
  277. #define SMIC_SC_SMM_WR_NEXT (SMIC_STATUS|SMIC_SMM|SMIC_WR_NEXT)
  278. #define SMIC_SC_SMM_WR_END (SMIC_STATUS|SMIC_SMM|SMIC_WR_END)
  279. #define SMIC_SC_SMM_RD_START (SMIC_STATUS|SMIC_SMM|SMIC_RD_START)
  280. #define SMIC_SC_SMM_RD_NEXT (SMIC_STATUS|SMIC_SMM|SMIC_RD_NEXT)
  281. #define SMIC_SC_SMM_RD_END (SMIC_STATUS|SMIC_SMM|SMIC_RD_END)
  282. /* these are the control/status codes we actually use
  283. SMIC_CC_SMS_GET_STATUS 0x40
  284. SMIC_CC_SMS_WR_START 0x41
  285. SMIC_CC_SMS_WR_NEXT 0x42
  286. SMIC_CC_SMS_WR_END 0x43
  287. SMIC_CC_SMS_RD_START 0x44
  288. SMIC_CC_SMS_RD_NEXT 0x45
  289. SMIC_CC_SMS_RD_END 0x46
  290. SMIC_SC_SMS_READY 0xC0
  291. SMIC_SC_SMS_WR_START 0xC1
  292. SMIC_SC_SMS_WR_NEXT 0xC2
  293. SMIC_SC_SMS_WR_END 0xC3
  294. SMIC_SC_SMS_RD_START 0xC4
  295. SMIC_SC_SMS_RD_NEXT 0xC5
  296. SMIC_SC_SMS_RD_END 0xC6
  297. */
  298. static enum si_sm_result smic_event(struct si_sm_data *smic, long time)
  299. {
  300. unsigned char status;
  301. unsigned char flags;
  302. unsigned char data;
  303. if (smic->state == SMIC_HOSED) {
  304. init_smic_data(smic, smic->io);
  305. return SI_SM_HOSED;
  306. }
  307. if (smic->state != SMIC_IDLE) {
  308. if (smic_debug & SMIC_DEBUG_STATES)
  309. printk(KERN_DEBUG
  310. "smic_event - smic->smic_timeout = %ld,"
  311. " time = %ld\n",
  312. smic->smic_timeout, time);
  313. /*
  314. * FIXME: smic_event is sometimes called with time >
  315. * SMIC_RETRY_TIMEOUT
  316. */
  317. if (time < SMIC_RETRY_TIMEOUT) {
  318. smic->smic_timeout -= time;
  319. if (smic->smic_timeout < 0) {
  320. start_error_recovery(smic, "smic timed out.");
  321. return SI_SM_CALL_WITH_DELAY;
  322. }
  323. }
  324. }
  325. flags = read_smic_flags(smic);
  326. if (flags & SMIC_FLAG_BSY)
  327. return SI_SM_CALL_WITH_DELAY;
  328. status = read_smic_status(smic);
  329. if (smic_debug & SMIC_DEBUG_STATES)
  330. printk(KERN_DEBUG
  331. "smic_event - state = %d, flags = 0x%02x,"
  332. " status = 0x%02x\n",
  333. smic->state, flags, status);
  334. switch (smic->state) {
  335. case SMIC_IDLE:
  336. /* in IDLE we check for available messages */
  337. if (flags & SMIC_SMS_DATA_AVAIL)
  338. return SI_SM_ATTN;
  339. return SI_SM_IDLE;
  340. case SMIC_START_OP:
  341. /* sanity check whether smic is really idle */
  342. write_smic_control(smic, SMIC_CC_SMS_GET_STATUS);
  343. write_smic_flags(smic, flags | SMIC_FLAG_BSY);
  344. smic->state = SMIC_OP_OK;
  345. break;
  346. case SMIC_OP_OK:
  347. if (status != SMIC_SC_SMS_READY) {
  348. /* this should not happen */
  349. start_error_recovery(smic,
  350. "state = SMIC_OP_OK,"
  351. " status != SMIC_SC_SMS_READY");
  352. return SI_SM_CALL_WITH_DELAY;
  353. }
  354. /* OK so far; smic is idle let us start ... */
  355. write_smic_control(smic, SMIC_CC_SMS_WR_START);
  356. write_next_byte(smic);
  357. write_smic_flags(smic, flags | SMIC_FLAG_BSY);
  358. smic->state = SMIC_WRITE_START;
  359. break;
  360. case SMIC_WRITE_START:
  361. if (status != SMIC_SC_SMS_WR_START) {
  362. start_error_recovery(smic,
  363. "state = SMIC_WRITE_START, "
  364. "status != SMIC_SC_SMS_WR_START");
  365. return SI_SM_CALL_WITH_DELAY;
  366. }
  367. /*
  368. * we must not issue WR_(NEXT|END) unless
  369. * TX_DATA_READY is set
  370. * */
  371. if (flags & SMIC_TX_DATA_READY) {
  372. if (smic->write_count == 1) {
  373. /* last byte */
  374. write_smic_control(smic, SMIC_CC_SMS_WR_END);
  375. smic->state = SMIC_WRITE_END;
  376. } else {
  377. write_smic_control(smic, SMIC_CC_SMS_WR_NEXT);
  378. smic->state = SMIC_WRITE_NEXT;
  379. }
  380. write_next_byte(smic);
  381. write_smic_flags(smic, flags | SMIC_FLAG_BSY);
  382. } else
  383. return SI_SM_CALL_WITH_DELAY;
  384. break;
  385. case SMIC_WRITE_NEXT:
  386. if (status != SMIC_SC_SMS_WR_NEXT) {
  387. start_error_recovery(smic,
  388. "state = SMIC_WRITE_NEXT, "
  389. "status != SMIC_SC_SMS_WR_NEXT");
  390. return SI_SM_CALL_WITH_DELAY;
  391. }
  392. /* this is the same code as in SMIC_WRITE_START */
  393. if (flags & SMIC_TX_DATA_READY) {
  394. if (smic->write_count == 1) {
  395. write_smic_control(smic, SMIC_CC_SMS_WR_END);
  396. smic->state = SMIC_WRITE_END;
  397. } else {
  398. write_smic_control(smic, SMIC_CC_SMS_WR_NEXT);
  399. smic->state = SMIC_WRITE_NEXT;
  400. }
  401. write_next_byte(smic);
  402. write_smic_flags(smic, flags | SMIC_FLAG_BSY);
  403. } else
  404. return SI_SM_CALL_WITH_DELAY;
  405. break;
  406. case SMIC_WRITE_END:
  407. if (status != SMIC_SC_SMS_WR_END) {
  408. start_error_recovery(smic,
  409. "state = SMIC_WRITE_END, "
  410. "status != SMIC_SC_SMS_WR_END");
  411. return SI_SM_CALL_WITH_DELAY;
  412. }
  413. /* data register holds an error code */
  414. data = read_smic_data(smic);
  415. if (data != 0) {
  416. if (smic_debug & SMIC_DEBUG_ENABLE)
  417. printk(KERN_DEBUG
  418. "SMIC_WRITE_END: data = %02x\n", data);
  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. break;
  426. case SMIC_WRITE2READ:
  427. /*
  428. * we must wait for RX_DATA_READY to be set before we
  429. * can continue
  430. */
  431. if (flags & SMIC_RX_DATA_READY) {
  432. write_smic_control(smic, SMIC_CC_SMS_RD_START);
  433. write_smic_flags(smic, flags | SMIC_FLAG_BSY);
  434. smic->state = SMIC_READ_START;
  435. } else
  436. return SI_SM_CALL_WITH_DELAY;
  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. break;
  453. case SMIC_READ_NEXT:
  454. switch (status) {
  455. /*
  456. * smic tells us that this is the last byte to be read
  457. * --> clean up
  458. */
  459. case SMIC_SC_SMS_RD_END:
  460. read_next_byte(smic);
  461. write_smic_control(smic, SMIC_CC_SMS_RD_END);
  462. write_smic_flags(smic, flags | SMIC_FLAG_BSY);
  463. smic->state = SMIC_READ_END;
  464. break;
  465. case SMIC_SC_SMS_RD_NEXT:
  466. if (flags & SMIC_RX_DATA_READY) {
  467. read_next_byte(smic);
  468. write_smic_control(smic, SMIC_CC_SMS_RD_NEXT);
  469. write_smic_flags(smic, flags | SMIC_FLAG_BSY);
  470. smic->state = SMIC_READ_NEXT;
  471. } else
  472. return SI_SM_CALL_WITH_DELAY;
  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_DEBUG
  494. "SMIC_READ_END: data = %02x\n", data);
  495. start_error_recovery(smic,
  496. "state = SMIC_READ_END, "
  497. "data != SUCCESS");
  498. return SI_SM_CALL_WITH_DELAY;
  499. } else {
  500. smic->state = SMIC_IDLE;
  501. return SI_SM_TRANSACTION_COMPLETE;
  502. }
  503. case SMIC_HOSED:
  504. init_smic_data(smic, smic->io);
  505. return SI_SM_HOSED;
  506. default:
  507. if (smic_debug & SMIC_DEBUG_ENABLE) {
  508. printk(KERN_DEBUG "smic->state = %d\n", smic->state);
  509. start_error_recovery(smic, "state = UNKNOWN");
  510. return SI_SM_CALL_WITH_DELAY;
  511. }
  512. }
  513. smic->smic_timeout = SMIC_RETRY_TIMEOUT;
  514. return SI_SM_CALL_WITHOUT_DELAY;
  515. }
  516. static int smic_detect(struct si_sm_data *smic)
  517. {
  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. */
  524. if (read_smic_flags(smic) == 0xff)
  525. return 1;
  526. return 0;
  527. }
  528. static void smic_cleanup(struct si_sm_data *kcs)
  529. {
  530. }
  531. static int smic_size(void)
  532. {
  533. return sizeof(struct si_sm_data);
  534. }
  535. struct si_sm_handlers smic_smi_handlers = {
  536. .init_data = init_smic_data,
  537. .start_transaction = start_smic_transaction,
  538. .get_result = smic_get_result,
  539. .event = smic_event,
  540. .detect = smic_detect,
  541. .cleanup = smic_cleanup,
  542. .size = smic_size,
  543. };