aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/fcoe
diff options
context:
space:
mode:
authorJoe Eykholt <jeykholt@cisco.com>2009-11-03 14:48:27 -0500
committerJames Bottomley <James.Bottomley@suse.de>2009-12-04 13:01:13 -0500
commitdd42dac4ecd1799077c132aab35d3c36b26d4d8c (patch)
treed3ca67f50eccef31071bfe26e09bf97c686bc088 /drivers/scsi/fcoe
parent1f4aed818d26eb9ed54520fbeb85d5ee691baa94 (diff)
[SCSI] libfcoe: FIP should report link to libfc whether selected or not
The fnic driver with FIP is reporting link up, even though it's down. When the interface is shut down by the switch, we receive a clear virtual link, and set the state reported to libfc as down, although we still report it up. Clearly wrong. That causes the subsequent link down event not to be reported, and /sys shows the host "Online". Currently, in FIP mode, if an FCF times out, then link to libfc is reported as down, to stop FLOGIs. That interferes with the LLD link down being reported. Users really need to know the physical link information, to diagnose cabling issues, so physical link status should be reported to libfc. If the selected FCF needs to be reported, that should be done separately, in a later patch. 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/libfcoe.c60
1 files changed, 30 insertions, 30 deletions
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index 787e7225ddde..4d857c2aef6c 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;