diff options
Diffstat (limited to 'tools/serial_probe')
-rw-r--r-- | tools/serial_probe/.cvsignore | 1 | ||||
-rw-r--r-- | tools/serial_probe/Makefile | 4 | ||||
-rw-r--r-- | tools/serial_probe/device.h | 52 | ||||
-rw-r--r-- | tools/serial_probe/kudzu.h | 26 | ||||
-rw-r--r-- | tools/serial_probe/serial.c | 770 | ||||
-rw-r--r-- | tools/serial_probe/serial.h | 4 | ||||
-rw-r--r-- | tools/serial_probe/serial_probe.c | 30 |
7 files changed, 438 insertions, 449 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 index 8e8590d62..86deb49f9 100644 --- a/tools/serial_probe/Makefile +++ b/tools/serial_probe/Makefile @@ -5,5 +5,9 @@ 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 index fa5f8183e..58d1414a0 100644 --- a/tools/serial_probe/device.h +++ b/tools/serial_probe/device.h @@ -1,5 +1,4 @@ - -/* Copyright 1999 Red Hat, Inc. +/* Copyright 1999-2003 Red Hat, Inc. * * This software may be freely redistributed under the terms of the GNU * public license. @@ -18,30 +17,56 @@ enum deviceClass { /* device classes... this is somewhat ad-hoc */ - CLASS_UNSPEC, CLASS_OTHER, CLASS_NETWORK, CLASS_SCSI, CLASS_VIDEO, - CLASS_AUDIO, CLASS_MOUSE, CLASS_MODEM, CLASS_CDROM, CLASS_TAPE, - CLASS_FLOPPY, CLASS_SCANNER, CLASS_HD, CLASS_RAID, CLASS_PRINTER, - CLASS_CAPTURE, CLASS_KEYBOARD, CLASS_PCMCIA + 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_UNSPEC = ~0, BUS_OTHER = (1 << 0), BUS_PCI = (1 << 1), BUS_SBUS = (1 << 2), - BUS_PSAUX = (1 << 3), - BUS_SERIAL = (1 << 4), + 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), -#ifdef _i_wanna_build_this_crap_ - BUS_ISAPNP = (1 << 9), -#endif + 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 { @@ -50,7 +75,7 @@ struct device { struct device *next; /* Used for ordering, and for aliasing (modem0, modem1, etc.) */ int index; - enum deviceClass class; /* type */ + 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 */ @@ -76,5 +101,4 @@ struct device *readDevice(FILE *file); /* 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 new file mode 100644 index 000000000..f96565cca --- /dev/null +++ b/tools/serial_probe/kudzu.h @@ -0,0 +1,26 @@ +/* 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 index 14b315817..5159c3dae 100644 --- a/tools/serial_probe/serial.c +++ b/tools/serial_probe/serial.c @@ -1,6 +1,4 @@ -/* probe serial port for PnP/Legacy devices - * - * Copyright 1999 Red Hat, Inc. +/* Copyright 1999-2003 Red Hat, Inc. * * This software may be freely redistributed under the terms of the GNU * public license. @@ -9,6 +7,7 @@ * 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 */ @@ -26,9 +25,13 @@ #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 */ @@ -76,10 +79,6 @@ struct pnp_com_id { #define PNP_COM_NOEXIST 8 /* no device seen */ #define PNP_COM_PNPDEV 512 /* its a PNP device */ -/* level of debugging output */ -/* current any value > 0 dumps all available debugging output */ -static int debug_level=0; - static void serialFreeDevice(struct serialDevice *dev) { if (dev->pnpmfr) free(dev->pnpmfr); if (dev->pnpmodel) free(dev->pnpmodel); @@ -90,111 +89,74 @@ static void serialFreeDevice(struct serialDevice *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); + 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; -} - -/* UNUSED */ -void print_status_lines( int fd ) { - int modem_lines; - - ioctl(fd, TIOCMGET, &modem_lines); - - printf("DTR : %s\n",(modem_lines & TIOCM_DTR ? "On" : "Off")); - printf("RTS : %s\n",(modem_lines & TIOCM_RTS ? "On" : "Off")); - printf("CTS : %s\n",(modem_lines & TIOCM_CTS ? "On" : "Off")); - printf("DSR : %s\n",(modem_lines & TIOCM_DSR ? "On" : "Off")); - printf("CD : %s\n",(modem_lines & TIOCM_CD ? "On" : "Off")); - printf("RI : %s\n",(modem_lines & TIOCM_RI ? "On" : "Off")); + 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; } -/* UNUSED except in debug */ -/* outputs data in a hex table, 8 values per row */ -void print_hex_data( unsigned char *data, int len ) { - int i, j, pos; - - if (len == 0) { - printf("No data to print.\n"); - return; - } +struct serialDevice * serialNewDevice(struct serialDevice *dev) { + struct serialDevice *ret; - pos = 0; - for (i=0; i< len; i+=8) { - printf("0x%.4x ", i); - for (j=i; j < len && j < i+8; j++) { - printf("0x%.2x ",data[pos++]); - } - printf("\n"); - } + 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). */ -int wait_for_input (int fd, struct timeval *timo) { +static int wait_for_input (int fd, struct timeval *timo) { fd_set ready; int n; @@ -205,72 +167,31 @@ int wait_for_input (int fd, struct timeval *timo) { return n; } -/* UNUSED */ -/* read characters into the buffer buf, until one of: */ -/* char_timeout expired before next character arrives */ -/* total_timeout expires */ -/* maxlen characters are retrieved */ -/* */ -/* returns < 0 if it fails */ -/* otherwise the # of characters received is returned */ -/* char_timeout is in microseconds (millionths of a sec) */ -/* total_timeout is in seconds */ -int timed_serial_read(int fd, int char_timeout, int total_timeout, - unsigned char *buf, int maxlen ) { - - int done, pos, starttime, temp; - struct timeval timo; - unsigned char intbuf[2]; - - /* start reading */ - done = 0; - pos = 0; - starttime=time(NULL); - memset(buf, 0, maxlen); - while (!done) { - timo.tv_sec=0; - timo.tv_usec=char_timeout; - if (wait_for_input(fd, &timo) > 0) { - temp = read( fd, intbuf, 1 ); - if (temp < 0) { - if (errno != EAGAIN) - return -1; - } else { - buf[pos++] = intbuf[0]; - buf[pos] = 0; - } - } else - done = 1; - - /* shouldnt run more than 5 seconds */ - if (time(NULL)-starttime > total_timeout ) - done = 1; - - if (pos > maxlen) - done = 1; - } - return pos; -} - - -int open_serial_port( char *port ) { +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) + 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 */ -int get_serial_lines( int fd ) { +static int get_serial_lines( int fd ) { int modem_lines; ioctl(fd, TIOCMGET, &modem_lines); @@ -278,13 +199,15 @@ int get_serial_lines( int fd ) { } /* <0 means ioctl error occurred */ -int set_serial_lines( int fd, int modem_lines ) { +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 */ -int setup_serial_port( int fd, int nbits, struct termios *attr ) { - +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); @@ -299,8 +222,10 @@ int setup_serial_port( int fd, int nbits, struct termios *attr ) { attr->c_cc[VMIN] = 1; attr->c_cc[VTIME] = 5; - cfsetospeed( attr, B1200); - cfsetispeed( attr, B1200); + if (cfsetospeed( attr, B1200)) + return -1; + if (cfsetispeed( attr, B1200)) + return -1; return tcsetattr(fd, TCSANOW, attr); } @@ -309,19 +234,19 @@ int setup_serial_port( int fd, int nbits, struct termios *attr ) { * to respond to PnP probes after they've been opened by gpm or XFree. */ -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); +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); } @@ -331,21 +256,23 @@ int init_port(int fd) { /* */ /* 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 */ -int init_pnp_com_seq1( int fd ) { +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; + return PNP_COM_FATAL; modem_lines = get_serial_lines(fd); - /* turn off RTS */ + /* 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); @@ -356,18 +283,15 @@ int init_pnp_com_seq1( int fd ) { /* see if we got DSR coming up */ if (!dsr_status) { - /* turn DTR and RTS back on and try alternative methods */ - modem_lines |= TIOCM_DTR | TIOCM_RTS; - set_serial_lines(fd, modem_lines); - rc = PNP_COM_OK; + DEBUG("Device did not set DSR\n"); } /* COM port Setup, 1st phase */ - /* 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 as PnP requires */ + + /* 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; @@ -382,16 +306,43 @@ int init_pnp_com_seq1( int fd ) { set_serial_lines(fd, modem_lines); usleep(200000); - /* now entering next phase */ + /* Wait for response, 1st phase */ modem_lines |= TIOCM_RTS; set_serial_lines(fd, modem_lines); - usleep(200000); + /* 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 */ /* */ @@ -399,7 +350,7 @@ int init_pnp_com_seq1( int fd ) { /* PNP_COM_OK - probe initiated successfully */ /* PNP_COM_FAIL - DSR never came on - try alterntives */ /* means (ATI9?) to get PnP string */ -int init_pnp_com_ati9( int fd ) { +static int init_pnp_com_ati9( int fd ) { int modem_lines; int temp; int done; @@ -409,6 +360,7 @@ int init_pnp_com_ati9( int fd ) { struct timeval timo; struct termios portattr; + DEBUG("Querying ATI9 info from modem\n"); modem_lines = get_serial_lines(fd); /* turn off RTS */ @@ -441,8 +393,7 @@ int init_pnp_com_ati9( int fd ) { usleep(200000); /* send the 'AT' command */ - if (debug_level > 0) - printf("Sending ATI9 command to modem\n"); + DEBUG("Sending ATI9 command to modem\n"); write(fd, "ATI9\r", 5); @@ -476,8 +427,7 @@ int init_pnp_com_ati9( int fd ) { if (strstr(resp, "ATI9\r")) done = 1; - if (debug_level > 0) - printf("ATI9 probe ->%d \"%s\"\n",respindex, resp); + DEBUG("ATI9 probe ->%d \"%s\"\n",respindex, resp); } /* see if we saw the 'OK' response */ @@ -501,7 +451,7 @@ int init_pnp_com_ati9( int fd ) { /* PNP_COM_OK - probe saw 'M' */ /* PNP_COM_FAIL - Never saw the 'M' response */ -int find_legacy_mouse( int fd ) { +static int find_legacy_mouse( int fd ) { int modem_lines; int temp; int done; @@ -510,6 +460,8 @@ int find_legacy_mouse( int fd ) { 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) @@ -552,9 +504,10 @@ int find_legacy_mouse( int fd ) { if (time(NULL)-starttime > 2 ) done = 1; } - if (*resp == 'M') + if (*resp == 'M') { + DEBUG("Found legacy mouse\n"); return PNP_COM_OK; - else + } else return PNP_COM_FAIL; } @@ -567,7 +520,7 @@ int find_legacy_mouse( int fd ) { /* PNP_COM_FATAL - error, errno has reason */ /* PNP_COM_OK - probe saw 'OK' */ /* PNP_COM_FAIL - Never saw the 'OK' response */ -int find_legacy_modem( int fd ) { +static int find_legacy_modem( int fd ) { int modem_lines; int temp; int done; @@ -577,6 +530,8 @@ int find_legacy_modem( int fd ) { 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) @@ -594,8 +549,7 @@ int find_legacy_modem( int fd ) { usleep(200000); /* send the 'AT' command */ - if (debug_level > 0) - printf("Sending AT command to modem\n"); + DEBUG("Sending AT command to modem\n"); write(fd, "AT\r", 3); @@ -637,7 +591,7 @@ int find_legacy_modem( int fd ) { /* timeout after 3 seconds */ /* should probably set a 200 msec timeout per char, as spec says */ /* if no char received, we're done */ -int read_pnp_string( int fd, unsigned char *pnp_string, int *pnp_len, int pnp_stringbuf_size ) { +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; @@ -645,9 +599,11 @@ int read_pnp_string( int fd, unsigned char *pnp_string, int *pnp_len, int pnp_st 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; + pnp_index = 0; seen_start = 0; done = 0; end_char = 0; @@ -659,7 +615,7 @@ int read_pnp_string( int fd, unsigned char *pnp_string, int *pnp_len, int pnp_st temp = read( fd, buf, 1 ); if (temp < 0) { if (errno != EAGAIN) - return PNP_COM_FATAL; + return PNP_COM_FAIL; } else { for (counter=0; counter < temp; counter++) { pnp_string[pnp_index++] = buf[counter]; @@ -682,30 +638,23 @@ int read_pnp_string( int fd, unsigned char *pnp_string, int *pnp_len, int pnp_st } else done = 1; - /* shouldnt run more than 4 seconds */ - if (time(NULL)-starttime > 4 ) + /* 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; - return 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; } -/* UNUSED */ -/* simple little helper function */ -void xlate_memcpy( void *dest, void *src, int len, int xlate_flag ) { - unsigned char *d, *s; - int i; - - for (i=0,d=dest,s=src; i<len; i++, d++, s++) - *d = (*s) + ((xlate_flag) ? 0x20 : 0 ); -} - /* parse the PnP ID string into components */ -int parse_pnp_string( unsigned char *pnp_id_string, int pnp_len, +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; @@ -714,7 +663,6 @@ int parse_pnp_string( unsigned char *pnp_id_string, int pnp_len, unsigned char *endfield; unsigned char *temppos; unsigned char *pnp_string; - unsigned char end_char; int no_more_extensions=0; int stage; @@ -724,6 +672,8 @@ int parse_pnp_string( unsigned char *pnp_id_string, int pnp_len, 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)); @@ -736,13 +686,23 @@ int parse_pnp_string( unsigned char *pnp_id_string, int pnp_len, 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 && p2 ) { + if ( p1 && p1end && p2 && p2end ) { start = (p1 < p2) ? p1 : p2; - } else if (p1) + } else if ( p1 && p1end ) start = p1; - else if (p2) + else if ( p2 && p2end ) start = p2; else start = NULL; @@ -758,7 +718,6 @@ int parse_pnp_string( unsigned char *pnp_id_string, int pnp_len, /* 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; @@ -773,7 +732,6 @@ int parse_pnp_string( unsigned char *pnp_id_string, int pnp_len, } } else { pnp_id->xlate_6bit = 0; - end_char = EndPnP1; } /* move everything before the start of the PnP block */ @@ -867,85 +825,43 @@ int parse_pnp_string( unsigned char *pnp_id_string, int pnp_len, return 0; } -/* UNUSED except for debugging */ -void print_pnp_id( struct pnp_com_id id ) { - int i; - int extensions_exist; - int revision_temp; - - if (id.other_len != 0) { - printf("Detected non-PnP data stream at start.\n"); - printf(" Length = 0x%x\n",id.other_len); - printf(" Contents ="); - for (i=0; i<id.other_len; i++) - printf(" 0x%x",id.other_id[i]); - printf("\n"); - } else - printf("Non-PnP data stream not detected at start.\n"); - - - /* parse PnP revision bytes into a string values (eg. "1.00") */ - revision_temp = ((id.pnp_rev[0]&0x3f) << 6)+(id.pnp_rev[1]&0x3f); - sprintf(id.pnp_rev_str, "%d.%d",revision_temp/100,revision_temp % 100); - - printf("\nPnP Required fields:\n"); - printf(" Revision = %s\n",id.pnp_rev_str); - printf(" Manufacturer = %s\n",id.eisa_id); - printf(" Product ID = %s\n",id.product_id); - - extensions_exist = id.serial_number[0] || id.class_name[0] || - id.driver_id[0] || id.user_name[0]; - - if (extensions_exist) { - printf("\nPnP extension field(s) exist:\n"); - if (id.serial_number[0]) - printf(" Serial Number = %s\n",id.serial_number); - if (id.class_name[0]) - printf(" PnP class name = %s\n",id.class_name); - if (id.driver_id[0]) - printf(" PnP Compatible = %s\n",id.driver_id); - if (id.user_name[0]) - printf(" PnP Description = %s\n",id.user_name); - } -} - -int attempt_pnp_retrieve(int fd, char *pnp_string, int *pnp_strlen, int pnp_stringbuf_size) { +static int attempt_pnp_retrieve(int fd, char *pnp_string, int *pnp_strlen, int pnp_stringbuf_size) { int pnp_probe_status; - int tried_at_prodding; - int give_up; struct pnp_com_id pnp_id; - - tried_at_prodding=0; - give_up=0; + 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); - } else if (pnp_probe_status == PNP_COM_OK) { - read_pnp_string(fd, pnp_string, pnp_strlen, pnp_stringbuf_size ); - - if (debug_level > 0) { - printf("\nPNP string = |%s|\n\n",pnp_string); - print_hex_data(pnp_string, *pnp_strlen); - } - - 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) - if (!tried_at_prodding) { - write(fd, "AT\r", 3); - tried_at_prodding=1; - } else - give_up = 1; - else - return PNP_COM_OK; + 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 - give_up = 1; - } + 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 ); @@ -962,7 +878,6 @@ struct device *serialProbe(enum deviceClass probeClass, int probeFlags, int fd; int temp; int pnp_strlen; - int devicetype=-1; unsigned char pnp_string[100]; char port[20]; struct termios origattr; @@ -973,57 +888,51 @@ struct device *serialProbe(enum deviceClass probeClass, int probeFlags, 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; - } + 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; - } - } else console = 0; - #ifdef __powerpc__ - } - #endif + fstat(fd,&sb); + maj = major(sb.st_rdev); + if (maj != 4 && (maj < 136 || maj > 143)) { + if (ioctl (fd, TIOCLINUX, &twelve) < 0) { + if (ioctl (fd, TIOCGSERIAL, &si) >= 0) { + if (si.line > 0) { + console = 1 << si.line; + } else { + console = 0; } + } else console = 0; } - close(fd); + } + close(fd); } - - + + if ( - (probeClass == CLASS_UNSPEC) || - (probeClass == CLASS_OTHER) || - (probeClass == CLASS_MOUSE) || - (probeClass == CLASS_MODEM) || - (probeClass == CLASS_PRINTER) + (probeClass & CLASS_UNSPEC) || + (probeClass & CLASS_OTHER) || + (probeClass & CLASS_MOUSE) || + (probeClass & CLASS_MODEM) || + (probeClass & CLASS_PRINTER) ) { int x; @@ -1035,82 +944,77 @@ struct device *serialProbe(enum deviceClass probeClass, int probeFlags, /* Make sure it's not in use */ snprintf(lockfile,32,"/var/lock/LCK..ttyS%d",x); - if (!stat(lockfile,&sbuf)) - continue; + 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)) - continue; + 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; + continue; } /* save the current state of the port */ temp = tcgetattr(fd, &origattr); if (temp < 0) { - close(fd); - continue; + 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; - attempt_pnp_retrieve( fd, pnp_string, &pnp_strlen, sizeof(pnp_string) - 1 ); - + 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) { - if (*pnp_string == 'M') { /* Legacy mouse */ - if (probeClass == CLASS_MOUSE || probeClass == CLASS_UNSPEC) { - serdev = serialNewDevice(NULL); - serdev->class=CLASS_MOUSE; - serdev->device=strdup(port+5); - serdev->desc=strdup("Generic Serial Mouse"); - serdev->driver=strdup("generic"); - if (devlist) - serdev->next = devlist; - devlist = (struct device *)serdev; - if (probeFlags & PROBE_ONE) { - tcsetattr(fd, TCSANOW, &origattr); - tcflush(fd, TCIOFLUSH); - close(fd); - return devlist; - } - } - tcsetattr(fd, TCSANOW, &origattr); - close(fd); - continue; - } + 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) { - goto endprobe; + DEBUG("Got PNP data back, but failed to parse. Aborting\n"); + goto endprobe; } else { char *foo; int len; - if (debug_level > 0) { - printf("PnP ID string for serial device on port %s\n",port); - print_pnp_id( pnp_id ); - } + 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; + 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); + 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; + 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); + 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); + serdev->pnpmfr = strdup(pnp_id.eisa_id); + serdev->pnpmodel = strdup(pnp_id.product_id); free(foo); foo=pnp_id.product_id; @@ -1119,87 +1023,97 @@ struct device *serialProbe(enum deviceClass probeClass, int probeFlags, foo = strstr(pnp_id.driver_id,"PNP")+3; serdev->pnpcompat = strdup(pnp_id.driver_id); } - if (!strncmp(foo, "0F", 2)) - serdev->class = CLASS_MOUSE; - else if (!strncmp(foo, "C", 1)) - serdev->class = CLASS_MODEM; - else if (!strncmp(pnp_id.class_name, "Modem", 5)) - serdev->class = CLASS_MODEM; + + 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->class = CLASS_OTHER; - if (serdev->class == probeClass || probeClass == CLASS_UNSPEC) { - if (devlist) - serdev->next = devlist; - devlist = (struct device *)serdev; - if (probeFlags & PROBE_ONE) { - tcsetattr(fd, TCSANOW, &origattr); - tcflush(fd, TCIOFLUSH); - close(fd); - return devlist; - } + 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); + 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_UNSPEC || probeClass == CLASS_MOUSE) { - serdev=serialNewDevice(NULL); - serdev->class = 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; - } + 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; + } + goto endprobe; } else { - if (debug_level > 0) - printf("Didnt see a legacy mouse, need to ATI it now.\n"); - + DEBUG("Didn't see a legacy mouse.\n"); + temp = find_legacy_modem(fd); if (temp == PNP_COM_FATAL) { - goto endprobe; + goto endprobe; } else if (temp == PNP_COM_OK) { - if (debug_level > 0) - printf("\nLegacy modem signature seen.\n\n"); - if (probeClass == CLASS_UNSPEC || probeClass == CLASS_MODEM) { - serdev=serialNewDevice(NULL); - serdev->class = 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; - } + 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; + goto endprobe; } else { - if (debug_level > 0) - printf("Didnt see a legacy modem, game over.\n"); + DEBUG("Didnt see a legacy modem, game over.\n"); } } } -endprobe: + endprobe: + DEBUG("Restoring original port attributes\n"); tcsetattr(fd, TCSANOW, &origattr); tcflush(fd, TCIOFLUSH); close(fd); diff --git a/tools/serial_probe/serial.h b/tools/serial_probe/serial.h index 75d178ce9..691abeb26 100644 --- a/tools/serial_probe/serial.h +++ b/tools/serial_probe/serial.h @@ -1,4 +1,4 @@ -/* Copyright 1999 Red Hat, Inc. +/* Copyright 1999-2003 Red Hat, Inc. * * This software may be freely redistributed under the terms of the GNU * public license. @@ -18,7 +18,7 @@ struct serialDevice { /* common fields */ struct device *next; /* next device in list */ int index; - enum deviceClass class; /* type */ + 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 */ diff --git a/tools/serial_probe/serial_probe.c b/tools/serial_probe/serial_probe.c index b8abb6917..a9aae52e5 100644 --- a/tools/serial_probe/serial_probe.c +++ b/tools/serial_probe/serial_probe.c @@ -1,4 +1,4 @@ -/* Copyright 1999 MandrakeSoft <fpons@mandrakesoft.com> +/* Copyright 1999 Mandrakesoft <fpons@mandrakesoft.com> * * The following file used by this one are copyrighted by RedHat and * are taken from kudzu : @@ -39,9 +39,9 @@ struct device *newDevice(struct device *old, struct device *new) { new = malloc(sizeof(struct device)); memset(new,'\0',sizeof(struct device)); } - new->class = CLASS_UNSPEC; + new->type = CLASS_UNSPEC; } else { - new->class = old->class; + 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); @@ -74,7 +74,29 @@ int main () { while (devices) { serialDevice = (struct serialDevice*)devices; - printf("CLASS=%s\n", classStrings[serialDevice->class]); + 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); |