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]

 



Add Cc. to experts: Johannes Berg, David S. Miller, Marcel Holtmann and
Gary Lin

Hi OldÅich, 

æ æï2011-03-20 æ 21:09 +0100ïOldÅich JedliÄka æåï
> Hi Joey Lee,
> 
> Finally I've got little time to expriment.
> 

Thank's for you also reserve time to trace it. And, I also add comment
on bugzilla:
https://bugzilla.kernel.org/show_bug.cgi?id=31002

> On Wednesday 16 March 2011 09:59:16 Joey Lee wrote:
> > 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);
> 
> Both work. I've tested first CONFIG_RFKILL_INPUT disabled. Second I've tried to 
> enable CONFIG_RFKILL_INPUT, but remove the mentioned block of code. The result 
> is working bluetooth HW switch.
> 

Yes, that because the following patch introduce
driver with persistent state will affect the global state only if rfkill-input
is enabled:

http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b3fa1329eaf2a7b97124dacf5b663fd51346ac19

It maybe workaround another rfkill-input issue, but causes it replicate acer-wmi's 
bluetooth killswitch initial state (or any driver that used rfkill_init_sw_state) 
to any new bluetooth killswitch.

It's not make sense.

> > > > 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> > > 
> > > 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.
> 
> `lshal -m` outputs this:
> 
> <bluetooth key pressed>
> 20:45:53.694: platform_i8042_i8042_KBD_port_logicaldev_input condition 
> ButtonPressed = bluetooth
> 20:45:54.666: platform_acer_wmi_rfkill_acer_bluetooth_bluetooth property 
> killswitch.state = 1 (0x1)
> 20:45:54.678: usb_device_a5c_2101_noserial added
> ...
> <bluetooth key pressed again>
> 20:46:02.435: platform_i8042_i8042_KBD_port_logicaldev_input condition 
> ButtonPressed = brightness-up
> 20:46:02.668: platform_acer_wmi_rfkill_acer_bluetooth_bluetooth property 
> killswitch.state = 0 (0x0)
> 20:46:02.919: usb_device_a5c_2101_noserial_if1 removed
> ...
> 
> Strange is "brightness-up" key, somebody is wrong here.
> 

Yes, brightness-up key is another story, maybe you can enable acpi debug
to look at montior which acpi method or _Q event method used:

echo 0xFFFFFFFF >/sys/module/acpi/parameters/debug_layer
echo 0xF >/sys/module/acpi/parameters/debug_level

But, this is not related to our current killswitch issue, let us skip
it.

> > > 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.
> 
> Disabling CONFIG_RFKILL_INPUT works - see above. I had a look at Kconfig in 
> net/rfkill and there is a line "default y if !EXPERT" which means (I think) 
> that it would be enabled by default for anybody not enabling expert options. 
> So other non-expert users would have the same troubles as I have.
> 

I agreed your point, and I don't think rfkill-input need enable for all
non-Expert user because it sometimes have conflict with EC or userland
behavior.

I still suggest you can disable rfkill-input then please try Gary Lin's
urfkill daemon, it can do what does rfkill-input do and more
flexibility.

> I've tried `rfkill unblock <acer-bluetooth number>` with my second test 
> (enabled CONFIG_RFKILL_INPUT plus patched core.c) - it works perfectly.
> 
> Anyway, it looks like using CONFIG_RFKILL_INPUT is broken to some degree, 
> because enabling the config switch changes bluetooth HW/SW switch from working 
> to not-fully-working.
> 
> Cheers,
> OldÅich.
> 

The root cause is what I said in the above, it's hard to fix in kernel
module because user only can choice enable/disable rfkill-input in
Kconfig and even cann't choice it when system boot.

I thought we need:
 - set rfkill-input to EXPERT, remove !EXPERT
 - add a kernel option to rfkill for user can choice enable it or not
when system boot.
 - Add comment in Documentation/rfkill.txt for remind user can use
urfkill daemon (or any other userland daemon) to replace rfkill-input.

Of course need rfkill experts' more professional comments for this
topic.
I will try to generate a patches to implement the above 3 things then
send out to rfkill experts for review.


Thank's a lot!
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