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

📄 io_edgeport.c

📁 该文件是rt_linux
💻 C
📖 第 1 页 / 共 5 页
字号:
					}				}			}			position += 2;			++portNumber;		}	}}/***************************************************************************** * edge_bulk_in_callback *	this is the callback function for when we have received data on the  *	bulk in endpoint. *****************************************************************************/static void edge_bulk_in_callback (struct urb *urb){	struct edgeport_serial	*edge_serial = (struct edgeport_serial *)urb->context;	unsigned char		*data = urb->transfer_buffer;	int			status;	__u16			raw_data_length;	dbg("%s", __FUNCTION__);	if (serial_paranoia_check (edge_serial->serial, __FUNCTION__)) {		return;	}	if (urb->status) {		dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);		return;	}	if (urb->actual_length) {		raw_data_length = urb->actual_length;		usb_serial_debug_data (__FILE__, __FUNCTION__, raw_data_length, data);		/* decrement our rxBytes available by the number that we just got */		edge_serial->rxBytesAvail -= raw_data_length;		dbg("%s - Received = %d, rxBytesAvail %d", __FUNCTION__, raw_data_length, edge_serial->rxBytesAvail);		process_rcvd_data (edge_serial, data, urb->actual_length);		/* check to see if there's any more data for us to read */		if ((edge_serial->rxBytesAvail > 0) &&		    (edge_serial->read_urb->status != -EINPROGRESS)) {			dbg(" --- Posting a read");			/* there is, so resubmit our urb */			edge_serial->read_urb->dev = edge_serial->serial->dev;			status = usb_submit_urb(edge_serial->read_urb);			if (status) {				err("%s - usb_submit_urb(read bulk) failed, status = %d", __FUNCTION__, status);			}		}	}}/***************************************************************************** * edge_bulk_out_data_callback *	this is the callback function for when we have finished sending serial data *	on the bulk out endpoint. *****************************************************************************/static void edge_bulk_out_data_callback (struct urb *urb){	struct edgeport_port *edge_port = (struct edgeport_port *)urb->context;	struct tty_struct *tty;	dbg("%s", __FUNCTION__);	if (port_paranoia_check (edge_port->port, __FUNCTION__)) {		return;	}	if (urb->status) {		dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);	}	tty = edge_port->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);	}	// Release the Write URB	edge_port->write_in_progress = FALSE;	// Check if more data needs to be sent	send_more_port_data((struct edgeport_serial *)(edge_port->port->serial->private), edge_port);}/***************************************************************************** * BulkOutCmdCallback *	this is the callback function for when we have finished sending a command *	on the bulk out endpoint. *****************************************************************************/static void edge_bulk_out_cmd_callback (struct urb *urb){	struct edgeport_port *edge_port = (struct edgeport_port *)urb->context;	struct tty_struct *tty;	int status = urb->status;	dbg("%s", __FUNCTION__);	CmdUrbs--;	dbg("%s - FREE URB %p (outstanding %d)", __FUNCTION__, urb, CmdUrbs);	/* clean up the transfer buffer */	if (urb->transfer_buffer != NULL) {		kfree(urb->transfer_buffer);	}	// Free the command urb	usb_unlink_urb (urb);	usb_free_urb   (urb);	if (port_paranoia_check (edge_port->port, __FUNCTION__)) {		return;	}	if (status) {		dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, status);		return;	}	/* Get pointer to tty */	tty = edge_port->port->tty;	/* tell the tty driver that something has changed */	if (tty)		wake_up_interruptible(&tty->write_wait);	/* we have completed the command */	edge_port->commandPending = FALSE;	wake_up_interruptible(&edge_port->wait_command);}/***************************************************************************** * Driver tty interface functions *****************************************************************************//***************************************************************************** * SerialOpen *	this function is called by the tty driver when a port is opened *	If successful, we return 0 *	Otherwise we return a negative error number. *****************************************************************************/static int edge_open (struct usb_serial_port *port, struct file * filp){	struct edgeport_port *edge_port = (struct edgeport_port *)port->private;	struct usb_serial *serial;	struct edgeport_serial *edge_serial;	int response;	int 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;	/* see if we've set up our endpoint info yet (can't set it up in edge_startup	   as the structures were not set up at that time.) */	serial = port->serial;	edge_serial = (struct edgeport_serial *)serial->private;	if (edge_serial == NULL) {		return -ENODEV;	}	if (edge_serial->interrupt_in_buffer == NULL) {		struct usb_serial_port *port0 = &serial->port[0];				/* not set up yet, so do it now */		edge_serial->interrupt_in_buffer = port0->interrupt_in_buffer;		edge_serial->interrupt_in_endpoint = port0->interrupt_in_endpointAddress;		edge_serial->interrupt_read_urb = port0->interrupt_in_urb;		edge_serial->bulk_in_buffer = port0->bulk_in_buffer;		edge_serial->bulk_in_endpoint = port0->bulk_in_endpointAddress;		edge_serial->read_urb = port0->read_urb;		edge_serial->bulk_out_endpoint = port0->bulk_out_endpointAddress;			/* set up our interrupt urb */		FILL_INT_URB(edge_serial->interrupt_read_urb,			     serial->dev,			     usb_rcvintpipe(serial->dev,					    port0->interrupt_in_endpointAddress),			     port0->interrupt_in_buffer,			     edge_serial->interrupt_read_urb->transfer_buffer_length,			     edge_interrupt_callback, edge_serial,			     edge_serial->interrupt_read_urb->interval);				/* set up our bulk in urb */		FILL_BULK_URB(edge_serial->read_urb, serial->dev,			      usb_rcvbulkpipe(serial->dev, port0->bulk_in_endpointAddress),			      port0->bulk_in_buffer,			      edge_serial->read_urb->transfer_buffer_length,			      edge_bulk_in_callback, edge_serial);		/* start interrupt read for this edgeport		 * this interrupt will continue as long as the edgeport is connected */		response = usb_submit_urb (edge_serial->interrupt_read_urb);		if (response) {			err("%s - Error %d submitting control urb", __FUNCTION__, response);		}	}		/* initialize our wait queues */	init_waitqueue_head(&edge_port->wait_open);	init_waitqueue_head(&edge_port->wait_chase);	init_waitqueue_head(&edge_port->delta_msr_wait);	init_waitqueue_head(&edge_port->wait_command);	/* initialize our icount structure */	memset (&(edge_port->icount), 0x00, sizeof(edge_port->icount));	/* initialize our port settings */	edge_port->txCredits            = 0;			/* Can't send any data yet */	edge_port->shadowMCR            = MCR_MASTER_IE;	/* Must always set this bit to enable ints! */	edge_port->chaseResponsePending = FALSE;	/* send a open port command */	edge_port->openPending = TRUE;	edge_port->open        = FALSE;	response = send_iosp_ext_cmd (edge_port, IOSP_CMD_OPEN_PORT, 0);	if (response < 0) {		err("%s - error sending open port command", __FUNCTION__);		edge_port->openPending = FALSE;		return -ENODEV;	}	/* now wait for the port to be completly opened */	timeout = OPEN_TIMEOUT;	while (timeout && edge_port->openPending == TRUE) {		timeout = interruptible_sleep_on_timeout (&edge_port->wait_open, timeout);	}	if (edge_port->open == FALSE) {		/* open timed out */		dbg("%s - open timedout", __FUNCTION__);		edge_port->openPending = FALSE;		return -ENODEV;	}	/* create the txfifo */	edge_port->txfifo.head	= 0;	edge_port->txfifo.tail	= 0;	edge_port->txfifo.count	= 0;	edge_port->txfifo.size	= edge_port->maxTxCredits;	edge_port->txfifo.fifo	= kmalloc (edge_port->maxTxCredits, GFP_KERNEL);	if (!edge_port->txfifo.fifo) {		dbg("%s - no memory", __FUNCTION__);		edge_close (port, filp);		return -ENOMEM;	}	/* Allocate a URB for the write */	edge_port->write_urb = usb_alloc_urb (0);	if (!edge_port->write_urb) {		dbg("%s - no memory", __FUNCTION__);		edge_close (port, filp);		return -ENOMEM;	}	dbg("%s(%d) - Initialize TX fifo to %d bytes", __FUNCTION__, port->number, edge_port->maxTxCredits);	dbg("%s exited", __FUNCTION__);	return 0;}/************************************************************************ * * block_until_chase_response * *	This function will block the close until one of the following: *		1. Response to our Chase comes from Edgeport *		2. A timout of 10 seconds without activity has expired *		   (1K of Edgeport data @ 2400 baud ==> 4 sec to empty) * ************************************************************************/static void block_until_chase_response(struct edgeport_port *edge_port){	__u16 lastCredits;	int timeout = 1*HZ;	int wait = 10;	while (1) {		// Save Last credits		lastCredits = edge_port->txCredits;		// Did we get our Chase response		if (edge_port->chaseResponsePending == FALSE) {			dbg("%s - Got Chase Response", __FUNCTION__);			// did we get all of our credit back?			if (edge_port->txCredits == edge_port->maxTxCredits ) {				dbg("%s - Got all credits", __FUNCTION__);				return;			}		}		// Block the thread for a while		interruptible_sleep_on_timeout (&edge_port->wait_chase, timeout);		if (lastCredits == edge_port->txCredits) {			// No activity.. count down.			wait--;			if (wait == 0) {				edge_port->chaseResponsePending = FALSE;				dbg("%s - Chase TIMEOUT", __FUNCTION__);				return;			}		} else {			// Reset timout value back to 10 seconds			dbg("%s - Last %d, Current %d", __FUNCTION__, lastCredits, edge_port->txCredits);			wait = 10;		}	}}/************************************************************************ * * block_until_tx_empty * *	This function will block the close until one of the following: *		1. TX count are 0 *		2. The edgeport has stopped *		3. A timout of 3 seconds without activity has expired * ************************************************************************/static void block_until_tx_empty (struct edgeport_port *edge_port){	struct TxFifo *fifo = &edge_port->txfifo;	__u32 lastCount;	int timeout = HZ/10;	int wait = 30;	while (1) {		// Save Last count		lastCount = fifo->count;		// Is the Edgeport Buffer empty?		if (lastCount == 0) {			dbg("%s - TX Buffer Empty", __FUNCTION__);			return;		}		// Block the thread for a while		interruptible_sleep_on_timeout (&edge_port->wait_chase, timeout);		dbg("%s wait", __FUNCTION__);		if (lastCount == fifo->count) {			// No activity.. count down.			wait--;			if (wait == 0) {				dbg("%s - TIMEOUT", __FUNCTION__);				return;			}		} else {			// Reset timout value back to seconds			wait = 30;		}	}}/***************************************************************************** * edge_close *	this function is called by the tty driver when a port is closed *****************************************************************************/static void edge_close (struct usb_serial_port *port, struct file * filp){	struct usb_serial *serial;	struct edgeport_serial *edge_serial;	struct edgeport_port *edge_port;	int status;	if (port_paranoia_check (port, __FUNCTION__))		return;		dbg("%s - port %d", __FUNCTION__, port->number);			 

⌨️ 快捷键说明

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