Skip to content

Commit

Permalink
9821 want a way to run vendor-specific commands via libscsi
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
rmustacc committed Jan 10, 2019
1 parent 095ab6c commit b75e7d7
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 11 deletions.
4 changes: 4 additions & 0 deletions usr/src/lib/scsi/libscsi/common/libscsi.h
Expand Up @@ -21,6 +21,7 @@

/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, Joyent, Inc.
*/

#ifndef _LIBSCSI_H
Expand Down Expand Up @@ -125,8 +126,11 @@ extern libscsi_errno_t libscsi_errcode(const char *);

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 *);
Expand Down
48 changes: 40 additions & 8 deletions usr/src/lib/scsi/libscsi/common/scsi_engine.c
Expand Up @@ -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>
Expand Down Expand Up @@ -264,6 +265,18 @@ libscsi_action_get_flags(const libscsi_action_t *ap)
return (aip->lsai_flags);
}

/*
* 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
Expand Down Expand Up @@ -469,11 +482,11 @@ libscsi_action_set_senselen(libscsi_action_t *ap, size_t len)
* 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;

/*
Expand All @@ -492,14 +505,14 @@ libscsi_action_alloc(libscsi_hdl_t *hp, spc3_cmd_t cmd, uint_t flags,
"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
Expand Down Expand Up @@ -549,6 +562,25 @@ libscsi_action_alloc(libscsi_hdl_t *hp, spc3_cmd_t cmd, uint_t flags,
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)
{
Expand Down
2 changes: 2 additions & 0 deletions usr/src/lib/scsi/libscsi/libscsi_api.map
Expand Up @@ -21,6 +21,7 @@

#
# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2017, Joyent, Inc.
#

$mapfile_version 2
Expand All @@ -40,6 +41,7 @@ SYMBOL_SCOPE {
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 };
Expand Down
3 changes: 3 additions & 0 deletions usr/src/lib/scsi/libscsi/mapfile-vers
Expand Up @@ -21,6 +21,7 @@

#
# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2017, Joyent, Inc.
#

#
Expand All @@ -46,11 +47,13 @@ SYMBOL_VERSION SUNWprivate_1.1 {
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;
Expand Down
6 changes: 3 additions & 3 deletions usr/src/lib/scsi/plugins/scsi/engines/uscsi/uscsi.c
Expand Up @@ -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>
Expand Down Expand Up @@ -150,7 +150,7 @@ uscsi_exec(libscsi_hdl_t *hp, void *private, libscsi_action_t *ap)
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);

Expand Down

0 comments on commit b75e7d7

Please sign in to comment.