lkml.org 
[lkml]   [2004]   [May]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH] Re: Segmentation fault in i810_audio.c:__i810_update_lvi
    On Tue, May 11, 2004 at 12:27:28AM -0700, Andrew Morton wrote:
    > Gary Wong <gtw@cs.bu.edu> wrote:
    > > I believe that one of two fixes should be applied: either the
    > > SNDCTL_DSP_SETTRIGGER ioctl handling should not enable the
    > > PCM_ENABLE_{IN,OUT}PUT bits unless file->f_mode is compatible,
    > > or i810_release() should ignore the PCM_ENABLE_* bits without
    > > the corresponding FMODE_*.
    >
    > The first option sounds more appropriate but I wonder if it could break
    > existing applications? Probably not, if it oopses.

    I agree; I had a look at a few other drivers at random (audio, esssolo1,
    trident) and they all silently ignore inappropriate PCM_ENABLE_* bits.

    > Let's try option #1, please.

    OK, a patch is attached. It seems to fix the problem on a 2.6.3 system
    with Herbert Xu's patches from Jeff Garzik applied.

    break-i810.c is a small test case which hopefully demonstrates the
    problem.

    Cheers,
    Gary.
    --
    Gary Wong gtw@cs.bu.edu http://cs-people.bu.edu/gtw/
    --- i810_audio.c.herbert 2004-05-11 12:36:05.674715334 -0400
    +++ i810_audio.c 2004-05-11 12:41:50.101624990 -0400
    @@ -2186,6 +2186,10 @@
    #if defined(DEBUG) || defined(DEBUG_MMAP)
    printk("SNDCTL_DSP_SETTRIGGER 0x%x\n", val);
    #endif
    + if (!(file->f_mode & FMODE_READ ))
    + val &= ~PCM_ENABLE_INPUT;
    + if (!(file->f_mode & FMODE_WRITE ))
    + val &= ~PCM_ENABLE_OUTPUT;
    if((file->f_mode & FMODE_READ) && !(val & PCM_ENABLE_INPUT) && dmabuf->enable == ADC_RUNNING) {
    stop_adc(state);
    }
    @@ -2193,7 +2197,7 @@
    stop_dac(state);
    }
    dmabuf->trigger = val;
    - if((file->f_mode & FMODE_WRITE) && (val & PCM_ENABLE_OUTPUT) && !(dmabuf->enable & DAC_RUNNING)) {
    + if((val & PCM_ENABLE_OUTPUT) && !(dmabuf->enable & DAC_RUNNING)) {
    if (!dmabuf->write_channel) {
    dmabuf->ready = 0;
    dmabuf->write_channel = state->card->alloc_pcm_channel(state->card);
    @@ -2214,7 +2218,7 @@
    i810_update_lvi(state, 0);
    start_dac(state);
    }
    - if((file->f_mode & FMODE_READ) && (val & PCM_ENABLE_INPUT) && !(dmabuf->enable & ADC_RUNNING)) {
    + if((val & PCM_ENABLE_INPUT) && !(dmabuf->enable & ADC_RUNNING)) {
    if (!dmabuf->read_channel) {
    dmabuf->ready = 0;
    dmabuf->read_channel = state->card->alloc_rec_pcm_channel(state->card);#include <fcntl.h>
    #include <sys/ioctl.h>
    #include <sys/soundcard.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>

    extern int main( void ) {

    #define DSP "/dev/dsp"

    int f = open( DSP, O_RDONLY );
    int i, n;
    fd_set fds;

    if( f < 0 ) {
    perror( DSP );

    return EXIT_FAILURE;
    }

    n = 0;
    if( ioctl( f, SNDCTL_DSP_SETTRIGGER, &n ) < 0 ) {
    perror( "SNDCTL_DSP_SETTRIGGER" );

    return EXIT_FAILURE;
    }

    n = PCM_ENABLE_INPUT | PCM_ENABLE_OUTPUT;
    if( ioctl( f, SNDCTL_DSP_SETTRIGGER, &n ) < 0 ) {
    perror( "SNDCTL_DSP_SETTRIGGER" );

    return EXIT_FAILURE;
    }

    for( i = 0; i < 10; i++ ) {
    char a[ 1024 ];

    FD_ZERO( &fds );
    FD_SET( f, &fds );

    if( select( f + 1, &fds, NULL, NULL, NULL ) < 0 )
    perror( "select" );

    if( read( f, a, 1024 ) < 0 )
    perror( "read" );
    }

    close( f );

    return EXIT_SUCCESS;
    }
    \
     
     \ /
      Last update: 2005-03-22 14:03    [W:0.046 / U:32.848 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site