void zfcp_dbf_san_ct_request(struct zfcp_fsf_req *fsf_req) { struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; struct zfcp_wka_port *wka_port = ct->wka_port; struct zfcp_adapter *adapter = wka_port->adapter; struct zfcp_dbf *dbf = adapter->dbf; struct ct_hdr *hdr = sg_virt(ct->req); struct zfcp_dbf_san_record *r = &dbf->san_buf; struct zfcp_dbf_san_record_ct_request *oct = &r->u.ct_req; int level = 3; unsigned long flags; spin_lock_irqsave(&dbf->san_lock, flags); memset(r, 0, sizeof(*r)); strncpy(r->tag, "octc", ZFCP_DBF_TAG_SIZE); r->fsf_reqid = fsf_req->req_id; r->fsf_seqno = fsf_req->seq_no; r->s_id = fc_host_port_id(adapter->scsi_host); r->d_id = wka_port->d_id; oct->cmd_req_code = hdr->cmd_rsp_code; oct->revision = hdr->revision; oct->gs_type = hdr->gs_type; oct->gs_subtype = hdr->gs_subtype; oct->options = hdr->options; oct->max_res_size = hdr->max_res_size; oct->len = min((int)ct->req->length - (int)sizeof(struct ct_hdr), ZFCP_DBF_SAN_MAX_PAYLOAD); debug_event(dbf->san, level, r, sizeof(*r)); zfcp_dbf_hexdump(dbf->san, r, sizeof(*r), level, (void *)hdr + sizeof(struct ct_hdr), oct->len); spin_unlock_irqrestore(&dbf->san_lock, flags); }
/** * zfcp_san_dbf_event_ct_request - trace event for issued CT request * @fsf_req: request containing issued CT data */ void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req) { struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; struct zfcp_port *port = ct->port; struct zfcp_adapter *adapter = port->adapter; struct ct_hdr *hdr = zfcp_sg_to_address(ct->req); struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf; struct zfcp_san_dbf_record_ct_request *oct = &r->u.ct_req; unsigned long flags; spin_lock_irqsave(&adapter->san_dbf_lock, flags); memset(r, 0, sizeof(*r)); strncpy(r->tag, "octc", ZFCP_DBF_TAG_SIZE); r->fsf_reqid = (unsigned long)fsf_req; r->fsf_seqno = fsf_req->seq_no; r->s_id = fc_host_port_id(adapter->scsi_host); r->d_id = port->d_id; oct->cmd_req_code = hdr->cmd_rsp_code; oct->revision = hdr->revision; oct->gs_type = hdr->gs_type; oct->gs_subtype = hdr->gs_subtype; oct->options = hdr->options; oct->max_res_size = hdr->max_res_size; oct->len = min((int)ct->req->length - (int)sizeof(struct ct_hdr), ZFCP_DBF_CT_PAYLOAD); memcpy(oct->payload, (void *)hdr + sizeof(struct ct_hdr), oct->len); debug_event(adapter->san_dbf, 3, r, sizeof(*r)); spin_unlock_irqrestore(&adapter->san_dbf_lock, flags); }
/* * fc_elsct_send - sends ELS/CT frame */ static struct fc_seq *fc_elsct_send(struct fc_lport *lport, struct fc_rport *rport, struct fc_frame *fp, unsigned int op, void (*resp)(struct fc_seq *, struct fc_frame *fp, void *arg), void *arg, u32 timer_msec) { enum fc_rctl r_ctl; u32 did; enum fc_fh_type fh_type; int rc; /* ELS requests */ if ((op >= ELS_LS_RJT) && (op <= ELS_AUTH_ELS)) rc = fc_els_fill(lport, rport, fp, op, &r_ctl, &did, &fh_type); else /* CT requests */ rc = fc_ct_fill(lport, fp, op, &r_ctl, &did, &fh_type); if (rc) return NULL; fc_fill_fc_hdr(fp, r_ctl, did, fc_host_port_id(lport->host), fh_type, FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); return lport->tt.exch_seq_send(lport, fp, resp, NULL, arg, timer_msec); }
/** * zfcp_san_dbf_event_ct_response - trace event for completion of CT request * @fsf_req: request containing CT response */ void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req) { struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; struct zfcp_wka_port *wka_port = ct->wka_port; struct zfcp_adapter *adapter = wka_port->adapter; struct ct_hdr *hdr = sg_virt(ct->resp); struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf; struct zfcp_san_dbf_record_ct_response *rct = &r->u.ct_resp; int level = 3; unsigned long flags; spin_lock_irqsave(&adapter->san_dbf_lock, flags); memset(r, 0, sizeof(*r)); strncpy(r->tag, "rctc", ZFCP_DBF_TAG_SIZE); r->fsf_reqid = (unsigned long)fsf_req; r->fsf_seqno = fsf_req->seq_no; r->s_id = wka_port->d_id; r->d_id = fc_host_port_id(adapter->scsi_host); rct->cmd_rsp_code = hdr->cmd_rsp_code; rct->revision = hdr->revision; rct->reason_code = hdr->reason_code; rct->expl = hdr->reason_code_expl; rct->vendor_unique = hdr->vendor_unique; rct->max_res_size = hdr->max_res_size; rct->len = min((int)ct->resp->length - (int)sizeof(struct ct_hdr), ZFCP_DBF_SAN_MAX_PAYLOAD); debug_event(adapter->san_dbf, level, r, sizeof(*r)); zfcp_dbf_hexdump(adapter->san_dbf, r, sizeof(*r), level, (void *)hdr + sizeof(struct ct_hdr), rct->len); spin_unlock_irqrestore(&adapter->san_dbf_lock, flags); }
/** * zfcp_dbf_san_ct_response - trace event for completion of CT request * @fsf_req: request containing CT response */ void zfcp_dbf_san_ct_response(struct zfcp_fsf_req *fsf_req) { struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; struct zfcp_wka_port *wka_port = ct->wka_port; struct zfcp_adapter *adapter = wka_port->adapter; struct ct_hdr *hdr = sg_virt(ct->resp); struct zfcp_dbf *dbf = adapter->dbf; struct zfcp_dbf_san_record *r = &dbf->san_buf; struct zfcp_dbf_san_record_ct_response *rct = &r->u.ct_resp; int level = 3; unsigned long flags; spin_lock_irqsave(&dbf->san_lock, flags); memset(r, 0, sizeof(*r)); strncpy(r->tag, "rctc", ZFCP_DBF_TAG_SIZE); r->fsf_reqid = fsf_req->req_id; r->fsf_seqno = fsf_req->seq_no; r->s_id = wka_port->d_id; r->d_id = fc_host_port_id(adapter->scsi_host); rct->cmd_rsp_code = hdr->cmd_rsp_code; rct->revision = hdr->revision; rct->reason_code = hdr->reason_code; rct->expl = hdr->reason_code_expl; rct->vendor_unique = hdr->vendor_unique; rct->max_res_size = hdr->max_res_size; rct->len = min((int)ct->resp->length - (
/** * fc_linkdown() - Handler for transport linkdown events * @lport: The local port whose link is down */ void fc_linkdown(struct fc_lport *lport) { printk(KERN_INFO "host%d: libfc: Link down on port (%6x)\n", lport->host->host_no, fc_host_port_id(lport->host)); mutex_lock(&lport->lp_mutex); __fc_linkdown(lport); mutex_unlock(&lport->lp_mutex); }
void zfcp_dbf_san_els_request(struct zfcp_fsf_req *fsf_req) { struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data; zfcp_dbf_san_els("oels", 2, fsf_req, fc_host_port_id(els->adapter->scsi_host), els->d_id, *(u8 *) sg_virt(els->req), sg_virt(els->req), els->req->length); }
/** * zfcp_san_dbf_event_els_response - trace event for completed ELS * @fsf_req: request containing ELS response */ void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *fsf_req) { struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data; zfcp_san_dbf_event_els("rels", 2, fsf_req, els->d_id, fc_host_port_id(els->adapter->scsi_host), *(u8 *)sg_virt(els->req), sg_virt(els->resp), els->resp->length); }
/** * zfcp_san_dbf_event_els_request - trace event for issued ELS * @fsf_req: request containing issued ELS */ void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *fsf_req) { struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data; zfcp_san_dbf_event_els("oels", 2, fsf_req, fc_host_port_id(els->adapter->scsi_host), els->d_id, *(u8 *) zfcp_sg_to_address(els->req), zfcp_sg_to_address(els->req), els->req->length); }
/** * FC transport template entry, get SCSI host port ID. */ void bfad_im_get_host_port_id(struct Scsi_Host *shost) { struct bfad_im_port_s *im_port = (struct bfad_im_port_s *) shost->hostdata[0]; struct bfad_port_s *port = im_port->port; fc_host_port_id(shost) = bfa_os_hton3b(bfa_fcs_port_get_fcid(port->fcs_port)); }
/* * csio_get_host_port_id - sysfs entries for nport_id is * populated/cached from this function */ static void csio_get_host_port_id(struct Scsi_Host *shost) { struct csio_lnode *ln = shost_priv(shost); struct csio_hw *hw = csio_lnode_to_hw(ln); spin_lock_irq(&hw->lock); fc_host_port_id(shost) = ln->nport_id; spin_unlock_irq(&hw->lock); }
void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *fsf_req) { struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data; _zfcp_san_dbf_event_common_els("rels", 2, fsf_req, els->d_id, fc_host_port_id(els->adapter->scsi_host), *(u8 *) zfcp_sg_to_address(els->req), zfcp_sg_to_address(els->resp), els->resp->length); }
void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req) { struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; struct zfcp_port *port = ct->port; struct zfcp_adapter *adapter = port->adapter; _zfcp_san_dbf_event_common_ct("rctc", fsf_req, port->d_id, fc_host_port_id(adapter->scsi_host), zfcp_sg_to_address(ct->resp), ct->resp->length); }
/** * fc_lport_set_port_id() - set the local port Port ID * @lport: The local port which will have its Port ID set. * @port_id: The new port ID. * @fp: The frame containing the incoming request, or NULL. * * Locking Note: The lport lock is expected to be held before calling * this function. */ static void fc_lport_set_port_id(struct fc_lport *lport, u32 port_id, struct fc_frame *fp) { if (port_id) printk(KERN_INFO "host%d: Assigned Port ID %6x\n", lport->host->host_no, port_id); fc_host_port_id(lport->host) = port_id; if (lport->tt.lport_set_port_id) lport->tt.lport_set_port_id(lport, port_id, fp); }
void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *fsf_req) { struct zfcp_adapter *adapter = fsf_req->adapter; struct fsf_status_read_buffer *status_buffer = (struct fsf_status_read_buffer *)fsf_req->data; int length = (int)status_buffer->length - (int)((void *)&status_buffer->payload - (void *)status_buffer); _zfcp_san_dbf_event_common_els("iels", 1, fsf_req, status_buffer->d_id, fc_host_port_id(adapter->scsi_host), *(u8 *) status_buffer->payload, (void *)status_buffer->payload, length); }
/** * zfcp_san_dbf_event_incoming_els - trace event for incomig ELS * @fsf_req: request containing unsolicited status buffer with incoming ELS */ void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *fsf_req) { struct zfcp_adapter *adapter = fsf_req->adapter; struct fsf_status_read_buffer *buf = (struct fsf_status_read_buffer *)fsf_req->data; int length = (int)buf->length - (int)((void *)&buf->payload - (void *)buf); zfcp_san_dbf_event_els("iels", 1, fsf_req, buf->d_id, fc_host_port_id(adapter->scsi_host), buf->payload.data[0], (void *)buf->payload.data, length); }
void fc_linkdown(struct fc_lport *lport) { mutex_lock(&lport->lp_mutex); printk(KERN_INFO "libfc: Link down on port (%6x)\n", fc_host_port_id(lport->host)); if (lport->link_up) { lport->link_up = 0; fc_lport_enter_reset(lport); lport->tt.fcp_cleanup(lport); } mutex_unlock(&lport->lp_mutex); }
static void fc_lport_reset_locked(struct fc_lport *lport) { if (lport->dns_rp) lport->tt.rport_logoff(lport->dns_rp); lport->ptp_rp = NULL; lport->tt.disc_stop(lport); lport->tt.exch_mgr_reset(lport, 0, 0); fc_host_fabric_name(lport->host) = 0; fc_host_port_id(lport->host) = 0; }
void fc_linkup(struct fc_lport *lport) { printk(KERN_INFO "libfc: Link up on port (%6x)\n", fc_host_port_id(lport->host)); mutex_lock(&lport->lp_mutex); if (!lport->link_up) { lport->link_up = 1; if (lport->state == LPORT_ST_RESET) fc_lport_enter_flogi(lport); } mutex_unlock(&lport->lp_mutex); }
/** * 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, fc_host_port_id(lport->host)); fh->fh_type = FC_TYPE_CT; 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 = 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)) return -ECOMM; return 0; }
void fc_lport_disc_callback(struct fc_lport *lport, enum fc_disc_event event) { switch (event) { case DISC_EV_SUCCESS: FC_LPORT_DBG(lport, "Discovery succeeded\n"); break; case DISC_EV_FAILED: printk(KERN_ERR "libfc: Discovery failed for port (%6x)\n", fc_host_port_id(lport->host)); mutex_lock(&lport->lp_mutex); fc_lport_enter_reset(lport); mutex_unlock(&lport->lp_mutex); break; case DISC_EV_NONE: WARN_ON(1); break; } }
static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, void *lp_arg) { struct fc_lport *lport = lp_arg; struct fc_frame_header *fh; struct fc_els_flogi *flp; u32 did; u16 csp_flags; unsigned int r_a_tov; unsigned int e_d_tov; u16 mfs; FC_LPORT_DBG(lport, "Received a FLOGI %s\n", fc_els_resp_type(fp)); if (fp == ERR_PTR(-FC_EX_CLOSED)) return; mutex_lock(&lport->lp_mutex); if (lport->state != LPORT_ST_FLOGI) { FC_LPORT_DBG(lport, "Received a FLOGI response, but in state " "%s\n", fc_lport_state(lport)); if (IS_ERR(fp)) goto err; goto out; } if (IS_ERR(fp)) { fc_lport_error(lport, fp); goto err; } fh = fc_frame_header_get(fp); did = ntoh24(fh->fh_d_id); if (fc_frame_payload_op(fp) == ELS_LS_ACC && did != 0) { printk(KERN_INFO "libfc: Assigned FID (%6x) in FLOGI response\n", did); fc_host_port_id(lport->host) = did; flp = fc_frame_payload_get(fp, sizeof(*flp)); if (flp) { mfs = ntohs(flp->fl_csp.sp_bb_data) & FC_SP_BB_DATA_MASK; if (mfs >= FC_SP_MIN_MAX_PAYLOAD && mfs < lport->mfs) lport->mfs = mfs; csp_flags = ntohs(flp->fl_csp.sp_features); r_a_tov = ntohl(flp->fl_csp.sp_r_a_tov); e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov); if (csp_flags & FC_SP_FT_EDTR) e_d_tov /= 1000000; if ((csp_flags & FC_SP_FT_FPORT) == 0) { if (e_d_tov > lport->e_d_tov) lport->e_d_tov = e_d_tov; lport->r_a_tov = 2 * e_d_tov; printk(KERN_INFO "libfc: Port (%6x) entered " "point to point mode\n", did); fc_lport_ptp_setup(lport, ntoh24(fh->fh_s_id), get_unaligned_be64( &flp->fl_wwpn), get_unaligned_be64( &flp->fl_wwnn)); } else { lport->e_d_tov = e_d_tov; lport->r_a_tov = r_a_tov; fc_host_fabric_name(lport->host) = get_unaligned_be64(&flp->fl_wwnn); fc_lport_enter_dns(lport); } } } else { FC_LPORT_DBG(lport, "Bad FLOGI response\n"); } out: fc_frame_free(fp); err: mutex_unlock(&lport->lp_mutex); }
static void fc_lport_recv_flogi_req(struct fc_seq *sp_in, struct fc_frame *rx_fp, struct fc_lport *lport) { struct fc_frame *fp; struct fc_frame_header *fh; struct fc_seq *sp; struct fc_exch *ep; struct fc_els_flogi *flp; struct fc_els_flogi *new_flp; u64 remote_wwpn; u32 remote_fid; u32 local_fid; u32 f_ctl; FC_LPORT_DBG(lport, "Received FLOGI request while in state %s\n", fc_lport_state(lport)); fh = fc_frame_header_get(rx_fp); remote_fid = ntoh24(fh->fh_s_id); 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 "libfc: Received FLOGI from port " "with same WWPN %llx\n", remote_wwpn); goto out; } FC_LPORT_DBG(lport, "FLOGI from port WWPN %llx\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_host_port_id(lport->host) = local_fid; fp = fc_frame_alloc(lport, sizeof(*flp)); if (fp) { sp = lport->tt.seq_start_next(fr_seq(rx_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; f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ; ep = fc_seq_exch(sp); fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid, FC_TYPE_ELS, f_ctl, 0); lport->tt.seq_send(lport, sp, fp); } else { fc_lport_error(lport, fp); } fc_lport_ptp_setup(lport, remote_fid, remote_wwpn, get_unaligned_be64(&flp->fl_wwnn)); out: sp = fr_seq(rx_fp); fc_frame_free(rx_fp); }