usbmsc: Add USBMSC_NOT_STALL_BULKEP for RP2040 workaround
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.
This commit is contained in:
parent
e00546335d
commit
8d722709cd
@ -852,6 +852,14 @@ config USBMSC_SCSI_STACKSIZE
|
||||
Stack size used with the SCSI kernel thread. The default value
|
||||
is not tuned.
|
||||
|
||||
config USBMSC_NOT_STALL_BULKEP
|
||||
bool "Not stall USBMSC bulk endpoints for workaround"
|
||||
default n
|
||||
---help---
|
||||
Not stall USBMSC bulk endpoints in some conditions.
|
||||
Because RP2040 usbdev driver cannot handle stalling/resuming bulk
|
||||
endpoints well, this workaround is required.
|
||||
|
||||
endif
|
||||
|
||||
menuconfig RNDIS
|
||||
|
@ -663,12 +663,14 @@ static inline int usbmsc_cmdinquiry(FAR struct usbmsc_dev_s *priv,
|
||||
response->qualtype = SCSIRESP_INQUIRYPQ_NOTCAPABLE |
|
||||
SCSIRESP_INQUIRYPD_UNKNOWN;
|
||||
}
|
||||
#ifndef CONFIG_USBMSC_NOT_STALL_BULKEP
|
||||
else if ((inquiry->flags != 0) || (inquiry->pagecode != 0))
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_INQUIRYFLAGS), 0);
|
||||
priv->lun->sd = SCSI_KCQIR_INVALIDFIELDINCBA;
|
||||
ret = -EINVAL;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
memset(response, 0, SCSIRESP_INQUIRY_SIZEOF);
|
||||
@ -822,7 +824,9 @@ static int inline usbmsc_cmdmodesense6(FAR struct usbmsc_dev_s *priv,
|
||||
(FAR struct scsicmd_modesense6_s *)priv->cdb;
|
||||
FAR struct scsiresp_modeparameterhdr6_s *mph =
|
||||
(FAR struct scsiresp_modeparameterhdr6_s *)buf;
|
||||
#ifndef CONFIG_USBMSC_NOT_STALL_BULKEP
|
||||
int mdlen;
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
priv->u.alloclen = modesense->alloclen;
|
||||
@ -830,6 +834,11 @@ static int inline usbmsc_cmdmodesense6(FAR struct usbmsc_dev_s *priv,
|
||||
USBMSC_FLAGS_DIRDEVICE2HOST);
|
||||
if (ret == OK)
|
||||
{
|
||||
#ifdef CONFIG_USBMSC_NOT_STALL_BULKEP
|
||||
priv->residue = priv->cbwlen = priv->nreqbytes =
|
||||
SCSIRESP_MODEPARAMETERHDR6_SIZEOF;
|
||||
#endif
|
||||
|
||||
if ((modesense->flags & ~SCSICMD_MODESENSE6_DBD) != 0 ||
|
||||
modesense->subpgcode != 0)
|
||||
{
|
||||
@ -851,6 +860,7 @@ static int inline usbmsc_cmdmodesense6(FAR struct usbmsc_dev_s *priv,
|
||||
(priv->lun->readonly ? SCSIRESP_MODEPARMHDR_DAPARM_WP : 0x00);
|
||||
mph->bdlen = 0; /* Block descriptor length */
|
||||
|
||||
#ifndef CONFIG_USBMSC_NOT_STALL_BULKEP
|
||||
/* There are no block descriptors, only the following mode page: */
|
||||
|
||||
ret = usbmsc_modepage(priv,
|
||||
@ -867,6 +877,7 @@ static int inline usbmsc_cmdmodesense6(FAR struct usbmsc_dev_s *priv,
|
||||
priv->nreqbytes =
|
||||
mdlen + SCSIRESP_MODEPARAMETERHDR6_SIZEOF;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -2584,6 +2595,7 @@ static int usbmsc_cmdfinishstate(FAR struct usbmsc_dev_s *priv)
|
||||
|
||||
if (priv->residue > 0)
|
||||
{
|
||||
#ifndef CONFIG_USBMSC_NOT_STALL_BULKEP
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDFINISHRESIDUE),
|
||||
(uint16_t)priv->residue);
|
||||
|
||||
@ -2601,6 +2613,9 @@ static int usbmsc_cmdfinishstate(FAR struct usbmsc_dev_s *priv)
|
||||
nxsig_usleep (100000);
|
||||
#else
|
||||
EP_STALL(priv->epbulkin);
|
||||
#endif
|
||||
#else
|
||||
priv->residue = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user