Hello,
This patch adds support for interrupt_out to match the existing
interrupt_in support in usb-serial. I thought that it would be cleaner in
the long run to have the support here as to reproducing similar
functionality in (possibly many) other places.
It also adds a few more debugging messages, and makes a few existing ones
more specific. (I needed them for writing a driver, it is likely someone
else might need them under similar conditions.)
Thank you,
-Neil-
diff -ur ../linux-2.6.0-test5.dist/drivers/usb/serial/usb-serial.c
./drivers/usb/serial/usb-serial.c
--- ../linux-2.6.0-test5.dist/drivers/usb/serial/usb-serial.c Mon Sep 8 12:50:02
2003
+++ ./drivers/usb/serial/usb-serial.c Thu Sep 25 19:47:06 2003
@@ -14,6 +14,11 @@
*
* See Documentation/usb/usb-serial.txt for more information on using this driver
*
+ * (09/25/2003) nw
+ * Added support interrupt_out to match the existing interrupt_in support.
+ * Added a few more debugging messages, made a few existing ones more
+ * specific.
+ *
* (12/10/2002) gkh
* Split the ports off into their own struct device, and added a
* usb-serial bus driver.
@@ -894,9 +899,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);
}
}
@@ -927,9 +937,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);
}
@@ -967,6 +982,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;
@@ -977,6 +993,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;
@@ -1026,14 +1043,16 @@
/* descriptor matches, let's find the endpoints needed */
/* check out the endpoints */
+ dbg("checking for endpoints");
iface_desc = &interface->altsetting[0];
+ dbg("this device claims to have %d endpoints",iface_desc->desc.bNumEndpoints);
for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
endpoint = &iface_desc->endpoint[i].desc;
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;
}
@@ -1041,7 +1060,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;
}
@@ -1049,12 +1068,19 @@
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 a interrupt out endpoint */
+ dbg("found interrupt out on endpoint %d",i);
+ interrupt_out_endpoint[num_interrupt_out] = endpoint;
+ ++num_interrupt_out;
+ }
}
-
+ dbg("found %d bulk_in, %d bulk_out, %d interrupt_in %d interrupt_out",
num_bulk_in, num_bulk_out, num_interrupt_in, num_interrupt_out);
#if defined(CONFIG_USB_SERIAL_PL2303) || defined(CONFIG_USB_SERIAL_PL2303_MODULE)
/* BEGIN HORRIBLE HACK FOR PL2303 */
/* this is needed due to the looney way its endpoints are set up */
@@ -1129,11 +1155,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);
@@ -1220,6 +1248,32 @@
endpoint->bInterval);
}
+ 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);
+ }
+
+
+
/* if this device type has an attach function, call it */
if (type->attach) {
if (!try_module_get(type->owner)) {
@@ -1281,6 +1335,14 @@
if (port->interrupt_in_urb)
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 */
diff -ur ../linux-2.6.0-test5.dist/drivers/usb/serial/usb-serial.h
./drivers/usb/serial/usb-serial.h
--- ../linux-2.6.0-test5.dist/drivers/usb/serial/usb-serial.h Mon Sep 8 12:51:01
2003
+++ ./drivers/usb/serial/usb-serial.h Sun Sep 21 18:44:28 2003
@@ -77,6 +77,8 @@
* @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_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
@@ -103,6 +105,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;
@@ -139,6 +146,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
@@ -158,6 +166,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;
@@ -193,6 +202,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.
@@ -225,6 +236,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;
@@ -256,6 +268,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:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel