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

📄 kobil_sct.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	unsigned char *data = purb->transfer_buffer;	char *dbg_data;	dbg("%s - port %d", __FUNCTION__, port->number);	if (purb->status) {		dbg("%s - port %d Read int status not zero: %d", __FUNCTION__, port->number, purb->status);		return;	}		tty = port->tty; 	if (purb->actual_length) {				// BEGIN DEBUG		dbg_data = (unsigned char *) kmalloc((3 *  purb->actual_length + 10) * sizeof(char), GFP_KERNEL);  		if (! dbg_data) {			return;		}		memset(dbg_data, 0, (3 *  purb->actual_length + 10));		for (i = 0; i < purb->actual_length; i++) { 			sprintf(dbg_data +3*i, "%02X ", data[i]); 		}		dbg(" <-- %s", dbg_data );		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);	}}static void kobil_write_callback( struct urb *purb ){}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;	int i;	char *data;	if (count == 0) {		dbg("%s - port %d write request of 0 bytes", __FUNCTION__, port->number);		return 0;	}	priv = (struct kobil_private *) port->private;	if (count > (KOBIL_BUF_LENGTH - priv->filled)) {		dbg("%s - port %d Error: write request bigger than buffer size", __FUNCTION__, port->number);		return -ENOMEM;	}		// BEGIN DEBUG	data = (unsigned char *) kmalloc((3 * count + 10) * sizeof(char), GFP_KERNEL);  	if (! data) {		return (-1);	}	memset(data, 0, (3 * count + 10));	for (i = 0; i < count; i++) { 		sprintf(data +3*i, "%02X ", buf[i]); 	} 	dbg(" %d --> %s", port->number, data );	kfree(data);	// END DEBUG	// 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);	}	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_bulk_urb( port->write_urb,					   port->serial->dev,					   usb_sndbulkpipe( port->serial->dev, priv->write_int_endpoint_address),					   port->write_urb->transfer_buffer,					   length,					   kobil_write_callback,					   port				);			priv->cur_pos = priv->cur_pos + length;			result = usb_submit_urb( port->write_urb );			dbg("%s - port %d Send write URB returns: %i", __FUNCTION__, port->number, result);			todo = priv->filled - priv->cur_pos;			if (todo > 0) {				//mdelay(16);				set_current_state(TASK_UNINTERRUPTIBLE);				schedule_timeout(24 * HZ / 1000);			}		} // end while				priv->filled = 0;		priv->cur_pos = 0;						// 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;					// start reading			result = usb_submit_urb( port->interrupt_in_urb ); 			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){	return 8;}static int  kobil_ioctl(struct usb_serial_port *port, struct file *file,			unsigned int cmd, unsigned long arg){	struct kobil_private * priv;	int mask;	int result;	unsigned short urb_val = 0;	unsigned char *transfer_buffer;	int transfer_buffer_length = 8;	char *settings;	priv = (struct kobil_private *) port->private;	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, (void *)arg, sizeof(struct termios));		if (result) {			dbg("%s - port %d Error in verify_area", __FUNCTION__, port->number);			return(result);		}		kernel_termios_to_user_termios((struct termios *)arg, &priv->internal_termios);		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, (void *)arg, sizeof(struct termios));		if (result) {			dbg("%s - port %d Error in verify_area", __FUNCTION__, port->number);			return result;		}		user_termios_to_kernel_termios( &priv->internal_termios, (struct termios *)arg);				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		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,					  0,					  KOBIL_TIMEOUT			);				dbg("%s - port %d Send reset_all_queues (FLUSH) URB returns: %i", __FUNCTION__, port->number, result);		return ((result < 0) ? -EFAULT : 0);	case TIOCMGET: // 0x5415		// allocate memory for transfer buffer		transfer_buffer = (unsigned char *) kmalloc(transfer_buffer_length, GFP_KERNEL);  		if (! transfer_buffer) {			return -ENOBUFS;		} else {			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 (TIOCMGET) 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 put_user(priv->line_state, (unsigned long *) arg);			case TIOCMSET: // 0x5418		if (get_user(mask, (unsigned long *) arg)){			return -EFAULT;		}		if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) {			if ((mask & TIOCM_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,						  ( ((mask & TIOCM_DTR) != 0) ? SUSBCR_SSL_SETDTR : SUSBCR_SSL_CLRDTR),						  0,						  NULL,						  0,						  KOBIL_TIMEOUT				);					} else {			if ((mask & TIOCM_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,						  (((mask & TIOCM_RTS) != 0) ? SUSBCR_SSL_SETRTS : SUSBCR_SSL_CLRRTS),						  0,						  NULL,						  0,						  KOBIL_TIMEOUT				);		}		dbg("%s - port %d Send set_status_line (TIOCMSET) URB returns: %i", __FUNCTION__, port->number, result);		return ((result < 0) ? -EFAULT : 0);	}	return 0;}static int __init kobil_init (void){	usb_serial_register (&kobil_device);	info(DRIVER_VERSION " " DRIVER_AUTHOR);	info(DRIVER_DESC);	return 0;}static void __exit kobil_exit (void){	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_PARM(debug, "i");MODULE_PARM_DESC(debug, "Debug enabled or not");

⌨️ 快捷键说明

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