sys/dev/mfi/mfi_tbolt.c
/*
 * This routine prepare and issue INIT2 frame to the Firmware
 */
This routine prepare and issue INIT2 frame to the Firmware
This routine prepare and issue INIT2 frame to the Firmware
int
mfi_tbolt_init_MFI_queue(struct mfi_softc *sc)
{
	struct MPI2_IOC_INIT_REQUEST   *mpi2IocInit;
	struct mfi_init_frame		*mfi_init;
	uintptr_t			offset = 0;
	bus_addr_t			phyAddress;
	MFI_ADDRESS			*mfiAddressTemp;
	struct mfi_command		*cm, cmd_tmp;
	int error;
	mtx_assert(&sc->mfi_io_lock, MA_OWNED);
	if (sc->MFA_enabled) {
		device_printf(sc->mfi_dev, "tbolt_init already initialised!\n");
		return 1;
	}
	if ((cm = mfi_dequeue_free(sc)) == NULL) {
		device_printf(sc->mfi_dev, "tbolt_init failed to get command "
		    " entry!\n");
		return (EBUSY);
	}
	cmd_tmp.cm_frame = cm->cm_frame;
	cmd_tmp.cm_frame_busaddr = cm->cm_frame_busaddr;
	cmd_tmp.cm_dmamap = cm->cm_dmamap;
	cm->cm_frame = (union mfi_frame *)((uintptr_t)sc->mfi_tb_init);
	cm->cm_frame_busaddr = sc->mfi_tb_init_busaddr;
	cm->cm_dmamap = sc->mfi_tb_init_dmamap;
	cm->cm_frame->header.context = 0;
	mfi_init = &cm->cm_frame->init;
	mpi2IocInit = (struct MPI2_IOC_INIT_REQUEST *)sc->mfi_tb_ioc_init_desc;
	bzero(mpi2IocInit, sizeof(struct MPI2_IOC_INIT_REQUEST));
	mpi2IocInit->Function  = MPI2_FUNCTION_IOC_INIT;
	mpi2IocInit->WhoInit   = MPI2_WHOINIT_HOST_DRIVER;
	mpi2IocInit->MsgVersion = MPI2_VERSION;
	mpi2IocInit->HeaderVersion = MPI2_HEADER_VERSION;
	mpi2IocInit->SystemRequestFrameSize = sc->raid_io_msg_size/4;
	mpi2IocInit->ReplyDescriptorPostQueueDepth
	    = (uint16_t)sc->mfi_max_fw_cmds;
	mpi2IocInit->ReplyFreeQueueDepth = 0; 
	offset = (uintptr_t) sc->reply_frame_pool_align
	    - (uintptr_t)sc->request_message_pool;
	phyAddress = sc->mfi_tb_busaddr + offset;
	mfiAddressTemp =
	    (MFI_ADDRESS *)&mpi2IocInit->ReplyDescriptorPostQueueAddress;
	mfiAddressTemp->u.addressLow = (uint32_t)phyAddress;
	mfiAddressTemp->u.addressHigh = (uint32_t)((uint64_t)phyAddress >> 32);
	offset = sc->request_message_pool_align - sc->request_message_pool;
	phyAddress =  sc->mfi_tb_busaddr + offset;
	mfiAddressTemp = (MFI_ADDRESS *)&mpi2IocInit->SystemRequestFrameBaseAddress;
	mfiAddressTemp->u.addressLow = (uint32_t)phyAddress;
	mfiAddressTemp->u.addressHigh = (uint32_t)((uint64_t)phyAddress >> 32);
	mpi2IocInit->ReplyFreeQueueAddress =  0; 
	mpi2IocInit->TimeStamp = time_uptime;
	if (sc->verbuf) {
		snprintf((char *)sc->verbuf, strlen(MEGASAS_VERSION) + 2, "%s\n",
                MEGASAS_VERSION);
		mfi_init->driver_ver_lo = (uint32_t)sc->verbuf_h_busaddr;
		mfi_init->driver_ver_hi =
		    (uint32_t)((uint64_t)sc->verbuf_h_busaddr >> 32);
	}
	phyAddress =  sc->mfi_tb_ioc_init_busaddr;
	mfi_init->qinfo_new_addr_lo = (uint32_t)phyAddress;
	mfi_init->qinfo_new_addr_hi = (uint32_t)((uint64_t)phyAddress >> 32);
	mfi_init->header.flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
	mfi_init->header.cmd = MFI_CMD_INIT;
	mfi_init->header.data_len = sizeof(struct MPI2_IOC_INIT_REQUEST);
	mfi_init->header.cmd_status = MFI_STAT_INVALID_STATUS;
	cm->cm_data = NULL;
	cm->cm_flags |= MFI_CMD_POLLED;
	cm->cm_timestamp = time_uptime;
	if ((error = mfi_mapcmd(sc, cm)) != 0) {
		device_printf(sc->mfi_dev, "failed to send IOC init2 "
		    "command %d at %lx\n", error, (long)cm->cm_frame_busaddr);
		goto out;
	}
	if (mfi_init->header.cmd_status == MFI_STAT_OK) {
		sc->MFA_enabled = 1;
	} else {
		device_printf(sc->mfi_dev, "Init command Failed %#x\n",
		    mfi_init->header.cmd_status);
		error = mfi_init->header.cmd_status;
		goto out;
	}
out:
	cm->cm_frame = cmd_tmp.cm_frame;
	cm->cm_frame_busaddr = cmd_tmp.cm_frame_busaddr;
	cm->cm_dmamap = cmd_tmp.cm_dmamap;
	mfi_release_command(cm);
	return (error);
}
int mfi_tbolt_init_MFI_queue ( struct mfi_softc * sc ) { struct MPI2_IOC_INIT_REQUEST * mpi2IocInit ; struct mfi_init_frame * mfi_init ; uintptr_t offset = 0 ; bus_addr_t phyAddress ; MFI_ADDRESS * mfiAddressTemp ; struct mfi_command * cm , cmd_tmp ; int error ; mtx_assert ( & sc -> mfi_io_lock , MA_OWNED ) ; if ( sc -> MFA_enabled ) { device_printf ( sc -> mfi_dev , " \n " ) ; return 1 ; } if ( ( cm = mfi_dequeue_free ( sc ) ) == NULL ) { device_printf ( sc -> mfi_dev , " " " \n " ) ; return ( EBUSY ) ; } cmd_tmp . cm_frame = cm -> cm_frame ; cmd_tmp . cm_frame_busaddr = cm -> cm_frame_busaddr ; cmd_tmp . cm_dmamap = cm -> cm_dmamap ; cm -> cm_frame = ( union mfi_frame * ) ( ( uintptr_t ) sc -> mfi_tb_init ) ; cm -> cm_frame_busaddr = sc -> mfi_tb_init_busaddr ; cm -> cm_dmamap = sc -> mfi_tb_init_dmamap ; cm -> cm_frame -> header . context = 0 ; mfi_init = & cm -> cm_frame -> init ; mpi2IocInit = ( struct MPI2_IOC_INIT_REQUEST * ) sc -> mfi_tb_ioc_init_desc ; bzero ( mpi2IocInit , sizeof ( struct MPI2_IOC_INIT_REQUEST ) ) ; mpi2IocInit -> Function = MPI2_FUNCTION_IOC_INIT ; mpi2IocInit -> WhoInit = MPI2_WHOINIT_HOST_DRIVER ; mpi2IocInit -> MsgVersion = MPI2_VERSION ; mpi2IocInit -> HeaderVersion = MPI2_HEADER_VERSION ; mpi2IocInit -> SystemRequestFrameSize = sc -> raid_io_msg_size / 4 ; mpi2IocInit -> ReplyDescriptorPostQueueDepth = ( uint16_t ) sc -> mfi_max_fw_cmds ; mpi2IocInit -> ReplyFreeQueueDepth = 0 ; offset = ( uintptr_t ) sc -> reply_frame_pool_align - ( uintptr_t ) sc -> request_message_pool ; phyAddress = sc -> mfi_tb_busaddr + offset ; mfiAddressTemp = ( MFI_ADDRESS * ) & mpi2IocInit -> ReplyDescriptorPostQueueAddress ; mfiAddressTemp -> u . addressLow = ( uint32_t ) phyAddress ; mfiAddressTemp -> u . addressHigh = ( uint32_t ) ( ( uint64_t ) phyAddress >> 32 ) ; offset = sc -> request_message_pool_align - sc -> request_message_pool ; phyAddress = sc -> mfi_tb_busaddr + offset ; mfiAddressTemp = ( MFI_ADDRESS * ) & mpi2IocInit -> SystemRequestFrameBaseAddress ; mfiAddressTemp -> u . addressLow = ( uint32_t ) phyAddress ; mfiAddressTemp -> u . addressHigh = ( uint32_t ) ( ( uint64_t ) phyAddress >> 32 ) ; mpi2IocInit -> ReplyFreeQueueAddress = 0 ; mpi2IocInit -> TimeStamp = time_uptime ; if ( sc -> verbuf ) { snprintf ( ( char * ) sc -> verbuf , strlen ( MEGASAS_VERSION ) + 2 , " \n " , MEGASAS_VERSION ) ; mfi_init -> driver_ver_lo = ( uint32_t ) sc -> verbuf_h_busaddr ; mfi_init -> driver_ver_hi = ( uint32_t ) ( ( uint64_t ) sc -> verbuf_h_busaddr >> 32 ) ; } phyAddress = sc -> mfi_tb_ioc_init_busaddr ; mfi_init -> qinfo_new_addr_lo = ( uint32_t ) phyAddress ; mfi_init -> qinfo_new_addr_hi = ( uint32_t ) ( ( uint64_t ) phyAddress >> 32 ) ; mfi_init -> header . flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE ; mfi_init -> header . cmd = MFI_CMD_INIT ; mfi_init -> header . data_len = sizeof ( struct MPI2_IOC_INIT_REQUEST ) ; mfi_init -> header . cmd_status = MFI_STAT_INVALID_STATUS ; cm -> cm_data = NULL ; cm -> cm_flags |= MFI_CMD_POLLED ; cm -> cm_timestamp = time_uptime ; if ( ( error = mfi_mapcmd ( sc , cm ) ) != 0 ) { device_printf ( sc -> mfi_dev , " " " \n " , error , ( long ) cm -> cm_frame_busaddr ) ; goto out ; } if ( mfi_init -> header . cmd_status == MFI_STAT_OK ) { sc -> MFA_enabled = 1 ; } else { device_printf ( sc -> mfi_dev , " \n " , mfi_init -> header . cmd_status ) ; error = mfi_init -> header . cmd_status ; goto out ; } out : cm -> cm_frame = cmd_tmp . cm_frame ; cm -> cm_frame_busaddr = cmd_tmp . cm_frame_busaddr ; cm -> cm_dmamap = cmd_tmp . cm_dmamap ; mfi_release_command ( cm ) ; return ( error ) ; }
This routine prepare and issue INIT2 frame to the Firmware
This routine prepare and issue INIT2 frame to the Firmware
/* Check if initialization is already completed */ /*
	 * Abuse the SG list area of the frame to hold the init_qinfo
	 * object;
	 */ /* set MsgVersion and HeaderVersion host driver was built with */ /* Not supported by MR. */ /* Get physical address of reply frame pool */ /* Get physical address of request message pool */ /* Not supported by MR. */ /* Get the physical address of the mpi2 ioc init command */