OpenSolaris and USB Communication Device Class - Abstract Control Model



What is now

OpenSolaris currently doesn't support any USB device of Communication Device Class (CDC). In this article I want to explain what CDC is, how it is supported in other systems and how you can use some of those devices in OpenSolaris even without native driver.

Communication Device Class (CDC) is used for USB devices such as analog Modems, ISDN modems, telephone sets, Ethernet controls, ATM controls, etc. For particular types of device, CDC defines separates subclasses. One of probably mostly used subclasses is an Abstract Control Model (ACM). USB CDC-ACM device can be described as device which understands standard V.25ter (AT) commands. Since I am interested only in CDC-ACM devices (understand I have one of those), I will focus on this subclass only.

As I already stated OpenSolaris doesn't contain CDC native support at all. What about the other open systems? They do support it. Linux has got its cdc-acm driver and BSD clones (FreeBSD, OpenBSD, NetBSD) have their umodem (umodem(4)).

So, what we can do under OpenSolaris? We can try to write our own native CDC-ACM driver (the best start would be to use USB skeleton driver), use UGEN driver or potentially libusb(3LIB).

I will try to explain my particular experience with using of UGEN driver (man ugen(7D)). UGEN stands for USB generic driver and it was ported from NetBSD (NetBSD man page for ugen(4)).

Using USB CDC-ACM device under OpenSolaris to connect to internet via PPP

This procedure was tested with USB CDMA modem GPC-6420, which is used in Czech Republic by one of internet providers. Detailed description how to connect to internet from Solaris operating system with this device can be found on Vitezslav Batrla's blog (in Czech).

- Bind UGEN driver to CDC-ACM device

Use add_drv(1M) (use prtconf -vD, to get alias name for this command).

Example (note that examples here are specific to GPC-6420 modem):

add_drv -i '"usb5c6,3196.0"' -m '\* 0666 root sys' ugen

After UGEN is successfully bound and device is connected to USB port, there is created new directory structure under /dev/usb.

Example:

ls /dev/usb/5c6.3196/0/

cntrl0 devstat if0in1stat if1in10stat if1out11stat

cntrl0stat if0in1 if1in10 if1out11


This structure describes connected USB device and can be used for communication with the device. Communication can be done be using standard I/O operations such as open, read, write, ...

- Typical USB CDC-ACM device has the following structure

Control endpoint (every USB device has it) can be used in case of CDC-ACM for setting or inquiring of modem parameters (bit rate, data bits, ...). Corresponding UGEN files are cntrl0 (read/write) and cntrl0stat (used to read error code, when I/O operation on this endpoint fails).

Interface[0]:
- endpoint[0]: notification from device (events such connected/disconnected), corresponding UGEN files: if0in1 (interrupt mode) and if0in1stat (used to read error code, when I/O operation on this endpoint fails).

Interface[1]:
- endpoint[0]: data in (data from device, including response to AT commands), corresponding UGEN files: if1in10 (bulk mode) and if1in10stat (used to read error code, when I/O operation on this endpoint fails)
- endpoint[1]: data out (data to device, including AT commands), corresponding UGEN files: if1out11 (bulk mode) and if1out11stat (used to read error code, when I/O operation on this endpoint fails)

Note: device status can be read from UGEN file: devstat

- Dealing with UGEN timeouts

For our purposes we will use only if1in10 and if1out11. But before we can use it, we must change default timeout of 10 seconds. Otherwise we will receive EIO error, after reading from bulk endpoint (when there are no data available).

This can be done in Solaris 10 by adding the following line in /etc/system
set ugen:ugen_bulk_timeout = 3600
And the line for newer versions of Solaris operating system (Nevada) is:
set usba:ugen_bulk_timeout = 3600

Note: There is known issue (6333195), which makes x86/32 kernel to ignore this setting. One of possible workarounds is to ping to some IP address. Monitor Vita's blog for others.

- Configure PPP connection for your internet provider

The important point here is, that you should use pppd(1m) with option notty. This options will allow us to use as data channel redirected standard input/output from/to pppd instead of using real terminal device.

Connection to internet can be done then for example in this way:

cat /dev/usb/5c6.3196/0/if1in10 | pppd call [your_isp] > /dev/usb/5c6.3196/0/if1out11

Does OpenSolaris need native CDC-ACM driver?

My guess is that it would be better. Well, the solution I tried to present here is perfectly working and there doesn't seem to be any speed degradation. The main problem is that there are many existing applications (tip(1) is one of them :-) which expect real terminal device. It means they expect one device file to which they can write, read from and use standard terminal ioctls on it.

Comments:

Hi Petr,

Just trialling a USB acm device from MiniMax (High Speed wireless mobile broadband CDMA usb modem) issued by Telstra in Australia.

Got any hints?

The device is already attached to /dev/usb/device1 and when I try to use it with pppd I get the error:
cat: input error on /dev/usb/device1: No such device or address.


This is the output from prtconf -vD


communications, instance #1 (driver name: usb_mid)
Hardware properties:
name='driver-minor' type=int items=1
value=00000000
name='driver-major' type=int items=1
value=00000002
name='configuration#' type=int items=1
value=00000001
name='usb-product-name' type=string items=1
value='Qualcomm CDMA Technologies MSM'
name='usb-vendor-name' type=string items=1
value='Qualcomm, Incorporated'
name='usb-serialno' type=string items=1
value='Serial Number'
name='usb-release' type=int items=1
value=00000101
name='usb-num-configs' type=int items=1
value=00000001
name='usb-revision-id' type=int items=1
value=00000000
name='usb-product-id' type=int items=1
value=00003196
name='usb-vendor-id' type=int items=1
value=000005c6
name='compatible' type=string items=9
value='usb5c6,3196.0' + 'usb5c6,3196' + 'usb5c6,class2.0.0' + 'usb5c6.class2.0' + 'usb5c6.class2' + 'usb,class2.0.0' + 'usb,class2.0' + 'usb,class2' + 'usb,device'
name='reg' type=int items=1
value=00000001
name='assigned-address' type=int items=1
value=00000002
Device Minor Nodes:
dev=(58,1)
dev_path=/pci@0,0/pci1028,186@1d,2/communications@1:usb_mid
spectype=chr
type=minor
dev_link=/dev/usb/device1
modem
Hardware properties:
name='interface' type=int items=1
value=00000000
name='compatible'
type=string items=8
value='usbif5c6,3196.0.config1.0' + 'usbif5c6,3196.config1.0' + 'usbif5c6,class2.2.1' + 'usbif5c6,class2.2' + 'usbif5c6,class2' + 'usbif,class2.2.1' + 'usbif,class2.2' + 'usbif,class2'
name='reg' type=int items=2
value=00000000.00000001
name='assigned-address' type=int items=1
value=00000002
data
Hardware properties:
name='interface' type=int items=1
value=00000001
name='compatible' type=string items=8
value='usbif5c6,3196.0.config1.1' + 'usbif5c6,3196.config1.1' + 'usbif5c6,classa.0.0' + 'usbif5c6,classa.0' + 'usbif5c6,classa' + 'usbif,classa.0.0' + 'usbif,classa.0' + 'usbif,classa'
name='reg' type=int items=2
value=00000001.00000001
name='assigned-address' type=int items=1
value=00000002

Posted by Peter Firmstone on February 17, 2006 at 12:26 AM CET #

Post a Comment:
Comments are closed for this entry.
About

psum

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today