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

📄 kobil_sct.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		  kfree(dbg_data);		*/		// END DEBUG		for (i = 0; i < purb->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);	}	// someone sets the dev to 0 if the close method has been called	port->interrupt_in_urb->dev = port->serial->dev;	result = usb_submit_urb( port->interrupt_in_urb, GFP_ATOMIC ); 	dbg("%s - port %d Send read URB returns: %i", __FUNCTION__, port->number, result);}static void kobil_write_callback( struct urb *purb, struct pt_regs *regs ){}static int kobil_write (struct usb_serial_port *port, int from_user, 			const unsigned char *buf, int count){	int length = 0;	int result = 0;	int todo = 0;	struct kobil_private * priv;	if (count == 0) {		dbg("%s - port %d write request of 0 bytes", __FUNCTION__, port->number);		return 0;	}	priv = usb_get_serial_port_data(port);	if (count > (KOBIL_BUF_LENGTH - priv->filled)) {		dbg("%s - port %d Error: write request bigger than buffer size", __FUNCTION__, port->number);		return -ENOMEM;	}	// Copy data to buffer	if (from_user) {		if (copy_from_user(priv->buf + priv->filled, buf, count)) {			return -EFAULT;		}	} else {		memcpy (priv->buf + priv->filled, buf, count);	}	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, priv->buf + priv->filled);	priv->filled = priv->filled + count;	// only send complete block. TWIN, KAAN SIM and adapter K use the same protocol.	if ( ((priv->device_type != KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 2) && (priv->filled >= (priv->buf[1] + 3))) || 	     ((priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 3) && (priv->filled >= (priv->buf[2] + 4))) ) {				// stop reading (except TWIN and KAAN SIM)		if ( (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) || (priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) ) {			usb_unlink_urb( port->interrupt_in_urb );		}		todo = priv->filled - priv->cur_pos;		while(todo > 0) {			// max 8 byte in one urb (endpoint size)			length = (todo < 8) ? todo : 8;			// copy data to transfer buffer			memcpy(port->write_urb->transfer_buffer, priv->buf + priv->cur_pos, length );			usb_fill_int_urb( port->write_urb,					  port->serial->dev,					  usb_sndintpipe(port->serial->dev, priv->write_int_endpoint_address),					  port->write_urb->transfer_buffer,					  length,					  kobil_write_callback,					  port,					  8				);			priv->cur_pos = priv->cur_pos + length;			result = usb_submit_urb( port->write_urb, GFP_NOIO );			dbg("%s - port %d Send write URB returns: %i", __FUNCTION__, port->number, result);			todo = priv->filled - priv->cur_pos;			if (todo > 0) {				msleep(24);			}		} // end while				priv->filled = 0;		priv->cur_pos = 0;		// someone sets the dev to 0 if the close method has been called		port->interrupt_in_urb->dev = port->serial->dev;				// start reading (except TWIN and KAAN SIM)		if ( (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) || (priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) ) {			// someone sets the dev to 0 if the close method has been called			port->interrupt_in_urb->dev = port->serial->dev;						result = usb_submit_urb( port->interrupt_in_urb, GFP_NOIO ); 			dbg("%s - port %d Send read URB returns: %i", __FUNCTION__, port->number, result);		}	}	return count;}static int kobil_write_room (struct usb_serial_port *port){	//dbg("%s - port %d", __FUNCTION__, port->number);	return 8;}static int kobil_tiocmget(struct usb_serial_port *port, struct file *file){	struct kobil_private * priv;	int result;	unsigned char *transfer_buffer;	int transfer_buffer_length = 8;	priv = usb_get_serial_port_data(port);	if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) {		// This device doesn't support ioctl calls		return -EINVAL;	}	// allocate memory for transfer buffer	transfer_buffer = (unsigned char *) kmalloc(transfer_buffer_length, GFP_KERNEL);  	if (!transfer_buffer) {		return -ENOMEM;	}	memset(transfer_buffer, 0, transfer_buffer_length);	result = usb_control_msg( port->serial->dev, 				  usb_rcvctrlpipe(port->serial->dev, 0 ), 				  SUSBCRequest_GetStatusLineState,				  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN,				  0,				  0,				  transfer_buffer,				  transfer_buffer_length,				  KOBIL_TIMEOUT);	dbg("%s - port %d Send get_status_line_state URB returns: %i. Statusline: %02x", 	    __FUNCTION__, port->number, result, transfer_buffer[0]);	if ((transfer_buffer[0] & SUSBCR_GSL_DSR) != 0) {		priv->line_state |= TIOCM_DSR;	} else {		priv->line_state &= ~TIOCM_DSR; 	}	kfree(transfer_buffer);	return priv->line_state;}static int  kobil_tiocmset(struct usb_serial_port *port, struct file *file,			   unsigned int set, unsigned int clear){	struct kobil_private * priv;	int result;	int dtr = 0;	int rts = 0;	unsigned char *transfer_buffer;	int transfer_buffer_length = 8;	priv = usb_get_serial_port_data(port);	if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) {		// This device doesn't support ioctl calls		return -EINVAL;	}	// allocate memory for transfer buffer	transfer_buffer = (unsigned char *) kmalloc(transfer_buffer_length, GFP_KERNEL);	if (! transfer_buffer) {		return -ENOMEM;	}	memset(transfer_buffer, 0, transfer_buffer_length);	if (set & TIOCM_RTS)		rts = 1;	if (set & TIOCM_DTR)		dtr = 1;	if (clear & TIOCM_RTS)		rts = 0;	if (clear & TIOCM_DTR)		dtr = 0;	if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) {		if (dtr != 0)			dbg("%s - port %d Setting DTR", __FUNCTION__, port->number);		else			dbg("%s - port %d Clearing DTR", __FUNCTION__, port->number);		result = usb_control_msg( port->serial->dev, 					  usb_rcvctrlpipe(port->serial->dev, 0 ), 					  SUSBCRequest_SetStatusLinesOrQueues,					  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,					  ((dtr != 0) ? SUSBCR_SSL_SETDTR : SUSBCR_SSL_CLRDTR),					  0,					  transfer_buffer,					  0,					  KOBIL_TIMEOUT);	} else {		if (rts != 0)			dbg("%s - port %d Setting RTS", __FUNCTION__, port->number);		else			dbg("%s - port %d Clearing RTS", __FUNCTION__, port->number);		result = usb_control_msg( port->serial->dev, 					  usb_rcvctrlpipe(port->serial->dev, 0 ), 					  SUSBCRequest_SetStatusLinesOrQueues,					  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,					  ((rts != 0) ? SUSBCR_SSL_SETRTS : SUSBCR_SSL_CLRRTS),					  0,					  transfer_buffer,					  0,					  KOBIL_TIMEOUT);	}	dbg("%s - port %d Send set_status_line URB returns: %i", __FUNCTION__, port->number, result);	kfree(transfer_buffer);	return (result < 0) ? result : 0;}static int  kobil_ioctl(struct usb_serial_port *port, struct file *file,			unsigned int cmd, unsigned long arg){	struct kobil_private * priv;	int result;	unsigned short urb_val = 0;	unsigned char *transfer_buffer;	int transfer_buffer_length = 8;	char *settings;	void __user *user_arg = (void __user *)arg;	priv = usb_get_serial_port_data(port);	if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) {		// This device doesn't support ioctl calls		return 0;	}	switch (cmd) {	case TCGETS:   // 0x5401		result = verify_area(VERIFY_WRITE, user_arg, sizeof(struct termios));		if (result) {			dbg("%s - port %d Error in verify_area", __FUNCTION__, port->number);			return(result);		}		if (kernel_termios_to_user_termios((struct termios __user *)arg,						   &priv->internal_termios))			return -EFAULT;		return 0;	case TCSETS:   // 0x5402		if (!(port->tty->termios)) {			dbg("%s - port %d Error: port->tty->termios is NULL", __FUNCTION__, port->number);			return -ENOTTY;		}		result = verify_area(VERIFY_READ, user_arg, sizeof(struct termios));		if (result) {			dbg("%s - port %d Error in verify_area", __FUNCTION__, port->number);			return result;		}		if (user_termios_to_kernel_termios(&priv->internal_termios,						   (struct termios __user *)arg))			return -EFAULT;				settings = (unsigned char *) kmalloc(50, GFP_KERNEL);  		if (! settings) {			return -ENOBUFS;		}		memset(settings, 0, 50);		switch (priv->internal_termios.c_cflag & CBAUD) {		case B1200:			urb_val = SUSBCR_SBR_1200;			strcat(settings, "1200 ");			break;		case B9600:		default:			urb_val = SUSBCR_SBR_9600;			strcat(settings, "9600 ");			break;		}		urb_val |= (priv->internal_termios.c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits : SUSBCR_SPASB_1StopBit;		strcat(settings, (priv->internal_termios.c_cflag & CSTOPB) ? "2 StopBits " : "1 StopBit ");		if (priv->internal_termios.c_cflag & PARENB) {			if  (priv->internal_termios.c_cflag & PARODD) {				urb_val |= SUSBCR_SPASB_OddParity;				strcat(settings, "Odd Parity");			} else {				urb_val |= SUSBCR_SPASB_EvenParity;				strcat(settings, "Even Parity");			}		} else {			urb_val |= SUSBCR_SPASB_NoParity;			strcat(settings, "No Parity");		}		dbg("%s - port %d setting port to: %s", __FUNCTION__, port->number, settings );		result = usb_control_msg( port->serial->dev, 					  usb_rcvctrlpipe(port->serial->dev, 0 ), 					  SUSBCRequest_SetBaudRateParityAndStopBits,					  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,					  urb_val,					  0,					  settings,					  0,					  KOBIL_TIMEOUT			);		dbg("%s - port %d Send set_baudrate URB returns: %i", __FUNCTION__, port->number, result);		kfree(settings);		return 0;	case TCFLSH:   // 0x540B		transfer_buffer = (unsigned char *) kmalloc(transfer_buffer_length, GFP_KERNEL);		if (! transfer_buffer) {		 	return -ENOBUFS;		}		result = usb_control_msg( port->serial->dev, 		 			  usb_rcvctrlpipe(port->serial->dev, 0 ), 					  SUSBCRequest_Misc,					  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,					  SUSBCR_MSC_ResetAllQueues,					  0,					  NULL,//transfer_buffer,					  0,					  KOBIL_TIMEOUT			);				dbg("%s - port %d Send reset_all_queues (FLUSH) URB returns: %i", __FUNCTION__, port->number, result);		kfree(transfer_buffer);		return ((result < 0) ? -EFAULT : 0);	}	return -ENOIOCTLCMD;}static int __init kobil_init (void){	int retval;	retval = usb_serial_register(&kobil_device);	if (retval)		goto failed_usb_serial_register;	retval = usb_register(&kobil_driver);	if (retval) 		goto failed_usb_register;	info(DRIVER_VERSION " " DRIVER_AUTHOR);	info(DRIVER_DESC);	return 0;failed_usb_register:	usb_serial_deregister(&kobil_device);failed_usb_serial_register:	return retval;}static void __exit kobil_exit (void){	usb_deregister (&kobil_driver);	usb_serial_deregister (&kobil_device);}module_init(kobil_init);module_exit(kobil_exit);MODULE_AUTHOR( DRIVER_AUTHOR );MODULE_DESCRIPTION( DRIVER_DESC );MODULE_LICENSE( "GPL" );module_param(debug, bool, S_IRUGO | S_IWUSR);MODULE_PARM_DESC(debug, "Debug enabled or not");

⌨️ 快捷键说明

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