diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/hci_sysfs.c | 17 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/tty.c | 3 |
2 files changed, 19 insertions, 1 deletions
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index cad510309dcf..17f7fb720553 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c | |||
@@ -316,9 +316,26 @@ void hci_conn_add_sysfs(struct hci_conn *conn) | |||
316 | schedule_work(&conn->work); | 316 | schedule_work(&conn->work); |
317 | } | 317 | } |
318 | 318 | ||
319 | static int __match_tty(struct device *dev, void *data) | ||
320 | { | ||
321 | /* The rfcomm tty device will possibly retain even when conn | ||
322 | * is down, and sysfs doesn't support move zombie device, | ||
323 | * so we should move the device before conn device is destroyed. | ||
324 | * Due to the only child device of hci_conn dev is rfcomm | ||
325 | * tty_dev, here just return 1 | ||
326 | */ | ||
327 | return 1; | ||
328 | } | ||
329 | |||
319 | static void del_conn(struct work_struct *work) | 330 | static void del_conn(struct work_struct *work) |
320 | { | 331 | { |
332 | struct device *dev; | ||
321 | struct hci_conn *conn = container_of(work, struct hci_conn, work); | 333 | struct hci_conn *conn = container_of(work, struct hci_conn, work); |
334 | |||
335 | while (dev = device_find_child(&conn->dev, NULL, __match_tty)) { | ||
336 | device_move(dev, NULL); | ||
337 | put_device(dev); | ||
338 | } | ||
322 | device_del(&conn->dev); | 339 | device_del(&conn->dev); |
323 | put_device(&conn->dev); | 340 | put_device(&conn->dev); |
324 | } | 341 | } |
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index a6a758dd1f7d..788c70321858 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c | |||
@@ -696,7 +696,8 @@ static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp) | |||
696 | BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc, dev->opened); | 696 | BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc, dev->opened); |
697 | 697 | ||
698 | if (--dev->opened == 0) { | 698 | if (--dev->opened == 0) { |
699 | device_move(dev->tty_dev, NULL); | 699 | if (dev->tty_dev->parent) |
700 | device_move(dev->tty_dev, NULL); | ||
700 | 701 | ||
701 | /* Close DLC and dettach TTY */ | 702 | /* Close DLC and dettach TTY */ |
702 | rfcomm_dlc_close(dev->dlc, 0); | 703 | rfcomm_dlc_close(dev->dlc, 0); |