Hi,

Since it looks like my usb-serial patch against 2.3.99-pre7-2 didn't
make it in (but my patch against 2.3.99-pre7-4 did), so here's that
patch again, with a few new updates against 2.3.99-pre7-5.

It fixes the problems with devfs and moves the usb-serial driver to
usb/tts/{0,1,...}, updates some of the documentation, and fixes some
problems in the whiteheat driver (like now open and close actually
work.)

Thanks,

greg k-h
greg@(kroah|wirex).com
diff -Naur -X dontdiff linux-2.3.99-pre7-5/Documentation/usb/usb-serial.txt 
linux-2.3.99-pre7-5-greg/Documentation/usb/usb-serial.txt
--- linux-2.3.99-pre7-5/Documentation/usb/usb-serial.txt        Thu May  4 22:13:48 
2000
+++ linux-2.3.99-pre7-5-greg/Documentation/usb/usb-serial.txt   Thu May  4 22:31:09 
+2000
@@ -10,30 +10,30 @@
 
 CONFIGURATION
 
-  Currently the driver can handle up to 16 different serial interfaces at
-  one time. Once more of the drivers become stable, this number will be
-  increased to the full 256. 
+  Currently the driver can handle up to 256 different serial interfaces at
+  one time. 
 
-  The major number that the driver uses is 188 so to use the driver,
-  create the following nodes:
+  If you are not using devfs:
+    The major number that the driver uses is 188 so to use the driver,
+    create the following nodes:
        mknod /dev/ttyUSB0 c 188 0
        mknod /dev/ttyUSB1 c 188 1
        mknod /dev/ttyUSB2 c 188 2
        mknod /dev/ttyUSB3 c 188 3
-       mknod /dev/ttyUSB4 c 188 4
-       mknod /dev/ttyUSB5 c 188 5
-       mknod /dev/ttyUSB6 c 188 6
-       mknod /dev/ttyUSB7 c 188 7
-       mknod /dev/ttyUSB8 c 188 8
-       mknod /dev/ttyUSB9 c 188 9
-       mknod /dev/ttyUSB10 c 188 10
-       mknod /dev/ttyUSB11 c 188 11
-       mknod /dev/ttyUSB12 c 188 12
-       mknod /dev/ttyUSB13 c 188 13
-       mknod /dev/ttyUSB14 c 188 14
-       mknod /dev/ttyUSB15 c 188 15
-       mknod /dev/ttyUSB16 c 188 16
-
+               .
+               .
+               .
+       mknod /dev/ttyUSB254 c 188 254
+       mknod /dev/ttyUSB255 c 188 255
+
+  If you are using devfs:
+    The devices supported by this driver will show up as
+    /dev/usb/tts/{0,1,...}
+
+  When the device is connected and recognized by the driver, the driver
+  will print to the system log, which node(s) the device has been bound
+  to.
+  
 
 SPECIFIC DEVICES SUPPORTED
 
@@ -45,8 +45,9 @@
   being fully supported.
 
 Current status:
-  The device's firmware is downloaded on connection, but the use of a
-  special Anchor Chips extension is currently giving me problems.
+  The device's firmware is downloaded on connection, the new firmware 
+  runs properly and all four ports are successfuly recognized and connected.
+  Now data flow needs to be implemented properly.
   This driver is not fully operational.
 
 
@@ -61,7 +62,9 @@
   
   When the device is connected, try talking to it on the second port
   (this is usually /dev/ttyUSB1 if you do not have any other usb-serial
-  devices in the system.)
+  devices in the system.) The system log should tell you which port is
+  the port to use for the HotSync transfer. The "Generic" port can be used
+  for other device communication, such as a PPP link.
 
   There is a webpage and mailing lists for this portion of the driver at: 
   http://usbvisor.sourceforge.net/
@@ -89,6 +92,19 @@
    HW flow control
    not all of the standard USB descriptors are handled: Get_Status, Set_Feature
    O_NONBLOCK, select()
+
+
+FTDI Single Port Serial Driver
+
+  This is a single port DB-25 serial adapter. More information about this
+  device and the Linux driver can be found at:
+       http://reality.sgi.com/bryder_wellington/ftdi_sio/
+
+
+ZyXEL omni.net lcd plus ISDN TA
+
+  This is an ISDN TA. Please report both successes and troubles to the
+  author at [EMAIL PROTECTED]
 
 
 Generic Serial driver
diff -Naur -X dontdiff linux-2.3.99-pre7-5/drivers/usb/serial/ezusb_convert.pl 
linux-2.3.99-pre7-5-greg/drivers/usb/serial/ezusb_convert.pl
--- linux-2.3.99-pre7-5/drivers/usb/serial/ezusb_convert.pl     Thu May  4 22:13:48 
2000
+++ linux-2.3.99-pre7-5-greg/drivers/usb/serial/ezusb_convert.pl        Thu May  4 
+22:31:09 2000
@@ -16,8 +16,8 @@
     # ':' <len> <addr> <type> <len-data> <crc> '\r'
     #  len, type, crc are 2-char hex, addr is 4-char hex. type is 00 for
     # normal records, 01 for EOF
-    my($lenstring, $addrstring, $typestring, $reststring) =
-      /^:(\w\w)(\w\w\w\w)(\w\w)(\w+)$/;
+    my($lenstring, $addrstring, $typestring, $reststring, $doscrap) =
+      /^:(\w\w)(\w\w\w\w)(\w\w)(\w+)(\r?)$/;
     die "malformed line: $_" unless $reststring;
     last if $typestring eq '01';
     my($len) = hex($lenstring);
diff -Naur -X dontdiff linux-2.3.99-pre7-5/drivers/usb/serial/ftdi_sio.c 
linux-2.3.99-pre7-5-greg/drivers/usb/serial/ftdi_sio.c
--- linux-2.3.99-pre7-5/drivers/usb/serial/ftdi_sio.c   Thu May  4 22:13:48 2000
+++ linux-2.3.99-pre7-5-greg/drivers/usb/serial/ftdi_sio.c      Thu May  4 22:31:09 
+2000
@@ -1,7 +1,7 @@
 /*
  * USB FTDI SIO driver
  *
- *     (C) Copyright (C) 1999, 2000
+ *     Copyright (C) 1999, 2000
  *         Greg Kroah-Hartman ([EMAIL PROTECTED])
  *          Bill Ryder ([EMAIL PROTECTED])
  *
diff -Naur -X dontdiff linux-2.3.99-pre7-5/drivers/usb/serial/keyspan_pda.c 
linux-2.3.99-pre7-5-greg/drivers/usb/serial/keyspan_pda.c
--- linux-2.3.99-pre7-5/drivers/usb/serial/keyspan_pda.c        Thu May  4 22:13:48 
2000
+++ linux-2.3.99-pre7-5-greg/drivers/usb/serial/keyspan_pda.c   Thu May  4 22:31:09 
+2000
@@ -1,7 +1,7 @@
 /*
  * USB Keyspan PDA Converter driver
  *
- *     (C) Copyright (C) 1999, 2000
+ *     Copyright (C) 1999, 2000
  *         Greg Kroah-Hartman ([EMAIL PROTECTED])
  *
  *     This program is free software; you can redistribute it and/or modify
diff -Naur -X dontdiff linux-2.3.99-pre7-5/drivers/usb/serial/omninet.c 
linux-2.3.99-pre7-5-greg/drivers/usb/serial/omninet.c
--- linux-2.3.99-pre7-5/drivers/usb/serial/omninet.c    Thu May  4 22:13:48 2000
+++ linux-2.3.99-pre7-5-greg/drivers/usb/serial/omninet.c       Thu May  4 22:31:09 
+2000
@@ -8,6 +8,8 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
+ * Please report both successes and troubles to the author at [EMAIL PROTECTED]
+ *
  */
 
 #include <linux/config.h>
diff -Naur -X dontdiff linux-2.3.99-pre7-5/drivers/usb/serial/usb-serial.h 
linux-2.3.99-pre7-5-greg/drivers/usb/serial/usb-serial.h
--- linux-2.3.99-pre7-5/drivers/usb/serial/usb-serial.h Thu May  4 22:26:40 2000
+++ linux-2.3.99-pre7-5-greg/drivers/usb/serial/usb-serial.h    Thu May  4 22:31:09 
+2000
@@ -1,7 +1,7 @@
 /*
  * USB Serial Converter driver
  *
- *     (C) Copyright (C) 1999, 2000
+ *     Copyright (C) 1999, 2000
  *         Greg Kroah-Hartman ([EMAIL PROTECTED])
  *
  *     This program is free software; you can redistribute it and/or modify
@@ -20,7 +20,7 @@
 #include <linux/config.h>
 
 #define SERIAL_TTY_MAJOR       188     /* Nice legal number now */
-#define SERIAL_TTY_MINORS      16      /* Actually we are allowed 255, but this is 
good for now */
+#define SERIAL_TTY_MINORS      255     /* loads of devices :) */
 
 #define MAX_NUM_PORTS          8       /* The maximum number of ports one device can 
grab at once */
 
diff -Naur -X dontdiff linux-2.3.99-pre7-5/drivers/usb/serial/usbserial.c 
linux-2.3.99-pre7-5-greg/drivers/usb/serial/usbserial.c
--- linux-2.3.99-pre7-5/drivers/usb/serial/usbserial.c  Thu May  4 22:26:40 2000
+++ linux-2.3.99-pre7-5-greg/drivers/usb/serial/usbserial.c     Thu May  4 23:37:39 
+2000
@@ -1,7 +1,7 @@
 /*
  * USB Serial Converter driver
  *
- *     (C) Copyright (C) 1999, 2000
+ *     Copyright (C) 1999, 2000
  *         Greg Kroah-Hartman ([EMAIL PROTECTED])
  *
  *     This program is free software; you can redistribute it and/or modify
@@ -16,6 +16,10 @@
  * 
  * (05/03/2000) gkh
  *     Added the Digi Acceleport driver from Al Borchers and Peter Berger.
+ * 
+ * (05/02/2000) gkh
+ *     Changed devfs and tty register code to work properly now. This was based on
+ *     the ACM driver changes by Vojtech Pavlik.
  *
  * (04/27/2000) Ryan VanderBijl
  *     Put calls to *_paranoia_checks into one function.
@@ -295,11 +299,6 @@
 };
 
 
-/* variables needed for the tty_driver structure */
-static char *driver_name       = "usb";
-static char *tty_driver_name   = "usb/tty/%d";
-
-
 /* local function prototypes */
 static int  serial_open (struct tty_struct *tty, struct file * filp);
 static void serial_close (struct tty_struct *tty, struct file * filp);
@@ -321,6 +320,7 @@
 };
 
 static int                     serial_refcount;
+static struct tty_driver       serial_tty_driver;
 static struct tty_struct *     serial_tty[SERIAL_TTY_MINORS];
 static struct termios *                serial_termios[SERIAL_TTY_MINORS];
 static struct termios *                serial_termios_locked[SERIAL_TTY_MINORS];
@@ -886,48 +886,6 @@
 }
 
 
-static struct tty_driver * usb_serial_tty_driver_init (struct usb_serial *serial)
-{
-       struct tty_driver *serial_tty_driver;
-
-       if (!(serial_tty_driver = kmalloc(sizeof(struct tty_driver), GFP_KERNEL))) {
-               err("Out of memory");
-               return NULL;
-       }
-
-       memset (serial_tty_driver, 0x00, sizeof(struct tty_driver));
-
-       /* initialize the entries that we don't want to be NULL */
-       serial_tty_driver->magic                = TTY_DRIVER_MAGIC;
-       serial_tty_driver->driver_name          = driver_name;
-       serial_tty_driver->name                 = tty_driver_name;
-       serial_tty_driver->major                = SERIAL_TTY_MAJOR;
-       serial_tty_driver->minor_start          = serial->minor;
-       serial_tty_driver->num                  = serial->num_ports;
-       serial_tty_driver->type                 = TTY_DRIVER_TYPE_SERIAL;
-       serial_tty_driver->subtype              = SERIAL_TYPE_NORMAL;
-       serial_tty_driver->flags                = TTY_DRIVER_REAL_RAW;
-       serial_tty_driver->refcount             = &serial_refcount;
-       serial_tty_driver->table                = serial_tty;
-       serial_tty_driver->termios              = serial_termios;
-       serial_tty_driver->termios_locked       = serial_termios_locked;
-       serial_tty_driver->open                 = serial_open;
-       serial_tty_driver->close                = serial_close;
-       serial_tty_driver->write                = serial_write;
-       serial_tty_driver->write_room           = serial_write_room;
-       serial_tty_driver->ioctl                = serial_ioctl;
-       serial_tty_driver->set_termios          = serial_set_termios;
-       serial_tty_driver->throttle             = serial_throttle;
-       serial_tty_driver->unthrottle           = serial_unthrottle;
-       serial_tty_driver->break_ctl            = serial_break;
-       serial_tty_driver->chars_in_buffer      = serial_chars_in_buffer;
-       serial_tty_driver->init_termios         = tty_std_termios;
-       serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-
-       return serial_tty_driver;
-}
-
-
 static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
 {
        struct usb_serial *serial = NULL;
@@ -1047,18 +1005,6 @@
        serial->num_bulk_out = num_bulk_out;
        serial->num_interrupt_in = num_interrupt_in;
 
-       /* initialize a tty_driver for this device */
-       serial->tty_driver = usb_serial_tty_driver_init (serial);
-       if (serial->tty_driver == NULL) {
-               err("Can't create a tty_serial_driver");
-               goto probe_error;
-       }
-
-       if (tty_register_driver (serial->tty_driver)) {
-               err("failed to register tty driver");
-               goto probe_error;
-       }
-       
        /* if this device type has a startup function, call it */
        if (type->startup) {
                if (type->startup (serial)) {
@@ -1142,14 +1088,16 @@
        max_endpoints = MAX(max_endpoints, num_interrupt_in);
        for (i = 0; i < max_endpoints; ++i) {
                port = &serial->port[i];
-               port->number = i;
+               port->number = i + serial->minor;
                port->serial = serial;
                port->magic = USB_SERIAL_PORT_MAGIC;
        }
        
+       /* initialize the devfs nodes for this device and let the user know what ports 
+we are bound to */
        for (i = 0; i < serial->num_ports; ++i) {
-               info("%s converter now attached to ttyUSB%d", 
-                    type->name, serial->minor + i);
+               tty_register_devfs (&serial_tty_driver, 0, serial->port[i].number);
+               info("%s converter now attached to ttyUSB%d (or usb/tts/%d for 
+devfs)", 
+                    type->name, serial->port[i].number, serial->port[i].number);
        }
        
        return serial; /* success */
@@ -1181,13 +1129,6 @@
        /* return the minor range that this device had */
        return_serial (serial);
 
-       /* if this device has a tty_driver, then unregister it and free it */
-       if (serial->tty_driver) {
-               tty_unregister_driver (serial->tty_driver);
-               kfree (serial->tty_driver);
-               serial->tty_driver = NULL;
-       }
-
        /* free up any memory that we allocated */
        kfree (serial);
        MOD_DEC_USE_COUNT;
@@ -1237,18 +1178,13 @@
                }
 
                for (i = 0; i < serial->num_ports; ++i) {
-                       info("%s converter now disconnected from ttyUSB%d", 
serial->type->name, serial->minor + i);
+                       tty_unregister_devfs (&serial_tty_driver, 
+serial->port[i].number);
+                       info("%s converter now disconnected from ttyUSB%d", 
+serial->type->name, serial->port[i].number);
                }
 
                /* return the minor range that this device had */
                return_serial (serial);
 
-               /* if this device has a tty_driver, then unregister it and free it */
-               if (serial->tty_driver) {
-                       tty_unregister_driver (serial->tty_driver);
-                       kfree (serial->tty_driver);
-                       serial->tty_driver = NULL;
-               }
                /* free up any memory that we allocated */
                kfree (serial);
 
@@ -1260,6 +1196,35 @@
 }
 
 
+static struct tty_driver serial_tty_driver = {
+       magic:                  TTY_DRIVER_MAGIC,
+       driver_name:            "usb-serial",
+       name:                   "usb/tts/%d",
+       major:                  SERIAL_TTY_MAJOR,
+       minor_start:            0,
+       num:                    SERIAL_TTY_MINORS,
+       type:                   TTY_DRIVER_TYPE_SERIAL,
+       subtype:                SERIAL_TYPE_NORMAL,
+       flags:                  TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS,
+       
+       refcount:               &serial_refcount,
+       table:                  serial_tty,
+       termios:                serial_termios,
+       termios_locked:         serial_termios_locked,
+       
+       open:                   serial_open,
+       close:                  serial_close,
+       write:                  serial_write,
+       write_room:             serial_write_room,
+       ioctl:                  serial_ioctl,
+       set_termios:            serial_set_termios,
+       throttle:               serial_throttle,
+       unthrottle:             serial_unthrottle,
+       break_ctl:              serial_break,
+       chars_in_buffer:        serial_chars_in_buffer,
+};
+
+
 int usb_serial_init(void)
 {
        int i;
@@ -1282,9 +1247,18 @@
        if (!something)
                info ("USB Serial driver is not configured for any devices!");
 
+       /* register the tty driver */
+       serial_tty_driver.init_termios          = tty_std_termios;
+       serial_tty_driver.init_termios.c_cflag  = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+       if (tty_register_driver (&serial_tty_driver)) {
+               err("failed to register tty driver");
+               return -1;
+       }
+
        /* register the USB driver */
        result = usb_register(&usb_serial_driver);
        if (result < 0) {
+               tty_unregister_driver(&serial_tty_driver);
                err("usb_register failed for the usb-serial driver. Error number %d", 
result);
                return -1;
        }
@@ -1296,6 +1270,7 @@
 void usb_serial_exit(void)
 {
        usb_deregister(&usb_serial_driver);
+       tty_unregister_driver(&serial_tty_driver);
 }
 
 
diff -Naur -X dontdiff linux-2.3.99-pre7-5/drivers/usb/serial/visor.c 
linux-2.3.99-pre7-5-greg/drivers/usb/serial/visor.c
--- linux-2.3.99-pre7-5/drivers/usb/serial/visor.c      Thu May  4 22:26:40 2000
+++ linux-2.3.99-pre7-5-greg/drivers/usb/serial/visor.c Thu May  4 22:31:09 2000
@@ -1,7 +1,7 @@
 /*
  * USB HandSpring Visor driver
  *
- *     (C) Copyright (C) 1999, 2000
+ *     Copyright (C) 1999, 2000
  *         Greg Kroah-Hartman ([EMAIL PROTECTED])
  *
  *     This program is free software; you can redistribute it and/or modify
diff -Naur -X dontdiff linux-2.3.99-pre7-5/drivers/usb/serial/visor.h 
linux-2.3.99-pre7-5-greg/drivers/usb/serial/visor.h
--- linux-2.3.99-pre7-5/drivers/usb/serial/visor.h      Thu May  4 22:13:48 2000
+++ linux-2.3.99-pre7-5-greg/drivers/usb/serial/visor.h Thu May  4 22:31:09 2000
@@ -1,7 +1,7 @@
 /*
  * USB HandSpring Visor driver
  *
- *     (C) Copyright (C) 1999, 2000
+ *     Copyright (C) 1999, 2000
  *         Greg Kroah-Hartman ([EMAIL PROTECTED])
  *
  *     This program is free software; you can redistribute it and/or modify
diff -Naur -X dontdiff linux-2.3.99-pre7-5/drivers/usb/serial/whiteheat.c 
linux-2.3.99-pre7-5-greg/drivers/usb/serial/whiteheat.c
--- linux-2.3.99-pre7-5/drivers/usb/serial/whiteheat.c  Thu May  4 22:13:48 2000
+++ linux-2.3.99-pre7-5-greg/drivers/usb/serial/whiteheat.c     Fri May  5 00:05:56 
+2000
@@ -1,7 +1,7 @@
 /*
  * USB ConnectTech WhiteHEAT driver
  *
- *     (C) Copyright (C) 1999, 2000
+ *     Copyright (C) 1999, 2000
  *         Greg Kroah-Hartman ([EMAIL PROTECTED])
  *
  *     This program is free software; you can redistribute it and/or modify
@@ -11,6 +11,10 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  * 
+ * (05/04/2000) gkh
+ *     First cut at open and close commands. Data can flow through the ports at
+ *     default speeds now.
+ *
  * (03/26/2000) gkh
  *     Split driver up into device specific pieces.
  * 
@@ -45,6 +49,7 @@
 
 #include "whiteheat_fw.h"              /* firmware for the ConnectTech WhiteHEAT 
device */
 
+#include "whiteheat.h"                 /* WhiteHEAT specific commands */
 
 #define CONNECT_TECH_VENDOR_ID         0x0710
 #define CONNECT_TECH_FAKE_WHITE_HEAT_ID        0x0001
@@ -57,6 +62,7 @@
 static void whiteheat_throttle         (struct usb_serial_port *port);
 static void whiteheat_unthrottle       (struct usb_serial_port *port);
 static int  whiteheat_startup          (struct usb_serial *serial);
+static void whiteheat_shutdown         (struct usb_serial *serial);
 
 /* All of the device info needed for the Connect Tech WhiteHEAT */
 static __u16   connecttech_vendor_id                   = CONNECT_TECH_VENDOR_ID;
@@ -91,14 +97,124 @@
        throttle:               whiteheat_throttle,
        unthrottle:             whiteheat_unthrottle,
        set_termios:            whiteheat_set_termios,
+       shutdown:               whiteheat_shutdown,
+};
+
+struct whiteheat_private {
+       __u8                    command_finished;
+       wait_queue_head_t       wait_command;   /* for handling sleeping while waiting 
+for a command to finish */
 };
 
 
+#define COMMAND_PORT           4
+#define COMMAND_TIMEOUT                (2*HZ)  /* 2 second timeout for a command */
+
 /*****************************************************************************
  * Connect Tech's White Heat specific driver functions
  *****************************************************************************/
+static void command_port_write_callback (struct urb *urb)
+{
+       unsigned char *data = urb->transfer_buffer;
+#ifdef DEBUG
+       int i;
+#endif
+
+       dbg ("command_port_write_callback");
+
+       if (urb->status) {
+               dbg ("nonzero urb status: %d", urb->status);
+               return;
+       }
+
+#ifdef DEBUG
+       if (urb->actual_length) {
+               printk (KERN_DEBUG __FILE__ ": data read - length = %d, data = ", 
+urb->actual_length);
+               for (i = 0; i < urb->actual_length; ++i) {
+                       printk ("%.2x ", data[i]);
+               }
+               printk ("\n");
+       }
+#endif
+
+       return;
+}
+
+
+static void command_port_read_callback (struct urb *urb)
+{
+       struct whiteheat_private *info = (struct whiteheat_private *)urb->context;
+       unsigned char *data = urb->transfer_buffer;
+#ifdef DEBUG
+       int i;
+#endif
+
+       dbg ("command_port_write_callback");
+
+       if (urb->status) {
+               dbg ("nonzero urb status: %d", urb->status);
+               return;
+       }
+
+#ifdef DEBUG
+       if (urb->actual_length) {
+               printk (KERN_DEBUG __FILE__ ": data read - length = %d, data = ", 
+urb->actual_length);
+               for (i = 0; i < urb->actual_length; ++i) {
+                       printk ("%.2x ", data[i]);
+               }
+               printk ("\n");
+       }
+#endif
+
+       /* right now, if the command is COMMAND_COMPLETE, just flip the bit saying the 
+command finished */
+       /* in the future we're going to have to pay attention to the actual command 
+that completed */
+       if (data[0] == WHITEHEAT_CMD_COMPLETE) {
+               info->command_finished = TRUE;
+       }
+       
+       return;
+}
+
+
+static int whiteheat_send_cmd (struct usb_serial *serial, __u8 command, __u8 *data, 
+__u8 datasize)
+{
+       struct whiteheat_private *info;
+       struct usb_serial_port *port;
+       int timeout;
+       __u8 *transfer_buffer;
+
+       dbg("whiteheat_send_cmd: %d", command);
+
+       port = &serial->port[COMMAND_PORT];
+       info = (struct whiteheat_private *)port->private;
+       info->command_finished = FALSE;
+       
+       transfer_buffer = (__u8 *)port->write_urb->transfer_buffer;
+       transfer_buffer[0] = command;
+       memcpy (&transfer_buffer[1], data, datasize);
+       port->write_urb->transfer_buffer_length = datasize + 1;
+       if (usb_submit_urb (port->write_urb))
+               dbg ("submit urb failed");
+
+       /* wait for the command to complete */
+       timeout = COMMAND_TIMEOUT;
+       while (timeout && (info->command_finished == FALSE)) {
+               timeout = interruptible_sleep_on_timeout (&info->wait_command, 
+timeout);
+       }
+
+       if (info->command_finished == FALSE) {
+               return -1;
+       }
+
+       return 0;
+}
+
+
 static int whiteheat_open (struct usb_serial_port *port, struct file *filp)
 {
+       struct whiteheat_min_set        open_command;
+       struct usb_serial_port          *command_port;
+       struct whiteheat_private        *info;
+
        dbg("whiteheat_open port %d", port->number);
 
        if (port->active) {
@@ -106,22 +222,50 @@
                return -EINVAL;
        }
        port->active = 1;
- 
-       /*Start reading from the device*/
+
+       /* set up some stuff for our command port */
+       command_port = &port->serial->port[COMMAND_PORT];
+       if (command_port->private == NULL) {
+               info = (struct whiteheat_private *)kmalloc (sizeof(struct 
+whiteheat_private), GFP_KERNEL);
+               if (info == NULL) {
+                       err("out of memory");
+                       return -ENOMEM;
+               }
+               
+               init_waitqueue_head(&info->wait_command);
+               command_port->private = info;
+               command_port->write_urb->complete = command_port_write_callback;
+               command_port->read_urb->complete = command_port_read_callback;
+               usb_submit_urb (command_port->read_urb);        
+       }
+       
+       /* Start reading from the device */
        if (usb_submit_urb(port->read_urb))
                dbg("usb_submit_urb(read bulk) failed");
 
+       /* send an open port command */
+       open_command.port = port->number - port->minor;
+       whiteheat_send_cmd (port->serial, WHITEHEAT_OPEN, (__u8 *)&open_command, 
+sizeof(open_command));
+
        /* Need to do device specific setup here (control lines, baud rate, etc.) */
        /* FIXME!!! */
 
+       dbg("whiteheat_open exit");
+       
        return (0);
 }
 
 
 static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
 {
+       struct whiteheat_min_set        close_command;
+       
        dbg("whiteheat_close port %d", port->number);
        
+       /* send a close command to the port */
+       close_command.port = port->number - port->minor;
+       whiteheat_send_cmd (port->serial, WHITEHEAT_CLOSE, (__u8 *)&close_command, 
+sizeof(close_command));
+
        /* Need to change the control lines here */
        /* FIXME */
        
@@ -243,7 +387,24 @@
        response = ezusb_set_reset (serial, 0);
 
        /* we want this device to fail to have a driver assigned to it. */
-       return (1);
+       return 1;
+}
+
+
+static void whiteheat_shutdown (struct usb_serial *serial)
+{
+       struct usb_serial_port          *command_port;
+
+       dbg("whiteheat_shutdown");
+
+       /* set up some stuff for our command port */
+       command_port = &serial->port[COMMAND_PORT];
+       if (command_port->private != NULL) {
+               kfree (command_port->private);
+               command_port->private = NULL;
+       }
+
+       return;
 }
 
 #endif /* CONFIG_USB_SERIAL_WHITEHEAT */
diff -Naur -X dontdiff linux-2.3.99-pre7-5/drivers/usb/serial/whiteheat.h 
linux-2.3.99-pre7-5-greg/drivers/usb/serial/whiteheat.h
--- linux-2.3.99-pre7-5/drivers/usb/serial/whiteheat.h  Wed Dec 31 16:00:00 1969
+++ linux-2.3.99-pre7-5-greg/drivers/usb/serial/whiteheat.h     Thu May  4 22:56:09 
+2000
@@ -0,0 +1,169 @@
+/*
+ * USB ConnectTech WhiteHEAT driver
+ *
+ *      Copyright (C) 1999, 2000
+ *          Greg Kroah-Hartman ([EMAIL PROTECTED])
+ *
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2 of the License, or
+ *      (at your option) any later version.
+ *
+ * See Documentation/usb/usb-serial.txt for more information on using this driver
+ *
+ */
+
+#ifndef __LINUX_USB_SERIAL_WHITEHEAT_H
+#define __LINUX_USB_SERIAL_WHITEHEAT_H
+
+
+#define FALSE                          0
+#define TRUE                           1
+
+/* WhiteHEAT commands */
+#define WHITEHEAT_OPEN                 1       /* open the port */
+#define WHITEHEAT_CLOSE                        2       /* close the port */
+#define WHITEHEAT_SETUP_PORT           3       /* change port settings */
+#define WHITEHEAT_SET_RTS              4       /* turn RTS on or off */
+#define WHITEHEAT_SET_DTR              5       /* turn DTR on or off */
+#define WHITEHEAT_SET_BREAK            6       /* turn BREAK on or off */
+#define WHITEHEAT_DUMP                 7       /* dump memory */
+#define WHITEHEAT_STATUS               8       /* get status */
+#define WHITEHEAT_PURGE                        9       /* clear the UART fifos */
+#define WHITEHEAT_GET_DTR_RTS          10      /* get the state of DTR and RTS for a 
+port */
+#define WHITEHEAT_GET_HW_INFO          11      /* get EEPROM info and hardware ID */
+#define WHITEHEAT_REPORT_TX_DONE       12      /* get the next TX done */
+#define WHITEHEAT_EVENT                        13      /* unsolicited status events */
+#define WHITEHEAT_ECHO                 14      /* send data to the indicated IN 
+endpoint */
+#define WHITEHEAT_DO_TEST              15      /* perform the specified test */
+#define WHITEHEAT_CMD_COMPLETE         16      /* reply for certain commands */
+
+/* Data for the WHITEHEAT_SETUP_PORT command */
+#define WHITEHEAT_CTS_FLOW             0x08
+#define WHITEHEAT_RTS_FLOW             0x80
+#define WHITEHEAT_DSR_FLOW             0x10
+#define WHITEHEAT_DTR_FLOW             0x02
+struct whiteheat_port_settings {
+       __u8    port;           /* port number (1 to N) */
+       __u32   baud;           /* any value allowed, default 9600, arrives little 
+endian, range is 7 - 460800 */
+       __u8    bits;           /* 5, 6, 7, or 8, default 8 */
+       __u8    stop;           /* 1 or 2, default 1 (2 = 1.5 if bits = 5) */
+       __u8    parity;         /* 'n, e, o, 0, or 1' (ascii), default 'n'
+                                *      n = none        e = even        o = odd
+                                *      0 = force 0     1 = force 1     */
+       __u8    sflow;          /* 'n, r, t, or b' (ascii), default 'n'
+                                *      n = none
+                                *      r = receive (XOFF/XON transmitted when 
+receiver fills / empties)
+                                *      t = transmit (XOFF/XON received will 
+stop/start TX)
+                                *      b = both        */
+       __u8    xoff;           /* XOFF byte value, default 0x13 */
+       __u8    xon;            /* XON byte value, default 0x11 */
+       __u8    hflow;          /* bits indicate mode as follows:
+                                *      CTS (0x08) (CTS off/on will control/cause TX 
+off/on)
+                                *      DSR (0x10) (DSR off/on will control/cause TX 
+off/on)
+                                *      RTS (0x80) (RTS off/on when receiver 
+fills/empties)
+                                *      DTR (0x02) (DTR off/on when receiver 
+fills/empties) */
+       __u8    lloop;          /* local loopback 0 or 1, default 0 */
+};
+
+/* data for WHITEHEAT_SET_RTS, WHITEHEAT_SET_DTR, and WHITEHEAT_SET_BREAK commands */
+struct whiteheat_rdb_set {
+       __u8    port;           /* port number (1 to N) */
+       __u8    state;          /* 0 = off, non-zero = on */
+};
+
+/* data for:
+       WHITEHEAT_OPEN
+       WHITEHEAT_CLOSE
+       WHITEHEAT_STATUS
+       WHITEHEAT_GET_DTR_RTS
+       WHITEHEAT_REPORT_TX_DONE */
+struct whiteheat_min_set {
+       __u8    port;           /* port number (1 to N) */
+};
+
+/* data for WHITEHEAT_PURGE command */
+#define WHITEHEAT_PURGE_INPUT          0x01
+#define WHITEHEAT_PURGE_OUTPUT         0x02
+struct whiteheat_purge_set {
+       __u8    port;           /* port number (1 to N) */
+       __u8    what;           /* bit pattern of what to purge */
+};
+
+/* data for WHITEHEAT_DUMP command */
+struct whiteheat_dump_info {
+       __u8    mem_type;       /* memory type: 'd' = data, 'i' = idata, 'b' = bdata, 
+'x' = xdata */
+       __u16   addr;           /* memory address to dump, address range depends on 
+the above mem_type:
+                                *      'd' = 0 to ff (80 to FF is SFR's)
+                                *      'i' = 80 to ff
+                                *      'b' = 20 to 2f (bits returned as bytes)
+                                *      'x' = 0000 to ffff (also code space)    */
+       __u16   length;         /* number of bytes to dump, max 64 */
+};
+
+/* data for WHITEHEAT_ECHO command */
+struct whiteheat_echo_set {
+       __u8    port;           /* port number (1 to N) */
+       __u8    length;         /* length of message to echo */
+       __u8    echo_data[61];  /* data to echo */
+};
+
+/* data returned from WHITEHEAT_STATUS command */
+#define WHITEHEAT_OVERRUN_ERROR                0x02
+#define WHITEHEAT_PARITY_ERROR         0x04
+#define WHITEHEAT_FRAMING_ERROR                0x08
+#define WHITEHEAT_BREAK_ERROR          0x10
+
+#define WHITEHEAT_OHFLOW               0x01    /* TX is stopped by CTS (waiting for 
+CTS to go ON) */
+#define WHITEHEAT_IHFLOW               0x02    /* remote TX is stopped by RTS */
+#define WHITEHEAT_OSFLOW               0x04    /* TX is stopped by XOFF received 
+(waiting for XON to occur) */
+#define WHITEHEAT_ISFLOW               0x08    /* remote TX is stopped by XOFF 
+transmitted */
+#define WHITEHEAT_TX_DONE              0x80    /* TX has completed */
+
+#define WHITEHEAT_MODEM_EVENT          0x01
+#define WHITEHEAT_ERROR_EVENT          0x02
+#define WHITEHEAT_FLOW_EVENT           0x04
+#define WHITEHEAT_CONNECT_EVENT                0x08
+struct whiteheat_status_info {
+       __u8    port;           /* port number (1 to N) */
+       __u8    event;          /* indicates which of the following bytes are the 
+current event */
+       __u8    modem;          /* modem signal status (copy of UART MSR register) */
+       __u8    error;          /* PFO and RX break (copy of UART LSR register) */
+       __u8    flow;           /* flow control state */
+       __u8    connect;        /* connect state, non-zero value indicates connected */
+};
+
+/* data returned from WHITEHEAT_EVENT command */
+struct whiteheat_event {
+       __u8    port;           /* port number (1 to N) */
+       __u8    event;          /* indicates which of the following bytes are the 
+current event */
+       __u8    info;           /* either modem, error, flow, or connect information */
+};
+
+/* data retured by the WHITEHEAT_GET_HW_INFO command */
+struct whiteheat_hw_info {
+       __u8    hw_id;          /* hardware id number, WhiteHEAT = 0 */
+       __u8    sw_major_rev;   /* major version number */
+       __u8    sw_minor_rev;   /* minor version number */
+       struct whiteheat_hw_eeprom_info {
+               __u8    b0;                     /* B0 */
+               __u8    vendor_id_low;          /* vendor id (low byte) */
+               __u8    vendor_id_high;         /* vendor id (high byte) */
+               __u8    product_id_low;         /* product id (low byte) */
+               __u8    product_id_high;        /* product id (high byte) */
+               __u8    device_id_low;          /* device id (low byte) */
+               __u8    device_id_high;         /* device id (high byte) */
+               __u8    not_used_1;
+               __u8    serial_number_0;        /* serial number (low byte) */
+               __u8    serial_number_1;        /* serial number */
+               __u8    serial_number_2;        /* serial number */
+               __u8    serial_number_3;        /* serial number (high byte) */
+               __u8    not_used_2;
+               __u8    not_used_3;
+               __u8    checksum_low;           /* checksum (low byte) */
+               __u8    checksum_high;          /* checksum (high byte */
+       } hw_eeprom_info;       /* EEPROM contents */
+};
+
+#endif
+

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to