Author: hselasky
Date: Sun Jul 21 20:45:23 2013
New Revision: 253532
URL: http://svnweb.freebsd.org/changeset/base/253532

Log:
  Fix an XHCI regression:
  
  The Block Event Interrupts, BEI, feature does not
  work like expected with the Renesas XHCI chipsets.
  Revert feature.
  
  While at it correct the TD SIZE computation in
  case of Zero Length Packet, ZLP, in the end of a
  multi frame USB transfer.
  
  MFC after:    1 week
  PR:           usb/180726

Modified:
  head/sys/dev/usb/controller/xhci.c

Modified: head/sys/dev/usb/controller/xhci.c
==============================================================================
--- head/sys/dev/usb/controller/xhci.c  Sun Jul 21 19:44:53 2013        
(r253531)
+++ head/sys/dev/usb/controller/xhci.c  Sun Jul 21 20:45:23 2013        
(r253532)
@@ -1682,7 +1682,6 @@ restart:
                        /* fill out buffer pointers */
 
                        if (average == 0) {
-                               npkt = 0;
                                memset(&buf_res, 0, sizeof(buf_res));
                        } else {
                                usbd_get_page(temp->pc, temp->offset +
@@ -1697,15 +1696,17 @@ restart:
                                        buf_res.length = XHCI_TD_PAGE_SIZE;
 
                                npkt_off += buf_res.length;
-
-                               /* setup npkt */
-                               npkt = (len_old - npkt_off + 
temp->max_packet_size - 1) /
-                                   temp->max_packet_size;
-
-                               if (npkt > 31)
-                                       npkt = 31;
                        }
 
+                       /* setup npkt */
+                       npkt = (len_old - npkt_off + temp->max_packet_size - 1) 
/
+                           temp->max_packet_size;
+
+                       if (npkt == 0)
+                               npkt = 1;
+                       else if (npkt > 31)
+                               npkt = 31;
+
                        /* fill out TRB's */
                        td->td_trb[x].qwTrb0 =
                            htole64((uint64_t)buf_res.physaddr);
@@ -1719,9 +1720,7 @@ restart:
 
                        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) {
@@ -1756,10 +1755,8 @@ restart:
                                        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)
@@ -1838,6 +1835,7 @@ restart:
                usb_pc_cpu_flush(td_first->page_cache);
        }
 
+       /* clear TD SIZE to zero, hence this is the last TRB */
        /* 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));
        td->td_trb[td->ntrb - 1].dwTrb3 &= ~htole32(XHCI_TRB_3_CHAIN_BIT);
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to