]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/s390/scsi/zfcp_dbf.c
scsi: zfcp: trace channel log even for FCP command responses
[mirror_ubuntu-bionic-kernel.git] / drivers / s390 / scsi / zfcp_dbf.c
index a8b831000b2d687b9608a9658ac90650c7131b8e..bc6c1d6a1c42e83b3a2169608690cd7854a0c13d 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Debug traces for zfcp.
  *
- * Copyright IBM Corp. 2002, 2017
+ * Copyright IBM Corp. 2002, 2018
  */
 
 #define KMSG_COMPONENT "zfcp"
@@ -94,11 +94,9 @@ void zfcp_dbf_hba_fsf_res(char *tag, int level, struct zfcp_fsf_req *req)
        memcpy(rec->u.res.fsf_status_qual, &q_head->fsf_status_qual,
               FSF_STATUS_QUALIFIER_SIZE);
 
-       if (req->fsf_command != FSF_QTCB_FCP_CMND) {
-               rec->pl_len = q_head->log_length;
-               zfcp_dbf_pl_write(dbf, (char *)q_pref + q_head->log_start,
-                                 rec->pl_len, "fsf_res", req->req_id);
-       }
+       rec->pl_len = q_head->log_length;
+       zfcp_dbf_pl_write(dbf, (char *)q_pref + q_head->log_start,
+                         rec->pl_len, "fsf_res", req->req_id);
 
        debug_event(dbf->hba, level, rec, sizeof(*rec));
        spin_unlock_irqrestore(&dbf->hba_lock, flags);
@@ -285,6 +283,8 @@ void zfcp_dbf_rec_trig(char *tag, struct zfcp_adapter *adapter,
        struct list_head *entry;
        unsigned long flags;
 
+       lockdep_assert_held(&adapter->erp_lock);
+
        if (unlikely(!debug_level_enabled(dbf->rec, level)))
                return;
 
@@ -308,6 +308,27 @@ void zfcp_dbf_rec_trig(char *tag, struct zfcp_adapter *adapter,
        spin_unlock_irqrestore(&dbf->rec_lock, flags);
 }
 
+/**
+ * zfcp_dbf_rec_trig_lock - trace event related to triggered recovery with lock
+ * @tag: identifier for event
+ * @adapter: adapter on which the erp_action should run
+ * @port: remote port involved in the erp_action
+ * @sdev: scsi device involved in the erp_action
+ * @want: wanted erp_action
+ * @need: required erp_action
+ *
+ * The adapter->erp_lock must not be held.
+ */
+void zfcp_dbf_rec_trig_lock(char *tag, struct zfcp_adapter *adapter,
+                           struct zfcp_port *port, struct scsi_device *sdev,
+                           u8 want, u8 need)
+{
+       unsigned long flags;
+
+       read_lock_irqsave(&adapter->erp_lock, flags);
+       zfcp_dbf_rec_trig(tag, adapter, port, sdev, want, need);
+       read_unlock_irqrestore(&adapter->erp_lock, flags);
+}
 
 /**
  * zfcp_dbf_rec_run_lvl - trace event related to running recovery
@@ -643,6 +664,46 @@ void zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *sc,
        spin_unlock_irqrestore(&dbf->scsi_lock, flags);
 }
 
+/**
+ * zfcp_dbf_scsi_eh() - Trace event for special cases of scsi_eh callbacks.
+ * @tag: Identifier for event.
+ * @adapter: Pointer to zfcp adapter as context for this event.
+ * @scsi_id: SCSI ID/target to indicate scope of task management function (TMF).
+ * @ret: Return value of calling function.
+ *
+ * This SCSI trace variant does not depend on any of:
+ * scsi_cmnd, zfcp_fsf_req, scsi_device.
+ */
+void zfcp_dbf_scsi_eh(char *tag, struct zfcp_adapter *adapter,
+                     unsigned int scsi_id, int ret)
+{
+       struct zfcp_dbf *dbf = adapter->dbf;
+       struct zfcp_dbf_scsi *rec = &dbf->scsi_buf;
+       unsigned long flags;
+       static int const level = 1;
+
+       if (unlikely(!debug_level_enabled(adapter->dbf->scsi, level)))
+               return;
+
+       spin_lock_irqsave(&dbf->scsi_lock, flags);
+       memset(rec, 0, sizeof(*rec));
+
+       memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
+       rec->id = ZFCP_DBF_SCSI_CMND;
+       rec->scsi_result = ret; /* re-use field, int is 4 bytes and fits */
+       rec->scsi_retries = ~0;
+       rec->scsi_allowed = ~0;
+       rec->fcp_rsp_info = ~0;
+       rec->scsi_id = scsi_id;
+       rec->scsi_lun = (u32)ZFCP_DBF_INVALID_LUN;
+       rec->scsi_lun_64_hi = (u32)(ZFCP_DBF_INVALID_LUN >> 32);
+       rec->host_scribble = ~0;
+       memset(rec->scsi_opcode, 0xff, ZFCP_DBF_SCSI_OPCODE);
+
+       debug_event(dbf->scsi, level, rec, sizeof(*rec));
+       spin_unlock_irqrestore(&dbf->scsi_lock, flags);
+}
+
 static debug_info_t *zfcp_dbf_reg(const char *name, int size, int rec_size)
 {
        struct debug_info *d;