计算机的串口在哪里改,我想更改一个tty 串口设备的串口号,从串口2-到3,但是在源码里找不到在哪里改。...

#include

#include

#include

#include

#include

#include

#include

#include

#define FIFO_SIZE        PAGE_SIZE

__u32        cts;

__u32        rng;

__u32        rx;

__u32        frame;

__u32        parity;

};

struct sdio_uart_port {

struct kref                kref;

unsigned int                index;

struct mutex                func_lock;

unsigned int                regs_offset;

spinlock_t                write_lock;

unsigned int                uartclk;

unsigned int                rx_mctrl;

unsigned int                ignore_status_mask;

unsigned char           ier;

};

static struct sdio_uart_port *sdio_uart_table[UART_NR];

{

mutex_init(&port->func_lock);

if (kfifo_alloc(&port->xmit_fifo, FIFO_SIZE, GFP_KERNEL))

for (index = 0; index < UART_NR; index++) {

port->index = index;

ret = 0;

}

spin_unlock(&sdio_uart_table_lock);

return ret;

{

return NULL;

spin_lock(&sdio_uart_table_lock);

if (port)

spin_unlock(&sdio_uart_table_lock);

return port;

{

container_of(kref, struct sdio_uart_port, kref);

kfree(port);

{

}

static void sdio_uart_port_remove(struct sdio_uart_port *port)

struct sdio_func *func;

sdio_uart_table[port->index] = NULL;

* We're killing a port that potentially still is in use by

* to the SDIO function and arrange for the tty layer to

* Beware: the lock ordering is critical.

mutex_lock(&port->port.mutex);

func = port->func;

port->func = NULL;

tty = tty_port_tty_get(&port->port);

if (tty) {

tty_kref_put(tty);

mutex_unlock(&port->port.mutex);

sdio_disable_func(func);

}

static int sdio_uart_claim_func(struct sdio_uart_port *port)

mutex_lock(&port->func_lock);

mutex_unlock(&port->func_lock);

}

sdio_claim_host(port->func);

return 0;

{

sdio_release_host(port->func);

{

c = sdio_readb(port->func, port->regs_offset + offset, NULL);

}

static inline void sdio_out(struct sdio_uart_port *port, int offset, int value)

sdio_writeb(port->func, value, port->regs_offset + offset, NULL);

{

unsigned int ret;

/* FIXME: What stops this losing the delta bits and breaking

status = sdio_in(port, UART_MSR);

ret = 0;

ret |= TIOCM_CAR;

ret |= TIOCM_RNG;

ret |= TIOCM_DSR;

ret |= TIOCM_CTS;

}

static void sdio_uart_write_mctrl(struct sdio_uart_port *port,

{

mcr |= UART_MCR_RTS;

mcr |= UART_MCR_DTR;

mcr |= UART_MCR_OUT1;

mcr |= UART_MCR_OUT2;

mcr |= UART_MCR_LOOP;

sdio_out(port, UART_MCR, mcr);

unsigned int set, unsigned int clear)

unsigned int old;

old = port->mctrl;

if (old != port->mctrl)

}

#define sdio_uart_set_mctrl(port, x)        sdio_uart_update_mctrl(port, x, 0)

struct ktermios *termios,

{

unsigned int baud, quot;

switch (termios->c_cflag & CSIZE) {

cval = UART_LCR_WLEN5;

case CS6:

break;

cval = UART_LCR_WLEN7;

default:

cval = UART_LCR_WLEN8;

}

if (termios->c_cflag & CSTOPB)

if (termios->c_cflag & PARENB)

if (!(termios->c_cflag & PARODD))

baud = tty_termios_baud_rate(termios);

baud = 9600;  /* Special case: B0 rate. */

break;

* Oops, the quotient was zero.  Try again with the old

*/

if (old) {

old = NULL;

termios->c_cflag |= B9600;

quot = (2 * port->uartclk + baud) / (2 * baud);

if (baud < 2400)

else

if (termios->c_iflag & INPCK)

if (termios->c_iflag & (BRKINT | PARMRK))

* Characters to ignore

port->ignore_status_mask = 0;

port->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;

port->ignore_status_mask |= UART_LSR_BI;

* If we're ignoring parity and break indicators,

*/

port->ignore_status_mask |= UART_LSR_OE;

* ignore all characters if CREAD is not set

if ((termios->c_cflag & CREAD) == 0)

* CTS flow control flag and modem status interrupts

port->ier &= ~UART_IER_MSI;

port->ier |= UART_IER_MSI;

port->lcr = cval;

sdio_out(port, UART_IER, port->ier);

sdio_out(port, UART_DLL, quot & 0xff);

sdio_out(port, UART_LCR, cval);

}

static void sdio_uart_start_tx(struct sdio_uart_port *port)

if (!(port->ier & UART_IER_THRI)) {

sdio_out(port, UART_IER, port->ier);

}

static void sdio_uart_stop_tx(struct sdio_uart_port *port)

if (port->ier & UART_IER_THRI) {

sdio_out(port, UART_IER, port->ier);

}

static void sdio_uart_stop_rx(struct sdio_uart_port *port)

port->ier &= ~UART_IER_RLSI;

sdio_out(port, UART_IER, port->ier);

unsigned int *status)

struct tty_struct *tty = tty_port_tty_get(&port->port);

int max_count = 256;

do {

flag = TTY_NORMAL;

UART_LSR_FE | UART_LSR_OE))) {

* For statistics only

if (*status & UART_LSR_BI) {

port->icount.brk++;

port->icount.parity++;

port->icount.frame++;

port->icount.overrun++;

/*

*/

if (*status & UART_LSR_BI)

else if (*status & UART_LSR_PE)

else if (*status & UART_LSR_FE)

}

if ((*status & port->ignore_status_mask & ~UART_LSR_OE) == 0)

tty_insert_flip_char(tty, ch, flag);

/*

* it doesn't affect the current character.

if (*status & ~port->ignore_status_mask & UART_LSR_OE)

tty_insert_flip_char(tty, 0, TTY_OVERRUN);

*status = sdio_in(port, UART_LSR);

if (tty) {

tty_kref_put(tty);

}

static void sdio_uart_transmit_chars(struct sdio_uart_port *port)

struct kfifo *xmit = &port->xmit_fifo;

struct tty_struct *tty;

int len;

if (port->x_char) {

port->icount.tx++;

return;

tty->stopped || tty->hw_stopped) {

tty_kref_put(tty);

}

len = kfifo_out_locked(xmit, iobuf, 16, &port->write_lock);

sdio_out(port, UART_TX, iobuf[count]);

}

len = kfifo_len(xmit);

tty_wakeup(tty);

sdio_uart_stop_tx(port);

tty_kref_put(tty);

{

struct tty_struct *tty;

status = sdio_in(port, UART_MSR);

if ((status & UART_MSR_ANY_DELTA) == 0)

port->icount.rng++;

port->icount.dsr++;

port->icount.dcd++;

if (status & UART_MSR_DCD)

else {

tty = tty_port_tty_get(&port->port);

tty_hangup(tty);

}

}

port->icount.cts++;

if (tty && (tty->termios->c_cflag & CRTSCTS)) {

if (tty->hw_stopped) {

tty->hw_stopped = 0;

tty_wakeup(tty);

} else {

tty->hw_stopped = 1;

}

}

}

* This handles the interrupt from one port.

static void sdio_uart_irq(struct sdio_func *func)

struct sdio_uart_port *port = sdio_get_drvdata(func);

* In a few places sdio_uart_irq() is calLED directly instead of

* thread scheduled in order to reduce latency.  However, some

* (serial echo, flow control, etc.) through those same places

*/

return;

iir = sdio_in(port, UART_IIR);

return;

port->in_sdio_uart_irq = current;

if (lsr & UART_LSR_DR)

sdio_uart_check_modem_status(port);

sdio_uart_transmit_chars(port);

}

static int uart_carrier_raised(struct tty_port *tport)

struct sdio_uart_port *port =

unsigned int ret = sdio_uart_claim_func(port);

return 1;

sdio_uart_release_func(port);

return 1;

}

/**

*        @tport: tty port to be updated

*

*        adjusted during an open, close and hangup.

{

container_of(tport, struct sdio_uart_port, port);

if (ret)

if (onoff == 0)

else

sdio_uart_release_func(port);

*        sdio_uart_activate        -        start up hardware

*        @tty: tty bound to this port

*        Activate a tty port. The port locking guarantees us this will be

*        shutdown method run exactly once to match. Start up and shutdown are

*        at the same time even during a hangup event.

*        If we successfully start up the port we take an extra kref as we

*/

static int sdio_uart_activate(struct tty_port *tport, struct tty_struct *tty)

struct sdio_uart_port *port =

int ret;

/*

* once we have successfully opened the port.

set_bit(TTY_IO_ERROR, &tty->flags);

kfifo_reset(&port->xmit_fifo);

ret = sdio_uart_claim_func(port);

return ret;

if (ret)

ret = sdio_claim_irq(port->func, sdio_uart_irq);

goto err2;

/*

* (they will be reenabled in sdio_change_speed())

sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO);

UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);

* Clear the interrupt registers.

(void) sdio_in(port, UART_LSR);

(void) sdio_in(port, UART_IIR);

* Now, initialize the UART

sdio_out(port, UART_LCR, UART_LCR_WLEN8);

port->ier = UART_IER_RLSI|UART_IER_RDI|UART_IER_RTOIE|UART_IER_UUE;

sdio_uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);

if (tty->termios->c_cflag & CRTSCTS)

tty->hw_stopped = 1;

clear_bit(TTY_IO_ERROR, &tty->flags);

/* Kick the IRQ handler once while we're still holding the host lock */

return 0;

err2:

err1:

return ret;

*        sdio_uart_shutdown        -        stop hardware

*

*        run only if a successful matching activate already ran. The two are

*        at the same time even during a hangup event.

{

container_of(tport, struct sdio_uart_port, port);

if (ret)

sdio_release_irq(port->func);

sdio_out(port, UART_IER, 0);

sdio_uart_clear_mctrl(port, TIOCM_OUT2);

/* Disable break condition and FIFOs. */

sdio_out(port, UART_LCR, port->lcr);

UART_FCR_CLEAR_RCVR |

sdio_out(port, UART_FCR, 0);

sdio_disable_func(port->func);

sdio_uart_release_func(port);

*        sdio_uart_install        -        install method

*        @tty: the tty being bound

*        Look up and bind the tty and the driver together. Initialize

*/

static int sdio_uart_install(struct tty_driver *driver, struct tty_struct *tty)

int idx = tty->index;

int ret = tty_standard_install(driver, tty);

if (ret == 0)

tty->driver_data = port;

sdio_uart_port_put(port);

}

/**

*        @tty: the tty being destroyed

*        Called asynchronously when the last reference to the tty is dropped.

*/

static void sdio_uart_cleanup(struct tty_struct *tty)

struct sdio_uart_port *port = tty->driver_data;

sdio_uart_port_put(port);

*        Open/close/hangup is now entirely boilerplate

{

return tty_port_open(&port->port, tty, filp);

{

tty_port_close(&port->port, tty, filp);

{

tty_port_hangup(&port->port);

int count)

struct sdio_uart_port *port = tty->driver_data;

return -ENODEV;

ret = kfifo_in_locked(&port->xmit_fifo, buf, count, &port->write_lock);

int err = sdio_uart_claim_func(port);

sdio_uart_start_tx(port);

sdio_uart_release_func(port);

ret = err;

}

static int sdio_uart_write_room(struct tty_struct *tty)

struct sdio_uart_port *port = tty->driver_data;

}

static int sdio_uart_chars_in_buffer(struct tty_struct *tty)

struct sdio_uart_port *port = tty->driver_data;

}

static void sdio_uart_send_xchar(struct tty_struct *tty, char ch)

struct sdio_uart_port *port = tty->driver_data;

port->x_char = ch;

if (sdio_uart_claim_func(port) != 0)

sdio_uart_start_tx(port);

sdio_uart_release_func(port);

}

static void sdio_uart_throttle(struct tty_struct *tty)

struct sdio_uart_port *port = tty->driver_data;

if (!I_IXOFF(tty) && !(tty->termios->c_cflag & CRTSCTS))

return;

if (I_IXOFF(tty)) {

sdio_uart_start_tx(port);

sdio_uart_clear_mctrl(port, TIOCM_RTS);

sdio_uart_irq(port->func);

}

static void sdio_uart_unthrottle(struct tty_struct *tty)

struct sdio_uart_port *port = tty->driver_data;

if (!I_IXOFF(tty) && !(tty->termios->c_cflag & CRTSCTS))

return;

if (I_IXOFF(tty)) {

port->x_char = 0;

port->x_char = START_CHAR(tty);

}

sdio_uart_set_mctrl(port, TIOCM_RTS);

sdio_uart_irq(port->func);

}

static void sdio_uart_set_termios(struct tty_struct *tty,

{

unsigned int cflag = tty->termios->c_cflag;

if (sdio_uart_claim_func(port) != 0)

if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD))

if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {

if (!(cflag & CRTSCTS) || !test_bit(TTY_THROTTLED, &tty->flags))

sdio_uart_set_mctrl(port, mask);

if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) {

sdio_uart_start_tx(port);

if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) {

tty->hw_stopped = 1;

}

}

static int sdio_uart_break_ctl(struct tty_struct *tty, int break_state)

struct sdio_uart_port *port = tty->driver_data;

if (result != 0)

port->lcr |= UART_LCR_SBC;

port->lcr &= ~UART_LCR_SBC;

return 0;

{

int result;

result = sdio_uart_claim_func(port);

result = port->mctrl | sdio_uart_get_mctrl(port);

}

return result;

unsigned int set, unsigned int clear)

struct sdio_uart_port *port = tty->driver_data;

if (!result) {

sdio_uart_release_func(port);

}

static int sdio_uart_proc_show(struct seq_file *m, void *v)

int i;

seq_printf(m, "serinfo:1.0 driver%s%s revision:%s\n",

for (i = 0; i < UART_NR; i++) {

if (port) {

if (capable(CAP_SYS_ADMIN)) {

port->icount.tx, port->icount.rx);

seq_printf(m, " fe:%d",

if (port->icount.parity)

port->icount.parity);

seq_printf(m, " brk:%d",

if (port->icount.overrun)

port->icount.overrun);

seq_printf(m, " cts:%d",

if (port->icount.dsr)

port->icount.dsr);

seq_printf(m, " rng:%d",

if (port->icount.dcd)

port->icount.dcd);

sdio_uart_port_put(port);

}

return 0;

{

}

static const struct file_operations sdio_uart_proc_fops = {

.open                = sdio_uart_proc_open,

.llseek                = seq_lseek,

};

static const struct tty_port_operations sdio_uart_port_ops = {

.carrier_raised = uart_carrier_raised,

.activate = sdio_uart_activate,

.open                        = sdio_uart_open,

.write                        = sdio_uart_write,

.chars_in_buffer        = sdio_uart_chars_in_buffer,

.throttle                = sdio_uart_throttle,

.set_termios                = sdio_uart_set_termios,

.break_ctl                = sdio_uart_break_ctl,

.tiocmset                = sdio_uart_tiocmset,

.cleanup                = sdio_uart_cleanup,

};

static struct tty_driver *sdio_uart_tty_driver;

static int sdio_uart_probe(struct sdio_func *func,

{

int ret;

port = kzalloc(sizeof(struct sdio_uart_port), GFP_KERNEL);

return -ENOMEM;

if (func->class == SDIO_CLASS_UART) {

sdio_func_id(func));

return -ENOSYS;

/*

* and SUBTPL_RCVCAPS.

for (tpl = func->tuples; tpl; tpl = tpl->next) {

continue;

continue;

break;

if (!tpl) {

"%s: can't find tuple 0x91 subtuple 0 (SUBTPL_SIOREG) for GPS class\n",

kfree(port);

}

sdio_func_id(func), tpl->data[2], tpl->data[3]);

(tpl->data[5] << 8) |

pr_debug("%s: regs offset = 0x%x\n",

port->uartclk = tpl->data[7] * 115200;

port->uartclk = 115200;

sdio_func_id(func), port->uartclk,

} else {

return -EINVAL;

sdio_set_drvdata(func, port);

port->port.ops = &sdio_uart_port_ops;

ret = sdio_uart_add_port(port);

kfree(port);

struct device *dev;

port->index, &func->dev);

sdio_uart_port_remove(port);

}

}

static void sdio_uart_remove(struct sdio_func *func)

struct sdio_uart_port *port = sdio_get_drvdata(func);

tty_unregister_device(sdio_uart_tty_driver, port->index);

}

static const struct sdio_device_id sdio_uart_ids[] = {

{ SDIO_DEVICE_CLASS(SDIO_CLASS_GPS)                },

};

MODULE_DEVICE_TABLE(sdio, sdio_uart_ids);

static struct sdio_driver sdio_uart_driver = {

.remove                = sdio_uart_remove,

.id_table        = sdio_uart_ids,

{

struct tty_driver *tty_drv;

sdio_uart_tty_driver = tty_drv = alloc_tty_driver(UART_NR);

return -ENOMEM;

tty_drv->driver_name = "sdio_uart";

tty_drv->major = 0;  /* dynamically allocated */

tty_drv->type = TTY_DRIVER_TYPE_SERIAL;

tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;

tty_drv->init_termios.c_cflag = B4800 | CS8 | CREAD | HUPCL | CLOCAL;

tty_drv->init_termios.c_ospeed = 4800;

if (ret)

if (ret)

tty_unregister_driver(tty_drv);

put_tty_driver(tty_drv);

}

static void __exit sdio_uart_exit(void)

sdio_unregister_driver(&sdio_uart_driver);

put_tty_driver(sdio_uart_tty_driver);

module_exit(sdio_uart_exit);

MODULE_AUTHOR("Nicolas Pitre");

MODULE_LICENSE("GPL");

699ba7046c51816a17b33a7caa85f179.png

0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值