FreeBSD/sys/dev/mrsas/mrsas.c
/*
 * mrsas_ioc_init:	Sends IOC Init command to FW
 * input:			Adapter soft state
 *
 * Issues the IOC Init cmd to FW to initialize the ROC/controller.
 */
Sends IOC Init command to FW
input:                       Adapter soft state

Issues the IOC Init cmd to FW to initialize the ROC/controller.
Sends IOC Init command to FW input : Adapter soft state Issues the IOC Init cmd to FW to initialize the ROC / controller .
int
mrsas_ioc_init(struct mrsas_softc *sc)
{
	struct mrsas_init_frame *init_frame;
	pMpi2IOCInitRequest_t IOCInitMsg;
	MRSAS_REQUEST_DESCRIPTOR_UNION req_desc;
	u_int8_t max_wait = MRSAS_IOC_INIT_WAIT_TIME;
	bus_addr_t phys_addr;
	int i, retcode = 0;
	if (mrsas_alloc_ioc_cmd(sc)) {
		device_printf(sc->mrsas_dev, "Cannot allocate IOC command.\n");
		return (1);
	}
	IOCInitMsg = (pMpi2IOCInitRequest_t)(((char *)sc->ioc_init_mem) + 1024);
	IOCInitMsg->Function = MPI2_FUNCTION_IOC_INIT;
	IOCInitMsg->WhoInit = MPI2_WHOINIT_HOST_DRIVER;
	IOCInitMsg->MsgVersion = MPI2_VERSION;
	IOCInitMsg->HeaderVersion = MPI2_HEADER_VERSION;
	IOCInitMsg->SystemRequestFrameSize = MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE / 4;
	IOCInitMsg->ReplyDescriptorPostQueueDepth = sc->reply_q_depth;
	IOCInitMsg->ReplyDescriptorPostQueueAddress = sc->reply_desc_phys_addr;
	IOCInitMsg->SystemRequestFrameBaseAddress = sc->io_request_phys_addr;
	IOCInitMsg->HostMSIxVectors = (sc->msix_vectors > 0 ? sc->msix_vectors : 0);
	init_frame = (struct mrsas_init_frame *)sc->ioc_init_mem;
	init_frame->cmd = MFI_CMD_INIT;
	init_frame->cmd_status = 0xFF;
	init_frame->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
	if ((sc->device_id == MRSAS_INVADER) ||
	    (sc->device_id == MRSAS_FURY) ||
	    (sc->device_id == MRSAS_INTRUDER) ||
	    (sc->device_id == MRSAS_INTRUDER_24) ||
	    (sc->device_id == MRSAS_CUTLASS_52) ||
	    (sc->device_id == MRSAS_CUTLASS_53)) {
		init_frame->driver_operations.
		    mfi_capabilities.support_additional_msix = 1;
	}
	if (sc->verbuf_mem) {
		snprintf((char *)sc->verbuf_mem, strlen(MRSAS_VERSION) + 2, "%s\n",
		    MRSAS_VERSION);
		init_frame->driver_ver_lo = (bus_addr_t)sc->verbuf_phys_addr;
		init_frame->driver_ver_hi = 0;
	}
	init_frame->driver_operations.mfi_capabilities.support_ndrive_r1_lb = 1;
	init_frame->driver_operations.mfi_capabilities.support_max_255lds = 1;
	init_frame->driver_operations.mfi_capabilities.security_protocol_cmds_fw = 1;
	if (sc->max_chain_frame_sz > MEGASAS_CHAIN_FRAME_SZ_MIN)
		init_frame->driver_operations.mfi_capabilities.support_ext_io_size = 1;
	phys_addr = (bus_addr_t)sc->ioc_init_phys_mem + 1024;
	init_frame->queue_info_new_phys_addr_lo = phys_addr;
	init_frame->data_xfer_len = sizeof(Mpi2IOCInitRequest_t);
	req_desc.addr.Words = (bus_addr_t)sc->ioc_init_phys_mem;
	req_desc.MFAIo.RequestFlags =
	    (MRSAS_REQ_DESCRIPT_FLAGS_MFA << MRSAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
	mrsas_disable_intr(sc);
	mrsas_dprint(sc, MRSAS_OCR, "Issuing IOC INIT command to FW.\n");
	mrsas_fire_cmd(sc, req_desc.addr.u.low, req_desc.addr.u.high);
	if (init_frame->cmd_status == 0xFF) {
		for (i = 0; i < (max_wait * 1000); i++) {
			if (init_frame->cmd_status == 0xFF)
				DELAY(1000);
			else
				break;
		}
	}
	if (init_frame->cmd_status == 0)
		mrsas_dprint(sc, MRSAS_OCR,
		    "IOC INIT response received from FW.\n");
	else {
		if (init_frame->cmd_status == 0xFF)
			device_printf(sc->mrsas_dev, "IOC Init timed out after %d seconds.\n", max_wait);
		else
			device_printf(sc->mrsas_dev, "IOC Init failed, status = 0x%x\n", init_frame->cmd_status);
		retcode = 1;
	}
	mrsas_free_ioc_cmd(sc);
	return (retcode);
}
int mrsas_ioc_init ( struct mrsas_softc * sc ) { struct mrsas_init_frame * init_frame ; pMpi2IOCInitRequest_t IOCInitMsg ; MRSAS_REQUEST_DESCRIPTOR_UNION req_desc ; u_int8_t max_wait = MRSAS_IOC_INIT_WAIT_TIME ; bus_addr_t phys_addr ; int i , retcode = 0 ; if ( mrsas_alloc_ioc_cmd ( sc ) ) { device_printf ( sc -> mrsas_dev , " \n " ) ; return ( 1 ) ; } IOCInitMsg = ( pMpi2IOCInitRequest_t ) ( ( ( char * ) sc -> ioc_init_mem ) + 1024 ) ; IOCInitMsg -> Function = MPI2_FUNCTION_IOC_INIT ; IOCInitMsg -> WhoInit = MPI2_WHOINIT_HOST_DRIVER ; IOCInitMsg -> MsgVersion = MPI2_VERSION ; IOCInitMsg -> HeaderVersion = MPI2_HEADER_VERSION ; IOCInitMsg -> SystemRequestFrameSize = MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE / 4 ; IOCInitMsg -> ReplyDescriptorPostQueueDepth = sc -> reply_q_depth ; IOCInitMsg -> ReplyDescriptorPostQueueAddress = sc -> reply_desc_phys_addr ; IOCInitMsg -> SystemRequestFrameBaseAddress = sc -> io_request_phys_addr ; IOCInitMsg -> HostMSIxVectors = ( sc -> msix_vectors > 0 ? sc -> msix_vectors : 0 ) ; init_frame = ( struct mrsas_init_frame * ) sc -> ioc_init_mem ; init_frame -> cmd = MFI_CMD_INIT ; init_frame -> cmd_status = 0xFF ; init_frame -> flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE ; if ( ( sc -> device_id == MRSAS_INVADER ) || ( sc -> device_id == MRSAS_FURY ) || ( sc -> device_id == MRSAS_INTRUDER ) || ( sc -> device_id == MRSAS_INTRUDER_24 ) || ( sc -> device_id == MRSAS_CUTLASS_52 ) || ( sc -> device_id == MRSAS_CUTLASS_53 ) ) { init_frame -> driver_operations . mfi_capabilities . support_additional_msix = 1 ; } if ( sc -> verbuf_mem ) { snprintf ( ( char * ) sc -> verbuf_mem , strlen ( MRSAS_VERSION ) + 2 , " \n " , MRSAS_VERSION ) ; init_frame -> driver_ver_lo = ( bus_addr_t ) sc -> verbuf_phys_addr ; init_frame -> driver_ver_hi = 0 ; } init_frame -> driver_operations . mfi_capabilities . support_ndrive_r1_lb = 1 ; init_frame -> driver_operations . mfi_capabilities . support_max_255lds = 1 ; init_frame -> driver_operations . mfi_capabilities . security_protocol_cmds_fw = 1 ; if ( sc -> max_chain_frame_sz > MEGASAS_CHAIN_FRAME_SZ_MIN ) init_frame -> driver_operations . mfi_capabilities . support_ext_io_size = 1 ; phys_addr = ( bus_addr_t ) sc -> ioc_init_phys_mem + 1024 ; init_frame -> queue_info_new_phys_addr_lo = phys_addr ; init_frame -> data_xfer_len = sizeof ( Mpi2IOCInitRequest_t ) ; req_desc . addr . Words = ( bus_addr_t ) sc -> ioc_init_phys_mem ; req_desc . MFAIo . RequestFlags = ( MRSAS_REQ_DESCRIPT_FLAGS_MFA << MRSAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT ) ; mrsas_disable_intr ( sc ) ; mrsas_dprint ( sc , MRSAS_OCR , " \n " ) ; mrsas_fire_cmd ( sc , req_desc . addr . u . low , req_desc . addr . u . high ) ; if ( init_frame -> cmd_status == 0xFF ) { for ( i = 0 ; i < ( max_wait * 1000 ) ; i ++ ) { if ( init_frame -> cmd_status == 0xFF ) DELAY ( 1000 ) ; else break ; } } if ( init_frame -> cmd_status == 0 ) mrsas_dprint ( sc , MRSAS_OCR , " \n " ) ; else { if ( init_frame -> cmd_status == 0xFF ) device_printf ( sc -> mrsas_dev , " \n " , max_wait ) ; else device_printf ( sc -> mrsas_dev , " \n " , init_frame -> cmd_status ) ; retcode = 1 ; } mrsas_free_ioc_cmd ( sc ) ; return ( retcode ) ; }
mrsas_ioc_init:      Sends IOC Init command to FW
 input:                       Adapter soft state
mrsas_ioc_init : Sends IOC Init command to FW input : Adapter soft state
/* Allocate memory for the IOC INIT command */ /* driver support Extended MSIX */ /*
	 * Poll response timer to wait for Firmware response.  While this
	 * timer with the DELAY call could block CPU, the time interval for
	 * this is only 1 millisecond.
	 */