// 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>
 */

/*
 * Device Driver Control Block (DDCB) queue support. Definition of
 * interrupt handlers for queue support as well as triggering the
 * health monitor code in case of problems. The current hardware uses
 * an MSI interrupt which is shared between error handling and
 * functional code.
 */

#include <linux/types.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/pci.h>
#include <linux/string.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/crc-itu-t.h>

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

/*
 * N: next DDCB, this is where the next DDCB will be put.
 * A: active DDCB, this is where the code will look for the next completion.
 * x: DDCB is enqueued, we are waiting for its completion.

 * Situation (1): Empty queue
 *  +---+---+---+---+---+---+---+---+
 *  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
 *  |   |   |   |   |   |   |   |   |
 *  +---+---+---+---+---+---+---+---+
 *           A/N
 *  enqueued_ddcbs = A - N = 2 - 2 = 0
 *
 * Situation (2): Wrapped, N > A
 *  +---+---+---+---+---+---+---+---+
 *  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
 *  |   |   | x | x |   |   |   |   |
 *  +---+---+---+---+---+---+---+---+
 *            A       N
 *  enqueued_ddcbs = N - A = 4 - 2 = 2
 *
 * Situation (3): Queue wrapped, A > N
 *  +---+---+---+---+---+---+---+---+
 *  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
 *  | x | x |   |   | x | x | x | x |
 *  +---+---+---+---+---+---+---+---+
 *            N       A
 *  enqueued_ddcbs = queue_max  - (A - N) = 8 - (4 - 2) = 6
 *
 * Situation (4a): Queue full N > A
 *  +---+---+---+---+---+---+---+---+
 *  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
 *  | x | x | x | x | x | x | x |   |
 *  +---+---+---+---+---+---+---+---+
 *    A                           N
 *
 *  enqueued_ddcbs = N - A = 7 - 0 = 7
 *
 * Situation (4a): Queue full A > N
 *  +---+---+---+---+---+---+---+---+
 *  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
 *  | x | x | x |   | x | x | x | x |
 *  +---+---+---+---+---+---+---+---+
 *                N   A
 *  enqueued_ddcbs = queue_max - (A - N) = 8 - (4 - 3) = 7
 */

static int queue_empty(struct ddcb_queue *queue)
{
	return queue->ddcb_next == queue->ddcb_act;
}

static int queue_enqueued_ddcbs(struct ddcb_queue *queue)
{
	if (queue->ddcb_next >= queue->ddcb_act)
		return queue->ddcb_next - queue->ddcb_act;

	return queue->ddcb_max - (queue->ddcb_act - queue->ddcb_next);
}

static int queue_free_ddcbs(struct ddcb_queue *queue)
{
	int free_ddcbs = queue->ddcb_max - queue_enqueued_ddcbs(queue) - 1;

	if (WARN_ON_ONCE(free_ddcbs < 0)) { /* must never ever happen! */
		return 0;
	}
	return free_ddcbs;
}

/*
 * Use of the PRIV field in the DDCB for queue debugging:
 *
 * (1) Trying to get rid of a DDCB which saw a timeout:
 *     pddcb->priv[6] = 0xcc;   # cleared
 *
 * (2) Append a DDCB via NEXT bit:
 *     pddcb->priv[7] = 0xaa;	# appended
 *
 * (3) DDCB needed tapping:
 *     pddcb->priv[7] = 0xbb;   # tapped
 *
 * (4) DDCB marked as correctly finished:
 *     pddcb->priv[6] = 0xff;	# finished
 */

static inline void ddcb_mark_tapped(struct ddcb *pddcb)
{
	pddcb->priv[7] = 0xbb;  /* tapped */
}

static inline void ddcb_mark_appended(struct ddcb *pddcb)
{
	pddcb->priv[7] = 0xaa;	/* appended */
}

static inline void ddcb_mark_cleared(struct ddcb *pddcb)
{
	pddcb->priv[6] = 0xcc; /* cleared */
}

static inline void ddcb_mark_finished(struct ddcb *pddcb)
{
	pddcb->priv[6] = 0xff;	/* finished */
}

static inline void ddcb_mark_unused(struct ddcb *pddcb)
{
	pddcb->priv_64 = cpu_to_be64(0); /* not tapped */
}

/**
 * genwqe_crc16() - Generate 16-bit crc as required for DDCBs
 * @buff:       pointer to data buffer
 * @len:        length of data for calculation
 * @init:       initial crc (0xffff at start)
 *
 * Polynomial = x^16 + x^12 + x^5 + 1   (0x1021)
 * Example: 4 bytes 0x01 0x02 0x03 0x04 with init = 0xffff
 *          should result in a crc16 of 0x89c3
 *
 * Return: crc16 checksum in big endian format !
 */
static inline u16 genwqe_crc16(const u8 *buff, size_t len, u16 init)
{
	return crc_itu_t(init, buff, len);
}

static void print_ddcb_info(struct genwqe_dev *cd, struct ddcb_queue *queue)
{
	int i;
	struct ddcb *pddcb;
	unsigned long flags;
	struct pci_dev *pci_dev = cd->pci_dev;

	spin_lock_irqsave(&cd->print_lock, flags);

	dev_info(&pci_dev->dev,
		 "DDCB list for card #%d (ddcb_act=%d / ddcb_next=%d):\n",
		 cd->card_idx, queue->ddcb_act, queue->ddcb_next);

	pddcb = queue->ddcb_vaddr;
	for (i = 0; i < queue->ddcb_max; i++) {
		dev_err(&pci_dev->dev,
			"  %c %-3d: RETC=%03x SEQ=%04x HSI=%02X SHI=%02x PRIV=%06llx CMD=%03x\n",
			i == queue->ddcb_act ? '>' : ' ',
			i,
			be16_to_cpu(pddcb->retc_16),
			be16_to_cpu(pddcb->seqnum_16),
			pddcb->hsi,
			pddcb->shi,
			be64_to_cpu(pddcb->priv_64),
			pddcb->cmd);
		pddcb++;
	}
	spin_unlock_irqrestore(&cd->print_lock, flags);
}

struct genwqe_ddcb_cmd *ddcb_requ_alloc(void)
{
	struct ddcb_requ *req;

	req = kzalloc(sizeof(*req), GFP_KERNEL);
	if (!req)
		return NULL;

	return &req->cmd;
}

void ddcb_requ_free(struct genwqe_ddcb_cmd *cmd)
{
	struct ddcb_requ *req = container_of(cmd, struct ddcb_requ, cmd);

	kfree(req);
}

static inline enum genwqe_requ_state ddcb_requ_get_state(struct ddcb_requ *req)
{
	return req->req_state;
}

static inline void ddcb_requ_set_state(struct ddcb_requ *req,
				       enum genwqe_requ_state new_state)
{
	req->req_state = new_state;
}

static inline int ddcb_requ_collect_debug_data(struct ddcb_requ *req)
{
	return req->cmd.ddata_addr != 0x0;
}

/**
 * ddcb_requ_finished() - Returns the hardware state of the associated DDCB
 * @cd:          pointer to genwqe device descriptor
 * @req:         DDCB work request
 *
 * Status of ddcb_requ mirrors this hardware state, but is copied in
 * the ddcb_requ on interrupt/polling function. The lowlevel code
 * should check the hardware state directly, the higher level code
 * should check the copy.
 *
 * This function will also return true if the state of the queue is
 * not GENWQE_CARD_USED. This enables us to purge all DDCBs in the
 * shutdown case.
 */
static int ddcb_requ_finished(struct genwqe_dev *cd, struct ddcb_requ *req)
{
	return (ddcb_requ_get_state(req) == GENWQE_REQU_FINISHED) ||
		(cd->card_state != GENWQE_CARD_USED);
}

#define RET_DDCB_APPENDED 1
#define RET_DDCB_TAPPED   2
/**
 * enqueue_ddcb() - Enqueue a DDCB
 * @cd:         pointer to genwqe device descriptor
 * @queue:	queue this operation should be done on
 * @pddcb:      pointer to ddcb structure
 * @ddcb_no:    pointer to ddcb number being tapped
 *
 * Start execution of DDCB by tapping or append to queue via NEXT
 * bit. This is done by an atomic 'compare and swap' instruction and
 * checking SHI and HSI of the previous DDCB.
 *
 * This function must only be called with ddcb_lock held.
 *
 * Return: 1 if new DDCB is appended to previous
 *         2 if DDCB queue is tapped via register/simulation
 */
static int enqueue_ddcb(struct genwqe_dev *cd, struct ddcb_queue *queue,
			struct ddcb *pddcb, int ddcb_no)
{
	unsigned int try;
	int prev_no;
	struct ddcb *prev_ddcb;
	__be32 old, new, icrc_hsi_shi;
	u64 num;

	/*
	 * For performance checks a Dispatch Timestamp can be put into
	 * DDCB It is supposed to use the SLU's free running counter,
	 * but this requires PCIe cycles.
	 */
	ddcb_mark_unused(pddcb);

	/* check previous DDCB if already fetched */
	prev_no = (ddcb_no == 0) ? queue->ddcb_max - 1 : ddcb_no - 1;
	prev_ddcb = &queue->ddcb_vaddr[prev_no];

	/*
	 * It might have happened that the HSI.FETCHED bit is
	 * set. Retry in this case. Therefore I expect maximum 2 times
	 * trying.
	 */
	ddcb_mark_appended(pddcb);
	for (try = 0; try < 2; try++) {
		old = prev_ddcb->icrc_hsi_shi_32; /* read SHI/HSI in BE32 */

		/* try to append via NEXT bit if prev DDCB is not completed */
		if ((old & DDCB_COMPLETED_BE32) != 0x00000000)
			break;

		new = (old | DDCB_NEXT_BE32);

		wmb();		/* need to ensure write ordering */
		icrc_hsi_shi = cmpxchg(&prev_ddcb->icrc_hsi_shi_32, old, new);

		if (icrc_hsi_shi == old)
			return RET_DDCB_APPENDED; /* appended to queue */
	}

	/* Queue must be re-started by updating QUEUE_OFFSET */
	ddcb_mark_tapped(pddcb);
	num = (u64)ddcb_no << 8;

	wmb();			/* need to ensure write ordering */
	__genwqe_writeq(cd, queue->IO_QUEUE_OFFSET, num); /* start queue */

	return RET_DDCB_TAPPED;
}

/**
 * copy_ddcb_results() - Copy output state from real DDCB to request
 * @req:        pointer to requested DDCB parameters
 * @ddcb_no:    pointer to ddcb number being tapped
 *
 * Copy DDCB ASV to request struct. There is no endian
 * conversion made, since data structure in ASV is still
 * unknown here.
 *
 * This is needed by:
 *   - genwqe_purge_ddcb()
 *   - genwqe_check_ddcb_queue()
 */
static void copy_ddcb_results(struct ddcb_requ *req, int ddcb_no)
{
	struct ddcb_queue *queue = req->queue;
	struct ddcb *pddcb = &queue->ddcb_vaddr[req->num];

	memcpy(&req->cmd.asv[0], &pddcb->asv[0], DDCB_ASV_LENGTH);

	/* copy status flags of the variant part */
	req->cmd.vcrc     = be16_to_cpu(pddcb->vcrc_16);
	req->cmd.deque_ts = be64_to_cpu(pddcb->deque_ts_64);
	req->cmd.cmplt_ts = be64_to_cpu(pddcb->cmplt_ts_64);

	req->cmd.attn     = be16_to_cpu(pddcb->attn_16);
	req->cmd.progress = be32_to_cpu(pddcb->progress_32);
	req->cmd.retc     = be16_to_cpu(pddcb->retc_16);

	if (ddcb_requ_collect_debug_data(req)) {
		int prev_no = (ddcb_no == 0) ?
			queue->ddcb_max - 1 : ddcb_no - 1;
		struct ddcb *prev_pddcb = &queue->ddcb_vaddr[prev_no];

		memcpy(&req->debug_data.ddcb_finished, pddcb,
		       sizeof(req->debug_data.ddcb_finished));
		memcpy(&req->debug_data.ddcb_prev, prev_pddcb,
		       sizeof(req->debug_data.ddcb_prev));
	}
}

/**
 * genwqe_check_ddcb_queue() - Checks DDCB queue for completed work requests.
 * @cd:         pointer to genwqe device descriptor
 * @queue:	queue to be checked
 *
 * Return: Number of DDCBs which were finished
 */
static int genwqe_check_ddcb_queue(struct genwqe_dev *cd,
				   struct ddcb_queue *queue)
{
	unsigned long flags;
	int ddcbs_finished = 0;
	struct pci_dev *pci_dev = cd->pci_dev;

	spin_lock_irqsave(&queue->ddcb_lock, flags);

	/* FIXME avoid soft locking CPU */
	while (!queue_empty(queue) && (ddcbs_finished < queue->ddcb_max)) {

		struct ddcb *pddcb;
		struct ddcb_requ *req;
		u16 vcrc, vcrc_16, retc_16;

		pddcb = &queue->ddcb_vaddr[queue->ddcb_act];

		if ((pddcb->icrc_hsi_shi_32 & DDCB_COMPLETED_BE32) ==
		    0x00000000)
			goto go_home; /* not completed, continue waiting */

		wmb();  /*  Add sync to decouple prev. read operations */

		/* Note: DDCB could be purged */
		req = queue->ddcb_req[queue->ddcb_act];
		if (req == NULL) {
			/* this occurs if DDCB is purged, not an error */
			/* Move active DDCB further; Nothing to do anymore. */
			goto pick_next_one;
		}

		/*
		 * HSI=0x44 (fetched and completed), but RETC is
		 * 0x101, or even worse 0x000.
		 *
		 * In case of seeing the queue in inconsistent state
		 * we read the errcnts and the queue status to provide
		 * a trigger for our PCIe analyzer stop capturing.
		 */
		retc_16 = be16_to_cpu(pddcb->retc_16);
		if ((pddcb->hsi == 0x44) && (retc_16 <= 0x101)) {
			u64 errcnts, status;
			u64 ddcb_offs = (u64)pddcb - (u64)queue->ddcb_vaddr;

			errcnts = __genwqe_readq(cd, queue->IO_QUEUE_ERRCNTS);
			status  = __genwqe_readq(cd, queue->IO_QUEUE_STATUS);

			dev_err(&pci_dev->dev,
				"[%s] SEQN=%04x HSI=%02x RETC=%03x Q_ERRCNTS=%016llx Q_STATUS=%016llx DDCB_DMA_ADDR=%016llx\n",
				__func__, be16_to_cpu(pddcb->seqnum_16),
				pddcb->hsi, retc_16, errcnts, status,
				queue->ddcb_daddr + ddcb_offs);
		}

		copy_ddcb_results(req, queue->ddcb_act);
		queue->ddcb_req[queue->ddcb_act] = NULL; /* take from queue */

		dev_dbg(&pci_dev->dev, "FINISHED DDCB#%d\n", req->num);
		genwqe_hexdump(pci_dev, pddcb, sizeof(*pddcb));

		ddcb_mark_finished(pddcb);

		/* calculate CRC_16 to see if VCRC is correct */
		vcrc = genwqe_crc16(pddcb->asv,
				   VCRC_LENGTH(req->cmd.asv_length),
				   0xffff);
		vcrc_16 = be16_to_cpu(pddcb->vcrc_16);
		if (vcrc != vcrc_16) {
			printk_ratelimited(KERN_ERR
				"%s %s: err: wrong VCRC pre=%02x vcrc_len=%d bytes vcrc_data=%04x is not vcrc_card=%04x\n",
				GENWQE_DEVNAME, dev_name(&pci_dev->dev),
				pddcb->pre, VCRC_LENGTH(req->cmd.asv_length),
				vcrc, vcrc_16);
		}

		ddcb_requ_set_state(req, GENWQE_REQU_FINISHED);
		queue->ddcbs_completed++;
		queue->ddcbs_in_flight--;

		/* wake up process waiting for this DDCB, and
                   processes on the busy queue */
		wake_up_interruptible(&queue->ddcb_waitqs[queue->ddcb_act]);
		wake_up_interruptible(&queue->busy_waitq);

pick_next_one:
		queue->ddcb_act = (queue->ddcb_act + 1) % queue->ddcb_max;
		ddcbs_finished++;
	}

 go_home:
	spin_unlock_irqrestore(&queue->ddcb_lock, flags);
	return ddcbs_finished;
}

/**
 * __genwqe_wait_ddcb(): Waits until DDCB is completed
 * @cd:         pointer to genwqe device descriptor
 * @req:        pointer to requsted DDCB parameters
 *
 * The Service Layer will update the RETC in DDCB when processing is
 * pending or done.
 *
 * Return: > 0 remaining jiffies, DDCB completed
 *           -ETIMEDOUT	when timeout
 *           -ERESTARTSYS when ^C
 *           -EINVAL when unknown error condition
 *
 * When an error is returned the called needs to ensure that
 * purge_ddcb() is being called to get the &req removed from the
 * queue.
 */
int __genwqe_wait_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req)
{
	int rc;
	unsigned int ddcb_no;
	struct ddcb_queue *queue;
	struct pci_dev *pci_dev = cd->pci_dev;

	if (req == NULL)
		return -EINVAL;

	queue = req->queue;
	if (queue == NULL)
		return -EINVAL;

	ddcb_no = req->num;
	if (ddcb_no >= queue->ddcb_max)
		return -EINVAL;

	rc = wait_event_interruptible_timeout(queue->ddcb_waitqs[ddcb_no],
				ddcb_requ_finished(cd, req),
				GENWQE_DDCB_SOFTWARE_TIMEOUT * HZ);

	/*
	 * We need to distinguish 3 cases here:
	 *   1. rc == 0              timeout occurred
	 *   2. rc == -ERESTARTSYS   signal received
	 *   3. rc > 0               remaining jiffies condition is true
	 */
	if (rc == 0) {
		struct ddcb_queue *queue = req->queue;
		struct ddcb *pddcb;

		/*
		 * Timeout may be caused by long task switching time.
		 * When timeout happens, check if the request has
		 * meanwhile completed.
		 */
		genwqe_check_ddcb_queue(cd, req->queue);
		if (ddcb_requ_finished(cd, req))
			return rc;

		dev_err(&pci_dev->dev,
			"[%s] err: DDCB#%d timeout rc=%d state=%d req @ %p\n",
			__func__, req->num, rc,	ddcb_requ_get_state(req),
			req);
		dev_err(&pci_dev->dev,
			"[%s]      IO_QUEUE_STATUS=0x%016llx\n", __func__,
			__genwqe_readq(cd, queue->IO_QUEUE_STATUS));

		pddcb = &queue->ddcb_vaddr[req->num];
		genwqe_hexdump(pci_dev, pddcb, sizeof(*pddcb));

		print_ddcb_info(cd, req->queue);
		return -ETIMEDOUT;

	} else if (rc == -ERESTARTSYS) {
		return rc;
		/*
		 * EINTR:       Stops the application
		 * ERESTARTSYS: Restartable systemcall; called again
		 */

	} else if (rc < 0) {
		dev_err(&pci_dev->dev,
			"[%s] err: DDCB#%d unknown result (rc=%d) %d!\n",
			__func__, req->num, rc, ddcb_requ_get_state(req));
		return -EINVAL;
	}

	/* Severe error occured. Driver is forced to stop operation */
	if (cd->card_state != GENWQE_CARD_USED) {
		dev_err(&pci_dev->dev,
			"[%s] err: DDCB#%d forced to stop (rc=%d)\n",
			__func__, req->num, rc);
		return -EIO;
	}
	return rc;
}

/**
 * get_next_ddcb() - Get next available DDCB
 * @cd:         pointer to genwqe device descriptor
 * @queue:      DDCB queue
 * @num:        internal DDCB number
 *
 * DDCB's content is completely cleared but presets for PRE and
 * SEQNUM. This function must only be called when ddcb_lock is held.
 *
 * Return: NULL if no empty DDCB available otherwise ptr to next DDCB.
 */
static struct ddcb *get_next_ddcb(struct genwqe_dev *cd,
				  struct ddcb_queue *queue,
				  int *num)
{
	u64 *pu64;
	struct ddcb *pddcb;

	if (queue_free_ddcbs(queue) == 0) /* queue is  full */
		return NULL;

	/* find new ddcb */
	pddcb = &queue->ddcb_vaddr[queue->ddcb_next];

	/* if it is not completed, we are not allowed to use it */
	/* barrier(); */
	if ((pddcb->icrc_hsi_shi_32 & DDCB_COMPLETED_BE32) == 0x00000000)
		return NULL;

	*num = queue->ddcb_next;	/* internal DDCB number */
	queue->ddcb_next = (queue->ddcb_next + 1) % queue->ddcb_max;

	/* clear important DDCB fields */
	pu64 = (u64 *)pddcb;
	pu64[0] = 0ULL;		/* offs 0x00 (ICRC,HSI,SHI,...) */
	pu64[1] = 0ULL;		/* offs 0x01 (ACFUNC,CMD...) */

	/* destroy previous results in ASV */
	pu64[0x80/8] = 0ULL;	/* offs 0x80 (ASV + 0) */
	pu64[0x88/8] = 0ULL;	/* offs 0x88 (ASV + 0x08) */
	pu64[0x90/8] = 0ULL;	/* offs 0x90 (ASV + 0x10) */
	pu64[0x98/8] = 0ULL;	/* offs 0x98 (ASV + 0x18) */
	pu64[0xd0/8] = 0ULL;	/* offs 0xd0 (RETC,ATTN...) */

	pddcb->pre = DDCB_PRESET_PRE; /* 128 */
	pddcb->seqnum_16 = cpu_to_be16(queue->ddcb_seq++);
	return pddcb;
}

/**
 * __genwqe_purge_ddcb() - Remove a DDCB from the workqueue
 * @cd:         genwqe device descriptor
 * @req:        DDCB request
 *
 * This will fail when the request was already FETCHED. In this case
 * we need to wait until it is finished. Else the DDCB can be
 * reused. This function also ensures that the request data structure
 * is removed from ddcb_req[].
 *
 * Do not forget to call this function when genwqe_wait_ddcb() fails,
 * such that the request gets really removed from ddcb_req[].
 *
 * Return: 0 success
 */
int __genwqe_purge_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req)
{
	struct ddcb *pddcb = NULL;
	unsigned int t;
	unsigned long flags;
	struct ddcb_queue *queue = req->queue;
	struct pci_dev *pci_dev = cd->pci_dev;
	u64 queue_status;
	__be32 icrc_hsi_shi = 0x0000;
	__be32 old, new;

	/* unsigned long flags; */
	if (GENWQE_DDCB_SOFTWARE_TIMEOUT <= 0) {
		dev_err(&pci_dev->dev,
			"[%s] err: software timeout is not set!\n", __func__);
		return -EFAULT;
	}

	pddcb = &queue->ddcb_vaddr[req->num];

	for (t = 0; t < GENWQE_DDCB_SOFTWARE_TIMEOUT * 10; t++) {

		spin_lock_irqsave(&queue->ddcb_lock, flags);

		/* Check if req was meanwhile finished */
		if (ddcb_requ_get_state(req) == GENWQE_REQU_FINISHED)
			goto go_home;

		/* try to set PURGE bit if FETCHED/COMPLETED are not set */
		old = pddcb->icrc_hsi_shi_32;	/* read SHI/HSI in BE32 */
		if ((old & DDCB_FETCHED_BE32) == 0x00000000) {

			new = (old | DDCB_PURGE_BE32);
			icrc_hsi_shi = cmpxchg(&pddcb->icrc_hsi_shi_32,
					       old, new);
			if (icrc_hsi_shi == old)
				goto finish_ddcb;
		}

		/* normal finish with HSI bit */
		barrier();
		icrc_hsi_shi = pddcb->icrc_hsi_shi_32;
		if (icrc_hsi_shi & DDCB_COMPLETED_BE32)
			goto finish_ddcb;

		spin_unlock_irqrestore(&queue->ddcb_lock, flags);

		/*
		 * Here the check_ddcb() function will most likely
		 * discover this DDCB to be finished some point in
		 * time. It will mark the req finished and free it up
		 * in the list.
		 */

		copy_ddcb_results(req, req->num); /* for the failing case */
		msleep(100); /* sleep for 1/10 second and try again */
		continue;

finish_ddcb:
		copy_ddcb_results(req, req->num);
		ddcb_requ_set_state(req, GENWQE_REQU_FINISHED);
		queue->ddcbs_in_flight--;
		queue->ddcb_req[req->num] = NULL; /* delete from array */
		ddcb_mark_cleared(pddcb);

		/* Move active DDCB further; Nothing to do here anymore. */

		/*
		 * We need to ensure that there is at least one free
		 * DDCB in the queue. To do that, we must update
		 * ddcb_act only if the COMPLETED bit is set for the
		 * DDCB we are working on else we treat that DDCB even
		 * if we PURGED it as occupied (hardware is supposed
		 * to set the COMPLETED bit yet!).
		 */
		icrc_hsi_shi = pddcb->icrc_hsi_shi_32;
		if ((icrc_hsi_shi & DDCB_COMPLETED_BE32) &&
		    (queue->ddcb_act == req->num)) {
			queue->ddcb_act = ((queue->ddcb_act + 1) %
					   queue->ddcb_max);
		}
go_home:
		spin_unlock_irqrestore(&queue->ddcb_lock, flags);
		return 0;
	}

	/*
	 * If the card is dead and the queue is forced to stop, we
	 * might see this in the queue status register.
	 */
	queue_status = __genwqe_readq(cd, queue->IO_QUEUE_STATUS);

	dev_dbg(&pci_dev->dev, "UN/FINISHED DDCB#%d\n", req->num);
	genwqe_hexdump(pci_dev, pddcb, sizeof(*pddcb));

	dev_err(&pci_dev->dev,
		"[%s] err: DDCB#%d not purged and not completed after %d seconds QSTAT=%016llx!!\n",
		__func__, req->num, GENWQE_DDCB_SOFTWARE_TIMEOUT,
		queue_status);

	print_ddcb_info(cd, req->queue);

	return -EFAULT;
}

int genwqe_init_debug_data(struct genwqe_dev *cd, struct genwqe_debug_data *d)
{
	int len;
	struct pci_dev *pci_dev = cd->pci_dev;

	if (d == NULL) {
		dev_err(&pci_dev->dev,
			"[%s] err: invalid memory for debug data!\n",
			__func__);
		return -EFAULT;
	}

	len  = sizeof(d->driver_version);
	snprintf(d->driver_version, len, "%s", DRV_VERSION);
	d->slu_unitcfg = cd->slu_unitcfg;
	d->app_unitcfg = cd->app_unitcfg;
	return 0;
}

/**
 * __genwqe_enqueue_ddcb() - Enqueue a DDCB
 * @cd:         pointer to genwqe device descriptor
 * @req:        pointer to DDCB execution request
 * @f_flags:    file mode: blocking, non-blocking
 *
 * Return: 0 if enqueuing succeeded
 *         -EIO if card is unusable/PCIe problems
 *         -EBUSY if enqueuing failed
 */
int __genwqe_enqueue_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req,
			  unsigned int f_flags)
{
	struct ddcb *pddcb;
	unsigned long flags;
	struct ddcb_queue *queue;
	struct pci_dev *pci_dev = cd->pci_dev;
	u16 icrc;

 retry:
	if (cd->card_state != GENWQE_CARD_USED) {
		printk_ratelimited(KERN_ERR
			"%s %s: [%s] Card is unusable/PCIe problem Req#%d\n",
			GENWQE_DEVNAME, dev_name(&pci_dev->dev),
			__func__, req->num);
		return -EIO;
	}

	queue = req->queue = &cd->queue;

	/* FIXME circumvention to improve performance when no irq is
	 * there.
	 */
	if (GENWQE_POLLING_ENABLED)
		genwqe_check_ddcb_queue(cd, queue);

	/*
	 * It must be ensured to process all DDCBs in successive
	 * order. Use a lock here in order to prevent nested DDCB
	 * enqueuing.
	 */
	spin_lock_irqsave(&queue->ddcb_lock, flags);

	pddcb = get_next_ddcb(cd, queue, &req->num);	/* get ptr and num */
	if (pddcb == NULL) {
		int rc;

		spin_unlock_irqrestore(&queue->ddcb_lock, flags);

		if (f_flags & O_NONBLOCK) {
			queue->return_on_busy++;
			return -EBUSY;
		}

		queue->wait_on_busy++;
		rc = wait_event_interruptible(queue->busy_waitq,
					      queue_free_ddcbs(queue) != 0);
		dev_dbg(&pci_dev->dev, "[%s] waiting for free DDCB: rc=%d\n",
			__func__, rc);
		if (rc == -ERESTARTSYS)
			return rc;  /* interrupted by a signal */

		goto retry;
	}

	if (queue->ddcb_req[req->num] != NULL) {
		spin_unlock_irqrestore(&queue->ddcb_lock, flags);

		dev_err(&pci_dev->dev,
			"[%s] picked DDCB %d with req=%p still in use!!\n",
			__func__, req->num, req);
		return -EFAULT;
	}
	ddcb_requ_set_state(req, GENWQE_REQU_ENQUEUED);
	queue->ddcb_req[req->num] = req;

	pddcb->cmdopts_16 = cpu_to_be16(req->cmd.cmdopts);
	pddcb->cmd = req->cmd.cmd;
	pddcb->acfunc = req->cmd.acfunc;	/* functional unit */

	/*
	 * We know that we can get retc 0x104 with CRC error, do not
	 * stop the queue in those cases for this command. XDIR = 1
	 * does not work for old SLU versions.
	 *
	 * Last bitstream with the old XDIR behavior had SLU_ID
	 * 0x34199.
	 */
	if ((cd->slu_unitcfg & 0xFFFF0ull) > 0x34199ull)
		pddcb->xdir = 0x1;
	else
		pddcb->xdir = 0x0;


	pddcb->psp = (((req->cmd.asiv_length / 8) << 4) |
		      ((req->cmd.asv_length  / 8)));
	pddcb->disp_ts_64 = cpu_to_be64(req->cmd.disp_ts);

	/*
	 * If copying the whole DDCB_ASIV_LENGTH is impacting
	 * performance we need to change it to
	 * req->cmd.asiv_length. But simulation benefits from some
	 * non-architectured bits behind the architectured content.
	 *
	 * How much data is copied depends on the availability of the
	 * ATS field, which was introduced late. If the ATS field is
	 * supported ASIV is 8 bytes shorter than it used to be. Since
	 * the ATS field is copied too, the code should do exactly
	 * what it did before, but I wanted to make copying of the ATS
	 * field very explicit.
	 */
	if (genwqe_get_slu_id(cd) <= 0x2) {
		memcpy(&pddcb->__asiv[0],	/* destination */
		       &req->cmd.__asiv[0],	/* source */
		       DDCB_ASIV_LENGTH);	/* req->cmd.asiv_length */
	} else {
		pddcb->n.ats_64 = cpu_to_be64(req->cmd.ats);
		memcpy(&pddcb->n.asiv[0],	/* destination */
			&req->cmd.asiv[0],	/* source */
			DDCB_ASIV_LENGTH_ATS);	/* req->cmd.asiv_length */
	}

	pddcb->icrc_hsi_shi_32 = cpu_to_be32(0x00000000); /* for crc */

	/*
	 * Calculate CRC_16 for corresponding range PSP(7:4). Include
	 * empty 4 bytes prior to the data.
	 */
	icrc = genwqe_crc16((const u8 *)pddcb,
			   ICRC_LENGTH(req->cmd.asiv_length), 0xffff);
	pddcb->icrc_hsi_shi_32 = cpu_to_be32((u32)icrc << 16);

	/* enable DDCB completion irq */
	if (!GENWQE_POLLING_ENABLED)
		pddcb->icrc_hsi_shi_32 |= DDCB_INTR_BE32;

	dev_dbg(&pci_dev->dev, "INPUT DDCB#%d\n", req->num);
	genwqe_hexdump(pci_dev, pddcb, sizeof(*pddcb));

	if (ddcb_requ_collect_debug_data(req)) {
		/* use the kernel copy of debug data. copying back to
		   user buffer happens later */

		genwqe_init_debug_data(cd, &req->debug_data);
		memcpy(&req->debug_data.ddcb_before, pddcb,
		       sizeof(req->debug_data.ddcb_before));
	}

	enqueue_ddcb(cd, queue, pddcb, req->num);
	queue->ddcbs_in_flight++;

	if (queue->ddcbs_in_flight > queue->ddcbs_max_in_flight)
		queue->ddcbs_max_in_flight = queue->ddcbs_in_flight;

	ddcb_requ_set_state(req, GENWQE_REQU_TAPPED);
	spin_unlock_irqrestore(&queue->ddcb_lock, flags);
	wake_up_interruptible(&cd->queue_waitq);

	return 0;
}

/**
 * __genwqe_execute_raw_ddcb() - Setup and execute DDCB
 * @cd:         pointer to genwqe device descriptor
 * @cmd:        user provided DDCB command
 * @f_flags:    file mode: blocking, non-blocking
 */
int __genwqe_execute_raw_ddcb(struct genwqe_dev *cd,
			      struct genwqe_ddcb_cmd *cmd,
			      unsigned int f_flags)
{
	int rc = 0;
	struct pci_dev *pci_dev = cd->pci_dev;
	struct ddcb_requ *req = container_of(cmd, struct ddcb_requ, cmd);

	if (cmd->asiv_length > DDCB_ASIV_LENGTH) {
		dev_err(&pci_dev->dev, "[%s] err: wrong asiv_length of %d\n",
			__func__, cmd->asiv_length);
		return -EINVAL;
	}
	if (cmd->asv_length > DDCB_ASV_LENGTH) {
		dev_err(&pci_dev->dev, "[%s] err: wrong asv_length of %d\n",
			__func__, cmd->asiv_length);
		return -EINVAL;
	}
	rc = __genwqe_enqueue_ddcb(cd, req, f_flags);
	if (rc != 0)
		return rc;

	rc = __genwqe_wait_ddcb(cd, req);
	if (rc < 0)		/* error or signal interrupt */
		goto err_exit;

	if (ddcb_requ_collect_debug_data(req)) {
		if (copy_to_user((struct genwqe_debug_data __user *)
				 (unsigned long)cmd->ddata_addr,
				 &req->debug_data,
				 sizeof(struct genwqe_debug_data)))
			return -EFAULT;
	}

	/*
	 * Higher values than 0x102 indicate completion with faults,
	 * lower values than 0x102 indicate processing faults. Note
	 * that DDCB might have been purged. E.g. Cntl+C.
	 */
	if (cmd->retc != DDCB_RETC_COMPLETE) {
		/* This might happen e.g. flash read, and needs to be
		   handled by the upper layer code. */
		rc = -EBADMSG;	/* not processed/error retc */
	}

	return rc;

 err_exit:
	__genwqe_purge_ddcb(cd, req);

	if (ddcb_requ_collect_debug_data(req)) {
		if (copy_to_user((struct genwqe_debug_data __user *)
				 (unsigned long)cmd->ddata_addr,
				 &req->debug_data,
				 sizeof(struct genwqe_debug_data)))
			return -EFAULT;
	}
	return rc;
}

/**
 * genwqe_next_ddcb_ready() - Figure out if the next DDCB is already finished
 * @cd:         pointer to genwqe device descriptor
 *
 * We use this as condition for our wait-queue code.
 */
static int genwqe_next_ddcb_ready(struct genwqe_dev *cd)
{
	unsigned long flags;
	struct ddcb *pddcb;
	struct ddcb_queue *queue = &cd->queue;

	spin_lock_irqsave(&queue->ddcb_lock, flags);

	if (queue_empty(queue)) { /* empty queue */
		spin_unlock_irqrestore(&queue->ddcb_lock, flags);
		return 0;
	}

	pddcb = &queue->ddcb_vaddr[queue->ddcb_act];
	if (pddcb->icrc_hsi_shi_32 & DDCB_COMPLETED_BE32) { /* ddcb ready */
		spin_unlock_irqrestore(&queue->ddcb_lock, flags);
		return 1;
	}

	spin_unlock_irqrestore(&queue->ddcb_lock, flags);
	return 0;
}

/**
 * genwqe_ddcbs_in_flight() - Check how many DDCBs are in flight
 * @cd:         pointer to genwqe device descriptor
 *
 * Keep track on the number of DDCBs which ware currently in the
 * queue. This is needed for statistics as well as condition if we want
 * to wait or better do polling in case of no interrupts available.
 */
int genwqe_ddcbs_in_flight(struct genwqe_dev *cd)
{
	unsigned long flags;
	int ddcbs_in_flight = 0;
	struct ddcb_queue *queue = &cd->queue;

	spin_lock_irqsave(&queue->ddcb_lock, flags);
	ddcbs_in_flight += queue->ddcbs_in_flight;
	spin_unlock_irqrestore(&queue->ddcb_lock, flags);

	return ddcbs_in_flight;
}

static int setup_ddcb_queue(struct genwqe_dev *cd, struct ddcb_queue *queue)
{
	int rc, i;
	struct ddcb *pddcb;
	u64 val64;
	unsigned int queue_size;
	struct pci_dev *pci_dev = cd->pci_dev;

	if (GENWQE_DDCB_MAX < 2)
		return -EINVAL;

	queue_size = roundup(GENWQE_DDCB_MAX * sizeof(struct ddcb), PAGE_SIZE);

	queue->ddcbs_in_flight = 0;  /* statistics */
	queue->ddcbs_max_in_flight = 0;
	queue->ddcbs_completed = 0;
	queue->return_on_busy = 0;
	queue->wait_on_busy = 0;

	queue->ddcb_seq	  = 0x100; /* start sequence number */
	queue->ddcb_max	  = GENWQE_DDCB_MAX;
	queue->ddcb_vaddr = __genwqe_alloc_consistent(cd, queue_size,
						&queue->ddcb_daddr);
	if (queue->ddcb_vaddr == NULL) {
		dev_err(&pci_dev->dev,
			"[%s] **err: could not allocate DDCB **\n", __func__);
		return -ENOMEM;
	}
	queue->ddcb_req = kcalloc(queue->ddcb_max, sizeof(struct ddcb_requ *),
				  GFP_KERNEL);
	if (!queue->ddcb_req) {
		rc = -ENOMEM;
		goto free_ddcbs;
	}

	queue->ddcb_waitqs = kcalloc(queue->ddcb_max,
				     sizeof(wait_queue_head_t),
				     GFP_KERNEL);
	if (!queue->ddcb_waitqs) {
		rc = -ENOMEM;
		goto free_requs;
	}

	for (i = 0; i < queue->ddcb_max; i++) {
		pddcb = &queue->ddcb_vaddr[i];		     /* DDCBs */
		pddcb->icrc_hsi_shi_32 = DDCB_COMPLETED_BE32;
		pddcb->retc_16 = cpu_to_be16(0xfff);

		queue->ddcb_req[i] = NULL;		     /* requests */
		init_waitqueue_head(&queue->ddcb_waitqs[i]); /* waitqueues */
	}

	queue->ddcb_act  = 0;
	queue->ddcb_next = 0;	/* queue is empty */

	spin_lock_init(&queue->ddcb_lock);
	init_waitqueue_head(&queue->busy_waitq);

	val64 = ((u64)(queue->ddcb_max - 1) <<  8); /* lastptr */
	__genwqe_writeq(cd, queue->IO_QUEUE_CONFIG,  0x07);  /* iCRC/vCRC */
	__genwqe_writeq(cd, queue->IO_QUEUE_SEGMENT, queue->ddcb_daddr);
	__genwqe_writeq(cd, queue->IO_QUEUE_INITSQN, queue->ddcb_seq);
	__genwqe_writeq(cd, queue->IO_QUEUE_WRAP,    val64);
	return 0;

 free_requs:
	kfree(queue->ddcb_req);
	queue->ddcb_req = NULL;
 free_ddcbs:
	__genwqe_free_consistent(cd, queue_size, queue->ddcb_vaddr,
				queue->ddcb_daddr);
	queue->ddcb_vaddr = NULL;
	queue->ddcb_daddr = 0ull;
	return rc;

}

static int ddcb_queue_initialized(struct ddcb_queue *queue)
{
	return queue->ddcb_vaddr != NULL;
}

static void free_ddcb_queue(struct genwqe_dev *cd, struct ddcb_queue *queue)
{
	unsigned int queue_size;

	queue_size = roundup(queue->ddcb_max * sizeof(struct ddcb), PAGE_SIZE);

	kfree(queue->ddcb_req);
	queue->ddcb_req = NULL;

	if (queue->ddcb_vaddr) {
		__genwqe_free_consistent(cd, queue_size, queue->ddcb_vaddr,
					queue->ddcb_daddr);
		queue->ddcb_vaddr = NULL;
		queue->ddcb_daddr = 0ull;
	}
}

static irqreturn_t genwqe_pf_isr(int irq, void *dev_id)
{
	u64 gfir;
	struct genwqe_dev *cd = (struct genwqe_dev *)dev_id;
	struct pci_dev *pci_dev = cd->pci_dev;

	/*
	 * In case of fatal FIR error the queue is stopped, such that
	 * we can safely check it without risking anything.
	 */
	cd->irqs_processed++;
	wake_up_interruptible(&cd->queue_waitq);

	/*
	 * Checking for errors before kicking the queue might be
	 * safer, but slower for the good-case ... See above.
	 */
	gfir = __genwqe_readq(cd, IO_SLC_CFGREG_GFIR);
	if (((gfir & GFIR_ERR_TRIGGER) != 0x0) &&
	    !pci_channel_offline(pci_dev)) {

		if (cd->use_platform_recovery) {
			/*
			 * Since we use raw accessors, EEH errors won't be
			 * detected by the platform until we do a non-raw
			 * MMIO or config space read
			 */
			readq(cd->mmio + IO_SLC_CFGREG_GFIR);

			/* Don't do anything if the PCI channel is frozen */
			if (pci_channel_offline(pci_dev))
				goto exit;
		}

		wake_up_interruptible(&cd->health_waitq);

		/*
		 * By default GFIRs causes recovery actions. This
		 * count is just for debug when recovery is masked.
		 */
		dev_err_ratelimited(&pci_dev->dev,
				    "[%s] GFIR=%016llx\n",
				    __func__, gfir);
	}

 exit:
	return IRQ_HANDLED;
}

static irqreturn_t genwqe_vf_isr(int irq, void *dev_id)
{
	struct genwqe_dev *cd = (struct genwqe_dev *)dev_id;

	cd->irqs_processed++;
	wake_up_interruptible(&cd->queue_waitq);

	return IRQ_HANDLED;
}

/**
 * genwqe_card_thread() - Work thread for the DDCB queue
 * @data:         pointer to genwqe device descriptor
 *
 * The idea is to check if there are DDCBs in processing. If there are
 * some finished DDCBs, we process them and wakeup the
 * requestors. Otherwise we give other processes time using
 * cond_resched().
 */
static int genwqe_card_thread(void *data)
{
	int should_stop = 0;
	struct genwqe_dev *cd = (struct genwqe_dev *)data;

	while (!kthread_should_stop()) {

		genwqe_check_ddcb_queue(cd, &cd->queue);

		if (GENWQE_POLLING_ENABLED) {
			wait_event_interruptible_timeout(
				cd->queue_waitq,
				genwqe_ddcbs_in_flight(cd) ||
				(should_stop = kthread_should_stop()), 1);
		} else {
			wait_event_interruptible_timeout(
				cd->queue_waitq,
				genwqe_next_ddcb_ready(cd) ||
				(should_stop = kthread_should_stop()), HZ);
		}
		if (should_stop)
			break;

		/*
		 * Avoid soft lockups on heavy loads; we do not want
		 * to disable our interrupts.
		 */
		cond_resched();
	}
	return 0;
}

/**
 * genwqe_setup_service_layer() - Setup DDCB queue
 * @cd:         pointer to genwqe device descriptor
 *
 * Allocate DDCBs. Configure Service Layer Controller (SLC).
 *
 * Return: 0 success
 */
int genwqe_setup_service_layer(struct genwqe_dev *cd)
{
	int rc;
	struct ddcb_queue *queue;
	struct pci_dev *pci_dev = cd->pci_dev;

	if (genwqe_is_privileged(cd)) {
		rc = genwqe_card_reset(cd);
		if (rc < 0) {
			dev_err(&pci_dev->dev,
				"[%s] err: reset failed.\n", __func__);
			return rc;
		}
		genwqe_read_softreset(cd);
	}

	queue = &cd->queue;
	queue->IO_QUEUE_CONFIG  = IO_SLC_QUEUE_CONFIG;
	queue->IO_QUEUE_STATUS  = IO_SLC_QUEUE_STATUS;
	queue->IO_QUEUE_SEGMENT = IO_SLC_QUEUE_SEGMENT;
	queue->IO_QUEUE_INITSQN = IO_SLC_QUEUE_INITSQN;
	queue->IO_QUEUE_OFFSET  = IO_SLC_QUEUE_OFFSET;
	queue->IO_QUEUE_WRAP    = IO_SLC_QUEUE_WRAP;
	queue->IO_QUEUE_WTIME   = IO_SLC_QUEUE_WTIME;
	queue->IO_QUEUE_ERRCNTS = IO_SLC_QUEUE_ERRCNTS;
	queue->IO_QUEUE_LRW     = IO_SLC_QUEUE_LRW;

	rc = setup_ddcb_queue(cd, queue);
	if (rc != 0) {
		rc = -ENODEV;
		goto err_out;
	}

	init_waitqueue_head(&cd->queue_waitq);
	cd->card_thread = kthread_run(genwqe_card_thread, cd,
				      GENWQE_DEVNAME "%d_thread",
				      cd->card_idx);
	if (IS_ERR(cd->card_thread)) {
		rc = PTR_ERR(cd->card_thread);
		cd->card_thread = NULL;
		goto stop_free_queue;
	}

	rc = genwqe_set_interrupt_capability(cd, GENWQE_MSI_IRQS);
	if (rc)
		goto stop_kthread;

	/*
	 * We must have all wait-queues initialized when we enable the
	 * interrupts. Otherwise we might crash if we get an early
	 * irq.
	 */
	init_waitqueue_head(&cd->health_waitq);

	if (genwqe_is_privileged(cd)) {
		rc = request_irq(pci_dev->irq, genwqe_pf_isr, IRQF_SHARED,
				 GENWQE_DEVNAME, cd);
	} else {
		rc = request_irq(pci_dev->irq, genwqe_vf_isr, IRQF_SHARED,
				 GENWQE_DEVNAME, cd);
	}
	if (rc < 0) {
		dev_err(&pci_dev->dev, "irq %d not free.\n", pci_dev->irq);
		goto stop_irq_cap;
	}

	cd->card_state = GENWQE_CARD_USED;
	return 0;

 stop_irq_cap:
	genwqe_reset_interrupt_capability(cd);
 stop_kthread:
	kthread_stop(cd->card_thread);
	cd->card_thread = NULL;
 stop_free_queue:
	free_ddcb_queue(cd, queue);
 err_out:
	return rc;
}

/**
 * queue_wake_up_all() - Handles fatal error case
 * @cd:         pointer to genwqe device descriptor
 *
 * The PCI device got unusable and we have to stop all pending
 * requests as fast as we can. The code after this must purge the
 * DDCBs in question and ensure that all mappings are freed.
 */
static int queue_wake_up_all(struct genwqe_dev *cd)
{
	unsigned int i;
	unsigned long flags;
	struct ddcb_queue *queue = &cd->queue;

	spin_lock_irqsave(&queue->ddcb_lock, flags);

	for (i = 0; i < queue->ddcb_max; i++)
		wake_up_interruptible(&queue->ddcb_waitqs[queue->ddcb_act]);

	wake_up_interruptible(&queue->busy_waitq);
	spin_unlock_irqrestore(&queue->ddcb_lock, flags);

	return 0;
}

/**
 * genwqe_finish_queue() - Remove any genwqe devices and user-interfaces
 * @cd:         pointer to genwqe device descriptor
 *
 * Relies on the pre-condition that there are no users of the card
 * device anymore e.g. with open file-descriptors.
 *
 * This function must be robust enough to be called twice.
 */
int genwqe_finish_queue(struct genwqe_dev *cd)
{
	int i, rc = 0, in_flight;
	int waitmax = GENWQE_DDCB_SOFTWARE_TIMEOUT;
	struct pci_dev *pci_dev = cd->pci_dev;
	struct ddcb_queue *queue = &cd->queue;

	if (!ddcb_queue_initialized(queue))
		return 0;

	/* Do not wipe out the error state. */
	if (cd->card_state == GENWQE_CARD_USED)
		cd->card_state = GENWQE_CARD_UNUSED;

	/* Wake up all requests in the DDCB queue such that they
	   should be removed nicely. */
	queue_wake_up_all(cd);

	/* We must wait to get rid of the DDCBs in flight */
	for (i = 0; i < waitmax; i++) {
		in_flight = genwqe_ddcbs_in_flight(cd);

		if (in_flight == 0)
			break;

		dev_dbg(&pci_dev->dev,
			"  DEBUG [%d/%d] waiting for queue to get empty: %d requests!\n",
			i, waitmax, in_flight);

		/*
		 * Severe severe error situation: The card itself has
		 * 16 DDCB queues, each queue has e.g. 32 entries,
		 * each DDBC has a hardware timeout of currently 250
		 * msec but the PFs have a hardware timeout of 8 sec
		 * ... so I take something large.
		 */
		msleep(1000);
	}
	if (i == waitmax) {
		dev_err(&pci_dev->dev, "  [%s] err: queue is not empty!!\n",
			__func__);
		rc = -EIO;
	}
	return rc;
}

/**
 * genwqe_release_service_layer() - Shutdown DDCB queue
 * @cd:       genwqe device descriptor
 *
 * This function must be robust enough to be called twice.
 */
int genwqe_release_service_layer(struct genwqe_dev *cd)
{
	struct pci_dev *pci_dev = cd->pci_dev;

	if (!ddcb_queue_initialized(&cd->queue))
		return 1;

	free_irq(pci_dev->irq, cd);
	genwqe_reset_interrupt_capability(cd);

	if (cd->card_thread != NULL) {
		kthread_stop(cd->card_thread);
		cd->card_thread = NULL;
	}

	free_ddcb_queue(cd, &cd->queue);
	return 0;
}
