Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 290989
b: refs/heads/master
c: 040030e
h: refs/heads/master
i:
  290987: c3ec719
v: v3
  • Loading branch information
Marcel Holtmann authored and Johan Hedberg committed Feb 20, 2012
1 parent 0c317df commit 33ddbca
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 95 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e0edf3733fb62f91bbb8ec3fab4a90b0ac2dd037
refs/heads/master: 040030ef7d907107e6489b39da518bdf94136d68
7 changes: 2 additions & 5 deletions trunk/include/net/bluetooth/hci_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -941,21 +941,18 @@ static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data,
int hci_register_cb(struct hci_cb *hcb);
int hci_unregister_cb(struct hci_cb *hcb);

int hci_register_notifier(struct notifier_block *nb);
int hci_unregister_notifier(struct notifier_block *nb);

int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param);
void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags);
void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);

void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode);

void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data);

/* ----- HCI Sockets ----- */
void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
void hci_send_to_control(struct sk_buff *skb, struct sock *skip_sk);

void hci_sock_dev_event(struct hci_dev *hdev, int event);

/* Management interface */
#define MGMT_ADDR_BREDR 0x00
#define MGMT_ADDR_LE_PUBLIC 0x01
Expand Down
1 change: 0 additions & 1 deletion trunk/net/bluetooth/hci_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
#include <linux/init.h>
#include <linux/skbuff.h>
#include <linux/interrupt.h>
#include <linux/notifier.h>
#include <net/sock.h>

#include <asm/system.h>
Expand Down
16 changes: 1 addition & 15 deletions trunk/net/bluetooth/hci_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
#include <linux/skbuff.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/notifier.h>
#include <linux/rfkill.h>
#include <linux/timer.h>
#include <linux/crypto.h>
Expand Down Expand Up @@ -69,24 +68,11 @@ DEFINE_RWLOCK(hci_dev_list_lock);
LIST_HEAD(hci_cb_list);
DEFINE_RWLOCK(hci_cb_list_lock);

/* HCI notifiers list */
static ATOMIC_NOTIFIER_HEAD(hci_notifier);

/* ---- HCI notifications ---- */

int hci_register_notifier(struct notifier_block *nb)
{
return atomic_notifier_chain_register(&hci_notifier, nb);
}

int hci_unregister_notifier(struct notifier_block *nb)
{
return atomic_notifier_chain_unregister(&hci_notifier, nb);
}

static void hci_notify(struct hci_dev *hdev, int event)
{
atomic_notifier_call_chain(&hci_notifier, event, hdev);
hci_sock_dev_event(hdev, event);
}

/* ---- HCI requests ---- */
Expand Down
29 changes: 0 additions & 29 deletions trunk/net/bluetooth/hci_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
#include <linux/init.h>
#include <linux/skbuff.h>
#include <linux/interrupt.h>
#include <linux/notifier.h>
#include <net/sock.h>

#include <asm/system.h>
Expand Down Expand Up @@ -3547,33 +3546,5 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
hdev->stat.evt_rx++;
}

/* Generate internal stack event */
void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
{
struct hci_event_hdr *hdr;
struct hci_ev_stack_internal *ev;
struct sk_buff *skb;

skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
if (!skb)
return;

hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
hdr->evt = HCI_EV_STACK_INTERNAL;
hdr->plen = sizeof(*ev) + dlen;

ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
ev->type = type;
memcpy(ev->data, data, dlen);

bt_cb(skb)->incoming = 1;
__net_timestamp(skb);

bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
skb->dev = (void *) hdev;
hci_send_to_sock(hdev, skb);
kfree_skb(skb);
}

module_param(enable_le, bool, 0644);
MODULE_PARM_DESC(enable_le, "Enable LE support");
105 changes: 61 additions & 44 deletions trunk/net/bluetooth/hci_sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,67 @@ void hci_send_to_control(struct sk_buff *skb, struct sock *skip_sk)
read_unlock(&hci_sk_list.lock);
}

/* Generate internal stack event */
static void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
{
struct hci_event_hdr *hdr;
struct hci_ev_stack_internal *ev;
struct sk_buff *skb;

skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
if (!skb)
return;

hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
hdr->evt = HCI_EV_STACK_INTERNAL;
hdr->plen = sizeof(*ev) + dlen;

ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
ev->type = type;
memcpy(ev->data, data, dlen);

bt_cb(skb)->incoming = 1;
__net_timestamp(skb);

bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
skb->dev = (void *) hdev;
hci_send_to_sock(hdev, skb);
kfree_skb(skb);
}

void hci_sock_dev_event(struct hci_dev *hdev, int event)
{
struct hci_ev_si_device ev;

BT_DBG("hdev %s event %d", hdev->name, event);

/* Send event to sockets */
ev.event = event;
ev.dev_id = hdev->id;
hci_si_event(NULL, HCI_EV_SI_DEVICE, sizeof(ev), &ev);

if (event == HCI_DEV_UNREG) {
struct sock *sk;
struct hlist_node *node;

/* Detach sockets from device */
read_lock(&hci_sk_list.lock);
sk_for_each(sk, node, &hci_sk_list.head) {
bh_lock_sock_nested(sk);
if (hci_pi(sk)->hdev == hdev) {
hci_pi(sk)->hdev = NULL;
sk->sk_err = EPIPE;
sk->sk_state = BT_OPEN;
sk->sk_state_change(sk);

hci_dev_put(hdev);
}
bh_unlock_sock(sk);
}
read_unlock(&hci_sk_list.lock);
}
}

static int hci_sock_release(struct socket *sock)
{
struct sock *sk = sock->sk;
Expand Down Expand Up @@ -821,52 +882,12 @@ static int hci_sock_create(struct net *net, struct socket *sock, int protocol,
return 0;
}

static int hci_sock_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
{
struct hci_dev *hdev = (struct hci_dev *) ptr;
struct hci_ev_si_device ev;

BT_DBG("hdev %s event %ld", hdev->name, event);

/* Send event to sockets */
ev.event = event;
ev.dev_id = hdev->id;
hci_si_event(NULL, HCI_EV_SI_DEVICE, sizeof(ev), &ev);

if (event == HCI_DEV_UNREG) {
struct sock *sk;
struct hlist_node *node;

/* Detach sockets from device */
read_lock(&hci_sk_list.lock);
sk_for_each(sk, node, &hci_sk_list.head) {
bh_lock_sock_nested(sk);
if (hci_pi(sk)->hdev == hdev) {
hci_pi(sk)->hdev = NULL;
sk->sk_err = EPIPE;
sk->sk_state = BT_OPEN;
sk->sk_state_change(sk);

hci_dev_put(hdev);
}
bh_unlock_sock(sk);
}
read_unlock(&hci_sk_list.lock);
}

return NOTIFY_DONE;
}

static const struct net_proto_family hci_sock_family_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.create = hci_sock_create,
};

static struct notifier_block hci_sock_nblock = {
.notifier_call = hci_sock_dev_event
};

int __init hci_sock_init(void)
{
int err;
Expand All @@ -879,8 +900,6 @@ int __init hci_sock_init(void)
if (err < 0)
goto error;

hci_register_notifier(&hci_sock_nblock);

BT_INFO("HCI socket layer initialized");

return 0;
Expand All @@ -896,8 +915,6 @@ void hci_sock_cleanup(void)
if (bt_sock_unregister(BTPROTO_HCI) < 0)
BT_ERR("HCI socket unregistration failed");

hci_unregister_notifier(&hci_sock_nblock);

proto_unregister(&hci_sk_proto);
}

Expand Down

0 comments on commit 33ddbca

Please sign in to comment.