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

📄 mos7840.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	Data = Data & ~0x0c;	status = 0;	status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data);	//Finally enable all interrupts	Data = 0x0;	Data = 0x0c;	status = 0;	status = mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);	//clearing rx_disable	Data = 0x0;	status = 0;	status =	    mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset, &Data);	Data = Data & ~0x20;	status = 0;	status =	    mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset, Data);	// rx_negate	Data = 0x0;	status = 0;	status =	    mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset, &Data);	Data = Data | 0x10;	status = 0;	status =	    mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset, Data);	/* 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;/* Check to see if we've set up our endpoint info yet    *     * (can't set it up in mos7840_startup as the structures *     * were not set up at that time.)                        */	if (port0->open_ports == 1) {		if (serial->port[0]->interrupt_in_buffer == NULL) {			/* set up interrupt urb */			usb_fill_int_urb(serial->port[0]->interrupt_in_urb,					 serial->dev,					 usb_rcvintpipe(serial->dev,							serial->port[0]->							interrupt_in_endpointAddress),					 serial->port[0]->interrupt_in_buffer,					 serial->port[0]->interrupt_in_urb->					 transfer_buffer_length,					 mos7840_interrupt_callback,					 serial,					 serial->port[0]->interrupt_in_urb->					 interval);			/* start interrupt read for mos7840               *			 * will continue as long as mos7840 is connected  */			response =			    usb_submit_urb(serial->port[0]->interrupt_in_urb,					   GFP_KERNEL);			if (response) {				err("%s - Error %d submitting interrupt urb",				    __FUNCTION__, response);			}		}	}	/* see if we've set up our endpoint info yet   *	 * (can't set it up in mos7840_startup as the  *	 * structures were not set up at that time.)   */	dbg("port number is %d \n", port->number);	dbg("serial number is %d \n", port->serial->minor);	dbg("Bulkin endpoint is %d \n", port->bulk_in_endpointAddress);	dbg("BulkOut endpoint is %d \n", port->bulk_out_endpointAddress);	dbg("Interrupt endpoint is %d \n", port->interrupt_in_endpointAddress);	dbg("port's number in the device is %d\n", mos7840_port->port_num);	mos7840_port->read_urb = port->read_urb;	/* set up our bulk in urb */	usb_fill_bulk_urb(mos7840_port->read_urb,			  serial->dev,			  usb_rcvbulkpipe(serial->dev,					  port->bulk_in_endpointAddress),			  port->bulk_in_buffer,			  mos7840_port->read_urb->transfer_buffer_length,			  mos7840_bulk_in_callback, mos7840_port);	dbg("mos7840_open: bulkin endpoint is %d\n",	    port->bulk_in_endpointAddress);	response = usb_submit_urb(mos7840_port->read_urb, GFP_KERNEL);	if (response) {		err("%s - Error %d submitting control urb", __FUNCTION__,		    response);	}	/* initialize our wait queues */	init_waitqueue_head(&mos7840_port->wait_chase);	init_waitqueue_head(&mos7840_port->delta_msr_wait);	/* initialize our icount structure */	memset(&(mos7840_port->icount), 0x00, sizeof(mos7840_port->icount));	/* initialize our port settings */	mos7840_port->shadowMCR = MCR_MASTER_IE;	/* Must set to enable ints! */	/* send a open port command */	mos7840_port->open = 1;	//mos7840_change_port_settings(mos7840_port,old_termios);	mos7840_port->icount.tx = 0;	mos7840_port->icount.rx = 0;	dbg("\n\nusb_serial serial:%p       mos7840_port:%p\n      usb_serial_port port:%p\n\n", serial, mos7840_port, port);	return 0;}/***************************************************************************** * mos7840_chars_in_buffer *	this function is called by the tty driver when it wants to know how many *	bytes of data we currently have outstanding in the port (data that has *	been written, but hasn't made it out the port yet) *	If successful, we return the number of bytes left to be written in the *	system, *	Otherwise we return a negative error number. *****************************************************************************/static int mos7840_chars_in_buffer(struct usb_serial_port *port){	int i;	int chars = 0;	unsigned long flags;	struct moschip_port *mos7840_port;	dbg("%s \n", " mos7840_chars_in_buffer:entering ...........");	if (mos7840_port_paranoia_check(port, __FUNCTION__)) {		dbg("%s", "Invalid port \n");		return -1;	}	mos7840_port = mos7840_get_port_private(port);	if (mos7840_port == NULL) {		dbg("%s \n", "mos7840_break:leaving ...........");		return -1;	}	spin_lock_irqsave(&mos7840_port->pool_lock,flags);	for (i = 0; i < NUM_URBS; ++i) {		if (mos7840_port->busy[i]) {			chars += URB_TRANSFER_BUFFER_SIZE;		}	}	spin_unlock_irqrestore(&mos7840_port->pool_lock,flags);	dbg("%s - returns %d", __FUNCTION__, chars);	return chars;}/************************************************************************ * * mos7840_block_until_tx_empty * *	This function will block the close until one of the following: *		1. TX count are 0 *		2. The mos7840 has stopped *		3. A timout of 3 seconds without activity has expired * ************************************************************************/static void mos7840_block_until_tx_empty(struct moschip_port *mos7840_port){	int timeout = HZ / 10;	int wait = 30;	int count;	while (1) {		count = mos7840_chars_in_buffer(mos7840_port->port);		/* Check for Buffer status */		if (count <= 0) {			return;		}		/* Block the thread for a while */		interruptible_sleep_on_timeout(&mos7840_port->wait_chase,					       timeout);		/* No activity.. count down section */		wait--;		if (wait == 0) {			dbg("%s - TIMEOUT", __FUNCTION__);			return;		} else {			/* Reset timout value back to seconds */			wait = 30;		}	}}/***************************************************************************** * mos7840_close *	this function is called by the tty driver when a port is closed *****************************************************************************/static void mos7840_close(struct usb_serial_port *port, struct file *filp){	struct usb_serial *serial;	struct moschip_port *mos7840_port;	struct moschip_port *port0;	int j;	__u16 Data;	dbg("%s\n", "mos7840_close:entering...");	if (mos7840_port_paranoia_check(port, __FUNCTION__)) {		dbg("%s", "Port Paranoia failed \n");		return;	}	serial = mos7840_get_usb_serial(port, __FUNCTION__);	if (!serial) {		dbg("%s", "Serial Paranoia failed \n");		return;	}	mos7840_port = mos7840_get_port_private(port);	port0 = mos7840_get_port_private(serial->port[0]);	if (mos7840_port == NULL || port0 == NULL)		return;	for (j = 0; j < NUM_URBS; ++j)		usb_kill_urb(mos7840_port->write_urb_pool[j]);	/* Freeing Write URBs */	for (j = 0; j < NUM_URBS; ++j) {		if (mos7840_port->write_urb_pool[j]) {			if (mos7840_port->write_urb_pool[j]->transfer_buffer)				kfree(mos7840_port->write_urb_pool[j]->				      transfer_buffer);			usb_free_urb(mos7840_port->write_urb_pool[j]);		}	}	if (serial->dev) {		/* flush and block until tx is empty */		mos7840_block_until_tx_empty(mos7840_port);	}	/* While closing port, shutdown all bulk read, write  *	 * and interrupt read if they exists                  */	if (serial->dev) {		if (mos7840_port->write_urb) {			dbg("%s", "Shutdown bulk write\n");			usb_kill_urb(mos7840_port->write_urb);		}		if (mos7840_port->read_urb) {			dbg("%s", "Shutdown bulk read\n");			usb_kill_urb(mos7840_port->read_urb);		}		if ((&mos7840_port->control_urb)) {			dbg("%s", "Shutdown control read\n");			//      usb_kill_urb (mos7840_port->control_urb);		}	}//              if(mos7840_port->ctrl_buf != NULL)//                      kfree(mos7840_port->ctrl_buf);	port0->open_ports--;	dbg("mos7840_num_open_ports in close%d:in port%d\n",	    port0->open_ports, port->number);	if (port0->open_ports == 0) {		if (serial->port[0]->interrupt_in_urb) {			dbg("%s", "Shutdown interrupt_in_urb\n");			usb_kill_urb(serial->port[0]->interrupt_in_urb);		}	}	if (mos7840_port->write_urb) {		/* if this urb had a transfer buffer already (old tx) free it */		if (mos7840_port->write_urb->transfer_buffer != NULL) {			kfree(mos7840_port->write_urb->transfer_buffer);		}		usb_free_urb(mos7840_port->write_urb);	}	Data = 0x0;	mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);	Data = 0x00;	mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);	mos7840_port->open = 0;	dbg("%s \n", "Leaving ............");}/************************************************************************ * * mos7840_block_until_chase_response * *	This function will block the close until one of the following: *		1. Response to our Chase comes from mos7840 *		2. A timout of 10 seconds without activity has expired *		   (1K of mos7840 data @ 2400 baud ==> 4 sec to empty) * ************************************************************************/static void mos7840_block_until_chase_response(struct moschip_port					       *mos7840_port){	int timeout = 1 * HZ;	int wait = 10;	int count;	while (1) {		count = mos7840_chars_in_buffer(mos7840_port->port);		/* Check for Buffer status */		if (count <= 0) {			return;		}		/* Block the thread for a while */		interruptible_sleep_on_timeout(&mos7840_port->wait_chase,					       timeout);		/* No activity.. count down section */		wait--;		if (wait == 0) {			dbg("%s - TIMEOUT", __FUNCTION__);			return;		} else {			/* Reset timout value back to seconds */			wait = 10;		}	}}/***************************************************************************** * mos7840_break *	this function sends a break to the port *****************************************************************************/static void mos7840_break(struct usb_serial_port *port, int break_state){	unsigned char data;	struct usb_serial *serial;	struct moschip_port *mos7840_port;	dbg("%s \n", "Entering ...........");	dbg("mos7840_break: Start\n");	if (mos7840_port_paranoia_check(port, __FUNCTION__)) {		dbg("%s", "Port Paranoia failed \n");		return;	}	serial = mos7840_get_usb_serial(port, __FUNCTION__);	if (!serial) {		dbg("%s", "Serial Paranoia failed \n");		return;	}	mos7840_port = mos7840_get_port_private(port);	if (mos7840_port == NULL) {		return;	}	if (serial->dev) {		/* flush and block until tx is empty */		mos7840_block_until_chase_response(mos7840_port);	}	if (break_state == -1) {		data = mos7840_port->shadowLCR | LCR_SET_BREAK;	} else {		data = mos7840_port->shadowLCR & ~LCR_SET_BREAK;	}	mos7840_port->shadowLCR = data;	dbg("mcs7840_break mos7840_port->shadowLCR is %x\n",	    mos7840_port->shadowLCR);	mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER,			     mos7840_port->shadowLCR);	return;}/***************************************************************************** * mos7840_write_room *	this function is called by the tty driver when it wants to know how many *	bytes of data we can accept for a specific port. *	If successful, we return the amount of room that we have for this port *	Otherwise we return a negative error number. *****************************************************************************/static int mos7840_write_room(struct usb_serial_port *port){	int i;	int room = 0;	unsigned long flags;	struct moschip_port *mos7840_port;	dbg("%s \n", " mos7840_write_room:entering ...........");	if (mos7840_port_paranoia_check(port, __FUNCTION__)) {		dbg("%s", "Invalid port \n");		dbg("%s \n", " mos7840_write_room:leaving ...........");		return -1;	}	mos7840_port = mos7840_get_port_private(port);	if (mos7840_port == NULL) {		dbg("%s \n", "mos7840_break:leaving ...........");		return -1;	}	spin_lock_irqsave(&mos7840_port->pool_lock, flags);	for (i = 0; i < NUM_URBS; ++i) {		if (!mos7840_port->busy[i]) {			room += URB_TRANSFER_BUFFER_SIZE;		}	}	spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);	room = (room == 0) ? 0 : room - URB_TRANSFER_BUFFER_SIZE + 1;	dbg("%s - returns %d", __FUNCTION__, room);	return room;}/***************************************************************************** * mos7840_write *	this function is called by the tty driver when data should be written to *	the port. *	If successful, we return the number of bytes written, otherwise we *      return a negative error number. *****************************************************************************/static int mos7840_write(struct usb_serial_port *port,			 const unsigned char *data, int count){	int status;	int i;	int bytes_sent = 0;	int transfer_size;	unsigned long flags;	struct moschip_port *mos7840_port;	struct usb_serial *serial;	struct urb *urb;	//__u16 Data;	const unsigned char *current_position = data;	unsigned char *data1;	dbg("%s \n", "entering ...........");	//dbg("mos7840_write: mos7840_port->shadowLCR is %x\n",mos7840_port->shadowLCR);#ifdef NOTMOS7840	Data = 0x00;	status = 0;	status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data);	mos7840_port->shadowLCR = Data;	dbg("mos7840_write: LINE_CONTROL_REGISTER is %x\n", Data);	dbg("mos7840_write: mos7840_port->shadowLCR is %x\n",	    mos7840_port->shadowLCR);	//Data = 0x03;	//status = mos7840_set_uart_reg(port,LINE_CONTROL_REGISTER,Data);	//mos7840_port->shadowLCR=Data;//Need to add later

⌨️ 快捷键说明

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