This is the bug/patch tracker for Rockbox. Click here for more information.
Quick links: Bugs · Patches · Rockbox frontpage
FS#8562 - USB storage driver work
Attached to Project:
Rockbox
Opened by Frank Gevaerts (fg) - Wednesday, 06 February 2008, 13:17 GMT+2
Last edited by Frank Gevaerts (fg) - Thursday, 02 October 2008, 22:38 GMT+2
Opened by Frank Gevaerts (fg) - Wednesday, 06 February 2008, 13:17 GMT+2
Last edited by Frank Gevaerts (fg) - Thursday, 02 October 2008, 22:38 GMT+2
|
DetailsThis is a followup for
Some fixes for the usb storage driver. The behaviour doesn't change, but according to my reading of all relevant specs, this should be more correct. |
This task depends upon
Closed by Frank Gevaerts (fg)
Thursday, 02 October 2008, 22:38 GMT+2
Reason for closing: Accepted
Additional comments about closing: All code is in svn. It doesn't fully work yet, but new patches can get new tasks
Thursday, 02 October 2008, 22:38 GMT+2
Reason for closing: Accepted
Additional comments about closing: All code is in svn. It doesn't fully work yet, but new patches can get new tasks
The largest remaining problems are:
- no high speed
- reading more than 16k in one transfer fails, and the host does not handle this gracefully. Probably someone needs to study UMS and/or SCSI specs in some detail to find out how to solve this
- no write support yet.
Currently it is possible to mount the device in linux (provided udev doesn't try to read too much from it), but that's about it.
du -csh /media/Sansa\ e260
find -name *bmp -exec md5sum "{}" ";"
cp -R "Albumname" /home/rasher/Desktop
cp -R /home/rasher/Desktop Albumname-copy
md5sum "Albumname/*"
md5sum "Albumname-copy/*"
All without flaws (and the md5sums match :-) ).
Edit: The filesystem was thoroughly hosed, and I had to format. So there's some work left still :-)
It is good enough to install a rockbox binary over it, and then booting.
Do you have a microSD card available you could plug in ? (preferably 2GB or less to make sure, but a larger one would do). I'd like to see if the same problem also happens on the SD-slot.
If you still want to test the rest of the patch, you can try changing line 322 in firmware/usbstack/usb_storage.c to :
capacity_data->block_count = htobe32(cinfo->numblocks * 1024 - 1);
(i.e. add the "* 1024")
Note that you might get usb resets in your dmesg now and then. These should be harmless (but they do slow everything down even more).
Some observations:
I have a 6gig SDHC card (I have no "normal" micro sd card) which is recognized but it can not find a valid fat filesystem on the device. The log has:
VFS: Can't find a valid FAT filesystem on dev sdg2
With longer disk operations I always see a timeout.
usb 1-7: reset full speed USB device using ohci_hcd and address 18
It is not going into "diskmode" without forcing it to (left button). I suspect this is causing small weird problems I have been seeing before.
Attaching the OF kernel log, below with this patch.
Feb 9 23:36:45 infirit usb 1-7: new full speed USB device using ohci_hcd and address 12
Feb 9 23:36:45 infirit usb 1-7: configuration #1 chosen from 1 choice
Feb 9 23:36:45 infirit scsi26 : SCSI emulation for USB Mass Storage devices
Feb 9 23:36:45 infirit usb-storage: device found at 12
Feb 9 23:36:45 infirit usb-storage: waiting for device to settle before scanning
Feb 9 23:36:50 infirit scsi scan: INQUIRY result too short (5), using 36
Feb 9 23:36:50 infirit scsi 26:0:0:0: Direct-Access mnopqrst PQ: 0 ANSI: 0
Feb 9 23:36:50 infirit sd 26:0:0:0: [sdg] 15708160 512-byte hardware sectors (8043 MB)
Feb 9 23:36:50 infirit sd 26:0:0:0: [sdg] Write Protect is off
Feb 9 23:36:50 infirit sd 26:0:0:0: [sdg] Mode Sense: 00 00 00 00
Feb 9 23:36:50 infirit sd 26:0:0:0: [sdg] Assuming drive cache: write through
Feb 9 23:36:50 infirit sd 26:0:0:0: [sdg] 15708160 512-byte hardware sectors (8043 MB)
Feb 9 23:36:50 infirit sd 26:0:0:0: [sdg] Write Protect is off
Feb 9 23:36:50 infirit sd 26:0:0:0: [sdg] Mode Sense: 00 00 00 00
Feb 9 23:36:50 infirit sd 26:0:0:0: [sdg] Assuming drive cache: write through
Feb 9 23:36:50 infirit sdg: sdg1 sdg2
Feb 9 23:36:50 infirit sd 26:0:0:0: [sdg] Attached SCSI removable disk
Feb 9 23:36:50 infirit sd 26:0:0:0: Attached scsi generic sg7 type 0
Feb 9 23:36:50 infirit usb-storage: device scan complete
I also got:
Feb 9 23:42:59 infirit usb 1-7: reset full speed USB device using ohci_hcd and address 13
Feb 9 23:42:59 infirit sd 27:0:0:0: [sdg] Result: hostbyte=0x05 driverbyte=0x00
Feb 9 23:42:59 infirit end_request: I/O error, dev sdg, sector 10872
Feb 9 23:43:59 infirit usb 1-7: reset full speed USB device using ohci_hcd and address 13
Feb 9 23:44:05 infirit sd 27:0:0:0: [sdg] READ CAPACITY failed
Many of the below
Feb 9 23:44:05 infirit FAT: Directory bread(block 10851297) failed
Sometimes this one.
scsi 27:0:0:0: rejecting I/O to dead device
That's expected. sdg2 is the sansa firmware partition, not the sd card. The sd card should be sdh, which is missing for some reason. Does the sd card work properly in rockbox ? It also doesnt't show up in the OF (the card isn't supported, but the slot should be shown)
- usb 1-7: reset full speed USB device using ohci_hcd and address 18
These are unfortunately still happening. They should be harmless, but slow things down a lot.
- I don't really understand what you mean by 'It is not going into "diskmode" without forcing it to (left button).'
- I only get the Result: hostbyte=0x05 driverbyte=0x00 and end_request: I/O error messages when I experiment with getting high speed to work. They look like USB level problems to me. Can you try checking if all cables are plugged in correctly, and maybe trying a different port on your PC (back ports vs front ports sometimes make a difference) ?
- The FAT Directory bread errors and the rejecting I/O to dead device errors are probably effects earlier I/O errors.
Disk mode is when the cable is connected, the music stops and a USB cable logo shows up. AFAIK the device can either be accessed as a disk and charging or just charging. The latter will allow the device to be used. With this patch I now connect the cable it will allow me to use the device and access it as a disk.
I do not see any FAT directory or any of the other errors (except the reset) when the device is in diskmode.
I changed the cable from the front connector to the back and this does not make any difference. The cables is connected correctly.
I've done a little more testing on my ipod Color (60GB hard disk):
1) You probably know this already, but I'm getting a message "scsi scan: INQUIRY result too short (5), using 36" when attaching the device (others have reported this on Sansas as well).
2) I started by reformatting my device using the OF's UMS mode and installing a Rockbox build.
3) I then rebooted and connected with Rockbox's UMS mode and copied a 300MB directory of FLACs. This appeared to work fine, although I did get a single "usb reset" in the logs (earlier tests showed many more usb resets).
4) I then umounted and then remounted the device (whilst still connected in Rockbox), and the directory structure appeared to be corrupted. Rebooting into the OF's UMS mode also showed the errors. Oddly, Rockbox seemed perfectly happy with the filesystem, and played my copied album fine.
I then repeated the test (by reformatting in the OF's UMS mode), and copied the same album across, and it worked fine... I'll keep testing and let you know if I can do something repeatable.
- In rasher's tests (on e260), the SD card slot is always shown both from OF and from rockbox, whether or not there is a 6G card in it or not, so I don't understand what is happening on your e280.
- I see what you mean by disk mode now. Actually the USB connect screen always be should be shown on connect, but there is a bug that stops that from happening. Can you reproduce the I/O or FAT errors if you stop de music first, and don't do anything that could write to the filesystem ?
@chrisjs169:
Testing is always welcome, but right now we're still at a point where there is a small but non-zero risk involved. We also seem to have quite a few sansa testers, so we don't absolutely require more. So it's up to you...
@linuxstb:
1. Yes I know. This is because we use the SCSI-RBC command set which is recommended bu the UMS spec, but nobody else does. Someone should look up the correct INQUIRY response from the SPC-2 spec and implement that. It doesn't seem to cause any problem, so it's low priority.
4. Did you do anything in rockbox that might have caused filesystem access (or did you get the USB screen ?)
Edit: Both on Linux and Windows (XP), although my 6GB sdhc card doesn't show up in Windows.
Can you check if CONFIG_SCSI_MULTI_LUN is enabled in your kernel config ? You can probably find the kernel config file somewhere in /boot.
Standard SD works without problem but SDHC does not. It fails with error:
FAT: bogus number of reserved sectors
VFS: Can't find a valid FAT filesystem on dev sdh1.
If I have some time tomorrow I will test the v2 patch again and see if I can reproduce the errors.
Can you try checking the filesystem ?
fsck.vfat /dev/sdh1
dosfsck 2.11 (12 Mar 2005)
dosfsck 2.11, 12 Mar 2005, FAT32, LFN
Logical sector size is zero.
I also fsck'd the SDHC card with a standard sd reader and this gives me no curuption.
From rockbox:
mkfs.vfat -F 32 /dev/sdcard_drive
This gives me a 2 gig fat filesystem which looks like SDHC is not working completely. It is not readable from the card reader and fsck.vfat exits with "Currently, only 1 or 2 FATs are supported, not 26". Mounting from rockbox and playing from rockbox works.
From the card reader:
mkfs.vfat -F 32 /dev/sdcard_drive
Creates 6 GB filesystem which I can mount and play music from rockbox.
It looks like the sd card before mkfs.vfat had something on it which rockbox could not handle but a card reader + linux could. Anyway it works now.
The scsi device names should be a bit more meaningful now. On ipods they should match what the OF is sending. ipods also have a correct serial number.
(thanks to linuxstb for most of the changes in this one)
- handle START_STOP_UNIT (makes the eject not hang)
- handle READ_FORMAT_CAPACITY (makes the sd slot work in windows)
Note that we don't handle unplugging the sd card while connected properly yet
defining USE_ROCKBOX_USB will enable all new stuff
I guess all that means "almost working but not quite." Maybe it's just a Vista thing (which I just had forced on me and hate)?
When plugging in the Sansa turned off, it still behaves normally for me, i.e., boots the OF.
- much less work is done in interrupt context
- rework the transfer descriptor allocation. This seems to have reduced the usb reset issue, but further testing is needed
- changed the usb_core thread shutdown as suggested by jhMikeS
Thanks for your work. You're filling a huge gap.
When I build with the path but remove the USE_ROCKBOX_USB define from my Makefile, the firmware works without a hitch. So it's probably not the build environment.
Another difference I have noticed from the OF is that Rockbox reports ANSI: 3, rather than ANSI: 0 for the OF. I was informed on IRC that this corresponds to the SCSI level. Changing it didn't make any noticable difference. Should we just report the same as the OF?
Along the same lines, the "mode sense" for the OF is 45 00 00 00, but 00 00 00 00 for Rockbox. I tried changing what Rockbox reports to be the same as the OF, but ended up getting a lot more resets and the disks never actually mounted for me on Linux.
barrywardell: I think we should be as standards-compliant as we can (within reason).
According to spc2r20.pdf (scsi primary commands v2), ANSI:0 means the device doesn't claim any compatibility, so the OS has to guess.
I'll try to fix the mode sense as well. The effect you are seeing is probably the OS asking for MODE SENSE data using different parameters, with 00 00 00 00 being acceptable for every one (probably interpreted as "i don't know"). and 45 00 00 00 being only valid for specific situations.
Anyway, I think we should actually start implementing what the scsi spec specifies as mandatory, instead of just doing whatever is needed to make it work (the latter will probably make it not work in some situations we didn't test yet)
I agree the version and responseformat fields as reported in the INQUIRY data should correspond to actual versions. For example, if we're following the set of specifications SBC-2 (SCSI block commands - 2) and SPC-3 (SCSI primary commands - 3), those fields should be 5 and 2 respectively.
It seems that the remaining problems might be triggered by control transactions not being handled in the interrupt handler any more, and thus being slower. This means that in some cases the host tries to start a new control transaction (after timing out on the previous one ?), which requires special handling by the driver software (see MCIMX31RM.pdf, 32.14.3.2).
I think this does not warrant returning everything to the interrupt handler, because (a) this problem can also occur then (although it should be much rarer), (b) this moving out significantly shortens the interrupt handling time, and (c) the new style handling allows for (IMO) much cleaner code.
What probably needs to happen is:
- implement the SETUP error-checking described in 32.14.3.2.2 (after understanding it properly...)
- find some way to make control transactions not wait on bulk. This can be done in several ways : (a) put control handling in a separate thread, and provide locking in all the right places, (b) put class drivers in separate threads, and provide the same locking, or (c) make usb_drv_send non-blocking, and adapt class drivers to handle this properly. (a) and (b) keep class drivers simple and add complexity to the controller driver, while (c) adds complexity to the class drivers while keeping the controller driver simple. I'm not sure which is best.
An easy way to crash this (in linux) is to start badblocks -w on your device, and then run "while true;do lsusb -d 0781: -v;done" (change vendor id as required). This makes badblocks block after a while (watch it using strace). If you then stop the lsusb loop you'll get a device reset and badblocks will go on, but if you leave the lsusb loop running the rockbox will stop responding properly to control packets. (I recommend to only do this on a sansa on the sd card, badblocks will damage your data...)
I also managed to crash svn like this once, but it's a lot harder.
This lsusb loop is not a "normal" load, so it might be more stable in real use, but I haven't done heavy testing of that yet.
(a) I think RBC (reduced block commands) won't work well, because when I set the device type accordingly Windows XP doesn't find a driver, and if the device type is set to DIRECT_ACCESS_DEVICE the host OS seems to assume a standard block device.
(b) For the scsi standards compliance I would like to go for SBC-2, which might require SPC-3. The reason is that SBC-2 allows to set the maximum transfer length, which if it is honored by the host OS (to be tested...), would allow us to reduce the transfer buffer. This would require a few commands that we don't really need, but those could probably be stubs.
(c) Maybe we should use the appropriate SCSI command (probably SCSI_START_STOP_UNIT or SCSI_ALLOW_MEDIUM_REMOVAL) to trigger showing of the USB screen. This would allow to copy some files, unmount the device, and leaving it plugged in to charge while using it.
This change gives a speed improvement of 50% to 100%
are there any patch dependencies? tried with the current svn repository
and put the following line somewhere in the file
#define USE_ROCKBOX_USB
I made a small speed test (just with the "...seconds remaining") in Windows Explorer (XP SP2) with a 21 MB file:
Rockbox: 60 seconds
OF: 25 seconds or maybe less
For me, this is more than perfect. Incredible job Frank, congratulations. Respect.
### /var/log/messages
Feb 18 20:32:45 backer-laptop kernel: [ 2054.240000] usb 3-1: new full speed USB device using uhci_hcd and address 9
Feb 18 20:32:45 backer-laptop kernel: [ 2054.408000] usb 3-1: configuration #1 chosen from 1 choice
### lshal -m
20:32:45.619: usb_device_781_7421_0000000000000000A4B4476617EA0AF4 added
20:32:45.694: usb_device_781_7421_0000000000000000A4B4476617EA0AF4_if0 added
20:32:45.697: usb_device_781_7421_0000000000000000A4B4476617EA0AF4_usbraw added
20:32:57.722: acpi_BAT1 property battery.voltage.current = 12545 (0x3101)
In fact, I used Rockbox's native USB support to update Rockbox itself for the first time ever.
- now passes all but one USBCV ch9 tests
- returns a SCSI error when encountering a disk/flash read/write error
Things not only have to be aligned to a cache line boundary but also size padded to a boundary so cacheable data isn't allocated in an overlapped manner with pieces of noncacheable data. It's best to concentrate all such data into a single structure and make sure it's padded. This helps to avoid wasting space since only one alignment/padding will be needed for all of it. If one isn't practical for all of it, of course keep the instances to a minimum.
apps/plugins/mpegplayer/video_out_rockbox.c demonstrates one (perhaps eccentric) way to do this since I'm not aware of GCC providing any sort of set-and-forget padding attribute.
Perhaps I've rambled too much :p and I hope that any questions were answered.
BTW, I think the proper alignment for PP is 16 bytes but I went cautious for now. Stick with the macros since other targets like the gigabeats actually need consideration in this manner when using DMA and they definitely are 32-byte aligned.
Removing them limits transfer buffers to 16k, but this turns out to only cause a 2% slowdown. As an added benefit, the simpler code makes simultaneous UMS and USB-serial work.
I made another test (same file as above) and I got just a bit over 35 seconds, which is incredible.
I'm unsure about something: when you plug in the cable while holding the center button pressed, it shouldn't appear as a drive in my computer, right? I can't notice any difference in the computer's behaviour. On the Sansa tho, if I press the center button, the USB screen doesn't appear but the connection starts anyway. I guess this can be easily fixed.
- alignment problem on some USB string descriptors
- does not show the sansa SD card slot to the host if no card is present. This is a workaround until I know how to handle removable drives properly.
- doesn't enable serial by default
This patch still requires USE_ROCKBOX_USB to be defined, and it still connects with the select button pressed. This will be fixed somewhere in the next round of cleanups.
Read time (132 MB):
OF: 4.125s
Rockbox: 2m22.580s
Transferring (both to and from) a 27MB file seems to take 0.1 seconds on Rockbox though..
What happens if I connect my e270 via USB, while running Rockbox (current SVN; native Rockbox USB support enabled), if I hold the select button while plugging in the cable?
Conversely, what happens if I *don't* hold that button while plugging in the cable?
I gather that there's some difference between these "modes" of connection, if that's the proper terminology, but I'm not understanding the difference. Is there a reason why one would hold the button or not?
What _should_ happen is that when holding the select button, you only charge over USB, i.e. the player doesn't present itself as a disk to the host.
What actually happens is that the player always presents itself as a disk, but the logic that makes disk connections safe is disabled by holding the button.
So in short:
- If you just want to charge, press the button while connecting. This will allow "normal" usage of the player. This is now dangerous due to a bug which allows the host to access the disk as well, which can lead to data corruption.
- If you want to transfer files, just plug in. The player will show the USB screen and disallow local disk accesses so the host has exclusive access.
I hope to fix this within the next few days
This has only been lightly tested, but since there are no real USB driver changes, it _should_ still be safe. Right now I am more interested in review than actual test results.
The content of the file is pretty big, should I upload it somewhere?
I'll try to find a way to get USE_ROCKBOX_USB working again. It might be useful to have all code in svn for easy testing without having to enable it by default from the start.
The main issue with this version is that for some reason it doesn't see a connection if plugged in while booting.
- USE_ROCKBOX_USB is back, and needs to be enabled for UMS to work
- firewire detection is now handled separately from usb detection
- the thread priority gets increased during UMS connections
I'd like to commit this to svn, so I'd especially like testing if everything still works _without_ USE_ROCKBOX_USB. I do need to know the following:
(without USE_ROCKBOX_USB)
1.the player reboots on plugin (and firewire players reboot on firewire plugin)
2.the player doesn't reboot on plugin when the "charge only" button is held (same for firewire)
2a.the player works correctly after unplugging, and plugging in again works as expected
3.the "screenshot on plugin" setting still works as expected
(with USE_ROCKBOX_USB)
3.the player enumerates as a mass storage device on normal plugin
4.the player doesn't enumerate as a mass storage device when the "charge only" button is held
5.the "screenshot on plugin" setting still works as expected, and doesn't present a mass storage device to the host
6.the player still works after unplugging, and plugging in again works as expected
7.firewire players still reboot on firewire plugin, except when the "charge only" button is held
3 -> works, 4 -> works, 5 -> No idea what this is, 6 -> works but will test more tomorrow, 7 -> no firewire on my sansa.
Tomorrow I will test without USE_ROCKBOX_USB if none have tested before me.
I did see a lot of data corruption with svn from yesterday (no patches) when I pushed 2 gigs of music to the sdhc card. In the logs I found a few resets and some io errors. I will try to reproduce this tomorrow with this patch.
http://www.rockbox.org/tracker/task/8272
Tested with this patch applied on my H340. Connect, disconnect and charge only mode behave as expected. I copied over 3.1Gb and there was no corruption or errors in the logs.
I hate to say it but the Mac OSX 10.5 does not like the usb storage driver.
I think this happens on alot of devices that I use :( Mac's aren't playiing very nice.
Here's the output: From dmesg
msdosfs_fat_uninit_vol: error 6 from msdosfs_fat_cache_flush
dlil_output: output error retval = 1
USBF: 337148.880 [0x3e2e400] The IOUSBFamily is having trouble enumerating a USB device that has been plugged in. It will keep retrying. (Port 1 of hub @ location: 0xfd000000)
USBF: 337148.880 [0x3e2e400] The IOUSBFamily was not able to enumerate a device.
USBF: 337362.327 AppleUSBUHCI[0x3ccc000]::Found a transaction past the completion deadline on bus 0x1d, timing out! (Addr: 3, EP: 1)
After disconnedcting and reconnecting:
USBF: 337743.369 AppleUSBUHCI[0x3e50000]::Found a transaction past the completion deadline on bus 0x3d, timing out! (Addr: 2, EP: 1)
USBF: 337774.371 AppleUSBUHCI[0x3e50000]::Found a transaction past the completion deadline on bus 0x3d, timing out! (Addr: 2, EP: 1)
After rebooting I get this:
dlil_output: output error retval = 1
dlil_output: output error retval = 1
disk1s0: ioctl(_IOWR,'d',101,16) is unsupported.
dlil_output: output error retval = 1
dlil_output: output error retval = 1
.... continued then below
USBF: 86.370 AppleUSBUHCI[0x3e36000]::Found a transaction past the completion deadline on bus 0x3d, timing out! (Addr: 2, EP: 1)
USBF: 117.371 AppleUSBUHCI[0x3e36000]::Found a tran
Other than that, on my H10 this is perfectly stable at high speed now. I've copied about a gigabyte of files back and forth several times without a single error or reset in dmesg and with the md5sums matching. What more (other than the SCSI commands) needs to be done before this can be enabled by default?
For that scenario to work though, I really need to know that this patch doesn't harm any player with USE_ROCKBOX_USB not set. This seems to be the case for both sansa c200 and e200, and h300, but I didn't hear about others yet.
Admittedly, the behaviour of the H10 is different from all the others. The reason it's different is that to get into disk mode, you have to be holding down right and have the USB cable connected as it boots.
So, basically, this patch doesn't change the behavior on H10 when USE_ROCKBOX_USB is not set.
If you notice extreme slowness, please report the exact player, operating system, and what USB ports on your PC you used (front, back,...). If possible try different ports (back ports are expected to work better)
For what it's worth, I'd connected the Sansa to my PC using a rear-panel USB port.
00 00 00 08 00 77 d7 ff 02 00 02 00 for the Sansa e260, whereas rockbox returns
00 00 00 08 00 77 d7 ff 00 00 02 02
It looks like an endian issue with SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA.
Maybe these are the 2 bytes we see in the Sansa SD-driver bug?
Actually I'm trying to find the cause of the 3 minutes lag in Windows. Windows keeps trying SCSI_READ_FORMAT_CAPACITY on the empty SD-Slot. Each time with a port reset and 20 seconds lag. It doesn't seem to like our fail CSW, but it's not the missing data_residue value...
Since I don't know how to implement that cleanly, I did a quick&dirty patch, just to demonstrate this issue. It apparently makes Windows completely happy and let it deal properly with the empty SD slot. It's been tested with W2K, XP and Vista with high speed. I didn't dare to write much, though.