diff options
-rw-r--r-- | drivers/usb/serial/option.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index b4fe9ffd6dd6..85e5fc08bba6 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -346,6 +346,19 @@ static int option_resume(struct usb_serial *serial); | |||
346 | #define HAIER_VENDOR_ID 0x201e | 346 | #define HAIER_VENDOR_ID 0x201e |
347 | #define HAIER_PRODUCT_CE100 0x2009 | 347 | #define HAIER_PRODUCT_CE100 0x2009 |
348 | 348 | ||
349 | /* some devices interfaces need special handling due to a number of reasons */ | ||
350 | enum option_blacklist_reason { | ||
351 | OPTION_BLACKLIST_NONE = 0, | ||
352 | OPTION_BLACKLIST_SENDSETUP = 1, | ||
353 | OPTION_BLACKLIST_RESERVED_IF = 2 | ||
354 | }; | ||
355 | |||
356 | struct option_blacklist_info { | ||
357 | const u32 infolen; /* number of interface numbers on blacklist */ | ||
358 | const u8 *ifaceinfo; /* pointer to the array holding the numbers */ | ||
359 | enum option_blacklist_reason reason; | ||
360 | }; | ||
361 | |||
349 | static const struct usb_device_id option_ids[] = { | 362 | static const struct usb_device_id option_ids[] = { |
350 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, | 363 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, |
351 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, | 364 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, |
@@ -711,6 +724,7 @@ struct option_intf_private { | |||
711 | spinlock_t susp_lock; | 724 | spinlock_t susp_lock; |
712 | unsigned int suspended:1; | 725 | unsigned int suspended:1; |
713 | int in_flight; | 726 | int in_flight; |
727 | struct option_blacklist_info *blacklist_info; | ||
714 | }; | 728 | }; |
715 | 729 | ||
716 | struct option_port_private { | 730 | struct option_port_private { |
@@ -780,9 +794,27 @@ static int option_probe(struct usb_serial *serial, | |||
780 | if (!data) | 794 | if (!data) |
781 | return -ENOMEM; | 795 | return -ENOMEM; |
782 | spin_lock_init(&data->susp_lock); | 796 | spin_lock_init(&data->susp_lock); |
797 | data->blacklist_info = (struct option_blacklist_info*) id->driver_info; | ||
783 | return 0; | 798 | return 0; |
784 | } | 799 | } |
785 | 800 | ||
801 | static enum option_blacklist_reason is_blacklisted(const u8 ifnum, | ||
802 | const struct option_blacklist_info *blacklist) | ||
803 | { | ||
804 | const u8 *info; | ||
805 | int i; | ||
806 | |||
807 | if (blacklist) { | ||
808 | info = blacklist->ifaceinfo; | ||
809 | |||
810 | for (i = 0; i < blacklist->infolen; i++) { | ||
811 | if (info[i] == ifnum) | ||
812 | return blacklist->reason; | ||
813 | } | ||
814 | } | ||
815 | return OPTION_BLACKLIST_NONE; | ||
816 | } | ||
817 | |||
786 | static void option_set_termios(struct tty_struct *tty, | 818 | static void option_set_termios(struct tty_struct *tty, |
787 | struct usb_serial_port *port, struct ktermios *old_termios) | 819 | struct usb_serial_port *port, struct ktermios *old_termios) |
788 | { | 820 | { |
@@ -1213,11 +1245,19 @@ static void option_setup_urbs(struct usb_serial *serial) | |||
1213 | static int option_send_setup(struct usb_serial_port *port) | 1245 | static int option_send_setup(struct usb_serial_port *port) |
1214 | { | 1246 | { |
1215 | struct usb_serial *serial = port->serial; | 1247 | struct usb_serial *serial = port->serial; |
1248 | struct option_intf_private *intfdata = | ||
1249 | (struct option_intf_private *) serial->private; | ||
1216 | struct option_port_private *portdata; | 1250 | struct option_port_private *portdata; |
1217 | int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber; | 1251 | int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber; |
1218 | int val = 0; | 1252 | int val = 0; |
1219 | dbg("%s", __func__); | 1253 | dbg("%s", __func__); |
1220 | 1254 | ||
1255 | if (is_blacklisted(ifNum, intfdata->blacklist_info) == | ||
1256 | OPTION_BLACKLIST_SENDSETUP) { | ||
1257 | dbg("No send_setup on blacklisted interface #%d\n", ifNum); | ||
1258 | return -EIO; | ||
1259 | } | ||
1260 | |||
1221 | portdata = usb_get_serial_port_data(port); | 1261 | portdata = usb_get_serial_port_data(port); |
1222 | 1262 | ||
1223 | if (portdata->dtr_state) | 1263 | if (portdata->dtr_state) |