Commit 0a85b964 authored by Marcel Holtmann's avatar Marcel Holtmann Committed by David S. Miller

[Bluetooth] Integrate services into the driver model

This patch integrates the services of the Bluetooth protocols RFCOMM,
BNEP and HIDP into the driver model. This makes it possible to assign
the virtual TTY, network and input devices to a specific Bluetooth
connection.
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent b219e3ac
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h> #include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h> #include <net/bluetooth/l2cap.h>
#include "bnep.h" #include "bnep.h"
...@@ -515,6 +516,26 @@ static int bnep_session(void *arg) ...@@ -515,6 +516,26 @@ static int bnep_session(void *arg)
return 0; return 0;
} }
static struct device *bnep_get_device(struct bnep_session *session)
{
bdaddr_t *src = &bt_sk(session->sock->sk)->src;
bdaddr_t *dst = &bt_sk(session->sock->sk)->dst;
struct hci_dev *hdev;
struct hci_conn *conn;
hdev = hci_get_route(dst, src);
if (!hdev)
return NULL;
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
if (!conn)
return NULL;
hci_dev_put(hdev);
return &conn->dev;
}
int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
{ {
struct net_device *dev; struct net_device *dev;
...@@ -534,7 +555,6 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) ...@@ -534,7 +555,6 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
if (!dev) if (!dev)
return -ENOMEM; return -ENOMEM;
down_write(&bnep_session_sem); down_write(&bnep_session_sem);
ss = __bnep_get_session(dst); ss = __bnep_get_session(dst);
...@@ -551,7 +571,7 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) ...@@ -551,7 +571,7 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
memcpy(s->eh.h_source, &dst, ETH_ALEN); memcpy(s->eh.h_source, &dst, ETH_ALEN);
memcpy(dev->dev_addr, s->eh.h_dest, ETH_ALEN); memcpy(dev->dev_addr, s->eh.h_dest, ETH_ALEN);
s->dev = dev; s->dev = dev;
s->sock = sock; s->sock = sock;
s->role = req->role; s->role = req->role;
s->state = BT_CONNECTED; s->state = BT_CONNECTED;
...@@ -568,6 +588,8 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) ...@@ -568,6 +588,8 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
bnep_set_default_proto_filter(s); bnep_set_default_proto_filter(s);
#endif #endif
SET_NETDEV_DEV(dev, bnep_get_device(s));
err = register_netdev(dev); err = register_netdev(dev);
if (err) { if (err) {
goto failed; goto failed;
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include <linux/input.h> #include <linux/input.h>
#include <net/bluetooth/bluetooth.h> #include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h> #include <net/bluetooth/l2cap.h>
#include "hidp.h" #include "hidp.h"
...@@ -528,6 +529,26 @@ static int hidp_session(void *arg) ...@@ -528,6 +529,26 @@ static int hidp_session(void *arg)
return 0; return 0;
} }
static struct device *hidp_get_device(struct hidp_session *session)
{
bdaddr_t *src = &bt_sk(session->ctrl_sock->sk)->src;
bdaddr_t *dst = &bt_sk(session->ctrl_sock->sk)->dst;
struct hci_dev *hdev;
struct hci_conn *conn;
hdev = hci_get_route(dst, src);
if (!hdev)
return NULL;
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
if (!conn)
return NULL;
hci_dev_put(hdev);
return &conn->dev;
}
static inline void hidp_setup_input(struct hidp_session *session, struct hidp_connadd_req *req) static inline void hidp_setup_input(struct hidp_session *session, struct hidp_connadd_req *req)
{ {
struct input_dev *input = session->input; struct input_dev *input = session->input;
...@@ -566,6 +587,8 @@ static inline void hidp_setup_input(struct hidp_session *session, struct hidp_co ...@@ -566,6 +587,8 @@ static inline void hidp_setup_input(struct hidp_session *session, struct hidp_co
input->relbit[0] |= BIT(REL_WHEEL); input->relbit[0] |= BIT(REL_WHEEL);
} }
input->cdev.dev = hidp_get_device(session);
input->event = hidp_input_event; input->event = hidp_input_event;
input_register_device(input); input_register_device(input);
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <net/bluetooth/bluetooth.h> #include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/rfcomm.h> #include <net/bluetooth/rfcomm.h>
#ifndef CONFIG_BT_RFCOMM_DEBUG #ifndef CONFIG_BT_RFCOMM_DEBUG
...@@ -161,6 +162,24 @@ static inline struct rfcomm_dev *rfcomm_dev_get(int id) ...@@ -161,6 +162,24 @@ static inline struct rfcomm_dev *rfcomm_dev_get(int id)
return dev; return dev;
} }
static struct device *rfcomm_get_device(struct rfcomm_dev *dev)
{
struct hci_dev *hdev;
struct hci_conn *conn;
hdev = hci_get_route(&dev->dst, &dev->src);
if (!hdev)
return NULL;
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst);
if (!conn)
return NULL;
hci_dev_put(hdev);
return &conn->dev;
}
static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
{ {
struct rfcomm_dev *dev; struct rfcomm_dev *dev;
...@@ -244,7 +263,7 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) ...@@ -244,7 +263,7 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
return err; return err;
} }
tty_register_device(rfcomm_tty_driver, dev->id, NULL); tty_register_device(rfcomm_tty_driver, dev->id, rfcomm_get_device(dev));
return dev->id; return dev->id;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment