From owner-svn-src-head@FreeBSD.ORG Sun Jun 2 11:58:32 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id F27E5D60; Sun, 2 Jun 2013 11:58:31 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id E50BC1FF8; Sun, 2 Jun 2013 11:58:31 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r52BwVEs050395; Sun, 2 Jun 2013 11:58:31 GMT (envelope-from hselasky@svn.freebsd.org) Received: (from hselasky@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r52BwVJU050394; Sun, 2 Jun 2013 11:58:31 GMT (envelope-from hselasky@svn.freebsd.org) Message-Id: <201306021158.r52BwVJU050394@svn.freebsd.org> From: Hans Petter Selasky Date: Sun, 2 Jun 2013 11:58:31 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r251251 - head/sys/dev/usb/controller X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 02 Jun 2013 11:58:32 -0000 Author: hselasky Date: Sun Jun 2 11:58:31 2013 New Revision: 251251 URL: http://svnweb.freebsd.org/changeset/base/251251 Log: Block event interrupts when we don't need it as soon as possible. Typically this feature is used for isochronous transfers. This reduces the amount of XHCI interrupting. MFC after: 1 week Modified: head/sys/dev/usb/controller/xhci.c Modified: head/sys/dev/usb/controller/xhci.c ============================================================================== --- head/sys/dev/usb/controller/xhci.c Sun Jun 2 11:44:23 2013 (r251250) +++ head/sys/dev/usb/controller/xhci.c Sun Jun 2 11:58:31 2013 (r251251) @@ -1545,6 +1545,7 @@ xhci_setup_generic_chain_sub(struct xhci { struct usb_page_search buf_res; struct xhci_td *td; + struct xhci_td *td_first; struct xhci_td *td_next; struct xhci_td *td_alt_next; uint32_t buf_offset; @@ -1564,7 +1565,7 @@ xhci_setup_generic_chain_sub(struct xhci restart: td = temp->td; - td_next = temp->td_next; + td_next = td_first = temp->td_next; while (1) { @@ -1698,7 +1699,9 @@ restart: td->td_trb[x].dwTrb2 = htole32(dword); + /* BEI: Interrupts are inhibited until EOT */ dword = XHCI_TRB_3_CHAIN_BIT | XHCI_TRB_3_CYCLE_BIT | + XHCI_TRB_3_BEI_BIT | XHCI_TRB_3_TYPE_SET(temp->trb_type) | XHCI_TRB_3_TBC_SET(temp->tbc) | XHCI_TRB_3_TLBPC_SET(temp->tlbpc); @@ -1761,8 +1764,10 @@ restart: td->td_trb[x].dwTrb2 = htole32(dword); + /* BEI: interrupts are inhibited until EOT */ dword = XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_LINK) | - XHCI_TRB_3_CYCLE_BIT | XHCI_TRB_3_IOC_BIT; + XHCI_TRB_3_CYCLE_BIT | XHCI_TRB_3_IOC_BIT | + XHCI_TRB_3_BEI_BIT; td->td_trb[x].dwTrb3 = htole32(dword); @@ -1790,9 +1795,14 @@ restart: goto restart; } - /* remove cycle bit from first if we are stepping the TRBs */ - if (temp->step_td) - td->td_trb[0].dwTrb3 &= ~htole32(XHCI_TRB_3_CYCLE_BIT); + /* need to force an interrupt if we are stepping the TRBs */ + if ((temp->direction & UE_DIR_IN) != 0 && temp->multishort == 0) { + /* remove cycle bit from first TRB if we are stepping them */ + if (temp->step_td) + td_first->td_trb[0].dwTrb3 &= ~htole32(XHCI_TRB_3_CYCLE_BIT); + /* make sure the last LINK event generates an interrupt */ + td->td_trb[td->ntrb].dwTrb3 &= ~htole32(XHCI_TRB_3_BEI_BIT); + } /* remove chain bit because this is the last TRB in the chain */ td->td_trb[td->ntrb - 1].dwTrb2 &= ~htole32(XHCI_TRB_2_TDSZ_SET(15)); @@ -2655,6 +2665,7 @@ xhci_transfer_insert(struct usb_xfer *xf { struct xhci_td *td_first; struct xhci_td *td_last; + struct xhci_trb *trb_link; struct xhci_endpoint_ext *pepext; uint64_t addr; usb_stream_t id; @@ -2730,11 +2741,15 @@ xhci_transfer_insert(struct usb_xfer *xf /* compute terminating return address */ addr += (inext * sizeof(struct xhci_trb)); + /* compute link TRB pointer */ + trb_link = td_last->td_trb + td_last->ntrb; + /* update next pointer of last link TRB */ - td_last->td_trb[td_last->ntrb].qwTrb0 = htole64(addr); - td_last->td_trb[td_last->ntrb].dwTrb2 = htole32(XHCI_TRB_2_IRQ_SET(0)); - td_last->td_trb[td_last->ntrb].dwTrb3 = htole32(XHCI_TRB_3_IOC_BIT | - XHCI_TRB_3_CYCLE_BIT | XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_LINK)); + trb_link->qwTrb0 = htole64(addr); + trb_link->dwTrb2 = htole32(XHCI_TRB_2_IRQ_SET(0)); + trb_link->dwTrb3 = htole32(XHCI_TRB_3_IOC_BIT | + XHCI_TRB_3_CYCLE_BIT | + XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_LINK)); #ifdef USB_DEBUG xhci_dump_trb(&td_last->td_trb[td_last->ntrb]);