This patch introduces a configuration option USBMSC_WRMULTIPLE,
which is used to store multiple blocks into a larger chunk that
then gets written via the mmcsd_writemultiple() (in case mmcsd
is used).
The bottleneck with the current implementation is the poor
performance due to short block writes. USBMSC_DRVR_WRITE()
always writes only one sector (with eMMC that's usually 512 bytes).
eMMC devices usually erase much larger regions with near constant
time (see Jedec JESD84-B51, Extended CSD register byte [225],
SUPER_PAGE_SIZE): 'This register defines one or multiple of
programmable boundary unit that is programmed at the same time.'
If USBMSC_WRMULTIPLE is defined, then USBMSC_NWRREQS is used to
allocate the write buffer size. We don't want this to be the
default behavior yet as this may reveal unseen bugs in usb drivers
due to the faster overall performance.
Sample configurations with measured performance:
- Without USBMSC_WRMULTIPLE: 470 Kb/s
- With USBMSC_WRMULTIPLE, CONFIG_USBMSC_NWRREQS=4: 1.1 Mb/s
(dd with bs=2k)
- With USBMSC_WRMULTIPLE, CONFIG_USBMSC_NWRREQS=16: 5.2 Mb/s
(dd with bs=8k)
No doubt, this feature alone may make the mass storage work 10
times faster than before with eMMC cards.
Signed-off-by: Eero Nurkkala <eero.nurkkala@offcode.fi>
iSerialNumber field in the device descriptor can be used to determining the
board when multiple boards connected to the same host. So add feature to change
serial string by board unique ID dynamically.
To use this feature, user must be implement the board_usbdev_serialstr() logic.
refs #13909
The new configuration CONFIG_USBMSC_NOT_STALL_BULKEP avoids to go into
stall state when :
- Receiving SCSI_CMD_INQUIRY with flags or pagecode != 0
- Receiving SCSI_CMD_MODESENSE6 and return the result data shorter than
the requested data size.
Instead of stall, it just ignores the error condition.
Originally the usb driver goes into the stall under the conditions
mentioned above to inform to the USB host that the requested SCSI feature
is not supported, or the result data is shorter than the requested data
size.
But, at this moment, RP2040 USB device driver cannot handle entering and
leaving stall state of the bulk endpoints well. Once stalls, the host -
device communication stops and cannot be resumed.
I have investigated to solve the issue and found that the existing
RP2040 USB device driver implementation, TinyUSB
(https://github.com/hathach/tinyusb) mass-storage class driver doesn't
enter the stall state like the treatment of this patch.
So, I introduce this new configuration as the RP2040 workaround.
In the future, when the RP2040 USB device driver is fixed and can handle
the bulk endpoint stall correctly, this patch should be reverted.
Resolution of Issue 619 will require multiple steps, this part of the first step in that resolution: Every call to nxsem_wait_uninterruptible() must handle the return value from nxsem_wait_uninterruptible properly. This commit is only for rwbuffer.c and those files under drivers/serial, drivers/timers, and drivers/usbdev.
This commit completes that step for all of the files under drivers/. Still remaining: All of the files under arch/.
Author: Alan Carvalho de Assis <acassis@gmail.com>
Run nxstyle on .c and .h files and fix it
Author: Alin Jerpelea <alin.jerpelea@sony.com>
drivers: usbdev: minor fix
drivers: usbdev: usbmsc full speed not available
Change transfer size to be based on maxpacket size.
drivers: usbdev: Fix string ID calculation
For *_STRBASE defines, it already unnecessary because composite device setup
has been changed, it would be calculated by *_composite.c in board sources.
drivers: usbdev: Fix invalid/unsupported command processing
Mass Storage Class shall stall when invalid or unsupported commands
has been recieved.
drivers: usbdev: Remove unnecessary reset logic
drivers: usbdev: Flags comparison fix
drivers: usbdev: Descriptor type mismatch fix when dual speed is enabled
* Simplify EINTR/ECANCEL error handling
1. Add semaphore uninterruptible wait function
2 .Replace semaphore wait loop with a single uninterruptible wait
3. Replace all sem_xxx to nxsem_xxx
* Unify the void cast usage
1. Remove void cast for function because many place ignore the returned value witout cast
2. Replace void cast for variable with UNUSED macro
This commit backs out most of commit b4747286b1. That change was added because sem_wait() would sometimes cause cancellation points inappropriated. But with these recent changes, nxsem_wait() is used instead and it is not a cancellation point.
In the OS, all calls to sem_wait() changed to nxsem_wait(). nxsem_wait() does not return errors via errno so each place where nxsem_wait() is now called must not examine the errno variable.
In all OS functions (not libraries), change sem_wait() to nxsem_wait(). This will prevent the OS from creating bogus cancellation points and from modifying the per-task errno variable.
sched/semaphore: Add the function nxsem_wait(). This is a new internal OS interface. It is functionally equivalent to sem_wait() except that (1) it is not a cancellation point, and (2) it does not set the per-thread errno value on return.
sched/semaphore: Add nxsem_post() which is identical to sem_post() except that it never modifies the errno variable. Changed all references to sem_post in the OS to nxsem_post().
sched/semaphore: Add nxsem_destroy() which is identical to sem_destroy() except that it never modifies the errno variable. Changed all references to sem_destroy() in the OS to nxsem_destroy().
libc/semaphore and sched/semaphore: Add nxsem_getprotocol() and nxsem_setprotocola which are identical to sem_getprotocol() and set_setprotocol() except that they never modifies the errno variable. Changed all references to sem_setprotocol in the OS to nxsem_setprotocol(). sem_getprotocol() was not used in the OS
The scsi thread was waiting for the wrong condition.
However, this was masked by the fact that the code creating the scsi thread
was also holding usbmsc_scsi_lock(priv) while initializing data, hence this
lock synchronized the scsi thread start with init completion.