diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_dbf.h')
-rw-r--r-- | drivers/s390/scsi/zfcp_dbf.h | 175 |
1 files changed, 150 insertions, 25 deletions
diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h index a573f7344dd6..6b1461e8f847 100644 --- a/drivers/s390/scsi/zfcp_dbf.h +++ b/drivers/s390/scsi/zfcp_dbf.h @@ -2,7 +2,7 @@ * This file is part of the zfcp device driver for * FCP adapters for IBM System z9 and zSeries. * - * Copyright IBM Corp. 2008, 2008 + * Copyright IBM Corp. 2008, 2009 * * 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 @@ -22,7 +22,9 @@ #ifndef ZFCP_DBF_H #define ZFCP_DBF_H +#include "zfcp_ext.h" #include "zfcp_fsf.h" +#include "zfcp_def.h" #define ZFCP_DBF_TAG_SIZE 4 #define ZFCP_DBF_ID_SIZE 7 @@ -35,13 +37,13 @@ struct zfcp_dbf_dump { u8 data[]; /* dump data */ } __attribute__ ((packed)); -struct zfcp_rec_dbf_record_thread { +struct zfcp_dbf_rec_record_thread { u32 total; u32 ready; u32 running; }; -struct zfcp_rec_dbf_record_target { +struct zfcp_dbf_rec_record_target { u64 ref; u32 status; u32 d_id; @@ -50,7 +52,7 @@ struct zfcp_rec_dbf_record_target { u32 erp_count; }; -struct zfcp_rec_dbf_record_trigger { +struct zfcp_dbf_rec_record_trigger { u8 want; u8 need; u32 as; @@ -62,21 +64,21 @@ struct zfcp_rec_dbf_record_trigger { u64 fcp_lun; }; -struct zfcp_rec_dbf_record_action { +struct zfcp_dbf_rec_record_action { u32 status; u32 step; u64 action; u64 fsf_req; }; -struct zfcp_rec_dbf_record { +struct zfcp_dbf_rec_record { u8 id; char id2[7]; union { - struct zfcp_rec_dbf_record_action action; - struct zfcp_rec_dbf_record_thread thread; - struct zfcp_rec_dbf_record_target target; - struct zfcp_rec_dbf_record_trigger trigger; + struct zfcp_dbf_rec_record_action action; + struct zfcp_dbf_rec_record_thread thread; + struct zfcp_dbf_rec_record_target target; + struct zfcp_dbf_rec_record_trigger trigger; } u; }; @@ -87,7 +89,7 @@ enum { ZFCP_REC_DBF_ID_TRIGGER, }; -struct zfcp_hba_dbf_record_response { +struct zfcp_dbf_hba_record_response { u32 fsf_command; u64 fsf_reqid; u32 fsf_seqno; @@ -125,7 +127,7 @@ struct zfcp_hba_dbf_record_response { } u; } __attribute__ ((packed)); -struct zfcp_hba_dbf_record_status { +struct zfcp_dbf_hba_record_status { u8 failed; u32 status_type; u32 status_subtype; @@ -139,24 +141,24 @@ struct zfcp_hba_dbf_record_status { u8 payload[ZFCP_DBF_UNSOL_PAYLOAD]; } __attribute__ ((packed)); -struct zfcp_hba_dbf_record_qdio { +struct zfcp_dbf_hba_record_qdio { u32 qdio_error; u8 sbal_index; u8 sbal_count; } __attribute__ ((packed)); -struct zfcp_hba_dbf_record { +struct zfcp_dbf_hba_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; + struct zfcp_dbf_hba_record_response response; + struct zfcp_dbf_hba_record_status status; + struct zfcp_dbf_hba_record_qdio qdio; struct fsf_bit_error_payload berr; } u; } __attribute__ ((packed)); -struct zfcp_san_dbf_record_ct_request { +struct zfcp_dbf_san_record_ct_request { u16 cmd_req_code; u8 revision; u8 gs_type; @@ -166,7 +168,7 @@ struct zfcp_san_dbf_record_ct_request { u32 len; } __attribute__ ((packed)); -struct zfcp_san_dbf_record_ct_response { +struct zfcp_dbf_san_record_ct_response { u16 cmd_rsp_code; u8 revision; u8 reason_code; @@ -176,27 +178,27 @@ struct zfcp_san_dbf_record_ct_response { u32 len; } __attribute__ ((packed)); -struct zfcp_san_dbf_record_els { +struct zfcp_dbf_san_record_els { u8 ls_code; u32 len; } __attribute__ ((packed)); -struct zfcp_san_dbf_record { +struct zfcp_dbf_san_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_request ct_req; - struct zfcp_san_dbf_record_ct_response ct_resp; - struct zfcp_san_dbf_record_els els; + struct zfcp_dbf_san_record_ct_request ct_req; + struct zfcp_dbf_san_record_ct_response ct_resp; + struct zfcp_dbf_san_record_els els; } u; #define ZFCP_DBF_SAN_MAX_PAYLOAD 1024 u8 payload[32]; } __attribute__ ((packed)); -struct zfcp_scsi_dbf_record { +struct zfcp_dbf_scsi_record { u8 tag[ZFCP_DBF_TAG_SIZE]; u8 tag2[ZFCP_DBF_TAG_SIZE]; u32 scsi_id; @@ -222,4 +224,127 @@ struct zfcp_scsi_dbf_record { u8 sns_info[ZFCP_DBF_SCSI_FCP_SNS_INFO]; } __attribute__ ((packed)); +struct zfcp_dbf { + debug_info_t *rec; + debug_info_t *hba; + debug_info_t *san; + debug_info_t *scsi; + spinlock_t rec_lock; + spinlock_t hba_lock; + spinlock_t san_lock; + spinlock_t scsi_lock; + struct zfcp_dbf_rec_record rec_buf; + struct zfcp_dbf_hba_record hba_buf; + struct zfcp_dbf_san_record san_buf; + struct zfcp_dbf_scsi_record scsi_buf; + struct zfcp_adapter *adapter; +}; + +static inline +void zfcp_dbf_hba_fsf_resp(const char *tag2, int level, + struct zfcp_fsf_req *req, struct zfcp_dbf *dbf) +{ + if (level <= dbf->hba->level) + _zfcp_dbf_hba_fsf_response(tag2, level, req, dbf); +} + +/** + * zfcp_dbf_hba_fsf_response - trace event for request completion + * @fsf_req: request that has been completed + */ +static inline void zfcp_dbf_hba_fsf_response(struct zfcp_fsf_req *req) +{ + struct zfcp_dbf *dbf = req->adapter->dbf; + struct fsf_qtcb *qtcb = req->qtcb; + + if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) && + (qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) { + zfcp_dbf_hba_fsf_resp("perr", 1, req, dbf); + + } else if (qtcb->header.fsf_status != FSF_GOOD) { + zfcp_dbf_hba_fsf_resp("ferr", 1, req, dbf); + + } else if ((req->fsf_command == FSF_QTCB_OPEN_PORT_WITH_DID) || + (req->fsf_command == FSF_QTCB_OPEN_LUN)) { + zfcp_dbf_hba_fsf_resp("open", 4, req, dbf); + + } else if (qtcb->header.log_length) { + zfcp_dbf_hba_fsf_resp("qtcb", 5, req, dbf); + + } else { + zfcp_dbf_hba_fsf_resp("norm", 6, req, dbf); + } + } + +/** + * zfcp_dbf_hba_fsf_unsol - trace event for an unsolicited status buffer + * @tag: tag indicating which kind of unsolicited status has been received + * @dbf: reference to dbf structure + * @status_buffer: buffer containing payload of unsolicited status + */ +static inline +void zfcp_dbf_hba_fsf_unsol(const char *tag, struct zfcp_dbf *dbf, + struct fsf_status_read_buffer *buf) +{ + int level = 2; + + if (level <= dbf->hba->level) + _zfcp_dbf_hba_fsf_unsol(tag, level, dbf, buf); +} + +static inline +void zfcp_dbf_scsi(const char *tag, const char *tag2, int level, + struct zfcp_dbf *dbf, struct scsi_cmnd *scmd, + struct zfcp_fsf_req *req, unsigned long old_id) +{ + if (level <= dbf->scsi->level) + _zfcp_dbf_scsi(tag, tag2, level, dbf, scmd, req, old_id); +} + +/** + * zfcp_dbf_scsi_result - trace event for SCSI command completion + * @tag: tag indicating success or failure of SCSI command + * @level: trace level applicable for this event + * @adapter: adapter that has been used to issue the SCSI command + * @scmd: SCSI command pointer + * @fsf_req: request used to issue SCSI command (might be NULL) + */ +static inline +void zfcp_dbf_scsi_result(const char *tag, int level, struct zfcp_dbf *dbf, + struct scsi_cmnd *scmd, struct zfcp_fsf_req *fsf_req) +{ + zfcp_dbf_scsi("rslt", tag, level, dbf, scmd, fsf_req, 0); +} + +/** + * zfcp_dbf_scsi_abort - trace event for SCSI command abort + * @tag: tag indicating success or failure of abort operation + * @adapter: adapter thas has been used to issue SCSI command to be aborted + * @scmd: SCSI command to be aborted + * @new_req: request containing abort (might be NULL) + * @old_id: identifier of request containg SCSI command to be aborted + */ +static inline +void zfcp_dbf_scsi_abort(const char *tag, struct zfcp_dbf *dbf, + struct scsi_cmnd *scmd, struct zfcp_fsf_req *new_req, + unsigned long old_id) +{ + zfcp_dbf_scsi("abrt", tag, 1, dbf, scmd, new_req, old_id); +} + +/** + * zfcp_dbf_scsi_devreset - trace event for Logical Unit or Target Reset + * @tag: tag indicating success or failure of reset operation + * @flag: indicates type of reset (Target Reset, Logical Unit Reset) + * @unit: unit that needs reset + * @scsi_cmnd: SCSI command which caused this error recovery + */ +static inline +void zfcp_dbf_scsi_devreset(const char *tag, u8 flag, struct zfcp_unit *unit, + struct scsi_cmnd *scsi_cmnd) +{ + zfcp_dbf_scsi(flag == FCP_TARGET_RESET ? "trst" : "lrst", tag, 1, + unit->port->adapter->dbf, scsi_cmnd, NULL, 0); +} + #endif /* ZFCP_DBF_H */ |