forked from mirrors/linux
		
	usb: irda: cleanup on ir-usb module
General cleanup on ir-usb module. Introduced a common header that could be used also on usb gadget framework. Lot's of cleanups and now using macros from the header file. Signed-off-by: Felipe Balbi <me@felipebalbi.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
		
							parent
							
								
									b963801164
								
							
						
					
					
						commit
						e0d795e4f3
					
				
					 2 changed files with 412 additions and 211 deletions
				
			
		|  | @ -19,7 +19,12 @@ | |||
|  * was written by Roman Weissgaerber <weissg@vienna.at>, Dag Brattli | ||||
|  * <dag@brattli.net>, and Jean Tourrilhes <jt@hpl.hp.com> | ||||
|  * | ||||
|  * See Documentation/usb/usb-serial.txt for more information on using this driver | ||||
|  * See Documentation/usb/usb-serial.txt for more information on using this | ||||
|  * driver | ||||
|  * | ||||
|  * 2008_Jun_02  Felipe Balbi <me@felipebalbi.com> | ||||
|  *	Introduced common header to be used also in USB Gadget Framework. | ||||
|  *	Still needs some other style fixes. | ||||
|  * | ||||
|  * 2007_Jun_21  Alan Cox <alan@redhat.com> | ||||
|  *	Minimal cleanups for some of the driver problens and tty layer abuse. | ||||
|  | @ -59,9 +64,10 @@ | |||
| #include <linux/tty_flip.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/spinlock.h> | ||||
| #include <asm/uaccess.h> | ||||
| #include <linux/uaccess.h> | ||||
| #include <linux/usb.h> | ||||
| #include <linux/usb/serial.h> | ||||
| #include <linux/usb/irda.h> | ||||
| 
 | ||||
| /*
 | ||||
|  * Version Information | ||||
|  | @ -70,100 +76,75 @@ | |||
| #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>" | ||||
| #define DRIVER_DESC "USB IR Dongle driver" | ||||
| 
 | ||||
| /* USB IrDA class spec information */ | ||||
| #define USB_CLASS_IRDA		0x02 | ||||
| #define USB_DT_IRDA		0x21 | ||||
| #define IU_REQ_GET_CLASS_DESC	0x06 | ||||
| #define SPEED_2400		0x01 | ||||
| #define SPEED_9600		0x02 | ||||
| #define SPEED_19200		0x03 | ||||
| #define SPEED_38400		0x04 | ||||
| #define SPEED_57600		0x05 | ||||
| #define SPEED_115200		0x06 | ||||
| #define SPEED_576000		0x07 | ||||
| #define SPEED_1152000		0x08 | ||||
| #define SPEED_4000000		0x09 | ||||
| 
 | ||||
| struct irda_class_desc { | ||||
| 	u8	bLength; | ||||
| 	u8	bDescriptorType; | ||||
| 	u16	bcdSpecRevision; | ||||
| 	u8	bmDataSize; | ||||
| 	u8	bmWindowSize; | ||||
| 	u8	bmMinTurnaroundTime; | ||||
| 	u16	wBaudRate; | ||||
| 	u8	bmAdditionalBOFs; | ||||
| 	u8	bIrdaRateSniff; | ||||
| 	u8	bMaxUnicastList; | ||||
| } __attribute__ ((packed)); | ||||
| 
 | ||||
| static int debug; | ||||
| 
 | ||||
| /* if overridden by the user, then use their value for the size of the read and
 | ||||
|  * write urbs */ | ||||
| static int buffer_size; | ||||
| 
 | ||||
| /* if overridden by the user, then use the specified number of XBOFs */ | ||||
| static int xbof = -1; | ||||
| 
 | ||||
| static int  ir_startup (struct usb_serial *serial); | ||||
| static int  ir_open (struct usb_serial_port *port, struct file *filep); | ||||
| static void ir_close (struct usb_serial_port *port, struct file *filep); | ||||
| static int  ir_write (struct usb_serial_port *port, const unsigned char *buf, int count); | ||||
| static void ir_write_bulk_callback (struct urb *urb); | ||||
| static void ir_read_bulk_callback (struct urb *urb); | ||||
| static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios); | ||||
| static int ir_startup(struct usb_serial *serial); | ||||
| static int ir_open(struct usb_serial_port *port, struct file *filep); | ||||
| static void ir_close(struct usb_serial_port *port, struct file *filep); | ||||
| static int ir_write(struct usb_serial_port *port, | ||||
| 		const unsigned char *buf, int count); | ||||
| static void ir_write_bulk_callback(struct urb *urb); | ||||
| static void ir_read_bulk_callback(struct urb *urb); | ||||
| static void ir_set_termios(struct usb_serial_port *port, | ||||
| 		struct ktermios *old_termios); | ||||
| 
 | ||||
| /* Not that this lot means you can only have one per system */ | ||||
| static u8 ir_baud = 0; | ||||
| static u8 ir_xbof = 0; | ||||
| static u8 ir_add_bof = 0; | ||||
| static u8 ir_baud; | ||||
| static u8 ir_xbof; | ||||
| static u8 ir_add_bof; | ||||
| 
 | ||||
| static struct usb_device_id id_table [] = { | ||||
| static struct usb_device_id ir_id_table[] = { | ||||
| 	{ USB_DEVICE(0x050f, 0x0180) },		/* KC Technology, KC-180 */ | ||||
| 	{ USB_DEVICE(0x08e9, 0x0100) },		/* XTNDAccess */ | ||||
| 	{ USB_DEVICE(0x09c4, 0x0011) },		/* ACTiSys ACT-IR2000U */ | ||||
| 	{ USB_INTERFACE_INFO (USB_CLASS_APP_SPEC, USB_CLASS_IRDA, 0) }, | ||||
| 	{ USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, USB_SUBCLASS_IRDA, 0) }, | ||||
| 	{ }					/* Terminating entry */ | ||||
| }; | ||||
| 
 | ||||
| MODULE_DEVICE_TABLE (usb, id_table); | ||||
| MODULE_DEVICE_TABLE(usb, ir_id_table); | ||||
| 
 | ||||
| static struct usb_driver ir_driver = { | ||||
| 	.name =		"ir-usb", | ||||
| 	.probe =	usb_serial_probe, | ||||
| 	.disconnect =	usb_serial_disconnect, | ||||
| 	.id_table =	id_table, | ||||
| 	.no_dynamic_id = 	1, | ||||
| 	.name		= "ir-usb", | ||||
| 	.probe		= usb_serial_probe, | ||||
| 	.disconnect	= usb_serial_disconnect, | ||||
| 	.id_table	= ir_id_table, | ||||
| 	.no_dynamic_id	= 1, | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| static struct usb_serial_driver ir_device = { | ||||
| 	.driver = { | ||||
| 		.owner =	THIS_MODULE, | ||||
| 		.name =		"ir-usb", | ||||
| 	.driver	= { | ||||
| 		.owner	= THIS_MODULE, | ||||
| 		.name	= "ir-usb", | ||||
| 	}, | ||||
| 	.description =		"IR Dongle", | ||||
| 	.usb_driver = 		&ir_driver, | ||||
| 	.id_table =		id_table, | ||||
| 	.num_ports =		1, | ||||
| 	.set_termios =		ir_set_termios, | ||||
| 	.attach =		ir_startup, | ||||
| 	.open =			ir_open, | ||||
| 	.close =		ir_close, | ||||
| 	.write =		ir_write, | ||||
| 	.write_bulk_callback =	ir_write_bulk_callback, | ||||
| 	.read_bulk_callback =	ir_read_bulk_callback, | ||||
| 	.description		= "IR Dongle", | ||||
| 	.usb_driver		= &ir_driver, | ||||
| 	.id_table		= ir_id_table, | ||||
| 	.num_ports		= 1, | ||||
| 	.set_termios		= ir_set_termios, | ||||
| 	.attach			= ir_startup, | ||||
| 	.open			= ir_open, | ||||
| 	.close			= ir_close, | ||||
| 	.write			= ir_write, | ||||
| 	.write_bulk_callback	= ir_write_bulk_callback, | ||||
| 	.read_bulk_callback	= ir_read_bulk_callback, | ||||
| }; | ||||
| 
 | ||||
| static inline void irda_usb_dump_class_desc(struct irda_class_desc *desc) | ||||
| static inline void irda_usb_dump_class_desc(struct usb_irda_cs_descriptor *desc) | ||||
| { | ||||
| 	dbg("bLength=%x", desc->bLength); | ||||
| 	dbg("bDescriptorType=%x", desc->bDescriptorType); | ||||
| 	dbg("bcdSpecRevision=%x", desc->bcdSpecRevision);  | ||||
| 	dbg("bcdSpecRevision=%x", __le16_to_cpu(desc->bcdSpecRevision)); | ||||
| 	dbg("bmDataSize=%x", desc->bmDataSize); | ||||
| 	dbg("bmWindowSize=%x", desc->bmWindowSize); | ||||
| 	dbg("bmMinTurnaroundTime=%d", desc->bmMinTurnaroundTime); | ||||
| 	dbg("wBaudRate=%x", desc->wBaudRate); | ||||
| 	dbg("wBaudRate=%x", __le16_to_cpu(desc->wBaudRate)); | ||||
| 	dbg("bmAdditionalBOFs=%x", desc->bmAdditionalBOFs); | ||||
| 	dbg("bIrdaRateSniff=%x", desc->bIrdaRateSniff); | ||||
| 	dbg("bMaxUnicastList=%x", desc->bMaxUnicastList); | ||||
|  | @ -181,17 +162,18 @@ static inline void irda_usb_dump_class_desc(struct irda_class_desc *desc) | |||
|  * | ||||
|  * Based on the same function in drivers/net/irda/irda-usb.c | ||||
|  */ | ||||
| static struct irda_class_desc *irda_usb_find_class_desc(struct usb_device *dev, unsigned int ifnum) | ||||
| static struct usb_irda_cs_descriptor * | ||||
| irda_usb_find_class_desc(struct usb_device *dev, unsigned int ifnum) | ||||
| { | ||||
| 	struct irda_class_desc *desc; | ||||
| 	struct usb_irda_cs_descriptor *desc; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	desc = kzalloc(sizeof (struct irda_class_desc), GFP_KERNEL); | ||||
| 	if (desc == NULL)  | ||||
| 	desc = kzalloc(sizeof(*desc), GFP_KERNEL); | ||||
| 	if (!desc) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev,0), | ||||
| 			IU_REQ_GET_CLASS_DESC, | ||||
| 	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | ||||
| 			USB_REQ_CS_IRDA_GET_CLASS_DESC, | ||||
| 			USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | ||||
| 			0, ifnum, desc, sizeof(*desc), 1000); | ||||
| 
 | ||||
|  | @ -199,17 +181,18 @@ static struct irda_class_desc *irda_usb_find_class_desc(struct usb_device *dev, | |||
| 	if (ret < sizeof(*desc)) { | ||||
| 		dbg("%s - class descriptor read %s (%d)", | ||||
| 				__func__, | ||||
| 				(ret<0) ? "failed" : "too short", | ||||
| 				(ret < 0) ? "failed" : "too short", | ||||
| 				ret); | ||||
| 		goto error; | ||||
| 	} | ||||
| 	if (desc->bDescriptorType != USB_DT_IRDA) { | ||||
| 	if (desc->bDescriptorType != USB_DT_CS_IRDA) { | ||||
| 		dbg("%s - bad class descriptor type", __func__); | ||||
| 		goto error; | ||||
| 	} | ||||
| 
 | ||||
| 	irda_usb_dump_class_desc(desc); | ||||
| 	return desc; | ||||
| 
 | ||||
| error: | ||||
| 	kfree(desc); | ||||
| 	return NULL; | ||||
|  | @ -219,64 +202,100 @@ static struct irda_class_desc *irda_usb_find_class_desc(struct usb_device *dev, | |||
| static u8 ir_xbof_change(u8 xbof) | ||||
| { | ||||
| 	u8 result; | ||||
| 
 | ||||
| 	/* reference irda-usb.c */ | ||||
| 	switch(xbof) { | ||||
| 		case 48: result = 0x10; break; | ||||
| 		case 28: | ||||
| 		case 24: result = 0x20; break; | ||||
| 		default: | ||||
| 		case 12: result = 0x30; break; | ||||
| 		case  5: | ||||
| 		case  6: result = 0x40; break; | ||||
| 		case  3: result = 0x50; break; | ||||
| 		case  2: result = 0x60; break; | ||||
| 		case  1: result = 0x70; break; | ||||
| 		case  0: result = 0x80; break; | ||||
| 	switch (xbof) { | ||||
| 	case 48: | ||||
| 		result = 0x10; | ||||
| 		break; | ||||
| 	case 28: | ||||
| 	case 24: | ||||
| 		result = 0x20; | ||||
| 		break; | ||||
| 	default: | ||||
| 	case 12: | ||||
| 		result = 0x30; | ||||
| 		break; | ||||
| 	case  5: | ||||
| 	case  6: | ||||
| 		result = 0x40; | ||||
| 		break; | ||||
| 	case  3: | ||||
| 		result = 0x50; | ||||
| 		break; | ||||
| 	case  2: | ||||
| 		result = 0x60; | ||||
| 		break; | ||||
| 	case  1: | ||||
| 		result = 0x70; | ||||
| 		break; | ||||
| 	case  0: | ||||
| 		result = 0x80; | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	return(result); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static int ir_startup (struct usb_serial *serial) | ||||
| static int ir_startup(struct usb_serial *serial) | ||||
| { | ||||
| 	struct irda_class_desc *irda_desc; | ||||
| 	struct usb_irda_cs_descriptor *irda_desc; | ||||
| 
 | ||||
| 	irda_desc = irda_usb_find_class_desc (serial->dev, 0); | ||||
| 	if (irda_desc == NULL) { | ||||
| 		dev_err (&serial->dev->dev, "IRDA class descriptor not found, device not bound\n"); | ||||
| 	irda_desc = irda_usb_find_class_desc(serial->dev, 0); | ||||
| 	if (!irda_desc) { | ||||
| 		dev_err(&serial->dev->dev, | ||||
| 			"IRDA class descriptor not found, device not bound\n"); | ||||
| 		return -ENODEV; | ||||
| 	} | ||||
| 
 | ||||
| 	dbg ("%s - Baud rates supported:%s%s%s%s%s%s%s%s%s", | ||||
| 	dbg("%s - Baud rates supported:%s%s%s%s%s%s%s%s%s", | ||||
| 		__func__, | ||||
| 		(irda_desc->wBaudRate & 0x0001) ? " 2400"    : "", | ||||
| 		(irda_desc->wBaudRate & 0x0002) ? " 9600"    : "", | ||||
| 		(irda_desc->wBaudRate & 0x0004) ? " 19200"   : "", | ||||
| 		(irda_desc->wBaudRate & 0x0008) ? " 38400"   : "", | ||||
| 		(irda_desc->wBaudRate & 0x0010) ? " 57600"   : "", | ||||
| 		(irda_desc->wBaudRate & 0x0020) ? " 115200"  : "", | ||||
| 		(irda_desc->wBaudRate & 0x0040) ? " 576000"  : "", | ||||
| 		(irda_desc->wBaudRate & 0x0080) ? " 1152000" : "", | ||||
| 		(irda_desc->wBaudRate & 0x0100) ? " 4000000" : ""); | ||||
| 		(irda_desc->wBaudRate & USB_IRDA_BR_2400) ? " 2400" : "", | ||||
| 		(irda_desc->wBaudRate & USB_IRDA_BR_9600) ? " 9600" : "", | ||||
| 		(irda_desc->wBaudRate & USB_IRDA_BR_19200) ? " 19200" : "", | ||||
| 		(irda_desc->wBaudRate & USB_IRDA_BR_38400) ? " 38400" : "", | ||||
| 		(irda_desc->wBaudRate & USB_IRDA_BR_57600) ? " 57600" : "", | ||||
| 		(irda_desc->wBaudRate & USB_IRDA_BR_115200) ? " 115200" : "", | ||||
| 		(irda_desc->wBaudRate & USB_IRDA_BR_576000) ? " 576000" : "", | ||||
| 		(irda_desc->wBaudRate & USB_IRDA_BR_1152000) ? " 1152000" : "", | ||||
| 		(irda_desc->wBaudRate & USB_IRDA_BR_4000000) ? " 4000000" : ""); | ||||
| 
 | ||||
| 	switch( irda_desc->bmAdditionalBOFs ) { | ||||
| 		case 0x01: ir_add_bof = 48; break; | ||||
| 		case 0x02: ir_add_bof = 24; break; | ||||
| 		case 0x04: ir_add_bof = 12; break; | ||||
| 		case 0x08: ir_add_bof =  6; break; | ||||
| 		case 0x10: ir_add_bof =  3; break; | ||||
| 		case 0x20: ir_add_bof =  2; break; | ||||
| 		case 0x40: ir_add_bof =  1; break; | ||||
| 		case 0x80: ir_add_bof =  0; break; | ||||
| 		default:; | ||||
| 	switch (irda_desc->bmAdditionalBOFs) { | ||||
| 	case USB_IRDA_AB_48: | ||||
| 		ir_add_bof = 48; | ||||
| 		break; | ||||
| 	case USB_IRDA_AB_24: | ||||
| 		ir_add_bof = 24; | ||||
| 		break; | ||||
| 	case USB_IRDA_AB_12: | ||||
| 		ir_add_bof = 12; | ||||
| 		break; | ||||
| 	case USB_IRDA_AB_6: | ||||
| 		ir_add_bof = 6; | ||||
| 		break; | ||||
| 	case USB_IRDA_AB_3: | ||||
| 		ir_add_bof = 3; | ||||
| 		break; | ||||
| 	case USB_IRDA_AB_2: | ||||
| 		ir_add_bof = 2; | ||||
| 		break; | ||||
| 	case USB_IRDA_AB_1: | ||||
| 		ir_add_bof = 1; | ||||
| 		break; | ||||
| 	case USB_IRDA_AB_0: | ||||
| 		ir_add_bof = 0; | ||||
| 		break; | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	kfree (irda_desc); | ||||
| 	kfree(irda_desc); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int ir_open (struct usb_serial_port *port, struct file *filp) | ||||
| static int ir_open(struct usb_serial_port *port, struct file *filp) | ||||
| { | ||||
| 	char *buffer; | ||||
| 	int result = 0; | ||||
|  | @ -285,43 +304,46 @@ static int ir_open (struct usb_serial_port *port, struct file *filp) | |||
| 
 | ||||
| 	if (buffer_size) { | ||||
| 		/* override the default buffer sizes */ | ||||
| 		buffer = kmalloc (buffer_size, GFP_KERNEL); | ||||
| 		buffer = kmalloc(buffer_size, GFP_KERNEL); | ||||
| 		if (!buffer) { | ||||
| 			dev_err (&port->dev, "%s - out of memory.\n", __func__); | ||||
| 			dev_err(&port->dev, "%s - out of memory.\n", __func__); | ||||
| 			return -ENOMEM; | ||||
| 		} | ||||
| 		kfree (port->read_urb->transfer_buffer); | ||||
| 		kfree(port->read_urb->transfer_buffer); | ||||
| 		port->read_urb->transfer_buffer = buffer; | ||||
| 		port->read_urb->transfer_buffer_length = buffer_size; | ||||
| 
 | ||||
| 		buffer = kmalloc (buffer_size, GFP_KERNEL); | ||||
| 		buffer = kmalloc(buffer_size, GFP_KERNEL); | ||||
| 		if (!buffer) { | ||||
| 			dev_err (&port->dev, "%s - out of memory.\n", __func__); | ||||
| 			dev_err(&port->dev, "%s - out of memory.\n", __func__); | ||||
| 			return -ENOMEM; | ||||
| 		} | ||||
| 		kfree (port->write_urb->transfer_buffer); | ||||
| 		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 ( | ||||
| 	usb_fill_bulk_urb( | ||||
| 		port->read_urb, | ||||
| 		port->serial->dev, | ||||
| 		usb_rcvbulkpipe(port->serial->dev, port->bulk_in_endpointAddress), | ||||
| 		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", __func__, result); | ||||
| 		dev_err(&port->dev, | ||||
| 			"%s - failed submitting read urb, error %d\n", | ||||
| 			__func__, result); | ||||
| 
 | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| static void ir_close (struct usb_serial_port *port, struct file * filp) | ||||
| static void ir_close(struct usb_serial_port *port, struct file *filp) | ||||
| { | ||||
| 	dbg("%s - port %d", __func__, port->number); | ||||
| 
 | ||||
|  | @ -329,7 +351,8 @@ static void ir_close (struct usb_serial_port *port, struct file * filp) | |||
| 	usb_kill_urb(port->read_urb); | ||||
| } | ||||
| 
 | ||||
| static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int count) | ||||
| static int ir_write(struct usb_serial_port *port, | ||||
| 		const unsigned char *buf, int count) | ||||
| { | ||||
| 	unsigned char *transfer_buffer; | ||||
| 	int result; | ||||
|  | @ -338,7 +361,7 @@ static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int | |||
| 	dbg("%s - port = %d, count = %d", __func__, port->number, count); | ||||
| 
 | ||||
| 	if (!port->tty) { | ||||
| 		dev_err (&port->dev, "%s - no tty???\n", __func__); | ||||
| 		dev_err(&port->dev, "%s - no tty???\n", __func__); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -359,7 +382,7 @@ static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int | |||
| 
 | ||||
| 	/*
 | ||||
| 	 * The first byte of the packet we send to the device contains an | ||||
| 	 * inband header which indicates an additional number of BOFs and | ||||
| 	 * inbound header which indicates an additional number of BOFs and | ||||
| 	 * a baud rate change. | ||||
| 	 * | ||||
| 	 * See section 5.4.2.2 of the USB IrDA spec. | ||||
|  | @ -367,9 +390,9 @@ static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int | |||
| 	*transfer_buffer = ir_xbof | ir_baud; | ||||
| 	++transfer_buffer; | ||||
| 
 | ||||
| 	memcpy (transfer_buffer, buf, transfer_size); | ||||
| 	memcpy(transfer_buffer, buf, transfer_size); | ||||
| 
 | ||||
| 	usb_fill_bulk_urb ( | ||||
| 	usb_fill_bulk_urb( | ||||
| 		port->write_urb, | ||||
| 		port->serial->dev, | ||||
| 		usb_sndbulkpipe(port->serial->dev, | ||||
|  | @ -381,17 +404,19 @@ static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int | |||
| 
 | ||||
| 	port->write_urb->transfer_flags = URB_ZERO_PACKET; | ||||
| 
 | ||||
| 	result = usb_submit_urb (port->write_urb, GFP_ATOMIC); | ||||
| 	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", __func__, result); | ||||
| 		dev_err(&port->dev, | ||||
| 			"%s - failed submitting write urb, error %d\n", | ||||
| 			__func__, result); | ||||
| 	} else | ||||
| 		result = transfer_size; | ||||
| 
 | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| static void ir_write_bulk_callback (struct urb *urb) | ||||
| static void ir_write_bulk_callback(struct urb *urb) | ||||
| { | ||||
| 	struct usb_serial_port *port = urb->context; | ||||
| 	int status = urb->status; | ||||
|  | @ -405,7 +430,7 @@ static void ir_write_bulk_callback (struct urb *urb) | |||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	usb_serial_debug_data ( | ||||
| 	usb_serial_debug_data( | ||||
| 		debug, | ||||
| 		&port->dev, | ||||
| 		__func__, | ||||
|  | @ -415,7 +440,7 @@ static void ir_write_bulk_callback (struct urb *urb) | |||
| 	usb_serial_port_softint(port); | ||||
| } | ||||
| 
 | ||||
| static void ir_read_bulk_callback (struct urb *urb) | ||||
| static void ir_read_bulk_callback(struct urb *urb) | ||||
| { | ||||
| 	struct usb_serial_port *port = urb->context; | ||||
| 	struct tty_struct *tty; | ||||
|  | @ -431,68 +456,69 @@ static void ir_read_bulk_callback (struct urb *urb) | |||
| 	} | ||||
| 
 | ||||
| 	switch (status) { | ||||
| 		case 0: /* Successful */ | ||||
| 	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; | ||||
| 		/*
 | ||||
| 		 * 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, | ||||
| 				__func__, | ||||
| 				urb->actual_length, | ||||
| 				data); | ||||
| 		usb_serial_debug_data( | ||||
| 			debug, | ||||
| 			&port->dev, | ||||
| 			__func__, | ||||
| 			urb->actual_length, | ||||
| 			data); | ||||
| 
 | ||||
| 			tty = port->tty; | ||||
| 		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); | ||||
| 			} | ||||
| 		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. | ||||
| 			 */ | ||||
| 		/*
 | ||||
| 		 * No break here. | ||||
| 		 * We want to resubmit the urb so we can read | ||||
| 		 * again. | ||||
| 		 */ | ||||
| 
 | ||||
| 		case -EPROTO: /* taking inspiration from pl2303.c */ | ||||
| 	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); | ||||
| 		/* 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", | ||||
| 					__func__, result); | ||||
| 
 | ||||
| 			break ; | ||||
| 
 | ||||
| 		default: | ||||
| 			dbg("%s - nonzero read bulk status received: %d", | ||||
| 				__func__, | ||||
| 				status); | ||||
| 			break ; | ||||
| 		result = usb_submit_urb(port->read_urb, GFP_ATOMIC); | ||||
| 		if (result) | ||||
| 			dev_err(&port->dev, | ||||
| 				"%s - failed resubmitting read urb, error %d\n", | ||||
| 				__func__, result); | ||||
| 		break; | ||||
| 
 | ||||
| 	default: | ||||
| 		dbg("%s - nonzero read bulk status received: %d", | ||||
| 			__func__, | ||||
| 			status); | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	return; | ||||
| } | ||||
| 
 | ||||
| static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) | ||||
| static void ir_set_termios(struct usb_serial_port *port, | ||||
| 		struct ktermios *old_termios) | ||||
| { | ||||
| 	unsigned char *transfer_buffer; | ||||
| 	int result; | ||||
|  | @ -510,19 +536,36 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t | |||
| 	 */ | ||||
| 
 | ||||
| 	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; | ||||
| 	case 2400: | ||||
| 		ir_baud = USB_IRDA_BR_2400; | ||||
| 		break; | ||||
| 	case 9600: | ||||
| 		ir_baud = USB_IRDA_BR_9600; | ||||
| 		break; | ||||
| 	case 19200: | ||||
| 		ir_baud = USB_IRDA_BR_19200; | ||||
| 		break; | ||||
| 	case 38400: | ||||
| 		ir_baud = USB_IRDA_BR_38400; | ||||
| 		break; | ||||
| 	case 57600: | ||||
| 		ir_baud = USB_IRDA_BR_57600; | ||||
| 		break; | ||||
| 	case 115200: | ||||
| 		ir_baud = USB_IRDA_BR_115200; | ||||
| 		break; | ||||
| 	case 576000: | ||||
| 		ir_baud = USB_IRDA_BR_576000; | ||||
| 		break; | ||||
| 	case 1152000: | ||||
| 		ir_baud = USB_IRDA_BR_1152000; | ||||
| 		break; | ||||
| 	case 4000000: | ||||
| 		ir_baud = USB_IRDA_BR_4000000; | ||||
| 		break; | ||||
| 	default: | ||||
| 		ir_baud = USB_IRDA_BR_9600; | ||||
| 		baud = 9600; | ||||
| 	} | ||||
| 
 | ||||
| 	if (xbof == -1) | ||||
|  | @ -538,10 +581,11 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t | |||
| 	transfer_buffer = port->write_urb->transfer_buffer; | ||||
| 	*transfer_buffer = ir_xbof | ir_baud; | ||||
| 
 | ||||
| 	usb_fill_bulk_urb ( | ||||
| 	usb_fill_bulk_urb( | ||||
| 		port->write_urb, | ||||
| 		port->serial->dev, | ||||
| 		usb_sndbulkpipe(port->serial->dev, port->bulk_out_endpointAddress), | ||||
| 		usb_sndbulkpipe(port->serial->dev, | ||||
| 			port->bulk_out_endpointAddress), | ||||
| 		port->write_urb->transfer_buffer, | ||||
| 		1, | ||||
| 		ir_write_bulk_callback, | ||||
|  | @ -549,38 +593,44 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t | |||
| 
 | ||||
| 	port->write_urb->transfer_flags = URB_ZERO_PACKET; | ||||
| 
 | ||||
| 	result = usb_submit_urb (port->write_urb, GFP_KERNEL); | ||||
| 	result = usb_submit_urb(port->write_urb, GFP_KERNEL); | ||||
| 	if (result) | ||||
| 		dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __func__, result); | ||||
| 		dev_err(&port->dev, | ||||
| 				"%s - failed submitting write urb, error %d\n", | ||||
| 				__func__, 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) | ||||
| 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) | ||||
| static void __exit ir_exit(void) | ||||
| { | ||||
| 	usb_deregister (&ir_driver); | ||||
| 	usb_serial_deregister (&ir_device); | ||||
| 	usb_deregister(&ir_driver); | ||||
| 	usb_serial_deregister(&ir_device); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										151
									
								
								include/linux/usb/irda.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								include/linux/usb/irda.h
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,151 @@ | |||
| /*
 | ||||
|  * USB IrDA Bridge Device Definition | ||||
|  */ | ||||
| 
 | ||||
| #ifndef __LINUX_USB_IRDA_H | ||||
| #define __LINUX_USB_IRDA_H | ||||
| 
 | ||||
| /* This device should use Application-specific class */ | ||||
| 
 | ||||
| #define USB_SUBCLASS_IRDA			0x02 | ||||
| 
 | ||||
| /*-------------------------------------------------------------------------*/ | ||||
| 
 | ||||
| /* Class-Specific requests (bRequest field) */ | ||||
| 
 | ||||
| #define USB_REQ_CS_IRDA_RECEIVING		1 | ||||
| #define USB_REQ_CS_IRDA_CHECK_MEDIA_BUSY	3 | ||||
| #define USB_REQ_CS_IRDA_RATE_SNIFF		4 | ||||
| #define USB_REQ_CS_IRDA_UNICAST_LIST		5 | ||||
| #define USB_REQ_CS_IRDA_GET_CLASS_DESC		6 | ||||
| 
 | ||||
| /*-------------------------------------------------------------------------*/ | ||||
| 
 | ||||
| /* Class-Specific descriptor */ | ||||
| 
 | ||||
| #define USB_DT_CS_IRDA				0x21 | ||||
| 
 | ||||
| /*-------------------------------------------------------------------------*/ | ||||
| 
 | ||||
| /* Data sizes */ | ||||
| 
 | ||||
| #define USB_IRDA_DS_2048			(1 << 5) | ||||
| #define USB_IRDA_DS_1024			(1 << 4) | ||||
| #define USB_IRDA_DS_512				(1 << 3) | ||||
| #define USB_IRDA_DS_256				(1 << 2) | ||||
| #define USB_IRDA_DS_128				(1 << 1) | ||||
| #define USB_IRDA_DS_64				(1 << 0) | ||||
| 
 | ||||
| /* Window sizes */ | ||||
| 
 | ||||
| #define USB_IRDA_WS_7				(1 << 6) | ||||
| #define USB_IRDA_WS_6				(1 << 5) | ||||
| #define USB_IRDA_WS_5				(1 << 4) | ||||
| #define USB_IRDA_WS_4				(1 << 3) | ||||
| #define USB_IRDA_WS_3				(1 << 2) | ||||
| #define USB_IRDA_WS_2				(1 << 1) | ||||
| #define USB_IRDA_WS_1				(1 << 0) | ||||
| 
 | ||||
| /* Min turnaround times in usecs */ | ||||
| 
 | ||||
| #define USB_IRDA_MTT_0				(1 << 7) | ||||
| #define USB_IRDA_MTT_10				(1 << 6) | ||||
| #define USB_IRDA_MTT_50				(1 << 5) | ||||
| #define USB_IRDA_MTT_100			(1 << 4) | ||||
| #define USB_IRDA_MTT_500			(1 << 3) | ||||
| #define USB_IRDA_MTT_1000			(1 << 2) | ||||
| #define USB_IRDA_MTT_5000			(1 << 1) | ||||
| #define USB_IRDA_MTT_10000			(1 << 0) | ||||
| 
 | ||||
| /* Baud rates */ | ||||
| 
 | ||||
| #define USB_IRDA_BR_4000000			(1 << 8) | ||||
| #define USB_IRDA_BR_1152000			(1 << 7) | ||||
| #define USB_IRDA_BR_576000			(1 << 6) | ||||
| #define USB_IRDA_BR_115200			(1 << 5) | ||||
| #define USB_IRDA_BR_57600			(1 << 4) | ||||
| #define USB_IRDA_BR_38400			(1 << 3) | ||||
| #define USB_IRDA_BR_19200			(1 << 2) | ||||
| #define USB_IRDA_BR_9600			(1 << 1) | ||||
| #define USB_IRDA_BR_2400			(1 << 0) | ||||
| 
 | ||||
| /* Additional BOFs */ | ||||
| 
 | ||||
| #define USB_IRDA_AB_0				(1 << 7) | ||||
| #define USB_IRDA_AB_1				(1 << 6) | ||||
| #define USB_IRDA_AB_2				(1 << 5) | ||||
| #define USB_IRDA_AB_3				(1 << 4) | ||||
| #define USB_IRDA_AB_6				(1 << 3) | ||||
| #define USB_IRDA_AB_12				(1 << 2) | ||||
| #define USB_IRDA_AB_24				(1 << 1) | ||||
| #define USB_IRDA_AB_48				(1 << 0) | ||||
| 
 | ||||
| /* IRDA Rate Sniff */ | ||||
| 
 | ||||
| #define USB_IRDA_RATE_SNIFF			1 | ||||
| 
 | ||||
| /*-------------------------------------------------------------------------*/ | ||||
| 
 | ||||
| struct usb_irda_cs_descriptor { | ||||
| 	__u8	bLength; | ||||
| 	__u8	bDescriptorType; | ||||
| 
 | ||||
| 	__le16	bcdSpecRevision; | ||||
| 	__u8	bmDataSize; | ||||
| 	__u8	bmWindowSize; | ||||
| 	__u8	bmMinTurnaroundTime; | ||||
| 	__le16	wBaudRate; | ||||
| 	__u8	bmAdditionalBOFs; | ||||
| 	__u8	bIrdaRateSniff; | ||||
| 	__u8	bMaxUnicastList; | ||||
| } __attribute__ ((packed)); | ||||
| 
 | ||||
| /*-------------------------------------------------------------------------*/ | ||||
| 
 | ||||
| /* Data Format */ | ||||
| 
 | ||||
| #define USB_IRDA_STATUS_MEDIA_BUSY	(1 << 7) | ||||
| 
 | ||||
| /* The following is a 4-bit value used for both
 | ||||
|  * inbound and outbound headers: | ||||
|  * | ||||
|  * 0 - speed ignored | ||||
|  * 1 - 2400 bps | ||||
|  * 2 - 9600 bps | ||||
|  * 3 - 19200 bps | ||||
|  * 4 - 38400 bps | ||||
|  * 5 - 57600 bps | ||||
|  * 6 - 115200 bps | ||||
|  * 7 - 576000 bps | ||||
|  * 8 - 1.152 Mbps | ||||
|  * 9 - 5 mbps | ||||
|  * 10..15 - Reserved | ||||
|  */ | ||||
| #define USB_IRDA_STATUS_LINK_SPEED	0x0f | ||||
| 
 | ||||
| /* The following is a 4-bit value used only for
 | ||||
|  * outbound header: | ||||
|  * | ||||
|  * 0 - No change (BOF ignored) | ||||
|  * 1 - 48 BOFs | ||||
|  * 2 - 24 BOFs | ||||
|  * 3 - 12 BOFs | ||||
|  * 4 - 6 BOFs | ||||
|  * 5 - 3 BOFs | ||||
|  * 6 - 2 BOFs | ||||
|  * 7 - 1 BOFs | ||||
|  * 8 - 0 BOFs | ||||
|  * 9..15 - Reserved | ||||
|  */ | ||||
| #define USB_IRDA_EXTRA_BOFS		0xf0 | ||||
| 
 | ||||
| struct usb_irda_inbound_header { | ||||
| 	__u8		bmStatus; | ||||
| }; | ||||
| 
 | ||||
| struct usb_irda_outbound_header { | ||||
| 	__u8		bmChange; | ||||
| }; | ||||
| 
 | ||||
| #endif /* __LINUX_USB_IRDA_H */ | ||||
| 
 | ||||
		Loading…
	
		Reference in a new issue
	
	 Felipe Balbi
						Felipe Balbi