aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/serial/usb-serial.c111
1 files changed, 47 insertions, 64 deletions
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 87802ea8bbc8..7d207d91a6a8 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -187,100 +187,92 @@ void usb_serial_put(struct usb_serial *serial)
187 * Create the termios objects for this tty. We use the default 187 * Create the termios objects for this tty. We use the default
188 * USB serial settings but permit them to be overridden by 188 * USB serial settings but permit them to be overridden by
189 * serial->type->init_termios. 189 * serial->type->init_termios.
190 *
191 * This is the first place a new tty gets used. Hence this is where we
192 * acquire references to the usb_serial structure and the driver module,
193 * where we store a pointer to the port, and where we do an autoresume.
194 * All these actions are reversed in serial_do_free().
190 */ 195 */
191static int serial_install(struct tty_driver *driver, struct tty_struct *tty) 196static int serial_install(struct tty_driver *driver, struct tty_struct *tty)
192{ 197{
193 int idx = tty->index; 198 int idx = tty->index;
194 struct usb_serial *serial; 199 struct usb_serial *serial;
195 int retval; 200 struct usb_serial_port *port;
201 int retval = -ENODEV;
202
203 serial = usb_serial_get_by_index(idx);
204 if (!serial)
205 return retval;
206
207 port = serial->port[idx - serial->minor];
208 if (!port)
209 goto error_no_port;
210 if (!try_module_get(serial->type->driver.owner))
211 goto error_module_get;
212
213 retval = usb_autopm_get_interface(serial->interface);
214 if (retval)
215 goto error_get_interface;
196 216
197 /* If the termios setup has yet to be done */ 217 /* If the termios setup has yet to be done */
198 if (tty->driver->termios[idx] == NULL) { 218 if (tty->driver->termios[idx] == NULL) {
199 /* perform the standard setup */ 219 /* perform the standard setup */
200 retval = tty_init_termios(tty); 220 retval = tty_init_termios(tty);
201 if (retval) 221 if (retval)
202 return retval; 222 goto error_init_termios;
203 /* allow the driver to update it */ 223 /* allow the driver to update it */
204 serial = usb_serial_get_by_index(tty->index); 224 if (serial->type->init_termios)
205 if (serial) { 225 serial->type->init_termios(tty);
206 if (serial->type->init_termios)
207 serial->type->init_termios(tty);
208 usb_serial_put(serial);
209 mutex_unlock(&serial->disc_mutex);
210 }
211 } 226 }
227 mutex_unlock(&serial->disc_mutex);
228
229 tty->driver_data = port;
230
212 /* Final install (we use the default method) */ 231 /* Final install (we use the default method) */
213 tty_driver_kref_get(driver); 232 tty_driver_kref_get(driver);
214 tty->count++; 233 tty->count++;
215 driver->ttys[idx] = tty; 234 driver->ttys[idx] = tty;
216 return 0; 235 return retval;
236
237 error_init_termios:
238 usb_autopm_put_interface(serial->interface);
239 error_get_interface:
240 module_put(serial->type->driver.owner);
241 error_module_get:
242 error_no_port:
243 usb_serial_put(serial);
244 mutex_unlock(&serial->disc_mutex);
245 return retval;
217} 246}
218 247
219static int serial_open (struct tty_struct *tty, struct file *filp) 248static int serial_open (struct tty_struct *tty, struct file *filp)
220{ 249{
221 struct usb_serial *serial; 250 struct usb_serial *serial;
222 struct usb_serial_port *port; 251 struct usb_serial_port *port;
223 unsigned int portNumber;
224 int retval = 0; 252 int retval = 0;
225 int first = 0; 253 int first = 0;
226 254
227 dbg("%s", __func__); 255 dbg("%s", __func__);
228 256
229 /* get the serial object associated with this tty pointer */ 257 port = tty->driver_data;
230 serial = usb_serial_get_by_index(tty->index); 258 serial = port->serial;
231 if (!serial) {
232 tty->driver_data = NULL;
233 return -ENODEV;
234 }
235
236 portNumber = tty->index - serial->minor;
237 port = serial->port[portNumber];
238 if (!port || serial->disconnected)
239 retval = -ENODEV;
240 /*
241 * Note: Our locking order requirement does not allow port->mutex
242 * to be acquired while serial->disc_mutex is held.
243 */
244 mutex_unlock(&serial->disc_mutex);
245 if (retval)
246 goto bailout_serial_put;
247 259
248 if (mutex_lock_interruptible(&port->mutex)) { 260 if (mutex_lock_interruptible(&port->mutex))
249 retval = -ERESTARTSYS; 261 return -ERESTARTSYS;
250 goto bailout_serial_put;
251 }
252 262
253 ++port->port.count; 263 ++port->port.count;
254
255 /* set up our port structure making the tty driver
256 * remember our port object, and us it */
257 tty->driver_data = port;
258 tty_port_tty_set(&port->port, tty); 264 tty_port_tty_set(&port->port, tty);
259 265
260 /* If the console is attached, the device is already open */ 266 /* If the console is attached, the device is already open */
261 if (port->port.count == 1 && !port->console) { 267 if (port->port.count == 1 && !port->console) {
262 first = 1; 268 first = 1;
263 /* lock this module before we call it
264 * this may fail, which means we must bail out,
265 * safe because we are called with BKL held */
266 if (!try_module_get(serial->type->driver.owner)) {
267 retval = -ENODEV;
268 goto bailout_mutex_unlock;
269 }
270
271 mutex_lock(&serial->disc_mutex); 269 mutex_lock(&serial->disc_mutex);
272 if (serial->disconnected)
273 retval = -ENODEV;
274 else
275 retval = usb_autopm_get_interface(serial->interface);
276 if (retval)
277 goto bailout_module_put;
278 270
279 /* only call the device specific open if this 271 /* only call the device specific open if this
280 * is the first time the port is opened */ 272 * is the first time the port is opened */
281 retval = serial->type->open(tty, port); 273 retval = serial->type->open(tty, port);
282 if (retval) 274 if (retval)
283 goto bailout_interface_put; 275 goto bailout_module_put;
284 mutex_unlock(&serial->disc_mutex); 276 mutex_unlock(&serial->disc_mutex);
285 set_bit(ASYNCB_INITIALIZED, &port->port.flags); 277 set_bit(ASYNCB_INITIALIZED, &port->port.flags);
286 } 278 }
@@ -297,18 +289,11 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
297 goto bailout_mutex_unlock; 289 goto bailout_mutex_unlock;
298 /* Undo the initial port actions */ 290 /* Undo the initial port actions */
299 mutex_lock(&serial->disc_mutex); 291 mutex_lock(&serial->disc_mutex);
300bailout_interface_put:
301 usb_autopm_put_interface(serial->interface);
302bailout_module_put: 292bailout_module_put:
303 mutex_unlock(&serial->disc_mutex); 293 mutex_unlock(&serial->disc_mutex);
304 module_put(serial->type->driver.owner);
305bailout_mutex_unlock: 294bailout_mutex_unlock:
306 port->port.count = 0; 295 port->port.count = 0;
307 tty->driver_data = NULL;
308 tty_port_tty_set(&port->port, NULL);
309 mutex_unlock(&port->mutex); 296 mutex_unlock(&port->mutex);
310bailout_serial_put:
311 usb_serial_put(serial);
312 return retval; 297 return retval;
313} 298}
314 299
@@ -355,9 +340,6 @@ static void serial_close(struct tty_struct *tty, struct file *filp)
355{ 340{
356 struct usb_serial_port *port = tty->driver_data; 341 struct usb_serial_port *port = tty->driver_data;
357 342
358 if (!port)
359 return;
360
361 dbg("%s - port %d", __func__, port->number); 343 dbg("%s - port %d", __func__, port->number);
362 344
363 if (tty_port_close_start(&port->port, tty, filp) == 0) 345 if (tty_port_close_start(&port->port, tty, filp) == 0)
@@ -365,7 +347,6 @@ static void serial_close(struct tty_struct *tty, struct file *filp)
365 serial_do_down(port); 347 serial_do_down(port);
366 tty_port_close_end(&port->port, tty); 348 tty_port_close_end(&port->port, tty);
367 tty_port_tty_set(&port->port, NULL); 349 tty_port_tty_set(&port->port, NULL);
368
369} 350}
370 351
371/** 352/**
@@ -386,9 +367,11 @@ static void serial_do_free(struct tty_struct *tty)
386 /* The console is magical. Do not hang up the console hardware 367 /* The console is magical. Do not hang up the console hardware
387 * or there will be tears. 368 * or there will be tears.
388 */ 369 */
389 if (port == NULL || port->console) 370 if (port->console)
390 return; 371 return;
391 372
373 tty->driver_data = NULL;
374
392 serial = port->serial; 375 serial = port->serial;
393 owner = serial->type->driver.owner; 376 owner = serial->type->driver.owner;
394 377