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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox