[PATCH v2 39/79] ALSA: korg1212: Allocate resources with device-managed APIs
Takashi Iwai
tiwai at suse.de
Wed Jul 21 00:28:01 CEST 2021
On Tue, 20 Jul 2021 21:41:51 +0200,
Nathan Chancellor wrote:
>
> On Thu, Jul 15, 2021 at 09:59:01AM +0200, Takashi Iwai wrote:
> > This patch converts the resource management in PCI korg1212 driver
> > with devres as a clean up. Each manual resource management is
> > converted with the corresponding devres helper, the page allocations
> > are done with the devres helper, and the card object release is
> > managed now via card->private_free instead of a lowlevel snd_device.
> >
> > This should give no user-visible functional changes.
> >
> > Signed-off-by: Takashi Iwai <tiwai at suse.de>
> > ---
> > sound/pci/korg1212/korg1212.c | 211 +++++++++-------------------------
> > 1 file changed, 55 insertions(+), 156 deletions(-)
> >
> > diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
> > index 030e01b062e4..7872abbd4587 100644
> > --- a/sound/pci/korg1212/korg1212.c
> > +++ b/sound/pci/korg1212/korg1212.c
> > @@ -320,10 +320,10 @@ struct snd_korg1212 {
> > unsigned long inIRQ;
> > void __iomem *iobase;
> >
> > - struct snd_dma_buffer dma_dsp;
> > - struct snd_dma_buffer dma_play;
> > - struct snd_dma_buffer dma_rec;
> > - struct snd_dma_buffer dma_shared;
> > + struct snd_dma_buffer *dma_dsp;
> > + struct snd_dma_buffer *dma_play;
> > + struct snd_dma_buffer *dma_rec;
> > + struct snd_dma_buffer *dma_shared;
> >
> > u32 DataBufsSize;
> >
> > @@ -1200,8 +1200,8 @@ static int snd_korg1212_downloadDSPCode(struct snd_korg1212 *korg1212)
> > snd_korg1212_setCardState(korg1212, K1212_STATE_DSP_IN_PROCESS);
> >
> > rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_StartDSPDownload,
> > - UpperWordSwap(korg1212->dma_dsp.addr),
> > - 0, 0, 0);
> > + UpperWordSwap(korg1212->dma_dsp->addr),
> > + 0, 0, 0);
> > if (rc)
> > K1212_DEBUG_PRINTK("K1212_DEBUG: Start DSP Download RC = %d [%s]\n",
> > rc, stateName[korg1212->cardState]);
> > @@ -1382,7 +1382,7 @@ static int snd_korg1212_playback_open(struct snd_pcm_substream *substream)
> > snd_korg1212_OpenCard(korg1212);
> >
> > runtime->hw = snd_korg1212_playback_info;
> > - snd_pcm_set_runtime_buffer(substream, &korg1212->dma_play);
> > + snd_pcm_set_runtime_buffer(substream, korg1212->dma_play);
> >
> > spin_lock_irqsave(&korg1212->lock, flags);
> >
> > @@ -1413,7 +1413,7 @@ static int snd_korg1212_capture_open(struct snd_pcm_substream *substream)
> > snd_korg1212_OpenCard(korg1212);
> >
> > runtime->hw = snd_korg1212_capture_info;
> > - snd_pcm_set_runtime_buffer(substream, &korg1212->dma_rec);
> > + snd_pcm_set_runtime_buffer(substream, korg1212->dma_rec);
> >
> > spin_lock_irqsave(&korg1212->lock, flags);
> >
> > @@ -2080,71 +2080,16 @@ static void snd_korg1212_proc_init(struct snd_korg1212 *korg1212)
> > snd_korg1212_proc_read);
> > }
> >
> > -static int
> > -snd_korg1212_free(struct snd_korg1212 *korg1212)
> > +static void
> > +snd_korg1212_free(struct snd_card *card)
> > {
> > - snd_korg1212_TurnOffIdleMonitor(korg1212);
> > -
> > - if (korg1212->irq >= 0) {
> > - snd_korg1212_DisableCardInterrupts(korg1212);
> > - free_irq(korg1212->irq, korg1212);
> > - korg1212->irq = -1;
> > - }
> > -
> > - if (korg1212->iobase != NULL) {
> > - iounmap(korg1212->iobase);
> > - korg1212->iobase = NULL;
> > - }
> > -
> > - pci_release_regions(korg1212->pci);
> > -
> > - // ----------------------------------------------------
> > - // free up memory resources used for the DSP download.
> > - // ----------------------------------------------------
> > - if (korg1212->dma_dsp.area) {
> > - snd_dma_free_pages(&korg1212->dma_dsp);
> > - korg1212->dma_dsp.area = NULL;
> > - }
> > -
> > -#ifndef K1212_LARGEALLOC
> > -
> > - // ------------------------------------------------------
> > - // free up memory resources used for the Play/Rec Buffers
> > - // ------------------------------------------------------
> > - if (korg1212->dma_play.area) {
> > - snd_dma_free_pages(&korg1212->dma_play);
> > - korg1212->dma_play.area = NULL;
> > - }
> > + struct snd_korg1212 *korg1212 = card->private_data;
> >
> > - if (korg1212->dma_rec.area) {
> > - snd_dma_free_pages(&korg1212->dma_rec);
> > - korg1212->dma_rec.area = NULL;
> > - }
> > -
> > -#endif
> > -
> > - // ----------------------------------------------------
> > - // free up memory resources used for the Shared Buffers
> > - // ----------------------------------------------------
> > - if (korg1212->dma_shared.area) {
> > - snd_dma_free_pages(&korg1212->dma_shared);
> > - korg1212->dma_shared.area = NULL;
> > - }
> > -
> > - pci_disable_device(korg1212->pci);
> > - kfree(korg1212);
> > - return 0;
> > -}
> > -
> > -static int snd_korg1212_dev_free(struct snd_device *device)
> > -{
> > - struct snd_korg1212 *korg1212 = device->device_data;
> > - K1212_DEBUG_PRINTK("K1212_DEBUG: Freeing device\n");
> > - return snd_korg1212_free(korg1212);
> > + snd_korg1212_TurnOffIdleMonitor(korg1212);
> > + snd_korg1212_DisableCardInterrupts(korg1212);
> > }
> >
> > -static int snd_korg1212_create(struct snd_card *card, struct pci_dev *pci,
> > - struct snd_korg1212 **rchip)
> > +static int snd_korg1212_create(struct snd_card *card, struct pci_dev *pci)
> >
> > {
> > int err, rc;
> > @@ -2152,24 +2097,13 @@ static int snd_korg1212_create(struct snd_card *card, struct pci_dev *pci,
> > unsigned iomem_size;
> > __maybe_unused unsigned ioport_size;
> > __maybe_unused unsigned iomem2_size;
> > - struct snd_korg1212 * korg1212;
> > + struct snd_korg1212 *korg1212 = card->private_data;
> > const struct firmware *dsp_code;
> >
> > - static const struct snd_device_ops ops = {
> > - .dev_free = snd_korg1212_dev_free,
> > - };
> > -
> > - * rchip = NULL;
> > - err = pci_enable_device(pci);
> > + err = pcim_enable_device(pci);
> > if (err < 0)
> > return err;
> >
> > - korg1212 = kzalloc(sizeof(*korg1212), GFP_KERNEL);
> > - if (korg1212 == NULL) {
> > - pci_disable_device(pci);
> > - return -ENOMEM;
> > - }
> > -
> > korg1212->card = card;
> > korg1212->pci = pci;
> >
> > @@ -2198,12 +2132,9 @@ static int snd_korg1212_create(struct snd_card *card, struct pci_dev *pci,
> > for (i=0; i<kAudioChannels; i++)
> > korg1212->volumePhase[i] = 0;
> >
> > - err = pci_request_regions(pci, "korg1212");
> > - if (err < 0) {
> > - kfree(korg1212);
> > - pci_disable_device(pci);
> > + err = pcim_iomap_regions_request_all(pci, 1 << 0, "korg1212");
> > + if (err < 0)
> > return err;
> > - }
> >
> > korg1212->iomem = pci_resource_start(korg1212->pci, 0);
> > korg1212->ioport = pci_resource_start(korg1212->pci, 1);
> > @@ -2223,26 +2154,20 @@ static int snd_korg1212_create(struct snd_card *card, struct pci_dev *pci,
> > korg1212->iomem2, iomem2_size,
> > stateName[korg1212->cardState]);
> >
> > - korg1212->iobase = ioremap(korg1212->iomem, iomem_size);
> > - if (!korg1212->iobase) {
> > - snd_printk(KERN_ERR "korg1212: unable to remap memory region 0x%lx-0x%lx\n", korg1212->iomem,
> > - korg1212->iomem + iomem_size - 1);
> > - snd_korg1212_free(korg1212);
> > - return -EBUSY;
> > - }
> > + korg1212->iobase = pcim_iomap_table(pci)[0];
> >
> > - err = request_irq(pci->irq, snd_korg1212_interrupt,
> > + err = devm_request_irq(&pci->dev, pci->irq, snd_korg1212_interrupt,
> > IRQF_SHARED,
> > KBUILD_MODNAME, korg1212);
> >
> > if (err) {
> > snd_printk(KERN_ERR "korg1212: unable to grab IRQ %d\n", pci->irq);
> > - snd_korg1212_free(korg1212);
> > return -EBUSY;
> > }
> >
> > korg1212->irq = pci->irq;
> > card->sync_irq = korg1212->irq;
> > + card->private_free = snd_korg1212_free;
> >
> > pci_set_master(korg1212->pci);
> >
> > @@ -2281,41 +2206,36 @@ static int snd_korg1212_create(struct snd_card *card, struct pci_dev *pci,
> > korg1212->idRegPtr,
> > stateName[korg1212->cardState]);
> >
> > - if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
> > - sizeof(struct KorgSharedBuffer), &korg1212->dma_shared) < 0) {
> > - snd_printk(KERN_ERR "korg1212: can not allocate shared buffer memory (%zd bytes)\n", sizeof(struct KorgSharedBuffer));
> > - snd_korg1212_free(korg1212);
> > - return -ENOMEM;
> > - }
> > - korg1212->sharedBufferPtr = (struct KorgSharedBuffer *)korg1212->dma_shared.area;
> > - korg1212->sharedBufferPhy = korg1212->dma_shared.addr;
> > + korg1212->dma_shared = snd_devm_alloc_pages(&pci->dev,
> > + SNDRV_DMA_TYPE_DEV,
> > + sizeof(struct KorgSharedBuffer));
> > + if (!korg1212->dma_shared)
> > + return -ENOMEM;
> > + korg1212->sharedBufferPtr = (struct KorgSharedBuffer *)korg1212->dma_shared->area;
> > + korg1212->sharedBufferPhy = korg1212->dma_shared->addr;
> >
> > K1212_DEBUG_PRINTK("K1212_DEBUG: Shared Buffer Area = 0x%p (0x%08lx), %d bytes\n", korg1212->sharedBufferPtr, korg1212->sharedBufferPhy, sizeof(struct KorgSharedBuffer));
> >
> > #ifndef K1212_LARGEALLOC
> > -
> > korg1212->DataBufsSize = sizeof(struct KorgAudioBuffer) * kNumBuffers;
> > + korg1212->dma_play = snd_devm_alloc_pages(&pci->dev, SNDRV_DMA_TYPE_DEV,
> > + korg1212->DataBufsSize);
> > + if (!korg1212->dma_play)
> > + return -ENOMEM;
> >
> > - if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
> > - korg1212->DataBufsSize, &korg1212->dma_play) < 0) {
> > - snd_printk(KERN_ERR "korg1212: can not allocate play data buffer memory (%d bytes)\n", korg1212->DataBufsSize);
> > - snd_korg1212_free(korg1212);
> > - return -ENOMEM;
> > - }
> > - korg1212->playDataBufsPtr = (struct KorgAudioBuffer *)korg1212->dma_play.area;
> > - korg1212->PlayDataPhy = korg1212->dma_play.addr;
> > + korg1212->playDataBufsPtr = (struct KorgAudioBuffer *)korg1212->dma_play->area;
> > + korg1212->PlayDataPhy = korg1212->dma_play->addr;
> >
> > K1212_DEBUG_PRINTK("K1212_DEBUG: Play Data Area = 0x%p (0x%08x), %d bytes\n",
> > korg1212->playDataBufsPtr, korg1212->PlayDataPhy, korg1212->DataBufsSize);
> >
> > - if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
> > - korg1212->DataBufsSize, &korg1212->dma_rec) < 0) {
> > - snd_printk(KERN_ERR "korg1212: can not allocate record data buffer memory (%d bytes)\n", korg1212->DataBufsSize);
> > - snd_korg1212_free(korg1212);
> > - return -ENOMEM;
> > - }
> > - korg1212->recordDataBufsPtr = (struct KorgAudioBuffer *)korg1212->dma_rec.area;
> > - korg1212->RecDataPhy = korg1212->dma_rec.addr;
> > + korg1212->dma_rec = snd_devm_alloc_pages(&pci->dev, SNDRV_DMA_TYPE_DEV,
> > + korg1212->DataBufsSize);
> > + if (!korg1212->dma_rec)
> > + return -ENOMEM;
> > +
> > + korg1212->recordDataBufsPtr = (struct KorgAudioBuffer *)korg1212->dma_rec->area;
> > + korg1212->RecDataPhy = korg1212->dma_rec->addr;
> >
> > K1212_DEBUG_PRINTK("K1212_DEBUG: Record Data Area = 0x%p (0x%08x), %d bytes\n",
> > korg1212->recordDataBufsPtr, korg1212->RecDataPhy, korg1212->DataBufsSize);
> > @@ -2336,26 +2256,22 @@ static int snd_korg1212_create(struct snd_card *card, struct pci_dev *pci,
> > korg1212->AdatTimeCodePhy = korg1212->sharedBufferPhy +
> > offsetof(struct KorgSharedBuffer, AdatTimeCode);
> >
> > + korg1212->dma_dsp = snd_devm_alloc_pages(&pci->dev, SNDRV_DMA_TYPE_DEV,
> > + dsp_code->size);
> > + if (!korg1212->dma_dsp)
> > + return -ENOMEM;
> > +
>
> Should this section be moved below the next one?
>
> sound/pci/korg1212/korg1212.c:2260:8: error: variable 'dsp_code' is uninitialized when used here [-Werror,-Wuninitialized]
> dsp_code->size);
> ^~~~~~~~
> sound/pci/korg1212/korg1212.c:2101:33: note: initialize the variable 'dsp_code' to silence this warning
> const struct firmware *dsp_code;
> ^
> = NULL
> 1 error generated.
Indeed, the wrong code shuffle caused it. The fix is below.
Takashi
-- 8< --
From: Takashi Iwai <tiwai at suse.de>
Subject: [PATCH] ALSA: korg1212: Fix wrongly shuffled firmware loader code
The recent change for the devres introduced the wrong code shuffling
in the korg1212 firmware loader function that may lead to a bad
pointer access. Restore the calls in the right order (and put back
the release_firmware() call in the error path, too).
Fixes: b5cde369b618 ("ALSA: korg1212: Allocate resources with device-managed APIs")
Reported-by: Nathan Chancellor <nathan at kernel.org>
Signed-off-by: Takashi Iwai <tiwai at suse.de>
---
sound/pci/korg1212/korg1212.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index 7872abbd4587..49ed2bfaf11f 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -2256,17 +2256,19 @@ static int snd_korg1212_create(struct snd_card *card, struct pci_dev *pci)
korg1212->AdatTimeCodePhy = korg1212->sharedBufferPhy +
offsetof(struct KorgSharedBuffer, AdatTimeCode);
- korg1212->dma_dsp = snd_devm_alloc_pages(&pci->dev, SNDRV_DMA_TYPE_DEV,
- dsp_code->size);
- if (!korg1212->dma_dsp)
- return -ENOMEM;
-
err = request_firmware(&dsp_code, "korg/k1212.dsp", &pci->dev);
if (err < 0) {
snd_printk(KERN_ERR "firmware not available\n");
return err;
}
+ korg1212->dma_dsp = snd_devm_alloc_pages(&pci->dev, SNDRV_DMA_TYPE_DEV,
+ dsp_code->size);
+ if (!korg1212->dma_dsp) {
+ release_firmware(dsp_code);
+ return -ENOMEM;
+ }
+
K1212_DEBUG_PRINTK("K1212_DEBUG: DSP Code area = 0x%p (0x%08x) %d bytes [%s]\n",
korg1212->dma_dsp->area, korg1212->dma_dsp->addr, dsp_code->size,
stateName[korg1212->cardState]);
--
2.26.2
More information about the Alsa-devel
mailing list