fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / s390 / scsi / zfcp_def.h
index 65c89d3..32933ed 100644 (file)
@@ -1,17 +1,8 @@
 /* 
- * 
- * linux/drivers/s390/scsi/zfcp_def.h
- * 
- * FCP adapter driver for IBM eServer zSeries 
- * 
- * (C) Copyright IBM Corp. 2002, 2004
+ * This file is part of the zfcp device driver for
+ * FCP adapters for IBM System z9 and zSeries.
  *
- * Author(s): Martin Peschke <mpeschke@de.ibm.com> 
- *            Raimund Schroeder <raimund.schroeder@de.ibm.com> 
- *            Aron Zeh
- *            Wolfgang Taphorn
- *            Stefan Bader <stefan.bader@de.ibm.com> 
- *            Heiko Carstens <heiko.carstens@de.ibm.com> 
+ * (C) Copyright IBM Corp. 2002, 2006
  * 
  * This program is free software; you can redistribute it and/or modify 
  * it under the terms of the GNU General Public License as published by 
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  */ 
 
-
 #ifndef ZFCP_DEF_H
 #define ZFCP_DEF_H
 
-/* this drivers version (do not edit !!! generated and updated by cvs) */
-#define ZFCP_DEF_REVISION "$Revision: 1.73 $"
-
 /*************************** INCLUDES *****************************************/
 
 #include <linux/init.h>
 #include <linux/miscdevice.h>
 #include <linux/major.h>
 #include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/slab.h>
+#include <linux/mempool.h>
+#include <linux/syscalls.h>
+#include <linux/ioctl.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_tcq.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
-#include "../../fc4/fc.h"
-#include "zfcp_fsf.h"
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_fc.h>
 #include <asm/ccwdev.h>
 #include <asm/qdio.h>
 #include <asm/debug.h>
 #include <asm/ebcdic.h>
-#include <linux/reboot.h>
-#include <linux/mempool.h>
-#include <linux/syscalls.h>
-#include <linux/ioctl.h>
-#ifdef CONFIG_S390_SUPPORT
-#include <linux/ioctl32.h>
-#endif
-
-/************************ DEBUG FLAGS *****************************************/
+#include "zfcp_fsf.h"
 
-#define        ZFCP_PRINT_FLAGS
 
 /********************* GENERAL DEFINES *********************************/
 
 /* zfcp version number, it consists of major, minor, and patch-level number */
-#define ZFCP_VERSION           "4.0.0"
+#define ZFCP_VERSION           "4.8.0"
 
+/**
+ * zfcp_sg_to_address - determine kernel address from struct scatterlist
+ * @list: struct scatterlist
+ * Return: kernel address
+ */
 static inline void *
 zfcp_sg_to_address(struct scatterlist *list)
 {
        return (void *) (page_address(list->page) + list->offset);
 }
 
+/**
+ * zfcp_address_to_sg - set up struct scatterlist from kernel address
+ * @address: kernel address
+ * @list: struct scatterlist
+ */
 static inline void
 zfcp_address_to_sg(void *address, struct scatterlist *list)
 {
@@ -83,14 +77,10 @@ zfcp_address_to_sg(void *address, struct scatterlist *list)
        list->offset = ((unsigned long) address) & (PAGE_SIZE - 1);
 }
 
-/********************* SCSI SPECIFIC DEFINES *********************************/
+#define REQUEST_LIST_SIZE 128
 
-/* 32 bit for SCSI ID and LUN as long as the SCSI stack uses this type */
-typedef u32 scsi_id_t;
-typedef u32 scsi_lun_t;
-
-#define ZFCP_ERP_SCSI_LOW_MEM_TIMEOUT           (100*HZ)
-#define ZFCP_SCSI_ER_TIMEOUT                    (100*HZ)
+/********************* SCSI SPECIFIC DEFINES *********************************/
+#define ZFCP_SCSI_ER_TIMEOUT                    (10*HZ)
 
 /********************* CIO/QDIO SPECIFIC DEFINES *****************************/
 
@@ -117,6 +107,10 @@ typedef u32 scsi_lun_t;
        (ZFCP_MAX_SBALS_PER_REQ * ZFCP_MAX_SBALES_PER_SBAL - 2)
         /* request ID + QTCB in SBALE 0 + 1 of first SBAL in chain */
 
+#define ZFCP_MAX_SECTORS (ZFCP_MAX_SBALES_PER_REQ * 8)
+        /* max. number of (data buffer) SBALEs in largest SBAL chain
+           multiplied with number of sectors per 4k block */
+
 /* FIXME(tune): free space should be one max. SBAL chain plus what? */
 #define ZFCP_QDIO_PCI_INTERVAL         (QDIO_MAX_BUFFERS_PER_Q \
                                          - (ZFCP_MAX_SBALS_PER_REQ + 4))
@@ -141,13 +135,17 @@ typedef u32 scsi_lun_t;
 #define FSF_QTCB_UNSOLICITED_STATUS            0x6305
 #define ZFCP_STATUS_READ_FAILED_THRESHOLD      3
 #define ZFCP_STATUS_READS_RECOM                        FSF_STATUS_READS_RECOM
-#define ZFCP_EXCHANGE_CONFIG_DATA_RETRIES      6
-#define ZFCP_EXCHANGE_CONFIG_DATA_SLEEP                50
+
+/* Do 1st retry in 1 second, then double the timeout for each following retry */
+#define ZFCP_EXCHANGE_CONFIG_DATA_FIRST_SLEEP  100
+#define ZFCP_EXCHANGE_CONFIG_DATA_RETRIES      7
+
+/* timeout value for "default timer" for fsf requests */
+#define ZFCP_FSF_REQUEST_TIMEOUT (60*HZ)
 
 /*************** FIBRE CHANNEL PROTOCOL SPECIFIC DEFINES ********************/
 
 typedef unsigned long long wwn_t;
-typedef unsigned int       fc_id_t;
 typedef unsigned long long fcp_lun_t;
 /* data length field may be at variable position in FCP-2 FCP_CMND IU */
 typedef unsigned int       fcp_dl_t;
@@ -156,7 +154,6 @@ typedef unsigned int       fcp_dl_t;
 
 /* timeout for name-server lookup (in seconds) */
 #define ZFCP_NS_GID_PN_TIMEOUT         10
-#define ZFCP_NS_GA_NXT_TIMEOUT         120
 
 /* largest SCSI command we can process */
 /* FCP-2 (FCP_CMND IU) allows up to (255-3+16) */
@@ -172,11 +169,11 @@ typedef unsigned int       fcp_dl_t;
 #define UNTAGGED       5
 
 /* task management flags in FCP-2 FCP_CMND IU */
-#define CLEAR_ACA              0x40
-#define TARGET_RESET           0x20
-#define LOGICAL_UNIT_RESET     0x10
-#define CLEAR_TASK_SET         0x04
-#define ABORT_TASK_SET         0x02
+#define FCP_CLEAR_ACA          0x40
+#define FCP_TARGET_RESET       0x20
+#define FCP_LOGICAL_UNIT_RESET 0x10
+#define FCP_CLEAR_TASK_SET     0x04
+#define FCP_ABORT_TASK_SET     0x02
 
 #define FCP_CDB_LENGTH         16
 
@@ -224,8 +221,9 @@ struct fcp_rsp_iu {
 #define RSP_CODE_TASKMAN_FAILED         5
 
 /* see fc-fs */
-#define LS_FAN 0x60000000
-#define LS_RSCN 0x61040000
+#define LS_RSCN  0x61040000
+#define LS_LOGO  0x05000000
+#define LS_PLOGI 0x03000000
 
 struct fcp_rscn_head {
         u8  command;
@@ -254,13 +252,6 @@ struct fcp_rscn_element {
 #define ZFCP_NO_PORTS_PER_DOMAIN  0x10000
 #define ZFCP_NO_PORTS_PER_FABRIC  0x1000000
 
-struct fcp_fan {
-        u32 command;
-        u32 fport_did;
-        wwn_t fport_wwpn;
-        wwn_t fport_wwname;
-} __attribute__((packed));
-
 /* see fc-ph */
 struct fcp_logo {
         u32 command;
@@ -269,157 +260,207 @@ struct fcp_logo {
 } __attribute__((packed));
 
 /*
- * FC-FS stuff
+ * DBF stuff
  */
-#define R_A_TOV                                10 /* seconds */
-#define ZFCP_ELS_TIMEOUT               (2 * R_A_TOV)
+#define ZFCP_DBF_TAG_SIZE      4
+
+struct zfcp_dbf_dump {
+       u8 tag[ZFCP_DBF_TAG_SIZE];
+       u32 total_size;         /* size of total dump data */
+       u32 offset;             /* how much data has being already dumped */
+       u32 size;               /* how much data comes with this record */
+       u8 data[];              /* dump data */
+} __attribute__ ((packed));
 
-#define ZFCP_LS_RJT                    0x01
-#define ZFCP_LS_ACC                    0x02
-#define ZFCP_LS_RTV                    0x0E
-#define ZFCP_LS_RLS                    0x0F
-#define ZFCP_LS_PDISC                  0x50
-#define ZFCP_LS_ADISC                  0x52
-#define ZFCP_LS_RSCN                   0x61
-#define ZFCP_LS_RNID                   0x78
-#define ZFCP_LS_RLIR                   0x7A
-#define ZFCP_LS_RTV_E_D_TOV_FLAG       0x04000000
-
-/* LS_ACC Reason Codes */
-#define ZFCP_LS_RJT_INVALID_COMMAND_CODE       0x01
-#define ZFCP_LS_RJT_LOGICAL_ERROR              0x03
-#define ZFCP_LS_RJT_LOGICAL_BUSY               0x05
-#define ZFCP_LS_RJT_PROTOCOL_ERROR             0x07
-#define ZFCP_LS_RJT_UNABLE_TO_PERFORM          0x09
-#define ZFCP_LS_RJT_COMMAND_NOT_SUPPORTED      0x0B
-#define ZFCP_LS_RJT_VENDOR_UNIQUE_ERROR                0xFF
-
-struct zfcp_ls_rjt {
-       u8              code;
-       u8              field[3];
-       u8              reserved;
-       u8      reason_code;
-       u8              reason_expl;
-       u8      vendor_unique;
+/* FIXME: to be inflated when reworking the erp dbf */
+struct zfcp_erp_dbf_record {
+       u8 dummy[16];
 } __attribute__ ((packed));
 
-struct zfcp_ls_rtv {
-       u8              code;
-       u8              field[3];
+struct zfcp_hba_dbf_record_response {
+       u32 fsf_command;
+       u64 fsf_reqid;
+       u32 fsf_seqno;
+       u64 fsf_issued;
+       u32 fsf_prot_status;
+       u32 fsf_status;
+       u8 fsf_prot_status_qual[FSF_PROT_STATUS_QUAL_SIZE];
+       u8 fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE];
+       u32 fsf_req_status;
+       u8 sbal_first;
+       u8 sbal_curr;
+       u8 sbal_last;
+       u8 pool;
+       u64 erp_action;
+       union {
+               struct {
+                       u64 scsi_cmnd;
+                       u64 scsi_serial;
+               } send_fcp;
+               struct {
+                       u64 wwpn;
+                       u32 d_id;
+                       u32 port_handle;
+               } port;
+               struct {
+                       u64 wwpn;
+                       u64 fcp_lun;
+                       u32 port_handle;
+                       u32 lun_handle;
+               } unit;
+               struct {
+                       u32 d_id;
+                       u8 ls_code;
+               } send_els;
+       } data;
 } __attribute__ ((packed));
 
-struct zfcp_ls_rtv_acc {
-       u8              code;
-       u8              field[3];
-       u32             r_a_tov;
-       u32             e_d_tov;
-       u32             qualifier;
+struct zfcp_hba_dbf_record_status {
+       u8 failed;
+       u32 status_type;
+       u32 status_subtype;
+       struct fsf_queue_designator
+        queue_designator;
+       u32 payload_size;
+#define ZFCP_DBF_UNSOL_PAYLOAD                         80
+#define ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL                32
+#define ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD     56
+#define ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT    2 * sizeof(u32)
+       u8 payload[ZFCP_DBF_UNSOL_PAYLOAD];
 } __attribute__ ((packed));
 
-struct zfcp_ls_rls {
-       u8              code;
-       u8              field[3];
-       fc_id_t         port_id;
+struct zfcp_hba_dbf_record_qdio {
+       u32 status;
+       u32 qdio_error;
+       u32 siga_error;
+       u8 sbal_index;
+       u8 sbal_count;
 } __attribute__ ((packed));
 
-struct zfcp_ls_rls_acc {
-       u8              code;
-       u8              field[3];
-       u32             link_failure_count;
-       u32             loss_of_sync_count;
-       u32             loss_of_signal_count;
-       u32             prim_seq_prot_error;
-       u32             invalid_transmition_word;
-       u32             invalid_crc_count;
+struct zfcp_hba_dbf_record {
+       u8 tag[ZFCP_DBF_TAG_SIZE];
+       u8 tag2[ZFCP_DBF_TAG_SIZE];
+       union {
+               struct zfcp_hba_dbf_record_response response;
+               struct zfcp_hba_dbf_record_status status;
+               struct zfcp_hba_dbf_record_qdio qdio;
+       } type;
 } __attribute__ ((packed));
 
-struct zfcp_ls_pdisc {
-       u8              code;
-       u8              field[3];
-       u8              common_svc_parm[16];
-               wwn_t   wwpn;
-       wwn_t           wwnn;
-       struct {
-               u8      class1[16];
-               u8      class2[16];
-               u8      class3[16];
-       } svc_parm;
-       u8              reserved[16];
-       u8              vendor_version[16];
+struct zfcp_san_dbf_record_ct {
+       union {
+               struct {
+                       u16 cmd_req_code;
+                       u8 revision;
+                       u8 gs_type;
+                       u8 gs_subtype;
+                       u8 options;
+                       u16 max_res_size;
+               } request;
+               struct {
+                       u16 cmd_rsp_code;
+                       u8 revision;
+                       u8 reason_code;
+                       u8 reason_code_expl;
+                       u8 vendor_unique;
+               } response;
+       } type;
+       u32 payload_size;
+#define ZFCP_DBF_CT_PAYLOAD    24
+       u8 payload[ZFCP_DBF_CT_PAYLOAD];
 } __attribute__ ((packed));
 
-struct zfcp_ls_pdisc_acc {
-       u8              code;
-       u8              field[3];
-       u8              common_svc_parm[16];
-       wwn_t           wwpn;
-       wwn_t           wwnn;
-       struct {
-               u8      class1[16];
-               u8      class2[16];
-               u8      class3[16];
-       } svc_parm;
-       u8              reserved[16];
-       u8              vendor_version[16];
+struct zfcp_san_dbf_record_els {
+       u8 ls_code;
+       u32 payload_size;
+#define ZFCP_DBF_ELS_PAYLOAD   32
+#define ZFCP_DBF_ELS_MAX_PAYLOAD 1024
+       u8 payload[ZFCP_DBF_ELS_PAYLOAD];
+} __attribute__ ((packed));
+
+struct zfcp_san_dbf_record {
+       u8 tag[ZFCP_DBF_TAG_SIZE];
+       u64 fsf_reqid;
+       u32 fsf_seqno;
+       u32 s_id;
+       u32 d_id;
+       union {
+               struct zfcp_san_dbf_record_ct ct;
+               struct zfcp_san_dbf_record_els els;
+       } type;
+} __attribute__ ((packed));
+
+struct zfcp_scsi_dbf_record {
+       u8 tag[ZFCP_DBF_TAG_SIZE];
+       u8 tag2[ZFCP_DBF_TAG_SIZE];
+       u32 scsi_id;
+       u32 scsi_lun;
+       u32 scsi_result;
+       u64 scsi_cmnd;
+       u64 scsi_serial;
+#define ZFCP_DBF_SCSI_OPCODE   16
+       u8 scsi_opcode[ZFCP_DBF_SCSI_OPCODE];
+       u8 scsi_retries;
+       u8 scsi_allowed;
+       u64 fsf_reqid;
+       u32 fsf_seqno;
+       u64 fsf_issued;
+       union {
+               u64 old_fsf_reqid;
+               struct {
+                       u8 rsp_validity;
+                       u8 rsp_scsi_status;
+                       u32 rsp_resid;
+                       u8 rsp_code;
+#define ZFCP_DBF_SCSI_FCP_SNS_INFO     16
+#define ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO 256
+                       u32 sns_info_len;
+                       u8 sns_info[ZFCP_DBF_SCSI_FCP_SNS_INFO];
+               } fcp;
+       } type;
+} __attribute__ ((packed));
+
+/*
+ * FC-FS stuff
+ */
+#define R_A_TOV                                10 /* seconds */
+#define ZFCP_ELS_TIMEOUT               (2 * R_A_TOV)
+
+#define ZFCP_LS_RLS                    0x0f
+#define ZFCP_LS_ADISC                  0x52
+#define ZFCP_LS_RPS                    0x56
+#define ZFCP_LS_RSCN                   0x61
+#define ZFCP_LS_RNID                   0x78
+
+struct zfcp_ls_rjt_par {
+       u8 action;
+       u8 reason_code;
+       u8 reason_expl;
+       u8 vendor_unique;
 } __attribute__ ((packed));
 
 struct zfcp_ls_adisc {
        u8              code;
        u8              field[3];
-       fc_id_t         hard_nport_id;
-       wwn_t           wwpn;
-       wwn_t           wwnn;
-       fc_id_t         nport_id;
+       u32             hard_nport_id;
+       u64             wwpn;
+       u64             wwnn;
+       u32             nport_id;
 } __attribute__ ((packed));
 
 struct zfcp_ls_adisc_acc {
        u8              code;
        u8              field[3];
-       fc_id_t         hard_nport_id;
-       wwn_t           wwpn;
-       wwn_t           wwnn;
-       fc_id_t         nport_id;
+       u32             hard_nport_id;
+       u64             wwpn;
+       u64             wwnn;
+       u32             nport_id;
 } __attribute__ ((packed));
 
-struct zfcp_ls_rnid {
-       u8              code;
-       u8              field[3];
-       u8              node_id_format;
-       u8              reserved[3];
-} __attribute__((packed));
-
-/* common identification data */
-struct zfcp_ls_rnid_common_id {
-       u64             n_port_name;
-       u64             node_name;
-} __attribute__((packed));
-
-/* general topology specific identification data */
-struct zfcp_ls_rnid_general_topology_id {
-       u8              vendor_unique[16];
-       u32             associated_type;
-       u32             physical_port_number;
-       u32             nr_attached_nodes;
-       u8              node_management;
-       u8              ip_version;
-       u16             port_number;
-       u8              ip_address[16];
-       u8              reserved[2];
-       u16             vendor_specific;
-} __attribute__((packed));
-
-struct zfcp_ls_rnid_acc {
-       u8              code;
-       u8              field[3];
-       u8              node_id_format;
-       u8              common_id_length;
-       u8              reserved;
-       u8              specific_id_length;
-       struct zfcp_ls_rnid_common_id
-                       common_id;
-       struct zfcp_ls_rnid_general_topology_id
-                       specific_id;
-} __attribute__((packed));
+struct zfcp_rc_entry {
+       u8 code;
+       const char *description;
+};
 
 /*
  * FC-GS-2 stuff
@@ -429,43 +470,15 @@ struct zfcp_ls_rnid_acc {
 #define ZFCP_CT_NAME_SERVER            0x02
 #define ZFCP_CT_SYNCHRONOUS            0x00
 #define ZFCP_CT_GID_PN                 0x0121
-#define ZFCP_CT_GA_NXT                 0x0100
 #define ZFCP_CT_MAX_SIZE               0x1020
 #define ZFCP_CT_ACCEPT                 0x8002
+#define ZFCP_CT_REJECT                 0x8001
 
 /*
  * FC-GS-4 stuff
  */
 #define ZFCP_CT_TIMEOUT                        (3 * R_A_TOV)
 
-
-/***************** S390 DEBUG FEATURE SPECIFIC DEFINES ***********************/
-
-/* debug feature entries per adapter */
-#define ZFCP_ERP_DBF_INDEX     1 
-#define ZFCP_ERP_DBF_AREAS     2
-#define ZFCP_ERP_DBF_LENGTH    16
-#define ZFCP_ERP_DBF_LEVEL     3
-#define ZFCP_ERP_DBF_NAME      "zfcperp"
-
-#define ZFCP_CMD_DBF_INDEX     2
-#define ZFCP_CMD_DBF_AREAS     1
-#define ZFCP_CMD_DBF_LENGTH    8
-#define ZFCP_CMD_DBF_LEVEL     3
-#define ZFCP_CMD_DBF_NAME      "zfcpcmd"
-
-#define ZFCP_ABORT_DBF_INDEX   2
-#define ZFCP_ABORT_DBF_AREAS   1
-#define ZFCP_ABORT_DBF_LENGTH  8
-#define ZFCP_ABORT_DBF_LEVEL   6
-#define ZFCP_ABORT_DBF_NAME    "zfcpabt"
-
-#define ZFCP_IN_ELS_DBF_INDEX  2
-#define ZFCP_IN_ELS_DBF_AREAS  1
-#define ZFCP_IN_ELS_DBF_LENGTH 8
-#define ZFCP_IN_ELS_DBF_LEVEL  6
-#define ZFCP_IN_ELS_DBF_NAME   "zfcpels"
-
 /******************** LOGGING MACROS AND DEFINES *****************************/
 
 /*
@@ -509,14 +522,14 @@ struct zfcp_ls_rnid_acc {
 
 /* all log-level defaults are combined to generate initial log-level */
 #define ZFCP_LOG_LEVEL_DEFAULTS \
-       (ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_INFO, ZFCP_LOG_AREA_OTHER) | \
-        ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_INFO, ZFCP_LOG_AREA_SCSI) | \
-        ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_INFO, ZFCP_LOG_AREA_FSF) | \
-        ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_INFO, ZFCP_LOG_AREA_CONFIG) | \
-        ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_INFO, ZFCP_LOG_AREA_CIO) | \
-        ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_INFO, ZFCP_LOG_AREA_QDIO) | \
-        ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_INFO, ZFCP_LOG_AREA_ERP) | \
-        ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_INFO, ZFCP_LOG_AREA_FC))
+       (ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_OTHER) | \
+        ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_SCSI) | \
+        ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_FSF) | \
+        ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_CONFIG) | \
+        ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_CIO) | \
+        ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_QDIO) | \
+        ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_ERP) | \
+        ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_FC))
 
 /* check whether we have the right level for logging */
 #define ZFCP_LOG_CHECK(level) \
@@ -525,59 +538,55 @@ struct zfcp_ls_rnid_acc {
 /* logging routine for zfcp */
 #define _ZFCP_LOG(fmt, args...) \
        printk(KERN_ERR ZFCP_NAME": %s(%d): " fmt, __FUNCTION__, \
-              __LINE__ , ##args);
+              __LINE__ , ##args)
 
 #define ZFCP_LOG(level, fmt, args...) \
+do { \
        if (ZFCP_LOG_CHECK(level)) \
-               _ZFCP_LOG(fmt , ##args)
+               _ZFCP_LOG(fmt, ##args); \
+} while (0)
        
 #if ZFCP_LOG_LEVEL_LIMIT < ZFCP_LOG_LEVEL_NORMAL
-# define ZFCP_LOG_NORMAL(fmt, args...)
+# define ZFCP_LOG_NORMAL(fmt, args...) do { } while (0)
 #else
 # define ZFCP_LOG_NORMAL(fmt, args...) \
+do { \
        if (ZFCP_LOG_CHECK(ZFCP_LOG_LEVEL_NORMAL)) \
-               printk(KERN_ERR ZFCP_NAME": " fmt , ##args);
+               printk(KERN_ERR ZFCP_NAME": " fmt, ##args); \
+} while (0)
 #endif
 
 #if ZFCP_LOG_LEVEL_LIMIT < ZFCP_LOG_LEVEL_INFO
-# define ZFCP_LOG_INFO(fmt, args...)
+# define ZFCP_LOG_INFO(fmt, args...)   do { } while (0)
 #else
 # define ZFCP_LOG_INFO(fmt, args...) \
+do { \
        if (ZFCP_LOG_CHECK(ZFCP_LOG_LEVEL_INFO)) \
-               printk(KERN_ERR ZFCP_NAME": " fmt , ##args);
+               printk(KERN_ERR ZFCP_NAME": " fmt, ##args); \
+} while (0)
 #endif
 
 #if ZFCP_LOG_LEVEL_LIMIT < ZFCP_LOG_LEVEL_DEBUG
-# define ZFCP_LOG_DEBUG(fmt, args...)
+# define ZFCP_LOG_DEBUG(fmt, args...)  do { } while (0)
 #else
 # define ZFCP_LOG_DEBUG(fmt, args...) \
        ZFCP_LOG(ZFCP_LOG_LEVEL_DEBUG, fmt , ##args)
 #endif
 
 #if ZFCP_LOG_LEVEL_LIMIT < ZFCP_LOG_LEVEL_TRACE
-# define ZFCP_LOG_TRACE(fmt, args...)
+# define ZFCP_LOG_TRACE(fmt, args...)  do { } while (0)
 #else
 # define ZFCP_LOG_TRACE(fmt, args...) \
        ZFCP_LOG(ZFCP_LOG_LEVEL_TRACE, fmt , ##args)
 #endif
 
-#ifndef ZFCP_PRINT_FLAGS
-# define ZFCP_LOG_FLAGS(level, fmt, args...)
-#else
-extern u32 flags_dump;
-# define ZFCP_LOG_FLAGS(level, fmt, args...) \
-       if (level <= flags_dump) \
-               _ZFCP_LOG(fmt , ##args)
-#endif
-
 /*************** ADAPTER/PORT/UNIT AND FSF_REQ STATUS FLAGS ******************/
 
 /* 
  * Note, the leftmost status byte is common among adapter, port 
  * and unit
  */
-#define ZFCP_COMMON_FLAGS                       0xff000000
-#define ZFCP_SPECIFIC_FLAGS                     0x00ffffff
+#define ZFCP_COMMON_FLAGS                      0xfff00000
 
 /* common status bits */
 #define ZFCP_STATUS_COMMON_REMOVE              0x80000000
@@ -588,6 +597,8 @@ extern u32 flags_dump;
 #define ZFCP_STATUS_COMMON_OPEN                 0x04000000
 #define ZFCP_STATUS_COMMON_CLOSING              0x02000000
 #define ZFCP_STATUS_COMMON_ERP_INUSE           0x01000000
+#define ZFCP_STATUS_COMMON_ACCESS_DENIED       0x00800000
+#define ZFCP_STATUS_COMMON_ACCESS_BOXED                0x00400000
 
 /* adapter status */
 #define ZFCP_STATUS_ADAPTER_QDIOUP             0x00000002
@@ -598,13 +609,14 @@ extern u32 flags_dump;
 #define ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL    0x00000080
 #define ZFCP_STATUS_ADAPTER_ERP_PENDING                0x00000100
 #define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED     0x00000200
+#define ZFCP_STATUS_ADAPTER_XPORT_OK           0x00000800
 
-#define ZFCP_STATUS_ADAPTER_SCSI_UP                    \
-               (ZFCP_STATUS_COMMON_UNBLOCKED | \
-                ZFCP_STATUS_ADAPTER_REGISTERED)
-
-
-#define ZFCP_DID_NAMESERVER                    0xFFFFFC
+/* FC-PH/FC-GS well-known address identifiers for generic services */
+#define ZFCP_DID_MANAGEMENT_SERVICE            0xFFFFFA
+#define ZFCP_DID_TIME_SERVICE                  0xFFFFFB
+#define ZFCP_DID_DIRECTORY_SERVICE             0xFFFFFC
+#define ZFCP_DID_ALIAS_SERVICE                 0xFFFFF8
+#define ZFCP_DID_KEY_DISTRIBUTION_SERVICE      0xFFFFF7
 
 /* remote port status */
 #define ZFCP_STATUS_PORT_PHYS_OPEN             0x00000001
@@ -614,13 +626,17 @@ extern u32 flags_dump;
 #define ZFCP_STATUS_PORT_NO_SCSI_ID            0x00000010
 #define ZFCP_STATUS_PORT_INVALID_WWPN          0x00000020
 
-#define ZFCP_STATUS_PORT_NAMESERVER \
+/* for ports with well known addresses */
+#define ZFCP_STATUS_PORT_WKA \
                (ZFCP_STATUS_PORT_NO_WWPN | \
                 ZFCP_STATUS_PORT_NO_SCSI_ID)
 
 /* logical unit status */
 #define ZFCP_STATUS_UNIT_NOTSUPPUNITRESET      0x00000001
-
+#define ZFCP_STATUS_UNIT_TEMPORARY             0x00000002
+#define ZFCP_STATUS_UNIT_SHARED                        0x00000004
+#define ZFCP_STATUS_UNIT_READONLY              0x00000008
+#define ZFCP_STATUS_UNIT_REGISTERED            0x00000010
 
 /* FSF request status (this does not have a common part) */
 #define ZFCP_STATUS_FSFREQ_NOT_INIT            0x00000000
@@ -723,45 +739,6 @@ struct zfcp_adapter_mempool {
        mempool_t *data_gid_pn;
 };
 
-struct  zfcp_exchange_config_data{
-};
-
-struct zfcp_open_port {
-        struct zfcp_port *port;
-};
-
-struct zfcp_close_port {
-       struct zfcp_port *port;
-};
-
-struct zfcp_open_unit {
-       struct zfcp_unit *unit;
-};
-
-struct zfcp_close_unit {
-       struct zfcp_unit *unit;
-};
-
-struct zfcp_close_physical_port {
-        struct zfcp_port *port;
-};
-
-struct zfcp_send_fcp_command_task {
-       struct zfcp_fsf_req *fsf_req;
-       struct zfcp_unit *unit;
-       struct scsi_cmnd *scsi_cmnd;
-       unsigned long start_jiffies;
-};
-
-struct zfcp_send_fcp_command_task_management {
-       struct zfcp_unit *unit;
-};
-
-struct zfcp_abort_fcp_command {
-       struct zfcp_fsf_req *fsf_req;
-       struct zfcp_unit *unit;
-};
-
 /*
  * header for CT_IU
  */
@@ -787,43 +764,28 @@ struct ct_iu_gid_pn_req {
        wwn_t wwpn;
 } __attribute__ ((packed));
 
-/* nameserver request CT_IU -- for requests where
- * a port identifier is required */
-struct ct_iu_ga_nxt_req {
-       struct ct_hdr header;
-       fc_id_t d_id;
-} __attribute__ ((packed));
-
 /* FS_ACC IU and data unit for GID_PN nameserver request */
 struct ct_iu_gid_pn_resp {
        struct ct_hdr header;
-       fc_id_t d_id;
-} __attribute__ ((packed));
-
-/* FS_ACC IU and data unit for GA_NXT nameserver request */
-struct ct_iu_ga_nxt_resp {
-       struct ct_hdr header;
-        u8 port_type;
-        u8 port_id[3];
-        u64 port_wwn;
-        u8 port_symbolic_name_length;
-        u8 port_symbolic_name[255];
-        u64 node_wwn;
-        u8 node_symbolic_name_length;
-        u8 node_symbolic_name[255];
-        u64 initial_process_associator;
-        u8 node_ip[16];
-        u32 cos;
-        u8 fc4_types[32];
-        u8 port_ip[16];
-        u64 fabric_wwn;
-        u8 reserved;
-        u8 hard_address[3];
+       u32 d_id;
 } __attribute__ ((packed));
 
 typedef void (*zfcp_send_ct_handler_t)(unsigned long);
 
-/* used to pass parameters to zfcp_send_ct() */
+/**
+ * struct zfcp_send_ct - used to pass parameters to function zfcp_fsf_send_ct
+ * @port: port where the request is sent to
+ * @req: scatter-gather list for request
+ * @resp: scatter-gather list for response
+ * @req_count: number of elements in request scatter-gather list
+ * @resp_count: number of elements in response scatter-gather list
+ * @handler: handler function (called for response to the request)
+ * @handler_data: data passed to handler function
+ * @pool: pointer to memory pool for ct request structure
+ * @timeout: FSF timeout for this request
+ * @completion: completion for synchronization purposes
+ * @status: used to pass error status to calling function
+ */
 struct zfcp_send_ct {
        struct zfcp_port *port;
        struct scatterlist *req;
@@ -832,9 +794,8 @@ struct zfcp_send_ct {
        unsigned int resp_count;
        zfcp_send_ct_handler_t handler;
        unsigned long handler_data;
-       mempool_t *pool;                /* mempool for ct not for fsf_req */
+       mempool_t *pool;
        int timeout;
-       struct timer_list *timer;
        struct completion *completion;
        int status;
 };
@@ -849,12 +810,27 @@ struct zfcp_gid_pn_data {
         struct zfcp_port *port;
 };
 
-typedef int (*zfcp_send_els_handler_t)(unsigned long);
-
-/* used to pass parameters to zfcp_send_els() */
-/* ToDo merge send_ct() and send_els() and corresponding structs */
+typedef void (*zfcp_send_els_handler_t)(unsigned long);
+
+/**
+ * struct zfcp_send_els - used to pass parameters to function zfcp_fsf_send_els
+ * @adapter: adapter where request is sent from
+ * @port: port where ELS is destinated (port reference count has to be increased)
+ * @d_id: destiniation id of port where request is sent to
+ * @req: scatter-gather list for request
+ * @resp: scatter-gather list for response
+ * @req_count: number of elements in request scatter-gather list
+ * @resp_count: number of elements in response scatter-gather list
+ * @handler: handler function (called for response to the request)
+ * @handler_data: data passed to handler function
+ * @completion: completion for synchronization purposes
+ * @ls_code: hex code of ELS command
+ * @status: used to pass error status to calling function
+ */
 struct zfcp_send_els {
+       struct zfcp_adapter *adapter;
        struct zfcp_port *port;
+       u32 d_id;
        struct scatterlist *req;
        struct scatterlist *resp;
        unsigned int req_count;
@@ -866,32 +842,6 @@ struct zfcp_send_els {
        int status;
 };
 
-struct zfcp_status_read {
-       struct fsf_status_read_buffer *buffer;
-};
-
-struct zfcp_fsf_done {
-       struct completion *complete;
-       int status;
-};
-
-/* request specific data */
-union zfcp_req_data {
-       struct zfcp_exchange_config_data exchange_config_data;
-       struct zfcp_open_port             open_port;
-       struct zfcp_close_port            close_port;
-       struct zfcp_open_unit             open_unit;
-       struct zfcp_close_unit            close_unit;
-       struct zfcp_close_physical_port   close_physical_port;
-       struct zfcp_send_fcp_command_task send_fcp_command_task;
-        struct zfcp_send_fcp_command_task_management
-                                         send_fcp_command_task_management;
-       struct zfcp_abort_fcp_command     abort_fcp_command;
-       struct zfcp_send_ct *send_ct;
-       struct zfcp_send_els *send_els;
-       struct zfcp_status_read           status_read;
-};
-
 struct zfcp_qdio_queue {
        struct qdio_buffer *buffer[QDIO_MAX_BUFFERS_PER_Q]; /* SBALs */
        u8                 free_index;        /* index of next free bfr
@@ -922,30 +872,24 @@ struct zfcp_adapter {
        atomic_t                refcount;          /* reference count */
        wait_queue_head_t       remove_wq;         /* can be used to wait for
                                                      refcount drop to zero */
-       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 */
+       u32                     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 */
-       u32                     fc_link_speed;     /* FC interface speed */
        u32                     hydra_version;     /* Hydra version */
        u32                     fsf_lic_version;
-        u32                    supported_features;/* of FCP channel */
+       u32                     adapter_features;  /* FCP channel features */
+       u32                     connection_features; /* host connection features */
         u32                    hardware_version;  /* of FCP channel */
-        u8                     serial_number[32]; /* of hardware */
        struct Scsi_Host        *scsi_host;        /* Pointer to mid-layer */
-       unsigned short          scsi_host_no;      /* Assigned host number */
-       unsigned char           name[9];
        struct list_head        port_list_head;    /* remote port list */
        struct list_head        port_remove_lh;    /* head of ports to be
                                                      removed */
        u32                     ports;             /* number of remote ports */
-        struct timer_list       scsi_er_timer;     /* SCSI err recovery watch */
-       struct list_head        fsf_req_list_head; /* head of FSF req list */
-       rwlock_t                fsf_req_list_lock; /* lock for ops on list of
-                                                     FSF requests */
-        atomic_t                       fsf_reqs_active;   /* # active FSF reqs */
+       atomic_t                reqs_active;       /* # active FSF reqs */
+       unsigned long           req_no;            /* unique FSF req number */
+       struct list_head        *req_list;         /* list of pending reqs */
+       spinlock_t              req_list_lock;     /* request list lock */
        struct zfcp_qdio_queue  request_queue;     /* request queue */
        u32                     fsf_req_seq_no;    /* FSF cmnd seq number */
        wait_queue_head_t       request_wq;        /* can be used to wait for
@@ -970,13 +914,24 @@ struct zfcp_adapter {
        u32                     erp_low_mem_count; /* nr of erp actions waiting
                                                      for memory */
        struct zfcp_port        *nameserver_port;  /* adapter's nameserver */
-        debug_info_t            *erp_dbf;          /* S/390 debug features */
-       debug_info_t            *abort_dbf;
-       debug_info_t            *in_els_dbf;
-       debug_info_t            *cmd_dbf;
-       rwlock_t                cmd_dbf_lock;
+       debug_info_t            *erp_dbf;
+       debug_info_t            *hba_dbf;
+       debug_info_t            *san_dbf;          /* debug feature areas */
+       debug_info_t            *scsi_dbf;
+       spinlock_t              erp_dbf_lock;
+       spinlock_t              hba_dbf_lock;
+       spinlock_t              san_dbf_lock;
+       spinlock_t              scsi_dbf_lock;
+       struct zfcp_erp_dbf_record      erp_dbf_buf;
+       struct zfcp_hba_dbf_record      hba_dbf_buf;
+       struct zfcp_san_dbf_record      san_dbf_buf;
+       struct zfcp_scsi_dbf_record     scsi_dbf_buf;
        struct zfcp_adapter_mempool     pool;      /* Adapter memory pools */
        struct qdio_initialize  qdio_init_data;    /* for qdio_establish */
+       struct device           generic_services;  /* directory for WKA ports */
+       struct fc_host_statistics *fc_stats;
+       struct fsf_qtcb_bottom_port *stats_reset_data;
+       unsigned long           stats_reset;
 };
 
 /*
@@ -986,6 +941,7 @@ struct zfcp_adapter {
  */
 struct zfcp_port {
        struct device          sysfs_device;   /* sysfs device */
+       struct fc_rport        *rport;         /* rport of fc transport class */
        struct list_head       list;           /* list of remote ports */
        atomic_t               refcount;       /* reference count */
        wait_queue_head_t      remove_wq;      /* can be used to wait for
@@ -996,13 +952,14 @@ struct zfcp_port {
                                                  list */
        u32                    units;          /* # of logical units in list */
        atomic_t               status;         /* status of this remote port */
-       scsi_id_t              scsi_id;        /* own SCSI ID */
        wwn_t                  wwnn;           /* WWNN if known */
        wwn_t                  wwpn;           /* WWPN */
-       fc_id_t                d_id;           /* D_ID */
+       u32                    d_id;           /* D_ID */
        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.
@@ -1017,19 +974,18 @@ struct zfcp_unit {
                                                  refcount drop to zero */
        struct zfcp_port       *port;          /* remote port of unit */
        atomic_t               status;         /* status of this logical unit */
-       scsi_lun_t             scsi_lun;       /* own SCSI LUN */
+       unsigned int           scsi_lun;       /* own SCSI LUN */
        fcp_lun_t              fcp_lun;        /* own FCP_LUN */
        u32                    handle;         /* handle assigned by FSF */
         struct scsi_device     *device;        /* scsi device struct pointer */
        struct zfcp_erp_action erp_action;     /* pending error recovery */
         atomic_t               erp_counter;
-       atomic_t               scsi_add_work;  /* used to synchronize */
-       wait_queue_head_t      scsi_add_wq;    /* wait for scsi_add_device */
 };
 
 /* FSF request */
 struct zfcp_fsf_req {
        struct list_head       list;           /* list of FSF requests */
+       unsigned long          req_id;         /* unique request ID */
        struct zfcp_adapter    *adapter;       /* adapter request belongs to */
        u8                     sbal_number;    /* nr of SBALs free for use */
        u8                     sbal_first;     /* first SBAL for this request */
@@ -1045,11 +1001,14 @@ struct zfcp_fsf_req {
        u32                    fsf_command;    /* FSF Command copy */
        struct fsf_qtcb        *qtcb;          /* address of associated QTCB */
        u32                    seq_no;         /* Sequence number of request */
-        union zfcp_req_data    data;           /* Info fields of request */ 
+        unsigned long          data;           /* private data of request */ 
+       struct timer_list      timer;          /* used for erp or scsi er */
        struct zfcp_erp_action *erp_action;    /* used if this request is
                                                  issued on behalf of erp */
        mempool_t              *pool;          /* used if request was alloacted
                                                  from emergency pool */
+       unsigned long long     issued;         /* request sent time (STCK) */
+       struct zfcp_unit       *unit;
 };
 
 typedef void zfcp_fsf_req_handler_t(struct zfcp_fsf_req*);
@@ -1057,29 +1016,32 @@ typedef void zfcp_fsf_req_handler_t(struct zfcp_fsf_req*);
 /* driver data */
 struct zfcp_data {
        struct scsi_host_template scsi_host_template;
+       struct scsi_transport_template *scsi_transport_template;
         atomic_t                status;             /* Module status flags */
        struct list_head        adapter_list_head;  /* head of adapter list */
        struct list_head        adapter_remove_lh;  /* head of adapters to be
                                                       removed */
-        rwlock_t                status_read_lock;   /* for status read thread */
-        struct list_head        status_read_receive_head;
-        struct list_head        status_read_send_head;
-        struct semaphore        status_read_sema;
-       wait_queue_head_t       status_read_thread_wqh;
        u32                     adapters;           /* # of adapters in list */
        rwlock_t                config_lock;        /* serialises changes
                                                       to adapter/port/unit
                                                       lists */
        struct semaphore        config_sema;        /* serialises configuration
                                                       changes */
-       struct notifier_block   reboot_notifier;     /* used to register cleanup
-                                                       functions */
        atomic_t                loglevel;            /* current loglevel */
        char                    init_busid[BUS_ID_SIZE];
        wwn_t                   init_wwpn;
        fcp_lun_t               init_fcp_lun;
+       char                    *driver_version;
+       struct kmem_cache               *fsf_req_qtcb_cache;
+       struct kmem_cache               *sr_buffer_cache;
+       struct kmem_cache               *gid_pn_cache;
 };
 
+/**
+ * struct zfcp_sg_list - struct describing a scatter-gather list
+ * @sg: pointer to array of (struct scatterlist)
+ * @count: number of elements in scatter-gather list
+ */
 struct zfcp_sg_list {
        struct scatterlist *sg;
        unsigned int count;
@@ -1093,16 +1055,13 @@ struct zfcp_sg_list {
 #define ZFCP_POOL_DATA_GID_PN_NR       1
 
 /* struct used by memory pools for fsf_requests */
-struct zfcp_fsf_req_pool_element {
+struct zfcp_fsf_req_qtcb {
        struct zfcp_fsf_req fsf_req;
        struct fsf_qtcb qtcb;
 };
 
 /********************** ZFCP SPECIFIC DEFINES ********************************/
 
-#define ZFCP_FSFREQ_CLEANUP_TIMEOUT    HZ/10
-
-#define ZFCP_KNOWN              0x00000001
 #define ZFCP_REQ_AUTO_CLEANUP  0x00000002
 #define ZFCP_WAIT_FOR_SBAL     0x00000004
 #define ZFCP_REQ_NO_QTCB       0x00000008
@@ -1110,9 +1069,6 @@ struct zfcp_fsf_req_pool_element {
 #define ZFCP_SET                0x00000100
 #define ZFCP_CLEAR              0x00000200
 
-#define ZFCP_INTERRUPTIBLE     1
-#define ZFCP_UNINTERRUPTIBLE   0
-
 #ifndef atomic_test_mask
 #define atomic_test_mask(mask, target) \
            ((atomic_read(target) & mask) == mask)
@@ -1123,32 +1079,6 @@ extern void _zfcp_hex_dump(char *, int);
                if (ZFCP_LOG_CHECK(level)) { \
                        _zfcp_hex_dump(addr, count); \
                }
-/*
- * Not yet optimal but useful:
- * Waits until the condition is met or the timeout occurs.
- * The condition may be a function call. This allows to
- * execute some additional instructions in addition
- * to a simple condition check.
- * The timeout is modified on exit and holds the remaining time.
- * Thus it is zero if a timeout ocurred, i.e. the condition was 
- * not met in the specified interval.
- */
-#define __ZFCP_WAIT_EVENT_TIMEOUT(timeout, condition) \
-do { \
-       set_current_state(TASK_UNINTERRUPTIBLE); \
-       while (!(condition) && timeout) \
-               timeout = schedule_timeout(timeout); \
-       current->state = TASK_RUNNING; \
-} while (0);
-
-#define ZFCP_WAIT_EVENT_TIMEOUT(waitqueue, timeout, condition) \
-do { \
-       wait_queue_t entry; \
-       init_waitqueue_entry(&entry, current); \
-       add_wait_queue(&waitqueue, &entry); \
-       __ZFCP_WAIT_EVENT_TIMEOUT(timeout, condition) \
-       remove_wait_queue(&waitqueue, &entry); \
-} while (0);
 
 #define zfcp_get_busid_by_adapter(adapter) (adapter->ccw_device->dev.bus_id)
 #define zfcp_get_busid_by_port(port) (zfcp_get_busid_by_adapter(port->adapter))