/*
 *  common.h
 *
 *  Copyright (C) 2007 - 2018 Vladislav Bolkhovitin <vst@vlnb.net>
 *  Copyright (C) 2007 - 2018 Western Digital Corporation
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation, version 2
 *  of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 */

#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>

#include <scst_user.h>

#include "debug.h"

#ifndef WRITE_SAME_10
#define WRITE_SAME_10	      0x41
#endif

/* 8 byte ASCII Vendor */
#define VENDOR				"ACTIFIO"
/* 4 byte ASCII Product Revision Level - left aligned */
#define FIO_REV				"370 "

#define MAX_USN_LEN			(20+1) /* For '\0' */

#define INQ_BUF_SZ			128
#define EVPD				0x01
#define CMDDT				0x02
#define NAA_ID_LEN			0x10

#define MSENSE_BUF_SZ			256
#define DBD				0x08	/* disable block descriptor */
#define WP				0x80	/* write protect */
#define DPOFUA				0x10	/* DPOFUA bit */
#define WCE				0x04	/* write cache enable */

#define PF				0x10	/* page format */
#define SP				0x01	/* save pages */
#define PS				0x80	/* parameter saveable */

#define	BYTE				8
#define	DEF_SECTORS			56
#define	DEF_HEADS			255

struct vdisk_tgt_dev {
	uint64_t sess_h;
};

struct vdisk_dev {
	int scst_usr_fd;
	uint32_t block_size;
	uint64_t nblocks;
	int block_shift;
	int64_t file_size;	/* in bytes */
	void *(*alloc_fn)(size_t size);

	pthread_mutex_t dev_mutex;

	/* Below flags and are protected by dev_mutex */
	unsigned int rd_only_flag:1;
	unsigned int wt_flag:1;
	unsigned int nv_cache:1;
	unsigned int o_direct_flag:1;
	unsigned int media_changed:1;
	unsigned int prevent_allow_medium_removal:1;
	unsigned int nullio:1;
	unsigned int cdrom_empty:1;
	unsigned int non_blocking:1;
#if defined(DEBUG_TM_IGNORE) || defined(DEBUG_TM_IGNORE_ALL)
	unsigned int debug_tm_ignore:1;
#if defined(DEBUG_TM_IGNORE_ALL)
	volatile int debug_tm_ignore_all;
#endif
#endif

	struct vdisk_tgt_dev tgt_devs[64];

	char *name;		/* Name of virtual device,
				   must be <= SCSI Model + 1 */
	char *file_name;	/* File name */
	char usn[MAX_USN_LEN];
	int type;
	uint8_t naa_id[NAA_ID_LEN];
};

struct vdisk_cmd
{
	int fd;
	struct scst_user_get_cmd *cmd;
	struct vdisk_dev *dev;
	unsigned int may_need_to_free_pbuf:1;
	struct scst_user_reply_cmd *reply;
	uint8_t sense[SCST_SENSE_BUFFERSIZE];
};

/*
 * min()/max() macros that also do
 * strict type-checking.. See the
 * "unnecessary" pointer comparison.
 */
#define min(x, y) ({ 		\
	typeof(x) _x = (x);	\
	typeof(y) _y = (y);	\
	(void) (&_x == &_y);	\
	_x < _y ? _x : _y; })

#define max(x, y) ({ 		\
	typeof(x) _x = (x);	\
	typeof(y) _y = (y);	\
	(void) (&_x == &_y);	\
	_x > _y ? _x : _y; })

#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

extern int vdisk_ID;
extern bool use_multi;

uint32_t crc32buf(const char *buf, size_t len);

uint64_t gen_dev_id_num(const struct vdisk_dev *dev);
void *main_loop(void *arg);
