From patchwork Tue Jan 28 14:22:45 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Kai_M=C3=A4kisara?= X-Patchwork-Id: 860793 Received: from fgw23-4.mail.saunalahti.fi (fgw23-4.mail.saunalahti.fi [62.142.5.110]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9869D19F11B for ; Tue, 28 Jan 2025 14:23:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.142.5.110 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738074193; cv=none; b=hrPNWuNIJJdNqUxBq+4wHQP2P7dgOmo2QGrYCHCRWqmRRVr97utvpFFzIoP93HMvqY0GVSxLCPyBeEP7gTAu6BDzZ17b+pogWthIXrU8SssI3ftTov5T4nK4g94dXvaUEgM4XNABXCzQdzFULsspRskxHctj7RNIdpJSr1ewZW8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738074193; c=relaxed/simple; bh=2M6k+DsYAMJCPOVzvlVP2VtfhES06yIndeT5+90aXnI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=QYgxjM2aukk/eACEZN/ULT2AQOSr4wM42lLWIgpvE5qhJ0UBlsilOSNxEfbpxG1RkCwornUae+ukKcm8lGwVdxhjJccLLLxDaGYBj0/smUJAp6zAhZjxJbSMGsJhlbN3Z5aRc0h8u6ZvYlDY40w5QCd++9MmZlE2zK6HSobfQ4Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=kolumbus.fi; spf=pass smtp.mailfrom=kolumbus.fi; dkim=pass (2048-bit key) header.d=kolumbus.fi header.i=@kolumbus.fi header.b=DK8K2g6G; arc=none smtp.client-ip=62.142.5.110 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=kolumbus.fi Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kolumbus.fi Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kolumbus.fi header.i=@kolumbus.fi header.b="DK8K2g6G" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kolumbus.fi; s=elisa1; h=content-transfer-encoding:content-type:mime-version:references:in-reply-to: message-id:date:subject:cc:to:from:from:to:cc:reply-to:subject:date: in-reply-to:references:list-archive:list-subscribe:list-unsubscribe: content-type:content-transfer-encoding:message-id; bh=xAgNlQZX/jDGUIhfy3hB7tnSWYPmrrVRICUvmeVtmR0=; b=DK8K2g6Gfi2a5a9RF2+GMUS/7XiNbm3FE8euvI1PcibhGSm70g4I2Qy8vwm+VKWTiYGULym6cj5wd PVlXJxM9l/LDdeN5ebQdBGK3SpXG5HSo/PLVNkA3BTk97DBnz6TRpx/Hzj3bCxHfcg1uOX/pfVaFJ1 WKXcVLLCygcHTGUxr0V4rBd0vdVogRGVep9Z3y7dZFb2xilrFwK9v6dvSOqFTFPrIPDgnBtfEK+qaW xoglp61PQCApY1QMx4IDQyqeAiqfzsb+iwivKxxg2UjXne1hhJKDo5jdwzkv2bNZ05i1Ny+vFDJr+B sLPCo9XOWRAXb0KduP92lOs4YufAPmw== Received: from kaipn1.makisara.private (85-156-116-90.elisa-laajakaista.fi [85.156.116.90]) by fgw23.mail.saunalahti.fi (Halon) with ESMTPSA id 649cf8df-dd83-11ef-a25c-005056bdfda7; Tue, 28 Jan 2025 16:23:07 +0200 (EET) From: =?utf-8?q?Kai_M=C3=A4kisara?= To: linux-scsi@vger.kernel.org, dgilbert@interlog.com Cc: jmeneghi@redhat.com, =?utf-8?q?Kai_M=C3=A4kisara?= Subject: [RFC PATCH 1/6] scsi: scsi_debug: First fixes for tapes Date: Tue, 28 Jan 2025 16:22:45 +0200 Message-ID: <20250128142250.163901-2-Kai.Makisara@kolumbus.fi> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250128142250.163901-1-Kai.Makisara@kolumbus.fi> References: <20250128142250.163901-1-Kai.Makisara@kolumbus.fi> Precedence: bulk X-Mailing-List: linux-scsi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Patch includes the following: - enable MODE SENSE/SELECT without actual page (to read/write only the Block Descriptor) - store the density code and block size in the Block Descriptor - fix REWIND not to use the wrong page filling function Signed-off-by: Kai Mäkisara --- drivers/scsi/scsi_debug.c | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 680ba180a672..00daa77f636c 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -173,6 +173,10 @@ static const char *sdebug_version_date = "20210520"; #define DEF_ZBC_MAX_OPEN_ZONES 8 #define DEF_ZBC_NR_CONV_ZONES 1 +/* Default parameters for tape drives */ +#define TAPE_DEF_DENSITY 0x0 +#define TAPE_DEF_BLKSIZE 0 + #define SDEBUG_LUN_0_VAL 0 /* bit mask values for sdebug_opts */ @@ -363,6 +367,10 @@ struct sdebug_dev_info { ktime_t create_ts; /* time since bootup that this device was created */ struct sdeb_zone_state *zstate; + /* For tapes */ + unsigned int tape_blksize; + unsigned int tape_density; + struct dentry *debugfs_entry; struct spinlock list_lock; struct list_head inject_err_list; @@ -773,7 +781,7 @@ static const struct opcode_info_t opcode_info_arr[SDEB_I_LAST_ELEM_P1 + 1] = { /* 20 */ {0, 0x1e, 0, 0, NULL, NULL, /* ALLOW REMOVAL */ {6, 0, 0, 0, 0x3, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {0, 0x1, 0, 0, resp_start_stop, NULL, /* REWIND ?? */ + {0, 0x1, 0, 0, NULL, NULL, /* REWIND ?? */ {6, 0x1, 0, 0, 0, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, {0, 0, 0, F_INV_OP | FF_RESPOND, NULL, NULL, /* ATA_PT */ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, @@ -2742,7 +2750,7 @@ static int resp_mode_sense(struct scsi_cmnd *scp, unsigned char *ap; unsigned char *arr __free(kfree); unsigned char *cmd = scp->cmnd; - bool dbd, llbaa, msense_6, is_disk, is_zbc; + bool dbd, llbaa, msense_6, is_disk, is_zbc, is_tape; arr = kzalloc(SDEBUG_MAX_MSENSE_SZ, GFP_ATOMIC); if (!arr) @@ -2755,7 +2763,8 @@ static int resp_mode_sense(struct scsi_cmnd *scp, llbaa = msense_6 ? false : !!(cmd[1] & 0x10); is_disk = (sdebug_ptype == TYPE_DISK); is_zbc = devip->zoned; - if ((is_disk || is_zbc) && !dbd) + is_tape = (sdebug_ptype == TYPE_TAPE); + if ((is_disk || is_zbc || is_tape) && !dbd) bd_len = llbaa ? 16 : 8; else bd_len = 0; @@ -2793,7 +2802,11 @@ static int resp_mode_sense(struct scsi_cmnd *scp, put_unaligned_be32(0xffffffff, ap + 0); else put_unaligned_be32(sdebug_capacity, ap + 0); - put_unaligned_be16(sdebug_sector_size, ap + 6); + if (is_tape) { + ap[0] = devip->tape_density; + put_unaligned_be16(devip->tape_blksize, ap + 6); + } else + put_unaligned_be16(sdebug_sector_size, ap + 6); offset += bd_len; ap = arr + offset; } else if (16 == bd_len) { @@ -2802,6 +2815,8 @@ static int resp_mode_sense(struct scsi_cmnd *scp, offset += bd_len; ap = arr + offset; } + if (cmd[2] == 0) + goto only_bd; /* Only block descriptor requested */ /* * N.B. If len>0 before resp_*_pg() call, then form of that call should be: @@ -2902,6 +2917,7 @@ static int resp_mode_sense(struct scsi_cmnd *scp, default: goto bad_pcode; } +only_bd: if (msense_6) arr[0] = offset - 1; else @@ -2945,7 +2961,14 @@ static int resp_mode_select(struct scsi_cmnd *scp, __func__, param_len, res); md_len = mselect6 ? (arr[0] + 1) : (get_unaligned_be16(arr + 0) + 2); bd_len = mselect6 ? arr[3] : get_unaligned_be16(arr + 6); - off = bd_len + (mselect6 ? 4 : 8); + off = (mselect6 ? 4 : 8); + if (sdebug_ptype == TYPE_TAPE) { + devip->tape_density = arr[off]; + devip->tape_blksize = get_unaligned_be16(arr + off + 6); + } + off += bd_len; + if (res <= off) + goto only_bd; /* No page written, just descriptors */ if (md_len > 2 || off >= res) { mk_sense_invalid_fld(scp, SDEB_IN_DATA, 0, -1); return check_condition_result; @@ -2998,6 +3021,7 @@ static int resp_mode_select(struct scsi_cmnd *scp, return check_condition_result; set_mode_changed_ua: set_bit(SDEBUG_UA_MODE_CHANGED, devip->uas_bm); +only_bd: return 0; } @@ -5835,6 +5859,10 @@ static struct sdebug_dev_info *sdebug_device_create( } else { devip->zoned = false; } + if (sdebug_ptype == TYPE_TAPE) { + devip->tape_density = TAPE_DEF_DENSITY; + devip->tape_blksize = TAPE_DEF_BLKSIZE; + } devip->create_ts = ktime_get_boottime(); atomic_set(&devip->stopped, (sdeb_tur_ms_to_ready > 0 ? 2 : 0)); spin_lock_init(&devip->list_lock); From patchwork Tue Jan 28 14:22:46 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Kai_M=C3=A4kisara?= X-Patchwork-Id: 860791 Received: from fgw22-4.mail.saunalahti.fi (fgw22-4.mail.saunalahti.fi [62.142.5.109]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9F56419F11B for ; Tue, 28 Jan 2025 14:24:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.142.5.109 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738074265; cv=none; b=k+5j1oEnQXfAvHMBCNtsnnOJvLfcj5TMtGVO6b4Ob6O7k1lxUFRqd12lF3ZPT7Gln0+1krBJR+esnLL6+MbIqu4j1fG8KyPzS5pGCxmmPbUGhmR9d7IlCRWFZXM2XktIqRURIyyYw6lV6lqYfznrF666dl8Z+qU0OIomlVAEZBw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738074265; c=relaxed/simple; bh=jiB60A5+vYBGO31PTsm3QDpHcFLj229002sLIyx+zYY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=PMGoGPevi+kRwHiZnu9NgsFTfT/Chz5QLetZRqExYJbUlP020eJLwTGW3kBRS5LrkIf91wevD03APmrTQYKVyrLbO59Ku0zKQbpGVWZD86qWvdegCU65gU5LlQUeVtUy38cmXnjVWTXKSebps4zE5pUNa93ce4Kl6D0hXTj6ahw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=kolumbus.fi; spf=pass smtp.mailfrom=kolumbus.fi; dkim=pass (2048-bit key) header.d=kolumbus.fi header.i=@kolumbus.fi header.b=KsFeHzTn; arc=none smtp.client-ip=62.142.5.109 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=kolumbus.fi Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kolumbus.fi Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kolumbus.fi header.i=@kolumbus.fi header.b="KsFeHzTn" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kolumbus.fi; s=elisa1; h=content-transfer-encoding:content-type:mime-version:references:in-reply-to: message-id:date:subject:cc:to:from:from:to:cc:reply-to:subject:date: in-reply-to:references:list-archive:list-subscribe:list-unsubscribe: content-type:content-transfer-encoding:message-id; bh=NbXeAm1CcjxzX2gCq5eDYhWCmfDIB9CxYkhQaxNmE3I=; b=KsFeHzTn/LtbOmcHownztMZhxlsGDRou0sYZJ6KzU1mYwnUq3ztbmyIN9uu/byeL2xuuWxax5rO/H GINDj1AZeQGNJkBE7N2DZBg1VLXloMtAkIMy25iqFwV3KDuDRdXdq4JHIiExATONc6N8lPD8gBd/mI AMjNXCKOSg+GaGa7VweTK8yFW5NRK4mlZMHUPI9Zub7H/94Pk2kW01CR74JDSaAgq0bgswzx8lhabA d9f/3MBuQVRFXkyHbqMgY0IjJPkJqRqULwPy+HEjETV/0rFHdXetXCn4RvtpBLkfXmpxq6AWfNrx88 uveCpIlumudgQEhyU/NQ4ZofFzaBdDw== Received: from kaipn1.makisara.private (85-156-116-90.elisa-laajakaista.fi [85.156.116.90]) by fgw23.mail.saunalahti.fi (Halon) with ESMTPSA id 665ceedd-dd83-11ef-a25c-005056bdfda7; Tue, 28 Jan 2025 16:23:09 +0200 (EET) From: =?utf-8?q?Kai_M=C3=A4kisara?= To: linux-scsi@vger.kernel.org, dgilbert@interlog.com Cc: jmeneghi@redhat.com, =?utf-8?q?Kai_M=C3=A4kisara?= Subject: [RFC PATCH 2/6] scsi: scsi_debug: Add READ BLOCK LIMITS and modify LOAD for tapes Date: Tue, 28 Jan 2025 16:22:46 +0200 Message-ID: <20250128142250.163901-3-Kai.Makisara@kolumbus.fi> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250128142250.163901-1-Kai.Makisara@kolumbus.fi> References: <20250128142250.163901-1-Kai.Makisara@kolumbus.fi> Precedence: bulk X-Mailing-List: linux-scsi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The changes: - add READ BLOCK LIMITS (512 - 1048576 bytes) - make LOAD send New Media UA (not correct by the standard, but makes possible to test also this UA) Signed-off-by: Kai Mäkisara --- drivers/scsi/scsi_debug.c | 130 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 123 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 00daa77f636c..19929625bd36 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -80,6 +80,7 @@ static const char *sdebug_version_date = "20210520"; #define INVALID_FIELD_IN_CDB 0x24 #define INVALID_FIELD_IN_PARAM_LIST 0x26 #define WRITE_PROTECTED 0x27 +#define UA_READY_ASC 0x28 #define UA_RESET_ASC 0x29 #define UA_CHANGED_ASC 0x2a #define TARGET_CHANGED_ASC 0x3f @@ -175,7 +176,11 @@ static const char *sdebug_version_date = "20210520"; /* Default parameters for tape drives */ #define TAPE_DEF_DENSITY 0x0 +#define TAPE_BAD_DENSITY 0x65 #define TAPE_DEF_BLKSIZE 0 +#define TAPE_MIN_BLKSIZE 512 +#define TAPE_MAX_BLKSIZE 1048576 +#define TAPE_MAX_PARTITIONS 2 #define SDEBUG_LUN_0_VAL 0 @@ -220,7 +225,8 @@ static const char *sdebug_version_date = "20210520"; #define SDEBUG_UA_LUNS_CHANGED 5 #define SDEBUG_UA_MICROCODE_CHANGED 6 /* simulate firmware change */ #define SDEBUG_UA_MICROCODE_CHANGED_WO_RESET 7 -#define SDEBUG_NUM_UAS 8 +#define SDEBUG_UA_NOT_READY_TO_READY 8 +#define SDEBUG_NUM_UAS 9 /* when 1==SDEBUG_OPT_MEDIUM_ERR, a medium error is simulated at this * sector on read commands: */ @@ -370,6 +376,8 @@ struct sdebug_dev_info { /* For tapes */ unsigned int tape_blksize; unsigned int tape_density; + unsigned char tape_partition; + unsigned int tape_location[TAPE_MAX_PARTITIONS]; struct dentry *debugfs_entry; struct spinlock list_lock; @@ -491,14 +499,16 @@ enum sdeb_opcode_index { SDEB_I_ZONE_OUT = 30, /* 0x94+SA; includes no data xfer */ SDEB_I_ZONE_IN = 31, /* 0x95+SA; all have data-in */ SDEB_I_ATOMIC_WRITE_16 = 32, - SDEB_I_LAST_ELEM_P1 = 33, /* keep this last (previous + 1) */ + SDEB_I_READ_BLOCK_LIMITS = 33, + SDEB_I_LOCATE = 34, + SDEB_I_LAST_ELEM_P1 = 35, /* keep this last (previous + 1) */ }; static const unsigned char opcode_ind_arr[256] = { /* 0x0; 0x0->0x1f: 6 byte cdbs */ SDEB_I_TEST_UNIT_READY, SDEB_I_REZERO_UNIT, 0, SDEB_I_REQUEST_SENSE, - 0, 0, 0, 0, + 0, SDEB_I_READ_BLOCK_LIMITS, 0, 0, SDEB_I_READ, 0, SDEB_I_WRITE, 0, 0, 0, 0, 0, 0, 0, SDEB_I_INQUIRY, 0, 0, SDEB_I_MODE_SELECT, SDEB_I_RESERVE, SDEB_I_RELEASE, @@ -506,7 +516,7 @@ static const unsigned char opcode_ind_arr[256] = { SDEB_I_ALLOW_REMOVAL, 0, /* 0x20; 0x20->0x3f: 10 byte cdbs */ 0, 0, 0, 0, 0, SDEB_I_READ_CAPACITY, 0, 0, - SDEB_I_READ, 0, SDEB_I_WRITE, 0, 0, 0, 0, SDEB_I_VERIFY, + SDEB_I_READ, 0, SDEB_I_WRITE, SDEB_I_LOCATE, 0, 0, 0, SDEB_I_VERIFY, 0, 0, 0, 0, SDEB_I_PRE_FETCH, SDEB_I_SYNC_CACHE, 0, 0, 0, 0, 0, SDEB_I_WRITE_BUFFER, 0, 0, 0, 0, /* 0x40; 0x40->0x5f: 10 byte cdbs */ @@ -581,6 +591,8 @@ static int resp_open_zone(struct scsi_cmnd *, struct sdebug_dev_info *); static int resp_close_zone(struct scsi_cmnd *, struct sdebug_dev_info *); static int resp_finish_zone(struct scsi_cmnd *, struct sdebug_dev_info *); static int resp_rwp_zone(struct scsi_cmnd *, struct sdebug_dev_info *); +static int resp_read_blklimits(struct scsi_cmnd *, struct sdebug_dev_info *); +static int resp_locate(struct scsi_cmnd *, struct sdebug_dev_info *); static int sdebug_do_add_host(bool mk_new_store); static int sdebug_add_host_helper(int per_host_idx); @@ -808,6 +820,7 @@ static const struct opcode_info_t opcode_info_arr[SDEB_I_LAST_ELEM_P1 + 1] = { resp_pre_fetch, pre_fetch_iarr, {10, 0x2, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0} }, /* PRE-FETCH (10) */ + /* READ POSITION (10) */ /* 30 */ {ARRAY_SIZE(zone_out_iarr), 0x94, 0x3, F_SA_LOW | F_M_ACCESS, @@ -823,6 +836,12 @@ static const struct opcode_info_t opcode_info_arr[SDEB_I_LAST_ELEM_P1 + 1] = { resp_atomic_write, NULL, /* ATOMIC WRITE 16 */ {16, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} }, + {0, 0x05, 0, F_D_IN, resp_read_blklimits, NULL, /* READ BLOCK LIMITS (6) */ + {6, 0, 0, 0, 0, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {0, 0x2b, 0, F_D_UNKN, resp_locate, NULL, /* LOCATE (10) */ + {10, 0x2, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xc7, 0, 0, + 0, 0, 0, 0} }, + /* sentinel */ {0xff, 0, 0, 0, NULL, NULL, /* terminating element */ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, @@ -1501,6 +1520,12 @@ static int make_ua(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) if (sdebug_verbose) cp = "reported luns data has changed"; break; + case SDEBUG_UA_NOT_READY_TO_READY: + mk_sense_buffer(scp, UNIT_ATTENTION, UA_READY_ASC, + 0); + if (sdebug_verbose) + cp = "not ready to ready transition/media change"; + break; default: pr_warn("unexpected unit attention code=%d\n", k); if (sdebug_verbose) @@ -2204,6 +2229,14 @@ static int resp_start_stop(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) changing = (stopped_state != want_stop); if (changing) atomic_xchg(&devip->stopped, want_stop); + if (sdebug_ptype == TYPE_TAPE && !want_stop) { + int i; + + set_bit(SDEBUG_UA_NOT_READY_TO_READY, devip->uas_bm); /* not legal! */ + for (i = 0; i < TAPE_MAX_PARTITIONS; i++) + devip->tape_location[i] = 0; + devip->tape_partition = 0; + } if (!changing || (cmd[1] & 0x1)) /* state unchanged or IMMED bit set in cdb */ return SDEG_RES_IMMED_MASK; else @@ -2736,6 +2769,17 @@ static int resp_sas_sha_m_spg(unsigned char *p, int pcontrol) return sizeof(sas_sha_m_pg); } +static int resp_partition_m_pg(unsigned char *p, int pcontrol, int target) +{ /* Partition page for mode_sense (tape) */ + unsigned char partition_pg[] = {0x11, 12, 1, 1, 0x80, 3, 9, 0, + 0xff, 0xff, 0x00, 40}; + + memcpy(p, partition_pg, sizeof(partition_pg)); + if (pcontrol == 1) + memset(p + 2, 0, sizeof(partition_pg) - 2); + return sizeof(partition_pg); +} + /* PAGE_SIZE is more than necessary but provides room for future expansion. */ #define SDEBUG_MAX_MSENSE_SZ PAGE_SIZE @@ -2872,6 +2916,12 @@ static int resp_mode_sense(struct scsi_cmnd *scp, } offset += len; break; + case 0x11: /* Partition Mode Page (tape) */ + if (!is_tape) + goto bad_pcode; + len += resp_partition_m_pg(ap, pcontrol, target); + offset += len; + break; case 0x19: /* if spc==1 then sas phy, control+discover */ if (subpcode > 0x2 && subpcode < 0xff) goto bad_subpcode; @@ -2963,12 +3013,24 @@ static int resp_mode_select(struct scsi_cmnd *scp, bd_len = mselect6 ? arr[3] : get_unaligned_be16(arr + 6); off = (mselect6 ? 4 : 8); if (sdebug_ptype == TYPE_TAPE) { + int blks; + + if (arr[off] == TAPE_BAD_DENSITY) { + mk_sense_invalid_fld(scp, SDEB_IN_DATA, 0, -1); + return check_condition_result; + } + blks = get_unaligned_be16(arr + off + 6); + if (blks != 0 && + (blks < TAPE_MIN_BLKSIZE || blks > TAPE_MAX_BLKSIZE)) { + mk_sense_invalid_fld(scp, SDEB_IN_DATA, 1, -1); + return check_condition_result; + } devip->tape_density = arr[off]; - devip->tape_blksize = get_unaligned_be16(arr + off + 6); + devip->tape_blksize = blks; } off += bd_len; if (res <= off) - goto only_bd; /* No page written, just descriptors */ + return 0; /* No page written, just descriptors */ if (md_len > 2 || off >= res) { mk_sense_invalid_fld(scp, SDEB_IN_DATA, 0, -1); return check_condition_result; @@ -3021,7 +3083,6 @@ static int resp_mode_select(struct scsi_cmnd *scp, return check_condition_result; set_mode_changed_ua: set_bit(SDEBUG_UA_MODE_CHANGED, devip->uas_bm); -only_bd: return 0; } @@ -3162,6 +3223,36 @@ static int resp_log_sense(struct scsi_cmnd *scp, min_t(u32, len, SDEBUG_MAX_INQ_ARR_SZ)); } +#define SDEBUG_READ_BLOCK_LIMITS_ARR_SZ 6 +static int resp_read_blklimits(struct scsi_cmnd *scp, + struct sdebug_dev_info *devip) +{ + unsigned char arr[SDEBUG_READ_BLOCK_LIMITS_ARR_SZ]; + + memset(arr, 0, SDEBUG_READ_BLOCK_LIMITS_ARR_SZ); + put_unaligned_be24(TAPE_MAX_BLKSIZE, arr + 1); + put_unaligned_be16(TAPE_MIN_BLKSIZE, arr + 4); + return fill_from_dev_buffer(scp, arr, SDEBUG_READ_BLOCK_LIMITS_ARR_SZ); +} + +static int resp_locate(struct scsi_cmnd *scp, + struct sdebug_dev_info *devip) +{ + unsigned char *cmd = scp->cmnd; + + if ((cmd[1] & 0x02) != 0) { + if (cmd[8] >= TAPE_MAX_PARTITIONS) { + mk_sense_invalid_fld(scp, SDEB_IN_CDB, 8, -1); + return check_condition_result; + } + devip->tape_partition = cmd[8]; + } + devip->tape_location[devip->tape_partition] = + get_unaligned_be32(cmd + 3); + + return 0; +} + static inline bool sdebug_dev_is_zoned(struct sdebug_dev_info *devip) { return devip->nr_zones != 0; @@ -4942,6 +5033,8 @@ static int resp_sync_cache(struct scsi_cmnd *scp, * a GOOD status otherwise. Model a disk with a big cache and yield * CONDITION MET. Actually tries to bring range in main memory into the * cache associated with the CPU(s). + * + * The pcode 0x34 is also used for READ POSITION by tape devices. */ static int resp_pre_fetch(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) @@ -4954,6 +5047,29 @@ static int resp_pre_fetch(struct scsi_cmnd *scp, struct sdeb_store_info *sip = devip2sip(devip, true); u8 *fsp = sip->storep; + if (sdebug_ptype == TYPE_TAPE) { + if (cmd[0] == PRE_FETCH) { /* READ POSITION (10) */ + int all_length; + unsigned char arr[20]; + unsigned int pos; + + all_length = get_unaligned_be16(cmd + 7); + if ((cmd[1] & 0xfe) != 0) { /* only short form */ + mk_sense_invalid_fld(scp, SDEB_IN_CDB, + 1, 0); + return check_condition_result; + } + memset(arr, 0, 20); + arr[1] = devip->tape_partition; + pos = devip->tape_location[devip->tape_partition]; + put_unaligned_be32(pos, arr + 4); + put_unaligned_be32(pos, arr + 8); + return fill_from_dev_buffer(scp, arr, 20); + } + mk_sense_invalid_opcode(scp); + return check_condition_result; + } + if (cmd[0] == PRE_FETCH) { /* 10 byte cdb */ lba = get_unaligned_be32(cmd + 2); nblks = get_unaligned_be16(cmd + 7); From patchwork Tue Jan 28 14:22:47 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Kai_M=C3=A4kisara?= X-Patchwork-Id: 860790 Received: from fgw21-4.mail.saunalahti.fi (fgw21-4.mail.saunalahti.fi [62.142.5.108]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 36B3219F11B for ; Tue, 28 Jan 2025 14:24:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.142.5.108 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738074284; cv=none; b=H4E+GeDTdA/8cP84iFkU+ZYUZQlMvSEX695pREJOrGr2CTS5Le1wZTuurDf/8rU8NWGvXMJgNwYPoanIdkfmB54uCpzx8S1ImeelUagt48JTvlGaxqbOCppQVSVeMZZi5L0ulPxCvy4+Gxzc97hiKA/Q1ARmRIjw+n+4GAYdtBg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738074284; c=relaxed/simple; bh=7/oj29mv6lLECmUmz7j4/7hDe1DuR0RGLd/oZUaK3QE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=miLHUonFCZDY/zAadxvsQHaArrUQ5a3wH79UnIYw7O1q8WtXYpMgcJNanMUtYodLGl9E959ZxYhTye+EF1NtLZywVyCaGoVkNJjj1y0XSxw5cJNKmCDVN0DXmu9rbyV2LCNLsfdGzIkId7BsF0GfmIfIG8JhpNQHB4PTVVMgimg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=kolumbus.fi; spf=pass smtp.mailfrom=kolumbus.fi; dkim=pass (2048-bit key) header.d=kolumbus.fi header.i=@kolumbus.fi header.b=cPZogSYJ; arc=none smtp.client-ip=62.142.5.108 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=kolumbus.fi Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kolumbus.fi Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kolumbus.fi header.i=@kolumbus.fi header.b="cPZogSYJ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kolumbus.fi; s=elisa1; h=content-transfer-encoding:content-type:mime-version:references:in-reply-to: message-id:date:subject:cc:to:from:from:to:cc:reply-to:subject:date: in-reply-to:references:list-archive:list-subscribe:list-unsubscribe: content-type:content-transfer-encoding:message-id; bh=YASrf/2teccezNM2m8VRe9kcTfB4tVhgNXs6mH5fZRQ=; b=cPZogSYJDQpxHDTrEhgQDZdstEvq59d5BiSfmjV9TaFOlc8sDxX2lcVT2wm1D+AP2I3Ve6muO/d7X DWrenp0bjz5tcX8sr1eUEF7+esa1ZHPZKpUU1N8l003gDt8FU2imNAEtZyFb0mZpU9i/wyTUKGbJFs 4JUjLaHNW5DKlVf2m1CULr8piQudhYRuZ0TMgw4Yn+5YSOEogkaJBRXQOPVef+kU6+ToGVMQbe02N0 uJyNlpw7mUBhoRgSE/n1R/tFhBGPqAoJNu+wqosGSSZWqn8WI4/aXHKIhn+e4z+bxZbhST4XSB8lHy 2EXjvUK7u3nwdpZON2mGy67b8KfUsng== Received: from kaipn1.makisara.private (85-156-116-90.elisa-laajakaista.fi [85.156.116.90]) by fgw23.mail.saunalahti.fi (Halon) with ESMTPSA id 68008b17-dd83-11ef-a25c-005056bdfda7; Tue, 28 Jan 2025 16:23:12 +0200 (EET) From: =?utf-8?q?Kai_M=C3=A4kisara?= To: linux-scsi@vger.kernel.org, dgilbert@interlog.com Cc: jmeneghi@redhat.com, =?utf-8?q?Kai_M=C3=A4kisara?= Subject: [RFC PATCH 3/6] scsi: scsi_debug: Add tape write support with block lengths and 4 bytes of data Date: Tue, 28 Jan 2025 16:22:47 +0200 Message-ID: <20250128142250.163901-4-Kai.Makisara@kolumbus.fi> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250128142250.163901-1-Kai.Makisara@kolumbus.fi> References: <20250128142250.163901-1-Kai.Makisara@kolumbus.fi> Precedence: bulk X-Mailing-List: linux-scsi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The tape partitions are implemented as fixed number of 8-byte units (partition zero 100 000 units and partition one 1000 units). The first four bytes of a unit contains the type of the unit (data block, filemark or end-of-data mark). If the units is a data block, the first four bytes contain the block length and the remaining four bytes the first bytes of written data. This allows the user to use tags to see that the read block is what it was supposed to be. This patch adds the WRITE(6) command for tapes and the WRITE FILEMARKS (6) command. The REWIND command is updated. Signed-off-by: Kai Mäkisara --- drivers/scsi/scsi_debug.c | 188 +++++++++++++++++++++++++++++++++++++- 1 file changed, 184 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 19929625bd36..2f0c73bd37b8 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -71,6 +71,10 @@ static const char *sdebug_version_date = "20210520"; #define NO_ADDITIONAL_SENSE 0x0 #define OVERLAP_ATOMIC_COMMAND_ASC 0x0 #define OVERLAP_ATOMIC_COMMAND_ASCQ 0x23 +#define FILEMARK_DETECTED_ASCQ 0x1 +#define EOP_EOM_DETECTED_ASCQ 0x2 +#define BEGINNING_OF_P_M_DETECTED_ASCQ 0x4 +#define EOD_DETECTED_ASCQ 0x5 #define LOGICAL_UNIT_NOT_READY 0x4 #define LOGICAL_UNIT_COMMUNICATION_FAILURE 0x8 #define UNRECOVERED_READ_ERR 0x11 @@ -83,6 +87,7 @@ static const char *sdebug_version_date = "20210520"; #define UA_READY_ASC 0x28 #define UA_RESET_ASC 0x29 #define UA_CHANGED_ASC 0x2a +#define TOO_MANY_IN_PARTITION_ASC 0x3b #define TARGET_CHANGED_ASC 0x3f #define LUNS_CHANGED_ASCQ 0x0e #define INSUFF_RES_ASC 0x55 @@ -180,7 +185,30 @@ static const char *sdebug_version_date = "20210520"; #define TAPE_DEF_BLKSIZE 0 #define TAPE_MIN_BLKSIZE 512 #define TAPE_MAX_BLKSIZE 1048576 +#define TAPE_EW 20 #define TAPE_MAX_PARTITIONS 2 +#define TAPE_PARTITION_0_UNITS 100000 +#define TAPE_PARTITION_1_UNITS 1000 + +/* The tape block data definitions */ +#define TAPE_BLOCK_FM_FLAG ((u32)0x1 << 30) +#define TAPE_BLOCK_EOD_FLAG ((u32)0x2 << 30) +#define TAPE_BLOCK_MARK_MASK ((u32)0x3 << 30) +#define TAPE_BLOCK_SIZE_MASK (~TAPE_BLOCK_MARK_MASK) +#define TAPE_BLOCK_MARK(a) (a & TAPE_BLOCK_MARK_MASK) +#define TAPE_BLOCK_SIZE(a) (a & TAPE_BLOCK_SIZE_MASK) +#define IS_TAPE_BLOCK_FM(a) ((a & TAPE_BLOCK_FM_FLAG) != 0) +#define IS_TAPE_BLOCK_EOD(a) ((a & TAPE_BLOCK_EOD_FLAG) != 0) + +struct tape_block { + u32 fl_size; + unsigned char data[4]; +}; + +/* Flags for sense data */ +#define SENSE_FLAG_FILEMARK 0x80 +#define SENSE_FLAG_EOM 0x40 +#define SENSE_FLAG_ILI 0x20 #define SDEBUG_LUN_0_VAL 0 @@ -378,6 +406,8 @@ struct sdebug_dev_info { unsigned int tape_density; unsigned char tape_partition; unsigned int tape_location[TAPE_MAX_PARTITIONS]; + unsigned int tape_eop[TAPE_MAX_PARTITIONS]; + struct tape_block *tape_blocks[TAPE_MAX_PARTITIONS]; struct dentry *debugfs_entry; struct spinlock list_lock; @@ -501,7 +531,8 @@ enum sdeb_opcode_index { SDEB_I_ATOMIC_WRITE_16 = 32, SDEB_I_READ_BLOCK_LIMITS = 33, SDEB_I_LOCATE = 34, - SDEB_I_LAST_ELEM_P1 = 35, /* keep this last (previous + 1) */ + SDEB_I_WRITE_FILEMARKS = 35, + SDEB_I_LAST_ELEM_P1 = 36, /* keep this last (previous + 1) */ }; @@ -510,8 +541,8 @@ static const unsigned char opcode_ind_arr[256] = { SDEB_I_TEST_UNIT_READY, SDEB_I_REZERO_UNIT, 0, SDEB_I_REQUEST_SENSE, 0, SDEB_I_READ_BLOCK_LIMITS, 0, 0, SDEB_I_READ, 0, SDEB_I_WRITE, 0, 0, 0, 0, 0, - 0, 0, SDEB_I_INQUIRY, 0, 0, SDEB_I_MODE_SELECT, SDEB_I_RESERVE, - SDEB_I_RELEASE, + SDEB_I_WRITE_FILEMARKS, 0, SDEB_I_INQUIRY, 0, 0, + SDEB_I_MODE_SELECT, SDEB_I_RESERVE, SDEB_I_RELEASE, 0, 0, SDEB_I_MODE_SENSE, SDEB_I_START_STOP, 0, SDEB_I_SEND_DIAG, SDEB_I_ALLOW_REMOVAL, 0, /* 0x20; 0x20->0x3f: 10 byte cdbs */ @@ -593,6 +624,8 @@ static int resp_finish_zone(struct scsi_cmnd *, struct sdebug_dev_info *); static int resp_rwp_zone(struct scsi_cmnd *, struct sdebug_dev_info *); static int resp_read_blklimits(struct scsi_cmnd *, struct sdebug_dev_info *); static int resp_locate(struct scsi_cmnd *, struct sdebug_dev_info *); +static int resp_write_filemarks(struct scsi_cmnd *, struct sdebug_dev_info *); +static int resp_rewind(struct scsi_cmnd *, struct sdebug_dev_info *); static int sdebug_do_add_host(bool mk_new_store); static int sdebug_add_host_helper(int per_host_idx); @@ -793,7 +826,7 @@ static const struct opcode_info_t opcode_info_arr[SDEB_I_LAST_ELEM_P1 + 1] = { /* 20 */ {0, 0x1e, 0, 0, NULL, NULL, /* ALLOW REMOVAL */ {6, 0, 0, 0, 0x3, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, - {0, 0x1, 0, 0, NULL, NULL, /* REWIND ?? */ + {0, 0x1, 0, 0, resp_rewind, NULL, {6, 0x1, 0, 0, 0, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, {0, 0, 0, F_INV_OP | FF_RESPOND, NULL, NULL, /* ATA_PT */ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, @@ -841,6 +874,8 @@ static const struct opcode_info_t opcode_info_arr[SDEB_I_LAST_ELEM_P1 + 1] = { {0, 0x2b, 0, F_D_UNKN, resp_locate, NULL, /* LOCATE (10) */ {10, 0x2, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0} }, + {0, 0x10, 0, F_D_IN, resp_write_filemarks, NULL, /* WRITE FILEMARKS (6) */ + {6, 0x01, 0xff, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, /* sentinel */ {0xff, 0, 0, 0, NULL, NULL, /* terminating element */ @@ -1358,6 +1393,30 @@ static void mk_sense_buffer(struct scsi_cmnd *scp, int key, int asc, int asq) my_name, key, asc, asq); } +/* Sense data that has information fields for tapes */ +static void mk_sense_info_tape(struct scsi_cmnd *scp, int key, int asc, int asq, + unsigned int information, unsigned char tape_flags) +{ + if (!scp->sense_buffer) { + sdev_printk(KERN_ERR, scp->device, + "%s: sense_buffer is NULL\n", __func__); + return; + } + memset(scp->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); + + scsi_build_sense(scp, /*sdebug_dsense*/ 0, key, asc, asq); + /* only fixed format so far */ + + scp->sense_buffer[0] |= 0x80; /* valid */ + scp->sense_buffer[2] |= tape_flags; + put_unaligned_be32(information, &scp->sense_buffer[3]); + + if (sdebug_verbose) + sdev_printk(KERN_INFO, scp->device, + "%s: [sense_key,asc,ascq]: [0x%x,0x%x,0x%x]\n", + my_name, key, asc, asq); +} + static void mk_sense_invalid_opcode(struct scsi_cmnd *scp) { mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_OPCODE, 0); @@ -3253,6 +3312,44 @@ static int resp_locate(struct scsi_cmnd *scp, return 0; } +static int resp_write_filemarks(struct scsi_cmnd *scp, + struct sdebug_dev_info *devip) +{ + unsigned char *cmd = scp->cmnd; + unsigned int i, count, pos; + u32 data; + int partition = devip->tape_partition; + + if ((cmd[1] & 0xfe) != 0) { /* probably write setmarks, not in >= SCSI-3 */ + mk_sense_invalid_fld(scp, SDEB_IN_CDB, 1, 1); + return check_condition_result; + } + count = get_unaligned_be24(cmd + 2); + data = TAPE_BLOCK_FM_FLAG; + for (i = 0, pos = devip->tape_location[partition]; i < count; i++, pos++) { + if (pos >= devip->tape_eop[partition] - 1) { /* don't overwrite EOD */ + devip->tape_location[partition] = devip->tape_eop[partition] - 1; + mk_sense_info_tape(scp, VOLUME_OVERFLOW, NO_ADDITIONAL_SENSE, + EOP_EOM_DETECTED_ASCQ, count, SENSE_FLAG_EOM); + return check_condition_result; + } + (devip->tape_blocks[partition] + pos)->fl_size = data; + } + (devip->tape_blocks[partition] + pos)->fl_size = + TAPE_BLOCK_EOD_FLAG; + devip->tape_location[partition] = pos; + + return 0; +} + +static int resp_rewind(struct scsi_cmnd *scp, + struct sdebug_dev_info *devip) +{ + devip->tape_location[devip->tape_partition] = 0; + + return 0; +} + static inline bool sdebug_dev_is_zoned(struct sdebug_dev_info *devip) { return devip->nr_zones != 0; @@ -4293,6 +4390,67 @@ static void unmap_region(struct sdeb_store_info *sip, sector_t lba, } } +static int resp_write_tape(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) +{ + u32 i, num, transfer, size, written = 0; + u8 *cmd = scp->cmnd; + struct scsi_data_buffer *sdb = &scp->sdb; + int partition = devip->tape_partition; + int pos = devip->tape_location[partition]; + struct tape_block *blp; + bool fixed, ew; + + if (cmd[0] != WRITE_6) { /* Only Write(6) supported */ + mk_sense_invalid_opcode(scp); + return illegal_condition_result; + } + + fixed = (cmd[1] & 1) != 0; + transfer = get_unaligned_be24(cmd + 2); + if (fixed) { + num = transfer; + size = devip->tape_blksize; + } else { + if (transfer < TAPE_MIN_BLKSIZE || + transfer > TAPE_MAX_BLKSIZE) { + mk_sense_invalid_fld(scp, SDEB_IN_CDB, 2, -1); + return check_condition_result; + } + num = 1; + size = transfer; + } + + scsi_set_resid(scp, num * transfer); + for (i = 0, blp = devip->tape_blocks[partition] + pos, ew = false; + i < num && pos < devip->tape_eop[partition] - 1; i++, pos++, blp++) { + blp->fl_size = size; + sg_copy_buffer(sdb->table.sgl, sdb->table.nents, + &(blp->data), 4, i * size, true); + written += size; + scsi_set_resid(scp, num * transfer - written); + ew |= (pos == devip->tape_eop[partition] - TAPE_EW); + } + + devip->tape_location[partition] = pos; + blp->fl_size = TAPE_BLOCK_EOD_FLAG; + if (pos >= devip->tape_eop[partition] - 1) { + mk_sense_info_tape(scp, VOLUME_OVERFLOW, + NO_ADDITIONAL_SENSE, EOP_EOM_DETECTED_ASCQ, + fixed ? num - i : transfer, + SENSE_FLAG_EOM); + return check_condition_result; + } + if (ew) { /* early warning */ + mk_sense_info_tape(scp, NO_SENSE, + NO_ADDITIONAL_SENSE, EOP_EOM_DETECTED_ASCQ, + fixed ? num - i : transfer, + SENSE_FLAG_EOM); + return check_condition_result; + } + + return 0; +} + static int resp_write_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) { bool check_prot; @@ -4305,6 +4463,9 @@ static int resp_write_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) u8 *cmd = scp->cmnd; bool meta_data_locked = false; + if (sdebug_ptype == TYPE_TAPE) + return resp_write_tape(scp, devip); + switch (cmd[0]) { case WRITE_16: ei_lba = 0; @@ -5976,8 +6137,27 @@ static struct sdebug_dev_info *sdebug_device_create( devip->zoned = false; } if (sdebug_ptype == TYPE_TAPE) { + int i; + devip->tape_density = TAPE_DEF_DENSITY; devip->tape_blksize = TAPE_DEF_BLKSIZE; + for (i = 0; i < TAPE_MAX_PARTITIONS; i++) { + devip->tape_eop[i] = i ? TAPE_PARTITION_1_UNITS : + TAPE_PARTITION_0_UNITS; + devip->tape_blocks[i] = + kcalloc(devip->tape_eop[i], + sizeof(struct tape_block), + GFP_KERNEL); + if (!devip->tape_blocks[i]) { + int j; + + for (j = 0; j < i; j++) + kfree(devip->tape_blocks[j]); + kfree(devip); + return NULL; + } + devip->tape_blocks[i]->fl_size = TAPE_BLOCK_EOD_FLAG; + } } devip->create_ts = ktime_get_boottime(); atomic_set(&devip->stopped, (sdeb_tur_ms_to_ready > 0 ? 2 : 0)); From patchwork Tue Jan 28 14:22:48 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Kai_M=C3=A4kisara?= X-Patchwork-Id: 860586 Received: from fgw22-4.mail.saunalahti.fi (fgw22-4.mail.saunalahti.fi [62.142.5.109]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9B39F19F11B for ; Tue, 28 Jan 2025 14:23:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.142.5.109 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738074205; cv=none; b=M92C4ptR+0lcAcD+trdoXxs3to/V0hFXxdg8bp9ZWnGv1REFWmjH2mSa2RQo70+f52W8LVneG7qu6+3zEF4K27BoFQNkS0VfUX4ZomZxHPGTJybTlrpGyhqmHUyPakGMVhatCnbnQbmKZZ1CQW379CGpWLLCkWV0lPKO6je9KDE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738074205; c=relaxed/simple; bh=5+rg6c6nauw5L6Q1yWnerqCifR9z2/eIYNgDQ4gWnjo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=PSbmjYqSDxLJRahszPSYhjitfjVgTgCvKHl0K53S4d9iwQDhhc5fFUr7bj4EIhk5sCeFzdjgH9nbZty43pPmnC1kYfyG5p1DX4Q1VcTFC7FZ8J3d0LwoRpFcKKSrr3b3h7rdYbMQd+Ny1/GHpp11b0jJu1YU82e5wWyZtKQnRpQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=kolumbus.fi; spf=pass smtp.mailfrom=kolumbus.fi; dkim=pass (2048-bit key) header.d=kolumbus.fi header.i=@kolumbus.fi header.b=o/3ns+0g; arc=none smtp.client-ip=62.142.5.109 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=kolumbus.fi Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kolumbus.fi Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kolumbus.fi header.i=@kolumbus.fi header.b="o/3ns+0g" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kolumbus.fi; s=elisa1; h=content-transfer-encoding:content-type:mime-version:references:in-reply-to: message-id:date:subject:cc:to:from:from:to:cc:reply-to:subject:date: in-reply-to:references:list-archive:list-subscribe:list-unsubscribe: content-type:content-transfer-encoding:message-id; bh=22BKiPsQ6HQhKSsG+9OMSJQAjs7aqko33eq0bjenRP8=; b=o/3ns+0gQQeLQARQ+9eKb0k4KfOcg++jEAqSLjMN10bGtISzMF53QPA5h+fwS31JXpc/Q4kgGssoW yWScMQwo83Nxxnx5IoNIqDhpB0C2LbBp1LivhCj78J/rVWymiFG9wPeiTBk7uZRzTtSDFOoe2dmTCs NVPADHMebobJoY+tijeK1NtdlbyeE9d1j3gM/9EGoIMnpGws4XN9I5V6uR8WraAdQwloo4rHyKbzi6 cJFmrxg8+b4fO+CgXgGjMp+2CrnVceuMpZALzvgpzhcMTqHEZUJsO0n4mqfDWOhOyE07XRDGL22NUN RrzqHLvaRts9zZVdXTmKmKQya6oc09A== Received: from kaipn1.makisara.private (85-156-116-90.elisa-laajakaista.fi [85.156.116.90]) by fgw23.mail.saunalahti.fi (Halon) with ESMTPSA id 69a217c2-dd83-11ef-a25c-005056bdfda7; Tue, 28 Jan 2025 16:23:15 +0200 (EET) From: =?utf-8?q?Kai_M=C3=A4kisara?= To: linux-scsi@vger.kernel.org, dgilbert@interlog.com Cc: jmeneghi@redhat.com, =?utf-8?q?Kai_M=C3=A4kisara?= Subject: [RFC PATCH 4/6] scsi: scsi_debug: Add read support and update locate for tapes Date: Tue, 28 Jan 2025 16:22:48 +0200 Message-ID: <20250128142250.163901-5-Kai.Makisara@kolumbus.fi> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250128142250.163901-1-Kai.Makisara@kolumbus.fi> References: <20250128142250.163901-1-Kai.Makisara@kolumbus.fi> Precedence: bulk X-Mailing-List: linux-scsi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Support for the READ (6) and SPACE (6) commands for tapes based on the previous write patch is added. The LOCATE (10) command is updated to use the written data. Signed-off-by: Kai Mäkisara --- drivers/scsi/scsi_debug.c | 240 +++++++++++++++++++++++++++++++++++++- 1 file changed, 235 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 2f0c73bd37b8..912b1c6cf92d 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -532,7 +532,8 @@ enum sdeb_opcode_index { SDEB_I_READ_BLOCK_LIMITS = 33, SDEB_I_LOCATE = 34, SDEB_I_WRITE_FILEMARKS = 35, - SDEB_I_LAST_ELEM_P1 = 36, /* keep this last (previous + 1) */ + SDEB_I_SPACE = 36, + SDEB_I_LAST_ELEM_P1 = 37, /* keep this last (previous + 1) */ }; @@ -541,7 +542,7 @@ static const unsigned char opcode_ind_arr[256] = { SDEB_I_TEST_UNIT_READY, SDEB_I_REZERO_UNIT, 0, SDEB_I_REQUEST_SENSE, 0, SDEB_I_READ_BLOCK_LIMITS, 0, 0, SDEB_I_READ, 0, SDEB_I_WRITE, 0, 0, 0, 0, 0, - SDEB_I_WRITE_FILEMARKS, 0, SDEB_I_INQUIRY, 0, 0, + SDEB_I_WRITE_FILEMARKS, SDEB_I_SPACE, SDEB_I_INQUIRY, 0, 0, SDEB_I_MODE_SELECT, SDEB_I_RESERVE, SDEB_I_RELEASE, 0, 0, SDEB_I_MODE_SENSE, SDEB_I_START_STOP, 0, SDEB_I_SEND_DIAG, SDEB_I_ALLOW_REMOVAL, 0, @@ -625,6 +626,7 @@ static int resp_rwp_zone(struct scsi_cmnd *, struct sdebug_dev_info *); static int resp_read_blklimits(struct scsi_cmnd *, struct sdebug_dev_info *); static int resp_locate(struct scsi_cmnd *, struct sdebug_dev_info *); static int resp_write_filemarks(struct scsi_cmnd *, struct sdebug_dev_info *); +static int resp_space(struct scsi_cmnd *, struct sdebug_dev_info *); static int resp_rewind(struct scsi_cmnd *, struct sdebug_dev_info *); static int sdebug_do_add_host(bool mk_new_store); @@ -872,10 +874,12 @@ static const struct opcode_info_t opcode_info_arr[SDEB_I_LAST_ELEM_P1 + 1] = { {0, 0x05, 0, F_D_IN, resp_read_blklimits, NULL, /* READ BLOCK LIMITS (6) */ {6, 0, 0, 0, 0, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, {0, 0x2b, 0, F_D_UNKN, resp_locate, NULL, /* LOCATE (10) */ - {10, 0x2, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xc7, 0, 0, + {10, 0x07, 0, 0xff, 0xff, 0xff, 0xff, 0, 0xff, 0xc7, 0, 0, 0, 0, 0, 0} }, {0, 0x10, 0, F_D_IN, resp_write_filemarks, NULL, /* WRITE FILEMARKS (6) */ {6, 0x01, 0xff, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {0, 0x11, 0, F_D_IN, resp_space, NULL, /* SPACE (6) */ + {6, 0x07, 0xff, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, /* sentinel */ {0xff, 0, 0, 0, NULL, NULL, /* terminating element */ @@ -3298,6 +3302,9 @@ static int resp_locate(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) { unsigned char *cmd = scp->cmnd; + unsigned int i, pos; + struct tape_block *blp; + int partition; if ((cmd[1] & 0x02) != 0) { if (cmd[8] >= TAPE_MAX_PARTITIONS) { @@ -3306,8 +3313,19 @@ static int resp_locate(struct scsi_cmnd *scp, } devip->tape_partition = cmd[8]; } - devip->tape_location[devip->tape_partition] = - get_unaligned_be32(cmd + 3); + pos = get_unaligned_be32(cmd + 3); + partition = devip->tape_partition; + + for (i = 0, blp = devip->tape_blocks[partition]; + i < pos && i < devip->tape_eop[partition]; i++, blp++) + if (IS_TAPE_BLOCK_EOD(blp->fl_size)) + break; + if (i < pos) { + devip->tape_location[partition] = i; + mk_sense_buffer(scp, BLANK_CHECK, 0x05, 0); + return check_condition_result; + } + devip->tape_location[partition] = pos; return 0; } @@ -3342,6 +3360,123 @@ static int resp_write_filemarks(struct scsi_cmnd *scp, return 0; } +static int resp_space(struct scsi_cmnd *scp, + struct sdebug_dev_info *devip) +{ + unsigned char *cmd = scp->cmnd, code; + int i, pos, count; + struct tape_block *blp; + int partition = devip->tape_partition; + + count = get_unaligned_be24(cmd + 2); + if ((count & 0x800000) != 0) /* extend negative to 32-bit count */ + count |= 0xff000000; + code = cmd[1] & 0x0f; + + pos = devip->tape_location[partition]; + if (code == 0) { /* blocks */ + if (count < 0) { + count = (-count); + pos -= 1; + for (i = 0, blp = devip->tape_blocks[partition] + pos; i < count; + i++) { + if (pos < 0) + goto is_bop; + else if (IS_TAPE_BLOCK_FM(blp->fl_size)) + goto is_fm; + if (i > 0) { + pos--; + blp--; + } + } + } else if (count > 0) { + for (i = 0, blp = devip->tape_blocks[partition] + pos; i < count; + i++, pos++, blp++) { + if (IS_TAPE_BLOCK_EOD(blp->fl_size)) + goto is_eod; + if (IS_TAPE_BLOCK_FM(blp->fl_size)) { + pos += 1; + goto is_fm; + } + if (pos >= devip->tape_eop[partition]) + goto is_eop; + } + } + } else if (code == 1) { /* filemarks */ + if (count < 0) { + count = (-count); + if (pos == 0) + goto is_bop; + else { + for (i = 0, blp = devip->tape_blocks[partition] + pos; + i < count && pos >= 0; i++, pos--, blp--) { + for (pos--, blp-- ; !IS_TAPE_BLOCK_FM(blp->fl_size) && + pos >= 0; pos--, blp--) + ; /* empty */ + if (pos < 0) + goto is_bop; + } + } + pos += 1; + } else if (count > 0) { + for (i = 0, blp = devip->tape_blocks[partition] + pos; + i < count; i++, pos++, blp++) { + for ( ; !IS_TAPE_BLOCK_FM(blp->fl_size) && + !IS_TAPE_BLOCK_EOD(blp->fl_size) && + pos < devip->tape_eop[partition]; + pos++, blp++) + ; /* empty */ + if (IS_TAPE_BLOCK_EOD(blp->fl_size)) + goto is_eod; + if (pos >= devip->tape_eop[partition]) + goto is_eop; + } + } + } else if (code == 3) { /* EOD */ + for (blp = devip->tape_blocks[partition] + pos; + !IS_TAPE_BLOCK_EOD(blp->fl_size) && pos < devip->tape_eop[partition]; + pos++, blp++) + ; /* empty */ + if (pos >= devip->tape_eop[partition]) + goto is_eop; + } else { + /* sequential filemarks not supported */ + mk_sense_invalid_fld(scp, SDEB_IN_CDB, 8, -1); + return check_condition_result; + } + devip->tape_location[partition] = pos; + return 0; + +is_fm: + devip->tape_location[partition] = pos; + mk_sense_info_tape(scp, NO_SENSE, NO_ADDITIONAL_SENSE, + FILEMARK_DETECTED_ASCQ, count - i, + SENSE_FLAG_FILEMARK); + return check_condition_result; + +is_eod: + devip->tape_location[partition] = pos; + mk_sense_info_tape(scp, BLANK_CHECK, NO_ADDITIONAL_SENSE, + EOD_DETECTED_ASCQ, count - i, + 0); + return check_condition_result; + +is_bop: + devip->tape_location[partition] = 0; + mk_sense_info_tape(scp, NO_SENSE, NO_ADDITIONAL_SENSE, + BEGINNING_OF_P_M_DETECTED_ASCQ, count - i, + SENSE_FLAG_EOM); + devip->tape_location[partition] = 0; + return check_condition_result; + +is_eop: + devip->tape_location[partition] = devip->tape_eop[partition] - 1; + mk_sense_info_tape(scp, MEDIUM_ERROR, NO_ADDITIONAL_SENSE, + EOP_EOM_DETECTED_ASCQ, (unsigned int)i, + SENSE_FLAG_EOM); + return check_condition_result; +} + static int resp_rewind(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) { @@ -4083,6 +4218,98 @@ static int prot_verify_read(struct scsi_cmnd *scp, sector_t start_sec, return ret; } +static int resp_read_tape(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) +{ + u32 i, num, transfer, size; + u8 *cmd = scp->cmnd; + struct scsi_data_buffer *sdb = &scp->sdb; + int partition = devip->tape_partition; + u32 pos = devip->tape_location[partition]; + struct tape_block *blp; + bool fixed, sili; + + if (cmd[0] != READ_6) { /* Only Read(6) supported */ + mk_sense_invalid_opcode(scp); + return illegal_condition_result; + } + fixed = (cmd[1] & 0x1) != 0; + sili = (cmd[1] & 0x2) != 0; + if (fixed && sili) { + mk_sense_invalid_fld(scp, SDEB_IN_CDB, 1, 1); + return check_condition_result; + } + + transfer = get_unaligned_be24(cmd + 2); + if (fixed) { + num = transfer; + size = devip->tape_blksize; + } else { + if (transfer < TAPE_MIN_BLKSIZE || + transfer > TAPE_MAX_BLKSIZE) { + mk_sense_invalid_fld(scp, SDEB_IN_CDB, 2, -1); + return check_condition_result; + } + num = 1; + size = transfer; + } + + for (i = 0, blp = devip->tape_blocks[partition] + pos; + i < num && pos < devip->tape_eop[partition]; + i++, pos++, blp++) { + devip->tape_location[partition] = pos + 1; + if (IS_TAPE_BLOCK_FM(blp->fl_size)) { + mk_sense_info_tape(scp, NO_SENSE, NO_ADDITIONAL_SENSE, + FILEMARK_DETECTED_ASCQ, fixed ? num - i : size, + SENSE_FLAG_FILEMARK); + scsi_set_resid(scp, (num - i) * size); + return check_condition_result; + } + /* Assume no REW */ + if (IS_TAPE_BLOCK_EOD(blp->fl_size)) { + mk_sense_info_tape(scp, BLANK_CHECK, NO_ADDITIONAL_SENSE, + EOD_DETECTED_ASCQ, fixed ? num - i : size, + 0); + devip->tape_location[partition] = pos; + scsi_set_resid(scp, (num - i) * size); + return check_condition_result; + } + sg_zero_buffer(sdb->table.sgl, sdb->table.nents, + size, i * size); + sg_copy_buffer(sdb->table.sgl, sdb->table.nents, + &(blp->data), 4, i * size, false); + if (fixed) { + if (blp->fl_size != devip->tape_blksize) { + scsi_set_resid(scp, (num - i) * size); + mk_sense_info_tape(scp, NO_SENSE, NO_ADDITIONAL_SENSE, + 0, num - i, + SENSE_FLAG_ILI); + return check_condition_result; + } + } else { + if (blp->fl_size != size) { + if (blp->fl_size < size) + scsi_set_resid(scp, size - blp->fl_size); + if (!sili) { + mk_sense_info_tape(scp, NO_SENSE, NO_ADDITIONAL_SENSE, + 0, size - blp->fl_size, + SENSE_FLAG_ILI); + return check_condition_result; + } + } + } + } + if (pos >= devip->tape_eop[partition]) { + mk_sense_info_tape(scp, NO_SENSE, NO_ADDITIONAL_SENSE, + EOP_EOM_DETECTED_ASCQ, fixed ? num - i : size, + SENSE_FLAG_EOM); + devip->tape_location[partition] = pos - 1; + return check_condition_result; + } + devip->tape_location[partition] = pos; + + return 0; +} + static int resp_read_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) { bool check_prot; @@ -4094,6 +4321,9 @@ static int resp_read_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) u8 *cmd = scp->cmnd; bool meta_data_locked = false; + if (sdebug_ptype == TYPE_TAPE) + return resp_read_tape(scp, devip); + switch (cmd[0]) { case READ_16: ei_lba = 0; From patchwork Tue Jan 28 14:22:49 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Kai_M=C3=A4kisara?= X-Patchwork-Id: 860584 Received: from fgw20-4.mail.saunalahti.fi (fgw20-4.mail.saunalahti.fi [62.142.5.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3583819F11B for ; Tue, 28 Jan 2025 14:24:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.142.5.107 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738074278; cv=none; b=LSRHKU1lu8tCgieJfNL0zZkdVjRAKGawsXUFhOoBObN9s1kD3ElT5iPxs72/gEqDvx4sWT0UcWojxTDyDo8r385oQL2CfqYdO8ewzUkn48aMqXvtRnxZqaivu+6Gb7KBIZ3+VFMioEVBW+NA8kSa/GEZ6h0idfYtpjwXugKNDac= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738074278; c=relaxed/simple; bh=mINQUpI1X+b3DHHvEgZnXyQEM0o0IDBpOu1dkt9EwGI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=E7yK0UcoIwiTOitl78XzKHKpdkITHaBDoVekjsWBbJkeMWL4+QqYUGhdCu97XTfEM+A/ey/IA7cjxGEm0LAur+d63ifn88n9AssngMTh7dUNKeWGykyvXK3KpVoH7Bu2BulC7ELFPXUBywbEgQQmrs77OGrpkeuMCB2vGYaUjgA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=kolumbus.fi; spf=pass smtp.mailfrom=kolumbus.fi; dkim=pass (2048-bit key) header.d=kolumbus.fi header.i=@kolumbus.fi header.b=UXLON3p2; arc=none smtp.client-ip=62.142.5.107 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=kolumbus.fi Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kolumbus.fi Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kolumbus.fi header.i=@kolumbus.fi header.b="UXLON3p2" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kolumbus.fi; s=elisa1; h=content-transfer-encoding:content-type:mime-version:references:in-reply-to: message-id:date:subject:cc:to:from:from:to:cc:reply-to:subject:date: in-reply-to:references:list-archive:list-subscribe:list-unsubscribe: content-type:content-transfer-encoding:message-id; bh=G+RyuJJ81pSLT5gtmDqg/qBXzBTsufbLYGGhXZzNR2M=; b=UXLON3p2yL3zRSDjf/n6g06vrLQiOmc4nxg1twf4A0KtDCum3g4pKxxcYXkIi4JUN2r47LjDsvfv5 h6A1Iq6D0LOPV/aUUVaViU5qYVRwytvlCJGLHg5Ez5YrjV8h0VroJ2SLRr8rdskeqO2qLG5sWoFktz LLnR9R7V7+DxkkrsSWI/55mw8vRk/ggXUEC7AZ+XBzQvc34CQtE1172UUUNKJ2IbE7Z9xw6N8hU3t/ UgIppqBjOnHndI7jcWOKtQYclslq0Om3Lc6XF6n3DhNE5QDVUxDp2h+tF2laAtVTKpC8z1DdWATQr8 fX6wF3h9n1WdKroUxYjXEF5V0fzmNkw== Received: from kaipn1.makisara.private (85-156-116-90.elisa-laajakaista.fi [85.156.116.90]) by fgw23.mail.saunalahti.fi (Halon) with ESMTPSA id 6b41b66e-dd83-11ef-a25c-005056bdfda7; Tue, 28 Jan 2025 16:23:18 +0200 (EET) From: =?utf-8?q?Kai_M=C3=A4kisara?= To: linux-scsi@vger.kernel.org, dgilbert@interlog.com Cc: jmeneghi@redhat.com, =?utf-8?q?Kai_M=C3=A4kisara?= Subject: [RFC PATCH 5/6] scsi: scsi_debug: Add compression mode page for tapes Date: Tue, 28 Jan 2025 16:22:49 +0200 Message-ID: <20250128142250.163901-6-Kai.Makisara@kolumbus.fi> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250128142250.163901-1-Kai.Makisara@kolumbus.fi> References: <20250128142250.163901-1-Kai.Makisara@kolumbus.fi> Precedence: bulk X-Mailing-List: linux-scsi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add support for compression mode page. The compression status is saved and returned. No UA is generated. Signed-off-by: Kai Mäkisara --- drivers/scsi/scsi_debug.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 912b1c6cf92d..ceacf38cee71 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -405,6 +405,7 @@ struct sdebug_dev_info { unsigned int tape_blksize; unsigned int tape_density; unsigned char tape_partition; + unsigned char tape_dce; unsigned int tape_location[TAPE_MAX_PARTITIONS]; unsigned int tape_eop[TAPE_MAX_PARTITIONS]; struct tape_block *tape_blocks[TAPE_MAX_PARTITIONS]; @@ -2843,6 +2844,20 @@ static int resp_partition_m_pg(unsigned char *p, int pcontrol, int target) return sizeof(partition_pg); } +static int resp_compression_m_pg(unsigned char *p, int pcontrol, int target, + unsigned char dce) +{ /* Compression page for mode_sense (tape) */ + unsigned char compression_pg[] = {0x0f, 14, 0x40, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 00, 00}; + + memcpy(p, compression_pg, sizeof(compression_pg)); + if (dce) + p[2] |= 0x80; + if (pcontrol == 1) + memset(p + 2, 0, sizeof(compression_pg) - 2); + return sizeof(compression_pg); +} + /* PAGE_SIZE is more than necessary but provides room for future expansion. */ #define SDEBUG_MAX_MSENSE_SZ PAGE_SIZE @@ -2979,6 +2994,12 @@ static int resp_mode_sense(struct scsi_cmnd *scp, } offset += len; break; + case 0xf: /* Compression Mode Page (tape) */ + if (!is_tape) + goto bad_pcode; + len += resp_compression_m_pg(ap, pcontrol, target, devip->tape_dce); + offset += len; + break; case 0x11: /* Partition Mode Page (tape) */ if (!is_tape) goto bad_pcode; @@ -3132,6 +3153,14 @@ static int resp_mode_select(struct scsi_cmnd *scp, goto set_mode_changed_ua; } break; + case 0xf: /* Compression mode page */ + if (sdebug_ptype != TYPE_TAPE) + goto bad_pcode; + if ((arr[off + 2] & 0x40) != 0) { + devip->tape_dce = (arr[off + 2] & 0x80) != 0; + return 0; + } + break; case 0x1c: /* Informational Exceptions Mode page */ if (iec_m_pg[1] == arr[off + 1]) { memcpy(iec_m_pg + 2, arr + off + 2, @@ -3147,6 +3176,10 @@ static int resp_mode_select(struct scsi_cmnd *scp, set_mode_changed_ua: set_bit(SDEBUG_UA_MODE_CHANGED, devip->uas_bm); return 0; + +bad_pcode: + mk_sense_invalid_fld(scp, SDEB_IN_CDB, 2, 5); + return check_condition_result; } static int resp_temp_l_pg(unsigned char *arr) From patchwork Tue Jan 28 14:22:50 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Kai_M=C3=A4kisara?= X-Patchwork-Id: 860792 Received: from fgw21-4.mail.saunalahti.fi (fgw21-4.mail.saunalahti.fi [62.142.5.108]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7071226AFC for ; Tue, 28 Jan 2025 14:23:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.142.5.108 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738074224; cv=none; b=CYSPOJ4o2zl3tYokHlOB8oq3LqFMPvEHNwayXnqvcQML03TIcNWWAI0W1sOKyYS+rwZo+1PTqlywXIzYtaYzJ9ruJyGKdPiWgDec5w/Fj67aljJ/+6lmMOyNJljAundvlu3KpZY+8xYoXgYTgeJLyON8B+o9HuxVakYd2dIyxiE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738074224; c=relaxed/simple; bh=M4V0o920wPk3JAnnje4ukYTg9er9iN/OWPGE9UrUL+o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=k0/dTYlDVKYFe6JwaRcDyAhPLzf54xd6RXoptqIuSj6/wRD2OpDxzRtUXzfteXHJwWdYQwq9ATIBydLYWyTWHZuBzVc/oif6ITspY18+VQ18RLK/J3Cxl9ghWG26sdTUXekhssX4L0orgIMIePrCOX582iyoZnZlUJqVjKzllYQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=kolumbus.fi; spf=pass smtp.mailfrom=kolumbus.fi; dkim=pass (2048-bit key) header.d=kolumbus.fi header.i=@kolumbus.fi header.b=c1F63nvI; arc=none smtp.client-ip=62.142.5.108 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=kolumbus.fi Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kolumbus.fi Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kolumbus.fi header.i=@kolumbus.fi header.b="c1F63nvI" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kolumbus.fi; s=elisa1; h=content-transfer-encoding:content-type:mime-version:references:in-reply-to: message-id:date:subject:cc:to:from:from:to:cc:reply-to:subject:date: in-reply-to:references:list-archive:list-subscribe:list-unsubscribe: content-type:content-transfer-encoding:message-id; bh=TY7bfxzNMEh+jzYBN3KL7dgpUfFemZO6Mw/7ajBrC/M=; b=c1F63nvIlwLgtcQAOHJIihd7BTX0fea5ALgsZPppCLVJDldUkF8zHIBPOPwciYC5jEN16oJkaJLT1 dv/6M+AuY/6WytHDl+Q2BKLPx01T7bPkThJn5ldKBpgjrSUeN195lZ1FS8FoOhIaK0Yx7w6NbxcGEN NaZw+BTgHeCMqmE5xhiLPbVfCP1C8rKUiJDyzUd3gqOGdalYvTqwjfkUBsyp7EetRlf2lXwQ26ktKL PY6H6VIkOfk75shf80TgF58rKCgtSVE2rKDJeIfBJug8+7ktu7MwMXslsZSViORKO7IO4c9wVf03fB dsklzGFv6jJmco9d++bVacxK6Rkzlqw== Received: from kaipn1.makisara.private (85-156-116-90.elisa-laajakaista.fi [85.156.116.90]) by fgw23.mail.saunalahti.fi (Halon) with ESMTPSA id 6d2b2707-dd83-11ef-a25c-005056bdfda7; Tue, 28 Jan 2025 16:23:21 +0200 (EET) From: =?utf-8?q?Kai_M=C3=A4kisara?= To: linux-scsi@vger.kernel.org, dgilbert@interlog.com Cc: jmeneghi@redhat.com, =?utf-8?q?Kai_M=C3=A4kisara?= Subject: [RFC PATCH 6/6] scsi: scsi_debug: Reset tape setting at device reset Date: Tue, 28 Jan 2025 16:22:50 +0200 Message-ID: <20250128142250.163901-7-Kai.Makisara@kolumbus.fi> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250128142250.163901-1-Kai.Makisara@kolumbus.fi> References: <20250128142250.163901-1-Kai.Makisara@kolumbus.fi> Precedence: bulk X-Mailing-List: linux-scsi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Set tape block size, density and compression to default values when the device is reset (either directly or via target, bus or host reset). Signed-off-by: Kai Mäkisara --- drivers/scsi/scsi_debug.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index ceacf38cee71..c5d7e8b59ff2 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -6730,6 +6730,20 @@ static int sdebug_fail_lun_reset(struct scsi_cmnd *cmnd) return 0; } +static void scsi_tape_reset_clear(struct sdebug_dev_info *devip) +{ + if (sdebug_ptype == TYPE_TAPE) { + int i; + + devip->tape_blksize = TAPE_DEF_BLKSIZE; + devip->tape_density = TAPE_DEF_DENSITY; + devip->tape_partition = 0; + devip->tape_dce = 0; + for (i = 0; i < TAPE_MAX_PARTITIONS; i++) + devip->tape_location[i] = 0; + } +} + static int scsi_debug_device_reset(struct scsi_cmnd *SCpnt) { struct scsi_device *sdp = SCpnt->device; @@ -6743,8 +6757,10 @@ static int scsi_debug_device_reset(struct scsi_cmnd *SCpnt) sdev_printk(KERN_INFO, sdp, "%s\n", __func__); scsi_debug_stop_all_queued(sdp); - if (devip) + if (devip) { set_bit(SDEBUG_UA_POR, devip->uas_bm); + scsi_tape_reset_clear(devip); + } if (sdebug_fail_lun_reset(SCpnt)) { scmd_printk(KERN_INFO, SCpnt, "fail lun reset 0x%x\n", opcode); @@ -6782,6 +6798,7 @@ static int scsi_debug_target_reset(struct scsi_cmnd *SCpnt) list_for_each_entry(devip, &sdbg_host->dev_info_list, dev_list) { if (devip->target == sdp->id) { set_bit(SDEBUG_UA_BUS_RESET, devip->uas_bm); + scsi_tape_reset_clear(devip); ++k; } } @@ -6813,6 +6830,7 @@ static int scsi_debug_bus_reset(struct scsi_cmnd *SCpnt) list_for_each_entry(devip, &sdbg_host->dev_info_list, dev_list) { set_bit(SDEBUG_UA_BUS_RESET, devip->uas_bm); + scsi_tape_reset_clear(devip); ++k; } @@ -6836,6 +6854,7 @@ static int scsi_debug_host_reset(struct scsi_cmnd *SCpnt) list_for_each_entry(devip, &sdbg_host->dev_info_list, dev_list) { set_bit(SDEBUG_UA_BUS_RESET, devip->uas_bm); + scsi_tape_reset_clear(devip); ++k; } }