/* SPDX-License-Identifier: GPL-2.0+ */
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/kernel.h>   /* printk() */
#include <linux/slab.h>     /* kmalloc() */
#include <linux/fs.h>       /* everything... */
#include <linux/errno.h>    /* error codes */
#include <linux/types.h>    /* size_t */
#include <linux/cdev.h>
#include <linux/uaccess.h>  /* copy_*_user */
#include <linux/aio.h>      /* aio stuff */
#include <linux/highmem.h>
#include <linux/pagemap.h>
#include "kpc_dma_driver.h"
#include "uapi.h"

/**********  Helper Functions  **********/
static inline
unsigned int  count_pages(unsigned long iov_base, size_t iov_len)
{
	unsigned long first = (iov_base             & PAGE_MASK) >> PAGE_SHIFT;
	unsigned long last  = ((iov_base+iov_len-1) & PAGE_MASK) >> PAGE_SHIFT;
	return last - first + 1;
}

static inline
unsigned int  count_parts_for_sge(struct scatterlist *sg)
{
	unsigned int sg_length = sg_dma_len(sg);
	sg_length += (0x80000-1);
	return (sg_length / 0x80000);
}

/**********  Transfer Helpers  **********/
static
int  kpc_dma_transfer(struct dev_private_data *priv, struct kiocb *kcb, unsigned long iov_base, size_t iov_len)
{
	unsigned int i = 0;
	long rv = 0;
	struct kpc_dma_device *ldev;
	struct aio_cb_data *acd;
	DECLARE_COMPLETION_ONSTACK(done);
	u32 desc_needed = 0;
	struct scatterlist *sg;
	u32 num_descrs_avail;
	struct kpc_dma_descriptor *desc;
	unsigned int pcnt;
	unsigned int p;
	u64 card_addr;
	u64 dma_addr;
	u64 user_ctl;
	
	BUG_ON(priv == NULL);
	ldev = priv->ldev;
	BUG_ON(ldev == NULL);
	
	dev_dbg(&priv->ldev->pldev->dev, "kpc_dma_transfer(priv = [%p], kcb = [%p], iov_base = [%p], iov_len = %ld) ldev = [%p]\n", priv, kcb, (void*)iov_base, iov_len, ldev);
	
	acd = (struct aio_cb_data *) kzalloc(sizeof(struct aio_cb_data), GFP_KERNEL);
	if (!acd){
		dev_err(&priv->ldev->pldev->dev, "Couldn't kmalloc space for for the aio data\n");
		return -ENOMEM;
	}
	memset(acd, 0x66, sizeof(struct aio_cb_data));
	
	acd->priv = priv;
	acd->ldev = priv->ldev;
	acd->cpl = &done;
	acd->flags = 0;
	acd->kcb = kcb;
	acd->len = iov_len;
	acd->page_count = count_pages(iov_base, iov_len);
	
	// Allocate an array of page pointers
	acd->user_pages = kzalloc(sizeof(struct page *) * acd->page_count, GFP_KERNEL);
	if (!acd->user_pages){
		dev_err(&priv->ldev->pldev->dev, "Couldn't kmalloc space for for the page pointers\n");
		rv = -ENOMEM;
		goto err_alloc_userpages;
	}
	
	// Lock the user buffer pages in memory, and hold on to the page pointers (for the sglist)
	down_read(&current->mm->mmap_sem);      /*  get memory map semaphore */
	rv = get_user_pages(iov_base, acd->page_count, FOLL_TOUCH | FOLL_WRITE | FOLL_GET, acd->user_pages, NULL);
	up_read(&current->mm->mmap_sem);        /*  release the semaphore */
	if (rv != acd->page_count){
		dev_err(&priv->ldev->pldev->dev, "Couldn't get_user_pages (%ld)\n", rv);
		goto err_get_user_pages;
	}
	
	// Allocate and setup the sg_table (scatterlist entries)
	rv = sg_alloc_table_from_pages(&acd->sgt, acd->user_pages, acd->page_count, iov_base & (PAGE_SIZE-1), iov_len, GFP_KERNEL);
	if (rv){
		dev_err(&priv->ldev->pldev->dev, "Couldn't alloc sg_table (%ld)\n", rv);
		goto err_alloc_sg_table;
	}
	
	// Setup the DMA mapping for all the sg entries
	acd->mapped_entry_count = dma_map_sg(&ldev->pldev->dev, acd->sgt.sgl, acd->sgt.nents, ldev->dir);
	if (acd->mapped_entry_count <= 0){
		dev_err(&priv->ldev->pldev->dev, "Couldn't dma_map_sg (%d)\n", acd->mapped_entry_count);
		goto err_dma_map_sg;
	}

	// Calculate how many descriptors are actually needed for this transfer.
	for_each_sg(acd->sgt.sgl, sg, acd->mapped_entry_count, i){
		desc_needed += count_parts_for_sge(sg);
	}
	
	lock_engine(ldev);
	
	// Figoure out how many descriptors are available and return an error if there aren't enough
	num_descrs_avail = count_descriptors_available(ldev);
	dev_dbg(&priv->ldev->pldev->dev, "    mapped_entry_count = %d    num_descrs_needed = %d    num_descrs_avail = %d\n", acd->mapped_entry_count, desc_needed, num_descrs_avail);
	if (desc_needed >= ldev->desc_pool_cnt){
		dev_warn(&priv->ldev->pldev->dev, "    mapped_entry_count = %d    num_descrs_needed = %d    num_descrs_avail = %d    TOO MANY to ever complete!\n", acd->mapped_entry_count, desc_needed, num_descrs_avail);
		rv = -EAGAIN;
		goto err_descr_too_many;
	}
	if (desc_needed > num_descrs_avail){
		dev_warn(&priv->ldev->pldev->dev, "    mapped_entry_count = %d    num_descrs_needed = %d    num_descrs_avail = %d    Too many to complete right now.\n", acd->mapped_entry_count, desc_needed, num_descrs_avail);
		rv = -EMSGSIZE;
		goto err_descr_too_many;
	}

	// Loop through all the sg table entries and fill out a descriptor for each one.
	desc = ldev->desc_next;
	card_addr = acd->priv->card_addr;
	for_each_sg(acd->sgt.sgl, sg, acd->mapped_entry_count, i){
		pcnt = count_parts_for_sge(sg);
		for (p = 0 ; p < pcnt ; p++){
			// Fill out the descriptor
			BUG_ON(desc == NULL);
			clear_desc(desc);
			if (p != pcnt-1){
				desc->DescByteCount = 0x80000;
			} else {
				desc->DescByteCount = sg_dma_len(sg) - (p * 0x80000);
			}
			desc->DescBufferByteCount = desc->DescByteCount;
			
			desc->DescControlFlags |= DMA_DESC_CTL_IRQONERR;
			if (i == 0 && p == 0)
				desc->DescControlFlags |= DMA_DESC_CTL_SOP;
			if (i == acd->mapped_entry_count-1 && p == pcnt-1)
				desc->DescControlFlags |= DMA_DESC_CTL_EOP | DMA_DESC_CTL_IRQONDONE;
			
			desc->DescCardAddrLS = (card_addr & 0xFFFFFFFF);
			desc->DescCardAddrMS = (card_addr >> 32) & 0xF;
			card_addr += desc->DescByteCount;
			
			dma_addr  = sg_dma_address(sg) + (p * 0x80000);
			desc->DescSystemAddrLS = (dma_addr & 0x00000000FFFFFFFF) >>  0;
			desc->DescSystemAddrMS = (dma_addr & 0xFFFFFFFF00000000) >> 32;
			
			user_ctl = acd->priv->user_ctl;
			if (i == acd->mapped_entry_count-1 && p == pcnt-1){
				user_ctl = acd->priv->user_ctl_last;
			}
			desc->DescUserControlLS = (user_ctl & 0x00000000FFFFFFFF) >>  0;
			desc->DescUserControlMS = (user_ctl & 0xFFFFFFFF00000000) >> 32;
			
			if (i == acd->mapped_entry_count-1 && p == pcnt-1)
				desc->acd = acd;
			
			dev_dbg(&priv->ldev->pldev->dev, "  Filled descriptor %p (acd = %p)\n", desc, desc->acd);
			
			ldev->desc_next = desc->Next;
			desc = desc->Next;
		}
	}
	
	// Send the filled descriptors off to the hardware to process!
	SetEngineSWPtr(ldev, ldev->desc_next);
	
	unlock_engine(ldev);
	
	// If this is a synchronous kiocb, we need to put the calling process to sleep until the transfer is complete
	if (kcb == NULL || is_sync_kiocb(kcb)){
		rv = wait_for_completion_interruptible(&done);
		// If the user aborted (rv == -ERESTARTSYS), we're no longer responsible for cleaning up the acd
		if (rv == -ERESTARTSYS){
			acd->cpl = NULL;
		}
		if (rv == 0){
			rv = acd->len;
			kfree(acd);
		}
		return rv;
	}
	
	return -EIOCBQUEUED;

 err_descr_too_many:
	unlock_engine(ldev);
	dma_unmap_sg(&ldev->pldev->dev, acd->sgt.sgl, acd->sgt.nents, ldev->dir);
	sg_free_table(&acd->sgt);
 err_dma_map_sg:
 err_alloc_sg_table:
	for (i = 0 ; i < acd->page_count ; i++){
		put_page(acd->user_pages[i]);
	}
 err_get_user_pages:
	kfree(acd->user_pages);
 err_alloc_userpages:
	kfree(acd);
	dev_dbg(&priv->ldev->pldev->dev, "kpc_dma_transfer returning with error %ld\n", rv);
	return rv;
}

void  transfer_complete_cb(struct aio_cb_data *acd, size_t xfr_count, u32 flags)
{
	unsigned int i;
	
	BUG_ON(acd == NULL);
	BUG_ON(acd->user_pages == NULL);
	BUG_ON(acd->sgt.sgl == NULL);
	BUG_ON(acd->ldev == NULL);
	BUG_ON(acd->ldev->pldev == NULL);
	
	dev_dbg(&acd->ldev->pldev->dev, "transfer_complete_cb(acd = [%p])\n", acd);
	
	for (i = 0 ; i < acd->page_count ; i++){
		if (!PageReserved(acd->user_pages[i])){
			set_page_dirty(acd->user_pages[i]);
		}
	}
	
	dma_unmap_sg(&acd->ldev->pldev->dev, acd->sgt.sgl, acd->sgt.nents, acd->ldev->dir);
	
	for (i = 0 ; i < acd->page_count ; i++){
		put_page(acd->user_pages[i]);
	}
	
	sg_free_table(&acd->sgt);
	
	kfree(acd->user_pages);
	
	acd->flags = flags;
	
	if (acd->kcb == NULL || is_sync_kiocb(acd->kcb)){
		if (acd->cpl){
			complete(acd->cpl);
		} else {
			// There's no completion, so we're responsible for cleaning up the acd
			kfree(acd);
		}
	} else {
#ifdef CONFIG_KPC_DMA_AIO
		aio_complete(acd->kcb, acd->len, acd->flags);
#endif
		kfree(acd);
	}
}

/**********  Fileops  **********/
static
int  kpc_dma_open(struct inode *inode, struct file *filp)
{
	struct dev_private_data *priv;
	struct kpc_dma_device *ldev = kpc_dma_lookup_device(iminor(inode));
	if (ldev == NULL)
		return -ENODEV;
	
	if (! atomic_dec_and_test(&ldev->open_count)){
		atomic_inc(&ldev->open_count);
		return -EBUSY; /* already open */
	}
	
	priv = kzalloc(sizeof(struct dev_private_data), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;
	
	priv->ldev = ldev;
	filp->private_data = priv;
	
	dev_dbg(&priv->ldev->pldev->dev, "kpc_dma_open(inode = [%p], filp = [%p]) priv = [%p] ldev = [%p]\n", inode, filp, priv, priv->ldev);
	return 0;
}

static
int  kpc_dma_close(struct inode *inode, struct file *filp)
{
	struct kpc_dma_descriptor *cur;
	struct dev_private_data *priv = (struct dev_private_data *)filp->private_data;
	struct kpc_dma_device *eng = priv->ldev;
	dev_dbg(&priv->ldev->pldev->dev, "kpc_dma_close(inode = [%p], filp = [%p]) priv = [%p], ldev = [%p]\n", inode, filp, priv, priv->ldev);
	
	lock_engine(eng);
	
	stop_dma_engine(eng);
	
	cur = eng->desc_completed->Next;
	while (cur != eng->desc_next){
		dev_dbg(&eng->pldev->dev, "Aborting descriptor %p (acd = %p)\n", cur, cur->acd);
		if (cur->DescControlFlags & DMA_DESC_CTL_EOP){
			if (cur->acd)
				transfer_complete_cb(cur->acd, 0, ACD_FLAG_ABORT);
		}
		
		clear_desc(cur);
		eng->desc_completed = cur;
		
		cur = cur->Next;
	}
	
	start_dma_engine(eng);
	
	unlock_engine(eng);
	
	atomic_inc(&priv->ldev->open_count); /* release the device */
	kfree(priv);
	return 0;
}

#ifdef CONFIG_KPC_DMA_AIO
static
int  kpc_dma_aio_cancel(struct kiocb *kcb)
{
	struct dev_private_data *priv = (struct dev_private_data *)kcb->ki_filp->private_data;
	dev_dbg(&priv->ldev->pldev->dev, "kpc_dma_aio_cancel(kcb = [%p]) priv = [%p], ldev = [%p]\n", kcb, priv, priv->ldev);
	return 0;
}

static
ssize_t   kpc_dma_aio_read(struct kiocb *kcb, const struct iovec *iov, unsigned long iov_count, loff_t pos)
{
	struct dev_private_data *priv = (struct dev_private_data *)kcb->ki_filp->private_data;
	dev_dbg(&priv->ldev->pldev->dev, "kpc_dma_aio_read(kcb = [%p], iov = [%p], iov_count = %ld, pos = %lld) priv = [%p], ldev = [%p]\n", kcb, iov, iov_count, pos, priv, priv->ldev);
	
	if (priv->ldev->dir != DMA_FROM_DEVICE)
		return -EMEDIUMTYPE;
	
	if (iov_count != 1){
		dev_err(&priv->ldev->pldev->dev, "kpc_dma_aio_read() called with iov_count > 1!\n");
		return -EFAULT;
	}
	
	if (!is_sync_kiocb(kcb))
		kiocb_set_cancel_fn(kcb, kpc_dma_aio_cancel);
	return kpc_dma_transfer(priv, kcb, (unsigned long)iov->iov_base, iov->iov_len);
}

static
ssize_t  kpc_dma_aio_write(struct kiocb *kcb, const struct iovec *iov, unsigned long iov_count, loff_t pos)
{
	struct dev_private_data *priv = (struct dev_private_data *)kcb->ki_filp->private_data;
	dev_dbg(&priv->ldev->pldev->dev, "kpc_dma_aio_write(kcb = [%p], iov = [%p], iov_count = %ld, pos = %lld) priv = [%p], ldev = [%p]\n", kcb, iov, iov_count, pos, priv, priv->ldev);
	
	if (priv->ldev->dir != DMA_TO_DEVICE)
		return -EMEDIUMTYPE;
	
	if (iov_count != 1){
		dev_err(&priv->ldev->pldev->dev, "kpc_dma_aio_write() called with iov_count > 1!\n");
		return -EFAULT;
	}
	
	if (!is_sync_kiocb(kcb))
		kiocb_set_cancel_fn(kcb, kpc_dma_aio_cancel);
	return kpc_dma_transfer(priv, kcb, (unsigned long)iov->iov_base, iov->iov_len);
}
#endif

static
ssize_t  kpc_dma_read( struct file *filp,       char __user *user_buf, size_t count, loff_t *ppos)
{
	struct dev_private_data *priv = (struct dev_private_data *)filp->private_data;
	dev_dbg(&priv->ldev->pldev->dev, "kpc_dma_read(filp = [%p], user_buf = [%p], count = %zu, ppos = [%p]) priv = [%p], ldev = [%p]\n", filp, user_buf, count, ppos, priv, priv->ldev);
	
	if (priv->ldev->dir != DMA_FROM_DEVICE)
		return -EMEDIUMTYPE;
	
	return kpc_dma_transfer(priv, (struct kiocb *)NULL, (unsigned long)user_buf, count);
}

static
ssize_t  kpc_dma_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *ppos)
{
	struct dev_private_data *priv = (struct dev_private_data *)filp->private_data;
	dev_dbg(&priv->ldev->pldev->dev, "kpc_dma_write(filp = [%p], user_buf = [%p], count = %zu, ppos = [%p]) priv = [%p], ldev = [%p]\n", filp, user_buf, count, ppos, priv, priv->ldev);
	
	if (priv->ldev->dir != DMA_TO_DEVICE)
		return -EMEDIUMTYPE;
	
	return kpc_dma_transfer(priv, (struct kiocb *)NULL, (unsigned long)user_buf, count);
}

static
long  kpc_dma_ioctl(struct file *filp, unsigned int ioctl_num, unsigned long ioctl_param)
{
	struct dev_private_data *priv = (struct dev_private_data *)filp->private_data;
	dev_dbg(&priv->ldev->pldev->dev, "kpc_dma_ioctl(filp = [%p], ioctl_num = 0x%x, ioctl_param = 0x%lx) priv = [%p], ldev = [%p]\n", filp, ioctl_num, ioctl_param, priv, priv->ldev);
	
	switch (ioctl_num){
		case KND_IOCTL_SET_CARD_ADDR:           priv->card_addr  = ioctl_param; return priv->card_addr; 
		case KND_IOCTL_SET_USER_CTL:            priv->user_ctl   = ioctl_param; return priv->user_ctl; 
		case KND_IOCTL_SET_USER_CTL_LAST:       priv->user_ctl_last = ioctl_param; return priv->user_ctl_last; 
		case KND_IOCTL_GET_USER_STS:            return priv->user_sts;
	}
	
	return -ENOTTY;
}


struct file_operations  kpc_dma_fops = {
	.owner      = THIS_MODULE,
	.open           = kpc_dma_open,
	.release        = kpc_dma_close,
	.read           = kpc_dma_read,
	.write          = kpc_dma_write,
#ifdef CONFIG_KPC_DMA_AIO
	.aio_read       = kpc_dma_aio_read,
	.aio_write      = kpc_dma_aio_write,
#endif
	.unlocked_ioctl = kpc_dma_ioctl,
};

