bool flv_demux::get_flv_tag_header_info( FLV_TAG_HEADER_INFO & tag_header_info ) { //read the tag type field,which holds 8 bit if( !bits_io::read_8_bit( tag_header_info.tag_type,_fflv_handler )) { return false; } //read the data size field,which holds 24 bit if( ! bits_io::read_24_bit(tag_header_info.tag_data_size, _fflv_handler )) return false; //read the timestamp and the timestampextend field, which hold 32 bit total if( ! bits_io::read_32_bit(tag_header_info.tag_timestamp, _fflv_handler ) ) return false; //now convert the data_size and timestamp to network byte order tag_header_info.tag_data_size = hton24(tag_header_info.tag_data_size); int tmp_timestamp = tag_header_info.tag_timestamp; tag_header_info.tag_timestamp = hton24( tmp_timestamp); tag_header_info.tag_timestamp |=( tmp_timestamp & 0xff000000 ); return true; }
static void qedf_process_l2_frame_compl(struct qedf_rport *fcport, struct fc_frame *fp, u16 l2_oxid) { struct fc_lport *lport = fcport->qedf->lport; struct fc_frame_header *fh; u32 crc; fh = (struct fc_frame_header *)fc_frame_header_get(fp); /* Set the OXID we return to what libfc used */ if (l2_oxid != FC_XID_UNKNOWN) fh->fh_ox_id = htons(l2_oxid); /* Setup header fields */ fh->fh_r_ctl = FC_RCTL_ELS_REP; fh->fh_type = FC_TYPE_ELS; /* Last sequence, end sequence */ fh->fh_f_ctl[0] = 0x98; hton24(fh->fh_d_id, lport->port_id); hton24(fh->fh_s_id, fcport->rdata->ids.port_id); fh->fh_rx_id = 0xffff; /* Set frame attributes */ crc = fcoe_fc_crc(fp); fc_frame_init(fp); fr_dev(fp) = lport; fr_sof(fp) = FC_SOF_I3; fr_eof(fp) = FC_EOF_T; fr_crc(fp) = cpu_to_le32(~crc); /* Send completed request to libfc */ fc_exch_recv(lport, fp); }
static void fc_lport_recv_flogi_req(struct fc_lport *lport, struct fc_frame *rx_fp) { struct fc_frame *fp; struct fc_frame_header *fh; struct fc_els_flogi *flp; struct fc_els_flogi *new_flp; u64 remote_wwpn; u32 remote_fid; u32 local_fid; FC_LPORT_DBG(lport, "Received FLOGI request while in state %s\n", fc_lport_state(lport)); remote_fid = fc_frame_sid(rx_fp); flp = fc_frame_payload_get(rx_fp, sizeof(*flp)); if (!flp) goto out; remote_wwpn = get_unaligned_be64(&flp->fl_wwpn); if (remote_wwpn == lport->wwpn) { printk(KERN_WARNING "host%d: libfc: Received FLOGI from port " "with same WWPN %16.16llx\n", lport->host->host_no, remote_wwpn); goto out; } FC_LPORT_DBG(lport, "FLOGI from port WWPN %16.16llx\n", remote_wwpn); local_fid = FC_LOCAL_PTP_FID_LO; if (remote_wwpn < lport->wwpn) { local_fid = FC_LOCAL_PTP_FID_HI; if (!remote_fid || remote_fid == local_fid) remote_fid = FC_LOCAL_PTP_FID_LO; } else if (!remote_fid) { remote_fid = FC_LOCAL_PTP_FID_HI; } fc_lport_set_port_id(lport, local_fid, rx_fp); fp = fc_frame_alloc(lport, sizeof(*flp)); if (fp) { new_flp = fc_frame_payload_get(fp, sizeof(*flp)); fc_lport_flogi_fill(lport, new_flp, ELS_FLOGI); new_flp->fl_cmd = (u8) ELS_LS_ACC; fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0); fh = fc_frame_header_get(fp); hton24(fh->fh_s_id, local_fid); hton24(fh->fh_d_id, remote_fid); lport->tt.frame_send(lport, fp); } else { fc_lport_error(lport, fp); } fc_lport_ptp_setup(lport, remote_fid, remote_wwpn, get_unaligned_be64(&flp->fl_wwnn)); out: fc_frame_free(rx_fp); }
/** * fc_lport_ct_request() - Send CT Passthrough request * @job: The BSG Passthrough job * @lport: The local port sending the request * @did: The destination FC-ID * @tov: The timeout period to wait for the response * * Locking Note: The lport lock is expected to be held before calling * this routine. */ static int fc_lport_ct_request(struct fc_bsg_job *job, struct fc_lport *lport, u32 did, u32 tov) { struct fc_bsg_info *info; struct fc_frame *fp; struct fc_frame_header *fh; struct fc_ct_req *ct; size_t len; fp = fc_frame_alloc(lport, sizeof(struct fc_ct_hdr) + job->request_payload.payload_len); if (!fp) return -ENOMEM; len = job->request_payload.payload_len; ct = fc_frame_payload_get(fp, len); sg_copy_to_buffer(job->request_payload.sg_list, job->request_payload.sg_cnt, ct, len); fh = fc_frame_header_get(fp); fh->fh_r_ctl = FC_RCTL_DD_UNSOL_CTL; hton24(fh->fh_d_id, did); hton24(fh->fh_s_id, lport->port_id); fh->fh_type = FC_TYPE_CT; hton24(fh->fh_f_ctl, FC_FCTL_REQ); fh->fh_cs_ctl = 0; fh->fh_df_ctl = 0; fh->fh_parm_offset = 0; info = kzalloc(sizeof(struct fc_bsg_info), GFP_KERNEL); if (!info) { fc_frame_free(fp); return -ENOMEM; } info->job = job; info->lport = lport; info->rsp_code = FC_FS_ACC; info->nents = job->reply_payload.sg_cnt; info->sg = job->reply_payload.sg_list; if (!lport->tt.exch_seq_send(lport, fp, fc_lport_bsg_resp, NULL, info, tov)) { kfree(info); return -ECOMM; } return 0; }
static int fc_lport_els_request(struct fc_bsg_job *job, struct fc_lport *lport, u32 did, u32 tov) { struct fc_bsg_info *info; struct fc_frame *fp; struct fc_frame_header *fh; char *pp; int len; fp = fc_frame_alloc(lport, job->request_payload.payload_len); if (!fp) return -ENOMEM; len = job->request_payload.payload_len; pp = fc_frame_payload_get(fp, len); sg_copy_to_buffer(job->request_payload.sg_list, job->request_payload.sg_cnt, pp, len); fh = fc_frame_header_get(fp); fh->fh_r_ctl = FC_RCTL_ELS_REQ; hton24(fh->fh_d_id, did); hton24(fh->fh_s_id, lport->port_id); fh->fh_type = FC_TYPE_ELS; hton24(fh->fh_f_ctl, FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT); fh->fh_cs_ctl = 0; fh->fh_df_ctl = 0; fh->fh_parm_offset = 0; info = kzalloc(sizeof(struct fc_bsg_info), GFP_KERNEL); if (!info) { fc_frame_free(fp); return -ENOMEM; } info->job = job; info->lport = lport; info->rsp_code = ELS_LS_ACC; info->nents = job->reply_payload.sg_cnt; info->sg = job->reply_payload.sg_list; if (!lport->tt.exch_seq_send(lport, fp, fc_lport_bsg_resp, NULL, info, tov)) return -ECOMM; return 0; }
/* high-level API to send LLC confirm link */ int smc_llc_send_confirm_link(struct smc_link *link, enum smc_llc_reqresp reqresp) { struct smc_link_group *lgr = smc_get_lgr(link); struct smc_llc_msg_confirm_link *confllc; struct smc_wr_tx_pend_priv *pend; struct smc_wr_buf *wr_buf; int rc; rc = smc_llc_add_pending_send(link, &wr_buf, &pend); if (rc) return rc; confllc = (struct smc_llc_msg_confirm_link *)wr_buf; memset(confllc, 0, sizeof(*confllc)); confllc->hd.common.type = SMC_LLC_CONFIRM_LINK; confllc->hd.length = sizeof(struct smc_llc_msg_confirm_link); confllc->hd.flags |= SMC_LLC_FLAG_NO_RMBE_EYEC; if (reqresp == SMC_LLC_RESP) confllc->hd.flags |= SMC_LLC_FLAG_RESP; memcpy(confllc->sender_mac, link->smcibdev->mac[link->ibport - 1], ETH_ALEN); memcpy(confllc->sender_gid, link->gid, SMC_GID_SIZE); hton24(confllc->sender_qp_num, link->roce_qp->qp_num); confllc->link_num = link->link_id; memcpy(confllc->link_uid, lgr->id, SMC_LGR_ID_SIZE); confllc->max_links = SMC_LLC_ADD_LNK_MAX_LINKS; /* enforce peer resp. */ /* send llc message */ rc = smc_wr_tx_send(link, pend); return rc; }
void send_nack5( tNode* pNode,UINT32 seqn, int oid_length, BYTE* poid, BOOL fSendNow ) { /* send NACK REASON_5:"ObjectID-payload not supported!" */ IAnnexET00NAckHeader header[sizeof_IAnnexET00NAckHeader]; IAnnexENAckReason reason[sizeof_IAnnexENAckReason_ND]; msaPrintFormat( pNode->pAnnexE->msaType, "Send NAck5(ObjectID-payload not supported, SEQN=%i) to Host(%08x:%i)", seqn, pNode->RemoteHost.nIP, pNode->RemoteHost.nPort ); header[IAnnexET00NAckHeader_Header+IAnnexET00Header_PFLAGS] = 0; /* header.Header.T = 0; header.Header.A = 0; header.Header.S = 0; header.Header.RES = 0; */ header[IAnnexET00NAckHeader_Header+IAnnexET00Header_TRANSPORT_TYPE] = AEPT00_NAck; hton16( 1, &header[IAnnexET00NAckHeader_NACK_COUNT] ); hton24( seqn, &reason[IAnnexENAckReason_SEQNUM] ); reason[IAnnexENAckReason_DATA_LENGTH] = (BYTE)(oid_length & 0xff); hton16( 5, &reason[IAnnexENAckReason_REASON] ); send_payload( pNode, header, sizeof_IAnnexET00NAckHeader, reason, sizeof_IAnnexENAckReason_ND, poid, oid_length, FALSE, FALSE, fSendNow ); }
void send_ack( tNode* pNode, UINT32 seqn, BOOL fSendNow ) { IAnnexET00Ack ack[sizeof_IAnnexET00Ack_ND+sizeof_IAnnexEAckData]; ack[IAnnexET00Ack_Header+IAnnexET00Header_PFLAGS] = 0; /* ack.Header.T = 0; ack.Header.A = 0; ack.Header.S = 0; ack.Header.RES = 0; */ ack[IAnnexET00Ack_Header+IAnnexET00Header_TRANSPORT_TYPE] = AEPT00_Ack; hton16( 1, &ack[IAnnexET00Ack_ACK_COUNT] ); hton24( seqn, &ack[IAnnexET00Ack_ACK+IAnnexEAckData_SEQNUM] ); ack[IAnnexET00Ack_ACK+IAnnexEAckData_RESERVED] = 0; send_payload( pNode, ack, sizeof_AckHeader( &ack ), &ack[IAnnexET00Ack_ACK], sizeof_IAnnexEAckData, NULL, 0, FALSE, FALSE, fSendNow ); }
int bnx2fc_send_rrq(struct bnx2fc_cmd *aborted_io_req) { struct fc_els_rrq rrq; struct bnx2fc_rport *tgt = aborted_io_req->tgt; struct fc_lport *lport = tgt->rdata->local_port; struct bnx2fc_els_cb_arg *cb_arg = NULL; u32 sid = tgt->sid; u32 r_a_tov = lport->r_a_tov; unsigned long start = jiffies; int rc; BNX2FC_ELS_DBG("Sending RRQ orig_xid = 0x%x\n", aborted_io_req->xid); memset(&rrq, 0, sizeof(rrq)); cb_arg = kzalloc(sizeof(struct bnx2fc_els_cb_arg), GFP_NOIO); if (!cb_arg) { printk(KERN_ERR PFX "Unable to allocate cb_arg for RRQ\n"); rc = -ENOMEM; goto rrq_err; } cb_arg->aborted_io_req = aborted_io_req; rrq.rrq_cmd = ELS_RRQ; hton24(rrq.rrq_s_id, sid); rrq.rrq_ox_id = htons(aborted_io_req->xid); rrq.rrq_rx_id = htons(aborted_io_req->task->rxwr_txrd.var_ctx.rx_id); retry_rrq: rc = bnx2fc_initiate_els(tgt, ELS_RRQ, &rrq, sizeof(rrq), bnx2fc_rrq_compl, cb_arg, r_a_tov); if (rc == -ENOMEM) { if (time_after(jiffies, start + (10 * HZ))) { BNX2FC_ELS_DBG("rrq Failed\n"); rc = FAILED; goto rrq_err; } msleep(20); goto retry_rrq; } rrq_err: if (rc) { BNX2FC_ELS_DBG("RRQ failed - release orig io req 0x%x\n", aborted_io_req->xid); kfree(cb_arg); spin_lock_bh(&tgt->tgt_lock); kref_put(&aborted_io_req->refcount, bnx2fc_cmd_release); spin_unlock_bh(&tgt->tgt_lock); } return rc; }
u8 *qedf_get_src_mac(struct fc_lport *lport) { u8 mac[ETH_ALEN]; u8 port_id[3]; struct qedf_ctx *qedf = lport_priv(lport); /* We need to use the lport port_id to create the data_src_addr */ if (is_zero_ether_addr(qedf->data_src_addr)) { hton24(port_id, lport->port_id); fc_fcoe_set_mac(mac, port_id); qedf->ctlr.update_mac(lport, mac); } return qedf->data_src_addr; }
int bnx2fc_send_rec(struct bnx2fc_cmd *orig_io_req) { struct fc_els_rec rec; struct bnx2fc_rport *tgt = orig_io_req->tgt; struct fc_lport *lport = tgt->rdata->local_port; struct bnx2fc_els_cb_arg *cb_arg = NULL; u32 sid = tgt->sid; u32 r_a_tov = lport->r_a_tov; int rc; BNX2FC_IO_DBG(orig_io_req, "Sending REC\n"); memset(&rec, 0, sizeof(rec)); cb_arg = kzalloc(sizeof(struct bnx2fc_els_cb_arg), GFP_ATOMIC); if (!cb_arg) { printk(KERN_ERR PFX "Unable to allocate cb_arg for REC\n"); rc = -ENOMEM; goto rec_err; } kref_get(&orig_io_req->refcount); cb_arg->aborted_io_req = orig_io_req; rec.rec_cmd = ELS_REC; hton24(rec.rec_s_id, sid); rec.rec_ox_id = htons(orig_io_req->xid); rec.rec_rx_id = htons(orig_io_req->task->rxwr_txrd.var_ctx.rx_id); rc = bnx2fc_initiate_els(tgt, ELS_REC, &rec, sizeof(rec), bnx2fc_rec_compl, cb_arg, r_a_tov); rec_err: if (rc) { BNX2FC_IO_DBG(orig_io_req, "REC failed - release\n"); spin_lock_bh(&tgt->tgt_lock); kref_put(&orig_io_req->refcount, bnx2fc_cmd_release); spin_unlock_bh(&tgt->tgt_lock); kfree(cb_arg); } return rc; }
void report_block_init(report_block_t *b, RtpSession *session){ guint packet_loss=0; guint8 loss_fraction=0; RtpStream *stream=&session->rtp; guint32 delay_snc_last_sr=0; /* compute the statistics */ /*printf("hwrcv_extseq.one=%u, hwrcv_seq_at_last_SR=%u hwrcv_since_last_SR=%u\n", stream->hwrcv_extseq.one, stream->hwrcv_seq_at_last_SR, stream->hwrcv_since_last_SR );*/ if (stream->hwrcv_seq_at_last_SR!=0){ packet_loss=(stream->hwrcv_extseq.one - stream->hwrcv_seq_at_last_SR) - stream->hwrcv_since_last_SR; stream->stats.cum_packet_loss+=packet_loss; loss_fraction=(int)(256.0*(float)packet_loss/(float)stream->hwrcv_since_last_SR); } /* reset them */ stream->hwrcv_since_last_SR=0; stream->hwrcv_seq_at_last_SR=stream->hwrcv_extseq.one; if (stream->last_rcv_SR_time.tv_sec!=0){ struct timeval now; gfloat delay; gettimeofday(&now,NULL); delay=((now.tv_sec-stream->last_rcv_SR_time.tv_sec)*1e6 ) + (now.tv_usec-stream->last_rcv_SR_time.tv_usec); delay=delay*65536*1e-6; delay_snc_last_sr=(guint32) delay; } b->ssrc=htonl(session->recv_ssrc); b->fraction_lost=loss_fraction; b->cum_num_packet_lost=hton24(stream->stats.cum_packet_loss); b->interarrival_jitter=htonl((guint32) stream->jittctl.inter_jitter); b->ext_high_seq_num_rec=htonl(stream->hwrcv_extseq.one); b->lsr=htonl(stream->last_rcv_SR_ts); b->delay_snc_last_sr=htonl(delay_snc_last_sr); }
void send_nack6( tNode* pNode, UINT32 seqn, int nPayload, BOOL fSendNow ) { /* send NACK REASON_6:"Payload Corrupted" */ IAnnexET00NAckHeader header[sizeof_IAnnexET00NAckHeader]; IAnnexENAckReason6 reason[sizeof_IAnnexENAckReason6]; msaPrintFormat( pNode->pAnnexE->msaType, "Send NAck6(Payload corrupted, Id=%i, SEQN=%i) to Host(%08x:%i)", nPayload, seqn, pNode->RemoteHost.nIP, pNode->RemoteHost.nPort ); header[IAnnexET00NAckHeader_Header+IAnnexET00Header_PFLAGS] = 0; /* header.Header.T = 0; header.Header.A = 0; header.Header.S = 0; header.Header.RES = 0; */ header[IAnnexET00NAckHeader_Header+IAnnexET00Header_TRANSPORT_TYPE] = AEPT00_NAck; hton16( 1, &header[IAnnexET00NAckHeader_NACK_COUNT] ); hton24( seqn, &reason[IAnnexENAckReason6_SEQNUM] ); reason[IAnnexENAckReason6_DATA_LENGTH] = 1; hton16( 6, &reason[IAnnexENAckReason6_REASON] ); reason[IAnnexENAckReason6_PAYLOAD_NUMBER] = (BYTE)nPayload; send_payload( pNode, header, sizeof_IAnnexET00NAckHeader, reason, sizeof_IAnnexENAckReason6, NULL, 0, FALSE, FALSE, fSendNow ); }
void send_nack4( tNode* pNode, UINT32 seqn, int static_type, BOOL fSendNow ) { /* send NACK REASON_4:"Static-payload type not supported" */ IAnnexET00NAckHeader header[sizeof_IAnnexET00NAckHeader]; IAnnexENAckReason4 reason[sizeof_IAnnexENAckReason4]; msaPrintFormat( pNode->pAnnexE->msaType, "Send NAck4(Static-payload-type=%i not supported, SEQN=%i) to Host(%08x:%i)", static_type, seqn, pNode->RemoteHost.nIP, pNode->RemoteHost.nPort ); header[IAnnexET00NAckHeader_Header+IAnnexET00Header_PFLAGS] = 0; /* header.Header.T = 0; header.Header.A = 0; header.Header.S = 0; header.Header.RES = 0; */ header[IAnnexET00NAckHeader_Header+IAnnexET00Header_TRANSPORT_TYPE] = AEPT00_NAck; hton16( 1, &header[IAnnexET00NAckHeader_NACK_COUNT] ); hton24( seqn, &reason[IAnnexENAckReason4_SEQNUM] ); reason[IAnnexENAckReason4_DATA_LENGTH] = 1; hton16( 4, &reason[IAnnexENAckReason4_REASON] ); reason[IAnnexENAckReason4_STATIC_TYPE] = (BYTE)static_type; send_payload( pNode, header, sizeof_IAnnexET00NAckHeader, reason, sizeof_IAnnexENAckReason4, NULL, 0, FALSE, FALSE, fSendNow ); }
/* Assumes kref is already held by caller */ int qedf_send_rrq(struct qedf_ioreq *aborted_io_req) { struct fc_els_rrq rrq; struct qedf_rport *fcport; struct fc_lport *lport; struct qedf_els_cb_arg *cb_arg = NULL; struct qedf_ctx *qedf; uint32_t sid; uint32_t r_a_tov; int rc; if (!aborted_io_req) { QEDF_ERR(NULL, "abort_io_req is NULL.\n"); return -EINVAL; } fcport = aborted_io_req->fcport; /* Check that fcport is still offloaded */ if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags)) { QEDF_ERR(NULL, "fcport is no longer offloaded.\n"); return -EINVAL; } if (!fcport->qedf) { QEDF_ERR(NULL, "fcport->qedf is NULL.\n"); return -EINVAL; } qedf = fcport->qedf; lport = qedf->lport; sid = fcport->sid; r_a_tov = lport->r_a_tov; QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS, "Sending RRQ orig " "io = %p, orig_xid = 0x%x\n", aborted_io_req, aborted_io_req->xid); memset(&rrq, 0, sizeof(rrq)); cb_arg = kzalloc(sizeof(struct qedf_els_cb_arg), GFP_NOIO); if (!cb_arg) { QEDF_ERR(&(qedf->dbg_ctx), "Unable to allocate cb_arg for " "RRQ\n"); rc = -ENOMEM; goto rrq_err; } cb_arg->aborted_io_req = aborted_io_req; rrq.rrq_cmd = ELS_RRQ; hton24(rrq.rrq_s_id, sid); rrq.rrq_ox_id = htons(aborted_io_req->xid); rrq.rrq_rx_id = htons(aborted_io_req->task->tstorm_st_context.read_write.rx_id); rc = qedf_initiate_els(fcport, ELS_RRQ, &rrq, sizeof(rrq), qedf_rrq_compl, cb_arg, r_a_tov); rrq_err: if (rc) { QEDF_ERR(&(qedf->dbg_ctx), "RRQ failed - release orig io " "req 0x%x\n", aborted_io_req->xid); kfree(cb_arg); kref_put(&aborted_io_req->refcount, qedf_release_cmd); } return rc; }
BOOL send_payload( tNode* pNode, void* payload_header, int payload_header_size, void* payload_data, int payload_data_size, void* payload_exdata, int payload_exdata_size, BOOL AckFlag, BOOL HFlag, BOOL SendNow ) { tPDU* pCurrentPDU; BOOL fFirstPayload = FALSE; /* if can't send add to the list of pended nodes */ if (AckFlag && (pNode->pWaitingForAckPDU != NULL)) { return FALSE; } /* get free PDU if needed */ if (pNode->pCurrentPDU == NULL) { PLIST_ENTRY plink; if (IsListEmpty( &pNode->pAnnexE->FreePDUList )) { InsertTailList( &pNode->pAnnexE->ResBlockedNodeList, &pNode->lPendLink ); return FALSE; } fFirstPayload = TRUE; plink = RemoveHeadList( &pNode->pAnnexE->FreePDUList ); pNode->pCurrentPDU = CONTAINING_RECORD( plink, tPDU, lPDULink ); pCurrentPDU = pNode->pCurrentPDU; pCurrentPDU->nIP = pNode->RemoteHost.nIP; pCurrentPDU->nPort = pNode->RemoteHost.nPort; pCurrentPDU->PDU[IAnnexEHeader_FLAGS] = 0; hton24( get_next_seqn( pNode ), &pCurrentPDU->PDU[IAnnexEHeader_SEQN] ); pCurrentPDU->nSize = sizeof_IAnnexEHeader; if (payload_header_size + payload_data_size + payload_exdata_size >= (pCurrentPDU->nMaxSize - pCurrentPDU->nSize)) { RV_ASSERT( FALSE ); /* this is serious APPLICATION bug (payload is greather than PDU size)!!! */ return FALSE; } } else pCurrentPDU = pNode->pCurrentPDU; /* check for free space in PDU */ if (payload_header_size + payload_data_size + payload_exdata_size < (pCurrentPDU->nMaxSize - pCurrentPDU->nSize)) { /* append payload to the PDU */ if (payload_header_size > 0) { memcpy( &pCurrentPDU->PDU[pCurrentPDU->nSize], payload_header, payload_header_size ); pCurrentPDU->nSize += payload_header_size; } if (payload_data_size > 0) { memcpy( &pCurrentPDU->PDU[pCurrentPDU->nSize], payload_data, payload_data_size ); pCurrentPDU->nSize += payload_data_size; } if (payload_exdata_size > 0) { memcpy( &pCurrentPDU->PDU[pCurrentPDU->nSize], payload_exdata, payload_exdata_size ); pCurrentPDU->nSize += payload_exdata_size; } AEHOr_A( pCurrentPDU->PDU, AckFlag ); AEHOr_H( pCurrentPDU->PDU, HFlag ); if ( (SendNow) && (!pNode->fDontSend) ) { send_current_pdu( pNode ); } return TRUE; } else { /* no place for that payload => send current PDU! */ send_current_pdu( pNode ); if (AckFlag && (pNode->pWaitingForAckPDU != NULL)) return FALSE; else return send_payload( pNode, payload_header, payload_header_size, payload_data, payload_data_size, payload_exdata, payload_exdata_size, AckFlag, HFlag, SendNow ); } }
/** * fc_lport_recv_flogi_req() - Receive a FLOGI request * @lport: The local port that recieved the request * @rx_fp: The FLOGI frame * * A received FLOGI request indicates a point-to-point connection. * Accept it with the common service parameters indicating our N port. * Set up to do a PLOGI if we have the higher-number WWPN. * * Locking Note: The lport lock is expected to be held before calling * this function. */ static void fc_lport_recv_flogi_req(struct fc_lport *lport, struct fc_frame *rx_fp) { struct fc_frame *fp; struct fc_frame_header *fh; struct fc_els_flogi *flp; struct fc_els_flogi *new_flp; u64 remote_wwpn; u32 remote_fid; u32 local_fid; FC_LPORT_DBG(lport, "Received FLOGI request while in state %s\n", fc_lport_state(lport)); remote_fid = fc_frame_sid(rx_fp); flp = fc_frame_payload_get(rx_fp, sizeof(*flp)); if (!flp) goto out; remote_wwpn = get_unaligned_be64(&flp->fl_wwpn); if (remote_wwpn == lport->wwpn) { printk(KERN_WARNING "host%d: libfc: Received FLOGI from port " "with same WWPN %16.16llx\n", lport->host->host_no, remote_wwpn); goto out; } FC_LPORT_DBG(lport, "FLOGI from port WWPN %16.16llx\n", remote_wwpn); /* * XXX what is the right thing to do for FIDs? * The originator might expect our S_ID to be 0xfffffe. * But if so, both of us could end up with the same FID. */ local_fid = FC_LOCAL_PTP_FID_LO; if (remote_wwpn < lport->wwpn) { local_fid = FC_LOCAL_PTP_FID_HI; if (!remote_fid || remote_fid == local_fid) remote_fid = FC_LOCAL_PTP_FID_LO; } else if (!remote_fid) { remote_fid = FC_LOCAL_PTP_FID_HI; } fc_lport_set_port_id(lport, local_fid, rx_fp); fp = fc_frame_alloc(lport, sizeof(*flp)); if (fp) { new_flp = fc_frame_payload_get(fp, sizeof(*flp)); fc_lport_flogi_fill(lport, new_flp, ELS_FLOGI); new_flp->fl_cmd = (u8) ELS_LS_ACC; /* * Send the response. If this fails, the originator should * repeat the sequence. */ fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0); fh = fc_frame_header_get(fp); hton24(fh->fh_s_id, local_fid); hton24(fh->fh_d_id, remote_fid); lport->tt.frame_send(lport, fp); } else { fc_lport_error(lport, fp); } fc_lport_ptp_setup(lport, remote_fid, remote_wwpn, get_unaligned_be64(&flp->fl_wwnn)); out: fc_frame_free(rx_fp); }
/* Assumes kref is already held by caller */ int qedf_send_rec(struct qedf_ioreq *orig_io_req) { struct fc_els_rec rec; struct qedf_rport *fcport; struct fc_lport *lport; struct qedf_els_cb_arg *cb_arg = NULL; struct qedf_ctx *qedf; uint32_t sid; uint32_t r_a_tov; int rc; if (!orig_io_req) { QEDF_ERR(NULL, "orig_io_req is NULL.\n"); return -EINVAL; } fcport = orig_io_req->fcport; /* Check that fcport is still offloaded */ if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags)) { QEDF_ERR(NULL, "fcport is no longer offloaded.\n"); return -EINVAL; } if (!fcport->qedf) { QEDF_ERR(NULL, "fcport->qedf is NULL.\n"); return -EINVAL; } /* Take reference until REC command completion */ kref_get(&orig_io_req->refcount); qedf = fcport->qedf; lport = qedf->lport; sid = fcport->sid; r_a_tov = lport->r_a_tov; memset(&rec, 0, sizeof(rec)); cb_arg = kzalloc(sizeof(struct qedf_els_cb_arg), GFP_NOIO); if (!cb_arg) { QEDF_ERR(&(qedf->dbg_ctx), "Unable to allocate cb_arg for " "REC\n"); rc = -ENOMEM; goto rec_err; } cb_arg->aborted_io_req = orig_io_req; rec.rec_cmd = ELS_REC; hton24(rec.rec_s_id, sid); rec.rec_ox_id = htons(orig_io_req->xid); rec.rec_rx_id = htons(orig_io_req->task->tstorm_st_context.read_write.rx_id); QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS, "Sending REC orig_io=%p, " "orig_xid=0x%x rx_id=0x%x\n", orig_io_req, orig_io_req->xid, rec.rec_rx_id); rc = qedf_initiate_els(fcport, ELS_REC, &rec, sizeof(rec), qedf_rec_compl, cb_arg, r_a_tov); rec_err: if (rc) { QEDF_ERR(&(qedf->dbg_ctx), "REC failed - release orig_io_req" "=0x%x\n", orig_io_req->xid); kfree(cb_arg); kref_put(&orig_io_req->refcount, qedf_release_cmd); } return rc; }