コード例 #1
0
ファイル: qla_iocb.c プロジェクト: rcplay/snake-os
/**
 * qla2x00_build_scsi_iocbs_32() - Build IOCB command utilizing 32bit
 * capable IOCB types.
 *
 * @sp: SRB command to process
 * @cmd_pkt: Command type 2 IOCB
 * @tot_dsds: Total number of segments to transfer
 */
void qla2x00_build_scsi_iocbs_32(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 2 IOCB */
    *((uint32_t *)(&cmd_pkt->entry_type)) =
        __constant_cpu_to_le32(COMMAND_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));

    /* Three DSDs are available in the Command Type 2 IOCB */
    avail_dsds = 3;
    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) {
            cont_entry_t	*cont_pkt;

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

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

            cur_seg++;
        }
    } else {
        *cur_dsd++ = cpu_to_le32(sp->dma_handle);
        *cur_dsd++ = cpu_to_le32(cmd->request_bufflen);
    }
}
コード例 #2
0
/*
 * qla2x00_build_scsi_iocbs_32() - Build IOCB command utilizing 32bit
 * capable IOCB types.
 *
 * @sp: SRB command to process
 * @cmd_pkt: Command type 2 IOCB
 * @tot_dsds: Total number of segments to transfer
 */
void qla2x00_build_scsi_iocbs_32(srb_t *sp, cmd_entry_t *cmd_pkt,
    uint16_t tot_dsds)
{
	uint16_t	avail_dsds;
	uint32_t	*cur_dsd;
	scsi_qla_host_t	*vha;
	struct scsi_cmnd *cmd;
	struct scatterlist *sg;
	int i;

	cmd = GET_CMD_SP(sp);

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

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

	vha = sp->fcport->vha;
	cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(sp));

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

	/* Load data segments */
	scsi_for_each_sg(cmd, sg, tot_dsds, i) {
		cont_entry_t *cont_pkt;

		/* Allocate additional continuation packets? */
		if (avail_dsds == 0) {
			/*
			 * Seven DSDs are available in the Continuation
			 * Type 0 IOCB.
			 */
			cont_pkt = qla2x00_prep_cont_type0_iocb(vha);
			cur_dsd = (uint32_t *)&cont_pkt->dseg_0_address;
			avail_dsds = 7;
		}

		*cur_dsd++ = cpu_to_le32(sg_dma_address(sg));
		*cur_dsd++ = cpu_to_le32(sg_dma_len(sg));
		avail_dsds--;
	}