diff options
Diffstat (limited to 'tools/serial_probe')
-rw-r--r-- | tools/serial_probe/.cvsignore | 1 | ||||
-rw-r--r-- | tools/serial_probe/Makefile | 13 | ||||
-rw-r--r-- | tools/serial_probe/device.h | 104 | ||||
-rw-r--r-- | tools/serial_probe/kudzu.h | 26 | ||||
-rw-r--r-- | tools/serial_probe/serial.c | 1136 | ||||
-rw-r--r-- | tools/serial_probe/serial.h | 43 | ||||
-rw-r--r-- | tools/serial_probe/serial_probe.c | 114 |
7 files changed, 0 insertions, 1437 deletions
diff --git a/tools/serial_probe/.cvsignore b/tools/serial_probe/.cvsignore deleted file mode 100644 index e8e3e2d94..000000000 --- a/tools/serial_probe/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -serial_probe diff --git a/tools/serial_probe/Makefile b/tools/serial_probe/Makefile deleted file mode 100644 index 86deb49f9..000000000 --- a/tools/serial_probe/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -CFLAGS = -Wall -Os -CFILES = $(wildcard *.c) -OFILES = $(CFILES:%.c=%.o) -GOAL = serial_probe - -$(GOAL): $(OFILES) - -serial.o: serial.c serial.h device.h kudzu.h -serial_probe.o: serial_probe.c serial.h device.h -serial_probe: serial_probe.o - -clean: - rm -f $(GOAL) $(OFILES) *~ diff --git a/tools/serial_probe/device.h b/tools/serial_probe/device.h deleted file mode 100644 index 58d1414a0..000000000 --- a/tools/serial_probe/device.h +++ /dev/null @@ -1,104 +0,0 @@ -/* Copyright 1999-2003 Red Hat, Inc. - * - * This software may be freely redistributed under the terms of the GNU - * public license. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - - -#ifndef _KUDZU_DEVICES_H_ -#define _KUDZU_DEVICES_H_ - -#include <stdio.h> - -enum deviceClass { - /* device classes... this is somewhat ad-hoc */ - CLASS_UNSPEC = ~0, - CLASS_OTHER = (1 << 0), - CLASS_NETWORK = (1 << 1), - CLASS_SCSI = (1 << 2), - CLASS_MOUSE = (1 << 3), - CLASS_AUDIO = (1 << 4), - CLASS_CDROM = (1 << 5), - CLASS_MODEM = (1 << 6), - CLASS_VIDEO = (1 << 7), - CLASS_TAPE = (1 << 8), - CLASS_FLOPPY = (1 << 9), - CLASS_SCANNER = (1 << 10), - CLASS_HD = (1 << 11), - CLASS_RAID = (1 << 12), - CLASS_PRINTER = (1 << 13), - CLASS_CAPTURE = (1 << 14), - CLASS_KEYBOARD = (1 << 15), - CLASS_MONITOR = (1 << 16), - CLASS_USB = (1 << 17), - CLASS_SOCKET = (1 << 18), - CLASS_FIREWIRE = (1 << 19), - CLASS_IDE = (1 << 20) -}; - -/* Update this if needed */ -#define CLASS_LAST CLASS_IDE - -enum deviceBus { - /* 'bus' that a device is attached to... this is also ad-hoc */ - /* BUS_SBUS is sort of a misnomer - it's more or less Sun */ - /* OpenPROM probing of all various associated non-PCI buses */ - BUS_UNSPEC = ~0, - BUS_OTHER = (1 << 0), - BUS_PCI = (1 << 1), - BUS_SBUS = (1 << 2), - BUS_SERIAL = (1 << 3), - BUS_PSAUX = (1 << 4), - BUS_PARALLEL = (1 << 5), - BUS_SCSI = (1 << 6), - BUS_IDE = (1 << 7), - /* Again, misnomer */ - BUS_KEYBOARD = (1 << 8), - BUS_DDC = (1 << 9), - BUS_USB = (1 << 10), - BUS_ISAPNP = (1 << 11), - BUS_MISC = (1 << 12), - BUS_FIREWIRE = (1 << 13), - BUS_PCMCIA = (1 << 14), - BUS_ADB = (1 << 15), - BUS_MACIO = (1 << 16) -}; - -struct device { - /* This pointer is used to make lists by the library. */ - /* Do not expect it to remain constant (or useful) across library calls. */ - struct device *next; - /* Used for ordering, and for aliasing (modem0, modem1, etc.) */ - int index; - enum deviceClass type; /* type */ - enum deviceBus bus; /* bus it's attached to */ - char * device; /* device file associated with it */ - char * driver; /* driver to load, if any */ - char * desc; /* a description */ - int detached; /* should we care if it disappears? */ - struct device *(*newDevice) (struct device *old, struct device *new); - void (*freeDevice) (struct device *dev); - void (*writeDevice) (FILE *file, struct device *dev); - int (*compareDevice) (struct device *dev1, struct device *dev2); -}; - -struct device *newDevice(struct device *old, struct device *new); -void freeDevice(struct device *dev); -void writeDevice(FILE *file, struct device *dev); -int compareDevice(struct device *dev1, struct device *dev2); -struct device *readDevice(FILE *file); - -/* Most of these aren't implemented yet...... */ -/* Return everything found, even non-useful stuff */ -#define PROBE_ALL 1 -/* Don't do 'dangerous' probes that could do weird things (isapnp, serial) */ -#define PROBE_SAFE (1<<1) -/* Stop at first device found */ -#define PROBE_ONE (1<<2) - -#endif diff --git a/tools/serial_probe/kudzu.h b/tools/serial_probe/kudzu.h deleted file mode 100644 index f96565cca..000000000 --- a/tools/serial_probe/kudzu.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright 1999-2003 Red Hat, Inc. - * - * This software may be freely redistributed under the terms of the GNU - * public license. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef _KUDZU_H_ -#define _KUDZU_H_ - -/* kudzu: it grows on you */ - -/* level of debugging output */ -#undef DEBUG_LEVEL - -#ifdef DEBUG_LEVEL -#define DEBUG(s...) fprintf(stderr,s) -#else -#define DEBUG(s...) ; -#endif - -#endif diff --git a/tools/serial_probe/serial.c b/tools/serial_probe/serial.c deleted file mode 100644 index c84cbcff5..000000000 --- a/tools/serial_probe/serial.c +++ /dev/null @@ -1,1136 +0,0 @@ -/* Copyright 1999-2003 Red Hat, Inc. - * - * This software may be freely redistributed under the terms of the GNU - * public license. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * probe serial port for PnP/Legacy devices - */ - - -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <unistd.h> -#include <termios.h> -#include <errno.h> -#include <string.h> -#include <signal.h> -#include <time.h> -#include <libgen.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/sysmacros.h> - -#include <asm/types.h> -#include <linux/serial.h> - -#include "serial.h" -#include "kudzu.h" - -/* character strings ARE null-terminated in the following structure */ -/* these elements are marked with a (string) in the comment */ -/* If PnP device sent 6 bit data stream, we've xlated by a 0x20 offset */ -/* When computing checksum, must remove this offset */ -struct pnp_com_id { - unsigned char xlate_6bit; /* does this contain xlated data */ - unsigned char other_id[17]; /* backward compatibility with pre-PNP */ - unsigned char other_len; /* length of the other_id */ - unsigned char pnp_rev[2]; /* PnP revision bytes */ - unsigned char pnp_rev_str[8]; /* PnP revision (string version) */ - unsigned char eisa_id[4]; /* EISA Mfr identifier (string) */ - unsigned char product_id[5]; /* Mfr determined product ID (string) */ - unsigned char serial_number[9];/* Optional dev serial number (string) */ - unsigned char class_name[33]; /* Optional PnP Class name (string) */ - unsigned char driver_id[42]; /* Optional compat device IDs (string) */ - unsigned char user_name[42]; /* Optional verbose product descr (string)*/ - unsigned char checksum[2]; /* Optional checksum */ -}; - -/* there are two possible bytes to signify the start of a PnP ID string */ -#define BeginPnP1 0x28 -#define BeginPnP2 0x08 - -/* Likewise, two possible stop bytes */ -#define EndPnP1 0x29 -#define EndPnP2 0x09 - -/* these chars indicate extensions to the base dev id exist */ -#define ExtendPnP1 0x5c -#define ExtendPnP2 0x3c - -#define PNP_COM_MAXLEN 256 - -/* results from initiating hardware probe of a hardware device */ -#define PNP_COM_FATAL 1 /* system error, check errno */ -#define PNP_COM_FAIL 2 /* probe ok, but found nothing */ -#define PNP_COM_OK 3 /* probe ok, we found it */ - -/* types of devices we might find */ -/* if PNP_COM_PNPDEV is NOT set, its a legacy device */ -#define PNP_COM_MOUSE 1 /* its a mouse */ -#define PNP_COM_MODEM 2 /* its a modem */ -#define PNP_COM_OTHER 4 /* device is there, cant tell what kind */ -#define PNP_COM_NOEXIST 8 /* no device seen */ -#define PNP_COM_PNPDEV 512 /* its a PNP device */ - -static void serialFreeDevice(struct serialDevice *dev) { - if (dev->pnpmfr) free(dev->pnpmfr); - if (dev->pnpmodel) free(dev->pnpmodel); - if (dev->pnpcompat) free(dev->pnpcompat); - if (dev->pnpdesc) free(dev->pnpdesc); - freeDevice((struct device *)dev); -} - -static void serialWriteDevice(FILE *file, struct serialDevice *dev) -{ - writeDevice(file, (struct device *) dev); - if (dev->pnpmfr) - fprintf(file,"pnpmfr: %s\n",dev->pnpmfr); - if (dev->pnpmodel) - fprintf(file,"pnpmodel: %s\n",dev->pnpmodel); - if (dev->pnpcompat) - fprintf(file,"pnpcompat: %s\n",dev->pnpcompat); - if (dev->pnpdesc) - fprintf(file,"pnpdesc: %s\n",dev->pnpdesc); -} - -static int serialCompareDevice( struct serialDevice *dev1, struct serialDevice *dev2) -{ - int x; - - x = compareDevice((struct device *)dev1, (struct device *)dev2); - if (x && x!=2) return x; - if (dev1->pnpmfr && dev2->pnpmfr && strcmp(dev1->pnpmfr,dev2->pnpmfr)) - return 1; - if ((!dev1->pnpmfr || !dev2->pnpmfr) && (dev1->pnpmfr != dev2->pnpmfr)) - return 1; - if (dev1->pnpmodel && dev2->pnpmodel && strcmp(dev1->pnpmodel,dev2->pnpmodel)) - return 1; - if ((!dev1->pnpmodel || !dev2->pnpmodel) && (dev1->pnpmodel != dev2->pnpmodel)) - return 1; - if (dev1->pnpcompat && dev2->pnpcompat && strcmp(dev1->pnpcompat,dev2->pnpcompat)) - return 1; - if ((!dev1->pnpcompat || !dev2->pnpcompat) && (dev1->pnpcompat != dev2->pnpcompat)) - return 1; - if (dev1->pnpdesc && dev2->pnpdesc && strcmp(dev1->pnpdesc,dev2->pnpdesc)) - return 1; - if ((!dev1->pnpdesc || !dev2->pnpdesc) && (dev1->pnpdesc != dev2->pnpdesc)) - return 1; - return x; -} - - -struct serialDevice * serialNewDevice(struct serialDevice *dev) { - struct serialDevice *ret; - - ret = malloc(sizeof(struct serialDevice)); - memset(ret,'\0',sizeof(struct serialDevice)); - ret=(struct serialDevice *)newDevice((struct device *)dev,(struct device *)ret); - ret->bus = BUS_SERIAL; - ret->newDevice = serialNewDevice; - ret->freeDevice = serialFreeDevice; - ret->writeDevice = serialWriteDevice; - ret->compareDevice = serialCompareDevice; - if (dev && dev->bus == BUS_SERIAL) { - if (dev->pnpmfr) - ret->pnpmfr=strdup(dev->pnpmfr); - if (dev->pnpmodel) - ret->pnpmodel=strdup(dev->pnpmodel); - if (dev->pnpcompat) - ret->pnpcompat=strdup(dev->pnpcompat); - if (dev->pnpdesc) - ret->pnpdesc=strdup(dev->pnpdesc); - } - return ret; -} - -/* - * wait_input - wait until there is data available on fd, - * for the length of time specified by *timo (indefinite - * if timo is NULL). - */ - -static int wait_for_input (int fd, struct timeval *timo) { - fd_set ready; - int n; - - FD_ZERO(&ready); - FD_SET(fd, &ready); - - n = select(fd+1, &ready, NULL, &ready, timo); - return n; -} - -static int open_serial_port( char *port ) { - int fd; - - DEBUG("opening serial port %s...", port); - - fd = open( port, O_RDWR | O_NONBLOCK); - if (fd < 0) { - DEBUG("failed.\n"); - return -1; - } else { - DEBUG("successful.\n"); - } - - /* reset file so it is no longer in non-blocking mode */ - if (fcntl(fd, F_SETFL, 0) < 0) { - close(fd); - DEBUG("Failed to set port to non-blocking mode\n"); - return -1; - } - - return fd; -} - -/* <0 means ioctl error occurred */ -static int get_serial_lines( int fd ) { - int modem_lines; - - ioctl(fd, TIOCMGET, &modem_lines); - return modem_lines; -} - -/* <0 means ioctl error occurred */ -static int set_serial_lines( int fd, int modem_lines ) { - return ioctl(fd, TIOCMSET, &modem_lines); -} - -/* set serial port to 1200 baud, 'nbits' bits, 1 stop, no parity */ -static int setup_serial_port( int fd, int nbits, struct termios *attr ) { - - DEBUG("setting up serial port\n"); - - attr->c_iflag = IGNBRK | IGNPAR; - attr->c_cflag = 0; - attr->c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD | PARENB); - attr->c_cflag |= CREAD | CLOCAL; /*| CRTSCTS ; */ - if (nbits == 7) - attr->c_cflag |= CS7 | CSTOPB; - else - attr->c_cflag |= CS8; - attr->c_oflag = 0; - attr->c_lflag = 0; - - attr->c_cc[VMIN] = 1; - attr->c_cc[VTIME] = 5; - - if (cfsetospeed( attr, B1200)) - return -1; - if (cfsetispeed( attr, B1200)) - return -1; - return tcsetattr(fd, TCSANOW, attr); -} - -/* Initialize the serial port to a known state *before* probing. This is - * apparently required for some Logitech mice, who will stubbornly refuse - * to respond to PnP probes after they've been opened by gpm or XFree. - */ - -static int init_port(int fd) { - struct termios attr; - - if (tcgetattr(fd,&attr)) - return 1; - - cfsetospeed(&attr, B2400); - cfsetispeed(&attr, B2400); - attr.c_iflag = IXON | ICRNL; - attr.c_cflag = CLOCAL | HUPCL | CREAD | B9600 | CS8; - attr.c_oflag = 0; - attr.c_lflag = 0; - return tcsetattr(fd, TCSANOW, &attr); -} - - -/* Request for PnP info from serial device */ -/* See page 6 of the pnpcom doc from Microsoft */ -/* Return code tells us what happened */ -/* */ -/* PNP_COM_FATAL - error, errno has reason */ -/* PNP_COM_OK - probe initiated successfully */ -static int init_pnp_com_seq1( int fd ) { - int modem_lines; - int temp; - int dsr_status; - int rc = PNP_COM_OK; - struct termios portattr; - - DEBUG("initializing 1st PNP sequence\n"); - if (init_port(fd)) - return PNP_COM_FATAL; - - modem_lines = get_serial_lines(fd); - - /* COM port initialization, check for device enumerate */ - - /* turn on DTR, turn off RTS */ - modem_lines |= TIOCM_DTR; - modem_lines &= ~TIOCM_RTS; - set_serial_lines(fd, modem_lines); - - /* wait 200ms for DSR=1 */ - usleep(200000); - - dsr_status = get_serial_lines(fd) & TIOCM_DSR; - /* see if we got DSR coming up */ - - if (!dsr_status) { - DEBUG("Device did not set DSR\n"); - } - - /* COM port Setup, 1st phase */ - temp = tcgetattr(fd, &portattr); - if (temp < 0) - return PNP_COM_FATAL; - - /* now we set port to be 1200 baud, 7 bits, no parity, 1 stop bit */ - temp = setup_serial_port( fd, 7, &portattr ); - if (temp < 0) - return PNP_COM_FATAL; - - /* we drop DTR and RTS */ - modem_lines &= ~( TIOCM_RTS | TIOCM_DTR); - set_serial_lines(fd, modem_lines); - usleep(200000); - - /* bring DTR back up */ - modem_lines |= TIOCM_DTR; - set_serial_lines(fd, modem_lines); - usleep(200000); - - /* Wait for response, 1st phase */ - modem_lines |= TIOCM_RTS; - set_serial_lines(fd, modem_lines); - /* usleep(200000); => AQ: not valid as we should look to receive data during this time!! */ - - return rc; -} - - -/* Request for PnP info from serial device */ -/* See page 6 of the pnpcom doc from Microsoft */ -/* Always returns PNP_COM_OK */ -static int init_pnp_com_seq2( int fd ) { - int modem_lines; - int rc = PNP_COM_OK; - - DEBUG("initializing 2nd PNP sequence\n"); - - modem_lines = get_serial_lines(fd); - - /* COM port setup, 2nd phase */ - /* turn off DTR and RTS */ - modem_lines &= ~(TIOCM_DTR | TIOCM_RTS); - set_serial_lines(fd, modem_lines); - usleep(200000); - - /* wait for response, 2nd phase */ - /* turn on DTR and RTS */ - modem_lines |= (TIOCM_DTR | TIOCM_RTS); - set_serial_lines(fd, modem_lines); - /* usleep(200000); => AQ: not valid as we should look to receive data during this time!! */ - - return rc; -} - - -/* Request for PnP info from serial modem device */ -/* Uses ATI9 code, may not do anything but return 'ERROR' */ -/* Return code tells us what happened */ -/* */ -/* PNP_COM_FATAL - error, errno has reason */ -/* PNP_COM_OK - probe initiated successfully */ -/* PNP_COM_FAIL - DSR never came on - try alterntives */ -/* means (ATI9?) to get PnP string */ -static int init_pnp_com_ati9( int fd ) { - int modem_lines; - int temp; - int done; - int respindex; - int starttime; - unsigned char resp[100], buf[2]; - struct timeval timo; - struct termios portattr; - - DEBUG("Querying ATI9 info from modem\n"); - modem_lines = get_serial_lines(fd); - - /* turn off RTS */ - modem_lines &= ~TIOCM_RTS; - set_serial_lines(fd, modem_lines); - - /* wait 200ms for DSR=1 */ - usleep(200000); - - /* now we set port to be 1200 baud, 8 bits, no parity, 1 stop bit */ - temp = tcgetattr(fd, &portattr); - if (temp < 0) { - modem_lines |= TIOCM_DTR | TIOCM_RTS; - set_serial_lines(fd, modem_lines); - return PNP_COM_FATAL; - } - - /* goto 1200 baud, 8 bits */ - temp = setup_serial_port( fd, 8, &portattr ); - if (temp < 0) { - modem_lines |= TIOCM_DTR | TIOCM_RTS; - set_serial_lines(fd, modem_lines); - return PNP_COM_FATAL; - } - - /* turn on DTR and RTS */ - modem_lines = get_serial_lines(fd); - modem_lines |= TIOCM_RTS | TIOCM_DTR; - set_serial_lines(fd, modem_lines); - usleep(200000); - - /* send the 'AT' command */ - DEBUG("Sending ATI9 command to modem\n"); - - write(fd, "ATI9\r", 5); - - /* start reading - read the AT command back */ - done = 0; - respindex= 0; - starttime=time(NULL); - memset(resp, 0, sizeof(resp)); - while (!done) { - timo.tv_sec=0; - timo.tv_usec=250000; - if (wait_for_input(fd, &timo) > 0) { - temp = read( fd, buf, 1 ); - if (temp < 0) { - if (errno != EAGAIN) - return PNP_COM_FATAL; - } else { - resp[respindex++] = buf[0]; - resp[respindex] = 0; - } - } else - done = 1; - - /* shouldnt run more than 5 seconds */ - if (time(NULL)-starttime > 5 ) - done = 1; - - if (respindex > 6) - done = 1; - - if (strstr(resp, "ATI9\r")) - done = 1; - - DEBUG("ATI9 probe ->%d \"%s\"\n",respindex, resp); - } - - /* see if we saw the 'OK' response */ - if (strstr(resp, "(")) - return PNP_COM_OK; - else - return PNP_COM_FAIL; - - return PNP_COM_OK; -} - -/* See if this is a legacy mouse device */ -/* Only called if the PnP probe above failed */ -/* We turn off the mouse via RS232 lines, then turn it on */ -/* If it spits out an 'M' character (at 1200 baud, 7N1) */ -/* it could be a mouse. */ -/* */ -/* Return code tells us what happened */ -/* */ -/* PNP_COM_FATAL - error, errno has reason */ -/* PNP_COM_OK - probe saw 'M' */ -/* PNP_COM_FAIL - Never saw the 'M' response */ - -static int find_legacy_mouse( int fd ) { - int modem_lines; - int temp; - int done; - int starttime; - unsigned char resp[2]; - struct timeval timo; - struct termios portattr; - - DEBUG("looking for a legacy mouse\n"); - - /* now we set port to be 1200 baud, 7 bits, no parity, 1 stop bit */ - temp = tcgetattr(fd, &portattr); - if (temp < 0) - return PNP_COM_FATAL; - - /* goto 1200 baud, etc etc*/ - temp = setup_serial_port( fd, 7, &portattr ); - if (temp < 0) - return PNP_COM_FATAL; - - /* we drop DTR and RTS */ - modem_lines = get_serial_lines(fd); - modem_lines &= ~( TIOCM_RTS | TIOCM_DTR); - set_serial_lines(fd, modem_lines); - usleep(200000); - - /* bring them DTR back up */ - modem_lines |= TIOCM_DTR | TIOCM_RTS; - set_serial_lines(fd, modem_lines); - - /* start reading - after first character we quit */ - done = 0; - starttime=time(NULL); - while (!done) { - timo.tv_sec=0; - timo.tv_usec=250000; - if (wait_for_input(fd, &timo) > 0) { - temp = read( fd, resp, 1 ); - if (temp < 0) { - if (errno != EAGAIN) - return PNP_COM_FATAL; - } else { - done = 1; - } - } else - done = 1; - - - /* shouldnt run more than 2 seconds */ - if (time(NULL)-starttime > 2 ) - done = 1; - } - if (*resp == 'M') { - DEBUG("Found legacy mouse\n"); - return PNP_COM_OK; - } else - return PNP_COM_FAIL; -} - -/* See if this is a legacy modem device */ -/* Only called if the PnP probe above failed */ -/* We send a '!AT' and see if we get an 'OK' back */ -/* */ -/* Return code tells us what happened */ -/* */ -/* PNP_COM_FATAL - error, errno has reason */ -/* PNP_COM_OK - probe saw 'OK' */ -/* PNP_COM_FAIL - Never saw the 'OK' response */ -static int find_legacy_modem( int fd ) { - int modem_lines; - int temp; - int done; - int respindex; - int starttime; - unsigned char resp[10], buf[2]; - struct timeval timo; - struct termios portattr; - - DEBUG("looking for a legacy modem\n"); - - /* now we set port to be 1200 baud, 8 bits, no parity, 1 stop bit */ - temp = tcgetattr(fd, &portattr); - if (temp < 0) - return PNP_COM_FATAL; - - /* goto 1200 baud, 8 bits */ - temp = setup_serial_port( fd, 8, &portattr ); - if (temp < 0) - return PNP_COM_FATAL; - - /* turn on DTR and RTS */ - modem_lines = get_serial_lines(fd); - modem_lines |= TIOCM_RTS | TIOCM_DTR; - set_serial_lines(fd, modem_lines); - usleep(200000); - - /* send the 'AT' command */ - DEBUG("Sending AT command to modem\n"); - - write(fd, "AT\r", 3); - - /* start reading - we'll get AT command back first, then modem response */ - done = 0; - respindex= 0; - starttime=time(NULL); - memset(resp, 0, sizeof(resp)); - while (!done) { - timo.tv_sec=0; - timo.tv_usec=250000; - if (wait_for_input(fd, &timo) > 0) { - temp = read( fd, buf, 1 ); - if (temp < 0) { - if (errno != EAGAIN) - return PNP_COM_FATAL; - } else { - resp[respindex++] = buf[0]; - } - } else - done = 1; - - /* shouldnt run more than 5 seconds */ - if (time(NULL)-starttime > 5 ) - done = 1; - - if (respindex > 9) - done = 1; - } - - /* see if we saw the 'OK' response */ - if (strstr(resp, "OK")) - return PNP_COM_OK; - else - return PNP_COM_FAIL; -} - -/* retrieve the PnP ID string */ -/* timeout after 3 seconds */ -/* should probably set a 200 msec timeout per char, as spec says */ -/* if no char received, we're done */ -static int read_pnp_string( int fd, unsigned char *pnp_string, int *pnp_len, int pnp_stringbuf_size ) { - int pnp_index; - int temp, done, counter; - int seen_start; - time_t starttime; - struct timeval timo; - unsigned char buf[80]; - unsigned char end_char; - - DEBUG("Attempting to read PNP ID string\n"); - - /* see if we have any input waiting */ - pnp_index = 0; - seen_start = 0; - done = 0; - end_char = 0; - starttime=time(NULL); - while (!done) { - timo.tv_sec=0; - timo.tv_usec=250000; - if (wait_for_input(fd, &timo) > 0) { - temp = read( fd, buf, 1 ); - if (temp < 0) { - if (errno != EAGAIN) - return PNP_COM_FAIL; - } else { - for (counter=0; counter < temp; counter++) { - pnp_string[pnp_index++] = buf[counter]; - if (seen_start) { - if (buf[counter] == end_char) { - done=1; - break; - } - } else { - if (buf[counter] == BeginPnP1) { - seen_start = 1; - end_char = EndPnP1; - } else if (buf[counter] == BeginPnP2) { - seen_start = 1; - end_char = EndPnP2; - } - } - } - } - } else - done = 1; - - /* shouldnt run more than 3 seconds */ - if (time(NULL)-starttime > 3 ) - done = 1; - - if (pnp_index >= pnp_stringbuf_size) - done = 1; - } - pnp_string[pnp_index] = 0; - *pnp_len=pnp_index; - if(*pnp_len > 0) - return PNP_COM_OK; - else /* allows to call seq2 to be conformant */ - return PNP_COM_FAIL; -} - -/* parse the PnP ID string into components */ -static int parse_pnp_string( unsigned char *pnp_id_string, int pnp_len, - struct pnp_com_id *pnp_id ) { - unsigned char *p1, *p2; - unsigned char *start; - unsigned char *end; - unsigned char *curpos; - unsigned char *endfield; - unsigned char *temppos; - unsigned char *pnp_string; - unsigned char end_char; - - int no_more_extensions=0; - int stage; - int len; - unsigned short int checksum; - char hex_checksum[5]; - - char extension_delims[] = {EndPnP1, EndPnP2, ExtendPnP1, ExtendPnP2, 0}; - char end_delims[] = {EndPnP1, EndPnP2, 0}; - unsigned char* p1end = NULL; - unsigned char* p2end = NULL; - - /* clear out pnp_id */ - memset(pnp_id, 0, sizeof(*pnp_id)); - - /* copy pnp_string to temp space */ - pnp_string = alloca(pnp_len+1); - memcpy(pnp_string, pnp_id_string, pnp_len+1); - - /* first find the start of the PnP part of string */ - p1 = memchr( pnp_string, BeginPnP1, pnp_len ); - p2 = memchr( pnp_string, BeginPnP2, pnp_len ); - - - if (p1) { - int p_len = pnp_len - (p1 - pnp_string); - p1end = memchr(p1, EndPnP1, p_len); - } - if (p2) { - int p_len = pnp_len - (p2 - pnp_string); - p2end = memchr(p2, EndPnP2, p_len); - } - - /* use the one which points nearest to start of the string */ - /* and is actually defined */ - if ( p1 && p1end && p2 && p2end ) { - start = (p1 < p2) ? p1 : p2; - } else if ( p1 && p1end ) - start = p1; - else if ( p2 && p2end ) - start = p2; - else - start = NULL; - - /* if no start then we're done */ - if (!start) - return -1; - - /* the length of the initial part cannot be more than 17 bytes */ - if ((start - pnp_string) > 17) - return -1; - - /* setup end character we are looking for based on the start character */ - if (start == p2) { - pnp_id->xlate_6bit = 1; - end_char = EndPnP2; - /* we need to xlate data in PnP fields */ - /* remember to skip the revision fields (bytes 1 and 2 after start) */ - temppos=start; - while (1) { - if (*temppos == EndPnP2) { - *temppos += 0x20; - break; - } else if (temppos != start+1 && temppos != start+2 ) - *temppos += 0x20; - - temppos++; - } - } else { - pnp_id->xlate_6bit = 0; - end_char = EndPnP1; - } - - /* move everything before the start of the PnP block */ - memcpy(pnp_id->other_id, pnp_string, start-pnp_string); - pnp_id->other_len = start - pnp_string; - - /* now we get the PnP fields - all were zero'd out above */ - curpos = start+1; - memcpy(pnp_id->pnp_rev,curpos,2); curpos += 2; - memcpy(pnp_id->eisa_id,curpos,3); curpos += 3; - memcpy(pnp_id->product_id,curpos,4); curpos += 4; - /* now we see if have extension fields */ - no_more_extensions = 0; - stage = 0; - while (!no_more_extensions) { - if (*curpos == ExtendPnP1 || *curpos == ExtendPnP2) { - curpos++; - endfield = strpbrk(curpos, extension_delims); - if (!endfield) - return -1; - /* if we reached the end of all PnP data, back off */ - /* cause there is a checksum at the end of extension data */ - if (*endfield == EndPnP1 || *endfield == EndPnP2) - endfield -= 2; - } else - break; - - len = endfield - curpos; - switch (stage) { - case 0: - if (len != 8 && len != 0 ) - return -1; - - memcpy(pnp_id->serial_number,curpos,len); - curpos += len; - break; - - case 1: - if (len > 33) - return -1; - memcpy(pnp_id->class_name, curpos, len); - curpos = endfield; - break; - - case 2: - if (len > 41) - return -1; - memcpy(pnp_id->driver_id, curpos, len); - curpos = endfield; - break; - - case 3: - if (len > 41) - return -1; - memcpy(pnp_id->user_name, curpos, len); - curpos = endfield; - break; - } - stage++; - } - - /* now find the end of all PnP data */ - end = strpbrk(curpos, end_delims); - if (!end) - return -1; - - /* if we had any extensions, we expect an checksum */ - if (stage != 0) { - /* copy checksum into struct */ - memcpy(pnp_id->checksum, curpos, 2); - - /* compute the checksum as the sum of all PnP bytes, excluding */ - /* the two byte checksum. */ - checksum = 0; - for (temppos=start; temppos <= end; temppos++) { - /* skip checksum in calculation */ - if (temppos == (end-2) || temppos == (end-1)) - continue; - /* dont xlate the revision at start */ - if (temppos != (start+1) && temppos != (start+2)) - checksum += *temppos - ((pnp_id->xlate_6bit) ? 0x20 : 0); - else - checksum += *temppos; - } - sprintf(hex_checksum, "%.2X", checksum & 0xff); - if (strncmp(hex_checksum, pnp_id->checksum, 2)) - return -1; - } - - /* checksum was ok, so we're done */ - return 0; -} - -static int attempt_pnp_retrieve(int fd, char *pnp_string, int *pnp_strlen, int pnp_stringbuf_size) { - int pnp_probe_status; - struct pnp_com_id pnp_id; - int tried_at_prodding=0, give_up=0; - - DEBUG("Attempting PNP information retrieval\n"); - - while (!give_up) { - pnp_probe_status = init_pnp_com_seq1(fd); - if (pnp_probe_status == PNP_COM_FATAL) - return PNP_COM_FATAL; - pnp_probe_status = read_pnp_string(fd, pnp_string, pnp_strlen, - pnp_stringbuf_size); - if (pnp_probe_status == PNP_COM_FAIL) { - init_pnp_com_seq2(fd); /* always succeeds */ - - pnp_probe_status = read_pnp_string(fd, pnp_string, pnp_strlen, - pnp_stringbuf_size); - } - - if (*pnp_strlen == 1 && pnp_string[0] == 'M') /* legacy mouse */ - return PNP_COM_OK; - /* see if we got anything useful, if not try AT command */ - /* to prod device into correct serial params */ - if (parse_pnp_string( pnp_string, *pnp_strlen, &pnp_id )<0) { - DEBUG("That failed.\n"); - if (!tried_at_prodding) { - DEBUG("Prod modem with AT command.\n"); - write(fd, "AT\r", 3); - tried_at_prodding=1; - } else - give_up = 1; - } else - return PNP_COM_OK; - } - - /* normal PNP detection has failed. */ - /* try sending a ATI9 code to the modem to see if we get PnP id back */ - init_pnp_com_ati9(fd); - read_pnp_string(fd, pnp_string, pnp_strlen, pnp_stringbuf_size ); - if (parse_pnp_string( pnp_string, *pnp_strlen, &pnp_id )<0) { - *pnp_strlen = 0; - pnp_string[0] = 0; - return PNP_COM_FAIL; - } else - return PNP_COM_OK; -} - -struct device *serialProbe(enum deviceClass probeClass, int probeFlags, - struct device *devlist) { - int fd; - int temp; - int pnp_strlen; - int devicetype=-1; - unsigned char pnp_string[100]; - char port[20]; - struct termios origattr; - struct pnp_com_id pnp_id; - struct serialDevice *serdev; - struct stat sb; - int maj, twelve=12; - int console=-1; - int stdin_line=-1; - struct serial_struct si; - - DEBUG("Probing for serial ports\n"); - - if (probeFlags & PROBE_SAFE) return devlist; - - /* Are we on a serial console? */ - fstat(0,&sb); - maj = major(sb.st_rdev); - if (maj != 4 && (maj < 136 || maj > 143)) { - if (ioctl (0, TIOCLINUX, &twelve) < 0) { - if (ioctl (0, TIOCGSERIAL, &si) >= 0) { - if (si.line > 0) { - stdin_line = 1 << si.line; - } else { - stdin_line = 0; - } - } else stdin_line = 0; - } - } - - fd=open("/dev/console",O_RDWR); - if (fd != -1) { - fstat(fd,&sb); - maj = major(sb.st_rdev); - if (maj != 4 && (maj < 136 || maj > 143)) { - if (ioctl (fd, TIOCLINUX, &twelve) < 0) { - #ifdef __powerpc__ - // we could have gotten an error for another reason - like EINVAL - // skipping ttyS0 on PPC - which is where most modems reside - if (errno == ENOTTY) { - #endif - if (ioctl (fd, TIOCGSERIAL, &si) >= 0) { - if (si.line > 0) { - console = 1 << si.line; - } else { - console = 0; - #ifdef __powerpc__ - } - #endif - } - } else console = 0; - } - } - close(fd); - } - - - if ( - (probeClass & CLASS_UNSPEC) || - (probeClass & CLASS_OTHER) || - (probeClass & CLASS_MOUSE) || - (probeClass & CLASS_MODEM) || - (probeClass & CLASS_PRINTER) - ) { - int x; - - for (x=0; x<=3 ; x++) { - struct stat sbuf; - char lockfile[32]; - if (x==console || x==stdin_line) continue; - snprintf(port,20,"/dev/ttyS%d",x); - - /* Make sure it's not in use */ - snprintf(lockfile,32,"/var/lock/LCK..ttyS%d",x); - if (!stat(lockfile,&sbuf)) { - DEBUG("Port %s in use, skipping probe.\n", - port); - continue; - } - memset(lockfile,'\0',32); - if (readlink("/dev/modem",lockfile,32)>0) { - if (!strcmp(basename(port),basename(lockfile))) { - snprintf(lockfile,32,"/var/lock/LCK..modem"); - if (!stat(lockfile,&sbuf)) { - DEBUG("Port %s in use, skipping probe.\n", - port); - continue; - } - } - } - - if ((fd=open_serial_port(port)) < 0) { - continue; - } - /* save the current state of the port */ - temp = tcgetattr(fd, &origattr); - if (temp < 0) { - DEBUG("unable to retrieve port attributes...no port present?\n"); - close(fd); - continue; - } - - - /* try twiddling RS232 control lines and see if it talks to us */ - devicetype=-1; - pnp_strlen = 0; - if (attempt_pnp_retrieve( fd, pnp_string, &pnp_strlen, - sizeof(pnp_string) - 1 ) == PNP_COM_FATAL) - goto endprobe; - - /* see if we found any PnP signature */ - if (pnp_strlen != 0 && (pnp_strlen != 1 || pnp_string[0] != 'M')) { - - /* fill in the PnP com structure */ - if (parse_pnp_string( pnp_string, pnp_strlen, &pnp_id )<0) { - DEBUG("Got PNP data back, but failed to parse. Aborting\n"); - goto endprobe; - } else { - char *foo; - int len; - - DEBUG("PNP data parsed.\n"); - serdev = serialNewDevice(NULL); - - if (pnp_id.user_name[0]) { - serdev->pnpdesc = strdup(pnp_id.user_name); - len = strlen(pnp_id.eisa_id) + - strlen(pnp_id.product_id) + - strlen(pnp_id.user_name) + 3; - foo = malloc(len); - snprintf(foo,len,"%s|%s %s",pnp_id.eisa_id, - pnp_id.product_id,pnp_id.user_name); - } else { - len = strlen(pnp_id.eisa_id) + - strlen(pnp_id.product_id) + 3; - foo = malloc(len); - snprintf(foo,len,"%s|%s",pnp_id.eisa_id, - pnp_id.product_id); - } - if (serdev->desc) free(serdev->desc); - serdev->desc=strdup(foo); - serdev->device=strdup(port+5); - if (serdev->driver) free(serdev->driver); - serdev->driver=strdup("ignore"); - serdev->pnpmfr = strdup(pnp_id.eisa_id); - serdev->pnpmodel = strdup(pnp_id.product_id); - - free(foo); - foo=pnp_id.product_id; - if (pnp_id.driver_id) { - if (strstr(pnp_id.driver_id,"PNP")) - foo = strstr(pnp_id.driver_id,"PNP")+3; - serdev->pnpcompat = strdup(pnp_id.driver_id); - } - - if (*pnp_id.other_id == 'M' || - !strncmp(pnp_id.class_name, "MOUSE", 5) || - !strncmp(foo, "0F", 2)) { - serdev->type = CLASS_MOUSE; - if (!strncmp(serdev->desc, "|", 1)) { - free(serdev->desc); - serdev->desc=strdup("Generic Serial Mouse"); - } - if (serdev->driver) free(serdev->driver); - serdev->driver = strdup("generic"); - } - else if (!strncmp(pnp_id.class_name, "MODEM", 5) || - !strncmp(foo, "C", 1)) - serdev->type = CLASS_MODEM; - else if (!strncmp(pnp_id.class_name, "PRINTER", 7)) - serdev->type = CLASS_PRINTER; - else - serdev->type = CLASS_OTHER; - if (serdev->type & probeClass) { - if (devlist) - serdev->next = devlist; - devlist = (struct device *)serdev; - if (probeFlags & PROBE_ONE) { - tcsetattr(fd, TCSANOW, &origattr); - tcflush(fd, TCIOFLUSH); - close(fd); - return devlist; - } - } else { - serdev->freeDevice(serdev); - } - goto endprobe; - } - } else { - DEBUG("No PNP data received.\n"); - /* try to find a legacy device */ - - temp = find_legacy_mouse(fd); - if (temp == PNP_COM_FATAL) { - goto endprobe; - } else if (temp == PNP_COM_OK) { - if (probeClass & CLASS_MOUSE) { - serdev=serialNewDevice(NULL); - serdev->type = CLASS_MOUSE; - serdev->device = strdup(port+5); - serdev->driver= strdup("generic"); - serdev->desc = strdup("Generic Serial Mouse"); - if (devlist) - serdev->next = devlist; - devlist = (struct device *)serdev; - if (probeFlags & PROBE_ONE) { - tcsetattr(fd, TCSANOW, &origattr); - tcflush(fd, TCIOFLUSH); - close(fd); - return devlist; - } - } - goto endprobe; - } else { - DEBUG("Didn't see a legacy mouse.\n"); - - temp = find_legacy_modem(fd); - if (temp == PNP_COM_FATAL) { - goto endprobe; - } else if (temp == PNP_COM_OK) { - DEBUG("Legacy modem signature seen.\n"); - if (probeClass & CLASS_MODEM) { - serdev=serialNewDevice(NULL); - serdev->type = CLASS_MODEM; - serdev->device = strdup(port+5); - serdev->driver= strdup("ignore"); - serdev->desc = strdup("Generic Serial Modem"); - if (devlist) - serdev->next = devlist; - devlist = (struct device *)serdev; - if (probeFlags & PROBE_ONE) { - tcsetattr(fd, TCSANOW, &origattr); - tcflush(fd, TCIOFLUSH); - close(fd); - return devlist; - } - } - goto endprobe; - } else { - DEBUG("Didnt see a legacy modem, game over.\n"); - } - } - } - endprobe: - DEBUG("Restoring original port attributes\n"); - tcsetattr(fd, TCSANOW, &origattr); - tcflush(fd, TCIOFLUSH); - close(fd); - } - } - return devlist; -} diff --git a/tools/serial_probe/serial.h b/tools/serial_probe/serial.h deleted file mode 100644 index 691abeb26..000000000 --- a/tools/serial_probe/serial.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright 1999-2003 Red Hat, Inc. - * - * This software may be freely redistributed under the terms of the GNU - * public license. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef _KUDZU_SERIAL_H_ -#define _KUDZU_SERIAL_H_ - -#include "device.h" - -struct serialDevice { - /* common fields */ - struct device *next; /* next device in list */ - int index; - enum deviceClass type; /* type */ - enum deviceBus bus; /* bus it's attached to */ - char * device; /* device file associated with it */ - char * driver; /* driver to load, if any */ - char * desc; /* a description */ - int detached; - /* serial-specific fields */ - struct serialDevice *(*newDevice) (struct serialDevice *dev); - void (*freeDevice) (struct serialDevice *dev); - void (*writeDevice) (FILE *file, struct serialDevice *dev); - int (*compareDevice) (struct serialDevice *dev1, struct serialDevice *dev2); - char * pnpmfr; - char * pnpmodel; - char * pnpcompat; - char * pnpdesc; - -}; - -struct serialDevice *serialNewDevice(struct serialDevice *dev); -struct device *serialProbe(enum deviceClass probeClass, int probeFlags, - struct device *devlist); - -#endif diff --git a/tools/serial_probe/serial_probe.c b/tools/serial_probe/serial_probe.c deleted file mode 100644 index a9aae52e5..000000000 --- a/tools/serial_probe/serial_probe.c +++ /dev/null @@ -1,114 +0,0 @@ -/* Copyright 1999 Mandrakesoft <fpons@mandrakesoft.com> - * - * The following file used by this one are copyrighted by RedHat and - * are taken from kudzu : - * device.h - * serial.h - * serial.c - * This file is taken from kudzu.c copyrighted by RedHat, 1999. - * - * This software may be freely redistributed under the terms of the GNU - * public license. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - -#include "serial.h" -#include "device.h" - -typedef struct device *(newFunc)(struct device *); -typedef int (initFunc)(); -typedef struct device *(probeFunc)(enum deviceClass, int, struct device *); - -char *classStrings[] = { - "UNSPEC", "OTHER", "NETWORK", "SCSI", "VIDEO", "AUDIO", - "MOUSE", "MODEM", "CDROM", "TAPE", "FLOPPY", "SCANNER", - "HD", "RAID", "PRINTER", "CAPTURE", "KEYBOARD", NULL -}; - -struct device *newDevice(struct device *old, struct device *new) { - if (!old) { - if (!new) { - new = malloc(sizeof(struct device)); - memset(new,'\0',sizeof(struct device)); - } - new->type = CLASS_UNSPEC; - } else { - new->type = old->type; - if (old->device) new->device = strdup(old->device); - if (old->driver) new->driver = strdup(old->driver); - if (old->desc) new->desc = strdup(old->desc); - } - new->newDevice = newDevice; - new->freeDevice = freeDevice; - new->compareDevice = compareDevice; - return new; -} - -void freeDevice(struct device *dev) { - if (!dev) { - printf("freeDevice(null)\n"); - abort(); /* return; */ - } - if (dev->device) free (dev->device); - if (dev->driver) free (dev->driver); - if (dev->desc) free (dev->desc); - free (dev); -} - -void writeDevice(FILE *file, struct device *dev) {} -int compareDevice(struct device *dev1, struct device *dev2) { return 0; } - -int main () { - struct device* devices = NULL; - struct serialDevice* serialDevice = NULL; - - devices = serialProbe(CLASS_UNSPEC, 0, devices); - while (devices) { - serialDevice = (struct serialDevice*)devices; - - printf("CLASS="); - if (serialDevice->type == CLASS_UNSPEC) puts("UNSPEC"); else - if (serialDevice->type == CLASS_OTHER) puts("OTHER"); else - if (serialDevice->type == CLASS_NETWORK) puts("NETWORK"); else - if (serialDevice->type == CLASS_SCSI) puts("SCSI"); else - if (serialDevice->type == CLASS_MOUSE) puts("MOUSE"); else - if (serialDevice->type == CLASS_AUDIO) puts("AUDIO"); else - if (serialDevice->type == CLASS_CDROM) puts("CDROM"); else - if (serialDevice->type == CLASS_MODEM) puts("MODEM"); else - if (serialDevice->type == CLASS_VIDEO) puts("VIDEO"); else - if (serialDevice->type == CLASS_TAPE) puts("TAPE"); else - if (serialDevice->type == CLASS_FLOPPY) puts("FLOPPY"); else - if (serialDevice->type == CLASS_SCANNER) puts("SCANNER"); else - if (serialDevice->type == CLASS_HD) puts("HD"); else - if (serialDevice->type == CLASS_RAID) puts("RAID"); else - if (serialDevice->type == CLASS_PRINTER) puts("PRINTER"); else - if (serialDevice->type == CLASS_CAPTURE) puts("CAPTURE"); else - if (serialDevice->type == CLASS_KEYBOARD) puts("KEYBOARD"); else - if (serialDevice->type == CLASS_MONITOR) puts("MONITOR"); else - if (serialDevice->type == CLASS_USB) puts("USB"); else - if (serialDevice->type == CLASS_SOCKET) puts("SOCKET"); else - if (serialDevice->type == CLASS_FIREWIRE) puts("FIREWIRE"); else - if (serialDevice->type == CLASS_IDE) puts("IDE"); - printf("BUS=SERIAL\n"); - printf("DEVICE=/dev/%s\n", serialDevice->device); - printf("DRIVER=%s\n", serialDevice->driver); - if (!serialDevice->pnpdesc) printf("DESCRIPTION=%s\n", serialDevice->desc); - if (serialDevice->pnpmfr) printf("MANUFACTURER=%s\n", serialDevice->pnpmfr); - if (serialDevice->pnpmodel) printf("MODEL=%s\n", serialDevice->pnpmodel); - if (serialDevice->pnpcompat) printf("COMPAT=%s\n", serialDevice->pnpcompat); - if (serialDevice->pnpdesc) printf("DESCRIPTION=%s\n", serialDevice->pnpdesc); - printf("\n"); - - devices=devices->next; - } - - return 0; -} |