From cf4ce59b3b70238352c7f1729f0f7223214828ad Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Fri, 20 Sep 2024 01:46:19 +0000 Subject: [PATCH] rtl88x2CE_WiFi_linux add concurrent mode --- kernel/sound/pci/rme9652/hdsp.c | 132 ++++++++++++++++++------------------------- 1 files changed, 55 insertions(+), 77 deletions(-) diff --git a/kernel/sound/pci/rme9652/hdsp.c b/kernel/sound/pci/rme9652/hdsp.c index a0797fc..9543474 100644 --- a/kernel/sound/pci/rme9652/hdsp.c +++ b/kernel/sound/pci/rme9652/hdsp.c @@ -1,24 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * ALSA driver for RME Hammerfall DSP audio interface(s) * * Copyright (c) 2002 Paul Davis * Marcus Andersson * Thomas Charbonnel - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * */ #include <linux/init.h> @@ -450,7 +436,7 @@ struct snd_rawmidi *rmidi; struct snd_rawmidi_substream *input; struct snd_rawmidi_substream *output; - char istimer; /* timer in use */ + signed char istimer; /* timer in use */ struct timer_list timer; spinlock_t lock; int pending; @@ -461,8 +447,8 @@ struct snd_pcm_substream *capture_substream; struct snd_pcm_substream *playback_substream; struct hdsp_midi midi[2]; - struct tasklet_struct midi_tasklet; - int use_midi_tasklet; + struct work_struct midi_work; + int use_midi_work; int precise_ptr; u32 control_register; /* cached value */ u32 control2_register; /* cached value */ @@ -493,7 +479,7 @@ pid_t playback_pid; int running; int system_sample_rate; - char *channel_map; + const signed char *channel_map; int dev; int irq; unsigned long port; @@ -515,12 +501,12 @@ where the data for that channel can be read/written from/to. */ -static char channel_map_df_ss[HDSP_MAX_CHANNELS] = { +static const signed char channel_map_df_ss[HDSP_MAX_CHANNELS] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 }; -static char channel_map_mf_ss[HDSP_MAX_CHANNELS] = { /* Multiface */ +static const char channel_map_mf_ss[HDSP_MAX_CHANNELS] = { /* Multiface */ /* Analog */ 0, 1, 2, 3, 4, 5, 6, 7, /* ADAT 2 */ @@ -530,7 +516,7 @@ -1, -1, -1, -1, -1, -1, -1, -1 }; -static char channel_map_ds[HDSP_MAX_CHANNELS] = { +static const signed char channel_map_ds[HDSP_MAX_CHANNELS] = { /* ADAT channels are remapped */ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, /* channels 12 and 13 are S/PDIF */ @@ -539,7 +525,7 @@ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; -static char channel_map_H9632_ss[HDSP_MAX_CHANNELS] = { +static const signed char channel_map_H9632_ss[HDSP_MAX_CHANNELS] = { /* ADAT channels */ 0, 1, 2, 3, 4, 5, 6, 7, /* SPDIF */ @@ -553,7 +539,7 @@ -1, -1 }; -static char channel_map_H9632_ds[HDSP_MAX_CHANNELS] = { +static const signed char channel_map_H9632_ds[HDSP_MAX_CHANNELS] = { /* ADAT */ 1, 3, 5, 7, /* SPDIF */ @@ -567,7 +553,7 @@ -1, -1, -1, -1, -1, -1 }; -static char channel_map_H9632_qs[HDSP_MAX_CHANNELS] = { +static const signed char channel_map_H9632_qs[HDSP_MAX_CHANNELS] = { /* ADAT is disabled in this mode */ /* SPDIF */ 8, 9, @@ -583,12 +569,7 @@ static int snd_hammerfall_get_buffer(struct pci_dev *pci, struct snd_dma_buffer *dmab, size_t size) { - dmab->dev.type = SNDRV_DMA_TYPE_DEV; - dmab->dev.dev = snd_dma_pci_data(pci); - if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), - size, dmab) < 0) - return -ENOMEM; - return 0; + return snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev, size, dmab); } static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_dev *pci) @@ -1404,7 +1385,6 @@ } } else { hdsp->control_register &= ~ie; - tasklet_kill(&hdsp->midi_tasklet); } hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); @@ -2561,37 +2541,37 @@ return change; } -#define HDSP_USE_MIDI_TASKLET(xname, xindex) \ +#define HDSP_USE_MIDI_WORK(xname, xindex) \ { .iface = SNDRV_CTL_ELEM_IFACE_CARD, \ .name = xname, \ .index = xindex, \ - .info = snd_hdsp_info_use_midi_tasklet, \ - .get = snd_hdsp_get_use_midi_tasklet, \ - .put = snd_hdsp_put_use_midi_tasklet \ + .info = snd_hdsp_info_use_midi_work, \ + .get = snd_hdsp_get_use_midi_work, \ + .put = snd_hdsp_put_use_midi_work \ } -static int hdsp_set_use_midi_tasklet(struct hdsp *hdsp, int use_tasklet) +static int hdsp_set_use_midi_work(struct hdsp *hdsp, int use_work) { - if (use_tasklet) - hdsp->use_midi_tasklet = 1; + if (use_work) + hdsp->use_midi_work = 1; else - hdsp->use_midi_tasklet = 0; + hdsp->use_midi_work = 0; return 0; } -#define snd_hdsp_info_use_midi_tasklet snd_ctl_boolean_mono_info +#define snd_hdsp_info_use_midi_work snd_ctl_boolean_mono_info -static int snd_hdsp_get_use_midi_tasklet(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hdsp_get_use_midi_work(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); spin_lock_irq(&hdsp->lock); - ucontrol->value.integer.value[0] = hdsp->use_midi_tasklet; + ucontrol->value.integer.value[0] = hdsp->use_midi_work; spin_unlock_irq(&hdsp->lock); return 0; } -static int snd_hdsp_put_use_midi_tasklet(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hdsp_put_use_midi_work(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); int change; @@ -2601,8 +2581,8 @@ return -EBUSY; val = ucontrol->value.integer.value[0] & 1; spin_lock_irq(&hdsp->lock); - change = (int)val != hdsp->use_midi_tasklet; - hdsp_set_use_midi_tasklet(hdsp, val); + change = (int)val != hdsp->use_midi_work; + hdsp_set_use_midi_work(hdsp, val); spin_unlock_irq(&hdsp->lock); return change; } @@ -2898,7 +2878,7 @@ return change; } -static struct snd_kcontrol_new snd_hdsp_9632_controls[] = { +static const struct snd_kcontrol_new snd_hdsp_9632_controls[] = { HDSP_DA_GAIN("DA Gain", 0), HDSP_AD_GAIN("AD Gain", 0), HDSP_PHONE_GAIN("Phones Gain", 0), @@ -2906,7 +2886,7 @@ HDSP_DDS_OFFSET("DDS Sample Rate Offset", 0) }; -static struct snd_kcontrol_new snd_hdsp_controls[] = { +static const struct snd_kcontrol_new snd_hdsp_controls[] = { { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), @@ -2969,7 +2949,7 @@ HDSP_ADATSYNC_SYNC_CHECK("ADAT Sync Lock Status", 0), HDSP_TOGGLE_SETTING("Line Out", HDSP_LineOut), HDSP_PRECISE_POINTER("Precise Pointer", 0), -HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0), +HDSP_USE_MIDI_WORK("Use Midi Tasklet", 0), }; @@ -3235,7 +3215,7 @@ return snd_ctl_enum_info(uinfo, 1, 2, texts); } -static struct snd_kcontrol_new snd_hdsp_rpm_controls[] = { +static const struct snd_kcontrol_new snd_hdsp_rpm_controls[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "RPM Bypass", @@ -3268,7 +3248,7 @@ HDSP_MIXER("Mixer", 0) }; -static struct snd_kcontrol_new snd_hdsp_96xx_aeb = +static const struct snd_kcontrol_new snd_hdsp_96xx_aeb = HDSP_TOGGLE_SETTING("Analog Extension Board", HDSP_AnalogExtensionBoard); static struct snd_kcontrol_new snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK; @@ -3372,7 +3352,8 @@ return; } } else { - int err = -EINVAL; + int err; + err = hdsp_request_fw_loader(hdsp); if (err < 0) { snd_iprintf(buffer, @@ -3388,7 +3369,7 @@ snd_iprintf(buffer, "MIDI1 Input status: 0x%x\n", hdsp_read(hdsp, HDSP_midiStatusIn0)); snd_iprintf(buffer, "MIDI2 Output status: 0x%x\n", hdsp_read(hdsp, HDSP_midiStatusOut1)); snd_iprintf(buffer, "MIDI2 Input status: 0x%x\n", hdsp_read(hdsp, HDSP_midiStatusIn1)); - snd_iprintf(buffer, "Use Midi Tasklet: %s\n", hdsp->use_midi_tasklet ? "on" : "off"); + snd_iprintf(buffer, "Use Midi Tasklet: %s\n", hdsp->use_midi_work ? "on" : "off"); snd_iprintf(buffer, "\n"); @@ -3708,10 +3689,7 @@ static void snd_hdsp_proc_init(struct hdsp *hdsp) { - struct snd_info_entry *entry; - - if (! snd_card_proc_new(hdsp->card, "hdsp", &entry)) - snd_info_set_text_ops(entry, hdsp, snd_hdsp_proc_read); + snd_card_ro_proc_new(hdsp->card, "hdsp", hdsp, snd_hdsp_proc_read); } static void snd_hdsp_free_buffers(struct hdsp *hdsp) @@ -3812,9 +3790,9 @@ return 0; } -static void hdsp_midi_tasklet(unsigned long arg) +static void hdsp_midi_work(struct work_struct *work) { - struct hdsp *hdsp = (struct hdsp *)arg; + struct hdsp *hdsp = container_of(work, struct hdsp, midi_work); if (hdsp->midi[0].pending) snd_hdsp_midi_input_read (&hdsp->midi[0]); @@ -3859,7 +3837,7 @@ } if (midi0 && midi0status) { - if (hdsp->use_midi_tasklet) { + if (hdsp->use_midi_work) { /* we disable interrupts for this input until processing is done */ hdsp->control_register &= ~HDSP_Midi0InterruptEnable; hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); @@ -3870,7 +3848,7 @@ } } if (hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632 && midi1 && midi1status) { - if (hdsp->use_midi_tasklet) { + if (hdsp->use_midi_work) { /* we disable interrupts for this input until processing is done */ hdsp->control_register &= ~HDSP_Midi1InterruptEnable; hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); @@ -3880,8 +3858,8 @@ snd_hdsp_midi_input_read (&hdsp->midi[1]); } } - if (hdsp->use_midi_tasklet && schedule) - tasklet_schedule(&hdsp->midi_tasklet); + if (hdsp->use_midi_work && schedule) + queue_work(system_highpri_wq, &hdsp->midi_work); return IRQ_HANDLED; } @@ -3891,7 +3869,7 @@ return hdsp_hw_pointer(hdsp); } -static char *hdsp_channel_buffer_location(struct hdsp *hdsp, +static signed char *hdsp_channel_buffer_location(struct hdsp *hdsp, int stream, int channel) @@ -3915,7 +3893,7 @@ void __user *src, unsigned long count) { struct hdsp *hdsp = snd_pcm_substream_chip(substream); - char *channel_buf; + signed char *channel_buf; if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES)) return -EINVAL; @@ -3933,7 +3911,7 @@ void *src, unsigned long count) { struct hdsp *hdsp = snd_pcm_substream_chip(substream); - char *channel_buf; + signed char *channel_buf; channel_buf = hdsp_channel_buffer_location(hdsp, substream->pstr->stream, channel); if (snd_BUG_ON(!channel_buf)) @@ -3947,7 +3925,7 @@ void __user *dst, unsigned long count) { struct hdsp *hdsp = snd_pcm_substream_chip(substream); - char *channel_buf; + signed char *channel_buf; if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES)) return -EINVAL; @@ -3965,7 +3943,7 @@ void *dst, unsigned long count) { struct hdsp *hdsp = snd_pcm_substream_chip(substream); - char *channel_buf; + signed char *channel_buf; channel_buf = hdsp_channel_buffer_location(hdsp, substream->pstr->stream, channel); if (snd_BUG_ON(!channel_buf)) @@ -3979,7 +3957,7 @@ unsigned long count) { struct hdsp *hdsp = snd_pcm_substream_chip(substream); - char *channel_buf; + signed char *channel_buf; channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel); if (snd_BUG_ON(!channel_buf)) @@ -4824,7 +4802,7 @@ break; } case SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE: { - struct hdsp_firmware __user *firmware; + struct hdsp_firmware firmware; u32 __user *firmware_data; int err; @@ -4837,10 +4815,9 @@ dev_info(hdsp->card->dev, "initializing firmware upload\n"); - firmware = (struct hdsp_firmware __user *)argp; - - if (get_user(firmware_data, &firmware->firmware_data)) + if (copy_from_user(&firmware, argp, sizeof(firmware))) return -EFAULT; + firmware_data = (u32 __user *)firmware.firmware_data; if (hdsp_check_for_iobox (hdsp)) return -EIO; @@ -5204,7 +5181,7 @@ spin_lock_init(&hdsp->lock); - tasklet_init(&hdsp->midi_tasklet, hdsp_midi_tasklet, (unsigned long)hdsp); + INIT_WORK(&hdsp->midi_work, hdsp_midi_work); pci_read_config_word(hdsp->pci, PCI_CLASS_REVISION, &hdsp->firmware_rev); hdsp->firmware_rev &= 0xff; @@ -5242,7 +5219,7 @@ if ((err = pci_request_regions(pci, "hdsp")) < 0) return err; hdsp->port = pci_resource_start(pci, 0); - if ((hdsp->iobase = ioremap_nocache(hdsp->port, HDSP_IO_EXTENT)) == NULL) { + if ((hdsp->iobase = ioremap(hdsp->port, HDSP_IO_EXTENT)) == NULL) { dev_err(hdsp->card->dev, "unable to remap region 0x%lx-0x%lx\n", hdsp->port, hdsp->port + HDSP_IO_EXTENT - 1); return -EBUSY; @@ -5255,8 +5232,9 @@ } hdsp->irq = pci->irq; + card->sync_irq = hdsp->irq; hdsp->precise_ptr = 0; - hdsp->use_midi_tasklet = 1; + hdsp->use_midi_work = 1; hdsp->dds_value = 0; if ((err = snd_hdsp_initialize_memory(hdsp)) < 0) @@ -5326,7 +5304,7 @@ { if (hdsp->port) { /* stop the audio, and cancel all interrupts */ - tasklet_kill(&hdsp->midi_tasklet); + cancel_work_sync(&hdsp->midi_work); hdsp->control_register &= ~(HDSP_Start|HDSP_AudioInterruptEnable|HDSP_Midi0InterruptEnable|HDSP_Midi1InterruptEnable); hdsp_write (hdsp, HDSP_controlRegister, hdsp->control_register); } -- Gitblit v1.6.2