root/drivers/s390/scsi/zfcp_def.h
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * zfcp device driver
 *
 * Global definitions for the zfcp device driver.
 *
 * Copyright IBM Corp. 2002, 2020
 */

#ifndef ZFCP_DEF_H
#define ZFCP_DEF_H

/*************************** INCLUDES *****************************************/

#include <linux/init.h>
#include <linux/moduleparam.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/scatterlist.h>
#include <linux/ioctl.h>
#include <scsi/fc/fc_fs.h>
#include <scsi/fc/fc_gs.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 <scsi/scsi_transport.h>
#include <scsi/scsi_transport_fc.h>
#include <scsi/scsi_bsg_fc.h>
#include <asm/ccwdev.h>
#include <asm/debug.h>
#include <asm/ebcdic.h>
#include <asm/sysinfo.h>
#include "zfcp_fsf.h"
#include "zfcp_fc.h"
#include "zfcp_qdio.h"

/********************* FSF SPECIFIC DEFINES *********************************/

/* ATTENTION: value must not be used by hardware */
#define FSF_QTCB_UNSOLICITED_STATUS             0x6305

/*************** ADAPTER/PORT/UNIT AND FSF_REQ STATUS FLAGS ******************/

/*
 * Note, the leftmost 12 status bits (3 nibbles) are common among adapter, port
 * and unit. This is a mask for bitwise 'and' with status values.
 */
#define ZFCP_COMMON_FLAGS                       0xfff00000

/* common status bits */
#define ZFCP_STATUS_COMMON_RUNNING              0x40000000
#define ZFCP_STATUS_COMMON_ERP_FAILED           0x20000000
#define ZFCP_STATUS_COMMON_UNBLOCKED            0x10000000
#define ZFCP_STATUS_COMMON_OPEN                 0x04000000
#define ZFCP_STATUS_COMMON_ERP_INUSE            0x01000000
#define ZFCP_STATUS_COMMON_ACCESS_DENIED        0x00800000
#define ZFCP_STATUS_COMMON_ACCESS_BOXED         0x00400000
#define ZFCP_STATUS_COMMON_NOESC                0x00200000

/* adapter status */
#define ZFCP_STATUS_ADAPTER_MB_ACT              0x00000001
#define ZFCP_STATUS_ADAPTER_QDIOUP              0x00000002
#define ZFCP_STATUS_ADAPTER_SIOSL_ISSUED        0x00000004
#define ZFCP_STATUS_ADAPTER_XCONFIG_OK          0x00000008
#define ZFCP_STATUS_ADAPTER_HOST_CON_INIT       0x00000010
#define ZFCP_STATUS_ADAPTER_ERP_PENDING         0x00000100
#define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED      0x00000200
#define ZFCP_STATUS_ADAPTER_DATA_DIV_ENABLED    0x00000400

/* remote port status */
#define ZFCP_STATUS_PORT_PHYS_OPEN              0x00000001
#define ZFCP_STATUS_PORT_LINK_TEST              0x00000002

/* FSF request status (this does not have a common part) */
#define ZFCP_STATUS_FSFREQ_ERROR                0x00000008
#define ZFCP_STATUS_FSFREQ_CLEANUP              0x00000010
#define ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED       0x00000040
#define ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED       0x00000080
#define ZFCP_STATUS_FSFREQ_TMFUNCFAILED         0x00000200
#define ZFCP_STATUS_FSFREQ_DISMISSED            0x00001000
#define ZFCP_STATUS_FSFREQ_XDATAINCOMPLETE      0x00020000

/************************* STRUCTURE DEFINITIONS *****************************/

/**
 * enum zfcp_erp_act_type - Type of ERP action object.
 * @ZFCP_ERP_ACTION_REOPEN_LUN: LUN recovery.
 * @ZFCP_ERP_ACTION_REOPEN_PORT: Port recovery.
 * @ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: Forced port recovery.
 * @ZFCP_ERP_ACTION_REOPEN_ADAPTER: Adapter recovery.
 *
 * Values must fit into u8 because of code dependencies:
 * zfcp_dbf_rec_trig(), &zfcp_dbf_rec_trigger.want, &zfcp_dbf_rec_trigger.need;
 * zfcp_dbf_rec_run_lvl(), zfcp_dbf_rec_run(), &zfcp_dbf_rec_running.rec_action.
 */
enum zfcp_erp_act_type {
        ZFCP_ERP_ACTION_REOPEN_LUN         = 1,
        ZFCP_ERP_ACTION_REOPEN_PORT        = 2,
        ZFCP_ERP_ACTION_REOPEN_PORT_FORCED = 3,
        ZFCP_ERP_ACTION_REOPEN_ADAPTER     = 4,
};

/*
 * Values must fit into u16 because of code dependencies:
 * zfcp_dbf_rec_run_lvl(), zfcp_dbf_rec_run(), zfcp_dbf_rec_run_wka(),
 * &zfcp_dbf_rec_running.rec_step.
 */
enum zfcp_erp_steps {
        ZFCP_ERP_STEP_UNINITIALIZED     = 0x0000,
        ZFCP_ERP_STEP_PHYS_PORT_CLOSING = 0x0010,
        ZFCP_ERP_STEP_PORT_CLOSING      = 0x0100,
        ZFCP_ERP_STEP_PORT_OPENING      = 0x0800,
        ZFCP_ERP_STEP_LUN_CLOSING       = 0x1000,
        ZFCP_ERP_STEP_LUN_OPENING       = 0x2000,
};

struct zfcp_erp_action {
        struct list_head list;
        enum zfcp_erp_act_type type;  /* requested action code */
        struct zfcp_adapter *adapter; /* device which should be recovered */
        struct zfcp_port *port;
        struct scsi_device *sdev;
        u32             status;       /* recovery status */
        enum zfcp_erp_steps     step;   /* active step of this erp action */
        u64                     fsf_req_id;
        struct timer_list timer;
};

/* holds various memory pools of an adapter */
struct zfcp_adapter_mempool {
        mempool_t *erp_req;
        mempool_t *gid_pn_req;
        mempool_t *scsi_req;
        mempool_t *scsi_abort;
        mempool_t *status_read_req;
        mempool_t *sr_data;
        mempool_t *gid_pn;
        mempool_t *qtcb_pool;
};

struct zfcp_adapter {
        struct kref             ref;
        u64                     peer_wwnn;         /* P2P peer WWNN */
        u64                     peer_wwpn;         /* P2P peer WWPN */
        u32                     peer_d_id;         /* P2P peer D_ID */
        struct ccw_device       *ccw_device;       /* S/390 ccw device */
        struct zfcp_qdio        *qdio;
        u32                     hydra_version;     /* Hydra version */
        u32                     fsf_lic_version;
        u32                     adapter_features;  /* FCP channel features */
        u32                     connection_features; /* host connection features */
        u32                     hardware_version;  /* of FCP channel */
        u32                     fc_security_algorithms; /* of FCP channel */
        u32                     fc_security_algorithms_old; /* 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;         /* remote port list */
        rwlock_t                port_list_lock;    /* port list lock */
        u64                     req_no;            /* unique FSF req number */
        struct zfcp_reqlist     *req_list;
        u32                     fsf_req_seq_no;    /* FSF cmnd seq number */
        rwlock_t                abort_lock;        /* Protects against SCSI
                                                      stack abort/command
                                                      completion races */
        atomic_t                stat_miss;         /* # missing status reads*/
        unsigned int            stat_read_buf_num;
        struct work_struct      stat_work;
        atomic_t                status;            /* status of this adapter */
        struct list_head        erp_ready_head;    /* error recovery for this
                                                      adapter/devices */
        wait_queue_head_t       erp_ready_wq;
        struct list_head        erp_running_head;
        rwlock_t                erp_lock;
        wait_queue_head_t       erp_done_wqh;
        struct zfcp_erp_action  erp_action;        /* pending error recovery */
        atomic_t                erp_counter;
        u32                     erp_total_count;   /* total nr of enqueued erp
                                                      actions */
        u32                     erp_low_mem_count; /* nr of erp actions waiting
                                                      for memory */
        struct task_struct      *erp_thread;
        struct zfcp_fc_wka_ports *gs;              /* generic services */
        struct zfcp_dbf         *dbf;              /* debug traces */
        struct zfcp_adapter_mempool     pool;      /* Adapter memory pools */
        struct fc_host_statistics *fc_stats;
        struct fsf_qtcb_bottom_port *stats_reset_data;
        unsigned long           stats_reset;
        struct delayed_work     scan_work;
        struct work_struct      ns_up_work;
        struct service_level    service_level;
        struct workqueue_struct *work_queue;
        struct device_dma_parameters dma_parms;
        struct zfcp_fc_events events;
        unsigned long           next_port_scan;
        struct zfcp_diag_adapter        *diagnostics;
        struct work_struct      version_change_lost_work;
};

struct zfcp_port {
        struct device          dev;
        struct fc_rport        *rport;         /* rport of fc transport class */
        struct list_head       list;           /* list of remote ports */
        struct zfcp_adapter    *adapter;       /* adapter used to access port */
        struct list_head        unit_list;      /* head of logical unit list */
        rwlock_t                unit_list_lock; /* unit list lock */
        atomic_t                units;         /* zfcp_unit count */
        atomic_t               status;         /* status of this remote port */
        u64                    wwnn;           /* WWNN if known */
        u64                    wwpn;           /* WWPN */
        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;
        u32                    connection_info;
        u32                    connection_info_old;
        struct work_struct     gid_pn_work;
        struct work_struct     test_link_work;
        struct work_struct     rport_work;
        enum { RPORT_NONE, RPORT_ADD, RPORT_DEL }  rport_task;
        unsigned int            starget_id;
};

struct zfcp_latency_record {
        u32 min;
        u32 max;
        u64 sum;
};

struct zfcp_latency_cont {
        struct zfcp_latency_record channel;
        struct zfcp_latency_record fabric;
        u64 counter;
};

struct zfcp_latencies {
        struct zfcp_latency_cont read;
        struct zfcp_latency_cont write;
        struct zfcp_latency_cont cmd;
        spinlock_t lock;
};

/**
 * struct zfcp_unit - LUN configured via zfcp sysfs
 * @dev: struct device for sysfs representation and reference counting
 * @list: entry in LUN/unit list per zfcp_port
 * @port: reference to zfcp_port where this LUN is configured
 * @fcp_lun: 64 bit LUN value
 * @scsi_work: for running scsi_scan_target
 *
 * This is the representation of a LUN that has been configured for
 * usage. The main data here is the 64 bit LUN value, data for
 * running I/O and recovery is in struct zfcp_scsi_dev.
 */
struct zfcp_unit {
        struct device           dev;
        struct list_head        list;
        struct zfcp_port        *port;
        u64                     fcp_lun;
        struct work_struct      scsi_work;
};

/**
 * struct zfcp_scsi_dev - zfcp data per SCSI device
 * @status: zfcp internal status flags
 * @lun_handle: handle from "open lun" for issuing FSF requests
 * @erp_action: zfcp erp data for opening and recovering this LUN
 * @erp_counter: zfcp erp counter for this LUN
 * @latencies: FSF channel and fabric latencies
 * @port: zfcp_port where this LUN belongs to
 */
struct zfcp_scsi_dev {
        atomic_t                status;
        u32                     lun_handle;
        struct zfcp_erp_action  erp_action;
        atomic_t                erp_counter;
        struct zfcp_latencies   latencies;
        struct zfcp_port        *port;
};

/**
 * sdev_to_zfcp - Access zfcp LUN data for SCSI device
 * @sdev: scsi_device where to get the zfcp_scsi_dev pointer
 */
static inline struct zfcp_scsi_dev *sdev_to_zfcp(struct scsi_device *sdev)
{
        return scsi_transport_device_data(sdev);
}

/**
 * zfcp_scsi_dev_lun - Return SCSI device LUN as 64 bit FCP LUN
 * @sdev: SCSI device where to get the LUN from
 */
static inline u64 zfcp_scsi_dev_lun(struct scsi_device *sdev)
{
        u64 fcp_lun;

        int_to_scsilun(sdev->lun, (struct scsi_lun *)&fcp_lun);
        return fcp_lun;
}

/**
 * struct zfcp_fsf_req - basic FSF request structure
 * @list: list of FSF requests
 * @req_id: unique request ID
 * @adapter: adapter this request belongs to
 * @qdio_req: qdio queue related values
 * @completion: used to signal the completion of the request
 * @status: status of the request
 * @qtcb: associated QTCB
 * @data: private data
 * @timer: timer data of this request
 * @erp_action: reference to erp action if request issued on behalf of ERP
 * @pool: reference to memory pool if used for this request
 * @issued: time when request was send (STCK)
 * @handler: handler which should be called to process response
 */
struct zfcp_fsf_req {
        struct list_head        list;
        u64                     req_id;
        struct zfcp_adapter     *adapter;
        struct zfcp_qdio_req    qdio_req;
        struct completion       completion;
        u32                     status;
        struct fsf_qtcb         *qtcb;
        void                    *data;
        struct timer_list       timer;
        struct zfcp_erp_action  *erp_action;
        mempool_t               *pool;
        unsigned long long      issued;
        void                    (*handler)(struct zfcp_fsf_req *);
};

static inline
int zfcp_adapter_multi_buffer_active(struct zfcp_adapter *adapter)
{
        return atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_MB_ACT;
}

static inline bool zfcp_fsf_req_is_status_read_buffer(struct zfcp_fsf_req *req)
{
        return req->qtcb == NULL;
}

#endif /* ZFCP_DEF_H */