00001 /* 00002 * File Name : kbdattach.c 00003 * 00004 * Description: Keyboard Driver line discipline attach program 00005 */ 00006 00007 /* 00008 * This file is part of kbdattach. 00009 * 00010 * kbdattach is free software: you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation, either version 2 of the License, or 00013 * (at your option) any later version. 00014 * 00015 * kbdattach is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 * GNU General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU General Public License 00021 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00022 */ 00023 00024 /** 00025 * Copyright (C) 2008 iRex Technologies B.V. 00026 * All rights reserved. 00027 * 00028 * Based on inputattach.c by Vojtech Pavlik 00029 */ 00030 00031 //---------------------------------------------------------------------------- 00032 // Include Files 00033 //---------------------------------------------------------------------------- 00034 00035 // system include files, between < > 00036 #include <linux/serio.h> 00037 00038 #include <sys/types.h> 00039 #include <sys/ioctl.h> 00040 00041 #include <stdio.h> 00042 #include <stdlib.h> 00043 #include <unistd.h> 00044 #include <fcntl.h> 00045 #include <termios.h> 00046 00047 00048 //---------------------------------------------------------------------------- 00049 // Type Declarations 00050 //---------------------------------------------------------------------------- 00051 00052 00053 //---------------------------------------------------------------------------- 00054 // Global Constants 00055 //---------------------------------------------------------------------------- 00056 00057 #define ION_LDISC N_MOUSE 00058 #define ION_SERIO_TYPE SERIO_STOWAWAY 00059 #define ION_SERIO_FLAGS CS8 00060 #define ION_SERIO_SPEED B115200 00061 00062 00063 //---------------------------------------------------------------------------- 00064 // Static Variables 00065 //---------------------------------------------------------------------------- 00066 00067 00068 //============================================================================ 00069 // Local Function Definitions 00070 //============================================================================ 00071 00072 /* static int readchar(int fd, unsigned char *c, int timeout); */ 00073 static void setline(int fd, int flags, int speed); 00074 00075 //============================================================================ 00076 // Functions Implementation 00077 //============================================================================ 00078 00079 int main(int argc, char **argv) 00080 { 00081 unsigned long devt; 00082 int ldisc; 00083 int fd; 00084 00085 // open device 00086 if ((fd = open(argv[1], O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0) { 00087 fprintf(stderr, "kbdattach: can't open device\n"); 00088 return 1; 00089 } 00090 00091 // set speed and flags 00092 setline(fd, ION_SERIO_FLAGS, ION_SERIO_SPEED); 00093 00094 // flush input junk 00095 // while (!readchar(fd, &c, 100)); 00096 // do device init if required 00097 00098 // set line discipline 00099 ldisc = ION_LDISC; 00100 if(ioctl(fd, TIOCSETD, &ldisc)) { 00101 fprintf(stderr, "kbdattach: can't set line discipline\n"); 00102 return 1; 00103 } 00104 00105 // set device type 00106 devt = ION_SERIO_TYPE; 00107 if(ioctl(fd, SPIOCSTYPE, &devt)) { 00108 fprintf(stderr, "kbdattach: can't set device type\n"); 00109 return 1; 00110 } 00111 00112 daemon(0,0); 00113 00114 read(fd, NULL, 0); 00115 00116 // reset line discipline 00117 ldisc = 0; 00118 ioctl(fd, TIOCSETD, &ldisc); 00119 close(fd); 00120 00121 return 0; 00122 } 00123 00124 00125 /* 00126 static int readchar(int fd, unsigned char *c, int timeout) 00127 { 00128 struct timeval tv; 00129 fd_set set; 00130 00131 tv.tv_sec = 0; 00132 tv.tv_usec = timeout * 1000; 00133 00134 FD_ZERO(&set); 00135 FD_SET(fd, &set); 00136 00137 if (!select(fd+1, &set, NULL, NULL, &tv)) return -1; 00138 if (read(fd, c, 1) != 1) return -1; 00139 00140 return 0; 00141 } 00142 */ 00143 00144 00145 static void setline(int fd, int flags, int speed) 00146 { 00147 struct termios t; 00148 00149 tcgetattr(fd, &t); 00150 00151 t.c_cflag = flags | CREAD | HUPCL | CLOCAL; 00152 t.c_iflag = IGNBRK | IGNPAR; 00153 t.c_oflag = 0; 00154 t.c_lflag = 0; 00155 t.c_cc[VMIN ] = 1; 00156 t.c_cc[VTIME] = 0; 00157 00158 cfsetispeed(&t, speed); 00159 cfsetospeed(&t, speed); 00160 00161 tcsetattr(fd, TCSANOW, &t); 00162 }