PORTS Forum

Ports and Interfaces => USB => Topic started by: bazz on March 22, 2015, 10:48:22 am

Title: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: bazz on March 22, 2015, 10:48:22 am
ARG! I'm implementing a device driver for the mass storage class on the Philips/NXP PDIUSBD12.. I'm hacking an old device.
It's been very challenging reverse engineering the device, the PDIUSBD12 is very picky.

I got to a point now where I can print to an LCD screen debug info and .. the USB device enumerates and begins communicating the standard basic commands READ INQUIRY, READ CAPACITY.. then it does a lot of READ (10)'s... then it starts heartbeating the TEST UNIT READY...

I'm on OSX Mavericks, and at this point, since I am pointing my LBA's directly to empty RAM.. OSX says "Do you want to initialize this drive" type message, and I say yes, and when I try to erase the drive as FAT32.. that's when I start to see the WRITE (10).. it tries to erase 0x100 512 byte sectors.. Since the PDIUSBD12 and I believe any other bulk EP max in this scenario is 64 bytes.. that's my max.. so I build up my sector thru many of these interrupts.. and after every sector I of course write it to memory, then repeat for all logical blocks.. anyways.. for some reason this will hang after the 7th transfer of the last logical block.. or more simply it doesn' transfer the last 64 byte block to me...

Now you might be wondering like.. maybe my logic was messed up and I was missing the first transfer and I was off... well.. perhaps not -- even if I consider this missing 64th block as if it was transferred, and send the CSW.. I get nothing... Even weirder is that if I stuff more data into the bulk IN buffer (like 1-2 more times) to the OSX host at the point of the missing last 64 bytes.. I will get a packet that is a bunch of 0's, definitely not a CBW.. and likely more erase data.. but if I follow the rabbit's hole any deeper I start getting REQUEST SENSE which my handler doesn't support the variable descriptor it seems to want...

So.. I'm at a total loss here... Any ideas anyone??

How could the host possibly want IN data at that point? What am I doing wrong  :(

I dont have access to a USB buss sniffer.. and I'm not very fortunate enough to have money lying around.. I would buy the popular one for $300-ish dollars Sayonara tax return...
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: Jan Axelson on March 22, 2015, 11:13:40 am
The best starting point for mass storage may be to capture traffic from a working device and try to emulate it as closely as possible. This doesn't free you from the obligation to comply fully with the specs, but it's a place to start.
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: bazz on March 22, 2015, 10:29:15 pm
Does this look legit.. So the price was so freakin' attractive, and I read the reviews... albeit not very many (20+), 1 year long membership-ish, I went for it.. http://www.ebay.com/itm/New-Beagle-USB-12-Protocol-Analyzer-TOTALPHASE-/221721890486?pt=LH_DefaultDomain_2&hash=item339fa78eb6

I think it will be the real thing **fingers crossed**
I feel like the timing was just right... This auction was just put up and I found it with only hours to go and no bids.. I then bought it just at the 30 second mark and one person just had bidded on it.. Whew!

So I have it, theoretically speaking.. You might wonder why I bought this over using software like Wireshark.. Namely this feels easier and I can get at the core. Setting up Wireshark with OS X .. mystery.. And I need a break from USB for some days now.. Worked too hard one night you know how that goes.

I did manage to host a wireshark session on Ubuntu on my Macbook Pro, but it enumerates differently, so actually my device, because of not supporting the MODE SENSE command, never shows up as a drive or undergoes any READ commands, for instance... After I stall MODE SENSE, it's just a rinse repeat to that stage forever..

It's tough to completely mimick a USB flash drive since my device enumerates will all of the logical blocks as 0's, I'm not sure if I can get a flash drive to do that even by erasing the partition to free space.. I didn't notice the wireshark session actually write all 0 to the drive.. but anyways..I think I might buckle down and write my own FAT12/16/32 partition thingy.. but I'm a little lost, I'll try including a MBR in there..

Should I write a "FAT partition image generator" -- would anyone else find that useful??
  . specify SECTOR SIZE
  . specify 'drive' size
  . include MBR?
  . Create FAT image.. ??

Is there something like this already available?
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: bazz on March 23, 2015, 04:24:12 am
Jan I'm just at that place... My code base is turning into a mess from all the experimentation.. I'm losing the organization I once had in trying to comply with the specs in the context of how the USB controller chip operates.. It's been really tough for me to put all the ducks in a row, so to speak.

If I know what's good for me, I'll go back a couple commits in the code base when things were more logical as far as sticking to SPEC.. and restart from there..

Once I get a scrollable debug screen and/or USB analyzer I should be able to make sense of my dilemma, and hopefully be able to compare to a working model.
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: Jan Axelson on March 23, 2015, 10:17:19 am
The Total Phase analyzer should help. It can show low-level things a software analyzer can't.
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: bazz on March 23, 2015, 06:55:24 pm
Below, I have laid out a plan to communicate my debug data over separate bulk endpoints, but I must call upon your experience.
Can I do this while my device's USB interface is set to Mass Storage Device? With your experience, can you anticipate whether I will run into problems communicating to both the host's MSD driver and a host PC program at the same time [over different endpoints]?

My USB Controller (pdiusbd12) has another 2 endpoints I can use [and also the option of control EP vendor commands]. I was thinking of adding 2 more bulk endpoint descriptors, which I am planning to utilize during the mass storage operations.. I would forward all debug log messages to the endpoints via a PC program which regularly queries the device for debug information with 2 simple commands.

But, can a USB device communicate with a pc program and the host's MSD driver at the same time? Or would I be building something that isn't designed to work?

such a mechanism could go as follows:
There are 2 command --

Code: [Select]
#define CMD_QUERY_DATA_AMT 1
#define CMD_FETCH_DATA 2

 -- each command is sent over the special BULK OUT EP, followed by 1 IN transaction.
1) Host queries device for debug info by sending a CMD_QUERY_DATA_AMT over the BULK OUT EP. Can wrap this command inside a simple CBW-like structure for signature verification.
2) Device responds how much data it has available to send over the BULK IN EP. can wrap this USHORT value inside a simple CSW-like structure for signature verification.
3) Host, if device has data, sends a CMD_FETCH_DATA over BULK OUT EP to ask for that amount of data from device/
4) Device sends the amount of raw data requested over BULK IN EP, and updates its circular buffer marker.
5) Host prints debug info to console window

6) no matter what, at the end of the host loop, should delay some amount of time (10-100 ms) to avoid overwhelming the device.
7) goto 1.

---- what follows is
----- more personal data I don't expect ppl to reply on, but response is welcome --------
I need to find a good C implementation of circular buffer, any ideas? Perhaps it's time to make life easier in the world of CPP.

println() must be modified to utilize a circular buffer

in the println() -- if the new string size would cause the circular buffer to overflow upon itself:
1) [check if IRQ / INT_EINT0 is active .. ] disable INT_EINT0
2) enter a routine which polls the USB interrupt register for the special Bulk EP's we are concerned with
3) flush the buffer, and return
4) re-enable INT_EINT0
5) resume regular println() activity
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: Jan Axelson on March 23, 2015, 09:19:24 pm
If a device interface identifies itself as mass storage in the descriptors, the host computer will assign the mass-storage driver to the interface. On the PC, the interface appears as a drive, and host applications can use file functions to read and write to the drive.

If you can put your debug data into a file, a PC application will be able to read it using file functions.

To support a different mechanism for reading and writing data, the device will need another interface (HID, WinUSB, virtual serial port, etc), and the device firmware for that interface must have access to the debug data you want to send.

Or you could write a low-level mass-storage filter driver that supports new commands, but this option is more difficult and the filter driver would likely need to be digitally signed.

What is the debug information you want to request?

Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: bazz on March 25, 2015, 05:48:38 am
Well, I had low-level information regarding the implementation of my Mass storage driver printed out.. This could be anything from notification of which of the 13 cases I am currently experiencing.. to what SCSI command is being processed currently..

I was hoping that I could seamlessly have the USB process both kinds of data.. but as you said, it cannot be done without 2 interfaces.. There's no way I am going to select between 2 different interfaces constantly... So I just going to implement a more sophisticated debug log on the LCD screen, with a scroll feature.
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: Barry Twycross on March 26, 2015, 02:23:26 am
I was going to say that you must have misplaced a packet somewhere, as my device does this with no hassle at all.

However, my device formats the media for the host. How big is your media? There are some sizes that are a little tricky for the host and I think I've seen initialization go wrong if the media is too small.

You really need an bus analyser to work out what's going on.

You might just be able to work out something is you used the logging USB family, or usbtracer. I think usbtracer in particular will tell you what transfers the host is lining up for the host controller. What controller is in you machine? What machine is it anyway?
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: bazz on March 26, 2015, 02:24:55 am
I am on a Macbookpro 2009, OSX Mavericks 10.9.5
My drive is 8MB in size.

Do you have any tips on doing a format device-side (FAT) .. I should go FAT12 given my small capacity, right? I'm hoping you won't tell me I'll have to do it from scratch, I'm hoping there's a library. but I'll do what I'll have to.

Can I just be honest? The USB has beaten me.
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: Barry Twycross on March 26, 2015, 12:43:57 pm
I am on a Macbookpro 2009, OSX Mavericks 10.9.5
I'm pretty sure that'll be using the built in Intel UHCI.

Quote
My drive is 8MB in size.
That is a bit small, I don't think the partitioning software copes with it correctly. Mine's 4MB.

You could test this theory by lying and saying your media is larger. You can fake any requests to sectors past the end of your real media, but you should take notice of requests to the last couple of sectors in your virtual media, the system uses them to find out where the end of the disk really is.

Quote
Do you have any tips on doing a format device-side (FAT) .. I should go FAT12 given my small capacity, right? I'm hoping you won't tell me I'll have to do it from scratch, I'm hoping there's a library. but I'll do what I'll have to.
FAT12 should work. I wrote both in just in case I needed it.

I did it from scratch. I think I got the format from a disk image, OS X can successfully make a disk image that small. That and the Wikipedia article on FAT.

When the disc is that small you really don't want a partition table, just a naked volume. That works with OS X and most Windows before 7. Win 7 wants partitions, so I put in an extra sector in front with that. (Which may be called a VBR.) Then you need a sector for the MBR, which is a copy of the VBR without the partition table, then the FAT and the directory.

Quote
Can I just be honest? The USB has beaten me.
In this case, its not really USB, its the partitioning software, which is Core Media or something like that.

You might also get some traction if you posted to one of the Apple mailing lists. I'm not sure USB is the right place for it though.
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: bazz on March 28, 2015, 07:22:11 am
Can you expound a little more on checking access to the last sectors of my "fake" virtual drive?
And do you just report the fake ones as being all zero????

If I manually preformat my memory as FAT, I can avert this problem altogether no? I mean avert having to fake the size of my disk..
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: Barry Twycross on March 28, 2015, 10:36:49 pm
Can you expound a little more on checking access to the last sectors of my "fake" virtual drive?
Just beware that the system will try accessing them, so requests shouldn't fail, at least reads.

Quote
And do you just report the fake ones as being all zero????
That would probably work.

Quote
If I manually preformat my memory as FAT, I can avert this problem altogether no?
Yes.

Quote
I mean avert having to fake the size of my disk..
I was suggesting faking the size of the disk would test whether the formatter is barfing on the small disk, or if you have a problem in your logic.
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: bazz on March 29, 2015, 04:12:29 am
Ah, right. Thanks for straightening that out *feels stupid*
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: bazz on April 01, 2015, 03:46:11 am
Made some progress today after a 5-day break period :)

this is a 2-part post, I'll post the latest news first!!
--------
I am using the Total Phase USB 12 USB Analyzer right now in this moment. It's worth the organization of the data, although I don't think a hardware level analyzer was necessary to spot this issue, I'm glad I have it/one. Trying to sift thru Apple's usbtracer command-line software looked like hell, and there's no manual I could find on it to make it usable. I hear it has limited output capabilities anyways.
----------- Part 1
Since I'm not yet well-versed in the Total Phase software, I did my analysis manually .. and since Total Phase doesn't provide Mass Storage "convenience" unless you fork lots of money for the higher-end models, I had to manually inspect the raw packet's CBW and CSW's .. It's not bad, given I'm already feeling the convenience from not having anything at all.. I'm kind of surprised they don't just provide the English translations.. but I guess they think that will motivate people to buy the higher end models... Dream on I say, at least for us hobbyists.. I'm ranting, so let me stay focused.

The problem lies in my driver, because the USB bus does indeed see the correct amount of packets. I'll take a look at that tomorrow when I'm feeling refreshed.

----------- Part 2

I [on a personal level, finally] learned how to incorporate on an initial level the FatFS library for embedded devices into my project. Fortunately, I was able to use the facilities of FatFS to format the drive. Yay, no need to create one absolutely manually!

I am able to successfully write a text file on the drive [with limited verification that this is operating 100% successfully, I am convinced].

Unfortunately, although the drive enumerates as before, and this time shows some updated information in Disk Utility (MBR partition scheme) for instance, I still run into that prior issue that spawned this whole thread -- the last transfer. See part 1 above in this post for updated details.
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: Barry Twycross on April 01, 2015, 03:55:00 pm
Trying to sift thru Apple's usbtracer command-line software looked like hell, and there's no manual I could find on it to make it usable.
Tracer really needs to be used in conjunction with the source code. Apple used to provide the source, but I'm not sure for the very latest OS. I have a head start there as I wrote some of the source.
Quote
since Total Phase doesn't provide Mass Storage "convenience" unless you fork lots of money for the higher-end models, I had to manually inspect the raw packet's CBW and CSW's
That's the way I wrote and debugged my device, with just the packet traces and no interpretation. Any USB analyzer is 100% better than no USB analyzer, though I did miss the packet interpretation I'd got using other analyzers. I eventually got approval to buy something better, but not before I'd done it totally without the help. As Total Phase doesn't provide a software upgrade to include packet interpretation, I went and bought a CATC/LeCroy/Teledyne Mercury T2 instead. I prefer the CATC software. That does packet interpretation which has made my life easier ever since.
Quote
The problem lies in my driver, because the USB bus does indeed see the correct amount of packets.
A. That's why I always recommend a hardware analyzer, doing USB without it is much like banging your head against a wall, only less rewarding.

B. So the packet appears on the bus, but you never see it in your firmware? That sounds like a classic case of data toggle mismatch. The correct behavior in response to a data toggle mismatch is to receive the packet, ACK it and then discard it. Any time someone says anything like "I see it on the bus but not in my software" I say data toggle.


Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: bazz on April 02, 2015, 01:55:21 am
I've made lots of progress.
On OSX, the drive can now "come online," I can view and edit a sample text file I created from the device-side. I can unmount the drive.

You might be wondering, what did I do to fix it?? Although your idea is sound on data toggling, that wasn't it. The problem for me is with the unique aspects of my USB controller ASIC what-have-you,the PDIUSBD12. As you know, when studying a datasheet, it takes time to fully comprehend the complete connection between everything -- well sometimes the datasheet says things that misleads your mind into thinking "OK I don't need to address XYZ," when you really do... That's what happened to me, and right now my solution is sub-optimal. Let me expound :

PDIUSBD12

Endpoint 2
This endpoint is different from the other endpoints. The other ones which have 16-byte single buffers. EP2 has 64-byte buffer, and is double buffered.. It's advertised as transparent in the datasheet. So I just operated on it the same way I would with my experience from dealing with EP 0 and enumerating the device.. WRONG -- the more I looked thru the datasheet I started realizing the potential importance of this double buffering behaviour.. Especially when I noticed a max-read of 130 bytes (2 extra to account for certain pecularities of the device as listed in datasheet). I felt like the packets were in the controller I just didn't know how to access them.. Then I noticed a command that would tell you if one of the 2 buffers was full.. Transparent my ass.. Just kidding :) ... The firmware example uses DMA with EP2, which I cannot do, and I can only wonder until I look at it whether it will shine light on how to properly handle -- but for now what I did in a hunch instinct was I moved all of my logic over to the smaller endpoint 1.. Changing some code to adapt for the smaller EP size, and wah-lah!! I proved my hunch! It started working!! And that's how I fixed so far :) I hope to in the future attempt a return to EP2's bigger buffer. I can probably figure out how to use it, given instincts and possible firmware documentation [as long as DMA doesn't auto-handle what I will need to handle manually].


And I learned a couple things at this point:

Point 1
I need a more dynamic response to TEST UNIT READY instead of just passing good CSW's if I want my "drive" to come back online after a dismount.. or during the OSX format process, which still doesn't complete due to this and possibly other future road blocks.

Point 2
If I remount the drive after unmount, the drive will not display the new files I may have added, and the one pre-existing text file is listed as having 0 bytes although the data and the other files raw data can be found in the partition if dumped by raw memory..But I didn't inspect the FAT itself to see if it became messed up. I suspect this is connected to my observation that when OSX mounts my drive, it writes some data to the partition.. off the top of my head I loosely recall it writing "MAC OSX" somewhere after the 1st or 2nd sector and a serial number too.

Summary on these points
I'm not too concerned with these observations or fixing them directly since I already know I'm not properly implementing the whole required-SCSI command set.. So here's what I've done to admonish that:

Learning from a Real Flash Drive
I immediately ran into a problem -- I am implementing a Full Speed product, but most flash drives are high-speed. Purchasing a full-speed product seemed pretty lame as they are rare and shipping is expensive, plus the crappy USB advertising makes it hard to guarantee the proper operation I'm after.. Luckily, I have some USB sticks here, and I prayed one of them may support Full Speed and that I could modify the bus speed from the OS-side..

Reducing 2.0 Bus Speed to Full Speed
I dabbled with virtualization but to no avail (VirtualBox and Windows XP)... although it is said you might be able to disable the 2.0 UHCI [may have the wrong term there] and get it working.. Not for me.... even with vbox extensions installed and USB 2.0 virtual UHCI enabled in V-OS settings... Luckily, I found a solution..

I booted into my Ubuntu 12.04 partition thru Refind [love it] and found some instructions on how to [maybe] be able to change the bus and port speed -- I was warned that my tech has to be old enough to do this. Anyway the instructions are here, and it worked : ) -- http://lists.en.qi-hardware.com/pipermail/discussion/2011-August/008508.html -- I'd love to make a mental note that using dmesg to find the usb bus and port was more intuitive than the output of lsusb, which has a device number which I originally mistakenly used for the port number.. With those instructions I had it working..

I got the TotalPhase USB driver working thru the UDEV instructions found here: http://www.totalphase.com/support/articles/200472426/#s4.3.1 -- the USB drivers themselves are easily found on totalphase's website..

Analyzing USB Stick at Full Speed
I proceeded to take a number of "snapshots" of different events.. Right now, I have the following:

Code: [Select]
1_enumerate_and_preload_drive.tdc                      1.1M
2_launch_gparted.tdc                                   765K
3_select_and_unmount_drive.tdc                         11M
4_erase_partition_to_unallocated.tdc                   3.0M
5_create_msdos_partition_table.tdc                     3.6M
6_create_fat16_partition.tdc                           6.8M
7_exit_gparted.tdc                                     908K
8_mount_open_drive_create_file_write_file_unmount.tdc  281K
9_connect_open_drive_open_file_close_file.tdc          1.4M

and to print that output, I just learned / found my own way to do this:
Code: [Select]
ls -lh | awk '{print $9,"   ",$5}' | column -t
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: bazz on April 02, 2015, 06:23:51 am
Another thing I'm curious of is that when a stall condition arises.. The host sends a CLEAR FEATURE request to my device.. I'm not sure I'm responding correctly to it, or maybe mis-parsing it, because communication then goes silent for a good amount of seconds before it resumes again.. I'm not sure if this is normal behavior. I'm looking for clarification on this. GET STATUS is also a potential culprit.

[too lazy to post source code, hoping for high-level advice]
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: bazz on April 02, 2015, 10:54:19 am
Mode Sense (6) Response -- Question

Note: It is my expectation that the behavior I'm about to describe is a case of the "Allocation Length" fields in SCSI Primary Commands, which when present allow the CSW residue to be set to 0 even when less data is sent than specified in the CBW.

This is from my live capture of a USB flash drive operating in Full Speed, with 64-byte bulk endpoints:

At "USB enumeration" -- the Linux host eventually sends its first MODE SENSE (6) command, asking for all supported pages.. In the CBW, a DataTransferLength of 0xC0 / 192 is specified.. This length is also specified inside the CBWCB.
The device goes on to reply with an IN packet of only 0x23 bytes, containing 2 Pages, Cache and Informational Exceptions Control. No block descriptors were sent. Immediately following this transmission, a CSW is sent with good status, and no residue..

The 13 Cases would have dictated other behavior -- such as send padded data, or stall the in-point, but that doesn't happen in this case.. Is this proper?

The USB operations happily proceed.. I do not notice either a STALL condition, or a CLEAR FEATURE request.. So I'm wondering, why wasn't the residue set and the stall occurring, like specified as should happen in the 13 cases.. ??? Whereas the device sends less info than specified in the CBW.. Is this a special case?? How come I did not read about such behavior, even in Jan's book or firmware implementation, which we can both agree was incomplete and the mode sense implementation was incomplete specifically.. [no offense]

But since this behavior appears non-standard and I haven't seen it anywhere else yet, I'm wondering if it will pop up in other commands I should know about.. Please someone shine light on this. Thank you [can't have the answers soon enough! hehe.. Fortunately I'll be spending the next few days on break, to give you some time :P ]  But please answer quickly :D


EDIT: Am I missing some documentation.. I have the USB 2.0 spec, the Mass storage spec, and the SCSI command sets, but I feel a little in the dark when it comes to exactly how each SCSI command is treated when in the context of being within CBW and CSW responses.. IS there a doc on that?
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: Barry Twycross on April 02, 2015, 05:26:56 pm
I've made lots of progress.

I'm glad things are working out for you.

Quote
Point 1
I need a more dynamic response to TEST UNIT READY instead of just passing good CSW's if I want my "drive" to come back online after a dismount.. or during the OSX format process, which still doesn't complete due to this and possibly other future road blocks.

Point 2
If I remount the drive after unmount, the drive will not display the new files I may have added,

Does your device declare itself as a removable device? That is it sets the RMB bit in the inquiry data. That's the easiest way of doing this. You need to keep state of whether your "media" is loaded or not. It can start out loaded, but you should get an eject command (Start/Stop unit with LoEj=1) which causes you to become not loaded. Then you return a sense of Not ready, no media to just about anything the host tries to do (including test unit ready). When you want to remount the media, you start returning good status to the test unit ready.

If the host thinks the media was ejected, it invalidates all caches and rereads the media and can find new files. This method works in our device and about 150 million iPods out there

Quote
Summary on these points
I'm not too concerned with these observations or fixing them directly since I already know I'm not properly implementing the whole required-SCSI command set.. So here's what I've done to admonish that:
I'd suggest you implement at least the RBC command set. ftp://ftp.t10.org/t10/document.97/97-260r2.pdf

And maybe the bootability set: http://www.usb.org/developers/docs/devclass_docs/usb_msc_boot_1.0.pdf

Quote
I am implementing a Full Speed product, but most flash drives are high-speed.
The easiest way to make something full speed, is to attach it via a full speed hub. You can still buy hubs which are advertised as full speed, we did for this very sort of reason.

It used to be that you could remove the Mac's EHCI driver and that would disable high speed. That hasn't worked since about the 2010 Macs though. Warning: Don't do this on the wrong machine, it will disable USB entirely.

If your Mac has slots, you may be able to find a UHCI or OHCI plug in card for it. That will be full speed only.
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: Barry Twycross on April 02, 2015, 05:28:56 pm
Another thing I'm curious of is that when a stall condition arises.. The host sends a CLEAR FEATURE request to my device.. I'm not sure I'm responding correctly to it, or maybe mis-parsing it, because communication then goes silent for a good amount of seconds before it resumes again.. I'm not sure if this is normal behavior. I'm looking for clarification on this. GET STATUS is also a potential culprit.
Are there NAKs on the bus during this quiet period? You may be ignoring them. If there are, the host is expecting you to do something that you aren't. A SETUP command will typically timeout after 5 sec which sounds like what you're describing.
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: Barry Twycross on April 02, 2015, 05:38:27 pm
Mode Sense (6) Response -- Question

Note: It is my expectation that the behavior I'm about to describe is a case of the "Allocation Length" fields in SCSI Primary Commands, which when present allow the CSW residue to be set to 0 even when less data is sent than specified in the CBW.
I'm not sure of what your question is exactly, and I can't be bothered to look up the 13 cases to check.

The first point is any random USB stick is likely to be very badly implemented. As one commentator noted their adherence to specs is "coincidental at best". They're likely to do just enough to enumerate successfully on Windows, so the behavior of Windows is the defacto standard for this.

At least for mode sense and inquiry if the SCSI command specifies an allocation length you can respond with less. No one cares about that. I don't know if its actually standard, or just customary.
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: Barry Twycross on April 02, 2015, 05:48:30 pm
It used to be that you could remove the Mac's EHCI driver and that would disable high speed. That hasn't worked since about the 2010 Macs though. Warning: Don't do this on the wrong machine, it will disable USB entirely.
I see you say you have a 2009 MacBook, this might work for you. But do it at your own risk, and have a backup plan in place in case it doesn't work. If you have another machine handy you can set up screen sharing or remote terminal access. This allows you to control a machine with dead USB enough to put it back together. The other back up plan is to have a different boot partition installed, you can boot to the other partition and recover things (maybe).

From the terminal:

Code: [Select]
sudo mv /System/Library/Extensions/IOUSBFamily.kext/Contents/PlugIns/AppleUSBEHCI.kext /
sudo touch /System/Library/Extensions

Then reboot. That moves your EHCI driver out from where it lives and tells IOKIt to rebuild its extension cache (now without the EHCI driver). Without the EHCI driver high speed IUSB no longer works, but with the right sort of machine (pre 2010) the full speed controllers will still work.

Recovery is to move it back to the proper place and touch the extensions folder.

I used to do this all the time when I needed a full speed host. There are some machine it doesn't work on, always have a backup plan and don't blame me if it hoses your machine.
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: bazz on April 02, 2015, 06:57:01 pm
hehe, I've read all your responses.. Thanks for the tip, it sounds pretty risky, and even tho I have a triple boot machine and separate external hard drive with OSX installed, I think I'll pass.

EDIT: Regarding RBC, you must not be talking about stating support for RBC in the inquiry response, right? I actually personally went out of my way NOT to -- well in Jan Axelson's Mass Storage book, she went on to explain that PC's don't have RBC drivers natively, and that it'd be easier to create one's own vendor firmware at that point... Or are you talking about implementing RBC in the context of having selected SBC in the inquiry response?

EDIT 2: I have chosen for heaven's sake to respond to inquiry that I support SPC-2 / SBC, even though there are much newer versions of SPC and SBC.. Maybe this is something I can upgrade when I feel more comfortable after having supported the older one which I can reference from the USB stick I have. I doubt much would change in the impl anyways.
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: Barry Twycross on April 03, 2015, 06:23:21 pm
You're right Windows doesn't support RBC as declared in the enquiry. So we just declare Zero, whatever that is.

I was thinking about what commands actually to support. RBC and Bootability make a good subset, it works with all hosts I've tried it on so far. I don't support Format or Verify, but that's never been a problem.
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: bazz on April 07, 2015, 07:10:16 am
hehe, I've read all your responses.. Thanks for the tip, it sounds pretty risky, and even tho I have a triple boot machine and separate external hard drive with OSX installed, I think I'll pass.

EDIT: Regarding RBC, you must not be talking about stating support for RBC in the inquiry response, right? I actually personally went out of my way NOT to -- well in Jan Axelson's Mass Storage book, she went on to explain that PC's don't have RBC drivers natively, and that it'd be easier to create one's own vendor firmware at that point... Or are you talking about implementing RBC in the context of having selected SBC in the inquiry response?

EDIT 2: I have chosen for heaven's sake to respond to inquiry that I support SPC-2 / SBC, even though there are much newer versions of SPC and SBC.. Maybe this is something I can upgrade when I feel more comfortable after having supported the older one which I can reference from the USB stick I have. I doubt much would change in the impl anyways.
I tried this on my laptop and it worked, but with the following caveat: The beagle must be running in high speed mode to function correctly.. On Linux I was able to toggle high/full speed by the bus, so that I could have the beagle running High speed and the USB flash drive running in full speed. can I do this on my OS X? If not, you suggested I buy a full-speed USB hub. Do you have any suggestions for what debugging a device over a hub is like? Will it make the log file more confusing to read?

EDIT
You're right Windows doesn't support RBC as declared in the enquiry. So we just declare Zero, whatever that is.
That would be SBC
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: bazz on April 07, 2015, 12:46:14 pm

Does your device declare itself as a removable device? That is it sets the RMB bit in the inquiry data. That's the easiest way of doing this. You need to keep state of whether your "media" is loaded or not. It can start out loaded, but you should get an eject command (Start/Stop unit with LoEj=1) which causes you to become not loaded. Then you return a sense of Not ready, no media to just about anything the host tries to do (including test unit ready). When you want to remount the media, you start returning good status to the test unit ready.

If the host thinks the media was ejected, it invalidates all caches and rereads the media and can find new files. This method works in our device and about 150 million iPods out there

OK, I'm coding this part of the driver, and I have some questions.
What if I receive a START/STOP and LoEj is != 1 ? What kind of circumstance does this put me in? Can I just ignore LoEj and perform all logic based on START/STOP?

Also, if SCSI commands are sent that have a data stage, what is the correct step during STOP stage?? Send junk data that is the requested length followed by the CSW == 1 status?
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: bazz on April 08, 2015, 12:27:59 pm
I fixed a dire mistake in my code and now I can basically operate the drive, format it, update it, everything :D. There are still some bugs in my code, but they are personal bugs I need to find.

Although my previous posts are still pending answers, I'd love to talk about the super-bug-fix I found today :D

Arg, so it all boils down to this:
&BulkXfer.dataBuffer vs. &BulkXfer.dataBuffer[0] or some prefer just BulkXfer.dataBuffer

Oops.. It was causing the Write(10) to not actually write to the proper buffer.. And THAT'S why everything wasn't working correctly.. AKA -- formatting getting stuck at "waiting for disks to reappear" on Mac OSX -- on Linux, causing the drive to appear as unformatted after ejecting and re-inserting.. And on OSX, causing the drive to not display file contents after ejecting/re-inserting the drive..

But now it works!!

Pending Issues
I still get a 5-second hang after Clear Feature.. but I don't know why.. Everything checks out fine.. I unstall the EP then I send an empty data response packet.. Any tips? I'll try to see if I can capture that event on my USB sniffer.. but with the increase in accuracy in my code, there are less and less stalled end point events :)

Also, sometimes the device just stops handling USB traffic.. Argh.. that's on my end..  
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: Jan Axelson on April 08, 2015, 02:01:12 pm
As Barry asked, is your device responding to the Clear Feature request? Does the request complete?
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: Barry Twycross on April 09, 2015, 05:04:06 pm
On Linux I was able to toggle high/full speed by the bus, so that I could have the beagle running High speed and the USB flash drive running in full speed. can I do this on my OS X? If not, you suggested I buy a full-speed USB hub. Do you have any suggestions for what debugging a device over a hub is like? Will it make the log file more confusing to read?
The idea of moving the EHCI driver aside kills all high speed in the system, so you probably can't have different busses running at different speeds.

By log file, do you mean the Beagle trace? A hub doesn't add significantly to the log's complexity. Its particularly easy if you can hide traffic to the hub, I'm not sure if the beagle does that or not. If not, there is very little traffic to the hub, and you only see the traffic to the hub, not the replies, if you position the analyzer below the hub.

One other thought, does your device chip have a high speed mode bit? Most chips I've worked with allow you to respond to the chirp or not. If you turn that off the device becomes full speed even on a high speed capable bus.
Title: Re: Mass Storage Write (10) hangs at very last EP OUT data transfer
Post by: Barry Twycross on April 09, 2015, 05:13:57 pm
OK, I'm coding this part of the driver, and I have some questions.
What if I receive a START/STOP and LoEj is != 1 ? What kind of circumstance does this put me in? Can I just ignore LoEj and perform all logic based on START/STOP?
Loaded and started are really two separate state variables. The drive has to be loaded before it can be started. You can arbitrarily change the notion of loaded media, started should be more up to the host. This works better using loaded, I tried it with started and there are few corner cases which don't work out.

Quote
Also, if SCSI commands are sent that have a data stage, what is the correct step during STOP stage?? Send junk data that is the requested length followed by the CSW == 1 status?
I dont understand what you're asking.