diff options
author | Aristeu Rozanski <aris@ruivo.org> | 2007-11-13 17:22:07 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-02-01 17:34:50 -0500 |
commit | c87d6a4f67657f4f1b992eea43796c7e7c09fb17 (patch) | |
tree | 7c6e2350b4774a3bf46a7b7e0f4305cccfa10722 /drivers/usb/serial/console.c | |
parent | 9a6b1efa6fd1ee022fdf42c91a9868c589cc95b7 (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>
Diffstat (limited to 'drivers/usb/serial/console.c')
-rw-r--r-- | drivers/usb/serial/console.c | 82 |
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; | 202 | out: |
203 | return retval; | ||
204 | free_termios: | ||
205 | kfree(termios); | ||
206 | port->tty = NULL; | ||
207 | free_tty: | ||
208 | kfree(tty); | ||
209 | reset_open_count: | ||
210 | port->open_count = 0; | ||
211 | goto out; | ||
198 | } | 212 | } |
199 | 213 | ||
200 | static void usb_console_write(struct console *co, const char *buf, unsigned count) | 214 | static void usb_console_write(struct console *co, const char *buf, unsigned count) |