Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
i4l.c
Go to the documentation of this file.
1 /*
2  * Stuff used by all variants of the driver
3  *
4  * Copyright (c) 2001 by Stefan Eilers,
5  * Hansjoerg Lipp <[email protected]>,
6  * Tilman Schmidt <[email protected]>.
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  * =====================================================================
14  */
15 
16 #include "gigaset.h"
17 #include <linux/isdnif.h>
18 #include <linux/export.h>
19 
20 #define SBUFSIZE 4096 /* sk_buff payload size */
21 #define TRANSBUFSIZE 768 /* bytes per skb for transparent receive */
22 #define HW_HDR_LEN 2 /* Header size used to store ack info */
23 #define MAX_BUF_SIZE (SBUFSIZE - HW_HDR_LEN) /* max data packet from LL */
24 
25 /* == Handling of I4L IO =====================================================*/
26 
27 /* writebuf_from_LL
28  * called by LL to transmit data on an open channel
29  * inserts the buffer data into the send queue and starts the transmission
30  * Note that this operation must not sleep!
31  * When the buffer is processed completely, gigaset_skb_sent() should be called.
32  * parameters:
33  * driverID driver ID as assigned by LL
34  * channel channel number
35  * ack if != 0 LL wants to be notified on completion via
36  * statcallb(ISDN_STAT_BSENT)
37  * skb skb containing data to send
38  * return value:
39  * number of accepted bytes
40  * 0 if temporarily unable to accept data (out of buffer space)
41  * <0 on error (eg. -EINVAL)
42  */
43 static int writebuf_from_LL(int driverID, int channel, int ack,
44  struct sk_buff *skb)
45 {
46  struct cardstate *cs = gigaset_get_cs_by_id(driverID);
47  struct bc_state *bcs;
48  unsigned char *ack_header;
49  unsigned len;
50 
51  if (!cs) {
52  pr_err("%s: invalid driver ID (%d)\n", __func__, driverID);
53  return -ENODEV;
54  }
56  dev_err(cs->dev, "%s: invalid channel ID (%d)\n",
57  __func__, channel);
58  return -ENODEV;
59  }
60  bcs = &cs->bcs[channel];
61 
62  /* can only handle linear sk_buffs */
63  if (skb_linearize(skb) < 0) {
64  dev_err(cs->dev, "%s: skb_linearize failed\n", __func__);
65  return -ENOMEM;
66  }
67  len = skb->len;
68 
70  "Receiving data from LL (id: %d, ch: %d, ack: %d, sz: %d)",
71  driverID, channel, ack, len);
72 
73  if (!len) {
74  if (ack)
75  dev_notice(cs->dev, "%s: not ACKing empty packet\n",
76  __func__);
77  return 0;
78  }
79  if (len > MAX_BUF_SIZE) {
80  dev_err(cs->dev, "%s: packet too large (%d bytes)\n",
81  __func__, len);
82  return -EINVAL;
83  }
84 
85  /* set up acknowledgement header */
86  if (skb_headroom(skb) < HW_HDR_LEN) {
87  /* should never happen */
88  dev_err(cs->dev, "%s: insufficient skb headroom\n", __func__);
89  return -ENOMEM;
90  }
91  skb_set_mac_header(skb, -HW_HDR_LEN);
92  skb->mac_len = HW_HDR_LEN;
93  ack_header = skb_mac_header(skb);
94  if (ack) {
95  ack_header[0] = len & 0xff;
96  ack_header[1] = len >> 8;
97  } else {
98  ack_header[0] = ack_header[1] = 0;
99  }
100  gig_dbg(DEBUG_MCMD, "skb: len=%u, ack=%d: %02x %02x",
101  len, ack, ack_header[0], ack_header[1]);
102 
103  /* pass to device-specific module */
104  return cs->ops->send_skb(bcs, skb);
105 }
106 
115 void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb)
116 {
117  isdn_if *iif = bcs->cs->iif;
118  unsigned char *ack_header = skb_mac_header(skb);
119  unsigned len;
121 
122  ++bcs->trans_up;
123 
124  if (skb->len)
125  dev_warn(bcs->cs->dev, "%s: skb->len==%d\n",
126  __func__, skb->len);
127 
128  len = ack_header[0] + ((unsigned) ack_header[1] << 8);
129  if (len) {
130  gig_dbg(DEBUG_MCMD, "ACKing to LL (id: %d, ch: %d, sz: %u)",
131  bcs->cs->myid, bcs->channel, len);
132 
133  response.driver = bcs->cs->myid;
134  response.command = ISDN_STAT_BSENT;
135  response.arg = bcs->channel;
136  response.parm.length = len;
137  iif->statcallb(&response);
138  }
139 }
141 
151 void gigaset_skb_rcvd(struct bc_state *bcs, struct sk_buff *skb)
152 {
153  isdn_if *iif = bcs->cs->iif;
154 
155  iif->rcvcallb_skb(bcs->cs->myid, bcs->channel, skb);
156  bcs->trans_down++;
157 }
159 
168 {
169  isdn_if *iif = bcs->cs->iif;
171 
172  /* if currently ignoring packets, just count down */
173  if (bcs->ignore) {
174  bcs->ignore--;
175  return;
176  }
177 
178  /* update statistics */
179  bcs->corrupted++;
180 
181  /* error -> LL */
182  gig_dbg(DEBUG_CMD, "sending L1ERR");
183  response.driver = bcs->cs->myid;
184  response.command = ISDN_STAT_L1ERR;
185  response.arg = bcs->channel;
186  response.parm.errcode = ISDN_STAT_L1ERR_RECV;
187  iif->statcallb(&response);
188 }
190 
191 /* This function will be called by LL to send commands
192  * NOTE: LL ignores the returned value, for commands other than ISDN_CMD_IOCTL,
193  * so don't put too much effort into it.
194  */
195 static int command_from_LL(isdn_ctrl *cntrl)
196 {
197  struct cardstate *cs;
198  struct bc_state *bcs;
199  int retval = 0;
200  char **commands;
201  int ch;
202  int i;
203  size_t l;
204 
205  gig_dbg(DEBUG_CMD, "driver: %d, command: %d, arg: 0x%lx",
206  cntrl->driver, cntrl->command, cntrl->arg);
207 
208  cs = gigaset_get_cs_by_id(cntrl->driver);
209  if (cs == NULL) {
210  pr_err("%s: invalid driver ID (%d)\n", __func__, cntrl->driver);
211  return -ENODEV;
212  }
213  ch = cntrl->arg & 0xff;
214 
215  switch (cntrl->command) {
216  case ISDN_CMD_IOCTL:
217  dev_warn(cs->dev, "ISDN_CMD_IOCTL not supported\n");
218  return -EINVAL;
219 
220  case ISDN_CMD_DIAL:
222  "ISDN_CMD_DIAL (phone: %s, msn: %s, si1: %d, si2: %d)",
223  cntrl->parm.setup.phone, cntrl->parm.setup.eazmsn,
224  cntrl->parm.setup.si1, cntrl->parm.setup.si2);
225 
226  if (ch >= cs->channels) {
227  dev_err(cs->dev,
228  "ISDN_CMD_DIAL: invalid channel (%d)\n", ch);
229  return -EINVAL;
230  }
231  bcs = cs->bcs + ch;
232  if (gigaset_get_channel(bcs) < 0) {
233  dev_err(cs->dev, "ISDN_CMD_DIAL: channel not free\n");
234  return -EBUSY;
235  }
236  switch (bcs->proto2) {
237  case L2_HDLC:
238  bcs->rx_bufsize = SBUFSIZE;
239  break;
240  default: /* assume transparent */
241  bcs->rx_bufsize = TRANSBUFSIZE;
242  }
243  dev_kfree_skb(bcs->rx_skb);
244  gigaset_new_rx_skb(bcs);
245 
246  commands = kzalloc(AT_NUM * (sizeof *commands), GFP_ATOMIC);
247  if (!commands) {
249  dev_err(cs->dev, "ISDN_CMD_DIAL: out of memory\n");
250  return -ENOMEM;
251  }
252 
253  l = 3 + strlen(cntrl->parm.setup.phone);
254  commands[AT_DIAL] = kmalloc(l, GFP_ATOMIC);
255  if (!commands[AT_DIAL])
256  goto oom;
257  if (cntrl->parm.setup.phone[0] == '*' &&
258  cntrl->parm.setup.phone[1] == '*') {
259  /* internal call: translate ** prefix to CTP value */
260  commands[AT_TYPE] = kstrdup("^SCTP=0\r", GFP_ATOMIC);
261  if (!commands[AT_TYPE])
262  goto oom;
263  snprintf(commands[AT_DIAL], l,
264  "D%s\r", cntrl->parm.setup.phone + 2);
265  } else {
266  commands[AT_TYPE] = kstrdup("^SCTP=1\r", GFP_ATOMIC);
267  if (!commands[AT_TYPE])
268  goto oom;
269  snprintf(commands[AT_DIAL], l,
270  "D%s\r", cntrl->parm.setup.phone);
271  }
272 
273  l = strlen(cntrl->parm.setup.eazmsn);
274  if (l) {
275  l += 8;
276  commands[AT_MSN] = kmalloc(l, GFP_ATOMIC);
277  if (!commands[AT_MSN])
278  goto oom;
279  snprintf(commands[AT_MSN], l, "^SMSN=%s\r",
280  cntrl->parm.setup.eazmsn);
281  }
282 
283  switch (cntrl->parm.setup.si1) {
284  case 1: /* audio */
285  /* BC = 9090A3: 3.1 kHz audio, A-law */
286  commands[AT_BC] = kstrdup("^SBC=9090A3\r", GFP_ATOMIC);
287  if (!commands[AT_BC])
288  goto oom;
289  break;
290  case 7: /* data */
291  default: /* hope the app knows what it is doing */
292  /* BC = 8890: unrestricted digital information */
293  commands[AT_BC] = kstrdup("^SBC=8890\r", GFP_ATOMIC);
294  if (!commands[AT_BC])
295  goto oom;
296  }
297  /* ToDo: other si1 values, inspect si2, set HLC/LLC */
298 
299  commands[AT_PROTO] = kmalloc(9, GFP_ATOMIC);
300  if (!commands[AT_PROTO])
301  goto oom;
302  snprintf(commands[AT_PROTO], 9, "^SBPR=%u\r", bcs->proto2);
303 
304  commands[AT_ISO] = kmalloc(9, GFP_ATOMIC);
305  if (!commands[AT_ISO])
306  goto oom;
307  snprintf(commands[AT_ISO], 9, "^SISO=%u\r",
308  (unsigned) bcs->channel + 1);
309 
310  if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, commands,
311  bcs->at_state.seq_index, NULL)) {
312  for (i = 0; i < AT_NUM; ++i)
313  kfree(commands[i]);
314  kfree(commands);
316  return -ENOMEM;
317  }
318  gigaset_schedule_event(cs);
319  break;
320  case ISDN_CMD_ACCEPTD:
321  gig_dbg(DEBUG_CMD, "ISDN_CMD_ACCEPTD");
322  if (ch >= cs->channels) {
323  dev_err(cs->dev,
324  "ISDN_CMD_ACCEPTD: invalid channel (%d)\n", ch);
325  return -EINVAL;
326  }
327  bcs = cs->bcs + ch;
328  switch (bcs->proto2) {
329  case L2_HDLC:
330  bcs->rx_bufsize = SBUFSIZE;
331  break;
332  default: /* assume transparent */
333  bcs->rx_bufsize = TRANSBUFSIZE;
334  }
335  dev_kfree_skb(bcs->rx_skb);
336  gigaset_new_rx_skb(bcs);
337  if (!gigaset_add_event(cs, &bcs->at_state,
338  EV_ACCEPT, NULL, 0, NULL))
339  return -ENOMEM;
340  gigaset_schedule_event(cs);
341 
342  break;
343  case ISDN_CMD_HANGUP:
344  gig_dbg(DEBUG_CMD, "ISDN_CMD_HANGUP");
345  if (ch >= cs->channels) {
346  dev_err(cs->dev,
347  "ISDN_CMD_HANGUP: invalid channel (%d)\n", ch);
348  return -EINVAL;
349  }
350  bcs = cs->bcs + ch;
351  if (!gigaset_add_event(cs, &bcs->at_state,
352  EV_HUP, NULL, 0, NULL))
353  return -ENOMEM;
354  gigaset_schedule_event(cs);
355 
356  break;
357  case ISDN_CMD_CLREAZ: /* Do not signal incoming signals */
358  dev_info(cs->dev, "ignoring ISDN_CMD_CLREAZ\n");
359  break;
360  case ISDN_CMD_SETEAZ: /* Signal incoming calls for given MSN */
361  dev_info(cs->dev, "ignoring ISDN_CMD_SETEAZ (%s)\n",
362  cntrl->parm.num);
363  break;
364  case ISDN_CMD_SETL2: /* Set L2 to given protocol */
365  if (ch >= cs->channels) {
366  dev_err(cs->dev,
367  "ISDN_CMD_SETL2: invalid channel (%d)\n", ch);
368  return -EINVAL;
369  }
370  bcs = cs->bcs + ch;
371  if (bcs->chstate & CHS_D_UP) {
372  dev_err(cs->dev,
373  "ISDN_CMD_SETL2: channel active (%d)\n", ch);
374  return -EINVAL;
375  }
376  switch (cntrl->arg >> 8) {
377  case ISDN_PROTO_L2_HDLC:
378  gig_dbg(DEBUG_CMD, "ISDN_CMD_SETL2: setting L2_HDLC");
379  bcs->proto2 = L2_HDLC;
380  break;
381  case ISDN_PROTO_L2_TRANS:
382  gig_dbg(DEBUG_CMD, "ISDN_CMD_SETL2: setting L2_VOICE");
383  bcs->proto2 = L2_VOICE;
384  break;
385  default:
386  dev_err(cs->dev,
387  "ISDN_CMD_SETL2: unsupported protocol (%lu)\n",
388  cntrl->arg >> 8);
389  return -EINVAL;
390  }
391  break;
392  case ISDN_CMD_SETL3: /* Set L3 to given protocol */
393  gig_dbg(DEBUG_CMD, "ISDN_CMD_SETL3");
394  if (ch >= cs->channels) {
395  dev_err(cs->dev,
396  "ISDN_CMD_SETL3: invalid channel (%d)\n", ch);
397  return -EINVAL;
398  }
399 
400  if (cntrl->arg >> 8 != ISDN_PROTO_L3_TRANS) {
401  dev_err(cs->dev,
402  "ISDN_CMD_SETL3: unsupported protocol (%lu)\n",
403  cntrl->arg >> 8);
404  return -EINVAL;
405  }
406 
407  break;
408 
409  default:
410  gig_dbg(DEBUG_CMD, "unknown command %d from LL",
411  cntrl->command);
412  return -EINVAL;
413  }
414 
415  return retval;
416 
417 oom:
418  dev_err(bcs->cs->dev, "out of memory\n");
419  for (i = 0; i < AT_NUM; ++i)
420  kfree(commands[i]);
421  kfree(commands);
423  return -ENOMEM;
424 }
425 
426 static void gigaset_i4l_cmd(struct cardstate *cs, int cmd)
427 {
428  isdn_if *iif = cs->iif;
430 
431  command.driver = cs->myid;
432  command.command = cmd;
433  command.arg = 0;
434  iif->statcallb(&command);
435 }
436 
437 static void gigaset_i4l_channel_cmd(struct bc_state *bcs, int cmd)
438 {
439  isdn_if *iif = bcs->cs->iif;
441 
442  command.driver = bcs->cs->myid;
443  command.command = cmd;
444  command.arg = bcs->channel;
445  iif->statcallb(&command);
446 }
447 
458 {
459  struct cardstate *cs = at_state->cs;
460  struct bc_state *bcs = at_state->bcs;
461  isdn_if *iif = cs->iif;
463  int retval;
464 
465  /* fill ICALL structure */
466  response.parm.setup.si1 = 0; /* default: unknown */
467  response.parm.setup.si2 = 0;
468  response.parm.setup.screen = 0;
469  response.parm.setup.plan = 0;
470  if (!at_state->str_var[STR_ZBC]) {
471  /* no BC (internal call): assume speech, A-law */
472  response.parm.setup.si1 = 1;
473  } else if (!strcmp(at_state->str_var[STR_ZBC], "8890")) {
474  /* unrestricted digital information */
475  response.parm.setup.si1 = 7;
476  } else if (!strcmp(at_state->str_var[STR_ZBC], "8090A3")) {
477  /* speech, A-law */
478  response.parm.setup.si1 = 1;
479  } else if (!strcmp(at_state->str_var[STR_ZBC], "9090A3")) {
480  /* 3,1 kHz audio, A-law */
481  response.parm.setup.si1 = 1;
482  response.parm.setup.si2 = 2;
483  } else {
484  dev_warn(cs->dev, "RING ignored - unsupported BC %s\n",
485  at_state->str_var[STR_ZBC]);
486  return ICALL_IGNORE;
487  }
488  if (at_state->str_var[STR_NMBR]) {
489  strlcpy(response.parm.setup.phone, at_state->str_var[STR_NMBR],
490  sizeof response.parm.setup.phone);
491  } else
492  response.parm.setup.phone[0] = 0;
493  if (at_state->str_var[STR_ZCPN]) {
494  strlcpy(response.parm.setup.eazmsn, at_state->str_var[STR_ZCPN],
495  sizeof response.parm.setup.eazmsn);
496  } else
497  response.parm.setup.eazmsn[0] = 0;
498 
499  if (!bcs) {
500  dev_notice(cs->dev, "no channel for incoming call\n");
501  response.command = ISDN_STAT_ICALLW;
502  response.arg = 0;
503  } else {
504  gig_dbg(DEBUG_CMD, "Sending ICALL");
505  response.command = ISDN_STAT_ICALL;
506  response.arg = bcs->channel;
507  }
508  response.driver = cs->myid;
509  retval = iif->statcallb(&response);
510  gig_dbg(DEBUG_CMD, "Response: %d", retval);
511  switch (retval) {
512  case 0: /* no takers */
513  return ICALL_IGNORE;
514  case 1: /* alerting */
515  bcs->chstate |= CHS_NOTIFY_LL;
516  return ICALL_ACCEPT;
517  case 2: /* reject */
518  return ICALL_REJECT;
519  case 3: /* incomplete */
520  dev_warn(cs->dev,
521  "LL requested unsupported feature: Incomplete Number\n");
522  return ICALL_IGNORE;
523  case 4: /* proceeding */
524  /* Gigaset will send ALERTING anyway.
525  * There doesn't seem to be a way to avoid this.
526  */
527  return ICALL_ACCEPT;
528  case 5: /* deflect */
529  dev_warn(cs->dev,
530  "LL requested unsupported feature: Call Deflection\n");
531  return ICALL_IGNORE;
532  default:
533  dev_err(cs->dev, "LL error %d on ICALL\n", retval);
534  return ICALL_IGNORE;
535  }
536 }
537 
545 void gigaset_isdn_connD(struct bc_state *bcs)
546 {
547  gig_dbg(DEBUG_CMD, "sending DCONN");
548  gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN);
549 }
550 
558 void gigaset_isdn_hupD(struct bc_state *bcs)
559 {
560  gig_dbg(DEBUG_CMD, "sending DHUP");
561  gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DHUP);
562 }
563 
571 void gigaset_isdn_connB(struct bc_state *bcs)
572 {
573  gig_dbg(DEBUG_CMD, "sending BCONN");
574  gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BCONN);
575 }
576 
584 void gigaset_isdn_hupB(struct bc_state *bcs)
585 {
586  gig_dbg(DEBUG_CMD, "sending BHUP");
587  gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BHUP);
588 }
589 
598 {
599  gig_dbg(DEBUG_CMD, "sending RUN");
600  gigaset_i4l_cmd(cs, ISDN_STAT_RUN);
601 }
602 
610 void gigaset_isdn_stop(struct cardstate *cs)
611 {
612  gig_dbg(DEBUG_CMD, "sending STOP");
613  gigaset_i4l_cmd(cs, ISDN_STAT_STOP);
614 }
615 
623 int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
624 {
625  isdn_if *iif;
626 
627  iif = kmalloc(sizeof *iif, GFP_KERNEL);
628  if (!iif) {
629  pr_err("out of memory\n");
630  return -ENOMEM;
631  }
632 
633  if (snprintf(iif->id, sizeof iif->id, "%s_%u", isdnid, cs->minor_index)
634  >= sizeof iif->id) {
635  pr_err("ID too long: %s\n", isdnid);
636  kfree(iif);
637  return -EINVAL;
638  }
639 
640  iif->owner = THIS_MODULE;
641  iif->channels = cs->channels;
642  iif->maxbufsize = MAX_BUF_SIZE;
648  iif->hl_hdrlen = HW_HDR_LEN; /* Area for storing ack */
649  iif->command = command_from_LL;
650  iif->writebuf_skb = writebuf_from_LL;
651  iif->writecmd = NULL; /* Don't support isdnctrl */
652  iif->readstat = NULL; /* Don't support isdnctrl */
653  iif->rcvcallb_skb = NULL; /* Will be set by LL */
654  iif->statcallb = NULL; /* Will be set by LL */
655 
656  if (!register_isdn(iif)) {
657  pr_err("register_isdn failed\n");
658  kfree(iif);
659  return -EINVAL;
660  }
661 
662  cs->iif = iif;
663  cs->myid = iif->channels; /* Set my device id */
664  cs->hw_hdr_len = HW_HDR_LEN;
665  return 0;
666 }
667 
673 {
674  gig_dbg(DEBUG_CMD, "sending UNLOAD");
675  gigaset_i4l_cmd(cs, ISDN_STAT_UNLOAD);
676  kfree(cs->iif);
677  cs->iif = NULL;
678 }
679 
684 {
685  pr_info("ISDN4Linux interface\n");
686  /* nothing to do */
687 }
688 
693 {
694  /* nothing to do */
695 }