PrettyOS Fehler-/Testthread
-
Revision 374
// ehci.c 374 void resetPort(uint8_t j) { pOpRegs->PORTSC[j] |= PSTS_POWERON; /* http://www.intel.com/technology/usb/download/ehci-r10.pdf (...) */ pOpRegs->PORTSC[j] &= ~PSTS_ENABLED; }
Der Kommentar aus dem Manual betrifft PSTS_PORT_RESET und nicht PSTS_POWERON.
Mein realer PC hat lt. Scan 10 USB-Ports. Davon sind aber nur 9 "von außen" verfügbar. Deshalb wird ein Port (jedesmal der gleiche) ständig als "power on, enabled, EHCI owned" angezeigt. Unabhängig davon ob nun ein USB-Gerät "eingeklinkt" ist/wird oder nicht. Dieser Port zeigt auch (ganz selten aber) mal "J-Status" an.
Außerdem kann es ganz, ganz, ganz selten passieren, daß die untere Statuszeile nach > 200 Sekunden für eine Sekunde Unsinn anzeigt (z.B. 55:55:5555 als Uhrzeit).
-
Revision 391
// ckernel.c rev 391 static void init() { // kernel_console_init(); // clear_screen(); gdt_install(); idt_install(); kernel_console_init(); clear_screen();
Besser die Deskriptoren zu aller erst installieren und danach den "Rest". VMWARE hatte mal in früheren Revisionen in "kernel_console_init" Mist gemacht woraus dann ein Triplefault resultierte. USB rev 391 funktioniert auf meinem realen PC auch.
-
USB rev 391 funktioniert auf meinem realen PC auch.
Danke für den Hinweis! Diese Version sollten wir nun zu einer stabilen, brauchbaren Basis ausbauen, bevor wir neue Experimente aufsetzen.
-
Revision 398
Hm, einmal würde reichen.// ckernel.c 398 static void init() { (...) // descriptors gdt_install(); idt_install(); // cf. interrupts.asm // descriptors gdt_install(); idt_install(); // cf. interrupts.asm // video kernel_console_init(); clear_screen(); (...) }
-
oh, das stimmt natürlich, wird geändert.
Danke
-
Revision 401
Da haben sich einige "Rechtschreibfehler" eingeschlichen:// usb2.c 401 void showConfigurationDesriptor(struct usb2_configurationDescriptor* d) (...)
Desriptor -> Descriptor
(Btw.: Wollt ihr den CDI-Kram auch mal einsetzen?)
-
Ja, wir würden ihn gerne einsetzen, aber das setzt Einsatzbereitschaft voraus: Die Implementation ist nichtmal ansatzweise fertig.
-
Da haben sich einige "Rechtschreibfehler" eingeschlichen
Danke!
Bevor wir noch beim Raptor enden, haben wir es korrigiert.
-
Wollt ihr den CDI-Kram auch mal einsetzen?
Wenn Du uns beim USB bulk transfer bei der Fehlersuche hilfst, kommen wir schneller daran.
-
Revision 434
Auf meinem realen PC funktioniert eine stark zusammengestrichene testMSD() perfekt:
// usb2_msd.c 434 void testMSD(uint8_t devAddr) { // maxLUN (0 for USB-sticks) usbDevices[devAddr].maxLUN = 0; usbTransferBulkOnlyMassStorageReset(devAddr, usbDevices[devAddr].numInterfaceMSD); // Reset Interface ///////// step 7: send SCSI comamnd "read(10)", read one block (512 byte) from LBA ..., get Status textColor(0x09); printf("\n>>> SCSI: read(10)"); textColor(0x0F); usbSendSCSIcmd(devAddr, usbDevices[devAddr].numEndpointOutMSD, usbDevices[devAddr].numEndpointInMSD, 0x28, 0, 1, true); waitForKeyStroke(); }
Aber ein zweiter Aufruf von usbSendSCSIcmd() innerhalb von testMSD() geht regelmäßig schief. Irgendwas stimmt mit den blöden Adressen noch nicht.
VMs schummeln ja immer in dieser Hinsicht.
-
stimmt, der einmalige Aufruf einer Funktion ging bisher immer recht gut, nur die Abfolge macht Probleme. Schau dir bitte mal die rev. 435 an.
Noch besser: die Version 436 mit aktiviertem #define _USB_DIAGNOSIS_ (ging vorher nicht fehlerfrei)
Ich habe noch ein "test unit ready" vor "inquiry" gesetzt, dann hakt es beim IN-endpoint bei "inquiry" aus, was zuvor an Platz eins bestens lief. Der QH/qTD-Code ist also prinzipiell ok.
Nimmt man zweimal inquiry hintereinander:
- erstes läuft gut
- beim zweiten "inquiry" wird der IN-QueueHead nicht mehr ausgeführtdev: 3 interface: 0 endpOUT: 2 endpIN: 1
USB2: usbTransferBulkOnlyMassStorageReset, dev: 3 interface: 0#
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''> SCSI: inquiry
OUT part#
IN part transfer>0#
virtAddrBuf0 C024D000h : 00h 80h 02h 02h 1Fh 00h 00h 00h 6Dh 65h 6Dh 6Fh 72h 79h
00h 00h 55h 53h 42h 32h 2Eh 30h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 31h 2Eh
30h 30h
virtAddrBuf0 C024D000h : memoryUSB2.01.00virtAddrBuf0 C024C000h : 55h 53h 42h 53h 12h 42h 42h 42h 00h 00h 00h 00h 00h
Command Passed ("good status")
qTD Status: 00h OK (no bit set)<-- data
qTD Status: 00h OK (no bit set)<-- statusCommand Block Status Values in "good status"
> Press key <<<
> SCSI: inquiry
OUT part#
IN part transfer>0###################
timeout - no STS_USBINT set!
virtAddrBuf0 C0253000h : 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h
00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h
00h 00h
virtAddrBuf0 C0253000h :virtAddrBuf0 C0252000h : 55h 53h 42h 53h AAh AAh AAh AAh AAh AAh AAh AAh AAh
qTD Status: 80h Active - HC transactions enabled<-- data
qTD Status: 80h Active - HC transactions enabled<-- statusBeide an den IN-QH angehängten qTD werden nicht ausgeführt, obwohl es beim ersten Durchgang problemlos abgearbeitet wird.
-
Irgendwas stimmt mit den blöden Adressen noch nicht.
@+gjm*: kannst du das genauer spezifizieren? Ich sehe beim speicher kein problem.
Die neue Rev. 437 ist etwas besser geeignet für Versuche.
-
Rev. 439 bietet nun den besten Überblick über den Transfer im qTD-Bereich.
-
Mit Rev. 441 haben wir eine erste stabile Plattform bei USB Mass Storage Device erzielt. Wenn sich dies stabilisiert können wir die Floppy bald in "Rente" schicken.
-
<RAM Disk at C0002000h DIR> dev 35 infošºíÆ×íí-îù̬Åîí^Àì?¬ÎNèTÝUÅË 9796 shell¤¼ìŽž„œššDþ„TôÁŽÅÞŽHÚÎÌŸË.[
Hier wurde offenbar etwas "kaputt" optimiert. Da fehlt das abschließende '\0'.
EDIT: wurde inzwischen repariert (neues strncpy)
-
Rev. 444 zeigt den oberflächlichen Grund, warum Transfers nicht laufen (qTD Status 0x80 (= active bit7) wird nicht zurück gesetzt und qTD nicht ausgeführt):
Es liegt am NAK counter. Setzt man RL (reload Nak Counter) auf 15 (4-bit-value), dann findet man bei manchen Devices NAK counter = 0, also 15 mal NAK. Dann bleibt der EHCI hilflos stehen.http://www.lowlevel.eu/wiki/USB (von XanClic):
Hier schickt der Host zuerst einmal das Datenpaket, kann das Gerät dieses nicht annehmen, antwortet es mit NAK. Wenn es das Paket empfangen kann, antwortet es mit ACK, wenn das Gerät danach noch ein Paket aufnehmen kann oder mit NYET, wenn nicht. Hat der Host ACK empfangen, so sendet er das nächste Paket. Hat er allerdings ein NYET oder ein NAK erhalten, dann beginnt er nun mit PING-Paketen. Das Gerät muss mit NAK antworten, wenn es immer noch kein Paket empfangen kann, oder mit ACK, wenn es nun bereit ist. Dies verringert die Anzahl an sinnlos gesendeten Daten natürlich erheblich. Das Gerät kann hierbei sogar angegeben, wann das nächste PING-Paket gesendet werden soll (der Host muss dies aber nicht befolgen).
Der NAK counter zählt auch NYET, wenn ich das richtig verstanden habe.
-
Revision 447
Sherlock Holmes schrieb:
Wenn man alles Unmögliche ausgeschlossen hat, muss in dem, was noch übrigbleibt, so unwahrscheinlich es auch scheinen mag, die Wahrheit zu finden sein.
^^ In diesem Sinne:
Nach jedem Aufruf von usbSendSCSIcmd (usb2_msd.c) geht das verloren, was der Aufruf von usbTransferSetConfiguration (usb2.c) in checkPortLineStatus (ehci.c) bewirkt hatte.
// usb2_msd.c 447 void testMSD(uint8_t devAddr) { (...) ///////// step 1: send SCSI comamnd "inquiry (opcode: 0x12)" textColor(0x09); printf("\n>>> SCSI: inquiry"); textColor(0x0F); //=====================================DEBUG============================ usbTransferSetConfiguration(devAddr,1); // usbTransferBulkOnlyMassStorageReset(devAddr, usbDevices[devAddr].numInterfaceMSD); // Reset Interface //=====================================DEBUG============================ usbSendSCSIcmd(...); ///////// step 2: send SCSI comamnd "test unit ready(6)" textColor(0x09); printf("\n>>> SCSI: test unit ready"); textColor(0x0F); //=====================================DEBUG============================ usbTransferSetConfiguration(devAddr,1); // usbTransferBulkOnlyMassStorageReset(devAddr, usbDevices[devAddr].numInterfaceMSD); // Reset Interface //=====================================DEBUG============================ usbSendSCSIcmd(...); // (usw.) }
^^ So läufts auf meinem realen PC.
-
Danke für den Tipp!
-
Ich habe das jetzt objektiv getestet:
- lief auch schon vorher auf real PC
- es gibt in der Tat usb-sticks, die die configuration zurück auf 0 setzen! Kann man mit getConfig ja vorher testen
- aber jetzt kommt es:
PrettyOS [Version 0.0.0.449] Console 1: EHCI Ports
--------------------------------------------------------------------------------
USB2: SET_CONFIGURATION 1>!
USB2: GET_CONFIGURATION>! 1
OUT part
asyncList: 01667000h <-- QH_Out CommandQTD: 01669000h
before aS:
curr QH: 01667000h next QH: 01667000h
curr qTD: 00000000h next qTD: 01669000h
NAK counter: 0>!
after aS:
curr QH: 01667000h next QH: 01667000h
curr qTD: 01669000h next qTD: 00000000h
NAK counter: 15
IN part
asyncList: 01668000h <-- QH_In
handshakeQTD: 0166B000h StatusQTD: 0166D000h DataQTD: 0166F000h
before aS:
curr QH: 01668000h next QH: 01668000h
curr qTD: 00000000h next qTD: 0166F000h
NAK counter: 0>!
after aS:
curr QH: 01668000h next QH: 01668000h
curr qTD: 0166B000h next qTD: 00000000h
NAK counter: 15
00h 80h 02h 02h 1Fh 00h 00h 00h 6Dh 65h 6Dh 6Fh 72h 79h 00h 00h 55h 53h 42h 32h
2Eh 30h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 31h 2Eh 30h 30h
memoryUSB2.01.0055h 53h 42h 53h 12h 42h 42h 42h 00h 00h 00h 00h 00h
Command Passed ("good status")
qTD Status: 01h Do Ping<-- command
qTD Status: 00h OK (no bit set)<-- data
qTD Status: 00h OK (no bit set)<-- status
USB2: GET_CONFIGURATION>! 0
USB2: SET_CONFIGURATION 1>!
USB2: GET_CONFIGURATION>! 0Command Block Status Values in "good status"
USB status: 00002000h
Reclamation> Press key <<<
--------------------------------------------------------------------------------
Port: 1, device attachedVor "inquiry" ist alles ok.
Nach "inquiry" sitzt die configuration auf 0 (bedeutet unkonfiguriert) und lässt sich aber auch nicht mehr gerade biegen auf 1.@+gjm+: Echt Superklasse dein Fund! Wie machst du das bloß?
-
Der Grund ist gefunden: ein falscher handshake nach dem CSW
Dieses Bild hat mich irre geleitet: http://www.beyondlogic.org/usbnutshell/contdata.gif in http://www.beyondlogic.org/usbnutshell/usb4.htm bei bulk transfer
Ich sehe drei Fälle:
- MSD device ist unempfindlich gegen falschen handshake (bei mir zwei 16 GB sticks und der 512 MB stick)
- MSD device ist empfindlich gegen handshake, man kann aber die config wieder setzen (das war der Fund von +gjm+)
- empfindlich, nicht reaparierbar, also trotz "setzen" kommt die config nicht mehr (mein 1 GB stick und Tobiking's Laptop mit seinem stick)
Der Fund von +gjm+, mein 1 GB stick und der Beweis bei Tobiking's Laptop, das waren wichtige Puzzleteile.
Der Meilenstein wurde erreicht!
Ein gewaltiger Dank gebührt +gjm+. Er begleitet PrettyOS seit den Anfängen in absolut konstruktiver Weise. Ihm gebührt ein Platz in der "Hall of Fame" unserer kleinen OS-Community.