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