/* SPDX-License-Identifier: GPL-2.0 */
/*
* zfcp device driver
* debug feature declarations
*
* Copyright IBM Corp . 2008 , 2020
*/
#ifndef ZFCP_DBF_H
#define ZFCP_DBF_H
#include <scsi/fc/fc_fcp.h>
#include "zfcp_ext.h"
#include "zfcp_fsf.h"
#include "zfcp_def.h"
#define ZFCP_DBF_TAG_LEN 7
#define ZFCP_DBF_INVALID_WWPN 0 x0000000000000000ull
#define ZFCP_DBF_INVALID_LUN 0 xFFFFFFFFFFFFFFFFull
enum zfcp_dbf_pseudo_erp_act_type {
ZFCP_PSEUDO_ERP_ACTION_RPORT_ADD = 0 xff,
ZFCP_PSEUDO_ERP_ACTION_RPORT_DEL = 0 xfe,
};
/**
* struct zfcp_dbf_rec_trigger - trace record for triggered recovery action
* @ ready : number of ready recovery actions
* @ running : number of running recovery actions
* @ want : wanted recovery action
* @ need : needed recovery action
*/
struct zfcp_dbf_rec_trigger {
u32 ready;
u32 running;
u8 want;
u8 need;
} __packed;
/**
* struct zfcp_dbf_rec_running - trace record for running recovery
* @ fsf_req_id : request id for fsf requests
* @ rec_status : status of the fsf request
* @ rec_step : current step of the recovery action
* @ rec_action : ERP action type
* @ rec_count : recoveries including retries for particular @ rec_action
*/
struct zfcp_dbf_rec_running {
u64 fsf_req_id;
u32 rec_status;
u16 rec_step;
u8 rec_action;
u8 rec_count;
} __packed;
/**
* enum zfcp_dbf_rec_id - recovery trace record id
* @ ZFCP_DBF_REC_TRIG : triggered recovery identifier
* @ ZFCP_DBF_REC_RUN : running recovery identifier
*/
enum zfcp_dbf_rec_id {
ZFCP_DBF_REC_TRIG = 1 ,
ZFCP_DBF_REC_RUN = 2 ,
};
/**
* struct zfcp_dbf_rec - trace record for error recovery actions
* @ id : unique number of recovery record type
* @ tag : identifier string specifying the location of initiation
* @ lun : logical unit number
* @ wwpn : word wide port number
* @ d_id : destination ID
* @ adapter_status : current status of the adapter
* @ port_status : current status of the port
* @ lun_status : current status of the lun
* @ u : record type specific data
* @ u . trig : structure zfcp_dbf_rec_trigger
* @ u . run : structure zfcp_dbf_rec_running
*/
struct zfcp_dbf_rec {
u8 id;
char tag[ZFCP_DBF_TAG_LEN];
u64 lun;
u64 wwpn;
u32 d_id;
u32 adapter_status;
u32 port_status;
u32 lun_status;
union {
struct zfcp_dbf_rec_trigger trig;
struct zfcp_dbf_rec_running run;
} u;
} __packed;
/**
* enum zfcp_dbf_san_id - SAN trace record identifier
* @ ZFCP_DBF_SAN_REQ : request trace record id
* @ ZFCP_DBF_SAN_RES : response trace record id
* @ ZFCP_DBF_SAN_ELS : extended link service record id
*/
enum zfcp_dbf_san_id {
ZFCP_DBF_SAN_REQ = 1 ,
ZFCP_DBF_SAN_RES = 2 ,
ZFCP_DBF_SAN_ELS = 3 ,
};
/** struct zfcp_dbf_san - trace record for SAN requests and responses
* @ id : unique number of recovery record type
* @ tag : identifier string specifying the location of initiation
* @ fsf_req_id : request id for fsf requests
* @ payload : unformatted information related to request / response
* @ d_id : destination id
*/
struct zfcp_dbf_san {
u8 id;
char tag[ZFCP_DBF_TAG_LEN];
u64 fsf_req_id;
u32 d_id;
#define ZFCP_DBF_SAN_MAX_PAYLOAD (FC_CT_HDR_LEN + 32 )
char payload[ZFCP_DBF_SAN_MAX_PAYLOAD];
u16 pl_len;
} __packed;
/**
* struct zfcp_dbf_hba_res - trace record for hba responses
* @ req_issued : timestamp when request was issued
* @ prot_status : protocol status
* @ prot_status_qual : protocol status qualifier
* @ fsf_status : fsf status
* @ fsf_status_qual : fsf status qualifier
* @ port_handle : handle for port
* @ lun_handle : handle for LUN
*/
struct zfcp_dbf_hba_res {
u64 req_issued;
u32 prot_status;
u8 prot_status_qual[FSF_PROT_STATUS_QUAL_SIZE];
u32 fsf_status;
u8 fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE];
u32 port_handle;
u32 lun_handle;
} __packed;
/**
* struct zfcp_dbf_hba_uss - trace record for unsolicited status
* @ status_type : type of unsolicited status
* @ status_subtype : subtype of unsolicited status
* @ d_id : destination ID
* @ lun : logical unit number
* @ queue_designator : queue designator
*/
struct zfcp_dbf_hba_uss {
u32 status_type;
u32 status_subtype;
u32 d_id;
u64 lun;
u64 queue_designator;
} __packed;
/**
* struct zfcp_dbf_hba_fces - trace record for FC Endpoint Security
* @ req_issued : timestamp when request was issued
* @ fsf_status : fsf status
* @ port_handle : handle for port
* @ wwpn : remote FC port WWPN
* @ fc_security_old : old FC Endpoint Security
* @ fc_security_new : new FC Endpoint Security
*
*/
struct zfcp_dbf_hba_fces {
u64 req_issued;
u32 fsf_status;
u32 port_handle;
u64 wwpn;
u32 fc_security_old;
u32 fc_security_new;
} __packed;
/**
* enum zfcp_dbf_hba_id - HBA trace record identifier
* @ ZFCP_DBF_HBA_RES : response trace record
* @ ZFCP_DBF_HBA_USS : unsolicited status trace record
* @ ZFCP_DBF_HBA_BIT : bit error trace record
* @ ZFCP_DBF_HBA_BASIC : basic adapter event , only trace tag , no other data
* @ ZFCP_DBF_HBA_FCES : FC Endpoint Security trace record
*/
enum zfcp_dbf_hba_id {
ZFCP_DBF_HBA_RES = 1 ,
ZFCP_DBF_HBA_USS = 2 ,
ZFCP_DBF_HBA_BIT = 3 ,
ZFCP_DBF_HBA_BASIC = 4 ,
ZFCP_DBF_HBA_FCES = 5 ,
};
/**
* struct zfcp_dbf_hba - common trace record for HBA records
* @ id : unique number of recovery record type
* @ tag : identifier string specifying the location of initiation
* @ fsf_req_id : request id for fsf requests
* @ fsf_req_status : status of fsf request
* @ fsf_cmd : fsf command
* @ fsf_seq_no : fsf sequence number
* @ pl_len : length of payload stored as zfcp_dbf_pay
* @ u : record type specific data
* @ u . res : data for fsf responses
* @ u . uss : data for unsolicited status buffer
* @ u . be : data for bit error unsolicited status buffer
* @ u . fces : data for FC Endpoint Security
*/
struct zfcp_dbf_hba {
u8 id;
char tag[ZFCP_DBF_TAG_LEN];
u64 fsf_req_id;
u32 fsf_req_status;
u32 fsf_cmd;
u32 fsf_seq_no;
u16 pl_len;
union {
struct zfcp_dbf_hba_res res;
struct zfcp_dbf_hba_uss uss;
struct fsf_bit_error_payload be;
struct zfcp_dbf_hba_fces fces;
} u;
} __packed;
/**
* enum zfcp_dbf_scsi_id - scsi trace record identifier
* @ ZFCP_DBF_SCSI_CMND : scsi command trace record
*/
enum zfcp_dbf_scsi_id {
ZFCP_DBF_SCSI_CMND = 1 ,
};
/**
* struct zfcp_dbf_scsi - common trace record for SCSI records
* @ id : unique number of recovery record type
* @ tag : identifier string specifying the location of initiation
* @ scsi_id : scsi device id
* @ scsi_lun : scsi device logical unit number , low part of 64 bit , old 32 bit
* @ scsi_result : scsi result
* @ scsi_retries : current retry number of scsi request
* @ scsi_allowed : allowed retries
* @ fcp_rsp_info : FCP response info code
* @ scsi_opcode : scsi opcode
* @ fsf_req_id : request id of fsf request
* @ host_scribble : LLD specific data attached to SCSI request
* @ pl_len : length of payload stored as zfcp_dbf_pay
* @ fcp_rsp : response for FCP request
* @ scsi_lun_64_hi : scsi device logical unit number , high part of 64 bit
*/
struct zfcp_dbf_scsi {
u8 id;
char tag[ZFCP_DBF_TAG_LEN];
u32 scsi_id;
u32 scsi_lun;
u32 scsi_result;
u8 scsi_retries;
u8 scsi_allowed;
u8 fcp_rsp_info;
#define ZFCP_DBF_SCSI_OPCODE 16
u8 scsi_opcode[ZFCP_DBF_SCSI_OPCODE];
u64 fsf_req_id;
u64 host_scribble;
u16 pl_len;
struct fcp_resp_with_ext fcp_rsp;
u32 scsi_lun_64_hi;
} __packed;
/**
* struct zfcp_dbf_pay - trace record for unformatted payload information
* @ area : area this record is originated from
* @ counter : ascending record number
* @ fsf_req_id : request id of fsf request
* @ data : unformatted data
*/
struct zfcp_dbf_pay {
u8 counter;
char area[ZFCP_DBF_TAG_LEN];
u64 fsf_req_id;
#define ZFCP_DBF_PAY_MAX_REC 0 x100
char data[ZFCP_DBF_PAY_MAX_REC];
} __packed;
/**
* struct zfcp_dbf - main dbf trace structure
* @ pay : reference to payload trace area
* @ rec : reference to recovery trace area
* @ hba : reference to hba trace area
* @ san : reference to san trace area
* @ scsi : reference to scsi trace area
* @ pay_lock : lock protecting payload trace buffer
* @ rec_lock : lock protecting recovery trace buffer
* @ hba_lock : lock protecting hba trace buffer
* @ san_lock : lock protecting san trace buffer
* @ scsi_lock : lock protecting scsi trace buffer
* @ pay_buf : pre - allocated buffer for payload
* @ rec_buf : pre - allocated buffer for recovery
* @ hba_buf : pre - allocated buffer for hba
* @ san_buf : pre - allocated buffer for san
* @ scsi_buf : pre - allocated buffer for scsi
*/
struct zfcp_dbf {
debug_info_t *pay;
debug_info_t *rec;
debug_info_t *hba;
debug_info_t *san;
debug_info_t *scsi;
spinlock_t pay_lock;
spinlock_t rec_lock;
spinlock_t hba_lock;
spinlock_t san_lock;
spinlock_t scsi_lock;
struct zfcp_dbf_pay pay_buf;
struct zfcp_dbf_rec rec_buf;
struct zfcp_dbf_hba hba_buf;
struct zfcp_dbf_san san_buf;
struct zfcp_dbf_scsi scsi_buf;
};
/**
* zfcp_dbf_hba_fsf_resp_suppress - true if we should not trace by default
* @ req : request that has been completed
*
* Returns true if FCP response with only benign residual under count .
*/
static inline
bool zfcp_dbf_hba_fsf_resp_suppress(struct zfcp_fsf_req *req)
{
struct fsf_qtcb *qtcb = req->qtcb;
u32 fsf_stat = qtcb->header.fsf_status;
struct fcp_resp *fcp_rsp;
u8 rsp_flags, fr_status;
if (qtcb->prefix.qtcb_type != FSF_IO_COMMAND)
return false ; /* not an FCP response */
fcp_rsp = &qtcb->bottom.io.fcp_rsp.iu.resp;
rsp_flags = fcp_rsp->fr_flags;
fr_status = fcp_rsp->fr_status;
return (fsf_stat == FSF_FCP_RSP_AVAILABLE) &&
(rsp_flags == FCP_RESID_UNDER) &&
(fr_status == SAM_STAT_GOOD);
}
static inline
void zfcp_dbf_hba_fsf_resp(char *tag, int level, struct zfcp_fsf_req *req)
{
if (debug_level_enabled(req->adapter->dbf->hba, level))
zfcp_dbf_hba_fsf_res(tag, level, req);
}
/**
* zfcp_dbf_hba_fsf_response - trace event for request completion
* @ req : request that has been completed
*/
static inline
void zfcp_dbf_hba_fsf_response(struct zfcp_fsf_req *req)
{
struct fsf_qtcb *qtcb = req->qtcb;
if (unlikely(req->status & (ZFCP_STATUS_FSFREQ_DISMISSED |
ZFCP_STATUS_FSFREQ_ERROR))) {
zfcp_dbf_hba_fsf_resp("fs_rerr" , 3 , req);
} else if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) &&
(qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) {
zfcp_dbf_hba_fsf_resp("fs_perr" , 1 , req);
} else if (qtcb->header.fsf_status != FSF_GOOD) {
zfcp_dbf_hba_fsf_resp("fs_ferr" ,
zfcp_dbf_hba_fsf_resp_suppress(req)
? 5 : 1 , req);
} else if ((qtcb->header.fsf_command == FSF_QTCB_OPEN_PORT_WITH_DID) ||
(qtcb->header.fsf_command == FSF_QTCB_OPEN_LUN)) {
zfcp_dbf_hba_fsf_resp("fs_open" , 4 , req);
} else if (qtcb->header.log_length) {
zfcp_dbf_hba_fsf_resp("fs_qtcb" , 5 , req);
} else {
zfcp_dbf_hba_fsf_resp("fs_norm" , 6 , req);
}
}
static inline
void _zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *scmd,
struct zfcp_fsf_req *req)
{
struct zfcp_adapter *adapter = (struct zfcp_adapter *)
scmd->device->host->hostdata[0 ];
if (debug_level_enabled(adapter->dbf->scsi, level))
zfcp_dbf_scsi_common(tag, level, scmd->device, scmd, req);
}
/**
* zfcp_dbf_scsi_result - trace event for SCSI command completion
* @ scmd : SCSI command pointer
* @ req : FSF request used to issue SCSI command
*/
static inline
void zfcp_dbf_scsi_result(struct scsi_cmnd *scmd, struct zfcp_fsf_req *req)
{
if (scmd->result != 0 )
_zfcp_dbf_scsi("rsl_err" , 3 , scmd, req);
else if (scmd->retries > 0 )
_zfcp_dbf_scsi("rsl_ret" , 4 , scmd, req);
else
_zfcp_dbf_scsi("rsl_nor" , 6 , scmd, req);
}
/**
* zfcp_dbf_scsi_fail_send - trace event for failure to send SCSI command
* @ scmd : SCSI command pointer
*/
static inline
void zfcp_dbf_scsi_fail_send(struct scsi_cmnd *scmd)
{
_zfcp_dbf_scsi("rsl_fai" , 4 , scmd, NULL);
}
/**
* zfcp_dbf_scsi_abort - trace event for SCSI command abort
* @ tag : tag indicating success or failure of abort operation
* @ scmd : SCSI command to be aborted
* @ fsf_req : request containing abort ( might be NULL )
*/
static inline
void zfcp_dbf_scsi_abort(char *tag, struct scsi_cmnd *scmd,
struct zfcp_fsf_req *fsf_req)
{
_zfcp_dbf_scsi(tag, 1 , scmd, fsf_req);
}
/**
* zfcp_dbf_scsi_devreset ( ) - Trace event for Logical Unit or Target Reset .
* @ tag : Tag indicating success or failure of reset operation .
* @ sdev : Pointer to SCSI device as context for this event .
* @ flag : Indicates type of reset ( Target Reset , Logical Unit Reset ) .
* @ fsf_req : Pointer to FSF request representing the TMF , or NULL .
*/
static inline
void zfcp_dbf_scsi_devreset(char *tag, struct scsi_device *sdev, u8 flag,
struct zfcp_fsf_req *fsf_req)
{
struct zfcp_adapter *adapter = (struct zfcp_adapter *)
sdev->host->hostdata[0 ];
char tmp_tag[ZFCP_DBF_TAG_LEN];
static int const level = 1 ;
if (unlikely(!debug_level_enabled(adapter->dbf->scsi, level)))
return ;
if (flag == FCP_TMF_TGT_RESET)
memcpy(tmp_tag, "tr_" , 3 );
else
memcpy(tmp_tag, "lr_" , 3 );
memcpy(&tmp_tag[3 ], tag, 4 );
zfcp_dbf_scsi_common(tmp_tag, level, sdev, NULL, fsf_req);
}
/**
* zfcp_dbf_scsi_nullcmnd ( ) - trace NULLify of SCSI command in dev / tgt - reset .
* @ scmnd : SCSI command that was NULLified .
* @ fsf_req : request that owned @ scmnd .
*/
static inline void zfcp_dbf_scsi_nullcmnd(struct scsi_cmnd *scmnd,
struct zfcp_fsf_req *fsf_req)
{
_zfcp_dbf_scsi("scfc__1" , 3 , scmnd, fsf_req);
}
#endif /* ZFCP_DBF_H */
Messung V0.5 in Prozent C=95 H=100 G=97
¤ Dauer der Verarbeitung: 0.17 Sekunden
(vorverarbeitet am 2026-09-28)
¤
*© Formatika GbR, Deutschland