Support for new device, important fix and enhancement to umass.c

grem freebsdusb at bindone.de
Wed Mar 28 03:05:27 UTC 2007


Hello,

I had trouble using a Raidsonic ICY BOX IB-220U-Wh external USB HDD case (fdisk,
disklabel, newfs, mount etc. fail with all kinds of weird error messages). It uses a
"SuperTop IDEDEVICE" controller (VendorId 0x14cd, ProductId 0x6600), which - after
googling around - seems to be used in different USB-to-IDE adaptors from different
vendors. As I learned from Linux/OpenBSD sources, this device needs the IGNORE_RESIDUE
quirk to be set. After adding an entry in usbdevs and an entry to umass_devdescrs in
umass.c things still didn't work. After a lot of trial and error I figured that the
IGNORE_RESIDUE quirk is not used at all in umass.c. The critical lines are 1668-1672 in
umass.c:

int Residue;
Residue = UGETDW(sc->csw.dCSWDataResidue);
if (Residue == 0 &&
	sc->transfer_datalen - sc->transfer_actlen != 0)
		Residue = sc->transfer_datalen - sc->transfer_actlen;

since these trust the residue returned by the device, even so it's wrong [and != 0] (as
indicated by IGNORE_RESIDUE).

I added the following lines in front of the code above:
if (sc->quirks & IGNORE_RESIDUE)
	USETDW(sc->csw.dCSWDataResidue, 0);
(which might be not the most elegant way to do it)
and hooray the device finally works without any problems.

I also added a convinience #define UMASS_PROTO_PROBE 0xffff, which can be used in entries
to umass_devdescrs to make umass_match_proto(...) only set the quirks and still get the
protocol details from the device (eases adding new "unusual" devices).

See below for patches to usbdevs and umass.c (against RELENG_6_2) for the new device, fix
for IGNORE_RESIDUE and the (maybe poorly named) UMASS_PROTO_PROBE extension. I would
really like to see at least the former two submitted to the source tree, since these
devices seem to be relatively common.

Any feedback is welcome, since I'm not an expert in how USB works/is implemented in FreeBSD.

/michael

--- usbdevs.orig        Thu Mar 15 16:23:52 2007
+++ usbdevs     Wed Mar 28 03:16:24 2007
@@ -514,6 +514,7 @@
 vendor RALINK          0x148f  Ralink Technology
 vendor IMAGINATION     0x149a  Imagination Technologies
 vendor CONCEPTRONIC    0x14b2  Conceptronic
+vendor SUPERTOP                0x14cd  Super Top
 vendor SILICONPORTALS  0x1527  Silicon Portals
 vendor PNY             0x154b  PNY
 vendor SOHOWARE                0x15e8  SOHOware
@@ -1596,6 +1597,9 @@
 product DIAMOND2 SUPRA2890     0x0b4a  SupraMax 2890 56K Modem
 product DIAMOND2 RIO600USB     0x5001  Rio 600 USB
 product DIAMOND2 RIO800USB     0x5002  Rio 800 USB
+
+/* Super Top products */
+product SUPERTOP IDEDEVICE     0x6600 Icybox disk enclosure

 /* System TALKS, Inc. */
 product SYSTEMTALKS SGCX2UL    0x1920  SGC-X2UL

------------------------------------------------------------------

--- umass.c.orig        Thu Mar 15 17:17:30 2007
+++ umass.c     Wed Mar 28 04:08:27 2007
@@ -282,6 +282,7 @@
 #      define UMASS_PROTO_UFI          0x0400
 #      define UMASS_PROTO_RBC          0x0800
 #      define UMASS_PROTO_COMMAND      0xff00  /* command protocol mask */
+#      define UMASS_PROTO_PROBE        0xffff  /* probe the protocol, even if found in
umass_devdescr) */

        /* Device specific quirks */
        u_int16_t       quirks;
@@ -494,6 +495,10 @@
          UMASS_PROTO_RBC | UMASS_PROTO_CBI,
          NO_QUIRKS
        },
+       { USB_VENDOR_SUPERTOP, USB_PRODUCT_SUPERTOP_IDEDEVICE, RID_WILDCARD,
+         UMASS_PROTO_PROBE,
+         IGNORE_RESIDUE
+       },
        { USB_VENDOR_TREK, USB_PRODUCT_TREK_THUMBDRIVE_8MB, RID_WILDCARD,
           UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
          IGNORE_RESIDUE
@@ -845,7 +850,10 @@
                        if (umass_devdescrs[i].rid == RID_WILDCARD) {
                                sc->proto = umass_devdescrs[i].proto;
                                sc->quirks = umass_devdescrs[i].quirks;
-                               return (UMATCH_VENDOR_PRODUCT);
+                               if (sc->proto == UMASS_PROTO_PROBE)
+                                       sc->proto = 0;
+                               else
+                                       return (UMATCH_VENDOR_PRODUCT);
                        } else if (umass_devdescrs[i].rid ==
                            UGETW(dd->bcdDevice)) {
                                sc->proto = umass_devdescrs[i].proto;
@@ -1665,6 +1673,8 @@
                                USETDW(sc->csw.dCSWSignature, CSWSIGNATURE);
                }

+               if (sc->quirks & IGNORE_RESIDUE)
+                 USETDW(sc->csw.dCSWDataResidue, 0);
                int Residue;
                Residue = UGETDW(sc->csw.dCSWDataResidue);
                if (Residue == 0 &&



More information about the freebsd-usb mailing list