|
@@ -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;
|
|
|
-
|
|
|
- /* 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);
|