patch-2.4.0-test9 linux/drivers/usb/uhci.c
Next file: linux/drivers/usb/usb-core.c
Previous file: linux/drivers/usb/storage/usb.h
Back to the patch index
Back to the overall index
- Lines: 201
- Date:
Tue Sep 19 17:47:06 2000
- Orig file:
v2.4.0-test8/linux/drivers/usb/uhci.c
- Orig date:
Thu Sep 7 08:39:00 2000
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/uhci.c linux/drivers/usb/uhci.c
@@ -493,8 +493,6 @@
urb->hcpriv = urbp;
- usb_inc_dev_use(urb->dev);
-
return urbp;
}
@@ -556,8 +554,6 @@
urb->hcpriv = NULL;
kmem_cache_free(uhci_up_cachep, urbp);
- usb_dec_dev_use(urb->dev);
-
unlock:
spin_unlock_irqrestore(&urb->lock, flags);
}
@@ -572,7 +568,7 @@
spin_lock_irqsave(&uhci->framelist_lock, flags);
- if (!urbp->fsbr) {
+ if ((!(urb->transfer_flags & USB_NO_FSBR)) && (!urbp->fsbr)) {
urbp->fsbr = 1;
if (!uhci->fsbr++)
uhci->skel_term_qh.link = virt_to_bus(&uhci->skel_hs_control_qh) | UHCI_PTR_QH;
@@ -591,7 +587,7 @@
spin_lock_irqsave(&uhci->framelist_lock, flags);
- if (urbp->fsbr) {
+ if ((!(urb->transfer_flags & USB_NO_FSBR)) && urbp->fsbr) {
urbp->fsbr = 0;
if (!--uhci->fsbr)
uhci->skel_term_qh.link = UHCI_PTR_TERM;
@@ -739,8 +735,6 @@
uhci_add_urb_list(uhci, urb);
- usb_inc_dev_use(urb->dev);
-
return -EINPROGRESS;
}
@@ -1316,10 +1310,13 @@
if (u && !(urb->transfer_flags & USB_QUEUE_BULK))
return -ENXIO;
+ usb_inc_dev_use(urb->dev);
spin_lock_irqsave(&urb->lock, flags);
if (!uhci_alloc_urb_priv(urb)) {
spin_unlock_irqrestore(&urb->lock, flags);
+ usb_dec_dev_use(urb->dev);
+
return -ENOMEM;
}
@@ -1329,17 +1326,16 @@
break;
case PIPE_INTERRUPT:
if (urb->bandwidth == 0) { /* not yet checked/allocated */
- bustime = usb_check_bandwidth (urb->dev, urb);
+ bustime = usb_check_bandwidth(urb->dev, urb);
if (bustime < 0)
ret = bustime;
else {
ret = uhci_submit_interrupt(urb);
if (ret == -EINPROGRESS)
- usb_claim_bandwidth (urb->dev, urb, bustime, 0);
+ usb_claim_bandwidth(urb->dev, urb, bustime, 0);
}
- } else { /* bandwidth is already set */
+ } else /* bandwidth is already set */
ret = uhci_submit_interrupt(urb);
- }
break;
case PIPE_BULK:
ret = uhci_submit_bulk(urb, u);
@@ -1350,7 +1346,7 @@
ret = -EINVAL;
break;
}
- bustime = usb_check_bandwidth (urb->dev, urb);
+ bustime = usb_check_bandwidth(urb->dev, urb);
if (bustime < 0) {
ret = bustime;
break;
@@ -1358,10 +1354,9 @@
ret = uhci_submit_isochronous(urb);
if (ret == -EINPROGRESS)
- usb_claim_bandwidth (urb->dev, urb, bustime, 1);
- } else { /* bandwidth is already set */
+ usb_claim_bandwidth(urb->dev, urb, bustime, 1);
+ } else /* bandwidth is already set */
ret = uhci_submit_isochronous(urb);
- }
break;
}
@@ -1371,8 +1366,10 @@
if (ret == -EINPROGRESS)
ret = 0;
- else
+ else {
uhci_unlink_generic(urb);
+ usb_dec_dev_use(urb->dev);
+ }
return ret;
}
@@ -1384,6 +1381,7 @@
*/
static void uhci_transfer_result(struct urb *urb)
{
+ struct usb_device *dev = urb->dev;
struct urb *turb;
int proceed = 0, is_ring = 0;
int ret = -EINVAL;
@@ -1420,22 +1418,23 @@
/* Release bandwidth for Interrupt or Isoc. transfers */
/* Spinlock needed ? */
if (urb->bandwidth)
- usb_release_bandwidth (urb->dev, urb, 1);
+ usb_release_bandwidth(urb->dev, urb, 1);
uhci_unlink_generic(urb);
break;
case PIPE_INTERRUPT:
/* Interrupts are an exception */
- urb->complete(urb);
- if (urb->interval)
+ if (urb->interval) {
+ urb->complete(urb);
uhci_reset_interrupt(urb);
- else {
- /* Release bandwidth for Interrupt or Isoc. transfers */
- /* Spinlock needed ? */
- if (urb->bandwidth)
- usb_release_bandwidth (urb->dev, urb, 0);
- uhci_unlink_generic(urb);
+ return;
}
- return; /* <-- Note the return */
+
+ /* Release bandwidth for Interrupt or Isoc. transfers */
+ /* Spinlock needed ? */
+ if (urb->bandwidth)
+ usb_release_bandwidth(urb->dev, urb, 0);
+ uhci_unlink_generic(urb);
+ break;
}
if (urb->next) {
@@ -1453,7 +1452,7 @@
is_ring = 1;
}
- if (urb->complete && (!proceed || (urb->transfer_flags & USB_URB_EARLY_COMPLETE))) {
+ if (urb->complete && !proceed) {
urb->complete(urb);
if (!proceed && is_ring)
uhci_submit_urb(urb);
@@ -1468,9 +1467,12 @@
turb = turb->next;
} while (turb && turb != urb->next);
- if (urb->complete && !(urb->transfer_flags & USB_URB_EARLY_COMPLETE))
+ if (urb->complete)
urb->complete(urb);
}
+
+ /* We decrement the usage count after we're done with everything */
+ usb_dec_dev_use(dev);
}
static int uhci_unlink_generic(struct urb *urb)
@@ -1494,6 +1496,8 @@
uhci_destroy_urb_priv(urb);
+ urb->dev = NULL;
+
return 0;
}
@@ -1520,10 +1524,10 @@
if (urb->bandwidth) {
switch (usb_pipetype(urb->pipe)) {
case PIPE_INTERRUPT:
- usb_release_bandwidth (urb->dev, urb, 0);
+ usb_release_bandwidth(urb->dev, urb, 0);
break;
case PIPE_ISOCHRONOUS:
- usb_release_bandwidth (urb->dev, urb, 1);
+ usb_release_bandwidth(urb->dev, urb, 1);
break;
default:
break;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)