From c2b1239a9f22f19c53543b460b24507d0e21ea0c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 21 Aug 2007 15:20:26 +0200 Subject: [PATCH] [ALSA] wavefront - Use standard firmware loader Use the standard firmware loader for loading ICS2115 OS firmware file. This is the last old bad guy that is still using sys_open() and sys_read() calls, and now all should be gone. The patch also adds the missing description of module options related with wavefront_synth.c. Due to this rewrite, user will have to copy or make symlink the firmware file appropriately to the standard firmware path such as /lib/firmware. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- .../sound/alsa/ALSA-Configuration.txt | 44 +++++++ sound/isa/Kconfig | 9 +- sound/isa/wavefront/wavefront_synth.c | 120 +++++++----------- 3 files changed, 92 insertions(+), 81 deletions(-) diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index d7660549bb91..3df33ea8bae6 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -1716,8 +1716,52 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. dma2 - DMA2 # for CS4232 PCM interface. isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) + The below are options for wavefront_synth features: + wf_raw - Assume that we need to boot the OS (default:no) + If yes, then during driver loading, the state of the board is + ignored, and we reset the board and load the firmware anyway. + fx_raw - Assume that the FX process needs help (default:yes) + If false, we'll leave the FX processor in whatever state it is + when the driver is loaded. The default is to download the + microprogram and associated coefficients to set it up for + "default" operation, whatever that means. + debug_default - Debug parameters for card initialization + wait_usecs - How long to wait without sleeping, usecs + (default:150) + This magic number seems to give pretty optimal throughput + based on my limited experimentation. + If you want to play around with it and find a better value, be + my guest. Remember, the idea is to get a number that causes us + to just busy wait for as many WaveFront commands as possible, + without coming up with a number so large that we hog the whole + CPU. + Specifically, with this number, out of about 134,000 status + waits, only about 250 result in a sleep. + sleep_interval - How long to sleep when waiting for reply + (default: 100) + sleep_tries - How many times to try sleeping during a wait + (default: 50) + ospath - Pathname to processed ICS2115 OS firmware + (default:wavefront.os) + The path name of the ISC2115 OS firmware. In the recent + version, it's handled via firmware loader framework, so it + must be installed in the proper path, typically, + /lib/firmware. + reset_time - How long to wait for a reset to take effect + (default:2) + ramcheck_time - How many seconds to wait for the RAM test + (default:20) + osrun_time - How many seconds to wait for the ICS2115 OS + (default:10) + This module supports multiple cards and ISA PnP. + Note: the firmware file "wavefront.os" was located in the earlier + version in /etc. Now it's loaded via firmware loader, and + must be in the proper firmware path, such as /lib/firmware. + Copy (or symlink) the file appropriately if you get an error + regarding firmware downloading after upgrading the kernel. + Module snd-sonicvibes --------------------- diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig index ea5084abe60f..6b6aa2c3b85c 100644 --- a/sound/isa/Kconfig +++ b/sound/isa/Kconfig @@ -414,7 +414,7 @@ config SND_SSCAPE config SND_WAVEFRONT tristate "Turtle Beach Maui,Tropez,Tropez+ (Wavefront)" depends on SND - select FW_LOADER if !SND_WAVEFRONT_FIRMWARE_IN_KERNEL + select FW_LOADER select SND_OPL3_LIB select SND_MPU401_UART select SND_CS4231_LIB @@ -430,8 +430,9 @@ config SND_WAVEFRONT_FIRMWARE_IN_KERNEL depends on SND_WAVEFRONT default y help - Say Y here to include the static firmware built in the kernel - for the Wavefront driver. If you choose N here, you need to - install the firmware files from the alsa-firmware package. + Say Y here to include the static firmware for FX DSP built in + the kernel for the Wavefront driver. If you choose N here, + you need to install the firmware files from the + alsa-firmware package. endmenu diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c index bacc51c86587..2da11e8337dd 100644 --- a/sound/isa/wavefront/wavefront_synth.c +++ b/sound/isa/wavefront/wavefront_synth.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -53,9 +54,8 @@ static int debug_default = 0; /* you can set this to control debugging /* XXX this needs to be made firmware and hardware version dependent */ -static char *ospath = "/etc/sound/wavefront.os"; /* where to find a processed - version of the WaveFront OS - */ +#define DEFAULT_OSPATH "wavefront.os" +static char *ospath = DEFAULT_OSPATH; /* the firmware file name */ static int wait_usecs = 150; /* This magic number seems to give pretty optimal throughput based on my limited experimentation. @@ -97,7 +97,7 @@ MODULE_PARM_DESC(sleep_interval, "how long to sleep when waiting for reply"); module_param(sleep_tries, int, 0444); MODULE_PARM_DESC(sleep_tries, "how many times to try sleeping during a wait"); module_param(ospath, charp, 0444); -MODULE_PARM_DESC(ospath, "full pathname to processed ICS2115 OS firmware"); +MODULE_PARM_DESC(ospath, "pathname to processed ICS2115 OS firmware"); module_param(reset_time, int, 0444); MODULE_PARM_DESC(reset_time, "how long to wait for a reset to take effect"); module_param(ramcheck_time, int, 0444); @@ -1938,111 +1938,75 @@ wavefront_reset_to_cleanliness (snd_wavefront_t *dev) return (1); } -#include -#include -#include -#include -#include -#include - - static int __devinit wavefront_download_firmware (snd_wavefront_t *dev, char *path) { - unsigned char section[WF_SECTION_MAX]; - signed char section_length; /* yes, just a char; max value is WF_SECTION_MAX */ + unsigned char *buf; + int len, err; int section_cnt_downloaded = 0; - int fd; - int c; - int i; - mm_segment_t fs; - - /* This tries to be a bit cleverer than the stuff Alan Cox did for - the generic sound firmware, in that it actually knows - something about the structure of the Motorola firmware. In - particular, it uses a version that has been stripped of the - 20K of useless header information, and had section lengths - added, making it possible to load the entire OS without any - [kv]malloc() activity, since the longest entity we ever read is - 42 bytes (well, WF_SECTION_MAX) long. - */ - - fs = get_fs(); - set_fs (get_ds()); + const struct firmware *firmware; - if ((fd = sys_open ((char __user *) path, 0, 0)) < 0) { - snd_printk ("Unable to load \"%s\".\n", - path); + err = request_firmware(&firmware, path, dev->card->dev); + if (err < 0) { + snd_printk(KERN_ERR "firmware (%s) download failed!!!\n", path); return 1; } - while (1) { - int x; - - if ((x = sys_read (fd, (char __user *) §ion_length, sizeof (section_length))) != - sizeof (section_length)) { - snd_printk ("firmware read error.\n"); - goto failure; - } - - if (section_length == 0) { + len = 0; + buf = firmware->data; + for (;;) { + int section_length = *(signed char *)buf; + if (section_length == 0) break; - } - if (section_length < 0 || section_length > WF_SECTION_MAX) { - snd_printk ("invalid firmware section length %d\n", - section_length); + snd_printk(KERN_ERR + "invalid firmware section length %d\n", + section_length); goto failure; } + buf++; + len++; - if (sys_read (fd, (char __user *) section, section_length) != section_length) { - snd_printk ("firmware section " - "read error.\n"); + if (firmware->size < len + section_length) { + snd_printk(KERN_ERR "firmware section read error.\n"); goto failure; } /* Send command */ - - if (wavefront_write (dev, WFC_DOWNLOAD_OS)) { + if (wavefront_write(dev, WFC_DOWNLOAD_OS)) goto failure; - } - for (i = 0; i < section_length; i++) { - if (wavefront_write (dev, section[i])) { + for (; section_length; section_length--) { + if (wavefront_write(dev, *buf)) goto failure; - } + buf++; + len++; } /* get ACK */ - - if (wavefront_wait (dev, STAT_CAN_READ)) { - - if ((c = inb (dev->data_port)) != WF_ACK) { - - snd_printk ("download " - "of section #%d not " - "acknowledged, ack = 0x%x\n", - section_cnt_downloaded + 1, c); - goto failure; - - } - - } else { - snd_printk ("time out for firmware ACK.\n"); + if (!wavefront_wait(dev, STAT_CAN_READ)) { + snd_printk(KERN_ERR "time out for firmware ACK.\n"); + goto failure; + } + err = inb(dev->data_port); + if (err != WF_ACK) { + snd_printk(KERN_ERR + "download of section #%d not " + "acknowledged, ack = 0x%x\n", + section_cnt_downloaded + 1, err); goto failure; } + section_cnt_downloaded++; } - sys_close (fd); - set_fs (fs); + release_firmware(firmware); return 0; failure: - sys_close (fd); - set_fs (fs); - snd_printk ("firmware download failed!!!\n"); + release_firmware(firmware); + snd_printk(KERN_ERR "firmware download failed!!!\n"); return 1; } @@ -2232,3 +2196,5 @@ snd_wavefront_detect (snd_wavefront_card_t *card) return 0; } + +MODULE_FIRMWARE(DEFAULT_OSPATH); -- 2.20.1