diff options
author | Joe Eykholt <jeykholt@cisco.com> | 2009-08-26 01:03:10 +0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-09-10 21:07:58 +0400 |
commit | 131203a1ef53f3a4deb3260031bc53c7e4db4a24 (patch) | |
tree | 0f85ee5bf5db4612a7a62aa8835f33a1acc5a9ac /drivers/scsi/libfc | |
parent | 6bd054cbf3f7da3442f30a7d4eb7da4dd1c44f21 (diff) | |
download | linux-131203a1ef53f3a4deb3260031bc53c7e4db4a24.tar.xz |
[SCSI] libfc: move remote port lookup for ELS requests into fc_rport.c.
This moves the remote port lookup for incoming ELS requests into
fc_rport.c, in preparation for handing PLOGI and LOGO from
unknown rports.
This changes the arg to rport_recv_req from an rdata to an lport.
Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/libfc')
-rw-r--r-- | drivers/scsi/libfc/fc_lport.c | 30 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_rport.c | 78 |
2 files changed, 43 insertions, 65 deletions
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c index caf68240bddf..d3f4e0c34f5c 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c @@ -812,10 +812,6 @@ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp, { struct fc_frame_header *fh = fc_frame_header_get(fp); void (*recv) (struct fc_seq *, struct fc_frame *, struct fc_lport *); - struct fc_rport_priv *rdata; - u32 s_id; - u32 d_id; - struct fc_seq_els_data rjt_data; mutex_lock(&lport->lp_mutex); @@ -831,7 +827,7 @@ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp, /* * Check opcode. */ - recv = NULL; + recv = lport->tt.rport_recv_req; switch (fc_frame_payload_op(fp)) { case ELS_FLOGI: recv = fc_lport_recv_flogi_req; @@ -858,29 +854,7 @@ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp, break; } - if (recv) - recv(sp, fp, lport); - else { - /* - * Find session. - * If this is a new incoming PLOGI, we won't find it. - */ - s_id = ntoh24(fh->fh_s_id); - d_id = ntoh24(fh->fh_d_id); - - rdata = lport->tt.rport_lookup(lport, s_id); - if (rdata) - lport->tt.rport_recv_req(sp, fp, rdata); - else { - rjt_data.fp = NULL; - rjt_data.reason = ELS_RJT_UNAB; - rjt_data.explan = ELS_EXPL_NONE; - lport->tt.seq_els_rsp_send(sp, - ELS_LS_RJT, - &rjt_data); - fc_frame_free(fp); - } - } + recv(sp, fp, lport); } else { FC_LPORT_DBG(lport, "dropping invalid frame (eof %x)\n", fr_eof(fp)); diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index cb54115c26cb..acdc72d6b873 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c @@ -912,57 +912,61 @@ static void fc_rport_enter_logo(struct fc_rport_priv *rdata) * fc_rport_recv_req() - Receive a request from a rport * @sp: current sequence in the PLOGI exchange * @fp: response frame - * @rdata_arg: private remote port data + * @lport: Fibre Channel local port * - * Locking Note: Called without the rport lock held. This - * function will hold the rport lock, call an _enter_* - * function and then unlock the rport. + * Locking Note: Called with the lport lock held. */ void fc_rport_recv_req(struct fc_seq *sp, struct fc_frame *fp, - struct fc_rport_priv *rdata) + struct fc_lport *lport) { - struct fc_lport *lport = rdata->local_port; - + struct fc_rport_priv *rdata; struct fc_frame_header *fh; struct fc_seq_els_data els_data; + u32 s_id; u8 op; - mutex_lock(&rdata->rp_mutex); - els_data.fp = NULL; els_data.explan = ELS_EXPL_NONE; els_data.reason = ELS_RJT_NONE; fh = fc_frame_header_get(fp); + s_id = ntoh24(fh->fh_s_id); - if (fh->fh_r_ctl == FC_RCTL_ELS_REQ && fh->fh_type == FC_TYPE_ELS) { - op = fc_frame_payload_op(fp); - switch (op) { - case ELS_PLOGI: - fc_rport_recv_plogi_req(rdata, sp, fp); - break; - case ELS_PRLI: - fc_rport_recv_prli_req(rdata, sp, fp); - break; - case ELS_PRLO: - fc_rport_recv_prlo_req(rdata, sp, fp); - break; - case ELS_LOGO: - fc_rport_recv_logo_req(rdata, sp, fp); - break; - case ELS_RRQ: - els_data.fp = fp; - lport->tt.seq_els_rsp_send(sp, ELS_RRQ, &els_data); - break; - case ELS_REC: - els_data.fp = fp; - lport->tt.seq_els_rsp_send(sp, ELS_REC, &els_data); - break; - default: - els_data.reason = ELS_RJT_UNSUP; - lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &els_data); - break; - } + rdata = lport->tt.rport_lookup(lport, s_id); + if (!rdata) { + els_data.reason = ELS_RJT_UNAB; + lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &els_data); + fc_frame_free(fp); + return; + } + mutex_lock(&rdata->rp_mutex); + + op = fc_frame_payload_op(fp); + switch (op) { + case ELS_PLOGI: + fc_rport_recv_plogi_req(rdata, sp, fp); + break; + case ELS_PRLI: + fc_rport_recv_prli_req(rdata, sp, fp); + break; + case ELS_PRLO: + fc_rport_recv_prlo_req(rdata, sp, fp); + break; + case ELS_LOGO: + fc_rport_recv_logo_req(rdata, sp, fp); + break; + case ELS_RRQ: + els_data.fp = fp; + lport->tt.seq_els_rsp_send(sp, ELS_RRQ, &els_data); + break; + case ELS_REC: + els_data.fp = fp; + lport->tt.seq_els_rsp_send(sp, ELS_REC, &els_data); + break; + default: + els_data.reason = ELS_RJT_UNSUP; + lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &els_data); + break; } mutex_unlock(&rdata->rp_mutex); |