gigaset: linearize skb
[safe/jmp/linux-2.6] / drivers / isdn / gigaset / i4l.c
1 /*
2  * Stuff used by all variants of the driver
3  *
4  * Copyright (c) 2001 by Stefan Eilers,
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  * =====================================================================
14  */
15
16 #include "gigaset.h"
17
18 /* == Handling of I4L IO =====================================================*/
19
20 /* writebuf_from_LL
21  * called by LL to transmit data on an open channel
22  * inserts the buffer data into the send queue and starts the transmission
23  * Note that this operation must not sleep!
24  * When the buffer is processed completely, gigaset_skb_sent() should be called.
25  * parameters:
26  *      driverID        driver ID as assigned by LL
27  *      channel         channel number
28  *      ack             if != 0 LL wants to be notified on completion via
29  *                      statcallb(ISDN_STAT_BSENT)
30  *      skb             skb containing data to send
31  * return value:
32  *      number of accepted bytes
33  *      0 if temporarily unable to accept data (out of buffer space)
34  *      <0 on error (eg. -EINVAL)
35  */
36 static int writebuf_from_LL(int driverID, int channel, int ack,
37                             struct sk_buff *skb)
38 {
39         struct cardstate *cs;
40         struct bc_state *bcs;
41         unsigned len;
42         unsigned skblen;
43
44         if (!(cs = gigaset_get_cs_by_id(driverID))) {
45                 pr_err("%s: invalid driver ID (%d)\n", __func__, driverID);
46                 return -ENODEV;
47         }
48         if (channel < 0 || channel >= cs->channels) {
49                 dev_err(cs->dev, "%s: invalid channel ID (%d)\n",
50                         __func__, channel);
51                 return -ENODEV;
52         }
53         bcs = &cs->bcs[channel];
54
55         /* can only handle linear sk_buffs */
56         if (skb_linearize(skb) < 0) {
57                 dev_err(cs->dev, "%s: skb_linearize failed\n", __func__);
58                 return -ENOMEM;
59         }
60         len = skb->len;
61
62         gig_dbg(DEBUG_LLDATA,
63                 "Receiving data from LL (id: %d, ch: %d, ack: %d, sz: %d)",
64                 driverID, channel, ack, len);
65
66         if (!len) {
67                 if (ack)
68                         dev_notice(cs->dev, "%s: not ACKing empty packet\n",
69                                    __func__);
70                 return 0;
71         }
72         if (len > MAX_BUF_SIZE) {
73                 dev_err(cs->dev, "%s: packet too large (%d bytes)\n",
74                         __func__, len);
75                 return -EINVAL;
76         }
77
78         skblen = ack ? len : 0;
79         skb->head[0] = skblen & 0xff;
80         skb->head[1] = skblen >> 8;
81         gig_dbg(DEBUG_MCMD, "skb: len=%u, skblen=%u: %02x %02x",
82                 len, skblen, (unsigned) skb->head[0], (unsigned) skb->head[1]);
83
84         /* pass to device-specific module */
85         return cs->ops->send_skb(bcs, skb);
86 }
87
88 void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb)
89 {
90         unsigned len;
91         isdn_ctrl response;
92
93         ++bcs->trans_up;
94
95         if (skb->len)
96                 dev_warn(bcs->cs->dev, "%s: skb->len==%d\n",
97                          __func__, skb->len);
98
99         len = (unsigned char) skb->head[0] |
100               (unsigned) (unsigned char) skb->head[1] << 8;
101         if (len) {
102                 gig_dbg(DEBUG_MCMD, "ACKing to LL (id: %d, ch: %d, sz: %u)",
103                         bcs->cs->myid, bcs->channel, len);
104
105                 response.driver = bcs->cs->myid;
106                 response.command = ISDN_STAT_BSENT;
107                 response.arg = bcs->channel;
108                 response.parm.length = len;
109                 bcs->cs->iif.statcallb(&response);
110         }
111 }
112 EXPORT_SYMBOL_GPL(gigaset_skb_sent);
113
114 /* This function will be called by LL to send commands
115  * NOTE: LL ignores the returned value, for commands other than ISDN_CMD_IOCTL,
116  * so don't put too much effort into it.
117  */
118 static int command_from_LL(isdn_ctrl *cntrl)
119 {
120         struct cardstate *cs = gigaset_get_cs_by_id(cntrl->driver);
121         struct bc_state *bcs;
122         int retval = 0;
123         struct setup_parm *sp;
124
125         gigaset_debugdrivers();
126
127         if (!cs) {
128                 pr_err("%s: invalid driver ID (%d)\n", __func__, cntrl->driver);
129                 return -ENODEV;
130         }
131
132         switch (cntrl->command) {
133         case ISDN_CMD_IOCTL:
134                 gig_dbg(DEBUG_ANY, "ISDN_CMD_IOCTL (driver: %d, arg: %ld)",
135                         cntrl->driver, cntrl->arg);
136
137                 dev_warn(cs->dev, "ISDN_CMD_IOCTL not supported\n");
138                 return -EINVAL;
139
140         case ISDN_CMD_DIAL:
141                 gig_dbg(DEBUG_ANY,
142                         "ISDN_CMD_DIAL (driver: %d, ch: %ld, "
143                         "phone: %s, ownmsn: %s, si1: %d, si2: %d)",
144                         cntrl->driver, cntrl->arg,
145                         cntrl->parm.setup.phone, cntrl->parm.setup.eazmsn,
146                         cntrl->parm.setup.si1, cntrl->parm.setup.si2);
147
148                 if (cntrl->arg >= cs->channels) {
149                         dev_err(cs->dev,
150                                 "ISDN_CMD_DIAL: invalid channel (%d)\n",
151                                 (int) cntrl->arg);
152                         return -EINVAL;
153                 }
154
155                 bcs = cs->bcs + cntrl->arg;
156
157                 if (!gigaset_get_channel(bcs)) {
158                         dev_err(cs->dev, "ISDN_CMD_DIAL: channel not free\n");
159                         return -EBUSY;
160                 }
161
162                 sp = kmalloc(sizeof *sp, GFP_ATOMIC);
163                 if (!sp) {
164                         gigaset_free_channel(bcs);
165                         dev_err(cs->dev, "ISDN_CMD_DIAL: out of memory\n");
166                         return -ENOMEM;
167                 }
168                 *sp = cntrl->parm.setup;
169
170                 if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, sp,
171                                        bcs->at_state.seq_index, NULL)) {
172                         //FIXME what should we do?
173                         kfree(sp);
174                         gigaset_free_channel(bcs);
175                         return -ENOMEM;
176                 }
177
178                 gig_dbg(DEBUG_CMD, "scheduling DIAL");
179                 gigaset_schedule_event(cs);
180                 break;
181         case ISDN_CMD_ACCEPTD: //FIXME
182                 gig_dbg(DEBUG_ANY, "ISDN_CMD_ACCEPTD");
183
184                 if (cntrl->arg >= cs->channels) {
185                         dev_err(cs->dev,
186                                 "ISDN_CMD_ACCEPTD: invalid channel (%d)\n",
187                                 (int) cntrl->arg);
188                         return -EINVAL;
189                 }
190
191                 if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg].at_state,
192                                        EV_ACCEPT, NULL, 0, NULL)) {
193                         //FIXME what should we do?
194                         return -ENOMEM;
195                 }
196
197                 gig_dbg(DEBUG_CMD, "scheduling ACCEPT");
198                 gigaset_schedule_event(cs);
199
200                 break;
201         case ISDN_CMD_ACCEPTB:
202                 gig_dbg(DEBUG_ANY, "ISDN_CMD_ACCEPTB");
203                 break;
204         case ISDN_CMD_HANGUP:
205                 gig_dbg(DEBUG_ANY, "ISDN_CMD_HANGUP (ch: %d)",
206                         (int) cntrl->arg);
207
208                 if (cntrl->arg >= cs->channels) {
209                         dev_err(cs->dev,
210                                 "ISDN_CMD_HANGUP: invalid channel (%d)\n",
211                                 (int) cntrl->arg);
212                         return -EINVAL;
213                 }
214
215                 if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg].at_state,
216                                        EV_HUP, NULL, 0, NULL)) {
217                         //FIXME what should we do?
218                         return -ENOMEM;
219                 }
220
221                 gig_dbg(DEBUG_CMD, "scheduling HUP");
222                 gigaset_schedule_event(cs);
223
224                 break;
225         case ISDN_CMD_CLREAZ: /* Do not signal incoming signals */ //FIXME
226                 gig_dbg(DEBUG_ANY, "ISDN_CMD_CLREAZ");
227                 break;
228         case ISDN_CMD_SETEAZ: /* Signal incoming calls for given MSN */ //FIXME
229                 gig_dbg(DEBUG_ANY,
230                         "ISDN_CMD_SETEAZ (id: %d, ch: %ld, number: %s)",
231                         cntrl->driver, cntrl->arg, cntrl->parm.num);
232                 break;
233         case ISDN_CMD_SETL2: /* Set L2 to given protocol */
234                 gig_dbg(DEBUG_ANY, "ISDN_CMD_SETL2 (ch: %ld, proto: %lx)",
235                         cntrl->arg & 0xff, (cntrl->arg >> 8));
236
237                 if ((cntrl->arg & 0xff) >= cs->channels) {
238                         dev_err(cs->dev,
239                                 "ISDN_CMD_SETL2: invalid channel (%d)\n",
240                                 (int) cntrl->arg & 0xff);
241                         return -EINVAL;
242                 }
243
244                 if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg & 0xff].at_state,
245                                        EV_PROTO_L2, NULL, cntrl->arg >> 8,
246                                        NULL)) {
247                         //FIXME what should we do?
248                         return -ENOMEM;
249                 }
250
251                 gig_dbg(DEBUG_CMD, "scheduling PROTO_L2");
252                 gigaset_schedule_event(cs);
253                 break;
254         case ISDN_CMD_SETL3: /* Set L3 to given protocol */
255                 gig_dbg(DEBUG_ANY, "ISDN_CMD_SETL3 (ch: %ld, proto: %lx)",
256                         cntrl->arg & 0xff, (cntrl->arg >> 8));
257
258                 if ((cntrl->arg & 0xff) >= cs->channels) {
259                         dev_err(cs->dev,
260                                 "ISDN_CMD_SETL3: invalid channel (%d)\n",
261                                 (int) cntrl->arg & 0xff);
262                         return -EINVAL;
263                 }
264
265                 if (cntrl->arg >> 8 != ISDN_PROTO_L3_TRANS) {
266                         dev_err(cs->dev,
267                                 "ISDN_CMD_SETL3: invalid protocol %lu\n",
268                                 cntrl->arg >> 8);
269                         return -EINVAL;
270                 }
271
272                 break;
273         case ISDN_CMD_PROCEED:
274                 gig_dbg(DEBUG_ANY, "ISDN_CMD_PROCEED"); //FIXME
275                 break;
276         case ISDN_CMD_ALERT:
277                 gig_dbg(DEBUG_ANY, "ISDN_CMD_ALERT"); //FIXME
278                 if (cntrl->arg >= cs->channels) {
279                         dev_err(cs->dev,
280                                 "ISDN_CMD_ALERT: invalid channel (%d)\n",
281                                 (int) cntrl->arg);
282                         return -EINVAL;
283                 }
284                 //bcs = cs->bcs + cntrl->arg;
285                 //bcs->proto2 = -1;
286                 // FIXME
287                 break;
288         case ISDN_CMD_REDIR:
289                 gig_dbg(DEBUG_ANY, "ISDN_CMD_REDIR"); //FIXME
290                 break;
291         case ISDN_CMD_PROT_IO:
292                 gig_dbg(DEBUG_ANY, "ISDN_CMD_PROT_IO");
293                 break;
294         case ISDN_CMD_FAXCMD:
295                 gig_dbg(DEBUG_ANY, "ISDN_CMD_FAXCMD");
296                 break;
297         case ISDN_CMD_GETL2:
298                 gig_dbg(DEBUG_ANY, "ISDN_CMD_GETL2");
299                 break;
300         case ISDN_CMD_GETL3:
301                 gig_dbg(DEBUG_ANY, "ISDN_CMD_GETL3");
302                 break;
303         case ISDN_CMD_GETEAZ:
304                 gig_dbg(DEBUG_ANY, "ISDN_CMD_GETEAZ");
305                 break;
306         case ISDN_CMD_SETSIL:
307                 gig_dbg(DEBUG_ANY, "ISDN_CMD_SETSIL");
308                 break;
309         case ISDN_CMD_GETSIL:
310                 gig_dbg(DEBUG_ANY, "ISDN_CMD_GETSIL");
311                 break;
312         default:
313                 dev_err(cs->dev, "unknown command %d from LL\n",
314                         cntrl->command);
315                 return -EINVAL;
316         }
317
318         return retval;
319 }
320
321 void gigaset_i4l_cmd(struct cardstate *cs, int cmd)
322 {
323         isdn_ctrl command;
324
325         command.driver = cs->myid;
326         command.command = cmd;
327         command.arg = 0;
328         cs->iif.statcallb(&command);
329 }
330
331 void gigaset_i4l_channel_cmd(struct bc_state *bcs, int cmd)
332 {
333         isdn_ctrl command;
334
335         command.driver = bcs->cs->myid;
336         command.command = cmd;
337         command.arg = bcs->channel;
338         bcs->cs->iif.statcallb(&command);
339 }
340
341 int gigaset_isdn_setup_dial(struct at_state_t *at_state, void *data)
342 {
343         struct bc_state *bcs = at_state->bcs;
344         unsigned proto;
345         const char *bc;
346         size_t length[AT_NUM];
347         size_t l;
348         int i;
349         struct setup_parm *sp = data;
350
351         switch (bcs->proto2) {
352         case ISDN_PROTO_L2_HDLC:
353                 proto = 1; /* 0: Bitsynchron, 1: HDLC, 2: voice */
354                 break;
355         case ISDN_PROTO_L2_TRANS:
356                 proto = 2; /* 0: Bitsynchron, 1: HDLC, 2: voice */
357                 break;
358         default:
359                 dev_err(bcs->cs->dev, "%s: invalid L2 protocol: %u\n",
360                         __func__, bcs->proto2);
361                 return -EINVAL;
362         }
363
364         switch (sp->si1) {
365         case 1:         /* audio */
366                 bc = "9090A3";  /* 3.1 kHz audio, A-law */
367                 break;
368         case 7:         /* data */
369         default:        /* hope the app knows what it is doing */
370                 bc = "8890";    /* unrestricted digital information */
371         }
372         //FIXME add missing si1 values from 1TR6, inspect si2, set HLC/LLC
373
374         length[AT_DIAL ] = 1 + strlen(sp->phone) + 1 + 1;
375         l = strlen(sp->eazmsn);
376         length[AT_MSN  ] = l ? 6 + l + 1 + 1 : 0;
377         length[AT_BC   ] = 5 + strlen(bc) + 1 + 1;
378         length[AT_PROTO] = 6 + 1 + 1 + 1; /* proto: 1 character */
379         length[AT_ISO  ] = 6 + 1 + 1 + 1; /* channel: 1 character */
380         length[AT_TYPE ] = 6 + 1 + 1 + 1; /* call type: 1 character */
381         length[AT_HLC  ] = 0;
382
383         for (i = 0; i < AT_NUM; ++i) {
384                 kfree(bcs->commands[i]);
385                 bcs->commands[i] = NULL;
386                 if (length[i] &&
387                     !(bcs->commands[i] = kmalloc(length[i], GFP_ATOMIC))) {
388                         dev_err(bcs->cs->dev, "out of memory\n");
389                         return -ENOMEM;
390                 }
391         }
392
393         /* type = 1: extern, 0: intern, 2: recall, 3: door, 4: centrex */
394         if (sp->phone[0] == '*' && sp->phone[1] == '*') {
395                 /* internal call: translate ** prefix to CTP value */
396                 snprintf(bcs->commands[AT_DIAL], length[AT_DIAL],
397                          "D%s\r", sp->phone+2);
398                 strncpy(bcs->commands[AT_TYPE], "^SCTP=0\r", length[AT_TYPE]);
399         } else {
400                 snprintf(bcs->commands[AT_DIAL], length[AT_DIAL],
401                          "D%s\r", sp->phone);
402                 strncpy(bcs->commands[AT_TYPE], "^SCTP=1\r", length[AT_TYPE]);
403         }
404
405         if (bcs->commands[AT_MSN])
406                 snprintf(bcs->commands[AT_MSN], length[AT_MSN],
407                          "^SMSN=%s\r", sp->eazmsn);
408         snprintf(bcs->commands[AT_BC   ], length[AT_BC   ],
409                  "^SBC=%s\r", bc);
410         snprintf(bcs->commands[AT_PROTO], length[AT_PROTO],
411                  "^SBPR=%u\r", proto);
412         snprintf(bcs->commands[AT_ISO  ], length[AT_ISO  ],
413                  "^SISO=%u\r", (unsigned)bcs->channel + 1);
414
415         return 0;
416 }
417
418 int gigaset_isdn_setup_accept(struct at_state_t *at_state)
419 {
420         unsigned proto;
421         size_t length[AT_NUM];
422         int i;
423         struct bc_state *bcs = at_state->bcs;
424
425         switch (bcs->proto2) {
426         case ISDN_PROTO_L2_HDLC:
427                 proto = 1; /* 0: Bitsynchron, 1: HDLC, 2: voice */
428                 break;
429         case ISDN_PROTO_L2_TRANS:
430                 proto = 2; /* 0: Bitsynchron, 1: HDLC, 2: voice */
431                 break;
432         default:
433                 dev_err(at_state->cs->dev, "%s: invalid protocol: %u\n",
434                         __func__, bcs->proto2);
435                 return -EINVAL;
436         }
437
438         length[AT_DIAL ] = 0;
439         length[AT_MSN  ] = 0;
440         length[AT_BC   ] = 0;
441         length[AT_PROTO] = 6 + 1 + 1 + 1; /* proto: 1 character */
442         length[AT_ISO  ] = 6 + 1 + 1 + 1; /* channel: 1 character */
443         length[AT_TYPE ] = 0;
444         length[AT_HLC  ] = 0;
445
446         for (i = 0; i < AT_NUM; ++i) {
447                 kfree(bcs->commands[i]);
448                 bcs->commands[i] = NULL;
449                 if (length[i] &&
450                     !(bcs->commands[i] = kmalloc(length[i], GFP_ATOMIC))) {
451                         dev_err(at_state->cs->dev, "out of memory\n");
452                         return -ENOMEM;
453                 }
454         }
455
456         snprintf(bcs->commands[AT_PROTO], length[AT_PROTO],
457                  "^SBPR=%u\r", proto);
458         snprintf(bcs->commands[AT_ISO  ], length[AT_ISO  ],
459                  "^SISO=%u\r", (unsigned) bcs->channel + 1);
460
461         return 0;
462 }
463
464 int gigaset_isdn_icall(struct at_state_t *at_state)
465 {
466         struct cardstate *cs = at_state->cs;
467         struct bc_state *bcs = at_state->bcs;
468         isdn_ctrl response;
469         int retval;
470
471         /* fill ICALL structure */
472         response.parm.setup.si1 = 0;    /* default: unknown */
473         response.parm.setup.si2 = 0;
474         response.parm.setup.screen = 0; //FIXME how to set these?
475         response.parm.setup.plan = 0;
476         if (!at_state->str_var[STR_ZBC]) {
477                 /* no BC (internal call): assume speech, A-law */
478                 response.parm.setup.si1 = 1;
479         } else if (!strcmp(at_state->str_var[STR_ZBC], "8890")) {
480                 /* unrestricted digital information */
481                 response.parm.setup.si1 = 7;
482         } else if (!strcmp(at_state->str_var[STR_ZBC], "8090A3")) {
483                 /* speech, A-law */
484                 response.parm.setup.si1 = 1;
485         } else if (!strcmp(at_state->str_var[STR_ZBC], "9090A3")) {
486                 /* 3,1 kHz audio, A-law */
487                 response.parm.setup.si1 = 1;
488                 response.parm.setup.si2 = 2;
489         } else {
490                 dev_warn(cs->dev, "RING ignored - unsupported BC %s\n",
491                      at_state->str_var[STR_ZBC]);
492                 return ICALL_IGNORE;
493         }
494         if (at_state->str_var[STR_NMBR]) {
495                 strncpy(response.parm.setup.phone, at_state->str_var[STR_NMBR],
496                         sizeof response.parm.setup.phone - 1);
497                 response.parm.setup.phone[sizeof response.parm.setup.phone - 1] = 0;
498         } else
499                 response.parm.setup.phone[0] = 0;
500         if (at_state->str_var[STR_ZCPN]) {
501                 strncpy(response.parm.setup.eazmsn, at_state->str_var[STR_ZCPN],
502                         sizeof response.parm.setup.eazmsn - 1);
503                 response.parm.setup.eazmsn[sizeof response.parm.setup.eazmsn - 1] = 0;
504         } else
505                 response.parm.setup.eazmsn[0] = 0;
506
507         if (!bcs) {
508                 dev_notice(cs->dev, "no channel for incoming call\n");
509                 response.command = ISDN_STAT_ICALLW;
510                 response.arg = 0; //FIXME
511         } else {
512                 gig_dbg(DEBUG_CMD, "Sending ICALL");
513                 response.command = ISDN_STAT_ICALL;
514                 response.arg = bcs->channel; //FIXME
515         }
516         response.driver = cs->myid;
517         retval = cs->iif.statcallb(&response);
518         gig_dbg(DEBUG_CMD, "Response: %d", retval);
519         switch (retval) {
520         case 0: /* no takers */
521                 return ICALL_IGNORE;
522         case 1: /* alerting */
523                 bcs->chstate |= CHS_NOTIFY_LL;
524                 return ICALL_ACCEPT;
525         case 2: /* reject */
526                 return ICALL_REJECT;
527         case 3: /* incomplete */
528                 dev_warn(cs->dev,
529                        "LL requested unsupported feature: Incomplete Number\n");
530                 return ICALL_IGNORE;
531         case 4: /* proceeding */
532                 /* Gigaset will send ALERTING anyway.
533                  * There doesn't seem to be a way to avoid this.
534                  */
535                 return ICALL_ACCEPT;
536         case 5: /* deflect */
537                 dev_warn(cs->dev,
538                          "LL requested unsupported feature: Call Deflection\n");
539                 return ICALL_IGNORE;
540         default:
541                 dev_err(cs->dev, "LL error %d on ICALL\n", retval);
542                 return ICALL_IGNORE;
543         }
544 }
545
546 /* Set Callback function pointer */
547 int gigaset_register_to_LL(struct cardstate *cs, const char *isdnid)
548 {
549         isdn_if *iif = &cs->iif;
550
551         gig_dbg(DEBUG_ANY, "Register driver capabilities to LL");
552
553         if (snprintf(iif->id, sizeof iif->id, "%s_%u", isdnid, cs->minor_index)
554             >= sizeof iif->id) {
555                 pr_err("ID too long: %s\n", isdnid);
556                 return 0;
557         }
558
559         iif->owner = THIS_MODULE;
560         iif->channels = cs->channels;
561         iif->maxbufsize = MAX_BUF_SIZE;
562         iif->features = ISDN_FEATURE_L2_TRANS |
563                 ISDN_FEATURE_L2_HDLC |
564 #ifdef GIG_X75
565                 ISDN_FEATURE_L2_X75I |
566 #endif
567                 ISDN_FEATURE_L3_TRANS |
568                 ISDN_FEATURE_P_EURO;
569         iif->hl_hdrlen = HW_HDR_LEN;            /* Area for storing ack */
570         iif->command = command_from_LL;
571         iif->writebuf_skb = writebuf_from_LL;
572         iif->writecmd = NULL;                   /* Don't support isdnctrl */
573         iif->readstat = NULL;                   /* Don't support isdnctrl */
574         iif->rcvcallb_skb = NULL;               /* Will be set by LL */
575         iif->statcallb = NULL;                  /* Will be set by LL */
576
577         if (!register_isdn(iif)) {
578                 pr_err("register_isdn failed\n");
579                 return 0;
580         }
581
582         cs->myid = iif->channels;               /* Set my device id */
583         return 1;
584 }