aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorElina Pasheva <epasheva@sierrawireless.com>2009-04-29 13:26:46 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-06-16 00:44:45 -0400
commit40d2ff32f102e69d482480265ec60ffb86b028de (patch)
treee296e28a1139c3f785328e043c112332764ca584 /drivers/usb
parente05b8e6e1066e7583dbb6b00407508797b737995 (diff)
USB: serial: sierra driver write path improvements
- Updated Copyright notice with new authors names - Version number set to 1.3.6 - Added a MAX_TRANSFER constant following Greg Kroah-Hartman's recommended setting of PAGE_SIZE-512 for USB transfer buffers and modified accordingly sierra_write() function. Signed-off-by: Elina Pasheva <epasheva@sierrawireless.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/serial/sierra.c52
1 files changed, 35 insertions, 17 deletions
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index f75688416b65..27f41f95aefb 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -1,7 +1,10 @@
1/* 1/*
2 USB Driver for Sierra Wireless 2 USB Driver for Sierra Wireless
3 3
4 Copyright (C) 2006, 2007, 2008 Kevin Lloyd <klloyd@sierrawireless.com> 4 Copyright (C) 2006, 2007, 2008 Kevin Lloyd <klloyd@sierrawireless.com>,
5
6 Copyright (C) 2008, 2009 Elina Pasheva, Matthew Safar, Rory Filer
7 <linux@sierrawireless.com>
5 8
6 IMPORTANT DISCLAIMER: This driver is not commercially supported by 9 IMPORTANT DISCLAIMER: This driver is not commercially supported by
7 Sierra Wireless. Use at your own risk. 10 Sierra Wireless. Use at your own risk.
@@ -14,8 +17,8 @@
14 Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> 17 Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org>
15*/ 18*/
16 19
17#define DRIVER_VERSION "v.1.3.5" 20#define DRIVER_VERSION "v.1.3.6"
18#define DRIVER_AUTHOR "Kevin Lloyd <klloyd@sierrawireless.com>" 21#define DRIVER_AUTHOR "Kevin Lloyd, Elina Pasheva, Matthew Safar, Rory Filer"
19#define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" 22#define DRIVER_DESC "USB Driver for Sierra Wireless USB modems"
20 23
21#include <linux/kernel.h> 24#include <linux/kernel.h>
@@ -34,6 +37,11 @@
34#define N_OUT_URB 64 37#define N_OUT_URB 64
35#define IN_BUFLEN 4096 38#define IN_BUFLEN 4096
36 39
40#define MAX_TRANSFER (PAGE_SIZE - 512)
41/* MAX_TRANSFER is chosen so that the VM is not stressed by
42 allocations > PAGE_SIZE and the number of packets in a page
43 is an integer 512 is the largest possible packet on EHCI */
44
37static int debug; 45static int debug;
38static int nmea; 46static int nmea;
39 47
@@ -419,50 +427,58 @@ static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port,
419 unsigned long flags; 427 unsigned long flags;
420 unsigned char *buffer; 428 unsigned char *buffer;
421 struct urb *urb; 429 struct urb *urb;
422 int status; 430 size_t writesize = min((size_t)count, (size_t)MAX_TRANSFER);
431 int retval = 0;
432
433 /* verify that we actually have some data to write */
434 if (count == 0)
435 return 0;
423 436
424 portdata = usb_get_serial_port_data(port); 437 portdata = usb_get_serial_port_data(port);
425 438
426 dev_dbg(&port->dev, "%s: write (%d chars)\n", __func__, count); 439 dev_dbg(&port->dev, "%s: write (%d bytes)\n", __func__, writesize);
427 440
428 spin_lock_irqsave(&portdata->lock, flags); 441 spin_lock_irqsave(&portdata->lock, flags);
442 dev_dbg(&port->dev, "%s - outstanding_urbs: %d\n", __func__,
443 portdata->outstanding_urbs);
429 if (portdata->outstanding_urbs > N_OUT_URB) { 444 if (portdata->outstanding_urbs > N_OUT_URB) {
430 spin_unlock_irqrestore(&portdata->lock, flags); 445 spin_unlock_irqrestore(&portdata->lock, flags);
431 dev_dbg(&port->dev, "%s - write limit hit\n", __func__); 446 dev_dbg(&port->dev, "%s - write limit hit\n", __func__);
432 return 0; 447 return 0;
433 } 448 }
434 portdata->outstanding_urbs++; 449 portdata->outstanding_urbs++;
450 dev_dbg(&port->dev, "%s - 1, outstanding_urbs: %d\n", __func__,
451 portdata->outstanding_urbs);
435 spin_unlock_irqrestore(&portdata->lock, flags); 452 spin_unlock_irqrestore(&portdata->lock, flags);
436 453
437 buffer = kmalloc(count, GFP_ATOMIC); 454 buffer = kmalloc(writesize, GFP_ATOMIC);
438 if (!buffer) { 455 if (!buffer) {
439 dev_err(&port->dev, "out of memory\n"); 456 dev_err(&port->dev, "out of memory\n");
440 count = -ENOMEM; 457 retval = -ENOMEM;
441 goto error_no_buffer; 458 goto error_no_buffer;
442 } 459 }
443 460
444 urb = usb_alloc_urb(0, GFP_ATOMIC); 461 urb = usb_alloc_urb(0, GFP_ATOMIC);
445 if (!urb) { 462 if (!urb) {
446 dev_err(&port->dev, "no more free urbs\n"); 463 dev_err(&port->dev, "no more free urbs\n");
447 count = -ENOMEM; 464 retval = -ENOMEM;
448 goto error_no_urb; 465 goto error_no_urb;
449 } 466 }
450 467
451 memcpy(buffer, buf, count); 468 memcpy(buffer, buf, writesize);
452 469
453 usb_serial_debug_data(debug, &port->dev, __func__, count, buffer); 470 usb_serial_debug_data(debug, &port->dev, __func__, writesize, buffer);
454 471
455 usb_fill_bulk_urb(urb, serial->dev, 472 usb_fill_bulk_urb(urb, serial->dev,
456 usb_sndbulkpipe(serial->dev, 473 usb_sndbulkpipe(serial->dev,
457 port->bulk_out_endpointAddress), 474 port->bulk_out_endpointAddress),
458 buffer, count, sierra_outdat_callback, port); 475 buffer, writesize, sierra_outdat_callback, port);
459 476
460 /* send it down the pipe */ 477 /* send it down the pipe */
461 status = usb_submit_urb(urb, GFP_ATOMIC); 478 retval = usb_submit_urb(urb, GFP_ATOMIC);
462 if (status) { 479 if (retval) {
463 dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed " 480 dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed "
464 "with status = %d\n", __func__, status); 481 "with status = %d\n", __func__, retval);
465 count = status;
466 goto error; 482 goto error;
467 } 483 }
468 484
@@ -470,7 +486,7 @@ static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port,
470 * really free it when it is finished with it */ 486 * really free it when it is finished with it */
471 usb_free_urb(urb); 487 usb_free_urb(urb);
472 488
473 return count; 489 return writesize;
474error: 490error:
475 usb_free_urb(urb); 491 usb_free_urb(urb);
476error_no_urb: 492error_no_urb:
@@ -478,8 +494,10 @@ error_no_urb:
478error_no_buffer: 494error_no_buffer:
479 spin_lock_irqsave(&portdata->lock, flags); 495 spin_lock_irqsave(&portdata->lock, flags);
480 --portdata->outstanding_urbs; 496 --portdata->outstanding_urbs;
497 dev_dbg(&port->dev, "%s - 2. outstanding_urbs: %d\n", __func__,
498 portdata->outstanding_urbs);
481 spin_unlock_irqrestore(&portdata->lock, flags); 499 spin_unlock_irqrestore(&portdata->lock, flags);
482 return count; 500 return retval;
483} 501}
484 502
485static void sierra_indat_callback(struct urb *urb) 503static void sierra_indat_callback(struct urb *urb)