| --- a/drivers/bluetooth/hci_intel.c |
| +++ b/drivers/bluetooth/hci_intel.c |
| @@ -122,8 +122,9 @@ static u8 intel_convert_speed(unsigned i |
| static int intel_wait_booting(struct hci_uart *hu) |
| { |
| struct intel_data *intel = hu->priv; |
| - int err; |
| + int err = 0; |
| |
| +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) |
| err = wait_on_bit_timeout(&intel->flags, STATE_BOOTING, |
| TASK_INTERRUPTIBLE, |
| msecs_to_jiffies(1000)); |
| @@ -137,6 +138,33 @@ static int intel_wait_booting(struct hci |
| bt_dev_err(hu->hdev, "Device boot timeout"); |
| return -ETIMEDOUT; |
| } |
| +#else |
| + if (test_bit(STATE_BOOTING, &intel->flags)) { |
| + DECLARE_WAITQUEUE(wait, current); |
| + signed long timeout; |
| + |
| + add_wait_queue(&hu->hdev->req_wait_q, &wait); |
| + set_current_state(TASK_INTERRUPTIBLE); |
| + |
| + /* Booting into operational firmware should not take |
| + * longer than 1 second. However if that happens, then |
| + * just fail the setup since something went wrong. |
| + */ |
| + timeout = schedule_timeout(msecs_to_jiffies(1000)); |
| + |
| + remove_wait_queue(&hu->hdev->req_wait_q, &wait); |
| + |
| + if (signal_pending(current)) { |
| + BT_ERR("%s: Device boot interrupted", hu->hdev->name); |
| + return -EINTR; |
| + } |
| + |
| + if (!timeout) { |
| + BT_ERR("%s: Device boot timeout", hu->hdev->name); |
| + return -ETIMEDOUT; |
| + } |
| + } |
| +#endif |
| |
| return err; |
| } |
| @@ -145,8 +173,9 @@ static int intel_wait_booting(struct hci |
| static int intel_wait_lpm_transaction(struct hci_uart *hu) |
| { |
| struct intel_data *intel = hu->priv; |
| - int err; |
| + int err = 0; |
| |
| +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) |
| err = wait_on_bit_timeout(&intel->flags, STATE_LPM_TRANSACTION, |
| TASK_INTERRUPTIBLE, |
| msecs_to_jiffies(1000)); |
| @@ -160,6 +189,29 @@ static int intel_wait_lpm_transaction(st |
| bt_dev_err(hu->hdev, "LPM transaction timeout"); |
| return -ETIMEDOUT; |
| } |
| +#else |
| + if (test_bit(STATE_LPM_TRANSACTION, &intel->flags)) { |
| + DECLARE_WAITQUEUE(wait, current); |
| + signed long timeout; |
| + |
| + add_wait_queue(&hu->hdev->req_wait_q, &wait); |
| + set_current_state(TASK_INTERRUPTIBLE); |
| + |
| + timeout = schedule_timeout(msecs_to_jiffies(1000)); |
| + |
| + remove_wait_queue(&hu->hdev->req_wait_q, &wait); |
| + |
| + if (signal_pending(current)) { |
| + BT_ERR("%s: LPM transaction interrupted", hu->hdev->name); |
| + return -EINTR; |
| + } |
| + |
| + if (!timeout) { |
| + BT_ERR("%s: LPM transaction timeout", hu->hdev->name); |
| + return -ETIMEDOUT; |
| + } |
| + } |
| +#endif |
| |
| return err; |
| } |
| @@ -812,6 +864,7 @@ static int intel_setup(struct hci_uart * |
| * and thus just timeout if that happens and fail the setup |
| * of this device. |
| */ |
| +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) |
| err = wait_on_bit_timeout(&intel->flags, STATE_DOWNLOADING, |
| TASK_INTERRUPTIBLE, |
| msecs_to_jiffies(5000)); |
| @@ -826,6 +879,33 @@ static int intel_setup(struct hci_uart * |
| err = -ETIMEDOUT; |
| goto done; |
| } |
| +#else |
| + if (test_bit(STATE_DOWNLOADING, &intel->flags)) { |
| + DECLARE_WAITQUEUE(wait, current); |
| + signed long timeout; |
| + |
| + add_wait_queue(&hdev->req_wait_q, &wait); |
| + set_current_state(TASK_INTERRUPTIBLE); |
| + |
| + /* Booting into operational firmware should not take |
| + * longer than 1 second. However if that happens, then |
| + * just fail the setup since something went wrong. |
| + */ |
| + timeout = schedule_timeout(msecs_to_jiffies(5000)); |
| + |
| + remove_wait_queue(&hdev->req_wait_q, &wait); |
| + |
| + if (signal_pending(current)) { |
| + BT_ERR("%s: Firmware loading interrupted", hdev->name); |
| + return -EINTR; |
| + } |
| + |
| + if (!timeout) { |
| + BT_ERR("%s: Firmware loading timeout", hdev->name); |
| + return -ETIMEDOUT; |
| + } |
| + } |
| +#endif |
| |
| if (test_bit(STATE_FIRMWARE_FAILED, &intel->flags)) { |
| bt_dev_err(hdev, "Firmware loading failed"); |
| @@ -957,8 +1037,12 @@ static int intel_recv_event(struct hci_d |
| |
| if (test_and_clear_bit(STATE_DOWNLOADING, &intel->flags) && |
| test_bit(STATE_FIRMWARE_LOADED, &intel->flags)) { |
| +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) |
| smp_mb__after_atomic(); |
| wake_up_bit(&intel->flags, STATE_DOWNLOADING); |
| +#else |
| + wake_up_interruptible(&hu->hdev->req_wait_q); |
| +#endif |
| } |
| |
| /* When switching to the operational firmware the device |
| @@ -968,8 +1052,12 @@ static int intel_recv_event(struct hci_d |
| } else if (skb->len == 9 && hdr->evt == 0xff && hdr->plen == 0x07 && |
| skb->data[2] == 0x02) { |
| if (test_and_clear_bit(STATE_BOOTING, &intel->flags)) { |
| +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) |
| smp_mb__after_atomic(); |
| wake_up_bit(&intel->flags, STATE_BOOTING); |
| +#else |
| + wake_up_interruptible(&hu->hdev->req_wait_q); |
| +#endif |
| } |
| } |
| recv: |
| @@ -1008,15 +1096,23 @@ static int intel_recv_lpm(struct hci_dev |
| case LPM_OP_SUSPEND_ACK: |
| set_bit(STATE_SUSPENDED, &intel->flags); |
| if (test_and_clear_bit(STATE_LPM_TRANSACTION, &intel->flags)) { |
| +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) |
| smp_mb__after_atomic(); |
| wake_up_bit(&intel->flags, STATE_LPM_TRANSACTION); |
| +#else |
| + wake_up_interruptible(&hu->hdev->req_wait_q); |
| +#endif |
| } |
| break; |
| case LPM_OP_RESUME_ACK: |
| clear_bit(STATE_SUSPENDED, &intel->flags); |
| if (test_and_clear_bit(STATE_LPM_TRANSACTION, &intel->flags)) { |
| +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) |
| smp_mb__after_atomic(); |
| wake_up_bit(&intel->flags, STATE_LPM_TRANSACTION); |
| +#else |
| + wake_up_interruptible(&hu->hdev->req_wait_q); |
| +#endif |
| } |
| break; |
| default: |