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

staging: ced1401: fix staged_callback()

Rename camel case arguments and locals in function staged_callback()
Signed-off-by: default avatarLuca Ellero <luca.ellero@brickedbrain.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 3ce341ad
...@@ -511,202 +511,242 @@ static void ced_copy_user_space(struct ced_data *ced, int n) ...@@ -511,202 +511,242 @@ static void ced_copy_user_space(struct ced_data *ced, int n)
/* Forward declarations for stuff used circularly */ /* Forward declarations for stuff used circularly */
static int ced_stage_chunk(struct ced_data *ced); static int ced_stage_chunk(struct ced_data *ced);
/*************************************************************************** /***************************************************************************
** ReadWrite_Complete ** ReadWrite_Complete
** **
** Completion routine for our staged read/write Irps ** Completion routine for our staged read/write Irps
*/ */
static void staged_callback(struct urb *pUrb) static void staged_callback(struct urb *urb)
{ {
struct ced_data *ced = pUrb->context; struct ced_data *ced = urb->context;
unsigned int nGot = pUrb->actual_length; /* what we transferred */ unsigned int got = urb->actual_length; /* what we transferred */
bool bCancel = false; bool cancel = false;
bool bRestartCharInput; /* used at the end */ bool restart_char_input; /* used at the end */
spin_lock(&ced->staged_lock); /* stop ced_read_write_mem() action */ spin_lock(&ced->staged_lock); /* stop ced_read_write_mem() action */
/* while this routine is running */ /* while this routine is running */
ced->staged_urb_pending = false; /* clear the flag for staged IRP pending */
if (pUrb->status) { /* sync/async unlink faults aren't errors */ /* clear the flag for staged IRP pending */
ced->staged_urb_pending = false;
if (urb->status) { /* sync/async unlink faults aren't errors */
if (! if (!
(pUrb->status == -ENOENT || pUrb->status == -ECONNRESET (urb->status == -ENOENT || urb->status == -ECONNRESET
|| pUrb->status == -ESHUTDOWN)) { || urb->status == -ESHUTDOWN)) {
dev_err(&ced->interface->dev, dev_err(&ced->interface->dev,
"%s: nonzero write bulk status received: %d\n", "%s: nonzero write bulk status received: %d\n",
__func__, pUrb->status); __func__, urb->status);
} else } else
dev_info(&ced->interface->dev, dev_info(&ced->interface->dev,
"%s: staged xfer cancelled\n", __func__); "%s: staged xfer cancelled\n", __func__);
spin_lock(&ced->err_lock); spin_lock(&ced->err_lock);
ced->errors = pUrb->status; ced->errors = urb->status;
spin_unlock(&ced->err_lock); spin_unlock(&ced->err_lock);
nGot = 0; /* and tidy up again if so */ got = 0; /* and tidy up again if so */
bCancel = true; cancel = true;
} else { } else {
dev_dbg(&ced->interface->dev, "%s: %d chars xferred\n", dev_dbg(&ced->interface->dev, "%s: %d chars xferred\n",
__func__, nGot); __func__, got);
if (ced->staged_read) /* if reading, save to user space */ if (ced->staged_read) /* if reading, save to user space */
ced_copy_user_space(ced, nGot); /* copy from buffer to user */ /* copy from buffer to user */
if (nGot == 0) ced_copy_user_space(ced, got);
if (got == 0)
dev_dbg(&ced->interface->dev, "%s: ZLP\n", __func__); dev_dbg(&ced->interface->dev, "%s: ZLP\n", __func__);
} }
/* Update the transfer length based on the TransferBufferLength value in the URB */ /* Update the transfer length based on the TransferBufferLength value */
ced->staged_done += nGot; /* in the URB */
ced->staged_done += got;
dev_dbg(&ced->interface->dev, "%s: done %d bytes of %d\n", dev_dbg(&ced->interface->dev, "%s: done %d bytes of %d\n",
__func__, ced->staged_done, ced->staged_length); __func__, ced->staged_done, ced->staged_length);
if ((ced->staged_done == ced->staged_length) || /* If no more to do */ if ((ced->staged_done == ced->staged_length) || /* If no more to do */
(bCancel)) { /* or this IRP was cancelled */ (cancel)) { /* or this IRP was cancelled */
/* Transfer area info */ /* Transfer area info */
struct transarea *pArea = &ced->trans_def[ced->staged_id]; struct transarea *ta = &ced->trans_def[ced->staged_id];
dev_dbg(&ced->interface->dev, dev_dbg(&ced->interface->dev,
"%s: transfer done, bytes %d, cancel %d\n", "%s: transfer done, bytes %d, cancel %d\n",
__func__, ced->staged_done, bCancel); __func__, ced->staged_done, cancel);
/* Here is where we sort out what to do with this transfer if using a circular buffer. We have */ /* Here is where we sort out what to do with this transfer if */
/* a completed transfer that can be assumed to fit into the transfer area. We should be able to */ /* using a circular buffer. We have a completed transfer that */
/* add this to the end of a growing block or to use it to start a new block unless the code */ /* can be assumed to fit into the transfer area. We should be */
/* that calculates the offset to use (in ced_read_write_mem) is totally duff. */ /* able to add this to the end of a growing block or to use */
if ((pArea->circular) && (pArea->circ_to_host) && (!bCancel) && /* Time to sort out circular buffer info? */ /* it to start a new block unless the code that calculates */
/* the offset to use (in ced_read_write_mem) is totally duff. */
if ((ta->circular) &&
(ta->circ_to_host) &&
(!cancel) && /* Time to sort out circular buffer info? */
(ced->staged_read)) {/* Only for tohost transfers for now */ (ced->staged_read)) {/* Only for tohost transfers for now */
if (pArea->blocks[1].size > 0) { /* If block 1 is in use we must append to it */ /* If block 1 is in use we must append to it */
if (ta->blocks[1].size > 0) {
if (ced->staged_offset == if (ced->staged_offset ==
(pArea->blocks[1].offset + (ta->blocks[1].offset +
pArea->blocks[1].size)) { ta->blocks[1].size)) {
pArea->blocks[1].size += ta->blocks[1].size +=
ced->staged_length; ced->staged_length;
dev_dbg(&ced->interface->dev, dev_dbg(&ced->interface->dev,
"RWM_Complete, circ block 1 now %d bytes at %d\n", "RWM_Complete, circ block 1 "
pArea->blocks[1].size, "now %d bytes at %d\n",
pArea->blocks[1].offset); ta->blocks[1].size,
ta->blocks[1].offset);
} else { } else {
/* Here things have gone very, very, wrong, but I cannot see how this can actually be achieved */ /* Here things have gone very, very */
pArea->blocks[1].offset = /* wrong, but I cannot see how this */
/* can actually be achieved */
ta->blocks[1].offset =
ced->staged_offset; ced->staged_offset;
pArea->blocks[1].size = ta->blocks[1].size =
ced->staged_length; ced->staged_length;
dev_err(&ced->interface->dev, dev_err(&ced->interface->dev,
"%s: ERROR, circ block 1 re-started %d bytes at %d\n", "%s: ERROR, circ block 1 "
"re-started %d bytes at %d\n",
__func__, __func__,
pArea->blocks[1].size, ta->blocks[1].size,
pArea->blocks[1].offset); ta->blocks[1].offset);
} }
} else { /* If block 1 is not used, we try to add to block 0 */ } else { /* If block 1 is not used, we try to add */
if (pArea->blocks[0].size > 0) { /* Got stored block 0 information? */ /*to block 0 */
/* Must append onto the existing block 0 */
/* Got stored block 0 information? */
if (ta->blocks[0].size > 0) {
/* Must append onto the */
/*existing block 0 */
if (ced->staged_offset == if (ced->staged_offset ==
(pArea->blocks[0].offset + (ta->blocks[0].offset +
pArea->blocks[0].size)) { ta->blocks[0].size)) {
pArea->blocks[0].size += ced->staged_length; /* Just add this transfer in */ /* Just add this transfer in */
ta->blocks[0].size +=
ced->staged_length;
dev_dbg(&ced->interface->dev, dev_dbg(&ced->interface->dev,
"RWM_Complete, circ block 0 now %d bytes at %d\n", "RWM_Complete, circ "
pArea->blocks[0]. "block 0 now %d bytes "
size, "at %d\n",
pArea->blocks[0]. ta->blocks[0].size,
offset); ta->blocks[0].offset);
} else { /* If it doesn't append, put into new block 1 */
pArea->blocks[1].offset = } else { /* If it doesn't append, put */
/* into new block 1 */
ta->blocks[1].offset =
ced->staged_offset; ced->staged_offset;
pArea->blocks[1].size = ta->blocks[1].size =
ced->staged_length; ced->staged_length;
dev_dbg(&ced->interface->dev, dev_dbg(&ced->interface->dev,
"RWM_Complete, circ block 1 started %d bytes at %d\n", "RWM_Complete, circ "
pArea->blocks[1]. "block 1 started %d "
size, "bytes at %d\n",
pArea->blocks[1]. ta->blocks[1].size,
offset); ta->blocks[1].offset);
} }
} else { /* No info stored yet, just save in block 0 */ } else { /* No info stored yet, just save */
pArea->blocks[0].offset = /* in block 0 */
ta->blocks[0].offset =
ced->staged_offset; ced->staged_offset;
pArea->blocks[0].size = ta->blocks[0].size =
ced->staged_length; ced->staged_length;
dev_dbg(&ced->interface->dev, dev_dbg(&ced->interface->dev,
"RWM_Complete, circ block 0 started %d bytes at %d\n", "RWM_Complete, circ block 0 "
pArea->blocks[0].size, "started %d bytes at %d\n",
pArea->blocks[0].offset); ta->blocks[0].size,
ta->blocks[0].offset);
} }
} }
} }
if (!bCancel) { /* Don't generate an event if cancelled */ if (!cancel) { /* Don't generate an event if cancelled */
dev_dbg(&ced->interface->dev, dev_dbg(&ced->interface->dev,
"RWM_Complete, bCircular %d, bToHost %d, eStart %d, eSize %d\n", "RWM_Complete, bCircular %d, bToHost %d, "
pArea->circular, pArea->event_to_host, "eStart %d, eSize %d\n",
pArea->event_st, pArea->event_sz); ta->circular, ta->event_to_host,
if ((pArea->event_sz) && /* Set a user-mode event... */ ta->event_st, ta->event_sz);
(ced->staged_read == pArea->event_to_host)) { /* ...on transfers in this direction? */ /* Set a user-mode event... */
int iWakeUp = 0; /* assume */ /* ...on transfers in this direction? */
if ((ta->event_sz) &&
(ced->staged_read == ta->event_to_host)) {
int wakeup = 0; /* assume */
/* If we have completed the right sort of DMA */ /* If we have completed the right sort of DMA */
/* transfer then set the event to notify the */ /* transfer then set the event to notify the */
/* user code to wake up anyone that is */ /* user code to wake up anyone that is */
/* waiting. */ /* waiting. */
if ((pArea->circular) && /* Circular areas use a simpler test */ if ((ta->circular) && /* Circular areas use a simpler test */
(pArea->circ_to_host)) { /* only in supported direction */ (ta->circ_to_host)) { /* only in supported direction */
/* Is total data waiting up to size limit? */ /* Is total data waiting up */
/* to size limit? */
unsigned int dwTotal = unsigned int dwTotal =
pArea->blocks[0].size + ta->blocks[0].size +
pArea->blocks[1].size; ta->blocks[1].size;
iWakeUp = (dwTotal >= pArea->event_sz); wakeup = (dwTotal >= ta->event_sz);
} else { } else {
unsigned int transEnd = unsigned int transEnd =
ced->staged_offset + ced->staged_offset +
ced->staged_length; ced->staged_length;
unsigned int eventEnd = unsigned int eventEnd =
pArea->event_st + pArea->event_sz; ta->event_st + ta->event_sz;
iWakeUp = (ced->staged_offset < eventEnd) wakeup = (ced->staged_offset < eventEnd)
&& (transEnd > pArea->event_st); && (transEnd > ta->event_st);
} }
if (iWakeUp) { if (wakeup) {
dev_dbg(&ced->interface->dev, dev_dbg(&ced->interface->dev,
"About to set event to notify app\n"); "About to set event to notify app\n");
wake_up_interruptible(&pArea->event); /* wake up waiting processes */
++pArea->wake_up; /* increment wakeup count */ /* wake up waiting processes */
wake_up_interruptible(&ta->event);
/* increment wakeup count */
++ta->wake_up;
} }
} }
} }
ced->dma_flag = MODE_CHAR; /* Switch back to char mode before ced_read_write_mem call */ /* Switch back to char mode before ced_read_write_mem call */
ced->dma_flag = MODE_CHAR;
if (!bCancel) { /* Don't look for waiting transfer if cancelled */ /* Don't look for waiting transfer if cancelled */
if (!cancel) {
/* If we have a transfer waiting, kick it off */ /* If we have a transfer waiting, kick it off */
if (ced->xfer_waiting) {/* Got a block xfer waiting? */ if (ced->xfer_waiting) {/* Got a block xfer waiting? */
int iReturn; int retval;
dev_info(&ced->interface->dev, dev_info(&ced->interface->dev,
"*** RWM_Complete *** pending transfer will now be set up!!!\n"); "*** RWM_Complete *** pending transfer"
iReturn = " will now be set up!!!\n");
ced_read_write_mem(ced, !ced->dma_info.outward, retval =
ced_read_write_mem(ced,
!ced->dma_info.outward,
ced->dma_info.ident, ced->dma_info.ident,
ced->dma_info.offset, ced->dma_info.offset,
ced->dma_info.size); ced->dma_info.size);
if (iReturn) if (retval)
dev_err(&ced->interface->dev, dev_err(&ced->interface->dev,
"RWM_Complete rw setup failed %d\n", "RWM_Complete rw setup failed %d\n",
iReturn); retval);
} }
} }
} else /* Here for more to do */ } else /* Here for more to do */
ced_stage_chunk(ced); /* fire off the next bit */ ced_stage_chunk(ced); /* fire off the next bit */
/* While we hold the staged_lock, see if we should reallow character input ints */ /* While we hold the staged_lock, see if we should reallow character */
/* Don't allow if cancelled, or if a new block has started or if there is a waiting block. */ /* input ints */
/* This feels wrong as we should ask which spin lock protects dma_flag. */ /* Don't allow if cancelled, or if a new block has started or if */
bRestartCharInput = !bCancel && (ced->dma_flag == MODE_CHAR) && /* there is a waiting block. */
/* This feels wrong as we should ask which spin lock protects */
/* dma_flag. */
restart_char_input = !cancel && (ced->dma_flag == MODE_CHAR) &&
!ced->xfer_waiting; !ced->xfer_waiting;
spin_unlock(&ced->staged_lock); /* Finally release the lock again */ spin_unlock(&ced->staged_lock); /* Finally release the lock again */
/* This is not correct as dma_flag is protected by the staged lock, but it is treated */ /* This is not correct as dma_flag is protected by the staged lock, */
/* in ced_allowi as if it were protected by the char lock. In any case, most systems will */ /* but it is treated in ced_allowi as if it were protected by the */
/* not be upset by char input during DMA... sigh. Needs sorting out. */ /* char lock. In any case, most systems will not be upset by char */
if (bRestartCharInput) /* may be out of date, but... */ /* input during DMA... sigh. Needs sorting out. */
if (restart_char_input) /* may be out of date, but... */
ced_allowi(ced); /* ...ced_allowi tests a lock too. */ ced_allowi(ced); /* ...ced_allowi tests a lock too. */
dev_dbg(&ced->interface->dev, "%s: done\n", __func__); dev_dbg(&ced->interface->dev, "%s: done\n", __func__);
} }
......
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