// SPDX-License-Identifier: GPL-2.0-only
/**
 * IBM Accelerator Family 'GenWQE'
 *
 * (C) Copyright IBM Corp. 2013
 *
 * Author: Frank Haverkamp <haver@linux.vnet.ibm.com>
 * Author: Joerg-Stephan Vogt <jsvogt@de.ibm.com>
 * Author: Michael Jung <mijung@gmx.net>
 * Author: Michael Ruettger <michael@ibmra.de>
 */

/*
 * Character device representation of the GenWQE device. This allows
 * user-space applications to communicate with the card.
 */

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/string.h>
#include <linux/fs.h>
#include <linux/sched/signal.h>
#include <linux/wait.h>
#include <linux/delay.h>
#include <linux/atomic.h>

#include "card_base.h"
#include "card_ddcb.h"

static int genwqe_open_files(struct genwqe_dev *cd)
{
	int rc;
	unsigned long flags;

	spin_lock_irqsave(&cd->file_lock, flags);
	rc = list_empty(&cd->file_list);
	spin_unlock_irqrestore(&cd->file_lock, flags);
	return !rc;
}

static void genwqe_add_file(struct genwqe_dev *cd, struct genwqe_file *cfile)
{
	unsigned long flags;

	cfile->opener = get_pid(task_tgid(current));
	spin_lock_irqsave(&cd->file_lock, flags);
	list_add(&cfile->list, &cd->file_list);
	spin_unlock_irqrestore(&cd->file_lock, flags);
}

static int genwqe_del_file(struct genwqe_dev *cd, struct genwqe_file *cfile)
{
	unsigned long flags;

	spin_lock_irqsave(&cd->file_lock, flags);
	list_del(&cfile->list);
	spin_unlock_irqrestore(&cd->file_lock, flags);
	put_pid(cfile->opener);

	return 0;
}

static void genwqe_add_pin(struct genwqe_file *cfile, struct dma_mapping *m)
{
	unsigned long flags;

	spin_lock_irqsave(&cfile->pin_lock, flags);
	list_add(&m->pin_list, &cfile->pin_list);
	spin_unlock_irqrestore(&cfile->pin_lock, flags);
}

static int genwqe_del_pin(struct genwqe_file *cfile, struct dma_mapping *m)
{
	unsigned long flags;

	spin_lock_irqsave(&cfile->pin_lock, flags);
	list_del(&m->pin_list);
	spin_unlock_irqrestore(&cfile->pin_lock, flags);

	return 0;
}

/**
 * genwqe_search_pin() - Search for the mapping for a userspace address
 * @cfile:	Descriptor of opened file
 * @u_addr:	User virtual address
 * @size:	Size of buffer
 * @dma_addr:	DMA address to be updated
 *
 * Return: Pointer to the corresponding mapping	NULL if not found
 */
static struct dma_mapping *genwqe_search_pin(struct genwqe_file *cfile,
					    unsigned long u_addr,
					    unsigned int size,
					    void **virt_addr)
{
	unsigned long flags;
	struct dma_mapping *m;

	spin_lock_irqsave(&cfile->pin_lock, flags);

	list_for_each_entry(m, &cfile->pin_list, pin_list) {
		if ((((u64)m->u_vaddr) <= (u_addr)) &&
		    (((u64)m->u_vaddr + m->size) >= (u_addr + size))) {

			if (virt_addr)
				*virt_addr = m->k_vaddr +
					(u_addr - (u64)m->u_vaddr);

			spin_unlock_irqrestore(&cfile->pin_lock, flags);
			return m;
		}
	}
	spin_unlock_irqrestore(&cfile->pin_lock, flags);
	return NULL;
}

static void __genwqe_add_mapping(struct genwqe_file *cfile,
			      struct dma_mapping *dma_map)
{
	unsigned long flags;

	spin_lock_irqsave(&cfile->map_lock, flags);
	list_add(&dma_map->card_list, &cfile->map_list);
	spin_unlock_irqrestore(&cfile->map_lock, flags);
}

static void __genwqe_del_mapping(struct genwqe_file *cfile,
			      struct dma_mapping *dma_map)
{
	unsigned long flags;

	spin_lock_irqsave(&cfile->map_lock, flags);
	list_del(&dma_map->card_list);
	spin_unlock_irqrestore(&cfile->map_lock, flags);
}


/**
 * __genwqe_search_mapping() - Search for the mapping for a userspace address
 * @cfile:	descriptor of opened file
 * @u_addr:	user virtual address
 * @size:	size of buffer
 * @dma_addr:	DMA address to be updated
 * Return: Pointer to the corresponding mapping	NULL if not found
 */
static struct dma_mapping *__genwqe_search_mapping(struct genwqe_file *cfile,
						   unsigned long u_addr,
						   unsigned int size,
						   dma_addr_t *dma_addr,
						   void **virt_addr)
{
	unsigned long flags;
	struct dma_mapping *m;
	struct pci_dev *pci_dev = cfile->cd->pci_dev;

	spin_lock_irqsave(&cfile->map_lock, flags);
	list_for_each_entry(m, &cfile->map_list, card_list) {

		if ((((u64)m->u_vaddr) <= (u_addr)) &&
		    (((u64)m->u_vaddr + m->size) >= (u_addr + size))) {

			/* match found: current is as expected and
			   addr is in range */
			if (dma_addr)
				*dma_addr = m->dma_addr +
					(u_addr - (u64)m->u_vaddr);

			if (virt_addr)
				*virt_addr = m->k_vaddr +
					(u_addr - (u64)m->u_vaddr);

			spin_unlock_irqrestore(&cfile->map_lock, flags);
			return m;
		}
	}
	spin_unlock_irqrestore(&cfile->map_lock, flags);

	dev_err(&pci_dev->dev,
		"[%s] Entry not found: u_addr=%lx, size=%x\n",
		__func__, u_addr, size);

	return NULL;
}

static void genwqe_remove_mappings(struct genwqe_file *cfile)
{
	int i = 0;
	struct list_head *node, *next;
	struct dma_mapping *dma_map;
	struct genwqe_dev *cd = cfile->cd;
	struct pci_dev *pci_dev = cfile->cd->pci_dev;

	list_for_each_safe(node, next, &cfile->map_list) {
		dma_map = list_entry(node, struct dma_mapping, card_list);

		list_del_init(&dma_map->card_list);

		/*
		 * This is really a bug, because those things should
		 * have been already tidied up.
		 *
		 * GENWQE_MAPPING_RAW should have been removed via mmunmap().
		 * GENWQE_MAPPING_SGL_TEMP should be removed by tidy up code.
		 */
		dev_err(&pci_dev->dev,
			"[%s] %d. cleanup mapping: u_vaddr=%p u_kaddr=%016lx dma_addr=%lx\n",
			__func__, i++, dma_map->u_vaddr,
			(unsigned long)dma_map->k_vaddr,
			(unsigned long)dma_map->dma_addr);

		if (dma_map->type == GENWQE_MAPPING_RAW) {
			/* we allocated this dynamically */
			__genwqe_free_consistent(cd, dma_map->size,
						dma_map->k_vaddr,
						dma_map->dma_addr);
			kfree(dma_map);
		} else if (dma_map->type == GENWQE_MAPPING_SGL_TEMP) {
			/* we use dma_map statically from the request */
			genwqe_user_vunmap(cd, dma_map);
		}
	}
}

static void genwqe_remove_pinnings(struct genwqe_file *cfile)
{
	struct list_head *node, *next;
	struct dma_mapping *dma_map;
	struct genwqe_dev *cd = cfile->cd;

	list_for_each_safe(node, next, &cfile->pin_list) {
		dma_map = list_entry(node, struct dma_mapping, pin_list);

		/*
		 * This is not a bug, because a killed processed might
		 * not call the unpin ioctl, which is supposed to free
		 * the resources.
		 *
		 * Pinnings are dymically allocated and need to be
		 * deleted.
		 */
		list_del_init(&dma_map->pin_list);
		genwqe_user_vunmap(cd, dma_map);
		kfree(dma_map);
	}
}

/**
 * genwqe_kill_fasync() - Send signal to all processes with open GenWQE files
 *
 * E.g. genwqe_send_signal(cd, SIGIO);
 */
static int genwqe_kill_fasync(struct genwqe_dev *cd, int sig)
{
	unsigned int files = 0;
	unsigned long flags;
	struct genwqe_file *cfile;

	spin_lock_irqsave(&cd->file_lock, flags);
	list_for_each_entry(cfile, &cd->file_list, list) {
		if (cfile->async_queue)
			kill_fasync(&cfile->async_queue, sig, POLL_HUP);
		files++;
	}
	spin_unlock_irqrestore(&cd->file_lock, flags);
	return files;
}

static int genwqe_terminate(struct genwqe_dev *cd)
{
	unsigned int files = 0;
	unsigned long flags;
	struct genwqe_file *cfile;

	spin_lock_irqsave(&cd->file_lock, flags);
	list_for_each_entry(cfile, &cd->file_list, list) {
		kill_pid(cfile->opener, SIGKILL, 1);
		files++;
	}
	spin_unlock_irqrestore(&cd->file_lock, flags);
	return files;
}

/**
 * genwqe_open() - file open
 * @inode:      file system information
 * @filp:	file handle
 *
 * This function is executed whenever an application calls
 * open("/dev/genwqe",..).
 *
 * Return: 0 if successful or <0 if errors
 */
static int genwqe_open(struct inode *inode, struct file *filp)
{
	struct genwqe_dev *cd;
	struct genwqe_file *cfile;

	cfile = kzalloc(sizeof(*cfile), GFP_KERNEL);
	if (cfile == NULL)
		return -ENOMEM;

	cd = container_of(inode->i_cdev, struct genwqe_dev, cdev_genwqe);
	cfile->cd = cd;
	cfile->filp = filp;
	cfile->client = NULL;

	spin_lock_init(&cfile->map_lock);  /* list of raw memory allocations */
	INIT_LIST_HEAD(&cfile->map_list);

	spin_lock_init(&cfile->pin_lock);  /* list of user pinned memory */
	INIT_LIST_HEAD(&cfile->pin_list);

	filp->private_data = cfile;

	genwqe_add_file(cd, cfile);
	return 0;
}

/**
 * genwqe_fasync() - Setup process to receive SIGIO.
 * @fd:        file descriptor
 * @filp:      file handle
 * @mode:      file mode
 *
 * Sending a signal is working as following:
 *
 * if (cdev->async_queue)
 *         kill_fasync(&cdev->async_queue, SIGIO, POLL_IN);
 *
 * Some devices also implement asynchronous notification to indicate
 * when the device can be written; in this case, of course,
 * kill_fasync must be called with a mode of POLL_OUT.
 */
static int genwqe_fasync(int fd, struct file *filp, int mode)
{
	struct genwqe_file *cdev = (struct genwqe_file *)filp->private_data;

	return fasync_helper(fd, filp, mode, &cdev->async_queue);
}


/**
 * genwqe_release() - file close
 * @inode:      file system information
 * @filp:       file handle
 *
 * This function is executed whenever an application calls 'close(fd_genwqe)'
 *
 * Return: always 0
 */
static int genwqe_release(struct inode *inode, struct file *filp)
{
	struct genwqe_file *cfile = (struct genwqe_file *)filp->private_data;
	struct genwqe_dev *cd = cfile->cd;

	/* there must be no entries in these lists! */
	genwqe_remove_mappings(cfile);
	genwqe_remove_pinnings(cfile);

	/* remove this filp from the asynchronously notified filp's */
	genwqe_fasync(-1, filp, 0);

	/*
	 * For this to work we must not release cd when this cfile is
	 * not yet released, otherwise the list entry is invalid,
	 * because the list itself gets reinstantiated!
	 */
	genwqe_del_file(cd, cfile);
	kfree(cfile);
	return 0;
}

static void genwqe_vma_open(struct vm_area_struct *vma)
{
	/* nothing ... */
}

/**
 * genwqe_vma_close() - Called each time when vma is unmapped
 *
 * Free memory which got allocated by GenWQE mmap().
 */
static void genwqe_vma_close(struct vm_area_struct *vma)
{
	unsigned long vsize = vma->vm_end - vma->vm_start;
	struct inode *inode = file_inode(vma->vm_file);
	struct dma_mapping *dma_map;
	struct genwqe_dev *cd = container_of(inode->i_cdev, struct genwqe_dev,
					    cdev_genwqe);
	struct pci_dev *pci_dev = cd->pci_dev;
	dma_addr_t d_addr = 0;
	struct genwqe_file *cfile = vma->vm_private_data;

	dma_map = __genwqe_search_mapping(cfile, vma->vm_start, vsize,
					 &d_addr, NULL);
	if (dma_map == NULL) {
		dev_err(&pci_dev->dev,
			"  [%s] err: mapping not found: v=%lx, p=%lx s=%lx\n",
			__func__, vma->vm_start, vma->vm_pgoff << PAGE_SHIFT,
			vsize);
		return;
	}
	__genwqe_del_mapping(cfile, dma_map);
	__genwqe_free_consistent(cd, dma_map->size, dma_map->k_vaddr,
				 dma_map->dma_addr);
	kfree(dma_map);
}

static const struct vm_operations_struct genwqe_vma_ops = {
	.open   = genwqe_vma_open,
	.close  = genwqe_vma_close,
};

/**
 * genwqe_mmap() - Provide contignous buffers to userspace
 *
 * We use mmap() to allocate contignous buffers used for DMA
 * transfers. After the buffer is allocated we remap it to user-space
 * and remember a reference to our dma_mapping data structure, where
 * we store the associated DMA address and allocated size.
 *
 * When we receive a DDCB execution request with the ATS bits set to
 * plain buffer, we lookup our dma_mapping list to find the
 * corresponding DMA address for the associated user-space address.
 */
static int genwqe_mmap(struct file *filp, struct vm_area_struct *vma)
{
	int rc;
	unsigned long pfn, vsize = vma->vm_end - vma->vm_start;
	struct genwqe_file *cfile = (struct genwqe_file *)filp->private_data;
	struct genwqe_dev *cd = cfile->cd;
	struct dma_mapping *dma_map;

	if (vsize == 0)
		return -EINVAL;

	if (get_order(vsize) > MAX_ORDER)
		return -ENOMEM;

	dma_map = kzalloc(sizeof(struct dma_mapping), GFP_KERNEL);
	if (dma_map == NULL)
		return -ENOMEM;

	genwqe_mapping_init(dma_map, GENWQE_MAPPING_RAW);
	dma_map->u_vaddr = (void *)vma->vm_start;
	dma_map->size = vsize;
	dma_map->nr_pages = DIV_ROUND_UP(vsize, PAGE_SIZE);
	dma_map->k_vaddr = __genwqe_alloc_consistent(cd, vsize,
						     &dma_map->dma_addr);
	if (dma_map->k_vaddr == NULL) {
		rc = -ENOMEM;
		goto free_dma_map;
	}

	if (capable(CAP_SYS_ADMIN) && (vsize > sizeof(dma_addr_t)))
		*(dma_addr_t *)dma_map->k_vaddr = dma_map->dma_addr;

	pfn = virt_to_phys(dma_map->k_vaddr) >> PAGE_SHIFT;
	rc = remap_pfn_range(vma,
			     vma->vm_start,
			     pfn,
			     vsize,
			     vma->vm_page_prot);
	if (rc != 0) {
		rc = -EFAULT;
		goto free_dma_mem;
	}

	vma->vm_private_data = cfile;
	vma->vm_ops = &genwqe_vma_ops;
	__genwqe_add_mapping(cfile, dma_map);

	return 0;

 free_dma_mem:
	__genwqe_free_consistent(cd, dma_map->size,
				dma_map->k_vaddr,
				dma_map->dma_addr);
 free_dma_map:
	kfree(dma_map);
	return rc;
}

/**
 * do_flash_update() - Excute flash update (write image or CVPD)
 * @cd:        genwqe device
 * @load:      details about image load
 *
 * Return: 0 if successful
 */

#define	FLASH_BLOCK	0x40000	/* we use 256k blocks */

static int do_flash_update(struct genwqe_file *cfile,
			   struct genwqe_bitstream *load)
{
	int rc = 0;
	int blocks_to_flash;
	dma_addr_t dma_addr;
	u64 flash = 0;
	size_t tocopy = 0;
	u8 __user *buf;
	u8 *xbuf;
	u32 crc;
	u8 cmdopts;
	struct genwqe_dev *cd = cfile->cd;
	struct file *filp = cfile->filp;
	struct pci_dev *pci_dev = cd->pci_dev;

	if ((load->size & 0x3) != 0)
		return -EINVAL;

	if (((unsigned long)(load->data_addr) & ~PAGE_MASK) != 0)
		return -EINVAL;

	/* FIXME Bits have changed for new service layer! */
	switch ((char)load->partition) {
	case '0':
		cmdopts = 0x14;
		break;		/* download/erase_first/part_0 */
	case '1':
		cmdopts = 0x1C;
		break;		/* download/erase_first/part_1 */
	case 'v':
		cmdopts = 0x0C;
		break;		/* download/erase_first/vpd */
	default:
		return -EINVAL;
	}

	buf = (u8 __user *)load->data_addr;
	xbuf = __genwqe_alloc_consistent(cd, FLASH_BLOCK, &dma_addr);
	if (xbuf == NULL)
		return -ENOMEM;

	blocks_to_flash = load->size / FLASH_BLOCK;
	while (load->size) {
		struct genwqe_ddcb_cmd *req;

		/*
		 * We must be 4 byte aligned. Buffer must be 0 appened
		 * to have defined values when calculating CRC.
		 */
		tocopy = min_t(size_t, load->size, FLASH_BLOCK);

		rc = copy_from_user(xbuf, buf, tocopy);
		if (rc) {
			rc = -EFAULT;
			goto free_buffer;
		}
		crc = genwqe_crc32(xbuf, tocopy, 0xffffffff);

		dev_dbg(&pci_dev->dev,
			"[%s] DMA: %lx CRC: %08x SZ: %ld %d\n",
			__func__, (unsigned long)dma_addr, crc, tocopy,
			blocks_to_flash);

		/* prepare DDCB for SLU process */
		req = ddcb_requ_alloc();
		if (req == NULL) {
			rc = -ENOMEM;
			goto free_buffer;
		}

		req->cmd = SLCMD_MOVE_FLASH;
		req->cmdopts = cmdopts;

		/* prepare invariant values */
		if (genwqe_get_slu_id(cd) <= 0x2) {
			*(__be64 *)&req->__asiv[0]  = cpu_to_be64(dma_addr);
			*(__be64 *)&req->__asiv[8]  = cpu_to_be64(tocopy);
			*(__be64 *)&req->__asiv[16] = cpu_to_be64(flash);
			*(__be32 *)&req->__asiv[24] = cpu_to_be32(0);
			req->__asiv[24]	       = load->uid;
			*(__be32 *)&req->__asiv[28] = cpu_to_be32(crc);

			/* for simulation only */
			*(__be64 *)&req->__asiv[88] = cpu_to_be64(load->slu_id);
			*(__be64 *)&req->__asiv[96] = cpu_to_be64(load->app_id);
			req->asiv_length = 32; /* bytes included in crc calc */
		} else {	/* setup DDCB for ATS architecture */
			*(__be64 *)&req->asiv[0]  = cpu_to_be64(dma_addr);
			*(__be32 *)&req->asiv[8]  = cpu_to_be32(tocopy);
			*(__be32 *)&req->asiv[12] = cpu_to_be32(0); /* resvd */
			*(__be64 *)&req->asiv[16] = cpu_to_be64(flash);
			*(__be32 *)&req->asiv[24] = cpu_to_be32(load->uid<<24);
			*(__be32 *)&req->asiv[28] = cpu_to_be32(crc);

			/* for simulation only */
			*(__be64 *)&req->asiv[80] = cpu_to_be64(load->slu_id);
			*(__be64 *)&req->asiv[88] = cpu_to_be64(load->app_id);

			/* Rd only */
			req->ats = 0x4ULL << 44;
			req->asiv_length = 40; /* bytes included in crc calc */
		}
		req->asv_length  = 8;

		/* For Genwqe5 we get back the calculated CRC */
		*(u64 *)&req->asv[0] = 0ULL;			/* 0x80 */

		rc = __genwqe_execute_raw_ddcb(cd, req, filp->f_flags);

		load->retc = req->retc;
		load->attn = req->attn;
		load->progress = req->progress;

		if (rc < 0) {
			ddcb_requ_free(req);
			goto free_buffer;
		}

		if (req->retc != DDCB_RETC_COMPLETE) {
			rc = -EIO;
			ddcb_requ_free(req);
			goto free_buffer;
		}

		load->size  -= tocopy;
		flash += tocopy;
		buf += tocopy;
		blocks_to_flash--;
		ddcb_requ_free(req);
	}

 free_buffer:
	__genwqe_free_consistent(cd, FLASH_BLOCK, xbuf, dma_addr);
	return rc;
}

static int do_flash_read(struct genwqe_file *cfile,
			 struct genwqe_bitstream *load)
{
	int rc, blocks_to_flash;
	dma_addr_t dma_addr;
	u64 flash = 0;
	size_t tocopy = 0;
	u8 __user *buf;
	u8 *xbuf;
	u8 cmdopts;
	struct genwqe_dev *cd = cfile->cd;
	struct file *filp = cfile->filp;
	struct pci_dev *pci_dev = cd->pci_dev;
	struct genwqe_ddcb_cmd *cmd;

	if ((load->size & 0x3) != 0)
		return -EINVAL;

	if (((unsigned long)(load->data_addr) & ~PAGE_MASK) != 0)
		return -EINVAL;

	/* FIXME Bits have changed for new service layer! */
	switch ((char)load->partition) {
	case '0':
		cmdopts = 0x12;
		break;		/* upload/part_0 */
	case '1':
		cmdopts = 0x1A;
		break;		/* upload/part_1 */
	case 'v':
		cmdopts = 0x0A;
		break;		/* upload/vpd */
	default:
		return -EINVAL;
	}

	buf = (u8 __user *)load->data_addr;
	xbuf = __genwqe_alloc_consistent(cd, FLASH_BLOCK, &dma_addr);
	if (xbuf == NULL)
		return -ENOMEM;

	blocks_to_flash = load->size / FLASH_BLOCK;
	while (load->size) {
		/*
		 * We must be 4 byte aligned. Buffer must be 0 appened
		 * to have defined values when calculating CRC.
		 */
		tocopy = min_t(size_t, load->size, FLASH_BLOCK);

		dev_dbg(&pci_dev->dev,
			"[%s] DMA: %lx SZ: %ld %d\n",
			__func__, (unsigned long)dma_addr, tocopy,
			blocks_to_flash);

		/* prepare DDCB for SLU process */
		cmd = ddcb_requ_alloc();
		if (cmd == NULL) {
			rc = -ENOMEM;
			goto free_buffer;
		}
		cmd->cmd = SLCMD_MOVE_FLASH;
		cmd->cmdopts = cmdopts;

		/* prepare invariant values */
		if (genwqe_get_slu_id(cd) <= 0x2) {
			*(__be64 *)&cmd->__asiv[0]  = cpu_to_be64(dma_addr);
			*(__be64 *)&cmd->__asiv[8]  = cpu_to_be64(tocopy);
			*(__be64 *)&cmd->__asiv[16] = cpu_to_be64(flash);
			*(__be32 *)&cmd->__asiv[24] = cpu_to_be32(0);
			cmd->__asiv[24] = load->uid;
			*(__be32 *)&cmd->__asiv[28] = cpu_to_be32(0) /* CRC */;
			cmd->asiv_length = 32; /* bytes included in crc calc */
		} else {	/* setup DDCB for ATS architecture */
			*(__be64 *)&cmd->asiv[0]  = cpu_to_be64(dma_addr);
			*(__be32 *)&cmd->asiv[8]  = cpu_to_be32(tocopy);
			*(__be32 *)&cmd->asiv[12] = cpu_to_be32(0); /* resvd */
			*(__be64 *)&cmd->asiv[16] = cpu_to_be64(flash);
			*(__be32 *)&cmd->asiv[24] = cpu_to_be32(load->uid<<24);
			*(__be32 *)&cmd->asiv[28] = cpu_to_be32(0); /* CRC */

			/* rd/wr */
			cmd->ats = 0x5ULL << 44;
			cmd->asiv_length = 40; /* bytes included in crc calc */
		}
		cmd->asv_length  = 8;

		/* we only get back the calculated CRC */
		*(u64 *)&cmd->asv[0] = 0ULL;	/* 0x80 */

		rc = __genwqe_execute_raw_ddcb(cd, cmd, filp->f_flags);

		load->retc = cmd->retc;
		load->attn = cmd->attn;
		load->progress = cmd->progress;

		if ((rc < 0) && (rc != -EBADMSG)) {
			ddcb_requ_free(cmd);
			goto free_buffer;
		}

		rc = copy_to_user(buf, xbuf, tocopy);
		if (rc) {
			rc = -EFAULT;
			ddcb_requ_free(cmd);
			goto free_buffer;
		}

		/* We know that we can get retc 0x104 with CRC err */
		if (((cmd->retc == DDCB_RETC_FAULT) &&
		     (cmd->attn != 0x02)) ||  /* Normally ignore CRC error */
		    ((cmd->retc == DDCB_RETC_COMPLETE) &&
		     (cmd->attn != 0x00))) {  /* Everything was fine */
			rc = -EIO;
			ddcb_requ_free(cmd);
			goto free_buffer;
		}

		load->size  -= tocopy;
		flash += tocopy;
		buf += tocopy;
		blocks_to_flash--;
		ddcb_requ_free(cmd);
	}
	rc = 0;

 free_buffer:
	__genwqe_free_consistent(cd, FLASH_BLOCK, xbuf, dma_addr);
	return rc;
}

static int genwqe_pin_mem(struct genwqe_file *cfile, struct genwqe_mem *m)
{
	int rc;
	struct genwqe_dev *cd = cfile->cd;
	struct pci_dev *pci_dev = cfile->cd->pci_dev;
	struct dma_mapping *dma_map;
	unsigned long map_addr;
	unsigned long map_size;

	if ((m->addr == 0x0) || (m->size == 0))
		return -EINVAL;
	if (m->size > ULONG_MAX - PAGE_SIZE - (m->addr & ~PAGE_MASK))
		return -EINVAL;

	map_addr = (m->addr & PAGE_MASK);
	map_size = round_up(m->size + (m->addr & ~PAGE_MASK), PAGE_SIZE);

	dma_map = kzalloc(sizeof(struct dma_mapping), GFP_KERNEL);
	if (dma_map == NULL)
		return -ENOMEM;

	genwqe_mapping_init(dma_map, GENWQE_MAPPING_SGL_PINNED);
	rc = genwqe_user_vmap(cd, dma_map, (void *)map_addr, map_size);
	if (rc != 0) {
		dev_err(&pci_dev->dev,
			"[%s] genwqe_user_vmap rc=%d\n", __func__, rc);
		kfree(dma_map);
		return rc;
	}

	genwqe_add_pin(cfile, dma_map);
	return 0;
}

static int genwqe_unpin_mem(struct genwqe_file *cfile, struct genwqe_mem *m)
{
	struct genwqe_dev *cd = cfile->cd;
	struct dma_mapping *dma_map;
	unsigned long map_addr;
	unsigned long map_size;

	if (m->addr == 0x0)
		return -EINVAL;

	map_addr = (m->addr & PAGE_MASK);
	map_size = round_up(m->size + (m->addr & ~PAGE_MASK), PAGE_SIZE);

	dma_map = genwqe_search_pin(cfile, map_addr, map_size, NULL);
	if (dma_map == NULL)
		return -ENOENT;

	genwqe_del_pin(cfile, dma_map);
	genwqe_user_vunmap(cd, dma_map);
	kfree(dma_map);
	return 0;
}

/**
 * ddcb_cmd_cleanup() - Remove dynamically created fixup entries
 *
 * Only if there are any. Pinnings are not removed.
 */
static int ddcb_cmd_cleanup(struct genwqe_file *cfile, struct ddcb_requ *req)
{
	unsigned int i;
	struct dma_mapping *dma_map;
	struct genwqe_dev *cd = cfile->cd;

	for (i = 0; i < DDCB_FIXUPS; i++) {
		dma_map = &req->dma_mappings[i];

		if (dma_mapping_used(dma_map)) {
			__genwqe_del_mapping(cfile, dma_map);
			genwqe_user_vunmap(cd, dma_map);
		}
		if (req->sgls[i].sgl != NULL)
			genwqe_free_sync_sgl(cd, &req->sgls[i]);
	}
	return 0;
}

/**
 * ddcb_cmd_fixups() - Establish DMA fixups/sglists for user memory references
 *
 * Before the DDCB gets executed we need to handle the fixups. We
 * replace the user-space addresses with DMA addresses or do
 * additional setup work e.g. generating a scatter-gather list which
 * is used to describe the memory referred to in the fixup.
 */
static int ddcb_cmd_fixups(struct genwqe_file *cfile, struct ddcb_requ *req)
{
	int rc;
	unsigned int asiv_offs, i;
	struct genwqe_dev *cd = cfile->cd;
	struct genwqe_ddcb_cmd *cmd = &req->cmd;
	struct dma_mapping *m;

	for (i = 0, asiv_offs = 0x00; asiv_offs <= 0x58;
	     i++, asiv_offs += 0x08) {

		u64 u_addr;
		dma_addr_t d_addr;
		u32 u_size = 0;
		u64 ats_flags;

		ats_flags = ATS_GET_FLAGS(cmd->ats, asiv_offs);

		switch (ats_flags) {

		case ATS_TYPE_DATA:
			break;	/* nothing to do here */

		case ATS_TYPE_FLAT_RDWR:
		case ATS_TYPE_FLAT_RD: {
			u_addr = be64_to_cpu(*((__be64 *)&cmd->
					       asiv[asiv_offs]));
			u_size = be32_to_cpu(*((__be32 *)&cmd->
					       asiv[asiv_offs + 0x08]));

			/*
			 * No data available. Ignore u_addr in this
			 * case and set addr to 0. Hardware must not
			 * fetch the buffer.
			 */
			if (u_size == 0x0) {
				*((__be64 *)&cmd->asiv[asiv_offs]) =
					cpu_to_be64(0x0);
				break;
			}

			m = __genwqe_search_mapping(cfile, u_addr, u_size,
						   &d_addr, NULL);
			if (m == NULL) {
				rc = -EFAULT;
				goto err_out;
			}

			*((__be64 *)&cmd->asiv[asiv_offs]) =
				cpu_to_be64(d_addr);
			break;
		}

		case ATS_TYPE_SGL_RDWR:
		case ATS_TYPE_SGL_RD: {
			int page_offs;

			u_addr = be64_to_cpu(*((__be64 *)
					       &cmd->asiv[asiv_offs]));
			u_size = be32_to_cpu(*((__be32 *)
					       &cmd->asiv[asiv_offs + 0x08]));

			/*
			 * No data available. Ignore u_addr in this
			 * case and set addr to 0. Hardware must not
			 * fetch the empty sgl.
			 */
			if (u_size == 0x0) {
				*((__be64 *)&cmd->asiv[asiv_offs]) =
					cpu_to_be64(0x0);
				break;
			}

			m = genwqe_search_pin(cfile, u_addr, u_size, NULL);
			if (m != NULL) {
				page_offs = (u_addr -
					     (u64)m->u_vaddr)/PAGE_SIZE;
			} else {
				m = &req->dma_mappings[i];

				genwqe_mapping_init(m,
						    GENWQE_MAPPING_SGL_TEMP);

				if (ats_flags == ATS_TYPE_SGL_RD)
					m->write = 0;

				rc = genwqe_user_vmap(cd, m, (void *)u_addr,
						      u_size);
				if (rc != 0)
					goto err_out;

				__genwqe_add_mapping(cfile, m);
				page_offs = 0;
			}

			/* create genwqe style scatter gather list */
			rc = genwqe_alloc_sync_sgl(cd, &req->sgls[i],
						   (void __user *)u_addr,
						   u_size, m->write);
			if (rc != 0)
				goto err_out;

			genwqe_setup_sgl(cd, &req->sgls[i],
					 &m->dma_list[page_offs]);

			*((__be64 *)&cmd->asiv[asiv_offs]) =
				cpu_to_be64(req->sgls[i].sgl_dma_addr);

			break;
		}
		default:
			rc = -EINVAL;
			goto err_out;
		}
	}
	return 0;

 err_out:
	ddcb_cmd_cleanup(cfile, req);
	return rc;
}

/**
 * genwqe_execute_ddcb() - Execute DDCB using userspace address fixups
 *
 * The code will build up the translation tables or lookup the
 * contignous memory allocation table to find the right translations
 * and DMA addresses.
 */
static int genwqe_execute_ddcb(struct genwqe_file *cfile,
			       struct genwqe_ddcb_cmd *cmd)
{
	int rc;
	struct genwqe_dev *cd = cfile->cd;
	struct file *filp = cfile->filp;
	struct ddcb_requ *req = container_of(cmd, struct ddcb_requ, cmd);

	rc = ddcb_cmd_fixups(cfile, req);
	if (rc != 0)
		return rc;

	rc = __genwqe_execute_raw_ddcb(cd, cmd, filp->f_flags);
	ddcb_cmd_cleanup(cfile, req);
	return rc;
}

static int do_execute_ddcb(struct genwqe_file *cfile,
			   unsigned long arg, int raw)
{
	int rc;
	struct genwqe_ddcb_cmd *cmd;
	struct genwqe_dev *cd = cfile->cd;
	struct file *filp = cfile->filp;

	cmd = ddcb_requ_alloc();
	if (cmd == NULL)
		return -ENOMEM;

	if (copy_from_user(cmd, (void __user *)arg, sizeof(*cmd))) {
		ddcb_requ_free(cmd);
		return -EFAULT;
	}

	if (!raw)
		rc = genwqe_execute_ddcb(cfile, cmd);
	else
		rc = __genwqe_execute_raw_ddcb(cd, cmd, filp->f_flags);

	/* Copy back only the modifed fields. Do not copy ASIV
	   back since the copy got modified by the driver. */
	if (copy_to_user((void __user *)arg, cmd,
			 sizeof(*cmd) - DDCB_ASIV_LENGTH)) {
		ddcb_requ_free(cmd);
		return -EFAULT;
	}

	ddcb_requ_free(cmd);
	return rc;
}

/**
 * genwqe_ioctl() - IO control
 * @filp:       file handle
 * @cmd:        command identifier (passed from user)
 * @arg:        argument (passed from user)
 *
 * Return: 0 success
 */
static long genwqe_ioctl(struct file *filp, unsigned int cmd,
			 unsigned long arg)
{
	int rc = 0;
	struct genwqe_file *cfile = (struct genwqe_file *)filp->private_data;
	struct genwqe_dev *cd = cfile->cd;
	struct pci_dev *pci_dev = cd->pci_dev;
	struct genwqe_reg_io __user *io;
	u64 val;
	u32 reg_offs;

	/* Return -EIO if card hit EEH */
	if (pci_channel_offline(pci_dev))
		return -EIO;

	if (_IOC_TYPE(cmd) != GENWQE_IOC_CODE)
		return -EINVAL;

	switch (cmd) {

	case GENWQE_GET_CARD_STATE:
		put_user(cd->card_state, (enum genwqe_card_state __user *)arg);
		return 0;

		/* Register access */
	case GENWQE_READ_REG64: {
		io = (struct genwqe_reg_io __user *)arg;

		if (get_user(reg_offs, &io->num))
			return -EFAULT;

		if ((reg_offs >= cd->mmio_len) || (reg_offs & 0x7))
			return -EINVAL;

		val = __genwqe_readq(cd, reg_offs);
		put_user(val, &io->val64);
		return 0;
	}

	case GENWQE_WRITE_REG64: {
		io = (struct genwqe_reg_io __user *)arg;

		if (!capable(CAP_SYS_ADMIN))
			return -EPERM;

		if ((filp->f_flags & O_ACCMODE) == O_RDONLY)
			return -EPERM;

		if (get_user(reg_offs, &io->num))
			return -EFAULT;

		if ((reg_offs >= cd->mmio_len) || (reg_offs & 0x7))
			return -EINVAL;

		if (get_user(val, &io->val64))
			return -EFAULT;

		__genwqe_writeq(cd, reg_offs, val);
		return 0;
	}

	case GENWQE_READ_REG32: {
		io = (struct genwqe_reg_io __user *)arg;

		if (get_user(reg_offs, &io->num))
			return -EFAULT;

		if ((reg_offs >= cd->mmio_len) || (reg_offs & 0x3))
			return -EINVAL;

		val = __genwqe_readl(cd, reg_offs);
		put_user(val, &io->val64);
		return 0;
	}

	case GENWQE_WRITE_REG32: {
		io = (struct genwqe_reg_io __user *)arg;

		if (!capable(CAP_SYS_ADMIN))
			return -EPERM;

		if ((filp->f_flags & O_ACCMODE) == O_RDONLY)
			return -EPERM;

		if (get_user(reg_offs, &io->num))
			return -EFAULT;

		if ((reg_offs >= cd->mmio_len) || (reg_offs & 0x3))
			return -EINVAL;

		if (get_user(val, &io->val64))
			return -EFAULT;

		__genwqe_writel(cd, reg_offs, val);
		return 0;
	}

		/* Flash update/reading */
	case GENWQE_SLU_UPDATE: {
		struct genwqe_bitstream load;

		if (!genwqe_is_privileged(cd))
			return -EPERM;

		if ((filp->f_flags & O_ACCMODE) == O_RDONLY)
			return -EPERM;

		if (copy_from_user(&load, (void __user *)arg,
				   sizeof(load)))
			return -EFAULT;

		rc = do_flash_update(cfile, &load);

		if (copy_to_user((void __user *)arg, &load, sizeof(load)))
			return -EFAULT;

		return rc;
	}

	case GENWQE_SLU_READ: {
		struct genwqe_bitstream load;

		if (!genwqe_is_privileged(cd))
			return -EPERM;

		if (genwqe_flash_readback_fails(cd))
			return -ENOSPC;	 /* known to fail for old versions */

		if (copy_from_user(&load, (void __user *)arg, sizeof(load)))
			return -EFAULT;

		rc = do_flash_read(cfile, &load);

		if (copy_to_user((void __user *)arg, &load, sizeof(load)))
			return -EFAULT;

		return rc;
	}

		/* memory pinning and unpinning */
	case GENWQE_PIN_MEM: {
		struct genwqe_mem m;

		if (copy_from_user(&m, (void __user *)arg, sizeof(m)))
			return -EFAULT;

		return genwqe_pin_mem(cfile, &m);
	}

	case GENWQE_UNPIN_MEM: {
		struct genwqe_mem m;

		if (copy_from_user(&m, (void __user *)arg, sizeof(m)))
			return -EFAULT;

		return genwqe_unpin_mem(cfile, &m);
	}

		/* launch an DDCB and wait for completion */
	case GENWQE_EXECUTE_DDCB:
		return do_execute_ddcb(cfile, arg, 0);

	case GENWQE_EXECUTE_RAW_DDCB: {

		if (!capable(CAP_SYS_ADMIN))
			return -EPERM;

		return do_execute_ddcb(cfile, arg, 1);
	}

	default:
		return -EINVAL;
	}

	return rc;
}

static const struct file_operations genwqe_fops = {
	.owner		= THIS_MODULE,
	.open		= genwqe_open,
	.fasync		= genwqe_fasync,
	.mmap		= genwqe_mmap,
	.unlocked_ioctl	= genwqe_ioctl,
	.compat_ioctl   = compat_ptr_ioctl,
	.release	= genwqe_release,
};

static int genwqe_device_initialized(struct genwqe_dev *cd)
{
	return cd->dev != NULL;
}

/**
 * genwqe_device_create() - Create and configure genwqe char device
 * @cd:      genwqe device descriptor
 *
 * This function must be called before we create any more genwqe
 * character devices, because it is allocating the major and minor
 * number which are supposed to be used by the client drivers.
 */
int genwqe_device_create(struct genwqe_dev *cd)
{
	int rc;
	struct pci_dev *pci_dev = cd->pci_dev;

	/*
	 * Here starts the individual setup per client. It must
	 * initialize its own cdev data structure with its own fops.
	 * The appropriate devnum needs to be created. The ranges must
	 * not overlap.
	 */
	rc = alloc_chrdev_region(&cd->devnum_genwqe, 0,
				 GENWQE_MAX_MINOR, GENWQE_DEVNAME);
	if (rc < 0) {
		dev_err(&pci_dev->dev, "err: alloc_chrdev_region failed\n");
		goto err_dev;
	}

	cdev_init(&cd->cdev_genwqe, &genwqe_fops);
	cd->cdev_genwqe.owner = THIS_MODULE;

	rc = cdev_add(&cd->cdev_genwqe, cd->devnum_genwqe, 1);
	if (rc < 0) {
		dev_err(&pci_dev->dev, "err: cdev_add failed\n");
		goto err_add;
	}

	/*
	 * Finally the device in /dev/... must be created. The rule is
	 * to use card%d_clientname for each created device.
	 */
	cd->dev = device_create_with_groups(cd->class_genwqe,
					    &cd->pci_dev->dev,
					    cd->devnum_genwqe, cd,
					    genwqe_attribute_groups,
					    GENWQE_DEVNAME "%u_card",
					    cd->card_idx);
	if (IS_ERR(cd->dev)) {
		rc = PTR_ERR(cd->dev);
		goto err_cdev;
	}

	genwqe_init_debugfs(cd);

	return 0;

 err_cdev:
	cdev_del(&cd->cdev_genwqe);
 err_add:
	unregister_chrdev_region(cd->devnum_genwqe, GENWQE_MAX_MINOR);
 err_dev:
	cd->dev = NULL;
	return rc;
}

static int genwqe_inform_and_stop_processes(struct genwqe_dev *cd)
{
	int rc;
	unsigned int i;
	struct pci_dev *pci_dev = cd->pci_dev;

	if (!genwqe_open_files(cd))
		return 0;

	dev_warn(&pci_dev->dev, "[%s] send SIGIO and wait ...\n", __func__);

	rc = genwqe_kill_fasync(cd, SIGIO);
	if (rc > 0) {
		/* give kill_timeout seconds to close file descriptors ... */
		for (i = 0; (i < GENWQE_KILL_TIMEOUT) &&
			     genwqe_open_files(cd); i++) {
			dev_info(&pci_dev->dev, "  %d sec ...", i);

			cond_resched();
			msleep(1000);
		}

		/* if no open files we can safely continue, else ... */
		if (!genwqe_open_files(cd))
			return 0;

		dev_warn(&pci_dev->dev,
			 "[%s] send SIGKILL and wait ...\n", __func__);

		rc = genwqe_terminate(cd);
		if (rc) {
			/* Give kill_timout more seconds to end processes */
			for (i = 0; (i < GENWQE_KILL_TIMEOUT) &&
				     genwqe_open_files(cd); i++) {
				dev_warn(&pci_dev->dev, "  %d sec ...", i);

				cond_resched();
				msleep(1000);
			}
		}
	}
	return 0;
}

/**
 * genwqe_device_remove() - Remove genwqe's char device
 *
 * This function must be called after the client devices are removed
 * because it will free the major/minor number range for the genwqe
 * drivers.
 *
 * This function must be robust enough to be called twice.
 */
int genwqe_device_remove(struct genwqe_dev *cd)
{
	int rc;
	struct pci_dev *pci_dev = cd->pci_dev;

	if (!genwqe_device_initialized(cd))
		return 1;

	genwqe_inform_and_stop_processes(cd);

	/*
	 * We currently do wait until all filedescriptors are
	 * closed. This leads to a problem when we abort the
	 * application which will decrease this reference from
	 * 1/unused to 0/illegal and not from 2/used 1/empty.
	 */
	rc = kref_read(&cd->cdev_genwqe.kobj.kref);
	if (rc != 1) {
		dev_err(&pci_dev->dev,
			"[%s] err: cdev_genwqe...refcount=%d\n", __func__, rc);
		panic("Fatal err: cannot free resources with pending references!");
	}

	genqwe_exit_debugfs(cd);
	device_destroy(cd->class_genwqe, cd->devnum_genwqe);
	cdev_del(&cd->cdev_genwqe);
	unregister_chrdev_region(cd->devnum_genwqe, GENWQE_MAX_MINOR);
	cd->dev = NULL;

	return 0;
}
