aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hidp/core.c
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2013-04-06 14:28:50 -0400
committerGustavo Padovan <gustavo.padovan@collabora.co.uk>2013-04-17 02:04:08 -0400
commit41edc0c034160408feaa78c9a50cc5e91a5928c7 (patch)
tree5717a0106d1bb5549e9386d79a746a5cea5f44d3 /net/bluetooth/hidp/core.c
parent7350e6cf360d32206cbe4e3d34fb48ab863bdb14 (diff)
Bluetooth: hidp: merge 'send' functions into hidp_send_message()
We handle skb buffers all over the place, even though we have hidp_send_*_message() helpers. This creates a more generic hidp_send_message() helper and uses it instead of dealing with transmit queues directly everywhere. Signed-off-by: David Herrmann <dh.herrmann@gmail.com> Acked-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Diffstat (limited to 'net/bluetooth/hidp/core.c')
-rw-r--r--net/bluetooth/hidp/core.c156
1 files changed, 60 insertions, 96 deletions
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index 8f81379e9907..5fcc0389d929 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -68,15 +68,6 @@ static void hidp_session_remove(struct l2cap_conn *conn,
68static int hidp_session_thread(void *arg); 68static int hidp_session_thread(void *arg);
69static void hidp_session_terminate(struct hidp_session *s); 69static void hidp_session_terminate(struct hidp_session *s);
70 70
71static inline void hidp_schedule(struct hidp_session *session)
72{
73 struct sock *ctrl_sk = session->ctrl_sock->sk;
74 struct sock *intr_sk = session->intr_sock->sk;
75
76 wake_up_interruptible(sk_sleep(ctrl_sk));
77 wake_up_interruptible(sk_sleep(intr_sk));
78}
79
80static void hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci) 71static void hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci)
81{ 72{
82 memset(ci, 0, sizeof(*ci)); 73 memset(ci, 0, sizeof(*ci));
@@ -107,11 +98,56 @@ static void hidp_copy_session(struct hidp_session *session, struct hidp_conninfo
107 } 98 }
108} 99}
109 100
101/* assemble skb, queue message on @transmit and wake up the session thread */
102static int hidp_send_message(struct hidp_session *session, struct socket *sock,
103 struct sk_buff_head *transmit, unsigned char hdr,
104 const unsigned char *data, int size)
105{
106 struct sk_buff *skb;
107 struct sock *sk = sock->sk;
108
109 BT_DBG("session %p data %p size %d", session, data, size);
110
111 if (atomic_read(&session->terminate))
112 return -EIO;
113
114 skb = alloc_skb(size + 1, GFP_ATOMIC);
115 if (!skb) {
116 BT_ERR("Can't allocate memory for new frame");
117 return -ENOMEM;
118 }
119
120 *skb_put(skb, 1) = hdr;
121 if (data && size > 0)
122 memcpy(skb_put(skb, size), data, size);
123
124 skb_queue_tail(transmit, skb);
125 wake_up_interruptible(sk_sleep(sk));
126
127 return 0;
128}
129
130static int hidp_send_ctrl_message(struct hidp_session *session,
131 unsigned char hdr, const unsigned char *data,
132 int size)
133{
134 return hidp_send_message(session, session->ctrl_sock,
135 &session->ctrl_transmit, hdr, data, size);
136}
137
138static int hidp_send_intr_message(struct hidp_session *session,
139 unsigned char hdr, const unsigned char *data,
140 int size)
141{
142 return hidp_send_message(session, session->intr_sock,
143 &session->intr_transmit, hdr, data, size);
144}
145
110static int hidp_queue_event(struct hidp_session *session, struct input_dev *dev, 146static int hidp_queue_event(struct hidp_session *session, struct input_dev *dev,
111 unsigned int type, unsigned int code, int value) 147 unsigned int type, unsigned int code, int value)
112{ 148{
113 unsigned char newleds; 149 unsigned char newleds;
114 struct sk_buff *skb; 150 unsigned char hdr, data[2];
115 151
116 BT_DBG("session %p type %d code %d value %d", session, type, code, value); 152 BT_DBG("session %p type %d code %d value %d", session, type, code, value);
117 153
@@ -129,21 +165,11 @@ static int hidp_queue_event(struct hidp_session *session, struct input_dev *dev,
129 165
130 session->leds = newleds; 166 session->leds = newleds;
131 167
132 skb = alloc_skb(3, GFP_ATOMIC); 168 hdr = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT;
133 if (!skb) { 169 data[0] = 0x01;
134 BT_ERR("Can't allocate memory for new frame"); 170 data[1] = newleds;
135 return -ENOMEM;
136 }
137
138 *skb_put(skb, 1) = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT;
139 *skb_put(skb, 1) = 0x01;
140 *skb_put(skb, 1) = newleds;
141
142 skb_queue_tail(&session->intr_transmit, skb);
143 171
144 hidp_schedule(session); 172 return hidp_send_intr_message(session, hdr, data, 2);
145
146 return 0;
147} 173}
148 174
149static int hidp_hidinput_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) 175static int hidp_hidinput_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
@@ -216,71 +242,9 @@ static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb)
216 input_sync(dev); 242 input_sync(dev);
217} 243}
218 244
219static int __hidp_send_ctrl_message(struct hidp_session *session,
220 unsigned char hdr, unsigned char *data,
221 int size)
222{
223 struct sk_buff *skb;
224
225 BT_DBG("session %p data %p size %d", session, data, size);
226
227 if (atomic_read(&session->terminate))
228 return -EIO;
229
230 skb = alloc_skb(size + 1, GFP_ATOMIC);
231 if (!skb) {
232 BT_ERR("Can't allocate memory for new frame");
233 return -ENOMEM;
234 }
235
236 *skb_put(skb, 1) = hdr;
237 if (data && size > 0)
238 memcpy(skb_put(skb, size), data, size);
239
240 skb_queue_tail(&session->ctrl_transmit, skb);
241
242 return 0;
243}
244
245static int hidp_send_ctrl_message(struct hidp_session *session,
246 unsigned char hdr, unsigned char *data, int size)
247{
248 int err;
249
250 err = __hidp_send_ctrl_message(session, hdr, data, size);
251
252 hidp_schedule(session);
253
254 return err;
255}
256
257static int hidp_queue_report(struct hidp_session *session,
258 unsigned char *data, int size)
259{
260 struct sk_buff *skb;
261
262 BT_DBG("session %p hid %p data %p size %d", session, session->hid, data, size);
263
264 skb = alloc_skb(size + 1, GFP_ATOMIC);
265 if (!skb) {
266 BT_ERR("Can't allocate memory for new frame");
267 return -ENOMEM;
268 }
269
270 *skb_put(skb, 1) = 0xa2;
271 if (size > 0)
272 memcpy(skb_put(skb, size), data, size);
273
274 skb_queue_tail(&session->intr_transmit, skb);
275
276 hidp_schedule(session);
277
278 return 0;
279}
280
281static int hidp_send_report(struct hidp_session *session, struct hid_report *report) 245static int hidp_send_report(struct hidp_session *session, struct hid_report *report)
282{ 246{
283 unsigned char buf[32]; 247 unsigned char buf[32], hdr;
284 int rsize; 248 int rsize;
285 249
286 rsize = ((report->size - 1) >> 3) + 1 + (report->id > 0); 250 rsize = ((report->size - 1) >> 3) + 1 + (report->id > 0);
@@ -288,8 +252,9 @@ static int hidp_send_report(struct hidp_session *session, struct hid_report *rep
288 return -EIO; 252 return -EIO;
289 253
290 hid_output_report(report, buf); 254 hid_output_report(report, buf);
255 hdr = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT;
291 256
292 return hidp_queue_report(session, buf, rsize); 257 return hidp_send_intr_message(session, hdr, buf, rsize);
293} 258}
294 259
295static int hidp_get_raw_report(struct hid_device *hid, 260static int hidp_get_raw_report(struct hid_device *hid,
@@ -328,7 +293,7 @@ static int hidp_get_raw_report(struct hid_device *hid,
328 session->waiting_report_number = numbered_reports ? report_number : -1; 293 session->waiting_report_number = numbered_reports ? report_number : -1;
329 set_bit(HIDP_WAITING_FOR_RETURN, &session->flags); 294 set_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
330 data[0] = report_number; 295 data[0] = report_number;
331 ret = hidp_send_ctrl_message(hid->driver_data, report_type, data, 1); 296 ret = hidp_send_ctrl_message(session, report_type, data, 1);
332 if (ret) 297 if (ret)
333 goto err; 298 goto err;
334 299
@@ -388,7 +353,7 @@ static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, s
388 report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE; 353 report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE;
389 break; 354 break;
390 case HID_OUTPUT_REPORT: 355 case HID_OUTPUT_REPORT:
391 report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_OUPUT; 356 report_type = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT;
392 break; 357 break;
393 default: 358 default:
394 return -EINVAL; 359 return -EINVAL;
@@ -399,8 +364,7 @@ static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, s
399 364
400 /* Set up our wait, and send the report request to the device. */ 365 /* Set up our wait, and send the report request to the device. */
401 set_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags); 366 set_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags);
402 ret = hidp_send_ctrl_message(hid->driver_data, report_type, data, 367 ret = hidp_send_ctrl_message(session, report_type, data, count);
403 count);
404 if (ret) 368 if (ret)
405 goto err; 369 goto err;
406 370
@@ -485,12 +449,12 @@ static void hidp_process_handshake(struct hidp_session *session,
485 case HIDP_HSHK_ERR_FATAL: 449 case HIDP_HSHK_ERR_FATAL:
486 /* Device requests a reboot, as this is the only way this error 450 /* Device requests a reboot, as this is the only way this error
487 * can be recovered. */ 451 * can be recovered. */
488 __hidp_send_ctrl_message(session, 452 hidp_send_ctrl_message(session,
489 HIDP_TRANS_HID_CONTROL | HIDP_CTRL_SOFT_RESET, NULL, 0); 453 HIDP_TRANS_HID_CONTROL | HIDP_CTRL_SOFT_RESET, NULL, 0);
490 break; 454 break;
491 455
492 default: 456 default:
493 __hidp_send_ctrl_message(session, 457 hidp_send_ctrl_message(session,
494 HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0); 458 HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
495 break; 459 break;
496 } 460 }
@@ -538,7 +502,7 @@ static int hidp_process_data(struct hidp_session *session, struct sk_buff *skb,
538 break; 502 break;
539 503
540 default: 504 default:
541 __hidp_send_ctrl_message(session, 505 hidp_send_ctrl_message(session,
542 HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0); 506 HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
543 } 507 }
544 508
@@ -585,7 +549,7 @@ static void hidp_recv_ctrl_frame(struct hidp_session *session,
585 break; 549 break;
586 550
587 default: 551 default:
588 __hidp_send_ctrl_message(session, 552 hidp_send_ctrl_message(session,
589 HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_UNSUPPORTED_REQUEST, NULL, 0); 553 HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_UNSUPPORTED_REQUEST, NULL, 0);
590 break; 554 break;
591 } 555 }