提交 44bfce5c 编写于 作者: D David S. Miller
...@@ -808,6 +808,7 @@ static int btmrvl_sdio_host_to_card(struct btmrvl_private *priv, ...@@ -808,6 +808,7 @@ static int btmrvl_sdio_host_to_card(struct btmrvl_private *priv,
exit: exit:
sdio_release_host(card->func); sdio_release_host(card->func);
kfree(tmpbuf);
return ret; return ret;
} }
......
...@@ -377,6 +377,9 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 ...@@ -377,6 +377,9 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
if (acl->state == BT_CONNECTED && if (acl->state == BT_CONNECTED &&
(sco->state == BT_OPEN || sco->state == BT_CLOSED)) { (sco->state == BT_OPEN || sco->state == BT_CLOSED)) {
acl->power_save = 1;
hci_conn_enter_active_mode(acl);
if (lmp_esco_capable(hdev)) if (lmp_esco_capable(hdev))
hci_setup_sync(sco, acl->handle); hci_setup_sync(sco, acl->handle);
else else
......
...@@ -1699,6 +1699,7 @@ static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_bu ...@@ -1699,6 +1699,7 @@ static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_bu
break; break;
case 0x1c: /* SCO interval rejected */ case 0x1c: /* SCO interval rejected */
case 0x1a: /* Unsupported Remote Feature */
case 0x1f: /* Unspecified error */ case 0x1f: /* Unspecified error */
if (conn->out && conn->attempt < 2) { if (conn->out && conn->attempt < 2) {
conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) | conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
......
...@@ -703,29 +703,9 @@ static void hidp_close(struct hid_device *hid) ...@@ -703,29 +703,9 @@ static void hidp_close(struct hid_device *hid)
static int hidp_parse(struct hid_device *hid) static int hidp_parse(struct hid_device *hid)
{ {
struct hidp_session *session = hid->driver_data; struct hidp_session *session = hid->driver_data;
struct hidp_connadd_req *req = session->req;
unsigned char *buf;
int ret;
buf = kmalloc(req->rd_size, GFP_KERNEL);
if (!buf)
return -ENOMEM;
if (copy_from_user(buf, req->rd_data, req->rd_size)) {
kfree(buf);
return -EFAULT;
}
ret = hid_parse_report(session->hid, buf, req->rd_size);
kfree(buf);
if (ret)
return ret;
session->req = NULL;
return 0; return hid_parse_report(session->hid, session->rd_data,
session->rd_size);
} }
static int hidp_start(struct hid_device *hid) static int hidp_start(struct hid_device *hid)
...@@ -770,12 +750,24 @@ static int hidp_setup_hid(struct hidp_session *session, ...@@ -770,12 +750,24 @@ static int hidp_setup_hid(struct hidp_session *session,
bdaddr_t src, dst; bdaddr_t src, dst;
int err; int err;
session->rd_data = kzalloc(req->rd_size, GFP_KERNEL);
if (!session->rd_data)
return -ENOMEM;
if (copy_from_user(session->rd_data, req->rd_data, req->rd_size)) {
err = -EFAULT;
goto fault;
}
session->rd_size = req->rd_size;
hid = hid_allocate_device(); hid = hid_allocate_device();
if (IS_ERR(hid)) if (IS_ERR(hid)) {
return PTR_ERR(hid); err = PTR_ERR(hid);
goto fault;
}
session->hid = hid; session->hid = hid;
session->req = req;
hid->driver_data = session; hid->driver_data = session;
baswap(&src, &bt_sk(session->ctrl_sock->sk)->src); baswap(&src, &bt_sk(session->ctrl_sock->sk)->src);
...@@ -806,6 +798,10 @@ static int hidp_setup_hid(struct hidp_session *session, ...@@ -806,6 +798,10 @@ static int hidp_setup_hid(struct hidp_session *session,
hid_destroy_device(hid); hid_destroy_device(hid);
session->hid = NULL; session->hid = NULL;
fault:
kfree(session->rd_data);
session->rd_data = NULL;
return err; return err;
} }
...@@ -900,6 +896,9 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, ...@@ -900,6 +896,9 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
session->hid = NULL; session->hid = NULL;
} }
kfree(session->rd_data);
session->rd_data = NULL;
purge: purge:
skb_queue_purge(&session->ctrl_transmit); skb_queue_purge(&session->ctrl_transmit);
skb_queue_purge(&session->intr_transmit); skb_queue_purge(&session->intr_transmit);
......
...@@ -154,7 +154,9 @@ struct hidp_session { ...@@ -154,7 +154,9 @@ struct hidp_session {
struct sk_buff_head ctrl_transmit; struct sk_buff_head ctrl_transmit;
struct sk_buff_head intr_transmit; struct sk_buff_head intr_transmit;
struct hidp_connadd_req *req; /* Report descriptor */
__u8 *rd_data;
uint rd_size;
}; };
static inline void hidp_schedule(struct hidp_session *session) static inline void hidp_schedule(struct hidp_session *session)
......
...@@ -252,7 +252,6 @@ static void rfcomm_session_timeout(unsigned long arg) ...@@ -252,7 +252,6 @@ static void rfcomm_session_timeout(unsigned long arg)
BT_DBG("session %p state %ld", s, s->state); BT_DBG("session %p state %ld", s, s->state);
set_bit(RFCOMM_TIMED_OUT, &s->flags); set_bit(RFCOMM_TIMED_OUT, &s->flags);
rfcomm_session_put(s);
rfcomm_schedule(RFCOMM_SCHED_TIMEO); rfcomm_schedule(RFCOMM_SCHED_TIMEO);
} }
...@@ -1151,7 +1150,11 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci) ...@@ -1151,7 +1150,11 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
break; break;
case BT_DISCONN: case BT_DISCONN:
rfcomm_session_put(s); /* When socket is closed and we are not RFCOMM
* initiator rfcomm_process_rx already calls
* rfcomm_session_put() */
if (s->sock->sk->sk_state != BT_CLOSED)
rfcomm_session_put(s);
break; break;
} }
} }
...@@ -1920,6 +1923,7 @@ static inline void rfcomm_process_sessions(void) ...@@ -1920,6 +1923,7 @@ static inline void rfcomm_process_sessions(void)
if (test_and_clear_bit(RFCOMM_TIMED_OUT, &s->flags)) { if (test_and_clear_bit(RFCOMM_TIMED_OUT, &s->flags)) {
s->state = BT_DISCONN; s->state = BT_DISCONN;
rfcomm_send_disc(s, 0); rfcomm_send_disc(s, 0);
rfcomm_session_put(s);
continue; continue;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册