From owner-p4-projects@FreeBSD.ORG Sun Aug 8 14:59:20 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 474B91065688; Sun, 8 Aug 2010 14:59:19 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A2BB31065676 for ; Sun, 8 Aug 2010 14:59:17 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 8F6B68FC15 for ; Sun, 8 Aug 2010 14:59:17 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.4/8.14.4) with ESMTP id o78ExH40013493 for ; Sun, 8 Aug 2010 14:59:17 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.4/8.14.4/Submit) id o78ExHsF013491 for perforce@freebsd.org; Sun, 8 Aug 2010 14:59:17 GMT (envelope-from hselasky@FreeBSD.org) Date: Sun, 8 Aug 2010 14:59:17 GMT Message-Id: <201008081459.o78ExHsF013491@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 182090 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 08 Aug 2010 14:59:20 -0000 http://p4web.freebsd.org/@@182090?ac=10 Change 182090 by hselasky@hselasky_laptop001 on 2010/08/08 14:58:42 USB controller (XHCI): - more bugfixes Affected files ... .. //depot/projects/usb/src/sys/dev/usb/controller/xhci.c#17 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb/controller/xhci.c#17 (text+ko) ==== @@ -652,7 +652,7 @@ status = XHCI_TRB_2_ERROR_GET(temp); temp = le32toh(trb->dwTrb3); - epno = XHCI_TRB_3_EP_GET(temp) + 1; + epno = XHCI_TRB_3_EP_GET(temp); index = XHCI_TRB_3_SLOT_GET(temp); /* check if error means halted */ @@ -667,9 +667,7 @@ return; } - epno++; - - if (epno >= XHCI_MAX_ENDPOINTS) { + if ((epno == 0) || (epno >= XHCI_MAX_ENDPOINTS)) { DPRINTF("Invalid endpoint.\n"); return; } @@ -688,14 +686,15 @@ td = xfer->td_transfer_cache; - DPRINTFN(5, "Checking if 0x%016llx == (0x%016llx .. 0x%016llx)\n", + DPRINTFN(5, "Checking if 0x%016llx == (0x%016llx .. 0x%016llx +/- 16)\n", (long long)td_event, (long long)td->td_self, (long long)td->td_event_last); if ((td_event == td->td_event_last) || + (td_event == (td->td_event_last - 16)) || (halted && (td_event >= td->td_self) && - (td_event < td->td_event_last))) { + (td_event <= td->td_event_last))) { usb_pc_cpu_invalidate(td->page_cache); @@ -1066,17 +1065,18 @@ switch (hdev->state) { case XHCI_ST_ADDRESSED: + case XHCI_ST_CONFIGURED: err = 0; break; - case XHCI_ST_ENABLED: + case XHCI_ST_DEFAULT: if (address == 0) { err = 0; break; } /* FALLTHROUGH */ - case XHCI_ST_DEFAULT: + case XHCI_ST_ENABLED: /* set configure mask to slot and EP0 */ xhci_configure_mask(udev, 3, 0); @@ -1149,7 +1149,6 @@ return (err); } -#if 0 static usb_error_t xhci_cmd_configure_ep(struct xhci_softc *sc, uint64_t input_ctx, uint8_t deconfigure, uint8_t slot_id) @@ -1171,7 +1170,6 @@ return (xhci_do_command(sc, &trb, 50 /* ms */)); } -#endif static usb_error_t xhci_cmd_evaluate_ctx(struct xhci_softc *sc, uint64_t input_ctx, @@ -1546,7 +1544,7 @@ /* compute event pointer */ addr = td->td_self; - addr += (x - 1) * sizeof(struct xhci_trb); + addr += x * sizeof(struct xhci_trb); td->td_event_last = addr; /* fill out link TRB */ @@ -2046,8 +2044,16 @@ route |= rh_port; } - temp = XHCI_SCTX_0_CTX_NUM_SET(XHCI_MAX_ENDPOINTS - 1) | - XHCI_SCTX_0_ROUTE_SET(route); + temp = XHCI_SCTX_0_ROUTE_SET(route); + + switch (sc->sc_hw.devs[index].state) { + case XHCI_ST_CONFIGURED: + temp |= XHCI_SCTX_0_CTX_NUM_SET(XHCI_MAX_ENDPOINTS - 1); + break; + default: + temp = XHCI_SCTX_0_CTX_NUM_SET(1); + break; + } switch (udev->speed) { case USB_SPEED_LOW: @@ -2298,10 +2304,15 @@ uint64_t addr; uint8_t i; uint8_t inext; + uint8_t trb_limit; + + DPRINTFN(8, "\n"); /* check if already inserted */ - if (xfer->flags_int.bandwidth_reclaimed) + if (xfer->flags_int.bandwidth_reclaimed) { + DPRINTFN(8, "Already in schedule\n"); return (0); + } pepext = xhci_get_endpoint_ext(xfer->xroot->udev, xfer->endpoint->edesc); @@ -2310,7 +2321,19 @@ td_last = xfer->td_transfer_last; addr = pepext->physaddr; - if (pepext->trb_used >= (XHCI_MAX_TRANSFERS - 1)) { + switch (xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE) { + case UE_CONTROL: + case UE_INTERRUPT: + /* single buffered */ + trb_limit = 1; + break; + default: + /* multi buffered */ + trb_limit = (XHCI_MAX_TRANSFERS - 2); + break; + } + + if (pepext->trb_used >= trb_limit) { DPRINTFN(8, "Too many TDs queued.\n"); return (USB_ERR_NOMEM); } @@ -2331,6 +2354,8 @@ if (pepext->trb_running == 0) { struct xhci_softc *sc = XHCI_BUS2SC(xfer->xroot->bus); + DPRINTFN(8, "Not running\n"); + /* start configuration */ (void)usb_proc_msignal(&sc->sc_config_proc, &sc->sc_config_msg[0], &sc->sc_config_msg[1]); @@ -2386,6 +2411,8 @@ usb_pc_cpu_flush(pepext->page_cache); + DPRINTF("qh_pos = %u\n", i); + pepext->xfer[i] = xfer; xfer->qh_pos = i; @@ -2396,6 +2423,10 @@ xhci_endpoint_doorbell(xfer); + /* start timeout, if any */ + if (xfer->timeout != 0) + usbd_transfer_timeout_ms(xfer, &xhci_timeout, xfer->timeout); + return (0); } @@ -2482,14 +2513,7 @@ DPRINTF("\n"); /* try to insert xfer on HW queue */ - if (xhci_transfer_insert(xfer) != 0) { - DPRINTFN(0, "Failed to insert " - "transfer %p into HW queue.\n", xfer); - } - - /* start timeout, if any */ - if (xfer->timeout != 0) - usbd_transfer_timeout_ms(xfer, &xhci_timeout, xfer->timeout); + xhci_transfer_insert(xfer); } struct usb_pipe_methods xhci_device_generic_methods = @@ -3181,6 +3205,8 @@ struct usb_page_search buf_hub; + DPRINTF("Configure HUB\n"); + usbd_get_page(&sc->sc_hw.devs[ hub->controller_slot_id].input_pc, 0, &buf_hub); @@ -3203,17 +3229,42 @@ err = xhci_configure_endpoint_by_xfer(xfer); if (err == 0) { - err = xhci_cmd_stop_ep(sc, 0, epno - 1, index); + + err = xhci_cmd_reset_ep(sc, 0, epno, index); if (err != 0) - DPRINTF("Could not stop endpoint\n"); + DPRINTF("Could not reset endpoint %u\n", epno); + + if (epno > 1) { + + err = xhci_cmd_stop_ep(sc, 0, epno, index); + + if (err != 0) + DPRINTF("Could not stop endpoint %u\n", epno); + + if (sc->sc_hw.devs[index].state != XHCI_ST_CONFIGURED) { + sc->sc_hw.devs[index].state = XHCI_ST_CONFIGURED; + + xhci_configure_mask(udev, 1, 0); + + err = xhci_configure_device(udev); + + if (err != 0) + DPRINTF("Could not deconfigure device\n"); + + err = xhci_cmd_evaluate_ctx(sc, buf_inp.physaddr, index); + + if (err != 0) + DPRINTF("Could not evaluate device\n"); + } - xhci_configure_mask(udev, 1U << epno, 1); + xhci_configure_mask(udev, 1U << epno, 1); - err = xhci_cmd_evaluate_ctx(sc, buf_inp.physaddr, index); + err = xhci_cmd_evaluate_ctx(sc, buf_inp.physaddr, index); - if (err != 0) - DPRINTF("Could not deconfigure endpoint %u\n", epno); + if (err != 0) + DPRINTF("Could not deconfigure endpoint %u\n", epno); + } xhci_configure_mask(udev, 1U << epno, 0); @@ -3221,20 +3272,20 @@ if (err != 0) DPRINTF("Could not configure endpoint %u\n", epno); + + err = xhci_cmd_configure_ep(sc, buf_inp.physaddr, 0, index); + + if (err != 0) + DPRINTF("Could not configure endpoint %u\n", epno); } /* reset endpoint */ if (err == 0) { - if ((edesc->bmAttributes & UE_XFERTYPE) == UE_BULK) - err = xhci_cmd_reset_ep(sc, 0, epno - 1, index); + err = xhci_cmd_set_tr_dequeue_ptr(sc, pepext->physaddr | + XHCI_EPCTX_2_DCS_SET(1), 0, epno, index); if (err != 0) - DPRINTF("Could not reset endpoint %u\n", epno); - - err = xhci_cmd_set_tr_dequeue_ptr(sc, pepext->physaddr, 0, epno - 1, index); - - if (err != 0) DPRINTF("Could not set dequeue ptr for endpoint %u\n", epno); } XHCI_CMD_UNLOCK(sc); @@ -3302,7 +3353,7 @@ /* check if halted is still cleared */ if (pepext->trb_halted == 0) { pepext->trb_running = 1; - pepext->trb_index = 1; + pepext->trb_index = 0; } goto restart; } @@ -3317,7 +3368,6 @@ /* queue changed - restart */ goto restart; - } }