Hello all,
I'd like some advice in getting a Siemens M34 USB DECT adapter to work
with Linux. This device announces itself (or, more precisely, four out
of its eight interfaces) as "Communications Class, Abstract Control
Model Subclass, V.25ter Protocol", but deviates sufficiently from the
standard that cdc-acm.c v0.24 refuses to claim it. The vendor (Siemens)
flatly refused to share any information about the device, but I'd really
like to get it to work anyway, because (a) the hardware is damn cute,
(b) users of our Siemens Gigaset 307x driver have been asking for it,
and (c) just to show them. ;-)
Leaving aside the "firmware update" and "audio" interfaces, I find
myself in front of four (4) CDC ACM interfaces, whose descriptors
(output of lsusb -vv attached) all look somewhat odd to me:
- Three of these interfaces (#0, #2 and #3) claim to be their own master
and slave at the same time (ie. they carry a union descriptor with both
bMasterInterface and bSlaveInterface equal to their own interface
number), while the fourth (#4), even more strangely, claims the firmware
update interface (#1) as its master and the first ACM device (#0) as its
slave.
- Two of them (#0 and #4) have only a notification endpoint, while the
other two (#2 and #3) include a pair of bulk endpoints and so just might
be able to support data connections.
I managed to hack cdc-acm.c so that it would at least accept the latter
two as modem devices. (Patch attached. It seems that cdc-acm.c was sort
of prepared for something like that already.) But during initialization
the second acm_control_msg already results in -ETIMEOUT:
> Nov 28 09:07:43 linux kernel: drivers/usb/class/cdc-acm.c: interfaces are
> valid
> Nov 28 09:07:43 linux kernel: cdc_acm 1-2:1.2: ttyACM0: USB ACM device
> Nov 28 09:07:43 linux kernel: drivers/usb/class/cdc-acm.c: acm_control_msg:
> rq: 0x22 val: 0x0 len: 0x0 result: 0
> Nov 28 09:07:49 linux kernel: drivers/usb/class/cdc-acm.c: acm_control_msg:
> rq: 0x20 val: 0x0 len: 0x7 result: -110
and when I open the corresponding device /dev/ttyACM0 with minicom and
try to send some AT commands to the device I never get any reply.
Am I on the right track at all or have I got it all completely wrong?
Do my changes to cdc-acm.c make any sense?
Thanks in advance for any hints.
Tilman
--
Tilman Schmidt E-Mail: [EMAIL PROTECTED]
Bonn, Germany
Diese Nachricht besteht zu 100% aus wiederverwerteten Bits.
Ungeöffnet mindestens haltbar bis: (siehe Rückseite)
Bus 001 Device 003: ID 0681:0026 Siemens Information and Communication Products
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 16
idVendor 0x0681 Siemens Information and Communication Products
idProduct 0x0026
bcdDevice 1.00
iManufacturer 3 Siemens AG
iProduct 2 DECT Data Device
iSerial 1 00823FC8AA
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 362
bNumInterfaces 8
bConfigurationValue 1
iConfiguration 4 DECT Configuration Descriptor
bmAttributes 0xe0
Self Powered
Remote Wakeup
MaxPower 90mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 2 Communications
bInterfaceSubClass 2 Abstract (modem)
bInterfaceProtocol 1 AT-commands (v.25ter)
iInterface 6 Cordless Device Configuration
invalid: 06 24 00 01 10 01
CDC ACM:
bmCapabilities 0x08
connection notifications
CDC Union:
bMasterInterface 0
bSlaveInterface 0
CDC Call Management:
bmCapabilities 0x01
call management
bDataInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 8
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 254 Application Specific Interface
bInterfaceSubClass 1 Device Firmware Update
bInterfaceProtocol 0
iInterface 5 Cordless Device Update
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 2 Communications
bInterfaceSubClass 2 Abstract (modem)
bInterfaceProtocol 1 AT-commands (v.25ter)
iInterface 7 Cordless Internet Access
invalid: 06 24 00 01 10 01
CDC ACM:
bmCapabilities 0x08
connection notifications
CDC Union:
bMasterInterface 2
bSlaveInterface 2
CDC Call Management:
bmCapabilities 0x05
call management
bDataInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 8
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x04 EP 4 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 3
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 2 Communications
bInterfaceSubClass 2 Abstract (modem)
bInterfaceProtocol 1 AT-commands (v.25ter)
iInterface 8 Cordless Device Line Access
invalid: 06 24 00 01 10 01
CDC ACM:
bmCapabilities 0x08
connection notifications
CDC Union:
bMasterInterface 3
bSlaveInterface 3
CDC Call Management:
bmCapabilities 0x05
call management
bDataInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x85 EP 5 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 8
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x86 EP 6 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0020 1x 32 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x07 EP 7 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0020 1x 32 bytes
bInterval 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 4
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 2 Communications
bInterfaceSubClass 2 Abstract (modem)
bInterfaceProtocol 1 AT-commands (v.25ter)
iInterface 9 Cordless PC Control
invalid: 06 24 00 01 10 01
CDC ACM:
bmCapabilities 0x08
connection notifications
CDC Union:
bMasterInterface 1
bSlaveInterface 0
CDC Call Management:
bmCapabilities 0x01
call management
bDataInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x88 EP 8 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 8
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 5
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 1 Control Device
bInterfaceProtocol 0
iInterface 10 Cordless Audio Interface
AudioControl Interface Descriptor:
bLength 10
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdADC 1.00
wTotalLength 52
bInCollection 2
baInterfaceNr( 0) 6
baInterfaceNr( 1) 7
AudioControl Interface Descriptor:
bLength 12
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 1
wTerminalType 0x0201 Microphone
bAssocTerminal 0
bNrChannels 1
wChannelConfig 0x0000
iChannelNames 0
iTerminal 0
AudioControl Interface Descriptor:
bLength 12
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 3
wTerminalType 0x0101 USB Streaming
bAssocTerminal 0
bNrChannels 1
wChannelConfig 0x0000
iChannelNames 0
iTerminal 0
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (OUTPUT_TERMINAL)
bTerminalID 4
wTerminalType 0x0101 USB Streaming
bAssocTerminal 0
bSourceID 1
iTerminal 0
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (OUTPUT_TERMINAL)
bTerminalID 2
wTerminalType 0x0502 Telephone
bAssocTerminal 0
bSourceID 3
iTerminal 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 6
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 10 Cordless Audio Interface
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 6
bAlternateSetting 1
bNumEndpoints 1
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 0
AudioStreaming Interface Descriptor:
bLength 7
bDescriptorType 36
bDescriptorSubtype 1 (AS_GENERAL)
bTerminalLink 3
bDelay 1 frames
wFormatTag 1 PCM
AudioStreaming Interface Descriptor:
bLength 11
bDescriptorType 36
bDescriptorSubtype 2 (FORMAT_TYPE)
bFormatType 1 (FORMAT_TYPE_I)
bNrChannels 1
bSubframeSize 2
bBitResolution 16
bSamFreqType 1 Discrete
tSamFreq[ 0] 8000
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x09 EP 9 OUT
bmAttributes 1
Transfer Type Isochronous
Synch Type None
Usage Type Data
wMaxPacketSize 0x0010 1x 16 bytes
bInterval 1
bRefresh 0
bSynchAddress 0
AudioControl Endpoint Descriptor:
bLength 7
bDescriptorType 37
bDescriptorSubtype 1 (EP_GENERAL)
bmAttributes 0x00
bLockDelayUnits 0 Undefined
wLockDelay 0 Undefined
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 7
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 10 Cordless Audio Interface
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 7
bAlternateSetting 1
bNumEndpoints 1
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 0
AudioStreaming Interface Descriptor:
bLength 7
bDescriptorType 36
bDescriptorSubtype 1 (AS_GENERAL)
bTerminalLink 4
bDelay 1 frames
wFormatTag 1 PCM
AudioStreaming Interface Descriptor:
bLength 11
bDescriptorType 36
bDescriptorSubtype 2 (FORMAT_TYPE)
bFormatType 1 (FORMAT_TYPE_I)
bNrChannels 1
bSubframeSize 2
bBitResolution 16
bSamFreqType 1 Discrete
tSamFreq[ 0] 8000
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x8a EP 10 IN
bmAttributes 1
Transfer Type Isochronous
Synch Type None
Usage Type Data
wMaxPacketSize 0x0010 1x 16 bytes
bInterval 1
bRefresh 0
bSynchAddress 0
AudioControl Endpoint Descriptor:
bLength 7
bDescriptorType 37
bDescriptorSubtype 1 (EP_GENERAL)
bmAttributes 0x00
bLockDelayUnits 0 Undefined
wLockDelay 0 Undefined
--- cdc-acm.c.orig 2005-11-28 16:51:36.000000000 +0100
+++ cdc-acm.c 2005-11-03 02:41:31.000000000 +0100
@@ -47,7 +47,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#undef DEBUG
+#define DEBUG
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -538,7 +538,7 @@
u8 ac_management_function = 0;
u8 call_management_function = 0;
int call_interface_num = -1;
- int data_interface_num;
+ int data_interface_num = -1;
unsigned long quirks;
/* handle quirks deadly to normal probing*/
@@ -619,6 +619,13 @@
dev_dbg(&intf->dev,"no interfaces\n");
return -ENODEV;
}
+ if (call_interface_num != union_header->bMasterInterface0) {
+ dev_dbg(&intf->dev, "Warning: bMasterInterface0=%d,
call_interface_num=%d, data_interface_num=%d\n",
+ union_header->bMasterInterface0,
+ call_interface_num, data_interface_num);
+ /* experiment: */
+ call_interface_num = union_header->bMasterInterface0;
+ }
}
if (data_interface_num != call_interface_num)
@@ -636,26 +643,45 @@
control_interface = data_interface;
data_interface = t;
} else {
- return -EINVAL;
+ dev_dbg(&intf->dev, "No data interface. (if %d class
0x%02x, if %d class 0x%02x)\n",
+ data_interface_num,
+
data_interface->cur_altsetting->desc.bInterfaceClass,
+ call_interface_num,
+
control_interface->cur_altsetting->desc.bInterfaceClass);
+ /* experiment: */
+ /* return -EINVAL; */
}
}
- if (usb_interface_claimed(data_interface)) { /* valid in this context */
+ if (data_interface != intf && usb_interface_claimed(data_interface)) {
/* valid in this context */
dev_dbg(&intf->dev,"The data interface isn't available\n");
return -EBUSY;
}
- if (data_interface->cur_altsetting->desc.bNumEndpoints < 2)
+ if (data_interface->cur_altsetting->desc.bNumEndpoints < 2) {
+ dev_dbg(&intf->dev, "Data interface bNumEndpoints = %d.\n",
data_interface->cur_altsetting->desc.bNumEndpoints);
return -EINVAL;
+ }
epctrl = &control_interface->cur_altsetting->endpoint[0].desc;
epread = &data_interface->cur_altsetting->endpoint[0].desc;
epwrite = &data_interface->cur_altsetting->endpoint[1].desc;
+ /* experiment: */
+ if (epread == epctrl) {
+ if (data_interface->cur_altsetting->desc.bNumEndpoints < 3) {
+ dev_dbg(&intf->dev, "Data interface bNumEndpoints =
%d.\n", data_interface->cur_altsetting->desc.bNumEndpoints);
+ return -EINVAL;
+ }
+ dev_dbg(&intf->dev, "Shared interface, shifting data EPs.\n");
+ epread = &data_interface->cur_altsetting->endpoint[1].desc;
+ epwrite = &data_interface->cur_altsetting->endpoint[2].desc;
+ }
/* workaround for switched endpoints */
- if ((epread->bEndpointAddress & USB_DIR_IN) != USB_DIR_IN) {
+ if (usb_pipeout(epread->bEndpointAddress))
+ if (usb_pipein(epwrite->bEndpointAddress)) {
/* descriptors are swapped */
struct usb_endpoint_descriptor *t;
dev_dbg(&intf->dev,"The data interface has switched
endpoints\n");
@@ -663,7 +689,15 @@
t = epread;
epread = epwrite;
epwrite = t;
- }
+ } else {
+ err("Bad data endpoint directions. (both out)\n");
+ return -EINVAL;
+ }
+ else
+ if (usb_pipein(epwrite->bEndpointAddress)) {
+ err("Bad data endpoint directions. (both in)\n");
+ return -EINVAL;
+ }
dbg("interfaces are valid");
for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++);