root/drivers/staging/isdn/gigaset/isocdata.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gigaset_isowbuf_init
  2. isowbuf_freebytes
  3. isowbuf_startwrite
  4. isowbuf_donewrite
  5. isowbuf_putbits
  6. isowbuf_putflag
  7. gigaset_isowbuf_getbytes
  8. dump_bytes
  9. hdlc_bitstuff_byte
  10. hdlc_buildframe
  11. trans_buildframe
  12. gigaset_isoc_buildframe
  13. hdlc_putbyte
  14. hdlc_flush
  15. hdlc_done
  16. hdlc_frag
  17. hdlc_unpack
  18. trans_receive
  19. gigaset_isoc_receive
  20. cmd_loop
  21. gigaset_isoc_input
  22. gigaset_isoc_send_skb

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Common data handling layer for bas_gigaset
   4  *
   5  * Copyright (c) 2005 by Tilman Schmidt <tilman@imap.cc>,
   6  *                       Hansjoerg Lipp <hjlipp@web.de>.
   7  *
   8  * =====================================================================
   9  * =====================================================================
  10  */
  11 
  12 #include "gigaset.h"
  13 #include <linux/crc-ccitt.h>
  14 #include <linux/bitrev.h>
  15 
  16 /* access methods for isowbuf_t */
  17 /* ============================ */
  18 
  19 /* initialize buffer structure
  20  */
  21 void gigaset_isowbuf_init(struct isowbuf_t *iwb, unsigned char idle)
  22 {
  23         iwb->read = 0;
  24         iwb->nextread = 0;
  25         iwb->write = 0;
  26         atomic_set(&iwb->writesem, 1);
  27         iwb->wbits = 0;
  28         iwb->idle = idle;
  29         memset(iwb->data + BAS_OUTBUFSIZE, idle, BAS_OUTBUFPAD);
  30 }
  31 
  32 /* compute number of bytes which can be appended to buffer
  33  * so that there is still room to append a maximum frame of flags
  34  */
  35 static inline int isowbuf_freebytes(struct isowbuf_t *iwb)
  36 {
  37         int read, write, freebytes;
  38 
  39         read = iwb->read;
  40         write = iwb->write;
  41         freebytes = read - write;
  42         if (freebytes > 0) {
  43                 /* no wraparound: need padding space within regular area */
  44                 return freebytes - BAS_OUTBUFPAD;
  45         } else if (read < BAS_OUTBUFPAD) {
  46                 /* wraparound: can use space up to end of regular area */
  47                 return BAS_OUTBUFSIZE - write;
  48         } else {
  49                 /* following the wraparound yields more space */
  50                 return freebytes + BAS_OUTBUFSIZE - BAS_OUTBUFPAD;
  51         }
  52 }
  53 
  54 /* start writing
  55  * acquire the write semaphore
  56  * return 0 if acquired, <0 if busy
  57  */
  58 static inline int isowbuf_startwrite(struct isowbuf_t *iwb)
  59 {
  60         if (!atomic_dec_and_test(&iwb->writesem)) {
  61                 atomic_inc(&iwb->writesem);
  62                 gig_dbg(DEBUG_ISO, "%s: couldn't acquire iso write semaphore",
  63                         __func__);
  64                 return -EBUSY;
  65         }
  66         gig_dbg(DEBUG_ISO,
  67                 "%s: acquired iso write semaphore, data[write]=%02x, nbits=%d",
  68                 __func__, iwb->data[iwb->write], iwb->wbits);
  69         return 0;
  70 }
  71 
  72 /* finish writing
  73  * release the write semaphore
  74  * returns the current write position
  75  */
  76 static inline int isowbuf_donewrite(struct isowbuf_t *iwb)
  77 {
  78         int write = iwb->write;
  79         atomic_inc(&iwb->writesem);
  80         return write;
  81 }
  82 
  83 /* append bits to buffer without any checks
  84  * - data contains bits to append, starting at LSB
  85  * - nbits is number of bits to append (0..24)
  86  * must be called with the write semaphore held
  87  * If more than nbits bits are set in data, the extraneous bits are set in the
  88  * buffer too, but the write position is only advanced by nbits.
  89  */
  90 static inline void isowbuf_putbits(struct isowbuf_t *iwb, u32 data, int nbits)
  91 {
  92         int write = iwb->write;
  93         data <<= iwb->wbits;
  94         data |= iwb->data[write];
  95         nbits += iwb->wbits;
  96         while (nbits >= 8) {
  97                 iwb->data[write++] = data & 0xff;
  98                 write %= BAS_OUTBUFSIZE;
  99                 data >>= 8;
 100                 nbits -= 8;
 101         }
 102         iwb->wbits = nbits;
 103         iwb->data[write] = data & 0xff;
 104         iwb->write = write;
 105 }
 106 
 107 /* put final flag on HDLC bitstream
 108  * also sets the idle fill byte to the correspondingly shifted flag pattern
 109  * must be called with the write semaphore held
 110  */
 111 static inline void isowbuf_putflag(struct isowbuf_t *iwb)
 112 {
 113         int write;
 114 
 115         /* add two flags, thus reliably covering one byte */
 116         isowbuf_putbits(iwb, 0x7e7e, 8);
 117         /* recover the idle flag byte */
 118         write = iwb->write;
 119         iwb->idle = iwb->data[write];
 120         gig_dbg(DEBUG_ISO, "idle fill byte %02x", iwb->idle);
 121         /* mask extraneous bits in buffer */
 122         iwb->data[write] &= (1 << iwb->wbits) - 1;
 123 }
 124 
 125 /* retrieve a block of bytes for sending
 126  * The requested number of bytes is provided as a contiguous block.
 127  * If necessary, the frame is filled to the requested number of bytes
 128  * with the idle value.
 129  * returns offset to frame, < 0 on busy or error
 130  */
 131 int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size)
 132 {
 133         int read, write, limit, src, dst;
 134         unsigned char pbyte;
 135 
 136         read = iwb->nextread;
 137         write = iwb->write;
 138         if (likely(read == write)) {
 139                 /* return idle frame */
 140                 return read < BAS_OUTBUFPAD ?
 141                         BAS_OUTBUFSIZE : read - BAS_OUTBUFPAD;
 142         }
 143 
 144         limit = read + size;
 145         gig_dbg(DEBUG_STREAM, "%s: read=%d write=%d limit=%d",
 146                 __func__, read, write, limit);
 147 #ifdef CONFIG_GIGASET_DEBUG
 148         if (unlikely(size < 0 || size > BAS_OUTBUFPAD)) {
 149                 pr_err("invalid size %d\n", size);
 150                 return -EINVAL;
 151         }
 152 #endif
 153 
 154         if (read < write) {
 155                 /* no wraparound in valid data */
 156                 if (limit >= write) {
 157                         /* append idle frame */
 158                         if (isowbuf_startwrite(iwb) < 0)
 159                                 return -EBUSY;
 160                         /* write position could have changed */
 161                         write = iwb->write;
 162                         if (limit >= write) {
 163                                 pbyte = iwb->data[write]; /* save
 164                                                              partial byte */
 165                                 limit = write + BAS_OUTBUFPAD;
 166                                 gig_dbg(DEBUG_STREAM,
 167                                         "%s: filling %d->%d with %02x",
 168                                         __func__, write, limit, iwb->idle);
 169                                 if (write + BAS_OUTBUFPAD < BAS_OUTBUFSIZE)
 170                                         memset(iwb->data + write, iwb->idle,
 171                                                BAS_OUTBUFPAD);
 172                                 else {
 173                                         /* wraparound, fill entire pad area */
 174                                         memset(iwb->data + write, iwb->idle,
 175                                                BAS_OUTBUFSIZE + BAS_OUTBUFPAD
 176                                                - write);
 177                                         limit = 0;
 178                                 }
 179                                 gig_dbg(DEBUG_STREAM,
 180                                         "%s: restoring %02x at %d",
 181                                         __func__, pbyte, limit);
 182                                 iwb->data[limit] = pbyte; /* restore
 183                                                              partial byte */
 184                                 iwb->write = limit;
 185                         }
 186                         isowbuf_donewrite(iwb);
 187                 }
 188         } else {
 189                 /* valid data wraparound */
 190                 if (limit >= BAS_OUTBUFSIZE) {
 191                         /* copy wrapped part into pad area */
 192                         src = 0;
 193                         dst = BAS_OUTBUFSIZE;
 194                         while (dst < limit && src < write)
 195                                 iwb->data[dst++] = iwb->data[src++];
 196                         if (dst <= limit) {
 197                                 /* fill pad area with idle byte */
 198                                 memset(iwb->data + dst, iwb->idle,
 199                                        BAS_OUTBUFSIZE + BAS_OUTBUFPAD - dst);
 200                         }
 201                         limit = src;
 202                 }
 203         }
 204         iwb->nextread = limit;
 205         return read;
 206 }
 207 
 208 /* dump_bytes
 209  * write hex bytes to syslog for debugging
 210  */
 211 static inline void dump_bytes(enum debuglevel level, const char *tag,
 212                               unsigned char *bytes, int count)
 213 {
 214 #ifdef CONFIG_GIGASET_DEBUG
 215         unsigned char c;
 216         static char dbgline[3 * 32 + 1];
 217         int i = 0;
 218 
 219         if (!(gigaset_debuglevel & level))
 220                 return;
 221 
 222         while (count-- > 0) {
 223                 if (i > sizeof(dbgline) - 4) {
 224                         dbgline[i] = '\0';
 225                         gig_dbg(level, "%s:%s", tag, dbgline);
 226                         i = 0;
 227                 }
 228                 c = *bytes++;
 229                 dbgline[i] = (i && !(i % 12)) ? '-' : ' ';
 230                 i++;
 231                 dbgline[i++] = hex_asc_hi(c);
 232                 dbgline[i++] = hex_asc_lo(c);
 233         }
 234         dbgline[i] = '\0';
 235         gig_dbg(level, "%s:%s", tag, dbgline);
 236 #endif
 237 }
 238 
 239 /*============================================================================*/
 240 
 241 /* bytewise HDLC bitstuffing via table lookup
 242  * lookup table: 5 subtables for 0..4 preceding consecutive '1' bits
 243  * index: 256*(number of preceding '1' bits) + (next byte to stuff)
 244  * value: bit  9.. 0 = result bits
 245  *        bit 12..10 = number of trailing '1' bits in result
 246  *        bit 14..13 = number of bits added by stuffing
 247  */
 248 static const u16 stufftab[5 * 256] = {
 249 /* previous 1s = 0: */
 250         0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
 251         0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x201f,
 252         0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
 253         0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x203e, 0x205f,
 254         0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
 255         0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x209f,
 256         0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
 257         0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x207c, 0x207d, 0x20be, 0x20df,
 258         0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487, 0x0488, 0x0489, 0x048a, 0x048b, 0x048c, 0x048d, 0x048e, 0x048f,
 259         0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x0497, 0x0498, 0x0499, 0x049a, 0x049b, 0x049c, 0x049d, 0x049e, 0x251f,
 260         0x04a0, 0x04a1, 0x04a2, 0x04a3, 0x04a4, 0x04a5, 0x04a6, 0x04a7, 0x04a8, 0x04a9, 0x04aa, 0x04ab, 0x04ac, 0x04ad, 0x04ae, 0x04af,
 261         0x04b0, 0x04b1, 0x04b2, 0x04b3, 0x04b4, 0x04b5, 0x04b6, 0x04b7, 0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc, 0x04bd, 0x253e, 0x255f,
 262         0x08c0, 0x08c1, 0x08c2, 0x08c3, 0x08c4, 0x08c5, 0x08c6, 0x08c7, 0x08c8, 0x08c9, 0x08ca, 0x08cb, 0x08cc, 0x08cd, 0x08ce, 0x08cf,
 263         0x08d0, 0x08d1, 0x08d2, 0x08d3, 0x08d4, 0x08d5, 0x08d6, 0x08d7, 0x08d8, 0x08d9, 0x08da, 0x08db, 0x08dc, 0x08dd, 0x08de, 0x299f,
 264         0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x0ce7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x0cef,
 265         0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x10f7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x2ddf,
 266 
 267 /* previous 1s = 1: */
 268         0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x200f,
 269         0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x202f,
 270         0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x204f,
 271         0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x203e, 0x206f,
 272         0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x208f,
 273         0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x20af,
 274         0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x20cf,
 275         0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x207c, 0x207d, 0x20be, 0x20ef,
 276         0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487, 0x0488, 0x0489, 0x048a, 0x048b, 0x048c, 0x048d, 0x048e, 0x250f,
 277         0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x0497, 0x0498, 0x0499, 0x049a, 0x049b, 0x049c, 0x049d, 0x049e, 0x252f,
 278         0x04a0, 0x04a1, 0x04a2, 0x04a3, 0x04a4, 0x04a5, 0x04a6, 0x04a7, 0x04a8, 0x04a9, 0x04aa, 0x04ab, 0x04ac, 0x04ad, 0x04ae, 0x254f,
 279         0x04b0, 0x04b1, 0x04b2, 0x04b3, 0x04b4, 0x04b5, 0x04b6, 0x04b7, 0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc, 0x04bd, 0x253e, 0x256f,
 280         0x08c0, 0x08c1, 0x08c2, 0x08c3, 0x08c4, 0x08c5, 0x08c6, 0x08c7, 0x08c8, 0x08c9, 0x08ca, 0x08cb, 0x08cc, 0x08cd, 0x08ce, 0x298f,
 281         0x08d0, 0x08d1, 0x08d2, 0x08d3, 0x08d4, 0x08d5, 0x08d6, 0x08d7, 0x08d8, 0x08d9, 0x08da, 0x08db, 0x08dc, 0x08dd, 0x08de, 0x29af,
 282         0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x0ce7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x2dcf,
 283         0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x10f7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x31ef,
 284 
 285 /* previous 1s = 2: */
 286         0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x2007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x2017,
 287         0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x2027, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x2037,
 288         0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x2047, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x2057,
 289         0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x2067, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x203e, 0x2077,
 290         0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x2087, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x2097,
 291         0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x20a7, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x20b7,
 292         0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x20c7, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x20d7,
 293         0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x20e7, 0x0078, 0x0079, 0x007a, 0x007b, 0x207c, 0x207d, 0x20be, 0x20f7,
 294         0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x2507, 0x0488, 0x0489, 0x048a, 0x048b, 0x048c, 0x048d, 0x048e, 0x2517,
 295         0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x2527, 0x0498, 0x0499, 0x049a, 0x049b, 0x049c, 0x049d, 0x049e, 0x2537,
 296         0x04a0, 0x04a1, 0x04a2, 0x04a3, 0x04a4, 0x04a5, 0x04a6, 0x2547, 0x04a8, 0x04a9, 0x04aa, 0x04ab, 0x04ac, 0x04ad, 0x04ae, 0x2557,
 297         0x04b0, 0x04b1, 0x04b2, 0x04b3, 0x04b4, 0x04b5, 0x04b6, 0x2567, 0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc, 0x04bd, 0x253e, 0x2577,
 298         0x08c0, 0x08c1, 0x08c2, 0x08c3, 0x08c4, 0x08c5, 0x08c6, 0x2987, 0x08c8, 0x08c9, 0x08ca, 0x08cb, 0x08cc, 0x08cd, 0x08ce, 0x2997,
 299         0x08d0, 0x08d1, 0x08d2, 0x08d3, 0x08d4, 0x08d5, 0x08d6, 0x29a7, 0x08d8, 0x08d9, 0x08da, 0x08db, 0x08dc, 0x08dd, 0x08de, 0x29b7,
 300         0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x2dc7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x2dd7,
 301         0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x31e7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x41f7,
 302 
 303 /* previous 1s = 3: */
 304         0x0000, 0x0001, 0x0002, 0x2003, 0x0004, 0x0005, 0x0006, 0x200b, 0x0008, 0x0009, 0x000a, 0x2013, 0x000c, 0x000d, 0x000e, 0x201b,
 305         0x0010, 0x0011, 0x0012, 0x2023, 0x0014, 0x0015, 0x0016, 0x202b, 0x0018, 0x0019, 0x001a, 0x2033, 0x001c, 0x001d, 0x001e, 0x203b,
 306         0x0020, 0x0021, 0x0022, 0x2043, 0x0024, 0x0025, 0x0026, 0x204b, 0x0028, 0x0029, 0x002a, 0x2053, 0x002c, 0x002d, 0x002e, 0x205b,
 307         0x0030, 0x0031, 0x0032, 0x2063, 0x0034, 0x0035, 0x0036, 0x206b, 0x0038, 0x0039, 0x003a, 0x2073, 0x003c, 0x003d, 0x203e, 0x207b,
 308         0x0040, 0x0041, 0x0042, 0x2083, 0x0044, 0x0045, 0x0046, 0x208b, 0x0048, 0x0049, 0x004a, 0x2093, 0x004c, 0x004d, 0x004e, 0x209b,
 309         0x0050, 0x0051, 0x0052, 0x20a3, 0x0054, 0x0055, 0x0056, 0x20ab, 0x0058, 0x0059, 0x005a, 0x20b3, 0x005c, 0x005d, 0x005e, 0x20bb,
 310         0x0060, 0x0061, 0x0062, 0x20c3, 0x0064, 0x0065, 0x0066, 0x20cb, 0x0068, 0x0069, 0x006a, 0x20d3, 0x006c, 0x006d, 0x006e, 0x20db,
 311         0x0070, 0x0071, 0x0072, 0x20e3, 0x0074, 0x0075, 0x0076, 0x20eb, 0x0078, 0x0079, 0x007a, 0x20f3, 0x207c, 0x207d, 0x20be, 0x40fb,
 312         0x0480, 0x0481, 0x0482, 0x2503, 0x0484, 0x0485, 0x0486, 0x250b, 0x0488, 0x0489, 0x048a, 0x2513, 0x048c, 0x048d, 0x048e, 0x251b,
 313         0x0490, 0x0491, 0x0492, 0x2523, 0x0494, 0x0495, 0x0496, 0x252b, 0x0498, 0x0499, 0x049a, 0x2533, 0x049c, 0x049d, 0x049e, 0x253b,
 314         0x04a0, 0x04a1, 0x04a2, 0x2543, 0x04a4, 0x04a5, 0x04a6, 0x254b, 0x04a8, 0x04a9, 0x04aa, 0x2553, 0x04ac, 0x04ad, 0x04ae, 0x255b,
 315         0x04b0, 0x04b1, 0x04b2, 0x2563, 0x04b4, 0x04b5, 0x04b6, 0x256b, 0x04b8, 0x04b9, 0x04ba, 0x2573, 0x04bc, 0x04bd, 0x253e, 0x257b,
 316         0x08c0, 0x08c1, 0x08c2, 0x2983, 0x08c4, 0x08c5, 0x08c6, 0x298b, 0x08c8, 0x08c9, 0x08ca, 0x2993, 0x08cc, 0x08cd, 0x08ce, 0x299b,
 317         0x08d0, 0x08d1, 0x08d2, 0x29a3, 0x08d4, 0x08d5, 0x08d6, 0x29ab, 0x08d8, 0x08d9, 0x08da, 0x29b3, 0x08dc, 0x08dd, 0x08de, 0x29bb,
 318         0x0ce0, 0x0ce1, 0x0ce2, 0x2dc3, 0x0ce4, 0x0ce5, 0x0ce6, 0x2dcb, 0x0ce8, 0x0ce9, 0x0cea, 0x2dd3, 0x0cec, 0x0ced, 0x0cee, 0x2ddb,
 319         0x10f0, 0x10f1, 0x10f2, 0x31e3, 0x10f4, 0x10f5, 0x10f6, 0x31eb, 0x20f8, 0x20f9, 0x20fa, 0x41f3, 0x257c, 0x257d, 0x29be, 0x46fb,
 320 
 321 /* previous 1s = 4: */
 322         0x0000, 0x2001, 0x0002, 0x2005, 0x0004, 0x2009, 0x0006, 0x200d, 0x0008, 0x2011, 0x000a, 0x2015, 0x000c, 0x2019, 0x000e, 0x201d,
 323         0x0010, 0x2021, 0x0012, 0x2025, 0x0014, 0x2029, 0x0016, 0x202d, 0x0018, 0x2031, 0x001a, 0x2035, 0x001c, 0x2039, 0x001e, 0x203d,
 324         0x0020, 0x2041, 0x0022, 0x2045, 0x0024, 0x2049, 0x0026, 0x204d, 0x0028, 0x2051, 0x002a, 0x2055, 0x002c, 0x2059, 0x002e, 0x205d,
 325         0x0030, 0x2061, 0x0032, 0x2065, 0x0034, 0x2069, 0x0036, 0x206d, 0x0038, 0x2071, 0x003a, 0x2075, 0x003c, 0x2079, 0x203e, 0x407d,
 326         0x0040, 0x2081, 0x0042, 0x2085, 0x0044, 0x2089, 0x0046, 0x208d, 0x0048, 0x2091, 0x004a, 0x2095, 0x004c, 0x2099, 0x004e, 0x209d,
 327         0x0050, 0x20a1, 0x0052, 0x20a5, 0x0054, 0x20a9, 0x0056, 0x20ad, 0x0058, 0x20b1, 0x005a, 0x20b5, 0x005c, 0x20b9, 0x005e, 0x20bd,
 328         0x0060, 0x20c1, 0x0062, 0x20c5, 0x0064, 0x20c9, 0x0066, 0x20cd, 0x0068, 0x20d1, 0x006a, 0x20d5, 0x006c, 0x20d9, 0x006e, 0x20dd,
 329         0x0070, 0x20e1, 0x0072, 0x20e5, 0x0074, 0x20e9, 0x0076, 0x20ed, 0x0078, 0x20f1, 0x007a, 0x20f5, 0x207c, 0x40f9, 0x20be, 0x417d,
 330         0x0480, 0x2501, 0x0482, 0x2505, 0x0484, 0x2509, 0x0486, 0x250d, 0x0488, 0x2511, 0x048a, 0x2515, 0x048c, 0x2519, 0x048e, 0x251d,
 331         0x0490, 0x2521, 0x0492, 0x2525, 0x0494, 0x2529, 0x0496, 0x252d, 0x0498, 0x2531, 0x049a, 0x2535, 0x049c, 0x2539, 0x049e, 0x253d,
 332         0x04a0, 0x2541, 0x04a2, 0x2545, 0x04a4, 0x2549, 0x04a6, 0x254d, 0x04a8, 0x2551, 0x04aa, 0x2555, 0x04ac, 0x2559, 0x04ae, 0x255d,
 333         0x04b0, 0x2561, 0x04b2, 0x2565, 0x04b4, 0x2569, 0x04b6, 0x256d, 0x04b8, 0x2571, 0x04ba, 0x2575, 0x04bc, 0x2579, 0x253e, 0x467d,
 334         0x08c0, 0x2981, 0x08c2, 0x2985, 0x08c4, 0x2989, 0x08c6, 0x298d, 0x08c8, 0x2991, 0x08ca, 0x2995, 0x08cc, 0x2999, 0x08ce, 0x299d,
 335         0x08d0, 0x29a1, 0x08d2, 0x29a5, 0x08d4, 0x29a9, 0x08d6, 0x29ad, 0x08d8, 0x29b1, 0x08da, 0x29b5, 0x08dc, 0x29b9, 0x08de, 0x29bd,
 336         0x0ce0, 0x2dc1, 0x0ce2, 0x2dc5, 0x0ce4, 0x2dc9, 0x0ce6, 0x2dcd, 0x0ce8, 0x2dd1, 0x0cea, 0x2dd5, 0x0cec, 0x2dd9, 0x0cee, 0x2ddd,
 337         0x10f0, 0x31e1, 0x10f2, 0x31e5, 0x10f4, 0x31e9, 0x10f6, 0x31ed, 0x20f8, 0x41f1, 0x20fa, 0x41f5, 0x257c, 0x46f9, 0x29be, 0x4b7d
 338 };
 339 
 340 /* hdlc_bitstuff_byte
 341  * perform HDLC bitstuffing for one input byte (8 bits, LSB first)
 342  * parameters:
 343  *      cin     input byte
 344  *      ones    number of trailing '1' bits in result before this step
 345  *      iwb     pointer to output buffer structure
 346  *              (write semaphore must be held)
 347  * return value:
 348  *      number of trailing '1' bits in result after this step
 349  */
 350 
 351 static inline int hdlc_bitstuff_byte(struct isowbuf_t *iwb, unsigned char cin,
 352                                      int ones)
 353 {
 354         u16 stuff;
 355         int shiftinc, newones;
 356 
 357         /* get stuffing information for input byte
 358          * value: bit  9.. 0 = result bits
 359          *        bit 12..10 = number of trailing '1' bits in result
 360          *        bit 14..13 = number of bits added by stuffing
 361          */
 362         stuff = stufftab[256 * ones + cin];
 363         shiftinc = (stuff >> 13) & 3;
 364         newones = (stuff >> 10) & 7;
 365         stuff &= 0x3ff;
 366 
 367         /* append stuffed byte to output stream */
 368         isowbuf_putbits(iwb, stuff, 8 + shiftinc);
 369         return newones;
 370 }
 371 
 372 /* hdlc_buildframe
 373  * Perform HDLC framing with bitstuffing on a byte buffer
 374  * The input buffer is regarded as a sequence of bits, starting with the least
 375  * significant bit of the first byte and ending with the most significant bit
 376  * of the last byte. A 16 bit FCS is appended as defined by RFC 1662.
 377  * Whenever five consecutive '1' bits appear in the resulting bit sequence, a
 378  * '0' bit is inserted after them.
 379  * The resulting bit string and a closing flag pattern (PPP_FLAG, '01111110')
 380  * are appended to the output buffer starting at the given bit position, which
 381  * is assumed to already contain a leading flag.
 382  * The output buffer must have sufficient length; count + count/5 + 6 bytes
 383  * starting at *out are safe and are verified to be present.
 384  * parameters:
 385  *      in      input buffer
 386  *      count   number of bytes in input buffer
 387  *      iwb     pointer to output buffer structure
 388  *              (write semaphore must be held)
 389  * return value:
 390  *      position of end of packet in output buffer on success,
 391  *      -EAGAIN if write semaphore busy or buffer full
 392  */
 393 
 394 static inline int hdlc_buildframe(struct isowbuf_t *iwb,
 395                                   unsigned char *in, int count)
 396 {
 397         int ones;
 398         u16 fcs;
 399         int end;
 400         unsigned char c;
 401 
 402         if (isowbuf_freebytes(iwb) < count + count / 5 + 6 ||
 403             isowbuf_startwrite(iwb) < 0) {
 404                 gig_dbg(DEBUG_ISO, "%s: %d bytes free -> -EAGAIN",
 405                         __func__, isowbuf_freebytes(iwb));
 406                 return -EAGAIN;
 407         }
 408 
 409         dump_bytes(DEBUG_STREAM_DUMP, "snd data", in, count);
 410 
 411         /* bitstuff and checksum input data */
 412         fcs = PPP_INITFCS;
 413         ones = 0;
 414         while (count-- > 0) {
 415                 c = *in++;
 416                 ones = hdlc_bitstuff_byte(iwb, c, ones);
 417                 fcs = crc_ccitt_byte(fcs, c);
 418         }
 419 
 420         /* bitstuff and append FCS
 421          * (complemented, least significant byte first) */
 422         fcs ^= 0xffff;
 423         ones = hdlc_bitstuff_byte(iwb, fcs & 0x00ff, ones);
 424         ones = hdlc_bitstuff_byte(iwb, (fcs >> 8) & 0x00ff, ones);
 425 
 426         /* put closing flag and repeat byte for flag idle */
 427         isowbuf_putflag(iwb);
 428         end = isowbuf_donewrite(iwb);
 429         return end;
 430 }
 431 
 432 /* trans_buildframe
 433  * Append a block of 'transparent' data to the output buffer,
 434  * inverting the bytes.
 435  * The output buffer must have sufficient length; count bytes
 436  * starting at *out are safe and are verified to be present.
 437  * parameters:
 438  *      in      input buffer
 439  *      count   number of bytes in input buffer
 440  *      iwb     pointer to output buffer structure
 441  *              (write semaphore must be held)
 442  * return value:
 443  *      position of end of packet in output buffer on success,
 444  *      -EAGAIN if write semaphore busy or buffer full
 445  */
 446 
 447 static inline int trans_buildframe(struct isowbuf_t *iwb,
 448                                    unsigned char *in, int count)
 449 {
 450         int write;
 451         unsigned char c;
 452 
 453         if (unlikely(count <= 0))
 454                 return iwb->write;
 455 
 456         if (isowbuf_freebytes(iwb) < count ||
 457             isowbuf_startwrite(iwb) < 0) {
 458                 gig_dbg(DEBUG_ISO, "can't put %d bytes", count);
 459                 return -EAGAIN;
 460         }
 461 
 462         gig_dbg(DEBUG_STREAM, "put %d bytes", count);
 463         dump_bytes(DEBUG_STREAM_DUMP, "snd data", in, count);
 464 
 465         write = iwb->write;
 466         do {
 467                 c = bitrev8(*in++);
 468                 iwb->data[write++] = c;
 469                 write %= BAS_OUTBUFSIZE;
 470         } while (--count > 0);
 471         iwb->write = write;
 472         iwb->idle = c;
 473 
 474         return isowbuf_donewrite(iwb);
 475 }
 476 
 477 int gigaset_isoc_buildframe(struct bc_state *bcs, unsigned char *in, int len)
 478 {
 479         int result;
 480 
 481         switch (bcs->proto2) {
 482         case L2_HDLC:
 483                 result = hdlc_buildframe(bcs->hw.bas->isooutbuf, in, len);
 484                 gig_dbg(DEBUG_ISO, "%s: %d bytes HDLC -> %d",
 485                         __func__, len, result);
 486                 break;
 487         default:                        /* assume transparent */
 488                 result = trans_buildframe(bcs->hw.bas->isooutbuf, in, len);
 489                 gig_dbg(DEBUG_ISO, "%s: %d bytes trans -> %d",
 490                         __func__, len, result);
 491         }
 492         return result;
 493 }
 494 
 495 /* hdlc_putbyte
 496  * append byte c to current skb of B channel structure *bcs, updating fcs
 497  */
 498 static inline void hdlc_putbyte(unsigned char c, struct bc_state *bcs)
 499 {
 500         bcs->rx_fcs = crc_ccitt_byte(bcs->rx_fcs, c);
 501         if (bcs->rx_skb == NULL)
 502                 /* skipping */
 503                 return;
 504         if (bcs->rx_skb->len >= bcs->rx_bufsize) {
 505                 dev_warn(bcs->cs->dev, "received oversized packet discarded\n");
 506                 bcs->hw.bas->giants++;
 507                 dev_kfree_skb_any(bcs->rx_skb);
 508                 bcs->rx_skb = NULL;
 509                 return;
 510         }
 511         __skb_put_u8(bcs->rx_skb, c);
 512 }
 513 
 514 /* hdlc_flush
 515  * drop partial HDLC data packet
 516  */
 517 static inline void hdlc_flush(struct bc_state *bcs)
 518 {
 519         /* clear skb or allocate new if not skipping */
 520         if (bcs->rx_skb != NULL)
 521                 skb_trim(bcs->rx_skb, 0);
 522         else
 523                 gigaset_new_rx_skb(bcs);
 524 
 525         /* reset packet state */
 526         bcs->rx_fcs = PPP_INITFCS;
 527 }
 528 
 529 /* hdlc_done
 530  * process completed HDLC data packet
 531  */
 532 static inline void hdlc_done(struct bc_state *bcs)
 533 {
 534         struct cardstate *cs = bcs->cs;
 535         struct sk_buff *procskb;
 536         unsigned int len;
 537 
 538         if (unlikely(bcs->ignore)) {
 539                 bcs->ignore--;
 540                 hdlc_flush(bcs);
 541                 return;
 542         }
 543         procskb = bcs->rx_skb;
 544         if (procskb == NULL) {
 545                 /* previous error */
 546                 gig_dbg(DEBUG_ISO, "%s: skb=NULL", __func__);
 547                 gigaset_isdn_rcv_err(bcs);
 548         } else if (procskb->len < 2) {
 549                 dev_notice(cs->dev, "received short frame (%d octets)\n",
 550                            procskb->len);
 551                 bcs->hw.bas->runts++;
 552                 dev_kfree_skb_any(procskb);
 553                 gigaset_isdn_rcv_err(bcs);
 554         } else if (bcs->rx_fcs != PPP_GOODFCS) {
 555                 dev_notice(cs->dev, "frame check error\n");
 556                 bcs->hw.bas->fcserrs++;
 557                 dev_kfree_skb_any(procskb);
 558                 gigaset_isdn_rcv_err(bcs);
 559         } else {
 560                 len = procskb->len;
 561                 __skb_trim(procskb, len -= 2);  /* subtract FCS */
 562                 gig_dbg(DEBUG_ISO, "%s: good frame (%d octets)", __func__, len);
 563                 dump_bytes(DEBUG_STREAM_DUMP,
 564                            "rcv data", procskb->data, len);
 565                 bcs->hw.bas->goodbytes += len;
 566                 gigaset_skb_rcvd(bcs, procskb);
 567         }
 568         gigaset_new_rx_skb(bcs);
 569         bcs->rx_fcs = PPP_INITFCS;
 570 }
 571 
 572 /* hdlc_frag
 573  * drop HDLC data packet with non-integral last byte
 574  */
 575 static inline void hdlc_frag(struct bc_state *bcs, unsigned inbits)
 576 {
 577         if (unlikely(bcs->ignore)) {
 578                 bcs->ignore--;
 579                 hdlc_flush(bcs);
 580                 return;
 581         }
 582 
 583         dev_notice(bcs->cs->dev, "received partial byte (%d bits)\n", inbits);
 584         bcs->hw.bas->alignerrs++;
 585         gigaset_isdn_rcv_err(bcs);
 586         __skb_trim(bcs->rx_skb, 0);
 587         bcs->rx_fcs = PPP_INITFCS;
 588 }
 589 
 590 /* bit counts lookup table for HDLC bit unstuffing
 591  * index: input byte
 592  * value: bit 0..3 = number of consecutive '1' bits starting from LSB
 593  *        bit 4..6 = number of consecutive '1' bits starting from MSB
 594  *                   (replacing 8 by 7 to make it fit; the algorithm won't care)
 595  *        bit 7 set if there are 5 or more "interior" consecutive '1' bits
 596  */
 597 static const unsigned char bitcounts[256] = {
 598         0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
 599         0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05,
 600         0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
 601         0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x80, 0x06,
 602         0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
 603         0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05,
 604         0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
 605         0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x80, 0x81, 0x80, 0x07,
 606         0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x14,
 607         0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x15,
 608         0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x14,
 609         0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x90, 0x16,
 610         0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x23, 0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x24,
 611         0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x23, 0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x25,
 612         0x30, 0x31, 0x30, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x31, 0x30, 0x32, 0x30, 0x31, 0x30, 0x34,
 613         0x40, 0x41, 0x40, 0x42, 0x40, 0x41, 0x40, 0x43, 0x50, 0x51, 0x50, 0x52, 0x60, 0x61, 0x70, 0x78
 614 };
 615 
 616 /* hdlc_unpack
 617  * perform HDLC frame processing (bit unstuffing, flag detection, FCS
 618  * calculation) on a sequence of received data bytes (8 bits each, LSB first)
 619  * pass on successfully received, complete frames as SKBs via gigaset_skb_rcvd
 620  * notify of errors via gigaset_isdn_rcv_err
 621  * tally frames, errors etc. in BC structure counters
 622  * parameters:
 623  *      src     received data
 624  *      count   number of received bytes
 625  *      bcs     receiving B channel structure
 626  */
 627 static inline void hdlc_unpack(unsigned char *src, unsigned count,
 628                                struct bc_state *bcs)
 629 {
 630         struct bas_bc_state *ubc = bcs->hw.bas;
 631         int inputstate;
 632         unsigned seqlen, inbyte, inbits;
 633 
 634         /* load previous state:
 635          * inputstate = set of flag bits:
 636          * - INS_flag_hunt: no complete opening flag received since connection
 637          *                  setup or last abort
 638          * - INS_have_data: at least one complete data byte received since last
 639          *                  flag
 640          * seqlen = number of consecutive '1' bits in last 7 input stream bits
 641          *          (0..7)
 642          * inbyte = accumulated partial data byte (if !INS_flag_hunt)
 643          * inbits = number of valid bits in inbyte, starting at LSB (0..6)
 644          */
 645         inputstate = bcs->inputstate;
 646         seqlen = ubc->seqlen;
 647         inbyte = ubc->inbyte;
 648         inbits = ubc->inbits;
 649 
 650         /* bit unstuffing a byte a time
 651          * Take your time to understand this; it's straightforward but tedious.
 652          * The "bitcounts" lookup table is used to speed up the counting of
 653          * leading and trailing '1' bits.
 654          */
 655         while (count--) {
 656                 unsigned char c = *src++;
 657                 unsigned char tabentry = bitcounts[c];
 658                 unsigned lead1 = tabentry & 0x0f;
 659                 unsigned trail1 = (tabentry >> 4) & 0x0f;
 660 
 661                 seqlen += lead1;
 662 
 663                 if (unlikely(inputstate & INS_flag_hunt)) {
 664                         if (c == PPP_FLAG) {
 665                                 /* flag-in-one */
 666                                 inputstate &= ~(INS_flag_hunt | INS_have_data);
 667                                 inbyte = 0;
 668                                 inbits = 0;
 669                         } else if (seqlen == 6 && trail1 != 7) {
 670                                 /* flag completed & not followed by abort */
 671                                 inputstate &= ~(INS_flag_hunt | INS_have_data);
 672                                 inbyte = c >> (lead1 + 1);
 673                                 inbits = 7 - lead1;
 674                                 if (trail1 >= 8) {
 675                                         /* interior stuffing:
 676                                          * omitting the MSB handles most cases,
 677                                          * correct the incorrectly handled
 678                                          * cases individually */
 679                                         inbits--;
 680                                         switch (c) {
 681                                         case 0xbe:
 682                                                 inbyte = 0x3f;
 683                                                 break;
 684                                         }
 685                                 }
 686                         }
 687                         /* else: continue flag-hunting */
 688                 } else if (likely(seqlen < 5 && trail1 < 7)) {
 689                         /* streamlined case: 8 data bits, no stuffing */
 690                         inbyte |= c << inbits;
 691                         hdlc_putbyte(inbyte & 0xff, bcs);
 692                         inputstate |= INS_have_data;
 693                         inbyte >>= 8;
 694                         /* inbits unchanged */
 695                 } else if (likely(seqlen == 6 && inbits == 7 - lead1 &&
 696                                   trail1 + 1 == inbits &&
 697                                   !(inputstate & INS_have_data))) {
 698                         /* streamlined case: flag idle - state unchanged */
 699                 } else if (unlikely(seqlen > 6)) {
 700                         /* abort sequence */
 701                         ubc->aborts++;
 702                         hdlc_flush(bcs);
 703                         inputstate |= INS_flag_hunt;
 704                 } else if (seqlen == 6) {
 705                         /* closing flag, including (6 - lead1) '1's
 706                          * and one '0' from inbits */
 707                         if (inbits > 7 - lead1) {
 708                                 hdlc_frag(bcs, inbits + lead1 - 7);
 709                                 inputstate &= ~INS_have_data;
 710                         } else {
 711                                 if (inbits < 7 - lead1)
 712                                         ubc->stolen0s++;
 713                                 if (inputstate & INS_have_data) {
 714                                         hdlc_done(bcs);
 715                                         inputstate &= ~INS_have_data;
 716                                 }
 717                         }
 718 
 719                         if (c == PPP_FLAG) {
 720                                 /* complete flag, LSB overlaps preceding flag */
 721                                 ubc->shared0s++;
 722                                 inbits = 0;
 723                                 inbyte = 0;
 724                         } else if (trail1 != 7) {
 725                                 /* remaining bits */
 726                                 inbyte = c >> (lead1 + 1);
 727                                 inbits = 7 - lead1;
 728                                 if (trail1 >= 8) {
 729                                         /* interior stuffing:
 730                                          * omitting the MSB handles most cases,
 731                                          * correct the incorrectly handled
 732                                          * cases individually */
 733                                         inbits--;
 734                                         switch (c) {
 735                                         case 0xbe:
 736                                                 inbyte = 0x3f;
 737                                                 break;
 738                                         }
 739                                 }
 740                         } else {
 741                                 /* abort sequence follows,
 742                                  * skb already empty anyway */
 743                                 ubc->aborts++;
 744                                 inputstate |= INS_flag_hunt;
 745                         }
 746                 } else { /* (seqlen < 6) && (seqlen == 5 || trail1 >= 7) */
 747 
 748                         if (c == PPP_FLAG) {
 749                                 /* complete flag */
 750                                 if (seqlen == 5)
 751                                         ubc->stolen0s++;
 752                                 if (inbits) {
 753                                         hdlc_frag(bcs, inbits);
 754                                         inbits = 0;
 755                                         inbyte = 0;
 756                                 } else if (inputstate & INS_have_data)
 757                                         hdlc_done(bcs);
 758                                 inputstate &= ~INS_have_data;
 759                         } else if (trail1 == 7) {
 760                                 /* abort sequence */
 761                                 ubc->aborts++;
 762                                 hdlc_flush(bcs);
 763                                 inputstate |= INS_flag_hunt;
 764                         } else {
 765                                 /* stuffed data */
 766                                 if (trail1 < 7) { /* => seqlen == 5 */
 767                                         /* stuff bit at position lead1,
 768                                          * no interior stuffing */
 769                                         unsigned char mask = (1 << lead1) - 1;
 770                                         c = (c & mask) | ((c & ~mask) >> 1);
 771                                         inbyte |= c << inbits;
 772                                         inbits += 7;
 773                                 } else if (seqlen < 5) { /* trail1 >= 8 */
 774                                         /* interior stuffing:
 775                                          * omitting the MSB handles most cases,
 776                                          * correct the incorrectly handled
 777                                          * cases individually */
 778                                         switch (c) {
 779                                         case 0xbe:
 780                                                 c = 0x7e;
 781                                                 break;
 782                                         }
 783                                         inbyte |= c << inbits;
 784                                         inbits += 7;
 785                                 } else { /* seqlen == 5 && trail1 >= 8 */
 786 
 787                                         /* stuff bit at lead1 *and* interior
 788                                          * stuffing -- unstuff individually */
 789                                         switch (c) {
 790                                         case 0x7d:
 791                                                 c = 0x3f;
 792                                                 break;
 793                                         case 0xbe:
 794                                                 c = 0x3f;
 795                                                 break;
 796                                         case 0x3e:
 797                                                 c = 0x1f;
 798                                                 break;
 799                                         case 0x7c:
 800                                                 c = 0x3e;
 801                                                 break;
 802                                         }
 803                                         inbyte |= c << inbits;
 804                                         inbits += 6;
 805                                 }
 806                                 if (inbits >= 8) {
 807                                         inbits -= 8;
 808                                         hdlc_putbyte(inbyte & 0xff, bcs);
 809                                         inputstate |= INS_have_data;
 810                                         inbyte >>= 8;
 811                                 }
 812                         }
 813                 }
 814                 seqlen = trail1 & 7;
 815         }
 816 
 817         /* save new state */
 818         bcs->inputstate = inputstate;
 819         ubc->seqlen = seqlen;
 820         ubc->inbyte = inbyte;
 821         ubc->inbits = inbits;
 822 }
 823 
 824 /* trans_receive
 825  * pass on received USB frame transparently as SKB via gigaset_skb_rcvd
 826  * invert bytes
 827  * tally frames, errors etc. in BC structure counters
 828  * parameters:
 829  *      src     received data
 830  *      count   number of received bytes
 831  *      bcs     receiving B channel structure
 832  */
 833 static inline void trans_receive(unsigned char *src, unsigned count,
 834                                  struct bc_state *bcs)
 835 {
 836         struct sk_buff *skb;
 837         int dobytes;
 838         unsigned char *dst;
 839 
 840         if (unlikely(bcs->ignore)) {
 841                 bcs->ignore--;
 842                 return;
 843         }
 844         skb = bcs->rx_skb;
 845         if (skb == NULL) {
 846                 skb = gigaset_new_rx_skb(bcs);
 847                 if (skb == NULL)
 848                         return;
 849         }
 850         dobytes = bcs->rx_bufsize - skb->len;
 851         while (count > 0) {
 852                 dst = skb_put(skb, count < dobytes ? count : dobytes);
 853                 while (count > 0 && dobytes > 0) {
 854                         *dst++ = bitrev8(*src++);
 855                         count--;
 856                         dobytes--;
 857                 }
 858                 if (dobytes == 0) {
 859                         dump_bytes(DEBUG_STREAM_DUMP,
 860                                    "rcv data", skb->data, skb->len);
 861                         bcs->hw.bas->goodbytes += skb->len;
 862                         gigaset_skb_rcvd(bcs, skb);
 863                         skb = gigaset_new_rx_skb(bcs);
 864                         if (skb == NULL)
 865                                 return;
 866                         dobytes = bcs->rx_bufsize;
 867                 }
 868         }
 869 }
 870 
 871 void gigaset_isoc_receive(unsigned char *src, unsigned count,
 872                           struct bc_state *bcs)
 873 {
 874         switch (bcs->proto2) {
 875         case L2_HDLC:
 876                 hdlc_unpack(src, count, bcs);
 877                 break;
 878         default:                /* assume transparent */
 879                 trans_receive(src, count, bcs);
 880         }
 881 }
 882 
 883 /* == data input =========================================================== */
 884 
 885 /* process a block of received bytes in command mode (mstate != MS_LOCKED)
 886  * Append received bytes to the command response buffer and forward them
 887  * line by line to the response handler.
 888  * Note: Received lines may be terminated by CR, LF, or CR LF, which will be
 889  * removed before passing the line to the response handler.
 890  */
 891 static void cmd_loop(unsigned char *src, int numbytes, struct inbuf_t *inbuf)
 892 {
 893         struct cardstate *cs = inbuf->cs;
 894         unsigned cbytes      = cs->cbytes;
 895         unsigned char c;
 896 
 897         while (numbytes--) {
 898                 c = *src++;
 899                 switch (c) {
 900                 case '\n':
 901                         if (cbytes == 0 && cs->respdata[0] == '\r') {
 902                                 /* collapse LF with preceding CR */
 903                                 cs->respdata[0] = 0;
 904                                 break;
 905                         }
 906                         /* fall through */
 907                 case '\r':
 908                         /* end of message line, pass to response handler */
 909                         if (cbytes >= MAX_RESP_SIZE) {
 910                                 dev_warn(cs->dev, "response too large (%d)\n",
 911                                          cbytes);
 912                                 cbytes = MAX_RESP_SIZE;
 913                         }
 914                         cs->cbytes = cbytes;
 915                         gigaset_dbg_buffer(DEBUG_TRANSCMD, "received response",
 916                                            cbytes, cs->respdata);
 917                         gigaset_handle_modem_response(cs);
 918                         cbytes = 0;
 919 
 920                         /* store EOL byte for CRLF collapsing */
 921                         cs->respdata[0] = c;
 922                         break;
 923                 default:
 924                         /* append to line buffer if possible */
 925                         if (cbytes < MAX_RESP_SIZE)
 926                                 cs->respdata[cbytes] = c;
 927                         cbytes++;
 928                 }
 929         }
 930 
 931         /* save state */
 932         cs->cbytes = cbytes;
 933 }
 934 
 935 
 936 /* process a block of data received through the control channel
 937  */
 938 void gigaset_isoc_input(struct inbuf_t *inbuf)
 939 {
 940         struct cardstate *cs = inbuf->cs;
 941         unsigned tail, head, numbytes;
 942         unsigned char *src;
 943 
 944         head = inbuf->head;
 945         while (head != (tail = inbuf->tail)) {
 946                 gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail);
 947                 if (head > tail)
 948                         tail = RBUFSIZE;
 949                 src = inbuf->data + head;
 950                 numbytes = tail - head;
 951                 gig_dbg(DEBUG_INTR, "processing %u bytes", numbytes);
 952 
 953                 if (cs->mstate == MS_LOCKED) {
 954                         gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response",
 955                                            numbytes, src);
 956                         gigaset_if_receive(inbuf->cs, src, numbytes);
 957                 } else {
 958                         cmd_loop(src, numbytes, inbuf);
 959                 }
 960 
 961                 head += numbytes;
 962                 if (head == RBUFSIZE)
 963                         head = 0;
 964                 gig_dbg(DEBUG_INTR, "setting head to %u", head);
 965                 inbuf->head = head;
 966         }
 967 }
 968 
 969 
 970 /* == data output ========================================================== */
 971 
 972 /**
 973  * gigaset_isoc_send_skb() - queue an skb for sending
 974  * @bcs:        B channel descriptor structure.
 975  * @skb:        data to send.
 976  *
 977  * Called by LL to queue an skb for sending, and start transmission if
 978  * necessary.
 979  * Once the payload data has been transmitted completely, gigaset_skb_sent()
 980  * will be called with the skb's link layer header preserved.
 981  *
 982  * Return value:
 983  *      number of bytes accepted for sending (skb->len) if ok,
 984  *      error code < 0 (eg. -ENODEV) on error
 985  */
 986 int gigaset_isoc_send_skb(struct bc_state *bcs, struct sk_buff *skb)
 987 {
 988         int len = skb->len;
 989         unsigned long flags;
 990 
 991         spin_lock_irqsave(&bcs->cs->lock, flags);
 992         if (!bcs->cs->connected) {
 993                 spin_unlock_irqrestore(&bcs->cs->lock, flags);
 994                 return -ENODEV;
 995         }
 996 
 997         skb_queue_tail(&bcs->squeue, skb);
 998         gig_dbg(DEBUG_ISO, "%s: skb queued, qlen=%d",
 999                 __func__, skb_queue_len(&bcs->squeue));
1000 
1001         /* tasklet submits URB if necessary */
1002         tasklet_schedule(&bcs->hw.bas->sent_tasklet);
1003         spin_unlock_irqrestore(&bcs->cs->lock, flags);
1004 
1005         return len;     /* ok so far */
1006 }

/* [<][>][^][v][top][bottom][index][help] */