Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.
La shoutbox n'est pas chargée par défaut pour des raisons de performances. Cliquez pour charger.

Forum Casio - Discussions


Index du Forum » Discussions » Investigating the slow file transfer of calculator under Linux
Calcloverhk Hors ligne Membre Points: 457 Défis: 10 Message

Investigating the slow file transfer of calculator under Linux

Posté le 06/11/2026 20:12

One of the longstanding issues I encountered when switching from Windows to Linux is the file transfer of Casio USB mass storage calculators between both platforms. That is, Windows is much faster than Linux in this case. For instance, transferring a 3.4 MB KhiCAS MPM add-in to my Graph Math+ takes about 3-4 minutes in Linux, whereas it is only 30 seconds at most in Windows. To figure out what happened during the write operations, I decided to capture and dissect these UMS packets using Wireshark, and I have to say this is wild.

For context, UMS devices are managed by the usb-storage driver in Linux. The parameter max_sectors controls the maximum amount of data that will be transfered to or from the device in a single command. Its default value is 240, which means a maximum transferred data size of 120 KiB where a sector is 512 bytes. The send retrial happens when dCSWDataResidue is non-zero and bCSWStatus = 0 (partial success), and its maximum is SD_MAX_RETRIES = 5. dCSWDataResidue must represent the difference between the amount of data expected from dCBWDataTransferLength and the actual amount of data transferred.

Let's take look at the 1 MB file capture in Linux. Applying usbms.dCBWSignature filter:



Each 4096-byte packet advances LBA as expected and has a duration of 0.01 s. Keep this delta in mind because it will be important later. Now you can see the following 6 packets of 120 KiB data are at LBA = 0x5e70, and it is the same for the next group at LBA = 0x5f60 and so on. Applying additional usbms.dCSWSignature filter and zooming in LBA = 0x5e70:



The calculator USB driver reports dCSWDataResidue = 118784, implying it only receives 122880 - 118784 = 4096 bytes from the host, and here is the problem. If the calculator really receives 4 KiB of data only, its delta should be the same as the one for the previous packets which is 0.01 s. However the value here is 0.3 s, thus having the same flash write speed, i.e. 4096 / 0.01 = 400 KiB/s and 122880 / 0.3 = 400 KiB/s. Combining with the fact that bCSWStatus = 0x00 (Good), this indicates the 120 KiB of data is actually written to the calculator storage on the first packet, and its driver is lying about the data residue that misleads the Linux SCSI driver to re-send the exact CBW command for 5 times. In Windows case, USBSTOR ignores the entire field and continues to send the next CBW, hence a faster speed.

Even worse, the misleading residue also affects the read operation, which leads to a detection failure that surfaces whenever I update systemd to 261 or higher. Lephenixnoir has previously documented on this matter and identified that it was due to the constant I/O errors generated from the USB calculator. Taking an example from his libblkid log:

[ +0.000011] sd 0:0:0:0: [sda] tag#0 CDB: Read(10) 28 00 00 00 01 f0 00 00 10 00
[ +0.000006] I/O error, dev sda, sector 496 op 0x0:(READ) flags 0x880700 phys_seg 2 prio class 2
[ +0.028607] sd 0:0:0:0: [sda] tag#0 FAILED Result: hostbyte=DID_ERROR driverbyte=DRIVER_OK cmd_age=0s

The 8th and 9th byte of CDB 00 10 represents the transfer length that specifies the number of contiguous logical blocks to read. Here 0x0010 = 16 blocks * 512 bytes = 8 KiB, which is larger than 4 KiB and triggers the bug.

We can reproduce this with the following bash script, and the expected result would be "ok" for the first 4k and "EIO" for the rest.

for bs in 1k 2k 3k 4k 5k 6k 7k 8k 9k 10k; do
    sudo dd if=/dev/sda1 of=/dev/null bs=$bs count=1 iflag=direct \
        2>/dev/null && echo "$bs ok" || echo "$bs EIO"
done

Linux has various "USB quirks" flags to deal with finicky storages, and the relevant one for our calculators is US_FL_IGNORE_RESIDUE in drivers/usb/storage/unusual_dev.h. The following patch was submitted to the upstream Linux kernel by Cakeisalie5 and is under review. Thanks @Cake <3

UNUSUAL_DEV( 0x07cf, 0x6102, 0x0100, 0x0100,
        "Casio",
        "fx-CP400",
        USB_SC_DEVICE, USB_PR_DEVICE, NULL,
        US_FL_IGNORE_RESIDUE ),
UNUSUAL_DEV( 0x07cf, 0x6103, 0x0100, 0x0100,
        "Casio",
        "fx-CG50",
        USB_SC_DEVICE, USB_PR_DEVICE, NULL,
        US_FL_IGNORE_RESIDUE ),

While waiting for the merge, you can immediately apply the equivalent fix with the following commands:

echo "options usb-storage quirks=07cf:6102:r,07cf:6103:r" | sudo tee /etc/modprobe.d/casio-usb-quirks.conf
sudo modprobe -r uas; sleep 2; sudo modprobe -r usb-storage; sudo modprobe usb-storage

The temporary alternative is to set max_sectors_kb to 4 so that every read is then split into 4096-byte commands and the residue arithmetic never goes wrong:

echo 4 | sudo tee /sys/block/sda/queue/max_sectors_kb
sudo udevadm trigger

In a nutshell:



cacioandpepe Hors ligne Membre Points: 25 Défis: 0 Message

Citer : Posté le 07/11/2026 02:58 | #


Hey. Sorry for the inactivity, been a bit busy lately.
Thanks for looking into this; Nonetheless I've been inactive, I will make sure to get it upstream faster by getting a
Tested-by tag
Also one more thing, if you have anything like this in the future, please don't go into personal messages on
the forum, write me an email or reply to that Linux port branch. I'd be happy to help.

And again,
Thanks

GPG : F747 7C61 CC79 5021 E060 6117 1E55 9E70 DF46 E38B
cacioandpepe Hors ligne Membre Points: 25 Défis: 0 Message

Citer : Posté le 07/11/2026 03:46 | #


Got you tested and Tested-by tag
I replied to your friend and the maintainer who Acked-by it
(for some reason Planet-casio flagged and removed my message, or magic).

Good job on the patch.
If you need any help with this next time,
write me an email or reply to Linux development
thread.

GPG : F747 7C61 CC79 5021 E060 6117 1E55 9E70 DF46 E38B
Calcloverhk Hors ligne Membre Points: 457 Défis: 10 Message

Citer : Posté le 07/11/2026 05:44 | #


Cacioandpepe a écrit :
Got you tested and Tested-by tag
I replied to your friend and the maintainer who Acked-by it
(for some reason Planet-casio flagged and removed my message, or magic).

Thanks! Linux kernel 7.4 LTS is on the way, and I sure hope it gets merged before the official release

Cacioandpepe a écrit :

Also one more thing, if you have anything like this in the future, please don't go into personal messages on
the forum, write me an email or reply to that Linux port branch. I'd be happy to help.

Noted
C.Basic Wiki Project progress as of 2024/2/12
   30%
Ptune4 (Submit SDRAM test result) | C.Basic developer
The reptile will say "Planète" and then "Casio".


LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

→ ⇒ √ Σ ∫ ≠ ≥ ≤ π θ ◢ ± α β γ δ Δ σ ≈ ∞ ∈ λ
captcha

Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2026 | Il y a 247 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd