View | Details | Raw Unified | Return to bug 257082 | Differences between
and this patch

Collapse All | Expand All

(-)b/sys/dev/usb/controller/atmegadci.c (-35 / +2 lines)
Lines 1421-1427 static void Link Here
1421
atmegadci_device_isoc_fs_enter(struct usb_xfer *xfer)
1421
atmegadci_device_isoc_fs_enter(struct usb_xfer *xfer)
1422
{
1422
{
1423
	struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus);
1423
	struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus);
1424
	uint32_t temp;
1425
	uint32_t nframes;
1424
	uint32_t nframes;
1426
1425
1427
	DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
1426
	DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
Lines 1433-1473 atmegadci_device_isoc_fs_enter(struct usb_xfer *xfer) Link Here
1433
	    (ATMEGA_READ_1(sc, ATMEGA_UDFNUMH) << 8) |
1432
	    (ATMEGA_READ_1(sc, ATMEGA_UDFNUMH) << 8) |
1434
	    (ATMEGA_READ_1(sc, ATMEGA_UDFNUML));
1433
	    (ATMEGA_READ_1(sc, ATMEGA_UDFNUML));
1435
1434
1436
	nframes &= ATMEGA_FRAME_MASK;
1435
	if (usbd_xfer_get_isochronous_start_frame(
1437
1436
	    xfer, nframes, 1, ATMEGA_FRAME_MASK, NULL))
1438
	/*
1439
	 * check if the frame index is within the window where the frames
1440
	 * will be inserted
1441
	 */
1442
	temp = (nframes - xfer->endpoint->isoc_next) & ATMEGA_FRAME_MASK;
1443
1444
	if ((xfer->endpoint->is_synced == 0) ||
1445
	    (temp < xfer->nframes)) {
1446
		/*
1447
		 * If there is data underflow or the pipe queue is
1448
		 * empty we schedule the transfer a few frames ahead
1449
		 * of the current frame position. Else two isochronous
1450
		 * transfers might overlap.
1451
		 */
1452
		xfer->endpoint->isoc_next = (nframes + 3) & ATMEGA_FRAME_MASK;
1453
		xfer->endpoint->is_synced = 1;
1454
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
1437
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
1455
	}
1456
	/*
1457
	 * compute how many milliseconds the insertion is ahead of the
1458
	 * current frame position:
1459
	 */
1460
	temp = (xfer->endpoint->isoc_next - nframes) & ATMEGA_FRAME_MASK;
1461
1462
	/*
1463
	 * pre-compute when the isochronous transfer will be finished:
1464
	 */
1465
	xfer->isoc_time_complete =
1466
	    usb_isoc_time_expand(&sc->sc_bus, nframes) + temp +
1467
	    xfer->nframes;
1468
1469
	/* compute frame number for next insertion */
1470
	xfer->endpoint->isoc_next += xfer->nframes;
1471
1438
1472
	/* setup TDs */
1439
	/* setup TDs */
1473
	atmegadci_setup_standard_chain(xfer);
1440
	atmegadci_setup_standard_chain(xfer);
(-)b/sys/dev/usb/controller/avr32dci.c (-35 / +8 lines)
Lines 1355-1361 static void Link Here
1355
avr32dci_device_isoc_fs_enter(struct usb_xfer *xfer)
1355
avr32dci_device_isoc_fs_enter(struct usb_xfer *xfer)
1356
{
1356
{
1357
	struct avr32dci_softc *sc = AVR32_BUS2SC(xfer->xroot->bus);
1357
	struct avr32dci_softc *sc = AVR32_BUS2SC(xfer->xroot->bus);
1358
	uint32_t temp;
1359
	uint32_t nframes;
1358
	uint32_t nframes;
1360
	uint8_t ep_no;
1359
	uint8_t ep_no;
1361
1360
Lines 1366-1406 avr32dci_device_isoc_fs_enter(struct usb_xfer *xfer) Link Here
1366
	ep_no = xfer->endpointno & UE_ADDR;
1365
	ep_no = xfer->endpointno & UE_ADDR;
1367
	nframes = (AVR32_READ_4(sc, AVR32_FNUM) / 8);
1366
	nframes = (AVR32_READ_4(sc, AVR32_FNUM) / 8);
1368
1367
1369
	nframes &= AVR32_FRAME_MASK;
1368
	if (usbd_xfer_get_isochronous_start_frame(
1370
1369
	    xfer, nframes, 1, AVR32_FRAME_MASK, NULL))
1371
	/*
1372
	 * check if the frame index is within the window where the frames
1373
	 * will be inserted
1374
	 */
1375
	temp = (nframes - xfer->endpoint->isoc_next) & AVR32_FRAME_MASK;
1376
1377
	if ((xfer->endpoint->is_synced == 0) ||
1378
	    (temp < xfer->nframes)) {
1379
		/*
1380
		 * If there is data underflow or the pipe queue is
1381
		 * empty we schedule the transfer a few frames ahead
1382
		 * of the current frame position. Else two isochronous
1383
		 * transfers might overlap.
1384
		 */
1385
		xfer->endpoint->isoc_next = (nframes + 3) & AVR32_FRAME_MASK;
1386
		xfer->endpoint->is_synced = 1;
1387
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
1370
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
1388
	}
1389
	/*
1390
	 * compute how many milliseconds the insertion is ahead of the
1391
	 * current frame position:
1392
	 */
1393
	temp = (xfer->endpoint->isoc_next - nframes) & AVR32_FRAME_MASK;
1394
1395
	/*
1396
	 * pre-compute when the isochronous transfer will be finished:
1397
	 */
1398
	xfer->isoc_time_complete =
1399
	    usb_isoc_time_expand(&sc->sc_bus, nframes) + temp +
1400
	    xfer->nframes;
1401
1402
	/* compute frame number for next insertion */
1403
	xfer->endpoint->isoc_next += xfer->nframes;
1404
1371
1405
	/* setup TDs */
1372
	/* setup TDs */
1406
	avr32dci_setup_standard_chain(xfer);
1373
	avr32dci_setup_standard_chain(xfer);
Lines 1690-1695 avr32dci_roothub_exec(struct usb_device *udev, Link Here
1690
		len = sizeof(avr32dci_devd);
1657
		len = sizeof(avr32dci_devd);
1691
		ptr = (const void *)&avr32dci_devd;
1658
		ptr = (const void *)&avr32dci_devd;
1692
		goto tr_valid;
1659
		goto tr_valid;
1660
	case UDESC_DEVICE_QUALIFIER:
1661
		if (value & 0xff)
1662
			goto tr_stalled;
1663
		len = sizeof(avr32dci_odevd);
1664
		ptr = (const void *)&avr32dci_odevd;
1665
		goto tr_valid;
1693
	case UDESC_CONFIG:
1666
	case UDESC_CONFIG:
1694
		if (value & 0xff) {
1667
		if (value & 0xff) {
1695
			goto tr_stalled;
1668
			goto tr_stalled;
(-)b/sys/dev/usb/controller/dwc_otg.c (-43 / +2 lines)
Lines 4189-4197 dwc_otg_device_isoc_start(struct usb_xfer *xfer) Link Here
4189
{
4189
{
4190
	struct dwc_otg_softc *sc = DWC_OTG_BUS2SC(xfer->xroot->bus);
4190
	struct dwc_otg_softc *sc = DWC_OTG_BUS2SC(xfer->xroot->bus);
4191
	uint32_t temp;
4191
	uint32_t temp;
4192
	uint32_t msframes;
4193
	uint32_t framenum;
4192
	uint32_t framenum;
4194
	uint8_t shift = usbd_xfer_get_fps_shift(xfer);
4195
4193
4196
	DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
4194
	DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
4197
	    xfer, xfer->endpoint->isoc_next, xfer->nframes);
4195
	    xfer, xfer->endpoint->isoc_next, xfer->nframes);
Lines 4214-4265 dwc_otg_device_isoc_start(struct usb_xfer *xfer) Link Here
4214
	if (sc->sc_flags.status_high_speed)
4212
	if (sc->sc_flags.status_high_speed)
4215
		framenum /= 8;
4213
		framenum /= 8;
4216
4214
4217
	framenum &= DWC_OTG_FRAME_MASK;
4215
	if (usbd_xfer_get_isochronous_start_frame(
4218
4216
	    xfer, framenum, 1, DWC_OTG_FRAME_MASK, NULL))
4219
	/*
4220
	 * Compute number of milliseconds worth of data traffic for
4221
	 * this USB transfer:
4222
	 */ 
4223
	if (xfer->xroot->udev->speed == USB_SPEED_HIGH)
4224
		msframes = ((xfer->nframes << shift) + 7) / 8;
4225
	else
4226
		msframes = xfer->nframes;
4227
4228
	/*
4229
	 * check if the frame index is within the window where the frames
4230
	 * will be inserted
4231
	 */
4232
	temp = (framenum - xfer->endpoint->isoc_next) & DWC_OTG_FRAME_MASK;
4233
4234
	if ((xfer->endpoint->is_synced == 0) || (temp < msframes)) {
4235
		/*
4236
		 * If there is data underflow or the pipe queue is
4237
		 * empty we schedule the transfer a few frames ahead
4238
		 * of the current frame position. Else two isochronous
4239
		 * transfers might overlap.
4240
		 */
4241
		xfer->endpoint->isoc_next = (framenum + 3) & DWC_OTG_FRAME_MASK;
4242
		xfer->endpoint->is_synced = 1;
4243
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
4217
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
4244
	}
4245
	/*
4246
	 * compute how many milliseconds the insertion is ahead of the
4247
	 * current frame position:
4248
	 */
4249
	temp = (xfer->endpoint->isoc_next - framenum) & DWC_OTG_FRAME_MASK;
4250
4251
	/*
4252
	 * pre-compute when the isochronous transfer will be finished:
4253
	 */
4254
	xfer->isoc_time_complete =
4255
		usb_isoc_time_expand(&sc->sc_bus, framenum) + temp + msframes;
4256
4218
4257
	/* setup TDs */
4219
	/* setup TDs */
4258
	dwc_otg_setup_standard_chain(xfer);
4220
	dwc_otg_setup_standard_chain(xfer);
4259
4221
4260
	/* compute frame number for next insertion */
4261
	xfer->endpoint->isoc_next += msframes;
4262
4263
	/* start TD chain */
4222
	/* start TD chain */
4264
	dwc_otg_start_standard_chain(xfer);
4223
	dwc_otg_start_standard_chain(xfer);
4265
}
4224
}
(-)b/sys/dev/usb/controller/ehci.c (-82 / +14 lines)
Lines 2440-2445 ehci_device_isoc_fs_enter(struct usb_xfer *xfer) Link Here
2440
	uint32_t *plen;
2440
	uint32_t *plen;
2441
	uint32_t buf_offset;
2441
	uint32_t buf_offset;
2442
	uint32_t nframes;
2442
	uint32_t nframes;
2443
	uint32_t startframe;
2443
	uint32_t temp;
2444
	uint32_t temp;
2444
	uint32_t sitd_mask;
2445
	uint32_t sitd_mask;
2445
	uint16_t tlen;
2446
	uint16_t tlen;
Lines 2458-2496 ehci_device_isoc_fs_enter(struct usb_xfer *xfer) Link Here
2458
2459
2459
	nframes = EOREAD4(sc, EHCI_FRINDEX) / 8;
2460
	nframes = EOREAD4(sc, EHCI_FRINDEX) / 8;
2460
2461
2461
	/*
2462
	if (usbd_xfer_get_isochronous_start_frame(
2462
	 * check if the frame index is within the window where the frames
2463
	    xfer, nframes, 1, EHCI_VIRTUAL_FRAMELIST_COUNT - 1, &startframe))
2463
	 * will be inserted
2464
		DPRINTFN(3, "start next=%d\n", startframe);
2464
	 */
2465
	buf_offset = (nframes - xfer->endpoint->isoc_next) &
2466
	    (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
2467
2468
	if ((xfer->endpoint->is_synced == 0) ||
2469
	    (buf_offset < xfer->nframes)) {
2470
		/*
2471
		 * If there is data underflow or the pipe queue is empty we
2472
		 * schedule the transfer a few frames ahead of the current
2473
		 * frame position. Else two isochronous transfers might
2474
		 * overlap.
2475
		 */
2476
		xfer->endpoint->isoc_next = (nframes + 3) &
2477
		    (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
2478
		xfer->endpoint->is_synced = 1;
2479
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
2480
	}
2481
	/*
2482
	 * compute how many milliseconds the insertion is ahead of the
2483
	 * current frame position:
2484
	 */
2485
	buf_offset = (xfer->endpoint->isoc_next - nframes) &
2486
	    (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
2487
2488
	/*
2489
	 * pre-compute when the isochronous transfer will be finished:
2490
	 */
2491
	xfer->isoc_time_complete =
2492
	    usb_isoc_time_expand(&sc->sc_bus, nframes) +
2493
	    buf_offset + xfer->nframes;
2494
2465
2495
	/* get the real number of frames */
2466
	/* get the real number of frames */
2496
2467
Lines 2507-2517 ehci_device_isoc_fs_enter(struct usb_xfer *xfer) Link Here
2507
	td = xfer->td_start[xfer->flags_int.curr_dma_set];
2478
	td = xfer->td_start[xfer->flags_int.curr_dma_set];
2508
	xfer->td_transfer_first = td;
2479
	xfer->td_transfer_first = td;
2509
2480
2510
	pp_last = &sc->sc_isoc_fs_p_last[xfer->endpoint->isoc_next];
2481
	pp_last = &sc->sc_isoc_fs_p_last[startframe];
2511
2482
2512
	/* store starting position */
2483
	/* store starting position */
2513
2484
2514
	xfer->qh_pos = xfer->endpoint->isoc_next;
2485
	xfer->qh_pos = startframe;
2515
2486
2516
	while (nframes--) {
2487
	while (nframes--) {
2517
		if (td == NULL) {
2488
		if (td == NULL) {
Lines 2633-2642 ehci_device_isoc_fs_enter(struct usb_xfer *xfer) Link Here
2633
2604
2634
	xfer->td_transfer_last = td_last;
2605
	xfer->td_transfer_last = td_last;
2635
2606
2636
	/* update isoc_next */
2637
	xfer->endpoint->isoc_next = (pp_last - &sc->sc_isoc_fs_p_last[0]) &
2638
	    (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
2639
2640
	/*
2607
	/*
2641
	 * We don't allow cancelling of the SPLIT transaction USB FULL
2608
	 * We don't allow cancelling of the SPLIT transaction USB FULL
2642
	 * speed transfer, because it disturbs the bandwidth
2609
	 * speed transfer, because it disturbs the bandwidth
Lines 2743-2753 ehci_device_isoc_hs_enter(struct usb_xfer *xfer) Link Here
2743
	uint32_t status;
2710
	uint32_t status;
2744
	uint32_t buf_offset;
2711
	uint32_t buf_offset;
2745
	uint32_t nframes;
2712
	uint32_t nframes;
2713
	uint32_t startframe;
2746
	uint32_t itd_offset[8 + 1];
2714
	uint32_t itd_offset[8 + 1];
2747
	uint8_t x;
2715
	uint8_t x;
2748
	uint8_t td_no;
2716
	uint8_t td_no;
2749
	uint8_t page_no;
2717
	uint8_t page_no;
2750
	uint8_t shift = usbd_xfer_get_fps_shift(xfer);
2751
2718
2752
#ifdef USB_DEBUG
2719
#ifdef USB_DEBUG
2753
	uint8_t once = 1;
2720
	uint8_t once = 1;
Lines 2755-2801 ehci_device_isoc_hs_enter(struct usb_xfer *xfer) Link Here
2755
#endif
2722
#endif
2756
2723
2757
	DPRINTFN(6, "xfer=%p next=%d nframes=%d shift=%d\n",
2724
	DPRINTFN(6, "xfer=%p next=%d nframes=%d shift=%d\n",
2758
	    xfer, xfer->endpoint->isoc_next, xfer->nframes, (int)shift);
2725
	    xfer, xfer->endpoint->isoc_next, xfer->nframes,
2726
	    usbd_xfer_get_fps_shift(xfer));
2759
2727
2760
	/* get the current frame index */
2728
	/* get the current frame index */
2761
2729
2762
	nframes = EOREAD4(sc, EHCI_FRINDEX) / 8;
2730
	nframes = EOREAD4(sc, EHCI_FRINDEX) / 8;
2763
2731
2764
	/*
2732
	if (usbd_xfer_get_isochronous_start_frame(
2765
	 * check if the frame index is within the window where the frames
2733
	    xfer, nframes, 1, EHCI_VIRTUAL_FRAMELIST_COUNT - 1, &startframe))
2766
	 * will be inserted
2734
		DPRINTFN(3, "start next=%d\n", startframe);
2767
	 */
2768
	buf_offset = (nframes - xfer->endpoint->isoc_next) &
2769
	    (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
2770
2771
	if ((xfer->endpoint->is_synced == 0) ||
2772
	    (buf_offset < (((xfer->nframes << shift) + 7) / 8))) {
2773
		/*
2774
		 * If there is data underflow or the pipe queue is empty we
2775
		 * schedule the transfer a few frames ahead of the current
2776
		 * frame position. Else two isochronous transfers might
2777
		 * overlap.
2778
		 */
2779
		xfer->endpoint->isoc_next = (nframes + 3) &
2780
		    (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
2781
		xfer->endpoint->is_synced = 1;
2782
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
2783
	}
2784
	/*
2785
	 * compute how many milliseconds the insertion is ahead of the
2786
	 * current frame position:
2787
	 */
2788
	buf_offset = (xfer->endpoint->isoc_next - nframes) &
2789
	    (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
2790
2791
	/*
2792
	 * pre-compute when the isochronous transfer will be finished:
2793
	 */
2794
	xfer->isoc_time_complete =
2795
	    usb_isoc_time_expand(&sc->sc_bus, nframes) + buf_offset +
2796
	    (((xfer->nframes << shift) + 7) / 8);
2797
2798
	/* get the real number of frames */
2799
2735
2800
	nframes = xfer->nframes;
2736
	nframes = xfer->nframes;
2801
2737
Lines 2811-2821 ehci_device_isoc_hs_enter(struct usb_xfer *xfer) Link Here
2811
	td = xfer->td_start[xfer->flags_int.curr_dma_set];
2747
	td = xfer->td_start[xfer->flags_int.curr_dma_set];
2812
	xfer->td_transfer_first = td;
2748
	xfer->td_transfer_first = td;
2813
2749
2814
	pp_last = &sc->sc_isoc_hs_p_last[xfer->endpoint->isoc_next];
2750
	pp_last = &sc->sc_isoc_hs_p_last[startframe];
2815
2751
2816
	/* store starting position */
2752
	/* store starting position */
2817
2753
2818
	xfer->qh_pos = xfer->endpoint->isoc_next;
2754
	xfer->qh_pos = startframe;
2819
2755
2820
	while (nframes) {
2756
	while (nframes) {
2821
		if (td == NULL) {
2757
		if (td == NULL) {
Lines 2927-2936 ehci_device_isoc_hs_enter(struct usb_xfer *xfer) Link Here
2927
	}
2863
	}
2928
2864
2929
	xfer->td_transfer_last = td_last;
2865
	xfer->td_transfer_last = td_last;
2930
2931
	/* update isoc_next */
2932
	xfer->endpoint->isoc_next = (pp_last - &sc->sc_isoc_hs_p_last[0]) &
2933
	    (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
2934
}
2866
}
2935
2867
2936
static void
2868
static void
(-)b/sys/dev/usb/controller/musb_otg.c (-40 / +2 lines)
Lines 3436-3444 static void Link Here
3436
musbotg_device_isoc_enter(struct usb_xfer *xfer)
3436
musbotg_device_isoc_enter(struct usb_xfer *xfer)
3437
{
3437
{
3438
	struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
3438
	struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
3439
	uint32_t temp;
3440
	uint32_t nframes;
3439
	uint32_t nframes;
3441
	uint32_t fs_frames;
3442
3440
3443
	DPRINTFN(5, "xfer=%p next=%d nframes=%d\n",
3441
	DPRINTFN(5, "xfer=%p next=%d nframes=%d\n",
3444
	    xfer, xfer->endpoint->isoc_next, xfer->nframes);
3442
	    xfer, xfer->endpoint->isoc_next, xfer->nframes);
Lines 3447-3491 musbotg_device_isoc_enter(struct usb_xfer *xfer) Link Here
3447
3445
3448
	nframes = MUSB2_READ_2(sc, MUSB2_REG_FRAME);
3446
	nframes = MUSB2_READ_2(sc, MUSB2_REG_FRAME);
3449
3447
3450
	/*
3448
	if (usbd_xfer_get_isochronous_start_frame(
3451
	 * check if the frame index is within the window where the frames
3449
	    xfer, nframes, 1, MUSB2_MASK_FRAME, NULL))
3452
	 * will be inserted
3453
	 */
3454
	temp = (nframes - xfer->endpoint->isoc_next) & MUSB2_MASK_FRAME;
3455
3456
	if (usbd_get_speed(xfer->xroot->udev) == USB_SPEED_HIGH) {
3457
		fs_frames = (xfer->nframes + 7) / 8;
3458
	} else {
3459
		fs_frames = xfer->nframes;
3460
	}
3461
3462
	if ((xfer->endpoint->is_synced == 0) ||
3463
	    (temp < fs_frames)) {
3464
		/*
3465
		 * If there is data underflow or the pipe queue is
3466
		 * empty we schedule the transfer a few frames ahead
3467
		 * of the current frame position. Else two isochronous
3468
		 * transfers might overlap.
3469
		 */
3470
		xfer->endpoint->isoc_next = (nframes + 3) & MUSB2_MASK_FRAME;
3471
		xfer->endpoint->is_synced = 1;
3472
		DPRINTFN(2, "start next=%d\n", xfer->endpoint->isoc_next);
3450
		DPRINTFN(2, "start next=%d\n", xfer->endpoint->isoc_next);
3473
	}
3474
	/*
3475
	 * compute how many milliseconds the insertion is ahead of the
3476
	 * current frame position:
3477
	 */
3478
	temp = (xfer->endpoint->isoc_next - nframes) & MUSB2_MASK_FRAME;
3479
3480
	/*
3481
	 * pre-compute when the isochronous transfer will be finished:
3482
	 */
3483
	xfer->isoc_time_complete =
3484
	    usb_isoc_time_expand(&sc->sc_bus, nframes) + temp +
3485
	    fs_frames;
3486
3487
	/* compute frame number for next insertion */
3488
	xfer->endpoint->isoc_next += fs_frames;
3489
3451
3490
	/* setup TDs */
3452
	/* setup TDs */
3491
	musbotg_setup_standard_chain(xfer);
3453
	musbotg_setup_standard_chain(xfer);
(-)b/sys/dev/usb/controller/ohci.c (-27 / +6 lines)
Lines 1824-1829 ohci_device_isoc_enter(struct usb_xfer *xfer) Link Here
1824
	struct ohci_hcca *hcca;
1824
	struct ohci_hcca *hcca;
1825
	uint32_t buf_offset;
1825
	uint32_t buf_offset;
1826
	uint32_t nframes;
1826
	uint32_t nframes;
1827
	uint32_t startframe;
1827
	uint32_t ed_flags;
1828
	uint32_t ed_flags;
1828
	uint32_t *plen;
1829
	uint32_t *plen;
1829
	uint16_t itd_offset[OHCI_ITD_NOFFSET];
1830
	uint16_t itd_offset[OHCI_ITD_NOFFSET];
Lines 1840-1870 ohci_device_isoc_enter(struct usb_xfer *xfer) Link Here
1840
	DPRINTFN(6, "xfer=%p isoc_next=%u nframes=%u hcca_fn=%u\n",
1841
	DPRINTFN(6, "xfer=%p isoc_next=%u nframes=%u hcca_fn=%u\n",
1841
	    xfer, xfer->endpoint->isoc_next, xfer->nframes, nframes);
1842
	    xfer, xfer->endpoint->isoc_next, xfer->nframes, nframes);
1842
1843
1843
	if ((xfer->endpoint->is_synced == 0) ||
1844
	if (usbd_xfer_get_isochronous_start_frame(
1844
	    (((nframes - xfer->endpoint->isoc_next) & 0xFFFF) < xfer->nframes) ||
1845
	    xfer, nframes, 1, 0xFFFF, &startframe))
1845
	    (((xfer->endpoint->isoc_next - nframes) & 0xFFFF) >= 128)) {
1846
		DPRINTFN(3, "start next=%d\n", startframe);
1846
		/*
1847
		 * If there is data underflow or the pipe queue is empty we
1848
		 * schedule the transfer a few frames ahead of the current
1849
		 * frame position. Else two isochronous transfers might
1850
		 * overlap.
1851
		 */
1852
		xfer->endpoint->isoc_next = (nframes + 3) & 0xFFFF;
1853
		xfer->endpoint->is_synced = 1;
1854
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
1855
	}
1856
	/*
1857
	 * compute how many milliseconds the insertion is ahead of the
1858
	 * current frame position:
1859
	 */
1860
	buf_offset = ((xfer->endpoint->isoc_next - nframes) & 0xFFFF);
1861
1862
	/*
1863
	 * pre-compute when the isochronous transfer will be finished:
1864
	 */
1865
	xfer->isoc_time_complete =
1866
	    (usb_isoc_time_expand(&sc->sc_bus, nframes) + buf_offset +
1867
	    xfer->nframes);
1868
1847
1869
	/* get the real number of frames */
1848
	/* get the real number of frames */
1870
1849
Lines 1905-1916 ohci_device_isoc_enter(struct usb_xfer *xfer) Link Here
1905
			/* fill current ITD */
1884
			/* fill current ITD */
1906
			td->itd_flags = htole32(
1885
			td->itd_flags = htole32(
1907
			    OHCI_ITD_NOCC |
1886
			    OHCI_ITD_NOCC |
1908
			    OHCI_ITD_SET_SF(xfer->endpoint->isoc_next) |
1887
			    OHCI_ITD_SET_SF(startframe) |
1909
			    OHCI_ITD_NOINTR |
1888
			    OHCI_ITD_NOINTR |
1910
			    OHCI_ITD_SET_FC(ncur));
1889
			    OHCI_ITD_SET_FC(ncur));
1911
1890
1912
			td->frames = ncur;
1891
			td->frames = ncur;
1913
			xfer->endpoint->isoc_next += ncur;
1892
			startframe += ncur;
1914
1893
1915
			if (length == 0) {
1894
			if (length == 0) {
1916
				/* all zero */
1895
				/* all zero */
(-)b/sys/dev/usb/controller/saf1761_otg.c (-66 / +4 lines)
Lines 2632-2638 static void Link Here
2632
saf1761_otg_device_isoc_enter(struct usb_xfer *xfer)
2632
saf1761_otg_device_isoc_enter(struct usb_xfer *xfer)
2633
{
2633
{
2634
	struct saf1761_otg_softc *sc = SAF1761_OTG_BUS2SC(xfer->xroot->bus);
2634
	struct saf1761_otg_softc *sc = SAF1761_OTG_BUS2SC(xfer->xroot->bus);
2635
	uint32_t temp;
2636
	uint32_t nframes;
2635
	uint32_t nframes;
2637
2636
2638
	DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
2637
	DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
Lines 2642-2680 saf1761_otg_device_isoc_enter(struct usb_xfer *xfer) Link Here
2642
2641
2643
	nframes = SAF1761_READ_LE_4(sc, SOTG_FRAME_NUM);
2642
	nframes = SAF1761_READ_LE_4(sc, SOTG_FRAME_NUM);
2644
2643
2645
	/*
2644
	if (usbd_xfer_get_isochronous_start_frame(
2646
	 * check if the frame index is within the window where the
2645
	    xfer, nframes, 1, SOTG_FRAME_NUM_SOFR_MASK, NULL))
2647
	 * frames will be inserted
2648
	 */
2649
	temp = (nframes - xfer->endpoint->isoc_next) & SOTG_FRAME_NUM_SOFR_MASK;
2650
2651
	if ((xfer->endpoint->is_synced == 0) ||
2652
	    (temp < xfer->nframes)) {
2653
		/*
2654
		 * If there is data underflow or the pipe queue is
2655
		 * empty we schedule the transfer a few frames ahead
2656
		 * of the current frame position. Else two isochronous
2657
		 * transfers might overlap.
2658
		 */
2659
		xfer->endpoint->isoc_next = (nframes + 3) & SOTG_FRAME_NUM_SOFR_MASK;
2660
		xfer->endpoint->is_synced = 1;
2661
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
2646
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
2662
	}
2663
	/*
2664
	 * compute how many milliseconds the insertion is ahead of the
2665
	 * current frame position:
2666
	 */
2667
	temp = (xfer->endpoint->isoc_next - nframes) & SOTG_FRAME_NUM_SOFR_MASK;
2668
2669
	/*
2670
	 * pre-compute when the isochronous transfer will be finished:
2671
	 */
2672
	xfer->isoc_time_complete =
2673
	    usb_isoc_time_expand(&sc->sc_bus, nframes) + temp +
2674
	    xfer->nframes;
2675
2676
	/* compute frame number for next insertion */
2677
	xfer->endpoint->isoc_next += xfer->nframes;
2678
2647
2679
	/* setup TDs */
2648
	/* setup TDs */
2680
	saf1761_otg_setup_standard_chain(xfer);
2649
	saf1761_otg_setup_standard_chain(xfer);
Lines 2714-2720 static void Link Here
2714
saf1761_otg_host_isoc_enter(struct usb_xfer *xfer)
2683
saf1761_otg_host_isoc_enter(struct usb_xfer *xfer)
2715
{
2684
{
2716
	struct saf1761_otg_softc *sc = SAF1761_OTG_BUS2SC(xfer->xroot->bus);
2685
	struct saf1761_otg_softc *sc = SAF1761_OTG_BUS2SC(xfer->xroot->bus);
2717
	uint32_t temp;
2718
	uint32_t nframes;
2686
	uint32_t nframes;
2719
2687
2720
	DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
2688
	DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
Lines 2724-2762 saf1761_otg_host_isoc_enter(struct usb_xfer *xfer) Link Here
2724
2692
2725
	nframes = (SAF1761_READ_LE_4(sc, SOTG_FRINDEX) & SOTG_FRINDEX_MASK) >> 3;
2693
	nframes = (SAF1761_READ_LE_4(sc, SOTG_FRINDEX) & SOTG_FRINDEX_MASK) >> 3;
2726
2694
2727
	/*
2695
	if (usbd_xfer_get_isochronous_start_frame(
2728
	 * check if the frame index is within the window where the
2696
	    xfer, nframes, 1, SOTG_FRINDEX_MASK >> 3, NULL))
2729
	 * frames will be inserted
2730
	 */
2731
	temp = (nframes - xfer->endpoint->isoc_next) & (SOTG_FRINDEX_MASK >> 3);
2732
2733
	if ((xfer->endpoint->is_synced == 0) ||
2734
	    (temp < xfer->nframes)) {
2735
		/*
2736
		 * If there is data underflow or the pipe queue is
2737
		 * empty we schedule the transfer a few frames ahead
2738
		 * of the current frame position. Else two isochronous
2739
		 * transfers might overlap.
2740
		 */
2741
		xfer->endpoint->isoc_next = (nframes + 3) & (SOTG_FRINDEX_MASK >> 3);
2742
		xfer->endpoint->is_synced = 1;
2743
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
2697
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
2744
	}
2745
	/*
2746
	 * compute how many milliseconds the insertion is ahead of the
2747
	 * current frame position:
2748
	 */
2749
	temp = (xfer->endpoint->isoc_next - nframes) & (SOTG_FRINDEX_MASK >> 3);
2750
2751
	/*
2752
	 * pre-compute when the isochronous transfer will be finished:
2753
	 */
2754
	xfer->isoc_time_complete =
2755
	    usb_isoc_time_expand(&sc->sc_bus, nframes) + temp +
2756
	    xfer->nframes;
2757
2758
	/* compute frame number for next insertion */
2759
	xfer->endpoint->isoc_next += xfer->nframes;
2760
2698
2761
	/* setup TDs */
2699
	/* setup TDs */
2762
	saf1761_otg_setup_standard_chain(xfer);
2700
	saf1761_otg_setup_standard_chain(xfer);
(-)b/sys/dev/usb/controller/uhci.c (-35 / +6 lines)
Lines 2111-2117 uhci_device_isoc_enter(struct usb_xfer *xfer) Link Here
2111
	struct uhci_mem_layout ml;
2111
	struct uhci_mem_layout ml;
2112
	uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
2112
	uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
2113
	uint32_t nframes;
2113
	uint32_t nframes;
2114
	uint32_t temp;
2114
	uint32_t startframe;
2115
	uint32_t *plen;
2115
	uint32_t *plen;
2116
2116
2117
#ifdef USB_DEBUG
2117
#ifdef USB_DEBUG
Lines 2127-2160 uhci_device_isoc_enter(struct usb_xfer *xfer) Link Here
2127
2127
2128
	nframes = UREAD2(sc, UHCI_FRNUM);
2128
	nframes = UREAD2(sc, UHCI_FRNUM);
2129
2129
2130
	temp = (nframes - xfer->endpoint->isoc_next) &
2130
	if (usbd_xfer_get_isochronous_start_frame(
2131
	    (UHCI_VFRAMELIST_COUNT - 1);
2131
	    xfer, nframes, 1, UHCI_VFRAMELIST_COUNT - 1, &startframe))
2132
2132
		DPRINTFN(3, "start next=%d\n", startframe);
2133
	if ((xfer->endpoint->is_synced == 0) ||
2134
	    (temp < xfer->nframes)) {
2135
		/*
2136
		 * If there is data underflow or the pipe queue is empty we
2137
		 * schedule the transfer a few frames ahead of the current
2138
		 * frame position. Else two isochronous transfers might
2139
		 * overlap.
2140
		 */
2141
		xfer->endpoint->isoc_next = (nframes + 3) & (UHCI_VFRAMELIST_COUNT - 1);
2142
		xfer->endpoint->is_synced = 1;
2143
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
2144
	}
2145
	/*
2146
	 * compute how many milliseconds the insertion is ahead of the
2147
	 * current frame position:
2148
	 */
2149
	temp = (xfer->endpoint->isoc_next - nframes) &
2150
	    (UHCI_VFRAMELIST_COUNT - 1);
2151
2152
	/*
2153
	 * pre-compute when the isochronous transfer will be finished:
2154
	 */
2155
	xfer->isoc_time_complete =
2156
	    usb_isoc_time_expand(&sc->sc_bus, nframes) + temp +
2157
	    xfer->nframes;
2158
2133
2159
	/* get the real number of frames */
2134
	/* get the real number of frames */
2160
2135
Lines 2171-2181 uhci_device_isoc_enter(struct usb_xfer *xfer) Link Here
2171
	td = xfer->td_start[xfer->flags_int.curr_dma_set];
2146
	td = xfer->td_start[xfer->flags_int.curr_dma_set];
2172
	xfer->td_transfer_first = td;
2147
	xfer->td_transfer_first = td;
2173
2148
2174
	pp_last = &sc->sc_isoc_p_last[xfer->endpoint->isoc_next];
2149
	pp_last = &sc->sc_isoc_p_last[startframe];
2175
2150
2176
	/* store starting position */
2151
	/* store starting position */
2177
2152
2178
	xfer->qh_pos = xfer->endpoint->isoc_next;
2153
	xfer->qh_pos = startframe;
2179
2154
2180
	while (nframes--) {
2155
	while (nframes--) {
2181
		if (td == NULL) {
2156
		if (td == NULL) {
Lines 2252-2261 uhci_device_isoc_enter(struct usb_xfer *xfer) Link Here
2252
	}
2227
	}
2253
2228
2254
	xfer->td_transfer_last = td_last;
2229
	xfer->td_transfer_last = td_last;
2255
2256
	/* update isoc_next */
2257
	xfer->endpoint->isoc_next = (pp_last - &sc->sc_isoc_p_last[0]) &
2258
	    (UHCI_VFRAMELIST_COUNT - 1);
2259
}
2230
}
2260
2231
2261
static void
2232
static void
(-)b/sys/dev/usb/controller/uss820dci.c (-33 / +2 lines)
Lines 1706-1712 static void Link Here
1706
uss820dci_device_isoc_fs_enter(struct usb_xfer *xfer)
1706
uss820dci_device_isoc_fs_enter(struct usb_xfer *xfer)
1707
{
1707
{
1708
	struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
1708
	struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
1709
	uint32_t temp;
1710
	uint32_t nframes;
1709
	uint32_t nframes;
1711
1710
1712
	DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
1711
	DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
Lines 1716-1754 uss820dci_device_isoc_fs_enter(struct usb_xfer *xfer) Link Here
1716
1715
1717
	nframes = USS820_READ_1(sc, USS820_SOFL);
1716
	nframes = USS820_READ_1(sc, USS820_SOFL);
1718
1717
1719
	/*
1718
	if (usbd_xfer_get_isochronous_start_frame(
1720
	 * check if the frame index is within the window where the
1719
	    xfer, nframes, 1, USS820_SOFL_MASK, NULL))
1721
	 * frames will be inserted
1722
	 */
1723
	temp = (nframes - xfer->endpoint->isoc_next) & USS820_SOFL_MASK;
1724
1725
	if ((xfer->endpoint->is_synced == 0) ||
1726
	    (temp < xfer->nframes)) {
1727
		/*
1728
		 * If there is data underflow or the pipe queue is
1729
		 * empty we schedule the transfer a few frames ahead
1730
		 * of the current frame position. Else two isochronous
1731
		 * transfers might overlap.
1732
		 */
1733
		xfer->endpoint->isoc_next = (nframes + 3) & USS820_SOFL_MASK;
1734
		xfer->endpoint->is_synced = 1;
1735
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
1720
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
1736
	}
1737
	/*
1738
	 * compute how many milliseconds the insertion is ahead of the
1739
	 * current frame position:
1740
	 */
1741
	temp = (xfer->endpoint->isoc_next - nframes) & USS820_SOFL_MASK;
1742
1743
	/*
1744
	 * pre-compute when the isochronous transfer will be finished:
1745
	 */
1746
	xfer->isoc_time_complete =
1747
	    usb_isoc_time_expand(&sc->sc_bus, nframes) + temp +
1748
	    xfer->nframes;
1749
1750
	/* compute frame number for next insertion */
1751
	xfer->endpoint->isoc_next += xfer->nframes;
1752
1721
1753
	/* setup TDs */
1722
	/* setup TDs */
1754
	uss820dci_setup_standard_chain(xfer);
1723
	uss820dci_setup_standard_chain(xfer);
(-)b/sys/dev/usb/controller/xhci.c (-43 / +15 lines)
Lines 133-140 struct xhci_std_temp { Link Here
133
	uint32_t		offset;
133
	uint32_t		offset;
134
	uint32_t		max_packet_size;
134
	uint32_t		max_packet_size;
135
	uint32_t		average;
135
	uint32_t		average;
136
	uint32_t		isoc_frame;
136
	uint16_t		isoc_delta;
137
	uint16_t		isoc_delta;
137
	uint16_t		isoc_frame;
138
	uint8_t			shortpkt;
138
	uint8_t			shortpkt;
139
	uint8_t			multishort;
139
	uint8_t			multishort;
140
	uint8_t			last_frame;
140
	uint8_t			last_frame;
Lines 644-649 xhci_init(struct xhci_softc *sc, device_t self, uint8_t dma32) Link Here
644
644
645
	DPRINTF("HCS2=0x%08x\n", temp);
645
	DPRINTF("HCS2=0x%08x\n", temp);
646
646
647
	/* get isochronous scheduling threshold */
648
	sc->sc_ist = XHCI_HCS2_IST(temp);
649
647
	/* get number of scratchpads */
650
	/* get number of scratchpads */
648
	sc->sc_noscratch = XHCI_HCS2_SPB_MAX(temp);
651
	sc->sc_noscratch = XHCI_HCS2_SPB_MAX(temp);
649
652
Lines 2026-2032 xhci_setup_generic_chain(struct usb_xfer *xfer) Link Here
2026
	struct xhci_std_temp temp;
2029
	struct xhci_std_temp temp;
2027
	struct xhci_td *td;
2030
	struct xhci_td *td;
2028
	uint32_t x;
2031
	uint32_t x;
2029
	uint32_t y;
2030
	uint8_t mult;
2032
	uint8_t mult;
2031
2033
2032
	temp.do_isoc_sync = 0;
2034
	temp.do_isoc_sync = 0;
Lines 2075-2081 xhci_setup_generic_chain(struct usb_xfer *xfer) Link Here
2075
2077
2076
		x = XREAD4(temp.sc, runt, XHCI_MFINDEX);
2078
		x = XREAD4(temp.sc, runt, XHCI_MFINDEX);
2077
2079
2078
		DPRINTF("MFINDEX=0x%08x\n", x);
2080
		DPRINTF("MFINDEX=0x%08x IST=0x%x\n", x, sc->sc_ist);
2081
2082
		/* add isochronous scheduling threshold */
2083
		if (temp.sc->sc_ist & 8)
2084
			x += (temp.sc->sc_ist & 7) << 3;
2085
		else
2086
			x += (temp.sc->sc_ist & 7);
2079
2087
2080
		switch (usbd_get_speed(xfer->xroot->udev)) {
2088
		switch (usbd_get_speed(xfer->xroot->udev)) {
2081
		case USB_SPEED_FULL:
2089
		case USB_SPEED_FULL:
Lines 2089-2104 xhci_setup_generic_chain(struct usb_xfer *xfer) Link Here
2089
			temp.isoc_delta = 1U << shift;
2097
			temp.isoc_delta = 1U << shift;
2090
			x += temp.isoc_delta - 1;
2098
			x += temp.isoc_delta - 1;
2091
			x &= ~(temp.isoc_delta - 1);
2099
			x &= ~(temp.isoc_delta - 1);
2092
			/* simple frame load balancing */
2093
			x += xfer->endpoint->usb_uframe;
2094
			break;
2100
			break;
2095
		}
2101
		}
2096
2102
2097
		y = XHCI_MFINDEX_GET(x - xfer->endpoint->isoc_next);
2103
		if (usbd_xfer_get_isochronous_start_frame(
2098
2104
		    xfer, x, 8, XHCI_MFINDEX_GET(-1), &temp.isoc_frame)) {
2099
		if ((xfer->endpoint->is_synced == 0) ||
2100
		    (y < (xfer->nframes << shift)) ||
2101
		    (XHCI_MFINDEX_GET(-y) >= (128 * 8))) {
2102
			/*
2105
			/*
2103
			 * If there is data underflow or the pipe
2106
			 * If there is data underflow or the pipe
2104
			 * queue is empty we schedule the transfer a
2107
			 * queue is empty we schedule the transfer a
Lines 2106-2132 xhci_setup_generic_chain(struct usb_xfer *xfer) Link Here
2106
			 * position. Else two isochronous transfers
2109
			 * position. Else two isochronous transfers
2107
			 * might overlap.
2110
			 * might overlap.
2108
			 */
2111
			 */
2109
			xfer->endpoint->isoc_next = XHCI_MFINDEX_GET(x + (3 * 8));
2110
			xfer->endpoint->is_synced = 1;
2111
			temp.do_isoc_sync = 1;
2112
			temp.do_isoc_sync = 1;
2112
2113
2113
			DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
2114
			DPRINTFN(3, "start next=%d\n", temp.isoc_frame);
2114
		}
2115
		}
2115
2116
2116
		/* compute isochronous completion time */
2117
2118
		y = XHCI_MFINDEX_GET(xfer->endpoint->isoc_next - (x & ~7));
2119
2120
		xfer->isoc_time_complete =
2121
		    usb_isoc_time_expand(&temp.sc->sc_bus, x / 8) +
2122
		    (y / 8) + (((xfer->nframes << shift) + 7) / 8);
2123
2124
		x = 0;
2117
		x = 0;
2125
		temp.isoc_frame = xfer->endpoint->isoc_next;
2126
		temp.trb_type = XHCI_TRB_TYPE_ISOCH;
2118
		temp.trb_type = XHCI_TRB_TYPE_ISOCH;
2127
2119
2128
		xfer->endpoint->isoc_next += xfer->nframes << shift;
2129
2130
	} else if (xfer->flags_int.control_xfr) {
2120
	} else if (xfer->flags_int.control_xfr) {
2131
		/* check if we should prepend a setup message */
2121
		/* check if we should prepend a setup message */
2132
2122
Lines 3063-3077 xhci_device_done(struct usb_xfer *xfer, usb_error_t error) Link Here
3063
static void
3053
static void
3064
xhci_device_generic_open(struct usb_xfer *xfer)
3054
xhci_device_generic_open(struct usb_xfer *xfer)
3065
{
3055
{
3066
	if (xfer->flags_int.isochronous_xfr) {
3056
	DPRINTF("\n");
3067
		switch (xfer->xroot->udev->speed) {
3068
		case USB_SPEED_FULL:
3069
			break;
3070
		default:
3071
			usb_hs_bandwidth_alloc(xfer);
3072
			break;
3073
		}
3074
	}
3075
}
3057
}
3076
3058
3077
static void
3059
static void
Lines 3080-3095 xhci_device_generic_close(struct usb_xfer *xfer) Link Here
3080
	DPRINTF("\n");
3062
	DPRINTF("\n");
3081
3063
3082
	xhci_device_done(xfer, USB_ERR_CANCELLED);
3064
	xhci_device_done(xfer, USB_ERR_CANCELLED);
3083
3084
	if (xfer->flags_int.isochronous_xfr) {
3085
		switch (xfer->xroot->udev->speed) {
3086
		case USB_SPEED_FULL:
3087
			break;
3088
		default:
3089
			usb_hs_bandwidth_free(xfer);
3090
			break;
3091
		}
3092
	}
3093
}
3065
}
3094
3066
3095
static void
3067
static void
(-)b/sys/dev/usb/controller/xhci.h (-1 / +6 lines)
Lines 33-39 Link Here
33
#define	XHCI_MAX_DEVICES	MIN(USB_MAX_DEVICES, 128)
33
#define	XHCI_MAX_DEVICES	MIN(USB_MAX_DEVICES, 128)
34
#define	XHCI_MAX_ENDPOINTS	32	/* hardcoded - do not change */
34
#define	XHCI_MAX_ENDPOINTS	32	/* hardcoded - do not change */
35
#define	XHCI_MAX_SCRATCHPADS	256	/* theoretical max is 1023 */
35
#define	XHCI_MAX_SCRATCHPADS	256	/* theoretical max is 1023 */
36
#define	XHCI_MAX_EVENTS		(16 * 13)
36
#define	XHCI_MAX_EVENTS		232
37
#define	XHCI_MAX_COMMANDS	(16 * 1)
37
#define	XHCI_MAX_COMMANDS	(16 * 1)
38
#define	XHCI_MAX_RSEG		1
38
#define	XHCI_MAX_RSEG		1
39
#define	XHCI_MAX_TRANSFERS	4
39
#define	XHCI_MAX_TRANSFERS	4
Lines 383-388 struct xhci_hw_root { Link Here
383
	struct xhci_trb			hwr_commands[XHCI_MAX_COMMANDS];
383
	struct xhci_trb			hwr_commands[XHCI_MAX_COMMANDS];
384
};
384
};
385
385
386
CTASSERT(sizeof(struct xhci_hw_root) == XHCI_PAGE_SIZE);
387
386
struct xhci_endpoint_ext {
388
struct xhci_endpoint_ext {
387
	struct xhci_trb		*trb;
389
	struct xhci_trb		*trb;
388
	struct usb_xfer		*xfer[XHCI_MAX_TRANSFERS * XHCI_MAX_STREAMS];
390
	struct usb_xfer		*xfer[XHCI_MAX_TRANSFERS * XHCI_MAX_STREAMS];
Lines 527-532 struct xhci_softc { Link Here
527
	/* size of context */
529
	/* size of context */
528
	uint8_t			sc_ctx_is_64_byte;
530
	uint8_t			sc_ctx_is_64_byte;
529
531
532
	/* Isochronous Scheduling Threshold */
533
	uint8_t			sc_ist;
534
530
	/* vendor string for root HUB */
535
	/* vendor string for root HUB */
531
	char			sc_vendor[16];
536
	char			sc_vendor[16];
532
};
537
};
(-)b/sys/dev/usb/usb_transfer.c (+66 lines)
Lines 3680-3682 usbd_xfer_maxp_was_clamped(struct usb_xfer *xfer) Link Here
3680
{
3680
{
3681
	return (xfer->flags_int.maxp_was_clamped);
3681
	return (xfer->flags_int.maxp_was_clamped);
3682
}
3682
}
3683
3684
/*
3685
 * The following function computes the next isochronous frame number
3686
 * where the isochronous transfer shall be queued.
3687
 *
3688
 * The function returns non-zero if there was a discontinuity.
3689
 * Else zero is returned for normal operation.
3690
 */
3691
uint8_t
3692
usbd_xfer_get_isochronous_start_frame(struct usb_xfer *xfer, uint32_t frame_curr,
3693
    uint32_t frame_ms, uint32_t frame_mask, uint32_t *p_frame_start)
3694
{
3695
	uint32_t duration;
3696
	uint32_t delta;
3697
	uint8_t retval;
3698
	uint8_t shift;
3699
3700
	delta  = (xfer->endpoint->isoc_next - frame_curr) & frame_mask;
3701
3702
	/*
3703
	 * Check if it is the first transfer, the future frame delta
3704
	 * is less than one millisecond, or if the frame delta is
3705
	 * negative:
3706
	 */
3707
	if (xfer->endpoint->is_synced == 0 ||
3708
	    delta < frame_ms || delta > (frame_mask / 2)) {
3709
		xfer->endpoint->isoc_next = (frame_curr + frame_ms) & frame_mask;
3710
		xfer->endpoint->is_synced = 1;
3711
3712
		retval = 1;
3713
	} else {
3714
		retval = 0;
3715
	}
3716
3717
	/* Store start time, if any. */
3718
	if (p_frame_start != NULL)
3719
		*p_frame_start = xfer->endpoint->isoc_next & frame_mask;
3720
3721
	/* Get relative completion time, in milliseconds. */
3722
	delta = xfer->endpoint->isoc_next - frame_curr + (frame_curr % frame_ms);
3723
	delta &= frame_mask;
3724
	delta /= frame_ms;
3725
3726
	switch (usbd_get_speed(xfer->xroot->udev)) {
3727
	case USB_SPEED_FULL:
3728
		shift = 3;
3729
		break;
3730
	default:
3731
		shift = usbd_xfer_get_fps_shift(xfer);
3732
		break;
3733
	}
3734
3735
	/* Get duration in milliseconds */
3736
	duration = ((xfer->nframes << shift) + 7) / 8;
3737
3738
	/* Compute full 32-bit completion time, in milliseconds. */
3739
	xfer->isoc_time_complete =
3740
	    usb_isoc_time_expand(xfer->xroot->bus, frame_curr / frame_ms) +
3741
	    delta + duration;
3742
3743
	/* Compute next isochronous frame. */
3744
	xfer->endpoint->isoc_next += duration * frame_ms;
3745
	xfer->endpoint->isoc_next &= frame_mask;
3746
3747
	return (retval);
3748
}
(-)b/sys/dev/usb/usb_transfer.h (+1 lines)
Lines 250-254 void usbd_transfer_timeout_ms(struct usb_xfer *xfer, Link Here
250
	    void (*cb) (void *arg), usb_timeout_t ms);
250
	    void (*cb) (void *arg), usb_timeout_t ms);
251
usb_timeout_t usbd_get_dma_delay(struct usb_device *udev);
251
usb_timeout_t usbd_get_dma_delay(struct usb_device *udev);
252
void	usbd_transfer_power_ref(struct usb_xfer *xfer, int val);
252
void	usbd_transfer_power_ref(struct usb_xfer *xfer, int val);
253
uint8_t	usbd_xfer_get_isochronous_start_frame(struct usb_xfer *, uint32_t, uint32_t, uint32_t, uint32_t *);
253
254
254
#endif					/* _USB_TRANSFER_H_ */
255
#endif					/* _USB_TRANSFER_H_ */

Return to bug 257082