FreeBSD/sys/dev/mrsas/mrsas.c
/*
 * mrsas_transition_to_ready:  Move FW to Ready state input:
 * Adapter instance soft state
 *
 * During the initialization, FW passes can potentially be in any one of several
 * possible states. If the FW in operational, waiting-for-handshake states,
 * driver must take steps to bring it to ready state. Otherwise, it has to
 * wait for the ready state.
 */
Move FW to Ready state input:
Adapter instance soft state

During the initialization, FW passes can potentially be in any one of several
possible states. If the FW in operational, waiting-for-handshake states,
driver must take steps to bring it to ready state. Otherwise, it has to
wait for the ready state.
Move FW to Ready state input : Adapter instance soft state During the initialization FW passes can potentially be in any one of several possible states . If the FW in operational waiting - for - handshake states driver must take steps to bring it to ready state . Otherwise it has to wait for the ready state .
int
mrsas_transition_to_ready(struct mrsas_softc *sc, int ocr)
{
	int i;
	u_int8_t max_wait;
	u_int32_t val, fw_state;
	u_int32_t cur_state;
	u_int32_t abs_state, curr_abs_state;
	val = mrsas_read_reg(sc, offsetof(mrsas_reg_set, outbound_scratch_pad));
	fw_state = val & MFI_STATE_MASK;
	max_wait = MRSAS_RESET_WAIT_TIME;
	if (fw_state != MFI_STATE_READY)
		device_printf(sc->mrsas_dev, "Waiting for FW to come to ready state\n");
	while (fw_state != MFI_STATE_READY) {
		abs_state = mrsas_read_reg(sc, offsetof(mrsas_reg_set, outbound_scratch_pad));
		switch (fw_state) {
		case MFI_STATE_FAULT:
			device_printf(sc->mrsas_dev, "FW is in FAULT state!!\n");
			if (ocr) {
				cur_state = MFI_STATE_FAULT;
				break;
			} else
				return -ENODEV;
		case MFI_STATE_WAIT_HANDSHAKE:
			mrsas_write_reg(sc, offsetof(mrsas_reg_set, doorbell),
			    MFI_INIT_CLEAR_HANDSHAKE | MFI_INIT_HOTPLUG);
			cur_state = MFI_STATE_WAIT_HANDSHAKE;
			break;
		case MFI_STATE_BOOT_MESSAGE_PENDING:
			mrsas_write_reg(sc, offsetof(mrsas_reg_set, doorbell),
			    MFI_INIT_HOTPLUG);
			cur_state = MFI_STATE_BOOT_MESSAGE_PENDING;
			break;
		case MFI_STATE_OPERATIONAL:
			mrsas_disable_intr(sc);
			mrsas_write_reg(sc, offsetof(mrsas_reg_set, doorbell), MFI_RESET_FLAGS);
			for (i = 0; i < max_wait * 1000; i++) {
				if (mrsas_read_reg(sc, offsetof(mrsas_reg_set, doorbell)) & 1)
					DELAY(1000);
				else
					break;
			}
			cur_state = MFI_STATE_OPERATIONAL;
			break;
		case MFI_STATE_UNDEFINED:
			cur_state = MFI_STATE_UNDEFINED;
			break;
		case MFI_STATE_BB_INIT:
			cur_state = MFI_STATE_BB_INIT;
			break;
		case MFI_STATE_FW_INIT:
			cur_state = MFI_STATE_FW_INIT;
			break;
		case MFI_STATE_FW_INIT_2:
			cur_state = MFI_STATE_FW_INIT_2;
			break;
		case MFI_STATE_DEVICE_SCAN:
			cur_state = MFI_STATE_DEVICE_SCAN;
			break;
		case MFI_STATE_FLUSH_CACHE:
			cur_state = MFI_STATE_FLUSH_CACHE;
			break;
		default:
			device_printf(sc->mrsas_dev, "Unknown state 0x%x\n", fw_state);
			return -ENODEV;
		}
		for (i = 0; i < (max_wait * 1000); i++) {
			fw_state = (mrsas_read_reg(sc, offsetof(mrsas_reg_set,
			    outbound_scratch_pad)) & MFI_STATE_MASK);
			curr_abs_state = mrsas_read_reg(sc, offsetof(mrsas_reg_set,
			    outbound_scratch_pad));
			if (abs_state == curr_abs_state)
				DELAY(1000);
			else
				break;
		}
		if (curr_abs_state == abs_state) {
			device_printf(sc->mrsas_dev, "FW state [%d] hasn't changed "
			    "in %d secs\n", fw_state, max_wait);
			return -ENODEV;
		}
	}
	mrsas_dprint(sc, MRSAS_OCR, "FW now in Ready state\n");
	return 0;
}
int mrsas_transition_to_ready ( struct mrsas_softc * sc , int ocr ) { int i ; u_int8_t max_wait ; u_int32_t val , fw_state ; u_int32_t cur_state ; u_int32_t abs_state , curr_abs_state ; val = mrsas_read_reg ( sc , offsetof ( mrsas_reg_set , outbound_scratch_pad ) ) ; fw_state = val & MFI_STATE_MASK ; max_wait = MRSAS_RESET_WAIT_TIME ; if ( fw_state != MFI_STATE_READY ) device_printf ( sc -> mrsas_dev , " \n " ) ; while ( fw_state != MFI_STATE_READY ) { abs_state = mrsas_read_reg ( sc , offsetof ( mrsas_reg_set , outbound_scratch_pad ) ) ; switch ( fw_state ) { case MFI_STATE_FAULT : device_printf ( sc -> mrsas_dev , " \n " ) ; if ( ocr ) { cur_state = MFI_STATE_FAULT ; break ; } else return - ENODEV ; case MFI_STATE_WAIT_HANDSHAKE : mrsas_write_reg ( sc , offsetof ( mrsas_reg_set , doorbell ) , MFI_INIT_CLEAR_HANDSHAKE | MFI_INIT_HOTPLUG ) ; cur_state = MFI_STATE_WAIT_HANDSHAKE ; break ; case MFI_STATE_BOOT_MESSAGE_PENDING : mrsas_write_reg ( sc , offsetof ( mrsas_reg_set , doorbell ) , MFI_INIT_HOTPLUG ) ; cur_state = MFI_STATE_BOOT_MESSAGE_PENDING ; break ; case MFI_STATE_OPERATIONAL : mrsas_disable_intr ( sc ) ; mrsas_write_reg ( sc , offsetof ( mrsas_reg_set , doorbell ) , MFI_RESET_FLAGS ) ; for ( i = 0 ; i < max_wait * 1000 ; i ++ ) { if ( mrsas_read_reg ( sc , offsetof ( mrsas_reg_set , doorbell ) ) & 1 ) DELAY ( 1000 ) ; else break ; } cur_state = MFI_STATE_OPERATIONAL ; break ; case MFI_STATE_UNDEFINED : cur_state = MFI_STATE_UNDEFINED ; break ; case MFI_STATE_BB_INIT : cur_state = MFI_STATE_BB_INIT ; break ; case MFI_STATE_FW_INIT : cur_state = MFI_STATE_FW_INIT ; break ; case MFI_STATE_FW_INIT_2 : cur_state = MFI_STATE_FW_INIT_2 ; break ; case MFI_STATE_DEVICE_SCAN : cur_state = MFI_STATE_DEVICE_SCAN ; break ; case MFI_STATE_FLUSH_CACHE : cur_state = MFI_STATE_FLUSH_CACHE ; break ; default : device_printf ( sc -> mrsas_dev , " \n " , fw_state ) ; return - ENODEV ; } for ( i = 0 ; i < ( max_wait * 1000 ) ; i ++ ) { fw_state = ( mrsas_read_reg ( sc , offsetof ( mrsas_reg_set , outbound_scratch_pad ) ) & MFI_STATE_MASK ) ; curr_abs_state = mrsas_read_reg ( sc , offsetof ( mrsas_reg_set , outbound_scratch_pad ) ) ; if ( abs_state == curr_abs_state ) DELAY ( 1000 ) ; else break ; } if ( curr_abs_state == abs_state ) { device_printf ( sc -> mrsas_dev , " " " \n " , fw_state , max_wait ) ; return - ENODEV ; } } mrsas_dprint ( sc , MRSAS_OCR , " \n " ) ; return 0 ; }
mrsas_transition_to_ready:  Move FW to Ready state input:
 Adapter instance soft state
mrsas_transition_to_ready : Move FW to Ready state input : Adapter instance soft state
/* Set the CLR bit in inbound doorbell */ /*
			 * Bring it to READY state; assuming max wait 10
			 * secs
			 */ /*
			 * This state should not last for more than 2
			 * seconds
			 */ /*
		 * The cur_state should not last for more than max_wait secs
		 */ /*
		 * Return error if fw_state hasn't changed after max_wait
		 */