diff options
Diffstat (limited to 'drivers/scsi/fcoe/libfcoe.c')
-rw-r--r-- | drivers/scsi/fcoe/libfcoe.c | 30 |
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 | */ |
149 | void fcoe_ctlr_destroy(struct fcoe_ctlr *fip) | 149 | void 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 | } |
159 | EXPORT_SYMBOL(fcoe_ctlr_destroy); | 163 | EXPORT_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 | ||
885 | len_err: | 895 | len_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); |