diff options
Diffstat (limited to 'drivers/scsi/ibmvscsi/ibmvfc.c')
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvfc.c | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index b4b805e8d7db..166d96450a0e 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c | |||
@@ -2254,10 +2254,13 @@ static void ibmvfc_handle_async(struct ibmvfc_async_crq *crq, | |||
2254 | continue; | 2254 | continue; |
2255 | if (crq->node_name && tgt->ids.node_name != crq->node_name) | 2255 | if (crq->node_name && tgt->ids.node_name != crq->node_name) |
2256 | continue; | 2256 | continue; |
2257 | ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT); | 2257 | if (tgt->need_login && crq->event == IBMVFC_AE_ELS_LOGO) |
2258 | tgt->logo_rcvd = 1; | ||
2259 | if (!tgt->need_login || crq->event == IBMVFC_AE_ELS_PLOGI) { | ||
2260 | ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT); | ||
2261 | ibmvfc_reinit_host(vhost); | ||
2262 | } | ||
2258 | } | 2263 | } |
2259 | |||
2260 | ibmvfc_reinit_host(vhost); | ||
2261 | break; | 2264 | break; |
2262 | case IBMVFC_AE_LINK_DOWN: | 2265 | case IBMVFC_AE_LINK_DOWN: |
2263 | case IBMVFC_AE_ADAPTER_FAILED: | 2266 | case IBMVFC_AE_ADAPTER_FAILED: |
@@ -2783,27 +2786,27 @@ static void ibmvfc_tasklet(void *data) | |||
2783 | 2786 | ||
2784 | spin_lock_irqsave(vhost->host->host_lock, flags); | 2787 | spin_lock_irqsave(vhost->host->host_lock, flags); |
2785 | while (!done) { | 2788 | while (!done) { |
2786 | /* Pull all the valid messages off the CRQ */ | ||
2787 | while ((crq = ibmvfc_next_crq(vhost)) != NULL) { | ||
2788 | ibmvfc_handle_crq(crq, vhost); | ||
2789 | crq->valid = 0; | ||
2790 | } | ||
2791 | |||
2792 | /* Pull all the valid messages off the async CRQ */ | 2789 | /* Pull all the valid messages off the async CRQ */ |
2793 | while ((async = ibmvfc_next_async_crq(vhost)) != NULL) { | 2790 | while ((async = ibmvfc_next_async_crq(vhost)) != NULL) { |
2794 | ibmvfc_handle_async(async, vhost); | 2791 | ibmvfc_handle_async(async, vhost); |
2795 | async->valid = 0; | 2792 | async->valid = 0; |
2796 | } | 2793 | } |
2797 | 2794 | ||
2798 | vio_enable_interrupts(vdev); | 2795 | /* Pull all the valid messages off the CRQ */ |
2799 | if ((crq = ibmvfc_next_crq(vhost)) != NULL) { | 2796 | while ((crq = ibmvfc_next_crq(vhost)) != NULL) { |
2800 | vio_disable_interrupts(vdev); | ||
2801 | ibmvfc_handle_crq(crq, vhost); | 2797 | ibmvfc_handle_crq(crq, vhost); |
2802 | crq->valid = 0; | 2798 | crq->valid = 0; |
2803 | } else if ((async = ibmvfc_next_async_crq(vhost)) != NULL) { | 2799 | } |
2800 | |||
2801 | vio_enable_interrupts(vdev); | ||
2802 | if ((async = ibmvfc_next_async_crq(vhost)) != NULL) { | ||
2804 | vio_disable_interrupts(vdev); | 2803 | vio_disable_interrupts(vdev); |
2805 | ibmvfc_handle_async(async, vhost); | 2804 | ibmvfc_handle_async(async, vhost); |
2806 | async->valid = 0; | 2805 | async->valid = 0; |
2806 | } else if ((crq = ibmvfc_next_crq(vhost)) != NULL) { | ||
2807 | vio_disable_interrupts(vdev); | ||
2808 | ibmvfc_handle_crq(crq, vhost); | ||
2809 | crq->valid = 0; | ||
2807 | } else | 2810 | } else |
2808 | done = 1; | 2811 | done = 1; |
2809 | } | 2812 | } |
@@ -2927,7 +2930,11 @@ static void ibmvfc_tgt_prli_done(struct ibmvfc_event *evt) | |||
2927 | break; | 2930 | break; |
2928 | case IBMVFC_MAD_FAILED: | 2931 | case IBMVFC_MAD_FAILED: |
2929 | default: | 2932 | default: |
2930 | if (ibmvfc_retry_cmd(rsp->status, rsp->error)) | 2933 | if ((rsp->status & IBMVFC_VIOS_FAILURE) && rsp->error == IBMVFC_PLOGI_REQUIRED) |
2934 | level += ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_plogi); | ||
2935 | else if (tgt->logo_rcvd) | ||
2936 | level += ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_plogi); | ||
2937 | else if (ibmvfc_retry_cmd(rsp->status, rsp->error)) | ||
2931 | level += ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_prli); | 2938 | level += ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_prli); |
2932 | else | 2939 | else |
2933 | ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT); | 2940 | ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT); |
@@ -3054,6 +3061,7 @@ static void ibmvfc_tgt_send_plogi(struct ibmvfc_target *tgt) | |||
3054 | return; | 3061 | return; |
3055 | 3062 | ||
3056 | kref_get(&tgt->kref); | 3063 | kref_get(&tgt->kref); |
3064 | tgt->logo_rcvd = 0; | ||
3057 | evt = ibmvfc_get_event(vhost); | 3065 | evt = ibmvfc_get_event(vhost); |
3058 | vhost->discovery_threads++; | 3066 | vhost->discovery_threads++; |
3059 | ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT); | 3067 | ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT); |