By moving our sanity checks our internal function
__dwc3_gadget_ep_queue() we can simplify the
externally visible API while also making sure that
callers of __dwc3_gadget_ep_queue() also make use of
the same checks.
Signed-off-by: Felipe Balbi <balbi@ti.com>
Because interrupt endpoints usually transmit such
small amounts of data, it seems pointless to prestart
transfers and try to get speed improvements. This
patch also sorts out a problem with CDC ECM function
where its notification endpoint gets stuck in busy
state and we continuously issue Update Transfer
commands.
Fixes: 8a1a9c9e45 ("usb: dwc3: gadget: start transfer on XFER_COMPLETE")
Signed-off-by: Felipe Balbi <balbi@ti.com>
In some SoCs, dwc3 is implemented as a USB2.0 only
core, meaning that it can't ever achieve SuperSpeed.
Currect driver always sets gadget.max_speed to
USB_SPEED_SUPER unconditionally. This can causes
issues to some Host stacks where the host will issue
a GetBOS() request and we will reply with a BOS
containing Superspeed Capability Descriptor.
At least Windows seems to be upset by this fact and
prints a warning that we should connect $this device
to another port.
[ balbi@ti.com : rewrote entire commit, including
source code comment to make a lot clearer what the
problem is ]
Cc: <stable@vger.kernel.org>
Signed-off-by: Ben McCauley <ben.mccauley@garmin.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
This reverts commit 8f2c9544ab.
As it breaks g_ether on my Baytrail FFRD8 device. Everything starts out
fine, but after a bit of data has been transferred it just stops
flowing.
Note that I do get a bunch of these "NOHZ: local_softirq_pending 08"
when booting the machine, but I'm not really sure if they're related
to this problem.
Cc: Felipe Balbi <balbi@ti.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: linux-usb@vger.kernel.org
Cc: stable@vger.kernel.org
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
This reverts commit 70f3a9caa1.
That commit was causing a lockdep splat with g_ether and that
was interfering with proper functionality.
Signed-off-by: Felipe Balbi <balbi@ti.com>
We *know* our threads executes with our IRQs
disabled. We really don't need to use the _irqsave()
variant of spin_lock().
Signed-off-by: Felipe Balbi <balbi@ti.com>
Instead of limiting __dwc3_gadget_kick_transfer() to
Xfer Complete, we can try to issue Update Transfer
command from Xfer In Progress too.
Signed-off-by: Felipe Balbi <balbi@ti.com>
If we get a Xfer Not Ready event with reason
"Transfer Active" it means endpoint is still
transferring data and we can use that to issue
update transfer for this particular endpoint
in case we have pending requests in our queue.
Signed-off-by: Felipe Balbi <balbi@ti.com>
if by the time we get to XFER_COMPLETE we have
pending requests to be processed, instead of waiting
for a following XFER_NOT_READY, let's start the request
right away and, maybe, save the time of a few NAKs
due to lack of started transfers.
Signed-off-by: Felipe Balbi <balbi@ti.com>
We shouldn't return -EBUSY, that's used only internally
when the core still has transfers in flight on a given
endpoint.
Also, combine the error reporting so that we don't have
to duplicate it.
Signed-off-by: Felipe Balbi <balbi@ti.com>
Instead of clearing DWC3_PENDING_REQUEST when
we start transfer, let's do it when the request
is actually queued, that way we know for sure
that we're clearing in the right time.
Signed-off-by: Felipe Balbi <balbi@ti.com>
In an attempt to make dwc3 slightly faster, let's
start usb_requests as soon as they come as that will
let us avoid a XFER_NOT_READY event and save a little
bit of time.
Signed-off-by: Felipe Balbi <balbi@ti.com>
by moving trace_dwc3_ep_queue() from dwc3_gadget_ep_queue()
to __dwc3_gadget_ep_queue() after usb_request is properly
initialized, makes for a better output always showing a
request with 0 actual and -115 (-EINPROGRESS) status.
Signed-off-by: Felipe Balbi <balbi@ti.com>
Using spin_lock() in hard irq handler is pointless
and causes a BUG() in RT (real-time) configuration
so get rid of it.
The reason it's pointless is because the driver is
basically accessing register which is, anyways,
atomic.
Signed-off-by: Roger Quadros <rogerq@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Convert endpoint configuration to new capabilities model.
Signed-off-by: Robert Baldyga <r.baldyga@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Add chained TRB support to ep0. Now TRB's can be chained just by
invoking _dwc3_ep0_start_trans_ with 'chain' parameter set to true.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
We have a "Enabling %s" trace when enabling an endpoint
but that message felt lonely without a matching
"Disabling %s". Add it.
Signed-off-by: Felipe Balbi <balbi@ti.com>
In case of non-Isochronous transfers, we don't
want to clear DWC3_EP_BUSY flag until XferComplete
event. That's because XferInProgress was only enabled
so we can recycle TRBs and usb_requests quicker, but
there are still other pending requests being transferred.
In order to make sure we don't allow for another StartTransfer
command while the HW is still processing other transfers,
we must keep DWC3_EP_BUSY flag set and this what this patch
does.
Fixes: f3af36511e (usb: dwc3: gadget: always enable IOC on
bulk/interrupt transfers)
Cc: <stable@vger.kernel.org> # v3.15+
Reported-by: sundeep subbaraya <sundeep.lkml@gmail.com>
Tested-by: sundeep subbaraya <sundeep.lkml@gmail.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
We need to return error to caller if command is not sent to
controller succesfully.
Signed-off-by: Subbaraya Sundeep Bhatta <sbhatta@xilinx.com>
Fixes: 72246da40f (usb: Introduce DesignWare USB3 DRD Driver)
Cc: <stable@vger.kernel.org>
Signed-off-by: Felipe Balbi <balbi@ti.com>
We need to return error to caller if command is not sent to
controller succesfully.
Signed-off-by: Subbaraya Sundeep Bhatta <sbhatta@xilinx.com>
Fixes: b09bb64239 (usb: dwc3: gadget: implement Global Command support)
Cc: <stable@vger.kernel.org> #v3.5+
Signed-off-by: Felipe Balbi <balbi@ti.com>
Now that we're using XFERINPROGRESS for all endpoint
types (except Control), we will *always* be completing
one TRB at a time, so it's safe to remove the loop
from dwc3_cleanup_done_reqs.
Signed-off-by: Felipe Balbi <balbi@ti.com>
Delete private selfpowered variable, and use common one.
Signed-off-by: Peter Chen <peter.chen@freescale.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
commit 8e74475b0e (usb: dwc3: gadget: use udc-core's
reset notifier) added support for the new UDC core's
reset notifier to dwc3 but while at it, it removed
a spin_lock() from dwc3_reset_gadget() which might
cause an unbalanced spin_unlock() further down the line
Fixes: 8e74475b0e (usb: dwc3: gadget: use udc-core's reset notifier)
Cc: <stable@vger.kernel.org> # v3.19
Signed-off-by: Felipe Balbi <balbi@ti.com>
if an unknown IRQ event is triggered, that means
the HW is really misbehaving. Instead of printing
a debug message, let's WARN() so users report
when that happens.
Signed-off-by: Felipe Balbi <balbi@ti.com>
DWC3 gadget sets up a pool of 32 TRBs for each EP during initialization. This
means, the max TRBs that can be submitted for an EP is fixed to 32. Since the
request queue for an EP is a linked list, any number of requests can be queued
to it by the gadget layer. However, the dwc3 driver must not submit TRBs more
than the pool it has created for. This limit wasn't respected when SG was used
resulting in submitting more than the max TRBs, eventually leading to
non-transfer of the TRBs submitted over the max limit.
Root cause:
When SG is used, there are two loops iterating to prepare TRBs:
- Outer loop over the request_list
- Inner loop over the SG list
The code was missing break to get out of the outer loop.
Fixes: eeb720fb21 (usb: dwc3: gadget: add support for SG lists)
Cc: <stable@vger.kernel.org> # v3.9+
Signed-off-by: Amit Virdi <amit.virdi@st.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
When scatter gather (SG) is used, multiple TRBs are prepared from one DWC3
request (dwc3_request). So while preparing TRBs, the 'last' flag should be set
only when it is the last TRB being prepared from the last dwc3_request entry.
The current implementation uses list_is_last to check if the dwc3_request is the
last entry from the request_list. However, list_is_last returns false for the
last entry too. This is because, while preparing the first TRB from a request,
the function dwc3_prepare_one_trb modifies the request's next and prev pointers
while moving the URB to req_queued. Hence, list_is_last always returns false no
matter what.
The correct way is not to access the modified pointers of dwc3_request but to
use list_empty macro instead.
Fixes: e5ba5ec833 (usb: dwc3: gadget: fix scatter gather implementation)
Signed-off-by: Amit Virdi <amit.virdi@st.com>
Cc: <stable@vger.kernel.org> # v3.9+
Signed-off-by: Felipe Balbi <balbi@ti.com>
dwc3_gadget_init_hw_endpoints calls dwc3_alloc_trb_pool only if epnum is not
equal to 0 or 1. Hence, rechecking it in the called function is redundant.
Signed-off-by: Amit Virdi <amit.virdi@st.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Replace usb_gadget_driver's disconnect with udc-core's reset notifier at
bus reset handler.
Signed-off-by: Felipe Balbi <balbi@ti.com>
Signed-off-by: Peter Chen <peter.chen@freescale.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
HIRD threshold should be configurable by different platforms.
From DesignWare databook:
When HIRD_Threshold[4] is set to 1b1 and HIRD value is greater than or
equal to the value in HIRD_Threshold[3:0], dwc3 asserts output signals
utmi_l1_suspend_n to put PHY into Deep Low-Power mode in L1.
When HIRD_Threshold[4] is set to 1b0 or the HIRD value is less than
HIRD_Threshold[3:0], dwc3 asserts output signals utmi_sleep_n on L1.
Signed-off-by: Huang Rui <ray.huang@amd.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
When parameter DWC_USB3_LPM_ERRATA_ENABLE is enabled in Andvanced
Configuration of coreConsultant, it supports of xHCI BESL Errata Dated
10/19/2011 is enabled in host mode. In device mode it adds the capability
to send NYET response threshold based on the BESL value received in the LPM
token, and the threhold is configurable for each soc platform.
This patch adds an entry that soc platform is able to define the lpm
capacity with their own device tree or bus glue layer.
[ balbi@ti.com : added devicetree documentation, spelled threshold
completely, made sure threshold is only applied to
proper core revisions. ]
Signed-off-by: Huang Rui <ray.huang@amd.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
now that no UDC driver relies on the extra
'driver' argument to ->udc_stop(), we can
safely remove it.
This commit is based on previous work by
Robert Baldyga <r.baldyga@samsung.com> which
can be found at [1]; however that patch turned
out to have a high probability of regressing
many UDC drivers because of a blind search & replace
s/driver/$udc->driver/ which caused the 'driver'
argument to stop_activity() to be a valid non-NULL
pointer when it should be NULL, thus causing UDCs
to mistakenly call gadget driver's ->disconnect()
callback.
[1] http://markmail.org/message/x5zneg4xea4zntab
Acked-by: Peter Chen <peter.chen@freescale.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Some gadget/function drivers might want to do
improper request recycling by allocating a single
request from one particular endpoint and queueing
it to another completely unrelated endpoint.
One such case was found with f_loopback.c.
To prevent such cases from happening again, let's
WARN() so we get a loud enough failure and persuade
users to report errors.
Signed-off-by: Felipe Balbi <balbi@ti.com>
whenever we get a Disconnect Interrupt, we should
make sure to update out udc state to NOT_ATTACHED,
otherwise sysfs will show wrong values.
Signed-off-by: Felipe Balbi <balbi@ti.com>
Using ->prepare()/->complete() to mask/unmask
IRQs is wrong at least for dwc3. We need to
make sure that by the end of ->resume(), IRQs
are working and ready to fire because a child
device may need working IRQs for its own ->resume()
method.
Signed-off-by: Felipe Balbi <balbi@ti.com>
On ISOC endpoints the last trb_pool entry used as a
LINK TRB is not getting zeroed out correctly due to
memset being called incorrectly and in the wrong place.
If pool allocated from DMA was not zero-initialized
to begin with this will result in the size and ctrl
values being random garbage. Call memset correctly after
assignment of the trb_link pointer.
Fixes: f6bafc6a1c ("usb: dwc3: convert TRBs into bitshifts")
Cc: <stable@vger.kernel.org> # v3.4+
Signed-off-by: Jack Pham <jackp@codeaurora.org>
Signed-off-by: Felipe Balbi <balbi@ti.com>
According to our Gadget Framework API documentation,
->set_halt() *must* return -EAGAIN if we have pending
transfers (on either direction) or FIFO isn't empty (on
TX endpoints).
Fix this bug so that the mass storage gadget can be used
without stall=0 parameter.
This patch should be backported to all kernels since v3.2.
Cc: <stable@vger.kernel.org> # v3.2+
Suggested-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Instead of releasing the lock and calling locked
versions of our set_halt() methods, let's hold
the lock all the way through and call unlocked
versions of those functions.
Signed-off-by: Felipe Balbi <balbi@ti.com>
__dwc3_gadget_ep_set_halt() is the function which
handles the actual halt feature. In order to cope
with some extra cleanup comming as a follow-up patch
let's move the isochronous endpoint check there too.
Signed-off-by: Felipe Balbi <balbi@ti.com>
Use the recently introduced usb_gadget_giveback_request() in favor of
direct invocation of the completion routine.
All places in drivers/usb/ matching "[-.]complete(" were replaced with a
call to usb_gadget_giveback_request(). This was compile-tested with all
ARM drivers enabled and runtime-tested for musb.
Signed-off-by: Michal Sojka <sojka@merica.cz>
Acked-by: Felipe Balbi <balbi@ti.com>
Tested-by: Felipe Balbi <balbi@ti.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
When we're debugging hard-to-reproduce and time-sensitive
use cases, printk() poses too much overhead. That's when
the kernel's tracing infrastructure comes into play.
This patch implements a few initial tracepoints for the
dwc3 driver. More traces can be added as necessary in order
to ease the task of debugging dwc3.
Reviewed-by: Paul Zimmerman <paulz@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Those functions are only using within debugging
messages, grouping them into debug.h makes sense.
While at that, also add missing multiple inclusion
guard.
Signed-off-by: Felipe Balbi <balbi@ti.com>
After commit 2ec2a8be (usb: dwc3: gadget:
always enable IOC on bulk/interrupt transfers)
we created a situation where it was possible to
hang a bulk/interrupt endpoint if we had more
than one pending request in our queue and they
were both started with a single Start Transfer
command.
The problems triggers because we had not enabled
Transfer In Progress event for those endpoints
and we were not able to process early giveback
of requests completed without LST bit set.
Fix the problem by finally enabling Xfer In Progress
event for all endpoint types, except control.
Fixes: 2ec2a8be (usb: dwc3: gadget: always
enable IOC on bulk/interrupt transfers)
Cc: <stable@vger.kernel.org> # v3.14+
Reported-by: Pratyush Anand <pratyush.anand@st.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
dep->endpoint.desc is checked at the beginning of
dwc3_gadget_ep_queue(), but after that it may be set to NULL
by another thread and then accessed again in dwc3_gadget_ep_queue().
This will lead to kernel oops.
Expand spinlock protection area to aviod race condition.
Signed-off-by: Zhuang Jin Can <jin.can.zhuang@intel.com>
Signed-off-by: Jiebing Li <jiebing.li@intel.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>