diff mbox series

Bluetooth: btusb: add sysfs attribute to control USB alt setting

Message ID 20241212173551.192925-1-yinghsu@chromium.org
State New
Headers show
Series Bluetooth: btusb: add sysfs attribute to control USB alt setting | expand

Commit Message

Ying Hsu Dec. 12, 2024, 5:35 p.m. UTC
When a Bluetooth raw socket is open, the HCI event related to SCO
connection changes are not dispatched to the hci_event module, and
the underlying Bluetooth controller's USB Interface 1 will not be
updated accordingly.

This patch adds `isoc_alt` sysfs attribute, allowing user space
to update the alternate setting of the USB interface alternate
setting as needed.

BUG=b:382526205
TEST=read and write /sys/class/bluetooth/hci0/isoc_alt

Series-to: linux-bluetooth@vger.kernel.org
Series-to: luiz.dentz@gmail.com
Series-cc: chromeos-bluetooth-upstreaming@chromium.org

Commit-notes:
This commit has been tested on a chromebook with AX211.
END

Change-Id: Ifc708cc471a8834b344c26fce1ce2fe3e5992cad
Signed-off-by: Ying Hsu <yinghsu@chromium.org>
---
 drivers/bluetooth/btusb.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

Comments

Luiz Augusto von Dentz Dec. 12, 2024, 6:02 p.m. UTC | #1
Hi Ying,

On Thu, Dec 12, 2024 at 12:35 PM Ying Hsu <yinghsu@chromium.org> wrote:
>
> When a Bluetooth raw socket is open, the HCI event related to SCO
> connection changes are not dispatched to the hci_event module, and
> the underlying Bluetooth controller's USB Interface 1 will not be
> updated accordingly.
>
> This patch adds `isoc_alt` sysfs attribute, allowing user space
> to update the alternate setting of the USB interface alternate
> setting as needed.
>
> BUG=b:382526205
> TEST=read and write /sys/class/bluetooth/hci0/isoc_alt
>
> Series-to: linux-bluetooth@vger.kernel.org
> Series-to: luiz.dentz@gmail.com
> Series-cc: chromeos-bluetooth-upstreaming@chromium.org
>
> Commit-notes:
> This commit has been tested on a chromebook with AX211.
> END
>
> Change-Id: Ifc708cc471a8834b344c26fce1ce2fe3e5992cad

Ok, what is up with these artifacts? I don't think we use those upstream.

> Signed-off-by: Ying Hsu <yinghsu@chromium.org>
> ---
>  drivers/bluetooth/btusb.c | 32 ++++++++++++++++++++++++++++++++
>  1 file changed, 32 insertions(+)
>
> diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
> index 279fe6c115fa..e8446f3e026e 100644
> --- a/drivers/bluetooth/btusb.c
> +++ b/drivers/bluetooth/btusb.c
> @@ -3645,6 +3645,32 @@ static const struct file_operations force_poll_sync_fops = {
>         .llseek         = default_llseek,
>  };
>
> +static ssize_t isoc_alt_show(struct device *dev,
> +                            struct device_attribute *attr,
> +                            char *buf)
> +{
> +       struct btusb_data *data = dev_get_drvdata(dev);
> +
> +       return sysfs_emit(buf, "%d\n", data->isoc_altsetting);
> +}
> +
> +static ssize_t isoc_alt_store(struct device *dev,
> +                             struct device_attribute *attr,
> +                             const char *buf, size_t count)
> +{
> +       struct btusb_data *data = dev_get_drvdata(dev);
> +       int alt;
> +       int ret;
> +
> +       if (kstrtoint(buf, 10, &alt))
> +               return -EINVAL;
> +
> +       ret = btusb_switch_alt_setting(data->hdev, alt);
> +       return ret < 0 ? ret : count;
> +}
> +
> +static DEVICE_ATTR_RW(isoc_alt);
> +
>  static int btusb_probe(struct usb_interface *intf,
>                        const struct usb_device_id *id)
>  {
> @@ -4032,6 +4058,10 @@ static int btusb_probe(struct usb_interface *intf,
>         debugfs_create_file("force_poll_sync", 0644, hdev->debugfs, data,
>                             &force_poll_sync_fops);
>
> +       err = device_create_file(&intf->dev, &dev_attr_isoc_alt);
> +       if (err)
> +               goto out_free_dev;

This should probably be behind a check for data->isoc, otherwise it
won't be useful to export into sysfs if there isn't any interface to
begin with or that has been marked as broken (e.g. BTUSB_BROKEN_ISOC).

>         return 0;
>
>  out_free_dev:
> @@ -4052,6 +4082,8 @@ static void btusb_disconnect(struct usb_interface *intf)
>                 return;
>
>         hdev = data->hdev;
> +       device_remove_file(&intf->dev, &dev_attr_isoc_alt);

Ditto, make it conditional to data->isoc.

>         usb_set_intfdata(data->intf, NULL);
>
>         if (data->isoc)
> --
> 2.47.0.338.g60cca15819-goog
>
diff mbox series

Patch

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 279fe6c115fa..e8446f3e026e 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -3645,6 +3645,32 @@  static const struct file_operations force_poll_sync_fops = {
 	.llseek		= default_llseek,
 };
 
+static ssize_t isoc_alt_show(struct device *dev,
+			     struct device_attribute *attr,
+			     char *buf)
+{
+	struct btusb_data *data = dev_get_drvdata(dev);
+
+	return sysfs_emit(buf, "%d\n", data->isoc_altsetting);
+}
+
+static ssize_t isoc_alt_store(struct device *dev,
+			      struct device_attribute *attr,
+			      const char *buf, size_t count)
+{
+	struct btusb_data *data = dev_get_drvdata(dev);
+	int alt;
+	int ret;
+
+	if (kstrtoint(buf, 10, &alt))
+		return -EINVAL;
+
+	ret = btusb_switch_alt_setting(data->hdev, alt);
+	return ret < 0 ? ret : count;
+}
+
+static DEVICE_ATTR_RW(isoc_alt);
+
 static int btusb_probe(struct usb_interface *intf,
 		       const struct usb_device_id *id)
 {
@@ -4032,6 +4058,10 @@  static int btusb_probe(struct usb_interface *intf,
 	debugfs_create_file("force_poll_sync", 0644, hdev->debugfs, data,
 			    &force_poll_sync_fops);
 
+	err = device_create_file(&intf->dev, &dev_attr_isoc_alt);
+	if (err)
+		goto out_free_dev;
+
 	return 0;
 
 out_free_dev:
@@ -4052,6 +4082,8 @@  static void btusb_disconnect(struct usb_interface *intf)
 		return;
 
 	hdev = data->hdev;
+	device_remove_file(&intf->dev, &dev_attr_isoc_alt);
+
 	usb_set_intfdata(data->intf, NULL);
 
 	if (data->isoc)