Пример #1
0
/**
 * qla24xx_prep_ms_iocb() - Prepare common CT IOCB fields for SNS CT query.
 * @ha: HA context
 * @req_size: request size in bytes
 * @rsp_size: response size in bytes
 *
 * Returns a pointer to the @ha's ms_iocb.
 */
void *
qla24xx_prep_ms_iocb(scsi_qla_host_t *vha, uint32_t req_size, uint32_t rsp_size)
{
	struct qla_hw_data *ha = vha->hw;
	struct ct_entry_24xx *ct_pkt;

	ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
	memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));

	ct_pkt->entry_type = CT_IOCB_TYPE;
	ct_pkt->entry_count = 1;
	ct_pkt->nport_handle = __constant_cpu_to_le16(NPH_SNS);
	ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
	ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
	ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1);
	ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
	ct_pkt->cmd_byte_count = cpu_to_le32(req_size);

	ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
	ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
	ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;

	ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
	ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
	ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
	ct_pkt->vp_index = vha->vp_idx;

	return (ct_pkt);
}
Пример #2
0
static int ql_mb_dump_ram(struct ql_adapter *qdev, u64 req_dma, u32 addr,
	u32 size)
{
	int status = 0;
	struct mbox_params mbc;
	struct mbox_params *mbcp = &mbc;

	memset(mbcp, 0, sizeof(struct mbox_params));

	mbcp->in_count = 9;
	mbcp->out_count = 1;

	mbcp->mbox_in[0] = MB_CMD_DUMP_RISC_RAM;
	mbcp->mbox_in[1] = LSW(addr);
	mbcp->mbox_in[2] = MSW(req_dma);
	mbcp->mbox_in[3] = LSW(req_dma);
	mbcp->mbox_in[4] = MSW(size);
	mbcp->mbox_in[5] = LSW(size);
	mbcp->mbox_in[6] = MSW(MSD(req_dma));
	mbcp->mbox_in[7] = LSW(MSD(req_dma));
	mbcp->mbox_in[8] = MSW(addr);


	status = ql_mailbox_command(qdev, mbcp);
	if (status)
		return status;

	if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
		netif_err(qdev, drv, qdev->ndev, "Failed to dump risc RAM.\n");
		status = -EIO;
	}
	return status;
}
Пример #3
0
/**
 * qla24xx_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
 * @ha: HA context
 * @req_size: request size in bytes
 * @rsp_size: response size in bytes
 *
 * Returns a pointer to the @ha's ms_iocb.
 */
void *
qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size,
    uint32_t rsp_size)
{
	struct ct_entry_24xx *ct_pkt;

	ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
	memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));

	ct_pkt->entry_type = CT_IOCB_TYPE;
	ct_pkt->entry_count = 1;
	ct_pkt->nport_handle = cpu_to_le16(ha->mgmt_svr_loop_id);
	ct_pkt->timeout = __constant_cpu_to_le16(59);
	ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
	ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1);
	ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
	ct_pkt->cmd_byte_count = cpu_to_le32(req_size);

	ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
	ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
	ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;

	ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
	ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
	ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;

	return ct_pkt;
}
Пример #4
0
/**
 * qla2x00_prep_ms_iocb() - Prepare common MS/CT IOCB fields for SNS CT query.
 * @ha: HA context
 * @req_size: request size in bytes
 * @rsp_size: response size in bytes
 *
 * Returns a pointer to the @ha's ms_iocb.
 */
void *
qla2x00_prep_ms_iocb(scsi_qla_host_t *vha, uint32_t req_size, uint32_t rsp_size)
{
	struct qla_hw_data *ha = vha->hw;
	ms_iocb_entry_t *ms_pkt;

	ms_pkt = ha->ms_iocb;
	memset(ms_pkt, 0, sizeof(ms_iocb_entry_t));

	ms_pkt->entry_type = MS_IOCB_TYPE;
	ms_pkt->entry_count = 1;
	SET_TARGET_ID(ha, ms_pkt->loop_id, SIMPLE_NAME_SERVER);
	ms_pkt->control_flags = __constant_cpu_to_le16(CF_READ | CF_HEAD_TAG);
	ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
	ms_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
	ms_pkt->total_dsd_count = __constant_cpu_to_le16(2);
	ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size);
	ms_pkt->req_bytecount = cpu_to_le32(req_size);

	ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
	ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
	ms_pkt->dseg_req_length = ms_pkt->req_bytecount;

	ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
	ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
	ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount;

	return (ms_pkt);
}
Пример #5
0
/**
 * qla2x00_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
 * @ha: HA context
 * @req_size: request size in bytes
 * @rsp_size: response size in bytes
 *
 * Returns a pointer to the @ha's ms_iocb.
 */
void *
qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size,
    uint32_t rsp_size)
{
	ms_iocb_entry_t *ms_pkt;

	ms_pkt = ha->ms_iocb;
	memset(ms_pkt, 0, sizeof(ms_iocb_entry_t));

	ms_pkt->entry_type = MS_IOCB_TYPE;
	ms_pkt->entry_count = 1;
	SET_TARGET_ID(ha, ms_pkt->loop_id, ha->mgmt_svr_loop_id);
	ms_pkt->control_flags = __constant_cpu_to_le16(CF_READ | CF_HEAD_TAG);
	ms_pkt->timeout = __constant_cpu_to_le16(59);
	ms_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
	ms_pkt->total_dsd_count = __constant_cpu_to_le16(2);
	ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size);
	ms_pkt->req_bytecount = cpu_to_le32(req_size);

	ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
	ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
	ms_pkt->dseg_req_length = ms_pkt->req_bytecount;

	ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
	ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
	ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount;

	return ms_pkt;
}
Пример #6
0
void arssort(string strings[], size_t scnt)
{
   list listnodes;
   int i;

    /* allocate memory based on the number of strings in the array */
    listnodes = (list ) calloc(scnt, sizeof(struct listrec));

    /* point the linked list nodes to the strings in the array */
    for( i=0; i<scnt; i++)
    {
        listnodes[i].str = strings[i];
        if (i<(scnt-1))
           listnodes[i].next = &listnodes[i+1]; 
        else
           listnodes[i].next = NULL;
    }

    /* sort */
    listnodes = MSD(listnodes, scnt);

    /* write the strings back into the array */
    for (i = 0;  i < scnt ; i++, listnodes=listnodes->next)
       strings[i] = listnodes->str;

   return;
}
Пример #7
0
/* Get info of a NIC partition */
int qlcnic_get_nic_info(struct qlcnic_adapter *adapter,
				struct qlcnic_info *npar_info, u8 func_id)
{
	int	err;
	dma_addr_t nic_dma_t;
	struct qlcnic_info *nic_info;
	void *nic_info_addr;
	size_t	nic_size = sizeof(struct qlcnic_info);

	nic_info_addr = pci_alloc_consistent(adapter->pdev,
		nic_size, &nic_dma_t);
	if (!nic_info_addr)
		return -ENOMEM;
	memset(nic_info_addr, 0, nic_size);

	nic_info = (struct qlcnic_info *) nic_info_addr;
	err = qlcnic_issue_cmd(adapter,
			adapter->ahw.pci_func,
			adapter->fw_hal_version,
			MSD(nic_dma_t),
			LSD(nic_dma_t),
			(func_id << 16 | nic_size),
			QLCNIC_CDRP_CMD_GET_NIC_INFO);

	if (err == QLCNIC_RCODE_SUCCESS) {
		npar_info->pci_func = le16_to_cpu(nic_info->pci_func);
		npar_info->op_mode = le16_to_cpu(nic_info->op_mode);
		npar_info->phys_port = le16_to_cpu(nic_info->phys_port);
		npar_info->switch_mode = le16_to_cpu(nic_info->switch_mode);
		npar_info->max_tx_ques = le16_to_cpu(nic_info->max_tx_ques);
		npar_info->max_rx_ques = le16_to_cpu(nic_info->max_rx_ques);
		npar_info->min_tx_bw = le16_to_cpu(nic_info->min_tx_bw);
		npar_info->max_tx_bw = le16_to_cpu(nic_info->max_tx_bw);
		npar_info->capabilities = le32_to_cpu(nic_info->capabilities);
		npar_info->max_mtu = le16_to_cpu(nic_info->max_mtu);

		dev_info(&adapter->pdev->dev,
			"phy port: %d switch_mode: %d,\n"
			"\tmax_tx_q: %d max_rx_q: %d min_tx_bw: 0x%x,\n"
			"\tmax_tx_bw: 0x%x max_mtu:0x%x, capabilities: 0x%x\n",
			npar_info->phys_port, npar_info->switch_mode,
			npar_info->max_tx_ques, npar_info->max_rx_ques,
			npar_info->min_tx_bw, npar_info->max_tx_bw,
			npar_info->max_mtu, npar_info->capabilities);
	} else {
		dev_err(&adapter->pdev->dev,
			"Failed to get nic info%d\n", err);
		err = -EIO;
	}

	pci_free_consistent(adapter->pdev, nic_size, nic_info_addr, nic_dma_t);
	return err;
}
Пример #8
0
void MSD_seq(char **ffpp, char **ffii, const int nin, /**/ float *out) {

    BopData *dpp0, *dii0, *dpp, *dii;
    const int *ii0, *ii;
    const float *pp0, *pp;
    long np;

    BPC( bop_ini(&dpp0) );
    BPC( bop_ini(&dii0) );
    
    read_data(ffpp[0], dpp0, ffii[0], dii0);
    pp0 = (const float *) bop_get_data(dpp0);
    ii0 = (const   int *) bop_get_data(dii0);

    BPC( bop_get_n(dii0, &np) );
    const int buffsize = max_index(ii0, np) + 1;

    float *rr0 = new float[3*buffsize]; /* initial  positions     */
    float *rrc = new float[3*buffsize]; /* current  positions     */
    float *rrp = new float[3*buffsize]; /* previous positions     */
    float *ddL = new float[3*buffsize]; /* helper for periodic BC */

    memset(rr0, 0, 3*buffsize*sizeof(float));
    memset(ddL, 0, 3*buffsize*sizeof(float));
    pp2rr_sorted(ii0, pp0, np, 6, /**/ rr0);
    memcpy(rrp, rr0, 3*buffsize*sizeof(float));
    
    for (int i = 1; i < nin; ++i) {
        BPC( bop_ini(&dpp) );
        BPC( bop_ini(&dii) );
        
        read_data(ffpp[i], dpp, ffii[i], dii);
        pp = (const float *) bop_get_data(dpp);
        ii = (const   int *) bop_get_data(dii);

        memset(rrc, 0, 3*buffsize*sizeof(float));
        pp2rr_sorted(ii, pp, np, 6, /**/ rrc);
        updddL(rrp, rrc, buffsize, /**/ ddL);

        out[i-1] = MSD(rr0, rrc, ddL, buffsize, np);
        
        BPC( bop_fin(dpp) );
        BPC( bop_fin(dii) );
        memcpy(rrp, rrc, 3*buffsize*sizeof(float));
    }

    delete[] rr0; delete[] rrc;
    delete[] rrp; delete[] ddL;
    BPC( bop_fin(dpp0) );
    BPC( bop_fin(dii0) );
}
Пример #9
0
/* Get PCI Info of a partition */
int qlcnic_get_pci_info(struct qlcnic_adapter *adapter,
				struct qlcnic_pci_info *pci_info)
{
	int err = 0, i;
	dma_addr_t pci_info_dma_t;
	struct qlcnic_pci_info *npar;
	void *pci_info_addr;
	size_t npar_size = sizeof(struct qlcnic_pci_info);
	size_t pci_size = npar_size * QLCNIC_MAX_PCI_FUNC;

	pci_info_addr = pci_alloc_consistent(adapter->pdev, pci_size,
			&pci_info_dma_t);
	if (!pci_info_addr)
		return -ENOMEM;
	memset(pci_info_addr, 0, pci_size);

	npar = (struct qlcnic_pci_info *) pci_info_addr;
	err = qlcnic_issue_cmd(adapter,
			adapter->ahw.pci_func,
			adapter->fw_hal_version,
			MSD(pci_info_dma_t),
			LSD(pci_info_dma_t),
			pci_size,
			QLCNIC_CDRP_CMD_GET_PCI_INFO);

	if (err == QLCNIC_RCODE_SUCCESS) {
		for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++, npar++, pci_info++) {
			pci_info->id = le32_to_cpu(npar->id);
			pci_info->active = le32_to_cpu(npar->active);
			pci_info->type = le32_to_cpu(npar->type);
			pci_info->default_port =
				le32_to_cpu(npar->default_port);
			pci_info->tx_min_bw =
				le32_to_cpu(npar->tx_min_bw);
			pci_info->tx_max_bw =
				le32_to_cpu(npar->tx_max_bw);
			memcpy(pci_info->mac, npar->mac, ETH_ALEN);
		}
	} else {
		dev_err(&adapter->pdev->dev,
			"Failed to get PCI Info%d\n", err);
		err = -EIO;
	}

	pci_free_consistent(adapter->pdev, pci_size, pci_info_addr,
		pci_info_dma_t);
	return err;
}
Пример #10
0
/* Configure a NIC partition */
int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *nic)
{
	int err = -EIO;
	dma_addr_t nic_dma_t;
	void *nic_info_addr;
	struct qlcnic_info *nic_info;
	size_t nic_size = sizeof(struct qlcnic_info);

	if (adapter->op_mode != QLCNIC_MGMT_FUNC)
		return err;

	nic_info_addr = pci_alloc_consistent(adapter->pdev, nic_size,
			&nic_dma_t);
	if (!nic_info_addr)
		return -ENOMEM;

	memset(nic_info_addr, 0, nic_size);
	nic_info = (struct qlcnic_info *)nic_info_addr;

	nic_info->pci_func = cpu_to_le16(nic->pci_func);
	nic_info->op_mode = cpu_to_le16(nic->op_mode);
	nic_info->phys_port = cpu_to_le16(nic->phys_port);
	nic_info->switch_mode = cpu_to_le16(nic->switch_mode);
	nic_info->capabilities = cpu_to_le32(nic->capabilities);
	nic_info->max_mac_filters = nic->max_mac_filters;
	nic_info->max_tx_ques = cpu_to_le16(nic->max_tx_ques);
	nic_info->max_rx_ques = cpu_to_le16(nic->max_rx_ques);
	nic_info->min_tx_bw = cpu_to_le16(nic->min_tx_bw);
	nic_info->max_tx_bw = cpu_to_le16(nic->max_tx_bw);

	err = qlcnic_issue_cmd(adapter,
			adapter->ahw.pci_func,
			adapter->fw_hal_version,
			MSD(nic_dma_t),
			LSD(nic_dma_t),
			((nic->pci_func << 16) | nic_size),
			QLCNIC_CDRP_CMD_SET_NIC_INFO);

	if (err != QLCNIC_RCODE_SUCCESS) {
		dev_err(&adapter->pdev->dev,
			"Failed to set nic info%d\n", err);
		err = -EIO;
	}

	pci_free_consistent(adapter->pdev, nic_size, nic_info_addr, nic_dma_t);
	return err;
}
Пример #11
0
/**
 * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query.
 * @ha: HA context
 * @cmd: GS command
 * @scmd_len: Subcommand length
 * @data_size: response size in bytes
 *
 * Returns a pointer to the @ha's sns_cmd.
 */
static inline struct sns_cmd_pkt *
qla2x00_prep_sns_cmd(scsi_qla_host_t *ha, uint16_t cmd, uint16_t scmd_len,
    uint16_t data_size)
{
	uint16_t		wc;
	struct sns_cmd_pkt	*sns_cmd;

	sns_cmd = ha->sns_cmd;
	memset(sns_cmd, 0, sizeof(struct sns_cmd_pkt));
	wc = data_size / 2;			/* Size in 16bit words. */
	sns_cmd->p.cmd.buffer_length = cpu_to_le16(wc);
	sns_cmd->p.cmd.buffer_address[0] = cpu_to_le32(LSD(ha->sns_cmd_dma));
	sns_cmd->p.cmd.buffer_address[1] = cpu_to_le32(MSD(ha->sns_cmd_dma));
	sns_cmd->p.cmd.subcommand_length = cpu_to_le16(scmd_len);
	sns_cmd->p.cmd.subcommand = cpu_to_le16(cmd);
	wc = (data_size - 16) / 4;		/* Size in 32bit words. */
	sns_cmd->p.cmd.size = cpu_to_le16(wc);

	return (sns_cmd);
}
Пример #12
0
/**
 * qla2x00_build_scsi_iocbs_64() - Build IOCB command utilizing 64bit
 * capable IOCB types.
 *
 * @sp: SRB command to process
 * @cmd_pkt: Command type 3 IOCB
 * @tot_dsds: Total number of segments to transfer
 */
void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt,
    uint16_t tot_dsds)
{
	uint16_t	avail_dsds;
	uint32_t	*cur_dsd;
	scsi_qla_host_t	*ha;
	struct scsi_cmnd *cmd;

	cmd = sp->cmd;

	/* Update entry type to indicate Command Type 3 IOCB */
	*((uint32_t *)(&cmd_pkt->entry_type)) =
	    __constant_cpu_to_le32(COMMAND_A64_TYPE);

	/* No data transfer */
	if (cmd->request_bufflen == 0 || cmd->sc_data_direction == DMA_NONE) {
		cmd_pkt->byte_count = __constant_cpu_to_le32(0);
		return;
	}

	ha = sp->ha;

	cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(cmd));

	/* Two DSDs are available in the Command Type 3 IOCB */
	avail_dsds = 2;
	cur_dsd = (uint32_t *)&cmd_pkt->dseg_0_address;

	/* Load data segments */
	if (cmd->use_sg != 0) {
		struct	scatterlist *cur_seg;
		struct	scatterlist *end_seg;

		cur_seg = (struct scatterlist *)cmd->request_buffer;
		end_seg = cur_seg + tot_dsds;
		while (cur_seg < end_seg) {
			dma_addr_t	sle_dma;
			cont_a64_entry_t *cont_pkt;

			/* Allocate additional continuation packets? */
			if (avail_dsds == 0) {
				/*
				 * Five DSDs are available in the Continuation
				 * Type 1 IOCB.
				 */
				cont_pkt = qla2x00_prep_cont_type1_iocb(ha);
				cur_dsd = (uint32_t *)cont_pkt->dseg_0_address;
				avail_dsds = 5;
			}

			sle_dma = sg_dma_address(cur_seg);
			*cur_dsd++ = cpu_to_le32(LSD(sle_dma));
			*cur_dsd++ = cpu_to_le32(MSD(sle_dma));
			*cur_dsd++ = cpu_to_le32(sg_dma_len(cur_seg));
			avail_dsds--;

			cur_seg++;
		}
	} else {
		dma_addr_t	req_dma;
		struct page	*page;
		unsigned long	offset;

		page = virt_to_page(cmd->request_buffer);
		offset = ((unsigned long)cmd->request_buffer & ~PAGE_MASK);
		req_dma = pci_map_page(ha->pdev, page, offset,
		    cmd->request_bufflen, cmd->sc_data_direction);

		sp->dma_handle = req_dma;

		*cur_dsd++ = cpu_to_le32(LSD(req_dma));
		*cur_dsd++ = cpu_to_le32(MSD(req_dma));
		*cur_dsd++ = cpu_to_le32(cmd->request_bufflen);
	}
}
Пример #13
0
/**
 * qla24xx_build_scsi_iocbs() - Build IOCB command utilizing Command Type 7
 * IOCB types.
 *
 * @sp: SRB command to process
 * @cmd_pkt: Command type 3 IOCB
 * @tot_dsds: Total number of segments to transfer
 */
static inline void
qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
                         uint16_t tot_dsds)
{
    uint16_t	avail_dsds;
    uint32_t	*cur_dsd;
    scsi_qla_host_t	*ha;
    struct scsi_cmnd *cmd;

    cmd = sp->cmd;

    /* Update entry type to indicate Command Type 3 IOCB */
    *((uint32_t *)(&cmd_pkt->entry_type)) =
        __constant_cpu_to_le32(COMMAND_TYPE_7);

    /* No data transfer */
    if (cmd->request_bufflen == 0 || cmd->sc_data_direction == DMA_NONE) {
        cmd_pkt->byte_count = __constant_cpu_to_le32(0);
        return;
    }

    ha = sp->ha;

    /* Set transfer direction */
    if (cmd->sc_data_direction == DMA_TO_DEVICE)
        cmd_pkt->task_mgmt_flags =
            __constant_cpu_to_le16(TMF_WRITE_DATA);
    else if (cmd->sc_data_direction == DMA_FROM_DEVICE)
        cmd_pkt->task_mgmt_flags =
            __constant_cpu_to_le16(TMF_READ_DATA);

    /* One DSD is available in the Command Type 3 IOCB */
    avail_dsds = 1;
    cur_dsd = (uint32_t *)&cmd_pkt->dseg_0_address;

    /* Load data segments */
    if (cmd->use_sg != 0) {
        struct	scatterlist *cur_seg;
        struct	scatterlist *end_seg;

        cur_seg = (struct scatterlist *)cmd->request_buffer;
        end_seg = cur_seg + tot_dsds;
        while (cur_seg < end_seg) {
            dma_addr_t	sle_dma;
            cont_a64_entry_t *cont_pkt;

            /* Allocate additional continuation packets? */
            if (avail_dsds == 0) {
                /*
                 * Five DSDs are available in the Continuation
                 * Type 1 IOCB.
                 */
                cont_pkt = qla2x00_prep_cont_type1_iocb(ha);
                cur_dsd = (uint32_t *)cont_pkt->dseg_0_address;
                avail_dsds = 5;
            }

            sle_dma = sg_dma_address(cur_seg);
            *cur_dsd++ = cpu_to_le32(LSD(sle_dma));
            *cur_dsd++ = cpu_to_le32(MSD(sle_dma));
            *cur_dsd++ = cpu_to_le32(sg_dma_len(cur_seg));
            avail_dsds--;

            cur_seg++;
        }
    } else {
        *cur_dsd++ = cpu_to_le32(LSD(sp->dma_handle));
        *cur_dsd++ = cpu_to_le32(MSD(sp->dma_handle));
        *cur_dsd++ = cpu_to_le32(cmd->request_bufflen);
    }
}