]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - drivers/isdn/gigaset/common.c
gigaset: correct debugging output selection
[mirror_ubuntu-jammy-kernel.git] / drivers / isdn / gigaset / common.c
CommitLineData
6fd5ea63
HL
1/*
2 * Stuff used by all variants of the driver
3 *
70440cf2 4 * Copyright (c) 2001 by Stefan Eilers,
6fd5ea63
HL
5 * Hansjoerg Lipp <hjlipp@web.de>,
6 * Tilman Schmidt <tilman@imap.cc>.
7 *
8 * =====================================================================
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
13 * =====================================================================
6fd5ea63
HL
14 */
15
16#include "gigaset.h"
17#include <linux/ctype.h>
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20
21/* Version Information */
70440cf2 22#define DRIVER_AUTHOR "Hansjoerg Lipp <hjlipp@web.de>, Tilman Schmidt <tilman@imap.cc>, Stefan Eilers"
6fd5ea63
HL
23#define DRIVER_DESC "Driver for Gigaset 307x"
24
2038724c
TS
25#ifdef CONFIG_GIGASET_DEBUG
26#define DRIVER_DESC_DEBUG " (debug build)"
27#else
28#define DRIVER_DESC_DEBUG ""
29#endif
30
6fd5ea63
HL
31/* Module parameters */
32int gigaset_debuglevel = DEBUG_DEFAULT;
33EXPORT_SYMBOL_GPL(gigaset_debuglevel);
34module_param_named(debug, gigaset_debuglevel, int, S_IRUGO|S_IWUSR);
35MODULE_PARM_DESC(debug, "debug level");
36
70440cf2 37/* driver state flags */
784d5858
TS
38#define VALID_MINOR 0x01
39#define VALID_ID 0x02
6fd5ea63 40
6fd5ea63 41void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg,
01371500 42 size_t len, const unsigned char *buf)
6fd5ea63
HL
43{
44 unsigned char outbuf[80];
784d5858 45 unsigned char c;
6fd5ea63
HL
46 size_t space = sizeof outbuf - 1;
47 unsigned char *out = outbuf;
01371500 48 size_t numin = len;
6fd5ea63 49
01371500 50 while (numin--) {
784d5858
TS
51 c = *buf++;
52 if (c == '~' || c == '^' || c == '\\') {
01371500 53 if (!space--)
784d5858
TS
54 break;
55 *out++ = '\\';
56 }
57 if (c & 0x80) {
01371500 58 if (!space--)
784d5858
TS
59 break;
60 *out++ = '~';
61 c ^= 0x80;
62 }
63 if (c < 0x20 || c == 0x7f) {
01371500 64 if (!space--)
784d5858 65 break;
6fd5ea63 66 *out++ = '^';
784d5858 67 c ^= 0x40;
6fd5ea63 68 }
01371500 69 if (!space--)
784d5858
TS
70 break;
71 *out++ = c;
6fd5ea63
HL
72 }
73 *out = 0;
74
784d5858 75 gig_dbg(level, "%s (%u bytes): %s", msg, (unsigned) len, outbuf);
6fd5ea63
HL
76}
77EXPORT_SYMBOL_GPL(gigaset_dbg_buffer);
78
79static int setflags(struct cardstate *cs, unsigned flags, unsigned delay)
80{
81 int r;
82
83 r = cs->ops->set_modem_ctrl(cs, cs->control_state, flags);
84 cs->control_state = flags;
85 if (r < 0)
86 return r;
87
88 if (delay) {
89 set_current_state(TASK_INTERRUPTIBLE);
90 schedule_timeout(delay * HZ / 1000);
91 }
92
93 return 0;
94}
95
96int gigaset_enterconfigmode(struct cardstate *cs)
97{
98 int i, r;
99
6fd5ea63
HL
100 cs->control_state = TIOCM_RTS; //FIXME
101
102 r = setflags(cs, TIOCM_DTR, 200);
103 if (r < 0)
104 goto error;
105 r = setflags(cs, 0, 200);
106 if (r < 0)
107 goto error;
108 for (i = 0; i < 5; ++i) {
109 r = setflags(cs, TIOCM_RTS, 100);
110 if (r < 0)
111 goto error;
112 r = setflags(cs, 0, 100);
113 if (r < 0)
114 goto error;
115 }
116 r = setflags(cs, TIOCM_RTS|TIOCM_DTR, 800);
117 if (r < 0)
118 goto error;
119
120 return 0;
121
122error:
784d5858 123 dev_err(cs->dev, "error %d on setuartbits\n", -r);
6fd5ea63
HL
124 cs->control_state = TIOCM_RTS|TIOCM_DTR; // FIXME is this a good value?
125 cs->ops->set_modem_ctrl(cs, 0, TIOCM_RTS|TIOCM_DTR);
126
127 return -1; //r
128}
129
130static int test_timeout(struct at_state_t *at_state)
131{
132 if (!at_state->timer_expires)
133 return 0;
134
135 if (--at_state->timer_expires) {
784d5858
TS
136 gig_dbg(DEBUG_MCMD, "decreased timer of %p to %lu",
137 at_state, at_state->timer_expires);
6fd5ea63
HL
138 return 0;
139 }
140
141 if (!gigaset_add_event(at_state->cs, at_state, EV_TIMEOUT, NULL,
69049cc8 142 at_state->timer_index, NULL)) {
6fd5ea63
HL
143 //FIXME what should we do?
144 }
145
146 return 1;
147}
148
149static void timer_tick(unsigned long data)
150{
151 struct cardstate *cs = (struct cardstate *) data;
152 unsigned long flags;
153 unsigned channel;
154 struct at_state_t *at_state;
155 int timeout = 0;
156
157 spin_lock_irqsave(&cs->lock, flags);
158
159 for (channel = 0; channel < cs->channels; ++channel)
160 if (test_timeout(&cs->bcs[channel].at_state))
161 timeout = 1;
162
163 if (test_timeout(&cs->at_state))
164 timeout = 1;
165
166 list_for_each_entry(at_state, &cs->temp_at_states, list)
167 if (test_timeout(at_state))
168 timeout = 1;
169
69049cc8 170 if (cs->running) {
ec81b5e6 171 mod_timer(&cs->timer, jiffies + msecs_to_jiffies(GIG_TICK));
6fd5ea63 172 if (timeout) {
784d5858 173 gig_dbg(DEBUG_CMD, "scheduling timeout");
6fd5ea63
HL
174 tasklet_schedule(&cs->event_tasklet);
175 }
176 }
177
178 spin_unlock_irqrestore(&cs->lock, flags);
179}
180
181int gigaset_get_channel(struct bc_state *bcs)
182{
183 unsigned long flags;
184
185 spin_lock_irqsave(&bcs->cs->lock, flags);
e468c048 186 if (bcs->use_count || !try_module_get(bcs->cs->driver->owner)) {
784d5858
TS
187 gig_dbg(DEBUG_ANY, "could not allocate channel %d",
188 bcs->channel);
6fd5ea63
HL
189 spin_unlock_irqrestore(&bcs->cs->lock, flags);
190 return 0;
191 }
192 ++bcs->use_count;
193 bcs->busy = 1;
784d5858 194 gig_dbg(DEBUG_ANY, "allocated channel %d", bcs->channel);
6fd5ea63
HL
195 spin_unlock_irqrestore(&bcs->cs->lock, flags);
196 return 1;
197}
198
199void gigaset_free_channel(struct bc_state *bcs)
200{
201 unsigned long flags;
202
203 spin_lock_irqsave(&bcs->cs->lock, flags);
204 if (!bcs->busy) {
784d5858 205 gig_dbg(DEBUG_ANY, "could not free channel %d", bcs->channel);
6fd5ea63
HL
206 spin_unlock_irqrestore(&bcs->cs->lock, flags);
207 return;
208 }
209 --bcs->use_count;
210 bcs->busy = 0;
e468c048 211 module_put(bcs->cs->driver->owner);
784d5858 212 gig_dbg(DEBUG_ANY, "freed channel %d", bcs->channel);
6fd5ea63
HL
213 spin_unlock_irqrestore(&bcs->cs->lock, flags);
214}
215
216int gigaset_get_channels(struct cardstate *cs)
217{
218 unsigned long flags;
219 int i;
220
221 spin_lock_irqsave(&cs->lock, flags);
222 for (i = 0; i < cs->channels; ++i)
223 if (cs->bcs[i].use_count) {
224 spin_unlock_irqrestore(&cs->lock, flags);
784d5858 225 gig_dbg(DEBUG_ANY, "could not allocate all channels");
6fd5ea63
HL
226 return 0;
227 }
228 for (i = 0; i < cs->channels; ++i)
229 ++cs->bcs[i].use_count;
230 spin_unlock_irqrestore(&cs->lock, flags);
231
784d5858 232 gig_dbg(DEBUG_ANY, "allocated all channels");
6fd5ea63
HL
233
234 return 1;
235}
236
237void gigaset_free_channels(struct cardstate *cs)
238{
239 unsigned long flags;
240 int i;
241
784d5858 242 gig_dbg(DEBUG_ANY, "unblocking all channels");
6fd5ea63
HL
243 spin_lock_irqsave(&cs->lock, flags);
244 for (i = 0; i < cs->channels; ++i)
245 --cs->bcs[i].use_count;
246 spin_unlock_irqrestore(&cs->lock, flags);
247}
248
249void gigaset_block_channels(struct cardstate *cs)
250{
251 unsigned long flags;
252 int i;
253
784d5858 254 gig_dbg(DEBUG_ANY, "blocking all channels");
6fd5ea63
HL
255 spin_lock_irqsave(&cs->lock, flags);
256 for (i = 0; i < cs->channels; ++i)
257 ++cs->bcs[i].use_count;
258 spin_unlock_irqrestore(&cs->lock, flags);
259}
260
261static void clear_events(struct cardstate *cs)
262{
263 struct event_t *ev;
264 unsigned head, tail;
69049cc8 265 unsigned long flags;
6fd5ea63 266
69049cc8 267 spin_lock_irqsave(&cs->ev_lock, flags);
6fd5ea63 268
69049cc8
TS
269 head = cs->ev_head;
270 tail = cs->ev_tail;
6fd5ea63
HL
271
272 while (tail != head) {
273 ev = cs->events + head;
274 kfree(ev->ptr);
6fd5ea63
HL
275 head = (head + 1) % MAX_EVENTS;
276 }
277
69049cc8
TS
278 cs->ev_head = tail;
279
280 spin_unlock_irqrestore(&cs->ev_lock, flags);
6fd5ea63
HL
281}
282
283struct event_t *gigaset_add_event(struct cardstate *cs,
784d5858
TS
284 struct at_state_t *at_state, int type,
285 void *ptr, int parameter, void *arg)
6fd5ea63
HL
286{
287 unsigned long flags;
288 unsigned next, tail;
289 struct event_t *event = NULL;
290
291 spin_lock_irqsave(&cs->ev_lock, flags);
292
69049cc8 293 tail = cs->ev_tail;
6fd5ea63 294 next = (tail + 1) % MAX_EVENTS;
69049cc8 295 if (unlikely(next == cs->ev_head))
5002779d 296 dev_err(cs->dev, "event queue full\n");
6fd5ea63
HL
297 else {
298 event = cs->events + tail;
299 event->type = type;
300 event->at_state = at_state;
301 event->cid = -1;
302 event->ptr = ptr;
303 event->arg = arg;
304 event->parameter = parameter;
69049cc8 305 cs->ev_tail = next;
6fd5ea63
HL
306 }
307
308 spin_unlock_irqrestore(&cs->ev_lock, flags);
309
310 return event;
311}
312EXPORT_SYMBOL_GPL(gigaset_add_event);
313
314static void free_strings(struct at_state_t *at_state)
315{
316 int i;
317
318 for (i = 0; i < STR_NUM; ++i) {
319 kfree(at_state->str_var[i]);
320 at_state->str_var[i] = NULL;
321 }
322}
323
324static void clear_at_state(struct at_state_t *at_state)
325{
326 free_strings(at_state);
327}
328
329static void dealloc_at_states(struct cardstate *cs)
330{
331 struct at_state_t *cur, *next;
332
333 list_for_each_entry_safe(cur, next, &cs->temp_at_states, list) {
334 list_del(&cur->list);
335 free_strings(cur);
336 kfree(cur);
337 }
338}
339
340static void gigaset_freebcs(struct bc_state *bcs)
341{
342 int i;
343
784d5858 344 gig_dbg(DEBUG_INIT, "freeing bcs[%d]->hw", bcs->channel);
6fd5ea63 345 if (!bcs->cs->ops->freebcshw(bcs)) {
784d5858 346 gig_dbg(DEBUG_INIT, "failed");
6fd5ea63
HL
347 }
348
784d5858 349 gig_dbg(DEBUG_INIT, "clearing bcs[%d]->at_state", bcs->channel);
6fd5ea63 350 clear_at_state(&bcs->at_state);
784d5858 351 gig_dbg(DEBUG_INIT, "freeing bcs[%d]->skb", bcs->channel);
6fd5ea63
HL
352
353 if (bcs->skb)
354 dev_kfree_skb(bcs->skb);
355 for (i = 0; i < AT_NUM; ++i) {
356 kfree(bcs->commands[i]);
357 bcs->commands[i] = NULL;
358 }
359}
360
70440cf2
TS
361static struct cardstate *alloc_cs(struct gigaset_driver *drv)
362{
363 unsigned long flags;
364 unsigned i;
e468c048 365 struct cardstate *cs;
e702ff0b 366 struct cardstate *ret = NULL;
70440cf2
TS
367
368 spin_lock_irqsave(&drv->lock, flags);
e468c048
TS
369 if (drv->blocked)
370 goto exit;
70440cf2 371 for (i = 0; i < drv->minors; ++i) {
e468c048
TS
372 cs = drv->cs + i;
373 if (!(cs->flags & VALID_MINOR)) {
374 cs->flags = VALID_MINOR;
375 ret = cs;
70440cf2 376 break;
e702ff0b 377 }
70440cf2 378 }
e468c048 379exit:
70440cf2
TS
380 spin_unlock_irqrestore(&drv->lock, flags);
381 return ret;
382}
383
384static void free_cs(struct cardstate *cs)
385{
e468c048 386 cs->flags = 0;
70440cf2
TS
387}
388
389static void make_valid(struct cardstate *cs, unsigned mask)
390{
391 unsigned long flags;
392 struct gigaset_driver *drv = cs->driver;
393 spin_lock_irqsave(&drv->lock, flags);
e468c048 394 cs->flags |= mask;
70440cf2
TS
395 spin_unlock_irqrestore(&drv->lock, flags);
396}
397
398static void make_invalid(struct cardstate *cs, unsigned mask)
399{
400 unsigned long flags;
401 struct gigaset_driver *drv = cs->driver;
402 spin_lock_irqsave(&drv->lock, flags);
e468c048 403 cs->flags &= ~mask;
70440cf2
TS
404 spin_unlock_irqrestore(&drv->lock, flags);
405}
406
6fd5ea63
HL
407void gigaset_freecs(struct cardstate *cs)
408{
409 int i;
410 unsigned long flags;
411
412 if (!cs)
413 return;
414
abfd1dc7 415 mutex_lock(&cs->mutex);
6fd5ea63
HL
416
417 if (!cs->bcs)
418 goto f_cs;
419 if (!cs->inbuf)
420 goto f_bcs;
421
422 spin_lock_irqsave(&cs->lock, flags);
69049cc8 423 cs->running = 0;
917f5085
TS
424 spin_unlock_irqrestore(&cs->lock, flags); /* event handler and timer are
425 not rescheduled below */
6fd5ea63
HL
426
427 tasklet_kill(&cs->event_tasklet);
428 del_timer_sync(&cs->timer);
429
430 switch (cs->cs_init) {
431 default:
3dda4e37
HL
432 /* clear device sysfs */
433 gigaset_free_dev_sysfs(cs);
434
6fd5ea63
HL
435 gigaset_if_free(cs);
436
784d5858 437 gig_dbg(DEBUG_INIT, "clearing hw");
6fd5ea63
HL
438 cs->ops->freecshw(cs);
439
440 //FIXME cmdbuf
441
442 /* fall through */
443 case 2: /* error in initcshw */
444 /* Deregister from LL */
445 make_invalid(cs, VALID_ID);
784d5858 446 gig_dbg(DEBUG_INIT, "clearing iif");
6fd5ea63
HL
447 gigaset_i4l_cmd(cs, ISDN_STAT_UNLOAD);
448
449 /* fall through */
450 case 1: /* error when regestering to LL */
784d5858 451 gig_dbg(DEBUG_INIT, "clearing at_state");
6fd5ea63
HL
452 clear_at_state(&cs->at_state);
453 dealloc_at_states(cs);
454
455 /* fall through */
456 case 0: /* error in one call to initbcs */
457 for (i = 0; i < cs->channels; ++i) {
784d5858 458 gig_dbg(DEBUG_INIT, "clearing bcs[%d]", i);
6fd5ea63
HL
459 gigaset_freebcs(cs->bcs + i);
460 }
461
462 clear_events(cs);
784d5858 463 gig_dbg(DEBUG_INIT, "freeing inbuf");
6fd5ea63
HL
464 kfree(cs->inbuf);
465 }
784d5858 466f_bcs: gig_dbg(DEBUG_INIT, "freeing bcs[]");
6fd5ea63 467 kfree(cs->bcs);
784d5858 468f_cs: gig_dbg(DEBUG_INIT, "freeing cs");
abfd1dc7 469 mutex_unlock(&cs->mutex);
6fd5ea63
HL
470 free_cs(cs);
471}
472EXPORT_SYMBOL_GPL(gigaset_freecs);
473
474void gigaset_at_init(struct at_state_t *at_state, struct bc_state *bcs,
784d5858 475 struct cardstate *cs, int cid)
6fd5ea63
HL
476{
477 int i;
478
479 INIT_LIST_HEAD(&at_state->list);
480 at_state->waiting = 0;
481 at_state->getstring = 0;
482 at_state->pending_commands = 0;
483 at_state->timer_expires = 0;
484 at_state->timer_active = 0;
69049cc8
TS
485 at_state->timer_index = 0;
486 at_state->seq_index = 0;
6fd5ea63
HL
487 at_state->ConState = 0;
488 for (i = 0; i < STR_NUM; ++i)
489 at_state->str_var[i] = NULL;
490 at_state->int_var[VAR_ZDLE] = 0;
491 at_state->int_var[VAR_ZCTP] = -1;
492 at_state->int_var[VAR_ZSAU] = ZSAU_NULL;
493 at_state->cs = cs;
494 at_state->bcs = bcs;
495 at_state->cid = cid;
496 if (!cid)
497 at_state->replystruct = cs->tabnocid;
498 else
499 at_state->replystruct = cs->tabcid;
500}
501
502
503static void gigaset_inbuf_init(struct inbuf_t *inbuf, struct bc_state *bcs,
784d5858 504 struct cardstate *cs, int inputstate)
6fd5ea63
HL
505/* inbuf->read must be allocated before! */
506{
9d4bee2b
TS
507 inbuf->head = 0;
508 inbuf->tail = 0;
6fd5ea63
HL
509 inbuf->cs = cs;
510 inbuf->bcs = bcs; /*base driver: NULL*/
9d4bee2b 511 inbuf->rcvbuf = NULL;
6fd5ea63
HL
512 inbuf->inputstate = inputstate;
513}
514
714e8236
TS
515/* append received bytes to inbuf */
516int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src,
517 unsigned numbytes)
518{
519 unsigned n, head, tail, bytesleft;
520
521 gig_dbg(DEBUG_INTR, "received %u bytes", numbytes);
522
523 if (!numbytes)
524 return 0;
525
526 bytesleft = numbytes;
9d4bee2b
TS
527 tail = inbuf->tail;
528 head = inbuf->head;
714e8236
TS
529 gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail);
530
531 while (bytesleft) {
532 if (head > tail)
533 n = head - 1 - tail;
534 else if (head == 0)
535 n = (RBUFSIZE-1) - tail;
536 else
537 n = RBUFSIZE - tail;
538 if (!n) {
539 dev_err(inbuf->cs->dev,
898eb71c
JP
540 "buffer overflow (%u bytes lost)\n",
541 bytesleft);
714e8236
TS
542 break;
543 }
544 if (n > bytesleft)
545 n = bytesleft;
546 memcpy(inbuf->data + tail, src, n);
547 bytesleft -= n;
548 tail = (tail + n) % RBUFSIZE;
549 src += n;
550 }
551 gig_dbg(DEBUG_INTR, "setting tail to %u", tail);
9d4bee2b 552 inbuf->tail = tail;
714e8236
TS
553 return numbytes != bytesleft;
554}
555EXPORT_SYMBOL_GPL(gigaset_fill_inbuf);
556
6fd5ea63
HL
557/* Initialize the b-channel structure */
558static struct bc_state *gigaset_initbcs(struct bc_state *bcs,
784d5858 559 struct cardstate *cs, int channel)
6fd5ea63
HL
560{
561 int i;
562
563 bcs->tx_skb = NULL; //FIXME -> hw part
564
565 skb_queue_head_init(&bcs->squeue);
566
567 bcs->corrupted = 0;
568 bcs->trans_down = 0;
569 bcs->trans_up = 0;
570
784d5858 571 gig_dbg(DEBUG_INIT, "setting up bcs[%d]->at_state", channel);
6fd5ea63
HL
572 gigaset_at_init(&bcs->at_state, bcs, cs, -1);
573
6fd5ea63
HL
574#ifdef CONFIG_GIGASET_DEBUG
575 bcs->emptycount = 0;
576#endif
577
784d5858 578 gig_dbg(DEBUG_INIT, "allocating bcs[%d]->skb", channel);
6fd5ea63
HL
579 bcs->fcs = PPP_INITFCS;
580 bcs->inputstate = 0;
581 if (cs->ignoreframes) {
582 bcs->inputstate |= INS_skip_frame;
583 bcs->skb = NULL;
584 } else if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)
585 skb_reserve(bcs->skb, HW_HDR_LEN);
586 else {
c8770dca 587 pr_err("out of memory\n");
6fd5ea63
HL
588 bcs->inputstate |= INS_skip_frame;
589 }
590
591 bcs->channel = channel;
592 bcs->cs = cs;
593
594 bcs->chstate = 0;
595 bcs->use_count = 1;
596 bcs->busy = 0;
597 bcs->ignore = cs->ignoreframes;
598
599 for (i = 0; i < AT_NUM; ++i)
600 bcs->commands[i] = NULL;
601
784d5858 602 gig_dbg(DEBUG_INIT, " setting up bcs[%d]->hw", channel);
6fd5ea63
HL
603 if (cs->ops->initbcshw(bcs))
604 return bcs;
605
784d5858 606 gig_dbg(DEBUG_INIT, " failed");
6fd5ea63 607
784d5858 608 gig_dbg(DEBUG_INIT, " freeing bcs[%d]->skb", channel);
6fd5ea63
HL
609 if (bcs->skb)
610 dev_kfree_skb(bcs->skb);
611
612 return NULL;
613}
614
615/* gigaset_initcs
616 * Allocate and initialize cardstate structure for Gigaset driver
617 * Calls hardware dependent gigaset_initcshw() function
618 * Calls B channel initialization function gigaset_initbcs() for each B channel
619 * parameters:
784d5858 620 * drv hardware driver the device belongs to
6fd5ea63 621 * channels number of B channels supported by device
917f5085
TS
622 * onechannel !=0: B channel data and AT commands share one
623 * communication channel
6fd5ea63
HL
624 * ==0: B channels have separate communication channels
625 * ignoreframes number of frames to ignore after setting up B channel
626 * cidmode !=0: start in CallID mode
627 * modulename name of driver module (used for I4L registration)
628 * return value:
629 * pointer to cardstate structure
630 */
631struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
632 int onechannel, int ignoreframes,
633 int cidmode, const char *modulename)
634{
635 struct cardstate *cs = NULL;
69049cc8 636 unsigned long flags;
6fd5ea63
HL
637 int i;
638
784d5858 639 gig_dbg(DEBUG_INIT, "allocating cs");
e702ff0b 640 if (!(cs = alloc_cs(drv))) {
c8770dca 641 pr_err("maximum number of devices exceeded\n");
e702ff0b
TS
642 return NULL;
643 }
e702ff0b 644
784d5858 645 gig_dbg(DEBUG_INIT, "allocating bcs[0..%d]", channels - 1);
6fd5ea63 646 cs->bcs = kmalloc(channels * sizeof(struct bc_state), GFP_KERNEL);
e702ff0b 647 if (!cs->bcs) {
c8770dca 648 pr_err("out of memory\n");
6fd5ea63 649 goto error;
e702ff0b 650 }
784d5858 651 gig_dbg(DEBUG_INIT, "allocating inbuf");
6fd5ea63 652 cs->inbuf = kmalloc(sizeof(struct inbuf_t), GFP_KERNEL);
e702ff0b 653 if (!cs->inbuf) {
c8770dca 654 pr_err("out of memory\n");
6fd5ea63 655 goto error;
e702ff0b 656 }
6fd5ea63
HL
657
658 cs->cs_init = 0;
659 cs->channels = channels;
660 cs->onechannel = onechannel;
661 cs->ignoreframes = ignoreframes;
662 INIT_LIST_HEAD(&cs->temp_at_states);
69049cc8 663 cs->running = 0;
6fd5ea63
HL
664 init_timer(&cs->timer); /* clear next & prev */
665 spin_lock_init(&cs->ev_lock);
69049cc8
TS
666 cs->ev_tail = 0;
667 cs->ev_head = 0;
abfd1dc7 668
917f5085
TS
669 tasklet_init(&cs->event_tasklet, &gigaset_handle_event,
670 (unsigned long) cs);
9d4bee2b 671 cs->commands_pending = 0;
6fd5ea63
HL
672 cs->cur_at_seq = 0;
673 cs->gotfwver = -1;
674 cs->open_count = 0;
784d5858 675 cs->dev = NULL;
6fd5ea63 676 cs->tty = NULL;
01107d34 677 cs->tty_dev = NULL;
69049cc8 678 cs->cidmode = cidmode != 0;
528efc6a
TS
679 cs->tabnocid = gigaset_tab_nocid;
680 cs->tabcid = gigaset_tab_cid;
6fd5ea63
HL
681
682 init_waitqueue_head(&cs->waitqueue);
683 cs->waiting = 0;
684
9d4bee2b
TS
685 cs->mode = M_UNKNOWN;
686 cs->mstate = MS_UNINITIALIZED;
6fd5ea63
HL
687
688 for (i = 0; i < channels; ++i) {
784d5858 689 gig_dbg(DEBUG_INIT, "setting up bcs[%d].read", i);
e702ff0b 690 if (!gigaset_initbcs(cs->bcs + i, cs, i)) {
c8770dca 691 pr_err("could not allocate channel %d data\n", i);
6fd5ea63 692 goto error;
e702ff0b 693 }
6fd5ea63
HL
694 }
695
696 ++cs->cs_init;
697
784d5858 698 gig_dbg(DEBUG_INIT, "setting up at_state");
6fd5ea63
HL
699 spin_lock_init(&cs->lock);
700 gigaset_at_init(&cs->at_state, NULL, cs, 0);
701 cs->dle = 0;
702 cs->cbytes = 0;
703
784d5858 704 gig_dbg(DEBUG_INIT, "setting up inbuf");
6fd5ea63
HL
705 if (onechannel) { //FIXME distinction necessary?
706 gigaset_inbuf_init(cs->inbuf, cs->bcs, cs, INS_command);
707 } else
708 gigaset_inbuf_init(cs->inbuf, NULL, cs, INS_command);
709
69049cc8
TS
710 cs->connected = 0;
711 cs->isdn_up = 0;
6fd5ea63 712
784d5858 713 gig_dbg(DEBUG_INIT, "setting up cmdbuf");
6fd5ea63
HL
714 cs->cmdbuf = cs->lastcmdbuf = NULL;
715 spin_lock_init(&cs->cmdlock);
716 cs->curlen = 0;
717 cs->cmdbytes = 0;
718
784d5858 719 gig_dbg(DEBUG_INIT, "setting up iif");
6fd5ea63 720 if (!gigaset_register_to_LL(cs, modulename)) {
c8770dca 721 pr_err("error registering ISDN device\n");
6fd5ea63
HL
722 goto error;
723 }
724
725 make_valid(cs, VALID_ID);
726 ++cs->cs_init;
784d5858 727 gig_dbg(DEBUG_INIT, "setting up hw");
c8770dca 728 if (!cs->ops->initcshw(cs))
6fd5ea63
HL
729 goto error;
730
731 ++cs->cs_init;
732
7435f50e 733 /* set up character device */
6fd5ea63
HL
734 gigaset_if_init(cs);
735
3dda4e37
HL
736 /* set up device sysfs */
737 gigaset_init_dev_sysfs(cs);
738
69049cc8
TS
739 spin_lock_irqsave(&cs->lock, flags);
740 cs->running = 1;
741 spin_unlock_irqrestore(&cs->lock, flags);
ec81b5e6
TS
742 setup_timer(&cs->timer, timer_tick, (unsigned long) cs);
743 cs->timer.expires = jiffies + msecs_to_jiffies(GIG_TICK);
6fd5ea63
HL
744 /* FIXME: can jiffies increase too much until the timer is added?
745 * Same problem(?) with mod_timer() in timer_tick(). */
746 add_timer(&cs->timer);
747
784d5858 748 gig_dbg(DEBUG_INIT, "cs initialized");
6fd5ea63
HL
749 return cs;
750
e702ff0b 751error:
784d5858 752 gig_dbg(DEBUG_INIT, "failed");
6fd5ea63
HL
753 gigaset_freecs(cs);
754 return NULL;
755}
756EXPORT_SYMBOL_GPL(gigaset_initcs);
757
73a88814 758/* ReInitialize the b-channel structure on hangup */
6fd5ea63
HL
759void gigaset_bcs_reinit(struct bc_state *bcs)
760{
761 struct sk_buff *skb;
762 struct cardstate *cs = bcs->cs;
763 unsigned long flags;
764
765 while ((skb = skb_dequeue(&bcs->squeue)) != NULL)
766 dev_kfree_skb(skb);
767
917f5085 768 spin_lock_irqsave(&cs->lock, flags);
6fd5ea63
HL
769 clear_at_state(&bcs->at_state);
770 bcs->at_state.ConState = 0;
771 bcs->at_state.timer_active = 0;
772 bcs->at_state.timer_expires = 0;
784d5858 773 bcs->at_state.cid = -1; /* No CID defined */
6fd5ea63
HL
774 spin_unlock_irqrestore(&cs->lock, flags);
775
776 bcs->inputstate = 0;
777
778#ifdef CONFIG_GIGASET_DEBUG
779 bcs->emptycount = 0;
780#endif
781
782 bcs->fcs = PPP_INITFCS;
783 bcs->chstate = 0;
784
785 bcs->ignore = cs->ignoreframes;
786 if (bcs->ignore)
787 bcs->inputstate |= INS_skip_frame;
788
789
790 cs->ops->reinitbcshw(bcs);
791}
792
793static void cleanup_cs(struct cardstate *cs)
794{
795 struct cmdbuf_t *cb, *tcb;
796 int i;
797 unsigned long flags;
798
799 spin_lock_irqsave(&cs->lock, flags);
800
9d4bee2b
TS
801 cs->mode = M_UNKNOWN;
802 cs->mstate = MS_UNINITIALIZED;
6fd5ea63
HL
803
804 clear_at_state(&cs->at_state);
805 dealloc_at_states(cs);
806 free_strings(&cs->at_state);
807 gigaset_at_init(&cs->at_state, NULL, cs, 0);
808
809 kfree(cs->inbuf->rcvbuf);
810 cs->inbuf->rcvbuf = NULL;
811 cs->inbuf->inputstate = INS_command;
9d4bee2b
TS
812 cs->inbuf->head = 0;
813 cs->inbuf->tail = 0;
6fd5ea63
HL
814
815 cb = cs->cmdbuf;
816 while (cb) {
817 tcb = cb;
818 cb = cb->next;
819 kfree(tcb);
820 }
821 cs->cmdbuf = cs->lastcmdbuf = NULL;
822 cs->curlen = 0;
823 cs->cmdbytes = 0;
824 cs->gotfwver = -1;
825 cs->dle = 0;
826 cs->cur_at_seq = 0;
9d4bee2b 827 cs->commands_pending = 0;
6fd5ea63
HL
828 cs->cbytes = 0;
829
830 spin_unlock_irqrestore(&cs->lock, flags);
831
832 for (i = 0; i < cs->channels; ++i) {
833 gigaset_freebcs(cs->bcs + i);
834 if (!gigaset_initbcs(cs->bcs + i, cs, i))
c8770dca 835 pr_err("could not allocate channel %d data\n", i);
6fd5ea63
HL
836 }
837
838 if (cs->waiting) {
839 cs->cmd_result = -ENODEV;
840 cs->waiting = 0;
841 wake_up_interruptible(&cs->waitqueue);
842 }
843}
844
845
846int gigaset_start(struct cardstate *cs)
847{
69049cc8
TS
848 unsigned long flags;
849
abfd1dc7 850 if (mutex_lock_interruptible(&cs->mutex))
6fd5ea63 851 return 0;
6fd5ea63 852
69049cc8
TS
853 spin_lock_irqsave(&cs->lock, flags);
854 cs->connected = 1;
855 spin_unlock_irqrestore(&cs->lock, flags);
6fd5ea63 856
9d4bee2b 857 if (cs->mstate != MS_LOCKED) {
6fd5ea63
HL
858 cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR|TIOCM_RTS);
859 cs->ops->baud_rate(cs, B115200);
860 cs->ops->set_line_ctrl(cs, CS8);
861 cs->control_state = TIOCM_DTR|TIOCM_RTS;
862 } else {
863 //FIXME use some saved values?
864 }
865
866 cs->waiting = 1;
867
868 if (!gigaset_add_event(cs, &cs->at_state, EV_START, NULL, 0, NULL)) {
869 cs->waiting = 0;
870 //FIXME what should we do?
871 goto error;
872 }
873
784d5858 874 gig_dbg(DEBUG_CMD, "scheduling START");
6fd5ea63
HL
875 gigaset_schedule_event(cs);
876
877 wait_event(cs->waitqueue, !cs->waiting);
878
abfd1dc7 879 mutex_unlock(&cs->mutex);
6fd5ea63
HL
880 return 1;
881
882error:
abfd1dc7 883 mutex_unlock(&cs->mutex);
6fd5ea63
HL
884 return 0;
885}
886EXPORT_SYMBOL_GPL(gigaset_start);
887
e468c048
TS
888/* gigaset_shutdown
889 * check if a device is associated to the cardstate structure and stop it
890 * return value: 0 if ok, -1 if no device was associated
891 */
892int gigaset_shutdown(struct cardstate *cs)
6fd5ea63 893{
abfd1dc7 894 mutex_lock(&cs->mutex);
6fd5ea63 895
5d49c101
TS
896 if (!(cs->flags & VALID_MINOR)) {
897 mutex_unlock(&cs->mutex);
e468c048 898 return -1;
5d49c101 899 }
e468c048 900
6fd5ea63
HL
901 cs->waiting = 1;
902
903 if (!gigaset_add_event(cs, &cs->at_state, EV_SHUTDOWN, NULL, 0, NULL)) {
904 //FIXME what should we do?
905 goto exit;
906 }
907
784d5858 908 gig_dbg(DEBUG_CMD, "scheduling SHUTDOWN");
6fd5ea63
HL
909 gigaset_schedule_event(cs);
910
2869b23e 911 wait_event(cs->waitqueue, !cs->waiting);
6fd5ea63
HL
912
913 cleanup_cs(cs);
914
915exit:
abfd1dc7 916 mutex_unlock(&cs->mutex);
e468c048 917 return 0;
6fd5ea63
HL
918}
919EXPORT_SYMBOL_GPL(gigaset_shutdown);
920
921void gigaset_stop(struct cardstate *cs)
922{
abfd1dc7 923 mutex_lock(&cs->mutex);
6fd5ea63 924
6fd5ea63
HL
925 cs->waiting = 1;
926
927 if (!gigaset_add_event(cs, &cs->at_state, EV_STOP, NULL, 0, NULL)) {
928 //FIXME what should we do?
929 goto exit;
930 }
931
784d5858 932 gig_dbg(DEBUG_CMD, "scheduling STOP");
6fd5ea63
HL
933 gigaset_schedule_event(cs);
934
2869b23e 935 wait_event(cs->waitqueue, !cs->waiting);
6fd5ea63 936
6fd5ea63
HL
937 cleanup_cs(cs);
938
939exit:
abfd1dc7 940 mutex_unlock(&cs->mutex);
6fd5ea63
HL
941}
942EXPORT_SYMBOL_GPL(gigaset_stop);
943
944static LIST_HEAD(drivers);
34af946a 945static DEFINE_SPINLOCK(driver_lock);
6fd5ea63
HL
946
947struct cardstate *gigaset_get_cs_by_id(int id)
948{
949 unsigned long flags;
35dc8457
TS
950 struct cardstate *ret = NULL;
951 struct cardstate *cs;
6fd5ea63
HL
952 struct gigaset_driver *drv;
953 unsigned i;
954
955 spin_lock_irqsave(&driver_lock, flags);
956 list_for_each_entry(drv, &drivers, list) {
957 spin_lock(&drv->lock);
958 for (i = 0; i < drv->minors; ++i) {
e468c048
TS
959 cs = drv->cs + i;
960 if ((cs->flags & VALID_ID) && cs->myid == id) {
961 ret = cs;
6fd5ea63 962 break;
e468c048 963 }
6fd5ea63
HL
964 }
965 spin_unlock(&drv->lock);
966 if (ret)
967 break;
968 }
969 spin_unlock_irqrestore(&driver_lock, flags);
970 return ret;
971}
972
973void gigaset_debugdrivers(void)
974{
975 unsigned long flags;
976 static struct cardstate *cs;
977 struct gigaset_driver *drv;
978 unsigned i;
979
980 spin_lock_irqsave(&driver_lock, flags);
981 list_for_each_entry(drv, &drivers, list) {
784d5858 982 gig_dbg(DEBUG_DRIVER, "driver %p", drv);
6fd5ea63
HL
983 spin_lock(&drv->lock);
984 for (i = 0; i < drv->minors; ++i) {
784d5858 985 gig_dbg(DEBUG_DRIVER, " index %u", i);
6fd5ea63 986 cs = drv->cs + i;
784d5858 987 gig_dbg(DEBUG_DRIVER, " cardstate %p", cs);
e468c048 988 gig_dbg(DEBUG_DRIVER, " flags 0x%02x", cs->flags);
784d5858
TS
989 gig_dbg(DEBUG_DRIVER, " minor_index %u",
990 cs->minor_index);
991 gig_dbg(DEBUG_DRIVER, " driver %p", cs->driver);
992 gig_dbg(DEBUG_DRIVER, " i4l id %d", cs->myid);
6fd5ea63
HL
993 }
994 spin_unlock(&drv->lock);
995 }
996 spin_unlock_irqrestore(&driver_lock, flags);
997}
6fd5ea63 998
8ca445df 999static struct cardstate *gigaset_get_cs_by_minor(unsigned minor)
6fd5ea63
HL
1000{
1001 unsigned long flags;
35dc8457 1002 struct cardstate *ret = NULL;
6fd5ea63
HL
1003 struct gigaset_driver *drv;
1004 unsigned index;
1005
1006 spin_lock_irqsave(&driver_lock, flags);
1007 list_for_each_entry(drv, &drivers, list) {
1008 if (minor < drv->minor || minor >= drv->minor + drv->minors)
1009 continue;
1010 index = minor - drv->minor;
1011 spin_lock(&drv->lock);
e468c048 1012 if (drv->cs[index].flags & VALID_MINOR)
6fd5ea63
HL
1013 ret = drv->cs + index;
1014 spin_unlock(&drv->lock);
1015 if (ret)
1016 break;
1017 }
1018 spin_unlock_irqrestore(&driver_lock, flags);
1019 return ret;
1020}
1021
8ca445df
AB
1022struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty)
1023{
1024 if (tty->index < 0 || tty->index >= tty->driver->num)
1025 return NULL;
1026 return gigaset_get_cs_by_minor(tty->index + tty->driver->minor_start);
1027}
1028
6fd5ea63
HL
1029void gigaset_freedriver(struct gigaset_driver *drv)
1030{
1031 unsigned long flags;
1032
1033 spin_lock_irqsave(&driver_lock, flags);
1034 list_del(&drv->list);
1035 spin_unlock_irqrestore(&driver_lock, flags);
1036
1037 gigaset_if_freedriver(drv);
6fd5ea63
HL
1038
1039 kfree(drv->cs);
6fd5ea63
HL
1040 kfree(drv);
1041}
1042EXPORT_SYMBOL_GPL(gigaset_freedriver);
1043
1044/* gigaset_initdriver
1045 * Allocate and initialize gigaset_driver structure. Initialize interface.
1046 * parameters:
784d5858
TS
1047 * minor First minor number
1048 * minors Number of minors this driver can handle
1049 * procname Name of the driver
1050 * devname Name of the device files (prefix without minor number)
6fd5ea63 1051 * return value:
784d5858 1052 * Pointer to the gigaset_driver structure on success, NULL on failure.
6fd5ea63
HL
1053 */
1054struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors,
784d5858
TS
1055 const char *procname,
1056 const char *devname,
784d5858
TS
1057 const struct gigaset_ops *ops,
1058 struct module *owner)
6fd5ea63
HL
1059{
1060 struct gigaset_driver *drv;
1061 unsigned long flags;
1062 unsigned i;
1063
1064 drv = kmalloc(sizeof *drv, GFP_KERNEL);
1065 if (!drv)
1066 return NULL;
f4675c70 1067
6fd5ea63
HL
1068 drv->have_tty = 0;
1069 drv->minor = minor;
1070 drv->minors = minors;
1071 spin_lock_init(&drv->lock);
1072 drv->blocked = 0;
1073 drv->ops = ops;
1074 drv->owner = owner;
1075 INIT_LIST_HEAD(&drv->list);
1076
1077 drv->cs = kmalloc(minors * sizeof *drv->cs, GFP_KERNEL);
1078 if (!drv->cs)
e702ff0b 1079 goto error;
f4675c70 1080
6fd5ea63 1081 for (i = 0; i < minors; ++i) {
e468c048 1082 drv->cs[i].flags = 0;
6fd5ea63
HL
1083 drv->cs[i].driver = drv;
1084 drv->cs[i].ops = drv->ops;
1085 drv->cs[i].minor_index = i;
5d49c101 1086 mutex_init(&drv->cs[i].mutex);
6fd5ea63
HL
1087 }
1088
f4eaa370 1089 gigaset_if_initdriver(drv, procname, devname);
6fd5ea63
HL
1090
1091 spin_lock_irqsave(&driver_lock, flags);
1092 list_add(&drv->list, &drivers);
1093 spin_unlock_irqrestore(&driver_lock, flags);
1094
1095 return drv;
1096
e702ff0b 1097error:
6fd5ea63 1098 kfree(drv->cs);
6fd5ea63 1099 kfree(drv);
6fd5ea63
HL
1100 return NULL;
1101}
1102EXPORT_SYMBOL_GPL(gigaset_initdriver);
1103
6fd5ea63
HL
1104void gigaset_blockdriver(struct gigaset_driver *drv)
1105{
6fd5ea63 1106 drv->blocked = 1;
6fd5ea63
HL
1107}
1108EXPORT_SYMBOL_GPL(gigaset_blockdriver);
1109
1110static int __init gigaset_init_module(void)
1111{
1112 /* in accordance with the principle of least astonishment,
1113 * setting the 'debug' parameter to 1 activates a sensible
1114 * set of default debug levels
1115 */
1116 if (gigaset_debuglevel == 1)
1117 gigaset_debuglevel = DEBUG_DEFAULT;
1118
2038724c 1119 pr_info(DRIVER_DESC DRIVER_DESC_DEBUG "\n");
6fd5ea63
HL
1120 return 0;
1121}
1122
1123static void __exit gigaset_exit_module(void)
1124{
1125}
1126
1127module_init(gigaset_init_module);
1128module_exit(gigaset_exit_module);
1129
1130MODULE_AUTHOR(DRIVER_AUTHOR);
1131MODULE_DESCRIPTION(DRIVER_DESC);
1132
1133MODULE_LICENSE("GPL");