diff options
author | Tilman Schmidt <tilman@imap.cc> | 2009-10-06 08:19:07 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-10-07 01:43:50 -0400 |
commit | 088ec0cc96e2befd5f3c035123f95c17bdf26e64 (patch) | |
tree | 4d0fdcc26e6bfd9ee320cf716f56a695e38be8ae /drivers/isdn | |
parent | 7ecc59c1b7fd5749667fc31f8683099cbef38977 (diff) |
gigaset: prepare for CAPI implementation
Reorganize the code of the Gigaset driver, moving all isdn4linux
dependencies to the source file i4l.c so that it can be replaced
by a file capi.c interfacing to Kernel CAPI instead.
Impact: refactoring, no functional change
Signed-off-by: Tilman Schmidt <tilman@imap.cc>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/isdn')
-rw-r--r-- | drivers/isdn/gigaset/asyncdata.c | 124 | ||||
-rw-r--r-- | drivers/isdn/gigaset/bas-gigaset.c | 4 | ||||
-rw-r--r-- | drivers/isdn/gigaset/common.c | 50 | ||||
-rw-r--r-- | drivers/isdn/gigaset/ev-layer.c | 64 | ||||
-rw-r--r-- | drivers/isdn/gigaset/gigaset.h | 90 | ||||
-rw-r--r-- | drivers/isdn/gigaset/i4l.c | 506 | ||||
-rw-r--r-- | drivers/isdn/gigaset/isocdata.c | 79 |
7 files changed, 492 insertions, 425 deletions
diff --git a/drivers/isdn/gigaset/asyncdata.c b/drivers/isdn/gigaset/asyncdata.c index 44a58e6f8f65..a25216bf475e 100644 --- a/drivers/isdn/gigaset/asyncdata.c +++ b/drivers/isdn/gigaset/asyncdata.c | |||
@@ -119,10 +119,7 @@ static inline int hdlc_loop(unsigned char c, unsigned char *src, int numbytes, | |||
119 | int inputstate = bcs->inputstate; | 119 | int inputstate = bcs->inputstate; |
120 | __u16 fcs = bcs->fcs; | 120 | __u16 fcs = bcs->fcs; |
121 | struct sk_buff *skb = bcs->skb; | 121 | struct sk_buff *skb = bcs->skb; |
122 | unsigned char error; | ||
123 | struct sk_buff *compskb; | ||
124 | int startbytes = numbytes; | 122 | int startbytes = numbytes; |
125 | int l; | ||
126 | 123 | ||
127 | if (unlikely(inputstate & INS_byte_stuff)) { | 124 | if (unlikely(inputstate & INS_byte_stuff)) { |
128 | inputstate &= ~INS_byte_stuff; | 125 | inputstate &= ~INS_byte_stuff; |
@@ -158,8 +155,8 @@ byte_stuff: | |||
158 | #endif | 155 | #endif |
159 | 156 | ||
160 | /* end of frame */ | 157 | /* end of frame */ |
161 | error = 1; | 158 | gigaset_isdn_rcv_err(bcs); |
162 | gigaset_rcv_error(NULL, cs, bcs); | 159 | dev_kfree_skb(skb); |
163 | } else if (!(inputstate & INS_have_data)) { /* 7E 7E */ | 160 | } else if (!(inputstate & INS_have_data)) { /* 7E 7E */ |
164 | #ifdef CONFIG_GIGASET_DEBUG | 161 | #ifdef CONFIG_GIGASET_DEBUG |
165 | ++bcs->emptycount; | 162 | ++bcs->emptycount; |
@@ -170,54 +167,39 @@ byte_stuff: | |||
170 | "7e----------------------------"); | 167 | "7e----------------------------"); |
171 | 168 | ||
172 | /* end of frame */ | 169 | /* end of frame */ |
173 | error = 0; | ||
174 | |||
175 | if (unlikely(fcs != PPP_GOODFCS)) { | 170 | if (unlikely(fcs != PPP_GOODFCS)) { |
176 | dev_err(cs->dev, | 171 | dev_err(cs->dev, |
177 | "Checksum failed, %u bytes corrupted!\n", | 172 | "Checksum failed, %u bytes corrupted!\n", |
178 | skb->len); | 173 | skb->len); |
179 | compskb = NULL; | 174 | gigaset_isdn_rcv_err(bcs); |
180 | gigaset_rcv_error(compskb, cs, bcs); | 175 | dev_kfree_skb(skb); |
181 | error = 1; | 176 | } else if (likely(skb->len > 2)) { |
177 | __skb_trim(skb, skb->len - 2); | ||
178 | gigaset_skb_rcvd(bcs, skb); | ||
182 | } else { | 179 | } else { |
183 | if (likely((l = skb->len) > 2)) { | 180 | if (skb->len) { |
184 | skb->tail -= 2; | 181 | dev_err(cs->dev, |
185 | skb->len -= 2; | 182 | "invalid packet size (%d)\n", skb->len); |
186 | } else { | 183 | gigaset_isdn_rcv_err(bcs); |
187 | dev_kfree_skb(skb); | ||
188 | skb = NULL; | ||
189 | inputstate |= INS_skip_frame; | ||
190 | if (l == 1) { | ||
191 | dev_err(cs->dev, | ||
192 | "invalid packet size (1)!\n"); | ||
193 | error = 1; | ||
194 | gigaset_rcv_error(NULL, | ||
195 | cs, bcs); | ||
196 | } | ||
197 | } | ||
198 | if (likely(!(error || | ||
199 | (inputstate & | ||
200 | INS_skip_frame)))) { | ||
201 | gigaset_rcv_skb(skb, cs, bcs); | ||
202 | } | 184 | } |
185 | dev_kfree_skb(skb); | ||
203 | } | 186 | } |
204 | } | 187 | } |
205 | 188 | ||
206 | if (unlikely(error)) | ||
207 | if (skb) | ||
208 | dev_kfree_skb(skb); | ||
209 | |||
210 | fcs = PPP_INITFCS; | 189 | fcs = PPP_INITFCS; |
211 | inputstate &= ~(INS_have_data | INS_skip_frame); | 190 | inputstate &= ~(INS_have_data | INS_skip_frame); |
212 | if (unlikely(bcs->ignore)) { | 191 | if (unlikely(bcs->ignore)) { |
213 | inputstate |= INS_skip_frame; | 192 | inputstate |= INS_skip_frame; |
214 | skb = NULL; | 193 | skb = NULL; |
215 | } else if (likely((skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)) { | ||
216 | skb_reserve(skb, HW_HDR_LEN); | ||
217 | } else { | 194 | } else { |
218 | dev_warn(cs->dev, | 195 | skb = dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len); |
219 | "could not allocate new skb\n"); | 196 | if (skb != NULL) { |
220 | inputstate |= INS_skip_frame; | 197 | skb_reserve(skb, cs->hw_hdr_len); |
198 | } else { | ||
199 | dev_warn(cs->dev, | ||
200 | "could not allocate new skb\n"); | ||
201 | inputstate |= INS_skip_frame; | ||
202 | } | ||
221 | } | 203 | } |
222 | 204 | ||
223 | break; | 205 | break; |
@@ -314,18 +296,21 @@ static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes, | |||
314 | /* pass data up */ | 296 | /* pass data up */ |
315 | if (likely(inputstate & INS_have_data)) { | 297 | if (likely(inputstate & INS_have_data)) { |
316 | if (likely(!(inputstate & INS_skip_frame))) { | 298 | if (likely(!(inputstate & INS_skip_frame))) { |
317 | gigaset_rcv_skb(skb, cs, bcs); | 299 | gigaset_skb_rcvd(bcs, skb); |
318 | } | 300 | } |
319 | inputstate &= ~(INS_have_data | INS_skip_frame); | 301 | inputstate &= ~(INS_have_data | INS_skip_frame); |
320 | if (unlikely(bcs->ignore)) { | 302 | if (unlikely(bcs->ignore)) { |
321 | inputstate |= INS_skip_frame; | 303 | inputstate |= INS_skip_frame; |
322 | skb = NULL; | 304 | skb = NULL; |
323 | } else if (likely((skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) | ||
324 | != NULL)) { | ||
325 | skb_reserve(skb, HW_HDR_LEN); | ||
326 | } else { | 305 | } else { |
327 | dev_warn(cs->dev, "could not allocate new skb\n"); | 306 | skb = dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len); |
328 | inputstate |= INS_skip_frame; | 307 | if (skb != NULL) { |
308 | skb_reserve(skb, cs->hw_hdr_len); | ||
309 | } else { | ||
310 | dev_warn(cs->dev, | ||
311 | "could not allocate new skb\n"); | ||
312 | inputstate |= INS_skip_frame; | ||
313 | } | ||
329 | } | 314 | } |
330 | } | 315 | } |
331 | 316 | ||
@@ -383,7 +368,7 @@ void gigaset_m10x_input(struct inbuf_t *inbuf) | |||
383 | /* FIXME use function pointers? */ | 368 | /* FIXME use function pointers? */ |
384 | if (inbuf->inputstate & INS_command) | 369 | if (inbuf->inputstate & INS_command) |
385 | procbytes = cmd_loop(c, src, numbytes, inbuf); | 370 | procbytes = cmd_loop(c, src, numbytes, inbuf); |
386 | else if (inbuf->bcs->proto2 == ISDN_PROTO_L2_HDLC) | 371 | else if (inbuf->bcs->proto2 == L2_HDLC) |
387 | procbytes = hdlc_loop(c, src, numbytes, inbuf); | 372 | procbytes = hdlc_loop(c, src, numbytes, inbuf); |
388 | else | 373 | else |
389 | procbytes = iraw_loop(c, src, numbytes, inbuf); | 374 | procbytes = iraw_loop(c, src, numbytes, inbuf); |
@@ -440,16 +425,16 @@ EXPORT_SYMBOL_GPL(gigaset_m10x_input); | |||
440 | 425 | ||
441 | /* == data output ========================================================== */ | 426 | /* == data output ========================================================== */ |
442 | 427 | ||
443 | /* Encoding of a PPP packet into an octet stuffed HDLC frame | 428 | /* |
444 | * with FCS, opening and closing flags. | 429 | * Encode a data packet into an octet stuffed HDLC frame with FCS, |
430 | * opening and closing flags, preserving headroom data. | ||
445 | * parameters: | 431 | * parameters: |
446 | * skb skb containing original packet (freed upon return) | 432 | * skb skb containing original packet (freed upon return) |
447 | * head number of headroom bytes to allocate in result skb | 433 | * headroom number of headroom bytes to preserve |
448 | * tail number of tailroom bytes to allocate in result skb | ||
449 | * Return value: | 434 | * Return value: |
450 | * pointer to newly allocated skb containing the result frame | 435 | * pointer to newly allocated skb containing the result frame |
451 | */ | 436 | */ |
452 | static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int head, int tail) | 437 | static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int headroom) |
453 | { | 438 | { |
454 | struct sk_buff *hdlc_skb; | 439 | struct sk_buff *hdlc_skb; |
455 | __u16 fcs; | 440 | __u16 fcs; |
@@ -471,16 +456,17 @@ static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int head, int tail) | |||
471 | 456 | ||
472 | /* size of new buffer: original size + number of stuffing bytes | 457 | /* size of new buffer: original size + number of stuffing bytes |
473 | * + 2 bytes FCS + 2 stuffing bytes for FCS (if needed) + 2 flag bytes | 458 | * + 2 bytes FCS + 2 stuffing bytes for FCS (if needed) + 2 flag bytes |
459 | * + room for acknowledgement header | ||
474 | */ | 460 | */ |
475 | hdlc_skb = dev_alloc_skb(skb->len + stuf_cnt + 6 + tail + head); | 461 | hdlc_skb = dev_alloc_skb(skb->len + stuf_cnt + 6 + headroom); |
476 | if (!hdlc_skb) { | 462 | if (!hdlc_skb) { |
477 | dev_kfree_skb(skb); | 463 | dev_kfree_skb(skb); |
478 | return NULL; | 464 | return NULL; |
479 | } | 465 | } |
480 | skb_reserve(hdlc_skb, head); | ||
481 | 466 | ||
482 | /* Copy acknowledge request into new skb */ | 467 | /* Copy acknowledgement header into new skb */ |
483 | memcpy(hdlc_skb->head, skb->head, 2); | 468 | skb_reserve(hdlc_skb, headroom); |
469 | memcpy(hdlc_skb->head, skb->head, headroom); | ||
484 | 470 | ||
485 | /* Add flag sequence in front of everything.. */ | 471 | /* Add flag sequence in front of everything.. */ |
486 | *(skb_put(hdlc_skb, 1)) = PPP_FLAG; | 472 | *(skb_put(hdlc_skb, 1)) = PPP_FLAG; |
@@ -515,15 +501,16 @@ static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int head, int tail) | |||
515 | return hdlc_skb; | 501 | return hdlc_skb; |
516 | } | 502 | } |
517 | 503 | ||
518 | /* Encoding of a raw packet into an octet stuffed bit inverted frame | 504 | /* |
505 | * Encode a data packet into an octet stuffed raw bit inverted frame, | ||
506 | * preserving headroom data. | ||
519 | * parameters: | 507 | * parameters: |
520 | * skb skb containing original packet (freed upon return) | 508 | * skb skb containing original packet (freed upon return) |
521 | * head number of headroom bytes to allocate in result skb | 509 | * headroom number of headroom bytes to preserve |
522 | * tail number of tailroom bytes to allocate in result skb | ||
523 | * Return value: | 510 | * Return value: |
524 | * pointer to newly allocated skb containing the result frame | 511 | * pointer to newly allocated skb containing the result frame |
525 | */ | 512 | */ |
526 | static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail) | 513 | static struct sk_buff *iraw_encode(struct sk_buff *skb, int headroom) |
527 | { | 514 | { |
528 | struct sk_buff *iraw_skb; | 515 | struct sk_buff *iraw_skb; |
529 | unsigned char c; | 516 | unsigned char c; |
@@ -531,12 +518,15 @@ static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail) | |||
531 | int len; | 518 | int len; |
532 | 519 | ||
533 | /* worst case: every byte must be stuffed */ | 520 | /* worst case: every byte must be stuffed */ |
534 | iraw_skb = dev_alloc_skb(2*skb->len + tail + head); | 521 | iraw_skb = dev_alloc_skb(2*skb->len + headroom); |
535 | if (!iraw_skb) { | 522 | if (!iraw_skb) { |
536 | dev_kfree_skb(skb); | 523 | dev_kfree_skb(skb); |
537 | return NULL; | 524 | return NULL; |
538 | } | 525 | } |
539 | skb_reserve(iraw_skb, head); | 526 | |
527 | /* Copy acknowledgement header into new skb */ | ||
528 | skb_reserve(iraw_skb, headroom); | ||
529 | memcpy(iraw_skb->head, skb->head, headroom); | ||
540 | 530 | ||
541 | cp = skb->data; | 531 | cp = skb->data; |
542 | len = skb->len; | 532 | len = skb->len; |
@@ -555,8 +545,10 @@ static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail) | |||
555 | * @bcs: B channel descriptor structure. | 545 | * @bcs: B channel descriptor structure. |
556 | * @skb: data to send. | 546 | * @skb: data to send. |
557 | * | 547 | * |
558 | * Called by i4l.c to encode and queue an skb for sending, and start | 548 | * Called by LL to encode and queue an skb for sending, and start |
559 | * transmission if necessary. | 549 | * transmission if necessary. |
550 | * Once the payload data has been transmitted completely, gigaset_skb_sent() | ||
551 | * will be called with the first cs->hw_hdr_len bytes of skb->head preserved. | ||
560 | * | 552 | * |
561 | * Return value: | 553 | * Return value: |
562 | * number of bytes accepted for sending (skb->len) if ok, | 554 | * number of bytes accepted for sending (skb->len) if ok, |
@@ -567,10 +559,10 @@ int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb) | |||
567 | unsigned len = skb->len; | 559 | unsigned len = skb->len; |
568 | unsigned long flags; | 560 | unsigned long flags; |
569 | 561 | ||
570 | if (bcs->proto2 == ISDN_PROTO_L2_HDLC) | 562 | if (bcs->proto2 == L2_HDLC) |
571 | skb = HDLC_Encode(skb, HW_HDR_LEN, 0); | 563 | skb = HDLC_Encode(skb, bcs->cs->hw_hdr_len); |
572 | else | 564 | else |
573 | skb = iraw_encode(skb, HW_HDR_LEN, 0); | 565 | skb = iraw_encode(skb, bcs->cs->hw_hdr_len); |
574 | if (!skb) { | 566 | if (!skb) { |
575 | dev_err(bcs->cs->dev, | 567 | dev_err(bcs->cs->dev, |
576 | "unable to allocate memory for encoding!\n"); | 568 | "unable to allocate memory for encoding!\n"); |
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index 5ed1d99eb9f3..388e63a8ae94 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c | |||
@@ -911,7 +911,7 @@ static int starturbs(struct bc_state *bcs) | |||
911 | int rc; | 911 | int rc; |
912 | 912 | ||
913 | /* initialize L2 reception */ | 913 | /* initialize L2 reception */ |
914 | if (bcs->proto2 == ISDN_PROTO_L2_HDLC) | 914 | if (bcs->proto2 == L2_HDLC) |
915 | bcs->inputstate |= INS_flag_hunt; | 915 | bcs->inputstate |= INS_flag_hunt; |
916 | 916 | ||
917 | /* submit all isochronous input URBs */ | 917 | /* submit all isochronous input URBs */ |
@@ -1064,7 +1064,7 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx) | |||
1064 | "%s: buffer busy at frame %d", | 1064 | "%s: buffer busy at frame %d", |
1065 | __func__, nframe); | 1065 | __func__, nframe); |
1066 | /* tasklet will be restarted from | 1066 | /* tasklet will be restarted from |
1067 | gigaset_send_skb() */ | 1067 | gigaset_isoc_send_skb() */ |
1068 | } else { | 1068 | } else { |
1069 | dev_err(ucx->bcs->cs->dev, | 1069 | dev_err(ucx->bcs->cs->dev, |
1070 | "%s: buffer error %d at frame %d\n", | 1070 | "%s: buffer error %d at frame %d\n", |
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index 33dcd8d72b7c..15dc0fc28a96 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c | |||
@@ -463,6 +463,12 @@ void gigaset_freecs(struct cardstate *cs) | |||
463 | 463 | ||
464 | switch (cs->cs_init) { | 464 | switch (cs->cs_init) { |
465 | default: | 465 | default: |
466 | /* clear B channel structures */ | ||
467 | for (i = 0; i < cs->channels; ++i) { | ||
468 | gig_dbg(DEBUG_INIT, "clearing bcs[%d]", i); | ||
469 | gigaset_freebcs(cs->bcs + i); | ||
470 | } | ||
471 | |||
466 | /* clear device sysfs */ | 472 | /* clear device sysfs */ |
467 | gigaset_free_dev_sysfs(cs); | 473 | gigaset_free_dev_sysfs(cs); |
468 | 474 | ||
@@ -477,22 +483,16 @@ void gigaset_freecs(struct cardstate *cs) | |||
477 | case 2: /* error in initcshw */ | 483 | case 2: /* error in initcshw */ |
478 | /* Deregister from LL */ | 484 | /* Deregister from LL */ |
479 | make_invalid(cs, VALID_ID); | 485 | make_invalid(cs, VALID_ID); |
480 | gig_dbg(DEBUG_INIT, "clearing iif"); | 486 | gigaset_isdn_unregister(cs); |
481 | gigaset_i4l_cmd(cs, ISDN_STAT_UNLOAD); | ||
482 | 487 | ||
483 | /* fall through */ | 488 | /* fall through */ |
484 | case 1: /* error when regestering to LL */ | 489 | case 1: /* error when registering to LL */ |
485 | gig_dbg(DEBUG_INIT, "clearing at_state"); | 490 | gig_dbg(DEBUG_INIT, "clearing at_state"); |
486 | clear_at_state(&cs->at_state); | 491 | clear_at_state(&cs->at_state); |
487 | dealloc_at_states(cs); | 492 | dealloc_at_states(cs); |
488 | 493 | ||
489 | /* fall through */ | 494 | /* fall through */ |
490 | case 0: /* error in one call to initbcs */ | 495 | case 0: /* error in basic setup */ |
491 | for (i = 0; i < cs->channels; ++i) { | ||
492 | gig_dbg(DEBUG_INIT, "clearing bcs[%d]", i); | ||
493 | gigaset_freebcs(cs->bcs + i); | ||
494 | } | ||
495 | |||
496 | clear_events(cs); | 496 | clear_events(cs); |
497 | gig_dbg(DEBUG_INIT, "freeing inbuf"); | 497 | gig_dbg(DEBUG_INIT, "freeing inbuf"); |
498 | kfree(cs->inbuf); | 498 | kfree(cs->inbuf); |
@@ -620,11 +620,14 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs, | |||
620 | if (cs->ignoreframes) { | 620 | if (cs->ignoreframes) { |
621 | bcs->inputstate |= INS_skip_frame; | 621 | bcs->inputstate |= INS_skip_frame; |
622 | bcs->skb = NULL; | 622 | bcs->skb = NULL; |
623 | } else if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) | 623 | } else { |
624 | skb_reserve(bcs->skb, HW_HDR_LEN); | 624 | bcs->skb = dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len); |
625 | else { | 625 | if (bcs->skb != NULL) |
626 | pr_err("out of memory\n"); | 626 | skb_reserve(bcs->skb, cs->hw_hdr_len); |
627 | bcs->inputstate |= INS_skip_frame; | 627 | else { |
628 | pr_err("out of memory\n"); | ||
629 | bcs->inputstate |= INS_skip_frame; | ||
630 | } | ||
628 | } | 631 | } |
629 | 632 | ||
630 | bcs->channel = channel; | 633 | bcs->channel = channel; |
@@ -726,14 +729,6 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, | |||
726 | cs->mode = M_UNKNOWN; | 729 | cs->mode = M_UNKNOWN; |
727 | cs->mstate = MS_UNINITIALIZED; | 730 | cs->mstate = MS_UNINITIALIZED; |
728 | 731 | ||
729 | for (i = 0; i < channels; ++i) { | ||
730 | gig_dbg(DEBUG_INIT, "setting up bcs[%d].read", i); | ||
731 | if (!gigaset_initbcs(cs->bcs + i, cs, i)) { | ||
732 | pr_err("could not allocate channel %d data\n", i); | ||
733 | goto error; | ||
734 | } | ||
735 | } | ||
736 | |||
737 | ++cs->cs_init; | 732 | ++cs->cs_init; |
738 | 733 | ||
739 | gig_dbg(DEBUG_INIT, "setting up at_state"); | 734 | gig_dbg(DEBUG_INIT, "setting up at_state"); |
@@ -758,7 +753,7 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, | |||
758 | cs->cmdbytes = 0; | 753 | cs->cmdbytes = 0; |
759 | 754 | ||
760 | gig_dbg(DEBUG_INIT, "setting up iif"); | 755 | gig_dbg(DEBUG_INIT, "setting up iif"); |
761 | if (!gigaset_register_to_LL(cs, modulename)) { | 756 | if (!gigaset_isdn_register(cs, modulename)) { |
762 | pr_err("error registering ISDN device\n"); | 757 | pr_err("error registering ISDN device\n"); |
763 | goto error; | 758 | goto error; |
764 | } | 759 | } |
@@ -777,6 +772,15 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, | |||
777 | /* set up device sysfs */ | 772 | /* set up device sysfs */ |
778 | gigaset_init_dev_sysfs(cs); | 773 | gigaset_init_dev_sysfs(cs); |
779 | 774 | ||
775 | /* set up channel data structures */ | ||
776 | for (i = 0; i < channels; ++i) { | ||
777 | gig_dbg(DEBUG_INIT, "setting up bcs[%d]", i); | ||
778 | if (!gigaset_initbcs(cs->bcs + i, cs, i)) { | ||
779 | pr_err("could not allocate channel %d data\n", i); | ||
780 | goto error; | ||
781 | } | ||
782 | } | ||
783 | |||
780 | spin_lock_irqsave(&cs->lock, flags); | 784 | spin_lock_irqsave(&cs->lock, flags); |
781 | cs->running = 1; | 785 | cs->running = 1; |
782 | spin_unlock_irqrestore(&cs->lock, flags); | 786 | spin_unlock_irqrestore(&cs->lock, flags); |
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c index cc768caa38f5..cb25d2b834b9 100644 --- a/drivers/isdn/gigaset/ev-layer.c +++ b/drivers/isdn/gigaset/ev-layer.c | |||
@@ -127,7 +127,6 @@ | |||
127 | #define ACT_NOTIFY_BC_UP 39 | 127 | #define ACT_NOTIFY_BC_UP 39 |
128 | #define ACT_DIAL 40 | 128 | #define ACT_DIAL 40 |
129 | #define ACT_ACCEPT 41 | 129 | #define ACT_ACCEPT 41 |
130 | #define ACT_PROTO_L2 42 | ||
131 | #define ACT_HUP 43 | 130 | #define ACT_HUP 43 |
132 | #define ACT_IF_LOCK 44 | 131 | #define ACT_IF_LOCK 44 |
133 | #define ACT_START 45 | 132 | #define ACT_START 45 |
@@ -365,8 +364,6 @@ struct reply_t gigaset_tab_cid[] = | |||
365 | {EV_BC_CLOSED, -1, -1, -1, -1,-1, {ACT_NOTIFY_BC_DOWN}}, //FIXME | 364 | {EV_BC_CLOSED, -1, -1, -1, -1,-1, {ACT_NOTIFY_BC_DOWN}}, //FIXME |
366 | 365 | ||
367 | /* misc. */ | 366 | /* misc. */ |
368 | {EV_PROTO_L2, -1, -1, -1, -1,-1, {ACT_PROTO_L2}}, //FIXME | ||
369 | |||
370 | {RSP_ZCON, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME | 367 | {RSP_ZCON, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME |
371 | {RSP_ZCCR, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME | 368 | {RSP_ZCCR, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME |
372 | {RSP_ZAOC, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME | 369 | {RSP_ZAOC, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME |
@@ -714,7 +711,7 @@ static void disconnect(struct at_state_t **at_state_p) | |||
714 | /* notify LL */ | 711 | /* notify LL */ |
715 | if (bcs->chstate & (CHS_D_UP | CHS_NOTIFY_LL)) { | 712 | if (bcs->chstate & (CHS_D_UP | CHS_NOTIFY_LL)) { |
716 | bcs->chstate &= ~(CHS_D_UP | CHS_NOTIFY_LL); | 713 | bcs->chstate &= ~(CHS_D_UP | CHS_NOTIFY_LL); |
717 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DHUP); | 714 | gigaset_isdn_hupD(bcs); |
718 | } | 715 | } |
719 | } else { | 716 | } else { |
720 | /* no B channel assigned: just deallocate */ | 717 | /* no B channel assigned: just deallocate */ |
@@ -872,12 +869,12 @@ static void bchannel_down(struct bc_state *bcs) | |||
872 | { | 869 | { |
873 | if (bcs->chstate & CHS_B_UP) { | 870 | if (bcs->chstate & CHS_B_UP) { |
874 | bcs->chstate &= ~CHS_B_UP; | 871 | bcs->chstate &= ~CHS_B_UP; |
875 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BHUP); | 872 | gigaset_isdn_hupB(bcs); |
876 | } | 873 | } |
877 | 874 | ||
878 | if (bcs->chstate & (CHS_D_UP | CHS_NOTIFY_LL)) { | 875 | if (bcs->chstate & (CHS_D_UP | CHS_NOTIFY_LL)) { |
879 | bcs->chstate &= ~(CHS_D_UP | CHS_NOTIFY_LL); | 876 | bcs->chstate &= ~(CHS_D_UP | CHS_NOTIFY_LL); |
880 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DHUP); | 877 | gigaset_isdn_hupD(bcs); |
881 | } | 878 | } |
882 | 879 | ||
883 | gigaset_free_channel(bcs); | 880 | gigaset_free_channel(bcs); |
@@ -894,15 +891,16 @@ static void bchannel_up(struct bc_state *bcs) | |||
894 | } | 891 | } |
895 | 892 | ||
896 | bcs->chstate |= CHS_B_UP; | 893 | bcs->chstate |= CHS_B_UP; |
897 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BCONN); | 894 | gigaset_isdn_connB(bcs); |
898 | } | 895 | } |
899 | 896 | ||
900 | static void start_dial(struct at_state_t *at_state, void *data, unsigned seq_index) | 897 | static void start_dial(struct at_state_t *at_state, void *data, unsigned seq_index) |
901 | { | 898 | { |
902 | struct bc_state *bcs = at_state->bcs; | 899 | struct bc_state *bcs = at_state->bcs; |
903 | struct cardstate *cs = at_state->cs; | 900 | struct cardstate *cs = at_state->cs; |
904 | int retval; | 901 | char **commands = data; |
905 | unsigned long flags; | 902 | unsigned long flags; |
903 | int i; | ||
906 | 904 | ||
907 | bcs->chstate |= CHS_NOTIFY_LL; | 905 | bcs->chstate |= CHS_NOTIFY_LL; |
908 | 906 | ||
@@ -913,10 +911,10 @@ static void start_dial(struct at_state_t *at_state, void *data, unsigned seq_ind | |||
913 | } | 911 | } |
914 | spin_unlock_irqrestore(&cs->lock, flags); | 912 | spin_unlock_irqrestore(&cs->lock, flags); |
915 | 913 | ||
916 | retval = gigaset_isdn_setup_dial(at_state, data); | 914 | for (i = 0; i < AT_NUM; ++i) { |
917 | if (retval != 0) | 915 | kfree(bcs->commands[i]); |
918 | goto error; | 916 | bcs->commands[i] = commands[i]; |
919 | 917 | } | |
920 | 918 | ||
921 | at_state->pending_commands |= PC_CID; | 919 | at_state->pending_commands |= PC_CID; |
922 | gig_dbg(DEBUG_CMD, "Scheduling PC_CID"); | 920 | gig_dbg(DEBUG_CMD, "Scheduling PC_CID"); |
@@ -924,6 +922,10 @@ static void start_dial(struct at_state_t *at_state, void *data, unsigned seq_ind | |||
924 | return; | 922 | return; |
925 | 923 | ||
926 | error: | 924 | error: |
925 | for (i = 0; i < AT_NUM; ++i) { | ||
926 | kfree(commands[i]); | ||
927 | commands[i] = NULL; | ||
928 | } | ||
927 | at_state->pending_commands |= PC_NOCID; | 929 | at_state->pending_commands |= PC_NOCID; |
928 | gig_dbg(DEBUG_CMD, "Scheduling PC_NOCID"); | 930 | gig_dbg(DEBUG_CMD, "Scheduling PC_NOCID"); |
929 | cs->commands_pending = 1; | 931 | cs->commands_pending = 1; |
@@ -933,20 +935,31 @@ error: | |||
933 | static void start_accept(struct at_state_t *at_state) | 935 | static void start_accept(struct at_state_t *at_state) |
934 | { | 936 | { |
935 | struct cardstate *cs = at_state->cs; | 937 | struct cardstate *cs = at_state->cs; |
936 | int retval; | 938 | struct bc_state *bcs = at_state->bcs; |
939 | int i; | ||
937 | 940 | ||
938 | retval = gigaset_isdn_setup_accept(at_state); | 941 | for (i = 0; i < AT_NUM; ++i) { |
942 | kfree(bcs->commands[i]); | ||
943 | bcs->commands[i] = NULL; | ||
944 | } | ||
939 | 945 | ||
940 | if (retval == 0) { | 946 | bcs->commands[AT_PROTO] = kmalloc(9, GFP_ATOMIC); |
941 | at_state->pending_commands |= PC_ACCEPT; | 947 | bcs->commands[AT_ISO] = kmalloc(9, GFP_ATOMIC); |
942 | gig_dbg(DEBUG_CMD, "Scheduling PC_ACCEPT"); | 948 | if (!bcs->commands[AT_PROTO] || !bcs->commands[AT_ISO]) { |
943 | cs->commands_pending = 1; | 949 | dev_err(at_state->cs->dev, "out of memory\n"); |
944 | } else { | ||
945 | /* error reset */ | 950 | /* error reset */ |
946 | at_state->pending_commands |= PC_HUP; | 951 | at_state->pending_commands |= PC_HUP; |
947 | gig_dbg(DEBUG_CMD, "Scheduling PC_HUP"); | 952 | gig_dbg(DEBUG_CMD, "Scheduling PC_HUP"); |
948 | cs->commands_pending = 1; | 953 | cs->commands_pending = 1; |
954 | return; | ||
949 | } | 955 | } |
956 | |||
957 | snprintf(bcs->commands[AT_PROTO], 9, "^SBPR=%u\r", bcs->proto2); | ||
958 | snprintf(bcs->commands[AT_ISO], 9, "^SISO=%u\r", bcs->channel + 1); | ||
959 | |||
960 | at_state->pending_commands |= PC_ACCEPT; | ||
961 | gig_dbg(DEBUG_CMD, "Scheduling PC_ACCEPT"); | ||
962 | cs->commands_pending = 1; | ||
950 | } | 963 | } |
951 | 964 | ||
952 | static void do_start(struct cardstate *cs) | 965 | static void do_start(struct cardstate *cs) |
@@ -957,7 +970,7 @@ static void do_start(struct cardstate *cs) | |||
957 | schedule_init(cs, MS_INIT); | 970 | schedule_init(cs, MS_INIT); |
958 | 971 | ||
959 | cs->isdn_up = 1; | 972 | cs->isdn_up = 1; |
960 | gigaset_i4l_cmd(cs, ISDN_STAT_RUN); | 973 | gigaset_isdn_start(cs); |
961 | // FIXME: not in locked mode | 974 | // FIXME: not in locked mode |
962 | // FIXME 2: only after init sequence | 975 | // FIXME 2: only after init sequence |
963 | 976 | ||
@@ -975,7 +988,7 @@ static void finish_shutdown(struct cardstate *cs) | |||
975 | /* Tell the LL that the device is not available .. */ | 988 | /* Tell the LL that the device is not available .. */ |
976 | if (cs->isdn_up) { | 989 | if (cs->isdn_up) { |
977 | cs->isdn_up = 0; | 990 | cs->isdn_up = 0; |
978 | gigaset_i4l_cmd(cs, ISDN_STAT_STOP); | 991 | gigaset_isdn_stop(cs); |
979 | } | 992 | } |
980 | 993 | ||
981 | /* The rest is done by cleanup_cs () in user mode. */ | 994 | /* The rest is done by cleanup_cs () in user mode. */ |
@@ -1276,7 +1289,7 @@ static void do_action(int action, struct cardstate *cs, | |||
1276 | break; | 1289 | break; |
1277 | } | 1290 | } |
1278 | bcs->chstate |= CHS_D_UP; | 1291 | bcs->chstate |= CHS_D_UP; |
1279 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN); | 1292 | gigaset_isdn_connD(bcs); |
1280 | cs->ops->init_bchannel(bcs); | 1293 | cs->ops->init_bchannel(bcs); |
1281 | break; | 1294 | break; |
1282 | case ACT_DLE1: | 1295 | case ACT_DLE1: |
@@ -1284,7 +1297,7 @@ static void do_action(int action, struct cardstate *cs, | |||
1284 | bcs = cs->bcs + cs->curchannel; | 1297 | bcs = cs->bcs + cs->curchannel; |
1285 | 1298 | ||
1286 | bcs->chstate |= CHS_D_UP; | 1299 | bcs->chstate |= CHS_D_UP; |
1287 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN); | 1300 | gigaset_isdn_connD(bcs); |
1288 | cs->ops->init_bchannel(bcs); | 1301 | cs->ops->init_bchannel(bcs); |
1289 | break; | 1302 | break; |
1290 | case ACT_FAKEHUP: | 1303 | case ACT_FAKEHUP: |
@@ -1474,11 +1487,6 @@ static void do_action(int action, struct cardstate *cs, | |||
1474 | case ACT_ACCEPT: | 1487 | case ACT_ACCEPT: |
1475 | start_accept(at_state); | 1488 | start_accept(at_state); |
1476 | break; | 1489 | break; |
1477 | case ACT_PROTO_L2: | ||
1478 | gig_dbg(DEBUG_CMD, "set protocol to %u", | ||
1479 | (unsigned) ev->parameter); | ||
1480 | at_state->bcs->proto2 = ev->parameter; | ||
1481 | break; | ||
1482 | case ACT_HUP: | 1490 | case ACT_HUP: |
1483 | at_state->pending_commands |= PC_HUP; | 1491 | at_state->pending_commands |= PC_HUP; |
1484 | cs->commands_pending = 1; | 1492 | cs->commands_pending = 1; |
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h index a2f6125739eb..1185da2dbf61 100644 --- a/drivers/isdn/gigaset/gigaset.h +++ b/drivers/isdn/gigaset/gigaset.h | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/compiler.h> | 23 | #include <linux/compiler.h> |
24 | #include <linux/types.h> | 24 | #include <linux/types.h> |
25 | #include <linux/spinlock.h> | 25 | #include <linux/spinlock.h> |
26 | #include <linux/isdnif.h> | ||
27 | #include <linux/usb.h> | 26 | #include <linux/usb.h> |
28 | #include <linux/skbuff.h> | 27 | #include <linux/skbuff.h> |
29 | #include <linux/netdevice.h> | 28 | #include <linux/netdevice.h> |
@@ -40,7 +39,6 @@ | |||
40 | 39 | ||
41 | #define MAX_REC_PARAMS 10 /* Max. number of params in response string */ | 40 | #define MAX_REC_PARAMS 10 /* Max. number of params in response string */ |
42 | #define MAX_RESP_SIZE 512 /* Max. size of a response string */ | 41 | #define MAX_RESP_SIZE 512 /* Max. size of a response string */ |
43 | #define HW_HDR_LEN 2 /* Header size used to store ack info */ | ||
44 | 42 | ||
45 | #define MAX_EVENTS 64 /* size of event queue */ | 43 | #define MAX_EVENTS 64 /* size of event queue */ |
46 | 44 | ||
@@ -216,7 +214,6 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, | |||
216 | #define EV_START -110 | 214 | #define EV_START -110 |
217 | #define EV_STOP -111 | 215 | #define EV_STOP -111 |
218 | #define EV_IF_LOCK -112 | 216 | #define EV_IF_LOCK -112 |
219 | #define EV_PROTO_L2 -113 | ||
220 | #define EV_ACCEPT -114 | 217 | #define EV_ACCEPT -114 |
221 | #define EV_DIAL -115 | 218 | #define EV_DIAL -115 |
222 | #define EV_HUP -116 | 219 | #define EV_HUP -116 |
@@ -259,6 +256,11 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, | |||
259 | #define SM_LOCKED 0 | 256 | #define SM_LOCKED 0 |
260 | #define SM_ISDN 1 /* default */ | 257 | #define SM_ISDN 1 /* default */ |
261 | 258 | ||
259 | /* layer 2 protocols (AT^SBPR=...) */ | ||
260 | #define L2_BITSYNC 0 | ||
261 | #define L2_HDLC 1 | ||
262 | #define L2_VOICE 2 | ||
263 | |||
262 | struct gigaset_ops; | 264 | struct gigaset_ops; |
263 | struct gigaset_driver; | 265 | struct gigaset_driver; |
264 | 266 | ||
@@ -395,7 +397,7 @@ struct bc_state { | |||
395 | 397 | ||
396 | unsigned chstate; /* bitmap (CHS_*) */ | 398 | unsigned chstate; /* bitmap (CHS_*) */ |
397 | int ignore; | 399 | int ignore; |
398 | unsigned proto2; /* Layer 2 protocol (ISDN_PROTO_L2_*) */ | 400 | unsigned proto2; /* layer 2 protocol (L2_*) */ |
399 | char *commands[AT_NUM]; /* see AT_XXXX */ | 401 | char *commands[AT_NUM]; /* see AT_XXXX */ |
400 | 402 | ||
401 | #ifdef CONFIG_GIGASET_DEBUG | 403 | #ifdef CONFIG_GIGASET_DEBUG |
@@ -456,12 +458,13 @@ struct cardstate { | |||
456 | 458 | ||
457 | unsigned running; /* !=0 if events are handled */ | 459 | unsigned running; /* !=0 if events are handled */ |
458 | unsigned connected; /* !=0 if hardware is connected */ | 460 | unsigned connected; /* !=0 if hardware is connected */ |
459 | unsigned isdn_up; /* !=0 after ISDN_STAT_RUN */ | 461 | unsigned isdn_up; /* !=0 after gigaset_isdn_start() */ |
460 | 462 | ||
461 | unsigned cidmode; | 463 | unsigned cidmode; |
462 | 464 | ||
463 | int myid; /* id for communication with LL */ | 465 | int myid; /* id for communication with LL */ |
464 | isdn_if iif; | 466 | void *iif; /* LL interface structure */ |
467 | unsigned short hw_hdr_len; /* headroom needed in data skbs */ | ||
465 | 468 | ||
466 | struct reply_t *tabnocid; | 469 | struct reply_t *tabnocid; |
467 | struct reply_t *tabcid; | 470 | struct reply_t *tabcid; |
@@ -616,7 +619,9 @@ struct gigaset_ops { | |||
616 | int (*baud_rate)(struct cardstate *cs, unsigned cflag); | 619 | int (*baud_rate)(struct cardstate *cs, unsigned cflag); |
617 | int (*set_line_ctrl)(struct cardstate *cs, unsigned cflag); | 620 | int (*set_line_ctrl)(struct cardstate *cs, unsigned cflag); |
618 | 621 | ||
619 | /* Called from i4l.c to put an skb into the send-queue. */ | 622 | /* Called from LL interface to put an skb into the send-queue. |
623 | * After sending is completed, gigaset_skb_sent() must be called | ||
624 | * with the first cs->hw_hdr_len bytes of skb->head preserved. */ | ||
620 | int (*send_skb)(struct bc_state *bcs, struct sk_buff *skb); | 625 | int (*send_skb)(struct bc_state *bcs, struct sk_buff *skb); |
621 | 626 | ||
622 | /* Called from ev-layer.c to process a block of data | 627 | /* Called from ev-layer.c to process a block of data |
@@ -638,8 +643,7 @@ struct gigaset_ops { | |||
638 | * Functions implemented in asyncdata.c | 643 | * Functions implemented in asyncdata.c |
639 | */ | 644 | */ |
640 | 645 | ||
641 | /* Called from i4l.c to put an skb into the send-queue. | 646 | /* Called from LL interface to put an skb into the send queue. */ |
642 | * After sending gigaset_skb_sent() should be called. */ | ||
643 | int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb); | 647 | int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb); |
644 | 648 | ||
645 | /* Called from ev-layer.c to process a block of data | 649 | /* Called from ev-layer.c to process a block of data |
@@ -650,8 +654,7 @@ void gigaset_m10x_input(struct inbuf_t *inbuf); | |||
650 | * Functions implemented in isocdata.c | 654 | * Functions implemented in isocdata.c |
651 | */ | 655 | */ |
652 | 656 | ||
653 | /* Called from i4l.c to put an skb into the send-queue. | 657 | /* Called from LL interface to put an skb into the send queue. */ |
654 | * After sending gigaset_skb_sent() should be called. */ | ||
655 | int gigaset_isoc_send_skb(struct bc_state *bcs, struct sk_buff *skb); | 658 | int gigaset_isoc_send_skb(struct bc_state *bcs, struct sk_buff *skb); |
656 | 659 | ||
657 | /* Called from ev-layer.c to process a block of data | 660 | /* Called from ev-layer.c to process a block of data |
@@ -674,36 +677,26 @@ void gigaset_isowbuf_init(struct isowbuf_t *iwb, unsigned char idle); | |||
674 | int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size); | 677 | int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size); |
675 | 678 | ||
676 | /* =========================================================================== | 679 | /* =========================================================================== |
677 | * Functions implemented in i4l.c/gigaset.h | 680 | * Functions implemented in LL interface |
678 | */ | 681 | */ |
679 | 682 | ||
680 | /* Called by gigaset_initcs() for setting up with the isdn4linux subsystem */ | 683 | /* Called from common.c for setting up/shutting down with the ISDN subsystem */ |
681 | int gigaset_register_to_LL(struct cardstate *cs, const char *isdnid); | 684 | int gigaset_isdn_register(struct cardstate *cs, const char *isdnid); |
685 | void gigaset_isdn_unregister(struct cardstate *cs); | ||
682 | 686 | ||
683 | /* Called from xxx-gigaset.c to indicate completion of sending an skb */ | 687 | /* Called from hardware module to indicate completion of an skb */ |
684 | void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb); | 688 | void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb); |
689 | void gigaset_skb_rcvd(struct bc_state *bcs, struct sk_buff *skb); | ||
690 | void gigaset_isdn_rcv_err(struct bc_state *bcs); | ||
685 | 691 | ||
686 | /* Called from common.c/ev-layer.c to indicate events relevant to the LL */ | 692 | /* Called from common.c/ev-layer.c to indicate events relevant to the LL */ |
693 | void gigaset_isdn_start(struct cardstate *cs); | ||
694 | void gigaset_isdn_stop(struct cardstate *cs); | ||
687 | int gigaset_isdn_icall(struct at_state_t *at_state); | 695 | int gigaset_isdn_icall(struct at_state_t *at_state); |
688 | int gigaset_isdn_setup_accept(struct at_state_t *at_state); | 696 | void gigaset_isdn_connD(struct bc_state *bcs); |
689 | int gigaset_isdn_setup_dial(struct at_state_t *at_state, void *data); | 697 | void gigaset_isdn_hupD(struct bc_state *bcs); |
690 | 698 | void gigaset_isdn_connB(struct bc_state *bcs); | |
691 | void gigaset_i4l_cmd(struct cardstate *cs, int cmd); | 699 | void gigaset_isdn_hupB(struct bc_state *bcs); |
692 | void gigaset_i4l_channel_cmd(struct bc_state *bcs, int cmd); | ||
693 | |||
694 | |||
695 | static inline void gigaset_isdn_rcv_err(struct bc_state *bcs) | ||
696 | { | ||
697 | isdn_ctrl response; | ||
698 | |||
699 | /* error -> LL */ | ||
700 | gig_dbg(DEBUG_CMD, "sending L1ERR"); | ||
701 | response.driver = bcs->cs->myid; | ||
702 | response.command = ISDN_STAT_L1ERR; | ||
703 | response.arg = bcs->channel; | ||
704 | response.parm.errcode = ISDN_STAT_L1ERR_RECV; | ||
705 | bcs->cs->iif.statcallb(&response); | ||
706 | } | ||
707 | 700 | ||
708 | /* =========================================================================== | 701 | /* =========================================================================== |
709 | * Functions implemented in ev-layer.c | 702 | * Functions implemented in ev-layer.c |
@@ -816,35 +809,6 @@ static inline void gigaset_bchannel_up(struct bc_state *bcs) | |||
816 | /* handling routines for sk_buff */ | 809 | /* handling routines for sk_buff */ |
817 | /* ============================= */ | 810 | /* ============================= */ |
818 | 811 | ||
819 | /* pass received skb to LL | ||
820 | * Warning: skb must not be accessed anymore! | ||
821 | */ | ||
822 | static inline void gigaset_rcv_skb(struct sk_buff *skb, | ||
823 | struct cardstate *cs, | ||
824 | struct bc_state *bcs) | ||
825 | { | ||
826 | cs->iif.rcvcallb_skb(cs->myid, bcs->channel, skb); | ||
827 | bcs->trans_down++; | ||
828 | } | ||
829 | |||
830 | /* handle reception of corrupted skb | ||
831 | * Warning: skb must not be accessed anymore! | ||
832 | */ | ||
833 | static inline void gigaset_rcv_error(struct sk_buff *procskb, | ||
834 | struct cardstate *cs, | ||
835 | struct bc_state *bcs) | ||
836 | { | ||
837 | if (procskb) | ||
838 | dev_kfree_skb(procskb); | ||
839 | |||
840 | if (bcs->ignore) | ||
841 | --bcs->ignore; | ||
842 | else { | ||
843 | ++bcs->corrupted; | ||
844 | gigaset_isdn_rcv_err(bcs); | ||
845 | } | ||
846 | } | ||
847 | |||
848 | /* append received bytes to inbuf */ | 812 | /* append received bytes to inbuf */ |
849 | int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src, | 813 | int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src, |
850 | unsigned numbytes); | 814 | unsigned numbytes); |
diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c index 654489d836cd..aca72a06184e 100644 --- a/drivers/isdn/gigaset/i4l.c +++ b/drivers/isdn/gigaset/i4l.c | |||
@@ -14,6 +14,9 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include "gigaset.h" | 16 | #include "gigaset.h" |
17 | #include <linux/isdnif.h> | ||
18 | |||
19 | #define HW_HDR_LEN 2 /* Header size used to store ack info */ | ||
17 | 20 | ||
18 | /* == Handling of I4L IO =====================================================*/ | 21 | /* == Handling of I4L IO =====================================================*/ |
19 | 22 | ||
@@ -95,6 +98,7 @@ static int writebuf_from_LL(int driverID, int channel, int ack, | |||
95 | */ | 98 | */ |
96 | void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb) | 99 | void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb) |
97 | { | 100 | { |
101 | isdn_if *iif = bcs->cs->iif; | ||
98 | unsigned len; | 102 | unsigned len; |
99 | isdn_ctrl response; | 103 | isdn_ctrl response; |
100 | 104 | ||
@@ -114,71 +118,177 @@ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb) | |||
114 | response.command = ISDN_STAT_BSENT; | 118 | response.command = ISDN_STAT_BSENT; |
115 | response.arg = bcs->channel; | 119 | response.arg = bcs->channel; |
116 | response.parm.length = len; | 120 | response.parm.length = len; |
117 | bcs->cs->iif.statcallb(&response); | 121 | iif->statcallb(&response); |
118 | } | 122 | } |
119 | } | 123 | } |
120 | EXPORT_SYMBOL_GPL(gigaset_skb_sent); | 124 | EXPORT_SYMBOL_GPL(gigaset_skb_sent); |
121 | 125 | ||
126 | /** | ||
127 | * gigaset_skb_rcvd() - pass received skb to LL | ||
128 | * @bcs: B channel descriptor structure. | ||
129 | * @skb: received data. | ||
130 | * | ||
131 | * Called by hardware module {bas,ser,usb}_gigaset when user data has | ||
132 | * been successfully received, for passing to the LL. | ||
133 | * Warning: skb must not be accessed anymore! | ||
134 | */ | ||
135 | void gigaset_skb_rcvd(struct bc_state *bcs, struct sk_buff *skb) | ||
136 | { | ||
137 | isdn_if *iif = bcs->cs->iif; | ||
138 | |||
139 | iif->rcvcallb_skb(bcs->cs->myid, bcs->channel, skb); | ||
140 | bcs->trans_down++; | ||
141 | } | ||
142 | EXPORT_SYMBOL_GPL(gigaset_skb_rcvd); | ||
143 | |||
144 | /** | ||
145 | * gigaset_isdn_rcv_err() - signal receive error | ||
146 | * @bcs: B channel descriptor structure. | ||
147 | * | ||
148 | * Called by hardware module {bas,ser,usb}_gigaset when a receive error | ||
149 | * has occurred, for signalling to the LL. | ||
150 | */ | ||
151 | void gigaset_isdn_rcv_err(struct bc_state *bcs) | ||
152 | { | ||
153 | isdn_if *iif = bcs->cs->iif; | ||
154 | isdn_ctrl response; | ||
155 | |||
156 | /* if currently ignoring packets, just count down */ | ||
157 | if (bcs->ignore) { | ||
158 | bcs->ignore--; | ||
159 | return; | ||
160 | } | ||
161 | |||
162 | /* update statistics */ | ||
163 | bcs->corrupted++; | ||
164 | |||
165 | /* error -> LL */ | ||
166 | gig_dbg(DEBUG_CMD, "sending L1ERR"); | ||
167 | response.driver = bcs->cs->myid; | ||
168 | response.command = ISDN_STAT_L1ERR; | ||
169 | response.arg = bcs->channel; | ||
170 | response.parm.errcode = ISDN_STAT_L1ERR_RECV; | ||
171 | iif->statcallb(&response); | ||
172 | } | ||
173 | EXPORT_SYMBOL_GPL(gigaset_isdn_rcv_err); | ||
174 | |||
122 | /* This function will be called by LL to send commands | 175 | /* This function will be called by LL to send commands |
123 | * NOTE: LL ignores the returned value, for commands other than ISDN_CMD_IOCTL, | 176 | * NOTE: LL ignores the returned value, for commands other than ISDN_CMD_IOCTL, |
124 | * so don't put too much effort into it. | 177 | * so don't put too much effort into it. |
125 | */ | 178 | */ |
126 | static int command_from_LL(isdn_ctrl *cntrl) | 179 | static int command_from_LL(isdn_ctrl *cntrl) |
127 | { | 180 | { |
128 | struct cardstate *cs = gigaset_get_cs_by_id(cntrl->driver); | 181 | struct cardstate *cs; |
129 | struct bc_state *bcs; | 182 | struct bc_state *bcs; |
130 | int retval = 0; | 183 | int retval = 0; |
131 | struct setup_parm *sp; | 184 | char **commands; |
185 | int ch; | ||
186 | int i; | ||
187 | size_t l; | ||
132 | 188 | ||
133 | gigaset_debugdrivers(); | 189 | gigaset_debugdrivers(); |
134 | 190 | ||
135 | if (!cs) { | 191 | gig_dbg(DEBUG_CMD, "driver: %d, command: %d, arg: 0x%lx", |
192 | cntrl->driver, cntrl->command, cntrl->arg); | ||
193 | |||
194 | cs = gigaset_get_cs_by_id(cntrl->driver); | ||
195 | if (cs == NULL) { | ||
136 | pr_err("%s: invalid driver ID (%d)\n", __func__, cntrl->driver); | 196 | pr_err("%s: invalid driver ID (%d)\n", __func__, cntrl->driver); |
137 | return -ENODEV; | 197 | return -ENODEV; |
138 | } | 198 | } |
199 | ch = cntrl->arg & 0xff; | ||
139 | 200 | ||
140 | switch (cntrl->command) { | 201 | switch (cntrl->command) { |
141 | case ISDN_CMD_IOCTL: | 202 | case ISDN_CMD_IOCTL: |
142 | gig_dbg(DEBUG_ANY, "ISDN_CMD_IOCTL (driver: %d, arg: %ld)", | ||
143 | cntrl->driver, cntrl->arg); | ||
144 | |||
145 | dev_warn(cs->dev, "ISDN_CMD_IOCTL not supported\n"); | 203 | dev_warn(cs->dev, "ISDN_CMD_IOCTL not supported\n"); |
146 | return -EINVAL; | 204 | return -EINVAL; |
147 | 205 | ||
148 | case ISDN_CMD_DIAL: | 206 | case ISDN_CMD_DIAL: |
149 | gig_dbg(DEBUG_ANY, | 207 | gig_dbg(DEBUG_ANY, |
150 | "ISDN_CMD_DIAL (driver: %d, ch: %ld, " | 208 | "ISDN_CMD_DIAL (phone: %s, msn: %s, si1: %d, si2: %d)", |
151 | "phone: %s, ownmsn: %s, si1: %d, si2: %d)", | ||
152 | cntrl->driver, cntrl->arg, | ||
153 | cntrl->parm.setup.phone, cntrl->parm.setup.eazmsn, | 209 | cntrl->parm.setup.phone, cntrl->parm.setup.eazmsn, |
154 | cntrl->parm.setup.si1, cntrl->parm.setup.si2); | 210 | cntrl->parm.setup.si1, cntrl->parm.setup.si2); |
155 | 211 | ||
156 | if (cntrl->arg >= cs->channels) { | 212 | if (ch >= cs->channels) { |
157 | dev_err(cs->dev, | 213 | dev_err(cs->dev, |
158 | "ISDN_CMD_DIAL: invalid channel (%d)\n", | 214 | "ISDN_CMD_DIAL: invalid channel (%d)\n", ch); |
159 | (int) cntrl->arg); | ||
160 | return -EINVAL; | 215 | return -EINVAL; |
161 | } | 216 | } |
162 | 217 | bcs = cs->bcs + ch; | |
163 | bcs = cs->bcs + cntrl->arg; | ||
164 | |||
165 | if (!gigaset_get_channel(bcs)) { | 218 | if (!gigaset_get_channel(bcs)) { |
166 | dev_err(cs->dev, "ISDN_CMD_DIAL: channel not free\n"); | 219 | dev_err(cs->dev, "ISDN_CMD_DIAL: channel not free\n"); |
167 | return -EBUSY; | 220 | return -EBUSY; |
168 | } | 221 | } |
169 | 222 | ||
170 | sp = kmalloc(sizeof *sp, GFP_ATOMIC); | 223 | commands = kzalloc(AT_NUM*(sizeof *commands), GFP_ATOMIC); |
171 | if (!sp) { | 224 | if (!commands) { |
172 | gigaset_free_channel(bcs); | 225 | gigaset_free_channel(bcs); |
173 | dev_err(cs->dev, "ISDN_CMD_DIAL: out of memory\n"); | 226 | dev_err(cs->dev, "ISDN_CMD_DIAL: out of memory\n"); |
174 | return -ENOMEM; | 227 | return -ENOMEM; |
175 | } | 228 | } |
176 | *sp = cntrl->parm.setup; | ||
177 | 229 | ||
178 | if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, sp, | 230 | l = 3 + strlen(cntrl->parm.setup.phone); |
231 | commands[AT_DIAL] = kmalloc(l, GFP_ATOMIC); | ||
232 | if (!commands[AT_DIAL]) | ||
233 | goto oom; | ||
234 | if (cntrl->parm.setup.phone[0] == '*' && | ||
235 | cntrl->parm.setup.phone[1] == '*') { | ||
236 | /* internal call: translate ** prefix to CTP value */ | ||
237 | commands[AT_TYPE] = kstrdup("^SCTP=0\r", GFP_ATOMIC); | ||
238 | if (!commands[AT_TYPE]) | ||
239 | goto oom; | ||
240 | snprintf(commands[AT_DIAL], l, | ||
241 | "D%s\r", cntrl->parm.setup.phone+2); | ||
242 | } else { | ||
243 | commands[AT_TYPE] = kstrdup("^SCTP=1\r", GFP_ATOMIC); | ||
244 | if (!commands[AT_TYPE]) | ||
245 | goto oom; | ||
246 | snprintf(commands[AT_DIAL], l, | ||
247 | "D%s\r", cntrl->parm.setup.phone); | ||
248 | } | ||
249 | |||
250 | l = strlen(cntrl->parm.setup.eazmsn); | ||
251 | if (l) { | ||
252 | l += 8; | ||
253 | commands[AT_MSN] = kmalloc(l, GFP_ATOMIC); | ||
254 | if (!commands[AT_MSN]) | ||
255 | goto oom; | ||
256 | snprintf(commands[AT_MSN], l, "^SMSN=%s\r", | ||
257 | cntrl->parm.setup.eazmsn); | ||
258 | } | ||
259 | |||
260 | switch (cntrl->parm.setup.si1) { | ||
261 | case 1: /* audio */ | ||
262 | /* BC = 9090A3: 3.1 kHz audio, A-law */ | ||
263 | commands[AT_BC] = kstrdup("^SBC=9090A3\r", GFP_ATOMIC); | ||
264 | if (!commands[AT_BC]) | ||
265 | goto oom; | ||
266 | break; | ||
267 | case 7: /* data */ | ||
268 | default: /* hope the app knows what it is doing */ | ||
269 | /* BC = 8890: unrestricted digital information */ | ||
270 | commands[AT_BC] = kstrdup("^SBC=8890\r", GFP_ATOMIC); | ||
271 | if (!commands[AT_BC]) | ||
272 | goto oom; | ||
273 | } | ||
274 | /* ToDo: other si1 values, inspect si2, set HLC/LLC */ | ||
275 | |||
276 | commands[AT_PROTO] = kmalloc(9, GFP_ATOMIC); | ||
277 | if (!commands[AT_PROTO]) | ||
278 | goto oom; | ||
279 | snprintf(commands[AT_PROTO], 9, "^SBPR=%u\r", bcs->proto2); | ||
280 | |||
281 | commands[AT_ISO] = kmalloc(9, GFP_ATOMIC); | ||
282 | if (!commands[AT_ISO]) | ||
283 | goto oom; | ||
284 | snprintf(commands[AT_ISO], 9, "^SISO=%u\r", | ||
285 | (unsigned) bcs->channel + 1); | ||
286 | |||
287 | if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, commands, | ||
179 | bcs->at_state.seq_index, NULL)) { | 288 | bcs->at_state.seq_index, NULL)) { |
180 | //FIXME what should we do? | 289 | for (i = 0; i < AT_NUM; ++i) |
181 | kfree(sp); | 290 | kfree(commands[i]); |
291 | kfree(commands); | ||
182 | gigaset_free_channel(bcs); | 292 | gigaset_free_channel(bcs); |
183 | return -ENOMEM; | 293 | return -ENOMEM; |
184 | } | 294 | } |
@@ -186,93 +296,83 @@ static int command_from_LL(isdn_ctrl *cntrl) | |||
186 | gig_dbg(DEBUG_CMD, "scheduling DIAL"); | 296 | gig_dbg(DEBUG_CMD, "scheduling DIAL"); |
187 | gigaset_schedule_event(cs); | 297 | gigaset_schedule_event(cs); |
188 | break; | 298 | break; |
189 | case ISDN_CMD_ACCEPTD: //FIXME | 299 | case ISDN_CMD_ACCEPTD: |
190 | gig_dbg(DEBUG_ANY, "ISDN_CMD_ACCEPTD"); | 300 | if (ch >= cs->channels) { |
191 | |||
192 | if (cntrl->arg >= cs->channels) { | ||
193 | dev_err(cs->dev, | 301 | dev_err(cs->dev, |
194 | "ISDN_CMD_ACCEPTD: invalid channel (%d)\n", | 302 | "ISDN_CMD_ACCEPTD: invalid channel (%d)\n", ch); |
195 | (int) cntrl->arg); | ||
196 | return -EINVAL; | 303 | return -EINVAL; |
197 | } | 304 | } |
198 | 305 | bcs = cs->bcs + ch; | |
199 | if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg].at_state, | 306 | if (!gigaset_add_event(cs, &bcs->at_state, |
200 | EV_ACCEPT, NULL, 0, NULL)) { | 307 | EV_ACCEPT, NULL, 0, NULL)) |
201 | //FIXME what should we do? | ||
202 | return -ENOMEM; | 308 | return -ENOMEM; |
203 | } | ||
204 | 309 | ||
205 | gig_dbg(DEBUG_CMD, "scheduling ACCEPT"); | 310 | gig_dbg(DEBUG_CMD, "scheduling ACCEPT"); |
206 | gigaset_schedule_event(cs); | 311 | gigaset_schedule_event(cs); |
207 | 312 | ||
208 | break; | 313 | break; |
209 | case ISDN_CMD_ACCEPTB: | 314 | case ISDN_CMD_ACCEPTB: |
210 | gig_dbg(DEBUG_ANY, "ISDN_CMD_ACCEPTB"); | ||
211 | break; | 315 | break; |
212 | case ISDN_CMD_HANGUP: | 316 | case ISDN_CMD_HANGUP: |
213 | gig_dbg(DEBUG_ANY, "ISDN_CMD_HANGUP (ch: %d)", | 317 | if (ch >= cs->channels) { |
214 | (int) cntrl->arg); | ||
215 | |||
216 | if (cntrl->arg >= cs->channels) { | ||
217 | dev_err(cs->dev, | 318 | dev_err(cs->dev, |
218 | "ISDN_CMD_HANGUP: invalid channel (%d)\n", | 319 | "ISDN_CMD_HANGUP: invalid channel (%d)\n", ch); |
219 | (int) cntrl->arg); | ||
220 | return -EINVAL; | 320 | return -EINVAL; |
221 | } | 321 | } |
222 | 322 | bcs = cs->bcs + ch; | |
223 | if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg].at_state, | 323 | if (!gigaset_add_event(cs, &bcs->at_state, |
224 | EV_HUP, NULL, 0, NULL)) { | 324 | EV_HUP, NULL, 0, NULL)) |
225 | //FIXME what should we do? | ||
226 | return -ENOMEM; | 325 | return -ENOMEM; |
227 | } | ||
228 | 326 | ||
229 | gig_dbg(DEBUG_CMD, "scheduling HUP"); | 327 | gig_dbg(DEBUG_CMD, "scheduling HUP"); |
230 | gigaset_schedule_event(cs); | 328 | gigaset_schedule_event(cs); |
231 | 329 | ||
232 | break; | 330 | break; |
233 | case ISDN_CMD_CLREAZ: /* Do not signal incoming signals */ //FIXME | 331 | case ISDN_CMD_CLREAZ: /* Do not signal incoming signals */ |
234 | gig_dbg(DEBUG_ANY, "ISDN_CMD_CLREAZ"); | 332 | dev_info(cs->dev, "ignoring ISDN_CMD_CLREAZ\n"); |
235 | break; | 333 | break; |
236 | case ISDN_CMD_SETEAZ: /* Signal incoming calls for given MSN */ //FIXME | 334 | case ISDN_CMD_SETEAZ: /* Signal incoming calls for given MSN */ |
237 | gig_dbg(DEBUG_ANY, | 335 | dev_info(cs->dev, "ignoring ISDN_CMD_SETEAZ (%s)\n", |
238 | "ISDN_CMD_SETEAZ (id: %d, ch: %ld, number: %s)", | 336 | cntrl->parm.num); |
239 | cntrl->driver, cntrl->arg, cntrl->parm.num); | ||
240 | break; | 337 | break; |
241 | case ISDN_CMD_SETL2: /* Set L2 to given protocol */ | 338 | case ISDN_CMD_SETL2: /* Set L2 to given protocol */ |
242 | gig_dbg(DEBUG_ANY, "ISDN_CMD_SETL2 (ch: %ld, proto: %lx)", | 339 | if (ch >= cs->channels) { |
243 | cntrl->arg & 0xff, (cntrl->arg >> 8)); | ||
244 | |||
245 | if ((cntrl->arg & 0xff) >= cs->channels) { | ||
246 | dev_err(cs->dev, | 340 | dev_err(cs->dev, |
247 | "ISDN_CMD_SETL2: invalid channel (%d)\n", | 341 | "ISDN_CMD_SETL2: invalid channel (%d)\n", ch); |
248 | (int) cntrl->arg & 0xff); | ||
249 | return -EINVAL; | 342 | return -EINVAL; |
250 | } | 343 | } |
251 | 344 | bcs = cs->bcs + ch; | |
252 | if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg & 0xff].at_state, | 345 | if (bcs->chstate & CHS_D_UP) { |
253 | EV_PROTO_L2, NULL, cntrl->arg >> 8, | 346 | dev_err(cs->dev, |
254 | NULL)) { | 347 | "ISDN_CMD_SETL2: channel active (%d)\n", ch); |
255 | //FIXME what should we do? | 348 | return -EINVAL; |
256 | return -ENOMEM; | 349 | } |
350 | switch (cntrl->arg >> 8) { | ||
351 | case ISDN_PROTO_L2_HDLC: | ||
352 | gig_dbg(DEBUG_CMD, "ISDN_CMD_SETL2: setting L2_HDLC"); | ||
353 | bcs->proto2 = L2_HDLC; | ||
354 | break; | ||
355 | case ISDN_PROTO_L2_TRANS: | ||
356 | gig_dbg(DEBUG_CMD, "ISDN_CMD_SETL2: setting L2_VOICE"); | ||
357 | bcs->proto2 = L2_VOICE; | ||
358 | break; | ||
359 | default: | ||
360 | dev_err(cs->dev, | ||
361 | "ISDN_CMD_SETL2: unsupported protocol (%lu)\n", | ||
362 | cntrl->arg >> 8); | ||
363 | return -EINVAL; | ||
257 | } | 364 | } |
258 | |||
259 | gig_dbg(DEBUG_CMD, "scheduling PROTO_L2"); | ||
260 | gigaset_schedule_event(cs); | ||
261 | break; | 365 | break; |
262 | case ISDN_CMD_SETL3: /* Set L3 to given protocol */ | 366 | case ISDN_CMD_SETL3: /* Set L3 to given protocol */ |
263 | gig_dbg(DEBUG_ANY, "ISDN_CMD_SETL3 (ch: %ld, proto: %lx)", | 367 | if (ch >= cs->channels) { |
264 | cntrl->arg & 0xff, (cntrl->arg >> 8)); | ||
265 | |||
266 | if ((cntrl->arg & 0xff) >= cs->channels) { | ||
267 | dev_err(cs->dev, | 368 | dev_err(cs->dev, |
268 | "ISDN_CMD_SETL3: invalid channel (%d)\n", | 369 | "ISDN_CMD_SETL3: invalid channel (%d)\n", ch); |
269 | (int) cntrl->arg & 0xff); | ||
270 | return -EINVAL; | 370 | return -EINVAL; |
271 | } | 371 | } |
272 | 372 | ||
273 | if (cntrl->arg >> 8 != ISDN_PROTO_L3_TRANS) { | 373 | if (cntrl->arg >> 8 != ISDN_PROTO_L3_TRANS) { |
274 | dev_err(cs->dev, | 374 | dev_err(cs->dev, |
275 | "ISDN_CMD_SETL3: invalid protocol %lu\n", | 375 | "ISDN_CMD_SETL3: unsupported protocol (%lu)\n", |
276 | cntrl->arg >> 8); | 376 | cntrl->arg >> 8); |
277 | return -EINVAL; | 377 | return -EINVAL; |
278 | } | 378 | } |
@@ -324,149 +424,34 @@ static int command_from_LL(isdn_ctrl *cntrl) | |||
324 | } | 424 | } |
325 | 425 | ||
326 | return retval; | 426 | return retval; |
427 | |||
428 | oom: | ||
429 | dev_err(bcs->cs->dev, "out of memory\n"); | ||
430 | for (i = 0; i < AT_NUM; ++i) | ||
431 | kfree(commands[i]); | ||
432 | return -ENOMEM; | ||
327 | } | 433 | } |
328 | 434 | ||
329 | void gigaset_i4l_cmd(struct cardstate *cs, int cmd) | 435 | static void gigaset_i4l_cmd(struct cardstate *cs, int cmd) |
330 | { | 436 | { |
437 | isdn_if *iif = cs->iif; | ||
331 | isdn_ctrl command; | 438 | isdn_ctrl command; |
332 | 439 | ||
333 | command.driver = cs->myid; | 440 | command.driver = cs->myid; |
334 | command.command = cmd; | 441 | command.command = cmd; |
335 | command.arg = 0; | 442 | command.arg = 0; |
336 | cs->iif.statcallb(&command); | 443 | iif->statcallb(&command); |
337 | } | 444 | } |
338 | 445 | ||
339 | void gigaset_i4l_channel_cmd(struct bc_state *bcs, int cmd) | 446 | static void gigaset_i4l_channel_cmd(struct bc_state *bcs, int cmd) |
340 | { | 447 | { |
448 | isdn_if *iif = bcs->cs->iif; | ||
341 | isdn_ctrl command; | 449 | isdn_ctrl command; |
342 | 450 | ||
343 | command.driver = bcs->cs->myid; | 451 | command.driver = bcs->cs->myid; |
344 | command.command = cmd; | 452 | command.command = cmd; |
345 | command.arg = bcs->channel; | 453 | command.arg = bcs->channel; |
346 | bcs->cs->iif.statcallb(&command); | 454 | iif->statcallb(&command); |
347 | } | ||
348 | |||
349 | int gigaset_isdn_setup_dial(struct at_state_t *at_state, void *data) | ||
350 | { | ||
351 | struct bc_state *bcs = at_state->bcs; | ||
352 | unsigned proto; | ||
353 | const char *bc; | ||
354 | size_t length[AT_NUM]; | ||
355 | size_t l; | ||
356 | int i; | ||
357 | struct setup_parm *sp = data; | ||
358 | |||
359 | switch (bcs->proto2) { | ||
360 | case ISDN_PROTO_L2_HDLC: | ||
361 | proto = 1; /* 0: Bitsynchron, 1: HDLC, 2: voice */ | ||
362 | break; | ||
363 | case ISDN_PROTO_L2_TRANS: | ||
364 | proto = 2; /* 0: Bitsynchron, 1: HDLC, 2: voice */ | ||
365 | break; | ||
366 | default: | ||
367 | dev_err(bcs->cs->dev, "%s: invalid L2 protocol: %u\n", | ||
368 | __func__, bcs->proto2); | ||
369 | return -EINVAL; | ||
370 | } | ||
371 | |||
372 | switch (sp->si1) { | ||
373 | case 1: /* audio */ | ||
374 | bc = "9090A3"; /* 3.1 kHz audio, A-law */ | ||
375 | break; | ||
376 | case 7: /* data */ | ||
377 | default: /* hope the app knows what it is doing */ | ||
378 | bc = "8890"; /* unrestricted digital information */ | ||
379 | } | ||
380 | //FIXME add missing si1 values from 1TR6, inspect si2, set HLC/LLC | ||
381 | |||
382 | length[AT_DIAL ] = 1 + strlen(sp->phone) + 1 + 1; | ||
383 | l = strlen(sp->eazmsn); | ||
384 | length[AT_MSN ] = l ? 6 + l + 1 + 1 : 0; | ||
385 | length[AT_BC ] = 5 + strlen(bc) + 1 + 1; | ||
386 | length[AT_PROTO] = 6 + 1 + 1 + 1; /* proto: 1 character */ | ||
387 | length[AT_ISO ] = 6 + 1 + 1 + 1; /* channel: 1 character */ | ||
388 | length[AT_TYPE ] = 6 + 1 + 1 + 1; /* call type: 1 character */ | ||
389 | length[AT_HLC ] = 0; | ||
390 | |||
391 | for (i = 0; i < AT_NUM; ++i) { | ||
392 | kfree(bcs->commands[i]); | ||
393 | bcs->commands[i] = NULL; | ||
394 | if (length[i] && | ||
395 | !(bcs->commands[i] = kmalloc(length[i], GFP_ATOMIC))) { | ||
396 | dev_err(bcs->cs->dev, "out of memory\n"); | ||
397 | return -ENOMEM; | ||
398 | } | ||
399 | } | ||
400 | |||
401 | /* type = 1: extern, 0: intern, 2: recall, 3: door, 4: centrex */ | ||
402 | if (sp->phone[0] == '*' && sp->phone[1] == '*') { | ||
403 | /* internal call: translate ** prefix to CTP value */ | ||
404 | snprintf(bcs->commands[AT_DIAL], length[AT_DIAL], | ||
405 | "D%s\r", sp->phone+2); | ||
406 | strncpy(bcs->commands[AT_TYPE], "^SCTP=0\r", length[AT_TYPE]); | ||
407 | } else { | ||
408 | snprintf(bcs->commands[AT_DIAL], length[AT_DIAL], | ||
409 | "D%s\r", sp->phone); | ||
410 | strncpy(bcs->commands[AT_TYPE], "^SCTP=1\r", length[AT_TYPE]); | ||
411 | } | ||
412 | |||
413 | if (bcs->commands[AT_MSN]) | ||
414 | snprintf(bcs->commands[AT_MSN], length[AT_MSN], | ||
415 | "^SMSN=%s\r", sp->eazmsn); | ||
416 | snprintf(bcs->commands[AT_BC ], length[AT_BC ], | ||
417 | "^SBC=%s\r", bc); | ||
418 | snprintf(bcs->commands[AT_PROTO], length[AT_PROTO], | ||
419 | "^SBPR=%u\r", proto); | ||
420 | snprintf(bcs->commands[AT_ISO ], length[AT_ISO ], | ||
421 | "^SISO=%u\r", (unsigned)bcs->channel + 1); | ||
422 | |||
423 | return 0; | ||
424 | } | ||
425 | |||
426 | int gigaset_isdn_setup_accept(struct at_state_t *at_state) | ||
427 | { | ||
428 | unsigned proto; | ||
429 | size_t length[AT_NUM]; | ||
430 | int i; | ||
431 | struct bc_state *bcs = at_state->bcs; | ||
432 | |||
433 | switch (bcs->proto2) { | ||
434 | case ISDN_PROTO_L2_HDLC: | ||
435 | proto = 1; /* 0: Bitsynchron, 1: HDLC, 2: voice */ | ||
436 | break; | ||
437 | case ISDN_PROTO_L2_TRANS: | ||
438 | proto = 2; /* 0: Bitsynchron, 1: HDLC, 2: voice */ | ||
439 | break; | ||
440 | default: | ||
441 | dev_err(at_state->cs->dev, "%s: invalid protocol: %u\n", | ||
442 | __func__, bcs->proto2); | ||
443 | return -EINVAL; | ||
444 | } | ||
445 | |||
446 | length[AT_DIAL ] = 0; | ||
447 | length[AT_MSN ] = 0; | ||
448 | length[AT_BC ] = 0; | ||
449 | length[AT_PROTO] = 6 + 1 + 1 + 1; /* proto: 1 character */ | ||
450 | length[AT_ISO ] = 6 + 1 + 1 + 1; /* channel: 1 character */ | ||
451 | length[AT_TYPE ] = 0; | ||
452 | length[AT_HLC ] = 0; | ||
453 | |||
454 | for (i = 0; i < AT_NUM; ++i) { | ||
455 | kfree(bcs->commands[i]); | ||
456 | bcs->commands[i] = NULL; | ||
457 | if (length[i] && | ||
458 | !(bcs->commands[i] = kmalloc(length[i], GFP_ATOMIC))) { | ||
459 | dev_err(at_state->cs->dev, "out of memory\n"); | ||
460 | return -ENOMEM; | ||
461 | } | ||
462 | } | ||
463 | |||
464 | snprintf(bcs->commands[AT_PROTO], length[AT_PROTO], | ||
465 | "^SBPR=%u\r", proto); | ||
466 | snprintf(bcs->commands[AT_ISO ], length[AT_ISO ], | ||
467 | "^SISO=%u\r", (unsigned) bcs->channel + 1); | ||
468 | |||
469 | return 0; | ||
470 | } | 455 | } |
471 | 456 | ||
472 | /** | 457 | /** |
@@ -482,6 +467,7 @@ int gigaset_isdn_icall(struct at_state_t *at_state) | |||
482 | { | 467 | { |
483 | struct cardstate *cs = at_state->cs; | 468 | struct cardstate *cs = at_state->cs; |
484 | struct bc_state *bcs = at_state->bcs; | 469 | struct bc_state *bcs = at_state->bcs; |
470 | isdn_if *iif = cs->iif; | ||
485 | isdn_ctrl response; | 471 | isdn_ctrl response; |
486 | int retval; | 472 | int retval; |
487 | 473 | ||
@@ -531,7 +517,7 @@ int gigaset_isdn_icall(struct at_state_t *at_state) | |||
531 | response.arg = bcs->channel; //FIXME | 517 | response.arg = bcs->channel; //FIXME |
532 | } | 518 | } |
533 | response.driver = cs->myid; | 519 | response.driver = cs->myid; |
534 | retval = cs->iif.statcallb(&response); | 520 | retval = iif->statcallb(&response); |
535 | gig_dbg(DEBUG_CMD, "Response: %d", retval); | 521 | gig_dbg(DEBUG_CMD, "Response: %d", retval); |
536 | switch (retval) { | 522 | switch (retval) { |
537 | case 0: /* no takers */ | 523 | case 0: /* no takers */ |
@@ -560,16 +546,109 @@ int gigaset_isdn_icall(struct at_state_t *at_state) | |||
560 | } | 546 | } |
561 | } | 547 | } |
562 | 548 | ||
563 | /* Set Callback function pointer */ | 549 | /** |
564 | int gigaset_register_to_LL(struct cardstate *cs, const char *isdnid) | 550 | * gigaset_isdn_connD() - signal D channel connect |
551 | * @bcs: B channel descriptor structure. | ||
552 | * | ||
553 | * Called by main module to notify the LL that the D channel connection has | ||
554 | * been established. | ||
555 | */ | ||
556 | void gigaset_isdn_connD(struct bc_state *bcs) | ||
565 | { | 557 | { |
566 | isdn_if *iif = &cs->iif; | 558 | gig_dbg(DEBUG_CMD, "sending DCONN"); |
559 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN); | ||
560 | } | ||
567 | 561 | ||
568 | gig_dbg(DEBUG_ANY, "Register driver capabilities to LL"); | 562 | /** |
563 | * gigaset_isdn_hupD() - signal D channel hangup | ||
564 | * @bcs: B channel descriptor structure. | ||
565 | * | ||
566 | * Called by main module to notify the LL that the D channel connection has | ||
567 | * been shut down. | ||
568 | */ | ||
569 | void gigaset_isdn_hupD(struct bc_state *bcs) | ||
570 | { | ||
571 | gig_dbg(DEBUG_CMD, "sending DHUP"); | ||
572 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DHUP); | ||
573 | } | ||
574 | |||
575 | /** | ||
576 | * gigaset_isdn_connB() - signal B channel connect | ||
577 | * @bcs: B channel descriptor structure. | ||
578 | * | ||
579 | * Called by main module to notify the LL that the B channel connection has | ||
580 | * been established. | ||
581 | */ | ||
582 | void gigaset_isdn_connB(struct bc_state *bcs) | ||
583 | { | ||
584 | gig_dbg(DEBUG_CMD, "sending BCONN"); | ||
585 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BCONN); | ||
586 | } | ||
587 | |||
588 | /** | ||
589 | * gigaset_isdn_hupB() - signal B channel hangup | ||
590 | * @bcs: B channel descriptor structure. | ||
591 | * | ||
592 | * Called by main module to notify the LL that the B channel connection has | ||
593 | * been shut down. | ||
594 | */ | ||
595 | void gigaset_isdn_hupB(struct bc_state *bcs) | ||
596 | { | ||
597 | gig_dbg(DEBUG_CMD, "sending BHUP"); | ||
598 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BHUP); | ||
599 | } | ||
600 | |||
601 | /** | ||
602 | * gigaset_isdn_start() - signal device availability | ||
603 | * @cs: device descriptor structure. | ||
604 | * | ||
605 | * Called by main module to notify the LL that the device is available for | ||
606 | * use. | ||
607 | */ | ||
608 | void gigaset_isdn_start(struct cardstate *cs) | ||
609 | { | ||
610 | gig_dbg(DEBUG_CMD, "sending RUN"); | ||
611 | gigaset_i4l_cmd(cs, ISDN_STAT_RUN); | ||
612 | } | ||
613 | |||
614 | /** | ||
615 | * gigaset_isdn_stop() - signal device unavailability | ||
616 | * @cs: device descriptor structure. | ||
617 | * | ||
618 | * Called by main module to notify the LL that the device is no longer | ||
619 | * available for use. | ||
620 | */ | ||
621 | void gigaset_isdn_stop(struct cardstate *cs) | ||
622 | { | ||
623 | gig_dbg(DEBUG_CMD, "sending STOP"); | ||
624 | gigaset_i4l_cmd(cs, ISDN_STAT_STOP); | ||
625 | } | ||
626 | |||
627 | /** | ||
628 | * gigaset_isdn_register() - register to LL | ||
629 | * @cs: device descriptor structure. | ||
630 | * @isdnid: device name. | ||
631 | * | ||
632 | * Called by main module to register the device with the LL. | ||
633 | * | ||
634 | * Return value: 1 for success, 0 for failure | ||
635 | */ | ||
636 | int gigaset_isdn_register(struct cardstate *cs, const char *isdnid) | ||
637 | { | ||
638 | isdn_if *iif; | ||
639 | |||
640 | pr_info("ISDN4Linux interface\n"); | ||
641 | |||
642 | iif = kmalloc(sizeof *iif, GFP_KERNEL); | ||
643 | if (!iif) { | ||
644 | pr_err("out of memory\n"); | ||
645 | return 0; | ||
646 | } | ||
569 | 647 | ||
570 | if (snprintf(iif->id, sizeof iif->id, "%s_%u", isdnid, cs->minor_index) | 648 | if (snprintf(iif->id, sizeof iif->id, "%s_%u", isdnid, cs->minor_index) |
571 | >= sizeof iif->id) { | 649 | >= sizeof iif->id) { |
572 | pr_err("ID too long: %s\n", isdnid); | 650 | pr_err("ID too long: %s\n", isdnid); |
651 | kfree(iif); | ||
573 | return 0; | 652 | return 0; |
574 | } | 653 | } |
575 | 654 | ||
@@ -593,9 +672,26 @@ int gigaset_register_to_LL(struct cardstate *cs, const char *isdnid) | |||
593 | 672 | ||
594 | if (!register_isdn(iif)) { | 673 | if (!register_isdn(iif)) { |
595 | pr_err("register_isdn failed\n"); | 674 | pr_err("register_isdn failed\n"); |
675 | kfree(iif); | ||
596 | return 0; | 676 | return 0; |
597 | } | 677 | } |
598 | 678 | ||
679 | cs->iif = iif; | ||
599 | cs->myid = iif->channels; /* Set my device id */ | 680 | cs->myid = iif->channels; /* Set my device id */ |
681 | cs->hw_hdr_len = HW_HDR_LEN; | ||
600 | return 1; | 682 | return 1; |
601 | } | 683 | } |
684 | |||
685 | /** | ||
686 | * gigaset_isdn_unregister() - unregister from LL | ||
687 | * @cs: device descriptor structure. | ||
688 | * | ||
689 | * Called by main module to unregister the device from the LL. | ||
690 | */ | ||
691 | void gigaset_isdn_unregister(struct cardstate *cs) | ||
692 | { | ||
693 | gig_dbg(DEBUG_CMD, "sending UNLOAD"); | ||
694 | gigaset_i4l_cmd(cs, ISDN_STAT_UNLOAD); | ||
695 | kfree(cs->iif); | ||
696 | cs->iif = NULL; | ||
697 | } | ||
diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c index 9f3ef7b4248c..7dabfd35874c 100644 --- a/drivers/isdn/gigaset/isocdata.c +++ b/drivers/isdn/gigaset/isocdata.c | |||
@@ -500,7 +500,7 @@ int gigaset_isoc_buildframe(struct bc_state *bcs, unsigned char *in, int len) | |||
500 | int result; | 500 | int result; |
501 | 501 | ||
502 | switch (bcs->proto2) { | 502 | switch (bcs->proto2) { |
503 | case ISDN_PROTO_L2_HDLC: | 503 | case L2_HDLC: |
504 | result = hdlc_buildframe(bcs->hw.bas->isooutbuf, in, len); | 504 | result = hdlc_buildframe(bcs->hw.bas->isooutbuf, in, len); |
505 | gig_dbg(DEBUG_ISO, "%s: %d bytes HDLC -> %d", | 505 | gig_dbg(DEBUG_ISO, "%s: %d bytes HDLC -> %d", |
506 | __func__, len, result); | 506 | __func__, len, result); |
@@ -542,8 +542,9 @@ static inline void hdlc_flush(struct bc_state *bcs) | |||
542 | if (likely(bcs->skb != NULL)) | 542 | if (likely(bcs->skb != NULL)) |
543 | skb_trim(bcs->skb, 0); | 543 | skb_trim(bcs->skb, 0); |
544 | else if (!bcs->ignore) { | 544 | else if (!bcs->ignore) { |
545 | if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) | 545 | bcs->skb = dev_alloc_skb(SBUFSIZE + bcs->cs->hw_hdr_len); |
546 | skb_reserve(bcs->skb, HW_HDR_LEN); | 546 | if (bcs->skb) |
547 | skb_reserve(bcs->skb, bcs->cs->hw_hdr_len); | ||
547 | else | 548 | else |
548 | dev_err(bcs->cs->dev, "could not allocate skb\n"); | 549 | dev_err(bcs->cs->dev, "could not allocate skb\n"); |
549 | } | 550 | } |
@@ -557,7 +558,9 @@ static inline void hdlc_flush(struct bc_state *bcs) | |||
557 | */ | 558 | */ |
558 | static inline void hdlc_done(struct bc_state *bcs) | 559 | static inline void hdlc_done(struct bc_state *bcs) |
559 | { | 560 | { |
561 | struct cardstate *cs = bcs->cs; | ||
560 | struct sk_buff *procskb; | 562 | struct sk_buff *procskb; |
563 | unsigned int len; | ||
561 | 564 | ||
562 | if (unlikely(bcs->ignore)) { | 565 | if (unlikely(bcs->ignore)) { |
563 | bcs->ignore--; | 566 | bcs->ignore--; |
@@ -568,32 +571,33 @@ static inline void hdlc_done(struct bc_state *bcs) | |||
568 | if ((procskb = bcs->skb) == NULL) { | 571 | if ((procskb = bcs->skb) == NULL) { |
569 | /* previous error */ | 572 | /* previous error */ |
570 | gig_dbg(DEBUG_ISO, "%s: skb=NULL", __func__); | 573 | gig_dbg(DEBUG_ISO, "%s: skb=NULL", __func__); |
571 | gigaset_rcv_error(NULL, bcs->cs, bcs); | 574 | gigaset_isdn_rcv_err(bcs); |
572 | } else if (procskb->len < 2) { | 575 | } else if (procskb->len < 2) { |
573 | dev_notice(bcs->cs->dev, "received short frame (%d octets)\n", | 576 | dev_notice(cs->dev, "received short frame (%d octets)\n", |
574 | procskb->len); | 577 | procskb->len); |
575 | bcs->hw.bas->runts++; | 578 | bcs->hw.bas->runts++; |
576 | gigaset_rcv_error(procskb, bcs->cs, bcs); | 579 | dev_kfree_skb(procskb); |
580 | gigaset_isdn_rcv_err(bcs); | ||
577 | } else if (bcs->fcs != PPP_GOODFCS) { | 581 | } else if (bcs->fcs != PPP_GOODFCS) { |
578 | dev_notice(bcs->cs->dev, "frame check error (0x%04x)\n", | 582 | dev_notice(cs->dev, "frame check error (0x%04x)\n", bcs->fcs); |
579 | bcs->fcs); | ||
580 | bcs->hw.bas->fcserrs++; | 583 | bcs->hw.bas->fcserrs++; |
581 | gigaset_rcv_error(procskb, bcs->cs, bcs); | 584 | dev_kfree_skb(procskb); |
585 | gigaset_isdn_rcv_err(bcs); | ||
582 | } else { | 586 | } else { |
583 | procskb->len -= 2; /* subtract FCS */ | 587 | len = procskb->len; |
584 | procskb->tail -= 2; | 588 | __skb_trim(procskb, len -= 2); /* subtract FCS */ |
585 | gig_dbg(DEBUG_ISO, "%s: good frame (%d octets)", | 589 | gig_dbg(DEBUG_ISO, "%s: good frame (%d octets)", __func__, len); |
586 | __func__, procskb->len); | ||
587 | dump_bytes(DEBUG_STREAM_DUMP, | 590 | dump_bytes(DEBUG_STREAM_DUMP, |
588 | "rcv data", procskb->data, procskb->len); | 591 | "rcv data", procskb->data, len); |
589 | bcs->hw.bas->goodbytes += procskb->len; | 592 | bcs->hw.bas->goodbytes += len; |
590 | gigaset_rcv_skb(procskb, bcs->cs, bcs); | 593 | gigaset_skb_rcvd(bcs, procskb); |
591 | } | 594 | } |
592 | 595 | ||
593 | if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) | 596 | bcs->skb = dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len); |
594 | skb_reserve(bcs->skb, HW_HDR_LEN); | 597 | if (bcs->skb) |
598 | skb_reserve(bcs->skb, cs->hw_hdr_len); | ||
595 | else | 599 | else |
596 | dev_err(bcs->cs->dev, "could not allocate skb\n"); | 600 | dev_err(cs->dev, "could not allocate skb\n"); |
597 | bcs->fcs = PPP_INITFCS; | 601 | bcs->fcs = PPP_INITFCS; |
598 | } | 602 | } |
599 | 603 | ||
@@ -610,12 +614,8 @@ static inline void hdlc_frag(struct bc_state *bcs, unsigned inbits) | |||
610 | 614 | ||
611 | dev_notice(bcs->cs->dev, "received partial byte (%d bits)\n", inbits); | 615 | dev_notice(bcs->cs->dev, "received partial byte (%d bits)\n", inbits); |
612 | bcs->hw.bas->alignerrs++; | 616 | bcs->hw.bas->alignerrs++; |
613 | gigaset_rcv_error(bcs->skb, bcs->cs, bcs); | 617 | gigaset_isdn_rcv_err(bcs); |
614 | 618 | __skb_trim(bcs->skb, 0); | |
615 | if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) | ||
616 | skb_reserve(bcs->skb, HW_HDR_LEN); | ||
617 | else | ||
618 | dev_err(bcs->cs->dev, "could not allocate skb\n"); | ||
619 | bcs->fcs = PPP_INITFCS; | 619 | bcs->fcs = PPP_INITFCS; |
620 | } | 620 | } |
621 | 621 | ||
@@ -648,8 +648,8 @@ static const unsigned char bitcounts[256] = { | |||
648 | /* hdlc_unpack | 648 | /* hdlc_unpack |
649 | * perform HDLC frame processing (bit unstuffing, flag detection, FCS calculation) | 649 | * perform HDLC frame processing (bit unstuffing, flag detection, FCS calculation) |
650 | * on a sequence of received data bytes (8 bits each, LSB first) | 650 | * on a sequence of received data bytes (8 bits each, LSB first) |
651 | * pass on successfully received, complete frames as SKBs via gigaset_rcv_skb | 651 | * pass on successfully received, complete frames as SKBs via gigaset_skb_rcvd |
652 | * notify of errors via gigaset_rcv_error | 652 | * notify of errors via gigaset_isdn_rcv_err |
653 | * tally frames, errors etc. in BC structure counters | 653 | * tally frames, errors etc. in BC structure counters |
654 | * parameters: | 654 | * parameters: |
655 | * src received data | 655 | * src received data |
@@ -841,7 +841,7 @@ static inline void hdlc_unpack(unsigned char *src, unsigned count, | |||
841 | } | 841 | } |
842 | 842 | ||
843 | /* trans_receive | 843 | /* trans_receive |
844 | * pass on received USB frame transparently as SKB via gigaset_rcv_skb | 844 | * pass on received USB frame transparently as SKB via gigaset_skb_rcvd |
845 | * invert bytes | 845 | * invert bytes |
846 | * tally frames, errors etc. in BC structure counters | 846 | * tally frames, errors etc. in BC structure counters |
847 | * parameters: | 847 | * parameters: |
@@ -852,6 +852,7 @@ static inline void hdlc_unpack(unsigned char *src, unsigned count, | |||
852 | static inline void trans_receive(unsigned char *src, unsigned count, | 852 | static inline void trans_receive(unsigned char *src, unsigned count, |
853 | struct bc_state *bcs) | 853 | struct bc_state *bcs) |
854 | { | 854 | { |
855 | struct cardstate *cs = bcs->cs; | ||
855 | struct sk_buff *skb; | 856 | struct sk_buff *skb; |
856 | int dobytes; | 857 | int dobytes; |
857 | unsigned char *dst; | 858 | unsigned char *dst; |
@@ -862,12 +863,12 @@ static inline void trans_receive(unsigned char *src, unsigned count, | |||
862 | return; | 863 | return; |
863 | } | 864 | } |
864 | if (unlikely((skb = bcs->skb) == NULL)) { | 865 | if (unlikely((skb = bcs->skb) == NULL)) { |
865 | bcs->skb = skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN); | 866 | bcs->skb = skb = dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len); |
866 | if (!skb) { | 867 | if (!skb) { |
867 | dev_err(bcs->cs->dev, "could not allocate skb\n"); | 868 | dev_err(cs->dev, "could not allocate skb\n"); |
868 | return; | 869 | return; |
869 | } | 870 | } |
870 | skb_reserve(skb, HW_HDR_LEN); | 871 | skb_reserve(skb, cs->hw_hdr_len); |
871 | } | 872 | } |
872 | bcs->hw.bas->goodbytes += skb->len; | 873 | bcs->hw.bas->goodbytes += skb->len; |
873 | dobytes = TRANSBUFSIZE - skb->len; | 874 | dobytes = TRANSBUFSIZE - skb->len; |
@@ -881,14 +882,14 @@ static inline void trans_receive(unsigned char *src, unsigned count, | |||
881 | if (dobytes == 0) { | 882 | if (dobytes == 0) { |
882 | dump_bytes(DEBUG_STREAM_DUMP, | 883 | dump_bytes(DEBUG_STREAM_DUMP, |
883 | "rcv data", skb->data, skb->len); | 884 | "rcv data", skb->data, skb->len); |
884 | gigaset_rcv_skb(skb, bcs->cs, bcs); | 885 | gigaset_skb_rcvd(bcs, skb); |
885 | bcs->skb = skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN); | 886 | bcs->skb = skb = |
887 | dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len); | ||
886 | if (!skb) { | 888 | if (!skb) { |
887 | dev_err(bcs->cs->dev, | 889 | dev_err(cs->dev, "could not allocate skb\n"); |
888 | "could not allocate skb\n"); | ||
889 | return; | 890 | return; |
890 | } | 891 | } |
891 | skb_reserve(bcs->skb, HW_HDR_LEN); | 892 | skb_reserve(skb, cs->hw_hdr_len); |
892 | dobytes = TRANSBUFSIZE; | 893 | dobytes = TRANSBUFSIZE; |
893 | } | 894 | } |
894 | } | 895 | } |
@@ -897,7 +898,7 @@ static inline void trans_receive(unsigned char *src, unsigned count, | |||
897 | void gigaset_isoc_receive(unsigned char *src, unsigned count, struct bc_state *bcs) | 898 | void gigaset_isoc_receive(unsigned char *src, unsigned count, struct bc_state *bcs) |
898 | { | 899 | { |
899 | switch (bcs->proto2) { | 900 | switch (bcs->proto2) { |
900 | case ISDN_PROTO_L2_HDLC: | 901 | case L2_HDLC: |
901 | hdlc_unpack(src, count, bcs); | 902 | hdlc_unpack(src, count, bcs); |
902 | break; | 903 | break; |
903 | default: /* assume transparent */ | 904 | default: /* assume transparent */ |
@@ -981,8 +982,10 @@ void gigaset_isoc_input(struct inbuf_t *inbuf) | |||
981 | * @bcs: B channel descriptor structure. | 982 | * @bcs: B channel descriptor structure. |
982 | * @skb: data to send. | 983 | * @skb: data to send. |
983 | * | 984 | * |
984 | * Called by i4l.c to queue an skb for sending, and start transmission if | 985 | * Called by LL to queue an skb for sending, and start transmission if |
985 | * necessary. | 986 | * necessary. |
987 | * Once the payload data has been transmitted completely, gigaset_skb_sent() | ||
988 | * will be called with the first cs->hw_hdr_len bytes of skb->head preserved. | ||
986 | * | 989 | * |
987 | * Return value: | 990 | * Return value: |
988 | * number of bytes accepted for sending (skb->len) if ok, | 991 | * number of bytes accepted for sending (skb->len) if ok, |