Hi,

This patch against 2.4.3-pre4 fixes the following bugs in the whiteheat
driver:
        - fixed the usb_device_id table so the driver will recognize the
          device now (by Stuart MacDonald).
        - fixed the ability to have the port open by more than one
          client at a time.
        - fixed the MOD_INC and MOD_DEC logic.

thanks,

greg k-h

-- 
greg@(kroah|wirex).com
diff -Naur -X dontdiff linux-2.4.3-pre4/drivers/usb/serial/whiteheat.c 
linux-2.4.3-pre4-greg/drivers/usb/serial/whiteheat.c
--- linux-2.4.3-pre4/drivers/usb/serial/whiteheat.c     Thu Feb 22 23:43:26 2001
+++ linux-2.4.3-pre4-greg/drivers/usb/serial/whiteheat.c        Mon Mar 19 16:29:54 
+2001
@@ -1,7 +1,7 @@
 /*
  * USB ConnectTech WhiteHEAT driver
  *
- *     Copyright (C) 1999, 2000
+ *     Copyright (C) 1999 - 2001
  *         Greg Kroah-Hartman ([EMAIL PROTECTED])
  *
  *     This program is free software; you can redistribute it and/or modify
@@ -11,6 +11,11 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  * 
+ * 2001_Mar_19 gkh
+ *     Fixed MOD_INC and MOD_DEC logic, the ability to open a port more 
+ *     than once, and the got the proper usb_device_id table entries so
+ *     the driver works again.
+ *
  * (11/01/2000) Adam J. Richter
  *     usb_device_id table support
  * 
@@ -93,7 +98,7 @@
 };
 
 static __devinitdata struct usb_device_id id_table_prerenumeration [] = {
-       { USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_WHITE_HEAT_ID) },
+       { USB_DEVICE(CONNECT_TECH_VENDOR_ID, CONNECT_TECH_FAKE_WHITE_HEAT_ID) },
        { }                                             /* Terminating entry */
 };
 
@@ -289,43 +294,44 @@
 
        dbg(__FUNCTION__" - port %d", port->number);
 
-       if (port->active) {
-               dbg (__FUNCTION__ " - device already open");
-               return -EINVAL;
-       }
-       port->active = 1;
-
-       /* 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(__FUNCTION__ " - out of memory");
-                       return -ENOMEM;
+       ++port->open_count;
+       MOD_INC_USE_COUNT;
+       
+       if (!port->active) {
+               port->active = 1;
+
+               /* 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(__FUNCTION__ " - 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;
+                       command_port->read_urb->dev = port->serial->dev;
+                       command_port->tty = port->tty;          /* need this to "fake" 
+our our sanity check macros */
+                       usb_submit_urb (command_port->read_urb);
                }
                
-               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;
-               command_port->read_urb->dev = port->serial->dev;
-               command_port->tty = port->tty;          /* need this to "fake" our our 
sanity check macros */
-               usb_submit_urb (command_port->read_urb);
-       }
+               /* Start reading from the device */
+               port->read_urb->dev = port->serial->dev;
+               result = usb_submit_urb(port->read_urb);
+               if (result)
+                       err(__FUNCTION__ " - failed submitting read urb, error %d", 
+result);
+       
+               /* send an open port command */
+               /* firmware uses 1 based port numbering */
+               open_command.port = port->number - port->serial->minor + 1;
+               whiteheat_send_cmd (port->serial, WHITEHEAT_OPEN, (__u8 
+*)&open_command, sizeof(open_command));
        
-       /* Start reading from the device */
-       port->read_urb->dev = port->serial->dev;
-       result = usb_submit_urb(port->read_urb);
-       if (result)
-               err(__FUNCTION__ " - failed submitting read urb, error %d", result);
-
-       /* send an open port command */
-       /* firmware uses 1 based port numbering */
-       open_command.port = port->number - port->serial->minor + 1;
-       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!!! */
+               /* Need to do device specific setup here (control lines, baud rate, 
+etc.) */
+               /* FIXME!!! */
+       }
 
        dbg(__FUNCTION__ " - exit");
        
@@ -339,18 +345,23 @@
        
        dbg(__FUNCTION__ " - port %d", port->number);
        
-       /* send a close command to the port */
-       /* firmware uses 1 based port numbering */
-       close_command.port = port->number - port->serial->minor + 1;
-       whiteheat_send_cmd (port->serial, WHITEHEAT_CLOSE, (__u8 *)&close_command, 
sizeof(close_command));
+       --port->open_count;
 
-       /* Need to change the control lines here */
-       /* FIXME */
+       if (port->open_count <= 0) {
+               /* send a close command to the port */
+               /* firmware uses 1 based port numbering */
+               close_command.port = port->number - port->serial->minor + 1;
+               whiteheat_send_cmd (port->serial, WHITEHEAT_CLOSE, (__u8 
+*)&close_command, sizeof(close_command));
        
-       /* shutdown our bulk reads and writes */
-       usb_unlink_urb (port->write_urb);
-       usb_unlink_urb (port->read_urb);
-       port->active = 0;
+               /* 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);
+               port->active = 0;
+       }
+       MOD_DEC_USE_COUNT;
 }
 
 
@@ -548,8 +559,16 @@
 static void whiteheat_shutdown (struct usb_serial *serial)
 {
        struct usb_serial_port          *command_port;
+       int i;
 
        dbg(__FUNCTION__);
+
+       /* stop reads and writes on all ports */
+       for (i=0; i < serial->num_ports; ++i) {
+               while (serial->port[i].open_count > 0) {
+                       whiteheat_close (&serial->port[i], NULL);
+               }
+       }
 
        /* free up our private data for our command port */
        command_port = &serial->port[COMMAND_PORT];

Reply via email to