aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/fcoe/libfcoe.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/fcoe/libfcoe.c')
-rw-r--r--drivers/scsi/fcoe/libfcoe.c30
1 files changed, 19 insertions, 11 deletions
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index f544340d318b..62a4c2026072 100644
--- a/drivers/scsi/fcoe/libfcoe.c
+++ b/drivers/scsi/fcoe/libfcoe.c
@@ -69,7 +69,7 @@ do { \
69 do { \ 69 do { \
70 CMD; \ 70 CMD; \
71 } while (0); \ 71 } while (0); \
72} while (0); 72} while (0)
73 73
74#define LIBFCOE_DBG(fmt, args...) \ 74#define LIBFCOE_DBG(fmt, args...) \
75 LIBFCOE_CHECK_LOGGING(LIBFCOE_LOGGING, \ 75 LIBFCOE_CHECK_LOGGING(LIBFCOE_LOGGING, \
@@ -148,13 +148,17 @@ static void fcoe_ctlr_reset_fcfs(struct fcoe_ctlr *fip)
148 */ 148 */
149void fcoe_ctlr_destroy(struct fcoe_ctlr *fip) 149void fcoe_ctlr_destroy(struct fcoe_ctlr *fip)
150{ 150{
151 flush_work(&fip->recv_work); 151 cancel_work_sync(&fip->recv_work);
152 spin_lock_bh(&fip->fip_recv_list.lock);
153 __skb_queue_purge(&fip->fip_recv_list);
154 spin_unlock_bh(&fip->fip_recv_list.lock);
155
152 spin_lock_bh(&fip->lock); 156 spin_lock_bh(&fip->lock);
153 fip->state = FIP_ST_DISABLED; 157 fip->state = FIP_ST_DISABLED;
154 fcoe_ctlr_reset_fcfs(fip); 158 fcoe_ctlr_reset_fcfs(fip);
155 spin_unlock_bh(&fip->lock); 159 spin_unlock_bh(&fip->lock);
156 del_timer_sync(&fip->timer); 160 del_timer_sync(&fip->timer);
157 flush_work(&fip->link_work); 161 cancel_work_sync(&fip->link_work);
158} 162}
159EXPORT_SYMBOL(fcoe_ctlr_destroy); 163EXPORT_SYMBOL(fcoe_ctlr_destroy);
160 164
@@ -413,10 +417,18 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip,
413 struct fip_mac_desc *mac; 417 struct fip_mac_desc *mac;
414 struct fcoe_fcf *fcf; 418 struct fcoe_fcf *fcf;
415 size_t dlen; 419 size_t dlen;
420 u16 fip_flags;
416 421
417 fcf = fip->sel_fcf; 422 fcf = fip->sel_fcf;
418 if (!fcf) 423 if (!fcf)
419 return -ENODEV; 424 return -ENODEV;
425
426 /* set flags according to both FCF and lport's capability on SPMA */
427 fip_flags = fcf->flags;
428 fip_flags &= fip->spma ? FIP_FL_SPMA | FIP_FL_FPMA : FIP_FL_FPMA;
429 if (!fip_flags)
430 return -ENODEV;
431
420 dlen = sizeof(struct fip_encaps) + skb->len; /* len before push */ 432 dlen = sizeof(struct fip_encaps) + skb->len; /* len before push */
421 cap = (struct fip_encaps_head *)skb_push(skb, sizeof(*cap)); 433 cap = (struct fip_encaps_head *)skb_push(skb, sizeof(*cap));
422 434
@@ -429,9 +441,7 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip,
429 cap->fip.fip_op = htons(FIP_OP_LS); 441 cap->fip.fip_op = htons(FIP_OP_LS);
430 cap->fip.fip_subcode = FIP_SC_REQ; 442 cap->fip.fip_subcode = FIP_SC_REQ;
431 cap->fip.fip_dl_len = htons((dlen + sizeof(*mac)) / FIP_BPW); 443 cap->fip.fip_dl_len = htons((dlen + sizeof(*mac)) / FIP_BPW);
432 cap->fip.fip_flags = htons(FIP_FL_FPMA); 444 cap->fip.fip_flags = htons(fip_flags);
433 if (fip->spma)
434 cap->fip.fip_flags |= htons(FIP_FL_SPMA);
435 445
436 cap->encaps.fd_desc.fip_dtype = dtype; 446 cap->encaps.fd_desc.fip_dtype = dtype;
437 cap->encaps.fd_desc.fip_dlen = dlen / FIP_BPW; 447 cap->encaps.fd_desc.fip_dlen = dlen / FIP_BPW;
@@ -879,7 +889,7 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
879 stats->RxFrames++; 889 stats->RxFrames++;
880 stats->RxWords += skb->len / FIP_BPW; 890 stats->RxWords += skb->len / FIP_BPW;
881 891
882 fc_exch_recv(lp, lp->emp, fp); 892 fc_exch_recv(lp, fp);
883 return; 893 return;
884 894
885len_err: 895len_err:
@@ -1104,7 +1114,6 @@ static void fcoe_ctlr_timeout(unsigned long arg)
1104 struct fcoe_fcf *sel; 1114 struct fcoe_fcf *sel;
1105 struct fcoe_fcf *fcf; 1115 struct fcoe_fcf *fcf;
1106 unsigned long next_timer = jiffies + msecs_to_jiffies(FIP_VN_KA_PERIOD); 1116 unsigned long next_timer = jiffies + msecs_to_jiffies(FIP_VN_KA_PERIOD);
1107 DECLARE_MAC_BUF(buf);
1108 u8 send_ctlr_ka; 1117 u8 send_ctlr_ka;
1109 u8 send_port_ka; 1118 u8 send_port_ka;
1110 1119
@@ -1128,9 +1137,8 @@ static void fcoe_ctlr_timeout(unsigned long arg)
1128 fcf = sel; /* the old FCF may have been freed */ 1137 fcf = sel; /* the old FCF may have been freed */
1129 if (sel) { 1138 if (sel) {
1130 printk(KERN_INFO "libfcoe: host%d: FIP selected " 1139 printk(KERN_INFO "libfcoe: host%d: FIP selected "
1131 "Fibre-Channel Forwarder MAC %s\n", 1140 "Fibre-Channel Forwarder MAC %pM\n",
1132 fip->lp->host->host_no, 1141 fip->lp->host->host_no, sel->fcf_mac);
1133 print_mac(buf, sel->fcf_mac));
1134 memcpy(fip->dest_addr, sel->fcf_mac, ETH_ALEN); 1142 memcpy(fip->dest_addr, sel->fcf_mac, ETH_ALEN);
1135 fip->port_ka_time = jiffies + 1143 fip->port_ka_time = jiffies +
1136 msecs_to_jiffies(FIP_VN_KA_PERIOD); 1144 msecs_to_jiffies(FIP_VN_KA_PERIOD);