Hi all,

I am a linux developer ( for the company listed below ). We are developing
test devices for telecommunications systems using linux in portable PC's.

We have been supplied ( by Motorola ) with a new mobile phone which has a
USB serial port interface ( a T720, also known as a T280 in other countries
).


Motorola provided us with a usb serial device driver for this phone which
was developed under a version of the 2.2.x kernel. However, when I connected
the phone ( under 2.4.20-8 ) I had a number of problems.

The first problem is that the device cannot be assigned a new number if it
is connected to the usb bus AFTER the uhci_hcd module is loaded. I MUST
connect the phone BEFORE loading uhci_hcd. This problem sometimes shows up
as well if the phone is connected via a hub. ( either self-powered or cable
powered ). I get warnings about possible cable problems.

I have read on the web that this problem might be caused by slow usb control
firmware in the phone. At present I cannot find a cure for this problem.
NB: This problem does NOT occur when using the phone under MS windows or in
normal use of the phone as an AT device in Minicom, ONLY during initial
connection.



The second problem is a failure to configure the phone when connected.
Investigation revealed that the source of the problem is :

In the device configuration there are listed 3 interfaces, these are
numbered 0, 1 and 12 ( this is actually an engineering version, Im not sure
if the standard phone will have the '12' interface )

Section of cat /proc/bus/usb/devices follows ( my t720 device driver already
loaded ). I have placed a '*' on the relevant lines.

        T:  Bus=01 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#=  3 Spd=12  MxCh= 0
        D:  Ver= 1.10 Cls=ff(vend.) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
        P:  Vendor=22b8 ProdID=1004 Rev= 0.01
        S:  Manufacturer=Motorola Inc.
        S:  Product=Motorola Phone (T720)
        C:* #Ifs= 3 Cfg#= 1 Atr=c0 MxPwr= 20mA
*       I:  If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=02 Prot=01
Driver=usbserial
        E:  Ad=89(I) Atr=03(Int.) MxPS=  16 Ivl=10ms
*       I:  If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00
Driver=usbserial
        E:  Ad=01(O) Atr=02(Bulk) MxPS=  16 Ivl=0ms
        E:  Ad=82(I) Atr=02(Bulk) MxPS=  16 Ivl=0ms
*       I:  If#=12 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=08 Prot=ff
Driver=usbserial
        E:  Ad=03(O) Atr=02(Bulk) MxPS=  16 Ivl=0ms
        E:  Ad=84(I) Atr=02(Bulk) MxPS=  32 Ivl=0ms
        [EMAIL PROTECTED] linux-2.6.1]# lsmod
        Module                  Size  Used by
        uhci_hcd               30664  0
        ftdi_sio               27716  0
        t720                    2336  0
        usbserial              29968  2 ftdi_sio,t720
        usbcore               111732  5 uhci_hcd,ftdi_sio,usbserial
        autofs                 15200  0
        parport_pc             26152  0
        parport                40832  1 parport_pc


( NB: Ignore the ftdi_sio, this is another usb<->RS232 device )

This causes the file drivers/usb/core/config.c to fail as it expects the
interface numbers to be contiguous. The kernel 2.4.x did not have a check
for this and caused a kernel dump during usb_parse_interface(). The kernel
2.6.1 adds a check for this but causes the phone to be rejected as a result.

( NB: This is started when I modprobe uhci_hcd, before the phone driver is
even loaded ).


Therefore I have made some changes to the files drivers/usb/core/config.c
and include/linux/usb.h files to store the device interface number and
process the reported interfaces as a counter incremented array, rather than
directly using the reported interface number as the array index

I have tested these changes with our test mobile phone, a usb 1.1 hub, a usb
2.0 PCMCIA card reader, usb audio device and a ftdi_sio usb-serial
convertor.

I am now ready to submit them for further testing and possible future
inclusion into the linux kernel. I have also added the Motorola t720 driver
to my local copy of the linux kernel source build ( modified my Kconfig and
Makefile in the drivers/usb/serial directory )


Any help/advice with a resolution to the first problem is greatly
appreciated, as are suggestions for improvements to the changes I have made.

NB: I have been reading all the documentation I can find on interface
descriptors and can find no requirement for the interface numbers to be in
any specific order, let alone being contiguous so I believe this to be
perfectly legal under the USB spec ).


The changes are as follows :

( NB: this is from the drivers/usb/core/config.c file in 2.6.1, my modified
file=config.c, against the distributed source file=config.c.orig ).


[EMAIL PROTECTED] linux-2.6.1]# diff -u drivers/usb/core/config.c
drivers/usb/core/config.c.orig
--- drivers/usb/core/config.c   2004-01-23 15:10:14.000000000 +0000
+++ drivers/usb/core/config.c.orig      2004-01-22 17:01:43.000000000 +0000
@@ -108,15 +108,8 @@
                        d->bDescriptorType, USB_DT_INTERFACE);
                return -EINVAL;
        }
-
-       /* We have got the interfacenumber, search the config->interface[]
-               table to find the relevant array position */
-       inum = d->bInterfaceNumber;
-       i = 0;
-       while(inum != config->interface[i]->bifNumber && i <
config->desc.bNumInterfaces)
-               i++;
-       inum = i;

+       inum = d->bInterfaceNumber;
        if (inum >= config->desc.bNumInterfaces) {

                /* Skip to the next interface descriptor */
@@ -206,7 +199,6 @@
        return buffer - buffer0;
}

-
 int usb_parse_configuration(struct usb_host_config *config, char *buffer,
int size)
 {
        int nintf, nintf_orig;
@@ -228,7 +220,6 @@
        config->desc.wTotalLength = size;

        nintf = nintf_orig = config->desc.bNumInterfaces;
-
        if (nintf > USB_MAXINTERFACES) {
                warn("too many interfaces (%d max %d)",
                    nintf, USB_MAXINTERFACES);
@@ -236,16 +227,13 @@
        }

        for (i = 0; i < nintf; ++i) {
-
                interface = config->interface[i] =
                    kmalloc(sizeof(struct usb_interface), GFP_KERNEL);
                dbg("kmalloc IF %p, numif %i", interface, i);
-
                if (!interface) {
                        err("out of memory");
                        return -ENOMEM;
                }
-
                memset(interface, 0, sizeof(struct usb_interface));
                interface->dev.release = usb_release_intf;
                device_initialize(&interface->dev);
@@ -256,9 +244,6 @@
        buffer2 = buffer;
        size2 = size;
        j = 0;
-
-        i = 0; /* make i a usb_interface array index - 1st array pos */
-
        while (size2 >= sizeof(struct usb_descriptor_header)) {
                header = (struct usb_descriptor_header *) buffer2;
                if ((header->bLength > size2) || (header->bLength < 2)) {
@@ -274,29 +259,14 @@
                                return -EINVAL;
                        }
                        d = (struct usb_interface_descriptor *) header;
-
-                       /* Have we already stored this interfacenumber ? */
-                       if(config->interface[i]->bifNumber !=
d->bInterfaceNumber)
-                               i++; /* No, move to next location */
-
-                       /* Note: This will fail if the interface numbers
-                               ever arrive in non-linear order
-                               eg. 0, 1, 2 and 0, 1, 12 and 0, 1, 1, 2 are
okay
-                                   0, 1, 1, 2, 2, 1, 1, 3 is bad */
-
-                       /* make i the index position and store the
-                               interface number in the struct,
-                               is it used anywhere else ? */
-                       /* i = d->bInterfaceNumber; */
-                       config->interface[i]->bifNumber =
d->bInterfaceNumber;
-
+                       i = d->bInterfaceNumber;
                        if (i >= nintf_orig) {
                                warn("invalid interface number (%d/%d)",
                                    i, nintf_orig);
                                return -EINVAL;
                        }
-                        if (i < nintf)
-                                ++config->interface[i]->num_altsetting;
+                       if (i < nintf)
+                               ++config->interface[i]->num_altsetting;

                } else if ((header->bDescriptorType == USB_DT_DEVICE ||
                    header->bDescriptorType == USB_DT_CONFIG) && j) {
@@ -305,7 +275,6 @@
                }

                j = 1;
-
                buffer2 += header->bLength;
                size2 -= header->bLength;
        }
@@ -313,7 +282,6 @@
        /* Allocate the altsetting arrays */
        for (i = 0; i < config->desc.bNumInterfaces; ++i) {
                interface = config->interface[i];
-
                if (interface->num_altsetting > USB_MAXALTSETTING) {
                        warn("too many alternate settings for interface %d
(%d max %d)\n",
                            i, interface->num_altsetting,
USB_MAXALTSETTING);
@@ -372,7 +340,6 @@
        /* Check for missing altsettings */
        for (i = 0; i < nintf; ++i) {
                interface = config->interface[i];
-
                for (j = 0; j < interface->num_altsetting; ++j) {
                        if (!interface->altsetting[j].desc.bLength) {
                                warn("missing altsetting %d for interface
%d", j, i);
[EMAIL PROTECTED] linux-2.6.1]#




Apologies if any of this is made unclear by the post or line-wrapping. Im
extremely new to this list ( as in, about 4 days ) so Im not sure on the
EXACT procedure. I will also have a device driver for the phone to post in
addition to the change for the configuration .



Thanks - Graeme

----------------------------------------
Graeme Jones - Software Developer, Research And Development

ROSCOM Limited

Bateman Street
Derby
Derbyshire
DE23 8JQ
ENGLAND

Tel : +44 1332 344990
Fax : +44 1332 206424
www.roscom.co.uk

DISCLAIMER : The contents of this e-mail and any attachments are
confidential and are intended only for the use of the recipient(s) unless
otherwise indicated. If you have received this e-mail in error, please
notify the sender(s) immediately by telephone. Please destroy and delete the
message from your computer. Any form of reproduction, dissemination,
copying, disclosure, modification, distribution and/or publication of this
e-mail is strictly prohibited unless expressly authorised by the sender(s).
No person, without written confirmation of the contents of this e-mail,
should rely on it. Whilst this e-mail and the information it contains are
supplied in good faith, ROSCOM Limited, shall be under no liability in
respect of the contents of this e-mail or for any reliance the recipient may
place on it. This e-mail is sent for information purposes only and shall not
have the effect of creating a contract between the parties.

VIRUSES : ROSCOM takes every care to ensure that every employee scans all
attachments for viruses using a leading Virus Checker and the latest virus
updates. The virus scanner package may not be able to detect all viruses and
variants. Please be aware that there is a risk involved whenever downloading
e-mail attachments to your computer and that, ROSCOM is not responsible for
any damages caused by your decision to do so.




-------------------------------------------------------
The SF.Net email is sponsored by EclipseCon 2004
Premiere Conference on Open Tools Development and Integration
See the breadth of Eclipse activity. February 3-5 in Anaheim, CA.
http://www.eclipsecon.org/osdn
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to