aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/gigaset/asyncdata.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/gigaset/asyncdata.c')
-rw-r--r--drivers/isdn/gigaset/asyncdata.c132
1 files changed, 61 insertions, 71 deletions
diff --git a/drivers/isdn/gigaset/asyncdata.c b/drivers/isdn/gigaset/asyncdata.c
index 171f8b703d61..ce3cd77094b3 100644
--- a/drivers/isdn/gigaset/asyncdata.c
+++ b/drivers/isdn/gigaset/asyncdata.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (c) 2005 by Tilman Schmidt <tilman@imap.cc>, 4 * Copyright (c) 2005 by Tilman Schmidt <tilman@imap.cc>,
5 * Hansjoerg Lipp <hjlipp@web.de>, 5 * Hansjoerg Lipp <hjlipp@web.de>,
6 * Stefan Eilers <Eilers.Stefan@epost.de>. 6 * Stefan Eilers.
7 * 7 *
8 * ===================================================================== 8 * =====================================================================
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
@@ -11,10 +11,6 @@
11 * published by the Free Software Foundation; either version 2 of 11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version. 12 * the License, or (at your option) any later version.
13 * ===================================================================== 13 * =====================================================================
14 * ToDo: ...
15 * =====================================================================
16 * Version: $Id: asyncdata.c,v 1.2.2.7 2005/11/13 23:05:18 hjlipp Exp $
17 * =====================================================================
18 */ 14 */
19 15
20#include "gigaset.h" 16#include "gigaset.h"
@@ -45,7 +41,7 @@ static inline int muststuff(unsigned char c)
45 * number of processed bytes 41 * number of processed bytes
46 */ 42 */
47static inline int cmd_loop(unsigned char c, unsigned char *src, int numbytes, 43static inline int cmd_loop(unsigned char c, unsigned char *src, int numbytes,
48 struct inbuf_t *inbuf) 44 struct inbuf_t *inbuf)
49{ 45{
50 struct cardstate *cs = inbuf->cs; 46 struct cardstate *cs = inbuf->cs;
51 unsigned cbytes = cs->cbytes; 47 unsigned cbytes = cs->cbytes;
@@ -55,10 +51,11 @@ static inline int cmd_loop(unsigned char c, unsigned char *src, int numbytes,
55 for (;;) { 51 for (;;) {
56 cs->respdata[cbytes] = c; 52 cs->respdata[cbytes] = c;
57 if (c == 10 || c == 13) { 53 if (c == 10 || c == 13) {
58 dbg(DEBUG_TRANSCMD, "%s: End of Command (%d Bytes)", 54 gig_dbg(DEBUG_TRANSCMD, "%s: End of Command (%d Bytes)",
59 __func__, cbytes); 55 __func__, cbytes);
60 cs->cbytes = cbytes; 56 cs->cbytes = cbytes;
61 gigaset_handle_modem_response(cs); /* can change cs->dle */ 57 gigaset_handle_modem_response(cs); /* can change
58 cs->dle */
62 cbytes = 0; 59 cbytes = 0;
63 60
64 if (cs->dle && 61 if (cs->dle &&
@@ -71,7 +68,7 @@ static inline int cmd_loop(unsigned char c, unsigned char *src, int numbytes,
71 if (cbytes < MAX_RESP_SIZE - 1) 68 if (cbytes < MAX_RESP_SIZE - 1)
72 cbytes++; 69 cbytes++;
73 else 70 else
74 warn("response too large"); 71 dev_warn(cs->dev, "response too large\n");
75 } 72 }
76 73
77 if (!numbytes) 74 if (!numbytes)
@@ -96,11 +93,12 @@ static inline int cmd_loop(unsigned char c, unsigned char *src, int numbytes,
96 * number of processed bytes 93 * number of processed bytes
97 */ 94 */
98static inline int lock_loop(unsigned char *src, int numbytes, 95static inline int lock_loop(unsigned char *src, int numbytes,
99 struct inbuf_t *inbuf) 96 struct inbuf_t *inbuf)
100{ 97{
101 struct cardstate *cs = inbuf->cs; 98 struct cardstate *cs = inbuf->cs;
102 99
103 gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response", numbytes, src, 0); 100 gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response",
101 numbytes, src);
104 gigaset_if_receive(cs, src, numbytes); 102 gigaset_if_receive(cs, src, numbytes);
105 103
106 return numbytes; 104 return numbytes;
@@ -115,24 +113,18 @@ static inline int lock_loop(unsigned char *src, int numbytes,
115 * numbytes (all bytes processed) on error --FIXME 113 * numbytes (all bytes processed) on error --FIXME
116 */ 114 */
117static inline int hdlc_loop(unsigned char c, unsigned char *src, int numbytes, 115static inline int hdlc_loop(unsigned char c, unsigned char *src, int numbytes,
118 struct inbuf_t *inbuf) 116 struct inbuf_t *inbuf)
119{ 117{
120 struct cardstate *cs = inbuf->cs; 118 struct cardstate *cs = inbuf->cs;
121 struct bc_state *bcs = inbuf->bcs; 119 struct bc_state *bcs = inbuf->bcs;
122 int inputstate; 120 int inputstate = bcs->inputstate;
123 __u16 fcs; 121 __u16 fcs = bcs->fcs;
124 struct sk_buff *skb; 122 struct sk_buff *skb = bcs->skb;
125 unsigned char error; 123 unsigned char error;
126 struct sk_buff *compskb; 124 struct sk_buff *compskb;
127 int startbytes = numbytes; 125 int startbytes = numbytes;
128 int l; 126 int l;
129 127
130 IFNULLRETVAL(bcs, numbytes);
131 inputstate = bcs->inputstate;
132 fcs = bcs->fcs;
133 skb = bcs->skb;
134 IFNULLRETVAL(skb, numbytes);
135
136 if (unlikely(inputstate & INS_byte_stuff)) { 128 if (unlikely(inputstate & INS_byte_stuff)) {
137 inputstate &= ~INS_byte_stuff; 129 inputstate &= ~INS_byte_stuff;
138 goto byte_stuff; 130 goto byte_stuff;
@@ -156,39 +148,37 @@ byte_stuff:
156 c ^= PPP_TRANS; 148 c ^= PPP_TRANS;
157#ifdef CONFIG_GIGASET_DEBUG 149#ifdef CONFIG_GIGASET_DEBUG
158 if (unlikely(!muststuff(c))) 150 if (unlikely(!muststuff(c)))
159 dbg(DEBUG_HDLC, 151 gig_dbg(DEBUG_HDLC, "byte stuffed: 0x%02x", c);
160 "byte stuffed: 0x%02x", c);
161#endif 152#endif
162 } else if (unlikely(c == PPP_FLAG)) { 153 } else if (unlikely(c == PPP_FLAG)) {
163 if (unlikely(inputstate & INS_skip_frame)) { 154 if (unlikely(inputstate & INS_skip_frame)) {
164 if (!(inputstate & INS_have_data)) { /* 7E 7E */ 155 if (!(inputstate & INS_have_data)) { /* 7E 7E */
165 //dbg(DEBUG_HDLC, "(7e)7e------------------------");
166#ifdef CONFIG_GIGASET_DEBUG 156#ifdef CONFIG_GIGASET_DEBUG
167 ++bcs->emptycount; 157 ++bcs->emptycount;
168#endif 158#endif
169 } else 159 } else
170 dbg(DEBUG_HDLC, 160 gig_dbg(DEBUG_HDLC,
171 "7e----------------------------"); 161 "7e----------------------------");
172 162
173 /* end of frame */ 163 /* end of frame */
174 error = 1; 164 error = 1;
175 gigaset_rcv_error(NULL, cs, bcs); 165 gigaset_rcv_error(NULL, cs, bcs);
176 } else if (!(inputstate & INS_have_data)) { /* 7E 7E */ 166 } else if (!(inputstate & INS_have_data)) { /* 7E 7E */
177 //dbg(DEBUG_HDLC, "(7e)7e------------------------");
178#ifdef CONFIG_GIGASET_DEBUG 167#ifdef CONFIG_GIGASET_DEBUG
179 ++bcs->emptycount; 168 ++bcs->emptycount;
180#endif 169#endif
181 break; 170 break;
182 } else { 171 } else {
183 dbg(DEBUG_HDLC, 172 gig_dbg(DEBUG_HDLC,
184 "7e----------------------------"); 173 "7e----------------------------");
185 174
186 /* end of frame */ 175 /* end of frame */
187 error = 0; 176 error = 0;
188 177
189 if (unlikely(fcs != PPP_GOODFCS)) { 178 if (unlikely(fcs != PPP_GOODFCS)) {
190 err("Packet checksum at %lu failed, " 179 dev_err(cs->dev,
191 "packet is corrupted (%u bytes)!", 180 "Packet checksum at %lu failed, "
181 "packet is corrupted (%u bytes)!\n",
192 bcs->rcvbytes, skb->len); 182 bcs->rcvbytes, skb->len);
193 compskb = NULL; 183 compskb = NULL;
194 gigaset_rcv_error(compskb, cs, bcs); 184 gigaset_rcv_error(compskb, cs, bcs);
@@ -202,9 +192,11 @@ byte_stuff:
202 skb = NULL; 192 skb = NULL;
203 inputstate |= INS_skip_frame; 193 inputstate |= INS_skip_frame;
204 if (l == 1) { 194 if (l == 1) {
205 err("invalid packet size (1)!"); 195 dev_err(cs->dev,
196 "invalid packet size (1)!\n");
206 error = 1; 197 error = 1;
207 gigaset_rcv_error(NULL, cs, bcs); 198 gigaset_rcv_error(NULL,
199 cs, bcs);
208 } 200 }
209 } 201 }
210 if (likely(!(error || 202 if (likely(!(error ||
@@ -227,7 +219,8 @@ byte_stuff:
227 } else if (likely((skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)) { 219 } else if (likely((skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)) {
228 skb_reserve(skb, HW_HDR_LEN); 220 skb_reserve(skb, HW_HDR_LEN);
229 } else { 221 } else {
230 warn("could not allocate new skb"); 222 dev_warn(cs->dev,
223 "could not allocate new skb\n");
231 inputstate |= INS_skip_frame; 224 inputstate |= INS_skip_frame;
232 } 225 }
233 226
@@ -235,7 +228,7 @@ byte_stuff:
235#ifdef CONFIG_GIGASET_DEBUG 228#ifdef CONFIG_GIGASET_DEBUG
236 } else if (unlikely(muststuff(c))) { 229 } else if (unlikely(muststuff(c))) {
237 /* Should not happen. Possible after ZDLE=1<CR><LF>. */ 230 /* Should not happen. Possible after ZDLE=1<CR><LF>. */
238 dbg(DEBUG_HDLC, "not byte stuffed: 0x%02x", c); 231 gig_dbg(DEBUG_HDLC, "not byte stuffed: 0x%02x", c);
239#endif 232#endif
240 } 233 }
241 234
@@ -243,8 +236,8 @@ byte_stuff:
243 236
244#ifdef CONFIG_GIGASET_DEBUG 237#ifdef CONFIG_GIGASET_DEBUG
245 if (unlikely(!(inputstate & INS_have_data))) { 238 if (unlikely(!(inputstate & INS_have_data))) {
246 dbg(DEBUG_HDLC, 239 gig_dbg(DEBUG_HDLC, "7e (%d x) ================",
247 "7e (%d x) ================", bcs->emptycount); 240 bcs->emptycount);
248 bcs->emptycount = 0; 241 bcs->emptycount = 0;
249 } 242 }
250#endif 243#endif
@@ -253,14 +246,13 @@ byte_stuff:
253 246
254 if (likely(!(inputstate & INS_skip_frame))) { 247 if (likely(!(inputstate & INS_skip_frame))) {
255 if (unlikely(skb->len == SBUFSIZE)) { 248 if (unlikely(skb->len == SBUFSIZE)) {
256 warn("received packet too long"); 249 dev_warn(cs->dev, "received packet too long\n");
257 dev_kfree_skb_any(skb); 250 dev_kfree_skb_any(skb);
258 skb = NULL; 251 skb = NULL;
259 inputstate |= INS_skip_frame; 252 inputstate |= INS_skip_frame;
260 break; 253 break;
261 } 254 }
262 *gigaset_skb_put_quick(skb, 1) = c; 255 *__skb_put(skb, 1) = c;
263 /* *__skb_put (skb, 1) = c; */
264 fcs = crc_ccitt_byte(fcs, c); 256 fcs = crc_ccitt_byte(fcs, c);
265 } 257 }
266 258
@@ -289,19 +281,14 @@ byte_stuff:
289 * numbytes (all bytes processed) on error --FIXME 281 * numbytes (all bytes processed) on error --FIXME
290 */ 282 */
291static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes, 283static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes,
292 struct inbuf_t *inbuf) 284 struct inbuf_t *inbuf)
293{ 285{
294 struct cardstate *cs = inbuf->cs; 286 struct cardstate *cs = inbuf->cs;
295 struct bc_state *bcs = inbuf->bcs; 287 struct bc_state *bcs = inbuf->bcs;
296 int inputstate; 288 int inputstate = bcs->inputstate;
297 struct sk_buff *skb; 289 struct sk_buff *skb = bcs->skb;
298 int startbytes = numbytes; 290 int startbytes = numbytes;
299 291
300 IFNULLRETVAL(bcs, numbytes);
301 inputstate = bcs->inputstate;
302 skb = bcs->skb;
303 IFNULLRETVAL(skb, numbytes);
304
305 for (;;) { 292 for (;;) {
306 /* add character */ 293 /* add character */
307 inputstate |= INS_have_data; 294 inputstate |= INS_have_data;
@@ -309,13 +296,13 @@ static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes,
309 if (likely(!(inputstate & INS_skip_frame))) { 296 if (likely(!(inputstate & INS_skip_frame))) {
310 if (unlikely(skb->len == SBUFSIZE)) { 297 if (unlikely(skb->len == SBUFSIZE)) {
311 //FIXME just pass skb up and allocate a new one 298 //FIXME just pass skb up and allocate a new one
312 warn("received packet too long"); 299 dev_warn(cs->dev, "received packet too long\n");
313 dev_kfree_skb_any(skb); 300 dev_kfree_skb_any(skb);
314 skb = NULL; 301 skb = NULL;
315 inputstate |= INS_skip_frame; 302 inputstate |= INS_skip_frame;
316 break; 303 break;
317 } 304 }
318 *gigaset_skb_put_quick(skb, 1) = gigaset_invtab[c]; 305 *__skb_put(skb, 1) = gigaset_invtab[c];
319 } 306 }
320 307
321 if (unlikely(!numbytes)) 308 if (unlikely(!numbytes))
@@ -343,7 +330,7 @@ static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes,
343 != NULL)) { 330 != NULL)) {
344 skb_reserve(skb, HW_HDR_LEN); 331 skb_reserve(skb, HW_HDR_LEN);
345 } else { 332 } else {
346 warn("could not allocate new skb"); 333 dev_warn(cs->dev, "could not allocate new skb\n");
347 inputstate |= INS_skip_frame; 334 inputstate |= INS_skip_frame;
348 } 335 }
349 } 336 }
@@ -364,13 +351,13 @@ void gigaset_m10x_input(struct inbuf_t *inbuf)
364 351
365 head = atomic_read(&inbuf->head); 352 head = atomic_read(&inbuf->head);
366 tail = atomic_read(&inbuf->tail); 353 tail = atomic_read(&inbuf->tail);
367 dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail); 354 gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail);
368 355
369 if (head != tail) { 356 if (head != tail) {
370 cs = inbuf->cs; 357 cs = inbuf->cs;
371 src = inbuf->data + head; 358 src = inbuf->data + head;
372 numbytes = (head > tail ? RBUFSIZE : tail) - head; 359 numbytes = (head > tail ? RBUFSIZE : tail) - head;
373 dbg(DEBUG_INTR, "processing %u bytes", numbytes); 360 gig_dbg(DEBUG_INTR, "processing %u bytes", numbytes);
374 361
375 while (numbytes) { 362 while (numbytes) {
376 if (atomic_read(&cs->mstate) == MS_LOCKED) { 363 if (atomic_read(&cs->mstate) == MS_LOCKED) {
@@ -392,8 +379,7 @@ void gigaset_m10x_input(struct inbuf_t *inbuf)
392 379
393 if (!(inbuf->inputstate & INS_DLE_char)) { 380 if (!(inbuf->inputstate & INS_DLE_char)) {
394 381
395 /* FIXME Einfach je nach Modus Funktionszeiger in cs setzen [hier+hdlc_loop]? */ 382 /* FIXME use function pointers? */
396 /* FIXME Spart folgendes "if" und ermoeglicht andere Protokolle */
397 if (inbuf->inputstate & INS_command) 383 if (inbuf->inputstate & INS_command)
398 procbytes = cmd_loop(c, src, numbytes, inbuf); 384 procbytes = cmd_loop(c, src, numbytes, inbuf);
399 else if (inbuf->bcs->proto2 == ISDN_PROTO_L2_HDLC) 385 else if (inbuf->bcs->proto2 == ISDN_PROTO_L2_HDLC)
@@ -403,13 +389,14 @@ void gigaset_m10x_input(struct inbuf_t *inbuf)
403 389
404 src += procbytes; 390 src += procbytes;
405 numbytes -= procbytes; 391 numbytes -= procbytes;
406 } else { /* DLE-char */ 392 } else { /* DLE char */
407 inbuf->inputstate &= ~INS_DLE_char; 393 inbuf->inputstate &= ~INS_DLE_char;
408 switch (c) { 394 switch (c) {
409 case 'X': /*begin of command*/ 395 case 'X': /*begin of command*/
410#ifdef CONFIG_GIGASET_DEBUG 396#ifdef CONFIG_GIGASET_DEBUG
411 if (inbuf->inputstate & INS_command) 397 if (inbuf->inputstate & INS_command)
412 err("received <DLE> 'X' in command mode"); 398 dev_err(cs->dev,
399 "received <DLE> 'X' in command mode\n");
413#endif 400#endif
414 inbuf->inputstate |= 401 inbuf->inputstate |=
415 INS_command | INS_DLE_command; 402 INS_command | INS_DLE_command;
@@ -417,7 +404,8 @@ void gigaset_m10x_input(struct inbuf_t *inbuf)
417 case '.': /*end of command*/ 404 case '.': /*end of command*/
418#ifdef CONFIG_GIGASET_DEBUG 405#ifdef CONFIG_GIGASET_DEBUG
419 if (!(inbuf->inputstate & INS_command)) 406 if (!(inbuf->inputstate & INS_command))
420 err("received <DLE> '.' in hdlc mode"); 407 dev_err(cs->dev,
408 "received <DLE> '.' in hdlc mode\n");
421#endif 409#endif
422 inbuf->inputstate &= cs->dle ? 410 inbuf->inputstate &= cs->dle ?
423 ~(INS_DLE_command|INS_command) 411 ~(INS_DLE_command|INS_command)
@@ -425,7 +413,9 @@ void gigaset_m10x_input(struct inbuf_t *inbuf)
425 break; 413 break;
426 //case DLE_FLAG: /*DLE_FLAG in data stream*/ /* schon oben behandelt! */ 414 //case DLE_FLAG: /*DLE_FLAG in data stream*/ /* schon oben behandelt! */
427 default: 415 default:
428 err("received 0x10 0x%02x!", (int) c); 416 dev_err(cs->dev,
417 "received 0x10 0x%02x!\n",
418 (int) c);
429 /* FIXME: reset driver?? */ 419 /* FIXME: reset driver?? */
430 } 420 }
431 } 421 }
@@ -444,7 +434,7 @@ nextbyte:
444 } 434 }
445 } 435 }
446 436
447 dbg(DEBUG_INTR, "setting head to %u", head); 437 gig_dbg(DEBUG_INTR, "setting head to %u", head);
448 atomic_set(&inbuf->head, head); 438 atomic_set(&inbuf->head, head);
449 } 439 }
450} 440}
@@ -479,14 +469,13 @@ static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int head, int tail)
479 stuf_cnt++; 469 stuf_cnt++;
480 fcs = crc_ccitt_byte(fcs, *cp++); 470 fcs = crc_ccitt_byte(fcs, *cp++);
481 } 471 }
482 fcs ^= 0xffff; /* complement */ 472 fcs ^= 0xffff; /* complement */
483 473
484 /* size of new buffer: original size + number of stuffing bytes 474 /* size of new buffer: original size + number of stuffing bytes
485 * + 2 bytes FCS + 2 stuffing bytes for FCS (if needed) + 2 flag bytes 475 * + 2 bytes FCS + 2 stuffing bytes for FCS (if needed) + 2 flag bytes
486 */ 476 */
487 hdlc_skb = dev_alloc_skb(skb->len + stuf_cnt + 6 + tail + head); 477 hdlc_skb = dev_alloc_skb(skb->len + stuf_cnt + 6 + tail + head);
488 if (!hdlc_skb) { 478 if (!hdlc_skb) {
489 err("unable to allocate memory for HDLC encoding!");
490 dev_kfree_skb(skb); 479 dev_kfree_skb(skb);
491 return NULL; 480 return NULL;
492 } 481 }
@@ -508,7 +497,7 @@ static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int head, int tail)
508 } 497 }
509 498
510 /* Finally add FCS (byte stuffed) and flag sequence */ 499 /* Finally add FCS (byte stuffed) and flag sequence */
511 c = (fcs & 0x00ff); /* least significant byte first */ 500 c = (fcs & 0x00ff); /* least significant byte first */
512 if (muststuff(c)) { 501 if (muststuff(c)) {
513 *(skb_put(hdlc_skb, 1)) = PPP_ESCAPE; 502 *(skb_put(hdlc_skb, 1)) = PPP_ESCAPE;
514 c ^= PPP_TRANS; 503 c ^= PPP_TRANS;
@@ -546,7 +535,6 @@ static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail)
546 /* worst case: every byte must be stuffed */ 535 /* worst case: every byte must be stuffed */
547 iraw_skb = dev_alloc_skb(2*skb->len + tail + head); 536 iraw_skb = dev_alloc_skb(2*skb->len + tail + head);
548 if (!iraw_skb) { 537 if (!iraw_skb) {
549 err("unable to allocate memory for HDLC encoding!");
550 dev_kfree_skb(skb); 538 dev_kfree_skb(skb);
551 return NULL; 539 return NULL;
552 } 540 }
@@ -577,21 +565,23 @@ static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail)
577 */ 565 */
578int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb) 566int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb)
579{ 567{
580 unsigned len; 568 unsigned len = skb->len;
581 569 unsigned long flags;
582 IFNULLRETVAL(bcs, -EFAULT);
583 IFNULLRETVAL(skb, -EFAULT);
584 len = skb->len;
585 570
586 if (bcs->proto2 == ISDN_PROTO_L2_HDLC) 571 if (bcs->proto2 == ISDN_PROTO_L2_HDLC)
587 skb = HDLC_Encode(skb, HW_HDR_LEN, 0); 572 skb = HDLC_Encode(skb, HW_HDR_LEN, 0);
588 else 573 else
589 skb = iraw_encode(skb, HW_HDR_LEN, 0); 574 skb = iraw_encode(skb, HW_HDR_LEN, 0);
590 if (!skb) 575 if (!skb) {
576 err("unable to allocate memory for encoding!\n");
591 return -ENOMEM; 577 return -ENOMEM;
578 }
592 579
593 skb_queue_tail(&bcs->squeue, skb); 580 skb_queue_tail(&bcs->squeue, skb);
594 tasklet_schedule(&bcs->cs->write_tasklet); 581 spin_lock_irqsave(&bcs->cs->lock, flags);
582 if (bcs->cs->connected)
583 tasklet_schedule(&bcs->cs->write_tasklet);
584 spin_unlock_irqrestore(&bcs->cs->lock, flags);
595 585
596 return len; /* ok so far */ 586 return len; /* ok so far */
597} 587}