~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/arch/um/drivers/umn_kern.c

Version: ~ [ 0.6-2.3.46 ] ~
Architecture: ~ [ um ] ~

** Warning: Cannot open xref database.

1 #include "linux/init.h" 2 #include "linux/netdevice.h" 3 #include "linux/skbuff.h" 4 #include "linux/if_arp.h" 5 #include "linux/init.h" 6 #include "umn.h" 7 #include "user_util.h" 8 #include "kern_util.h" 9 10 struct umn { 11 int used; 12 int tty_fd; 13 int slave; 14 int orig_disc; 15 int slipno; 16 int rcount; 17 int esc; 18 char rbuff[3000]; 19 int buffsize; 20 struct net_device dev; 21 }; 22 23 struct umn umn = { 0, -1, -1, -1 }; 24 25 static int xmit(struct sk_buff *skb, struct net_device *dev) 26 { 27 return(umn_send_packet(umn.tty_fd, skb->data, skb->len)); 28 } 29 30 void umn_rcv(char *data, int len) 31 { 32 struct sk_buff *skb; 33 34 skb = dev_alloc_skb(len); 35 memcpy(skb_put(skb, len), data, len); 36 skb->mac.raw = skb->data; 37 skb->dev = &umn.dev; 38 skb->protocol = htons(ETH_P_IP); 39 netif_rx(skb); 40 } 41 42 /* SLIP protocol characters. */ 43 #define END 0300 /* indicates end of frame */ 44 #define ESC 0333 /* indicates byte stuffing */ 45 #define ESC_END 0334 /* ESC ESC_END means END 'data' */ 46 #define ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */ 47 48 void slip_unesc(unsigned char s) 49 { 50 51 switch(s) { 52 case END: 53 if (umn.rcount > 2) { 54 umn_rcv(umn.rbuff, umn.rcount); 55 } 56 umn.esc = 0; 57 umn.rcount = 0; 58 return; 59 60 case ESC: 61 umn.esc = 1; 62 return; 63 case ESC_ESC: 64 if(umn.esc){ 65 umn.esc = 0; 66 s = ESC; 67 } 68 break; 69 case ESC_END: 70 if(umn.esc){ 71 umn.esc = 0; 72 s = END; 73 } 74 break; 75 } 76 if (umn.rcount < umn.buffsize) { 77 umn.rbuff[umn.rcount++] = s; 78 return; 79 } 80 printk("umn receive overflow\n"); 81 } 82 83 spinlock_t umn_lock = SPIN_LOCK_UNLOCKED; 84 85 static int open(struct net_device *dev) 86 { 87 spin_lock(&umn_lock); 88 if(umn.used){ 89 spin_unlock(&umn_lock); 90 return(-ENXIO); 91 } 92 umn.used = 1; 93 spin_unlock(&umn_lock); 94 umn.tty_fd = open_umn_tty(&umn.orig_disc, &umn.slave, &umn.slipno); 95 umn.rcount = 0; 96 umn.esc = 0; 97 umn.buffsize = sizeof(umn.rbuff)/sizeof(umn.rbuff[0]); 98 if(umn.tty_fd == -1) return(-1); 99 else return(0); 100 } 101 102 static int close (struct net_device *dev) 103 { 104 spin_lock(&umn_lock); 105 if(!umn.used){ 106 spin_unlock(&umn_lock); 107 return(-ENXIO); 108 } 109 umn.used = 0; 110 spin_unlock(&umn_lock); 111 close_umn_tty(umn.tty_fd, umn.slave, umn.orig_disc); 112 return(0); 113 } 114 115 static int ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) 116 { 117 printk("umn ioctl = %d\n", cmd); 118 if((cmd >= SIOCDEVPRIVATE) && (cmd <= SIOCDEVPRIVATE + 15)) 119 return(-EOPNOTSUPP); 120 KERN_UNTESTED(); 121 return(-EOPNOTSUPP); 122 } 123 124 static int set_addr(struct net_device *dev, void *addr) 125 { 126 struct sockaddr *sa; 127 char in_addr[sizeof("255.255.255.255")]; 128 unsigned char *eth_addr; 129 130 sa = addr; 131 eth_addr = (unsigned char *) sa->sa_data; 132 sprintf(in_addr, "%d.%d.%d.%d", eth_addr[0], eth_addr[1], eth_addr[2], 133 eth_addr[3]); 134 return(set_umn_addr(umn.slipno, in_addr)); 135 } 136 137 static int init_dev(struct net_device *dev) 138 { 139 dev->mtu = 1500; 140 dev->hard_start_xmit = xmit; 141 dev->open = open; 142 dev->stop = close; 143 dev->get_stats = NULL; 144 dev->do_ioctl = ioctl; 145 dev->hard_header_len = 0; 146 dev->addr_len = 4; 147 dev->type = ARPHRD_ETHER; 148 dev->tx_queue_len = 256; 149 dev->set_mac_address = set_addr; 150 dev_init_buffers(dev); 151 dev->flags = IFF_NOARP; 152 return 0; 153 } 154 155 int __init umn_init(void) 156 { 157 struct net_device *d; 158 159 d = &umn.dev; 160 d->name = "umn"; 161 d->init = init_dev; 162 if(register_netdev(d)) 163 printk("Couldn't initialize umn\n"); 164 return(0); 165 } 166 __initcall(umn_init); 167

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.