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

📄 synclink.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
		if ( UscVector )			(*UscIsrTable[UscVector])(info);		else if ( (DmaVector&(BIT10|BIT9)) == BIT10)			mgsl_isr_transmit_dma(info);		else			mgsl_isr_receive_dma(info);		if ( info->isr_overflow ) {			printk(KERN_ERR"%s(%d):%s isr overflow irq=%d\n",				__FILE__,__LINE__,info->device_name, irq);			usc_DisableMasterIrqBit(info);			usc_DisableDmaInterrupts(info,DICR_MASTER);			break;		}	}		/* Request bottom half processing if there's something 	 * for it to do and the bh is not already running	 */	if ( info->pending_bh && !info->bh_running && !info->bh_requested ) {		if ( debug_level >= DEBUG_LEVEL_ISR )				printk("%s(%d):%s queueing bh task.\n",				__FILE__,__LINE__,info->device_name);		queue_task(&info->task, &tq_immediate);		mark_bh(IMMEDIATE_BH);		info->bh_requested = 1;	}	spin_unlock(&info->irq_spinlock);		if ( debug_level >= DEBUG_LEVEL_ISR )			printk("%s(%d):mgsl_interrupt(%d)exit.\n",			__FILE__,__LINE__,irq);}	/* end of mgsl_interrupt() *//* startup() *  * 	Initialize and start device. * 	 * Arguments:		info	pointer to device instance data * Return Value:	0 if success, otherwise error code */static int startup(struct mgsl_struct * info){	int retval = 0;		if ( debug_level >= DEBUG_LEVEL_INFO )		printk("%s(%d):mgsl_startup(%s)\n",__FILE__,__LINE__,info->device_name);			if (info->flags & ASYNC_INITIALIZED)		return 0;		if (!info->xmit_buf) {		/* allocate a page of memory for a transmit buffer */		info->xmit_buf = (unsigned char *)get_free_page(GFP_KERNEL);		if (!info->xmit_buf) {			printk(KERN_ERR"%s(%d):%s can't allocate transmit buffer\n",				__FILE__,__LINE__,info->device_name);			return -ENOMEM;		}	}	info->pending_bh = 0;		init_timer(&info->tx_timer);	info->tx_timer.data = (unsigned long)info;	info->tx_timer.function = mgsl_tx_timeout;		/* Allocate and claim adapter resources */	retval = mgsl_claim_resources(info);		/* perform existance check and diagnostics */	if ( !retval )		retval = mgsl_adapter_test(info);			if ( retval ) {  		if (capable(CAP_SYS_ADMIN) && info->tty)			set_bit(TTY_IO_ERROR, &info->tty->flags);		mgsl_release_resources(info);  		return retval;  	}	/* program hardware for current parameters */	mgsl_change_params(info);		if (info->tty)		clear_bit(TTY_IO_ERROR, &info->tty->flags);	info->flags |= ASYNC_INITIALIZED;		return 0;	}	/* end of startup() *//* shutdown() * * Called by mgsl_close() and mgsl_hangup() to shutdown hardware * * Arguments:		info	pointer to device instance data * Return Value:	None */static void shutdown(struct mgsl_struct * info){	unsigned long flags;		if (!(info->flags & ASYNC_INITIALIZED))		return;	if (debug_level >= DEBUG_LEVEL_INFO)		printk("%s(%d):mgsl_shutdown(%s)\n",			 __FILE__,__LINE__, info->device_name );	/* clear status wait queue because status changes */	/* can't happen after shutting down the hardware */	wake_up_interruptible(&info->status_event_wait_q);	wake_up_interruptible(&info->event_wait_q);	del_timer(&info->tx_timer);		if (info->xmit_buf) {		free_page((unsigned long) info->xmit_buf);		info->xmit_buf = 0;	}	spin_lock_irqsave(&info->irq_spinlock,flags);	usc_DisableMasterIrqBit(info);	usc_stop_receiver(info);	usc_stop_transmitter(info);	usc_DisableInterrupts(info,RECEIVE_DATA + RECEIVE_STATUS +		TRANSMIT_DATA + TRANSMIT_STATUS + IO_PIN + MISC );	usc_DisableDmaInterrupts(info,DICR_MASTER + DICR_TRANSMIT + DICR_RECEIVE);		/* Disable DMAEN (Port 7, Bit 14) */	/* This disconnects the DMA request signal from the ISA bus */	/* on the ISA adapter. This has no effect for the PCI adapter */	usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT15) | BIT14));		/* Disable INTEN (Port 6, Bit12) */	/* This disconnects the IRQ request signal to the ISA bus */	/* on the ISA adapter. This has no effect for the PCI adapter */	usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) | BIT12));	 	if (!info->tty || info->tty->termios->c_cflag & HUPCL) { 		info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS);		usc_set_serial_signals(info);	}		spin_unlock_irqrestore(&info->irq_spinlock,flags);	mgsl_release_resources(info);			if (info->tty)		set_bit(TTY_IO_ERROR, &info->tty->flags);	info->flags &= ~ASYNC_INITIALIZED;	}	/* end of shutdown() */static void mgsl_program_hw(struct mgsl_struct *info){	unsigned long flags;	spin_lock_irqsave(&info->irq_spinlock,flags);		usc_stop_receiver(info);	usc_stop_transmitter(info);	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;		if (info->params.mode == MGSL_MODE_HDLC ||	    info->params.mode == MGSL_MODE_RAW ||	    info->netcount)		usc_set_sync_mode(info);	else		usc_set_async_mode(info);			usc_set_serial_signals(info);		info->dcd_chkcount = 0;	info->cts_chkcount = 0;	info->ri_chkcount = 0;	info->dsr_chkcount = 0;	usc_EnableStatusIrqs(info,SICR_CTS+SICR_DSR+SICR_DCD+SICR_RI);			usc_EnableInterrupts(info, IO_PIN);	usc_get_serial_signals(info);			if (info->netcount || info->tty->termios->c_cflag & CREAD)		usc_start_receiver(info);			spin_unlock_irqrestore(&info->irq_spinlock,flags);}/* Reconfigure adapter based on new parameters */static void mgsl_change_params(struct mgsl_struct *info){	unsigned cflag;	int bits_per_char;	if (!info->tty || !info->tty->termios)		return;			if (debug_level >= DEBUG_LEVEL_INFO)		printk("%s(%d):mgsl_change_params(%s)\n",			 __FILE__,__LINE__, info->device_name );			 	cflag = info->tty->termios->c_cflag;	/* if B0 rate (hangup) specified then negate DTR and RTS */	/* otherwise assert DTR and RTS */ 	if (cflag & CBAUD)		info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR;	else		info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR);		/* byte size and parity */		switch (cflag & CSIZE) {	      case CS5: info->params.data_bits = 5; break;	      case CS6: info->params.data_bits = 6; break;	      case CS7: info->params.data_bits = 7; break;	      case CS8: info->params.data_bits = 8; break;	      /* Never happens, but GCC is too dumb to figure it out */	      default:  info->params.data_bits = 7; break;	      }	      	if (cflag & CSTOPB)		info->params.stop_bits = 2;	else		info->params.stop_bits = 1;	info->params.parity = ASYNC_PARITY_NONE;	if (cflag & PARENB) {		if (cflag & PARODD)			info->params.parity = ASYNC_PARITY_ODD;		else			info->params.parity = ASYNC_PARITY_EVEN;#ifdef CMSPAR		if (cflag & CMSPAR)			info->params.parity = ASYNC_PARITY_SPACE;#endif	}	/* calculate number of jiffies to transmit a full	 * FIFO (32 bytes) at specified data rate	 */	bits_per_char = info->params.data_bits + 			info->params.stop_bits + 1;	/* if port data rate is set to 460800 or less then	 * allow tty settings to override, otherwise keep the	 * current data rate.	 */	if (info->params.data_rate <= 460800)		info->params.data_rate = tty_get_baud_rate(info->tty);		if ( info->params.data_rate ) {		info->timeout = (32*HZ*bits_per_char) / 				info->params.data_rate;	}	info->timeout += HZ/50;		/* Add .02 seconds of slop */	if (cflag & CRTSCTS)		info->flags |= ASYNC_CTS_FLOW;	else		info->flags &= ~ASYNC_CTS_FLOW;			if (cflag & CLOCAL)		info->flags &= ~ASYNC_CHECK_CD;	else		info->flags |= ASYNC_CHECK_CD;	/* process tty input control flags */		info->read_status_mask = RXSTATUS_OVERRUN;	if (I_INPCK(info->tty))		info->read_status_mask |= RXSTATUS_PARITY_ERROR | RXSTATUS_FRAMING_ERROR; 	if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) 		info->read_status_mask |= RXSTATUS_BREAK_RECEIVED;		if (I_IGNPAR(info->tty))		info->ignore_status_mask |= RXSTATUS_PARITY_ERROR | RXSTATUS_FRAMING_ERROR;	if (I_IGNBRK(info->tty)) {		info->ignore_status_mask |= RXSTATUS_BREAK_RECEIVED;		/* If ignoring parity and break indicators, ignore 		 * overruns too.  (For real raw support).		 */		if (I_IGNPAR(info->tty))			info->ignore_status_mask |= RXSTATUS_OVERRUN;	}	mgsl_program_hw(info);}	/* end of mgsl_change_params() *//* mgsl_put_char() *  * 	Add a character to the transmit buffer. * 	 * Arguments:		tty	pointer to tty information structure * 			ch	character to add to transmit buffer * 		 * Return Value:	None */static void mgsl_put_char(struct tty_struct *tty, unsigned char ch){	struct mgsl_struct *info = (struct mgsl_struct *)tty->driver_data;	unsigned long flags;	if ( debug_level >= DEBUG_LEVEL_INFO ) {		printk( "%s(%d):mgsl_put_char(%d) on %s\n",			__FILE__,__LINE__,ch,info->device_name);	}				if (mgsl_paranoia_check(info, tty->device, "mgsl_put_char"))		return;	if (!tty || !info->xmit_buf)		return;	spin_lock_irqsave(&info->irq_spinlock,flags);		if ( (info->params.mode == MGSL_MODE_ASYNC ) || !info->tx_active ) {			if (info->xmit_cnt < SERIAL_XMIT_SIZE - 1) {			info->xmit_buf[info->xmit_head++] = ch;			info->xmit_head &= SERIAL_XMIT_SIZE-1;			info->xmit_cnt++;		}	}		spin_unlock_irqrestore(&info->irq_spinlock,flags);	}	/* end of mgsl_put_char() *//* mgsl_flush_chars() *  * 	Enable transmitter so remaining characters in the * 	transmit buffer are sent. * 	 * Arguments:		tty	pointer to tty information structure * Return Value:	None */static void mgsl_flush_chars(struct tty_struct *tty){	struct mgsl_struct *info = (struct mgsl_struct *)tty->driver_data;	unsigned long flags;					if ( debug_level >= DEBUG_LEVEL_INFO )		printk( "%s(%d):mgsl_flush_chars() entry on %s xmit_cnt=%d\n",			__FILE__,__LINE__,info->device_name,info->xmit_cnt);		if (mgsl_paranoia_check(info, tty->device, "mgsl_flush_chars"))		return;	if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||	    !info->xmit_buf)		return;	if ( debug_level >= DEBUG_LEVEL_INFO )		printk( "%s(%d):mgsl_flush_chars() entry on %s starting transmitter\n",			__FILE__,__LINE__,info->device_name );	spin_lock_irqsave(&info->irq_spinlock,flags);		if (!info->tx_active) {		if ( (info->params.mode == MGSL_MODE_HDLC ||			info->params.mode == MGSL_MODE_RAW) && info->xmit_cnt ) {			/* operating in synchronous (frame oriented) mode */			/* copy data from circular xmit_buf to */			/* transmit DMA buffer. */			mgsl_load_tx_dma_buffer(info,				 info->xmit_buf,info->xmit_cnt);		}	 	usc_start_transmitter(info);	}		spin_unlock_irqrestore(&info->irq_spinlock,flags);	}	/* end of mgsl_flush_chars() *//* mgsl_write() *  * 	Send a block of data * 	 * Arguments: *  * 	tty		pointer to tty information structure * 	from_user	flag: 1 = from user process * 	buf		pointer to buffer containing send data * 	count		size of send data in bytes * 	 * Return Value:	number of characters written */static int mgsl_write(struct tty_struct * tty, int from_user,		    const unsigned char *buf, int count){	int	c, ret = 0, err;	struct mgsl_struct *info = (struct mgsl_struct *)tty->driver_data;	unsigned long flags;		if ( debug_level >= DEBUG_LEVEL_INFO )		printk( "%s(%d):mgsl_write(%s) count=%d\n",			__FILE__,__LINE__,info->device_name,count);		if (mgsl_paranoia_check(info, tty->device, "mgsl_write"))		goto cleanup;	if (!tty || !info->xmit_buf || !tmp_buf)		goto cleanup;	if ( info->params.mode == MGSL_MODE_HDLC ||			info->params.mode == MGSL_MODE_RAW ) {		/* operating in synchronous (frame oriented) mode */		/* operating in synchronous (frame oriented) mode */		if (info->tx_active) {			if ( info->params.mode == MGSL_MODE_HDLC ) {				ret = 0;				goto cleanup;			}			/* transmitter is actively sending data -			 * if we have multiple transmit dma and			 * holding buffers, attempt to queue this			 * frame for transmission at a later time.			 */			if (info->tx_holding_count >= info->num_tx_holding_buffers ) {				/* no tx holding buffers available */				ret = 0

⌨️ 快捷键说明

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