This source file includes following definitions.
- isdn_MOD_INC_USE_COUNT
- isdn_MOD_DEC_USE_COUNT
- isdn_dumppkt
- isdn_new_buf
- isdn_free_queue
- isdn_dc2minor
- isdn_timer_funct
- isdn_timer_ctrl
- isdn_receive_callback
- isdn_all_eaz
- isdn_status_callback
- isdn_getnum
- isdn_readbchan
- isdn_minor2drv
- isdn_minor2chan
- isdn_statstr
- isdn_info_update
- isdn_read
- isdn_lseek
- isdn_write
- isdn_select
- isdn_set_allcfg
- isdn_get_allcfg
- isdn_ioctl
- isdn_open
- isdn_close
- isdn_map_eaz2msn
- isdn_get_free_channel
- isdn_free_channel
- isdn_unexclusive_channel
- isdn_receive_skb_callback
- isdn_writebuf_stub
- register_isdn
- isdn_getrev
- isdn_export_syms
- isdn_init
- cleanup_module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 #ifndef STANDALONE
43 #include <linux/config.h>
44 #endif
45 #include <linux/module.h>
46 #include <linux/version.h>
47 #ifndef __GENKSYMS__
48 #include <linux/isdn.h>
49 #endif
50 #include "isdn_common.h"
51 #include "isdn_tty.h"
52 #include "isdn_net.h"
53 #include "isdn_ppp.h"
54 #include "isdn_cards.h"
55
56
57
58
59 #undef ISDN_DEBUG_STATCALLB
60
61 isdn_dev *dev = (isdn_dev *) 0;
62
63 static int has_exported = 0;
64 static char *isdn_revision = "$Revision: 1.4 $";
65
66 extern char *isdn_net_revision;
67 extern char *isdn_tty_revision;
68 #ifdef CONFIG_ISDN_PPP
69 extern char *isdn_ppp_revision;
70 #else
71 static char *isdn_ppp_revision = ": none $";
72 #endif
73
74 void isdn_MOD_INC_USE_COUNT(void)
75 {
76 MOD_INC_USE_COUNT;
77 }
78
79 void isdn_MOD_DEC_USE_COUNT(void)
80 {
81 MOD_DEC_USE_COUNT;
82 }
83
84 #if defined(ISDN_DEBUG_NET_DUMP) || defined(ISDN_DEBUG_MODEM_DUMP)
85 void isdn_dumppkt(char *s, u_char * p, int len, int dumplen)
86 {
87 int dumpc;
88
89 printk(KERN_DEBUG "%s(%d) ", s, len);
90 for (dumpc = 0; (dumpc < dumplen) && (len); len--, dumpc++)
91 printk(" %02x", *p++);
92 printk("\n");
93 }
94 #endif
95
96
97 u_char *
98 isdn_new_buf(pqueue ** queue, int length)
99 {
100 pqueue *p;
101 pqueue *q;
102
103 if ((p = *queue)) {
104 while (p) {
105 q = p;
106 p = (pqueue *) p->next;
107 }
108 p = (pqueue *) kmalloc(sizeof(pqueue) + length, GFP_ATOMIC);
109 q->next = (u_char *) p;
110 } else
111 p = *queue = (pqueue *) kmalloc(sizeof(pqueue) + length, GFP_ATOMIC);
112 if (p) {
113 p->size = sizeof(pqueue) + length;
114 p->length = length;
115 p->next = NULL;
116 p->rptr = p->buffer;
117 return p->buffer;
118 } else {
119 return (u_char *) NULL;
120 }
121 }
122
123 static void isdn_free_queue(pqueue ** queue)
124 {
125 pqueue *p;
126 pqueue *q;
127
128 p = *queue;
129 while (p) {
130 q = p;
131 p = (pqueue *) p->next;
132 kfree_s(q, q->size);
133 }
134 *queue = (pqueue *) 0;
135 }
136
137 int isdn_dc2minor(int di, int ch)
138 {
139 int i;
140 for (i = 0; i < ISDN_MAX_CHANNELS; i++)
141 if (dev->chanmap[i] == ch && dev->drvmap[i] == di)
142 return i;
143 return -1;
144 }
145
146 static int isdn_timer_cnt1 = 0;
147 static int isdn_timer_cnt2 = 0;
148
149 static void isdn_timer_funct(ulong dummy)
150 {
151 int tf = dev->tflags;
152
153 if (tf & ISDN_TIMER_FAST) {
154 if (tf & ISDN_TIMER_MODEMREAD)
155 isdn_tty_readmodem();
156 if (tf & ISDN_TIMER_MODEMPLUS)
157 isdn_tty_modem_escape();
158 if (tf & ISDN_TIMER_MODEMXMIT)
159 isdn_tty_modem_xmit();
160 }
161 if (tf & ISDN_TIMER_SLOW) {
162 if (++isdn_timer_cnt1 > ISDN_TIMER_02SEC) {
163 isdn_timer_cnt1 = 0;
164 if (tf & ISDN_TIMER_NETDIAL)
165 isdn_net_dial();
166 }
167 if (++isdn_timer_cnt2 > ISDN_TIMER_1SEC) {
168 isdn_timer_cnt2 = 0;
169 if (tf & ISDN_TIMER_NETHANGUP)
170 isdn_net_autohup();
171 if (tf & ISDN_TIMER_MODEMRING)
172 isdn_tty_modem_ring();
173 #if (defined CONFIG_ISDN_PPP ) && (defined ISDN_CONFIG_MPP)
174 if (tf & ISDN_TIMER_IPPP)
175 isdn_ppp_timer_timeout();
176 #endif
177 }
178 }
179 if (tf) {
180 int flags;
181
182 save_flags(flags);
183 cli();
184 del_timer(&dev->timer);
185 dev->timer.function = isdn_timer_funct;
186 dev->timer.expires = jiffies + ISDN_TIMER_RES;
187 add_timer(&dev->timer);
188 restore_flags(flags);
189 }
190 }
191
192 void isdn_timer_ctrl(int tf, int onoff)
193 {
194 int flags;
195
196 save_flags(flags);
197 cli();
198 if ((tf & ISDN_TIMER_SLOW) && (!(dev->tflags & ISDN_TIMER_SLOW))) {
199
200 isdn_timer_cnt1 = 0;
201 isdn_timer_cnt2 = 0;
202 }
203 if (onoff)
204 dev->tflags |= tf;
205 else
206 dev->tflags &= ~tf;
207 if (dev->tflags) {
208 del_timer(&dev->timer);
209 dev->timer.function = isdn_timer_funct;
210 dev->timer.expires = jiffies + ISDN_TIMER_RES;
211 add_timer(&dev->timer);
212 }
213 restore_flags(flags);
214 }
215
216
217
218
219
220
221
222
223
224
225 static void isdn_receive_callback(int di, int channel, u_char * buf, int len)
226 {
227 ulong flags;
228 char *p;
229 int i;
230 int midx;
231
232 if (dev->global_flags & ISDN_GLOBAL_STOPPED)
233 return;
234 if ((i = isdn_dc2minor(di,channel))==-1)
235 return;
236
237 if (isdn_net_receive_callback(i, buf, len))
238 return;
239
240 if (len) {
241 save_flags(flags);
242 cli();
243 midx = dev->m_idx[i];
244 if (dev->mdm.atmodem[midx].mdmreg[13] & 2)
245
246 if ((buf[0] == 1) && ((buf[1] == 0) || (buf[1] == 1))) {
247 #ifdef ISDN_DEBUG_MODEM_DUMP
248 isdn_dumppkt("T70strip1:", buf, len, len);
249 #endif
250 buf += 4;
251 len -= 4;
252 #ifdef ISDN_DEBUG_MODEM_DUMP
253 isdn_dumppkt("T70strip2:", buf, len, len);
254 #endif
255 }
256
257 if (!dev->drv[di]->rpqueue[channel])
258 if (isdn_tty_try_read(midx, buf, len)) {
259 restore_flags(flags);
260 return;
261 }
262
263
264
265 p = isdn_new_buf(&dev->drv[di]->rpqueue[channel], len);
266 if (!p) {
267 printk(KERN_WARNING "isdn: malloc of rcvbuf failed, dropping.\n");
268 dev->drv[di]->rcverr[channel]++;
269 restore_flags(flags);
270 return;
271 } else {
272 memcpy(p, buf, len);
273 dev->drv[di]->rcvcount[channel] += len;
274 }
275
276 if ((dev->modempoll) && (midx >= 0)) {
277 if (dev->mdm.rcvsched[midx])
278 isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1);
279 }
280 wake_up_interruptible(&dev->drv[di]->rcv_waitq[channel]);
281 restore_flags(flags);
282 }
283 }
284
285 void isdn_all_eaz(int di, int ch)
286 {
287 isdn_ctrl cmd;
288
289 cmd.driver = di;
290 cmd.arg = ch;
291 cmd.command = ISDN_CMD_SETEAZ;
292 cmd.num[0] = '\0';
293 (void) dev->drv[di]->interface->command(&cmd);
294 }
295
296 static int isdn_status_callback(isdn_ctrl * c)
297 {
298 int di;
299 int mi;
300 ulong flags;
301 int i;
302 int r;
303 isdn_ctrl cmd;
304
305 di = c->driver;
306 i = isdn_dc2minor(di, c->arg);
307 switch (c->command) {
308 case ISDN_STAT_BSENT:
309 if (i<0)
310 return -1;
311 if (dev->global_flags & ISDN_GLOBAL_STOPPED)
312 return 0;
313 if (isdn_net_stat_callback(i, c->command))
314 return 0;
315 #if FUTURE
316 isdn_tty_bsent(di, c->arg);
317 #endif
318 wake_up_interruptible(&dev->drv[di]->snd_waitq[c->arg]);
319 break;
320 case ISDN_STAT_STAVAIL:
321 save_flags(flags);
322 cli();
323 dev->drv[di]->stavail += c->arg;
324 restore_flags(flags);
325 wake_up_interruptible(&dev->drv[di]->st_waitq);
326 break;
327 case ISDN_STAT_RUN:
328 dev->drv[di]->running = 1;
329 for (i = 0; i < ISDN_MAX_CHANNELS; i++)
330 if (dev->drvmap[i] == di)
331 isdn_all_eaz(di, dev->chanmap[i]);
332 break;
333 case ISDN_STAT_STOP:
334 dev->drv[di]->running = 0;
335 break;
336 case ISDN_STAT_ICALL:
337 if (i<0)
338 return -1;
339 #ifdef ISDN_DEBUG_STATCALLB
340 printk(KERN_DEBUG "ICALL (net): %d %ld %s\n", di, c->arg, c->num);
341 #endif
342 if (dev->global_flags & ISDN_GLOBAL_STOPPED) {
343 cmd.driver = di;
344 cmd.arg = c->arg;
345 cmd.command = ISDN_CMD_HANGUP;
346 dev->drv[di]->interface->command(&cmd);
347 return 0;
348 }
349
350
351 r = isdn_net_find_icall(di, c->arg, i, c->num);
352 switch (r) {
353 case 0:
354
355
356
357 if ((mi = isdn_tty_find_icall(di, c->arg, c->num)) >= 0) {
358 dev->mdm.msr[mi] |= UART_MSR_RI;
359 isdn_tty_modem_result(2, &dev->mdm.info[mi]);
360 isdn_timer_ctrl(ISDN_TIMER_MODEMRING, 1);
361 } else if (dev->drv[di]->reject_bus) {
362 cmd.driver = di;
363 cmd.arg = c->arg;
364 cmd.command = ISDN_CMD_HANGUP;
365 dev->drv[di]->interface->command(&cmd);
366 }
367 break;
368 case 1:
369
370 isdn_net_dial();
371 cmd.driver = di;
372 cmd.arg = c->arg;
373 cmd.command = ISDN_CMD_ACCEPTD;
374 dev->drv[di]->interface->command(&cmd);
375 break;
376 case 2:
377 case 3:
378 cmd.driver = di;
379 cmd.arg = c->arg;
380 cmd.command = ISDN_CMD_HANGUP;
381 dev->drv[di]->interface->command(&cmd);
382 if (r == 2)
383
384 isdn_net_dial();
385 break;
386 }
387 return 0;
388 break;
389 case ISDN_STAT_CINF:
390 if (i<0)
391 return -1;
392 #ifdef ISDN_DEBUG_STATCALLB
393 printk(KERN_DEBUG "CINF: %ld %s\n", c->arg, c->num);
394 #endif
395 if (dev->global_flags & ISDN_GLOBAL_STOPPED)
396 return 0;
397 if (strcmp(c->num, "0"))
398 isdn_net_stat_callback(i, c->command);
399 break;
400 case ISDN_STAT_CAUSE:
401 #ifdef ISDN_DEBUG_STATCALLB
402 printk(KERN_DEBUG "CAUSE: %ld %s\n", c->arg, c->num);
403 #endif
404 printk(KERN_INFO "isdn: cause: %s\n", c->num);
405 break;
406 case ISDN_STAT_DCONN:
407 if (i<0)
408 return -1;
409 #ifdef ISDN_DEBUG_STATCALLB
410 printk(KERN_DEBUG "DCONN: %ld\n", c->arg);
411 #endif
412 if (dev->global_flags & ISDN_GLOBAL_STOPPED)
413 return 0;
414
415 if (isdn_net_stat_callback(i, c->command))
416 break;
417 if ((mi = dev->m_idx[i]) >= 0)
418
419 if (dev->mdm.info[mi].flags &
420 (ISDN_ASYNC_NORMAL_ACTIVE | ISDN_ASYNC_CALLOUT_ACTIVE)) {
421 if (dev->mdm.dialing[mi] == 1) {
422 dev->mdm.dialing[mi] = 2;
423 cmd.driver = di;
424 cmd.arg = c->arg;
425 cmd.command = ISDN_CMD_ACCEPTB;
426 dev->drv[di]->interface->command(&cmd);
427 return 0;
428 }
429 }
430 break;
431 case ISDN_STAT_DHUP:
432 if (i<0)
433 return -1;
434 #ifdef ISDN_DEBUG_STATCALLB
435 printk(KERN_DEBUG "DHUP: %ld\n", c->arg);
436 #endif
437 if (dev->global_flags & ISDN_GLOBAL_STOPPED)
438 return 0;
439 dev->drv[di]->flags &= ~(1 << (c->arg));
440 isdn_info_update();
441
442 if (isdn_net_stat_callback(i, c->command))
443 break;
444 if ((mi = dev->m_idx[i]) >= 0) {
445
446 if (dev->mdm.info[mi].flags &
447 (ISDN_ASYNC_NORMAL_ACTIVE | ISDN_ASYNC_CALLOUT_ACTIVE)) {
448 if (dev->mdm.dialing[mi] == 1) {
449 dev->mdm.dialing[mi] = 0;
450 isdn_tty_modem_result(7, &dev->mdm.info[mi]);
451 }
452 if (dev->mdm.online[mi])
453 isdn_tty_modem_result(3, &dev->mdm.info[mi]);
454 #ifdef ISDN_DEBUG_MODEM_HUP
455 printk(KERN_DEBUG "Mhup in ISDN_STAT_DHUP\n");
456 #endif
457 isdn_tty_modem_hup(&dev->mdm.info[mi]);
458 dev->mdm.msr[mi] &= ~(UART_MSR_DCD | UART_MSR_RI);
459 return 0;
460 }
461 }
462 break;
463 case ISDN_STAT_BCONN:
464 if (i<0)
465 return -1;
466 #ifdef ISDN_DEBUG_STATCALLB
467 printk(KERN_DEBUG "BCONN: %ld\n", c->arg);
468 #endif
469
470 if (dev->global_flags & ISDN_GLOBAL_STOPPED)
471 return 0;
472 dev->drv[di]->flags |= (1 << (c->arg));
473 isdn_info_update();
474 if (isdn_net_stat_callback(i, c->command))
475 break;
476 if ((mi = dev->m_idx[i]) >= 0) {
477
478
479
480 if (dev->mdm.info[mi].flags &
481 (ISDN_ASYNC_NORMAL_ACTIVE | ISDN_ASYNC_CALLOUT_ACTIVE)) {
482 dev->mdm.msr[mi] |= UART_MSR_DCD;
483 if (dev->mdm.dialing[mi])
484 dev->mdm.dialing[mi] = 0;
485 dev->mdm.rcvsched[mi] = 1;
486 isdn_tty_modem_result(5, &dev->mdm.info[mi]);
487 }
488 }
489 break;
490 case ISDN_STAT_BHUP:
491 if (i<0)
492 return -1;
493 #ifdef ISDN_DEBUG_STATCALLB
494 printk(KERN_DEBUG "BHUP: %ld\n", c->arg);
495 #endif
496 if (dev->global_flags & ISDN_GLOBAL_STOPPED)
497 return 0;
498 dev->drv[di]->flags &= ~(1 << (c->arg));
499 isdn_info_update();
500 if ((mi = dev->m_idx[i]) >= 0) {
501
502 if (dev->mdm.info[mi].flags &
503 (ISDN_ASYNC_NORMAL_ACTIVE | ISDN_ASYNC_CALLOUT_ACTIVE)) {
504 dev->mdm.msr[mi] &= ~(UART_MSR_DCD | UART_MSR_RI);
505 if (dev->mdm.online[mi])
506 isdn_tty_modem_result(3, &dev->mdm.info[mi]);
507 #ifdef ISDN_DEBUG_MODEM_HUP
508 printk(KERN_DEBUG "Mhup in ISDN_STAT_BHUP\n");
509 #endif
510 isdn_tty_modem_hup(&dev->mdm.info[mi]);
511 }
512 }
513 break;
514 case ISDN_STAT_NODCH:
515 if (i<0)
516 return -1;
517 #ifdef ISDN_DEBUG_STATCALLB
518 printk(KERN_DEBUG "NODCH: %ld\n", c->arg);
519 #endif
520 if (dev->global_flags & ISDN_GLOBAL_STOPPED)
521 return 0;
522 if (isdn_net_stat_callback(i, c->command))
523 break;
524 if ((mi = dev->m_idx[i]) >= 0) {
525 if (dev->mdm.info[mi].flags &
526 (ISDN_ASYNC_NORMAL_ACTIVE | ISDN_ASYNC_CALLOUT_ACTIVE)) {
527 if (dev->mdm.dialing[mi]) {
528 dev->mdm.dialing[mi] = 0;
529 isdn_tty_modem_result(6, &dev->mdm.info[mi]);
530 }
531 dev->mdm.msr[mi] &= ~UART_MSR_DCD;
532 if (dev->mdm.online[mi]) {
533 isdn_tty_modem_result(3, &dev->mdm.info[mi]);
534 dev->mdm.online[mi] = 0;
535 }
536 }
537 }
538 break;
539 case ISDN_STAT_ADDCH:
540 break;
541 case ISDN_STAT_UNLOAD:
542 save_flags(flags);
543 cli();
544 for (i = 0; i < ISDN_MAX_CHANNELS; i++)
545 if (dev->drvmap[i] == di) {
546 dev->drvmap[i] = -1;
547 dev->chanmap[i] = -1;
548 dev->mdm.info[i].isdn_driver = -1;
549 dev->mdm.info[i].isdn_channel = -1;
550 isdn_info_update();
551 }
552 dev->drivers--;
553 dev->channels -= dev->drv[di]->channels;
554 kfree(dev->drv[di]->rcverr);
555 kfree(dev->drv[di]->rcvcount);
556 for (i = 0; i < dev->drv[di]->channels; i++)
557 isdn_free_queue(&dev->drv[di]->rpqueue[i]);
558 kfree(dev->drv[di]->rcv_waitq);
559 kfree(dev->drv[di]->snd_waitq);
560 kfree(dev->drv[di]);
561 dev->drv[di] = NULL;
562 dev->drvid[di][0] = '\0';
563 isdn_info_update();
564 restore_flags(flags);
565 return 0;
566 default:
567 return -1;
568 }
569 return 0;
570 }
571
572
573
574
575 int isdn_getnum(char **p)
576 {
577 int v = -1;
578
579 while (*p[0] >= '0' && *p[0] <= '9')
580 v = ((v < 0) ? 0 : (v * 10)) + (int) ((*p[0]++) - '0');
581 return v;
582 }
583
584 int isdn_readbchan(int di, int channel, u_char * buf, u_char * fp, int len, int user)
585 {
586 int avail;
587 int left;
588 int count;
589 int copy_l;
590 int dflag;
591 int flags;
592 pqueue *p;
593 u_char *cp;
594
595 if (!dev->drv[di]->rpqueue[channel]) {
596 if (user)
597 interruptible_sleep_on(&dev->drv[di]->rcv_waitq[channel]);
598 else
599 return 0;
600 }
601 if (!dev->drv[di])
602 return 0;
603 save_flags(flags);
604 cli();
605 avail = dev->drv[di]->rcvcount[channel];
606 restore_flags(flags);
607 left = MIN(len, avail);
608 cp = buf;
609 count = 0;
610 while (left) {
611 if ((copy_l = dev->drv[di]->rpqueue[channel]->length) > left) {
612 copy_l = left;
613 dflag = 0;
614 } else
615 dflag = 1;
616 p = dev->drv[di]->rpqueue[channel];
617 if (user)
618 memcpy_tofs(cp, p->rptr, copy_l);
619 else
620 memcpy(cp, p->rptr, copy_l);
621 if (fp) {
622 memset(fp, 0, copy_l);
623 fp += copy_l;
624 }
625 left -= copy_l;
626 count += copy_l;
627 cp += copy_l;
628 if (dflag) {
629 if (fp)
630 *(fp - 1) = 0xff;
631 save_flags(flags);
632 cli();
633 dev->drv[di]->rpqueue[channel] = (pqueue *) p->next;
634 kfree_s(p, p->size);
635 restore_flags(flags);
636 } else {
637 p->rptr += copy_l;
638 p->length -= copy_l;
639 }
640 save_flags(flags);
641 cli();
642 dev->drv[di]->rcvcount[channel] -= copy_l;
643 restore_flags(flags);
644 }
645 return count;
646 }
647
648 static __inline int isdn_minor2drv(int minor)
649 {
650 return (dev->drvmap[minor]);
651 }
652
653 static __inline int isdn_minor2chan(int minor)
654 {
655 return (dev->chanmap[minor]);
656 }
657
658 static char *
659 isdn_statstr(void)
660 {
661 static char istatbuf[2048];
662 char *p;
663 int i;
664
665 sprintf(istatbuf, "idmap:\t");
666 p = istatbuf + strlen(istatbuf);
667 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
668 sprintf(p, "%s ", (dev->drvmap[i] < 0) ? "-" : dev->drvid[dev->drvmap[i]]);
669 p = istatbuf + strlen(istatbuf);
670 }
671 sprintf(p, "\nchmap:\t");
672 p = istatbuf + strlen(istatbuf);
673 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
674 sprintf(p, "%d ", dev->chanmap[i]);
675 p = istatbuf + strlen(istatbuf);
676 }
677 sprintf(p, "\ndrmap:\t");
678 p = istatbuf + strlen(istatbuf);
679 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
680 sprintf(p, "%d ", dev->drvmap[i]);
681 p = istatbuf + strlen(istatbuf);
682 }
683 sprintf(p, "\nusage:\t");
684 p = istatbuf + strlen(istatbuf);
685 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
686 sprintf(p, "%d ", dev->usage[i]);
687 p = istatbuf + strlen(istatbuf);
688 }
689 sprintf(p, "\nflags:\t");
690 p = istatbuf + strlen(istatbuf);
691 for (i = 0; i < ISDN_MAX_DRIVERS; i++) {
692 if (dev->drv[i]) {
693 sprintf(p, "%ld ", dev->drv[i]->flags);
694 p = istatbuf + strlen(istatbuf);
695 } else {
696 sprintf(p, "? ");
697 p = istatbuf + strlen(istatbuf);
698 }
699 }
700 sprintf(p, "\nphone:\t");
701 p = istatbuf + strlen(istatbuf);
702 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
703 sprintf(p, "%s ", dev->num[i]);
704 p = istatbuf + strlen(istatbuf);
705 }
706 sprintf(p, "\n");
707 return istatbuf;
708 }
709
710
711
712 void isdn_info_update(void)
713 {
714 infostruct *p = dev->infochain;
715
716 while (p) {
717 *(p->private) = 1;
718 p = (infostruct *) p->next;
719 }
720 wake_up_interruptible(&(dev->info_waitq));
721 }
722
723 static int isdn_read(struct inode *inode, struct file *file, char *buf, int count)
724 {
725 uint minor = MINOR(inode->i_rdev);
726 int len = 0;
727 ulong flags;
728 int drvidx;
729 int chidx;
730
731 if (minor == ISDN_MINOR_STATUS) {
732 char *p;
733 if (!file->private_data)
734 interruptible_sleep_on(&(dev->info_waitq));
735 save_flags(flags);
736 p = isdn_statstr();
737 restore_flags(flags);
738 file->private_data = 0;
739 if ((len = strlen(p)) <= count) {
740 memcpy_tofs(buf, p, len);
741 file->f_pos += len;
742 return len;
743 }
744 return 0;
745 }
746 if (!dev->drivers)
747 return -ENODEV;
748 if (minor < ISDN_MINOR_CTRL) {
749 drvidx = isdn_minor2drv(minor);
750 if (drvidx < 0)
751 return -ENODEV;
752 if (!dev->drv[drvidx]->running)
753 return -ENODEV;
754 chidx = isdn_minor2chan(minor);
755 len = isdn_readbchan(drvidx, chidx, buf, 0, count, 1);
756 file->f_pos += len;
757 return len;
758 }
759 if (minor <= ISDN_MINOR_CTRLMAX) {
760 drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL);
761 if (drvidx < 0)
762 return -ENODEV;
763 if (!dev->drv[drvidx]->stavail)
764 interruptible_sleep_on(&(dev->drv[drvidx]->st_waitq));
765 if (dev->drv[drvidx]->interface->readstat)
766 len = dev->drv[drvidx]->interface->
767 readstat(buf, MIN(count, dev->drv[drvidx]->stavail), 1);
768 else
769 len = 0;
770 save_flags(flags);
771 cli();
772 dev->drv[drvidx]->stavail -= len;
773 restore_flags(flags);
774 file->f_pos += len;
775 return len;
776 }
777 #ifdef CONFIG_ISDN_PPP
778 if (minor <= ISDN_MINOR_PPPMAX)
779 return (isdn_ppp_read(minor - ISDN_MINOR_PPP, file, buf, count));
780 #endif
781 return -ENODEV;
782 }
783
784 static int isdn_lseek(struct inode *inode, struct file *file, off_t offset, int orig)
785 {
786 return -ESPIPE;
787 }
788
789 static int isdn_write(struct inode *inode, struct file *file, const char *buf, int count)
790 {
791 uint minor = MINOR(inode->i_rdev);
792 int drvidx;
793 int chidx;
794
795 if (minor == ISDN_MINOR_STATUS)
796 return -EPERM;
797 if (!dev->drivers)
798 return -ENODEV;
799 if (minor < ISDN_MINOR_CTRL) {
800 drvidx = isdn_minor2drv(minor);
801 if (drvidx < 0)
802 return -ENODEV;
803 if (!dev->drv[drvidx]->running)
804 return -ENODEV;
805 chidx = isdn_minor2chan(minor);
806 while (dev->drv[drvidx]->interface->writebuf(drvidx, chidx, buf, count, 1) != count)
807 interruptible_sleep_on(&dev->drv[drvidx]->snd_waitq[chidx]);
808 return count;
809 }
810 if (minor <= ISDN_MINOR_CTRLMAX) {
811 drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL);
812 if (drvidx < 0)
813 return -ENODEV;
814
815
816
817
818
819
820 if (dev->drv[drvidx]->interface->writecmd)
821 return (dev->drv[drvidx]->interface->writecmd(buf, count, 1));
822 else
823 return count;
824 }
825 #ifdef CONFIG_ISDN_PPP
826 if (minor <= ISDN_MINOR_PPPMAX)
827 return (isdn_ppp_write(minor - ISDN_MINOR_PPP, file, buf, count));
828 #endif
829 return -ENODEV;
830 }
831
832 static int isdn_select(struct inode *inode, struct file *file, int type, select_table * st)
833 {
834 uint minor = MINOR(inode->i_rdev);
835
836 if (minor == ISDN_MINOR_STATUS) {
837 if (file->private_data)
838 return 1;
839 else {
840 if (st)
841 select_wait(&(dev->info_waitq), st);
842 return 0;
843 }
844 }
845 if (minor <= ISDN_MINOR_CTRLMAX)
846 return 1;
847 #ifdef CONFIG_ISDN_PPP
848 if (minor <= ISDN_MINOR_PPPMAX)
849 return (isdn_ppp_select(minor - ISDN_MINOR_PPP, file, type, st));
850 #endif
851 return -ENODEV;
852 }
853
854 static int isdn_set_allcfg(char *src)
855 {
856 int ret;
857 int i;
858 ulong flags;
859 char buf[1024];
860 isdn_net_ioctl_cfg cfg;
861 isdn_net_ioctl_phone phone;
862
863 if ((ret = isdn_net_rmall()))
864 return ret;
865 save_flags(flags);
866 cli();
867 if ((ret = verify_area(VERIFY_READ, (void *) src, sizeof(int)))) {
868 restore_flags(flags);
869 return ret;
870 }
871 memcpy_tofs((char *) &i, src, sizeof(int));
872 while (i) {
873 char *c;
874 char *c2;
875
876 if ((ret = verify_area(VERIFY_READ, (void *) src, sizeof(cfg)))) {
877 restore_flags(flags);
878 return ret;
879 }
880 memcpy_tofs((char *) &cfg, src, sizeof(cfg));
881 src += sizeof(cfg);
882 if (!isdn_net_new(cfg.name, NULL)) {
883 restore_flags(flags);
884 return -EIO;
885 }
886 if ((ret = isdn_net_setcfg(&cfg))) {
887 restore_flags(flags);
888 return ret;
889 }
890 if ((ret = verify_area(VERIFY_READ, (void *) src, sizeof(buf)))) {
891 restore_flags(flags);
892 return ret;
893 }
894 memcpy_fromfs(buf, src, sizeof(buf));
895 src += sizeof(buf);
896 c = buf;
897 while (*c) {
898 if ((c2 = strchr(c, ' ')))
899 *c2++ = '\0';
900 strcpy(phone.phone, c);
901 strcpy(phone.name, cfg.name);
902 phone.outgoing = 0;
903 if ((ret = isdn_net_addphone(&phone))) {
904 restore_flags(flags);
905 return ret;
906 }
907 if (c2)
908 c = c2;
909 else
910 c += strlen(c);
911 }
912 if ((ret = verify_area(VERIFY_READ, (void *) src, sizeof(buf)))) {
913 restore_flags(flags);
914 return ret;
915 }
916 memcpy_fromfs(buf, src, sizeof(buf));
917 src += sizeof(buf);
918 c = buf;
919 while (*c) {
920 if ((c2 = strchr(c, ' ')))
921 *c2++ = '\0';
922 strcpy(phone.phone, c);
923 strcpy(phone.name, cfg.name);
924 phone.outgoing = 1;
925 if ((ret = isdn_net_addphone(&phone))) {
926 restore_flags(flags);
927 return ret;
928 }
929 if (c2)
930 c = c2;
931 else
932 c += strlen(c);
933 }
934 i--;
935 }
936 restore_flags(flags);
937 return 0;
938 }
939
940 static int isdn_get_allcfg(char *dest)
941 {
942 isdn_net_ioctl_cfg cfg;
943 isdn_net_ioctl_phone phone;
944 isdn_net_dev *p;
945 ulong flags;
946 int ret;
947
948
949 save_flags(flags);
950 cli();
951 p = dev->netdev;
952 while (p) {
953 if ((ret = verify_area(VERIFY_WRITE, (void *) dest, sizeof(cfg) + 10))) {
954 restore_flags(flags);
955 return ret;
956 }
957 strcpy(cfg.eaz, p->local.msn);
958 cfg.exclusive = p->local.exclusive;
959 if (p->local.pre_device >= 0) {
960 sprintf(cfg.drvid, "%s,%d", dev->drvid[p->local.pre_device],
961 p->local.pre_channel);
962 } else
963 cfg.drvid[0] = '\0';
964 cfg.onhtime = p->local.onhtime;
965 cfg.charge = p->local.charge;
966 cfg.l2_proto = p->local.l2_proto;
967 cfg.l3_proto = p->local.l3_proto;
968 cfg.p_encap = p->local.p_encap;
969 cfg.secure = (p->local.flags & ISDN_NET_SECURE) ? 1 : 0;
970 cfg.callback = (p->local.flags & ISDN_NET_CALLBACK) ? 1 : 0;
971 cfg.chargehup = (p->local.hupflags & 4) ? 1 : 0;
972 cfg.ihup = (p->local.hupflags & 8) ? 1 : 0;
973 memcpy_tofs(dest, p->local.name, 10);
974 dest += 10;
975 memcpy_tofs(dest, (char *) &cfg, sizeof(cfg));
976 dest += sizeof(cfg);
977 strcpy(phone.name, p->local.name);
978 phone.outgoing = 0;
979 if ((ret = isdn_net_getphones(&phone, dest)) < 0) {
980 restore_flags(flags);
981 return ret;
982 } else
983 dest += ret;
984 strcpy(phone.name, p->local.name);
985 phone.outgoing = 1;
986 if ((ret = isdn_net_getphones(&phone, dest)) < 0) {
987 restore_flags(flags);
988 return ret;
989 } else
990 dest += ret;
991 p = p->next;
992 }
993 restore_flags(flags);
994 return 0;
995 }
996
997 static int isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
998 {
999 uint minor = MINOR(inode->i_rdev);
1000 isdn_ctrl c;
1001 int drvidx;
1002 int chidx;
1003 int ret;
1004 char *s;
1005 char name[10];
1006 char bname[21];
1007 isdn_ioctl_struct iocts;
1008 isdn_net_ioctl_phone phone;
1009 isdn_net_ioctl_cfg cfg;
1010
1011 if (minor == ISDN_MINOR_STATUS)
1012 return -EPERM;
1013 if (!dev->drivers)
1014 return -ENODEV;
1015 if (minor < ISDN_MINOR_CTRL) {
1016 drvidx = isdn_minor2drv(minor);
1017 if (drvidx < 0)
1018 return -ENODEV;
1019 chidx = isdn_minor2chan(minor);
1020 if (!dev->drv[drvidx]->running)
1021 return -ENODEV;
1022 return 0;
1023 }
1024 if (minor <= ISDN_MINOR_CTRLMAX) {
1025 switch (cmd) {
1026 #ifdef CONFIG_NETDEVICES
1027 case IIOCNETAIF:
1028
1029 if (arg) {
1030 if ((ret = verify_area(VERIFY_READ, (void *) arg, sizeof(name))))
1031 return ret;
1032 memcpy_fromfs(name, (char *) arg, sizeof(name));
1033 s = name;
1034 } else
1035 s = NULL;
1036 if ((s = isdn_net_new(s, NULL))) {
1037 if ((ret = verify_area(VERIFY_WRITE, (void *) arg, strlen(s) + 1)))
1038 return ret;
1039 memcpy_tofs((char *) arg, s, strlen(s) + 1);
1040 return 0;
1041 } else
1042 return -ENODEV;
1043 case IIOCNETASL:
1044
1045 if (arg) {
1046 if ((ret = verify_area(VERIFY_READ, (void *) arg, sizeof(bname))))
1047 return ret;
1048 memcpy_fromfs(bname, (char *) arg, sizeof(bname));
1049 } else
1050 return -EINVAL;
1051 if ((s = isdn_net_newslave(bname))) {
1052 if ((ret = verify_area(VERIFY_WRITE, (void *) arg, strlen(s) + 1)))
1053 return ret;
1054 memcpy_tofs((char *) arg, s, strlen(s) + 1);
1055 return 0;
1056 } else
1057 return -ENODEV;
1058 case IIOCNETDIF:
1059
1060 if (arg) {
1061 if ((ret = verify_area(VERIFY_READ, (void *) arg, sizeof(name))))
1062 return ret;
1063 memcpy_fromfs(name, (char *) arg, sizeof(name));
1064 return isdn_net_rm(name);
1065 } else
1066 return -EINVAL;
1067 case IIOCNETSCF:
1068
1069 if (arg) {
1070 if ((ret = verify_area(VERIFY_READ, (void *) arg, sizeof(cfg))))
1071 return ret;
1072 memcpy_fromfs((char *) &cfg, (char *) arg, sizeof(cfg));
1073 return isdn_net_setcfg(&cfg);
1074 } else
1075 return -EINVAL;
1076 case IIOCNETGCF:
1077
1078 if (arg) {
1079 if ((ret = verify_area(VERIFY_READ, (void *) arg, sizeof(cfg))))
1080 return ret;
1081 memcpy_fromfs((char *) &cfg, (char *) arg, sizeof(cfg));
1082 if (!(ret = isdn_net_getcfg(&cfg))) {
1083 if ((ret = verify_area(VERIFY_WRITE, (void *) arg, sizeof(cfg))))
1084 return ret;
1085 memcpy_tofs((char *) arg, (char *) &cfg, sizeof(cfg));
1086 }
1087 return ret;
1088 } else
1089 return -EINVAL;
1090 case IIOCNETANM:
1091
1092 if (arg) {
1093 if ((ret = verify_area(VERIFY_READ, (void *) arg, sizeof(phone))))
1094 return ret;
1095 memcpy_fromfs((char *) &phone, (char *) arg, sizeof(phone));
1096 return isdn_net_addphone(&phone);
1097 } else
1098 return -EINVAL;
1099 case IIOCNETGNM:
1100
1101 if (arg) {
1102 if ((ret = verify_area(VERIFY_READ, (void *) arg, sizeof(phone))))
1103 return ret;
1104 memcpy_fromfs((char *) &phone, (char *) arg, sizeof(phone));
1105 return isdn_net_getphones(&phone, (char *) arg);
1106 } else
1107 return -EINVAL;
1108 case IIOCNETDNM:
1109
1110 if (arg) {
1111 memcpy_fromfs((char *) &phone, (char *) arg, sizeof(phone));
1112 if ((ret = verify_area(VERIFY_READ, (void *) arg, sizeof(phone))))
1113 return ret;
1114 return isdn_net_delphone(&phone);
1115 } else
1116 return -EINVAL;
1117 case IIOCNETDIL:
1118
1119 if (arg) {
1120 if ((ret = verify_area(VERIFY_READ, (void *) arg, sizeof(name))))
1121 return ret;
1122 memcpy_fromfs(name, (char *) arg, sizeof(name));
1123 return isdn_net_force_dial(name);
1124 } else
1125 return -EINVAL;
1126 #ifdef CONFIG_ISDN_PPP
1127 case IIOCNETALN:
1128 if(arg) {
1129 if ((ret = verify_area(VERIFY_READ,
1130 (void*)arg,
1131 sizeof(name))))
1132 return ret;
1133 } else
1134 return -EINVAL;
1135 memcpy_fromfs(name,(char*)arg,sizeof(name));
1136 return isdn_ppp_dial_slave(name);
1137 case IIOCNETDLN:
1138
1139 return 2;
1140 #endif
1141 case IIOCNETHUP:
1142
1143 if (arg) {
1144 if ((ret = verify_area(VERIFY_READ, (void *) arg, sizeof(name))))
1145 return ret;
1146 memcpy_fromfs(name, (char *) arg, sizeof(name));
1147 return isdn_net_force_hangup(name);
1148 } else
1149 return -EINVAL;
1150 break;
1151 #endif
1152 case IIOCSETVER:
1153 dev->net_verbose = arg;
1154 printk(KERN_INFO "isdn: Verbose-Level is %d\n", dev->net_verbose);
1155 return 0;
1156 case IIOCSETGST:
1157 if (arg)
1158 dev->global_flags |= ISDN_GLOBAL_STOPPED;
1159 else
1160 dev->global_flags &= ~ISDN_GLOBAL_STOPPED;
1161 printk(KERN_INFO "isdn: Global Mode %s\n",
1162 (dev->global_flags & ISDN_GLOBAL_STOPPED) ? "stopped" : "running");
1163 return 0;
1164 case IIOCSETBRJ:
1165 drvidx = -1;
1166 if (arg) {
1167 int i;
1168 char *p;
1169 if ((ret = verify_area(VERIFY_READ, (void *) arg,
1170 sizeof(isdn_ioctl_struct))))
1171 return ret;
1172 memcpy_fromfs((char *) &iocts, (char *) arg, sizeof(isdn_ioctl_struct));
1173 if (strlen(iocts.drvid)) {
1174 if ((p = strchr(iocts.drvid, ',')))
1175 *p = 0;
1176 drvidx = -1;
1177 for (i = 0; i < ISDN_MAX_DRIVERS; i++)
1178 if (!(strcmp(dev->drvid[i], iocts.drvid))) {
1179 drvidx = i;
1180 break;
1181 }
1182 }
1183 }
1184 if (drvidx == -1)
1185 return -ENODEV;
1186 dev->drv[drvidx]->reject_bus = iocts.arg;
1187 return 0;
1188 case IIOCGETSET:
1189
1190
1191 if (arg)
1192 return (isdn_get_allcfg((char *) arg));
1193 else
1194 return -EINVAL;
1195 break;
1196 case IIOCSETSET:
1197
1198
1199 if (arg)
1200 return (isdn_set_allcfg((char *) arg));
1201 else
1202 return -EINVAL;
1203 break;
1204 case IIOCSIGPRF:
1205 dev->profd = current;
1206 return 0;
1207 break;
1208 case IIOCGETPRF:
1209
1210 if (arg) {
1211 char *p = (char *) arg;
1212 int i;
1213
1214 if ((ret = verify_area(VERIFY_WRITE, (void *) arg,
1215 (ISDN_MODEM_ANZREG + ISDN_MSNLEN)
1216 * ISDN_MAX_CHANNELS)))
1217 return ret;
1218
1219 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
1220 memcpy_tofs(p, dev->mdm.atmodem[i].profile, ISDN_MODEM_ANZREG);
1221 p += ISDN_MODEM_ANZREG;
1222 memcpy_tofs(p, dev->mdm.atmodem[i].pmsn, ISDN_MSNLEN);
1223 p += ISDN_MSNLEN;
1224 }
1225 return (ISDN_MODEM_ANZREG + ISDN_MSNLEN) * ISDN_MAX_CHANNELS;
1226 } else
1227 return -EINVAL;
1228 break;
1229 case IIOCSETPRF:
1230
1231 if (arg) {
1232 char *p = (char *) arg;
1233 int i;
1234
1235 if ((ret = verify_area(VERIFY_READ, (void *) arg,
1236 (ISDN_MODEM_ANZREG + ISDN_MSNLEN)
1237 * ISDN_MAX_CHANNELS)))
1238 return ret;
1239
1240 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
1241 memcpy_fromfs(dev->mdm.atmodem[i].profile, p, ISDN_MODEM_ANZREG);
1242 p += ISDN_MODEM_ANZREG;
1243 memcpy_fromfs(dev->mdm.atmodem[i].pmsn, p, ISDN_MSNLEN);
1244 p += ISDN_MSNLEN;
1245 }
1246 return 0;
1247 } else
1248 return -EINVAL;
1249 break;
1250 case IIOCSETMAP:
1251 case IIOCGETMAP:
1252
1253 if (arg) {
1254 int i;
1255 char *p;
1256 char nstring[255];
1257
1258 if ((ret = verify_area(VERIFY_READ, (void *) arg,
1259 sizeof(isdn_ioctl_struct))))
1260 return ret;
1261 memcpy_fromfs((char *) &iocts, (char *) arg, sizeof(isdn_ioctl_struct));
1262 if (strlen(iocts.drvid)) {
1263 drvidx = -1;
1264 for (i = 0; i < ISDN_MAX_DRIVERS; i++)
1265 if (!(strcmp(dev->drvid[i], iocts.drvid))) {
1266 drvidx = i;
1267 break;
1268 }
1269 } else
1270 drvidx = 0;
1271 if (drvidx == -1)
1272 return -ENODEV;
1273 if (cmd == IIOCSETMAP) {
1274 if ((ret = verify_area(VERIFY_READ, (void *) iocts.arg, 255)))
1275 return ret;
1276 memcpy_fromfs(nstring, (char *) iocts.arg, 255);
1277 memset(dev->drv[drvidx]->msn2eaz, 0,
1278 sizeof(dev->drv[drvidx]->msn2eaz));
1279 p = strtok(nstring, ",");
1280 i = 0;
1281 while ((p) && (i < 10)) {
1282 strcpy(dev->drv[drvidx]->msn2eaz[i++], p);
1283 p = strtok(NULL, ",");
1284 }
1285 } else {
1286 p = nstring;
1287 for (i = 0; i < 10; i++)
1288 p += sprintf(p, "%s%s",
1289 strlen(dev->drv[drvidx]->msn2eaz[i]) ?
1290 dev->drv[drvidx]->msn2eaz[i] : "-",
1291 (i < 9) ? "," : "\0");
1292 if ((ret = verify_area(VERIFY_WRITE, (void *) iocts.arg,
1293 strlen(nstring) + 1)))
1294 return ret;
1295 memcpy_tofs((char *) iocts.arg, nstring, strlen(nstring) + 1);
1296 }
1297 return 0;
1298 } else
1299 return -EINVAL;
1300 case IIOCDBGVAR:
1301 if (arg) {
1302 if ((ret = verify_area(VERIFY_WRITE, (void *) arg, sizeof(ulong))))
1303 return ret;
1304 memcpy_tofs((char *) arg, (char *) &dev, sizeof(ulong));
1305 return 0;
1306 } else
1307 return -EINVAL;
1308 break;
1309 default:
1310 if ((cmd&IIOCDRVCTL)==IIOCDRVCTL)
1311 cmd = ((cmd>>_IOC_NRSHIFT)&_IOC_NRMASK)& ISDN_DRVIOCTL_MASK;
1312 else
1313 return -EINVAL;
1314 if (arg) {
1315 int i;
1316 char *p;
1317 if ((ret = verify_area(VERIFY_READ, (void *) arg,
1318 sizeof(isdn_ioctl_struct))))
1319 return ret;
1320 memcpy_fromfs((char *) &iocts, (char *) arg, sizeof(isdn_ioctl_struct));
1321 if (strlen(iocts.drvid)) {
1322 if ((p = strchr(iocts.drvid, ',')))
1323 *p = 0;
1324 drvidx = -1;
1325 for (i = 0; i < ISDN_MAX_DRIVERS; i++)
1326 if (!(strcmp(dev->drvid[i], iocts.drvid))) {
1327 drvidx = i;
1328 break;
1329 }
1330 } else
1331 drvidx = 0;
1332 if (drvidx == -1)
1333 return -ENODEV;
1334 if ((ret = verify_area(VERIFY_WRITE, (void *) arg,
1335 sizeof(isdn_ioctl_struct))))
1336 return ret;
1337 c.driver = drvidx;
1338 c.command = ISDN_CMD_IOCTL;
1339 c.arg = cmd;
1340 memcpy(c.num, (char *) &iocts.arg, sizeof(ulong));
1341 ret = dev->drv[drvidx]->interface->command(&c);
1342 memcpy((char *) &iocts.arg, c.num, sizeof(ulong));
1343 memcpy_tofs((char *) arg, &iocts, sizeof(isdn_ioctl_struct));
1344 return ret;
1345 } else
1346 return -EINVAL;
1347 }
1348 }
1349 #ifdef CONFIG_ISDN_PPP
1350 if (minor <= ISDN_MINOR_PPPMAX)
1351 return (isdn_ppp_ioctl(minor - ISDN_MINOR_PPP, file, cmd, arg));
1352 #endif
1353 return -ENODEV;
1354 }
1355
1356
1357
1358
1359
1360
1361 static int isdn_open(struct inode *ino, struct file *filep)
1362 {
1363 uint minor = MINOR(ino->i_rdev);
1364 int drvidx;
1365 int chidx;
1366 isdn_ctrl c;
1367
1368 if (minor == ISDN_MINOR_STATUS) {
1369 infostruct *p;
1370
1371 if ((p = (infostruct *) kmalloc(sizeof(infostruct), GFP_KERNEL))) {
1372 MOD_INC_USE_COUNT;
1373 p->next = (char *) dev->infochain;
1374 p->private = (char *) &(filep->private_data);
1375 dev->infochain = p;
1376
1377 filep->private_data = (char *) 1;
1378 return 0;
1379 } else
1380 return -ENOMEM;
1381 }
1382 if (!dev->channels)
1383 return -ENODEV;
1384 if (minor < ISDN_MINOR_CTRL) {
1385 drvidx = isdn_minor2drv(minor);
1386 if (drvidx < 0)
1387 return -ENODEV;
1388 chidx = isdn_minor2chan(minor);
1389 if (!dev->drv[drvidx]->running)
1390 return -ENODEV;
1391 if (!(dev->drv[drvidx]->flags & (1 << chidx)))
1392 return -ENODEV;
1393 c.command = ISDN_CMD_LOCK;
1394 c.driver = drvidx;
1395 (void) dev->drv[drvidx]->interface->command(&c);
1396 MOD_INC_USE_COUNT;
1397 return 0;
1398 }
1399 if (minor <= ISDN_MINOR_CTRLMAX) {
1400 drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL);
1401 if (drvidx < 0)
1402 return -ENODEV;
1403 c.command = ISDN_CMD_LOCK;
1404 c.driver = drvidx;
1405 MOD_INC_USE_COUNT;
1406 (void) dev->drv[drvidx]->interface->command(&c);
1407 return 0;
1408 }
1409 #ifdef CONFIG_ISDN_PPP
1410 if (minor <= ISDN_MINOR_PPPMAX) {
1411 int ret;
1412 if (!(ret = isdn_ppp_open(minor - ISDN_MINOR_PPP, filep)))
1413 MOD_INC_USE_COUNT;
1414 return ret;
1415 }
1416 #endif
1417 return -ENODEV;
1418 }
1419
1420 static void isdn_close(struct inode *ino, struct file *filep)
1421 {
1422 uint minor = MINOR(ino->i_rdev);
1423 int drvidx;
1424 isdn_ctrl c;
1425
1426 if (!dev->channels)
1427 return;
1428 MOD_DEC_USE_COUNT;
1429 if (minor == ISDN_MINOR_STATUS) {
1430 infostruct *p = dev->infochain;
1431 infostruct *q = NULL;
1432 while (p) {
1433 if (p->private == (char *) &(filep->private_data)) {
1434 if (q)
1435 q->next = p->next;
1436 else
1437 dev->infochain = (infostruct *) (p->next);
1438 return;
1439 }
1440 q = p;
1441 p = (infostruct *) (p->next);
1442 }
1443 printk(KERN_WARNING "isdn: No private data while closing isdnctrl\n");
1444 }
1445 if (minor < ISDN_MINOR_CTRL) {
1446 drvidx = isdn_minor2drv(minor);
1447 if (drvidx < 0)
1448 return;
1449 c.command = ISDN_CMD_UNLOCK;
1450 c.driver = drvidx;
1451 (void) dev->drv[drvidx]->interface->command(&c);
1452 return;
1453 }
1454 if (minor <= ISDN_MINOR_CTRLMAX) {
1455 drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL);
1456 if (drvidx < 0)
1457 return;
1458 if (dev->profd == current)
1459 dev->profd = NULL;
1460 c.command = ISDN_CMD_UNLOCK;
1461 c.driver = drvidx;
1462 (void) dev->drv[drvidx]->interface->command(&c);
1463 return;
1464 }
1465 #ifdef CONFIG_ISDN_PPP
1466 if (minor <= ISDN_MINOR_PPPMAX) {
1467 isdn_ppp_release(minor - ISDN_MINOR_PPP, filep);
1468 }
1469 #endif
1470 }
1471
1472 static struct file_operations isdn_fops =
1473 {
1474 isdn_lseek,
1475 isdn_read,
1476 isdn_write,
1477 NULL,
1478 isdn_select,
1479 isdn_ioctl,
1480 NULL,
1481 isdn_open,
1482 isdn_close,
1483 NULL
1484 };
1485
1486 char *
1487 isdn_map_eaz2msn(char *msn, int di)
1488 {
1489 driver *this = dev->drv[di];
1490 int i;
1491
1492 if (strlen(msn) == 1) {
1493 i = msn[0] - '0';
1494 if ((i >= 0) && (i <= 9))
1495 if (strlen(this->msn2eaz[i]))
1496 return (this->msn2eaz[i]);
1497 }
1498 return (msn);
1499 }
1500
1501
1502
1503
1504
1505 int isdn_get_free_channel(int usage, int l2_proto, int l3_proto, int pre_dev
1506 ,int pre_chan)
1507 {
1508 int i;
1509 ulong flags;
1510 ulong features;
1511
1512 save_flags(flags);
1513 cli();
1514 features = (1 << l2_proto) | (0x100 << l3_proto);
1515 for (i = 0; i < ISDN_MAX_CHANNELS; i++)
1516 if (USG_NONE(dev->usage[i]) &&
1517 (dev->drvmap[i] != -1)) {
1518 int d = dev->drvmap[i];
1519 if ((dev->usage[i] & ISDN_USAGE_EXCLUSIVE) &&
1520 ((pre_dev != d) || (pre_chan != dev->chanmap[i])))
1521 continue;
1522 if ((dev->drv[d]->running)) {
1523 if ((dev->drv[d]->interface->features & features) == features) {
1524 if ((pre_dev < 0) || (pre_chan < 0)) {
1525 dev->usage[i] &= ISDN_USAGE_EXCLUSIVE;
1526 dev->usage[i] |= usage;
1527 isdn_info_update();
1528 restore_flags(flags);
1529 return i;
1530 } else {
1531 if ((pre_dev == d) && (pre_chan == dev->chanmap[i])) {
1532 dev->usage[i] &= ISDN_USAGE_EXCLUSIVE;
1533 dev->usage[i] |= usage;
1534 isdn_info_update();
1535 restore_flags(flags);
1536 return i;
1537 }
1538 }
1539 }
1540 }
1541 }
1542 restore_flags(flags);
1543 return -1;
1544 }
1545
1546
1547
1548
1549 void isdn_free_channel(int di, int ch, int usage)
1550 {
1551 int i;
1552 ulong flags;
1553
1554 save_flags(flags);
1555 cli();
1556 for (i = 0; i < ISDN_MAX_CHANNELS; i++)
1557 if (((dev->usage[i] & ISDN_USAGE_MASK) == usage) &&
1558 (dev->drvmap[i] == di) &&
1559 (dev->chanmap[i] == ch)) {
1560 dev->usage[i] &= (ISDN_USAGE_NONE | ISDN_USAGE_EXCLUSIVE);
1561 strcpy(dev->num[i], "???");
1562 isdn_info_update();
1563 restore_flags(flags);
1564 return;
1565 }
1566 restore_flags(flags);
1567 }
1568
1569
1570
1571
1572 void isdn_unexclusive_channel(int di, int ch)
1573 {
1574 int i;
1575 ulong flags;
1576
1577 save_flags(flags);
1578 cli();
1579 for (i = 0; i < ISDN_MAX_CHANNELS; i++)
1580 if ((dev->drvmap[i] == di) &&
1581 (dev->chanmap[i] == ch)) {
1582 dev->usage[i] &= ~ISDN_USAGE_EXCLUSIVE;
1583 isdn_info_update();
1584 restore_flags(flags);
1585 return;
1586 }
1587 restore_flags(flags);
1588 }
1589
1590
1591
1592
1593
1594 void isdn_receive_skb_callback(int drvidx, int chan, struct sk_buff *skb)
1595 {
1596 int i;
1597
1598 if (dev->global_flags & ISDN_GLOBAL_STOPPED)
1599 return;
1600 if ((i = isdn_dc2minor(drvidx,chan))==-1)
1601 return;
1602 if (isdn_net_rcv_skb(i, skb) == 0) {
1603 isdn_receive_callback(drvidx, chan, skb->data, skb->len);
1604 skb->free = 1;
1605 kfree_skb(skb, FREE_READ);
1606 }
1607 }
1608
1609
1610
1611
1612
1613 int isdn_writebuf_stub(int drvidx, int chan, const u_char *buf, int len,
1614 int user)
1615 {
1616 struct sk_buff * skb;
1617
1618 skb = alloc_skb(dev->drv[drvidx]->interface->hl_hdrlen + len, GFP_ATOMIC);
1619 if (skb == NULL)
1620 return 0;
1621
1622 skb_reserve(skb, dev->drv[drvidx]->interface->hl_hdrlen);
1623 skb->free = 1;
1624
1625 if (user)
1626 memcpy_fromfs(skb_put(skb, len), buf, len);
1627 else
1628 memcpy(skb_put(skb, len), buf, len);
1629
1630 return dev->drv[drvidx]->interface->writebuf_skb(drvidx, chan, skb);
1631 }
1632
1633
1634
1635
1636
1637
1638 int register_isdn(isdn_if * i)
1639 {
1640 driver *d;
1641 int n, j, k;
1642 ulong flags;
1643 int drvidx;
1644
1645 if (dev->drivers >= ISDN_MAX_DRIVERS) {
1646 printk(KERN_WARNING "register_isdn: Max. %d drivers supported\n",
1647 ISDN_MAX_DRIVERS);
1648 return 0;
1649 }
1650 n = i->channels;
1651 if (dev->channels + n >= ISDN_MAX_CHANNELS) {
1652 printk(KERN_WARNING "register_isdn: Max. %d channels supported\n",
1653 ISDN_MAX_CHANNELS);
1654 return 0;
1655 }
1656 if (!(d = (driver *) kmalloc(sizeof(driver), GFP_KERNEL))) {
1657 printk(KERN_WARNING "register_isdn: Could not alloc driver-struct\n");
1658 return 0;
1659 }
1660 memset((char *) d, 0, sizeof(driver));
1661 if (!(d->rcverr = (int *) kmalloc(sizeof(int) * n, GFP_KERNEL))) {
1662 printk(KERN_WARNING "register_isdn: Could not alloc rcverr\n");
1663 kfree(d);
1664 return 0;
1665 }
1666 memset((char *) d->rcverr, 0, sizeof(int) * n);
1667 if (!(d->rcvcount = (int *) kmalloc(sizeof(int) * n, GFP_KERNEL))) {
1668 printk(KERN_WARNING "register_isdn: Could not alloc rcvcount\n");
1669 kfree(d->rcverr);
1670 kfree(d);
1671 return 0;
1672 }
1673 memset((char *) d->rcvcount, 0, sizeof(int) * n);
1674 if (!(d->rpqueue = (pqueue **) kmalloc(sizeof(pqueue *) * n, GFP_KERNEL))) {
1675 printk(KERN_WARNING "register_isdn: Could not alloc rpqueue\n");
1676 kfree(d->rcvcount);
1677 kfree(d->rcverr);
1678 kfree(d);
1679 return 0;
1680 }
1681 memset((char *) d->rpqueue, 0, sizeof(pqueue *) * n);
1682 if (!(d->rcv_waitq = (struct wait_queue **)
1683 kmalloc(sizeof(struct wait_queue *) * n, GFP_KERNEL))) {
1684 printk(KERN_WARNING "register_isdn: Could not alloc rcv_waitq\n");
1685 kfree(d->rpqueue);
1686 kfree(d->rcvcount);
1687 kfree(d->rcverr);
1688 kfree(d);
1689 return 0;
1690 }
1691 memset((char *) d->rcv_waitq, 0, sizeof(struct wait_queue *) * n);
1692 if (!(d->snd_waitq = (struct wait_queue **)
1693 kmalloc(sizeof(struct wait_queue *) * n, GFP_KERNEL))) {
1694 printk(KERN_WARNING "register_isdn: Could not alloc snd_waitq\n");
1695 kfree(d->rcv_waitq);
1696 kfree(d->rpqueue);
1697 kfree(d->rcvcount);
1698 kfree(d->rcverr);
1699 kfree(d);
1700 return 0;
1701 }
1702 memset((char *) d->snd_waitq, 0, sizeof(struct wait_queue *) * n);
1703 d->channels = n;
1704 d->loaded = 1;
1705 d->maxbufsize = i->maxbufsize;
1706 d->pktcount = 0;
1707 d->stavail = 0;
1708 d->running = 0;
1709 d->flags = 0;
1710 d->interface = i;
1711 for (drvidx = 0; drvidx < ISDN_MAX_DRIVERS; drvidx++)
1712 if (!dev->drv[drvidx])
1713 break;
1714 i->channels = drvidx;
1715
1716 if (i->writebuf_skb && (!i->writebuf))
1717 i->writebuf = isdn_writebuf_stub;
1718
1719 i->rcvcallb_skb = isdn_receive_skb_callback;
1720 i->rcvcallb = isdn_receive_callback;
1721 i->statcallb = isdn_status_callback;
1722 if (!strlen(i->id))
1723 sprintf(i->id, "line%d", drvidx);
1724 save_flags(flags);
1725 cli();
1726 for (j = 0; j < n; j++)
1727 for (k = 0; k < ISDN_MAX_CHANNELS; k++)
1728 if (dev->chanmap[k] < 0) {
1729 dev->chanmap[k] = j;
1730 dev->drvmap[k] = drvidx;
1731 break;
1732 }
1733 dev->drv[drvidx] = d;
1734 dev->channels += n;
1735 strcpy(dev->drvid[drvidx], i->id);
1736 isdn_info_update();
1737 dev->drivers++;
1738 restore_flags(flags);
1739 return 1;
1740 }
1741
1742
1743
1744
1745
1746
1747
1748 extern int printk(const char *fmt,...);
1749
1750 #ifdef MODULE
1751 #define isdn_init init_module
1752 #endif
1753
1754 static char *isdn_getrev(const char *revision)
1755 {
1756 static char rev[20];
1757 char *p;
1758
1759 if ((p = strchr(revision, ':'))) {
1760 strcpy(rev, p + 2);
1761 p = strchr(rev, '$');
1762 *--p = 0;
1763 } else
1764 strcpy(rev, "???");
1765 return rev;
1766 }
1767
1768 static struct symbol_table isdn_syms = {
1769 #include <linux/symtab_begin.h>
1770 X(register_isdn),
1771 #include <linux/symtab_end.h>
1772 };
1773
1774 static void isdn_export_syms(void)
1775 {
1776 register_symtab(&isdn_syms);
1777 has_exported = 1;
1778 }
1779
1780
1781
1782
1783 int isdn_init(void)
1784 {
1785 int i;
1786
1787 sti();
1788 if (!(dev = (isdn_dev *) kmalloc(sizeof(isdn_dev), GFP_KERNEL))) {
1789 printk(KERN_WARNING "isdn: Could not allocate device-struct.\n");
1790 return -EIO;
1791 }
1792 memset((char *) dev, 0, sizeof(isdn_dev));
1793 for (i = 0; i < ISDN_MAX_DRIVERS; i++)
1794 dev->drvmap[i] = -1;
1795 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
1796 dev->chanmap[i] = -1;
1797 dev->m_idx[i] = -1;
1798 strcpy(dev->num[i], "???");
1799 }
1800 if (register_chrdev(ISDN_MAJOR, "isdn", &isdn_fops)) {
1801 printk(KERN_WARNING "isdn: Could not register control devices\n");
1802 kfree(dev);
1803 return -EIO;
1804 }
1805 if ((i = isdn_tty_modem_init()) < 0) {
1806 printk(KERN_WARNING "isdn: Could not register tty devices\n");
1807 if (i == -3)
1808 tty_unregister_driver(&dev->mdm.cua_modem);
1809 if (i <= -2)
1810 tty_unregister_driver(&dev->mdm.tty_modem);
1811 kfree(dev);
1812 unregister_chrdev(ISDN_MAJOR, "isdn");
1813 return -EIO;
1814 }
1815 #ifdef CONFIG_ISDN_PPP
1816 if (isdn_ppp_init() < 0) {
1817 printk(KERN_WARNING "isdn: Could not create PPP-device-structs\n");
1818 tty_unregister_driver(&dev->mdm.tty_modem);
1819 tty_unregister_driver(&dev->mdm.cua_modem);
1820 for (i = 0; i < ISDN_MAX_CHANNELS; i++)
1821 kfree(dev->mdm.info[i].xmit_buf);
1822 unregister_chrdev(ISDN_MAJOR, "isdn");
1823 kfree(dev);
1824 return -EIO;
1825 }
1826 #endif
1827
1828 if (!has_exported)
1829 isdn_export_syms();
1830
1831 printk(KERN_NOTICE "ISDN subsystem Rev: %s/%s/%s/%s",
1832 isdn_getrev(isdn_revision),
1833 isdn_getrev(isdn_tty_revision),
1834 isdn_getrev(isdn_net_revision),
1835 isdn_getrev(isdn_ppp_revision));
1836
1837 #ifdef MODULE
1838 printk(" loaded\n");
1839 #else
1840 printk("\n");
1841 isdn_cards_init();
1842 #endif
1843 isdn_info_update();
1844 return 0;
1845 }
1846
1847 #ifdef MODULE
1848
1849
1850
1851 void cleanup_module(void)
1852 {
1853 int flags;
1854 int i;
1855
1856 #ifdef CONFIG_ISDN_PPP
1857 isdn_ppp_cleanup();
1858 #endif
1859 save_flags(flags);
1860 cli();
1861 if (isdn_net_rmall() < 0) {
1862 printk(KERN_WARNING "isdn: net-device busy, remove cancelled\n");
1863 restore_flags(flags);
1864 return;
1865 }
1866 if (tty_unregister_driver(&dev->mdm.tty_modem)) {
1867 printk(KERN_WARNING "isdn: ttyI-device busy, remove cancelled\n");
1868 restore_flags(flags);
1869 return;
1870 }
1871 if (tty_unregister_driver(&dev->mdm.cua_modem)) {
1872 printk(KERN_WARNING "isdn: cui-device busy, remove cancelled\n");
1873 restore_flags(flags);
1874 return;
1875 }
1876 for (i = 0; i < ISDN_MAX_CHANNELS; i++)
1877 kfree(dev->mdm.info[i].xmit_buf - 4);
1878 if (unregister_chrdev(ISDN_MAJOR, "isdn") != 0) {
1879 printk(KERN_WARNING "isdn: controldevice busy, remove cancelled\n");
1880 } else {
1881 del_timer(&dev->timer);
1882 kfree(dev);
1883 printk(KERN_NOTICE "ISDN-subsystem unloaded\n");
1884 }
1885 restore_flags(flags);
1886 }
1887 #endif