[prev in list] [next in list] [prev in thread] [next in thread] 

List:       linux-usb-devel
Subject:    [linux-usb-devel] [patch 2/3] usb-serial: add interrupt out support and improved debug messages
From:       Lonnie Mendez <lmendez19 () austin ! rr ! com>
Date:       2004-09-30 23:59:40
Message-ID: 200409301859.40082.lmendez19 () austin ! rr ! com
[Download RAW message or body]

This patch adds equal support for interrupt out transfers to the usb-serial core to \
match the current interrupt in support.  It also improves a few debug messages, \
nothing major.  This is necessary for the cypress_m8 driver being released 9/30/04.

Signed-off-by: Lonnie Mendez <lmendez19@austin.rr.com>


["cypress-3-2.patch" (text/x-diff)]

--- a/drivers/usb/serial/usb-serial.c	2004-09-30 16:18:43.146802216 -0500
+++ b/drivers/usb/serial/usb-serial.c	2004-09-30 16:19:50.229604080 -0500
@@ -466,9 +466,14 @@
 				usb_unlink_urb(port->interrupt_in_urb);
 				usb_free_urb(port->interrupt_in_urb);
 			}
+			if (port->interrupt_out_urb) {
+				usb_unlink_urb(port->interrupt_out_urb);
+				usb_free_urb(port->interrupt_out_urb);
+			}
 			kfree(port->bulk_in_buffer);
 			kfree(port->bulk_out_buffer);
 			kfree(port->interrupt_in_buffer);
+			kfree(port->interrupt_out_buffer);
 		}
 	}
 
@@ -825,9 +830,14 @@
 		usb_unlink_urb(port->interrupt_in_urb);
 		usb_free_urb(port->interrupt_in_urb);
 	}
+	if (port->interrupt_out_urb) {
+		usb_unlink_urb(port->interrupt_out_urb);
+		usb_free_urb(port->interrupt_out_urb);
+	}
 	kfree(port->bulk_in_buffer);
 	kfree(port->bulk_out_buffer);
 	kfree(port->interrupt_in_buffer);
+	kfree(port->interrupt_out_buffer);
 	kfree(port);
 }
 
@@ -862,6 +872,7 @@
 	struct usb_host_interface *iface_desc;
 	struct usb_endpoint_descriptor *endpoint;
 	struct usb_endpoint_descriptor *interrupt_in_endpoint[MAX_NUM_PORTS];
+	struct usb_endpoint_descriptor *interrupt_out_endpoint[MAX_NUM_PORTS];
 	struct usb_endpoint_descriptor *bulk_in_endpoint[MAX_NUM_PORTS];
 	struct usb_endpoint_descriptor *bulk_out_endpoint[MAX_NUM_PORTS];
 	struct usb_serial_device_type *type = NULL;
@@ -872,6 +883,7 @@
 	int buffer_size;
 	int i;
 	int num_interrupt_in = 0;
+	int num_interrupt_out = 0;
 	int num_bulk_in = 0;
 	int num_bulk_out = 0;
 	int num_ports = 0;
@@ -928,7 +940,7 @@
 		if ((endpoint->bEndpointAddress & 0x80) &&
 		    ((endpoint->bmAttributes & 3) == 0x02)) {
 			/* we found a bulk in endpoint */
-			dbg("found bulk in");
+			dbg("found bulk in on endpoint %d", i);
 			bulk_in_endpoint[num_bulk_in] = endpoint;
 			++num_bulk_in;
 		}
@@ -936,7 +948,7 @@
 		if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
 		    ((endpoint->bmAttributes & 3) == 0x02)) {
 			/* we found a bulk out endpoint */
-			dbg("found bulk out");
+			dbg("found bulk out on endpoint %d", i);
 			bulk_out_endpoint[num_bulk_out] = endpoint;
 			++num_bulk_out;
 		}
@@ -944,10 +956,18 @@
 		if ((endpoint->bEndpointAddress & 0x80) &&
 		    ((endpoint->bmAttributes & 3) == 0x03)) {
 			/* we found a interrupt in endpoint */
-			dbg("found interrupt in");
+			dbg("found interrupt in on endpoint %d", i);
 			interrupt_in_endpoint[num_interrupt_in] = endpoint;
 			++num_interrupt_in;
 		}
+
+		if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
+		    ((endpoint->bmAttributes & 3) == 0x03)) {
+			/* we found an interrupt out endpoint */
+			dbg("found interrupt out on endpoint %d", i);
+			interrupt_out_endpoint[num_interrupt_out] = endpoint;
+			++num_interrupt_out;
+		}
 	}
 
 #if defined(CONFIG_USB_SERIAL_PL2303) || defined(CONFIG_USB_SERIAL_PL2303_MODULE)
@@ -1024,11 +1044,13 @@
 	serial->num_bulk_in = num_bulk_in;
 	serial->num_bulk_out = num_bulk_out;
 	serial->num_interrupt_in = num_interrupt_in;
+	serial->num_interrupt_out = num_interrupt_out;
 
 	/* create our ports, we need as many as the max endpoints */
 	/* we don't use num_ports here cauz some devices have more endpoint pairs than \
ports */  max_endpoints = max(num_bulk_in, num_bulk_out);
 	max_endpoints = max(max_endpoints, num_interrupt_in);
+	max_endpoints = max(max_endpoints, num_interrupt_out);
 	max_endpoints = max(max_endpoints, (int)serial->num_ports);
 	serial->num_port_pointers = max_endpoints;
 	dbg("%s - setting up %d port structures for this device", __FUNCTION__, \
max_endpoints); @@ -1091,29 +1113,61 @@
 				   port);
 	}
 
-	for (i = 0; i < num_interrupt_in; ++i) {
-		endpoint = interrupt_in_endpoint[i];
-		port = serial->port[i];
-		port->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
-		if (!port->interrupt_in_urb) {
-			dev_err(&interface->dev, "No free urbs available\n");
-			goto probe_error;
+	if (serial->type->read_int_callback) {
+		for (i = 0; i < num_interrupt_in; ++i) {
+			endpoint = interrupt_in_endpoint[i];
+			port = serial->port[i];
+			port->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
+			if (!port->interrupt_in_urb) {
+				dev_err(&interface->dev, "No free urbs available\n");
+				goto probe_error;
+			}
+			buffer_size = endpoint->wMaxPacketSize;
+			port->interrupt_in_endpointAddress = endpoint->bEndpointAddress;
+			port->interrupt_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
+			if (!port->interrupt_in_buffer) {
+				dev_err(&interface->dev, "Couldn't allocate interrupt_in_buffer\n");
+				goto probe_error;
+			}
+			usb_fill_int_urb (port->interrupt_in_urb, dev, 
+					  usb_rcvintpipe (dev,
+							  endpoint->bEndpointAddress),
+					  port->interrupt_in_buffer, buffer_size, 
+					  serial->type->read_int_callback, port, 
+					  endpoint->bInterval);
 		}
-		buffer_size = endpoint->wMaxPacketSize;
-		port->interrupt_in_endpointAddress = endpoint->bEndpointAddress;
-		port->interrupt_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
-		if (!port->interrupt_in_buffer) {
-			dev_err(&interface->dev, "Couldn't allocate interrupt_in_buffer\n");
-			goto probe_error;
+	} else if (num_interrupt_in) {
+		dbg("the device claims to support interrupt in transfers, but read_int_callback is \
not defined"); +	}
+	
+	if (serial->type->write_int_callback) {
+		for (i = 0; i < num_interrupt_out; ++i) {
+			endpoint = interrupt_out_endpoint[i];
+			port = serial->port[i];
+			port->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL);
+			if (!port->interrupt_out_urb) {
+				dev_err(&interface->dev, "No free urbs available\n");
+				goto probe_error;
+			}
+			buffer_size = endpoint->wMaxPacketSize;
+			port->interrupt_out_size = buffer_size;
+			port->interrupt_out_endpointAddress = endpoint->bEndpointAddress;
+			port->interrupt_out_buffer = kmalloc (buffer_size, GFP_KERNEL);
+			if (!port->interrupt_out_buffer) {
+				dev_err(&interface->dev, "Couldn't allocate interrupt_out_buffer\n");
+				goto probe_error;
+			}
+			usb_fill_int_urb (port->interrupt_out_urb, dev,
+					  usb_sndintpipe (dev,
+							  endpoint->bEndpointAddress),
+					  port->interrupt_out_buffer, buffer_size,
+					  serial->type->write_int_callback, port,
+					  endpoint->bInterval);
 		}
-		usb_fill_int_urb (port->interrupt_in_urb, dev, 
-				  usb_rcvintpipe (dev,
-						  endpoint->bEndpointAddress),
-				  port->interrupt_in_buffer, buffer_size, 
-				  serial->type->read_int_callback, port, 
-				  endpoint->bInterval);
+	} else if (num_interrupt_out) {
+		dbg("the device claims to support interrupt out transfers, but write_int_callback \
is not defined");  }
-
+	
 	/* if this device type has an attach function, call it */
 	if (type->attach) {
 		if (!try_module_get(type->owner)) {
@@ -1176,6 +1230,14 @@
 			usb_free_urb (port->interrupt_in_urb);
 		kfree(port->interrupt_in_buffer);
 	}
+	for (i = 0; i < num_interrupt_out; ++i) {
+		port = serial->port[i];
+		if (!port)
+			continue;
+		if (port->interrupt_out_urb)
+			usb_free_urb (port->interrupt_out_urb);
+		kfree(port->interrupt_out_buffer);
+	}
 
 	/* return the minor range that this device had */
 	return_serial (serial);
--- a/drivers/usb/serial/usb-serial.h	2004-08-14 05:56:25.000000000 -0500
+++ b/drivers/usb/serial/usb-serial.h	2004-09-30 16:19:50.242602104 -0500
@@ -74,6 +74,11 @@
  * @interrupt_in_urb: pointer to the interrupt in struct urb for this port.
  * @interrupt_in_endpointAddress: endpoint address for the interrupt in pipe
  *	for this port.
+ * @interrupt_out_buffer: pointer to the interrupt out buffer for this port.
+ * @interrupt_out_size: the size of the interrupt_out_buffer, in bytes.
+ * @interrupt_out_urb: pointer to the interrupt out struct urb for this port.
+ * @interrupt_out_endpointAddress: endpoint address for the interrupt out pipe
+ * 	for this port.
  * @bulk_in_buffer: pointer to the bulk in buffer for this port.
  * @read_urb: pointer to the bulk in struct urb for this port.
  * @bulk_in_endpointAddress: endpoint address for the bulk in pipe for this
@@ -99,6 +104,11 @@
 	struct urb *		interrupt_in_urb;
 	__u8			interrupt_in_endpointAddress;
 
+	unsigned char *		interrupt_out_buffer;
+	int			interrupt_out_size;
+	struct urb *		interrupt_out_urb;
+	__u8			interrupt_out_endpointAddress;
+
 	unsigned char *		bulk_in_buffer;
 	struct urb *		read_urb;
 	__u8			bulk_in_endpointAddress;
@@ -134,6 +144,7 @@
  * @minor: the starting minor number for this device
  * @num_ports: the number of ports this device has
  * @num_interrupt_in: number of interrupt in endpoints we have
+ * @num_interrupt_out: number of interrupt out endpoints we have
  * @num_bulk_in: number of bulk in endpoints we have
  * @num_bulk_out: number of bulk out endpoints we have
  * @vendor: vendor id of this device
@@ -152,6 +163,7 @@
 	unsigned char			num_ports;
 	unsigned char			num_port_pointers;
 	char				num_interrupt_in;
+	char				num_interrupt_out;
 	char				num_bulk_in;
 	char				num_bulk_out;
 	__u16				vendor;
@@ -187,6 +199,8 @@
  *	of the devices this structure can support.
  * @num_interrupt_in: the number of interrupt in endpoints this device will
  *	have.
+ * @num_interrupt_out: the number of interrupt out endpoints this device will
+ *	have.
  * @num_bulk_in: the number of bulk in endpoints this device will have.
  * @num_bulk_out: the number of bulk out endpoints this device will have.
  * @num_ports: the number of different ports this device will have.
@@ -219,6 +233,7 @@
 	char	*short_name;
 	const struct usb_device_id *id_table;
 	char	num_interrupt_in;
+	char	num_interrupt_out;
 	char	num_bulk_in;
 	char	num_bulk_out;
 	char	num_ports;
@@ -250,6 +265,7 @@
 	int  (*tiocmset)	(struct usb_serial_port *port, struct file *file, unsigned int \
set, unsigned int clear);  
 	void (*read_int_callback)(struct urb *urb, struct pt_regs *regs);
+	void (*write_int_callback)(struct urb *urb, struct pt_regs *regs);
 	void (*read_bulk_callback)(struct urb *urb, struct pt_regs *regs);
 	void (*write_bulk_callback)(struct urb *urb, struct pt_regs *regs);
 };


-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
http://productguide.itmanagersjournal.com/guidepromo.tmpl
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic