Sourcecode Fortschritt


  • Mod

    Rev. 427:

    - testMSD(deviceAddr) ausgelagert aus ehci.c
    - alte usb-Funktionen nicht mehr gebraucht (auskommentiert, kommen demnächst weg)


  • Mod

    Rev. 428:

    Sicherung vor "Umbau auf qTD umhängen bei stabilen QH"

    Diese Version läuft mit 1GB usb-Stick auf VMWare

    bitte beachten: for(uint32_t sector=1055; sector < 1060; sector++)
    das ist 0x83E00 beginnend, hat bei mir in VMWare geklappt, zumindest ab 0x84000 (zweiter gelesener Sektor)



  • oh, hab ich ausversehen sektor 1055 bis 1060 committed? Das war ja eig. nur für meinen Stick gültig, damit ich mal was sehe...


  • Mod

    Macht doch nix. 🙂

    Erste Versuche des Einhängens von qTDs in QH endeten leider in Host System Error. 🙄
    http://www.henkessoft.de/OS_Dev/Downloads/PrettyOS_rev428umgebaut001.zip <--- bitte check, vielleicht können wir die Vorgehensweise doch noch nutzen.



  • Revision 429:

    - Ring-Strukturen angelegt (für Scheduler-Umbauten voraussichtlich nötig), analog zu list
    - ODA aufgelöst (in Einzelvariablen und system)
    - Alle Userprogramme neu übersetzt (wegen Userlibänderung)
    - Formatierungen
    - Smilie-Bug gefixt.


  • Mod

    Diese Revision 429 funktioniert in VMWare mit einem 1GB stick komplett wie gewünscht: http://www.henkessoft.de/OS_Dev/Bilder/rev429.PNG

    Wir suchen den Weg dies zu verallgemeinern.


  • Mod

    Rev. 430:

    Auslagerungen und Streichungen zur Erhöhung der Lesbarkeit und Wartbarkeit wurden vorgenommen:

    ehciQHqTD.h/c: Queue Head (QH) und Queue Element Transfer Descriptor (qTD)
    usb2_msd.h/c: USB 2.0 Mass Storage Devices (MSD)


  • Mod

    Rev. 431:

    Verbesserungen im Code bei ehci/usb


  • Mod

    Rev. 432:

    Zwischenstand nach Vorbild tatOS
    siehe: http://www.c-plusplus.net/forum/viewtopic-var-t-is-253016-and-start-is-71.html

    testMSD(): Umgebaut auf die dort verwendete Startreihenfolge.


  • Mod

    Rev. 433:

    In VMWare geht 1GB und 16 GB usb-stick, Test-PC zeigt noch qTD-status 0x80 (wird nicht ausgeführt)

    Fehler im Bereich SCSI-Befehle wurden korrigiert (z.B. werden bei read im SCSI cmd nicht byte sondern blocks angegeben).

    Bitte mit Simulationen und PC testen. 🙂

    Dank an den Ersteller von tatOS. Es geht nichts über praktische Vorbilder mit vielen Kommentaren direkt im Code, sollten wir uns selbst ein Beispiel daran nehmen. 👍



  • Ganz nützlich wär vlt. noch ein Link zu Tatos, denn Google rückt damit nur ungern raus, da es gerne nach Tattoos suchen möchte. (mit vielen "-"-Angaben schafft man es schon, aber es ist mühsam)


  • Mod


  • Mod

    Rev. 434:

    bei real PC hängt es im IN-Zweig von usbSendSCSIcmd


  • Mod

    rev. 435: Zwischenstand

    einige verbesserungen, real PC problem aber noch nicht gelöst


  • Mod

    Rev. 436: da +gjm+ auf speicherprobleme tippt, hier eine korrigierte Version mit #define _USB_DIAGNOSIS_ aktiviert.

    Hier der aktuelle Ablauf auf PC mit meinem 1GB stick:

    dev: 3 interface: 0 endpOUT: 2 endpIN: 1
    USB2: usbTransferBulkOnlyMassStorageReset, dev: 3 interface: 0#
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    > SCSI: inquiry
    OUT part#
    IN part transfer>0#
    virtAddrBuf0 C0252000h : 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 C0251000h : 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)<-- status

    Command Block Status Values in "good status"

    > Press key <<<
    > SCSI: test unit ready
    OUT part#
    IN part transfer==0###################
    timeout - no STS_USBINT set!
    virtAddrBuf0 C0257000h : 55h 53h 42h 53h AAh AAh AAh AAh AAh AAh AAh AAh AAh

    qTD Status: 00h OK (no bit set)<-- data
    qTD Status: 80h Active - HC transactions enabled<-- status

    > Press key <<<
    > SCSI: request sense
    OUT part#
    IN part transfer>0###################
    timeout - no STS_USBINT set!
    virtAddrBuf0 C025D000h : 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h
    00h 00h 00h 00h

    virtAddrBuf0 C025C000h : 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<-- status

    > Press key <<<

    Wie man sieht, steigt der Ablauf beim ersten "test unit ready" (der zweite SCSI command nach dem ersten "inquiry") Beim IN-Endpoint mit seinem QH/qTD Essemble aus.

    So sieht dort der Code aus:

    printf("\nIN part");
    
        pOpRegs->ASYNCLISTADDR = paging_get_phys_addr(kernel_pd, QH_In);
    
        // IN qTDs 
        void* QTD_In;
        void* next = createQTD_Handshake(OUT); // Handshake
        if (TransferLength > 0)
        {
            printf(" transfer>0");
            next = StatusQTD = createQTD_MSDStatus((uintptr_t)next, 1); // next, toggle // IN 13 byte
            QTD_In = DataQTD = createQTD_IO((uintptr_t)next, IN,  0, TransferLength); // IN/OUT DATA0, ... byte
        }
        else
        {
            printf(" transfer==0");
            QTD_In = StatusQTD = createQTD_MSDStatus((uintptr_t)next, 0); // next, toggle // IN 13 byte
        }
    
        // IN QH
        createQH(QH_In, paging_get_phys_addr(kernel_pd, QH_In), QTD_In, 1, device, endpointIn, 512); // endpoint IN/OUT for MSD
    
        performAsyncScheduler();
    
        if (TransferLength) // byte
        {
            printf("\n");
            showPacket(DataQTDpage0,TransferLength);
            if ((TransferLength==512) && (TransferLength==36)) // data block, inquiry feedback
            {
                showPacketAlphaNumeric(DataQTDpage0,TransferLength);
            }
        }
    
        printf("\n");
        showPacket(MSDStatusQTDpage0,13);
    
        if( ( (*(((uint32_t*)MSDStatusQTDpage0)+3)) & 0x000000FF ) == 0x0 )
        {
            printf("\nCommand Passed (\"good status\") ");
        }
        if( ( (*(((uint32_t*)MSDStatusQTDpage0)+3)) & 0x000000FF ) == 0x1 )
        {
            printf("\nCommand failed");
        }
        if( ( (*(((uint32_t*)MSDStatusQTDpage0)+3)) & 0x000000FF ) == 0x2 )
        {
            printf("\nPhase Error");
        }
    
        // transfer diagnosis
        showStatusbyteQTD(DataQTD);   printf("<-- data");   // In/Out Data
        showStatusbyteQTD(StatusQTD); printf("<-- status"); // In CSW
    


  • Muss man extra committen, nur um _USB_DIAGNOSIS_ zu aktivieren?


  • Mod

    Das lief leider nicht fehlerfrei. Ich wollte +gjm+ nicht zumuten, die entsprechende Version zumindest lauffähig zu bekommen.

    Den Ausgabe-Bug habe ich noch übersehen, bitte mit ODER-Verknüpfung anstelle UND:

    if ((TransferLength==512) || (TransferLength==36)) // data block, inquiry feedback
    {
        showPacketAlphaNumeric(DataQTDpage0,TransferLength);
    }
    

  • Mod

    Rev. 437:

    ehci/usb:

    - void performAsyncScheduler(bool stop) <--- für control transfers mit stop (sonst laufen die nicht), in usbSendSCSIcmd ohne stop (mit stop wird noch der cmd auf OUT ausgeführt, aber nicht der IN zweig)

    - QHs und qTD werden analysiert

    - zwei QHs (für OUT und IN) im asyncScheduler, die aufeinander zeigen

    Ergebnis:
    a) in VMWare perfekt
    b) real PC:

    ...
    1648000h <-- QH_Out
    IN part
    asyncList: 01649000h <-- QH_In transfer>0#
    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.00

    55h 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

    Command Block Status Values in "good status"

    > Analyze Async List <<<
    asyncList: 01649000h
    USB status: 00008000h
    Asynchronous Schedule Status

    > Press key <<<
    > SCSI: test unit ready
    OUT part
    asyncList: 01649000h <-- QH_Out
    IN part
    asyncList: 0164F000h <-- QH_In transfer==0###################
    timeout - no STS_USBINT set!
    55h 53h 42h 53h AAh AAh AAh AAh AAh AAh AAh AAh AAh

    qTD Status: 80h Active - HC transactions enabled<-- command
    qTD Status: 80h Active - HC transactions enabled<-- status

    > Analyze Async List <<<
    asyncList: 01649000h
    USB status: 00008000h
    Asynchronous Schedule Status

    > Press key <<<


  • Mod

    Rev. 438:
    mit Analyse des Fortgangs des Async. Schedulers

    Den Fortgang im Async. Scheduler sieht man an aS und nextQH.

    Den Fortgang über eine qTD-Kette sieht man hier sehr gut:
    next qTD <--- auszuführender qTD
    curr qTD <--- zuletzt ausgeführter qTD

    hier ist alles ok:

    > SCSI: inquiry
    OUT part
    asyncList: 01663000h <-- QH_Out
    IN part transfer>0
    before aS:
    aS: 01663000h
    nextQH: 01664000h
    curr qTD: 00000000h next qTD: 01665000h

    > Press key <<<#
    after aS:
    aS: 01664000h
    nextQH: 01663000h
    curr qTD: 01667000h next qTD: 00000000h

    > Press key <<<
    00h 80h 02h 02h 1Fh 00h 00h 00h 41h 36h 30h 43h 30h 37h 30h 34h 46h 6Ch 61h 73h
    68h 20h 44h 69h 73h 6Bh 20h 20h 20h 20h 20h 20h 38h 2Eh 30h 37h
    A60C0704Flash Disk 8.07

    55h 53h 42h 53h 12h 42h 42h 42h 00h 00h 00h 00h 00h

    Command Passed ("good status")
    qTD Status: 00h OK (no bit set)<-- command
    qTD Status: 00h OK (no bit set)<-- data
    qTD Status: 00h OK (no bit set)<-- status

    Command Block Status Values in "good status"

    > Analyze Async List <<<
    asyncList (phys): 01664000h DataQTD (phys): 01669000h
    USB status: 00000000h

    hier bleibt er zwischen QH_Out und QH_In stecken:

    > SCSI: read capacity
    OUT part
    asyncList: 01687000h <-- QH_Out
    IN part transfer>0
    before aS:
    aS: 01687000h
    nextQH: 01688000h
    curr qTD: 00000000h next qTD: 01689000h

    > Press key <<<#
    after aS:
    aS: 01687000h
    nextQH: 01688000h
    curr qTD: 01689000h next qTD: 00000000h

    > Press key <<<
    00h 00h 00h 00h 00h 00h 00h 00h

    55h 53h 42h 53h AAh AAh AAh AAh AAh AAh AAh AAh AAh

    qTD Status: 00h OK (no bit set)<-- command
    qTD Status: 80h Active - HC transactions enabled<-- data
    qTD Status: 80h Active - HC transactions enabled<-- status
    Capacity: 0 MB, Last LBA: 0, block size 0

    > Analyze Async List <<<
    asyncList (phys): 01687000h DataQTD (phys): 0168D000h
    USB status: 00002000h
    Reclamation

    Aktuelle Fragestellung:
    Was hemmt auf real PC den Übergang von QH_Out nach QH_In? Konstruktive Ideen zur Klärung dieser Frage werden gerne entgegen genommen. 😉

    Hintergrund:
    Der EHCI speichert in seinem OpRegister ASYNCLISTADDR (Current Asynchronous List Address Register) die physische Adresse des QH, der als letztes verwendet wurde bzw. als nächstes ausgeführt wird (round robin). Steuergrößen beim Ablauf sind das H-Bit im QH und das Reclamation Bit im USB Status-Register.
    Innerhalb des QH zeigt next qTD auf den qTD, der als nächstes ausgeführt wird. Der zuletzt ausgeführte qTD wird in current qTD gespeichert.

    ehci spec 1.0, 4.10.5:

    4.10.5 Follow Queue Head Horizontal Pointer
    The host controller must use the horizontal pointer in the queue head to the next schedule data structure
    when any of the following conditions exist:
    • If the Active bit is a one on exit from the Execute Transaction state, or
    • When the host controller exits the Write Back qTD state, or
    • If the Advance Queue state fails to advance the queue because the target qTD is not active, or
    • If the Halted bit is a one on exit from the Fetch QH state.
    There is no functional requirement that the host controller wait until the current transaction is complete
    before using the horizontal pointer to read the next linked data structure. However, it must wait until the
    current transaction is complete before executing the next data structure.


  • Mod

    Rev. 439:

    Wenn der Übergang von QH1 zu QH2 ein Problem ist, dann trennen wir die beiden eben wieder und lassen sie auf sich selbst zeigen. Diese Version konzentriert sich auf den Ablauf bei den qTD-Ketten und zeigt daher die entsprechenden physischen Speicher der qTD an, damit man mit curr qTD und next qTD beobachten kann, wie weit es läuft.

    In VMWare sehe ich einen perfekten Ablauf, d.h. der Code ist von der Ablauflogik her ok.

    Auf real PC werden die qTD im IN-Zweig entweder vollständig oder teilweise nicht ausgeführt. Trotz der optimalen Beobachtungsmöglichkeit bleibt der Grund noch im Dunkeln. Daher wurde bisher noch kein "Hot Fix" gefunden.


Anmelden zum Antworten