Commit af59cf40 authored by Pete Zaitcev's avatar Pete Zaitcev Committed by Greg Kroah-Hartman

USB: Fix error cleanup path in airprime

Fix up the error processing path: in usb_submit_urb failed, we forgot
to free buffers. Also, don't free buffers in read callback: less error
prone, 21 LOC less, no need to comment so much. N.B. write path is ok
to do kfree.
Signed-off-by: default avatarPete Zaitcev <zaitcev@redhat.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 23004e24
...@@ -58,11 +58,6 @@ static void airprime_read_bulk_callback(struct urb *urb) ...@@ -58,11 +58,6 @@ static void airprime_read_bulk_callback(struct urb *urb)
if (urb->status) { if (urb->status) {
dbg("%s - nonzero read bulk status received: %d", dbg("%s - nonzero read bulk status received: %d",
__FUNCTION__, urb->status); __FUNCTION__, urb->status);
/* something happened, so free up the memory for this urb */
if (urb->transfer_buffer) {
kfree (urb->transfer_buffer);
urb->transfer_buffer = NULL;
}
return; return;
} }
usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
...@@ -146,6 +141,8 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp) ...@@ -146,6 +141,8 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp)
airprime_read_bulk_callback, port); airprime_read_bulk_callback, port);
result = usb_submit_urb(urb, GFP_KERNEL); result = usb_submit_urb(urb, GFP_KERNEL);
if (result) { if (result) {
usb_free_urb(urb);
kfree(buffer);
dev_err(&port->dev, dev_err(&port->dev,
"%s - failed submitting read urb %d for port %d, error %d\n", "%s - failed submitting read urb %d for port %d, error %d\n",
__FUNCTION__, i, port->number, result); __FUNCTION__, i, port->number, result);
...@@ -160,27 +157,12 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp) ...@@ -160,27 +157,12 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp)
/* some error happened, cancel any submitted urbs and clean up anything that /* some error happened, cancel any submitted urbs and clean up anything that
got allocated successfully */ got allocated successfully */
for ( ; i >= 0; --i) { while (i-- != 0) {
urb = priv->read_urbp[i]; urb = priv->read_urbp[i];
if (urb) { buffer = urb->transfer_buffer;
/* This urb was submitted successfully. So we have to usb_kill_urb (urb);
cancel it. usb_free_urb (urb);
Unlinking the urb will invoke read_bulk_callback() kfree (buffer);
with an error status, so its transfer buffer will
be freed there */
if (usb_unlink_urb (urb) != -EINPROGRESS) {
/* comments in drivers/usb/core/urb.c say this
can only happen if the urb was never submitted,
or has completed already.
Either way we may have to free the transfer
buffer here. */
if (urb->transfer_buffer) {
kfree (urb->transfer_buffer);
urb->transfer_buffer = NULL;
}
}
usb_free_urb (urb);
}
} }
out: out:
...@@ -194,10 +176,9 @@ static void airprime_close(struct usb_serial_port *port, struct file * filp) ...@@ -194,10 +176,9 @@ static void airprime_close(struct usb_serial_port *port, struct file * filp)
dbg("%s - port %d", __FUNCTION__, port->number); dbg("%s - port %d", __FUNCTION__, port->number);
/* killing the urb will invoke read_bulk_callback() with an error status,
so the transfer buffer will be freed there */
for (i = 0; i < NUM_READ_URBS; ++i) { for (i = 0; i < NUM_READ_URBS; ++i) {
usb_kill_urb (priv->read_urbp[i]); usb_kill_urb (priv->read_urbp[i]);
kfree (priv->read_urbp[i]->transfer_buffer);
usb_free_urb (priv->read_urbp[i]); usb_free_urb (priv->read_urbp[i]);
} }
......
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