/* ced_ioc.c
 ioctl part of the 1401 usb device driver for linux.
 Copyright (C) 2010 Cambridge Electronic Design Ltd
 Author Greg P Smith (greg@ced.co.uk)

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kref.h>
#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/mutex.h>
#include <linux/page-flags.h>
#include <linux/pagemap.h>
#include <linux/jiffies.h>

#include "usb1401.h"

/****************************************************************************
** FlushOutBuff
**
** Empties the Output buffer and sets int lines. Used from user level only
****************************************************************************/
void FlushOutBuff(DEVICE_EXTENSION * pdx)
{
	dev_dbg(&pdx->interface->dev, "%s currentState=%d", __func__,
		pdx->sCurrentState);
	if (pdx->sCurrentState == U14ERR_TIME)	/* Do nothing if hardware in trouble */
		return;
//    CharSend_Cancel(pdx);                   /* Kill off any pending I/O */
	spin_lock_irq(&pdx->charOutLock);
	pdx->dwNumOutput = 0;
	pdx->dwOutBuffGet = 0;
	pdx->dwOutBuffPut = 0;
	spin_unlock_irq(&pdx->charOutLock);
}

/****************************************************************************
**
** FlushInBuff
**
** Empties the input buffer and sets int lines
****************************************************************************/
void FlushInBuff(DEVICE_EXTENSION * pdx)
{
	dev_dbg(&pdx->interface->dev, "%s currentState=%d", __func__,
		pdx->sCurrentState);
	if (pdx->sCurrentState == U14ERR_TIME)	/* Do nothing if hardware in trouble */
		return;
//    CharRead_Cancel(pDevObject);            /* Kill off any pending I/O */
	spin_lock_irq(&pdx->charInLock);
	pdx->dwNumInput = 0;
	pdx->dwInBuffGet = 0;
	pdx->dwInBuffPut = 0;
	spin_unlock_irq(&pdx->charInLock);
}

/****************************************************************************
** PutChars
**
** Utility routine to copy chars into the output buffer and fire them off.
** called from user mode, holds charOutLock.
****************************************************************************/
static int PutChars(DEVICE_EXTENSION * pdx, const char *pCh,
		    unsigned int uCount)
{
	int iReturn;
	spin_lock_irq(&pdx->charOutLock);	// get the output spin lock
	if ((OUTBUF_SZ - pdx->dwNumOutput) >= uCount) {
		unsigned int u;
		for (u = 0; u < uCount; u++) {
			pdx->outputBuffer[pdx->dwOutBuffPut++] = pCh[u];
			if (pdx->dwOutBuffPut >= OUTBUF_SZ)
				pdx->dwOutBuffPut = 0;
		}
		pdx->dwNumOutput += uCount;
		spin_unlock_irq(&pdx->charOutLock);
		iReturn = SendChars(pdx);	// ...give a chance to transmit data
	} else {
		iReturn = U14ERR_NOOUT;	// no room at the out (ha-ha)
		spin_unlock_irq(&pdx->charOutLock);
	}
	return iReturn;
}

/*****************************************************************************
** Add the data in pData (local pointer) of length n to the output buffer, and
** trigger an output transfer if this is appropriate. User mode.
** Holds the io_mutex
*****************************************************************************/
int SendString(DEVICE_EXTENSION * pdx, const char __user * pData,
	       unsigned int n)
{
	int iReturn = U14ERR_NOERROR;	// assume all will be well
	char buffer[OUTBUF_SZ + 1];	// space in our address space for characters
	if (n > OUTBUF_SZ)	// check space in local buffer...
		return U14ERR_NOOUT;	// ...too many characters
	if (copy_from_user(buffer, pData, n))
		return -EFAULT;
	buffer[n] = 0;		// terminate for debug purposes

	mutex_lock(&pdx->io_mutex);	// Protect disconnect from new i/o
	if (n > 0)		// do nothing if nowt to do!
	{
		dev_dbg(&pdx->interface->dev, "%s n=%d>%s<", __func__, n,
			buffer);
		iReturn = PutChars(pdx, buffer, n);
	}

	Allowi(pdx, false);	// make sure we have input int
	mutex_unlock(&pdx->io_mutex);

	return iReturn;
}

/****************************************************************************
** SendChar
**
** Sends a single character to the 1401. User mode, holds io_mutex.
****************************************************************************/
int SendChar(DEVICE_EXTENSION * pdx, char c)
{
	int iReturn;
	mutex_lock(&pdx->io_mutex);	// Protect disconnect from new i/o
	iReturn = PutChars(pdx, &c, 1);
	dev_dbg(&pdx->interface->dev, "SendChar >%c< (0x%02x)", c, c);
	Allowi(pdx, false);	// Make sure char reads are running
	mutex_unlock(&pdx->io_mutex);
	return iReturn;
}

/***************************************************************************
**
** Get1401State
**
**  Retrieves state information from the 1401, adjusts the 1401 state held
**  in the device extension to indicate the current 1401 type.
**
**  *state is updated with information about the 1401 state as returned by the
**         1401. The low byte is a code for what 1401 is doing:
**
**  0       normal 1401 operation
**  1       sending chars to host
**  2       sending block data to host
**  3       reading block data from host
**  4       sending an escape sequence to the host
**  0x80    1401 is executing self-test, in which case the upper word
**          is the last error code seen (or zero for no new error).
**
** *error is updated with error information if a self-test error code
**          is returned in the upper word of state.
**
**  both state and error are set to -1 if there are comms problems, and
**  to zero if there is a simple failure.
**
** return error code (U14ERR_NOERROR for OK)
*/
int Get1401State(DEVICE_EXTENSION * pdx, __u32 * state, __u32 * error)
{
	int nGot;
	dev_dbg(&pdx->interface->dev, "Get1401State() entry");

	*state = 0xFFFFFFFF;	// Start off with invalid state
	nGot = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0),
			       GET_STATUS, (D_TO_H | VENDOR | DEVREQ), 0, 0,
			       pdx->statBuf, sizeof(pdx->statBuf), HZ);
	if (nGot != sizeof(pdx->statBuf)) {
		dev_err(&pdx->interface->dev,
			"Get1401State() FAILED, return code %d", nGot);
		pdx->sCurrentState = U14ERR_TIME;	// Indicate that things are very wrong indeed
		*state = 0;	// Force status values to a known state
		*error = 0;
	} else {
		int nDevice;
		dev_dbg(&pdx->interface->dev,
			"Get1401State() Success, state: 0x%x, 0x%x",
			pdx->statBuf[0], pdx->statBuf[1]);

		*state = pdx->statBuf[0];	// Return the state values to the calling code
		*error = pdx->statBuf[1];

		nDevice = pdx->udev->descriptor.bcdDevice >> 8;	// 1401 type code value
		switch (nDevice)	// so we can clean up current state
		{
		case 0:
			pdx->sCurrentState = U14ERR_U1401;
			break;

		default:	// allow lots of device codes for future 1401s
			if ((nDevice >= 1) && (nDevice <= 23))
				pdx->sCurrentState = (short)(nDevice + 6);
			else
				pdx->sCurrentState = U14ERR_ILL;
			break;
		}
	}

	return pdx->sCurrentState >= 0 ? U14ERR_NOERROR : pdx->sCurrentState;
}

/****************************************************************************
** ReadWrite_Cancel
**
** Kills off staged read\write request from the USB if one is pending.
****************************************************************************/
int ReadWrite_Cancel(DEVICE_EXTENSION * pdx)
{
	dev_dbg(&pdx->interface->dev, "ReadWrite_Cancel entry %d",
		pdx->bStagedUrbPending);
#ifdef NOT_WRITTEN_YET
	int ntStatus = STATUS_SUCCESS;
	bool bResult = false;
	unsigned int i;
	// We can fill this in when we know how we will implement the staged transfer stuff
	spin_lock_irq(&pdx->stagedLock);

	if (pdx->bStagedUrbPending)	// anything to be cancelled? May need more...
	{
		dev_info(&pdx->interface - dev,
			 "ReadWrite_Cancel about to cancel Urb");

		//       KeClearEvent(&pdx->StagingDoneEvent);   // Clear the staging done flag
		USB_ASSERT(pdx->pStagedIrp != NULL);

		// Release the spinlock first otherwise the completion routine may hang
		//  on the spinlock while this function hands waiting for the event.
		spin_unlock_irq(&pdx->stagedLock);
		bResult = IoCancelIrp(pdx->pStagedIrp);	// Actually do the cancel
		if (bResult) {
			LARGE_INTEGER timeout;
			timeout.QuadPart = -10000000;	// Use a timeout of 1 second
			dev_info(&pdx->interface - dev,
				 "ReadWrite_Cancel about to wait till done");
			ntStatus =
			    KeWaitForSingleObject(&pdx->StagingDoneEvent,
						  Executive, KernelMode, FALSE,
						  &timeout);
		} else {
			dev_info(&pdx->interface - dev,
				 "ReadWrite_Cancel, cancellation failed");
			ntStatus = U14ERR_FAIL;
		}
		USB_KdPrint(DBGLVL_DEFAULT,
			    ("ReadWrite_Cancel ntStatus = 0x%x decimal %d\n",
			     ntStatus, ntStatus));
	} else
		spin_unlock_irq(&pdx->stagedLock);

	dev_info(&pdx->interface - dev, "ReadWrite_Cancel  done");
	return ntStatus;
#else
	return U14ERR_NOERROR;
#endif

}

/***************************************************************************
** InSelfTest - utility to check in self test. Return 1 for ST, 0 for not or
** a -ve error code if we failed for some reason.
***************************************************************************/
static int InSelfTest(DEVICE_EXTENSION * pdx, unsigned int *pState)
{
	unsigned int state, error;
	int iReturn = Get1401State(pdx, &state, &error);	// see if in self-test
	if (iReturn == U14ERR_NOERROR)	// if all still OK
		iReturn = (state == (unsigned int)-1) ||	// TX problem or...
		    ((state & 0xff) == 0x80);	// ...self test
	*pState = state;	// return actual state
	return iReturn;
}

/***************************************************************************
** Is1401 - ALWAYS CALLED HOLDING THE io_mutex
**
** Tests for the current state of the 1401. Sets sCurrentState:
**
**  U14ERR_NOIF  1401  i/f card not installed (not done here)
**  U14ERR_OFF   1401  apparently not switched on
**  U14ERR_NC    1401  appears to be not connected
**  U14ERR_ILL   1401  if it is there its not very well at all
**  U14ERR_TIME  1401  appears OK, but doesn't communicate - very bad
**  U14ERR_STD   1401  OK and ready for use
**  U14ERR_PLUS  1401+ OK and ready for use
**  U14ERR_U1401 Micro1401 OK and ready for use
**  U14ERR_POWER Power1401 OK and ready for use
**  U14ERR_U14012 Micro1401 mkII OK and ready for use
**
**  Returns TRUE if a 1401 detected and OK, else FALSE
****************************************************************************/
bool Is1401(DEVICE_EXTENSION * pdx)
{
	int iReturn;
	dev_dbg(&pdx->interface->dev, "%s", __func__);

	ced_draw_down(pdx);	// wait for, then kill outstanding Urbs
	FlushInBuff(pdx);	// Clear out input buffer & pipe
	FlushOutBuff(pdx);	// Clear output buffer & pipe

	// The next call returns 0 if OK, but has returned 1 in the past, meaning that
	// usb_unlock_device() is needed... now it always is
	iReturn = usb_lock_device_for_reset(pdx->udev, pdx->interface);

	// release the io_mutex because if we don't, we will deadlock due to system
	// calls back into the driver.
	mutex_unlock(&pdx->io_mutex);	// locked, so we will not get system calls
	if (iReturn >= 0)	// if we failed
	{
		iReturn = usb_reset_device(pdx->udev);	// try to do the reset
		usb_unlock_device(pdx->udev);	// undo the lock
	}

	mutex_lock(&pdx->io_mutex);	// hold stuff off while we wait
	pdx->dwDMAFlag = MODE_CHAR;	// Clear DMA mode flag regardless!
	if (iReturn == 0)	// if all is OK still
	{
		unsigned int state;
		iReturn = InSelfTest(pdx, &state);	// see if likely in self test
		if (iReturn > 0)	// do we need to wait for self-test?
		{
			unsigned long ulTimeOut = jiffies + 30 * HZ;	// when to give up
			while ((iReturn > 0) && time_before(jiffies, ulTimeOut)) {
				schedule();	// let other stuff run
				iReturn = InSelfTest(pdx, &state);	// see if done yet
			}
		}

		if (iReturn == 0)	// if all is OK...
			iReturn = state == 0;	// then success is that the state is 0
	} else
		iReturn = 0;	// we failed
	pdx->bForceReset = false;	// Clear forced reset flag now

	return iReturn > 0;
}

/****************************************************************************
** QuickCheck  - ALWAYS CALLED HOLDING THE io_mutex
** This is used to test for a 1401. It will try to do a quick check if all is
**  OK, that is the 1401 was OK the last time it was asked, and there is no DMA
**  in progress, and if the bTestBuff flag is set, the character buffers must be
**  empty too. If the quick check shows that the state is still the same, then
**  all is OK.
**
** If any of the above conditions are not met, or if the state or type of the
**  1401 has changed since the previous test, the full Is1401 test is done, but
**  only if bCanReset is also TRUE.
**
** The return value is TRUE if a useable 1401 is found, FALSE if not
*/
bool QuickCheck(DEVICE_EXTENSION * pdx, bool bTestBuff, bool bCanReset)
{
	bool bRet = false;	// assume it will fail and we will reset
	bool bShortTest;

	bShortTest = ((pdx->dwDMAFlag == MODE_CHAR) &&	// no DMA running
		      (!pdx->bForceReset) &&	// Not had a real reset forced
		      (pdx->sCurrentState >= U14ERR_STD));	// No 1401 errors stored

	dev_dbg(&pdx->interface->dev,
		"%s DMAFlag:%d, state:%d, force:%d, testBuff:%d, short:%d",
		__func__, pdx->dwDMAFlag, pdx->sCurrentState, pdx->bForceReset,
		bTestBuff, bShortTest);

	if ((bTestBuff) &&	// Buffer check requested, and...
	    (pdx->dwNumInput || pdx->dwNumOutput))	// ...characters were in the buffer?
	{
		bShortTest = false;	// Then do the full test
		dev_dbg(&pdx->interface->dev,
			"%s will reset as buffers not empty", __func__);
	}

	if (bShortTest || !bCanReset)	// Still OK to try the short test?
	{			// Always test if no reset - we want state update
		unsigned int state, error;
		dev_dbg(&pdx->interface->dev, "%s->Get1401State", __func__);
		if (Get1401State(pdx, &state, &error) == U14ERR_NOERROR)	// Check on the 1401 state
		{
			if ((state & 0xFF) == 0)	// If call worked, check the status value
				bRet = true;	// If that was zero, all is OK, no reset needed
		}
	}

	if (!bRet && bCanReset)	// If all not OK, then
	{
		dev_info(&pdx->interface->dev, "%s->Is1401 %d %d %d %d",
			 __func__, bShortTest, pdx->sCurrentState, bTestBuff,
			 pdx->bForceReset);
		bRet = Is1401(pdx);	//  do full test
	}

	return bRet;
}

/****************************************************************************
** Reset1401
**
** Resets the 1401 and empties the i/o buffers
*****************************************************************************/
int Reset1401(DEVICE_EXTENSION * pdx)
{
	mutex_lock(&pdx->io_mutex);	// Protect disconnect from new i/o
	dev_dbg(&pdx->interface->dev, "ABout to call QuickCheck");
	QuickCheck(pdx, true, true);	// Check 1401, reset if not OK
	mutex_unlock(&pdx->io_mutex);
	return U14ERR_NOERROR;
}

/****************************************************************************
** GetChar
**
** Gets a single character from the 1401
****************************************************************************/
int GetChar(DEVICE_EXTENSION * pdx)
{
	int iReturn = U14ERR_NOIN;	// assume we will get  nothing
	mutex_lock(&pdx->io_mutex);	// Protect disconnect from new i/o

	dev_dbg(&pdx->interface->dev, "GetChar");

	Allowi(pdx, false);	// Make sure char reads are running
	SendChars(pdx);		// and send any buffered chars

	spin_lock_irq(&pdx->charInLock);
	if (pdx->dwNumInput > 0)	// worth looking
	{
		iReturn = pdx->inputBuffer[pdx->dwInBuffGet++];
		if (pdx->dwInBuffGet >= INBUF_SZ)
			pdx->dwInBuffGet = 0;
		pdx->dwNumInput--;
	} else
		iReturn = U14ERR_NOIN;	// no input data to read
	spin_unlock_irq(&pdx->charInLock);

	Allowi(pdx, false);	// Make sure char reads are running

	mutex_unlock(&pdx->io_mutex);	// Protect disconnect from new i/o
	return iReturn;
}

/****************************************************************************
** GetString
**
** Gets a string from the 1401. Returns chars up to the next CR or when
** there are no more to read or nowhere to put them. CR is translated to
** 0 and counted as a character. If the string does not end in a 0, we will
** add one, if there is room, but it is not counted as a character.
**
** returns the count of characters (including the terminator, or 0 if none
** or a negative error code.
****************************************************************************/
int GetString(DEVICE_EXTENSION * pdx, char __user * pUser, int n)
{
	int nAvailable;		// character in the buffer
	int iReturn = U14ERR_NOIN;
	if (n <= 0)
		return -ENOMEM;

	mutex_lock(&pdx->io_mutex);	// Protect disconnect from new i/o
	Allowi(pdx, false);	// Make sure char reads are running
	SendChars(pdx);		// and send any buffered chars

	spin_lock_irq(&pdx->charInLock);
	nAvailable = pdx->dwNumInput;	// characters available now
	if (nAvailable > n)	// read max of space in pUser...
		nAvailable = n;	// ...or input characters

	if (nAvailable > 0)	// worth looking?
	{
		char buffer[INBUF_SZ + 1];	// space for a linear copy of data
		int nGot = 0;
		int nCopyToUser;	// number to copy to user
		char cData;
		do {
			cData = pdx->inputBuffer[pdx->dwInBuffGet++];
			if (cData == CR_CHAR)	// replace CR with zero
				cData = (char)0;

			if (pdx->dwInBuffGet >= INBUF_SZ)
				pdx->dwInBuffGet = 0;	// wrap buffer pointer

			buffer[nGot++] = cData;	// save the output
		}
		while ((nGot < nAvailable) && cData);

		nCopyToUser = nGot;	// what to copy...
		if (cData)	// do we need null
		{
			buffer[nGot] = (char)0;	// make it tidy
			if (nGot < n)	// if space in user buffer...
				++nCopyToUser;	// ...copy the 0 as well.
		}

		pdx->dwNumInput -= nGot;
		spin_unlock_irq(&pdx->charInLock);

		dev_dbg(&pdx->interface->dev,
			"GetString read %d characters >%s<", nGot, buffer);
		if (copy_to_user(pUser, buffer, nCopyToUser))
			iReturn = -EFAULT;
		else
			iReturn = nGot;		// report characters read
	} else
		spin_unlock_irq(&pdx->charInLock);

	Allowi(pdx, false);	// Make sure char reads are running
	mutex_unlock(&pdx->io_mutex);	// Protect disconnect from new i/o

	return iReturn;
}

/*******************************************************************************
** Get count of characters in the inout buffer.
*******************************************************************************/
int Stat1401(DEVICE_EXTENSION * pdx)
{
	int iReturn;
	mutex_lock(&pdx->io_mutex);	// Protect disconnect from new i/o
	Allowi(pdx, false);	// make sure we allow pending chars
	SendChars(pdx);		// in both directions
	iReturn = pdx->dwNumInput;	// no lock as single read
	mutex_unlock(&pdx->io_mutex);	// Protect disconnect from new i/o
	return iReturn;
}

/****************************************************************************
** LineCount
**
** Returns the number of newline chars in the buffer. There is no need for
** any fancy interlocks as we only read the interrupt routine data, and the
** system is arranged so nothing can be destroyed.
****************************************************************************/
int LineCount(DEVICE_EXTENSION * pdx)
{
	int iReturn = 0;	// will be count of line ends

	mutex_lock(&pdx->io_mutex);	// Protect disconnect from new i/o
	Allowi(pdx, false);	// Make sure char reads are running
	SendChars(pdx);		// and send any buffered chars
	spin_lock_irq(&pdx->charInLock);	// Get protection

	if (pdx->dwNumInput > 0)	// worth looking?
	{
		unsigned int dwIndex = pdx->dwInBuffGet;	// start at first available
		unsigned int dwEnd = pdx->dwInBuffPut;	// Position for search end
		do {
			if (pdx->inputBuffer[dwIndex++] == CR_CHAR)
				++iReturn;	// inc count if CR

			if (dwIndex >= INBUF_SZ)	// see if we fall off buff
				dwIndex = 0;
		}
		while (dwIndex != dwEnd);	// go to last available
	}

	spin_unlock_irq(&pdx->charInLock);
	dev_dbg(&pdx->interface->dev, "LineCount returned %d", iReturn);
	mutex_unlock(&pdx->io_mutex);	// Protect disconnect from new i/o
	return iReturn;
}

/****************************************************************************
** GetOutBufSpace
**
** Gets the space in the output buffer. Called from user code.
*****************************************************************************/
int GetOutBufSpace(DEVICE_EXTENSION * pdx)
{
	int iReturn;
	mutex_lock(&pdx->io_mutex);	// Protect disconnect from new i/o
	SendChars(pdx);		// send any buffered chars
	iReturn = (int)(OUTBUF_SZ - pdx->dwNumOutput);	// no lock needed for single read
	dev_dbg(&pdx->interface->dev, "OutBufSpace %d", iReturn);
	mutex_unlock(&pdx->io_mutex);	// Protect disconnect from new i/o
	return iReturn;
}

/****************************************************************************
**
** ClearArea
**
** Clears up a transfer area. This is always called in the context of a user
** request, never from a call-back.
****************************************************************************/
int ClearArea(DEVICE_EXTENSION * pdx, int nArea)
{
	int iReturn = U14ERR_NOERROR;

	if ((nArea < 0) || (nArea >= MAX_TRANSAREAS)) {
		iReturn = U14ERR_BADAREA;
		dev_err(&pdx->interface->dev, "%s Attempt to clear area %d",
			__func__, nArea);
	} else {
		TRANSAREA *pTA = &pdx->rTransDef[nArea];	// to save typing
		if (!pTA->bUsed)	// if not used...
			iReturn = U14ERR_NOTSET;	// ...nothing to be done
		else {
			// We must save the memory we return as we shouldn't mess with memory while
			// holding a spin lock.
			struct page **pPages = 0;	// save page address list
			int nPages = 0;	// and number of pages
			int np;

			dev_dbg(&pdx->interface->dev, "%s area %d", __func__,
				nArea);
			spin_lock_irq(&pdx->stagedLock);
			if ((pdx->StagedId == nArea)
			    && (pdx->dwDMAFlag > MODE_CHAR)) {
				iReturn = U14ERR_UNLOCKFAIL;	// cannot delete as in use
				dev_err(&pdx->interface->dev,
					"%s call on area %d while active",
					__func__, nArea);
			} else {
				pPages = pTA->pPages;	// save page address list
				nPages = pTA->nPages;	// and page count
				if (pTA->dwEventSz)	// if events flagging in use
					wake_up_interruptible(&pTA->wqEvent);	// release anything that was waiting

				if (pdx->bXFerWaiting
				    && (pdx->rDMAInfo.wIdent == nArea))
					pdx->bXFerWaiting = false;	// Cannot have pending xfer if area cleared

				// Clean out the TRANSAREA except for the wait queue, which is at the end
				// This sets bUsed to false and dwEventSz to 0 to say area not used and no events.
				memset(pTA, 0,
				       sizeof(TRANSAREA) -
				       sizeof(wait_queue_head_t));
			}
			spin_unlock_irq(&pdx->stagedLock);

			if (pPages)	// if we decided to release the memory
			{
				// Now we must undo the pinning down of the pages. We will assume the worst and mark
				// all the pages as dirty. Don't be tempted to move this up above as you must not be
				// holding a spin lock to do this stuff as it is not atomic.
				dev_dbg(&pdx->interface->dev, "%s nPages=%d",
					__func__, nPages);

				for (np = 0; np < nPages; ++np) {
					if (pPages[np]) {
						SetPageDirty(pPages[np]);
						page_cache_release(pPages[np]);
					}
				}

				kfree(pPages);
				dev_dbg(&pdx->interface->dev,
					"%s kfree(pPages) done", __func__);
			}
		}
	}

	return iReturn;
}

/****************************************************************************
** SetArea
**
** Sets up a transfer area - the functional part. Called by both
** SetTransfer and SetCircular.
****************************************************************************/
static int SetArea(DEVICE_EXTENSION * pdx, int nArea, char __user * puBuf,
		   unsigned int dwLength, bool bCircular, bool bCircToHost)
{
	// Start by working out the page aligned start of the area and the size
	// of the area in pages, allowing for the start not being aligned and the
	// end needing to be rounded up to a page boundary.
	unsigned long ulStart = ((unsigned long)puBuf) & PAGE_MASK;
	unsigned int ulOffset = ((unsigned long)puBuf) & (PAGE_SIZE - 1);
	int len = (dwLength + ulOffset + PAGE_SIZE - 1) >> PAGE_SHIFT;

	TRANSAREA *pTA = &pdx->rTransDef[nArea];	// to save typing
	struct page **pPages = 0;	// space for page tables
	int nPages = 0;		// and number of pages

	int iReturn = ClearArea(pdx, nArea);	// see if OK to use this area
	if ((iReturn != U14ERR_NOTSET) &&	// if not area unused and...
	    (iReturn != U14ERR_NOERROR))	// ...not all OK, then...
		return iReturn;	// ...we cannot use this area

	if (!access_ok(VERIFY_WRITE, puBuf, dwLength))	// if we cannot access the memory...
		return -EFAULT;	// ...then we are done

	// Now allocate space to hold the page pointer and virtual address pointer tables
	pPages = kmalloc(len * sizeof(struct page *), GFP_KERNEL);
	if (!pPages) {
		iReturn = U14ERR_NOMEMORY;
		goto error;
	}
	dev_dbg(&pdx->interface->dev, "%s %p, length=%06x, circular %d",
		__func__, puBuf, dwLength, bCircular);

	// To pin down user pages we must first acquire the mapping semaphore.
	down_read(&current->mm->mmap_sem);	// get memory map semaphore
	nPages =
	    get_user_pages(current, current->mm, ulStart, len, 1, 0, pPages, 0);
	up_read(&current->mm->mmap_sem);	// release the semaphore
	dev_dbg(&pdx->interface->dev, "%s nPages = %d", __func__, nPages);

	if (nPages > 0)		// if we succeeded
	{
		// If you are tempted to use page_address (form LDD3), forget it. You MUST use
		// kmap() or kmap_atomic() to get a virtual address. page_address will give you
		// (null) or at least it does in this context with an x86 machine.
		spin_lock_irq(&pdx->stagedLock);
		pTA->lpvBuff = puBuf;	// keep start of region (user address)
		pTA->dwBaseOffset = ulOffset;	// save offset in first page to start of xfer
		pTA->dwLength = dwLength;	// Size if the region in bytes
		pTA->pPages = pPages;	// list of pages that are used by buffer
		pTA->nPages = nPages;	// number of pages

		pTA->bCircular = bCircular;
		pTA->bCircToHost = bCircToHost;

		pTA->aBlocks[0].dwOffset = 0;
		pTA->aBlocks[0].dwSize = 0;
		pTA->aBlocks[1].dwOffset = 0;
		pTA->aBlocks[1].dwSize = 0;
		pTA->bUsed = true;	// This is now a used block

		spin_unlock_irq(&pdx->stagedLock);
		iReturn = U14ERR_NOERROR;	// say all was well
	} else {
		iReturn = U14ERR_LOCKFAIL;
		goto error;
	}

	return iReturn;

error:
	kfree(pPages);
	return iReturn;
}

/****************************************************************************
** SetTransfer
**
** Sets up a transfer area record. If the area is already set, we attempt to
** unset it. Unsetting will fail if the area is booked, and a transfer to that
** area is in progress. Otherwise, we will release the area and re-assign it.
****************************************************************************/
int SetTransfer(DEVICE_EXTENSION * pdx, TRANSFERDESC __user * pTD)
{
	int iReturn;
	TRANSFERDESC td;

	if (copy_from_user(&td, pTD, sizeof(td)))
		return -EFAULT;

	mutex_lock(&pdx->io_mutex);
	dev_dbg(&pdx->interface->dev, "%s area:%d, size:%08x", __func__,
		td.wAreaNum, td.dwLength);
	// The strange cast is done so that we don't get warnings in 32-bit linux about the size of the
	// pointer. The pointer is always passed as a 64-bit object so that we don't have problems using
	// a 32-bit program on a 64-bit system. unsigned long is 64-bits on a 64-bit system.
	iReturn =
	    SetArea(pdx, td.wAreaNum,
		    (char __user *)((unsigned long)td.lpvBuff), td.dwLength,
		    false, false);
	mutex_unlock(&pdx->io_mutex);
	return iReturn;
}

/****************************************************************************
** UnSetTransfer
** Erases a transfer area record
****************************************************************************/
int UnsetTransfer(DEVICE_EXTENSION * pdx, int nArea)
{
	int iReturn;
	mutex_lock(&pdx->io_mutex);
	iReturn = ClearArea(pdx, nArea);
	mutex_unlock(&pdx->io_mutex);
	return iReturn;
}

/****************************************************************************
** SetEvent
** Creates an event that we can test for based on a transfer to/from an area.
** The area must be setup for a transfer. We attempt to simulate the Windows
** driver behavior for events (as we don't actually use them), which is to
** pretend that whatever the user asked for was achieved, so we return 1 if
** try to create one, and 0 if they ask to remove (assuming all else was OK).
****************************************************************************/
int SetEvent(DEVICE_EXTENSION * pdx, TRANSFEREVENT __user * pTE)
{
	int iReturn = U14ERR_NOERROR;
	TRANSFEREVENT te;

	// get a local copy of the data
	if (copy_from_user(&te, pTE, sizeof(te)))
		return -EFAULT;

	if (te.wAreaNum >= MAX_TRANSAREAS)	// the area must exist
		return U14ERR_BADAREA;
	else {
		TRANSAREA *pTA = &pdx->rTransDef[te.wAreaNum];
		mutex_lock(&pdx->io_mutex);	// make sure we have no competitor
		spin_lock_irq(&pdx->stagedLock);
		if (pTA->bUsed)	// area must be in use
		{
			pTA->dwEventSt = te.dwStart;	// set area regions
			pTA->dwEventSz = te.dwLength;	// set size (0 cancels it)
			pTA->bEventToHost = te.wFlags & 1;	// set the direction
			pTA->iWakeUp = 0;	// zero the wake up count
		} else
			iReturn = U14ERR_NOTSET;
		spin_unlock_irq(&pdx->stagedLock);
		mutex_unlock(&pdx->io_mutex);
	}
	return iReturn ==
	    U14ERR_NOERROR ? (te.iSetEvent ? 1 : U14ERR_NOERROR) : iReturn;
}

/****************************************************************************
** WaitEvent
** Sleep the process with a timeout waiting for an event. Returns the number
** of times that a block met the event condition since we last cleared it or
** 0 if timed out, or -ve error (bad area or not set, or signal).
****************************************************************************/
int WaitEvent(DEVICE_EXTENSION * pdx, int nArea, int msTimeOut)
{
	int iReturn;
	if ((unsigned)nArea >= MAX_TRANSAREAS)
		return U14ERR_BADAREA;
	else {
		int iWait;
		TRANSAREA *pTA = &pdx->rTransDef[nArea];
		msTimeOut = (msTimeOut * HZ + 999) / 1000;	// convert timeout to jiffies

		// We cannot wait holding the mutex, but we check the flags while holding
		// it. This may well be pointless as another thread could get in between
		// releasing it and the wait call. However, this would have to clear the
		// iWakeUp flag. However, the !pTA-bUsed may help us in this case.
		mutex_lock(&pdx->io_mutex);	// make sure we have no competitor
		if (!pTA->bUsed || !pTA->dwEventSz)	// check something to wait for...
			return U14ERR_NOTSET;	// ...else we do nothing
		mutex_unlock(&pdx->io_mutex);

		if (msTimeOut)
			iWait =
			    wait_event_interruptible_timeout(pTA->wqEvent,
							     pTA->iWakeUp
							     || !pTA->bUsed,
							     msTimeOut);
		else
			iWait =
			    wait_event_interruptible(pTA->wqEvent, pTA->iWakeUp
						     || !pTA->bUsed);
		if (iWait)
			iReturn = -ERESTARTSYS;	// oops - we have had a SIGNAL
		else
			iReturn = pTA->iWakeUp;	// else the wakeup count

		spin_lock_irq(&pdx->stagedLock);
		pTA->iWakeUp = 0;	// clear the flag
		spin_unlock_irq(&pdx->stagedLock);
	}
	return iReturn;
}

/****************************************************************************
** TestEvent
** Test the event to see if a WaitEvent would return immediately. Returns the
** number of times a block completed since the last call, or 0 if none or a
** negative error.
****************************************************************************/
int TestEvent(DEVICE_EXTENSION * pdx, int nArea)
{
	int iReturn;
	if ((unsigned)nArea >= MAX_TRANSAREAS)
		iReturn = U14ERR_BADAREA;
	else {
		TRANSAREA *pTA = &pdx->rTransDef[nArea];
		mutex_lock(&pdx->io_mutex);	// make sure we have no competitor
		spin_lock_irq(&pdx->stagedLock);
		iReturn = pTA->iWakeUp;	// get wakeup count since last call
		pTA->iWakeUp = 0;	// clear the count
		spin_unlock_irq(&pdx->stagedLock);
		mutex_unlock(&pdx->io_mutex);
	}
	return iReturn;
}

/****************************************************************************
** GetTransferInfo
** Puts the current state of the 1401 in a TGET_TX_BLOCK.
*****************************************************************************/
int GetTransfer(DEVICE_EXTENSION * pdx, TGET_TX_BLOCK __user * pTX)
{
	int iReturn = U14ERR_NOERROR;
	unsigned int dwIdent;

	mutex_lock(&pdx->io_mutex);
	dwIdent = pdx->StagedId;	// area ident for last xfer
	if (dwIdent >= MAX_TRANSAREAS)
		iReturn = U14ERR_BADAREA;
	else {
		// Return the best information we have - we don't have physical addresses
		TGET_TX_BLOCK *tx;

		tx = kzalloc(sizeof(*tx), GFP_KERNEL);
		if (!tx) {
			mutex_unlock(&pdx->io_mutex);
			return -ENOMEM;
		}
		tx->size = pdx->rTransDef[dwIdent].dwLength;
		tx->linear = (long long)((long)pdx->rTransDef[dwIdent].lpvBuff);
		tx->avail = GET_TX_MAXENTRIES;	// how many blocks we could return
		tx->used = 1;	// number we actually return
		tx->entries[0].physical =
		    (long long)(tx->linear + pdx->StagedOffset);
		tx->entries[0].size = tx->size;

		if (copy_to_user(pTX, tx, sizeof(*tx)))
			iReturn = -EFAULT;
		kfree(tx);
	}
	mutex_unlock(&pdx->io_mutex);
	return iReturn;
}

/****************************************************************************
** KillIO1401
**
** Empties the host i/o buffers
****************************************************************************/
int KillIO1401(DEVICE_EXTENSION * pdx)
{
	dev_dbg(&pdx->interface->dev, "%s", __func__);
	mutex_lock(&pdx->io_mutex);
	FlushOutBuff(pdx);
	FlushInBuff(pdx);
	mutex_unlock(&pdx->io_mutex);
	return U14ERR_NOERROR;
}

/****************************************************************************
** BlkTransState
** Returns a 0 or a 1 for whether DMA is happening. No point holding a mutex
** for this as it only does one read.
*****************************************************************************/
int BlkTransState(DEVICE_EXTENSION * pdx)
{
	int iReturn = pdx->dwDMAFlag != MODE_CHAR;
	dev_dbg(&pdx->interface->dev, "%s = %d", __func__, iReturn);
	return iReturn;
}

/****************************************************************************
** StateOf1401
**
** Puts the current state of the 1401 in the Irp return buffer.
*****************************************************************************/
int StateOf1401(DEVICE_EXTENSION * pdx)
{
	int iReturn;
	mutex_lock(&pdx->io_mutex);

	QuickCheck(pdx, false, false);	// get state up to date, no reset
	iReturn = pdx->sCurrentState;

	mutex_unlock(&pdx->io_mutex);
	dev_dbg(&pdx->interface->dev, "%s = %d", __func__, iReturn);

	return iReturn;
}

/****************************************************************************
** StartSelfTest
**
** Initiates a self-test cycle. The assumption is that we have no interrupts
** active, so we should make sure that this is the case.
*****************************************************************************/
int StartSelfTest(DEVICE_EXTENSION * pdx)
{
	int nGot;
	mutex_lock(&pdx->io_mutex);
	dev_dbg(&pdx->interface->dev, "%s", __func__);

	ced_draw_down(pdx);	// wait for, then kill outstanding Urbs
	FlushInBuff(pdx);	// Clear out input buffer & pipe
	FlushOutBuff(pdx);	// Clear output buffer & pipe
//    ReadWrite_Cancel(pDeviceObject);        /* so things stay tidy */
	pdx->dwDMAFlag = MODE_CHAR;	/* Clear DMA mode flags here */

	nGot = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0), DB_SELFTEST, (H_TO_D | VENDOR | DEVREQ), 0, 0, 0, 0, HZ);	// allow 1 second timeout
	pdx->ulSelfTestTime = jiffies + HZ * 30;	// 30 seconds into the future

	mutex_unlock(&pdx->io_mutex);
	if (nGot < 0)
		dev_err(&pdx->interface->dev, "%s err=%d", __func__, nGot);
	return nGot < 0 ? U14ERR_FAIL : U14ERR_NOERROR;
}

/****************************************************************************
** CheckSelfTest
**
** Check progress of a self-test cycle
****************************************************************************/
int CheckSelfTest(DEVICE_EXTENSION * pdx, TGET_SELFTEST __user * pGST)
{
	unsigned int state, error;
	int iReturn;
	TGET_SELFTEST gst;	// local work space
	memset(&gst, 0, sizeof(gst));	// clear out the space (sets code 0)

	mutex_lock(&pdx->io_mutex);

	dev_dbg(&pdx->interface->dev, "%s", __func__);
	iReturn = Get1401State(pdx, &state, &error);
	if (iReturn == U14ERR_NOERROR)	// Only accept zero if it happens twice
		iReturn = Get1401State(pdx, &state, &error);

	if (iReturn != U14ERR_NOERROR)	// Self-test can cause comms errors
	{			// so we assume still testing
		dev_err(&pdx->interface->dev,
			"%s Get1401State=%d, assuming still testing", __func__,
			iReturn);
		state = 0x80;	// Force still-testing, no error
		error = 0;
		iReturn = U14ERR_NOERROR;
	}

	if ((state == -1) && (error == -1))	// If Get1401State had problems
	{
		dev_err(&pdx->interface->dev,
			"%s Get1401State failed, assuming still testing",
			__func__);
		state = 0x80;	// Force still-testing, no error
		error = 0;
	}

	if ((state & 0xFF) == 0x80)	// If we are still in self-test
	{
		if (state & 0x00FF0000)	// Have we got an error?
		{
			gst.code = (state & 0x00FF0000) >> 16;	// read the error code
			gst.x = error & 0x0000FFFF;	// Error data X
			gst.y = (error & 0xFFFF0000) >> 16;	// and data Y
			dev_dbg(&pdx->interface->dev, "Self-test error code %d",
				gst.code);
		} else		// No error, check for timeout
		{
			unsigned long ulNow = jiffies;	// get current time
			if (time_after(ulNow, pdx->ulSelfTestTime)) {
				gst.code = -2;	// Flag the timeout
				dev_dbg(&pdx->interface->dev,
					"Self-test timed-out");
			} else
				dev_dbg(&pdx->interface->dev,
					"Self-test on-going");
		}
	} else {
		gst.code = -1;	// Flag the test is done
		dev_dbg(&pdx->interface->dev, "Self-test done");
	}

	if (gst.code < 0)	// If we have a problem or finished
	{			// If using the 2890 we should reset properly
		if ((pdx->nPipes == 4) && (pdx->s1401Type <= TYPEPOWER))
			Is1401(pdx);	// Get 1401 reset and OK
		else
			QuickCheck(pdx, true, true);	// Otherwise check without reset unless problems
	}
	mutex_unlock(&pdx->io_mutex);

	if (copy_to_user(pGST, &gst, sizeof(gst)))
		return -EFAULT;

	return iReturn;
}

/****************************************************************************
** TypeOf1401
**
** Returns code for standard, plus, micro1401, power1401 or none
****************************************************************************/
int TypeOf1401(DEVICE_EXTENSION * pdx)
{
	int iReturn = TYPEUNKNOWN;
	mutex_lock(&pdx->io_mutex);
	dev_dbg(&pdx->interface->dev, "%s", __func__);

	switch (pdx->s1401Type) {
	case TYPE1401:
		iReturn = U14ERR_STD;
		break;		// Handle these types directly
	case TYPEPLUS:
		iReturn = U14ERR_PLUS;
		break;
	case TYPEU1401:
		iReturn = U14ERR_U1401;
		break;
	default:
		if ((pdx->s1401Type >= TYPEPOWER) && (pdx->s1401Type <= 25))
			iReturn = pdx->s1401Type + 4;	// We can calculate types
		else		//  for up-coming 1401 designs
			iReturn = TYPEUNKNOWN;	// Don't know or not there
	}
	dev_dbg(&pdx->interface->dev, "%s %d", __func__, iReturn);
	mutex_unlock(&pdx->io_mutex);

	return iReturn;
}

/****************************************************************************
** TransferFlags
**
** Returns flags on block transfer abilities
****************************************************************************/
int TransferFlags(DEVICE_EXTENSION * pdx)
{
	int iReturn = U14TF_MULTIA | U14TF_DIAG |	// we always have multiple DMA area
	    U14TF_NOTIFY | U14TF_CIRCTH;	// diagnostics, notify and circular
	dev_dbg(&pdx->interface->dev, "%s", __func__);
	mutex_lock(&pdx->io_mutex);
	if (pdx->bIsUSB2)	// Set flag for USB2 if appropriate
		iReturn |= U14TF_USB2;
	mutex_unlock(&pdx->io_mutex);

	return iReturn;
}

/***************************************************************************
** DbgCmd1401
** Issues a debug\diagnostic command to the 1401 along with a 32-bit datum
** This is a utility command used for dbg operations.
*/
static int DbgCmd1401(DEVICE_EXTENSION * pdx, unsigned char cmd,
		      unsigned int data)
{
	int iReturn;
	dev_dbg(&pdx->interface->dev, "%s entry", __func__);
	iReturn = usb_control_msg(pdx->udev, usb_sndctrlpipe(pdx->udev, 0), cmd, (H_TO_D | VENDOR | DEVREQ), (unsigned short)data, (unsigned short)(data >> 16), 0, 0, HZ);	// allow 1 second timeout
	if (iReturn < 0)
		dev_err(&pdx->interface->dev, "%s fail code=%d", __func__,
			iReturn);

	return iReturn;
}

/****************************************************************************
** DbgPeek
**
** Execute the diagnostic peek operation. Uses address, width and repeats.
****************************************************************************/
int DbgPeek(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB)
{
	int iReturn;
	TDBGBLOCK db;

	if (copy_from_user(&db, pDB, sizeof(db)))
		return -EFAULT;

	mutex_lock(&pdx->io_mutex);
	dev_dbg(&pdx->interface->dev, "%s @ %08x", __func__, db.iAddr);

	iReturn = DbgCmd1401(pdx, DB_SETADD, db.iAddr);
	if (iReturn == U14ERR_NOERROR)
		iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth);
	if (iReturn == U14ERR_NOERROR)
		iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats);
	if (iReturn == U14ERR_NOERROR)
		iReturn = DbgCmd1401(pdx, DB_PEEK, 0);
	mutex_unlock(&pdx->io_mutex);

	return iReturn;
}

/****************************************************************************
** DbgPoke
**
** Execute the diagnostic poke operation. Parameters are in the CSBLOCK struct
** in order address, size, repeats and value to poke.
****************************************************************************/
int DbgPoke(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB)
{
	int iReturn;
	TDBGBLOCK db;

	if (copy_from_user(&db, pDB, sizeof(db)))
		return -EFAULT;

	mutex_lock(&pdx->io_mutex);
	dev_dbg(&pdx->interface->dev, "%s @ %08x", __func__, db.iAddr);

	iReturn = DbgCmd1401(pdx, DB_SETADD, db.iAddr);
	if (iReturn == U14ERR_NOERROR)
		iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth);
	if (iReturn == U14ERR_NOERROR)
		iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats);
	if (iReturn == U14ERR_NOERROR)
		iReturn = DbgCmd1401(pdx, DB_POKE, db.iData);
	mutex_unlock(&pdx->io_mutex);

	return iReturn;
}

/****************************************************************************
** DbgRampData
**
** Execute the diagnostic ramp data operation. Parameters are in the CSBLOCK struct
** in order address, default, enable mask, size and repeats.
****************************************************************************/
int DbgRampData(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB)
{
	int iReturn;
	TDBGBLOCK db;

	if (copy_from_user(&db, pDB, sizeof(db)))
		return -EFAULT;

	mutex_lock(&pdx->io_mutex);
	dev_dbg(&pdx->interface->dev, "%s @ %08x", __func__, db.iAddr);

	iReturn = DbgCmd1401(pdx, DB_SETADD, db.iAddr);
	if (iReturn == U14ERR_NOERROR)
		iReturn = DbgCmd1401(pdx, DB_SETDEF, db.iDefault);
	if (iReturn == U14ERR_NOERROR)
		iReturn = DbgCmd1401(pdx, DB_SETMASK, db.iMask);
	if (iReturn == U14ERR_NOERROR)
		iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth);
	if (iReturn == U14ERR_NOERROR)
		iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats);
	if (iReturn == U14ERR_NOERROR)
		iReturn = DbgCmd1401(pdx, DB_RAMPD, 0);
	mutex_unlock(&pdx->io_mutex);

	return iReturn;
}

/****************************************************************************
** DbgRampAddr
**
** Execute the diagnostic ramp address operation
****************************************************************************/
int DbgRampAddr(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB)
{
	int iReturn;
	TDBGBLOCK db;

	if (copy_from_user(&db, pDB, sizeof(db)))
		return -EFAULT;

	mutex_lock(&pdx->io_mutex);
	dev_dbg(&pdx->interface->dev, "%s", __func__);

	iReturn = DbgCmd1401(pdx, DB_SETDEF, db.iDefault);
	if (iReturn == U14ERR_NOERROR)
		iReturn = DbgCmd1401(pdx, DB_SETMASK, db.iMask);
	if (iReturn == U14ERR_NOERROR)
		iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth);
	if (iReturn == U14ERR_NOERROR)
		iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats);
	if (iReturn == U14ERR_NOERROR)
		iReturn = DbgCmd1401(pdx, DB_RAMPA, 0);
	mutex_unlock(&pdx->io_mutex);

	return iReturn;
}

/****************************************************************************
** DbgGetData
**
** Retrieve the data resulting from the last debug Peek operation
****************************************************************************/
int DbgGetData(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB)
{
	int iReturn;
	TDBGBLOCK db;
	memset(&db, 0, sizeof(db));	// fill returned block with 0s

	mutex_lock(&pdx->io_mutex);
	dev_dbg(&pdx->interface->dev, "%s", __func__);

	// Read back the last peeked value from the 1401.
	iReturn = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0),
				  DB_DATA, (D_TO_H | VENDOR | DEVREQ), 0, 0,
				  &db.iData, sizeof(db.iData), HZ);
	if (iReturn == sizeof(db.iData)) {
		if (copy_to_user(pDB, &db, sizeof(db)))
			iReturn = -EFAULT;
		else
			iReturn = U14ERR_NOERROR;
	} else
		dev_err(&pdx->interface->dev, "%s failed, code %d", __func__,
			iReturn);

	mutex_unlock(&pdx->io_mutex);

	return iReturn;
}

/****************************************************************************
** DbgStopLoop
**
** Stop any never-ending debug loop, we just call Get1401State for USB
**
****************************************************************************/
int DbgStopLoop(DEVICE_EXTENSION * pdx)
{
	int iReturn;
	unsigned int uState, uErr;

	mutex_lock(&pdx->io_mutex);
	dev_dbg(&pdx->interface->dev, "%s", __func__);
	iReturn = Get1401State(pdx, &uState, &uErr);
	mutex_unlock(&pdx->io_mutex);

	return iReturn;
}

/****************************************************************************
** SetCircular
**
** Sets up a transfer area record for circular transfers. If the area is
** already set, we attempt to unset it. Unsetting will fail if the area is
** booked and a transfer to that area is in progress. Otherwise, we will
** release the area and re-assign it.
****************************************************************************/
int SetCircular(DEVICE_EXTENSION * pdx, TRANSFERDESC __user * pTD)
{
	int iReturn;
	bool bToHost;
	TRANSFERDESC td;

	if (copy_from_user(&td, pTD, sizeof(td)))
		return -EFAULT;

	mutex_lock(&pdx->io_mutex);
	dev_dbg(&pdx->interface->dev, "%s area:%d, size:%08x", __func__,
		td.wAreaNum, td.dwLength);
	bToHost = td.eSize != 0;	// this is used as the tohost flag

	// The strange cast is done so that we don't get warnings in 32-bit linux about the size of the
	// pointer. The pointer is always passed as a 64-bit object so that we don't have problems using
	// a 32-bit program on a 64-bit system. unsigned long is 64-bits on a 64-bit system.
	iReturn =
	    SetArea(pdx, td.wAreaNum,
		    (char __user *)((unsigned long)td.lpvBuff), td.dwLength,
		    true, bToHost);
	mutex_unlock(&pdx->io_mutex);
	return iReturn;
}

/****************************************************************************
** GetCircBlock
**
** Return the next available block of circularly-transferred data.
****************************************************************************/
int GetCircBlock(DEVICE_EXTENSION * pdx, TCIRCBLOCK __user * pCB)
{
	int iReturn = U14ERR_NOERROR;
	unsigned int nArea;
	TCIRCBLOCK cb;

	dev_dbg(&pdx->interface->dev, "%s", __func__);

	if (copy_from_user(&cb, pCB, sizeof(cb)))
		return -EFAULT;

	mutex_lock(&pdx->io_mutex);

	nArea = cb.nArea;	// Retrieve parameters first
	cb.dwOffset = 0;	// set default result (nothing)
	cb.dwSize = 0;

	if (nArea < MAX_TRANSAREAS)	// The area number must be OK
	{
		TRANSAREA *pArea = &pdx->rTransDef[nArea];	// Pointer to relevant info
		spin_lock_irq(&pdx->stagedLock);	// Lock others out

		if ((pArea->bUsed) && (pArea->bCircular) &&	// Must be circular area
		    (pArea->bCircToHost))	// For now at least must be to host
		{
			if (pArea->aBlocks[0].dwSize > 0)	// Got anything?
			{
				cb.dwOffset = pArea->aBlocks[0].dwOffset;
				cb.dwSize = pArea->aBlocks[0].dwSize;
				dev_dbg(&pdx->interface->dev,
					"%s return block 0: %d bytes at %d",
					__func__, cb.dwSize, cb.dwOffset);
			}
		} else
			iReturn = U14ERR_NOTSET;

		spin_unlock_irq(&pdx->stagedLock);
	} else
		iReturn = U14ERR_BADAREA;

	if (copy_to_user(pCB, &cb, sizeof(cb)))
		iReturn = -EFAULT;

	mutex_unlock(&pdx->io_mutex);
	return iReturn;
}

/****************************************************************************
** FreeCircBlock
**
** Frees a block of circularly-transferred data and returns the next one.
****************************************************************************/
int FreeCircBlock(DEVICE_EXTENSION * pdx, TCIRCBLOCK __user * pCB)
{
	int iReturn = U14ERR_NOERROR;
	unsigned int nArea, uStart, uSize;
	TCIRCBLOCK cb;

	dev_dbg(&pdx->interface->dev, "%s", __func__);

	if (copy_from_user(&cb, pCB, sizeof(cb)))
		return -EFAULT;

	mutex_lock(&pdx->io_mutex);

	nArea = cb.nArea;	// Retrieve parameters first
	uStart = cb.dwOffset;
	uSize = cb.dwSize;
	cb.dwOffset = 0;	// then set default result (nothing)
	cb.dwSize = 0;

	if (nArea < MAX_TRANSAREAS)	// The area number must be OK
	{
		TRANSAREA *pArea = &pdx->rTransDef[nArea];	// Pointer to relevant info
		spin_lock_irq(&pdx->stagedLock);	// Lock others out

		if ((pArea->bUsed) && (pArea->bCircular) &&	// Must be circular area
		    (pArea->bCircToHost))	// For now at least must be to host
		{
			bool bWaiting = false;

			if ((pArea->aBlocks[0].dwSize >= uSize) &&	// Got anything?
			    (pArea->aBlocks[0].dwOffset == uStart))	// Must be legal data
			{
				pArea->aBlocks[0].dwSize -= uSize;
				pArea->aBlocks[0].dwOffset += uSize;
				if (pArea->aBlocks[0].dwSize == 0)	// Have we emptied this block?
				{
					if (pArea->aBlocks[1].dwSize)	// Is there a second block?
					{
						pArea->aBlocks[0] = pArea->aBlocks[1];	// Copy down block 2 data
						pArea->aBlocks[1].dwSize = 0;	// and mark the second block as unused
						pArea->aBlocks[1].dwOffset = 0;
					} else
						pArea->aBlocks[0].dwOffset = 0;
				}

				dev_dbg(&pdx->interface->dev,
					"%s free %d bytes at %d, return %d bytes at %d, wait=%d",
					__func__, uSize, uStart,
					pArea->aBlocks[0].dwSize,
					pArea->aBlocks[0].dwOffset,
					pdx->bXFerWaiting);

				// Return the next available block of memory as well
				if (pArea->aBlocks[0].dwSize > 0)	// Got anything?
				{
					cb.dwOffset =
					    pArea->aBlocks[0].dwOffset;
					cb.dwSize = pArea->aBlocks[0].dwSize;
				}

				bWaiting = pdx->bXFerWaiting;
				if (bWaiting && pdx->bStagedUrbPending) {
					dev_err(&pdx->interface->dev,
						"%s ERROR: waiting xfer and staged Urb pending!",
						__func__);
					bWaiting = false;
				}
			} else {
				dev_err(&pdx->interface->dev,
					"%s ERROR: freeing %d bytes at %d, block 0 is %d bytes at %d",
					__func__, uSize, uStart,
					pArea->aBlocks[0].dwSize,
					pArea->aBlocks[0].dwOffset);
				iReturn = U14ERR_NOMEMORY;
			}

			// If we have one, kick off pending transfer
			if (bWaiting)	// Got a block xfer waiting?
			{
				int RWMStat =
				    ReadWriteMem(pdx, !pdx->rDMAInfo.bOutWard,
						 pdx->rDMAInfo.wIdent,
						 pdx->rDMAInfo.dwOffset,
						 pdx->rDMAInfo.dwSize);
				if (RWMStat != U14ERR_NOERROR)
					dev_err(&pdx->interface->dev,
						"%s rw setup failed %d",
						__func__, RWMStat);
			}
		} else
			iReturn = U14ERR_NOTSET;

		spin_unlock_irq(&pdx->stagedLock);
	} else
		iReturn = U14ERR_BADAREA;

	if (copy_to_user(pCB, &cb, sizeof(cb)))
		iReturn = -EFAULT;

	mutex_unlock(&pdx->io_mutex);
	return iReturn;
}
