Commit 1cc7b53c authored by Luca Ellero's avatar Luca Ellero Committed by Greg Kroah-Hartman

staging: ced1401: remove typedef DEVICE_EXTENSION

Signed-off-by: default avatarLuca Ellero <luca.ellero@brickedbrain.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 70bc3dbe
...@@ -36,19 +36,19 @@ ...@@ -36,19 +36,19 @@
** **
** Empties the Output buffer and sets int lines. Used from user level only ** Empties the Output buffer and sets int lines. Used from user level only
****************************************************************************/ ****************************************************************************/
static void ced_flush_out_buff(DEVICE_EXTENSION *pdx) static void ced_flush_out_buff(struct ced_data *ced)
{ {
dev_dbg(&pdx->interface->dev, "%s: currentState=%d\n", dev_dbg(&ced->interface->dev, "%s: currentState=%d\n",
__func__, pdx->sCurrentState); __func__, ced->sCurrentState);
if (pdx->sCurrentState == U14ERR_TIME) /* Do nothing if hardware in trouble */ if (ced->sCurrentState == U14ERR_TIME) /* Do nothing if hardware in trouble */
return; return;
/* Kill off any pending I/O */ /* Kill off any pending I/O */
/* CharSend_Cancel(pdx); */ /* CharSend_Cancel(ced); */
spin_lock_irq(&pdx->charOutLock); spin_lock_irq(&ced->charOutLock);
pdx->dwNumOutput = 0; ced->dwNumOutput = 0;
pdx->dwOutBuffGet = 0; ced->dwOutBuffGet = 0;
pdx->dwOutBuffPut = 0; ced->dwOutBuffPut = 0;
spin_unlock_irq(&pdx->charOutLock); spin_unlock_irq(&ced->charOutLock);
} }
/**************************************************************************** /****************************************************************************
...@@ -57,19 +57,19 @@ static void ced_flush_out_buff(DEVICE_EXTENSION *pdx) ...@@ -57,19 +57,19 @@ static void ced_flush_out_buff(DEVICE_EXTENSION *pdx)
** **
** Empties the input buffer and sets int lines ** Empties the input buffer and sets int lines
****************************************************************************/ ****************************************************************************/
static void ced_flush_in_buff(DEVICE_EXTENSION *pdx) static void ced_flush_in_buff(struct ced_data *ced)
{ {
dev_dbg(&pdx->interface->dev, "%s: currentState=%d\n", dev_dbg(&ced->interface->dev, "%s: currentState=%d\n",
__func__, pdx->sCurrentState); __func__, ced->sCurrentState);
if (pdx->sCurrentState == U14ERR_TIME) /* Do nothing if hardware in trouble */ if (ced->sCurrentState == U14ERR_TIME) /* Do nothing if hardware in trouble */
return; return;
/* Kill off any pending I/O */ /* Kill off any pending I/O */
/* CharRead_Cancel(pDevObject); */ /* CharRead_Cancel(pDevObject); */
spin_lock_irq(&pdx->charInLock); spin_lock_irq(&ced->charInLock);
pdx->dwNumInput = 0; ced->dwNumInput = 0;
pdx->dwInBuffGet = 0; ced->dwInBuffGet = 0;
pdx->dwInBuffPut = 0; ced->dwInBuffPut = 0;
spin_unlock_irq(&pdx->charInLock); spin_unlock_irq(&ced->charInLock);
} }
/**************************************************************************** /****************************************************************************
...@@ -78,24 +78,24 @@ static void ced_flush_in_buff(DEVICE_EXTENSION *pdx) ...@@ -78,24 +78,24 @@ static void ced_flush_in_buff(DEVICE_EXTENSION *pdx)
** Utility routine to copy chars into the output buffer and fire them off. ** Utility routine to copy chars into the output buffer and fire them off.
** called from user mode, holds charOutLock. ** called from user mode, holds charOutLock.
****************************************************************************/ ****************************************************************************/
static int ced_put_chars(DEVICE_EXTENSION *pdx, const char *pCh, static int ced_put_chars(struct ced_data *ced, const char *pCh,
unsigned int uCount) unsigned int uCount)
{ {
int iReturn; int iReturn;
spin_lock_irq(&pdx->charOutLock); /* get the output spin lock */ spin_lock_irq(&ced->charOutLock); /* get the output spin lock */
if ((OUTBUF_SZ - pdx->dwNumOutput) >= uCount) { if ((OUTBUF_SZ - ced->dwNumOutput) >= uCount) {
unsigned int u; unsigned int u;
for (u = 0; u < uCount; u++) { for (u = 0; u < uCount; u++) {
pdx->outputBuffer[pdx->dwOutBuffPut++] = pCh[u]; ced->outputBuffer[ced->dwOutBuffPut++] = pCh[u];
if (pdx->dwOutBuffPut >= OUTBUF_SZ) if (ced->dwOutBuffPut >= OUTBUF_SZ)
pdx->dwOutBuffPut = 0; ced->dwOutBuffPut = 0;
} }
pdx->dwNumOutput += uCount; ced->dwNumOutput += uCount;
spin_unlock_irq(&pdx->charOutLock); spin_unlock_irq(&ced->charOutLock);
iReturn = ced_send_chars(pdx); /* ...give a chance to transmit data */ iReturn = ced_send_chars(ced); /* ...give a chance to transmit data */
} else { } else {
iReturn = U14ERR_NOOUT; /* no room at the out (ha-ha) */ iReturn = U14ERR_NOOUT; /* no room at the out (ha-ha) */
spin_unlock_irq(&pdx->charOutLock); spin_unlock_irq(&ced->charOutLock);
} }
return iReturn; return iReturn;
} }
...@@ -105,7 +105,7 @@ static int ced_put_chars(DEVICE_EXTENSION *pdx, const char *pCh, ...@@ -105,7 +105,7 @@ static int ced_put_chars(DEVICE_EXTENSION *pdx, const char *pCh,
** trigger an output transfer if this is appropriate. User mode. ** trigger an output transfer if this is appropriate. User mode.
** Holds the io_mutex ** Holds the io_mutex
*****************************************************************************/ *****************************************************************************/
int ced_send_string(DEVICE_EXTENSION *pdx, const char __user *pData, int ced_send_string(struct ced_data *ced, const char __user *pData,
unsigned int n) unsigned int n)
{ {
int iReturn = U14ERR_NOERROR; /* assume all will be well */ int iReturn = U14ERR_NOERROR; /* assume all will be well */
...@@ -116,15 +116,15 @@ int ced_send_string(DEVICE_EXTENSION *pdx, const char __user *pData, ...@@ -116,15 +116,15 @@ int ced_send_string(DEVICE_EXTENSION *pdx, const char __user *pData,
return -EFAULT; return -EFAULT;
buffer[n] = 0; /* terminate for debug purposes */ buffer[n] = 0; /* terminate for debug purposes */
mutex_lock(&pdx->io_mutex); /* Protect disconnect from new i/o */ mutex_lock(&ced->io_mutex); /* Protect disconnect from new i/o */
if (n > 0) { /* do nothing if nowt to do! */ if (n > 0) { /* do nothing if nowt to do! */
dev_dbg(&pdx->interface->dev, "%s: n=%d>%s<\n", dev_dbg(&ced->interface->dev, "%s: n=%d>%s<\n",
__func__, n, buffer); __func__, n, buffer);
iReturn = ced_put_chars(pdx, buffer, n); iReturn = ced_put_chars(ced, buffer, n);
} }
ced_allowi(pdx); /* make sure we have input int */ ced_allowi(ced); /* make sure we have input int */
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
return iReturn; return iReturn;
} }
...@@ -134,14 +134,14 @@ int ced_send_string(DEVICE_EXTENSION *pdx, const char __user *pData, ...@@ -134,14 +134,14 @@ int ced_send_string(DEVICE_EXTENSION *pdx, const char __user *pData,
** **
** Sends a single character to the 1401. User mode, holds io_mutex. ** Sends a single character to the 1401. User mode, holds io_mutex.
****************************************************************************/ ****************************************************************************/
int ced_send_char(DEVICE_EXTENSION *pdx, char c) int ced_send_char(struct ced_data *ced, char c)
{ {
int iReturn; int iReturn;
mutex_lock(&pdx->io_mutex); /* Protect disconnect from new i/o */ mutex_lock(&ced->io_mutex); /* Protect disconnect from new i/o */
iReturn = ced_put_chars(pdx, &c, 1); iReturn = ced_put_chars(ced, &c, 1);
dev_dbg(&pdx->interface->dev, "ced_send_char >%c< (0x%02x)\n", c, c); dev_dbg(&ced->interface->dev, "ced_send_char >%c< (0x%02x)\n", c, c);
ced_allowi(pdx); /* Make sure char reads are running */ ced_allowi(ced); /* Make sure char reads are running */
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
return iReturn; return iReturn;
} }
...@@ -171,46 +171,46 @@ int ced_send_char(DEVICE_EXTENSION *pdx, char c) ...@@ -171,46 +171,46 @@ int ced_send_char(DEVICE_EXTENSION *pdx, char c)
** **
** return error code (U14ERR_NOERROR for OK) ** return error code (U14ERR_NOERROR for OK)
*/ */
int ced_get_state(DEVICE_EXTENSION *pdx, __u32 *state, __u32 *error) int ced_get_state(struct ced_data *ced, __u32 *state, __u32 *error)
{ {
int nGot; int nGot;
dev_dbg(&pdx->interface->dev, "%s: entry\n", __func__); dev_dbg(&ced->interface->dev, "%s: entry\n", __func__);
*state = 0xFFFFFFFF; /* Start off with invalid state */ *state = 0xFFFFFFFF; /* Start off with invalid state */
nGot = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0), nGot = usb_control_msg(ced->udev, usb_rcvctrlpipe(ced->udev, 0),
GET_STATUS, (D_TO_H | VENDOR | DEVREQ), 0, 0, GET_STATUS, (D_TO_H | VENDOR | DEVREQ), 0, 0,
pdx->statBuf, sizeof(pdx->statBuf), HZ); ced->statBuf, sizeof(ced->statBuf), HZ);
if (nGot != sizeof(pdx->statBuf)) { if (nGot != sizeof(ced->statBuf)) {
dev_err(&pdx->interface->dev, dev_err(&ced->interface->dev,
"%s: FAILED, return code %d\n", __func__, nGot); "%s: FAILED, return code %d\n", __func__, nGot);
pdx->sCurrentState = U14ERR_TIME; /* Indicate that things are very wrong indeed */ ced->sCurrentState = U14ERR_TIME; /* Indicate that things are very wrong indeed */
*state = 0; /* Force status values to a known state */ *state = 0; /* Force status values to a known state */
*error = 0; *error = 0;
} else { } else {
int nDevice; int nDevice;
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"%s: Success, state: 0x%x, 0x%x\n", "%s: Success, state: 0x%x, 0x%x\n",
__func__, pdx->statBuf[0], pdx->statBuf[1]); __func__, ced->statBuf[0], ced->statBuf[1]);
*state = pdx->statBuf[0]; /* Return the state values to the calling code */ *state = ced->statBuf[0]; /* Return the state values to the calling code */
*error = pdx->statBuf[1]; *error = ced->statBuf[1];
nDevice = pdx->udev->descriptor.bcdDevice >> 8; /* 1401 type code value */ nDevice = ced->udev->descriptor.bcdDevice >> 8; /* 1401 type code value */
switch (nDevice) { /* so we can clean up current state */ switch (nDevice) { /* so we can clean up current state */
case 0: case 0:
pdx->sCurrentState = U14ERR_U1401; ced->sCurrentState = U14ERR_U1401;
break; break;
default: /* allow lots of device codes for future 1401s */ default: /* allow lots of device codes for future 1401s */
if ((nDevice >= 1) && (nDevice <= 23)) if ((nDevice >= 1) && (nDevice <= 23))
pdx->sCurrentState = (short)(nDevice + 6); ced->sCurrentState = (short)(nDevice + 6);
else else
pdx->sCurrentState = U14ERR_ILL; ced->sCurrentState = U14ERR_ILL;
break; break;
} }
} }
return pdx->sCurrentState >= 0 ? U14ERR_NOERROR : pdx->sCurrentState; return ced->sCurrentState >= 0 ? U14ERR_NOERROR : ced->sCurrentState;
} }
/**************************************************************************** /****************************************************************************
...@@ -218,39 +218,39 @@ int ced_get_state(DEVICE_EXTENSION *pdx, __u32 *state, __u32 *error) ...@@ -218,39 +218,39 @@ int ced_get_state(DEVICE_EXTENSION *pdx, __u32 *state, __u32 *error)
** **
** Kills off staged read\write request from the USB if one is pending. ** Kills off staged read\write request from the USB if one is pending.
****************************************************************************/ ****************************************************************************/
int ced_read_write_cancel(DEVICE_EXTENSION *pdx) int ced_read_write_cancel(struct ced_data *ced)
{ {
dev_dbg(&pdx->interface->dev, "%s: entry %d\n", dev_dbg(&ced->interface->dev, "%s: entry %d\n",
__func__, pdx->bStagedUrbPending); __func__, ced->bStagedUrbPending);
#ifdef NOT_WRITTEN_YET #ifdef NOT_WRITTEN_YET
int ntStatus = STATUS_SUCCESS; int ntStatus = STATUS_SUCCESS;
bool bResult = false; bool bResult = false;
unsigned int i; unsigned int i;
/* We can fill this in when we know how we will implement the staged transfer stuff */ /* We can fill this in when we know how we will implement the staged transfer stuff */
spin_lock_irq(&pdx->stagedLock); spin_lock_irq(&ced->stagedLock);
if (pdx->bStagedUrbPending) { /* anything to be cancelled? May need more... */ if (ced->bStagedUrbPending) { /* anything to be cancelled? May need more... */
dev_info(&pdx->interface - dev, dev_info(&ced->interface - dev,
"ced_read_write_cancel about to cancel Urb\n"); "ced_read_write_cancel about to cancel Urb\n");
/* Clear the staging done flag */ /* Clear the staging done flag */
/* KeClearEvent(&pdx->StagingDoneEvent); */ /* KeClearEvent(&ced->StagingDoneEvent); */
USB_ASSERT(pdx->pStagedIrp != NULL); USB_ASSERT(ced->pStagedIrp != NULL);
/* Release the spinlock first otherwise the completion routine may hang */ /* Release the spinlock first otherwise the completion routine may hang */
/* on the spinlock while this function hands waiting for the event. */ /* on the spinlock while this function hands waiting for the event. */
spin_unlock_irq(&pdx->stagedLock); spin_unlock_irq(&ced->stagedLock);
bResult = IoCancelIrp(pdx->pStagedIrp); /* Actually do the cancel */ bResult = IoCancelIrp(ced->pStagedIrp); /* Actually do the cancel */
if (bResult) { if (bResult) {
LARGE_INTEGER timeout; LARGE_INTEGER timeout;
timeout.QuadPart = -10000000; /* Use a timeout of 1 second */ timeout.QuadPart = -10000000; /* Use a timeout of 1 second */
dev_info(&pdx->interface - dev, dev_info(&ced->interface - dev,
"%s: about to wait till done\n", __func__); "%s: about to wait till done\n", __func__);
ntStatus = ntStatus =
KeWaitForSingleObject(&pdx->StagingDoneEvent, KeWaitForSingleObject(&ced->StagingDoneEvent,
Executive, KernelMode, FALSE, Executive, KernelMode, FALSE,
&timeout); &timeout);
} else { } else {
dev_info(&pdx->interface - dev, dev_info(&ced->interface - dev,
"%s: cancellation failed\n", __func__); "%s: cancellation failed\n", __func__);
ntStatus = U14ERR_FAIL; ntStatus = U14ERR_FAIL;
} }
...@@ -258,9 +258,9 @@ int ced_read_write_cancel(DEVICE_EXTENSION *pdx) ...@@ -258,9 +258,9 @@ int ced_read_write_cancel(DEVICE_EXTENSION *pdx)
("ced_read_write_cancel ntStatus = 0x%x decimal %d\n", ("ced_read_write_cancel ntStatus = 0x%x decimal %d\n",
ntStatus, ntStatus)); ntStatus, ntStatus));
} else } else
spin_unlock_irq(&pdx->stagedLock); spin_unlock_irq(&ced->stagedLock);
dev_info(&pdx->interface - dev, "%s: done\n", __func__); dev_info(&ced->interface - dev, "%s: done\n", __func__);
return ntStatus; return ntStatus;
#else #else
return U14ERR_NOERROR; return U14ERR_NOERROR;
...@@ -272,10 +272,10 @@ int ced_read_write_cancel(DEVICE_EXTENSION *pdx) ...@@ -272,10 +272,10 @@ int ced_read_write_cancel(DEVICE_EXTENSION *pdx)
** ced_in_self_test - utility to check in self test. Return 1 for ST, 0 for not or ** ced_in_self_test - utility to check in self test. Return 1 for ST, 0 for not or
** a -ve error code if we failed for some reason. ** a -ve error code if we failed for some reason.
***************************************************************************/ ***************************************************************************/
static int ced_in_self_test(DEVICE_EXTENSION *pdx, unsigned int *pState) static int ced_in_self_test(struct ced_data *ced, unsigned int *pState)
{ {
unsigned int state, error; unsigned int state, error;
int iReturn = ced_get_state(pdx, &state, &error); /* see if in self-test */ int iReturn = ced_get_state(ced, &state, &error); /* see if in self-test */
if (iReturn == U14ERR_NOERROR) /* if all still OK */ if (iReturn == U14ERR_NOERROR) /* if all still OK */
iReturn = (state == (unsigned int)-1) || /* TX problem or... */ iReturn = (state == (unsigned int)-1) || /* TX problem or... */
((state & 0xff) == 0x80); /* ...self test */ ((state & 0xff) == 0x80); /* ...self test */
...@@ -301,37 +301,37 @@ static int ced_in_self_test(DEVICE_EXTENSION *pdx, unsigned int *pState) ...@@ -301,37 +301,37 @@ static int ced_in_self_test(DEVICE_EXTENSION *pdx, unsigned int *pState)
** **
** Returns TRUE if a 1401 detected and OK, else FALSE ** Returns TRUE if a 1401 detected and OK, else FALSE
****************************************************************************/ ****************************************************************************/
static bool ced_is_1401(DEVICE_EXTENSION *pdx) static bool ced_is_1401(struct ced_data *ced)
{ {
int iReturn; int iReturn;
dev_dbg(&pdx->interface->dev, "%s\n", __func__); dev_dbg(&ced->interface->dev, "%s\n", __func__);
ced_draw_down(pdx); /* wait for, then kill outstanding Urbs */ ced_draw_down(ced); /* wait for, then kill outstanding Urbs */
ced_flush_in_buff(pdx); /* Clear out input buffer & pipe */ ced_flush_in_buff(ced); /* Clear out input buffer & pipe */
ced_flush_out_buff(pdx); /* Clear output buffer & pipe */ ced_flush_out_buff(ced); /* Clear output buffer & pipe */
/* The next call returns 0 if OK, but has returned 1 in the past, meaning that */ /* 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 */ /* usb_unlock_device() is needed... now it always is */
iReturn = usb_lock_device_for_reset(pdx->udev, pdx->interface); iReturn = usb_lock_device_for_reset(ced->udev, ced->interface);
/* release the io_mutex because if we don't, we will deadlock due to system */ /* release the io_mutex because if we don't, we will deadlock due to system */
/* calls back into the driver. */ /* calls back into the driver. */
mutex_unlock(&pdx->io_mutex); /* locked, so we will not get system calls */ mutex_unlock(&ced->io_mutex); /* locked, so we will not get system calls */
if (iReturn >= 0) { /* if we failed */ if (iReturn >= 0) { /* if we failed */
iReturn = usb_reset_device(pdx->udev); /* try to do the reset */ iReturn = usb_reset_device(ced->udev); /* try to do the reset */
usb_unlock_device(pdx->udev); /* undo the lock */ usb_unlock_device(ced->udev); /* undo the lock */
} }
mutex_lock(&pdx->io_mutex); /* hold stuff off while we wait */ mutex_lock(&ced->io_mutex); /* hold stuff off while we wait */
pdx->dwDMAFlag = MODE_CHAR; /* Clear DMA mode flag regardless! */ ced->dwDMAFlag = MODE_CHAR; /* Clear DMA mode flag regardless! */
if (iReturn == 0) { /* if all is OK still */ if (iReturn == 0) { /* if all is OK still */
unsigned int state; unsigned int state;
iReturn = ced_in_self_test(pdx, &state); /* see if likely in self test */ iReturn = ced_in_self_test(ced, &state); /* see if likely in self test */
if (iReturn > 0) { /* do we need to wait for self-test? */ if (iReturn > 0) { /* do we need to wait for self-test? */
unsigned long ulTimeOut = jiffies + 30 * HZ; /* when to give up */ unsigned long ulTimeOut = jiffies + 30 * HZ; /* when to give up */
while ((iReturn > 0) && time_before(jiffies, ulTimeOut)) { while ((iReturn > 0) && time_before(jiffies, ulTimeOut)) {
schedule(); /* let other stuff run */ schedule(); /* let other stuff run */
iReturn = ced_in_self_test(pdx, &state); /* see if done yet */ iReturn = ced_in_self_test(ced, &state); /* see if done yet */
} }
} }
...@@ -339,7 +339,7 @@ static bool ced_is_1401(DEVICE_EXTENSION *pdx) ...@@ -339,7 +339,7 @@ static bool ced_is_1401(DEVICE_EXTENSION *pdx)
iReturn = state == 0; /* then success is that the state is 0 */ iReturn = state == 0; /* then success is that the state is 0 */
} else } else
iReturn = 0; /* we failed */ iReturn = 0; /* we failed */
pdx->bForceReset = false; /* Clear forced reset flag now */ ced->bForceReset = false; /* Clear forced reset flag now */
return iReturn > 0; return iReturn > 0;
} }
...@@ -358,42 +358,42 @@ static bool ced_is_1401(DEVICE_EXTENSION *pdx) ...@@ -358,42 +358,42 @@ static bool ced_is_1401(DEVICE_EXTENSION *pdx)
** **
** The return value is TRUE if a useable 1401 is found, FALSE if not ** The return value is TRUE if a useable 1401 is found, FALSE if not
*/ */
static bool ced_quick_check(DEVICE_EXTENSION *pdx, bool bTestBuff, bool bCanReset) static bool ced_quick_check(struct ced_data *ced, bool bTestBuff, bool bCanReset)
{ {
bool bRet = false; /* assume it will fail and we will reset */ bool bRet = false; /* assume it will fail and we will reset */
bool bShortTest; bool bShortTest;
bShortTest = ((pdx->dwDMAFlag == MODE_CHAR) && /* no DMA running */ bShortTest = ((ced->dwDMAFlag == MODE_CHAR) && /* no DMA running */
(!pdx->bForceReset) && /* Not had a real reset forced */ (!ced->bForceReset) && /* Not had a real reset forced */
(pdx->sCurrentState >= U14ERR_STD)); /* No 1401 errors stored */ (ced->sCurrentState >= U14ERR_STD)); /* No 1401 errors stored */
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"%s: DMAFlag:%d, state:%d, force:%d, testBuff:%d, short:%d\n", "%s: DMAFlag:%d, state:%d, force:%d, testBuff:%d, short:%d\n",
__func__, pdx->dwDMAFlag, pdx->sCurrentState, pdx->bForceReset, __func__, ced->dwDMAFlag, ced->sCurrentState, ced->bForceReset,
bTestBuff, bShortTest); bTestBuff, bShortTest);
if ((bTestBuff) && /* Buffer check requested, and... */ if ((bTestBuff) && /* Buffer check requested, and... */
(pdx->dwNumInput || pdx->dwNumOutput)) { /* ...characters were in the buffer? */ (ced->dwNumInput || ced->dwNumOutput)) { /* ...characters were in the buffer? */
bShortTest = false; /* Then do the full test */ bShortTest = false; /* Then do the full test */
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"%s: will reset as buffers not empty\n", __func__); "%s: will reset as buffers not empty\n", __func__);
} }
if (bShortTest || !bCanReset) { /* Still OK to try the short test? */ if (bShortTest || !bCanReset) { /* Still OK to try the short test? */
/* Always test if no reset - we want state update */ /* Always test if no reset - we want state update */
unsigned int state, error; unsigned int state, error;
dev_dbg(&pdx->interface->dev, "%s: ced_get_state\n", __func__); dev_dbg(&ced->interface->dev, "%s: ced_get_state\n", __func__);
if (ced_get_state(pdx, &state, &error) == U14ERR_NOERROR) { /* Check on the 1401 state */ if (ced_get_state(ced, &state, &error) == U14ERR_NOERROR) { /* Check on the 1401 state */
if ((state & 0xFF) == 0) /* If call worked, check the status value */ if ((state & 0xFF) == 0) /* If call worked, check the status value */
bRet = true; /* If that was zero, all is OK, no reset needed */ bRet = true; /* If that was zero, all is OK, no reset needed */
} }
} }
if (!bRet && bCanReset) { /* If all not OK, then */ if (!bRet && bCanReset) { /* If all not OK, then */
dev_info(&pdx->interface->dev, "%s: ced_is_1401 %d %d %d %d\n", dev_info(&ced->interface->dev, "%s: ced_is_1401 %d %d %d %d\n",
__func__, bShortTest, pdx->sCurrentState, bTestBuff, __func__, bShortTest, ced->sCurrentState, bTestBuff,
pdx->bForceReset); ced->bForceReset);
bRet = ced_is_1401(pdx); /* do full test */ bRet = ced_is_1401(ced); /* do full test */
} }
return bRet; return bRet;
...@@ -404,13 +404,13 @@ static bool ced_quick_check(DEVICE_EXTENSION *pdx, bool bTestBuff, bool bCanRese ...@@ -404,13 +404,13 @@ static bool ced_quick_check(DEVICE_EXTENSION *pdx, bool bTestBuff, bool bCanRese
** **
** Resets the 1401 and empties the i/o buffers ** Resets the 1401 and empties the i/o buffers
*****************************************************************************/ *****************************************************************************/
int ced_reset(DEVICE_EXTENSION *pdx) int ced_reset(struct ced_data *ced)
{ {
mutex_lock(&pdx->io_mutex); /* Protect disconnect from new i/o */ mutex_lock(&ced->io_mutex); /* Protect disconnect from new i/o */
dev_dbg(&pdx->interface->dev, "%s: About to call ced_quick_check\n", dev_dbg(&ced->interface->dev, "%s: About to call ced_quick_check\n",
__func__); __func__);
ced_quick_check(pdx, true, true); /* Check 1401, reset if not OK */ ced_quick_check(ced, true, true); /* Check 1401, reset if not OK */
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
return U14ERR_NOERROR; return U14ERR_NOERROR;
} }
...@@ -419,29 +419,29 @@ int ced_reset(DEVICE_EXTENSION *pdx) ...@@ -419,29 +419,29 @@ int ced_reset(DEVICE_EXTENSION *pdx)
** **
** Gets a single character from the 1401 ** Gets a single character from the 1401
****************************************************************************/ ****************************************************************************/
int ced_get_char(DEVICE_EXTENSION *pdx) int ced_get_char(struct ced_data *ced)
{ {
int iReturn = U14ERR_NOIN; /* assume we will get nothing */ int iReturn = U14ERR_NOIN; /* assume we will get nothing */
mutex_lock(&pdx->io_mutex); /* Protect disconnect from new i/o */ mutex_lock(&ced->io_mutex); /* Protect disconnect from new i/o */
dev_dbg(&pdx->interface->dev, "%s\n", __func__); dev_dbg(&ced->interface->dev, "%s\n", __func__);
ced_allowi(pdx); /* Make sure char reads are running */ ced_allowi(ced); /* Make sure char reads are running */
ced_send_chars(pdx); /* and send any buffered chars */ ced_send_chars(ced); /* and send any buffered chars */
spin_lock_irq(&pdx->charInLock); spin_lock_irq(&ced->charInLock);
if (pdx->dwNumInput > 0) { /* worth looking */ if (ced->dwNumInput > 0) { /* worth looking */
iReturn = pdx->inputBuffer[pdx->dwInBuffGet++]; iReturn = ced->inputBuffer[ced->dwInBuffGet++];
if (pdx->dwInBuffGet >= INBUF_SZ) if (ced->dwInBuffGet >= INBUF_SZ)
pdx->dwInBuffGet = 0; ced->dwInBuffGet = 0;
pdx->dwNumInput--; ced->dwNumInput--;
} else } else
iReturn = U14ERR_NOIN; /* no input data to read */ iReturn = U14ERR_NOIN; /* no input data to read */
spin_unlock_irq(&pdx->charInLock); spin_unlock_irq(&ced->charInLock);
ced_allowi(pdx); /* Make sure char reads are running */ ced_allowi(ced); /* Make sure char reads are running */
mutex_unlock(&pdx->io_mutex); /* Protect disconnect from new i/o */ mutex_unlock(&ced->io_mutex); /* Protect disconnect from new i/o */
return iReturn; return iReturn;
} }
...@@ -456,19 +456,19 @@ int ced_get_char(DEVICE_EXTENSION *pdx) ...@@ -456,19 +456,19 @@ int ced_get_char(DEVICE_EXTENSION *pdx)
** returns the count of characters (including the terminator, or 0 if none ** returns the count of characters (including the terminator, or 0 if none
** or a negative error code. ** or a negative error code.
****************************************************************************/ ****************************************************************************/
int ced_get_string(DEVICE_EXTENSION *pdx, char __user *pUser, int n) int ced_get_string(struct ced_data *ced, char __user *pUser, int n)
{ {
int nAvailable; /* character in the buffer */ int nAvailable; /* character in the buffer */
int iReturn = U14ERR_NOIN; int iReturn = U14ERR_NOIN;
if (n <= 0) if (n <= 0)
return -ENOMEM; return -ENOMEM;
mutex_lock(&pdx->io_mutex); /* Protect disconnect from new i/o */ mutex_lock(&ced->io_mutex); /* Protect disconnect from new i/o */
ced_allowi(pdx); /* Make sure char reads are running */ ced_allowi(ced); /* Make sure char reads are running */
ced_send_chars(pdx); /* and send any buffered chars */ ced_send_chars(ced); /* and send any buffered chars */
spin_lock_irq(&pdx->charInLock); spin_lock_irq(&ced->charInLock);
nAvailable = pdx->dwNumInput; /* characters available now */ nAvailable = ced->dwNumInput; /* characters available now */
if (nAvailable > n) /* read max of space in pUser... */ if (nAvailable > n) /* read max of space in pUser... */
nAvailable = n; /* ...or input characters */ nAvailable = n; /* ...or input characters */
...@@ -478,12 +478,12 @@ int ced_get_string(DEVICE_EXTENSION *pdx, char __user *pUser, int n) ...@@ -478,12 +478,12 @@ int ced_get_string(DEVICE_EXTENSION *pdx, char __user *pUser, int n)
int nCopyToUser; /* number to copy to user */ int nCopyToUser; /* number to copy to user */
char cData; char cData;
do { do {
cData = pdx->inputBuffer[pdx->dwInBuffGet++]; cData = ced->inputBuffer[ced->dwInBuffGet++];
if (cData == CR_CHAR) /* replace CR with zero */ if (cData == CR_CHAR) /* replace CR with zero */
cData = (char)0; cData = (char)0;
if (pdx->dwInBuffGet >= INBUF_SZ) if (ced->dwInBuffGet >= INBUF_SZ)
pdx->dwInBuffGet = 0; /* wrap buffer pointer */ ced->dwInBuffGet = 0; /* wrap buffer pointer */
buffer[nGot++] = cData; /* save the output */ buffer[nGot++] = cData; /* save the output */
} while ((nGot < nAvailable) && cData); } while ((nGot < nAvailable) && cData);
...@@ -495,20 +495,20 @@ int ced_get_string(DEVICE_EXTENSION *pdx, char __user *pUser, int n) ...@@ -495,20 +495,20 @@ int ced_get_string(DEVICE_EXTENSION *pdx, char __user *pUser, int n)
++nCopyToUser; /* ...copy the 0 as well. */ ++nCopyToUser; /* ...copy the 0 as well. */
} }
pdx->dwNumInput -= nGot; ced->dwNumInput -= nGot;
spin_unlock_irq(&pdx->charInLock); spin_unlock_irq(&ced->charInLock);
dev_dbg(&pdx->interface->dev, "%s: read %d characters >%s<\n", dev_dbg(&ced->interface->dev, "%s: read %d characters >%s<\n",
__func__, nGot, buffer); __func__, nGot, buffer);
if (copy_to_user(pUser, buffer, nCopyToUser)) if (copy_to_user(pUser, buffer, nCopyToUser))
iReturn = -EFAULT; iReturn = -EFAULT;
else else
iReturn = nGot; /* report characters read */ iReturn = nGot; /* report characters read */
} else } else
spin_unlock_irq(&pdx->charInLock); spin_unlock_irq(&ced->charInLock);
ced_allowi(pdx); /* Make sure char reads are running */ ced_allowi(ced); /* Make sure char reads are running */
mutex_unlock(&pdx->io_mutex); /* Protect disconnect from new i/o */ mutex_unlock(&ced->io_mutex); /* Protect disconnect from new i/o */
return iReturn; return iReturn;
} }
...@@ -516,14 +516,14 @@ int ced_get_string(DEVICE_EXTENSION *pdx, char __user *pUser, int n) ...@@ -516,14 +516,14 @@ int ced_get_string(DEVICE_EXTENSION *pdx, char __user *pUser, int n)
/******************************************************************************* /*******************************************************************************
** Get count of characters in the inout buffer. ** Get count of characters in the inout buffer.
*******************************************************************************/ *******************************************************************************/
int ced_stat_1401(DEVICE_EXTENSION *pdx) int ced_stat_1401(struct ced_data *ced)
{ {
int iReturn; int iReturn;
mutex_lock(&pdx->io_mutex); /* Protect disconnect from new i/o */ mutex_lock(&ced->io_mutex); /* Protect disconnect from new i/o */
ced_allowi(pdx); /* make sure we allow pending chars */ ced_allowi(ced); /* make sure we allow pending chars */
ced_send_chars(pdx); /* in both directions */ ced_send_chars(ced); /* in both directions */
iReturn = pdx->dwNumInput; /* no lock as single read */ iReturn = ced->dwNumInput; /* no lock as single read */
mutex_unlock(&pdx->io_mutex); /* Protect disconnect from new i/o */ mutex_unlock(&ced->io_mutex); /* Protect disconnect from new i/o */
return iReturn; return iReturn;
} }
...@@ -534,20 +534,20 @@ int ced_stat_1401(DEVICE_EXTENSION *pdx) ...@@ -534,20 +534,20 @@ int ced_stat_1401(DEVICE_EXTENSION *pdx)
** any fancy interlocks as we only read the interrupt routine data, and the ** any fancy interlocks as we only read the interrupt routine data, and the
** system is arranged so nothing can be destroyed. ** system is arranged so nothing can be destroyed.
****************************************************************************/ ****************************************************************************/
int ced_line_count(DEVICE_EXTENSION *pdx) int ced_line_count(struct ced_data *ced)
{ {
int iReturn = 0; /* will be count of line ends */ int iReturn = 0; /* will be count of line ends */
mutex_lock(&pdx->io_mutex); /* Protect disconnect from new i/o */ mutex_lock(&ced->io_mutex); /* Protect disconnect from new i/o */
ced_allowi(pdx); /* Make sure char reads are running */ ced_allowi(ced); /* Make sure char reads are running */
ced_send_chars(pdx); /* and send any buffered chars */ ced_send_chars(ced); /* and send any buffered chars */
spin_lock_irq(&pdx->charInLock); /* Get protection */ spin_lock_irq(&ced->charInLock); /* Get protection */
if (pdx->dwNumInput > 0) { /* worth looking? */ if (ced->dwNumInput > 0) { /* worth looking? */
unsigned int dwIndex = pdx->dwInBuffGet; /* start at first available */ unsigned int dwIndex = ced->dwInBuffGet; /* start at first available */
unsigned int dwEnd = pdx->dwInBuffPut; /* Position for search end */ unsigned int dwEnd = ced->dwInBuffPut; /* Position for search end */
do { do {
if (pdx->inputBuffer[dwIndex++] == CR_CHAR) if (ced->inputBuffer[dwIndex++] == CR_CHAR)
++iReturn; /* inc count if CR */ ++iReturn; /* inc count if CR */
if (dwIndex >= INBUF_SZ) /* see if we fall off buff */ if (dwIndex >= INBUF_SZ) /* see if we fall off buff */
...@@ -555,9 +555,9 @@ int ced_line_count(DEVICE_EXTENSION *pdx) ...@@ -555,9 +555,9 @@ int ced_line_count(DEVICE_EXTENSION *pdx)
} while (dwIndex != dwEnd); /* go to last available */ } while (dwIndex != dwEnd); /* go to last available */
} }
spin_unlock_irq(&pdx->charInLock); spin_unlock_irq(&ced->charInLock);
dev_dbg(&pdx->interface->dev, "%s: returned %d\n", __func__, iReturn); dev_dbg(&ced->interface->dev, "%s: returned %d\n", __func__, iReturn);
mutex_unlock(&pdx->io_mutex); /* Protect disconnect from new i/o */ mutex_unlock(&ced->io_mutex); /* Protect disconnect from new i/o */
return iReturn; return iReturn;
} }
...@@ -566,14 +566,14 @@ int ced_line_count(DEVICE_EXTENSION *pdx) ...@@ -566,14 +566,14 @@ int ced_line_count(DEVICE_EXTENSION *pdx)
** **
** Gets the space in the output buffer. Called from user code. ** Gets the space in the output buffer. Called from user code.
*****************************************************************************/ *****************************************************************************/
int ced_get_out_buf_space(DEVICE_EXTENSION *pdx) int ced_get_out_buf_space(struct ced_data *ced)
{ {
int iReturn; int iReturn;
mutex_lock(&pdx->io_mutex); /* Protect disconnect from new i/o */ mutex_lock(&ced->io_mutex); /* Protect disconnect from new i/o */
ced_send_chars(pdx); /* send any buffered chars */ ced_send_chars(ced); /* send any buffered chars */
iReturn = (int)(OUTBUF_SZ - pdx->dwNumOutput); /* no lock needed for single read */ iReturn = (int)(OUTBUF_SZ - ced->dwNumOutput); /* no lock needed for single read */
dev_dbg(&pdx->interface->dev, "%s: %d\n", __func__, iReturn); dev_dbg(&ced->interface->dev, "%s: %d\n", __func__, iReturn);
mutex_unlock(&pdx->io_mutex); /* Protect disconnect from new i/o */ mutex_unlock(&ced->io_mutex); /* Protect disconnect from new i/o */
return iReturn; return iReturn;
} }
...@@ -584,17 +584,17 @@ int ced_get_out_buf_space(DEVICE_EXTENSION *pdx) ...@@ -584,17 +584,17 @@ int ced_get_out_buf_space(DEVICE_EXTENSION *pdx)
** Clears up a transfer area. This is always called in the context of a user ** Clears up a transfer area. This is always called in the context of a user
** request, never from a call-back. ** request, never from a call-back.
****************************************************************************/ ****************************************************************************/
int ced_clear_area(DEVICE_EXTENSION *pdx, int nArea) int ced_clear_area(struct ced_data *ced, int nArea)
{ {
int iReturn = U14ERR_NOERROR; int iReturn = U14ERR_NOERROR;
if ((nArea < 0) || (nArea >= MAX_TRANSAREAS)) { if ((nArea < 0) || (nArea >= MAX_TRANSAREAS)) {
iReturn = U14ERR_BADAREA; iReturn = U14ERR_BADAREA;
dev_err(&pdx->interface->dev, "%s: Attempt to clear area %d\n", dev_err(&ced->interface->dev, "%s: Attempt to clear area %d\n",
__func__, nArea); __func__, nArea);
} else { } else {
/* to save typing */ /* to save typing */
struct transarea *pTA = &pdx->rTransDef[nArea]; struct transarea *pTA = &ced->rTransDef[nArea];
if (!pTA->bUsed) /* if not used... */ if (!pTA->bUsed) /* if not used... */
iReturn = U14ERR_NOTSET; /* ...nothing to be done */ iReturn = U14ERR_NOTSET; /* ...nothing to be done */
else { else {
...@@ -604,13 +604,13 @@ int ced_clear_area(DEVICE_EXTENSION *pdx, int nArea) ...@@ -604,13 +604,13 @@ int ced_clear_area(DEVICE_EXTENSION *pdx, int nArea)
int nPages = 0; /* and number of pages */ int nPages = 0; /* and number of pages */
int np; int np;
dev_dbg(&pdx->interface->dev, "%s: area %d\n", dev_dbg(&ced->interface->dev, "%s: area %d\n",
__func__, nArea); __func__, nArea);
spin_lock_irq(&pdx->stagedLock); spin_lock_irq(&ced->stagedLock);
if ((pdx->StagedId == nArea) if ((ced->StagedId == nArea)
&& (pdx->dwDMAFlag > MODE_CHAR)) { && (ced->dwDMAFlag > MODE_CHAR)) {
iReturn = U14ERR_UNLOCKFAIL; /* cannot delete as in use */ iReturn = U14ERR_UNLOCKFAIL; /* cannot delete as in use */
dev_err(&pdx->interface->dev, dev_err(&ced->interface->dev,
"%s: call on area %d while active\n", "%s: call on area %d while active\n",
__func__, nArea); __func__, nArea);
} else { } else {
...@@ -619,9 +619,9 @@ int ced_clear_area(DEVICE_EXTENSION *pdx, int nArea) ...@@ -619,9 +619,9 @@ int ced_clear_area(DEVICE_EXTENSION *pdx, int nArea)
if (pTA->dwEventSz) /* if events flagging in use */ if (pTA->dwEventSz) /* if events flagging in use */
wake_up_interruptible(&pTA->wqEvent); /* release anything that was waiting */ wake_up_interruptible(&pTA->wqEvent); /* release anything that was waiting */
if (pdx->bXFerWaiting if (ced->bXFerWaiting
&& (pdx->rDMAInfo.wIdent == nArea)) && (ced->rDMAInfo.wIdent == nArea))
pdx->bXFerWaiting = false; /* Cannot have pending xfer if area cleared */ ced->bXFerWaiting = false; /* Cannot have pending xfer if area cleared */
/* Clean out the struct transarea except for the wait queue, which is at the end */ /* Clean out the struct 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. */ /* This sets bUsed to false and dwEventSz to 0 to say area not used and no events. */
...@@ -629,13 +629,13 @@ int ced_clear_area(DEVICE_EXTENSION *pdx, int nArea) ...@@ -629,13 +629,13 @@ int ced_clear_area(DEVICE_EXTENSION *pdx, int nArea)
sizeof(struct transarea) - sizeof(struct transarea) -
sizeof(wait_queue_head_t)); sizeof(wait_queue_head_t));
} }
spin_unlock_irq(&pdx->stagedLock); spin_unlock_irq(&ced->stagedLock);
if (pPages) { /* if we decided to release the memory */ 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 */ /* 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 */ /* 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. */ /* holding a spin lock to do this stuff as it is not atomic. */
dev_dbg(&pdx->interface->dev, "%s: nPages=%d\n", dev_dbg(&ced->interface->dev, "%s: nPages=%d\n",
__func__, nPages); __func__, nPages);
for (np = 0; np < nPages; ++np) { for (np = 0; np < nPages; ++np) {
...@@ -646,7 +646,7 @@ int ced_clear_area(DEVICE_EXTENSION *pdx, int nArea) ...@@ -646,7 +646,7 @@ int ced_clear_area(DEVICE_EXTENSION *pdx, int nArea)
} }
kfree(pPages); kfree(pPages);
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"%s: kfree(pPages) done\n", __func__); "%s: kfree(pPages) done\n", __func__);
} }
} }
...@@ -661,7 +661,7 @@ int ced_clear_area(DEVICE_EXTENSION *pdx, int nArea) ...@@ -661,7 +661,7 @@ int ced_clear_area(DEVICE_EXTENSION *pdx, int nArea)
** Sets up a transfer area - the functional part. Called by both ** Sets up a transfer area - the functional part. Called by both
** ced_set_transfer and ced_set_circular. ** ced_set_transfer and ced_set_circular.
****************************************************************************/ ****************************************************************************/
static int ced_set_area(DEVICE_EXTENSION *pdx, int nArea, char __user *puBuf, static int ced_set_area(struct ced_data *ced, int nArea, char __user *puBuf,
unsigned int dwLength, bool bCircular, bool bCircToHost) unsigned int dwLength, bool bCircular, bool bCircToHost)
{ {
/* Start by working out the page aligned start of the area and the size */ /* Start by working out the page aligned start of the area and the size */
...@@ -671,11 +671,11 @@ static int ced_set_area(DEVICE_EXTENSION *pdx, int nArea, char __user *puBuf, ...@@ -671,11 +671,11 @@ static int ced_set_area(DEVICE_EXTENSION *pdx, int nArea, char __user *puBuf,
unsigned int ulOffset = ((unsigned long)puBuf) & (PAGE_SIZE - 1); unsigned int ulOffset = ((unsigned long)puBuf) & (PAGE_SIZE - 1);
int len = (dwLength + ulOffset + PAGE_SIZE - 1) >> PAGE_SHIFT; int len = (dwLength + ulOffset + PAGE_SIZE - 1) >> PAGE_SHIFT;
struct transarea *pTA = &pdx->rTransDef[nArea]; /* to save typing */ struct transarea *pTA = &ced->rTransDef[nArea]; /* to save typing */
struct page **pPages = NULL; /* space for page tables */ struct page **pPages = NULL; /* space for page tables */
int nPages = 0; /* and number of pages */ int nPages = 0; /* and number of pages */
int iReturn = ced_clear_area(pdx, nArea); /* see if OK to use this area */ int iReturn = ced_clear_area(ced, nArea); /* see if OK to use this area */
if ((iReturn != U14ERR_NOTSET) && /* if not area unused and... */ if ((iReturn != U14ERR_NOTSET) && /* if not area unused and... */
(iReturn != U14ERR_NOERROR)) /* ...not all OK, then... */ (iReturn != U14ERR_NOERROR)) /* ...not all OK, then... */
return iReturn; /* ...we cannot use this area */ return iReturn; /* ...we cannot use this area */
...@@ -689,18 +689,18 @@ static int ced_set_area(DEVICE_EXTENSION *pdx, int nArea, char __user *puBuf, ...@@ -689,18 +689,18 @@ static int ced_set_area(DEVICE_EXTENSION *pdx, int nArea, char __user *puBuf,
iReturn = U14ERR_NOMEMORY; iReturn = U14ERR_NOMEMORY;
goto error; goto error;
} }
dev_dbg(&pdx->interface->dev, "%s: %p, length=%06x, circular %d\n", dev_dbg(&ced->interface->dev, "%s: %p, length=%06x, circular %d\n",
__func__, puBuf, dwLength, bCircular); __func__, puBuf, dwLength, bCircular);
/* To pin down user pages we must first acquire the mapping semaphore. */ /* To pin down user pages we must first acquire the mapping semaphore. */
nPages = get_user_pages_fast(ulStart, len, 1, pPages); nPages = get_user_pages_fast(ulStart, len, 1, pPages);
dev_dbg(&pdx->interface->dev, "%s: nPages = %d\n", __func__, nPages); dev_dbg(&ced->interface->dev, "%s: nPages = %d\n", __func__, nPages);
if (nPages > 0) { /* if we succeeded */ if (nPages > 0) { /* if we succeeded */
/* If you are tempted to use page_address (form LDD3), forget it. You MUST use */ /* 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 */ /* 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. */ /* (null) or at least it does in this context with an x86 machine. */
spin_lock_irq(&pdx->stagedLock); spin_lock_irq(&ced->stagedLock);
pTA->lpvBuff = puBuf; /* keep start of region (user address) */ pTA->lpvBuff = puBuf; /* keep start of region (user address) */
pTA->dwBaseOffset = ulOffset; /* save offset in first page to start of xfer */ pTA->dwBaseOffset = ulOffset; /* save offset in first page to start of xfer */
pTA->dwLength = dwLength; /* Size if the region in bytes */ pTA->dwLength = dwLength; /* Size if the region in bytes */
...@@ -716,7 +716,7 @@ static int ced_set_area(DEVICE_EXTENSION *pdx, int nArea, char __user *puBuf, ...@@ -716,7 +716,7 @@ static int ced_set_area(DEVICE_EXTENSION *pdx, int nArea, char __user *puBuf,
pTA->aBlocks[1].dwSize = 0; pTA->aBlocks[1].dwSize = 0;
pTA->bUsed = true; /* This is now a used block */ pTA->bUsed = true; /* This is now a used block */
spin_unlock_irq(&pdx->stagedLock); spin_unlock_irq(&ced->stagedLock);
iReturn = U14ERR_NOERROR; /* say all was well */ iReturn = U14ERR_NOERROR; /* say all was well */
} else { } else {
iReturn = U14ERR_LOCKFAIL; iReturn = U14ERR_LOCKFAIL;
...@@ -737,7 +737,7 @@ static int ced_set_area(DEVICE_EXTENSION *pdx, int nArea, char __user *puBuf, ...@@ -737,7 +737,7 @@ static int ced_set_area(DEVICE_EXTENSION *pdx, int nArea, char __user *puBuf,
** unset it. Unsetting will fail if the area is booked, and a transfer to that ** 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. ** area is in progress. Otherwise, we will release the area and re-assign it.
****************************************************************************/ ****************************************************************************/
int ced_set_transfer(DEVICE_EXTENSION *pdx, struct transfer_area_desc __user *pTD) int ced_set_transfer(struct ced_data *ced, struct transfer_area_desc __user *pTD)
{ {
int iReturn; int iReturn;
struct transfer_area_desc td; struct transfer_area_desc td;
...@@ -745,17 +745,17 @@ int ced_set_transfer(DEVICE_EXTENSION *pdx, struct transfer_area_desc __user *pT ...@@ -745,17 +745,17 @@ int ced_set_transfer(DEVICE_EXTENSION *pdx, struct transfer_area_desc __user *pT
if (copy_from_user(&td, pTD, sizeof(td))) if (copy_from_user(&td, pTD, sizeof(td)))
return -EFAULT; return -EFAULT;
mutex_lock(&pdx->io_mutex); mutex_lock(&ced->io_mutex);
dev_dbg(&pdx->interface->dev, "%s: area:%d, size:%08x\n", dev_dbg(&ced->interface->dev, "%s: area:%d, size:%08x\n",
__func__, td.wAreaNum, td.dwLength); __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 */ /* 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 */ /* 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. */ /* a 32-bit program on a 64-bit system. unsigned long is 64-bits on a 64-bit system. */
iReturn = iReturn =
ced_set_area(pdx, td.wAreaNum, ced_set_area(ced, td.wAreaNum,
(char __user *)((unsigned long)td.lpvBuff), td.dwLength, (char __user *)((unsigned long)td.lpvBuff), td.dwLength,
false, false); false, false);
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
return iReturn; return iReturn;
} }
...@@ -763,12 +763,12 @@ int ced_set_transfer(DEVICE_EXTENSION *pdx, struct transfer_area_desc __user *pT ...@@ -763,12 +763,12 @@ int ced_set_transfer(DEVICE_EXTENSION *pdx, struct transfer_area_desc __user *pT
** UnSetTransfer ** UnSetTransfer
** Erases a transfer area record ** Erases a transfer area record
****************************************************************************/ ****************************************************************************/
int ced_unset_transfer(DEVICE_EXTENSION *pdx, int nArea) int ced_unset_transfer(struct ced_data *ced, int nArea)
{ {
int iReturn; int iReturn;
mutex_lock(&pdx->io_mutex); mutex_lock(&ced->io_mutex);
iReturn = ced_clear_area(pdx, nArea); iReturn = ced_clear_area(ced, nArea);
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
return iReturn; return iReturn;
} }
...@@ -780,7 +780,7 @@ int ced_unset_transfer(DEVICE_EXTENSION *pdx, int nArea) ...@@ -780,7 +780,7 @@ int ced_unset_transfer(DEVICE_EXTENSION *pdx, int nArea)
** pretend that whatever the user asked for was achieved, so we return 1 if ** 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). ** try to create one, and 0 if they ask to remove (assuming all else was OK).
****************************************************************************/ ****************************************************************************/
int ced_set_event(DEVICE_EXTENSION *pdx, struct transfer_event __user *pTE) int ced_set_event(struct ced_data *ced, struct transfer_event __user *pTE)
{ {
int iReturn = U14ERR_NOERROR; int iReturn = U14ERR_NOERROR;
struct transfer_event te; struct transfer_event te;
...@@ -792,9 +792,9 @@ int ced_set_event(DEVICE_EXTENSION *pdx, struct transfer_event __user *pTE) ...@@ -792,9 +792,9 @@ int ced_set_event(DEVICE_EXTENSION *pdx, struct transfer_event __user *pTE)
if (te.wAreaNum >= MAX_TRANSAREAS) /* the area must exist */ if (te.wAreaNum >= MAX_TRANSAREAS) /* the area must exist */
return U14ERR_BADAREA; return U14ERR_BADAREA;
else { else {
struct transarea *pTA = &pdx->rTransDef[te.wAreaNum]; struct transarea *pTA = &ced->rTransDef[te.wAreaNum];
mutex_lock(&pdx->io_mutex); /* make sure we have no competitor */ mutex_lock(&ced->io_mutex); /* make sure we have no competitor */
spin_lock_irq(&pdx->stagedLock); spin_lock_irq(&ced->stagedLock);
if (pTA->bUsed) { /* area must be in use */ if (pTA->bUsed) { /* area must be in use */
pTA->dwEventSt = te.dwStart; /* set area regions */ pTA->dwEventSt = te.dwStart; /* set area regions */
pTA->dwEventSz = te.dwLength; /* set size (0 cancels it) */ pTA->dwEventSz = te.dwLength; /* set size (0 cancels it) */
...@@ -802,8 +802,8 @@ int ced_set_event(DEVICE_EXTENSION *pdx, struct transfer_event __user *pTE) ...@@ -802,8 +802,8 @@ int ced_set_event(DEVICE_EXTENSION *pdx, struct transfer_event __user *pTE)
pTA->iWakeUp = 0; /* zero the wake up count */ pTA->iWakeUp = 0; /* zero the wake up count */
} else } else
iReturn = U14ERR_NOTSET; iReturn = U14ERR_NOTSET;
spin_unlock_irq(&pdx->stagedLock); spin_unlock_irq(&ced->stagedLock);
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
} }
return iReturn == return iReturn ==
U14ERR_NOERROR ? (te.iSetEvent ? 1 : U14ERR_NOERROR) : iReturn; U14ERR_NOERROR ? (te.iSetEvent ? 1 : U14ERR_NOERROR) : iReturn;
...@@ -815,24 +815,24 @@ int ced_set_event(DEVICE_EXTENSION *pdx, struct transfer_event __user *pTE) ...@@ -815,24 +815,24 @@ int ced_set_event(DEVICE_EXTENSION *pdx, struct transfer_event __user *pTE)
** of times that a block met the event condition since we last cleared it or ** 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). ** 0 if timed out, or -ve error (bad area or not set, or signal).
****************************************************************************/ ****************************************************************************/
int ced_wait_event(DEVICE_EXTENSION *pdx, int nArea, int msTimeOut) int ced_wait_event(struct ced_data *ced, int nArea, int msTimeOut)
{ {
int iReturn; int iReturn;
if ((unsigned)nArea >= MAX_TRANSAREAS) if ((unsigned)nArea >= MAX_TRANSAREAS)
return U14ERR_BADAREA; return U14ERR_BADAREA;
else { else {
int iWait; int iWait;
struct transarea *pTA = &pdx->rTransDef[nArea]; struct transarea *pTA = &ced->rTransDef[nArea];
msTimeOut = (msTimeOut * HZ + 999) / 1000; /* convert timeout to jiffies */ msTimeOut = (msTimeOut * HZ + 999) / 1000; /* convert timeout to jiffies */
/* We cannot wait holding the mutex, but we check the flags while holding */ /* 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 */ /* 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 */ /* 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. */ /* iWakeUp flag. However, the !pTA-bUsed may help us in this case. */
mutex_lock(&pdx->io_mutex); /* make sure we have no competitor */ mutex_lock(&ced->io_mutex); /* make sure we have no competitor */
if (!pTA->bUsed || !pTA->dwEventSz) /* check something to wait for... */ if (!pTA->bUsed || !pTA->dwEventSz) /* check something to wait for... */
return U14ERR_NOTSET; /* ...else we do nothing */ return U14ERR_NOTSET; /* ...else we do nothing */
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
if (msTimeOut) if (msTimeOut)
iWait = iWait =
...@@ -849,9 +849,9 @@ int ced_wait_event(DEVICE_EXTENSION *pdx, int nArea, int msTimeOut) ...@@ -849,9 +849,9 @@ int ced_wait_event(DEVICE_EXTENSION *pdx, int nArea, int msTimeOut)
else else
iReturn = pTA->iWakeUp; /* else the wakeup count */ iReturn = pTA->iWakeUp; /* else the wakeup count */
spin_lock_irq(&pdx->stagedLock); spin_lock_irq(&ced->stagedLock);
pTA->iWakeUp = 0; /* clear the flag */ pTA->iWakeUp = 0; /* clear the flag */
spin_unlock_irq(&pdx->stagedLock); spin_unlock_irq(&ced->stagedLock);
} }
return iReturn; return iReturn;
} }
...@@ -862,19 +862,19 @@ int ced_wait_event(DEVICE_EXTENSION *pdx, int nArea, int msTimeOut) ...@@ -862,19 +862,19 @@ int ced_wait_event(DEVICE_EXTENSION *pdx, int nArea, int msTimeOut)
** number of times a block completed since the last call, or 0 if none or a ** number of times a block completed since the last call, or 0 if none or a
** negative error. ** negative error.
****************************************************************************/ ****************************************************************************/
int ced_test_event(DEVICE_EXTENSION *pdx, int nArea) int ced_test_event(struct ced_data *ced, int nArea)
{ {
int iReturn; int iReturn;
if ((unsigned)nArea >= MAX_TRANSAREAS) if ((unsigned)nArea >= MAX_TRANSAREAS)
iReturn = U14ERR_BADAREA; iReturn = U14ERR_BADAREA;
else { else {
struct transarea *pTA = &pdx->rTransDef[nArea]; struct transarea *pTA = &ced->rTransDef[nArea];
mutex_lock(&pdx->io_mutex); /* make sure we have no competitor */ mutex_lock(&ced->io_mutex); /* make sure we have no competitor */
spin_lock_irq(&pdx->stagedLock); spin_lock_irq(&ced->stagedLock);
iReturn = pTA->iWakeUp; /* get wakeup count since last call */ iReturn = pTA->iWakeUp; /* get wakeup count since last call */
pTA->iWakeUp = 0; /* clear the count */ pTA->iWakeUp = 0; /* clear the count */
spin_unlock_irq(&pdx->stagedLock); spin_unlock_irq(&ced->stagedLock);
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
} }
return iReturn; return iReturn;
} }
...@@ -883,13 +883,13 @@ int ced_test_event(DEVICE_EXTENSION *pdx, int nArea) ...@@ -883,13 +883,13 @@ int ced_test_event(DEVICE_EXTENSION *pdx, int nArea)
** ced_get_transferInfo ** ced_get_transferInfo
** Puts the current state of the 1401 in a TGET_TX_BLOCK. ** Puts the current state of the 1401 in a TGET_TX_BLOCK.
*****************************************************************************/ *****************************************************************************/
int ced_get_transfer(DEVICE_EXTENSION *pdx, TGET_TX_BLOCK __user *pTX) int ced_get_transfer(struct ced_data *ced, TGET_TX_BLOCK __user *pTX)
{ {
int iReturn = U14ERR_NOERROR; int iReturn = U14ERR_NOERROR;
unsigned int dwIdent; unsigned int dwIdent;
mutex_lock(&pdx->io_mutex); mutex_lock(&ced->io_mutex);
dwIdent = pdx->StagedId; /* area ident for last xfer */ dwIdent = ced->StagedId; /* area ident for last xfer */
if (dwIdent >= MAX_TRANSAREAS) if (dwIdent >= MAX_TRANSAREAS)
iReturn = U14ERR_BADAREA; iReturn = U14ERR_BADAREA;
else { else {
...@@ -898,22 +898,22 @@ int ced_get_transfer(DEVICE_EXTENSION *pdx, TGET_TX_BLOCK __user *pTX) ...@@ -898,22 +898,22 @@ int ced_get_transfer(DEVICE_EXTENSION *pdx, TGET_TX_BLOCK __user *pTX)
tx = kzalloc(sizeof(*tx), GFP_KERNEL); tx = kzalloc(sizeof(*tx), GFP_KERNEL);
if (!tx) { if (!tx) {
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
return -ENOMEM; return -ENOMEM;
} }
tx->size = pdx->rTransDef[dwIdent].dwLength; tx->size = ced->rTransDef[dwIdent].dwLength;
tx->linear = (long long)((long)pdx->rTransDef[dwIdent].lpvBuff); tx->linear = (long long)((long)ced->rTransDef[dwIdent].lpvBuff);
tx->avail = GET_TX_MAXENTRIES; /* how many blocks we could return */ tx->avail = GET_TX_MAXENTRIES; /* how many blocks we could return */
tx->used = 1; /* number we actually return */ tx->used = 1; /* number we actually return */
tx->entries[0].physical = tx->entries[0].physical =
(long long)(tx->linear + pdx->StagedOffset); (long long)(tx->linear + ced->StagedOffset);
tx->entries[0].size = tx->size; tx->entries[0].size = tx->size;
if (copy_to_user(pTX, tx, sizeof(*tx))) if (copy_to_user(pTX, tx, sizeof(*tx)))
iReturn = -EFAULT; iReturn = -EFAULT;
kfree(tx); kfree(tx);
} }
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
return iReturn; return iReturn;
} }
...@@ -922,13 +922,13 @@ int ced_get_transfer(DEVICE_EXTENSION *pdx, TGET_TX_BLOCK __user *pTX) ...@@ -922,13 +922,13 @@ int ced_get_transfer(DEVICE_EXTENSION *pdx, TGET_TX_BLOCK __user *pTX)
** **
** Empties the host i/o buffers ** Empties the host i/o buffers
****************************************************************************/ ****************************************************************************/
int ced_kill_io(DEVICE_EXTENSION *pdx) int ced_kill_io(struct ced_data *ced)
{ {
dev_dbg(&pdx->interface->dev, "%s\n", __func__); dev_dbg(&ced->interface->dev, "%s\n", __func__);
mutex_lock(&pdx->io_mutex); mutex_lock(&ced->io_mutex);
ced_flush_out_buff(pdx); ced_flush_out_buff(ced);
ced_flush_in_buff(pdx); ced_flush_in_buff(ced);
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
return U14ERR_NOERROR; return U14ERR_NOERROR;
} }
...@@ -937,16 +937,16 @@ int ced_kill_io(DEVICE_EXTENSION *pdx) ...@@ -937,16 +937,16 @@ int ced_kill_io(DEVICE_EXTENSION *pdx)
** **
** Puts the current state of the 1401 in the Irp return buffer. ** Puts the current state of the 1401 in the Irp return buffer.
*****************************************************************************/ *****************************************************************************/
int ced_state_of_1401(DEVICE_EXTENSION *pdx) int ced_state_of_1401(struct ced_data *ced)
{ {
int iReturn; int iReturn;
mutex_lock(&pdx->io_mutex); mutex_lock(&ced->io_mutex);
ced_quick_check(pdx, false, false); /* get state up to date, no reset */ ced_quick_check(ced, false, false); /* get state up to date, no reset */
iReturn = pdx->sCurrentState; iReturn = ced->sCurrentState;
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
dev_dbg(&pdx->interface->dev, "%s: %d\n", __func__, iReturn); dev_dbg(&ced->interface->dev, "%s: %d\n", __func__, iReturn);
return iReturn; return iReturn;
} }
...@@ -957,27 +957,27 @@ int ced_state_of_1401(DEVICE_EXTENSION *pdx) ...@@ -957,27 +957,27 @@ int ced_state_of_1401(DEVICE_EXTENSION *pdx)
** Initiates a self-test cycle. The assumption is that we have no interrupts ** Initiates a self-test cycle. The assumption is that we have no interrupts
** active, so we should make sure that this is the case. ** active, so we should make sure that this is the case.
*****************************************************************************/ *****************************************************************************/
int ced_start_self_test(DEVICE_EXTENSION *pdx) int ced_start_self_test(struct ced_data *ced)
{ {
int nGot; int nGot;
mutex_lock(&pdx->io_mutex); mutex_lock(&ced->io_mutex);
dev_dbg(&pdx->interface->dev, "%s\n", __func__); dev_dbg(&ced->interface->dev, "%s\n", __func__);
ced_draw_down(pdx); /* wait for, then kill outstanding Urbs */ ced_draw_down(ced); /* wait for, then kill outstanding Urbs */
ced_flush_in_buff(pdx); /* Clear out input buffer & pipe */ ced_flush_in_buff(ced); /* Clear out input buffer & pipe */
ced_flush_out_buff(pdx); /* Clear output buffer & pipe */ ced_flush_out_buff(ced); /* Clear output buffer & pipe */
/* so things stay tidy */ /* so things stay tidy */
/* ced_read_write_cancel(pDeviceObject); */ /* ced_read_write_cancel(pDeviceObject); */
pdx->dwDMAFlag = MODE_CHAR; /* Clear DMA mode flags here */ ced->dwDMAFlag = MODE_CHAR; /* Clear DMA mode flags here */
nGot = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0), nGot = usb_control_msg(ced->udev, usb_rcvctrlpipe(ced->udev, 0),
DB_SELFTEST, (H_TO_D | VENDOR | DEVREQ), DB_SELFTEST, (H_TO_D | VENDOR | DEVREQ),
0, 0, NULL, 0, HZ); /* allow 1 second timeout */ 0, 0, NULL, 0, HZ); /* allow 1 second timeout */
pdx->ulSelfTestTime = jiffies + HZ * 30; /* 30 seconds into the future */ ced->ulSelfTestTime = jiffies + HZ * 30; /* 30 seconds into the future */
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
if (nGot < 0) if (nGot < 0)
dev_err(&pdx->interface->dev, "%s: err=%d\n", __func__, nGot); dev_err(&ced->interface->dev, "%s: err=%d\n", __func__, nGot);
return nGot < 0 ? U14ERR_FAIL : U14ERR_NOERROR; return nGot < 0 ? U14ERR_FAIL : U14ERR_NOERROR;
} }
...@@ -986,23 +986,23 @@ int ced_start_self_test(DEVICE_EXTENSION *pdx) ...@@ -986,23 +986,23 @@ int ced_start_self_test(DEVICE_EXTENSION *pdx)
** **
** Check progress of a self-test cycle ** Check progress of a self-test cycle
****************************************************************************/ ****************************************************************************/
int ced_check_self_test(DEVICE_EXTENSION *pdx, TGET_SELFTEST __user *pGST) int ced_check_self_test(struct ced_data *ced, TGET_SELFTEST __user *pGST)
{ {
unsigned int state, error; unsigned int state, error;
int iReturn; int iReturn;
TGET_SELFTEST gst; /* local work space */ TGET_SELFTEST gst; /* local work space */
memset(&gst, 0, sizeof(gst)); /* clear out the space (sets code 0) */ memset(&gst, 0, sizeof(gst)); /* clear out the space (sets code 0) */
mutex_lock(&pdx->io_mutex); mutex_lock(&ced->io_mutex);
dev_dbg(&pdx->interface->dev, "%s\n", __func__); dev_dbg(&ced->interface->dev, "%s\n", __func__);
iReturn = ced_get_state(pdx, &state, &error); iReturn = ced_get_state(ced, &state, &error);
if (iReturn == U14ERR_NOERROR) /* Only accept zero if it happens twice */ if (iReturn == U14ERR_NOERROR) /* Only accept zero if it happens twice */
iReturn = ced_get_state(pdx, &state, &error); iReturn = ced_get_state(ced, &state, &error);
if (iReturn != U14ERR_NOERROR) { /* Self-test can cause comms errors */ if (iReturn != U14ERR_NOERROR) { /* Self-test can cause comms errors */
/* so we assume still testing */ /* so we assume still testing */
dev_err(&pdx->interface->dev, dev_err(&ced->interface->dev,
"%s: ced_get_state=%d, assuming still testing\n", "%s: ced_get_state=%d, assuming still testing\n",
__func__, iReturn); __func__, iReturn);
state = 0x80; /* Force still-testing, no error */ state = 0x80; /* Force still-testing, no error */
...@@ -1011,7 +1011,7 @@ int ced_check_self_test(DEVICE_EXTENSION *pdx, TGET_SELFTEST __user *pGST) ...@@ -1011,7 +1011,7 @@ int ced_check_self_test(DEVICE_EXTENSION *pdx, TGET_SELFTEST __user *pGST)
} }
if ((state == -1) && (error == -1)) { /* If ced_get_state had problems */ if ((state == -1) && (error == -1)) { /* If ced_get_state had problems */
dev_err(&pdx->interface->dev, dev_err(&ced->interface->dev,
"%s: ced_get_state failed, assuming still testing\n", "%s: ced_get_state failed, assuming still testing\n",
__func__); __func__);
state = 0x80; /* Force still-testing, no error */ state = 0x80; /* Force still-testing, no error */
...@@ -1023,31 +1023,31 @@ int ced_check_self_test(DEVICE_EXTENSION *pdx, TGET_SELFTEST __user *pGST) ...@@ -1023,31 +1023,31 @@ int ced_check_self_test(DEVICE_EXTENSION *pdx, TGET_SELFTEST __user *pGST)
gst.code = (state & 0x00FF0000) >> 16; /* read the error code */ gst.code = (state & 0x00FF0000) >> 16; /* read the error code */
gst.x = error & 0x0000FFFF; /* Error data X */ gst.x = error & 0x0000FFFF; /* Error data X */
gst.y = (error & 0xFFFF0000) >> 16; /* and data Y */ gst.y = (error & 0xFFFF0000) >> 16; /* and data Y */
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"Self-test error code %d\n", gst.code); "Self-test error code %d\n", gst.code);
} else { /* No error, check for timeout */ } else { /* No error, check for timeout */
unsigned long ulNow = jiffies; /* get current time */ unsigned long ulNow = jiffies; /* get current time */
if (time_after(ulNow, pdx->ulSelfTestTime)) { if (time_after(ulNow, ced->ulSelfTestTime)) {
gst.code = -2; /* Flag the timeout */ gst.code = -2; /* Flag the timeout */
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"Self-test timed-out\n"); "Self-test timed-out\n");
} else } else
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"Self-test on-going\n"); "Self-test on-going\n");
} }
} else { } else {
gst.code = -1; /* Flag the test is done */ gst.code = -1; /* Flag the test is done */
dev_dbg(&pdx->interface->dev, "Self-test done\n"); dev_dbg(&ced->interface->dev, "Self-test done\n");
} }
if (gst.code < 0) { /* If we have a problem or finished */ if (gst.code < 0) { /* If we have a problem or finished */
/* If using the 2890 we should reset properly */ /* If using the 2890 we should reset properly */
if ((pdx->nPipes == 4) && (pdx->s1401Type <= TYPEPOWER)) if ((ced->nPipes == 4) && (ced->s1401Type <= TYPEPOWER))
ced_is_1401(pdx); /* Get 1401 reset and OK */ ced_is_1401(ced); /* Get 1401 reset and OK */
else else
ced_quick_check(pdx, true, true); /* Otherwise check without reset unless problems */ ced_quick_check(ced, true, true); /* Otherwise check without reset unless problems */
} }
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
if (copy_to_user(pGST, &gst, sizeof(gst))) if (copy_to_user(pGST, &gst, sizeof(gst)))
return -EFAULT; return -EFAULT;
...@@ -1060,13 +1060,13 @@ int ced_check_self_test(DEVICE_EXTENSION *pdx, TGET_SELFTEST __user *pGST) ...@@ -1060,13 +1060,13 @@ int ced_check_self_test(DEVICE_EXTENSION *pdx, TGET_SELFTEST __user *pGST)
** **
** Returns code for standard, plus, micro1401, power1401 or none ** Returns code for standard, plus, micro1401, power1401 or none
****************************************************************************/ ****************************************************************************/
int ced_type_of_1401(DEVICE_EXTENSION *pdx) int ced_type_of_1401(struct ced_data *ced)
{ {
int iReturn = TYPEUNKNOWN; int iReturn = TYPEUNKNOWN;
mutex_lock(&pdx->io_mutex); mutex_lock(&ced->io_mutex);
dev_dbg(&pdx->interface->dev, "%s\n", __func__); dev_dbg(&ced->interface->dev, "%s\n", __func__);
switch (pdx->s1401Type) { switch (ced->s1401Type) {
case TYPE1401: case TYPE1401:
iReturn = U14ERR_STD; iReturn = U14ERR_STD;
break; /* Handle these types directly */ break; /* Handle these types directly */
...@@ -1077,13 +1077,13 @@ int ced_type_of_1401(DEVICE_EXTENSION *pdx) ...@@ -1077,13 +1077,13 @@ int ced_type_of_1401(DEVICE_EXTENSION *pdx)
iReturn = U14ERR_U1401; iReturn = U14ERR_U1401;
break; break;
default: default:
if ((pdx->s1401Type >= TYPEPOWER) && (pdx->s1401Type <= 25)) if ((ced->s1401Type >= TYPEPOWER) && (ced->s1401Type <= 25))
iReturn = pdx->s1401Type + 4; /* We can calculate types */ iReturn = ced->s1401Type + 4; /* We can calculate types */
else /* for up-coming 1401 designs */ else /* for up-coming 1401 designs */
iReturn = TYPEUNKNOWN; /* Don't know or not there */ iReturn = TYPEUNKNOWN; /* Don't know or not there */
} }
dev_dbg(&pdx->interface->dev, "%s %d\n", __func__, iReturn); dev_dbg(&ced->interface->dev, "%s %d\n", __func__, iReturn);
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
return iReturn; return iReturn;
} }
...@@ -1093,15 +1093,15 @@ int ced_type_of_1401(DEVICE_EXTENSION *pdx) ...@@ -1093,15 +1093,15 @@ int ced_type_of_1401(DEVICE_EXTENSION *pdx)
** **
** Returns flags on block transfer abilities ** Returns flags on block transfer abilities
****************************************************************************/ ****************************************************************************/
int ced_transfer_flags(DEVICE_EXTENSION *pdx) int ced_transfer_flags(struct ced_data *ced)
{ {
int iReturn = U14TF_MULTIA | U14TF_DIAG | /* we always have multiple DMA area */ int iReturn = U14TF_MULTIA | U14TF_DIAG | /* we always have multiple DMA area */
U14TF_NOTIFY | U14TF_CIRCTH; /* diagnostics, notify and circular */ U14TF_NOTIFY | U14TF_CIRCTH; /* diagnostics, notify and circular */
dev_dbg(&pdx->interface->dev, "%s\n", __func__); dev_dbg(&ced->interface->dev, "%s\n", __func__);
mutex_lock(&pdx->io_mutex); mutex_lock(&ced->io_mutex);
if (pdx->bIsUSB2) /* Set flag for USB2 if appropriate */ if (ced->bIsUSB2) /* Set flag for USB2 if appropriate */
iReturn |= U14TF_USB2; iReturn |= U14TF_USB2;
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
return iReturn; return iReturn;
} }
...@@ -1111,18 +1111,18 @@ int ced_transfer_flags(DEVICE_EXTENSION *pdx) ...@@ -1111,18 +1111,18 @@ int ced_transfer_flags(DEVICE_EXTENSION *pdx)
** Issues a debug\diagnostic command to the 1401 along with a 32-bit datum ** Issues a debug\diagnostic command to the 1401 along with a 32-bit datum
** This is a utility command used for dbg operations. ** This is a utility command used for dbg operations.
*/ */
static int ced_dbg_cmd(DEVICE_EXTENSION *pdx, unsigned char cmd, static int ced_dbg_cmd(struct ced_data *ced, unsigned char cmd,
unsigned int data) unsigned int data)
{ {
int iReturn; int iReturn;
dev_dbg(&pdx->interface->dev, "%s: entry\n", __func__); dev_dbg(&ced->interface->dev, "%s: entry\n", __func__);
iReturn = usb_control_msg(pdx->udev, usb_sndctrlpipe(pdx->udev, 0), cmd, iReturn = usb_control_msg(ced->udev, usb_sndctrlpipe(ced->udev, 0), cmd,
(H_TO_D | VENDOR | DEVREQ), (H_TO_D | VENDOR | DEVREQ),
(unsigned short)data, (unsigned short)data,
(unsigned short)(data >> 16), NULL, 0, HZ); (unsigned short)(data >> 16), NULL, 0, HZ);
/* allow 1 second timeout */ /* allow 1 second timeout */
if (iReturn < 0) if (iReturn < 0)
dev_err(&pdx->interface->dev, "%s: fail code=%d\n", dev_err(&ced->interface->dev, "%s: fail code=%d\n",
__func__, iReturn); __func__, iReturn);
return iReturn; return iReturn;
...@@ -1133,7 +1133,7 @@ static int ced_dbg_cmd(DEVICE_EXTENSION *pdx, unsigned char cmd, ...@@ -1133,7 +1133,7 @@ static int ced_dbg_cmd(DEVICE_EXTENSION *pdx, unsigned char cmd,
** **
** Execute the diagnostic peek operation. Uses address, width and repeats. ** Execute the diagnostic peek operation. Uses address, width and repeats.
****************************************************************************/ ****************************************************************************/
int ced_dbg_peek(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) int ced_dbg_peek(struct ced_data *ced, TDBGBLOCK __user *pDB)
{ {
int iReturn; int iReturn;
TDBGBLOCK db; TDBGBLOCK db;
...@@ -1141,17 +1141,17 @@ int ced_dbg_peek(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) ...@@ -1141,17 +1141,17 @@ int ced_dbg_peek(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
if (copy_from_user(&db, pDB, sizeof(db))) if (copy_from_user(&db, pDB, sizeof(db)))
return -EFAULT; return -EFAULT;
mutex_lock(&pdx->io_mutex); mutex_lock(&ced->io_mutex);
dev_dbg(&pdx->interface->dev, "%s: @ %08x\n", __func__, db.iAddr); dev_dbg(&ced->interface->dev, "%s: @ %08x\n", __func__, db.iAddr);
iReturn = ced_dbg_cmd(pdx, DB_SETADD, db.iAddr); iReturn = ced_dbg_cmd(ced, DB_SETADD, db.iAddr);
if (iReturn == U14ERR_NOERROR) if (iReturn == U14ERR_NOERROR)
iReturn = ced_dbg_cmd(pdx, DB_WIDTH, db.iWidth); iReturn = ced_dbg_cmd(ced, DB_WIDTH, db.iWidth);
if (iReturn == U14ERR_NOERROR) if (iReturn == U14ERR_NOERROR)
iReturn = ced_dbg_cmd(pdx, DB_REPEATS, db.iRepeats); iReturn = ced_dbg_cmd(ced, DB_REPEATS, db.iRepeats);
if (iReturn == U14ERR_NOERROR) if (iReturn == U14ERR_NOERROR)
iReturn = ced_dbg_cmd(pdx, DB_PEEK, 0); iReturn = ced_dbg_cmd(ced, DB_PEEK, 0);
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
return iReturn; return iReturn;
} }
...@@ -1162,7 +1162,7 @@ int ced_dbg_peek(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) ...@@ -1162,7 +1162,7 @@ int ced_dbg_peek(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
** Execute the diagnostic poke operation. Parameters are in the CSBLOCK struct ** Execute the diagnostic poke operation. Parameters are in the CSBLOCK struct
** in order address, size, repeats and value to poke. ** in order address, size, repeats and value to poke.
****************************************************************************/ ****************************************************************************/
int ced_dbg_poke(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) int ced_dbg_poke(struct ced_data *ced, TDBGBLOCK __user *pDB)
{ {
int iReturn; int iReturn;
TDBGBLOCK db; TDBGBLOCK db;
...@@ -1170,17 +1170,17 @@ int ced_dbg_poke(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) ...@@ -1170,17 +1170,17 @@ int ced_dbg_poke(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
if (copy_from_user(&db, pDB, sizeof(db))) if (copy_from_user(&db, pDB, sizeof(db)))
return -EFAULT; return -EFAULT;
mutex_lock(&pdx->io_mutex); mutex_lock(&ced->io_mutex);
dev_dbg(&pdx->interface->dev, "%s: @ %08x\n", __func__, db.iAddr); dev_dbg(&ced->interface->dev, "%s: @ %08x\n", __func__, db.iAddr);
iReturn = ced_dbg_cmd(pdx, DB_SETADD, db.iAddr); iReturn = ced_dbg_cmd(ced, DB_SETADD, db.iAddr);
if (iReturn == U14ERR_NOERROR) if (iReturn == U14ERR_NOERROR)
iReturn = ced_dbg_cmd(pdx, DB_WIDTH, db.iWidth); iReturn = ced_dbg_cmd(ced, DB_WIDTH, db.iWidth);
if (iReturn == U14ERR_NOERROR) if (iReturn == U14ERR_NOERROR)
iReturn = ced_dbg_cmd(pdx, DB_REPEATS, db.iRepeats); iReturn = ced_dbg_cmd(ced, DB_REPEATS, db.iRepeats);
if (iReturn == U14ERR_NOERROR) if (iReturn == U14ERR_NOERROR)
iReturn = ced_dbg_cmd(pdx, DB_POKE, db.iData); iReturn = ced_dbg_cmd(ced, DB_POKE, db.iData);
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
return iReturn; return iReturn;
} }
...@@ -1191,7 +1191,7 @@ int ced_dbg_poke(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) ...@@ -1191,7 +1191,7 @@ int ced_dbg_poke(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
** Execute the diagnostic ramp data operation. Parameters are in the CSBLOCK struct ** Execute the diagnostic ramp data operation. Parameters are in the CSBLOCK struct
** in order address, default, enable mask, size and repeats. ** in order address, default, enable mask, size and repeats.
****************************************************************************/ ****************************************************************************/
int ced_dbg_ramp_data(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) int ced_dbg_ramp_data(struct ced_data *ced, TDBGBLOCK __user *pDB)
{ {
int iReturn; int iReturn;
TDBGBLOCK db; TDBGBLOCK db;
...@@ -1199,21 +1199,21 @@ int ced_dbg_ramp_data(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) ...@@ -1199,21 +1199,21 @@ int ced_dbg_ramp_data(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
if (copy_from_user(&db, pDB, sizeof(db))) if (copy_from_user(&db, pDB, sizeof(db)))
return -EFAULT; return -EFAULT;
mutex_lock(&pdx->io_mutex); mutex_lock(&ced->io_mutex);
dev_dbg(&pdx->interface->dev, "%s: @ %08x\n", __func__, db.iAddr); dev_dbg(&ced->interface->dev, "%s: @ %08x\n", __func__, db.iAddr);
iReturn = ced_dbg_cmd(pdx, DB_SETADD, db.iAddr); iReturn = ced_dbg_cmd(ced, DB_SETADD, db.iAddr);
if (iReturn == U14ERR_NOERROR) if (iReturn == U14ERR_NOERROR)
iReturn = ced_dbg_cmd(pdx, DB_SETDEF, db.iDefault); iReturn = ced_dbg_cmd(ced, DB_SETDEF, db.iDefault);
if (iReturn == U14ERR_NOERROR) if (iReturn == U14ERR_NOERROR)
iReturn = ced_dbg_cmd(pdx, DB_SETMASK, db.iMask); iReturn = ced_dbg_cmd(ced, DB_SETMASK, db.iMask);
if (iReturn == U14ERR_NOERROR) if (iReturn == U14ERR_NOERROR)
iReturn = ced_dbg_cmd(pdx, DB_WIDTH, db.iWidth); iReturn = ced_dbg_cmd(ced, DB_WIDTH, db.iWidth);
if (iReturn == U14ERR_NOERROR) if (iReturn == U14ERR_NOERROR)
iReturn = ced_dbg_cmd(pdx, DB_REPEATS, db.iRepeats); iReturn = ced_dbg_cmd(ced, DB_REPEATS, db.iRepeats);
if (iReturn == U14ERR_NOERROR) if (iReturn == U14ERR_NOERROR)
iReturn = ced_dbg_cmd(pdx, DB_RAMPD, 0); iReturn = ced_dbg_cmd(ced, DB_RAMPD, 0);
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
return iReturn; return iReturn;
} }
...@@ -1223,7 +1223,7 @@ int ced_dbg_ramp_data(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) ...@@ -1223,7 +1223,7 @@ int ced_dbg_ramp_data(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
** **
** Execute the diagnostic ramp address operation ** Execute the diagnostic ramp address operation
****************************************************************************/ ****************************************************************************/
int ced_dbg_ramp_addr(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) int ced_dbg_ramp_addr(struct ced_data *ced, TDBGBLOCK __user *pDB)
{ {
int iReturn; int iReturn;
TDBGBLOCK db; TDBGBLOCK db;
...@@ -1231,19 +1231,19 @@ int ced_dbg_ramp_addr(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) ...@@ -1231,19 +1231,19 @@ int ced_dbg_ramp_addr(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
if (copy_from_user(&db, pDB, sizeof(db))) if (copy_from_user(&db, pDB, sizeof(db)))
return -EFAULT; return -EFAULT;
mutex_lock(&pdx->io_mutex); mutex_lock(&ced->io_mutex);
dev_dbg(&pdx->interface->dev, "%s\n", __func__); dev_dbg(&ced->interface->dev, "%s\n", __func__);
iReturn = ced_dbg_cmd(pdx, DB_SETDEF, db.iDefault); iReturn = ced_dbg_cmd(ced, DB_SETDEF, db.iDefault);
if (iReturn == U14ERR_NOERROR) if (iReturn == U14ERR_NOERROR)
iReturn = ced_dbg_cmd(pdx, DB_SETMASK, db.iMask); iReturn = ced_dbg_cmd(ced, DB_SETMASK, db.iMask);
if (iReturn == U14ERR_NOERROR) if (iReturn == U14ERR_NOERROR)
iReturn = ced_dbg_cmd(pdx, DB_WIDTH, db.iWidth); iReturn = ced_dbg_cmd(ced, DB_WIDTH, db.iWidth);
if (iReturn == U14ERR_NOERROR) if (iReturn == U14ERR_NOERROR)
iReturn = ced_dbg_cmd(pdx, DB_REPEATS, db.iRepeats); iReturn = ced_dbg_cmd(ced, DB_REPEATS, db.iRepeats);
if (iReturn == U14ERR_NOERROR) if (iReturn == U14ERR_NOERROR)
iReturn = ced_dbg_cmd(pdx, DB_RAMPA, 0); iReturn = ced_dbg_cmd(ced, DB_RAMPA, 0);
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
return iReturn; return iReturn;
} }
...@@ -1253,17 +1253,17 @@ int ced_dbg_ramp_addr(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) ...@@ -1253,17 +1253,17 @@ int ced_dbg_ramp_addr(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
** **
** Retrieve the data resulting from the last debug Peek operation ** Retrieve the data resulting from the last debug Peek operation
****************************************************************************/ ****************************************************************************/
int ced_dbg_get_data(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) int ced_dbg_get_data(struct ced_data *ced, TDBGBLOCK __user *pDB)
{ {
int iReturn; int iReturn;
TDBGBLOCK db; TDBGBLOCK db;
memset(&db, 0, sizeof(db)); /* fill returned block with 0s */ memset(&db, 0, sizeof(db)); /* fill returned block with 0s */
mutex_lock(&pdx->io_mutex); mutex_lock(&ced->io_mutex);
dev_dbg(&pdx->interface->dev, "%s\n", __func__); dev_dbg(&ced->interface->dev, "%s\n", __func__);
/* Read back the last peeked value from the 1401. */ /* Read back the last peeked value from the 1401. */
iReturn = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0), iReturn = usb_control_msg(ced->udev, usb_rcvctrlpipe(ced->udev, 0),
DB_DATA, (D_TO_H | VENDOR | DEVREQ), 0, 0, DB_DATA, (D_TO_H | VENDOR | DEVREQ), 0, 0,
&db.iData, sizeof(db.iData), HZ); &db.iData, sizeof(db.iData), HZ);
if (iReturn == sizeof(db.iData)) { if (iReturn == sizeof(db.iData)) {
...@@ -1272,10 +1272,10 @@ int ced_dbg_get_data(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) ...@@ -1272,10 +1272,10 @@ int ced_dbg_get_data(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
else else
iReturn = U14ERR_NOERROR; iReturn = U14ERR_NOERROR;
} else } else
dev_err(&pdx->interface->dev, "%s: failed, code %d\n", dev_err(&ced->interface->dev, "%s: failed, code %d\n",
__func__, iReturn); __func__, iReturn);
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
return iReturn; return iReturn;
} }
...@@ -1286,15 +1286,15 @@ int ced_dbg_get_data(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) ...@@ -1286,15 +1286,15 @@ int ced_dbg_get_data(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
** Stop any never-ending debug loop, we just call ced_get_state for USB ** Stop any never-ending debug loop, we just call ced_get_state for USB
** **
****************************************************************************/ ****************************************************************************/
int ced_dbg_stop_loop(DEVICE_EXTENSION *pdx) int ced_dbg_stop_loop(struct ced_data *ced)
{ {
int iReturn; int iReturn;
unsigned int uState, uErr; unsigned int uState, uErr;
mutex_lock(&pdx->io_mutex); mutex_lock(&ced->io_mutex);
dev_dbg(&pdx->interface->dev, "%s\n", __func__); dev_dbg(&ced->interface->dev, "%s\n", __func__);
iReturn = ced_get_state(pdx, &uState, &uErr); iReturn = ced_get_state(ced, &uState, &uErr);
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
return iReturn; return iReturn;
} }
...@@ -1307,7 +1307,7 @@ int ced_dbg_stop_loop(DEVICE_EXTENSION *pdx) ...@@ -1307,7 +1307,7 @@ int ced_dbg_stop_loop(DEVICE_EXTENSION *pdx)
** booked and a transfer to that area is in progress. Otherwise, we will ** booked and a transfer to that area is in progress. Otherwise, we will
** release the area and re-assign it. ** release the area and re-assign it.
****************************************************************************/ ****************************************************************************/
int ced_set_circular(DEVICE_EXTENSION *pdx, struct transfer_area_desc __user *pTD) int ced_set_circular(struct ced_data *ced, struct transfer_area_desc __user *pTD)
{ {
int iReturn; int iReturn;
bool bToHost; bool bToHost;
...@@ -1316,8 +1316,8 @@ int ced_set_circular(DEVICE_EXTENSION *pdx, struct transfer_area_desc __user *pT ...@@ -1316,8 +1316,8 @@ int ced_set_circular(DEVICE_EXTENSION *pdx, struct transfer_area_desc __user *pT
if (copy_from_user(&td, pTD, sizeof(td))) if (copy_from_user(&td, pTD, sizeof(td)))
return -EFAULT; return -EFAULT;
mutex_lock(&pdx->io_mutex); mutex_lock(&ced->io_mutex);
dev_dbg(&pdx->interface->dev, "%s: area:%d, size:%08x\n", dev_dbg(&ced->interface->dev, "%s: area:%d, size:%08x\n",
__func__, td.wAreaNum, td.dwLength); __func__, td.wAreaNum, td.dwLength);
bToHost = td.eSize != 0; /* this is used as the tohost flag */ bToHost = td.eSize != 0; /* this is used as the tohost flag */
...@@ -1325,10 +1325,10 @@ int ced_set_circular(DEVICE_EXTENSION *pdx, struct transfer_area_desc __user *pT ...@@ -1325,10 +1325,10 @@ int ced_set_circular(DEVICE_EXTENSION *pdx, struct transfer_area_desc __user *pT
/* pointer. The pointer is always passed as a 64-bit object so that we don't have problems using */ /* 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. */ /* a 32-bit program on a 64-bit system. unsigned long is 64-bits on a 64-bit system. */
iReturn = iReturn =
ced_set_area(pdx, td.wAreaNum, ced_set_area(ced, td.wAreaNum,
(char __user *)((unsigned long)td.lpvBuff), td.dwLength, (char __user *)((unsigned long)td.lpvBuff), td.dwLength,
true, bToHost); true, bToHost);
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
return iReturn; return iReturn;
} }
...@@ -1337,18 +1337,18 @@ int ced_set_circular(DEVICE_EXTENSION *pdx, struct transfer_area_desc __user *pT ...@@ -1337,18 +1337,18 @@ int ced_set_circular(DEVICE_EXTENSION *pdx, struct transfer_area_desc __user *pT
** **
** Return the next available block of circularly-transferred data. ** Return the next available block of circularly-transferred data.
****************************************************************************/ ****************************************************************************/
int ced_get_circ_block(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB) int ced_get_circ_block(struct ced_data *ced, TCIRCBLOCK __user *pCB)
{ {
int iReturn = U14ERR_NOERROR; int iReturn = U14ERR_NOERROR;
unsigned int nArea; unsigned int nArea;
TCIRCBLOCK cb; TCIRCBLOCK cb;
dev_dbg(&pdx->interface->dev, "%s\n", __func__); dev_dbg(&ced->interface->dev, "%s\n", __func__);
if (copy_from_user(&cb, pCB, sizeof(cb))) if (copy_from_user(&cb, pCB, sizeof(cb)))
return -EFAULT; return -EFAULT;
mutex_lock(&pdx->io_mutex); mutex_lock(&ced->io_mutex);
nArea = cb.nArea; /* Retrieve parameters first */ nArea = cb.nArea; /* Retrieve parameters first */
cb.dwOffset = 0; /* set default result (nothing) */ cb.dwOffset = 0; /* set default result (nothing) */
...@@ -1356,29 +1356,29 @@ int ced_get_circ_block(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB) ...@@ -1356,29 +1356,29 @@ int ced_get_circ_block(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB)
if (nArea < MAX_TRANSAREAS) { /* The area number must be OK */ if (nArea < MAX_TRANSAREAS) { /* The area number must be OK */
/* Pointer to relevant info */ /* Pointer to relevant info */
struct transarea *pArea = &pdx->rTransDef[nArea]; struct transarea *pArea = &ced->rTransDef[nArea];
spin_lock_irq(&pdx->stagedLock); /* Lock others out */ spin_lock_irq(&ced->stagedLock); /* Lock others out */
if ((pArea->bUsed) && (pArea->bCircular) && /* Must be circular area */ if ((pArea->bUsed) && (pArea->bCircular) && /* Must be circular area */
(pArea->bCircToHost)) { /* For now at least must be to host */ (pArea->bCircToHost)) { /* For now at least must be to host */
if (pArea->aBlocks[0].dwSize > 0) { /* Got anything? */ if (pArea->aBlocks[0].dwSize > 0) { /* Got anything? */
cb.dwOffset = pArea->aBlocks[0].dwOffset; cb.dwOffset = pArea->aBlocks[0].dwOffset;
cb.dwSize = pArea->aBlocks[0].dwSize; cb.dwSize = pArea->aBlocks[0].dwSize;
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"%s: return block 0: %d bytes at %d\n", "%s: return block 0: %d bytes at %d\n",
__func__, cb.dwSize, cb.dwOffset); __func__, cb.dwSize, cb.dwOffset);
} }
} else } else
iReturn = U14ERR_NOTSET; iReturn = U14ERR_NOTSET;
spin_unlock_irq(&pdx->stagedLock); spin_unlock_irq(&ced->stagedLock);
} else } else
iReturn = U14ERR_BADAREA; iReturn = U14ERR_BADAREA;
if (copy_to_user(pCB, &cb, sizeof(cb))) if (copy_to_user(pCB, &cb, sizeof(cb)))
iReturn = -EFAULT; iReturn = -EFAULT;
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
return iReturn; return iReturn;
} }
...@@ -1387,18 +1387,18 @@ int ced_get_circ_block(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB) ...@@ -1387,18 +1387,18 @@ int ced_get_circ_block(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB)
** **
** Frees a block of circularly-transferred data and returns the next one. ** Frees a block of circularly-transferred data and returns the next one.
****************************************************************************/ ****************************************************************************/
int ced_free_circ_block(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB) int ced_free_circ_block(struct ced_data *ced, TCIRCBLOCK __user *pCB)
{ {
int iReturn = U14ERR_NOERROR; int iReturn = U14ERR_NOERROR;
unsigned int nArea, uStart, uSize; unsigned int nArea, uStart, uSize;
TCIRCBLOCK cb; TCIRCBLOCK cb;
dev_dbg(&pdx->interface->dev, "%s\n", __func__); dev_dbg(&ced->interface->dev, "%s\n", __func__);
if (copy_from_user(&cb, pCB, sizeof(cb))) if (copy_from_user(&cb, pCB, sizeof(cb)))
return -EFAULT; return -EFAULT;
mutex_lock(&pdx->io_mutex); mutex_lock(&ced->io_mutex);
nArea = cb.nArea; /* Retrieve parameters first */ nArea = cb.nArea; /* Retrieve parameters first */
uStart = cb.dwOffset; uStart = cb.dwOffset;
...@@ -1408,8 +1408,8 @@ int ced_free_circ_block(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB) ...@@ -1408,8 +1408,8 @@ int ced_free_circ_block(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB)
if (nArea < MAX_TRANSAREAS) { /* The area number must be OK */ if (nArea < MAX_TRANSAREAS) { /* The area number must be OK */
/* Pointer to relevant info */ /* Pointer to relevant info */
struct transarea *pArea = &pdx->rTransDef[nArea]; struct transarea *pArea = &ced->rTransDef[nArea];
spin_lock_irq(&pdx->stagedLock); /* Lock others out */ spin_lock_irq(&ced->stagedLock); /* Lock others out */
if ((pArea->bUsed) && (pArea->bCircular) && /* Must be circular area */ if ((pArea->bUsed) && (pArea->bCircular) && /* Must be circular area */
(pArea->bCircToHost)) { /* For now at least must be to host */ (pArea->bCircToHost)) { /* For now at least must be to host */
...@@ -1428,12 +1428,12 @@ int ced_free_circ_block(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB) ...@@ -1428,12 +1428,12 @@ int ced_free_circ_block(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB)
pArea->aBlocks[0].dwOffset = 0; pArea->aBlocks[0].dwOffset = 0;
} }
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"%s: free %d bytes at %d, return %d bytes at %d, wait=%d\n", "%s: free %d bytes at %d, return %d bytes at %d, wait=%d\n",
__func__, uSize, uStart, __func__, uSize, uStart,
pArea->aBlocks[0].dwSize, pArea->aBlocks[0].dwSize,
pArea->aBlocks[0].dwOffset, pArea->aBlocks[0].dwOffset,
pdx->bXFerWaiting); ced->bXFerWaiting);
/* Return the next available block of memory as well */ /* Return the next available block of memory as well */
if (pArea->aBlocks[0].dwSize > 0) { /* Got anything? */ if (pArea->aBlocks[0].dwSize > 0) { /* Got anything? */
...@@ -1442,15 +1442,15 @@ int ced_free_circ_block(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB) ...@@ -1442,15 +1442,15 @@ int ced_free_circ_block(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB)
cb.dwSize = pArea->aBlocks[0].dwSize; cb.dwSize = pArea->aBlocks[0].dwSize;
} }
bWaiting = pdx->bXFerWaiting; bWaiting = ced->bXFerWaiting;
if (bWaiting && pdx->bStagedUrbPending) { if (bWaiting && ced->bStagedUrbPending) {
dev_err(&pdx->interface->dev, dev_err(&ced->interface->dev,
"%s: ERROR: waiting xfer and staged Urb pending!\n", "%s: ERROR: waiting xfer and staged Urb pending!\n",
__func__); __func__);
bWaiting = false; bWaiting = false;
} }
} else { } else {
dev_err(&pdx->interface->dev, dev_err(&ced->interface->dev,
"%s: ERROR: freeing %d bytes at %d, block 0 is %d bytes at %d\n", "%s: ERROR: freeing %d bytes at %d, block 0 is %d bytes at %d\n",
__func__, uSize, uStart, __func__, uSize, uStart,
pArea->aBlocks[0].dwSize, pArea->aBlocks[0].dwSize,
...@@ -1461,25 +1461,25 @@ int ced_free_circ_block(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB) ...@@ -1461,25 +1461,25 @@ int ced_free_circ_block(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB)
/* If we have one, kick off pending transfer */ /* If we have one, kick off pending transfer */
if (bWaiting) { /* Got a block xfer waiting? */ if (bWaiting) { /* Got a block xfer waiting? */
int RWMStat = int RWMStat =
ced_read_write_mem(pdx, !pdx->rDMAInfo.bOutWard, ced_read_write_mem(ced, !ced->rDMAInfo.bOutWard,
pdx->rDMAInfo.wIdent, ced->rDMAInfo.wIdent,
pdx->rDMAInfo.dwOffset, ced->rDMAInfo.dwOffset,
pdx->rDMAInfo.dwSize); ced->rDMAInfo.dwSize);
if (RWMStat != U14ERR_NOERROR) if (RWMStat != U14ERR_NOERROR)
dev_err(&pdx->interface->dev, dev_err(&ced->interface->dev,
"%s: rw setup failed %d\n", "%s: rw setup failed %d\n",
__func__, RWMStat); __func__, RWMStat);
} }
} else } else
iReturn = U14ERR_NOTSET; iReturn = U14ERR_NOTSET;
spin_unlock_irq(&pdx->stagedLock); spin_unlock_irq(&ced->stagedLock);
} else } else
iReturn = U14ERR_BADAREA; iReturn = U14ERR_BADAREA;
if (copy_to_user(pCB, &cb, sizeof(cb))) if (copy_to_user(pCB, &cb, sizeof(cb)))
iReturn = -EFAULT; iReturn = -EFAULT;
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
return iReturn; return iReturn;
} }
...@@ -70,7 +70,7 @@ it is very out of date. A lot of information was gleaned from the latest ...@@ -70,7 +70,7 @@ it is very out of date. A lot of information was gleaned from the latest
usb_skeleton.c code (you need to download the kernel sources to get this). usb_skeleton.c code (you need to download the kernel sources to get this).
To match the Windows version, everything is done using ioctl calls. All the To match the Windows version, everything is done using ioctl calls. All the
device state is held in the DEVICE_EXTENSION (named to match Windows use). device state is held in the struct ced_data.
Block transfers are done by using get_user_pages() to pin down a list of Block transfers are done by using get_user_pages() to pin down a list of
pages that we hold a pointer to in the device driver. We also allocate a pages that we hold a pointer to in the device driver. We also allocate a
coherent transfer buffer of size STAGED_SZ (this must be a multiple of the coherent transfer buffer of size STAGED_SZ (this must be a multiple of the
...@@ -123,32 +123,32 @@ static struct usb_driver ced_driver; ...@@ -123,32 +123,32 @@ static struct usb_driver ced_driver;
static void ced_delete(struct kref *kref) static void ced_delete(struct kref *kref)
{ {
DEVICE_EXTENSION *pdx = to_DEVICE_EXTENSION(kref); struct ced_data *ced = to_ced_data(kref);
/* Free up the output buffer, then free the output urb. Note that the interface member */ /* Free up the output buffer, then free the output urb. Note that the interface member */
/* of pdx will probably be NULL, so cannot be used to get to dev. */ /* of ced will probably be NULL, so cannot be used to get to dev. */
usb_free_coherent(pdx->udev, OUTBUF_SZ, pdx->pCoherCharOut, usb_free_coherent(ced->udev, OUTBUF_SZ, ced->pCoherCharOut,
pdx->pUrbCharOut->transfer_dma); ced->pUrbCharOut->transfer_dma);
usb_free_urb(pdx->pUrbCharOut); usb_free_urb(ced->pUrbCharOut);
/* Do the same for chan input */ /* Do the same for chan input */
usb_free_coherent(pdx->udev, INBUF_SZ, pdx->pCoherCharIn, usb_free_coherent(ced->udev, INBUF_SZ, ced->pCoherCharIn,
pdx->pUrbCharIn->transfer_dma); ced->pUrbCharIn->transfer_dma);
usb_free_urb(pdx->pUrbCharIn); usb_free_urb(ced->pUrbCharIn);
/* Do the same for the block transfers */ /* Do the same for the block transfers */
usb_free_coherent(pdx->udev, STAGED_SZ, pdx->pCoherStagedIO, usb_free_coherent(ced->udev, STAGED_SZ, ced->pCoherStagedIO,
pdx->pStagedUrb->transfer_dma); ced->pStagedUrb->transfer_dma);
usb_free_urb(pdx->pStagedUrb); usb_free_urb(ced->pStagedUrb);
usb_put_dev(pdx->udev); usb_put_dev(ced->udev);
kfree(pdx); kfree(ced);
} }
/* This is the driver end of the open() call from user space. */ /* This is the driver end of the open() call from user space. */
static int ced_open(struct inode *inode, struct file *file) static int ced_open(struct inode *inode, struct file *file)
{ {
DEVICE_EXTENSION *pdx; struct ced_data *ced;
int retval = 0; int retval = 0;
int subminor = iminor(inode); int subminor = iminor(inode);
struct usb_interface *interface = struct usb_interface *interface =
...@@ -160,42 +160,42 @@ static int ced_open(struct inode *inode, struct file *file) ...@@ -160,42 +160,42 @@ static int ced_open(struct inode *inode, struct file *file)
goto exit; goto exit;
} }
pdx = usb_get_intfdata(interface); ced = usb_get_intfdata(interface);
if (!pdx) { if (!ced) {
retval = -ENODEV; retval = -ENODEV;
goto exit; goto exit;
} }
dev_dbg(&interface->dev, "%s: got pdx\n", __func__); dev_dbg(&interface->dev, "%s: got ced\n", __func__);
/* increment our usage count for the device */ /* increment our usage count for the device */
kref_get(&pdx->kref); kref_get(&ced->kref);
/* lock the device to allow correctly handling errors /* lock the device to allow correctly handling errors
* in resumption */ * in resumption */
mutex_lock(&pdx->io_mutex); mutex_lock(&ced->io_mutex);
if (!pdx->open_count++) { if (!ced->open_count++) {
retval = usb_autopm_get_interface(interface); retval = usb_autopm_get_interface(interface);
if (retval) { if (retval) {
pdx->open_count--; ced->open_count--;
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
kref_put(&pdx->kref, ced_delete); kref_put(&ced->kref, ced_delete);
goto exit; goto exit;
} }
} else { /* uncomment this block if you want exclusive open */ } else { /* uncomment this block if you want exclusive open */
dev_err(&interface->dev, "%s: fail: already open\n", __func__); dev_err(&interface->dev, "%s: fail: already open\n", __func__);
retval = -EBUSY; retval = -EBUSY;
pdx->open_count--; ced->open_count--;
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
kref_put(&pdx->kref, ced_delete); kref_put(&ced->kref, ced_delete);
goto exit; goto exit;
} }
/* prevent the device from being autosuspended */ /* prevent the device from being autosuspended */
/* save our object in the file's private structure */ /* save our object in the file's private structure */
file->private_data = pdx; file->private_data = ced;
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
exit: exit:
return retval; return retval;
...@@ -203,43 +203,43 @@ static int ced_open(struct inode *inode, struct file *file) ...@@ -203,43 +203,43 @@ static int ced_open(struct inode *inode, struct file *file)
static int ced_release(struct inode *inode, struct file *file) static int ced_release(struct inode *inode, struct file *file)
{ {
DEVICE_EXTENSION *pdx = file->private_data; struct ced_data *ced = file->private_data;
if (pdx == NULL) if (ced == NULL)
return -ENODEV; return -ENODEV;
dev_dbg(&pdx->interface->dev, "%s: called\n", __func__); dev_dbg(&ced->interface->dev, "%s: called\n", __func__);
mutex_lock(&pdx->io_mutex); mutex_lock(&ced->io_mutex);
if (!--pdx->open_count && pdx->interface) /* Allow autosuspend */ if (!--ced->open_count && ced->interface) /* Allow autosuspend */
usb_autopm_put_interface(pdx->interface); usb_autopm_put_interface(ced->interface);
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
kref_put(&pdx->kref, ced_delete); /* decrement the count on our device */ kref_put(&ced->kref, ced_delete); /* decrement the count on our device */
return 0; return 0;
} }
static int ced_flush(struct file *file, fl_owner_t id) static int ced_flush(struct file *file, fl_owner_t id)
{ {
int res; int res;
DEVICE_EXTENSION *pdx = file->private_data; struct ced_data *ced = file->private_data;
if (pdx == NULL) if (ced == NULL)
return -ENODEV; return -ENODEV;
dev_dbg(&pdx->interface->dev, "%s: char in pend=%d\n", dev_dbg(&ced->interface->dev, "%s: char in pend=%d\n",
__func__, pdx->bReadCharsPending); __func__, ced->bReadCharsPending);
/* wait for io to stop */ /* wait for io to stop */
mutex_lock(&pdx->io_mutex); mutex_lock(&ced->io_mutex);
dev_dbg(&pdx->interface->dev, "%s: got io_mutex\n", __func__); dev_dbg(&ced->interface->dev, "%s: got io_mutex\n", __func__);
ced_draw_down(pdx); ced_draw_down(ced);
/* read out errors, leave subsequent opens a clean slate */ /* read out errors, leave subsequent opens a clean slate */
spin_lock_irq(&pdx->err_lock); spin_lock_irq(&ced->err_lock);
res = pdx->errors ? (pdx->errors == -EPIPE ? -EPIPE : -EIO) : 0; res = ced->errors ? (ced->errors == -EPIPE ? -EPIPE : -EIO) : 0;
pdx->errors = 0; ced->errors = 0;
spin_unlock_irq(&pdx->err_lock); spin_unlock_irq(&ced->err_lock);
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
dev_dbg(&pdx->interface->dev, "%s: exit reached\n", __func__); dev_dbg(&ced->interface->dev, "%s: exit reached\n", __func__);
return res; return res;
} }
...@@ -247,13 +247,13 @@ static int ced_flush(struct file *file, fl_owner_t id) ...@@ -247,13 +247,13 @@ static int ced_flush(struct file *file, fl_owner_t id)
/*************************************************************************** /***************************************************************************
** can_accept_io_requests ** can_accept_io_requests
** If the device is removed, interface is set NULL. We also clear our pointer ** If the device is removed, interface is set NULL. We also clear our pointer
** from the interface, so we should make sure that pdx is not NULL. This will ** from the interface, so we should make sure that ced is not NULL. This will
** not help with a device extension held by a file. ** not help with a device extension held by a file.
** return true if can accept new io requests, else false ** return true if can accept new io requests, else false
*/ */
static bool can_accept_io_requests(DEVICE_EXTENSION *pdx) static bool can_accept_io_requests(struct ced_data *ced)
{ {
return pdx && pdx->interface; /* Can we accept IO requests */ return ced && ced->interface; /* Can we accept IO requests */
} }
/**************************************************************************** /****************************************************************************
...@@ -262,73 +262,73 @@ static bool can_accept_io_requests(DEVICE_EXTENSION *pdx) ...@@ -262,73 +262,73 @@ static bool can_accept_io_requests(DEVICE_EXTENSION *pdx)
****************************************************************************/ ****************************************************************************/
static void ced_writechar_callback(struct urb *pUrb) static void ced_writechar_callback(struct urb *pUrb)
{ {
DEVICE_EXTENSION *pdx = pUrb->context; struct ced_data *ced = pUrb->context;
int nGot = pUrb->actual_length; /* what we transferred */ int nGot = pUrb->actual_length; /* what we transferred */
if (pUrb->status) { /* sync/async unlink faults aren't errors */ if (pUrb->status) { /* sync/async unlink faults aren't errors */
if (! if (!
(pUrb->status == -ENOENT || pUrb->status == -ECONNRESET (pUrb->status == -ENOENT || pUrb->status == -ECONNRESET
|| pUrb->status == -ESHUTDOWN)) { || pUrb->status == -ESHUTDOWN)) {
dev_err(&pdx->interface->dev, dev_err(&ced->interface->dev,
"%s: nonzero write bulk status received: %d\n", "%s: nonzero write bulk status received: %d\n",
__func__, pUrb->status); __func__, pUrb->status);
} }
spin_lock(&pdx->err_lock); spin_lock(&ced->err_lock);
pdx->errors = pUrb->status; ced->errors = pUrb->status;
spin_unlock(&pdx->err_lock); spin_unlock(&ced->err_lock);
nGot = 0; /* and tidy up again if so */ nGot = 0; /* and tidy up again if so */
spin_lock(&pdx->charOutLock); /* already at irq level */ spin_lock(&ced->charOutLock); /* already at irq level */
pdx->dwOutBuffGet = 0; /* Reset the output buffer */ ced->dwOutBuffGet = 0; /* Reset the output buffer */
pdx->dwOutBuffPut = 0; ced->dwOutBuffPut = 0;
pdx->dwNumOutput = 0; /* Clear the char count */ ced->dwNumOutput = 0; /* Clear the char count */
pdx->bPipeError[0] = 1; /* Flag an error for later */ ced->bPipeError[0] = 1; /* Flag an error for later */
pdx->bSendCharsPending = false; /* Allow other threads again */ ced->bSendCharsPending = false; /* Allow other threads again */
spin_unlock(&pdx->charOutLock); /* already at irq level */ spin_unlock(&ced->charOutLock); /* already at irq level */
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"%s: char out done, 0 chars sent\n", __func__); "%s: char out done, 0 chars sent\n", __func__);
} else { } else {
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"%s: char out done, %d chars sent\n", __func__, nGot); "%s: char out done, %d chars sent\n", __func__, nGot);
spin_lock(&pdx->charOutLock); /* already at irq level */ spin_lock(&ced->charOutLock); /* already at irq level */
pdx->dwNumOutput -= nGot; /* Now adjust the char send buffer */ ced->dwNumOutput -= nGot; /* Now adjust the char send buffer */
pdx->dwOutBuffGet += nGot; /* to match what we did */ ced->dwOutBuffGet += nGot; /* to match what we did */
if (pdx->dwOutBuffGet >= OUTBUF_SZ) /* Can't do this any earlier as data could be overwritten */ if (ced->dwOutBuffGet >= OUTBUF_SZ) /* Can't do this any earlier as data could be overwritten */
pdx->dwOutBuffGet = 0; ced->dwOutBuffGet = 0;
if (pdx->dwNumOutput > 0) { /* if more to be done... */ if (ced->dwNumOutput > 0) { /* if more to be done... */
int nPipe = 0; /* The pipe number to use */ int nPipe = 0; /* The pipe number to use */
int iReturn; int iReturn;
char *pDat = &pdx->outputBuffer[pdx->dwOutBuffGet]; char *pDat = &ced->outputBuffer[ced->dwOutBuffGet];
unsigned int dwCount = pdx->dwNumOutput; /* maximum to send */ unsigned int dwCount = ced->dwNumOutput; /* maximum to send */
if ((pdx->dwOutBuffGet + dwCount) > OUTBUF_SZ) /* does it cross buffer end? */ if ((ced->dwOutBuffGet + dwCount) > OUTBUF_SZ) /* does it cross buffer end? */
dwCount = OUTBUF_SZ - pdx->dwOutBuffGet; dwCount = OUTBUF_SZ - ced->dwOutBuffGet;
spin_unlock(&pdx->charOutLock); /* we are done with stuff that changes */ spin_unlock(&ced->charOutLock); /* we are done with stuff that changes */
memcpy(pdx->pCoherCharOut, pDat, dwCount); /* copy output data to the buffer */ memcpy(ced->pCoherCharOut, pDat, dwCount); /* copy output data to the buffer */
usb_fill_bulk_urb(pdx->pUrbCharOut, pdx->udev, usb_fill_bulk_urb(ced->pUrbCharOut, ced->udev,
usb_sndbulkpipe(pdx->udev, usb_sndbulkpipe(ced->udev,
pdx->epAddr[0]), ced->epAddr[0]),
pdx->pCoherCharOut, dwCount, ced->pCoherCharOut, dwCount,
ced_writechar_callback, pdx); ced_writechar_callback, ced);
pdx->pUrbCharOut->transfer_flags |= ced->pUrbCharOut->transfer_flags |=
URB_NO_TRANSFER_DMA_MAP; URB_NO_TRANSFER_DMA_MAP;
usb_anchor_urb(pdx->pUrbCharOut, &pdx->submitted); /* in case we need to kill it */ usb_anchor_urb(ced->pUrbCharOut, &ced->submitted); /* in case we need to kill it */
iReturn = usb_submit_urb(pdx->pUrbCharOut, GFP_ATOMIC); iReturn = usb_submit_urb(ced->pUrbCharOut, GFP_ATOMIC);
dev_dbg(&pdx->interface->dev, "%s: n=%d>%s<\n", dev_dbg(&ced->interface->dev, "%s: n=%d>%s<\n",
__func__, dwCount, pDat); __func__, dwCount, pDat);
spin_lock(&pdx->charOutLock); /* grab lock for errors */ spin_lock(&ced->charOutLock); /* grab lock for errors */
if (iReturn) { if (iReturn) {
pdx->bPipeError[nPipe] = 1; /* Flag an error to be handled later */ ced->bPipeError[nPipe] = 1; /* Flag an error to be handled later */
pdx->bSendCharsPending = false; /* Allow other threads again */ ced->bSendCharsPending = false; /* Allow other threads again */
usb_unanchor_urb(pdx->pUrbCharOut); usb_unanchor_urb(ced->pUrbCharOut);
dev_err(&pdx->interface->dev, dev_err(&ced->interface->dev,
"%s: usb_submit_urb() returned %d\n", "%s: usb_submit_urb() returned %d\n",
__func__, iReturn); __func__, iReturn);
} }
} else } else
pdx->bSendCharsPending = false; /* Allow other threads again */ ced->bSendCharsPending = false; /* Allow other threads again */
spin_unlock(&pdx->charOutLock); /* already at irq level */ spin_unlock(&ced->charOutLock); /* already at irq level */
} }
} }
...@@ -337,89 +337,89 @@ static void ced_writechar_callback(struct urb *pUrb) ...@@ -337,89 +337,89 @@ static void ced_writechar_callback(struct urb *pUrb)
** Transmit the characters in the output buffer to the 1401. This may need ** Transmit the characters in the output buffer to the 1401. This may need
** breaking down into multiple transfers. ** breaking down into multiple transfers.
****************************************************************************/ ****************************************************************************/
int ced_send_chars(DEVICE_EXTENSION *pdx) int ced_send_chars(struct ced_data *ced)
{ {
int iReturn = U14ERR_NOERROR; int iReturn = U14ERR_NOERROR;
spin_lock_irq(&pdx->charOutLock); /* Protect ourselves */ spin_lock_irq(&ced->charOutLock); /* Protect ourselves */
if ((!pdx->bSendCharsPending) && /* Not currently sending */ if ((!ced->bSendCharsPending) && /* Not currently sending */
(pdx->dwNumOutput > 0) && /* has characters to output */ (ced->dwNumOutput > 0) && /* has characters to output */
(can_accept_io_requests(pdx))) { /* and current activity is OK */ (can_accept_io_requests(ced))) { /* and current activity is OK */
unsigned int dwCount = pdx->dwNumOutput; /* Get a copy of the character count */ unsigned int dwCount = ced->dwNumOutput; /* Get a copy of the character count */
pdx->bSendCharsPending = true; /* Set flag to lock out other threads */ ced->bSendCharsPending = true; /* Set flag to lock out other threads */
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"Send %d chars to 1401, EP0 flag %d\n", "Send %d chars to 1401, EP0 flag %d\n",
dwCount, pdx->nPipes == 3); dwCount, ced->nPipes == 3);
/* If we have only 3 end points we must send the characters to the 1401 using EP0. */ /* If we have only 3 end points we must send the characters to the 1401 using EP0. */
if (pdx->nPipes == 3) { if (ced->nPipes == 3) {
/* For EP0 character transmissions to the 1401, we have to hang about until they */ /* For EP0 character transmissions to the 1401, we have to hang about until they */
/* are gone, as otherwise without more character IO activity they will never go. */ /* are gone, as otherwise without more character IO activity they will never go. */
unsigned int count = dwCount; /* Local char counter */ unsigned int count = dwCount; /* Local char counter */
unsigned int index = 0; /* The index into the char buffer */ unsigned int index = 0; /* The index into the char buffer */
spin_unlock_irq(&pdx->charOutLock); /* Free spinlock as we call USBD */ spin_unlock_irq(&ced->charOutLock); /* Free spinlock as we call USBD */
while ((count > 0) && (iReturn == U14ERR_NOERROR)) { while ((count > 0) && (iReturn == U14ERR_NOERROR)) {
/* We have to break the transfer up into 64-byte chunks because of a 2270 problem */ /* We have to break the transfer up into 64-byte chunks because of a 2270 problem */
int n = count > 64 ? 64 : count; /* Chars for this xfer, max of 64 */ int n = count > 64 ? 64 : count; /* Chars for this xfer, max of 64 */
int nSent = usb_control_msg(pdx->udev, int nSent = usb_control_msg(ced->udev,
usb_sndctrlpipe(pdx->udev, 0), /* use end point 0 */ usb_sndctrlpipe(ced->udev, 0), /* use end point 0 */
DB_CHARS, /* bRequest */ DB_CHARS, /* bRequest */
(H_TO_D | VENDOR | DEVREQ), /* to the device, vendor request to the device */ (H_TO_D | VENDOR | DEVREQ), /* to the device, vendor request to the device */
0, 0, /* value and index are both 0 */ 0, 0, /* value and index are both 0 */
&pdx->outputBuffer[index], /* where to send from */ &ced->outputBuffer[index], /* where to send from */
n, /* how much to send */ n, /* how much to send */
1000); /* timeout in jiffies */ 1000); /* timeout in jiffies */
if (nSent <= 0) { if (nSent <= 0) {
iReturn = nSent ? nSent : -ETIMEDOUT; /* if 0 chars says we timed out */ iReturn = nSent ? nSent : -ETIMEDOUT; /* if 0 chars says we timed out */
dev_err(&pdx->interface->dev, dev_err(&ced->interface->dev,
"Send %d chars by EP0 failed: %d\n", "Send %d chars by EP0 failed: %d\n",
n, iReturn); n, iReturn);
} else { } else {
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"Sent %d chars by EP0\n", n); "Sent %d chars by EP0\n", n);
count -= nSent; count -= nSent;
index += nSent; index += nSent;
} }
} }
spin_lock_irq(&pdx->charOutLock); /* Protect pdx changes, released by general code */ spin_lock_irq(&ced->charOutLock); /* Protect ced changes, released by general code */
pdx->dwOutBuffGet = 0; /* so reset the output buffer */ ced->dwOutBuffGet = 0; /* so reset the output buffer */
pdx->dwOutBuffPut = 0; ced->dwOutBuffPut = 0;
pdx->dwNumOutput = 0; /* and clear the buffer count */ ced->dwNumOutput = 0; /* and clear the buffer count */
pdx->bSendCharsPending = false; /* Allow other threads again */ ced->bSendCharsPending = false; /* Allow other threads again */
} else { /* Here for sending chars normally - we hold the spin lock */ } else { /* Here for sending chars normally - we hold the spin lock */
int nPipe = 0; /* The pipe number to use */ int nPipe = 0; /* The pipe number to use */
char *pDat = &pdx->outputBuffer[pdx->dwOutBuffGet]; char *pDat = &ced->outputBuffer[ced->dwOutBuffGet];
if ((pdx->dwOutBuffGet + dwCount) > OUTBUF_SZ) /* does it cross buffer end? */ if ((ced->dwOutBuffGet + dwCount) > OUTBUF_SZ) /* does it cross buffer end? */
dwCount = OUTBUF_SZ - pdx->dwOutBuffGet; dwCount = OUTBUF_SZ - ced->dwOutBuffGet;
spin_unlock_irq(&pdx->charOutLock); /* we are done with stuff that changes */ spin_unlock_irq(&ced->charOutLock); /* we are done with stuff that changes */
memcpy(pdx->pCoherCharOut, pDat, dwCount); /* copy output data to the buffer */ memcpy(ced->pCoherCharOut, pDat, dwCount); /* copy output data to the buffer */
usb_fill_bulk_urb(pdx->pUrbCharOut, pdx->udev, usb_fill_bulk_urb(ced->pUrbCharOut, ced->udev,
usb_sndbulkpipe(pdx->udev, usb_sndbulkpipe(ced->udev,
pdx->epAddr[0]), ced->epAddr[0]),
pdx->pCoherCharOut, dwCount, ced->pCoherCharOut, dwCount,
ced_writechar_callback, pdx); ced_writechar_callback, ced);
pdx->pUrbCharOut->transfer_flags |= ced->pUrbCharOut->transfer_flags |=
URB_NO_TRANSFER_DMA_MAP; URB_NO_TRANSFER_DMA_MAP;
usb_anchor_urb(pdx->pUrbCharOut, &pdx->submitted); usb_anchor_urb(ced->pUrbCharOut, &ced->submitted);
iReturn = usb_submit_urb(pdx->pUrbCharOut, GFP_KERNEL); iReturn = usb_submit_urb(ced->pUrbCharOut, GFP_KERNEL);
spin_lock_irq(&pdx->charOutLock); /* grab lock for errors */ spin_lock_irq(&ced->charOutLock); /* grab lock for errors */
if (iReturn) { if (iReturn) {
pdx->bPipeError[nPipe] = 1; /* Flag an error to be handled later */ ced->bPipeError[nPipe] = 1; /* Flag an error to be handled later */
pdx->bSendCharsPending = false; /* Allow other threads again */ ced->bSendCharsPending = false; /* Allow other threads again */
usb_unanchor_urb(pdx->pUrbCharOut); /* remove from list of active urbs */ usb_unanchor_urb(ced->pUrbCharOut); /* remove from list of active urbs */
} }
} }
} else if (pdx->bSendCharsPending && (pdx->dwNumOutput > 0)) } else if (ced->bSendCharsPending && (ced->dwNumOutput > 0))
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"%s: bSendCharsPending:true\n", __func__); "%s: bSendCharsPending:true\n", __func__);
dev_dbg(&pdx->interface->dev, "%s: exit code: %d\n", __func__, iReturn); dev_dbg(&ced->interface->dev, "%s: exit code: %d\n", __func__, iReturn);
spin_unlock_irq(&pdx->charOutLock); /* Now let go of the spinlock */ spin_unlock_irq(&ced->charOutLock); /* Now let go of the spinlock */
return iReturn; return iReturn;
} }
...@@ -427,27 +427,27 @@ int ced_send_chars(DEVICE_EXTENSION *pdx) ...@@ -427,27 +427,27 @@ int ced_send_chars(DEVICE_EXTENSION *pdx)
** ced_copy_user_space ** ced_copy_user_space
** This moves memory between pinned down user space and the pCoherStagedIO ** This moves memory between pinned down user space and the pCoherStagedIO
** memory buffer we use for transfers. Copy n bytes in the directions that ** memory buffer we use for transfers. Copy n bytes in the directions that
** is defined by pdx->StagedRead. The user space is determined by the area ** is defined by ced->StagedRead. The user space is determined by the area
** in pdx->StagedId and the offset in pdx->StagedDone. The user ** in ced->StagedId and the offset in ced->StagedDone. The user
** area may well not start on a page boundary, so allow for that. ** area may well not start on a page boundary, so allow for that.
** **
** We have a table of physical pages that describe the area, so we can use ** We have a table of physical pages that describe the area, so we can use
** this to get a virtual address that the kernel can use. ** this to get a virtual address that the kernel can use.
** **
** pdx Is our device extension which holds all we know about the transfer. ** ced Is our device extension which holds all we know about the transfer.
** n The number of bytes to move one way or the other. ** n The number of bytes to move one way or the other.
***************************************************************************/ ***************************************************************************/
static void ced_copy_user_space(DEVICE_EXTENSION *pdx, int n) static void ced_copy_user_space(struct ced_data *ced, int n)
{ {
unsigned int nArea = pdx->StagedId; unsigned int nArea = ced->StagedId;
if (nArea < MAX_TRANSAREAS) { if (nArea < MAX_TRANSAREAS) {
/* area to be used */ /* area to be used */
struct transarea *pArea = &pdx->rTransDef[nArea]; struct transarea *pArea = &ced->rTransDef[nArea];
unsigned int dwOffset = unsigned int dwOffset =
pdx->StagedDone + pdx->StagedOffset + pArea->dwBaseOffset; ced->StagedDone + ced->StagedOffset + pArea->dwBaseOffset;
char *pCoherBuf = pdx->pCoherStagedIO; /* coherent buffer */ char *pCoherBuf = ced->pCoherStagedIO; /* coherent buffer */
if (!pArea->bUsed) { if (!pArea->bUsed) {
dev_err(&pdx->interface->dev, "%s: area %d unused\n", dev_err(&ced->interface->dev, "%s: area %d unused\n",
__func__, nArea); __func__, nArea);
return; return;
} }
...@@ -462,7 +462,7 @@ static void ced_copy_user_space(DEVICE_EXTENSION *pdx, int n) ...@@ -462,7 +462,7 @@ static void ced_copy_user_space(DEVICE_EXTENSION *pdx, int n)
size_t uiXfer = PAGE_SIZE - uiPageOff; /* max to transfer on this page */ size_t uiXfer = PAGE_SIZE - uiPageOff; /* max to transfer on this page */
if (uiXfer > n) /* limit byte count if too much */ if (uiXfer > n) /* limit byte count if too much */
uiXfer = n; /* for the page */ uiXfer = n; /* for the page */
if (pdx->StagedRead) if (ced->StagedRead)
memcpy(pvAddress + uiPageOff, memcpy(pvAddress + uiPageOff,
pCoherBuf, uiXfer); pCoherBuf, uiXfer);
else else
...@@ -474,26 +474,26 @@ static void ced_copy_user_space(DEVICE_EXTENSION *pdx, int n) ...@@ -474,26 +474,26 @@ static void ced_copy_user_space(DEVICE_EXTENSION *pdx, int n)
pCoherBuf += uiXfer; pCoherBuf += uiXfer;
n -= uiXfer; n -= uiXfer;
} else { } else {
dev_err(&pdx->interface->dev, dev_err(&ced->interface->dev,
"%s: did not map page %d\n", "%s: did not map page %d\n",
__func__, nPage); __func__, nPage);
return; return;
} }
} else { } else {
dev_err(&pdx->interface->dev, dev_err(&ced->interface->dev,
"%s: exceeded pages %d\n", "%s: exceeded pages %d\n",
__func__, nPage); __func__, nPage);
return; return;
} }
} }
} else } else
dev_err(&pdx->interface->dev, "%s: bad area %d\n", dev_err(&ced->interface->dev, "%s: bad area %d\n",
__func__, nArea); __func__, nArea);
} }
/* Forward declarations for stuff used circularly */ /* Forward declarations for stuff used circularly */
static int ced_stage_chunk(DEVICE_EXTENSION *pdx); static int ced_stage_chunk(struct ced_data *ced);
/*************************************************************************** /***************************************************************************
** ReadWrite_Complete ** ReadWrite_Complete
** **
...@@ -501,76 +501,76 @@ static int ced_stage_chunk(DEVICE_EXTENSION *pdx); ...@@ -501,76 +501,76 @@ static int ced_stage_chunk(DEVICE_EXTENSION *pdx);
*/ */
static void staged_callback(struct urb *pUrb) static void staged_callback(struct urb *pUrb)
{ {
DEVICE_EXTENSION *pdx = pUrb->context; struct ced_data *ced = pUrb->context;
unsigned int nGot = pUrb->actual_length; /* what we transferred */ unsigned int nGot = pUrb->actual_length; /* what we transferred */
bool bCancel = false; bool bCancel = false;
bool bRestartCharInput; /* used at the end */ bool bRestartCharInput; /* used at the end */
spin_lock(&pdx->stagedLock); /* stop ced_read_write_mem() action while this routine is running */ spin_lock(&ced->stagedLock); /* stop ced_read_write_mem() action while this routine is running */
pdx->bStagedUrbPending = false; /* clear the flag for staged IRP pending */ ced->bStagedUrbPending = false; /* clear the flag for staged IRP pending */
if (pUrb->status) { /* sync/async unlink faults aren't errors */ if (pUrb->status) { /* sync/async unlink faults aren't errors */
if (! if (!
(pUrb->status == -ENOENT || pUrb->status == -ECONNRESET (pUrb->status == -ENOENT || pUrb->status == -ECONNRESET
|| pUrb->status == -ESHUTDOWN)) { || pUrb->status == -ESHUTDOWN)) {
dev_err(&pdx->interface->dev, dev_err(&ced->interface->dev,
"%s: nonzero write bulk status received: %d\n", "%s: nonzero write bulk status received: %d\n",
__func__, pUrb->status); __func__, pUrb->status);
} else } else
dev_info(&pdx->interface->dev, dev_info(&ced->interface->dev,
"%s: staged xfer cancelled\n", __func__); "%s: staged xfer cancelled\n", __func__);
spin_lock(&pdx->err_lock); spin_lock(&ced->err_lock);
pdx->errors = pUrb->status; ced->errors = pUrb->status;
spin_unlock(&pdx->err_lock); spin_unlock(&ced->err_lock);
nGot = 0; /* and tidy up again if so */ nGot = 0; /* and tidy up again if so */
bCancel = true; bCancel = true;
} else { } else {
dev_dbg(&pdx->interface->dev, "%s: %d chars xferred\n", dev_dbg(&ced->interface->dev, "%s: %d chars xferred\n",
__func__, nGot); __func__, nGot);
if (pdx->StagedRead) /* if reading, save to user space */ if (ced->StagedRead) /* if reading, save to user space */
ced_copy_user_space(pdx, nGot); /* copy from buffer to user */ ced_copy_user_space(ced, nGot); /* copy from buffer to user */
if (nGot == 0) if (nGot == 0)
dev_dbg(&pdx->interface->dev, "%s: ZLP\n", __func__); dev_dbg(&ced->interface->dev, "%s: ZLP\n", __func__);
} }
/* Update the transfer length based on the TransferBufferLength value in the URB */ /* Update the transfer length based on the TransferBufferLength value in the URB */
pdx->StagedDone += nGot; ced->StagedDone += nGot;
dev_dbg(&pdx->interface->dev, "%s: done %d bytes of %d\n", dev_dbg(&ced->interface->dev, "%s: done %d bytes of %d\n",
__func__, pdx->StagedDone, pdx->StagedLength); __func__, ced->StagedDone, ced->StagedLength);
if ((pdx->StagedDone == pdx->StagedLength) || /* If no more to do */ if ((ced->StagedDone == ced->StagedLength) || /* If no more to do */
(bCancel)) { /* or this IRP was cancelled */ (bCancel)) { /* or this IRP was cancelled */
/* Transfer area info */ /* Transfer area info */
struct transarea *pArea = &pdx->rTransDef[pdx->StagedId]; struct transarea *pArea = &ced->rTransDef[ced->StagedId];
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"%s: transfer done, bytes %d, cancel %d\n", "%s: transfer done, bytes %d, cancel %d\n",
__func__, pdx->StagedDone, bCancel); __func__, ced->StagedDone, bCancel);
/* Here is where we sort out what to do with this transfer if using a circular buffer. We have */ /* Here is where we sort out what to do with this transfer if using a circular buffer. We have */
/* a completed transfer that can be assumed to fit into the transfer area. We should be able to */ /* a completed transfer that can be assumed to fit into the transfer area. We should be able to */
/* add this to the end of a growing block or to use it to start a new block unless the code */ /* add this to the end of a growing block or to use it to start a new block unless the code */
/* that calculates the offset to use (in ced_read_write_mem) is totally duff. */ /* that calculates the offset to use (in ced_read_write_mem) is totally duff. */
if ((pArea->bCircular) && (pArea->bCircToHost) && (!bCancel) && /* Time to sort out circular buffer info? */ if ((pArea->bCircular) && (pArea->bCircToHost) && (!bCancel) && /* Time to sort out circular buffer info? */
(pdx->StagedRead)) { /* Only for tohost transfers for now */ (ced->StagedRead)) { /* Only for tohost transfers for now */
if (pArea->aBlocks[1].dwSize > 0) { /* If block 1 is in use we must append to it */ if (pArea->aBlocks[1].dwSize > 0) { /* If block 1 is in use we must append to it */
if (pdx->StagedOffset == if (ced->StagedOffset ==
(pArea->aBlocks[1].dwOffset + (pArea->aBlocks[1].dwOffset +
pArea->aBlocks[1].dwSize)) { pArea->aBlocks[1].dwSize)) {
pArea->aBlocks[1].dwSize += pArea->aBlocks[1].dwSize +=
pdx->StagedLength; ced->StagedLength;
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"RWM_Complete, circ block 1 now %d bytes at %d\n", "RWM_Complete, circ block 1 now %d bytes at %d\n",
pArea->aBlocks[1].dwSize, pArea->aBlocks[1].dwSize,
pArea->aBlocks[1].dwOffset); pArea->aBlocks[1].dwOffset);
} else { } else {
/* Here things have gone very, very, wrong, but I cannot see how this can actually be achieved */ /* Here things have gone very, very, wrong, but I cannot see how this can actually be achieved */
pArea->aBlocks[1].dwOffset = pArea->aBlocks[1].dwOffset =
pdx->StagedOffset; ced->StagedOffset;
pArea->aBlocks[1].dwSize = pArea->aBlocks[1].dwSize =
pdx->StagedLength; ced->StagedLength;
dev_err(&pdx->interface->dev, dev_err(&ced->interface->dev,
"%s: ERROR, circ block 1 re-started %d bytes at %d\n", "%s: ERROR, circ block 1 re-started %d bytes at %d\n",
__func__, __func__,
pArea->aBlocks[1].dwSize, pArea->aBlocks[1].dwSize,
...@@ -579,11 +579,11 @@ static void staged_callback(struct urb *pUrb) ...@@ -579,11 +579,11 @@ static void staged_callback(struct urb *pUrb)
} else { /* If block 1 is not used, we try to add to block 0 */ } else { /* If block 1 is not used, we try to add to block 0 */
if (pArea->aBlocks[0].dwSize > 0) { /* Got stored block 0 information? */ if (pArea->aBlocks[0].dwSize > 0) { /* Got stored block 0 information? */
/* Must append onto the existing block 0 */ /* Must append onto the existing block 0 */
if (pdx->StagedOffset == if (ced->StagedOffset ==
(pArea->aBlocks[0].dwOffset + (pArea->aBlocks[0].dwOffset +
pArea->aBlocks[0].dwSize)) { pArea->aBlocks[0].dwSize)) {
pArea->aBlocks[0].dwSize += pdx->StagedLength; /* Just add this transfer in */ pArea->aBlocks[0].dwSize += ced->StagedLength; /* Just add this transfer in */
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"RWM_Complete, circ block 0 now %d bytes at %d\n", "RWM_Complete, circ block 0 now %d bytes at %d\n",
pArea->aBlocks[0]. pArea->aBlocks[0].
dwSize, dwSize,
...@@ -591,10 +591,10 @@ static void staged_callback(struct urb *pUrb) ...@@ -591,10 +591,10 @@ static void staged_callback(struct urb *pUrb)
dwOffset); dwOffset);
} else { /* If it doesn't append, put into new block 1 */ } else { /* If it doesn't append, put into new block 1 */
pArea->aBlocks[1].dwOffset = pArea->aBlocks[1].dwOffset =
pdx->StagedOffset; ced->StagedOffset;
pArea->aBlocks[1].dwSize = pArea->aBlocks[1].dwSize =
pdx->StagedLength; ced->StagedLength;
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"RWM_Complete, circ block 1 started %d bytes at %d\n", "RWM_Complete, circ block 1 started %d bytes at %d\n",
pArea->aBlocks[1]. pArea->aBlocks[1].
dwSize, dwSize,
...@@ -603,10 +603,10 @@ static void staged_callback(struct urb *pUrb) ...@@ -603,10 +603,10 @@ static void staged_callback(struct urb *pUrb)
} }
} else { /* No info stored yet, just save in block 0 */ } else { /* No info stored yet, just save in block 0 */
pArea->aBlocks[0].dwOffset = pArea->aBlocks[0].dwOffset =
pdx->StagedOffset; ced->StagedOffset;
pArea->aBlocks[0].dwSize = pArea->aBlocks[0].dwSize =
pdx->StagedLength; ced->StagedLength;
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"RWM_Complete, circ block 0 started %d bytes at %d\n", "RWM_Complete, circ block 0 started %d bytes at %d\n",
pArea->aBlocks[0].dwSize, pArea->aBlocks[0].dwSize,
pArea->aBlocks[0].dwOffset); pArea->aBlocks[0].dwOffset);
...@@ -615,12 +615,12 @@ static void staged_callback(struct urb *pUrb) ...@@ -615,12 +615,12 @@ static void staged_callback(struct urb *pUrb)
} }
if (!bCancel) { /* Don't generate an event if cancelled */ if (!bCancel) { /* Don't generate an event if cancelled */
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"RWM_Complete, bCircular %d, bToHost %d, eStart %d, eSize %d\n", "RWM_Complete, bCircular %d, bToHost %d, eStart %d, eSize %d\n",
pArea->bCircular, pArea->bEventToHost, pArea->bCircular, pArea->bEventToHost,
pArea->dwEventSt, pArea->dwEventSz); pArea->dwEventSt, pArea->dwEventSz);
if ((pArea->dwEventSz) && /* Set a user-mode event... */ if ((pArea->dwEventSz) && /* Set a user-mode event... */
(pdx->StagedRead == pArea->bEventToHost)) { /* ...on transfers in this direction? */ (ced->StagedRead == pArea->bEventToHost)) { /* ...on transfers in this direction? */
int iWakeUp = 0; /* assume */ int iWakeUp = 0; /* assume */
/* If we have completed the right sort of DMA transfer then set the event to notify */ /* If we have completed the right sort of DMA transfer then set the event to notify */
/* the user code to wake up anyone that is waiting. */ /* the user code to wake up anyone that is waiting. */
...@@ -633,16 +633,16 @@ static void staged_callback(struct urb *pUrb) ...@@ -633,16 +633,16 @@ static void staged_callback(struct urb *pUrb)
iWakeUp = (dwTotal >= pArea->dwEventSz); iWakeUp = (dwTotal >= pArea->dwEventSz);
} else { } else {
unsigned int transEnd = unsigned int transEnd =
pdx->StagedOffset + ced->StagedOffset +
pdx->StagedLength; ced->StagedLength;
unsigned int eventEnd = unsigned int eventEnd =
pArea->dwEventSt + pArea->dwEventSz; pArea->dwEventSt + pArea->dwEventSz;
iWakeUp = (pdx->StagedOffset < eventEnd) iWakeUp = (ced->StagedOffset < eventEnd)
&& (transEnd > pArea->dwEventSt); && (transEnd > pArea->dwEventSt);
} }
if (iWakeUp) { if (iWakeUp) {
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"About to set event to notify app\n"); "About to set event to notify app\n");
wake_up_interruptible(&pArea->wqEvent); /* wake up waiting processes */ wake_up_interruptible(&pArea->wqEvent); /* wake up waiting processes */
++pArea->iWakeUp; /* increment wakeup count */ ++pArea->iWakeUp; /* increment wakeup count */
...@@ -650,44 +650,44 @@ static void staged_callback(struct urb *pUrb) ...@@ -650,44 +650,44 @@ static void staged_callback(struct urb *pUrb)
} }
} }
pdx->dwDMAFlag = MODE_CHAR; /* Switch back to char mode before ced_read_write_mem call */ ced->dwDMAFlag = MODE_CHAR; /* Switch back to char mode before ced_read_write_mem call */
if (!bCancel) { /* Don't look for waiting transfer if cancelled */ if (!bCancel) { /* Don't look for waiting transfer if cancelled */
/* If we have a transfer waiting, kick it off */ /* If we have a transfer waiting, kick it off */
if (pdx->bXFerWaiting) { /* Got a block xfer waiting? */ if (ced->bXFerWaiting) { /* Got a block xfer waiting? */
int iReturn; int iReturn;
dev_info(&pdx->interface->dev, dev_info(&ced->interface->dev,
"*** RWM_Complete *** pending transfer will now be set up!!!\n"); "*** RWM_Complete *** pending transfer will now be set up!!!\n");
iReturn = iReturn =
ced_read_write_mem(pdx, !pdx->rDMAInfo.bOutWard, ced_read_write_mem(ced, !ced->rDMAInfo.bOutWard,
pdx->rDMAInfo.wIdent, ced->rDMAInfo.wIdent,
pdx->rDMAInfo.dwOffset, ced->rDMAInfo.dwOffset,
pdx->rDMAInfo.dwSize); ced->rDMAInfo.dwSize);
if (iReturn) if (iReturn)
dev_err(&pdx->interface->dev, dev_err(&ced->interface->dev,
"RWM_Complete rw setup failed %d\n", "RWM_Complete rw setup failed %d\n",
iReturn); iReturn);
} }
} }
} else /* Here for more to do */ } else /* Here for more to do */
ced_stage_chunk(pdx); /* fire off the next bit */ ced_stage_chunk(ced); /* fire off the next bit */
/* While we hold the stagedLock, see if we should reallow character input ints */ /* While we hold the stagedLock, see if we should reallow character input ints */
/* Don't allow if cancelled, or if a new block has started or if there is a waiting block. */ /* Don't allow if cancelled, or if a new block has started or if there is a waiting block. */
/* This feels wrong as we should ask which spin lock protects dwDMAFlag. */ /* This feels wrong as we should ask which spin lock protects dwDMAFlag. */
bRestartCharInput = !bCancel && (pdx->dwDMAFlag == MODE_CHAR) bRestartCharInput = !bCancel && (ced->dwDMAFlag == MODE_CHAR)
&& !pdx->bXFerWaiting; && !ced->bXFerWaiting;
spin_unlock(&pdx->stagedLock); /* Finally release the lock again */ spin_unlock(&ced->stagedLock); /* Finally release the lock again */
/* This is not correct as dwDMAFlag is protected by the staged lock, but it is treated */ /* This is not correct as dwDMAFlag is protected by the staged lock, but it is treated */
/* in ced_allowi as if it were protected by the char lock. In any case, most systems will */ /* in ced_allowi as if it were protected by the char lock. In any case, most systems will */
/* not be upset by char input during DMA... sigh. Needs sorting out. */ /* not be upset by char input during DMA... sigh. Needs sorting out. */
if (bRestartCharInput) /* may be out of date, but... */ if (bRestartCharInput) /* may be out of date, but... */
ced_allowi(pdx); /* ...ced_allowi tests a lock too. */ ced_allowi(ced); /* ...ced_allowi tests a lock too. */
dev_dbg(&pdx->interface->dev, "%s: done\n", __func__); dev_dbg(&ced->interface->dev, "%s: done\n", __func__);
} }
/**************************************************************************** /****************************************************************************
...@@ -698,47 +698,47 @@ static void staged_callback(struct urb *pUrb) ...@@ -698,47 +698,47 @@ static void staged_callback(struct urb *pUrb)
** The calling code must have acquired the staging spinlock before calling ** The calling code must have acquired the staging spinlock before calling
** this function, and is responsible for releasing it. We are at callback level. ** this function, and is responsible for releasing it. We are at callback level.
****************************************************************************/ ****************************************************************************/
static int ced_stage_chunk(DEVICE_EXTENSION *pdx) static int ced_stage_chunk(struct ced_data *ced)
{ {
int iReturn = U14ERR_NOERROR; int iReturn = U14ERR_NOERROR;
unsigned int ChunkSize; unsigned int ChunkSize;
int nPipe = pdx->StagedRead ? 3 : 2; /* The pipe number to use for reads or writes */ int nPipe = ced->StagedRead ? 3 : 2; /* The pipe number to use for reads or writes */
if (pdx->nPipes == 3) if (ced->nPipes == 3)
nPipe--; /* Adjust for the 3-pipe case */ nPipe--; /* Adjust for the 3-pipe case */
if (nPipe < 0) /* and trap case that should never happen */ if (nPipe < 0) /* and trap case that should never happen */
return U14ERR_FAIL; return U14ERR_FAIL;
if (!can_accept_io_requests(pdx)) { /* got sudden remove? */ if (!can_accept_io_requests(ced)) { /* got sudden remove? */
dev_info(&pdx->interface->dev, "%s: sudden remove, giving up\n", dev_info(&ced->interface->dev, "%s: sudden remove, giving up\n",
__func__); __func__);
return U14ERR_FAIL; /* could do with a better error */ return U14ERR_FAIL; /* could do with a better error */
} }
ChunkSize = (pdx->StagedLength - pdx->StagedDone); /* transfer length remaining */ ChunkSize = (ced->StagedLength - ced->StagedDone); /* transfer length remaining */
if (ChunkSize > STAGED_SZ) /* make sure to keep legal */ if (ChunkSize > STAGED_SZ) /* make sure to keep legal */
ChunkSize = STAGED_SZ; /* limit to max allowed */ ChunkSize = STAGED_SZ; /* limit to max allowed */
if (!pdx->StagedRead) /* if writing... */ if (!ced->StagedRead) /* if writing... */
ced_copy_user_space(pdx, ChunkSize); /* ...copy data into the buffer */ ced_copy_user_space(ced, ChunkSize); /* ...copy data into the buffer */
usb_fill_bulk_urb(pdx->pStagedUrb, pdx->udev, usb_fill_bulk_urb(ced->pStagedUrb, ced->udev,
pdx->StagedRead ? usb_rcvbulkpipe(pdx->udev, ced->StagedRead ? usb_rcvbulkpipe(ced->udev,
pdx-> ced->
epAddr[nPipe]) : epAddr[nPipe]) :
usb_sndbulkpipe(pdx->udev, pdx->epAddr[nPipe]), usb_sndbulkpipe(ced->udev, ced->epAddr[nPipe]),
pdx->pCoherStagedIO, ChunkSize, staged_callback, pdx); ced->pCoherStagedIO, ChunkSize, staged_callback, ced);
pdx->pStagedUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; ced->pStagedUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
usb_anchor_urb(pdx->pStagedUrb, &pdx->submitted); /* in case we need to kill it */ usb_anchor_urb(ced->pStagedUrb, &ced->submitted); /* in case we need to kill it */
iReturn = usb_submit_urb(pdx->pStagedUrb, GFP_ATOMIC); iReturn = usb_submit_urb(ced->pStagedUrb, GFP_ATOMIC);
if (iReturn) { if (iReturn) {
usb_unanchor_urb(pdx->pStagedUrb); /* kill it */ usb_unanchor_urb(ced->pStagedUrb); /* kill it */
pdx->bPipeError[nPipe] = 1; /* Flag an error to be handled later */ ced->bPipeError[nPipe] = 1; /* Flag an error to be handled later */
dev_err(&pdx->interface->dev, "%s: submit urb failed, code %d\n", dev_err(&ced->interface->dev, "%s: submit urb failed, code %d\n",
__func__, iReturn); __func__, iReturn);
} else } else
pdx->bStagedUrbPending = true; /* Set the flag for staged URB pending */ ced->bStagedUrbPending = true; /* Set the flag for staged URB pending */
dev_dbg(&pdx->interface->dev, "%s: done so far:%d, this size:%d\n", dev_dbg(&ced->interface->dev, "%s: done so far:%d, this size:%d\n",
__func__, pdx->StagedDone, ChunkSize); __func__, ced->StagedDone, ChunkSize);
return iReturn; return iReturn;
} }
...@@ -760,34 +760,34 @@ static int ced_stage_chunk(DEVICE_EXTENSION *pdx) ...@@ -760,34 +760,34 @@ static int ced_stage_chunk(DEVICE_EXTENSION *pdx)
** transfer. ** transfer.
** dwLen - the number of bytes to transfer. ** dwLen - the number of bytes to transfer.
*/ */
int ced_read_write_mem(DEVICE_EXTENSION *pdx, bool Read, unsigned short wIdent, int ced_read_write_mem(struct ced_data *ced, bool Read, unsigned short wIdent,
unsigned int dwOffs, unsigned int dwLen) unsigned int dwOffs, unsigned int dwLen)
{ {
/* Transfer area info */ /* Transfer area info */
struct transarea *pArea = &pdx->rTransDef[wIdent]; struct transarea *pArea = &ced->rTransDef[wIdent];
if (!can_accept_io_requests(pdx)) { /* Are we in a state to accept new requests? */ if (!can_accept_io_requests(ced)) { /* Are we in a state to accept new requests? */
dev_err(&pdx->interface->dev, "%s: can't accept requests\n", dev_err(&ced->interface->dev, "%s: can't accept requests\n",
__func__); __func__);
return U14ERR_FAIL; return U14ERR_FAIL;
} }
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"%s: xfer %d bytes to %s, offset %d, area %d\n", "%s: xfer %d bytes to %s, offset %d, area %d\n",
__func__, dwLen, Read ? "host" : "1401", dwOffs, wIdent); __func__, dwLen, Read ? "host" : "1401", dwOffs, wIdent);
/* Amazingly, we can get an escape sequence back before the current staged Urb is done, so we */ /* Amazingly, we can get an escape sequence back before the current staged Urb is done, so we */
/* have to check for this situation and, if so, wait until all is OK. */ /* have to check for this situation and, if so, wait until all is OK. */
if (pdx->bStagedUrbPending) { if (ced->bStagedUrbPending) {
pdx->bXFerWaiting = true; /* Flag we are waiting */ ced->bXFerWaiting = true; /* Flag we are waiting */
dev_info(&pdx->interface->dev, dev_info(&ced->interface->dev,
"%s: xfer is waiting, as previous staged pending\n", "%s: xfer is waiting, as previous staged pending\n",
__func__); __func__);
return U14ERR_NOERROR; return U14ERR_NOERROR;
} }
if (dwLen == 0) { /* allow 0-len read or write; just return success */ if (dwLen == 0) { /* allow 0-len read or write; just return success */
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"%s: OK; zero-len read/write request\n", __func__); "%s: OK; zero-len read/write request\n", __func__);
return U14ERR_NOERROR; return U14ERR_NOERROR;
} }
...@@ -797,7 +797,7 @@ int ced_read_write_mem(DEVICE_EXTENSION *pdx, bool Read, unsigned short wIdent, ...@@ -797,7 +797,7 @@ int ced_read_write_mem(DEVICE_EXTENSION *pdx, bool Read, unsigned short wIdent,
/* If so, we sort out offset ourself */ /* If so, we sort out offset ourself */
bool bWait = false; /* Flag for transfer having to wait */ bool bWait = false; /* Flag for transfer having to wait */
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"Circular buffers are %d at %d and %d at %d\n", "Circular buffers are %d at %d and %d at %d\n",
pArea->aBlocks[0].dwSize, pArea->aBlocks[0].dwOffset, pArea->aBlocks[0].dwSize, pArea->aBlocks[0].dwOffset,
pArea->aBlocks[1].dwSize, pArea->aBlocks[1].dwOffset); pArea->aBlocks[1].dwSize, pArea->aBlocks[1].dwOffset);
...@@ -820,28 +820,28 @@ int ced_read_write_mem(DEVICE_EXTENSION *pdx, bool Read, unsigned short wIdent, ...@@ -820,28 +820,28 @@ int ced_read_write_mem(DEVICE_EXTENSION *pdx, bool Read, unsigned short wIdent,
} }
if (bWait) { /* This transfer will have to wait? */ if (bWait) { /* This transfer will have to wait? */
pdx->bXFerWaiting = true; /* Flag we are waiting */ ced->bXFerWaiting = true; /* Flag we are waiting */
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"%s: xfer waiting for circular buffer space\n", "%s: xfer waiting for circular buffer space\n",
__func__); __func__);
return U14ERR_NOERROR; return U14ERR_NOERROR;
} }
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"%s: circular xfer, %d bytes starting at %d\n", "%s: circular xfer, %d bytes starting at %d\n",
__func__, dwLen, dwOffs); __func__, dwLen, dwOffs);
} }
/* Save the parameters for the read\write transfer */ /* Save the parameters for the read\write transfer */
pdx->StagedRead = Read; /* Save the parameters for this read */ ced->StagedRead = Read; /* Save the parameters for this read */
pdx->StagedId = wIdent; /* ID allows us to get transfer area info */ ced->StagedId = wIdent; /* ID allows us to get transfer area info */
pdx->StagedOffset = dwOffs; /* The area within the transfer area */ ced->StagedOffset = dwOffs; /* The area within the transfer area */
pdx->StagedLength = dwLen; ced->StagedLength = dwLen;
pdx->StagedDone = 0; /* Initialise the byte count */ ced->StagedDone = 0; /* Initialise the byte count */
pdx->dwDMAFlag = MODE_LINEAR; /* Set DMA mode flag at this point */ ced->dwDMAFlag = MODE_LINEAR; /* Set DMA mode flag at this point */
pdx->bXFerWaiting = false; /* Clearly not a transfer waiting now */ ced->bXFerWaiting = false; /* Clearly not a transfer waiting now */
/* KeClearEvent(&pdx->StagingDoneEvent); // Clear the transfer done event */ /* KeClearEvent(&ced->StagingDoneEvent); // Clear the transfer done event */
ced_stage_chunk(pdx); /* fire off the first chunk */ ced_stage_chunk(ced); /* fire off the first chunk */
return U14ERR_NOERROR; return U14ERR_NOERROR;
} }
...@@ -945,14 +945,14 @@ static bool ced_read_huff(volatile unsigned int *pDWord, char *pBuf, ...@@ -945,14 +945,14 @@ static bool ced_read_huff(volatile unsigned int *pDWord, char *pBuf,
** **
*****************************************************************************/ *****************************************************************************/
static bool ced_read_dma_info(volatile struct dmadesc *pDmaDesc, static bool ced_read_dma_info(volatile struct dmadesc *pDmaDesc,
DEVICE_EXTENSION *pdx, struct ced_data *ced,
char *pBuf, unsigned int dwCount) char *pBuf, unsigned int dwCount)
{ {
bool bResult = false; /* assume we won't succeed */ bool bResult = false; /* assume we won't succeed */
unsigned char ucData; unsigned char ucData;
unsigned int dDone = 0; /* We haven't parsed anything so far */ unsigned int dDone = 0; /* We haven't parsed anything so far */
dev_dbg(&pdx->interface->dev, "%s\n", __func__); dev_dbg(&ced->interface->dev, "%s\n", __func__);
if (ced_read_char(&ucData, pBuf, &dDone, dwCount)) { if (ced_read_char(&ucData, pBuf, &dDone, dwCount)) {
unsigned char ucTransCode = (ucData & 0x0F); /* get code for transfer type */ unsigned char ucTransCode = (ucData & 0x0F); /* get code for transfer type */
...@@ -964,7 +964,7 @@ static bool ced_read_dma_info(volatile struct dmadesc *pDmaDesc, ...@@ -964,7 +964,7 @@ static bool ced_read_dma_info(volatile struct dmadesc *pDmaDesc,
pDmaDesc->dwSize = 0; /* initialise other bits */ pDmaDesc->dwSize = 0; /* initialise other bits */
pDmaDesc->dwOffset = 0; pDmaDesc->dwOffset = 0;
dev_dbg(&pdx->interface->dev, "%s: type: %d ident: %d\n", dev_dbg(&ced->interface->dev, "%s: type: %d ident: %d\n",
__func__, pDmaDesc->wTransType, pDmaDesc->wIdent); __func__, pDmaDesc->wTransType, pDmaDesc->wIdent);
pDmaDesc->bOutWard = (ucTransCode != TM_EXTTOHOST); /* set transfer direction */ pDmaDesc->bOutWard = (ucTransCode != TM_EXTTOHOST); /* set transfer direction */
...@@ -979,27 +979,27 @@ static bool ced_read_dma_info(volatile struct dmadesc *pDmaDesc, ...@@ -979,27 +979,27 @@ static bool ced_read_dma_info(volatile struct dmadesc *pDmaDesc,
&& ced_read_huff(&(pDmaDesc->dwSize), pBuf, && ced_read_huff(&(pDmaDesc->dwSize), pBuf,
&dDone, dwCount); &dDone, dwCount);
if (bResult) { if (bResult) {
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"%s: xfer offset & size %d %d\n", "%s: xfer offset & size %d %d\n",
__func__, pDmaDesc->dwOffset, __func__, pDmaDesc->dwOffset,
pDmaDesc->dwSize); pDmaDesc->dwSize);
if ((wIdent >= MAX_TRANSAREAS) || /* Illegal area number, or... */ if ((wIdent >= MAX_TRANSAREAS) || /* Illegal area number, or... */
(!pdx->rTransDef[wIdent].bUsed) || /* area not set up, or... */ (!ced->rTransDef[wIdent].bUsed) || /* area not set up, or... */
(pDmaDesc->dwOffset > pdx->rTransDef[wIdent].dwLength) || /* range/size */ (pDmaDesc->dwOffset > ced->rTransDef[wIdent].dwLength) || /* range/size */
((pDmaDesc->dwOffset + ((pDmaDesc->dwOffset +
pDmaDesc->dwSize) > pDmaDesc->dwSize) >
(pdx->rTransDef[wIdent]. (ced->rTransDef[wIdent].
dwLength))) { dwLength))) {
bResult = false; /* bad parameter(s) */ bResult = false; /* bad parameter(s) */
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"%s: bad param - id %d, bUsed %d, offset %d, size %d, area length %d\n", "%s: bad param - id %d, bUsed %d, offset %d, size %d, area length %d\n",
__func__, wIdent, __func__, wIdent,
pdx->rTransDef[wIdent]. ced->rTransDef[wIdent].
bUsed, bUsed,
pDmaDesc->dwOffset, pDmaDesc->dwOffset,
pDmaDesc->dwSize, pDmaDesc->dwSize,
pdx->rTransDef[wIdent]. ced->rTransDef[wIdent].
dwLength); dwLength);
} }
} }
...@@ -1012,7 +1012,7 @@ static bool ced_read_dma_info(volatile struct dmadesc *pDmaDesc, ...@@ -1012,7 +1012,7 @@ static bool ced_read_dma_info(volatile struct dmadesc *pDmaDesc,
bResult = false; bResult = false;
if (!bResult) /* now check parameters for validity */ if (!bResult) /* now check parameters for validity */
dev_err(&pdx->interface->dev, "%s: error reading Esc sequence\n", dev_err(&ced->interface->dev, "%s: error reading Esc sequence\n",
__func__); __func__);
return bResult; return bResult;
...@@ -1032,7 +1032,7 @@ static bool ced_read_dma_info(volatile struct dmadesc *pDmaDesc, ...@@ -1032,7 +1032,7 @@ static bool ced_read_dma_info(volatile struct dmadesc *pDmaDesc,
** this is known to be at least 2 or we will not be called. ** this is known to be at least 2 or we will not be called.
** **
****************************************************************************/ ****************************************************************************/
static int ced_handle_esc(DEVICE_EXTENSION *pdx, char *pCh, static int ced_handle_esc(struct ced_data *ced, char *pCh,
unsigned int dwCount) unsigned int dwCount)
{ {
int iReturn = U14ERR_FAIL; int iReturn = U14ERR_FAIL;
...@@ -1043,48 +1043,48 @@ static int ced_handle_esc(DEVICE_EXTENSION *pdx, char *pCh, ...@@ -1043,48 +1043,48 @@ static int ced_handle_esc(DEVICE_EXTENSION *pdx, char *pCh,
if (pCh[0] == '?') { /* Is this an information response */ if (pCh[0] == '?') { /* Is this an information response */
/* Parse and save the information */ /* Parse and save the information */
} else { } else {
spin_lock(&pdx->stagedLock); /* Lock others out */ spin_lock(&ced->stagedLock); /* Lock others out */
if (ced_read_dma_info(&pdx->rDMAInfo, pdx, pCh, dwCount)) { /* Get DMA parameters */ if (ced_read_dma_info(&ced->rDMAInfo, ced, pCh, dwCount)) { /* Get DMA parameters */
unsigned short wTransType = pdx->rDMAInfo.wTransType; /* check transfer type */ unsigned short wTransType = ced->rDMAInfo.wTransType; /* check transfer type */
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"%s: xfer to %s, offset %d, length %d\n", "%s: xfer to %s, offset %d, length %d\n",
__func__, __func__,
pdx->rDMAInfo.bOutWard ? "1401" : "host", ced->rDMAInfo.bOutWard ? "1401" : "host",
pdx->rDMAInfo.dwOffset, pdx->rDMAInfo.dwSize); ced->rDMAInfo.dwOffset, ced->rDMAInfo.dwSize);
if (pdx->bXFerWaiting) { /* Check here for badly out of kilter... */ if (ced->bXFerWaiting) { /* Check here for badly out of kilter... */
/* This can never happen, really */ /* This can never happen, really */
dev_err(&pdx->interface->dev, dev_err(&ced->interface->dev,
"ERROR: DMA setup while transfer still waiting\n"); "ERROR: DMA setup while transfer still waiting\n");
} else { } else {
if ((wTransType == TM_EXTTOHOST) if ((wTransType == TM_EXTTOHOST)
|| (wTransType == TM_EXTTO1401)) { || (wTransType == TM_EXTTO1401)) {
iReturn = iReturn =
ced_read_write_mem(pdx, ced_read_write_mem(ced,
!pdx->rDMAInfo. !ced->rDMAInfo.
bOutWard, bOutWard,
pdx->rDMAInfo.wIdent, ced->rDMAInfo.wIdent,
pdx->rDMAInfo.dwOffset, ced->rDMAInfo.dwOffset,
pdx->rDMAInfo.dwSize); ced->rDMAInfo.dwSize);
if (iReturn != U14ERR_NOERROR) if (iReturn != U14ERR_NOERROR)
dev_err(&pdx->interface->dev, dev_err(&ced->interface->dev,
"%s: ced_read_write_mem() failed %d\n", "%s: ced_read_write_mem() failed %d\n",
__func__, iReturn); __func__, iReturn);
} else /* This covers non-linear transfer setup */ } else /* This covers non-linear transfer setup */
dev_err(&pdx->interface->dev, dev_err(&ced->interface->dev,
"%s: Unknown block xfer type %d\n", "%s: Unknown block xfer type %d\n",
__func__, wTransType); __func__, wTransType);
} }
} else /* Failed to read parameters */ } else /* Failed to read parameters */
dev_err(&pdx->interface->dev, "%s: ced_read_dma_info() fail\n", dev_err(&ced->interface->dev, "%s: ced_read_dma_info() fail\n",
__func__); __func__);
spin_unlock(&pdx->stagedLock); /* OK here */ spin_unlock(&ced->stagedLock); /* OK here */
} }
dev_dbg(&pdx->interface->dev, "%s: returns %d\n", __func__, iReturn); dev_dbg(&ced->interface->dev, "%s: returns %d\n", __func__, iReturn);
return iReturn; return iReturn;
} }
...@@ -1094,65 +1094,65 @@ static int ced_handle_esc(DEVICE_EXTENSION *pdx, char *pCh, ...@@ -1094,65 +1094,65 @@ static int ced_handle_esc(DEVICE_EXTENSION *pdx, char *pCh,
****************************************************************************/ ****************************************************************************/
static void ced_readchar_callback(struct urb *pUrb) static void ced_readchar_callback(struct urb *pUrb)
{ {
DEVICE_EXTENSION *pdx = pUrb->context; struct ced_data *ced = pUrb->context;
int nGot = pUrb->actual_length; /* what we transferred */ int nGot = pUrb->actual_length; /* what we transferred */
if (pUrb->status) { /* Do we have a problem to handle? */ if (pUrb->status) { /* Do we have a problem to handle? */
int nPipe = pdx->nPipes == 4 ? 1 : 0; /* The pipe number to use for error */ int nPipe = ced->nPipes == 4 ? 1 : 0; /* The pipe number to use for error */
/* sync/async unlink faults aren't errors... just saying device removed or stopped */ /* sync/async unlink faults aren't errors... just saying device removed or stopped */
if (! if (!
(pUrb->status == -ENOENT || pUrb->status == -ECONNRESET (pUrb->status == -ENOENT || pUrb->status == -ECONNRESET
|| pUrb->status == -ESHUTDOWN)) { || pUrb->status == -ESHUTDOWN)) {
dev_err(&pdx->interface->dev, dev_err(&ced->interface->dev,
"%s: nonzero write bulk status received: %d\n", "%s: nonzero write bulk status received: %d\n",
__func__, pUrb->status); __func__, pUrb->status);
} else } else
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"%s: 0 chars pUrb->status=%d (shutdown?)\n", "%s: 0 chars pUrb->status=%d (shutdown?)\n",
__func__, pUrb->status); __func__, pUrb->status);
spin_lock(&pdx->err_lock); spin_lock(&ced->err_lock);
pdx->errors = pUrb->status; ced->errors = pUrb->status;
spin_unlock(&pdx->err_lock); spin_unlock(&ced->err_lock);
nGot = 0; /* and tidy up again if so */ nGot = 0; /* and tidy up again if so */
spin_lock(&pdx->charInLock); /* already at irq level */ spin_lock(&ced->charInLock); /* already at irq level */
pdx->bPipeError[nPipe] = 1; /* Flag an error for later */ ced->bPipeError[nPipe] = 1; /* Flag an error for later */
} else { } else {
if ((nGot > 1) && ((pdx->pCoherCharIn[0] & 0x7f) == 0x1b)) { /* Esc sequence? */ if ((nGot > 1) && ((ced->pCoherCharIn[0] & 0x7f) == 0x1b)) { /* Esc sequence? */
ced_handle_esc(pdx, &pdx->pCoherCharIn[1], nGot - 1); /* handle it */ ced_handle_esc(ced, &ced->pCoherCharIn[1], nGot - 1); /* handle it */
spin_lock(&pdx->charInLock); /* already at irq level */ spin_lock(&ced->charInLock); /* already at irq level */
} else { } else {
spin_lock(&pdx->charInLock); /* already at irq level */ spin_lock(&ced->charInLock); /* already at irq level */
if (nGot > 0) { if (nGot > 0) {
unsigned int i; unsigned int i;
if (nGot < INBUF_SZ) { if (nGot < INBUF_SZ) {
pdx->pCoherCharIn[nGot] = 0; /* tidy the string */ ced->pCoherCharIn[nGot] = 0; /* tidy the string */
dev_dbg(&pdx->interface->dev, dev_dbg(&ced->interface->dev,
"%s: got %d chars >%s<\n", "%s: got %d chars >%s<\n",
__func__, nGot, __func__, nGot,
pdx->pCoherCharIn); ced->pCoherCharIn);
} }
/* We know that whatever we read must fit in the input buffer */ /* We know that whatever we read must fit in the input buffer */
for (i = 0; i < nGot; i++) { for (i = 0; i < nGot; i++) {
pdx->inputBuffer[pdx->dwInBuffPut++] = ced->inputBuffer[ced->dwInBuffPut++] =
pdx->pCoherCharIn[i] & 0x7F; ced->pCoherCharIn[i] & 0x7F;
if (pdx->dwInBuffPut >= INBUF_SZ) if (ced->dwInBuffPut >= INBUF_SZ)
pdx->dwInBuffPut = 0; ced->dwInBuffPut = 0;
} }
if ((pdx->dwNumInput + nGot) <= INBUF_SZ) if ((ced->dwNumInput + nGot) <= INBUF_SZ)
pdx->dwNumInput += nGot; /* Adjust the buffer count accordingly */ ced->dwNumInput += nGot; /* Adjust the buffer count accordingly */
} else } else
dev_dbg(&pdx->interface->dev, "%s: read ZLP\n", dev_dbg(&ced->interface->dev, "%s: read ZLP\n",
__func__); __func__);
} }
} }
pdx->bReadCharsPending = false; /* No longer have a pending read */ ced->bReadCharsPending = false; /* No longer have a pending read */
spin_unlock(&pdx->charInLock); /* already at irq level */ spin_unlock(&ced->charInLock); /* already at irq level */
ced_allowi(pdx); /* see if we can do the next one */ ced_allowi(ced); /* see if we can do the next one */
} }
/**************************************************************************** /****************************************************************************
...@@ -1162,47 +1162,47 @@ static void ced_readchar_callback(struct urb *pUrb) ...@@ -1162,47 +1162,47 @@ static void ced_readchar_callback(struct urb *pUrb)
** we can pick up any inward transfers. This can be called in multiple contexts ** we can pick up any inward transfers. This can be called in multiple contexts
** so we use the irqsave version of the spinlock. ** so we use the irqsave version of the spinlock.
****************************************************************************/ ****************************************************************************/
int ced_allowi(DEVICE_EXTENSION *pdx) int ced_allowi(struct ced_data *ced)
{ {
int iReturn = U14ERR_NOERROR; int iReturn = U14ERR_NOERROR;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&pdx->charInLock, flags); /* can be called in multiple contexts */ spin_lock_irqsave(&ced->charInLock, flags); /* can be called in multiple contexts */
/* We don't want char input running while DMA is in progress as we know that this */ /* We don't want char input running while DMA is in progress as we know that this */
/* can cause sequencing problems for the 2270. So don't. It will also allow the */ /* can cause sequencing problems for the 2270. So don't. It will also allow the */
/* ERR response to get back to the host code too early on some PCs, even if there */ /* ERR response to get back to the host code too early on some PCs, even if there */
/* is no actual driver failure, so we don't allow this at all. */ /* is no actual driver failure, so we don't allow this at all. */
if (!pdx->bInDrawDown && /* stop input if */ if (!ced->bInDrawDown && /* stop input if */
!pdx->bReadCharsPending && /* If no read request outstanding */ !ced->bReadCharsPending && /* If no read request outstanding */
(pdx->dwNumInput < (INBUF_SZ / 2)) && /* and there is some space */ (ced->dwNumInput < (INBUF_SZ / 2)) && /* and there is some space */
(pdx->dwDMAFlag == MODE_CHAR) && /* not doing any DMA */ (ced->dwDMAFlag == MODE_CHAR) && /* not doing any DMA */
(!pdx->bXFerWaiting) && /* no xfer waiting to start */ (!ced->bXFerWaiting) && /* no xfer waiting to start */
(can_accept_io_requests(pdx))) { /* and activity is generally OK */ (can_accept_io_requests(ced))) { /* and activity is generally OK */
/* then off we go */ /* then off we go */
unsigned int nMax = INBUF_SZ - pdx->dwNumInput; /* max we could read */ unsigned int nMax = INBUF_SZ - ced->dwNumInput; /* max we could read */
int nPipe = pdx->nPipes == 4 ? 1 : 0; /* The pipe number to use */ int nPipe = ced->nPipes == 4 ? 1 : 0; /* The pipe number to use */
dev_dbg(&pdx->interface->dev, "%s: %d chars in input buffer\n", dev_dbg(&ced->interface->dev, "%s: %d chars in input buffer\n",
__func__, pdx->dwNumInput); __func__, ced->dwNumInput);
usb_fill_int_urb(pdx->pUrbCharIn, pdx->udev, usb_fill_int_urb(ced->pUrbCharIn, ced->udev,
usb_rcvintpipe(pdx->udev, pdx->epAddr[nPipe]), usb_rcvintpipe(ced->udev, ced->epAddr[nPipe]),
pdx->pCoherCharIn, nMax, ced_readchar_callback, ced->pCoherCharIn, nMax, ced_readchar_callback,
pdx, pdx->bInterval); ced, ced->bInterval);
pdx->pUrbCharIn->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* short xfers are OK by default */ ced->pUrbCharIn->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* short xfers are OK by default */
usb_anchor_urb(pdx->pUrbCharIn, &pdx->submitted); /* in case we need to kill it */ usb_anchor_urb(ced->pUrbCharIn, &ced->submitted); /* in case we need to kill it */
iReturn = usb_submit_urb(pdx->pUrbCharIn, GFP_ATOMIC); iReturn = usb_submit_urb(ced->pUrbCharIn, GFP_ATOMIC);
if (iReturn) { if (iReturn) {
usb_unanchor_urb(pdx->pUrbCharIn); /* remove from list of active Urbs */ usb_unanchor_urb(ced->pUrbCharIn); /* remove from list of active Urbs */
pdx->bPipeError[nPipe] = 1; /* Flag an error to be handled later */ ced->bPipeError[nPipe] = 1; /* Flag an error to be handled later */
dev_err(&pdx->interface->dev, dev_err(&ced->interface->dev,
"%s: submit urb failed: %d\n", "%s: submit urb failed: %d\n",
__func__, iReturn); __func__, iReturn);
} else } else
pdx->bReadCharsPending = true; /* Flag that we are active here */ ced->bReadCharsPending = true; /* Flag that we are active here */
} }
spin_unlock_irqrestore(&pdx->charInLock, flags); spin_unlock_irqrestore(&ced->charInLock, flags);
return iReturn; return iReturn;
...@@ -1211,15 +1211,15 @@ int ced_allowi(DEVICE_EXTENSION *pdx) ...@@ -1211,15 +1211,15 @@ int ced_allowi(DEVICE_EXTENSION *pdx)
/***************************************************************************** /*****************************************************************************
** The ioctl entry point to the driver that is used by us to talk to it. ** The ioctl entry point to the driver that is used by us to talk to it.
** inode The device node (no longer in 3.0.0 kernels) ** inode The device node (no longer in 3.0.0 kernels)
** file The file that is open, which holds our pdx pointer ** file The file that is open, which holds our ced pointer
** ulArg The argument passed in. Note that long is 64-bits in 64-bit system, i.e. it is big ** ulArg The argument passed in. Note that long is 64-bits in 64-bit system, i.e. it is big
** enough for a 64-bit pointer. ** enough for a 64-bit pointer.
*****************************************************************************/ *****************************************************************************/
static long ced_ioctl(struct file *file, unsigned int cmd, unsigned long ulArg) static long ced_ioctl(struct file *file, unsigned int cmd, unsigned long ulArg)
{ {
int err = 0; int err = 0;
DEVICE_EXTENSION *pdx = file->private_data; struct ced_data *ced = file->private_data;
if (!can_accept_io_requests(pdx)) /* check we still exist */ if (!can_accept_io_requests(ced)) /* check we still exist */
return -ENODEV; return -ENODEV;
/* Check that access is allowed, where is is needed. Anything that would have an indeterminate */ /* Check that access is allowed, where is is needed. Anything that would have an indeterminate */
...@@ -1233,38 +1233,38 @@ static long ced_ioctl(struct file *file, unsigned int cmd, unsigned long ulArg) ...@@ -1233,38 +1233,38 @@ static long ced_ioctl(struct file *file, unsigned int cmd, unsigned long ulArg)
switch (_IOC_NR(cmd)) { switch (_IOC_NR(cmd)) {
case _IOC_NR(IOCTL_CED_SENDSTRING(0)): case _IOC_NR(IOCTL_CED_SENDSTRING(0)):
return ced_send_string(pdx, (const char __user *)ulArg, return ced_send_string(ced, (const char __user *)ulArg,
_IOC_SIZE(cmd)); _IOC_SIZE(cmd));
case _IOC_NR(IOCTL_CED_RESET1401): case _IOC_NR(IOCTL_CED_RESET1401):
return ced_reset(pdx); return ced_reset(ced);
case _IOC_NR(IOCTL_CED_GETCHAR): case _IOC_NR(IOCTL_CED_GETCHAR):
return ced_get_char(pdx); return ced_get_char(ced);
case _IOC_NR(IOCTL_CED_SENDCHAR): case _IOC_NR(IOCTL_CED_SENDCHAR):
return ced_send_char(pdx, (char)ulArg); return ced_send_char(ced, (char)ulArg);
case _IOC_NR(IOCTL_CED_STAT1401): case _IOC_NR(IOCTL_CED_STAT1401):
return ced_stat_1401(pdx); return ced_stat_1401(ced);
case _IOC_NR(IOCTL_CED_LINECOUNT): case _IOC_NR(IOCTL_CED_LINECOUNT):
return ced_line_count(pdx); return ced_line_count(ced);
case _IOC_NR(IOCTL_CED_GETSTRING(0)): case _IOC_NR(IOCTL_CED_GETSTRING(0)):
return ced_get_string(pdx, (char __user *)ulArg, _IOC_SIZE(cmd)); return ced_get_string(ced, (char __user *)ulArg, _IOC_SIZE(cmd));
case _IOC_NR(IOCTL_CED_SETTRANSFER): case _IOC_NR(IOCTL_CED_SETTRANSFER):
return ced_set_transfer(pdx, (struct transfer_area_desc __user *) ulArg); return ced_set_transfer(ced, (struct transfer_area_desc __user *) ulArg);
case _IOC_NR(IOCTL_CED_UNSETTRANSFER): case _IOC_NR(IOCTL_CED_UNSETTRANSFER):
return ced_unset_transfer(pdx, (int)ulArg); return ced_unset_transfer(ced, (int)ulArg);
case _IOC_NR(IOCTL_CED_SETEVENT): case _IOC_NR(IOCTL_CED_SETEVENT):
return ced_set_event(pdx, (struct transfer_event __user *) ulArg); return ced_set_event(ced, (struct transfer_event __user *) ulArg);
case _IOC_NR(IOCTL_CED_GETOUTBUFSPACE): case _IOC_NR(IOCTL_CED_GETOUTBUFSPACE):
return ced_get_out_buf_space(pdx); return ced_get_out_buf_space(ced);
case _IOC_NR(IOCTL_CED_GETBASEADDRESS): case _IOC_NR(IOCTL_CED_GETBASEADDRESS):
return -1; return -1;
...@@ -1273,66 +1273,66 @@ static long ced_ioctl(struct file *file, unsigned int cmd, unsigned long ulArg) ...@@ -1273,66 +1273,66 @@ static long ced_ioctl(struct file *file, unsigned int cmd, unsigned long ulArg)
return (2 << 24) | (DRIVERMAJREV << 16) | DRIVERMINREV; /* USB | MAJOR | MINOR */ return (2 << 24) | (DRIVERMAJREV << 16) | DRIVERMINREV; /* USB | MAJOR | MINOR */
case _IOC_NR(IOCTL_CED_GETTRANSFER): case _IOC_NR(IOCTL_CED_GETTRANSFER):
return ced_get_transfer(pdx, (TGET_TX_BLOCK __user *) ulArg); return ced_get_transfer(ced, (TGET_TX_BLOCK __user *) ulArg);
case _IOC_NR(IOCTL_CED_KILLIO1401): case _IOC_NR(IOCTL_CED_KILLIO1401):
return ced_kill_io(pdx); return ced_kill_io(ced);
case _IOC_NR(IOCTL_CED_STATEOF1401): case _IOC_NR(IOCTL_CED_STATEOF1401):
return ced_state_of_1401(pdx); return ced_state_of_1401(ced);
case _IOC_NR(IOCTL_CED_GRAB1401): case _IOC_NR(IOCTL_CED_GRAB1401):
case _IOC_NR(IOCTL_CED_FREE1401): case _IOC_NR(IOCTL_CED_FREE1401):
return U14ERR_NOERROR; return U14ERR_NOERROR;
case _IOC_NR(IOCTL_CED_STARTSELFTEST): case _IOC_NR(IOCTL_CED_STARTSELFTEST):
return ced_start_self_test(pdx); return ced_start_self_test(ced);
case _IOC_NR(IOCTL_CED_CHECKSELFTEST): case _IOC_NR(IOCTL_CED_CHECKSELFTEST):
return ced_check_self_test(pdx, (TGET_SELFTEST __user *) ulArg); return ced_check_self_test(ced, (TGET_SELFTEST __user *) ulArg);
case _IOC_NR(IOCTL_CED_TYPEOF1401): case _IOC_NR(IOCTL_CED_TYPEOF1401):
return ced_type_of_1401(pdx); return ced_type_of_1401(ced);
case _IOC_NR(IOCTL_CED_TRANSFERFLAGS): case _IOC_NR(IOCTL_CED_TRANSFERFLAGS):
return ced_transfer_flags(pdx); return ced_transfer_flags(ced);
case _IOC_NR(IOCTL_CED_DBGPEEK): case _IOC_NR(IOCTL_CED_DBGPEEK):
return ced_dbg_peek(pdx, (TDBGBLOCK __user *) ulArg); return ced_dbg_peek(ced, (TDBGBLOCK __user *) ulArg);
case _IOC_NR(IOCTL_CED_DBGPOKE): case _IOC_NR(IOCTL_CED_DBGPOKE):
return ced_dbg_poke(pdx, (TDBGBLOCK __user *) ulArg); return ced_dbg_poke(ced, (TDBGBLOCK __user *) ulArg);
case _IOC_NR(IOCTL_CED_DBGRAMPDATA): case _IOC_NR(IOCTL_CED_DBGRAMPDATA):
return ced_dbg_ramp_data(pdx, (TDBGBLOCK __user *) ulArg); return ced_dbg_ramp_data(ced, (TDBGBLOCK __user *) ulArg);
case _IOC_NR(IOCTL_CED_DBGRAMPADDR): case _IOC_NR(IOCTL_CED_DBGRAMPADDR):
return ced_dbg_ramp_addr(pdx, (TDBGBLOCK __user *) ulArg); return ced_dbg_ramp_addr(ced, (TDBGBLOCK __user *) ulArg);
case _IOC_NR(IOCTL_CED_DBGGETDATA): case _IOC_NR(IOCTL_CED_DBGGETDATA):
return ced_dbg_get_data(pdx, (TDBGBLOCK __user *) ulArg); return ced_dbg_get_data(ced, (TDBGBLOCK __user *) ulArg);
case _IOC_NR(IOCTL_CED_DBGSTOPLOOP): case _IOC_NR(IOCTL_CED_DBGSTOPLOOP):
return ced_dbg_stop_loop(pdx); return ced_dbg_stop_loop(ced);
case _IOC_NR(IOCTL_CED_FULLRESET): case _IOC_NR(IOCTL_CED_FULLRESET):
pdx->bForceReset = true; /* Set a flag for a full reset */ ced->bForceReset = true; /* Set a flag for a full reset */
break; break;
case _IOC_NR(IOCTL_CED_SETCIRCULAR): case _IOC_NR(IOCTL_CED_SETCIRCULAR):
return ced_set_circular(pdx, (struct transfer_area_desc __user *) ulArg); return ced_set_circular(ced, (struct transfer_area_desc __user *) ulArg);
case _IOC_NR(IOCTL_CED_GETCIRCBLOCK): case _IOC_NR(IOCTL_CED_GETCIRCBLOCK):
return ced_get_circ_block(pdx, (TCIRCBLOCK __user *) ulArg); return ced_get_circ_block(ced, (TCIRCBLOCK __user *) ulArg);
case _IOC_NR(IOCTL_CED_FREECIRCBLOCK): case _IOC_NR(IOCTL_CED_FREECIRCBLOCK):
return ced_free_circ_block(pdx, (TCIRCBLOCK __user *) ulArg); return ced_free_circ_block(ced, (TCIRCBLOCK __user *) ulArg);
case _IOC_NR(IOCTL_CED_WAITEVENT): case _IOC_NR(IOCTL_CED_WAITEVENT):
return ced_wait_event(pdx, (int)(ulArg & 0xff), (int)(ulArg >> 8)); return ced_wait_event(ced, (int)(ulArg & 0xff), (int)(ulArg >> 8));
case _IOC_NR(IOCTL_CED_TESTEVENT): case _IOC_NR(IOCTL_CED_TESTEVENT):
return ced_test_event(pdx, (int)ulArg); return ced_test_event(ced, (int)ulArg);
default: default:
return U14ERR_NO_SUCH_FN; return U14ERR_NO_SUCH_FN;
...@@ -1360,47 +1360,47 @@ static struct usb_class_driver ced_class = { ...@@ -1360,47 +1360,47 @@ static struct usb_class_driver ced_class = {
}; };
/* Check that the device that matches a 1401 vendor and product ID is OK to use and */ /* Check that the device that matches a 1401 vendor and product ID is OK to use and */
/* initialise our DEVICE_EXTENSION. */ /* initialise our struct ced_data. */
static int ced_probe(struct usb_interface *interface, static int ced_probe(struct usb_interface *interface,
const struct usb_device_id *id) const struct usb_device_id *id)
{ {
DEVICE_EXTENSION *pdx; struct ced_data *ced;
struct usb_host_interface *iface_desc; struct usb_host_interface *iface_desc;
struct usb_endpoint_descriptor *endpoint; struct usb_endpoint_descriptor *endpoint;
int i, bcdDevice; int i, bcdDevice;
int retval = -ENOMEM; int retval = -ENOMEM;
/* allocate memory for our device extension and initialize it */ /* allocate memory for our device extension and initialize it */
pdx = kzalloc(sizeof(*pdx), GFP_KERNEL); ced = kzalloc(sizeof(*ced), GFP_KERNEL);
if (!pdx) if (!ced)
goto error; goto error;
for (i = 0; i < MAX_TRANSAREAS; ++i) { /* Initialise the wait queues */ for (i = 0; i < MAX_TRANSAREAS; ++i) { /* Initialise the wait queues */
init_waitqueue_head(&pdx->rTransDef[i].wqEvent); init_waitqueue_head(&ced->rTransDef[i].wqEvent);
} }
/* Put initialises for our stuff here. Note that all of *pdx is zero, so */ /* Put initialises for our stuff here. Note that all of *ced is zero, so */
/* no need to explicitly zero it. */ /* no need to explicitly zero it. */
spin_lock_init(&pdx->charOutLock); spin_lock_init(&ced->charOutLock);
spin_lock_init(&pdx->charInLock); spin_lock_init(&ced->charInLock);
spin_lock_init(&pdx->stagedLock); spin_lock_init(&ced->stagedLock);
/* Initialises from the skeleton stuff */ /* Initialises from the skeleton stuff */
kref_init(&pdx->kref); kref_init(&ced->kref);
mutex_init(&pdx->io_mutex); mutex_init(&ced->io_mutex);
spin_lock_init(&pdx->err_lock); spin_lock_init(&ced->err_lock);
init_usb_anchor(&pdx->submitted); init_usb_anchor(&ced->submitted);
pdx->udev = usb_get_dev(interface_to_usbdev(interface)); ced->udev = usb_get_dev(interface_to_usbdev(interface));
pdx->interface = interface; ced->interface = interface;
/* Attempt to identify the device */ /* Attempt to identify the device */
bcdDevice = pdx->udev->descriptor.bcdDevice; bcdDevice = ced->udev->descriptor.bcdDevice;
i = (bcdDevice >> 8); i = (bcdDevice >> 8);
if (i == 0) if (i == 0)
pdx->s1401Type = TYPEU1401; ced->s1401Type = TYPEU1401;
else if ((i >= 1) && (i <= 23)) else if ((i >= 1) && (i <= 23))
pdx->s1401Type = i + 2; ced->s1401Type = i + 2;
else { else {
dev_err(&interface->dev, "%s: Unknown device. bcdDevice = %d\n", dev_err(&interface->dev, "%s: Unknown device. bcdDevice = %d\n",
__func__, bcdDevice); __func__, bcdDevice);
...@@ -1409,58 +1409,58 @@ static int ced_probe(struct usb_interface *interface, ...@@ -1409,58 +1409,58 @@ static int ced_probe(struct usb_interface *interface,
/* set up the endpoint information. We only care about the number of EP as */ /* set up the endpoint information. We only care about the number of EP as */
/* we know that we are dealing with a 1401 device. */ /* we know that we are dealing with a 1401 device. */
iface_desc = interface->cur_altsetting; iface_desc = interface->cur_altsetting;
pdx->nPipes = iface_desc->desc.bNumEndpoints; ced->nPipes = iface_desc->desc.bNumEndpoints;
dev_info(&interface->dev, "1401Type=%d with %d End Points\n", dev_info(&interface->dev, "1401Type=%d with %d End Points\n",
pdx->s1401Type, pdx->nPipes); ced->s1401Type, ced->nPipes);
if ((pdx->nPipes < 3) || (pdx->nPipes > 4)) if ((ced->nPipes < 3) || (ced->nPipes > 4))
goto error; goto error;
/* Allocate the URBs we hold for performing transfers */ /* Allocate the URBs we hold for performing transfers */
pdx->pUrbCharOut = usb_alloc_urb(0, GFP_KERNEL); /* character output URB */ ced->pUrbCharOut = usb_alloc_urb(0, GFP_KERNEL); /* character output URB */
pdx->pUrbCharIn = usb_alloc_urb(0, GFP_KERNEL); /* character input URB */ ced->pUrbCharIn = usb_alloc_urb(0, GFP_KERNEL); /* character input URB */
pdx->pStagedUrb = usb_alloc_urb(0, GFP_KERNEL); /* block transfer URB */ ced->pStagedUrb = usb_alloc_urb(0, GFP_KERNEL); /* block transfer URB */
if (!pdx->pUrbCharOut || !pdx->pUrbCharIn || !pdx->pStagedUrb) { if (!ced->pUrbCharOut || !ced->pUrbCharIn || !ced->pStagedUrb) {
dev_err(&interface->dev, "%s: URB alloc failed\n", __func__); dev_err(&interface->dev, "%s: URB alloc failed\n", __func__);
goto error; goto error;
} }
pdx->pCoherStagedIO = ced->pCoherStagedIO =
usb_alloc_coherent(pdx->udev, STAGED_SZ, GFP_KERNEL, usb_alloc_coherent(ced->udev, STAGED_SZ, GFP_KERNEL,
&pdx->pStagedUrb->transfer_dma); &ced->pStagedUrb->transfer_dma);
pdx->pCoherCharOut = ced->pCoherCharOut =
usb_alloc_coherent(pdx->udev, OUTBUF_SZ, GFP_KERNEL, usb_alloc_coherent(ced->udev, OUTBUF_SZ, GFP_KERNEL,
&pdx->pUrbCharOut->transfer_dma); &ced->pUrbCharOut->transfer_dma);
pdx->pCoherCharIn = ced->pCoherCharIn =
usb_alloc_coherent(pdx->udev, INBUF_SZ, GFP_KERNEL, usb_alloc_coherent(ced->udev, INBUF_SZ, GFP_KERNEL,
&pdx->pUrbCharIn->transfer_dma); &ced->pUrbCharIn->transfer_dma);
if (!pdx->pCoherCharOut || !pdx->pCoherCharIn || !pdx->pCoherStagedIO) { if (!ced->pCoherCharOut || !ced->pCoherCharIn || !ced->pCoherStagedIO) {
dev_err(&interface->dev, "%s: Coherent buffer alloc failed\n", dev_err(&interface->dev, "%s: Coherent buffer alloc failed\n",
__func__); __func__);
goto error; goto error;
} }
for (i = 0; i < pdx->nPipes; ++i) { for (i = 0; i < ced->nPipes; ++i) {
endpoint = &iface_desc->endpoint[i].desc; endpoint = &iface_desc->endpoint[i].desc;
pdx->epAddr[i] = endpoint->bEndpointAddress; ced->epAddr[i] = endpoint->bEndpointAddress;
dev_info(&interface->dev, "Pipe %d, ep address %02x\n", dev_info(&interface->dev, "Pipe %d, ep address %02x\n",
i, pdx->epAddr[i]); i, ced->epAddr[i]);
if (((pdx->nPipes == 3) && (i == 0)) || /* if char input end point */ if (((ced->nPipes == 3) && (i == 0)) || /* if char input end point */
((pdx->nPipes == 4) && (i == 1))) { ((ced->nPipes == 4) && (i == 1))) {
pdx->bInterval = endpoint->bInterval; /* save the endpoint interrupt interval */ ced->bInterval = endpoint->bInterval; /* save the endpoint interrupt interval */
dev_info(&interface->dev, "Pipe %d, bInterval = %d\n", dev_info(&interface->dev, "Pipe %d, bInterval = %d\n",
i, pdx->bInterval); i, ced->bInterval);
} }
/* Detect USB2 by checking last ep size (64 if USB1) */ /* Detect USB2 by checking last ep size (64 if USB1) */
if (i == pdx->nPipes - 1) { /* if this is the last ep (bulk) */ if (i == ced->nPipes - 1) { /* if this is the last ep (bulk) */
pdx->bIsUSB2 = ced->bIsUSB2 =
le16_to_cpu(endpoint->wMaxPacketSize) > 64; le16_to_cpu(endpoint->wMaxPacketSize) > 64;
dev_info(&pdx->interface->dev, "USB%d\n", dev_info(&ced->interface->dev, "USB%d\n",
pdx->bIsUSB2 + 1); ced->bIsUSB2 + 1);
} }
} }
/* save our data pointer in this interface device */ /* save our data pointer in this interface device */
usb_set_intfdata(interface, pdx); usb_set_intfdata(interface, ced);
/* we can register the device now, as it is ready */ /* we can register the device now, as it is ready */
retval = usb_register_dev(interface, &ced_class); retval = usb_register_dev(interface, &ced_class);
...@@ -1479,34 +1479,34 @@ static int ced_probe(struct usb_interface *interface, ...@@ -1479,34 +1479,34 @@ static int ced_probe(struct usb_interface *interface,
return 0; return 0;
error: error:
if (pdx) if (ced)
kref_put(&pdx->kref, ced_delete); /* frees allocated memory */ kref_put(&ced->kref, ced_delete); /* frees allocated memory */
return retval; return retval;
} }
static void ced_disconnect(struct usb_interface *interface) static void ced_disconnect(struct usb_interface *interface)
{ {
DEVICE_EXTENSION *pdx = usb_get_intfdata(interface); struct ced_data *ced = usb_get_intfdata(interface);
int minor = interface->minor; int minor = interface->minor;
int i; int i;
usb_set_intfdata(interface, NULL); /* remove the pdx from the interface */ usb_set_intfdata(interface, NULL); /* remove the ced from the interface */
usb_deregister_dev(interface, &ced_class); /* give back our minor device number */ usb_deregister_dev(interface, &ced_class); /* give back our minor device number */
mutex_lock(&pdx->io_mutex); /* stop more I/O starting while... */ mutex_lock(&ced->io_mutex); /* stop more I/O starting while... */
ced_draw_down(pdx); /* ...wait for then kill any io */ ced_draw_down(ced); /* ...wait for then kill any io */
for (i = 0; i < MAX_TRANSAREAS; ++i) { for (i = 0; i < MAX_TRANSAREAS; ++i) {
int iErr = ced_clear_area(pdx, i); /* ...release any used memory */ int iErr = ced_clear_area(ced, i); /* ...release any used memory */
if (iErr == U14ERR_UNLOCKFAIL) if (iErr == U14ERR_UNLOCKFAIL)
dev_err(&pdx->interface->dev, "%s: Area %d was in used\n", dev_err(&ced->interface->dev, "%s: Area %d was in used\n",
__func__, i); __func__, i);
} }
pdx->interface = NULL; /* ...we kill off link to interface */ ced->interface = NULL; /* ...we kill off link to interface */
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
usb_kill_anchored_urbs(&pdx->submitted); usb_kill_anchored_urbs(&ced->submitted);
kref_put(&pdx->kref, ced_delete); /* decrement our usage count */ kref_put(&ced->kref, ced_delete); /* decrement our usage count */
dev_info(&interface->dev, "USB cedusb #%d now disconnected\n", minor); dev_info(&interface->dev, "USB cedusb #%d now disconnected\n", minor);
} }
...@@ -1515,57 +1515,57 @@ static void ced_disconnect(struct usb_interface *interface) ...@@ -1515,57 +1515,57 @@ static void ced_disconnect(struct usb_interface *interface)
/* are left. NBNB we will need to have a mechanism to stop circular xfers */ /* are left. NBNB we will need to have a mechanism to stop circular xfers */
/* from trying to fire off more urbs. We will wait up to 3 seconds for Urbs */ /* from trying to fire off more urbs. We will wait up to 3 seconds for Urbs */
/* to be done. */ /* to be done. */
void ced_draw_down(DEVICE_EXTENSION *pdx) void ced_draw_down(struct ced_data *ced)
{ {
int time; int time;
dev_dbg(&pdx->interface->dev, "%s: called\n", __func__); dev_dbg(&ced->interface->dev, "%s: called\n", __func__);
pdx->bInDrawDown = true; ced->bInDrawDown = true;
time = usb_wait_anchor_empty_timeout(&pdx->submitted, 3000); time = usb_wait_anchor_empty_timeout(&ced->submitted, 3000);
if (!time) { /* if we timed out we kill the urbs */ if (!time) { /* if we timed out we kill the urbs */
usb_kill_anchored_urbs(&pdx->submitted); usb_kill_anchored_urbs(&ced->submitted);
dev_err(&pdx->interface->dev, "%s: timed out\n", __func__); dev_err(&ced->interface->dev, "%s: timed out\n", __func__);
} }
pdx->bInDrawDown = false; ced->bInDrawDown = false;
} }
static int ced_suspend(struct usb_interface *intf, pm_message_t message) static int ced_suspend(struct usb_interface *intf, pm_message_t message)
{ {
DEVICE_EXTENSION *pdx = usb_get_intfdata(intf); struct ced_data *ced = usb_get_intfdata(intf);
if (!pdx) if (!ced)
return 0; return 0;
ced_draw_down(pdx); ced_draw_down(ced);
dev_dbg(&pdx->interface->dev, "%s: called\n", __func__); dev_dbg(&ced->interface->dev, "%s: called\n", __func__);
return 0; return 0;
} }
static int ced_resume(struct usb_interface *intf) static int ced_resume(struct usb_interface *intf)
{ {
DEVICE_EXTENSION *pdx = usb_get_intfdata(intf); struct ced_data *ced = usb_get_intfdata(intf);
if (!pdx) if (!ced)
return 0; return 0;
dev_dbg(&pdx->interface->dev, "%s: called\n", __func__); dev_dbg(&ced->interface->dev, "%s: called\n", __func__);
return 0; return 0;
} }
static int ced_pre_reset(struct usb_interface *intf) static int ced_pre_reset(struct usb_interface *intf)
{ {
DEVICE_EXTENSION *pdx = usb_get_intfdata(intf); struct ced_data *ced = usb_get_intfdata(intf);
dev_dbg(&pdx->interface->dev, "%s\n", __func__); dev_dbg(&ced->interface->dev, "%s\n", __func__);
mutex_lock(&pdx->io_mutex); mutex_lock(&ced->io_mutex);
ced_draw_down(pdx); ced_draw_down(ced);
return 0; return 0;
} }
static int ced_post_reset(struct usb_interface *intf) static int ced_post_reset(struct usb_interface *intf)
{ {
DEVICE_EXTENSION *pdx = usb_get_intfdata(intf); struct ced_data *ced = usb_get_intfdata(intf);
dev_dbg(&pdx->interface->dev, "%s\n", __func__); dev_dbg(&ced->interface->dev, "%s\n", __func__);
/* we are sure no URBs are active - no locking needed */ /* we are sure no URBs are active - no locking needed */
pdx->errors = -EPIPE; ced->errors = -EPIPE;
mutex_unlock(&pdx->io_mutex); mutex_unlock(&ced->io_mutex);
return 0; return 0;
} }
......
...@@ -134,7 +134,7 @@ struct dmadesc { ...@@ -134,7 +134,7 @@ struct dmadesc {
/* Structure to hold all of our device specific stuff. We are making this as similar as we */ /* Structure to hold all of our device specific stuff. We are making this as similar as we */
/* can to the Windows driver to help in our understanding of what is going on. */ /* can to the Windows driver to help in our understanding of what is going on. */
typedef struct _DEVICE_EXTENSION { struct ced_data {
char inputBuffer[INBUF_SZ]; /* The two buffers */ char inputBuffer[INBUF_SZ]; /* The two buffers */
char outputBuffer[OUTBUF_SZ]; /* accessed by the host functions */ char outputBuffer[OUTBUF_SZ]; /* accessed by the host functions */
volatile unsigned int dwNumInput; /* num of chars in input buffer */ volatile unsigned int dwNumInput; /* num of chars in input buffer */
...@@ -197,48 +197,49 @@ typedef struct _DEVICE_EXTENSION { ...@@ -197,48 +197,49 @@ typedef struct _DEVICE_EXTENSION {
int open_count; /* count the number of openers */ int open_count; /* count the number of openers */
spinlock_t err_lock; /* lock for errors */ spinlock_t err_lock; /* lock for errors */
struct kref kref; struct kref kref;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION; };
#define to_DEVICE_EXTENSION(d) container_of(d, DEVICE_EXTENSION, kref)
#define to_ced_data(d) container_of(d, struct ced_data, kref)
/* Definitions of routimes used between compilation object files */ /* Definitions of routimes used between compilation object files */
/* in usb1401.c */ /* in usb1401.c */
extern int ced_allowi(DEVICE_EXTENSION *pdx); extern int ced_allowi(struct ced_data * ced);
extern int ced_send_chars(DEVICE_EXTENSION *pdx); extern int ced_send_chars(struct ced_data *ced);
extern void ced_draw_down(DEVICE_EXTENSION *pdx); extern void ced_draw_down(struct ced_data *ced);
extern int ced_read_write_mem(DEVICE_EXTENSION *pdx, bool Read, unsigned short wIdent, extern int ced_read_write_mem(struct ced_data *ced, bool Read, unsigned short wIdent,
unsigned int dwOffs, unsigned int dwLen); unsigned int dwOffs, unsigned int dwLen);
/* in ced_ioc.c */ /* in ced_ioc.c */
extern int ced_clear_area(DEVICE_EXTENSION *pdx, int nArea); extern int ced_clear_area(struct ced_data *ced, int nArea);
extern int ced_send_string(DEVICE_EXTENSION *pdx, const char __user *pData, unsigned int n); extern int ced_send_string(struct ced_data *ced, const char __user *pData, unsigned int n);
extern int ced_send_char(DEVICE_EXTENSION *pdx, char c); extern int ced_send_char(struct ced_data *ced, char c);
extern int ced_get_state(DEVICE_EXTENSION *pdx, __u32 *state, __u32 *error); extern int ced_get_state(struct ced_data *ced, __u32 *state, __u32 *error);
extern int ced_read_write_cancel(DEVICE_EXTENSION *pdx); extern int ced_read_write_cancel(struct ced_data *ced);
extern int ced_reset(DEVICE_EXTENSION *pdx); extern int ced_reset(struct ced_data *ced);
extern int ced_get_char(DEVICE_EXTENSION *pdx); extern int ced_get_char(struct ced_data *ced);
extern int ced_get_string(DEVICE_EXTENSION *pdx, char __user *pUser, int n); extern int ced_get_string(struct ced_data *ced, char __user *pUser, int n);
extern int ced_set_transfer(DEVICE_EXTENSION *pdx, struct transfer_area_desc __user *pTD); extern int ced_set_transfer(struct ced_data *ced, struct transfer_area_desc __user *pTD);
extern int ced_unset_transfer(DEVICE_EXTENSION *pdx, int nArea); extern int ced_unset_transfer(struct ced_data *ced, int nArea);
extern int ced_set_event(DEVICE_EXTENSION *pdx, struct transfer_event __user *pTE); extern int ced_set_event(struct ced_data *ced, struct transfer_event __user *pTE);
extern int ced_stat_1401(DEVICE_EXTENSION *pdx); extern int ced_stat_1401(struct ced_data *ced);
extern int ced_line_count(DEVICE_EXTENSION *pdx); extern int ced_line_count(struct ced_data *ced);
extern int ced_get_out_buf_space(DEVICE_EXTENSION *pdx); extern int ced_get_out_buf_space(struct ced_data *ced);
extern int ced_get_transfer(DEVICE_EXTENSION *pdx, TGET_TX_BLOCK __user *pGTB); extern int ced_get_transfer(struct ced_data *ced, TGET_TX_BLOCK __user *pGTB);
extern int ced_kill_io(DEVICE_EXTENSION *pdx); extern int ced_kill_io(struct ced_data *ced);
extern int ced_state_of_1401(DEVICE_EXTENSION *pdx); extern int ced_state_of_1401(struct ced_data *ced);
extern int ced_start_self_test(DEVICE_EXTENSION *pdx); extern int ced_start_self_test(struct ced_data *ced);
extern int ced_check_self_test(DEVICE_EXTENSION *pdx, TGET_SELFTEST __user *pGST); extern int ced_check_self_test(struct ced_data *ced, TGET_SELFTEST __user *pGST);
extern int ced_type_of_1401(DEVICE_EXTENSION *pdx); extern int ced_type_of_1401(struct ced_data *ced);
extern int ced_transfer_flags(DEVICE_EXTENSION *pdx); extern int ced_transfer_flags(struct ced_data *ced);
extern int ced_dbg_peek(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB); extern int ced_dbg_peek(struct ced_data *ced, TDBGBLOCK __user *pDB);
extern int ced_dbg_poke(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB); extern int ced_dbg_poke(struct ced_data *ced, TDBGBLOCK __user *pDB);
extern int ced_dbg_ramp_data(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB); extern int ced_dbg_ramp_data(struct ced_data *ced, TDBGBLOCK __user *pDB);
extern int ced_dbg_ramp_addr(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB); extern int ced_dbg_ramp_addr(struct ced_data *ced, TDBGBLOCK __user *pDB);
extern int ced_dbg_get_data(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB); extern int ced_dbg_get_data(struct ced_data *ced, TDBGBLOCK __user *pDB);
extern int ced_dbg_stop_loop(DEVICE_EXTENSION *pdx); extern int ced_dbg_stop_loop(struct ced_data *ced);
extern int ced_set_circular(DEVICE_EXTENSION *pdx, struct transfer_area_desc __user *pTD); extern int ced_set_circular(struct ced_data *ced, struct transfer_area_desc __user *pTD);
extern int ced_get_circ_block(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB); extern int ced_get_circ_block(struct ced_data *ced, TCIRCBLOCK __user *pCB);
extern int ced_free_circ_block(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB); extern int ced_free_circ_block(struct ced_data *ced, TCIRCBLOCK __user *pCB);
extern int ced_wait_event(DEVICE_EXTENSION *pdx, int nArea, int msTimeOut); extern int ced_wait_event(struct ced_data *ced, int nArea, int msTimeOut);
extern int ced_test_event(DEVICE_EXTENSION *pdx, int nArea); extern int ced_test_event(struct ced_data *ced, int nArea);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment