diff options
author | Joe Eykholt <jeykholt@cisco.com> | 2009-11-03 14:49:16 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-12-04 13:01:18 -0500 |
commit | 386309ce927a308d7742a6fb24a536d3383fbd49 (patch) | |
tree | 4e8ddbb895e5bd837020896a1c2505ea8bc3159b /drivers/scsi/fcoe | |
parent | e6d8a1b0b53a156979120dd0593c1867b8ea89d3 (diff) |
[SCSI] libfcoe: fcoe: simplify receive FLOGI response
There was a locking problem where the fip->lock was held during
the call to update_mac(). The rtnl_lock() must be taken before
the fip->lock, not the other way around. This fixes that.
Now that fcoe_ctlr_recv_flog() is called only from the response handler
to a FLOGI request, some checking can be eliminated. Instead of calling
update_mac(), just fill in the granted_mac address for the passed-in
frame (skb).
Eliminate the passed-in source MAC address since it is also in the skb.
Also, in fcoe, call fcoe_set_src_mac() directly instead of going thru
the fip function pointer. This will generate less code.
Then, since fip isn't needed for LOGO response, use lport as the arg.
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/fcoe')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 15 | ||||
-rw-r--r-- | drivers/scsi/fcoe/libfcoe.c | 12 |
2 files changed, 11 insertions, 16 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index b15ec996b477..343900ac0ece 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -2247,15 +2247,12 @@ static void fcoe_flogi_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg) | |||
2247 | mac = fr_cb(fp)->granted_mac; | 2247 | mac = fr_cb(fp)->granted_mac; |
2248 | if (is_zero_ether_addr(mac)) { | 2248 | if (is_zero_ether_addr(mac)) { |
2249 | /* pre-FIP */ | 2249 | /* pre-FIP */ |
2250 | mac = eth_hdr(&fp->skb)->h_source; | 2250 | if (fcoe_ctlr_recv_flogi(fip, lport, fp)) { |
2251 | if (fcoe_ctlr_recv_flogi(fip, lport, fp, mac)) { | ||
2252 | fc_frame_free(fp); | 2251 | fc_frame_free(fp); |
2253 | return; | 2252 | return; |
2254 | } | 2253 | } |
2255 | } else { | ||
2256 | /* FIP, libfcoe has already seen it */ | ||
2257 | fip->update_mac(lport, fr_cb(fp)->granted_mac); | ||
2258 | } | 2254 | } |
2255 | fcoe_update_src_mac(lport, mac); | ||
2259 | done: | 2256 | done: |
2260 | fc_lport_flogi_resp(seq, fp, lport); | 2257 | fc_lport_flogi_resp(seq, fp, lport); |
2261 | } | 2258 | } |
@@ -2271,13 +2268,11 @@ done: | |||
2271 | */ | 2268 | */ |
2272 | static void fcoe_logo_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg) | 2269 | static void fcoe_logo_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg) |
2273 | { | 2270 | { |
2274 | struct fcoe_ctlr *fip = arg; | 2271 | struct fc_lport *lport = arg; |
2275 | struct fc_exch *exch = fc_seq_exch(seq); | ||
2276 | struct fc_lport *lport = exch->lp; | ||
2277 | static u8 zero_mac[ETH_ALEN] = { 0 }; | 2272 | static u8 zero_mac[ETH_ALEN] = { 0 }; |
2278 | 2273 | ||
2279 | if (!IS_ERR(fp)) | 2274 | if (!IS_ERR(fp)) |
2280 | fip->update_mac(lport, zero_mac); | 2275 | fcoe_update_src_mac(lport, zero_mac); |
2281 | fc_lport_logo_resp(seq, fp, lport); | 2276 | fc_lport_logo_resp(seq, fp, lport); |
2282 | } | 2277 | } |
2283 | 2278 | ||
@@ -2312,7 +2307,7 @@ static struct fc_seq *fcoe_elsct_send(struct fc_lport *lport, u32 did, | |||
2312 | if (ntoh24(fh->fh_d_id) != FC_FID_FLOGI) | 2307 | if (ntoh24(fh->fh_d_id) != FC_FID_FLOGI) |
2313 | break; | 2308 | break; |
2314 | return fc_elsct_send(lport, did, fp, op, fcoe_logo_resp, | 2309 | return fc_elsct_send(lport, did, fp, op, fcoe_logo_resp, |
2315 | fip, timeout); | 2310 | lport, timeout); |
2316 | } | 2311 | } |
2317 | return fc_elsct_send(lport, did, fp, op, resp, arg, timeout); | 2312 | return fc_elsct_send(lport, did, fp, op, resp, arg, timeout); |
2318 | } | 2313 | } |
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c index 2aab97221c6c..2988b71d1e87 100644 --- a/drivers/scsi/fcoe/libfcoe.c +++ b/drivers/scsi/fcoe/libfcoe.c | |||
@@ -1254,10 +1254,9 @@ static void fcoe_ctlr_recv_work(struct work_struct *recv_work) | |||
1254 | } | 1254 | } |
1255 | 1255 | ||
1256 | /** | 1256 | /** |
1257 | * fcoe_ctlr_recv_flogi() - Snoop pre-FIP receipt of FLOGI response or request | 1257 | * fcoe_ctlr_recv_flogi() - Snoop pre-FIP receipt of FLOGI response |
1258 | * @fip: The FCoE controller | 1258 | * @fip: The FCoE controller |
1259 | * @fp: The FC frame to snoop | 1259 | * @fp: The FC frame to snoop |
1260 | * @sa: Ethernet source MAC address from received FCoE frame | ||
1261 | * | 1260 | * |
1262 | * Snoop potential response to FLOGI or even incoming FLOGI. | 1261 | * Snoop potential response to FLOGI or even incoming FLOGI. |
1263 | * | 1262 | * |
@@ -1265,16 +1264,18 @@ static void fcoe_ctlr_recv_work(struct work_struct *recv_work) | |||
1265 | * by fip->flogi_oxid != FC_XID_UNKNOWN. | 1264 | * by fip->flogi_oxid != FC_XID_UNKNOWN. |
1266 | * | 1265 | * |
1267 | * The caller is responsible for freeing the frame. | 1266 | * The caller is responsible for freeing the frame. |
1267 | * Fill in the granted_mac address. | ||
1268 | * | 1268 | * |
1269 | * Return non-zero if the frame should not be delivered to libfc. | 1269 | * Return non-zero if the frame should not be delivered to libfc. |
1270 | */ | 1270 | */ |
1271 | int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_lport *lport, | 1271 | int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_lport *lport, |
1272 | struct fc_frame *fp, u8 *sa) | 1272 | struct fc_frame *fp) |
1273 | { | 1273 | { |
1274 | struct fc_frame_header *fh; | 1274 | struct fc_frame_header *fh; |
1275 | u8 op; | 1275 | u8 op; |
1276 | u8 mac[ETH_ALEN]; | 1276 | u8 *sa; |
1277 | 1277 | ||
1278 | sa = eth_hdr(&fp->skb)->h_source; | ||
1278 | fh = fc_frame_header_get(fp); | 1279 | fh = fc_frame_header_get(fp); |
1279 | if (fh->fh_type != FC_TYPE_ELS) | 1280 | if (fh->fh_type != FC_TYPE_ELS) |
1280 | return 0; | 1281 | return 0; |
@@ -1305,9 +1306,8 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_lport *lport, | |||
1305 | fip->map_dest = 0; | 1306 | fip->map_dest = 0; |
1306 | } | 1307 | } |
1307 | fip->flogi_oxid = FC_XID_UNKNOWN; | 1308 | fip->flogi_oxid = FC_XID_UNKNOWN; |
1308 | fc_fcoe_set_mac(mac, fh->fh_d_id); | ||
1309 | fip->update_mac(lport, mac); | ||
1310 | spin_unlock_bh(&fip->lock); | 1309 | spin_unlock_bh(&fip->lock); |
1310 | fc_fcoe_set_mac(fr_cb(fp)->granted_mac, fh->fh_d_id); | ||
1311 | } else if (op == ELS_FLOGI && fh->fh_r_ctl == FC_RCTL_ELS_REQ && sa) { | 1311 | } else if (op == ELS_FLOGI && fh->fh_r_ctl == FC_RCTL_ELS_REQ && sa) { |
1312 | /* | 1312 | /* |
1313 | * Save source MAC for point-to-point responses. | 1313 | * Save source MAC for point-to-point responses. |