// 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
 * @virt_addr:	Virtual 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
 * @virt_addr:	Virtual 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
 * @cd: GenWQE device information
 * @sig: Signal to send out
 *
 * 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
 * @vma: VMA area to close
 *
 * 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
 * @filp:	File pointer (unused)
 * @vma:	VMA area to map
 *
 * 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;
}

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

/**
 * do_flash_update() - Excute flash update (write image or CVPD)
 * @cfile:	Descriptor of opened file
 * @load:      details about image load
 *
 * Return: 0 if successful
 */
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
 * @cfile:	Descriptor of opened file
 * @req:	DDCB work request
 *
 * 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
 * @cfile:	Descriptor of opened file
 * @req:	DDCB work request
 *
 * 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
 * @cfile:	Descriptor of opened file
 * @cmd:        Command identifier (passed from user)
 *
 * 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
 * @cd: GenWQE device information
 *
 * 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;
}
