diff options
Diffstat (limited to 'drivers/scsi/libfc')
-rw-r--r-- | drivers/scsi/libfc/fc_exch.c | 96 |
1 files changed, 53 insertions, 43 deletions
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c index 10a6a2a7bfc5..c772d8d27159 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c | |||
@@ -334,6 +334,52 @@ static void fc_exch_release(struct fc_exch *ep) | |||
334 | } | 334 | } |
335 | 335 | ||
336 | /** | 336 | /** |
337 | * fc_exch_timer_cancel() - cancel exch timer | ||
338 | * @ep: The exchange whose timer to be canceled | ||
339 | */ | ||
340 | static inline void fc_exch_timer_cancel(struct fc_exch *ep) | ||
341 | { | ||
342 | if (cancel_delayed_work(&ep->timeout_work)) { | ||
343 | FC_EXCH_DBG(ep, "Exchange timer canceled\n"); | ||
344 | atomic_dec(&ep->ex_refcnt); /* drop hold for timer */ | ||
345 | } | ||
346 | } | ||
347 | |||
348 | /** | ||
349 | * fc_exch_timer_set_locked() - Start a timer for an exchange w/ the | ||
350 | * the exchange lock held | ||
351 | * @ep: The exchange whose timer will start | ||
352 | * @timer_msec: The timeout period | ||
353 | * | ||
354 | * Used for upper level protocols to time out the exchange. | ||
355 | * The timer is cancelled when it fires or when the exchange completes. | ||
356 | */ | ||
357 | static inline void fc_exch_timer_set_locked(struct fc_exch *ep, | ||
358 | unsigned int timer_msec) | ||
359 | { | ||
360 | if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) | ||
361 | return; | ||
362 | |||
363 | FC_EXCH_DBG(ep, "Exchange timer armed : %d msecs\n", timer_msec); | ||
364 | |||
365 | if (queue_delayed_work(fc_exch_workqueue, &ep->timeout_work, | ||
366 | msecs_to_jiffies(timer_msec))) | ||
367 | fc_exch_hold(ep); /* hold for timer */ | ||
368 | } | ||
369 | |||
370 | /** | ||
371 | * fc_exch_timer_set() - Lock the exchange and set the timer | ||
372 | * @ep: The exchange whose timer will start | ||
373 | * @timer_msec: The timeout period | ||
374 | */ | ||
375 | static void fc_exch_timer_set(struct fc_exch *ep, unsigned int timer_msec) | ||
376 | { | ||
377 | spin_lock_bh(&ep->ex_lock); | ||
378 | fc_exch_timer_set_locked(ep, timer_msec); | ||
379 | spin_unlock_bh(&ep->ex_lock); | ||
380 | } | ||
381 | |||
382 | /** | ||
337 | * fc_exch_done_locked() - Complete an exchange with the exchange lock held | 383 | * fc_exch_done_locked() - Complete an exchange with the exchange lock held |
338 | * @ep: The exchange that is complete | 384 | * @ep: The exchange that is complete |
339 | */ | 385 | */ |
@@ -354,8 +400,7 @@ static int fc_exch_done_locked(struct fc_exch *ep) | |||
354 | 400 | ||
355 | if (!(ep->esb_stat & ESB_ST_REC_QUAL)) { | 401 | if (!(ep->esb_stat & ESB_ST_REC_QUAL)) { |
356 | ep->state |= FC_EX_DONE; | 402 | ep->state |= FC_EX_DONE; |
357 | if (cancel_delayed_work(&ep->timeout_work)) | 403 | fc_exch_timer_cancel(ep); |
358 | atomic_dec(&ep->ex_refcnt); /* drop hold for timer */ | ||
359 | rc = 0; | 404 | rc = 0; |
360 | } | 405 | } |
361 | return rc; | 406 | return rc; |
@@ -419,40 +464,6 @@ static void fc_exch_delete(struct fc_exch *ep) | |||
419 | } | 464 | } |
420 | 465 | ||
421 | /** | 466 | /** |
422 | * fc_exch_timer_set_locked() - Start a timer for an exchange w/ the | ||
423 | * the exchange lock held | ||
424 | * @ep: The exchange whose timer will start | ||
425 | * @timer_msec: The timeout period | ||
426 | * | ||
427 | * Used for upper level protocols to time out the exchange. | ||
428 | * The timer is cancelled when it fires or when the exchange completes. | ||
429 | */ | ||
430 | static inline void fc_exch_timer_set_locked(struct fc_exch *ep, | ||
431 | unsigned int timer_msec) | ||
432 | { | ||
433 | if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) | ||
434 | return; | ||
435 | |||
436 | FC_EXCH_DBG(ep, "Exchange timer armed\n"); | ||
437 | |||
438 | if (queue_delayed_work(fc_exch_workqueue, &ep->timeout_work, | ||
439 | msecs_to_jiffies(timer_msec))) | ||
440 | fc_exch_hold(ep); /* hold for timer */ | ||
441 | } | ||
442 | |||
443 | /** | ||
444 | * fc_exch_timer_set() - Lock the exchange and set the timer | ||
445 | * @ep: The exchange whose timer will start | ||
446 | * @timer_msec: The timeout period | ||
447 | */ | ||
448 | static void fc_exch_timer_set(struct fc_exch *ep, unsigned int timer_msec) | ||
449 | { | ||
450 | spin_lock_bh(&ep->ex_lock); | ||
451 | fc_exch_timer_set_locked(ep, timer_msec); | ||
452 | spin_unlock_bh(&ep->ex_lock); | ||
453 | } | ||
454 | |||
455 | /** | ||
456 | * fc_seq_send() - Send a frame using existing sequence/exchange pair | 467 | * fc_seq_send() - Send a frame using existing sequence/exchange pair |
457 | * @lport: The local port that the exchange will be sent on | 468 | * @lport: The local port that the exchange will be sent on |
458 | * @sp: The sequence to be sent | 469 | * @sp: The sequence to be sent |
@@ -1544,8 +1555,10 @@ static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp) | |||
1544 | FC_EXCH_DBG(ep, "exch: BLS rctl %x - %s\n", fh->fh_r_ctl, | 1555 | FC_EXCH_DBG(ep, "exch: BLS rctl %x - %s\n", fh->fh_r_ctl, |
1545 | fc_exch_rctl_name(fh->fh_r_ctl)); | 1556 | fc_exch_rctl_name(fh->fh_r_ctl)); |
1546 | 1557 | ||
1547 | if (cancel_delayed_work_sync(&ep->timeout_work)) | 1558 | if (cancel_delayed_work_sync(&ep->timeout_work)) { |
1559 | FC_EXCH_DBG(ep, "Exchange timer canceled\n"); | ||
1548 | fc_exch_release(ep); /* release from pending timer hold */ | 1560 | fc_exch_release(ep); /* release from pending timer hold */ |
1561 | } | ||
1549 | 1562 | ||
1550 | spin_lock_bh(&ep->ex_lock); | 1563 | spin_lock_bh(&ep->ex_lock); |
1551 | switch (fh->fh_r_ctl) { | 1564 | switch (fh->fh_r_ctl) { |
@@ -1732,8 +1745,7 @@ static void fc_exch_reset(struct fc_exch *ep) | |||
1732 | spin_lock_bh(&ep->ex_lock); | 1745 | spin_lock_bh(&ep->ex_lock); |
1733 | fc_exch_abort_locked(ep, 0); | 1746 | fc_exch_abort_locked(ep, 0); |
1734 | ep->state |= FC_EX_RST_CLEANUP; | 1747 | ep->state |= FC_EX_RST_CLEANUP; |
1735 | if (cancel_delayed_work(&ep->timeout_work)) | 1748 | fc_exch_timer_cancel(ep); |
1736 | atomic_dec(&ep->ex_refcnt); /* drop hold for timer */ | ||
1737 | resp = ep->resp; | 1749 | resp = ep->resp; |
1738 | ep->resp = NULL; | 1750 | ep->resp = NULL; |
1739 | if (ep->esb_stat & ESB_ST_REC_QUAL) | 1751 | if (ep->esb_stat & ESB_ST_REC_QUAL) |
@@ -2128,10 +2140,8 @@ static void fc_exch_els_rrq(struct fc_frame *fp) | |||
2128 | ep->esb_stat &= ~ESB_ST_REC_QUAL; | 2140 | ep->esb_stat &= ~ESB_ST_REC_QUAL; |
2129 | atomic_dec(&ep->ex_refcnt); /* drop hold for rec qual */ | 2141 | atomic_dec(&ep->ex_refcnt); /* drop hold for rec qual */ |
2130 | } | 2142 | } |
2131 | if (ep->esb_stat & ESB_ST_COMPLETE) { | 2143 | if (ep->esb_stat & ESB_ST_COMPLETE) |
2132 | if (cancel_delayed_work(&ep->timeout_work)) | 2144 | fc_exch_timer_cancel(ep); |
2133 | atomic_dec(&ep->ex_refcnt); /* drop timer hold */ | ||
2134 | } | ||
2135 | 2145 | ||
2136 | spin_unlock_bh(&ep->ex_lock); | 2146 | spin_unlock_bh(&ep->ex_lock); |
2137 | 2147 | ||