]> err.no Git - linux-2.6/commitdiff
[SCSI] zfcp: fix adapter erp when link is unplugged
authorAndreas Herrmann <aherrman@de.ibm.com>
Sat, 11 Feb 2006 00:41:50 +0000 (01:41 +0100)
committer <jejb@mulgrave.il.steeleye.com> <>
Sun, 12 Feb 2006 17:11:58 +0000 (11:11 -0600)
Remove endless polling for replug of the local link. Just wait for
link up notification.

Signed-off-by: Andreas Herrmann <aherrman@de.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
drivers/s390/scsi/zfcp_def.h
drivers/s390/scsi/zfcp_erp.c
drivers/s390/scsi/zfcp_fsf.c

index 7dac56c49ade9c349691556dcb1b472e7a74eb58..f031199c7414a16f186a88bdd8c6ffd088316932 100644 (file)
@@ -152,11 +152,6 @@ typedef u32 scsi_lun_t;
 #define ZFCP_EXCHANGE_CONFIG_DATA_FIRST_SLEEP  100
 #define ZFCP_EXCHANGE_CONFIG_DATA_RETRIES      7
 
-/* Retry 5 times every 2 second, then every minute */
-#define ZFCP_EXCHANGE_PORT_DATA_SHORT_RETRIES  5
-#define ZFCP_EXCHANGE_PORT_DATA_SHORT_SLEEP    200
-#define ZFCP_EXCHANGE_PORT_DATA_LONG_SLEEP     6000
-
 /* timeout value for "default timer" for fsf requests */
 #define ZFCP_FSF_REQUEST_TIMEOUT (60*HZ);
 
index da947e662031f6114b02121591b0f912ac41ff73..8ed6fcb41653a83dd12976408bbf06602ef666c8 100644 (file)
@@ -2246,15 +2246,6 @@ zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *erp_action)
 {
        int retval;
 
-       if ((atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
-                             &erp_action->adapter->status)) &&
-           (erp_action->adapter->adapter_features &
-            FSF_FEATURE_HBAAPI_MANAGEMENT)) {
-               zfcp_erp_adapter_strategy_open_fsf_xport(erp_action);
-               atomic_set(&erp_action->adapter->erp_counter, 0);
-               return ZFCP_ERP_FAILED;
-       }
-
        retval = zfcp_erp_adapter_strategy_open_fsf_xconfig(erp_action);
        if (retval == ZFCP_ERP_FAILED)
                return ZFCP_ERP_FAILED;
@@ -2266,13 +2257,6 @@ zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *erp_action)
        return zfcp_erp_adapter_strategy_open_fsf_statusread(erp_action);
 }
 
-/*
- * function:   
- *
- * purpose:    
- *
- * returns:
- */
 static int
 zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action)
 {
@@ -2350,48 +2334,40 @@ static int
 zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action)
 {
        int ret;
-       int retries;
-       int sleep;
-       struct zfcp_adapter *adapter = erp_action->adapter;
+       struct zfcp_adapter *adapter;
 
+       adapter = erp_action->adapter;
        atomic_clear_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
 
-       retries = 0;
-       do {
-               write_lock(&adapter->erp_lock);
-               zfcp_erp_action_to_running(erp_action);
-               write_unlock(&adapter->erp_lock);
-               zfcp_erp_timeout_init(erp_action);
-               ret = zfcp_fsf_exchange_port_data(erp_action, adapter, NULL);
-               if (ret == -EOPNOTSUPP) {
-                       debug_text_event(adapter->erp_dbf, 3, "a_xport_notsupp");
-                       return ZFCP_ERP_SUCCEEDED;
-               } else if (ret) {
-                       debug_text_event(adapter->erp_dbf, 3, "a_xport_failed");
-                       return ZFCP_ERP_FAILED;
-               }
-               debug_text_event(adapter->erp_dbf, 6, "a_xport_ok");
+       write_lock(&adapter->erp_lock);
+       zfcp_erp_action_to_running(erp_action);
+       write_unlock(&adapter->erp_lock);
 
-               down(&adapter->erp_ready_sem);
-               if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {
-                       ZFCP_LOG_INFO("error: exchange of port data "
-                                     "for adapter %s timed out\n",
-                                     zfcp_get_busid_by_adapter(adapter));
-                       break;
-               }
-               if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
-                                     &adapter->status))
-                       break;
+       zfcp_erp_timeout_init(erp_action);
+       ret = zfcp_fsf_exchange_port_data(erp_action, adapter, NULL);
+       if (ret == -EOPNOTSUPP) {
+               debug_text_event(adapter->erp_dbf, 3, "a_xport_notsupp");
+               return ZFCP_ERP_SUCCEEDED;
+       } else if (ret) {
+               debug_text_event(adapter->erp_dbf, 3, "a_xport_failed");
+               return ZFCP_ERP_FAILED;
+       }
+       debug_text_event(adapter->erp_dbf, 6, "a_xport_ok");
 
-               if (retries < ZFCP_EXCHANGE_PORT_DATA_SHORT_RETRIES) {
-                       sleep = ZFCP_EXCHANGE_PORT_DATA_SHORT_SLEEP;
-                       retries++;
-               } else
-                       sleep = ZFCP_EXCHANGE_PORT_DATA_LONG_SLEEP;
-               schedule_timeout(sleep);
-       } while (1);
+       ret = ZFCP_ERP_SUCCEEDED;
+       down(&adapter->erp_ready_sem);
+       if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {
+               ZFCP_LOG_INFO("error: exchange port data timed out (adapter "
+                             "%s)\n", zfcp_get_busid_by_adapter(adapter));
+               ret = ZFCP_ERP_FAILED;
+       }
+       if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status)) {
+               ZFCP_LOG_INFO("error: exchange port data failed (adapter "
+                             "%s\n", zfcp_get_busid_by_adapter(adapter));
+               ret = ZFCP_ERP_FAILED;
+       }
 
-       return ZFCP_ERP_SUCCEEDED;
+       return ret;
 }
 
 /*
index 9f0cb3d820c06ce1753854e3946ebc4add466cfd..bd8cd4d4613452b9b247e14c182cc5bfc40dba53 100644 (file)
@@ -388,6 +388,7 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
        case FSF_PROT_LINK_DOWN:
                zfcp_fsf_link_down_info_eval(adapter,
                                             &prot_status_qual->link_down_info);
+               zfcp_erp_adapter_reopen(adapter, 0);
                fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                break;
 
@@ -558,10 +559,8 @@ zfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter,
 
        atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status);
 
-       if (link_down == NULL) {
-               zfcp_erp_adapter_reopen(adapter, 0);
-               return;
-       }
+       if (link_down == NULL)
+               goto out;
 
        switch (link_down->error_code) {
        case FSF_PSQ_LINK_NO_LIGHT:
@@ -643,16 +642,8 @@ zfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter,
                                link_down->explanation_code,
                                link_down->vendor_specific_code);
 
-       switch (link_down->error_code) {
-       case FSF_PSQ_LINK_NO_LIGHT:
-       case FSF_PSQ_LINK_WRAP_PLUG:
-       case FSF_PSQ_LINK_NO_FCP:
-       case FSF_PSQ_LINK_FIRMWARE_UPDATE:
-               zfcp_erp_adapter_reopen(adapter, 0);
-               break;
-       default:
-               zfcp_erp_adapter_failed(adapter);
-       }
+ out:
+       zfcp_erp_adapter_failed(adapter);
 }
 
 /*
@@ -2304,6 +2295,35 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
        return retval;
 }
 
+/**
+ * zfcp_fsf_exchange_port_evaluate
+ * @fsf_req: fsf_req which belongs to xchg port data request
+ * @xchg_ok: specifies if xchg port data was incomplete or complete (0/1)
+ */
+static void
+zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
+{
+       struct zfcp_adapter *adapter;
+       struct fsf_qtcb *qtcb;
+       struct fsf_qtcb_bottom_port *bottom, *data;
+       struct Scsi_Host *shost;
+
+       adapter = fsf_req->adapter;
+       qtcb = fsf_req->qtcb;
+       bottom = &qtcb->bottom.port;
+       shost = adapter->scsi_host;
+
+       data = (struct fsf_qtcb_bottom_port*) fsf_req->data;
+       if (data)
+               memcpy(data, bottom, sizeof(struct fsf_qtcb_bottom_port));
+
+       if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
+               fc_host_permanent_port_name(shost) = bottom->wwpn;
+       else
+               fc_host_permanent_port_name(shost) = fc_host_port_name(shost);
+       fc_host_maxframe_size(shost) = bottom->maximum_frame_size;
+       fc_host_supported_speeds(shost) = bottom->supported_speed;
+}
 
 /**
  * zfcp_fsf_exchange_port_data_handler - handler for exchange_port_data request
@@ -2312,38 +2332,26 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
 static void
 zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *fsf_req)
 {
-       struct zfcp_adapter *adapter = fsf_req->adapter;
-       struct Scsi_Host *shost = adapter->scsi_host;
-       struct fsf_qtcb *qtcb = fsf_req->qtcb;
-       struct fsf_qtcb_bottom_port *bottom, *data;
+       struct zfcp_adapter *adapter;
+       struct fsf_qtcb *qtcb;
+
+       adapter = fsf_req->adapter;
+       qtcb = fsf_req->qtcb;
 
        if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)
                return;
 
        switch (qtcb->header.fsf_status) {
         case FSF_GOOD:
+               zfcp_fsf_exchange_port_evaluate(fsf_req, 1);
                atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
-
-               bottom = &qtcb->bottom.port;
-               data = (struct fsf_qtcb_bottom_port*) fsf_req->data;
-               if (data)
-                       memcpy(data, bottom, sizeof(struct fsf_qtcb_bottom_port));
-               if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
-                       fc_host_permanent_port_name(shost) = bottom->wwpn;
-               else
-                       fc_host_permanent_port_name(shost) =
-                               fc_host_port_name(shost);
-               fc_host_maxframe_size(shost) = bottom->maximum_frame_size;
-               fc_host_supported_speeds(shost) = bottom->supported_speed;
                break;
-
        case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE:
+               zfcp_fsf_exchange_port_evaluate(fsf_req, 0);
                atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
-
                zfcp_fsf_link_down_info_eval(adapter,
                        &qtcb->header.fsf_status_qual.link_down_info);
                 break;
-
         default:
                debug_text_event(adapter->erp_dbf, 0, "xchg-port-ng");
                debug_event(adapter->erp_dbf, 0,