From 02f6ada2132cbdab804e3433e302b0290b627f52 Mon Sep 17 00:00:00 2001 From: CMY Date: Mon, 18 Jul 2011 17:58:48 +0800 Subject: [PATCH] =?utf8?q?=E6=94=AF=E6=8C=81=E6=9B=B4=E5=A4=9A=E7=9A=843g?= =?utf8?q?=20dongle?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- drivers/base/bus.c | 15 ++++ drivers/base/devices_filter.h | 146 ++++++++++++++++++++++++++++++++++ drivers/usb/serial/option.c | 10 +++ 3 files changed, 171 insertions(+) create mode 100644 drivers/base/devices_filter.h diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 57bc944028c8..659fcaa6bd42 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -17,6 +17,8 @@ #include #include "base.h" #include "power/power.h" +#include "linux/usb.h" +#include "devices_filter.h" #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr) #define to_bus(obj) container_of(obj, struct bus_type_private, subsys.kobj) @@ -404,7 +406,20 @@ int bus_for_each_drv(struct bus_type *bus, struct device_driver *start, klist_iter_init_node(&bus->p->klist_drivers, &i, start ? &start->p->knode_bus : NULL); while ((drv = next_driver(&i)) && !error) + { + if( !strcmp(drv->name, "usb-storage") && data ) + { + struct usb_device *udev = interface_to_usbdev( to_usb_interface( (struct device *)data) ); + usb_parameter usbp = {udev->descriptor.idVendor, udev->descriptor.idProduct, + udev->manufacturer, udev->product, NULL}; + if( is_skip_device(&usbp) ) + { + printk("Skip device\n"); + continue; + } + } error = fn(drv, data); + } klist_iter_exit(&i); return error; } diff --git a/drivers/base/devices_filter.h b/drivers/base/devices_filter.h new file mode 100644 index 000000000000..0a39257583ad --- /dev/null +++ b/drivers/base/devices_filter.h @@ -0,0 +1,146 @@ +#ifndef __DEVICES_FILTER_H +#define __DEVICES_FILTER_H +//lt 2010-12-03... + +#define USB_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + +typedef struct { + int vid; + int pid; + const char *manufacturer; + const char *product; + void *data; +}usb_parameter; + +static usb_parameter not_skip_device_list[] = { + {0x12D1, 0x1001, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", "HUAWEI Mobile",NULL}, +// {0x12D1, 0x1411, "HUAWEI Technology", "HUAWEI Mobile",NULL}, +}; + +static usb_parameter skip_device_list[] = { + {0x12D1, 0x1DA1, NULL, NULL, NULL}, + {0x12D1, 0x1D09, NULL, NULL, NULL}, + {0x12D1, 0x1520, NULL, NULL, NULL}, + {0x12D1, 0x14AC, NULL, NULL, NULL}, + {0x12D1, 0x1465, NULL, NULL, NULL}, + {0x12D1, 0x1446, NULL, NULL, NULL}, + {0x12D1, 0x1414, NULL, NULL, NULL}, + {0x12D1, 0x140C, NULL, NULL, NULL}, + {0x12D1, 0x1003, NULL, NULL, NULL}, + {0x12D1, 0x1001, NULL, NULL, NULL}, + + {0x19D2, 0xFFF5, NULL, NULL, NULL}, + {0x19D2, 0xFFF1, NULL, NULL, NULL}, + {0x19D2, 0x2000, NULL, NULL, NULL}, + {0x19D2, 0x0120, NULL, NULL, NULL}, + {0x19D2, 0x0094, NULL, NULL, NULL}, + {0x19D2, 0x0079, NULL, NULL, NULL}, + {0x19D2, 0x0073, NULL, NULL, NULL}, + {0x19D2, 0x0033, NULL, NULL, NULL}, + {0x19D2, 0x0031, NULL, NULL, NULL}, + {0x19D2, 0x0026, NULL, NULL, NULL}, + {0x19D2, 0x0017, NULL, NULL, NULL}, + {0x19D2, 0x0015, NULL, NULL, NULL}, + + {0x04CC, 0x225A, NULL, NULL, NULL}, + {0x04CC, 0x2259, NULL, NULL, NULL}, + + {0x1410, 0x5010, NULL, NULL, NULL}, + {0x1410, 0x4400, NULL, NULL, NULL}, + + {0x1D09, 0xAEF4, NULL, NULL, NULL}, + + {0x1BBB, 0xF000, NULL, NULL, NULL}, + {0x1BBB, 0x0017, NULL, NULL, NULL}, + +// 山寨 +// {0x05C6, -1, NULL, NULL, NULL}, + {0x20B9, 0x1682, NULL, NULL, NULL}, + + {0x028A, 0x1006, NULL, NULL, NULL}, + + {0x1C9E, 0x6061, NULL, NULL, NULL}, + {0x1C9E, 0x6000, NULL, NULL, NULL}, + {0x1C9E, 0x1001, NULL, NULL, NULL}, + + {0x21F5, 0x2008, NULL, NULL, NULL}, + {0x21F5, 0x1000, NULL, NULL, NULL}, + + {0x6000, 0x1000, NULL, NULL, NULL}, + + {0x0685, 0x7000, NULL, NULL, NULL}, +}; + +/* + 0 - 不同 + 1 - 相同 + */ +static int match_string(const char* s1, const char* s2) +{ + int count = 0; + while( s1[count] && s2[count] && !(s1[count]-s2[count]) ) + ++count; + + return !(s1[count]-s2[count]); +} + +/* 1 - match + * 0 - no match + */ +static int __must_check inline match_for_each_entry(usb_parameter* pusbp1, usb_parameter* pusbp2) +{ + if( pusbp1->vid>=0 && pusbp1->vid!=pusbp2->vid) + return 0; + + if( pusbp1->pid>=0 && pusbp1->pid!=pusbp2->pid) + return 0; + + if( pusbp1->manufacturer ) + { + if( pusbp2->manufacturer==NULL ) + return 0; + else if( strcmp(pusbp1->manufacturer, pusbp2->manufacturer) ) + return 0; + } + + if( pusbp1->product ) + { + if( pusbp2->product==NULL ) + return 0; + else if( strcmp(pusbp1->product, pusbp2->product) ) + return 0; + } + + return 1; +} + +/* + 0 - don't skip + 1 - skip the device + */ +static int is_skip_device(usb_parameter *pusbp) +{ + int i = 0; +/* + 在 not_skip_device_list 中寻找匹配,找到则该 device 正常流程 + 在 skip_device_list 中寻找匹配,找到则该 device 跳过attach + 对于不在 skip_device_list,not_skip_device_list,则正常流程 + */ + for(i = 0; i < USB_ARRAY_SIZE(not_skip_device_list); i++) + { + if(match_for_each_entry(not_skip_device_list+i, pusbp)){ + return 0; + } + } + + for(i = 0; i < USB_ARRAY_SIZE(skip_device_list); i++) + { + if(match_for_each_entry(skip_device_list+i, pusbp)){ + return 1; + } + } + + return 0; +} + +#endif //__DEVICES_FILTER_H diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 6eb7b83f3645..2c07ad320cee 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -945,6 +945,16 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(0x1234, 0x0033) }, { USB_DEVICE(0xFEED, 0x0001) }, { USB_DEVICE(ALCATEL_VENDOR_ID, 0x0017) }, + { USB_DEVICE(0x1C9E, 0x9E00) }, + { USB_DEVICE(0x1C9E, 0xF000) }, + { USB_DEVICE(0x19D2, 0x1303) }, + { USB_DEVICE(0x19F5, 0x9013) }, // MW100 + { USB_DEVICE(0x21F5, 0x2008) }, + { USB_DEVICE(0x12D1, 0x1D09) }, + { USB_DEVICE(0x04CC, 0x2259) }, + { USB_DEVICE(0x04CC, 0x226E) }, + { USB_DEVICE(0x04CC, 0x225A) }, + { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0015) }, /* Cinterion */ { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) }, -- 2.34.1