1 /* 2 * QEMU System Emulator 3 * 4 * Copyright (c) 2003-2008 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24 25 #include "qemu/osdep.h" 26 #include "qemu/module.h" 27 #include "qemu/option.h" 28 #include "qemu/sockets.h" 29 #include "io/channel-file.h" 30 #include "qapi/error.h" 31 32 #ifdef _WIN32 33 #include "chardev/char-win.h" 34 #else 35 #include <sys/ioctl.h> 36 #include <termios.h> 37 #include "chardev/char-fd.h" 38 #endif 39 40 #include "chardev/char-serial.h" 41 42 #ifdef _WIN32 43 44 static void qmp_chardev_open_serial(Chardev *chr, 45 ChardevBackend *backend, 46 bool *be_opened, 47 Error **errp) 48 { 49 ChardevHostdev *serial = backend->u.serial.data; 50 51 win_chr_serial_init(chr, serial->device, errp); 52 } 53 54 #elif defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \ 55 || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) \ 56 || defined(__GLIBC__) || defined(__APPLE__) 57 58 static void tty_serial_init(int fd, int speed, 59 int parity, int data_bits, int stop_bits) 60 { 61 struct termios tty = {0}; 62 speed_t spd; 63 64 #if 0 65 printf("tty_serial_init: speed=%d parity=%c data=%d stop=%d\n", 66 speed, parity, data_bits, stop_bits); 67 #endif 68 tcgetattr(fd, &tty); 69 70 #define check_speed(val) \ 71 if (speed <= val) { \ 72 spd = B##val; \ 73 goto done; \ 74 } 75 76 speed = speed * 10 / 11; 77 check_speed(50); 78 check_speed(75); 79 check_speed(110); 80 check_speed(134); 81 check_speed(150); 82 check_speed(200); 83 check_speed(300); 84 check_speed(600); 85 check_speed(1200); 86 check_speed(1800); 87 check_speed(2400); 88 check_speed(4800); 89 check_speed(9600); 90 check_speed(19200); 91 check_speed(38400); 92 /* Non-Posix values follow. They may be unsupported on some systems. */ 93 check_speed(57600); 94 check_speed(115200); 95 #ifdef B230400 96 check_speed(230400); 97 #endif 98 #ifdef B460800 99 check_speed(460800); 100 #endif 101 #ifdef B500000 102 check_speed(500000); 103 #endif 104 #ifdef B576000 105 check_speed(576000); 106 #endif 107 #ifdef B921600 108 check_speed(921600); 109 #endif 110 #ifdef B1000000 111 check_speed(1000000); 112 #endif 113 #ifdef B1152000 114 check_speed(1152000); 115 #endif 116 #ifdef B1500000 117 check_speed(1500000); 118 #endif 119 #ifdef B2000000 120 check_speed(2000000); 121 #endif 122 #ifdef B2500000 123 check_speed(2500000); 124 #endif 125 #ifdef B3000000 126 check_speed(3000000); 127 #endif 128 #ifdef B3500000 129 check_speed(3500000); 130 #endif 131 #ifdef B4000000 132 check_speed(4000000); 133 #endif 134 spd = B115200; 135 136 #undef check_speed 137 done: 138 cfsetispeed(&tty, spd); 139 cfsetospeed(&tty, spd); 140 141 tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP 142 | INLCR | IGNCR | ICRNL | IXON); 143 tty.c_oflag &= ~OPOST; 144 tty.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG); 145 tty.c_cflag &= ~(CSIZE | PARENB | PARODD | CRTSCTS | CSTOPB); 146 switch (data_bits) { 147 default: 148 case 8: 149 tty.c_cflag |= CS8; 150 break; 151 case 7: 152 tty.c_cflag |= CS7; 153 break; 154 case 6: 155 tty.c_cflag |= CS6; 156 break; 157 case 5: 158 tty.c_cflag |= CS5; 159 break; 160 } 161 switch (parity) { 162 default: 163 case 'N': 164 break; 165 case 'E': 166 tty.c_cflag |= PARENB; 167 break; 168 case 'O': 169 tty.c_cflag |= PARENB | PARODD; 170 break; 171 } 172 if (stop_bits == 2) { 173 tty.c_cflag |= CSTOPB; 174 } 175 176 tcsetattr(fd, TCSANOW, &tty); 177 } 178 179 static int tty_serial_ioctl(Chardev *chr, int cmd, void *arg) 180 { 181 FDChardev *s = FD_CHARDEV(chr); 182 QIOChannelFile *fioc = QIO_CHANNEL_FILE(s->ioc_in); 183 184 switch (cmd) { 185 case CHR_IOCTL_SERIAL_SET_PARAMS: 186 { 187 QEMUSerialSetParams *ssp = arg; 188 tty_serial_init(fioc->fd, 189 ssp->speed, ssp->parity, 190 ssp->data_bits, ssp->stop_bits); 191 } 192 break; 193 case CHR_IOCTL_SERIAL_SET_BREAK: 194 { 195 int enable = *(int *)arg; 196 if (enable) { 197 tcsendbreak(fioc->fd, 1); 198 } 199 } 200 break; 201 case CHR_IOCTL_SERIAL_GET_TIOCM: 202 { 203 int sarg = 0; 204 int *targ = (int *)arg; 205 ioctl(fioc->fd, TIOCMGET, &sarg); 206 *targ = 0; 207 if (sarg & TIOCM_CTS) { 208 *targ |= CHR_TIOCM_CTS; 209 } 210 if (sarg & TIOCM_CAR) { 211 *targ |= CHR_TIOCM_CAR; 212 } 213 if (sarg & TIOCM_DSR) { 214 *targ |= CHR_TIOCM_DSR; 215 } 216 if (sarg & TIOCM_RI) { 217 *targ |= CHR_TIOCM_RI; 218 } 219 if (sarg & TIOCM_DTR) { 220 *targ |= CHR_TIOCM_DTR; 221 } 222 if (sarg & TIOCM_RTS) { 223 *targ |= CHR_TIOCM_RTS; 224 } 225 } 226 break; 227 case CHR_IOCTL_SERIAL_SET_TIOCM: 228 { 229 int sarg = *(int *)arg; 230 int targ = 0; 231 ioctl(fioc->fd, TIOCMGET, &targ); 232 targ &= ~(CHR_TIOCM_CTS | CHR_TIOCM_CAR | CHR_TIOCM_DSR 233 | CHR_TIOCM_RI | CHR_TIOCM_DTR | CHR_TIOCM_RTS); 234 if (sarg & CHR_TIOCM_CTS) { 235 targ |= TIOCM_CTS; 236 } 237 if (sarg & CHR_TIOCM_CAR) { 238 targ |= TIOCM_CAR; 239 } 240 if (sarg & CHR_TIOCM_DSR) { 241 targ |= TIOCM_DSR; 242 } 243 if (sarg & CHR_TIOCM_RI) { 244 targ |= TIOCM_RI; 245 } 246 if (sarg & CHR_TIOCM_DTR) { 247 targ |= TIOCM_DTR; 248 } 249 if (sarg & CHR_TIOCM_RTS) { 250 targ |= TIOCM_RTS; 251 } 252 ioctl(fioc->fd, TIOCMSET, &targ); 253 } 254 break; 255 default: 256 return -ENOTSUP; 257 } 258 return 0; 259 } 260 261 static void qmp_chardev_open_serial(Chardev *chr, 262 ChardevBackend *backend, 263 bool *be_opened, 264 Error **errp) 265 { 266 ChardevHostdev *serial = backend->u.serial.data; 267 int fd; 268 269 fd = qmp_chardev_open_file_source(serial->device, O_RDWR | O_NONBLOCK, 270 errp); 271 if (fd < 0) { 272 return; 273 } 274 if (!g_unix_set_fd_nonblocking(fd, true, NULL)) { 275 error_setg_errno(errp, errno, "Failed to set FD nonblocking"); 276 return; 277 } 278 tty_serial_init(fd, 115200, 'N', 8, 1); 279 280 qemu_chr_open_fd(chr, fd, fd); 281 } 282 #endif /* __linux__ || __sun__ */ 283 284 #ifdef HAVE_CHARDEV_SERIAL 285 static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend, 286 Error **errp) 287 { 288 const char *device = qemu_opt_get(opts, "path"); 289 ChardevHostdev *serial; 290 291 if (device == NULL) { 292 error_setg(errp, "chardev: serial/tty: no device path given"); 293 return; 294 } 295 backend->type = CHARDEV_BACKEND_KIND_SERIAL; 296 serial = backend->u.serial.data = g_new0(ChardevHostdev, 1); 297 qemu_chr_parse_common(opts, qapi_ChardevHostdev_base(serial)); 298 serial->device = g_strdup(device); 299 } 300 301 static void char_serial_class_init(ObjectClass *oc, void *data) 302 { 303 ChardevClass *cc = CHARDEV_CLASS(oc); 304 305 cc->parse = qemu_chr_parse_serial; 306 cc->open = qmp_chardev_open_serial; 307 #ifndef _WIN32 308 cc->chr_ioctl = tty_serial_ioctl; 309 #endif 310 } 311 312 313 static const TypeInfo char_serial_type_info = { 314 .name = TYPE_CHARDEV_SERIAL, 315 #ifdef _WIN32 316 .parent = TYPE_CHARDEV_WIN, 317 #else 318 .parent = TYPE_CHARDEV_FD, 319 #endif 320 .class_init = char_serial_class_init, 321 }; 322 323 static void register_types(void) 324 { 325 type_register_static(&char_serial_type_info); 326 } 327 328 type_init(register_types); 329 330 #endif 331