iommu/amd: Don't take domain->lock recursivly
[pandora-kernel.git] / net / bluetooth / cmtp / capi.c
1 /*
2    CMTP implementation for Linux Bluetooth stack (BlueZ).
3    Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License version 2 as
7    published by the Free Software Foundation;
8
9    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
10    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
13    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
14    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
19    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
20    SOFTWARE IS DISCLAIMED.
21 */
22
23 #include <linux/module.h>
24 #include <linux/proc_fs.h>
25 #include <linux/seq_file.h>
26 #include <linux/types.h>
27 #include <linux/errno.h>
28 #include <linux/kernel.h>
29 #include <linux/sched.h>
30 #include <linux/slab.h>
31 #include <linux/poll.h>
32 #include <linux/fcntl.h>
33 #include <linux/skbuff.h>
34 #include <linux/socket.h>
35 #include <linux/ioctl.h>
36 #include <linux/file.h>
37 #include <linux/wait.h>
38 #include <linux/kthread.h>
39 #include <net/sock.h>
40
41 #include <linux/isdn/capilli.h>
42 #include <linux/isdn/capicmd.h>
43 #include <linux/isdn/capiutil.h>
44
45 #include "cmtp.h"
46
47 #define CAPI_INTEROPERABILITY           0x20
48
49 #define CAPI_INTEROPERABILITY_REQ       CAPICMD(CAPI_INTEROPERABILITY, CAPI_REQ)
50 #define CAPI_INTEROPERABILITY_CONF      CAPICMD(CAPI_INTEROPERABILITY, CAPI_CONF)
51 #define CAPI_INTEROPERABILITY_IND       CAPICMD(CAPI_INTEROPERABILITY, CAPI_IND)
52 #define CAPI_INTEROPERABILITY_RESP      CAPICMD(CAPI_INTEROPERABILITY, CAPI_RESP)
53
54 #define CAPI_INTEROPERABILITY_REQ_LEN   (CAPI_MSG_BASELEN + 2)
55 #define CAPI_INTEROPERABILITY_CONF_LEN  (CAPI_MSG_BASELEN + 4)
56 #define CAPI_INTEROPERABILITY_IND_LEN   (CAPI_MSG_BASELEN + 2)
57 #define CAPI_INTEROPERABILITY_RESP_LEN  (CAPI_MSG_BASELEN + 2)
58
59 #define CAPI_FUNCTION_REGISTER          0
60 #define CAPI_FUNCTION_RELEASE           1
61 #define CAPI_FUNCTION_GET_PROFILE       2
62 #define CAPI_FUNCTION_GET_MANUFACTURER  3
63 #define CAPI_FUNCTION_GET_VERSION       4
64 #define CAPI_FUNCTION_GET_SERIAL_NUMBER 5
65 #define CAPI_FUNCTION_MANUFACTURER      6
66 #define CAPI_FUNCTION_LOOPBACK          7
67
68
69 #define CMTP_MSGNUM     1
70 #define CMTP_APPLID     2
71 #define CMTP_MAPPING    3
72
73 static struct cmtp_application *cmtp_application_add(struct cmtp_session *session, __u16 appl)
74 {
75         struct cmtp_application *app = kzalloc(sizeof(*app), GFP_KERNEL);
76
77         BT_DBG("session %p application %p appl %d", session, app, appl);
78
79         if (!app)
80                 return NULL;
81
82         app->state = BT_OPEN;
83         app->appl = appl;
84
85         list_add_tail(&app->list, &session->applications);
86
87         return app;
88 }
89
90 static void cmtp_application_del(struct cmtp_session *session, struct cmtp_application *app)
91 {
92         BT_DBG("session %p application %p", session, app);
93
94         if (app) {
95                 list_del(&app->list);
96                 kfree(app);
97         }
98 }
99
100 static struct cmtp_application *cmtp_application_get(struct cmtp_session *session, int pattern, __u16 value)
101 {
102         struct cmtp_application *app;
103         struct list_head *p, *n;
104
105         list_for_each_safe(p, n, &session->applications) {
106                 app = list_entry(p, struct cmtp_application, list);
107                 switch (pattern) {
108                 case CMTP_MSGNUM:
109                         if (app->msgnum == value)
110                                 return app;
111                         break;
112                 case CMTP_APPLID:
113                         if (app->appl == value)
114                                 return app;
115                         break;
116                 case CMTP_MAPPING:
117                         if (app->mapping == value)
118                                 return app;
119                         break;
120                 }
121         }
122
123         return NULL;
124 }
125
126 static int cmtp_msgnum_get(struct cmtp_session *session)
127 {
128         session->msgnum++;
129
130         if ((session->msgnum & 0xff) > 200)
131                 session->msgnum = CMTP_INITIAL_MSGNUM + 1;
132
133         return session->msgnum;
134 }
135
136 static void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb)
137 {
138         struct cmtp_scb *scb = (void *) skb->cb;
139
140         BT_DBG("session %p skb %p len %d", session, skb, skb->len);
141
142         scb->id = -1;
143         scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3);
144
145         skb_queue_tail(&session->transmit, skb);
146
147         wake_up_interruptible(sk_sleep(session->sock->sk));
148 }
149
150 static void cmtp_send_interopmsg(struct cmtp_session *session,
151                                         __u8 subcmd, __u16 appl, __u16 msgnum,
152                                         __u16 function, unsigned char *buf, int len)
153 {
154         struct sk_buff *skb;
155         unsigned char *s;
156
157         BT_DBG("session %p subcmd 0x%02x appl %d msgnum %d", session, subcmd, appl, msgnum);
158
159         skb = alloc_skb(CAPI_MSG_BASELEN + 6 + len, GFP_ATOMIC);
160         if (!skb) {
161                 BT_ERR("Can't allocate memory for interoperability packet");
162                 return;
163         }
164
165         s = skb_put(skb, CAPI_MSG_BASELEN + 6 + len);
166
167         capimsg_setu16(s, 0, CAPI_MSG_BASELEN + 6 + len);
168         capimsg_setu16(s, 2, appl);
169         capimsg_setu8 (s, 4, CAPI_INTEROPERABILITY);
170         capimsg_setu8 (s, 5, subcmd);
171         capimsg_setu16(s, 6, msgnum);
172
173         /* Interoperability selector (Bluetooth Device Management) */
174         capimsg_setu16(s, 8, 0x0001);
175
176         capimsg_setu8 (s, 10, 3 + len);
177         capimsg_setu16(s, 11, function);
178         capimsg_setu8 (s, 13, len);
179
180         if (len > 0)
181                 memcpy(s + 14, buf, len);
182
183         cmtp_send_capimsg(session, skb);
184 }
185
186 static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *skb)
187 {
188         struct capi_ctr *ctrl = &session->ctrl;
189         struct cmtp_application *application;
190         __u16 appl, msgnum, func, info;
191         __u32 controller;
192
193         BT_DBG("session %p skb %p len %d", session, skb, skb->len);
194
195         switch (CAPIMSG_SUBCOMMAND(skb->data)) {
196         case CAPI_CONF:
197                 if (skb->len < CAPI_MSG_BASELEN + 10)
198                         break;
199
200                 func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5);
201                 info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8);
202
203                 switch (func) {
204                 case CAPI_FUNCTION_REGISTER:
205                         msgnum = CAPIMSG_MSGID(skb->data);
206
207                         application = cmtp_application_get(session, CMTP_MSGNUM, msgnum);
208                         if (application) {
209                                 application->state = BT_CONNECTED;
210                                 application->msgnum = 0;
211                                 application->mapping = CAPIMSG_APPID(skb->data);
212                                 wake_up_interruptible(&session->wait);
213                         }
214
215                         break;
216
217                 case CAPI_FUNCTION_RELEASE:
218                         appl = CAPIMSG_APPID(skb->data);
219
220                         application = cmtp_application_get(session, CMTP_MAPPING, appl);
221                         if (application) {
222                                 application->state = BT_CLOSED;
223                                 application->msgnum = 0;
224                                 wake_up_interruptible(&session->wait);
225                         }
226
227                         break;
228
229                 case CAPI_FUNCTION_GET_PROFILE:
230                         if (skb->len < CAPI_MSG_BASELEN + 11 + sizeof(capi_profile))
231                                 break;
232
233                         controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11);
234                         msgnum = CAPIMSG_MSGID(skb->data);
235
236                         if (!info && (msgnum == CMTP_INITIAL_MSGNUM)) {
237                                 session->ncontroller = controller;
238                                 wake_up_interruptible(&session->wait);
239                                 break;
240                         }
241
242                         if (!info && ctrl) {
243                                 memcpy(&ctrl->profile,
244                                         skb->data + CAPI_MSG_BASELEN + 11,
245                                         sizeof(capi_profile));
246                                 session->state = BT_CONNECTED;
247                                 capi_ctr_ready(ctrl);
248                         }
249
250                         break;
251
252                 case CAPI_FUNCTION_GET_MANUFACTURER:
253                         if (skb->len < CAPI_MSG_BASELEN + 15)
254                                 break;
255
256                         controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 10);
257
258                         if (!info && ctrl) {
259                                 int len = min_t(uint, CAPI_MANUFACTURER_LEN,
260                                                 skb->data[CAPI_MSG_BASELEN + 14]);
261
262                                 memset(ctrl->manu, 0, CAPI_MANUFACTURER_LEN);
263                                 strncpy(ctrl->manu,
264                                         skb->data + CAPI_MSG_BASELEN + 15, len);
265                         }
266
267                         break;
268
269                 case CAPI_FUNCTION_GET_VERSION:
270                         if (skb->len < CAPI_MSG_BASELEN + 32)
271                                 break;
272
273                         controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
274
275                         if (!info && ctrl) {
276                                 ctrl->version.majorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 16);
277                                 ctrl->version.minorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 20);
278                                 ctrl->version.majormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 24);
279                                 ctrl->version.minormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 28);
280                         }
281
282                         break;
283
284                 case CAPI_FUNCTION_GET_SERIAL_NUMBER:
285                         if (skb->len < CAPI_MSG_BASELEN + 17)
286                                 break;
287
288                         controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
289
290                         if (!info && ctrl) {
291                                 int len = min_t(uint, CAPI_SERIAL_LEN,
292                                                 skb->data[CAPI_MSG_BASELEN + 16]);
293
294                                 memset(ctrl->serial, 0, CAPI_SERIAL_LEN);
295                                 strncpy(ctrl->serial,
296                                         skb->data + CAPI_MSG_BASELEN + 17, len);
297                         }
298
299                         break;
300                 }
301
302                 break;
303
304         case CAPI_IND:
305                 if (skb->len < CAPI_MSG_BASELEN + 6)
306                         break;
307
308                 func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3);
309
310                 if (func == CAPI_FUNCTION_LOOPBACK) {
311                         int len = min_t(uint, skb->len - CAPI_MSG_BASELEN - 6,
312                                                 skb->data[CAPI_MSG_BASELEN + 5]);
313                         appl = CAPIMSG_APPID(skb->data);
314                         msgnum = CAPIMSG_MSGID(skb->data);
315                         cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func,
316                                                 skb->data + CAPI_MSG_BASELEN + 6, len);
317                 }
318
319                 break;
320         }
321
322         kfree_skb(skb);
323 }
324
325 void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb)
326 {
327         struct capi_ctr *ctrl = &session->ctrl;
328         struct cmtp_application *application;
329         __u16 appl;
330         __u32 contr;
331
332         BT_DBG("session %p skb %p len %d", session, skb, skb->len);
333
334         if (skb->len < CAPI_MSG_BASELEN)
335                 return;
336
337         if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) {
338                 cmtp_recv_interopmsg(session, skb);
339                 return;
340         }
341
342         if (session->flags & (1 << CMTP_LOOPBACK)) {
343                 kfree_skb(skb);
344                 return;
345         }
346
347         appl = CAPIMSG_APPID(skb->data);
348         contr = CAPIMSG_CONTROL(skb->data);
349
350         application = cmtp_application_get(session, CMTP_MAPPING, appl);
351         if (application) {
352                 appl = application->appl;
353                 CAPIMSG_SETAPPID(skb->data, appl);
354         } else {
355                 BT_ERR("Can't find application with id %d", appl);
356                 kfree_skb(skb);
357                 return;
358         }
359
360         if ((contr & 0x7f) == 0x01) {
361                 contr = (contr & 0xffffff80) | session->num;
362                 CAPIMSG_SETCONTROL(skb->data, contr);
363         }
364
365         if (!ctrl) {
366                 BT_ERR("Can't find controller %d for message", session->num);
367                 kfree_skb(skb);
368                 return;
369         }
370
371         capi_ctr_handle_message(ctrl, appl, skb);
372 }
373
374 static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
375 {
376         BT_DBG("ctrl %p data %p", ctrl, data);
377
378         return 0;
379 }
380
381 static void cmtp_reset_ctr(struct capi_ctr *ctrl)
382 {
383         struct cmtp_session *session = ctrl->driverdata;
384
385         BT_DBG("ctrl %p", ctrl);
386
387         capi_ctr_down(ctrl);
388
389         kthread_stop(session->task);
390 }
391
392 static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
393 {
394         DECLARE_WAITQUEUE(wait, current);
395         struct cmtp_session *session = ctrl->driverdata;
396         struct cmtp_application *application;
397         unsigned long timeo = CMTP_INTEROP_TIMEOUT;
398         unsigned char buf[8];
399         int err = 0, nconn, want = rp->level3cnt;
400
401         BT_DBG("ctrl %p appl %d level3cnt %d datablkcnt %d datablklen %d",
402                 ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen);
403
404         application = cmtp_application_add(session, appl);
405         if (!application) {
406                 BT_ERR("Can't allocate memory for new application");
407                 return;
408         }
409
410         if (want < 0)
411                 nconn = ctrl->profile.nbchannel * -want;
412         else
413                 nconn = want;
414
415         if (nconn == 0)
416                 nconn = ctrl->profile.nbchannel;
417
418         capimsg_setu16(buf, 0, nconn);
419         capimsg_setu16(buf, 2, rp->datablkcnt);
420         capimsg_setu16(buf, 4, rp->datablklen);
421
422         application->state = BT_CONFIG;
423         application->msgnum = cmtp_msgnum_get(session);
424
425         cmtp_send_interopmsg(session, CAPI_REQ, 0x0000, application->msgnum,
426                                 CAPI_FUNCTION_REGISTER, buf, 6);
427
428         add_wait_queue(&session->wait, &wait);
429         while (1) {
430                 set_current_state(TASK_INTERRUPTIBLE);
431
432                 if (!timeo) {
433                         err = -EAGAIN;
434                         break;
435                 }
436
437                 if (application->state == BT_CLOSED) {
438                         err = -application->err;
439                         break;
440                 }
441
442                 if (application->state == BT_CONNECTED)
443                         break;
444
445                 if (signal_pending(current)) {
446                         err = -EINTR;
447                         break;
448                 }
449
450                 timeo = schedule_timeout(timeo);
451         }
452         set_current_state(TASK_RUNNING);
453         remove_wait_queue(&session->wait, &wait);
454
455         if (err) {
456                 cmtp_application_del(session, application);
457                 return;
458         }
459 }
460
461 static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl)
462 {
463         struct cmtp_session *session = ctrl->driverdata;
464         struct cmtp_application *application;
465
466         BT_DBG("ctrl %p appl %d", ctrl, appl);
467
468         application = cmtp_application_get(session, CMTP_APPLID, appl);
469         if (!application) {
470                 BT_ERR("Can't find application");
471                 return;
472         }
473
474         application->msgnum = cmtp_msgnum_get(session);
475
476         cmtp_send_interopmsg(session, CAPI_REQ, application->mapping, application->msgnum,
477                                 CAPI_FUNCTION_RELEASE, NULL, 0);
478
479         wait_event_interruptible_timeout(session->wait,
480                         (application->state == BT_CLOSED), CMTP_INTEROP_TIMEOUT);
481
482         cmtp_application_del(session, application);
483 }
484
485 static u16 cmtp_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
486 {
487         struct cmtp_session *session = ctrl->driverdata;
488         struct cmtp_application *application;
489         __u16 appl;
490         __u32 contr;
491
492         BT_DBG("ctrl %p skb %p", ctrl, skb);
493
494         appl = CAPIMSG_APPID(skb->data);
495         contr = CAPIMSG_CONTROL(skb->data);
496
497         application = cmtp_application_get(session, CMTP_APPLID, appl);
498         if ((!application) || (application->state != BT_CONNECTED)) {
499                 BT_ERR("Can't find application with id %d", appl);
500                 return CAPI_ILLAPPNR;
501         }
502
503         CAPIMSG_SETAPPID(skb->data, application->mapping);
504
505         if ((contr & 0x7f) == session->num) {
506                 contr = (contr & 0xffffff80) | 0x01;
507                 CAPIMSG_SETCONTROL(skb->data, contr);
508         }
509
510         cmtp_send_capimsg(session, skb);
511
512         return CAPI_NOERROR;
513 }
514
515 static char *cmtp_procinfo(struct capi_ctr *ctrl)
516 {
517         return "CAPI Message Transport Protocol";
518 }
519
520 static int cmtp_proc_show(struct seq_file *m, void *v)
521 {
522         struct capi_ctr *ctrl = m->private;
523         struct cmtp_session *session = ctrl->driverdata;
524         struct cmtp_application *app;
525         struct list_head *p, *n;
526
527         seq_printf(m, "%s\n\n", cmtp_procinfo(ctrl));
528         seq_printf(m, "addr %s\n", session->name);
529         seq_printf(m, "ctrl %d\n", session->num);
530
531         list_for_each_safe(p, n, &session->applications) {
532                 app = list_entry(p, struct cmtp_application, list);
533                 seq_printf(m, "appl %d -> %d\n", app->appl, app->mapping);
534         }
535
536         return 0;
537 }
538
539 static int cmtp_proc_open(struct inode *inode, struct file *file)
540 {
541         return single_open(file, cmtp_proc_show, PDE(inode)->data);
542 }
543
544 static const struct file_operations cmtp_proc_fops = {
545         .owner          = THIS_MODULE,
546         .open           = cmtp_proc_open,
547         .read           = seq_read,
548         .llseek         = seq_lseek,
549         .release        = single_release,
550 };
551
552 int cmtp_attach_device(struct cmtp_session *session)
553 {
554         unsigned char buf[4];
555         long ret;
556
557         BT_DBG("session %p", session);
558
559         capimsg_setu32(buf, 0, 0);
560
561         cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM,
562                                 CAPI_FUNCTION_GET_PROFILE, buf, 4);
563
564         ret = wait_event_interruptible_timeout(session->wait,
565                         session->ncontroller, CMTP_INTEROP_TIMEOUT);
566
567         BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name);
568
569         if (!ret)
570                 return -ETIMEDOUT;
571
572         if (!session->ncontroller)
573                 return -ENODEV;
574
575         if (session->ncontroller > 1)
576                 BT_INFO("Setting up only CAPI controller 1");
577
578         session->ctrl.owner      = THIS_MODULE;
579         session->ctrl.driverdata = session;
580         strcpy(session->ctrl.name, session->name);
581
582         session->ctrl.driver_name   = "cmtp";
583         session->ctrl.load_firmware = cmtp_load_firmware;
584         session->ctrl.reset_ctr     = cmtp_reset_ctr;
585         session->ctrl.register_appl = cmtp_register_appl;
586         session->ctrl.release_appl  = cmtp_release_appl;
587         session->ctrl.send_message  = cmtp_send_message;
588
589         session->ctrl.procinfo      = cmtp_procinfo;
590         session->ctrl.proc_fops = &cmtp_proc_fops;
591
592         if (attach_capi_ctr(&session->ctrl) < 0) {
593                 BT_ERR("Can't attach new controller");
594                 return -EBUSY;
595         }
596
597         session->num = session->ctrl.cnr;
598
599         BT_DBG("session %p num %d", session, session->num);
600
601         capimsg_setu32(buf, 0, 1);
602
603         cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
604                                 CAPI_FUNCTION_GET_MANUFACTURER, buf, 4);
605
606         cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
607                                 CAPI_FUNCTION_GET_VERSION, buf, 4);
608
609         cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
610                                 CAPI_FUNCTION_GET_SERIAL_NUMBER, buf, 4);
611
612         cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
613                                 CAPI_FUNCTION_GET_PROFILE, buf, 4);
614
615         return 0;
616 }
617
618 void cmtp_detach_device(struct cmtp_session *session)
619 {
620         BT_DBG("session %p", session);
621
622         detach_capi_ctr(&session->ctrl);
623 }