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

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

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

** Warning: Cannot open xref database.

1 #include <stdio.h> 2 #include <unistd.h> 3 #include <stdlib.h> 4 #include <fcntl.h> 5 #include <termios.h> 6 #include <wait.h> 7 #include <signal.h> 8 #include <sched.h> 9 #include <errno.h> 10 #include <sys/socket.h> 11 #include <sys/ioctl.h> 12 #include <sys/vfs.h> 13 #include "umn.h" 14 #include "user_util.h" 15 #include "kern_util.h" 16 #include "user.h" 17 18 extern char *ptsname(int); 19 20 char buff[3000]; 21 22 /* SLIP protocol characters. */ 23 #define END 0300 /* indicates end of frame */ 24 #define ESC 0333 /* indicates byte stuffing */ 25 #define ESC_END 0334 /* ESC ESC_END means END 'data' */ 26 #define ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */ 27 28 static int slip_esc(unsigned char *s, unsigned char *d, int len) 29 { 30 unsigned char *ptr = d; 31 unsigned char c; 32 33 /* 34 * Send an initial END character to flush out any 35 * data that may have accumulated in the receiver 36 * due to line noise. 37 */ 38 39 *ptr++ = END; 40 41 /* 42 * For each byte in the packet, send the appropriate 43 * character sequence, according to the SLIP protocol. 44 */ 45 46 while (len-- > 0) { 47 switch(c = *s++) { 48 case END: 49 *ptr++ = ESC; 50 *ptr++ = ESC_END; 51 break; 52 case ESC: 53 *ptr++ = ESC; 54 *ptr++ = ESC_ESC; 55 break; 56 default: 57 *ptr++ = c; 58 break; 59 } 60 } 61 *ptr++ = END; 62 return (ptr - d); 63 } 64 65 int umn_send_packet(int fd, void *data, int len) 66 { 67 int actual, n; 68 69 actual = slip_esc(data, buff, len); 70 n = write(fd, buff, actual); 71 if(n == actual) return(0); 72 else return(1); 73 } 74 75 static void umn_read(int fd) 76 { 77 int i, n; 78 79 n = read(fd, buff, sizeof(buff)/sizeof(buff[0])); 80 if(n == 0) printk("umn_read hit EOF\n"); 81 else if(n < 0){ 82 if(errno == EIO){ 83 close(fd); 84 return; 85 } 86 printk("umn_read had error, errno = %d\n", errno); 87 } 88 else { 89 for(i=0;i<n;i++) 90 slip_unesc(buff[i]); 91 } 92 } 93 94 static int set_up_tty(int fd) 95 { 96 int i; 97 struct termios tios; 98 99 if (tcgetattr(fd, &tios) < 0) { 100 printk("could not get initial terminal attributes\n"); 101 return(-1); 102 } 103 104 tios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL; 105 tios.c_iflag = IGNBRK | IGNPAR; 106 tios.c_oflag = 0; 107 tios.c_lflag = 0; 108 for (i = 0; i < NCCS; i++) 109 tios.c_cc[i] = 0; 110 tios.c_cc[VMIN] = 1; 111 tios.c_cc[VTIME] = 0; 112 113 cfsetospeed(&tios, B38400); 114 cfsetispeed(&tios, B38400); 115 116 if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) { 117 printk("failed to set terminal attributes\n"); 118 return(-1); 119 } 120 return(0); 121 } 122 123 static int run_ifconfig(int (*proc)(void *), void *arg) 124 { 125 unsigned long stack; 126 int pid, status; 127 128 stack = alloc_stack(); 129 pid = clone(proc, (void *) stack_sp(stack), SIGCHLD, arg); 130 if(pid < 0){ 131 printk("clone of ifconfig failed\n"); 132 return(-1); 133 } 134 pid = waitpid(pid, &status, 0); 135 if(pid < 0){ 136 printk("wait for um_ifconfig failed\n"); 137 return(-1); 138 } 139 if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){ 140 printk("um_ifconfig failed\n"); 141 return(-1); 142 } 143 free_stack(stack); 144 return(0); 145 } 146 147 int open_umn_tty(int *orig_disc_out, int *slave_out, int *slipno_out) 148 { 149 struct statfs buf; 150 int sfd, mfd, disc, sencap, n; 151 char slip_name[sizeof("slxxxx")]; 152 153 if((mfd = open("/dev/ptmx", O_RDWR)) < 0){ 154 printk("Couldn't open tty for slip line\n"); 155 return(-1); 156 } 157 if(statfs(ptsname(mfd), &buf) < 0){ 158 printk("statfs failed\n"); 159 return(-1); 160 } 161 if(unlockpt(mfd) < 0){ 162 printk("Couldn't open tty for slip line\n"); 163 return(-1); 164 } 165 if((sfd = open(ptsname(mfd), O_RDWR)) < 0){ 166 printk("Couldn't open tty for slip line\n"); 167 return(-1); 168 } 169 if(set_up_tty(sfd)) return(-1); 170 disc = N_SLIP; 171 sencap = 0; 172 if((ioctl(sfd, TIOCGETD, &orig_disc_out) < 0) || 173 ((n = ioctl(sfd, TIOCSETD, &disc)) < 0) || 174 (ioctl(sfd, SIOCSIFENCAP, &sencap) < 0)){ 175 printk("Couldn't set up slip\n"); 176 return(-1); 177 } 178 sprintf(slip_name, "sl%d", n); 179 add_input_request(INPUT_NEW_FD, mfd, umn_read); 180 *slave_out = sfd; 181 *slipno_out = n; 182 return(mfd); 183 } 184 185 static int ifconfig_addr_tramp(void *arg) 186 { 187 char *args[] = { "um_ifconfig", "-n", NULL, "192.168.0.254", 188 "pointopoint", NULL, NULL }; 189 char **more_args; 190 191 more_args = arg; 192 args[2] = more_args[0]; 193 args[5] = more_args[1]; 194 execvp("um_ifconfig", args); 195 return(-1); 196 } 197 198 int set_umn_addr(int slipno, char *addr) 199 { 200 char slip_name[sizeof("slxxxx")], *args[2]; 201 202 sprintf(slip_name, "sl%d", slipno); 203 args[0] = slip_name; 204 args[1] = addr; 205 return(run_ifconfig(ifconfig_addr_tramp, args)); 206 } 207 208 void close_umn_tty(int master, int slave, int orig_disc) 209 { 210 ioctl(slave, TIOCSETD, &orig_disc); 211 close(slave); 212 close(master); 213 } 214 215

~ [ 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.