diff options
Diffstat (limited to 'drivers/scsi/libfc/fc_exch.c')
| -rw-r--r-- | drivers/scsi/libfc/fc_exch.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c index 2bc22be5f849..145ab9ba55ea 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c | |||
| @@ -415,9 +415,9 @@ static void fc_exch_timeout(struct work_struct *work) | |||
| 415 | e_stat = ep->esb_stat; | 415 | e_stat = ep->esb_stat; |
| 416 | if (e_stat & ESB_ST_COMPLETE) { | 416 | if (e_stat & ESB_ST_COMPLETE) { |
| 417 | ep->esb_stat = e_stat & ~ESB_ST_REC_QUAL; | 417 | ep->esb_stat = e_stat & ~ESB_ST_REC_QUAL; |
| 418 | spin_unlock_bh(&ep->ex_lock); | ||
| 418 | if (e_stat & ESB_ST_REC_QUAL) | 419 | if (e_stat & ESB_ST_REC_QUAL) |
| 419 | fc_exch_rrq(ep); | 420 | fc_exch_rrq(ep); |
| 420 | spin_unlock_bh(&ep->ex_lock); | ||
| 421 | goto done; | 421 | goto done; |
| 422 | } else { | 422 | } else { |
| 423 | resp = ep->resp; | 423 | resp = ep->resp; |
| @@ -1624,14 +1624,14 @@ static void fc_exch_rrq(struct fc_exch *ep) | |||
| 1624 | struct fc_lport *lp; | 1624 | struct fc_lport *lp; |
| 1625 | struct fc_els_rrq *rrq; | 1625 | struct fc_els_rrq *rrq; |
| 1626 | struct fc_frame *fp; | 1626 | struct fc_frame *fp; |
| 1627 | struct fc_seq *rrq_sp; | ||
| 1628 | u32 did; | 1627 | u32 did; |
| 1629 | 1628 | ||
| 1630 | lp = ep->lp; | 1629 | lp = ep->lp; |
| 1631 | 1630 | ||
| 1632 | fp = fc_frame_alloc(lp, sizeof(*rrq)); | 1631 | fp = fc_frame_alloc(lp, sizeof(*rrq)); |
| 1633 | if (!fp) | 1632 | if (!fp) |
| 1634 | return; | 1633 | goto retry; |
| 1634 | |||
| 1635 | rrq = fc_frame_payload_get(fp, sizeof(*rrq)); | 1635 | rrq = fc_frame_payload_get(fp, sizeof(*rrq)); |
| 1636 | memset(rrq, 0, sizeof(*rrq)); | 1636 | memset(rrq, 0, sizeof(*rrq)); |
| 1637 | rrq->rrq_cmd = ELS_RRQ; | 1637 | rrq->rrq_cmd = ELS_RRQ; |
| @@ -1647,13 +1647,20 @@ static void fc_exch_rrq(struct fc_exch *ep) | |||
| 1647 | fc_host_port_id(lp->host), FC_TYPE_ELS, | 1647 | fc_host_port_id(lp->host), FC_TYPE_ELS, |
| 1648 | FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); | 1648 | FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); |
| 1649 | 1649 | ||
| 1650 | rrq_sp = fc_exch_seq_send(lp, fp, fc_exch_rrq_resp, NULL, ep, | 1650 | if (fc_exch_seq_send(lp, fp, fc_exch_rrq_resp, NULL, ep, lp->e_d_tov)) |
| 1651 | lp->e_d_tov); | 1651 | return; |
| 1652 | if (!rrq_sp) { | 1652 | |
| 1653 | ep->esb_stat |= ESB_ST_REC_QUAL; | 1653 | retry: |
| 1654 | fc_exch_timer_set_locked(ep, ep->r_a_tov); | 1654 | spin_lock_bh(&ep->ex_lock); |
| 1655 | if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) { | ||
| 1656 | spin_unlock_bh(&ep->ex_lock); | ||
| 1657 | /* drop hold for rec qual */ | ||
| 1658 | fc_exch_release(ep); | ||
| 1655 | return; | 1659 | return; |
| 1656 | } | 1660 | } |
| 1661 | ep->esb_stat |= ESB_ST_REC_QUAL; | ||
| 1662 | fc_exch_timer_set_locked(ep, ep->r_a_tov); | ||
| 1663 | spin_unlock_bh(&ep->ex_lock); | ||
| 1657 | } | 1664 | } |
| 1658 | 1665 | ||
| 1659 | 1666 | ||
