Re: [PATCH 5.12 regression fix] Bluetooth: btusb: Revert Fix the autosuspend enable and disable

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On 2/19/21 12:41 AM, Luiz Augusto von Dentz wrote:
> Hi Hans,
> 
> On Thu, Feb 18, 2021 at 2:08 PM Hans de Goede <hdegoede@xxxxxxxxxx> wrote:
>>
>> Hi Marcel,
>>
>> On 2/18/21 9:01 PM, Marcel Holtmann wrote:
>>> Hi Hans,
>>>
>>>>>> drivers/usb/core/hub.c: usb_new_device() contains the following:
>>>>> [...]
>>>>>>         err = hci_register_dev(hdev);
>>>>>>       if (err < 0)
>>>>>> @@ -4688,9 +4688,6 @@ static void btusb_disconnect(struct usb_interface *intf)
>>>>>>           gpiod_put(data->reset_gpio);
>>>>>>         hci_free_dev(hdev);
>>>>>> -
>>>>>> -    if (!enable_autosuspend)
>>>>>> -        usb_enable_autosuspend(data->udev);
>>>>> Hi Hans,
>>>>>
>>>>> And Do we need to call usb_disable_autosuspend() in the disconnect()? like below:
>>>>>
>>>>> diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
>>>>> index 32161dd40ed6..ef831492363c 100644
>>>>> --- a/drivers/bluetooth/btusb.c
>>>>> +++ b/drivers/bluetooth/btusb.c
>>>>> @@ -4673,6 +4673,9 @@ static void btusb_disconnect(struct usb_interface *intf)
>>>>>
>>>>>         hci_unregister_dev(hdev);
>>>>>
>>>>> +       if (enable_autosuspend)
>>>>> +               usb_disable_autosuspend(data->udev);
>>>>> +
>>>>>         if (intf == data->intf) {
>>>>>                 if (data->isoc)
>>>>> usb_driver_release_interface(&btusb_driver, data->isoc);
>>>>>
>>>>>
>>>>> Before the btusb_probe() is called, the usb device is autosuspend disabled, suppose users set the btusb.enable_autosuspend=1, the driver btusb will enable the autosuspend on this device. If users remove this driver, the disconnect() will be called, the usb device will keep autosuspend enabled. Next time if users reload this driver by 'sudo modprobe  btusb enalbe_autosuspend=0',  they will find the device is autosuspend enabled instead of disabled.
>>>>
>>>> The problem with calling usb_disable_autosuspend() is that the auto-suspend setting is a bool,
>>>> rather then a counter, so if a udev-rule or the user manually through e.g. :
>>>>
>>>> echo auto > /sys/bus/usb/devices/1-10/power/control
>>>>
>>>> Has enabled autosuspend then we would be disabling it, which is undesirable.
>>>>
>>>> Most USB drivers which have some way of enabling autosuspend by-default
>>>> (IOW which call usb_enable_autosuspend()) simply enable it at the end
>>>> of a successful probe and leave it as is on remove.
>>>>
>>>> Also keep in mind that remove normally runs on unplug of the device, in
>>>> which case it does not matter as the device is going away.
>>>>
>>>> If a user wants to disable autosuspend after loading the btusb module,
>>>> the correct way to do this is by simply running e.g. :
>>>>
>>>> echo on > /sys/bus/usb/devices/1-10/power/control
>>>>
>>>> Rather then rmmod-ing and insmod-ing the module with a different module-param value.
>>>
>>> then lets remove the module parameter from btusb.ko.
>>
>> The module parameter is useful to make sure runtime-suspend never gets
>> enabled starting from boot onwards, either through the kernel cmdline
>> or through modprobe.conf settings.
>>
>> Also the module parameter is used to implement CONFIG_BT_HCIBTUSB_AUTOSUSPEND
>> Kconfig option which sets the default value for the module param;
>> and most distros enable that option since it having autosuspend enabled
>> is the right thing to do in almost all cases.
> 
> Actually in case we are connected we should probably disable
> autosuspend as some BT controllers don't seem to be able to transmit
> any data back to the host if the connection stays idle long enough to
> trigger auto suspend.

Do those controller accept connection requests from previously paired
devices, without them having to be woken from userspace first?

In my experience if controllers have this issue then these controller
falsely advertise USB remote wake-up support / has broken USB remote
wake-up support and devices will also not automatically (re)connect
without first going to the bluetooth control-panel in the desktop
which wakes-up the controller from the PC side.

The fix for these controllers would be to explicitly disable
remote-wakeup on these controllers by making a call like this:

	device_set_wakeup_capable(&data->udev->dev, false);

But only on controllers where we know the remote-wakeup is broken.

This will still allow the device to be runtime/auto-suspended when
bluetooth is disabled by the user, while disabling it when bluetooth
is enabled. This works this way because of the following btusb.c code:

static int btusb_open(struct hci_dev *hdev)
{
	...
	data->intf->needs_remote_wakeup = 1;
	...
}

static int btusb_close(struct hci_dev *hdev)
{
	...
	data->intf->needs_remote_wakeup = 0;
	...
}

Regards,

Hans




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux