aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-11-22 10:55:11 -0500
committerTakashi Iwai <tiwai@suse.de>2012-11-22 11:48:07 -0500
commit90caaef6a1ce2ec6675b1dc5afd57767954ab7e8 (patch)
tree30a46cb8716a243fe250267ab1df899cecbc2707
parent7009fa568b126a07b2de8ead103e378534453830 (diff)
ALSA: hdsp: improve firmware caching
As the recent firmware code tries to reread and cache the firmware by itself, it's even better to keep the struct firmware data instead of keeping a local copy. Also, it makes little sense to disable the fw loader for this driver, so added the explicit dependency, too. Last, but not least, allocate the firmware data loaded via ioctl in vmalloc'ed buffer instead, as the firmware size isn't that small. Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/Kconfig1
-rw-r--r--sound/pci/rme9652/hdsp.c62
2 files changed, 35 insertions, 28 deletions
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 59dbb7035da..947cfb4eb30 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -572,6 +572,7 @@ source "sound/pci/hda/Kconfig"
572 572
573config SND_HDSP 573config SND_HDSP
574 tristate "RME Hammerfall DSP Audio" 574 tristate "RME Hammerfall DSP Audio"
575 select FW_LOADER
575 select SND_HWDEP 576 select SND_HWDEP
576 select SND_RAWMIDI 577 select SND_RAWMIDI
577 select SND_PCM 578 select SND_PCM
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 0d6930c4f4b..b8ddbb18f14 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -59,13 +59,11 @@ MODULE_LICENSE("GPL");
59MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP}," 59MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP},"
60 "{RME HDSP-9652}," 60 "{RME HDSP-9652},"
61 "{RME HDSP-9632}}"); 61 "{RME HDSP-9632}}");
62#ifdef HDSP_FW_LOADER
63MODULE_FIRMWARE("rpm_firmware.bin"); 62MODULE_FIRMWARE("rpm_firmware.bin");
64MODULE_FIRMWARE("multiface_firmware.bin"); 63MODULE_FIRMWARE("multiface_firmware.bin");
65MODULE_FIRMWARE("multiface_firmware_rev11.bin"); 64MODULE_FIRMWARE("multiface_firmware_rev11.bin");
66MODULE_FIRMWARE("digiface_firmware.bin"); 65MODULE_FIRMWARE("digiface_firmware.bin");
67MODULE_FIRMWARE("digiface_firmware_rev11.bin"); 66MODULE_FIRMWARE("digiface_firmware_rev11.bin");
68#endif
69 67
70#define HDSP_MAX_CHANNELS 26 68#define HDSP_MAX_CHANNELS 26
71#define HDSP_MAX_DS_CHANNELS 14 69#define HDSP_MAX_DS_CHANNELS 14
@@ -423,12 +421,7 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin");
423#define HDSP_DMA_AREA_BYTES ((HDSP_MAX_CHANNELS+1) * HDSP_CHANNEL_BUFFER_BYTES) 421#define HDSP_DMA_AREA_BYTES ((HDSP_MAX_CHANNELS+1) * HDSP_CHANNEL_BUFFER_BYTES)
424#define HDSP_DMA_AREA_KILOBYTES (HDSP_DMA_AREA_BYTES/1024) 422#define HDSP_DMA_AREA_KILOBYTES (HDSP_DMA_AREA_BYTES/1024)
425 423
426/* use hotplug firmware loader? */ 424#define HDSP_FIRMWARE_SIZE (24413 * 4)
427#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
428#if !defined(HDSP_USE_HWDEP_LOADER)
429#define HDSP_FW_LOADER
430#endif
431#endif
432 425
433struct hdsp_9632_meters { 426struct hdsp_9632_meters {
434 u32 input_peak[16]; 427 u32 input_peak[16];
@@ -475,7 +468,8 @@ struct hdsp {
475 enum HDSP_IO_Type io_type; /* ditto, but for code use */ 468 enum HDSP_IO_Type io_type; /* ditto, but for code use */
476 unsigned short firmware_rev; 469 unsigned short firmware_rev;
477 unsigned short state; /* stores state bits */ 470 unsigned short state; /* stores state bits */
478 u32 firmware_cache[24413]; /* this helps recover from accidental iobox power failure */ 471 const struct firmware *firmware;
472 u32 *fw_uploaded;
479 size_t period_bytes; /* guess what this is */ 473 size_t period_bytes; /* guess what this is */
480 unsigned char max_channels; 474 unsigned char max_channels;
481 unsigned char qs_in_channels; /* quad speed mode for H9632 */ 475 unsigned char qs_in_channels; /* quad speed mode for H9632 */
@@ -712,6 +706,17 @@ static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) {
712 706
713 int i; 707 int i;
714 unsigned long flags; 708 unsigned long flags;
709 const u32 *cache;
710
711 if (hdsp->fw_uploaded)
712 cache = hdsp->fw_uploaded;
713 else {
714 if (!hdsp->firmware)
715 return -ENODEV;
716 cache = (u32 *)hdsp->firmware->data;
717 if (!cache)
718 return -ENODEV;
719 }
715 720
716 if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) { 721 if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
717 722
@@ -727,8 +732,8 @@ static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) {
727 732
728 hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD); 733 hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);
729 734
730 for (i = 0; i < 24413; ++i) { 735 for (i = 0; i < HDSP_FIRMWARE_SIZE / 4; ++i) {
731 hdsp_write(hdsp, HDSP_fifoData, hdsp->firmware_cache[i]); 736 hdsp_write(hdsp, HDSP_fifoData, cache[i]);
732 if (hdsp_fifo_wait (hdsp, 127, HDSP_LONG_WAIT)) { 737 if (hdsp_fifo_wait (hdsp, 127, HDSP_LONG_WAIT)) {
733 snd_printk ("Hammerfall-DSP: timeout during firmware loading\n"); 738 snd_printk ("Hammerfall-DSP: timeout during firmware loading\n");
734 return -EIO; 739 return -EIO;
@@ -798,9 +803,7 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp)
798} 803}
799 804
800 805
801#ifdef HDSP_FW_LOADER
802static int hdsp_request_fw_loader(struct hdsp *hdsp); 806static int hdsp_request_fw_loader(struct hdsp *hdsp);
803#endif
804 807
805static int hdsp_check_for_firmware (struct hdsp *hdsp, int load_on_demand) 808static int hdsp_check_for_firmware (struct hdsp *hdsp, int load_on_demand)
806{ 809{
@@ -813,10 +816,8 @@ static int hdsp_check_for_firmware (struct hdsp *hdsp, int load_on_demand)
813 snd_printk(KERN_ERR "Hammerfall-DSP: firmware not present.\n"); 816 snd_printk(KERN_ERR "Hammerfall-DSP: firmware not present.\n");
814 /* try to load firmware */ 817 /* try to load firmware */
815 if (! (hdsp->state & HDSP_FirmwareCached)) { 818 if (! (hdsp->state & HDSP_FirmwareCached)) {
816#ifdef HDSP_FW_LOADER
817 if (! hdsp_request_fw_loader(hdsp)) 819 if (! hdsp_request_fw_loader(hdsp))
818 return 0; 820 return 0;
819#endif
820 snd_printk(KERN_ERR 821 snd_printk(KERN_ERR
821 "Hammerfall-DSP: No firmware loaded nor " 822 "Hammerfall-DSP: No firmware loaded nor "
822 "cached, please upload firmware.\n"); 823 "cached, please upload firmware.\n");
@@ -3673,9 +3674,7 @@ snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
3673 } 3674 }
3674 } else { 3675 } else {
3675 int err = -EINVAL; 3676 int err = -EINVAL;
3676#ifdef HDSP_FW_LOADER
3677 err = hdsp_request_fw_loader(hdsp); 3677 err = hdsp_request_fw_loader(hdsp);
3678#endif
3679 if (err < 0) { 3678 if (err < 0) {
3680 snd_iprintf(buffer, 3679 snd_iprintf(buffer,
3681 "No firmware loaded nor cached, " 3680 "No firmware loaded nor cached, "
@@ -5100,8 +5099,18 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
5100 if (hdsp_check_for_iobox (hdsp)) 5099 if (hdsp_check_for_iobox (hdsp))
5101 return -EIO; 5100 return -EIO;
5102 5101
5103 if (copy_from_user(hdsp->firmware_cache, firmware_data, sizeof(hdsp->firmware_cache)) != 0) 5102 if (!hdsp->fw_uploaded) {
5103 hdsp->fw_uploaded = vmalloc(HDSP_FIRMWARE_SIZE);
5104 if (!hdsp->fw_uploaded)
5105 return -ENOMEM;
5106 }
5107
5108 if (copy_from_user(hdsp->fw_uploaded, firmware_data,
5109 HDSP_FIRMWARE_SIZE)) {
5110 vfree(hdsp->fw_uploaded);
5111 hdsp->fw_uploaded = NULL;
5104 return -EFAULT; 5112 return -EFAULT;
5113 }
5105 5114
5106 hdsp->state |= HDSP_FirmwareCached; 5115 hdsp->state |= HDSP_FirmwareCached;
5107 5116
@@ -5330,7 +5339,6 @@ static int snd_hdsp_create_alsa_devices(struct snd_card *card, struct hdsp *hdsp
5330 return 0; 5339 return 0;
5331} 5340}
5332 5341
5333#ifdef HDSP_FW_LOADER
5334/* load firmware via hotplug fw loader */ 5342/* load firmware via hotplug fw loader */
5335static int hdsp_request_fw_loader(struct hdsp *hdsp) 5343static int hdsp_request_fw_loader(struct hdsp *hdsp)
5336{ 5344{
@@ -5373,16 +5381,13 @@ static int hdsp_request_fw_loader(struct hdsp *hdsp)
5373 snd_printk(KERN_ERR "Hammerfall-DSP: cannot load firmware %s\n", fwfile); 5381 snd_printk(KERN_ERR "Hammerfall-DSP: cannot load firmware %s\n", fwfile);
5374 return -ENOENT; 5382 return -ENOENT;
5375 } 5383 }
5376 if (fw->size < sizeof(hdsp->firmware_cache)) { 5384 if (fw->size < HDSP_FIRMWARE_SIZE) {
5377 snd_printk(KERN_ERR "Hammerfall-DSP: too short firmware size %d (expected %d)\n", 5385 snd_printk(KERN_ERR "Hammerfall-DSP: too short firmware size %d (expected %d)\n",
5378 (int)fw->size, (int)sizeof(hdsp->firmware_cache)); 5386 (int)fw->size, HDSP_FIRMWARE_SIZE);
5379 release_firmware(fw);
5380 return -EINVAL; 5387 return -EINVAL;
5381 } 5388 }
5382 5389
5383 memcpy(hdsp->firmware_cache, fw->data, sizeof(hdsp->firmware_cache)); 5390 hdsp->firmware = fw;
5384
5385 release_firmware(fw);
5386 5391
5387 hdsp->state |= HDSP_FirmwareCached; 5392 hdsp->state |= HDSP_FirmwareCached;
5388 5393
@@ -5406,7 +5411,6 @@ static int hdsp_request_fw_loader(struct hdsp *hdsp)
5406 } 5411 }
5407 return 0; 5412 return 0;
5408} 5413}
5409#endif
5410 5414
5411static int __devinit snd_hdsp_create(struct snd_card *card, 5415static int __devinit snd_hdsp_create(struct snd_card *card,
5412 struct hdsp *hdsp) 5416 struct hdsp *hdsp)
@@ -5504,7 +5508,6 @@ static int __devinit snd_hdsp_create(struct snd_card *card,
5504 return err; 5508 return err;
5505 5509
5506 if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) { 5510 if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
5507#ifdef HDSP_FW_LOADER
5508 if ((err = hdsp_request_fw_loader(hdsp)) < 0) 5511 if ((err = hdsp_request_fw_loader(hdsp)) < 0)
5509 /* we don't fail as this can happen 5512 /* we don't fail as this can happen
5510 if userspace is not ready for 5513 if userspace is not ready for
@@ -5514,7 +5517,6 @@ static int __devinit snd_hdsp_create(struct snd_card *card,
5514 else 5517 else
5515 /* init is complete, we return */ 5518 /* init is complete, we return */
5516 return 0; 5519 return 0;
5517#endif
5518 /* we defer initialization */ 5520 /* we defer initialization */
5519 snd_printk(KERN_INFO "Hammerfall-DSP: card initialization pending : waiting for firmware\n"); 5521 snd_printk(KERN_INFO "Hammerfall-DSP: card initialization pending : waiting for firmware\n");
5520 if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0) 5522 if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0)
@@ -5568,6 +5570,10 @@ static int snd_hdsp_free(struct hdsp *hdsp)
5568 5570
5569 snd_hdsp_free_buffers(hdsp); 5571 snd_hdsp_free_buffers(hdsp);
5570 5572
5573 if (hdsp->firmware)
5574 release_firmware(hdsp->firmware);
5575 vfree(hdsp->fw_uploaded);
5576
5571 if (hdsp->iobase) 5577 if (hdsp->iobase)
5572 iounmap(hdsp->iobase); 5578 iounmap(hdsp->iobase);
5573 5579