aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial
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
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')
-rw-r--r--drivers/usb/serial/cyberjack.c19
-rw-r--r--drivers/usb/serial/generic.c24
-rw-r--r--drivers/usb/serial/ipaq.c5
-rw-r--r--drivers/usb/serial/ipw.c14
-rw-r--r--drivers/usb/serial/ir-usb.c16
-rw-r--r--drivers/usb/serial/keyspan_pda.c19
-rw-r--r--drivers/usb/serial/omninet.c17
-rw-r--r--drivers/usb/serial/safe_serial.c13
-rw-r--r--drivers/usb/serial/usb-serial.c1
-rw-r--r--drivers/usb/serial/usb-serial.h3
10 files changed, 85 insertions, 46 deletions
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
index 46a204cd40e1..b5b431067b08 100644
--- a/drivers/usb/serial/cyberjack.c
+++ b/drivers/usb/serial/cyberjack.c
@@ -213,10 +213,14 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b
213 return (0); 213 return (0);
214 } 214 }
215 215
216 if (port->write_urb->status == -EINPROGRESS) { 216 spin_lock(&port->lock);
217 if (port->write_urb_busy) {
218 spin_unlock(&port->lock);
217 dbg("%s - already writing", __FUNCTION__); 219 dbg("%s - already writing", __FUNCTION__);
218 return (0); 220 return 0;
219 } 221 }
222 port->write_urb_busy = 1;
223 spin_unlock(&port->lock);
220 224
221 spin_lock_irqsave(&priv->lock, flags); 225 spin_lock_irqsave(&priv->lock, flags);
222 226
@@ -224,6 +228,7 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b
224 /* To much data for buffer. Reset buffer. */ 228 /* To much data for buffer. Reset buffer. */
225 priv->wrfilled=0; 229 priv->wrfilled=0;
226 spin_unlock_irqrestore(&priv->lock, flags); 230 spin_unlock_irqrestore(&priv->lock, flags);
231 port->write_urb_busy = 0;
227 return (0); 232 return (0);
228 } 233 }
229 234
@@ -268,6 +273,7 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b
268 priv->wrfilled=0; 273 priv->wrfilled=0;
269 priv->wrsent=0; 274 priv->wrsent=0;
270 spin_unlock_irqrestore(&priv->lock, flags); 275 spin_unlock_irqrestore(&priv->lock, flags);
276 port->write_urb_busy = 0;
271 return 0; 277 return 0;
272 } 278 }
273 279
@@ -412,7 +418,8 @@ static void cyberjack_write_bulk_callback (struct urb *urb, struct pt_regs *regs
412 struct cyberjack_private *priv = usb_get_serial_port_data(port); 418 struct cyberjack_private *priv = usb_get_serial_port_data(port);
413 419
414 dbg("%s - port %d", __FUNCTION__, port->number); 420 dbg("%s - port %d", __FUNCTION__, port->number);
415 421
422 port->write_urb_busy = 0;
416 if (urb->status) { 423 if (urb->status) {
417 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); 424 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
418 return; 425 return;
@@ -424,12 +431,6 @@ static void cyberjack_write_bulk_callback (struct urb *urb, struct pt_regs *regs
424 if( priv->wrfilled ) { 431 if( priv->wrfilled ) {
425 int length, blksize, result; 432 int length, blksize, result;
426 433
427 if (port->write_urb->status == -EINPROGRESS) {
428 dbg("%s - already writing", __FUNCTION__);
429 spin_unlock(&priv->lock);
430 return;
431 }
432
433 dbg("%s - transmitting data (frame n)", __FUNCTION__); 434 dbg("%s - transmitting data (frame n)", __FUNCTION__);
434 435
435 length = ((priv->wrfilled - priv->wrsent) > port->bulk_out_size) ? 436 length = ((priv->wrfilled - priv->wrsent) > port->bulk_out_size) ?
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;
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index 3bd69c4ef24b..c05c2a2a0f31 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -818,11 +818,6 @@ static void ipaq_write_gather(struct usb_serial_port *port)
818 struct ipaq_packet *pkt, *tmp; 818 struct ipaq_packet *pkt, *tmp;
819 struct urb *urb = port->write_urb; 819 struct urb *urb = port->write_urb;
820 820
821 if (urb->status == -EINPROGRESS) {
822 /* Should never happen */
823 err("%s - flushing while urb is active !", __FUNCTION__);
824 return;
825 }
826 room = URBDATA_SIZE; 821 room = URBDATA_SIZE;
827 list_for_each_entry_safe(pkt, tmp, &priv->queue, list) { 822 list_for_each_entry_safe(pkt, tmp, &priv->queue, list) {
828 count = min(room, (int)(pkt->len - pkt->written)); 823 count = min(room, (int)(pkt->len - pkt->written));
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c
index 11105d74f461..85e242459c27 100644
--- a/drivers/usb/serial/ipw.c
+++ b/drivers/usb/serial/ipw.c
@@ -399,16 +399,21 @@ static int ipw_write(struct usb_serial_port *port, const unsigned char *buf, int
399 dbg("%s - write request of 0 bytes", __FUNCTION__); 399 dbg("%s - write request of 0 bytes", __FUNCTION__);
400 return 0; 400 return 0;
401 } 401 }
402 402
403 /* Racy and broken, FIXME properly! */ 403 spin_lock(&port->lock);
404 if (port->write_urb->status == -EINPROGRESS) 404 if (port->write_urb_busy) {
405 spin_unlock(&port->lock);
406 dbg("%s - already writing", __FUNCTION__);
405 return 0; 407 return 0;
408 }
409 port->write_urb_busy = 1;
410 spin_unlock(&port->lock);
406 411
407 count = min(count, port->bulk_out_size); 412 count = min(count, port->bulk_out_size);
408 memcpy(port->bulk_out_buffer, buf, count); 413 memcpy(port->bulk_out_buffer, buf, count);
409 414
410 dbg("%s count now:%d", __FUNCTION__, count); 415 dbg("%s count now:%d", __FUNCTION__, count);
411 416
412 usb_fill_bulk_urb(port->write_urb, dev, 417 usb_fill_bulk_urb(port->write_urb, dev,
413 usb_sndbulkpipe(dev, port->bulk_out_endpointAddress), 418 usb_sndbulkpipe(dev, port->bulk_out_endpointAddress),
414 port->write_urb->transfer_buffer, 419 port->write_urb->transfer_buffer,
@@ -418,6 +423,7 @@ static int ipw_write(struct usb_serial_port *port, const unsigned char *buf, int
418 423
419 ret = usb_submit_urb(port->write_urb, GFP_ATOMIC); 424 ret = usb_submit_urb(port->write_urb, GFP_ATOMIC);
420 if (ret != 0) { 425 if (ret != 0) {
426 port->write_urb_busy = 0;
421 dbg("%s - usb_submit_urb(write bulk) failed with error = %d", __FUNCTION__, ret); 427 dbg("%s - usb_submit_urb(write bulk) failed with error = %d", __FUNCTION__, ret);
422 return ret; 428 return ret;
423 } 429 }
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
index 59f234df5f89..937b2fdd7171 100644
--- a/drivers/usb/serial/ir-usb.c
+++ b/drivers/usb/serial/ir-usb.c
@@ -341,10 +341,14 @@ static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int
341 if (count == 0) 341 if (count == 0)
342 return 0; 342 return 0;
343 343
344 if (port->write_urb->status == -EINPROGRESS) { 344 spin_lock(&port->lock);
345 dbg ("%s - already writing", __FUNCTION__); 345 if (port->write_urb_busy) {
346 spin_unlock(&port->lock);
347 dbg("%s - already writing", __FUNCTION__);
346 return 0; 348 return 0;
347 } 349 }
350 port->write_urb_busy = 1;
351 spin_unlock(&port->lock);
348 352
349 transfer_buffer = port->write_urb->transfer_buffer; 353 transfer_buffer = port->write_urb->transfer_buffer;
350 transfer_size = min(count, port->bulk_out_size - 1); 354 transfer_size = min(count, port->bulk_out_size - 1);
@@ -374,9 +378,10 @@ static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int
374 port->write_urb->transfer_flags = URB_ZERO_PACKET; 378 port->write_urb->transfer_flags = URB_ZERO_PACKET;
375 379
376 result = usb_submit_urb (port->write_urb, GFP_ATOMIC); 380 result = usb_submit_urb (port->write_urb, GFP_ATOMIC);
377 if (result) 381 if (result) {
382 port->write_urb_busy = 0;
378 dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result); 383 dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result);
379 else 384 } else
380 result = transfer_size; 385 result = transfer_size;
381 386
382 return result; 387 return result;
@@ -387,7 +392,8 @@ static void ir_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
387 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 392 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
388 393
389 dbg("%s - port %d", __FUNCTION__, port->number); 394 dbg("%s - port %d", __FUNCTION__, port->number);
390 395
396 port->write_urb_busy = 0;
391 if (urb->status) { 397 if (urb->status) {
392 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); 398 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
393 return; 399 return;
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index 7fd0aa9eccf6..635c384cb15a 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -520,9 +520,13 @@ static int keyspan_pda_write(struct usb_serial_port *port,
520 the TX urb is in-flight (wait until it completes) 520 the TX urb is in-flight (wait until it completes)
521 the device is full (wait until it says there is room) 521 the device is full (wait until it says there is room)
522 */ 522 */
523 if (port->write_urb->status == -EINPROGRESS || priv->tx_throttled ) { 523 spin_lock(&port->lock);
524 return( 0 ); 524 if (port->write_urb_busy || priv->tx_throttled) {
525 spin_unlock(&port->lock);
526 return 0;
525 } 527 }
528 port->write_urb_busy = 1;
529 spin_unlock(&port->lock);
526 530
527 /* At this point the URB is in our control, nobody else can submit it 531 /* At this point the URB is in our control, nobody else can submit it
528 again (the only sudden transition was the one from EINPROGRESS to 532 again (the only sudden transition was the one from EINPROGRESS to
@@ -570,7 +574,7 @@ static int keyspan_pda_write(struct usb_serial_port *port,
570 memcpy (port->write_urb->transfer_buffer, buf, count); 574 memcpy (port->write_urb->transfer_buffer, buf, count);
571 /* send the data out the bulk port */ 575 /* send the data out the bulk port */
572 port->write_urb->transfer_buffer_length = count; 576 port->write_urb->transfer_buffer_length = count;
573 577
574 priv->tx_room -= count; 578 priv->tx_room -= count;
575 579
576 port->write_urb->dev = port->serial->dev; 580 port->write_urb->dev = port->serial->dev;
@@ -593,6 +597,8 @@ static int keyspan_pda_write(struct usb_serial_port *port,
593 597
594 rc = count; 598 rc = count;
595exit: 599exit:
600 if (rc < 0)
601 port->write_urb_busy = 0;
596 return rc; 602 return rc;
597} 603}
598 604
@@ -602,6 +608,7 @@ static void keyspan_pda_write_bulk_callback (struct urb *urb, struct pt_regs *re
602 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 608 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
603 struct keyspan_pda_private *priv; 609 struct keyspan_pda_private *priv;
604 610
611 port->write_urb_busy = 0;
605 priv = usb_get_serial_port_data(port); 612 priv = usb_get_serial_port_data(port);
606 613
607 /* queue up a wakeup at scheduler time */ 614 /* queue up a wakeup at scheduler time */
@@ -626,12 +633,12 @@ static int keyspan_pda_write_room (struct usb_serial_port *port)
626static int keyspan_pda_chars_in_buffer (struct usb_serial_port *port) 633static int keyspan_pda_chars_in_buffer (struct usb_serial_port *port)
627{ 634{
628 struct keyspan_pda_private *priv; 635 struct keyspan_pda_private *priv;
629 636
630 priv = usb_get_serial_port_data(port); 637 priv = usb_get_serial_port_data(port);
631 638
632 /* when throttled, return at least WAKEUP_CHARS to tell select() (via 639 /* when throttled, return at least WAKEUP_CHARS to tell select() (via
633 n_tty.c:normal_poll() ) that we're not writeable. */ 640 n_tty.c:normal_poll() ) that we're not writeable. */
634 if( port->write_urb->status == -EINPROGRESS || priv->tx_throttled ) 641 if (port->write_urb_busy || priv->tx_throttled)
635 return 256; 642 return 256;
636 return 0; 643 return 0;
637} 644}
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;
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c
index 0e85ed6c6c19..96a17568cbf1 100644
--- a/drivers/usb/serial/safe_serial.c
+++ b/drivers/usb/serial/safe_serial.c
@@ -299,10 +299,14 @@ static int safe_write (struct usb_serial_port *port, const unsigned char *buf, i
299 dbg ("%s - write request of 0 bytes", __FUNCTION__); 299 dbg ("%s - write request of 0 bytes", __FUNCTION__);
300 return (0); 300 return (0);
301 } 301 }
302 if (port->write_urb->status == -EINPROGRESS) { 302 spin_lock(&port->lock);
303 dbg ("%s - already writing", __FUNCTION__); 303 if (port->write_urb_busy) {
304 return (0); 304 spin_unlock(&port->lock);
305 dbg("%s - already writing", __FUNCTION__);
306 return 0;
305 } 307 }
308 port->write_urb_busy = 1;
309 spin_unlock(&port->lock);
306 310
307 packet_length = port->bulk_out_size; // get max packetsize 311 packet_length = port->bulk_out_size; // get max packetsize
308 312
@@ -354,6 +358,7 @@ static int safe_write (struct usb_serial_port *port, const unsigned char *buf, i
354#endif 358#endif
355 port->write_urb->dev = port->serial->dev; 359 port->write_urb->dev = port->serial->dev;
356 if ((result = usb_submit_urb (port->write_urb, GFP_KERNEL))) { 360 if ((result = usb_submit_urb (port->write_urb, GFP_KERNEL))) {
361 port->write_urb_busy = 0;
357 err ("%s - failed submitting write urb, error %d", __FUNCTION__, result); 362 err ("%s - failed submitting write urb, error %d", __FUNCTION__, result);
358 return 0; 363 return 0;
359 } 364 }
@@ -368,7 +373,7 @@ static int safe_write_room (struct usb_serial_port *port)
368 373
369 dbg ("%s", __FUNCTION__); 374 dbg ("%s", __FUNCTION__);
370 375
371 if (port->write_urb->status != -EINPROGRESS) 376 if (port->write_urb_busy)
372 room = port->bulk_out_size - (safe ? 2 : 0); 377 room = port->bulk_out_size - (safe ? 2 : 0);
373 378
374 if (room) { 379 if (room) {
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 5da76dd8fb28..0267b26dde18 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -1047,6 +1047,7 @@ int usb_serial_probe(struct usb_interface *interface,
1047 memset(port, 0x00, sizeof(struct usb_serial_port)); 1047 memset(port, 0x00, sizeof(struct usb_serial_port));
1048 port->number = i + serial->minor; 1048 port->number = i + serial->minor;
1049 port->serial = serial; 1049 port->serial = serial;
1050 spin_lock_init(&port->lock);
1050 INIT_WORK(&port->work, usb_serial_port_softint, port); 1051 INIT_WORK(&port->work, usb_serial_port_softint, port);
1051 serial->port[i] = port; 1052 serial->port[i] = port;
1052 } 1053 }
diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h
index d1f0c4057fa6..57f92f054c75 100644
--- a/drivers/usb/serial/usb-serial.h
+++ b/drivers/usb/serial/usb-serial.h
@@ -69,6 +69,7 @@
69 * usb_serial_port: structure for the specific ports of a device. 69 * usb_serial_port: structure for the specific ports of a device.
70 * @serial: pointer back to the struct usb_serial owner of this port. 70 * @serial: pointer back to the struct usb_serial owner of this port.
71 * @tty: pointer to the corresponding tty for this port. 71 * @tty: pointer to the corresponding tty for this port.
72 * @lock: spinlock to grab when updating portions of this structure.
72 * @number: the number of the port (the minor number). 73 * @number: the number of the port (the minor number).
73 * @interrupt_in_buffer: pointer to the interrupt in buffer for this port. 74 * @interrupt_in_buffer: pointer to the interrupt in buffer for this port.
74 * @interrupt_in_urb: pointer to the interrupt in struct urb for this port. 75 * @interrupt_in_urb: pointer to the interrupt in struct urb for this port.
@@ -98,6 +99,7 @@
98struct usb_serial_port { 99struct usb_serial_port {
99 struct usb_serial * serial; 100 struct usb_serial * serial;
100 struct tty_struct * tty; 101 struct tty_struct * tty;
102 spinlock_t lock;
101 unsigned char number; 103 unsigned char number;
102 104
103 unsigned char * interrupt_in_buffer; 105 unsigned char * interrupt_in_buffer;
@@ -117,6 +119,7 @@ struct usb_serial_port {
117 unsigned char * bulk_out_buffer; 119 unsigned char * bulk_out_buffer;
118 int bulk_out_size; 120 int bulk_out_size;
119 struct urb * write_urb; 121 struct urb * write_urb;
122 int write_urb_busy;
120 __u8 bulk_out_endpointAddress; 123 __u8 bulk_out_endpointAddress;
121 124
122 wait_queue_head_t write_wait; 125 wait_queue_head_t write_wait;