Index: sys/dev/usb/usb_device.c =================================================================== --- sys/dev/usb/usb_device.c +++ sys/dev/usb/usb_device.c @@ -2053,7 +2053,7 @@ * Try to figure out if there are any MSC quirks we * should apply automatically: */ - err = usb_msc_auto_quirk(udev, 0); + err = usb_msc_auto_quirk(udev, 0, &uaa); if (err != 0) { set_config_failed = 1; Index: sys/dev/usb/usb_msctest.h =================================================================== --- sys/dev/usb/usb_msctest.h +++ sys/dev/usb/usb_msctest.h @@ -3,6 +3,7 @@ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. + * Copyright (c) 2021-2022 Idwer Vollering. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -44,7 +45,7 @@ usb_error_t usb_msc_eject(struct usb_device *udev, uint8_t iface_index, int method); usb_error_t usb_msc_auto_quirk(struct usb_device *udev, - uint8_t iface_index); + uint8_t iface_index, struct usb_attach_arg *uaa); usb_error_t usb_msc_read_10(struct usb_device *udev, uint8_t iface_index, uint32_t lba, uint32_t blocks, void *buffer); Index: sys/dev/usb/usb_msctest.c =================================================================== --- sys/dev/usb/usb_msctest.c +++ sys/dev/usb/usb_msctest.c @@ -3,6 +3,7 @@ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2008,2011 Hans Petter Selasky. All rights reserved. + * Copyright (c) 2021-2022 Idwer Vollering. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,9 +30,6 @@ /* * The following file contains code that will detect USB autoinstall * disks. - * - * TODO: Potentially we could add code to automatically detect USB - * mass storage quirks for not supported SCSI commands! */ #ifdef USB_GLOBAL_INCLUDE_FILE @@ -760,7 +758,8 @@ } usb_error_t -usb_msc_auto_quirk(struct usb_device *udev, uint8_t iface_index) +usb_msc_auto_quirk(struct usb_device *udev, uint8_t iface_index, + struct usb_attach_arg *uaa) { struct bbb_transfer *sc; uint8_t timeout; @@ -836,6 +835,42 @@ timeout = 1; + if (usb_test_quirk(uaa, UQ_MSC_NO_TEST_UNIT_READY) == 0) { + err = bbb_command_start(sc, DIR_NONE, 0, NULL, 0, + &scsi_test_unit_ready, sizeof(scsi_test_unit_ready), + USB_MS_HZ); + if (err == ERR_CSW_FAILED) { + if (usb_get_manufacturer(udev) != NULL && usb_get_product(udev) != NULL) { + DPRINTFN(0, "Applying dynamic quirk UQ_MSC_NO_TEST_UNIT_READY for USB mass storage device %s %s (VID/DID 0x%x:0x%x)\n", + usb_get_manufacturer(udev), + usb_get_product(udev), + UGETW(udev->ddesc.idVendor), + UGETW(udev->ddesc.idProduct) + ); + } + usbd_add_dynamic_quirk(udev, UQ_MSC_NO_TEST_UNIT_READY); + /* fall through */ + } + } + + if (usb_test_quirk(uaa, UQ_MSC_NO_SYNC_CACHE) == 0) { + err = bbb_command_start(sc, DIR_NONE, 0, NULL, 0, + &scsi_sync_cache, sizeof(scsi_sync_cache), + USB_MS_HZ); + if (err == ERR_CSW_FAILED) { + if (usb_get_manufacturer(udev) != NULL && usb_get_product(udev) != NULL) { + DPRINTFN(0, "Applying dynamic quirk UQ_MSC_NO_SYNC_CACHE for USB mass storage device %s %s (VID/DID 0x%x:0x%x)\n", + usb_get_manufacturer(udev), + usb_get_product(udev), + UGETW(udev->ddesc.idVendor), + UGETW(udev->ddesc.idProduct) + ); + } + usbd_add_dynamic_quirk(udev, UQ_MSC_NO_SYNC_CACHE); + goto error; + } + } + retry_sync_cache: err = bbb_command_start(sc, DIR_IN, 0, NULL, 0, &scsi_sync_cache, sizeof(scsi_sync_cache), @@ -917,9 +952,7 @@ DPRINTF("Device did not respond, enabling all quirks\n"); - usbd_add_dynamic_quirk(udev, UQ_MSC_NO_SYNC_CACHE); usbd_add_dynamic_quirk(udev, UQ_MSC_NO_PREVENT_ALLOW); - usbd_add_dynamic_quirk(udev, UQ_MSC_NO_TEST_UNIT_READY); /* Need to re-enumerate the device */ usbd_req_re_enumerate(udev, NULL);