From 4912e5b2089a0acf89e107aed68d627ccdf28eb7 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Mon, 9 Jan 2017 16:01:08 +0000 Subject: [PATCH] scsi: implement decoding of all SG_* ioctl commands * print_sg_req_info.c: New file. * Makefile.am (strace_SOURCES): Add it. * xlat/sg_scsi_reset.in: New file. * scsi.c: Include "xlat/sg_scsi_reset.h". (scsi_ioctl): Implement decoding of all SG_* ioctl commands. --- Makefile.am | 1 + print_sg_req_info.c | 74 ++++++++++++++++++++++++++++++ scsi.c | 103 ++++++++++++++++++++++++++++++++++++++++++ xlat/sg_scsi_reset.in | 6 +++ 4 files changed, 184 insertions(+) create mode 100644 print_sg_req_info.c create mode 100644 xlat/sg_scsi_reset.in diff --git a/Makefile.am b/Makefile.am index da5bfa21..25caf9a6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -185,6 +185,7 @@ strace_SOURCES = \ print_dev_t.c \ print_mq_attr.c \ print_msgbuf.c \ + print_sg_req_info.c \ print_sigevent.c \ print_statfs.c \ print_struct_stat.c \ diff --git a/print_sg_req_info.c b/print_sg_req_info.c new file mode 100644 index 00000000..9f0249ec --- /dev/null +++ b/print_sg_req_info.c @@ -0,0 +1,74 @@ +/* + * Decode struct sg_req_info. + * + * Copyright (c) 2017 Dmitry V. Levin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "defs.h" + +#ifdef HAVE_SCSI_SG_H + +#include DEF_MPERS_TYPE(struct_sg_req_info) + +# include + +typedef struct sg_req_info struct_sg_req_info; + +#endif /* HAVE_SCSI_SG_H */ + +#include MPERS_DEFS + +#ifdef HAVE_SCSI_SG_H + +MPERS_PRINTER_DECL(int, decode_sg_req_info, + struct tcb *const tcp, const kernel_ulong_t arg) +{ + struct_sg_req_info info; + + if (entering(tcp)) + return 0; + + tprints(", "); + if (!umove_or_printaddr(tcp, arg, &info)) { + tprintf("{req_state=%hhd" + ", orphan=%hhd" + ", sg_io_owned=%hhd" + ", problem=%hhd" + ", pack_id=%d" + ", usr_ptr=", + info.req_state, + info.orphan, + info.sg_io_owned, + info.problem, + info.pack_id); + printaddr(ptr_to_kulong(info.usr_ptr)); + tprintf(", duration=%u}", info.duration); + } + + return RVAL_DECODED | 1; +} + +#endif /* HAVE_SCSI_SG_H */ diff --git a/scsi.c b/scsi.c index 1f6fafa3..35796201 100644 --- a/scsi.c +++ b/scsi.c @@ -33,6 +33,7 @@ #endif #include "xlat/scsi_sg_commands.h" +#include "xlat/sg_scsi_reset.h" static int decode_sg_io(struct tcb *const tcp, const uint32_t iid, @@ -50,6 +51,38 @@ decode_sg_io(struct tcb *const tcp, const uint32_t iid, } +#ifdef HAVE_SCSI_SG_H + +static int +decode_sg_scsi_id(struct tcb *const tcp, const kernel_ulong_t arg) +{ + struct sg_scsi_id id; + + if (entering(tcp)) + return 0; + + tprints(", "); + if (!umove_or_printaddr(tcp, arg, &id)) { + tprintf("{host_no=%d" + ", channel=%d" + ", scsi_id=%#x" + ", lun=%d" + ", scsi_type=%#x" + ", h_cmd_per_lun=%hd" + ", d_queue_depth=%hd}", + id.host_no, + id.channel, + id.scsi_id, + id.lun, + id.scsi_type, + id.h_cmd_per_lun, + id.d_queue_depth); + } + return RVAL_DECODED | 1; +} + +#endif /* HAVE_SCSI_SG_H */ + int scsi_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg) @@ -72,6 +105,76 @@ scsi_ioctl(struct tcb *const tcp, const unsigned int code, tprints("}"); break; } + +#ifdef HAVE_SCSI_SG_H + /* returns struct sg_scsi_id */ + case SG_GET_SCSI_ID: + return decode_sg_scsi_id(tcp, arg); + /* returns struct sg_req_info */ + case SG_GET_REQUEST_TABLE: + return decode_sg_req_info(tcp, arg); +#endif /* HAVE_SCSI_SG_H */ + + /* takes a value by pointer */ + case SG_SCSI_RESET: { + unsigned int val; + tprints(", "); + if (!umove_or_printaddr(tcp, arg, &val)) { + tprints("["); + if (val & SG_SCSI_RESET_NO_ESCALATE) { + printxval(sg_scsi_reset, + SG_SCSI_RESET_NO_ESCALATE, 0); + tprints("|"); + } + printxval(sg_scsi_reset, + val & ~SG_SCSI_RESET_NO_ESCALATE, + "SG_SCSI_RESET_???"); + tprints("]"); + + } + break; + } + + /* takes a signed int by pointer */ + case SG_NEXT_CMD_LEN: + case SG_SET_COMMAND_Q: + case SG_SET_DEBUG: + case SG_SET_FORCE_LOW_DMA: + case SG_SET_FORCE_PACK_ID: + case SG_SET_KEEP_ORPHAN: + case SG_SET_RESERVED_SIZE: + case SG_SET_TIMEOUT: + tprints(", "); + printnum_int(tcp, arg, "%d"); + break; + + /* returns a signed int by pointer */ + case SG_EMULATED_HOST: + case SG_GET_ACCESS_COUNT: + case SG_GET_COMMAND_Q: + case SG_GET_KEEP_ORPHAN: + case SG_GET_LOW_DMA: + case SG_GET_NUM_WAITING: + case SG_GET_PACK_ID: + case SG_GET_RESERVED_SIZE: + case SG_GET_SG_TABLESIZE: + case SG_GET_TRANSFORM: + case SG_GET_VERSION_NUM: + if (entering(tcp)) + return 0; + tprints(", "); + printnum_int(tcp, arg, "%d"); + break; + + /* takes an integer by value */ + case SG_SET_TRANSFORM: + tprintf(", %#x", (unsigned int) arg); + break; + + /* no arguments */ + case SG_GET_TIMEOUT: + break; + default: return RVAL_DECODED; } diff --git a/xlat/sg_scsi_reset.in b/xlat/sg_scsi_reset.in new file mode 100644 index 00000000..0df4a90d --- /dev/null +++ b/xlat/sg_scsi_reset.in @@ -0,0 +1,6 @@ +SG_SCSI_RESET_NOTHING 0 +SG_SCSI_RESET_DEVICE 1 +SG_SCSI_RESET_BUS 2 +SG_SCSI_RESET_HOST 3 +SG_SCSI_RESET_TARGET 4 +SG_SCSI_RESET_NO_ESCALATE 0x100 -- 2.40.0