From owner-svn-src-stable@FreeBSD.ORG Tue Jun 11 06:18:52 2013 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 98A8B8F0; Tue, 11 Jun 2013 06:18:52 +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 8A1411D73; Tue, 11 Jun 2013 06:18:52 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r5B6Iq1A005903; Tue, 11 Jun 2013 06:18:52 GMT (envelope-from hselasky@svn.freebsd.org) Received: (from hselasky@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r5B6IqB6005901; Tue, 11 Jun 2013 06:18:52 GMT (envelope-from hselasky@svn.freebsd.org) Message-Id: <201306110618.r5B6IqB6005901@svn.freebsd.org> From: Hans Petter Selasky Date: Tue, 11 Jun 2013 06:18:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r251614 - stable/9/sys/dev/usb/controller X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Jun 2013 06:18:52 -0000 Author: hselasky Date: Tue Jun 11 06:18:51 2013 New Revision: 251614 URL: http://svnweb.freebsd.org/changeset/base/251614 Log: MFC r251249, r251251, r251252, r2512, r251254 and r251515: Correct XHCI DMA descriptor programming. Correct maximum IRQ rate. Modified: stable/9/sys/dev/usb/controller/xhci.c stable/9/sys/dev/usb/controller/xhcireg.h Directory Properties: stable/9/sys/ (props changed) stable/9/sys/dev/ (props changed) Modified: stable/9/sys/dev/usb/controller/xhci.c ============================================================================== --- stable/9/sys/dev/usb/controller/xhci.c Tue Jun 11 03:37:29 2013 (r251613) +++ stable/9/sys/dev/usb/controller/xhci.c Tue Jun 11 06:18:51 2013 (r251614) @@ -1533,9 +1533,11 @@ xhci_setup_generic_chain_sub(struct xhci struct xhci_td *td; struct xhci_td *td_next; struct xhci_td *td_alt_next; + struct xhci_td *td_first; uint32_t buf_offset; uint32_t average; uint32_t len_old; + uint32_t npkt_off; uint32_t dword; uint8_t shortpkt_old; uint8_t precompute; @@ -1545,12 +1547,13 @@ xhci_setup_generic_chain_sub(struct xhci buf_offset = 0; shortpkt_old = temp->shortpkt; len_old = temp->len; + npkt_off = 0; precompute = 1; restart: td = temp->td; - td_next = temp->td_next; + td_next = td_first = temp->td_next; while (1) { @@ -1651,7 +1654,7 @@ restart: /* fill out buffer pointers */ if (average == 0) { - npkt = 1; + npkt = 0; memset(&buf_res, 0, sizeof(buf_res)); } else { usbd_get_page(temp->pc, temp->offset + @@ -1665,8 +1668,10 @@ restart: if (buf_res.length > XHCI_TD_PAGE_SIZE) buf_res.length = XHCI_TD_PAGE_SIZE; + npkt_off += buf_res.length; + /* setup npkt */ - npkt = (average + temp->max_packet_size - 1) / + npkt = (len_old - npkt_off + temp->max_packet_size - 1) / temp->max_packet_size; if (npkt > 31) @@ -1684,32 +1689,55 @@ restart: td->td_trb[x].dwTrb2 = htole32(dword); - dword = XHCI_TRB_3_CHAIN_BIT | XHCI_TRB_3_CYCLE_BIT | - XHCI_TRB_3_TYPE_SET(temp->trb_type) | - (temp->do_isoc_sync ? - XHCI_TRB_3_FRID_SET(temp->isoc_frame / 8) : - XHCI_TRB_3_ISO_SIA_BIT) | - XHCI_TRB_3_TBC_SET(temp->tbc) | - XHCI_TRB_3_TLBPC_SET(temp->tlbpc); - - temp->do_isoc_sync = 0; - - if (temp->direction == UE_DIR_IN) { - dword |= XHCI_TRB_3_DIR_IN; - - /* - * NOTE: Only the SETUP stage should - * use the IDT bit. Else transactions - * can be sent using the wrong data - * toggle value. - */ - if (temp->trb_type != - XHCI_TRB_TYPE_SETUP_STAGE && - temp->trb_type != - XHCI_TRB_TYPE_STATUS_STAGE) - dword |= XHCI_TRB_3_ISP_BIT; + switch (temp->trb_type) { + case XHCI_TRB_TYPE_ISOCH: + /* 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_TBC_SET(temp->tbc) | + XHCI_TRB_3_TLBPC_SET(temp->tlbpc); + if (td != td_first) { + dword |= XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_NORMAL); + } else if (temp->do_isoc_sync != 0) { + temp->do_isoc_sync = 0; + /* wait until "isoc_frame" */ + dword |= XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_ISOCH) | + XHCI_TRB_3_FRID_SET(temp->isoc_frame / 8); + } else { + /* start data transfer at next interval */ + dword |= XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_ISOCH) | + XHCI_TRB_3_ISO_SIA_BIT; + } + if (temp->direction == UE_DIR_IN) + dword |= XHCI_TRB_3_DIR_IN | XHCI_TRB_3_ISP_BIT; + break; + case XHCI_TRB_TYPE_DATA_STAGE: + dword = XHCI_TRB_3_CHAIN_BIT | XHCI_TRB_3_CYCLE_BIT | + XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_DATA_STAGE) | + XHCI_TRB_3_TBC_SET(temp->tbc) | + XHCI_TRB_3_TLBPC_SET(temp->tlbpc); + if (temp->direction == UE_DIR_IN) + dword |= XHCI_TRB_3_DIR_IN | XHCI_TRB_3_ISP_BIT; + break; + case XHCI_TRB_TYPE_STATUS_STAGE: + dword = XHCI_TRB_3_CHAIN_BIT | XHCI_TRB_3_CYCLE_BIT | + XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_STATUS_STAGE) | + XHCI_TRB_3_TBC_SET(temp->tbc) | + XHCI_TRB_3_TLBPC_SET(temp->tlbpc); + if (temp->direction == UE_DIR_IN) + dword |= XHCI_TRB_3_DIR_IN; + break; + default: /* XHCI_TRB_TYPE_NORMAL */ + /* BEI: Interrupts are inhibited until EOT */ + dword = XHCI_TRB_3_CHAIN_BIT | XHCI_TRB_3_CYCLE_BIT | + XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_NORMAL) | + XHCI_TRB_3_BEI_BIT | + XHCI_TRB_3_TBC_SET(temp->tbc) | + XHCI_TRB_3_TLBPC_SET(temp->tlbpc); + if (temp->direction == UE_DIR_IN) + dword |= XHCI_TRB_3_DIR_IN | XHCI_TRB_3_ISP_BIT; + break; } - td->td_trb[x].dwTrb3 = htole32(dword); average -= buf_res.length; @@ -1773,9 +1801,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); + /* + * Remove cycle bit from the first TRB if we are + * stepping them: + */ + if (temp->step_td != 0) { + td_first->td_trb[0].dwTrb3 &= ~htole32(XHCI_TRB_3_CYCLE_BIT); + usb_pc_cpu_flush(td_first->page_cache); + } /* 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)); @@ -2601,6 +2634,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; uint8_t i; @@ -2666,11 +2700,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]); Modified: stable/9/sys/dev/usb/controller/xhcireg.h ============================================================================== --- stable/9/sys/dev/usb/controller/xhcireg.h Tue Jun 11 03:37:29 2013 (r251613) +++ stable/9/sys/dev/usb/controller/xhcireg.h Tue Jun 11 06:18:51 2013 (r251614) @@ -166,7 +166,7 @@ #define XHCI_IMOD_IVAL_SET(x) (((x) & 0xFFFF) << 0) /* 250ns unit */ #define XHCI_IMOD_ICNT_GET(x) (((x) >> 16) & 0xFFFF) /* 250ns unit */ #define XHCI_IMOD_ICNT_SET(x) (((x) & 0xFFFF) << 16) /* 250ns unit */ -#define XHCI_IMOD_DEFAULT 0x000001F4U /* 8000 IRQ/second */ +#define XHCI_IMOD_DEFAULT 0x000003E8U /* 8000 IRQ/second */ #define XHCI_ERSTSZ(n) (0x0028 + (0x20 * (n))) /* XHCI event ring segment table size */ #define XHCI_ERSTS_GET(x) ((x) & 0xFFFF) #define XHCI_ERSTS_SET(x) ((x) & 0xFFFF)