diff options
author | Marco Peereboom <marco@cvs.openbsd.org> | 2006-04-06 22:44:25 +0000 |
---|---|---|
committer | Marco Peereboom <marco@cvs.openbsd.org> | 2006-04-06 22:44:25 +0000 |
commit | da675f40fefca37deefd78b185bf8d371de83a7a (patch) | |
tree | ecaf519945ab5097eb09b7d85af0892f2128ade5 /sys/dev | |
parent | 569ada761bf9775239f5426a93fe1a0574c0a793 (diff) |
Add fw transition logic.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ic/mfi.c | 63 |
1 files changed, 62 insertions, 1 deletions
diff --git a/sys/dev/ic/mfi.c b/sys/dev/ic/mfi.c index 2ba693fc522..a3e78c36644 100644 --- a/sys/dev/ic/mfi.c +++ b/sys/dev/ic/mfi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mfi.c,v 1.1 2006/04/06 20:22:53 marco Exp $ */ +/* $OpenBSD: mfi.c,v 1.2 2006/04/06 22:44:24 marco Exp $ */ /* * Copyright (c) 2006 Marco Peereboom <marco@peereboom.us> * @@ -56,6 +56,64 @@ struct scsi_device mfi_dev = { NULL, NULL, NULL, NULL }; +int mfi_transition_firmware(struct mfi_softc *); + +int +mfi_transition_firmware(struct mfi_softc *sc) +{ +#if 0 + int32_t fw_state, cur_state; + int max_wait, i; + + /* fw_state = MFI_READ4(sc, MFI_OMSG0) & MFI_STATE_MASK; */ + while (fw_state != MFI_STATE_READY) { +#ifdef MFI_DEBUG + printf("Waiting for firmware to become ready\n"); +#endif /* MFI_DEBUG */ + cur_state = fw_state; + switch (fw_state) { + case MFI_STATE_FAULT: + device_printf(sc->mfi_dev, "Firmware fault\n"); + return (ENXIO); + case MFI_STATE_WAIT_HANDSHAKE: + MFI_WRITE4(sc, MFI_IDB, MFI_INIT_CLEAR_HANDSHAKE); + max_wait = 2; + break; + case MFI_STATE_OPERATIONAL: + MFI_WRITE4(sc, MFI_IDB, MFI_INIT_READY); + max_wait = 10; + break; + case MFI_STATE_UNDEFINED: + case MFI_STATE_BB_INIT: + max_wait = 2; + break; + case MFI_STATE_FW_INIT: + case MFI_STATE_DEVICE_SCAN: + case MFI_STATE_FLUSH_CACHE: + max_wait = 20; + break; + default: + device_printf(sc->mfi_dev,"Unknown firmware state %d\n", + fw_state); + return (ENXIO); + } + for (i = 0; i < (max_wait * 10); i++) { + fw_state = MFI_READ4(sc, MFI_OMSG0) & MFI_STATE_MASK; + if (fw_state == cur_state) + DELAY(100000); + else + break; + } + if (fw_state == cur_state) { + device_printf(sc->mfi_dev, "firmware stuck in state " + "%#x\n", fw_state); + return (ENXIO); + } + } +#endif + return (0); +} + void mfiminphys(struct buf *bp) { @@ -68,6 +126,9 @@ mfiminphys(struct buf *bp) int mfi_attach(struct mfi_softc *sc) { + if (mfi_transition_firmware(sc)) + return (1); + return (1); } |