Wish List (generally ignored ;-), Brainstorming
bmork
Posts: 167
Joined: 15 Mar 2012, 22:47
Location: Oslo, Norway

Switching MBIM devices

Post by bmork » 06 Sep 2012, 17:51

Hello, I need some ideas on how to handle new CDC MBIM devices intended for Windows 8. These will typically present 2 or more configurations in the unswitched mode, where the first configuration will be a "Windows 7 compatibility" mode similar to what we are used to: A single mass storage device with a driver CD and some magic command to morph the device into another mode with a number of serial and NDIS interfaces.

When we get CDC MBIM driver support in the kernel we may want to start not switching modes, but instead just set some configuration > 1. I see that usb_modeswitch already has support for setting a non default configuration, but the problem is that this will happen after switching.

And we must expect vendors recycling the device IDs, so we need to support selecting mode switching or configuration switching based on the available configurations.

I just got this sample:

Code: Select all

Bus 002 Device 038: ID 12d1:1446 Huawei Technologies Co., Ltd. E1552/E1800/E173 (HSPA modem)
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass          239 Miscellaneous Device
  bDeviceSubClass         2 ?
  bDeviceProtocol         1 Interface Association
  bMaxPacketSize0        64
  idVendor           0x12d1 Huawei Technologies Co., Ltd.
  idProduct          0x1446 E1552/E1800/E173 (HSPA modem)
  bcdDevice            0.00
  iManufacturer           4 Huawei Technologies
  iProduct                3 HUAWEI MBIM Device
  iSerial                 5 <FF><FF><FF><FF><FF><FF><FF><FF><FF><FF><FF><FF><FF><FF><FF><FF>
  bNumConfigurations      2
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           32
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          1 Huawei Configuration
    bmAttributes         0xc0
      Self Powered
    MaxPower              500mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         8 Mass Storage
      bInterfaceSubClass      6 SCSI
      bInterfaceProtocol     80 Bulk-Only
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           87
    bNumInterfaces          2
    bConfigurationValue     2
    iConfiguration          2 Huawei Configuration
    bmAttributes         0xc0
      Self Powered
    MaxPower              500mA
    Interface Association:
      bLength                 8
      bDescriptorType        11
      bFirstInterface         0
      bInterfaceCount         2
      bFunctionClass          2 Communications
      bFunctionSubClass      14 
      bFunctionProtocol       0 
      iFunction               0 
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         2 Communications
      bInterfaceSubClass     14 
      bInterfaceProtocol      0 
      iInterface              0 
      CDC Header:
        bcdCDC               1.10
      CDC MBIM:
        bcdMBIMVersion       1.00
        wMaxControlMessage   1536
        bNumberFilters       16
        bMaxFilterSize       40
        wMaxSegmentSize      4096
        bmNetworkCapabilities 0x20
          8-byte ntb input size
      CDC Union:
        bMasterInterface        0
        bSlaveInterface         1 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               5
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass        10 CDC Data
      bInterfaceSubClass      0 Unused
      bInterfaceProtocol      2 
      iInterface              0 
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       1
      bNumEndpoints           2
      bInterfaceClass        10 CDC Data
      bInterfaceSubClass      0 Unused
      bInterfaceProtocol      2 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval              32
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval              32
Device Qualifier (for other device speed):
  bLength                10
  bDescriptorType         6
  bcdUSB               2.00
  bDeviceClass          239 Miscellaneous Device
  bDeviceSubClass         2 ?
  bDeviceProtocol         1 Interface Association
  bMaxPacketSize0        64
  bNumConfigurations      2
Device Status:     0x0000
  (Bus Powered)

As you can see, this matches existing usb_modeswitch data for 12d1:1446. And that needs to stay to support all older devices. But this one we'd like to have unswitched and set to configuration #2 so that we can use the MBIM function.

How should we do that? I don't think we want to add any new policy to the kernel. Could we make a generic udev rule overriding usb_modeswitch and choosing the MBIM configurations instead, maybe?

Josh
Site Admin
Posts: 6570
Joined: 03 Nov 2007, 00:30

Re: Switching MBIM devices

Post by Josh » 06 Sep 2012, 23:52

Well, all we would need is
  1. a way to identify such a device; any unequivocal attribute will do
  2. a way to check the abilities of the kernel or the presence of the new driver/subsystem
The wrapper can take care of deciding about action or non-action, in a similar way as it does now for IDs that are ambiguous.

Josh
Site Admin
Posts: 6570
Joined: 03 Nov 2007, 00:30

Re: Switching MBIM devices

Post by Josh » 07 Sep 2012, 00:00

Looking at the example, there are some attributes that differ from the known devices with the same ID.

Of course there is the iProduct string containing "MBIM" but I don't know how reliable that is unless it's part of a 'standard agreement'.

Then there is the fact that the device has two configurations. Is that part of the 'MBIM standard' ?

Anyway, thanks for the info, I'll try to do some research as well.

bmork
Posts: 167
Joined: 15 Mar 2012, 22:47
Location: Oslo, Norway

Re: Switching MBIM devices

Post by bmork » 07 Sep 2012, 12:35

Josh wrote:Looking at the example, there are some attributes that differ from the known devices with the same ID.

Of course there is the iProduct string containing "MBIM" but I don't know how reliable that is unless it's part of a 'standard agreement'.
I assume that is a vendor choice and nothing else. Probably something that will go away too, when MBIM becomes the supported firmware.
Then there is the fact that the device has two configurations. Is that part of the 'MBIM standard' ?
No. But it is part of a Microsoft specification on how to support both Windows 8 and Windows 7 (read any previous Windows version), so I assume it will be quite common until vendors start dropping support for anything older than Windows 8.

Microsoft specifies that the legacy configuration must be default in this case, and that the Windows 8 configuration must be number 2, 3 or 4. They also have extended some of their weird hidden Microsoft specific alternatives to real USB descriptors where Windows can find information about which configuration to choose. But I am hoping that we can avoid looking at that, because
  • a) Microsoft does not write USB standards,
    b) the documentation license is rather dubious,
    c) the method is error prone,
    d) we can manage better without it
Anyway, thanks for the info, I'll try to do some research as well.
Great. I will also try different alternatives. There seem to me to be a hole in the Linux implementation of multiple configurations. You would want a hotplug helper to choose the correct configuration, but to do that it will need to see all the available configurations, not only the active one.

Bjørn

Josh
Site Admin
Posts: 6570
Joined: 03 Nov 2007, 00:30

Re: Switching MBIM devices

Post by Josh » 07 Sep 2012, 14:10

bmork wrote:Microsoft specifies that the legacy configuration must be default in this case, and that the Windows 8 configuration must be number 2, 3 or 4. They also have extended some of their weird hidden Microsoft specific alternatives to real USB descriptors where Windows can find information about which configuration to choose. But I am hoping that we can avoid looking at that, because
  • a) Microsoft does not write USB standards,
    b) the documentation license is rather dubious,
    c) the method is error prone,
    d) we can manage better without it
...
There seem to me to be a hole in the Linux implementation of multiple configurations. You would want a hotplug helper to choose the correct configuration, but to do that it will need to see all the available configurations, not only the active one.
Actually that last point is not a problem. Just as "lsusb" is able to list all configurations, not just the active one, any other libusb program can check the details of every announced configuration - contrary to the mode-switching business, where you have no way of knowing what you will get beforehand ...

BTW, usb_modeswitch is already handling some devices that need a simple configuration change instead of a 'secret' mode-switch command. So no problem there either.

Having had a look into the MBIM spec V1.0, there seems to be no mentioning of "initial" device states; it only sets the requirements for a ready-to-use device configuration.

bmork
Posts: 167
Joined: 15 Mar 2012, 22:47
Location: Oslo, Norway

Re: Switching MBIM devices

Post by bmork » 07 Sep 2012, 15:23

Josh wrote:
bmork wrote:There seem to me to be a hole in the Linux implementation of multiple configurations. You would want a hotplug helper to choose the correct configuration, but to do that it will need to see all the available configurations, not only the active one.
Actually that last point is not a problem. Just as "lsusb" is able to list all configurations, not just the active one, any other libusb program can check the details of every announced configuration - contrary to the mode-switching business, where you have no way of knowing what you will get beforehand ...
Yes, I know. But you cannot use the alternate configuration in udev rules. So you cannot say

Code: Select all

if any non active configuration matches class foo
then select that config
as an udev rule. You can only match on the attributes of the current config. But that is probably more of an udev problem than a Linux problem.
BTW, usb_modeswitch is already handling some devices that need a simple configuration change instead of a 'secret' mode-switch command. So no problem there either.
Yes, the problem is that the device ID matches existing devices without MBIM. The default usb_modeswitch configuration will therefore switch the device into legacy mode.
Having had a look into the MBIM spec V1.0, there seems to be no mentioning of "initial" device states; it only sets the requirements for a ready-to-use device configuration.
[/quote][/quote]

Yes, I have only seen the multi configuration specified by Microsoft: http://msdn.microsoft.com/en-us/library ... ndows.aspx

But we can safely assume that most vendors with morphing devices will implement this spec in their first MBIM firmwares, like the sample I've got from Huawei.

Anyway, I took a shot at adding some support to just let usb_modeswitch always select an MBIM configuration if availbale. This will probably have to be refined, but it works for me.

EDIT: Not entirely true. mbim_cfg was missing intialization (manually fixed below), and this leads to unexpected results if the user wants to manually select another config. udev will then call usb_modeswitch, which again will select the MBIM config. You can work around it by editing the usb_modeswitch config, but I find that annoying as an end user.


Tried to add it as an attachment, but only got "the extenstion is not allowed", so I gave up. Here is is as a code blob:

Code: Select all

diff --git a/usb_modeswitch.c b/usb_modeswitch.c
index ce0e1de..a6dde79 100644
--- a/usb_modeswitch.c
+++ b/usb_modeswitch.c
@@ -86,6 +86,7 @@ char DetachStorageOnly=0, HuaweiMode=0, SierraMode=0, SonyMode=0, GCTMode=0, Kob
 char SequansMode=0, MobileActionMode=0, CiscoMode=0, QisdaMode=0;
 char verbose=0, show_progress=1, ResetUSB=0, CheckSuccess=0, config_read=0;
 char NeedResponse=0, NoDriverLoading=0, InquireDevice=1, sysmode=0;
+char IgnoreMBIM=0;
 
 char imanufact[DESCR_MAX], iproduct[DESCR_MAX], iserial[DESCR_MAX];
 
@@ -142,6 +143,7 @@ static struct option long_options[] = {
 	{"interface",			required_argument, 0, 'i'},
 	{"configuration",		required_argument, 0, 'u'},
 	{"altsetting",			required_argument, 0, 'a'},
+	{"ignore-mbim",			no_argument, 0, 'x'},
 	{0, 0, 0, 0}
 };
 
@@ -178,6 +180,7 @@ void readConfigFile(const char *configFilename)
 	ParseParamHex(configFilename, Interface);
 	ParseParamHex(configFilename, Configuration);
 	ParseParamHex(configFilename, AltSetting);
+	ParseParamBool(configFilename, IgnoreMBIM);
 
 	/* TargetProductList has priority over TargetProduct */
 	if (TargetProduct != -1 && TargetProductList[0] != '\0') {
@@ -254,6 +257,11 @@ void printConfig()
 		fprintf (output,"System integration mode enabled\n");
 	else
 		fprintf (output,"System integration mode disabled\n");
+	if ( IgnoreMBIM )
+		fprintf (output,"Ignoring MBIM configurations\n");
+	else
+		fprintf (output,"Preferring MBIM configurations\n");
+
 	fprintf (output,"\n");
 }
 
@@ -271,7 +279,7 @@ int readArguments(int argc, char **argv)
 
 	while (1)
 	{
-		c = getopt_long (argc, argv, "heWQDndHSOBGTNALRItv:p:V:P:C:m:M:2:3:w:r:c:i:u:a:s:f:b:g:",
+		c = getopt_long (argc, argv, "heWQDndHSOBGTNALRItxv:p:V:P:C:m:M:2:3:w:r:c:i:u:a:s:f:b:g:",
 						long_options, &option_index);
 
 		/* Detect the end of the options. */
@@ -316,6 +324,7 @@ int readArguments(int argc, char **argv)
 			case 'i': Interface = strtol(optarg, NULL, 16); break;
 			case 'u': Configuration = strtol(optarg, NULL, 16); break;
 			case 'a': AltSetting = strtol(optarg, NULL, 16); break;
+			case 'x': IgnoreMBIM = 1; break;
 
 			case 'f':
 				longConfig = malloc(strlen(optarg)+5);
@@ -346,12 +355,11 @@ int readArguments(int argc, char **argv)
 	return count;
 }
 
-
 int main(int argc, char **argv)
 {
 	int numDefaults=0, specialMode=0, sonySuccess=0;
 	int currentConfig=0, defaultClass=0, interfaceClass=0;
-
+	int mbim_cfg=0;
 
 	/* Make sure we have empty strings even if not set by config */
 	TargetProductList[0] = '\0';
@@ -464,13 +472,22 @@ int main(int argc, char **argv)
 	 * The dispatcher is using this always if no change of configuration
 	 * is required for switching
 	 */
-	if (Configuration > -1)
+	if (Configuration > -1) {
 		currentConfig = get_current_configuration(devh);
-	else {
+		if (!IgnoreMBIM)
+			mbim_cfg = find_mbim_config(dev);
+	} else {
 		SHOW_PROGRESS(output,"Skipping the check for the current configuration\n");
 		currentConfig = 0;
 	}
 
+	if (mbim_cfg > 0) {
+		MessageContent[0] = '\0'; /* Do not switch MBIM devices. */
+		InquireDevice = 0;        /* No need to inquire when not switching */
+		ResetUSB = 0;             /* Silently ignore */
+		Configuration = mbim_cfg; /* warn if set? */
+	}
+
 	if (Interface == -1)
 		Interface = dev->config[0].interface[0].altsetting[0].bInterfaceNumber;
 	SHOW_PROGRESS(output,"Using interface number %d\n", Interface);
@@ -550,6 +567,12 @@ int main(int argc, char **argv)
 		exit(1);
 	}
 
+	/* Warn if special mode is used for a MBIM device */
+	if ( specialMode && mbim_cfg > 0) {
+		SHOW_PROGRESS(output,"Invalid mode for a MBIM device. Aborting.\n\n");
+		exit(1);
+	}
+
 	if ( !specialMode && !strlen(MessageContent) && AltSetting == -1 && Configuration == 0 )
 		SHOW_PROGRESS(output,"Warning: no switching method given.\n");
 
@@ -648,6 +671,10 @@ int main(int argc, char **argv)
 	}
 
 	if (CheckSuccess) {
+		if ((mbim_cfg > 0) && (currentConfig == mbim_cfg)) {
+			printf("ok:\n");
+			goto CLOSING;
+		}
 		if (searchMode == SEARCH_BUSDEV && sysmode) {
 			SHOW_PROGRESS(output,"Bus/dev search active, referring success check to wrapper. Bye.\n\n");
 			printf("ok:busdev\n");
@@ -1680,6 +1707,29 @@ int get_interface_class(struct usb_device *dev, int cfgNumber, int ifcNumber)
 	return -1;
 }
 
+int find_mbim_config(struct usb_device *dev)
+{
+	int i, j, k;
+
+	// look up the first config with a MBIM interface
+	for (i=0; i<dev->descriptor.bNumConfigurations; i++) {
+		for (j=0; j<dev->config[i].bNumInterfaces; j++)
+			// MBIM interfaces may have a NCM 1.0 compatibility mode as altsetting 0
+			for (k=0; k<dev->config[i].interface[j].num_altsetting; k++) {
+//				SHOW_PROGRESS(output,"Test: looking at cfg %d intf %d altsetting %d, ic/isc/ip %02x/%02x/%02x\n",
+//					dev->config[i].bConfigurationValue,
+//					j, k,
+//					dev->config[i].interface[j].altsetting[k].bInterfaceClass,
+//					dev->config[i].interface[j].altsetting[k].bInterfaceSubClass,
+//					dev->config[i].interface[j].altsetting[k].bInterfaceProtocol);
+				if ((dev->config[i].interface[j].altsetting[k].bInterfaceClass == 0x02) &&
+					(dev->config[i].interface[j].altsetting[k].bInterfaceSubClass == 0x0e) &&
+					(dev->config[i].interface[j].altsetting[k].bInterfaceProtocol == 0x00))
+					return dev->config[i].bConfigurationValue;
+			}
+	}
+	return -1;
+}
 
 /* Parameter parsing */
 
@@ -1881,5 +1931,6 @@ void printHelp()
 	" -f, --long-config <text>      get long configuration from string\n\n"
 	" -i, --interface NUM           select initial USB interface (default 0)\n"
 	" -u, --configuration NUM       select USB configuration\n"
-	" -a, --altsetting NUM          select alternative USB interface setting\n\n");
+	" -a, --altsetting NUM          select alternative USB interface setting\n"
+	" -x, --ignore-mbim             ignore MBIM configuration\n\n");
 }
diff --git a/usb_modeswitch.h b/usb_modeswitch.h
index 3649f86..b4df14c 100644
--- a/usb_modeswitch.h
+++ b/usb_modeswitch.h
@@ -53,6 +53,7 @@ int find_first_bulk_input_endpoint(struct usb_device *dev);
 int get_current_configuration(struct usb_dev_handle* devh);
 int get_interface0_class(struct usb_device *dev, int devconfig);
 int get_interface_class(struct usb_device *dev, int cfgNumber, int ifcNumber);
+int find_mbim_config(struct usb_device *dev);
 char* ReadParseParam(const char* FileName, char *VariableName);
 int hex2num(char c);
 int hex2byte(const char *hex);

LOM
Posts: 1404
Joined: 11 Jul 2012, 15:14
Location: Koh Samui, TH

Re: Switching MBIM devices

Post by LOM » 07 Sep 2012, 15:52

Josh wrote:Looking at the example, there are some attributes that differ from the known devices with the same ID.

Of course there is the iProduct string containing "MBIM" but I don't know how reliable that is unless it's part of a 'standard agreement'.

Then there is the fact that the device has two configurations. Is that part of the 'MBIM standard' ?

Anyway, thanks for the info, I'll try to do some research as well.

bDeviceClass 239 Miscellaneous Device
bDeviceSubClass 2 ?
bDeviceProtocol 1 Interface Association

makes it different from previous 12d1:1446 sticks.

bmork
Posts: 167
Joined: 15 Mar 2012, 22:47
Location: Oslo, Norway

Re: Switching MBIM devices

Post by bmork » 07 Sep 2012, 16:09

LOM wrote:
Josh wrote:Looking at the example, there are some attributes that differ from the known devices with the same ID.

Of course there is the iProduct string containing "MBIM" but I don't know how reliable that is unless it's part of a 'standard agreement'.

Then there is the fact that the device has two configurations. Is that part of the 'MBIM standard' ?

Anyway, thanks for the info, I'll try to do some research as well.

bDeviceClass 239 Miscellaneous Device
bDeviceSubClass 2 ?
bDeviceProtocol 1 Interface Association

makes it different from previous 12d1:1446 sticks.
Yes, but this only tells us that it is an IAD device. It could be anything. See
http://www.usb.org/developers/whitepape ... de_r10.pdf

It can of course be used for this specific device. But that is not the question. The question is: How do we make this work for any device already in the usb_modeswitch default config. We need to somehow match on the MBIM subclass in the non-default configuration.

Given the problems with udev helpers, which pretty much will prevent a user from switching configs from any helper dictated default, I am starting to wonder if this policy is best placed in usb_choose_configuration() in the kernel after all. At least, that won't prevent neither user nor usb_modeswitch or any other helper from changing to a non-default config.

Bjørn

Josh
Site Admin
Posts: 6570
Joined: 03 Nov 2007, 00:30

Re: Switching MBIM devices

Post by Josh » 07 Sep 2012, 17:57

bmork wrote:But you cannot use the alternate configuration in udev rules. So you cannot say

Code: Select all

if any non active configuration matches class foo
then select that config
as an udev rule. You can only match on the attributes of the current config.
Again, I don't see any fundamental problem. Let usb_modeswitch (wrapper and binary) handle all 12d1:1446 devices that appear with if class 8. It will be able to do all the checking, with the necessary alterations of course. Here is the possible flow:
  1. Check number of configurations (and/or iProduct) - wrapper via sysfs
  2. If hints of MBIM, check availability of driver - wrapper
  3. If no driver, switch to 'legacy' modem - binary
  4. else double-check second configuration and select it - binary or wrapper
As a side note, I'm trying to keep linux-specific features out of the binary to maintain its portability.
Yes, the problem is that the device ID matches existing devices without MBIM. The default usb_modeswitch configuration will therefore switch the device into legacy mode.
I will work on the changes and provide a test package.

My guess is that there will be no manufacturer-independent solution, but that situation is no different than it was up to now. For the Huawei, the two configurations are a new and unique property.

I will look at your patch and I will change the whitelist for file extensions. Just updated the forum software to make attachments possible in the first place ...

bmork
Posts: 167
Joined: 15 Mar 2012, 22:47
Location: Oslo, Norway

Re: Switching MBIM devices

Post by bmork » 07 Sep 2012, 18:07

Josh wrote:Again, I don't see any fundamental problem. Let usb_modeswitch (wrapper and binary) handle all 12d1:1446 devices that appear with if class 8. It will be able to do all the checking, with the necessary alterations of course. Here is the possible flow:
  1. Check number of configurations (and/or iProduct) - wrapper via sysfs
  2. If hints of MBIM, check availability of driver - wrapper
  3. If no driver, switch to 'legacy' modem - binary
  4. else double-check second configuration and select it - binary or wrapper
Sounds good.
As a side note, I'm trying to keep linux-specific features out of the binary to maintain its portability.
Right. That should not be any problem here as you will only use libusb for this.
I will work on the changes and provide a test package.
Thanks. I appreciate it.
My guess is that there will be no manufacturer-independent solution, but that situation is no different than it was up to now.
Don't be too sure about this. Microsoft are pretty strict here, requiring the vendors to support their class based MBIM driver for Windows 8. They are not allowed to depend on any vendor specific driver. So we should be able to use the same rules to implement vendor independent mobile broadband modem support in Linux as well. Finally.

Josh
Site Admin
Posts: 6570
Joined: 03 Nov 2007, 00:30

Re: Switching MBIM devices

Post by Josh » 07 Sep 2012, 18:53

bmork wrote:
My guess is that there will be no manufacturer-independent solution, but that situation is no different than it was up to now.
Don't be too sure about this. Microsoft are pretty strict here, requiring the vendors to support their class based MBIM driver for Windows 8. They are not allowed to depend on any vendor specific driver. So we should be able to use the same rules to implement vendor independent mobile broadband modem support in Linux as well. Finally.
Yes, I hope so with respect to the actual interface and driver.

I was referring to the device preparation. And I don't think that on-board software is going to go away.

Well, let's just wait until the modems of other makers start to pop up.

Josh
Site Admin
Posts: 6570
Joined: 03 Nov 2007, 00:30

Re: Switching MBIM devices

Post by Josh » 07 Sep 2012, 22:40

I have prepared a quick test version:

http://www.draisberghof.de/usb_modeswit ... ta.tar.bz2

Howto:

Add option "CheckMBIM=1" to config file "12d1:1446" (put it into /etc/usb_modeswitch.d and it will be preferred).

To simulate the presence of a driver, create a file with a name containing "mbim" in /tmp.
Example: /tmp/mbim.ko

If no such file is present, the modem should be switched to the 'legacy' mode, otherwise the MBIM configuration should be activated.

I don't have a device with multiple configurations so I could not test all aspects.

bmork
Posts: 167
Joined: 15 Mar 2012, 22:47
Location: Oslo, Norway

Re: Switching MBIM devices

Post by bmork » 10 Sep 2012, 14:35

Josh wrote:I have prepared a quick test version:

http://www.draisberghof.de/usb_modeswit ... ta.tar.bz2

Howto:

Add option "CheckMBIM=1" to config file "12d1:1446" (put it into /etc/usb_modeswitch.d and it will be preferred).

To simulate the presence of a driver, create a file with a name containing "mbim" in /tmp.
Example: /tmp/mbim.ko

If no such file is present, the modem should be switched to the 'legacy' mode, otherwise the MBIM configuration should be activated.
This seems to work fine. Thanks. But it does have the annoying issue which I don't think any udev helper application can avoid:

Code: Select all

nemi:/tmp# grep . /sys/bus/usb/devices/2-2/bConfigurationValue 
2
nemi:/tmp# echo 1 >/sys/bus/usb/devices/2-2/bConfigurationValue 
nemi:/tmp# grep . /sys/bus/usb/devices/2-2/bConfigurationValue 
2
There are good reasons why an end user should be allowed to change to the non-default configuration, like wanting to mount the driver CD. Even if you add some workaround to usb-modeswitch, that is not going to match user expectations here. The user will expect the standard sysfs interface to work. I do not see any way to achieve that using the existing udev hotplug interface.
I don't have a device with multiple configurations so I could not test all aspects.
I see. There is a bug in usb_modeswitch.tcl related to multiple configurations in general:

Code: Select all

set ifdir "[file tail $devdir]:1.0"
The "1" in the above code is the currently active configuration. The hard coded value makes the script fail if any other configuration is active or activated during switching:

Code: Select all

Checking success of mode switch for max. 20 seconds ...
 Reading attributes ...
   Warning: USB attribute "2-2:1.0/bInterfaceClass" not found
 Essential attributes are missing, continue wait ...
 Reading attributes ...
   Warning: USB attribute "2-2:1.0/bInterfaceClass" not found
Because the currently active config is "2":

Code: Select all

bjorn@nemi:/tmp$ grep . /sys/bus/usb/devices/2-2:*/bInterfaceClass
/sys/bus/usb/devices/2-2:2.0/bInterfaceClass:02
/sys/bus/usb/devices/2-2:2.1/bInterfaceClass:0a


Bjørn

Josh
Site Admin
Posts: 6570
Joined: 03 Nov 2007, 00:30

Re: Switching MBIM devices

Post by Josh » 10 Sep 2012, 15:45

bmork wrote:This seems to work fine. Thanks. But it does have the annoying issue which I don't think any udev helper application can avoid
I can see the problem.

I wonder if it goes away if we change the "rules" file so that the rules match only for an "add" event instead of "add || change".
bmork wrote:There is a bug in usb_modeswitch.tcl related to multiple configurations in general [...] The hard coded value makes the script fail if any other configuration is active or activated during switching
A big slip on my side. I will correct this. Thanks for the heads-up!

bmork
Posts: 167
Joined: 15 Mar 2012, 22:47
Location: Oslo, Norway

Re: Switching MBIM devices

Post by bmork » 11 Sep 2012, 09:17

Josh wrote:
bmork wrote:This seems to work fine. Thanks. But it does have the annoying issue which I don't think any udev helper application can avoid
I can see the problem.

I wonder if it goes away if we change the "rules" file so that the rules match only for an "add" event instead of "add || change".
That's a good question. I just tested and found that you don't actually receive any device related event at all. But all the interfaces are of course removed and new ones added, and those add events are matched by usb-modeswitch. For example:

Code: Select all

KERNEL[10835.586741] remove   /devices/pci0000:00/0000:00:1d.7/usb8/8-2/8-2:1.0 (usb)
ACTION=remove
DEVPATH=/devices/pci0000:00/0000:00:1d.7/usb8/8-2/8-2:1.0
DEVTYPE=usb_interface
INTERFACE=8/6/80
MODALIAS=usb:v12D1p1446d0000dcEFdsc02dp01ic08isc06ip50in00
PRODUCT=12d1/1446/0
SEQNUM=2247
SUBSYSTEM=usb
TYPE=239/2/1
UDEV_LOG=3

KERNEL[10835.588216] add      /devices/pci0000:00/0000:00:1d.7/usb8/8-2/8-2:2.0 (usb)
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:1d.7/usb8/8-2/8-2:2.0
DEVTYPE=usb_interface
INTERFACE=2/14/0
MODALIAS=usb:v12D1p1446d0000dcEFdsc02dp01ic02isc0Eip00in00
PRODUCT=12d1/1446/0
SEQNUM=2248
SUBSYSTEM=usb
TYPE=239/2/1
UDEV_LOG=3
So what you could do is match on DEVTYPE=usb_device instead of SUBSYSTEM=usb. I have no idea if that have unwanted side effects, though....


Bjørn

Post Reply