aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/uhci-q.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/uhci-q.c')
-rw-r--r--drivers/usb/host/uhci-q.c258
1 files changed, 185 insertions, 73 deletions
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index 30b88459ac7d..2cbb239e63f8 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -248,16 +248,26 @@ static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci,
248 INIT_LIST_HEAD(&qh->node); 248 INIT_LIST_HEAD(&qh->node);
249 249
250 if (udev) { /* Normal QH */ 250 if (udev) { /* Normal QH */
251 qh->dummy_td = uhci_alloc_td(uhci); 251 qh->type = hep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
252 if (!qh->dummy_td) { 252 if (qh->type != USB_ENDPOINT_XFER_ISOC) {
253 dma_pool_free(uhci->qh_pool, qh, dma_handle); 253 qh->dummy_td = uhci_alloc_td(uhci);
254 return NULL; 254 if (!qh->dummy_td) {
255 dma_pool_free(uhci->qh_pool, qh, dma_handle);
256 return NULL;
257 }
255 } 258 }
256 qh->state = QH_STATE_IDLE; 259 qh->state = QH_STATE_IDLE;
257 qh->hep = hep; 260 qh->hep = hep;
258 qh->udev = udev; 261 qh->udev = udev;
259 hep->hcpriv = qh; 262 hep->hcpriv = qh;
260 qh->type = hep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; 263
264 if (qh->type == USB_ENDPOINT_XFER_INT ||
265 qh->type == USB_ENDPOINT_XFER_ISOC)
266 qh->load = usb_calc_bus_time(udev->speed,
267 usb_endpoint_dir_in(&hep->desc),
268 qh->type == USB_ENDPOINT_XFER_ISOC,
269 le16_to_cpu(hep->desc.wMaxPacketSize))
270 / 1000 + 1;
261 271
262 } else { /* Skeleton QH */ 272 } else { /* Skeleton QH */
263 qh->state = QH_STATE_ACTIVE; 273 qh->state = QH_STATE_ACTIVE;
@@ -275,7 +285,8 @@ static void uhci_free_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
275 list_del(&qh->node); 285 list_del(&qh->node);
276 if (qh->udev) { 286 if (qh->udev) {
277 qh->hep->hcpriv = NULL; 287 qh->hep->hcpriv = NULL;
278 uhci_free_td(uhci, qh->dummy_td); 288 if (qh->dummy_td)
289 uhci_free_td(uhci, qh->dummy_td);
279 } 290 }
280 dma_pool_free(uhci->qh_pool, qh, qh->dma_handle); 291 dma_pool_free(uhci->qh_pool, qh, qh->dma_handle);
281} 292}
@@ -327,7 +338,7 @@ static int uhci_cleanup_queue(struct uhci_hcd *uhci, struct uhci_qh *qh,
327 goto done; 338 goto done;
328 qh->element = UHCI_PTR_TERM; 339 qh->element = UHCI_PTR_TERM;
329 340
330 /* Control pipes have to worry about toggles */ 341 /* Control pipes don't have to worry about toggles */
331 if (qh->type == USB_ENDPOINT_XFER_CONTROL) 342 if (qh->type == USB_ENDPOINT_XFER_CONTROL)
332 goto done; 343 goto done;
333 344
@@ -493,6 +504,121 @@ static void uhci_make_qh_idle(struct uhci_hcd *uhci, struct uhci_qh *qh)
493 wake_up_all(&uhci->waitqh); 504 wake_up_all(&uhci->waitqh);
494} 505}
495 506
507/*
508 * Find the highest existing bandwidth load for a given phase and period.
509 */
510static int uhci_highest_load(struct uhci_hcd *uhci, int phase, int period)
511{
512 int highest_load = uhci->load[phase];
513
514 for (phase += period; phase < MAX_PHASE; phase += period)
515 highest_load = max_t(int, highest_load, uhci->load[phase]);
516 return highest_load;
517}
518
519/*
520 * Set qh->phase to the optimal phase for a periodic transfer and
521 * check whether the bandwidth requirement is acceptable.
522 */
523static int uhci_check_bandwidth(struct uhci_hcd *uhci, struct uhci_qh *qh)
524{
525 int minimax_load;
526
527 /* Find the optimal phase (unless it is already set) and get
528 * its load value. */
529 if (qh->phase >= 0)
530 minimax_load = uhci_highest_load(uhci, qh->phase, qh->period);
531 else {
532 int phase, load;
533 int max_phase = min_t(int, MAX_PHASE, qh->period);
534
535 qh->phase = 0;
536 minimax_load = uhci_highest_load(uhci, qh->phase, qh->period);
537 for (phase = 1; phase < max_phase; ++phase) {
538 load = uhci_highest_load(uhci, phase, qh->period);
539 if (load < minimax_load) {
540 minimax_load = load;
541 qh->phase = phase;
542 }
543 }
544 }
545
546 /* Maximum allowable periodic bandwidth is 90%, or 900 us per frame */
547 if (minimax_load + qh->load > 900) {
548 dev_dbg(uhci_dev(uhci), "bandwidth allocation failed: "
549 "period %d, phase %d, %d + %d us\n",
550 qh->period, qh->phase, minimax_load, qh->load);
551 return -ENOSPC;
552 }
553 return 0;
554}
555
556/*
557 * Reserve a periodic QH's bandwidth in the schedule
558 */
559static void uhci_reserve_bandwidth(struct uhci_hcd *uhci, struct uhci_qh *qh)
560{
561 int i;
562 int load = qh->load;
563 char *p = "??";
564
565 for (i = qh->phase; i < MAX_PHASE; i += qh->period) {
566 uhci->load[i] += load;
567 uhci->total_load += load;
568 }
569 uhci_to_hcd(uhci)->self.bandwidth_allocated =
570 uhci->total_load / MAX_PHASE;
571 switch (qh->type) {
572 case USB_ENDPOINT_XFER_INT:
573 ++uhci_to_hcd(uhci)->self.bandwidth_int_reqs;
574 p = "INT";
575 break;
576 case USB_ENDPOINT_XFER_ISOC:
577 ++uhci_to_hcd(uhci)->self.bandwidth_isoc_reqs;
578 p = "ISO";
579 break;
580 }
581 qh->bandwidth_reserved = 1;
582 dev_dbg(uhci_dev(uhci),
583 "%s dev %d ep%02x-%s, period %d, phase %d, %d us\n",
584 "reserve", qh->udev->devnum,
585 qh->hep->desc.bEndpointAddress, p,
586 qh->period, qh->phase, load);
587}
588
589/*
590 * Release a periodic QH's bandwidth reservation
591 */
592static void uhci_release_bandwidth(struct uhci_hcd *uhci, struct uhci_qh *qh)
593{
594 int i;
595 int load = qh->load;
596 char *p = "??";
597
598 for (i = qh->phase; i < MAX_PHASE; i += qh->period) {
599 uhci->load[i] -= load;
600 uhci->total_load -= load;
601 }
602 uhci_to_hcd(uhci)->self.bandwidth_allocated =
603 uhci->total_load / MAX_PHASE;
604 switch (qh->type) {
605 case USB_ENDPOINT_XFER_INT:
606 --uhci_to_hcd(uhci)->self.bandwidth_int_reqs;
607 p = "INT";
608 break;
609 case USB_ENDPOINT_XFER_ISOC:
610 --uhci_to_hcd(uhci)->self.bandwidth_isoc_reqs;
611 p = "ISO";
612 break;
613 }
614 qh->bandwidth_reserved = 0;
615 dev_dbg(uhci_dev(uhci),
616 "%s dev %d ep%02x-%s, period %d, phase %d, %d us\n",
617 "release", qh->udev->devnum,
618 qh->hep->desc.bEndpointAddress, p,
619 qh->period, qh->phase, load);
620}
621
496static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, 622static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci,
497 struct urb *urb) 623 struct urb *urb)
498{ 624{
@@ -796,7 +922,6 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
796 wmb(); 922 wmb();
797 qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE); 923 qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE);
798 qh->dummy_td = td; 924 qh->dummy_td = td;
799 qh->period = urb->interval;
800 925
801 usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), 926 usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
802 usb_pipeout(urb->pipe), toggle); 927 usb_pipeout(urb->pipe), toggle);
@@ -827,28 +952,42 @@ static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb,
827static int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb, 952static int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb,
828 struct uhci_qh *qh) 953 struct uhci_qh *qh)
829{ 954{
830 int exponent; 955 int ret;
831 956
832 /* USB 1.1 interrupt transfers only involve one packet per interval. 957 /* USB 1.1 interrupt transfers only involve one packet per interval.
833 * Drivers can submit URBs of any length, but longer ones will need 958 * Drivers can submit URBs of any length, but longer ones will need
834 * multiple intervals to complete. 959 * multiple intervals to complete.
835 */ 960 */
836 961
837 /* Figure out which power-of-two queue to use */ 962 if (!qh->bandwidth_reserved) {
838 for (exponent = 7; exponent >= 0; --exponent) { 963 int exponent;
839 if ((1 << exponent) <= urb->interval)
840 break;
841 }
842 if (exponent < 0)
843 return -EINVAL;
844 urb->interval = 1 << exponent;
845 964
846 if (qh->period == 0) 965 /* Figure out which power-of-two queue to use */
966 for (exponent = 7; exponent >= 0; --exponent) {
967 if ((1 << exponent) <= urb->interval)
968 break;
969 }
970 if (exponent < 0)
971 return -EINVAL;
972 qh->period = 1 << exponent;
847 qh->skel = uhci->skelqh[UHCI_SKEL_INDEX(exponent)]; 973 qh->skel = uhci->skelqh[UHCI_SKEL_INDEX(exponent)];
848 else if (qh->period != urb->interval)
849 return -EINVAL; /* Can't change the period */
850 974
851 return uhci_submit_common(uhci, urb, qh); 975 /* For now, interrupt phase is fixed by the layout
976 * of the QH lists. */
977 qh->phase = (qh->period / 2) & (MAX_PHASE - 1);
978 ret = uhci_check_bandwidth(uhci, qh);
979 if (ret)
980 return ret;
981 } else if (qh->period > urb->interval)
982 return -EINVAL; /* Can't decrease the period */
983
984 ret = uhci_submit_common(uhci, urb, qh);
985 if (ret == 0) {
986 urb->interval = qh->period;
987 if (!qh->bandwidth_reserved)
988 uhci_reserve_bandwidth(uhci, qh);
989 }
990 return ret;
852} 991}
853 992
854/* 993/*
@@ -995,15 +1134,32 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
995 return -EFBIG; 1134 return -EFBIG;
996 1135
997 /* Check the period and figure out the starting frame number */ 1136 /* Check the period and figure out the starting frame number */
998 if (qh->period == 0) { 1137 if (!qh->bandwidth_reserved) {
1138 qh->period = urb->interval;
999 if (urb->transfer_flags & URB_ISO_ASAP) { 1139 if (urb->transfer_flags & URB_ISO_ASAP) {
1140 qh->phase = -1; /* Find the best phase */
1141 i = uhci_check_bandwidth(uhci, qh);
1142 if (i)
1143 return i;
1144
1145 /* Allow a little time to allocate the TDs */
1000 uhci_get_current_frame_number(uhci); 1146 uhci_get_current_frame_number(uhci);
1001 urb->start_frame = uhci->frame_number + 10; 1147 frame = uhci->frame_number + 10;
1148
1149 /* Move forward to the first frame having the
1150 * correct phase */
1151 urb->start_frame = frame + ((qh->phase - frame) &
1152 (qh->period - 1));
1002 } else { 1153 } else {
1003 i = urb->start_frame - uhci->last_iso_frame; 1154 i = urb->start_frame - uhci->last_iso_frame;
1004 if (i <= 0 || i >= UHCI_NUMFRAMES) 1155 if (i <= 0 || i >= UHCI_NUMFRAMES)
1005 return -EINVAL; 1156 return -EINVAL;
1157 qh->phase = urb->start_frame & (qh->period - 1);
1158 i = uhci_check_bandwidth(uhci, qh);
1159 if (i)
1160 return i;
1006 } 1161 }
1162
1007 } else if (qh->period != urb->interval) { 1163 } else if (qh->period != urb->interval) {
1008 return -EINVAL; /* Can't change the period */ 1164 return -EINVAL; /* Can't change the period */
1009 1165
@@ -1049,9 +1205,6 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
1049 /* Set the interrupt-on-completion flag on the last packet. */ 1205 /* Set the interrupt-on-completion flag on the last packet. */
1050 td->status |= __constant_cpu_to_le32(TD_CTRL_IOC); 1206 td->status |= __constant_cpu_to_le32(TD_CTRL_IOC);
1051 1207
1052 qh->skel = uhci->skel_iso_qh;
1053 qh->period = urb->interval;
1054
1055 /* Add the TDs to the frame list */ 1208 /* Add the TDs to the frame list */
1056 frame = urb->start_frame; 1209 frame = urb->start_frame;
1057 list_for_each_entry(td, &urbp->td_list, list) { 1210 list_for_each_entry(td, &urbp->td_list, list) {
@@ -1065,6 +1218,9 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
1065 qh->iso_status = 0; 1218 qh->iso_status = 0;
1066 } 1219 }
1067 1220
1221 qh->skel = uhci->skel_iso_qh;
1222 if (!qh->bandwidth_reserved)
1223 uhci_reserve_bandwidth(uhci, qh);
1068 return 0; 1224 return 0;
1069} 1225}
1070 1226
@@ -1119,7 +1275,6 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd,
1119 unsigned long flags; 1275 unsigned long flags;
1120 struct urb_priv *urbp; 1276 struct urb_priv *urbp;
1121 struct uhci_qh *qh; 1277 struct uhci_qh *qh;
1122 int bustime;
1123 1278
1124 spin_lock_irqsave(&uhci->lock, flags); 1279 spin_lock_irqsave(&uhci->lock, flags);
1125 1280
@@ -1149,35 +1304,11 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd,
1149 ret = uhci_submit_bulk(uhci, urb, qh); 1304 ret = uhci_submit_bulk(uhci, urb, qh);
1150 break; 1305 break;
1151 case USB_ENDPOINT_XFER_INT: 1306 case USB_ENDPOINT_XFER_INT:
1152 if (list_empty(&qh->queue)) { 1307 ret = uhci_submit_interrupt(uhci, urb, qh);
1153 bustime = usb_check_bandwidth(urb->dev, urb);
1154 if (bustime < 0)
1155 ret = bustime;
1156 else {
1157 ret = uhci_submit_interrupt(uhci, urb, qh);
1158 if (ret == 0)
1159 usb_claim_bandwidth(urb->dev, urb, bustime, 0);
1160 }
1161 } else { /* inherit from parent */
1162 struct urb_priv *eurbp;
1163
1164 eurbp = list_entry(qh->queue.prev, struct urb_priv,
1165 node);
1166 urb->bandwidth = eurbp->urb->bandwidth;
1167 ret = uhci_submit_interrupt(uhci, urb, qh);
1168 }
1169 break; 1308 break;
1170 case USB_ENDPOINT_XFER_ISOC: 1309 case USB_ENDPOINT_XFER_ISOC:
1171 urb->error_count = 0; 1310 urb->error_count = 0;
1172 bustime = usb_check_bandwidth(urb->dev, urb);
1173 if (bustime < 0) {
1174 ret = bustime;
1175 break;
1176 }
1177
1178 ret = uhci_submit_isochronous(uhci, urb, qh); 1311 ret = uhci_submit_isochronous(uhci, urb, qh);
1179 if (ret == 0)
1180 usb_claim_bandwidth(urb->dev, urb, bustime, 1);
1181 break; 1312 break;
1182 } 1313 }
1183 if (ret != 0) 1314 if (ret != 0)
@@ -1274,24 +1405,6 @@ __acquires(uhci->lock)
1274 1405
1275 uhci_free_urb_priv(uhci, urbp); 1406 uhci_free_urb_priv(uhci, urbp);
1276 1407
1277 switch (qh->type) {
1278 case USB_ENDPOINT_XFER_ISOC:
1279 /* Release bandwidth for Interrupt or Isoc. transfers */
1280 if (urb->bandwidth)
1281 usb_release_bandwidth(urb->dev, urb, 1);
1282 break;
1283 case USB_ENDPOINT_XFER_INT:
1284 /* Release bandwidth for Interrupt or Isoc. transfers */
1285 /* Make sure we don't release if we have a queued URB */
1286 if (list_empty(&qh->queue) && urb->bandwidth)
1287 usb_release_bandwidth(urb->dev, urb, 0);
1288 else
1289 /* bandwidth was passed on to queued URB, */
1290 /* so don't let usb_unlink_urb() release it */
1291 urb->bandwidth = 0;
1292 break;
1293 }
1294
1295 spin_unlock(&uhci->lock); 1408 spin_unlock(&uhci->lock);
1296 usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb); 1409 usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb);
1297 spin_lock(&uhci->lock); 1410 spin_lock(&uhci->lock);
@@ -1300,9 +1413,8 @@ __acquires(uhci->lock)
1300 * reserved bandwidth. */ 1413 * reserved bandwidth. */
1301 if (list_empty(&qh->queue)) { 1414 if (list_empty(&qh->queue)) {
1302 uhci_unlink_qh(uhci, qh); 1415 uhci_unlink_qh(uhci, qh);
1303 1416 if (qh->bandwidth_reserved)
1304 /* Bandwidth stuff not yet implemented */ 1417 uhci_release_bandwidth(uhci, qh);
1305 qh->period = 0;
1306 } 1418 }
1307} 1419}
1308 1420