FreeBSD/sys/dev/mrsas/mrsas.c
/*
 * mrsas_get_pd_list:           Returns FW's PD list structure input:
 * Adapter soft state
 *
 * Issues an internal command (DCMD) to get the FW's controller PD list
 * structure.  This information is mainly used to find out about system
 * supported by Firmware.
 */
Returns FW's PD list structure input:
Adapter soft state

Issues an internal command (DCMD) to get the FW's controller PD list
structure.  This information is mainly used to find out about system
supported by Firmware.
Returns FW ' s PD list structure input : Adapter soft state Issues an internal command ( DCMD ) to get the FW ' s controller PD list structure . This information is mainly used to find out about system supported by Firmware .
static int
mrsas_get_pd_list(struct mrsas_softc *sc)
{
	int retcode = 0, pd_index = 0, pd_count = 0, pd_list_size;
	u_int8_t do_ocr = 1;
	struct mrsas_mfi_cmd *cmd;
	struct mrsas_dcmd_frame *dcmd;
	struct MR_PD_LIST *pd_list_mem;
	struct MR_PD_ADDRESS *pd_addr;
	bus_addr_t pd_list_phys_addr = 0;
	struct mrsas_tmp_dcmd *tcmd;
	cmd = mrsas_get_mfi_cmd(sc);
	if (!cmd) {
		device_printf(sc->mrsas_dev,
		    "Cannot alloc for get PD list cmd\n");
		return 1;
	}
	dcmd = &cmd->frame->dcmd;
	tcmd = malloc(sizeof(struct mrsas_tmp_dcmd), M_MRSAS, M_NOWAIT);
	pd_list_size = MRSAS_MAX_PD * sizeof(struct MR_PD_LIST);
	if (mrsas_alloc_tmp_dcmd(sc, tcmd, pd_list_size) != SUCCESS) {
		device_printf(sc->mrsas_dev,
		    "Cannot alloc dmamap for get PD list cmd\n");
		mrsas_release_mfi_cmd(cmd);
		mrsas_free_tmp_dcmd(tcmd);
		free(tcmd, M_MRSAS);
		return (ENOMEM);
	} else {
		pd_list_mem = tcmd->tmp_dcmd_mem;
		pd_list_phys_addr = tcmd->tmp_dcmd_phys_addr;
	}
	memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
	dcmd->mbox.b[0] = MR_PD_QUERY_TYPE_EXPOSED_TO_HOST;
	dcmd->mbox.b[1] = 0;
	dcmd->cmd = MFI_CMD_DCMD;
	dcmd->cmd_status = 0xFF;
	dcmd->sge_count = 1;
	dcmd->flags = MFI_FRAME_DIR_READ;
	dcmd->timeout = 0;
	dcmd->pad_0 = 0;
	dcmd->data_xfer_len = MRSAS_MAX_PD * sizeof(struct MR_PD_LIST);
	dcmd->opcode = MR_DCMD_PD_LIST_QUERY;
	dcmd->sgl.sge32[0].phys_addr = pd_list_phys_addr;
	dcmd->sgl.sge32[0].length = MRSAS_MAX_PD * sizeof(struct MR_PD_LIST);
	retcode = mrsas_issue_polled(sc, cmd);
	if (retcode == ETIMEDOUT)
		goto dcmd_timeout;
	pd_count = MRSAS_MAX_PD;
	pd_addr = pd_list_mem->addr;
	if (pd_list_mem->count < pd_count) {
		memset(sc->local_pd_list, 0,
		    MRSAS_MAX_PD * sizeof(struct mrsas_pd_list));
		for (pd_index = 0; pd_index < pd_list_mem->count; pd_index++) {
			sc->local_pd_list[pd_addr->deviceId].tid = pd_addr->deviceId;
			sc->local_pd_list[pd_addr->deviceId].driveType =
			    pd_addr->scsiDevType;
			sc->local_pd_list[pd_addr->deviceId].driveState =
			    MR_PD_STATE_SYSTEM;
			pd_addr++;
		}
		memcpy(sc->pd_list, sc->local_pd_list, sizeof(sc->local_pd_list));
		do_ocr = 0;
	}
dcmd_timeout:
	mrsas_free_tmp_dcmd(tcmd);
	free(tcmd, M_MRSAS);
	if (do_ocr)
		sc->do_timedout_reset = MFI_DCMD_TIMEOUT_OCR;
	else
		mrsas_release_mfi_cmd(cmd);
	return (retcode);
}
static int mrsas_get_pd_list ( struct mrsas_softc * sc ) { int retcode = 0 , pd_index = 0 , pd_count = 0 , pd_list_size ; u_int8_t do_ocr = 1 ; struct mrsas_mfi_cmd * cmd ; struct mrsas_dcmd_frame * dcmd ; struct MR_PD_LIST * pd_list_mem ; struct MR_PD_ADDRESS * pd_addr ; bus_addr_t pd_list_phys_addr = 0 ; struct mrsas_tmp_dcmd * tcmd ; cmd = mrsas_get_mfi_cmd ( sc ) ; if ( ! cmd ) { device_printf ( sc -> mrsas_dev , " \n " ) ; return 1 ; } dcmd = & cmd -> frame -> dcmd ; tcmd = malloc ( sizeof ( struct mrsas_tmp_dcmd ) , M_MRSAS , M_NOWAIT ) ; pd_list_size = MRSAS_MAX_PD * sizeof ( struct MR_PD_LIST ) ; if ( mrsas_alloc_tmp_dcmd ( sc , tcmd , pd_list_size ) != SUCCESS ) { device_printf ( sc -> mrsas_dev , " \n " ) ; mrsas_release_mfi_cmd ( cmd ) ; mrsas_free_tmp_dcmd ( tcmd ) ; free ( tcmd , M_MRSAS ) ; return ( ENOMEM ) ; } else { pd_list_mem = tcmd -> tmp_dcmd_mem ; pd_list_phys_addr = tcmd -> tmp_dcmd_phys_addr ; } memset ( dcmd -> mbox . b , 0 , MFI_MBOX_SIZE ) ; dcmd -> mbox . b [ 0 ] = MR_PD_QUERY_TYPE_EXPOSED_TO_HOST ; dcmd -> mbox . b [ 1 ] = 0 ; dcmd -> cmd = MFI_CMD_DCMD ; dcmd -> cmd_status = 0xFF ; dcmd -> sge_count = 1 ; dcmd -> flags = MFI_FRAME_DIR_READ ; dcmd -> timeout = 0 ; dcmd -> pad_0 = 0 ; dcmd -> data_xfer_len = MRSAS_MAX_PD * sizeof ( struct MR_PD_LIST ) ; dcmd -> opcode = MR_DCMD_PD_LIST_QUERY ; dcmd -> sgl . sge32 [ 0 ] . phys_addr = pd_list_phys_addr ; dcmd -> sgl . sge32 [ 0 ] . length = MRSAS_MAX_PD * sizeof ( struct MR_PD_LIST ) ; retcode = mrsas_issue_polled ( sc , cmd ) ; if ( retcode == ETIMEDOUT ) goto dcmd_timeout ; pd_count = MRSAS_MAX_PD ; pd_addr = pd_list_mem -> addr ; if ( pd_list_mem -> count < pd_count ) { memset ( sc -> local_pd_list , 0 , MRSAS_MAX_PD * sizeof ( struct mrsas_pd_list ) ) ; for ( pd_index = 0 ; pd_index < pd_list_mem -> count ; pd_index ++ ) { sc -> local_pd_list [ pd_addr -> deviceId ] . tid = pd_addr -> deviceId ; sc -> local_pd_list [ pd_addr -> deviceId ] . driveType = pd_addr -> scsiDevType ; sc -> local_pd_list [ pd_addr -> deviceId ] . driveState = MR_PD_STATE_SYSTEM ; pd_addr ++ ; } memcpy ( sc -> pd_list , sc -> local_pd_list , sizeof ( sc -> local_pd_list ) ) ; do_ocr = 0 ; } dcmd_timeout : mrsas_free_tmp_dcmd ( tcmd ) ; free ( tcmd , M_MRSAS ) ; if ( do_ocr ) sc -> do_timedout_reset = MFI_DCMD_TIMEOUT_OCR ; else mrsas_release_mfi_cmd ( cmd ) ; return ( retcode ) ; }
mrsas_get_pd_list:           Returns FW's PD list structure input:
 Adapter soft state
mrsas_get_pd_list : Returns FW ' s PD list structure input : Adapter soft state
/* Get the instance PD list */ /*
		 * Use mutext/spinlock if pd_list component size increase more than
		 * 32 bit.
		 */