コード例 #1
0
ファイル: tfc_cmd.c プロジェクト: ashang/xpenology-3.x
/*
 * Send TX_RDY (transfer ready).
 */
int ft_write_pending(struct se_cmd *se_cmd)
{
    struct ft_cmd *cmd = container_of(se_cmd, struct ft_cmd, se_cmd);
    struct fc_frame *fp;
    struct fcp_txrdy *txrdy;
    struct fc_lport *lport;
    struct fc_exch *ep;
    struct fc_frame_header *fh;
    u32 f_ctl;

    ft_dump_cmd(cmd, __func__);

    if (cmd->aborted)
        return 0;
    ep = fc_seq_exch(cmd->seq);
    lport = ep->lp;
    fp = fc_frame_alloc(lport, sizeof(*txrdy));
    if (!fp)
        return -ENOMEM; /* Signal QUEUE_FULL */

    txrdy = fc_frame_payload_get(fp, sizeof(*txrdy));
    memset(txrdy, 0, sizeof(*txrdy));
    txrdy->ft_burst_len = htonl(se_cmd->data_length);

    cmd->seq = lport->tt.seq_start_next(cmd->seq);
    fc_fill_fc_hdr(fp, FC_RCTL_DD_DATA_DESC, ep->did, ep->sid, FC_TYPE_FCP,
                   FC_FC_EX_CTX | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);

    fh = fc_frame_header_get(fp);
    f_ctl = ntoh24(fh->fh_f_ctl);

    /* Only if it is 'Exchange Responder' */
    if (f_ctl & FC_FC_EX_CTX) {
        /* Target is 'exchange responder' and sending XFER_READY
         * to 'exchange initiator (initiator)'
         */
        if ((ep->xid <= lport->lro_xid) &&
                (fh->fh_r_ctl == FC_RCTL_DD_DATA_DESC)) {
            if (se_cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) {
                /*
                 * cmd may have been broken up into multiple
                 * tasks. Link their sgs together so we can
                 * operate on them all at once.
                 */
                transport_do_task_sg_chain(se_cmd);
                cmd->sg = se_cmd->t_tasks_sg_chained;
                cmd->sg_cnt =
                    se_cmd->t_tasks_sg_chained_no;
            }
            if (cmd->sg && lport->tt.ddp_target(lport, ep->xid,
                                                cmd->sg,
                                                cmd->sg_cnt))
                cmd->was_ddp_setup = 1;
        }
    }
    lport->tt.seq_send(lport, cmd->seq, fp);
    return 0;
}
コード例 #2
0
ファイル: tfc_cmd.c プロジェクト: rrowicki/Chrono_Kernel-1
/*
 * Send TX_RDY (transfer ready).
 */
int ft_write_pending(struct se_cmd *se_cmd)
{
	struct ft_cmd *cmd = container_of(se_cmd, struct ft_cmd, se_cmd);
	struct fc_frame *fp;
	struct fcp_txrdy *txrdy;
	struct fc_lport *lport;
	struct fc_exch *ep;
	struct fc_frame_header *fh;
	u32 f_ctl;

	ft_dump_cmd(cmd, __func__);

	ep = fc_seq_exch(cmd->seq);
	lport = ep->lp;
	fp = fc_frame_alloc(lport, sizeof(*txrdy));
	if (!fp)
		return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES;

	txrdy = fc_frame_payload_get(fp, sizeof(*txrdy));
	memset(txrdy, 0, sizeof(*txrdy));
	txrdy->ft_burst_len = htonl(se_cmd->data_length);

	cmd->seq = lport->tt.seq_start_next(cmd->seq);
	fc_fill_fc_hdr(fp, FC_RCTL_DD_DATA_DESC, ep->did, ep->sid, FC_TYPE_FCP,
		       FC_FC_EX_CTX | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);

	fh = fc_frame_header_get(fp);
	f_ctl = ntoh24(fh->fh_f_ctl);

	/* Only if it is 'Exchange Responder' */
	if (f_ctl & FC_FC_EX_CTX) {
		/* Target is 'exchange responder' and sending XFER_READY
		 * to 'exchange initiator (initiator)'
		 */
		if ((ep->xid <= lport->lro_xid) &&
		    (fh->fh_r_ctl == FC_RCTL_DD_DATA_DESC)) {
			if (se_cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) {
				/*
				 * Map se_mem list to scatterlist, so that
				 * DDP can be setup. DDP setup function require
				 * scatterlist. se_mem_list is internal to
				 * TCM/LIO target
				 */
				transport_do_task_sg_chain(se_cmd);
				cmd->sg = T_TASK(se_cmd)->t_tasks_sg_chained;
				cmd->sg_cnt =
					T_TASK(se_cmd)->t_tasks_sg_chained_no;
			}
			if (cmd->sg && lport->tt.ddp_setup(lport, ep->xid,
						    cmd->sg, cmd->sg_cnt))
				cmd->was_ddp_setup = 1;
		}
	}
	lport->tt.seq_send(lport, cmd->seq, fp);
	return 0;
}
コード例 #3
0
int ft_write_pending(struct se_cmd *se_cmd)
{
	struct ft_cmd *cmd = container_of(se_cmd, struct ft_cmd, se_cmd);
	struct fc_frame *fp;
	struct fcp_txrdy *txrdy;
	struct fc_lport *lport;
	struct fc_exch *ep;
	struct fc_frame_header *fh;
	u32 f_ctl;

	ft_dump_cmd(cmd, __func__);

	if (cmd->aborted)
		return 0;
	ep = fc_seq_exch(cmd->seq);
	lport = ep->lp;
	fp = fc_frame_alloc(lport, sizeof(*txrdy));
	if (!fp)
		return -ENOMEM; 

	txrdy = fc_frame_payload_get(fp, sizeof(*txrdy));
	memset(txrdy, 0, sizeof(*txrdy));
	txrdy->ft_burst_len = htonl(se_cmd->data_length);

	cmd->seq = lport->tt.seq_start_next(cmd->seq);
	fc_fill_fc_hdr(fp, FC_RCTL_DD_DATA_DESC, ep->did, ep->sid, FC_TYPE_FCP,
		       FC_FC_EX_CTX | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);

	fh = fc_frame_header_get(fp);
	f_ctl = ntoh24(fh->fh_f_ctl);

	
	if (f_ctl & FC_FC_EX_CTX) {
		if ((ep->xid <= lport->lro_xid) &&
		    (fh->fh_r_ctl == FC_RCTL_DD_DATA_DESC)) {
			if (se_cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) {
				transport_do_task_sg_chain(se_cmd);
				cmd->sg = se_cmd->t_tasks_sg_chained;
				cmd->sg_cnt =
					se_cmd->t_tasks_sg_chained_no;
			}
			if (cmd->sg && lport->tt.ddp_target(lport, ep->xid,
							    cmd->sg,
							    cmd->sg_cnt))
				cmd->was_ddp_setup = 1;
		}
	}
	lport->tt.seq_send(lport, cmd->seq, fp);
	return 0;
}