]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/s390/scsi/zfcp_fsf.c
[PATCH] s390: Remove CVS generated information
[karo-tx-linux.git] / drivers / s390 / scsi / zfcp_fsf.c
index 3b0fc1163f5f4fa00e35438434e3e0f8da34300f..9f0cb3d820c06ce1753854e3946ebc4add466cfd 100644 (file)
@@ -30,8 +30,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define ZFCP_FSF_C_REVISION "$Revision: 1.92 $"
-
 #include "zfcp_ext.h"
 
 static int zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *);
@@ -554,6 +552,17 @@ static void
 zfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter,
                             struct fsf_link_down_info *link_down)
 {
+       if (atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
+                            &adapter->status))
+               return;
+
+       atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status);
+
+       if (link_down == NULL) {
+               zfcp_erp_adapter_reopen(adapter, 0);
+               return;
+       }
+
        switch (link_down->error_code) {
        case FSF_PSQ_LINK_NO_LIGHT:
                ZFCP_LOG_NORMAL("The local link to adapter %s is down "
@@ -634,20 +643,15 @@ zfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter,
                                link_down->explanation_code,
                                link_down->vendor_specific_code);
 
-       if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
-                             &adapter->status)) {
-               atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
-                               &adapter->status);
-               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);
-               }
+       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);
        }
 }
 
@@ -919,30 +923,36 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req)
                case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK:
                        ZFCP_LOG_INFO("Physical link to adapter %s is down\n",
                                      zfcp_get_busid_by_adapter(adapter));
+                       zfcp_fsf_link_down_info_eval(adapter,
+                               (struct fsf_link_down_info *)
+                               &status_buffer->payload);
                        break;
                case FSF_STATUS_READ_SUB_FDISC_FAILED:
                        ZFCP_LOG_INFO("Local link to adapter %s is down "
                                      "due to failed FDISC login\n",
-                             zfcp_get_busid_by_adapter(adapter));
+                                     zfcp_get_busid_by_adapter(adapter));
+                       zfcp_fsf_link_down_info_eval(adapter,
+                               (struct fsf_link_down_info *)
+                               &status_buffer->payload);
                        break;
                case FSF_STATUS_READ_SUB_FIRMWARE_UPDATE:
                        ZFCP_LOG_INFO("Local link to adapter %s is down "
                                      "due to firmware update on adapter\n",
                                      zfcp_get_busid_by_adapter(adapter));
+                       zfcp_fsf_link_down_info_eval(adapter, NULL);
                        break;
                default:
                        ZFCP_LOG_INFO("Local link to adapter %s is down "
                                      "due to unknown reason\n",
                                      zfcp_get_busid_by_adapter(adapter));
+                       zfcp_fsf_link_down_info_eval(adapter, NULL);
                };
-               zfcp_fsf_link_down_info_eval(adapter,
-                       (struct fsf_link_down_info *) &status_buffer->payload);
                break;
 
        case FSF_STATUS_READ_LINK_UP:
                ZFCP_LOG_NORMAL("Local link to adapter %s was replugged. "
-                             "Restarting operations on this adapter\n",
-                             zfcp_get_busid_by_adapter(adapter));
+                               "Restarting operations on this adapter\n",
+                               zfcp_get_busid_by_adapter(adapter));
                /* All ports should be marked as ready to run again */
                zfcp_erp_modify_adapter_status(adapter,
                                               ZFCP_STATUS_COMMON_RUNNING,
@@ -952,6 +962,40 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req)
                                        | ZFCP_STATUS_COMMON_ERP_FAILED);
                break;
 
+       case FSF_STATUS_READ_NOTIFICATION_LOST:
+               ZFCP_LOG_NORMAL("Unsolicited status notification(s) lost: "
+                               "adapter %s%s%s%s%s%s%s%s%s\n",
+                               zfcp_get_busid_by_adapter(adapter),
+                               (status_buffer->status_subtype &
+                                       FSF_STATUS_READ_SUB_INCOMING_ELS) ?
+                                       ", incoming ELS" : "",
+                               (status_buffer->status_subtype &
+                                       FSF_STATUS_READ_SUB_SENSE_DATA) ?
+                                       ", sense data" : "",
+                               (status_buffer->status_subtype &
+                                       FSF_STATUS_READ_SUB_LINK_STATUS) ?
+                                       ", link status change" : "",
+                               (status_buffer->status_subtype &
+                                       FSF_STATUS_READ_SUB_PORT_CLOSED) ?
+                                       ", port close" : "",
+                               (status_buffer->status_subtype &
+                                       FSF_STATUS_READ_SUB_BIT_ERROR_THRESHOLD) ?
+                                       ", bit error exception" : "",
+                               (status_buffer->status_subtype &
+                                       FSF_STATUS_READ_SUB_ACT_UPDATED) ?
+                                       ", ACT update" : "",
+                               (status_buffer->status_subtype &
+                                       FSF_STATUS_READ_SUB_ACT_HARDENED) ?
+                                       ", ACT hardening" : "",
+                               (status_buffer->status_subtype &
+                                       FSF_STATUS_READ_SUB_FEATURE_UPDATE_ALERT) ?
+                                       ", adapter feature change" : "");
+
+               if (status_buffer->status_subtype &
+                   FSF_STATUS_READ_SUB_ACT_UPDATED)
+                       zfcp_erp_adapter_access_changed(adapter);
+               break;
+
        case FSF_STATUS_READ_CFDC_UPDATED:
                ZFCP_LOG_NORMAL("CFDC has been updated on the adapter %s\n",
                              zfcp_get_busid_by_adapter(adapter));
@@ -1942,6 +1986,7 @@ zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
        erp_action->fsf_req->qtcb->bottom.config.feature_selection =
                        FSF_FEATURE_CFDC |
                        FSF_FEATURE_LUN_SHARING |
+                       FSF_FEATURE_NOTIFICATION_LOST |
                        FSF_FEATURE_UPDATE_ALERT;
 
        /* start QDIO request for this FSF request */
@@ -1996,27 +2041,30 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
                fc_host_port_id(shost) = bottom->s_id & ZFCP_DID_MASK;
                fc_host_speed(shost) = bottom->fc_link_speed;
                fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;
-               adapter->fc_topology = bottom->fc_topology;
                adapter->hydra_version = bottom->adapter_type;
-               if (adapter->physical_wwpn == 0)
-                       adapter->physical_wwpn = fc_host_port_name(shost);
-               if (adapter->physical_s_id == 0)
-                       adapter->physical_s_id = fc_host_port_id(shost);
+               if (fc_host_permanent_port_name(shost) == -1)
+                       fc_host_permanent_port_name(shost) =
+                               fc_host_port_name(shost);
+               if (bottom->fc_topology == FSF_TOPO_P2P) {
+                       adapter->peer_d_id = bottom->peer_d_id & ZFCP_DID_MASK;
+                       adapter->peer_wwpn = bottom->plogi_payload.wwpn;
+                       adapter->peer_wwnn = bottom->plogi_payload.wwnn;
+                       fc_host_port_type(shost) = FC_PORTTYPE_PTP;
+               } else if (bottom->fc_topology == FSF_TOPO_FABRIC)
+                       fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
+               else if (bottom->fc_topology == FSF_TOPO_AL)
+                       fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
+               else
+                       fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
        } else {
                fc_host_node_name(shost) = 0;
                fc_host_port_name(shost) = 0;
                fc_host_port_id(shost) = 0;
                fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
-               adapter->fc_topology = 0;
+               fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
                adapter->hydra_version = 0;
        }
 
-       if (adapter->fc_topology == FSF_TOPO_P2P) {
-               adapter->peer_d_id = bottom->peer_d_id & ZFCP_DID_MASK;
-               adapter->peer_wwpn = bottom->plogi_payload.wwpn;
-               adapter->peer_wwnn = bottom->plogi_payload.wwnn;
-       }
-
        if (adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT) {
                adapter->hardware_version = bottom->hardware_version;
                memcpy(fc_host_serial_number(shost), bottom->serial_number,
@@ -2085,8 +2133,8 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
                if (zfcp_fsf_exchange_config_evaluate(fsf_req, 1))
                        return -EIO;
 
-               switch (adapter->fc_topology) {
-               case FSF_TOPO_P2P:
+               switch (fc_host_port_type(adapter->scsi_host)) {
+               case FC_PORTTYPE_PTP:
                        ZFCP_LOG_NORMAL("Point-to-Point fibrechannel "
                                        "configuration detected at adapter %s\n"
                                        "Peer WWNN 0x%016llx, "
@@ -2099,7 +2147,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
                        debug_text_event(fsf_req->adapter->erp_dbf, 0,
                                         "top-p-to-p");
                        break;
-               case FSF_TOPO_AL:
+               case FC_PORTTYPE_NLPORT:
                        ZFCP_LOG_NORMAL("error: Arbitrated loop fibrechannel "
                                        "topology detected at adapter %s "
                                        "unsupported, shutting down adapter\n",
@@ -2108,7 +2156,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
                                         "top-al");
                        zfcp_erp_adapter_shutdown(adapter, 0);
                        return -EIO;
-               case FSF_TOPO_FABRIC:
+               case FC_PORTTYPE_NPORT:
                        ZFCP_LOG_NORMAL("Switched fabric fibrechannel "
                                      "network detected at adapter %s.\n",
                                      zfcp_get_busid_by_adapter(adapter));
@@ -2121,7 +2169,6 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
                                        "of a type known to the zfcp "
                                        "driver, shutting down adapter\n",
                                        zfcp_get_busid_by_adapter(adapter));
-                       adapter->fc_topology = FSF_TOPO_ERROR;
                        debug_text_exception(fsf_req->adapter->erp_dbf, 0,
                                             "unknown-topo");
                        zfcp_erp_adapter_shutdown(adapter, 0);
@@ -2191,13 +2238,10 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
                 return -EOPNOTSUPP;
         }
 
-       timer = kmalloc(sizeof(struct timer_list), GFP_KERNEL);
-       if (!timer)
-               return -ENOMEM;
-
        /* setup new FSF request */
        retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA,
-                                     0, 0, &lock_flags, &fsf_req);
+                                    erp_action ? ZFCP_REQ_AUTO_CLEANUP : 0,
+                                    0, &lock_flags, &fsf_req);
        if (retval < 0) {
                ZFCP_LOG_INFO("error: Out of resources. Could not create an "
                               "exchange port data request for"
@@ -2205,25 +2249,33 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
                              zfcp_get_busid_by_adapter(adapter));
                write_unlock_irqrestore(&adapter->request_queue.queue_lock,
                                        lock_flags);
-               goto out;
-       }
-
-       if (erp_action) {
-               erp_action->fsf_req = fsf_req;
-               fsf_req->erp_action = erp_action;
+               return retval;
        }
 
        if (data)
-       fsf_req->data = (unsigned long) data;
+               fsf_req->data = (unsigned long) data;
 
        sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
         sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
         sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
-       init_timer(timer);
-       timer->function = zfcp_fsf_request_timeout_handler;
-       timer->data = (unsigned long) adapter;
-       timer->expires = ZFCP_FSF_REQUEST_TIMEOUT;
+       if (erp_action) {
+               erp_action->fsf_req = fsf_req;
+               fsf_req->erp_action = erp_action;
+               timer = &erp_action->timer;
+       } else {
+               timer = kmalloc(sizeof(struct timer_list), GFP_ATOMIC);
+               if (!timer) {
+                       write_unlock_irqrestore(&adapter->request_queue.queue_lock,
+                                               lock_flags);
+                       zfcp_fsf_req_free(fsf_req);
+                       return -ENOMEM;
+               }
+               init_timer(timer);
+               timer->function = zfcp_fsf_request_timeout_handler;
+               timer->data = (unsigned long) adapter;
+               timer->expires = ZFCP_FSF_REQUEST_TIMEOUT;
+       }
 
        retval = zfcp_fsf_req_send(fsf_req, timer);
        if (retval) {
@@ -2233,23 +2285,22 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
                zfcp_fsf_req_free(fsf_req);
                if (erp_action)
                        erp_action->fsf_req = NULL;
+               else
+                       kfree(timer);
                write_unlock_irqrestore(&adapter->request_queue.queue_lock,
                                        lock_flags);
-               goto out;
+               return retval;
        }
 
-       ZFCP_LOG_DEBUG("Exchange Port Data request initiated (adapter %s)\n",
-                      zfcp_get_busid_by_adapter(adapter));
-
-       write_unlock_irqrestore(&adapter->request_queue.queue_lock,
-                               lock_flags);
+       write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags);
 
-       wait_event(fsf_req->completion_wq,
-                  fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
-       del_timer_sync(timer);
-       zfcp_fsf_req_free(fsf_req);
- out:
-       kfree(timer);
+       if (!erp_action) {
+               wait_event(fsf_req->completion_wq,
+                          fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
+               del_timer_sync(timer);
+               zfcp_fsf_req_free(fsf_req);
+               kfree(timer);
+       }
        return retval;
 }
 
@@ -2277,14 +2328,13 @@ zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *fsf_req)
                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) {
-                       adapter->physical_wwpn = bottom->wwpn;
-                       adapter->physical_s_id = bottom->fc_port_id;
-               } else {
-                       adapter->physical_wwpn = fc_host_port_name(shost);
-                       adapter->physical_s_id = fc_host_port_id(shost);
-               }
+               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: