DM USB: xHCI: workaround for USB SSD which supports UAS protocol

The USB mediator doesn't support USB Attached SCSI (UAS) protocol
due to no proper implementation for USB Stream. This patch will
use USB Bulk transfer to workaround until formal implentation for
UAS is ready.

Tracked-On: #3486
Signed-off-by: Xiaoguang Wu <xiaoguang.wu@intel.com>
Acked-by: Yu Wang <yu1.wang@intel.com>
This commit is contained in:
Xiaoguang Wu 2019-07-17 11:30:32 +08:00 committed by ACRN System Integration
parent 0e2cfd2dee
commit 55a5876eba

View File

@ -902,6 +902,36 @@ done:
return xfer->status;
}
static void
clear_uas_desc(struct usb_dev *udev, uint8_t *data, uint32_t len)
{
struct usb_devpath *path;
int32_t i;
/* only process configuration descriptor */
if (len < 2 || data[1] != 0x2)
return;
i = 0;
path = &udev->info.path;
while (i < len) {
/* When UAS protocol is found in interface descriptor, set it
* to invalid value.
*
* According to USB3 spec 9.6.5, Standard Interface Descriptor,
* data[i+0] => bLength
* data[i+1] => bDescriptorType
* data[i+7] => bInterfaceProtocol
*/
if (data[i] == 9 && data[i+1] == 0x4 && data[i+7] == 0x62) {
UPRINTF(LFTL, "%d-%s: clear uas protocol\r\n",
path->bus, usb_dev_path(path));
data[i+7] = 0;
}
i = i + data[i];
}
}
int
usb_dev_request(void *pdata, struct usb_data_xfer *xfer)
{
@ -914,6 +944,7 @@ usb_dev_request(void *pdata, struct usb_data_xfer *xfer)
struct usb_data_xfer_block *blk;
uint8_t *data;
int rc;
bool need_chk_uas = false;
udev = pdata;
xfer->status = USB_ERR_NORMAL_COMPLETION;
@ -960,6 +991,10 @@ usb_dev_request(void *pdata, struct usb_data_xfer *xfer)
UPRINTF(LDBG, "UR_SET_INTERFACE\n");
usb_dev_set_if(udev, index, value, xfer);
goto out;
case UREQ(UR_GET_DESCRIPTOR, UT_READ):
if (value == 0x0200)
need_chk_uas = true;
break;
case UREQ(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
if (value) {
/* according to usb spec (ch9), this is impossible */
@ -985,6 +1020,13 @@ usb_dev_request(void *pdata, struct usb_data_xfer *xfer)
rc = libusb_control_transfer(udev->handle, request_type, request,
value, index, data, len, 300);
/* TODO: Currently, the USB Attached SCSI (UAS) protocol is not
* supported and the following code is used as a workaround now.
* UAS will be implemented in future.
*/
if (need_chk_uas)
clear_uas_desc(udev, data, rc);
if (rc >= 0 && blk) {
blk->blen = len - rc;
blk->bdone += rc;