| .. | .. |
|---|
| 101 | 101 | { |
|---|
| 102 | 102 | struct sk_buff *skb; |
|---|
| 103 | 103 | struct sock *sk = sock->sk; |
|---|
| 104 | + int ret; |
|---|
| 104 | 105 | |
|---|
| 105 | 106 | BT_DBG("session %p data %p size %d", session, data, size); |
|---|
| 106 | 107 | |
|---|
| .. | .. |
|---|
| 114 | 115 | } |
|---|
| 115 | 116 | |
|---|
| 116 | 117 | skb_put_u8(skb, hdr); |
|---|
| 117 | | - if (data && size > 0) |
|---|
| 118 | + if (data && size > 0) { |
|---|
| 118 | 119 | skb_put_data(skb, data, size); |
|---|
| 120 | + ret = size; |
|---|
| 121 | + } else { |
|---|
| 122 | + ret = 0; |
|---|
| 123 | + } |
|---|
| 119 | 124 | |
|---|
| 120 | 125 | skb_queue_tail(transmit, skb); |
|---|
| 121 | 126 | wake_up_interruptible(sk_sleep(sk)); |
|---|
| 122 | 127 | |
|---|
| 123 | | - return 0; |
|---|
| 128 | + return ret; |
|---|
| 124 | 129 | } |
|---|
| 125 | 130 | |
|---|
| 126 | 131 | static int hidp_send_ctrl_message(struct hidp_session *session, |
|---|
| .. | .. |
|---|
| 262 | 267 | set_bit(HIDP_WAITING_FOR_RETURN, &session->flags); |
|---|
| 263 | 268 | data[0] = report_number; |
|---|
| 264 | 269 | ret = hidp_send_ctrl_message(session, report_type, data, 1); |
|---|
| 265 | | - if (ret) |
|---|
| 270 | + if (ret < 0) |
|---|
| 266 | 271 | goto err; |
|---|
| 267 | 272 | |
|---|
| 268 | 273 | /* Wait for the return of the report. The returned report |
|---|
| .. | .. |
|---|
| 338 | 343 | data[0] = reportnum; |
|---|
| 339 | 344 | set_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags); |
|---|
| 340 | 345 | ret = hidp_send_ctrl_message(session, report_type, data, count); |
|---|
| 341 | | - if (ret) |
|---|
| 346 | + if (ret < 0) |
|---|
| 342 | 347 | goto err; |
|---|
| 343 | 348 | |
|---|
| 344 | 349 | /* Wait for the ACK from the device. */ |
|---|
| .. | .. |
|---|
| 428 | 433 | static void hidp_del_timer(struct hidp_session *session) |
|---|
| 429 | 434 | { |
|---|
| 430 | 435 | if (session->idle_to > 0) |
|---|
| 431 | | - del_timer(&session->timer); |
|---|
| 436 | + del_timer_sync(&session->timer); |
|---|
| 432 | 437 | } |
|---|
| 433 | 438 | |
|---|
| 434 | 439 | static void hidp_process_report(struct hidp_session *session, int type, |
|---|
| .. | .. |
|---|
| 649 | 654 | } |
|---|
| 650 | 655 | |
|---|
| 651 | 656 | static int hidp_setup_input(struct hidp_session *session, |
|---|
| 652 | | - struct hidp_connadd_req *req) |
|---|
| 657 | + const struct hidp_connadd_req *req) |
|---|
| 653 | 658 | { |
|---|
| 654 | 659 | struct input_dev *input; |
|---|
| 655 | 660 | int i; |
|---|
| .. | .. |
|---|
| 748 | 753 | /* This function sets up the hid device. It does not add it |
|---|
| 749 | 754 | to the HID system. That is done in hidp_add_connection(). */ |
|---|
| 750 | 755 | static int hidp_setup_hid(struct hidp_session *session, |
|---|
| 751 | | - struct hidp_connadd_req *req) |
|---|
| 756 | + const struct hidp_connadd_req *req) |
|---|
| 752 | 757 | { |
|---|
| 753 | 758 | struct hid_device *hid; |
|---|
| 754 | 759 | int err; |
|---|
| .. | .. |
|---|
| 775 | 780 | hid->version = req->version; |
|---|
| 776 | 781 | hid->country = req->country; |
|---|
| 777 | 782 | |
|---|
| 778 | | - strncpy(hid->name, req->name, sizeof(hid->name)); |
|---|
| 783 | + strscpy(hid->name, req->name, sizeof(hid->name)); |
|---|
| 779 | 784 | |
|---|
| 780 | 785 | snprintf(hid->phys, sizeof(hid->phys), "%pMR", |
|---|
| 781 | 786 | &l2cap_pi(session->ctrl_sock->sk)->chan->src); |
|---|
| .. | .. |
|---|
| 807 | 812 | |
|---|
| 808 | 813 | /* initialize session devices */ |
|---|
| 809 | 814 | static int hidp_session_dev_init(struct hidp_session *session, |
|---|
| 810 | | - struct hidp_connadd_req *req) |
|---|
| 815 | + const struct hidp_connadd_req *req) |
|---|
| 811 | 816 | { |
|---|
| 812 | 817 | int ret; |
|---|
| 813 | 818 | |
|---|
| .. | .. |
|---|
| 906 | 911 | static int hidp_session_new(struct hidp_session **out, const bdaddr_t *bdaddr, |
|---|
| 907 | 912 | struct socket *ctrl_sock, |
|---|
| 908 | 913 | struct socket *intr_sock, |
|---|
| 909 | | - struct hidp_connadd_req *req, |
|---|
| 914 | + const struct hidp_connadd_req *req, |
|---|
| 910 | 915 | struct l2cap_conn *conn) |
|---|
| 911 | 916 | { |
|---|
| 912 | 917 | struct hidp_session *session; |
|---|
| .. | .. |
|---|
| 1074 | 1079 | static void hidp_session_terminate(struct hidp_session *session) |
|---|
| 1075 | 1080 | { |
|---|
| 1076 | 1081 | atomic_inc(&session->terminate); |
|---|
| 1082 | + /* |
|---|
| 1083 | + * See the comment preceding the call to wait_woken() |
|---|
| 1084 | + * in hidp_session_run(). |
|---|
| 1085 | + */ |
|---|
| 1077 | 1086 | wake_up_interruptible(&hidp_session_wq); |
|---|
| 1078 | 1087 | } |
|---|
| 1079 | 1088 | |
|---|
| .. | .. |
|---|
| 1193 | 1202 | * thread is woken up by ->sk_state_changed(). |
|---|
| 1194 | 1203 | */ |
|---|
| 1195 | 1204 | |
|---|
| 1196 | | - /* Ensure session->terminate is updated */ |
|---|
| 1197 | | - smp_mb__before_atomic(); |
|---|
| 1198 | 1205 | if (atomic_read(&session->terminate)) |
|---|
| 1199 | 1206 | break; |
|---|
| 1200 | 1207 | |
|---|
| .. | .. |
|---|
| 1228 | 1235 | hidp_process_transmit(session, &session->ctrl_transmit, |
|---|
| 1229 | 1236 | session->ctrl_sock); |
|---|
| 1230 | 1237 | |
|---|
| 1238 | + /* |
|---|
| 1239 | + * wait_woken() performs the necessary memory barriers |
|---|
| 1240 | + * for us; see the header comment for this primitive. |
|---|
| 1241 | + */ |
|---|
| 1231 | 1242 | wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); |
|---|
| 1232 | 1243 | } |
|---|
| 1233 | 1244 | remove_wait_queue(&hidp_session_wq, &wait); |
|---|
| 1234 | 1245 | |
|---|
| 1235 | 1246 | atomic_inc(&session->terminate); |
|---|
| 1236 | | - |
|---|
| 1237 | | - /* Ensure session->terminate is updated */ |
|---|
| 1238 | | - smp_mb__after_atomic(); |
|---|
| 1239 | 1247 | } |
|---|
| 1240 | 1248 | |
|---|
| 1241 | 1249 | static int hidp_session_wake_function(wait_queue_entry_t *wait, |
|---|
| .. | .. |
|---|
| 1271 | 1279 | add_wait_queue(sk_sleep(session->intr_sock->sk), &intr_wait); |
|---|
| 1272 | 1280 | /* This memory barrier is paired with wq_has_sleeper(). See |
|---|
| 1273 | 1281 | * sock_poll_wait() for more information why this is needed. */ |
|---|
| 1274 | | - smp_mb(); |
|---|
| 1282 | + smp_mb__before_atomic(); |
|---|
| 1275 | 1283 | |
|---|
| 1276 | 1284 | /* notify synchronous startup that we're ready */ |
|---|
| 1277 | 1285 | atomic_inc(&session->state); |
|---|
| .. | .. |
|---|
| 1335 | 1343 | return 0; |
|---|
| 1336 | 1344 | } |
|---|
| 1337 | 1345 | |
|---|
| 1338 | | -int hidp_connection_add(struct hidp_connadd_req *req, |
|---|
| 1346 | +int hidp_connection_add(const struct hidp_connadd_req *req, |
|---|
| 1339 | 1347 | struct socket *ctrl_sock, |
|---|
| 1340 | 1348 | struct socket *intr_sock) |
|---|
| 1341 | 1349 | { |
|---|