/*
 * SCSI Zoned Block commands
 *
 * Copyright (C) 2014-2015 SUSE Linux GmbH
 * Written by: Hannes Reinecke <hare@suse.de>
 * Modified by: Damien Le Moal <damien.lemoal@hgst.com>
 * Modified by: Shaun Tancheff <shaun.tancheff@seagate.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version
 * 2 as published by the Free Software Foundation.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING.  If not, write to
 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
 * USA.
 *
 */

#include <linux/blkdev.h>

#include <asm/unaligned.h>

#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_dbg.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_driver.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_eh.h>

#include "sd.h"
#include "scsi_priv.h"

enum zbc_zone_type {
	ZBC_ZONE_TYPE_CONV = 0x1,
	ZBC_ZONE_TYPE_SEQWRITE_REQ,
	ZBC_ZONE_TYPE_SEQWRITE_PREF,
	ZBC_ZONE_TYPE_RESERVED,
};

enum zbc_zone_cond {
	ZBC_ZONE_COND_NO_WP,
	ZBC_ZONE_COND_EMPTY,
	ZBC_ZONE_COND_IMP_OPEN,
	ZBC_ZONE_COND_EXP_OPEN,
	ZBC_ZONE_COND_CLOSED,
	ZBC_ZONE_COND_READONLY = 0xd,
	ZBC_ZONE_COND_FULL,
	ZBC_ZONE_COND_OFFLINE,
};

/**
 * Convert a zone descriptor to a zone struct.
 */
static void sd_zbc_parse_report(struct scsi_disk *sdkp,
				u8 *buf,
				struct blk_zone *zone)
{
	struct scsi_device *sdp = sdkp->device;

	memset(zone, 0, sizeof(struct blk_zone));

	zone->type = buf[0] & 0x0f;
	zone->cond = (buf[1] >> 4) & 0xf;
	if (buf[1] & 0x01)
		zone->reset = 1;
	if (buf[1] & 0x02)
		zone->non_seq = 1;

	zone->len = logical_to_sectors(sdp, get_unaligned_be64(&buf[8]));
	zone->start = logical_to_sectors(sdp, get_unaligned_be64(&buf[16]));
	zone->wp = logical_to_sectors(sdp, get_unaligned_be64(&buf[24]));
	if (zone->type != ZBC_ZONE_TYPE_CONV &&
	    zone->cond == ZBC_ZONE_COND_FULL)
		zone->wp = zone->start + zone->len;
}

/**
 * Issue a REPORT ZONES scsi command.
 */
static int sd_zbc_report_zones(struct scsi_disk *sdkp, unsigned char *buf,
			       unsigned int buflen, sector_t lba)
{
	struct scsi_device *sdp = sdkp->device;
	const int timeout = sdp->request_queue->rq_timeout;
	struct scsi_sense_hdr sshdr;
	unsigned char cmd[16];
	unsigned int rep_len;
	int result;

	memset(cmd, 0, 16);
	cmd[0] = ZBC_IN;
	cmd[1] = ZI_REPORT_ZONES;
	put_unaligned_be64(lba, &cmd[2]);
	put_unaligned_be32(buflen, &cmd[10]);
	memset(buf, 0, buflen);

	result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE,
				  buf, buflen, &sshdr,
				  timeout, SD_MAX_RETRIES, NULL);
	if (result) {
		sd_printk(KERN_ERR, sdkp,
			  "REPORT ZONES lba %llu failed with %d/%d\n",
			  (unsigned long long)lba,
			  host_byte(result), driver_byte(result));
		return -EIO;
	}

	rep_len = get_unaligned_be32(&buf[0]);
	if (rep_len < 64) {
		sd_printk(KERN_ERR, sdkp,
			  "REPORT ZONES report invalid length %u\n",
			  rep_len);
		return -EIO;
	}

	return 0;
}

int sd_zbc_setup_report_cmnd(struct scsi_cmnd *cmd)
{
	struct request *rq = cmd->request;
	struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
	sector_t lba, sector = blk_rq_pos(rq);
	unsigned int nr_bytes = blk_rq_bytes(rq);
	int ret;

	WARN_ON(nr_bytes == 0);

	if (!sd_is_zoned(sdkp))
		/* Not a zoned device */
		return BLKPREP_KILL;

	ret = scsi_init_io(cmd);
	if (ret != BLKPREP_OK)
		return ret;

	cmd->cmd_len = 16;
	memset(cmd->cmnd, 0, cmd->cmd_len);
	cmd->cmnd[0] = ZBC_IN;
	cmd->cmnd[1] = ZI_REPORT_ZONES;
	lba = sectors_to_logical(sdkp->device, sector);
	put_unaligned_be64(lba, &cmd->cmnd[2]);
	put_unaligned_be32(nr_bytes, &cmd->cmnd[10]);
	/* Do partial report for speeding things up */
	cmd->cmnd[14] = ZBC_REPORT_ZONE_PARTIAL;

	cmd->sc_data_direction = DMA_FROM_DEVICE;
	cmd->sdb.length = nr_bytes;
	cmd->transfersize = sdkp->device->sector_size;
	cmd->allowed = 0;

	/*
	 * Report may return less bytes than requested. Make sure
	 * to report completion on the entire initial request.
	 */
	rq->__data_len = nr_bytes;

	return BLKPREP_OK;
}

static void sd_zbc_report_zones_complete(struct scsi_cmnd *scmd,
					 unsigned int good_bytes)
{
	struct request *rq = scmd->request;
	struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
	struct sg_mapping_iter miter;
	struct blk_zone_report_hdr hdr;
	struct blk_zone zone;
	unsigned int offset, bytes = 0;
	unsigned long flags;
	u8 *buf;

	if (good_bytes < 64)
		return;

	memset(&hdr, 0, sizeof(struct blk_zone_report_hdr));

	sg_miter_start(&miter, scsi_sglist(scmd), scsi_sg_count(scmd),
		       SG_MITER_TO_SG | SG_MITER_ATOMIC);

	local_irq_save(flags);
	while (sg_miter_next(&miter) && bytes < good_bytes) {

		buf = miter.addr;
		offset = 0;

		if (bytes == 0) {
			/* Set the report header */
			hdr.nr_zones = min_t(unsigned int,
					 (good_bytes - 64) / 64,
					 get_unaligned_be32(&buf[0]) / 64);
			memcpy(buf, &hdr, sizeof(struct blk_zone_report_hdr));
			offset += 64;
			bytes += 64;
		}

		/* Parse zone descriptors */
		while (offset < miter.length && hdr.nr_zones) {
			WARN_ON(offset > miter.length);
			buf = miter.addr + offset;
			sd_zbc_parse_report(sdkp, buf, &zone);
			memcpy(buf, &zone, sizeof(struct blk_zone));
			offset += 64;
			bytes += 64;
			hdr.nr_zones--;
		}

		if (!hdr.nr_zones)
			break;

	}
	sg_miter_stop(&miter);
	local_irq_restore(flags);
}

static inline sector_t sd_zbc_zone_sectors(struct scsi_disk *sdkp)
{
	return logical_to_sectors(sdkp->device, sdkp->zone_blocks);
}

static inline unsigned int sd_zbc_zone_no(struct scsi_disk *sdkp,
					  sector_t sector)
{
	return sectors_to_logical(sdkp->device, sector) >> sdkp->zone_shift;
}

int sd_zbc_setup_reset_cmnd(struct scsi_cmnd *cmd)
{
	struct request *rq = cmd->request;
	struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
	sector_t sector = blk_rq_pos(rq);
	sector_t block = sectors_to_logical(sdkp->device, sector);

	if (!sd_is_zoned(sdkp))
		/* Not a zoned device */
		return BLKPREP_KILL;

	if (sdkp->device->changed)
		return BLKPREP_KILL;

	if (sector & (sd_zbc_zone_sectors(sdkp) - 1))
		/* Unaligned request */
		return BLKPREP_KILL;

	cmd->cmd_len = 16;
	memset(cmd->cmnd, 0, cmd->cmd_len);
	cmd->cmnd[0] = ZBC_OUT;
	cmd->cmnd[1] = ZO_RESET_WRITE_POINTER;
	put_unaligned_be64(block, &cmd->cmnd[2]);

	rq->timeout = SD_TIMEOUT;
	cmd->sc_data_direction = DMA_NONE;
	cmd->transfersize = 0;
	cmd->allowed = 0;

	return BLKPREP_OK;
}

int sd_zbc_write_lock_zone(struct scsi_cmnd *cmd)
{
	struct request *rq = cmd->request;
	struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
	sector_t sector = blk_rq_pos(rq);
	sector_t zone_sectors = sd_zbc_zone_sectors(sdkp);
	unsigned int zno = sd_zbc_zone_no(sdkp, sector);

	/*
	 * Note: Checks of the alignment of the write command on
	 * logical blocks is done in sd.c
	 */

	/* Do not allow zone boundaries crossing on host-managed drives */
	if (blk_queue_zoned_model(sdkp->disk->queue) == BLK_ZONED_HM &&
	    (sector & (zone_sectors - 1)) + blk_rq_sectors(rq) > zone_sectors)
		return BLKPREP_KILL;

	/*
	 * Do not issue more than one write at a time per
	 * zone. This solves write ordering problems due to
	 * the unlocking of the request queue in the dispatch
	 * path in the non scsi-mq case. For scsi-mq, this
	 * also avoids potential write reordering when multiple
	 * threads running on different CPUs write to the same
	 * zone (with a synchronized sequential pattern).
	 */
	if (sdkp->zones_wlock &&
	    test_and_set_bit(zno, sdkp->zones_wlock))
		return BLKPREP_DEFER;

	return BLKPREP_OK;
}

void sd_zbc_write_unlock_zone(struct scsi_cmnd *cmd)
{
	struct request *rq = cmd->request;
	struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);

	if (sdkp->zones_wlock) {
		unsigned int zno = sd_zbc_zone_no(sdkp, blk_rq_pos(rq));
		WARN_ON_ONCE(!test_bit(zno, sdkp->zones_wlock));
		clear_bit_unlock(zno, sdkp->zones_wlock);
		smp_mb__after_atomic();
	}
}

void sd_zbc_complete(struct scsi_cmnd *cmd,
		     unsigned int good_bytes,
		     struct scsi_sense_hdr *sshdr)
{
	int result = cmd->result;
	struct request *rq = cmd->request;

	switch (req_op(rq)) {
	case REQ_OP_ZONE_RESET:

		if (result &&
		    sshdr->sense_key == ILLEGAL_REQUEST &&
		    sshdr->asc == 0x24)
			/*
			 * INVALID FIELD IN CDB error: reset of a conventional
			 * zone was attempted. Nothing to worry about, so be
			 * quiet about the error.
			 */
			rq->rq_flags |= RQF_QUIET;
		break;

	case REQ_OP_WRITE:
	case REQ_OP_WRITE_ZEROES:
	case REQ_OP_WRITE_SAME:

		/* Unlock the zone */
		sd_zbc_write_unlock_zone(cmd);

		if (result &&
		    sshdr->sense_key == ILLEGAL_REQUEST &&
		    sshdr->asc == 0x21)
			/*
			 * INVALID ADDRESS FOR WRITE error: It is unlikely that
			 * retrying write requests failed with any kind of
			 * alignement error will result in success. So don't.
			 */
			cmd->allowed = 0;
		break;

	case REQ_OP_ZONE_REPORT:

		if (!result)
			sd_zbc_report_zones_complete(cmd, good_bytes);
		break;

	}
}

/**
 * Read zoned block device characteristics (VPD page B6).
 */
static int sd_zbc_read_zoned_characteristics(struct scsi_disk *sdkp,
					     unsigned char *buf)
{

	if (scsi_get_vpd_page(sdkp->device, 0xb6, buf, 64)) {
		sd_printk(KERN_NOTICE, sdkp,
			  "Unconstrained-read check failed\n");
		return -ENODEV;
	}

	if (sdkp->device->type != TYPE_ZBC) {
		/* Host-aware */
		sdkp->urswrz = 1;
		sdkp->zones_optimal_open = get_unaligned_be64(&buf[8]);
		sdkp->zones_optimal_nonseq = get_unaligned_be64(&buf[12]);
		sdkp->zones_max_open = 0;
	} else {
		/* Host-managed */
		sdkp->urswrz = buf[4] & 1;
		sdkp->zones_optimal_open = 0;
		sdkp->zones_optimal_nonseq = 0;
		sdkp->zones_max_open = get_unaligned_be64(&buf[16]);
	}

	return 0;
}

/**
 * Check reported capacity.
 */
static int sd_zbc_check_capacity(struct scsi_disk *sdkp,
				 unsigned char *buf)
{
	sector_t lba;
	int ret;

	if (sdkp->rc_basis != 0)
		return 0;

	/* Do a report zone to get the maximum LBA to check capacity */
	ret = sd_zbc_report_zones(sdkp, buf, SD_BUF_SIZE, 0);
	if (ret)
		return ret;

	/* The max_lba field is the capacity of this device */
	lba = get_unaligned_be64(&buf[8]);
	if (lba + 1 == sdkp->capacity)
		return 0;

	if (sdkp->first_scan)
		sd_printk(KERN_WARNING, sdkp,
			  "Changing capacity from %llu to max LBA+1 %llu\n",
			  (unsigned long long)sdkp->capacity,
			  (unsigned long long)lba + 1);
	sdkp->capacity = lba + 1;

	return 0;
}

#define SD_ZBC_BUF_SIZE 131072

static int sd_zbc_check_zone_size(struct scsi_disk *sdkp)
{
	u64 zone_blocks;
	sector_t block = 0;
	unsigned char *buf;
	unsigned char *rec;
	unsigned int buf_len;
	unsigned int list_length;
	int ret;
	u8 same;

	sdkp->zone_blocks = 0;

	/* Get a buffer */
	buf = kmalloc(SD_ZBC_BUF_SIZE, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	/* Do a report zone to get the same field */
	ret = sd_zbc_report_zones(sdkp, buf, SD_ZBC_BUF_SIZE, 0);
	if (ret) {
		zone_blocks = 0;
		goto out;
	}

	same = buf[4] & 0x0f;
	if (same > 0) {
		rec = &buf[64];
		zone_blocks = get_unaligned_be64(&rec[8]);
		goto out;
	}

	/*
	 * Check the size of all zones: all zones must be of
	 * equal size, except the last zone which can be smaller
	 * than other zones.
	 */
	do {

		/* Parse REPORT ZONES header */
		list_length = get_unaligned_be32(&buf[0]) + 64;
		rec = buf + 64;
		if (list_length < SD_ZBC_BUF_SIZE)
			buf_len = list_length;
		else
			buf_len = SD_ZBC_BUF_SIZE;

		/* Parse zone descriptors */
		while (rec < buf + buf_len) {
			zone_blocks = get_unaligned_be64(&rec[8]);
			if (sdkp->zone_blocks == 0) {
				sdkp->zone_blocks = zone_blocks;
			} else if (zone_blocks != sdkp->zone_blocks &&
				   (block + zone_blocks < sdkp->capacity
				    || zone_blocks > sdkp->zone_blocks)) {
				zone_blocks = 0;
				goto out;
			}
			block += zone_blocks;
			rec += 64;
		}

		if (block < sdkp->capacity) {
			ret = sd_zbc_report_zones(sdkp, buf,
						  SD_ZBC_BUF_SIZE, block);
			if (ret)
				return ret;
		}

	} while (block < sdkp->capacity);

	zone_blocks = sdkp->zone_blocks;

out:
	kfree(buf);

	if (!zone_blocks) {
		if (sdkp->first_scan)
			sd_printk(KERN_NOTICE, sdkp,
				  "Devices with non constant zone "
				  "size are not supported\n");
		return -ENODEV;
	}

	if (!is_power_of_2(zone_blocks)) {
		if (sdkp->first_scan)
			sd_printk(KERN_NOTICE, sdkp,
				  "Devices with non power of 2 zone "
				  "size are not supported\n");
		return -ENODEV;
	}

	if (logical_to_sectors(sdkp->device, zone_blocks) > UINT_MAX) {
		if (sdkp->first_scan)
			sd_printk(KERN_NOTICE, sdkp,
				  "Zone size too large\n");
		return -ENODEV;
	}

	sdkp->zone_blocks = zone_blocks;

	return 0;
}

static int sd_zbc_setup(struct scsi_disk *sdkp)
{

	/* chunk_sectors indicates the zone size */
	blk_queue_chunk_sectors(sdkp->disk->queue,
			logical_to_sectors(sdkp->device, sdkp->zone_blocks));
	sdkp->zone_shift = ilog2(sdkp->zone_blocks);
	sdkp->nr_zones = sdkp->capacity >> sdkp->zone_shift;
	if (sdkp->capacity & (sdkp->zone_blocks - 1))
		sdkp->nr_zones++;

	if (!sdkp->zones_wlock) {
		sdkp->zones_wlock = kcalloc(BITS_TO_LONGS(sdkp->nr_zones),
					    sizeof(unsigned long),
					    GFP_KERNEL);
		if (!sdkp->zones_wlock)
			return -ENOMEM;
	}

	return 0;
}

int sd_zbc_read_zones(struct scsi_disk *sdkp,
		      unsigned char *buf)
{
	int ret;

	if (!sd_is_zoned(sdkp))
		/*
		 * Device managed or normal SCSI disk,
		 * no special handling required
		 */
		return 0;


	/* Get zoned block device characteristics */
	ret = sd_zbc_read_zoned_characteristics(sdkp, buf);
	if (ret)
		goto err;

	/*
	 * Check for unconstrained reads: host-managed devices with
	 * constrained reads (drives failing read after write pointer)
	 * are not supported.
	 */
	if (!sdkp->urswrz) {
		if (sdkp->first_scan)
			sd_printk(KERN_NOTICE, sdkp,
			  "constrained reads devices are not supported\n");
		ret = -ENODEV;
		goto err;
	}

	/* Check capacity */
	ret = sd_zbc_check_capacity(sdkp, buf);
	if (ret)
		goto err;

	/*
	 * Check zone size: only devices with a constant zone size (except
	 * an eventual last runt zone) that is a power of 2 are supported.
	 */
	ret = sd_zbc_check_zone_size(sdkp);
	if (ret)
		goto err;

	/* The drive satisfies the kernel restrictions: set it up */
	ret = sd_zbc_setup(sdkp);
	if (ret)
		goto err;

	/* READ16/WRITE16 is mandatory for ZBC disks */
	sdkp->device->use_16_for_rw = 1;
	sdkp->device->use_10_for_rw = 0;

	return 0;

err:
	sdkp->capacity = 0;

	return ret;
}

void sd_zbc_remove(struct scsi_disk *sdkp)
{
	kfree(sdkp->zones_wlock);
	sdkp->zones_wlock = NULL;
}

void sd_zbc_print_zones(struct scsi_disk *sdkp)
{
	if (!sd_is_zoned(sdkp) || !sdkp->capacity)
		return;

	if (sdkp->capacity & (sdkp->zone_blocks - 1))
		sd_printk(KERN_NOTICE, sdkp,
			  "%u zones of %u logical blocks + 1 runt zone\n",
			  sdkp->nr_zones - 1,
			  sdkp->zone_blocks);
	else
		sd_printk(KERN_NOTICE, sdkp,
			  "%u zones of %u logical blocks\n",
			  sdkp->nr_zones,
			  sdkp->zone_blocks);
}
