[PATCH 08/12] USB: kobil_sct: use port interrupt-out urb

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Use the port interrupt-out urb rather than abusing the port write_urb
pointer and allocating a new urb at every open (but the first...).

Note that the write_urb abuse would have led to a double free should
there ever be interfaces with a bulk-out endpoint.

Signed-off-by: Johan Hovold <jhovold@xxxxxxxxx>
---
 drivers/usb/serial/kobil_sct.c | 75 +++++-------------------------------------
 1 file changed, 8 insertions(+), 67 deletions(-)

diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
index 5bcfd57..78b48c3 100644
--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -65,7 +65,7 @@ static int  kobil_tiocmget(struct tty_struct *tty);
 static int  kobil_tiocmset(struct tty_struct *tty,
 			   unsigned int set, unsigned int clear);
 static void kobil_read_int_callback(struct urb *urb);
-static void kobil_write_callback(struct urb *purb);
+static void kobil_write_int_callback(struct urb *urb);
 static void kobil_set_termios(struct tty_struct *tty,
 			struct usb_serial_port *port, struct ktermios *old);
 static void kobil_init_termios(struct tty_struct *tty);
@@ -99,6 +99,7 @@ static struct usb_serial_driver kobil_device = {
 	.write =		kobil_write,
 	.write_room =		kobil_write_room,
 	.read_int_callback =	kobil_read_int_callback,
+	.write_int_callback =	kobil_write_int_callback,
 };
 
 static struct usb_serial_driver * const serial_drivers[] = {
@@ -106,7 +107,6 @@ static struct usb_serial_driver * const serial_drivers[] = {
 };
 
 struct kobil_private {
-	int write_int_endpoint_address;
 	unsigned char buf[KOBIL_BUF_LENGTH]; /* buffer for the APDU to send */
 	int filled;  /* index of the last char in buf */
 	int cur_pos; /* index of the next char to send in buf */
@@ -116,14 +116,8 @@ struct kobil_private {
 
 static int kobil_port_probe(struct usb_serial_port *port)
 {
-	int i;
 	struct usb_serial *serial = port->serial;
 	struct kobil_private *priv;
-	struct usb_device *pdev;
-	struct usb_host_config *actconfig;
-	struct usb_interface *interface;
-	struct usb_host_interface *altsetting;
-	struct usb_host_endpoint *endpoint;
 
 	priv = kmalloc(sizeof(struct kobil_private), GFP_KERNEL);
 	if (!priv)
@@ -149,23 +143,6 @@ static int kobil_port_probe(struct usb_serial_port *port)
 	}
 	usb_set_serial_port_data(port, priv);
 
-	/* search for the necessary endpoints */
-	pdev = serial->dev;
-	actconfig = pdev->actconfig;
-	interface = actconfig->interface[0];
-	altsetting = interface->cur_altsetting;
-	endpoint = altsetting->endpoint;
-
-	for (i = 0; i < altsetting->desc.bNumEndpoints; i++) {
-		endpoint = &altsetting->endpoint[i];
-		if (usb_endpoint_is_int_out(&endpoint->desc)) {
-			dev_dbg(&serial->dev->dev,
-				"%s Found interrupt out endpoint. Address: %d\n",
-				__func__, endpoint->desc.bEndpointAddress);
-			priv->write_int_endpoint_address =
-				endpoint->desc.bEndpointAddress;
-		}
-	}
 	return 0;
 }
 
@@ -197,7 +174,6 @@ static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port)
 	struct kobil_private *priv;
 	unsigned char *transfer_buffer;
 	int transfer_buffer_length = 8;
-	int write_urb_transfer_buffer_length = 8;
 
 	priv = usb_get_serial_port_data(port);
 
@@ -206,27 +182,6 @@ static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port)
 	if (!transfer_buffer)
 		return -ENOMEM;
 
-	/* allocate write_urb */
-	if (!port->write_urb) {
-		dev_dbg(dev, "%s - Allocating port->write_urb\n", __func__);
-		port->write_urb = usb_alloc_urb(0, GFP_KERNEL);
-		if (!port->write_urb) {
-			dev_dbg(dev, "%s - usb_alloc_urb failed\n", __func__);
-			kfree(transfer_buffer);
-			return -ENOMEM;
-		}
-	}
-
-	/* allocate memory for write_urb transfer buffer */
-	port->write_urb->transfer_buffer =
-			kmalloc(write_urb_transfer_buffer_length, GFP_KERNEL);
-	if (!port->write_urb->transfer_buffer) {
-		kfree(transfer_buffer);
-		usb_free_urb(port->write_urb);
-		port->write_urb = NULL;
-		return -ENOMEM;
-	}
-
 	/* get hardware version */
 	result = usb_control_msg(port->serial->dev,
 			  usb_rcvctrlpipe(port->serial->dev, 0),
@@ -302,12 +257,7 @@ static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port)
 static void kobil_close(struct usb_serial_port *port)
 {
 	/* FIXME: Add rts/dtr methods */
-	if (port->write_urb) {
-		usb_poison_urb(port->write_urb);
-		kfree(port->write_urb->transfer_buffer);
-		usb_free_urb(port->write_urb);
-		port->write_urb = NULL;
-	}
+	usb_kill_urb(port->interrupt_out_urb);
 	usb_kill_urb(port->interrupt_in_urb);
 }
 
@@ -336,7 +286,7 @@ static void kobil_read_int_callback(struct urb *urb)
 }
 
 
-static void kobil_write_callback(struct urb *purb)
+static void kobil_write_int_callback(struct urb *urb)
 {
 }
 
@@ -379,23 +329,14 @@ static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port,
 
 		while (todo > 0) {
 			/* max 8 byte in one urb (endpoint size) */
-			length = (todo < 8) ? todo : 8;
+			length = min(todo, port->interrupt_out_size);
 			/* copy data to transfer buffer */
-			memcpy(port->write_urb->transfer_buffer,
+			memcpy(port->interrupt_out_buffer,
 					priv->buf + priv->cur_pos, length);
-			usb_fill_int_urb(port->write_urb,
-				  port->serial->dev,
-				  usb_sndintpipe(port->serial->dev,
-					priv->write_int_endpoint_address),
-				  port->write_urb->transfer_buffer,
-				  length,
-				  kobil_write_callback,
-				  port,
-				  8
-			);
+			port->interrupt_out_urb->transfer_buffer_length = length;
 
 			priv->cur_pos = priv->cur_pos + length;
-			result = usb_submit_urb(port->write_urb, GFP_NOIO);
+			result = usb_submit_urb(port->interrupt_out_urb, GFP_NOIO);
 			dev_dbg(&port->dev, "%s - Send write URB returns: %i\n", __func__, result);
 			todo = priv->filled - priv->cur_pos;
 
-- 
1.8.1.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux