summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libfc/fc_lport.c
diff options
context:
space:
mode:
authorJoe Eykholt <jeykholt@cisco.com>2009-11-03 11:49:05 -0800
committerJames Bottomley <James.Bottomley@suse.de>2009-12-04 12:01:17 -0600
commit093bb6a2d378ee83fc6ab886c772b6be86abb5a8 (patch)
tree30fea295440a3c4d5242902fbf3a7b3543d9aa9d /drivers/scsi/libfc/fc_lport.c
parent52a6690d3f0cb7414c34b1e26c569b32d4987662 (diff)
downloadkernel-crypto-093bb6a2d378ee83fc6ab886c772b6be86abb5a8.tar.gz
kernel-crypto-093bb6a2d378ee83fc6ab886c772b6be86abb5a8.tar.xz
kernel-crypto-093bb6a2d378ee83fc6ab886c772b6be86abb5a8.zip
[SCSI] libfc: add set_fid function to libfc template
This is to notify the LLD when an FC_ID is assigned to the local port. The fnic driver needs to push the assigned FC_ID to firmware. It currently does this by intercepting the FLOGI responses, and in order to make that code more common with FIP and NPIV, it makes more sense to wait until the local port has completely handled the FLOGI or FDISC response. Also, when we fix point-to-point FC_ID assignment, we'll need this callback as well. Add a call to the libfc template, which is called whenever the local port FC_ID is being assigned. It defaults to fc_lport_set_fid(), supplied by libfc. As additional benefit of this function, the LLD may determine the MAC address that caused the change by looking at the received frame. We also print the assigned port ID as long as it isn't 0. Setting port ID to 0 happens often in reset while retrying FLOGI, and would be uninteresting. This replaces the previous message which didn't identify the host adapter instance. patch v2 note: changed one word in a comment. "intercepted" -> "provided". 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/fc_lport.c')
-rw-r--r--drivers/scsi/libfc/fc_lport.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 90930c43545..653b52dd2ff 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -733,6 +733,27 @@ static void fc_lport_enter_ready(struct fc_lport *lport)
}
/**
+ * 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);
+}
+
+/**
* fc_lport_recv_flogi_req() - Receive a FLOGI request
* @sp_in: The sequence the FLOGI is on
* @rx_fp: The FLOGI frame
@@ -790,7 +811,7 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
remote_fid = FC_LOCAL_PTP_FID_HI;
}
- fc_host_port_id(lport->host) = local_fid;
+ fc_lport_set_port_id(lport, local_fid, rx_fp);
fp = fc_frame_alloc(lport, sizeof(*flp));
if (fp) {
@@ -926,7 +947,9 @@ static void fc_lport_reset_locked(struct fc_lport *lport)
lport->tt.exch_mgr_reset(lport, 0, 0);
fc_host_fabric_name(lport->host) = 0;
- fc_host_port_id(lport->host) = 0;
+
+ if (fc_host_port_id(lport->host))
+ fc_lport_set_port_id(lport, 0, NULL);
}
/**
@@ -1428,11 +1451,6 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
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) &
@@ -1452,6 +1470,7 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
if (e_d_tov > lport->e_d_tov)
lport->e_d_tov = e_d_tov;
lport->r_a_tov = 2 * e_d_tov;
+ fc_lport_set_port_id(lport, did, fp);
printk(KERN_INFO "libfc: Port (%6x) entered "
"point to point mode\n", did);
fc_lport_ptp_setup(lport, ntoh24(fh->fh_s_id),
@@ -1464,6 +1483,7 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
lport->r_a_tov = r_a_tov;
fc_host_fabric_name(lport->host) =
get_unaligned_be64(&flp->fl_wwnn);
+ fc_lport_set_port_id(lport, did, fp);
fc_lport_enter_dns(lport);
}
}