Hi Johan, > We need to let the setup stage complete cleanly even when the HCI device > is rfkilled. Otherwise the HCI device will stay in an undefined state > and never get notified to user space through mgmt (even when it gets > unblocked through rfkill). > > This patch makes sure that hci_dev_open() can be called in the HCI_SETUP > stage, that blocking the device doesn't abort the setup stage, and that > the device gets proper powered down as soon as the setup stage completes > in case it was blocked meanwhile. > > The bug that this patch fixed can be very easily reproduced using e.g. > the rfkill command line too. By running "rfkill block all" before > inserting a Bluetooth dongle the resulting HCI device goes into a state > where it is never announced over mgmt, not even when "rfkill unblock all" > is run. > > Signed-off-by: Johan Hedberg <johan.hedberg@xxxxxxxxx> > Cc: stable@xxxxxxxxxxxxxxx > --- > net/bluetooth/hci_core.c | 14 ++++++++++++-- > 1 file changed, 12 insertions(+), 2 deletions(-) > > diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c > index d0d6cf8..433820a 100644 > --- a/net/bluetooth/hci_core.c > +++ b/net/bluetooth/hci_core.c > @@ -1148,7 +1148,11 @@ int hci_dev_open(__u16 dev) > goto done; > } > > - if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) { > + /* Check for rfkill but allow the HCI setup stage to proceed > + * (which in itself doesn't cause any RF activity). > + */ > + if (test_bit(HCI_RFKILLED, &hdev->dev_flags) && > + !test_bit(HCI_SETUP, &hdev->dev_flags)) { > ret = -ERFKILL; > goto done; > } > @@ -1599,7 +1603,8 @@ static int hci_rfkill_set_block(void *data, bool blocked) > > if (blocked) { > set_bit(HCI_RFKILLED, &hdev->dev_flags); > - hci_dev_do_close(hdev); > + if (!test_bit(HCI_SETUP, &hdev->dev_flags)) > + hci_dev_do_close(hdev); > } else { > clear_bit(HCI_RFKILLED, &hdev->dev_flags); > } > @@ -1624,6 +1629,11 @@ static void hci_power_on(struct work_struct *work) > return; > } > > + if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) { > + clear_bit(HCI_AUTO_OFF, &hdev->dev_flags); > + hci_dev_do_close(hdev); > + } > + this might be better extend with } else if (test_bit(HCI_AUTO_OFF, ...) > if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) > queue_delayed_work(hdev->req_workqueue, &hdev->power_off, > HCI_AUTO_OFF_TIMEOUT); Makes the code a little bit more readable for the reason that I want to add a return from the function to the HCI_RFKILLED check every time I read it, but that would be actually wrong. Regards Marcel -- 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