[PATCH v15 07/10] USB/ppc4xx: Add Synopsys DWC OTG PCD function

Pratyush Anand pratyush.anand at gmail.com
Thu Oct 20 20:55:54 EST 2011


On Sat, Oct 15, 2011 at 3:39 AM,  <tmarri at apm.com> wrote:
> From: Tirumala Marri <tmarri at apm.com>
>
> The PCD is responsible for translating requests from the gadget driver
> to appropriate actions on the DWC OTG controller.
>

[...]

> +static int dwc_otg_pcd_ep_disable(struct usb_ep *_ep)
> +{
> +       struct pcd_ep *ep;
> +       struct core_if *core_if;
> +       unsigned long flags;
> +
> +       ep = container_of(_ep, struct pcd_ep, ep);
> +       if (!_ep || !ep->desc)
> +               return -EINVAL;
> +
> +       core_if = ep->pcd->otg_dev->core_if;
> +
> +       spin_lock_irqsave(&ep->pcd->lock, flags);
> +
> +       request_nuke(ep);
> +       dwc_otg_ep_deactivate(core_if, &ep->dwc_ep);
> +
> +       ep->desc = NULL;
> +       ep->stopped = 1;
> +       if (ep->dwc_ep.is_in) {
> +               release_perio_tx_fifo(core_if, ep->dwc_ep.tx_fifo_num);
> +               release_tx_fifo(core_if, ep->dwc_ep.tx_fifo_num);

Is only releasing fifo sufficient?
Will the above procedure insures that EP is disable?
I think not.
To insure that EP is disabled , you need to fllow steps as defines in specs.

Also, Fifo must be flushed completely.

Just a question: Which test have you run to test the driver?

I had tested your v13 with testusb and zero gadget and found that all the IN
test were failing because of this limitation.


> +       }
> +

[...]

> +/**
> + * Set the EP STALL.
> + */
> +void dwc_otg_ep_set_stall(struct core_if *core_if, struct dwc_ep *ep)
> +{
> +       u32 depctl = 0;
> +       ulong depctl_addr;
> +
> +       if (ep->is_in) {
> +               depctl_addr =
> +                   (core_if->dev_if->in_ep_regs[ep->num]) + DWC_DIEPCTL;
> +               depctl = dwc_reg_read(depctl_addr, 0);
> +
> +               /* set the disable and stall bits */
> +               if (DWC_DEPCTL_EPENA_RD(depctl))
> +                       depctl = DWC_DEPCTL_EPDIS_RW(depctl, 1);
> +               depctl = DWC_DEPCTL_STALL_HNDSHK_RW(depctl, 1);
> +               dwc_reg_write(depctl_addr, 0, depctl);

After stall bit set, you must disable EP.
Also you must clear TX fifo completetly for respective EP.


> +       } else {
> +               depctl_addr =
> +                   (core_if->dev_if->out_ep_regs[ep->num] + DWC_DOEPCTL);
> +               depctl = dwc_reg_read(depctl_addr, 0);
> +
> +               /* set the stall bit */
> +               depctl = DWC_DEPCTL_STALL_HNDSHK_RW(depctl, 1);
> +               dwc_reg_write(depctl_addr, 0, depctl);
> +       }
> +}

Regards
Pratyush


More information about the Linuxppc-dev mailing list