From: Alok <develnewbie@gmail.com>
To: BlueZ development <bluez-devel@lists.sourceforge.net>
Subject: Re: [Bluez-devel] Handling simultaneous SCO connections: Does BlueZhave multiple SCO buffers?
Date: Thu, 12 Jul 2007 14:57:13 +0530 [thread overview]
Message-ID: <1184232433.6210.12.camel@localhost> (raw)
In-Reply-To: <1184227287.5997.2.camel@Epimenides>
[-- Attachment #1: Type: text/plain, Size: 1663 bytes --]
On Thu, 2007-07-12 at 04:01 -0400, George Hansel wrote:
> On Thu, 2007-07-12 at 06:58 +0200, Niels v/d Spek wrote:
> > Brad Midgley wrote:
> > > George
> > >
> > > bluetooth adapters that are connected by usb need to have a kernel mod
> > > to allow the alternate setting to be changed dynamically. There's an
> > > experimental patch out there:
> > >
> > > http://article.gmane.org/gmane.linux.bluez.devel/11999
> > >
> > > the patch also assumes you have the flowcontrol patch applied first:
> > >
> > > http://bluetooth-alsa.cvs.sourceforge.net/bluetooth-alsa/plugz/patches/sco-flowcontrol-v4.2.diff?view=log
> > >
> > Brad,
> >
> > I'm using Ubuntu 7.4 and like to know of this patches are there also needed?
> >
> > thanks anyway
> >
> > Niels
> > > Brad
> > >
> > > -------------------------------------------------------------------------
>
> Neils,
>
> I am also using Ubuntu 7.04 (latest patches, etc). As it turned out, I
> created a workaround for my problem, not using the patches. Depending
> on your application, you will need them as well. The Bluetooth stack
> is developed independently, but is incorporated into the Linux kernel,
> and so should be quite uniform throughout different distributions.
>
> George
Hi,
If you want to use multiple SCO connections (and your adapter is
connected through USB )you need the alternate setting patch along with
the sco-flowcontrol patch.
Brad, There are some changes in that patch , I am attaching the latest
one.
There can be some issues which i might have missed, will test it out and
send a final patch soon.
Thanks to Whoopie for testing the new patch .
Thanks,
Alok Barsode.
[-- Attachment #2: alternate-setting.patch --]
[-- Type: text/x-patch, Size: 5978 bytes --]
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index 406af57..03b362e 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -837,11 +837,112 @@ static void hci_usb_destruct(struct hci_dev *hdev)
kfree(husb);
}
+#ifdef CONFIG_BT_HCIUSB_SCO
static void hci_usb_notify(struct hci_dev *hdev, unsigned int evt)
{
+ struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
+ unsigned long flags;
+ int new_alts;
+
BT_DBG("%s evt %d", hdev->name, evt);
+ new_alts = hdev->conn_hash.sco_num;
+
+ if(hdev->voice_setting & 0x0020){
+ new_alts *= 2;
+ if(new_alts > 5)
+ new_alts = 5;
+ }
+
+ write_lock_irqsave(&husb->completion_lock, flags);
+
+ if(new_alts != husb->curr_isoc_alts){
+ husb->new_isoc_alts = new_alts;
+ schedule_work(&husb->work);
+ }
+
+ write_unlock_irqrestore(&husb->completion_lock, flags);
+
}
+static void set_isoc_alternate(struct work_struct *work)
+{
+ struct hci_usb *husb = container_of(work, struct hci_usb, work);
+ struct _urb *_urb, *_tmp;
+ struct _urb_queue *q = &husb->pending_q[isoc];
+ /*This list holds the already submitted URBs */
+ struct list_head inprocess;
+ unsigned long flags;
+ /*Holds the number of URBs we need to skip(which are submitted) */
+ atomic_t temp;
+ int isoc_ifnum=1,e;
+
+ struct usb_interface *isocIface;
+ struct usb_host_endpoint *ep;
+ struct usb_host_interface *uif;
+ struct usb_host_endpoint *out = NULL;
+ struct usb_host_endpoint *in = NULL;
+
+ INIT_LIST_HEAD(&inprocess);
+ temp = husb->pending_tx[isoc];
+
+ 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);
+ clear_bit(HCI_USB_TX_WAKEUP, &husb->state);
+ isocIface = usb_ifnum_to_if(husb->udev, isoc_ifnum);
+
+ /* Set the setting and the in/out endpoints */
+ if (isocIface) {
+ uif = &isocIface->altsetting[husb->new_isoc_alts];
+ 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", isoc_ifnum, husb->new_isoc_alts);
+
+ if (usb_set_interface(husb->udev, isoc_ifnum, husb->new_isoc_alts)) {
+ BT_ERR("Can't set isoc interface settings");
+ husb->isoc_iface = isocIface;
+ usb_driver_release_interface(&hci_usb_driver,husb->isoc_iface);
+ husb->isoc_iface = NULL;
+ } else {
+ husb->isoc_iface = isocIface;
+ husb->isoc_in_ep = in;
+ husb->isoc_out_ep = out;
+ husb->curr_isoc_alts = husb->new_isoc_alts;
+ }
+ }
+ }
+
+ set_bit(HCI_USB_TX_WAKEUP, &husb->state);
+}
+#endif
+
static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(intf);
@@ -853,7 +954,7 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
struct usb_interface *isoc_iface;
struct hci_usb *husb;
struct hci_dev *hdev;
- int i, e, size, isoc_ifnum, isoc_alts;
+ int i, e, size, isoc_ifnum;
BT_DBG("udev %p intf %p", udev, intf);
@@ -922,7 +1023,7 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
/* Find isochronous endpoints that we can use */
size = 0;
isoc_iface = NULL;
- isoc_alts = 0;
+ husb->curr_isoc_alts = 0;
isoc_ifnum = 1;
#ifdef CONFIG_BT_HCIUSB_SCO
@@ -946,7 +1047,7 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
break;
size = le16_to_cpu(ep->desc.wMaxPacketSize);
- isoc_alts = uif->desc.bAlternateSetting;
+ husb->curr_isoc_alts = uif->desc.bAlternateSetting;
if (ep->desc.bEndpointAddress & USB_DIR_IN)
isoc_in_ep = ep;
@@ -960,10 +1061,10 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
if (!isoc_in_ep || !isoc_out_ep)
BT_DBG("Isoc endpoints not found");
else {
- BT_DBG("isoc ifnum %d alts %d", isoc_ifnum, isoc_alts);
+ BT_DBG("isoc ifnum %d alts %d", isoc_ifnum, husb->curr_isoc_alts);
if (usb_driver_claim_interface(&hci_usb_driver, isoc_iface, husb) != 0)
BT_ERR("Can't claim isoc interface");
- else if (usb_set_interface(udev, isoc_ifnum, isoc_alts)) {
+ else if (usb_set_interface(udev, isoc_ifnum, husb->curr_isoc_alts)) {
BT_ERR("Can't set isoc interface settings");
husb->isoc_iface = isoc_iface;
usb_driver_release_interface(&hci_usb_driver, isoc_iface);
@@ -975,6 +1076,7 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
}
}
}
+ INIT_WORK(&husb->work,set_isoc_alternate);
#endif
rwlock_init(&husb->completion_lock);
diff --git a/drivers/bluetooth/hci_usb.h b/drivers/bluetooth/hci_usb.h
index 963fc55..c9fbf0e 100644
--- a/drivers/bluetooth/hci_usb.h
+++ b/drivers/bluetooth/hci_usb.h
@@ -108,11 +108,14 @@ struct hci_usb {
struct usb_host_endpoint *bulk_in_ep;
struct usb_host_endpoint *bulk_out_ep;
struct usb_host_endpoint *intr_in_ep;
-
+#ifdef CONFIG_BT_HCIUSB_SCO
struct usb_interface *isoc_iface;
struct usb_host_endpoint *isoc_out_ep;
struct usb_host_endpoint *isoc_in_ep;
-
+ struct work_struct work;
+ int curr_isoc_alts;
+ int new_isoc_alts;
+#endif
__u8 ctrl_req;
struct sk_buff_head transmit_q[4];
[-- Attachment #3: Type: text/plain, Size: 286 bytes --]
-------------------------------------------------------------------------
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/
[-- Attachment #4: Type: text/plain, Size: 164 bytes --]
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel
prev parent reply other threads:[~2007-07-12 9:27 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-07-11 18:30 [Bluez-devel] Handling simultaneous SCO connections: Does BlueZ have multiple SCO buffers? George Hansel
2007-07-11 20:02 ` Brad Midgley
2007-07-12 4:58 ` [Bluez-devel] Handling simultaneous SCO connections: Does BlueZhave " Niels v/d Spek
2007-07-12 8:01 ` George Hansel
2007-07-12 9:27 ` Alok [this message]
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=1184232433.6210.12.camel@localhost \
--to=develnewbie@gmail.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.