// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2021 Broadcom. All Rights Reserved. The term
 * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
 */

#include "efct_driver.h"
#include "efct_hw.h"
#include "efct_io.h"

struct efct_io_pool {
	struct efct *efct;
	spinlock_t lock;	/* IO pool lock */
	u32 io_num_ios;		/* Total IOs allocated */
	struct efct_io *ios[EFCT_NUM_SCSI_IOS];
	struct list_head freelist;

};

struct efct_io_pool *
efct_io_pool_create(struct efct *efct, u32 num_sgl)
{
	u32 i = 0;
	struct efct_io_pool *io_pool;
	struct efct_io *io;

	/* Allocate the IO pool */
	io_pool = kzalloc(sizeof(*io_pool), GFP_KERNEL);
	if (!io_pool)
		return NULL;

	io_pool->efct = efct;
	INIT_LIST_HEAD(&io_pool->freelist);
	/* initialize IO pool lock */
	spin_lock_init(&io_pool->lock);

	for (i = 0; i < EFCT_NUM_SCSI_IOS; i++) {
		io = kzalloc(sizeof(*io), GFP_KERNEL);
		if (!io)
			break;

		io_pool->io_num_ios++;
		io_pool->ios[i] = io;
		io->tag = i;
		io->instance_index = i;

		/* Allocate a response buffer */
		io->rspbuf.size = SCSI_RSP_BUF_LENGTH;
		io->rspbuf.virt = dma_alloc_coherent(&efct->pci->dev,
						     io->rspbuf.size,
						     &io->rspbuf.phys, GFP_KERNEL);
		if (!io->rspbuf.virt) {
			efc_log_err(efct, "dma_alloc rspbuf failed\n");
			efct_io_pool_free(io_pool);
			return NULL;
		}

		/* Allocate SGL */
		io->sgl = kzalloc(sizeof(*io->sgl) * num_sgl, GFP_KERNEL);
		if (!io->sgl) {
			efct_io_pool_free(io_pool);
			return NULL;
		}

		io->sgl_allocated = num_sgl;
		io->sgl_count = 0;

		INIT_LIST_HEAD(&io->list_entry);
		list_add_tail(&io->list_entry, &io_pool->freelist);
	}

	return io_pool;
}

int
efct_io_pool_free(struct efct_io_pool *io_pool)
{
	struct efct *efct;
	u32 i;
	struct efct_io *io;

	if (io_pool) {
		efct = io_pool->efct;

		for (i = 0; i < io_pool->io_num_ios; i++) {
			io = io_pool->ios[i];
			if (!io)
				continue;

			kfree(io->sgl);
			dma_free_coherent(&efct->pci->dev,
					  io->rspbuf.size, io->rspbuf.virt,
					  io->rspbuf.phys);
			memset(&io->rspbuf, 0, sizeof(struct efc_dma));
		}

		kfree(io_pool);
		efct->xport->io_pool = NULL;
	}

	return 0;
}

struct efct_io *
efct_io_pool_io_alloc(struct efct_io_pool *io_pool)
{
	struct efct_io *io = NULL;
	struct efct *efct;
	unsigned long flags = 0;

	efct = io_pool->efct;

	spin_lock_irqsave(&io_pool->lock, flags);

	if (!list_empty(&io_pool->freelist)) {
		io = list_first_entry(&io_pool->freelist, struct efct_io,
				      list_entry);
		list_del_init(&io->list_entry);
	}

	spin_unlock_irqrestore(&io_pool->lock, flags);

	if (!io)
		return NULL;

	io->io_type = EFCT_IO_TYPE_MAX;
	io->hio_type = EFCT_HW_IO_MAX;
	io->hio = NULL;
	io->transferred = 0;
	io->efct = efct;
	io->timeout = 0;
	io->sgl_count = 0;
	io->tgt_task_tag = 0;
	io->init_task_tag = 0;
	io->hw_tag = 0;
	io->display_name = "pending";
	io->seq_init = 0;
	io->io_free = 0;
	io->release = NULL;
	atomic_add_return(1, &efct->xport->io_active_count);
	atomic_add_return(1, &efct->xport->io_total_alloc);
	return io;
}

/* Free an object used to track an IO */
void
efct_io_pool_io_free(struct efct_io_pool *io_pool, struct efct_io *io)
{
	struct efct *efct;
	struct efct_hw_io *hio = NULL;
	unsigned long flags = 0;

	efct = io_pool->efct;

	spin_lock_irqsave(&io_pool->lock, flags);
	hio = io->hio;
	io->hio = NULL;
	io->io_free = 1;
	INIT_LIST_HEAD(&io->list_entry);
	list_add(&io->list_entry, &io_pool->freelist);
	spin_unlock_irqrestore(&io_pool->lock, flags);

	if (hio)
		efct_hw_io_free(&efct->hw, hio);

	atomic_sub_return(1, &efct->xport->io_active_count);
	atomic_add_return(1, &efct->xport->io_total_free);
}

/* Find an I/O given it's node and ox_id */
struct efct_io *
efct_io_find_tgt_io(struct efct *efct, struct efct_node *node,
		    u16 ox_id, u16 rx_id)
{
	struct efct_io	*io = NULL;
	unsigned long flags = 0;
	u8 found = false;

	spin_lock_irqsave(&node->active_ios_lock, flags);
	list_for_each_entry(io, &node->active_ios, list_entry) {
		if ((io->cmd_tgt && io->init_task_tag == ox_id) &&
		    (rx_id == 0xffff || io->tgt_task_tag == rx_id)) {
			if (kref_get_unless_zero(&io->ref))
				found = true;
			break;
		}
	}
	spin_unlock_irqrestore(&node->active_ios_lock, flags);
	return found ? io : NULL;
}
