[SCSI] zfcp: Warn about storage devices with broken PLOGI data
[safe/jmp/linux-2.6] / drivers / s390 / scsi / zfcp_fsf.c
index 665967f..5126461 100644 (file)
@@ -892,7 +892,7 @@ static void zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *req)
        case FSF_ADAPTER_STATUS_AVAILABLE:
                switch (fsq->word[0]) {
                case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
-                       zfcp_test_link(unit->port);
+                       zfcp_fc_test_link(unit->port);
                        /* fall through */
                case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
                        req->status |= ZFCP_STATUS_FSFREQ_ERROR;
@@ -1058,9 +1058,28 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
        bytes = zfcp_qdio_sbals_from_sg(adapter->qdio, &req->queue_req,
                                        SBAL_FLAGS0_TYPE_WRITE_READ,
                                        sg_resp, max_sbals);
+       req->qtcb->bottom.support.resp_buf_length = bytes;
        if (bytes <= 0)
                return -EIO;
-       req->qtcb->bottom.support.resp_buf_length = bytes;
+
+       return 0;
+}
+
+static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req,
+                                struct scatterlist *sg_req,
+                                struct scatterlist *sg_resp,
+                                int max_sbals)
+{
+       int ret;
+
+       ret = zfcp_fsf_setup_ct_els_sbals(req, sg_req, sg_resp, max_sbals);
+       if (ret)
+               return ret;
+
+       /* common settings for ct/gs and els requests */
+       req->qtcb->bottom.support.service_class = FSF_CLASS_3;
+       req->qtcb->bottom.support.timeout = 2 * R_A_TOV;
+       zfcp_fsf_start_timer(req, 2 * R_A_TOV + 10);
 
        return 0;
 }
@@ -1089,19 +1108,16 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool)
        }
 
        req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
-       ret = zfcp_fsf_setup_ct_els_sbals(req, ct->req, ct->resp,
-                                         FSF_MAX_SBALS_PER_REQ);
+       ret = zfcp_fsf_setup_ct_els(req, ct->req, ct->resp,
+                                   FSF_MAX_SBALS_PER_REQ);
        if (ret)
                goto failed_send;
 
        req->handler = zfcp_fsf_send_ct_handler;
        req->qtcb->header.port_handle = wka_port->handle;
-       req->qtcb->bottom.support.service_class = FSF_CLASS_3;
-       req->qtcb->bottom.support.timeout = ct->timeout;
        req->data = ct;
 
        zfcp_dbf_san_ct_request(req);
-       zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
 
        ret = zfcp_fsf_req_send(req);
        if (ret)
@@ -1139,7 +1155,7 @@ static void zfcp_fsf_send_els_handler(struct zfcp_fsf_req *req)
                switch (header->fsf_status_qual.word[0]){
                case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
                        if (port && (send_els->ls_code != ZFCP_LS_ADISC))
-                               zfcp_test_link(port);
+                               zfcp_fc_test_link(port);
                        /*fall through */
                case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
                case FSF_SQ_RETRY_IF_POSSIBLE:
@@ -1176,7 +1192,6 @@ int zfcp_fsf_send_els(struct zfcp_send_els *els)
 {
        struct zfcp_fsf_req *req;
        struct zfcp_qdio *qdio = els->adapter->qdio;
-       struct fsf_qtcb_bottom_support *bottom;
        int ret = -EIO;
 
        spin_lock_bh(&qdio->req_q_lock);
@@ -1191,21 +1206,17 @@ int zfcp_fsf_send_els(struct zfcp_send_els *els)
        }
 
        req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
-       ret = zfcp_fsf_setup_ct_els_sbals(req, els->req, els->resp, 2);
+       ret = zfcp_fsf_setup_ct_els(req, els->req, els->resp, 2);
 
        if (ret)
                goto failed_send;
 
-       bottom = &req->qtcb->bottom.support;
+       req->qtcb->bottom.support.d_id = els->d_id;
        req->handler = zfcp_fsf_send_els_handler;
-       bottom->d_id = els->d_id;
-       bottom->service_class = FSF_CLASS_3;
-       bottom->timeout = 2 * R_A_TOV;
        req->data = els;
 
        zfcp_dbf_san_els_request(req);
 
-       zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
        ret = zfcp_fsf_req_send(req);
        if (ret)
                goto failed_send;
@@ -1464,9 +1475,16 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req)
                plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els;
                if (req->qtcb->bottom.support.els1_length >=
                    FSF_PLOGI_MIN_LEN) {
-                       if (plogi->serv_param.wwpn != port->wwpn)
+                       if (plogi->serv_param.wwpn != port->wwpn) {
                                port->d_id = 0;
-                       else {
+                               dev_warn(&port->adapter->ccw_device->dev,
+                                        "A port opened with WWPN 0x%016Lx "
+                                        "returned data that identifies it as "
+                                        "WWPN 0x%016Lx\n",
+                                        (unsigned long long) port->wwpn,
+                                        (unsigned long long)
+                                         plogi->serv_param.wwpn);
+                       } else {
                                port->wwnn = plogi->serv_param.wwnn;
                                zfcp_fc_plogi_evaluate(port, plogi);
                        }
@@ -1889,7 +1907,7 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req)
        case FSF_ADAPTER_STATUS_AVAILABLE:
                switch (header->fsf_status_qual.word[0]) {
                case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
-                       zfcp_test_link(unit->port);
+                       zfcp_fc_test_link(unit->port);
                        /* fall through */
                case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
                        req->status |= ZFCP_STATUS_FSFREQ_ERROR;
@@ -2024,7 +2042,7 @@ static void zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *req)
        case FSF_ADAPTER_STATUS_AVAILABLE:
                switch (req->qtcb->header.fsf_status_qual.word[0]) {
                case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
-                       zfcp_test_link(unit->port);
+                       zfcp_fc_test_link(unit->port);
                        /* fall through */
                case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
                        req->status |= ZFCP_STATUS_FSFREQ_ERROR;
@@ -2307,7 +2325,7 @@ static void zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *req)
        case FSF_ADAPTER_STATUS_AVAILABLE:
                if (header->fsf_status_qual.word[0] ==
                    FSF_SQ_INVOKE_LINK_TEST_PROCEDURE)
-                       zfcp_test_link(unit->port);
+                       zfcp_fc_test_link(unit->port);
                req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                break;
        }