aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorElina Pasheva <epasheva@sierrawireless.com>2009-06-11 09:32:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-11 11:51:07 -0400
commit4db2299da213d1ba8cf7f4c0a197ae7ba49db5cb (patch)
treeedb02c370e4a1e69f20d88b9ec2c9780eba196d8 /drivers/usb
parentb9a44bc19f48fd82b8f411500a9bb0ea4153d23c (diff)
sierra: driver interface blacklisting
Interface blacklisting is necessary for non-serial interfaces that are handled by a different driver. The interface blacklisting is implemented in sierra driver per device. Each device in need of a blacklist has a static information array kept in the driver. This array contains the interface numbers that are blacklisted. The pointer for each blacklist array and the length of that blacklist are 'bundled' in data structure sierra_iface_info. A pointer to this information is set in id_table when the device is added to the id_table. The following is summary of changes we have made to sierra.c driver in this patch dealing with interface blacklisting support: - Added data structure sierra_iface_info and function is_blacklisted() to support blacklisting - Modified sierra_probe() to handle blacklisted interfaces accordingly - Improved comments in id_table - Added new device in id_table with blacklist interface support Signed-off-by: Elina Pasheva <epasheva@sierrawireless.com> Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/serial/sierra.c51
1 files changed, 48 insertions, 3 deletions
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 88ec7bfd9d35..17ac34f4d668 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -37,6 +37,12 @@
37static int debug; 37static int debug;
38static int nmea; 38static int nmea;
39 39
40/* Used in interface blacklisting */
41struct sierra_iface_info {
42 const u32 infolen; /* number of interface numbers on blacklist */
43 const u8 *ifaceinfo; /* pointer to the array holding the numbers */
44};
45
40static int sierra_set_power_state(struct usb_device *udev, __u16 swiState) 46static int sierra_set_power_state(struct usb_device *udev, __u16 swiState)
41{ 47{
42 int result; 48 int result;
@@ -83,6 +89,23 @@ static int sierra_calc_num_ports(struct usb_serial *serial)
83 return result; 89 return result;
84} 90}
85 91
92static int is_blacklisted(const u8 ifnum,
93 const struct sierra_iface_info *blacklist)
94{
95 const u8 *info;
96 int i;
97
98 if (blacklist) {
99 info = blacklist->ifaceinfo;
100
101 for (i = 0; i < blacklist->infolen; i++) {
102 if (info[i] == ifnum)
103 return 1;
104 }
105 }
106 return 0;
107}
108
86static int sierra_calc_interface(struct usb_serial *serial) 109static int sierra_calc_interface(struct usb_serial *serial)
87{ 110{
88 int interface; 111 int interface;
@@ -151,9 +174,25 @@ static int sierra_probe(struct usb_serial *serial,
151 */ 174 */
152 usb_set_serial_data(serial, (void *)num_ports); 175 usb_set_serial_data(serial, (void *)num_ports);
153 176
177 /* ifnum could have changed - by calling usb_set_interface */
178 ifnum = sierra_calc_interface(serial);
179
180 if (is_blacklisted(ifnum,
181 (struct sierra_iface_info *)id->driver_info)) {
182 dev_dbg(&serial->dev->dev,
183 "Ignoring blacklisted interface #%d\n", ifnum);
184 return -ENODEV;
185 }
186
154 return result; 187 return result;
155} 188}
156 189
190static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11 };
191static const struct sierra_iface_info direct_ip_interface_blacklist = {
192 .infolen = ARRAY_SIZE(direct_ip_non_serial_ifaces),
193 .ifaceinfo = direct_ip_non_serial_ifaces,
194};
195
157static struct usb_device_id id_table [] = { 196static struct usb_device_id id_table [] = {
158 { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ 197 { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */
159 { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ 198 { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */
@@ -186,9 +225,11 @@ static struct usb_device_id id_table [] = {
186 { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */ 225 { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */
187 { USB_DEVICE(0x1199, 0x683A) }, /* Sierra Wireless MC8785 */ 226 { USB_DEVICE(0x1199, 0x683A) }, /* Sierra Wireless MC8785 */
188 { USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */ 227 { USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */
189 { USB_DEVICE(0x1199, 0x683C) }, /* Sierra Wireless MC8790 */ 228 /* Sierra Wireless MC8790, MC8791, MC8792 Composite */
190 { USB_DEVICE(0x1199, 0x683D) }, /* Sierra Wireless MC8790 */ 229 { USB_DEVICE(0x1199, 0x683C) },
191 { USB_DEVICE(0x1199, 0x683E) }, /* Sierra Wireless MC8790 */ 230 { USB_DEVICE(0x1199, 0x683D) }, /* Sierra Wireless MC8791 Composite */
231 /* Sierra Wireless MC8790, MC8791, MC8792 */
232 { USB_DEVICE(0x1199, 0x683E) },
192 { USB_DEVICE(0x1199, 0x6850) }, /* Sierra Wireless AirCard 880 */ 233 { USB_DEVICE(0x1199, 0x6850) }, /* Sierra Wireless AirCard 880 */
193 { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */ 234 { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */
194 { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880 E */ 235 { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880 E */
@@ -209,6 +250,10 @@ static struct usb_device_id id_table [] = {
209 { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ 250 { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */
210 { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */ 251 { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */
211 252
253 { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */
254 .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
255 },
256
212 { } 257 { }
213}; 258};
214MODULE_DEVICE_TABLE(usb, id_table); 259MODULE_DEVICE_TABLE(usb, id_table);