/*
 * This file is mostly copied from libzbc.
 *
 * Copyright (C) 2009-2014, HGST, Inc.  All rights reserved.
 *
 * This software is distributed under the terms of the BSD 2-clause license,
 * "as is," without technical support, and WITHOUT ANY WARRANTY, without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE. You should have received a copy of the BSD 2-clause license along
 * with libzbc. If not, see  <http://opensource.org/licenses/BSD-2-Clause>.
 *
 * Authors: Damien Le Moal (damien.lemoal@hgst.com)
 *          Christophe Louargant (christophe.louargant@hgst.com)
 *
 * Integrated into f2fs-tools by:
 *          Jaegeuk Kim (jaegeuk@kernel.org)
 */

#include <f2fs_fs.h>

#include "zbc.h"

static struct zbc_sg_cmd_s
{

    char                *cdb_cmd_name;
    int                 cdb_opcode;
    int                 cdb_sa;
    size_t              cdb_length;
    int			dir;

} zbc_sg_cmd_list[ZBC_SG_CMD_NUM] = {

    /* ZBC_SG_TEST_UNIT_READY */
    {
        "TEST UNIT READY",
        ZBC_SG_TEST_UNIT_READY_CDB_OPCODE,
        0,
        ZBC_SG_TEST_UNIT_READY_CDB_LENGTH,
	SG_DXFER_NONE
    },

    /* ZBC_SG_INQUIRY */
    {
        "INQUIRY",
        ZBC_SG_INQUIRY_CDB_OPCODE,
        0,
        ZBC_SG_INQUIRY_CDB_LENGTH,
	SG_DXFER_FROM_DEV
    },

    /* ZBC_SG_READ_CAPACITY */
    {
        "READ CAPACITY 16",
        ZBC_SG_READ_CAPACITY_CDB_OPCODE,
        ZBC_SG_READ_CAPACITY_CDB_SA,
        ZBC_SG_READ_CAPACITY_CDB_LENGTH,
	SG_DXFER_FROM_DEV
    },

    /* ZBC_SG_READ */
    {
        "READ 16",
        ZBC_SG_READ_CDB_OPCODE,
        0,
        ZBC_SG_READ_CDB_LENGTH,
	SG_DXFER_FROM_DEV
    },

    /* ZBC_SG_WRITE */
    {
        "WRITE 16",
        ZBC_SG_WRITE_CDB_OPCODE,
        0,
        ZBC_SG_WRITE_CDB_LENGTH,
	SG_DXFER_TO_DEV
    },

    /* ZBC_SG_SYNC_CACHE */
    {
        "SYNCHRONIZE CACHE 16",
        ZBC_SG_SYNC_CACHE_CDB_OPCODE,
        0,
        ZBC_SG_SYNC_CACHE_CDB_LENGTH,
	SG_DXFER_NONE
    },

    /* ZBC_SG_REPORT_ZONES */
    {
        "REPORT ZONES",
        ZBC_SG_REPORT_ZONES_CDB_OPCODE,
        ZBC_SG_REPORT_ZONES_CDB_SA,
        ZBC_SG_REPORT_ZONES_CDB_LENGTH,
	SG_DXFER_FROM_DEV
    },

    /* ZBC_SG_OPEN_ZONE */
    {
        "OPEN ZONE",
        ZBC_SG_OPEN_ZONE_CDB_OPCODE,
        ZBC_SG_OPEN_ZONE_CDB_SA,
        ZBC_SG_OPEN_ZONE_CDB_LENGTH,
	SG_DXFER_NONE
    },

    /* ZBC_SG_CLOSE_ZONE */
    {
        "CLOSE ZONE",
        ZBC_SG_CLOSE_ZONE_CDB_OPCODE,
        ZBC_SG_CLOSE_ZONE_CDB_SA,
        ZBC_SG_CLOSE_ZONE_CDB_LENGTH,
	SG_DXFER_NONE
    },

    /* ZBC_SG_FINISH_ZONE */
    {
        "FINISH ZONE",
        ZBC_SG_FINISH_ZONE_CDB_OPCODE,
        ZBC_SG_FINISH_ZONE_CDB_SA,
        ZBC_SG_FINISH_ZONE_CDB_LENGTH,
	SG_DXFER_NONE
    },

    /* ZBC_SG_RESET_WRITE_POINTER */
    {
        "RESET WRITE POINTER",
        ZBC_SG_RESET_WRITE_POINTER_CDB_OPCODE,
        ZBC_SG_RESET_WRITE_POINTER_CDB_SA,
        ZBC_SG_RESET_WRITE_POINTER_CDB_LENGTH,
	SG_DXFER_NONE
    },

    /* ZBC_SG_SET_ZONES */
    {
        "SET ZONES",
        ZBC_SG_SET_ZONES_CDB_OPCODE,
        ZBC_SG_SET_ZONES_CDB_SA,
        ZBC_SG_SET_ZONES_CDB_LENGTH,
	SG_DXFER_NONE
    },

    /* ZBC_SG_SET_WRITE_POINTER */
    {
        "SET WRITE POINTER",
        ZBC_SG_SET_WRITE_POINTER_CDB_OPCODE,
        ZBC_SG_SET_WRITE_POINTER_CDB_SA,
        ZBC_SG_SET_WRITE_POINTER_CDB_LENGTH,
	SG_DXFER_NONE
    },

    /* ZBC_SG_ATA12 */
    {
	"ATA 12",
	ZBC_SG_ATA12_CDB_OPCODE,
	0,
        ZBC_SG_ATA12_CDB_LENGTH,
	0
    },

    /* ZBC_SG_ATA16 */
    {
	"ATA 16",
	ZBC_SG_ATA16_CDB_OPCODE,
	0,
        ZBC_SG_ATA16_CDB_LENGTH,
	0
    }
};

static void zbc_sg_cmd_set_bytes(uint8_t *cmd, void *buf, int bytes)
{
	uint8_t *v = (uint8_t *) buf;
	int i;

	for (i = 0; i < bytes; i++) {
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
		/* The least significant byte is stored last */
		cmd[bytes - i - 1] = v[i];
#else
		/* The most significant byte is stored first */
		cmd[i] = v[i];
#endif
	}
	return;
}

static void zbc_sg_cmd_get_bytes(uint8_t *val, union converter *conv, int bytes)
{
	uint8_t *v = (uint8_t *) val;
	int i;

	memset(conv, 0, sizeof(union converter));

	for(i = 0; i < bytes; i++) {
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
		conv->val_buf[bytes - i - 1] = v[i];
#else
		conv->val_buf[i] = v[i];
#endif
	}
	return;
}

static inline void zbc_sg_cmd_set_int64(uint8_t *buf, uint64_t val)
{
	zbc_sg_cmd_set_bytes(buf, &val, 8);
	return;
}

static inline void zbc_sg_cmd_set_int32(uint8_t *buf, uint32_t val)
{
	zbc_sg_cmd_set_bytes(buf, &val, 4);
	return;
}

static inline uint32_t zbc_sg_cmd_get_int32(uint8_t *buf)
{
	union converter conv;

	zbc_sg_cmd_get_bytes(buf, &conv, 4);
	return conv.val32;
}

static inline uint64_t zbc_sg_cmd_get_int64(uint8_t *buf)
{
	union converter conv;

	zbc_sg_cmd_get_bytes(buf, &conv, 8);
	return( conv.val64 );

}

static void zbc_sg_cmd_destroy(zbc_sg_cmd_t *cmd)
{
	/* Free the command */
	if (!cmd)
		return;

	if (cmd->out_buf && cmd->out_buf_needfree) {
		free(cmd->out_buf);
		cmd->out_buf = NULL;
		cmd->out_bufsz = 0;
	}
	memset(cmd, 0, sizeof(*cmd));
	return;
}

static int zbc_sg_cmd_init(zbc_sg_cmd_t *cmd, int cmd_code,
				uint8_t *out_buf, size_t out_bufsz)
{
	int ret = 0;

	if ((!cmd) || (cmd_code < 0) || (cmd_code >= ZBC_SG_CMD_NUM) ) {
		ERR_MSG("Invalid command specified\n");
		return -EINVAL;
	}

	/* Set command */
	memset(cmd, 0, sizeof(zbc_sg_cmd_t));
	cmd->code = cmd_code;
	cmd->cdb_sz = zbc_sg_cmd_list[cmd_code].cdb_length;
	cmd->cdb_opcode = zbc_sg_cmd_list[cmd_code].cdb_opcode;
	cmd->cdb_sa = zbc_sg_cmd_list[cmd_code].cdb_sa;

	/* Set output buffer */
	if (out_buf) {
		/* Set specified buffer */
		if (!out_bufsz) {
			ERR_MSG("Invalid 0 output buffer size\n");
			ret = -EINVAL;
			goto out;
		}
		cmd->out_buf = out_buf;
		cmd->out_bufsz = out_bufsz;
	} else if (out_bufsz) {
		/* Allocate a buffer */
		ret = posix_memalign((void **)&cmd->out_buf,
				sysconf(_SC_PAGESIZE), out_bufsz);
		if ( ret != 0 ) {
			ERR_MSG("No memory for output buffer (%zu B)\n",
					out_bufsz);
			ret = -ENOMEM;
			goto out;
		}
		memset(cmd->out_buf, 0, out_bufsz);
		cmd->out_bufsz = out_bufsz;
		cmd->out_buf_needfree = 1;
	}

	/* OK: setup SGIO header */
	memset(&cmd->io_hdr, 0, sizeof(sg_io_hdr_t));

	cmd->io_hdr.interface_id    = 'S';
	cmd->io_hdr.timeout         = 20000;
	cmd->io_hdr.flags           = 0; //SG_FLAG_DIRECT_IO;

	cmd->io_hdr.cmd_len         = cmd->cdb_sz;
	cmd->io_hdr.cmdp            = &cmd->cdb[0];

	cmd->io_hdr.dxfer_direction = zbc_sg_cmd_list[cmd_code].dir;
	cmd->io_hdr.dxfer_len       = cmd->out_bufsz;
	cmd->io_hdr.dxferp          = cmd->out_buf;

	cmd->io_hdr.mx_sb_len       = ZBC_SG_SENSE_MAX_LENGTH;
	cmd->io_hdr.sbp             = cmd->sense_buf;
out:
	if (ret != 0)
		zbc_sg_cmd_destroy(cmd);

	return ret;
}

static char *zbc_sg_cmd_name(zbc_sg_cmd_t *cmd)
{
	char *name;

	if ((cmd->code >= 0)
			&& (cmd->code < ZBC_SG_CMD_NUM)) {
		name = zbc_sg_cmd_list[cmd->code].cdb_cmd_name;
	} else {
		name = "(UNKNOWN COMMAND)";
	}

	return name;
}

static void zbc_sg_set_sense(uint8_t *sense_buf)
{
	if (sense_buf == NULL) {
		c.zbd_errno.sk       = 0x00;
		c.zbd_errno.asc_ascq = 0x0000;
	} else {
		if ((sense_buf[0] & 0x7F) == 0x72
				|| (sense_buf[0] & 0x7F) == 0x73) {
			/* store sense key, ASC/ASCQ */
			c.zbd_errno.sk       = sense_buf[1] & 0x0F;
			c.zbd_errno.asc_ascq = ((int)sense_buf[2] << 8) |
							(int)sense_buf[3];
		} else if ((sense_buf[0] & 0x7F) == 0x70
				|| (sense_buf[0] & 0x7F) == 0x71) {
			/* store sense key, ASC/ASCQ */
			c.zbd_errno.sk       = sense_buf[2] & 0x0F;
			c.zbd_errno.asc_ascq = ((int)sense_buf[12] << 8) |
							(int)sense_buf[13];
		}
	}
	return;
}

static int zbc_sg_cmd_exec(zbc_sg_cmd_t *cmd)
{
	int ret;

	/* Send the SG_IO command */
	ret = ioctl(c.fd, SG_IO, &cmd->io_hdr);
	if (ret) {
		ERR_MSG("SG_IO ioctl failed (%s)\n", strerror(errno));
		goto out;
	}

	/* Reset errno */
	zbc_sg_set_sense(NULL);

	DBG(1, "Command %s done: status 0x%02x (0x%02x), host status 0x%04x, driver status 0x%04x (flags 0x%04x)\n",
			zbc_sg_cmd_name(cmd),
			(unsigned int)cmd->io_hdr.status,
			(unsigned int)cmd->io_hdr.masked_status,
			(unsigned int)cmd->io_hdr.host_status,
			(unsigned int)zbc_sg_cmd_driver_status(cmd),
			(unsigned int)zbc_sg_cmd_driver_flags(cmd));

	/* Check status */
	if (((cmd->code == ZBC_SG_ATA12) || (cmd->code == ZBC_SG_ATA16))
			&& (cmd->cdb[2] & (1 << 5)) ) {

		/* ATA command status */
		if (cmd->io_hdr.status != ZBC_SG_CHECK_CONDITION) {
			zbc_sg_set_sense(cmd->sense_buf);
			ret = -EIO;
			goto out;
		}

		if ((zbc_sg_cmd_driver_status(cmd) == ZBC_SG_DRIVER_SENSE)
				&& (cmd->io_hdr.sb_len_wr > 21)
				&& (cmd->sense_buf[21] != 0x50) ) {
			zbc_sg_set_sense(cmd->sense_buf);
			ret = -EIO;
			goto out;
		}
		cmd->io_hdr.status = 0;
	}

	if (cmd->io_hdr.status
			|| (cmd->io_hdr.host_status != ZBC_SG_DID_OK)
			|| (zbc_sg_cmd_driver_status(cmd) &&
			(zbc_sg_cmd_driver_status(cmd) != ZBC_SG_DRIVER_SENSE)) ) {

		ERR_MSG("Command %s failed with status 0x%02x (0x%02x), host status 0x%04x, driver status 0x%04x (flags 0x%04x)\n",
				zbc_sg_cmd_name(cmd),
				(unsigned int)cmd->io_hdr.status,
				(unsigned int)cmd->io_hdr.masked_status,
				(unsigned int)cmd->io_hdr.host_status,
				(unsigned int)zbc_sg_cmd_driver_status(cmd),
				(unsigned int)zbc_sg_cmd_driver_flags(cmd));
		zbc_sg_set_sense(cmd->sense_buf);
		ret = -EIO;
		goto out;
	}

	if (cmd->io_hdr.resid) {
		ERR_MSG("Transfer missing %d B of data\n",
				cmd->io_hdr.resid);
		cmd->out_bufsz -= cmd->io_hdr.resid;
	}
out:
	return ret;
}

#define ZBC_SCSI_REPORT_ZONES_BUFSZ     524288

int zbc_scsi_report_zones(void)
{
	zbc_sg_cmd_t cmd;
	uint8_t *buf;
	zbc_zone_t *z, *zones = NULL;
	int i, buf_nz, ret;
	size_t bufsz;
	uint32_t idx = 0, nr_zones = 0;
	uint64_t next_lba = 0;
	int phase = 0;
next:
	bufsz = ZBC_ZONE_DESCRIPTOR_OFFSET;
	if (phase) {
		if (c.nr_zones - idx == 0)
			return 0;

		bufsz += (size_t)(c.nr_zones - idx) *
					ZBC_ZONE_DESCRIPTOR_LENGTH;
		if (bufsz > ZBC_SCSI_REPORT_ZONES_BUFSZ)
			bufsz = ZBC_SCSI_REPORT_ZONES_BUFSZ;
	}

	/* For in kernel ATA translation: align to 512 B */
	bufsz = (bufsz + 511) & ~511;

	/* Allocate and intialize report zones command */
	ret = zbc_sg_cmd_init(&cmd, ZBC_SG_REPORT_ZONES, NULL, bufsz);
	if (ret) {
		ERR_MSG("zbc_sg_cmd_init failed\n");
		return ret;
	}

	/* Fill command CDB:
	 * +=============================================================================+
	 * |  Bit|   7    |   6    |   5    |   4    |   3    |   2    |   1    |   0    |
	 * |Byte |        |        |        |        |        |        |        |        |
	 * |=====+==========================+============================================|
	 * | 0   |                           Operation Code (95h)                        |
	 * |-----+-----------------------------------------------------------------------|
	 * | 1   |      Reserved            |       Service Action (00h)                 |
	 * |-----+-----------------------------------------------------------------------|
	 * | 2   | (MSB)                                                                 |
	 * |- - -+---                        Zone Start LBA                           ---|
	 * | 9   |                                                                 (LSB) |
	 * |-----+-----------------------------------------------------------------------|
	 * | 10  | (MSB)                                                                 |
	 * |- - -+---                        Allocation Length                        ---|
	 * | 13  |                                                                 (LSB) |
	 * |-----+-----------------------------------------------------------------------|
	 * | 14  |Partial |Reserved|                 Reporting Options                   |
	 * |-----+-----------------------------------------------------------------------|
	 * | 15  |                           Control                                     |
	 * +=============================================================================+
	 */
	cmd.cdb[0] = ZBC_SG_REPORT_ZONES_CDB_OPCODE;
	cmd.cdb[1] = ZBC_SG_REPORT_ZONES_CDB_SA;
	zbc_sg_cmd_set_int64(&cmd.cdb[2], next_lba);
	zbc_sg_cmd_set_int32(&cmd.cdb[10], (unsigned int) bufsz);
	cmd.cdb[14] = 0;

	/* Send the SG_IO command */
	ret = zbc_sg_cmd_exec(&cmd);
	if (ret != 0)
		goto out;

	if (cmd.out_bufsz < ZBC_ZONE_DESCRIPTOR_OFFSET) {
		ERR_MSG("Not enough data received (need at least %d B, got %zu B)\n",
				ZBC_ZONE_DESCRIPTOR_OFFSET,
				cmd.out_bufsz);
		ret = -EIO;
		goto out;
	}

	/* Process output:
	 * +=============================================================================+
	 * |  Bit|   7    |   6    |   5    |   4    |   3    |   2    |   1    |   0    |
	 * |Byte |        |        |        |        |        |        |        |        |
	 * |=====+=======================================================================|
	 * |  0  | (MSB)                                                                 |
	 * |- - -+---               Zone List Length (n - 64)                         ---|
	 * |  3  |                                                                 (LSB) |
	 * |-----+-----------------------------------------------------------------------|
	 * |  4  |              Reserved             |               Same                |
	 * |-----+-----------------------------------------------------------------------|
	 * |  5  |                                                                       |
	 * |- - -+---                        Reserved                                 ---|
	 * |  7  |                                                                       |
	 * |-----+-----------------------------------------------------------------------|
	 * |  8  | (MSB)                                                                 |
	 * |- - -+---                      Maximum LBA                                ---|
	 * | 15  |                                                                 (LSB) |
	 * |-----+-----------------------------------------------------------------------|
	 * | 16  | (MSB)                                                                 |
	 * |- - -+---                        Reserved                                 ---|
	 * | 63  |                                                                 (LSB) |
	 * |=====+=======================================================================|
	 * |     |                       Vendor-Specific Parameters                      |
	 * |=====+=======================================================================|
	 * | 64  | (MSB)                                                                 |
	 * |- - -+---                  Zone Descriptor [first]                        ---|
	 * | 127 |                                                                 (LSB) |
	 * |-----+-----------------------------------------------------------------------|
	 * |                                    .                                        |
	 * |                                    .                                        |
	 * |                                    .                                        |
	 * |-----+-----------------------------------------------------------------------|
	 * |n-63 |                                                                       |
	 * |- - -+---                   Zone Descriptor [last]                        ---|
	 * | n   |                                                                       |
	 * +=============================================================================+
	 */

	/* Get number of zones in result */
	buf = (uint8_t *)cmd.out_buf;
	nr_zones = zbc_sg_cmd_get_int32(buf) / ZBC_ZONE_DESCRIPTOR_LENGTH;

	/* read # of zones and then get all the zone info */
	if (phase == 0) {
		c.nr_zones = nr_zones;
		c.nr_conventional = 0;
		zbc_sg_cmd_destroy(&cmd);
		phase++;
		goto next;
	}

	if (nr_zones > c.nr_zones - idx)
		nr_zones = c.nr_zones - idx;

	buf_nz = (cmd.out_bufsz - ZBC_ZONE_DESCRIPTOR_OFFSET) /
						ZBC_ZONE_DESCRIPTOR_LENGTH;
	if (nr_zones > buf_nz)
		nr_zones = buf_nz;

	if (!nr_zones) {
		ERR_MSG("No more zones\n");
		goto out;
	}

	/* Allocate zone array */
	zones = (zbc_zone_t *)malloc(sizeof(zbc_zone_t) * nr_zones);
	if (!zones) {
		ERR_MSG("No memory\n");
		goto out;
	}
	memset(zones, 0, sizeof(zbc_zone_t) * nr_zones);

	/* Get zone descriptors:
	 * +=============================================================================+
	 * |  Bit|   7    |   6    |   5    |   4    |   3    |   2    |   1    |   0    |
	 * |Byte |        |        |        |        |        |        |        |        |
	 * |=====+=======================================================================|
	 * |  0  |             Reserved              |            Zone type              |
	 * |-----+-----------------------------------------------------------------------|
	 * |  1  |          Zone condition           |    Reserved     |non-seq |  Reset |
	 * |-----+-----------------------------------------------------------------------|
	 * |  2  |                                                                       |
	 * |- - -+---                             Reserved                            ---|
	 * |  7  |                                                                       |
	 * |-----+-----------------------------------------------------------------------|
	 * |  8  | (MSB)                                                                 |
	 * |- - -+---                           Zone Length                           ---|
	 * | 15  |                                                                 (LSB) |
	 * |-----+-----------------------------------------------------------------------|
	 * | 16  | (MSB)                                                                 |
	 * |- - -+---                          Zone Start LBA                         ---|
	 * | 23  |                                                                 (LSB) |
	 * |-----+-----------------------------------------------------------------------|
	 * | 24  | (MSB)                                                                 |
	 * |- - -+---                         Write Pointer LBA                       ---|
	 * | 31  |                                                                 (LSB) |
	 * |-----+-----------------------------------------------------------------------|
	 * | 32  |                                                                       |
	 * |- - -+---                             Reserved                            ---|
	 * | 63  |                                                                       |
	 * +=============================================================================+
	 */
	buf += ZBC_ZONE_DESCRIPTOR_OFFSET;

	for(i = 0; i < nr_zones; i++) {
		zones[i].zbz_type = buf[0] & 0x0f;
		zones[i].zbz_condition = (buf[1] >> 4) & 0x0f;
		zones[i].zbz_length = zbc_sg_cmd_get_int64(&buf[8]);
		zones[i].zbz_start = zbc_sg_cmd_get_int64(&buf[16]);
		zones[i].zbz_write_pointer = zbc_sg_cmd_get_int64(&buf[24]);
		zones[i].zbz_flags = buf[1] & 0x03;

		buf += ZBC_ZONE_DESCRIPTOR_LENGTH;
	}

	for (i = 0; i < nr_zones; i++) {
		z = &zones[i];
		if ( zbc_zone_conventional(z) ) {
			c.nr_conventional++;
			DBG(1, "Zone %05d: type 0x%x (%s), cond 0x%x (%s), LBA %llu, %llu sectors, wp N/A\n",
				i + idx,
				zbc_zone_type(z),
				zbc_zone_type_str(zbc_zone_type(z)),
				zbc_zone_condition(z),
				zbc_zone_condition_str(zbc_zone_condition(z)),
				zbc_zone_start_lba(z),
				zbc_zone_length(z));
		} else {
			DBG(1, "Zone %05d: type 0x%x (%s), cond 0x%x (%s), need_reset %d, non_seq %d, LBA %llu, %llu sectors, wp %llu\n",
				i + idx,
				zbc_zone_type(z),
				zbc_zone_type_str(zbc_zone_type(z)),
				zbc_zone_condition(z),
				zbc_zone_condition_str(zbc_zone_condition(z)),
				zbc_zone_need_reset(z),
				zbc_zone_non_seq(z),
				zbc_zone_start_lba(z),
				zbc_zone_length(z),
				zbc_zone_wp_lba(z));
		}
	}

	idx += nr_zones;
	next_lba = zones[nr_zones - 1].zbz_start + zones[nr_zones - 1].zbz_length;
	c.zone_sectors = zones[nr_zones - 1].zbz_length;
	phase++;
	zbc_sg_cmd_destroy(&cmd);
	free(zones);
	goto next;
out:
	zbc_sg_cmd_destroy(&cmd);
	return ret;
}
