Bluetooth: Fix mgmt handling of power on failures

If hci_dev_open fails we need to ensure that the corresponding
mgmt_set_powered command gets an appropriate response. This patch fixes
the missing response by adding a new mgmt_set_powered_failed function
that's used to indicate a power on failure to mgmt. Since a situation
with the device being rfkilled may require special handling in user
space the patch uses a new dedicated mgmt status code for this.

Signed-off-by: Johan Hedberg <[email protected]>
Cc: [email protected]
Acked-by: Marcel Holtmann <[email protected]>
Signed-off-by: Gustavo Padovan <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
This commit is contained in:
Johan Hedberg 2013-05-29 09:51:29 +03:00 • committed by John W. Linville
commit 96570ffcca
4 changed files with 28 additions and 1 deletions

View file

@ -1555,11 +1555,15 @@ static const struct rfkill_ops hci_rfkill_ops = {
static void hci_power_on(struct work_struct *work)
{
struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
int err;
BT_DBG("%s", hdev->name);
if (hci_dev_open(hdev->id) < 0)
err = hci_dev_open(hdev->id);
if (err < 0) {
mgmt_set_powered_failed(hdev, err);
return;
}
if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
queue_delayed_work(hdev->req_workqueue, &hdev->power_off,

View file

@ -3418,6 +3418,27 @@ new_settings:
return err;
}
int mgmt_set_powered_failed(struct hci_dev *hdev, int err)
{
struct pending_cmd *cmd;
u8 status;
cmd = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev);
if (!cmd)
return -ENOENT;
if (err == -ERFKILL)
status = MGMT_STATUS_RFKILLED;
else
status = MGMT_STATUS_FAILED;
err = cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_POWERED, status);
mgmt_pending_remove(cmd);
return err;
}
int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable)
{
struct cmd_lookup match = { NULL, hdev };