Commit b3b774fc authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

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

USB: fix the usb class drivers due to interrupt urb no automatic resubmission change to the usb core
parent d20c58aa
...@@ -767,6 +767,7 @@ static void bluetooth_int_callback (struct urb *urb) ...@@ -767,6 +767,7 @@ static void bluetooth_int_callback (struct urb *urb)
unsigned int i; unsigned int i;
unsigned int count = urb->actual_length; unsigned int count = urb->actual_length;
unsigned int packet_size; unsigned int packet_size;
int status;
dbg("%s", __FUNCTION__); dbg("%s", __FUNCTION__);
...@@ -775,14 +776,24 @@ static void bluetooth_int_callback (struct urb *urb) ...@@ -775,14 +776,24 @@ static void bluetooth_int_callback (struct urb *urb)
return; return;
} }
if (urb->status) { switch (urb->status) {
dbg("%s - nonzero int status received: %d", __FUNCTION__, urb->status); case 0:
/* success */
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; return;
default:
dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
goto exit;
} }
if (!count) { if (!count) {
dbg("%s - zero length int", __FUNCTION__); dbg("%s - zero length int", __FUNCTION__);
return; goto exit;
} }
...@@ -803,7 +814,7 @@ static void bluetooth_int_callback (struct urb *urb) ...@@ -803,7 +814,7 @@ static void bluetooth_int_callback (struct urb *urb)
} }
if (count == 0) { if (count == 0) {
urb->actual_length = 0; urb->actual_length = 0;
return; goto exit;
} }
#endif #endif
/* We add a packet type identifier to the beginning of each /* We add a packet type identifier to the beginning of each
...@@ -820,7 +831,7 @@ static void bluetooth_int_callback (struct urb *urb) ...@@ -820,7 +831,7 @@ static void bluetooth_int_callback (struct urb *urb)
if (bluetooth->int_packet_pos + count > EVENT_BUFFER_SIZE) { if (bluetooth->int_packet_pos + count > EVENT_BUFFER_SIZE) {
err("%s - exceeded EVENT_BUFFER_SIZE", __FUNCTION__); err("%s - exceeded EVENT_BUFFER_SIZE", __FUNCTION__);
bluetooth->int_packet_pos = 0; bluetooth->int_packet_pos = 0;
return; goto exit;
} }
memcpy (&bluetooth->int_buffer[bluetooth->int_packet_pos], memcpy (&bluetooth->int_buffer[bluetooth->int_packet_pos],
...@@ -831,12 +842,12 @@ static void bluetooth_int_callback (struct urb *urb) ...@@ -831,12 +842,12 @@ static void bluetooth_int_callback (struct urb *urb)
if (bluetooth->int_packet_pos >= EVENT_HDR_SIZE) if (bluetooth->int_packet_pos >= EVENT_HDR_SIZE)
packet_size = bluetooth->int_buffer[2]; packet_size = bluetooth->int_buffer[2];
else else
return; goto exit;
if (packet_size + EVENT_HDR_SIZE < bluetooth->int_packet_pos) { if (packet_size + EVENT_HDR_SIZE < bluetooth->int_packet_pos) {
err("%s - packet was too long", __FUNCTION__); err("%s - packet was too long", __FUNCTION__);
bluetooth->int_packet_pos = 0; bluetooth->int_packet_pos = 0;
return; goto exit;
} }
if (packet_size + EVENT_HDR_SIZE == bluetooth->int_packet_pos) { if (packet_size + EVENT_HDR_SIZE == bluetooth->int_packet_pos) {
...@@ -851,6 +862,12 @@ static void bluetooth_int_callback (struct urb *urb) ...@@ -851,6 +862,12 @@ static void bluetooth_int_callback (struct urb *urb)
bluetooth->int_packet_pos = 0; bluetooth->int_packet_pos = 0;
} }
exit:
status = usb_submit_urb (urb, GFP_ATOMIC);
if (status)
err ("%s - usb_submit_urb failed with result %d",
__FUNCTION__, status);
} }
......
...@@ -185,20 +185,32 @@ static void acm_ctrl_irq(struct urb *urb) ...@@ -185,20 +185,32 @@ static void acm_ctrl_irq(struct urb *urb)
struct usb_ctrlrequest *dr = urb->transfer_buffer; struct usb_ctrlrequest *dr = urb->transfer_buffer;
unsigned char *data = (unsigned char *)(dr + 1); unsigned char *data = (unsigned char *)(dr + 1);
int newctrl; int newctrl;
int status;
if (!ACM_READY(acm)) return;
switch (urb->status) {
if (urb->status < 0) { case 0:
dbg("nonzero ctrl irq status received: %d", urb->status); /* success */
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; return;
default:
dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
goto exit;
} }
if (!ACM_READY(acm))
goto exit;
switch (dr->bRequest) { switch (dr->bRequest) {
case ACM_IRQ_NETWORK: case ACM_IRQ_NETWORK:
dbg("%s network", data[0] ? "connected to" : "disconnected from"); dbg("%s network", data[0] ? "connected to" : "disconnected from");
return; break;
case ACM_IRQ_LINE_STATE: case ACM_IRQ_LINE_STATE:
...@@ -217,13 +229,18 @@ static void acm_ctrl_irq(struct urb *urb) ...@@ -217,13 +229,18 @@ static void acm_ctrl_irq(struct urb *urb)
acm->ctrlin & ACM_CTRL_FRAMING ? '+' : '-', acm->ctrlin & ACM_CTRL_PARITY ? '+' : '-', acm->ctrlin & ACM_CTRL_FRAMING ? '+' : '-', acm->ctrlin & ACM_CTRL_PARITY ? '+' : '-',
acm->ctrlin & ACM_CTRL_OVERRUN ? '+' : '-'); acm->ctrlin & ACM_CTRL_OVERRUN ? '+' : '-');
return; break;
default: default:
dbg("unknown control event received: request %d index %d len %d data0 %d data1 %d", dbg("unknown control event received: request %d index %d len %d data0 %d data1 %d",
dr->bRequest, dr->wIndex, dr->wLength, data[0], data[1]); dr->bRequest, dr->wIndex, dr->wLength, data[0], data[1]);
return; break;
} }
exit:
status = usb_submit_urb (urb, GFP_ATOMIC);
if (status)
err ("%s - usb_submit_urb failed with result %d",
__FUNCTION__, status);
} }
static void acm_read_bulk(struct urb *urb) static void acm_read_bulk(struct urb *urb)
......
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