diff options
| -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, |
