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

📄 ir-usb.c

📁 基于S3CEB2410平台LINUX操作系统下 USB驱动源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	down (&port->sem);	--port->open_count;	if (port->open_count <= 0) {		if (serial->dev) {			/* shutdown our bulk read */			usb_unlink_urb (port->read_urb);		}		port->active = 0;		port->open_count = 0;	}	up (&port->sem);	MOD_DEC_USE_COUNT;}static int ir_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count){	unsigned char *transfer_buffer;	int result;	int transfer_size;	dbg("%s - port = %d, count = %d", __FUNCTION__, port->number, count);	if (!port->tty) {		err ("%s - no tty???", __FUNCTION__);		return 0;	}	if (count == 0)		return 0;	if (port->write_urb->status == -EINPROGRESS) {		dbg ("%s - already writing", __FUNCTION__);		return 0;	}	transfer_buffer = port->write_urb->transfer_buffer;	transfer_size = min(count, port->bulk_out_size - 1);	/*	 * The first byte of the packet we send to the device contains an	 * inband header which indicates an additional number of BOFs and	 * a baud rate change.	 *	 * See section 5.4.2.2 of the USB IrDA spec.	 */	*transfer_buffer = ir_xbof | ir_baud;	++transfer_buffer;	if (from_user) {		if (copy_from_user (transfer_buffer, buf, transfer_size))			return -EFAULT;	} else {		memcpy (transfer_buffer, buf, transfer_size);	}	usb_fill_bulk_urb (		port->write_urb,		port->serial->dev,		usb_sndbulkpipe(port->serial->dev,			port->bulk_out_endpointAddress),		port->write_urb->transfer_buffer,		transfer_size + 1,		ir_write_bulk_callback,		port);	port->write_urb->transfer_flags		= USB_QUEUE_BULK		| USB_ZERO_PACKET;	result = usb_submit_urb (port->write_urb);	if (result)		err("%s - failed submitting write urb, error %d", __FUNCTION__, result);	else		result = transfer_size;	return result;}static void ir_write_bulk_callback (struct urb *urb){	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;	if (port_paranoia_check (port, __FUNCTION__))		return;		dbg("%s - port %d", __FUNCTION__, port->number);		if (urb->status) {		dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);		return;	}	usb_serial_debug_data (		__FILE__,		__FUNCTION__,		urb->actual_length,		urb->transfer_buffer);	queue_task(&port->tqueue, &tq_immediate);	mark_bh(IMMEDIATE_BH);		return;}static void ir_read_bulk_callback (struct urb *urb){	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);	struct tty_struct *tty;	unsigned char *data = urb->transfer_buffer;	int result;	if (port_paranoia_check (port, __FUNCTION__))		return;	dbg("%s - port %d", __FUNCTION__, port->number);	if (!serial) {		dbg("%s - bad serial pointer, exiting", __FUNCTION__);		return;	}	if (!port->active) {		dbg("%s - port closed.", __FUNCTION__);		return;	}	switch (urb->status) {		case 0: /* Successful */			/*			 * The first byte of the packet we get from the device			 * contains a busy indicator and baud rate change.			 * See section 5.4.1.2 of the USB IrDA spec.			 */			if((*data & 0x0f) > 0) ir_baud = *data & 0x0f;			usb_serial_debug_data (				__FILE__,				__FUNCTION__,				urb->actual_length,				data);			/*			 * Bypass flip-buffers, and feed the ldisc directly			 * due to our potentally large buffer size.  Since we			 * used to set low_latency, this is exactly what the			 * tty layer did anyway :)			 */			tty = port->tty;			tty->ldisc.receive_buf(				tty,				data+1,				NULL,				urb->actual_length-1);			/*			 * No break here.			 * We want to resubmit the urb so we can read			 * again.			 */		case -EPROTO: /* taking inspiration from pl2303.c */			/* Continue trying to always read */			usb_fill_bulk_urb (				port->read_urb,				serial->dev, 				usb_rcvbulkpipe(serial->dev,					port->bulk_in_endpointAddress),				port->read_urb->transfer_buffer,				port->read_urb->transfer_buffer_length,				ir_read_bulk_callback,				port);			port->read_urb->transfer_flags = USB_QUEUE_BULK;			result = usb_submit_urb(port->read_urb);			if (result)				err("%s - failed resubmitting read urb, error %d",					__FUNCTION__, 					result);			break ;		default:			dbg("%s - nonzero read bulk status received: %d",				__FUNCTION__, 				urb->status);			break ;	}	return;}static void ir_set_termios (struct usb_serial_port *port, struct termios *old_termios){	unsigned char *transfer_buffer;	unsigned int cflag;	int result;	dbg("%s - port %d", __FUNCTION__, port->number);	if ((!port->tty) || (!port->tty->termios)) {		dbg("%s - no tty structures", __FUNCTION__);		return;	}	cflag = port->tty->termios->c_cflag;	/* check that they really want us to change something */	if (old_termios) {		if ((cflag == old_termios->c_cflag) &&		    (RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) {			dbg("%s - nothing to change...", __FUNCTION__);			return;		}	}	/* All we can change is the baud rate */	if (cflag & CBAUD) {		dbg ("%s - asking for baud %d",			__FUNCTION__,			tty_get_baud_rate(port->tty));		/* 		 * FIXME, we should compare the baud request against the		 * capability stated in the IR header that we got in the		 * startup funtion.		 */		switch (cflag & CBAUD) {			case B2400:    ir_baud = SPEED_2400;    break;			default:			case B9600:    ir_baud = SPEED_9600;    break;			case B19200:   ir_baud = SPEED_19200;   break;			case B38400:   ir_baud = SPEED_38400;   break;			case B57600:   ir_baud = SPEED_57600;   break;			case B115200:  ir_baud = SPEED_115200;  break;			case B576000:  ir_baud = SPEED_576000;  break;			case B1152000: ir_baud = SPEED_1152000; break;			case B4000000: ir_baud = SPEED_4000000; break;		}		if (xbof == -1) {			ir_xbof = ir_xbof_change(ir_add_bof);		} else {			ir_xbof = ir_xbof_change(xbof) ;		}		/* Notify the tty driver that the termios have changed. */		port->tty->ldisc.set_termios(port->tty, NULL);		/* FIXME need to check to see if our write urb is busy right		 * now, or use a urb pool.		 *		 * send the baud change out on an "empty" data packet		 */		transfer_buffer = port->write_urb->transfer_buffer;		*transfer_buffer = ir_xbof | ir_baud;		usb_fill_bulk_urb (			port->write_urb,			port->serial->dev,			usb_sndbulkpipe(port->serial->dev,				port->bulk_out_endpointAddress),			port->write_urb->transfer_buffer,			1,			ir_write_bulk_callback,			port);		port->write_urb->transfer_flags			= USB_QUEUE_BULK			| USB_ZERO_PACKET;		result = usb_submit_urb (port->write_urb);		if (result)			err("%s - failed submitting write urb, error %d", __FUNCTION__, result);	}	return;}static int __init ir_init (void){	usb_serial_register (&ir_device);	info(DRIVER_DESC " " DRIVER_VERSION);	return 0;}static void __exit ir_exit (void){	usb_serial_deregister (&ir_device);}module_init(ir_init);module_exit(ir_exit);MODULE_AUTHOR(DRIVER_AUTHOR);MODULE_DESCRIPTION(DRIVER_DESC);MODULE_LICENSE("GPL");MODULE_PARM(debug, "i");MODULE_PARM_DESC(debug, "Debug enabled or not");MODULE_PARM(xbof, "i");MODULE_PARM_DESC(xbof, "Force specific number of XBOFs");MODULE_PARM(buffer_size, "i");MODULE_PARM_DESC(buffer_size, "Size of the transfer buffers");

⌨️ 快捷键说明

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