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); |
