diff options
author | Pete Zaitcev <zaitcev@redhat.com> | 2007-02-03 02:13:14 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-02-16 18:32:18 -0500 |
commit | af59cf404fc7ad6cc642de9e78252fb264917611 (patch) | |
tree | 0c70ca5d995fb1814fffd02ec9a5adb0b6e246d1 /drivers/usb/serial | |
parent | 23004e241ccc03678592a8b392573e8514ec962f (diff) |
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: Pete Zaitcev <zaitcev@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/serial')
-rw-r--r-- | drivers/usb/serial/airprime.c | 35 |
1 files changed, 8 insertions, 27 deletions
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index 0af42e32fa0a..18816bf96a4d 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c | |||
@@ -58,11 +58,6 @@ static void airprime_read_bulk_callback(struct urb *urb) | |||
58 | if (urb->status) { | 58 | if (urb->status) { |
59 | dbg("%s - nonzero read bulk status received: %d", | 59 | dbg("%s - nonzero read bulk status received: %d", |
60 | __FUNCTION__, urb->status); | 60 | __FUNCTION__, urb->status); |
61 | /* something happened, so free up the memory for this urb */ | ||
62 | if (urb->transfer_buffer) { | ||
63 | kfree (urb->transfer_buffer); | ||
64 | urb->transfer_buffer = NULL; | ||
65 | } | ||
66 | return; | 61 | return; |
67 | } | 62 | } |
68 | usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); | 63 | 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 | airprime_read_bulk_callback, port); | 141 | airprime_read_bulk_callback, port); |
147 | result = usb_submit_urb(urb, GFP_KERNEL); | 142 | result = usb_submit_urb(urb, GFP_KERNEL); |
148 | if (result) { | 143 | if (result) { |
144 | usb_free_urb(urb); | ||
145 | kfree(buffer); | ||
149 | dev_err(&port->dev, | 146 | dev_err(&port->dev, |
150 | "%s - failed submitting read urb %d for port %d, error %d\n", | 147 | "%s - failed submitting read urb %d for port %d, error %d\n", |
151 | __FUNCTION__, i, port->number, result); | 148 | __FUNCTION__, i, port->number, result); |
@@ -160,27 +157,12 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp) | |||
160 | /* some error happened, cancel any submitted urbs and clean up anything that | 157 | /* some error happened, cancel any submitted urbs and clean up anything that |
161 | got allocated successfully */ | 158 | got allocated successfully */ |
162 | 159 | ||
163 | for ( ; i >= 0; --i) { | 160 | while (i-- != 0) { |
164 | urb = priv->read_urbp[i]; | 161 | urb = priv->read_urbp[i]; |
165 | if (urb) { | 162 | buffer = urb->transfer_buffer; |
166 | /* This urb was submitted successfully. So we have to | 163 | usb_kill_urb (urb); |
167 | cancel it. | 164 | usb_free_urb (urb); |
168 | Unlinking the urb will invoke read_bulk_callback() | 165 | kfree (buffer); |
169 | with an error status, so its transfer buffer will | ||
170 | be freed there */ | ||
171 | if (usb_unlink_urb (urb) != -EINPROGRESS) { | ||
172 | /* comments in drivers/usb/core/urb.c say this | ||
173 | can only happen if the urb was never submitted, | ||
174 | or has completed already. | ||
175 | Either way we may have to free the transfer | ||
176 | buffer here. */ | ||
177 | if (urb->transfer_buffer) { | ||
178 | kfree (urb->transfer_buffer); | ||
179 | urb->transfer_buffer = NULL; | ||
180 | } | ||
181 | } | ||
182 | usb_free_urb (urb); | ||
183 | } | ||
184 | } | 166 | } |
185 | 167 | ||
186 | out: | 168 | out: |
@@ -194,10 +176,9 @@ static void airprime_close(struct usb_serial_port *port, struct file * filp) | |||
194 | 176 | ||
195 | dbg("%s - port %d", __FUNCTION__, port->number); | 177 | dbg("%s - port %d", __FUNCTION__, port->number); |
196 | 178 | ||
197 | /* killing the urb will invoke read_bulk_callback() with an error status, | ||
198 | so the transfer buffer will be freed there */ | ||
199 | for (i = 0; i < NUM_READ_URBS; ++i) { | 179 | for (i = 0; i < NUM_READ_URBS; ++i) { |
200 | usb_kill_urb (priv->read_urbp[i]); | 180 | usb_kill_urb (priv->read_urbp[i]); |
181 | kfree (priv->read_urbp[i]->transfer_buffer); | ||
201 | usb_free_urb (priv->read_urbp[i]); | 182 | usb_free_urb (priv->read_urbp[i]); |
202 | } | 183 | } |
203 | 184 | ||