The following reply was made to PR usb/179342; it has been noted by GNATS.

From: dfil...@freebsd.org (dfilter service)
To: bug-follo...@freebsd.org
Cc:  
Subject: Re: usb/179342: commit references a PR
Date: Fri,  7 Jun 2013 22:36:05 +0000 (UTC)

 Author: hselasky
 Date: Fri Jun  7 22:35:58 2013
 New Revision: 251515
 URL: http://svnweb.freebsd.org/changeset/base/251515
 
 Log:
   Fix some recent regression issues:
   
   1) Only multi-TD isochronous transfers should use NORMAL
   type after specific type as per XHCI specification.
   
   2) BEI bit is only available in NORMAL and ISOCHRONOUS
   TRB types. Don't use this bit for other types to avoid
   hardware asserts. Reserved bits should be don't care
   though ...
   
   MFC after:   1 week
   PR:          usb/179342
 
 Modified:
   head/sys/dev/usb/controller/xhci.c
 
 Modified: head/sys/dev/usb/controller/xhci.c
 ==============================================================================
 --- head/sys/dev/usb/controller/xhci.c Fri Jun  7 22:01:06 2013        
(r251514)
 +++ head/sys/dev/usb/controller/xhci.c Fri Jun  7 22:35:58 2013        
(r251515)
 @@ -1561,6 +1561,7 @@ 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;
 @@ -1569,7 +1570,6 @@ xhci_setup_generic_chain_sub(struct xhci
        uint8_t shortpkt_old;
        uint8_t precompute;
        uint8_t x;
 -      uint8_t first_trb = 1;
  
        td_alt_next = NULL;
        buf_offset = 0;
 @@ -1581,7 +1581,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) {
  
 @@ -1717,48 +1717,55 @@ 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_TBC_SET(temp->tbc) |
 -                        XHCI_TRB_3_TLBPC_SET(temp->tlbpc);
 -
 -                      if (first_trb != 0) {
 -                              first_trb = 0;
 -                              dword |= XHCI_TRB_3_TYPE_SET(temp->trb_type);
 -                              /*
 -                               * Remove cycle bit from the first TRB
 -                               * if we are stepping them:
 -                               */
 -                              if (temp->step_td != 0)
 -                                      dword &= ~XHCI_TRB_3_CYCLE_BIT;
 -                      } else {
 -                              dword |= 
XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_NORMAL);
 -                      }
 -                      if (temp->trb_type == XHCI_TRB_TYPE_ISOCH) {
 -                              if (temp->do_isoc_sync != 0) {
 +                      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;
 -                                      dword |= 
XHCI_TRB_3_FRID_SET(temp->isoc_frame / 8);
 +                                      /* wait until "isoc_frame" */
 +                                      dword |= 
XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_ISOCH) |
 +                                          
XHCI_TRB_3_FRID_SET(temp->isoc_frame / 8);
                                } else {
 -                                      dword |= XHCI_TRB_3_ISO_SIA_BIT;
 +                                      /* 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;
                        }
 -                      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;
 -                      }
 -
                        td->td_trb[x].dwTrb3 = htole32(dword);
  
                        average -= buf_res.length;
 @@ -1793,10 +1800,8 @@ 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_BEI_BIT;
 +                  XHCI_TRB_3_CYCLE_BIT | XHCI_TRB_3_IOC_BIT;
  
                td->td_trb[x].dwTrb3 = htole32(dword);
  
 @@ -1824,10 +1829,13 @@ restart:
                goto restart;
        }
  
 -      /* need to force an interrupt if we are stepping the TRBs */
 -      if ((temp->direction & UE_DIR_IN) != 0 && temp->multishort == 0) {
 -              /* make sure the last LINK event generates an interrupt */
 -              td->td_trb[td->ntrb].dwTrb3 &= ~htole32(XHCI_TRB_3_BEI_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 */
 _______________________________________________
 svn-src-...@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
 
_______________________________________________
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"

Reply via email to