aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-sched.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ehci-sched.c')
-rw-r--r--drivers/usb/host/ehci-sched.c216
1 files changed, 215 insertions, 1 deletions
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 5871944e614..4859900bd13 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -163,6 +163,190 @@ static int same_tt (struct usb_device *dev1, struct usb_device *dev2)
163 return 1; 163 return 1;
164} 164}
165 165
166#ifdef CONFIG_USB_EHCI_TT_NEWSCHED
167
168/* Which uframe does the low/fullspeed transfer start in?
169 *
170 * The parameter is the mask of ssplits in "H-frame" terms
171 * and this returns the transfer start uframe in "B-frame" terms,
172 * which allows both to match, e.g. a ssplit in "H-frame" uframe 0
173 * will cause a transfer in "B-frame" uframe 0. "B-frames" lag
174 * "H-frames" by 1 uframe. See the EHCI spec sec 4.5 and figure 4.7.
175 */
176static inline unsigned char tt_start_uframe(struct ehci_hcd *ehci, __le32 mask)
177{
178 unsigned char smask = QH_SMASK & le32_to_cpu(mask);
179 if (!smask) {
180 ehci_err(ehci, "invalid empty smask!\n");
181 /* uframe 7 can't have bw so this will indicate failure */
182 return 7;
183 }
184 return ffs(smask) - 1;
185}
186
187static const unsigned char
188max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 30, 0 };
189
190/* carryover low/fullspeed bandwidth that crosses uframe boundries */
191static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8])
192{
193 int i;
194 for (i=0; i<7; i++) {
195 if (max_tt_usecs[i] < tt_usecs[i]) {
196 tt_usecs[i+1] += tt_usecs[i] - max_tt_usecs[i];
197 tt_usecs[i] = max_tt_usecs[i];
198 }
199 }
200}
201
202/* How many of the tt's periodic downstream 1000 usecs are allocated?
203 *
204 * While this measures the bandwidth in terms of usecs/uframe,
205 * the low/fullspeed bus has no notion of uframes, so any particular
206 * low/fullspeed transfer can "carry over" from one uframe to the next,
207 * since the TT just performs downstream transfers in sequence.
208 *
209 * For example two seperate 100 usec transfers can start in the same uframe,
210 * and the second one would "carry over" 75 usecs into the next uframe.
211 */
212static void
213periodic_tt_usecs (
214 struct ehci_hcd *ehci,
215 struct usb_device *dev,
216 unsigned frame,
217 unsigned short tt_usecs[8]
218)
219{
220 __le32 *hw_p = &ehci->periodic [frame];
221 union ehci_shadow *q = &ehci->pshadow [frame];
222 unsigned char uf;
223
224 memset(tt_usecs, 0, 16);
225
226 while (q->ptr) {
227 switch (Q_NEXT_TYPE(*hw_p)) {
228 case Q_TYPE_ITD:
229 hw_p = &q->itd->hw_next;
230 q = &q->itd->itd_next;
231 continue;
232 case Q_TYPE_QH:
233 if (same_tt(dev, q->qh->dev)) {
234 uf = tt_start_uframe(ehci, q->qh->hw_info2);
235 tt_usecs[uf] += q->qh->tt_usecs;
236 }
237 hw_p = &q->qh->hw_next;
238 q = &q->qh->qh_next;
239 continue;
240 case Q_TYPE_SITD:
241 if (same_tt(dev, q->sitd->urb->dev)) {
242 uf = tt_start_uframe(ehci, q->sitd->hw_uframe);
243 tt_usecs[uf] += q->sitd->stream->tt_usecs;
244 }
245 hw_p = &q->sitd->hw_next;
246 q = &q->sitd->sitd_next;
247 continue;
248 // case Q_TYPE_FSTN:
249 default:
250 ehci_dbg(ehci,
251 "ignoring periodic frame %d FSTN\n", frame);
252 hw_p = &q->fstn->hw_next;
253 q = &q->fstn->fstn_next;
254 }
255 }
256
257 carryover_tt_bandwidth(tt_usecs);
258
259 if (max_tt_usecs[7] < tt_usecs[7])
260 ehci_err(ehci, "frame %d tt sched overrun: %d usecs\n",
261 frame, tt_usecs[7] - max_tt_usecs[7]);
262}
263
264/*
265 * Return true if the device's tt's downstream bus is available for a
266 * periodic transfer of the specified length (usecs), starting at the
267 * specified frame/uframe. Note that (as summarized in section 11.19
268 * of the usb 2.0 spec) TTs can buffer multiple transactions for each
269 * uframe.
270 *
271 * The uframe parameter is when the fullspeed/lowspeed transfer
272 * should be executed in "B-frame" terms, which is the same as the
273 * highspeed ssplit's uframe (which is in "H-frame" terms). For example
274 * a ssplit in "H-frame" 0 causes a transfer in "B-frame" 0.
275 * See the EHCI spec sec 4.5 and fig 4.7.
276 *
277 * This checks if the full/lowspeed bus, at the specified starting uframe,
278 * has the specified bandwidth available, according to rules listed
279 * in USB 2.0 spec section 11.18.1 fig 11-60.
280 *
281 * This does not check if the transfer would exceed the max ssplit
282 * limit of 16, specified in USB 2.0 spec section 11.18.4 requirement #4,
283 * since proper scheduling limits ssplits to less than 16 per uframe.
284 */
285static int tt_available (
286 struct ehci_hcd *ehci,
287 unsigned period,
288 struct usb_device *dev,
289 unsigned frame,
290 unsigned uframe,
291 u16 usecs
292)
293{
294 if ((period == 0) || (uframe >= 7)) /* error */
295 return 0;
296
297 for (; frame < ehci->periodic_size; frame += period) {
298 unsigned short tt_usecs[8];
299
300 periodic_tt_usecs (ehci, dev, frame, tt_usecs);
301
302 ehci_vdbg(ehci, "tt frame %d check %d usecs start uframe %d in"
303 " schedule %d/%d/%d/%d/%d/%d/%d/%d\n",
304 frame, usecs, uframe,
305 tt_usecs[0], tt_usecs[1], tt_usecs[2], tt_usecs[3],
306 tt_usecs[4], tt_usecs[5], tt_usecs[6], tt_usecs[7]);
307
308 if (max_tt_usecs[uframe] <= tt_usecs[uframe]) {
309 ehci_vdbg(ehci, "frame %d uframe %d fully scheduled\n",
310 frame, uframe);
311 return 0;
312 }
313
314 /* special case for isoc transfers larger than 125us:
315 * the first and each subsequent fully used uframe
316 * must be empty, so as to not illegally delay
317 * already scheduled transactions
318 */
319 if (125 < usecs) {
320 int ufs = (usecs / 125) - 1;
321 int i;
322 for (i = uframe; i < (uframe + ufs) && i < 8; i++)
323 if (0 < tt_usecs[i]) {
324 ehci_vdbg(ehci,
325 "multi-uframe xfer can't fit "
326 "in frame %d uframe %d\n",
327 frame, i);
328 return 0;
329 }
330 }
331
332 tt_usecs[uframe] += usecs;
333
334 carryover_tt_bandwidth(tt_usecs);
335
336 /* fail if the carryover pushed bw past the last uframe's limit */
337 if (max_tt_usecs[7] < tt_usecs[7]) {
338 ehci_vdbg(ehci,
339 "tt unavailable usecs %d frame %d uframe %d\n",
340 usecs, frame, uframe);
341 return 0;
342 }
343 }
344
345 return 1;
346}
347
348#else
349
166/* return true iff the device's transaction translator is available 350/* return true iff the device's transaction translator is available
167 * for a periodic transfer starting at the specified frame, using 351 * for a periodic transfer starting at the specified frame, using
168 * all the uframes in the mask. 352 * all the uframes in the mask.
@@ -237,6 +421,8 @@ static int tt_no_collision (
237 return 1; 421 return 1;
238} 422}
239 423
424#endif /* CONFIG_USB_EHCI_TT_NEWSCHED */
425
240/*-------------------------------------------------------------------------*/ 426/*-------------------------------------------------------------------------*/
241 427
242static int enable_periodic (struct ehci_hcd *ehci) 428static int enable_periodic (struct ehci_hcd *ehci)
@@ -481,7 +667,7 @@ static int check_intr_schedule (
481) 667)
482{ 668{
483 int retval = -ENOSPC; 669 int retval = -ENOSPC;
484 u8 mask; 670 u8 mask = 0;
485 671
486 if (qh->c_usecs && uframe >= 6) /* FSTN territory? */ 672 if (qh->c_usecs && uframe >= 6) /* FSTN territory? */
487 goto done; 673 goto done;
@@ -494,6 +680,24 @@ static int check_intr_schedule (
494 goto done; 680 goto done;
495 } 681 }
496 682
683#ifdef CONFIG_USB_EHCI_TT_NEWSCHED
684 if (tt_available (ehci, qh->period, qh->dev, frame, uframe,
685 qh->tt_usecs)) {
686 unsigned i;
687
688 /* TODO : this may need FSTN for SSPLIT in uframe 5. */
689 for (i=uframe+1; i<8 && i<uframe+4; i++)
690 if (!check_period (ehci, frame, i,
691 qh->period, qh->c_usecs))
692 goto done;
693 else
694 mask |= 1 << i;
695
696 retval = 0;
697
698 *c_maskp = cpu_to_le32 (mask << 8);
699 }
700#else
497 /* Make sure this tt's buffer is also available for CSPLITs. 701 /* Make sure this tt's buffer is also available for CSPLITs.
498 * We pessimize a bit; probably the typical full speed case 702 * We pessimize a bit; probably the typical full speed case
499 * doesn't need the second CSPLIT. 703 * doesn't need the second CSPLIT.
@@ -514,6 +718,7 @@ static int check_intr_schedule (
514 goto done; 718 goto done;
515 retval = 0; 719 retval = 0;
516 } 720 }
721#endif
517done: 722done:
518 return retval; 723 return retval;
519} 724}
@@ -1047,12 +1252,21 @@ sitd_slot_ok (
1047 frame = uframe >> 3; 1252 frame = uframe >> 3;
1048 uf = uframe & 7; 1253 uf = uframe & 7;
1049 1254
1255#ifdef CONFIG_USB_EHCI_TT_NEWSCHED
1256 /* The tt's fullspeed bus bandwidth must be available.
1257 * tt_available scheduling guarantees 10+% for control/bulk.
1258 */
1259 if (!tt_available (ehci, period_uframes << 3,
1260 stream->udev, frame, uf, stream->tt_usecs))
1261 return 0;
1262#else
1050 /* tt must be idle for start(s), any gap, and csplit. 1263 /* tt must be idle for start(s), any gap, and csplit.
1051 * assume scheduling slop leaves 10+% for control/bulk. 1264 * assume scheduling slop leaves 10+% for control/bulk.
1052 */ 1265 */
1053 if (!tt_no_collision (ehci, period_uframes << 3, 1266 if (!tt_no_collision (ehci, period_uframes << 3,
1054 stream->udev, frame, mask)) 1267 stream->udev, frame, mask))
1055 return 0; 1268 return 0;
1269#endif
1056 1270
1057 /* check starts (OUT uses more than one) */ 1271 /* check starts (OUT uses more than one) */
1058 max_used = 100 - stream->usecs; 1272 max_used = 100 - stream->usecs;