ipmi_smic_sm.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605
  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 2000000
  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. {
  100. enum smic_states state;
  101. struct si_sm_io *io;
  102. unsigned char write_data[MAX_SMIC_WRITE_SIZE];
  103. int write_pos;
  104. int write_count;
  105. int orig_write_count;
  106. unsigned char read_data[MAX_SMIC_READ_SIZE];
  107. int read_pos;
  108. int truncated;
  109. unsigned int error_retries;
  110. long smic_timeout;
  111. };
  112. static unsigned int init_smic_data (struct si_sm_data *smic,
  113. struct si_sm_io *io)
  114. {
  115. smic->state = SMIC_IDLE;
  116. smic->io = io;
  117. smic->write_pos = 0;
  118. smic->write_count = 0;
  119. smic->orig_write_count = 0;
  120. smic->read_pos = 0;
  121. smic->error_retries = 0;
  122. smic->truncated = 0;
  123. smic->smic_timeout = SMIC_RETRY_TIMEOUT;
  124. /* We use 3 bytes of I/O. */
  125. return 3;
  126. }
  127. static int start_smic_transaction(struct si_sm_data *smic,
  128. unsigned char *data, unsigned int size)
  129. {
  130. unsigned int i;
  131. if ((size < 2) || (size > MAX_SMIC_WRITE_SIZE)) {
  132. return -1;
  133. }
  134. if ((smic->state != SMIC_IDLE) && (smic->state != SMIC_HOSED)) {
  135. return -2;
  136. }
  137. if (smic_debug & SMIC_DEBUG_MSG) {
  138. printk(KERN_INFO "start_smic_transaction -");
  139. for (i = 0; i < size; i ++) {
  140. printk (" %02x", (unsigned char) (data [i]));
  141. }
  142. printk ("\n");
  143. }
  144. smic->error_retries = 0;
  145. memcpy(smic->write_data, data, size);
  146. smic->write_count = size;
  147. smic->orig_write_count = size;
  148. smic->write_pos = 0;
  149. smic->read_pos = 0;
  150. smic->state = SMIC_START_OP;
  151. smic->smic_timeout = SMIC_RETRY_TIMEOUT;
  152. return 0;
  153. }
  154. static int smic_get_result(struct si_sm_data *smic,
  155. unsigned char *data, unsigned int length)
  156. {
  157. int i;
  158. if (smic_debug & SMIC_DEBUG_MSG) {
  159. printk (KERN_INFO "smic_get result -");
  160. for (i = 0; i < smic->read_pos; i ++) {
  161. printk (" %02x", (smic->read_data [i]));
  162. }
  163. printk ("\n");
  164. }
  165. if (length < smic->read_pos) {
  166. smic->read_pos = length;
  167. smic->truncated = 1;
  168. }
  169. memcpy(data, smic->read_data, smic->read_pos);
  170. if ((length >= 3) && (smic->read_pos < 3)) {
  171. data[2] = IPMI_ERR_UNSPECIFIED;
  172. smic->read_pos = 3;
  173. }
  174. if (smic->truncated) {
  175. data[2] = IPMI_ERR_MSG_TRUNCATED;
  176. smic->truncated = 0;
  177. }
  178. return smic->read_pos;
  179. }
  180. static inline unsigned char read_smic_flags(struct si_sm_data *smic)
  181. {
  182. return smic->io->inputb(smic->io, 2);
  183. }
  184. static inline unsigned char read_smic_status(struct si_sm_data *smic)
  185. {
  186. return smic->io->inputb(smic->io, 1);
  187. }
  188. static inline unsigned char read_smic_data(struct si_sm_data *smic)
  189. {
  190. return smic->io->inputb(smic->io, 0);
  191. }
  192. static inline void write_smic_flags(struct si_sm_data *smic,
  193. unsigned char flags)
  194. {
  195. smic->io->outputb(smic->io, 2, flags);
  196. }
  197. static inline void write_smic_control(struct si_sm_data *smic,
  198. unsigned char control)
  199. {
  200. smic->io->outputb(smic->io, 1, control);
  201. }
  202. static inline void write_si_sm_data (struct si_sm_data *smic,
  203. unsigned char data)
  204. {
  205. smic->io->outputb(smic->io, 0, data);
  206. }
  207. static inline void start_error_recovery(struct si_sm_data *smic, char *reason)
  208. {
  209. (smic->error_retries)++;
  210. if (smic->error_retries > SMIC_MAX_ERROR_RETRIES) {
  211. if (smic_debug & SMIC_DEBUG_ENABLE) {
  212. printk(KERN_WARNING
  213. "ipmi_smic_drv: smic hosed: %s\n", reason);
  214. }
  215. smic->state = SMIC_HOSED;
  216. } else {
  217. smic->write_count = smic->orig_write_count;
  218. smic->write_pos = 0;
  219. smic->read_pos = 0;
  220. smic->state = SMIC_START_OP;
  221. smic->smic_timeout = SMIC_RETRY_TIMEOUT;
  222. }
  223. }
  224. static inline void write_next_byte(struct si_sm_data *smic)
  225. {
  226. write_si_sm_data(smic, smic->write_data[smic->write_pos]);
  227. (smic->write_pos)++;
  228. (smic->write_count)--;
  229. }
  230. static inline void read_next_byte (struct si_sm_data *smic)
  231. {
  232. if (smic->read_pos >= MAX_SMIC_READ_SIZE) {
  233. read_smic_data (smic);
  234. smic->truncated = 1;
  235. } else {
  236. smic->read_data[smic->read_pos] = read_smic_data(smic);
  237. (smic->read_pos)++;
  238. }
  239. }
  240. /* SMIC Control/Status Code Components */
  241. #define SMIC_GET_STATUS 0x00 /* Control form's name */
  242. #define SMIC_READY 0x00 /* Status form's name */
  243. #define SMIC_WR_START 0x01 /* Unified Control/Status names... */
  244. #define SMIC_WR_NEXT 0x02
  245. #define SMIC_WR_END 0x03
  246. #define SMIC_RD_START 0x04
  247. #define SMIC_RD_NEXT 0x05
  248. #define SMIC_RD_END 0x06
  249. #define SMIC_CODE_MASK 0x0f
  250. #define SMIC_CONTROL 0x00
  251. #define SMIC_STATUS 0x80
  252. #define SMIC_CS_MASK 0x80
  253. #define SMIC_SMS 0x40
  254. #define SMIC_SMM 0x60
  255. #define SMIC_STREAM_MASK 0x60
  256. /* SMIC Control Codes */
  257. #define SMIC_CC_SMS_GET_STATUS (SMIC_CONTROL|SMIC_SMS|SMIC_GET_STATUS)
  258. #define SMIC_CC_SMS_WR_START (SMIC_CONTROL|SMIC_SMS|SMIC_WR_START)
  259. #define SMIC_CC_SMS_WR_NEXT (SMIC_CONTROL|SMIC_SMS|SMIC_WR_NEXT)
  260. #define SMIC_CC_SMS_WR_END (SMIC_CONTROL|SMIC_SMS|SMIC_WR_END)
  261. #define SMIC_CC_SMS_RD_START (SMIC_CONTROL|SMIC_SMS|SMIC_RD_START)
  262. #define SMIC_CC_SMS_RD_NEXT (SMIC_CONTROL|SMIC_SMS|SMIC_RD_NEXT)
  263. #define SMIC_CC_SMS_RD_END (SMIC_CONTROL|SMIC_SMS|SMIC_RD_END)
  264. #define SMIC_CC_SMM_GET_STATUS (SMIC_CONTROL|SMIC_SMM|SMIC_GET_STATUS)
  265. #define SMIC_CC_SMM_WR_START (SMIC_CONTROL|SMIC_SMM|SMIC_WR_START)
  266. #define SMIC_CC_SMM_WR_NEXT (SMIC_CONTROL|SMIC_SMM|SMIC_WR_NEXT)
  267. #define SMIC_CC_SMM_WR_END (SMIC_CONTROL|SMIC_SMM|SMIC_WR_END)
  268. #define SMIC_CC_SMM_RD_START (SMIC_CONTROL|SMIC_SMM|SMIC_RD_START)
  269. #define SMIC_CC_SMM_RD_NEXT (SMIC_CONTROL|SMIC_SMM|SMIC_RD_NEXT)
  270. #define SMIC_CC_SMM_RD_END (SMIC_CONTROL|SMIC_SMM|SMIC_RD_END)
  271. /* SMIC Status Codes */
  272. #define SMIC_SC_SMS_READY (SMIC_STATUS|SMIC_SMS|SMIC_READY)
  273. #define SMIC_SC_SMS_WR_START (SMIC_STATUS|SMIC_SMS|SMIC_WR_START)
  274. #define SMIC_SC_SMS_WR_NEXT (SMIC_STATUS|SMIC_SMS|SMIC_WR_NEXT)
  275. #define SMIC_SC_SMS_WR_END (SMIC_STATUS|SMIC_SMS|SMIC_WR_END)
  276. #define SMIC_SC_SMS_RD_START (SMIC_STATUS|SMIC_SMS|SMIC_RD_START)
  277. #define SMIC_SC_SMS_RD_NEXT (SMIC_STATUS|SMIC_SMS|SMIC_RD_NEXT)
  278. #define SMIC_SC_SMS_RD_END (SMIC_STATUS|SMIC_SMS|SMIC_RD_END)
  279. #define SMIC_SC_SMM_READY (SMIC_STATUS|SMIC_SMM|SMIC_READY)
  280. #define SMIC_SC_SMM_WR_START (SMIC_STATUS|SMIC_SMM|SMIC_WR_START)
  281. #define SMIC_SC_SMM_WR_NEXT (SMIC_STATUS|SMIC_SMM|SMIC_WR_NEXT)
  282. #define SMIC_SC_SMM_WR_END (SMIC_STATUS|SMIC_SMM|SMIC_WR_END)
  283. #define SMIC_SC_SMM_RD_START (SMIC_STATUS|SMIC_SMM|SMIC_RD_START)
  284. #define SMIC_SC_SMM_RD_NEXT (SMIC_STATUS|SMIC_SMM|SMIC_RD_NEXT)
  285. #define SMIC_SC_SMM_RD_END (SMIC_STATUS|SMIC_SMM|SMIC_RD_END)
  286. /* these are the control/status codes we actually use
  287. SMIC_CC_SMS_GET_STATUS 0x40
  288. SMIC_CC_SMS_WR_START 0x41
  289. SMIC_CC_SMS_WR_NEXT 0x42
  290. SMIC_CC_SMS_WR_END 0x43
  291. SMIC_CC_SMS_RD_START 0x44
  292. SMIC_CC_SMS_RD_NEXT 0x45
  293. SMIC_CC_SMS_RD_END 0x46
  294. SMIC_SC_SMS_READY 0xC0
  295. SMIC_SC_SMS_WR_START 0xC1
  296. SMIC_SC_SMS_WR_NEXT 0xC2
  297. SMIC_SC_SMS_WR_END 0xC3
  298. SMIC_SC_SMS_RD_START 0xC4
  299. SMIC_SC_SMS_RD_NEXT 0xC5
  300. SMIC_SC_SMS_RD_END 0xC6
  301. */
  302. static enum si_sm_result smic_event (struct si_sm_data *smic, long time)
  303. {
  304. unsigned char status;
  305. unsigned char flags;
  306. unsigned char data;
  307. if (smic->state == SMIC_HOSED) {
  308. init_smic_data(smic, smic->io);
  309. return SI_SM_HOSED;
  310. }
  311. if (smic->state != SMIC_IDLE) {
  312. if (smic_debug & SMIC_DEBUG_STATES) {
  313. printk(KERN_INFO
  314. "smic_event - smic->smic_timeout = %ld,"
  315. " time = %ld\n",
  316. smic->smic_timeout, time);
  317. }
  318. /* FIXME: smic_event is sometimes called with time > SMIC_RETRY_TIMEOUT */
  319. if (time < SMIC_RETRY_TIMEOUT) {
  320. smic->smic_timeout -= time;
  321. if (smic->smic_timeout < 0) {
  322. start_error_recovery(smic, "smic timed out.");
  323. return SI_SM_CALL_WITH_DELAY;
  324. }
  325. }
  326. }
  327. flags = read_smic_flags(smic);
  328. if (flags & SMIC_FLAG_BSY)
  329. return SI_SM_CALL_WITH_DELAY;
  330. status = read_smic_status (smic);
  331. if (smic_debug & SMIC_DEBUG_STATES)
  332. printk(KERN_INFO
  333. "smic_event - state = %d, flags = 0x%02x,"
  334. " status = 0x%02x\n",
  335. smic->state, flags, status);
  336. switch (smic->state) {
  337. case SMIC_IDLE:
  338. /* in IDLE we check for available messages */
  339. if (flags & SMIC_SMS_DATA_AVAIL)
  340. {
  341. return SI_SM_ATTN;
  342. }
  343. return SI_SM_IDLE;
  344. case SMIC_START_OP:
  345. /* sanity check whether smic is really idle */
  346. write_smic_control(smic, SMIC_CC_SMS_GET_STATUS);
  347. write_smic_flags(smic, flags | SMIC_FLAG_BSY);
  348. smic->state = SMIC_OP_OK;
  349. break;
  350. case SMIC_OP_OK:
  351. if (status != SMIC_SC_SMS_READY) {
  352. /* this should not happen */
  353. start_error_recovery(smic,
  354. "state = SMIC_OP_OK,"
  355. " status != SMIC_SC_SMS_READY");
  356. return SI_SM_CALL_WITH_DELAY;
  357. }
  358. /* OK so far; smic is idle let us start ... */
  359. write_smic_control(smic, SMIC_CC_SMS_WR_START);
  360. write_next_byte(smic);
  361. write_smic_flags(smic, flags | SMIC_FLAG_BSY);
  362. smic->state = SMIC_WRITE_START;
  363. break;
  364. case SMIC_WRITE_START:
  365. if (status != SMIC_SC_SMS_WR_START) {
  366. start_error_recovery(smic,
  367. "state = SMIC_WRITE_START, "
  368. "status != SMIC_SC_SMS_WR_START");
  369. return SI_SM_CALL_WITH_DELAY;
  370. }
  371. /* we must not issue WR_(NEXT|END) unless
  372. TX_DATA_READY is set */
  373. if (flags & SMIC_TX_DATA_READY) {
  374. if (smic->write_count == 1) {
  375. /* last byte */
  376. write_smic_control(smic, SMIC_CC_SMS_WR_END);
  377. smic->state = SMIC_WRITE_END;
  378. } else {
  379. write_smic_control(smic, SMIC_CC_SMS_WR_NEXT);
  380. smic->state = SMIC_WRITE_NEXT;
  381. }
  382. write_next_byte(smic);
  383. write_smic_flags(smic, flags | SMIC_FLAG_BSY);
  384. }
  385. else {
  386. return SI_SM_CALL_WITH_DELAY;
  387. }
  388. break;
  389. case SMIC_WRITE_NEXT:
  390. if (status != SMIC_SC_SMS_WR_NEXT) {
  391. start_error_recovery(smic,
  392. "state = SMIC_WRITE_NEXT, "
  393. "status != SMIC_SC_SMS_WR_NEXT");
  394. return SI_SM_CALL_WITH_DELAY;
  395. }
  396. /* this is the same code as in SMIC_WRITE_START */
  397. if (flags & SMIC_TX_DATA_READY) {
  398. if (smic->write_count == 1) {
  399. write_smic_control(smic, SMIC_CC_SMS_WR_END);
  400. smic->state = SMIC_WRITE_END;
  401. }
  402. else {
  403. write_smic_control(smic, SMIC_CC_SMS_WR_NEXT);
  404. smic->state = SMIC_WRITE_NEXT;
  405. }
  406. write_next_byte(smic);
  407. write_smic_flags(smic, flags | SMIC_FLAG_BSY);
  408. }
  409. else {
  410. return SI_SM_CALL_WITH_DELAY;
  411. }
  412. break;
  413. case SMIC_WRITE_END:
  414. if (status != SMIC_SC_SMS_WR_END) {
  415. start_error_recovery (smic,
  416. "state = SMIC_WRITE_END, "
  417. "status != SMIC_SC_SMS_WR_END");
  418. return SI_SM_CALL_WITH_DELAY;
  419. }
  420. /* data register holds an error code */
  421. data = read_smic_data(smic);
  422. if (data != 0) {
  423. if (smic_debug & SMIC_DEBUG_ENABLE) {
  424. printk(KERN_INFO
  425. "SMIC_WRITE_END: data = %02x\n", data);
  426. }
  427. start_error_recovery(smic,
  428. "state = SMIC_WRITE_END, "
  429. "data != SUCCESS");
  430. return SI_SM_CALL_WITH_DELAY;
  431. } else {
  432. smic->state = SMIC_WRITE2READ;
  433. }
  434. break;
  435. case SMIC_WRITE2READ:
  436. /* we must wait for RX_DATA_READY to be set before we
  437. can continue */
  438. if (flags & SMIC_RX_DATA_READY) {
  439. write_smic_control(smic, SMIC_CC_SMS_RD_START);
  440. write_smic_flags(smic, flags | SMIC_FLAG_BSY);
  441. smic->state = SMIC_READ_START;
  442. } else {
  443. return SI_SM_CALL_WITH_DELAY;
  444. }
  445. break;
  446. case SMIC_READ_START:
  447. if (status != SMIC_SC_SMS_RD_START) {
  448. start_error_recovery(smic,
  449. "state = SMIC_READ_START, "
  450. "status != SMIC_SC_SMS_RD_START");
  451. return SI_SM_CALL_WITH_DELAY;
  452. }
  453. if (flags & SMIC_RX_DATA_READY) {
  454. read_next_byte(smic);
  455. write_smic_control(smic, SMIC_CC_SMS_RD_NEXT);
  456. write_smic_flags(smic, flags | SMIC_FLAG_BSY);
  457. smic->state = SMIC_READ_NEXT;
  458. } else {
  459. return SI_SM_CALL_WITH_DELAY;
  460. }
  461. break;
  462. case SMIC_READ_NEXT:
  463. switch (status) {
  464. /* smic tells us that this is the last byte to be read
  465. --> clean up */
  466. case SMIC_SC_SMS_RD_END:
  467. read_next_byte(smic);
  468. write_smic_control(smic, SMIC_CC_SMS_RD_END);
  469. write_smic_flags(smic, flags | SMIC_FLAG_BSY);
  470. smic->state = SMIC_READ_END;
  471. break;
  472. case SMIC_SC_SMS_RD_NEXT:
  473. if (flags & SMIC_RX_DATA_READY) {
  474. read_next_byte(smic);
  475. write_smic_control(smic, SMIC_CC_SMS_RD_NEXT);
  476. write_smic_flags(smic, flags | SMIC_FLAG_BSY);
  477. smic->state = SMIC_READ_NEXT;
  478. } else {
  479. return SI_SM_CALL_WITH_DELAY;
  480. }
  481. break;
  482. default:
  483. start_error_recovery(
  484. smic,
  485. "state = SMIC_READ_NEXT, "
  486. "status != SMIC_SC_SMS_RD_(NEXT|END)");
  487. return SI_SM_CALL_WITH_DELAY;
  488. }
  489. break;
  490. case SMIC_READ_END:
  491. if (status != SMIC_SC_SMS_READY) {
  492. start_error_recovery(smic,
  493. "state = SMIC_READ_END, "
  494. "status != SMIC_SC_SMS_READY");
  495. return SI_SM_CALL_WITH_DELAY;
  496. }
  497. data = read_smic_data(smic);
  498. /* data register holds an error code */
  499. if (data != 0) {
  500. if (smic_debug & SMIC_DEBUG_ENABLE) {
  501. printk(KERN_INFO
  502. "SMIC_READ_END: data = %02x\n", data);
  503. }
  504. start_error_recovery(smic,
  505. "state = SMIC_READ_END, "
  506. "data != SUCCESS");
  507. return SI_SM_CALL_WITH_DELAY;
  508. } else {
  509. smic->state = SMIC_IDLE;
  510. return SI_SM_TRANSACTION_COMPLETE;
  511. }
  512. case SMIC_HOSED:
  513. init_smic_data(smic, smic->io);
  514. return SI_SM_HOSED;
  515. default:
  516. if (smic_debug & SMIC_DEBUG_ENABLE) {
  517. printk(KERN_WARNING "smic->state = %d\n", smic->state);
  518. start_error_recovery(smic, "state = UNKNOWN");
  519. return SI_SM_CALL_WITH_DELAY;
  520. }
  521. }
  522. smic->smic_timeout = SMIC_RETRY_TIMEOUT;
  523. return SI_SM_CALL_WITHOUT_DELAY;
  524. }
  525. static int smic_detect(struct si_sm_data *smic)
  526. {
  527. /* It's impossible for the SMIC fnags register to be all 1's,
  528. (assuming a properly functioning, self-initialized BMC)
  529. but that's what you get from reading a bogus address, so we
  530. test that first. */
  531. if (read_smic_flags(smic) == 0xff)
  532. return 1;
  533. return 0;
  534. }
  535. static void smic_cleanup(struct si_sm_data *kcs)
  536. {
  537. }
  538. static int smic_size(void)
  539. {
  540. return sizeof(struct si_sm_data);
  541. }
  542. struct si_sm_handlers smic_smi_handlers =
  543. {
  544. .init_data = init_smic_data,
  545. .start_transaction = start_smic_transaction,
  546. .get_result = smic_get_result,
  547. .event = smic_event,
  548. .detect = smic_detect,
  549. .cleanup = smic_cleanup,
  550. .size = smic_size,
  551. };