Commit feb0a36a authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman

USB: kobil_sct: use port interrupt-out urb

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: default avatarJohan Hovold <jhovold@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 9c0343aa
...@@ -65,7 +65,7 @@ static int kobil_tiocmget(struct tty_struct *tty); ...@@ -65,7 +65,7 @@ static int kobil_tiocmget(struct tty_struct *tty);
static int kobil_tiocmset(struct tty_struct *tty, static int kobil_tiocmset(struct tty_struct *tty,
unsigned int set, unsigned int clear); unsigned int set, unsigned int clear);
static void kobil_read_int_callback(struct urb *urb); 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, static void kobil_set_termios(struct tty_struct *tty,
struct usb_serial_port *port, struct ktermios *old); struct usb_serial_port *port, struct ktermios *old);
static void kobil_init_termios(struct tty_struct *tty); static void kobil_init_termios(struct tty_struct *tty);
...@@ -99,6 +99,7 @@ static struct usb_serial_driver kobil_device = { ...@@ -99,6 +99,7 @@ static struct usb_serial_driver kobil_device = {
.write = kobil_write, .write = kobil_write,
.write_room = kobil_write_room, .write_room = kobil_write_room,
.read_int_callback = kobil_read_int_callback, .read_int_callback = kobil_read_int_callback,
.write_int_callback = kobil_write_int_callback,
}; };
static struct usb_serial_driver * const serial_drivers[] = { static struct usb_serial_driver * const serial_drivers[] = {
...@@ -106,7 +107,6 @@ static struct usb_serial_driver * const serial_drivers[] = { ...@@ -106,7 +107,6 @@ static struct usb_serial_driver * const serial_drivers[] = {
}; };
struct kobil_private { struct kobil_private {
int write_int_endpoint_address;
unsigned char buf[KOBIL_BUF_LENGTH]; /* buffer for the APDU to send */ unsigned char buf[KOBIL_BUF_LENGTH]; /* buffer for the APDU to send */
int filled; /* index of the last char in buf */ int filled; /* index of the last char in buf */
int cur_pos; /* index of the next char to send in buf */ int cur_pos; /* index of the next char to send in buf */
...@@ -116,14 +116,8 @@ struct kobil_private { ...@@ -116,14 +116,8 @@ struct kobil_private {
static int kobil_port_probe(struct usb_serial_port *port) static int kobil_port_probe(struct usb_serial_port *port)
{ {
int i;
struct usb_serial *serial = port->serial; struct usb_serial *serial = port->serial;
struct kobil_private *priv; 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); priv = kmalloc(sizeof(struct kobil_private), GFP_KERNEL);
if (!priv) if (!priv)
...@@ -149,23 +143,6 @@ static int kobil_port_probe(struct usb_serial_port *port) ...@@ -149,23 +143,6 @@ static int kobil_port_probe(struct usb_serial_port *port)
} }
usb_set_serial_port_data(port, priv); 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; return 0;
} }
...@@ -197,7 +174,6 @@ static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -197,7 +174,6 @@ static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port)
struct kobil_private *priv; struct kobil_private *priv;
unsigned char *transfer_buffer; unsigned char *transfer_buffer;
int transfer_buffer_length = 8; int transfer_buffer_length = 8;
int write_urb_transfer_buffer_length = 8;
priv = usb_get_serial_port_data(port); priv = usb_get_serial_port_data(port);
...@@ -206,27 +182,6 @@ static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -206,27 +182,6 @@ static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port)
if (!transfer_buffer) if (!transfer_buffer)
return -ENOMEM; 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 */ /* get hardware version */
result = usb_control_msg(port->serial->dev, result = usb_control_msg(port->serial->dev,
usb_rcvctrlpipe(port->serial->dev, 0), usb_rcvctrlpipe(port->serial->dev, 0),
...@@ -302,12 +257,7 @@ static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -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) static void kobil_close(struct usb_serial_port *port)
{ {
/* FIXME: Add rts/dtr methods */ /* FIXME: Add rts/dtr methods */
if (port->write_urb) { usb_kill_urb(port->interrupt_out_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_in_urb); usb_kill_urb(port->interrupt_in_urb);
} }
...@@ -336,7 +286,7 @@ static void kobil_read_int_callback(struct urb *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, ...@@ -379,23 +329,14 @@ static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port,
while (todo > 0) { while (todo > 0) {
/* max 8 byte in one urb (endpoint size) */ /* 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 */ /* copy data to transfer buffer */
memcpy(port->write_urb->transfer_buffer, memcpy(port->interrupt_out_buffer,
priv->buf + priv->cur_pos, length); priv->buf + priv->cur_pos, length);
usb_fill_int_urb(port->write_urb, port->interrupt_out_urb->transfer_buffer_length = length;
port->serial->dev,
usb_sndintpipe(port->serial->dev,
priv->write_int_endpoint_address),
port->write_urb->transfer_buffer,
length,
kobil_write_callback,
port,
8
);
priv->cur_pos = priv->cur_pos + 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); dev_dbg(&port->dev, "%s - Send write URB returns: %i\n", __func__, result);
todo = priv->filled - priv->cur_pos; todo = priv->filled - priv->cur_pos;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment