Commit 64a06f19 authored by Takashi Iwai's avatar Takashi Iwai

ALSA: usx2y: Fix shmem initialization

Currently us428ctls_shmem pages are allocated dynamically upon the
mmap call, but this is quite racy.  Since the shared memory itself is
mandatory for the mmap, let's allocate it at the beginning of the card
initialization.  Also, fix the initialization of the wait queue, too.

Link: https://lore.kernel.org/r/20210517131545.27252-9-tiwai@suse.deSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent c1f24841
...@@ -60,14 +60,6 @@ static int snd_us428ctls_mmap(struct snd_hwdep *hw, struct file *filp, struct vm ...@@ -60,14 +60,6 @@ static int snd_us428ctls_mmap(struct snd_hwdep *hw, struct file *filp, struct vm
return -EINVAL; return -EINVAL;
} }
if (!us428->us428ctls_sharedmem) {
init_waitqueue_head(&us428->us428ctls_wait_queue_head);
us428->us428ctls_sharedmem = alloc_pages_exact(US428_SHAREDMEM_PAGES, GFP_KERNEL);
if (!us428->us428ctls_sharedmem)
return -ENOMEM;
memset(us428->us428ctls_sharedmem, -1, US428_SHAREDMEM_PAGES);
us428->us428ctls_sharedmem->ctl_snapshot_last = -2;
}
area->vm_ops = &us428ctls_vm_ops; area->vm_ops = &us428ctls_vm_ops;
area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
area->vm_private_data = hw->private_data; area->vm_private_data = hw->private_data;
...@@ -232,18 +224,26 @@ int usx2y_hwdep_new(struct snd_card *card, struct usb_device *device) ...@@ -232,18 +224,26 @@ int usx2y_hwdep_new(struct snd_card *card, struct usb_device *device)
{ {
int err; int err;
struct snd_hwdep *hw; struct snd_hwdep *hw;
struct usx2ydev *us428 = usx2y(card);
err = snd_hwdep_new(card, SND_USX2Y_LOADER_ID, 0, &hw); err = snd_hwdep_new(card, SND_USX2Y_LOADER_ID, 0, &hw);
if (err < 0) if (err < 0)
return err; return err;
hw->iface = SNDRV_HWDEP_IFACE_USX2Y; hw->iface = SNDRV_HWDEP_IFACE_USX2Y;
hw->private_data = usx2y(card); hw->private_data = us428;
hw->ops.dsp_status = snd_usx2y_hwdep_dsp_status; hw->ops.dsp_status = snd_usx2y_hwdep_dsp_status;
hw->ops.dsp_load = snd_usx2y_hwdep_dsp_load; hw->ops.dsp_load = snd_usx2y_hwdep_dsp_load;
hw->ops.mmap = snd_us428ctls_mmap; hw->ops.mmap = snd_us428ctls_mmap;
hw->ops.poll = snd_us428ctls_poll; hw->ops.poll = snd_us428ctls_poll;
hw->exclusive = 1; hw->exclusive = 1;
sprintf(hw->name, "/dev/bus/usb/%03d/%03d", device->bus->busnum, device->devnum); sprintf(hw->name, "/dev/bus/usb/%03d/%03d", device->bus->busnum, device->devnum);
us428->us428ctls_sharedmem = alloc_pages_exact(US428_SHAREDMEM_PAGES, GFP_KERNEL);
if (!us428->us428ctls_sharedmem)
return -ENOMEM;
memset(us428->us428ctls_sharedmem, -1, US428_SHAREDMEM_PAGES);
us428->us428ctls_sharedmem->ctl_snapshot_last = -2;
return 0; return 0;
} }
...@@ -375,6 +375,7 @@ static int usx2y_create_card(struct usb_device *device, ...@@ -375,6 +375,7 @@ static int usx2y_create_card(struct usb_device *device,
card->private_free = snd_usx2y_card_private_free; card->private_free = snd_usx2y_card_private_free;
usx2y(card)->dev = device; usx2y(card)->dev = device;
init_waitqueue_head(&usx2y(card)->prepare_wait_queue); init_waitqueue_head(&usx2y(card)->prepare_wait_queue);
init_waitqueue_head(&usx2y(card)->us428ctls_wait_queue_head);
mutex_init(&usx2y(card)->pcm_mutex); mutex_init(&usx2y(card)->pcm_mutex);
INIT_LIST_HEAD(&usx2y(card)->midi_list); INIT_LIST_HEAD(&usx2y(card)->midi_list);
strcpy(card->driver, "USB "NAME_ALLCAPS""); strcpy(card->driver, "USB "NAME_ALLCAPS"");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment