usb: ci_udc: add some error-checking to handle_setup()

Enhance handle_setup() to detect whether the list of active requests is
empty. If it is, and handle_setup() needs a usb_request object to reply,
STALL the endpoint instead. For more details, see the comment this patch
adds.

FIXME:

Before "usb: ci_udc: allow multiple buffer allocs per ep", the ep0 req
was statically allocated, and the code simply referenced that. There was
no concept of having to pull the req out of the queue, since it could be
found elsewhere. That said, handle_ep_complete did (IIRC) always re-queue
the transaction.

Instead of this change, we should special-case ep0 to pre-allocate the
req, and access it directly. Then, we can fix the later commit "usb:
ci_udc: complete ep0 direction handling" NOT to re-queue the req after
the Status Phase is complete. This should also solve DFU getting req
complete callbacks for the 0-length status transfers, and incrementing
the sequence number, and bitching about the sequence number being
invalid.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
usb: ci_udc: use a single descriptor for ep0

ci_udc currently points ep->desc at separate descriptors for IN and OUT.
These descriptors only differ in the ep address IN/OUT field. Modify the
code to use a single descriptor, and change that descriptor's ep address
to indicate IN/OUT as required. This removes some data duplication.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
usb: ci_udc: complete ep0 direction handling

handle_setup() currently assumes that the response to a Setup transaction
will be an OUT transaction, and any subsequent packet (if any) will be an
IN transaction.

This appears to be valid in many cases; both USB enumeration and Mass
Storage work OK with this restriction.

However, DFU uses ep0 to transfer data in either direction. This renders
the assumption invalid; when sending data from device to host, the Data
Phase is an IN transaction, and the Status Phase is an OUT transaction.

Enhance handle_setup() to deduce the correct direction for the USB
transactions based on Setup transaction data.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
dfu: fix some issues with reads/uploads

FIXME: This breaks filesystem DFU, since I've only implemented the
changes for raw device DFU.

DFU read support appears to rely upon dfu->read_medium() updating the
passed-by-reference len parameter to indicate the remaining size
available for reading.

dfu_read_medium_mmc() never does this, and the implementation of
dfu_read_medium_nand() will only work if called just once; it hard-codes
the value to the total size of the NAND device irrespective of read
offset.

I believe that overloading dfu->read_medium() is confusing. As such,
this patch introduces a new function dfu->get_medium_size() which can
be used to explicitly find out the medium size, and nothing else.
dfu_read() is modified to use this function to set the initial value for
dfu->r_left, rather than attempting to use the side-effects of
dfu->read_medium() for this purpose.

Due to this change, dfu_read() must initially set dfu->b_left to 0, since
no data has been read.

dfu_read_buffer_fill() must also be modified not to adjust dfu->r_left
when simply copying data from dfu->i_buf_start to the upload request
buffer. r_left represents the amount of data left to be read from HW.
That value is not affected by the memcpy(), but only by calls to
dfu->read_medium().

After this change, I can read from either a 4MB or 1.5MB chunk of a 4MB
eMMC boot partion with CONFIG_SYS_DFU_DATA_BUF_SIZE==1MB. Without this
change, attempting to do that would result in DFU read returning no data
at all due to r_left never being set.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
ARM: tegra: enable USB device mode and UMS on some boards

For each of Jetson TK1, Venice2, and Beaver:

- Enable the first USB controller in DT, and describe its configuration.

- Enable USB device/gadge support. This allows the user to type e.g.
  "ums 0 mmc 0" at the command-line to cause U-Boot to act a USB device
  implementing the USB Mass Storage protocol, and expose MMC device 0
  that way.

This allows a host PC to mount the Tegra device's MMC, partition it, and
install a filesystem on it.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
v2: Add missing tegra-common-ums.h

Note: This depends on a bunch of changes to the Tegra EHCI driver and
U-Boot UMS (USB Mass Storage) code, which are likely to be taken through
the USB maintainer tree. We should hold off until those commits show up
in the main U-Boot repo before applying this patch.

FIXME: I need to allocat a valid CONFIG_G_DNL_PRODUCT_NUM.
HACK: ARM: tegra: enable DFU too

FIXME: This should likely be in a separate tegra-common-dfu.h.

Signed-off-by: Stephen Warren <swarren@nvidia.com>