76 lines · c
1// SPDX-License-Identifier: GPL-2.02#include <linux/bitops.h>3#include <linux/cleanup.h>4#include <linux/seq_file.h>5#include <scsi/scsi_cmnd.h>6#include <scsi/scsi_dbg.h>7#include <scsi/scsi_host.h>8#include "scsi_debugfs.h"9 10#define SCSI_CMD_FLAG_NAME(name)[const_ilog2(SCMD_##name)] = #name11static const char *const scsi_cmd_flags[] = {12 SCSI_CMD_FLAG_NAME(TAGGED),13 SCSI_CMD_FLAG_NAME(INITIALIZED),14 SCSI_CMD_FLAG_NAME(LAST),15};16#undef SCSI_CMD_FLAG_NAME17 18static int scsi_flags_show(struct seq_file *m, const unsigned long flags,19 const char *const *flag_name, int flag_name_count)20{21 bool sep = false;22 int i;23 24 for_each_set_bit(i, &flags, BITS_PER_LONG) {25 if (sep)26 seq_puts(m, "|");27 sep = true;28 if (i < flag_name_count && flag_name[i])29 seq_puts(m, flag_name[i]);30 else31 seq_printf(m, "%d", i);32 }33 return 0;34}35 36static const char *scsi_cmd_list_info(struct scsi_cmnd *cmd)37{38 struct Scsi_Host *shost = cmd->device->host;39 struct scsi_cmnd *cmd2;40 41 guard(spinlock_irq)(shost->host_lock);42 43 list_for_each_entry(cmd2, &shost->eh_abort_list, eh_entry)44 if (cmd == cmd2)45 return "on eh_abort_list";46 47 list_for_each_entry(cmd2, &shost->eh_cmd_q, eh_entry)48 if (cmd == cmd2)49 return "on eh_cmd_q";50 51 return NULL;52}53 54void scsi_show_rq(struct seq_file *m, struct request *rq)55{56 struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq);57 int alloc_ms = jiffies_to_msecs(jiffies - cmd->jiffies_at_alloc);58 int timeout_ms = jiffies_to_msecs(rq->timeout);59 char buf[80] = "(?)";60 61 if (cmd->flags & SCMD_INITIALIZED) {62 const char *list_info = scsi_cmd_list_info(cmd);63 64 __scsi_format_command(buf, sizeof(buf), cmd->cmnd, cmd->cmd_len);65 seq_printf(m, ", .cmd=%s, .retries=%d, .allowed=%d, .result = %#x%s%s",66 buf, cmd->retries, cmd->allowed, cmd->result,67 list_info ? ", " : "", list_info ? : "");68 seq_printf(m, ", .timeout=%d.%03d, allocated %d.%03d s ago",69 timeout_ms / 1000, timeout_ms % 1000,70 alloc_ms / 1000, alloc_ms % 1000);71 }72 seq_printf(m, ", .flags=");73 scsi_flags_show(m, cmd->flags, scsi_cmd_flags,74 ARRAY_SIZE(scsi_cmd_flags));75}76