lkml.org 
[lkml]   [2006]   [Jan]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    SubjectRe: [PATCH] hci_usb: implement suspend/resume
    From
    Date
    The attached patch implements suspend/resume for the hci_usb bluetooth
    driver by simply killing all outstanding urbs on suspend, and re-issuing
    them on resume.

    This allows me to actually use the internal bluetooth "dongle" in my
    powerbook after suspend-to-ram without taking down all userland programs
    (sdpd, ...) and the hci device and reloading the module.

    Signed-Off-By: Johannes Berg <johannes@sipsolutions.net>

    --- linux-2.6.git.orig/drivers/bluetooth/hci_usb.c
    +++ linux-2.6.git/drivers/bluetooth/hci_usb.c
    @@ -1043,10 +1043,65 @@
    hci_free_dev(hdev);
    }

    +static int hci_usb_suspend(struct usb_interface *intf, pm_message_t message)
    +{
    + struct hci_usb *husb = usb_get_intfdata(intf);
    + int i;
    + unsigned long flags;
    + struct list_head killed;
    +
    + if (!husb || intf == husb->isoc_iface)
    + return 0;
    +
    + INIT_LIST_HEAD(&killed);
    +
    + for (i = 0; i < 4; i++) {
    + struct _urb_queue *q = &husb->pending_q[i];
    + struct _urb *_urb, *_tmp;
    + while ((_urb = _urb_dequeue(q))) {
    + /* reset queue since _urb_dequeue sets it to NULL */
    + _urb->queue = q;
    + usb_kill_urb(&_urb->urb);
    + list_add(&_urb->list, &killed);
    + }
    + spin_lock_irqsave(&q->lock, flags);
    + list_for_each_entry_safe(_urb, _tmp, &killed, list) {
    + list_move_tail(&_urb->list, &q->head);
    + }
    + spin_unlock_irqrestore(&q->lock, flags);
    + }
    + return 0;
    +}
    +
    +static int hci_usb_resume(struct usb_interface *intf)
    +{
    + struct hci_usb *husb = usb_get_intfdata(intf);
    + int i, err = 0;
    + unsigned long flags;
    + if (!husb || intf == husb->isoc_iface)
    + return 0;
    +
    + for (i = 0; i < 4; i++) {
    + struct _urb_queue *q = &husb->pending_q[i];
    + struct _urb *_urb;
    + spin_lock_irqsave(&q->lock, flags);
    + list_for_each_entry(_urb, &q->head, list) {
    + err = usb_submit_urb(&_urb->urb, GFP_ATOMIC);
    + if (err) break;
    + }
    + spin_unlock_irqrestore(&q->lock, flags);
    + if (err)
    + return -EIO;
    + }
    + return 0;
    +}
    +
    static struct usb_driver hci_usb_driver = {
    .name = "hci_usb",
    .probe = hci_usb_probe,
    .disconnect = hci_usb_disconnect,
    + .suspend = hci_usb_suspend,
    + .resume = hci_usb_resume,
    .id_table = bluetooth_ids,
    };


    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2006-01-18 19:42    [W:0.022 / U:5.040 seconds]
    ©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site