[RoLUG] Modifica device driver

ben benhamal76@yahoo.it
Sab 14 Giu 2003 00:39:00 CEST


On Fri, 13 Jun 2003 10:30:59 +0200
ciarez <ciarez@inwind.it> wrote:

ciao cristiaaaaaaaaaaaaaaan ...
lo sapete vero che cristian sampei si è laureato ? ;-)

>moduli videodev (penso sia l'implementazione dei v4l)

zi zi :-)

> Ho poi utilizzato vidcat per catturare una immagine su disco.
> Da PC funziona perfettamente.
> Sul PDA, vidcat rimane in attesa e finchè non si preme ctrl-c non esce e non fa
> nulla: rimane li.

/usr/src/Documentation/usb/ov511.txt

non so se ahi già provato a fare il loading del modulo con questa opzione 
che pare cadere a fagiuolo :-) 

NAME: printph
  TYPE: integer (Boolean)
  DEFAULT: 0
  DESC: Setting this to 1 will dump the first 12 bytes of each isoc frame. This
        is only useful if you are trying to debug problems with the isoc data
        stream (i.e.: camera initializes, but vidcat hangs until Ctrl-C). Be
        warned that this dumps a large number of messages to your kernel log

potresti provare a fare un confronto tra i log su pc e su pda per vedere che 
cosa non va.
Hai provato a vedere se esiste una entry in /proc/video/ov511/ ?
Così dovresti essere sicuro che la telecamera sia inizializzata ... credo ...
Ho scoperto che questo problema è abbastanza diffuso anche con altri tipi 
di telecamere usb , non basate su chipset OmniVideo . 


> Debuggando il modulo ov511 versione 1.48a (il kernel è un 2.4.18 patchato x
> arm), ho scoperto che si blocca alla riga 5160:
> interruptible_sleep_on(&ov511->wq);

qui "vado a palpetto" ... spero che Voi mi corrigerete :-)
in ov511.h trovi la struct usb_ov511 
una delle voci è 

wait_queue_head_t wq;   /* Processes waiting */

quindi sei davanti ad una wait queue , un meccanismo del kernel
per mettere un processo in attesa quando le sue richieste
non possono venire soddisfatte.
Il fatto che sia usata la chiamata interruptible_sleep_on
mi fa pensare che che la richiesta venga accodata ad una 
coda già esistente.Inoltre ogni volta che vedi la variante 
 interruptible dovresti poi vedere una riga del tipo 
if (signal_pending(current)) return -EINTR
che dovrebbe essere quello che ti permette di capire 
l' interruzzione con gdbserver.
E' possibile che tra l' if precedente

if ((ov511->frame[vm.frame].width != vm.width) ||
                    (ov511->frame[vm.frame].height != vm.height) ||
                    (ov511->frame[vm.frame].format != vm.format) ||
                    (ov511->frame[vm.frame].sub_flag != ov511->sub_flag) ||
                    (ov511->frame[vm.frame].depth != depth)) {


e interruptible_sleep_on ci sia una race condition , cioè che il valore
di una delle variabili cambi subito dopo che il test ha avuto successo
e prima della sleep.Proprio perchè questa situazione è nota come causa del lockup
dei driver ( vedi pagina 287 di linux device drivers ) è preferibile utilizzare
in luogo di sleep_on   la funzione : 
int wait_event_interruptible(wait_head_queue_t wq, int condition ) ....
però mi piacerebbe vedere che casino succede togliendo tutti stì punti
esclamativi :-)
ciao 
Luca  



Maggiori informazioni sulla lista RoLUG