[SCSI] zfcp: Add information about interrupt to trace.
[safe/jmp/linux-2.6] / drivers / s390 / scsi / zfcp_def.h
index 32933ed..fc61a8e 100644 (file)
@@ -1,23 +1,23 @@
-/* 
+/*
  * This file is part of the zfcp device driver for
  * FCP adapters for IBM System z9 and zSeries.
  *
  * (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 
- * the Free Software Foundation; either version 2, or (at your option) 
- * any later version. 
- * 
- * This program is distributed in the hope that it will be useful, 
- * but WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
- * GNU General Public License for more details. 
- * 
- * You should have received a copy of the GNU General Public License 
- * along with this program; if not, write to the Free Software 
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
- */ 
+ *
+ * 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
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
 
 #ifndef ZFCP_DEF_H
 #define ZFCP_DEF_H
@@ -34,6 +34,7 @@
 #include <linux/slab.h>
 #include <linux/mempool.h>
 #include <linux/syscalls.h>
+#include <linux/scatterlist.h>
 #include <linux/ioctl.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_tcq.h>
@@ -46,6 +47,7 @@
 #include <asm/qdio.h>
 #include <asm/debug.h>
 #include <asm/ebcdic.h>
+#include "zfcp_dbf.h"
 #include "zfcp_fsf.h"
 
 
 static inline void *
 zfcp_sg_to_address(struct scatterlist *list)
 {
-       return (void *) (page_address(list->page) + list->offset);
+       return sg_virt(list);
 }
 
 /**
  * zfcp_address_to_sg - set up struct scatterlist from kernel address
  * @address: kernel address
  * @list: struct scatterlist
+ * @size: buffer size
  */
 static inline void
-zfcp_address_to_sg(void *address, struct scatterlist *list)
+zfcp_address_to_sg(void *address, struct scatterlist *list, unsigned int size)
 {
-       list->page = virt_to_page(address);
-       list->offset = ((unsigned long) address) & (PAGE_SIZE - 1);
+       sg_set_buf(list, address, size);
 }
 
 #define REQUEST_LIST_SIZE 128
@@ -90,7 +92,7 @@ zfcp_address_to_sg(void *address, struct scatterlist *list)
 #define ZFCP_DEVICE_TYPE        0x1732
 #define ZFCP_DEVICE_MODEL       0x03
 #define ZFCP_DEVICE_MODEL_PRIV 0x04
+
 /* allow as many chained SBALs as are supported by hardware */
 #define ZFCP_MAX_SBALS_PER_REQ         FSF_MAX_SBALS_PER_REQ
 #define ZFCP_MAX_SBALS_PER_CT_REQ      FSF_MAX_SBALS_PER_REQ
@@ -117,7 +119,7 @@ zfcp_address_to_sg(void *address, struct scatterlist *list)
 
 #define ZFCP_SBAL_TIMEOUT               (5*HZ)
 
-#define ZFCP_TYPE2_RECOVERY_TIME        (8*HZ)
+#define ZFCP_TYPE2_RECOVERY_TIME        8      /* seconds */
 
 /* queue polling (values in microseconds) */
 #define ZFCP_MAX_INPUT_THRESHOLD       5000    /* FIXME: tune */
@@ -126,6 +128,7 @@ zfcp_address_to_sg(void *address, struct scatterlist *list)
 #define ZFCP_MIN_OUTPUT_THRESHOLD      1       /* ignored by QDIO layer */
 
 #define QDIO_SCSI_QFMT                 1       /* 1 for FSF */
+#define QBUFF_PER_PAGE                 (PAGE_SIZE / sizeof(struct qdio_buffer))
 
 /********************* FSF SPECIFIC DEFINES *********************************/
 
@@ -133,11 +136,10 @@ zfcp_address_to_sg(void *address, struct scatterlist *list)
 #define ZFCP_QTCB_VERSION      FSF_QTCB_CURRENT_VERSION
 /* ATTENTION: value must not be used by hardware */
 #define FSF_QTCB_UNSOLICITED_STATUS            0x6305
-#define ZFCP_STATUS_READ_FAILED_THRESHOLD      3
 #define ZFCP_STATUS_READS_RECOM                        FSF_STATUS_READS_RECOM
 
 /* 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_FIRST_SLEEP  1
 #define ZFCP_EXCHANGE_CONFIG_DATA_RETRIES      7
 
 /* timeout value for "default timer" for fsf requests */
@@ -260,167 +262,6 @@ struct fcp_logo {
 } __attribute__((packed));
 
 /*
- * DBF stuff
- */
-#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));
-
-/* FIXME: to be inflated when reworking the erp dbf */
-struct zfcp_erp_dbf_record {
-       u8 dummy[16];
-} __attribute__ ((packed));
-
-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_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_hba_dbf_record_qdio {
-       u32 status;
-       u32 qdio_error;
-       u32 siga_error;
-       u8 sbal_index;
-       u8 sbal_count;
-} __attribute__ ((packed));
-
-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_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_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 */
@@ -507,7 +348,7 @@ struct zfcp_rc_entry {
 
 /*
  * this allows removal of logging code by the preprocessor
- * (the most detailed log level still to be compiled in is specified, 
+ * (the most detailed log level still to be compiled in is specified,
  * higher log levels are removed)
  */
 #define ZFCP_LOG_LEVEL_LIMIT   ZFCP_LOG_LEVEL_TRACE
@@ -537,7 +378,7 @@ struct zfcp_rc_entry {
 
 /* logging routine for zfcp */
 #define _ZFCP_LOG(fmt, args...) \
-       printk(KERN_ERR ZFCP_NAME": %s(%d): " fmt, __FUNCTION__, \
+       printk(KERN_ERR ZFCP_NAME": %s(%d): " fmt, __func__, \
               __LINE__ , ##args)
 
 #define ZFCP_LOG(level, fmt, args...) \
@@ -545,7 +386,7 @@ do { \
        if (ZFCP_LOG_CHECK(level)) \
                _ZFCP_LOG(fmt, ##args); \
 } while (0)
-       
+
 #if ZFCP_LOG_LEVEL_LIMIT < ZFCP_LOG_LEVEL_NORMAL
 # define ZFCP_LOG_NORMAL(fmt, args...) do { } while (0)
 #else
@@ -582,8 +423,8 @@ do { \
 
 /*************** ADAPTER/PORT/UNIT AND FSF_REQ STATUS FLAGS ******************/
 
-/* 
- * Note, the leftmost status byte is common among adapter, port 
+/*
+ * Note, the leftmost status byte is common among adapter, port
  * and unit
  */
 #define ZFCP_COMMON_FLAGS                      0xfff00000
@@ -632,11 +473,11 @@ do { \
                 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
+#define ZFCP_STATUS_UNIT_SCSI_WORK_PENDING     0x00000020
 
 /* FSF request status (this does not have a common part) */
 #define ZFCP_STATUS_FSFREQ_NOT_INIT            0x00000000
@@ -866,6 +707,24 @@ struct zfcp_erp_action {
        struct timer_list timer;
 };
 
+struct fsf_latency_record {
+       u32 min;
+       u32 max;
+       u64 sum;
+};
+
+struct latency_cont {
+       struct fsf_latency_record channel;
+       struct fsf_latency_record fabric;
+       u64 counter;
+};
+
+struct zfcp_latencies {
+       struct latency_cont read;
+       struct latency_cont write;
+       struct latency_cont cmd;
+       spinlock_t lock;
+};
 
 struct zfcp_adapter {
        struct list_head        list;              /* list of adapters */
@@ -881,6 +740,7 @@ struct zfcp_adapter {
        u32                     adapter_features;  /* FCP channel features */
        u32                     connection_features; /* host connection features */
         u32                    hardware_version;  /* of FCP channel */
+       u16                     timer_ticks;       /* time int for a tick */
        struct Scsi_Host        *scsi_host;        /* Pointer to mid-layer */
        struct list_head        port_list_head;    /* remote port list */
        struct list_head        port_remove_lh;    /* head of ports to be
@@ -898,7 +758,8 @@ struct zfcp_adapter {
        rwlock_t                abort_lock;        /* Protects against SCSI
                                                      stack abort/command
                                                      completion races */
-       u16                     status_read_failed; /* # failed status reads */
+       atomic_t                stat_miss;         /* # missing status reads*/
+       struct work_struct      stat_work;
        atomic_t                status;            /* status of this adapter */
        struct list_head        erp_ready_head;    /* error recovery for this
                                                      adapter/devices */
@@ -914,15 +775,15 @@ 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;
+       debug_info_t            *rec_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              rec_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_rec_dbf_record      rec_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;
@@ -980,6 +841,7 @@ struct zfcp_unit {
         struct scsi_device     *device;        /* scsi device struct pointer */
        struct zfcp_erp_action erp_action;     /* pending error recovery */
         atomic_t               erp_counter;
+       struct zfcp_latencies   latencies;
 };
 
 /* FSF request */
@@ -989,20 +851,20 @@ struct zfcp_fsf_req {
        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 */
-       u8                     sbal_last;      /* last possible SBAL for
+       u8                     sbal_last;      /* last SBAL for this request */
+       u8                     sbal_limit;      /* last possible SBAL for
                                                  this reuest */
-       u8                     sbal_curr;      /* current SBAL during creation
-                                                 of request */
        u8                     sbale_curr;     /* current SBALE during creation
                                                  of request */
+       u8                      sbal_response;  /* SBAL used in interrupt */
        wait_queue_head_t      completion_wq;  /* can be used by a routine
                                                  to wait for completion */
        volatile u32           status;         /* status of this request */
        u32                    fsf_command;    /* FSF Command copy */
        struct fsf_qtcb        *qtcb;          /* address of associated QTCB */
        u32                    seq_no;         /* Sequence number of request */
-        unsigned long          data;           /* private data of request */ 
-       struct timer_list      timer;          /* used for erp or scsi er */
+       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
@@ -1085,6 +947,56 @@ extern void _zfcp_hex_dump(char *, int);
 #define zfcp_get_busid_by_unit(unit) (zfcp_get_busid_by_port(unit->port))
 
 /*
+ * Helper functions for request ID management.
+ */
+static inline int zfcp_reqlist_hash(unsigned long req_id)
+{
+       return req_id % REQUEST_LIST_SIZE;
+}
+
+static inline void zfcp_reqlist_add(struct zfcp_adapter *adapter,
+                                   struct zfcp_fsf_req *fsf_req)
+{
+       unsigned int idx;
+
+       idx = zfcp_reqlist_hash(fsf_req->req_id);
+       list_add_tail(&fsf_req->list, &adapter->req_list[idx]);
+}
+
+static inline void zfcp_reqlist_remove(struct zfcp_adapter *adapter,
+                                      struct zfcp_fsf_req *fsf_req)
+{
+       list_del(&fsf_req->list);
+}
+
+static inline struct zfcp_fsf_req *
+zfcp_reqlist_find(struct zfcp_adapter *adapter, unsigned long req_id)
+{
+       struct zfcp_fsf_req *request;
+       unsigned int idx;
+
+       idx = zfcp_reqlist_hash(req_id);
+       list_for_each_entry(request, &adapter->req_list[idx], list)
+               if (request->req_id == req_id)
+                       return request;
+       return NULL;
+}
+
+static inline struct zfcp_fsf_req *
+zfcp_reqlist_find_safe(struct zfcp_adapter *adapter, struct zfcp_fsf_req *req)
+{
+       struct zfcp_fsf_req *request;
+       unsigned int idx;
+
+       for (idx = 0; idx < REQUEST_LIST_SIZE; idx++) {
+               list_for_each_entry(request, &adapter->req_list[idx], list)
+                       if (request == req)
+                               return request;
+       }
+       return NULL;
+}
+
+/*
  *  functions needed for reference/usage counting
  */