📄 serial_cnxt.c
字号:
inst->mctrl_flags &= ~TIOCM_RTS; cnxt_control(inst, COMCTRL_CONTROL_CLRRTS, 0); } if ((mctrl & TIOCM_DTR) && !(inst->mctrl_flags & TIOCM_DTR)) { inst->mctrl_flags |= TIOCM_DTR; cnxt_control(inst, COMCTRL_CONTROL_SETDTR, 0); } if (!(mctrl & TIOCM_DTR) && (inst->mctrl_flags & TIOCM_DTR)) { inst->mctrl_flags &= ~TIOCM_DTR; cnxt_control(inst, COMCTRL_CONTROL_CLRDTR, 0); }}static voidcnxt_break_ctl(struct uart_port *port, int break_state){ struct cnxt_serial_inst *inst = &cnxt_serial_inst[port - cnxt_ports]; //printk(KERN_DEBUG "%s: break_state=%d\n", __FUNCTION__, break_state); cnxt_control(inst, break_state ? COMCTRL_CONTROL_SET_BREAK_ON : COMCTRL_CONTROL_SET_BREAK_OFF, 0);}__shimcall__static voidcnxt_event_handler(struct cnxt_serial_inst *inst, UINT32 dwEvtMask){ struct uart_port *port = inst->port; u_int mctrl_flags, orig_mctrl_flags; int sched_intr=0; //printk(KERN_DEBUG "%s: port=%p dwEvtMask=0x%04lx\n", __FUNCTION__, port, dwEvtMask); orig_mctrl_flags = mctrl_flags = inst->mctrl_flags; if((dwEvtMask & COMCTRL_EVT_RXCHAR)) { inst->evt_rxchar = 1; sched_intr = 1; } if(dwEvtMask & COMCTRL_EVT_BREAK) { inst->evt_rxbreak = 1; sched_intr = 1; } if((dwEvtMask & COMCTRL_EVT_RXOVRN)) { inst->evt_rxovrn = 1; sched_intr = 1; }#if 0 if((dwEvtMask & COMCTRL_EVT_TXCHAR)) { }#endif if((dwEvtMask & COMCTRL_EVT_TXEMPTY)) { inst->evt_txempty = 1; sched_intr = 1; } if((dwEvtMask & COMCTRL_EVT_CTS)) { if(dwEvtMask & COMCTRL_EVT_CTSS) { mctrl_flags |= TIOCM_CTS; } else { mctrl_flags &= ~TIOCM_CTS; } } if(dwEvtMask & COMCTRL_EVT_DSR) { if(dwEvtMask & COMCTRL_EVT_DSRS) { mctrl_flags |= TIOCM_DSR; } else { mctrl_flags &= ~TIOCM_DSR; } if(port) port->icount.dsr++; } if(dwEvtMask & COMCTRL_EVT_RLSD) { if(dwEvtMask & COMCTRL_EVT_RLSDS) { mctrl_flags |= TIOCM_CAR; } else { mctrl_flags &= ~TIOCM_CAR; } } if(dwEvtMask & COMCTRL_EVT_RING) { if(dwEvtMask & COMCTRL_EVT_RINGS) { mctrl_flags |= TIOCM_RNG; if(port) port->icount.rng++; } else { mctrl_flags &= ~TIOCM_RNG; } } if(inst->mctrl_flags != mctrl_flags) { inst->mctrl_flags = mctrl_flags;#if 0 printk(KERN_DEBUG "%cCTS %cDSR %cDCD %cRI\n", inst->mctrl_flags&TIOCM_CTS?'+':'-', inst->mctrl_flags&TIOCM_DSR?'+':'-', inst->mctrl_flags&TIOCM_CAR?'+':'-', inst->mctrl_flags&TIOCM_RNG?'+':'-');#endif if(port && inst->uart_info) { if((mctrl_flags & TIOCM_CAR) != (orig_mctrl_flags & TIOCM_CAR)) { uart_handle_dcd_change(#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) inst->uart_info,#else inst->uart_port,#endif mctrl_flags & TIOCM_CAR);#ifdef COMCTRL_MONITOR_POUND_UG_SUPPORT if(loglastcallstatus && !(mctrl_flags & TIOCM_CAR)) { PORT_MONITOR_DATA monitorData; static char largebuf[PAGE_SIZE]; char *p, *nl; monitorData.dwSize = sizeof(largebuf); monitorData.pBuf = largebuf; cnxt_monitor(inst, COMCTRL_MONITOR_POUND_UG, &monitorData); p = largebuf; while((nl = strchr(p, '\n'))) { printk(KERN_INFO "%.*s", (int)(nl - p) + 1, p); p = nl + 1; } if(*p) printk(KERN_INFO "%s\n", p); }#endif } if((mctrl_flags & TIOCM_CTS) != (orig_mctrl_flags & TIOCM_CTS)) uart_handle_cts_change(#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) inst->uart_info,#else inst->uart_port,#endif mctrl_flags & TIOCM_CTS); wake_up_interruptible(&inst->uart_info->delta_msr_wait); } } if(port && sched_intr) { cnxt_sched_intr(inst); } return;}static intcnxt_startup(struct uart_port *port#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) , struct uart_info *info#endif ){ struct cnxt_serial_inst *inst = &cnxt_serial_inst[port - cnxt_ports]; if(!inst->hcomctrl) return -ENODEV; if(inst->uart_info) return -EBUSY;#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) if (!try_inc_mod_count(inst->owner)) return -ENODEV;#else if (!try_module_get(inst->owner)) return -ENODEV;#endif /* flush any characters or events received while we were shutdown */ while(ComCtrl_Read(inst->hcomctrl, inst->readbuf, sizeof(inst->readbuf)) > 0); inst->readcount = inst->readoffset = 0; inst->evt_rxchar = 0; inst->evt_rxbreak = 0; inst->evt_rxovrn = 0; inst->uart_port = port;#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) inst->uart_info = info;#else inst->uart_info = port->info;#endif inst->rxenabled = 1; inst->txenabled = 1; return 0;}static voidcnxt_shutdown(struct uart_port *port#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) , struct uart_info *info#endif ){ struct cnxt_serial_inst *inst = &cnxt_serial_inst[port - cnxt_ports]; //printk(KERN_DEBUG "%s\n", __FUNCTION__); inst->rxenabled = 0; inst->txenabled = 0; inst->uart_info = NULL; inst->uart_port = NULL; if (inst->owner) {#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) __MOD_DEC_USE_COUNT(inst->owner);#else module_put(inst->owner);#endif }}#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)static voidcnxt_change_speed(struct uart_port *port, u_int cflag, u_int iflag, u_int quot){ struct cnxt_serial_inst *inst = &cnxt_serial_inst[port - cnxt_ports]; PORT_CONFIG port_config; //printk(KERN_DEBUG "%s\n", __FUNCTION__); memset(&port_config, 0, sizeof(port_config)); if(quot) { port_config.dwDteSpeed = port->uartclk / (16 * quot); port_config.dwValidFileds |= PC_DTE_SPEED; } if(cflag & PARENB) { if(cflag & PARODD) port_config.eParity = PC_PARITY_ODD; else port_config.eParity = PC_PARITY_EVEN; } else port_config.eParity = PC_PARITY_NONE; port_config.dwValidFileds |= PC_PARITY; if((cflag & CSIZE) == CS7) { port_config.eDataBits = PC_DATABITS_7; } else { port_config.eDataBits = PC_DATABITS_8; } port_config.dwValidFileds |= PC_DATA_BITS; if (cflag & CRTSCTS) { port_config.fCTS = TRUE; port_config.fRTS = TRUE; } port_config.dwValidFileds |= PC_CTS | PC_RTS; cnxt_control(inst, COMCTRL_CONTROL_PORTCONFIG, &port_config);}#elsestatic voidcnxt_set_termios(struct uart_port *port, struct termios *termios, struct termios *old){ struct cnxt_serial_inst *inst = &cnxt_serial_inst[port - cnxt_ports]; PORT_CONFIG port_config; //printk(KERN_DEBUG "%s\n", __FUNCTION__); memset(&port_config, 0, sizeof(port_config)); port_config.dwDteSpeed = uart_get_baud_rate(port, termios, old, 75, 4000000); port_config.dwValidFileds |= PC_DTE_SPEED; if(termios->c_cflag & PARENB) { if(termios->c_cflag & PARODD) port_config.eParity = PC_PARITY_ODD; else port_config.eParity = PC_PARITY_EVEN; } else port_config.eParity = PC_PARITY_NONE; port_config.dwValidFileds |= PC_PARITY; if((termios->c_cflag & CSIZE) == CS7) { port_config.eDataBits = PC_DATABITS_7; } else { port_config.eDataBits = PC_DATABITS_8; } port_config.dwValidFileds |= PC_DATA_BITS; if (termios->c_cflag & CRTSCTS) { port_config.fCTS = TRUE; port_config.fRTS = TRUE; } port_config.dwValidFileds |= PC_CTS | PC_RTS; cnxt_control(inst, COMCTRL_CONTROL_PORTCONFIG, &port_config);#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) uart_update_timeout(port, termios->c_cflag, port_config.dwDteSpeed);#endif}#endifstatic voidcnxt_enable_ms(struct uart_port *port){}static voidcnxt_release_port(struct uart_port *port){ struct cnxt_serial_inst *inst = &cnxt_serial_inst[port - cnxt_ports]; //printk(KERN_DEBUG "%s\n", __FUNCTION__); if(inst->port != port) { printk(KERN_ERR"%s: inst->port(%p) != port(%p), i=%d cnxt_ports=%p\n", __FUNCTION__, inst->port, port, (int)(port - cnxt_ports), cnxt_ports); } inst->port = NULL;}static intcnxt_request_port(struct uart_port *port){ struct cnxt_serial_inst *inst = &cnxt_serial_inst[port - cnxt_ports]; //printk(KERN_DEBUG "%s\n", __FUNCTION__); if(!inst->port) inst->port = port; else { if(inst->port != port) { printk(KERN_ERR"%s: inst->port(%p) != port(%p), i=%d cnxt_ports=%p\n", __FUNCTION__, inst->port, port, (int)(port - cnxt_ports), cnxt_ports); } } return 0;}#ifndef PORT_CNXT#define PORT_CNXT 36#endifstatic voidcnxt_config_port(struct uart_port *port, int flags){ //printk(KERN_DEBUG "%s\n", __FUNCTION__); if (flags & UART_CONFIG_TYPE && cnxt_request_port(port) == 0) { port->type = PORT_CNXT; }}/* * Verify the new serial_struct (for TIOCSSERIAL). * The only change we allow are to the flags */static intcnxt_verify_port(struct uart_port *port, struct serial_struct *ser){ int ret = 0; if (ser->type != PORT_CNXT) ret = -EINVAL; if (port->irq != ser->irq) ret = -EINVAL; /*if (ser->io_type != SERIAL_IO_MEM) ret = -EINVAL;*/ if (port->uartclk / 16 != ser->baud_base) ret = -EINVAL; /*if ((void *)port->mapbase != ser->iomem_base) ret = -EINVAL;*/ if (port->iobase != ser->port) ret = -EINVAL; if (ser->hub6 != 0) ret = -EINVAL; return ret;}static const char *cnxt_type(struct uart_port *port){ return cnxt_serial_inst[port->line].typestr ? cnxt_serial_inst[port->line].typestr : CNXTDRVDSC;}static struct uart_ops cnxt_pops = { .tx_empty = cnxt_tx_empty, .set_mctrl = cnxt_set_mctrl, .get_mctrl = cnxt_get_mctrl, .stop_tx = cnxt_stop_tx, .start_tx = cnxt_start_tx, .stop_rx = cnxt_stop_rx, .enable_ms = cnxt_enable_ms, .break_ctl = cnxt_break_ctl, .startup = cnxt_startup, .shutdown = cnxt_shutdown, .type = cnxt_type,#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) .change_speed = cnxt_change_speed,#else .set_termios = cnxt_set_termios,#endif .release_port = cnxt_release_port, .request_port = cnxt_request_port, .config_port = cnxt_config_port, .verify_port = cnxt_verify_port,};static int serialmajor = CNXTSERIALMAJOR;#ifdef FOUND_MODULE_PARAMmodule_param(serialmajor, int, 0);#elseMODULE_PARM(serialmajor, "i");#endifMODULE_PARM_DESC(serialmajor, "Major device number for serial device");#ifdef CNXTCALOUTMAJORstatic int calloutmajor = CNXTCALOUTMAJOR;#ifdef FOUND_MODULE_PARAMmodule_param(calloutmajor, int, 0);#elseMODULE_PARM(calloutmajor, "i");#endif#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)MODULE_PARM_DESC(calloutmajor, "Major device number for callout device");#elseMODULE_PARM_DESC(calloutmajor, "Major device number for callout device (ignored/deprecated)");#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) */#endif#ifdef COMCTRL_MONITOR_POUND_UG_SUPPORT#ifdef FOUND_MODULE_PARAMmodule_param(loglastcallstatus, int, 0);#elseMODULE_PARM(loglastcallstatus, "i");#endifMODULE_PARM_DESC(loglastcallstatus, "Log AT#UG command output after each connection");#endifstatic struct uart_driver cnxt_reg = { .owner = THIS_MODULE,#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)#ifdef CONFIG_DEVFS_FS .normal_name = "ttyS"CNXTSERDEV"%d", .callout_name = "cua"CNXTSERDEV"%d",#else .normal_name = "ttyS"CNXTSERDEV, .callout_name = "cua"CNXTSERDEV,#endif .normal_driver = &cnxt_tty_driver_normal, .callout_driver = &cnxt_tty_driver_callout, .table = cnxt_tty_table, .termios = cnxt_termios, .termios_locked = cnxt_termios_locked, .port = cnxt_ports,#else .driver_name = CNXTTARGET"serial", .devfs_name = "ttyS"CNXTSERDEV, .dev_name = "ttyS"CNXTSERDEV,#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) */ .minor = CNXTSERIALMINOR, .nr = NR_PORTS,};#ifndef CNXTSERIAL_INCLUDE_CORE#define uart_init() 0#define uart_exit() {}#endif#ifdef CONFIG_PROC_FS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -