aboutsummaryrefslogtreecommitdiffstats
path: root/net/irda/ircomm/ircomm_tty.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/irda/ircomm/ircomm_tty.c')
-rw-r--r--net/irda/ircomm/ircomm_tty.c320
1 files changed, 154 insertions, 166 deletions
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
index 6b9d5a0e42f9..95a3a7a336ba 100644
--- a/net/irda/ircomm/ircomm_tty.c
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -52,6 +52,8 @@
52#include <net/irda/ircomm_tty_attach.h> 52#include <net/irda/ircomm_tty_attach.h>
53#include <net/irda/ircomm_tty.h> 53#include <net/irda/ircomm_tty.h>
54 54
55static int ircomm_tty_install(struct tty_driver *driver,
56 struct tty_struct *tty);
55static int ircomm_tty_open(struct tty_struct *tty, struct file *filp); 57static int ircomm_tty_open(struct tty_struct *tty, struct file *filp);
56static void ircomm_tty_close(struct tty_struct * tty, struct file *filp); 58static void ircomm_tty_close(struct tty_struct * tty, struct file *filp);
57static int ircomm_tty_write(struct tty_struct * tty, 59static int ircomm_tty_write(struct tty_struct * tty,
@@ -82,6 +84,7 @@ static struct tty_driver *driver;
82static hashbin_t *ircomm_tty = NULL; 84static hashbin_t *ircomm_tty = NULL;
83 85
84static const struct tty_operations ops = { 86static const struct tty_operations ops = {
87 .install = ircomm_tty_install,
85 .open = ircomm_tty_open, 88 .open = ircomm_tty_open,
86 .close = ircomm_tty_close, 89 .close = ircomm_tty_close,
87 .write = ircomm_tty_write, 90 .write = ircomm_tty_write,
@@ -104,6 +107,35 @@ static const struct tty_operations ops = {
104#endif /* CONFIG_PROC_FS */ 107#endif /* CONFIG_PROC_FS */
105}; 108};
106 109
110static void ircomm_port_raise_dtr_rts(struct tty_port *port, int raise)
111{
112 struct ircomm_tty_cb *self = container_of(port, struct ircomm_tty_cb,
113 port);
114 /*
115 * Here, we use to lock those two guys, but as ircomm_param_request()
116 * does it itself, I don't see the point (and I see the deadlock).
117 * Jean II
118 */
119 if (raise)
120 self->settings.dte |= IRCOMM_RTS | IRCOMM_DTR;
121 else
122 self->settings.dte &= ~(IRCOMM_RTS | IRCOMM_DTR);
123
124 ircomm_param_request(self, IRCOMM_DTE, TRUE);
125}
126
127static int ircomm_port_carrier_raised(struct tty_port *port)
128{
129 struct ircomm_tty_cb *self = container_of(port, struct ircomm_tty_cb,
130 port);
131 return self->settings.dce & IRCOMM_CD;
132}
133
134static const struct tty_port_operations ircomm_port_ops = {
135 .dtr_rts = ircomm_port_raise_dtr_rts,
136 .carrier_raised = ircomm_port_carrier_raised,
137};
138
107/* 139/*
108 * Function ircomm_tty_init() 140 * Function ircomm_tty_init()
109 * 141 *
@@ -194,7 +226,7 @@ static int ircomm_tty_startup(struct ircomm_tty_cb *self)
194 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); 226 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
195 227
196 /* Check if already open */ 228 /* Check if already open */
197 if (test_and_set_bit(ASYNC_B_INITIALIZED, &self->flags)) { 229 if (test_and_set_bit(ASYNCB_INITIALIZED, &self->port.flags)) {
198 IRDA_DEBUG(2, "%s(), already open so break out!\n", __func__ ); 230 IRDA_DEBUG(2, "%s(), already open so break out!\n", __func__ );
199 return 0; 231 return 0;
200 } 232 }
@@ -231,7 +263,7 @@ static int ircomm_tty_startup(struct ircomm_tty_cb *self)
231 263
232 return 0; 264 return 0;
233err: 265err:
234 clear_bit(ASYNC_B_INITIALIZED, &self->flags); 266 clear_bit(ASYNCB_INITIALIZED, &self->port.flags);
235 return ret; 267 return ret;
236} 268}
237 269
@@ -242,72 +274,62 @@ err:
242 * 274 *
243 */ 275 */
244static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, 276static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
245 struct file *filp) 277 struct tty_struct *tty, struct file *filp)
246{ 278{
279 struct tty_port *port = &self->port;
247 DECLARE_WAITQUEUE(wait, current); 280 DECLARE_WAITQUEUE(wait, current);
248 int retval; 281 int retval;
249 int do_clocal = 0, extra_count = 0; 282 int do_clocal = 0, extra_count = 0;
250 unsigned long flags; 283 unsigned long flags;
251 struct tty_struct *tty;
252 284
253 IRDA_DEBUG(2, "%s()\n", __func__ ); 285 IRDA_DEBUG(2, "%s()\n", __func__ );
254 286
255 tty = self->tty;
256
257 /* 287 /*
258 * If non-blocking mode is set, or the port is not enabled, 288 * If non-blocking mode is set, or the port is not enabled,
259 * then make the check up front and then exit. 289 * then make the check up front and then exit.
260 */ 290 */
261 if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ 291 if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
262 /* nonblock mode is set or port is not enabled */ 292 /* nonblock mode is set or port is not enabled */
263 self->flags |= ASYNC_NORMAL_ACTIVE; 293 port->flags |= ASYNC_NORMAL_ACTIVE;
264 IRDA_DEBUG(1, "%s(), O_NONBLOCK requested!\n", __func__ ); 294 IRDA_DEBUG(1, "%s(), O_NONBLOCK requested!\n", __func__ );
265 return 0; 295 return 0;
266 } 296 }
267 297
268 if (tty->termios->c_cflag & CLOCAL) { 298 if (tty->termios.c_cflag & CLOCAL) {
269 IRDA_DEBUG(1, "%s(), doing CLOCAL!\n", __func__ ); 299 IRDA_DEBUG(1, "%s(), doing CLOCAL!\n", __func__ );
270 do_clocal = 1; 300 do_clocal = 1;
271 } 301 }
272 302
273 /* Wait for carrier detect and the line to become 303 /* Wait for carrier detect and the line to become
274 * free (i.e., not in use by the callout). While we are in 304 * free (i.e., not in use by the callout). While we are in
275 * this loop, self->open_count is dropped by one, so that 305 * this loop, port->count is dropped by one, so that
276 * mgsl_close() knows when to free things. We restore it upon 306 * mgsl_close() knows when to free things. We restore it upon
277 * exit, either normal or abnormal. 307 * exit, either normal or abnormal.
278 */ 308 */
279 309
280 retval = 0; 310 retval = 0;
281 add_wait_queue(&self->open_wait, &wait); 311 add_wait_queue(&port->open_wait, &wait);
282 312
283 IRDA_DEBUG(2, "%s(%d):block_til_ready before block on %s open_count=%d\n", 313 IRDA_DEBUG(2, "%s(%d):block_til_ready before block on %s open_count=%d\n",
284 __FILE__,__LINE__, tty->driver->name, self->open_count ); 314 __FILE__, __LINE__, tty->driver->name, port->count);
285 315
286 /* As far as I can see, we protect open_count - Jean II */ 316 spin_lock_irqsave(&port->lock, flags);
287 spin_lock_irqsave(&self->spinlock, flags);
288 if (!tty_hung_up_p(filp)) { 317 if (!tty_hung_up_p(filp)) {
289 extra_count = 1; 318 extra_count = 1;
290 self->open_count--; 319 port->count--;
291 } 320 }
292 spin_unlock_irqrestore(&self->spinlock, flags); 321 spin_unlock_irqrestore(&port->lock, flags);
293 self->blocked_open++; 322 port->blocked_open++;
294 323
295 while (1) { 324 while (1) {
296 if (tty->termios->c_cflag & CBAUD) { 325 if (tty->termios.c_cflag & CBAUD)
297 /* Here, we use to lock those two guys, but 326 tty_port_raise_dtr_rts(port);
298 * as ircomm_param_request() does it itself,
299 * I don't see the point (and I see the deadlock).
300 * Jean II */
301 self->settings.dte |= IRCOMM_RTS + IRCOMM_DTR;
302
303 ircomm_param_request(self, IRCOMM_DTE, TRUE);
304 }
305 327
306 current->state = TASK_INTERRUPTIBLE; 328 current->state = TASK_INTERRUPTIBLE;
307 329
308 if (tty_hung_up_p(filp) || 330 if (tty_hung_up_p(filp) ||
309 !test_bit(ASYNC_B_INITIALIZED, &self->flags)) { 331 !test_bit(ASYNCB_INITIALIZED, &port->flags)) {
310 retval = (self->flags & ASYNC_HUP_NOTIFY) ? 332 retval = (port->flags & ASYNC_HUP_NOTIFY) ?
311 -EAGAIN : -ERESTARTSYS; 333 -EAGAIN : -ERESTARTSYS;
312 break; 334 break;
313 } 335 }
@@ -317,8 +339,8 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
317 * specified, we cannot return before the IrCOMM link is 339 * specified, we cannot return before the IrCOMM link is
318 * ready 340 * ready
319 */ 341 */
320 if (!test_bit(ASYNC_B_CLOSING, &self->flags) && 342 if (!test_bit(ASYNCB_CLOSING, &port->flags) &&
321 (do_clocal || (self->settings.dce & IRCOMM_CD)) && 343 (do_clocal || tty_port_carrier_raised(port)) &&
322 self->state == IRCOMM_TTY_READY) 344 self->state == IRCOMM_TTY_READY)
323 { 345 {
324 break; 346 break;
@@ -330,46 +352,36 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
330 } 352 }
331 353
332 IRDA_DEBUG(1, "%s(%d):block_til_ready blocking on %s open_count=%d\n", 354 IRDA_DEBUG(1, "%s(%d):block_til_ready blocking on %s open_count=%d\n",
333 __FILE__,__LINE__, tty->driver->name, self->open_count ); 355 __FILE__, __LINE__, tty->driver->name, port->count);
334 356
335 schedule(); 357 schedule();
336 } 358 }
337 359
338 __set_current_state(TASK_RUNNING); 360 __set_current_state(TASK_RUNNING);
339 remove_wait_queue(&self->open_wait, &wait); 361 remove_wait_queue(&port->open_wait, &wait);
340 362
341 if (extra_count) { 363 if (extra_count) {
342 /* ++ is not atomic, so this should be protected - Jean II */ 364 /* ++ is not atomic, so this should be protected - Jean II */
343 spin_lock_irqsave(&self->spinlock, flags); 365 spin_lock_irqsave(&port->lock, flags);
344 self->open_count++; 366 port->count++;
345 spin_unlock_irqrestore(&self->spinlock, flags); 367 spin_unlock_irqrestore(&port->lock, flags);
346 } 368 }
347 self->blocked_open--; 369 port->blocked_open--;
348 370
349 IRDA_DEBUG(1, "%s(%d):block_til_ready after blocking on %s open_count=%d\n", 371 IRDA_DEBUG(1, "%s(%d):block_til_ready after blocking on %s open_count=%d\n",
350 __FILE__,__LINE__, tty->driver->name, self->open_count); 372 __FILE__, __LINE__, tty->driver->name, port->count);
351 373
352 if (!retval) 374 if (!retval)
353 self->flags |= ASYNC_NORMAL_ACTIVE; 375 port->flags |= ASYNC_NORMAL_ACTIVE;
354 376
355 return retval; 377 return retval;
356} 378}
357 379
358/* 380
359 * Function ircomm_tty_open (tty, filp) 381static int ircomm_tty_install(struct tty_driver *driver, struct tty_struct *tty)
360 *
361 * This routine is called when a particular tty device is opened. This
362 * routine is mandatory; if this routine is not filled in, the attempted
363 * open will fail with ENODEV.
364 */
365static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
366{ 382{
367 struct ircomm_tty_cb *self; 383 struct ircomm_tty_cb *self;
368 unsigned int line = tty->index; 384 unsigned int line = tty->index;
369 unsigned long flags;
370 int ret;
371
372 IRDA_DEBUG(2, "%s()\n", __func__ );
373 385
374 /* Check if instance already exists */ 386 /* Check if instance already exists */
375 self = hashbin_lock_find(ircomm_tty, line, NULL); 387 self = hashbin_lock_find(ircomm_tty, line, NULL);
@@ -381,6 +393,8 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
381 return -ENOMEM; 393 return -ENOMEM;
382 } 394 }
383 395
396 tty_port_init(&self->port);
397 self->port.ops = &ircomm_port_ops;
384 self->magic = IRCOMM_TTY_MAGIC; 398 self->magic = IRCOMM_TTY_MAGIC;
385 self->flow = FLOW_STOP; 399 self->flow = FLOW_STOP;
386 400
@@ -388,13 +402,9 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
388 INIT_WORK(&self->tqueue, ircomm_tty_do_softint); 402 INIT_WORK(&self->tqueue, ircomm_tty_do_softint);
389 self->max_header_size = IRCOMM_TTY_HDR_UNINITIALISED; 403 self->max_header_size = IRCOMM_TTY_HDR_UNINITIALISED;
390 self->max_data_size = IRCOMM_TTY_DATA_UNINITIALISED; 404 self->max_data_size = IRCOMM_TTY_DATA_UNINITIALISED;
391 self->close_delay = 5*HZ/10;
392 self->closing_wait = 30*HZ;
393 405
394 /* Init some important stuff */ 406 /* Init some important stuff */
395 init_timer(&self->watchdog_timer); 407 init_timer(&self->watchdog_timer);
396 init_waitqueue_head(&self->open_wait);
397 init_waitqueue_head(&self->close_wait);
398 spin_lock_init(&self->spinlock); 408 spin_lock_init(&self->spinlock);
399 409
400 /* 410 /*
@@ -404,31 +414,48 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
404 * 414 *
405 * Note this is completely usafe and doesn't work properly 415 * Note this is completely usafe and doesn't work properly
406 */ 416 */
407 tty->termios->c_iflag = 0; 417 tty->termios.c_iflag = 0;
408 tty->termios->c_oflag = 0; 418 tty->termios.c_oflag = 0;
409 419
410 /* Insert into hash */ 420 /* Insert into hash */
411 hashbin_insert(ircomm_tty, (irda_queue_t *) self, line, NULL); 421 hashbin_insert(ircomm_tty, (irda_queue_t *) self, line, NULL);
412 } 422 }
413 /* ++ is not atomic, so this should be protected - Jean II */
414 spin_lock_irqsave(&self->spinlock, flags);
415 self->open_count++;
416 423
417 tty->driver_data = self; 424 return tty_port_install(&self->port, driver, tty);
418 self->tty = tty; 425}
419 spin_unlock_irqrestore(&self->spinlock, flags); 426
427/*
428 * Function ircomm_tty_open (tty, filp)
429 *
430 * This routine is called when a particular tty device is opened. This
431 * routine is mandatory; if this routine is not filled in, the attempted
432 * open will fail with ENODEV.
433 */
434static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
435{
436 struct ircomm_tty_cb *self = tty->driver_data;
437 unsigned long flags;
438 int ret;
439
440 IRDA_DEBUG(2, "%s()\n", __func__ );
441
442 /* ++ is not atomic, so this should be protected - Jean II */
443 spin_lock_irqsave(&self->port.lock, flags);
444 self->port.count++;
445 spin_unlock_irqrestore(&self->port.lock, flags);
446 tty_port_tty_set(&self->port, tty);
420 447
421 IRDA_DEBUG(1, "%s(), %s%d, count = %d\n", __func__ , tty->driver->name, 448 IRDA_DEBUG(1, "%s(), %s%d, count = %d\n", __func__ , tty->driver->name,
422 self->line, self->open_count); 449 self->line, self->port.count);
423 450
424 /* Not really used by us, but lets do it anyway */ 451 /* Not really used by us, but lets do it anyway */
425 self->tty->low_latency = (self->flags & ASYNC_LOW_LATENCY) ? 1 : 0; 452 tty->low_latency = (self->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0;
426 453
427 /* 454 /*
428 * If the port is the middle of closing, bail out now 455 * If the port is the middle of closing, bail out now
429 */ 456 */
430 if (tty_hung_up_p(filp) || 457 if (tty_hung_up_p(filp) ||
431 test_bit(ASYNC_B_CLOSING, &self->flags)) { 458 test_bit(ASYNCB_CLOSING, &self->port.flags)) {
432 459
433 /* Hm, why are we blocking on ASYNC_CLOSING if we 460 /* Hm, why are we blocking on ASYNC_CLOSING if we
434 * do return -EAGAIN/-ERESTARTSYS below anyway? 461 * do return -EAGAIN/-ERESTARTSYS below anyway?
@@ -438,14 +465,15 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
438 * probably better sleep uninterruptible? 465 * probably better sleep uninterruptible?
439 */ 466 */
440 467
441 if (wait_event_interruptible(self->close_wait, !test_bit(ASYNC_B_CLOSING, &self->flags))) { 468 if (wait_event_interruptible(self->port.close_wait,
469 !test_bit(ASYNCB_CLOSING, &self->port.flags))) {
442 IRDA_WARNING("%s - got signal while blocking on ASYNC_CLOSING!\n", 470 IRDA_WARNING("%s - got signal while blocking on ASYNC_CLOSING!\n",
443 __func__); 471 __func__);
444 return -ERESTARTSYS; 472 return -ERESTARTSYS;
445 } 473 }
446 474
447#ifdef SERIAL_DO_RESTART 475#ifdef SERIAL_DO_RESTART
448 return (self->flags & ASYNC_HUP_NOTIFY) ? 476 return (self->port.flags & ASYNC_HUP_NOTIFY) ?
449 -EAGAIN : -ERESTARTSYS; 477 -EAGAIN : -ERESTARTSYS;
450#else 478#else
451 return -EAGAIN; 479 return -EAGAIN;
@@ -453,7 +481,7 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
453 } 481 }
454 482
455 /* Check if this is a "normal" ircomm device, or an irlpt device */ 483 /* Check if this is a "normal" ircomm device, or an irlpt device */
456 if (line < 0x10) { 484 if (self->line < 0x10) {
457 self->service_type = IRCOMM_3_WIRE | IRCOMM_9_WIRE; 485 self->service_type = IRCOMM_3_WIRE | IRCOMM_9_WIRE;
458 self->settings.service_type = IRCOMM_9_WIRE; /* 9 wire as default */ 486 self->settings.service_type = IRCOMM_9_WIRE; /* 9 wire as default */
459 /* Jan Kiszka -> add DSR/RI -> Conform to IrCOMM spec */ 487 /* Jan Kiszka -> add DSR/RI -> Conform to IrCOMM spec */
@@ -469,7 +497,7 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
469 if (ret) 497 if (ret)
470 return ret; 498 return ret;
471 499
472 ret = ircomm_tty_block_til_ready(self, filp); 500 ret = ircomm_tty_block_til_ready(self, tty, filp);
473 if (ret) { 501 if (ret) {
474 IRDA_DEBUG(2, 502 IRDA_DEBUG(2,
475 "%s(), returning after block_til_ready with %d\n", __func__ , 503 "%s(), returning after block_til_ready with %d\n", __func__ ,
@@ -489,81 +517,22 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
489static void ircomm_tty_close(struct tty_struct *tty, struct file *filp) 517static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
490{ 518{
491 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; 519 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
492 unsigned long flags; 520 struct tty_port *port = &self->port;
493 521
494 IRDA_DEBUG(0, "%s()\n", __func__ ); 522 IRDA_DEBUG(0, "%s()\n", __func__ );
495 523
496 IRDA_ASSERT(self != NULL, return;); 524 IRDA_ASSERT(self != NULL, return;);
497 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); 525 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
498 526
499 spin_lock_irqsave(&self->spinlock, flags); 527 if (tty_port_close_start(port, tty, filp) == 0)
500
501 if (tty_hung_up_p(filp)) {
502 spin_unlock_irqrestore(&self->spinlock, flags);
503
504 IRDA_DEBUG(0, "%s(), returning 1\n", __func__ );
505 return;
506 }
507
508 if ((tty->count == 1) && (self->open_count != 1)) {
509 /*
510 * Uh, oh. tty->count is 1, which means that the tty
511 * structure will be freed. state->count should always
512 * be one in these conditions. If it's greater than
513 * one, we've got real problems, since it means the
514 * serial port won't be shutdown.
515 */
516 IRDA_DEBUG(0, "%s(), bad serial port count; "
517 "tty->count is 1, state->count is %d\n", __func__ ,
518 self->open_count);
519 self->open_count = 1;
520 }
521
522 if (--self->open_count < 0) {
523 IRDA_ERROR("%s(), bad serial port count for ttys%d: %d\n",
524 __func__, self->line, self->open_count);
525 self->open_count = 0;
526 }
527 if (self->open_count) {
528 spin_unlock_irqrestore(&self->spinlock, flags);
529
530 IRDA_DEBUG(0, "%s(), open count > 0\n", __func__ );
531 return; 528 return;
532 }
533
534 /* Hum... Should be test_and_set_bit ??? - Jean II */
535 set_bit(ASYNC_B_CLOSING, &self->flags);
536
537 /* We need to unlock here (we were unlocking at the end of this
538 * function), because tty_wait_until_sent() may schedule.
539 * I don't know if the rest should be protected somehow,
540 * so someone should check. - Jean II */
541 spin_unlock_irqrestore(&self->spinlock, flags);
542
543 /*
544 * Now we wait for the transmit buffer to clear; and we notify
545 * the line discipline to only process XON/XOFF characters.
546 */
547 tty->closing = 1;
548 if (self->closing_wait != ASYNC_CLOSING_WAIT_NONE)
549 tty_wait_until_sent_from_close(tty, self->closing_wait);
550 529
551 ircomm_tty_shutdown(self); 530 ircomm_tty_shutdown(self);
552 531
553 tty_driver_flush_buffer(tty); 532 tty_driver_flush_buffer(tty);
554 tty_ldisc_flush(tty);
555
556 tty->closing = 0;
557 self->tty = NULL;
558 533
559 if (self->blocked_open) { 534 tty_port_close_end(port, tty);
560 if (self->close_delay) 535 tty_port_tty_set(port, NULL);
561 schedule_timeout_interruptible(self->close_delay);
562 wake_up_interruptible(&self->open_wait);
563 }
564
565 self->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
566 wake_up_interruptible(&self->close_wait);
567} 536}
568 537
569/* 538/*
@@ -606,7 +575,7 @@ static void ircomm_tty_do_softint(struct work_struct *work)
606 if (!self || self->magic != IRCOMM_TTY_MAGIC) 575 if (!self || self->magic != IRCOMM_TTY_MAGIC)
607 return; 576 return;
608 577
609 tty = self->tty; 578 tty = tty_port_tty_get(&self->port);
610 if (!tty) 579 if (!tty)
611 return; 580 return;
612 581
@@ -627,7 +596,7 @@ static void ircomm_tty_do_softint(struct work_struct *work)
627 } 596 }
628 597
629 if (tty->hw_stopped) 598 if (tty->hw_stopped)
630 return; 599 goto put;
631 600
632 /* Unlink transmit buffer */ 601 /* Unlink transmit buffer */
633 spin_lock_irqsave(&self->spinlock, flags); 602 spin_lock_irqsave(&self->spinlock, flags);
@@ -646,6 +615,8 @@ static void ircomm_tty_do_softint(struct work_struct *work)
646 615
647 /* Check if user (still) wants to be waken up */ 616 /* Check if user (still) wants to be waken up */
648 tty_wakeup(tty); 617 tty_wakeup(tty);
618put:
619 tty_kref_put(tty);
649} 620}
650 621
651/* 622/*
@@ -880,7 +851,7 @@ static void ircomm_tty_throttle(struct tty_struct *tty)
880 ircomm_tty_send_xchar(tty, STOP_CHAR(tty)); 851 ircomm_tty_send_xchar(tty, STOP_CHAR(tty));
881 852
882 /* Hardware flow control? */ 853 /* Hardware flow control? */
883 if (tty->termios->c_cflag & CRTSCTS) { 854 if (tty->termios.c_cflag & CRTSCTS) {
884 self->settings.dte &= ~IRCOMM_RTS; 855 self->settings.dte &= ~IRCOMM_RTS;
885 self->settings.dte |= IRCOMM_DELTA_RTS; 856 self->settings.dte |= IRCOMM_DELTA_RTS;
886 857
@@ -912,7 +883,7 @@ static void ircomm_tty_unthrottle(struct tty_struct *tty)
912 } 883 }
913 884
914 /* Using hardware flow control? */ 885 /* Using hardware flow control? */
915 if (tty->termios->c_cflag & CRTSCTS) { 886 if (tty->termios.c_cflag & CRTSCTS) {
916 self->settings.dte |= (IRCOMM_RTS|IRCOMM_DELTA_RTS); 887 self->settings.dte |= (IRCOMM_RTS|IRCOMM_DELTA_RTS);
917 888
918 ircomm_param_request(self, IRCOMM_DTE, TRUE); 889 ircomm_param_request(self, IRCOMM_DTE, TRUE);
@@ -955,7 +926,7 @@ static void ircomm_tty_shutdown(struct ircomm_tty_cb *self)
955 926
956 IRDA_DEBUG(0, "%s()\n", __func__ ); 927 IRDA_DEBUG(0, "%s()\n", __func__ );
957 928
958 if (!test_and_clear_bit(ASYNC_B_INITIALIZED, &self->flags)) 929 if (!test_and_clear_bit(ASYNCB_INITIALIZED, &self->port.flags))
959 return; 930 return;
960 931
961 ircomm_tty_detach_cable(self); 932 ircomm_tty_detach_cable(self);
@@ -994,6 +965,7 @@ static void ircomm_tty_shutdown(struct ircomm_tty_cb *self)
994static void ircomm_tty_hangup(struct tty_struct *tty) 965static void ircomm_tty_hangup(struct tty_struct *tty)
995{ 966{
996 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; 967 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
968 struct tty_port *port = &self->port;
997 unsigned long flags; 969 unsigned long flags;
998 970
999 IRDA_DEBUG(0, "%s()\n", __func__ ); 971 IRDA_DEBUG(0, "%s()\n", __func__ );
@@ -1004,14 +976,17 @@ static void ircomm_tty_hangup(struct tty_struct *tty)
1004 /* ircomm_tty_flush_buffer(tty); */ 976 /* ircomm_tty_flush_buffer(tty); */
1005 ircomm_tty_shutdown(self); 977 ircomm_tty_shutdown(self);
1006 978
1007 /* I guess we need to lock here - Jean II */ 979 spin_lock_irqsave(&port->lock, flags);
1008 spin_lock_irqsave(&self->spinlock, flags); 980 port->flags &= ~ASYNC_NORMAL_ACTIVE;
1009 self->flags &= ~ASYNC_NORMAL_ACTIVE; 981 if (port->tty) {
1010 self->tty = NULL; 982 set_bit(TTY_IO_ERROR, &port->tty->flags);
1011 self->open_count = 0; 983 tty_kref_put(port->tty);
1012 spin_unlock_irqrestore(&self->spinlock, flags); 984 }
985 port->tty = NULL;
986 port->count = 0;
987 spin_unlock_irqrestore(&port->lock, flags);
1013 988
1014 wake_up_interruptible(&self->open_wait); 989 wake_up_interruptible(&port->open_wait);
1015} 990}
1016 991
1017/* 992/*
@@ -1071,20 +1046,20 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self)
1071 IRDA_ASSERT(self != NULL, return;); 1046 IRDA_ASSERT(self != NULL, return;);
1072 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); 1047 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
1073 1048
1074 tty = self->tty; 1049 tty = tty_port_tty_get(&self->port);
1075 1050
1076 status = self->settings.dce; 1051 status = self->settings.dce;
1077 1052
1078 if (status & IRCOMM_DCE_DELTA_ANY) { 1053 if (status & IRCOMM_DCE_DELTA_ANY) {
1079 /*wake_up_interruptible(&self->delta_msr_wait);*/ 1054 /*wake_up_interruptible(&self->delta_msr_wait);*/
1080 } 1055 }
1081 if ((self->flags & ASYNC_CHECK_CD) && (status & IRCOMM_DELTA_CD)) { 1056 if ((self->port.flags & ASYNC_CHECK_CD) && (status & IRCOMM_DELTA_CD)) {
1082 IRDA_DEBUG(2, 1057 IRDA_DEBUG(2,
1083 "%s(), ircomm%d CD now %s...\n", __func__ , self->line, 1058 "%s(), ircomm%d CD now %s...\n", __func__ , self->line,
1084 (status & IRCOMM_CD) ? "on" : "off"); 1059 (status & IRCOMM_CD) ? "on" : "off");
1085 1060
1086 if (status & IRCOMM_CD) { 1061 if (status & IRCOMM_CD) {
1087 wake_up_interruptible(&self->open_wait); 1062 wake_up_interruptible(&self->port.open_wait);
1088 } else { 1063 } else {
1089 IRDA_DEBUG(2, 1064 IRDA_DEBUG(2,
1090 "%s(), Doing serial hangup..\n", __func__ ); 1065 "%s(), Doing serial hangup..\n", __func__ );
@@ -1092,10 +1067,10 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self)
1092 tty_hangup(tty); 1067 tty_hangup(tty);
1093 1068
1094 /* Hangup will remote the tty, so better break out */ 1069 /* Hangup will remote the tty, so better break out */
1095 return; 1070 goto put;
1096 } 1071 }
1097 } 1072 }
1098 if (self->flags & ASYNC_CTS_FLOW) { 1073 if (tty && tty_port_cts_enabled(&self->port)) {
1099 if (tty->hw_stopped) { 1074 if (tty->hw_stopped) {
1100 if (status & IRCOMM_CTS) { 1075 if (status & IRCOMM_CTS) {
1101 IRDA_DEBUG(2, 1076 IRDA_DEBUG(2,
@@ -1103,10 +1078,10 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self)
1103 tty->hw_stopped = 0; 1078 tty->hw_stopped = 0;
1104 1079
1105 /* Wake up processes blocked on open */ 1080 /* Wake up processes blocked on open */
1106 wake_up_interruptible(&self->open_wait); 1081 wake_up_interruptible(&self->port.open_wait);
1107 1082
1108 schedule_work(&self->tqueue); 1083 schedule_work(&self->tqueue);
1109 return; 1084 goto put;
1110 } 1085 }
1111 } else { 1086 } else {
1112 if (!(status & IRCOMM_CTS)) { 1087 if (!(status & IRCOMM_CTS)) {
@@ -1116,6 +1091,8 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self)
1116 } 1091 }
1117 } 1092 }
1118 } 1093 }
1094put:
1095 tty_kref_put(tty);
1119} 1096}
1120 1097
1121/* 1098/*
@@ -1128,6 +1105,7 @@ static int ircomm_tty_data_indication(void *instance, void *sap,
1128 struct sk_buff *skb) 1105 struct sk_buff *skb)
1129{ 1106{
1130 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance; 1107 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
1108 struct tty_struct *tty;
1131 1109
1132 IRDA_DEBUG(2, "%s()\n", __func__ ); 1110 IRDA_DEBUG(2, "%s()\n", __func__ );
1133 1111
@@ -1135,7 +1113,8 @@ static int ircomm_tty_data_indication(void *instance, void *sap,
1135 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); 1113 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
1136 IRDA_ASSERT(skb != NULL, return -1;); 1114 IRDA_ASSERT(skb != NULL, return -1;);
1137 1115
1138 if (!self->tty) { 1116 tty = tty_port_tty_get(&self->port);
1117 if (!tty) {
1139 IRDA_DEBUG(0, "%s(), no tty!\n", __func__ ); 1118 IRDA_DEBUG(0, "%s(), no tty!\n", __func__ );
1140 return 0; 1119 return 0;
1141 } 1120 }
@@ -1146,7 +1125,7 @@ static int ircomm_tty_data_indication(void *instance, void *sap,
1146 * Devices like WinCE can do this, and since they don't send any 1125 * Devices like WinCE can do this, and since they don't send any
1147 * params, we can just as well declare the hardware for running. 1126 * params, we can just as well declare the hardware for running.
1148 */ 1127 */
1149 if (self->tty->hw_stopped && (self->flow == FLOW_START)) { 1128 if (tty->hw_stopped && (self->flow == FLOW_START)) {
1150 IRDA_DEBUG(0, "%s(), polling for line settings!\n", __func__ ); 1129 IRDA_DEBUG(0, "%s(), polling for line settings!\n", __func__ );
1151 ircomm_param_request(self, IRCOMM_POLL, TRUE); 1130 ircomm_param_request(self, IRCOMM_POLL, TRUE);
1152 1131
@@ -1159,8 +1138,9 @@ static int ircomm_tty_data_indication(void *instance, void *sap,
1159 * Use flip buffer functions since the code may be called from interrupt 1138 * Use flip buffer functions since the code may be called from interrupt
1160 * context 1139 * context
1161 */ 1140 */
1162 tty_insert_flip_string(self->tty, skb->data, skb->len); 1141 tty_insert_flip_string(tty, skb->data, skb->len);
1163 tty_flip_buffer_push(self->tty); 1142 tty_flip_buffer_push(tty);
1143 tty_kref_put(tty);
1164 1144
1165 /* No need to kfree_skb - see ircomm_ttp_data_indication() */ 1145 /* No need to kfree_skb - see ircomm_ttp_data_indication() */
1166 1146
@@ -1211,12 +1191,13 @@ static void ircomm_tty_flow_indication(void *instance, void *sap,
1211 IRDA_ASSERT(self != NULL, return;); 1191 IRDA_ASSERT(self != NULL, return;);
1212 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); 1192 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
1213 1193
1214 tty = self->tty; 1194 tty = tty_port_tty_get(&self->port);
1215 1195
1216 switch (cmd) { 1196 switch (cmd) {
1217 case FLOW_START: 1197 case FLOW_START:
1218 IRDA_DEBUG(2, "%s(), hw start!\n", __func__ ); 1198 IRDA_DEBUG(2, "%s(), hw start!\n", __func__ );
1219 tty->hw_stopped = 0; 1199 if (tty)
1200 tty->hw_stopped = 0;
1220 1201
1221 /* ircomm_tty_do_softint will take care of the rest */ 1202 /* ircomm_tty_do_softint will take care of the rest */
1222 schedule_work(&self->tqueue); 1203 schedule_work(&self->tqueue);
@@ -1224,15 +1205,19 @@ static void ircomm_tty_flow_indication(void *instance, void *sap,
1224 default: /* If we get here, something is very wrong, better stop */ 1205 default: /* If we get here, something is very wrong, better stop */
1225 case FLOW_STOP: 1206 case FLOW_STOP:
1226 IRDA_DEBUG(2, "%s(), hw stopped!\n", __func__ ); 1207 IRDA_DEBUG(2, "%s(), hw stopped!\n", __func__ );
1227 tty->hw_stopped = 1; 1208 if (tty)
1209 tty->hw_stopped = 1;
1228 break; 1210 break;
1229 } 1211 }
1212
1213 tty_kref_put(tty);
1230 self->flow = cmd; 1214 self->flow = cmd;
1231} 1215}
1232 1216
1233#ifdef CONFIG_PROC_FS 1217#ifdef CONFIG_PROC_FS
1234static void ircomm_tty_line_info(struct ircomm_tty_cb *self, struct seq_file *m) 1218static void ircomm_tty_line_info(struct ircomm_tty_cb *self, struct seq_file *m)
1235{ 1219{
1220 struct tty_struct *tty;
1236 char sep; 1221 char sep;
1237 1222
1238 seq_printf(m, "State: %s\n", ircomm_tty_state[self->state]); 1223 seq_printf(m, "State: %s\n", ircomm_tty_state[self->state]);
@@ -1328,40 +1313,43 @@ static void ircomm_tty_line_info(struct ircomm_tty_cb *self, struct seq_file *m)
1328 1313
1329 seq_puts(m, "Flags:"); 1314 seq_puts(m, "Flags:");
1330 sep = ' '; 1315 sep = ' ';
1331 if (self->flags & ASYNC_CTS_FLOW) { 1316 if (tty_port_cts_enabled(&self->port)) {
1332 seq_printf(m, "%cASYNC_CTS_FLOW", sep); 1317 seq_printf(m, "%cASYNC_CTS_FLOW", sep);
1333 sep = '|'; 1318 sep = '|';
1334 } 1319 }
1335 if (self->flags & ASYNC_CHECK_CD) { 1320 if (self->port.flags & ASYNC_CHECK_CD) {
1336 seq_printf(m, "%cASYNC_CHECK_CD", sep); 1321 seq_printf(m, "%cASYNC_CHECK_CD", sep);
1337 sep = '|'; 1322 sep = '|';
1338 } 1323 }
1339 if (self->flags & ASYNC_INITIALIZED) { 1324 if (self->port.flags & ASYNC_INITIALIZED) {
1340 seq_printf(m, "%cASYNC_INITIALIZED", sep); 1325 seq_printf(m, "%cASYNC_INITIALIZED", sep);
1341 sep = '|'; 1326 sep = '|';
1342 } 1327 }
1343 if (self->flags & ASYNC_LOW_LATENCY) { 1328 if (self->port.flags & ASYNC_LOW_LATENCY) {
1344 seq_printf(m, "%cASYNC_LOW_LATENCY", sep); 1329 seq_printf(m, "%cASYNC_LOW_LATENCY", sep);
1345 sep = '|'; 1330 sep = '|';
1346 } 1331 }
1347 if (self->flags & ASYNC_CLOSING) { 1332 if (self->port.flags & ASYNC_CLOSING) {
1348 seq_printf(m, "%cASYNC_CLOSING", sep); 1333 seq_printf(m, "%cASYNC_CLOSING", sep);
1349 sep = '|'; 1334 sep = '|';
1350 } 1335 }
1351 if (self->flags & ASYNC_NORMAL_ACTIVE) { 1336 if (self->port.flags & ASYNC_NORMAL_ACTIVE) {
1352 seq_printf(m, "%cASYNC_NORMAL_ACTIVE", sep); 1337 seq_printf(m, "%cASYNC_NORMAL_ACTIVE", sep);
1353 sep = '|'; 1338 sep = '|';
1354 } 1339 }
1355 seq_putc(m, '\n'); 1340 seq_putc(m, '\n');
1356 1341
1357 seq_printf(m, "Role: %s\n", self->client ? "client" : "server"); 1342 seq_printf(m, "Role: %s\n", self->client ? "client" : "server");
1358 seq_printf(m, "Open count: %d\n", self->open_count); 1343 seq_printf(m, "Open count: %d\n", self->port.count);
1359 seq_printf(m, "Max data size: %d\n", self->max_data_size); 1344 seq_printf(m, "Max data size: %d\n", self->max_data_size);
1360 seq_printf(m, "Max header size: %d\n", self->max_header_size); 1345 seq_printf(m, "Max header size: %d\n", self->max_header_size);
1361 1346
1362 if (self->tty) 1347 tty = tty_port_tty_get(&self->port);
1348 if (tty) {
1363 seq_printf(m, "Hardware: %s\n", 1349 seq_printf(m, "Hardware: %s\n",
1364 self->tty->hw_stopped ? "Stopped" : "Running"); 1350 tty->hw_stopped ? "Stopped" : "Running");
1351 tty_kref_put(tty);
1352 }
1365} 1353}
1366 1354
1367static int ircomm_tty_proc_show(struct seq_file *m, void *v) 1355static int ircomm_tty_proc_show(struct seq_file *m, void *v)