X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fs390%2Fscsi%2Fzfcp_def.h;h=32933ed54b8a05dbe3534ac90395bbbf3d1ee283;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=65c89d3358f9453926455108b977fa61f49958ef;hpb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;p=linux-2.6.git diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 65c89d335..32933ed54 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -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 - * Raimund Schroeder - * Aron Zeh - * Wolfgang Taphorn - * Stefan Bader - * Heiko Carstens + * (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 @@ -28,13 +19,9 @@ * 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 @@ -42,40 +29,47 @@ #include #include #include +#include +#include +#include +#include +#include +#include #include #include #include #include #include -#include "../../fc4/fc.h" -#include "zfcp_fsf.h" +#include +#include #include #include #include #include -#include -#include -#include -#include -#ifdef CONFIG_S390_SUPPORT -#include -#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))