zfcp: add point-2-point support
author <jejb@titanic.il.steeleye.com> <>
Mon, 11 Apr 2005 04:04:28 +0000 (23:04 -0500)
committerJames Bottomley <jejb@titanic>
Mon, 18 Apr 2005 17:34:41 +0000 (12:34 -0500)
From: Andreas Herrmann <aherrman@de.ibm.com>

This patch mainly introduces support for point-2-point
topology.

From: Heiko Carstens <heiko.carstens@de.ibm.com>
From: Maxim Shchetynin <maxim@de.ibm.com>
From: Andreas Herrmann <aherrman@de.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
drivers/s390/scsi/zfcp_aux.c
drivers/s390/scsi/zfcp_def.h
drivers/s390/scsi/zfcp_erp.c
drivers/s390/scsi/zfcp_fsf.c
drivers/s390/scsi/zfcp_fsf.h
drivers/s390/scsi/zfcp_sysfs_adapter.c

index 6a43322ccb0a570a99e9ebe1dfabec475728ca47..a393cf4d0313cb22c7c8449168749b3b88a7744d 100644 (file)
@@ -89,10 +89,10 @@ MODULE_DESCRIPTION
     ("FCP (SCSI over Fibre Channel) HBA driver for IBM eServer zSeries");
 MODULE_LICENSE("GPL");
 
-module_param(device, charp, 0);
+module_param(device, charp, 0400);
 MODULE_PARM_DESC(device, "specify initial device");
 
-module_param(loglevel, uint, 0);
+module_param(loglevel, uint, 0400);
 MODULE_PARM_DESC(loglevel,
                 "log levels, 8 nibbles: "
                 "FC ERP QDIO CIO Config FSF SCSI Other, "
index 53fcccbb424c8c324170d8d5ec9cd90be0f8eb03..0afa1c4696ca6b5f7ae4c1356ad7b640f8c8b8cc 100644 (file)
@@ -70,7 +70,7 @@
 /********************* GENERAL DEFINES *********************************/
 
 /* zfcp version number, it consists of major, minor, and patch-level number */
-#define ZFCP_VERSION           "4.2.0"
+#define ZFCP_VERSION           "4.3.0"
 
 /**
  * zfcp_sg_to_address - determine kernel address from struct scatterlist
@@ -851,6 +851,9 @@ struct zfcp_adapter {
        wwn_t                   wwnn;              /* WWNN */
        wwn_t                   wwpn;              /* WWPN */
        fc_id_t                 s_id;              /* N_Port ID */
+       wwn_t                   peer_wwnn;         /* P2P peer WWNN */
+       wwn_t                   peer_wwpn;         /* P2P peer WWPN */
+       fc_id_t                 peer_d_id;         /* P2P peer D_ID */
        struct ccw_device       *ccw_device;       /* S/390 ccw device */
        u8                      fc_service_class;
        u32                     fc_topology;       /* FC topology */
index cfc0d8c588dfb8a653cfdd517de4e453867bc046..53ebc1cdfe2de995e4ea39bc75076549cab847e8 100644 (file)
@@ -2568,6 +2568,23 @@ zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *erp_action)
        case ZFCP_ERP_STEP_UNINITIALIZED:
        case ZFCP_ERP_STEP_PHYS_PORT_CLOSING:
        case ZFCP_ERP_STEP_PORT_CLOSING:
+               if (adapter->fc_topology == FSF_TOPO_P2P) {
+                       if (port->wwpn != adapter->peer_wwpn) {
+                               ZFCP_LOG_NORMAL("Failed to open port 0x%016Lx "
+                                               "on adapter %s.\nPeer WWPN "
+                                               "0x%016Lx does not match\n",
+                                               port->wwpn,
+                                               zfcp_get_busid_by_adapter(adapter),
+                                               adapter->peer_wwpn);
+                               zfcp_erp_port_failed(port);
+                               retval = ZFCP_ERP_FAILED;
+                               break;
+                       }
+                       port->d_id = adapter->peer_d_id;
+                       atomic_set_mask(ZFCP_STATUS_PORT_DID_DID, &port->status);
+                       retval = zfcp_erp_port_strategy_open_port(erp_action);
+                       break;
+               }
                if (!(adapter->nameserver_port)) {
                        retval = zfcp_nameserver_enqueue(adapter);
                        if (retval != 0) {
@@ -3516,8 +3533,9 @@ zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter)
        debug_text_event(adapter->erp_dbf, 3, "a_access_unblock");
        debug_event(adapter->erp_dbf, 3, &adapter->name, 8);
 
-       zfcp_erp_port_access_changed(adapter->nameserver_port);
        read_lock_irqsave(&zfcp_data.config_lock, flags);
+       if (adapter->nameserver_port)
+               zfcp_erp_port_access_changed(adapter->nameserver_port);
        list_for_each_entry(port, &adapter->port_list_head, list)
                if (port != adapter->nameserver_port)
                        zfcp_erp_port_access_changed(port);
index 578b9fbe5206510c2ed5c5ed3cdda3adeedf3a69..148b11c822bf818c9299744a907a0bdfe39d674e 100644 (file)
@@ -2107,6 +2107,9 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
                       bottom->low_qtcb_version, bottom->high_qtcb_version);
        adapter->fsf_lic_version = bottom->lic_version;
        adapter->supported_features = bottom->supported_features;
+       adapter->peer_wwpn = 0;
+       adapter->peer_wwnn = 0;
+       adapter->peer_d_id = 0;
 
        if (xchg_ok) {
                adapter->wwnn = bottom->nport_serv_param.wwnn;
@@ -2124,13 +2127,19 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
                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->supported_features & FSF_FEATURE_HBAAPI_MANAGEMENT){
                adapter->hardware_version = bottom->hardware_version;
                memcpy(adapter->serial_number, bottom->serial_number, 17);
                EBCASC(adapter->serial_number, sizeof(adapter->serial_number));
        }
 
-       ZFCP_LOG_INFO("The adapter %s reported the following characteristics:\n"
+       ZFCP_LOG_NORMAL("The adapter %s reported the following characteristics:\n"
                      "WWNN 0x%016Lx, "
                      "WWPN 0x%016Lx, "
                      "S_ID 0x%08x,\n"
@@ -2194,14 +2203,18 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
                switch (adapter->fc_topology) {
                case FSF_TOPO_P2P:
                        ZFCP_LOG_FLAGS(1, "FSF_TOPO_P2P\n");
-                       ZFCP_LOG_NORMAL("error: Point-to-point fibrechannel "
-                                       "configuration detected at adapter %s "
-                                       "unsupported, shutting down adapter\n",
-                                       zfcp_get_busid_by_adapter(adapter));
+                       ZFCP_LOG_NORMAL("Point-to-Point fibrechannel "
+                                       "configuration detected at adapter %s\n"
+                                       "Peer WWNN 0x%016llx, "
+                                       "peer WWPN 0x%016llx, "
+                                       "peer d_id 0x%06x\n",
+                                       zfcp_get_busid_by_adapter(adapter),
+                                       adapter->peer_wwnn,
+                                       adapter->peer_wwpn,
+                                       adapter->peer_d_id);
                        debug_text_event(fsf_req->adapter->erp_dbf, 0,
                                         "top-p-to-p");
-                       zfcp_erp_adapter_shutdown(adapter, 0);
-                       return -EIO;
+                       break;
                case FSF_TOPO_AL:
                        ZFCP_LOG_FLAGS(1, "FSF_TOPO_AL\n");
                        ZFCP_LOG_NORMAL("error: Arbitrated loop fibrechannel "
@@ -2226,6 +2239,7 @@ 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);
@@ -4281,6 +4295,7 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req)
                                      bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE);
                        zfcp_cmd_dbf_event_fsf("undeffcp", fsf_req, NULL, 0);
                        set_host_byte(&scpnt->result, DID_ERROR);
+                       goto skip_fsfstatus;
                }
        }
 
@@ -4334,7 +4349,7 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req)
 
                scpnt->resid = fcp_rsp_iu->fcp_resid;
                if (scpnt->request_bufflen - scpnt->resid < scpnt->underflow)
-                       scpnt->result |= DID_ERROR << 16;
+                       set_host_byte(&scpnt->result, DID_ERROR);
        }
 
  skip_fsfstatus:
@@ -4607,6 +4622,13 @@ zfcp_fsf_control_file_handler(struct zfcp_fsf_req *fsf_req)
                if (bottom->operation_subtype == FSF_CFDC_OPERATION_SUBTYPE) {
                        switch (header->fsf_status_qual.word[0]) {
 
+                       case FSF_SQ_CFDC_HARDENED_ON_SE:
+                               ZFCP_LOG_NORMAL(
+                                       "CFDC on the adapter %s has being "
+                                       "hardened on primary and secondary SE\n",
+                                       zfcp_get_busid_by_adapter(adapter));
+                               break;
+
                        case FSF_SQ_CFDC_COULD_NOT_HARDEN_ON_SE:
                                ZFCP_LOG_NORMAL(
                                        "CFDC of the adapter %s could not "
index 5889956bbf08699b749ba2e0fa68b1eff7a5b499..07140dfda2a7c3c5f6d112327f57ee423553a8bb 100644 (file)
 #define FSF_SQ_NO_RETRY_POSSIBLE               0x07
 
 /* FSF status qualifier for CFDC commands */
+#define FSF_SQ_CFDC_HARDENED_ON_SE             0x00000000
 #define FSF_SQ_CFDC_COULD_NOT_HARDEN_ON_SE     0x00000001
 #define FSF_SQ_CFDC_COULD_NOT_HARDEN_ON_SE2    0x00000002
 /* CFDC subtable codes */
@@ -357,7 +358,6 @@ struct fsf_nport_serv_param {
        u8  class3_serv_param[16];
        u8  class4_serv_param[16];
        u8  vendor_version_level[16];
-       u8  res1[16];
 } __attribute__ ((packed));
 
 struct fsf_plogi {
@@ -415,11 +415,13 @@ struct fsf_qtcb_bottom_config {
        u8 res2[12];
        u32 s_id;
        struct fsf_nport_serv_param nport_serv_param;
+       u8 reserved_nport_serv_param[16];
        u8 res3[8];
        u32 adapter_ports;
        u32 hardware_version;
        u8 serial_number[32];
-       u8 res4[272];
+       struct fsf_nport_serv_param plogi_payload;
+       u8 res4[160];
 } __attribute__ ((packed));
 
 struct fsf_qtcb_bottom_port {
index ff28ade1dfc7ad1825b10a2225438bc77314ff73..23e2dca55bb81f5156f38cab9079da360aa30302 100644 (file)
@@ -65,6 +65,9 @@ ZFCP_DEFINE_ADAPTER_ATTR(status, "0x%08x\n", atomic_read(&adapter->status));
 ZFCP_DEFINE_ADAPTER_ATTR(wwnn, "0x%016llx\n", adapter->wwnn);
 ZFCP_DEFINE_ADAPTER_ATTR(wwpn, "0x%016llx\n", adapter->wwpn);
 ZFCP_DEFINE_ADAPTER_ATTR(s_id, "0x%06x\n", adapter->s_id);
+ZFCP_DEFINE_ADAPTER_ATTR(peer_wwnn, "0x%016llx\n", adapter->peer_wwnn);
+ZFCP_DEFINE_ADAPTER_ATTR(peer_wwpn, "0x%016llx\n", adapter->peer_wwpn);
+ZFCP_DEFINE_ADAPTER_ATTR(peer_d_id, "0x%06x\n", adapter->peer_d_id);
 ZFCP_DEFINE_ADAPTER_ATTR(card_version, "0x%04x\n", adapter->hydra_version);
 ZFCP_DEFINE_ADAPTER_ATTR(lic_version, "0x%08x\n", adapter->fsf_lic_version);
 ZFCP_DEFINE_ADAPTER_ATTR(fc_link_speed, "%d Gb/s\n", adapter->fc_link_speed);
@@ -255,6 +258,9 @@ static struct attribute *zfcp_adapter_attrs[] = {
        &dev_attr_wwnn.attr,
        &dev_attr_wwpn.attr,
        &dev_attr_s_id.attr,
+       &dev_attr_peer_wwnn.attr,
+       &dev_attr_peer_wwpn.attr,
+       &dev_attr_peer_d_id.attr,
        &dev_attr_card_version.attr,
        &dev_attr_lic_version.attr,
        &dev_attr_fc_link_speed.attr,