// SPDX-License-Identifier: GPL-2.0-only
// Copyright 2014 Cisco Systems, Inc.  All rights reserved.

#include <linux/errno.h>
#include <linux/mempool.h>

#include <scsi/scsi_tcq.h>

#include "snic_disc.h"
#include "snic.h"
#include "snic_io.h"


/* snic target types */
static const char * const snic_tgt_type_str[] = {
	[SNIC_TGT_DAS] = "DAS",
	[SNIC_TGT_SAN] = "SAN",
};

static inline const char *
snic_tgt_type_to_str(int typ)
{
	return ((typ > SNIC_TGT_NONE && typ <= SNIC_TGT_SAN) ?
		 snic_tgt_type_str[typ] : "Unknown");
}

static const char * const snic_tgt_state_str[] = {
	[SNIC_TGT_STAT_INIT]	= "INIT",
	[SNIC_TGT_STAT_ONLINE]	= "ONLINE",
	[SNIC_TGT_STAT_OFFLINE]	= "OFFLINE",
	[SNIC_TGT_STAT_DEL]	= "DELETION IN PROGRESS",
};

const char *
snic_tgt_state_to_str(int state)
{
	return ((state >= SNIC_TGT_STAT_INIT && state <= SNIC_TGT_STAT_DEL) ?
		snic_tgt_state_str[state] : "UNKNOWN");
}

/*
 * Initiate report_tgt req desc
 */
static void
snic_report_tgt_init(struct snic_host_req *req, u32 hid, u8 *buf, u32 len,
		     dma_addr_t rsp_buf_pa, ulong ctx)
{
	struct snic_sg_desc *sgd = NULL;


	snic_io_hdr_enc(&req->hdr, SNIC_REQ_REPORT_TGTS, 0, SCSI_NO_TAG, hid,
			1, ctx);

	req->u.rpt_tgts.sg_cnt = cpu_to_le16(1);
	sgd = req_to_sgl(req);
	sgd[0].addr = cpu_to_le64(rsp_buf_pa);
	sgd[0].len = cpu_to_le32(len);
	sgd[0]._resvd = 0;
	req->u.rpt_tgts.sg_addr = cpu_to_le64((ulong)sgd);
}

/*
 * snic_queue_report_tgt_req: Queues report target request.
 */
static int
snic_queue_report_tgt_req(struct snic *snic)
{
	struct snic_req_info *rqi = NULL;
	u32 ntgts, buf_len = 0;
	u8 *buf = NULL;
	dma_addr_t pa = 0;
	int ret = 0;

	rqi = snic_req_init(snic, 1);
	if (!rqi) {
		ret = -ENOMEM;
		goto error;
	}

	if (snic->fwinfo.max_tgts)
		ntgts = min_t(u32, snic->fwinfo.max_tgts, snic->shost->max_id);
	else
		ntgts = snic->shost->max_id;

	/* Allocate Response Buffer */
	SNIC_BUG_ON(ntgts == 0);
	buf_len = ntgts * sizeof(struct snic_tgt_id) + SNIC_SG_DESC_ALIGN;

	buf = kzalloc(buf_len, GFP_KERNEL);
	if (!buf) {
		snic_req_free(snic, rqi);
		SNIC_HOST_ERR(snic->shost, "Resp Buf Alloc Failed.\n");

		ret = -ENOMEM;
		goto error;
	}

	SNIC_BUG_ON((((unsigned long)buf) % SNIC_SG_DESC_ALIGN) != 0);

	pa = dma_map_single(&snic->pdev->dev, buf, buf_len, DMA_FROM_DEVICE);
	if (dma_mapping_error(&snic->pdev->dev, pa)) {
		SNIC_HOST_ERR(snic->shost,
			      "Rpt-tgt rspbuf %p: PCI DMA Mapping Failed\n",
			      buf);
		kfree(buf);
		snic_req_free(snic, rqi);
		ret = -EINVAL;

		goto error;
	}


	SNIC_BUG_ON(pa == 0);
	rqi->sge_va = (ulong) buf;

	snic_report_tgt_init(rqi->req,
			     snic->config.hid,
			     buf,
			     buf_len,
			     pa,
			     (ulong)rqi);

	snic_handle_untagged_req(snic, rqi);

	ret = snic_queue_wq_desc(snic, rqi->req, rqi->req_len);
	if (ret) {
		dma_unmap_single(&snic->pdev->dev, pa, buf_len,
				 DMA_FROM_DEVICE);
		kfree(buf);
		rqi->sge_va = 0;
		snic_release_untagged_req(snic, rqi);
		SNIC_HOST_ERR(snic->shost, "Queuing Report Tgts Failed.\n");

		goto error;
	}

	SNIC_DISC_DBG(snic->shost, "Report Targets Issued.\n");

	return ret;

error:
	SNIC_HOST_ERR(snic->shost,
		      "Queuing Report Targets Failed, err = %d\n",
		      ret);
	return ret;
} /* end of snic_queue_report_tgt_req */

/* call into SML */
static void
snic_scsi_scan_tgt(struct work_struct *work)
{
	struct snic_tgt *tgt = container_of(work, struct snic_tgt, scan_work);
	struct Scsi_Host *shost = dev_to_shost(&tgt->dev);
	unsigned long flags;

	SNIC_HOST_INFO(shost, "Scanning Target id 0x%x\n", tgt->id);
	scsi_scan_target(&tgt->dev,
			 tgt->channel,
			 tgt->scsi_tgt_id,
			 SCAN_WILD_CARD,
			 SCSI_SCAN_RESCAN);

	spin_lock_irqsave(shost->host_lock, flags);
	tgt->flags &= ~SNIC_TGT_SCAN_PENDING;
	spin_unlock_irqrestore(shost->host_lock, flags);
} /* end of snic_scsi_scan_tgt */

/*
 * snic_tgt_lookup :
 */
static struct snic_tgt *
snic_tgt_lookup(struct snic *snic, struct snic_tgt_id *tgtid)
{
	struct list_head *cur, *nxt;
	struct snic_tgt *tgt = NULL;

	list_for_each_safe(cur, nxt, &snic->disc.tgt_list) {
		tgt = list_entry(cur, struct snic_tgt, list);
		if (tgt->id == le32_to_cpu(tgtid->tgt_id))
			return tgt;
		tgt = NULL;
	}

	return tgt;
} /* end of snic_tgt_lookup */

/*
 * snic_tgt_dev_release : Called on dropping last ref for snic_tgt object
 */
void
snic_tgt_dev_release(struct device *dev)
{
	struct snic_tgt *tgt = dev_to_tgt(dev);

	SNIC_HOST_INFO(snic_tgt_to_shost(tgt),
		       "Target Device ID %d (%s) Permanently Deleted.\n",
		       tgt->id,
		       dev_name(dev));

	SNIC_BUG_ON(!list_empty(&tgt->list));
	kfree(tgt);
}

/*
 * snic_tgt_del : work function to delete snic_tgt
 */
static void
snic_tgt_del(struct work_struct *work)
{
	struct snic_tgt *tgt = container_of(work, struct snic_tgt, del_work);
	struct Scsi_Host *shost = snic_tgt_to_shost(tgt);

	if (tgt->flags & SNIC_TGT_SCAN_PENDING)
		scsi_flush_work(shost);

	/* Block IOs on child devices, stops new IOs */
	scsi_target_block(&tgt->dev);

	/* Cleanup IOs */
	snic_tgt_scsi_abort_io(tgt);

	/* Unblock IOs now, to flush if there are any. */
	scsi_target_unblock(&tgt->dev, SDEV_TRANSPORT_OFFLINE);

	/* Delete SCSI Target and sdevs */
	scsi_remove_target(&tgt->dev);  /* ?? */
	device_del(&tgt->dev);
	put_device(&tgt->dev);
} /* end of snic_tgt_del */

/* snic_tgt_create: checks for existence of snic_tgt, if it doesn't
 * it creates one.
 */
static struct snic_tgt *
snic_tgt_create(struct snic *snic, struct snic_tgt_id *tgtid)
{
	struct snic_tgt *tgt = NULL;
	unsigned long flags;
	int ret;

	tgt = snic_tgt_lookup(snic, tgtid);
	if (tgt) {
		/* update the information if required */
		return tgt;
	}

	tgt = kzalloc(sizeof(*tgt), GFP_KERNEL);
	if (!tgt) {
		SNIC_HOST_ERR(snic->shost, "Failure to allocate snic_tgt.\n");
		ret = -ENOMEM;

		return tgt;
	}

	INIT_LIST_HEAD(&tgt->list);
	tgt->id = le32_to_cpu(tgtid->tgt_id);
	tgt->channel = 0;

	SNIC_BUG_ON(le16_to_cpu(tgtid->tgt_type) > SNIC_TGT_SAN);
	tgt->tdata.typ = le16_to_cpu(tgtid->tgt_type);

	/*
	 * Plugging into SML Device Tree
	 */
	tgt->tdata.disc_id = 0;
	tgt->state = SNIC_TGT_STAT_INIT;
	device_initialize(&tgt->dev);
	tgt->dev.parent = get_device(&snic->shost->shost_gendev);
	tgt->dev.release = snic_tgt_dev_release;
	INIT_WORK(&tgt->scan_work, snic_scsi_scan_tgt);
	INIT_WORK(&tgt->del_work, snic_tgt_del);
	switch (tgt->tdata.typ) {
	case SNIC_TGT_DAS:
		dev_set_name(&tgt->dev, "snic_das_tgt:%d:%d-%d",
			     snic->shost->host_no, tgt->channel, tgt->id);
		break;

	case SNIC_TGT_SAN:
		dev_set_name(&tgt->dev, "snic_san_tgt:%d:%d-%d",
			     snic->shost->host_no, tgt->channel, tgt->id);
		break;

	default:
		SNIC_HOST_INFO(snic->shost, "Target type Unknown Detected.\n");
		dev_set_name(&tgt->dev, "snic_das_tgt:%d:%d-%d",
			     snic->shost->host_no, tgt->channel, tgt->id);
		break;
	}

	spin_lock_irqsave(snic->shost->host_lock, flags);
	list_add_tail(&tgt->list, &snic->disc.tgt_list);
	tgt->scsi_tgt_id = snic->disc.nxt_tgt_id++;
	tgt->state = SNIC_TGT_STAT_ONLINE;
	spin_unlock_irqrestore(snic->shost->host_lock, flags);

	SNIC_HOST_INFO(snic->shost,
		       "Tgt %d, type = %s detected. Adding..\n",
		       tgt->id, snic_tgt_type_to_str(tgt->tdata.typ));

	ret = device_add(&tgt->dev);
	if (ret) {
		SNIC_HOST_ERR(snic->shost,
			      "Snic Tgt: device_add, with err = %d\n",
			      ret);

		put_device(&snic->shost->shost_gendev);
		spin_lock_irqsave(snic->shost->host_lock, flags);
		list_del(&tgt->list);
		spin_unlock_irqrestore(snic->shost->host_lock, flags);
		kfree(tgt);
		tgt = NULL;

		return tgt;
	}

	SNIC_HOST_INFO(snic->shost, "Scanning %s.\n", dev_name(&tgt->dev));

	scsi_queue_work(snic->shost, &tgt->scan_work);

	return tgt;
} /* end of snic_tgt_create */

/* Handler for discovery */
void
snic_handle_tgt_disc(struct work_struct *work)
{
	struct snic *snic = container_of(work, struct snic, tgt_work);
	struct snic_tgt_id *tgtid = NULL;
	struct snic_tgt *tgt = NULL;
	unsigned long flags;
	int i;

	spin_lock_irqsave(&snic->snic_lock, flags);
	if (snic->in_remove) {
		spin_unlock_irqrestore(&snic->snic_lock, flags);
		kfree(snic->disc.rtgt_info);

		return;
	}
	spin_unlock_irqrestore(&snic->snic_lock, flags);

	mutex_lock(&snic->disc.mutex);
	/* Discover triggered during disc in progress */
	if (snic->disc.req_cnt) {
		snic->disc.state = SNIC_DISC_DONE;
		snic->disc.req_cnt = 0;
		mutex_unlock(&snic->disc.mutex);
		kfree(snic->disc.rtgt_info);
		snic->disc.rtgt_info = NULL;

		SNIC_HOST_INFO(snic->shost, "tgt_disc: Discovery restart.\n");
		/* Start Discovery Again */
		snic_disc_start(snic);

		return;
	}

	tgtid = (struct snic_tgt_id *)snic->disc.rtgt_info;

	SNIC_BUG_ON(snic->disc.rtgt_cnt == 0 || tgtid == NULL);

	for (i = 0; i < snic->disc.rtgt_cnt; i++) {
		tgt = snic_tgt_create(snic, &tgtid[i]);
		if (!tgt) {
			int buf_sz = snic->disc.rtgt_cnt * sizeof(*tgtid);

			SNIC_HOST_ERR(snic->shost, "Failed to create tgt.\n");
			snic_hex_dump("rpt_tgt_rsp", (char *)tgtid, buf_sz);
			break;
		}
	}

	snic->disc.rtgt_info = NULL;
	snic->disc.state = SNIC_DISC_DONE;
	mutex_unlock(&snic->disc.mutex);

	SNIC_HOST_INFO(snic->shost, "Discovery Completed.\n");

	kfree(tgtid);
} /* end of snic_handle_tgt_disc */


int
snic_report_tgt_cmpl_handler(struct snic *snic, struct snic_fw_req *fwreq)
{

	u8 typ, cmpl_stat;
	u32 cmnd_id, hid, tgt_cnt = 0;
	ulong ctx;
	struct snic_req_info *rqi = NULL;
	struct snic_tgt_id *tgtid;
	int i, ret = 0;

	snic_io_hdr_dec(&fwreq->hdr, &typ, &cmpl_stat, &cmnd_id, &hid, &ctx);
	rqi = (struct snic_req_info *) ctx;
	tgtid = (struct snic_tgt_id *) rqi->sge_va;

	tgt_cnt = le32_to_cpu(fwreq->u.rpt_tgts_cmpl.tgt_cnt);
	if (tgt_cnt == 0) {
		SNIC_HOST_ERR(snic->shost, "No Targets Found on this host.\n");
		ret = 1;

		goto end;
	}

	/* printing list of targets here */
	SNIC_HOST_INFO(snic->shost, "Target Count = %d\n", tgt_cnt);

	SNIC_BUG_ON(tgt_cnt > snic->fwinfo.max_tgts);

	for (i = 0; i < tgt_cnt; i++)
		SNIC_HOST_INFO(snic->shost,
			       "Tgt id = 0x%x\n",
			       le32_to_cpu(tgtid[i].tgt_id));

	/*
	 * Queue work for further processing,
	 * Response Buffer Memory is freed after creating targets
	 */
	snic->disc.rtgt_cnt = tgt_cnt;
	snic->disc.rtgt_info = (u8 *) tgtid;
	queue_work(snic_glob->event_q, &snic->tgt_work);
	ret = 0;

end:
	/* Unmap Response Buffer */
	snic_pci_unmap_rsp_buf(snic, rqi);
	if (ret)
		kfree(tgtid);

	rqi->sge_va = 0;
	snic_release_untagged_req(snic, rqi);

	return ret;
} /* end of snic_report_tgt_cmpl_handler */

/* Discovery init fn */
void
snic_disc_init(struct snic_disc *disc)
{
	INIT_LIST_HEAD(&disc->tgt_list);
	mutex_init(&disc->mutex);
	disc->disc_id = 0;
	disc->nxt_tgt_id = 0;
	disc->state = SNIC_DISC_INIT;
	disc->req_cnt = 0;
	disc->rtgt_cnt = 0;
	disc->rtgt_info = NULL;
	disc->cb = NULL;
} /* end of snic_disc_init */

/* Discovery, uninit fn */
void
snic_disc_term(struct snic *snic)
{
	struct snic_disc *disc = &snic->disc;

	mutex_lock(&disc->mutex);
	if (disc->req_cnt) {
		disc->req_cnt = 0;
		SNIC_SCSI_DBG(snic->shost, "Terminating Discovery.\n");
	}
	mutex_unlock(&disc->mutex);
}

/*
 * snic_disc_start: Discovery Start ...
 */
int
snic_disc_start(struct snic *snic)
{
	struct snic_disc *disc = &snic->disc;
	unsigned long flags;
	int ret = 0;

	SNIC_SCSI_DBG(snic->shost, "Discovery Start.\n");

	spin_lock_irqsave(&snic->snic_lock, flags);
	if (snic->in_remove) {
		spin_unlock_irqrestore(&snic->snic_lock, flags);
		SNIC_ERR("snic driver removal in progress ...\n");
		ret = 0;

		return ret;
	}
	spin_unlock_irqrestore(&snic->snic_lock, flags);

	mutex_lock(&disc->mutex);
	if (disc->state == SNIC_DISC_PENDING) {
		disc->req_cnt++;
		mutex_unlock(&disc->mutex);

		return ret;
	}
	disc->state = SNIC_DISC_PENDING;
	mutex_unlock(&disc->mutex);

	ret = snic_queue_report_tgt_req(snic);
	if (ret)
		SNIC_HOST_INFO(snic->shost, "Discovery Failed, err=%d.\n", ret);

	return ret;
} /* end of snic_disc_start */

/*
 * snic_disc_work :
 */
void
snic_handle_disc(struct work_struct *work)
{
	struct snic *snic = container_of(work, struct snic, disc_work);
	int ret = 0;

	SNIC_HOST_INFO(snic->shost, "disc_work: Discovery\n");

	ret = snic_disc_start(snic);
	if (ret)
		goto disc_err;

disc_err:
	SNIC_HOST_ERR(snic->shost,
		      "disc_work: Discovery Failed w/ err = %d\n",
		      ret);
} /* end of snic_disc_work */

/*
 * snic_tgt_del_all : cleanup all snic targets
 * Called on unbinding the interface
 */
void
snic_tgt_del_all(struct snic *snic)
{
	struct snic_tgt *tgt = NULL;
	struct list_head *cur, *nxt;
	unsigned long flags;

	scsi_flush_work(snic->shost);

	mutex_lock(&snic->disc.mutex);
	spin_lock_irqsave(snic->shost->host_lock, flags);

	list_for_each_safe(cur, nxt, &snic->disc.tgt_list) {
		tgt = list_entry(cur, struct snic_tgt, list);
		tgt->state = SNIC_TGT_STAT_DEL;
		list_del_init(&tgt->list);
		SNIC_HOST_INFO(snic->shost, "Tgt %d q'ing for del\n", tgt->id);
		queue_work(snic_glob->event_q, &tgt->del_work);
		tgt = NULL;
	}
	spin_unlock_irqrestore(snic->shost->host_lock, flags);
	mutex_unlock(&snic->disc.mutex);

	flush_workqueue(snic_glob->event_q);
} /* end of snic_tgt_del_all */
