bluetooth: do not move child device other than rfcomm
[sfrench/cifs-2.6.git] / net / bluetooth / hci_sysfs.c
index e13cf5ef144cd59a8a8f7eee15ae24d7826020ba..84360c117d4e3e8bb3e9a68d66bcde0cdf4d3d88 100644 (file)
@@ -320,28 +320,34 @@ void hci_conn_add_sysfs(struct hci_conn *conn)
        queue_work(btaddconn, &conn->work);
 }
 
+/*
+ * The rfcomm tty device will possibly retain even when conn
+ * is down, and sysfs doesn't support move zombie device,
+ * so we should move the device before conn device is destroyed.
+ */
 static int __match_tty(struct device *dev, void *data)
 {
-       /* The rfcomm tty device will possibly retain even when conn
-        * is down, and sysfs doesn't support move zombie device,
-        * so we should move the device before conn device is destroyed.
-        * Due to the only child device of hci_conn dev is rfcomm
-        * tty_dev, here just return 1
-        */
-       return 1;
+       return !strncmp(dev->bus_id, "rfcomm", 6);
 }
 
 static void del_conn(struct work_struct *work)
 {
-       struct device *dev;
        struct hci_conn *conn = container_of(work, struct hci_conn, work);
+       struct hci_dev *hdev = conn->hdev;
+
+       while (1) {
+               struct device *dev;
 
-       while (dev = device_find_child(&conn->dev, NULL, __match_tty)) {
+               dev = device_find_child(&conn->dev, NULL, __match_tty);
+               if (!dev)
+                       break;
                device_move(dev, NULL);
                put_device(dev);
        }
+
        device_del(&conn->dev);
        put_device(&conn->dev);
+       hci_dev_put(hdev);
 }
 
 void hci_conn_del_sysfs(struct hci_conn *conn)