[PATCH] spin[un]locks revision on new cmpci driver (5.64)

Carlos E Gorges (carlos@techlinux.com.br)
Fri, 25 May 2001 21:02:06 -0400


-----BEGIN PGP SIGNED MESSAGE-----
Hash: RIPEMD160

HI all,

Finally I discovered my problem :-)

The following patch fixes SMP hangs w/ cmpci v5.64 ( k244-ac17 ).

- --- linux-244ac/drivers/sound/cmpci.c Fri May 25 05:26:27 2001
+++ linux/drivers/sound/cmpci.c Fri May 25 20:14:49 2001
@@ -1,5 +1,4 @@
/****************************************************************************
*/
- -
/*
* cmpci.c -- C-Media PCI audio driver.
*
@@ -76,6 +75,10 @@
* was calling prog_dmabuf with s->lock held, call missing
* unlock_kernel in cm_midi_release
*
+ * Fri May 25 2001 - Carlos Eduardo Gorges <carlos@techlinux.com.br>
+ * - some drivers cleanups
+ * - spin[un]locks revision ( fix SMP support )
+ *
*/

/****************************************************************************
*/
@@ -226,10 +229,6 @@

#define SND_DEV_DSP16 5

- -#define set_dac1_rate set_adc_rate
- -#define stop_dac1 stop_adc
- -#define get_dmadac1 get_dmaadc
- -
/* --------------------------------------------------------------------- */

struct cm_state {
@@ -342,7 +341,6 @@
/* --------------------------------------------------------------------- */

static struct cm_state *devs;
- -static struct cm_state *devaudio;
static unsigned long wavetable_mem;

/* --------------------------------------------------------------------- */
@@ -577,8 +575,8 @@
{
unsigned long flags;

- - spin_lock_irqsave(&s->lock, flags);
set_spdifout(s, rate);
+ spin_lock_irqsave(&s->lock, flags);
/* enable AC3 */
if (rate == 48000 || rate == 44100) {
// mute DAC
@@ -697,7 +695,7 @@
if (s->curr_channels <= 2)
set_spdifout(s, rate);
if (s->status & DO_DUAL_DAC)
- - set_dac1_rate(s, rate);
+ set_adc_rate(s, rate);
}

/* --------------------------------------------------------------------- */
@@ -759,12 +757,16 @@

extern inline void enable_dac(struct cm_state *s)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&s->lock, flags);
if (!(s->enable & CM_ENABLE_CH1)) {
/* enable channel */
s->enable |= CM_ENABLE_CH1;
outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
}
maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~8, 0);
+ spin_unlock_irqrestore(&s->lock, flags);
if (s->status & DO_DUAL_DAC)
enable_adc(s);
}
@@ -794,7 +796,7 @@
}
spin_unlock_irqrestore(&s->lock, flags);
if (s->status & DO_DUAL_DAC)
- - stop_dac1(s);
+ stop_adc(s);
}

static void start_adc(struct cm_state *s)
@@ -819,7 +821,9 @@
if ((s->dma_adc.mapped || s->dma_adc.count > 0) && s->dma_adc.ready) {
/* enable interrupt */
// maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~0, 1);
- - enable_dac(s);
+ spin_unlock_irqrestore(&s->lock, flags);
+ enable_dac(s);
+ spin_lock_irqsave(&s->lock, flags);
}
spin_unlock_irqrestore(&s->lock, flags);
}
@@ -832,7 +836,9 @@
if ((s->dma_dac.mapped || s->dma_dac.count > 0) && s->dma_dac.ready) {
/* enable interrupt */
maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~0, 2);
+ spin_unlock_irqrestore(&s->lock, flags);
enable_dac(s);
+ spin_lock_irqsave(&s->lock, flags);
}
spin_unlock_irqrestore(&s->lock, flags);
if (s->status & DO_DUAL_DAC)
@@ -848,7 +854,11 @@
spin_lock_irqsave(&s->lock, flags);
if ((channels > 2) && (channels <= s->max_channels)
&& (((s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK) == (CM_CFMT_STEREO |
CM_CFMT_16BIT))) {
+
+ spin_unlock_irqrestore(&s->lock, flags);
set_spdifout(s, 0);
+ spin_lock_irqsave(&s->lock, flags);
+
if (s->capability & CAN_MULTI_CH_HW) {
// NXCHG
maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3, ~0, 0x80);
@@ -880,8 +890,11 @@
fmts |= CM_CFMT_16BIT << CM_CFMT_ADCSHIFT;
fmts |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;
fmts |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
+
+ spin_unlock_irqrestore(&s->lock, flags);
set_fmt(s, fmtm, fmts);
- - set_dac1_rate(s, s->ratedac);
+ set_adc_rate(s, s->ratedac);
+ spin_lock_irqsave(&s->lock, flags);
}
// N4SPK3D, disable 4 speaker mode (analog duplicate)
if (s->speakers > 2)
@@ -925,7 +938,6 @@
db->mapped = db->ready = 0;
}

- -
/* Ch1 is used for playback, Ch0 is used for recording */

static int prog_dmabuf(struct cm_state *s, unsigned rec)
@@ -939,7 +951,6 @@
unsigned char fmt;
unsigned long flags;

- - spin_lock_irqsave(&s->lock, flags);
fmt = s->fmt;
if (rec) {
stop_adc(s);
@@ -948,7 +959,7 @@
stop_dac(s);
fmt >>= CM_CFMT_DACSHIFT;
}
- - spin_unlock_irqrestore(&s->lock, flags);
+
fmt &= CM_CFMT_MASK;
db->hwptr = db->swptr = db->total_bytes = db->count = db->error =
db->endcleared = 0;
if (!db->rawbuf) {
@@ -1212,6 +1223,7 @@
[SOUND_MIXER_CD] = { DSP_MIX_CDVOLIDX_L, DSP_MIX_CDVOLIDX_R,
MT_5MUTE, 0x04, 0x02 },
[SOUND_MIXER_LINE] = { DSP_MIX_LINEVOLIDX_L, DSP_MIX_LINEVOLIDX_R,
MT_5MUTE, 0x10, 0x08 },
[SOUND_MIXER_MIC] = { DSP_MIX_MICVOLIDX, DSP_MIX_MICVOLIDX,
MT_5MUTEMONO, 0x01, 0x01 },
+
[SOUND_MIXER_SYNTH] = { DSP_MIX_FMVOLIDX_L, DSP_MIX_FMVOLIDX_R,
MT_5MUTE, 0x40, 0x00 },
[SOUND_MIXER_VOLUME] = { DSP_MIX_MASTERVOLIDX_L, DSP_MIX_MASTERVOLIDX_R,
MT_5MUTE, 0x00, 0x00 },
[SOUND_MIXER_PCM] = { DSP_MIX_VOICEVOLIDX_L, DSP_MIX_VOICEVOLIDX_R,
MT_5MUTE, 0x00, 0x00 }
@@ -2546,7 +2558,11 @@
init_timer(&s->midi.timer);
s->midi.timer.expires = jiffies+1;
s->midi.timer.data = (unsigned long)s;
+
+ spin_unlock_irqrestore(&s->lock, flags);
s->midi.timer.function = cm_midi_timer;
+ spin_lock_irqsave(&s->lock, flags);
+
add_timer(&s->midi.timer);
}
if (file->f_mode & FMODE_READ) {
- --
_________________________
Carlos E Gorges
(carlos@techlinux.com.br)
Tech informática LTDA
Brazil
_________________________

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.5 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iQIXAwUBOw8AkhfQA3nqPEsZFAO5+wgAx8Dkg/n3OAFF0Hp5pBmwe8rIoOMXo+sH
HZfMdeNUHMXCGy+MZhdufzj6CpVs8pgYILZqXS/cWsn2a+nAJFvBTECL70IdPUFE
bQCyDWhsaOK8jLdQEq/xOChDy4rww72XcupCWLF8KC9o3hZSxZGgDyOdltbk+//l
3sqThWQusoAkjTZjWfhpf3t5k54p3GNH2wKG5RXxLaI+r9Ef8YlYk8UGDlEhrbCW
S5SWkTShrS3iighe6I05XAJsBN5x6BSOAIODH+/tPOSXsJcR7gVmyzvKoPbLXeeT
auvnExxfeFQ7jyT08smeCXh11OxJUe1aRlAkAqcIIIgiCzLgGvt+Gwf/QzYycCuo
nmU2t81OvP95N0u8mbJwDNWxVCtWen4glir2VUfLc2GH83n3+LCEMmtKpZOviIfs
A6oON9l2uO2CfACTH/tW6PaCzEz1sZ5yZ79d1Rdf3d5qbZfAVgQFLF+Oqfthvbbe
8xj1i94rkLM/TZw/vbmLTK+DCzXI3GrXE+RI2kDa8I4hYbt6WksorABamjVKGR9v
imyMkmGyScvVtO6PM1zKbfGiOaC6GFuUjTPNNP4/CaVg66z4/3WIGfVNJkj0Ppn2
r9qdq6V39hs4xsP+gQfFsZka46/RnpGg431ZjwxmOxWnOdgerenRRpd/Wpp+PQx+
1Esxgt7dNTeWJw==
=vypo
-----END PGP SIGNATURE-----
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/