Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

serial: use tty_port

Switch the serial_core based drivers to use the new tty_port structure.
We can't quite use all of it yet because of the dynamically allocated
extras in the serial_core layer.

Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Alan Cox and committed by
Linus Torvalds
df4f4dd4 6f67048c

+60 -58
+1 -1
drivers/serial/8250.c
··· 1287 1287 static void 1288 1288 receive_chars(struct uart_8250_port *up, unsigned int *status) 1289 1289 { 1290 - struct tty_struct *tty = up->port.info->tty; 1290 + struct tty_struct *tty = up->port.info->port.tty; 1291 1291 unsigned char ch, lsr = *status; 1292 1292 int max_count = 256; 1293 1293 char flag;
+1 -1
drivers/serial/jsm/jsm_neo.c
··· 998 998 { 50, B50 }, 999 999 }; 1000 1000 1001 - cflag = C_BAUD(ch->uart_port.info->tty); 1001 + cflag = C_BAUD(ch->uart_port.info->port.tty); 1002 1002 baud = 9600; 1003 1003 for (i = 0; i < ARRAY_SIZE(baud_rates); i++) { 1004 1004 if (baud_rates[i].cflag == cflag) {
+4 -4
drivers/serial/jsm/jsm_tty.c
··· 145 145 struct ktermios *termios; 146 146 147 147 spin_lock_irqsave(&port->lock, lock_flags); 148 - termios = port->info->tty->termios; 148 + termios = port->info->port.tty->termios; 149 149 if (ch == termios->c_cc[VSTART]) 150 150 channel->ch_bd->bd_ops->send_start_character(channel); 151 151 ··· 239 239 channel->ch_cached_lsr = 0; 240 240 channel->ch_stops_sent = 0; 241 241 242 - termios = port->info->tty->termios; 242 + termios = port->info->port.tty->termios; 243 243 channel->ch_c_cflag = termios->c_cflag; 244 244 channel->ch_c_iflag = termios->c_iflag; 245 245 channel->ch_c_oflag = termios->c_oflag; ··· 272 272 jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, "start\n"); 273 273 274 274 bd = channel->ch_bd; 275 - ts = channel->uart_port.info->tty->termios; 275 + ts = channel->uart_port.info->port.tty->termios; 276 276 277 277 channel->ch_flags &= ~(CH_STOPI); 278 278 ··· 515 515 if (!ch) 516 516 return; 517 517 518 - tp = ch->uart_port.info->tty; 518 + tp = ch->uart_port.info->port.tty; 519 519 520 520 bd = ch->ch_bd; 521 521 if(!bd)
+42 -38
drivers/serial/serial_core.c
··· 50 50 51 51 #define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) 52 52 53 - #define uart_users(state) ((state)->count + ((state)->info ? (state)->info->blocked_open : 0)) 53 + #define uart_users(state) ((state)->count + ((state)->info ? (state)->info->port.blocked_open : 0)) 54 54 55 55 #ifdef CONFIG_SERIAL_CORE_CONSOLE 56 56 #define uart_console(port) ((port)->cons && (port)->cons->index == (port)->line) ··· 113 113 static void uart_tasklet_action(unsigned long data) 114 114 { 115 115 struct uart_state *state = (struct uart_state *)data; 116 - tty_wakeup(state->info->tty); 116 + tty_wakeup(state->info->port.tty); 117 117 } 118 118 119 119 static inline void ··· 135 135 136 136 /* 137 137 * Startup the port. This will be called once per open. All calls 138 - * will be serialised by the per-port semaphore. 138 + * will be serialised by the per-port mutex. 139 139 */ 140 140 static int uart_startup(struct uart_state *state, int init_hw) 141 141 { ··· 152 152 * once we have successfully opened the port. Also set 153 153 * up the tty->alt_speed kludge 154 154 */ 155 - set_bit(TTY_IO_ERROR, &info->tty->flags); 155 + set_bit(TTY_IO_ERROR, &info->port.tty->flags); 156 156 157 157 if (port->type == PORT_UNKNOWN) 158 158 return 0; ··· 162 162 * buffer. 163 163 */ 164 164 if (!info->xmit.buf) { 165 + /* This is protected by the per port mutex */ 165 166 page = get_zeroed_page(GFP_KERNEL); 166 167 if (!page) 167 168 return -ENOMEM; ··· 183 182 * Setup the RTS and DTR signals once the 184 183 * port is open and ready to respond. 185 184 */ 186 - if (info->tty->termios->c_cflag & CBAUD) 185 + if (info->port.tty->termios->c_cflag & CBAUD) 187 186 uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR); 188 187 } 189 188 190 189 if (info->flags & UIF_CTS_FLOW) { 191 190 spin_lock_irq(&port->lock); 192 191 if (!(port->ops->get_mctrl(port) & TIOCM_CTS)) 193 - info->tty->hw_stopped = 1; 192 + info->port.tty->hw_stopped = 1; 194 193 spin_unlock_irq(&port->lock); 195 194 } 196 195 197 196 info->flags |= UIF_INITIALIZED; 198 197 199 - clear_bit(TTY_IO_ERROR, &info->tty->flags); 198 + clear_bit(TTY_IO_ERROR, &info->port.tty->flags); 200 199 } 201 200 202 201 if (retval && capable(CAP_SYS_ADMIN)) ··· 218 217 /* 219 218 * Set the TTY IO error marker 220 219 */ 221 - if (info->tty) 222 - set_bit(TTY_IO_ERROR, &info->tty->flags); 220 + if (info->port.tty) 221 + set_bit(TTY_IO_ERROR, &info->port.tty->flags); 223 222 224 223 if (info->flags & UIF_INITIALIZED) { 225 224 info->flags &= ~UIF_INITIALIZED; ··· 227 226 /* 228 227 * Turn off DTR and RTS early. 229 228 */ 230 - if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) 229 + if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) 231 230 uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); 232 231 233 232 /* ··· 427 426 static void 428 427 uart_change_speed(struct uart_state *state, struct ktermios *old_termios) 429 428 { 430 - struct tty_struct *tty = state->info->tty; 429 + struct tty_struct *tty = state->info->port.tty; 431 430 struct uart_port *port = state->port; 432 431 struct ktermios *termios; 433 432 ··· 837 836 state->closing_wait = closing_wait; 838 837 if (new_serial.xmit_fifo_size) 839 838 port->fifosize = new_serial.xmit_fifo_size; 840 - if (state->info->tty) 841 - state->info->tty->low_latency = 839 + if (state->info->port.tty) 840 + state->info->port.tty->low_latency = 842 841 (port->flags & UPF_LOW_LATENCY) ? 1 : 0; 843 842 844 843 check_and_exit: ··· 858 857 printk(KERN_NOTICE 859 858 "%s sets custom speed on %s. This " 860 859 "is deprecated.\n", current->comm, 861 - tty_name(state->info->tty, buf)); 860 + tty_name(state->info->port.tty, buf)); 862 861 } 863 862 uart_change_speed(state, NULL); 864 863 } ··· 890 889 */ 891 890 if (port->x_char || 892 891 ((uart_circ_chars_pending(&state->info->xmit) > 0) && 893 - !state->info->tty->stopped && !state->info->tty->hw_stopped)) 892 + !state->info->port.tty->stopped && !state->info->port.tty->hw_stopped)) 894 893 result &= ~TIOCSER_TEMT; 895 894 896 895 return put_user(result, value); ··· 1240 1239 */ 1241 1240 if (!(old_termios->c_cflag & CLOCAL) && 1242 1241 (tty->termios->c_cflag & CLOCAL)) 1243 - wake_up_interruptible(&state->info->open_wait); 1242 + wake_up_interruptible(&state->info->port.open_wait); 1244 1243 #endif 1245 1244 } 1246 1245 ··· 1321 1320 tty_ldisc_flush(tty); 1322 1321 1323 1322 tty->closing = 0; 1324 - state->info->tty = NULL; 1323 + state->info->port.tty = NULL; 1325 1324 1326 - if (state->info->blocked_open) { 1325 + if (state->info->port.blocked_open) { 1327 1326 if (state->close_delay) 1328 1327 msleep_interruptible(state->close_delay); 1329 1328 } else if (!uart_console(port)) { ··· 1334 1333 * Wake up anyone trying to open this port. 1335 1334 */ 1336 1335 state->info->flags &= ~UIF_NORMAL_ACTIVE; 1337 - wake_up_interruptible(&state->info->open_wait); 1336 + wake_up_interruptible(&state->info->port.open_wait); 1338 1337 1339 1338 done: 1340 1339 mutex_unlock(&state->mutex); ··· 1418 1417 uart_shutdown(state); 1419 1418 state->count = 0; 1420 1419 state->info->flags &= ~UIF_NORMAL_ACTIVE; 1421 - state->info->tty = NULL; 1422 - wake_up_interruptible(&state->info->open_wait); 1420 + state->info->port.tty = NULL; 1421 + wake_up_interruptible(&state->info->port.open_wait); 1423 1422 wake_up_interruptible(&state->info->delta_msr_wait); 1424 1423 } 1425 1424 mutex_unlock(&state->mutex); ··· 1433 1432 */ 1434 1433 static void uart_update_termios(struct uart_state *state) 1435 1434 { 1436 - struct tty_struct *tty = state->info->tty; 1435 + struct tty_struct *tty = state->info->port.tty; 1437 1436 struct uart_port *port = state->port; 1438 1437 1439 1438 if (uart_console(port) && port->cons->cflag) { ··· 1472 1471 struct uart_port *port = state->port; 1473 1472 unsigned int mctrl; 1474 1473 1475 - info->blocked_open++; 1474 + info->port.blocked_open++; 1476 1475 state->count--; 1477 1476 1478 - add_wait_queue(&info->open_wait, &wait); 1477 + add_wait_queue(&info->port.open_wait, &wait); 1479 1478 while (1) { 1480 1479 set_current_state(TASK_INTERRUPTIBLE); 1481 1480 1482 1481 /* 1483 1482 * If we have been hung up, tell userspace/restart open. 1484 1483 */ 1485 - if (tty_hung_up_p(filp) || info->tty == NULL) 1484 + if (tty_hung_up_p(filp) || info->port.tty == NULL) 1486 1485 break; 1487 1486 1488 1487 /* ··· 1501 1500 * have set TTY_IO_ERROR for a non-existant port. 1502 1501 */ 1503 1502 if ((filp->f_flags & O_NONBLOCK) || 1504 - (info->tty->termios->c_cflag & CLOCAL) || 1505 - (info->tty->flags & (1 << TTY_IO_ERROR))) 1503 + (info->port.tty->termios->c_cflag & CLOCAL) || 1504 + (info->port.tty->flags & (1 << TTY_IO_ERROR))) 1506 1505 break; 1507 1506 1508 1507 /* ··· 1510 1509 * not set RTS here - we want to make sure we catch 1511 1510 * the data from the modem. 1512 1511 */ 1513 - if (info->tty->termios->c_cflag & CBAUD) 1512 + if (info->port.tty->termios->c_cflag & CBAUD) 1514 1513 uart_set_mctrl(port, TIOCM_DTR); 1515 1514 1516 1515 /* ··· 1532 1531 break; 1533 1532 } 1534 1533 set_current_state(TASK_RUNNING); 1535 - remove_wait_queue(&info->open_wait, &wait); 1534 + remove_wait_queue(&info->port.open_wait, &wait); 1536 1535 1537 1536 state->count++; 1538 - info->blocked_open--; 1537 + info->port.blocked_open--; 1539 1538 1540 1539 if (signal_pending(current)) 1541 1540 return -ERESTARTSYS; 1542 1541 1543 - if (!info->tty || tty_hung_up_p(filp)) 1542 + if (!info->port.tty || tty_hung_up_p(filp)) 1544 1543 return -EAGAIN; 1545 1544 1546 1545 return 0; ··· 1563 1562 goto err_unlock; 1564 1563 } 1565 1564 1565 + /* BKL: RACE HERE - LEAK */ 1566 + /* We should move this into the uart_state structure and kill off 1567 + this whole complexity */ 1566 1568 if (!state->info) { 1567 1569 state->info = kzalloc(sizeof(struct uart_info), GFP_KERNEL); 1568 1570 if (state->info) { 1569 - init_waitqueue_head(&state->info->open_wait); 1571 + init_waitqueue_head(&state->info->port.open_wait); 1570 1572 init_waitqueue_head(&state->info->delta_msr_wait); 1571 1573 1572 1574 /* ··· 1626 1622 * be re-entered while allocating the info structure, or while we 1627 1623 * request any IRQs that the driver may need. This also has the nice 1628 1624 * side-effect that it delays the action of uart_hangup, so we can 1629 - * guarantee that info->tty will always contain something reasonable. 1625 + * guarantee that info->port.tty will always contain something reasonable. 1630 1626 */ 1631 1627 state = uart_get(drv, line); 1632 1628 if (IS_ERR(state)) { ··· 1642 1638 tty->driver_data = state; 1643 1639 tty->low_latency = (state->port->flags & UPF_LOW_LATENCY) ? 1 : 0; 1644 1640 tty->alt_speed = 0; 1645 - state->info->tty = tty; 1641 + state->info->port.tty = tty; 1646 1642 1647 1643 /* 1648 1644 * If the port is in the middle of closing, bail out now. ··· 2105 2101 /* 2106 2102 * If that's unset, use the tty termios setting. 2107 2103 */ 2108 - if (state->info && state->info->tty && termios.c_cflag == 0) 2109 - termios = *state->info->tty->termios; 2104 + if (state->info && state->info->port.tty && termios.c_cflag == 0) 2105 + termios = *state->info->port.tty->termios; 2110 2106 2111 2107 uart_change_pm(state, 0); 2112 2108 port->ops->set_termios(port, &termios, NULL); ··· 2525 2521 tty_unregister_device(drv->tty_driver, port->line); 2526 2522 2527 2523 info = state->info; 2528 - if (info && info->tty) 2529 - tty_vhangup(info->tty); 2524 + if (info && info->port.tty) 2525 + tty_vhangup(info->port.tty); 2530 2526 2531 2527 /* 2532 2528 * All users of this port should now be disconnected from
+12 -14
include/linux/serial_core.h
··· 344 344 * stuff here. 345 345 */ 346 346 struct uart_info { 347 - struct tty_struct *tty; 347 + struct tty_port port; 348 348 struct circ_buf xmit; 349 349 uif_t flags; 350 350 351 351 /* 352 352 * Definitions for info->flags. These are _private_ to serial_core, and 353 353 * are specific to this structure. They may be queried by low level drivers. 354 + * 355 + * FIXME: use the ASY_ definitions 354 356 */ 355 357 #define UIF_CHECK_CD ((__force uif_t) (1 << 25)) 356 358 #define UIF_CTS_FLOW ((__force uif_t) (1 << 26)) ··· 360 358 #define UIF_INITIALIZED ((__force uif_t) (1 << 31)) 361 359 #define UIF_SUSPENDED ((__force uif_t) (1 << 30)) 362 360 363 - int blocked_open; 364 - 365 361 struct tasklet_struct tlet; 366 - 367 - wait_queue_head_t open_wait; 368 362 wait_queue_head_t delta_msr_wait; 369 363 }; 370 364 ··· 437 439 #define uart_circ_chars_free(circ) \ 438 440 (CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE)) 439 441 440 - #define uart_tx_stopped(port) \ 441 - ((port)->info->tty->stopped || (port)->info->tty->hw_stopped) 442 + #define uart_tx_stopped(portp) \ 443 + ((portp)->info->port.tty->stopped || (portp)->info->port.tty->hw_stopped) 442 444 443 445 /* 444 446 * The following are helper functions for the low level drivers. ··· 449 451 #ifdef SUPPORT_SYSRQ 450 452 if (port->sysrq) { 451 453 if (ch && time_before(jiffies, port->sysrq)) { 452 - handle_sysrq(ch, port->info ? port->info->tty : NULL); 454 + handle_sysrq(ch, port->info ? port->info->port.tty : NULL); 453 455 port->sysrq = 0; 454 456 return 1; 455 457 } ··· 478 480 } 479 481 #endif 480 482 if (port->flags & UPF_SAK) 481 - do_SAK(info->tty); 483 + do_SAK(info->port.tty); 482 484 return 0; 483 485 } 484 486 ··· 501 503 502 504 if (info->flags & UIF_CHECK_CD) { 503 505 if (status) 504 - wake_up_interruptible(&info->open_wait); 505 - else if (info->tty) 506 - tty_hangup(info->tty); 506 + wake_up_interruptible(&info->port.open_wait); 507 + else if (info->port.tty) 508 + tty_hangup(info->port.tty); 507 509 } 508 510 } 509 511 ··· 516 518 uart_handle_cts_change(struct uart_port *port, unsigned int status) 517 519 { 518 520 struct uart_info *info = port->info; 519 - struct tty_struct *tty = info->tty; 521 + struct tty_struct *tty = info->port.tty; 520 522 521 523 port->icount.cts++; 522 524 ··· 542 544 uart_insert_char(struct uart_port *port, unsigned int status, 543 545 unsigned int overrun, unsigned int ch, unsigned int flag) 544 546 { 545 - struct tty_struct *tty = port->info->tty; 547 + struct tty_struct *tty = port->info->port.tty; 546 548 547 549 if ((status & port->ignore_status_mask & ~overrun) == 0) 548 550 tty_insert_flip_char(tty, ch, flag);