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

📄 ir-usb.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
	result = usb_submit_urb(port->read_urb, GFP_KERNEL);	if (result)		dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __FUNCTION__, result);	return result;}static void ir_close (struct usb_serial_port *port, struct file * filp){	dbg("%s - port %d", __FUNCTION__, port->number);			 	/* shutdown our bulk read */	usb_kill_urb(port->read_urb);}static int ir_write (struct usb_serial_port *port, 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) {		dev_err (&port->dev, "%s - no tty???\n", __FUNCTION__);		return 0;	}	if (count == 0)		return 0;	spin_lock(&port->lock);	if (port->write_urb_busy) {		spin_unlock(&port->lock);		dbg("%s - already writing", __FUNCTION__);		return 0;	}	port->write_urb_busy = 1;	spin_unlock(&port->lock);	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;	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 = URB_ZERO_PACKET;	result = usb_submit_urb (port->write_urb, GFP_ATOMIC);	if (result) {		port->write_urb_busy = 0;		dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result);	} else		result = transfer_size;	return result;}static void ir_write_bulk_callback (struct urb *urb, struct pt_regs *regs){	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;	dbg("%s - port %d", __FUNCTION__, port->number);	port->write_urb_busy = 0;	if (urb->status) {		dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);		return;	}	usb_serial_debug_data (		debug,		&port->dev,		__FUNCTION__,		urb->actual_length,		urb->transfer_buffer);	schedule_work(&port->work);}static void ir_read_bulk_callback (struct urb *urb, struct pt_regs *regs){	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;	struct tty_struct *tty;	unsigned char *data = urb->transfer_buffer;	int result;	dbg("%s - port %d", __FUNCTION__, port->number);	if (!port->open_count) {		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 (				debug,				&port->dev,				__FUNCTION__,				urb->actual_length,				data);			/*			 * Bypass flip-buffers, and feed the ldisc directly			 * due to our potentially large buffer size.  Since we			 * used to set low_latency, this is exactly what the			 * tty layer did anyway :)			 */			tty = port->tty;			/*			 *	FIXME: must not do this in IRQ context,			 *	must honour TTY_DONT_FLIP			 */			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,				port->serial->dev, 				usb_rcvbulkpipe(port->serial->dev,					port->bulk_in_endpointAddress),				port->read_urb->transfer_buffer,				port->read_urb->transfer_buffer_length,				ir_read_bulk_callback,				port);			result = usb_submit_urb(port->read_urb, GFP_ATOMIC);			if (result)				dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n",					__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 function.		 */		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;#ifdef B4000000			case B4000000: ir_baud = SPEED_4000000; break;#endif		}		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 = URB_ZERO_PACKET;		result = usb_submit_urb (port->write_urb, GFP_KERNEL);		if (result)			dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result);	}	return;}static int __init ir_init (void){	int retval;	retval = usb_serial_register(&ir_device);	if (retval)		goto failed_usb_serial_register;	retval = usb_register(&ir_driver);	if (retval) 		goto failed_usb_register;	info(DRIVER_DESC " " DRIVER_VERSION);	return 0;failed_usb_register:	usb_serial_deregister(&ir_device);failed_usb_serial_register:	return retval;}static void __exit ir_exit (void){	usb_deregister (&ir_driver);	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_param(debug, bool, S_IRUGO | S_IWUSR);MODULE_PARM_DESC(debug, "Debug enabled or not");module_param(xbof, int, 0);MODULE_PARM_DESC(xbof, "Force specific number of XBOFs");module_param(buffer_size, int, 0);MODULE_PARM_DESC(buffer_size, "Size of the transfer buffers");

⌨️ 快捷键说明

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