I've been working with coreboot and SeaBIOS lately to try to get a platform working, including having boot capability using an SD-to-USB adapter. I got stuck on this last part: the USB/SD adapter would start enumeration, but would fail out during TEST_UNIT_READY because the device came back with a STALL (this via a LeCroy/CACT USB analyzer). I compared the transactions to those done during USB enumeration/configuration in Linux, and I noticed that the Direction bit in bmCBWFlags is *cleared* for the TEST_UNIT_READY command in Linux, but *set* in coreboot.
In both cases, dCBWDataTransferLength is zero.
The USB MSC spec that I'm using states: If [dCBWDataTransferLength] is zero, the device and the host shall transfer no data between the CBW and the associated CSW, and the device shall ignore the value of the Direction bit in bmCBWFlags.
Obviously, this device is not ignoring the Direction flag. So... what should it be? I modified Paolo's patch (usb-msc.c, usb_cmd_data() function) from 27 Feb 2012 to look like this: cbw.dCBWDataTransferLength = bytes; if ((cbw.CBWCB[0] == CDB_CMD_WRITE_10) || (cbw.CBWCB[0] == CDB_CMD_TEST_UNIT_READY)) { cbw.bmCBWFlags = USB_DIR_OUT; } else { cbw.bmCBWFlags = USB_DIR_IN; } cbw.bCBWLUN = 0; // XXX
This change allows the device to work, but: 1. Is this the right way to do this? 2. Will this break anything else? 3. Are there other commands that should be set for OUT instead of IN?
Thanks! -- Steve G.