Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 174925
b: refs/heads/master
c: 3a2b808
h: refs/heads/master
i:
  174923: 13151de
v: v3
  • Loading branch information
Elina Pasheva authored and Greg Kroah-Hartman committed Dec 11, 2009
1 parent a834581 commit 7279e1f
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 13 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: b97503ffa79f0a4aa13c7cd8b449b98d3077c78f
refs/heads/master: 3a2b808e95287c8235e25a833fda3dad3e9853ef
89 changes: 77 additions & 12 deletions trunk/drivers/usb/serial/sierra.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
Portions based on the option driver by Matthias Urlichs <smurf@smurf.noris.de>
Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org>
*/

#define DRIVER_VERSION "v.1.3.8"
/* Uncomment to log function calls */
/* #define DEBUG */
#define DRIVER_VERSION "v.1.7.16"
#define DRIVER_AUTHOR "Kevin Lloyd, Elina Pasheva, Matthew Safar, Rory Filer"
#define DRIVER_DESC "USB Driver for Sierra Wireless USB modems"

Expand All @@ -33,8 +34,10 @@
#define SWIMS_USB_REQUEST_SetPower 0x00
#define SWIMS_USB_REQUEST_SetNmea 0x07

#define N_IN_URB 8
#define N_OUT_URB 64
#define N_IN_URB_HM 8
#define N_OUT_URB_HM 64
#define N_IN_URB 4
#define N_OUT_URB 4
#define IN_BUFLEN 4096

#define MAX_TRANSFER (PAGE_SIZE - 512)
Expand Down Expand Up @@ -124,6 +127,23 @@ static int is_blacklisted(const u8 ifnum,
return 0;
}

static int is_himemory(const u8 ifnum,
const struct sierra_iface_info *himemorylist)
{
const u8 *info;
int i;

if (himemorylist) {
info = himemorylist->ifaceinfo;

for (i=0; i < himemorylist->infolen; i++) {
if (info[i] == ifnum)
return 1;
}
}
return 0;
}

static int sierra_calc_interface(struct usb_serial *serial)
{
int interface;
Expand Down Expand Up @@ -186,6 +206,20 @@ static int sierra_probe(struct usb_serial *serial,
return result;
}

/* interfaces with higher memory requirements */
static const u8 hi_memory_typeA_ifaces[] = { 0, 2 };
static const struct sierra_iface_info typeA_interface_list = {
.infolen = ARRAY_SIZE(hi_memory_typeA_ifaces),
.ifaceinfo = hi_memory_typeA_ifaces,
};

static const u8 hi_memory_typeB_ifaces[] = { 3, 4, 5, 6 };
static const struct sierra_iface_info typeB_interface_list = {
.infolen = ARRAY_SIZE(hi_memory_typeB_ifaces),
.ifaceinfo = hi_memory_typeB_ifaces,
};

/* 'blacklist' of interfaces not served by this driver */
static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11 };
static const struct sierra_iface_info direct_ip_interface_blacklist = {
.infolen = ARRAY_SIZE(direct_ip_non_serial_ifaces),
Expand Down Expand Up @@ -286,8 +320,10 @@ struct sierra_port_private {
struct usb_anchor active;
struct usb_anchor delayed;

int num_out_urbs;
int num_in_urbs;
/* Input endpoints and buffers for this port */
struct urb *in_urbs[N_IN_URB];
struct urb *in_urbs[N_IN_URB_HM];

/* Settings for the port */
int rts_state; /* Handshaking pins (outputs) */
Expand Down Expand Up @@ -460,7 +496,7 @@ static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port,
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) {
if (portdata->outstanding_urbs > portdata->num_out_urbs) {
spin_unlock_irqrestore(&portdata->lock, flags);
dev_dbg(&port->dev, "%s - write limit hit\n", __func__);
return 0;
Expand Down Expand Up @@ -665,7 +701,7 @@ static int sierra_write_room(struct tty_struct *tty)
/* try to give a good number back based on if we have any free urbs at
* this point in time */
spin_lock_irqsave(&portdata->lock, flags);
if (portdata->outstanding_urbs > N_OUT_URB * 2 / 3) {
if (portdata->outstanding_urbs > (portdata->num_out_urbs * 2) / 3) {
spin_unlock_irqrestore(&portdata->lock, flags);
dev_dbg(&port->dev, "%s - write limit hit\n", __func__);
return 0;
Expand All @@ -680,7 +716,7 @@ static void sierra_stop_rx_urbs(struct usb_serial_port *port)
int i;
struct sierra_port_private *portdata = usb_get_serial_port_data(port);

for (i = 0; i < ARRAY_SIZE(portdata->in_urbs); i++)
for (i = 0; i < portdata->num_in_urbs; i++)
usb_kill_urb(portdata->in_urbs[i]);

usb_kill_urb(port->interrupt_in_urb);
Expand All @@ -695,7 +731,7 @@ static int sierra_submit_rx_urbs(struct usb_serial_port *port, gfp_t mem_flags)
struct sierra_port_private *portdata = usb_get_serial_port_data(port);

ok_cnt = 0;
for (i = 0; i < ARRAY_SIZE(portdata->in_urbs); i++) {
for (i = 0; i < portdata->num_in_urbs; i++) {
urb = portdata->in_urbs[i];
if (!urb)
continue;
Expand Down Expand Up @@ -791,7 +827,7 @@ static void sierra_close(struct usb_serial_port *port)
/* Stop reading urbs */
sierra_stop_rx_urbs(port);
/* .. and release them */
for (i = 0; i < N_IN_URB; i++) {
for (i = 0; i < portdata->num_in_urbs; i++) {
sierra_release_urb(portdata->in_urbs[i]);
portdata->in_urbs[i] = NULL;
}
Expand All @@ -818,7 +854,7 @@ static int sierra_open(struct tty_struct *tty, struct usb_serial_port *port)


endpoint = port->bulk_in_endpointAddress;
for (i = 0; i < ARRAY_SIZE(portdata->in_urbs); i++) {
for (i = 0; i < portdata->num_in_urbs; i++) {
urb = sierra_setup_urb(serial, endpoint, USB_DIR_IN, port,
IN_BUFLEN, GFP_KERNEL,
sierra_indat_callback);
Expand Down Expand Up @@ -869,7 +905,9 @@ static int sierra_startup(struct usb_serial *serial)
{
struct usb_serial_port *port;
struct sierra_port_private *portdata;
struct sierra_iface_info *himemoryp = NULL;
int i;
u8 ifnum;

dev_dbg(&serial->dev->dev, "%s\n", __func__);

Expand All @@ -886,13 +924,40 @@ static int sierra_startup(struct usb_serial *serial)
portdata = kzalloc(sizeof(*portdata), GFP_KERNEL);
if (!portdata) {
dev_dbg(&port->dev, "%s: kmalloc for "
"sierra_port_private (%d) failed!.\n",
"sierra_port_private (%d) failed!\n",
__func__, i);
return -ENOMEM;
}
spin_lock_init(&portdata->lock);
init_usb_anchor(&portdata->active);
init_usb_anchor(&portdata->delayed);
ifnum = i;
/* Assume low memory requirements */
portdata->num_out_urbs = N_OUT_URB;
portdata->num_in_urbs = N_IN_URB;

/* Determine actual memory requirements */
if (serial->num_ports == 1) {
/* Get interface number for composite device */
ifnum = sierra_calc_interface(serial);
himemoryp =
(struct sierra_iface_info *)&typeB_interface_list;
if (is_himemory(ifnum, himemoryp)) {
portdata->num_out_urbs = N_OUT_URB_HM;
portdata->num_in_urbs = N_IN_URB_HM;
}
}
else {
himemoryp =
(struct sierra_iface_info *)&typeA_interface_list;
if (is_himemory(i, himemoryp)) {
portdata->num_out_urbs = N_OUT_URB_HM;
portdata->num_in_urbs = N_IN_URB_HM;
}
}
dev_dbg(&serial->dev->dev,
"Memory usage (urbs) interface #%d, in=%d, out=%d\n",
ifnum,portdata->num_in_urbs, portdata->num_out_urbs );
/* Set the port private data pointer */
usb_set_serial_port_data(port, portdata);
}
Expand Down

0 comments on commit 7279e1f

Please sign in to comment.