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

📄 io_ti.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 5 页
字号:
{	int port_number = port->port->number - port->port->serial->minor;	dbg ("%s", __FUNCTION__);	return TIWriteCommandSync (port->port->serial->dev,				UMPC_SET_CLR_LOOPBACK,				(__u8)(UMPM_UART1_PORT + port_number),				0,	/* clear */				NULL,				0);}static int TISetBreak (struct edgeport_port *port){	int port_number = port->port->number - port->port->serial->minor;	dbg ("%s", __FUNCTION__);	return TIWriteCommandSync (port->port->serial->dev,				UMPC_SET_CLR_BREAK,				(__u8)(UMPM_UART1_PORT + port_number),				1,	/* set */				NULL,				0);}static int TIClearBreak (struct edgeport_port *port){	int port_number = port->port->number - port->port->serial->minor;	dbg ("%s", __FUNCTION__);	return TIWriteCommandSync (port->port->serial->dev,				UMPC_SET_CLR_BREAK,				(__u8)(UMPM_UART1_PORT + port_number),				0,	/* clear */				NULL,				0);}static int TIRestoreMCR (struct edgeport_port *port, __u8 mcr){	int status = 0;	dbg ("%s - %x", __FUNCTION__, mcr);	if (mcr & MCR_DTR)		status = TISetDtr (port);	else		status = TIClearDtr (port);	if (status)		return status;	if (mcr & MCR_RTS)		status = TISetRts (port);	else		status = TIClearRts (port);	if (status)		return status;	if (mcr & MCR_LOOPBACK)		status = TISetLoopBack (port);	else		status = TIClearLoopBack (port);	return status;}/* Convert TI LSR to standard UART flags */static __u8 MapLineStatus (__u8 ti_lsr){	__u8 lsr = 0;#define MAP_FLAG(flagUmp, flagUart)    \	if (ti_lsr & flagUmp) lsr |= flagUart;	MAP_FLAG(UMP_UART_LSR_OV_MASK, LSR_OVER_ERR)	/* overrun */	MAP_FLAG(UMP_UART_LSR_PE_MASK, LSR_PAR_ERR)	/* parity error */	MAP_FLAG(UMP_UART_LSR_FE_MASK, LSR_FRM_ERR)	/* framing error */	MAP_FLAG(UMP_UART_LSR_BR_MASK, LSR_BREAK)	/* break detected */	MAP_FLAG(UMP_UART_LSR_RX_MASK, LSR_RX_AVAIL)	/* receive data available */	MAP_FLAG(UMP_UART_LSR_TX_MASK, LSR_TX_EMPTY)	/* transmit holding register empty */#undef MAP_FLAG	return lsr;}static void handle_new_msr (struct edgeport_port *edge_port, __u8 msr){	struct async_icount *icount;	dbg ("%s - %02x", __FUNCTION__, msr);	if (msr & (EDGEPORT_MSR_DELTA_CTS | EDGEPORT_MSR_DELTA_DSR | EDGEPORT_MSR_DELTA_RI | EDGEPORT_MSR_DELTA_CD)) {		icount = &edge_port->icount;		/* update input line counters */		if (msr & EDGEPORT_MSR_DELTA_CTS)			icount->cts++;		if (msr & EDGEPORT_MSR_DELTA_DSR)			icount->dsr++;		if (msr & EDGEPORT_MSR_DELTA_CD)			icount->dcd++;		if (msr & EDGEPORT_MSR_DELTA_RI)			icount->rng++;		wake_up_interruptible (&edge_port->delta_msr_wait);	}	/* Save the new modem status */	edge_port->shadow_msr = msr & 0xf0;	return;}static void handle_new_lsr (struct edgeport_port *edge_port, int lsr_data, __u8 lsr, __u8 data){	struct async_icount *icount;	__u8 new_lsr = (__u8)(lsr & (__u8)(LSR_OVER_ERR | LSR_PAR_ERR | LSR_FRM_ERR | LSR_BREAK));	dbg ("%s - %02x", __FUNCTION__, new_lsr);	edge_port->shadow_lsr = lsr;	if (new_lsr & LSR_BREAK) {		/*		 * Parity and Framing errors only count if they		 * occur exclusive of a break being received.		 */		new_lsr &= (__u8)(LSR_OVER_ERR | LSR_BREAK);	}	/* Place LSR data byte into Rx buffer */	if (lsr_data && edge_port->port->tty) {		tty_insert_flip_char(edge_port->port->tty, data, 0);		tty_flip_buffer_push(edge_port->port->tty);	}	/* update input line counters */	icount = &edge_port->icount;	if (new_lsr & LSR_BREAK)		icount->brk++;	if (new_lsr & LSR_OVER_ERR)		icount->overrun++;	if (new_lsr & LSR_PAR_ERR)		icount->parity++;	if (new_lsr & LSR_FRM_ERR)		icount->frame++;}static void edge_interrupt_callback (struct urb *urb){	struct edgeport_serial	*edge_serial = (struct edgeport_serial *)urb->context;	struct usb_serial_port *port;	struct edgeport_port *edge_port;	unsigned char *data = urb->transfer_buffer;	int length = urb->actual_length;	int port_number;	int function;	__u8 lsr;	__u8 msr;	dbg("%s", __FUNCTION__);	if (serial_paranoia_check (edge_serial->serial, __FUNCTION__)) {		return;	}	if (urb->status) {		dbg("%s - nonzero control read status received: %d", __FUNCTION__, urb->status);		return;	}	if (!length) {		dbg ("%s - no data in urb", __FUNCTION__);		return;	}			usb_serial_debug_data (__FILE__, __FUNCTION__, length, data);			if (length != 2) {		dbg ("%s - expecting packet of size 2, got %d", __FUNCTION__, length);		return;	}	port_number = TIUMP_GET_PORT_FROM_CODE (data[0]);	function    = TIUMP_GET_FUNC_FROM_CODE (data[0]);	dbg ("%s - port_number %d, function %d, info 0x%x",	     __FUNCTION__, port_number, function, data[1]);	port = &edge_serial->serial->port[port_number];	if (port_paranoia_check (port, __FUNCTION__)) {		dbg ("%s - change found for port that is not present",		     __FUNCTION__);		return;	}	edge_port = port->private;	if (!edge_port) {		dbg ("%s - edge_port not found", __FUNCTION__);		return;	}	switch (function) {	case TIUMP_INTERRUPT_CODE_LSR:		lsr = MapLineStatus(data[1]);		if (lsr & UMP_UART_LSR_DATA_MASK) {			/* Save the LSR event for bulk read completion routine */			dbg ("%s - LSR Event Port %u LSR Status = %02x",			     __FUNCTION__, port_number, lsr);			edge_port->lsr_event = 1;			edge_port->lsr_mask = lsr;		} else {			dbg ("%s - ===== Port %d LSR Status = %02x ======",			     __FUNCTION__, port_number, lsr);			handle_new_lsr (edge_port, 0, lsr, 0);		}		break;	case TIUMP_INTERRUPT_CODE_MSR:	// MSR		/* Copy MSR from UMP */		msr = data[1];		dbg ("%s - ===== Port %u MSR Status = %02x ======\n",		     __FUNCTION__, port_number, msr);		handle_new_msr (edge_port, msr);		break;	default:		err ("%s - Unknown Interrupt code from UMP %x\n",		     __FUNCTION__, data[1]);		break;			}}static void edge_bulk_in_callback (struct urb *urb){	struct edgeport_port *edge_port = (struct edgeport_port *)urb->context;	unsigned char *data = urb->transfer_buffer;	struct tty_struct *tty;	int status;	int i;	int port_number;	dbg("%s", __FUNCTION__);	if (port_paranoia_check (edge_port->port, __FUNCTION__))		return;	if (urb->status) {		dbg ("%s - nonzero read bulk status received: %d",		     __FUNCTION__, urb->status);		if (urb->status == -EPIPE) {			/* clear any problem that might have happened on this pipe */			usb_clear_halt (edge_port->port->serial->dev, urb->pipe);			goto exit;		}		return;	}	port_number = edge_port->port->number - edge_port->port->serial->minor;	if (edge_port->lsr_event) {		edge_port->lsr_event = 0;		dbg ("%s ===== Port %u LSR Status = %02x, Data = %02x ======",		     __FUNCTION__, port_number, edge_port->lsr_mask, *data);		handle_new_lsr (edge_port, 1, edge_port->lsr_mask, *data);		/* Adjust buffer length/pointer */		--urb->actual_length;		++data;	}	tty = edge_port->port->tty;	if (tty && urb->actual_length) {		usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);		if (edge_port->close_pending) {			dbg ("%s - close is pending, dropping data on the floor.", __FUNCTION__);		} else {			for (i = 0; i < urb->actual_length ; ++i) {				/* if we insert more than TTY_FLIPBUF_SIZE characters,				 * we drop them. */				if (tty->flip.count >= TTY_FLIPBUF_SIZE) {					tty_flip_buffer_push(tty);				}				/* this doesn't actually push the data through unless				 * tty->low_latency is set */				tty_insert_flip_char(tty, data[i], 0);			}			tty_flip_buffer_push(tty);		}		edge_port->icount.rx += urb->actual_length;	}exit:	/* continue always trying to read */	urb->dev = edge_port->port->serial->dev;	status = usb_submit_urb (urb);	if (status)		err ("%s - usb_submit_urb failed with result %d",		     __FUNCTION__, status);}static void edge_bulk_out_callback (struct urb *urb){	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);	struct tty_struct *tty;	dbg ("%s - port %d", __FUNCTION__, port->number);	if (!serial) {		dbg ("%s - bad serial pointer, exiting", __FUNCTION__);		return;	}	if (urb->status) {		dbg ("%s - nonzero write bulk status received: %d",		     __FUNCTION__, urb->status);		if (urb->status == -EPIPE) {			/* clear any problem that might have happened on this pipe */			usb_clear_halt (serial->dev, urb->pipe);		}		return;	}	tty = port->tty;	if (tty) {		/* let the tty driver wakeup if it has a special write_wakeup function */		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) {			(tty->ldisc.write_wakeup)(tty);		}		/* tell the tty driver that something has changed */		wake_up_interruptible(&tty->write_wait);	}}static int edge_open (struct usb_serial_port *port, struct file * filp){	struct edgeport_port *edge_port = (struct edgeport_port *)port->private;	struct edgeport_serial *edge_serial;	struct usb_device *dev;	struct urb *urb;	int port_number;	int status;	u16 open_settings;	u8 transaction_timeout;	if (port_paranoia_check (port, __FUNCTION__))		return -ENODEV;		dbg("%s - port %d", __FUNCTION__, port->number);	if (edge_port == NULL)		return -ENODEV;	/* force low_latency on so that our tty_push actually forces the data through, 	   otherwise it is scheduled, and with high data rates (like with OHCI) data	   can get lost. */	if (port->tty)		port->tty->low_latency = 1;	port_number = port->number - port->serial->minor;	switch (port_number) {		case 0:			edge_port->uart_base = UMPMEM_BASE_UART1;			edge_port->dma_address = UMPD_OEDB1_ADDRESS;			break;		case 1:			edge_port->uart_base = UMPMEM_BASE_UART2;			edge_port->dma_address = UMPD_OEDB2_ADDRESS;			break;		default:			err ("Unknown port number!!!");			return -ENODEV;	}	dbg ("%s - port_number = %d, uart_base = %04x, dma_address = %04x",	     __FUNCTION__, port_number, edge_port->uart_base, edge_port->dma_address);	dev = port->serial->dev;	memset (&(edge_port->icount), 0x00, sizeof(edge_port->icount));	init_waitqueue_head (&edge_port->delta_msr_wait);	/* turn off loopback */	status = TIClearLoopBack (edge_port);	if (status)		return status;		/* set up the port settings */	edge_set_termios (port, NULL);	/* open up the port */	/* milliseconds to timeout for DMA transfer */	transaction_timeout = 2;	edge_port->ump_read_timeout = max (20, ((transaction_timeout * 3) / 2) );	// milliseconds to timeout for DMA transfer	open_settings = (u8)(UMP_DMA_MODE_CONTINOUS | 			     UMP_PIPE_TRANS_TIMEOUT_ENA | 			     (transaction_timeout << 2));	dbg ("%s - Sending UMPC_OPEN_PORT", __FUNCTION__);	/* Tell TI to open and start the port */	status = TIWriteCommandSync (dev,					UMPC_OPEN_PORT,					(u8)(UMPM_UART1_PORT + port_number),					open_settings,					NULL,					0);	if (status)		return status;	/* Start the DMA? */	status = TIWriteCommandSync (dev,					UMPC_START_PORT,					(u8)(UMPM_UART1_PORT + port_number),					0,					NULL,					0);	if (status)		return status;	/* Clear TX and RX buffers in UMP */	status = TIPurgeDataSync (port, UMP_PORT_DIR_OUT | UMP_PORT_DIR_IN);	if (status)		return status;	/* Read Initial MSR */	status = TIReadVendorRequestSync (dev,					UMPC_READ_MSR,	// Request					0,		// wValue					(__u16)(UMPM_UART1_PORT + port_number),	// wIndex (Address)					&edge_port->shadow_msr,			// TransferBuffer					1);					// TransferBufferLength	if (status)		return status;	dbg ("ShadowMSR 0x%X", edge_port->shadow_msr); 	edge_serial = edge_port->edge_serial;	if (edge_serial->num_ports_open == 0) {		dbg ("%s - setting up bulk in urb", __FUNCTION__);		/* we are the first port to be opened, let's post the interrupt urb */		urb = edge_serial->serial->port[0].interrupt_in_urb;		if (!urb) {			err ("%s - no interrupt urb present, exiting", __FUNCTION__);			return -EINVAL;		}		urb->complete = edge_interrupt_callback;		urb->context = edge_serial;		urb->dev = dev;		status = usb_submit_urb (urb);		if (status) {			err ("%s - usb_submit_urb failed with value %d", __FUNCTION__, status);			return status;		}	}	/*	 * reset the data toggle on the bulk endpoints to work around bug in	 * host controllers where things get out of sync some times	 */	usb_clear_halt (dev, port->write_urb->pipe);	usb_clear_halt (dev, port->read_urb->pipe);	/* start up our bulk read urb */	urb = port->read_urb;	if (!urb) {		err ("%s - no read urb present, exiting", __FUNCTION__);		return -EINVAL;	}	urb->complete = edge_bulk_in_callback;	urb->context = edge_port;

⌨️ 快捷键说明

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