Commit 2206c3be authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

USB: fix the usb misc drivers due to interrupt urb no automatic resubmission...

USB: fix the usb misc drivers due to interrupt urb no automatic resubmission change to the usb core.
parent 3d98867e
...@@ -1014,30 +1014,39 @@ static void auerswald_int_complete (struct urb * urb) ...@@ -1014,30 +1014,39 @@ static void auerswald_int_complete (struct urb * urb)
pauerbuf_t bp = NULL; pauerbuf_t bp = NULL;
pauerswald_t cp = (pauerswald_t) urb->context; pauerswald_t cp = (pauerswald_t) urb->context;
dbg ("auerswald_int_complete called"); dbg ("%s called", __FUNCTION__);
/* do not respond to an error condition */ switch (urb->status) {
if (urb->status != 0) { case 0:
dbg ("nonzero URB status = %d", urb->status); /* success */
return; break;
} case -ECONNRESET:
case -ENOENT:
case -ESHUTDOWN:
/* this urb is terminated, clean up */
dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
return;
default:
dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
goto exit;
}
/* check if all needed data was received */ /* check if all needed data was received */
if (urb->actual_length < AU_IRQMINSIZE) { if (urb->actual_length < AU_IRQMINSIZE) {
dbg ("invalid data length received: %d bytes", urb->actual_length); dbg ("invalid data length received: %d bytes", urb->actual_length);
return; goto exit;
} }
/* check the command code */ /* check the command code */
if (cp->intbufp[0] != AU_IRQCMDID) { if (cp->intbufp[0] != AU_IRQCMDID) {
dbg ("invalid command received: %d", cp->intbufp[0]); dbg ("invalid command received: %d", cp->intbufp[0]);
return; goto exit;
} }
/* check the command type */ /* check the command type */
if (cp->intbufp[1] != AU_BLOCKRDY) { if (cp->intbufp[1] != AU_BLOCKRDY) {
dbg ("invalid command type received: %d", cp->intbufp[1]); dbg ("invalid command type received: %d", cp->intbufp[1]);
return; goto exit;
} }
/* now extract the information */ /* now extract the information */
...@@ -1047,13 +1056,13 @@ static void auerswald_int_complete (struct urb * urb) ...@@ -1047,13 +1056,13 @@ static void auerswald_int_complete (struct urb * urb)
/* check the channel id */ /* check the channel id */
if (channelid >= AUH_TYPESIZE) { if (channelid >= AUH_TYPESIZE) {
dbg ("invalid channel id received: %d", channelid); dbg ("invalid channel id received: %d", channelid);
return; goto exit;
} }
/* check the byte count */ /* check the byte count */
if (bytecount > (cp->maxControlLength+AUH_SIZE)) { if (bytecount > (cp->maxControlLength+AUH_SIZE)) {
dbg ("invalid byte count received: %d", bytecount); dbg ("invalid byte count received: %d", bytecount);
return; goto exit;
} }
dbg ("Service Channel = %d", channelid); dbg ("Service Channel = %d", channelid);
dbg ("Byte Count = %d", bytecount); dbg ("Byte Count = %d", bytecount);
...@@ -1077,7 +1086,7 @@ static void auerswald_int_complete (struct urb * urb) ...@@ -1077,7 +1086,7 @@ static void auerswald_int_complete (struct urb * urb)
The only real solution is: having enought buffers! The only real solution is: having enought buffers!
Or perhaps temporary disabling the int endpoint? Or perhaps temporary disabling the int endpoint?
*/ */
return; goto exit;
} }
/* fill the control message */ /* fill the control message */
...@@ -1098,6 +1107,11 @@ static void auerswald_int_complete (struct urb * urb) ...@@ -1098,6 +1107,11 @@ static void auerswald_int_complete (struct urb * urb)
auerswald_ctrlread_complete( bp->urbp); auerswald_ctrlread_complete( bp->urbp);
/* here applies the same problem as above: device locking! */ /* here applies the same problem as above: device locking! */
} }
exit:
ret = usb_submit_urb (urb, GFP_ATOMIC);
if (ret)
err ("%s - usb_submit_urb failed with result %d",
__FUNCTION__, ret);
} }
/* int memory deallocation /* int memory deallocation
......
...@@ -846,14 +846,21 @@ intr_callback(struct urb *urb) ...@@ -846,14 +846,21 @@ intr_callback(struct urb *urb)
{ {
struct brlvger_priv *priv = urb->context; struct brlvger_priv *priv = urb->context;
int intr_idx, read_idx; int intr_idx, read_idx;
int status;
if( urb->status ) { switch (urb->status) {
if(urb->status == -ETIMEDOUT) case 0:
dbg2("Status -ETIMEDOUT, " /* success */
"probably disconnected"); break;
else if(urb->status != -ENOENT) case -ECONNRESET:
err("Status: %d", urb->status); case -ENOENT:
case -ESHUTDOWN:
/* this urb is terminated, clean up */
dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
return; return;
default:
dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
goto exit;
} }
read_idx = atomic_read(&priv->read_idx); read_idx = atomic_read(&priv->read_idx);
...@@ -862,7 +869,7 @@ intr_callback(struct urb *urb) ...@@ -862,7 +869,7 @@ intr_callback(struct urb *urb)
if(read_idx == intr_idx) { if(read_idx == intr_idx) {
dbg2("Queue full, dropping braille display input"); dbg2("Queue full, dropping braille display input");
spin_unlock(&priv->intr_idx_lock); spin_unlock(&priv->intr_idx_lock);
return; /* queue full */ goto exit; /* queue full */
} }
memcpy(priv->event_queue[intr_idx], urb->transfer_buffer, memcpy(priv->event_queue[intr_idx], urb->transfer_buffer,
...@@ -873,6 +880,12 @@ intr_callback(struct urb *urb) ...@@ -873,6 +880,12 @@ intr_callback(struct urb *urb)
spin_unlock(&priv->intr_idx_lock); spin_unlock(&priv->intr_idx_lock);
wake_up_interruptible(&priv->read_wait); wake_up_interruptible(&priv->read_wait);
exit:
status = usb_submit_urb (urb, GFP_ATOMIC);
if (status)
err ("%s - usb_submit_urb failed with result %d",
__FUNCTION__, status);
} }
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
......
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