diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-07-28 23:18:56 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-07-28 23:18:56 +0000 |
commit | 4d657aa39d5bcae60c2c11bf8fb66692ddd1c9e7 (patch) | |
tree | 30f3b08741a4d4b98b16bd99ea2757ff715d1c11 /drivers/usb/uhci.c | |
parent | eed6b7c84cc33f229f6fecd884d9a22af5bec514 (diff) |
Merge with 2.4.0-test5 final.
Diffstat (limited to 'drivers/usb/uhci.c')
-rw-r--r-- | drivers/usb/uhci.c | 58 |
1 files changed, 55 insertions, 3 deletions
diff --git a/drivers/usb/uhci.c b/drivers/usb/uhci.c index a3d8d3d42..31be1c0e2 100644 --- a/drivers/usb/uhci.c +++ b/drivers/usb/uhci.c @@ -1296,6 +1296,7 @@ static int uhci_submit_urb(struct urb *urb) struct uhci *uhci; unsigned long flags; struct urb *u; + int bustime; if (!urb) return -EINVAL; @@ -1325,13 +1326,40 @@ static int uhci_submit_urb(struct urb *urb) ret = uhci_submit_control(urb); break; case PIPE_INTERRUPT: - ret = uhci_submit_interrupt(urb); + if (urb->bandwidth == 0) { /* not yet checked/allocated */ + 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); + } + } else { /* bandwidth is already set */ + ret = uhci_submit_interrupt(urb); + } break; case PIPE_BULK: ret = uhci_submit_bulk(urb, u); break; case PIPE_ISOCHRONOUS: - ret = uhci_submit_isochronous(urb); + if (urb->bandwidth == 0) { /* not yet checked/allocated */ + if (urb->number_of_packets <= 0) { + ret = -EINVAL; + break; + } + bustime = usb_check_bandwidth (urb->dev, urb); + if (bustime < 0) { + ret = bustime; + break; + } + + ret = uhci_submit_isochronous(urb); + if (ret == -EINPROGRESS) + usb_claim_bandwidth (urb->dev, urb, bustime, 1); + } else { /* bandwidth is already set */ + ret = uhci_submit_isochronous(urb); + } break; } @@ -1387,6 +1415,10 @@ static void uhci_transfer_result(struct urb *urb) case PIPE_CONTROL: case PIPE_BULK: case PIPE_ISOCHRONOUS: + /* Release bandwidth for Interrupt or Isoc. transfers */ + /* Spinlock needed ? */ + if (urb->bandwidth) + usb_release_bandwidth (urb->dev, urb, 1); uhci_unlink_generic(urb); break; case PIPE_INTERRUPT: @@ -1394,8 +1426,13 @@ static void uhci_transfer_result(struct urb *urb) urb->complete(urb); if (urb->interval) uhci_reset_interrupt(urb); - else + 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; /* <-- Note the return */ } @@ -1476,6 +1513,21 @@ static int uhci_unlink_urb(struct urb *urb) if (usb_pipedevice(urb->pipe) == uhci->rh.devnum) return rh_unlink_urb(urb); + /* Release bandwidth for Interrupt or Isoc. transfers */ + /* Spinlock needed ? */ + if (urb->bandwidth) { + switch (usb_pipetype(urb->pipe)) { + case PIPE_INTERRUPT: + usb_release_bandwidth (urb->dev, urb, 0); + break; + case PIPE_ISOCHRONOUS: + usb_release_bandwidth (urb->dev, urb, 1); + break; + default: + break; + } + } + if (urb->status == -EINPROGRESS) { uhci_unlink_generic(urb); |