Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 15 Mar 2026 00:48:23 +0100
From:      Oliver Pinter <oliver.pntr@gmail.com>
To:        "Bjoern A. Zeeb" <bz@freebsd.org>
Cc:        "src-committers@freebsd.org" <src-committers@freebsd.org>,  "dev-commits-src-all@freebsd.org" <dev-commits-src-all@freebsd.org>,  "dev-commits-src-main@freebsd.org" <dev-commits-src-main@freebsd.org>
Subject:   Re: git: b4daeded66b5 - main - usb: umass: add SCSIEJECT quirk and fix RTW8821CU_CD (USB mode switch)
Message-ID:  <CAPjTQNE7ZWsYByR45p%2B5hGBfrWZMVxv5M=W10f-4wDc7ik7yVw@mail.gmail.com>
In-Reply-To: <69aedac4.33ef1.717b7bd3@gitrepo.freebsd.org>

index | next in thread | previous in thread | raw e-mail

[-- Attachment #1 --]
On Monday, March 9, 2026, Bjoern A. Zeeb <bz@freebsd.org> wrote:

> The branch main has been updated by bz:
>
> URL: https://cgit.FreeBSD.org/src/commit/?id=
> b4daeded66b5e950ed8e618d66915b863c2414b1
>
> commit b4daeded66b5e950ed8e618d66915b863c2414b1
> Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
> AuthorDate: 2026-01-26 13:19:37 +0000
> Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
> CommitDate: 2026-03-09 14:35:31 +0000
>
>     usb: umass: add SCSIEJECT quirk and fix RTW8821CU_CD (USB mode switch)
>
>     Several Realtek (and lots other) USB dongles present themselves as
>     CDROM device first.  Upon eject they do a mode switch and suddenly
>     are a different kind of device (sometimes even with different IDs),
>     e.g., a wireless dongle.
>
>     In order to avoid the CDROM stage and rather than adding the quirk
>     handling to more drivers, add support to umass and if enabled
>     automatically eject the "CDROM" to make it the real device.
>
>     Longer-term some other drivers could stop using their hand-rolled
>     support for this.  It is unclear as-to how much we need the list of
>     (eject) quirks from u3g here, or if these are very specific to that
>     kind of devices.


Hi!

Wouldn't be better to initiate these kind of ejects from devd rather than
from kernel?


>
>     Sponsored by:   The FreeBSD Foundation
>     Fixes:          b3b6a959c85a, 9c0cce328363
>     Reviewed by:    imp
>     Differential Revision: https://reviews.freebsd.org/D54901
> ---
>  sys/dev/usb/quirk/usb_quirk.c |  2 +-
>  sys/dev/usb/storage/umass.c   | 57 ++++++++++++++++++++++++++++++
> ++++++++++++-
>  2 files changed, 57 insertions(+), 2 deletions(-)
>
> diff --git a/sys/dev/usb/quirk/usb_quirk.c b/sys/dev/usb/quirk/usb_quirk.c
> index 04441b2a344b..303f76f37fb0 100644
> --- a/sys/dev/usb/quirk/usb_quirk.c
> +++ b/sys/dev/usb/quirk/usb_quirk.c
> @@ -532,7 +532,7 @@ static struct usb_quirk_entry
> usb_quirks[USB_DEV_QUIRKS_MAX] = {
>             UQ_MSC_NO_INQUIRY, UQ_CFG_INDEX_0),
>         USB_QUIRK(SMART2, G2MEMKEY, UQ_MSC_NO_INQUIRY),
>         USB_QUIRK_REV(RALINK, RT_STOR, 0x0001, 0x0001, UQ_MSC_IGNORE),
> -       USB_QUIRK(REALTEK, RTW8821CU_CD, UQ_MSC_IGNORE),
> +       USB_QUIRK(REALTEK, RTW8821CU_CD, UQ_MSC_EJECT_SCSIEJECT),
>         /* Non-standard USB MIDI devices */
>         USB_QUIRK(ROLAND, UM1, UQ_AU_VENDOR_CLASS),
>         USB_QUIRK(ROLAND, SC8850, UQ_AU_VENDOR_CLASS),
> diff --git a/sys/dev/usb/storage/umass.c b/sys/dev/usb/storage/umass.c
> index cacf4ddf8f16..0ee6ea992fa7 100644
> --- a/sys/dev/usb/storage/umass.c
> +++ b/sys/dev/usb/storage/umass.c
> @@ -115,6 +115,7 @@
>  #include <sys/sx.h>
>  #include <sys/unistd.h>
>  #include <sys/callout.h>
> +#include <sys/eventhandler.h>
>  #include <sys/malloc.h>
>  #include <sys/priv.h>
>
> @@ -124,6 +125,7 @@
>  #include "usbdevs.h"
>
>  #include <dev/usb/quirk/usb_quirk.h>
> +#include <dev/usb/usb_msctest.h>
>
>  #include <cam/cam.h>
>  #include <cam/cam_ccb.h>
> @@ -705,6 +707,59 @@ static const uint8_t fake_inq_data[SHORT_INQUIRY_LENGTH]
> = {
>  #define        UFI_COMMAND_LENGTH      12      /* UFI commands are always
> 12 bytes */
>  #define        ATAPI_COMMAND_LENGTH    12      /* ATAPI commands are
> always 12 bytes */
>
> +static void
> +umass_autoinst_eject_quirks(void *arg __unused, struct usb_device *udev,
> +    struct usb_attach_arg *uaa)
> +{
> +       struct usb_interface *iface;
> +       struct usb_interface_descriptor *id;
> +
> +       if (uaa->dev_state != UAA_DEV_READY)
> +               return;
> +
> +       iface = usbd_get_iface(udev, 0);
> +       if (iface == NULL)
> +               return;
> +
> +       id = iface->idesc;
> +       if (id == NULL || id->bInterfaceClass != UICLASS_MASS)
> +               return;
> +
> +       if (usb_test_quirk(uaa, UQ_MSC_EJECT_SCSIEJECT)) {
> +               int error;
> +
> +               error = usb_msc_eject(uaa->device, 0, MSC_EJECT_STOPUNIT);
> +               if (error == 0)
> +                       uaa->dev_state = UAA_DEV_EJECTING;
> +               else
> +                       printf("UMASS failed to eject by SCSI eject
> STOPUNIT "
> +                           "command based on quirk: %d\n", error);
> +       }
> +}
> +
> +static eventhandler_tag umass_drv_evh_tag;
> +
> +static int
> +umass_driver_evh(struct module *mod, int what, void *arg)
> +{
> +
> +       switch (what) {
> +       case MOD_LOAD:
> +               umass_drv_evh_tag = EVENTHANDLER_REGISTER(usb_dev_
> configured,
> +                   umass_autoinst_eject_quirks, NULL,
> EVENTHANDLER_PRI_ANY);
> +               break;
> +       case MOD_UNLOAD:
> +               if (umass_drv_evh_tag != NULL)
> +                       EVENTHANDLER_DEREGISTER(usb_dev_configured,
> +                           umass_drv_evh_tag);
> +               break;
> +       default:
> +               return (EOPNOTSUPP);
> +       }
> +
> +       return (0);
> +}
> +
>  static device_method_t umass_methods[] = {
>         /* Device interface */
>         DEVMETHOD(device_probe, umass_probe),
> @@ -725,7 +780,7 @@ static const STRUCT_USB_HOST_ID __used umass_devs[] = {
>         {USB_IFACE_CLASS(UICLASS_MASS),},
>  };
>
> -DRIVER_MODULE(umass, uhub, umass_driver, NULL, NULL);
> +DRIVER_MODULE(umass, uhub, umass_driver, umass_driver_evh, NULL);
>  MODULE_DEPEND(umass, usb, 1, 1, 1);
>  MODULE_DEPEND(umass, cam, 1, 1, 1);
>  MODULE_VERSION(umass, 1);
>
>

[-- Attachment #2 --]
<br><br>On Monday, March 9, 2026, Bjoern A. Zeeb &lt;<a href="mailto:bz@freebsd.org">bz@freebsd.org</a>&gt; wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The branch main has been updated by bz:<br>
<br>
URL: <a href="https://cgit.FreeBSD.org/src/commit/?id=b4daeded66b5e950ed8e618d66915b863c2414b1" target="_blank">https://cgit.FreeBSD.org/src/<wbr>commit/?id=<wbr>b4daeded66b5e950ed8e618d66915b<wbr>863c2414b1</a><br>;
<br>
commit b4daeded66b5e950ed8e618d66915b<wbr>863c2414b1<br>
Author:     Bjoern A. Zeeb &lt;bz@FreeBSD.org&gt;<br>
AuthorDate: 2026-01-26 13:19:37 +0000<br>
Commit:     Bjoern A. Zeeb &lt;bz@FreeBSD.org&gt;<br>
CommitDate: 2026-03-09 14:35:31 +0000<br>
<br>
    usb: umass: add SCSIEJECT quirk and fix RTW8821CU_CD (USB mode switch)<br>
<br>
    Several Realtek (and lots other) USB dongles present themselves as<br>
    CDROM device first.  Upon eject they do a mode switch and suddenly<br>
    are a different kind of device (sometimes even with different IDs),<br>
    e.g., a wireless dongle.<br>
<br>
    In order to avoid the CDROM stage and rather than adding the quirk<br>
    handling to more drivers, add support to umass and if enabled<br>
    automatically eject the &quot;CDROM&quot; to make it the real device.<br>
<br>
    Longer-term some other drivers could stop using their hand-rolled<br>
    support for this.  It is unclear as-to how much we need the list of<br>
    (eject) quirks from u3g here, or if these are very specific to that<br>
    kind of devices.</blockquote><div><br></div><div>Hi!</div><div><br></div><div>Wouldn&#39;t be better to initiate these kind of ejects from devd rather than from kernel?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
    Sponsored by:   The FreeBSD Foundation<br>
    Fixes:          b3b6a959c85a, 9c0cce328363<br>
    Reviewed by:    imp<br>
    Differential Revision: <a href="https://reviews.freebsd.org/D54901" target="_blank">https://reviews.freebsd.org/<wbr>D54901</a><br>;
---<br>
 sys/dev/usb/quirk/usb_quirk.c |  2 +-<br>
 sys/dev/usb/storage/umass.c   | 57 ++++++++++++++++++++++++++++++<wbr>++++++++++++-<br>
 2 files changed, 57 insertions(+), 2 deletions(-)<br>
<br>
diff --git a/sys/dev/usb/quirk/usb_quirk.<wbr>c b/sys/dev/usb/quirk/usb_quirk.<wbr>c<br>
index 04441b2a344b..303f76f37fb0 100644<br>
--- a/sys/dev/usb/quirk/usb_quirk.<wbr>c<br>
+++ b/sys/dev/usb/quirk/usb_quirk.<wbr>c<br>
@@ -532,7 +532,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {<br>
            UQ_MSC_NO_INQUIRY, UQ_CFG_INDEX_0),<br>
        USB_QUIRK(SMART2, G2MEMKEY, UQ_MSC_NO_INQUIRY),<br>
        USB_QUIRK_REV(RALINK, RT_STOR, 0x0001, 0x0001, UQ_MSC_IGNORE),<br>
-       USB_QUIRK(REALTEK, RTW8821CU_CD, UQ_MSC_IGNORE),<br>
+       USB_QUIRK(REALTEK, RTW8821CU_CD, UQ_MSC_EJECT_SCSIEJECT),<br>
        /* Non-standard USB MIDI devices */<br>
        USB_QUIRK(ROLAND, UM1, UQ_AU_VENDOR_CLASS),<br>
        USB_QUIRK(ROLAND, SC8850, UQ_AU_VENDOR_CLASS),<br>
diff --git a/sys/dev/usb/storage/umass.c b/sys/dev/usb/storage/umass.c<br>
index cacf4ddf8f16..0ee6ea992fa7 100644<br>
--- a/sys/dev/usb/storage/umass.c<br>
+++ b/sys/dev/usb/storage/umass.c<br>
@@ -115,6 +115,7 @@<br>
 #include &lt;sys/sx.h&gt;<br>
 #include &lt;sys/unistd.h&gt;<br>
 #include &lt;sys/callout.h&gt;<br>
+#include &lt;sys/eventhandler.h&gt;<br>
 #include &lt;sys/malloc.h&gt;<br>
 #include &lt;sys/priv.h&gt;<br>
<br>
@@ -124,6 +125,7 @@<br>
 #include &quot;usbdevs.h&quot;<br>
<br>
 #include &lt;dev/usb/quirk/usb_quirk.h&gt;<br>
+#include &lt;dev/usb/usb_msctest.h&gt;<br>
<br>
 #include &lt;cam/cam.h&gt;<br>
 #include &lt;cam/cam_ccb.h&gt;<br>
@@ -705,6 +707,59 @@ static const uint8_t fake_inq_data[SHORT_INQUIRY_<wbr>LENGTH] = {<br>
 #define        UFI_COMMAND_LENGTH      12      /* UFI commands are always 12 bytes */<br>
 #define        ATAPI_COMMAND_LENGTH    12      /* ATAPI commands are always 12 bytes */<br>
<br>
+static void<br>
+umass_autoinst_eject_quirks(<wbr>void *arg __unused, struct usb_device *udev,<br>
+    struct usb_attach_arg *uaa)<br>
+{<br>
+       struct usb_interface *iface;<br>
+       struct usb_interface_descriptor *id;<br>
+<br>
+       if (uaa-&gt;dev_state != UAA_DEV_READY)<br>
+               return;<br>
+<br>
+       iface = usbd_get_iface(udev, 0);<br>
+       if (iface == NULL)<br>
+               return;<br>
+<br>
+       id = iface-&gt;idesc;<br>
+       if (id == NULL || id-&gt;bInterfaceClass != UICLASS_MASS)<br>
+               return;<br>
+<br>
+       if (usb_test_quirk(uaa, UQ_MSC_EJECT_SCSIEJECT)) {<br>
+               int error;<br>
+<br>
+               error = usb_msc_eject(uaa-&gt;device, 0, MSC_EJECT_STOPUNIT);<br>
+               if (error == 0)<br>
+                       uaa-&gt;dev_state = UAA_DEV_EJECTING;<br>
+               else<br>
+                       printf(&quot;UMASS failed to eject by SCSI eject STOPUNIT &quot;<br>
+                           &quot;command based on quirk: %d\n&quot;, error);<br>
+       }<br>
+}<br>
+<br>
+static eventhandler_tag umass_drv_evh_tag;<br>
+<br>
+static int<br>
+umass_driver_evh(struct module *mod, int what, void *arg)<br>
+{<br>
+<br>
+       switch (what) {<br>
+       case MOD_LOAD:<br>
+               umass_drv_evh_tag = EVENTHANDLER_REGISTER(usb_dev_<wbr>configured,<br>
+                   umass_autoinst_eject_quirks, NULL, EVENTHANDLER_PRI_ANY);<br>
+               break;<br>
+       case MOD_UNLOAD:<br>
+               if (umass_drv_evh_tag != NULL)<br>
+                       EVENTHANDLER_DEREGISTER(usb_<wbr>dev_configured,<br>
+                           umass_drv_evh_tag);<br>
+               break;<br>
+       default:<br>
+               return (EOPNOTSUPP);<br>
+       }<br>
+<br>
+       return (0);<br>
+}<br>
+<br>
 static device_method_t umass_methods[] = {<br>
        /* Device interface */<br>
        DEVMETHOD(device_probe, umass_probe),<br>
@@ -725,7 +780,7 @@ static const STRUCT_USB_HOST_ID __used umass_devs[] = {<br>
        {USB_IFACE_CLASS(UICLASS_MASS)<wbr>,},<br>
 };<br>
<br>
-DRIVER_MODULE(umass, uhub, umass_driver, NULL, NULL);<br>
+DRIVER_MODULE(umass, uhub, umass_driver, umass_driver_evh, NULL);<br>
 MODULE_DEPEND(umass, usb, 1, 1, 1);<br>
 MODULE_DEPEND(umass, cam, 1, 1, 1);<br>
 MODULE_VERSION(umass, 1);<br>
<br>
</blockquote>
home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAPjTQNE7ZWsYByR45p%2B5hGBfrWZMVxv5M=W10f-4wDc7ik7yVw>