1
1
/*
2
2
* USB Serial Converter Generic functions
3
3
*
4
- * Copyright (C) 2010 Johan Hovold ([email protected] )
4
+ * Copyright (C) 2010 - 2011 Johan Hovold ([email protected] )
5
5
* Copyright (C) 1999 - 2002 Greg Kroah-Hartman ([email protected] )
6
6
*
7
7
* This program is free software; you can redistribute it and/or
@@ -132,7 +132,7 @@ int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port
132
132
133
133
/* if we have a bulk endpoint, start reading from it */
134
134
if (port -> bulk_in_size )
135
- result = usb_serial_generic_submit_read_urb (port , GFP_KERNEL );
135
+ result = usb_serial_generic_submit_read_urbs (port , GFP_KERNEL );
136
136
137
137
return result ;
138
138
}
@@ -157,8 +157,10 @@ static void generic_cleanup(struct usb_serial_port *port)
157
157
kfifo_reset_out (& port -> write_fifo );
158
158
spin_unlock_irqrestore (& port -> lock , flags );
159
159
}
160
- if (port -> bulk_in_size )
161
- usb_kill_urb (port -> read_urb );
160
+ if (port -> bulk_in_size ) {
161
+ for (i = 0 ; i < ARRAY_SIZE (port -> read_urbs ); ++ i )
162
+ usb_kill_urb (port -> read_urbs [i ]);
163
+ }
162
164
}
163
165
}
164
166
@@ -308,19 +310,52 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty)
308
310
return chars ;
309
311
}
310
312
311
- int usb_serial_generic_submit_read_urb (struct usb_serial_port * port ,
313
+ static int usb_serial_generic_submit_read_urb (struct usb_serial_port * port ,
314
+ int index , gfp_t mem_flags )
315
+ {
316
+ int res ;
317
+
318
+ if (!test_and_clear_bit (index , & port -> read_urbs_free ))
319
+ return 0 ;
320
+
321
+ dbg ("%s - port %d, urb %d\n" , __func__ , port -> number , index );
322
+
323
+ res = usb_submit_urb (port -> read_urbs [index ], mem_flags );
324
+ if (res ) {
325
+ if (res != - EPERM ) {
326
+ dev_err (& port -> dev ,
327
+ "%s - usb_submit_urb failed: %d\n" ,
328
+ __func__ , res );
329
+ }
330
+ set_bit (index , & port -> read_urbs_free );
331
+ return res ;
332
+ }
333
+
334
+ return 0 ;
335
+ }
336
+
337
+ int usb_serial_generic_submit_read_urbs (struct usb_serial_port * port ,
312
338
gfp_t mem_flags )
313
339
{
314
- int result ;
340
+ int res ;
341
+ int i ;
315
342
316
- result = usb_submit_urb (port -> read_urb , mem_flags );
317
- if (result && result != - EPERM ) {
318
- dev_err (& port -> dev , "%s - error submitting urb: %d\n" ,
319
- __func__ , result );
343
+ dbg ("%s - port %d" , __func__ , port -> number );
344
+
345
+ for (i = 0 ; i < ARRAY_SIZE (port -> read_urbs ); ++ i ) {
346
+ res = usb_serial_generic_submit_read_urb (port , i , mem_flags );
347
+ if (res )
348
+ goto err ;
320
349
}
321
- return result ;
350
+
351
+ return 0 ;
352
+ err :
353
+ for (; i >= 0 ; -- i )
354
+ usb_kill_urb (port -> read_urbs [i ]);
355
+
356
+ return res ;
322
357
}
323
- EXPORT_SYMBOL_GPL (usb_serial_generic_submit_read_urb );
358
+ EXPORT_SYMBOL_GPL (usb_serial_generic_submit_read_urbs );
324
359
325
360
void usb_serial_generic_process_read_urb (struct urb * urb )
326
361
{
@@ -356,14 +391,19 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb)
356
391
{
357
392
struct usb_serial_port * port = urb -> context ;
358
393
unsigned char * data = urb -> transfer_buffer ;
359
- int status = urb -> status ;
360
394
unsigned long flags ;
395
+ int i ;
361
396
362
- dbg ("%s - port %d" , __func__ , port -> number );
397
+ for (i = 0 ; i < ARRAY_SIZE (port -> read_urbs ); ++ i ) {
398
+ if (urb == port -> read_urbs [i ])
399
+ break ;
400
+ }
401
+ set_bit (i , & port -> read_urbs_free );
363
402
364
- if (unlikely (status != 0 )) {
365
- dbg ("%s - nonzero read bulk status received: %d" ,
366
- __func__ , status );
403
+ dbg ("%s - port %d, urb %d, len %d\n" , __func__ , port -> number , i ,
404
+ urb -> actual_length );
405
+ if (urb -> status ) {
406
+ dbg ("%s - non-zero urb status: %d\n" , __func__ , urb -> status );
367
407
return ;
368
408
}
369
409
@@ -376,7 +416,7 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb)
376
416
port -> throttled = port -> throttle_req ;
377
417
if (!port -> throttled ) {
378
418
spin_unlock_irqrestore (& port -> lock , flags );
379
- usb_serial_generic_submit_read_urb (port , GFP_ATOMIC );
419
+ usb_serial_generic_submit_read_urb (port , i , GFP_ATOMIC );
380
420
} else
381
421
spin_unlock_irqrestore (& port -> lock , flags );
382
422
}
@@ -443,7 +483,7 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty)
443
483
spin_unlock_irq (& port -> lock );
444
484
445
485
if (was_throttled )
446
- usb_serial_generic_submit_read_urb (port , GFP_KERNEL );
486
+ usb_serial_generic_submit_read_urbs (port , GFP_KERNEL );
447
487
}
448
488
EXPORT_SYMBOL_GPL (usb_serial_generic_unthrottle );
449
489
@@ -509,8 +549,9 @@ int usb_serial_generic_resume(struct usb_serial *serial)
509
549
if (!test_bit (ASYNCB_INITIALIZED , & port -> port .flags ))
510
550
continue ;
511
551
512
- if (port -> read_urb ) {
513
- r = usb_submit_urb (port -> read_urb , GFP_NOIO );
552
+ if (port -> bulk_in_size ) {
553
+ r = usb_serial_generic_submit_read_urbs (port ,
554
+ GFP_NOIO );
514
555
if (r < 0 )
515
556
c ++ ;
516
557
}
0 commit comments