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

📄 ir-usb.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
			return -ENOMEM;		}		kfree (port->write_urb->transfer_buffer);		port->write_urb->transfer_buffer = buffer;		port->write_urb->transfer_buffer_length = buffer_size;		port->bulk_out_size = buffer_size;	}	/* Start reading from the device */	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_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_bh(&port->lock);	if (port->write_urb_busy) {		spin_unlock_bh(&port->lock);		dbg("%s - already writing", __FUNCTION__);		return 0;	}	port->write_urb_busy = 1;	spin_unlock_bh(&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 usb_serial_port *port = (struct usb_serial_port *)urb->context;	int status = urb->status;	dbg("%s - port %d", __FUNCTION__, port->number);	port->write_urb_busy = 0;	if (status) {		dbg("%s - nonzero write bulk status received: %d",		    __FUNCTION__, status);		return;	}	usb_serial_debug_data (		debug,		&port->dev,		__FUNCTION__,		urb->actual_length,		urb->transfer_buffer);	usb_serial_port_softint(port);}static void ir_read_bulk_callback (struct urb *urb){	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;	struct tty_struct *tty;	unsigned char *data = urb->transfer_buffer;	int result;	int status = urb->status;	dbg("%s - port %d", __FUNCTION__, port->number);	if (!port->open_count) {		dbg("%s - port closed.", __FUNCTION__);		return;	}	switch (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);			tty = port->tty;			if (tty_buffer_request_room(tty, urb->actual_length - 1)) {				tty_insert_flip_string(tty, data+1, urb->actual_length - 1);				tty_flip_buffer_push(tty);			}			/*			 * 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__, 				status);			break ;	}	return;}static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios){	unsigned char *transfer_buffer;	int result;	speed_t baud;	int ir_baud;	dbg("%s - port %d", __FUNCTION__, port->number);	baud = 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 (baud) {		case 2400:	ir_baud = SPEED_2400; break;		case 9600:	ir_baud = SPEED_9600; break;		case 19200:	ir_baud = SPEED_19200; break;		case 38400:	ir_baud = SPEED_38400; break;		case 57600:	ir_baud = SPEED_57600; break;		case 115200:	ir_baud = SPEED_115200; break;		case 576000:	ir_baud = SPEED_576000; break;		case 1152000:	ir_baud = SPEED_1152000; break;		case 4000000:	ir_baud = SPEED_4000000; break;			break;		default:			ir_baud = SPEED_9600;			baud = 9600;	}	if (xbof == -1)		ir_xbof = ir_xbof_change(ir_add_bof);	else		ir_xbof = ir_xbof_change(xbof) ;	/* 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);	/* Only speed changes are supported */	tty_termios_copy_hw(port->tty->termios, old_termios);	tty_encode_baud_rate(port->tty, baud, baud);}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 + -