On Mon, May 31, 2004 at 02:15:23PM +0200, Oliver Neukum wrote:
> Hi,
> 
> I am sorry. I should have sent you this long ago.
> 
>       Sorry
>               Oliver
> 
> Signed-off-by: Oliver Neukum <[EMAIL PROTECTED]>

Signed-off-by: Vojtech Pavlik <[EMAIL PROTECTED]>

Greg, another one for you, and you need to apply this one first.

Oliver - thanks, I suppose this will fix problems with some of the
devices that have slightly unusual descriptor sets.

> 
> You can import this changeset into BK by piping this whole message to:
> '| bk receive [path to repository]' or apply the patch as usual.
> 
> ===================================================================
> 
> 
> [EMAIL PROTECTED], 2004-05-30 10:50:37+02:00, [EMAIL PROTECTED]
>   - fix probing to use cdc union descriptor
> 
> 
>  cdc-acm.c |  274 ++++++++++++++++++++++----------------------------------------
>  cdc-acm.h |  114 +++++++++++++++++++++++++
>  2 files changed, 214 insertions(+), 174 deletions(-)
> 
> 
diff -Nru a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
--- a/drivers/usb/class/cdc-acm.c       Sun May 30 10:56:45 2004
+++ b/drivers/usb/class/cdc-acm.c       Sun May 30 10:56:45 2004
@@ -60,6 +60,8 @@
 #include <linux/usb.h>
 #include <asm/byteorder.h>
 
+#include "cdc-acm.h"
+
 /*
  * Version Information
  */
@@ -67,98 +69,6 @@
 #define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik"
 #define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN 
adapters"
 
-/*
- * CMSPAR, some architectures can't have space and mark parity.
- */
-
-#ifndef CMSPAR
-#define CMSPAR                 0
-#endif
-
-/*
- * Major and minor numbers.
- */
-
-#define ACM_TTY_MAJOR          166
-#define ACM_TTY_MINORS         32
-
-/*
- * Requests.
- */
-
-#define USB_RT_ACM             (USB_TYPE_CLASS | USB_RECIP_INTERFACE)
-
-#define ACM_REQ_COMMAND                0x00
-#define ACM_REQ_RESPONSE       0x01
-#define ACM_REQ_SET_FEATURE    0x02
-#define ACM_REQ_GET_FEATURE    0x03
-#define ACM_REQ_CLEAR_FEATURE  0x04
-
-#define ACM_REQ_SET_LINE       0x20
-#define ACM_REQ_GET_LINE       0x21
-#define ACM_REQ_SET_CONTROL    0x22
-#define ACM_REQ_SEND_BREAK     0x23
-
-/*
- * IRQs.
- */
-
-#define ACM_IRQ_NETWORK                0x00
-#define ACM_IRQ_LINE_STATE     0x20
-
-/*
- * Output control lines.
- */
-
-#define ACM_CTRL_DTR           0x01
-#define ACM_CTRL_RTS           0x02
-
-/*
- * Input control lines and line errors.
- */
-
-#define ACM_CTRL_DCD           0x01
-#define ACM_CTRL_DSR           0x02
-#define ACM_CTRL_BRK           0x04
-#define ACM_CTRL_RI            0x08
-
-#define ACM_CTRL_FRAMING       0x10
-#define ACM_CTRL_PARITY                0x20
-#define ACM_CTRL_OVERRUN       0x40
-
-/*
- * Line speed and caracter encoding.
- */
-
-struct acm_line {
-       __u32 speed;
-       __u8 stopbits;
-       __u8 parity;
-       __u8 databits;
-} __attribute__ ((packed));
-
-/*
- * Internal driver structures.
- */
-
-struct acm {
-       struct usb_device *dev;                         /* the corresponding usb 
device */
-       struct usb_interface *control;                  /* control interface */
-       struct usb_interface *data;                     /* data interface */
-       struct tty_struct *tty;                         /* the corresponding tty */
-       struct urb *ctrlurb, *readurb, *writeurb;       /* urbs */
-       struct acm_line line;                           /* line coding (bits, stop, 
parity) */
-       struct work_struct work;                        /* work queue entry for line 
discipline waking up */
-       struct tasklet_struct bh;                       /* rx processing */
-       unsigned int ctrlin;                            /* input control lines (DCD, 
DSR, RI, break, overruns) */
-       unsigned int ctrlout;                           /* output control lines (DTR, 
RTS) */
-       unsigned int writesize;                         /* max packet size for the 
output bulk endpoint */
-       unsigned int used;                              /* someone has this acm's 
device open */
-       unsigned int minor;                             /* acm minor number */
-       unsigned char throttle;                         /* throttled by tty layer */
-       unsigned char clocal;                           /* termios CLOCAL */
-};
-
 static struct usb_driver acm_driver;
 static struct tty_driver *acm_tty_driver;
 static struct acm *acm_table[ACM_TTY_MINORS];
@@ -567,77 +477,102 @@
  * USB probe and disconnect routines.
  */
 
-#define CHECK_XFERTYPE(descr, xfer_type) (((descr)->bmAttributes & 
USB_ENDPOINT_XFERTYPE_MASK) == xfer_type)
-                       
 static int acm_probe (struct usb_interface *intf,
                      const struct usb_device_id *id)
 {
-       struct usb_device *dev;
+       struct union_desc *union_header = NULL;
+       char *buffer = intf->altsetting->extra;
+       int buflen = intf->altsetting->extralen;
+       struct usb_interface *control_interface;
+       struct usb_interface *data_interface;
+       struct usb_endpoint_descriptor *epctrl;
+       struct usb_endpoint_descriptor *epread;
+       struct usb_endpoint_descriptor *epwrite;
+       struct usb_device *usb_dev = interface_to_usbdev(intf);
        struct acm *acm;
-       struct usb_host_config *cfacm;
-       struct usb_interface *data = NULL;
-       struct usb_host_interface *ifcom, *ifdata = NULL;
-       struct usb_endpoint_descriptor *epctrl = NULL;
-       struct usb_endpoint_descriptor *epread = NULL;
-       struct usb_endpoint_descriptor *epwrite = NULL;
-       int readsize, ctrlsize, minor, j;
-       unsigned char *buf;
-
-       dev = interface_to_usbdev (intf);
-
-       cfacm = dev->actconfig;
-
-       /* We know we're probe()d with the control interface. */
-       ifcom = intf->cur_altsetting;
-
-       /* ACM doesn't guarantee the data interface is
-        * adjacent to the control interface, or that if one
-        * is there it's not for call management ... so find
-        * it
-        */
-       for (j = 0; j < cfacm->desc.bNumInterfaces; j++) {
-               ifdata = cfacm->interface[j]->cur_altsetting;
-               data = cfacm->interface[j];
-
-               if (ifdata->desc.bInterfaceClass == USB_CLASS_CDC_DATA
-                   && ifdata->desc.bNumEndpoints == 2) {
-                       
-                       epctrl = &ifcom->endpoint[0].desc;
-                       epread = &ifdata->endpoint[0].desc;
-                       epwrite = &ifdata->endpoint[1].desc;
-
-                       if ((epctrl->bEndpointAddress & USB_DIR_IN) != USB_DIR_IN
-                           || !CHECK_XFERTYPE(epctrl,  USB_ENDPOINT_XFER_INT)
-                           || !CHECK_XFERTYPE(epread,  USB_ENDPOINT_XFER_BULK)
-                           || !CHECK_XFERTYPE(epwrite, USB_ENDPOINT_XFER_BULK)
-                           || ((epread->bEndpointAddress & USB_DIR_IN)
-                               ^ (epwrite->bEndpointAddress & USB_DIR_IN)) != 
USB_DIR_IN) {
-                               /* not suitable */
-                               goto next_interface;
-                       }
-                       
-                       if ((epread->bEndpointAddress & USB_DIR_IN) != USB_DIR_IN) {
-                               /* descriptors are swapped */
-                               epread = &ifdata->endpoint[1].desc;
-                               epwrite = &ifdata->endpoint[0].desc;
-                       }
-                       dev_dbg(&intf->dev, "found data interface at %d\n", j);
-                       break;
-               } else {
-next_interface:
-                       ifdata = NULL;
-                       data = NULL;
+       int minor;
+       int ctrlsize,readsize;
+       char *buf;
+
+       if (!buffer) {
+               err("Wierd descriptor references");
+               return -EINVAL;
+       }
+
+       while (buflen > 0) {
+               if (buffer [1] != USB_DT_CS_INTERFACE) {
+                       err("skipping garbage");
+                       goto next_desc;
                }
+
+               switch (buffer [2]) {
+                       case CDC_UNION_TYPE: /* we've found it */
+                               if (union_header) {
+                                       err("More than one union descriptor, skipping 
...");
+                                       goto next_desc;
+                               }
+                               union_header = (struct union_desc *)buffer;
+                               break;
+                       default:
+                               err("Ignoring extra header");
+                               break;
+                       }
+next_desc:
+               buflen -= buffer[0];
+               buffer += buffer[0];
+       }
+
+       if (!union_header) {
+               dev_dbg(&intf->dev,"No union descriptor, giving up\n");
+               return -ENODEV;
        }
 
-       /* there's been a problem */
-       if (!ifdata) {
-               dev_dbg(&intf->dev, "data interface not found\n");
+       control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0);
+       data_interface = usb_ifnum_to_if(usb_dev, union_header->bSlaveInterface0);
+       if (!control_interface || !data_interface) {
+               dev_dbg(&intf->dev,"no interfaces\n");
                return -ENODEV;
+       }
 
+       if (usb_interface_claimed(data_interface)) { /* valid in this context */
+               dev_dbg(&intf->dev,"The data interface isn't available\n");
+               return -EBUSY;
        }
 
+       /*workaround for switched interfaces */
+       if (data_interface->cur_altsetting->desc.bInterfaceClass != 
CDC_DATA_INTERFACE_TYPE) {
+               if (control_interface->cur_altsetting->desc.bInterfaceClass == 
CDC_DATA_INTERFACE_TYPE) {
+                       struct usb_interface *t;
+                       dev_dbg(&intf->dev,"Your device has switched interfaces.\n");
+
+                       t = control_interface;
+                       control_interface = data_interface;
+                       data_interface = t;
+               } else {
+                       return -EINVAL;
+               }
+       }
+       if (data_interface->cur_altsetting->desc.bNumEndpoints < 2)
+               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;
+
+
+       /* workaround for switched endpoints */
+       if ((epread->bEndpointAddress & USB_DIR_IN) != USB_DIR_IN) {
+               /* descriptors are swapped */
+               struct usb_endpoint_descriptor *t;
+               dev_dbg(&intf->dev,"The data interface has switched endpoints\n");
+               
+               t = epread;
+               epread = epwrite;
+               epwrite = t;
+       }
+       dbg("interfaces are valid");
        for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++);
+
        if (acm_table[minor]) {
                err("no more free acm devices");
                return -ENODEV;
@@ -647,21 +582,21 @@
                dev_dbg(&intf->dev, "out of memory (acm kmalloc)\n");
                return -ENOMEM;
        }
-       
        memset(acm, 0, sizeof(struct acm));
 
        ctrlsize = epctrl->wMaxPacketSize;
        readsize = epread->wMaxPacketSize;
        acm->writesize = epwrite->wMaxPacketSize;
-       acm->control = intf;
-       acm->data = data;
+       acm->control = control_interface;
+       acm->data = data_interface;
        acm->minor = minor;
-       acm->dev = dev;
+       acm->dev = usb_dev;
 
        acm->bh.func = acm_rx_tasklet;
        acm->bh.data = (unsigned long) acm;
        INIT_WORK(&acm->work, acm_softint, acm);
 
+
        if (!(buf = kmalloc(ctrlsize + readsize + acm->writesize, GFP_KERNEL))) {
                dev_dbg(&intf->dev, "out of memory (buf kmalloc)\n");
                kfree(acm);
@@ -693,29 +628,17 @@
                return -ENOMEM;
        }
 
-       usb_fill_int_urb(acm->ctrlurb, dev, usb_rcvintpipe(dev, 
epctrl->bEndpointAddress),
-               buf, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval);
+       usb_fill_int_urb(acm->ctrlurb, usb_dev, usb_rcvintpipe(usb_dev, 
epctrl->bEndpointAddress),
+                        buf, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval);
 
-       usb_fill_bulk_urb(acm->readurb, dev, usb_rcvbulkpipe(dev, 
epread->bEndpointAddress),
-               buf += ctrlsize, readsize, acm_read_bulk, acm);
+       usb_fill_bulk_urb(acm->readurb, usb_dev, usb_rcvbulkpipe(usb_dev, 
epread->bEndpointAddress),
+                         buf += ctrlsize, readsize, acm_read_bulk, acm);
        acm->readurb->transfer_flags |= URB_NO_FSBR;
 
-       usb_fill_bulk_urb(acm->writeurb, dev, usb_sndbulkpipe(dev, 
epwrite->bEndpointAddress),
-               buf += readsize, acm->writesize, acm_write_bulk, acm);
+       usb_fill_bulk_urb(acm->writeurb, usb_dev, usb_sndbulkpipe(usb_dev, 
epwrite->bEndpointAddress),
+                         buf += readsize, acm->writesize, acm_write_bulk, acm);
        acm->writeurb->transfer_flags |= URB_NO_FSBR;
 
-       if ( (j = usb_driver_claim_interface(&acm_driver, data, acm)) != 0) {
-               err("claim failed");
-               usb_free_urb(acm->ctrlurb);
-               usb_free_urb(acm->readurb);
-               usb_free_urb(acm->writeurb);
-               kfree(acm);
-               kfree(buf);
-               return j;
-       } 
-
-       tty_register_device(acm_tty_driver, minor, &intf->dev);
-
        dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor);
 
        acm_set_control(acm, acm->ctrlout);
@@ -724,11 +647,14 @@
        acm->line.databits = 8;
        acm_set_line(acm, &acm->line);
 
+       usb_driver_claim_interface(&acm_driver, data_interface, acm);
+
+       tty_register_device(acm_tty_driver, minor, &intf->dev);
+
        acm_table[minor] = acm;
        usb_set_intfdata (intf, acm);
        return 0;
 }
-#undef CHECK_XFERTYPE
 
 static void acm_disconnect(struct usb_interface *intf)
 {
diff -Nru a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h
--- /dev/null   Wed Dec 31 16:00:00 1969
+++ b/drivers/usb/class/cdc-acm.h       Sun May 30 10:56:45 2004
@@ -0,0 +1,114 @@
+/*
+ *
+ * Includes for cdc-acm.c
+ *
+ * Mainly take from usbnet's cdc-ether part
+ *
+ */
+
+/*
+ * CMSPAR, some architectures can't have space and mark parity.
+ */
+
+#ifndef CMSPAR
+#define CMSPAR                 0
+#endif
+
+/*
+ * Major and minor numbers.
+ */
+
+#define ACM_TTY_MAJOR          166
+#define ACM_TTY_MINORS         32
+
+/*
+ * Requests.
+ */
+
+#define USB_RT_ACM             (USB_TYPE_CLASS | USB_RECIP_INTERFACE)
+
+#define ACM_REQ_COMMAND                0x00
+#define ACM_REQ_RESPONSE       0x01
+#define ACM_REQ_SET_FEATURE    0x02
+#define ACM_REQ_GET_FEATURE    0x03
+#define ACM_REQ_CLEAR_FEATURE  0x04
+
+#define ACM_REQ_SET_LINE       0x20
+#define ACM_REQ_GET_LINE       0x21
+#define ACM_REQ_SET_CONTROL    0x22
+#define ACM_REQ_SEND_BREAK     0x23
+
+/*
+ * IRQs.
+ */
+
+#define ACM_IRQ_NETWORK                0x00
+#define ACM_IRQ_LINE_STATE     0x20
+
+/*
+ * Output control lines.
+ */
+
+#define ACM_CTRL_DTR           0x01
+#define ACM_CTRL_RTS           0x02
+
+/*
+ * Input control lines and line errors.
+ */
+
+#define ACM_CTRL_DCD           0x01
+#define ACM_CTRL_DSR           0x02
+#define ACM_CTRL_BRK           0x04
+#define ACM_CTRL_RI            0x08
+
+#define ACM_CTRL_FRAMING       0x10
+#define ACM_CTRL_PARITY                0x20
+#define ACM_CTRL_OVERRUN       0x40
+
+/*
+ * Line speed and caracter encoding.
+ */
+
+struct acm_line {
+       __u32 speed;
+       __u8 stopbits;
+       __u8 parity;
+       __u8 databits;
+} __attribute__ ((packed));
+
+/*
+ * Internal driver structures.
+ */
+
+struct acm {
+       struct usb_device *dev;                         /* the corresponding usb 
device */
+       struct usb_interface *control;                  /* control interface */
+       struct usb_interface *data;                     /* data interface */
+       struct tty_struct *tty;                         /* the corresponding tty */
+       struct urb *ctrlurb, *readurb, *writeurb;       /* urbs */
+       struct acm_line line;                           /* line coding (bits, stop, 
parity) */
+       struct work_struct work;                        /* work queue entry for line 
discipline waking up */
+       struct tasklet_struct bh;                       /* rx processing */
+       unsigned int ctrlin;                            /* input control lines (DCD, 
DSR, RI, break, overruns) */
+       unsigned int ctrlout;                           /* output control lines (DTR, 
RTS) */
+       unsigned int writesize;                         /* max packet size for the 
output bulk endpoint */
+       unsigned int used;                              /* someone has this acm's 
device open */
+       unsigned int minor;                             /* acm minor number */
+       unsigned char throttle;                         /* throttled by tty layer */
+       unsigned char clocal;                           /* termios CLOCAL */
+};
+
+/* "Union Functional Descriptor" from CDC spec 5.2.3.X */
+struct union_desc {
+       u8      bLength;
+       u8      bDescriptorType;
+       u8      bDescriptorSubType;
+
+       u8      bMasterInterface0;
+       u8      bSlaveInterface0;
+       /* ... and there could be other slave interfaces */
+} __attribute__ ((packed));
+
+#define CDC_UNION_TYPE         0x06
+#define CDC_DATA_INTERFACE_TYPE        0x0a
+

===================================================================


This BitKeeper patch contains the following changesets:
1.1758
## Wrapped with gzip_uu ##


M'XL( ,VAN4   \59>W/:[EMAIL PROTECTED] (,/J="@[EMAIL PROTECTED]<'93FY1*
M2 /H+"16&MGQ'?[NUSTCB8?D1U*;NL2Q9C0]W;[EMAIL PROTECTED],HXX4^MX-C>07
MY)]AS#K2TG:FE"UJ 4VNDV4MC.:P9(8A+-47X9+6!7U]$E$:UYFMR;#^T6;.
[EMAIL PROTECTED]".I-3U_P^Y6M"[EMAIL PROTECTED]&]A!W,ZIHR<G<DLC&YLWXW?V&SA
MAT&-1780+RFS:TZX7.>D:TU1-/C;4%NZTFBNU:9BM-:.ZJJJ;:C4533CI&G(
M\XC.WUQ'H;TH;C>4AG:BJ<J)UEH;BF&TY3Y1:VJK<4(4HZXTZKI"5*734#IZ
[EMAIL PROTECTED]>=\4]0'^54CQXK\EOR]\'NR0X[)S/M&5E$X]8(Y\"=)3(GC.B0)
MO# @+HV=R%N!7/D#:1AMY43^N-&H?/R=?V19L17Y]<,G7;L1KL3U))[6'=^.
MXSJ .;:=96V1:E57E);65K6UHBLM8]W2FHHS;=HG;:=E:X;S=_#6UXK::#4 
MZ.,*WV:(;)PMQ1N*VEHWFJUV<SUU],9,56>:H<]TVIK^$$1G _'$:&C:NM%H
[EMAIL PROTECTED])]V'B.49X020_X$_^2?:!T>!,HF I1V1VMW5.WI"%!^
[EMAIL PROTECTED]'/E"ZHA%7$2E/./7'%/>!X$DA+!XC,DE!$W\0Y1LDB!^(H9]N(/5'
M#*2JQL])4N^("DKF 7E)CJ-;[EMAIL PROTECTED]>%SCWZ_6(21DU9#K1S+!'S(,'#^!!$AF
M843R,$P7+VPO\.\(LZ\IF47A$O+F-*#L5<[EMAIL PROTECTED]
M:U9)#'Y&[,A9>(PZ+(E C&,'KQA9V#>4Q"O;@>7 )4L[ND9&'KNKI8Q>>+/ 
MI;.4E?P"QEY TZDD28K\@@:N-\ME7MC_AA-P;EX HR!93D%M.;^40;=W84TF
[EMAIL PROTECTED]:;!:7AJ-+<RQ)NI8S-^E?"[EMAIL PROTECTED]
MO?/N>$S68G70&WZTAJ/)P'S7[0T.]Z"[EMAIL PROTECTED]"JCD8?[P<
MC0>XJA96QX.)]6[0G5R9G$ K$+S?)="+TL\'77.;Q"B!B&+.AR-<UXH0WV^M
MED/L78XFYN4Y$A0AC@>COO76''0_X+J>*WUH_E9J/GAOC0:3WR_-#R4ZPU4$
M8XTGW4D*..-XF;[EMAIL PROTECTED]>+#GE()O8EY;O4GIE14.E\R)V-)J#O'&A08
M<U_$$:%1%)9[HA#4ZS\DJ#\VI:)=^=+;]/1&";PA7SDI$_;.[()_OX=U52FN
M0FP-)[EMAIL PROTECTED]>C6#5V.CT'$GB%:4N/[!C1[;#("_0P E=:+>R8\<L
M2AQ&(+U87"G_E27+2G1-[#WELQ,2LW U]5B<S452R&:NS6RQ>D\LRV8L\J8)
MHY9%*A5()M?4/3P\W;()X AL/[EMAIL PROTECTED]"# +%3$A'#2&>0XRZ4W'N2F(WB>0K*1
MZD<$DAW8-X+=JS# @R$AR0CK.]L]E#S#[':4NL2I8)(YR!;[EMAIL PROTECTED]');O
M8>S.2H=','X8+"SNR(JF@(U%/@RJY"BBMBM&MZ!O"L-39 //>'M7;CS\E<GB
M+X2M206M4^56K*:V.]QF<!M&U];[EMAIL PROTECTED] 1B!11TQXL1Y^MZL>.M^/#6
MON9:7^V<WXZO?<HRGM-%RC'B[;Y#XQCWX(8DB+UY %X*>B1X<B_(3N"5!&\%
MHK)*(/ZJQ!Q6R10T=%TE(?A1!)P.RUF&"<MXAB6I!IA.D-]D7+*?*S[V_I/K
M=6G#&="I&<'77"=HUY3S-/&O05ON*L3=!79PPW$S3EB&[EMAIL PROTECTED]@Q>C':&&
MI[X;KFA0W,^+:,8  V2[JNZ2.PL;D44A8S[=>*"8NV1ZQYW/M^]*-SI^Z-A^
MOHU&2R^,2>_\LM<]1_)[$=#DX(K?U=XE@<-@ &'=SZ]M!Z([Z?5[F$T<TJAI
M-;WV!V[/_!TW6WC1PTA/3J3I.0WF;'$J)AM6$[A:[EMAIL PROTECTED] !UF
M :FD&\8^M#4[;P%WK5;CB1&;)8R3Q >[EMAIL PROTECTED]/+7EC5"_9UV-
MAI<CWG+P?-_<6>QW)]U-WR&H@,@&'H]?IYRG/R'\X)50=J"S#M[PWR&TU>Q/
M_+;P]1GW0575=+6MM]<&3 W>ON]]8C :'>TY_3LL'P/(__]G!GZQ?7:K[_Q(
MJ]_4"#0.GNCPR4%^;3@ '^BW%-+6Y'X#GOS1@ O($!_M39'8!,V1&"[EMAIL PROTECTED];
MGI'1U?DY^#>/X*-I,IOQM^#(L^/7ML]BRACHX/@U_09J!4),*4#F0ZIYD P6
M3Y\HHYM7#U)BK7R(+$N7UL84Y(BN,'4_BQ#+Y+,(>3([EMAIL PROTECTED]""
MU_"[EMAIL PROTECTED] =[M$A#1Q.VB:H+_8F4+,8(&:M"%2'QJK%E#)ZGO!FI_"(L<[EMAIL PROTECTED]
M3X+*53GXW:.1N^6))*)  +T:C0] [EMAIL PROTECTED]/AJ-/733Q/3*[7>[EMAIL PROTECTED]
MP==$$2Q11FK\/]6OY)<S?N7I0[\_WKKR<%(A/K[V5BL,CKD=3>TY%3*E>0C!
M$H 3<#6>PK$AJ.$J 9*E^-;#3YZY'.UKRM"QX_TTV"'[EMAIL PROTECTED],
MDH"Z[<,IDQ3710BYF4'($ZR3^^$*#4V&&[)YBKF(&M_=\]][P5(IB:=#<1ZQ
MBW<7? @)W$Y\UI%S:,,[EMAIL PROTECTED]@FF&8;/Q7LZ1X.;44L=G1,CY4_EZ*EZC
M$G_=?7V?^TM10^"4ECN=5UZ*H(5I]6 4EJAH[MV(]NQ+L.=)H\O^X!/X=%/7
M";JTWB &>.M^1(.B>"C/H,? B/!FE316JF0;U_'K0OU%>;MQ_QW,]JHV\N*Z
M* )<K\DONV(>UE$0;I5UH1(X>1.2+*@;1BVB"SD[Z<N"K.\MJ5O9$P-RT+6A
M7GG8GHDN#@&"S86'EV&80+>X=W7P8OS\8M_8GF]/?5JPU=NK\6>.M$UT#?L7
M;,WMB <3-J B&D6/N-6S\)/L8CY^[221M9WDT5MJTUS3/2QPF#,>Z%8V*:9@
MB6?R/GN"]P,5A*616%3HYS")LK89F^D2;=2$2C%S20R\L*QP2:7.7RA<4M&G
M.;1[0OV8BA,4TC5FH/OOL<<H60[2(A:3?Q#ML*0(P&E$E00(+Y]AC:PJ0GJI
MI;E1%$_<_Q2LTLV\H'[7;C7;_07AIY?,,D^F^>DS1ZX(L) ;,LUT71?NTC%Y
M*0K<T [EMAIL PROTECTED]/4^*<-&"LA+?VJL5R.%A^E3KP W\S%C>\<#\%%E(
MR\+_\J9E8X%->[*E6,;K@(1B#[9B&P_ LXY(8 ;[EMAIL PROTECTED]@$<3FL=AL]&"
MAP2])[EMAIL PROTECTED]"6>SXGX<<H^CMP:V,/*AXI*6^4TLR- )I&"J M)+>Y9"28>3Z7
M9271M"[EMAIL PROTECTED])\W-ID?!I$#=8JMO!7=5 3AW$5['U8QQK!65C<[EMAIL PROTECTED]/+B_[B
MLRT&/ .!PK"':[;;B+&E*#L8\>*^ 9E_>=D'B63[*,N],D6),+&R;X!FO:& 
MC#,NG$\18$O1!4#C$8#9!Z$]A''@EB'DU$]"W &6BM@ Y=-]I"VB(E2MB;T#
M%\CO2J)@;MRH\A(YB+7JGHMEW" =X&<SN'IZV$:DG3F>UL+WV6;>;E?))@CY
AUGY+5\$%\_^*A^!SKN-D>:8WV]2E)XK\/^:P A !(   
 


-- 
Vojtech Pavlik
SuSE Labs, SuSE CR


-------------------------------------------------------
This SF.Net email is sponsored by: Oracle 10g
Get certified on the hottest thing ever to hit the market... Oracle 10g. 
Take an Oracle 10g class now, and we'll give you the exam FREE.
http://ads.osdn.com/?ad_id=3149&alloc_id=8166&op=click
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to