summaryrefslogtreecommitdiff
path: root/sys/dev/ic
diff options
context:
space:
mode:
authorMarco Peereboom <marco@cvs.openbsd.org>2006-04-06 22:44:25 +0000
committerMarco Peereboom <marco@cvs.openbsd.org>2006-04-06 22:44:25 +0000
commitda675f40fefca37deefd78b185bf8d371de83a7a (patch)
treeecaf519945ab5097eb09b7d85af0892f2128ade5 /sys/dev/ic
parent569ada761bf9775239f5426a93fe1a0574c0a793 (diff)
Add fw transition logic.
Diffstat (limited to 'sys/dev/ic')
-rw-r--r--sys/dev/ic/mfi.c63
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);
}