mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-21 13:08:42 +00:00
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:
parent
0e2cfd2dee
commit
55a5876eba
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user