^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * scsi_logging.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2014 SUSE Linux Products GmbH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2014 Hannes Reinecke <hare@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <scsi/scsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <scsi/scsi_cmnd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <scsi/scsi_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <scsi/scsi_eh.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <scsi/scsi_dbg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static char *scsi_log_reserve_buffer(size_t *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *len = 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) return kmalloc(*len, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static void scsi_log_release_buffer(char *bufptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) kfree(bufptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static inline const char *scmd_name(const struct scsi_cmnd *scmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) return scmd->request->rq_disk ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) scmd->request->rq_disk->disk_name : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static size_t sdev_format_header(char *logbuf, size_t logbuf_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) const char *name, int tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) size_t off = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) off += scnprintf(logbuf + off, logbuf_len - off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) "[%s] ", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (WARN_ON(off >= logbuf_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) return off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if (tag >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) off += scnprintf(logbuf + off, logbuf_len - off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) "tag#%d ", tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) return off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) void sdev_prefix_printk(const char *level, const struct scsi_device *sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) const char *name, const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) char *logbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) size_t off = 0, logbuf_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (!sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) logbuf = scsi_log_reserve_buffer(&logbuf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (!logbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) off += scnprintf(logbuf + off, logbuf_len - off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) "[%s] ", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (!WARN_ON(off >= logbuf_len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) off += vscnprintf(logbuf + off, logbuf_len - off, fmt, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) dev_printk(level, &sdev->sdev_gendev, "%s", logbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) scsi_log_release_buffer(logbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) EXPORT_SYMBOL(sdev_prefix_printk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) void scmd_printk(const char *level, const struct scsi_cmnd *scmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) char *logbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) size_t off = 0, logbuf_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (!scmd || !scmd->cmnd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) logbuf = scsi_log_reserve_buffer(&logbuf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (!logbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) off = sdev_format_header(logbuf, logbuf_len, scmd_name(scmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) scmd->request->tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (off < logbuf_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) off += vscnprintf(logbuf + off, logbuf_len - off, fmt, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) dev_printk(level, &scmd->device->sdev_gendev, "%s", logbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) scsi_log_release_buffer(logbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) EXPORT_SYMBOL(scmd_printk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static size_t scsi_format_opcode_name(char *buffer, size_t buf_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) const unsigned char *cdbp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) int sa, cdb0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) const char *cdb_name = NULL, *sa_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) size_t off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) cdb0 = cdbp[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (cdb0 == VARIABLE_LENGTH_CMD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) int len = scsi_varlen_cdb_length(cdbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (len < 10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) off = scnprintf(buffer, buf_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) "short variable length command, len=%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) sa = (cdbp[8] << 8) + cdbp[9];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) sa = cdbp[1] & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (!scsi_opcode_sa_name(cdb0, sa, &cdb_name, &sa_name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (cdb_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) off = scnprintf(buffer, buf_len, "%s", cdb_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) off = scnprintf(buffer, buf_len, "opcode=0x%x", cdb0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (WARN_ON(off >= buf_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (cdb0 >= VENDOR_SPECIFIC_CDB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) off += scnprintf(buffer + off, buf_len - off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) " (vendor)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) else if (cdb0 >= 0x60 && cdb0 < 0x7e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) off += scnprintf(buffer + off, buf_len - off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) " (reserved)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (sa_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) off = scnprintf(buffer, buf_len, "%s", sa_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) else if (cdb_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) off = scnprintf(buffer, buf_len, "%s, sa=0x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) cdb_name, sa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) off = scnprintf(buffer, buf_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) "opcode=0x%x, sa=0x%x", cdb0, sa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) WARN_ON(off >= buf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) size_t __scsi_format_command(char *logbuf, size_t logbuf_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) const unsigned char *cdb, size_t cdb_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) int len, k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) size_t off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) off = scsi_format_opcode_name(logbuf, logbuf_len, cdb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (off >= logbuf_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) len = scsi_command_size(cdb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (cdb_len < len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) len = cdb_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* print out all bytes in cdb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) for (k = 0; k < len; ++k) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (off > logbuf_len - 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) off += scnprintf(logbuf + off, logbuf_len - off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) " %02x", cdb[k]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) EXPORT_SYMBOL(__scsi_format_command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) void scsi_print_command(struct scsi_cmnd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) int k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) char *logbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) size_t off, logbuf_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (!cmd->cmnd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) logbuf = scsi_log_reserve_buffer(&logbuf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (!logbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) off = sdev_format_header(logbuf, logbuf_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) scmd_name(cmd), cmd->request->tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (off >= logbuf_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) goto out_printk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) off += scnprintf(logbuf + off, logbuf_len - off, "CDB: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (WARN_ON(off >= logbuf_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) goto out_printk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) off += scsi_format_opcode_name(logbuf + off, logbuf_len - off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) cmd->cmnd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (off >= logbuf_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) goto out_printk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /* print out all bytes in cdb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (cmd->cmd_len > 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /* Print opcode in one line and use separate lines for CDB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) off += scnprintf(logbuf + off, logbuf_len - off, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) dev_printk(KERN_INFO, &cmd->device->sdev_gendev, "%s", logbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) for (k = 0; k < cmd->cmd_len; k += 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) size_t linelen = min(cmd->cmd_len - k, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) off = sdev_format_header(logbuf, logbuf_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) scmd_name(cmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) cmd->request->tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (!WARN_ON(off > logbuf_len - 58)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) off += scnprintf(logbuf + off, logbuf_len - off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) "CDB[%02x]: ", k);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) hex_dump_to_buffer(&cmd->cmnd[k], linelen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 16, 1, logbuf + off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) logbuf_len - off, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) dev_printk(KERN_INFO, &cmd->device->sdev_gendev, "%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) logbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (!WARN_ON(off > logbuf_len - 49)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) off += scnprintf(logbuf + off, logbuf_len - off, " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) hex_dump_to_buffer(cmd->cmnd, cmd->cmd_len, 16, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) logbuf + off, logbuf_len - off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) out_printk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) dev_printk(KERN_INFO, &cmd->device->sdev_gendev, "%s", logbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) scsi_log_release_buffer(logbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) EXPORT_SYMBOL(scsi_print_command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static size_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) scsi_format_extd_sense(char *buffer, size_t buf_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) unsigned char asc, unsigned char ascq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) size_t off = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) const char *extd_sense_fmt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) const char *extd_sense_str = scsi_extd_sense_format(asc, ascq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) &extd_sense_fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (extd_sense_str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) off = scnprintf(buffer, buf_len, "Add. Sense: %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) extd_sense_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (extd_sense_fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) off += scnprintf(buffer + off, buf_len - off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) "(%s%x)", extd_sense_fmt, ascq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (asc >= 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) off = scnprintf(buffer, buf_len, "<<vendor>>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) off += scnprintf(buffer + off, buf_len - off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) "ASC=0x%x ", asc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (ascq >= 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) off += scnprintf(buffer + off, buf_len - off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) "<<vendor>>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) off += scnprintf(buffer + off, buf_len - off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) "ASCQ=0x%x ", ascq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) static size_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) scsi_format_sense_hdr(char *buffer, size_t buf_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) const struct scsi_sense_hdr *sshdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) const char *sense_txt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) size_t off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) off = scnprintf(buffer, buf_len, "Sense Key : ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) sense_txt = scsi_sense_key_string(sshdr->sense_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (sense_txt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) off += scnprintf(buffer + off, buf_len - off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) "%s ", sense_txt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) off += scnprintf(buffer + off, buf_len - off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) "0x%x ", sshdr->sense_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) off += scnprintf(buffer + off, buf_len - off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) scsi_sense_is_deferred(sshdr) ? "[deferred] " : "[current] ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (sshdr->response_code >= 0x72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) off += scnprintf(buffer + off, buf_len - off, "[descriptor] ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) scsi_log_dump_sense(const struct scsi_device *sdev, const char *name, int tag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) const unsigned char *sense_buffer, int sense_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) char *logbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) size_t logbuf_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) logbuf = scsi_log_reserve_buffer(&logbuf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (!logbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) for (i = 0; i < sense_len; i += 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) int len = min(sense_len - i, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) size_t off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) off = sdev_format_header(logbuf, logbuf_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) name, tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) hex_dump_to_buffer(&sense_buffer[i], len, 16, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) logbuf + off, logbuf_len - off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) dev_printk(KERN_INFO, &sdev->sdev_gendev, "%s", logbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) scsi_log_release_buffer(logbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) scsi_log_print_sense_hdr(const struct scsi_device *sdev, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) int tag, const struct scsi_sense_hdr *sshdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) char *logbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) size_t off, logbuf_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) logbuf = scsi_log_reserve_buffer(&logbuf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (!logbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) off = sdev_format_header(logbuf, logbuf_len, name, tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) off += scsi_format_sense_hdr(logbuf + off, logbuf_len - off, sshdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) dev_printk(KERN_INFO, &sdev->sdev_gendev, "%s", logbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) scsi_log_release_buffer(logbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) logbuf = scsi_log_reserve_buffer(&logbuf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (!logbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) off = sdev_format_header(logbuf, logbuf_len, name, tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) off += scsi_format_extd_sense(logbuf + off, logbuf_len - off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) sshdr->asc, sshdr->ascq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) dev_printk(KERN_INFO, &sdev->sdev_gendev, "%s", logbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) scsi_log_release_buffer(logbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) scsi_log_print_sense(const struct scsi_device *sdev, const char *name, int tag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) const unsigned char *sense_buffer, int sense_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct scsi_sense_hdr sshdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (scsi_normalize_sense(sense_buffer, sense_len, &sshdr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) scsi_log_print_sense_hdr(sdev, name, tag, &sshdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) scsi_log_dump_sense(sdev, name, tag, sense_buffer, sense_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * Print normalized SCSI sense header with a prefix.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) scsi_print_sense_hdr(const struct scsi_device *sdev, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) const struct scsi_sense_hdr *sshdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) scsi_log_print_sense_hdr(sdev, name, -1, sshdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) EXPORT_SYMBOL(scsi_print_sense_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) /* Normalize and print sense buffer with name prefix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) void __scsi_print_sense(const struct scsi_device *sdev, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) const unsigned char *sense_buffer, int sense_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) scsi_log_print_sense(sdev, name, -1, sense_buffer, sense_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) EXPORT_SYMBOL(__scsi_print_sense);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) /* Normalize and print sense buffer in SCSI command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) void scsi_print_sense(const struct scsi_cmnd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) scsi_log_print_sense(cmd->device, scmd_name(cmd), cmd->request->tag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) EXPORT_SYMBOL(scsi_print_sense);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) void scsi_print_result(const struct scsi_cmnd *cmd, const char *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) int disposition)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) char *logbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) size_t off, logbuf_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) const char *mlret_string = scsi_mlreturn_string(disposition);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) const char *hb_string = scsi_hostbyte_string(cmd->result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) const char *db_string = scsi_driverbyte_string(cmd->result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) unsigned long cmd_age = (jiffies - cmd->jiffies_at_alloc) / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) logbuf = scsi_log_reserve_buffer(&logbuf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (!logbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) off = sdev_format_header(logbuf, logbuf_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) scmd_name(cmd), cmd->request->tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (off >= logbuf_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) goto out_printk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (msg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) off += scnprintf(logbuf + off, logbuf_len - off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) "%s: ", msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (WARN_ON(off >= logbuf_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) goto out_printk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (mlret_string)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) off += scnprintf(logbuf + off, logbuf_len - off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) "%s ", mlret_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) off += scnprintf(logbuf + off, logbuf_len - off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) "UNKNOWN(0x%02x) ", disposition);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (WARN_ON(off >= logbuf_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) goto out_printk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) off += scnprintf(logbuf + off, logbuf_len - off, "Result: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (WARN_ON(off >= logbuf_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) goto out_printk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (hb_string)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) off += scnprintf(logbuf + off, logbuf_len - off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) "hostbyte=%s ", hb_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) off += scnprintf(logbuf + off, logbuf_len - off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) "hostbyte=0x%02x ", host_byte(cmd->result));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (WARN_ON(off >= logbuf_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) goto out_printk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (db_string)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) off += scnprintf(logbuf + off, logbuf_len - off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) "driverbyte=%s ", db_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) off += scnprintf(logbuf + off, logbuf_len - off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) "driverbyte=0x%02x ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) driver_byte(cmd->result));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) off += scnprintf(logbuf + off, logbuf_len - off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) "cmd_age=%lus", cmd_age);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) out_printk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) dev_printk(KERN_INFO, &cmd->device->sdev_gendev, "%s", logbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) scsi_log_release_buffer(logbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) EXPORT_SYMBOL(scsi_print_result);