Hi,

Here's a patch for the usb-serial driver that does a number of things:
 - Fixes the static urbs, now all urbs that the driver uses are created
   with usb_alloc_urb and released with usb_free_urb.
 - Fixes a few oops that can happen (and did) when a device is removed
   while a program is trying to talk to it.
 - Moves the internal structure of the driver to be based on a port
   instead of a whole device. This fixes the problem that multiport
   devices could not have more than one port open at one time. It also
   cleaned up the code a bit.
 - Adds my name to the CREDITS file.

It is against 2.3.99-pre2.

Thanks,

greg k-h
[EMAIL PROTECTED]
diff -Naur -X dontdiff linux-2.3.99-pre2/CREDITS linux-2.3.99-pre2-greg/CREDITS
--- linux-2.3.99-pre2/CREDITS   Sun Mar 19 16:36:45 2000
+++ linux-2.3.99-pre2-greg/CREDITS      Sun Mar 19 16:48:05 2000
@@ -1327,6 +1327,13 @@
 E: [EMAIL PROTECTED]
 D: CYPRESS CY82C693 chipset IDE, Digital's PC-Alpha 164SX boards
 
+N: Greg Kroah-Hartman
+E: [EMAIL PROTECTED]
+W: http://www.kroah.com/linux-usb/
+D: USB Serial Converter driver framework, USB Handspring Visor driver
+D: ConnectTech WHITEHeat USB driver, Generic USB Serial driver
+D: bits and pieces of USB core code.
+
 N: Russell Kroll
 E: [EMAIL PROTECTED]
 W: http://www.exploits.org/
diff -Naur -X dontdiff linux-2.3.99-pre2/drivers/usb/serial/usb-serial.c 
linux-2.3.99-pre2-greg/drivers/usb/serial/usb-serial.c
--- linux-2.3.99-pre2/drivers/usb/serial/usb-serial.c   Sun Mar 19 16:36:46 2000
+++ linux-2.3.99-pre2-greg/drivers/usb/serial/usb-serial.c      Sun Mar 19 16:41:18 
+2000
@@ -14,6 +14,16 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  * 
+ * (03/19/2000) gkh
+ *     Fixed oops that could happen when device was removed while a program
+ *     was talking to the device.
+ *     Removed the static urbs and now all urbs are created and destroyed
+ *     dynamically.
+ *     Reworked the internal interface. Now everything is based on the 
+ *     usb_serial_port structure instead of the larger usb_serial structure.
+ *     This fixes the bug that a multiport device could not have more than
+ *     one port open at one time.
+ *
  * (03/17/2000) gkh
  *     Added config option for debugging messages.
  *     Added patch for keyspan pda from Brian Warner.
@@ -220,10 +230,9 @@
 static void usb_serial_disconnect(struct usb_device *dev, void *ptr);
 
 static struct usb_driver usb_serial_driver = {
-       "serial",
-       usb_serial_probe,
-       usb_serial_disconnect,
-       { NULL, NULL }
+       name:           "serial",
+       probe:          usb_serial_probe,
+       disconnect:     usb_serial_disconnect,
 };
 
 static int                     serial_refcount;
@@ -233,11 +242,50 @@
 static struct usb_serial       *serial_table[SERIAL_TTY_MINORS] = {NULL, };
 
 
+static inline int serial_paranoia_check (struct usb_serial *serial, const char 
+*function)
+{
+       if (!serial) {
+               dbg("%s - serial == NULL", function);
+               return -1;
+       }
+       if (serial->magic != USB_SERIAL_MAGIC) {
+               dbg("%s - bad magic number for serial", function);
+               return -1;
+       }
+       if (!serial->type) {
+               dbg("%s - serial->type == NULL!", function);
+               return -1;
+       }
 
-static struct usb_serial *get_serial_by_minor (int minor)
+       return 0;
+}
+
+
+static inline int port_paranoia_check (struct usb_serial_port *port, const char 
+*function)
 {
-       dbg("get_serial_by_minor %d", minor);
+       if (!port) {
+               dbg("%s - port == NULL", function);
+               return -1;
+       }
+       if (port->magic != USB_SERIAL_PORT_MAGIC) {
+               dbg("%s - bad magic number for port", function);
+               return -1;
+       }
+       if (!port->serial) {
+               dbg("%s - port->serial == NULL", function);
+               return -1;
+       }
+       if (!port->tty) {
+               dbg("%s - port->tty == NULL", function);
+               return -1;
+       }
 
+       return 0;
+}
+
+
+static struct usb_serial *get_serial_by_minor (int minor)
+{
        return serial_table[minor];
 }
 
@@ -267,6 +315,7 @@
                        return NULL;
                }
                memset(serial, 0, sizeof(struct usb_serial));
+               serial->magic = USB_SERIAL_MAGIC;
                serial_table[i] = serial;
                *minor = i;
                dbg("minor base = %d", *minor);
@@ -337,6 +386,8 @@
 static int serial_open (struct tty_struct *tty, struct file * filp)
 {
        struct usb_serial *serial;
+       struct usb_serial_port *port;
+       int portNumber;
        
        dbg("serial_open");
 
@@ -346,180 +397,182 @@
        /* get the serial object associated with this tty pointer */
        serial = get_serial_by_minor (MINOR(tty->device));
 
-       /* do some sanity checking that we really have a device present */
-       if (!serial) {
-               dbg("serial == NULL!");
-               return (-ENODEV);
-       }
-       if (!serial->type) {
-               dbg("serial->type == NULL!");
-               return (-ENODEV);
+       if (serial_paranoia_check (serial, "serial_open")) {
+               return -ENODEV;
        }
 
-       /* make the tty driver remember our serial object, and us it */
-       tty->driver_data = serial;
-       serial->tty = tty;
+       /* set up our port structure */
+       portNumber = MINOR(tty->device) - serial->minor;
+       port = &serial->port[portNumber];
+       port->number = portNumber;
+       port->serial = serial;
+       port->magic = USB_SERIAL_PORT_MAGIC;
+       
+       /* make the tty driver remember our port object, and us it */
+       tty->driver_data = port;
+       port->tty = tty;
         
        /* pass on to the driver specific version of this function if it is available 
*/
        if (serial->type->open) {
-               return (serial->type->open(tty, filp));
+               return (serial->type->open(port, filp));
        } else {
-               return (generic_serial_open(tty, filp));
+               return (generic_open(port, filp));
        }
 }
 
 
 static void serial_close(struct tty_struct *tty, struct file * filp)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port;       
+       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial *serial;
 
        dbg("serial_close");
 
-       if (!serial) {
-               dbg("serial == NULL!");
+       if (port_paranoia_check (port, "serial_close")) {
                return;
        }
 
-       port = MINOR(tty->device) - serial->minor;
-
-       dbg("serial_close port %d", port);
-       
-       /* do some sanity checking that we really have a device present */
-       if (!serial->type) {
-               dbg("serial->type == NULL!");
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "serial_close")) {
                return;
        }
-       if (!serial->port[port].active) {
-               dbg ("device not opened");
+
+       dbg("serial_close port %d", port->number);
+       
+       if (!port->active) {
+               dbg ("port not opened");
                return;
        }
 
        /* pass on to the driver specific version of this function if it is available 
*/
        if (serial->type->close) {
-               serial->type->close(tty, filp);
+               serial->type->close(port, filp);
        } else {
-               generic_serial_close(tty, filp);
+               generic_close(port, filp);
        }
 }      
 
 
 static int serial_write (struct tty_struct * tty, int from_user, const unsigned char 
*buf, int count)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
+       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial *serial;
        
-       dbg("serial_write port %d, %d byte(s)", port, count);
-
-       /* do some sanity checking that we really have a device present */
-       if (!serial) {
-               dbg("serial == NULL!");
-               return (-ENODEV);
+       dbg("serial_write");
+       
+       if (port_paranoia_check (port, "serial_write")) {
+               return -ENODEV;
        }
-       if (!serial->type) {
-               dbg("serial->type == NULL!");
-               return (-ENODEV);
+       
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "serial_write")) {
+               return -ENODEV;
        }
-       if (!serial->port[port].active) {
-               dbg ("device not opened");
-               return (-EINVAL);
+       
+       dbg("serial_write port %d, %d byte(s)", port->number, count);
+
+       if (!port->active) {
+               dbg ("port not opened");
+               return -EINVAL;
        }
        
        /* pass on to the driver specific version of this function if it is available 
*/
        if (serial->type->write) {
-               return (serial->type->write(tty, from_user, buf, count));
+               return (serial->type->write(port, from_user, buf, count));
        } else {
-               return (generic_serial_write(tty, from_user, buf, count));
+               return (generic_write(port, from_user, buf, count));
        }
 }
 
 
 static int serial_write_room (struct tty_struct *tty) 
 {
-       struct usb_serial *serial = (struct usb_serial *)tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
-
-       dbg("serial_write_room port %d", port);
+       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial *serial;
        
-       /* do some sanity checking that we really have a device present */
-       if (!serial) {
-               dbg("serial == NULL!");
-               return (-ENODEV);
+       dbg("serial_write_room");
+       
+       if (port_paranoia_check (port, "serial_write")) {
+               return -ENODEV;
        }
-       if (!serial->type) {
-               dbg("serial->type == NULL!");
-               return (-ENODEV);
+       
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "serial_write")) {
+               return -ENODEV;
        }
-       if (!serial->port[port].active) {
-               dbg ("device not open");
-               return (-EINVAL);
+       
+       dbg("serial_write_room port %d", port->number);
+       
+       if (!port->active) {
+               dbg ("port not open");
+               return -EINVAL;
        }
        
        /* pass on to the driver specific version of this function if it is available 
*/
        if (serial->type->write_room) {
-               return (serial->type->write_room(tty));
+               return (serial->type->write_room(port));
        } else {
-               return (generic_write_room(tty));
+               return (generic_write_room(port));
        }
 }
 
 
 static int serial_chars_in_buffer (struct tty_struct *tty) 
 {
-       struct usb_serial *serial = (struct usb_serial *)tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
-
-       dbg("serial_chars_in_buffer port %d", port);
+       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial *serial;
        
-       /* do some sanity checking that we really have a device present */
-       if (!serial) {
-               dbg("serial == NULL!");
-               return (-ENODEV);
+       dbg("serial_chars_in_buffer");
+       
+       if (port_paranoia_check (port, "serial_chars_in_buffer")) {
+               return -ENODEV;
        }
-       if (!serial->type) {
-               dbg("serial->type == NULL!");
-               return (-ENODEV);
+       
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "serial_chars_in_buffer")) {
+               return -ENODEV;
        }
-       if (!serial->port[port].active) {
-               dbg ("device not open");
-               return (-EINVAL);
+       
+       if (!port->active) {
+               dbg ("port not open");
+               return -EINVAL;
        }
        
        /* pass on to the driver specific version of this function if it is available 
*/
        if (serial->type->chars_in_buffer) {
-               return (serial->type->chars_in_buffer(tty));
+               return (serial->type->chars_in_buffer(port));
        } else {
-               return (generic_chars_in_buffer(tty));
+               return (generic_chars_in_buffer(port));
        }
 }
 
 
 static void serial_throttle (struct tty_struct * tty)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
-
-       dbg("serial_throttle port %d", port);
+       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial *serial;
        
-       /* do some sanity checking that we really have a device present */
-       if (!serial) {
-               dbg("serial == NULL!");
+       dbg("serial_throttle");
+       
+       if (port_paranoia_check (port, "serial_throttle")) {
                return;
        }
-       if (!serial->type) {
-               dbg("serial->type == NULL!");
+       
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "serial_throttle")) {
                return;
        }
-       if (!serial->port[port].active) {
-               dbg ("device not open");
+       
+       dbg("serial_throttle port %d", port->number);
+       
+       if (!port->active) {
+               dbg ("port not open");
                return;
        }
 
        /* pass on to the driver specific version of this function */
        if (serial->type->throttle) {
-               serial->type->throttle(tty);
-       } else {
-               generic_throttle(tty);
+               serial->type->throttle(port);
        }
 
        return;
@@ -528,30 +581,30 @@
 
 static void serial_unthrottle (struct tty_struct * tty)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
-
-       dbg("serial_unthrottle port %d", port);
+       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial *serial;
        
-       /* do some sanity checking that we really have a device present */
-       if (!serial) {
-               dbg("serial == NULL!");
+       dbg("serial_unthrottle");
+       
+       if (port_paranoia_check (port, "serial_unthrottle")) {
                return;
        }
-       if (!serial->type) {
-               dbg("serial->type == NULL!");
+       
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "serial_unthrottle")) {
                return;
        }
-       if (!serial->port[port].active) {
-               dbg ("device not open");
+       
+       dbg("serial_unthrottle port %d", port->number);
+       
+       if (!port->active) {
+               dbg ("port not open");
                return;
        }
 
        /* pass on to the driver specific version of this function */
        if (serial->type->unthrottle) {
-               serial->type->unthrottle(tty);
-       } else {
-               generic_unthrottle(tty);
+               serial->type->unthrottle(port);
        }
 
        return;
@@ -560,70 +613,62 @@
 
 static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int 
cmd, unsigned long arg)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port;       
-
+       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial *serial;
+       
        dbg("serial_ioctl");
-
-       if (!serial) {
-               dbg("serial == NULL!");
+       
+       if (port_paranoia_check (port, "serial_ioctl")) {
                return -ENODEV;
        }
 
-       port = MINOR(tty->device) - serial->minor;
-
-       dbg("serial_ioctl port %d", port);
-       
-       /* do some sanity checking that we really have a device present */
-       if (!serial->type) {
-               dbg("serial->type == NULL!");
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "serial_ioctl")) {
                return -ENODEV;
        }
-       if (!serial->port[port].active) {
-               dbg ("device not open");
+       
+       dbg("serial_ioctl port %d", port->number);
+       
+       if (!port->active) {
+               dbg ("port not open");
                return -ENODEV;
        }
 
        /* pass on to the driver specific version of this function if it is available 
*/
        if (serial->type->ioctl) {
-               return (serial->type->ioctl(tty, file, cmd, arg));
+               return (serial->type->ioctl(port, file, cmd, arg));
        } else {
-               return (generic_ioctl (tty, file, cmd, arg));
+               return -ENOIOCTLCMD;
        }
 }
 
 
 static void serial_set_termios (struct tty_struct *tty, struct termios * old)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port;       
-
+       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial *serial;
+       
        dbg("serial_set_termios");
-
-       if (!serial) {
-               dbg("serial == NULL!");
+       
+       if (port_paranoia_check (port, "serial_set_termios")) {
                return;
        }
 
-       port = MINOR(tty->device) - serial->minor;
-
-       dbg("serial_set_termios port %d", port);
-       
-       /* do some sanity checking that we really have a device present */
-       if (!serial->type) {
-               dbg("serial->type == NULL!");
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "serial_set_termios")) {
                return;
        }
-       if (!serial->port[port].active) {
-               dbg ("device not open");
+
+       dbg("serial_set_termios port %d", port->number);
+
+       if (!port->active) {
+               dbg ("port not open");
                return;
        }
 
        /* pass on to the driver specific version of this function if it is available 
*/
        if (serial->type->set_termios) {
-               serial->type->set_termios(tty, old);
-       } else {
-               generic_set_termios (tty, old);
+               serial->type->set_termios(port, old);
        }
        
        return;
@@ -632,32 +677,31 @@
 
 static void serial_break (struct tty_struct *tty, int break_state)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port;       
-
-       if (!serial) {
-               dbg("serial == NULL!");
+       struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+       struct usb_serial *serial;
+       
+       dbg("serial_break");
+       
+       if (port_paranoia_check (port, "serial_break")) {
                return;
        }
 
-       port = MINOR(tty->device) - serial->minor;
-
-       dbg("serial_break port %d", port);
-       
-       /* do some sanity checking that we really have a device present */
-       if (!serial->type) {
-               dbg("serial->type == NULL!");
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "serial_break")) {
                return;
        }
-       if (!serial->port[port].active) {
-               dbg ("device not open");
+
+       dbg("serial_break port %d", port->number);
+
+       if (!port->active) {
+               dbg ("port not open");
                return;
        }
 
        /* pass on to the driver specific version of this function if it is
            available */
        if (serial->type->break_ctl) {
-               serial->type->break_ctl(tty, break_state);
+               serial->type->break_ctl(port, break_state);
        }
 }
 
@@ -666,13 +710,9 @@
 /*****************************************************************************
  * Connect Tech's White Heat specific driver functions
  *****************************************************************************/
-static int whiteheat_serial_open (struct tty_struct *tty, struct file *filp)
+static int whiteheat_open (struct usb_serial_port *port, struct file *filp)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
-
-       dbg("whiteheat_serial_open port %d", portNumber);
+       dbg("whiteheat_open port %d", port->number);
 
        if (port->active) {
                dbg ("device already open");
@@ -681,7 +721,7 @@
        port->active = 1;
  
        /*Start reading from the device*/
-       if (usb_submit_urb(&port->read_urb))
+       if (usb_submit_urb(port->read_urb))
                dbg("usb_submit_urb(read bulk) failed");
 
        /* Need to do device specific setup here (control lines, baud rate, etc.) */
@@ -691,36 +731,30 @@
 }
 
 
-static void whiteheat_serial_close(struct tty_struct *tty, struct file * filp)
+static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
-
-       dbg("whiteheat_serial_close port %d", portNumber);
+       dbg("whiteheat_close port %d", port->number);
        
        /* Need to change the control lines here */
        /* FIXME */
        
        /* shutdown our bulk reads and writes */
-       usb_unlink_urb (&port->write_urb);
-       usb_unlink_urb (&port->read_urb);
+       usb_unlink_urb (port->write_urb);
+       usb_unlink_urb (port->read_urb);
        port->active = 0;
 }
 
 
-static void whiteheat_set_termios (struct tty_struct *tty, struct termios 
*old_termios)
+static void whiteheat_set_termios (struct usb_serial_port *port, struct termios 
+*old_termios)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
-       unsigned int cflag = tty->termios->c_cflag;
+       unsigned int cflag = port->tty->termios->c_cflag;
 
-       dbg("whiteheat_set_termios port %d", port);
+       dbg("whiteheat_set_termios port %d", port->number);
 
        /* check that they really want us to change something */
        if (old_termios) {
                if ((cflag == old_termios->c_cflag) &&
-                   (RELEVANT_IFLAG(tty->termios->c_iflag) == 
RELEVANT_IFLAG(old_termios->c_iflag))) {
+                   (RELEVANT_IFLAG(port->tty->termios->c_iflag) == 
+RELEVANT_IFLAG(old_termios->c_iflag))) {
                        dbg("nothing to change...");
                        return;
                }
@@ -732,12 +766,9 @@
        return;
 }
 
-static void whiteheat_throttle (struct tty_struct * tty)
+static void whiteheat_throttle (struct usb_serial_port *port)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
-
-       dbg("whiteheat_throttle port %d", port);
+       dbg("whiteheat_throttle port %d", port->number);
 
        /* Change the control signals */
        /* FIXME!!! */
@@ -746,12 +777,9 @@
 }
 
 
-static void whiteheat_unthrottle (struct tty_struct * tty)
+static void whiteheat_unthrottle (struct usb_serial_port *port)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
-
-       dbg("whiteheat_unthrottle port %d", port);
+       dbg("whiteheat_unthrottle port %d", port->number);
 
        /* Change the control signals */
        /* FIXME!!! */
@@ -837,13 +865,9 @@
 /******************************************************************************
  * Handspring Visor specific driver functions
  ******************************************************************************/
-static int visor_serial_open (struct tty_struct *tty, struct file *filp)
+static int visor_open (struct usb_serial_port *port, struct file *filp)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data;
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
-
-       dbg("visor_serial_open port %d", portNumber);
+       dbg("visor_open port %d", port->number);
 
        if (port->active) {
                dbg ("device already open");
@@ -853,23 +877,22 @@
        port->active = 1;
 
        /*Start reading from the device*/
-       if (usb_submit_urb(&port->read_urb))
+       if (usb_submit_urb(port->read_urb))
                dbg("usb_submit_urb(read bulk) failed");
 
        return (0);
 }
 
-static void visor_serial_close(struct tty_struct *tty, struct file * filp)
+
+static void visor_close (struct usb_serial_port *port, struct file * filp)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data;
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
+       struct usb_serial *serial = port->serial;
        unsigned char *transfer_buffer =  kmalloc (0x12, GFP_KERNEL);
        
-       dbg("visor_serial_close port %d", portNumber);
+       dbg("visor_close port %d", port->number);
                         
        if (!transfer_buffer) {
-               err("visor_serial_close: kmalloc(%d) failed.", 0x12);
+               err("visor_close: kmalloc(%d) failed.", 0x12);
        } else {
                /* send a shutdown message to the device */
                usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), 
VISOR_CLOSE_NOTIFICATION,
@@ -877,33 +900,27 @@
        }
 
        /* shutdown our bulk reads and writes */
-       usb_unlink_urb (&port->write_urb);
-       usb_unlink_urb (&port->read_urb);
+       usb_unlink_urb (port->write_urb);
+       usb_unlink_urb (port->read_urb);
        port->active = 0;
 }
 
 
-static void visor_throttle (struct tty_struct * tty)
+static void visor_throttle (struct usb_serial_port *port)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data;
-       int port = MINOR(tty->device) - serial->minor;
-
-       dbg("visor_throttle port %d", port);
+       dbg("visor_throttle port %d", port->number);
 
-       usb_unlink_urb (&serial->port[port].read_urb);
+       usb_unlink_urb (port->read_urb);
 
        return;
 }
 
 
-static void visor_unthrottle (struct tty_struct * tty)
+static void visor_unthrottle (struct usb_serial_port *port)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data;
-       int port = MINOR(tty->device) - serial->minor;
+       dbg("visor_unthrottle port %d", port->number);
 
-       dbg("visor_unthrottle port %d", port);
-
-       if (usb_unlink_urb (&serial->port[port].read_urb))
+       if (usb_unlink_urb (port->read_urb))
                dbg("usb_submit_urb(read bulk) failed");
 
        return;
@@ -988,17 +1005,15 @@
 
 #include "ftdi_sio.h"
 
-static int  ftdi_sio_serial_open (struct tty_struct *tty, struct file *filp)
+static int  ftdi_sio_open (struct usb_serial_port *port, struct file *filp)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
+       struct usb_serial *serial = port->serial;
        char buf[1]; /* Needed for the usb_control_msg I think */
 
-       dbg("ftdi_sio_serial_open port %d", portNumber);
+       dbg("ftdi_sio_open port %d", port->number);
 
        if (port->active) {
-               dbg ("device already open");
+               dbg ("port already open");
                return -EINVAL;
        }
        port->active = 1;
@@ -1069,21 +1084,19 @@
        }
        
        /*Start reading from the device*/
-       if (usb_submit_urb(&port->read_urb))
+       if (usb_submit_urb(port->read_urb))
                dbg("usb_submit_urb(read bulk) failed");
 
        return (0);
 }
 
 
-static void ftdi_sio_serial_close (struct tty_struct *tty, struct file *filp)
+static void ftdi_sio_close (struct usb_serial_port *port, struct file *filp)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
+       struct usb_serial *serial = port->serial;
        char buf[1];
 
-       dbg("ftdi_sio_serial_close port %d", portNumber);
+       dbg("ftdi_sio_close port %d", port->number);
        
        /* FIXME - might be able to do both simultaneously */
        if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
@@ -1104,8 +1117,8 @@
        /* FIXME Should I flush the device here? - not doing it for now */
 
        /* shutdown our bulk reads and writes */
-       usb_unlink_urb (&port->write_urb);
-       usb_unlink_urb (&port->read_urb);
+       usb_unlink_urb (port->write_urb);
+       usb_unlink_urb (port->read_urb);
        port->active = 0;
 }
 
@@ -1116,15 +1129,13 @@
    B1 0
    B2..7 length of message excluding byte 0
 */
-static int ftdi_sio_serial_write (struct tty_struct * tty, int from_user, 
-                                 const unsigned char *buf, int count)
+static int ftdi_sio_write (struct usb_serial_port *port, int from_user, 
+                          const unsigned char *buf, int count)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
+       struct usb_serial *serial = port->serial;
        const int data_offset = 1;
 
-       dbg("ftdi_sio_serial_write port %d, %d bytes", portNumber, count);
+       dbg("ftdi_sio_serial_write port %d, %d bytes", port->number, count);
 
        if (count == 0) {
                dbg("write request of 0 bytes");
@@ -1133,9 +1144,9 @@
 
        /* only do something if we have a bulk out endpoint */
        if (serial->num_bulk_out) {
-               unsigned char *first_byte = port->write_urb.transfer_buffer;
+               unsigned char *first_byte = port->write_urb->transfer_buffer;
 
-               if (port->write_urb.status == -EINPROGRESS) {
+               if (port->write_urb->status == -EINPROGRESS) {
                        dbg ("already writing");
                        return 0;
                }
@@ -1148,16 +1159,16 @@
 
                /* Copy in the data to send */
                if (from_user) {
-                       copy_from_user(port->write_urb.transfer_buffer + data_offset , 
+                       copy_from_user(port->write_urb->transfer_buffer + data_offset 
+, 
                                       buf, count - data_offset );
                }
                else {
-                       memcpy(port->write_urb.transfer_buffer + data_offset,
+                       memcpy(port->write_urb->transfer_buffer + data_offset,
                               buf, count - data_offset );
                }  
 
                /* Write the control byte at the front of the packet*/
-               first_byte = port->write_urb.transfer_buffer;
+               first_byte = port->write_urb->transfer_buffer;
                *first_byte = 1 | ((count-data_offset) << 2) ; 
 
 #ifdef DEBUG
@@ -1181,9 +1192,9 @@
 
 #endif
                /* send the data out the bulk port */
-               port->write_urb.transfer_buffer_length = count;
+               port->write_urb->transfer_buffer_length = count;
 
-               if (usb_submit_urb(&port->write_urb))
+               if (usb_submit_urb(port->write_urb))
                        dbg("usb_submit_urb(write bulk) failed");
 
                dbg("write returning: %d", count - data_offset);
@@ -1197,14 +1208,24 @@
 
 static void ftdi_sio_read_bulk_callback (struct urb *urb)
 { /* ftdi_sio_serial_buld_callback */
-       struct usb_serial *serial = (struct usb_serial *)urb->context;
-               struct tty_struct *tty = serial->tty; 
+       struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+       struct usb_serial *serial;
+               struct tty_struct *tty;
                unsigned char *data = urb->transfer_buffer;
        const int data_offset = 2;
        int i;
 
        dbg("ftdi_sio_read_bulk_callback");
 
+       if (port_paranoia_check (port, "ftdi_sio_read_bulk_callback")) {
+               return;
+       }
+
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "ftdi_sio_read_bulk_callback")) {
+               return;
+       }
+       
        if (urb->status) {
                dbg("nonzero read bulk status received: %d", urb->status);
                return;
@@ -1227,6 +1248,7 @@
        
 
        if (urb->actual_length > data_offset) {
+               tty = port->tty;
                for (i = data_offset ; i < urb->actual_length ; ++i) {
                        tty_insert_flip_char(tty, data[i], 0);
                }
@@ -1241,14 +1263,14 @@
 } /* ftdi_sio_serial_read_bulk_callback */
 
 
-static void ftdi_sio_set_termios (struct tty_struct *tty, struct termios *old_termios)
+static void ftdi_sio_set_termios (struct usb_serial_port *port, struct termios 
+*old_termios)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
-       unsigned int cflag = tty->termios->c_cflag;
+       struct usb_serial *serial = port->serial;
+       unsigned int cflag = port->tty->termios->c_cflag;
        __u16 urb_value; /* Will hold the new flags */
        char buf[1]; /* Perhaps I should dynamically alloc this? */
-       dbg("ftdi_sio_set_termios port %d", port);
+       
+       dbg("ftdi_sio_set_termios port %d", port->number);
 
        /* FIXME - we should keep the old termios really */
        /* FIXME -For this cut I don't care if the line is really changing or 
@@ -1312,14 +1334,14 @@
 
 
 /*FIXME - the beginnings of this implementation - not even hooked into the driver yet 
*/
-static int ftdi_sio_ioctl (struct tty_struct *tty, struct file * file, unsigned int 
cmd, unsigned long arg)
+static int ftdi_sio_ioctl (struct usb_serial_port *port, struct file * file, unsigned 
+int cmd, unsigned long arg)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
+       struct usb_serial *serial = port->serial;
        __u16 urb_value=0; /* Will hold the new flags */
        char buf[1];
        int  ret, mask;
-       dbg("ftdi_sio_ioctl port %d", port);
+       
+       dbg("ftdi_sio_ioctl port %d", port->number);
 
        /* Based on code from acm.c */
        switch (cmd) {
@@ -1408,8 +1430,9 @@
 
 static void keyspan_pda_rx_interrupt (struct urb *urb)
 {
-       struct usb_serial *serial = (struct usb_serial *) urb->context;
-       struct tty_struct *tty = serial->tty;
+       struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+       struct usb_serial *serial;
+               struct tty_struct *tty;
        unsigned char *data = urb->transfer_buffer;
        int i;
 
@@ -1417,11 +1440,21 @@
        if (urb->status)
                return;
        
-       /* see if the message is data or a status interrupt */
+       if (port_paranoia_check (port, "keyspan_pda_rx_interrupt")) {
+               return;
+       }
+
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "keyspan_pda_rx_interrupt")) {
+               return;
+       }
+       
+       /* see if the message is data or a status interrupt */
        switch (data[0]) {
        case 0:
                /* rest of message is rx data */
                if (urb->actual_length) {
+                       tty = serial->port[0].tty;
                        for (i = 1; i < urb->actual_length ; ++i) {
                                tty_insert_flip_char(tty, data[i], 0);
                        }
@@ -1435,6 +1468,7 @@
                case 1: /* modemline change */
                        break;
                case 2: /* tx unthrottle interrupt */
+                       tty = serial->port[0].tty;
                        serial->tx_throttled = 0;
                        wake_up(&serial->write_wait); /* wake up writer */
                        wake_up(&tty->write_wait); /* them too */
@@ -1451,11 +1485,8 @@
 }
 
 
-static void keyspan_pda_rx_throttle (struct tty_struct *tty)
+static void keyspan_pda_rx_throttle (struct usb_serial_port *port)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
-
        /* stop receiving characters. We just turn off the URB request, and
           let chars pile up in the device. If we're doing hardware
           flowcontrol, the device will signal the other end when its buffer
@@ -1463,19 +1494,16 @@
           send an XOFF, although it might make sense to foist that off
           upon the device too. */
 
-       dbg("keyspan_pda_rx_throttle port %d", port);
-       usb_unlink_urb(&serial->port[port].read_urb);
+       dbg("keyspan_pda_rx_throttle port %d", port->number);
+       usb_unlink_urb(port->read_urb);
 }
 
 
-static void keyspan_pda_rx_unthrottle (struct tty_struct *tty)
+static void keyspan_pda_rx_unthrottle (struct usb_serial_port *port)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
-
        /* just restart the receive interrupt URB */
-       dbg("keyspan_pda_rx_unthrottle port %d", port);
-       if (usb_submit_urb(&serial->port[port].read_urb))
+       dbg("keyspan_pda_rx_unthrottle port %d", port->number);
+       if (usb_submit_urb(port->read_urb))
                dbg(" usb_submit_urb(read urb) failed");
        return;
 }
@@ -1516,9 +1544,9 @@
 }
 
 
-static void keyspan_pda_break_ctl (struct tty_struct *tty, int break_state)
+static void keyspan_pda_break_ctl (struct usb_serial_port *port, int break_state)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data;
+       struct usb_serial *serial = port->serial;
        int value;
        if (break_state == -1)
                value = 1; /* start break */
@@ -1535,11 +1563,11 @@
 }
 
 
-static void keyspan_pda_set_termios (struct tty_struct *tty,
+static void keyspan_pda_set_termios (struct usb_serial_port *port, 
                                     struct termios *old_termios)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       unsigned int cflag = tty->termios->c_cflag;
+       struct usb_serial *serial = port->serial;
+       unsigned int cflag = port->tty->termios->c_cflag;
 
        /* cflag specifies lots of stuff: number of stop bits, parity, number
           of data bits, baud. What can the device actually handle?:
@@ -1611,10 +1639,10 @@
 }
 
 
-static int keyspan_pda_ioctl(struct tty_struct *tty, struct file *file,
+static int keyspan_pda_ioctl(struct usb_serial_port *port, struct file *file,
                             unsigned int cmd, unsigned long arg)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data;
+       struct usb_serial *serial = port->serial;
        int rc;
        unsigned int value;
        unsigned char status, mask;
@@ -1677,11 +1705,10 @@
        return -ENOIOCTLCMD;
 }
 
-static int keyspan_pda_write(struct tty_struct * tty, int from_user, 
+static int keyspan_pda_write(struct usb_serial_port *port, int from_user, 
                             const unsigned char *buf, int count)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
+       struct usb_serial *serial = port->serial;
        int request_unthrottle = 0;
        int rc = 0;
        DECLARE_WAITQUEUE(wait, current);
@@ -1704,7 +1731,7 @@
           the TX urb is in-flight (wait until it completes)
           the device is full (wait until it says there is room)
        */
-       while (serial->port[port].write_urb.status == -EINPROGRESS) {
+       while (port->write_urb->status == -EINPROGRESS) {
                if (0 /* file->f_flags & O_NONBLOCK */) {
                        rc = -EAGAIN;
                        goto err;
@@ -1746,8 +1773,7 @@
        remove_wait_queue(&serial->write_wait, &wait);
        set_current_state(TASK_RUNNING);
 
-       count = (count > serial->port[port].bulk_out_size) ? 
-               serial->port[port].bulk_out_size : count;
+       count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
        if (count > serial->tx_room) {
                unsigned char room;
                /* Looks like we might overrun the Tx buffer. Ask the device
@@ -1784,17 +1810,15 @@
        if (count) {
                /* now transfer data */
                if (from_user) {
-                       copy_from_user(serial->port[port].write_urb.transfer_buffer,
-                                      buf, count);
+                       copy_from_user(port->write_urb->transfer_buffer, buf, count);
                }
                else {
-                       memcpy (serial->port[port].write_urb.transfer_buffer, 
-                               buf, count);
+                       memcpy (port->write_urb->transfer_buffer, buf, count);
                }  
                /* send the data out the bulk port */
-               serial->port[port].write_urb.transfer_buffer_length = count;
+               port->write_urb->transfer_buffer_length = count;
                
-               if (usb_submit_urb(&serial->port[port].write_urb))
+               if (usb_submit_urb(port->write_urb))
                        dbg(" usb_submit_urb(write bulk) failed");
        }
        else {
@@ -1828,11 +1852,22 @@
 
 static void keyspan_pda_write_bulk_callback (struct urb *urb)
 {
-       struct usb_serial *serial = (struct usb_serial *) urb->context;
-       struct tty_struct *tty = serial->tty; 
+       struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+       struct usb_serial *serial;
+               struct tty_struct *tty;
+
+       if (port_paranoia_check (port, "keyspan_pda_rx_interrupt")) {
+               return;
+       }
 
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "keyspan_pda_rx_interrupt")) {
+               return;
+       }
+       
        wake_up_interruptible(&serial->write_wait);
 
+       tty = port->tty;
        if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && 
            tty->ldisc.write_wakeup)
                (tty->ldisc.write_wakeup)(tty);
@@ -1841,9 +1876,9 @@
 }
 
 
-static int keyspan_pda_write_room (struct tty_struct *tty)
+static int keyspan_pda_write_room (struct usb_serial_port *port)
 {
-       struct usb_serial *serial = (struct usb_serial *)tty->driver_data; 
+       struct usb_serial *serial = port->serial;
 
        /* used by n_tty.c for processing of tabs and such. Giving it our
           conservative guess is probably good enough, but needs testing by
@@ -1853,9 +1888,9 @@
 }
 
 
-static int keyspan_pda_chars_in_buffer (struct tty_struct *tty) 
+static int keyspan_pda_chars_in_buffer (struct usb_serial_port *port)
 {
-       struct usb_serial *serial = (struct usb_serial *)tty->driver_data; 
+       struct usb_serial *serial = port->serial;
        
        /* when throttled, return at least WAKEUP_CHARS to tell select() (via
           n_tty.c:normal_poll() ) that we're not writeable. */
@@ -1865,11 +1900,9 @@
 }
 
 
-static int keyspan_pda_serial_open (struct tty_struct *tty, struct file *filp)
+static int keyspan_pda_open (struct usb_serial_port *port, struct file *filp)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
+       struct usb_serial *serial = port->serial;
        unsigned char room;
        int rc;
 
@@ -1901,33 +1934,30 @@
 
        /* the normal serial device seems to always turn on DTR and RTS here,
           so do the same */
-       if (tty->termios->c_cflag & CBAUD)
+       if (port->tty->termios->c_cflag & CBAUD)
                keyspan_pda_set_modem_info(serial, (1<<7) | (1<<2) );
        else
                keyspan_pda_set_modem_info(serial, 0);
 
        /*Start reading from the device*/
-       if (usb_submit_urb(&port->read_urb))
+       if (usb_submit_urb(port->read_urb))
                dbg(" usb_submit_urb(read int) failed");
 
        return (0);
 }
 
 
-static void keyspan_pda_serial_close(struct tty_struct *tty, 
-                                    struct file *filp)
+static void keyspan_pda_close(struct usb_serial_port *port, struct file *filp)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
+       struct usb_serial *serial = port->serial;
 
        /* the normal serial device seems to always shut off DTR and RTS now */
-       if (tty->termios->c_cflag & HUPCL)
+       if (port->tty->termios->c_cflag & HUPCL)
                keyspan_pda_set_modem_info(serial, 0);
 
        /* shutdown our bulk reads and writes */
-       usb_unlink_urb (&port->write_urb);
-       usb_unlink_urb (&port->read_urb);
+       usb_unlink_urb (port->write_urb);
+       usb_unlink_urb (port->read_urb);
        port->active = 0;
 }
 
@@ -1971,7 +2001,7 @@
        intin = serial->port[0].interrupt_in_endpoint;
 
        /* set up the receive interrupt urb */
-       FILL_INT_URB(&serial->port[0].read_urb, serial->dev,
+       FILL_INT_URB(serial->port[0].read_urb, serial->dev,
                     usb_rcvintpipe(serial->dev, intin->bEndpointAddress),
                     serial->port[0].interrupt_in_buffer,
                     intin->wMaxPacketSize,
@@ -1990,13 +2020,11 @@
 /*****************************************************************************
  * generic devices specific driver functions
  *****************************************************************************/
-static int generic_serial_open (struct tty_struct *tty, struct file *filp)
+static int generic_open (struct usb_serial_port *port, struct file *filp)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
+       struct usb_serial *serial = port->serial;
 
-       dbg("generic_serial_open port %d", portNumber);
+       dbg("generic_open port %d", port->number);
 
        if (port->active) {
                dbg ("device already open");
@@ -2007,7 +2035,7 @@
        /* if we have a bulk interrupt, start reading from it */
        if (serial->num_bulk_in) {
                /*Start reading from the device*/
-               if (usb_submit_urb(&port->read_urb))
+               if (usb_submit_urb(port->read_urb))
                        dbg("usb_submit_urb(read bulk) failed");
        }
 
@@ -2015,33 +2043,29 @@
 }
 
 
-static void generic_serial_close(struct tty_struct *tty, struct file * filp)
+static void generic_close (struct usb_serial_port *port, struct file * filp)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
+       struct usb_serial *serial = port->serial;
 
-       dbg("generic_serial_close port %d", portNumber);
+       dbg("generic_close port %d", port->number);
        
        /* shutdown any bulk reads that might be going on */
        if (serial->num_bulk_out) {
-               usb_unlink_urb (&port->write_urb);
+               usb_unlink_urb (port->write_urb);
        }
        if (serial->num_bulk_in) {
-               usb_unlink_urb (&port->read_urb);
+               usb_unlink_urb (port->read_urb);
        }
 
        port->active = 0;
 }
 
 
-static int generic_serial_write (struct tty_struct * tty, int from_user, const 
unsigned char *buf, int count)
+static int generic_write (struct usb_serial_port *port, int from_user, const unsigned 
+char *buf, int count)
 {
-       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
+       struct usb_serial *serial = port->serial;
 
-       dbg("generic_serial_write port %d", portNumber);
+       dbg("generic_serial_write port %d", port->number);
 
        if (count == 0) {
                dbg("write request of 0 bytes");
@@ -2050,7 +2074,7 @@
 
        /* only do something if we have a bulk out endpoint */
        if (serial->num_bulk_out) {
-               if (port->write_urb.status == -EINPROGRESS) {
+               if (port->write_urb->status == -EINPROGRESS) {
                        dbg ("already writing");
                        return (0);
                }
@@ -2058,16 +2082,16 @@
                count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
 
                if (from_user) {
-                       copy_from_user(port->write_urb.transfer_buffer, buf, count);
+                       copy_from_user(port->write_urb->transfer_buffer, buf, count);
                }
                else {
-                       memcpy (port->write_urb.transfer_buffer, buf, count);
+                       memcpy (port->write_urb->transfer_buffer, buf, count);
                }  
 
                /* send the data out the bulk port */
-               port->write_urb.transfer_buffer_length = count;
+               port->write_urb->transfer_buffer_length = count;
 
-               if (usb_submit_urb(&port->write_urb))
+               if (usb_submit_urb(port->write_urb))
                        dbg("usb_submit_urb(write bulk) failed");
 
                return (count);
@@ -2078,17 +2102,15 @@
 } 
 
 
-static int generic_write_room (struct tty_struct *tty) 
+static int generic_write_room (struct usb_serial_port *port)
 {
-       struct usb_serial *serial = (struct usb_serial *)tty->driver_data; 
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
+       struct usb_serial *serial = port->serial;
        int room;
 
-       dbg("generic_write_room port %d", portNumber);
+       dbg("generic_write_room port %d", port->number);
        
        if (serial->num_bulk_out) {
-               if (port->write_urb.status == -EINPROGRESS)
+               if (port->write_urb->status == -EINPROGRESS)
                        room = 0;
                else
                        room = port->bulk_out_size;
@@ -2100,16 +2122,14 @@
 }
 
 
-static int generic_chars_in_buffer (struct tty_struct *tty) 
+static int generic_chars_in_buffer (struct usb_serial_port *port)
 {
-       struct usb_serial *serial = (struct usb_serial *)tty->driver_data; 
-       int portNumber = MINOR(tty->device) - serial->minor;
-       struct usb_serial_port *port = &serial->port[portNumber];
+       struct usb_serial *serial = port->serial;
 
-       dbg("generic_chars_in_buffer port %d", portNumber);
+       dbg("generic_chars_in_buffer port %d", port->number);
        
        if (serial->num_bulk_out) {
-               if (port->write_urb.status == -EINPROGRESS) {
+               if (port->write_urb->status == -EINPROGRESS) {
                        return (port->bulk_out_size);
                }
        }
@@ -2118,43 +2138,25 @@
 }
 
 
-static void generic_throttle (struct tty_struct *tty) 
-{
-       /* do nothing for the generic device */
-       return;
-}
-
-
-static void generic_unthrottle (struct tty_struct *tty) 
-{
-       /* do nothing for the generic device */
-       return;
-}
-
-
-static int generic_ioctl (struct tty_struct *tty, struct file * file, unsigned int 
cmd, unsigned long arg)
-{
-       /* generic driver doesn't support any ioctls yet */
-       return -ENOIOCTLCMD;
-}
-
-
-static void generic_set_termios (struct tty_struct *tty, struct termios * old)
-{
-       /* generic driver doesn't really care about setting any line settings */
-       return;
-}
-
-
 static void generic_read_bulk_callback (struct urb *urb)
 {
-       struct usb_serial *serial = (struct usb_serial *)urb->context;
-               struct tty_struct *tty = serial->tty; 
+       struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+       struct usb_serial *serial;
+               struct tty_struct *tty;
                unsigned char *data = urb->transfer_buffer;
        int i;
 
        dbg("generic_read_bulk_callback");
 
+       if (port_paranoia_check (port, "generic_read_bulk_callback")) {
+               return;
+       }
+
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "generic_read_bulk_callback")) {
+               return;
+       }
+       
        if (urb->status) {
                dbg("nonzero read bulk status received: %d", urb->status);
                return;
@@ -2169,7 +2171,8 @@
                printk ("\n");
        }
 #endif
-       
+
+       tty = port->tty;
        if (urb->actual_length) {
                for (i = 0; i < urb->actual_length ; ++i) {
                         tty_insert_flip_char(tty, data[i], 0);
@@ -2187,16 +2190,27 @@
 
 static void generic_write_bulk_callback (struct urb *urb)
 {
-       struct usb_serial *serial = (struct usb_serial *) urb->context; 
-               struct tty_struct *tty = serial->tty; 
+       struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+       struct usb_serial *serial;
+               struct tty_struct *tty;
 
        dbg("generic_write_bulk_callback");
 
+       if (port_paranoia_check (port, "generic_write_bulk_callback")) {
+               return;
+       }
+
+       serial = port->serial;
+       if (serial_paranoia_check (serial, "generic_write_bulk_callback")) {
+               return;
+       }
+       
        if (urb->status) {
                dbg("nonzero write bulk status received: %d", urb->status);
                return;
        }
 
+       tty = port->tty;
        if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
                (tty->ldisc.write_wakeup)(tty);
 
@@ -2206,7 +2220,6 @@
 }
 
 
-
 static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
 {
        struct usb_serial *serial = NULL;
@@ -2331,6 +2344,11 @@
                                /* set up the endpoint information */
                                for (i = 0; i < num_bulk_in; ++i) {
                                        port = &serial->port[i];
+                                       port->read_urb = usb_alloc_urb (0);
+                                       if (!port->read_urb) {
+                                               err("No free urbs available");
+                                               goto probe_error;
+                                       }
                                        buffer_size = 
bulk_in_endpoint[i]->wMaxPacketSize;
                                        port->bulk_in_buffer = kmalloc (buffer_size, 
GFP_KERNEL);
                                        if (!port->bulk_in_buffer) {
@@ -2338,16 +2356,21 @@
                                                goto probe_error;
                                        }
                                        if (serial->type->read_bulk_callback) {
-                                               FILL_BULK_URB(&port->read_urb, dev, 
usb_rcvbulkpipe (dev, bulk_in_endpoint[i]->bEndpointAddress),
-                                                               port->bulk_in_buffer, 
buffer_size, serial->type->read_bulk_callback, serial);
+                                               FILL_BULK_URB(port->read_urb, dev, 
+usb_rcvbulkpipe (dev, bulk_in_endpoint[i]->bEndpointAddress),
+                                                               port->bulk_in_buffer, 
+buffer_size, serial->type->read_bulk_callback, port);
                                        } else {
-                                               FILL_BULK_URB(&port->read_urb, dev, 
usb_rcvbulkpipe (dev, bulk_in_endpoint[i]->bEndpointAddress),
-                                                               port->bulk_in_buffer, 
buffer_size, generic_read_bulk_callback, serial);
+                                               FILL_BULK_URB(port->read_urb, dev, 
+usb_rcvbulkpipe (dev, bulk_in_endpoint[i]->bEndpointAddress),
+                                                               port->bulk_in_buffer, 
+buffer_size, generic_read_bulk_callback, port);
                                        }
                                }
 
                                for (i = 0; i < num_bulk_out; ++i) {
                                        port = &serial->port[i];
+                                       port->write_urb = usb_alloc_urb(0);
+                                       if (!port->write_urb) {
+                                               err("No free urbs available");
+                                               goto probe_error;
+                                       }
                                        port->bulk_out_size = 
bulk_out_endpoint[i]->wMaxPacketSize;
                                        port->bulk_out_buffer = kmalloc 
(port->bulk_out_size, GFP_KERNEL);
                                        if (!port->bulk_out_buffer) {
@@ -2355,25 +2378,31 @@
                                                goto probe_error;
                                        }
                                        if (serial->type->write_bulk_callback) {
-                                               FILL_BULK_URB(&port->write_urb, dev, 
usb_sndbulkpipe (dev, bulk_out_endpoint[i]->bEndpointAddress),
-                                                               port->bulk_out_buffer, 
port->bulk_out_size, serial->type->write_bulk_callback, serial);
+                                               FILL_BULK_URB(port->write_urb, dev, 
+usb_sndbulkpipe (dev, bulk_out_endpoint[i]->bEndpointAddress),
+                                                               port->bulk_out_buffer, 
+port->bulk_out_size, serial->type->write_bulk_callback, port);
                                        } else {
-                                               FILL_BULK_URB(&port->write_urb, dev, 
usb_sndbulkpipe (dev, bulk_out_endpoint[i]->bEndpointAddress),
-                                                               port->bulk_out_buffer, 
port->bulk_out_size, generic_write_bulk_callback, serial);
+                                               FILL_BULK_URB(port->write_urb, dev, 
+usb_sndbulkpipe (dev, bulk_out_endpoint[i]->bEndpointAddress),
+                                                               port->bulk_out_buffer, 
+port->bulk_out_size, generic_write_bulk_callback, port);
                                        }
                                }
 
 #if 0 /* use this code when WhiteHEAT is up and running */
                                for (i = 0; i < num_interrupt_in; ++i) {
+                                       port = &serial->port[i];
+                                       port->control_urb = usb_alloc_urb(0);
+                                       if (!port->control_urb) {
+                                               err("No free urbs available");
+                                               goto probe_error;
+                                       }
                                        buffer_size = 
interrupt_in_endpoint[i]->wMaxPacketSize;
-                                       serial->interrupt_in_buffer[i] = kmalloc 
(buffer_size, GFP_KERNEL);
-                                       if (!serial->interrupt_in_buffer[i]) {
+                                       port->interrupt_in_buffer = kmalloc 
+(buffer_size, GFP_KERNEL);
+                                       if (!port->interrupt_in_buffer) {
                                                err("Couldn't allocate 
interrupt_in_buffer");
                                                goto probe_error;
                                        }
-                                       FILL_INT_URB(&serial->control_urb[i], dev, 
usb_rcvintpipe (dev, interrupt_in_endpoint[i]->bEndpointAddress),
-                                                       
serial->interrupt_in_buffer[i], buffer_size, serial_control_irq,
-                                                       serial, 
interrupt_in_endpoint[i]->bInterval);
+                                       FILL_INT_URB(port->control_urb, dev, 
+usb_rcvintpipe (dev, interrupt_in_endpoint[i]->bEndpointAddress),
+                                                       port->interrupt_in_buffer, 
+buffer_size, serial_control_irq,
+                                                       port, 
+interrupt_in_endpoint[i]->bInterval);
                                }
 #endif
 
@@ -2395,15 +2424,27 @@
 
 probe_error:
        if (serial) {
-               for (i = 0; i < num_bulk_in; ++i)
+               for (i = 0; i < num_bulk_in; ++i) {
+                       port = &serial->port[i];
+                       if (port->read_urb)
+                               usb_free_urb (port->read_urb);
                        if (serial->port[i].bulk_in_buffer[i])
                                kfree (serial->port[i].bulk_in_buffer);
-               for (i = 0; i < num_bulk_out; ++i)
+               }
+               for (i = 0; i < num_bulk_out; ++i) {
+                       port = &serial->port[i];
+                       if (port->write_urb)
+                               usb_free_urb (port->write_urb);
                        if (serial->port[i].bulk_out_buffer)
                                kfree (serial->port[i].bulk_out_buffer);
-               for (i = 0; i < num_interrupt_in; ++i)
+               }
+               for (i = 0; i < num_interrupt_in; ++i) {
+                       port = &serial->port[i];
+                       if (port->control_urb)
+                               usb_free_urb (port->control_urb);
                        if (serial->port[i].interrupt_in_buffer)
                                kfree (serial->port[i].interrupt_in_buffer);
+               }
                
                /* return the minor range that this device had */
                return_serial (serial);
@@ -2422,27 +2463,33 @@
        int i;
 
        if (serial) {
-               /* need to stop any transfers...*/
-               for (i = 0; i < serial->num_ports; ++i) {
-                       port = &serial->port[i];
-                       usb_unlink_urb (&port->write_urb);
-                       usb_unlink_urb (&port->read_urb);
-                       port->active = 0;
-               }
+               for (i = 0; i < serial->num_ports; ++i)
+                       serial->port[i].active = 0;
 
-               /* free up any memory that we allocated */
                for (i = 0; i < serial->num_bulk_in; ++i) {
                        port = &serial->port[i];
+                       if (port->read_urb) {
+                               usb_unlink_urb (port->read_urb);
+                               usb_free_urb (port->read_urb);
+                       }
                        if (port->bulk_in_buffer)
                                kfree (port->bulk_in_buffer);
                }
                for (i = 0; i < serial->num_bulk_out; ++i) {
                        port = &serial->port[i];
+                       if (port->write_urb) {
+                               usb_unlink_urb (port->write_urb);
+                               usb_free_urb (port->write_urb);
+                       }
                        if (port->bulk_out_buffer)
                                kfree (port->bulk_out_buffer);
                }
                for (i = 0; i < serial->num_interrupt_in; ++i) {
                        port = &serial->port[i];
+                       if (port->control_urb) {
+                               usb_unlink_urb (port->control_urb);
+                               usb_free_urb (port->control_urb);
+                       }
                        if (port->interrupt_in_buffer)
                                kfree (port->interrupt_in_buffer);
                }
@@ -2468,7 +2515,7 @@
 static struct tty_driver serial_tty_driver = {
        magic:                  TTY_DRIVER_MAGIC,
        driver_name:            "usb",
-       name:                   "ttyUSB",
+       name:                   "ttyUSB%d",
        major:                  SERIAL_TTY_MAJOR,
        minor_start:            0,
        num:                    SERIAL_TTY_MINORS,
diff -Naur -X dontdiff linux-2.3.99-pre2/drivers/usb/serial/usb-serial.h 
linux-2.3.99-pre2-greg/drivers/usb/serial/usb-serial.h
--- linux-2.3.99-pre2/drivers/usb/serial/usb-serial.h   Sun Mar 19 16:36:46 2000
+++ linux-2.3.99-pre2-greg/drivers/usb/serial/usb-serial.h      Sun Mar 19 16:41:18 
+2000
@@ -52,8 +52,12 @@
 
 #define MAX_NUM_PORTS  8       /* The maximum number of ports one device can grab at 
once */
 
+#define USB_SERIAL_MAGIC       0x6702  /* magic number for usb_serial struct */
+#define USB_SERIAL_PORT_MAGIC  0x7301  /* magic number for usb_serial_port struct */
+
 
 struct usb_serial_port {
+       int                     magic;
        struct usb_serial       *serial;        /* pointer back to the owner of this 
port */
        struct tty_struct *     tty;            /* the coresponding tty for this 
device */
        unsigned char           minor;
@@ -63,21 +67,21 @@
        struct usb_endpoint_descriptor * interrupt_in_endpoint;
        __u8                    interrupt_in_interval;
        unsigned char *         interrupt_in_buffer;
-       struct urb              control_urb;
+       struct urb *            control_urb;
 
        unsigned char *         bulk_in_buffer;
-       struct urb              read_urb;
+       struct urb *            read_urb;
 
        unsigned char *         bulk_out_buffer;
        int                     bulk_out_size;
-       struct urb              write_urb;
+       struct urb *            write_urb;
        void *                  private;        /* data private to the specific driver 
*/
 };
 
 struct usb_serial {
+       int                             magic;
        struct usb_device *             dev;
        struct usb_serial_device_type * type;
-       struct tty_struct *             tty;                    /* the coresponding 
tty for this device */
        unsigned char                   minor;
        unsigned char                   num_ports;              /* the number of ports 
this device has */
        char                            num_interrupt_in;       /* number of interrupt 
in endpoints we have */
@@ -121,16 +125,16 @@
        int (*startup) (struct usb_serial *serial);     /* return 0 to continue 
initialization, anything else to abort */
        
        /* serial function calls */
-       int  (*open)(struct tty_struct * tty, struct file * filp);
-       void (*close)(struct tty_struct * tty, struct file * filp);
-       int  (*write)(struct tty_struct * tty, int from_user,const unsigned char *buf, 
int count);
-       int  (*write_room)(struct tty_struct *tty);
-       int  (*ioctl)(struct tty_struct *tty, struct file * file, unsigned int cmd, 
unsigned long arg);
-       void (*set_termios)(struct tty_struct *tty, struct termios * old);
-       void (*break_ctl)(struct tty_struct *tty, int break_state);
-       int  (*chars_in_buffer)(struct tty_struct *tty);
-       void (*throttle)(struct tty_struct * tty);
-       void (*unthrottle)(struct tty_struct * tty);
+       int  (*open)            (struct usb_serial_port *port, struct file * filp);
+       void (*close)           (struct usb_serial_port *port, struct file * filp);
+       int  (*write)           (struct usb_serial_port *port, int from_user, const 
+unsigned char *buf, int count);
+       int  (*write_room)      (struct usb_serial_port *port);
+       int  (*ioctl)           (struct usb_serial_port *port, struct file * file, 
+unsigned int cmd, unsigned long arg);
+       void (*set_termios)     (struct usb_serial_port *port, struct termios * old);
+       void (*break_ctl)       (struct usb_serial_port *port, int break_state);
+       int  (*chars_in_buffer) (struct usb_serial_port *port);
+       void (*throttle)        (struct usb_serial_port *port);
+       void (*unthrottle)      (struct usb_serial_port *port);
        
        void (*read_bulk_callback)(struct urb *urb);
        void (*write_bulk_callback)(struct urb *urb);
@@ -140,15 +144,11 @@
 /* function prototypes for a "generic" type serial converter (no flow control, not 
all endpoints needed) */
 /* need to always compile these in, as some of the other devices use these functions 
as their own. */
 /* if a driver does not provide a function pointer, the generic function will be 
called. */
-static int  generic_serial_open                (struct tty_struct *tty, struct file 
*filp);
-static void generic_serial_close       (struct tty_struct *tty, struct file *filp);
-static int  generic_serial_write       (struct tty_struct *tty, int from_user, const 
unsigned char *buf, int count);
-static int  generic_write_room         (struct tty_struct *tty);
-static int  generic_ioctl              (struct tty_struct *tty, struct file * file, 
unsigned int cmd, unsigned long arg);
-static void generic_set_termios                (struct tty_struct *tty, struct 
termios * old);
-static int  generic_chars_in_buffer    (struct tty_struct *tty);
-static void generic_throttle           (struct tty_struct *tty);
-static void generic_unthrottle         (struct tty_struct *tty);
+static int  generic_open               (struct usb_serial_port *port, struct file 
+*filp);
+static void generic_close              (struct usb_serial_port *port, struct file 
+*filp);
+static int  generic_write              (struct usb_serial_port *port, int from_user, 
+const unsigned char *buf, int count);
+static int  generic_write_room         (struct usb_serial_port *port);
+static int  generic_chars_in_buffer    (struct usb_serial_port *port);
 static void generic_read_bulk_callback (struct urb *urb);
 static void generic_write_bulk_callback        (struct urb *urb);
 
@@ -172,11 +172,11 @@
 
 #ifdef CONFIG_USB_SERIAL_WHITEHEAT
 /* function prototypes for the Connect Tech WhiteHEAT serial converter */
-static int  whiteheat_serial_open      (struct tty_struct *tty, struct file *filp);
-static void whiteheat_serial_close     (struct tty_struct *tty, struct file *filp);
-static void whiteheat_set_termios      (struct tty_struct *tty, struct termios * old);
-static void whiteheat_throttle         (struct tty_struct *tty);
-static void whiteheat_unthrottle       (struct tty_struct *tty);
+static int  whiteheat_open             (struct usb_serial_port *port, struct file 
+*filp);
+static void whiteheat_close            (struct usb_serial_port *port, struct file 
+*filp);
+static void whiteheat_set_termios      (struct usb_serial_port *port, struct termios 
+* old);
+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);
 
 /* All of the device info needed for the Connect Tech WhiteHEAT */
@@ -193,6 +193,7 @@
        num_interrupt_in:       NUM_DONT_CARE,
        num_bulk_in:            NUM_DONT_CARE,
        num_bulk_out:           NUM_DONT_CARE,
+       num_ports:              1,
        startup:                whiteheat_startup       
 };
 static struct usb_serial_device_type whiteheat_device = {
@@ -206,8 +207,8 @@
        num_bulk_in:            NUM_DONT_CARE,
        num_bulk_out:           NUM_DONT_CARE,
        num_ports:              4,
-       open:                   whiteheat_serial_open,
-       close:                  whiteheat_serial_close,
+       open:                   whiteheat_open,
+       close:                  whiteheat_close,
        throttle:               whiteheat_throttle,
        unthrottle:             whiteheat_unthrottle,
        set_termios:            whiteheat_set_termios,
@@ -269,11 +270,11 @@
 
 
 /* function prototypes for a handspring visor */
-static int  visor_serial_open          (struct tty_struct *tty, struct file *filp);
-static void visor_serial_close         (struct tty_struct *tty, struct file *filp);
-static void visor_throttle             (struct tty_struct *tty);
-static void visor_unthrottle           (struct tty_struct *tty);
-static int  visor_startup              (struct usb_serial *serial);
+static int  visor_open         (struct usb_serial_port *port, struct file *filp);
+static void visor_close                (struct usb_serial_port *port, struct file 
+*filp);
+static void visor_throttle     (struct usb_serial_port *port);
+static void visor_unthrottle   (struct usb_serial_port *port);
+static int  visor_startup      (struct usb_serial *serial);
 
 /* All of the device info needed for the Handspring Visor */
 static __u16   handspring_vendor_id    = HANDSPRING_VENDOR_ID;
@@ -289,8 +290,8 @@
        num_bulk_in:            2,
        num_bulk_out:           2,
        num_ports:              2,
-       open:                   visor_serial_open,
-       close:                  visor_serial_close,
+       open:                   visor_open,
+       close:                  visor_close,
        throttle:               visor_throttle,
        unthrottle:             visor_unthrottle,
        startup:                visor_startup,
@@ -300,12 +301,12 @@
 
 #ifdef CONFIG_USB_SERIAL_FTDI_SIO
 /* function prototypes for a FTDI serial converter */
-static int  ftdi_sio_serial_open       (struct tty_struct *tty, struct file *filp);
-static void ftdi_sio_serial_close      (struct tty_struct *tty, struct file *filp);
-static int  ftdi_sio_serial_write      (struct tty_struct *tty, int from_user, const 
unsigned char *buf, int count);
+static int  ftdi_sio_open              (struct usb_serial_port *port, struct file 
+*filp);
+static void ftdi_sio_close             (struct usb_serial_port *port, struct file 
+*filp);
+static int  ftdi_sio_write             (struct usb_serial_port *port, int from_user, 
+const unsigned char *buf, int count);
 static void ftdi_sio_read_bulk_callback        (struct urb *urb);
-static void ftdi_sio_set_termios               (struct tty_struct *tty, struct 
termios * old);
-static int ftdi_sio_ioctl (struct tty_struct *tty, struct file * file, unsigned int 
cmd, unsigned long arg);
+static void ftdi_sio_set_termios       (struct usb_serial_port *port, struct termios 
+* old);
+static int  ftdi_sio_ioctl             (struct usb_serial_port *port, struct file * 
+file, unsigned int cmd, unsigned long arg);
 
 /* All of the device info needed for the FTDI SIO serial converter */
 static __u16   ftdi_vendor_id          = FTDI_VENDOR_ID;
@@ -321,9 +322,10 @@
        num_bulk_in:            1,
        num_bulk_out:           1,
        num_ports:              1,
-       open:                   ftdi_sio_serial_open,
-       close:                  ftdi_sio_serial_close,
-       write:                  ftdi_sio_serial_write,
+       open:                   ftdi_sio_open,
+       close:                  ftdi_sio_close,
+       write:                  ftdi_sio_write,
+       ioctl:                  ftdi_sio_ioctl,
        read_bulk_callback:     ftdi_sio_read_bulk_callback,
        set_termios:            ftdi_sio_set_termios
 };
@@ -332,28 +334,28 @@
 
 #ifdef CONFIG_USB_SERIAL_KEYSPAN_PDA
 /* function prototypes for a Keyspan PDA serial converter */
-static int  keyspan_pda_serial_open    (struct tty_struct *tty, 
+static int  keyspan_pda_open           (struct usb_serial_port *port,
                                         struct file *filp);
-static void keyspan_pda_serial_close   (struct tty_struct *tty, 
+static void keyspan_pda_close          (struct usb_serial_port *port,
                                         struct file *filp);
 static int  keyspan_pda_startup                (struct usb_serial *serial);
-static void keyspan_pda_rx_throttle    (struct tty_struct *tty);
-static void keyspan_pda_rx_unthrottle  (struct tty_struct *tty);
+static void keyspan_pda_rx_throttle    (struct usb_serial_port *port);
+static void keyspan_pda_rx_unthrottle  (struct usb_serial_port *port);
 static int  keyspan_pda_setbaud                (struct usb_serial *serial, int baud);
-static int  keyspan_pda_write_room     (struct tty_struct *tty);
-static int  keyspan_pda_write          (struct tty_struct *tty,
+static int  keyspan_pda_write_room     (struct usb_serial_port *port);
+static int  keyspan_pda_write          (struct usb_serial_port *port,
                                         int from_user,
                                         const unsigned char *buf,
                                         int count);
 static void keyspan_pda_write_bulk_callback (struct urb *urb);
-static int  keyspan_pda_chars_in_buffer (struct tty_struct *tty);
-static int  keyspan_pda_ioctl          (struct tty_struct *tty,
+static int  keyspan_pda_chars_in_buffer (struct usb_serial_port *port);
+static int  keyspan_pda_ioctl          (struct usb_serial_port *port,
                                         struct file *file,
                                         unsigned int cmd,
                                         unsigned long arg);
-static void keyspan_pda_set_termios    (struct tty_struct *tty,
+static void keyspan_pda_set_termios    (struct usb_serial_port *port,
                                         struct termios *old);
-static void keyspan_pda_break_ctl      (struct tty_struct *tty,
+static void keyspan_pda_break_ctl      (struct usb_serial_port *port,
                                         int break_state);
 static int  keyspan_pda_fake_startup   (struct usb_serial *serial);
 
@@ -385,8 +387,8 @@
        num_bulk_in:            0,
        num_bulk_out:           1,
        num_ports:              1,
-       open:                   keyspan_pda_serial_open,
-       close:                  keyspan_pda_serial_close,
+       open:                   keyspan_pda_open,
+       close:                  keyspan_pda_close,
        write:                  keyspan_pda_write,
        write_room:             keyspan_pda_write_room,
        write_bulk_callback:    keyspan_pda_write_bulk_callback,

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

Reply via email to