[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 <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
This commit is contained in:
parent
33bf17abf9
commit
c2b1239a9f
|
@ -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
|
||||
---------------------
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/snd_wavefront.h>
|
||||
|
@ -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 <linux/fs.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
|
||||
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;
|
||||
const struct firmware *firmware;
|
||||
|
||||
/* 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());
|
||||
|
||||
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);
|
||||
|
|
Loading…
Reference in New Issue
Block a user