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

📄 isdn_tty.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 5 页
字号:
	f->scantime = 0;	memset(&f->id[0], 32, FAXIDLEN - 1);	f->id[FAXIDLEN - 1] = 0;	f->badlin = 0;	f->badmul = 0;	f->bor = 0;	f->nbc = 0;	f->cq = 0;	f->cr = 0;	f->ctcrty = 0;	f->minsp = 0;	f->phcto = 30;	f->rel = 0;	memset(&f->pollid[0], 32, FAXIDLEN - 1);	f->pollid[FAXIDLEN - 1] = 0;}#endifstatic voidisdn_tty_modem_reset_regs(modem_info * info, int force){	atemu *m = &info->emu;	if ((m->mdmreg[REG_DTRR] & BIT_DTRR) || force) {		memcpy(m->mdmreg, m->profile, ISDN_MODEM_NUMREG);		memcpy(m->msn, m->pmsn, ISDN_MSNLEN);		memcpy(m->lmsn, m->plmsn, ISDN_LMSNLEN);		info->xmit_size = m->mdmreg[REG_PSIZE] * 16;	}#ifdef CONFIG_ISDN_AUDIO	isdn_tty_modem_reset_vpar(m);#endif#ifdef CONFIG_ISDN_TTY_FAX	isdn_tty_modem_reset_faxpar(info);#endif	m->mdmcmdl = 0;}static voidmodem_write_profile(atemu * m){	memcpy(m->profile, m->mdmreg, ISDN_MODEM_NUMREG);	memcpy(m->pmsn, m->msn, ISDN_MSNLEN);	memcpy(m->plmsn, m->lmsn, ISDN_LMSNLEN);	if (dev->profd)		send_sig(SIGIO, dev->profd, 1);}intisdn_tty_modem_init(void){	modem *m;	int i;	modem_info *info;	m = &dev->mdm;	memset(&m->tty_modem, 0, sizeof(struct tty_driver));	m->tty_modem.magic = TTY_DRIVER_MAGIC;	m->tty_modem.name = isdn_ttyname_ttyI;	m->tty_modem.major = ISDN_TTY_MAJOR;	m->tty_modem.minor_start = 0;	m->tty_modem.num = ISDN_MAX_CHANNELS;	m->tty_modem.type = TTY_DRIVER_TYPE_SERIAL;	m->tty_modem.subtype = ISDN_SERIAL_TYPE_NORMAL;	m->tty_modem.init_termios = tty_std_termios;	m->tty_modem.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;	m->tty_modem.flags = TTY_DRIVER_REAL_RAW;	m->tty_modem.refcount = &m->refcount;	m->tty_modem.table = m->modem_table;	m->tty_modem.termios = m->modem_termios;	m->tty_modem.termios_locked = m->modem_termios_locked;	m->tty_modem.open = isdn_tty_open;	m->tty_modem.close = isdn_tty_close;	m->tty_modem.write = isdn_tty_write;	m->tty_modem.put_char = NULL;	m->tty_modem.flush_chars = isdn_tty_flush_chars;	m->tty_modem.write_room = isdn_tty_write_room;	m->tty_modem.chars_in_buffer = isdn_tty_chars_in_buffer;	m->tty_modem.flush_buffer = isdn_tty_flush_buffer;	m->tty_modem.ioctl = isdn_tty_ioctl;	m->tty_modem.throttle = isdn_tty_throttle;	m->tty_modem.unthrottle = isdn_tty_unthrottle;	m->tty_modem.set_termios = isdn_tty_set_termios;	m->tty_modem.stop = NULL;	m->tty_modem.start = NULL;	m->tty_modem.hangup = isdn_tty_hangup;	m->tty_modem.driver_name = "isdn_tty";	/*	 * The callout device is just like normal device except for	 * major number and the subtype code.	 */	m->cua_modem = m->tty_modem;	m->cua_modem.name = isdn_ttyname_cui;	m->cua_modem.major = ISDN_TTYAUX_MAJOR;	m->tty_modem.minor_start = 0;	m->cua_modem.subtype = ISDN_SERIAL_TYPE_CALLOUT;	if (tty_register_driver(&m->tty_modem)) {		printk(KERN_WARNING "isdn_tty: Couldn't register modem-device\n");		return -1;	}	if (tty_register_driver(&m->cua_modem)) {		printk(KERN_WARNING "isdn_tty: Couldn't register modem-callout-device\n");		return -2;	}	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {		info = &m->info[i];#ifdef CONFIG_ISDN_TTY_FAX		if (!(info->fax = kmalloc(sizeof(T30_s), GFP_KERNEL))) {			printk(KERN_ERR "Could not allocate fax t30-buffer\n");			return -3;		}#endif		init_MUTEX(&info->write_sem);		sprintf(info->last_cause, "0000");		sprintf(info->last_num, "none");		info->last_dir = 0;		info->last_lhup = 1;		info->last_l2 = -1;		info->last_si = 0;		isdn_tty_reset_profile(&info->emu);		isdn_tty_modem_reset_regs(info, 1);		info->magic = ISDN_ASYNC_MAGIC;		info->line = i;		info->tty = 0;		info->x_char = 0;		info->count = 0;		info->blocked_open = 0;		info->callout_termios = m->cua_modem.init_termios;		info->normal_termios = m->tty_modem.init_termios;		init_waitqueue_head(&info->open_wait);		init_waitqueue_head(&info->close_wait);		info->isdn_driver = -1;		info->isdn_channel = -1;		info->drv_index = -1;		info->xmit_size = ISDN_SERIAL_XMIT_SIZE;		skb_queue_head_init(&info->xmit_queue);#ifdef CONFIG_ISDN_AUDIO		skb_queue_head_init(&info->dtmf_queue);#endif		if (!(info->xmit_buf = kmalloc(ISDN_SERIAL_XMIT_MAX + 5, GFP_KERNEL))) {			printk(KERN_ERR "Could not allocate modem xmit-buffer\n");			return -3;		}		/* Make room for T.70 header */		info->xmit_buf += 4;	}	return 0;}/* * isdn_tty_match_icall(char *MSN, atemu *tty_emulator, int dev_idx) *      match the MSN against the MSNs (glob patterns) defined for tty_emulator, *      and return 0 for match, 1 for no match, 2 if MSN could match if longer. */static intisdn_tty_match_icall(char *cid, atemu *emu, int di){#ifdef ISDN_DEBUG_MODEM_ICALL	printk(KERN_DEBUG "m_fi: msn=%s lmsn=%s mmsn=%s mreg[SI1]=%d mreg[SI2]=%d\n",	       emu->msn, emu->lmsn, isdn_map_eaz2msn(emu->msn, di),	       emu->mdmreg[REG_SI1], emu->mdmreg[REG_SI2]);#endif	if (strlen(emu->lmsn)) {		char *p = emu->lmsn;		char *q;		int  tmp;		int  ret = 0;		while (1) {			if ((q = strchr(p, ';')))				*q = '\0';			if ((tmp = isdn_msncmp(cid, isdn_map_eaz2msn(p, di))) > ret)				ret = tmp;#ifdef ISDN_DEBUG_MODEM_ICALL			printk(KERN_DEBUG "m_fi: lmsnX=%s mmsn=%s -> tmp=%d\n",			       p, isdn_map_eaz2msn(emu->msn, di), tmp);#endif			if (q) {				*q = ';';				p = q;				p++;			}			if (!tmp)				return 0;			if (!q)				break;		}		return ret;	} else {		int tmp;		tmp = isdn_msncmp(cid, isdn_map_eaz2msn(emu->msn, di));#ifdef ISDN_DEBUG_MODEM_ICALL			printk(KERN_DEBUG "m_fi: mmsn=%s -> tmp=%d\n",			       isdn_map_eaz2msn(emu->msn, di), tmp);#endif		return tmp;	}}/* * An incoming call-request has arrived. * Search the tty-devices for an appropriate device and bind * it to the ISDN-Channel. * Return: * *  0 = No matching device found. *  1 = A matching device found. *  3 = No match found, but eventually would match, if *      CID is longer. */intisdn_tty_find_icall(int di, int ch, setup_parm *setup){	char *eaz;	int i;	int wret;	int idx;	int si1;	int si2;	char *nr;	ulong flags;	if (!setup->phone[0]) {		nr = "0";		printk(KERN_INFO "isdn_tty: Incoming call without OAD, assuming '0'\n");	} else		nr = setup->phone;	si1 = (int) setup->si1;	si2 = (int) setup->si2;	if (!setup->eazmsn[0]) {		printk(KERN_WARNING "isdn_tty: Incoming call without CPN, assuming '0'\n");		eaz = "0";	} else		eaz = setup->eazmsn;#ifdef ISDN_DEBUG_MODEM_ICALL	printk(KERN_DEBUG "m_fi: eaz=%s si1=%d si2=%d\n", eaz, si1, si2);#endif	wret = 0;	save_flags(flags);	cli();	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {		modem_info *info = &dev->mdm.info[i];                if (info->count == 0)                    continue;		if ((info->emu.mdmreg[REG_SI1] & si2bit[si1]) &&  /* SI1 is matching */		    (info->emu.mdmreg[REG_SI2] == si2))	{         /* SI2 is matching */			idx = isdn_dc2minor(di, ch);#ifdef ISDN_DEBUG_MODEM_ICALL			printk(KERN_DEBUG "m_fi: match1 wret=%d\n", wret);			printk(KERN_DEBUG "m_fi: idx=%d flags=%08lx drv=%d ch=%d usg=%d\n", idx,			       info->flags, info->isdn_driver, info->isdn_channel,			       dev->usage[idx]);#endif			if (#ifndef FIX_FILE_TRANSFER				(info->flags & ISDN_ASYNC_NORMAL_ACTIVE) &&#endif				(info->isdn_driver == -1) &&				(info->isdn_channel == -1) &&				(USG_NONE(dev->usage[idx]))) {				int matchret;				if ((matchret = isdn_tty_match_icall(eaz, &info->emu, di)) > wret)					wret = matchret;				if (!matchret) {                  /* EAZ is matching */					info->isdn_driver = di;					info->isdn_channel = ch;					info->drv_index = idx;					dev->m_idx[idx] = info->line;					dev->usage[idx] &= ISDN_USAGE_EXCLUSIVE;					dev->usage[idx] |= isdn_calc_usage(si1, info->emu.mdmreg[REG_L2PROT]); 					strcpy(dev->num[idx], nr);					strcpy(info->emu.cpn, eaz);					info->emu.mdmreg[REG_SI1I] = si2bit[si1];					info->emu.mdmreg[REG_PLAN] = setup->plan;					info->emu.mdmreg[REG_SCREEN] = setup->screen;					isdn_info_update();					restore_flags(flags);					printk(KERN_INFO "isdn_tty: call from %s, -> RING on ttyI%d\n", nr,					       info->line);					info->msr |= UART_MSR_RI;					isdn_tty_modem_result(RESULT_RING, info);					isdn_timer_ctrl(ISDN_TIMER_MODEMRING, 1);					return 1;				}			}		}	}	restore_flags(flags);	printk(KERN_INFO "isdn_tty: call from %s -> %s %s\n", nr, eaz,	       ((dev->drv[di]->flags & DRV_FLAG_REJBUS) && (wret != 2))? "rejected" : "ignored");	return (wret == 2)?3:0;}#define TTY_IS_ACTIVE(info) \	(info->flags & (ISDN_ASYNC_NORMAL_ACTIVE | ISDN_ASYNC_CALLOUT_ACTIVE))intisdn_tty_stat_callback(int i, isdn_ctrl *c){	int mi;	modem_info *info;	char *e;	if (i < 0)		return 0;	if ((mi = dev->m_idx[i]) >= 0) {		info = &dev->mdm.info[mi];		switch (c->command) {                        case ISDN_STAT_CINF:                                printk(KERN_DEBUG "CHARGEINFO on ttyI%d: %ld %s\n", info->line, c->arg, c->parm.num);                                info->emu.charge = (unsigned) simple_strtoul(c->parm.num, &e, 10);                                if (e == (char *)c->parm.num)					info->emu.charge = 0;				                                break;						case ISDN_STAT_BSENT:#ifdef ISDN_TTY_STAT_DEBUG				printk(KERN_DEBUG "tty_STAT_BSENT ttyI%d\n", info->line);#endif				if ((info->isdn_driver == c->driver) &&				    (info->isdn_channel == c->arg)) {					info->msr |= UART_MSR_CTS;					if (info->send_outstanding)						if (!(--info->send_outstanding))							info->lsr |= UART_LSR_TEMT;					isdn_tty_tint(info);					return 1;				}				break;			case ISDN_STAT_CAUSE:#ifdef ISDN_TTY_STAT_DEBUG				printk(KERN_DEBUG "tty_STAT_CAUSE ttyI%d\n", info->line);#endif				/* Signal cause to tty-device */				strncpy(info->last_cause, c->parm.num, 5);				return 1;			case ISDN_STAT_DISPLAY:#ifdef ISDN_TTY_STAT_DEBUG				printk(KERN_DEBUG "tty_STAT_DISPLAY ttyI%d\n", info->line);#endif				/* Signal display to tty-device */				if ((info->emu.mdmreg[REG_DISPLAY] & BIT_DISPLAY) && 					!(info->emu.mdmreg[REG_RESPNUM] & BIT_RESPNUM)) {				  isdn_tty_at_cout("\r\n", info);				  isdn_tty_at_cout("DISPLAY: ", info);				  isdn_tty_at_cout(c->parm.display, info);				  isdn_tty_at_cout("\r\n", info);				}				return 1;			case ISDN_STAT_DCONN:#ifdef ISDN_TTY_STAT_DEBUG				printk(KERN_DEBUG "tty_STAT_DCONN ttyI%d\n", info->line);#endif				if (TTY_IS_ACTIVE(info)) {					if (info->dialing == 1) {						info->dialing = 2;						return 1;					}				}				break;			case ISDN_STAT_DHUP:#ifdef ISDN_TTY_STAT_DEBUG				printk(KERN_DEBUG "tty_STAT_DHUP ttyI%d\n", info->line);#endif				if (TTY_IS_ACTIVE(info)) {					if (info->dialing == 1) 						isdn_tty_modem_result(RESULT_BUSY, info);					if (info->dialing > 1) 						isdn_tty_modem_result(RESULT_NO_CARRIER, info);					info->dialing = 0;#ifdef ISDN_DEBUG_MODEM_HUP					printk(KERN_DEBUG "Mhup in ISDN_STAT_DHUP\n");#endif					isdn_tty_modem_hup(info, 0);					return 1;				}				break;			case ISDN_STAT_BCONN:#ifdef ISDN_TTY_STAT_DEBUG				printk(KERN_DEBUG "tty_STAT_BCONN ttyI%d\n", info->line);#endif				/* Wake up any processes waiting				 * for incoming call of this device when				 * DCD follow the state of incoming carrier				 */				if (info->blocked_open &&				   (info->emu.mdmreg[REG_DCD] & BIT_DCD)) {					wake_up_interruptible(&info->open_wait);				}				/* Schedule CONNECT-Message to any tty				 * waiting for it and				 * set DCD-bit of its modem-status.				 */				if (TTY_IS_ACTIVE(info) ||				    (info->blocked_open && (info->emu.mdmreg[REG_DCD] & BIT_DCD))) {					info->msr |= UART_MSR_DCD;					info->emu.charge = 0;					if (info->dialing & 0xf)						info->last_dir = 1;					else						info->last_dir = 0;					info->dialing = 0;					info->rcvsched = 1;					if (USG_MODEM(dev->usage[i])) {						if (info->emu.mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM) {							strcpy(info->emu.connmsg, c->parm.num);							isdn_tty_modem_result(RESULT_CONNECT, info);						} else							isdn_tty_modem_result(RESULT_CONNECT64000, info);					}					if (USG_VOICE(dev->usage[i]))						isdn_tty_modem_result(RESULT_VCON, info);					return 1;				}				break;			case ISDN_STAT_BHUP:#ifdef ISDN_TTY_STAT_DEBUG				printk(KERN_DEBUG "tty_STAT_BHUP ttyI%d\n", info->line);#endif				if (TTY_IS_ACTIVE(info)) {#ifdef ISDN_DEBUG_MODEM_HUP					printk(KERN_DEBUG "Mhup in ISDN_STAT_BHUP\n");#endif					isdn_tty_modem_hup(info, 0);					return 1;				}				break;			case ISDN_STAT_NODCH:#ifdef ISDN_TTY_STAT_DEBUG				printk(KERN_DEBUG "tty_STAT_NODCH ttyI%d\n", info->line);#endif				if (TTY_IS_ACTIVE(info)) {					if (info->dialing) {						info->dialing = 0;						info->last_l2 = -1;						info->last_si = 0;						sprintf(info->last_cause, "0000");						isdn_tty_modem_result(RESULT_NO_DIALTONE, info);					}					isdn_tty_modem_hup(info, 0);					return 1;				}				break;			case ISDN_STAT_UNLOAD:#ifdef ISDN_TTY_STAT_DEBUG				printk(KERN_DEBUG "tty_STAT_UNLOAD ttyI%d\n", info->line);#endif				for (i = 0; i < ISDN_MAX_CHANNELS; i++) {					info = &dev->mdm.info[i];					if (info->isdn_driver == c->driver) {						if (info->online)							isdn_tty_modem_hup(info, 1);					}				}				return 1;#ifdef CONFIG_ISDN_TTY_FAX			case ISDN_STAT_FAXIND:				if (TTY_IS_ACTIVE(info)) {					isdn_tty_fax_command(info, c); 				}				break;#endif#ifdef CONFIG_ISDN_AUDIO			case ISDN_STAT_AUDIO:				if (TTY_IS_ACTIVE(info)) {					switch(c->parm.num[0]) {						case ISDN_AUDIO_DTMF:							if (info->vonline) {								isdn_audio_put_dle_code(info,									c->parm.num[1]);							}							break;					}				}				break;#endif		}	}	return 0;}/********************************************************************* Modem-Emulator-Routines *********************************************************************/#define cmdchar(c) ((c>=' ')&&(c<=0x7f))/* * Put a message from the AT-emulator into receive-buffer of tty, * convert CR, LF, and BS to values 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -