diff options
Diffstat (limited to 'drivers/scsi/ibmvscsi/ibmvfc.c')
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvfc.c | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index ae560bc04f9d..4e0b7c8eb32e 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c | |||
@@ -556,11 +556,12 @@ static void ibmvfc_link_down(struct ibmvfc_host *vhost, | |||
556 | /** | 556 | /** |
557 | * ibmvfc_init_host - Start host initialization | 557 | * ibmvfc_init_host - Start host initialization |
558 | * @vhost: ibmvfc host struct | 558 | * @vhost: ibmvfc host struct |
559 | * @relogin: is this a re-login? | ||
559 | * | 560 | * |
560 | * Return value: | 561 | * Return value: |
561 | * nothing | 562 | * nothing |
562 | **/ | 563 | **/ |
563 | static void ibmvfc_init_host(struct ibmvfc_host *vhost) | 564 | static void ibmvfc_init_host(struct ibmvfc_host *vhost, int relogin) |
564 | { | 565 | { |
565 | struct ibmvfc_target *tgt; | 566 | struct ibmvfc_target *tgt; |
566 | 567 | ||
@@ -574,6 +575,11 @@ static void ibmvfc_init_host(struct ibmvfc_host *vhost) | |||
574 | } | 575 | } |
575 | 576 | ||
576 | if (!ibmvfc_set_host_state(vhost, IBMVFC_INITIALIZING)) { | 577 | if (!ibmvfc_set_host_state(vhost, IBMVFC_INITIALIZING)) { |
578 | if (!relogin) { | ||
579 | memset(vhost->async_crq.msgs, 0, PAGE_SIZE); | ||
580 | vhost->async_crq.cur = 0; | ||
581 | } | ||
582 | |||
577 | list_for_each_entry(tgt, &vhost->targets, queue) | 583 | list_for_each_entry(tgt, &vhost->targets, queue) |
578 | tgt->need_login = 1; | 584 | tgt->need_login = 1; |
579 | scsi_block_requests(vhost->host); | 585 | scsi_block_requests(vhost->host); |
@@ -1059,9 +1065,10 @@ static void ibmvfc_get_starget_port_id(struct scsi_target *starget) | |||
1059 | static int ibmvfc_wait_while_resetting(struct ibmvfc_host *vhost) | 1065 | static int ibmvfc_wait_while_resetting(struct ibmvfc_host *vhost) |
1060 | { | 1066 | { |
1061 | long timeout = wait_event_timeout(vhost->init_wait_q, | 1067 | long timeout = wait_event_timeout(vhost->init_wait_q, |
1062 | (vhost->state == IBMVFC_ACTIVE || | 1068 | ((vhost->state == IBMVFC_ACTIVE || |
1063 | vhost->state == IBMVFC_HOST_OFFLINE || | 1069 | vhost->state == IBMVFC_HOST_OFFLINE || |
1064 | vhost->state == IBMVFC_LINK_DEAD), | 1070 | vhost->state == IBMVFC_LINK_DEAD) && |
1071 | vhost->action == IBMVFC_HOST_ACTION_NONE), | ||
1065 | (init_timeout * HZ)); | 1072 | (init_timeout * HZ)); |
1066 | 1073 | ||
1067 | return timeout ? 0 : -EIO; | 1074 | return timeout ? 0 : -EIO; |
@@ -1450,8 +1457,8 @@ static void ibmvfc_scsi_done(struct ibmvfc_event *evt) | |||
1450 | struct ibmvfc_cmd *vfc_cmd = &evt->xfer_iu->cmd; | 1457 | struct ibmvfc_cmd *vfc_cmd = &evt->xfer_iu->cmd; |
1451 | struct ibmvfc_fcp_rsp *rsp = &vfc_cmd->rsp; | 1458 | struct ibmvfc_fcp_rsp *rsp = &vfc_cmd->rsp; |
1452 | struct scsi_cmnd *cmnd = evt->cmnd; | 1459 | struct scsi_cmnd *cmnd = evt->cmnd; |
1453 | int rsp_len = 0; | 1460 | u32 rsp_len = 0; |
1454 | int sense_len = rsp->fcp_sense_len; | 1461 | u32 sense_len = rsp->fcp_sense_len; |
1455 | 1462 | ||
1456 | if (cmnd) { | 1463 | if (cmnd) { |
1457 | if (vfc_cmd->response_flags & IBMVFC_ADAPTER_RESID_VALID) | 1464 | if (vfc_cmd->response_flags & IBMVFC_ADAPTER_RESID_VALID) |
@@ -1468,7 +1475,7 @@ static void ibmvfc_scsi_done(struct ibmvfc_event *evt) | |||
1468 | rsp_len = rsp->fcp_rsp_len; | 1475 | rsp_len = rsp->fcp_rsp_len; |
1469 | if ((sense_len + rsp_len) > SCSI_SENSE_BUFFERSIZE) | 1476 | if ((sense_len + rsp_len) > SCSI_SENSE_BUFFERSIZE) |
1470 | sense_len = SCSI_SENSE_BUFFERSIZE - rsp_len; | 1477 | sense_len = SCSI_SENSE_BUFFERSIZE - rsp_len; |
1471 | if ((rsp->flags & FCP_SNS_LEN_VALID) && rsp->fcp_sense_len) | 1478 | if ((rsp->flags & FCP_SNS_LEN_VALID) && rsp->fcp_sense_len && rsp_len <= 8) |
1472 | memcpy(cmnd->sense_buffer, rsp->data.sense + rsp_len, sense_len); | 1479 | memcpy(cmnd->sense_buffer, rsp->data.sense + rsp_len, sense_len); |
1473 | 1480 | ||
1474 | ibmvfc_log_error(evt); | 1481 | ibmvfc_log_error(evt); |
@@ -2077,17 +2084,18 @@ static void ibmvfc_handle_async(struct ibmvfc_async_crq *crq, | |||
2077 | { | 2084 | { |
2078 | const char *desc = ibmvfc_get_ae_desc(crq->event); | 2085 | const char *desc = ibmvfc_get_ae_desc(crq->event); |
2079 | 2086 | ||
2080 | ibmvfc_log(vhost, 3, "%s event received\n", desc); | 2087 | ibmvfc_log(vhost, 3, "%s event received. scsi_id: %lx, wwpn: %lx," |
2088 | " node_name: %lx\n", desc, crq->scsi_id, crq->wwpn, crq->node_name); | ||
2081 | 2089 | ||
2082 | switch (crq->event) { | 2090 | switch (crq->event) { |
2083 | case IBMVFC_AE_LINK_UP: | 2091 | case IBMVFC_AE_LINK_UP: |
2084 | case IBMVFC_AE_RESUME: | 2092 | case IBMVFC_AE_RESUME: |
2085 | vhost->events_to_log |= IBMVFC_AE_LINKUP; | 2093 | vhost->events_to_log |= IBMVFC_AE_LINKUP; |
2086 | ibmvfc_init_host(vhost); | 2094 | ibmvfc_init_host(vhost, 1); |
2087 | break; | 2095 | break; |
2088 | case IBMVFC_AE_SCN_FABRIC: | 2096 | case IBMVFC_AE_SCN_FABRIC: |
2089 | vhost->events_to_log |= IBMVFC_AE_RSCN; | 2097 | vhost->events_to_log |= IBMVFC_AE_RSCN; |
2090 | ibmvfc_init_host(vhost); | 2098 | ibmvfc_init_host(vhost, 1); |
2091 | break; | 2099 | break; |
2092 | case IBMVFC_AE_SCN_NPORT: | 2100 | case IBMVFC_AE_SCN_NPORT: |
2093 | case IBMVFC_AE_SCN_GROUP: | 2101 | case IBMVFC_AE_SCN_GROUP: |
@@ -2133,13 +2141,13 @@ static void ibmvfc_handle_crq(struct ibmvfc_crq *crq, struct ibmvfc_host *vhost) | |||
2133 | /* Send back a response */ | 2141 | /* Send back a response */ |
2134 | rc = ibmvfc_send_crq_init_complete(vhost); | 2142 | rc = ibmvfc_send_crq_init_complete(vhost); |
2135 | if (rc == 0) | 2143 | if (rc == 0) |
2136 | ibmvfc_init_host(vhost); | 2144 | ibmvfc_init_host(vhost, 0); |
2137 | else | 2145 | else |
2138 | dev_err(vhost->dev, "Unable to send init rsp. rc=%ld\n", rc); | 2146 | dev_err(vhost->dev, "Unable to send init rsp. rc=%ld\n", rc); |
2139 | break; | 2147 | break; |
2140 | case IBMVFC_CRQ_INIT_COMPLETE: | 2148 | case IBMVFC_CRQ_INIT_COMPLETE: |
2141 | dev_info(vhost->dev, "Partner initialization complete\n"); | 2149 | dev_info(vhost->dev, "Partner initialization complete\n"); |
2142 | ibmvfc_init_host(vhost); | 2150 | ibmvfc_init_host(vhost, 0); |
2143 | break; | 2151 | break; |
2144 | default: | 2152 | default: |
2145 | dev_err(vhost->dev, "Unknown crq message type: %d\n", crq->format); | 2153 | dev_err(vhost->dev, "Unknown crq message type: %d\n", crq->format); |
@@ -3357,8 +3365,6 @@ static void ibmvfc_npiv_login(struct ibmvfc_host *vhost) | |||
3357 | mad->buffer.va = vhost->login_buf_dma; | 3365 | mad->buffer.va = vhost->login_buf_dma; |
3358 | mad->buffer.len = sizeof(*vhost->login_buf); | 3366 | mad->buffer.len = sizeof(*vhost->login_buf); |
3359 | 3367 | ||
3360 | memset(vhost->async_crq.msgs, 0, PAGE_SIZE); | ||
3361 | vhost->async_crq.cur = 0; | ||
3362 | ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_INIT_WAIT); | 3368 | ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_INIT_WAIT); |
3363 | 3369 | ||
3364 | if (!ibmvfc_send_event(evt, vhost, default_timeout)) | 3370 | if (!ibmvfc_send_event(evt, vhost, default_timeout)) |
@@ -3601,8 +3607,9 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost) | |||
3601 | } | 3607 | } |
3602 | } | 3608 | } |
3603 | 3609 | ||
3604 | if (vhost->reinit) { | 3610 | if (vhost->reinit && !ibmvfc_set_host_state(vhost, IBMVFC_INITIALIZING)) { |
3605 | vhost->reinit = 0; | 3611 | vhost->reinit = 0; |
3612 | scsi_block_requests(vhost->host); | ||
3606 | ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_QUERY); | 3613 | ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_QUERY); |
3607 | } else { | 3614 | } else { |
3608 | ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_NONE); | 3615 | ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_NONE); |