diff options
-rw-r--r-- | drivers/scsi/fcoe/libfcoe.c | 60 | ||||
-rw-r--r-- | include/scsi/libfcoe.h | 1 |
2 files changed, 31 insertions, 30 deletions
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c index 787e7225ddd..4d857c2aef6 100644 --- a/drivers/scsi/fcoe/libfcoe.c +++ b/drivers/scsi/fcoe/libfcoe.c | |||
@@ -277,38 +277,16 @@ EXPORT_SYMBOL(fcoe_ctlr_link_up); | |||
277 | /** | 277 | /** |
278 | * fcoe_ctlr_reset() - Reset a FCoE controller | 278 | * fcoe_ctlr_reset() - Reset a FCoE controller |
279 | * @fip: The FCoE controller to reset | 279 | * @fip: The FCoE controller to reset |
280 | * @new_state: The FIP state to be entered | ||
281 | * | ||
282 | * Returns non-zero if the link was up and now isn't. | ||
283 | */ | 280 | */ |
284 | static int fcoe_ctlr_reset(struct fcoe_ctlr *fip, enum fip_state new_state) | 281 | static void fcoe_ctlr_reset(struct fcoe_ctlr *fip) |
285 | { | 282 | { |
286 | struct fc_lport *lport = fip->lp; | ||
287 | int link_dropped; | ||
288 | |||
289 | spin_lock_bh(&fip->lock); | ||
290 | fcoe_ctlr_reset_fcfs(fip); | 283 | fcoe_ctlr_reset_fcfs(fip); |
291 | del_timer(&fip->timer); | 284 | del_timer(&fip->timer); |
292 | fip->state = new_state; | ||
293 | fip->ctlr_ka_time = 0; | 285 | fip->ctlr_ka_time = 0; |
294 | fip->port_ka_time = 0; | 286 | fip->port_ka_time = 0; |
295 | fip->sol_time = 0; | 287 | fip->sol_time = 0; |
296 | fip->flogi_oxid = FC_XID_UNKNOWN; | 288 | fip->flogi_oxid = FC_XID_UNKNOWN; |
297 | fip->map_dest = 0; | 289 | fip->map_dest = 0; |
298 | fip->last_link = 0; | ||
299 | link_dropped = fip->link; | ||
300 | fip->link = 0; | ||
301 | spin_unlock_bh(&fip->lock); | ||
302 | |||
303 | if (link_dropped) | ||
304 | fc_linkdown(lport); | ||
305 | |||
306 | if (new_state == FIP_ST_ENABLED) { | ||
307 | fcoe_ctlr_solicit(fip, NULL); | ||
308 | fc_linkup(lport); | ||
309 | link_dropped = 0; | ||
310 | } | ||
311 | return link_dropped; | ||
312 | } | 290 | } |
313 | 291 | ||
314 | /** | 292 | /** |
@@ -322,7 +300,20 @@ static int fcoe_ctlr_reset(struct fcoe_ctlr *fip, enum fip_state new_state) | |||
322 | */ | 300 | */ |
323 | int fcoe_ctlr_link_down(struct fcoe_ctlr *fip) | 301 | int fcoe_ctlr_link_down(struct fcoe_ctlr *fip) |
324 | { | 302 | { |
325 | return fcoe_ctlr_reset(fip, FIP_ST_LINK_WAIT); | 303 | int link_dropped; |
304 | |||
305 | LIBFCOE_FIP_DBG(fip, "link down.\n"); | ||
306 | spin_lock_bh(&fip->lock); | ||
307 | fcoe_ctlr_reset(fip); | ||
308 | link_dropped = fip->link; | ||
309 | fip->link = 0; | ||
310 | fip->last_link = 0; | ||
311 | fip->state = FIP_ST_LINK_WAIT; | ||
312 | spin_unlock_bh(&fip->lock); | ||
313 | |||
314 | if (link_dropped) | ||
315 | fc_linkdown(fip->lp); | ||
316 | return link_dropped; | ||
326 | } | 317 | } |
327 | EXPORT_SYMBOL(fcoe_ctlr_link_down); | 318 | EXPORT_SYMBOL(fcoe_ctlr_link_down); |
328 | 319 | ||
@@ -994,7 +985,13 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip, | |||
994 | desc_mask); | 985 | desc_mask); |
995 | } else { | 986 | } else { |
996 | LIBFCOE_FIP_DBG(fip, "performing Clear Virtual Link\n"); | 987 | LIBFCOE_FIP_DBG(fip, "performing Clear Virtual Link\n"); |
997 | fcoe_ctlr_reset(fip, FIP_ST_ENABLED); | 988 | |
989 | spin_lock_bh(&fip->lock); | ||
990 | fcoe_ctlr_reset(fip); | ||
991 | spin_unlock_bh(&fip->lock); | ||
992 | |||
993 | fc_lport_reset(fip->lp); | ||
994 | fcoe_ctlr_solicit(fip, NULL); | ||
998 | } | 995 | } |
999 | } | 996 | } |
1000 | 997 | ||
@@ -1152,15 +1149,14 @@ static void fcoe_ctlr_timeout(unsigned long arg) | |||
1152 | fip->port_ka_time = jiffies + | 1149 | fip->port_ka_time = jiffies + |
1153 | msecs_to_jiffies(FIP_VN_KA_PERIOD); | 1150 | msecs_to_jiffies(FIP_VN_KA_PERIOD); |
1154 | fip->ctlr_ka_time = jiffies + sel->fka_period; | 1151 | fip->ctlr_ka_time = jiffies + sel->fka_period; |
1155 | fip->link = 1; | ||
1156 | } else { | 1152 | } else { |
1157 | printk(KERN_NOTICE "libfcoe: host%d: " | 1153 | printk(KERN_NOTICE "libfcoe: host%d: " |
1158 | "FIP Fibre-Channel Forwarder timed out. " | 1154 | "FIP Fibre-Channel Forwarder timed out. " |
1159 | "Starting FCF discovery.\n", | 1155 | "Starting FCF discovery.\n", |
1160 | fip->lp->host->host_no); | 1156 | fip->lp->host->host_no); |
1161 | fip->link = 0; | 1157 | fip->reset_req = 1; |
1158 | schedule_work(&fip->link_work); | ||
1162 | } | 1159 | } |
1163 | schedule_work(&fip->link_work); | ||
1164 | } | 1160 | } |
1165 | 1161 | ||
1166 | if (sel) { | 1162 | if (sel) { |
@@ -1205,20 +1201,24 @@ static void fcoe_ctlr_link_work(struct work_struct *work) | |||
1205 | u8 *mac; | 1201 | u8 *mac; |
1206 | int link; | 1202 | int link; |
1207 | int last_link; | 1203 | int last_link; |
1204 | int reset; | ||
1208 | 1205 | ||
1209 | fip = container_of(work, struct fcoe_ctlr, link_work); | 1206 | fip = container_of(work, struct fcoe_ctlr, link_work); |
1210 | spin_lock_bh(&fip->lock); | 1207 | spin_lock_bh(&fip->lock); |
1211 | last_link = fip->last_link; | 1208 | last_link = fip->last_link; |
1212 | link = fip->link; | 1209 | link = fip->link; |
1213 | fip->last_link = link; | 1210 | fip->last_link = link; |
1211 | reset = fip->reset_req; | ||
1212 | fip->reset_req = 0; | ||
1214 | spin_unlock_bh(&fip->lock); | 1213 | spin_unlock_bh(&fip->lock); |
1215 | 1214 | ||
1216 | if (last_link != link) { | 1215 | if (last_link != link) { |
1217 | if (link) | 1216 | if (link) |
1218 | fc_linkup(fip->lp); | 1217 | fc_linkup(fip->lp); |
1219 | else | 1218 | else |
1220 | fcoe_ctlr_reset(fip, FIP_ST_LINK_WAIT); | 1219 | fc_linkdown(fip->lp); |
1221 | } | 1220 | } else if (reset && link) |
1221 | fc_lport_reset(fip->lp); | ||
1222 | 1222 | ||
1223 | if (fip->send_ctlr_ka) { | 1223 | if (fip->send_ctlr_ka) { |
1224 | fip->send_ctlr_ka = 0; | 1224 | fip->send_ctlr_ka = 0; |
diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h index 2344a00e92e..e38ffa05dc2 100644 --- a/include/scsi/libfcoe.h +++ b/include/scsi/libfcoe.h | |||
@@ -108,6 +108,7 @@ struct fcoe_ctlr { | |||
108 | u8 flogi_count; | 108 | u8 flogi_count; |
109 | u8 link; | 109 | u8 link; |
110 | u8 last_link; | 110 | u8 last_link; |
111 | u8 reset_req; | ||
111 | u8 map_dest; | 112 | u8 map_dest; |
112 | u8 spma; | 113 | u8 spma; |
113 | u8 send_ctlr_ka; | 114 | u8 send_ctlr_ka; |