Skip to contentSkip to conversation

new sco flowcontrol patch

Bluez-devel Brad Midgley 2 participants 8 messages Mar 19, 2007 – Apr 3, 2007

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

Marcel

per our conversation about this, I have reworked the sco flowcontrol patch against the linus git tree (2.6.21rc2) and successfully tested it. Most of the comments are out so you can more easily see what is changing. I left about 3 comments in that are parts of new blocks of code.

I made a couple of changes like the signature of a function used as a fn pointer and avoiding a variable rename but this is essentially the same code people have been testing against older kernels.

It's also in bluetooth-alsa cvs under plugz/patches/

I used to have a testcase from Fabien that would consistently crash the unpatched kernel but I couldn't dig it up. That would be good for eg regression testing and I will put it in plugz cvs when we track it down.

Please give the patch a look.

Brad

include/net/bluetooth/hci.h +0 -0
include/net/bluetooth/hci_core.h +5 -3
index c0fc396..bd9be7a 100644
@@ -25,6 +25,8 @@
 #ifndef __HCI_CORE_H
 #define __HCI_CORE_H
 
+#include <linux/hrtimer.h>
+
 #include <net/bluetooth/hci.h>
 
 /* HCI upper protocols */
@@ -89,7 +91,7 @@ struct hci_dev {
 
 	atomic_t	cmd_cnt;
 	unsigned int	acl_cnt;
-	unsigned int	sco_cnt;
+	atomic_t	sco_cnt;
 
 	unsigned int	acl_mtu;
 	unsigned int	sco_mtu;
@@ -145,7 +147,6 @@ struct hci_conn {
 	struct list_head list;
 
 	atomic_t	 refcnt;
-	spinlock_t	 lock;
 
 	bdaddr_t	 dst;
 	__u16		 handle;
@@ -162,10 +163,11 @@ struct hci_conn {
 	__u8             power_save;
 	unsigned long	 pend;
 
-	unsigned int	 sent;
+	atomic_t	 sent;
 
 	struct sk_buff_head data_q;
 
+	struct hrtimer tx_timer;
 	struct timer_list disc_timer;
 	struct timer_list idle_timer;
 
include/net/bluetooth/sco.h +3 -5
index e28a2a7..4ba976b 100644
@@ -26,12 +26,7 @@ #ifndef __SCO_H
 #define __SCO_H
 
 /* SCO defaults */
-#define SCO_DEFAULT_MTU		500
-#define SCO_DEFAULT_FLUSH_TO	0xFFFF
-
 #define SCO_CONN_TIMEOUT	(HZ * 40)
-#define SCO_DISCONN_TIMEOUT	(HZ * 2)
-#define SCO_CONN_IDLE_TIMEOUT	(HZ * 60)
 
 /* SCO socket address */
 struct sockaddr_sco {
@@ -51,6 +46,9 @@ struct sco_conninfo {
 	__u8  dev_class[3];
 };
 
+#define SCO_TXBUFS	0x03
+#define SCO_RXBUFS	0x04
+
 /* ---- SCO connections ---- */
 struct sco_conn {
 	struct hci_conn	*hcon;
net/bluetooth/hci_conn.c +6 -1
index f3403fd..72c7a07 100644
@@ -185,6 +185,8 @@ struct hci_conn *hci_conn_add(struct hci
 
 	skb_queue_head_init(&conn->data_q);
 
+	hrtimer_init(&conn->tx_timer, CLOCK_MONOTONIC, HRTIMER_NORESTART);
+
 	init_timer(&conn->disc_timer);
 	conn->disc_timer.function = hci_conn_timeout;
 	conn->disc_timer.data = (unsigned long) conn;
@@ -194,6 +196,7 @@ struct hci_conn *hci_conn_add(struct hci
 	conn->idle_timer.data = (unsigned long) conn;
 
 	atomic_set(&conn->refcnt, 0);
+	atomic_set(&conn->sent, 0);
 
 	hci_dev_hold(hdev);
 
@@ -220,6 +223,8 @@ int hci_conn_del(struct hci_conn *conn)
 
 	del_timer(&conn->disc_timer);
 
+	hrtimer_cancel(&conn->tx_timer);
+
 	if (conn->type == SCO_LINK) {
 		struct hci_conn *acl = conn->link;
 		if (acl) {
@@ -232,7 +237,7 @@ int hci_conn_del(struct hci_conn *conn)
 			sco->link = NULL;
 
 		/* Unacked frames */
-		hdev->acl_cnt += conn->sent;
+		hdev->acl_cnt += atomic_read(&conn->sent);
 	}
 
 	tasklet_disable(&hdev->tx_task);
net/bluetooth/hci_core.c +95 -30

204 lines not on this page · raw message

net/bluetooth/hci_event.c +4 -7
index 936d3fc..e220e0a 100644
@@ -319,7 +319,7 @@ static void hci_cc_info_param(struct hci
 		lv = (struct hci_rp_read_loc_version *) skb->data;
 
 		if (lv->status) {
-			BT_DBG("%s READ_LOCAL_VERSION failed %d", hdev->name, lf->status);
+			BT_DBG("%s READ_LOCAL_VERSION failed %d", hdev->name, lv->status);
 			break;
 		}
 
@@ -381,7 +381,7 @@ static void hci_cc_info_param(struct hci
 		}
 
 		hdev->acl_cnt = hdev->acl_pkts;
-		hdev->sco_cnt = hdev->sco_pkts;
+		atomic_set(&hdev->sco_cnt, hdev->sco_pkts);
 
 		BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
 			hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts);
@@ -879,12 +879,9 @@ static inline void hci_num_comp_pkts_evt
 
 		conn = hci_conn_hash_lookup_handle(hdev, handle);
 		if (conn) {
-			conn->sent -= count;
+			atomic_sub(count, &conn->sent);
 
-			if (conn->type == SCO_LINK) {
-				if ((hdev->sco_cnt += count) > hdev->sco_pkts)
-					hdev->sco_cnt = hdev->sco_pkts;
-			} else {
+			if (conn->type == ACL_LINK) {
 				if ((hdev->acl_cnt += count) > hdev->acl_pkts)
 					hdev->acl_cnt = hdev->acl_pkts;
 			}
net/bluetooth/sco.c +132 -15

230 lines not on this page · raw message

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

_______________________________________________
Bluez-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel

maintainer
#1 lore raw

Hi Brad,

Quoted 9 lines

per our conversation about this, I have reworked the sco flowcontrol patch against the linus git tree (2.6.21rc2) and successfully tested it. Most of the comments are out so you can more easily see what is changing. I left about 3 comments in that are parts of new blocks of code.

I made a couple of changes like the signature of a function used as a fn pointer and avoiding a variable rename but this is essentially the same code people have been testing against older kernels.

Quoted 5 lines

It's also in bluetooth-alsa cvs under plugz/patches/

I used to have a testcase from Fabien that would consistently crash the unpatched kernel but I couldn't dig it up. That would be good for eg regression testing and I will put it in plugz cvs when we track it down.

I did an initial review and there are still some whitespace and coding style issues that need to be fixed.

The biggest thing however is hci_sched_sco(). This function is ugly as hell and basically unreadable. Please use break or continue instead of cascaded if clauses. I am not gonna review this piece of the patch until that is fixed.

Regards

Marcel

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Bluez-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel

#2 lore raw

Marcel

Quoted 3 lines

The biggest thing however is hci_sched_sco(). This function is ugly as hell and basically unreadable. Please use break or continue instead of cascaded if clauses.

ok I will work on it and submit another patch this week.

Brad

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Bluez-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel

#3 lore raw
In reply to Marcel Holtmann

Marcel

Quoted 4 lines

The biggest thing however is hci_sched_sco(). This function is ugly as hell and basically unreadable. Please use break or continue instead of cascaded if clauses. I am not gonna review this piece of the patch until that is fixed.

I fixed a few whitespace problems and changed hci_sched_sco so it didn't get deep into nested if's. How does it look now?

Brad

include/net/bluetooth/bluetooth.h +0 -0
include/net/bluetooth/hci.h +0 -0
include/net/bluetooth/hci_core.h +5 -3
index c0fc396..bd9be7a 100644
@@ -25,6 +25,8 @@
 #ifndef __HCI_CORE_H
 #define __HCI_CORE_H
 
+#include <linux/hrtimer.h>
+
 #include <net/bluetooth/hci.h>
 
 /* HCI upper protocols */
@@ -89,7 +91,7 @@ struct hci_dev {
 
 	atomic_t	cmd_cnt;
 	unsigned int	acl_cnt;
-	unsigned int	sco_cnt;
+	atomic_t	sco_cnt;
 
 	unsigned int	acl_mtu;
 	unsigned int	sco_mtu;
@@ -145,7 +147,6 @@ struct hci_conn {
 	struct list_head list;
 
 	atomic_t	 refcnt;
-	spinlock_t	 lock;
 
 	bdaddr_t	 dst;
 	__u16		 handle;
@@ -162,10 +163,11 @@ struct hci_conn {
 	__u8             power_save;
 	unsigned long	 pend;
 
-	unsigned int	 sent;
+	atomic_t	 sent;
 
 	struct sk_buff_head data_q;
 
+	struct hrtimer tx_timer;
 	struct timer_list disc_timer;
 	struct timer_list idle_timer;
 
include/net/bluetooth/l2cap.h +0 -0
include/net/bluetooth/rfcomm.h +0 -0
include/net/bluetooth/sco.h +3 -5
index e28a2a7..4ba976b 100644
@@ -26,12 +26,7 @@ #ifndef __SCO_H
 #define __SCO_H
 
 /* SCO defaults */
-#define SCO_DEFAULT_MTU		500
-#define SCO_DEFAULT_FLUSH_TO	0xFFFF
-
 #define SCO_CONN_TIMEOUT	(HZ * 40)
-#define SCO_DISCONN_TIMEOUT	(HZ * 2)
-#define SCO_CONN_IDLE_TIMEOUT	(HZ * 60)
 
 /* SCO socket address */
 struct sockaddr_sco {
@@ -51,6 +46,9 @@ struct sco_conninfo {
 	__u8  dev_class[3];
 };
 
+#define SCO_TXBUFS	0x03
+#define SCO_RXBUFS	0x04
+
 /* ---- SCO connections ---- */
 struct sco_conn {
 	struct hci_conn	*hcon;
net/bluetooth/Kconfig +0 -0
net/bluetooth/Makefile +0 -0
net/bluetooth/af_bluetooth.c +0 -0
net/bluetooth/bnep/Kconfig +0 -0
net/bluetooth/bnep/Makefile +0 -0
net/bluetooth/bnep/bnep.h +0 -0
net/bluetooth/bnep/core.c +0 -0
net/bluetooth/bnep/netdev.c +0 -0
net/bluetooth/bnep/sock.c +0 -0
net/bluetooth/cmtp/Kconfig +0 -0
net/bluetooth/cmtp/Makefile +0 -0
net/bluetooth/cmtp/capi.c +0 -0
net/bluetooth/cmtp/cmtp.h +0 -0
net/bluetooth/cmtp/core.c +0 -0
net/bluetooth/cmtp/sock.c +0 -0
net/bluetooth/hci_conn.c +6 -1
index f3403fd..72c7a07 100644
@@ -185,6 +185,8 @@ struct hci_conn *hci_conn_add(struct hci
 
 	skb_queue_head_init(&conn->data_q);
 
+	hrtimer_init(&conn->tx_timer, CLOCK_MONOTONIC, HRTIMER_NORESTART);
+
 	init_timer(&conn->disc_timer);
 	conn->disc_timer.function = hci_conn_timeout;
 	conn->disc_timer.data = (unsigned long) conn;
@@ -194,6 +196,7 @@ struct hci_conn *hci_conn_add(struct hci
 	conn->idle_timer.data = (unsigned long) conn;
 
 	atomic_set(&conn->refcnt, 0);
+	atomic_set(&conn->sent, 0);
 
 	hci_dev_hold(hdev);
 
@@ -220,6 +223,8 @@ int hci_conn_del(struct hci_conn *conn)
 
 	del_timer(&conn->disc_timer);
 
+	hrtimer_cancel(&conn->tx_timer);
+
 	if (conn->type == SCO_LINK) {
 		struct hci_conn *acl = conn->link;
 		if (acl) {
@@ -232,7 +237,7 @@ int hci_conn_del(struct hci_conn *conn)
 			sco->link = NULL;
 
 		/* Unacked frames */
-		hdev->acl_cnt += conn->sent;
+		hdev->acl_cnt += atomic_read(&conn->sent);
 	}
 
 	tasklet_disable(&hdev->tx_task);
net/bluetooth/hci_core.c +99 -28

208 lines not on this page · raw message

net/bluetooth/hci_event.c +4 -7
index 936d3fc..e220e0a 100644
@@ -319,7 +319,7 @@ static void hci_cc_info_param(struct hci
 		lv = (struct hci_rp_read_loc_version *) skb->data;
 
 		if (lv->status) {
-			BT_DBG("%s READ_LOCAL_VERSION failed %d", hdev->name, lf->status);
+			BT_DBG("%s READ_LOCAL_VERSION failed %d", hdev->name, lv->status);
 			break;
 		}
 
@@ -381,7 +381,7 @@ static void hci_cc_info_param(struct hci
 		}
 
 		hdev->acl_cnt = hdev->acl_pkts;
-		hdev->sco_cnt = hdev->sco_pkts;
+		atomic_set(&hdev->sco_cnt, hdev->sco_pkts);
 
 		BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
 			hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts);
@@ -879,12 +879,9 @@ static inline void hci_num_comp_pkts_evt
 
 		conn = hci_conn_hash_lookup_handle(hdev, handle);
 		if (conn) {
-			conn->sent -= count;
+			atomic_sub(count, &conn->sent);
 
-			if (conn->type == SCO_LINK) {
-				if ((hdev->sco_cnt += count) > hdev->sco_pkts)
-					hdev->sco_cnt = hdev->sco_pkts;
-			} else {
+			if (conn->type == ACL_LINK) {
 				if ((hdev->acl_cnt += count) > hdev->acl_pkts)
 					hdev->acl_cnt = hdev->acl_pkts;
 			}
net/bluetooth/hci_sock.c +0 -0
net/bluetooth/hci_sysfs.c +0 -0
net/bluetooth/hidp/Kconfig +0 -0
net/bluetooth/hidp/Makefile +0 -0
net/bluetooth/hidp/core.c +0 -0
net/bluetooth/hidp/hidp.h +0 -0
net/bluetooth/hidp/sock.c +0 -0
net/bluetooth/l2cap.c +0 -0
net/bluetooth/lib.c +0 -0
net/bluetooth/rfcomm/Kconfig +0 -0
net/bluetooth/rfcomm/Makefile +0 -0
net/bluetooth/rfcomm/core.c +0 -0
net/bluetooth/rfcomm/sock.c +0 -0
net/bluetooth/rfcomm/tty.c +0 -0
net/bluetooth/sco.c +132 -15

230 lines not on this page · raw message

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

_______________________________________________
Bluez-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel

maintainer
#4 lore raw

Hi Brad,

Quoted 7 lines
Quoted 4 lines

The biggest thing however is hci_sched_sco(). This function is ugly as hell and basically unreadable. Please use break or continue instead of cascaded if clauses. I am not gonna review this piece of the patch until that is fixed.

I fixed a few whitespace problems and changed hci_sched_sco so it didn't get deep into nested if's. How does it look now?

please also fix the other coding style issues. Some comments and a lot of if clauses are violating the whitespace requirements. It is "if (" and not "if(". It is also "(char *) &val" and not "(char *)&val".

And the code in sco_sock_queue_rcv_skb() is bad. We don't initialize variables if not really needed. In this case if skb_queue_len() check fails simply call return -ENOMEM. Strip the label and call return 0 at the end of the function. Don't make the code more complex than it actually is.

And no forward declaration of sco_sock_queue_rcv_skb() if not really needed.

Why are we using SCO_TXBUFS and not reuse SO_SNDBUF since the value is directly mapped to sk_sndbuf. Same applies to sk_rcvbuf.

And why do we have to do "c->tx_timer.function = hci_sco_tx_timer" over and over again. Isn't it enough if we set the timer function once after init of the timer.

Regards

Marcel

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Bluez-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel

#5 lore raw

Marcel

Quoted 3 lines

And why do we have to do "c->tx_timer.function = hci_sco_tx_timer" over and over again. Isn't it enough if we set the timer function once after init of the timer.

should this happen directly inside hci_conn.c or through something like a notification?

To use it in hci_conn I'd want to move the definition of the function there too but that may not be the right fit.

Brad

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Bluez-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel

maintainer
#6 lore raw

Hi Brad,

Quoted 9 lines
Quoted 3 lines

And why do we have to do "c->tx_timer.function = hci_sco_tx_timer" over and over again. Isn't it enough if we set the timer function once after init of the timer.

should this happen directly inside hci_conn.c or through something like a notification?

To use it in hci_conn I'd want to move the definition of the function there too but that may not be the right fit.

actually hci_sco_tx_timer() should be in hci_conn.c. There is no need to put that into hci_core.c and make this so complex.

Regards

Marcel

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Bluez-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel

#7 lore raw
In reply to Marcel Holtmann

Marcel

Quoted 13 lines

please also fix the other coding style issues. Some comments and a lot of if clauses are violating the whitespace requirements. It is "if (" and not "if(". It is also "(char *) &val" and not "(char *)&val".

And the code in sco_sock_queue_rcv_skb() is bad. We don't initialize variables if not really needed. In this case if skb_queue_len() check fails simply call return -ENOMEM. Strip the label and call return 0 at the end of the function. Don't make the code more complex than it actually is.

And no forward declaration of sco_sock_queue_rcv_skb() if not really needed.

Quoted 6 lines

Why are we using SCO_TXBUFS and not reuse SO_SNDBUF since the value is directly mapped to sk_sndbuf. Same applies to sk_rcvbuf.

And why do we have to do "c->tx_timer.function = hci_sco_tx_timer" over and over again. Isn't it enough if we set the timer function once after init of the timer.

I believe I've applied all these suggestions. Let me know if there are still any issues.

Brad

include/net/bluetooth/bluetooth.h +0 -0
include/net/bluetooth/hci.h +0 -0
include/net/bluetooth/hci_core.h +5 -3
index c0fc396..bd9be7a 100644
@@ -25,6 +25,8 @@
 #ifndef __HCI_CORE_H
 #define __HCI_CORE_H
 
+#include <linux/hrtimer.h>
+
 #include <net/bluetooth/hci.h>
 
 /* HCI upper protocols */
@@ -89,7 +91,7 @@ struct hci_dev {
 
 	atomic_t	cmd_cnt;
 	unsigned int	acl_cnt;
-	unsigned int	sco_cnt;
+	atomic_t	sco_cnt;
 
 	unsigned int	acl_mtu;
 	unsigned int	sco_mtu;
@@ -145,7 +147,6 @@ struct hci_conn {
 	struct list_head list;
 
 	atomic_t	 refcnt;
-	spinlock_t	 lock;
 
 	bdaddr_t	 dst;
 	__u16		 handle;
@@ -162,10 +163,11 @@ struct hci_conn {
 	__u8             power_save;
 	unsigned long	 pend;
 
-	unsigned int	 sent;
+	atomic_t	 sent;
 
 	struct sk_buff_head data_q;
 
+	struct hrtimer tx_timer;
 	struct timer_list disc_timer;
 	struct timer_list idle_timer;
 
include/net/bluetooth/l2cap.h +0 -0
include/net/bluetooth/rfcomm.h +0 -0
include/net/bluetooth/sco.h +0 -5
index e28a2a7..599b3d0 100644
@@ -26,12 +26,7 @@ #ifndef __SCO_H
 #define __SCO_H
 
 /* SCO defaults */
-#define SCO_DEFAULT_MTU		500
-#define SCO_DEFAULT_FLUSH_TO	0xFFFF
-
 #define SCO_CONN_TIMEOUT	(HZ * 40)
-#define SCO_DISCONN_TIMEOUT	(HZ * 2)
-#define SCO_CONN_IDLE_TIMEOUT	(HZ * 60)
 
 /* SCO socket address */
 struct sockaddr_sco {
net/bluetooth/Kconfig +0 -0
net/bluetooth/Makefile +0 -0
net/bluetooth/af_bluetooth.c +0 -0
net/bluetooth/bnep/Kconfig +0 -0
net/bluetooth/bnep/Makefile +0 -0
net/bluetooth/bnep/bnep.h +0 -0
net/bluetooth/bnep/core.c +0 -0
net/bluetooth/bnep/netdev.c +0 -0
net/bluetooth/bnep/sock.c +0 -0
net/bluetooth/cmtp/Kconfig +0 -0
net/bluetooth/cmtp/Makefile +0 -0
net/bluetooth/cmtp/capi.c +0 -0
net/bluetooth/cmtp/cmtp.h +0 -0
net/bluetooth/cmtp/core.c +0 -0
net/bluetooth/cmtp/sock.c +0 -0
net/bluetooth/hci_conn.c +29 -1
index f3403fd..7be72a0 100644
@@ -165,6 +165,26 @@ static void hci_conn_idle(unsigned long 
 	hci_conn_enter_sniff_mode(conn);
 }
 
+static  enum hrtimer_restart hci_sco_tx_timer(struct hrtimer *timer)
+{
+	struct hci_conn *conn = container_of(timer, struct hci_conn, tx_timer);
+#ifdef CONFIG_BT_HCI_CORE_DEBUG
+	ktime_t now = timer->base->get_time();
+
+	BT_DBG("%s, conn %p, time %5lu.%06lu", conn->hdev->name, conn,
+		(unsigned long) now.tv64, 
+		do_div(now.tv64, NSEC_PER_SEC) / 1000);
+#endif
+
+	if (atomic_read(&conn->sent) > 0) {
+		atomic_dec(&conn->sent);
+		atomic_inc(&conn->hdev->sco_cnt);
+		hci_sched_tx(conn->hdev);
+	}
+	return HRTIMER_NORESTART;
+}
+ 
+
 struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
 {
 	struct hci_conn *conn;
@@ -185,6 +205,11 @@ struct hci_conn *hci_conn_add(struct hci
 
 	skb_queue_head_init(&conn->data_q);
 
+	hrtimer_init(&conn->tx_timer, CLOCK_MONOTONIC, HRTIMER_NORESTART);
+
+	if(type == SCO_LINK)
+		conn->tx_timer.function = hci_sco_tx_timer;
+
 	init_timer(&conn->disc_timer);
 	conn->disc_timer.function = hci_conn_timeout;
 	conn->disc_timer.data = (unsigned long) conn;
@@ -194,6 +219,7 @@ struct hci_conn *hci_conn_add(struct hci
 	conn->idle_timer.data = (unsigned long) conn;
 
 	atomic_set(&conn->refcnt, 0);
+	atomic_set(&conn->sent, 0);
 
 	hci_dev_hold(hdev);
 
@@ -220,6 +246,8 @@ int hci_conn_del(struct hci_conn *conn)
 
 	del_timer(&conn->disc_timer);
 
+	hrtimer_cancel(&conn->tx_timer);
+
 	if (conn->type == SCO_LINK) {
 		struct hci_conn *acl = conn->link;
 		if (acl) {
@@ -232,7 +260,7 @@ int hci_conn_del(struct hci_conn *conn)
 			sco->link = NULL;
 
 		/* Unacked frames */
-		hdev->acl_cnt += conn->sent;
+		hdev->acl_cnt += atomic_read(&conn->sent);
 	}
 
 	tasklet_disable(&hdev->tx_task);
net/bluetooth/hci_core.c +70 -26

177 lines not on this page · raw message

net/bluetooth/hci_event.c +4 -7
index 936d3fc..e220e0a 100644
@@ -319,7 +319,7 @@ static void hci_cc_info_param(struct hci
 		lv = (struct hci_rp_read_loc_version *) skb->data;
 
 		if (lv->status) {
-			BT_DBG("%s READ_LOCAL_VERSION failed %d", hdev->name, lf->status);
+			BT_DBG("%s READ_LOCAL_VERSION failed %d", hdev->name, lv->status);
 			break;
 		}
 
@@ -381,7 +381,7 @@ static void hci_cc_info_param(struct hci
 		}
 
 		hdev->acl_cnt = hdev->acl_pkts;
-		hdev->sco_cnt = hdev->sco_pkts;
+		atomic_set(&hdev->sco_cnt, hdev->sco_pkts);
 
 		BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
 			hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts);
@@ -879,12 +879,9 @@ static inline void hci_num_comp_pkts_evt
 
 		conn = hci_conn_hash_lookup_handle(hdev, handle);
 		if (conn) {
-			conn->sent -= count;
+			atomic_sub(count, &conn->sent);
 
-			if (conn->type == SCO_LINK) {
-				if ((hdev->sco_cnt += count) > hdev->sco_pkts)
-					hdev->sco_cnt = hdev->sco_pkts;
-			} else {
+			if (conn->type == ACL_LINK) {
 				if ((hdev->acl_cnt += count) > hdev->acl_pkts)
 					hdev->acl_cnt = hdev->acl_pkts;
 			}
net/bluetooth/hci_sock.c +0 -0
net/bluetooth/hci_sysfs.c +0 -0
net/bluetooth/hidp/Kconfig +0 -0
net/bluetooth/hidp/Makefile +0 -0
net/bluetooth/hidp/core.c +0 -0
net/bluetooth/hidp/hidp.h +0 -0
net/bluetooth/hidp/sock.c +0 -0
net/bluetooth/l2cap.c +0 -0
net/bluetooth/lib.c +0 -0
net/bluetooth/rfcomm/Kconfig +0 -0
net/bluetooth/rfcomm/Makefile +0 -0
net/bluetooth/rfcomm/core.c +0 -0
net/bluetooth/rfcomm/sock.c +0 -0
net/bluetooth/rfcomm/tty.c +0 -0
net/bluetooth/sco.c +120 -16

224 lines not on this page · raw message

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

_______________________________________________
Bluez-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel