Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] SMP rewrite of mkiss

Rewrite the mkiss driver to make it SMP-proof following the example of
6pack.c.

Signed-off-by: Ralf Baechle DL5RB <ralf@linux-mips.org>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>

authored by

Ralf Baechle and committed by
Jeff Garzik
815f62bf 75a95178

+566 -605
+1 -1
drivers/net/hamradio/Kconfig
··· 1 1 config MKISS 2 2 tristate "Serial port KISS driver" 3 - depends on AX25 && BROKEN_ON_SMP 3 + depends on AX25 4 4 ---help--- 5 5 KISS is a protocol used for the exchange of data between a computer 6 6 and a Terminal Node Controller (a small embedded system commonly
+565 -604
drivers/net/hamradio/mkiss.c
··· 1 1 /* 2 - * MKISS Driver 2 + * This program is free software; you can distribute it and/or modify it 3 + * under the terms of the GNU General Public License (Version 2) as 4 + * published by the Free Software Foundation. 3 5 * 4 - * This module: 5 - * This module is free software; you can redistribute it and/or 6 - * modify it under the terms of the GNU General Public License 7 - * as published by the Free Software Foundation; either version 8 - * 2 of the License, or (at your option) any later version. 6 + * This program is distributed in the hope it will be useful, but WITHOUT 7 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 8 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 9 + * for more details. 9 10 * 10 - * This module implements the AX.25 protocol for kernel-based 11 - * devices like TTYs. It interfaces between a raw TTY, and the 12 - * kernel's AX.25 protocol layers, just like slip.c. 13 - * AX.25 needs to be separated from slip.c while slip.c is no 14 - * longer a static kernel device since it is a module. 15 - * This method clears the way to implement other kiss protocols 16 - * like mkiss smack g8bpq ..... so far only mkiss is implemented. 11 + * You should have received a copy of the GNU General Public License along 12 + * with this program; if not, write to the Free Software Foundation, Inc., 13 + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 17 14 * 18 - * Hans Alblas <hans@esrac.ele.tue.nl> 19 - * 20 - * History 21 - * Jonathan (G4KLX) Fixed to match Linux networking changes - 2.1.15. 22 - * Matthias (DG2FEF) Added support for FlexNet CRC (on special request) 23 - * Fixed bug in ax25_close(): dev_lock_wait() was 24 - * called twice, causing a deadlock. 25 - * Jeroen (PE1RXQ) Removed old MKISS_MAGIC stuff and calls to 26 - * MOD_*_USE_COUNT 27 - * Remove cli() and fix rtnl lock usage. 15 + * Copyright (C) Hans Alblas PE1AYX <hans@esrac.ele.tue.nl> 16 + * Copyright (C) 2004, 05 Ralf Baechle DL5RB <ralf@linux-mips.org> 28 17 */ 29 18 30 19 #include <linux/config.h> ··· 39 50 40 51 #include <net/ax25.h> 41 52 42 - #include "mkiss.h" 43 - 44 53 #ifdef CONFIG_INET 45 54 #include <linux/ip.h> 46 55 #include <linux/tcp.h> 47 56 #endif 48 57 49 - static char banner[] __initdata = KERN_INFO "mkiss: AX.25 Multikiss, Hans Albas PE1AYX\n"; 58 + #define AX_MTU 236 50 59 51 - typedef struct ax25_ctrl { 52 - struct ax_disp ctrl; /* */ 53 - struct net_device dev; /* the device */ 54 - } ax25_ctrl_t; 60 + /* SLIP/KISS protocol characters. */ 61 + #define END 0300 /* indicates end of frame */ 62 + #define ESC 0333 /* indicates byte stuffing */ 63 + #define ESC_END 0334 /* ESC ESC_END means END 'data' */ 64 + #define ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */ 55 65 56 - static ax25_ctrl_t **ax25_ctrls; 66 + struct mkiss { 67 + struct tty_struct *tty; /* ptr to TTY structure */ 68 + struct net_device *dev; /* easy for intr handling */ 57 69 58 - int ax25_maxdev = AX25_MAXDEV; /* Can be overridden with insmod! */ 70 + /* These are pointers to the malloc()ed frame buffers. */ 71 + spinlock_t buflock;/* lock for rbuf and xbuf */ 72 + unsigned char *rbuff; /* receiver buffer */ 73 + int rcount; /* received chars counter */ 74 + unsigned char *xbuff; /* transmitter buffer */ 75 + unsigned char *xhead; /* pointer to next byte to XMIT */ 76 + int xleft; /* bytes left in XMIT queue */ 59 77 60 - static struct tty_ldisc ax_ldisc; 78 + struct net_device_stats stats; 61 79 62 - static int ax25_init(struct net_device *); 63 - static int kiss_esc(unsigned char *, unsigned char *, int); 64 - static int kiss_esc_crc(unsigned char *, unsigned char *, unsigned short, int); 65 - static void kiss_unesc(struct ax_disp *, unsigned char); 80 + /* Detailed SLIP statistics. */ 81 + int mtu; /* Our mtu (to spot changes!) */ 82 + int buffsize; /* Max buffers sizes */ 66 83 67 - /*---------------------------------------------------------------------------*/ 84 + unsigned long flags; /* Flag values/ mode etc */ 85 + /* long req'd: used by set_bit --RR */ 86 + #define AXF_INUSE 0 /* Channel in use */ 87 + #define AXF_ESCAPE 1 /* ESC received */ 88 + #define AXF_ERROR 2 /* Parity, etc. error */ 89 + #define AXF_KEEPTEST 3 /* Keepalive test flag */ 90 + #define AXF_OUTWAIT 4 /* is outpacket was flag */ 68 91 69 - static const unsigned short Crc_flex_table[] = { 70 - 0x0f87, 0x1e0e, 0x2c95, 0x3d1c, 0x49a3, 0x582a, 0x6ab1, 0x7b38, 71 - 0x83cf, 0x9246, 0xa0dd, 0xb154, 0xc5eb, 0xd462, 0xe6f9, 0xf770, 72 - 0x1f06, 0x0e8f, 0x3c14, 0x2d9d, 0x5922, 0x48ab, 0x7a30, 0x6bb9, 73 - 0x934e, 0x82c7, 0xb05c, 0xa1d5, 0xd56a, 0xc4e3, 0xf678, 0xe7f1, 74 - 0x2e85, 0x3f0c, 0x0d97, 0x1c1e, 0x68a1, 0x7928, 0x4bb3, 0x5a3a, 75 - 0xa2cd, 0xb344, 0x81df, 0x9056, 0xe4e9, 0xf560, 0xc7fb, 0xd672, 76 - 0x3e04, 0x2f8d, 0x1d16, 0x0c9f, 0x7820, 0x69a9, 0x5b32, 0x4abb, 77 - 0xb24c, 0xa3c5, 0x915e, 0x80d7, 0xf468, 0xe5e1, 0xd77a, 0xc6f3, 78 - 0x4d83, 0x5c0a, 0x6e91, 0x7f18, 0x0ba7, 0x1a2e, 0x28b5, 0x393c, 79 - 0xc1cb, 0xd042, 0xe2d9, 0xf350, 0x87ef, 0x9666, 0xa4fd, 0xb574, 80 - 0x5d02, 0x4c8b, 0x7e10, 0x6f99, 0x1b26, 0x0aaf, 0x3834, 0x29bd, 81 - 0xd14a, 0xc0c3, 0xf258, 0xe3d1, 0x976e, 0x86e7, 0xb47c, 0xa5f5, 82 - 0x6c81, 0x7d08, 0x4f93, 0x5e1a, 0x2aa5, 0x3b2c, 0x09b7, 0x183e, 83 - 0xe0c9, 0xf140, 0xc3db, 0xd252, 0xa6ed, 0xb764, 0x85ff, 0x9476, 84 - 0x7c00, 0x6d89, 0x5f12, 0x4e9b, 0x3a24, 0x2bad, 0x1936, 0x08bf, 85 - 0xf048, 0xe1c1, 0xd35a, 0xc2d3, 0xb66c, 0xa7e5, 0x957e, 0x84f7, 86 - 0x8b8f, 0x9a06, 0xa89d, 0xb914, 0xcdab, 0xdc22, 0xeeb9, 0xff30, 87 - 0x07c7, 0x164e, 0x24d5, 0x355c, 0x41e3, 0x506a, 0x62f1, 0x7378, 88 - 0x9b0e, 0x8a87, 0xb81c, 0xa995, 0xdd2a, 0xcca3, 0xfe38, 0xefb1, 89 - 0x1746, 0x06cf, 0x3454, 0x25dd, 0x5162, 0x40eb, 0x7270, 0x63f9, 90 - 0xaa8d, 0xbb04, 0x899f, 0x9816, 0xeca9, 0xfd20, 0xcfbb, 0xde32, 91 - 0x26c5, 0x374c, 0x05d7, 0x145e, 0x60e1, 0x7168, 0x43f3, 0x527a, 92 - 0xba0c, 0xab85, 0x991e, 0x8897, 0xfc28, 0xeda1, 0xdf3a, 0xceb3, 93 - 0x3644, 0x27cd, 0x1556, 0x04df, 0x7060, 0x61e9, 0x5372, 0x42fb, 94 - 0xc98b, 0xd802, 0xea99, 0xfb10, 0x8faf, 0x9e26, 0xacbd, 0xbd34, 95 - 0x45c3, 0x544a, 0x66d1, 0x7758, 0x03e7, 0x126e, 0x20f5, 0x317c, 96 - 0xd90a, 0xc883, 0xfa18, 0xeb91, 0x9f2e, 0x8ea7, 0xbc3c, 0xadb5, 97 - 0x5542, 0x44cb, 0x7650, 0x67d9, 0x1366, 0x02ef, 0x3074, 0x21fd, 98 - 0xe889, 0xf900, 0xcb9b, 0xda12, 0xaead, 0xbf24, 0x8dbf, 0x9c36, 99 - 0x64c1, 0x7548, 0x47d3, 0x565a, 0x22e5, 0x336c, 0x01f7, 0x107e, 100 - 0xf808, 0xe981, 0xdb1a, 0xca93, 0xbe2c, 0xafa5, 0x9d3e, 0x8cb7, 101 - 0x7440, 0x65c9, 0x5752, 0x46db, 0x3264, 0x23ed, 0x1176, 0x00ff 92 + int mode; 93 + int crcmode; /* MW: for FlexNet, SMACK etc. */ 94 + #define CRC_MODE_NONE 0 95 + #define CRC_MODE_FLEX 1 96 + #define CRC_MODE_SMACK 2 97 + 98 + atomic_t refcnt; 99 + struct semaphore dead_sem; 102 100 }; 103 101 104 102 /*---------------------------------------------------------------------------*/ 105 103 104 + static const unsigned short crc_flex_table[] = { 105 + 0x0f87, 0x1e0e, 0x2c95, 0x3d1c, 0x49a3, 0x582a, 0x6ab1, 0x7b38, 106 + 0x83cf, 0x9246, 0xa0dd, 0xb154, 0xc5eb, 0xd462, 0xe6f9, 0xf770, 107 + 0x1f06, 0x0e8f, 0x3c14, 0x2d9d, 0x5922, 0x48ab, 0x7a30, 0x6bb9, 108 + 0x934e, 0x82c7, 0xb05c, 0xa1d5, 0xd56a, 0xc4e3, 0xf678, 0xe7f1, 109 + 0x2e85, 0x3f0c, 0x0d97, 0x1c1e, 0x68a1, 0x7928, 0x4bb3, 0x5a3a, 110 + 0xa2cd, 0xb344, 0x81df, 0x9056, 0xe4e9, 0xf560, 0xc7fb, 0xd672, 111 + 0x3e04, 0x2f8d, 0x1d16, 0x0c9f, 0x7820, 0x69a9, 0x5b32, 0x4abb, 112 + 0xb24c, 0xa3c5, 0x915e, 0x80d7, 0xf468, 0xe5e1, 0xd77a, 0xc6f3, 113 + 0x4d83, 0x5c0a, 0x6e91, 0x7f18, 0x0ba7, 0x1a2e, 0x28b5, 0x393c, 114 + 0xc1cb, 0xd042, 0xe2d9, 0xf350, 0x87ef, 0x9666, 0xa4fd, 0xb574, 115 + 0x5d02, 0x4c8b, 0x7e10, 0x6f99, 0x1b26, 0x0aaf, 0x3834, 0x29bd, 116 + 0xd14a, 0xc0c3, 0xf258, 0xe3d1, 0x976e, 0x86e7, 0xb47c, 0xa5f5, 117 + 0x6c81, 0x7d08, 0x4f93, 0x5e1a, 0x2aa5, 0x3b2c, 0x09b7, 0x183e, 118 + 0xe0c9, 0xf140, 0xc3db, 0xd252, 0xa6ed, 0xb764, 0x85ff, 0x9476, 119 + 0x7c00, 0x6d89, 0x5f12, 0x4e9b, 0x3a24, 0x2bad, 0x1936, 0x08bf, 120 + 0xf048, 0xe1c1, 0xd35a, 0xc2d3, 0xb66c, 0xa7e5, 0x957e, 0x84f7, 121 + 0x8b8f, 0x9a06, 0xa89d, 0xb914, 0xcdab, 0xdc22, 0xeeb9, 0xff30, 122 + 0x07c7, 0x164e, 0x24d5, 0x355c, 0x41e3, 0x506a, 0x62f1, 0x7378, 123 + 0x9b0e, 0x8a87, 0xb81c, 0xa995, 0xdd2a, 0xcca3, 0xfe38, 0xefb1, 124 + 0x1746, 0x06cf, 0x3454, 0x25dd, 0x5162, 0x40eb, 0x7270, 0x63f9, 125 + 0xaa8d, 0xbb04, 0x899f, 0x9816, 0xeca9, 0xfd20, 0xcfbb, 0xde32, 126 + 0x26c5, 0x374c, 0x05d7, 0x145e, 0x60e1, 0x7168, 0x43f3, 0x527a, 127 + 0xba0c, 0xab85, 0x991e, 0x8897, 0xfc28, 0xeda1, 0xdf3a, 0xceb3, 128 + 0x3644, 0x27cd, 0x1556, 0x04df, 0x7060, 0x61e9, 0x5372, 0x42fb, 129 + 0xc98b, 0xd802, 0xea99, 0xfb10, 0x8faf, 0x9e26, 0xacbd, 0xbd34, 130 + 0x45c3, 0x544a, 0x66d1, 0x7758, 0x03e7, 0x126e, 0x20f5, 0x317c, 131 + 0xd90a, 0xc883, 0xfa18, 0xeb91, 0x9f2e, 0x8ea7, 0xbc3c, 0xadb5, 132 + 0x5542, 0x44cb, 0x7650, 0x67d9, 0x1366, 0x02ef, 0x3074, 0x21fd, 133 + 0xe889, 0xf900, 0xcb9b, 0xda12, 0xaead, 0xbf24, 0x8dbf, 0x9c36, 134 + 0x64c1, 0x7548, 0x47d3, 0x565a, 0x22e5, 0x336c, 0x01f7, 0x107e, 135 + 0xf808, 0xe981, 0xdb1a, 0xca93, 0xbe2c, 0xafa5, 0x9d3e, 0x8cb7, 136 + 0x7440, 0x65c9, 0x5752, 0x46db, 0x3264, 0x23ed, 0x1176, 0x00ff 137 + }; 138 + 106 139 static unsigned short calc_crc_flex(unsigned char *cp, int size) 107 140 { 108 - unsigned short crc = 0xffff; 109 - 110 - while (size--) 111 - crc = (crc << 8) ^ Crc_flex_table[((crc >> 8) ^ *cp++) & 0xff]; 141 + unsigned short crc = 0xffff; 112 142 113 - return crc; 143 + while (size--) 144 + crc = (crc << 8) ^ crc_flex_table[((crc >> 8) ^ *cp++) & 0xff]; 145 + 146 + return crc; 114 147 } 115 - 116 - /*---------------------------------------------------------------------------*/ 117 148 118 149 static int check_crc_flex(unsigned char *cp, int size) 119 150 { 120 - unsigned short crc = 0xffff; 151 + unsigned short crc = 0xffff; 121 152 122 - if (size < 3) 123 - return -1; 153 + if (size < 3) 154 + return -1; 124 155 125 - while (size--) 126 - crc = (crc << 8) ^ Crc_flex_table[((crc >> 8) ^ *cp++) & 0xff]; 156 + while (size--) 157 + crc = (crc << 8) ^ crc_flex_table[((crc >> 8) ^ *cp++) & 0xff]; 127 158 128 - if ((crc & 0xffff) != 0x7070) 129 - return -1; 159 + if ((crc & 0xffff) != 0x7070) 160 + return -1; 130 161 131 - return 0; 162 + return 0; 163 + } 164 + 165 + /* 166 + * Standard encapsulation 167 + */ 168 + 169 + static int kiss_esc(unsigned char *s, unsigned char *d, int len) 170 + { 171 + unsigned char *ptr = d; 172 + unsigned char c; 173 + 174 + /* 175 + * Send an initial END character to flush out any data that may have 176 + * accumulated in the receiver due to line noise. 177 + */ 178 + 179 + *ptr++ = END; 180 + 181 + while (len-- > 0) { 182 + switch (c = *s++) { 183 + case END: 184 + *ptr++ = ESC; 185 + *ptr++ = ESC_END; 186 + break; 187 + case ESC: 188 + *ptr++ = ESC; 189 + *ptr++ = ESC_ESC; 190 + break; 191 + default: 192 + *ptr++ = c; 193 + break; 194 + } 195 + } 196 + 197 + *ptr++ = END; 198 + 199 + return ptr - d; 200 + } 201 + 202 + /* 203 + * MW: 204 + * OK its ugly, but tell me a better solution without copying the 205 + * packet to a temporary buffer :-) 206 + */ 207 + static int kiss_esc_crc(unsigned char *s, unsigned char *d, unsigned short crc, 208 + int len) 209 + { 210 + unsigned char *ptr = d; 211 + unsigned char c=0; 212 + 213 + *ptr++ = END; 214 + while (len > 0) { 215 + if (len > 2) 216 + c = *s++; 217 + else if (len > 1) 218 + c = crc >> 8; 219 + else if (len > 0) 220 + c = crc & 0xff; 221 + 222 + len--; 223 + 224 + switch (c) { 225 + case END: 226 + *ptr++ = ESC; 227 + *ptr++ = ESC_END; 228 + break; 229 + case ESC: 230 + *ptr++ = ESC; 231 + *ptr++ = ESC_ESC; 232 + break; 233 + default: 234 + *ptr++ = c; 235 + break; 236 + } 237 + } 238 + *ptr++ = END; 239 + 240 + return ptr - d; 241 + } 242 + 243 + /* Send one completely decapsulated AX.25 packet to the AX.25 layer. */ 244 + static void ax_bump(struct mkiss *ax) 245 + { 246 + struct sk_buff *skb; 247 + int count; 248 + 249 + spin_lock_bh(&ax->buflock); 250 + if (ax->rbuff[0] > 0x0f) { 251 + if (ax->rbuff[0] & 0x20) { 252 + ax->crcmode = CRC_MODE_FLEX; 253 + if (check_crc_flex(ax->rbuff, ax->rcount) < 0) { 254 + ax->stats.rx_errors++; 255 + return; 256 + } 257 + ax->rcount -= 2; 258 + /* dl9sau bugfix: the trailling two bytes flexnet crc 259 + * will not be passed to the kernel. thus we have 260 + * to correct the kissparm signature, because it 261 + * indicates a crc but there's none 262 + */ 263 + *ax->rbuff &= ~0x20; 264 + } 265 + } 266 + spin_unlock_bh(&ax->buflock); 267 + 268 + count = ax->rcount; 269 + 270 + if ((skb = dev_alloc_skb(count)) == NULL) { 271 + printk(KERN_ERR "mkiss: %s: memory squeeze, dropping packet.\n", 272 + ax->dev->name); 273 + ax->stats.rx_dropped++; 274 + return; 275 + } 276 + 277 + spin_lock_bh(&ax->buflock); 278 + memcpy(skb_put(skb,count), ax->rbuff, count); 279 + spin_unlock_bh(&ax->buflock); 280 + skb->protocol = ax25_type_trans(skb, ax->dev); 281 + netif_rx(skb); 282 + ax->dev->last_rx = jiffies; 283 + ax->stats.rx_packets++; 284 + ax->stats.rx_bytes += count; 285 + } 286 + 287 + static void kiss_unesc(struct mkiss *ax, unsigned char s) 288 + { 289 + switch (s) { 290 + case END: 291 + /* drop keeptest bit = VSV */ 292 + if (test_bit(AXF_KEEPTEST, &ax->flags)) 293 + clear_bit(AXF_KEEPTEST, &ax->flags); 294 + 295 + if (!test_and_clear_bit(AXF_ERROR, &ax->flags) && (ax->rcount > 2)) 296 + ax_bump(ax); 297 + 298 + clear_bit(AXF_ESCAPE, &ax->flags); 299 + ax->rcount = 0; 300 + return; 301 + 302 + case ESC: 303 + set_bit(AXF_ESCAPE, &ax->flags); 304 + return; 305 + case ESC_ESC: 306 + if (test_and_clear_bit(AXF_ESCAPE, &ax->flags)) 307 + s = ESC; 308 + break; 309 + case ESC_END: 310 + if (test_and_clear_bit(AXF_ESCAPE, &ax->flags)) 311 + s = END; 312 + break; 313 + } 314 + 315 + spin_lock_bh(&ax->buflock); 316 + if (!test_bit(AXF_ERROR, &ax->flags)) { 317 + if (ax->rcount < ax->buffsize) { 318 + ax->rbuff[ax->rcount++] = s; 319 + spin_unlock_bh(&ax->buflock); 320 + return; 321 + } 322 + 323 + ax->stats.rx_over_errors++; 324 + set_bit(AXF_ERROR, &ax->flags); 325 + } 326 + spin_unlock_bh(&ax->buflock); 327 + } 328 + 329 + static int ax_set_mac_address(struct net_device *dev, void *addr) 330 + { 331 + struct sockaddr_ax25 *sa = addr; 332 + 333 + spin_lock_irq(&dev->xmit_lock); 334 + memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN); 335 + spin_unlock_irq(&dev->xmit_lock); 336 + 337 + return 0; 132 338 } 133 339 134 340 /*---------------------------------------------------------------------------*/ 135 341 136 - /* Find a free channel, and link in this `tty' line. */ 137 - static inline struct ax_disp *ax_alloc(void) 138 - { 139 - ax25_ctrl_t *axp=NULL; 140 - int i; 141 - 142 - for (i = 0; i < ax25_maxdev; i++) { 143 - axp = ax25_ctrls[i]; 144 - 145 - /* Not allocated ? */ 146 - if (axp == NULL) 147 - break; 148 - 149 - /* Not in use ? */ 150 - if (!test_and_set_bit(AXF_INUSE, &axp->ctrl.flags)) 151 - break; 152 - } 153 - 154 - /* Sorry, too many, all slots in use */ 155 - if (i >= ax25_maxdev) 156 - return NULL; 157 - 158 - /* If no channels are available, allocate one */ 159 - if (axp == NULL && (ax25_ctrls[i] = kmalloc(sizeof(ax25_ctrl_t), GFP_KERNEL)) != NULL) { 160 - axp = ax25_ctrls[i]; 161 - } 162 - memset(axp, 0, sizeof(ax25_ctrl_t)); 163 - 164 - /* Initialize channel control data */ 165 - set_bit(AXF_INUSE, &axp->ctrl.flags); 166 - sprintf(axp->dev.name, "ax%d", i++); 167 - axp->ctrl.tty = NULL; 168 - axp->dev.base_addr = i; 169 - axp->dev.priv = (void *)&axp->ctrl; 170 - axp->dev.next = NULL; 171 - axp->dev.init = ax25_init; 172 - 173 - if (axp != NULL) { 174 - /* 175 - * register device so that it can be ifconfig'ed 176 - * ax25_init() will be called as a side-effect 177 - * SIDE-EFFECT WARNING: ax25_init() CLEARS axp->ctrl ! 178 - */ 179 - if (register_netdev(&axp->dev) == 0) { 180 - /* (Re-)Set the INUSE bit. Very Important! */ 181 - set_bit(AXF_INUSE, &axp->ctrl.flags); 182 - axp->ctrl.dev = &axp->dev; 183 - axp->dev.priv = (void *) &axp->ctrl; 184 - 185 - return &axp->ctrl; 186 - } else { 187 - clear_bit(AXF_INUSE,&axp->ctrl.flags); 188 - printk(KERN_ERR "mkiss: ax_alloc() - register_netdev() failure.\n"); 189 - } 190 - } 191 - 192 - return NULL; 193 - } 194 - 195 - /* Free an AX25 channel. */ 196 - static inline void ax_free(struct ax_disp *ax) 197 - { 198 - /* Free all AX25 frame buffers. */ 199 - if (ax->rbuff) 200 - kfree(ax->rbuff); 201 - ax->rbuff = NULL; 202 - if (ax->xbuff) 203 - kfree(ax->xbuff); 204 - ax->xbuff = NULL; 205 - if (!test_and_clear_bit(AXF_INUSE, &ax->flags)) 206 - printk(KERN_ERR "mkiss: %s: ax_free for already free unit.\n", ax->dev->name); 207 - } 208 - 209 - static void ax_changedmtu(struct ax_disp *ax) 342 + static void ax_changedmtu(struct mkiss *ax) 210 343 { 211 344 struct net_device *dev = ax->dev; 212 345 unsigned char *xbuff, *rbuff, *oxbuff, *orbuff; ··· 348 237 rbuff = kmalloc(len + 4, GFP_ATOMIC); 349 238 350 239 if (xbuff == NULL || rbuff == NULL) { 351 - printk(KERN_ERR "mkiss: %s: unable to grow ax25 buffers, MTU change cancelled.\n", 240 + printk(KERN_ERR "mkiss: %s: unable to grow ax25 buffers, " 241 + "MTU change cancelled.\n", 352 242 ax->dev->name); 353 243 dev->mtu = ax->mtu; 354 244 if (xbuff != NULL) ··· 371 259 memcpy(ax->xbuff, ax->xhead, ax->xleft); 372 260 } else { 373 261 ax->xleft = 0; 374 - ax->tx_dropped++; 262 + ax->stats.tx_dropped++; 375 263 } 376 264 } 377 265 ··· 382 270 memcpy(ax->rbuff, orbuff, ax->rcount); 383 271 } else { 384 272 ax->rcount = 0; 385 - ax->rx_over_errors++; 273 + ax->stats.rx_over_errors++; 386 274 set_bit(AXF_ERROR, &ax->flags); 387 275 } 388 276 } ··· 392 280 393 281 spin_unlock_bh(&ax->buflock); 394 282 395 - if (oxbuff != NULL) 396 - kfree(oxbuff); 397 - if (orbuff != NULL) 398 - kfree(orbuff); 399 - } 400 - 401 - 402 - /* Set the "sending" flag. This must be atomic. */ 403 - static inline void ax_lock(struct ax_disp *ax) 404 - { 405 - netif_stop_queue(ax->dev); 406 - } 407 - 408 - 409 - /* Clear the "sending" flag. This must be atomic. */ 410 - static inline void ax_unlock(struct ax_disp *ax) 411 - { 412 - netif_start_queue(ax->dev); 413 - } 414 - 415 - /* Send one completely decapsulated AX.25 packet to the AX.25 layer. */ 416 - static void ax_bump(struct ax_disp *ax) 417 - { 418 - struct sk_buff *skb; 419 - int count; 420 - 421 - spin_lock_bh(&ax->buflock); 422 - if (ax->rbuff[0] > 0x0f) { 423 - if (ax->rbuff[0] & 0x20) { 424 - ax->crcmode = CRC_MODE_FLEX; 425 - if (check_crc_flex(ax->rbuff, ax->rcount) < 0) { 426 - ax->rx_errors++; 427 - return; 428 - } 429 - ax->rcount -= 2; 430 - /* dl9sau bugfix: the trailling two bytes flexnet crc 431 - * will not be passed to the kernel. thus we have 432 - * to correct the kissparm signature, because it 433 - * indicates a crc but there's none 434 - */ 435 - *ax->rbuff &= ~0x20; 436 - } 437 - } 438 - spin_unlock_bh(&ax->buflock); 439 - 440 - count = ax->rcount; 441 - 442 - if ((skb = dev_alloc_skb(count)) == NULL) { 443 - printk(KERN_ERR "mkiss: %s: memory squeeze, dropping packet.\n", ax->dev->name); 444 - ax->rx_dropped++; 445 - return; 446 - } 447 - 448 - spin_lock_bh(&ax->buflock); 449 - memcpy(skb_put(skb,count), ax->rbuff, count); 450 - spin_unlock_bh(&ax->buflock); 451 - skb->protocol = ax25_type_trans(skb, ax->dev); 452 - netif_rx(skb); 453 - ax->dev->last_rx = jiffies; 454 - ax->rx_packets++; 455 - ax->rx_bytes+=count; 283 + kfree(oxbuff); 284 + kfree(orbuff); 456 285 } 457 286 458 287 /* Encapsulate one AX.25 packet and stuff into a TTY queue. */ 459 - static void ax_encaps(struct ax_disp *ax, unsigned char *icp, int len) 288 + static void ax_encaps(struct net_device *dev, unsigned char *icp, int len) 460 289 { 290 + struct mkiss *ax = netdev_priv(dev); 461 291 unsigned char *p; 462 292 int actual, count; 463 293 ··· 409 355 if (len > ax->mtu) { /* Sigh, shouldn't occur BUT ... */ 410 356 len = ax->mtu; 411 357 printk(KERN_ERR "mkiss: %s: truncating oversized transmit packet!\n", ax->dev->name); 412 - ax->tx_dropped++; 413 - ax_unlock(ax); 358 + ax->stats.tx_dropped++; 359 + netif_start_queue(dev); 414 360 return; 415 361 } 416 362 ··· 431 377 break; 432 378 } 433 379 434 - ax->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); 380 + set_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags); 435 381 actual = ax->tty->driver->write(ax->tty, ax->xbuff, count); 436 - ax->tx_packets++; 437 - ax->tx_bytes+=actual; 382 + ax->stats.tx_packets++; 383 + ax->stats.tx_bytes += actual; 384 + 438 385 ax->dev->trans_start = jiffies; 439 386 ax->xleft = count - actual; 440 387 ax->xhead = ax->xbuff + actual; ··· 443 388 spin_unlock_bh(&ax->buflock); 444 389 } 445 390 446 - /* 447 - * Called by the driver when there's room for more data. If we have 448 - * more packets to send, we send them here. 449 - */ 450 - static void ax25_write_wakeup(struct tty_struct *tty) 451 - { 452 - int actual; 453 - struct ax_disp *ax = (struct ax_disp *) tty->disc_data; 454 - 455 - /* First make sure we're connected. */ 456 - if (ax == NULL || ax->magic != AX25_MAGIC || !netif_running(ax->dev)) 457 - return; 458 - if (ax->xleft <= 0) { 459 - /* Now serial buffer is almost free & we can start 460 - * transmission of another packet 461 - */ 462 - tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); 463 - 464 - netif_wake_queue(ax->dev); 465 - return; 466 - } 467 - 468 - actual = tty->driver->write(tty, ax->xhead, ax->xleft); 469 - ax->xleft -= actual; 470 - ax->xhead += actual; 471 - } 472 - 473 391 /* Encapsulate an AX.25 packet and kick it into a TTY queue. */ 474 392 static int ax_xmit(struct sk_buff *skb, struct net_device *dev) 475 393 { 476 - struct ax_disp *ax = netdev_priv(dev); 394 + struct mkiss *ax = netdev_priv(dev); 477 395 478 396 if (!netif_running(dev)) { 479 397 printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name); ··· 468 440 "bad line quality" : "driver error"); 469 441 470 442 ax->xleft = 0; 471 - ax->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); 472 - ax_unlock(ax); 443 + clear_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags); 444 + netif_start_queue(dev); 473 445 } 474 446 475 447 /* We were not busy, so we are now... :-) */ 476 448 if (skb != NULL) { 477 - ax_lock(ax); 478 - ax_encaps(ax, skb->data, skb->len); 449 + netif_stop_queue(dev); 450 + ax_encaps(dev, skb->data, skb->len); 479 451 kfree_skb(skb); 480 452 } 453 + 454 + return 0; 455 + } 456 + 457 + static int ax_open_dev(struct net_device *dev) 458 + { 459 + struct mkiss *ax = netdev_priv(dev); 460 + 461 + if (ax->tty == NULL) 462 + return -ENODEV; 481 463 482 464 return 0; 483 465 } ··· 520 482 /* Open the low-level part of the AX25 channel. Easy! */ 521 483 static int ax_open(struct net_device *dev) 522 484 { 523 - struct ax_disp *ax = netdev_priv(dev); 485 + struct mkiss *ax = netdev_priv(dev); 524 486 unsigned long len; 525 487 526 488 if (ax->tty == NULL) ··· 557 519 558 520 spin_lock_init(&ax->buflock); 559 521 560 - netif_start_queue(dev); 561 522 return 0; 562 523 563 524 noxbuff: ··· 570 533 /* Close the low-level part of the AX25 channel. Easy! */ 571 534 static int ax_close(struct net_device *dev) 572 535 { 573 - struct ax_disp *ax = netdev_priv(dev); 536 + struct mkiss *ax = netdev_priv(dev); 574 537 575 - if (ax->tty == NULL) 576 - return -EBUSY; 577 - 578 - ax->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); 538 + if (ax->tty) 539 + clear_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags); 579 540 580 541 netif_stop_queue(dev); 581 542 582 543 return 0; 583 544 } 584 545 585 - static int ax25_receive_room(struct tty_struct *tty) 546 + static struct net_device_stats *ax_get_stats(struct net_device *dev) 586 547 { 587 - return 65536; /* We can handle an infinite amount of data. :-) */ 548 + struct mkiss *ax = netdev_priv(dev); 549 + 550 + return &ax->stats; 551 + } 552 + 553 + static void ax_setup(struct net_device *dev) 554 + { 555 + static char ax25_bcast[AX25_ADDR_LEN] = 556 + {'Q'<<1,'S'<<1,'T'<<1,' '<<1,' '<<1,' '<<1,'0'<<1}; 557 + static char ax25_test[AX25_ADDR_LEN] = 558 + {'L'<<1,'I'<<1,'N'<<1,'U'<<1,'X'<<1,' '<<1,'1'<<1}; 559 + 560 + /* Finish setting up the DEVICE info. */ 561 + dev->mtu = AX_MTU; 562 + dev->hard_start_xmit = ax_xmit; 563 + dev->open = ax_open_dev; 564 + dev->stop = ax_close; 565 + dev->get_stats = ax_get_stats; 566 + dev->set_mac_address = ax_set_mac_address; 567 + dev->hard_header_len = 0; 568 + dev->addr_len = 0; 569 + dev->type = ARPHRD_AX25; 570 + dev->tx_queue_len = 10; 571 + dev->hard_header = ax_header; 572 + dev->rebuild_header = ax_rebuild_header; 573 + 574 + memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN); 575 + memcpy(dev->dev_addr, ax25_test, AX25_ADDR_LEN); 576 + 577 + dev->flags = IFF_BROADCAST | IFF_MULTICAST; 578 + } 579 + 580 + /* 581 + * We have a potential race on dereferencing tty->disc_data, because the tty 582 + * layer provides no locking at all - thus one cpu could be running 583 + * sixpack_receive_buf while another calls sixpack_close, which zeroes 584 + * tty->disc_data and frees the memory that sixpack_receive_buf is using. The 585 + * best way to fix this is to use a rwlock in the tty struct, but for now we 586 + * use a single global rwlock for all ttys in ppp line discipline. 587 + */ 588 + static rwlock_t disc_data_lock = RW_LOCK_UNLOCKED; 589 + 590 + static struct mkiss *mkiss_get(struct tty_struct *tty) 591 + { 592 + struct mkiss *ax; 593 + 594 + read_lock(&disc_data_lock); 595 + ax = tty->disc_data; 596 + if (ax) 597 + atomic_inc(&ax->refcnt); 598 + read_unlock(&disc_data_lock); 599 + 600 + return ax; 601 + } 602 + 603 + static void mkiss_put(struct mkiss *ax) 604 + { 605 + if (atomic_dec_and_test(&ax->refcnt)) 606 + up(&ax->dead_sem); 607 + } 608 + 609 + static int mkiss_open(struct tty_struct *tty) 610 + { 611 + struct net_device *dev; 612 + struct mkiss *ax; 613 + int err; 614 + 615 + if (!capable(CAP_NET_ADMIN)) 616 + return -EPERM; 617 + 618 + dev = alloc_netdev(sizeof(struct mkiss), "ax%d", ax_setup); 619 + if (!dev) { 620 + err = -ENOMEM; 621 + goto out; 622 + } 623 + 624 + ax = netdev_priv(dev); 625 + ax->dev = dev; 626 + 627 + spin_lock_init(&ax->buflock); 628 + atomic_set(&ax->refcnt, 1); 629 + init_MUTEX_LOCKED(&ax->dead_sem); 630 + 631 + ax->tty = tty; 632 + tty->disc_data = ax; 633 + 634 + if (tty->driver->flush_buffer) 635 + tty->driver->flush_buffer(tty); 636 + 637 + /* Restore default settings */ 638 + dev->type = ARPHRD_AX25; 639 + 640 + /* Perform the low-level AX25 initialization. */ 641 + if ((err = ax_open(ax->dev))) { 642 + goto out_free_netdev; 643 + } 644 + 645 + if (register_netdev(dev)) 646 + goto out_free_buffers; 647 + 648 + netif_start_queue(dev); 649 + 650 + /* Done. We have linked the TTY line to a channel. */ 651 + return 0; 652 + 653 + out_free_buffers: 654 + kfree(ax->rbuff); 655 + kfree(ax->xbuff); 656 + 657 + out_free_netdev: 658 + free_netdev(dev); 659 + 660 + out: 661 + return err; 662 + } 663 + 664 + static void mkiss_close(struct tty_struct *tty) 665 + { 666 + struct mkiss *ax; 667 + 668 + write_lock(&disc_data_lock); 669 + ax = tty->disc_data; 670 + tty->disc_data = NULL; 671 + write_unlock(&disc_data_lock); 672 + 673 + if (ax == 0) 674 + return; 675 + 676 + /* 677 + * We have now ensured that nobody can start using ap from now on, but 678 + * we have to wait for all existing users to finish. 679 + */ 680 + if (!atomic_dec_and_test(&ax->refcnt)) 681 + down(&ax->dead_sem); 682 + 683 + unregister_netdev(ax->dev); 684 + 685 + /* Free all AX25 frame buffers. */ 686 + kfree(ax->rbuff); 687 + kfree(ax->xbuff); 688 + 689 + ax->tty = NULL; 690 + } 691 + 692 + /* Perform I/O control on an active ax25 channel. */ 693 + static int mkiss_ioctl(struct tty_struct *tty, struct file *file, 694 + unsigned int cmd, unsigned long arg) 695 + { 696 + struct mkiss *ax = mkiss_get(tty); 697 + struct net_device *dev = ax->dev; 698 + unsigned int tmp, err; 699 + 700 + /* First make sure we're connected. */ 701 + if (ax == NULL) 702 + return -ENXIO; 703 + 704 + switch (cmd) { 705 + case SIOCGIFNAME: 706 + err = copy_to_user((void __user *) arg, ax->dev->name, 707 + strlen(ax->dev->name) + 1) ? -EFAULT : 0; 708 + break; 709 + 710 + case SIOCGIFENCAP: 711 + err = put_user(4, (int __user *) arg); 712 + break; 713 + 714 + case SIOCSIFENCAP: 715 + if (get_user(tmp, (int __user *) arg)) { 716 + err = -EFAULT; 717 + break; 718 + } 719 + 720 + ax->mode = tmp; 721 + dev->addr_len = AX25_ADDR_LEN; 722 + dev->hard_header_len = AX25_KISS_HEADER_LEN + 723 + AX25_MAX_HEADER_LEN + 3; 724 + dev->type = ARPHRD_AX25; 725 + 726 + err = 0; 727 + break; 728 + 729 + case SIOCSIFHWADDR: { 730 + char addr[AX25_ADDR_LEN]; 731 + printk(KERN_INFO "In SIOCSIFHWADDR"); 732 + 733 + if (copy_from_user(&addr, 734 + (void __user *) arg, AX25_ADDR_LEN)) { 735 + err = -EFAULT; 736 + break; 737 + } 738 + 739 + spin_lock_irq(&dev->xmit_lock); 740 + memcpy(dev->dev_addr, addr, AX25_ADDR_LEN); 741 + spin_unlock_irq(&dev->xmit_lock); 742 + 743 + err = 0; 744 + break; 745 + } 746 + default: 747 + err = -ENOIOCTLCMD; 748 + } 749 + 750 + mkiss_put(ax); 751 + 752 + return err; 588 753 } 589 754 590 755 /* ··· 795 556 * a block of data has been received, which can now be decapsulated 796 557 * and sent on to the AX.25 layer for further processing. 797 558 */ 798 - static void ax25_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) 559 + static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp, 560 + char *fp, int count) 799 561 { 800 - struct ax_disp *ax = (struct ax_disp *) tty->disc_data; 562 + struct mkiss *ax = mkiss_get(tty); 801 563 802 - if (ax == NULL || ax->magic != AX25_MAGIC || !netif_running(ax->dev)) 564 + if (!ax) 803 565 return; 804 566 805 567 /* ··· 814 574 while (count--) { 815 575 if (fp != NULL && *fp++) { 816 576 if (!test_and_set_bit(AXF_ERROR, &ax->flags)) 817 - ax->rx_errors++; 577 + ax->stats.rx_errors++; 818 578 cp++; 819 579 continue; 820 580 } 821 581 822 582 kiss_unesc(ax, *cp++); 823 583 } 584 + 585 + mkiss_put(ax); 586 + if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) 587 + && tty->driver->unthrottle) 588 + tty->driver->unthrottle(tty); 824 589 } 825 590 826 - static int ax25_open(struct tty_struct *tty) 591 + static int mkiss_receive_room(struct tty_struct *tty) 827 592 { 828 - struct ax_disp *ax = (struct ax_disp *) tty->disc_data; 829 - int err; 830 - 831 - /* First make sure we're not already connected. */ 832 - if (ax && ax->magic == AX25_MAGIC) 833 - return -EEXIST; 834 - 835 - /* OK. Find a free AX25 channel to use. */ 836 - if ((ax = ax_alloc()) == NULL) 837 - return -ENFILE; 838 - 839 - ax->tty = tty; 840 - tty->disc_data = ax; 841 - 842 - if (tty->driver->flush_buffer) 843 - tty->driver->flush_buffer(tty); 844 - 845 - /* Restore default settings */ 846 - ax->dev->type = ARPHRD_AX25; 847 - 848 - /* Perform the low-level AX25 initialization. */ 849 - if ((err = ax_open(ax->dev))) 850 - return err; 851 - 852 - /* Done. We have linked the TTY line to a channel. */ 853 - return ax->dev->base_addr; 854 - } 855 - 856 - static void ax25_close(struct tty_struct *tty) 857 - { 858 - struct ax_disp *ax = (struct ax_disp *) tty->disc_data; 859 - 860 - /* First make sure we're connected. */ 861 - if (ax == NULL || ax->magic != AX25_MAGIC) 862 - return; 863 - 864 - unregister_netdev(ax->dev); 865 - 866 - tty->disc_data = NULL; 867 - ax->tty = NULL; 868 - 869 - ax_free(ax); 870 - } 871 - 872 - 873 - static struct net_device_stats *ax_get_stats(struct net_device *dev) 874 - { 875 - static struct net_device_stats stats; 876 - struct ax_disp *ax = netdev_priv(dev); 877 - 878 - memset(&stats, 0, sizeof(struct net_device_stats)); 879 - 880 - stats.rx_packets = ax->rx_packets; 881 - stats.tx_packets = ax->tx_packets; 882 - stats.rx_bytes = ax->rx_bytes; 883 - stats.tx_bytes = ax->tx_bytes; 884 - stats.rx_dropped = ax->rx_dropped; 885 - stats.tx_dropped = ax->tx_dropped; 886 - stats.tx_errors = ax->tx_errors; 887 - stats.rx_errors = ax->rx_errors; 888 - stats.rx_over_errors = ax->rx_over_errors; 889 - 890 - return &stats; 891 - } 892 - 893 - 894 - /************************************************************************ 895 - * STANDARD ENCAPSULATION * 896 - ************************************************************************/ 897 - 898 - static int kiss_esc(unsigned char *s, unsigned char *d, int len) 899 - { 900 - unsigned char *ptr = d; 901 - unsigned char c; 902 - 903 - /* 904 - * Send an initial END character to flush out any 905 - * data that may have accumulated in the receiver 906 - * due to line noise. 907 - */ 908 - 909 - *ptr++ = END; 910 - 911 - while (len-- > 0) { 912 - switch (c = *s++) { 913 - case END: 914 - *ptr++ = ESC; 915 - *ptr++ = ESC_END; 916 - break; 917 - case ESC: 918 - *ptr++ = ESC; 919 - *ptr++ = ESC_ESC; 920 - break; 921 - default: 922 - *ptr++ = c; 923 - break; 924 - } 925 - } 926 - 927 - *ptr++ = END; 928 - 929 - return ptr - d; 593 + return 65536; /* We can handle an infinite amount of data. :-) */ 930 594 } 931 595 932 596 /* 933 - * MW: 934 - * OK its ugly, but tell me a better solution without copying the 935 - * packet to a temporary buffer :-) 597 + * Called by the driver when there's room for more data. If we have 598 + * more packets to send, we send them here. 936 599 */ 937 - static int kiss_esc_crc(unsigned char *s, unsigned char *d, unsigned short crc, int len) 600 + static void mkiss_write_wakeup(struct tty_struct *tty) 938 601 { 939 - unsigned char *ptr = d; 940 - unsigned char c=0; 602 + struct mkiss *ax = mkiss_get(tty); 603 + int actual; 941 604 942 - *ptr++ = END; 943 - while (len > 0) { 944 - if (len > 2) 945 - c = *s++; 946 - else if (len > 1) 947 - c = crc >> 8; 948 - else if (len > 0) 949 - c = crc & 0xff; 605 + if (!ax) 606 + return; 950 607 951 - len--; 608 + if (ax->xleft <= 0) { 609 + /* Now serial buffer is almost free & we can start 610 + * transmission of another packet 611 + */ 612 + clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); 952 613 953 - switch (c) { 954 - case END: 955 - *ptr++ = ESC; 956 - *ptr++ = ESC_END; 957 - break; 958 - case ESC: 959 - *ptr++ = ESC; 960 - *ptr++ = ESC_ESC; 961 - break; 962 - default: 963 - *ptr++ = c; 964 - break; 965 - } 966 - } 967 - *ptr++ = END; 968 - return ptr - d; 969 - } 970 - 971 - static void kiss_unesc(struct ax_disp *ax, unsigned char s) 972 - { 973 - switch (s) { 974 - case END: 975 - /* drop keeptest bit = VSV */ 976 - if (test_bit(AXF_KEEPTEST, &ax->flags)) 977 - clear_bit(AXF_KEEPTEST, &ax->flags); 978 - 979 - if (!test_and_clear_bit(AXF_ERROR, &ax->flags) && (ax->rcount > 2)) 980 - ax_bump(ax); 981 - 982 - clear_bit(AXF_ESCAPE, &ax->flags); 983 - ax->rcount = 0; 984 - return; 985 - 986 - case ESC: 987 - set_bit(AXF_ESCAPE, &ax->flags); 988 - return; 989 - case ESC_ESC: 990 - if (test_and_clear_bit(AXF_ESCAPE, &ax->flags)) 991 - s = ESC; 992 - break; 993 - case ESC_END: 994 - if (test_and_clear_bit(AXF_ESCAPE, &ax->flags)) 995 - s = END; 996 - break; 614 + netif_wake_queue(ax->dev); 615 + goto out; 997 616 } 998 617 999 - spin_lock_bh(&ax->buflock); 1000 - if (!test_bit(AXF_ERROR, &ax->flags)) { 1001 - if (ax->rcount < ax->buffsize) { 1002 - ax->rbuff[ax->rcount++] = s; 1003 - spin_unlock_bh(&ax->buflock); 1004 - return; 1005 - } 618 + actual = tty->driver->write(tty, ax->xhead, ax->xleft); 619 + ax->xleft -= actual; 620 + ax->xhead += actual; 1006 621 1007 - ax->rx_over_errors++; 1008 - set_bit(AXF_ERROR, &ax->flags); 1009 - } 1010 - spin_unlock_bh(&ax->buflock); 622 + out: 623 + mkiss_put(ax); 1011 624 } 1012 625 626 + static struct tty_ldisc ax_ldisc = { 627 + .magic = TTY_LDISC_MAGIC, 628 + .name = "mkiss", 629 + .open = mkiss_open, 630 + .close = mkiss_close, 631 + .ioctl = mkiss_ioctl, 632 + .receive_buf = mkiss_receive_buf, 633 + .receive_room = mkiss_receive_room, 634 + .write_wakeup = mkiss_write_wakeup 635 + }; 1013 636 1014 - static int ax_set_mac_address(struct net_device *dev, void __user *addr) 1015 - { 1016 - if (copy_from_user(dev->dev_addr, addr, AX25_ADDR_LEN)) 1017 - return -EFAULT; 1018 - return 0; 1019 - } 1020 - 1021 - static int ax_set_dev_mac_address(struct net_device *dev, void *addr) 1022 - { 1023 - struct sockaddr *sa = addr; 1024 - 1025 - memcpy(dev->dev_addr, sa->sa_data, AX25_ADDR_LEN); 1026 - 1027 - return 0; 1028 - } 1029 - 1030 - 1031 - /* Perform I/O control on an active ax25 channel. */ 1032 - static int ax25_disp_ioctl(struct tty_struct *tty, void *file, int cmd, void __user *arg) 1033 - { 1034 - struct ax_disp *ax = (struct ax_disp *) tty->disc_data; 1035 - unsigned int tmp; 1036 - 1037 - /* First make sure we're connected. */ 1038 - if (ax == NULL || ax->magic != AX25_MAGIC) 1039 - return -EINVAL; 1040 - 1041 - switch (cmd) { 1042 - case SIOCGIFNAME: 1043 - if (copy_to_user(arg, ax->dev->name, strlen(ax->dev->name) + 1)) 1044 - return -EFAULT; 1045 - return 0; 1046 - 1047 - case SIOCGIFENCAP: 1048 - return put_user(4, (int __user *)arg); 1049 - 1050 - case SIOCSIFENCAP: 1051 - if (get_user(tmp, (int __user *)arg)) 1052 - return -EFAULT; 1053 - ax->mode = tmp; 1054 - ax->dev->addr_len = AX25_ADDR_LEN; /* sizeof an AX.25 addr */ 1055 - ax->dev->hard_header_len = AX25_KISS_HEADER_LEN + AX25_MAX_HEADER_LEN + 3; 1056 - ax->dev->type = ARPHRD_AX25; 1057 - return 0; 1058 - 1059 - case SIOCSIFHWADDR: 1060 - return ax_set_mac_address(ax->dev, arg); 1061 - 1062 - default: 1063 - return -ENOIOCTLCMD; 1064 - } 1065 - } 1066 - 1067 - static int ax_open_dev(struct net_device *dev) 1068 - { 1069 - struct ax_disp *ax = netdev_priv(dev); 1070 - 1071 - if (ax->tty == NULL) 1072 - return -ENODEV; 1073 - 1074 - return 0; 1075 - } 1076 - 1077 - 1078 - /* Initialize the driver. Called by network startup. */ 1079 - static int ax25_init(struct net_device *dev) 1080 - { 1081 - struct ax_disp *ax = netdev_priv(dev); 1082 - 1083 - static char ax25_bcast[AX25_ADDR_LEN] = 1084 - {'Q'<<1,'S'<<1,'T'<<1,' '<<1,' '<<1,' '<<1,'0'<<1}; 1085 - static char ax25_test[AX25_ADDR_LEN] = 1086 - {'L'<<1,'I'<<1,'N'<<1,'U'<<1,'X'<<1,' '<<1,'1'<<1}; 1087 - 1088 - if (ax == NULL) /* Allocation failed ?? */ 1089 - return -ENODEV; 1090 - 1091 - /* Set up the "AX25 Control Block". (And clear statistics) */ 1092 - memset(ax, 0, sizeof (struct ax_disp)); 1093 - ax->magic = AX25_MAGIC; 1094 - ax->dev = dev; 1095 - 1096 - /* Finish setting up the DEVICE info. */ 1097 - dev->mtu = AX_MTU; 1098 - dev->hard_start_xmit = ax_xmit; 1099 - dev->open = ax_open_dev; 1100 - dev->stop = ax_close; 1101 - dev->get_stats = ax_get_stats; 1102 - dev->set_mac_address = ax_set_dev_mac_address; 1103 - dev->hard_header_len = 0; 1104 - dev->addr_len = 0; 1105 - dev->type = ARPHRD_AX25; 1106 - dev->tx_queue_len = 10; 1107 - dev->hard_header = ax_header; 1108 - dev->rebuild_header = ax_rebuild_header; 1109 - 1110 - memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN); 1111 - memcpy(dev->dev_addr, ax25_test, AX25_ADDR_LEN); 1112 - 1113 - /* New-style flags. */ 1114 - dev->flags = IFF_BROADCAST | IFF_MULTICAST; 1115 - 1116 - return 0; 1117 - } 1118 - 1119 - 1120 - /* ******************************************************************** */ 1121 - /* * Init MKISS driver * */ 1122 - /* ******************************************************************** */ 637 + static char banner[] __initdata = KERN_INFO \ 638 + "mkiss: AX.25 Multikiss, Hans Albas PE1AYX\n"; 639 + static char msg_regfail[] __initdata = KERN_ERR \ 640 + "mkiss: can't register line discipline (err = %d)\n"; 1123 641 1124 642 static int __init mkiss_init_driver(void) 1125 643 { ··· 885 887 886 888 printk(banner); 887 889 888 - if (ax25_maxdev < 4) 889 - ax25_maxdev = 4; /* Sanity */ 890 + if ((status = tty_register_ldisc(N_AX25, &ax_ldisc)) != 0) 891 + printk(msg_regfail); 890 892 891 - if ((ax25_ctrls = kmalloc(sizeof(void *) * ax25_maxdev, GFP_KERNEL)) == NULL) { 892 - printk(KERN_ERR "mkiss: Can't allocate ax25_ctrls[] array!\n"); 893 - return -ENOMEM; 894 - } 895 - 896 - /* Clear the pointer array, we allocate devices when we need them */ 897 - memset(ax25_ctrls, 0, sizeof(void*) * ax25_maxdev); /* Pointers */ 898 - 899 - /* Fill in our line protocol discipline, and register it */ 900 - ax_ldisc.magic = TTY_LDISC_MAGIC; 901 - ax_ldisc.name = "mkiss"; 902 - ax_ldisc.open = ax25_open; 903 - ax_ldisc.close = ax25_close; 904 - ax_ldisc.ioctl = (int (*)(struct tty_struct *, struct file *, 905 - unsigned int, unsigned long))ax25_disp_ioctl; 906 - ax_ldisc.receive_buf = ax25_receive_buf; 907 - ax_ldisc.receive_room = ax25_receive_room; 908 - ax_ldisc.write_wakeup = ax25_write_wakeup; 909 - 910 - if ((status = tty_register_ldisc(N_AX25, &ax_ldisc)) != 0) { 911 - printk(KERN_ERR "mkiss: can't register line discipline (err = %d)\n", status); 912 - kfree(ax25_ctrls); 913 - } 914 893 return status; 915 894 } 916 895 896 + static const char msg_unregfail[] __exitdata = KERN_ERR \ 897 + "mkiss: can't unregister line discipline (err = %d)\n"; 898 + 917 899 static void __exit mkiss_exit_driver(void) 918 900 { 919 - int i; 901 + int ret; 920 902 921 - for (i = 0; i < ax25_maxdev; i++) { 922 - if (ax25_ctrls[i]) { 923 - /* 924 - * VSV = if dev->start==0, then device 925 - * unregistered while close proc. 926 - */ 927 - if (netif_running(&ax25_ctrls[i]->dev)) 928 - unregister_netdev(&ax25_ctrls[i]->dev); 929 - kfree(ax25_ctrls[i]); 930 - } 931 - } 932 - 933 - kfree(ax25_ctrls); 934 - ax25_ctrls = NULL; 935 - 936 - if ((i = tty_unregister_ldisc(N_AX25))) 937 - printk(KERN_ERR "mkiss: can't unregister line discipline (err = %d)\n", i); 903 + if ((ret = tty_unregister_ldisc(N_AX25))) 904 + printk(msg_unregfail, ret); 938 905 } 939 906 940 - MODULE_AUTHOR("Hans Albas PE1AYX <hans@esrac.ele.tue.nl>"); 907 + MODULE_AUTHOR("Ralf Baechle DL5RB <ralf@linux-mips.org>"); 941 908 MODULE_DESCRIPTION("KISS driver for AX.25 over TTYs"); 942 - MODULE_PARM(ax25_maxdev, "i"); 943 - MODULE_PARM_DESC(ax25_maxdev, "number of MKISS devices"); 944 909 MODULE_LICENSE("GPL"); 945 910 MODULE_ALIAS_LDISC(N_AX25); 911 + 946 912 module_init(mkiss_init_driver); 947 913 module_exit(mkiss_exit_driver); 948 -