Mercurial > unleashed > wips
changeset 20579:2727d178ec5b
9821 want a way to run vendor-specific commands via libscsi
Reviewed by: Bryan Cantrill <bryan@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Approved by: Richard Lowe <richlowe@richlowe.net>
author | Robert Mustacchi <rm@joyent.com> |
---|---|
date | Sat, 08 Sep 2018 22:39:06 +0000 |
parents | 6e15a783e3f0 |
children | 7acd63403bc1 |
files | usr/src/lib/scsi/libscsi/common/libscsi.h usr/src/lib/scsi/libscsi/common/scsi_engine.c usr/src/lib/scsi/libscsi/libscsi_api.map usr/src/lib/scsi/libscsi/mapfile-vers usr/src/lib/scsi/plugins/scsi/engines/uscsi/uscsi.c |
diffstat | 5 files changed, 52 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/lib/scsi/libscsi/common/libscsi.h Thu Jan 10 17:09:29 2019 +0200 +++ b/usr/src/lib/scsi/libscsi/common/libscsi.h Sat Sep 08 22:39:06 2018 +0000 @@ -21,6 +21,7 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, Joyent, Inc. */ #ifndef _LIBSCSI_H @@ -125,8 +126,11 @@ extern libscsi_action_t *libscsi_action_alloc(libscsi_hdl_t *, spc3_cmd_t, uint_t, void *, size_t); +extern libscsi_action_t *libscsi_action_alloc_vendor(libscsi_hdl_t *, + spc3_cmd_t, size_t, uint_t, void *, size_t); extern sam4_status_t libscsi_action_get_status(const libscsi_action_t *); extern void libscsi_action_set_timeout(libscsi_action_t *, uint32_t); +extern size_t libscsi_action_get_cdblen(const libscsi_action_t *); extern uint32_t libscsi_action_get_timeout(const libscsi_action_t *); extern uint_t libscsi_action_get_flags(const libscsi_action_t *); extern uint8_t *libscsi_action_get_cdb(const libscsi_action_t *);
--- a/usr/src/lib/scsi/libscsi/common/scsi_engine.c Thu Jan 10 17:09:29 2019 +0200 +++ b/usr/src/lib/scsi/libscsi/common/scsi_engine.c Sat Sep 08 22:39:06 2018 +0000 @@ -21,6 +21,7 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, Joyent, Inc. */ #include <sys/types.h> @@ -265,6 +266,18 @@ } /* + * Return the length of the CDB buffer associated with this action. Never + * fails. + */ +size_t +libscsi_action_get_cdblen(const libscsi_action_t *ap) +{ + const libscsi_action_impl_t *aip = (const libscsi_action_impl_t *)ap; + + return (aip->lsai_cdb_len); +} + +/* * Returns the address of the action's CDB. The CDB buffer is guaranteed to * be large enough to hold the complete CDB for the command specified when the * action was allocated. Therefore, changing the command/opcode portion of @@ -469,11 +482,11 @@ * If cmd is SPC3_CMD_REQUEST_SENSE, this flag must be clear. */ libscsi_action_t * -libscsi_action_alloc(libscsi_hdl_t *hp, spc3_cmd_t cmd, uint_t flags, - void *buf, size_t buflen) +libscsi_action_alloc_vendor(libscsi_hdl_t *hp, spc3_cmd_t cmd, size_t cdbsz, + uint_t flags, void *buf, size_t buflen) { libscsi_action_impl_t *aip; - size_t cdbsz, sz; + size_t sz; ptrdiff_t off; /* @@ -492,14 +505,14 @@ "in order to use a buffer"); return (NULL); } - if (cmd == SPC3_CMD_REQUEST_SENSE && (flags & LIBSCSI_AF_RQSENSE)) { - (void) libscsi_error(hp, ESCSI_BADFLAGS, "request sense " - "flag not allowed for request sense command"); + + if (cdbsz == 0) { + (void) libscsi_error(hp, ESCSI_BADLENGTH, "the supplied CDB " + "buffer size has an invalid length, it must be non-zero."); return (NULL); } - if ((sz = cdbsz = libscsi_cmd_cdblen(hp, cmd)) == 0) - return (NULL); + sz = cdbsz; /* * If the caller has asked for a buffer but has not provided one, we @@ -549,6 +562,25 @@ return ((libscsi_action_t *)aip); } +libscsi_action_t * +libscsi_action_alloc(libscsi_hdl_t *hp, spc3_cmd_t cmd, uint_t flags, + void *buf, size_t buflen) +{ + size_t cdbsz; + + if (cmd == SPC3_CMD_REQUEST_SENSE && (flags & LIBSCSI_AF_RQSENSE)) { + (void) libscsi_error(hp, ESCSI_BADFLAGS, "request sense " + "flag not allowed for request sense command"); + return (NULL); + } + + if ((cdbsz = libscsi_cmd_cdblen(hp, cmd)) == 0) + return (NULL); + + return (libscsi_action_alloc_vendor(hp, cmd, cdbsz, flags, buf, + buflen)); +} + void libscsi_action_free(libscsi_action_t *ap) {
--- a/usr/src/lib/scsi/libscsi/libscsi_api.map Thu Jan 10 17:09:29 2019 +0200 +++ b/usr/src/lib/scsi/libscsi/libscsi_api.map Sat Sep 08 22:39:06 2018 +0000 @@ -21,6 +21,7 @@ # # Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2017, Joyent, Inc. # $mapfile_version 2 @@ -40,6 +41,7 @@ libscsi_action_get_timeout { TYPE = FUNCTION; FLAGS = extern }; libscsi_action_get_flags { TYPE = FUNCTION; FLAGS = extern }; libscsi_action_get_cdb { TYPE = FUNCTION; FLAGS = extern }; + libscsi_action_get_cdblen { TYPE = FUNCTION; FLAGS = extern }; libscsi_action_get_buffer { TYPE = FUNCTION; FLAGS = extern }; libscsi_action_get_sense { TYPE = FUNCTION; FLAGS = extern }; libscsi_action_set_status { TYPE = FUNCTION; FLAGS = extern };
--- a/usr/src/lib/scsi/libscsi/mapfile-vers Thu Jan 10 17:09:29 2019 +0200 +++ b/usr/src/lib/scsi/libscsi/mapfile-vers Sat Sep 08 22:39:06 2018 +0000 @@ -21,6 +21,7 @@ # # Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2017, Joyent, Inc. # # @@ -46,11 +47,13 @@ libscsi_open; libscsi_close; libscsi_action_alloc; + libscsi_action_alloc_vendor; libscsi_action_get_status; libscsi_action_set_status; libscsi_action_get_timeout; libscsi_action_set_timeout; libscsi_action_get_cdb; + libscsi_action_get_cdblen; libscsi_action_get_flags; libscsi_action_get_buffer; libscsi_action_get_sense;
--- a/usr/src/lib/scsi/plugins/scsi/engines/uscsi/uscsi.c Thu Jan 10 17:09:29 2019 +0200 +++ b/usr/src/lib/scsi/plugins/scsi/engines/uscsi/uscsi.c Sat Sep 08 22:39:06 2018 +0000 @@ -22,10 +22,10 @@ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright (c) 2017, Joyent, Inc. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/scsi/impl/uscsi.h> #include <sys/scsi/generic/commands.h> @@ -150,7 +150,7 @@ cmd.uscsi_timeout = (short)libscsi_action_get_timeout(ap); cmd.uscsi_cdb = (caddr_t)cp; - cmd.uscsi_cdblen = libscsi_cmd_cdblen(hp, *cp); + cmd.uscsi_cdblen = libscsi_action_get_cdblen(ap); if (cmd.uscsi_cdblen == 0) return (-1);