Re: acer-wmi: rfkill and bluetooth enabling doesn't work as in 2.6.37

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

 



Hi OldÅich,

æ äï2011-03-16 æ 07:32 +0100ïOldÅich JedliÄka æåï
> > After trace rfkill-input stuff, I thought this is rfkill-input's normal
> > behavior but not a bug.
> > 
> > Unfortunately, I didn't find any workaround way when a driver need to
> > call rfkill_init_sw_state, e.g. acer-wmi driver.
> > 
> > The rfkill-input will sync the rfkill state to all killswitchs that have
> > the same type. For example, acer-wmi set the initial software switch to
> > _BLOCK_ when driver initial, then rfkill-input will also set any new
> > bluetooth killswitch state to _BLOCK_ .
> 
> The rfkill_sync_work syncs with rfkill_global_states, which is set during 
> intitialization or by rfkill_switch_all, if I read it correctly. This should 
> be independent to acer-bluetooth state. The rfkill_global_states[BLUETOOTH] 
> should be unblocked initially, I need to verify it.
> 

Yes!
Ideally, killswitch state should be independent to different driver,
even the killswitch type is the same.

But, 
If you enabled CONFIG_RFKILL_INPUT, then rfkill_register will replicate
state for each killswitch that have the same type:

vi net/rfkill/core.c

int __must_check rfkill_register(struct rfkill *rfkill)
{
...
        if (!rfkill->persistent || rfkill_epo_lock_active) {
                schedule_work(&rfkill->sync_work);
        } else {		/* if rfkill->persistent then set the state to all the same type */
#ifdef CONFIG_RFKILL_INPUT	/* when CONFIG_RFKILL_INPUT = Y */
                bool soft_blocked = !!(rfkill->state & RFKILL_BLOCK_SW);

                if (!atomic_read(&rfkill_input_disabled))
                        __rfkill_switch_all(rfkill->type, soft_blocked);	/* here call switch all to sync state */
#endif
        }

When any driver call rfkill_init_sw_state for set the initial state to
killswitch, this rfkill->persistent will set to true:

void rfkill_init_sw_state(struct rfkill *rfkill, bool blocked)	/* acer-wmi driver used it to set inital killswitch state */
{
....
        spin_lock_irqsave(&rfkill->lock, flags);
        __rfkill_set_sw_state(rfkill, blocked);	
        rfkill->persistent = true			/* persistent set to true */


That's why acer-wmi bluetooth killswitch's state was been replicate to
hci_core's killswitch state.

When CONFIG_RFKILL_INPUT set to Y, and any driver call
rfkill_init_sw_state before register rfkill, then rfkill_register will
try to sync state to the same killswitch type like the above.

It's make sense,
because rfkill-input only can block/unblock the same killswitch type at
the same time, before rfkill-input active, it want all the same type's
state is full the same.

And,
rfkill-input also suppose user only can use keycode (maybe Fn key) to
control killswitch state, so, direct use rkill tool or echo state to
killswitch for change the state will cause killswitchs' state lost link.
It like we do.


> There is some magic in rfkill/input.c that plays with global states, but I 
> don't know if or how that one is used in my case.
> 

Suggest you can disable CONFIG_RFKILL_INPUT or markup the following
code. You will see the new bluetooth killswitch will be unblock when it
created.

diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index 0198191..0dec078 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -950,14 +950,14 @@ int __must_check rfkill_register(struct rfkill *rfkill)
 
        if (!rfkill->persistent || rfkill_epo_lock_active) {
                schedule_work(&rfkill->sync_work);
-       } else {
-#ifdef CONFIG_RFKILL_INPUT
-               bool soft_blocked = !!(rfkill->state & RFKILL_BLOCK_SW);
-
-               if (!atomic_read(&rfkill_input_disabled))
-                       __rfkill_switch_all(rfkill->type, soft_blocked);
-#endif
-       }
+       } //else {
+//#ifdef CONFIG_RFKILL_INPUT
+//             bool soft_blocked = !!(rfkill->state & RFKILL_BLOCK_SW);
+//
+//             if (!atomic_read(&rfkill_input_disabled))
+//                     __rfkill_switch_all(rfkill->type, soft_blocked);
+//#endif
+//     }
 
        rfkill_send_events(rfkill, RFKILL_OP_ADD);

> > Acer's BIOS default setup bluetooth's state is disable when system cold
> > boot, and BIOS also can save the connection devices' state when system
> > reboot. Currently, acer-wmi driver have right behavior to sync the state
> > with BIOS.
> >
> > Face to your situation, my suggestion is:
> > 
> > - Use userland application to correct killswitch state.
> >   highly suggest You can try urfkill daemon:
> > http://www.freedesktop.org/wiki/Software/urfkill or
> >   write a startup script to enable bluetooth when system boot.
> > 
> > - Disable rfkill-input module if you didn't real use it.
> >   The TravelMate 5730G have wifi hotkey that only emit KEY_WLAN, but
> >   doesn't emit KEY_BLUETOOTH, that means rfkill-input cann't help you
> >   enable bluetooth killswitch.
> 
> I didn't have time to look at the problem more deeply to identify who is 
> setting the global state to "blocked" or what really happens. Anyway, I did 
> some testing with pressing the HW bluetooth switch and I saw the following 
> immediately _after_ pressing the HW switch to enable bluetooth:
> 
> oldium ~ # rfkill list
> 0: acer-wireless: Wireless LAN
>         Soft blocked: no
>         Hard blocked: no
> 1: acer-bluetooth: Bluetooth
>         Soft blocked: no
>         Hard blocked: no
> 2: acer-threeg: Wireless WAN
>         Soft blocked: yes
>         Hard blocked: no
> 3: phy0: Wireless LAN
>         Soft blocked: no
>         Hard blocked: no
> 
> I had this output 3 times immediately after each other. I'm using keyboard 
> "up" and "enter" to repeat the last shell command, so this is a relatively 
> slow operation. So the state when the acer-bluetooth was unblocked stayed for 
> relatively long time before hci0 appeared in rfkill. Afterwards I saw:
> 
> oldium ~ # rfkill list
> 0: acer-wireless: Wireless LAN
>         Soft blocked: no
>         Hard blocked: no
> 1: acer-bluetooth: Bluetooth
>         Soft blocked: no
>         Hard blocked: no
> 2: acer-threeg: Wireless WAN
>         Soft blocked: yes
>         Hard blocked: no
> 3: phy0: Wireless LAN
>         Soft blocked: no
>         Hard blocked: no
> 5: hci0: Bluetooth
>         Soft blocked: yes
>         Hard blocked: no
> 

My Acer machine have no HW bluetooth key but only have one HW WLAN key
that emit KEY_WLAN.
Please use lshal to monitor your HW bluetooth key and make sure it emit
KEY_BLUETOOTH.

> So it looks like the hci0 went blocked even when the acer-bluetooth switch was 
> unblocked. So it looks like the hci0 state is independent on the initial acer-
> bluetooth state.
> 
> Hopefully I have some time this evening (CET timezone) to add some stack 
> traces and logs to see what really happens on my system.
> 
> Cheers,
> OldÅich.
> 

Still suggest you can disable CONFIG_RFKILL_INPUT then use rfkill tool
to set acer-wmi bluetooth killswitch for test, must have different
result.


Thank's
Joey Lee

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[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