aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hidp
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /net/bluetooth/hidp
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'net/bluetooth/hidp')
-rw-r--r--net/bluetooth/hidp/core.c137
-rw-r--r--net/bluetooth/hidp/hidp.h4
-rw-r--r--net/bluetooth/hidp/sock.c7
3 files changed, 86 insertions, 62 deletions
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index 49d8495d69be..280529ad9274 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -243,6 +243,39 @@ static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb)
243 input_sync(dev); 243 input_sync(dev);
244} 244}
245 245
246static int __hidp_send_ctrl_message(struct hidp_session *session,
247 unsigned char hdr, unsigned char *data, int size)
248{
249 struct sk_buff *skb;
250
251 BT_DBG("session %p data %p size %d", session, data, size);
252
253 if (!(skb = alloc_skb(size + 1, GFP_ATOMIC))) {
254 BT_ERR("Can't allocate memory for new frame");
255 return -ENOMEM;
256 }
257
258 *skb_put(skb, 1) = hdr;
259 if (data && size > 0)
260 memcpy(skb_put(skb, size), data, size);
261
262 skb_queue_tail(&session->ctrl_transmit, skb);
263
264 return 0;
265}
266
267static inline int hidp_send_ctrl_message(struct hidp_session *session,
268 unsigned char hdr, unsigned char *data, int size)
269{
270 int err;
271
272 err = __hidp_send_ctrl_message(session, hdr, data, size);
273
274 hidp_schedule(session);
275
276 return err;
277}
278
246static int hidp_queue_report(struct hidp_session *session, 279static int hidp_queue_report(struct hidp_session *session,
247 unsigned char *data, int size) 280 unsigned char *data, int size)
248{ 281{
@@ -280,6 +313,26 @@ static int hidp_send_report(struct hidp_session *session, struct hid_report *rep
280 return hidp_queue_report(session, buf, rsize); 313 return hidp_queue_report(session, buf, rsize);
281} 314}
282 315
316static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count,
317 unsigned char report_type)
318{
319 switch (report_type) {
320 case HID_FEATURE_REPORT:
321 report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE;
322 break;
323 case HID_OUTPUT_REPORT:
324 report_type = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT;
325 break;
326 default:
327 return -EINVAL;
328 }
329
330 if (hidp_send_ctrl_message(hid->driver_data, report_type,
331 data, count))
332 return -ENOMEM;
333 return count;
334}
335
283static void hidp_idle_timeout(unsigned long arg) 336static void hidp_idle_timeout(unsigned long arg)
284{ 337{
285 struct hidp_session *session = (struct hidp_session *) arg; 338 struct hidp_session *session = (struct hidp_session *) arg;
@@ -300,39 +353,6 @@ static inline void hidp_del_timer(struct hidp_session *session)
300 del_timer(&session->timer); 353 del_timer(&session->timer);
301} 354}
302 355
303static int __hidp_send_ctrl_message(struct hidp_session *session,
304 unsigned char hdr, unsigned char *data, int size)
305{
306 struct sk_buff *skb;
307
308 BT_DBG("session %p data %p size %d", session, data, size);
309
310 if (!(skb = alloc_skb(size + 1, GFP_ATOMIC))) {
311 BT_ERR("Can't allocate memory for new frame");
312 return -ENOMEM;
313 }
314
315 *skb_put(skb, 1) = hdr;
316 if (data && size > 0)
317 memcpy(skb_put(skb, size), data, size);
318
319 skb_queue_tail(&session->ctrl_transmit, skb);
320
321 return 0;
322}
323
324static inline int hidp_send_ctrl_message(struct hidp_session *session,
325 unsigned char hdr, unsigned char *data, int size)
326{
327 int err;
328
329 err = __hidp_send_ctrl_message(session, hdr, data, size);
330
331 hidp_schedule(session);
332
333 return err;
334}
335
336static void hidp_process_handshake(struct hidp_session *session, 356static void hidp_process_handshake(struct hidp_session *session,
337 unsigned char param) 357 unsigned char param)
338{ 358{
@@ -694,29 +714,9 @@ static void hidp_close(struct hid_device *hid)
694static int hidp_parse(struct hid_device *hid) 714static int hidp_parse(struct hid_device *hid)
695{ 715{
696 struct hidp_session *session = hid->driver_data; 716 struct hidp_session *session = hid->driver_data;
697 struct hidp_connadd_req *req = session->req;
698 unsigned char *buf;
699 int ret;
700
701 buf = kmalloc(req->rd_size, GFP_KERNEL);
702 if (!buf)
703 return -ENOMEM;
704
705 if (copy_from_user(buf, req->rd_data, req->rd_size)) {
706 kfree(buf);
707 return -EFAULT;
708 }
709
710 ret = hid_parse_report(session->hid, buf, req->rd_size);
711
712 kfree(buf);
713
714 if (ret)
715 return ret;
716 717
717 session->req = NULL; 718 return hid_parse_report(session->hid, session->rd_data,
718 719 session->rd_size);
719 return 0;
720} 720}
721 721
722static int hidp_start(struct hid_device *hid) 722static int hidp_start(struct hid_device *hid)
@@ -761,12 +761,24 @@ static int hidp_setup_hid(struct hidp_session *session,
761 bdaddr_t src, dst; 761 bdaddr_t src, dst;
762 int err; 762 int err;
763 763
764 session->rd_data = kzalloc(req->rd_size, GFP_KERNEL);
765 if (!session->rd_data)
766 return -ENOMEM;
767
768 if (copy_from_user(session->rd_data, req->rd_data, req->rd_size)) {
769 err = -EFAULT;
770 goto fault;
771 }
772 session->rd_size = req->rd_size;
773
764 hid = hid_allocate_device(); 774 hid = hid_allocate_device();
765 if (IS_ERR(hid)) 775 if (IS_ERR(hid)) {
766 return PTR_ERR(session->hid); 776 err = PTR_ERR(hid);
777 goto fault;
778 }
767 779
768 session->hid = hid; 780 session->hid = hid;
769 session->req = req; 781
770 hid->driver_data = session; 782 hid->driver_data = session;
771 783
772 baswap(&src, &bt_sk(session->ctrl_sock->sk)->src); 784 baswap(&src, &bt_sk(session->ctrl_sock->sk)->src);
@@ -785,6 +797,8 @@ static int hidp_setup_hid(struct hidp_session *session,
785 hid->dev.parent = hidp_get_device(session); 797 hid->dev.parent = hidp_get_device(session);
786 hid->ll_driver = &hidp_hid_driver; 798 hid->ll_driver = &hidp_hid_driver;
787 799
800 hid->hid_output_raw_report = hidp_output_raw_report;
801
788 err = hid_add_device(hid); 802 err = hid_add_device(hid);
789 if (err < 0) 803 if (err < 0)
790 goto failed; 804 goto failed;
@@ -795,6 +809,10 @@ failed:
795 hid_destroy_device(hid); 809 hid_destroy_device(hid);
796 session->hid = NULL; 810 session->hid = NULL;
797 811
812fault:
813 kfree(session->rd_data);
814 session->rd_data = NULL;
815
798 return err; 816 return err;
799} 817}
800 818
@@ -889,6 +907,9 @@ unlink:
889 session->hid = NULL; 907 session->hid = NULL;
890 } 908 }
891 909
910 kfree(session->rd_data);
911 session->rd_data = NULL;
912
892purge: 913purge:
893 skb_queue_purge(&session->ctrl_transmit); 914 skb_queue_purge(&session->ctrl_transmit);
894 skb_queue_purge(&session->intr_transmit); 915 skb_queue_purge(&session->intr_transmit);
diff --git a/net/bluetooth/hidp/hidp.h b/net/bluetooth/hidp/hidp.h
index faf3d74c3586..a4e215d50c10 100644
--- a/net/bluetooth/hidp/hidp.h
+++ b/net/bluetooth/hidp/hidp.h
@@ -154,7 +154,9 @@ struct hidp_session {
154 struct sk_buff_head ctrl_transmit; 154 struct sk_buff_head ctrl_transmit;
155 struct sk_buff_head intr_transmit; 155 struct sk_buff_head intr_transmit;
156 156
157 struct hidp_connadd_req *req; 157 /* Report descriptor */
158 __u8 *rd_data;
159 uint rd_size;
158}; 160};
159 161
160static inline void hidp_schedule(struct hidp_session *session) 162static inline void hidp_schedule(struct hidp_session *session)
diff --git a/net/bluetooth/hidp/sock.c b/net/bluetooth/hidp/sock.c
index 37c9d7d2e688..250dfd46237d 100644
--- a/net/bluetooth/hidp/sock.c
+++ b/net/bluetooth/hidp/sock.c
@@ -26,7 +26,6 @@
26#include <linux/capability.h> 26#include <linux/capability.h>
27#include <linux/errno.h> 27#include <linux/errno.h>
28#include <linux/kernel.h> 28#include <linux/kernel.h>
29#include <linux/slab.h>
30#include <linux/poll.h> 29#include <linux/poll.h>
31#include <linux/fcntl.h> 30#include <linux/fcntl.h>
32#include <linux/skbuff.h> 31#include <linux/skbuff.h>
@@ -35,6 +34,7 @@
35#include <linux/file.h> 34#include <linux/file.h>
36#include <linux/init.h> 35#include <linux/init.h>
37#include <linux/compat.h> 36#include <linux/compat.h>
37#include <linux/gfp.h>
38#include <net/sock.h> 38#include <net/sock.h>
39 39
40#include "hidp.h" 40#include "hidp.h"
@@ -241,7 +241,8 @@ static struct proto hidp_proto = {
241 .obj_size = sizeof(struct bt_sock) 241 .obj_size = sizeof(struct bt_sock)
242}; 242};
243 243
244static int hidp_sock_create(struct net *net, struct socket *sock, int protocol) 244static int hidp_sock_create(struct net *net, struct socket *sock, int protocol,
245 int kern)
245{ 246{
246 struct sock *sk; 247 struct sock *sk;
247 248
@@ -268,7 +269,7 @@ static int hidp_sock_create(struct net *net, struct socket *sock, int protocol)
268 return 0; 269 return 0;
269} 270}
270 271
271static struct net_proto_family hidp_sock_family_ops = { 272static const struct net_proto_family hidp_sock_family_ops = {
272 .family = PF_BLUETOOTH, 273 .family = PF_BLUETOOTH,
273 .owner = THIS_MODULE, 274 .owner = THIS_MODULE,
274 .create = hidp_sock_create 275 .create = hidp_sock_create