Date: Wed, 28 Mar 2007 04:52:53 +0200 From: grem <freebsdusb@bindone.de> To: freebsd-usb@freebsd.org Subject: Support for new device, important fix and enhancement to umass.c Message-ID: <4609D885.8070505@bindone.de>
next in thread | raw e-mail | index | archive | help
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 &&
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4609D885.8070505>