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 1441-1447 static void Link Here
1441
atmegadci_device_isoc_fs_enter(struct usb_xfer *xfer)
1441
atmegadci_device_isoc_fs_enter(struct usb_xfer *xfer)
1442
{
1442
{
1443
	struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus);
1443
	struct atmegadci_softc *sc = ATMEGA_BUS2SC(xfer->xroot->bus);
1444
	uint32_t temp;
1445
	uint32_t nframes;
1444
	uint32_t nframes;
1446
1445
1447
	DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
1446
	DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
Lines 1453-1493 atmegadci_device_isoc_fs_enter(struct usb_xfer *xfer) Link Here
1453
	    (ATMEGA_READ_1(sc, ATMEGA_UDFNUMH) << 8) |
1452
	    (ATMEGA_READ_1(sc, ATMEGA_UDFNUMH) << 8) |
1454
	    (ATMEGA_READ_1(sc, ATMEGA_UDFNUML));
1453
	    (ATMEGA_READ_1(sc, ATMEGA_UDFNUML));
1455
1454
1456
	nframes &= ATMEGA_FRAME_MASK;
1455
	if (usbd_xfer_get_isochronous_start_frame(
1457
1456
	    xfer, nframes, 0, 1, ATMEGA_FRAME_MASK, NULL))
1458
	/*
1459
	 * check if the frame index is within the window where the frames
1460
	 * will be inserted
1461
	 */
1462
	temp = (nframes - xfer->endpoint->isoc_next) & ATMEGA_FRAME_MASK;
1463
1464
	if ((xfer->endpoint->is_synced == 0) ||
1465
	    (temp < xfer->nframes)) {
1466
		/*
1467
		 * If there is data underflow or the pipe queue is
1468
		 * empty we schedule the transfer a few frames ahead
1469
		 * of the current frame position. Else two isochronous
1470
		 * transfers might overlap.
1471
		 */
1472
		xfer->endpoint->isoc_next = (nframes + 3) & ATMEGA_FRAME_MASK;
1473
		xfer->endpoint->is_synced = 1;
1474
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
1457
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
1475
	}
1476
	/*
1477
	 * compute how many milliseconds the insertion is ahead of the
1478
	 * current frame position:
1479
	 */
1480
	temp = (xfer->endpoint->isoc_next - nframes) & ATMEGA_FRAME_MASK;
1481
1482
	/*
1483
	 * pre-compute when the isochronous transfer will be finished:
1484
	 */
1485
	xfer->isoc_time_complete =
1486
	    usb_isoc_time_expand(&sc->sc_bus, nframes) + temp +
1487
	    xfer->nframes;
1488
1489
	/* compute frame number for next insertion */
1490
	xfer->endpoint->isoc_next += xfer->nframes;
1491
1458
1492
	/* setup TDs */
1459
	/* setup TDs */
1493
	atmegadci_setup_standard_chain(xfer);
1460
	atmegadci_setup_standard_chain(xfer);
(-)b/sys/dev/usb/controller/avr32dci.c (-35 / +8 lines)
Lines 1371-1377 static void Link Here
1371
avr32dci_device_isoc_fs_enter(struct usb_xfer *xfer)
1371
avr32dci_device_isoc_fs_enter(struct usb_xfer *xfer)
1372
{
1372
{
1373
	struct avr32dci_softc *sc = AVR32_BUS2SC(xfer->xroot->bus);
1373
	struct avr32dci_softc *sc = AVR32_BUS2SC(xfer->xroot->bus);
1374
	uint32_t temp;
1375
	uint32_t nframes;
1374
	uint32_t nframes;
1376
	uint8_t ep_no;
1375
	uint8_t ep_no;
1377
1376
Lines 1382-1422 avr32dci_device_isoc_fs_enter(struct usb_xfer *xfer) Link Here
1382
	ep_no = xfer->endpointno & UE_ADDR;
1381
	ep_no = xfer->endpointno & UE_ADDR;
1383
	nframes = (AVR32_READ_4(sc, AVR32_FNUM) / 8);
1382
	nframes = (AVR32_READ_4(sc, AVR32_FNUM) / 8);
1384
1383
1385
	nframes &= AVR32_FRAME_MASK;
1384
	if (usbd_xfer_get_isochronous_start_frame(
1386
1385
	    xfer, nframes, 0, 1, AVR32_FRAME_MASK, NULL))
1387
	/*
1388
	 * check if the frame index is within the window where the frames
1389
	 * will be inserted
1390
	 */
1391
	temp = (nframes - xfer->endpoint->isoc_next) & AVR32_FRAME_MASK;
1392
1393
	if ((xfer->endpoint->is_synced == 0) ||
1394
	    (temp < xfer->nframes)) {
1395
		/*
1396
		 * If there is data underflow or the pipe queue is
1397
		 * empty we schedule the transfer a few frames ahead
1398
		 * of the current frame position. Else two isochronous
1399
		 * transfers might overlap.
1400
		 */
1401
		xfer->endpoint->isoc_next = (nframes + 3) & AVR32_FRAME_MASK;
1402
		xfer->endpoint->is_synced = 1;
1403
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
1386
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
1404
	}
1405
	/*
1406
	 * compute how many milliseconds the insertion is ahead of the
1407
	 * current frame position:
1408
	 */
1409
	temp = (xfer->endpoint->isoc_next - nframes) & AVR32_FRAME_MASK;
1410
1411
	/*
1412
	 * pre-compute when the isochronous transfer will be finished:
1413
	 */
1414
	xfer->isoc_time_complete =
1415
	    usb_isoc_time_expand(&sc->sc_bus, nframes) + temp +
1416
	    xfer->nframes;
1417
1418
	/* compute frame number for next insertion */
1419
	xfer->endpoint->isoc_next += xfer->nframes;
1420
1387
1421
	/* setup TDs */
1388
	/* setup TDs */
1422
	avr32dci_setup_standard_chain(xfer);
1389
	avr32dci_setup_standard_chain(xfer);
Lines 1707-1712 avr32dci_roothub_exec(struct usb_device *udev, Link Here
1707
		len = sizeof(avr32dci_devd);
1674
		len = sizeof(avr32dci_devd);
1708
		ptr = (const void *)&avr32dci_devd;
1675
		ptr = (const void *)&avr32dci_devd;
1709
		goto tr_valid;
1676
		goto tr_valid;
1677
	case UDESC_DEVICE_QUALIFIER:
1678
		if (value & 0xff)
1679
			goto tr_stalled;
1680
		len = sizeof(avr32dci_odevd);
1681
		ptr = (const void *)&avr32dci_odevd;
1682
		goto tr_valid;
1710
	case UDESC_CONFIG:
1683
	case UDESC_CONFIG:
1711
		if (value & 0xff) {
1684
		if (value & 0xff) {
1712
			goto tr_stalled;
1685
			goto tr_stalled;
(-)b/sys/dev/usb/controller/dwc_otg.c (-43 / +2 lines)
Lines 4197-4205 dwc_otg_device_isoc_start(struct usb_xfer *xfer) Link Here
4197
{
4197
{
4198
	struct dwc_otg_softc *sc = DWC_OTG_BUS2SC(xfer->xroot->bus);
4198
	struct dwc_otg_softc *sc = DWC_OTG_BUS2SC(xfer->xroot->bus);
4199
	uint32_t temp;
4199
	uint32_t temp;
4200
	uint32_t msframes;
4201
	uint32_t framenum;
4200
	uint32_t framenum;
4202
	uint8_t shift = usbd_xfer_get_fps_shift(xfer);
4203
4201
4204
	DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
4202
	DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
4205
	    xfer, xfer->endpoint->isoc_next, xfer->nframes);
4203
	    xfer, xfer->endpoint->isoc_next, xfer->nframes);
Lines 4222-4273 dwc_otg_device_isoc_start(struct usb_xfer *xfer) Link Here
4222
	if (sc->sc_flags.status_high_speed)
4220
	if (sc->sc_flags.status_high_speed)
4223
		framenum /= 8;
4221
		framenum /= 8;
4224
4222
4225
	framenum &= DWC_OTG_FRAME_MASK;
4223
	if (usbd_xfer_get_isochronous_start_frame(
4226
4224
	    xfer, framenum, 0, 1, DWC_OTG_FRAME_MASK, NULL))
4227
	/*
4228
	 * Compute number of milliseconds worth of data traffic for
4229
	 * this USB transfer:
4230
	 */ 
4231
	if (xfer->xroot->udev->speed == USB_SPEED_HIGH)
4232
		msframes = ((xfer->nframes << shift) + 7) / 8;
4233
	else
4234
		msframes = xfer->nframes;
4235
4236
	/*
4237
	 * check if the frame index is within the window where the frames
4238
	 * will be inserted
4239
	 */
4240
	temp = (framenum - xfer->endpoint->isoc_next) & DWC_OTG_FRAME_MASK;
4241
4242
	if ((xfer->endpoint->is_synced == 0) || (temp < msframes)) {
4243
		/*
4244
		 * If there is data underflow or the pipe queue is
4245
		 * empty we schedule the transfer a few frames ahead
4246
		 * of the current frame position. Else two isochronous
4247
		 * transfers might overlap.
4248
		 */
4249
		xfer->endpoint->isoc_next = (framenum + 3) & DWC_OTG_FRAME_MASK;
4250
		xfer->endpoint->is_synced = 1;
4251
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
4225
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
4252
	}
4253
	/*
4254
	 * compute how many milliseconds the insertion is ahead of the
4255
	 * current frame position:
4256
	 */
4257
	temp = (xfer->endpoint->isoc_next - framenum) & DWC_OTG_FRAME_MASK;
4258
4259
	/*
4260
	 * pre-compute when the isochronous transfer will be finished:
4261
	 */
4262
	xfer->isoc_time_complete =
4263
		usb_isoc_time_expand(&sc->sc_bus, framenum) + temp + msframes;
4264
4226
4265
	/* setup TDs */
4227
	/* setup TDs */
4266
	dwc_otg_setup_standard_chain(xfer);
4228
	dwc_otg_setup_standard_chain(xfer);
4267
4229
4268
	/* compute frame number for next insertion */
4269
	xfer->endpoint->isoc_next += msframes;
4270
4271
	/* start TD chain */
4230
	/* start TD chain */
4272
	dwc_otg_start_standard_chain(xfer);
4231
	dwc_otg_start_standard_chain(xfer);
4273
}
4232
}
(-)b/sys/dev/usb/controller/ehci.c (-82 / +14 lines)
Lines 2465-2470 ehci_device_isoc_fs_enter(struct usb_xfer *xfer) Link Here
2465
	uint32_t *plen;
2465
	uint32_t *plen;
2466
	uint32_t buf_offset;
2466
	uint32_t buf_offset;
2467
	uint32_t nframes;
2467
	uint32_t nframes;
2468
	uint32_t startframe;
2468
	uint32_t temp;
2469
	uint32_t temp;
2469
	uint32_t sitd_mask;
2470
	uint32_t sitd_mask;
2470
	uint16_t tlen;
2471
	uint16_t tlen;
Lines 2483-2521 ehci_device_isoc_fs_enter(struct usb_xfer *xfer) Link Here
2483
2484
2484
	nframes = EOREAD4(sc, EHCI_FRINDEX) / 8;
2485
	nframes = EOREAD4(sc, EHCI_FRINDEX) / 8;
2485
2486
2486
	/*
2487
	if (usbd_xfer_get_isochronous_start_frame(
2487
	 * check if the frame index is within the window where the frames
2488
	    xfer, nframes, 0, 1, EHCI_VIRTUAL_FRAMELIST_COUNT - 1, &startframe))
2488
	 * will be inserted
2489
		DPRINTFN(3, "start next=%d\n", startframe);
2489
	 */
2490
	buf_offset = (nframes - xfer->endpoint->isoc_next) &
2491
	    (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
2492
2493
	if ((xfer->endpoint->is_synced == 0) ||
2494
	    (buf_offset < xfer->nframes)) {
2495
		/*
2496
		 * If there is data underflow or the pipe queue is empty we
2497
		 * schedule the transfer a few frames ahead of the current
2498
		 * frame position. Else two isochronous transfers might
2499
		 * overlap.
2500
		 */
2501
		xfer->endpoint->isoc_next = (nframes + 3) &
2502
		    (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
2503
		xfer->endpoint->is_synced = 1;
2504
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
2505
	}
2506
	/*
2507
	 * compute how many milliseconds the insertion is ahead of the
2508
	 * current frame position:
2509
	 */
2510
	buf_offset = (xfer->endpoint->isoc_next - nframes) &
2511
	    (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
2512
2513
	/*
2514
	 * pre-compute when the isochronous transfer will be finished:
2515
	 */
2516
	xfer->isoc_time_complete =
2517
	    usb_isoc_time_expand(&sc->sc_bus, nframes) +
2518
	    buf_offset + xfer->nframes;
2519
2490
2520
	/* get the real number of frames */
2491
	/* get the real number of frames */
2521
2492
Lines 2532-2542 ehci_device_isoc_fs_enter(struct usb_xfer *xfer) Link Here
2532
	td = xfer->td_start[xfer->flags_int.curr_dma_set];
2503
	td = xfer->td_start[xfer->flags_int.curr_dma_set];
2533
	xfer->td_transfer_first = td;
2504
	xfer->td_transfer_first = td;
2534
2505
2535
	pp_last = &sc->sc_isoc_fs_p_last[xfer->endpoint->isoc_next];
2506
	pp_last = &sc->sc_isoc_fs_p_last[startframe];
2536
2507
2537
	/* store starting position */
2508
	/* store starting position */
2538
2509
2539
	xfer->qh_pos = xfer->endpoint->isoc_next;
2510
	xfer->qh_pos = startframe;
2540
2511
2541
	while (nframes--) {
2512
	while (nframes--) {
2542
		if (td == NULL) {
2513
		if (td == NULL) {
Lines 2658-2667 ehci_device_isoc_fs_enter(struct usb_xfer *xfer) Link Here
2658
2629
2659
	xfer->td_transfer_last = td_last;
2630
	xfer->td_transfer_last = td_last;
2660
2631
2661
	/* update isoc_next */
2662
	xfer->endpoint->isoc_next = (pp_last - &sc->sc_isoc_fs_p_last[0]) &
2663
	    (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
2664
2665
	/*
2632
	/*
2666
	 * We don't allow cancelling of the SPLIT transaction USB FULL
2633
	 * We don't allow cancelling of the SPLIT transaction USB FULL
2667
	 * speed transfer, because it disturbs the bandwidth
2634
	 * speed transfer, because it disturbs the bandwidth
Lines 2770-2780 ehci_device_isoc_hs_enter(struct usb_xfer *xfer) Link Here
2770
	uint32_t status;
2737
	uint32_t status;
2771
	uint32_t buf_offset;
2738
	uint32_t buf_offset;
2772
	uint32_t nframes;
2739
	uint32_t nframes;
2740
	uint32_t startframe;
2773
	uint32_t itd_offset[8 + 1];
2741
	uint32_t itd_offset[8 + 1];
2774
	uint8_t x;
2742
	uint8_t x;
2775
	uint8_t td_no;
2743
	uint8_t td_no;
2776
	uint8_t page_no;
2744
	uint8_t page_no;
2777
	uint8_t shift = usbd_xfer_get_fps_shift(xfer);
2778
2745
2779
#ifdef USB_DEBUG
2746
#ifdef USB_DEBUG
2780
	uint8_t once = 1;
2747
	uint8_t once = 1;
Lines 2782-2828 ehci_device_isoc_hs_enter(struct usb_xfer *xfer) Link Here
2782
#endif
2749
#endif
2783
2750
2784
	DPRINTFN(6, "xfer=%p next=%d nframes=%d shift=%d\n",
2751
	DPRINTFN(6, "xfer=%p next=%d nframes=%d shift=%d\n",
2785
	    xfer, xfer->endpoint->isoc_next, xfer->nframes, (int)shift);
2752
	    xfer, xfer->endpoint->isoc_next, xfer->nframes,
2753
	    usbd_xfer_get_fps_shift(xfer));
2786
2754
2787
	/* get the current frame index */
2755
	/* get the current frame index */
2788
2756
2789
	nframes = EOREAD4(sc, EHCI_FRINDEX) / 8;
2757
	nframes = EOREAD4(sc, EHCI_FRINDEX) / 8;
2790
2758
2791
	/*
2759
	if (usbd_xfer_get_isochronous_start_frame(
2792
	 * check if the frame index is within the window where the frames
2760
	    xfer, nframes, 0, 1, EHCI_VIRTUAL_FRAMELIST_COUNT - 1, &startframe))
2793
	 * will be inserted
2761
		DPRINTFN(3, "start next=%d\n", startframe);
2794
	 */
2795
	buf_offset = (nframes - xfer->endpoint->isoc_next) &
2796
	    (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
2797
2798
	if ((xfer->endpoint->is_synced == 0) ||
2799
	    (buf_offset < (((xfer->nframes << shift) + 7) / 8))) {
2800
		/*
2801
		 * If there is data underflow or the pipe queue is empty we
2802
		 * schedule the transfer a few frames ahead of the current
2803
		 * frame position. Else two isochronous transfers might
2804
		 * overlap.
2805
		 */
2806
		xfer->endpoint->isoc_next = (nframes + 3) &
2807
		    (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
2808
		xfer->endpoint->is_synced = 1;
2809
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
2810
	}
2811
	/*
2812
	 * compute how many milliseconds the insertion is ahead of the
2813
	 * current frame position:
2814
	 */
2815
	buf_offset = (xfer->endpoint->isoc_next - nframes) &
2816
	    (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
2817
2818
	/*
2819
	 * pre-compute when the isochronous transfer will be finished:
2820
	 */
2821
	xfer->isoc_time_complete =
2822
	    usb_isoc_time_expand(&sc->sc_bus, nframes) + buf_offset +
2823
	    (((xfer->nframes << shift) + 7) / 8);
2824
2825
	/* get the real number of frames */
2826
2762
2827
	nframes = xfer->nframes;
2763
	nframes = xfer->nframes;
2828
2764
Lines 2838-2848 ehci_device_isoc_hs_enter(struct usb_xfer *xfer) Link Here
2838
	td = xfer->td_start[xfer->flags_int.curr_dma_set];
2774
	td = xfer->td_start[xfer->flags_int.curr_dma_set];
2839
	xfer->td_transfer_first = td;
2775
	xfer->td_transfer_first = td;
2840
2776
2841
	pp_last = &sc->sc_isoc_hs_p_last[xfer->endpoint->isoc_next];
2777
	pp_last = &sc->sc_isoc_hs_p_last[startframe];
2842
2778
2843
	/* store starting position */
2779
	/* store starting position */
2844
2780
2845
	xfer->qh_pos = xfer->endpoint->isoc_next;
2781
	xfer->qh_pos = startframe;
2846
2782
2847
	while (nframes) {
2783
	while (nframes) {
2848
		if (td == NULL) {
2784
		if (td == NULL) {
Lines 2955-2964 ehci_device_isoc_hs_enter(struct usb_xfer *xfer) Link Here
2955
	}
2891
	}
2956
2892
2957
	xfer->td_transfer_last = td_last;
2893
	xfer->td_transfer_last = td_last;
2958
2959
	/* update isoc_next */
2960
	xfer->endpoint->isoc_next = (pp_last - &sc->sc_isoc_hs_p_last[0]) &
2961
	    (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
2962
}
2894
}
2963
2895
2964
static void
2896
static void
(-)b/sys/dev/usb/controller/musb_otg.c (-40 / +2 lines)
Lines 3474-3482 static void Link Here
3474
musbotg_device_isoc_enter(struct usb_xfer *xfer)
3474
musbotg_device_isoc_enter(struct usb_xfer *xfer)
3475
{
3475
{
3476
	struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
3476
	struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
3477
	uint32_t temp;
3478
	uint32_t nframes;
3477
	uint32_t nframes;
3479
	uint32_t fs_frames;
3480
3478
3481
	DPRINTFN(5, "xfer=%p next=%d nframes=%d\n",
3479
	DPRINTFN(5, "xfer=%p next=%d nframes=%d\n",
3482
	    xfer, xfer->endpoint->isoc_next, xfer->nframes);
3480
	    xfer, xfer->endpoint->isoc_next, xfer->nframes);
Lines 3485-3529 musbotg_device_isoc_enter(struct usb_xfer *xfer) Link Here
3485
3483
3486
	nframes = MUSB2_READ_2(sc, MUSB2_REG_FRAME);
3484
	nframes = MUSB2_READ_2(sc, MUSB2_REG_FRAME);
3487
3485
3488
	/*
3486
	if (usbd_xfer_get_isochronous_start_frame(
3489
	 * check if the frame index is within the window where the frames
3487
	    xfer, nframes, 0, 1, MUSB2_MASK_FRAME, NULL))
3490
	 * will be inserted
3491
	 */
3492
	temp = (nframes - xfer->endpoint->isoc_next) & MUSB2_MASK_FRAME;
3493
3494
	if (usbd_get_speed(xfer->xroot->udev) == USB_SPEED_HIGH) {
3495
		fs_frames = (xfer->nframes + 7) / 8;
3496
	} else {
3497
		fs_frames = xfer->nframes;
3498
	}
3499
3500
	if ((xfer->endpoint->is_synced == 0) ||
3501
	    (temp < fs_frames)) {
3502
		/*
3503
		 * If there is data underflow or the pipe queue is
3504
		 * empty we schedule the transfer a few frames ahead
3505
		 * of the current frame position. Else two isochronous
3506
		 * transfers might overlap.
3507
		 */
3508
		xfer->endpoint->isoc_next = (nframes + 3) & MUSB2_MASK_FRAME;
3509
		xfer->endpoint->is_synced = 1;
3510
		DPRINTFN(2, "start next=%d\n", xfer->endpoint->isoc_next);
3488
		DPRINTFN(2, "start next=%d\n", xfer->endpoint->isoc_next);
3511
	}
3512
	/*
3513
	 * compute how many milliseconds the insertion is ahead of the
3514
	 * current frame position:
3515
	 */
3516
	temp = (xfer->endpoint->isoc_next - nframes) & MUSB2_MASK_FRAME;
3517
3518
	/*
3519
	 * pre-compute when the isochronous transfer will be finished:
3520
	 */
3521
	xfer->isoc_time_complete =
3522
	    usb_isoc_time_expand(&sc->sc_bus, nframes) + temp +
3523
	    fs_frames;
3524
3525
	/* compute frame number for next insertion */
3526
	xfer->endpoint->isoc_next += fs_frames;
3527
3489
3528
	/* setup TDs */
3490
	/* setup TDs */
3529
	musbotg_setup_standard_chain(xfer);
3491
	musbotg_setup_standard_chain(xfer);
(-)b/sys/dev/usb/controller/ohci.c (-27 / +6 lines)
Lines 1844-1849 ohci_device_isoc_enter(struct usb_xfer *xfer) Link Here
1844
	struct ohci_hcca *hcca;
1844
	struct ohci_hcca *hcca;
1845
	uint32_t buf_offset;
1845
	uint32_t buf_offset;
1846
	uint32_t nframes;
1846
	uint32_t nframes;
1847
	uint32_t startframe;
1847
	uint32_t ed_flags;
1848
	uint32_t ed_flags;
1848
	uint32_t *plen;
1849
	uint32_t *plen;
1849
	uint16_t itd_offset[OHCI_ITD_NOFFSET];
1850
	uint16_t itd_offset[OHCI_ITD_NOFFSET];
Lines 1860-1890 ohci_device_isoc_enter(struct usb_xfer *xfer) Link Here
1860
	DPRINTFN(6, "xfer=%p isoc_next=%u nframes=%u hcca_fn=%u\n",
1861
	DPRINTFN(6, "xfer=%p isoc_next=%u nframes=%u hcca_fn=%u\n",
1861
	    xfer, xfer->endpoint->isoc_next, xfer->nframes, nframes);
1862
	    xfer, xfer->endpoint->isoc_next, xfer->nframes, nframes);
1862
1863
1863
	if ((xfer->endpoint->is_synced == 0) ||
1864
	if (usbd_xfer_get_isochronous_start_frame(
1864
	    (((nframes - xfer->endpoint->isoc_next) & 0xFFFF) < xfer->nframes) ||
1865
	    xfer, nframes, 0, 1, 0xFFFF, &startframe))
1865
	    (((xfer->endpoint->isoc_next - nframes) & 0xFFFF) >= 128)) {
1866
		DPRINTFN(3, "start next=%d\n", startframe);
1866
		/*
1867
		 * If there is data underflow or the pipe queue is empty we
1868
		 * schedule the transfer a few frames ahead of the current
1869
		 * frame position. Else two isochronous transfers might
1870
		 * overlap.
1871
		 */
1872
		xfer->endpoint->isoc_next = (nframes + 3) & 0xFFFF;
1873
		xfer->endpoint->is_synced = 1;
1874
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
1875
	}
1876
	/*
1877
	 * compute how many milliseconds the insertion is ahead of the
1878
	 * current frame position:
1879
	 */
1880
	buf_offset = ((xfer->endpoint->isoc_next - nframes) & 0xFFFF);
1881
1882
	/*
1883
	 * pre-compute when the isochronous transfer will be finished:
1884
	 */
1885
	xfer->isoc_time_complete =
1886
	    (usb_isoc_time_expand(&sc->sc_bus, nframes) + buf_offset +
1887
	    xfer->nframes);
1888
1867
1889
	/* get the real number of frames */
1868
	/* get the real number of frames */
1890
1869
Lines 1926-1937 ohci_device_isoc_enter(struct usb_xfer *xfer) Link Here
1926
			/* fill current ITD */
1905
			/* fill current ITD */
1927
			td->itd_flags = htole32(
1906
			td->itd_flags = htole32(
1928
			    OHCI_ITD_NOCC |
1907
			    OHCI_ITD_NOCC |
1929
			    OHCI_ITD_SET_SF(xfer->endpoint->isoc_next) |
1908
			    OHCI_ITD_SET_SF(startframe) |
1930
			    OHCI_ITD_NOINTR |
1909
			    OHCI_ITD_NOINTR |
1931
			    OHCI_ITD_SET_FC(ncur));
1910
			    OHCI_ITD_SET_FC(ncur));
1932
1911
1933
			td->frames = ncur;
1912
			td->frames = ncur;
1934
			xfer->endpoint->isoc_next += ncur;
1913
			startframe += ncur;
1935
1914
1936
			if (length == 0) {
1915
			if (length == 0) {
1937
				/* all zero */
1916
				/* all zero */
(-)b/sys/dev/usb/controller/saf1761_otg.c (-66 / +4 lines)
Lines 2645-2651 static void Link Here
2645
saf1761_otg_device_isoc_enter(struct usb_xfer *xfer)
2645
saf1761_otg_device_isoc_enter(struct usb_xfer *xfer)
2646
{
2646
{
2647
	struct saf1761_otg_softc *sc = SAF1761_OTG_BUS2SC(xfer->xroot->bus);
2647
	struct saf1761_otg_softc *sc = SAF1761_OTG_BUS2SC(xfer->xroot->bus);
2648
	uint32_t temp;
2649
	uint32_t nframes;
2648
	uint32_t nframes;
2650
2649
2651
	DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
2650
	DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
Lines 2655-2693 saf1761_otg_device_isoc_enter(struct usb_xfer *xfer) Link Here
2655
2654
2656
	nframes = SAF1761_READ_LE_4(sc, SOTG_FRAME_NUM);
2655
	nframes = SAF1761_READ_LE_4(sc, SOTG_FRAME_NUM);
2657
2656
2658
	/*
2657
	if (usbd_xfer_get_isochronous_start_frame(
2659
	 * check if the frame index is within the window where the
2658
	    xfer, nframes, 0, 1, SOTG_FRAME_NUM_SOFR_MASK, NULL))
2660
	 * frames will be inserted
2661
	 */
2662
	temp = (nframes - xfer->endpoint->isoc_next) & SOTG_FRAME_NUM_SOFR_MASK;
2663
2664
	if ((xfer->endpoint->is_synced == 0) ||
2665
	    (temp < xfer->nframes)) {
2666
		/*
2667
		 * If there is data underflow or the pipe queue is
2668
		 * empty we schedule the transfer a few frames ahead
2669
		 * of the current frame position. Else two isochronous
2670
		 * transfers might overlap.
2671
		 */
2672
		xfer->endpoint->isoc_next = (nframes + 3) & SOTG_FRAME_NUM_SOFR_MASK;
2673
		xfer->endpoint->is_synced = 1;
2674
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
2659
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
2675
	}
2676
	/*
2677
	 * compute how many milliseconds the insertion is ahead of the
2678
	 * current frame position:
2679
	 */
2680
	temp = (xfer->endpoint->isoc_next - nframes) & SOTG_FRAME_NUM_SOFR_MASK;
2681
2682
	/*
2683
	 * pre-compute when the isochronous transfer will be finished:
2684
	 */
2685
	xfer->isoc_time_complete =
2686
	    usb_isoc_time_expand(&sc->sc_bus, nframes) + temp +
2687
	    xfer->nframes;
2688
2689
	/* compute frame number for next insertion */
2690
	xfer->endpoint->isoc_next += xfer->nframes;
2691
2660
2692
	/* setup TDs */
2661
	/* setup TDs */
2693
	saf1761_otg_setup_standard_chain(xfer);
2662
	saf1761_otg_setup_standard_chain(xfer);
Lines 2727-2733 static void Link Here
2727
saf1761_otg_host_isoc_enter(struct usb_xfer *xfer)
2696
saf1761_otg_host_isoc_enter(struct usb_xfer *xfer)
2728
{
2697
{
2729
	struct saf1761_otg_softc *sc = SAF1761_OTG_BUS2SC(xfer->xroot->bus);
2698
	struct saf1761_otg_softc *sc = SAF1761_OTG_BUS2SC(xfer->xroot->bus);
2730
	uint32_t temp;
2731
	uint32_t nframes;
2699
	uint32_t nframes;
2732
2700
2733
	DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
2701
	DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
Lines 2737-2775 saf1761_otg_host_isoc_enter(struct usb_xfer *xfer) Link Here
2737
2705
2738
	nframes = (SAF1761_READ_LE_4(sc, SOTG_FRINDEX) & SOTG_FRINDEX_MASK) >> 3;
2706
	nframes = (SAF1761_READ_LE_4(sc, SOTG_FRINDEX) & SOTG_FRINDEX_MASK) >> 3;
2739
2707
2740
	/*
2708
	if (usbd_xfer_get_isochronous_start_frame(
2741
	 * check if the frame index is within the window where the
2709
	    xfer, nframes, 0, 1, SOTG_FRINDEX_MASK >> 3, NULL))
2742
	 * frames will be inserted
2743
	 */
2744
	temp = (nframes - xfer->endpoint->isoc_next) & (SOTG_FRINDEX_MASK >> 3);
2745
2746
	if ((xfer->endpoint->is_synced == 0) ||
2747
	    (temp < xfer->nframes)) {
2748
		/*
2749
		 * If there is data underflow or the pipe queue is
2750
		 * empty we schedule the transfer a few frames ahead
2751
		 * of the current frame position. Else two isochronous
2752
		 * transfers might overlap.
2753
		 */
2754
		xfer->endpoint->isoc_next = (nframes + 3) & (SOTG_FRINDEX_MASK >> 3);
2755
		xfer->endpoint->is_synced = 1;
2756
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
2710
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
2757
	}
2758
	/*
2759
	 * compute how many milliseconds the insertion is ahead of the
2760
	 * current frame position:
2761
	 */
2762
	temp = (xfer->endpoint->isoc_next - nframes) & (SOTG_FRINDEX_MASK >> 3);
2763
2764
	/*
2765
	 * pre-compute when the isochronous transfer will be finished:
2766
	 */
2767
	xfer->isoc_time_complete =
2768
	    usb_isoc_time_expand(&sc->sc_bus, nframes) + temp +
2769
	    xfer->nframes;
2770
2771
	/* compute frame number for next insertion */
2772
	xfer->endpoint->isoc_next += xfer->nframes;
2773
2711
2774
	/* setup TDs */
2712
	/* setup TDs */
2775
	saf1761_otg_setup_standard_chain(xfer);
2713
	saf1761_otg_setup_standard_chain(xfer);
(-)b/sys/dev/usb/controller/uhci.c (-35 / +6 lines)
Lines 2142-2148 uhci_device_isoc_enter(struct usb_xfer *xfer) Link Here
2142
	struct uhci_mem_layout ml;
2142
	struct uhci_mem_layout ml;
2143
	uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
2143
	uhci_softc_t *sc = UHCI_BUS2SC(xfer->xroot->bus);
2144
	uint32_t nframes;
2144
	uint32_t nframes;
2145
	uint32_t temp;
2145
	uint32_t startframe;
2146
	uint32_t *plen;
2146
	uint32_t *plen;
2147
2147
2148
#ifdef USB_DEBUG
2148
#ifdef USB_DEBUG
Lines 2158-2191 uhci_device_isoc_enter(struct usb_xfer *xfer) Link Here
2158
2158
2159
	nframes = UREAD2(sc, UHCI_FRNUM);
2159
	nframes = UREAD2(sc, UHCI_FRNUM);
2160
2160
2161
	temp = (nframes - xfer->endpoint->isoc_next) &
2161
	if (usbd_xfer_get_isochronous_start_frame(
2162
	    (UHCI_VFRAMELIST_COUNT - 1);
2162
	    xfer, nframes, 0, 1, UHCI_VFRAMELIST_COUNT - 1, &startframe))
2163
2163
		DPRINTFN(3, "start next=%d\n", startframe);
2164
	if ((xfer->endpoint->is_synced == 0) ||
2165
	    (temp < xfer->nframes)) {
2166
		/*
2167
		 * If there is data underflow or the pipe queue is empty we
2168
		 * schedule the transfer a few frames ahead of the current
2169
		 * frame position. Else two isochronous transfers might
2170
		 * overlap.
2171
		 */
2172
		xfer->endpoint->isoc_next = (nframes + 3) & (UHCI_VFRAMELIST_COUNT - 1);
2173
		xfer->endpoint->is_synced = 1;
2174
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
2175
	}
2176
	/*
2177
	 * compute how many milliseconds the insertion is ahead of the
2178
	 * current frame position:
2179
	 */
2180
	temp = (xfer->endpoint->isoc_next - nframes) &
2181
	    (UHCI_VFRAMELIST_COUNT - 1);
2182
2183
	/*
2184
	 * pre-compute when the isochronous transfer will be finished:
2185
	 */
2186
	xfer->isoc_time_complete =
2187
	    usb_isoc_time_expand(&sc->sc_bus, nframes) + temp +
2188
	    xfer->nframes;
2189
2164
2190
	/* get the real number of frames */
2165
	/* get the real number of frames */
2191
2166
Lines 2202-2212 uhci_device_isoc_enter(struct usb_xfer *xfer) Link Here
2202
	td = xfer->td_start[xfer->flags_int.curr_dma_set];
2177
	td = xfer->td_start[xfer->flags_int.curr_dma_set];
2203
	xfer->td_transfer_first = td;
2178
	xfer->td_transfer_first = td;
2204
2179
2205
	pp_last = &sc->sc_isoc_p_last[xfer->endpoint->isoc_next];
2180
	pp_last = &sc->sc_isoc_p_last[startframe];
2206
2181
2207
	/* store starting position */
2182
	/* store starting position */
2208
2183
2209
	xfer->qh_pos = xfer->endpoint->isoc_next;
2184
	xfer->qh_pos = startframe;
2210
2185
2211
	while (nframes--) {
2186
	while (nframes--) {
2212
		if (td == NULL) {
2187
		if (td == NULL) {
Lines 2285-2294 uhci_device_isoc_enter(struct usb_xfer *xfer) Link Here
2285
	}
2260
	}
2286
2261
2287
	xfer->td_transfer_last = td_last;
2262
	xfer->td_transfer_last = td_last;
2288
2289
	/* update isoc_next */
2290
	xfer->endpoint->isoc_next = (pp_last - &sc->sc_isoc_p_last[0]) &
2291
	    (UHCI_VFRAMELIST_COUNT - 1);
2292
}
2263
}
2293
2264
2294
static void
2265
static void
(-)b/sys/dev/usb/controller/uss820dci.c (-33 / +2 lines)
Lines 1724-1730 static void Link Here
1724
uss820dci_device_isoc_fs_enter(struct usb_xfer *xfer)
1724
uss820dci_device_isoc_fs_enter(struct usb_xfer *xfer)
1725
{
1725
{
1726
	struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
1726
	struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
1727
	uint32_t temp;
1728
	uint32_t nframes;
1727
	uint32_t nframes;
1729
1728
1730
	DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
1729
	DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
Lines 1734-1772 uss820dci_device_isoc_fs_enter(struct usb_xfer *xfer) Link Here
1734
1733
1735
	nframes = USS820_READ_1(sc, USS820_SOFL);
1734
	nframes = USS820_READ_1(sc, USS820_SOFL);
1736
1735
1737
	/*
1736
	if (usbd_xfer_get_isochronous_start_frame(
1738
	 * check if the frame index is within the window where the
1737
	    xfer, nframes, 0, 1, USS820_SOFL_MASK, NULL))
1739
	 * frames will be inserted
1740
	 */
1741
	temp = (nframes - xfer->endpoint->isoc_next) & USS820_SOFL_MASK;
1742
1743
	if ((xfer->endpoint->is_synced == 0) ||
1744
	    (temp < xfer->nframes)) {
1745
		/*
1746
		 * If there is data underflow or the pipe queue is
1747
		 * empty we schedule the transfer a few frames ahead
1748
		 * of the current frame position. Else two isochronous
1749
		 * transfers might overlap.
1750
		 */
1751
		xfer->endpoint->isoc_next = (nframes + 3) & USS820_SOFL_MASK;
1752
		xfer->endpoint->is_synced = 1;
1753
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
1738
		DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
1754
	}
1755
	/*
1756
	 * compute how many milliseconds the insertion is ahead of the
1757
	 * current frame position:
1758
	 */
1759
	temp = (xfer->endpoint->isoc_next - nframes) & USS820_SOFL_MASK;
1760
1761
	/*
1762
	 * pre-compute when the isochronous transfer will be finished:
1763
	 */
1764
	xfer->isoc_time_complete =
1765
	    usb_isoc_time_expand(&sc->sc_bus, nframes) + temp +
1766
	    xfer->nframes;
1767
1768
	/* compute frame number for next insertion */
1769
	xfer->endpoint->isoc_next += xfer->nframes;
1770
1739
1771
	/* setup TDs */
1740
	/* setup TDs */
1772
	uss820dci_setup_standard_chain(xfer);
1741
	uss820dci_setup_standard_chain(xfer);
(-)b/sys/dev/usb/controller/xhci.c (-50 / +34 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 2089-2146 xhci_setup_generic_chain(struct usb_xfer *xfer) Link Here
2089
2092
2090
		x = XREAD4(temp.sc, runt, XHCI_MFINDEX);
2093
		x = XREAD4(temp.sc, runt, XHCI_MFINDEX);
2091
2094
2092
		DPRINTF("MFINDEX=0x%08x\n", x);
2095
		DPRINTF("MFINDEX=0x%08x IST=0x%x\n", x, temp.sc->sc_ist);
2093
2096
2094
		switch (usbd_get_speed(xfer->xroot->udev)) {
2097
		switch (usbd_get_speed(xfer->xroot->udev)) {
2095
		case USB_SPEED_FULL:
2098
		case USB_SPEED_FULL:
2096
			shift = 3;
2099
			shift = 3;
2097
			temp.isoc_delta = 8;	/* 1ms */
2100
			temp.isoc_delta = 8;	/* 1ms */
2098
			x += temp.isoc_delta - 1;
2099
			x &= ~(temp.isoc_delta - 1);
2100
			break;
2101
			break;
2101
		default:
2102
		default:
2102
			shift = usbd_xfer_get_fps_shift(xfer);
2103
			shift = usbd_xfer_get_fps_shift(xfer);
2103
			temp.isoc_delta = 1U << shift;
2104
			temp.isoc_delta = 1U << shift;
2104
			x += temp.isoc_delta - 1;
2105
			x &= ~(temp.isoc_delta - 1);
2106
			/* simple frame load balancing */
2107
			x += xfer->endpoint->usb_uframe;
2108
			break;
2105
			break;
2109
		}
2106
		}
2110
2107
2111
		y = XHCI_MFINDEX_GET(x - xfer->endpoint->isoc_next);
2108
		/* Compute isochronous scheduling threshold. */
2109
		if (temp.sc->sc_ist & 8)
2110
			y = (temp.sc->sc_ist & 7) << 3;
2111
		else
2112
			y = (temp.sc->sc_ist & 7);
2112
2113
2113
		if ((xfer->endpoint->is_synced == 0) ||
2114
		/* Range check the IST. */
2114
		    (y < (xfer->nframes << shift)) ||
2115
		if (y < 8) {
2115
		    (XHCI_MFINDEX_GET(-y) >= (128 * 8))) {
2116
			y = 0;
2117
		} else if (y > 15) {
2118
			DPRINTFN(3, "IST(%d) is too big!\n", temp.sc->sc_ist);
2116
			/*
2119
			/*
2117
			 * If there is data underflow or the pipe
2120
			 * The USB stack minimum isochronous transfer
2118
			 * queue is empty we schedule the transfer a
2121
			 * size is typically 2x2 ms of payload. If the
2119
			 * few frames ahead of the current frame
2122
			 * IST makes is above 15 microframes, we have
2120
			 * position. Else two isochronous transfers
2123
			 * an effective scheduling delay of more than
2121
			 * might overlap.
2124
			 * or equal to 2 milliseconds, which is too
2125
			 * much.
2122
			 */
2126
			 */
2123
			xfer->endpoint->isoc_next = XHCI_MFINDEX_GET(x + (3 * 8));
2127
		} else {
2124
			xfer->endpoint->is_synced = 1;
2128
			/*
2125
			temp.do_isoc_sync = 1;
2129
			 * Subtract one millisecond, because the
2126
2130
			 * generic code adds that to the latency.
2127
			DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
2131
			 */
2132
			y -= 8;
2128
		}
2133
		}
2129
2134
2130
		/* compute isochronous completion time */
2135
		if (usbd_xfer_get_isochronous_start_frame(
2131
2136
		    xfer, x, y, 8, XHCI_MFINDEX_GET(-1), &temp.isoc_frame)) {
2132
		y = XHCI_MFINDEX_GET(xfer->endpoint->isoc_next - (x & ~7));
2137
			/* Start isochronous transfer at specified time. */
2138
			temp.do_isoc_sync = 1;
2133
2139
2134
		xfer->isoc_time_complete =
2140
			DPRINTFN(3, "start next=%d\n", temp.isoc_frame);
2135
		    usb_isoc_time_expand(&temp.sc->sc_bus, x / 8) +
2141
		}
2136
		    (y / 8) + (((xfer->nframes << shift) + 7) / 8);
2137
2142
2138
		x = 0;
2143
		x = 0;
2139
		temp.isoc_frame = xfer->endpoint->isoc_next;
2140
		temp.trb_type = XHCI_TRB_TYPE_ISOCH;
2144
		temp.trb_type = XHCI_TRB_TYPE_ISOCH;
2141
2145
2142
		xfer->endpoint->isoc_next += xfer->nframes << shift;
2143
2144
	} else if (xfer->flags_int.control_xfr) {
2146
	} else if (xfer->flags_int.control_xfr) {
2145
2147
2146
		/* check if we should prepend a setup message */
2148
		/* check if we should prepend a setup message */
Lines 3087-3101 xhci_device_done(struct usb_xfer *xfer, usb_error_t error) Link Here
3087
static void
3089
static void
3088
xhci_device_generic_open(struct usb_xfer *xfer)
3090
xhci_device_generic_open(struct usb_xfer *xfer)
3089
{
3091
{
3090
	if (xfer->flags_int.isochronous_xfr) {
3092
	DPRINTF("\n");
3091
		switch (xfer->xroot->udev->speed) {
3092
		case USB_SPEED_FULL:
3093
			break;
3094
		default:
3095
			usb_hs_bandwidth_alloc(xfer);
3096
			break;
3097
		}
3098
	}
3099
}
3093
}
3100
3094
3101
static void
3095
static void
Lines 3104-3119 xhci_device_generic_close(struct usb_xfer *xfer) Link Here
3104
	DPRINTF("\n");
3098
	DPRINTF("\n");
3105
3099
3106
	xhci_device_done(xfer, USB_ERR_CANCELLED);
3100
	xhci_device_done(xfer, USB_ERR_CANCELLED);
3107
3108
	if (xfer->flags_int.isochronous_xfr) {
3109
		switch (xfer->xroot->udev->speed) {
3110
		case USB_SPEED_FULL:
3111
			break;
3112
		default:
3113
			usb_hs_bandwidth_free(xfer);
3114
			break;
3115
		}
3116
	}
3117
}
3101
}
3118
3102
3119
static void
3103
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 (+69 lines)
Lines 3662-3664 usbd_xfer_maxp_was_clamped(struct usb_xfer *xfer) Link Here
3662
{
3662
{
3663
	return (xfer->flags_int.maxp_was_clamped);
3663
	return (xfer->flags_int.maxp_was_clamped);
3664
}
3664
}
3665
3666
/*
3667
 * The following function computes the next isochronous frame number
3668
 * where the first isochronous packet should be queued.
3669
 *
3670
 * The function returns non-zero if there was a discontinuity.
3671
 * Else zero is returned for normal operation.
3672
 */
3673
uint8_t
3674
usbd_xfer_get_isochronous_start_frame(struct usb_xfer *xfer, uint32_t frame_curr,
3675
    uint32_t frame_min, uint32_t frame_ms, uint32_t frame_mask, uint32_t *p_frame_start)
3676
{
3677
	uint32_t duration;
3678
	uint32_t delta;
3679
	uint8_t retval;
3680
	uint8_t shift;
3681
3682
	/* Compute time ahead of current schedule. */
3683
	delta = (xfer->endpoint->isoc_next - frame_curr) & frame_mask;
3684
3685
	/*
3686
	 * Check if it is the first transfer or if the future frame
3687
	 * delta is less than one millisecond or if the frame delta is
3688
	 * negative:
3689
	 */
3690
	if (xfer->endpoint->is_synced == 0 ||
3691
	    delta < (frame_ms + frame_min) ||
3692
	    delta > (frame_mask / 2)) {
3693
		/* Schedule transfer 2 milliseconds into the future. */
3694
		xfer->endpoint->isoc_next = (frame_curr + 2 * frame_ms + frame_min) & frame_mask;
3695
		xfer->endpoint->is_synced = 1;
3696
3697
		retval = 1;
3698
	} else {
3699
		retval = 0;
3700
	}
3701
3702
	/* Store start time, if any. */
3703
	if (p_frame_start != NULL)
3704
		*p_frame_start = xfer->endpoint->isoc_next & frame_mask;
3705
3706
	/* Get relative completion time, in milliseconds. */
3707
	delta = xfer->endpoint->isoc_next - frame_curr + (frame_curr % frame_ms);
3708
	delta &= frame_mask;
3709
	delta /= frame_ms;
3710
3711
	switch (usbd_get_speed(xfer->xroot->udev)) {
3712
	case USB_SPEED_FULL:
3713
		shift = 3;
3714
		break;
3715
	default:
3716
		shift = usbd_xfer_get_fps_shift(xfer);
3717
		break;
3718
	}
3719
3720
	/* Get duration in milliseconds, rounded up. */
3721
	duration = ((xfer->nframes << shift) + 7) / 8;
3722
3723
	/* Compute full 32-bit completion time, in milliseconds. */
3724
	xfer->isoc_time_complete =
3725
	    usb_isoc_time_expand(xfer->xroot->bus, frame_curr / frame_ms) +
3726
	    delta + duration;
3727
3728
	/* Compute next isochronous frame. */
3729
	xfer->endpoint->isoc_next += duration * frame_ms;
3730
	xfer->endpoint->isoc_next &= frame_mask;
3731
3732
	return (retval);
3733
}
(-)b/sys/dev/usb/usb_transfer.h (+1 lines)
Lines 252-256 void usbd_transfer_timeout_ms(struct usb_xfer *xfer, Link Here
252
	    void (*cb) (void *arg), usb_timeout_t ms);
252
	    void (*cb) (void *arg), usb_timeout_t ms);
253
usb_timeout_t usbd_get_dma_delay(struct usb_device *udev);
253
usb_timeout_t usbd_get_dma_delay(struct usb_device *udev);
254
void	usbd_transfer_power_ref(struct usb_xfer *xfer, int val);
254
void	usbd_transfer_power_ref(struct usb_xfer *xfer, int val);
255
uint8_t	usbd_xfer_get_isochronous_start_frame(struct usb_xfer *, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t *);
255
256
256
#endif					/* _USB_TRANSFER_H_ */
257
#endif					/* _USB_TRANSFER_H_ */

Return to bug 257082