FreeBSD/sys/dev/mrsas/mrsas.c
/*
 * mrsas_alloc_mpt_cmds:	Allocates the command packets
 * input:					Adapter instance soft state
 *
 * This function allocates the internal commands for IOs. Each command that is
 * issued to FW is wrapped in a local data structure called mrsas_mpt_cmd. An
 * array is allocated with mrsas_mpt_cmd context.  The free commands are
 * maintained in a linked list (cmd pool). SMID value range is from 1 to
 * max_fw_cmds.
 */
Allocates the command packets
input:                                       Adapter instance soft state

This function allocates the internal commands for IOs. Each command that is
issued to FW is wrapped in a local data structure called mrsas_mpt_cmd. An
array is allocated with mrsas_mpt_cmd context.  The free commands are
maintained in a linked list (cmd pool). SMID value range is from 1 to
max_fw_cmds.
Allocates the command packets input : Adapter instance soft state This function allocates the internal commands for IOs . Each command that is issued to FW is wrapped in a local data structure called mrsas_mpt_cmd . An array is allocated with mrsas_mpt_cmd context . The free commands are maintained in a linked list ( cmd pool ) . SMID value range is from 1 to max_fw_cmds .
int
mrsas_alloc_mpt_cmds(struct mrsas_softc *sc)
{
	int i, j;
	u_int32_t max_cmd, count;
	struct mrsas_mpt_cmd *cmd;
	pMpi2ReplyDescriptorsUnion_t reply_desc;
	u_int32_t offset, chain_offset, sense_offset;
	bus_addr_t io_req_base_phys, chain_frame_base_phys, sense_base_phys;
	u_int8_t *io_req_base, *chain_frame_base, *sense_base;
	max_cmd = sc->max_fw_cmds;
	sc->req_desc = malloc(sc->request_alloc_sz, M_MRSAS, M_NOWAIT);
	if (!sc->req_desc) {
		device_printf(sc->mrsas_dev, "Out of memory, cannot alloc req desc\n");
		return (ENOMEM);
	}
	memset(sc->req_desc, 0, sc->request_alloc_sz);
	sc->mpt_cmd_list = malloc(sizeof(struct mrsas_mpt_cmd *) * max_cmd, M_MRSAS, M_NOWAIT);
	if (!sc->mpt_cmd_list) {
		device_printf(sc->mrsas_dev, "Cannot alloc memory for mpt_cmd_list.\n");
		return (ENOMEM);
	}
	memset(sc->mpt_cmd_list, 0, sizeof(struct mrsas_mpt_cmd *) * max_cmd);
	for (i = 0; i < max_cmd; i++) {
		sc->mpt_cmd_list[i] = malloc(sizeof(struct mrsas_mpt_cmd),
		    M_MRSAS, M_NOWAIT);
		if (!sc->mpt_cmd_list[i]) {
			for (j = 0; j < i; j++)
				free(sc->mpt_cmd_list[j], M_MRSAS);
			free(sc->mpt_cmd_list, M_MRSAS);
			sc->mpt_cmd_list = NULL;
			return (ENOMEM);
		}
	}
	io_req_base = (u_int8_t *)sc->io_request_mem + MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE;
	io_req_base_phys = (bus_addr_t)sc->io_request_phys_addr + MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE;
	chain_frame_base = (u_int8_t *)sc->chain_frame_mem;
	chain_frame_base_phys = (bus_addr_t)sc->chain_frame_phys_addr;
	sense_base = (u_int8_t *)sc->sense_mem;
	sense_base_phys = (bus_addr_t)sc->sense_phys_addr;
	for (i = 0; i < max_cmd; i++) {
		cmd = sc->mpt_cmd_list[i];
		offset = MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE * i;
		chain_offset = sc->max_chain_frame_sz * i;
		sense_offset = MRSAS_SENSE_LEN * i;
		memset(cmd, 0, sizeof(struct mrsas_mpt_cmd));
		cmd->index = i + 1;
		cmd->ccb_ptr = NULL;
		callout_init(&cmd->cm_callout, 0);
		cmd->sync_cmd_idx = (u_int32_t)MRSAS_ULONG_MAX;
		cmd->sc = sc;
		cmd->io_request = (MRSAS_RAID_SCSI_IO_REQUEST *) (io_req_base + offset);
		memset(cmd->io_request, 0, sizeof(MRSAS_RAID_SCSI_IO_REQUEST));
		cmd->io_request_phys_addr = io_req_base_phys + offset;
		cmd->chain_frame = (MPI2_SGE_IO_UNION *) (chain_frame_base + chain_offset);
		cmd->chain_frame_phys_addr = chain_frame_base_phys + chain_offset;
		cmd->sense = sense_base + sense_offset;
		cmd->sense_phys_addr = sense_base_phys + sense_offset;
		if (bus_dmamap_create(sc->data_tag, 0, &cmd->data_dmamap)) {
			return (FAIL);
		}
		TAILQ_INSERT_TAIL(&(sc->mrsas_mpt_cmd_list_head), cmd, next);
	}
	reply_desc = sc->reply_desc_mem;
	count = sc->msix_vectors > 0 ? sc->msix_vectors : 1;
	for (i = 0; i < sc->reply_q_depth * count; i++, reply_desc++) {
		reply_desc->Words = MRSAS_ULONG_MAX;
	}
	return (0);
}
int mrsas_alloc_mpt_cmds ( struct mrsas_softc * sc ) { int i , j ; u_int32_t max_cmd , count ; struct mrsas_mpt_cmd * cmd ; pMpi2ReplyDescriptorsUnion_t reply_desc ; u_int32_t offset , chain_offset , sense_offset ; bus_addr_t io_req_base_phys , chain_frame_base_phys , sense_base_phys ; u_int8_t * io_req_base , * chain_frame_base , * sense_base ; max_cmd = sc -> max_fw_cmds ; sc -> req_desc = malloc ( sc -> request_alloc_sz , M_MRSAS , M_NOWAIT ) ; if ( ! sc -> req_desc ) { device_printf ( sc -> mrsas_dev , " \n " ) ; return ( ENOMEM ) ; } memset ( sc -> req_desc , 0 , sc -> request_alloc_sz ) ; sc -> mpt_cmd_list = malloc ( sizeof ( struct mrsas_mpt_cmd * ) * max_cmd , M_MRSAS , M_NOWAIT ) ; if ( ! sc -> mpt_cmd_list ) { device_printf ( sc -> mrsas_dev , " \n " ) ; return ( ENOMEM ) ; } memset ( sc -> mpt_cmd_list , 0 , sizeof ( struct mrsas_mpt_cmd * ) * max_cmd ) ; for ( i = 0 ; i < max_cmd ; i ++ ) { sc -> mpt_cmd_list [ i ] = malloc ( sizeof ( struct mrsas_mpt_cmd ) , M_MRSAS , M_NOWAIT ) ; if ( ! sc -> mpt_cmd_list [ i ] ) { for ( j = 0 ; j < i ; j ++ ) free ( sc -> mpt_cmd_list [ j ] , M_MRSAS ) ; free ( sc -> mpt_cmd_list , M_MRSAS ) ; sc -> mpt_cmd_list = NULL ; return ( ENOMEM ) ; } } io_req_base = ( u_int8_t * ) sc -> io_request_mem + MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE ; io_req_base_phys = ( bus_addr_t ) sc -> io_request_phys_addr + MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE ; chain_frame_base = ( u_int8_t * ) sc -> chain_frame_mem ; chain_frame_base_phys = ( bus_addr_t ) sc -> chain_frame_phys_addr ; sense_base = ( u_int8_t * ) sc -> sense_mem ; sense_base_phys = ( bus_addr_t ) sc -> sense_phys_addr ; for ( i = 0 ; i < max_cmd ; i ++ ) { cmd = sc -> mpt_cmd_list [ i ] ; offset = MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE * i ; chain_offset = sc -> max_chain_frame_sz * i ; sense_offset = MRSAS_SENSE_LEN * i ; memset ( cmd , 0 , sizeof ( struct mrsas_mpt_cmd ) ) ; cmd -> index = i + 1 ; cmd -> ccb_ptr = NULL ; callout_init ( & cmd -> cm_callout , 0 ) ; cmd -> sync_cmd_idx = ( u_int32_t ) MRSAS_ULONG_MAX ; cmd -> sc = sc ; cmd -> io_request = ( MRSAS_RAID_SCSI_IO_REQUEST * ) ( io_req_base + offset ) ; memset ( cmd -> io_request , 0 , sizeof ( MRSAS_RAID_SCSI_IO_REQUEST ) ) ; cmd -> io_request_phys_addr = io_req_base_phys + offset ; cmd -> chain_frame = ( MPI2_SGE_IO_UNION * ) ( chain_frame_base + chain_offset ) ; cmd -> chain_frame_phys_addr = chain_frame_base_phys + chain_offset ; cmd -> sense = sense_base + sense_offset ; cmd -> sense_phys_addr = sense_base_phys + sense_offset ; if ( bus_dmamap_create ( sc -> data_tag , 0 , & cmd -> data_dmamap ) ) { return ( FAIL ) ; } TAILQ_INSERT_TAIL ( & ( sc -> mrsas_mpt_cmd_list_head ) , cmd , next ) ; } reply_desc = sc -> reply_desc_mem ; count = sc -> msix_vectors > 0 ? sc -> msix_vectors : 1 ; for ( i = 0 ; i < sc -> reply_q_depth * count ; i ++ , reply_desc ++ ) { reply_desc -> Words = MRSAS_ULONG_MAX ; } return ( 0 ) ; }
mrsas_alloc_mpt_cmds:        Allocates the command packets
 input:                                       Adapter instance soft state
mrsas_alloc_mpt_cmds : Allocates the command packets input : Adapter instance soft state
/*
	 * sc->mpt_cmd_list is an array of struct mrsas_mpt_cmd pointers.
	 * Allocate the dynamic array first and then allocate individual
	 * commands.
	 */ /* Initialize reply descriptor array to 0xFFFFFFFF */