ZitatOriginal von UFO
Ich hab's ausprobiert:
Der "wait for registers to be programmed"-Teil darf auf keinen Fall entfernt werden.
Wie man sieht, ist der Code ziemlich feuergefährlich.
Dann ist aber was anders auch noch faul. Das UPLD_DEBI-Bit kann nur 0 sein, wenn in eines der DEBI-Register geschrieben wurde und kein neuer Upload erfolgt ist. Außer während der Initialisierung (+Reinitialisierung nach ARM-Crash), erfolgt der Zugriff auf die DEBI-Register nur innerhalb des DEBI-Locks. Während der Initialisierung greift nur ein Thread auf die Register zu. Es darf daher keine Situation geben, bei der man auf den Upload warten muß.
Zitat
Ich möchte auf keinen Fall irgendwelche Regressions in den Treiber einbauen.
Deswegen habe ich die Funktion ja nach av7110_xx ausgelagert.
Zitat
Daher schlage ich vor, den Code in saa7146_core nur so weit zu korrigieren, daß der busyloop-Timeout auch mit gesperrten Interrupts funktioniert. Die Timeouts sind zwar relativ hoch, aber damit sind wir auf der sicheren Seite.
Ich würde der Funktion schon in irgendeiner Form ein Timeout übergeben wollen. Bei gesperrten Interrupts sollte die Wartezeit eigentlich < 50µs sein. 250ms sind da indiskutabel.
Man sollte auch darüber nachdenken, wie man den DEBI-Zugriff außerhalb der Interrupt-Routinen regelt. Man kann da immer kurz nach einem DMA-Start treffen. Dann muß man im schlechtesten Fall ca. 650µs bei gesperrten Interrupts warten. Für die Funktionen wdebi()/rdebi() sollte es einen zusätzlichen Mutex zum Verriegeln und eine Wait-Queue geben. Außerdem sollte start_debi_dma() ein Flag in den Device-Daten setzen, das einen aktiven DMA-Transfer markiert. wdebi()/rdebi() prüft dann innerhalb des DEBI-Spinlocks auf einen aktiven DMA-Transfer. Ist der vorhanden, werden die Daten für den DEBI-Request in den Device-Daten abgelegt und es wird über eine Wait-Queue auf die Abarbeitung des Requests gewartet. Die Abarbeitung erfolgt dann in debiirq(). debiirq() führt gegebenenfalls einen zusätzlichen Request aus, weckt den wartenden Thread auf und setzt das DMA-Flag zurück. Gleichzeitige Zugriffe von rdebi()/wdebi() werden durch den zusätzlichen Mutex verhindert. Möglicherweise kann man hierfür auch den dcom-Lock mitbenutzen.
Gruß
e9hack