Re: usb/179342: commit references a PR

2013-06-07 Thread dfilter service
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 14:30:20 + (UTC)

 Author: hselasky
 Date: Fri Jun  7 14:30:06 2013
 New Revision: 251499
 URL: http://svnweb.freebsd.org/changeset/base/251499
 
 Log:
   Add support for polling the XHCI interrupt handler when
   the regular interrupt handler is not working properly or
   in case of MSI interrupts which are not yet supported.
   Remove interrupt setup code for FreeBSD versions older
   than 700031.
   
   MFC after:   1 week
   PR:  usb/179342
 
 Modified:
   head/sys/dev/usb/controller/xhci.c
   head/sys/dev/usb/controller/xhci.h
   head/sys/dev/usb/controller/xhci_pci.c
 
 Modified: head/sys/dev/usb/controller/xhci.c
 ==
 --- head/sys/dev/usb/controller/xhci.c Fri Jun  7 14:23:11 2013
(r251498)
 +++ head/sys/dev/usb/controller/xhci.c Fri Jun  7 14:30:06 2013
(r251499)
 @@ -90,6 +90,7 @@
  #ifdef USB_DEBUG
  static int xhcidebug;
  static int xhciroute;
 +static int xhcipolling;
  
  static SYSCTL_NODE(_hw_usb, OID_AUTO, xhci, CTLFLAG_RW, 0, USB XHCI);
  SYSCTL_INT(_hw_usb_xhci, OID_AUTO, debug, CTLFLAG_RW | CTLFLAG_TUN,
 @@ -98,6 +99,9 @@ TUNABLE_INT(hw.usb.xhci.debug, xhcide
  SYSCTL_INT(_hw_usb_xhci, OID_AUTO, xhci_port_route, CTLFLAG_RW | CTLFLAG_TUN,
  xhciroute, 0, Routing bitmap for switching EHCI ports to XHCI 
controller);
  TUNABLE_INT(hw.usb.xhci.xhci_port_route, xhciroute);
 +SYSCTL_INT(_hw_usb_xhci, OID_AUTO, use_polling, CTLFLAG_RW | CTLFLAG_TUN,
 +xhcipolling, 0, Set to enable software interrupt polling for XHCI 
controller);
 +TUNABLE_INT(hw.usb.xhci.use_polling, xhcipolling);
  #endif
  
  #define   XHCI_INTR_ENDPT 1
 @@ -194,6 +198,16 @@ xhci_get_port_route(void)
  #endif
  }
  
 +uint8_t
 +xhci_use_polling(void)
 +{
 +#ifdef USB_DEBUG
 +  return (xhcipolling != 0);
 +#else
 +  return (0);
 +#endif
 +}
 +
  static void
  xhci_iterate_hw_softc(struct usb_bus *bus, usb_bus_mem_sub_cb_t *cb)
  {
 
 Modified: head/sys/dev/usb/controller/xhci.h
 ==
 --- head/sys/dev/usb/controller/xhci.h Fri Jun  7 14:23:11 2013
(r251498)
 +++ head/sys/dev/usb/controller/xhci.h Fri Jun  7 14:30:06 2013
(r251499)
 @@ -438,6 +438,8 @@ struct xhci_softc {
/* configure message */
struct usb_bus_msg  sc_config_msg[2];
  
 +  struct usb_callout  sc_callout;
 +
union xhci_hub_desc sc_hub_desc;
  
struct cv   sc_cmd_cv;
 @@ -500,6 +502,7 @@ struct xhci_softc {
  /* prototypes */
  
  uint32_t  xhci_get_port_route(void);
 +uint8_t   xhci_use_polling(void);
  usb_error_t xhci_halt_controller(struct xhci_softc *);
  usb_error_t xhci_init(struct xhci_softc *, device_t);
  usb_error_t xhci_start_controller(struct xhci_softc *);
 
 Modified: head/sys/dev/usb/controller/xhci_pci.c
 ==
 --- head/sys/dev/usb/controller/xhci_pci.c Fri Jun  7 14:23:11 2013
(r251498)
 +++ head/sys/dev/usb/controller/xhci_pci.c Fri Jun  7 14:30:06 2013
(r251499)
 @@ -132,6 +132,16 @@ xhci_pci_probe(device_t self)
}
  }
  
 +static void
 +xhci_interrupt_poll(void *_sc)
 +{
 +  struct xhci_softc *sc = _sc;
 +  USB_BUS_UNLOCK(sc-sc_bus);
 +  xhci_interrupt(sc);
 +  USB_BUS_LOCK(sc-sc_bus);
 +  usb_callout_reset(sc-sc_callout, 1, (void *)xhci_interrupt_poll, sc);
 +}
 +
  static int
  xhci_pci_attach(device_t self)
  {
 @@ -159,12 +169,13 @@ xhci_pci_attach(device_t self)
sc-sc_io_hdl = rman_get_bushandle(sc-sc_io_res);
sc-sc_io_size = rman_get_size(sc-sc_io_res);
  
 +  usb_callout_init_mtx(sc-sc_callout, sc-sc_bus.bus_mtx, 0);
 +
rid = 0;
sc-sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, rid,
RF_SHAREABLE | RF_ACTIVE);
if (sc-sc_irq_res == NULL) {
device_printf(self, Could not allocate IRQ\n);
 -  goto error;
}
sc-sc_bus.bdev = device_add_child(self, usbus, -1);
if (sc-sc_bus.bdev == NULL) {
 @@ -175,18 +186,22 @@ xhci_pci_attach(device_t self)
  
sprintf(sc-sc_vendor, 0x%04x, pci_get_vendor(self));
  
 -#if (__FreeBSD_version = 700031)
 -  err = bus_setup_intr(self, sc-sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
 -  NULL, (driver_intr_t *)xhci_interrupt, sc, sc-sc_intr_hdl);
 -#else
 -  err = bus_setup_intr(self, sc-sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
 -  (driver_intr_t *)xhci_interrupt, sc, sc-sc_intr_hdl);
 -#endif
 -  if (err) {
 -  device_printf(self, Could not setup IRQ, err=%d\n, err);
 -  sc-sc_intr_hdl = NULL;
 -  goto error

Re: usb/179342: commit references a PR

2013-06-07 Thread dfilter service
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 + (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