diff options
Diffstat (limited to 'drivers/net/usb/qmi_wwan.c')
| -rw-r--r-- | drivers/net/usb/qmi_wwan.c | 87 | 
1 files changed, 44 insertions, 43 deletions
| diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 3b206786b5e7..b01960fcfbc9 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -197,6 +197,10 @@ err:  static int qmi_wwan_cdc_wdm_manage_power(struct usb_interface *intf, int on)  {  	struct usbnet *dev = usb_get_intfdata(intf); + +	/* can be called while disconnecting */ +	if (!dev) +		return 0;  	return qmi_wwan_manage_power(dev, on);  } @@ -257,29 +261,6 @@ err:  	return rv;  } -/* Gobi devices uses identical class/protocol codes for all interfaces regardless - * of function. Some of these are CDC ACM like and have the exact same endpoints - * we are looking for. This leaves two possible strategies for identifying the - * correct interface: - *   a) hardcoding interface number, or - *   b) use the fact that the wwan interface is the only one lacking additional - *      (CDC functional) descriptors - * - * Let's see if we can get away with the generic b) solution. - */ -static int qmi_wwan_bind_gobi(struct usbnet *dev, struct usb_interface *intf) -{ -	int rv = -EINVAL; - -	/* ignore any interface with additional descriptors */ -	if (intf->cur_altsetting->extralen) -		goto err; - -	rv = qmi_wwan_bind_shared(dev, intf); -err: -	return rv; -} -  static void qmi_wwan_unbind_shared(struct usbnet *dev, struct usb_interface *intf)  {  	struct usb_driver *subdriver = (void *)dev->data[0]; @@ -347,15 +328,15 @@ static const struct driver_info	qmi_wwan_shared = {  	.manage_power	= qmi_wwan_manage_power,  }; -static const struct driver_info	qmi_wwan_gobi = { -	.description	= "Qualcomm Gobi wwan/QMI device", +static const struct driver_info	qmi_wwan_force_int0 = { +	.description	= "Qualcomm WWAN/QMI device",  	.flags		= FLAG_WWAN, -	.bind		= qmi_wwan_bind_gobi, +	.bind		= qmi_wwan_bind_shared,  	.unbind		= qmi_wwan_unbind_shared,  	.manage_power	= qmi_wwan_manage_power, +	.data		= BIT(0), /* interface whitelist bitmap */  }; -/* ZTE suck at making USB descriptors */  static const struct driver_info	qmi_wwan_force_int1 = {  	.description	= "Qualcomm WWAN/QMI device",  	.flags		= FLAG_WWAN, @@ -365,6 +346,15 @@ static const struct driver_info	qmi_wwan_force_int1 = {  	.data		= BIT(1), /* interface whitelist bitmap */  }; +static const struct driver_info	qmi_wwan_force_int3 = { +	.description	= "Qualcomm WWAN/QMI device", +	.flags		= FLAG_WWAN, +	.bind		= qmi_wwan_bind_shared, +	.unbind		= qmi_wwan_unbind_shared, +	.manage_power	= qmi_wwan_manage_power, +	.data		= BIT(3), /* interface whitelist bitmap */ +}; +  static const struct driver_info	qmi_wwan_force_int4 = {  	.description	= "Qualcomm WWAN/QMI device",  	.flags		= FLAG_WWAN, @@ -390,16 +380,23 @@ static const struct driver_info	qmi_wwan_force_int4 = {  static const struct driver_info	qmi_wwan_sierra = {  	.description	= "Sierra Wireless wwan/QMI device",  	.flags		= FLAG_WWAN, -	.bind		= qmi_wwan_bind_gobi, +	.bind		= qmi_wwan_bind_shared,  	.unbind		= qmi_wwan_unbind_shared,  	.manage_power	= qmi_wwan_manage_power,  	.data		= BIT(8) | BIT(19), /* interface whitelist bitmap */  };  #define HUAWEI_VENDOR_ID	0x12D1 + +/* Gobi 1000 QMI/wwan interface number is 3 according to qcserial */ +#define QMI_GOBI1K_DEVICE(vend, prod) \ +	USB_DEVICE(vend, prod), \ +	.driver_info = (unsigned long)&qmi_wwan_force_int3 + +/* Gobi 2000 and Gobi 3000 QMI/wwan interface number is 0 according to qcserial */  #define QMI_GOBI_DEVICE(vend, prod) \  	USB_DEVICE(vend, prod), \ -	.driver_info = (unsigned long)&qmi_wwan_gobi +	.driver_info = (unsigned long)&qmi_wwan_force_int0  static const struct usb_device_id products[] = {  	{	/* Huawei E392, E398 and possibly others sharing both device id and more... */ @@ -510,20 +507,24 @@ static const struct usb_device_id products[] = {  		.bInterfaceProtocol = 0xff,  		.driver_info        = (unsigned long)&qmi_wwan_sierra,  	}, -	{QMI_GOBI_DEVICE(0x05c6, 0x9212)},	/* Acer Gobi Modem Device */ -	{QMI_GOBI_DEVICE(0x03f0, 0x1f1d)},	/* HP un2400 Gobi Modem Device */ -	{QMI_GOBI_DEVICE(0x03f0, 0x371d)},	/* HP un2430 Mobile Broadband Module */ -	{QMI_GOBI_DEVICE(0x04da, 0x250d)},	/* Panasonic Gobi Modem device */ -	{QMI_GOBI_DEVICE(0x413c, 0x8172)},	/* Dell Gobi Modem device */ -	{QMI_GOBI_DEVICE(0x1410, 0xa001)},	/* Novatel Gobi Modem device */ -	{QMI_GOBI_DEVICE(0x0b05, 0x1776)},	/* Asus Gobi Modem device */ -	{QMI_GOBI_DEVICE(0x19d2, 0xfff3)},	/* ONDA Gobi Modem device */ -	{QMI_GOBI_DEVICE(0x05c6, 0x9001)},	/* Generic Gobi Modem device */ -	{QMI_GOBI_DEVICE(0x05c6, 0x9002)},	/* Generic Gobi Modem device */ -	{QMI_GOBI_DEVICE(0x05c6, 0x9202)},	/* Generic Gobi Modem device */ -	{QMI_GOBI_DEVICE(0x05c6, 0x9203)},	/* Generic Gobi Modem device */ -	{QMI_GOBI_DEVICE(0x05c6, 0x9222)},	/* Generic Gobi Modem device */ -	{QMI_GOBI_DEVICE(0x05c6, 0x9009)},	/* Generic Gobi Modem device */ + +	/* Gobi 1000 devices */ +	{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)},	/* Acer Gobi Modem Device */ +	{QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)},	/* HP un2400 Gobi Modem Device */ +	{QMI_GOBI1K_DEVICE(0x03f0, 0x371d)},	/* HP un2430 Mobile Broadband Module */ +	{QMI_GOBI1K_DEVICE(0x04da, 0x250d)},	/* Panasonic Gobi Modem device */ +	{QMI_GOBI1K_DEVICE(0x413c, 0x8172)},	/* Dell Gobi Modem device */ +	{QMI_GOBI1K_DEVICE(0x1410, 0xa001)},	/* Novatel Gobi Modem device */ +	{QMI_GOBI1K_DEVICE(0x0b05, 0x1776)},	/* Asus Gobi Modem device */ +	{QMI_GOBI1K_DEVICE(0x19d2, 0xfff3)},	/* ONDA Gobi Modem device */ +	{QMI_GOBI1K_DEVICE(0x05c6, 0x9001)},	/* Generic Gobi Modem device */ +	{QMI_GOBI1K_DEVICE(0x05c6, 0x9002)},	/* Generic Gobi Modem device */ +	{QMI_GOBI1K_DEVICE(0x05c6, 0x9202)},	/* Generic Gobi Modem device */ +	{QMI_GOBI1K_DEVICE(0x05c6, 0x9203)},	/* Generic Gobi Modem device */ +	{QMI_GOBI1K_DEVICE(0x05c6, 0x9222)},	/* Generic Gobi Modem device */ +	{QMI_GOBI1K_DEVICE(0x05c6, 0x9009)},	/* Generic Gobi Modem device */ + +	/* Gobi 2000 and 3000 devices */  	{QMI_GOBI_DEVICE(0x413c, 0x8186)},	/* Dell Gobi 2000 Modem device (N0218, VU936) */  	{QMI_GOBI_DEVICE(0x05c6, 0x920b)},	/* Generic Gobi 2000 Modem device */  	{QMI_GOBI_DEVICE(0x05c6, 0x9225)},	/* Sony Gobi 2000 Modem device (N0279, VU730) */ | 
