aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/generic.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2005-04-23 15:49:16 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-06-27 17:43:47 -0400
commit507ca9bc0476662f3463888d583864834eab1e11 (patch)
tree421a373de235fcb4cb46a4723a1e9f00a71f709a /drivers/usb/serial/generic.c
parentf4df0e334a9fc731689e8ba4f42a0d72a7491348 (diff)
[PATCH] USB: add ability for usb-serial drivers to determine if their write urb is currently being used.
This removes a lot of racy and buggy code by trying to check the status of the urb. Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/serial/generic.c')
-rw-r--r--drivers/usb/serial/generic.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 99214aa3cd19..ddde5fb13f6b 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -174,10 +174,14 @@ int usb_serial_generic_write(struct usb_serial_port *port, const unsigned char *
174 174
175 /* only do something if we have a bulk out endpoint */ 175 /* only do something if we have a bulk out endpoint */
176 if (serial->num_bulk_out) { 176 if (serial->num_bulk_out) {
177 if (port->write_urb->status == -EINPROGRESS) { 177 spin_lock(&port->lock);
178 if (port->write_urb_busy) {
179 spin_unlock(&port->lock);
178 dbg("%s - already writing", __FUNCTION__); 180 dbg("%s - already writing", __FUNCTION__);
179 return (0); 181 return 0;
180 } 182 }
183 port->write_urb_busy = 1;
184 spin_unlock(&port->lock);
181 185
182 count = (count > port->bulk_out_size) ? port->bulk_out_size : count; 186 count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
183 187
@@ -195,17 +199,20 @@ int usb_serial_generic_write(struct usb_serial_port *port, const unsigned char *
195 usb_serial_generic_write_bulk_callback), port); 199 usb_serial_generic_write_bulk_callback), port);
196 200
197 /* send the data out the bulk port */ 201 /* send the data out the bulk port */
202 port->write_urb_busy = 1;
198 result = usb_submit_urb(port->write_urb, GFP_ATOMIC); 203 result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
199 if (result) 204 if (result) {
200 dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result); 205 dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result);
201 else 206 /* don't have to grab the lock here, as we will retry if != 0 */
207 port->write_urb_busy = 0;
208 } else
202 result = count; 209 result = count;
203 210
204 return result; 211 return result;
205 } 212 }
206 213
207 /* no bulk out, so return 0 bytes written */ 214 /* no bulk out, so return 0 bytes written */
208 return (0); 215 return 0;
209} 216}
210 217
211int usb_serial_generic_write_room (struct usb_serial_port *port) 218int usb_serial_generic_write_room (struct usb_serial_port *port)
@@ -214,9 +221,9 @@ int usb_serial_generic_write_room (struct usb_serial_port *port)
214 int room = 0; 221 int room = 0;
215 222
216 dbg("%s - port %d", __FUNCTION__, port->number); 223 dbg("%s - port %d", __FUNCTION__, port->number);
217 224
218 if (serial->num_bulk_out) { 225 if (serial->num_bulk_out) {
219 if (port->write_urb->status != -EINPROGRESS) 226 if (port->write_urb_busy)
220 room = port->bulk_out_size; 227 room = port->bulk_out_size;
221 } 228 }
222 229
@@ -232,7 +239,7 @@ int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port)
232 dbg("%s - port %d", __FUNCTION__, port->number); 239 dbg("%s - port %d", __FUNCTION__, port->number);
233 240
234 if (serial->num_bulk_out) { 241 if (serial->num_bulk_out) {
235 if (port->write_urb->status == -EINPROGRESS) 242 if (port->write_urb_busy)
236 chars = port->write_urb->transfer_buffer_length; 243 chars = port->write_urb->transfer_buffer_length;
237 } 244 }
238 245
@@ -291,6 +298,7 @@ void usb_serial_generic_write_bulk_callback (struct urb *urb, struct pt_regs *re
291 298
292 dbg("%s - port %d", __FUNCTION__, port->number); 299 dbg("%s - port %d", __FUNCTION__, port->number);
293 300
301 port->write_urb_busy = 0;
294 if (urb->status) { 302 if (urb->status) {
295 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); 303 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
296 return; 304 return;