diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2005-04-23 15:49:16 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2005-06-27 17:43:47 -0400 |
commit | 507ca9bc0476662f3463888d583864834eab1e11 (patch) | |
tree | 421a373de235fcb4cb46a4723a1e9f00a71f709a /drivers/usb/serial/omninet.c | |
parent | f4df0e334a9fc731689e8ba4f42a0d72a7491348 (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/omninet.c')
-rw-r--r-- | drivers/usb/serial/omninet.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index b5f2c06d4f3e..6a99ae192df1 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c | |||
@@ -254,10 +254,15 @@ static int omninet_write (struct usb_serial_port *port, const unsigned char *buf | |||
254 | dbg("%s - write request of 0 bytes", __FUNCTION__); | 254 | dbg("%s - write request of 0 bytes", __FUNCTION__); |
255 | return (0); | 255 | return (0); |
256 | } | 256 | } |
257 | if (wport->write_urb->status == -EINPROGRESS) { | 257 | |
258 | spin_lock(&port->lock); | ||
259 | if (port->write_urb_busy) { | ||
260 | spin_unlock(&port->lock); | ||
258 | dbg("%s - already writing", __FUNCTION__); | 261 | dbg("%s - already writing", __FUNCTION__); |
259 | return (0); | 262 | return 0; |
260 | } | 263 | } |
264 | port->write_urb_busy = 1; | ||
265 | spin_unlock(&port->lock); | ||
261 | 266 | ||
262 | count = (count > OMNINET_BULKOUTSIZE) ? OMNINET_BULKOUTSIZE : count; | 267 | count = (count > OMNINET_BULKOUTSIZE) ? OMNINET_BULKOUTSIZE : count; |
263 | 268 | ||
@@ -275,9 +280,10 @@ static int omninet_write (struct usb_serial_port *port, const unsigned char *buf | |||
275 | 280 | ||
276 | wport->write_urb->dev = serial->dev; | 281 | wport->write_urb->dev = serial->dev; |
277 | result = usb_submit_urb(wport->write_urb, GFP_ATOMIC); | 282 | result = usb_submit_urb(wport->write_urb, GFP_ATOMIC); |
278 | if (result) | 283 | if (result) { |
284 | port->write_urb_busy = 0; | ||
279 | err("%s - failed submitting write urb, error %d", __FUNCTION__, result); | 285 | err("%s - failed submitting write urb, error %d", __FUNCTION__, result); |
280 | else | 286 | } else |
281 | result = count; | 287 | result = count; |
282 | 288 | ||
283 | return result; | 289 | return result; |
@@ -291,7 +297,7 @@ static int omninet_write_room (struct usb_serial_port *port) | |||
291 | 297 | ||
292 | int room = 0; // Default: no room | 298 | int room = 0; // Default: no room |
293 | 299 | ||
294 | if (wport->write_urb->status != -EINPROGRESS) | 300 | if (wport->write_urb_busy) |
295 | room = wport->bulk_out_size - OMNINET_HEADERLEN; | 301 | room = wport->bulk_out_size - OMNINET_HEADERLEN; |
296 | 302 | ||
297 | // dbg("omninet_write_room returns %d", room); | 303 | // dbg("omninet_write_room returns %d", room); |
@@ -306,6 +312,7 @@ static void omninet_write_bulk_callback (struct urb *urb, struct pt_regs *regs) | |||
306 | 312 | ||
307 | // dbg("omninet_write_bulk_callback, port %0x\n", port); | 313 | // dbg("omninet_write_bulk_callback, port %0x\n", port); |
308 | 314 | ||
315 | port->write_urb_busy = 0; | ||
309 | if (urb->status) { | 316 | if (urb->status) { |
310 | dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); | 317 | dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); |
311 | return; | 318 | return; |