107 unsigned int rx_read_idx; |
107 unsigned int rx_read_idx; |
108 unsigned int rx_write_idx; |
108 unsigned int rx_write_idx; |
109 |
109 |
110 struct timer_list timer; |
110 struct timer_list timer; |
111 struct tty_struct *tty; |
111 struct tty_struct *tty; |
|
112 unsigned int open_count; |
|
113 struct semaphore sem; |
112 |
114 |
113 ec_tty_operations_t ops; |
115 ec_tty_operations_t ops; |
114 void *cb_data; |
116 void *cb_data; |
115 }; |
117 }; |
116 |
118 |
196 t->wakeup = 0; |
198 t->wakeup = 0; |
197 t->rx_read_idx = 0; |
199 t->rx_read_idx = 0; |
198 t->rx_write_idx = 0; |
200 t->rx_write_idx = 0; |
199 init_timer(&t->timer); |
201 init_timer(&t->timer); |
200 t->tty = NULL; |
202 t->tty = NULL; |
|
203 t->open_count = 0; |
|
204 init_MUTEX(&t->sem); |
201 t->ops = *ops; |
205 t->ops = *ops; |
202 t->cb_data = cb_data; |
206 t->cb_data = cb_data; |
203 |
207 |
204 t->dev = tty_register_device(tty_driver, t->minor, NULL); |
208 t->dev = tty_register_device(tty_driver, t->minor, NULL); |
205 if (IS_ERR(t->dev)) { |
209 if (IS_ERR(t->dev)) { |
364 { |
368 { |
365 ec_tty_t *t; |
369 ec_tty_t *t; |
366 int line = tty->index; |
370 int line = tty->index; |
367 |
371 |
368 #if EC_TTY_DEBUG >= 1 |
372 #if EC_TTY_DEBUG >= 1 |
369 printk(KERN_INFO PFX "Opening line %i.\n", line); |
373 printk(KERN_INFO PFX "%s(tty=%p, file=%p): Opening line %i.\n", |
|
374 __func__, tty, file, line); |
370 #endif |
375 #endif |
371 |
376 |
372 if (line < 0 || line >= EC_TTY_MAX_DEVICES) { |
377 if (line < 0 || line >= EC_TTY_MAX_DEVICES) { |
|
378 tty->driver_data = NULL; |
373 return -ENXIO; |
379 return -ENXIO; |
374 } |
380 } |
375 |
381 |
376 t = ttys[line]; |
382 t = ttys[line]; |
377 if (!t) { |
383 if (!t) { |
|
384 tty->driver_data = NULL; |
378 return -ENXIO; |
385 return -ENXIO; |
379 } |
386 } |
380 |
387 |
381 if (t->tty) { |
388 if (!t->tty) { |
382 return -EBUSY; |
389 t->tty = tty; |
383 } |
390 tty->driver_data = t; |
384 |
391 } |
385 t->tty = tty; |
392 |
386 tty->driver_data = t; |
393 down(&t->sem); |
|
394 t->open_count++; |
|
395 up(&t->sem); |
387 return 0; |
396 return 0; |
388 } |
397 } |
389 |
398 |
390 /*****************************************************************************/ |
399 /*****************************************************************************/ |
391 |
400 |
392 static void ec_tty_close(struct tty_struct *tty, struct file *file) |
401 static void ec_tty_close(struct tty_struct *tty, struct file *file) |
393 { |
402 { |
394 ec_tty_t *t = (ec_tty_t *) tty->driver_data; |
403 ec_tty_t *t = (ec_tty_t *) tty->driver_data; |
395 |
404 |
396 #if EC_TTY_DEBUG >= 1 |
405 #if EC_TTY_DEBUG >= 1 |
397 printk(KERN_INFO PFX "Closing line %i.\n", tty->index); |
406 printk(KERN_INFO PFX "%s(tty=%p, file=%p): Closing line %i.\n", |
398 #endif |
407 __func__, tty, file, tty->index); |
399 |
408 #endif |
400 if (t->tty == tty) { |
409 |
401 t->tty = NULL; |
410 if (t) { |
|
411 down(&t->sem); |
|
412 if (--t->open_count == 0) { |
|
413 t->tty = NULL; |
|
414 } |
|
415 up(&t->sem); |
402 } |
416 } |
403 } |
417 } |
404 |
418 |
405 /*****************************************************************************/ |
419 /*****************************************************************************/ |
406 |
420 |