[PATCH] 2.4.19 Bluetooth [1/5] core fixes

From: Maksim (Max) (maxk@qualcomm.com)
Date: Sun Aug 04 2002 - 05:47:53 EST


Hi Marcelo, Alan,

Here is another round of Bluetooth updates.

Bluetooth core.

- Device and socket locking fixes

- Fix poll()/select() on connecting socket

- Support for hotplug

- Other minor and trivial fixes

 include/net/bluetooth/hci.h | 10 +++---
 include/net/bluetooth/hci_core.h | 4 +-
 net/bluetooth/af_bluetooth.c | 15 ++++++----
 net/bluetooth/hci_conn.c | 8 ++---
 net/bluetooth/hci_core.c | 57 ++++++++++++++++++++++++++++-----------
 net/bluetooth/hci_event.c | 14 +++------
 net/bluetooth/hci_sock.c | 3 --
 7 files changed, 68 insertions(+), 43 deletions(-)

http://bluez.sourceforge.net/patches/patch-2.4.19-bluetooth-core.gz

Please apply

Max

diff -urN -x 'l2cap*' -x 'sco*' linux.orig/net/bluetooth/af_bluetooth.c linux/net/bluetooth/af_bluetooth.c
--- linux.orig/net/bluetooth/af_bluetooth.c Sat Aug 3 11:59:47 2002
+++ linux/net/bluetooth/af_bluetooth.c Sat Aug 3 18:04:31 2002
@@ -25,9 +25,9 @@
 /*
  * BlueZ Bluetooth address family and sockets.
  *
- * $Id: af_bluetooth.c,v 1.6 2002/06/25 22:03:39 maxk Exp $
+ * $Id: af_bluetooth.c,v 1.8 2002/07/22 20:32:54 maxk Exp $
  */
-#define VERSION "2.1"
+#define VERSION "2.2"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -111,18 +111,18 @@
 
 void bluez_sock_link(struct bluez_sock_list *l, struct sock *sk)
 {
- write_lock(&l->lock);
+ write_lock_bh(&l->lock);
         sk->next = l->head;
         l->head = sk;
         sock_hold(sk);
- write_unlock(&l->lock);
+ write_unlock_bh(&l->lock);
 }
 
 void bluez_sock_unlink(struct bluez_sock_list *l, struct sock *sk)
 {
         struct sock **skp;
 
- write_lock(&l->lock);
+ write_lock_bh(&l->lock);
         for (skp = &l->head; *skp; skp = &((*skp)->next)) {
                 if (*skp == sk) {
                         *skp = sk->next;
@@ -130,7 +130,7 @@
                         break;
                 }
         }
- write_unlock(&l->lock);
+ write_unlock_bh(&l->lock);
 }
 
 void bluez_accept_enqueue(struct sock *parent, struct sock *sk)
@@ -242,6 +242,9 @@
         if (sk->state == BT_CLOSED)
                 mask |= POLLHUP;
 
+ if (sk->state == BT_CONNECT || sk->state == BT_CONNECT2)
+ return mask;
+
         if (sock_writeable(sk))
                 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
         else
diff -urN -x 'l2cap*' -x 'sco*' linux.orig/net/bluetooth/hci_conn.c linux/net/bluetooth/hci_conn.c
--- linux.orig/net/bluetooth/hci_conn.c Sat Aug 3 11:59:47 2002
+++ linux/net/bluetooth/hci_conn.c Sat Aug 3 17:22:49 2002
@@ -25,7 +25,7 @@
 /*
  * HCI Connection handling.
  *
- * $Id: hci_conn.c,v 1.3 2002/06/25 22:03:39 maxk Exp $
+ * $Id: hci_conn.c,v 1.5 2002/07/17 18:46:25 maxk Exp $
  */
 
 #include <linux/config.h>
@@ -73,7 +73,7 @@
         bacpy(&cp.bdaddr, &conn->dst);
 
         if ((ie = inquiry_cache_lookup(hdev, &conn->dst)) &&
- inquiry_entry_age(ie) > INQUIRY_ENTRY_AGE_MAX) {
+ inquiry_entry_age(ie) <= INQUIRY_ENTRY_AGE_MAX) {
                 cp.pscan_rep_mode = ie->info.pscan_rep_mode;
                 cp.pscan_mode = ie->info.pscan_mode;
                 cp.clock_offset = ie->info.clock_offset | __cpu_to_le16(0x8000);
@@ -217,7 +217,7 @@
 
         BT_DBG("%s -> %s", batostr(src), batostr(dst));
 
- spin_lock_bh(&hdev_list_lock);
+ read_lock_bh(&hdev_list_lock);
 
         list_for_each(p, &hdev_list) {
                 struct hci_dev *d;
@@ -245,7 +245,7 @@
         if (hdev)
                 hci_dev_hold(hdev);
 
- spin_unlock_bh(&hdev_list_lock);
+ read_unlock_bh(&hdev_list_lock);
         return hdev;
 }
 
diff -urN -x 'l2cap*' -x 'sco*' linux.orig/net/bluetooth/hci_core.c linux/net/bluetooth/hci_core.c
--- linux.orig/net/bluetooth/hci_core.c Sat Aug 3 11:59:47 2002
+++ linux/net/bluetooth/hci_core.c Sat Aug 3 17:22:50 2002
@@ -25,11 +25,12 @@
 /*
  * BlueZ HCI Core.
  *
- * $Id: hci_core.c,v 1.7 2002/06/25 22:03:39 maxk Exp $
+ * $Id: hci_core.c,v 1.11 2002/07/04 00:25:11 maxk Exp $
  */
 
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/kmod.h>
 
 #include <linux/types.h>
 #include <linux/errno.h>
@@ -66,7 +67,7 @@
 
 /* HCI device list */
 LIST_HEAD(hdev_list);
-spinlock_t hdev_list_lock;
+rwlock_t hdev_list_lock = RW_LOCK_UNLOCKED;
 
 /* HCI protocols */
 #define HCI_MAX_PROTO 2
@@ -93,6 +94,32 @@
         notifier_call_chain(&hci_notifier, event, hdev);
 }
 
+/* ---- HCI hotplug support ---- */
+
+#ifdef CONFIG_HOTPLUG
+
+static int hci_run_hotplug(char *dev, char *action)
+{
+ char *argv[3], *envp[5], dstr[20], astr[32];
+
+ sprintf(dstr, "DEVICE=%s", dev);
+ sprintf(astr, "ACTION=%s", action);
+
+ argv[0] = hotplug_path;
+ argv[1] = "bluetooth";
+ argv[2] = NULL;
+
+ envp[0] = "HOME=/";
+ envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
+ envp[2] = dstr;
+ envp[3] = astr;
+ envp[4] = NULL;
+
+ return call_usermodehelper(argv[0], argv, envp);
+}
+#else
+#define hci_run_hotplug(A...)
+#endif
 
 /* ---- HCI requests ---- */
 
@@ -270,7 +297,7 @@
         if (index < 0)
                 return NULL;
 
- spin_lock(&hdev_list_lock);
+ read_lock(&hdev_list_lock);
         list_for_each(p, &hdev_list) {
                 hdev = list_entry(p, struct hci_dev, list);
                 if (hdev->id == index) {
@@ -280,7 +307,7 @@
         }
         hdev = NULL;
 done:
- spin_unlock(&hdev_list_lock);
+ read_unlock(&hdev_list_lock);
         return hdev;
 }
 
@@ -699,7 +726,7 @@
                 return -ENOMEM;
         dr = dl->dev_req;
 
- spin_lock_bh(&hdev_list_lock);
+ read_lock_bh(&hdev_list_lock);
         list_for_each(p, &hdev_list) {
                 struct hci_dev *hdev;
                 hdev = list_entry(p, struct hci_dev, list);
@@ -708,7 +735,7 @@
                 if (++n >= dev_num)
                         break;
         }
- spin_unlock_bh(&hdev_list_lock);
+ read_unlock_bh(&hdev_list_lock);
 
         dl->dev_num = n;
         size = n * sizeof(struct hci_dev_req) + sizeof(__u16);
@@ -768,7 +795,7 @@
         if (!hdev->open || !hdev->close || !hdev->destruct)
                 return -EINVAL;
 
- spin_lock_bh(&hdev_list_lock);
+ write_lock_bh(&hdev_list_lock);
 
         /* Find first available device id */
         list_for_each(p, &hdev_list) {
@@ -806,12 +833,13 @@
         memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
 
         atomic_set(&hdev->promisc, 0);
-
- hci_notify(hdev, HCI_DEV_REG);
 
         MOD_INC_USE_COUNT;
 
- spin_unlock_bh(&hdev_list_lock);
+ write_unlock_bh(&hdev_list_lock);
+
+ hci_notify(hdev, HCI_DEV_REG);
+ hci_run_hotplug(hdev->name, "register");
 
         return id;
 }
@@ -821,13 +849,15 @@
 {
         BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
 
- spin_lock_bh(&hdev_list_lock);
+ write_lock_bh(&hdev_list_lock);
         list_del(&hdev->list);
- spin_unlock_bh(&hdev_list_lock);
+ write_unlock_bh(&hdev_list_lock);
 
         hci_dev_do_close(hdev);
 
         hci_notify(hdev, HCI_DEV_UNREG);
+ hci_run_hotplug(hdev->name, "unregister");
+
         hci_dev_put(hdev);
 
         MOD_DEC_USE_COUNT;
@@ -1366,9 +1396,6 @@
 
 int hci_core_init(void)
 {
- /* Init locks */
- spin_lock_init(&hdev_list_lock);
-
         return 0;
 }
 
diff -urN -x 'l2cap*' -x 'sco*' linux.orig/net/bluetooth/hci_event.c linux/net/bluetooth/hci_event.c
--- linux.orig/net/bluetooth/hci_event.c Sat Aug 3 11:59:47 2002
+++ linux/net/bluetooth/hci_event.c Sat Aug 3 17:22:50 2002
@@ -25,7 +25,7 @@
 /*
  * HCI Events.
  *
- * $Id: hci_event.c,v 1.3 2002/04/17 17:37:16 maxk Exp $
+ * $Id: hci_event.c,v 1.4 2002/07/27 18:14:38 maxk Exp $
  */
 
 #include <linux/config.h>
@@ -352,16 +352,12 @@
                         hci_dev_lock(hdev);
         
                         acl = conn_hash_lookup_handle(hdev, handle);
- if (!acl || !(sco = acl->link)) {
- hci_dev_unlock(hdev);
- break;
+ if (acl && (sco = acl->link)) {
+ sco->state = BT_CLOSED;
+ hci_proto_connect_cfm(sco, status);
+ hci_conn_del(sco);
                         }
 
- sco->state = BT_CLOSED;
-
- hci_proto_connect_cfm(sco, status);
- hci_conn_del(sco);
-
                         hci_dev_unlock(hdev);
                 }
                 break;
diff -urN -x 'l2cap*' -x 'sco*' linux.orig/net/bluetooth/hci_sock.c linux/net/bluetooth/hci_sock.c
--- linux.orig/net/bluetooth/hci_sock.c Sat Aug 3 11:59:47 2002
+++ linux/net/bluetooth/hci_sock.c Sat Aug 3 17:22:51 2002
@@ -25,7 +25,7 @@
 /*
  * BlueZ HCI socket layer.
  *
- * $Id: hci_sock.c,v 1.4 2002/04/18 22:26:14 maxk Exp $
+ * $Id: hci_sock.c,v 1.5 2002/07/22 20:32:54 maxk Exp $
  */
 
 #include <linux/config.h>
@@ -129,7 +129,6 @@
 
                 if (sock_queue_rcv_skb(sk, nskb))
                         kfree_skb(nskb);
-
         }
         read_unlock(&hci_sk_list.lock);
 }
diff -urN linux.orig/include/net/bluetooth/hci.h linux/include/net/bluetooth/hci.h
--- linux.orig/include/net/bluetooth/hci.h Sat Aug 3 11:59:47 2002
+++ linux/include/net/bluetooth/hci.h Sat Aug 3 17:23:14 2002
@@ -23,7 +23,7 @@
 */
 
 /*
- * $Id: hci.h,v 1.4 2002/04/18 22:26:15 maxk Exp $
+ * $Id: hci.h,v 1.5 2002/06/27 17:29:30 maxk Exp $
  */
 
 #ifndef __HCI_H
@@ -113,10 +113,10 @@
 #define ACL_PTYPE_MASK (~SCO_PTYPE_MASK)
 
 /* ACL flags */
-#define ACL_CONT 0x0001
-#define ACL_START 0x0002
-#define ACL_ACTIVE_BCAST 0x0010
-#define ACL_PICO_BCAST 0x0020
+#define ACL_CONT 0x01
+#define ACL_START 0x02
+#define ACL_ACTIVE_BCAST 0x04
+#define ACL_PICO_BCAST 0x08
 
 /* Baseband links */
 #define SCO_LINK 0x00
diff -urN linux.orig/include/net/bluetooth/hci_core.h linux/include/net/bluetooth/hci_core.h
--- linux.orig/include/net/bluetooth/hci_core.h Sat Aug 3 11:59:47 2002
+++ linux/include/net/bluetooth/hci_core.h Sat Aug 3 17:23:15 2002
@@ -23,7 +23,7 @@
 */
 
 /*
- * $Id: hci_core.h,v 1.4 2002/06/25 22:04:43 maxk Exp $
+ * $Id: hci_core.h,v 1.5 2002/06/27 04:56:30 maxk Exp $
  */
 
 #ifndef __HCI_CORE_H
@@ -149,7 +149,7 @@
 
 extern struct hci_proto *hci_proto[];
 extern struct list_head hdev_list;
-extern spinlock_t hdev_list_lock;
+extern rwlock_t hdev_list_lock;
 
 /* ----- Inquiry cache ----- */
 #define INQUIRY_CACHE_AGE_MAX (HZ*30) // 30 seconds

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed Aug 07 2002 - 22:00:25 EST