Linux bluetooth development
 help / color / mirror / Atom feed
* [Bluez-devel] Modified patch (Dynamic Alternate Setting)
@ 2007-04-25 21:24 list subscribe
  2007-04-25 22:04 ` Marcel Holtmann
  0 siblings, 1 reply; 5+ messages in thread
From: list subscribe @ 2007-04-25 21:24 UTC (permalink / raw)
  To: BlueZ development

[-- Attachment #1: Type: text/plain, Size: 90 bytes --]

Marcel,

I have made the changes u suggested.
Take a look and let me know.

Thanks,
Alok.

[-- Attachment #2: alternate-setting-patch --]
[-- Type: application/octet-stream, Size: 5700 bytes --]

diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index 406af57..3742ab7 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -56,6 +56,8 @@
 #undef  BT_DBG
 #define BT_DBG(D...)
 #endif
+/* The Workque Function */
+static void set_alternate_config(struct work_struct *work);
 
 #ifndef CONFIG_BT_HCIUSB_ZERO_PACKET
 #undef  URB_ZERO_PACKET
@@ -840,6 +842,7 @@ static void hci_usb_destruct(struct hci_dev *hdev)
 static void hci_usb_notify(struct hci_dev *hdev, unsigned int evt)
 {
 	BT_DBG("%s evt %d", hdev->name, evt);
+	schedule_work(&hdev->setting_work);
 }
 
 static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -1007,6 +1010,7 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
 
 	hdev->owner = THIS_MODULE;
 
+    INIT_WORK(&hdev->setting_work,set_alternate_config);
 	if (reset || id->driver_info & HCI_RESET)
 		set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
 
@@ -1142,6 +1146,128 @@ static int hci_usb_resume(struct usb_interface *intf)
 	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)
+{
+
+  struct hci_dev *hdev = container_of(work, struct hci_dev, setting_work);
+  struct hci_usb *hUSB = (struct hci_usb *) hdev->driver_data;
+  
+/* if bit=0,its 8bit encoding else its 16bit */
+__u16 bit = 0x20;
+struct usb_interface *isocIface;
+  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(hdev->conn_hash.sco_num > 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(hdev->conn_hash.sco_num)
+		{
+		case 1:
+			if(hdev->voice_setting && bit)
+				isocAlt=2;
+			else
+				isocAlt=1;
+			break;
+		case 2:
+			if(hdev->voice_setting && bit)
+				isocAlt=4;
+			else
+				isocAlt=2;
+			break;
+		case 3:
+			if(hdev->voice_setting && 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);
+		isocIface = usb_ifnum_to_if(hUSB->udev, isocIfnum);
+		/* 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(hUSB->udev,isocIfnum, isocAlt)) {
+					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;
+				}
+			}
+		}
+		set_bit(HCI_USB_TX_WAKEUP, &hUSB->state);
+	}
+
+}
+  
+
+
 static struct usb_driver hci_usb_driver = {
 	.name		= "hci_usb",
 	.probe		= hci_usb_probe,
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 8a57b7d..f060288 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -110,6 +110,7 @@ struct hci_dev {
 	struct sk_buff_head	raw_q;
 	struct sk_buff_head	cmd_q;
 
+        struct work_struct      setting_work;
 	struct sk_buff		*sent_cmd;
 
 	struct semaphore	req_lock;

[-- 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

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [Bluez-devel] Modified patch (Dynamic Alternate Setting)
  2007-04-25 21:24 [Bluez-devel] Modified patch (Dynamic Alternate Setting) list subscribe
@ 2007-04-25 22:04 ` Marcel Holtmann
  2007-04-27 19:40   ` Marcel Holtmann
  0 siblings, 1 reply; 5+ messages in thread
From: Marcel Holtmann @ 2007-04-25 22:04 UTC (permalink / raw)
  To: BlueZ development

Hi,

> I have made the changes u suggested.
> Take a look and let me know.

please fix the coding style of your additions. This patch is unreadable
in this state. No forward declarations and no heavy nesting.

Regards

Marcel



-------------------------------------------------------------------------
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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Bluez-devel] Modified patch (Dynamic Alternate Setting)
  2007-04-25 22:04 ` Marcel Holtmann
@ 2007-04-27 19:40   ` Marcel Holtmann
  2007-04-27 20:10     ` Marcel Holtmann
  0 siblings, 1 reply; 5+ messages in thread
From: Marcel Holtmann @ 2007-04-27 19:40 UTC (permalink / raw)
  To: BlueZ development

[-- Attachment #1: Type: text/plain, Size: 412 bytes --]

Hi,

> > I have made the changes u suggested.
> > Take a look and let me know.
> 
> please fix the coding style of your additions. This patch is unreadable
> in this state. No forward declarations and no heavy nesting.

the following patch follows more my understanding how this should look
like. However the attached patch doesn't contain the code for stopping
and resubmitting the ISOC URBs.

Regards

Marcel


[-- Attachment #2: patch --]
[-- Type: text/x-patch, Size: 2529 bytes --]

diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index 406af57..b668476 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -839,7 +839,41 @@ static void hci_usb_destruct(struct hci_dev *hdev)
 
 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->isoc_alts) {
+		husb->pend_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);
+
+	write_lock(&husb->completion_lock);
+
+	usb_set_interface(husb->udev, husb->isoc_ifnum, husb->pend_alts);
+
+	husb->isoc_alts = husb->pend_alts;
+
+	write_unlock(&husb->completion_lock);
 }
 
 static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -974,6 +1008,11 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
 				husb->isoc_out_ep = isoc_out_ep;
 			}
 		}
+
+		husb->isoc_ifnum = isoc_ifnum;
+		husb->isoc_alts  = 0;
+
+		usb_set_interface(udev, isoc_ifnum, husb->isoc_alts);
 	}
 #endif
 
@@ -994,6 +1033,8 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
 
 	husb->hdev = hdev;
 
+	INIT_WORK(&husb->work, set_isoc_alternate);
+
 	hdev->type = HCI_USB;
 	hdev->driver_data = husb;
 	SET_HCIDEV_DEV(hdev, &intf->dev);
diff --git a/drivers/bluetooth/hci_usb.h b/drivers/bluetooth/hci_usb.h
index 963fc55..f1a7934 100644
--- a/drivers/bluetooth/hci_usb.h
+++ b/drivers/bluetooth/hci_usb.h
@@ -102,9 +102,9 @@ struct hci_usb {
 	struct hci_dev		*hdev;
 
 	unsigned long		state;
-	
+
 	struct usb_device	*udev;
-	
+
 	struct usb_host_endpoint	*bulk_in_ep;
 	struct usb_host_endpoint	*bulk_out_ep;
 	struct usb_host_endpoint	*intr_in_ep;
@@ -113,8 +113,14 @@ struct hci_usb {
 	struct usb_host_endpoint	*isoc_out_ep;
 	struct usb_host_endpoint	*isoc_in_ep;
 
+	int				isoc_ifnum;
+	int				isoc_alts;
+	int				pend_alts;
+
 	__u8			ctrl_req;
 
+	struct work_struct	work;
+
 	struct sk_buff_head	transmit_q[4];
 	struct sk_buff		*reassembly[4];		/* Reassembly buffers */
 

[-- 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

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [Bluez-devel] Modified patch (Dynamic Alternate Setting)
  2007-04-27 19:40   ` Marcel Holtmann
@ 2007-04-27 20:10     ` Marcel Holtmann
  2007-05-03 21:17       ` list subscribe
  0 siblings, 1 reply; 5+ messages in thread
From: Marcel Holtmann @ 2007-04-27 20:10 UTC (permalink / raw)
  To: BlueZ development

[-- Attachment #1: Type: text/plain, Size: 521 bytes --]

Hi,

> > > I have made the changes u suggested.
> > > Take a look and let me know.
> > 
> > please fix the coding style of your additions. This patch is unreadable
> > in this state. No forward declarations and no heavy nesting.
> 
> the following patch follows more my understanding how this should look
> like. However the attached patch doesn't contain the code for stopping
> and resubmitting the ISOC URBs.

attached is a revised patch that improves the case where
CONFIG_BT_HCIUSB_SCO is not set.

Regards

Marcel


[-- Attachment #2: patch --]
[-- Type: text/x-patch, Size: 2471 bytes --]

diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index 406af57..0727f68 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -837,10 +837,50 @@ 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->isoc_alts) {
+		husb->pend_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);
+
+	write_lock(&husb->completion_lock);
+
+	usb_set_interface(husb->udev, husb->isoc_ifnum, husb->pend_alts);
+
+	husb->isoc_alts = husb->pend_alts;
+
+	write_unlock(&husb->completion_lock);
+}
+#else
+static void hci_usb_notify(struct hci_dev *hdev, unsigned int evt)
+{
 }
+#endif
 
 static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
@@ -974,7 +1014,14 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
 				husb->isoc_out_ep = isoc_out_ep;
 			}
 		}
+
+		husb->isoc_ifnum = isoc_ifnum;
+		husb->isoc_alts  = 0;
+
+		usb_set_interface(udev, isoc_ifnum, husb->isoc_alts);
 	}
+
+	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..fbe0954 100644
--- a/drivers/bluetooth/hci_usb.h
+++ b/drivers/bluetooth/hci_usb.h
@@ -102,17 +102,26 @@ struct hci_usb {
 	struct hci_dev		*hdev;
 
 	unsigned long		state;
-	
+
 	struct usb_device	*udev;
-	
+
 	struct usb_host_endpoint	*bulk_in_ep;
 	struct usb_host_endpoint	*bulk_out_ep;
 	struct usb_host_endpoint	*intr_in_ep;
 
 	struct usb_interface		*isoc_iface;
+
+#ifdef CONFIG_BT_HCIUSB_SCO
 	struct usb_host_endpoint	*isoc_out_ep;
 	struct usb_host_endpoint	*isoc_in_ep;
 
+	int			isoc_ifnum;
+	int			isoc_alts;
+	int			pend_alts;
+
+	struct work_struct	work;
+#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

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [Bluez-devel] Modified patch (Dynamic Alternate Setting)
  2007-04-27 20:10     ` Marcel Holtmann
@ 2007-05-03 21:17       ` list subscribe
  0 siblings, 0 replies; 5+ messages in thread
From: list subscribe @ 2007-05-03 21:17 UTC (permalink / raw)
  To: BlueZ development

[-- Attachment #1: Type: text/plain, Size: 683 bytes --]

Marcel,

Added the urb  part  to your patch.
Take a look.

On 4/28/07, Marcel Holtmann <marcel@holtmann.org> wrote:
> Hi,
>
> > > > I have made the changes u suggested.
> > > > Take a look and let me know.
> > >
> > > please fix the coding style of your additions. This patch is unreadable
> > > in this state. No forward declarations and no heavy nesting.
> >
> > the following patch follows more my understanding how this should look
> > like. However the attached patch doesn't contain the code for stopping
> > and resubmitting the ISOC URBs.
>
> attached is a revised patch that improves the case where
> CONFIG_BT_HCIUSB_SCO is not set.
>
> Regards
>
> Marcel
>

Thanks,
Alok.

[-- Attachment #2: alternate-setting-patch --]
[-- Type: application/octet-stream, Size: 6052 bytes --]

diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index 406af57..9001d8d 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -837,11 +837,114 @@ 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];
+	
+	write_lock(&husb->completion_lock);
+
+	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", isocIfnum, 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);
+	write_unlock(&husb->completion_lock);
+}
+#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 +956,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 +1025,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 +1049,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 +1063,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 +1078,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

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2007-05-03 21:17 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-04-25 21:24 [Bluez-devel] Modified patch (Dynamic Alternate Setting) list subscribe
2007-04-25 22:04 ` Marcel Holtmann
2007-04-27 19:40   ` Marcel Holtmann
2007-04-27 20:10     ` Marcel Holtmann
2007-05-03 21:17       ` list subscribe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox