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

USB: fix the usb drivers outside the drivers/usb tree due to interrupt urb no...

USB: fix the usb drivers outside the drivers/usb tree due to interrupt urb no automatic resubmission change to the usb core.
parent 4416fcb0
...@@ -438,16 +438,34 @@ static void hci_usb_interrupt(struct urb *urb) ...@@ -438,16 +438,34 @@ static void hci_usb_interrupt(struct urb *urb)
__u8 *data = urb->transfer_buffer; __u8 *data = urb->transfer_buffer;
int count = urb->actual_length; int count = urb->actual_length;
int len = HCI_EVENT_HDR_SIZE; int len = HCI_EVENT_HDR_SIZE;
int status;
BT_DBG("%s urb %p count %d", husb->hdev.name, urb, count); BT_DBG("%s urb %p count %d", husb->hdev.name, urb, count);
if (!test_bit(HCI_RUNNING, &husb->hdev.flags)) if (!test_bit(HCI_RUNNING, &husb->hdev.flags))
return; return;
if (urb->status || !count) { switch (urb->status) {
case 0:
/* success */
break;
case -ECONNRESET:
case -ENOENT:
case -ESHUTDOWN:
/* this urb is terminated, clean up */
BT_DBG("%s urb shutting down with status: %d",
husb->hdev.name, urb->status);
return;
default:
BT_ERR("%s nonzero urb status received: %d",
husb->hdev.name, urb->status);
goto exit;
}
if (!count) {
BT_DBG("%s intr status %d, count %d", BT_DBG("%s intr status %d, count %d",
husb->hdev.name, urb->status, count); husb->hdev.name, urb->status, count);
return; goto exit;
} }
read_lock(&husb->completion_lock); read_lock(&husb->completion_lock);
...@@ -499,12 +517,18 @@ static void hci_usb_interrupt(struct urb *urb) ...@@ -499,12 +517,18 @@ static void hci_usb_interrupt(struct urb *urb)
done: done:
read_unlock(&husb->completion_lock); read_unlock(&husb->completion_lock);
return; goto exit;
bad_len: bad_len:
BT_ERR("%s bad frame len %d expected %d", husb->hdev.name, count, len); BT_ERR("%s bad frame len %d expected %d", husb->hdev.name, count, len);
husb->hdev.stat.err_rx++; husb->hdev.stat.err_rx++;
read_unlock(&husb->completion_lock); read_unlock(&husb->completion_lock);
exit:
status = usb_submit_urb (urb, GFP_ATOMIC);
if (status)
BT_ERR ("%s usb_submit_urb failed with result %d",
husb->hdev.name, status);
} }
static void hci_usb_tx_complete(struct urb *urb) static void hci_usb_tx_complete(struct urb *urb)
......
...@@ -77,9 +77,32 @@ void iforce_usb_xmit(struct iforce *iforce) ...@@ -77,9 +77,32 @@ void iforce_usb_xmit(struct iforce *iforce)
static void iforce_usb_irq(struct urb *urb) static void iforce_usb_irq(struct urb *urb)
{ {
struct iforce *iforce = urb->context; struct iforce *iforce = urb->context;
if (urb->status) return; int status;
switch (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;
default:
dbg("%s - urb has status of: %d", __FUNCTION__, urb->status);
goto exit;
}
iforce_process_packet(iforce, iforce_process_packet(iforce,
(iforce->data[0] << 8) | (urb->actual_length - 1), iforce->data + 1); (iforce->data[0] << 8) | (urb->actual_length - 1), iforce->data + 1);
exit:
status = usb_submit_urb (urb, GFP_ATOMIC);
if (status)
err ("%s - usb_submit_urb failed with result %d",
__FUNCTION__, status);
} }
static void iforce_usb_out(struct urb *urb) static void iforce_usb_out(struct urb *urb)
......
...@@ -182,21 +182,28 @@ static void usb_int_complete(struct urb *urb) ...@@ -182,21 +182,28 @@ static void usb_int_complete(struct urb *urb)
u_char irqbyte; u_char irqbyte;
struct st5481_adapter *adapter = urb->context; struct st5481_adapter *adapter = urb->context;
int j; int j;
int status;
if (urb->status < 0) { switch (urb->status) {
if (urb->status != -ENOENT) { case 0:
WARN("urb status %d",urb->status); /* success */
urb->actual_length = 0; break;
} else { case -ECONNRESET:
DBG(1,"urb killed"); case -ENOENT:
return; // Give up case -ESHUTDOWN:
} /* this urb is terminated, clean up */
DBG(1, "urb shutting down with status: %d", urb->status);
return;
default:
WARN("nonzero urb status received: %d", urb->status);
goto exit;
} }
DBG_PACKET(1, data, INT_PKT_SIZE); DBG_PACKET(1, data, INT_PKT_SIZE);
if (urb->actual_length == 0) { if (urb->actual_length == 0) {
return; goto exit;
} }
irqbyte = data[MPINT]; irqbyte = data[MPINT];
...@@ -221,6 +228,11 @@ static void usb_int_complete(struct urb *urb) ...@@ -221,6 +228,11 @@ static void usb_int_complete(struct urb *urb)
adapter->bcs[j].b_out.flow_event |= data[FFINT_B1 + j]; adapter->bcs[j].b_out.flow_event |= data[FFINT_B1 + j];
urb->actual_length = 0; urb->actual_length = 0;
exit:
status = usb_submit_urb (urb, GFP_ATOMIC);
if (status)
WARN("usb_submit_urb failed with result %d", 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