⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serial_cnxt.c

📁 一个Linux下的软猫驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
	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 + -