linux/drivers/s390/scsi/zfcp_dbf.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 * zfcp device driver
   4 * debug feature declarations
   5 *
   6 * Copyright IBM Corp. 2008, 2017
   7 */
   8
   9#ifndef ZFCP_DBF_H
  10#define ZFCP_DBF_H
  11
  12#include <scsi/fc/fc_fcp.h>
  13#include "zfcp_ext.h"
  14#include "zfcp_fsf.h"
  15#include "zfcp_def.h"
  16
  17#define ZFCP_DBF_TAG_LEN       7
  18
  19#define ZFCP_DBF_INVALID_LUN    0xFFFFFFFFFFFFFFFFull
  20
  21enum zfcp_dbf_pseudo_erp_act_type {
  22        ZFCP_PSEUDO_ERP_ACTION_RPORT_ADD = 0xff,
  23        ZFCP_PSEUDO_ERP_ACTION_RPORT_DEL = 0xfe,
  24};
  25
  26/**
  27 * struct zfcp_dbf_rec_trigger - trace record for triggered recovery action
  28 * @ready: number of ready recovery actions
  29 * @running: number of running recovery actions
  30 * @want: wanted recovery action
  31 * @need: needed recovery action
  32 */
  33struct zfcp_dbf_rec_trigger {
  34        u32 ready;
  35        u32 running;
  36        u8 want;
  37        u8 need;
  38} __packed;
  39
  40/**
  41 * struct zfcp_dbf_rec_running - trace record for running recovery
  42 * @fsf_req_id: request id for fsf requests
  43 * @rec_status: status of the fsf request
  44 * @rec_step: current step of the recovery action
  45 * @rec_action: ERP action type
  46 * @rec_count: recoveries including retries for particular @rec_action
  47 */
  48struct zfcp_dbf_rec_running {
  49        u64 fsf_req_id;
  50        u32 rec_status;
  51        u16 rec_step;
  52        u8 rec_action;
  53        u8 rec_count;
  54} __packed;
  55
  56/**
  57 * enum zfcp_dbf_rec_id - recovery trace record id
  58 * @ZFCP_DBF_REC_TRIG: triggered recovery identifier
  59 * @ZFCP_DBF_REC_RUN: running recovery identifier
  60 */
  61enum zfcp_dbf_rec_id {
  62        ZFCP_DBF_REC_TRIG       = 1,
  63        ZFCP_DBF_REC_RUN        = 2,
  64};
  65
  66/**
  67 * struct zfcp_dbf_rec - trace record for error recovery actions
  68 * @id: unique number of recovery record type
  69 * @tag: identifier string specifying the location of initiation
  70 * @lun: logical unit number
  71 * @wwpn: word wide port number
  72 * @d_id: destination ID
  73 * @adapter_status: current status of the adapter
  74 * @port_status: current status of the port
  75 * @lun_status: current status of the lun
  76 * @u: record type specific data
  77 * @u.trig: structure zfcp_dbf_rec_trigger
  78 * @u.run: structure zfcp_dbf_rec_running
  79 */
  80struct zfcp_dbf_rec {
  81        u8 id;
  82        char tag[ZFCP_DBF_TAG_LEN];
  83        u64 lun;
  84        u64 wwpn;
  85        u32 d_id;
  86        u32 adapter_status;
  87        u32 port_status;
  88        u32 lun_status;
  89        union {
  90                struct zfcp_dbf_rec_trigger trig;
  91                struct zfcp_dbf_rec_running run;
  92        } u;
  93} __packed;
  94
  95/**
  96 * enum zfcp_dbf_san_id - SAN trace record identifier
  97 * @ZFCP_DBF_SAN_REQ: request trace record id
  98 * @ZFCP_DBF_SAN_RES: response trace record id
  99 * @ZFCP_DBF_SAN_ELS: extended link service record id
 100 */
 101enum zfcp_dbf_san_id {
 102        ZFCP_DBF_SAN_REQ        = 1,
 103        ZFCP_DBF_SAN_RES        = 2,
 104        ZFCP_DBF_SAN_ELS        = 3,
 105};
 106
 107/** struct zfcp_dbf_san - trace record for SAN requests and responses
 108 * @id: unique number of recovery record type
 109 * @tag: identifier string specifying the location of initiation
 110 * @fsf_req_id: request id for fsf requests
 111 * @payload: unformatted information related to request/response
 112 * @d_id: destination id
 113 */
 114struct zfcp_dbf_san {
 115        u8 id;
 116        char tag[ZFCP_DBF_TAG_LEN];
 117        u64 fsf_req_id;
 118        u32 d_id;
 119#define ZFCP_DBF_SAN_MAX_PAYLOAD (FC_CT_HDR_LEN + 32)
 120        char payload[ZFCP_DBF_SAN_MAX_PAYLOAD];
 121        u16 pl_len;
 122} __packed;
 123
 124/**
 125 * struct zfcp_dbf_hba_res - trace record for hba responses
 126 * @req_issued: timestamp when request was issued
 127 * @prot_status: protocol status
 128 * @prot_status_qual: protocol status qualifier
 129 * @fsf_status: fsf status
 130 * @fsf_status_qual: fsf status qualifier
 131 * @port_handle: handle for port
 132 * @lun_handle: handle for LUN
 133 */
 134struct zfcp_dbf_hba_res {
 135        u64 req_issued;
 136        u32 prot_status;
 137        u8  prot_status_qual[FSF_PROT_STATUS_QUAL_SIZE];
 138        u32 fsf_status;
 139        u8  fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE];
 140        u32 port_handle;
 141        u32 lun_handle;
 142} __packed;
 143
 144/**
 145 * struct zfcp_dbf_hba_uss - trace record for unsolicited status
 146 * @status_type: type of unsolicited status
 147 * @status_subtype: subtype of unsolicited status
 148 * @d_id: destination ID
 149 * @lun: logical unit number
 150 * @queue_designator: queue designator
 151 */
 152struct zfcp_dbf_hba_uss {
 153        u32 status_type;
 154        u32 status_subtype;
 155        u32 d_id;
 156        u64 lun;
 157        u64 queue_designator;
 158} __packed;
 159
 160/**
 161 * enum zfcp_dbf_hba_id - HBA trace record identifier
 162 * @ZFCP_DBF_HBA_RES: response trace record
 163 * @ZFCP_DBF_HBA_USS: unsolicited status trace record
 164 * @ZFCP_DBF_HBA_BIT: bit error trace record
 165 * @ZFCP_DBF_HBA_BASIC: basic adapter event, only trace tag, no other data
 166 */
 167enum zfcp_dbf_hba_id {
 168        ZFCP_DBF_HBA_RES        = 1,
 169        ZFCP_DBF_HBA_USS        = 2,
 170        ZFCP_DBF_HBA_BIT        = 3,
 171        ZFCP_DBF_HBA_BASIC      = 4,
 172};
 173
 174/**
 175 * struct zfcp_dbf_hba - common trace record for HBA records
 176 * @id: unique number of recovery record type
 177 * @tag: identifier string specifying the location of initiation
 178 * @fsf_req_id: request id for fsf requests
 179 * @fsf_req_status: status of fsf request
 180 * @fsf_cmd: fsf command
 181 * @fsf_seq_no: fsf sequence number
 182 * @pl_len: length of payload stored as zfcp_dbf_pay
 183 * @u: record type specific data
 184 * @u.res: data for fsf responses
 185 * @u.uss: data for unsolicited status buffer
 186 * @u.be:  data for bit error unsolicited status buffer
 187 */
 188struct zfcp_dbf_hba {
 189        u8 id;
 190        char tag[ZFCP_DBF_TAG_LEN];
 191        u64 fsf_req_id;
 192        u32 fsf_req_status;
 193        u32 fsf_cmd;
 194        u32 fsf_seq_no;
 195        u16 pl_len;
 196        union {
 197                struct zfcp_dbf_hba_res res;
 198                struct zfcp_dbf_hba_uss uss;
 199                struct fsf_bit_error_payload be;
 200        } u;
 201} __packed;
 202
 203/**
 204 * enum zfcp_dbf_scsi_id - scsi trace record identifier
 205 * @ZFCP_DBF_SCSI_CMND: scsi command trace record
 206 */
 207enum zfcp_dbf_scsi_id {
 208        ZFCP_DBF_SCSI_CMND      = 1,
 209};
 210
 211/**
 212 * struct zfcp_dbf_scsi - common trace record for SCSI records
 213 * @id: unique number of recovery record type
 214 * @tag: identifier string specifying the location of initiation
 215 * @scsi_id: scsi device id
 216 * @scsi_lun: scsi device logical unit number, low part of 64 bit, old 32 bit
 217 * @scsi_result: scsi result
 218 * @scsi_retries: current retry number of scsi request
 219 * @scsi_allowed: allowed retries
 220 * @fcp_rsp_info: FCP response info code
 221 * @scsi_opcode: scsi opcode
 222 * @fsf_req_id: request id of fsf request
 223 * @host_scribble: LLD specific data attached to SCSI request
 224 * @pl_len: length of payload stored as zfcp_dbf_pay
 225 * @fcp_rsp: response for FCP request
 226 * @scsi_lun_64_hi: scsi device logical unit number, high part of 64 bit
 227 */
 228struct zfcp_dbf_scsi {
 229        u8 id;
 230        char tag[ZFCP_DBF_TAG_LEN];
 231        u32 scsi_id;
 232        u32 scsi_lun;
 233        u32 scsi_result;
 234        u8 scsi_retries;
 235        u8 scsi_allowed;
 236        u8 fcp_rsp_info;
 237#define ZFCP_DBF_SCSI_OPCODE    16
 238        u8 scsi_opcode[ZFCP_DBF_SCSI_OPCODE];
 239        u64 fsf_req_id;
 240        u64 host_scribble;
 241        u16 pl_len;
 242        struct fcp_resp_with_ext fcp_rsp;
 243        u32 scsi_lun_64_hi;
 244} __packed;
 245
 246/**
 247 * struct zfcp_dbf_pay - trace record for unformatted payload information
 248 * @area: area this record is originated from
 249 * @counter: ascending record number
 250 * @fsf_req_id: request id of fsf request
 251 * @data: unformatted data
 252 */
 253struct zfcp_dbf_pay {
 254        u8 counter;
 255        char area[ZFCP_DBF_TAG_LEN];
 256        u64 fsf_req_id;
 257#define ZFCP_DBF_PAY_MAX_REC 0x100
 258        char data[ZFCP_DBF_PAY_MAX_REC];
 259} __packed;
 260
 261/**
 262 * struct zfcp_dbf - main dbf trace structure
 263 * @pay: reference to payload trace area
 264 * @rec: reference to recovery trace area
 265 * @hba: reference to hba trace area
 266 * @san: reference to san trace area
 267 * @scsi: reference to scsi trace area
 268 * @pay_lock: lock protecting payload trace buffer
 269 * @rec_lock: lock protecting recovery trace buffer
 270 * @hba_lock: lock protecting hba trace buffer
 271 * @san_lock: lock protecting san trace buffer
 272 * @scsi_lock: lock protecting scsi trace buffer
 273 * @pay_buf: pre-allocated buffer for payload
 274 * @rec_buf: pre-allocated buffer for recovery
 275 * @hba_buf: pre-allocated buffer for hba
 276 * @san_buf: pre-allocated buffer for san
 277 * @scsi_buf: pre-allocated buffer for scsi
 278 */
 279struct zfcp_dbf {
 280        debug_info_t                    *pay;
 281        debug_info_t                    *rec;
 282        debug_info_t                    *hba;
 283        debug_info_t                    *san;
 284        debug_info_t                    *scsi;
 285        spinlock_t                      pay_lock;
 286        spinlock_t                      rec_lock;
 287        spinlock_t                      hba_lock;
 288        spinlock_t                      san_lock;
 289        spinlock_t                      scsi_lock;
 290        struct zfcp_dbf_pay             pay_buf;
 291        struct zfcp_dbf_rec             rec_buf;
 292        struct zfcp_dbf_hba             hba_buf;
 293        struct zfcp_dbf_san             san_buf;
 294        struct zfcp_dbf_scsi            scsi_buf;
 295};
 296
 297/**
 298 * zfcp_dbf_hba_fsf_resp_suppress - true if we should not trace by default
 299 * @req: request that has been completed
 300 *
 301 * Returns true if FCP response with only benign residual under count.
 302 */
 303static inline
 304bool zfcp_dbf_hba_fsf_resp_suppress(struct zfcp_fsf_req *req)
 305{
 306        struct fsf_qtcb *qtcb = req->qtcb;
 307        u32 fsf_stat = qtcb->header.fsf_status;
 308        struct fcp_resp *fcp_rsp;
 309        u8 rsp_flags, fr_status;
 310
 311        if (qtcb->prefix.qtcb_type != FSF_IO_COMMAND)
 312                return false; /* not an FCP response */
 313        fcp_rsp = &qtcb->bottom.io.fcp_rsp.iu.resp;
 314        rsp_flags = fcp_rsp->fr_flags;
 315        fr_status = fcp_rsp->fr_status;
 316        return (fsf_stat == FSF_FCP_RSP_AVAILABLE) &&
 317                (rsp_flags == FCP_RESID_UNDER) &&
 318                (fr_status == SAM_STAT_GOOD);
 319}
 320
 321static inline
 322void zfcp_dbf_hba_fsf_resp(char *tag, int level, struct zfcp_fsf_req *req)
 323{
 324        if (debug_level_enabled(req->adapter->dbf->hba, level))
 325                zfcp_dbf_hba_fsf_res(tag, level, req);
 326}
 327
 328/**
 329 * zfcp_dbf_hba_fsf_response - trace event for request completion
 330 * @req: request that has been completed
 331 */
 332static inline
 333void zfcp_dbf_hba_fsf_response(struct zfcp_fsf_req *req)
 334{
 335        struct fsf_qtcb *qtcb = req->qtcb;
 336
 337        if (unlikely(req->status & (ZFCP_STATUS_FSFREQ_DISMISSED |
 338                                    ZFCP_STATUS_FSFREQ_ERROR))) {
 339                zfcp_dbf_hba_fsf_resp("fs_rerr", 3, req);
 340
 341        } else if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) &&
 342            (qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) {
 343                zfcp_dbf_hba_fsf_resp("fs_perr", 1, req);
 344
 345        } else if (qtcb->header.fsf_status != FSF_GOOD) {
 346                zfcp_dbf_hba_fsf_resp("fs_ferr",
 347                                      zfcp_dbf_hba_fsf_resp_suppress(req)
 348                                      ? 5 : 1, req);
 349
 350        } else if ((qtcb->header.fsf_command == FSF_QTCB_OPEN_PORT_WITH_DID) ||
 351                   (qtcb->header.fsf_command == FSF_QTCB_OPEN_LUN)) {
 352                zfcp_dbf_hba_fsf_resp("fs_open", 4, req);
 353
 354        } else if (qtcb->header.log_length) {
 355                zfcp_dbf_hba_fsf_resp("fs_qtcb", 5, req);
 356
 357        } else {
 358                zfcp_dbf_hba_fsf_resp("fs_norm", 6, req);
 359        }
 360}
 361
 362static inline
 363void _zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *scmd,
 364                   struct zfcp_fsf_req *req)
 365{
 366        struct zfcp_adapter *adapter = (struct zfcp_adapter *)
 367                                        scmd->device->host->hostdata[0];
 368
 369        if (debug_level_enabled(adapter->dbf->scsi, level))
 370                zfcp_dbf_scsi_common(tag, level, scmd->device, scmd, req);
 371}
 372
 373/**
 374 * zfcp_dbf_scsi_result - trace event for SCSI command completion
 375 * @scmd: SCSI command pointer
 376 * @req: FSF request used to issue SCSI command
 377 */
 378static inline
 379void zfcp_dbf_scsi_result(struct scsi_cmnd *scmd, struct zfcp_fsf_req *req)
 380{
 381        if (scmd->result != 0)
 382                _zfcp_dbf_scsi("rsl_err", 3, scmd, req);
 383        else if (scmd->retries > 0)
 384                _zfcp_dbf_scsi("rsl_ret", 4, scmd, req);
 385        else
 386                _zfcp_dbf_scsi("rsl_nor", 6, scmd, req);
 387}
 388
 389/**
 390 * zfcp_dbf_scsi_fail_send - trace event for failure to send SCSI command
 391 * @scmd: SCSI command pointer
 392 */
 393static inline
 394void zfcp_dbf_scsi_fail_send(struct scsi_cmnd *scmd)
 395{
 396        _zfcp_dbf_scsi("rsl_fai", 4, scmd, NULL);
 397}
 398
 399/**
 400 * zfcp_dbf_scsi_abort - trace event for SCSI command abort
 401 * @tag: tag indicating success or failure of abort operation
 402 * @scmd: SCSI command to be aborted
 403 * @fsf_req: request containing abort (might be NULL)
 404 */
 405static inline
 406void zfcp_dbf_scsi_abort(char *tag, struct scsi_cmnd *scmd,
 407                         struct zfcp_fsf_req *fsf_req)
 408{
 409        _zfcp_dbf_scsi(tag, 1, scmd, fsf_req);
 410}
 411
 412/**
 413 * zfcp_dbf_scsi_devreset() - Trace event for Logical Unit or Target Reset.
 414 * @tag: Tag indicating success or failure of reset operation.
 415 * @sdev: Pointer to SCSI device as context for this event.
 416 * @flag: Indicates type of reset (Target Reset, Logical Unit Reset).
 417 * @fsf_req: Pointer to FSF request representing the TMF, or NULL.
 418 */
 419static inline
 420void zfcp_dbf_scsi_devreset(char *tag, struct scsi_device *sdev, u8 flag,
 421                            struct zfcp_fsf_req *fsf_req)
 422{
 423        struct zfcp_adapter *adapter = (struct zfcp_adapter *)
 424                                        sdev->host->hostdata[0];
 425        char tmp_tag[ZFCP_DBF_TAG_LEN];
 426        static int const level = 1;
 427
 428        if (unlikely(!debug_level_enabled(adapter->dbf->scsi, level)))
 429                return;
 430
 431        if (flag == FCP_TMF_TGT_RESET)
 432                memcpy(tmp_tag, "tr_", 3);
 433        else
 434                memcpy(tmp_tag, "lr_", 3);
 435
 436        memcpy(&tmp_tag[3], tag, 4);
 437        zfcp_dbf_scsi_common(tmp_tag, level, sdev, NULL, fsf_req);
 438}
 439
 440/**
 441 * zfcp_dbf_scsi_nullcmnd() - trace NULLify of SCSI command in dev/tgt-reset.
 442 * @scmnd: SCSI command that was NULLified.
 443 * @fsf_req: request that owned @scmnd.
 444 */
 445static inline void zfcp_dbf_scsi_nullcmnd(struct scsi_cmnd *scmnd,
 446                                          struct zfcp_fsf_req *fsf_req)
 447{
 448        _zfcp_dbf_scsi("scfc__1", 3, scmnd, fsf_req);
 449}
 450
 451#endif /* ZFCP_DBF_H */
 452