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 
cmtp_application_add(struct cmtp_session * session,__u16 appl)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 
cmtp_application_del(struct cmtp_session * session,struct cmtp_application * app)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 
cmtp_application_get(struct cmtp_session * session,int pattern,__u16 value)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 
cmtp_msgnum_get(struct cmtp_session * session)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 
cmtp_send_interopmsg(struct cmtp_session * session,__u8 subcmd,__u16 appl,__u16 msgnum,__u16 function,unsigned char * buf,int len)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 
cmtp_recv_interopmsg(struct cmtp_session * session,struct sk_buff * skb)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 
cmtp_recv_capimsg(struct cmtp_session * session,struct sk_buff * skb)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 
cmtp_send_capimsg(struct cmtp_session * session,struct sk_buff * skb)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 
cmtp_load_firmware(struct capi_ctr * ctrl,capiloaddata * data)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 
cmtp_reset_ctr(struct capi_ctr * ctrl)432 static void cmtp_reset_ctr(struct capi_ctr *ctrl)
433 {
434 	BT_DBG("ctrl %p", ctrl);
435 
436 	ctrl->reseted(ctrl);
437 }
438 
cmtp_remove_ctr(struct capi_ctr * ctrl)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 
cmtp_register_appl(struct capi_ctr * ctrl,__u16 appl,capi_register_params * rp)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 
cmtp_release_appl(struct capi_ctr * ctrl,__u16 appl)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 
cmtp_send_message(struct capi_ctr * ctrl,struct sk_buff * skb)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 
cmtp_procinfo(struct capi_ctr * ctrl)592 static char *cmtp_procinfo(struct capi_ctr *ctrl)
593 {
594 	return "CAPI Message Transport Protocol";
595 }
596 
cmtp_ctr_read_proc(char * page,char ** start,off_t off,int count,int * eof,struct capi_ctr * ctrl)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 
cmtp_attach_device(struct cmtp_session * session)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 
cmtp_detach_device(struct cmtp_session * session)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 
cmtp_init_capi(void)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 
cmtp_cleanup_capi(void)731 void cmtp_cleanup_capi(void)
732 {
733 	detach_capi_driver(&cmtp_driver);
734 }
735