This refactor results in a cleaner state machine code and promotes
consistency, readability, and maintanability of this driver.
This refactor state machine was well tested and it is currently running in
production code and devices.
Signed-off-by: Felipe F. Tonello <eu@felipetonello.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
512 is the value used by wMaxPacketSize, as specified by the USB Spec. This
makes sure this driver uses, by default, the most optimal value for IN and OUT
endpoint requests.
Signed-off-by: Felipe F. Tonello <eu@felipetonello.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
The new version of alloc_ep_req() already aligns the buffer size to
wMaxPacketSize on OUT endpoints.
Signed-off-by: Felipe F. Tonello <eu@felipetonello.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
We added some new locking here, but missed an error path where we need
to unlock.
Fixes: 9acdf4df2f ('usb: gadget: f_midi: added spinlock on transmit function')
Acked-by: Michal Nazarewicz <mina86@mina86.com>
Acked-by: Felipe F. Tonello <eu@felipetonello.com>
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
buflen by default (256) is smaller than wMaxPacketSize (512) in high-speed
devices.
That caused the OUT endpoint to freeze if the host send any data packet of
length greater than 256 bytes.
This is an example dump of what happended on that enpoint:
HOST: [DATA][Length=260][...]
DEVICE: [NAK]
HOST: [PING]
DEVICE: [NAK]
HOST: [PING]
DEVICE: [NAK]
...
HOST: [PING]
DEVICE: [NAK]
This patch fixes this problem by setting the minimum usb_request's buffer size
for the OUT endpoint as its wMaxPacketSize.
Acked-by: Michal Nazarewicz <mina86@mina86.com>
Signed-off-by: Felipe F. Tonello <eu@felipetonello.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Since f_midi_transmit is called by both ALSA and USB sub-systems, it can
potentially cause a race condition between both calls because f_midi_transmit
is not reentrant nor thread-safe. This is due to an implementation detail that
the transmit function looks for the next available usb request from the fifo
and only enqueues it if there is data to send, otherwise just re-uses it. So,
if both ALSA and USB frameworks calls this function at the same time,
kfifo_seek() will return the same usb_request, which will cause a race
condition.
To solve this problem a syncronization mechanism is necessary. In this case it
is used a spinlock since f_midi_transmit is also called by usb_request->complete
callback in interrupt context.
Cc: <stable@vger.kernel.org> # v4.5+
Fixes: e1e3d7ec5d ("usb: gadget: f_midi: pre-allocate IN requests")
Signed-off-by: Felipe F. Tonello <eu@felipetonello.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
For every in_substream, there must be a corresponding gmidi_in_port
structure so it is perfectly viable and some might argue sensible to
stash pointer to the input substream in the gmidi_in_port structure.
This has an added benefit that if in_ports < MAX_PORTS, the whole
f_midi structure takes up less space because only in_ports number of
pointers for in_substream are allocated instead of MAX_PORTS lots of
them.
Signed-off-by: Michal Nazarewicz <mina86@mina86.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
We added a new error path to this function and we forgot to drop the
lock.
Fixes: e1e3d7ec5d ('usb: gadget: f_midi: pre-allocate IN requests')
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
[mina86@mina86.com: rebased on top of refactoring commit]
Signed-off-by: Michal Nazarewicz <mina86@mina86.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Reduce number of allocations, simplify memory management and reduce
memory usage by stacking the gmidi_in_port elements at the end of the
f_midi structure using a flexible array.
Signed-off-by: Michal Nazarewicz <mina86@mina86.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
In general case, all of midi->in_port pointers may be non-NULL which
implies that the ‘if (\!port)’ condition will never execute thus never
zeroing midi->in_last_port. Fix by rewriting the loop such that the
field is set to zero if \!port or end of loop has been reached.
Signed-off-by: Michal Nazarewicz <mina86@mina86.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Move some of the f_midi_transmit to a separate f_midi_do_transmit
function so the massive indention levels are not so jarring. This
introduces no changes in behaviour.
Signed-off-by: Michal Nazarewicz <mina86@mina86.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
remove a field which is unnecessary. No functional changes.
Signed-off-by: Felipe F. Tonello <eu@felipetonello.com>
Signed-off-by: Michal Nazarewicz <mina86@mina86.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
This patch introduces pre-allocation of IN endpoint USB requests. This
improves on latency (requires no usb request allocation on transmit) and avoid
several potential probles on allocating too many usb requests (which involves
DMA pool allocation problems).
This implementation also handles better multiple MIDI Gadget ports, always
processing the last processed MIDI substream if the last USB request wasn't
enought to handle the whole stream.
Signed-off-by: Felipe F. Tonello <eu@felipetonello.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
This ensures that the midi function will only work if the proper number of
IN and OUT requrests are allocated. Otherwise the function will work with less
requests then what the user wants.
Signed-off-by: Felipe F. Tonello <eu@felipetonello.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
This avoids duplication of USB requests for OUT endpoint and
re-enabling endpoints.
Signed-off-by: Felipe F. Tonello <eu@felipetonello.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
This function is shared between gadget functions, so this avoid unnecessary
duplicated code and potentially avoid memory leaks.
Reviewed-by: Robert Baldyga <r.baldyga@samsung.com>
Signed-off-by: Felipe F. Tonello <eu@felipetonello.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
This code is duplicated from f_midi_start_ep(midi, f, midi->out_ep).
Reviewed-by: Robert Baldyga <r.baldyga@samsung.com>
Signed-off-by: Felipe F. Tonello <eu@felipetonello.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
This patch fixes a memory leak that occurs when an endpoint fails to enqueue
the request. If that happens the complete function will never be called, thus
never freeing the request.
Signed-off-by: Felipe F. Tonello <eu@felipetonello.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
This makes sure f_midi doesn't try to enqueue data when the IN endpoint is
disabled, ie, USB cable is disconnected.
Reviewed-by: Robert Baldyga <r.baldyga@samsung.com>
Signed-off-by: Felipe F. Tonello <eu@felipetonello.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Pull SCSI target updates from Nicholas Bellinger:
"This series contains HCH's changes to absorb configfs attribute
->show() + ->store() function pointer usage from it's original
tree-wide consumers, into common configfs code.
It includes usb-gadget, target w/ drivers, netconsole and ocfs2
changes to realize the improved simplicity, that now renders the
original include/target/configfs_macros.h CPP magic for fabric drivers
and others, unnecessary and obsolete.
And with common code in place, new configfs attributes can be added
easier than ever before.
Note, there are further improvements in-flight from other folks for
v4.5 code in configfs land, plus number of target fixes for post -rc1
code"
In the meantime, a new user of the now-removed old configfs API came in
through the char/misc tree in commit 7bd1d4093c ("stm class: Introduce
an abstraction for System Trace Module devices").
This merge resolution comes from Alexander Shishkin, who updated his stm
class tracing abstraction to account for the removal of the old
show_attribute and store_attribute methods in commit 517982229f
("configfs: remove old API") from this pull. As Alexander says about
that patch:
"There's no need to keep an extra wrapper structure per item and the
awkward show_attribute/store_attribute item ops are no longer needed.
This patch converts policy code to the new api, all the while making
the code quite a bit smaller and easier on the eyes.
Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>"
That patch was folded into the merge so that the tree should be fully
bisectable.
* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (23 commits)
configfs: remove old API
ocfs2/cluster: use per-attribute show and store methods
ocfs2/cluster: move locking into attribute store methods
netconsole: use per-attribute show and store methods
target: use per-attribute show and store methods
spear13xx_pcie_gadget: use per-attribute show and store methods
dlm: use per-attribute show and store methods
usb-gadget/f_serial: use per-attribute show and store methods
usb-gadget/f_phonet: use per-attribute show and store methods
usb-gadget/f_obex: use per-attribute show and store methods
usb-gadget/f_uac2: use per-attribute show and store methods
usb-gadget/f_uac1: use per-attribute show and store methods
usb-gadget/f_mass_storage: use per-attribute show and store methods
usb-gadget/f_sourcesink: use per-attribute show and store methods
usb-gadget/f_printer: use per-attribute show and store methods
usb-gadget/f_midi: use per-attribute show and store methods
usb-gadget/f_loopback: use per-attribute show and store methods
usb-gadget/ether: use per-attribute show and store methods
usb-gadget/f_acm: use per-attribute show and store methods
usb-gadget/f_hid: use per-attribute show and store methods
...
To simplify the configfs interface and remove boilerplate code that also
causes binary bloat.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Acked-by: Felipe Balbi <balbi@ti.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Since ep->driver_data is not used for endpoint claiming, neither for
enabled/disabled state storing, we can reduce number of places where
we read or modify it's value, as now it has no particular meaning for
function or framework logic.
In case of f_midi we only need to store in ep->driver_data pointer to
struct f_midi, as it's used in f_midi_complete() callback and related
functions. All other uses of ep->driver_data are now meaningless and
can be safely removed.
Signed-off-by: Robert Baldyga <r.baldyga@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
f_midi is not checking whether there is an error on usb_ep_queue
request, ignoring potential problems, such as memory leaks.
Signed-off-by: Felipe F. Tonello <eu@felipetonello.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Function midi registers two interfaces with single set_alt() function
which means that f_midi_set_alt() is called twice when configuration
is set. That means that endpoint initialization and ep request allocation
is done two times. To avoid this problem we do such things only once,
for interface number 1 (MIDI Streaming interface).
Signed-off-by: Robert Baldyga <r.baldyga@samsung.com>
Acked-by: Michal Nazarewicz <mina86@mina86.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
In case kstrdup() fails the resources to release are
midi->in_port[] and midi. No cards have been registered,
so no need to unregister any.
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Replace a misspelled function name by %s and then __func__.
This was done using Coccinelle, including the use of Levenshtein distance,
as proposed by Rasmus Villemoes.
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: Felipe Balbi <balbi@ti.com>
drivers/usb/gadget/function/f_midi.c:1072:21: sparse: symbol 'f_midi_alloc' was not declared. Should it be static?
drivers/usb/gadget/legacy/gmidi.c:118:30: sparse: symbol 'fi_midi' was not declared. Should it be static?
drivers/usb/gadget/legacy/gmidi.c:119:21: sparse: symbol 'f_midi' was not declared. Should it be static?
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Make the midi function available for gadgets composed with configfs.
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
In order to add configfs support the usb_gstrings_attach must be used.
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
There are no old f_midi interface users left, so remove it.
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Converting midi to the new function interface requires converting
the USB midi's function code and its users.
This patch converts the f_midi.c to the new function interface.
The file can now be compiled into a separate usb_f_midi.ko module.
The old function interface is provided by means of a preprocessor
conditional directives. After all users are converted, the old interface
can be removed.
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
kstrdup() might fail, so check its return value and react appropriately.
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
The soundcard index to use for the ALSA device creation is passed as a
parameter to f_midi_bind_config(), but is assigned to midi->index only
after the call to f_midi_register_card(midi). So no matter what is passed
to f_midi_bind_config(), the actual index for snd_card_new() is always 0.
This probably works ok if at the moment of f_midi's bind there are no
other snd_cards, but if there are, it is not possible to bind f_midi.
This patch moves the assignment to a place before the call to
f_midi_register_card(midi).
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
The drivers/usb/gadget directory contains many files.
Files which are related can be distributed into separate directories.
This patch moves the USB functions implementations into a separate directory.
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>