[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>
diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c
index bacc51c8..2da11e8 100644
--- a/sound/isa/wavefront/wavefront_synth.c
+++ b/sound/isa/wavefront/wavefront_synth.c
@@ -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 @@
 
 /* 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_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 @@
 	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 *) &section_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 @@
 
 	return 0;
 }
+
+MODULE_FIRMWARE(DEFAULT_OSPATH);