/*
 * Copyright (c) 2007 Vladimir Nadvornik <nadvornik@suse.cz>
 * Copyright (c) 2007-2017 Dmitry V. Levin <ldv@altlinux.org>
 * 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 <scsi/sg.h>
#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,
	     const kernel_ulong_t arg)
{
	switch (iid) {
		case 'S':
			return decode_sg_io_v3(tcp, arg);
		case 'Q':
			return decode_sg_io_v4(tcp, arg);
		default:
			tprintf("[%u]", iid);
			return RVAL_IOCTL_DECODED;
	}

}

#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_IOCTL_DECODED;
}

#endif /* HAVE_SCSI_SG_H */

int
scsi_ioctl(struct tcb *const tcp, const unsigned int code,
	   const kernel_ulong_t arg)
{
	switch (code) {
	case SG_IO:
		if (entering(tcp)) {
			uint32_t iid;

			tprints(", ");
			if (umove_or_printaddr(tcp, arg, &iid)) {
				break;
			} else {
				return decode_sg_io(tcp, iid, arg);
			}
		} else {
			uint32_t *piid = get_tcb_priv_data(tcp);
			if (piid)
				decode_sg_io(tcp, *piid, arg);
			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;
	}

	return RVAL_IOCTL_DECODED;
}
