Ziel: USB-Treiber


  • Mod

    In http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/io/usb/scsa2usb/usb_ms_bulkonly.c findet man folgende Handlungsanweisung:

    /*
     * scsa2usb_bulk_only_transport:
     *	Implements the BO state machine by these steps:
     *	a) Issues CBW to a Bulk Only device.
     *	b) Start Data Phase if applicable
     *	c) Start Status Phase
     *
     *	returns TRAN_* values
     *
     * scsa2usb_bulk_only_state_machine:
     *
     * scsa2usb_bulk_only_transport() handles the normal transitions or
     * continuation after clearing stalls or error recovery.
     *
     * Command Phase:
     *	prepare a valid CBW and transport it on bulk-out pipe
     *	if error on bulkout:
     *		set pkt_reason to CMD_TRAN_ERR
     *		new pkt state is SCSA2USB_PKT_DO_COMP
     *		reset recovery synchronously
     *	else
     *		proceed to data phase
     *
     * Data Phase:
     *	if data in:
     *		setup data in on bulkin
     *	else if data out:
     *		setup data out on bulkout
     *
     *	data: (in)
     *		copy data transferred so far, no more data to transfer
     *
     *		if stall on bulkin pipe
     *			terminate data transfers, set cmd_done
     *			clear stall on bulkin syncrhonously
     *		else if other exception
     *			set pkt_reason to CMD_TRAN_ERR
     *			new pkt state is SCSA2USB_PKT_DO_COMP
     *			reset recovery syncrhonously
     *		else (no error)
     *			receive status
     *
     *	 data: (out)
     *		if stall on bulkout pipe
     *			terminate data transfers, set cmd_done
     *			clear stall on bulkout synchronously USBA
     *		else if other exception
     *			set pkt_reason to CMD_TRAN_ERR
     *			new pkt state is SCSA2USB_PKT_DO_COMP
     *			reset recovery synchronously
     *		else (no error)
     *			receive status
     *
     * Status Phase:
     *
     *	if stall (first attempt)
     *		new pkt state is SCSA2USB_PKT_PROCESS_CSW
     *		setup receiving status on bulkin
     *		if stall (second attempt)
     *			new pkt state is SCSA2USB_PKT_DO_COMP
     *			reset recovery synchronously, we are hosed.
     *		else
     *			goto check CSW
     *	else
     *		goto check CSW
     *
     * check CSW:
     *	- check length equals 13, signature, and matching tag
     *	- check status is less than or equal to 2
     *	- check residue is less than or equal to data length
     *		adjust residue based on if we got valid data
     *
     *	if not OK
     *		new pkt state is SCSA2USB_PKT_DO_COMP
     *		set pkt reason CMD_TRAN_ERR
     *		reset recovery synchronously, we are hosed
     *	else if phase error
     *		new pkt state is SCSA2USB_PKT_DO_COMP
     *		set pkt reason CMD_TRAN_ERR
     *		reset recovery synchronously
     *	else if (status < 2)
     *		if status is equal to 1
     *			set check condition
     *		if residue
     *			calculate residue from data xferred and DataResidue
     *
     *			set pkt_residue
     *		goto  SCSA2USB_PKT_DO_COMP
     *
     * The reset recovery walks sequentially thru device reset, clearing
     * stalls and pipe resets. When the reset recovery completes we return
     * to the taskq thread.
     *
     * Clearing stalls clears the stall condition, resets the pipe, and
     * then returns to the transport.
     */
    

    Hinweis: "we are hosed" ---> http://forum.wordreference.com/showthread.php?t=1115999

    Dieses schrittweise Vorgehen beim bulk-only-Transfer - vor allem mit der entsprechenden Fehlerbehandlung - fehlt uns noch, wird nun step-by-step umgesetzt.

    Ab Rev. 460 wurde eine Struktur hinzugefügt, mit der man bulk Transfers bezüglich command-, data, status-Phase verfolgen kann, um auf Fehler angemessen zu reagieren und den erfolgreichen Verlauf festhalten zu können.



  • Hier die Ergebnisse meines Tests:

    makefilexxx: Gefunden, korrekt gelesen. Fat32-Bugfix funktioniert also. Gute Arbeit 🙂
    makefile: Nicht gefunden. Er vergleicht Zeichen, korrekt bei den ersten 8. Dann glaubt er jedoch ein O oder eine 0 (nicht genau erkennbar) aus der FAT gelesen zu haben. Laut HxD steht dort Space, also 0x20. Vermutetes Problem: ToLower verunstaltet Space.

    EDIT: Nein, weitere Tests haben ergeben: ToLower ist unschuldig. Der Wert des kreisförmigen Zeichen ist 0x42. Dieser Wert steht bereits in foDest->name[i], ist m.E. falsch und er entsteht nicht erst bei der folgenden Umwandlung.


  • Mod

    0x42 entspricht in ASCII dem Zeichen 'B'. Ich werde versuchen, diesen Eintrag von Anfang an auf 11 Spaces zu setzen.



  • ein B?
    Warum zeigt er dann ein kreisförmiges Zeichen (0, O) an?


  • Mod

    ich habe noch nicht heraus gefunden, wo dieses 'B' im Code herrührt. 😕


  • Mod

    Falls jemand mit in ehci/usb/usb_msd/fat einsteigen will, stelle ich hier den Ablauf, der devices betrifft (Stand: Rev. 475), im Funktionenablauf dar:

    PrettyOS startet nach dem Bootloader stage 1 und 2 in ckernel.c mit dem eigentlichen kernel:

    Dort startet Strang 1, der die Floppy-Disk und den EHCI (und daran direkt anhängende devices) aktiviert:
    
    EHCI_flag // first EHCI found?
    
    floppy // floppy installieren
    
    pci // EHCI (für usb2-highspeed-Geräte, RTL8139 installieren, ...)
    
    RAM disk // shell starten; weitere files, die man dort einspielen kann, sind bisher ungenutzt
    
    kernel idle loop // handleEvents() als Drehscheibe für ehci_init, ehci_portcheck, mt_screenshot (momentan screenshot auf Floppy schreiben)
    
    ehci_install
    --> addEvent(&EHCI_INIT)
    --> analyzeEHCI
    
    ehci_init (thread)
    --> startEHCI
       --> initEHCIHostController
          --> startHostController
              --> resetHostController
              --> DeactivateLegacySupport           
          --> enablePorts
              --> resetPort
              --> setupUSBDevice(portnumber)
    
    Strang 2 startet durch Einstecken eines Highspeed usb-Device an einem direkten usb-Port (also nicht Hub):
    
    Interrupt durch Port Change (STS_PORT_CHANGE)
    --> ehci_handler
        --> addEvent(&EHCI_PORTCHECK)
    
    --> ehci_portcheck (thread)
        --> portCheck
            --> showPORTC
                --> resetPort
                --> checkPortLineStatus
                    --> setupUSBDevice(portnumber) s.u.
    
    In setupUSBDevice(portnumber) werden folgende Abläufe angestoßen:
    --> usbTransferEnumerate (liefert devAddr)
    --> usbTransferDevice(devAddr)
    --> usbTransferConfig(devAddr) (interfaces, endpoints)
    --> usbTransferString(devAddr) (language)
    --> usbTransferStringUnicode(devAddr,k) (vendor, product,revision)
    --> usbTransferSetConfiguration(devAddr,1)
    --> usbTransferGetConfiguration(devAddr) 
    --> testMSD(devAddr,config)
    

  • Mod

    Ab und zu gibt es sogar Anerkennung von dritter Seite:

    "i downloaded your OS and had a look through your code. Good Work!"

    Quelle: http://forum.osdev.org/viewtopic.php?f=1&t=22095
    Hier zahlt es sich auch aus, dass wir die Kommentare konsequent in englischer Sprache verfassen.


  • Mod

    Hier eine Übersicht über die Strukuren bezüglich usb-devices, usb-msd und device manager in ehci/usb-Modulen:

    ehci.c:

    port_t  port[17]; // device manager
    
    // usb devices list
    extern usb2_Device_t usbDevices[17]; // ports 1-16 // 0 not used
    
    // Device Manager
    disk_t      usbDev[17];
    partition_t usbDevVolume[17];
    

    usb2.c:

    usb2_Device_t usbDevices[17]; // ports 1-16 // 0 not used
    

    usb2_msd.c:

    extern usb2_Device_t usbDevices[17]; // ports 1-16 // 0 not used
    

    usb2.h:

    typedef struct usb2_Device
    {
        uint16_t usbSpec;
        uint8_t  usbClass;
        uint8_t  usbSubclass;
        uint8_t  usbProtocol;
        uint8_t  maxPacketSize;
        uint16_t vendor;
        uint16_t product;
        uint16_t releaseNumber;
        uint8_t  manufacturerStringID;
        uint8_t  productStringID;
        uint8_t  serNumberStringID;
        uint8_t  numConfigurations;
        uint8_t  maxLUN;
    
        // MSD specific
        char     productName[16];
        char     serialNumber[13];
        uint8_t  numInterfaceMSD;
        uint8_t  InterfaceClass;
        uint8_t  InterfaceSubclass;
        uint8_t  numEndpointInMSD;
        uint8_t  numEndpointOutMSD;
        bool     ToggleEndpointInMSD;
        bool     ToggleEndpointOutMSD;
    } usb2_Device_t;
    

    -------------------------------------------------------

    Kritik von MrX (im IRC):

    a) Es liegt auf dem Stack
    b) Es unterstützt nur 1 Partition pro Stick
    c) Zusammenhängende Daten werden auseinandergerissen

    Vorschlag zur Veränderung (MrX):

    struct usb2msd_t
    {
    /*usb-spezifische Member*/
    disk_t disk; //disk.data = this;
    Partitionen liegen ja in disk.
    Port sollte bei EHCI bleiben, das ist klar 😉
    letztlich hast Du dann statt der derzeit 4? Arrays nur noch 2, eines für ports und eines von usb2msd_t


  • Mod

    usbWrite ist im EHCI/USB-Transferbereich noch nicht "hübsch" implementiert, aber es funktioniert. 🙂 (siehe Rev. 547)



  • Bin neulich auf folgende interessante Liste gestossen: http://www2.one-eyed-alien.net/~mdharm/linux-usb/target_offenses.txt
    Nur zur Info 🙂


  • Mod

    Tobiking hat im irc-chat an folgendes thema erinnert: http://www.lvr.com/forum/index.php?topic=48.0 Vielleicht hat jemand eine idee, wie man da weiter kommen könnte


Anmelden zum Antworten