libusb usb_interrupt_read hangs under FreeBSD

Xiaofan Chen xiaofanc at gmail.com
Wed Jul 4 17:33:11 UTC 2007


> On 4/4/07, Hans Petter Selasky <hselasky at c2i.net> wrote:
> > On Wednesday 04 April 2007 01:55, Xiaofan Chen wrote:
> > > On 4/3/07, Hans Petter Selasky <hselasky at c2i.net> wrote:
> > > > Hi,
> > > >
> > > > I think that your device is broken, and goes bad when it receives a
> > > > clear-stall request for the interrupt pipe. That is not very uncommon.
> > >
> > > Could you be more clearer? I'd like to communicate this problem
> > > to the firmware developer of PICKit 2 inside Microchip. Thanks.
> >
> > The chip does not handle a clear-stall request on the control pipe to
> > clear-stall on the interrupt pipe. The result is that the interrupt pipe
> > stops, or at least all buffers are cleared.
> >
> > I could be more detailed, but I think the developers will understand what I
> > mean.
> >

Sorry to dig out this again. I read a bit more on the firmware source code
and I found the following. Seems a bit dubious. The USB controller used
is Microchip 18F2550.

Any comments? Thanks in advance.

/******************************************************************************
* Function:        void USBStallHandler(void)
*
* PreCondition:    A STALL packet is sent to the host by the SIE.
*
* Input:           None
*
* Output:          None
*
* Side Effects:    None
*
* Overview:        The STALLIF is set anytime the SIE sends out a STALL
*                  packet regardless of which endpoint causes it.
*                  A Setup transaction overrides the STALL function. A stalled
*                  endpoint stops stalling once it receives a setup packet.
*                  In this case, the SIE will accepts the Setup packet and
*                  set the TRNIF flag to notify the firmware. STALL function
*                  for that particular endpoint pipe will be automatically
*                  disabled (direction specific).
*
*                  There are a few reasons for an endpoint to be stalled.
*                  1. When a non-supported USB request is received.
*                     Example: GET_DESCRIPTOR(DEVICE_QUALIFIER)
*                  2. When an endpoint is currently halted.
*                  3. When the device class specifies that an endpoint must
*                     stall in response to a specific event.
*                     Example: Mass Storage Device Class
*                              If the CBW is not valid, the device shall
*                              STALL the Bulk-In pipe.
*                              See USB Mass Storage Class Bulk-only Transport
*                              Specification for more details.
*
* Note:            UEPn.EPSTALL can be scanned to see which endpoint causes
*                  the stall event.
*                  If
*****************************************************************************/
void USBStallHandler(void)
{
  /*
   * Does not really have to do anything here,
   * even for the control endpoint.
   * All BDs of Endpoint 0 are owned by SIE right now,
   * but once a Setup Transaction is received, the ownership
   * for EP0_OUT will be returned to CPU.
   * When the Setup Transaction is serviced, the ownership
   * for EP0_IN will then be forced back to CPU by firmware.
   *
   * NOTE: Above description is not quite true at this point.
   *       It seems the SIE never returns the UOWN bit to CPU,
   *       and a TRNIF is never generated upon successful
   *       reception of a SETUP transaction.
   *       Firmware work-around is implemented below.
   */
  if(UEP0bits.EPSTALL == 1)
  {
      USBPrepareForNextSetupTrf();        // Firmware Work-Around
      UEP0bits.EPSTALL = 0;
  }
  UIRbits.STALLIF = 0;
}//end USBStallHandler


/******************************************************************************
* Function:        void USBPrepareForNextSetupTrf(void)
*
* PreCondition:    None
*
* Input:           None
*
* Output:          None
*
* Side Effects:    None
*
* Overview:        The routine forces EP0 OUT to be ready for a new Setup
*                  transaction, and forces EP0 IN to be owned by CPU.
*
* Note:            None
*****************************************************************************/
void USBPrepareForNextSetupTrf(void)
{
    ctrl_trf_state = WAIT_SETUP;            // See usbctrltrf.h
    ep0Bo.Cnt = EP0_BUFF_SIZE;              // Defined in usbcfg.h
    ep0Bo.ADR = (byte*)&SetupPkt;
    ep0Bo.Stat._byte = _USIE|_DAT0|_DTSEN;  // EP0 buff dsc init, see usbmmap.h
    ep0Bi.Stat._byte = _UCPU;               // EP0 IN buffer initialization
}//end USBPrepareForNextSetupTrf

/** EOF usbctrltrf.c *********************************************************/


More information about the freebsd-usb mailing list