aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/fcoe/libfcoe.c60
-rw-r--r--include/scsi/libfcoe.h1
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 */
284static int fcoe_ctlr_reset(struct fcoe_ctlr *fip, enum fip_state new_state) 281static 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 */
323int fcoe_ctlr_link_down(struct fcoe_ctlr *fip) 301int 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}
327EXPORT_SYMBOL(fcoe_ctlr_link_down); 318EXPORT_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;