diff options
Diffstat (limited to 'drivers/usb/serial/console.c')
-rw-r--r-- | drivers/usb/serial/console.c | 90 |
1 files changed, 54 insertions, 36 deletions
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index 0362654d3b52..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 | ||
@@ -133,11 +133,14 @@ static int usb_console_setup(struct console *co, char *options) | |||
133 | } | 133 | } |
134 | co->cflag = cflag; | 134 | co->cflag = cflag; |
135 | 135 | ||
136 | /* grab the first serial port that happens to be connected */ | 136 | /* |
137 | serial = usb_serial_get_by_index(0); | 137 | * no need to check the index here: if the index is wrong, console |
138 | * code won't call us | ||
139 | */ | ||
140 | serial = usb_serial_get_by_index(co->index); | ||
138 | if (serial == NULL) { | 141 | if (serial == NULL) { |
139 | /* no device is connected yet, sorry :( */ | 142 | /* no device is connected yet, sorry :( */ |
140 | err ("No USB device connected to ttyUSB0"); | 143 | err ("No USB device connected to ttyUSB%i", co->index); |
141 | return -ENODEV; | 144 | return -ENODEV; |
142 | } | 145 | } |
143 | 146 | ||
@@ -148,49 +151,64 @@ static int usb_console_setup(struct console *co, char *options) | |||
148 | 151 | ||
149 | ++port->open_count; | 152 | ++port->open_count; |
150 | 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 | |||
151 | /* only call the device specific open if this | 177 | /* only call the device specific open if this |
152 | * is the first time the port is opened */ | 178 | * is the first time the port is opened */ |
153 | if (serial->type->open) | 179 | if (serial->type->open) |
154 | retval = serial->type->open(port, NULL); | 180 | retval = serial->type->open(port, NULL); |
155 | else | 181 | else |
156 | retval = usb_serial_generic_open(port, NULL); | 182 | retval = usb_serial_generic_open(port, NULL); |
157 | if (retval) | ||
158 | port->open_count = 0; | ||
159 | } | ||
160 | 183 | ||
161 | if (retval) { | 184 | if (retval) { |
162 | err ("could not open USB console port"); | 185 | err("could not open USB console port"); |
163 | return retval; | 186 | goto free_termios; |
164 | } | ||
165 | |||
166 | if (serial->type->set_termios) { | ||
167 | struct ktermios dummy; | ||
168 | /* build up a fake tty structure so that the open call has something | ||
169 | * to look at to get the cflag value */ | ||
170 | tty = kzalloc(sizeof(*tty), GFP_KERNEL); | ||
171 | if (!tty) { | ||
172 | err ("no more memory"); | ||
173 | return -ENOMEM; | ||
174 | } | 187 | } |
175 | termios = kzalloc(sizeof(*termios), GFP_KERNEL); | ||
176 | if (!termios) { | ||
177 | err ("no more memory"); | ||
178 | kfree (tty); | ||
179 | return -ENOMEM; | ||
180 | } | ||
181 | memset(&dummy, 0, sizeof(struct ktermios)); | ||
182 | termios->c_cflag = cflag; | ||
183 | tty->termios = termios; | ||
184 | port->tty = tty; | ||
185 | 188 | ||
186 | /* set up the initial termios settings */ | 189 | if (serial->type->set_termios) { |
187 | serial->type->set_termios(port, &dummy); | 190 | termios->c_cflag = cflag; |
188 | port->tty = NULL; | 191 | serial->type->set_termios(port, &dummy); |
189 | kfree (termios); | 192 | |
190 | kfree (tty); | 193 | port->tty = NULL; |
194 | kfree(termios); | ||
195 | kfree(tty); | ||
196 | } | ||
191 | } | 197 | } |
192 | 198 | ||
199 | port->console = 1; | ||
200 | retval = 0; | ||
201 | |||
202 | out: | ||
193 | return retval; | 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; | ||
194 | } | 212 | } |
195 | 213 | ||
196 | 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) |