Ziel: USB-Treiber


  • Mod

    Diese für USB Mass Storage Devices interessante WebPage von Jan Axelson dokumentiere ich hier, bevor sie verschwindet:

    http://www.lvr.com/device_errors.htm

    USB Mass Storage Device Problems

    These are reported problems with various USB mass-storage devices. If you're developing device firmware, check this list for common problems to avoid. If you're developing host software, check this list for problems you may need to work around. Thanks to the Usb-storage e-mail list for many of these. Additions, corrections, and suggestions welcome via

    Descriptor Problems

    The device’s bInterfaceSubClass is FFh instead of 06h or another value defined by the USB mass-storage specifications.

    The device’s bInterfaceProtocol is invalid (should be 50h for bulk-only transport).

    The device has no serial number or the serial number has invalid characters as defined in the bulk-only transport specification.

    Multiple devices with the same Vendor ID and Product ID have the same serial number.

    Different device or firmware revisions have the same bcdDevice value.

    Control Transfer Problems

    A device with multiple LUNs doesn’t implement the Get Max LUN request.

    When the endpoint isn’t halted, receiving a Clear Feature (ENDPOINT_HALT) request for the endpoint causes the device to crash.

    On receiving a Clear Feature (ENDPOINT_HALT) request followed by a Get Status (ENDPOINT) request, the device crashes.

    The device doesn’t implement the Bulk-only Mass Storage Reset request properly. To work around this failure, a host might need to issue a Set Port Feature (PORT_RESET) request to the device’s hub port.

    On receiving a Set Interface request, the device doesn’t reset the data toggles for the bulk endpoints.

    General Problems with Commands

    The device has a single LUN but responds to commands for any LUN.

    The signature in the CSW is incorrect.

    The device returns no data or incorrect data in the dCSWDataResidue field.

    The data-transport phase fails unless there is a delay of up to 120 msecs. between the end of the command-transport phase and the beginning of the data-transport phase.

    After completing enumeration, the device requires a few seconds before it responds properly to received CBWs.

    In commands where the device may return variable-length data in the data-transport phase, after returning all available data but less than the requested amount of data, the device returns 01h (failed) in the bCSWStatus field of the CSW.

    The device can only do transfers of 32 KB, or can only do transfers of 32 KB or less, or returns invalid dCSWDataResidue data in the CSW for transfers greater than 32 KB.

    Problems with Specific SCSI Commands

    Specific commands challenge some devices.

    INQUIRY

    The device crashes if the ALLOCATION LENGTH parameter doesn’t equal 36.

    The device returns an incorrect value in the VERSION field (byte 2). See the SPC specification or other relevant command-set documents for the correct values for your device.

    The device returns 05h (SPC-3) in the VERSION field but the device doesn’t support the REPORT LUNS command (mandatory for SPC-3).

    The device returns an incorrect value in the ADDITIONAL LENGTH parameter.

    When a UNIT ATTENTION condition exists, the device fails the command and returns a sense key of UNIT ATTENTION. (The device should perform the command and should not report or clear the UNIT ATTENTION condition.)

    MODE SENSE

    The device crashes if the ALLOCATION LENGTH parameter doesn’t equal 192.

    When the PAGE CODE parameter equals 3Fh (Return all subpage 00h mode pages in page_0 format), the device crashes.

    The device doesn’t implement all mode pages required by relevant specifications.

    The device doesn’t implement all mandatory versions of the command. Read/write devices that are bootable and that don’t have a PDT of 05h (CD/DVD drive) must support MODE SENSE(10).

    PREVENT ALLOW MEDIUM REMOVAL

    On receiving the command, the device stops functioning or behaves as if the storage media is removed even if it isn’t.

    READ

    The device doesn’t implement all mandatory versions of the command. Devices that comply with SBC-2 or SBC-3 should implement both READ(6) and READ(10).

    READ CAPACITY

    The LOGICAL BLOCK ADDRESS field contains an incorrect value (the correct value + 1) because the device is reporting the number of sectors rather than the LBA of the highest sector.

    REQUEST SENSE

    In devices with removable media, when the media changes, the device doesn’t set the SENSE KEY to 06h (UNIT ATTENTION) to indicate the change (required by SBC-2 and SBC-3).

    START STOP UNIT

    On receiving the command, the device crashes.

    WRITE

    The device doesn’t implement all mandatory versions of the command. Writable devices that comply with SBC-2 or SBC-3 should implement both WRITE(6) and WRITE(10).

    siehe auch: http://www2.one-eyed-alien.net/~mdharm/linux-usb/target_offenses.txt


  • 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