@@ -19,9 +19,11 @@ static irqreturn_t line_interrupt(int irq, void *data)
19
19
{
20
20
struct chan * chan = data ;
21
21
struct line * line = chan -> line ;
22
+ struct tty_struct * tty = tty_port_tty_get (& line -> port );
22
23
23
24
if (line )
24
- chan_interrupt (line , line -> tty , irq );
25
+ chan_interrupt (line , tty , irq );
26
+ tty_kref_put (tty );
25
27
return IRQ_HANDLED ;
26
28
}
27
29
@@ -219,92 +221,6 @@ void line_set_termios(struct tty_struct *tty, struct ktermios * old)
219
221
/* nothing */
220
222
}
221
223
222
- static const struct {
223
- int cmd ;
224
- char * level ;
225
- char * name ;
226
- } tty_ioctls [] = {
227
- /* don't print these, they flood the log ... */
228
- { TCGETS , NULL , "TCGETS" },
229
- { TCSETS , NULL , "TCSETS" },
230
- { TCSETSW , NULL , "TCSETSW" },
231
- { TCFLSH , NULL , "TCFLSH" },
232
- { TCSBRK , NULL , "TCSBRK" },
233
-
234
- /* general tty stuff */
235
- { TCSETSF , KERN_DEBUG , "TCSETSF" },
236
- { TCGETA , KERN_DEBUG , "TCGETA" },
237
- { TIOCMGET , KERN_DEBUG , "TIOCMGET" },
238
- { TCSBRKP , KERN_DEBUG , "TCSBRKP" },
239
- { TIOCMSET , KERN_DEBUG , "TIOCMSET" },
240
-
241
- /* linux-specific ones */
242
- { TIOCLINUX , KERN_INFO , "TIOCLINUX" },
243
- { KDGKBMODE , KERN_INFO , "KDGKBMODE" },
244
- { KDGKBTYPE , KERN_INFO , "KDGKBTYPE" },
245
- { KDSIGACCEPT , KERN_INFO , "KDSIGACCEPT" },
246
- };
247
-
248
- int line_ioctl (struct tty_struct * tty , unsigned int cmd ,
249
- unsigned long arg )
250
- {
251
- int ret ;
252
- int i ;
253
-
254
- ret = 0 ;
255
- switch (cmd ) {
256
- #ifdef TIOCGETP
257
- case TIOCGETP :
258
- case TIOCSETP :
259
- case TIOCSETN :
260
- #endif
261
- #ifdef TIOCGETC
262
- case TIOCGETC :
263
- case TIOCSETC :
264
- #endif
265
- #ifdef TIOCGLTC
266
- case TIOCGLTC :
267
- case TIOCSLTC :
268
- #endif
269
- /* Note: these are out of date as we now have TCGETS2 etc but this
270
- whole lot should probably go away */
271
- case TCGETS :
272
- case TCSETSF :
273
- case TCSETSW :
274
- case TCSETS :
275
- case TCGETA :
276
- case TCSETAF :
277
- case TCSETAW :
278
- case TCSETA :
279
- case TCXONC :
280
- case TCFLSH :
281
- case TIOCOUTQ :
282
- case TIOCINQ :
283
- case TIOCGLCKTRMIOS :
284
- case TIOCSLCKTRMIOS :
285
- case TIOCPKT :
286
- case TIOCGSOFTCAR :
287
- case TIOCSSOFTCAR :
288
- return - ENOIOCTLCMD ;
289
- #if 0
290
- case TCwhatever :
291
- /* do something */
292
- break ;
293
- #endif
294
- default :
295
- for (i = 0 ; i < ARRAY_SIZE (tty_ioctls ); i ++ )
296
- if (cmd == tty_ioctls [i ].cmd )
297
- break ;
298
- if (i == ARRAY_SIZE (tty_ioctls )) {
299
- printk (KERN_ERR "%s: %s: unknown ioctl: 0x%x\n" ,
300
- __func__ , tty -> name , cmd );
301
- }
302
- ret = - ENOIOCTLCMD ;
303
- break ;
304
- }
305
- return ret ;
306
- }
307
-
308
224
void line_throttle (struct tty_struct * tty )
309
225
{
310
226
struct line * line = tty -> driver_data ;
@@ -333,7 +249,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
333
249
{
334
250
struct chan * chan = data ;
335
251
struct line * line = chan -> line ;
336
- struct tty_struct * tty = line -> tty ;
252
+ struct tty_struct * tty ;
337
253
int err ;
338
254
339
255
/*
@@ -352,10 +268,13 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
352
268
}
353
269
spin_unlock (& line -> lock );
354
270
271
+ tty = tty_port_tty_get (& line -> port );
355
272
if (tty == NULL )
356
273
return IRQ_NONE ;
357
274
358
275
tty_wakeup (tty );
276
+ tty_kref_put (tty );
277
+
359
278
return IRQ_HANDLED ;
360
279
}
361
280
@@ -377,88 +296,75 @@ int line_setup_irq(int fd, int input, int output, struct line *line, void *data)
377
296
return err ;
378
297
}
379
298
380
- /*
381
- * Normally, a driver like this can rely mostly on the tty layer
382
- * locking, particularly when it comes to the driver structure.
383
- * However, in this case, mconsole requests can come in "from the
384
- * side", and race with opens and closes.
385
- *
386
- * mconsole config requests will want to be sure the device isn't in
387
- * use, and get_config, open, and close will want a stable
388
- * configuration. The checking and modification of the configuration
389
- * is done under a spinlock. Checking whether the device is in use is
390
- * line->tty->count > 1, also under the spinlock.
391
- *
392
- * line->count serves to decide whether the device should be enabled or
393
- * disabled on the host. If it's equal to 0, then we are doing the
394
- * first open or last close. Otherwise, open and close just return.
395
- */
396
-
397
- int line_open (struct line * lines , struct tty_struct * tty )
299
+ static int line_activate (struct tty_port * port , struct tty_struct * tty )
398
300
{
399
- struct line * line = & lines [tty -> index ];
400
- int err = - ENODEV ;
401
-
402
- mutex_lock (& line -> count_lock );
403
- if (!line -> valid )
404
- goto out_unlock ;
405
-
406
- err = 0 ;
407
- if (line -> count ++ )
408
- goto out_unlock ;
409
-
410
- BUG_ON (tty -> driver_data );
411
- tty -> driver_data = line ;
412
- line -> tty = tty ;
301
+ int ret ;
302
+ struct line * line = tty -> driver_data ;
413
303
414
- err = enable_chan (line );
415
- if (err ) /* line_close() will be called by our caller */
416
- goto out_unlock ;
304
+ ret = enable_chan (line );
305
+ if (ret )
306
+ return ret ;
417
307
418
308
if (!line -> sigio ) {
419
309
chan_enable_winch (line -> chan_out , tty );
420
310
line -> sigio = 1 ;
421
311
}
422
312
423
313
chan_window_size (line , & tty -> winsize .ws_row ,
424
- & tty -> winsize .ws_col );
425
- out_unlock :
426
- mutex_unlock (& line -> count_lock );
427
- return err ;
314
+ & tty -> winsize .ws_col );
315
+
316
+ return 0 ;
428
317
}
429
318
430
- static void unregister_winch (struct tty_struct * tty );
319
+ static const struct tty_port_operations line_port_ops = {
320
+ .activate = line_activate ,
321
+ };
431
322
432
- void line_close (struct tty_struct * tty , struct file * filp )
323
+ int line_open (struct tty_struct * tty , struct file * filp )
433
324
{
434
325
struct line * line = tty -> driver_data ;
435
326
436
- /*
437
- * If line_open fails (and tty->driver_data is never set),
438
- * tty_open will call line_close. So just return in this case.
439
- */
440
- if (line == NULL )
441
- return ;
327
+ return tty_port_open (& line -> port , tty , filp );
328
+ }
442
329
443
- /* We ignore the error anyway! */
444
- flush_buffer (line );
330
+ int line_install (struct tty_driver * driver , struct tty_struct * tty ,
331
+ struct line * line )
332
+ {
333
+ int ret ;
445
334
446
- mutex_lock (& line -> count_lock );
447
- BUG_ON (!line -> valid );
335
+ ret = tty_standard_install (driver , tty );
336
+ if (ret )
337
+ return ret ;
448
338
449
- if (-- line -> count )
450
- goto out_unlock ;
339
+ tty -> driver_data = line ;
451
340
452
- line -> tty = NULL ;
453
- tty -> driver_data = NULL ;
341
+ return 0 ;
342
+ }
343
+
344
+ static void unregister_winch (struct tty_struct * tty );
345
+
346
+ void line_cleanup (struct tty_struct * tty )
347
+ {
348
+ struct line * line = tty -> driver_data ;
454
349
455
350
if (line -> sigio ) {
456
351
unregister_winch (tty );
457
352
line -> sigio = 0 ;
458
353
}
354
+ }
355
+
356
+ void line_close (struct tty_struct * tty , struct file * filp )
357
+ {
358
+ struct line * line = tty -> driver_data ;
459
359
460
- out_unlock :
461
- mutex_unlock (& line -> count_lock );
360
+ tty_port_close (& line -> port , tty , filp );
361
+ }
362
+
363
+ void line_hangup (struct tty_struct * tty )
364
+ {
365
+ struct line * line = tty -> driver_data ;
366
+
367
+ tty_port_hangup (& line -> port );
462
368
}
463
369
464
370
void close_lines (struct line * lines , int nlines )
@@ -476,9 +382,7 @@ int setup_one_line(struct line *lines, int n, char *init,
476
382
struct tty_driver * driver = line -> driver -> driver ;
477
383
int err = - EINVAL ;
478
384
479
- mutex_lock (& line -> count_lock );
480
-
481
- if (line -> count ) {
385
+ if (line -> port .count ) {
482
386
* error_out = "Device is already open" ;
483
387
goto out ;
484
388
}
@@ -519,7 +423,6 @@ int setup_one_line(struct line *lines, int n, char *init,
519
423
}
520
424
}
521
425
out :
522
- mutex_unlock (& line -> count_lock );
523
426
return err ;
524
427
}
525
428
@@ -607,13 +510,17 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
607
510
608
511
line = & lines [dev ];
609
512
610
- mutex_lock (& line -> count_lock );
611
513
if (!line -> valid )
612
514
CONFIG_CHUNK (str , size , n , "none" , 1 );
613
- else if (line -> tty == NULL )
614
- CONFIG_CHUNK (str , size , n , line -> init_str , 1 );
615
- else n = chan_config_string (line , str , size , error_out );
616
- mutex_unlock (& line -> count_lock );
515
+ else {
516
+ struct tty_struct * tty = tty_port_tty_get (& line -> port );
517
+ if (tty == NULL ) {
518
+ CONFIG_CHUNK (str , size , n , line -> init_str , 1 );
519
+ } else {
520
+ n = chan_config_string (line , str , size , error_out );
521
+ tty_kref_put (tty );
522
+ }
523
+ }
617
524
618
525
return n ;
619
526
}
@@ -663,8 +570,9 @@ int register_lines(struct line_driver *line_driver,
663
570
driver -> init_termios = tty_std_termios ;
664
571
665
572
for (i = 0 ; i < nlines ; i ++ ) {
573
+ tty_port_init (& lines [i ].port );
574
+ lines [i ].port .ops = & line_port_ops ;
666
575
spin_lock_init (& lines [i ].lock );
667
- mutex_init (& lines [i ].count_lock );
668
576
lines [i ].driver = line_driver ;
669
577
INIT_LIST_HEAD (& lines [i ].chan_list );
670
578
}
0 commit comments