Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / drivers / usb / serial / console.c
index 8023bb7..3a9073d 100644 (file)
  *
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/tty.h>
 #include <linux/console.h>
 #include <linux/usb.h>
+#include <linux/usb/serial.h>
 
 static int debug;
 
-#include "usb-serial.h"
-
 struct usbcons_info {
        int                     magic;
        int                     break_flag;
@@ -202,7 +200,7 @@ static void usb_console_write(struct console *co, const char *buf, unsigned coun
        struct usb_serial *serial;
        int retval = -ENODEV;
 
-       if (!port)
+       if (!port || port->serial->dev->state == USB_STATE_NOTATTACHED)
                return;
        serial = port->serial;
 
@@ -213,17 +211,38 @@ static void usb_console_write(struct console *co, const char *buf, unsigned coun
 
        if (!port->open_count) {
                dbg ("%s - port not opened", __FUNCTION__);
-               goto exit;
+               return;
        }
 
-       /* pass on to the driver specific version of this function if it is available */
-       if (serial->type->write)
-               retval = serial->type->write(port, buf, count);
-       else
-               retval = usb_serial_generic_write(port, buf, count);
-
-exit:
-       dbg("%s - return value (if we had one): %d", __FUNCTION__, retval);
+       while (count) {
+               unsigned int i;
+               unsigned int lf;
+               /* search for LF so we can insert CR if necessary */
+               for (i=0, lf=0 ; i < count ; i++) {
+                       if (*(buf + i) == 10) {
+                               lf = 1;
+                               i++;
+                               break;
+                       }
+               }
+               /* pass on to the driver specific version of this function if it is available */
+               if (serial->type->write)
+                       retval = serial->type->write(port, buf, i);
+               else
+                       retval = usb_serial_generic_write(port, buf, i);
+               dbg("%s - return value : %d", __FUNCTION__, retval);
+               if (lf) {
+                       /* append CR after LF */
+                       unsigned char cr = 13;
+                       if (serial->type->write)
+                               retval = serial->type->write(port, &cr, 1);
+                       else
+                               retval = usb_serial_generic_write(port, &cr, 1);
+                       dbg("%s - return value : %d", __FUNCTION__, retval);
+               }
+               buf += i;
+               count -= i;
+       }
 }
 
 static struct console usbcons = {
@@ -234,6 +253,14 @@ static struct console usbcons = {
        .index =        -1,
 };
 
+void usb_serial_console_disconnect(struct usb_serial *serial)
+{
+       if (serial && serial->port && serial->port[0] && serial->port[0] == usbcons_info.port) {
+               usb_serial_console_exit();
+               usb_serial_put(serial);
+       }
+}
+
 void usb_serial_console_init (int serial_debug, int minor)
 {
        debug = serial_debug;
@@ -259,6 +286,11 @@ void usb_serial_console_init (int serial_debug, int minor)
 
 void usb_serial_console_exit (void)
 {
-       unregister_console(&usbcons);
+       if (usbcons_info.port) {
+               unregister_console(&usbcons);
+               if (usbcons_info.port->open_count)
+                       usbcons_info.port->open_count--;
+               usbcons_info.port = NULL;
+       }
 }