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 @@
**
** 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",
__func__, pdx->sCurrentState);
if (pdx->sCurrentState == U14ERR_TIME) /* Do nothing if hardware in trouble */
dev_dbg(&ced->interface->dev, "%s: currentState=%d\n",
__func__, ced->sCurrentState);
if (ced->sCurrentState == U14ERR_TIME) /* Do nothing if hardware in trouble */
return;
/* Kill off any pending I/O */
/* CharSend_Cancel(pdx); */
spin_lock_irq(&pdx->charOutLock);
pdx->dwNumOutput = 0;
pdx->dwOutBuffGet = 0;
pdx->dwOutBuffPut = 0;
spin_unlock_irq(&pdx->charOutLock);
/* CharSend_Cancel(ced); */
spin_lock_irq(&ced->charOutLock);
ced->dwNumOutput = 0;
ced->dwOutBuffGet = 0;
ced->dwOutBuffPut = 0;
spin_unlock_irq(&ced->charOutLock);
}
/****************************************************************************
......@@ -57,19 +57,19 @@ static void ced_flush_out_buff(DEVICE_EXTENSION *pdx)
**
** 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",
__func__, pdx->sCurrentState);
if (pdx->sCurrentState == U14ERR_TIME) /* Do nothing if hardware in trouble */
dev_dbg(&ced->interface->dev, "%s: currentState=%d\n",
__func__, ced->sCurrentState);
if (ced->sCurrentState == U14ERR_TIME) /* Do nothing if hardware in trouble */
return;
/* Kill off any pending I/O */
/* CharRead_Cancel(pDevObject); */
spin_lock_irq(&pdx->charInLock);
pdx->dwNumInput = 0;
pdx->dwInBuffGet = 0;
pdx->dwInBuffPut = 0;
spin_unlock_irq(&pdx->charInLock);
spin_lock_irq(&ced->charInLock);
ced->dwNumInput = 0;
ced->dwInBuffGet = 0;
ced->dwInBuffPut = 0;
spin_unlock_irq(&ced->charInLock);
}
/****************************************************************************
......@@ -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.
** 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)
{
int iReturn;
spin_lock_irq(&pdx->charOutLock); /* get the output spin lock */
if ((OUTBUF_SZ - pdx->dwNumOutput) >= uCount) {
spin_lock_irq(&ced->charOutLock); /* get the output spin lock */
if ((OUTBUF_SZ - ced->dwNumOutput) >= uCount) {
unsigned int u;
for (u = 0; u < uCount; u++) {
pdx->outputBuffer[pdx->dwOutBuffPut++] = pCh[u];
if (pdx->dwOutBuffPut >= OUTBUF_SZ)
pdx->dwOutBuffPut = 0;
ced->outputBuffer[ced->dwOutBuffPut++] = pCh[u];
if (ced->dwOutBuffPut >= OUTBUF_SZ)
ced->dwOutBuffPut = 0;
}
pdx->dwNumOutput += uCount;
spin_unlock_irq(&pdx->charOutLock);
iReturn = ced_send_chars(pdx); /* ...give a chance to transmit data */
ced->dwNumOutput += uCount;
spin_unlock_irq(&ced->charOutLock);
iReturn = ced_send_chars(ced); /* ...give a chance to transmit data */
} else {
iReturn = U14ERR_NOOUT; /* no room at the out (ha-ha) */
spin_unlock_irq(&pdx->charOutLock);
spin_unlock_irq(&ced->charOutLock);
}
return iReturn;
}
......@@ -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.
** 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)
{
int iReturn = U14ERR_NOERROR; /* assume all will be well */
......@@ -116,15 +116,15 @@ int ced_send_string(DEVICE_EXTENSION *pdx, const char __user *pData,
return -EFAULT;
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! */
dev_dbg(&pdx->interface->dev, "%s: n=%d>%s<\n",
dev_dbg(&ced->interface->dev, "%s: n=%d>%s<\n",
__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 */
mutex_unlock(&pdx->io_mutex);
ced_allowi(ced); /* make sure we have input int */
mutex_unlock(&ced->io_mutex);
return iReturn;
}
......@@ -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.
****************************************************************************/
int ced_send_char(DEVICE_EXTENSION *pdx, char c)
int ced_send_char(struct ced_data *ced, char c)
{
int iReturn;
mutex_lock(&pdx->io_mutex); /* Protect disconnect from new i/o */
iReturn = ced_put_chars(pdx, &c, 1);
dev_dbg(&pdx->interface->dev, "ced_send_char >%c< (0x%02x)\n", c, c);
ced_allowi(pdx); /* Make sure char reads are running */
mutex_unlock(&pdx->io_mutex);
mutex_lock(&ced->io_mutex); /* Protect disconnect from new i/o */
iReturn = ced_put_chars(ced, &c, 1);
dev_dbg(&ced->interface->dev, "ced_send_char >%c< (0x%02x)\n", c, c);
ced_allowi(ced); /* Make sure char reads are running */
mutex_unlock(&ced->io_mutex);
return iReturn;
}
......@@ -171,46 +171,46 @@ int ced_send_char(DEVICE_EXTENSION *pdx, char c)
**
** 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;
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 */
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,
pdx->statBuf, sizeof(pdx->statBuf), HZ);
if (nGot != sizeof(pdx->statBuf)) {
dev_err(&pdx->interface->dev,
ced->statBuf, sizeof(ced->statBuf), HZ);
if (nGot != sizeof(ced->statBuf)) {
dev_err(&ced->interface->dev,
"%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 */
*error = 0;
} else {
int nDevice;
dev_dbg(&pdx->interface->dev,
dev_dbg(&ced->interface->dev,
"%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 */
*error = pdx->statBuf[1];
*state = ced->statBuf[0]; /* Return the state values to the calling code */
*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 */
case 0:
pdx->sCurrentState = U14ERR_U1401;
ced->sCurrentState = U14ERR_U1401;
break;
default: /* allow lots of device codes for future 1401s */
if ((nDevice >= 1) && (nDevice <= 23))
pdx->sCurrentState = (short)(nDevice + 6);
ced->sCurrentState = (short)(nDevice + 6);
else
pdx->sCurrentState = U14ERR_ILL;
ced->sCurrentState = U14ERR_ILL;
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)
**
** 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",
__func__, pdx->bStagedUrbPending);
dev_dbg(&ced->interface->dev, "%s: entry %d\n",
__func__, ced->bStagedUrbPending);
#ifdef NOT_WRITTEN_YET
int ntStatus = STATUS_SUCCESS;
bool bResult = false;
unsigned int i;
/* We can fill this in when we know how we will implement the staged transfer stuff */
spin_lock_irq(&pdx->stagedLock);
spin_lock_irq(&ced->stagedLock);
if (pdx->bStagedUrbPending) { /* anything to be cancelled? May need more... */
dev_info(&pdx->interface - dev,
if (ced->bStagedUrbPending) { /* anything to be cancelled? May need more... */
dev_info(&ced->interface - dev,
"ced_read_write_cancel about to cancel Urb\n");
/* Clear the staging done flag */
/* KeClearEvent(&pdx->StagingDoneEvent); */
USB_ASSERT(pdx->pStagedIrp != NULL);
/* KeClearEvent(&ced->StagingDoneEvent); */
USB_ASSERT(ced->pStagedIrp != NULL);
/* Release the spinlock first otherwise the completion routine may hang */
/* on the spinlock while this function hands waiting for the event. */
spin_unlock_irq(&pdx->stagedLock);
bResult = IoCancelIrp(pdx->pStagedIrp); /* Actually do the cancel */
spin_unlock_irq(&ced->stagedLock);
bResult = IoCancelIrp(ced->pStagedIrp); /* Actually do the cancel */
if (bResult) {
LARGE_INTEGER timeout;
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__);
ntStatus =
KeWaitForSingleObject(&pdx->StagingDoneEvent,
KeWaitForSingleObject(&ced->StagingDoneEvent,
Executive, KernelMode, FALSE,
&timeout);
} else {
dev_info(&pdx->interface - dev,
dev_info(&ced->interface - dev,
"%s: cancellation failed\n", __func__);
ntStatus = U14ERR_FAIL;
}
......@@ -258,9 +258,9 @@ int ced_read_write_cancel(DEVICE_EXTENSION *pdx)
("ced_read_write_cancel ntStatus = 0x%x decimal %d\n",
ntStatus, ntStatus));
} 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;
#else
return U14ERR_NOERROR;
......@@ -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
** 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;
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 */
iReturn = (state == (unsigned int)-1) || /* TX problem or... */
((state & 0xff) == 0x80); /* ...self test */
......@@ -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
****************************************************************************/
static bool ced_is_1401(DEVICE_EXTENSION *pdx)
static bool ced_is_1401(struct ced_data *ced)
{
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_flush_in_buff(pdx); /* Clear out input buffer & pipe */
ced_flush_out_buff(pdx); /* Clear output buffer & pipe */
ced_draw_down(ced); /* wait for, then kill outstanding Urbs */
ced_flush_in_buff(ced); /* Clear out input 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 */
/* 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 */
/* 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 */
iReturn = usb_reset_device(pdx->udev); /* try to do the reset */
usb_unlock_device(pdx->udev); /* undo the lock */
iReturn = usb_reset_device(ced->udev); /* try to do the reset */
usb_unlock_device(ced->udev); /* undo the lock */
}
mutex_lock(&pdx->io_mutex); /* hold stuff off while we wait */
pdx->dwDMAFlag = MODE_CHAR; /* Clear DMA mode flag regardless! */
mutex_lock(&ced->io_mutex); /* hold stuff off while we wait */
ced->dwDMAFlag = MODE_CHAR; /* Clear DMA mode flag regardless! */
if (iReturn == 0) { /* if all is OK still */
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? */
unsigned long ulTimeOut = jiffies + 30 * HZ; /* when to give up */
while ((iReturn > 0) && time_before(jiffies, ulTimeOut)) {
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)
iReturn = state == 0; /* then success is that the state is 0 */
} else
iReturn = 0; /* we failed */
pdx->bForceReset = false; /* Clear forced reset flag now */
ced->bForceReset = false; /* Clear forced reset flag now */
return iReturn > 0;
}
......@@ -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
*/
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 bShortTest;
bShortTest = ((pdx->dwDMAFlag == MODE_CHAR) && /* no DMA running */
(!pdx->bForceReset) && /* Not had a real reset forced */
(pdx->sCurrentState >= U14ERR_STD)); /* No 1401 errors stored */
bShortTest = ((ced->dwDMAFlag == MODE_CHAR) && /* no DMA running */
(!ced->bForceReset) && /* Not had a real reset forced */
(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",
__func__, pdx->dwDMAFlag, pdx->sCurrentState, pdx->bForceReset,
__func__, ced->dwDMAFlag, ced->sCurrentState, ced->bForceReset,
bTestBuff, bShortTest);
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 */
dev_dbg(&pdx->interface->dev,
dev_dbg(&ced->interface->dev,
"%s: will reset as buffers not empty\n", __func__);
}
if (bShortTest || !bCanReset) { /* Still OK to try the short test? */
/* Always test if no reset - we want state update */
unsigned int state, error;
dev_dbg(&pdx->interface->dev, "%s: ced_get_state\n", __func__);
if (ced_get_state(pdx, &state, &error) == U14ERR_NOERROR) { /* Check on the 1401 state */
dev_dbg(&ced->interface->dev, "%s: ced_get_state\n", __func__);
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 */
bRet = true; /* If that was zero, all is OK, no reset needed */
}
}
if (!bRet && bCanReset) { /* If all not OK, then */
dev_info(&pdx->interface->dev, "%s: ced_is_1401 %d %d %d %d\n",
__func__, bShortTest, pdx->sCurrentState, bTestBuff,
pdx->bForceReset);
bRet = ced_is_1401(pdx); /* do full test */
dev_info(&ced->interface->dev, "%s: ced_is_1401 %d %d %d %d\n",
__func__, bShortTest, ced->sCurrentState, bTestBuff,
ced->bForceReset);
bRet = ced_is_1401(ced); /* do full test */
}
return bRet;
......@@ -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
*****************************************************************************/
int ced_reset(DEVICE_EXTENSION *pdx)
int ced_reset(struct ced_data *ced)
{
mutex_lock(&pdx->io_mutex); /* Protect disconnect from new i/o */
dev_dbg(&pdx->interface->dev, "%s: About to call ced_quick_check\n",
mutex_lock(&ced->io_mutex); /* Protect disconnect from new i/o */
dev_dbg(&ced->interface->dev, "%s: About to call ced_quick_check\n",
__func__);
ced_quick_check(pdx, true, true); /* Check 1401, reset if not OK */
mutex_unlock(&pdx->io_mutex);
ced_quick_check(ced, true, true); /* Check 1401, reset if not OK */
mutex_unlock(&ced->io_mutex);
return U14ERR_NOERROR;
}
......@@ -419,29 +419,29 @@ int ced_reset(DEVICE_EXTENSION *pdx)
**
** 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 */
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_send_chars(pdx); /* and send any buffered chars */
ced_allowi(ced); /* Make sure char reads are running */
ced_send_chars(ced); /* and send any buffered chars */
spin_lock_irq(&pdx->charInLock);
if (pdx->dwNumInput > 0) { /* worth looking */
iReturn = pdx->inputBuffer[pdx->dwInBuffGet++];
if (pdx->dwInBuffGet >= INBUF_SZ)
pdx->dwInBuffGet = 0;
pdx->dwNumInput--;
spin_lock_irq(&ced->charInLock);
if (ced->dwNumInput > 0) { /* worth looking */
iReturn = ced->inputBuffer[ced->dwInBuffGet++];
if (ced->dwInBuffGet >= INBUF_SZ)
ced->dwInBuffGet = 0;
ced->dwNumInput--;
} else
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;
}
......@@ -456,19 +456,19 @@ int ced_get_char(DEVICE_EXTENSION *pdx)
** returns the count of characters (including the terminator, or 0 if none
** 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 iReturn = U14ERR_NOIN;
if (n <= 0)
return -ENOMEM;
mutex_lock(&pdx->io_mutex); /* Protect disconnect from new i/o */
ced_allowi(pdx); /* Make sure char reads are running */
ced_send_chars(pdx); /* and send any buffered chars */
mutex_lock(&ced->io_mutex); /* Protect disconnect from new i/o */
ced_allowi(ced); /* Make sure char reads are running */
ced_send_chars(ced); /* and send any buffered chars */
spin_lock_irq(&pdx->charInLock);
nAvailable = pdx->dwNumInput; /* characters available now */
spin_lock_irq(&ced->charInLock);
nAvailable = ced->dwNumInput; /* characters available now */
if (nAvailable > n) /* read max of space in pUser... */
nAvailable = n; /* ...or input characters */
......@@ -478,12 +478,12 @@ int ced_get_string(DEVICE_EXTENSION *pdx, char __user *pUser, int n)
int nCopyToUser; /* number to copy to user */
char cData;
do {
cData = pdx->inputBuffer[pdx->dwInBuffGet++];
cData = ced->inputBuffer[ced->dwInBuffGet++];
if (cData == CR_CHAR) /* replace CR with zero */
cData = (char)0;
if (pdx->dwInBuffGet >= INBUF_SZ)
pdx->dwInBuffGet = 0; /* wrap buffer pointer */
if (ced->dwInBuffGet >= INBUF_SZ)
ced->dwInBuffGet = 0; /* wrap buffer pointer */
buffer[nGot++] = cData; /* save the output */
} while ((nGot < nAvailable) && cData);
......@@ -495,20 +495,20 @@ int ced_get_string(DEVICE_EXTENSION *pdx, char __user *pUser, int n)
++nCopyToUser; /* ...copy the 0 as well. */
}
pdx->dwNumInput -= nGot;
spin_unlock_irq(&pdx->charInLock);
ced->dwNumInput -= nGot;
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);
if (copy_to_user(pUser, buffer, nCopyToUser))
iReturn = -EFAULT;
else
iReturn = nGot; /* report characters read */
} else
spin_unlock_irq(&pdx->charInLock);
spin_unlock_irq(&ced->charInLock);
ced_allowi(pdx); /* Make sure char reads are running */
mutex_unlock(&pdx->io_mutex); /* Protect disconnect from new i/o */
ced_allowi(ced); /* Make sure char reads are running */
mutex_unlock(&ced->io_mutex); /* Protect disconnect from new i/o */
return iReturn;
}
......@@ -516,14 +516,14 @@ int ced_get_string(DEVICE_EXTENSION *pdx, char __user *pUser, int n)
/*******************************************************************************
** 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;
mutex_lock(&pdx->io_mutex); /* Protect disconnect from new i/o */
ced_allowi(pdx); /* make sure we allow pending chars */
ced_send_chars(pdx); /* in both directions */
iReturn = pdx->dwNumInput; /* no lock as single read */
mutex_unlock(&pdx->io_mutex); /* Protect disconnect from new i/o */
mutex_lock(&ced->io_mutex); /* Protect disconnect from new i/o */
ced_allowi(ced); /* make sure we allow pending chars */
ced_send_chars(ced); /* in both directions */
iReturn = ced->dwNumInput; /* no lock as single read */
mutex_unlock(&ced->io_mutex); /* Protect disconnect from new i/o */
return iReturn;
}
......@@ -534,20 +534,20 @@ int ced_stat_1401(DEVICE_EXTENSION *pdx)
** any fancy interlocks as we only read the interrupt routine data, and the
** 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 */
mutex_lock(&pdx->io_mutex); /* Protect disconnect from new i/o */
ced_allowi(pdx); /* Make sure char reads are running */
ced_send_chars(pdx); /* and send any buffered chars */
spin_lock_irq(&pdx->charInLock); /* Get protection */
mutex_lock(&ced->io_mutex); /* Protect disconnect from new i/o */
ced_allowi(ced); /* Make sure char reads are running */
ced_send_chars(ced); /* and send any buffered chars */
spin_lock_irq(&ced->charInLock); /* Get protection */
if (pdx->dwNumInput > 0) { /* worth looking? */
unsigned int dwIndex = pdx->dwInBuffGet; /* start at first available */
unsigned int dwEnd = pdx->dwInBuffPut; /* Position for search end */
if (ced->dwNumInput > 0) { /* worth looking? */
unsigned int dwIndex = ced->dwInBuffGet; /* start at first available */
unsigned int dwEnd = ced->dwInBuffPut; /* Position for search end */
do {
if (pdx->inputBuffer[dwIndex++] == CR_CHAR)
if (ced->inputBuffer[dwIndex++] == CR_CHAR)
++iReturn; /* inc count if CR */
if (dwIndex >= INBUF_SZ) /* see if we fall off buff */
......@@ -555,9 +555,9 @@ int ced_line_count(DEVICE_EXTENSION *pdx)
} while (dwIndex != dwEnd); /* go to last available */
}
spin_unlock_irq(&pdx->charInLock);
dev_dbg(&pdx->interface->dev, "%s: returned %d\n", __func__, iReturn);
mutex_unlock(&pdx->io_mutex); /* Protect disconnect from new i/o */
spin_unlock_irq(&ced->charInLock);
dev_dbg(&ced->interface->dev, "%s: returned %d\n", __func__, iReturn);
mutex_unlock(&ced->io_mutex); /* Protect disconnect from new i/o */
return iReturn;
}
......@@ -566,14 +566,14 @@ int ced_line_count(DEVICE_EXTENSION *pdx)
**
** 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;
mutex_lock(&pdx->io_mutex); /* Protect disconnect from new i/o */
ced_send_chars(pdx); /* send any buffered chars */
iReturn = (int)(OUTBUF_SZ - pdx->dwNumOutput); /* no lock needed for single read */
dev_dbg(&pdx->interface->dev, "%s: %d\n", __func__, iReturn);
mutex_unlock(&pdx->io_mutex); /* Protect disconnect from new i/o */
mutex_lock(&ced->io_mutex); /* Protect disconnect from new i/o */
ced_send_chars(ced); /* send any buffered chars */
iReturn = (int)(OUTBUF_SZ - ced->dwNumOutput); /* no lock needed for single read */
dev_dbg(&ced->interface->dev, "%s: %d\n", __func__, iReturn);
mutex_unlock(&ced->io_mutex); /* Protect disconnect from new i/o */
return iReturn;
}
......@@ -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
** 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;
if ((nArea < 0) || (nArea >= MAX_TRANSAREAS)) {
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);
} else {
/* to save typing */
struct transarea *pTA = &pdx->rTransDef[nArea];
struct transarea *pTA = &ced->rTransDef[nArea];
if (!pTA->bUsed) /* if not used... */
iReturn = U14ERR_NOTSET; /* ...nothing to be done */
else {
......@@ -604,13 +604,13 @@ int ced_clear_area(DEVICE_EXTENSION *pdx, int nArea)
int nPages = 0; /* and number of pages */
int np;
dev_dbg(&pdx->interface->dev, "%s: area %d\n",
dev_dbg(&ced->interface->dev, "%s: area %d\n",
__func__, nArea);
spin_lock_irq(&pdx->stagedLock);
if ((pdx->StagedId == nArea)
&& (pdx->dwDMAFlag > MODE_CHAR)) {
spin_lock_irq(&ced->stagedLock);
if ((ced->StagedId == nArea)
&& (ced->dwDMAFlag > MODE_CHAR)) {
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",
__func__, nArea);
} else {
......@@ -619,9 +619,9 @@ int ced_clear_area(DEVICE_EXTENSION *pdx, int nArea)
if (pTA->dwEventSz) /* if events flagging in use */
wake_up_interruptible(&pTA->wqEvent); /* release anything that was waiting */
if (pdx->bXFerWaiting
&& (pdx->rDMAInfo.wIdent == nArea))
pdx->bXFerWaiting = false; /* Cannot have pending xfer if area cleared */
if (ced->bXFerWaiting
&& (ced->rDMAInfo.wIdent == nArea))
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 */
/* 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)
sizeof(struct transarea) -
sizeof(wait_queue_head_t));
}
spin_unlock_irq(&pdx->stagedLock);
spin_unlock_irq(&ced->stagedLock);
if (pPages) { /* if we decided to release the memory */
/* Now we must undo the pinning down of the pages. We will assume the worst and mark */
/* all the pages as dirty. Don't be tempted to move this up above as you must not be */
/* holding a spin lock to do this stuff as it is not atomic. */
dev_dbg(&pdx->interface->dev, "%s: nPages=%d\n",
dev_dbg(&ced->interface->dev, "%s: nPages=%d\n",
__func__, nPages);
for (np = 0; np < nPages; ++np) {
......@@ -646,7 +646,7 @@ int ced_clear_area(DEVICE_EXTENSION *pdx, int nArea)
}
kfree(pPages);
dev_dbg(&pdx->interface->dev,
dev_dbg(&ced->interface->dev,
"%s: kfree(pPages) done\n", __func__);
}
}
......@@ -661,7 +661,7 @@ int ced_clear_area(DEVICE_EXTENSION *pdx, int nArea)
** Sets up a transfer area - the functional part. Called by both
** 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)
{
/* 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,
unsigned int ulOffset = ((unsigned long)puBuf) & (PAGE_SIZE - 1);
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 */
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... */
(iReturn != U14ERR_NOERROR)) /* ...not all OK, then... */
return iReturn; /* ...we cannot use this area */
......@@ -689,18 +689,18 @@ static int ced_set_area(DEVICE_EXTENSION *pdx, int nArea, char __user *puBuf,
iReturn = U14ERR_NOMEMORY;
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);
/* To pin down user pages we must first acquire the mapping semaphore. */
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 you are tempted to use page_address (form LDD3), forget it. You MUST use */
/* kmap() or kmap_atomic() to get a virtual address. page_address will give you */
/* (null) or at least it does in this context with an x86 machine. */
spin_lock_irq(&pdx->stagedLock);
spin_lock_irq(&ced->stagedLock);
pTA->lpvBuff = puBuf; /* keep start of region (user address) */
pTA->dwBaseOffset = ulOffset; /* save offset in first page to start of xfer */
pTA->dwLength = dwLength; /* Size if the region in bytes */
......@@ -716,7 +716,7 @@ static int ced_set_area(DEVICE_EXTENSION *pdx, int nArea, char __user *puBuf,
pTA->aBlocks[1].dwSize = 0;
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 */
} else {
iReturn = U14ERR_LOCKFAIL;
......@@ -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
** 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;
struct transfer_area_desc td;
......@@ -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)))
return -EFAULT;
mutex_lock(&pdx->io_mutex);
dev_dbg(&pdx->interface->dev, "%s: area:%d, size:%08x\n",
mutex_lock(&ced->io_mutex);
dev_dbg(&ced->interface->dev, "%s: area:%d, size:%08x\n",
__func__, td.wAreaNum, td.dwLength);
/* The strange cast is done so that we don't get warnings in 32-bit linux about the size of the */
/* pointer. The pointer is always passed as a 64-bit object so that we don't have problems using */
/* a 32-bit program on a 64-bit system. unsigned long is 64-bits on a 64-bit system. */
iReturn =
ced_set_area(pdx, td.wAreaNum,
ced_set_area(ced, td.wAreaNum,
(char __user *)((unsigned long)td.lpvBuff), td.dwLength,
false, false);
mutex_unlock(&pdx->io_mutex);
mutex_unlock(&ced->io_mutex);
return iReturn;
}
......@@ -763,12 +763,12 @@ int ced_set_transfer(DEVICE_EXTENSION *pdx, struct transfer_area_desc __user *pT
** UnSetTransfer
** 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;
mutex_lock(&pdx->io_mutex);
iReturn = ced_clear_area(pdx, nArea);
mutex_unlock(&pdx->io_mutex);
mutex_lock(&ced->io_mutex);
iReturn = ced_clear_area(ced, nArea);
mutex_unlock(&ced->io_mutex);
return iReturn;
}
......@@ -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
** 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;
struct transfer_event te;
......@@ -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 */
return U14ERR_BADAREA;
else {
struct transarea *pTA = &pdx->rTransDef[te.wAreaNum];
mutex_lock(&pdx->io_mutex); /* make sure we have no competitor */
spin_lock_irq(&pdx->stagedLock);
struct transarea *pTA = &ced->rTransDef[te.wAreaNum];
mutex_lock(&ced->io_mutex); /* make sure we have no competitor */
spin_lock_irq(&ced->stagedLock);
if (pTA->bUsed) { /* area must be in use */
pTA->dwEventSt = te.dwStart; /* set area regions */
pTA->dwEventSz = te.dwLength; /* set size (0 cancels it) */
......@@ -802,8 +802,8 @@ int ced_set_event(DEVICE_EXTENSION *pdx, struct transfer_event __user *pTE)
pTA->iWakeUp = 0; /* zero the wake up count */
} else
iReturn = U14ERR_NOTSET;
spin_unlock_irq(&pdx->stagedLock);
mutex_unlock(&pdx->io_mutex);
spin_unlock_irq(&ced->stagedLock);
mutex_unlock(&ced->io_mutex);
}
return 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)
** of times that a block met the event condition since we last cleared it or
** 0 if timed out, or -ve error (bad area or not set, or signal).
****************************************************************************/
int ced_wait_event(DEVICE_EXTENSION *pdx, int nArea, int msTimeOut)
int ced_wait_event(struct ced_data *ced, int nArea, int msTimeOut)
{
int iReturn;
if ((unsigned)nArea >= MAX_TRANSAREAS)
return U14ERR_BADAREA;
else {
int iWait;
struct transarea *pTA = &pdx->rTransDef[nArea];
struct transarea *pTA = &ced->rTransDef[nArea];
msTimeOut = (msTimeOut * HZ + 999) / 1000; /* convert timeout to jiffies */
/* We cannot wait holding the mutex, but we check the flags while holding */
/* it. This may well be pointless as another thread could get in between */
/* releasing it and the wait call. However, this would have to clear the */
/* iWakeUp flag. However, the !pTA-bUsed may help us in this case. */
mutex_lock(&pdx->io_mutex); /* make sure we have no competitor */
mutex_lock(&ced->io_mutex); /* make sure we have no competitor */
if (!pTA->bUsed || !pTA->dwEventSz) /* check something to wait for... */
return U14ERR_NOTSET; /* ...else we do nothing */
mutex_unlock(&pdx->io_mutex);
mutex_unlock(&ced->io_mutex);
if (msTimeOut)
iWait =
......@@ -849,9 +849,9 @@ int ced_wait_event(DEVICE_EXTENSION *pdx, int nArea, int msTimeOut)
else
iReturn = pTA->iWakeUp; /* else the wakeup count */
spin_lock_irq(&pdx->stagedLock);
spin_lock_irq(&ced->stagedLock);
pTA->iWakeUp = 0; /* clear the flag */
spin_unlock_irq(&pdx->stagedLock);
spin_unlock_irq(&ced->stagedLock);
}
return iReturn;
}
......@@ -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
** negative error.
****************************************************************************/
int ced_test_event(DEVICE_EXTENSION *pdx, int nArea)
int ced_test_event(struct ced_data *ced, int nArea)
{
int iReturn;
if ((unsigned)nArea >= MAX_TRANSAREAS)
iReturn = U14ERR_BADAREA;
else {
struct transarea *pTA = &pdx->rTransDef[nArea];
mutex_lock(&pdx->io_mutex); /* make sure we have no competitor */
spin_lock_irq(&pdx->stagedLock);
struct transarea *pTA = &ced->rTransDef[nArea];
mutex_lock(&ced->io_mutex); /* make sure we have no competitor */
spin_lock_irq(&ced->stagedLock);
iReturn = pTA->iWakeUp; /* get wakeup count since last call */
pTA->iWakeUp = 0; /* clear the count */
spin_unlock_irq(&pdx->stagedLock);
mutex_unlock(&pdx->io_mutex);
spin_unlock_irq(&ced->stagedLock);
mutex_unlock(&ced->io_mutex);
}
return iReturn;
}
......@@ -883,13 +883,13 @@ int ced_test_event(DEVICE_EXTENSION *pdx, int nArea)
** ced_get_transferInfo
** 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;
unsigned int dwIdent;
mutex_lock(&pdx->io_mutex);
dwIdent = pdx->StagedId; /* area ident for last xfer */
mutex_lock(&ced->io_mutex);
dwIdent = ced->StagedId; /* area ident for last xfer */
if (dwIdent >= MAX_TRANSAREAS)
iReturn = U14ERR_BADAREA;
else {
......@@ -898,22 +898,22 @@ int ced_get_transfer(DEVICE_EXTENSION *pdx, TGET_TX_BLOCK __user *pTX)
tx = kzalloc(sizeof(*tx), GFP_KERNEL);
if (!tx) {
mutex_unlock(&pdx->io_mutex);
mutex_unlock(&ced->io_mutex);
return -ENOMEM;
}
tx->size = pdx->rTransDef[dwIdent].dwLength;
tx->linear = (long long)((long)pdx->rTransDef[dwIdent].lpvBuff);
tx->size = ced->rTransDef[dwIdent].dwLength;
tx->linear = (long long)((long)ced->rTransDef[dwIdent].lpvBuff);
tx->avail = GET_TX_MAXENTRIES; /* how many blocks we could return */
tx->used = 1; /* number we actually return */
tx->entries[0].physical =
(long long)(tx->linear + pdx->StagedOffset);
(long long)(tx->linear + ced->StagedOffset);
tx->entries[0].size = tx->size;
if (copy_to_user(pTX, tx, sizeof(*tx)))
iReturn = -EFAULT;
kfree(tx);
}
mutex_unlock(&pdx->io_mutex);
mutex_unlock(&ced->io_mutex);
return iReturn;
}
......@@ -922,13 +922,13 @@ int ced_get_transfer(DEVICE_EXTENSION *pdx, TGET_TX_BLOCK __user *pTX)
**
** 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__);
mutex_lock(&pdx->io_mutex);
ced_flush_out_buff(pdx);
ced_flush_in_buff(pdx);
mutex_unlock(&pdx->io_mutex);
dev_dbg(&ced->interface->dev, "%s\n", __func__);
mutex_lock(&ced->io_mutex);
ced_flush_out_buff(ced);
ced_flush_in_buff(ced);
mutex_unlock(&ced->io_mutex);
return U14ERR_NOERROR;
}
......@@ -937,16 +937,16 @@ int ced_kill_io(DEVICE_EXTENSION *pdx)
**
** 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;
mutex_lock(&pdx->io_mutex);
mutex_lock(&ced->io_mutex);
ced_quick_check(pdx, false, false); /* get state up to date, no reset */
iReturn = pdx->sCurrentState;
ced_quick_check(ced, false, false); /* get state up to date, no reset */
iReturn = ced->sCurrentState;
mutex_unlock(&pdx->io_mutex);
dev_dbg(&pdx->interface->dev, "%s: %d\n", __func__, iReturn);
mutex_unlock(&ced->io_mutex);
dev_dbg(&ced->interface->dev, "%s: %d\n", __func__, iReturn);
return iReturn;
}
......@@ -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
** 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;
mutex_lock(&pdx->io_mutex);
dev_dbg(&pdx->interface->dev, "%s\n", __func__);
mutex_lock(&ced->io_mutex);
dev_dbg(&ced->interface->dev, "%s\n", __func__);
ced_draw_down(pdx); /* wait for, then kill outstanding Urbs */
ced_flush_in_buff(pdx); /* Clear out input buffer & pipe */
ced_flush_out_buff(pdx); /* Clear output buffer & pipe */
ced_draw_down(ced); /* wait for, then kill outstanding Urbs */
ced_flush_in_buff(ced); /* Clear out input buffer & pipe */
ced_flush_out_buff(ced); /* Clear output buffer & pipe */
/* so things stay tidy */
/* 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),
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)
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;
}
......@@ -986,23 +986,23 @@ int ced_start_self_test(DEVICE_EXTENSION *pdx)
**
** 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;
int iReturn;
TGET_SELFTEST gst; /* local work space */
memset(&gst, 0, sizeof(gst)); /* clear out the space (sets code 0) */
mutex_lock(&pdx->io_mutex);
mutex_lock(&ced->io_mutex);
dev_dbg(&pdx->interface->dev, "%s\n", __func__);
iReturn = ced_get_state(pdx, &state, &error);
dev_dbg(&ced->interface->dev, "%s\n", __func__);
iReturn = ced_get_state(ced, &state, &error);
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 */
/* so we assume still testing */
dev_err(&pdx->interface->dev,
dev_err(&ced->interface->dev,
"%s: ced_get_state=%d, assuming still testing\n",
__func__, iReturn);
state = 0x80; /* Force still-testing, no error */
......@@ -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 */
dev_err(&pdx->interface->dev,
dev_err(&ced->interface->dev,
"%s: ced_get_state failed, assuming still testing\n",
__func__);
state = 0x80; /* Force still-testing, no error */
......@@ -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.x = error & 0x0000FFFF; /* Error data X */
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);
} else { /* No error, check for timeout */
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 */
dev_dbg(&pdx->interface->dev,
dev_dbg(&ced->interface->dev,
"Self-test timed-out\n");
} else
dev_dbg(&pdx->interface->dev,
dev_dbg(&ced->interface->dev,
"Self-test on-going\n");
}
} else {
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 using the 2890 we should reset properly */
if ((pdx->nPipes == 4) && (pdx->s1401Type <= TYPEPOWER))
ced_is_1401(pdx); /* Get 1401 reset and OK */
if ((ced->nPipes == 4) && (ced->s1401Type <= TYPEPOWER))
ced_is_1401(ced); /* Get 1401 reset and OK */
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)))
return -EFAULT;
......@@ -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
****************************************************************************/
int ced_type_of_1401(DEVICE_EXTENSION *pdx)
int ced_type_of_1401(struct ced_data *ced)
{
int iReturn = TYPEUNKNOWN;
mutex_lock(&pdx->io_mutex);
dev_dbg(&pdx->interface->dev, "%s\n", __func__);
mutex_lock(&ced->io_mutex);
dev_dbg(&ced->interface->dev, "%s\n", __func__);
switch (pdx->s1401Type) {
switch (ced->s1401Type) {
case TYPE1401:
iReturn = U14ERR_STD;
break; /* Handle these types directly */
......@@ -1077,13 +1077,13 @@ int ced_type_of_1401(DEVICE_EXTENSION *pdx)
iReturn = U14ERR_U1401;
break;
default:
if ((pdx->s1401Type >= TYPEPOWER) && (pdx->s1401Type <= 25))
iReturn = pdx->s1401Type + 4; /* We can calculate types */
if ((ced->s1401Type >= TYPEPOWER) && (ced->s1401Type <= 25))
iReturn = ced->s1401Type + 4; /* We can calculate types */
else /* for up-coming 1401 designs */
iReturn = TYPEUNKNOWN; /* Don't know or not there */
}
dev_dbg(&pdx->interface->dev, "%s %d\n", __func__, iReturn);
mutex_unlock(&pdx->io_mutex);
dev_dbg(&ced->interface->dev, "%s %d\n", __func__, iReturn);
mutex_unlock(&ced->io_mutex);
return iReturn;
}
......@@ -1093,15 +1093,15 @@ int ced_type_of_1401(DEVICE_EXTENSION *pdx)
**
** 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 */
U14TF_NOTIFY | U14TF_CIRCTH; /* diagnostics, notify and circular */
dev_dbg(&pdx->interface->dev, "%s\n", __func__);
mutex_lock(&pdx->io_mutex);
if (pdx->bIsUSB2) /* Set flag for USB2 if appropriate */
dev_dbg(&ced->interface->dev, "%s\n", __func__);
mutex_lock(&ced->io_mutex);
if (ced->bIsUSB2) /* Set flag for USB2 if appropriate */
iReturn |= U14TF_USB2;
mutex_unlock(&pdx->io_mutex);
mutex_unlock(&ced->io_mutex);
return iReturn;
}
......@@ -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
** 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)
{
int iReturn;
dev_dbg(&pdx->interface->dev, "%s: entry\n", __func__);
iReturn = usb_control_msg(pdx->udev, usb_sndctrlpipe(pdx->udev, 0), cmd,
dev_dbg(&ced->interface->dev, "%s: entry\n", __func__);
iReturn = usb_control_msg(ced->udev, usb_sndctrlpipe(ced->udev, 0), cmd,
(H_TO_D | VENDOR | DEVREQ),
(unsigned short)data,
(unsigned short)(data >> 16), NULL, 0, HZ);
/* allow 1 second timeout */
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);
return iReturn;
......@@ -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.
****************************************************************************/
int ced_dbg_peek(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
int ced_dbg_peek(struct ced_data *ced, TDBGBLOCK __user *pDB)
{
int iReturn;
TDBGBLOCK db;
......@@ -1141,17 +1141,17 @@ int ced_dbg_peek(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
if (copy_from_user(&db, pDB, sizeof(db)))
return -EFAULT;
mutex_lock(&pdx->io_mutex);
dev_dbg(&pdx->interface->dev, "%s: @ %08x\n", __func__, db.iAddr);
mutex_lock(&ced->io_mutex);
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)
iReturn = ced_dbg_cmd(pdx, DB_WIDTH, db.iWidth);
iReturn = ced_dbg_cmd(ced, DB_WIDTH, db.iWidth);
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)
iReturn = ced_dbg_cmd(pdx, DB_PEEK, 0);
mutex_unlock(&pdx->io_mutex);
iReturn = ced_dbg_cmd(ced, DB_PEEK, 0);
mutex_unlock(&ced->io_mutex);
return iReturn;
}
......@@ -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
** 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;
TDBGBLOCK db;
......@@ -1170,17 +1170,17 @@ int ced_dbg_poke(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
if (copy_from_user(&db, pDB, sizeof(db)))
return -EFAULT;
mutex_lock(&pdx->io_mutex);
dev_dbg(&pdx->interface->dev, "%s: @ %08x\n", __func__, db.iAddr);
mutex_lock(&ced->io_mutex);
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)
iReturn = ced_dbg_cmd(pdx, DB_WIDTH, db.iWidth);
iReturn = ced_dbg_cmd(ced, DB_WIDTH, db.iWidth);
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)
iReturn = ced_dbg_cmd(pdx, DB_POKE, db.iData);
mutex_unlock(&pdx->io_mutex);
iReturn = ced_dbg_cmd(ced, DB_POKE, db.iData);
mutex_unlock(&ced->io_mutex);
return iReturn;
}
......@@ -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
** 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;
TDBGBLOCK db;
......@@ -1199,21 +1199,21 @@ int ced_dbg_ramp_data(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
if (copy_from_user(&db, pDB, sizeof(db)))
return -EFAULT;
mutex_lock(&pdx->io_mutex);
dev_dbg(&pdx->interface->dev, "%s: @ %08x\n", __func__, db.iAddr);
mutex_lock(&ced->io_mutex);
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)
iReturn = ced_dbg_cmd(pdx, DB_SETDEF, db.iDefault);
iReturn = ced_dbg_cmd(ced, DB_SETDEF, db.iDefault);
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)
iReturn = ced_dbg_cmd(pdx, DB_WIDTH, db.iWidth);
iReturn = ced_dbg_cmd(ced, DB_WIDTH, db.iWidth);
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)
iReturn = ced_dbg_cmd(pdx, DB_RAMPD, 0);
mutex_unlock(&pdx->io_mutex);
iReturn = ced_dbg_cmd(ced, DB_RAMPD, 0);
mutex_unlock(&ced->io_mutex);
return iReturn;
}
......@@ -1223,7 +1223,7 @@ int ced_dbg_ramp_data(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
**
** 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;
TDBGBLOCK db;
......@@ -1231,19 +1231,19 @@ int ced_dbg_ramp_addr(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
if (copy_from_user(&db, pDB, sizeof(db)))
return -EFAULT;
mutex_lock(&pdx->io_mutex);
dev_dbg(&pdx->interface->dev, "%s\n", __func__);
mutex_lock(&ced->io_mutex);
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)
iReturn = ced_dbg_cmd(pdx, DB_SETMASK, db.iMask);
iReturn = ced_dbg_cmd(ced, DB_SETMASK, db.iMask);
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)
iReturn = ced_dbg_cmd(pdx, DB_REPEATS, db.iRepeats);
iReturn = ced_dbg_cmd(ced, DB_REPEATS, db.iRepeats);
if (iReturn == U14ERR_NOERROR)
iReturn = ced_dbg_cmd(pdx, DB_RAMPA, 0);
mutex_unlock(&pdx->io_mutex);
iReturn = ced_dbg_cmd(ced, DB_RAMPA, 0);
mutex_unlock(&ced->io_mutex);
return iReturn;
}
......@@ -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
****************************************************************************/
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;
TDBGBLOCK db;
memset(&db, 0, sizeof(db)); /* fill returned block with 0s */
mutex_lock(&pdx->io_mutex);
dev_dbg(&pdx->interface->dev, "%s\n", __func__);
mutex_lock(&ced->io_mutex);
dev_dbg(&ced->interface->dev, "%s\n", __func__);
/* 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.iData, sizeof(db.iData), HZ);
if (iReturn == sizeof(db.iData)) {
......@@ -1272,10 +1272,10 @@ int ced_dbg_get_data(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
else
iReturn = U14ERR_NOERROR;
} else
dev_err(&pdx->interface->dev, "%s: failed, code %d\n",
dev_err(&ced->interface->dev, "%s: failed, code %d\n",
__func__, iReturn);
mutex_unlock(&pdx->io_mutex);
mutex_unlock(&ced->io_mutex);
return iReturn;
}
......@@ -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
**
****************************************************************************/
int ced_dbg_stop_loop(DEVICE_EXTENSION *pdx)
int ced_dbg_stop_loop(struct ced_data *ced)
{
int iReturn;
unsigned int uState, uErr;
mutex_lock(&pdx->io_mutex);
dev_dbg(&pdx->interface->dev, "%s\n", __func__);
iReturn = ced_get_state(pdx, &uState, &uErr);
mutex_unlock(&pdx->io_mutex);
mutex_lock(&ced->io_mutex);
dev_dbg(&ced->interface->dev, "%s\n", __func__);
iReturn = ced_get_state(ced, &uState, &uErr);
mutex_unlock(&ced->io_mutex);
return iReturn;
}
......@@ -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
** 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;
bool bToHost;
......@@ -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)))
return -EFAULT;
mutex_lock(&pdx->io_mutex);
dev_dbg(&pdx->interface->dev, "%s: area:%d, size:%08x\n",
mutex_lock(&ced->io_mutex);
dev_dbg(&ced->interface->dev, "%s: area:%d, size:%08x\n",
__func__, td.wAreaNum, td.dwLength);
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
/* pointer. The pointer is always passed as a 64-bit object so that we don't have problems using */
/* a 32-bit program on a 64-bit system. unsigned long is 64-bits on a 64-bit system. */
iReturn =
ced_set_area(pdx, td.wAreaNum,
ced_set_area(ced, td.wAreaNum,
(char __user *)((unsigned long)td.lpvBuff), td.dwLength,
true, bToHost);
mutex_unlock(&pdx->io_mutex);
mutex_unlock(&ced->io_mutex);
return iReturn;
}
......@@ -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.
****************************************************************************/
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;
unsigned int nArea;
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)))
return -EFAULT;
mutex_lock(&pdx->io_mutex);
mutex_lock(&ced->io_mutex);
nArea = cb.nArea; /* Retrieve parameters first */
cb.dwOffset = 0; /* set default result (nothing) */
......@@ -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 */
/* Pointer to relevant info */
struct transarea *pArea = &pdx->rTransDef[nArea];
spin_lock_irq(&pdx->stagedLock); /* Lock others out */
struct transarea *pArea = &ced->rTransDef[nArea];
spin_lock_irq(&ced->stagedLock); /* Lock others out */
if ((pArea->bUsed) && (pArea->bCircular) && /* Must be circular area */
(pArea->bCircToHost)) { /* For now at least must be to host */
if (pArea->aBlocks[0].dwSize > 0) { /* Got anything? */
cb.dwOffset = pArea->aBlocks[0].dwOffset;
cb.dwSize = pArea->aBlocks[0].dwSize;
dev_dbg(&pdx->interface->dev,
dev_dbg(&ced->interface->dev,
"%s: return block 0: %d bytes at %d\n",
__func__, cb.dwSize, cb.dwOffset);
}
} else
iReturn = U14ERR_NOTSET;
spin_unlock_irq(&pdx->stagedLock);
spin_unlock_irq(&ced->stagedLock);
} else
iReturn = U14ERR_BADAREA;
if (copy_to_user(pCB, &cb, sizeof(cb)))
iReturn = -EFAULT;
mutex_unlock(&pdx->io_mutex);
mutex_unlock(&ced->io_mutex);
return iReturn;
}
......@@ -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.
****************************************************************************/
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;
unsigned int nArea, uStart, uSize;
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)))
return -EFAULT;
mutex_lock(&pdx->io_mutex);
mutex_lock(&ced->io_mutex);
nArea = cb.nArea; /* Retrieve parameters first */
uStart = cb.dwOffset;
......@@ -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 */
/* Pointer to relevant info */
struct transarea *pArea = &pdx->rTransDef[nArea];
spin_lock_irq(&pdx->stagedLock); /* Lock others out */
struct transarea *pArea = &ced->rTransDef[nArea];
spin_lock_irq(&ced->stagedLock); /* Lock others out */
if ((pArea->bUsed) && (pArea->bCircular) && /* Must be circular area */
(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)
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",
__func__, uSize, uStart,
pArea->aBlocks[0].dwSize,
pArea->aBlocks[0].dwOffset,
pdx->bXFerWaiting);
ced->bXFerWaiting);
/* Return the next available block of memory as well */
if (pArea->aBlocks[0].dwSize > 0) { /* Got anything? */
......@@ -1442,15 +1442,15 @@ int ced_free_circ_block(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB)
cb.dwSize = pArea->aBlocks[0].dwSize;
}
bWaiting = pdx->bXFerWaiting;
if (bWaiting && pdx->bStagedUrbPending) {
dev_err(&pdx->interface->dev,
bWaiting = ced->bXFerWaiting;
if (bWaiting && ced->bStagedUrbPending) {
dev_err(&ced->interface->dev,
"%s: ERROR: waiting xfer and staged Urb pending!\n",
__func__);
bWaiting = false;
}
} 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",
__func__, uSize, uStart,
pArea->aBlocks[0].dwSize,
......@@ -1461,25 +1461,25 @@ int ced_free_circ_block(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB)
/* If we have one, kick off pending transfer */
if (bWaiting) { /* Got a block xfer waiting? */
int RWMStat =
ced_read_write_mem(pdx, !pdx->rDMAInfo.bOutWard,
pdx->rDMAInfo.wIdent,
pdx->rDMAInfo.dwOffset,
pdx->rDMAInfo.dwSize);
ced_read_write_mem(ced, !ced->rDMAInfo.bOutWard,
ced->rDMAInfo.wIdent,
ced->rDMAInfo.dwOffset,
ced->rDMAInfo.dwSize);
if (RWMStat != U14ERR_NOERROR)
dev_err(&pdx->interface->dev,
dev_err(&ced->interface->dev,
"%s: rw setup failed %d\n",
__func__, RWMStat);
}
} else
iReturn = U14ERR_NOTSET;
spin_unlock_irq(&pdx->stagedLock);
spin_unlock_irq(&ced->stagedLock);
} else
iReturn = U14ERR_BADAREA;
if (copy_to_user(pCB, &cb, sizeof(cb)))
iReturn = -EFAULT;
mutex_unlock(&pdx->io_mutex);
mutex_unlock(&ced->io_mutex);
return iReturn;
}
......@@ -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).
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
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
......@@ -123,32 +123,32 @@ static struct usb_driver ced_driver;
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 */
/* of pdx will probably be NULL, so cannot be used to get to dev. */
usb_free_coherent(pdx->udev, OUTBUF_SZ, pdx->pCoherCharOut,
pdx->pUrbCharOut->transfer_dma);
usb_free_urb(pdx->pUrbCharOut);
/* of ced will probably be NULL, so cannot be used to get to dev. */
usb_free_coherent(ced->udev, OUTBUF_SZ, ced->pCoherCharOut,
ced->pUrbCharOut->transfer_dma);
usb_free_urb(ced->pUrbCharOut);
/* Do the same for chan input */
usb_free_coherent(pdx->udev, INBUF_SZ, pdx->pCoherCharIn,
pdx->pUrbCharIn->transfer_dma);
usb_free_urb(pdx->pUrbCharIn);
usb_free_coherent(ced->udev, INBUF_SZ, ced->pCoherCharIn,
ced->pUrbCharIn->transfer_dma);
usb_free_urb(ced->pUrbCharIn);
/* Do the same for the block transfers */
usb_free_coherent(pdx->udev, STAGED_SZ, pdx->pCoherStagedIO,
pdx->pStagedUrb->transfer_dma);
usb_free_urb(pdx->pStagedUrb);
usb_free_coherent(ced->udev, STAGED_SZ, ced->pCoherStagedIO,
ced->pStagedUrb->transfer_dma);
usb_free_urb(ced->pStagedUrb);
usb_put_dev(pdx->udev);
kfree(pdx);
usb_put_dev(ced->udev);
kfree(ced);
}
/* This is the driver end of the open() call from user space. */
static int ced_open(struct inode *inode, struct file *file)
{
DEVICE_EXTENSION *pdx;
struct ced_data *ced;
int retval = 0;
int subminor = iminor(inode);
struct usb_interface *interface =
......@@ -160,42 +160,42 @@ static int ced_open(struct inode *inode, struct file *file)
goto exit;
}
pdx = usb_get_intfdata(interface);
if (!pdx) {
ced = usb_get_intfdata(interface);
if (!ced) {
retval = -ENODEV;
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 */
kref_get(&pdx->kref);
kref_get(&ced->kref);
/* lock the device to allow correctly handling errors
* 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);
if (retval) {
pdx->open_count--;
mutex_unlock(&pdx->io_mutex);
kref_put(&pdx->kref, ced_delete);
ced->open_count--;
mutex_unlock(&ced->io_mutex);
kref_put(&ced->kref, ced_delete);
goto exit;
}
} else { /* uncomment this block if you want exclusive open */
dev_err(&interface->dev, "%s: fail: already open\n", __func__);
retval = -EBUSY;
pdx->open_count--;
mutex_unlock(&pdx->io_mutex);
kref_put(&pdx->kref, ced_delete);
ced->open_count--;
mutex_unlock(&ced->io_mutex);
kref_put(&ced->kref, ced_delete);
goto exit;
}
/* prevent the device from being autosuspended */
/* save our object in the file's private structure */
file->private_data = pdx;
mutex_unlock(&pdx->io_mutex);
file->private_data = ced;
mutex_unlock(&ced->io_mutex);
exit:
return retval;
......@@ -203,43 +203,43 @@ static int ced_open(struct inode *inode, struct file *file)
static int ced_release(struct inode *inode, struct file *file)
{
DEVICE_EXTENSION *pdx = file->private_data;
if (pdx == NULL)
struct ced_data *ced = file->private_data;
if (ced == NULL)
return -ENODEV;
dev_dbg(&pdx->interface->dev, "%s: called\n", __func__);
mutex_lock(&pdx->io_mutex);
if (!--pdx->open_count && pdx->interface) /* Allow autosuspend */
usb_autopm_put_interface(pdx->interface);
mutex_unlock(&pdx->io_mutex);
dev_dbg(&ced->interface->dev, "%s: called\n", __func__);
mutex_lock(&ced->io_mutex);
if (!--ced->open_count && ced->interface) /* Allow autosuspend */
usb_autopm_put_interface(ced->interface);
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;
}
static int ced_flush(struct file *file, fl_owner_t id)
{
int res;
DEVICE_EXTENSION *pdx = file->private_data;
if (pdx == NULL)
struct ced_data *ced = file->private_data;
if (ced == NULL)
return -ENODEV;
dev_dbg(&pdx->interface->dev, "%s: char in pend=%d\n",
__func__, pdx->bReadCharsPending);
dev_dbg(&ced->interface->dev, "%s: char in pend=%d\n",
__func__, ced->bReadCharsPending);
/* wait for io to stop */
mutex_lock(&pdx->io_mutex);
dev_dbg(&pdx->interface->dev, "%s: got io_mutex\n", __func__);
ced_draw_down(pdx);
mutex_lock(&ced->io_mutex);
dev_dbg(&ced->interface->dev, "%s: got io_mutex\n", __func__);
ced_draw_down(ced);
/* read out errors, leave subsequent opens a clean slate */
spin_lock_irq(&pdx->err_lock);
res = pdx->errors ? (pdx->errors == -EPIPE ? -EPIPE : -EIO) : 0;
pdx->errors = 0;
spin_unlock_irq(&pdx->err_lock);
spin_lock_irq(&ced->err_lock);
res = ced->errors ? (ced->errors == -EPIPE ? -EPIPE : -EIO) : 0;
ced->errors = 0;
spin_unlock_irq(&ced->err_lock);
mutex_unlock(&pdx->io_mutex);
dev_dbg(&pdx->interface->dev, "%s: exit reached\n", __func__);
mutex_unlock(&ced->io_mutex);
dev_dbg(&ced->interface->dev, "%s: exit reached\n", __func__);
return res;
}
......@@ -247,13 +247,13 @@ static int ced_flush(struct file *file, fl_owner_t id)
/***************************************************************************
** can_accept_io_requests
** 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.
** 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)
****************************************************************************/
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 */
if (pUrb->status) { /* sync/async unlink faults aren't errors */
if (!
(pUrb->status == -ENOENT || pUrb->status == -ECONNRESET
|| pUrb->status == -ESHUTDOWN)) {
dev_err(&pdx->interface->dev,
dev_err(&ced->interface->dev,
"%s: nonzero write bulk status received: %d\n",
__func__, pUrb->status);
}
spin_lock(&pdx->err_lock);
pdx->errors = pUrb->status;
spin_unlock(&pdx->err_lock);
spin_lock(&ced->err_lock);
ced->errors = pUrb->status;
spin_unlock(&ced->err_lock);
nGot = 0; /* and tidy up again if so */
spin_lock(&pdx->charOutLock); /* already at irq level */
pdx->dwOutBuffGet = 0; /* Reset the output buffer */
pdx->dwOutBuffPut = 0;
pdx->dwNumOutput = 0; /* Clear the char count */
pdx->bPipeError[0] = 1; /* Flag an error for later */
pdx->bSendCharsPending = false; /* Allow other threads again */
spin_unlock(&pdx->charOutLock); /* already at irq level */
dev_dbg(&pdx->interface->dev,
spin_lock(&ced->charOutLock); /* already at irq level */
ced->dwOutBuffGet = 0; /* Reset the output buffer */
ced->dwOutBuffPut = 0;
ced->dwNumOutput = 0; /* Clear the char count */
ced->bPipeError[0] = 1; /* Flag an error for later */
ced->bSendCharsPending = false; /* Allow other threads again */
spin_unlock(&ced->charOutLock); /* already at irq level */
dev_dbg(&ced->interface->dev,
"%s: char out done, 0 chars sent\n", __func__);
} else {
dev_dbg(&pdx->interface->dev,
dev_dbg(&ced->interface->dev,
"%s: char out done, %d chars sent\n", __func__, nGot);
spin_lock(&pdx->charOutLock); /* already at irq level */
pdx->dwNumOutput -= nGot; /* Now adjust the char send buffer */
pdx->dwOutBuffGet += nGot; /* to match what we did */
if (pdx->dwOutBuffGet >= OUTBUF_SZ) /* Can't do this any earlier as data could be overwritten */
pdx->dwOutBuffGet = 0;
spin_lock(&ced->charOutLock); /* already at irq level */
ced->dwNumOutput -= nGot; /* Now adjust the char send buffer */
ced->dwOutBuffGet += nGot; /* to match what we did */
if (ced->dwOutBuffGet >= OUTBUF_SZ) /* Can't do this any earlier as data could be overwritten */
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 iReturn;
char *pDat = &pdx->outputBuffer[pdx->dwOutBuffGet];
unsigned int dwCount = pdx->dwNumOutput; /* maximum to send */
if ((pdx->dwOutBuffGet + dwCount) > OUTBUF_SZ) /* does it cross buffer end? */
dwCount = OUTBUF_SZ - pdx->dwOutBuffGet;
spin_unlock(&pdx->charOutLock); /* we are done with stuff that changes */
memcpy(pdx->pCoherCharOut, pDat, dwCount); /* copy output data to the buffer */
usb_fill_bulk_urb(pdx->pUrbCharOut, pdx->udev,
usb_sndbulkpipe(pdx->udev,
pdx->epAddr[0]),
pdx->pCoherCharOut, dwCount,
ced_writechar_callback, pdx);
pdx->pUrbCharOut->transfer_flags |=
char *pDat = &ced->outputBuffer[ced->dwOutBuffGet];
unsigned int dwCount = ced->dwNumOutput; /* maximum to send */
if ((ced->dwOutBuffGet + dwCount) > OUTBUF_SZ) /* does it cross buffer end? */
dwCount = OUTBUF_SZ - ced->dwOutBuffGet;
spin_unlock(&ced->charOutLock); /* we are done with stuff that changes */
memcpy(ced->pCoherCharOut, pDat, dwCount); /* copy output data to the buffer */
usb_fill_bulk_urb(ced->pUrbCharOut, ced->udev,
usb_sndbulkpipe(ced->udev,
ced->epAddr[0]),
ced->pCoherCharOut, dwCount,
ced_writechar_callback, ced);
ced->pUrbCharOut->transfer_flags |=
URB_NO_TRANSFER_DMA_MAP;
usb_anchor_urb(pdx->pUrbCharOut, &pdx->submitted); /* in case we need to kill it */
iReturn = usb_submit_urb(pdx->pUrbCharOut, GFP_ATOMIC);
dev_dbg(&pdx->interface->dev, "%s: n=%d>%s<\n",
usb_anchor_urb(ced->pUrbCharOut, &ced->submitted); /* in case we need to kill it */
iReturn = usb_submit_urb(ced->pUrbCharOut, GFP_ATOMIC);
dev_dbg(&ced->interface->dev, "%s: n=%d>%s<\n",
__func__, dwCount, pDat);
spin_lock(&pdx->charOutLock); /* grab lock for errors */
spin_lock(&ced->charOutLock); /* grab lock for errors */
if (iReturn) {
pdx->bPipeError[nPipe] = 1; /* Flag an error to be handled later */
pdx->bSendCharsPending = false; /* Allow other threads again */
usb_unanchor_urb(pdx->pUrbCharOut);
dev_err(&pdx->interface->dev,
ced->bPipeError[nPipe] = 1; /* Flag an error to be handled later */
ced->bSendCharsPending = false; /* Allow other threads again */
usb_unanchor_urb(ced->pUrbCharOut);
dev_err(&ced->interface->dev,
"%s: usb_submit_urb() returned %d\n",
__func__, iReturn);
}
} else
pdx->bSendCharsPending = false; /* Allow other threads again */
spin_unlock(&pdx->charOutLock); /* already at irq level */
ced->bSendCharsPending = false; /* Allow other threads again */
spin_unlock(&ced->charOutLock); /* already at irq level */
}
}
......@@ -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
** breaking down into multiple transfers.
****************************************************************************/
int ced_send_chars(DEVICE_EXTENSION *pdx)
int ced_send_chars(struct ced_data *ced)
{
int iReturn = U14ERR_NOERROR;
spin_lock_irq(&pdx->charOutLock); /* Protect ourselves */
spin_lock_irq(&ced->charOutLock); /* Protect ourselves */
if ((!pdx->bSendCharsPending) && /* Not currently sending */
(pdx->dwNumOutput > 0) && /* has characters to output */
(can_accept_io_requests(pdx))) { /* and current activity is OK */
unsigned int dwCount = pdx->dwNumOutput; /* Get a copy of the character count */
pdx->bSendCharsPending = true; /* Set flag to lock out other threads */
if ((!ced->bSendCharsPending) && /* Not currently sending */
(ced->dwNumOutput > 0) && /* has characters to output */
(can_accept_io_requests(ced))) { /* and current activity is OK */
unsigned int dwCount = ced->dwNumOutput; /* Get a copy of the character count */
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",
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 (pdx->nPipes == 3) {
if (ced->nPipes == 3) {
/* 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. */
unsigned int count = dwCount; /* Local char counter */
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)) {
/* 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 nSent = usb_control_msg(pdx->udev,
usb_sndctrlpipe(pdx->udev, 0), /* use end point 0 */
int nSent = usb_control_msg(ced->udev,
usb_sndctrlpipe(ced->udev, 0), /* use end point 0 */
DB_CHARS, /* bRequest */
(H_TO_D | VENDOR | DEVREQ), /* to the device, vendor request to the device */
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 */
1000); /* timeout in jiffies */
if (nSent <= 0) {
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",
n, iReturn);
} else {
dev_dbg(&pdx->interface->dev,
dev_dbg(&ced->interface->dev,
"Sent %d chars by EP0\n", n);
count -= nSent;
index += nSent;
}
}
spin_lock_irq(&pdx->charOutLock); /* Protect pdx changes, released by general code */
pdx->dwOutBuffGet = 0; /* so reset the output buffer */
pdx->dwOutBuffPut = 0;
pdx->dwNumOutput = 0; /* and clear the buffer count */
pdx->bSendCharsPending = false; /* Allow other threads again */
spin_lock_irq(&ced->charOutLock); /* Protect ced changes, released by general code */
ced->dwOutBuffGet = 0; /* so reset the output buffer */
ced->dwOutBuffPut = 0;
ced->dwNumOutput = 0; /* and clear the buffer count */
ced->bSendCharsPending = false; /* Allow other threads again */
} else { /* Here for sending chars normally - we hold the spin lock */
int nPipe = 0; /* The pipe number to use */
char *pDat = &pdx->outputBuffer[pdx->dwOutBuffGet];
if ((pdx->dwOutBuffGet + dwCount) > OUTBUF_SZ) /* does it cross buffer end? */
dwCount = OUTBUF_SZ - pdx->dwOutBuffGet;
spin_unlock_irq(&pdx->charOutLock); /* we are done with stuff that changes */
memcpy(pdx->pCoherCharOut, pDat, dwCount); /* copy output data to the buffer */
usb_fill_bulk_urb(pdx->pUrbCharOut, pdx->udev,
usb_sndbulkpipe(pdx->udev,
pdx->epAddr[0]),
pdx->pCoherCharOut, dwCount,
ced_writechar_callback, pdx);
pdx->pUrbCharOut->transfer_flags |=
char *pDat = &ced->outputBuffer[ced->dwOutBuffGet];
if ((ced->dwOutBuffGet + dwCount) > OUTBUF_SZ) /* does it cross buffer end? */
dwCount = OUTBUF_SZ - ced->dwOutBuffGet;
spin_unlock_irq(&ced->charOutLock); /* we are done with stuff that changes */
memcpy(ced->pCoherCharOut, pDat, dwCount); /* copy output data to the buffer */
usb_fill_bulk_urb(ced->pUrbCharOut, ced->udev,
usb_sndbulkpipe(ced->udev,
ced->epAddr[0]),
ced->pCoherCharOut, dwCount,
ced_writechar_callback, ced);
ced->pUrbCharOut->transfer_flags |=
URB_NO_TRANSFER_DMA_MAP;
usb_anchor_urb(pdx->pUrbCharOut, &pdx->submitted);
iReturn = usb_submit_urb(pdx->pUrbCharOut, GFP_KERNEL);
spin_lock_irq(&pdx->charOutLock); /* grab lock for errors */
usb_anchor_urb(ced->pUrbCharOut, &ced->submitted);
iReturn = usb_submit_urb(ced->pUrbCharOut, GFP_KERNEL);
spin_lock_irq(&ced->charOutLock); /* grab lock for errors */
if (iReturn) {
pdx->bPipeError[nPipe] = 1; /* Flag an error to be handled later */
pdx->bSendCharsPending = false; /* Allow other threads again */
usb_unanchor_urb(pdx->pUrbCharOut); /* remove from list of active urbs */
ced->bPipeError[nPipe] = 1; /* Flag an error to be handled later */
ced->bSendCharsPending = false; /* Allow other threads again */
usb_unanchor_urb(ced->pUrbCharOut); /* remove from list of active urbs */
}
}
} else if (pdx->bSendCharsPending && (pdx->dwNumOutput > 0))
dev_dbg(&pdx->interface->dev,
} else if (ced->bSendCharsPending && (ced->dwNumOutput > 0))
dev_dbg(&ced->interface->dev,
"%s: bSendCharsPending:true\n", __func__);
dev_dbg(&pdx->interface->dev, "%s: exit code: %d\n", __func__, iReturn);
spin_unlock_irq(&pdx->charOutLock); /* Now let go of the spinlock */
dev_dbg(&ced->interface->dev, "%s: exit code: %d\n", __func__, iReturn);
spin_unlock_irq(&ced->charOutLock); /* Now let go of the spinlock */
return iReturn;
}
......@@ -427,27 +427,27 @@ int ced_send_chars(DEVICE_EXTENSION *pdx)
** ced_copy_user_space
** This moves memory between pinned down user space and the pCoherStagedIO
** 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
** in pdx->StagedId and the offset in pdx->StagedDone. The user
** is defined by ced->StagedRead. The user space is determined by the area
** in ced->StagedId and the offset in ced->StagedDone. The user
** 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
** 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.
***************************************************************************/
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) {
/* area to be used */
struct transarea *pArea = &pdx->rTransDef[nArea];
struct transarea *pArea = &ced->rTransDef[nArea];
unsigned int dwOffset =
pdx->StagedDone + pdx->StagedOffset + pArea->dwBaseOffset;
char *pCoherBuf = pdx->pCoherStagedIO; /* coherent buffer */
ced->StagedDone + ced->StagedOffset + pArea->dwBaseOffset;
char *pCoherBuf = ced->pCoherStagedIO; /* coherent buffer */
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);
return;
}
......@@ -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 */
if (uiXfer > n) /* limit byte count if too much */
uiXfer = n; /* for the page */
if (pdx->StagedRead)
if (ced->StagedRead)
memcpy(pvAddress + uiPageOff,
pCoherBuf, uiXfer);
else
......@@ -474,26 +474,26 @@ static void ced_copy_user_space(DEVICE_EXTENSION *pdx, int n)
pCoherBuf += uiXfer;
n -= uiXfer;
} else {
dev_err(&pdx->interface->dev,
dev_err(&ced->interface->dev,
"%s: did not map page %d\n",
__func__, nPage);
return;
}
} else {
dev_err(&pdx->interface->dev,
dev_err(&ced->interface->dev,
"%s: exceeded pages %d\n",
__func__, nPage);
return;
}
}
} else
dev_err(&pdx->interface->dev, "%s: bad area %d\n",
dev_err(&ced->interface->dev, "%s: bad area %d\n",
__func__, nArea);
}
/* 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
**
......@@ -501,76 +501,76 @@ static int ced_stage_chunk(DEVICE_EXTENSION *pdx);
*/
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 */
bool bCancel = false;
bool bRestartCharInput; /* used at the end */
spin_lock(&pdx->stagedLock); /* stop ced_read_write_mem() action while this routine is running */
pdx->bStagedUrbPending = false; /* clear the flag for staged IRP pending */
spin_lock(&ced->stagedLock); /* stop ced_read_write_mem() action while this routine is running */
ced->bStagedUrbPending = false; /* clear the flag for staged IRP pending */
if (pUrb->status) { /* sync/async unlink faults aren't errors */
if (!
(pUrb->status == -ENOENT || pUrb->status == -ECONNRESET
|| pUrb->status == -ESHUTDOWN)) {
dev_err(&pdx->interface->dev,
dev_err(&ced->interface->dev,
"%s: nonzero write bulk status received: %d\n",
__func__, pUrb->status);
} else
dev_info(&pdx->interface->dev,
dev_info(&ced->interface->dev,
"%s: staged xfer cancelled\n", __func__);
spin_lock(&pdx->err_lock);
pdx->errors = pUrb->status;
spin_unlock(&pdx->err_lock);
spin_lock(&ced->err_lock);
ced->errors = pUrb->status;
spin_unlock(&ced->err_lock);
nGot = 0; /* and tidy up again if so */
bCancel = true;
} else {
dev_dbg(&pdx->interface->dev, "%s: %d chars xferred\n",
dev_dbg(&ced->interface->dev, "%s: %d chars xferred\n",
__func__, nGot);
if (pdx->StagedRead) /* if reading, save to user space */
ced_copy_user_space(pdx, nGot); /* copy from buffer to user */
if (ced->StagedRead) /* if reading, save to user space */
ced_copy_user_space(ced, nGot); /* copy from buffer to user */
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 */
pdx->StagedDone += nGot;
ced->StagedDone += nGot;
dev_dbg(&pdx->interface->dev, "%s: done %d bytes of %d\n",
__func__, pdx->StagedDone, pdx->StagedLength);
dev_dbg(&ced->interface->dev, "%s: done %d bytes of %d\n",
__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 */
/* Transfer area info */
struct transarea *pArea = &pdx->rTransDef[pdx->StagedId];
dev_dbg(&pdx->interface->dev,
struct transarea *pArea = &ced->rTransDef[ced->StagedId];
dev_dbg(&ced->interface->dev,
"%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 */
/* 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 */
/* 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? */
(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 (pdx->StagedOffset ==
if (ced->StagedOffset ==
(pArea->aBlocks[1].dwOffset +
pArea->aBlocks[1].dwSize)) {
pArea->aBlocks[1].dwSize +=
pdx->StagedLength;
dev_dbg(&pdx->interface->dev,
ced->StagedLength;
dev_dbg(&ced->interface->dev,
"RWM_Complete, circ block 1 now %d bytes at %d\n",
pArea->aBlocks[1].dwSize,
pArea->aBlocks[1].dwOffset);
} else {
/* Here things have gone very, very, wrong, but I cannot see how this can actually be achieved */
pArea->aBlocks[1].dwOffset =
pdx->StagedOffset;
ced->StagedOffset;
pArea->aBlocks[1].dwSize =
pdx->StagedLength;
dev_err(&pdx->interface->dev,
ced->StagedLength;
dev_err(&ced->interface->dev,
"%s: ERROR, circ block 1 re-started %d bytes at %d\n",
__func__,
pArea->aBlocks[1].dwSize,
......@@ -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 */
if (pArea->aBlocks[0].dwSize > 0) { /* Got stored block 0 information? */
/* Must append onto the existing block 0 */
if (pdx->StagedOffset ==
if (ced->StagedOffset ==
(pArea->aBlocks[0].dwOffset +
pArea->aBlocks[0].dwSize)) {
pArea->aBlocks[0].dwSize += pdx->StagedLength; /* Just add this transfer in */
dev_dbg(&pdx->interface->dev,
pArea->aBlocks[0].dwSize += ced->StagedLength; /* Just add this transfer in */
dev_dbg(&ced->interface->dev,
"RWM_Complete, circ block 0 now %d bytes at %d\n",
pArea->aBlocks[0].
dwSize,
......@@ -591,10 +591,10 @@ static void staged_callback(struct urb *pUrb)
dwOffset);
} else { /* If it doesn't append, put into new block 1 */
pArea->aBlocks[1].dwOffset =
pdx->StagedOffset;
ced->StagedOffset;
pArea->aBlocks[1].dwSize =
pdx->StagedLength;
dev_dbg(&pdx->interface->dev,
ced->StagedLength;
dev_dbg(&ced->interface->dev,
"RWM_Complete, circ block 1 started %d bytes at %d\n",
pArea->aBlocks[1].
dwSize,
......@@ -603,10 +603,10 @@ static void staged_callback(struct urb *pUrb)
}
} else { /* No info stored yet, just save in block 0 */
pArea->aBlocks[0].dwOffset =
pdx->StagedOffset;
ced->StagedOffset;
pArea->aBlocks[0].dwSize =
pdx->StagedLength;
dev_dbg(&pdx->interface->dev,
ced->StagedLength;
dev_dbg(&ced->interface->dev,
"RWM_Complete, circ block 0 started %d bytes at %d\n",
pArea->aBlocks[0].dwSize,
pArea->aBlocks[0].dwOffset);
......@@ -615,12 +615,12 @@ static void staged_callback(struct urb *pUrb)
}
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",
pArea->bCircular, pArea->bEventToHost,
pArea->dwEventSt, pArea->dwEventSz);
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 */
/* 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. */
......@@ -633,16 +633,16 @@ static void staged_callback(struct urb *pUrb)
iWakeUp = (dwTotal >= pArea->dwEventSz);
} else {
unsigned int transEnd =
pdx->StagedOffset +
pdx->StagedLength;
ced->StagedOffset +
ced->StagedLength;
unsigned int eventEnd =
pArea->dwEventSt + pArea->dwEventSz;
iWakeUp = (pdx->StagedOffset < eventEnd)
iWakeUp = (ced->StagedOffset < eventEnd)
&& (transEnd > pArea->dwEventSt);
}
if (iWakeUp) {
dev_dbg(&pdx->interface->dev,
dev_dbg(&ced->interface->dev,
"About to set event to notify app\n");
wake_up_interruptible(&pArea->wqEvent); /* wake up waiting processes */
++pArea->iWakeUp; /* increment wakeup count */
......@@ -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 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;
dev_info(&pdx->interface->dev,
dev_info(&ced->interface->dev,
"*** RWM_Complete *** pending transfer will now be set up!!!\n");
iReturn =
ced_read_write_mem(pdx, !pdx->rDMAInfo.bOutWard,
pdx->rDMAInfo.wIdent,
pdx->rDMAInfo.dwOffset,
pdx->rDMAInfo.dwSize);
ced_read_write_mem(ced, !ced->rDMAInfo.bOutWard,
ced->rDMAInfo.wIdent,
ced->rDMAInfo.dwOffset,
ced->rDMAInfo.dwSize);
if (iReturn)
dev_err(&pdx->interface->dev,
dev_err(&ced->interface->dev,
"RWM_Complete rw setup failed %d\n",
iReturn);
}
}
} 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 */
/* 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. */
bRestartCharInput = !bCancel && (pdx->dwDMAFlag == MODE_CHAR)
&& !pdx->bXFerWaiting;
bRestartCharInput = !bCancel && (ced->dwDMAFlag == MODE_CHAR)
&& !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 */
/* 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. */
if (bRestartCharInput) /* may be out of date, but... */
ced_allowi(pdx); /* ...ced_allowi tests a lock too. */
dev_dbg(&pdx->interface->dev, "%s: done\n", __func__);
ced_allowi(ced); /* ...ced_allowi tests a lock too. */
dev_dbg(&ced->interface->dev, "%s: done\n", __func__);
}
/****************************************************************************
......@@ -698,47 +698,47 @@ static void staged_callback(struct urb *pUrb)
** The calling code must have acquired the staging spinlock before calling
** 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;
unsigned int ChunkSize;
int nPipe = pdx->StagedRead ? 3 : 2; /* The pipe number to use for reads or writes */
if (pdx->nPipes == 3)
int nPipe = ced->StagedRead ? 3 : 2; /* The pipe number to use for reads or writes */
if (ced->nPipes == 3)
nPipe--; /* Adjust for the 3-pipe case */
if (nPipe < 0) /* and trap case that should never happen */
return U14ERR_FAIL;
if (!can_accept_io_requests(pdx)) { /* got sudden remove? */
dev_info(&pdx->interface->dev, "%s: sudden remove, giving up\n",
if (!can_accept_io_requests(ced)) { /* got sudden remove? */
dev_info(&ced->interface->dev, "%s: sudden remove, giving up\n",
__func__);
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 */
ChunkSize = STAGED_SZ; /* limit to max allowed */
if (!pdx->StagedRead) /* if writing... */
ced_copy_user_space(pdx, ChunkSize); /* ...copy data into the buffer */
if (!ced->StagedRead) /* if writing... */
ced_copy_user_space(ced, ChunkSize); /* ...copy data into the buffer */
usb_fill_bulk_urb(pdx->pStagedUrb, pdx->udev,
pdx->StagedRead ? usb_rcvbulkpipe(pdx->udev,
pdx->
usb_fill_bulk_urb(ced->pStagedUrb, ced->udev,
ced->StagedRead ? usb_rcvbulkpipe(ced->udev,
ced->
epAddr[nPipe]) :
usb_sndbulkpipe(pdx->udev, pdx->epAddr[nPipe]),
pdx->pCoherStagedIO, ChunkSize, staged_callback, pdx);
pdx->pStagedUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
usb_anchor_urb(pdx->pStagedUrb, &pdx->submitted); /* in case we need to kill it */
iReturn = usb_submit_urb(pdx->pStagedUrb, GFP_ATOMIC);
usb_sndbulkpipe(ced->udev, ced->epAddr[nPipe]),
ced->pCoherStagedIO, ChunkSize, staged_callback, ced);
ced->pStagedUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
usb_anchor_urb(ced->pStagedUrb, &ced->submitted); /* in case we need to kill it */
iReturn = usb_submit_urb(ced->pStagedUrb, GFP_ATOMIC);
if (iReturn) {
usb_unanchor_urb(pdx->pStagedUrb); /* kill it */
pdx->bPipeError[nPipe] = 1; /* Flag an error to be handled later */
dev_err(&pdx->interface->dev, "%s: submit urb failed, code %d\n",
usb_unanchor_urb(ced->pStagedUrb); /* kill it */
ced->bPipeError[nPipe] = 1; /* Flag an error to be handled later */
dev_err(&ced->interface->dev, "%s: submit urb failed, code %d\n",
__func__, iReturn);
} else
pdx->bStagedUrbPending = true; /* Set the flag for staged URB pending */
dev_dbg(&pdx->interface->dev, "%s: done so far:%d, this size:%d\n",
__func__, pdx->StagedDone, ChunkSize);
ced->bStagedUrbPending = true; /* Set the flag for staged URB pending */
dev_dbg(&ced->interface->dev, "%s: done so far:%d, this size:%d\n",
__func__, ced->StagedDone, ChunkSize);
return iReturn;
}
......@@ -760,34 +760,34 @@ static int ced_stage_chunk(DEVICE_EXTENSION *pdx)
** 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)
{
/* 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? */
dev_err(&pdx->interface->dev, "%s: can't accept requests\n",
if (!can_accept_io_requests(ced)) { /* Are we in a state to accept new requests? */
dev_err(&ced->interface->dev, "%s: can't accept requests\n",
__func__);
return U14ERR_FAIL;
}
dev_dbg(&pdx->interface->dev,
dev_dbg(&ced->interface->dev,
"%s: xfer %d bytes to %s, offset %d, area %d\n",
__func__, dwLen, Read ? "host" : "1401", dwOffs, wIdent);
/* 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. */
if (pdx->bStagedUrbPending) {
pdx->bXFerWaiting = true; /* Flag we are waiting */
dev_info(&pdx->interface->dev,
if (ced->bStagedUrbPending) {
ced->bXFerWaiting = true; /* Flag we are waiting */
dev_info(&ced->interface->dev,
"%s: xfer is waiting, as previous staged pending\n",
__func__);
return U14ERR_NOERROR;
}
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__);
return U14ERR_NOERROR;
}
......@@ -797,7 +797,7 @@ int ced_read_write_mem(DEVICE_EXTENSION *pdx, bool Read, unsigned short wIdent,
/* If so, we sort out offset ourself */
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",
pArea->aBlocks[0].dwSize, pArea->aBlocks[0].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,
}
if (bWait) { /* This transfer will have to wait? */
pdx->bXFerWaiting = true; /* Flag we are waiting */
dev_dbg(&pdx->interface->dev,
ced->bXFerWaiting = true; /* Flag we are waiting */
dev_dbg(&ced->interface->dev,
"%s: xfer waiting for circular buffer space\n",
__func__);
return U14ERR_NOERROR;
}
dev_dbg(&pdx->interface->dev,
dev_dbg(&ced->interface->dev,
"%s: circular xfer, %d bytes starting at %d\n",
__func__, dwLen, dwOffs);
}
/* Save the parameters for the read\write transfer */
pdx->StagedRead = Read; /* Save the parameters for this read */
pdx->StagedId = wIdent; /* ID allows us to get transfer area info */
pdx->StagedOffset = dwOffs; /* The area within the transfer area */
pdx->StagedLength = dwLen;
pdx->StagedDone = 0; /* Initialise the byte count */
pdx->dwDMAFlag = MODE_LINEAR; /* Set DMA mode flag at this point */
pdx->bXFerWaiting = false; /* Clearly not a transfer waiting now */
ced->StagedRead = Read; /* Save the parameters for this read */
ced->StagedId = wIdent; /* ID allows us to get transfer area info */
ced->StagedOffset = dwOffs; /* The area within the transfer area */
ced->StagedLength = dwLen;
ced->StagedDone = 0; /* Initialise the byte count */
ced->dwDMAFlag = MODE_LINEAR; /* Set DMA mode flag at this point */
ced->bXFerWaiting = false; /* Clearly not a transfer waiting now */
/* KeClearEvent(&pdx->StagingDoneEvent); // Clear the transfer done event */
ced_stage_chunk(pdx); /* fire off the first chunk */
/* KeClearEvent(&ced->StagingDoneEvent); // Clear the transfer done event */
ced_stage_chunk(ced); /* fire off the first chunk */
return U14ERR_NOERROR;
}
......@@ -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,
DEVICE_EXTENSION *pdx,
struct ced_data *ced,
char *pBuf, unsigned int dwCount)
{
bool bResult = false; /* assume we won't succeed */
unsigned char ucData;
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)) {
unsigned char ucTransCode = (ucData & 0x0F); /* get code for transfer type */
......@@ -964,7 +964,7 @@ static bool ced_read_dma_info(volatile struct dmadesc *pDmaDesc,
pDmaDesc->dwSize = 0; /* initialise other bits */
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);
pDmaDesc->bOutWard = (ucTransCode != TM_EXTTOHOST); /* set transfer direction */
......@@ -979,27 +979,27 @@ static bool ced_read_dma_info(volatile struct dmadesc *pDmaDesc,
&& ced_read_huff(&(pDmaDesc->dwSize), pBuf,
&dDone, dwCount);
if (bResult) {
dev_dbg(&pdx->interface->dev,
dev_dbg(&ced->interface->dev,
"%s: xfer offset & size %d %d\n",
__func__, pDmaDesc->dwOffset,
pDmaDesc->dwSize);
if ((wIdent >= MAX_TRANSAREAS) || /* Illegal area number, or... */
(!pdx->rTransDef[wIdent].bUsed) || /* area not set up, or... */
(pDmaDesc->dwOffset > pdx->rTransDef[wIdent].dwLength) || /* range/size */
(!ced->rTransDef[wIdent].bUsed) || /* area not set up, or... */
(pDmaDesc->dwOffset > ced->rTransDef[wIdent].dwLength) || /* range/size */
((pDmaDesc->dwOffset +
pDmaDesc->dwSize) >
(pdx->rTransDef[wIdent].
(ced->rTransDef[wIdent].
dwLength))) {
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",
__func__, wIdent,
pdx->rTransDef[wIdent].
ced->rTransDef[wIdent].
bUsed,
pDmaDesc->dwOffset,
pDmaDesc->dwSize,
pdx->rTransDef[wIdent].
ced->rTransDef[wIdent].
dwLength);
}
}
......@@ -1012,7 +1012,7 @@ static bool ced_read_dma_info(volatile struct dmadesc *pDmaDesc,
bResult = false;
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__);
return bResult;
......@@ -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.
**
****************************************************************************/
static int ced_handle_esc(DEVICE_EXTENSION *pdx, char *pCh,
static int ced_handle_esc(struct ced_data *ced, char *pCh,
unsigned int dwCount)
{
int iReturn = U14ERR_FAIL;
......@@ -1043,48 +1043,48 @@ static int ced_handle_esc(DEVICE_EXTENSION *pdx, char *pCh,
if (pCh[0] == '?') { /* Is this an information response */
/* Parse and save the information */
} 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 */
unsigned short wTransType = pdx->rDMAInfo.wTransType; /* check transfer type */
if (ced_read_dma_info(&ced->rDMAInfo, ced, pCh, dwCount)) { /* Get DMA parameters */
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",
__func__,
pdx->rDMAInfo.bOutWard ? "1401" : "host",
pdx->rDMAInfo.dwOffset, pdx->rDMAInfo.dwSize);
ced->rDMAInfo.bOutWard ? "1401" : "host",
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 */
dev_err(&pdx->interface->dev,
dev_err(&ced->interface->dev,
"ERROR: DMA setup while transfer still waiting\n");
} else {
if ((wTransType == TM_EXTTOHOST)
|| (wTransType == TM_EXTTO1401)) {
iReturn =
ced_read_write_mem(pdx,
!pdx->rDMAInfo.
ced_read_write_mem(ced,
!ced->rDMAInfo.
bOutWard,
pdx->rDMAInfo.wIdent,
pdx->rDMAInfo.dwOffset,
pdx->rDMAInfo.dwSize);
ced->rDMAInfo.wIdent,
ced->rDMAInfo.dwOffset,
ced->rDMAInfo.dwSize);
if (iReturn != U14ERR_NOERROR)
dev_err(&pdx->interface->dev,
dev_err(&ced->interface->dev,
"%s: ced_read_write_mem() failed %d\n",
__func__, iReturn);
} else /* This covers non-linear transfer setup */
dev_err(&pdx->interface->dev,
dev_err(&ced->interface->dev,
"%s: Unknown block xfer type %d\n",
__func__, wTransType);
}
} 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__);
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;
}
......@@ -1094,65 +1094,65 @@ static int ced_handle_esc(DEVICE_EXTENSION *pdx, char *pCh,
****************************************************************************/
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 */
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 */
if (!
(pUrb->status == -ENOENT || pUrb->status == -ECONNRESET
|| pUrb->status == -ESHUTDOWN)) {
dev_err(&pdx->interface->dev,
dev_err(&ced->interface->dev,
"%s: nonzero write bulk status received: %d\n",
__func__, pUrb->status);
} else
dev_dbg(&pdx->interface->dev,
dev_dbg(&ced->interface->dev,
"%s: 0 chars pUrb->status=%d (shutdown?)\n",
__func__, pUrb->status);
spin_lock(&pdx->err_lock);
pdx->errors = pUrb->status;
spin_unlock(&pdx->err_lock);
spin_lock(&ced->err_lock);
ced->errors = pUrb->status;
spin_unlock(&ced->err_lock);
nGot = 0; /* and tidy up again if so */
spin_lock(&pdx->charInLock); /* already at irq level */
pdx->bPipeError[nPipe] = 1; /* Flag an error for later */
spin_lock(&ced->charInLock); /* already at irq level */
ced->bPipeError[nPipe] = 1; /* Flag an error for later */
} else {
if ((nGot > 1) && ((pdx->pCoherCharIn[0] & 0x7f) == 0x1b)) { /* Esc sequence? */
ced_handle_esc(pdx, &pdx->pCoherCharIn[1], nGot - 1); /* handle it */
spin_lock(&pdx->charInLock); /* already at irq level */
if ((nGot > 1) && ((ced->pCoherCharIn[0] & 0x7f) == 0x1b)) { /* Esc sequence? */
ced_handle_esc(ced, &ced->pCoherCharIn[1], nGot - 1); /* handle it */
spin_lock(&ced->charInLock); /* already at irq level */
} else {
spin_lock(&pdx->charInLock); /* already at irq level */
spin_lock(&ced->charInLock); /* already at irq level */
if (nGot > 0) {
unsigned int i;
if (nGot < INBUF_SZ) {
pdx->pCoherCharIn[nGot] = 0; /* tidy the string */
dev_dbg(&pdx->interface->dev,
ced->pCoherCharIn[nGot] = 0; /* tidy the string */
dev_dbg(&ced->interface->dev,
"%s: got %d chars >%s<\n",
__func__, nGot,
pdx->pCoherCharIn);
ced->pCoherCharIn);
}
/* We know that whatever we read must fit in the input buffer */
for (i = 0; i < nGot; i++) {
pdx->inputBuffer[pdx->dwInBuffPut++] =
pdx->pCoherCharIn[i] & 0x7F;
if (pdx->dwInBuffPut >= INBUF_SZ)
pdx->dwInBuffPut = 0;
ced->inputBuffer[ced->dwInBuffPut++] =
ced->pCoherCharIn[i] & 0x7F;
if (ced->dwInBuffPut >= INBUF_SZ)
ced->dwInBuffPut = 0;
}
if ((pdx->dwNumInput + nGot) <= INBUF_SZ)
pdx->dwNumInput += nGot; /* Adjust the buffer count accordingly */
if ((ced->dwNumInput + nGot) <= INBUF_SZ)
ced->dwNumInput += nGot; /* Adjust the buffer count accordingly */
} else
dev_dbg(&pdx->interface->dev, "%s: read ZLP\n",
dev_dbg(&ced->interface->dev, "%s: read ZLP\n",
__func__);
}
}
pdx->bReadCharsPending = false; /* No longer have a pending read */
spin_unlock(&pdx->charInLock); /* already at irq level */
ced->bReadCharsPending = false; /* No longer have a pending read */
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)
** we can pick up any inward transfers. This can be called in multiple contexts
** 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;
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 */
/* 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 */
/* is no actual driver failure, so we don't allow this at all. */
if (!pdx->bInDrawDown && /* stop input if */
!pdx->bReadCharsPending && /* If no read request outstanding */
(pdx->dwNumInput < (INBUF_SZ / 2)) && /* and there is some space */
(pdx->dwDMAFlag == MODE_CHAR) && /* not doing any DMA */
(!pdx->bXFerWaiting) && /* no xfer waiting to start */
(can_accept_io_requests(pdx))) { /* and activity is generally OK */
if (!ced->bInDrawDown && /* stop input if */
!ced->bReadCharsPending && /* If no read request outstanding */
(ced->dwNumInput < (INBUF_SZ / 2)) && /* and there is some space */
(ced->dwDMAFlag == MODE_CHAR) && /* not doing any DMA */
(!ced->bXFerWaiting) && /* no xfer waiting to start */
(can_accept_io_requests(ced))) { /* and activity is generally OK */
/* then off we go */
unsigned int nMax = INBUF_SZ - pdx->dwNumInput; /* max we could read */
int nPipe = pdx->nPipes == 4 ? 1 : 0; /* The pipe number to use */
dev_dbg(&pdx->interface->dev, "%s: %d chars in input buffer\n",
__func__, pdx->dwNumInput);
usb_fill_int_urb(pdx->pUrbCharIn, pdx->udev,
usb_rcvintpipe(pdx->udev, pdx->epAddr[nPipe]),
pdx->pCoherCharIn, nMax, ced_readchar_callback,
pdx, pdx->bInterval);
pdx->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 */
iReturn = usb_submit_urb(pdx->pUrbCharIn, GFP_ATOMIC);
unsigned int nMax = INBUF_SZ - ced->dwNumInput; /* max we could read */
int nPipe = ced->nPipes == 4 ? 1 : 0; /* The pipe number to use */
dev_dbg(&ced->interface->dev, "%s: %d chars in input buffer\n",
__func__, ced->dwNumInput);
usb_fill_int_urb(ced->pUrbCharIn, ced->udev,
usb_rcvintpipe(ced->udev, ced->epAddr[nPipe]),
ced->pCoherCharIn, nMax, ced_readchar_callback,
ced, ced->bInterval);
ced->pUrbCharIn->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* short xfers are OK by default */
usb_anchor_urb(ced->pUrbCharIn, &ced->submitted); /* in case we need to kill it */
iReturn = usb_submit_urb(ced->pUrbCharIn, GFP_ATOMIC);
if (iReturn) {
usb_unanchor_urb(pdx->pUrbCharIn); /* remove from list of active Urbs */
pdx->bPipeError[nPipe] = 1; /* Flag an error to be handled later */
dev_err(&pdx->interface->dev,
usb_unanchor_urb(ced->pUrbCharIn); /* remove from list of active Urbs */
ced->bPipeError[nPipe] = 1; /* Flag an error to be handled later */
dev_err(&ced->interface->dev,
"%s: submit urb failed: %d\n",
__func__, iReturn);
} 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;
......@@ -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.
** 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
** enough for a 64-bit pointer.
*****************************************************************************/
static long ced_ioctl(struct file *file, unsigned int cmd, unsigned long ulArg)
{
int err = 0;
DEVICE_EXTENSION *pdx = file->private_data;
if (!can_accept_io_requests(pdx)) /* check we still exist */
struct ced_data *ced = file->private_data;
if (!can_accept_io_requests(ced)) /* check we still exist */
return -ENODEV;
/* 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)
switch (_IOC_NR(cmd)) {
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));
case _IOC_NR(IOCTL_CED_RESET1401):
return ced_reset(pdx);
return ced_reset(ced);
case _IOC_NR(IOCTL_CED_GETCHAR):
return ced_get_char(pdx);
return ced_get_char(ced);
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):
return ced_stat_1401(pdx);
return ced_stat_1401(ced);
case _IOC_NR(IOCTL_CED_LINECOUNT):
return ced_line_count(pdx);
return ced_line_count(ced);
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):
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):
return ced_unset_transfer(pdx, (int)ulArg);
return ced_unset_transfer(ced, (int)ulArg);
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):
return ced_get_out_buf_space(pdx);
return ced_get_out_buf_space(ced);
case _IOC_NR(IOCTL_CED_GETBASEADDRESS):
return -1;
......@@ -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 */
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):
return ced_kill_io(pdx);
return ced_kill_io(ced);
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_FREE1401):
return U14ERR_NOERROR;
case _IOC_NR(IOCTL_CED_STARTSELFTEST):
return ced_start_self_test(pdx);
return ced_start_self_test(ced);
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):
return ced_type_of_1401(pdx);
return ced_type_of_1401(ced);
case _IOC_NR(IOCTL_CED_TRANSFERFLAGS):
return ced_transfer_flags(pdx);
return ced_transfer_flags(ced);
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):
return ced_dbg_poke(pdx, (TDBGBLOCK __user *) ulArg);
return ced_dbg_poke(ced, (TDBGBLOCK __user *) ulArg);
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):
return ced_dbg_ramp_addr(pdx, (TDBGBLOCK __user *) ulArg);
return ced_dbg_ramp_addr(ced, (TDBGBLOCK __user *) ulArg);
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):
return ced_dbg_stop_loop(pdx);
return ced_dbg_stop_loop(ced);
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;
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):
return ced_get_circ_block(pdx, (TCIRCBLOCK __user *) ulArg);
return ced_get_circ_block(ced, (TCIRCBLOCK __user *) ulArg);
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):
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):
return ced_test_event(pdx, (int)ulArg);
return ced_test_event(ced, (int)ulArg);
default:
return U14ERR_NO_SUCH_FN;
......@@ -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 */
/* initialise our DEVICE_EXTENSION. */
/* initialise our struct ced_data. */
static int ced_probe(struct usb_interface *interface,
const struct usb_device_id *id)
{
DEVICE_EXTENSION *pdx;
struct ced_data *ced;
struct usb_host_interface *iface_desc;
struct usb_endpoint_descriptor *endpoint;
int i, bcdDevice;
int retval = -ENOMEM;
/* allocate memory for our device extension and initialize it */
pdx = kzalloc(sizeof(*pdx), GFP_KERNEL);
if (!pdx)
ced = kzalloc(sizeof(*ced), GFP_KERNEL);
if (!ced)
goto error;
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. */
spin_lock_init(&pdx->charOutLock);
spin_lock_init(&pdx->charInLock);
spin_lock_init(&pdx->stagedLock);
spin_lock_init(&ced->charOutLock);
spin_lock_init(&ced->charInLock);
spin_lock_init(&ced->stagedLock);
/* Initialises from the skeleton stuff */
kref_init(&pdx->kref);
mutex_init(&pdx->io_mutex);
spin_lock_init(&pdx->err_lock);
init_usb_anchor(&pdx->submitted);
kref_init(&ced->kref);
mutex_init(&ced->io_mutex);
spin_lock_init(&ced->err_lock);
init_usb_anchor(&ced->submitted);
pdx->udev = usb_get_dev(interface_to_usbdev(interface));
pdx->interface = interface;
ced->udev = usb_get_dev(interface_to_usbdev(interface));
ced->interface = interface;
/* Attempt to identify the device */
bcdDevice = pdx->udev->descriptor.bcdDevice;
bcdDevice = ced->udev->descriptor.bcdDevice;
i = (bcdDevice >> 8);
if (i == 0)
pdx->s1401Type = TYPEU1401;
ced->s1401Type = TYPEU1401;
else if ((i >= 1) && (i <= 23))
pdx->s1401Type = i + 2;
ced->s1401Type = i + 2;
else {
dev_err(&interface->dev, "%s: Unknown device. bcdDevice = %d\n",
__func__, bcdDevice);
......@@ -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 */
/* we know that we are dealing with a 1401 device. */
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",
pdx->s1401Type, pdx->nPipes);
if ((pdx->nPipes < 3) || (pdx->nPipes > 4))
ced->s1401Type, ced->nPipes);
if ((ced->nPipes < 3) || (ced->nPipes > 4))
goto error;
/* Allocate the URBs we hold for performing transfers */
pdx->pUrbCharOut = usb_alloc_urb(0, GFP_KERNEL); /* character output URB */
pdx->pUrbCharIn = usb_alloc_urb(0, GFP_KERNEL); /* character input URB */
pdx->pStagedUrb = usb_alloc_urb(0, GFP_KERNEL); /* block transfer URB */
if (!pdx->pUrbCharOut || !pdx->pUrbCharIn || !pdx->pStagedUrb) {
ced->pUrbCharOut = usb_alloc_urb(0, GFP_KERNEL); /* character output URB */
ced->pUrbCharIn = usb_alloc_urb(0, GFP_KERNEL); /* character input URB */
ced->pStagedUrb = usb_alloc_urb(0, GFP_KERNEL); /* block transfer URB */
if (!ced->pUrbCharOut || !ced->pUrbCharIn || !ced->pStagedUrb) {
dev_err(&interface->dev, "%s: URB alloc failed\n", __func__);
goto error;
}
pdx->pCoherStagedIO =
usb_alloc_coherent(pdx->udev, STAGED_SZ, GFP_KERNEL,
&pdx->pStagedUrb->transfer_dma);
pdx->pCoherCharOut =
usb_alloc_coherent(pdx->udev, OUTBUF_SZ, GFP_KERNEL,
&pdx->pUrbCharOut->transfer_dma);
pdx->pCoherCharIn =
usb_alloc_coherent(pdx->udev, INBUF_SZ, GFP_KERNEL,
&pdx->pUrbCharIn->transfer_dma);
if (!pdx->pCoherCharOut || !pdx->pCoherCharIn || !pdx->pCoherStagedIO) {
ced->pCoherStagedIO =
usb_alloc_coherent(ced->udev, STAGED_SZ, GFP_KERNEL,
&ced->pStagedUrb->transfer_dma);
ced->pCoherCharOut =
usb_alloc_coherent(ced->udev, OUTBUF_SZ, GFP_KERNEL,
&ced->pUrbCharOut->transfer_dma);
ced->pCoherCharIn =
usb_alloc_coherent(ced->udev, INBUF_SZ, GFP_KERNEL,
&ced->pUrbCharIn->transfer_dma);
if (!ced->pCoherCharOut || !ced->pCoherCharIn || !ced->pCoherStagedIO) {
dev_err(&interface->dev, "%s: Coherent buffer alloc failed\n",
__func__);
goto error;
}
for (i = 0; i < pdx->nPipes; ++i) {
for (i = 0; i < ced->nPipes; ++i) {
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",
i, pdx->epAddr[i]);
if (((pdx->nPipes == 3) && (i == 0)) || /* if char input end point */
((pdx->nPipes == 4) && (i == 1))) {
pdx->bInterval = endpoint->bInterval; /* save the endpoint interrupt interval */
i, ced->epAddr[i]);
if (((ced->nPipes == 3) && (i == 0)) || /* if char input end point */
((ced->nPipes == 4) && (i == 1))) {
ced->bInterval = endpoint->bInterval; /* save the endpoint interrupt interval */
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) */
if (i == pdx->nPipes - 1) { /* if this is the last ep (bulk) */
pdx->bIsUSB2 =
if (i == ced->nPipes - 1) { /* if this is the last ep (bulk) */
ced->bIsUSB2 =
le16_to_cpu(endpoint->wMaxPacketSize) > 64;
dev_info(&pdx->interface->dev, "USB%d\n",
pdx->bIsUSB2 + 1);
dev_info(&ced->interface->dev, "USB%d\n",
ced->bIsUSB2 + 1);
}
}
/* 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 */
retval = usb_register_dev(interface, &ced_class);
......@@ -1479,34 +1479,34 @@ static int ced_probe(struct usb_interface *interface,
return 0;
error:
if (pdx)
kref_put(&pdx->kref, ced_delete); /* frees allocated memory */
if (ced)
kref_put(&ced->kref, ced_delete); /* frees allocated memory */
return retval;
}
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 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 */
mutex_lock(&pdx->io_mutex); /* stop more I/O starting while... */
ced_draw_down(pdx); /* ...wait for then kill any io */
mutex_lock(&ced->io_mutex); /* stop more I/O starting while... */
ced_draw_down(ced); /* ...wait for then kill any io */
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)
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);
}
pdx->interface = NULL; /* ...we kill off link to interface */
mutex_unlock(&pdx->io_mutex);
ced->interface = NULL; /* ...we kill off link to interface */
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);
}
......@@ -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 */
/* from trying to fire off more urbs. We will wait up to 3 seconds for Urbs */
/* to be done. */
void ced_draw_down(DEVICE_EXTENSION *pdx)
void ced_draw_down(struct ced_data *ced)
{
int time;
dev_dbg(&pdx->interface->dev, "%s: called\n", __func__);
dev_dbg(&ced->interface->dev, "%s: called\n", __func__);
pdx->bInDrawDown = true;
time = usb_wait_anchor_empty_timeout(&pdx->submitted, 3000);
ced->bInDrawDown = true;
time = usb_wait_anchor_empty_timeout(&ced->submitted, 3000);
if (!time) { /* if we timed out we kill the urbs */
usb_kill_anchored_urbs(&pdx->submitted);
dev_err(&pdx->interface->dev, "%s: timed out\n", __func__);
usb_kill_anchored_urbs(&ced->submitted);
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)
{
DEVICE_EXTENSION *pdx = usb_get_intfdata(intf);
if (!pdx)
struct ced_data *ced = usb_get_intfdata(intf);
if (!ced)
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;
}
static int ced_resume(struct usb_interface *intf)
{
DEVICE_EXTENSION *pdx = usb_get_intfdata(intf);
if (!pdx)
struct ced_data *ced = usb_get_intfdata(intf);
if (!ced)
return 0;
dev_dbg(&pdx->interface->dev, "%s: called\n", __func__);
dev_dbg(&ced->interface->dev, "%s: called\n", __func__);
return 0;
}
static int ced_pre_reset(struct usb_interface *intf)
{
DEVICE_EXTENSION *pdx = usb_get_intfdata(intf);
dev_dbg(&pdx->interface->dev, "%s\n", __func__);
mutex_lock(&pdx->io_mutex);
ced_draw_down(pdx);
struct ced_data *ced = usb_get_intfdata(intf);
dev_dbg(&ced->interface->dev, "%s\n", __func__);
mutex_lock(&ced->io_mutex);
ced_draw_down(ced);
return 0;
}
static int ced_post_reset(struct usb_interface *intf)
{
DEVICE_EXTENSION *pdx = usb_get_intfdata(intf);
dev_dbg(&pdx->interface->dev, "%s\n", __func__);
struct ced_data *ced = usb_get_intfdata(intf);
dev_dbg(&ced->interface->dev, "%s\n", __func__);
/* we are sure no URBs are active - no locking needed */
pdx->errors = -EPIPE;
mutex_unlock(&pdx->io_mutex);
ced->errors = -EPIPE;
mutex_unlock(&ced->io_mutex);
return 0;
}
......
......@@ -134,7 +134,7 @@ struct dmadesc {
/* 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. */
typedef struct _DEVICE_EXTENSION {
struct ced_data {
char inputBuffer[INBUF_SZ]; /* The two buffers */
char outputBuffer[OUTBUF_SZ]; /* accessed by the host functions */
volatile unsigned int dwNumInput; /* num of chars in input buffer */
......@@ -197,48 +197,49 @@ typedef struct _DEVICE_EXTENSION {
int open_count; /* count the number of openers */
spinlock_t err_lock; /* lock for errors */
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 */
/* in usb1401.c */
extern int ced_allowi(DEVICE_EXTENSION *pdx);
extern int ced_send_chars(DEVICE_EXTENSION *pdx);
extern void ced_draw_down(DEVICE_EXTENSION *pdx);
extern int ced_read_write_mem(DEVICE_EXTENSION *pdx, bool Read, unsigned short wIdent,
extern int ced_allowi(struct ced_data * ced);
extern int ced_send_chars(struct ced_data *ced);
extern void ced_draw_down(struct ced_data *ced);
extern int ced_read_write_mem(struct ced_data *ced, bool Read, unsigned short wIdent,
unsigned int dwOffs, unsigned int dwLen);
/* in ced_ioc.c */
extern int ced_clear_area(DEVICE_EXTENSION *pdx, int nArea);
extern int ced_send_string(DEVICE_EXTENSION *pdx, const char __user *pData, unsigned int n);
extern int ced_send_char(DEVICE_EXTENSION *pdx, char c);
extern int ced_get_state(DEVICE_EXTENSION *pdx, __u32 *state, __u32 *error);
extern int ced_read_write_cancel(DEVICE_EXTENSION *pdx);
extern int ced_reset(DEVICE_EXTENSION *pdx);
extern int ced_get_char(DEVICE_EXTENSION *pdx);
extern int ced_get_string(DEVICE_EXTENSION *pdx, char __user *pUser, int n);
extern int ced_set_transfer(DEVICE_EXTENSION *pdx, struct transfer_area_desc __user *pTD);
extern int ced_unset_transfer(DEVICE_EXTENSION *pdx, int nArea);
extern int ced_set_event(DEVICE_EXTENSION *pdx, struct transfer_event __user *pTE);
extern int ced_stat_1401(DEVICE_EXTENSION *pdx);
extern int ced_line_count(DEVICE_EXTENSION *pdx);
extern int ced_get_out_buf_space(DEVICE_EXTENSION *pdx);
extern int ced_get_transfer(DEVICE_EXTENSION *pdx, TGET_TX_BLOCK __user *pGTB);
extern int ced_kill_io(DEVICE_EXTENSION *pdx);
extern int ced_state_of_1401(DEVICE_EXTENSION *pdx);
extern int ced_start_self_test(DEVICE_EXTENSION *pdx);
extern int ced_check_self_test(DEVICE_EXTENSION *pdx, TGET_SELFTEST __user *pGST);
extern int ced_type_of_1401(DEVICE_EXTENSION *pdx);
extern int ced_transfer_flags(DEVICE_EXTENSION *pdx);
extern int ced_dbg_peek(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB);
extern int ced_dbg_poke(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB);
extern int ced_dbg_ramp_data(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB);
extern int ced_dbg_ramp_addr(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB);
extern int ced_dbg_get_data(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB);
extern int ced_dbg_stop_loop(DEVICE_EXTENSION *pdx);
extern int ced_set_circular(DEVICE_EXTENSION *pdx, struct transfer_area_desc __user *pTD);
extern int ced_get_circ_block(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB);
extern int ced_free_circ_block(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB);
extern int ced_wait_event(DEVICE_EXTENSION *pdx, int nArea, int msTimeOut);
extern int ced_test_event(DEVICE_EXTENSION *pdx, int nArea);
extern int ced_clear_area(struct ced_data *ced, int nArea);
extern int ced_send_string(struct ced_data *ced, const char __user *pData, unsigned int n);
extern int ced_send_char(struct ced_data *ced, char c);
extern int ced_get_state(struct ced_data *ced, __u32 *state, __u32 *error);
extern int ced_read_write_cancel(struct ced_data *ced);
extern int ced_reset(struct ced_data *ced);
extern int ced_get_char(struct ced_data *ced);
extern int ced_get_string(struct ced_data *ced, char __user *pUser, int n);
extern int ced_set_transfer(struct ced_data *ced, struct transfer_area_desc __user *pTD);
extern int ced_unset_transfer(struct ced_data *ced, int nArea);
extern int ced_set_event(struct ced_data *ced, struct transfer_event __user *pTE);
extern int ced_stat_1401(struct ced_data *ced);
extern int ced_line_count(struct ced_data *ced);
extern int ced_get_out_buf_space(struct ced_data *ced);
extern int ced_get_transfer(struct ced_data *ced, TGET_TX_BLOCK __user *pGTB);
extern int ced_kill_io(struct ced_data *ced);
extern int ced_state_of_1401(struct ced_data *ced);
extern int ced_start_self_test(struct ced_data *ced);
extern int ced_check_self_test(struct ced_data *ced, TGET_SELFTEST __user *pGST);
extern int ced_type_of_1401(struct ced_data *ced);
extern int ced_transfer_flags(struct ced_data *ced);
extern int ced_dbg_peek(struct ced_data *ced, TDBGBLOCK __user *pDB);
extern int ced_dbg_poke(struct ced_data *ced, TDBGBLOCK __user *pDB);
extern int ced_dbg_ramp_data(struct ced_data *ced, TDBGBLOCK __user *pDB);
extern int ced_dbg_ramp_addr(struct ced_data *ced, TDBGBLOCK __user *pDB);
extern int ced_dbg_get_data(struct ced_data *ced, TDBGBLOCK __user *pDB);
extern int ced_dbg_stop_loop(struct ced_data *ced);
extern int ced_set_circular(struct ced_data *ced, struct transfer_area_desc __user *pTD);
extern int ced_get_circ_block(struct ced_data *ced, TCIRCBLOCK __user *pCB);
extern int ced_free_circ_block(struct ced_data *ced, TCIRCBLOCK __user *pCB);
extern int ced_wait_event(struct ced_data *ced, int nArea, int msTimeOut);
extern int ced_test_event(struct ced_data *ced, int nArea);
#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