Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull more SCSI updates from James Bottomley:
"Mostly small bug fixes and small updates.

The only things of note is a qla2xxx fix for crash on hotplug and
timeout and the addition of a user exposed abstraction layer for
persistent reservation error return handling (which necessitates the
conversion of nvme.c as well as SCSI)"

* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
scsi: qla2xxx: Fix crash when I/O abort times out
nvme: Convert NVMe errors to PR errors
scsi: sd: Convert SCSI errors to PR errors
scsi: core: Rename status_byte to sg_status_byte
block: Add error codes for common PR failures
scsi: sd: sd_zbc: Trace zone append emulation
scsi: libfc: Include the correct header

+187 -11
+31 -2
drivers/nvme/host/core.c
··· 2117 2117 return nvme_submit_sync_cmd(ns->queue, c, data, 16); 2118 2118 } 2119 2119 2120 + static int nvme_sc_to_pr_err(int nvme_sc) 2121 + { 2122 + if (nvme_is_path_error(nvme_sc)) 2123 + return PR_STS_PATH_FAILED; 2124 + 2125 + switch (nvme_sc) { 2126 + case NVME_SC_SUCCESS: 2127 + return PR_STS_SUCCESS; 2128 + case NVME_SC_RESERVATION_CONFLICT: 2129 + return PR_STS_RESERVATION_CONFLICT; 2130 + case NVME_SC_ONCS_NOT_SUPPORTED: 2131 + return -EOPNOTSUPP; 2132 + case NVME_SC_BAD_ATTRIBUTES: 2133 + case NVME_SC_INVALID_OPCODE: 2134 + case NVME_SC_INVALID_FIELD: 2135 + case NVME_SC_INVALID_NS: 2136 + return -EINVAL; 2137 + default: 2138 + return PR_STS_IOERR; 2139 + } 2140 + } 2141 + 2120 2142 static int nvme_pr_command(struct block_device *bdev, u32 cdw10, 2121 2143 u64 key, u64 sa_key, u8 op) 2122 2144 { 2123 2145 struct nvme_command c = { }; 2124 2146 u8 data[16] = { 0, }; 2147 + int ret; 2125 2148 2126 2149 put_unaligned_le64(key, &data[0]); 2127 2150 put_unaligned_le64(sa_key, &data[8]); ··· 2154 2131 2155 2132 if (IS_ENABLED(CONFIG_NVME_MULTIPATH) && 2156 2133 bdev->bd_disk->fops == &nvme_ns_head_ops) 2157 - return nvme_send_ns_head_pr_command(bdev, &c, data); 2158 - return nvme_send_ns_pr_command(bdev->bd_disk->private_data, &c, data); 2134 + ret = nvme_send_ns_head_pr_command(bdev, &c, data); 2135 + else 2136 + ret = nvme_send_ns_pr_command(bdev->bd_disk->private_data, &c, 2137 + data); 2138 + if (ret < 0) 2139 + return ret; 2140 + 2141 + return nvme_sc_to_pr_err(ret); 2159 2142 } 2160 2143 2161 2144 static int nvme_pr_register(struct block_device *bdev, u64 old,
+1 -1
drivers/scsi/libfc/fc_disc.c
··· 24 24 #include <linux/slab.h> 25 25 #include <linux/err.h> 26 26 #include <linux/export.h> 27 - #include <linux/rculist.h> 27 + #include <linux/list.h> 28 28 29 29 #include <asm/unaligned.h> 30 30
+10 -4
drivers/scsi/qla2xxx/qla_init.c
··· 110 110 struct qla_qpair *qpair = sp->qpair; 111 111 u32 handle; 112 112 unsigned long flags; 113 + int sp_found = 0, cmdsp_found = 0; 113 114 114 115 if (sp->cmd_sp) 115 116 ql_dbg(ql_dbg_async, sp->vha, 0x507c, ··· 125 124 spin_lock_irqsave(qpair->qp_lock_ptr, flags); 126 125 for (handle = 1; handle < qpair->req->num_outstanding_cmds; handle++) { 127 126 if (sp->cmd_sp && (qpair->req->outstanding_cmds[handle] == 128 - sp->cmd_sp)) 127 + sp->cmd_sp)) { 129 128 qpair->req->outstanding_cmds[handle] = NULL; 129 + cmdsp_found = 1; 130 + } 130 131 131 132 /* removing the abort */ 132 133 if (qpair->req->outstanding_cmds[handle] == sp) { 133 134 qpair->req->outstanding_cmds[handle] = NULL; 135 + sp_found = 1; 134 136 break; 135 137 } 136 138 } 137 139 spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); 138 140 139 - if (sp->cmd_sp) { 141 + if (cmdsp_found && sp->cmd_sp) { 140 142 /* 141 143 * This done function should take care of 142 144 * original command ref: INIT ··· 147 143 sp->cmd_sp->done(sp->cmd_sp, QLA_OS_TIMER_EXPIRED); 148 144 } 149 145 150 - abt->u.abt.comp_status = cpu_to_le16(CS_TIMEOUT); 151 - sp->done(sp, QLA_OS_TIMER_EXPIRED); 146 + if (sp_found) { 147 + abt->u.abt.comp_status = cpu_to_le16(CS_TIMEOUT); 148 + sp->done(sp, QLA_OS_TIMER_EXPIRED); 149 + } 152 150 } 153 151 154 152 static void qla24xx_abort_sp_done(srb_t *sp, int res)
+1 -1
drivers/scsi/scsi_ioctl.c
··· 376 376 * fill in all the output members 377 377 */ 378 378 hdr->status = scmd->result & 0xff; 379 - hdr->masked_status = status_byte(scmd->result); 379 + hdr->masked_status = sg_status_byte(scmd->result); 380 380 hdr->msg_status = COMMAND_COMPLETE; 381 381 hdr->host_status = host_byte(scmd->result); 382 382 hdr->driver_status = 0;
+34 -1
drivers/scsi/sd.c
··· 1709 1709 } 1710 1710 }; 1711 1711 1712 + static int sd_scsi_to_pr_err(struct scsi_sense_hdr *sshdr, int result) 1713 + { 1714 + switch (host_byte(result)) { 1715 + case DID_TRANSPORT_MARGINAL: 1716 + case DID_TRANSPORT_DISRUPTED: 1717 + case DID_BUS_BUSY: 1718 + return PR_STS_RETRY_PATH_FAILURE; 1719 + case DID_NO_CONNECT: 1720 + return PR_STS_PATH_FAILED; 1721 + case DID_TRANSPORT_FAILFAST: 1722 + return PR_STS_PATH_FAST_FAILED; 1723 + } 1724 + 1725 + switch (status_byte(result)) { 1726 + case SAM_STAT_RESERVATION_CONFLICT: 1727 + return PR_STS_RESERVATION_CONFLICT; 1728 + case SAM_STAT_CHECK_CONDITION: 1729 + if (!scsi_sense_valid(sshdr)) 1730 + return PR_STS_IOERR; 1731 + 1732 + if (sshdr->sense_key == ILLEGAL_REQUEST && 1733 + (sshdr->asc == 0x26 || sshdr->asc == 0x24)) 1734 + return -EINVAL; 1735 + 1736 + fallthrough; 1737 + default: 1738 + return PR_STS_IOERR; 1739 + } 1740 + } 1741 + 1712 1742 static int sd_pr_command(struct block_device *bdev, u8 sa, 1713 1743 u64 key, u64 sa_key, u8 type, u8 flags) 1714 1744 { ··· 1767 1737 scsi_print_sense_hdr(sdev, NULL, &sshdr); 1768 1738 } 1769 1739 1770 - return result; 1740 + if (result <= 0) 1741 + return result; 1742 + 1743 + return sd_scsi_to_pr_err(&sshdr, result); 1771 1744 } 1772 1745 1773 1746 static int sd_pr_register(struct block_device *bdev, u64 old_key, u64 new_key,
+84
drivers/scsi/sd_trace.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (C) 2022 Western Digital Corporation or its affiliates. 4 + */ 5 + #undef TRACE_SYSTEM 6 + #define TRACE_SYSTEM sd 7 + 8 + #undef TRACE_INCLUDE_FILE 9 + #define TRACE_INCLUDE_FILE sd_trace 10 + 11 + #if !defined(_SD_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) 12 + #include <scsi/scsi_cmnd.h> 13 + #include <scsi/scsi_host.h> 14 + #include <linux/tracepoint.h> 15 + 16 + TRACE_EVENT(scsi_prepare_zone_append, 17 + 18 + TP_PROTO(struct scsi_cmnd *cmnd, sector_t lba, 19 + unsigned int wp_offset), 20 + 21 + TP_ARGS(cmnd, lba, wp_offset), 22 + 23 + TP_STRUCT__entry( 24 + __field( unsigned int, host_no ) 25 + __field( unsigned int, channel ) 26 + __field( unsigned int, id ) 27 + __field( unsigned int, lun ) 28 + __field( sector_t, lba ) 29 + __field( unsigned int, wp_offset ) 30 + ), 31 + 32 + TP_fast_assign( 33 + __entry->host_no = cmnd->device->host->host_no; 34 + __entry->channel = cmnd->device->channel; 35 + __entry->id = cmnd->device->id; 36 + __entry->lun = cmnd->device->lun; 37 + __entry->lba = lba; 38 + __entry->wp_offset = wp_offset; 39 + ), 40 + 41 + TP_printk("host_no=%u, channel=%u id=%u lun=%u lba=%llu wp_offset=%u", 42 + __entry->host_no, __entry->channel, __entry->id, 43 + __entry->lun, __entry->lba, __entry->wp_offset) 44 + ); 45 + 46 + TRACE_EVENT(scsi_zone_wp_update, 47 + 48 + TP_PROTO(struct scsi_cmnd *cmnd, sector_t rq_sector, 49 + unsigned int wp_offset, unsigned int good_bytes), 50 + 51 + TP_ARGS(cmnd, rq_sector, wp_offset, good_bytes), 52 + 53 + TP_STRUCT__entry( 54 + __field( unsigned int, host_no ) 55 + __field( unsigned int, channel ) 56 + __field( unsigned int, id ) 57 + __field( unsigned int, lun ) 58 + __field( sector_t, rq_sector ) 59 + __field( unsigned int, wp_offset ) 60 + __field( unsigned int, good_bytes ) 61 + ), 62 + 63 + TP_fast_assign( 64 + __entry->host_no = cmnd->device->host->host_no; 65 + __entry->channel = cmnd->device->channel; 66 + __entry->id = cmnd->device->id; 67 + __entry->lun = cmnd->device->lun; 68 + __entry->rq_sector = rq_sector; 69 + __entry->wp_offset = wp_offset; 70 + __entry->good_bytes = good_bytes; 71 + ), 72 + 73 + TP_printk("host_no=%u, channel=%u id=%u lun=%u rq_sector=%llu" \ 74 + " wp_offset=%u good_bytes=%u", 75 + __entry->host_no, __entry->channel, __entry->id, 76 + __entry->lun, __entry->rq_sector, __entry->wp_offset, 77 + __entry->good_bytes) 78 + ); 79 + #endif /* _SD_TRACE_H */ 80 + 81 + /* This part must be outside protection */ 82 + #undef TRACE_INCLUDE_PATH 83 + #define TRACE_INCLUDE_PATH ../../drivers/scsi 84 + #include <trace/define_trace.h>
+6
drivers/scsi/sd_zbc.c
··· 20 20 21 21 #include "sd.h" 22 22 23 + #define CREATE_TRACE_POINTS 24 + #include "sd_trace.h" 25 + 23 26 /** 24 27 * sd_zbc_get_zone_wp_offset - Get zone write pointer offset. 25 28 * @zone: Zone for which to return the write pointer offset. ··· 453 450 break; 454 451 } 455 452 453 + trace_scsi_prepare_zone_append(cmd, *lba, wp_offset); 456 454 *lba += wp_offset; 457 455 } 458 456 spin_unlock_irqrestore(&sdkp->zones_wp_offset_lock, flags); ··· 562 558 563 559 switch (op) { 564 560 case REQ_OP_ZONE_APPEND: 561 + trace_scsi_zone_wp_update(cmd, rq->__sector, 562 + sdkp->zones_wp_offset[zno], good_bytes); 565 563 rq->__sector += sdkp->zones_wp_offset[zno]; 566 564 fallthrough; 567 565 case REQ_OP_WRITE_ZEROES:
+1 -1
drivers/scsi/sg.c
··· 1349 1349 struct scsi_sense_hdr sshdr; 1350 1350 1351 1351 srp->header.status = 0xff & result; 1352 - srp->header.masked_status = status_byte(result); 1352 + srp->header.masked_status = sg_status_byte(result); 1353 1353 srp->header.msg_status = COMMAND_COMPLETE; 1354 1354 srp->header.host_status = host_byte(result); 1355 1355 srp->header.driver_status = driver_byte(result);
+1
include/scsi/scsi.h
··· 121 121 * msg_byte (unused) 122 122 * host_byte = set by low-level driver to indicate status. 123 123 */ 124 + #define status_byte(result) (result & 0xff) 124 125 #define host_byte(result) (((result) >> 16) & 0xff) 125 126 126 127 #define sense_class(sense) (((sense) >> 4) & 0x7)
+1 -1
include/scsi/sg.h
··· 159 159 #define TASK_ABORTED 0x20 160 160 161 161 /* Obsolete status_byte() declaration */ 162 - #define status_byte(result) (((result) >> 1) & 0x7f) 162 + #define sg_status_byte(result) (((result) >> 1) & 0x7f) 163 163 164 164 typedef struct sg_scsi_id { /* used by SG_GET_SCSI_ID ioctl() */ 165 165 int host_no; /* as in "scsi<n>" where 'n' is one of 0, 1, 2 etc */
+17
include/uapi/linux/pr.h
··· 4 4 5 5 #include <linux/types.h> 6 6 7 + enum pr_status { 8 + PR_STS_SUCCESS = 0x0, 9 + /* 10 + * The following error codes are based on SCSI, because the interface 11 + * was originally created for it and has existing users. 12 + */ 13 + /* Generic device failure. */ 14 + PR_STS_IOERR = 0x2, 15 + PR_STS_RESERVATION_CONFLICT = 0x18, 16 + /* Temporary path failure that can be retried. */ 17 + PR_STS_RETRY_PATH_FAILURE = 0xe0000, 18 + /* The request was failed due to a fast failure timer. */ 19 + PR_STS_PATH_FAST_FAILED = 0xf0000, 20 + /* The path cannot be reached and has been marked as failed. */ 21 + PR_STS_PATH_FAILED = 0x10000, 22 + }; 23 + 7 24 enum pr_type { 8 25 PR_WRITE_EXCLUSIVE = 1, 9 26 PR_EXCLUSIVE_ACCESS = 2,