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

📄 mos7840.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
{	struct usb_device *dev = mcs->port->serial->dev;	struct usb_ctrlrequest *dr = mcs->dr;	unsigned char *buffer = mcs->ctrl_buf;	int ret;	dr->bRequestType = MCS_RD_RTYPE;	dr->bRequest = MCS_RDREQ;	dr->wValue = cpu_to_le16(Wval);	//0;	dr->wIndex = cpu_to_le16(reg);	dr->wLength = cpu_to_le16(2);	usb_fill_control_urb(mcs->control_urb, dev, usb_rcvctrlpipe(dev, 0),			     (unsigned char *)dr, buffer, 2,			     mos7840_control_callback, mcs);	mcs->control_urb->transfer_buffer_length = 2;	ret = usb_submit_urb(mcs->control_urb, GFP_ATOMIC);	return ret;}/***************************************************************************** * mos7840_interrupt_callback *	this is the callback function for when we have received data on the *	interrupt endpoint. *****************************************************************************/static void mos7840_interrupt_callback(struct urb *urb){	int result;	int length;	struct moschip_port *mos7840_port;	struct usb_serial *serial;	__u16 Data;	unsigned char *data;	__u8 sp[5], st;	int i, rv = 0;	__u16 wval, wreg = 0;	int status = urb->status;	dbg("%s", " : Entering\n");	switch (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__,		    status);		return;	default:		dbg("%s - nonzero urb status received: %d", __FUNCTION__,		    status);		goto exit;	}	length = urb->actual_length;	data = urb->transfer_buffer;	serial = (struct usb_serial *)urb->context;	/* Moschip get 5 bytes	 * Byte 1 IIR Port 1 (port.number is 0)	 * Byte 2 IIR Port 2 (port.number is 1)	 * Byte 3 IIR Port 3 (port.number is 2)	 * Byte 4 IIR Port 4 (port.number is 3)	 * Byte 5 FIFO status for both */	if (length && length > 5) {		dbg("%s \n", "Wrong data !!!");		return;	}	sp[0] = (__u8) data[0];	sp[1] = (__u8) data[1];	sp[2] = (__u8) data[2];	sp[3] = (__u8) data[3];	st = (__u8) data[4];	for (i = 0; i < serial->num_ports; i++) {		mos7840_port = mos7840_get_port_private(serial->port[i]);		wval =		    (((__u16) serial->port[i]->number -		      (__u16) (serial->minor)) + 1) << 8;		if (mos7840_port->open) {			if (sp[i] & 0x01) {				dbg("SP%d No Interrupt !!!\n", i);			} else {				switch (sp[i] & 0x0f) {				case SERIAL_IIR_RLS:					dbg("Serial Port %d: Receiver status error or ", i);					dbg("address bit detected in 9-bit mode\n");					mos7840_port->MsrLsr = 1;					wreg = LINE_STATUS_REGISTER;					break;				case SERIAL_IIR_MS:					dbg("Serial Port %d: Modem status change\n", i);					mos7840_port->MsrLsr = 0;					wreg = MODEM_STATUS_REGISTER;					break;				}				spin_lock(&mos7840_port->pool_lock);				if (!mos7840_port->zombie) {					rv = mos7840_get_reg(mos7840_port, wval, wreg, &Data);				} else {					spin_unlock(&mos7840_port->pool_lock);					return;				}				spin_unlock(&mos7840_port->pool_lock);			}		}	}	if (!(rv < 0)) /* the completion handler for the control urb will resubmit */		return;exit:	result = usb_submit_urb(urb, GFP_ATOMIC);	if (result) {		dev_err(&urb->dev->dev,			"%s - Error %d submitting interrupt urb\n",			__FUNCTION__, result);	}}static int mos7840_port_paranoia_check(struct usb_serial_port *port,				       const char *function){	if (!port) {		dbg("%s - port == NULL", function);		return -1;	}	if (!port->serial) {		dbg("%s - port->serial == NULL", function);		return -1;	}	return 0;}/* Inline functions to check the sanity of a pointer that is passed to us */static int mos7840_serial_paranoia_check(struct usb_serial *serial,					 const char *function){	if (!serial) {		dbg("%s - serial == NULL", function);		return -1;	}	if (!serial->type) {		dbg("%s - serial->type == NULL!", function);		return -1;	}	return 0;}static struct usb_serial *mos7840_get_usb_serial(struct usb_serial_port *port,						 const char *function){	/* if no port was specified, or it fails a paranoia check */	if (!port ||	    mos7840_port_paranoia_check(port, function) ||	    mos7840_serial_paranoia_check(port->serial, function)) {		/* then say that we don't have a valid usb_serial thing, which will		 * end up genrating -ENODEV return values */		return NULL;	}	return port->serial;}/***************************************************************************** * mos7840_bulk_in_callback *	this is the callback function for when we have received data on the *	bulk in endpoint. *****************************************************************************/static void mos7840_bulk_in_callback(struct urb *urb){	int retval;	unsigned char *data;	struct usb_serial *serial;	struct usb_serial_port *port;	struct moschip_port *mos7840_port;	struct tty_struct *tty;	int status = urb->status;	if (status) {		dbg("nonzero read bulk status received: %d", status);		return;	}	mos7840_port = (struct moschip_port *)urb->context;	if (!mos7840_port) {		dbg("%s", "NULL mos7840_port pointer \n");		return;	}	port = (struct usb_serial_port *)mos7840_port->port;	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\n", "Bad serial pointer ");		return;	}	dbg("%s\n", "Entering... \n");	data = urb->transfer_buffer;	dbg("%s", "Entering ........... \n");	if (urb->actual_length) {		tty = mos7840_port->port->tty;		if (tty) {			tty_buffer_request_room(tty, urb->actual_length);			tty_insert_flip_string(tty, data, urb->actual_length);			dbg(" %s \n", data);			tty_flip_buffer_push(tty);		}		mos7840_port->icount.rx += urb->actual_length;		smp_wmb();		dbg("mos7840_port->icount.rx is %d:\n",		    mos7840_port->icount.rx);	}	if (!mos7840_port->read_urb) {		dbg("%s", "URB KILLED !!!\n");		return;	}	mos7840_port->read_urb->dev = serial->dev;	retval = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC);	if (retval) {		dbg(" usb_submit_urb(read bulk) failed, retval = %d",		 retval);	}}/***************************************************************************** * mos7840_bulk_out_data_callback *	this is the callback function for when we have finished sending serial data *	on the bulk out endpoint. *****************************************************************************/static void mos7840_bulk_out_data_callback(struct urb *urb){	struct moschip_port *mos7840_port;	struct tty_struct *tty;	int status = urb->status;	int i;	mos7840_port = (struct moschip_port *)urb->context;	spin_lock(&mos7840_port->pool_lock);	for (i = 0; i < NUM_URBS; i++) {		if (urb == mos7840_port->write_urb_pool[i]) {			mos7840_port->busy[i] = 0;			break;		}	}	spin_unlock(&mos7840_port->pool_lock);	if (status) {		dbg("nonzero write bulk status received:%d\n", status);		return;	}	if (mos7840_port_paranoia_check(mos7840_port->port, __FUNCTION__)) {		dbg("%s", "Port Paranoia failed \n");		return;	}	dbg("%s \n", "Entering .........");	tty = mos7840_port->port->tty;	if (tty && mos7840_port->open)		tty_wakeup(tty);}/************************************************************************//*       D R I V E R  T T Y  I N T E R F A C E  F U N C T I O N S       *//************************************************************************/#ifdef MCSSerialProbestatic int mos7840_serial_probe(struct usb_serial *serial,				const struct usb_device_id *id){	/*need to implement the mode_reg reading and updating\	   structures usb_serial_ device_type\	   (i.e num_ports, num_bulkin,bulkout etc) */	/* Also we can update the changes  attach */	return 1;}#endif/***************************************************************************** * mos7840_open *	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 mos7840_open(struct usb_serial_port *port, struct file *filp){	int response;	int j;	struct usb_serial *serial;	struct urb *urb;	__u16 Data;	int status;	struct moschip_port *mos7840_port;	struct moschip_port *port0;	if (mos7840_port_paranoia_check(port, __FUNCTION__)) {		dbg("%s", "Port Paranoia failed \n");		return -ENODEV;	}	serial = port->serial;	if (mos7840_serial_paranoia_check(serial, __FUNCTION__)) {		dbg("%s", "Serial Paranoia failed \n");		return -ENODEV;	}	mos7840_port = mos7840_get_port_private(port);	port0 = mos7840_get_port_private(serial->port[0]);	if (mos7840_port == NULL || port0 == NULL)		return -ENODEV;	usb_clear_halt(serial->dev, port->write_urb->pipe);	usb_clear_halt(serial->dev, port->read_urb->pipe);	port0->open_ports++;	/* Initialising the write urb pool */	for (j = 0; j < NUM_URBS; ++j) {		urb = usb_alloc_urb(0, GFP_KERNEL);		mos7840_port->write_urb_pool[j] = urb;		if (urb == NULL) {			err("No more urbs???");			continue;		}		urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);		if (!urb->transfer_buffer) {			usb_free_urb(urb);			mos7840_port->write_urb_pool[j] = NULL;			err("%s-out of memory for urb buffers.", __FUNCTION__);			continue;		}	}/***************************************************************************** * Initialize MCS7840 -- Write Init values to corresponding Registers * * Register Index * 1 : IER * 2 : FCR * 3 : LCR * 4 : MCR * * 0x08 : SP1/2 Control Reg *****************************************************************************///NEED to check the following Block	status = 0;	Data = 0x0;	status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset, &Data);	if (status < 0) {		dbg("Reading Spreg failed\n");		return -1;	}	Data |= 0x80;	status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data);	if (status < 0) {		dbg("writing Spreg failed\n");		return -1;	}	Data &= ~0x80;	status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data);	if (status < 0) {		dbg("writing Spreg failed\n");		return -1;	}//End of block to be checked	status = 0;	Data = 0x0;	status =	    mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset, &Data);	if (status < 0) {		dbg("Reading Controlreg failed\n");		return -1;	}	Data |= 0x08;		//Driver done bit	Data |= 0x20;		//rx_disable	status = mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset, Data);	if (status < 0) {		dbg("writing Controlreg failed\n");		return -1;	}	//do register settings here	// Set all regs to the device default values.	////////////////////////////////////	// First Disable all interrupts.	////////////////////////////////////	Data = 0x00;	status = mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);	if (status < 0) {		dbg("disableing interrupts failed\n");		return -1;	}	// Set FIFO_CONTROL_REGISTER to the default value	Data = 0x00;	status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);	if (status < 0) {		dbg("Writing FIFO_CONTROL_REGISTER  failed\n");		return -1;	}	Data = 0xcf;	status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);	if (status < 0) {		dbg("Writing FIFO_CONTROL_REGISTER  failed\n");		return -1;	}	Data = 0x03;	status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);	mos7840_port->shadowLCR = Data;	Data = 0x0b;	status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);	mos7840_port->shadowMCR = Data;	Data = 0x00;	status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data);	mos7840_port->shadowLCR = Data;	Data |= SERIAL_LCR_DLAB;	//data latch enable in LCR 0x80	status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);	Data = 0x0c;	status = 0;	status = mos7840_set_uart_reg(port, DIVISOR_LATCH_LSB, Data);	Data = 0x0;	status = 0;	status = mos7840_set_uart_reg(port, DIVISOR_LATCH_MSB, Data);	Data = 0x00;	status = 0;	status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data);	Data = Data & ~SERIAL_LCR_DLAB;	status = 0;	status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);	mos7840_port->shadowLCR = Data;	//clearing Bulkin and Bulkout Fifo	Data = 0x0;	status = 0;	status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset, &Data);	Data = Data | 0x0c;	status = 0;	status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data);

⌨️ 快捷键说明

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