From: Jose Vasconcellos <jose@vasmac.com>
To: BlueZ development <bluez-devel@lists.sourceforge.net>
Subject: Re: [Bluez-devel] [PATCH]Dynamic Alternate Setting patch (hci_usb.c)
Date: Tue, 24 Apr 2007 07:15:39 -0600 [thread overview]
Message-ID: <462E02FB.8000600@vasmac.com> (raw)
In-Reply-To: <fc27e74b0704240413v5b6e2e80h7b2feb40d27de686@mail.gmail.com>
Hi Alok,
This is a good start. There are a few other things to consider:
* Are there error conditions in hci_usb_tx_complete that need to be handled?
* How do you make sure data for different channels is interleaved?
Jose
list subscribe wrote:
> Hi,
>
> As per the discussion on #bluez channel , I am attaching a patch which
> dynamically manages the the alternate settings for SCO channels.
> The patch includes the following :
>
> 1. It declares a work queue(config_work), which is scheduled when
> 1. There is a change in number of SCO channels OR
> 2. There is a change in the Voice setting.
>
> 2. On invocation it determines the alternate setting based on the
> table given in HCI - usb spec docs. The table is also mentioned in
> the patch.
>
> 3. It then empties all the queued isochronous URBs , except those
> which are already submitted.
>
> 4. It then sets the alternate setting by calling usb_set_interface().
>
> I have tested this patch using "scotest".
> I am using 2.6.21-rc7 with sco-flowcontrol-v4.2.diff patch.
>
> Let me know if any changes are necessary.
> Any suggestions are welcome.
>
>
>
> Alok.
>
>
> --- hci_usb.c.orig 2007-04-16 19:37:41.000000000 +0530
> +++ hci_usb.c 2007-04-24 01:41:31.000000000 +0530
> @@ -47,6 +47,8 @@
>
> #include <linux/usb.h>
>
> +#include <linux/workqueue.h>
> +
> #include <net/bluetooth/bluetooth.h>
> #include <net/bluetooth/hci_core.h>
>
> @@ -57,6 +59,21 @@
> #define BT_DBG(D...)
> #endif
>
> +/* The number of SCO channels */
> +int NoSco=0;
> +/* The Voice setting */
> +__u16 VocSetting=0;
> +/* if bit=0,its 8bit encoding else its 16bit */
> +__u16 bit = 0x20;
> +
> +struct hci_usb *hUSB;
> +struct usb_device *usbdevice;
> +struct usb_interface *isocIface;
> +/* The Workque Function */
> +static void set_alternate_config(struct work_struct *work);
> +static DECLARE_WORK(config_work, set_alternate_config);
> +
> +
> #ifndef CONFIG_BT_HCIUSB_ZERO_PACKET
> #undef URB_ZERO_PACKET
> #define URB_ZERO_PACKET 0
> @@ -840,6 +857,10 @@
> static void hci_usb_notify(struct hci_dev *hdev, unsigned int evt)
> {
> BT_DBG("%s evt %d", hdev->name, evt);
> + NoSco = hdev->conn_hash.sco_num;
> + VocSetting = hdev->voice_setting;
> + hUSB = (struct hci_usb *) hdev->driver_data;
> + schedule_work(&config_work);
> }
>
> static int hci_usb_probe(struct usb_interface *intf, const struct
> usb_device_id *id)
> @@ -854,7 +875,7 @@
> struct hci_usb *husb;
> struct hci_dev *hdev;
> int i, e, size, isoc_ifnum, isoc_alts;
> -
> + usbdevice = interface_to_usbdev(intf);
> BT_DBG("udev %p intf %p", udev, intf);
>
> if (!id->driver_info) {
> @@ -926,9 +947,11 @@
> isoc_ifnum = 1;
>
> #ifdef CONFIG_BT_HCIUSB_SCO
> - if (isoc && !(id->driver_info & (HCI_BROKEN_ISOC | HCI_SNIFFER)))
> + if (isoc && !(id->driver_info & (HCI_BROKEN_ISOC | HCI_SNIFFER))){
> isoc_iface = usb_ifnum_to_if(udev, isoc_ifnum);
> -
> + isocIface = usb_ifnum_to_if(udev, isoc_ifnum);
> + }
> +
> if (isoc_iface) {
> int a;
> struct usb_host_endpoint *isoc_out_ep = NULL;
> @@ -1142,6 +1165,121 @@
> return 0;
> }
>
> +
> +/*Set the alternate setting based on the number of SCO channels and the
> + voice setting.This function is invoked when there is a change in
> Number of
> + SCO channels or when the voice encoding changes.*/
> +static void set_alternate_config(struct work_struct *work)
> +{
> + int isocIfnum=1, isocAlt=0;
> + struct usb_host_endpoint *ep;
> + struct usb_host_interface *uif;
> + struct _urb *_urb,*_tmp;
> + struct _urb_queue *q = &hUSB->pending_q[isoc];
> + unsigned long flags;
> + atomic_t temp;/*Holds the number of URBs we need to skip(which
> are submitted)*/
> + struct list_head inprocess;/*This list holds the already
> submitted URBs */
> +
> + /*Change the alternate setting only if the number of SCO channels
> are more than 1 */
> + if(NoSco > 0){
> + /* The alternate setting selection is based on the following
> table */
> + /* No. of SCO channels Bit-Encoding Alternate
> Setting Max. Packet Size */
> + /* 1 8bit
> 1 9 */
> + /* 1 16bit
> 2 17 */
> + /* 2 8bit
> 2 17 */
> + /* 2 16bit
> 4 33 */
> + /* 3 8bit
> 3 25 */
> + /* 3 16bit
> 5 49 */
> + switch(NoSco)
> + {
> + case 1:
> + if(VocSetting && bit)
> + isocAlt=2;
> + else
> + isocAlt=1;
> + break;
> + case 2:
> + if(VocSetting && bit)
> + isocAlt=4;
> + else
> + isocAlt=2;
> + break;
> + case 3:
> + if(VocSetting && bit)
> + isocAlt=5;
> + else
> + isocAlt=3;
> + break;
> + }
> +
> + /*Stop Current TX */
> + clear_bit(HCI_USB_TX_WAKEUP, &hUSB->state);
> + INIT_LIST_HEAD(&inprocess);
> + temp = hUSB->pending_tx[isoc];
> + /* We cannot purge URBs which have been submitted. inprocess
> is a */
> + /* temporary list which holds the currently submitted URBs. */
> + /* This list is later merged with the emptyed pending queue. */
> +
> + while ((_urb = _urb_dequeue(q))) {
> + /*Dequeue all the submitted URBs and put them in the
> temporary list*/
> + if(!atomic_dec_and_test(&temp)){
> + _urb->queue = q;
> + list_add(&_urb->list, &inprocess);
> + }
> + else{
> + /*Unlink all the rest of URBs and put them into the
> completed queue.*/
> + _urb_unlink(_urb);
> + _urb_queue_tail(__completed_q(hUSB,HCI_SCODATA_PKT),
> _urb);
> + }
> + }
> + /*merge the inprocess queue with the pending queue*/
> + spin_lock_irqsave(&q->lock, flags);
> + list_for_each_entry_safe(_urb, _tmp, &inprocess, list) {
> + list_move_tail(&_urb->list, &q->head);
> + }
> + spin_unlock_irqrestore(&q->lock, flags);
> +
> + /* Set the setting and the in/out endpoints */
> + if (isocIface) {
> + int e;
> + struct usb_host_endpoint *out = NULL;
> + struct usb_host_endpoint *in = NULL;
> + uif = &isocIface->altsetting[isocAlt];
> + for (e = 0; e < uif->desc.bNumEndpoints; e++) {
> + ep = &uif->endpoint[e];
> + switch (ep->desc.bmAttributes &
> USB_ENDPOINT_XFERTYPE_MASK) {
> + case USB_ENDPOINT_XFER_ISOC:
> + if (ep->desc.bEndpointAddress & USB_DIR_IN)
> + in = ep;
> + else
> + out = ep;
> + break;
> + }
> + }
> +
> + if (!in || !out)
> + BT_DBG("Isoc endpoints not found");
> + else {
> + BT_DBG("isoc ifnum %d alts %d", isocIfnum, isocAlt);
> + if (usb_set_interface(usbdevice, isocIfnum, isocAlt)) {
> + BT_ERR("Can't set isoc interface settings");
> + hUSB->isoc_iface = isocIface;
> + usb_driver_release_interface(&hci_usb_driver,
> isocIface);
> + hUSB->isoc_iface = NULL;
> + } else {
> + hUSB->isoc_iface = isocIface;
> + hUSB->isoc_in_ep = in;
> + hUSB->isoc_out_ep = out;
> + }
> + }
> + }
> + set_bit(HCI_USB_TX_WAKEUP, &hUSB->state);
> + }
> +
> +}
> +
> +
> +
> static struct usb_driver hci_usb_driver = {
> .name = "hci_usb",
> .probe = hci_usb_probe,
> ------------------------------------------------------------------------
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel
next prev parent reply other threads:[~2007-04-24 13:15 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-04-24 11:13 [Bluez-devel] [PATCH]Dynamic Alternate Setting patch (hci_usb.c) list subscribe
2007-04-24 13:15 ` Jose Vasconcellos [this message]
2007-04-24 15:08 ` list subscribe
2007-04-24 15:27 ` Jose Vasconcellos
2007-04-24 16:06 ` Marcel Holtmann
2007-04-24 16:13 ` alok
2007-04-24 17:08 ` Jose Vasconcellos
2007-04-24 18:38 ` Marcel Holtmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=462E02FB.8000600@vasmac.com \
--to=jose@vasmac.com \
--cc=bluez-devel@lists.sourceforge.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.