?? setserial.c
字號:
/* setserial.c - get/set Linux serial port info - rick sladkey *//* modified to do work again and added setting fast serial speeds, Michael K. Johnson, johnsonm@stolaf.edu *//* * Very heavily modified --- almost rewritten from scratch --- to have * a more flexible command structure. Now able to set any of the * serial-specific options using the TIOCSSERIAL ioctl(). * Theodore Ts'o, tytso@mit.edu, 1/1/93 * * Last modified: [tytso:19940520.0036EDT] */#include <stdio.h>#include <fcntl.h>#include <termios.h>#include <string.h>#include <errno.h>#ifdef HAVE_ASM_IOCTLS_H#include <asm/ioctls.h>#endif#ifdef HAVE_LINUX_HAYESESP_H#include <linux/hayesesp.h>#endif#include <linux/serial.h>#include "version.h"static char version_str[] = "setserial version " SETSERIAL_VERSION ", " SETSERIAL_DATE;char *progname;int verbosity = 1; /* 1 = normal, 0=boot-time, 2=everything */ /* -1 == arguments to setserial */int verbose_flag = 0; /* print results after setting a port */int quiet_flag = 0;int zero_flag = 0;struct serial_type_struct { int id; char *name;} serial_type_tbl[] = { PORT_UNKNOWN, "unknown", PORT_8250, "8250", PORT_16450, "16450", PORT_16550, "16550", PORT_16550A, "16550A", PORT_CIRRUS, "Cirrus", PORT_16650, "16650", PORT_16650V2, "16650V2", PORT_16750, "16750", PORT_16C950, "16950/954", PORT_16C950, "16950", PORT_16C950, "16954", PORT_16654, "16654", PORT_16850, "16850", PORT_UNKNOWN, "none", -1, NULL};#define CMD_FLAG 1#define CMD_PORT 2#define CMD_IRQ 3#define CMD_DIVISOR 4#define CMD_TYPE 5#define CMD_BASE 6#define CMD_DELAY 7#define CMD_WAIT 8#define CMD_WAIT2 9#define CMD_CONFIG 10#define CMD_GETMULTI 11#define CMD_SETMULTI 12#define CMD_RX_TRIG 13#define CMD_TX_TRIG 14#define CMD_FLOW_OFF 15#define CMD_FLOW_ON 16#define CMD_RX_TMOUT 17#define CMD_DMA_CHAN 18#define FLAG_CAN_INVERT 0x0001#define FLAG_NEED_ARG 0x0002struct flag_type_table { int cmd; char *name; int bits; int mask; int level; int flags;} flag_type_tbl[] = { CMD_FLAG, "spd_normal", 0, ASYNC_SPD_MASK, 2, 0, CMD_FLAG, "spd_hi", ASYNC_SPD_HI, ASYNC_SPD_MASK, 0, 0, CMD_FLAG, "spd_vhi", ASYNC_SPD_VHI, ASYNC_SPD_MASK, 0, 0, CMD_FLAG, "spd_shi", ASYNC_SPD_SHI, ASYNC_SPD_MASK, 0, 0, CMD_FLAG, "spd_warp", ASYNC_SPD_WARP, ASYNC_SPD_MASK, 0, 0, CMD_FLAG, "spd_cust", ASYNC_SPD_CUST, ASYNC_SPD_MASK, 0, 0, CMD_FLAG, "SAK", ASYNC_SAK, ASYNC_SAK, 0, FLAG_CAN_INVERT, CMD_FLAG, "Fourport", ASYNC_FOURPORT, ASYNC_FOURPORT, 0, FLAG_CAN_INVERT, CMD_FLAG, "hup_notify", ASYNC_HUP_NOTIFY, ASYNC_HUP_NOTIFY, 0, FLAG_CAN_INVERT, CMD_FLAG, "skip_test", ASYNC_SKIP_TEST,ASYNC_SKIP_TEST,2, FLAG_CAN_INVERT, CMD_FLAG, "auto_irq", ASYNC_AUTO_IRQ, ASYNC_AUTO_IRQ, 2, FLAG_CAN_INVERT, CMD_FLAG, "split_termios", ASYNC_SPLIT_TERMIOS, ASYNC_SPLIT_TERMIOS, 2, FLAG_CAN_INVERT, CMD_FLAG, "session_lockout", ASYNC_SESSION_LOCKOUT, ASYNC_SESSION_LOCKOUT, 2, FLAG_CAN_INVERT, CMD_FLAG, "pgrp_lockout", ASYNC_PGRP_LOCKOUT, ASYNC_PGRP_LOCKOUT, 2, FLAG_CAN_INVERT, CMD_FLAG, "callout_nohup", ASYNC_CALLOUT_NOHUP, ASYNC_CALLOUT_NOHUP, 2, FLAG_CAN_INVERT, CMD_FLAG, "low_latency", ASYNC_LOW_LATENCY, ASYNC_LOW_LATENCY, 0, FLAG_CAN_INVERT, CMD_PORT, "port", 0, 0, 0, FLAG_NEED_ARG, CMD_IRQ, "irq", 0, 0, 0, FLAG_NEED_ARG, CMD_DIVISOR, "divisor", 0, 0, 0, FLAG_NEED_ARG, CMD_TYPE, "uart", 0, 0, 0, FLAG_NEED_ARG, CMD_BASE, "base", 0, 0, 0, FLAG_NEED_ARG, CMD_BASE, "baud_base", 0, 0, 0, FLAG_NEED_ARG, CMD_DELAY, "close_delay", 0, 0, 0, FLAG_NEED_ARG, CMD_WAIT, "closing_wait", 0, 0, 0, FLAG_NEED_ARG, CMD_CONFIG, "autoconfig", 0, 0, 0, 0, CMD_CONFIG, "autoconfigure",0, 0, 0, 0, CMD_GETMULTI, "get_multiport",0, 0, 0, 0, CMD_SETMULTI, "set_multiport",0, 0, 0, 0,#ifdef TIOCGHAYESESP CMD_RX_TRIG, "rx_trigger", 0, 0, 0, FLAG_NEED_ARG, CMD_TX_TRIG, "tx_trigger", 0, 0, 0, FLAG_NEED_ARG, CMD_FLOW_OFF, "flow_off", 0, 0, 0, FLAG_NEED_ARG, CMD_FLOW_ON, "flow_on", 0, 0, 0, FLAG_NEED_ARG, CMD_RX_TMOUT, "rx_timeout", 0, 0, 0, FLAG_NEED_ARG, CMD_DMA_CHAN, "dma_channel", 0, 0, 0, FLAG_NEED_ARG,#endif 0, 0, 0, 0, 0, 0,}; char *serial_type(int id){ int i; for (i = 0; serial_type_tbl[i].id != -1; i++) if (id == serial_type_tbl[i].id) return serial_type_tbl[i].name; return "undefined";}int uart_type(char *name){ int i; for (i = 0; serial_type_tbl[i].id != -1; i++) if (!strcasecmp(name, serial_type_tbl[i].name)) return serial_type_tbl[i].id; return -1;}int atonum(char *s){ int n; while (*s == ' ') s++; if (strncmp(s, "0x", 2) == 0 || strncmp(s, "0X", 2) == 0) sscanf(s + 2, "%x", &n); else if (s[0] == '0' && s[1]) sscanf(s + 1, "%o", &n); else sscanf(s, "%d", &n); return n;}void print_flags(struct serial_struct *serinfo, char *prefix, char *postfix){ struct flag_type_table *p; int flags; int first = 1; flags = serinfo->flags; for (p = flag_type_tbl; p->name; p++) { if (p->cmd != CMD_FLAG) continue; if (verbosity == -1) { if ((flags & p->mask) == p->bits) printf(" %s", p->name); continue; } if (verbosity < p->level) continue; if ((flags & p->mask) == p->bits) { if (first) { printf("%s", prefix); first = 0; } else printf(" "); printf("%s", p->name); } } if (!first) printf("%s", postfix);}#ifdef TIOCSERGETMULTIvoid print_multiport(char *device, int fd){ struct serial_multiport_struct multi; if (ioctl(fd, TIOCSERGETMULTI, &multi) < 0) return; if (!multi.port1 && !multi.port2 && !multi.port3 && !multi.port4 && !multi.port_monitor) return; printf("%s", device); if (multi.port_monitor) printf(" port_monitor 0x%x", multi.port_monitor); if (multi.port1) printf(" port1 0x%x mask1 0x%x match1 0x%x", multi.port1, multi.mask1, multi.match1); if (multi.port2) printf(" port2 0x%x mask2 0x%x match2 0x%x", multi.port2, multi.mask2, multi.match2); if (multi.port3) printf(" port3 0x%x mask3 0x%x match3 0x%x", multi.port3, multi.mask3, multi.match3); if (multi.port4) printf(" port4 0x%x mask4 0x%x match4 0x%x", multi.port4, multi.mask4, multi.match4); printf("\n");}void multiport_usage(){ fprintf(stderr, "\nValid keywords after set_multiport are:\n"); fprintf(stderr, "\tport_monitor, port[1-4], mask[1-4], " "match[1-4]\n\n"); fprintf(stderr, "All arguments take an numeric argument following " "the keyword.\n"); fprintf(stderr, "Use a leading '0x' for hex numbers.\n\n");}void get_multiport(char *device, int fd){ struct serial_multiport_struct multi; if (ioctl(fd, TIOCSERGETMULTI, &multi) < 0) { perror("Cannot get multiport config"); exit(1); } printf("Multiport config for irq %d:\n", multi.irq); printf("\tPort monitor = 0x%x\n", multi.port_monitor); printf("\tPort1 = 0x%x, mask=0x%x, match=0x%x\n", multi.port1, multi.mask1, multi.match1); printf("\tPort2 = 0x%x, mask=0x%x, match=0x%x\n", multi.port2, multi.mask2, multi.match2); printf("\tPort3 = 0x%x, mask=0x%x, match=0x%x\n", multi.port3, multi.mask3, multi.match3); printf("\tPort4 = 0x%x, mask=0x%x, match=0x%x\n", multi.port4, multi.mask4, multi.match4);}void set_multiport(char *device, int fd, char ***in_arg){ char **arg = *in_arg; char *word, *argument; struct serial_multiport_struct multi; if (ioctl(fd, TIOCSERGETMULTI, &multi) < 0) { perror("Cannot get multiport config"); exit(1); } if (*arg == 0) { multiport_usage(); return; } while (*arg) { word = *arg++; if (*arg == 0) { multiport_usage(); exit(1); } argument = *arg++; if (strcasecmp(word, "port_monitor") == 0) { multi.port_monitor = atonum(argument); continue; } if (strcasecmp(word, "port1") == 0) { multi.port1 = atonum(argument); continue; } if (strcasecmp(word, "mask1") == 0) { multi.mask1 = atonum(argument); continue; } if (strcasecmp(word, "match1") == 0) { multi.match1 = atonum(argument); continue; } if (strcasecmp(word, "port2") == 0) { multi.port2 = atonum(argument); continue; } if (strcasecmp(word, "mask2") == 0) { multi.mask2 = atonum(argument); continue; } if (strcasecmp(word, "match2") == 0) { multi.match2 = atonum(argument); continue; } if (strcasecmp(word, "port3") == 0) { multi.port3 = atonum(argument); continue; } if (strcasecmp(word, "mask3") == 0) { multi.mask3 = atonum(argument); continue; } if (strcasecmp(word, "match3") == 0) { multi.match3 = atonum(argument); continue; } if (strcasecmp(word, "port4") == 0) { multi.port4 = atonum(argument); continue; } if (strcasecmp(word, "mask4") == 0) { multi.mask4 = atonum(argument); continue; } if (strcasecmp(word, "match4") == 0) { multi.match4 = atonum(argument); continue; } fprintf(stderr, "Unknown keyword %s.\n", word); multiport_usage(); exit(1); } if (ioctl(fd, TIOCSERSETMULTI, &multi) < 0) { perror("Cannot set multiport config"); exit(1); } *in_arg = arg;}#elsevoid get_multiport(char *device, int fd){ printf("Setserial was compiled under a kernel which did not\n"); printf("support the special serial multiport configs.\n");}void set_multiport(char *device, int fd, char ***in_arg){ printf("Setserial was compiled under a kernel which did not\n"); printf("support the special serial multiport configs.\n");}#endif#ifdef TIOCGHAYESESPvoid print_hayesesp(int fd){ struct hayes_esp_config esp; if (ioctl(fd, TIOCGHAYESESP, &esp) < 0) return; printf("\tHayes ESP enhanced mode configuration:\n"); printf("\t\tRX trigger level: %d, TX trigger level: %d\n", (int)esp.rx_trigger, (int)esp.tx_trigger); printf("\t\tFlow off level: %d, Flow on level: %d\n", (int)esp.flow_off, (int)esp.flow_on); printf("\t\tRX timeout: %u, DMA channel: %d\n\n", (unsigned int)esp.rx_timeout, (int)esp.dma_channel);}void set_hayesesp(int fd, int cmd, int arg){ struct hayes_esp_config esp; if (ioctl(fd, TIOCGHAYESESP, &esp) < 0) { printf("\nError: rx_trigger, tx_trigger, flow_off, " "flow_on, rx_timeout, and dma_channel\n" "are only valid for Hayes ESP ports.\n\n"); exit(1); } switch (cmd) { case CMD_RX_TRIG: esp.rx_trigger = arg; break;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -