mirror of https://gitee.com/openkylin/linux.git
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-next-2.6
This commit is contained in:
commit
099284bdec
|
@ -163,7 +163,7 @@ static int ath_enqueue(struct hci_uart *hu, struct sk_buff *skb)
|
|||
struct ath_struct *ath = hu->priv;
|
||||
|
||||
if (bt_cb(skb)->pkt_type == HCI_SCODATA_PKT) {
|
||||
kfree(skb);
|
||||
kfree_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -217,7 +217,7 @@ static struct hci_uart_proto athp = {
|
|||
.flush = ath_flush,
|
||||
};
|
||||
|
||||
int ath_init(void)
|
||||
int __init ath_init(void)
|
||||
{
|
||||
int err = hci_uart_register_proto(&athp);
|
||||
|
||||
|
@ -229,7 +229,7 @@ int ath_init(void)
|
|||
return err;
|
||||
}
|
||||
|
||||
int ath_deinit(void)
|
||||
int __exit ath_deinit(void)
|
||||
{
|
||||
return hci_uart_unregister_proto(&athp);
|
||||
}
|
||||
|
|
|
@ -739,7 +739,7 @@ static struct hci_uart_proto bcsp = {
|
|||
.flush = bcsp_flush
|
||||
};
|
||||
|
||||
int bcsp_init(void)
|
||||
int __init bcsp_init(void)
|
||||
{
|
||||
int err = hci_uart_register_proto(&bcsp);
|
||||
|
||||
|
@ -751,7 +751,7 @@ int bcsp_init(void)
|
|||
return err;
|
||||
}
|
||||
|
||||
int bcsp_deinit(void)
|
||||
int __exit bcsp_deinit(void)
|
||||
{
|
||||
return hci_uart_unregister_proto(&bcsp);
|
||||
}
|
||||
|
|
|
@ -151,107 +151,8 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len)
|
|||
/* Recv data */
|
||||
static int h4_recv(struct hci_uart *hu, void *data, int count)
|
||||
{
|
||||
struct h4_struct *h4 = hu->priv;
|
||||
register char *ptr;
|
||||
struct hci_event_hdr *eh;
|
||||
struct hci_acl_hdr *ah;
|
||||
struct hci_sco_hdr *sh;
|
||||
register int len, type, dlen;
|
||||
|
||||
BT_DBG("hu %p count %d rx_state %ld rx_count %ld",
|
||||
hu, count, h4->rx_state, h4->rx_count);
|
||||
|
||||
ptr = data;
|
||||
while (count) {
|
||||
if (h4->rx_count) {
|
||||
len = min_t(unsigned int, h4->rx_count, count);
|
||||
memcpy(skb_put(h4->rx_skb, len), ptr, len);
|
||||
h4->rx_count -= len; count -= len; ptr += len;
|
||||
|
||||
if (h4->rx_count)
|
||||
continue;
|
||||
|
||||
switch (h4->rx_state) {
|
||||
case H4_W4_DATA:
|
||||
BT_DBG("Complete data");
|
||||
|
||||
hci_recv_frame(h4->rx_skb);
|
||||
|
||||
h4->rx_state = H4_W4_PACKET_TYPE;
|
||||
h4->rx_skb = NULL;
|
||||
continue;
|
||||
|
||||
case H4_W4_EVENT_HDR:
|
||||
eh = hci_event_hdr(h4->rx_skb);
|
||||
|
||||
BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
|
||||
|
||||
h4_check_data_len(h4, eh->plen);
|
||||
continue;
|
||||
|
||||
case H4_W4_ACL_HDR:
|
||||
ah = hci_acl_hdr(h4->rx_skb);
|
||||
dlen = __le16_to_cpu(ah->dlen);
|
||||
|
||||
BT_DBG("ACL header: dlen %d", dlen);
|
||||
|
||||
h4_check_data_len(h4, dlen);
|
||||
continue;
|
||||
|
||||
case H4_W4_SCO_HDR:
|
||||
sh = hci_sco_hdr(h4->rx_skb);
|
||||
|
||||
BT_DBG("SCO header: dlen %d", sh->dlen);
|
||||
|
||||
h4_check_data_len(h4, sh->dlen);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* H4_W4_PACKET_TYPE */
|
||||
switch (*ptr) {
|
||||
case HCI_EVENT_PKT:
|
||||
BT_DBG("Event packet");
|
||||
h4->rx_state = H4_W4_EVENT_HDR;
|
||||
h4->rx_count = HCI_EVENT_HDR_SIZE;
|
||||
type = HCI_EVENT_PKT;
|
||||
break;
|
||||
|
||||
case HCI_ACLDATA_PKT:
|
||||
BT_DBG("ACL packet");
|
||||
h4->rx_state = H4_W4_ACL_HDR;
|
||||
h4->rx_count = HCI_ACL_HDR_SIZE;
|
||||
type = HCI_ACLDATA_PKT;
|
||||
break;
|
||||
|
||||
case HCI_SCODATA_PKT:
|
||||
BT_DBG("SCO packet");
|
||||
h4->rx_state = H4_W4_SCO_HDR;
|
||||
h4->rx_count = HCI_SCO_HDR_SIZE;
|
||||
type = HCI_SCODATA_PKT;
|
||||
break;
|
||||
|
||||
default:
|
||||
BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
|
||||
hu->hdev->stat.err_rx++;
|
||||
ptr++; count--;
|
||||
continue;
|
||||
};
|
||||
|
||||
ptr++; count--;
|
||||
|
||||
/* Allocate packet */
|
||||
h4->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
|
||||
if (!h4->rx_skb) {
|
||||
BT_ERR("Can't allocate mem for new packet");
|
||||
h4->rx_state = H4_W4_PACKET_TYPE;
|
||||
h4->rx_count = 0;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
h4->rx_skb->dev = (void *) hu->hdev;
|
||||
bt_cb(h4->rx_skb)->pkt_type = type;
|
||||
}
|
||||
if (hci_recv_stream_fragment(hu->hdev, data, count) < 0)
|
||||
BT_ERR("Frame Reassembly Failed");
|
||||
|
||||
return count;
|
||||
}
|
||||
|
@ -272,7 +173,7 @@ static struct hci_uart_proto h4p = {
|
|||
.flush = h4_flush,
|
||||
};
|
||||
|
||||
int h4_init(void)
|
||||
int __init h4_init(void)
|
||||
{
|
||||
int err = hci_uart_register_proto(&h4p);
|
||||
|
||||
|
@ -284,7 +185,7 @@ int h4_init(void)
|
|||
return err;
|
||||
}
|
||||
|
||||
int h4_deinit(void)
|
||||
int __exit h4_deinit(void)
|
||||
{
|
||||
return hci_uart_unregister_proto(&h4p);
|
||||
}
|
||||
|
|
|
@ -517,7 +517,7 @@ static struct hci_uart_proto llp = {
|
|||
.flush = ll_flush,
|
||||
};
|
||||
|
||||
int ll_init(void)
|
||||
int __init ll_init(void)
|
||||
{
|
||||
int err = hci_uart_register_proto(&llp);
|
||||
|
||||
|
@ -529,7 +529,7 @@ int ll_init(void)
|
|||
return err;
|
||||
}
|
||||
|
||||
int ll_deinit(void)
|
||||
int __exit ll_deinit(void)
|
||||
{
|
||||
return hci_uart_unregister_proto(&llp);
|
||||
}
|
||||
|
|
|
@ -256,6 +256,7 @@ enum {
|
|||
HCI_CONN_ENCRYPT_PEND,
|
||||
HCI_CONN_RSWITCH_PEND,
|
||||
HCI_CONN_MODE_CHANGE_PEND,
|
||||
HCI_CONN_SCO_SETUP_PEND,
|
||||
};
|
||||
|
||||
static inline void hci_conn_hash_init(struct hci_dev *hdev)
|
||||
|
@ -336,6 +337,7 @@ void hci_acl_connect(struct hci_conn *conn);
|
|||
void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
|
||||
void hci_add_sco(struct hci_conn *conn, __u16 handle);
|
||||
void hci_setup_sync(struct hci_conn *conn, __u16 handle);
|
||||
void hci_sco_setup(struct hci_conn *conn, __u8 status);
|
||||
|
||||
struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
|
||||
int hci_conn_del(struct hci_conn *conn);
|
||||
|
|
|
@ -155,6 +155,27 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle)
|
|||
hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp);
|
||||
}
|
||||
|
||||
/* Device _must_ be locked */
|
||||
void hci_sco_setup(struct hci_conn *conn, __u8 status)
|
||||
{
|
||||
struct hci_conn *sco = conn->link;
|
||||
|
||||
BT_DBG("%p", conn);
|
||||
|
||||
if (!sco)
|
||||
return;
|
||||
|
||||
if (!status) {
|
||||
if (lmp_esco_capable(conn->hdev))
|
||||
hci_setup_sync(sco, conn->handle);
|
||||
else
|
||||
hci_add_sco(sco, conn->handle);
|
||||
} else {
|
||||
hci_proto_connect_cfm(sco, status);
|
||||
hci_conn_del(sco);
|
||||
}
|
||||
}
|
||||
|
||||
static void hci_conn_timeout(unsigned long arg)
|
||||
{
|
||||
struct hci_conn *conn = (void *) arg;
|
||||
|
@ -385,10 +406,13 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
|
|||
acl->power_save = 1;
|
||||
hci_conn_enter_active_mode(acl);
|
||||
|
||||
if (lmp_esco_capable(hdev))
|
||||
hci_setup_sync(sco, acl->handle);
|
||||
else
|
||||
hci_add_sco(sco, acl->handle);
|
||||
if (test_bit(HCI_CONN_MODE_CHANGE_PEND, &acl->pend)) {
|
||||
/* defer SCO setup until mode change completed */
|
||||
set_bit(HCI_CONN_SCO_SETUP_PEND, &acl->pend);
|
||||
return sco;
|
||||
}
|
||||
|
||||
hci_sco_setup(acl, 0x00);
|
||||
}
|
||||
|
||||
return sco;
|
||||
|
|
|
@ -1149,7 +1149,7 @@ int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
|
|||
if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
|
||||
return -EILSEQ;
|
||||
|
||||
do {
|
||||
while (count) {
|
||||
rem = hci_reassembly(hdev, type, data, count,
|
||||
type - 1, GFP_ATOMIC);
|
||||
if (rem < 0)
|
||||
|
@ -1157,7 +1157,7 @@ int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
|
|||
|
||||
data += (count - rem);
|
||||
count = rem;
|
||||
} while (count);
|
||||
};
|
||||
|
||||
return rem;
|
||||
}
|
||||
|
@ -1170,7 +1170,7 @@ int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
|
|||
int type;
|
||||
int rem = 0;
|
||||
|
||||
do {
|
||||
while (count) {
|
||||
struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
|
||||
|
||||
if (!skb) {
|
||||
|
@ -1192,7 +1192,7 @@ int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
|
|||
|
||||
data += (count - rem);
|
||||
count = rem;
|
||||
} while (count);
|
||||
};
|
||||
|
||||
return rem;
|
||||
}
|
||||
|
|
|
@ -785,9 +785,13 @@ static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
|
|||
hci_dev_lock(hdev);
|
||||
|
||||
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
|
||||
if (conn)
|
||||
if (conn) {
|
||||
clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
|
||||
|
||||
if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
|
||||
hci_sco_setup(conn, status);
|
||||
}
|
||||
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
|
@ -808,9 +812,13 @@ static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
|
|||
hci_dev_lock(hdev);
|
||||
|
||||
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
|
||||
if (conn)
|
||||
if (conn) {
|
||||
clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
|
||||
|
||||
if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
|
||||
hci_sco_setup(conn, status);
|
||||
}
|
||||
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
|
@ -915,20 +923,8 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
|
|||
} else
|
||||
conn->state = BT_CLOSED;
|
||||
|
||||
if (conn->type == ACL_LINK) {
|
||||
struct hci_conn *sco = conn->link;
|
||||
if (sco) {
|
||||
if (!ev->status) {
|
||||
if (lmp_esco_capable(hdev))
|
||||
hci_setup_sync(sco, conn->handle);
|
||||
else
|
||||
hci_add_sco(sco, conn->handle);
|
||||
} else {
|
||||
hci_proto_connect_cfm(sco, ev->status);
|
||||
hci_conn_del(sco);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (conn->type == ACL_LINK)
|
||||
hci_sco_setup(conn, ev->status);
|
||||
|
||||
if (ev->status) {
|
||||
hci_proto_connect_cfm(conn, ev->status);
|
||||
|
@ -1481,6 +1477,9 @@ static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb
|
|||
else
|
||||
conn->power_save = 0;
|
||||
}
|
||||
|
||||
if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
|
||||
hci_sco_setup(conn, ev->status);
|
||||
}
|
||||
|
||||
hci_dev_unlock(hdev);
|
||||
|
|
|
@ -1152,7 +1152,7 @@ int __init rfcomm_init_sockets(void)
|
|||
return err;
|
||||
}
|
||||
|
||||
void rfcomm_cleanup_sockets(void)
|
||||
void __exit rfcomm_cleanup_sockets(void)
|
||||
{
|
||||
debugfs_remove(rfcomm_sock_debugfs);
|
||||
|
||||
|
|
|
@ -1153,7 +1153,7 @@ static const struct tty_operations rfcomm_ops = {
|
|||
.tiocmset = rfcomm_tty_tiocmset,
|
||||
};
|
||||
|
||||
int rfcomm_init_ttys(void)
|
||||
int __init rfcomm_init_ttys(void)
|
||||
{
|
||||
rfcomm_tty_driver = alloc_tty_driver(RFCOMM_TTY_PORTS);
|
||||
if (!rfcomm_tty_driver)
|
||||
|
@ -1183,7 +1183,7 @@ int rfcomm_init_ttys(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void rfcomm_cleanup_ttys(void)
|
||||
void __exit rfcomm_cleanup_ttys(void)
|
||||
{
|
||||
tty_unregister_driver(rfcomm_tty_driver);
|
||||
put_tty_driver(rfcomm_tty_driver);
|
||||
|
|
Loading…
Reference in New Issue