On Sun, Nov 01, 2009 at 12:47:38PM +0100, Krzysztof Helt wrote: > From: Krzysztof Helt <krzysztof.h1@xxxxx> > > The cs4236 was two step detection with call to the snd_wss_free() > between two steps. The snd_wss_free() did not free a sound device > created in the snd_wss_create(). This caused an OOPS during module > removal as the same sound device was released twice. The same OOPS > happened if the cs4236 module loading failed. > > Fix this by adapting the snd_cs4236_create() to correctly work with > chips less capable then cs4236. The snd_cs4236_create() behaves the > same as the snd_wss_create() if the chip is less capable than the cs4236. > > Signed-off-by: Krzysztof Helt <krzysztof.h1@xxxxx> > --- <snip> > @@ -281,83 +285,88 @@ int snd_cs4236_create(struct snd_card *card, > *rchip = NULL; > if (hardware == WSS_HW_DETECT) > hardware = WSS_HW_DETECT3; > - if (cport < 0x100) { > - snd_printk(KERN_ERR "please, specify control port " > - "for CS4236+ chips\n"); > - return -ENODEV; > - } > + > err = snd_wss_create(card, port, cport, > irq, dma1, dma2, hardware, hwshare, &chip); > if (err < 0) > return err; > > - if (!(chip->hardware & WSS_HW_CS4236B_MASK)) { > - snd_printk(KERN_ERR "CS4236+: MODE3 and extended registers " > - "not available, hardware=0x%x\n", chip->hardware); > - snd_device_free(card, chip); > - return -ENODEV; > - } > + if (chip->hardware & WSS_HW_CS4236B_MASK) { > #if 0 > - { > - int idx; > - for (idx = 0; idx < 8; idx++) > - snd_printk(KERN_DEBUG "CD%i = 0x%x\n", > - idx, inb(chip->cport + idx)); > - for (idx = 0; idx < 9; idx++) > - snd_printk(KERN_DEBUG "C%i = 0x%x\n", > - idx, snd_cs4236_ctrl_in(chip, idx)); > - } > + { > + int idx; > + for (idx = 0; idx < 8; idx++) > + snd_printk(KERN_DEBUG "CD%i = 0x%x\n", > + idx, inb(chip->cport + idx)); > + for (idx = 0; idx < 9; idx++) > + snd_printk(KERN_DEBUG "C%i = 0x%x\n", > + idx, snd_cs4236_ctrl_in(chip, idx)); > + } > #endif > - ver1 = snd_cs4236_ctrl_in(chip, 1); > - ver2 = snd_cs4236_ext_in(chip, CS4236_VERSION); > - snd_printdd("CS4236: [0x%lx] C1 (version) = 0x%x, ext = 0x%x\n", cport, ver1, ver2); > - if (ver1 != ver2) { > - snd_printk(KERN_ERR "CS4236+ chip detected, but " > - "control port 0x%lx is not valid\n", cport); > - snd_device_free(card, chip); > - return -ENODEV; > - } > - snd_cs4236_ctrl_out(chip, 0, 0x00); > - snd_cs4236_ctrl_out(chip, 2, 0xff); > - snd_cs4236_ctrl_out(chip, 3, 0x00); > - snd_cs4236_ctrl_out(chip, 4, 0x80); > - snd_cs4236_ctrl_out(chip, 5, ((IEC958_AES1_CON_PCM_CODER & 3) << 6) | IEC958_AES0_CON_EMPHASIS_NONE); > - snd_cs4236_ctrl_out(chip, 6, IEC958_AES1_CON_PCM_CODER >> 2); > - snd_cs4236_ctrl_out(chip, 7, 0x00); > - /* 0x8c for C8 is valid for Turtle Beach Malibu - the IEC-958 output */ > - /* is working with this setup, other hardware should have */ > - /* different signal paths and this value should be selectable */ > - /* in the future */ > - snd_cs4236_ctrl_out(chip, 8, 0x8c); > - chip->rate_constraint = snd_cs4236_xrate; > - chip->set_playback_format = snd_cs4236_playback_format; > - chip->set_capture_format = snd_cs4236_capture_format; > + if (cport < 0x100 || cport == SNDRV_AUTO_PORT) { > + snd_printk(KERN_ERR "please, specify control port " > + "for CS4236+ chips\n"); Missing a call to snd_device_free() here. > + return -ENODEV; > + } -- Ville Syrjälä syrjala@xxxxxx http://www.sci.fi/~syrjala/ _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel