more changes on original files
[linux-2.4.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/config.h>
24 #include <linux/module.h>
25
26 #include <linux/types.h>
27 #include <linux/errno.h>
28 #include <linux/kernel.h>
29 #include <linux/major.h>
30 #include <linux/sched.h>
31 #include <linux/slab.h>
32 #include <linux/poll.h>
33 #include <linux/fcntl.h>
34 #include <linux/skbuff.h>
35 #include <linux/socket.h>
36 #include <linux/ioctl.h>
37 #include <linux/file.h>
38 #include <net/sock.h>
39
40 #include <linux/capi.h>
41
42 #include "../drivers/isdn/avmb1/capilli.h"
43 #include "../drivers/isdn/avmb1/capicmd.h"
44 #include "../drivers/isdn/avmb1/capiutil.h"
45
46 #include "cmtp.h"
47
48 #ifndef CONFIG_BLUEZ_CMTP_DEBUG
49 #undef  BT_DBG
50 #define BT_DBG(D...)
51 #endif
52
53 #define REVISION "1.0"
54
55 #define CAPI_INTEROPERABILITY           0x20
56
57 #define CAPI_INTEROPERABILITY_REQ       CAPICMD(CAPI_INTEROPERABILITY, CAPI_REQ)
58 #define CAPI_INTEROPERABILITY_CONF      CAPICMD(CAPI_INTEROPERABILITY, CAPI_CONF)
59 #define CAPI_INTEROPERABILITY_IND       CAPICMD(CAPI_INTEROPERABILITY, CAPI_IND)
60 #define CAPI_INTEROPERABILITY_RESP      CAPICMD(CAPI_INTEROPERABILITY, CAPI_RESP)
61
62 #define CAPI_INTEROPERABILITY_REQ_LEN   (CAPI_MSG_BASELEN + 2)
63 #define CAPI_INTEROPERABILITY_CONF_LEN  (CAPI_MSG_BASELEN + 4)
64 #define CAPI_INTEROPERABILITY_IND_LEN   (CAPI_MSG_BASELEN + 2)
65 #define CAPI_INTEROPERABILITY_RESP_LEN  (CAPI_MSG_BASELEN + 2)
66
67 #define CAPI_FUNCTION_REGISTER          0
68 #define CAPI_FUNCTION_RELEASE           1
69 #define CAPI_FUNCTION_GET_PROFILE       2
70 #define CAPI_FUNCTION_GET_MANUFACTURER  3
71 #define CAPI_FUNCTION_GET_VERSION       4
72 #define CAPI_FUNCTION_GET_SERIAL_NUMBER 5
73 #define CAPI_FUNCTION_MANUFACTURER      6
74 #define CAPI_FUNCTION_LOOPBACK          7
75
76 static struct capi_driver_interface *di;
77
78
79 #define CMTP_MSGNUM     1
80 #define CMTP_APPLID     2
81 #define CMTP_MAPPING    3
82
83 static struct cmtp_application *cmtp_application_add(struct cmtp_session *session, __u16 appl)
84 {
85         struct cmtp_application *app = kmalloc(sizeof(*app), GFP_KERNEL);
86
87         BT_DBG("session %p application %p appl %d", session, app, appl);
88
89         if (!app)
90                 return NULL;
91
92         memset(app, 0, sizeof(*app));
93
94         app->state = BT_OPEN;
95         app->appl = appl;
96
97         list_add_tail(&app->list, &session->applications);
98
99         return app;
100 }
101
102 static void cmtp_application_del(struct cmtp_session *session, struct cmtp_application *app)
103 {
104         BT_DBG("session %p application %p", session, app);
105
106         if (app) {
107                 list_del(&app->list);
108                 kfree(app);
109         }
110 }
111
112 static struct cmtp_application *cmtp_application_get(struct cmtp_session *session, int pattern, __u16 value)
113 {
114         struct cmtp_application *app;
115         struct list_head *p, *n;
116
117         list_for_each_safe(p, n, &session->applications) {
118                 app = list_entry(p, struct cmtp_application, list);
119                 switch (pattern) {
120                 case CMTP_MSGNUM:
121                         if (app->msgnum == value)
122                                 return app;
123                         break;
124                 case CMTP_APPLID:
125                         if (app->appl == value)
126                                 return app;
127                         break;
128                 case CMTP_MAPPING:
129                         if (app->mapping == value)
130                                 return app;
131                         break;
132                 }
133         }
134
135         return NULL;
136 }
137
138 static int cmtp_msgnum_get(struct cmtp_session *session)
139 {
140         session->msgnum++;
141
142         if ((session->msgnum & 0xff) > 200)
143                 session->msgnum = CMTP_INITIAL_MSGNUM + 1;
144
145         return session->msgnum;
146 }
147
148
149 static void cmtp_send_interopmsg(struct cmtp_session *session,
150                                         __u8 subcmd, __u16 appl, __u16 msgnum,
151                                         __u16 function, unsigned char *buf, int len)
152 {
153         struct sk_buff *skb;
154         unsigned char *s;
155
156         BT_DBG("session %p subcmd 0x%02x appl %d msgnum %d", session, subcmd, appl, msgnum);
157
158         if (!(skb = alloc_skb(CAPI_MSG_BASELEN + 6 + len, GFP_ATOMIC))) {
159                 BT_ERR("Can't allocate memory for interoperability packet");
160                 return;
161         }
162
163         s = skb_put(skb, CAPI_MSG_BASELEN + 6 + len);
164
165         capimsg_setu16(s, 0, CAPI_MSG_BASELEN + 6 + len);
166         capimsg_setu16(s, 2, appl);
167         capimsg_setu8 (s, 4, CAPI_INTEROPERABILITY);
168         capimsg_setu8 (s, 5, subcmd);
169         capimsg_setu16(s, 6, msgnum);
170
171         /* Interoperability selector (Bluetooth Device Management) */
172         capimsg_setu16(s, 8, 0x0001);
173
174         capimsg_setu8 (s, 10, 3 + len);
175         capimsg_setu16(s, 11, function);
176         capimsg_setu8 (s, 13, len);
177
178         if (len > 0)
179                 memcpy(s + 14, buf, len);
180
181         cmtp_send_capimsg(session, skb);
182 }
183
184 static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *skb)
185 {
186         struct capi_ctr *ctrl = session->ctrl;
187         struct cmtp_application *application;
188         __u16 appl, msgnum, func, info;
189         __u32 controller;
190
191         BT_DBG("session %p skb %p len %d", session, skb, skb->len);
192
193         switch (CAPIMSG_SUBCOMMAND(skb->data)) {
194         case CAPI_CONF:
195                 if (skb->len < CAPI_MSG_BASELEN + 10)
196                         break;
197
198                 func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5);
199                 info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8);
200
201                 switch (func) {
202                 case CAPI_FUNCTION_REGISTER:
203                         msgnum = CAPIMSG_MSGID(skb->data);
204
205                         application = cmtp_application_get(session, CMTP_MSGNUM, msgnum);
206                         if (application) {
207                                 application->state = BT_CONNECTED;
208                                 application->msgnum = 0;
209                                 application->mapping = CAPIMSG_APPID(skb->data);
210                                 wake_up_interruptible(&session->wait);
211                         }
212
213                         break;
214
215                 case CAPI_FUNCTION_RELEASE:
216                         appl = CAPIMSG_APPID(skb->data);
217
218                         application = cmtp_application_get(session, CMTP_MAPPING, appl);
219                         if (application) {
220                                 application->state = BT_CLOSED;
221                                 application->msgnum = 0;
222                                 wake_up_interruptible(&session->wait);
223                         }
224
225                         break;
226
227                 case CAPI_FUNCTION_GET_PROFILE:
228                         if (skb->len < CAPI_MSG_BASELEN + 11 + sizeof(capi_profile))
229                                 break;
230
231                         controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11);
232                         msgnum = CAPIMSG_MSGID(skb->data);
233
234                         if (!info && (msgnum == CMTP_INITIAL_MSGNUM)) {
235                                 session->ncontroller = controller;
236                                 wake_up_interruptible(&session->wait);
237                                 break;
238                         }
239
240                         if (!info && ctrl) {
241                                 memcpy(&ctrl->profile,
242                                         skb->data + CAPI_MSG_BASELEN + 11,
243                                         sizeof(capi_profile));
244                                 session->state = BT_CONNECTED;
245                                 ctrl->ready(ctrl);
246                         }
247
248                         break;
249
250                 case CAPI_FUNCTION_GET_MANUFACTURER:
251                         if (skb->len < CAPI_MSG_BASELEN + 15)
252                                 break;
253
254                         controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 10);
255
256                         if (!info && ctrl) {
257                                 int len = min_t(uint, CAPI_MANUFACTURER_LEN,
258                                                 skb->data[CAPI_MSG_BASELEN + 14]);
259
260                                 memset(ctrl->manu, 0, CAPI_MANUFACTURER_LEN);
261                                 strncpy(ctrl->manu,
262                                         skb->data + CAPI_MSG_BASELEN + 15, len);
263                         }
264
265                         break;
266
267                 case CAPI_FUNCTION_GET_VERSION:
268                         if (skb->len < CAPI_MSG_BASELEN + 32)
269                                 break;
270
271                         controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
272
273                         if (!info && ctrl) {
274                                 ctrl->version.majorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 16);
275                                 ctrl->version.minorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 20);
276                                 ctrl->version.majormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 24);
277                                 ctrl->version.minormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 28);
278                         }
279
280                         break;
281
282                 case CAPI_FUNCTION_GET_SERIAL_NUMBER:
283                         if (skb->len < CAPI_MSG_BASELEN + 17)
284                                 break;
285
286                         controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
287
288                         if (!info && ctrl) {
289                                 int len = min_t(uint, CAPI_SERIAL_LEN,
290                                                 skb->data[CAPI_MSG_BASELEN + 16]);
291
292                                 memset(ctrl->serial, 0, CAPI_SERIAL_LEN);
293                                 strncpy(ctrl->serial,
294                                         skb->data + CAPI_MSG_BASELEN + 17, len);
295                         }
296
297                         break;
298                 }
299
300                 break;
301
302         case CAPI_IND:
303                 if (skb->len < CAPI_MSG_BASELEN + 6)
304                         break;
305
306                 func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3);
307
308                 if (func == CAPI_FUNCTION_LOOPBACK) {
309                         int len = min_t(uint, skb->len - CAPI_MSG_BASELEN - 6,
310                                                 skb->data[CAPI_MSG_BASELEN + 5]);
311                         appl = CAPIMSG_APPID(skb->data);
312                         msgnum = CAPIMSG_MSGID(skb->data);
313                         cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func,
314                                                 skb->data + CAPI_MSG_BASELEN + 6, len);
315                 }
316
317                 break;
318         }
319
320         kfree_skb(skb);
321 }
322
323 void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb)
324 {
325         struct capi_ctr *ctrl = session->ctrl;
326         struct cmtp_application *application;
327         __u16 cmd, appl, info;
328         __u32 ncci, contr;
329
330         BT_DBG("session %p skb %p len %d", session, skb, skb->len);
331
332         if (skb->len < CAPI_MSG_BASELEN)
333                 return;
334
335         if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) {
336                 cmtp_recv_interopmsg(session, skb);
337                 return;
338         }
339
340         if (session->flags & (1 << CMTP_LOOPBACK)) {
341                 kfree_skb(skb);
342                 return;
343         }
344
345         cmd = CAPICMD(CAPIMSG_COMMAND(skb->data), CAPIMSG_SUBCOMMAND(skb->data));
346         appl = CAPIMSG_APPID(skb->data);
347         contr = CAPIMSG_CONTROL(skb->data);
348
349         application = cmtp_application_get(session, CMTP_MAPPING, appl);
350         if (application) {
351                 appl = application->appl;
352                 CAPIMSG_SETAPPID(skb->data, appl);
353         } else {
354                 BT_ERR("Can't find application with id %d", appl);
355                 kfree_skb(skb);
356                 return;
357         }
358
359         if ((contr & 0x7f) == 0x01) {
360                 contr = (contr & 0xffffff80) | session->num;
361                 CAPIMSG_SETCONTROL(skb->data, contr);
362         }
363
364         if (!ctrl) {
365                 BT_ERR("Can't find controller %d for message", session->num);
366                 kfree_skb(skb);
367                 return;
368         }
369
370         switch (cmd) {
371         case CAPI_CONNECT_B3_CONF:
372                 ncci = CAPIMSG_NCCI(skb->data);
373                 info = CAPIMSG_U16(skb->data, 12);
374
375                 BT_DBG("CONNECT_B3_CONF ncci 0x%02x info 0x%02x", ncci, info);
376
377                 if (info == 0)
378                         ctrl->new_ncci(ctrl, appl, ncci, 8);
379
380                 ctrl->handle_capimsg(ctrl, appl, skb);
381                 break;
382
383         case CAPI_CONNECT_B3_IND:
384                 ncci = CAPIMSG_NCCI(skb->data);
385
386                 BT_DBG("CONNECT_B3_IND ncci 0x%02x", ncci);
387
388                 ctrl->new_ncci(ctrl, appl, ncci, 8);
389                 ctrl->handle_capimsg(ctrl, appl, skb);
390                 break;
391
392         case CAPI_DISCONNECT_B3_IND:
393                 ncci = CAPIMSG_NCCI(skb->data);
394
395                 BT_DBG("DISCONNECT_B3_IND ncci 0x%02x", ncci);
396
397                 if (ncci == 0xffffffff)
398                         BT_ERR("DISCONNECT_B3_IND with ncci 0xffffffff");
399
400                 ctrl->handle_capimsg(ctrl, appl, skb);
401                 ctrl->free_ncci(ctrl, appl, ncci);
402                 break;
403
404         default:
405                 ctrl->handle_capimsg(ctrl, appl, skb);
406                 break;
407         }
408 }
409
410 void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb)
411 {
412         struct cmtp_scb *scb = (void *) skb->cb;
413
414         BT_DBG("session %p skb %p len %d", session, skb, skb->len);
415
416         scb->id = -1;
417         scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3);
418
419         skb_queue_tail(&session->transmit, skb);
420
421         cmtp_schedule(session);
422 }
423
424
425 static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
426 {
427         BT_DBG("ctrl %p data %p", ctrl, data);
428
429         return -EIO;
430 }
431
432 static void cmtp_reset_ctr(struct capi_ctr *ctrl)
433 {
434         BT_DBG("ctrl %p", ctrl);
435
436         ctrl->reseted(ctrl);
437 }
438
439 static void cmtp_remove_ctr(struct capi_ctr *ctrl)
440 {
441         struct cmtp_session *session = ctrl->driverdata;
442
443         BT_DBG("ctrl %p", ctrl);
444
445         ctrl->suspend_output(ctrl);
446
447         atomic_inc(&session->terminate);
448         cmtp_schedule(session);
449 }
450
451 static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
452 {
453         DECLARE_WAITQUEUE(wait, current);
454         struct cmtp_session *session = ctrl->driverdata;
455         struct cmtp_application *application;
456         unsigned long timeo = CMTP_INTEROP_TIMEOUT;
457         unsigned char buf[8];
458         int err = 0, nconn, want = rp->level3cnt;
459
460         BT_DBG("ctrl %p appl %d level3cnt %d datablkcnt %d datablklen %d",
461                 ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen);
462
463         application = cmtp_application_add(session, appl);
464         if (!application) {
465                 BT_ERR("Can't allocate memory for new application");
466                 ctrl->appl_released(ctrl, appl);
467                 return;
468         }
469
470         if (want < 0)
471                 nconn = ctrl->profile.nbchannel * -want;
472         else
473                 nconn = want;
474
475         if (nconn == 0)
476                 nconn = ctrl->profile.nbchannel;
477
478         capimsg_setu16(buf, 0, nconn);
479         capimsg_setu16(buf, 2, rp->datablkcnt);
480         capimsg_setu16(buf, 4, rp->datablklen);
481
482         application->state = BT_CONFIG;
483         application->msgnum = cmtp_msgnum_get(session);
484
485         cmtp_send_interopmsg(session, CAPI_REQ, 0x0000, application->msgnum,
486                                 CAPI_FUNCTION_REGISTER, buf, 6);
487
488         add_wait_queue(&session->wait, &wait);
489         while (1) {
490                 set_current_state(TASK_INTERRUPTIBLE);
491
492                 if (!timeo) {
493                         err = -EAGAIN;
494                         break;
495                 }
496
497                 if (application->state == BT_CLOSED) {
498                         err = -application->err;
499                         break;
500                 }
501
502                 if (application->state == BT_CONNECTED)
503                         break;
504
505                 if (signal_pending(current)) {
506                         err = -EINTR;
507                         break;
508                 }
509
510                 timeo = schedule_timeout(timeo);
511         }
512         set_current_state(TASK_RUNNING);
513         remove_wait_queue(&session->wait, &wait);
514
515         if (err) {
516                 ctrl->appl_released(ctrl, appl);
517                 cmtp_application_del(session, application);
518                 return;
519         }
520
521         ctrl->appl_registered(ctrl, appl);
522 }
523
524 static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl)
525 {
526         DECLARE_WAITQUEUE(wait, current);
527         struct cmtp_session *session = ctrl->driverdata;
528         struct cmtp_application *application;
529         unsigned long timeo = CMTP_INTEROP_TIMEOUT;
530
531         BT_DBG("ctrl %p appl %d", ctrl, appl);
532
533         application = cmtp_application_get(session, CMTP_APPLID, appl);
534         if (!application) {
535                 BT_ERR("Can't find application");
536                 return;
537         }
538
539         application->msgnum = cmtp_msgnum_get(session);
540
541         cmtp_send_interopmsg(session, CAPI_REQ, application->mapping, application->msgnum,
542                                 CAPI_FUNCTION_RELEASE, NULL, 0);
543
544         add_wait_queue(&session->wait, &wait);
545         while (timeo) {
546                 set_current_state(TASK_INTERRUPTIBLE);
547
548                 if (application->state == BT_CLOSED)
549                         break;
550
551                 if (signal_pending(current))
552                         break;
553
554                 timeo = schedule_timeout(timeo);
555         }
556         set_current_state(TASK_RUNNING);
557         remove_wait_queue(&session->wait, &wait);
558
559         cmtp_application_del(session, application);
560         ctrl->appl_released(ctrl, appl);
561 }
562
563 static void cmtp_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
564 {
565         struct cmtp_session *session = ctrl->driverdata;
566         struct cmtp_application *application;
567         __u16 appl;
568         __u32 contr;
569
570         BT_DBG("ctrl %p skb %p", ctrl, skb);
571
572         appl = CAPIMSG_APPID(skb->data);
573         contr = CAPIMSG_CONTROL(skb->data);
574
575         application = cmtp_application_get(session, CMTP_APPLID, appl);
576         if ((!application) || (application->state != BT_CONNECTED)) {
577                 BT_ERR("Can't find application with id %d", appl);
578                 kfree_skb(skb);
579                 return;
580         }
581
582         CAPIMSG_SETAPPID(skb->data, application->mapping);
583
584         if ((contr & 0x7f) == session->num) {
585                 contr = (contr & 0xffffff80) | 0x01;
586                 CAPIMSG_SETCONTROL(skb->data, contr);
587         }
588
589         cmtp_send_capimsg(session, skb);
590 }
591
592 static char *cmtp_procinfo(struct capi_ctr *ctrl)
593 {
594         return "CAPI Message Transport Protocol";
595 }
596
597 static int cmtp_ctr_read_proc(char *page, char **start, off_t off, int count, int *eof, struct capi_ctr *ctrl)
598 {
599         struct cmtp_session *session = ctrl->driverdata;
600         struct cmtp_application *app;
601         struct list_head *p, *n;
602         int len = 0;
603
604         len += sprintf(page + len, "%s (Revision %s)\n\n", cmtp_procinfo(ctrl), REVISION);
605         len += sprintf(page + len, "addr %s\n", session->name);
606         len += sprintf(page + len, "ctrl %d\n", session->num);
607
608         list_for_each_safe(p, n, &session->applications) {
609                 app = list_entry(p, struct cmtp_application, list);
610                 len += sprintf(page + len, "appl %d -> %d\n", app->appl, app->mapping);
611         }
612
613         if (off + count >= len)
614                 *eof = 1;
615
616         if (len < off)
617                 return 0;
618
619         *start = page + off;
620
621         return ((count < len - off) ? count : len - off);
622 }
623
624 static struct capi_driver cmtp_driver = {
625         name:           "cmtp",
626         revision:       REVISION,
627         load_firmware:  cmtp_load_firmware,
628         reset_ctr:      cmtp_reset_ctr,
629         remove_ctr:     cmtp_remove_ctr,
630         register_appl:  cmtp_register_appl,
631         release_appl:   cmtp_release_appl,
632         send_message:   cmtp_send_message,
633         procinfo:       cmtp_procinfo,
634         ctr_read_proc:  cmtp_ctr_read_proc,
635
636         driver_read_proc:       0,
637         add_card:               0,
638 };
639
640
641 int cmtp_attach_device(struct cmtp_session *session)
642 {
643         DECLARE_WAITQUEUE(wait, current);
644         unsigned long timeo = CMTP_INTEROP_TIMEOUT;
645         unsigned char buf[4];
646
647         BT_DBG("session %p", session);
648
649         capimsg_setu32(buf, 0, 0);
650
651         cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM,
652                                 CAPI_FUNCTION_GET_PROFILE, buf, 4);
653
654         add_wait_queue(&session->wait, &wait);
655         while (timeo) {
656                 set_current_state(TASK_INTERRUPTIBLE);
657
658                 if (session->ncontroller)
659                         break;
660
661                 if (signal_pending(current))
662                         break;
663
664                 timeo = schedule_timeout(timeo);
665         }
666         set_current_state(TASK_RUNNING);
667         remove_wait_queue(&session->wait, &wait);
668
669         BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name);
670
671         if (!timeo)
672                 return -ETIMEDOUT;
673
674         if (!session->ncontroller)
675                 return -ENODEV;
676
677
678         if (session->ncontroller > 1)
679                 BT_INFO("Setting up only CAPI controller 1");
680
681         if (!(session->ctrl = di->attach_ctr(&cmtp_driver, session->name, session))) {
682                 BT_ERR("Can't attach new controller");
683                 return -EBUSY;
684         }
685
686         session->num = session->ctrl->cnr;
687
688         BT_DBG("session %p ctrl %p num %d", session, session->ctrl, session->num);
689
690         capimsg_setu32(buf, 0, 1);
691
692         cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
693                                 CAPI_FUNCTION_GET_MANUFACTURER, buf, 4);
694
695         cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
696                                 CAPI_FUNCTION_GET_VERSION, buf, 4);
697
698         cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
699                                 CAPI_FUNCTION_GET_SERIAL_NUMBER, buf, 4);
700
701         cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
702                                 CAPI_FUNCTION_GET_PROFILE, buf, 4);
703
704         return 0;
705 }
706
707 void cmtp_detach_device(struct cmtp_session *session)
708 {
709         struct capi_ctr *ctrl = session->ctrl;
710
711         BT_DBG("session %p ctrl %p", session, ctrl);
712
713         if (!ctrl)
714                 return;
715
716         ctrl->reseted(ctrl);
717
718         di->detach_ctr(ctrl);
719 }
720
721 int cmtp_init_capi(void)
722 {
723         if (!(di = attach_capi_driver(&cmtp_driver))) {
724                 BT_ERR("Can't attach CAPI driver");
725                 return -EIO;
726         }
727
728         return 0;
729 }
730
731 void cmtp_cleanup_capi(void)
732 {
733         detach_capi_driver(&cmtp_driver);
734 }