aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/usb-serial.c
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2008-04-30 03:54:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-30 11:29:47 -0400
commitf34d7a5b7010b82fe97da95496b9971435530062 (patch)
tree87e2abec1e33ed4fe5e63ee2fd000bc2ad745e57 /drivers/usb/serial/usb-serial.c
parent251b8dd7eee30fda089a1dc088abf4fc9a0dee9c (diff)
tty: The big operations rework
- Operations are now a shared const function block as with most other Linux objects - Introduce wrappers for some optional functions to get consistent behaviour - Wrap put_char which used to be patched by the tty layer - Document which functions are needed/optional - Make put_char report success/fail - Cache the driver->ops pointer in the tty as tty->ops - Remove various surplus lock calls we no longer need - Remove proc_write method as noted by Alexey Dobriyan - Introduce some missing sanity checks where certain driver/ldisc combinations would oops as they didn't check needed methods were present [akpm@linux-foundation.org: fix fs/compat_ioctl.c build] [akpm@linux-foundation.org: fix isicom] [akpm@linux-foundation.org: fix arch/ia64/hp/sim/simserial.c build] [akpm@linux-foundation.org: fix kgdb] Signed-off-by: Alan Cox <alan@redhat.com> Acked-by: Greg Kroah-Hartman <gregkh@suse.de> Cc: Jason Wessel <jason.wessel@windriver.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/usb/serial/usb-serial.c')
-rw-r--r--drivers/usb/serial/usb-serial.c129
1 files changed, 23 insertions, 106 deletions
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index a9934a3f9845..0cb0d77dc429 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -296,16 +296,14 @@ static int serial_write (struct tty_struct * tty, const unsigned char *buf, int
296 struct usb_serial_port *port = tty->driver_data; 296 struct usb_serial_port *port = tty->driver_data;
297 int retval = -ENODEV; 297 int retval = -ENODEV;
298 298
299 if (!port || port->serial->dev->state == USB_STATE_NOTATTACHED) 299 if (port->serial->dev->state == USB_STATE_NOTATTACHED)
300 goto exit; 300 goto exit;
301 301
302 dbg("%s - port %d, %d byte(s)", __func__, port->number, count); 302 dbg("%s - port %d, %d byte(s)", __func__, port->number, count);
303 303
304 if (!port->open_count) { 304 /* open_count is managed under the mutex lock for the tty so cannot
305 retval = -EINVAL; 305 drop to zero until after the last close completes */
306 dbg("%s - port not opened", __func__); 306 WARN_ON(!port->open_count);
307 goto exit;
308 }
309 307
310 /* pass on to the driver specific version of this function */ 308 /* pass on to the driver specific version of this function */
311 retval = port->serial->type->write(port, buf, count); 309 retval = port->serial->type->write(port, buf, count);
@@ -317,61 +315,28 @@ exit:
317static int serial_write_room (struct tty_struct *tty) 315static int serial_write_room (struct tty_struct *tty)
318{ 316{
319 struct usb_serial_port *port = tty->driver_data; 317 struct usb_serial_port *port = tty->driver_data;
320 int retval = -ENODEV;
321
322 if (!port)
323 goto exit;
324
325 dbg("%s - port %d", __func__, port->number); 318 dbg("%s - port %d", __func__, port->number);
326 319 WARN_ON(!port->open_count);
327 if (!port->open_count) {
328 dbg("%s - port not open", __func__);
329 goto exit;
330 }
331
332 /* pass on to the driver specific version of this function */ 320 /* pass on to the driver specific version of this function */
333 retval = port->serial->type->write_room(port); 321 return port->serial->type->write_room(port);
334
335exit:
336 return retval;
337} 322}
338 323
339static int serial_chars_in_buffer (struct tty_struct *tty) 324static int serial_chars_in_buffer (struct tty_struct *tty)
340{ 325{
341 struct usb_serial_port *port = tty->driver_data; 326 struct usb_serial_port *port = tty->driver_data;
342 int retval = -ENODEV;
343
344 if (!port)
345 goto exit;
346
347 dbg("%s = port %d", __func__, port->number); 327 dbg("%s = port %d", __func__, port->number);
348 328
349 if (!port->open_count) { 329 WARN_ON(!port->open_count);
350 dbg("%s - port not open", __func__);
351 goto exit;
352 }
353
354 /* pass on to the driver specific version of this function */ 330 /* pass on to the driver specific version of this function */
355 retval = port->serial->type->chars_in_buffer(port); 331 return port->serial->type->chars_in_buffer(port);
356
357exit:
358 return retval;
359} 332}
360 333
361static void serial_throttle (struct tty_struct * tty) 334static void serial_throttle (struct tty_struct * tty)
362{ 335{
363 struct usb_serial_port *port = tty->driver_data; 336 struct usb_serial_port *port = tty->driver_data;
364
365 if (!port)
366 return;
367
368 dbg("%s - port %d", __func__, port->number); 337 dbg("%s - port %d", __func__, port->number);
369 338
370 if (!port->open_count) { 339 WARN_ON(!port->open_count);
371 dbg ("%s - port not open", __func__);
372 return;
373 }
374
375 /* pass on to the driver specific version of this function */ 340 /* pass on to the driver specific version of this function */
376 if (port->serial->type->throttle) 341 if (port->serial->type->throttle)
377 port->serial->type->throttle(port); 342 port->serial->type->throttle(port);
@@ -380,17 +345,9 @@ static void serial_throttle (struct tty_struct * tty)
380static void serial_unthrottle (struct tty_struct * tty) 345static void serial_unthrottle (struct tty_struct * tty)
381{ 346{
382 struct usb_serial_port *port = tty->driver_data; 347 struct usb_serial_port *port = tty->driver_data;
383
384 if (!port)
385 return;
386
387 dbg("%s - port %d", __func__, port->number); 348 dbg("%s - port %d", __func__, port->number);
388 349
389 if (!port->open_count) { 350 WARN_ON(!port->open_count);
390 dbg("%s - port not open", __func__);
391 return;
392 }
393
394 /* pass on to the driver specific version of this function */ 351 /* pass on to the driver specific version of this function */
395 if (port->serial->type->unthrottle) 352 if (port->serial->type->unthrottle)
396 port->serial->type->unthrottle(port); 353 port->serial->type->unthrottle(port);
@@ -401,42 +358,27 @@ static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned in
401 struct usb_serial_port *port = tty->driver_data; 358 struct usb_serial_port *port = tty->driver_data;
402 int retval = -ENODEV; 359 int retval = -ENODEV;
403 360
404 lock_kernel();
405 if (!port)
406 goto exit;
407
408 dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd); 361 dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd);
409 362
410 /* Caution - port->open_count is BKL protected */ 363 WARN_ON(!port->open_count);
411 if (!port->open_count) {
412 dbg ("%s - port not open", __func__);
413 goto exit;
414 }
415 364
416 /* pass on to the driver specific version of this function if it is available */ 365 /* pass on to the driver specific version of this function if it is available */
417 if (port->serial->type->ioctl) 366 if (port->serial->type->ioctl) {
367 lock_kernel();
418 retval = port->serial->type->ioctl(port, file, cmd, arg); 368 retval = port->serial->type->ioctl(port, file, cmd, arg);
369 unlock_kernel();
370 }
419 else 371 else
420 retval = -ENOIOCTLCMD; 372 retval = -ENOIOCTLCMD;
421exit:
422 unlock_kernel();
423 return retval; 373 return retval;
424} 374}
425 375
426static void serial_set_termios (struct tty_struct *tty, struct ktermios * old) 376static void serial_set_termios (struct tty_struct *tty, struct ktermios * old)
427{ 377{
428 struct usb_serial_port *port = tty->driver_data; 378 struct usb_serial_port *port = tty->driver_data;
429
430 if (!port)
431 return;
432
433 dbg("%s - port %d", __func__, port->number); 379 dbg("%s - port %d", __func__, port->number);
434 380
435 if (!port->open_count) { 381 WARN_ON(!port->open_count);
436 dbg("%s - port not open", __func__);
437 return;
438 }
439
440 /* pass on to the driver specific version of this function if it is available */ 382 /* pass on to the driver specific version of this function if it is available */
441 if (port->serial->type->set_termios) 383 if (port->serial->type->set_termios)
442 port->serial->type->set_termios(port, old); 384 port->serial->type->set_termios(port, old);
@@ -448,24 +390,15 @@ static void serial_break (struct tty_struct *tty, int break_state)
448{ 390{
449 struct usb_serial_port *port = tty->driver_data; 391 struct usb_serial_port *port = tty->driver_data;
450 392
451 lock_kernel();
452 if (!port) {
453 unlock_kernel();
454 return;
455 }
456
457 dbg("%s - port %d", __func__, port->number); 393 dbg("%s - port %d", __func__, port->number);
458 394
459 if (!port->open_count) { 395 WARN_ON(!port->open_count);
460 dbg("%s - port not open", __func__);
461 unlock_kernel();
462 return;
463 }
464
465 /* pass on to the driver specific version of this function if it is available */ 396 /* pass on to the driver specific version of this function if it is available */
466 if (port->serial->type->break_ctl) 397 if (port->serial->type->break_ctl) {
398 lock_kernel();
467 port->serial->type->break_ctl(port, break_state); 399 port->serial->type->break_ctl(port, break_state);
468 unlock_kernel(); 400 unlock_kernel();
401 }
469} 402}
470 403
471static int serial_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) 404static int serial_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data)
@@ -519,19 +452,11 @@ static int serial_tiocmget (struct tty_struct *tty, struct file *file)
519{ 452{
520 struct usb_serial_port *port = tty->driver_data; 453 struct usb_serial_port *port = tty->driver_data;
521 454
522 if (!port)
523 return -ENODEV;
524
525 dbg("%s - port %d", __func__, port->number); 455 dbg("%s - port %d", __func__, port->number);
526 456
527 if (!port->open_count) { 457 WARN_ON(!port->open_count);
528 dbg("%s - port not open", __func__);
529 return -ENODEV;
530 }
531
532 if (port->serial->type->tiocmget) 458 if (port->serial->type->tiocmget)
533 return port->serial->type->tiocmget(port, file); 459 return port->serial->type->tiocmget(port, file);
534
535 return -EINVAL; 460 return -EINVAL;
536} 461}
537 462
@@ -540,19 +465,11 @@ static int serial_tiocmset (struct tty_struct *tty, struct file *file,
540{ 465{
541 struct usb_serial_port *port = tty->driver_data; 466 struct usb_serial_port *port = tty->driver_data;
542 467
543 if (!port)
544 return -ENODEV;
545
546 dbg("%s - port %d", __func__, port->number); 468 dbg("%s - port %d", __func__, port->number);
547 469
548 if (!port->open_count) { 470 WARN_ON(!port->open_count);
549 dbg("%s - port not open", __func__);
550 return -ENODEV;
551 }
552
553 if (port->serial->type->tiocmset) 471 if (port->serial->type->tiocmset)
554 return port->serial->type->tiocmset(port, file, set, clear); 472 return port->serial->type->tiocmset(port, file, set, clear);
555
556 return -EINVAL; 473 return -EINVAL;
557} 474}
558 475