Skip to content

Commit 9d2e19e

Browse files
committed
ALSA: gus: Fix repeated probes of snd_gus_create()
GUS card object may be repeatedly probed for the legacy ISA devices, and the behavior doesn't fit with the devres resource management. Revert partially back to the classical way for the snd_gus_card object, so that the repeated calls of snd_gus_create() are allowed. Fixes: 5b88da3 ("ALSA: gus: Allocate resources with device-managed APIs") Reported-by: kernel test robot <oliver.sang@intel.com> Link: https://lore.kernel.org/r/20210907093930.29009-1-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
1 parent 8491f59 commit 9d2e19e

File tree

1 file changed

+31
-13
lines changed

1 file changed

+31
-13
lines changed

sound/isa/gus/gus_main.c

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,24 @@ static void snd_gus_init_control(struct snd_gus_card *gus)
8787

8888
static int snd_gus_free(struct snd_gus_card *gus)
8989
{
90-
if (gus->gf1.res_port2) {
91-
snd_gf1_stop(gus);
92-
snd_gus_init_dma_irq(gus, 0);
90+
if (gus->gf1.res_port2 == NULL)
91+
goto __hw_end;
92+
snd_gf1_stop(gus);
93+
snd_gus_init_dma_irq(gus, 0);
94+
__hw_end:
95+
release_and_free_resource(gus->gf1.res_port1);
96+
release_and_free_resource(gus->gf1.res_port2);
97+
if (gus->gf1.irq >= 0)
98+
free_irq(gus->gf1.irq, (void *) gus);
99+
if (gus->gf1.dma1 >= 0) {
100+
disable_dma(gus->gf1.dma1);
101+
free_dma(gus->gf1.dma1);
93102
}
103+
if (!gus->equal_dma && gus->gf1.dma2 >= 0) {
104+
disable_dma(gus->gf1.dma2);
105+
free_dma(gus->gf1.dma2);
106+
}
107+
kfree(gus);
94108
return 0;
95109
}
96110

@@ -116,7 +130,7 @@ int snd_gus_create(struct snd_card *card,
116130
};
117131

118132
*rgus = NULL;
119-
gus = devm_kzalloc(card->dev, sizeof(*gus), GFP_KERNEL);
133+
gus = kzalloc(sizeof(*gus), GFP_KERNEL);
120134
if (gus == NULL)
121135
return -ENOMEM;
122136
spin_lock_init(&gus->reg_lock);
@@ -142,33 +156,35 @@ int snd_gus_create(struct snd_card *card,
142156
gus->gf1.reg_timerctrl = GUSP(gus, TIMERCNTRL);
143157
gus->gf1.reg_timerdata = GUSP(gus, TIMERDATA);
144158
/* allocate resources */
145-
gus->gf1.res_port1 = devm_request_region(card->dev, port, 16,
146-
"GUS GF1 (Adlib/SB)");
159+
gus->gf1.res_port1 = request_region(port, 16, "GUS GF1 (Adlib/SB)");
147160
if (!gus->gf1.res_port1) {
148161
snd_printk(KERN_ERR "gus: can't grab SB port 0x%lx\n", port);
162+
snd_gus_free(gus);
149163
return -EBUSY;
150164
}
151-
gus->gf1.res_port2 = devm_request_region(card->dev, port + 0x100, 12,
152-
"GUS GF1 (Synth)");
165+
gus->gf1.res_port2 = request_region(port + 0x100, 12, "GUS GF1 (Synth)");
153166
if (!gus->gf1.res_port2) {
154167
snd_printk(KERN_ERR "gus: can't grab synth port 0x%lx\n", port + 0x100);
168+
snd_gus_free(gus);
155169
return -EBUSY;
156170
}
157-
if (irq >= 0 && devm_request_irq(card->dev, irq, snd_gus_interrupt, 0,
158-
"GUS GF1", (void *) gus)) {
171+
if (irq >= 0 && request_irq(irq, snd_gus_interrupt, 0, "GUS GF1", (void *) gus)) {
159172
snd_printk(KERN_ERR "gus: can't grab irq %d\n", irq);
173+
snd_gus_free(gus);
160174
return -EBUSY;
161175
}
162176
gus->gf1.irq = irq;
163177
card->sync_irq = irq;
164-
if (snd_devm_request_dma(card->dev, dma1, "GUS - 1")) {
178+
if (request_dma(dma1, "GUS - 1")) {
165179
snd_printk(KERN_ERR "gus: can't grab DMA1 %d\n", dma1);
180+
snd_gus_free(gus);
166181
return -EBUSY;
167182
}
168183
gus->gf1.dma1 = dma1;
169184
if (dma2 >= 0 && dma1 != dma2) {
170-
if (snd_devm_request_dma(card->dev, dma2, "GUS - 2")) {
185+
if (request_dma(dma2, "GUS - 2")) {
171186
snd_printk(KERN_ERR "gus: can't grab DMA2 %d\n", dma2);
187+
snd_gus_free(gus);
172188
return -EBUSY;
173189
}
174190
gus->gf1.dma2 = dma2;
@@ -193,8 +209,10 @@ int snd_gus_create(struct snd_card *card,
193209
gus->gf1.volume_ramp = 25;
194210
gus->gf1.smooth_pan = 1;
195211
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, gus, &ops);
196-
if (err < 0)
212+
if (err < 0) {
213+
snd_gus_free(gus);
197214
return err;
215+
}
198216
*rgus = gus;
199217
return 0;
200218
}

0 commit comments

Comments
 (0)