From nobody Thu Dec 28 21:24:09 2023 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4T1M2d2P6Rz54gDW; Thu, 28 Dec 2023 21:24:09 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4T1M2d1VjSz4dww; Thu, 28 Dec 2023 21:24:09 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1703798649; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Va6JlhQP72fUnjUnl+0nPcRjQmfVozTi2gD8Jt6qFWU=; b=FV7IbmqcCB8DSNKHYFNnq7O4oG/e7ATJtDPylK1nR5NnpBNPI3n7mLKXVnz0Iq/+M5D6dg h/QbuL0PADAyrRmiSheDRv3aB3PxNg1U2wH8ZdiKbmNwNN00lgESeR3s1spZwH+7AFE7Up OIFcRK6BRvH/97Go674imVQ9W6GIftRDZ7dwPG2y9U0SgKYRaHDR6j9SbXFCMLm4Prfxqo KWh2iPSKVtdWWmAe+VfgehrlD+LwuFk/eTpRRpkY9Mm6KKn/UoJIrbW99G6fuiL94auRs2 sKEhdwR5cfC28dy8rJnyzUj7lYGKS7p2iX+9b/O3JGwX5mQp/1L4Oqd4N9ip6Q== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1703798649; a=rsa-sha256; cv=none; b=LGnPB19VUPE13WnGE+KXF4x7auS3Fkhp3L0603oLsR2fHcvlKqi053nZSlhnHnglSVaAw3 GK35gAJx+syzCEmHUEtNAqBOyuIVf7XHmMljb7fiOQoo6UFi9klDjAg4xuRvwHgjewaHLK fA4mhnR4wR1H+2ctSFFBjITUZ7O1FRPs1nBfg/lKgrQl0hlr/fYoyPjKHNPhrN/oFBC2hV bzhTIpxu/guZocMmtfrQbBAFP3nKWebyZa+4Ln233XixTbL0BydxOvX0FDQpv6TP7WyqbW R+FnTtbfErVX2uri1Xi2A8ha6jlVbQcLxamLkYdb1yGIaO/0gmxSfT7HCQVWmw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1703798649; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Va6JlhQP72fUnjUnl+0nPcRjQmfVozTi2gD8Jt6qFWU=; b=LZR4HZRhGlOk3OzgzTLifz+M1gmbOWYAacHY3ufUDzfP3uV5wDw+42TBuBE+wJxBa4YPvB wrUcaulS3qwH4skrCk6E4qGFLwzQWyIqvnSEyKb72jjlmxSgN6M0XDvzyuNA3k05PE245Q 1CEuOBjjNSeZ0p1cpPJx8Kq267h6mCz+gPu39/KJ0Xotv3WRiDdfynAhPLY2w07jpBlqZ5 AvArSKyOeUuoCYzba47/a84H98kNQO4jYWvTqa3MLE27peVIoDkEDeWjEdc985F0I4cIf4 bf6/UMXBPTzOc859n6LjcXd7dAlyng5MT8qmNeHPuXlDTwfLeufHfH+jIm6ADw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4T1M2d0ZYPzf6n; Thu, 28 Dec 2023 21:24:09 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 3BSLO9xs091690; Thu, 28 Dec 2023 21:24:09 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 3BSLO9cN091687; Thu, 28 Dec 2023 21:24:09 GMT (envelope-from git) Date: Thu, 28 Dec 2023 21:24:09 GMT Message-Id: <202312282124.3BSLO9cN091687@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: "Kenneth D. Merry" Subject: git: 40a492d38ee1 - main - camcontrol: Add a sense subcommand List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: ken X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 40a492d38ee10ecf9d9a099c5cdecc072e24d2d1 Auto-Submitted: auto-generated The branch main has been updated by ken: URL: https://cgit.FreeBSD.org/src/commit/?id=40a492d38ee10ecf9d9a099c5cdecc072e24d2d1 commit 40a492d38ee10ecf9d9a099c5cdecc072e24d2d1 Author: Kenneth D. Merry AuthorDate: 2023-12-28 21:23:16 +0000 Commit: Kenneth D. Merry CommitDate: 2023-12-28 21:23:16 +0000 camcontrol: Add a sense subcommand As the name suggests, this sends a SCSI REQUEST SENSE to a device, and prints out decoded sense information. It can also print out a hexdump of the sense data. sbin/camcontrol/camcontrol.c: Add the new sense subcommand. sbin/camcontrol/camcontrol.8: Document camcontrol sense. Sponsored by: Spectra Logic Reviewed by: mav MFC after: 3 days Differential Revision: https://reviews.freebsd.org/D43225 --- sbin/camcontrol/camcontrol.8 | 17 +++++- sbin/camcontrol/camcontrol.c | 122 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+), 1 deletion(-) diff --git a/sbin/camcontrol/camcontrol.8 b/sbin/camcontrol/camcontrol.8 index 2113c4fb2aab..0151376ff39f 100644 --- a/sbin/camcontrol/camcontrol.8 +++ b/sbin/camcontrol/camcontrol.8 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd June 1, 2023 +.Dd December 28, 2023 .Dt CAMCONTROL 8 .Os .Sh NAME @@ -51,6 +51,12 @@ .Op device id .Op generic args .Nm +.Ic sense +.Op device id +.Op generic args +.Op Fl D +.Op Fl x +.Nm .Ic inquiry .Op device id .Op generic args @@ -488,6 +494,15 @@ Send the SCSI test unit ready (0x00) command to the given device. The .Nm utility will report whether the device is ready or not. +.It Ic sense +Send a SCSI REQUEST SENSE command (0x03) to a device. +The decoded sense (or hexdump) is printed to stdout. +.Bl -tag -width 4n +.It Fl D +Request descriptor sense instead of fixed sense. +.It Fl x +Do a hexdump of the returned sense data. +.El .It Ic inquiry Send a SCSI inquiry command (0x12) to a device. By default, diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c index 9417943afcb3..555a67001443 100644 --- a/sbin/camcontrol/camcontrol.c +++ b/sbin/camcontrol/camcontrol.c @@ -111,6 +111,7 @@ typedef enum { CAM_CMD_DEVTYPE, CAM_CMD_AMA, CAM_CMD_DEPOP, + CAM_CMD_REQSENSE } cam_cmd; typedef enum { @@ -233,6 +234,7 @@ static struct camcontrol_opts option_table[] = { {"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"}, {"timestamp", CAM_CMD_TIMESTAMP, CAM_ARG_NONE, "f:mrsUT:"}, {"depop", CAM_CMD_DEPOP, CAM_ARG_NONE, "ac:de:ls"}, + {"sense", CAM_CMD_REQSENSE, CAM_ARG_NONE, "Dx"}, {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL}, {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL}, {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL}, @@ -279,6 +281,9 @@ static int print_dev_mmcsd(struct device_match_result *dev_result, #ifdef WITH_NVME static int print_dev_nvme(struct device_match_result *dev_result, char *tmpstr); #endif +static int requestsense(struct cam_device *device, int argc, char **argv, + char *combinedopt, int task_attr, int retry_count, + int timeout); static int testunitready(struct cam_device *device, int task_attr, int retry_count, int timeout, int quiet); static int scsistart(struct cam_device *device, int startstop, int loadeject, @@ -840,6 +845,114 @@ print_dev_nvme(struct device_match_result *dev_result, char *tmpstr) } #endif +static int +requestsense(struct cam_device *device, int argc, char **argv, + char *combinedopt, int task_attr, int retry_count, int timeout) +{ + int c; + int descriptor_sense = 0; + int do_hexdump = 0; + struct scsi_sense_data sense; + union ccb *ccb = NULL; + int error = 0; + size_t returned_bytes; + + while ((c = getopt(argc, argv, combinedopt)) != -1) { + switch (c) { + case 'D': + descriptor_sense = 1; + break; + case 'x': + do_hexdump = 1; + break; + default: + break; + } + } + + ccb = cam_getccb(device); + if (ccb == NULL) { + warnx("couldn't allocate CCB"); + return (1); + } + + /* cam_getccb cleans up the header, caller has to zero the payload */ + CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); + + bzero(&sense, sizeof(sense)); + + scsi_request_sense(&ccb->csio, + /*retries*/ retry_count, + /*cbfcnp*/ NULL, + /*data_ptr*/ (void *)&sense, + /*dxfer_len*/ sizeof(sense), + /*tag_action*/ task_attr, + /*sense_len*/ SSD_FULL_SIZE, + /*timeout*/ timeout ? timeout : 60000); + + if (descriptor_sense != 0) { + struct scsi_request_sense *cdb; + + cdb = (struct scsi_request_sense *)&ccb->csio.cdb_io.cdb_bytes; + cdb->byte2 |= SRS_DESC; + } + + ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; + + if (arglist & CAM_ARG_ERR_RECOVER) + ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; + + if (cam_send_ccb(device, ccb) < 0) { + warn("error sending REQUEST SENSE command"); + cam_freeccb(ccb); + error = 1; + goto bailout; + } + + /* + * REQUEST SENSE is not generally supposed to fail. But there can + * be transport or other errors that might cause it to fail. It + * may also fail if the user asks for descriptor sense and the + * device doesn't support it. So we check the CCB status here to see. + */ + if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { + warnx("REQUEST SENSE failed"); + cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); + error = 1; + goto bailout; + } + + returned_bytes = ccb->csio.dxfer_len - ccb->csio.resid; + + if (do_hexdump != 0) { + hexdump(&sense, returned_bytes, NULL, 0); + } else { + char path_str[80]; + struct sbuf *sb; + + cam_path_string(device, path_str, sizeof(path_str)); + sb = sbuf_new_auto(); + if (sb == NULL) { + warnx("%s: cannot allocate sbuf", __func__); + error = 1; + goto bailout; + } + + scsi_sense_only_sbuf(&sense, returned_bytes, sb, path_str, + &device->inq_data, scsiio_cdb_ptr(&ccb->csio), + ccb->csio.cdb_len); + + sbuf_finish(sb); + printf("%s", sbuf_data(sb)); + sbuf_delete(sb); + } +bailout: + if (ccb != NULL) + cam_freeccb(ccb); + + return (error); +} + static int testunitready(struct cam_device *device, int task_attr, int retry_count, int timeout, int quiet) @@ -9869,6 +9982,7 @@ usage(int printlong) " camcontrol devlist [-b] [-v]\n" " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n" " camcontrol tur [dev_id][generic args]\n" +" camcontrol sense [dev_id][generic args][-D][-x]\n" " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n" " camcontrol identify [dev_id][generic args] [-v]\n" " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n" @@ -9957,6 +10071,7 @@ usage(int printlong) "Specify one of the following options:\n" "devlist list all CAM devices\n" "periphlist list all CAM peripheral drivers attached to a device\n" +"sense send a request sense command to the named device\n" "tur send a test unit ready to the named device\n" "inquiry send a SCSI inquiry command to the named device\n" "identify send a ATA identify command to the named device\n" @@ -10021,6 +10136,9 @@ usage(int printlong) "-f format specify defect list format (block, bfi or phys)\n" "-G get the grown defect list\n" "-P get the permanent defect list\n" +"sense arguments:\n" +"-D request descriptor sense data\n" +"-x do a hexdump of the sense data\n" "inquiry arguments:\n" "-D get the standard inquiry data\n" "-S get the serial number\n" @@ -10491,6 +10609,10 @@ main(int argc, char **argv) case CAM_CMD_DEVTYPE: error = getdevtype(cam_dev); break; + case CAM_CMD_REQSENSE: + error = requestsense(cam_dev, argc, argv, combinedopt, + task_attr, retry_count, timeout); + break; case CAM_CMD_TUR: error = testunitready(cam_dev, task_attr, retry_count, timeout, 0);