From: Elina <epasheva@sierrawireless.com>
To: <gregkh@suse.de>
Cc: <rfiler@sierrawireless.com>, <linux-kernel@vger.kernel.org>
Subject: [PATCH 002/003] USB: serial: sierra driver blacklisting
Date: Mon, 6 Apr 2009 17:05:58 -0700 [thread overview]
Message-ID: <1239062758.10120.37.camel@Linuxdev3> (raw)
Subject: [PATCH 002/003] USB: serial: sierra driver blacklisting
From: Elina Pasheva <epasheva@sierrawireless.com>
The series of 3 patches modify sierra usb serial driver with
blacklisting of specific non-serial interfaces, bug fixing and
performance improvements.
This is [PATCH 002/003]. This patch depends on [PATCH 001/003].
The following is summary of changes we have made to sierra.c driver in
[PATCH 02/03] dealing with blacklisting:
- Added blacklist for specific non-serial interfaces.
- Removed potential kernel oops from sierra_calc_num_ports() function.
Calling this function twice would likely have caused an oops because the
function releases allocated memory after the first call.
- Modified sierra_probe() function to reflect the changes in
sierra_calc_num_ports().
Signed-off-by: Elina Pasheva <epasheva@sierrawireless.com>
---
drivers/usb/serial/sierra.c | 83 ++++++++++++++++++++--------------
1 file changed, 51 insertions(+), 32 deletions(-)
--- a/drivers/usb/serial/sierra.c 2009-03-27 15:39:09.000000000 -0700
+++ b/drivers/usb/serial/sierra.c 2009-03-27 16:26:23.000000000 -0700
@@ -47,6 +47,12 @@
static int debug;
static int nmea;
+/* list of interface numbers - used for constructing interface blacklists */
+struct list {
+ const u32 listlen; /* number of interface numbers on list */
+ const u8 *list; /* pointer to the array holding the numbers */
+};
+
static int sierra_set_power_state(struct usb_device *udev, __u16 swiState)
{
int result;
@@ -79,18 +85,38 @@ static int sierra_vsc_set_nmea(struct us
static int sierra_calc_num_ports(struct usb_serial *serial)
{
- int result;
- int *num_ports = usb_get_serial_data(serial);
- dev_dbg(&serial->dev->dev, "%s", __func__);
+ int num_ports = 0;
+ u8 ifnum, numendpoints;
- result = *num_ports;
+ dev_dbg(&serial->dev->dev, "%s\n", __func__);
- if (result) {
- kfree(num_ports);
- usb_set_serial_data(serial, NULL);
- }
+ ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
+ numendpoints = serial->interface->cur_altsetting->desc.bNumEndpoints;
- return result;
+ /* Dummy interface present on some SKUs should be ignored */
+ if (ifnum == 0x99)
+ num_ports = 0;
+ else if (numendpoints <= 3)
+ num_ports = 1;
+ else
+ num_ports = (numendpoints-1)/2;
+ return num_ports;
+}
+
+static int is_blacklisted(const u8 ifnum, const struct list *blacklist)
+{
+ const u8 *list;
+ int i;
+
+ if (blacklist) {
+ list = blacklist->list;
+
+ for (i = 0; i < blacklist->listlen; i++) {
+ if (list[i] == ifnum)
+ return 1;
+ }
+ }
+ return 0;
}
static int sierra_calc_interface(struct usb_serial *serial)
@@ -119,23 +145,12 @@ static int sierra_probe(struct usb_seria
{
int result = 0;
struct usb_device *udev;
- int *num_ports;
u8 ifnum;
- u8 numendpoints;
-
- dev_dbg(&serial->dev->dev, "%s", __func__);
-
- num_ports = kmalloc(sizeof(*num_ports), GFP_KERNEL);
- if (!num_ports)
- return -ENOMEM;
- ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
- numendpoints = serial->interface->cur_altsetting->desc.bNumEndpoints;
udev = serial->dev;
/* Figure out the interface number from the serial structure */
ifnum = sierra_calc_interface(serial);
-
/*
* If this interface supports more than 1 alternate
* select the 2nd one
@@ -147,23 +162,24 @@ static int sierra_probe(struct usb_seria
usb_set_interface(udev, ifnum, 1);
}
- /* Dummy interface present on some SKUs should be ignored */
- if (ifnum == 0x99)
- *num_ports = 0;
- else if (numendpoints <= 3)
- *num_ports = 1;
- else
- *num_ports = (numendpoints-1)/2;
+ /* ifnum could have changed - by calling usb_set_interface */
+ ifnum = sierra_calc_interface(serial);
- /*
- * save off our num_ports info so that we can use it in the
- * calc_num_ports callback
- */
- usb_set_serial_data(serial, (void *)num_ports);
+ if (is_blacklisted(ifnum, (struct list *)id->driver_info)) {
+ dev_dbg(&serial->dev->dev,
+ "Ignoring blacklisted interface #%d\n", ifnum);
+ return -ENODEV;
+ }
return result;
}
+static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9 };
+static const struct list direct_ip_interface_blacklist = {
+ .listlen = ARRAY_SIZE(direct_ip_non_serial_ifaces),
+ .list = direct_ip_non_serial_ifaces,
+};
+
static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */
{ USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */
@@ -221,6 +237,9 @@ static struct usb_device_id id_table []
{ USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */
{ USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */
+ { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */
+ .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
+ },
{ }
};
MODULE_DEVICE_TABLE(usb, id_table);
next reply other threads:[~2009-04-07 0:23 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-04-07 0:05 Elina [this message]
2009-04-07 1:02 ` [PATCH 002/003] USB: serial: sierra driver blacklisting Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1239062758.10120.37.camel@Linuxdev3 \
--to=epasheva@sierrawireless.com \
--cc=gregkh@suse.de \
--cc=linux-kernel@vger.kernel.org \
--cc=rfiler@sierrawireless.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.