提交 48b81cc1 编写于 作者: J John W. Linville

Merge branch 'for-upstream' of...

Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
......@@ -83,8 +83,8 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = {
};
static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
.helper = "sd8688_helper.bin",
.firmware = "sd8688.bin",
.helper = "mrvl/sd8688_helper.bin",
.firmware = "mrvl/sd8688.bin",
.reg = &btmrvl_reg_8688,
.sd_blksz_fw_dl = 64,
};
......@@ -1185,7 +1185,7 @@ MODULE_AUTHOR("Marvell International Ltd.");
MODULE_DESCRIPTION("Marvell BT-over-SDIO driver ver " VERSION);
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL v2");
MODULE_FIRMWARE("sd8688_helper.bin");
MODULE_FIRMWARE("sd8688.bin");
MODULE_FIRMWARE("mrvl/sd8688_helper.bin");
MODULE_FIRMWARE("mrvl/sd8688.bin");
MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin");
......@@ -232,7 +232,7 @@ struct bt_sock_list {
};
int bt_sock_register(int proto, const struct net_proto_family *ops);
int bt_sock_unregister(int proto);
void bt_sock_unregister(int proto);
void bt_sock_link(struct bt_sock_list *l, struct sock *s);
void bt_sock_unlink(struct bt_sock_list *l, struct sock *s);
int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
......@@ -260,12 +260,22 @@ struct l2cap_ctrl {
__u8 retries;
};
struct hci_dev;
typedef void (*hci_req_complete_t)(struct hci_dev *hdev, u8 status);
struct hci_req_ctrl {
bool start;
hci_req_complete_t complete;
};
struct bt_skb_cb {
__u8 pkt_type;
__u8 incoming;
__u16 expect;
__u8 force_active;
struct l2cap_ctrl control;
struct hci_req_ctrl req;
};
#define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb))
......
......@@ -119,10 +119,16 @@ enum {
HCI_CONNECTABLE,
HCI_DISCOVERABLE,
HCI_LINK_SECURITY,
HCI_PENDING_CLASS,
HCI_PERIODIC_INQ,
HCI_FAST_CONNECTABLE,
};
/* A mask for the flags that are supposed to remain when a reset happens
* or the HCI device is closed.
*/
#define HCI_PERSISTENT_MASK (BIT(HCI_LE_SCAN) | BIT(HCI_PERIODIC_INQ) | \
BIT(HCI_FAST_CONNECTABLE))
/* HCI ioctl defines */
#define HCIDEVUP _IOW('H', 201, int)
#define HCIDEVDOWN _IOW('H', 202, int)
......@@ -881,12 +887,25 @@ struct hci_rp_read_data_block_size {
__le16 num_blocks;
} __packed;
#define HCI_OP_READ_PAGE_SCAN_ACTIVITY 0x0c1b
struct hci_rp_read_page_scan_activity {
__u8 status;
__le16 interval;
__le16 window;
} __packed;
#define HCI_OP_WRITE_PAGE_SCAN_ACTIVITY 0x0c1c
struct hci_cp_write_page_scan_activity {
__le16 interval;
__le16 window;
} __packed;
#define HCI_OP_READ_PAGE_SCAN_TYPE 0x0c46
struct hci_rp_read_page_scan_type {
__u8 status;
__u8 type;
} __packed;
#define HCI_OP_WRITE_PAGE_SCAN_TYPE 0x0c47
#define PAGE_SCAN_TYPE_STANDARD 0x00
#define PAGE_SCAN_TYPE_INTERLACED 0x01
......
......@@ -165,6 +165,10 @@ struct hci_dev {
__u16 voice_setting;
__u8 io_capability;
__s8 inq_tx_power;
__u16 page_scan_interval;
__u16 page_scan_window;
__u8 page_scan_type;
__u16 devid_source;
__u16 devid_vendor;
__u16 devid_product;
......@@ -248,8 +252,6 @@ struct hci_dev {
__u32 req_status;
__u32 req_result;
__u16 init_last_cmd;
struct list_head mgmt_pending;
struct discovery_state discovery;
......@@ -574,7 +576,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev,
return NULL;
}
void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
void hci_disconnect(struct hci_conn *conn, __u8 reason);
void hci_setup_sync(struct hci_conn *conn, __u16 handle);
void hci_sco_setup(struct hci_conn *conn, __u8 status);
......@@ -742,8 +744,6 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
u8 *randomizer);
int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr);
int hci_update_ad(struct hci_dev *hdev);
void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
int hci_recv_frame(struct sk_buff *skb);
......@@ -1041,6 +1041,22 @@ 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);
struct hci_request {
struct hci_dev *hdev;
struct sk_buff_head cmd_q;
/* If something goes wrong when building the HCI request, the error
* value is stored in this field.
*/
int err;
};
void hci_req_init(struct hci_request *req, struct hci_dev *hdev);
int hci_req_run(struct hci_request *req, hci_req_complete_t complete);
void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void *param);
void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status);
void hci_req_cmd_status(struct hci_dev *hdev, u16 opcode, u8 status);
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);
......@@ -1153,7 +1169,7 @@ struct hci_sec_filter {
#define hci_req_lock(d) mutex_lock(&d->req_lock)
#define hci_req_unlock(d) mutex_unlock(&d->req_lock)
void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result);
void hci_update_ad(struct hci_request *req);
void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
u16 latency, u16 to_multiplier);
......
......@@ -158,7 +158,6 @@ struct rfcomm_session {
struct timer_list timer;
unsigned long state;
unsigned long flags;
atomic_t refcnt;
int initiator;
/* Default DLC parameters */
......@@ -276,11 +275,6 @@ static inline void rfcomm_dlc_unthrottle(struct rfcomm_dlc *d)
void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src,
bdaddr_t *dst);
static inline void rfcomm_session_hold(struct rfcomm_session *s)
{
atomic_inc(&s->refcnt);
}
/* ---- RFCOMM sockets ---- */
struct sockaddr_rc {
sa_family_t rc_family;
......
......@@ -397,13 +397,12 @@ static int a2mp_getampassoc_rsp(struct amp_mgr *mgr, struct sk_buff *skb,
if (ctrl) {
u8 *assoc;
assoc = kzalloc(assoc_len, GFP_KERNEL);
assoc = kmemdup(rsp->amp_assoc, assoc_len, GFP_KERNEL);
if (!assoc) {
amp_ctrl_put(ctrl);
return -ENOMEM;
}
memcpy(assoc, rsp->amp_assoc, assoc_len);
ctrl->assoc = assoc;
ctrl->assoc_len = assoc_len;
ctrl->assoc_rem_len = assoc_len;
......@@ -472,13 +471,12 @@ static int a2mp_createphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb,
size_t assoc_len = le16_to_cpu(hdr->len) - sizeof(*req);
u8 *assoc;
assoc = kzalloc(assoc_len, GFP_KERNEL);
assoc = kmemdup(req->amp_assoc, assoc_len, GFP_KERNEL);
if (!assoc) {
amp_ctrl_put(ctrl);
return -ENOMEM;
}
memcpy(assoc, req->amp_assoc, assoc_len);
ctrl->assoc = assoc;
ctrl->assoc_len = assoc_len;
ctrl->assoc_rem_len = assoc_len;
......
......@@ -92,23 +92,14 @@ int bt_sock_register(int proto, const struct net_proto_family *ops)
}
EXPORT_SYMBOL(bt_sock_register);
int bt_sock_unregister(int proto)
void bt_sock_unregister(int proto)
{
int err = 0;
if (proto < 0 || proto >= BT_MAX_PROTO)
return -EINVAL;
return;
write_lock(&bt_proto_lock);
if (!bt_proto[proto])
err = -ENOENT;
else
bt_proto[proto] = NULL;
bt_proto[proto] = NULL;
write_unlock(&bt_proto_lock);
return err;
}
EXPORT_SYMBOL(bt_sock_unregister);
......
......@@ -253,8 +253,6 @@ int __init bnep_sock_init(void)
void __exit bnep_sock_cleanup(void)
{
bt_procfs_cleanup(&init_net, "bnep");
if (bt_sock_unregister(BTPROTO_BNEP) < 0)
BT_ERR("Can't unregister BNEP socket");
bt_sock_unregister(BTPROTO_BNEP);
proto_unregister(&bnep_proto);
}
......@@ -264,8 +264,6 @@ int cmtp_init_sockets(void)
void cmtp_cleanup_sockets(void)
{
bt_procfs_cleanup(&init_net, "cmtp");
if (bt_sock_unregister(BTPROTO_CMTP) < 0)
BT_ERR("Can't unregister CMTP socket");
bt_sock_unregister(BTPROTO_CMTP);
proto_unregister(&cmtp_proto);
}
......@@ -117,7 +117,7 @@ static void hci_acl_create_connection_cancel(struct hci_conn *conn)
hci_send_cmd(conn->hdev, HCI_OP_CREATE_CONN_CANCEL, sizeof(cp), &cp);
}
void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
void hci_disconnect(struct hci_conn *conn, __u8 reason)
{
struct hci_cp_disconnect cp;
......@@ -253,7 +253,7 @@ static void hci_conn_disconnect(struct hci_conn *conn)
hci_amp_disconn(conn, reason);
break;
default:
hci_acl_disconn(conn, reason);
hci_disconnect(conn, reason);
break;
}
}
......
此差异已折叠。
此差异已折叠。
......@@ -854,6 +854,11 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
skb_queue_tail(&hdev->raw_q, skb);
queue_work(hdev->workqueue, &hdev->tx_work);
} else {
/* Stand-alone HCI commands must be flaged as
* single-command requests.
*/
bt_cb(skb)->req.start = true;
skb_queue_tail(&hdev->cmd_q, skb);
queue_work(hdev->workqueue, &hdev->cmd_work);
}
......@@ -1121,8 +1126,6 @@ int __init hci_sock_init(void)
void hci_sock_cleanup(void)
{
bt_procfs_cleanup(&init_net, "hci");
if (bt_sock_unregister(BTPROTO_HCI) < 0)
BT_ERR("HCI socket unregistration failed");
bt_sock_unregister(BTPROTO_HCI);
proto_unregister(&hci_sk_proto);
}
......@@ -590,10 +590,8 @@ int __init bt_sysfs_init(void)
bt_debugfs = debugfs_create_dir("bluetooth", NULL);
bt_class = class_create(THIS_MODULE, "bluetooth");
if (IS_ERR(bt_class))
return PTR_ERR(bt_class);
return 0;
return PTR_RET(bt_class);
}
void bt_sysfs_cleanup(void)
......
......@@ -311,6 +311,9 @@ static int hidp_get_raw_report(struct hid_device *hid,
int numbered_reports = hid->report_enum[report_type].numbered;
int ret;
if (atomic_read(&session->terminate))
return -EIO;
switch (report_type) {
case HID_FEATURE_REPORT:
report_type = HIDP_TRANS_GET_REPORT | HIDP_DATA_RTYPE_FEATURE;
......@@ -722,6 +725,7 @@ static int hidp_session(void *arg)
set_current_state(TASK_INTERRUPTIBLE);
}
set_current_state(TASK_RUNNING);
atomic_inc(&session->terminate);
remove_wait_queue(sk_sleep(intr_sk), &intr_wait);
remove_wait_queue(sk_sleep(ctrl_sk), &ctrl_wait);
......
......@@ -304,8 +304,6 @@ int __init hidp_init_sockets(void)
void __exit hidp_cleanup_sockets(void)
{
bt_procfs_cleanup(&init_net, "hidp");
if (bt_sock_unregister(BTPROTO_HIDP) < 0)
BT_ERR("Can't unregister HIDP socket");
bt_sock_unregister(BTPROTO_HIDP);
proto_unregister(&hidp_proto);
}
......@@ -1312,8 +1312,6 @@ int __init l2cap_init_sockets(void)
void l2cap_cleanup_sockets(void)
{
bt_procfs_cleanup(&init_net, "l2cap");
if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
BT_ERR("L2CAP socket unregistration failed");
bt_sock_unregister(BTPROTO_L2CAP);
proto_unregister(&l2cap_proto);
}
此差异已折叠。
......@@ -69,7 +69,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
u8 sec_level,
int *err);
static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst);
static void rfcomm_session_del(struct rfcomm_session *s);
static struct rfcomm_session *rfcomm_session_del(struct rfcomm_session *s);
/* ---- RFCOMM frame parsing macros ---- */
#define __get_dlci(b) ((b & 0xfc) >> 2)
......@@ -108,12 +108,6 @@ static void rfcomm_schedule(void)
wake_up_process(rfcomm_thread);
}
static void rfcomm_session_put(struct rfcomm_session *s)
{
if (atomic_dec_and_test(&s->refcnt))
rfcomm_session_del(s);
}
/* ---- RFCOMM FCS computation ---- */
/* reversed, 8-bit, poly=0x07 */
......@@ -249,16 +243,14 @@ static void rfcomm_session_set_timer(struct rfcomm_session *s, long timeout)
{
BT_DBG("session %p state %ld timeout %ld", s, s->state, timeout);
if (!mod_timer(&s->timer, jiffies + timeout))
rfcomm_session_hold(s);
mod_timer(&s->timer, jiffies + timeout);
}
static void rfcomm_session_clear_timer(struct rfcomm_session *s)
{
BT_DBG("session %p state %ld", s, s->state);
if (del_timer(&s->timer))
rfcomm_session_put(s);
del_timer_sync(&s->timer);
}
/* ---- RFCOMM DLCs ---- */
......@@ -336,8 +328,6 @@ static void rfcomm_dlc_link(struct rfcomm_session *s, struct rfcomm_dlc *d)
{
BT_DBG("dlc %p session %p", d, s);
rfcomm_session_hold(s);
rfcomm_session_clear_timer(s);
rfcomm_dlc_hold(d);
list_add(&d->list, &s->dlcs);
......@@ -356,8 +346,6 @@ static void rfcomm_dlc_unlink(struct rfcomm_dlc *d)
if (list_empty(&s->dlcs))
rfcomm_session_set_timer(s, RFCOMM_IDLE_TIMEOUT);
rfcomm_session_put(s);
}
static struct rfcomm_dlc *rfcomm_dlc_get(struct rfcomm_session *s, u8 dlci)
......@@ -493,12 +481,34 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
int rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
{
int r;
int r = 0;
struct rfcomm_dlc *d_list;
struct rfcomm_session *s, *s_list;
BT_DBG("dlc %p state %ld dlci %d err %d", d, d->state, d->dlci, err);
rfcomm_lock();
r = __rfcomm_dlc_close(d, err);
s = d->session;
if (!s)
goto no_session;
/* after waiting on the mutex check the session still exists
* then check the dlc still exists
*/
list_for_each_entry(s_list, &session_list, list) {
if (s_list == s) {
list_for_each_entry(d_list, &s->dlcs, list) {
if (d_list == d) {
r = __rfcomm_dlc_close(d, err);
break;
}
}
break;
}
}
no_session:
rfcomm_unlock();
return r;
}
......@@ -609,7 +619,7 @@ static struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state)
return s;
}
static void rfcomm_session_del(struct rfcomm_session *s)
static struct rfcomm_session *rfcomm_session_del(struct rfcomm_session *s)
{
int state = s->state;
......@@ -617,15 +627,14 @@ static void rfcomm_session_del(struct rfcomm_session *s)
list_del(&s->list);
if (state == BT_CONNECTED)
rfcomm_send_disc(s, 0);
rfcomm_session_clear_timer(s);
sock_release(s->sock);
kfree(s);
if (state != BT_LISTEN)
module_put(THIS_MODULE);
return NULL;
}
static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
......@@ -644,17 +653,16 @@ static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
return NULL;
}
static void rfcomm_session_close(struct rfcomm_session *s, int err)
static struct rfcomm_session *rfcomm_session_close(struct rfcomm_session *s,
int err)
{
struct rfcomm_dlc *d;
struct list_head *p, *n;
BT_DBG("session %p state %ld err %d", s, s->state, err);
rfcomm_session_hold(s);
s->state = BT_CLOSED;
BT_DBG("session %p state %ld err %d", s, s->state, err);
/* Close all dlcs */
list_for_each_safe(p, n, &s->dlcs) {
d = list_entry(p, struct rfcomm_dlc, list);
......@@ -663,7 +671,7 @@ static void rfcomm_session_close(struct rfcomm_session *s, int err)
}
rfcomm_session_clear_timer(s);
rfcomm_session_put(s);
return rfcomm_session_del(s);
}
static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
......@@ -715,8 +723,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
if (*err == 0 || *err == -EINPROGRESS)
return s;
rfcomm_session_del(s);
return NULL;
return rfcomm_session_del(s);
failed:
sock_release(sock);
......@@ -1105,7 +1112,7 @@ static void rfcomm_make_uih(struct sk_buff *skb, u8 addr)
}
/* ---- RFCOMM frame reception ---- */
static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
static struct rfcomm_session *rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
{
BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
......@@ -1114,7 +1121,7 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
if (!d) {
rfcomm_send_dm(s, dlci);
return 0;
return s;
}
switch (d->state) {
......@@ -1150,25 +1157,14 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
break;
case BT_DISCONN:
/* rfcomm_session_put is called later so don't do
* anything here otherwise we will mess up the session
* reference counter:
*
* (a) when we are the initiator dlc_unlink will drive
* the reference counter to 0 (there is no initial put
* after session_add)
*
* (b) when we are not the initiator rfcomm_rx_process
* will explicitly call put to balance the initial hold
* done after session add.
*/
s = rfcomm_session_close(s, ECONNRESET);
break;
}
}
return 0;
return s;
}
static int rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci)
static struct rfcomm_session *rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci)
{
int err = 0;
......@@ -1192,13 +1188,13 @@ static int rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci)
else
err = ECONNRESET;
s->state = BT_CLOSED;
rfcomm_session_close(s, err);
s = rfcomm_session_close(s, err);
}
return 0;
return s;
}
static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci)
static struct rfcomm_session *rfcomm_recv_disc(struct rfcomm_session *s,
u8 dlci)
{
int err = 0;
......@@ -1227,11 +1223,9 @@ static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci)
else
err = ECONNRESET;
s->state = BT_CLOSED;
rfcomm_session_close(s, err);
s = rfcomm_session_close(s, err);
}
return 0;
return s;
}
void rfcomm_dlc_accept(struct rfcomm_dlc *d)
......@@ -1652,11 +1646,18 @@ static int rfcomm_recv_data(struct rfcomm_session *s, u8 dlci, int pf, struct sk
return 0;
}
static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb)
static struct rfcomm_session *rfcomm_recv_frame(struct rfcomm_session *s,
struct sk_buff *skb)
{
struct rfcomm_hdr *hdr = (void *) skb->data;
u8 type, dlci, fcs;
if (!s) {
/* no session, so free socket data */
kfree_skb(skb);
return s;
}
dlci = __get_dlci(hdr->addr);
type = __get_type(hdr->ctrl);
......@@ -1667,7 +1668,7 @@ static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb)
if (__check_fcs(skb->data, type, fcs)) {
BT_ERR("bad checksum in packet");
kfree_skb(skb);
return -EILSEQ;
return s;
}
if (__test_ea(hdr->len))
......@@ -1683,22 +1684,23 @@ static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb)
case RFCOMM_DISC:
if (__test_pf(hdr->ctrl))
rfcomm_recv_disc(s, dlci);
s = rfcomm_recv_disc(s, dlci);
break;
case RFCOMM_UA:
if (__test_pf(hdr->ctrl))
rfcomm_recv_ua(s, dlci);
s = rfcomm_recv_ua(s, dlci);
break;
case RFCOMM_DM:
rfcomm_recv_dm(s, dlci);
s = rfcomm_recv_dm(s, dlci);
break;
case RFCOMM_UIH:
if (dlci)
return rfcomm_recv_data(s, dlci, __test_pf(hdr->ctrl), skb);
if (dlci) {
rfcomm_recv_data(s, dlci, __test_pf(hdr->ctrl), skb);
return s;
}
rfcomm_recv_mcc(s, skb);
break;
......@@ -1707,7 +1709,7 @@ static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb)
break;
}
kfree_skb(skb);
return 0;
return s;
}
/* ---- Connection and data processing ---- */
......@@ -1844,7 +1846,7 @@ static void rfcomm_process_dlcs(struct rfcomm_session *s)
}
}
static void rfcomm_process_rx(struct rfcomm_session *s)
static struct rfcomm_session *rfcomm_process_rx(struct rfcomm_session *s)
{
struct socket *sock = s->sock;
struct sock *sk = sock->sk;
......@@ -1856,17 +1858,15 @@ static void rfcomm_process_rx(struct rfcomm_session *s)
while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
skb_orphan(skb);
if (!skb_linearize(skb))
rfcomm_recv_frame(s, skb);
s = rfcomm_recv_frame(s, skb);
else
kfree_skb(skb);
}
if (sk->sk_state == BT_CLOSED) {
if (!s->initiator)
rfcomm_session_put(s);
if (s && (sk->sk_state == BT_CLOSED))
s = rfcomm_session_close(s, sk->sk_err);
rfcomm_session_close(s, sk->sk_err);
}
return s;
}
static void rfcomm_accept_connection(struct rfcomm_session *s)
......@@ -1891,8 +1891,6 @@ static void rfcomm_accept_connection(struct rfcomm_session *s)
s = rfcomm_session_add(nsock, BT_OPEN);
if (s) {
rfcomm_session_hold(s);
/* We should adjust MTU on incoming sessions.
* L2CAP MTU minus UIH header and FCS. */
s->mtu = min(l2cap_pi(nsock->sk)->chan->omtu,
......@@ -1903,7 +1901,7 @@ static void rfcomm_accept_connection(struct rfcomm_session *s)
sock_release(nsock);
}
static void rfcomm_check_connection(struct rfcomm_session *s)
static struct rfcomm_session *rfcomm_check_connection(struct rfcomm_session *s)
{
struct sock *sk = s->sock->sk;
......@@ -1921,10 +1919,10 @@ static void rfcomm_check_connection(struct rfcomm_session *s)
break;
case BT_CLOSED:
s->state = BT_CLOSED;
rfcomm_session_close(s, sk->sk_err);
s = rfcomm_session_close(s, sk->sk_err);
break;
}
return s;
}
static void rfcomm_process_sessions(void)
......@@ -1940,7 +1938,6 @@ static void rfcomm_process_sessions(void)
if (test_and_clear_bit(RFCOMM_TIMED_OUT, &s->flags)) {
s->state = BT_DISCONN;
rfcomm_send_disc(s, 0);
rfcomm_session_put(s);
continue;
}
......@@ -1949,21 +1946,18 @@ static void rfcomm_process_sessions(void)
continue;
}
rfcomm_session_hold(s);
switch (s->state) {
case BT_BOUND:
rfcomm_check_connection(s);
s = rfcomm_check_connection(s);
break;
default:
rfcomm_process_rx(s);
s = rfcomm_process_rx(s);
break;
}
rfcomm_process_dlcs(s);
rfcomm_session_put(s);
if (s)
rfcomm_process_dlcs(s);
}
rfcomm_unlock();
......@@ -2010,10 +2004,11 @@ static int rfcomm_add_listener(bdaddr_t *ba)
/* Add listening session */
s = rfcomm_session_add(sock, BT_LISTEN);
if (!s)
if (!s) {
err = -ENOMEM;
goto failed;
}
rfcomm_session_hold(s);
return 0;
failed:
sock_release(sock);
......@@ -2071,8 +2066,6 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
if (!s)
return;
rfcomm_session_hold(s);
list_for_each_safe(p, n, &s->dlcs) {
d = list_entry(p, struct rfcomm_dlc, list);
......@@ -2104,8 +2097,6 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
set_bit(RFCOMM_AUTH_REJECT, &d->flags);
}
rfcomm_session_put(s);
rfcomm_schedule();
}
......
......@@ -1065,8 +1065,7 @@ void __exit rfcomm_cleanup_sockets(void)
debugfs_remove(rfcomm_sock_debugfs);
if (bt_sock_unregister(BTPROTO_RFCOMM) < 0)
BT_ERR("RFCOMM socket layer unregistration failed");
bt_sock_unregister(BTPROTO_RFCOMM);
proto_unregister(&rfcomm_proto);
}
......@@ -1111,8 +1111,7 @@ void __exit sco_exit(void)
debugfs_remove(sco_debugfs);
if (bt_sock_unregister(BTPROTO_SCO) < 0)
BT_ERR("SCO socket unregistration failed");
bt_sock_unregister(BTPROTO_SCO);
proto_unregister(&sco_proto);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册