[SCSI] zfcp: evaluate plogi payload to set maxframe_size, supported_classes of rports
authorRalph Wuerthner <rwuerthn@de.ibm.com>
Mon, 22 May 2006 16:24:33 +0000 (18:24 +0200)
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>
Sun, 28 May 2006 16:45:15 +0000 (12:45 -0400)
Signed-off-by: Ralph Wuerthner <rwuerthn@de.ibm.com>
Signed-off-by: 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_ext.h
drivers/s390/scsi/zfcp_fsf.c
drivers/s390/scsi/zfcp_scsi.c

index bdaad5535e22e2aff9b245a364962040cd1c4380..9cd789b8acd4d4eb7e16dcc640fe43a48a60358e 100644 (file)
@@ -1748,4 +1748,25 @@ zfcp_handle_els_rjt(u32 sq, struct zfcp_ls_rjt_par *rjt_par)
        return ret;
 }
 
+/**
+ * zfcp_plogi_evaluate - evaluate PLOGI playload and copy important fields
+ * into zfcp_port structure
+ * @port: zfcp_port structure
+ * @plogi: plogi payload
+ */
+void
+zfcp_plogi_evaluate(struct zfcp_port *port, struct fsf_plogi *plogi)
+{
+       port->maxframe_size = plogi->serv_param.common_serv_param[7] |
+               ((plogi->serv_param.common_serv_param[6] & 0x0F) << 8);
+       if (plogi->serv_param.class1_serv_param[0] & 0x80)
+               port->supported_classes |= FC_COS_CLASS1;
+       if (plogi->serv_param.class2_serv_param[0] & 0x80)
+               port->supported_classes |= FC_COS_CLASS2;
+       if (plogi->serv_param.class3_serv_param[0] & 0x80)
+               port->supported_classes |= FC_COS_CLASS3;
+       if (plogi->serv_param.class4_serv_param[0] & 0x80)
+               port->supported_classes |= FC_COS_CLASS4;
+}
+
 #undef ZFCP_LOG_AREA
index e93272f1882703c7d266546f0c08388ece8a685b..a67d608388a16d5eb9496c008b7fa85360c5dd71 100644 (file)
@@ -959,6 +959,8 @@ struct zfcp_port {
        u32                    handle;         /* handle assigned by FSF */
        struct zfcp_erp_action erp_action;     /* pending error recovery */
         atomic_t               erp_counter;
+       u32                    maxframe_size;
+       u32                    supported_classes;
 };
 
 /* the struct device sysfs_device must be at the beginning of this structure.
index ce852c0de129872c4e669e0418e820251cdd81d7..05c47f6ca924c9804194f4bf86027fcfcd80fe36 100644 (file)
@@ -3257,8 +3257,12 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter,
                                                "(adapter %s, wwpn=0x%016Lx)\n",
                                                zfcp_get_busid_by_port(port),
                                                port->wwpn);
-                       else
+                       else {
                                scsi_flush_work(adapter->scsi_host);
+                               port->rport->maxframe_size = port->maxframe_size;
+                               port->rport->supported_classes =
+                                       port->supported_classes;
+                       }
                }
                zfcp_port_put(port);
                break;
index 6be2bb71c737b36f05422767157a9097b4333833..ab38b8ce27aad76c498ef5896374ff1f935e12ab 100644 (file)
@@ -115,6 +115,7 @@ extern int  zfcp_nameserver_enqueue(struct zfcp_adapter *);
 extern int  zfcp_ns_gid_pn_request(struct zfcp_erp_action *);
 extern int  zfcp_check_ct_response(struct ct_hdr *);
 extern int  zfcp_handle_els_rjt(u32, struct zfcp_ls_rjt_par *);
+extern void zfcp_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *);
 
 /******************************* SCSI ****************************************/
 extern int  zfcp_adapter_scsi_register(struct zfcp_adapter *);
index 55785acf8709ed300332a03c11f5b07b9f70f1ac..6335f9229184004d1fd92194af65addb6e746355 100644 (file)
@@ -2560,8 +2560,7 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req)
                if (!atomic_test_mask(ZFCP_STATUS_PORT_NO_WWPN, &port->status))
                {
                        if (fsf_req->qtcb->bottom.support.els1_length <
-                           ((((unsigned long) &plogi->serv_param.wwpn) -
-                             ((unsigned long) plogi)) + sizeof (u64))) {
+                           sizeof (struct fsf_plogi)) {
                                ZFCP_LOG_INFO(
                                        "warning: insufficient length of "
                                        "PLOGI payload (%i)\n",
@@ -2580,8 +2579,10 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req)
                                        atomic_clear_mask(
                                                ZFCP_STATUS_PORT_DID_DID,
                                                &port->status);
-                               } else
+                               } else {
                                        port->wwnn = plogi->serv_param.wwnn;
+                                       zfcp_plogi_evaluate(port, plogi);
+                               }
                        }
                }
                break;
index f198814196a475ee4ce5e8b0623da7170b1bad88..30e87197f5f887137cbc2a3eaf7cdcfc107a66de 100644 (file)
@@ -805,6 +805,7 @@ struct fc_function_template zfcp_transport_functions = {
        .show_starget_port_name = 1,
        .show_starget_node_name = 1,
        .show_rport_supported_classes = 1,
+       .show_rport_maxframe_size = 1,
        .show_host_node_name = 1,
        .show_host_port_name = 1,
        .show_host_permanent_port_name = 1,