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

📄 io_ti.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (tty && urb->actual_length) {		usb_serial_debug_data(debug, &edge_port->port->dev, __FUNCTION__, urb->actual_length, data);		if (edge_port->close_pending) {			dbg ("%s - close is pending, dropping data on the floor.", __FUNCTION__);		} else {			edge_tty_recv(&edge_port->port->dev, tty, data, urb->actual_length);		}		edge_port->icount.rx += urb->actual_length;	}exit:	/* continue read unless stopped */	spin_lock(&edge_port->ep_lock);	if (edge_port->ep_read_urb_state == EDGE_READ_URB_RUNNING) {		urb->dev = edge_port->port->serial->dev;		status = usb_submit_urb(urb, GFP_ATOMIC);	} else if (edge_port->ep_read_urb_state == EDGE_READ_URB_STOPPING) {		edge_port->ep_read_urb_state = EDGE_READ_URB_STOPPED;	}	spin_unlock(&edge_port->ep_lock);	if (status)		dev_err (&urb->dev->dev, "%s - usb_submit_urb failed with result %d\n",			 __FUNCTION__, status);}static void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned char *data, int length){	int cnt;	do {		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {			tty_flip_buffer_push(tty);			if (tty->flip.count >= TTY_FLIPBUF_SIZE) {				dev_err(dev, "%s - dropping data, %d bytes lost\n",					__FUNCTION__, length);				return;			}		}		cnt = min(length, TTY_FLIPBUF_SIZE - tty->flip.count);		memcpy(tty->flip.char_buf_ptr, data, cnt);		memset(tty->flip.flag_buf_ptr, 0, cnt);		tty->flip.char_buf_ptr += cnt;		tty->flip.flag_buf_ptr += cnt;		tty->flip.count += cnt;		data += cnt;		length -= cnt;	} while (length > 0);	tty_flip_buffer_push(tty);}static void edge_bulk_out_callback (struct urb *urb, struct pt_regs *regs){	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;	struct edgeport_port *edge_port = usb_get_serial_port_data(port);	dbg ("%s - port %d", __FUNCTION__, port->number);	edge_port->ep_write_urb_in_use = 0;	switch (urb->status) {	case 0:		/* success */		break;	case -ECONNRESET:	case -ENOENT:	case -ESHUTDOWN:		/* this urb is terminated, clean up */		dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);		return;	default:		dev_err (&urb->dev->dev,"%s - nonzero write bulk status received: %d\n",		     __FUNCTION__, urb->status);	}	/* send any buffered data */	edge_send(port);}static int edge_open (struct usb_serial_port *port, struct file * filp){	struct edgeport_port *edge_port = usb_get_serial_port_data(port);	struct edgeport_serial *edge_serial;	struct usb_device *dev;	struct urb *urb;	int port_number;	int status;	u16 open_settings;	u8 transaction_timeout;	dbg("%s - port %d", __FUNCTION__, port->number);	if (edge_port == NULL)		return -ENODEV;	if (port->tty)		port->tty->low_latency = low_latency;	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:			dev_err (&port->dev, "Unknown port number!!!\n");			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) {		dev_err(&port->dev,"%s - cannot send clear loopback command, %d\n",			__FUNCTION__, 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) {		dev_err(&port->dev,"%s - cannot send open command, %d\n", __FUNCTION__, status);		return status;	}	/* Start the DMA? */	status = TIWriteCommandSync (dev,					UMPC_START_PORT,					(u8)(UMPM_UART1_PORT + port_number),					0,					NULL,					0);	if (status) {		dev_err(&port->dev,"%s - cannot send start DMA command, %d\n", __FUNCTION__, status);		return status;	}	/* Clear TX and RX buffers in UMP */	status = TIPurgeDataSync (port, UMP_PORT_DIR_OUT | UMP_PORT_DIR_IN);	if (status) {		dev_err(&port->dev,"%s - cannot send clear buffers command, %d\n", __FUNCTION__, 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) { 		dev_err(&port->dev,"%s - cannot send read MSR command, %d\n", __FUNCTION__, status);		return status;	}	dbg ("ShadowMSR 0x%X", edge_port->shadow_msr); 	/* Set Initial MCR */	edge_port->shadow_mcr = MCR_RTS | MCR_DTR;	dbg ("ShadowMCR 0x%X", edge_port->shadow_mcr);	edge_serial = edge_port->edge_serial;	if (down_interruptible(&edge_serial->es_sem))		return -ERESTARTSYS;	if (edge_serial->num_ports_open == 0) {		/* 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) {			dev_err (&port->dev, "%s - no interrupt urb present, exiting\n", __FUNCTION__);			status = -EINVAL;			goto up_es_sem;		}		urb->complete = edge_interrupt_callback;		urb->context = edge_serial;		urb->dev = dev;		status = usb_submit_urb (urb, GFP_KERNEL);		if (status) {			dev_err (&port->dev, "%s - usb_submit_urb failed with value %d\n", __FUNCTION__, status);			goto up_es_sem;		}	}	/*	 * 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) {		dev_err (&port->dev, "%s - no read urb present, exiting\n", __FUNCTION__);		status = -EINVAL;		goto unlink_int_urb;	}	edge_port->ep_read_urb_state = EDGE_READ_URB_RUNNING;	urb->complete = edge_bulk_in_callback;	urb->context = edge_port;	urb->dev = dev;	status = usb_submit_urb (urb, GFP_KERNEL);	if (status) {		dev_err (&port->dev, "%s - read bulk usb_submit_urb failed with value %d\n", __FUNCTION__, status);		goto unlink_int_urb;	}	++edge_serial->num_ports_open;	dbg("%s - exited", __FUNCTION__);	goto up_es_sem;unlink_int_urb:	if (edge_port->edge_serial->num_ports_open == 0)		usb_kill_urb(port->serial->port[0]->interrupt_in_urb);up_es_sem:	up(&edge_serial->es_sem);	return status;}static void edge_close (struct usb_serial_port *port, struct file *filp){	struct edgeport_serial *edge_serial;	struct edgeport_port *edge_port;	int port_number;	int status;	dbg("%s - port %d", __FUNCTION__, port->number);			 	edge_serial = usb_get_serial_data(port->serial);	edge_port = usb_get_serial_port_data(port);	if ((edge_serial == NULL) || (edge_port == NULL))		return;		/* The bulkreadcompletion routine will check 	 * this flag and dump add read data */	edge_port->close_pending = 1;	/* chase the port close and flush */	TIChasePort (edge_port, (HZ*closing_wait)/100, 1);	usb_kill_urb(port->read_urb);	usb_kill_urb(port->write_urb);	edge_port->ep_write_urb_in_use = 0;	/* assuming we can still talk to the device,	 * send a close port command to it */	dbg("%s - send umpc_close_port", __FUNCTION__);	port_number = port->number - port->serial->minor;	status = TIWriteCommandSync (port->serial->dev,				     UMPC_CLOSE_PORT,				     (__u8)(UMPM_UART1_PORT + port_number),				     0,				     NULL,				     0);	down(&edge_serial->es_sem);	--edge_port->edge_serial->num_ports_open;	if (edge_port->edge_serial->num_ports_open <= 0) {		/* last port is now closed, let's shut down our interrupt urb */		usb_kill_urb(port->serial->port[0]->interrupt_in_urb);		edge_port->edge_serial->num_ports_open = 0;	}	up(&edge_serial->es_sem);	edge_port->close_pending = 0;	dbg("%s - exited", __FUNCTION__);}static int edge_write (struct usb_serial_port *port, const unsigned char *data, int count){	struct edgeport_port *edge_port = usb_get_serial_port_data(port);	unsigned long flags;	dbg("%s - port %d", __FUNCTION__, port->number);	if (count == 0) {		dbg("%s - write request of 0 bytes", __FUNCTION__);		return 0;	}	if (edge_port == NULL)		return -ENODEV;	if (edge_port->close_pending == 1)		return -ENODEV;	spin_lock_irqsave(&edge_port->ep_lock, flags);	count = edge_buf_put(edge_port->ep_out_buf, data, count);	spin_unlock_irqrestore(&edge_port->ep_lock, flags);	edge_send(port);	return count;}static void edge_send(struct usb_serial_port *port){	int count, result;	struct edgeport_port *edge_port = usb_get_serial_port_data(port);	struct tty_struct *tty = port->tty;	unsigned long flags;	dbg("%s - port %d", __FUNCTION__, port->number);	spin_lock_irqsave(&edge_port->ep_lock, flags);	if (edge_port->ep_write_urb_in_use) {		spin_unlock_irqrestore(&edge_port->ep_lock, flags);		return;	}	count = edge_buf_get(edge_port->ep_out_buf,				port->write_urb->transfer_buffer,				port->bulk_out_size);	if (count == 0) {		spin_unlock_irqrestore(&edge_port->ep_lock, flags);		return;	}	edge_port->ep_write_urb_in_use = 1;	spin_unlock_irqrestore(&edge_port->ep_lock, flags);	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, port->write_urb->transfer_buffer);	/* set up our urb */	usb_fill_bulk_urb (port->write_urb, port->serial->dev,			   usb_sndbulkpipe (port->serial->dev,					    port->bulk_out_endpointAddress),			   port->write_urb->transfer_buffer, count,			   edge_bulk_out_callback,			   port);	/* send the data out the bulk port */	result = usb_submit_urb(port->write_urb, GFP_ATOMIC);	if (result) {		dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result);		edge_port->ep_write_urb_in_use = 0;		// TODO: reschedule edge_send	} else {		edge_port->icount.tx += count;	}	/* wakeup any process waiting for writes to complete */	/* there is now more room in the buffer for new writes */	if (tty) {		/* let the tty driver wakeup if it has a special write_wakeup function */		tty_wakeup(tty);	}}static int edge_write_room (struct usb_serial_port *port){	struct edgeport_port *edge_port = usb_get_serial_port_data(port);	int room = 0;	unsigned long flags;	dbg("%s - port %d", __FUNCTION__, port->number);	if (edge_port == NULL)		return -ENODEV;	if (edge_port->close_pending == 1)		return -ENODEV;	spin_lock_irqsave(&edge_port->ep_lock, flags);	room = edge_buf_space_avail(edge_port->ep_out_buf);	spin_unlock_irqrestore(&edge_port->ep_lock, flags);	dbg("%s - returns %d", __FUNCTION__, room);	return room;}static int edge_chars_in_buffer (struct usb_serial_port *port){	struct edgeport_port *edge_port = usb_get_serial_port_data(port);	int chars = 0;	unsigned long flags;	dbg("%s - port %d", __FUNCTION__, port->number);	if (edge_port == NULL)		return -ENODEV;	if (edge_port->close_pending == 1)		return -ENODEV;	spin_lock_irqsave(&edge_port->ep_lock, flags);	chars = edge_buf_data_avail(edge_port->ep_out_buf);	spin_unlock_irqrestore(&edge_port->ep_lock, flags);	dbg ("%s - returns %d", __FUNCTION__, chars);	return chars;}static void edge_throttle (struct usb_serial_port *port){	struct edgeport_port *edge_port = usb_get_serial_port_data(port);	struct tty_struct *tty;	int status;	dbg("%s - port %d", __FUNCTION__, port->number);	if (edge_port == NULL)		return;	tty = port->tty;	if (!tty) {		dbg ("%s - no tty available", __FUNCTION__);		return;	}	/* if we are implementing XON/XOFF, send the stop character */	if (I_IXOFF(tty)) {		unsigned char stop_char = STOP_CHAR(tty);		status = edge_write (port, &stop_char, 1);		if (status <= 0) {			dev_err(&port->dev, "%s - failed to write stop character, %d\n", __FUNCTION__, status);		}	}	/* if w

⌨️ 快捷键说明

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