Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 151362
b: refs/heads/master
c: 40d2ff3
h: refs/heads/master
v: v3
  • Loading branch information
Elina Pasheva authored and Greg Kroah-Hartman committed Jun 16, 2009
1 parent 13a8662 commit a649c7c
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 18 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e05b8e6e1066e7583dbb6b00407508797b737995
refs/heads/master: 40d2ff32f102e69d482480265ec60ffb86b028de
52 changes: 35 additions & 17 deletions trunk/drivers/usb/serial/sierra.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
/*
USB Driver for Sierra Wireless
Copyright (C) 2006, 2007, 2008 Kevin Lloyd <klloyd@sierrawireless.com>
Copyright (C) 2006, 2007, 2008 Kevin Lloyd <klloyd@sierrawireless.com>,
Copyright (C) 2008, 2009 Elina Pasheva, Matthew Safar, Rory Filer
<linux@sierrawireless.com>
IMPORTANT DISCLAIMER: This driver is not commercially supported by
Sierra Wireless. Use at your own risk.
Expand All @@ -14,8 +17,8 @@
Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org>
*/

#define DRIVER_VERSION "v.1.3.5"
#define DRIVER_AUTHOR "Kevin Lloyd <klloyd@sierrawireless.com>"
#define DRIVER_VERSION "v.1.3.6"
#define DRIVER_AUTHOR "Kevin Lloyd, Elina Pasheva, Matthew Safar, Rory Filer"
#define DRIVER_DESC "USB Driver for Sierra Wireless USB modems"

#include <linux/kernel.h>
Expand All @@ -34,6 +37,11 @@
#define N_OUT_URB 64
#define IN_BUFLEN 4096

#define MAX_TRANSFER (PAGE_SIZE - 512)
/* MAX_TRANSFER is chosen so that the VM is not stressed by
allocations > PAGE_SIZE and the number of packets in a page
is an integer 512 is the largest possible packet on EHCI */

static int debug;
static int nmea;

Expand Down Expand Up @@ -419,67 +427,77 @@ static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port,
unsigned long flags;
unsigned char *buffer;
struct urb *urb;
int status;
size_t writesize = min((size_t)count, (size_t)MAX_TRANSFER);
int retval = 0;

/* verify that we actually have some data to write */
if (count == 0)
return 0;

portdata = usb_get_serial_port_data(port);

dev_dbg(&port->dev, "%s: write (%d chars)\n", __func__, count);
dev_dbg(&port->dev, "%s: write (%d bytes)\n", __func__, writesize);

spin_lock_irqsave(&portdata->lock, flags);
dev_dbg(&port->dev, "%s - outstanding_urbs: %d\n", __func__,
portdata->outstanding_urbs);
if (portdata->outstanding_urbs > N_OUT_URB) {
spin_unlock_irqrestore(&portdata->lock, flags);
dev_dbg(&port->dev, "%s - write limit hit\n", __func__);
return 0;
}
portdata->outstanding_urbs++;
dev_dbg(&port->dev, "%s - 1, outstanding_urbs: %d\n", __func__,
portdata->outstanding_urbs);
spin_unlock_irqrestore(&portdata->lock, flags);

buffer = kmalloc(count, GFP_ATOMIC);
buffer = kmalloc(writesize, GFP_ATOMIC);
if (!buffer) {
dev_err(&port->dev, "out of memory\n");
count = -ENOMEM;
retval = -ENOMEM;
goto error_no_buffer;
}

urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!urb) {
dev_err(&port->dev, "no more free urbs\n");
count = -ENOMEM;
retval = -ENOMEM;
goto error_no_urb;
}

memcpy(buffer, buf, count);
memcpy(buffer, buf, writesize);

usb_serial_debug_data(debug, &port->dev, __func__, count, buffer);
usb_serial_debug_data(debug, &port->dev, __func__, writesize, buffer);

usb_fill_bulk_urb(urb, serial->dev,
usb_sndbulkpipe(serial->dev,
port->bulk_out_endpointAddress),
buffer, count, sierra_outdat_callback, port);
buffer, writesize, sierra_outdat_callback, port);

/* send it down the pipe */
status = usb_submit_urb(urb, GFP_ATOMIC);
if (status) {
retval = usb_submit_urb(urb, GFP_ATOMIC);
if (retval) {
dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed "
"with status = %d\n", __func__, status);
count = status;
"with status = %d\n", __func__, retval);
goto error;
}

/* we are done with this urb, so let the host driver
* really free it when it is finished with it */
usb_free_urb(urb);

return count;
return writesize;
error:
usb_free_urb(urb);
error_no_urb:
kfree(buffer);
error_no_buffer:
spin_lock_irqsave(&portdata->lock, flags);
--portdata->outstanding_urbs;
dev_dbg(&port->dev, "%s - 2. outstanding_urbs: %d\n", __func__,
portdata->outstanding_urbs);
spin_unlock_irqrestore(&portdata->lock, flags);
return count;
return retval;
}

static void sierra_indat_callback(struct urb *urb)
Expand Down

0 comments on commit a649c7c

Please sign in to comment.