|
@@ -346,6 +346,19 @@ static int option_resume(struct usb_serial *serial);
|
|
|
#define HAIER_VENDOR_ID 0x201e
|
|
|
#define HAIER_PRODUCT_CE100 0x2009
|
|
|
|
|
|
+/* some devices interfaces need special handling due to a number of reasons */
|
|
|
+enum option_blacklist_reason {
|
|
|
+ OPTION_BLACKLIST_NONE = 0,
|
|
|
+ OPTION_BLACKLIST_SENDSETUP = 1,
|
|
|
+ OPTION_BLACKLIST_RESERVED_IF = 2
|
|
|
+};
|
|
|
+
|
|
|
+struct option_blacklist_info {
|
|
|
+ const u32 infolen; /* number of interface numbers on blacklist */
|
|
|
+ const u8 *ifaceinfo; /* pointer to the array holding the numbers */
|
|
|
+ enum option_blacklist_reason reason;
|
|
|
+};
|
|
|
+
|
|
|
static const struct usb_device_id option_ids[] = {
|
|
|
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
|
|
|
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
|
|
@@ -711,6 +724,7 @@ struct option_intf_private {
|
|
|
spinlock_t susp_lock;
|
|
|
unsigned int suspended:1;
|
|
|
int in_flight;
|
|
|
+ struct option_blacklist_info *blacklist_info;
|
|
|
};
|
|
|
|
|
|
struct option_port_private {
|
|
@@ -780,9 +794,27 @@ static int option_probe(struct usb_serial *serial,
|
|
|
if (!data)
|
|
|
return -ENOMEM;
|
|
|
spin_lock_init(&data->susp_lock);
|
|
|
+ data->blacklist_info = (struct option_blacklist_info*) id->driver_info;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static enum option_blacklist_reason is_blacklisted(const u8 ifnum,
|
|
|
+ const struct option_blacklist_info *blacklist)
|
|
|
+{
|
|
|
+ const u8 *info;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ if (blacklist) {
|
|
|
+ info = blacklist->ifaceinfo;
|
|
|
+
|
|
|
+ for (i = 0; i < blacklist->infolen; i++) {
|
|
|
+ if (info[i] == ifnum)
|
|
|
+ return blacklist->reason;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return OPTION_BLACKLIST_NONE;
|
|
|
+}
|
|
|
+
|
|
|
static void option_set_termios(struct tty_struct *tty,
|
|
|
struct usb_serial_port *port, struct ktermios *old_termios)
|
|
|
{
|
|
@@ -1213,11 +1245,19 @@ static void option_setup_urbs(struct usb_serial *serial)
|
|
|
static int option_send_setup(struct usb_serial_port *port)
|
|
|
{
|
|
|
struct usb_serial *serial = port->serial;
|
|
|
+ struct option_intf_private *intfdata =
|
|
|
+ (struct option_intf_private *) serial->private;
|
|
|
struct option_port_private *portdata;
|
|
|
int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
|
|
|
int val = 0;
|
|
|
dbg("%s", __func__);
|
|
|
|
|
|
+ if (is_blacklisted(ifNum, intfdata->blacklist_info) ==
|
|
|
+ OPTION_BLACKLIST_SENDSETUP) {
|
|
|
+ dbg("No send_setup on blacklisted interface #%d\n", ifNum);
|
|
|
+ return -EIO;
|
|
|
+ }
|
|
|
+
|
|
|
portdata = usb_get_serial_port_data(port);
|
|
|
|
|
|
if (portdata->dtr_state)
|