aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAristeu Rozanski <aris@ruivo.org>2007-11-13 17:22:07 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2008-02-01 17:34:50 -0500
commitc87d6a4f67657f4f1b992eea43796c7e7c09fb17 (patch)
tree7c6e2350b4774a3bf46a7b7e0f4305cccfa10722
parent9a6b1efa6fd1ee022fdf42c91a9868c589cc95b7 (diff)
USB: usb_serial_console: allocate fake tty and termios before calling driver open() method
The usb serial method set_termios() is called for the first time from open() method in order to set up the termios structure with the default device's settings, ignoring the current settings. Once it's initialized, the next set_termios() calls will update the device with the tty->termios settings. Currently USB serial console code calls the driver open() method without a tty and after that will allocate a fake tty and termios so the command line arguments can be applied to the device (console=ttyUSB0,115200,...). This makes the driver overwrite the termios with the default settings and not applying the command line options. This patch changes usb_console_setup() to allocate the fake tty and termios before the open() method is called. Tested successfully with a pl2303 Signed-off-by: Aristeu Rozanski <arozansk@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/serial/console.c82
1 files changed, 48 insertions, 34 deletions
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
index 04007c31d88d..66ce30c1b75b 100644
--- a/drivers/usb/serial/console.c
+++ b/drivers/usb/serial/console.c
@@ -64,8 +64,8 @@ static int usb_console_setup(struct console *co, char *options)
64 struct usb_serial *serial; 64 struct usb_serial *serial;
65 struct usb_serial_port *port; 65 struct usb_serial_port *port;
66 int retval = 0; 66 int retval = 0;
67 struct tty_struct *tty; 67 struct tty_struct *tty = NULL;
68 struct ktermios *termios; 68 struct ktermios *termios = NULL, dummy;
69 69
70 dbg ("%s", __FUNCTION__); 70 dbg ("%s", __FUNCTION__);
71 71
@@ -151,50 +151,64 @@ static int usb_console_setup(struct console *co, char *options)
151 151
152 ++port->open_count; 152 ++port->open_count;
153 if (port->open_count == 1) { 153 if (port->open_count == 1) {
154 if (serial->type->set_termios) {
155 /*
156 * allocate a fake tty so the driver can initialize
157 * the termios structure, then later call set_termios to
158 * configure according to command line arguments
159 */
160 tty = kzalloc(sizeof(*tty), GFP_KERNEL);
161 if (!tty) {
162 retval = -ENOMEM;
163 err("no more memory");
164 goto reset_open_count;
165 }
166 termios = kzalloc(sizeof(*termios), GFP_KERNEL);
167 if (!termios) {
168 retval = -ENOMEM;
169 err("no more memory");
170 goto free_tty;
171 }
172 memset(&dummy, 0, sizeof(struct ktermios));
173 tty->termios = termios;
174 port->tty = tty;
175 }
176
154 /* only call the device specific open if this 177 /* only call the device specific open if this
155 * is the first time the port is opened */ 178 * is the first time the port is opened */
156 if (serial->type->open) 179 if (serial->type->open)
157 retval = serial->type->open(port, NULL); 180 retval = serial->type->open(port, NULL);
158 else 181 else
159 retval = usb_serial_generic_open(port, NULL); 182 retval = usb_serial_generic_open(port, NULL);
160 if (retval)
161 port->open_count = 0;
162 }
163 183
164 if (retval) { 184 if (retval) {
165 err ("could not open USB console port"); 185 err("could not open USB console port");
166 return retval; 186 goto free_termios;
167 }
168
169 if (serial->type->set_termios) {
170 struct ktermios dummy;
171 /* build up a fake tty structure so that the open call has something
172 * to look at to get the cflag value */
173 tty = kzalloc(sizeof(*tty), GFP_KERNEL);
174 if (!tty) {
175 err ("no more memory");
176 return -ENOMEM;
177 } 187 }
178 termios = kzalloc(sizeof(*termios), GFP_KERNEL);
179 if (!termios) {
180 err ("no more memory");
181 kfree (tty);
182 return -ENOMEM;
183 }
184 memset(&dummy, 0, sizeof(struct ktermios));
185 termios->c_cflag = cflag;
186 tty->termios = termios;
187 port->tty = tty;
188 188
189 /* set up the initial termios settings */ 189 if (serial->type->set_termios) {
190 serial->type->set_termios(port, &dummy); 190 termios->c_cflag = cflag;
191 port->tty = NULL; 191 serial->type->set_termios(port, &dummy);
192 kfree (termios); 192
193 kfree (tty); 193 port->tty = NULL;
194 kfree(termios);
195 kfree(tty);
196 }
194 } 197 }
198
195 port->console = 1; 199 port->console = 1;
200 retval = 0;
196 201
197 return 0; 202out:
203 return retval;
204free_termios:
205 kfree(termios);
206 port->tty = NULL;
207free_tty:
208 kfree(tty);
209reset_open_count:
210 port->open_count = 0;
211goto out;
198} 212}
199 213
200static void usb_console_write(struct console *co, const char *buf, unsigned count) 214static void usb_console_write(struct console *co, const char *buf, unsigned count)