11da177e4SLinus Torvalds /* 2553448f6SChristof Schmitt * zfcp device driver 31da177e4SLinus Torvalds * 4553448f6SChristof Schmitt * Global definitions for the zfcp device driver. 51da177e4SLinus Torvalds * 6a2fa0aedSChristof Schmitt * Copyright IBM Corporation 2002, 2009 71da177e4SLinus Torvalds */ 81da177e4SLinus Torvalds 91da177e4SLinus Torvalds #ifndef ZFCP_DEF_H 101da177e4SLinus Torvalds #define ZFCP_DEF_H 111da177e4SLinus Torvalds 121da177e4SLinus Torvalds /*************************** INCLUDES *****************************************/ 131da177e4SLinus Torvalds 141da177e4SLinus Torvalds #include <linux/init.h> 151da177e4SLinus Torvalds #include <linux/moduleparam.h> 161da177e4SLinus Torvalds #include <linux/major.h> 171da177e4SLinus Torvalds #include <linux/blkdev.h> 181da177e4SLinus Torvalds #include <linux/delay.h> 191da177e4SLinus Torvalds #include <linux/timer.h> 20dd52e0eaSHeiko Carstens #include <linux/slab.h> 21dd52e0eaSHeiko Carstens #include <linux/mempool.h> 22dd52e0eaSHeiko Carstens #include <linux/syscalls.h> 23f1346372SFUJITA Tomonori #include <linux/scatterlist.h> 24dd52e0eaSHeiko Carstens #include <linux/ioctl.h> 259d544f2bSSven Schuetz #include <scsi/fc/fc_fs.h> 269d544f2bSSven Schuetz #include <scsi/fc/fc_gs.h> 271da177e4SLinus Torvalds #include <scsi/scsi.h> 281da177e4SLinus Torvalds #include <scsi/scsi_tcq.h> 291da177e4SLinus Torvalds #include <scsi/scsi_cmnd.h> 301da177e4SLinus Torvalds #include <scsi/scsi_device.h> 311da177e4SLinus Torvalds #include <scsi/scsi_host.h> 321da177e4SLinus Torvalds #include <scsi/scsi_transport.h> 331da177e4SLinus Torvalds #include <scsi/scsi_transport_fc.h> 349d544f2bSSven Schuetz #include <scsi/scsi_bsg_fc.h> 351da177e4SLinus Torvalds #include <asm/ccwdev.h> 361da177e4SLinus Torvalds #include <asm/qdio.h> 371da177e4SLinus Torvalds #include <asm/debug.h> 381da177e4SLinus Torvalds #include <asm/ebcdic.h> 39bd43a42bSChristof Schmitt #include <asm/sysinfo.h> 40dd52e0eaSHeiko Carstens #include "zfcp_fsf.h" 411da177e4SLinus Torvalds 421da177e4SLinus Torvalds /********************* GENERAL DEFINES *********************************/ 431da177e4SLinus Torvalds 4406506d00SAndreas Herrmann #define REQUEST_LIST_SIZE 128 4506506d00SAndreas Herrmann 461da177e4SLinus Torvalds /********************* SCSI SPECIFIC DEFINES *********************************/ 47f6c0e7a7SAndreas Herrmann #define ZFCP_SCSI_ER_TIMEOUT (10*HZ) 481da177e4SLinus Torvalds 491da177e4SLinus Torvalds /********************* CIO/QDIO SPECIFIC DEFINES *****************************/ 501da177e4SLinus Torvalds 511da177e4SLinus Torvalds /* DMQ bug workaround: don't use last SBALE */ 521da177e4SLinus Torvalds #define ZFCP_MAX_SBALES_PER_SBAL (QDIO_MAX_ELEMENTS_PER_BUFFER - 1) 531da177e4SLinus Torvalds 541da177e4SLinus Torvalds /* index of last SBALE (with respect to DMQ bug workaround) */ 551da177e4SLinus Torvalds #define ZFCP_LAST_SBALE_PER_SBAL (ZFCP_MAX_SBALES_PER_SBAL - 1) 561da177e4SLinus Torvalds 571da177e4SLinus Torvalds /* max. number of (data buffer) SBALEs in largest SBAL chain */ 581da177e4SLinus Torvalds #define ZFCP_MAX_SBALES_PER_REQ \ 59c41f8cbdSSwen Schillig (FSF_MAX_SBALS_PER_REQ * ZFCP_MAX_SBALES_PER_SBAL - 2) 601da177e4SLinus Torvalds /* request ID + QTCB in SBALE 0 + 1 of first SBAL in chain */ 611da177e4SLinus Torvalds 628d1a0060SSwen Schillig #define ZFCP_MAX_SECTORS (ZFCP_MAX_SBALES_PER_REQ * 8) 638d1a0060SSwen Schillig /* max. number of (data buffer) SBALEs in largest SBAL chain 648d1a0060SSwen Schillig multiplied with number of sectors per 4k block */ 658d1a0060SSwen Schillig 661da177e4SLinus Torvalds /********************* FSF SPECIFIC DEFINES *********************************/ 671da177e4SLinus Torvalds 681da177e4SLinus Torvalds /* ATTENTION: value must not be used by hardware */ 691da177e4SLinus Torvalds #define FSF_QTCB_UNSOLICITED_STATUS 0x6305 7022753fa5SAndreas Herrmann 711da177e4SLinus Torvalds /* timeout value for "default timer" for fsf requests */ 722abbe866SAndreas Herrmann #define ZFCP_FSF_REQUEST_TIMEOUT (60*HZ) 731da177e4SLinus Torvalds 741da177e4SLinus Torvalds /*************** FIBRE CHANNEL PROTOCOL SPECIFIC DEFINES ********************/ 751da177e4SLinus Torvalds 761da177e4SLinus Torvalds /* task attribute values in FCP-2 FCP_CMND IU */ 771da177e4SLinus Torvalds #define SIMPLE_Q 0 781da177e4SLinus Torvalds #define HEAD_OF_Q 1 791da177e4SLinus Torvalds #define ORDERED_Q 2 801da177e4SLinus Torvalds #define ACA_Q 4 811da177e4SLinus Torvalds #define UNTAGGED 5 821da177e4SLinus Torvalds 831da177e4SLinus Torvalds /* task management flags in FCP-2 FCP_CMND IU */ 841da177e4SLinus Torvalds #define FCP_CLEAR_ACA 0x40 851da177e4SLinus Torvalds #define FCP_TARGET_RESET 0x20 861da177e4SLinus Torvalds #define FCP_LOGICAL_UNIT_RESET 0x10 871da177e4SLinus Torvalds #define FCP_CLEAR_TASK_SET 0x04 881da177e4SLinus Torvalds #define FCP_ABORT_TASK_SET 0x02 891da177e4SLinus Torvalds 901da177e4SLinus Torvalds #define FCP_CDB_LENGTH 16 911da177e4SLinus Torvalds 921da177e4SLinus Torvalds #define ZFCP_DID_MASK 0x00FFFFFF 931da177e4SLinus Torvalds 941da177e4SLinus Torvalds /* FCP(-2) FCP_CMND IU */ 951da177e4SLinus Torvalds struct fcp_cmnd_iu { 967ba58c9cSSwen Schillig u64 fcp_lun; /* FCP logical unit number */ 971da177e4SLinus Torvalds u8 crn; /* command reference number */ 981da177e4SLinus Torvalds u8 reserved0:5; /* reserved */ 991da177e4SLinus Torvalds u8 task_attribute:3; /* task attribute */ 1001da177e4SLinus Torvalds u8 task_management_flags; /* task management flags */ 1011da177e4SLinus Torvalds u8 add_fcp_cdb_length:6; /* additional FCP_CDB length */ 1021da177e4SLinus Torvalds u8 rddata:1; /* read data */ 1031da177e4SLinus Torvalds u8 wddata:1; /* write data */ 1041da177e4SLinus Torvalds u8 fcp_cdb[FCP_CDB_LENGTH]; 1051da177e4SLinus Torvalds } __attribute__((packed)); 1061da177e4SLinus Torvalds 1071da177e4SLinus Torvalds /* FCP(-2) FCP_RSP IU */ 1081da177e4SLinus Torvalds struct fcp_rsp_iu { 1091da177e4SLinus Torvalds u8 reserved0[10]; 1101da177e4SLinus Torvalds union { 1111da177e4SLinus Torvalds struct { 1121da177e4SLinus Torvalds u8 reserved1:3; 1131da177e4SLinus Torvalds u8 fcp_conf_req:1; 1141da177e4SLinus Torvalds u8 fcp_resid_under:1; 1151da177e4SLinus Torvalds u8 fcp_resid_over:1; 1161da177e4SLinus Torvalds u8 fcp_sns_len_valid:1; 1171da177e4SLinus Torvalds u8 fcp_rsp_len_valid:1; 1181da177e4SLinus Torvalds } bits; 1191da177e4SLinus Torvalds u8 value; 1201da177e4SLinus Torvalds } validity; 1211da177e4SLinus Torvalds u8 scsi_status; 1221da177e4SLinus Torvalds u32 fcp_resid; 1231da177e4SLinus Torvalds u32 fcp_sns_len; 1241da177e4SLinus Torvalds u32 fcp_rsp_len; 1251da177e4SLinus Torvalds } __attribute__((packed)); 1261da177e4SLinus Torvalds 1271da177e4SLinus Torvalds 1281da177e4SLinus Torvalds #define RSP_CODE_GOOD 0 1291da177e4SLinus Torvalds #define RSP_CODE_LENGTH_MISMATCH 1 1301da177e4SLinus Torvalds #define RSP_CODE_FIELD_INVALID 2 1311da177e4SLinus Torvalds #define RSP_CODE_RO_MISMATCH 3 1321da177e4SLinus Torvalds #define RSP_CODE_TASKMAN_UNSUPP 4 1331da177e4SLinus Torvalds #define RSP_CODE_TASKMAN_FAILED 5 1341da177e4SLinus Torvalds 1351da177e4SLinus Torvalds /* see fc-fs */ 13624073b47SChristof Schmitt #define LS_RSCN 0x61 13724073b47SChristof Schmitt #define LS_LOGO 0x05 13824073b47SChristof Schmitt #define LS_PLOGI 0x03 1391da177e4SLinus Torvalds 1401da177e4SLinus Torvalds struct fcp_rscn_head { 1411da177e4SLinus Torvalds u8 command; 1421da177e4SLinus Torvalds u8 page_length; /* always 0x04 */ 1431da177e4SLinus Torvalds u16 payload_len; 1441da177e4SLinus Torvalds } __attribute__((packed)); 1451da177e4SLinus Torvalds 1461da177e4SLinus Torvalds struct fcp_rscn_element { 1471da177e4SLinus Torvalds u8 reserved:2; 1481da177e4SLinus Torvalds u8 event_qual:4; 1491da177e4SLinus Torvalds u8 addr_format:2; 1501da177e4SLinus Torvalds u32 nport_did:24; 1511da177e4SLinus Torvalds } __attribute__((packed)); 1521da177e4SLinus Torvalds 1531da177e4SLinus Torvalds /* see fc-ph */ 1541da177e4SLinus Torvalds struct fcp_logo { 1551da177e4SLinus Torvalds u32 command; 1561da177e4SLinus Torvalds u32 nport_did; 1577ba58c9cSSwen Schillig u64 nport_wwpn; 1581da177e4SLinus Torvalds } __attribute__((packed)); 1591da177e4SLinus Torvalds 1601da177e4SLinus Torvalds /* 1611da177e4SLinus Torvalds * FC-FS stuff 1621da177e4SLinus Torvalds */ 1631da177e4SLinus Torvalds #define R_A_TOV 10 /* seconds */ 1641da177e4SLinus Torvalds 1651da177e4SLinus Torvalds #define ZFCP_LS_RLS 0x0f 1661da177e4SLinus Torvalds #define ZFCP_LS_ADISC 0x52 1671da177e4SLinus Torvalds #define ZFCP_LS_RPS 0x56 1681da177e4SLinus Torvalds #define ZFCP_LS_RSCN 0x61 1691da177e4SLinus Torvalds #define ZFCP_LS_RNID 0x78 1701da177e4SLinus Torvalds 1711da177e4SLinus Torvalds struct zfcp_ls_adisc { 1721da177e4SLinus Torvalds u8 code; 1731da177e4SLinus Torvalds u8 field[3]; 1741da177e4SLinus Torvalds u32 hard_nport_id; 1751da177e4SLinus Torvalds u64 wwpn; 1761da177e4SLinus Torvalds u64 wwnn; 1771da177e4SLinus Torvalds u32 nport_id; 1781da177e4SLinus Torvalds } __attribute__ ((packed)); 1791da177e4SLinus Torvalds 1801da177e4SLinus Torvalds /* 1811da177e4SLinus Torvalds * FC-GS-2 stuff 1821da177e4SLinus Torvalds */ 1831da177e4SLinus Torvalds #define ZFCP_CT_REVISION 0x01 1841da177e4SLinus Torvalds #define ZFCP_CT_DIRECTORY_SERVICE 0xFC 1851da177e4SLinus Torvalds #define ZFCP_CT_NAME_SERVER 0x02 1861da177e4SLinus Torvalds #define ZFCP_CT_SYNCHRONOUS 0x00 187cc8c2829SSwen Schillig #define ZFCP_CT_SCSI_FCP 0x08 188cc8c2829SSwen Schillig #define ZFCP_CT_UNABLE_TO_PERFORM_CMD 0x09 1891da177e4SLinus Torvalds #define ZFCP_CT_GID_PN 0x0121 190cc8c2829SSwen Schillig #define ZFCP_CT_GPN_FT 0x0172 1911da177e4SLinus Torvalds #define ZFCP_CT_ACCEPT 0x8002 1921da177e4SLinus Torvalds #define ZFCP_CT_REJECT 0x8001 1931da177e4SLinus Torvalds 1941da177e4SLinus Torvalds /* 1951da177e4SLinus Torvalds * FC-GS-4 stuff 1961da177e4SLinus Torvalds */ 1971da177e4SLinus Torvalds #define ZFCP_CT_TIMEOUT (3 * R_A_TOV) 1981da177e4SLinus Torvalds 1991da177e4SLinus Torvalds /*************** ADAPTER/PORT/UNIT AND FSF_REQ STATUS FLAGS ******************/ 2001da177e4SLinus Torvalds 2011da177e4SLinus Torvalds /* 2021da177e4SLinus Torvalds * Note, the leftmost status byte is common among adapter, port 2031da177e4SLinus Torvalds * and unit 2041da177e4SLinus Torvalds */ 2051da177e4SLinus Torvalds #define ZFCP_COMMON_FLAGS 0xfff00000 2061da177e4SLinus Torvalds 2071da177e4SLinus Torvalds /* common status bits */ 2081da177e4SLinus Torvalds #define ZFCP_STATUS_COMMON_REMOVE 0x80000000 2091da177e4SLinus Torvalds #define ZFCP_STATUS_COMMON_RUNNING 0x40000000 2101da177e4SLinus Torvalds #define ZFCP_STATUS_COMMON_ERP_FAILED 0x20000000 2111da177e4SLinus Torvalds #define ZFCP_STATUS_COMMON_UNBLOCKED 0x10000000 2121da177e4SLinus Torvalds #define ZFCP_STATUS_COMMON_OPEN 0x04000000 2131da177e4SLinus Torvalds #define ZFCP_STATUS_COMMON_ERP_INUSE 0x01000000 2141da177e4SLinus Torvalds #define ZFCP_STATUS_COMMON_ACCESS_DENIED 0x00800000 215d736a27bSAndreas Herrmann #define ZFCP_STATUS_COMMON_ACCESS_BOXED 0x00400000 216cc8c2829SSwen Schillig #define ZFCP_STATUS_COMMON_NOESC 0x00200000 2171da177e4SLinus Torvalds 2181da177e4SLinus Torvalds /* adapter status */ 2191da177e4SLinus Torvalds #define ZFCP_STATUS_ADAPTER_QDIOUP 0x00000002 2201da177e4SLinus Torvalds #define ZFCP_STATUS_ADAPTER_XCONFIG_OK 0x00000008 2211da177e4SLinus Torvalds #define ZFCP_STATUS_ADAPTER_HOST_CON_INIT 0x00000010 2221da177e4SLinus Torvalds #define ZFCP_STATUS_ADAPTER_ERP_PENDING 0x00000100 2231da177e4SLinus Torvalds #define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED 0x00000200 2241da177e4SLinus Torvalds 2251da177e4SLinus Torvalds /* FC-PH/FC-GS well-known address identifiers for generic services */ 2265ab944f9SSwen Schillig #define ZFCP_DID_WKA 0xFFFFF0 2271da177e4SLinus Torvalds 2281da177e4SLinus Torvalds /* remote port status */ 2291da177e4SLinus Torvalds #define ZFCP_STATUS_PORT_PHYS_OPEN 0x00000001 23014e242eaSChristof Schmitt #define ZFCP_STATUS_PORT_LINK_TEST 0x00000002 2311da177e4SLinus Torvalds 2325ab944f9SSwen Schillig /* well known address (WKA) port status*/ 2335ab944f9SSwen Schillig enum zfcp_wka_status { 2345ab944f9SSwen Schillig ZFCP_WKA_PORT_OFFLINE, 2355ab944f9SSwen Schillig ZFCP_WKA_PORT_CLOSING, 2365ab944f9SSwen Schillig ZFCP_WKA_PORT_OPENING, 2375ab944f9SSwen Schillig ZFCP_WKA_PORT_ONLINE, 2385ab944f9SSwen Schillig }; 2391da177e4SLinus Torvalds 2401da177e4SLinus Torvalds /* logical unit status */ 2411da177e4SLinus Torvalds #define ZFCP_STATUS_UNIT_SHARED 0x00000004 2421da177e4SLinus Torvalds #define ZFCP_STATUS_UNIT_READONLY 0x00000008 2431da177e4SLinus Torvalds 2441da177e4SLinus Torvalds /* FSF request status (this does not have a common part) */ 2451da177e4SLinus Torvalds #define ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT 0x00000002 2461da177e4SLinus Torvalds #define ZFCP_STATUS_FSFREQ_ERROR 0x00000008 2471da177e4SLinus Torvalds #define ZFCP_STATUS_FSFREQ_CLEANUP 0x00000010 2481da177e4SLinus Torvalds #define ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED 0x00000040 2491da177e4SLinus Torvalds #define ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED 0x00000080 2501da177e4SLinus Torvalds #define ZFCP_STATUS_FSFREQ_ABORTED 0x00000100 2511da177e4SLinus Torvalds #define ZFCP_STATUS_FSFREQ_TMFUNCFAILED 0x00000200 2521da177e4SLinus Torvalds #define ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP 0x00000400 2531da177e4SLinus Torvalds #define ZFCP_STATUS_FSFREQ_RETRY 0x00000800 2541da177e4SLinus Torvalds #define ZFCP_STATUS_FSFREQ_DISMISSED 0x00001000 2551da177e4SLinus Torvalds 2561da177e4SLinus Torvalds /************************* STRUCTURE DEFINITIONS *****************************/ 2571da177e4SLinus Torvalds 2581da177e4SLinus Torvalds struct zfcp_fsf_req; 2591da177e4SLinus Torvalds 2601da177e4SLinus Torvalds /* holds various memory pools of an adapter */ 2611da177e4SLinus Torvalds struct zfcp_adapter_mempool { 262a4623c46SSwen Schillig mempool_t *erp_req; 263799b76d0SChristof Schmitt mempool_t *gid_pn_req; 264a4623c46SSwen Schillig mempool_t *scsi_req; 265a4623c46SSwen Schillig mempool_t *scsi_abort; 266a4623c46SSwen Schillig mempool_t *status_read_req; 267a4623c46SSwen Schillig mempool_t *status_read_data; 268a4623c46SSwen Schillig mempool_t *gid_pn_data; 269a4623c46SSwen Schillig mempool_t *qtcb_pool; 2701da177e4SLinus Torvalds }; 2711da177e4SLinus Torvalds 2721da177e4SLinus Torvalds /* 2731da177e4SLinus Torvalds * header for CT_IU 2741da177e4SLinus Torvalds */ 2751da177e4SLinus Torvalds struct ct_hdr { 2761da177e4SLinus Torvalds u8 revision; // 0x01 2771da177e4SLinus Torvalds u8 in_id[3]; // 0x00 2781da177e4SLinus Torvalds u8 gs_type; // 0xFC Directory Service 2791da177e4SLinus Torvalds u8 gs_subtype; // 0x02 Name Server 2801da177e4SLinus Torvalds u8 options; // 0x00 single bidirectional exchange 2811da177e4SLinus Torvalds u8 reserved0; 2821da177e4SLinus Torvalds u16 cmd_rsp_code; // 0x0121 GID_PN, or 0x0100 GA_NXT 2831da177e4SLinus Torvalds u16 max_res_size; // <= (4096 - 16) / 4 2841da177e4SLinus Torvalds u8 reserved1; 2851da177e4SLinus Torvalds u8 reason_code; 2861da177e4SLinus Torvalds u8 reason_code_expl; 2871da177e4SLinus Torvalds u8 vendor_unique; 2881da177e4SLinus Torvalds } __attribute__ ((packed)); 2891da177e4SLinus Torvalds 2901da177e4SLinus Torvalds /* nameserver request CT_IU -- for requests where 2911da177e4SLinus Torvalds * a port name is required */ 2921da177e4SLinus Torvalds struct ct_iu_gid_pn_req { 2931da177e4SLinus Torvalds struct ct_hdr header; 2947ba58c9cSSwen Schillig u64 wwpn; 2951da177e4SLinus Torvalds } __attribute__ ((packed)); 2961da177e4SLinus Torvalds 2971da177e4SLinus Torvalds /* FS_ACC IU and data unit for GID_PN nameserver request */ 2981da177e4SLinus Torvalds struct ct_iu_gid_pn_resp { 2991da177e4SLinus Torvalds struct ct_hdr header; 30013e1e1f0SAndreas Herrmann u32 d_id; 3011da177e4SLinus Torvalds } __attribute__ ((packed)); 3021da177e4SLinus Torvalds 303a4623c46SSwen Schillig struct ct_iu_gpn_ft_req { 304a4623c46SSwen Schillig struct ct_hdr header; 305a4623c46SSwen Schillig u8 flags; 306a4623c46SSwen Schillig u8 domain_id_scope; 307a4623c46SSwen Schillig u8 area_id_scope; 308a4623c46SSwen Schillig u8 fc4_type; 309a4623c46SSwen Schillig } __attribute__ ((packed)); 310a4623c46SSwen Schillig 311a4623c46SSwen Schillig 3121da177e4SLinus Torvalds /** 3131da177e4SLinus Torvalds * struct zfcp_send_ct - used to pass parameters to function zfcp_fsf_send_ct 3145ab944f9SSwen Schillig * @wka_port: port where the request is sent to 3151da177e4SLinus Torvalds * @req: scatter-gather list for request 3161da177e4SLinus Torvalds * @resp: scatter-gather list for response 3171da177e4SLinus Torvalds * @handler: handler function (called for response to the request) 3181da177e4SLinus Torvalds * @handler_data: data passed to handler function 3191da177e4SLinus Torvalds * @completion: completion for synchronization purposes 3201da177e4SLinus Torvalds * @status: used to pass error status to calling function 3211da177e4SLinus Torvalds */ 3221da177e4SLinus Torvalds struct zfcp_send_ct { 3235ab944f9SSwen Schillig struct zfcp_wka_port *wka_port; 3241da177e4SLinus Torvalds struct scatterlist *req; 3251da177e4SLinus Torvalds struct scatterlist *resp; 3267ba58c9cSSwen Schillig void (*handler)(unsigned long); 3271da177e4SLinus Torvalds unsigned long handler_data; 3281da177e4SLinus Torvalds struct completion *completion; 3291da177e4SLinus Torvalds int status; 3301da177e4SLinus Torvalds }; 3311da177e4SLinus Torvalds 3321da177e4SLinus Torvalds /* used for name server requests in error recovery */ 3331da177e4SLinus Torvalds struct zfcp_gid_pn_data { 3341da177e4SLinus Torvalds struct zfcp_send_ct ct; 3351da177e4SLinus Torvalds struct scatterlist req; 3361da177e4SLinus Torvalds struct scatterlist resp; 3371da177e4SLinus Torvalds struct ct_iu_gid_pn_req ct_iu_req; 3381da177e4SLinus Torvalds struct ct_iu_gid_pn_resp ct_iu_resp; 3391da177e4SLinus Torvalds struct zfcp_port *port; 3401da177e4SLinus Torvalds }; 3411da177e4SLinus Torvalds 3421da177e4SLinus Torvalds /** 3431da177e4SLinus Torvalds * struct zfcp_send_els - used to pass parameters to function zfcp_fsf_send_els 3441da177e4SLinus Torvalds * @adapter: adapter where request is sent from 34564b29a13SAndreas Herrmann * @port: port where ELS is destinated (port reference count has to be increased) 3461da177e4SLinus Torvalds * @d_id: destiniation id of port where request is sent to 3471da177e4SLinus Torvalds * @req: scatter-gather list for request 3481da177e4SLinus Torvalds * @resp: scatter-gather list for response 3491da177e4SLinus Torvalds * @handler: handler function (called for response to the request) 3501da177e4SLinus Torvalds * @handler_data: data passed to handler function 3511da177e4SLinus Torvalds * @completion: completion for synchronization purposes 3521da177e4SLinus Torvalds * @ls_code: hex code of ELS command 3531da177e4SLinus Torvalds * @status: used to pass error status to calling function 3541da177e4SLinus Torvalds */ 3551da177e4SLinus Torvalds struct zfcp_send_els { 3561da177e4SLinus Torvalds struct zfcp_adapter *adapter; 35764b29a13SAndreas Herrmann struct zfcp_port *port; 35813e1e1f0SAndreas Herrmann u32 d_id; 3591da177e4SLinus Torvalds struct scatterlist *req; 3601da177e4SLinus Torvalds struct scatterlist *resp; 3617ba58c9cSSwen Schillig void (*handler)(unsigned long); 3621da177e4SLinus Torvalds unsigned long handler_data; 3631da177e4SLinus Torvalds struct completion *completion; 3641da177e4SLinus Torvalds int ls_code; 3651da177e4SLinus Torvalds int status; 3661da177e4SLinus Torvalds }; 3671da177e4SLinus Torvalds 3685ab944f9SSwen Schillig struct zfcp_wka_port { 3695ab944f9SSwen Schillig struct zfcp_adapter *adapter; 3705ab944f9SSwen Schillig wait_queue_head_t completion_wq; 3715ab944f9SSwen Schillig enum zfcp_wka_status status; 3725ab944f9SSwen Schillig atomic_t refcount; 3735ab944f9SSwen Schillig u32 d_id; 3745ab944f9SSwen Schillig u32 handle; 3755ab944f9SSwen Schillig struct mutex mutex; 3765ab944f9SSwen Schillig struct delayed_work work; 3775ab944f9SSwen Schillig }; 3785ab944f9SSwen Schillig 3799d544f2bSSven Schuetz struct zfcp_wka_ports { 3809d544f2bSSven Schuetz struct zfcp_wka_port ms; /* management service */ 3819d544f2bSSven Schuetz struct zfcp_wka_port ts; /* time service */ 3829d544f2bSSven Schuetz struct zfcp_wka_port ds; /* directory service */ 3839d544f2bSSven Schuetz struct zfcp_wka_port as; /* alias service */ 3849d544f2bSSven Schuetz struct zfcp_wka_port ks; /* key distribution service */ 3859d544f2bSSven Schuetz }; 3869d544f2bSSven Schuetz 3871da177e4SLinus Torvalds struct zfcp_qdio_queue { 3880406289eSChristof Schmitt struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q]; 3890406289eSChristof Schmitt u8 first; /* index of next free bfr in queue */ 3900406289eSChristof Schmitt atomic_t count; /* number of free buffers in queue */ 3911da177e4SLinus Torvalds }; 3921da177e4SLinus Torvalds 3931da177e4SLinus Torvalds struct zfcp_erp_action { 3941da177e4SLinus Torvalds struct list_head list; 3951da177e4SLinus Torvalds int action; /* requested action code */ 3961da177e4SLinus Torvalds struct zfcp_adapter *adapter; /* device which should be recovered */ 3971da177e4SLinus Torvalds struct zfcp_port *port; 3981da177e4SLinus Torvalds struct zfcp_unit *unit; 39944cc76f2SSwen Schillig u32 status; /* recovery status */ 4001da177e4SLinus Torvalds u32 step; /* active step of this erp action */ 4011da177e4SLinus Torvalds struct zfcp_fsf_req *fsf_req; /* fsf request currently pending 4021da177e4SLinus Torvalds for this action */ 4031da177e4SLinus Torvalds struct timer_list timer; 4041da177e4SLinus Torvalds }; 4051da177e4SLinus Torvalds 406c9615858SChristof Schmitt struct fsf_latency_record { 407c9615858SChristof Schmitt u32 min; 408c9615858SChristof Schmitt u32 max; 409c9615858SChristof Schmitt u64 sum; 410c9615858SChristof Schmitt }; 411c9615858SChristof Schmitt 412c9615858SChristof Schmitt struct latency_cont { 413c9615858SChristof Schmitt struct fsf_latency_record channel; 414c9615858SChristof Schmitt struct fsf_latency_record fabric; 415c9615858SChristof Schmitt u64 counter; 416c9615858SChristof Schmitt }; 417c9615858SChristof Schmitt 418c9615858SChristof Schmitt struct zfcp_latencies { 419c9615858SChristof Schmitt struct latency_cont read; 420c9615858SChristof Schmitt struct latency_cont write; 421c9615858SChristof Schmitt struct latency_cont cmd; 422c9615858SChristof Schmitt spinlock_t lock; 423c9615858SChristof Schmitt }; 4241da177e4SLinus Torvalds 425564e1c86SSwen Schillig /** struct zfcp_qdio - basic QDIO data structure 426564e1c86SSwen Schillig * @resp_q: response queue 427564e1c86SSwen Schillig * @req_q: request queue 428564e1c86SSwen Schillig * @stat_lock: lock to protect req_q_util and req_q_time 429564e1c86SSwen Schillig * @req_q_lock; lock to serialize access to request queue 430564e1c86SSwen Schillig * @req_q_time: time of last fill level change 431564e1c86SSwen Schillig * @req_q_util: used for accounting 432564e1c86SSwen Schillig * @req_q_full: queue full incidents 433564e1c86SSwen Schillig * @req_q_wq: used to wait for SBAL availability 434564e1c86SSwen Schillig * @adapter: adapter used in conjunction with this QDIO structure 435564e1c86SSwen Schillig */ 436564e1c86SSwen Schillig struct zfcp_qdio { 437564e1c86SSwen Schillig struct zfcp_qdio_queue resp_q; 438564e1c86SSwen Schillig struct zfcp_qdio_queue req_q; 439564e1c86SSwen Schillig spinlock_t stat_lock; 440564e1c86SSwen Schillig spinlock_t req_q_lock; 44141e05a12SHeiko Carstens unsigned long long req_q_time; 442564e1c86SSwen Schillig u64 req_q_util; 443564e1c86SSwen Schillig atomic_t req_q_full; 444564e1c86SSwen Schillig wait_queue_head_t req_q_wq; 445564e1c86SSwen Schillig struct zfcp_adapter *adapter; 446564e1c86SSwen Schillig }; 447564e1c86SSwen Schillig 4481da177e4SLinus Torvalds struct zfcp_adapter { 4491da177e4SLinus Torvalds atomic_t refcount; /* reference count */ 4501da177e4SLinus Torvalds wait_queue_head_t remove_wq; /* can be used to wait for 4511da177e4SLinus Torvalds refcount drop to zero */ 4527ba58c9cSSwen Schillig u64 peer_wwnn; /* P2P peer WWNN */ 4537ba58c9cSSwen Schillig u64 peer_wwpn; /* P2P peer WWPN */ 45413e1e1f0SAndreas Herrmann u32 peer_d_id; /* P2P peer D_ID */ 4551da177e4SLinus Torvalds struct ccw_device *ccw_device; /* S/390 ccw device */ 456564e1c86SSwen Schillig struct zfcp_qdio *qdio; 4571da177e4SLinus Torvalds u32 hydra_version; /* Hydra version */ 4581da177e4SLinus Torvalds u32 fsf_lic_version; 459aef4a983SMaxim Shchetynin u32 adapter_features; /* FCP channel features */ 460aef4a983SMaxim Shchetynin u32 connection_features; /* host connection features */ 4611da177e4SLinus Torvalds u32 hardware_version; /* of FCP channel */ 462c9615858SChristof Schmitt u16 timer_ticks; /* time int for a tick */ 4631da177e4SLinus Torvalds struct Scsi_Host *scsi_host; /* Pointer to mid-layer */ 4641da177e4SLinus Torvalds struct list_head port_list_head; /* remote port list */ 465fea9d6c7SVolker Sameske unsigned long req_no; /* unique FSF req number */ 466fea9d6c7SVolker Sameske struct list_head *req_list; /* list of pending reqs */ 467fea9d6c7SVolker Sameske spinlock_t req_list_lock; /* request list lock */ 4681da177e4SLinus Torvalds u32 fsf_req_seq_no; /* FSF cmnd seq number */ 4691da177e4SLinus Torvalds rwlock_t abort_lock; /* Protects against SCSI 4701da177e4SLinus Torvalds stack abort/command 4711da177e4SLinus Torvalds completion races */ 472d26ab06eSSwen Schillig atomic_t stat_miss; /* # missing status reads*/ 473d26ab06eSSwen Schillig struct work_struct stat_work; 4741da177e4SLinus Torvalds atomic_t status; /* status of this adapter */ 4751da177e4SLinus Torvalds struct list_head erp_ready_head; /* error recovery for this 4761da177e4SLinus Torvalds adapter/devices */ 477347c6a96SChristof Schmitt wait_queue_head_t erp_ready_wq; 4781da177e4SLinus Torvalds struct list_head erp_running_head; 4791da177e4SLinus Torvalds rwlock_t erp_lock; 4801da177e4SLinus Torvalds wait_queue_head_t erp_done_wqh; 4811da177e4SLinus Torvalds struct zfcp_erp_action erp_action; /* pending error recovery */ 4821da177e4SLinus Torvalds atomic_t erp_counter; 4831da177e4SLinus Torvalds u32 erp_total_count; /* total nr of enqueued erp 4841da177e4SLinus Torvalds actions */ 4851da177e4SLinus Torvalds u32 erp_low_mem_count; /* nr of erp actions waiting 4861da177e4SLinus Torvalds for memory */ 487347c6a96SChristof Schmitt struct task_struct *erp_thread; 4889d544f2bSSven Schuetz struct zfcp_wka_ports *gs; /* generic services */ 489d46f384aSChristof Schmitt struct zfcp_dbf *dbf; /* debug traces */ 4901da177e4SLinus Torvalds struct zfcp_adapter_mempool pool; /* Adapter memory pools */ 491f6cd94b1SAndreas Herrmann struct fc_host_statistics *fc_stats; 492f6cd94b1SAndreas Herrmann struct fsf_qtcb_bottom_port *stats_reset_data; 493f6cd94b1SAndreas Herrmann unsigned long stats_reset; 494cc8c2829SSwen Schillig struct work_struct scan_work; 495bd43a42bSChristof Schmitt struct service_level service_level; 4964544683aSSwen Schillig struct workqueue_struct *work_queue; 4971da177e4SLinus Torvalds }; 4981da177e4SLinus Torvalds 4991da177e4SLinus Torvalds struct zfcp_port { 5001da177e4SLinus Torvalds struct device sysfs_device; /* sysfs device */ 5013859f6a2SAndreas Herrmann struct fc_rport *rport; /* rport of fc transport class */ 5021da177e4SLinus Torvalds struct list_head list; /* list of remote ports */ 5031da177e4SLinus Torvalds atomic_t refcount; /* reference count */ 5041da177e4SLinus Torvalds wait_queue_head_t remove_wq; /* can be used to wait for 5051da177e4SLinus Torvalds refcount drop to zero */ 5061da177e4SLinus Torvalds struct zfcp_adapter *adapter; /* adapter used to access port */ 5071da177e4SLinus Torvalds struct list_head unit_list_head; /* head of logical unit list */ 5081da177e4SLinus Torvalds atomic_t status; /* status of this remote port */ 5097ba58c9cSSwen Schillig u64 wwnn; /* WWNN if known */ 5107ba58c9cSSwen Schillig u64 wwpn; /* WWPN */ 51113e1e1f0SAndreas Herrmann u32 d_id; /* D_ID */ 5121da177e4SLinus Torvalds u32 handle; /* handle assigned by FSF */ 5131da177e4SLinus Torvalds struct zfcp_erp_action erp_action; /* pending error recovery */ 5141da177e4SLinus Torvalds atomic_t erp_counter; 51575bfc283SRalph Wuerthner u32 maxframe_size; 51675bfc283SRalph Wuerthner u32 supported_classes; 5175ab944f9SSwen Schillig struct work_struct gid_pn_work; 5188fdf30d5SChristof Schmitt struct work_struct test_link_work; 519a2fa0aedSChristof Schmitt struct work_struct rport_work; 520a2fa0aedSChristof Schmitt enum { RPORT_NONE, RPORT_ADD, RPORT_DEL } rport_task; 5211da177e4SLinus Torvalds }; 5221da177e4SLinus Torvalds 5231da177e4SLinus Torvalds struct zfcp_unit { 5241da177e4SLinus Torvalds struct device sysfs_device; /* sysfs device */ 5251da177e4SLinus Torvalds struct list_head list; /* list of logical units */ 5261da177e4SLinus Torvalds atomic_t refcount; /* reference count */ 5271da177e4SLinus Torvalds wait_queue_head_t remove_wq; /* can be used to wait for 5281da177e4SLinus Torvalds refcount drop to zero */ 5291da177e4SLinus Torvalds struct zfcp_port *port; /* remote port of unit */ 5301da177e4SLinus Torvalds atomic_t status; /* status of this logical unit */ 5317ba58c9cSSwen Schillig u64 fcp_lun; /* own FCP_LUN */ 5321da177e4SLinus Torvalds u32 handle; /* handle assigned by FSF */ 5331da177e4SLinus Torvalds struct scsi_device *device; /* scsi device struct pointer */ 5341da177e4SLinus Torvalds struct zfcp_erp_action erp_action; /* pending error recovery */ 5351da177e4SLinus Torvalds atomic_t erp_counter; 536c9615858SChristof Schmitt struct zfcp_latencies latencies; 53792d5193bSSwen Schillig struct work_struct scsi_work; 5381da177e4SLinus Torvalds }; 5391da177e4SLinus Torvalds 54042428f74SSwen Schillig /** 54142428f74SSwen Schillig * struct zfcp_queue_req - queue related values for a request 54242428f74SSwen Schillig * @sbal_number: number of free SBALs 54342428f74SSwen Schillig * @sbal_first: first SBAL for this request 54442428f74SSwen Schillig * @sbal_last: last SBAL for this request 54542428f74SSwen Schillig * @sbal_limit: last possible SBAL for this request 54642428f74SSwen Schillig * @sbale_curr: current SBALE at creation of this request 54742428f74SSwen Schillig * @sbal_response: SBAL used in interrupt 54842428f74SSwen Schillig * @qdio_outb_usage: usage of outbound queue 54942428f74SSwen Schillig * @qdio_inb_usage: usage of inbound queue 55042428f74SSwen Schillig */ 55142428f74SSwen Schillig struct zfcp_queue_req { 55242428f74SSwen Schillig u8 sbal_number; 55342428f74SSwen Schillig u8 sbal_first; 55442428f74SSwen Schillig u8 sbal_last; 55542428f74SSwen Schillig u8 sbal_limit; 55642428f74SSwen Schillig u8 sbale_curr; 55742428f74SSwen Schillig u8 sbal_response; 55842428f74SSwen Schillig u16 qdio_outb_usage; 55942428f74SSwen Schillig u16 qdio_inb_usage; 56042428f74SSwen Schillig }; 56142428f74SSwen Schillig 56242428f74SSwen Schillig /** 56342428f74SSwen Schillig * struct zfcp_fsf_req - basic FSF request structure 56442428f74SSwen Schillig * @list: list of FSF requests 56542428f74SSwen Schillig * @req_id: unique request ID 56642428f74SSwen Schillig * @adapter: adapter this request belongs to 56742428f74SSwen Schillig * @queue_req: queue related values 56842428f74SSwen Schillig * @completion: used to signal the completion of the request 56942428f74SSwen Schillig * @status: status of the request 57042428f74SSwen Schillig * @fsf_command: FSF command issued 57142428f74SSwen Schillig * @qtcb: associated QTCB 57242428f74SSwen Schillig * @seq_no: sequence number of this request 57342428f74SSwen Schillig * @data: private data 57442428f74SSwen Schillig * @timer: timer data of this request 57542428f74SSwen Schillig * @erp_action: reference to erp action if request issued on behalf of ERP 57642428f74SSwen Schillig * @pool: reference to memory pool if used for this request 57742428f74SSwen Schillig * @issued: time when request was send (STCK) 57842428f74SSwen Schillig * @unit: reference to unit if this request is a SCSI request 57942428f74SSwen Schillig * @handler: handler which should be called to process response 58042428f74SSwen Schillig */ 5811da177e4SLinus Torvalds struct zfcp_fsf_req { 58242428f74SSwen Schillig struct list_head list; 58342428f74SSwen Schillig unsigned long req_id; 58442428f74SSwen Schillig struct zfcp_adapter *adapter; 58542428f74SSwen Schillig struct zfcp_queue_req queue_req; 58642428f74SSwen Schillig struct completion completion; 58742428f74SSwen Schillig u32 status; 58842428f74SSwen Schillig u32 fsf_command; 58942428f74SSwen Schillig struct fsf_qtcb *qtcb; 59042428f74SSwen Schillig u32 seq_no; 59142428f74SSwen Schillig void *data; 59242428f74SSwen Schillig struct timer_list timer; 59342428f74SSwen Schillig struct zfcp_erp_action *erp_action; 59442428f74SSwen Schillig mempool_t *pool; 59542428f74SSwen Schillig unsigned long long issued; 596059c97d0SAndreas Herrmann struct zfcp_unit *unit; 597c41f8cbdSSwen Schillig void (*handler)(struct zfcp_fsf_req *); 5981da177e4SLinus Torvalds }; 5991da177e4SLinus Torvalds 6001da177e4SLinus Torvalds /* driver data */ 6011da177e4SLinus Torvalds struct zfcp_data { 6021da177e4SLinus Torvalds struct scsi_host_template scsi_host_template; 603dd52e0eaSHeiko Carstens struct scsi_transport_template *scsi_transport_template; 6041da177e4SLinus Torvalds rwlock_t config_lock; /* serialises changes 6051da177e4SLinus Torvalds to adapter/port/unit 6061da177e4SLinus Torvalds lists */ 60724680defSChristof Schmitt struct mutex config_mutex; 608a4623c46SSwen Schillig struct kmem_cache *gpn_ft_cache; 609a4623c46SSwen Schillig struct kmem_cache *qtcb_cache; 610e18b890bSChristoph Lameter struct kmem_cache *sr_buffer_cache; 611e18b890bSChristoph Lameter struct kmem_cache *gid_pn_cache; 6121da177e4SLinus Torvalds }; 6131da177e4SLinus Torvalds 6141da177e4SLinus Torvalds /********************** ZFCP SPECIFIC DEFINES ********************************/ 6151da177e4SLinus Torvalds 6161da177e4SLinus Torvalds #define ZFCP_SET 0x00000100 6171da177e4SLinus Torvalds #define ZFCP_CLEAR 0x00000200 6181da177e4SLinus Torvalds 6191da177e4SLinus Torvalds /* 620ca2d02c2SHeiko Carstens * Helper functions for request ID management. 621ca2d02c2SHeiko Carstens */ 622ca2d02c2SHeiko Carstens static inline int zfcp_reqlist_hash(unsigned long req_id) 623ca2d02c2SHeiko Carstens { 624ca2d02c2SHeiko Carstens return req_id % REQUEST_LIST_SIZE; 625ca2d02c2SHeiko Carstens } 626ca2d02c2SHeiko Carstens 627ca2d02c2SHeiko Carstens static inline void zfcp_reqlist_remove(struct zfcp_adapter *adapter, 628ca2d02c2SHeiko Carstens struct zfcp_fsf_req *fsf_req) 629ca2d02c2SHeiko Carstens { 630ca2d02c2SHeiko Carstens list_del(&fsf_req->list); 631ca2d02c2SHeiko Carstens } 632ca2d02c2SHeiko Carstens 633ca2d02c2SHeiko Carstens static inline struct zfcp_fsf_req * 634ca2d02c2SHeiko Carstens zfcp_reqlist_find(struct zfcp_adapter *adapter, unsigned long req_id) 635ca2d02c2SHeiko Carstens { 636ca2d02c2SHeiko Carstens struct zfcp_fsf_req *request; 637ca2d02c2SHeiko Carstens unsigned int idx; 638ca2d02c2SHeiko Carstens 639ca2d02c2SHeiko Carstens idx = zfcp_reqlist_hash(req_id); 640ca2d02c2SHeiko Carstens list_for_each_entry(request, &adapter->req_list[idx], list) 641ca2d02c2SHeiko Carstens if (request->req_id == req_id) 642ca2d02c2SHeiko Carstens return request; 643ca2d02c2SHeiko Carstens return NULL; 644ca2d02c2SHeiko Carstens } 645ca2d02c2SHeiko Carstens 646d1ad09dbSHeiko Carstens static inline struct zfcp_fsf_req * 647d1ad09dbSHeiko Carstens zfcp_reqlist_find_safe(struct zfcp_adapter *adapter, struct zfcp_fsf_req *req) 648d1ad09dbSHeiko Carstens { 649d1ad09dbSHeiko Carstens struct zfcp_fsf_req *request; 650d1ad09dbSHeiko Carstens unsigned int idx; 651d1ad09dbSHeiko Carstens 652d1ad09dbSHeiko Carstens for (idx = 0; idx < REQUEST_LIST_SIZE; idx++) { 653d1ad09dbSHeiko Carstens list_for_each_entry(request, &adapter->req_list[idx], list) 654d1ad09dbSHeiko Carstens if (request == req) 655d1ad09dbSHeiko Carstens return request; 656d1ad09dbSHeiko Carstens } 657d1ad09dbSHeiko Carstens return NULL; 658d1ad09dbSHeiko Carstens } 659d1ad09dbSHeiko Carstens 660ca2d02c2SHeiko Carstens /* 6611da177e4SLinus Torvalds * functions needed for reference/usage counting 6621da177e4SLinus Torvalds */ 6631da177e4SLinus Torvalds 6641da177e4SLinus Torvalds static inline void 6651da177e4SLinus Torvalds zfcp_unit_get(struct zfcp_unit *unit) 6661da177e4SLinus Torvalds { 6671da177e4SLinus Torvalds atomic_inc(&unit->refcount); 6681da177e4SLinus Torvalds } 6691da177e4SLinus Torvalds 6701da177e4SLinus Torvalds static inline void 6711da177e4SLinus Torvalds zfcp_unit_put(struct zfcp_unit *unit) 6721da177e4SLinus Torvalds { 6731da177e4SLinus Torvalds if (atomic_dec_return(&unit->refcount) == 0) 6741da177e4SLinus Torvalds wake_up(&unit->remove_wq); 6751da177e4SLinus Torvalds } 6761da177e4SLinus Torvalds 6771da177e4SLinus Torvalds static inline void 6781da177e4SLinus Torvalds zfcp_port_get(struct zfcp_port *port) 6791da177e4SLinus Torvalds { 6801da177e4SLinus Torvalds atomic_inc(&port->refcount); 6811da177e4SLinus Torvalds } 6821da177e4SLinus Torvalds 6831da177e4SLinus Torvalds static inline void 6841da177e4SLinus Torvalds zfcp_port_put(struct zfcp_port *port) 6851da177e4SLinus Torvalds { 6861da177e4SLinus Torvalds if (atomic_dec_return(&port->refcount) == 0) 6871da177e4SLinus Torvalds wake_up(&port->remove_wq); 6881da177e4SLinus Torvalds } 6891da177e4SLinus Torvalds 6901da177e4SLinus Torvalds static inline void 6911da177e4SLinus Torvalds zfcp_adapter_get(struct zfcp_adapter *adapter) 6921da177e4SLinus Torvalds { 6931da177e4SLinus Torvalds atomic_inc(&adapter->refcount); 6941da177e4SLinus Torvalds } 6951da177e4SLinus Torvalds 6961da177e4SLinus Torvalds static inline void 6971da177e4SLinus Torvalds zfcp_adapter_put(struct zfcp_adapter *adapter) 6981da177e4SLinus Torvalds { 6991da177e4SLinus Torvalds if (atomic_dec_return(&adapter->refcount) == 0) 7001da177e4SLinus Torvalds wake_up(&adapter->remove_wq); 7011da177e4SLinus Torvalds } 7021da177e4SLinus Torvalds 7031da177e4SLinus Torvalds #endif /* ZFCP_DEF_H */ 704