diff options
-rw-r--r-- | drivers/scsi/fcoe/libfcoe.c | 40 | ||||
-rw-r--r-- | include/scsi/libfcoe.h | 8 |
2 files changed, 13 insertions, 35 deletions
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c index 22f6e44fa737..b7718be3c096 100644 --- a/drivers/scsi/fcoe/libfcoe.c +++ b/drivers/scsi/fcoe/libfcoe.c | |||
@@ -51,7 +51,7 @@ MODULE_LICENSE("GPL v2"); | |||
51 | #define FCOE_CTLR_DEF_FKA FIP_DEF_FKA /* default keep alive (mS) */ | 51 | #define FCOE_CTLR_DEF_FKA FIP_DEF_FKA /* default keep alive (mS) */ |
52 | 52 | ||
53 | static void fcoe_ctlr_timeout(unsigned long); | 53 | static void fcoe_ctlr_timeout(unsigned long); |
54 | static void fcoe_ctlr_link_work(struct work_struct *); | 54 | static void fcoe_ctlr_timer_work(struct work_struct *); |
55 | static void fcoe_ctlr_recv_work(struct work_struct *); | 55 | static void fcoe_ctlr_recv_work(struct work_struct *); |
56 | 56 | ||
57 | static u8 fcoe_all_fcfs[ETH_ALEN] = FIP_ALL_FCF_MACS; | 57 | static u8 fcoe_all_fcfs[ETH_ALEN] = FIP_ALL_FCF_MACS; |
@@ -116,7 +116,7 @@ void fcoe_ctlr_init(struct fcoe_ctlr *fip) | |||
116 | spin_lock_init(&fip->lock); | 116 | spin_lock_init(&fip->lock); |
117 | fip->flogi_oxid = FC_XID_UNKNOWN; | 117 | fip->flogi_oxid = FC_XID_UNKNOWN; |
118 | setup_timer(&fip->timer, fcoe_ctlr_timeout, (unsigned long)fip); | 118 | setup_timer(&fip->timer, fcoe_ctlr_timeout, (unsigned long)fip); |
119 | INIT_WORK(&fip->link_work, fcoe_ctlr_link_work); | 119 | INIT_WORK(&fip->timer_work, fcoe_ctlr_timer_work); |
120 | INIT_WORK(&fip->recv_work, fcoe_ctlr_recv_work); | 120 | INIT_WORK(&fip->recv_work, fcoe_ctlr_recv_work); |
121 | skb_queue_head_init(&fip->fip_recv_list); | 121 | skb_queue_head_init(&fip->fip_recv_list); |
122 | } | 122 | } |
@@ -164,7 +164,7 @@ void fcoe_ctlr_destroy(struct fcoe_ctlr *fip) | |||
164 | fcoe_ctlr_reset_fcfs(fip); | 164 | fcoe_ctlr_reset_fcfs(fip); |
165 | spin_unlock_bh(&fip->lock); | 165 | spin_unlock_bh(&fip->lock); |
166 | del_timer_sync(&fip->timer); | 166 | del_timer_sync(&fip->timer); |
167 | cancel_work_sync(&fip->link_work); | 167 | cancel_work_sync(&fip->timer_work); |
168 | } | 168 | } |
169 | EXPORT_SYMBOL(fcoe_ctlr_destroy); | 169 | EXPORT_SYMBOL(fcoe_ctlr_destroy); |
170 | 170 | ||
@@ -257,14 +257,10 @@ void fcoe_ctlr_link_up(struct fcoe_ctlr *fip) | |||
257 | { | 257 | { |
258 | spin_lock_bh(&fip->lock); | 258 | spin_lock_bh(&fip->lock); |
259 | if (fip->state == FIP_ST_NON_FIP || fip->state == FIP_ST_AUTO) { | 259 | if (fip->state == FIP_ST_NON_FIP || fip->state == FIP_ST_AUTO) { |
260 | fip->last_link = 1; | ||
261 | fip->link = 1; | ||
262 | spin_unlock_bh(&fip->lock); | 260 | spin_unlock_bh(&fip->lock); |
263 | fc_linkup(fip->lp); | 261 | fc_linkup(fip->lp); |
264 | } else if (fip->state == FIP_ST_LINK_WAIT) { | 262 | } else if (fip->state == FIP_ST_LINK_WAIT) { |
265 | fip->state = fip->mode; | 263 | fip->state = fip->mode; |
266 | fip->last_link = 1; | ||
267 | fip->link = 1; | ||
268 | spin_unlock_bh(&fip->lock); | 264 | spin_unlock_bh(&fip->lock); |
269 | if (fip->state == FIP_ST_AUTO) | 265 | if (fip->state == FIP_ST_AUTO) |
270 | LIBFCOE_FIP_DBG(fip, "%s", "setting AUTO mode.\n"); | 266 | LIBFCOE_FIP_DBG(fip, "%s", "setting AUTO mode.\n"); |
@@ -306,9 +302,7 @@ int fcoe_ctlr_link_down(struct fcoe_ctlr *fip) | |||
306 | LIBFCOE_FIP_DBG(fip, "link down.\n"); | 302 | LIBFCOE_FIP_DBG(fip, "link down.\n"); |
307 | spin_lock_bh(&fip->lock); | 303 | spin_lock_bh(&fip->lock); |
308 | fcoe_ctlr_reset(fip); | 304 | fcoe_ctlr_reset(fip); |
309 | link_dropped = fip->link; | 305 | link_dropped = fip->state != FIP_ST_LINK_WAIT; |
310 | fip->link = 0; | ||
311 | fip->last_link = 0; | ||
312 | fip->state = FIP_ST_LINK_WAIT; | 306 | fip->state = FIP_ST_LINK_WAIT; |
313 | spin_unlock_bh(&fip->lock); | 307 | spin_unlock_bh(&fip->lock); |
314 | 308 | ||
@@ -1175,7 +1169,7 @@ static void fcoe_ctlr_timeout(unsigned long arg) | |||
1175 | "Starting FCF discovery.\n", | 1169 | "Starting FCF discovery.\n", |
1176 | fip->lp->host->host_no); | 1170 | fip->lp->host->host_no); |
1177 | fip->reset_req = 1; | 1171 | fip->reset_req = 1; |
1178 | schedule_work(&fip->link_work); | 1172 | schedule_work(&fip->timer_work); |
1179 | } | 1173 | } |
1180 | } | 1174 | } |
1181 | 1175 | ||
@@ -1201,43 +1195,31 @@ static void fcoe_ctlr_timeout(unsigned long arg) | |||
1201 | mod_timer(&fip->timer, next_timer); | 1195 | mod_timer(&fip->timer, next_timer); |
1202 | } | 1196 | } |
1203 | if (fip->send_ctlr_ka || fip->send_port_ka) | 1197 | if (fip->send_ctlr_ka || fip->send_port_ka) |
1204 | schedule_work(&fip->link_work); | 1198 | schedule_work(&fip->timer_work); |
1205 | spin_unlock_bh(&fip->lock); | 1199 | spin_unlock_bh(&fip->lock); |
1206 | } | 1200 | } |
1207 | 1201 | ||
1208 | /** | 1202 | /** |
1209 | * fcoe_ctlr_link_work() - Worker thread function for link changes | 1203 | * fcoe_ctlr_timer_work() - Worker thread function for timer work |
1210 | * @work: Handle to a FCoE controller | 1204 | * @work: Handle to a FCoE controller |
1211 | * | 1205 | * |
1212 | * See if the link status has changed and if so, report it. | 1206 | * Sends keep-alives and resets which must not |
1213 | * | ||
1214 | * This is here because fc_linkup() and fc_linkdown() must not | ||
1215 | * be called from the timer directly, since they use a mutex. | 1207 | * be called from the timer directly, since they use a mutex. |
1216 | */ | 1208 | */ |
1217 | static void fcoe_ctlr_link_work(struct work_struct *work) | 1209 | static void fcoe_ctlr_timer_work(struct work_struct *work) |
1218 | { | 1210 | { |
1219 | struct fcoe_ctlr *fip; | 1211 | struct fcoe_ctlr *fip; |
1220 | struct fc_lport *vport; | 1212 | struct fc_lport *vport; |
1221 | u8 *mac; | 1213 | u8 *mac; |
1222 | int link; | ||
1223 | int last_link; | ||
1224 | int reset; | 1214 | int reset; |
1225 | 1215 | ||
1226 | fip = container_of(work, struct fcoe_ctlr, link_work); | 1216 | fip = container_of(work, struct fcoe_ctlr, timer_work); |
1227 | spin_lock_bh(&fip->lock); | 1217 | spin_lock_bh(&fip->lock); |
1228 | last_link = fip->last_link; | ||
1229 | link = fip->link; | ||
1230 | fip->last_link = link; | ||
1231 | reset = fip->reset_req; | 1218 | reset = fip->reset_req; |
1232 | fip->reset_req = 0; | 1219 | fip->reset_req = 0; |
1233 | spin_unlock_bh(&fip->lock); | 1220 | spin_unlock_bh(&fip->lock); |
1234 | 1221 | ||
1235 | if (last_link != link) { | 1222 | if (reset) |
1236 | if (link) | ||
1237 | fc_linkup(fip->lp); | ||
1238 | else | ||
1239 | fc_linkdown(fip->lp); | ||
1240 | } else if (reset && link) | ||
1241 | fc_lport_reset(fip->lp); | 1223 | fc_lport_reset(fip->lp); |
1242 | 1224 | ||
1243 | if (fip->send_ctlr_ka) { | 1225 | if (fip->send_ctlr_ka) { |
diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h index c603f4a7e7fc..868ed26a9767 100644 --- a/include/scsi/libfcoe.h +++ b/include/scsi/libfcoe.h | |||
@@ -65,14 +65,12 @@ enum fip_state { | |||
65 | * @port_ka_time: time of next port keep-alive. | 65 | * @port_ka_time: time of next port keep-alive. |
66 | * @ctlr_ka_time: time of next controller keep-alive. | 66 | * @ctlr_ka_time: time of next controller keep-alive. |
67 | * @timer: timer struct used for all delayed events. | 67 | * @timer: timer struct used for all delayed events. |
68 | * @link_work: &work_struct for doing FCF selection. | 68 | * @timer_work: &work_struct for doing keep-alives and resets. |
69 | * @recv_work: &work_struct for receiving FIP frames. | 69 | * @recv_work: &work_struct for receiving FIP frames. |
70 | * @fip_recv_list: list of received FIP frames. | 70 | * @fip_recv_list: list of received FIP frames. |
71 | * @user_mfs: configured maximum FC frame size, including FC header. | 71 | * @user_mfs: configured maximum FC frame size, including FC header. |
72 | * @flogi_oxid: exchange ID of most recent fabric login. | 72 | * @flogi_oxid: exchange ID of most recent fabric login. |
73 | * @flogi_count: number of FLOGI attempts in AUTO mode. | 73 | * @flogi_count: number of FLOGI attempts in AUTO mode. |
74 | * @link: current link status for libfc. | ||
75 | * @last_link: last link state reported to libfc. | ||
76 | * @map_dest: use the FC_MAP mode for destination MAC addresses. | 74 | * @map_dest: use the FC_MAP mode for destination MAC addresses. |
77 | * @spma: supports SPMA server-provided MACs mode | 75 | * @spma: supports SPMA server-provided MACs mode |
78 | * @send_ctlr_ka: need to send controller keep alive | 76 | * @send_ctlr_ka: need to send controller keep alive |
@@ -100,14 +98,12 @@ struct fcoe_ctlr { | |||
100 | unsigned long port_ka_time; | 98 | unsigned long port_ka_time; |
101 | unsigned long ctlr_ka_time; | 99 | unsigned long ctlr_ka_time; |
102 | struct timer_list timer; | 100 | struct timer_list timer; |
103 | struct work_struct link_work; | 101 | struct work_struct timer_work; |
104 | struct work_struct recv_work; | 102 | struct work_struct recv_work; |
105 | struct sk_buff_head fip_recv_list; | 103 | struct sk_buff_head fip_recv_list; |
106 | u16 user_mfs; | 104 | u16 user_mfs; |
107 | u16 flogi_oxid; | 105 | u16 flogi_oxid; |
108 | u8 flogi_count; | 106 | u8 flogi_count; |
109 | u8 link; | ||
110 | u8 last_link; | ||
111 | u8 reset_req; | 107 | u8 reset_req; |
112 | u8 map_dest; | 108 | u8 map_dest; |
113 | u8 spma; | 109 | u8 spma; |