From dcd540873298c7feb50ec8aacde107f9aca04a0a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 30 Nov 2008 12:17:14 +0100 Subject: [PATCH] --- yaml --- r: 122415 b: refs/heads/master c: 6a88adf2adf5d6a3b759c2e114da4c5266ca3972 h: refs/heads/master i: 122413: 885a7ec98b511e6c9021d5b4f74f620a97db6751 122411: c80ff32a9931471c9abba1a2afff6c25a1edc64b 122407: 8b68b19998aa5365669694dfb24b5259ed465b89 122399: 23c11ed0bd72531f095576c9c363a43ca2cb2567 v: v3 --- [refs] | 2 +- trunk/drivers/bluetooth/btusb.c | 62 +++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index f746a28bc864..ef63ed809201 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: a780efa8124fe7ef23d8ef844d56afe960356615 +refs/heads/master: 6a88adf2adf5d6a3b759c2e114da4c5266ca3972 diff --git a/trunk/drivers/bluetooth/btusb.c b/trunk/drivers/bluetooth/btusb.c index 9ca95208fc24..0cd4a55dd5c4 100644 --- a/trunk/drivers/bluetooth/btusb.c +++ b/trunk/drivers/bluetooth/btusb.c @@ -198,6 +198,7 @@ struct btusb_data { struct usb_endpoint_descriptor *isoc_rx_ep; int isoc_altsetting; + int suspend_count; }; static void btusb_intr_complete(struct urb *urb) @@ -948,10 +949,71 @@ static void btusb_disconnect(struct usb_interface *intf) hci_free_dev(hdev); } +static int btusb_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct btusb_data *data = usb_get_intfdata(intf); + + BT_DBG("intf %p", intf); + + if (data->suspend_count++) + return 0; + + cancel_work_sync(&data->work); + + usb_kill_anchored_urbs(&data->tx_anchor); + + usb_kill_anchored_urbs(&data->isoc_anchor); + usb_kill_anchored_urbs(&data->bulk_anchor); + usb_kill_anchored_urbs(&data->intr_anchor); + + return 0; +} + +static int btusb_resume(struct usb_interface *intf) +{ + struct btusb_data *data = usb_get_intfdata(intf); + struct hci_dev *hdev = data->hdev; + int err; + + BT_DBG("intf %p", intf); + + if (--data->suspend_count) + return 0; + + if (!test_bit(HCI_RUNNING, &hdev->flags)) + return 0; + + if (test_bit(BTUSB_INTR_RUNNING, &data->flags)) { + err = btusb_submit_intr_urb(hdev, GFP_NOIO); + if (err < 0) { + clear_bit(BTUSB_INTR_RUNNING, &data->flags); + return err; + } + } + + if (test_bit(BTUSB_BULK_RUNNING, &data->flags)) { + if (btusb_submit_bulk_urb(hdev, GFP_NOIO) < 0) + clear_bit(BTUSB_BULK_RUNNING, &data->flags); + else + btusb_submit_bulk_urb(hdev, GFP_NOIO); + } + + if (test_bit(BTUSB_ISOC_RUNNING, &data->flags)) { + if (btusb_submit_isoc_urb(hdev, GFP_NOIO) < 0) + clear_bit(BTUSB_ISOC_RUNNING, &data->flags); + else + btusb_submit_isoc_urb(hdev, GFP_NOIO); + } + + return 0; +} + static struct usb_driver btusb_driver = { .name = "btusb", .probe = btusb_probe, .disconnect = btusb_disconnect, + .suspend = btusb_suspend, + .resume = btusb_resume, .id_table = btusb_table, };